zdashboard 1.6.2 → 2.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.
Files changed (31) hide show
  1. package/README.md +225 -41
  2. package/dist/cli.js +1388 -804
  3. package/dist/cli.js.map +1 -1
  4. package/dist/web/assets/MdViewer-C8ZG_xn1.js +1 -0
  5. package/dist/web/assets/Workspace-Cz1A_IXM.js +1 -0
  6. package/dist/web/assets/file-text-DqCOBCjz.js +6 -0
  7. package/dist/web/assets/index-B9eiA0v2.js +29 -0
  8. package/dist/web/assets/index-D58_bWw5.css +1 -0
  9. package/dist/web/assets/index-DkOVCCZ3.js +90 -0
  10. package/dist/web/assets/katex-BTcE7LSd.css +10 -0
  11. package/dist/web/assets/katex.min-DAmb8ZJI.js +270 -0
  12. package/dist/web/assets/web-8ZBVzAEO.js +26 -0
  13. package/dist/web/assets/web-CEyEoz0i.js +30 -0
  14. package/dist/web/assets/web-CXHaDUKR.js +25 -0
  15. package/dist/web/assets/{Viewer-CvXxR4rr.js → web-CrX-i-rZ.js} +7 -2
  16. package/dist/web/assets/web-D_b3sVrp.js +31 -0
  17. package/dist/web/assets/web-M4KeFgZw.js +2 -0
  18. package/dist/web/assets/{Viewer-DgUxcwns.js → web-Y4h9oNHC.js} +3 -3
  19. package/dist/web/index.html +2 -2
  20. package/package.json +4 -1
  21. package/dist/web/assets/DesignViewer-DIFMIK04.js +0 -26
  22. package/dist/web/assets/ReviewViewer-CzphymDs.js +0 -31
  23. package/dist/web/assets/ViewViewer-2gv2jIkV.js +0 -11
  24. package/dist/web/assets/folder-open-YuFnfZTO.js +0 -6
  25. package/dist/web/assets/index-BJ8mveF-.js +0 -446
  26. package/dist/web/assets/index-BwdPhy39.css +0 -10
  27. package/dist/web/assets/index-CgsmLt7m.js +0 -2
  28. package/dist/web/assets/index-D5XUdKxi.js +0 -2
  29. package/dist/web/assets/index-LAcTTLE0.js +0 -2
  30. package/dist/web/assets/index-Nmrw-5B2.js +0 -2
  31. package/dist/web/assets/index-f9TDtJW5.js +0 -2
package/README.md CHANGED
@@ -2,69 +2,252 @@
2
2
 
3
3
  ZCode skill 的通用 dashboard 平台。核心不动,skill 自带 viewer,未来 N 个 dashboard 自然接入。
4
4
 
5
- ## 架构
5
+ ## 架构 (v2.0)
6
6
 
7
7
  ```
8
8
  zdashboard/ ← 一个核心包,永远不写业务逻辑
9
9
  ├── src/
10
- │ ├── server/
11
- │ │ ├── detect.ts ← 自动发现 .zxxx/ 目录
12
- │ │ ├── index.ts /__<mode> 路由 委托给 plugin API handler
13
- │ │ └── plugins.ts plugin 加载器
14
- │ └── web/
15
- ├── App.tsx mode 驱动 sidebar + viewer 加载
16
- └── ...
17
- ├── src/plugins/ 内置 plugins(随核心发版)
18
- │ ├── bugs/
19
- │ ├── view/
20
- │ ├── review/
21
- └── design/
22
- └── package.json
10
+ │ ├── core/
11
+ │ │ ├── server.ts ← HTTP server + route/SSE 注册表
12
+ │ │ ├── reload.ts fs.watchSSE broadcast
13
+ │ │ ├── tree.ts /__files 文件树
14
+ └── manifest.ts ← /__plugins 插件清单
15
+ ├── plugins/ 内置 plugins(随核心发版)
16
+ │ ├── stats/ ← 项目统计(文件/目录/大小/扩展名 Top10)
17
+ │ │ ├── just/ Just Runner 任务执行
18
+ ├── bugs/ ← 禅道 Bugs 只读列表
19
+ ├── review/ ← 文档评审状态流转
20
+ ├── apply/ ← OpenSpec change 执行进度
21
+ │ ├── design/ ← 设计资产分类浏览
22
+ │ │ └── view/ ← 项目浏览(文件预览)
23
+ │ ├── web/ ← SPA 前端(Vite + React)
24
+ │ │ ├── App.tsx ← Shell:Topbar + IconRail + Workspace + StatusBar
25
+ │ │ ├── layout/ ← IconRail、StatusBar
26
+ │ │ ├── home/ ← HomeGrid 插件卡片
27
+ │ │ ├── components/ ← shared UI(button、card、tooltip...)
28
+ │ │ ├── viewers/ ← Markdown/Image/Code/Unsupported 预览器
29
+ │ │ └── hooks/ ← useSSE
30
+ │ └── server/ ← 后端 helpers(detect、scan、just-runner...)
31
+ ├── package.json
32
+ └── README.md
23
33
  ```
24
34
 
35
+ ## 设计原则
36
+
37
+ 1. **核心不动**:`src/core/` 提供 HTTP server、SSE、文件树、插件清单,不写任何业务逻辑
38
+ 2. **插件自包含**:每个 mode 在 `src/plugins/<mode>/` 内完成前后端(`index.ts` + `web.tsx` + `Workspace.tsx`)
39
+ 3. **Cordis 生命周期**:用 `ctx.effect(() => () => dispose())` 管理清理,`ctx.server.route/sse` 注册路由
40
+ 4. **SPA 首页**:`GET /` 直接返回 `index.html`,前端 hash 驱动 mode 切换(`#<mode>`)
41
+
25
42
  ## Plugin 约定
26
43
 
27
- 每个 skill 在 `assets/dashboard-viewer/` 放一个轻量 plugin:
44
+ 每个内置 plugin 提供:
28
45
 
29
46
  ```
30
- skills/zgoal/assets/dashboard-viewer/
31
- ├── index.ts ← 注册:mode='bugs',label='禅道'
32
- ├── Viewer.tsx 页面组件
33
- └── sidebar.tsx sidebar 按钮(可选)
47
+ src/plugins/<mode>/
48
+ ├── index.ts ← 后端:注册 /__<mode>* 路由
49
+ ├── web.tsx 前端 manifest(mode、label、icon、Workspace)
50
+ └── Workspace.tsx 前端页面组件
34
51
  ```
35
52
 
36
53
  ```ts
37
- // skills/zgoal/assets/dashboard-viewer/index.ts
54
+ // src/plugins/<mode>/web.tsx
55
+ import { lazy } from 'react';
56
+ import Workspace from './Workspace.js';
57
+
38
58
  export default {
39
- mode: 'bugs',
40
- label: '禅道',
59
+ mode: '<mode>',
60
+ label: '显示名',
41
61
  icon: '🎯',
42
- viewer: () => import('./Viewer'),
43
- sidebar: () => import('./sidebar'),
44
- apiRoutes: {
45
- '/api/bugs': async (req, res, root) => { /* ... */ }
46
- }
47
- }
62
+ description: '简短描述',
63
+ Workspace: lazy(() => import('./Workspace.js')),
64
+ } as const;
65
+ ```
66
+
67
+ 可选 `Sidebar` 槽(如 view、design 提供侧栏):
68
+
69
+ ```ts
70
+ import Sidebar from './Sidebar.js';
71
+
72
+ export default {
73
+ mode: '<mode>',
74
+ label: '显示名',
75
+ icon: '🎯',
76
+ description: '简短描述',
77
+ Sidebar: lazy(() => import('./Sidebar.js')),
78
+ Workspace: lazy(() => import('./Workspace.js')),
79
+ } as const;
80
+ ```
81
+
82
+ ```ts
83
+ // src/plugins/<mode>/index.ts
84
+ export default {
85
+ inject: ['server'] as const,
86
+ apply(ctx: Context, config: { root: string }) {
87
+ const server = (ctx as any).server;
88
+ if (!server?.route) return;
89
+
90
+ server.route('/__<mode>', async (req, res) => {
91
+ res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });
92
+ res.end(JSON.stringify({ /* ... */ }));
93
+ });
94
+ },
95
+ };
96
+ ```
97
+
98
+ 外部 plugin 放在 `--plugins <dir>` 下,结构同上,核心启动时自动扫描 `index.{ts,js,mjs}` 加载。
99
+
100
+ ### 外部插件编写指南
101
+
102
+ 外部插件允许自带静态 viewer 页面,通过 iframe 嵌入 dashboard。
103
+
104
+ **目录结构**
105
+
106
+ ```
107
+ my-skill/
108
+ ├── index.ts ← 必填:cordis 插件定义
109
+ └── web/ ← 可选:静态 viewer 目录
110
+ ├── index.html
111
+ └── assets/...
112
+ ```
113
+
114
+ **index.ts 约定**
115
+
116
+ ```ts
117
+ import type { Context } from 'cordis';
118
+
119
+ export default {
120
+ inject: ['server', 'dashboard'] as const,
121
+ apply(ctx: Context, config: { root: string }) {
122
+ const server = (ctx as any).server;
123
+ const dashboard = (ctx as any).dashboard;
124
+ if (!server?.route || !dashboard?.register) return;
125
+
126
+ // 注册后端 API
127
+ server.route('/__my-api', (req, res) => {
128
+ res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });
129
+ res.end(JSON.stringify({ ok: true }));
130
+ });
131
+
132
+ // 注册 manifest(mode === 目录名时,若有 web/index.html 会自动填充 viewerUrl)
133
+ dashboard.register({
134
+ mode: 'my-skill', // 必须与目录名一致才能自动填充 viewerUrl
135
+ label: 'My Skill',
136
+ icon: '🧩',
137
+ description: '描述',
138
+ });
139
+ },
140
+ };
48
141
  ```
49
142
 
50
- 核心平台启动时:
51
- 1. 加载内置 plugins(`src/plugins/`)
52
- 2. 扫描 `--plugins` 目录加载外部 plugins
53
- 3. 根据 `--mode` 激活对应 plugin
143
+ > 外部插件必须 `export default`(cordis `ctx.plugin()` 只接受函数或带 `apply` 的 default 对象)。
54
144
 
55
- ## 用法
145
+ **web/ 约定**
146
+
147
+ - `web/index.html` 必须存在才会被自动服务
148
+ - 自动挂载在 `/__plugin/<目录名>/`,例如目录 `my-skill` 对应 `/__plugin/my-skill/`
149
+ - 页面内可通过相对路径引用同目录资源(js/css/图片)
150
+ - 页面内可调用插件注册的 API(如 `/__my-api`),与 dashboard 同源
151
+
152
+ **viewerUrl 覆盖**
153
+
154
+ 如果需要在 manifest 中显式指定 viewerUrl,可直接写:
155
+
156
+ ```ts
157
+ dashboard.register({
158
+ mode: 'my-skill',
159
+ label: 'My Skill',
160
+ icon: '🧩',
161
+ description: '描述',
162
+ viewerUrl: '/custom-path/',
163
+ });
164
+ ```
165
+
166
+ 显式声明的 `viewerUrl` 优先于自动填充值。
167
+
168
+ **热刷新**
169
+
170
+ 外部 viewer 的 HTML 文件会自动注入 reload 脚本(与 dashboard SPA 一致),修改 `web/index.html` 后浏览器会自动刷新。
171
+
172
+ **沙箱说明**
173
+
174
+ 前端以 iframe 渲染 viewer,sandbox 属性设置为:
175
+
176
+ ```
177
+ allow-scripts allow-same-origin allow-forms allow-popups
178
+ ```
179
+
180
+ 保留同源能力(可访问 dashboard 的 `/__*` API);允许表单与弹窗(viewer 内 `window.open` 外链场景)。
181
+
182
+ **无 web 目录的插件**
183
+
184
+ 若插件目录没有 `web/index.html`,前端仍会显示插件卡片,但进入时展示占位页(不报错)。
185
+
186
+ ## CLI 用法
56
187
 
57
188
  ```bash
58
- # skill 直接调用
59
- npx zdashboard@latest --mode bugs --dir <项目根> --open
60
- npx zdashboard@latest --mode view --dir <项目根> --open
61
- npx zdashboard@latest --mode review --dir .zreview --open
62
- npx zdashboard@latest --mode design --dir <产出根> --open
63
-
64
- # 人类直接访问
65
- npx zdashboard --mode bugs --dir /path/to/project --port 4190
189
+ # 基本用法
190
+ pnpm build
191
+ node dist/cli.js --dir <项目根> --port 4190
192
+
193
+ # 打开浏览器
194
+ node dist/cli.js --dir <项目根> --port 4190 --open
195
+
196
+ # 启动后直达某个 mode(拼 #<mode>)
197
+ node dist/cli.js --dir <项目根> --port 4190 --page design
198
+
199
+ # 加载外部 plugins
200
+ node dist/cli.js --dir <项目根> --port 4190 --plugins ./my-plugins
66
201
  ```
67
202
 
203
+ ### 环境变量
204
+
205
+ - `PORT`:默认 4190(未被 `--port` 覆盖时)
206
+
207
+ ### 内置路由
208
+
209
+ | 路由 | 方法 | 说明 |
210
+ |------|------|------|
211
+ | `/` | GET | SPA 首页 |
212
+ | `/__config` | GET | `{ stopToken, version, root }` |
213
+ | `/__stop` | POST | `x-stop-token` 鉴权,干净退出 |
214
+ | `/__plugins` | GET | 内置 + 外部插件清单 |
215
+ | `/__files` | GET | 文件树(openspec/docs 过滤) |
216
+ | `/__reload` | SSE | `reload` + `files` 事件 |
217
+ | `/__just/recipes` | GET | just 任务列表 |
218
+ | `/__just/logs` | SSE | just 实时日志 |
219
+ | `/__just/{start,stop,restart}` | POST | just 任务控制 |
220
+ | `/__bugs` | GET | 禅道 bug 列表 |
221
+ | `/__review` | GET | 评审项列表 |
222
+ | `/__review/item` | POST | 更新评审项 |
223
+ | `/__review/status` | POST | 更新评审状态 |
224
+ | `/__docs` | GET | 项目文档列表 |
225
+ | `/__apply` | GET | OpenSpec changes 列表 |
226
+ | `/__apply/change` | GET | `?name=<change>` 详情 |
227
+ | `/__design/assets` | GET | 设计资产扫描 |
228
+ | `/__stats/data` | GET | 项目统计(内置 stats 插件) |
229
+ | `/__notes/data` | GET | 便签列表(examples/notes 示例) |
230
+ | `/__notes/save` | POST | 保存便签(`x-stop-token` 鉴权) |
231
+
232
+ ## 前端路由
233
+
234
+ 前端用 hash 驱动 mode:
235
+
236
+ - `/#<mode>` 激活对应 plugin Workspace
237
+ - `/#` 或空 hash 回到 HomeGrid
238
+ - IconRail 点击自动写 hash
239
+ - 浏览器前进/后退由 `hashchange` 事件处理
240
+
241
+ ## 技术栈
242
+
243
+ - **运行时**:Node.js 20+,ESM,`node:` 前缀
244
+ - **核心框架**:Cordis 4.0.0-rc.8(Context + Service + inject)
245
+ - **前端**:React 18 + Vite 5 + Tailwind 3
246
+ - **组件库**:Radix UI(tooltip、separator、scroll-area、slot)
247
+ - **HTTP**:Node `http` 模块(无 express 依赖)
248
+ - **构建**:tsup(CLI) + Vite(SPA)
249
+ - **包管理**:pnpm
250
+
68
251
  ## 迁移状态
69
252
 
70
253
  - [x] zview-dashboard → zdashboard(v1.0.0)
@@ -72,3 +255,4 @@ npx zdashboard --mode bugs --dir /path/to/project --port 4190
72
255
  - [x] zdesign-dashboard → zdashboard plugin(v1.2.0)
73
256
  - [x] zapply execution progress → zdashboard plugin(v1.3.3)
74
257
  - [x] zskills skill SKILL.md 统一调用 zdashboard
258
+ - [x] v2.0 cordis 重写:core 不动,插件自包含,SPA 首页