dsh-group-status 0.0.0-stage → 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 +16 -0
- package/LICENSE +21 -0
- package/README.en.md +203 -0
- package/README.md +200 -2
- package/cordis.patch.yml +5 -0
- package/icon.svg +11 -0
- package/lib/client.js +4781 -0
- package/lib/client.js.map +1 -0
- package/lib/index.js +45 -0
- package/lib/tsconfig.tsbuildinfo +1 -0
- package/lib/types/client/WorkspacePicker.d.ts +59 -0
- package/lib/types/client/WorkspacePicker.d.ts.map +1 -0
- package/lib/types/client/WorkspacePicker.js +126 -0
- package/lib/types/client/WorkspacePicker.js.map +1 -0
- package/lib/types/client/badge-settings.d.ts +68 -0
- package/lib/types/client/badge-settings.d.ts.map +1 -0
- package/lib/types/client/badge-settings.js +76 -0
- package/lib/types/client/badge-settings.js.map +1 -0
- package/lib/types/client/contract/slots.d.ts +451 -0
- package/lib/types/client/contract/slots.d.ts.map +1 -0
- package/lib/types/client/contract/slots.js +10 -0
- package/lib/types/client/contract/slots.js.map +1 -0
- package/lib/types/client/cross-plugin-summary.d.ts +134 -0
- package/lib/types/client/cross-plugin-summary.d.ts.map +1 -0
- package/lib/types/client/cross-plugin-summary.js +286 -0
- package/lib/types/client/cross-plugin-summary.js.map +1 -0
- package/lib/types/client/group-status.d.ts +80 -0
- package/lib/types/client/group-status.d.ts.map +1 -0
- package/lib/types/client/group-status.js +112 -0
- package/lib/types/client/group-status.js.map +1 -0
- package/lib/types/client/index.d.ts +42 -0
- package/lib/types/client/index.d.ts.map +1 -0
- package/lib/types/client/index.js +269 -0
- package/lib/types/client/index.js.map +1 -0
- package/lib/types/client/locales.d.ts +242 -0
- package/lib/types/client/locales.d.ts.map +1 -0
- package/lib/types/client/locales.js +240 -0
- package/lib/types/client/locales.js.map +1 -0
- package/lib/types/client/navigation.d.ts +149 -0
- package/lib/types/client/navigation.d.ts.map +1 -0
- package/lib/types/client/navigation.js +322 -0
- package/lib/types/client/navigation.js.map +1 -0
- package/lib/types/client/pin-order.d.ts +31 -0
- package/lib/types/client/pin-order.d.ts.map +1 -0
- package/lib/types/client/pin-order.js +31 -0
- package/lib/types/client/pin-order.js.map +1 -0
- package/lib/types/client/rows/AnimatedRows.d.ts +44 -0
- package/lib/types/client/rows/AnimatedRows.d.ts.map +1 -0
- package/lib/types/client/rows/AnimatedRows.js +139 -0
- package/lib/types/client/rows/AnimatedRows.js.map +1 -0
- package/lib/types/client/rows/GroupBadge.d.ts +43 -0
- package/lib/types/client/rows/GroupBadge.d.ts.map +1 -0
- package/lib/types/client/rows/GroupBadge.js +121 -0
- package/lib/types/client/rows/GroupBadge.js.map +1 -0
- package/lib/types/client/rows/Rows.d.ts +114 -0
- package/lib/types/client/rows/Rows.d.ts.map +1 -0
- package/lib/types/client/rows/Rows.js +362 -0
- package/lib/types/client/rows/Rows.js.map +1 -0
- package/lib/types/client/rows/WorkspaceBrowser.d.ts +8 -0
- package/lib/types/client/rows/WorkspaceBrowser.d.ts.map +1 -0
- package/lib/types/client/rows/WorkspaceBrowser.js +923 -0
- package/lib/types/client/rows/WorkspaceBrowser.js.map +1 -0
- package/lib/types/client/session-actions/ArchiveSession.d.ts +23 -0
- package/lib/types/client/session-actions/ArchiveSession.d.ts.map +1 -0
- package/lib/types/client/session-actions/ArchiveSession.js +91 -0
- package/lib/types/client/session-actions/ArchiveSession.js.map +1 -0
- package/lib/types/client/session-actions/ForkSession.d.ts +9 -0
- package/lib/types/client/session-actions/ForkSession.d.ts.map +1 -0
- package/lib/types/client/session-actions/ForkSession.js +18 -0
- package/lib/types/client/session-actions/ForkSession.js.map +1 -0
- package/lib/types/client/session-actions/PinSession.d.ts +14 -0
- package/lib/types/client/session-actions/PinSession.d.ts.map +1 -0
- package/lib/types/client/session-actions/PinSession.js +47 -0
- package/lib/types/client/session-actions/PinSession.js.map +1 -0
- package/lib/types/client/session-actions/RenameSession.d.ts +18 -0
- package/lib/types/client/session-actions/RenameSession.d.ts.map +1 -0
- package/lib/types/client/session-actions/RenameSession.js +73 -0
- package/lib/types/client/session-actions/RenameSession.js.map +1 -0
- package/lib/types/client/session-actions/RowActionToast.d.ts +12 -0
- package/lib/types/client/session-actions/RowActionToast.d.ts.map +1 -0
- package/lib/types/client/session-actions/RowActionToast.js +54 -0
- package/lib/types/client/session-actions/RowActionToast.js.map +1 -0
- package/lib/types/client/session-actions/derived.d.ts +12 -0
- package/lib/types/client/session-actions/derived.d.ts.map +1 -0
- package/lib/types/client/session-actions/derived.js +24 -0
- package/lib/types/client/session-actions/derived.js.map +1 -0
- package/lib/types/client/shortcuts.d.ts +46 -0
- package/lib/types/client/shortcuts.d.ts.map +1 -0
- package/lib/types/client/shortcuts.js +89 -0
- package/lib/types/client/shortcuts.js.map +1 -0
- package/lib/types/client/stores.d.ts +56 -0
- package/lib/types/client/stores.d.ts.map +1 -0
- package/lib/types/client/stores.js +69 -0
- package/lib/types/client/stores.js.map +1 -0
- package/lib/types/client/tree.d.ts +208 -0
- package/lib/types/client/tree.d.ts.map +1 -0
- package/lib/types/client/tree.js +458 -0
- package/lib/types/client/tree.js.map +1 -0
- package/lib/types/index.d.ts +56 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/index.js +44 -0
- package/lib/types/index.js.map +1 -0
- package/package.json +132 -4
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# 更新日志
|
|
2
|
+
|
|
3
|
+
本文件记录面向使用者的重要变更。细粒度提交历史见 git log。
|
|
4
|
+
|
|
5
|
+
## 未发布
|
|
6
|
+
|
|
7
|
+
## 0.2.0-rc.2-fork1
|
|
8
|
+
|
|
9
|
+
- **feat** 折叠分组聚合徽标:收起的文件夹行显示进行中(转圈)、待审批(黄点)、已完成(绿点)的聚合状态,带数字与悬停明细。
|
|
10
|
+
- **feat** 跨插件聚合(可选):接入 dsh-later 定时任务(时钟图标)与 dsh-gitea-dispatch 等待评审(列表笔图标),未安装时静默降级。
|
|
11
|
+
- **feat** 设置项 `showCompletedInBadge`:可关闭折叠徽标上的「已完成」绿点,默认开启。
|
|
12
|
+
- **feat** 无障碍:徽标带 `role="img"` + 本地化 `aria-label`,悬停 `title` 同文案。
|
|
13
|
+
- **refactor** 拆分 `badge-settings` / `group-status` 模块,新增 `GroupBadge` 组件。
|
|
14
|
+
- **refactor** 上游 `tree.ts` / `Rows.tsx` 代码下沉,侧栏展开态与官方版本逐像素一致。
|
|
15
|
+
- **docs** 中英双语 README + 上游升级手册 + 跨插件摘要模板说明。
|
|
16
|
+
- **test** 上游 spec 本地可跑(vitest + jsdom),新增折叠聚合用例(计数、待处理类互斥、子智能体、空白/归档跳过、跨插件来源)。
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 DeepSeek
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.en.md
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
<img src="icon.svg" width="72" alt="dsh-group-status"/>
|
|
4
|
+
|
|
5
|
+
# dsh-group-status — live status on collapsed folders
|
|
6
|
+
|
|
7
|
+
[中文](./README.md) | **English**
|
|
8
|
+
|
|
9
|
+
[](https://github.com/WuJiaoJue/dsh-group-status)
|
|
10
|
+
[](LICENSE)
|
|
11
|
+
[](https://github.com/deepseek-ai/deepseek-harness)
|
|
12
|
+
|
|
13
|
+
</div>
|
|
14
|
+
|
|
15
|
+
> In the DSH sidebar, **folding a workspace group takes every session status inside down with it** — running, approvals, reviews, all gone. This plugin gives the collapsed folder row its own aggregated badge: **yellow = pending approval, spinner = running, green = completed**, plus clock and review icons fed by other plugins, with a count and hover details. Expanded groups are untouched — child rows carry their own statuses.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Preview
|
|
20
|
+
|
|
21
|
+
**Collapsed folder rows carry the aggregate badge** — `tmp` has one running session (spinner), one completed (green dot), one scheduled task (clock), count `3`:
|
|
22
|
+
|
|
23
|
+
<p align="center">
|
|
24
|
+
<img src="docs/media/screenshot-folders.png" width="267" alt="Collapsed sidebar group tmp: spinner, green dot, clock icon and count 3"/>
|
|
25
|
+
</p>
|
|
26
|
+
|
|
27
|
+
**Hover for details** — the hover card appends aggregated detail lines under the path and creation time:
|
|
28
|
+
|
|
29
|
+
<p align="center">
|
|
30
|
+
<img src="docs/media/screenshot-hover.png" width="300" alt="Hover card: 1 Waiting for answer · 1 Running"/>
|
|
31
|
+
</p>
|
|
32
|
+
|
|
33
|
+
> The badge reuses DSH's native `StateDot`, so colors stay identical to the session rows. Both images are real screenshots.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## How to use
|
|
38
|
+
|
|
39
|
+
Fold any group that has live sessions; a badge appears after the folder name:
|
|
40
|
+
|
|
41
|
+
| Glyph | Meaning | Color |
|
|
42
|
+
|---|---|---|
|
|
43
|
+
| Yellow dot | Pending approval / plan review / answer inside | warning (same as rows) |
|
|
44
|
+
| Spinner | Running sessions inside, incl. running subagents | ongoing (`StateDot` animation) |
|
|
45
|
+
| Green dot | Completed-unread sessions inside | done (same as the row) |
|
|
46
|
+
| Clock | Scheduled tasks inside (data from dsh-later) | purple · orange (≤5 min) · red (overdue) |
|
|
47
|
+
| List-pen | Sessions waiting for a PR review (data from dsh-gitea-dispatch) | amber · red (overdue) |
|
|
48
|
+
|
|
49
|
+
Rules:
|
|
50
|
+
|
|
51
|
+
- **Completed reaches the badge**: `done` (completed-unread) now shows a green dot while folded, reusing the same `StateDot` state as the session row; a group with nothing but completed sessions shows a badge just like any other.
|
|
52
|
+
- **The count** = approvals + running + completed + sessions with scheduled tasks + sessions waiting for review. Whenever a badge renders it carries the count, including a single-session `1`.
|
|
53
|
+
- **Hover details**: the folder row's hover card appends lines in the order `approval · plan review · answer · running · subagents · waiting review · scheduled tasks · completed`, e.g. `1 Waiting for answer · 1 Running`.
|
|
54
|
+
- **Expanding defers to the rows**: the aggregate badge only renders while collapsed; expanded groups keep their per-row statuses with no duplication.
|
|
55
|
+
- **Accessible**: the badge is `role="img"` with a localized `aria-label` (e.g. `1 Waiting for answer · 1 Running`) and the same text as its `title`.
|
|
56
|
+
|
|
57
|
+
### Settings
|
|
58
|
+
|
|
59
|
+
Settings → Plugins → **dsh-group-status** (the config form on the plugin's page):
|
|
60
|
+
|
|
61
|
+
| Field | Default | Meaning |
|
|
62
|
+
|---|---|---|
|
|
63
|
+
| `showCompletedInBadge` | `true` | Whether the folded badge shows a green "completed" dot |
|
|
64
|
+
|
|
65
|
+
Switching it off takes `done` out of the folded row's aggregate entirely — no green dot, no contribution to the badge count, and it no longer keeps the badge alive, so a group with nothing but completed sessions shows no badge again. **The green dot on a session row itself is unaffected**: that is row-level state, not a folder hint.
|
|
66
|
+
|
|
67
|
+
Changes apply live, with no refresh. When the settings face cannot be read (e.g. the Host serves no settings service), it falls back to the default "show", matching the schema default — failing to read a config is not the user turning it off.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Feature overview
|
|
72
|
+
|
|
73
|
+
- **Visible when folded**: the aggregate only exists while collapsed; an expanded sidebar is pixel-identical to stock.
|
|
74
|
+
- **Same source of truth as rows**: priority, colors and wording all reuse the row derivation and `StateDot`; blank and archived sessions are skipped.
|
|
75
|
+
- **Cross-plugin aggregation** (optional): scheduled tasks from dsh-later, waiting PR reviews from dsh-gitea-dispatch — works fine with neither installed.
|
|
76
|
+
- **Usable with zero config**: sensible defaults out of the box; the one setting, `showCompletedInBadge`, can drop the green "completed" dot from the folded badge.
|
|
77
|
+
- **No stock files touched**: not a single file of the published `dsh-client-ui-workspace` is modified; all changes live in this repo's source, and the profile patch is two lines (add this package, disable the stock row).
|
|
78
|
+
- **Localized**: follows the DSH UI language (中文 / English) by reusing the stock locale keys; only `status.waitingReview` and `status.scheduled` are new.
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Cross-plugin status (optional)
|
|
83
|
+
|
|
84
|
+
### Consumer: how this plugin reads others
|
|
85
|
+
|
|
86
|
+
When sessions inside a group have scheduled tasks or wait on a PR review, the badge gains one icon each. This plugin does **not** poll anything itself — it asks the publishing plugin for a summary:
|
|
87
|
+
|
|
88
|
+
| Publisher | Provides | Consumer entry point |
|
|
89
|
+
|---|---|---|
|
|
90
|
+
| [dsh-later](https://github.com/WuJiaoJue/dsh-later) | `useScheduleSummary()`: session id → `{ count, pausedCount, nextAt, state }` | `require('dsh-later/client')` |
|
|
91
|
+
| dsh-gitea-dispatch | `useWaitingSummary()`: session id → `{ prNumber, state }` | `require('dsh-gitea-dispatch/client')` |
|
|
92
|
+
|
|
93
|
+
- When either plugin is **absent or disabled, the integration degrades silently**: no icon, everything else keeps working, no errors and no idle polling.
|
|
94
|
+
- This repo declares both external modules in `package.json` under `dsh.client.external`.
|
|
95
|
+
|
|
96
|
+
### Publisher: exposing your own summary
|
|
97
|
+
|
|
98
|
+
A plugin that wants to publish its state for others copies the skeleton in [`src/client/cross-plugin-summary.ts`](src/client/cross-plugin-summary.ts): `createSummaryStore` (a subscribable store) + `createSummaryRegistry` (heals late-registered stores) + `summarizeGroup` / `mapEquals` / `entryFor` / `normalizeSessionId` (folding and id normalization).
|
|
99
|
+
|
|
100
|
+
> ⚠️ **Copy it, do not import it.** Cross-plugin value imports do not resolve in this project — measured, the error is `Could not resolve "dsh-group-status"`: other plugins do not depend on this package, a client bundle is a self-contained closure factory, and the bundle-purity gate only rejects the `@deepseek-ai/*` prefix, so a cross-plugin import does not even get its dedicated diagnostic.
|
|
101
|
+
|
|
102
|
+
The working shape is: copy the template into the provider → the provider calls `registry.setStore(store)` and re-exports `registry.useSummary` from its client entry → the consumer then uses it through `require('<provider>/client')`. Every improvement to the template is locked by `tests/cross-plugin-summary.node.test.mjs`.
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Quick start
|
|
107
|
+
|
|
108
|
+
### Install into DSH
|
|
109
|
+
|
|
110
|
+
This package is a **fork override**: it registers the same slots as the stock `dsh-client-ui-workspace` and disables the stock row (patch in `cordis.patch.yml`). Build artifacts are committed, so installing from GitHub needs no local build:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
dsh plugin --profile web add "github:WuJiaoJue/dsh-group-status"
|
|
114
|
+
# Takes effect after restarting dsh web (the whole sidebar package is swapped)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
For local development, link a checkout and rebuild as you edit `src/`:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
git clone https://github.com/WuJiaoJue/dsh-group-status.git
|
|
121
|
+
cd dsh-group-status
|
|
122
|
+
pnpm install && pnpm build
|
|
123
|
+
|
|
124
|
+
dsh plugin --profile web add "link:$PWD"
|
|
125
|
+
# restart dsh web
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
> Dev tip: `pnpm watch` rebuilds on every `src/` change — but the sidebar is swapped as a whole, so **a dsh web restart is still required**.
|
|
129
|
+
|
|
130
|
+
### Verify
|
|
131
|
+
|
|
132
|
+
1. Fold a group with running / pending sessions → a badge appears after the folder name;
|
|
133
|
+
2. Hover the folder row → the detail lines appear (matching the badge's wording);
|
|
134
|
+
3. Expand the group → the badge disappears and child rows show their own statuses;
|
|
135
|
+
4. No errors in the browser console.
|
|
136
|
+
|
|
137
|
+
### Roll back
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
dsh plugin --profile web remove dsh-group-status
|
|
141
|
+
# Both patch lines are withdrawn together; the stock row comes back. Restart to apply.
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Compatibility
|
|
147
|
+
|
|
148
|
+
| Item | Value |
|
|
149
|
+
|---|---|
|
|
150
|
+
| DSH core | `0.2.0-rc.2` |
|
|
151
|
+
| peer dependency | `@deepseek-ai/cordis ~4.0.4` |
|
|
152
|
+
| Upstream base | `@deepseek-ai/dsh-client-ui-workspace 0.2.0-rc.2` (source vendored into `src/`) |
|
|
153
|
+
| Install shape | fork override: same slots registered, stock row disabled via `cordis.patch.yml` |
|
|
154
|
+
| Optional partners | dsh-later (schedule summary), dsh-gitea-dispatch (waiting-review summary) |
|
|
155
|
+
|
|
156
|
+
Every upstream generation requires a manual rebase — see the [upgrade runbook](./docs/upgrading.md). If upstream renames a slot, changes a component signature or the context contract, this package will not follow on its own.
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Development
|
|
161
|
+
|
|
162
|
+
```sh
|
|
163
|
+
pnpm install
|
|
164
|
+
pnpm build # tsc typecheck + tsdown bundle → lib/
|
|
165
|
+
pnpm watch # rebuild on src/ changes (a dsh web restart is still required)
|
|
166
|
+
pnpm test # = test:node (node --test, 12 cases) + test:spec (vitest + jsdom, 96 cases)
|
|
167
|
+
pnpm test:spec # the upstream spec suite only
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
`tests/` is a copy of the upstream suite plus this repository's own [tests/group-status.client.spec.ts](tests/group-status.client.spec.ts), which covers the fold aggregation itself (counts, priority, cross-plugin sources, blank/archived skipping).
|
|
171
|
+
|
|
172
|
+
Seven further upstream specs only run inside the DSH monorepo: they either need `dsh-client-test-runtime`'s deep imports of **unpublished sources**, or take runtime values out of a published `…/client` bundle whose closure expects the host app to preload its whole dependency set. They are explicitly skipped at the top of [vitest.config.ts](vitest.config.ts) with the reason spelled out per group — **do not light them up with stubs**; that would only test the stub.
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Known limitations
|
|
177
|
+
|
|
178
|
+
- **Upstream bumps need a manual rebase**: the upstream source is vendored (`src/`, `tests/`) and this is not a stable public API; slot names, component signatures and context contracts may shift under it. Steps are in the [upgrade runbook](./docs/upgrading.md).
|
|
179
|
+
- **One extra full traversal while collapsed**: aggregation shares the expanded derivation, so huge groups (hundreds of sessions) cost one extra traverse per status change — same order as expanded rendering, acceptable.
|
|
180
|
+
- **It produces no status itself**: the cross-plugin icons depend entirely on the summary APIs published by dsh-later / dsh-gitea-dispatch. Without them you simply lose those two icons.
|
|
181
|
+
- **The count is coarser than the details**: scheduled tasks are counted per *session*, not per task; the exact task count lives in dsh-later's own UI.
|
|
182
|
+
- **Collapsed sidebar only**: this plugin only adds an aggregate display — it does not touch the session state machine or the per-row badge predicates.
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Technical documentation
|
|
187
|
+
|
|
188
|
+
Developer and maintainer material, kept out of this README:
|
|
189
|
+
|
|
190
|
+
- [Upstream upgrade runbook](./docs/upgrading.md) — where the baseline came from, what changed locally, how to rebase and verify on the next upstream release
|
|
191
|
+
- [Cross-plugin summary template](./src/client/cross-plugin-summary.ts) — the provider-side skeleton itself; its header is the design note and carries the measured "copy, do not import" evidence
|
|
192
|
+
|
|
193
|
+
## License
|
|
194
|
+
|
|
195
|
+
MIT (inherited from the upstream `@deepseek-ai/dsh-client-ui-workspace`).
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
<div align="center">
|
|
200
|
+
|
|
201
|
+
<img src="icon.svg" width="48" alt="dsh-group-status"/>
|
|
202
|
+
|
|
203
|
+
</div>
|
package/README.md
CHANGED
|
@@ -1,3 +1,201 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<img src="icon.svg" width="72" alt="dsh-group-status"/>
|
|
4
|
+
|
|
5
|
+
# dsh-group-status — 收起的分组也看得见活
|
|
6
|
+
|
|
7
|
+
**中文** | [English](./README.en.md)
|
|
8
|
+
|
|
9
|
+
[](https://github.com/WuJiaoJue/dsh-group-status)
|
|
10
|
+
[](LICENSE)
|
|
11
|
+
[](https://github.com/deepseek-ai/deepseek-harness)
|
|
12
|
+
|
|
13
|
+
</div>
|
|
14
|
+
|
|
15
|
+
> DSH 侧栏里**分组一收起,里面会话的状态就跟着折叠消失**——进行中、待审批、等待评审全看不见了。这个插件让收起的文件夹行自己长出聚合徽标:**黄点待审批、转圈进行中**,再挂上定时任务与等待评审两个图标,带数字、悬停看明细;展开后一个像素都不改,子行自带状态。
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 效果预览
|
|
20
|
+
|
|
21
|
+
**收起的文件夹行自带聚合徽标** —— 下面 `tmp` 有 1 个进行中(转圈)、1 个已完成(绿点)、1 个定时任务(时钟),数字 `3`:
|
|
22
|
+
|
|
23
|
+
<p align="center">
|
|
24
|
+
<img src="docs/media/screenshot-folders.png" width="267" alt="侧栏中收起的 tmp 分组:转圈、绿点、时钟图标与数字 3"/>
|
|
25
|
+
</p>
|
|
26
|
+
|
|
27
|
+
**悬停看明细** —— hover 卡在原路径、创建时间下面追加聚合明细行:
|
|
28
|
+
|
|
29
|
+
<p align="center">
|
|
30
|
+
<img src="docs/media/screenshot-hover.png" width="300" alt="悬停卡片:1 等待回答 · 1 进行中"/>
|
|
31
|
+
</p>
|
|
32
|
+
|
|
33
|
+
> 徽标复用的就是 DSH 原生 `StateDot`,颜色与行内状态同源,不会走样。上面两张是实机截图。
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 使用方法
|
|
38
|
+
|
|
39
|
+
收起任意有活会话的分组,文件夹名后面出现徽标:
|
|
40
|
+
|
|
41
|
+
| 符号 | 含义 | 颜色 |
|
|
42
|
+
|---|---|---|
|
|
43
|
+
| 黄点 | 组内有待审批 / 计划待审 / 待回答 | warning(与行内一致)|
|
|
44
|
+
| 转圈 | 组内有进行中(含运行中的子智能体) | ongoing(`StateDot` 转圈动画)|
|
|
45
|
+
| 绿点 | 组内有已完成未读的会话 | done(与行内一致)|
|
|
46
|
+
| 时钟 | 组内有定时任务(数据来自 dsh-later) | 紫 · 橙(≤5 分钟)· 红(已到期)|
|
|
47
|
+
| 列表笔 | 组内有等待评审的 PR(数据来自 dsh-gitea-dispatch) | 琥珀 · 红(已超时)|
|
|
48
|
+
|
|
49
|
+
规则:
|
|
50
|
+
|
|
51
|
+
- **已完成进徽标**:`done`(已完成未读)折叠时也显示绿点,和会话行的绿点同一个 `StateDot` 状态;一组只剩已完成时徽标照常出现。
|
|
52
|
+
- **数字** = 待审批 + 进行中 + 已完成 + 有定时任务的会话 + 等待评审的会话;有徽标就带数字,只有一个会话时也会显示 `1`。
|
|
53
|
+
- **悬停明细**:文件夹行 hover 卡在路径、创建时间下面,按 `等待审批 · 计划待审 · 等待回答 · 进行中 · 子智能体 · 等待评审 · 定时任务 · 已完成` 的顺序追加明细行,例如 `1 等待回答 · 1 进行中`。
|
|
54
|
+
- **展开即让位**:聚合徽标只在折叠时出现;展开后子行自带状态,不重复显示。
|
|
55
|
+
- **无障碍**:徽标是 `role="img"` + 本地化 `aria-label`(如 `1 等待回答 · 1 进行中`),悬停 `title` 同文案,读屏与鼠标都读得到。
|
|
56
|
+
|
|
57
|
+
### 设置项
|
|
58
|
+
|
|
59
|
+
设置 → 插件 → **dsh-group-status**(插件详情页的配置表单):
|
|
60
|
+
|
|
61
|
+
| 字段 | 默认 | 说明 |
|
|
62
|
+
|---|---|---|
|
|
63
|
+
| `showCompletedInBadge` | `true` | 折叠徽标是否显示「已完成」绿点 |
|
|
64
|
+
|
|
65
|
+
关闭后,`done` 完全退出折叠行的聚合提示——不画绿点、不计入徽标数字、不参与「是否显示徽标」的判断,等于回到「一组只剩已完成时不出现徽标」。**会话行自身的绿点不受影响**:那是行级状态,不是分组提示。
|
|
66
|
+
|
|
67
|
+
改动即时生效,无需刷新。设置面读不到时(例如宿主未提供设置服务)回落为默认「显示」,与 schema 默认值同源——读不到配置不等于用户关掉了。
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## 特性一览
|
|
72
|
+
|
|
73
|
+
- **收起可见**:聚合状态只在分组折叠时出现,展开后的侧栏与官方版本逐像素一致。
|
|
74
|
+
- **与行内同源**:优先级、颜色、文案全部复用行内状态的派生逻辑与 `StateDot`,跳过空白会话与已归档会话。
|
|
75
|
+
- **跨插件聚合**(可选):dsh-later 的定时任务、dsh-gitea-dispatch 的等待评审,两个都没装也照常工作——见下。
|
|
76
|
+
- **零配置可用**:默认开箱即用;唯一的设置项 `showCompletedInBadge` 可关掉折叠徽标上的「已完成」绿点。
|
|
77
|
+
- **本体零改动**:官方 `dsh-client-ui-workspace` 包文件一个不动;改动全在本仓库源码里,profile 补丁只有两条(装本包、禁用官方行)。
|
|
78
|
+
- **多语言**:跟随 DSH 界面语言(中文 / English),复用官方文案键,只新增了 `status.waitingReview` 与 `status.scheduled`。
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## 跨插件状态(可选)
|
|
83
|
+
|
|
84
|
+
### 消费方:本插件怎么拿别人的状态
|
|
85
|
+
|
|
86
|
+
组内会话如果挂着定时任务或等待评审,徽标会各多一个图标。本插件**不自己轮询**,而是向数据源插件要一份摘要:
|
|
87
|
+
|
|
88
|
+
| 数据源 | 提供 | 消费方接入 |
|
|
89
|
+
|---|---|---|
|
|
90
|
+
| [dsh-later](https://github.com/WuJiaoJue/dsh-later) | `useScheduleSummary()`:会话 id → `{ count, pausedCount, nextAt, state }` | `require('dsh-later/client')` |
|
|
91
|
+
| dsh-gitea-dispatch | `useWaitingSummary()`:会话 id → `{ prNumber, state }` | `require('dsh-gitea-dispatch/client')` |
|
|
92
|
+
|
|
93
|
+
- 两个插件**未安装 / 未启用时静默降级**:图标不出现,其余徽标照常,不会报错也不会空转。
|
|
94
|
+
- 本仓库 `package.json` 的 `dsh.client.external` 声明了这两个外部模块。
|
|
95
|
+
|
|
96
|
+
### 提供方:想暴露摘要的插件看这里
|
|
97
|
+
|
|
98
|
+
别的插件要把自己的状态暴露给别人消费,可复用 [`src/client/cross-plugin-summary.ts`](src/client/cross-plugin-summary.ts) 这份骨架:`createSummaryStore`(可订阅 store)+ `createSummaryRegistry`(迟到的 store 自愈)+ `summarizeGroup` / `mapEquals` / `entryFor` / `normalizeSessionId`(折叠与 id 归一)。
|
|
99
|
+
|
|
100
|
+
> ⚠️ **复制,不要 import。** 跨插件值导入在本项目走不通,实测报错 `Could not resolve "dsh-group-status"`:别的插件不依赖本包,客户端 bundle 又是自包含的闭包工厂,而 bundle 纯净度闸门只拦 `@deepseek-ai/*` 前缀,连"跨插件值导入"的专用报错都不会给。
|
|
101
|
+
|
|
102
|
+
正确接法:把模板**复制**进 provider 插件 → provider 用 `registry.setStore(store)` 登记、从自己的 client 入口导出 `registry.useSummary` → consumer 再 `require('<provider>/client')` 用它的 hook。模板的每条改进都由 `tests/cross-plugin-summary.node.test.mjs` 锁住。
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## 快速开始
|
|
107
|
+
|
|
108
|
+
### 安装到 DSH
|
|
109
|
+
|
|
110
|
+
本包是一个 **fork 覆盖包**:注册与官方 `dsh-client-ui-workspace` 相同的槽位,并把官方那一行 disable(补丁见 `cordis.patch.yml`)。构建产物随仓库提交,从 GitHub 直接装即可,不需要本地构建:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
dsh plugin --profile web add "github:WuJiaoJue/dsh-group-status"
|
|
114
|
+
# 重启 dsh web 后生效(侧栏是整包替换,需重新生成浏览器模块)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
本机开发时用 link,改完 `src/` 重建即可生效:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
git clone https://github.com/WuJiaoJue/dsh-group-status.git
|
|
121
|
+
cd dsh-group-status
|
|
122
|
+
pnpm install && pnpm build
|
|
123
|
+
|
|
124
|
+
dsh plugin --profile web add "link:$PWD"
|
|
125
|
+
# 重启 dsh web
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
> 开发提示:`pnpm watch` 监听 `src/` 自动重建;但侧栏是整包替换,**改完仍需重启 dsh web**。
|
|
129
|
+
|
|
130
|
+
### 验证
|
|
131
|
+
|
|
132
|
+
1. 找一个有进行中 / 待审批会话的分组 → 收起 → 文件夹名后出现徽标;
|
|
133
|
+
2. 悬停文件夹行 → 明细行出现(与徽标文案一致);
|
|
134
|
+
3. 展开分组 → 徽标消失,子行自带状态;
|
|
135
|
+
4. 浏览器 console 无报错。
|
|
136
|
+
|
|
137
|
+
### 回滚
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
dsh plugin --profile web remove dsh-group-status
|
|
141
|
+
# 两条补丁一起撤,官方行自动回来;重启 dsh web 生效
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## 兼容性
|
|
147
|
+
|
|
148
|
+
| 项 | 值 |
|
|
149
|
+
|---|---|
|
|
150
|
+
| DSH 内核 | `0.2.0-rc.2` |
|
|
151
|
+
| peer 依赖 | `@deepseek-ai/cordis ~4.0.4` |
|
|
152
|
+
| 上游基线 | `@deepseek-ai/dsh-client-ui-workspace 0.2.0-rc.2`(源码已 vendored 进本仓库 `src/`)|
|
|
153
|
+
| 安装形态 | fork 覆盖包:同槽位注册 + `cordis.patch.yml` 禁用官方行 |
|
|
154
|
+
| 可选搭档 | dsh-later(定时任务摘要)、dsh-gitea-dispatch(等待评审摘要)|
|
|
155
|
+
|
|
156
|
+
上游一换代就得按[升级手册](./docs/upgrading.md) rebase 一次;上游改槽位名、组件签名或上下文契约时,本包不会自动跟上。
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## 开发
|
|
161
|
+
|
|
162
|
+
```sh
|
|
163
|
+
pnpm install
|
|
164
|
+
pnpm build # tsc 类型检查 + tsdown 打包 → lib/
|
|
165
|
+
pnpm watch # 监听 src/ 自动重建(改完仍需重启 dsh web,侧栏是整包替换)
|
|
166
|
+
pnpm test # = test:node(node --test,12 用例)+ test:spec(vitest + jsdom,96 用例)
|
|
167
|
+
pnpm test:spec # 只跑上游 spec 套件
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
`tests/` 是上游测试副本,外加本仓库自己的 [tests/group-status.client.spec.ts](tests/group-status.client.spec.ts)——它覆盖折叠聚合本身(计数、待处理类互斥、子智能体、空白/归档跳过、跨插件来源)。
|
|
171
|
+
|
|
172
|
+
上游另有 7 个 spec 只能在 DSH monorepo 里跑:它们要么依赖 `dsh-client-test-runtime` 对**未发布源码**的深导入,要么从已发布的 `…/client` 产物里取运行期值、而那个闭包要求宿主预载整套依赖。本地在 [vitest.config.ts](vitest.config.ts) 顶部显式跳过了它们,原因逐条写在文件里——**不要用假实现把它们点亮**,那只会测试假实现。
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## 已知限制
|
|
177
|
+
|
|
178
|
+
- **上游换代必须手工 rebase**:本包 vendored 了上游源码(`src/`、`tests/`),用的不是稳定公共 API;上游动槽位名、组件签名或上下文契约时要跟着改,步骤见[升级手册](./docs/upgrading.md)。
|
|
179
|
+
- **折叠时多一次全量遍历**:聚合计数与展开态共用同一份派生,超大分组(数百会话)每次状态变更多一次 traverse,与展开渲染同量级,可接受。
|
|
180
|
+
- **状态不自己产生**:跨插件图标完全依赖 dsh-later / dsh-gitea-dispatch 暴露的摘要 API,它们不装就只是没有那两个图标,不影响本体。
|
|
181
|
+
- **数字比明细粗**:定时任务按「组内有定时任务的会话数」计,不按任务条数累计;具体条数在 dsh-later 自己的界面上看。
|
|
182
|
+
- **只覆盖侧栏折叠态**:本插件只加聚合显示,不改会话状态机、不改行内 badge 的判据。
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## 技术文档
|
|
187
|
+
|
|
188
|
+
- [上游升级手册](./docs/upgrading.md) — 基线怎么来的、本地改了哪几处、上游换代时怎么 rebase 与验证
|
|
189
|
+
- [跨插件摘要模板](./src/client/cross-plugin-summary.ts) — 提供方(provider)侧骨架本体,文件头就是它的设计说明与「复制、不要 import」的实测依据
|
|
190
|
+
|
|
191
|
+
## 许可
|
|
192
|
+
|
|
193
|
+
MIT(沿用上游 `@deepseek-ai/dsh-client-ui-workspace`)。
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
<div align="center">
|
|
198
|
+
|
|
199
|
+
<img src="icon.svg" width="48" alt="dsh-group-status"/>
|
|
200
|
+
|
|
201
|
+
</div>
|
package/cordis.patch.yml
ADDED
package/icon.svg
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M6.4 12.6C6.4 11.2 7.5 10.1 8.9 10.1H14.2C15.0 10.1 15.8 10.5 16.3 11.1L17.6 12.8C18.1 13.4 18.9 13.8 19.7 13.8H27.1C28.5 13.8 29.6 14.9 29.6 16.3V24.4C29.6 25.8 28.5 26.9 27.1 26.9H8.9C7.5 26.9 6.4 25.8 6.4 24.4V12.6Z" stroke="url(#a)" stroke-width="2.4" stroke-linejoin="round"/>
|
|
3
|
+
<circle cx="14.4" cy="20.4" r="2.9" fill="url(#a)"/>
|
|
4
|
+
<circle cx="22.6" cy="20.4" r="2.9" fill="url(#a)" fill-opacity="0.45"/>
|
|
5
|
+
<defs>
|
|
6
|
+
<linearGradient id="a" x1="18" y1="9.4" x2="18" y2="27.6" gradientUnits="userSpaceOnUse">
|
|
7
|
+
<stop stop-color="#7AC2FF"/>
|
|
8
|
+
<stop offset="1" stop-color="#4A65E8"/>
|
|
9
|
+
</linearGradient>
|
|
10
|
+
</defs>
|
|
11
|
+
</svg>
|