@dsh-xhl/dsh-file-explorer 0.1.8 → 0.1.9
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/cordis.patch.yml +8 -8
- package/lib/client.js +37 -226
- package/lib/types/context-types.d.ts +0 -11
- package/package.json +113 -113
package/README.md
CHANGED
|
@@ -5,12 +5,14 @@
|
|
|
5
5
|
## 功能
|
|
6
6
|
|
|
7
7
|
- **聊天页标题栏图标**(`conversation.session.header.utilities`):一个内置编辑器图标,点击打开文件预览 / 编辑弹窗(聊天页保持与现状一致,无下拉)
|
|
8
|
-
- **Hero / 新建会话页 ButtonGroup
|
|
8
|
+
- **Hero / 新建会话页 ButtonGroup**:通过 `@dsh-xhl/dsh-hero-flex` 插件声明的
|
|
9
|
+
`hero.flex` 槽位渲染(**未安装该插件则不显示**);hero 上为**左主按钮 +
|
|
10
|
+
右下拉**的组合:
|
|
9
11
|
- **编辑器**(默认):点击打开文件预览 / 编辑弹窗(Ctrl+P 亦可)
|
|
10
12
|
- **文件夹**:点击直接打开会话工作区所在的**系统文件夹**(Windows `explorer` / macOS `open` / Linux `xdg-open`)
|
|
11
13
|
- **VSCode**:点击用 `code` 命令行在 **VS Code** 中打开会话工作区(自动探测安装位置 / PATH;宿主明确报告未安装时该项自动隐藏,探测请求本身失败则保持可见并退避重试)
|
|
12
14
|
- 选择记忆在 localStorage,点击后底部提示确认打开的路径;下拉选中某项会先切换默认打开方式,随后立即执行对应的打开动作
|
|
13
|
-
-
|
|
15
|
+
- 纯插件实现,不改动框架代码;hero 按钮组渲染依赖独立插件 `@dsh-xhl/dsh-hero-flex`(详见 `docs/hero-filex-button.md`)
|
|
14
16
|
- **对话内点击文件 → 编辑器预览**:聊天里的文件路径链接(工具行、产物行、正文提及)默认用系统程序打开;插件拦截 `remote.session.openWorkspacePath` 与 `workspaces.openPath` 两条通道,改为在编辑器弹窗中预览(目录或 cwd 外的路径仍落回系统打开)
|
|
15
17
|
- **文件列表**:左侧目录树(跳过 `node_modules`/`.git`/`dist` 等)
|
|
16
18
|
- **按文件名过滤**:输入即过滤
|
|
@@ -28,7 +30,7 @@ src/
|
|
|
28
30
|
+ /filex/file 媒体路由(图片/PDF 字节),loopback 信任围栏
|
|
29
31
|
trust-fence.ts Host-header loopback 校验(DNS-rebinding 防护)
|
|
30
32
|
client/
|
|
31
|
-
index.tsx 入口:聊天页 header 图标(内置编辑器)+ hero 模式 ButtonGroup
|
|
33
|
+
index.tsx 入口:聊天页 header 图标(内置编辑器)+ hero 模式 ButtonGroup(hero.flex 槽位)+ overlay 弹窗 + Ctrl+P 快捷键
|
|
32
34
|
Explorer.tsx 弹窗:文件树 / 文件名过滤 / 全文搜索 / 查看器分派(primitives 重排)
|
|
33
35
|
TextEditor.tsx CodeMirror 6 编辑器 + 搜索跳转高亮
|
|
34
36
|
lang.ts 扩展名 → CodeMirror 语言映射
|
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
|
@@ -37020,40 +37020,19 @@ window.__ModuleLoader__.load({
|
|
|
37020
37020
|
down. An 8px radius keeps it a rounded square rather than a full circle. */
|
|
37021
37021
|
.filex-header-btn{width:28px;height:28px;padding:0;border-radius:8px}
|
|
37022
37022
|
|
|
37023
|
-
/* ── hero ButtonGroup (
|
|
37024
|
-
/* The mode group shown
|
|
37023
|
+
/* ── hero ButtonGroup (hero.flex slot entry) ─────────────────────────── */
|
|
37024
|
+
/* The mode group shown on the hero / blank-session screen: the left
|
|
37025
37025
|
button carries the remembered mode's icon, the right chevron the mode
|
|
37026
37026
|
dropdown. Outer corners use the same rounded-rectangle radius as the
|
|
37027
37027
|
header buttons (8px on a 28px-tall button), so the group reads as one
|
|
37028
|
-
pill consistent with the session header icons.
|
|
37028
|
+
pill consistent with the session header icons. The host is the
|
|
37029
|
+
dsh-hero-flex plugin's hf-row (its own stylesheet); this sheet only
|
|
37030
|
+
styles the group itself. */
|
|
37029
37031
|
.filex-group{display:inline-flex;align-items:center;position:relative;height:28px}
|
|
37030
37032
|
.filex-group .filex-group-main,.filex-group .filex-group-trigger{height:28px}
|
|
37031
37033
|
.filex-group .filex-group-main{border-radius:8px 0 0 8px;padding:0 9px}
|
|
37032
37034
|
.filex-group .filex-group-trigger{margin-left:-1px;border-radius:0 8px 8px 0;border-left:0;padding:0 7px}
|
|
37033
37035
|
|
|
37034
|
-
/* ── header corner seat (new runtime) ────────────────────────────────── */
|
|
37035
|
-
/* The corner occupant: the hero ButtonGroup directly left of the right-
|
|
37036
|
-
sidebar expand button in one flex row — the same corner seat the shell's
|
|
37037
|
-
expand button occupies alone once the header chrome is shown, now shared
|
|
37038
|
-
with the plugin's open-actions group. The seat's own margin and the
|
|
37039
|
-
header's padding position the row at the far right of the blank header. */
|
|
37040
|
-
.filex-corner{display:flex;align-items:center;gap:8px}
|
|
37041
|
-
/* Re-painted expand button, same footprint as the shell's ExpandButton
|
|
37042
|
-
(28×28, 15px mirrored panel icon) but with a rounded-rectangle corner to
|
|
37043
|
-
match the editor button beside it; visible only while the panel is
|
|
37044
|
-
collapsed. */
|
|
37045
|
-
.filex-corner-expand{width:28px;height:28px;color:var(--dsw-alias-label-secondary,#9ca3af);cursor:pointer;background:transparent;border:none;border-radius:8px;flex:none;justify-content:center;align-items:center;padding:6px;display:inline-flex}
|
|
37046
|
-
.filex-corner-expand:hover{background:var(--dsw-alias-interactive-bg-hover,rgba(128,128,128,.15))}
|
|
37047
|
-
.filex-corner-expand-icon{transform:scaleX(-1)}
|
|
37048
|
-
|
|
37049
|
-
/* ── hero floating utility (shell.overlay entry) ─────────────────────── */
|
|
37050
|
-
/* The ButtonGroup, pinned by the plugin to the conversation column's
|
|
37051
|
-
top-right while the column is in its hero phase. The shell.overlay layer
|
|
37052
|
-
is click-through by design, so the entry opts back into pointer events;
|
|
37053
|
-
no explicit z-index keeps it below sibling overlay entries (modal,
|
|
37054
|
-
notices) and any body-portaled popup. */
|
|
37055
|
-
.filex-hero-fab{position:fixed;pointer-events:auto}
|
|
37056
|
-
|
|
37057
37036
|
/* ── transient notice strip ──────────────────────────────────────────── */
|
|
37058
37037
|
.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}
|
|
37059
37038
|
.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}
|
|
@@ -38075,19 +38054,17 @@ window.__ModuleLoader__.load({
|
|
|
38075
38054
|
*
|
|
38076
38055
|
* The in-chat session header (`conversation.session.header.utilities`) keeps
|
|
38077
38056
|
* a single built-in-editor icon: clicking it opens the file-explorer modal
|
|
38078
|
-
* (preview / edit).
|
|
38079
|
-
* plugin itself through the generic `shell.overlay` layer carries the full
|
|
38080
|
-
* ButtonGroup — the left button performs the remembered open action
|
|
38081
|
-
* (内置编辑器 / 系统文件夹 / VS Code) and the right chevron opens a dropdown
|
|
38082
|
-
* to switch between them. Selecting an entry both persists it as the new
|
|
38083
|
-
* default and immediately runs that action.
|
|
38057
|
+
* (preview / edit).
|
|
38084
38058
|
*
|
|
38085
|
-
* The
|
|
38086
|
-
*
|
|
38087
|
-
*
|
|
38088
|
-
*
|
|
38089
|
-
*
|
|
38090
|
-
*
|
|
38059
|
+
* The hero / blank-session open-actions ButtonGroup (编辑器 / 系统文件夹 /
|
|
38060
|
+
* VS Code) renders ONLY through the `hero.flex` slot declared by the
|
|
38061
|
+
* dsh-hero-flex plugin, which owns the header's corner seat at priority -1
|
|
38062
|
+
* and hosts the additive flex row beside the right-sidebar expand button.
|
|
38063
|
+
* Without dsh-hero-flex installed the ButtonGroup does not render at all —
|
|
38064
|
+
* this plugin no longer occupies the corner seat nor floats a fallback
|
|
38065
|
+
* overlay. The left button performs the remembered open action and the right
|
|
38066
|
+
* chevron opens a dropdown to switch between them; selecting an entry both
|
|
38067
|
+
* persists it as the new default and immediately runs that action.
|
|
38091
38068
|
*
|
|
38092
38069
|
* Session binding: every /filex request is conversation-scoped, so the modal
|
|
38093
38070
|
* must know WHICH session it belongs to — the host resolves the workspace
|
|
@@ -38352,21 +38329,20 @@ window.__ModuleLoader__.load({
|
|
|
38352
38329
|
}
|
|
38353
38330
|
/**
|
|
38354
38331
|
* The hero ButtonGroup: the left button carries the remembered mode's icon and
|
|
38355
|
-
* runs its action, the right chevron opens the mode dropdown. Rendered
|
|
38356
|
-
*
|
|
38357
|
-
*
|
|
38332
|
+
* runs its action, the right chevron opens the mode dropdown. Rendered only
|
|
38333
|
+
* through the `hero.flex` slot declared by the dsh-hero-flex plugin (hero /
|
|
38334
|
+
* blank-session header) — the in-chat header keeps the single built-in-editor
|
|
38358
38335
|
* `HeaderIcon`.
|
|
38359
38336
|
*
|
|
38360
|
-
* `sessionId`
|
|
38361
|
-
*
|
|
38362
|
-
*
|
|
38337
|
+
* `sessionId` comes from the slot's session standard kit; without it the
|
|
38338
|
+
* actions fall back to the live selection (`useSessions` → `state.current`)
|
|
38339
|
+
* and show a notice when none exists.
|
|
38363
38340
|
*/
|
|
38364
38341
|
function HeroGroup(props) {
|
|
38365
38342
|
const state = (0, react.useSyncExternalStore)(subscribe, getSnapshot);
|
|
38366
38343
|
const [menuOpen, setMenuOpen] = (0, react.useState)(false);
|
|
38367
38344
|
const useSessions = props.useSessions ?? (() => void 0);
|
|
38368
|
-
const
|
|
38369
|
-
const sessionId = props.sessionId ?? current;
|
|
38345
|
+
const sessionId = props.sessionId;
|
|
38370
38346
|
const sessionCwd = useSessions((s) => sessionId !== void 0 ? s.byId?.[sessionId]?.cwd : void 0);
|
|
38371
38347
|
const mode = state.mode;
|
|
38372
38348
|
const items = state.vscode ? MODE_ITEMS : MODE_ITEMS.filter((item) => item.id !== "vscode");
|
|
@@ -38426,163 +38402,6 @@ window.__ModuleLoader__.load({
|
|
|
38426
38402
|
})
|
|
38427
38403
|
});
|
|
38428
38404
|
}
|
|
38429
|
-
/**
|
|
38430
|
-
* Corner expand button re-painted beside the explorer ButtonGroup while this
|
|
38431
|
-
* plugin occupies the header's corner seat. Matches the shell's `ExpandButton`
|
|
38432
|
-
* (28×28, mirrored panel icon, tooltip); the toggle goes through the
|
|
38433
|
-
* cross-plugin `sidebarRight` face. Hides itself while the panel is open,
|
|
38434
|
-
* exactly like the shipped button — the DOM probe (`data-sidebar-right-open`)
|
|
38435
|
-
* is the same attribute the shell's panel root carries, so it tracks even
|
|
38436
|
-
* opens that did not come from this button.
|
|
38437
|
-
*/
|
|
38438
|
-
function CornerExpandButton(props) {
|
|
38439
|
-
const [expanded, setExpanded] = (0, react.useState)(false);
|
|
38440
|
-
(0, react.useEffect)(() => {
|
|
38441
|
-
const probe = () => {
|
|
38442
|
-
setExpanded(document.querySelector("[data-sidebar-right-open]") !== null);
|
|
38443
|
-
};
|
|
38444
|
-
probe();
|
|
38445
|
-
const observer = new MutationObserver(probe);
|
|
38446
|
-
observer.observe(document.body, {
|
|
38447
|
-
childList: true,
|
|
38448
|
-
subtree: true,
|
|
38449
|
-
attributes: true,
|
|
38450
|
-
attributeFilter: ["data-sidebar-right-open"]
|
|
38451
|
-
});
|
|
38452
|
-
window.addEventListener("resize", probe);
|
|
38453
|
-
return () => {
|
|
38454
|
-
observer.disconnect();
|
|
38455
|
-
window.removeEventListener("resize", probe);
|
|
38456
|
-
};
|
|
38457
|
-
}, []);
|
|
38458
|
-
if (expanded) return null;
|
|
38459
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
38460
|
-
label: "展开右侧栏",
|
|
38461
|
-
side: "bottom",
|
|
38462
|
-
delayMs: 500,
|
|
38463
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
38464
|
-
type: "button",
|
|
38465
|
-
className: "filex-corner-expand",
|
|
38466
|
-
"aria-label": "展开右侧栏",
|
|
38467
|
-
"data-sidebar-right-expand": "",
|
|
38468
|
-
onClick: () => {
|
|
38469
|
-
props.sidebar.toggleExpanded();
|
|
38470
|
-
},
|
|
38471
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPanelLeftOutline16, { className: "filex-corner-expand-icon" })
|
|
38472
|
-
})
|
|
38473
|
-
});
|
|
38474
|
-
}
|
|
38475
|
-
/**
|
|
38476
|
-
* The header's corner seat while the new-session header chrome is blank: the
|
|
38477
|
-
* explorer ButtonGroup sits directly left of the expand button — the same
|
|
38478
|
-
* corner seat, one flex row, no floating layer, no measuring. In a session
|
|
38479
|
-
* with records the `utilities` seat renders (where the editor icon lives), so
|
|
38480
|
-
* only the expand button is re-painted here; the DOM probe keeps the pair
|
|
38481
|
-
* from ever duplicating.
|
|
38482
|
-
*/
|
|
38483
|
-
function HeaderCornerGroup(props) {
|
|
38484
|
-
const [utilitiesPresent, setUtilitiesPresent] = (0, react.useState)(false);
|
|
38485
|
-
const [sidebar, setSidebar] = (0, react.useState)(void 0);
|
|
38486
|
-
(0, react.useEffect)(() => {
|
|
38487
|
-
let alive = true;
|
|
38488
|
-
let tries = 0;
|
|
38489
|
-
const read = () => {
|
|
38490
|
-
if (!alive) return;
|
|
38491
|
-
let value;
|
|
38492
|
-
try {
|
|
38493
|
-
value = ctxRef?.get?.("sidebarRight", false) ?? ctxRef?.sidebarRight;
|
|
38494
|
-
} catch {
|
|
38495
|
-
value = void 0;
|
|
38496
|
-
}
|
|
38497
|
-
if (value !== void 0) {
|
|
38498
|
-
setSidebar(value);
|
|
38499
|
-
return;
|
|
38500
|
-
}
|
|
38501
|
-
tries += 1;
|
|
38502
|
-
if (tries < 40) setTimeout(read, 250);
|
|
38503
|
-
};
|
|
38504
|
-
read();
|
|
38505
|
-
return () => {
|
|
38506
|
-
alive = false;
|
|
38507
|
-
};
|
|
38508
|
-
}, []);
|
|
38509
|
-
(0, react.useEffect)(() => {
|
|
38510
|
-
const probe = () => {
|
|
38511
|
-
setUtilitiesPresent(document.querySelector("[data-slot=\"conversation.session.header.utilities\"]") !== null);
|
|
38512
|
-
};
|
|
38513
|
-
probe();
|
|
38514
|
-
const observer = new MutationObserver(probe);
|
|
38515
|
-
observer.observe(document.body, {
|
|
38516
|
-
childList: true,
|
|
38517
|
-
subtree: true
|
|
38518
|
-
});
|
|
38519
|
-
return () => observer.disconnect();
|
|
38520
|
-
}, []);
|
|
38521
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38522
|
-
className: "filex-corner",
|
|
38523
|
-
children: [!utilitiesPresent && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HeroGroup, { sessionId: props.sessionId }), sidebar !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CornerExpandButton, { sidebar })]
|
|
38524
|
-
});
|
|
38525
|
-
}
|
|
38526
|
-
/**
|
|
38527
|
-
* Hero / new-session floating utility: the hero ButtonGroup, rendered by the
|
|
38528
|
-
* plugin itself through the generic `shell.overlay` floating layer (no shell
|
|
38529
|
-
* change needed) and pinned to the conversation column's top-right corner —
|
|
38530
|
-
* the spot where the session-header utilities sit once a conversation has
|
|
38531
|
-
* records. Shown only while the conversation column is in its `hero` phase
|
|
38532
|
-
* (no session at all, or a blank session whose header is deliberately
|
|
38533
|
-
* hidden); the position is measured from the rendered column root
|
|
38534
|
-
* (`[data-phase]`), so sidebar collapse and details-panel toggles are
|
|
38535
|
-
* tracked automatically. Clicking behaves exactly like the in-chat icon: in a
|
|
38536
|
-
* blank-session hero the actions bind to that session, and with no session
|
|
38537
|
-
* at all they surface the no-session notice.
|
|
38538
|
-
*
|
|
38539
|
-
* On the new runtime the corner seat carries the same ButtonGroup, so this
|
|
38540
|
-
* fallback hides itself the moment `.filex-corner` is rendered — the two
|
|
38541
|
-
* paths never overlap.
|
|
38542
|
-
*/
|
|
38543
|
-
function HeroFilexButton(props) {
|
|
38544
|
-
const [pos, setPos] = (0, react.useState)(null);
|
|
38545
|
-
(0, react.useEffect)(() => {
|
|
38546
|
-
const update = () => {
|
|
38547
|
-
if (document.querySelector(".filex-corner") !== null) {
|
|
38548
|
-
setPos(null);
|
|
38549
|
-
return;
|
|
38550
|
-
}
|
|
38551
|
-
const column = document.querySelector("[data-phase]");
|
|
38552
|
-
if (column === null || column.getAttribute("data-phase") !== "hero") {
|
|
38553
|
-
setPos(null);
|
|
38554
|
-
return;
|
|
38555
|
-
}
|
|
38556
|
-
const rect = column.getBoundingClientRect();
|
|
38557
|
-
if (rect.width === 0 || rect.height === 0) {
|
|
38558
|
-
setPos(null);
|
|
38559
|
-
return;
|
|
38560
|
-
}
|
|
38561
|
-
const top = rect.top + 14;
|
|
38562
|
-
const right = window.innerWidth - rect.right + 28;
|
|
38563
|
-
setPos((current) => current !== null && current.top === top && current.right === right ? current : {
|
|
38564
|
-
top,
|
|
38565
|
-
right
|
|
38566
|
-
});
|
|
38567
|
-
};
|
|
38568
|
-
const timer = window.setInterval(update, 400);
|
|
38569
|
-
window.addEventListener("resize", update);
|
|
38570
|
-
update();
|
|
38571
|
-
return () => {
|
|
38572
|
-
window.clearInterval(timer);
|
|
38573
|
-
window.removeEventListener("resize", update);
|
|
38574
|
-
};
|
|
38575
|
-
}, []);
|
|
38576
|
-
if (pos === null) return null;
|
|
38577
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
38578
|
-
className: "filex-hero-fab",
|
|
38579
|
-
style: {
|
|
38580
|
-
top: pos.top,
|
|
38581
|
-
right: pos.right
|
|
38582
|
-
},
|
|
38583
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HeroGroup, { useSessions: props.useSessions })
|
|
38584
|
-
});
|
|
38585
|
-
}
|
|
38586
38405
|
/** The overlay entry: keyboard shortcut + modal + transient notice. */
|
|
38587
38406
|
function ExplorerOverlay(props) {
|
|
38588
38407
|
const state = (0, react.useSyncExternalStore)(subscribe, getSnapshot);
|
|
@@ -38658,29 +38477,21 @@ window.__ModuleLoader__.load({
|
|
|
38658
38477
|
order: 10,
|
|
38659
38478
|
label: "文件预览 / 编辑"
|
|
38660
38479
|
}, HeaderIcon));
|
|
38661
|
-
ctx.slots.inject("shell.overlay", () => {
|
|
38662
|
-
|
|
38663
|
-
|
|
38664
|
-
|
|
38665
|
-
|
|
38666
|
-
|
|
38667
|
-
|
|
38668
|
-
|
|
38669
|
-
|
|
38670
|
-
|
|
38671
|
-
|
|
38672
|
-
|
|
38673
|
-
|
|
38674
|
-
|
|
38675
|
-
|
|
38676
|
-
heroFab();
|
|
38677
|
-
};
|
|
38678
|
-
});
|
|
38679
|
-
ctx.slots.inject("conversation.session.header.corner", () => ctx.slots.register({
|
|
38680
|
-
name: "conversation.session.header.corner",
|
|
38681
|
-
priority: -1,
|
|
38682
|
-
label: "文件预览 / 编辑(角落)"
|
|
38683
|
-
}, (props) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HeaderCornerGroup, { sessionId: props.sessionId })));
|
|
38480
|
+
ctx.slots.inject("shell.overlay", () => ctx.slots.register({
|
|
38481
|
+
name: "shell.overlay",
|
|
38482
|
+
id: "file-explorer-overlay",
|
|
38483
|
+
order: 100,
|
|
38484
|
+
label: "文件预览"
|
|
38485
|
+
}, ExplorerOverlay));
|
|
38486
|
+
ctx.slots.inject("hero.flex", () => ctx.slots.register({
|
|
38487
|
+
name: "hero.flex",
|
|
38488
|
+
id: "file-explorer",
|
|
38489
|
+
order: 10,
|
|
38490
|
+
label: "文件预览 / 编辑(hero)"
|
|
38491
|
+
}, (props) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HeroGroup, {
|
|
38492
|
+
sessionId: props.sessionId,
|
|
38493
|
+
useSessions: props.useSessions
|
|
38494
|
+
})));
|
|
38684
38495
|
probeVscode();
|
|
38685
38496
|
ctx.effect(() => {
|
|
38686
38497
|
const deps = {
|
|
@@ -111,22 +111,11 @@ export interface FilexSlotsService {
|
|
|
111
111
|
id?: string;
|
|
112
112
|
key?: string;
|
|
113
113
|
order?: number;
|
|
114
|
-
priority?: number;
|
|
115
114
|
label?: string | (() => string);
|
|
116
115
|
inject?: (...args: unknown[]) => Record<string, unknown>;
|
|
117
116
|
}, component: unknown): () => void;
|
|
118
117
|
inject(key: string, callback: () => () => void): () => void;
|
|
119
118
|
}
|
|
120
|
-
/**
|
|
121
|
-
* The cross-plugin right-sidebar face (`dsh-client-ui-sidebar-right` provides
|
|
122
|
-
* it as `ctx.sidebarRight`). Only the expand-toggle and expanded-state read
|
|
123
|
-
* are used here, to re-paint the header's corner expand button beside the
|
|
124
|
-
* explorer ButtonGroup while the plugin occupies the corner seat.
|
|
125
|
-
*/
|
|
126
|
-
export interface FilexSidebarRight {
|
|
127
|
-
isExpanded(): boolean;
|
|
128
|
-
toggleExpanded(): void;
|
|
129
|
-
}
|
|
130
119
|
declare module 'cordis' {
|
|
131
120
|
interface Context {
|
|
132
121
|
webServer: FilexWebServer;
|
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": "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.9",
|
|
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": "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
|
+
}
|