dsh-codinput 0.1.1 → 0.2.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/CHANGELOG.md +31 -0
- package/README.en.md +30 -26
- package/README.md +32 -28
- package/TESTING.md +10 -2
- package/assets/icon-white.svg +11 -0
- package/assets/icon.png +0 -0
- package/assets/icon.svg +11 -1
- package/assets/preview-ball-detail.png +0 -0
- package/assets/preview-float.png +0 -0
- package/assets/preview-normal.png +0 -0
- package/assets/preview-side.png +0 -0
- package/assets/preview-split.png +0 -0
- package/lib/client.js +57 -37
- package/package.json +1 -1
- package/src/client/attachments.ts +34 -0
- package/src/client/command.ts +52 -12
- package/src/client/components/AttachmentRail.tsx +20 -1
- package/src/client/components/CodinputBar.tsx +13 -35
- package/src/client/components/CodinputSurface.tsx +42 -8
- package/src/client/components/ImageLightbox.tsx +61 -0
- package/src/client/components/StatsRow.tsx +76 -43
- package/src/client/components/Toolbar.tsx +12 -36
- package/src/client/host-types.ts +6 -1
- package/src/client/i18n.ts +16 -2
- package/src/client/icons.tsx +33 -27
- package/src/client/sidebar.tsx +66 -7
- package/src/client/sideinput.ts +33 -7
- package/src/client/stats.ts +156 -53
- package/src/client/styles.ts +27 -7
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,37 @@
|
|
|
2
2
|
|
|
3
3
|
本项目遵循 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/) 与 [语义化版本](https://semver.org/lang/zh-CN/)。
|
|
4
4
|
|
|
5
|
+
## [0.2.0] — 2026-09-29
|
|
6
|
+
|
|
7
|
+
品牌换新 + 一批交互补全:图片原图预览、发送/停止、侧栏 `/codinput` 退出与自动启用,以及输入卡片与数据行对官方布局的逐值对齐。
|
|
8
|
+
|
|
9
|
+
### 新增
|
|
10
|
+
|
|
11
|
+
- **品牌图标全面换新**:自绘机型标(代码括号 + 航迹 + 纸飞机)替代 lucide `file-code-corner`——README 头图、悬浮/侧栏唤回小球、slash 的 `/codinput` 命令图标全部换新(小尺寸做了可读性简化);`assets/` 附透明 PNG、紫色矢量与白色线稿三件套。
|
|
12
|
+
- **附件图片原图预览**:点图片缩略图弹出全屏预览层(官方 primitives `ImageLightbox` 逐值复刻)——Esc、背板按下、右上关闭钮三种方式关闭,关闭后焦点还原缩略图。
|
|
13
|
+
- **发送 ⇆ 停止**:流式回复期间主按钮自动变停止(官方同款方块 glyph),点击即中断生成(官方 `conversation.cancel` 同链路);会话阻塞(审批等待)时停止钮仍可点;回复结束或中断后恢复发送。
|
|
14
|
+
- **侧栏 `/codinput` 退出**:侧栏里输入 `/codinput` 回车——接管关闭、Codinput 标签自动关闭、官方输入框原样回归;重新打开标签(或再次 `/codinput`)即恢复接管。
|
|
15
|
+
- **开标签即启用**:未启用接管时,打开右侧栏的 Codinput 标签直接启用插件。
|
|
16
|
+
|
|
17
|
+
### 变更
|
|
18
|
+
|
|
19
|
+
- **slash「添加 · 文件」接管期间照常可用**:接管面按官方契约绑定会话文件拾取器(`bindFilePicker`),文件条目不再随官方输入框卸载而消失;工具行的独立附件按钮随之移除(官方已并入 slash),粘贴 / 拖拽路径不变。
|
|
20
|
+
- **slash 菜单排序修正**:空查询不再整列排序(会把「添加/指令」小节打散),改为 `/codinput` 单行按字典序排入指令节首,其余保持官方使用序。
|
|
21
|
+
- **输入卡片与数据行对齐官方布局**:surface 复刻官方 composer root(侧向 clearance + 底距)、数据行复刻官方 dock(无横向内缩、距卡片 4px、胶囊组居中),窄列下卡片宽度与官方逐像素一致;圆角/字号/行高改走官方令牌。
|
|
22
|
+
- **侧栏承载语义补全**:标签定义 `keepMounted` 保活(浏览同栏其他标签不丢承载);承载以接管开关为前提(`/codinput` 退出即让位,重开自动恢复);分栏多标签时编辑面跟随后被查看的一栏。
|
|
23
|
+
- **性能与用量取数对齐官方**:`sessionStats` 投影优先、chat 节点派生兜底——tok/s 为 decodeTokens÷decodeMs 的会话持久值(历史会话也显示),缓存命中/时长格式化同官方规则;数据行字号走官方 secondary-1px 公式。
|
|
24
|
+
- **README 全面重写 + 五张展示图重拍**(真实对话素材、深色主题)。
|
|
25
|
+
|
|
26
|
+
### 修复
|
|
27
|
+
|
|
28
|
+
- 唤回小球在「侧栏收起 + Codinput 浮动面板打开」时不再多余出现(输入就在眼前)。
|
|
29
|
+
|
|
30
|
+
### 说明
|
|
31
|
+
|
|
32
|
+
- 宿主兼容不变:`0.1.7-rc.2`(next)实测通过,`0.1.5-rc.2` / `0.1.6-alpha.2` 沿用既往结论;升级宿主后建议按 [TESTING.md](./TESTING.md) 冒烟。
|
|
33
|
+
|
|
34
|
+
[0.2.0]: https://github.com/Witherwithwinter/DSH-Codinput/compare/v0.1.1...v0.2.0
|
|
35
|
+
|
|
5
36
|
## [0.1.1] — 2026-09-25
|
|
6
37
|
|
|
7
38
|
适配宿主 `0.1.7-rc.2`(`next` 通道)的官方候选菜单亚克力改版;旧 rc 宿主经 token 回退链保持原样。
|
package/README.en.md
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="./assets/icon.png" width="128" alt="DSH-Codinput" />
|
|
3
|
+
</p>
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
<h1 align="center">DSH-Codinput</h1>
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="https://www.npmjs.com/package/dsh-codinput"><img src="https://img.shields.io/npm/v/dsh-codinput" alt="npm Version" /></a>
|
|
9
|
+
<a href="https://github.com/deepseek-ai/deepseek-harness"><img src="https://img.shields.io/badge/DSH-0.1.5--rc.2%2B-blue" alt="DSH Version" /></a>
|
|
10
|
+
<a href="https://www.npmjs.com/package/dsh-codinput"><img src="https://img.shields.io/npm/dm/dsh-codinput" alt="Downloads" /></a>
|
|
11
|
+
<a href="https://github.com/Witherwithwinter/DSH-Codinput/stargazers"><img src="https://img.shields.io/github/stars/Witherwithwinter/DSH-Codinput" alt="GitHub Stars" /></a>
|
|
12
|
+
<a href="./LICENSE"><img src="https://img.shields.io/github/license/Witherwithwinter/DSH-Codinput" alt="License" /></a>
|
|
13
|
+
</p>
|
|
10
14
|
|
|
11
|
-
|
|
15
|
+
<p align="center"><a href="./README.md">中文</a> | English</p>
|
|
12
16
|
|
|
13
|
-
<p>
|
|
14
|
-
<img src="./assets/icon.svg" width="22" alt="" align="top" />
|
|
15
|
-
Icon: lucide <code>file-code-corner</code> (also used as the recall ball when the sidebar is collapsed)
|
|
16
|
-
</p>
|
|
17
|
+
<p align="center">A real code editor, right where the DeepSeek Harness chat composer used to be.</p>
|
|
17
18
|
|
|
18
19
|

|
|
19
20
|
|
|
@@ -24,7 +25,7 @@
|
|
|
24
25
|
</tr>
|
|
25
26
|
<tr>
|
|
26
27
|
<td width="50%"><img src="./assets/en/preview-side.png" alt="Sidebar tab mode" /><br /><sub>Sidebar tab mode (full-height, VS Code panel style)</sub></td>
|
|
27
|
-
<td width="50%"><img src="./assets/en/preview-ball-detail.png" alt="Recall ball" /><br /><sub>The recall ball shown when the sidebar is collapsed</sub></td>
|
|
28
|
+
<td width="50%"><img src="./assets/en/preview-ball-detail.png" alt="Recall ball" /><br /><sub>The recall ball shown when the sidebar is collapsed (close-up)</sub></td>
|
|
28
29
|
</tr>
|
|
29
30
|
</table>
|
|
30
31
|
|
|
@@ -40,15 +41,15 @@
|
|
|
40
41
|
| --- | --- | --- |
|
|
41
42
|
| Normal `normal` | default | The takeover card sits in the composer's own place |
|
|
42
43
|
| Floating `float` | drag the blank area of the card's top row | Pops out into a floating window: draggable, resizable from all four edges and four corners (position and size are remembered) |
|
|
43
|
-
| Sidebar tab `side` | open the “Codinput” tab in the right sidebar | The input lives in the sidebar panel; **collapsing the sidebar does not give the composer back** — the round ball under the title bar brings it back |
|
|
44
|
+
| Sidebar tab `side` | open the “Codinput” tab in the right sidebar | The input lives in the sidebar panel; **collapsing the sidebar does not give the composer back** — the round ball under the title bar brings it back; `/codinput` from the sidebar exits to the official composer and closes the tab |
|
|
44
45
|
|
|
45
|
-
- **Editor**: line numbers (optional), current-line and gutter highlighting, soft wrap, Tab indentation, a line/column indicator, and **
|
|
46
|
-
-
|
|
46
|
+
- **Editor**: line numbers (optional), current-line and gutter highlighting, soft wrap, Tab indentation, a line/column indicator, and an **edit + preview split** (live markdown, exactly half and half).
|
|
47
|
+
- **Undo history that survives mode switches**: drag into floating mode, hop into the sidebar, come back — `Ctrl+Z` still works. All three modes share the same official input machine, whose draft is the single source of truth (it survives mode switches, plugin toggles and reloads).
|
|
48
|
+
- **`/` `@`**: entirely the official trigger pipeline (track → official menu store → a faithful MenuView replica): candidate menu, drill-down, crumbs and skeletons match the official UI; `/codinput` slots into the head of the commands section alphabetically; everything else keeps the official usage order.
|
|
47
49
|
- **Model & reasoning effort**: read from the official shared directory (the same state source as `/model`). **Permissions**: the three official presets plus the RiskConfirmation modal for full access.
|
|
48
|
-
- **Attachments**:
|
|
49
|
-
- **
|
|
50
|
-
- **Settings**: Settings → Codinput (takeover on/off, line numbers, font, **fully custom send / line-break shortcuts** via a recorder, default view)
|
|
51
|
-
- **Draft**: the official input machine is the single source of truth (one write entry point); drafts survive mode switches, plugin toggles, and reloads.
|
|
50
|
+
- **Attachments**: slash Add · File (the takeover surface binds the shell's file-picker contract, so the entry keeps working while Codinput owns the composer), **paste images directly**, or **drop files onto the card** (clicking an image thumbnail opens the original-image lightbox, an ImageLightbox replica; the rail is a faithful replica of the official one: 64×64 image thumbnails, file cards with type glyph/name/size, upload spinner, progress bar, retry on failure).
|
|
51
|
+
- **Performance & usage**: a replica of the official stats dock — turns/steps · tok/s, total tok · cache hit, plus the context-usage dial — with value-for-value parity in data and formatting, each opening a detail panel; available in all three modes.
|
|
52
|
+
- **Settings**: Settings → Codinput (takeover on/off, line numbers, font, **fully custom send / line-break shortcuts** via a recorder, default view); with the takeover off, **opening the Codinput tab in the right sidebar enables it directly**.
|
|
52
53
|
|
|
53
54
|
## Installation
|
|
54
55
|
|
|
@@ -93,7 +94,7 @@ To pin a version or maintain the profile by hand, the manual equivalent of **Met
|
|
|
93
94
|
```jsonc
|
|
94
95
|
{
|
|
95
96
|
"dependencies": {
|
|
96
|
-
"dsh-codinput": "^0.1.
|
|
97
|
+
"dsh-codinput": "^0.1.1" // for local development: "link:/abs/path/to/DSH-Codinput"
|
|
97
98
|
},
|
|
98
99
|
"dsh": {
|
|
99
100
|
"profile": {
|
|
@@ -116,12 +117,12 @@ The host publishes **rc** builds on npm (`latest` is the current stable rc, `nex
|
|
|
116
117
|
|
|
117
118
|
| Host version | Status |
|
|
118
119
|
| --- | --- |
|
|
119
|
-
| `0.1.7-rc.2` | ✅ Verified on a real instance (current `next`; the acrylic candidate menu
|
|
120
|
+
| `0.1.7-rc.2` | ✅ Verified on a real instance (current `next`; the acrylic candidate menu, the relocated context meter and the dock row layout are aligned to this build) |
|
|
120
121
|
| `0.1.5-rc.2` | ✅ Verified on a real instance |
|
|
121
122
|
| `0.1.6-alpha.2` | ✅ Current development baseline; every feature verified end to end |
|
|
122
123
|
| others (incl. `0.1.5-rc.3`, the current `latest`) | untested; older hosts lack the rc.2 tokens, so the fallback chain keeps each host's official look |
|
|
123
124
|
|
|
124
|
-
For `0.1.7-rc.2`, on top of the real-instance run, the official CSS for the candidate menu
|
|
125
|
+
For `0.1.7-rc.2`, on top of the real-instance run, the official CSS for the candidate menu, the context meter and the stats dock was extracted value by value from that version's client packages (`dsh-client-ui-theme` / `dsh-client-ui-input-trigger` / `dsh-client-ui-conversation` / `dsh-client-ui-chat`) and checked against the replicas. The contracts this plugin relies on were verified per version: the three slots it uses (`conversation.composer.bar`, `sidebar.right.pane.tab`, `settings.section`), the `sidebarRight` / `sidebarRightTabs` / `locale` services and `openTabIn`, the sidebar expansion planner (dockkit `planSetExpanded`), the file-picker and tab-close contracts (`shell.bindFilePicker` / `tab.actions.close`), and the official primitives the replicas are copied from (`fileSizeText` / `fileExtension` and the attachment glyph paths, byte for byte). For how to re-run this on another channel, see the “Verifying on another channel” section of [TESTING.md](./TESTING.md).
|
|
125
126
|
|
|
126
127
|
The plugin leans on host internals (slot shadowing, `useTabInfo`, `sidebarRight`, `--dsw-*` tokens). Every call site guards with `typeof` checks and degrades gracefully, but a major host upgrade can still break it. **After upgrading the host, walk through [TESTING.md](./TESTING.md).**
|
|
127
128
|
|
|
@@ -129,9 +130,10 @@ The plugin leans on host internals (slot shadowing, `useTabInfo`, `sidebarRight`
|
|
|
129
130
|
|
|
130
131
|
- `/` `@` candidates come from host directories (skills / commands / files / sessions); when the host provides none, the menu is empty — the plugin cannot fill that in.
|
|
131
132
|
- **No syntax highlighting** and **no Esc behaviour** — deliberate product decisions (this is an input panel, not a code reader).
|
|
132
|
-
- While
|
|
133
|
+
- While a Codinput sidebar tab exists the composer is hidden entirely (single input surface rule; browsing another tab in the same pane does not bring it back). The official stats dock and context dial live inside the official composer, so they disappear with it and the replicated stats row takes over.
|
|
133
134
|
- Duplicating the “Codinput” tab into a second split pane shows a notice instead of a second editor (the input surface stays unique).
|
|
134
135
|
- The floating gesture only keeps “drag back to the composer area = normal”; “drag into the right sidebar = sidebar mode” was dropped by product decision.
|
|
136
|
+
- After a page reload, if the sidebar layout restores a Codinput tab that has not been opened yet, the composer shows up first — dockkit mounts restored tab bodies lazily; opening the tab once restores the sidebar carry.
|
|
135
137
|
|
|
136
138
|
## Development
|
|
137
139
|
|
|
@@ -151,15 +153,17 @@ npm run typecheck
|
|
|
151
153
|
### Host facts worth knowing before changing code
|
|
152
154
|
|
|
153
155
|
- **Takeover point**: `conversation.composer.bar` (a `single` slot; `priority:-1` shadows the official entry). Disposing the entry restores the official composer untouched.
|
|
154
|
-
- **Single input surface**: a sidebar tab body **counts as carrying the input the moment it mounts** (not based on visibility — collapsing the sidebar is CSS hiding plus a translate, the body stays mounted). The main entry renders `null` accordingly, and the mode is derived as `carrying ? 'side' : prefs.mode`, so coexistence is impossible by construction.
|
|
156
|
+
- **Single input surface**: a sidebar tab body **counts as carrying the input the moment it mounts** (not based on visibility — collapsing the sidebar is CSS hiding plus a translate, the body stays mounted). The main entry renders `null` accordingly, and the mode is derived as `carrying ? 'side' : prefs.mode`, so coexistence is impossible by construction. The carry claim lives on the body's lifetime, so the tab definition sets `keepMounted: true`: dockkit unmounts inactive tab bodies by default, and switching to another tab in the same pane would drop the claim and bring the composer back (same switch the official browser tab uses; note a tab restored after a reload only mounts its body once it has been activated).
|
|
155
157
|
- **Undo history**: switching modes remounts the editor, so `EditorState` is cached per session (`take/putEditorSnapshot`); extension callbacks go through a module-level hooks slot so a reused state never calls into an unmounted instance's props.
|
|
156
158
|
- **Official-side writes** (pick / claim / submit-clears) carry `externalAnnotation` + `Transaction.addToHistory.of(false)`, so undo only ever reverts what you typed.
|
|
157
159
|
- **Drawing a circle needs `corner-shape: round`**: the host root sets `corner-shape: superellipse(1.5)` globally, so a plain `border-radius:50%` renders as a rounded square.
|
|
158
160
|
- **The ball occupies no slot**: `conversation.session.header.corner` is the official sidebar expand button's seat (a `single` slot — taking it would remove the official button), so the ball is portalled to `body` and positioned from the measured header rect.
|
|
161
|
+
- **The slash File entry lives on the filePicker binding**: the official `file` contribution's `available` reads `shell.canPickFiles()`, and the picker is bound by the official InputBar when it mounts (`bindFilePicker`) and unbound on unmount — the takeover surface must re-bind it on mount (`attachments.bindSessionFilePicker`) or the entry disappears. **Never register a same-name contribution**: the host rejects duplicates at `register` time, fail-loud.
|
|
162
|
+
- **Closing a tab goes through the tab-domain action face**: `useTabInfo().tab.actions.close()` closes the tab itself (dockkit semantics; with a single docked tab it lays a guide down and collapses). To locate the session, do not use the diagnostic `__dshCodinputSessionId` (surface unmounts null it) — read the carry snapshot from the sideinput bus.
|
|
159
163
|
|
|
160
164
|
## Third-party attribution
|
|
161
165
|
|
|
162
|
-
Parts of this project **replicate DeepSeek Harness** (`@deepseek-ai/dsh`, MIT License, Copyright (c) 2026 DeepSeek): several SVG icon paths (the permission shield set, plus, paperclip, arrow-up, the generic file glyph, …) and CSS values for the composer card
|
|
166
|
+
Parts of this project **replicate DeepSeek Harness** (`@deepseek-ai/dsh`, MIT License, Copyright (c) 2026 DeepSeek): several SVG icon paths (the permission shield set, plus, paperclip, close, arrow-up, the generic file glyph, …) and CSS values for the composer card, the attachment rail and the original-image lightbox. They are used under the MIT license; the original copyright and permission notice are retained in [NOTICE](./NOTICE) alongside [LICENSE](./LICENSE).
|
|
163
167
|
|
|
164
168
|
Bundled third-party dependencies: CodeMirror 6 (MIT), marked (MIT), DOMPurify (Apache-2.0 / MPL-2.0 dual licensed).
|
|
165
169
|
|
package/README.md
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="./assets/icon.png" width="128" alt="DSH-Codinput" />
|
|
3
|
+
</p>
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
<h1 align="center">DSH-Codinput</h1>
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="https://www.npmjs.com/package/dsh-codinput"><img src="https://img.shields.io/npm/v/dsh-codinput" alt="npm Version" /></a>
|
|
9
|
+
<a href="https://github.com/deepseek-ai/deepseek-harness"><img src="https://img.shields.io/badge/DSH-0.1.5--rc.2%2B-blue" alt="DSH Version" /></a>
|
|
10
|
+
<a href="https://www.npmjs.com/package/dsh-codinput"><img src="https://img.shields.io/npm/dm/dsh-codinput" alt="Downloads" /></a>
|
|
11
|
+
<a href="https://github.com/Witherwithwinter/DSH-Codinput/stargazers"><img src="https://img.shields.io/github/stars/Witherwithwinter/DSH-Codinput" alt="GitHub Stars" /></a>
|
|
12
|
+
<a href="./LICENSE"><img src="https://img.shields.io/github/license/Witherwithwinter/DSH-Codinput" alt="License" /></a>
|
|
13
|
+
</p>
|
|
10
14
|
|
|
11
|
-
|
|
15
|
+
<p align="center">中文 | <a href="./README.en.md">English</a></p>
|
|
12
16
|
|
|
13
|
-
<p>
|
|
14
|
-
<img src="./assets/icon.svg" width="22" alt="" align="top" />
|
|
15
|
-
图标:lucide <code>file-code-corner</code>(同时用作侧栏收起后的唤出小球)
|
|
16
|
-
</p>
|
|
17
|
+
<p align="center">把 DeepSeek Harness 的聊天输入框,换成一个真正的代码编辑器。</p>
|
|
17
18
|
|
|
18
19
|

|
|
19
20
|
|
|
@@ -24,7 +25,7 @@
|
|
|
24
25
|
</tr>
|
|
25
26
|
<tr>
|
|
26
27
|
<td width="50%"><img src="./assets/preview-side.png" alt="侧栏标签模式" /><br /><sub>侧栏标签模式(VS Code 面板式全高)</sub></td>
|
|
27
|
-
<td width="50%"><img src="./assets/preview-ball-detail.png" alt="右上角小球" /><br /><sub
|
|
28
|
+
<td width="50%"><img src="./assets/preview-ball-detail.png" alt="右上角小球" /><br /><sub>侧栏收起时的唤出小球(特写)</sub></td>
|
|
28
29
|
</tr>
|
|
29
30
|
</table>
|
|
30
31
|
|
|
@@ -40,19 +41,19 @@
|
|
|
40
41
|
| --- | --- | --- |
|
|
41
42
|
| 普通 `normal` | 默认 | 接管卡片在原输入位 |
|
|
42
43
|
| 悬浮 `float` | 按住卡片顶部行空白区拖动 | 脱出为悬浮窗:可拖动位置、可拖边界/角落缩放(位置与尺寸记忆) |
|
|
43
|
-
| 侧栏标签 `side` | 打开右侧栏的「Codinput」标签 |
|
|
44
|
+
| 侧栏标签 `side` | 打开右侧栏的「Codinput」标签 | 输入在侧栏面板内;**侧栏收起不让位**,由标题栏下方的圆形小球唤回;侧栏里 `/codinput` 直接退回官方输入框并关闭本标签 |
|
|
44
45
|
|
|
45
|
-
- **编辑器**:行号(可关)、当前行与行号高亮、软换行、Tab
|
|
46
|
-
-
|
|
47
|
-
-
|
|
48
|
-
-
|
|
49
|
-
-
|
|
50
|
-
-
|
|
51
|
-
-
|
|
46
|
+
- **编辑器**:行号(可关)、当前行与行号高亮、软换行、Tab 缩进、行列指示,**编辑 + 预览分屏**(markdown 实时渲染,严格对半)。
|
|
47
|
+
- **撤销历史跨形态保留**:拖成悬浮、切到侧栏再回来,`Ctrl+Z` 依旧有效——三态共用同一台官方输入机,草稿即唯一事实源(形态切换、插件禁用、重启都不丢)。
|
|
48
|
+
- **`/` `@` 触发管线**:完全走官方链路(track → 官方 menu store → 逐项复刻的 MenuView),候选菜单、钻取、crumbs、骨架屏与官方逐一对齐;`/codinput` 按字典序排入指令节首,其余保持官方使用序。
|
|
49
|
+
- **模型与权限**:模型与思考强度读官方共享目录(与 `/model` 同一状态源);权限为官方三预设,含完全权限的风险确认模态。
|
|
50
|
+
- **附件**:slash「添加 · 文件」、**粘贴图片**、**拖文件进卡片**三条路径;点图片缩略图弹**原图预览**(官方 ImageLightbox 同构);上传中/失败有状态芯片,失败可整卡重试。
|
|
51
|
+
- **性能与用量**:复刻官方 stats dock——轮次/步数 · tok/s、累计 tok · 缓存命中、上下文占用小圈,取数与格式化逐值同官方,均可点开详情面板;三形态都有。
|
|
52
|
+
- **设置**:设置 → Codinput——启用接管、行号、字体、发送/换行快捷键**任意组合录制**、默认视图;未启用时**打开右侧栏的 Codinput 标签即直接启用**。
|
|
52
53
|
|
|
53
54
|
## 安装
|
|
54
55
|
|
|
55
|
-
要求:宿主 `@deepseek-ai/dsh
|
|
56
|
+
要求:宿主 `@deepseek-ai/dsh`(版本见下方[兼容性](#兼容性))。
|
|
56
57
|
|
|
57
58
|
### 方法 A:npm 包
|
|
58
59
|
|
|
@@ -93,7 +94,7 @@ dsh plugin --profile web add link:/abs/path/to/DSH-Codinput
|
|
|
93
94
|
```jsonc
|
|
94
95
|
{
|
|
95
96
|
"dependencies": {
|
|
96
|
-
"dsh-codinput": "^0.1.
|
|
97
|
+
"dsh-codinput": "^0.1.1" // 本地开发用 "link:/abs/path/to/DSH-Codinput"
|
|
97
98
|
},
|
|
98
99
|
"dsh": {
|
|
99
100
|
"profile": {
|
|
@@ -116,20 +117,21 @@ dsh plugin --profile web add link:/abs/path/to/DSH-Codinput
|
|
|
116
117
|
|
|
117
118
|
| 宿主版本 | 状态 |
|
|
118
119
|
| --- | --- |
|
|
119
|
-
| `0.1.7-rc.2` | ✅ 实机实测通过(`next`
|
|
120
|
+
| `0.1.7-rc.2` | ✅ 实机实测通过(`next` 通道当前版本;候选菜单亚克力、上下文小圈挪位、dock 行布局即为此版对齐) |
|
|
120
121
|
| `0.1.5-rc.2` | ✅ 实机实测通过 |
|
|
121
122
|
| `0.1.6-alpha.2` | ✅ 开发基线,全部功能端到端实测通过 |
|
|
122
123
|
| 其它(含 `latest` 现指向的 `0.1.5-rc.3`) | 未实测;旧宿主无 rc.2 新 token,回退链自动保持各版官方原形态 |
|
|
123
124
|
|
|
124
|
-
对 `0.1.7-rc.2` 除实机验证外,还从该版本的客户端包(`dsh-client-ui-theme` / `dsh-client-ui-input-trigger` / `dsh-client-ui-conversation
|
|
125
|
+
对 `0.1.7-rc.2` 除实机验证外,还从该版本的客户端包(`dsh-client-ui-theme` / `dsh-client-ui-input-trigger` / `dsh-client-ui-conversation` / `dsh-client-ui-chat`)逐值提取了候选菜单、上下文小圈与 stats dock 的官方 CSS 核对。插件依赖的契约按版本核对过:用到的 3 个槽位(`conversation.composer.bar`、`sidebar.right.pane.tab`、`settings.section`)、`sidebarRight` / `sidebarRightTabs` / `locale` 服务与 `openTabIn`、侧栏展开规划(dockkit `planSetExpanded`)、文件拾取与 tab 关闭契约(`shell.bindFilePicker` / `tab.actions.close`)、以及复刻所依据的官方原语(`fileSizeText` / `fileExtension` 与附件 glyph 路径,逐字一致)。插件对宿主内部结构的依赖较多(槽位遮蔽、`useTabInfo`、`sidebarRight`、`--dsw-*` 令牌),代码里处处用 `typeof` 守卫 + `try/catch` 降级,但宿主大版本升级仍可能失效。**升级宿主后请按 [TESTING.md](./TESTING.md) 走一遍冒烟清单。**
|
|
125
126
|
|
|
126
127
|
## 已知限制
|
|
127
128
|
|
|
128
129
|
- `/` `@` 的候选内容来自宿主目录(技能 / 命令 / 文件 / 会话);宿主不提供时为空,插件侧无法补。
|
|
129
130
|
- **没有语法高亮**、**没有 Esc 功能**——产品决策(输入面板不是代码阅读器)。
|
|
130
|
-
-
|
|
131
|
+
- **Codinput 标签存在期间主输入整体隐藏**(唯一输入入口约定,浏览同栏其他标签也不恢复);官方 stats dock 与上下文小圈都渲染在官方输入框内部,因此随之消失、由本插件的复刻数据行接管。
|
|
131
132
|
- 同一 pane 复制出第二个「Codinput」标签时,第二个面板只出提示、不渲染第二个编辑面(输入入口唯一)。
|
|
132
133
|
- 悬浮模式的手势只保留「拖回底部输入区 = 普通」;「拖入右侧栏 = 侧栏模式」已按产品决策舍弃。
|
|
134
|
+
- 页面重载后,若侧栏布局恢复了 Codinput 标签但尚未被点开过,主输入会先出现——dockkit 对重载恢复的标签是惰性挂载,点一次标签即恢复侧栏承载。
|
|
133
135
|
|
|
134
136
|
## 开发
|
|
135
137
|
|
|
@@ -149,15 +151,17 @@ npm run typecheck
|
|
|
149
151
|
### 改代码前值得先知道的宿主事实
|
|
150
152
|
|
|
151
153
|
- **接管点**:`conversation.composer.bar`(single 槽位,`priority:-1` 遮蔽官方条目)。卸载条目即官方输入框原样恢复。
|
|
152
|
-
- **唯一输入入口**:侧栏标签 body **挂载即承载**(不是按可见性——收起侧栏是 CSS 隐藏 + translate,body 仍挂载),主条目据此渲染 `null`;形态由 `承载 ? 'side' : prefs.mode`
|
|
154
|
+
- **唯一输入入口**:侧栏标签 body **挂载即承载**(不是按可见性——收起侧栏是 CSS 隐藏 + translate,body 仍挂载),主条目据此渲染 `null`;形态由 `承载 ? 'side' : prefs.mode` 派生,构造上不可能并存。承载声明挂在 body 生命周期上,因此标签定义必须 `keepMounted: true`:dockkit 默认会把非激活标签的 body 卸载,一旦切到同栏其他标签声明就消失、主输入回来(官方浏览器标签同款开关;注意重载后恢复的标签要**激活过一次** body 才挂载)。
|
|
153
155
|
- **撤销历史**:三态切换会重挂载编辑器,故按会话暂存 `EditorState`(`take/putEditorSnapshot`);扩展回调走模块级 hooks 槽,避免复用旧 state 时调到已卸载实例的 props。
|
|
154
156
|
- **官方侧灌入**(pick/claim/提交清空)用 `externalAnnotation` + `Transaction.addToHistory.of(false)`:不进撤销栈,撤销只记用户自己敲的内容。
|
|
155
157
|
- **画圆要写 `corner-shape: round`**:宿主根节点设了 `corner-shape: superellipse(1.5)`(全局超椭圆),只写 `border-radius:50%` 会渲染成圆角方。
|
|
156
158
|
- **小球不占槽位**:`conversation.session.header.corner` 是官方侧栏展开按钮的座位(single,占它会把官方按钮顶掉),故小球 portal 到 body、量标题栏矩形定位到标题栏下方。
|
|
159
|
+
- **slash「文件」行靠 filePicker 绑定活着**:官方 file 贡献的 `available` 读 `shell.canPickFiles()`,而 filePicker 由官方 InputBar 挂载时 `bindFilePicker` 绑上、卸载解绑——接管面挂载时必须补绑(`attachments.bindSessionFilePicker`),否则该行消失。**不要注册同名 contribution**:宿主 `register` 时即查重、直接 fail-loud。
|
|
160
|
+
- **关标签走 tab 域动作面**:`useTabInfo().tab.actions.close()` 关自己标签(dockkit 语义,唯一 docked 标签时自动垫 guide);会话定位别用诊断 `__dshCodinputSessionId`(表面卸载会清成 null),用 sideinput 总线的承载快照。
|
|
157
161
|
|
|
158
162
|
## 第三方归属
|
|
159
163
|
|
|
160
|
-
本项目的部分视觉素材与样式取值**复刻自 DeepSeek Harness**(`@deepseek-ai/dsh`,MIT License,Copyright (c) 2026 DeepSeek),包括若干 SVG 图标路径(权限盾牌系列、plus / paperclip / arrow-up
|
|
164
|
+
本项目的部分视觉素材与样式取值**复刻自 DeepSeek Harness**(`@deepseek-ai/dsh`,MIT License,Copyright (c) 2026 DeepSeek),包括若干 SVG 图标路径(权限盾牌系列、plus / paperclip / close / arrow-up 等)与输入框卡片、原图预览层的 CSS 取值。依 MIT 许可使用,原始版权与许可声明见仓库根目录 [NOTICE](./NOTICE) 与 [LICENSE](./LICENSE)。
|
|
161
165
|
|
|
162
166
|
内置第三方依赖:CodeMirror 6(MIT)、marked(MIT)、DOMPurify(Apache-2.0 / MPL-2.0 双许可)。
|
|
163
167
|
|
package/TESTING.md
CHANGED
|
@@ -25,10 +25,13 @@
|
|
|
25
25
|
- [ ] **悬浮 → 普通**:拖回底部输入区松手 → 回到原位(位置/尺寸记忆保留)
|
|
26
26
|
- [ ] **悬浮缩放**:拖四个边与四个角落 → 1:1 跟手、对边不动、不越出视口、不小于 360×140;松手后刷新页面尺寸保持
|
|
27
27
|
- [ ] **侧栏**:展开右侧栏 → 从指南页点「Codinput」→ 输入面出现在侧栏,**主输入位为空**
|
|
28
|
+
- [ ] **浏览其他标签不让位**:同栏加开「工作区文件」并切过去 → 主输入**仍不**回来(Codinput 标签存在即承载,靠 `keepMounted:true` 保 body 挂载)
|
|
29
|
+
- [ ] **重载后激活一次**:重载页面(侧栏恢复 Codinput+文件双标签、文件选中)→ 主输入先回来;点一次 Codinput 标签再切走 → 主输入不再回来(dockkit 对重载恢复的标签是惰性挂载,激活过才保活)
|
|
28
30
|
- [ ] **侧栏收起不让位**:收起右侧栏 → 主输入**不**回来,右上角出现圆形小球(标题栏下方、右对齐、与官方侧栏按钮不重叠)
|
|
29
31
|
- [ ] **小球唤回**:点小球 → 侧栏展开且 Codinput 可见,小球消失
|
|
30
32
|
- [ ] **退出侧栏**:关闭 Codinput 标签 → 主输入按 `prefs.mode` 原样恢复(普通卡片或悬浮)
|
|
31
|
-
- [ ]
|
|
33
|
+
- [ ] **侧栏内 /codinput 退出**:侧栏编辑器输入 `/codinput` 回车 → 接管关闭,**官方输入框**回到原位,**Codinput 标签自动关闭**(经 tab 域 `actions.close`;关闭唯一标签时侧栏随之收起);重开标签或 /codinput → 侧栏形态恢复(开标签自动启用)
|
|
34
|
+
- [ ] **复制标签**:右侧栏「分栏」后,两栏各开一个 Codinput 标签 → 编辑面跟随后被查看的一栏,两栏都可见时先开者持有、另一个只出提示;全局仍只有 1 个 `.cm-editor`
|
|
32
35
|
|
|
33
36
|
## 2. 编辑与草稿
|
|
34
37
|
|
|
@@ -51,8 +54,13 @@
|
|
|
51
54
|
|
|
52
55
|
- [ ] 模型下拉:显示当前模型与推理等级,切换后宿主 `/model` 一致
|
|
53
56
|
- [ ] 权限下拉:三预设 + glyph;选「完全权限」弹确认模态(勾选后才能启用)
|
|
54
|
-
- [ ]
|
|
57
|
+
- [ ] 附件:slash「添加 · 文件」(接管期间**照常可用**——接管面绑定 shell filePicker)、**粘贴图片** / **拖文件进卡片**(拖入时有描边提示)都能入草稿并出现芯片;移除附件正常;工具行**无**附件按钮
|
|
58
|
+
- [ ] **图片预览**:点图片缩略图 → 原图预览层(全屏遮罩+大图+右上关闭钮),Esc/背板按下/关闭钮三种方式可关,关闭后焦点还原到缩略图
|
|
59
|
+
- [ ] slash 菜单分组:空查询下 添加/指令/技能 各节连续(节头不重复),「文件」在添加节首,`/codinput` 在指令节首(字典序)
|
|
60
|
+
- [ ] **开标签即启用**:/codinput 退出后关闭 Codinput 标签再重新打开 → 自动恢复接管
|
|
55
61
|
- [ ] 发送按钮:草稿与附件皆空时禁用;空草稿手势转队列 Steer
|
|
62
|
+
- [ ] **停止形态**:流式回复期间主按钮变停止(停止方块 glyph、aria「停止」,含 blocked 审批等待),点击即中断(会话尾部出官方「已停止」状态);回复结束/中断后恢复发送;运行中草稿非空时按钮保持发送(提交走 steer/queue)
|
|
63
|
+
- [ ] 数据行与官方逐值一致:`{turns} 轮 {steps} 步 · {tps} tok/s`(tok/s = decodeTokens÷decodeMs,历史会话也有值)+ `{total} · 缓存命中 {pct}%` + 小圈;统计面板四行(模型用时/工具调用用时/TTFT 均值/TPS)与用量面板(缓存命中/未缓存输入/缓存读取/缓存写入(≠0)/输出)同官方语义
|
|
56
64
|
- [ ] 上下文小圈:百分比与分段面板数据合理
|
|
57
65
|
|
|
58
66
|
## 5. 设置
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="320" height="320" viewBox="0 0 320 320" fill="none" stroke="#ffffff" stroke-width="6.5" stroke-linecap="round" stroke-linejoin="round">
|
|
2
|
+
<!-- 左尖括号:发卡弯 + 内腿悬停收笔 + 底部小钩 -->
|
|
3
|
+
<path d="M 99 204 Q 93 215 86 205 L 35 148 L 88 87 Q 96 79 104 86 L 52 147 L 84 181" />
|
|
4
|
+
<!-- 右尖括号:闭合环带 -->
|
|
5
|
+
<path d="M 214 88 L 267 146 L 215 205 Q 223 216 230 209 L 282 150 L 231 88 Q 222 79 214 88 Z" />
|
|
6
|
+
<!-- 斜杠发卡 -->
|
|
7
|
+
<path d="M 138 154 L 169 59 A 5.3 5.3 0 0 1 179 62 L 151 146" />
|
|
8
|
+
<!-- 纸飞机 -->
|
|
9
|
+
<path d="M 227 121 L 87 189 L 130 207 L 130 240 Q 132 250 138 243 L 150 212 L 185 233 Z" />
|
|
10
|
+
<path d="M 130 207 L 227 121" />
|
|
11
|
+
</svg>
|
package/assets/icon.png
ADDED
|
Binary file
|
package/assets/icon.svg
CHANGED
|
@@ -1 +1,11 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="320" height="320" viewBox="0 0 320 320" fill="none" stroke="#4632de" stroke-width="6.5" stroke-linecap="round" stroke-linejoin="round">
|
|
2
|
+
<!-- 左尖括号:发卡弯 + 内腿悬停收笔 + 底部小钩 -->
|
|
3
|
+
<path d="M 99 204 Q 93 215 86 205 L 35 148 L 88 87 Q 96 79 104 86 L 52 147 L 84 181" />
|
|
4
|
+
<!-- 右尖括号:闭合环带 -->
|
|
5
|
+
<path d="M 214 88 L 267 146 L 215 205 Q 223 216 230 209 L 282 150 L 231 88 Q 222 79 214 88 Z" />
|
|
6
|
+
<!-- 斜杠发卡 -->
|
|
7
|
+
<path d="M 138 154 L 169 59 A 5.3 5.3 0 0 1 179 62 L 151 146" />
|
|
8
|
+
<!-- 纸飞机 -->
|
|
9
|
+
<path d="M 227 121 L 87 189 L 130 207 L 130 240 Q 132 250 138 243 L 150 212 L 185 233 Z" />
|
|
10
|
+
<path d="M 130 207 L 227 121" />
|
|
11
|
+
</svg>
|
|
Binary file
|
package/assets/preview-float.png
CHANGED
|
Binary file
|
|
Binary file
|
package/assets/preview-side.png
CHANGED
|
Binary file
|
package/assets/preview-split.png
CHANGED
|
Binary file
|