@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 CHANGED
@@ -5,12 +5,14 @@
5
5
  ## 功能
6
6
 
7
7
  - **聊天页标题栏图标**(`conversation.session.header.utilities`):一个内置编辑器图标,点击打开文件预览 / 编辑弹窗(聊天页保持与现状一致,无下拉)
8
- - **Hero / 新建会话页 ButtonGroup**:同一浮层位置由插件定位到会话列右上角(hero 阶段显示,有记录后由标题栏图标接管,无重复);hero 上为**左主按钮 + 右下拉**的组合:
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
- - 纯插件实现,不改动框架代码(详见 `docs/hero-filex-button.md`)
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 + overlay 弹窗 + Ctrl+P 快捷键
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 (shell.overlay entry) ──────────────────────────── */
37024
- /* The mode group shown only on the hero / new-session screen: the left
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). The hero / new-session floating utility rendered by the
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 floating entry pins itself to the conversation column's top-right
38086
- * while the column is in its hero phase — the no-session hero and the
38087
- * blank-session (new chat) hero, where the session header and its utilities
38088
- * seat are absent or deliberately hidden. It resolves its session itself:
38089
- * the actions fall back to the live selection (`useSessions` →
38090
- * `state.current`) and show a notice when none exists.
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 on the
38356
- * hero / new-session screen (both the corner seat on the new runtime and the
38357
- * floating fallback) — the in-chat header keeps the single built-in-editor
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` is optional: the corner seat supplies it from the session
38361
- * standard kit; the floating fallback (root-scoped overlay) resolves it from
38362
- * `useSessions` → `state.current` instead.
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 current = useSessions((s) => s.current);
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
- const overlay = ctx.slots.register({
38663
- name: "shell.overlay",
38664
- id: "file-explorer-overlay",
38665
- order: 100,
38666
- label: "文件预览"
38667
- }, ExplorerOverlay);
38668
- const heroFab = ctx.slots.register({
38669
- name: "shell.overlay",
38670
- id: "file-explorer-hero-fab",
38671
- order: 90,
38672
- label: "文件预览 / 编辑(hero)"
38673
- }, HeroFilexButton);
38674
- return () => {
38675
- overlay();
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.8",
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
+ }