dsh-flyout-sidebar 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Qinyun Cai
4
+ Copyright (c) 2026 oxlyn
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,149 @@
1
+ # dsh-flyout-sidebar
2
+
3
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](#license)
4
+
5
+ > DeepSeek Harness (DSH) 插件:可弹出式侧边栏——文件树 + Git 未提交变更列表,点击文件即可多标签预览,并可弹出为独立浏览器标签页。
6
+ >
7
+ > 中文 | [EN](README_EN.md)
8
+
9
+ ## 安装 / Install
10
+
11
+ ### 源码安装(GitHub)
12
+
13
+ ```sh
14
+ dsh plugin --profile web add github:oxlyn/dsh-flyout-sidebar
15
+ ```
16
+
17
+ ### 本地安装(开发)
18
+
19
+ ```sh
20
+ git clone https://github.com/oxlyn/dsh-flyout-sidebar.git
21
+ cd dsh-flyout-sidebar
22
+ npm install
23
+ npm run build # tsdown → dist/index.js + dist/client.js
24
+
25
+ # 在插件的父目录执行(dsh plugin add 的相对路径锚定调用目录):
26
+ cd ..
27
+ dsh plugin --profile web add ./dsh-flyout-sidebar # 符号链接安装;改 src/ 后 npm run build 并重启 dsh web 即可生效
28
+ dsh web
29
+ ```
30
+
31
+ ### 验证 / Verify
32
+
33
+ 装完**重启 `dsh web`** 并**硬刷新浏览器**(Cmd/Ctrl+Shift+R),界面右上角应出现常驻侧边栏图标按钮(无会话时也可见)。也可验证配置层:
34
+
35
+ ```sh
36
+ dsh --profile web --dump-config | grep dsh-flyout-sidebar # 配置层含本行
37
+ ```
38
+
39
+ ## 功能 / Features
40
+
41
+ | # | 形式 | 入口 | 说明 |
42
+ |---|------|------|------|
43
+ | 1 | 文件树视图(默认) | 面板打开即见 | 浏览当前工作区目录,懒加载展开、目录优先排序,实时跟随工作区/会话切换重新定位根目录 |
44
+ | 2 | Git 变更视图 | 面板右上角 git 分支图标 | 列出已变更未提交文件(`M`/`A`/`D`/`R`/`U` 徽章,悬停显示已暂存/未暂存,重命名显示原路径);点击文件显示相对 HEAD 的着色 unified diff,未跟踪文件自动合成新文件 diff |
45
+ | 3 | 多标签预览 | 点击文件 | 预览覆盖层盖住侧边栏左侧整个区域,可同时打开多个文件;按扩展名自动语法高亮,另支持 Markdown 渲染、图片、PDF、HTML 沙箱 iframe;⇥ 收起整个预览(标签保留,点文件恢复) |
46
+ | 4 | 弹出独立标签页 | 面板左上角 ↗ | 弹出为 `/flyout-sidebar` 独立网页,可拖到另一显示器;内容在左/面板在右,面板左右位置一键切换、宽度可拖动(默认最小宽,记忆偏好) |
47
+
48
+ **特性一览:**
49
+
50
+ - Git 变更列表按工作区分桶缓存:首次请求同步等待真实结果,之后即时响应 + 后台刷新(agent 每次工具执行后 700ms 去抖刷新,另有 15s 兜底轮询覆盖 IDE 等带外修改)
51
+ - 切换项目/会话时自动清空全部预览标签,杜绝跨项目内容串显
52
+ - git 变更行与文件树行可一键复制路径,或把 `@path` 引用写入会话输入框
53
+ - 面板与弹出页实时跟随 DSH 浅色 / 深色主题(弹出页经 `localStorage` 同步,首屏即正确)
54
+ - 与其他 sidebar 插件兼容:其他侧边卡片打开时自动让位到其左侧,两者同时可见
55
+ - 弹出页无标题栏,垂直空间全部留给内容;状态(live / git error / offline)并入面板顶行
56
+
57
+ ## 设置 / Settings
58
+
59
+ DSH 设置面板(左下角 ⚙️)新增「**Flyout Sidebar**」选项卡:
60
+
61
+ | 设置 | 默认 | 说明 |
62
+ |---|---|---|
63
+ | 默认展开 | 开 | 页面加载后侧边栏默认展开;关闭则默认收起 |
64
+ | 自动刷新 | 开 | Git 变更视图打开时每 2s 轮询最新状态 |
65
+ | 文件树 | 开 | 显示文件树视图与视图切换图标;关闭后面板固定显示 Git 变更视图 |
66
+ | 最短面板宽度 | 20% | 面板最小宽度(占窗口宽度的百分比,20–60%);更宽可拖动面板左边缘调整 |
67
+
68
+ 设置保存在浏览器 `localStorage`(键 `dsh-flyout-sidebar:settings`),刷新后仍生效;弹出页的面板宽度/左右位置偏好分别存于 `dsh-flyout-sidebar:panelw` / `panelLeft`。
69
+
70
+ ## 实现方式 / How it works
71
+
72
+ 插件分为 host 侧与 client 侧两部分,使用 TypeScript + JSX 编写,由 **tsdown** 打包成两个单文件 bundle:
73
+
74
+ ```
75
+ ┌─ host 侧 src/index.ts → dist/index.js(Node 进程,ESM)─────────┐
76
+ │ - host/artifacts.ts 产物跟踪(write/edit + shell 快照 diff) │
77
+ │ - host/git.ts git status/diff(按工作区分桶缓存) │
78
+ │ git status --porcelain=v1 -z 变更列表 │
79
+ │ git diff HEAD -M -- <path> 着色 unified diff 文本 │
80
+ │ - host/workspace.ts 会话 → 工作区 cwd 解析(含缓存) │
81
+ │ - host/files.ts 文件树列目录 / 文本读取 │
82
+ │ - host/page.ts 独立弹出页 HTML(内联 shared 源码) │
83
+ │ - host/routes.ts ctx.webServer.register: │
84
+ │ GET /flyout-sidebar/gitstatus 变更列表 JSON │
85
+ │ GET /flyout-sidebar/gitdiff 单文件 diff JSON │
86
+ │ GET /flyout-sidebar/listdir 文件树目录列表 │
87
+ │ GET /flyout-sidebar/content 文本内容(代码预览) │
88
+ │ GET /flyout-sidebar/media 图片 / PDF 二进制 │
89
+ │ - tools/result 事件 → 700ms 去抖刷新对应工作区的状态缓存 │
90
+ └──────────────────────────────────────────────────────────────────┘
91
+ │ fetch
92
+ ┌─ client 侧 src/client/index.tsx → dist/client.js(浏览器 IIFE)──┐
93
+ │ - React 组件(classic JSX 经 h 工厂编译;React 由 DSH 的 │
94
+ │ __ModuleLoader__ factory(require) 运行时提供,bundle 不内嵌) │
95
+ │ - shell.overlay:右上角常驻图标按钮 + 侧边栏面板 │
96
+ │ - 文件树 ⇄ Git 变更视图切换;多标签预览覆盖层(左侧全区域) │
97
+ │ - settings.section:Flyout Sidebar 设置项 │
98
+ │ - localStorage 跨页同步:当前会话 id、主题、面板偏好 │
99
+ └──────────────────────────────────────────────────────────────────┘
100
+ ```
101
+
102
+ 技术要点:`tsdown.config.ts` 一个配置打包两端(host ESM / client IIFE),自定义 `?raw` 插件在构建期把 shared 源码内联进独立弹出页的经典 `<script>`、把 vendored pdf.js 内嵌进 host bundle(离线可用);shared 模块 `shared/ext.js`(预览类型)、`shared/highlight.js`(零依赖语法高亮)、`shared/markdown.js`(Markdown 渲染)以「可移植 JS + JSDoc 类型」书写,两端复用并随弹出页内联;host 依赖通过 `inject: ['webServer', 'sessionQuery', 'timer']` 声明。
103
+
104
+ ## 环境要求 / Requirements
105
+
106
+ - Node `>=20`(DSH 宿主要求)
107
+ - `git` 在 PATH 中,且工作区为 git 仓库(否则 Git 变更视图显示错误提示,文件树不受影响)
108
+ - 本地构建需要 devDependencies(`tsdown`、`typescript` 等;运行时零依赖)
109
+
110
+ ## 开发 / Development
111
+
112
+ ```sh
113
+ npm run build # tsdown 重新生成 dist/index.js 与 dist/client.js
114
+ npm run check # tsc --noEmit 类型检查(strict)
115
+ npm test # node:test smoke:host 路由/事件 + client 组件渲染 + 弹出页脚本
116
+ ```
117
+
118
+ > 建议安装提交前守护(一次即可):`ln -sf ../../scripts/precommit.sh .git/hooks/pre-commit`。每次 `git commit` 自动重建 bundle,产物与源码不同步会直接拦截提交。
119
+
120
+ 项目结构:
121
+
122
+ ```
123
+ dsh-flyout-sidebar/
124
+ ├── tsdown.config.ts # tsdown 构建:host/client 双 bundle + ?raw 内联插件
125
+ ├── src/index.ts # Host 入口(导出 name/inject/apply,ESM)
126
+ ├── dist/ # ⚙️ 构建产物:index.js(host)/ client.js(浏览器),勿手改
127
+ ├── src/shared/ # 两端共享可移植模块(JSDoc 类型,随弹出页内联):ext / markdown / highlight
128
+ ├── src/host/ # host 模块:types / artifacts / workspace / files / git / page(弹出页 HTML)/ routes(HTTP)
129
+ ├── src/client/ # client 模块(TSX):jsx(React 桥)/ runtime / store / styles / icons / preview / components
130
+ ├── src/vendor/pdfjs/ # vendored pdf.js(构建期内嵌,离线可用)
131
+ ├── test/ # node:test smoke 测试(对 dist 产物做黑盒验证)
132
+ └── cordis.patch.yml # bundle 挂载补丁
133
+ ```
134
+
135
+ ## 更新 / Updates
136
+
137
+ ```sh
138
+ dsh plugin --profile web update dsh-flyout-sidebar # 或重新 add
139
+ ```
140
+
141
+ 随后重启 `dsh web` 并硬刷新浏览器。
142
+
143
+ ## 友情链接 / Links
144
+
145
+ - [LinuxDo](https://linux.do)
146
+
147
+ ## License
148
+
149
+ [MIT](LICENSE)
package/README_EN.md ADDED
@@ -0,0 +1,152 @@
1
+ # dsh-flyout-sidebar
2
+
3
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](#license)
4
+
5
+ > DeepSeek Harness (DSH) plugin: a flyout sidebar with a file tree and the Git changed-but-uncommitted files, multi-tab file preview, and a standalone flyout browser tab.
6
+ >
7
+ > [中文](README.md) | EN
8
+
9
+ ## Install
10
+
11
+ ### From GitHub sources
12
+
13
+ ```sh
14
+ dsh plugin --profile web add github:oxlyn/dsh-flyout-sidebar
15
+ ```
16
+
17
+ ### Local install (development)
18
+
19
+ ```sh
20
+ git clone https://github.com/oxlyn/dsh-flyout-sidebar.git
21
+ cd dsh-flyout-sidebar
22
+ npm install
23
+ npm run build # tsdown → dist/index.js + dist/client.js
24
+
25
+ # run from the parent directory (dsh plugin add resolves relative paths against the cwd):
26
+ cd ..
27
+ dsh plugin --profile web add ./dsh-flyout-sidebar # symlink install; after editing src/ run npm run build and restart dsh web
28
+ dsh web
29
+ ```
30
+
31
+ ### Verify
32
+
33
+ After installing, **restart `dsh web`** and **hard-refresh the browser** (Cmd/Ctrl+Shift+R). A persistent sidebar icon button appears in the top-right corner (visible even with no session). You can also verify the config layer:
34
+
35
+ ```sh
36
+ dsh --profile web --dump-config | grep dsh-flyout-sidebar # this line should appear
37
+ ```
38
+
39
+ ## Features
40
+
41
+ | # | Form | Entry | Description |
42
+ |---|------|-------|-------------|
43
+ | 1 | File tree view (default) | visible when the panel opens | Browse the current workspace; lazy-expanded directories, directories first; re-roots automatically when the workspace/session switches |
44
+ | 2 | Git changes view | git-branch icon in the panel header | Lists changed-but-uncommitted files (`M`/`A`/`D`/`R`/`U` badges, hover for staged/unstaged, renames show the original path); clicking a file shows a colored unified diff against HEAD — untracked files get a synthesized new-file diff |
45
+ | 3 | Multi-tab preview | click a file | The preview overlay covers the entire area left of the sidebar; open many files at once; syntax highlighting by extension, plus Markdown, images, PDF and sandboxed HTML iframes; ⇥ collapses the whole preview (tabs kept, opening a file restores them) |
46
+ | 4 | Flyout tab | ↗ in the panel header | Pops out to `/flyout-sidebar`, draggable to another monitor; content left / file panel right, one-click side swap, draggable width (defaults to minimum, preference remembered) |
47
+
48
+ **Highlights:**
49
+
50
+ - Git status is cached per workspace: the first request awaits the real result, then polls answer instantly while a background refresh runs (700ms debounce after every agent tool run, plus a 15s safety poll covering IDE edits)
51
+ - Switching projects/sessions clears all preview tabs automatically, so content never leaks across workspaces
52
+ - One-click path copy, or write an `@path` quote into the session composer, from git change rows and file tree rows
53
+ - Both the panel and the flyout tab follow DSH's light/dark theme in real time (the flyout syncs via `localStorage`, correct on first paint)
54
+ - Coexists with other sidebar plugins: it shifts left of other side cards automatically, both stay visible
55
+ - The flyout has no title bar — all vertical space goes to content; the status (live / git error / offline) lives in the panel header row
56
+
57
+ ## Settings
58
+
59
+ A "**Flyout Sidebar**" tab appears in the DSH settings panel (⚙️ in the bottom-left):
60
+
61
+ | Setting | Default | Description |
62
+ |---|---|---|
63
+ | Default expanded | on | Expand the sidebar on page load; when off it starts collapsed |
64
+ | Auto refresh | on | Poll the latest git status every 2s while the changes view is open |
65
+ | File tree | on | Show the file tree view and the view-toggle icon; when off the panel always shows the Git changes view |
66
+ | Min panel width | 20% | Minimum panel width (percent of window width, 20–60%); drag the panel's left edge to widen it |
67
+
68
+ Settings are stored in the browser's `localStorage` (key `dsh-flyout-sidebar:settings`); the flyout's panel width / side preferences live in `dsh-flyout-sidebar:panelw` / `panelLeft`.
69
+
70
+ ## How it works
71
+
72
+ The plugin splits into a host side and a client side, written in TypeScript + JSX and bundled by **tsdown** into two single-file bundles:
73
+
74
+ ```
75
+ ┌─ host side src/index.ts → dist/index.js (Node process, ESM) ────┐
76
+ │ - host/artifacts.ts artifact tracking (write/edit + shell │
77
+ │ snapshot diff) │
78
+ │ - host/git.ts git status/diff (per-workspace cache) │
79
+ │ git status --porcelain=v1 -z change list │
80
+ │ git diff HEAD -M -- <path> colored unified diff text │
81
+ │ - host/workspace.ts session → workspace cwd resolution │
82
+ │ - host/files.ts directory listing / text reading │
83
+ │ - host/page.ts standalone flyout page HTML (inlines the │
84
+ │ shared modules) │
85
+ │ - host/routes.ts ctx.webServer.register: │
86
+ │ GET /flyout-sidebar/gitstatus change list JSON │
87
+ │ GET /flyout-sidebar/gitdiff per-file diff JSON │
88
+ │ GET /flyout-sidebar/listdir directory listing │
89
+ │ GET /flyout-sidebar/content text content (code preview) │
90
+ │ GET /flyout-sidebar/media images / PDF binary │
91
+ │ - tools/result event → 700ms debounced cache refresh │
92
+ └──────────────────────────────────────────────────────────────────┘
93
+ │ fetch
94
+ ┌─ client side src/client/index.tsx → dist/client.js (IIFE) ───────┐
95
+ │ - React components (classic JSX via an `h` factory; React is │
96
+ │ provided at runtime by DSH's __ModuleLoader__ factory, the │
97
+ │ bundle does not embed it) │
98
+ │ - shell.overlay: persistent top-right icon button + panel │
99
+ │ - file tree ⇄ Git changes views; multi-tab preview overlay │
100
+ │ - settings.section: Flyout Sidebar settings │
101
+ │ - cross-tab localStorage sync: session id, theme, panel prefs │
102
+ └──────────────────────────────────────────────────────────────────┘
103
+ ```
104
+
105
+ Technical notes: a single `tsdown.config.ts` bundles both sides (host ESM / client IIFE); a custom `?raw` plugin inlines the shared module sources into the flyout page's classic `<script>` and embeds the vendored pdf.js into the host bundle (fully offline); shared modules `shared/ext.js` (preview types), `shared/highlight.js` (zero-dependency syntax highlighter) and `shared/markdown.js` (Markdown rendering) are portable JS with JSDoc types, reused on both sides and inlined into the flyout page; host dependencies are declared via `inject: ['webServer', 'sessionQuery', 'timer']`.
106
+
107
+ ## Requirements
108
+
109
+ - Node `>=20` (DSH host requirement)
110
+ - `git` on the PATH and a git repository as the workspace (otherwise the Git changes view shows an error; the file tree is unaffected)
111
+ - Local builds need the devDependencies (`tsdown`, `typescript`, ...; zero runtime dependencies)
112
+
113
+ ## Development
114
+
115
+ ```sh
116
+ npm run build # tsdown: regenerate dist/index.js and dist/client.js
117
+ npm run check # tsc --noEmit strict type checking
118
+ npm test # node:test smoke tests (host routes/events + client rendering + flyout page)
119
+ ```
120
+
121
+ > Recommended one-time setup of the pre-commit guard: `ln -sf ../../scripts/precommit.sh .git/hooks/pre-commit`. Every `git commit` rebuilds the bundles automatically and blocks the commit if they are out of sync with the sources.
122
+
123
+ Project structure:
124
+
125
+ ```
126
+ dsh-flyout-sidebar/
127
+ ├── tsdown.config.ts # tsdown build: host/client bundles + ?raw inline plugin
128
+ ├── src/index.ts # host entry (exports name/inject/apply, ESM)
129
+ ├── dist/ # ⚙️ generated: index.js (host) / client.js (browser), do not edit
130
+ ├── src/shared/ # shared portable modules (JSDoc types, inlined into the flyout page): ext / markdown / highlight
131
+ ├── src/host/ # host modules: types / artifacts / workspace / files / git / page (flyout HTML) / routes (HTTP)
132
+ ├── src/client/ # client modules (TSX): jsx (React bridge) / runtime / store / styles / icons / preview / components
133
+ ├── src/vendor/pdfjs/ # vendored pdf.js (embedded at build time, offline-safe)
134
+ ├── test/ # node:test smoke tests (black-box checks against dist)
135
+ └── cordis.patch.yml # bundle mount patch
136
+ ```
137
+
138
+ ## Updates
139
+
140
+ ```sh
141
+ dsh plugin --profile web update dsh-flyout-sidebar # or `add` again
142
+ ```
143
+
144
+ Then restart `dsh web` and hard-refresh the browser.
145
+
146
+ ## Links
147
+
148
+ - [LinuxDo](https://linux.do)
149
+
150
+ ## License
151
+
152
+ [MIT](LICENSE)
@@ -0,0 +1,19 @@
1
+ # dsh-flyout-sidebar bundle patch
2
+ #
3
+ # This file is the `dsh.bundle.patch` layer of the package: when installed
4
+ # through the official CLI —
5
+ #
6
+ # dsh plugin --profile web add dsh-flyout-sidebar
7
+ #
8
+ # — the command reconciles `dsh.profile.bundles` against installed packages
9
+ # and, seeing this declaration, appends the package to the bundle stack. The
10
+ # profile boot then merges THIS patch (a single `insert` of the plugin row),
11
+ # exactly like the manual cordis.patch.yml mount line. The client half is
12
+ # picked up automatically from the `dsh.client` + `exports` declarations in
13
+ # package.json — no profile file edits needed.
14
+ #
15
+ # Do not also add a manual mount line to the profile's cordis.patch.yml for
16
+ # this package — that would double-mount (two Node halves, two sidebars).
17
+ - insert:
18
+ - id: flyout-sidebar
19
+ name: 'dsh-flyout-sidebar'