@yiln-dsh/dsh-plugin-file-explorer 0.4.1 → 0.5.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.
Files changed (3) hide show
  1. package/README.md +18 -27
  2. package/client.js +74 -278
  3. package/package.json +5 -3
package/README.md CHANGED
@@ -1,17 +1,17 @@
1
1
  # @yiln-dsh/dsh-plugin-file-explorer
2
2
 
3
- A DSH `dsh.bundle` that replaces the built-in **details** column of the Web
4
- GUI with a workspace file explorer.
3
+ A DSH `dsh.bundle` that contributes a workspace file explorer page to the
4
+ `@yiln-dsh/dsh-plugin-right-panel` host.
5
5
 
6
- - Replaces the built-in tool-details right column while the bundle row is
7
- mounted (it is restored automatically when the plugin is disabled/removed).
8
- - Auto-opens when a conversation (non-blank session) starts.
9
- - **Files** tab: lists the active session's workspace directory, with folder
6
+ - Registers two independent right-panel pages: **Files** and **Git Graph**. The
7
+ host owns the right-column layout, navigation rail, width, and collapse
8
+ behavior.
9
+ - **Files** page: lists the active session's workspace directory, with folder
10
10
  navigation, editable path input, parent/refresh buttons, file and folder
11
11
  icons, and file sizes. File rows reveal view / download / delete buttons on
12
12
  hover; delete uses a second-click confirm. Image View supports fullscreen,
13
13
  25%-400% zoom, wheel zoom, and drag-to-pan after zooming.
14
- - **Git Graph** tab: a vscode/le-git-graph style commit graph rendered from
14
+ - **Git Graph** page: a vscode/le-git-graph style commit graph rendered from
15
15
  the repository containing the current directory —
16
16
  - colored lane graph with commit dots and merge curves (all branches or the
17
17
  current branch, refreshable),
@@ -22,34 +22,26 @@ GUI with a workspace file explorer.
22
22
  A/M/D/R status badges,
23
23
  - click a file to open its diff patch (commit shows `git show`, working tree
24
24
  shows `git diff HEAD`) in a dialog.
25
- - The column is a real layout column: it squeezes the conversation and its
26
- width can be dragged between 300–520px with the native splitter handle.
27
- - The chosen width persists across sessions and page reloads (localStorage):
28
- the plugin captures the shell layout store actions when the root entry wires
29
- them, restores the saved width right after `openDetails()`, and saves the
30
- column width after every resizer drag.
31
- - **Collapse to icon bar**: the collapse button matches the DSH session
32
- menu's circular panel-toggle style, with the direction mirrored for the
33
- right-side column. Clicking it keeps a real 56px rail in the layout with
34
- **Files** and **Git Graph** icons; clicking either reopens that tab at the
35
- last chosen width. The rail is not a floating overlay, and the panel state
36
- is preserved.
25
+ - The host keeps a real 56px right-edge icon rail when collapsed. Other
26
+ right-panel pages can appear alongside Files and overflow into the host's
27
+ searchable More menu.
37
28
 
38
29
  ## Layout
39
30
 
40
31
  | File | Content |
41
32
  | --- | --- |
42
33
  | `index.js` | Host half: registers exact `/ _dsh/file-explorer/*` routes backed by the Host `fs`/`subprocess` services, plus read-only git routes (`/ _dsh/file-explorer/git-log`, `git-commit`, `git-diff`, `git-status`) that run `git` with machine-readable separators and return JSON only. |
43
- | `client.js` | Client half: a static DSH client module registered into the `details` slot; Files + Git Graph tabs. |
34
+ | `client.js` | Client half: registers independent keyed `right-panel.page` entries for Files and Git Graph. |
44
35
  | `cordis.patch.yml` | Composition patch that mounts the host row — declared with `inject: [webServer]`, so it activates only after the stock webserver service (`127.0.0.1`) is up. |
45
36
 
46
37
  ## Install
47
38
 
48
- The package version is `@yiln-dsh/dsh-plugin-file-explorer@0.4.1`.
39
+ The package version is `@yiln-dsh/dsh-plugin-file-explorer@0.5.0`.
49
40
 
50
- ### Local source directory
41
+ The right-panel package must be installed in the same `web` profile:
51
42
 
52
43
  ```bash
44
+ dsh plugin --profile web add file:/path/to/dsh-plugin-right-panel
53
45
  dsh plugin --profile web add file:/path/to/dsh-plugin-file-explorer
54
46
  ```
55
47
 
@@ -61,7 +53,7 @@ pnpm pack
61
53
  ```
62
54
 
63
55
  ```bash
64
- dsh plugin --profile web add ./yiln-dsh-dsh-plugin-file-explorer-0.4.1.tgz
56
+ dsh plugin --profile web add ./yiln-dsh-dsh-plugin-file-explorer-0.5.0.tgz
65
57
  ```
66
58
 
67
59
  ### npm package
@@ -98,7 +90,6 @@ apply the new profile composition.
98
90
  sentinel) and file paths against a non-option, non-control-character check.
99
91
  - Rows have a fixed 34px height, so the hover action swap never changes the
100
92
  row height; directories reveal a delete-only action set on hover.
101
- - The browser module uses the `details` slot (scope: session), registering at
102
- priority `-6` to shadow the built-in tool-details occupant (priority `0`),
103
- the `layout` service (`openDetails` / `closeDetails`), the standard
104
- `useSessions` hook, and its own stylesheet.
93
+ - The browser module registers `file-explorer.files` and
94
+ `file-explorer.git` into the keyed `right-panel.page` Slot and uses the
95
+ standard session `useSessions` hook.
package/client.js CHANGED
@@ -1,11 +1,10 @@
1
1
  /**
2
2
  * dsh-plugin-file-explorer — browser bundle (static DSH client module).
3
3
  *
4
- * Renders the file explorer into the `details` slot (right layout column),
5
- * replacing the native tool-details panel while running. The column squeezes
6
- * the conversation and keeps the native resizer handle.
4
+ * Registers the file explorer as a page in the `right-panel` host. The host
5
+ * owns the right layout column, width, navigation rail, and page switching.
7
6
  *
8
- * Two views behind the header tabs:
7
+ * Two views behind the page's local tabs:
9
8
  * - Files: directory browser (list / read / download / delete via the
10
9
  * /_dsh/file-explorer API).
11
10
  * - Git Graph: a vscode/git-graph style commit DAG with colored lanes, ref
@@ -20,12 +19,12 @@ window.__ModuleLoader__.load({
20
19
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
21
20
  let React = require("react");
22
21
 
23
- const inject = ["slots", "layout"];
22
+ const inject = ["slots", "rightPanel"];
24
23
 
25
24
  function apply(ctx) {
26
25
  const slots = ctx.get('slots')
27
- const layout = ctx.get('layout')
28
- if (slots === undefined) return
26
+ const rightPanel = ctx.get('rightPanel')
27
+ if (slots === undefined || rightPanel === undefined) return
29
28
 
30
29
  const style = document.createElement("style");
31
30
  style.id = "dsh-plugin-file-explorer-style";
@@ -77,35 +76,6 @@ window.__ModuleLoader__.load({
77
76
  .dsh-fe-icon:hover {
78
77
  background: var(--dsw-alias-interactive-bg-hover, var(--dsw-alias-bg-layer-2, #e7e5e4));
79
78
  }
80
- .dsh-fe-tabs {
81
- display: flex;
82
- gap: 2px;
83
- padding: 8px 12px 0;
84
- }
85
- .dsh-fe-tab {
86
- flex: 1 1 0;
87
- height: 26px;
88
- border: 0;
89
- border-radius: 6px;
90
- background: transparent;
91
- color: var(--dsw-alias-label-secondary, #4b5563);
92
- cursor: pointer;
93
- font: inherit;
94
- font-size: 12px;
95
- display: inline-flex;
96
- align-items: center;
97
- justify-content: center;
98
- gap: 6px;
99
- }
100
- .dsh-fe-tab:hover {
101
- background: var(--dsw-alias-bg-layer-2, #e7e5e4);
102
- }
103
- .dsh-fe-tab-active,
104
- .dsh-fe-tab-active:hover {
105
- background: var(--dsw-alias-bg-layer-2, #e7e5e4);
106
- color: var(--dsw-alias-label-primary, #111827);
107
- font-weight: 600;
108
- }
109
79
  .dsh-fe-path {
110
80
  min-width: 0;
111
81
  margin: 8px 12px 0;
@@ -587,154 +557,19 @@ window.__ModuleLoader__.load({
587
557
  font-size: 12px;
588
558
  unicode-bidi: plaintext;
589
559
  }
590
- .dsh-fe-rail {
560
+ .dsh-fe-page {
591
561
  height: 100%;
592
- width: 100%;
593
- box-sizing: border-box;
562
+ min-height: 0;
594
563
  display: flex;
595
564
  flex-direction: column;
596
- align-items: center;
597
- gap: 6px;
598
- padding: 10px 6px;
565
+ box-sizing: border-box;
566
+ overflow: hidden;
599
567
  background: var(--dsw-specific-sidebar-fill, var(--dsw-alias-bg-base, #f5f5f4));
600
- border-left: 1px solid var(--dsw-alias-border-l2, rgba(0, 0, 0, 0.16));
601
- }
602
- /* While collapsed, keep a real RAIL_WIDTH column in the layout (like the left
603
- sidebar's 56px rail) instead of a floating overlay. This !important rule
604
- overrides React's inline grid-template-columns on the app frame; the data
605
- attribute is added by applyRail() and removed on expand/unload. */
606
- [data-dsh-fe-rail] {
607
- grid-template-columns: var(--dsh-fe-rail-sidebar, 280px) minmax(0, 1fr) 56px !important;
608
- }
609
- .dsh-fe-rail-button {
610
- width: 36px;
611
- height: 36px;
612
- border: 0;
613
- border-radius: 8px;
614
- background: transparent;
615
- color: var(--dsw-alias-label-secondary, #4b5563);
616
- cursor: pointer;
617
- display: inline-flex;
618
- align-items: center;
619
- justify-content: center;
620
- }
621
- .dsh-fe-rail-button:hover {
622
- background: var(--dsw-alias-bg-layer-2, #e7e5e4);
623
- color: var(--dsw-alias-brand-primary, #4f46e5);
568
+ color: var(--dsw-alias-label-primary, #111827);
624
569
  }
625
570
  `;
626
571
  document.head.append(style);
627
572
 
628
- // --- details-column width persistence ---------------------------------
629
- // The shell's layout store is transient: openDetails() resets the column
630
- // to its 360px contract default on every mount and session switch. The
631
- // bound store actions reach the LayoutController after every client
632
- // module has applied (the root entry's inject hook fires on first
633
- // render and again on re-register), so wrapping attachPanels on the
634
- // prototype captures them reliably. setDetails then restores the last
635
- // user-chosen width, and a document-level pointerup listener persists
636
- // the column width after each resizer drag.
637
- const WIDTH_KEY = "dsh-plugin-file-explorer.detailsWidth";
638
- const WIDTH_MIN = 300; // the layout contract's clamp floor
639
- let panelActions = null;
640
- let savedWidth = 0;
641
- try { savedWidth = Number(window.localStorage.getItem(WIDTH_KEY)) || 0 } catch (_e) { }
642
-
643
- const findDetailsColumn = () => {
644
- // The details column's own class is the reliable anchor: the drag
645
- // handle's previousElementSibling is the sidebar handle or the
646
- // overlay layer, never the column itself.
647
- const byClass = document.querySelector('[class*="detailsCol"]')
648
- if (byClass !== null) return byClass
649
- const handle = document.querySelector('[data-side="details"]')
650
- if (handle !== null && handle.previousElementSibling !== null) return handle.previousElementSibling
651
- return null
652
- }
653
- const persistWidth = () => {
654
- const column = findDetailsColumn()
655
- if (column === null) return
656
- const width = Math.round(column.getBoundingClientRect().width)
657
- if (width < WIDTH_MIN) return
658
- savedWidth = width
659
- try { window.localStorage.setItem(WIDTH_KEY, String(width)) } catch (_e) { }
660
- }
661
- const onDocumentPointerUp = () => { persistWidth() }
662
- document.addEventListener("pointerup", onDocumentPointerUp, true)
663
- ctx.effect(() => () => document.removeEventListener("pointerup", onDocumentPointerUp, true))
664
-
665
- if (layout !== undefined) {
666
- const proto = Object.getPrototypeOf(layout)
667
- if (proto !== null && typeof proto.attachPanels === "function") {
668
- const originalAttach = proto.attachPanels
669
- proto.attachPanels = function (actions) {
670
- panelActions = actions
671
- return originalAttach.call(this, actions)
672
- }
673
- ctx.effect(() => () => { proto.attachPanels = originalAttach })
674
- }
675
- }
676
- const restoreWidth = () => {
677
- if (savedWidth < WIDTH_MIN) return
678
- if (panelActions === null || typeof panelActions.setDetails !== "function") return
679
- try { panelActions.setDetails(savedWidth) } catch (_e) { }
680
- }
681
-
682
- // --- collapsed rail as a real layout column --------------------------
683
- // The layout contract gives the sidebar a 56px rail when closed but
684
- // closes the details column to 0px (no rail). To collapse like the left
685
- // sidebar, keep the store closed (no drag handle / border) and force the
686
- // frame's third grid track to RAIL_WIDTH via an !important stylesheet
687
- // rule keyed on a data attribute we own. CSS !important beats React's
688
- // inline grid style, so there is no fight with React re-renders: set the
689
- // attribute to collapse, remove it to expand. A MutationObserver only
690
- // refreshes the sidebar-width variable (the first track) when the app
691
- // re-renders the frame.
692
- const RAIL_WIDTH = 56;
693
- let railActive = false;
694
- const frameOfDetails = () => {
695
- const column = findDetailsColumn();
696
- if (column === null || column.parentElement === null) return null;
697
- return column.parentElement;
698
- };
699
- const syncRailVar = () => {
700
- const frame = frameOfDetails();
701
- if (frame === null) return;
702
- const sideCol = frame.children.length > 0 ? frame.children[0] : null;
703
- const sidebarPx = sideCol !== null ? Math.round(sideCol.getBoundingClientRect().width) : 280;
704
- try { frame.style.setProperty("--dsh-fe-rail-sidebar", `${sidebarPx}px`) } catch (_e) { }
705
- };
706
- const applyRail = () => {
707
- const frame = frameOfDetails();
708
- if (frame === null) return;
709
- if (railActive) {
710
- frame.setAttribute("data-dsh-fe-rail", "");
711
- syncRailVar();
712
- } else {
713
- frame.removeAttribute("data-dsh-fe-rail");
714
- }
715
- };
716
- const releaseRail = () => {
717
- railActive = false;
718
- applyRail();
719
- };
720
- let railObserver = null;
721
- if (typeof MutationObserver === "function") {
722
- railObserver = new MutationObserver(() => {
723
- if (railActive) syncRailVar();
724
- });
725
- ctx.effect(() => {
726
- const frame = frameOfDetails();
727
- if (frame !== null) railObserver.observe(frame, { attributes: true, attributeFilter: ["style"] });
728
- return () => {
729
- railObserver?.disconnect();
730
- const frame = frameOfDetails();
731
- if (frame !== null) frame.removeAttribute("data-dsh-fe-rail");
732
- railActive = false;
733
- };
734
- });
735
- }
736
- // -----------------------------------------------------------------------
737
-
738
573
  async function api(method, payload) {
739
574
  const options = { headers: { "content-type": "application/json" } };
740
575
  options.method = "POST";
@@ -1331,7 +1166,7 @@ window.__ModuleLoader__.load({
1331
1166
  )
1332
1167
  }
1333
1168
 
1334
- function FileExplorerPanel(props) {
1169
+ function FileExplorerPage(props) {
1335
1170
  if (typeof props.useSessions !== 'function') return null
1336
1171
 
1337
1172
  const sessionId = props.useSessions((state) => {
@@ -1364,23 +1199,11 @@ window.__ModuleLoader__.load({
1364
1199
  const [imageDragging, setImageDragging] = React.useState(false)
1365
1200
  const imageDrag = React.useRef(null)
1366
1201
  const [pendingDelete, setPendingDelete] = React.useState(null)
1367
- const [view, setView] = React.useState('files')
1368
- const [collapsed, setCollapsed] = React.useState(false)
1369
-
1370
- React.useEffect(() => {
1371
- if (sessionId === undefined) return
1372
- setCollapsed(false)
1373
- if (layout !== undefined) {
1374
- try { layout.openDetails() } catch (_e) { }
1375
- }
1376
- // Same-tick store updates batch in React, so restoring right after
1377
- // openDetails() replaces the 360px default without a visible jump.
1378
- restoreWidth()
1379
- }, [sessionId])
1380
1202
 
1381
1203
  React.useEffect(() => {
1382
1204
  if (sessionId === undefined) {
1383
- releaseRail()
1205
+ setParentPath(null)
1206
+ setRequestPath('')
1384
1207
  return
1385
1208
  }
1386
1209
  setParentPath(null)
@@ -1432,34 +1255,6 @@ window.__ModuleLoader__.load({
1432
1255
  return aDir - bDir || a.name.localeCompare(b.name)
1433
1256
  })
1434
1257
  const isRoot = parentPath === null || parentPath === currentPath
1435
- // Collapse into a slim icon rail that keeps a real 56px column in
1436
- // the layout (like the left sidebar's rail): the details store stays
1437
- // closed (no drag handle / border), and applyRail() toggles the
1438
- // [data-dsh-fe-rail] attribute so the !important stylesheet rule
1439
- // overrides the frame's third grid track. A MutationObserver keeps
1440
- // the sidebar-width variable fresh across app re-renders.
1441
- const collapse = () => {
1442
- setCollapsed(true)
1443
- railActive = true
1444
- closePreview()
1445
- setPendingDelete(null)
1446
- setEditingPath(false)
1447
- if (layout !== undefined) {
1448
- try { layout.closeDetails() } catch (_e) { }
1449
- }
1450
- applyRail()
1451
- }
1452
- const expand = (nextView) => {
1453
- releaseRail()
1454
- setCollapsed(false)
1455
- setView(nextView)
1456
- if (layout !== undefined) {
1457
- try { layout.openDetails() } catch (_e) { }
1458
- }
1459
- // Same-tick store updates batch in React, so restoring right after
1460
- // openDetails() replaces the 360px default without a visible jump.
1461
- restoreWidth()
1462
- }
1463
1258
  const reload = () => { setPendingDelete(null); setReloadTick((tick) => tick + 1) }
1464
1259
  const startEditPath = () => {
1465
1260
  setDraftPath(currentPath)
@@ -1678,65 +1473,13 @@ window.__ModuleLoader__.load({
1678
1473
  ),
1679
1474
  )
1680
1475
 
1681
- // Collapsed: a slim icon rail (file / git) that keeps a real 56px
1682
- // column in the layout (the [data-dsh-fe-rail] !important grid rule;
1683
- // see applyRail above), mirroring the left sidebar's collapsed rail.
1684
- // Placed after every handler declaration: a collapsed render must not
1685
- // return early and leave `expand` uninitialized (TDZ error on click).
1686
- if (collapsed) {
1687
- return React.createElement('div', {
1688
- className: 'dsh-fe-rail',
1689
- role: 'region',
1690
- 'aria-label': 'File explorer (collapsed)',
1691
- },
1692
- React.createElement('button', {
1693
- type: 'button',
1694
- className: 'dsh-fe-rail-button',
1695
- onClick: () => expand('files'),
1696
- title: 'Files',
1697
- 'aria-label': 'Open file explorer',
1698
- }, svgIcon(folderIcon, 16)),
1699
- React.createElement('button', {
1700
- type: 'button',
1701
- className: 'dsh-fe-rail-button',
1702
- onClick: () => expand('git'),
1703
- title: 'Git Graph',
1704
- 'aria-label': 'Open git graph',
1705
- }, svgIcon(branchIcon, 16)),
1706
- )
1707
- }
1708
-
1709
1476
  return React.createElement(React.Fragment, null,
1710
1477
  React.createElement('div', {
1711
- className: 'dsh-fe-panel',
1478
+ className: 'dsh-fe-page',
1712
1479
  role: 'region',
1713
- 'aria-label': 'File explorer',
1480
+ 'aria-label': 'Files',
1714
1481
  },
1715
- React.createElement('div', { className: 'dsh-fe-header' },
1716
- React.createElement('button', {
1717
- type: 'button',
1718
- className: 'dsh-fe-icon',
1719
- onClick: collapse,
1720
- 'aria-label': 'Collapse file explorer into icon bar',
1721
- title: 'Collapse',
1722
- }, collapseIcon),
1723
- React.createElement('div', { className: 'dsh-fe-title' }, view === 'git' ? 'Git Graph' : 'Files'),
1724
- ),
1725
- React.createElement('div', { className: 'dsh-fe-tabs' },
1726
- React.createElement('button', {
1727
- type: 'button',
1728
- className: 'dsh-fe-tab' + (view === 'files' ? ' dsh-fe-tab-active' : ''),
1729
- onClick: () => setView('files'),
1730
- }, svgIcon(folderIcon, 13), 'Files'),
1731
- React.createElement('button', {
1732
- type: 'button',
1733
- className: 'dsh-fe-tab' + (view === 'git' ? ' dsh-fe-tab-active' : ''),
1734
- onClick: () => setView('git'),
1735
- }, svgIcon(branchIcon, 13), 'Git Graph'),
1736
- ),
1737
- view === 'git'
1738
- ? React.createElement(GitGraphView, { api, cwd })
1739
- : filesView,
1482
+ filesView,
1740
1483
  ),
1741
1484
  preview &&
1742
1485
  React.createElement('div', {
@@ -1835,10 +1578,63 @@ window.__ModuleLoader__.load({
1835
1578
  )
1836
1579
  }
1837
1580
 
1838
- ctx.effect(() => slots.inject('details', () => slots.register(
1839
- { name: 'details', priority: -6 },
1840
- FileExplorerPanel,
1841
- )))
1581
+ function FileExplorerGitPage(props) {
1582
+ if (typeof props.useSessions !== 'function') return null
1583
+
1584
+ const sessionId = props.useSessions((state) => {
1585
+ const current = state.current
1586
+ if (current === undefined) return undefined
1587
+ const row = state.byId[current]
1588
+ if (!row || row.blank === true) return undefined
1589
+ return current
1590
+ })
1591
+ const cwd = props.useSessions((state) => {
1592
+ const current = state.current
1593
+ if (current === undefined) return undefined
1594
+ const row = state.byId[current]
1595
+ return row ? row.cwd : undefined
1596
+ })
1597
+
1598
+ if (sessionId === undefined) return null
1599
+ return React.createElement('div', {
1600
+ className: 'dsh-fe-page',
1601
+ role: 'region',
1602
+ 'aria-label': 'Git Graph',
1603
+ }, React.createElement(GitGraphView, { api, cwd }))
1604
+ }
1605
+
1606
+ ctx.effect(() => {
1607
+ const disposeFilesPage = rightPanel.registerPage({
1608
+ id: 'file-explorer.files',
1609
+ title: 'Files',
1610
+ group: 'Workspace',
1611
+ order: 20,
1612
+ placement: 'rail',
1613
+ icon: (size) => svgIcon(folderIcon, size),
1614
+ })
1615
+ const disposeGitPage = rightPanel.registerPage({
1616
+ id: 'file-explorer.git',
1617
+ title: 'Git Graph',
1618
+ group: 'Workspace',
1619
+ order: 21,
1620
+ placement: 'rail',
1621
+ icon: (size) => svgIcon(branchIcon, size),
1622
+ })
1623
+ const disposeFilesSlot = slots.inject('right-panel.page', () => slots.register({
1624
+ name: 'right-panel.page',
1625
+ key: 'file-explorer.files',
1626
+ }, FileExplorerPage))
1627
+ const disposeGitSlot = slots.inject('right-panel.page', () => slots.register({
1628
+ name: 'right-panel.page',
1629
+ key: 'file-explorer.git',
1630
+ }, FileExplorerGitPage))
1631
+ return () => {
1632
+ disposeFilesSlot()
1633
+ disposeGitSlot()
1634
+ disposeFilesPage()
1635
+ disposeGitPage()
1636
+ }
1637
+ })
1842
1638
  }
1843
1639
 
1844
1640
  exports.apply = apply;
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@yiln-dsh/dsh-plugin-file-explorer",
3
- "version": "0.4.1",
3
+ "version": "0.5.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "description": "DSH bundle plugin that replaces the Web GUI details column with a workspace file explorer.",
7
+ "description": "DSH bundle plugin that contributes a workspace file explorer page to the right-panel host.",
8
8
  "type": "module",
9
9
  "main": "index.js",
10
10
  "exports": {
@@ -18,6 +18,7 @@
18
18
  },
19
19
  "client": {
20
20
  "inject": [
21
+ "@yiln-dsh/dsh-plugin-right-panel",
21
22
  "@deepseek-ai/dsh-client-runtime",
22
23
  "@deepseek-ai/dsh-client-ui-layout",
23
24
  "@deepseek-ai/dsh-client-ui-renderer"
@@ -35,7 +36,8 @@
35
36
  "@deepseek-ai/cordis": ">=4.0.0",
36
37
  "@deepseek-ai/dsh-client-runtime": ">=0.1.0-rc.0",
37
38
  "@deepseek-ai/dsh-client-ui-layout": ">=0.1.0-rc.0",
38
- "@deepseek-ai/dsh-client-ui-renderer": ">=0.1.0-rc.0"
39
+ "@deepseek-ai/dsh-client-ui-renderer": ">=0.1.0-rc.0",
40
+ "@yiln-dsh/dsh-plugin-right-panel": ">=0.1.0"
39
41
  },
40
42
  "engines": {
41
43
  "node": ">=22"