@dsh-workbench/core 0.3.9 → 0.3.11
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/README.md +19 -7
- package/bin/dsh-workbench +2 -2
- package/client.js +1687 -1022
- package/cordis.patch.yml +60 -35
- package/dist/client/client.body.js +1687 -1022
- package/dist/client/index.js +1372 -707
- package/dist/host/index.js +2897 -2335
- package/dist/types/app/client.d.ts +2 -1
- package/dist/types/app/layouts/env-gate/boot-gate.d.ts +1 -1
- package/dist/types/app/layouts/market/use-module-versions.d.ts +13 -2
- package/dist/types/app/layouts/rightbar/MarketView.d.ts +6 -3
- package/dist/types/app/layouts/rightbar/market-act.d.ts +6 -3
- package/dist/types/app/layouts/rightbar/market-rows.d.ts +1 -1
- package/dist/types/app/layouts/rightbar/market-settle-hold.d.ts +2 -0
- package/dist/types/app/layouts/rightbar/market-settle.d.ts +20 -0
- package/dist/types/app/layouts/rightbar/market-shared-rows.d.ts +0 -1
- package/dist/types/app/layouts/rightbar/market-update-verdict.d.ts +41 -0
- package/dist/types/app/layouts/rightbar/market-view-text.d.ts +4 -1
- package/dist/types/app/layouts/rightbar/store.d.ts +14 -0
- package/dist/types/app/layouts/sidebar/LongTaskDot.d.ts +12 -0
- package/dist/types/app/layouts/sidebar/LongTaskHover.d.ts +12 -0
- package/dist/types/app/layouts/sidebar/edition-boot.d.ts +24 -0
- package/dist/types/app/layouts/sidebar/edition.d.ts +22 -0
- package/dist/types/app/layouts/workbench-settings/ConfigSyncItem.d.ts +5 -0
- package/dist/types/app/layouts/workbench-settings/SettingsItem.d.ts +17 -0
- package/dist/types/app/layouts/workbench-settings/SidebarEditionItem.d.ts +11 -0
- package/dist/types/app/layouts/workbench-settings/WorkbenchSettingsSection.d.ts +11 -0
- package/dist/types/modules/panels/model/approval.d.ts +12 -4
- package/dist/types/modules/panels/model/diy-browser-tools.d.ts +1 -1
- package/dist/types/modules/panels/model/diy-context.d.ts +31 -14
- package/dist/types/modules/panels/model/diy-page.d.ts +3 -2
- package/dist/types/modules/panels/model/diy-record.d.ts +3 -3
- package/dist/types/modules/panels/model/diy-report.d.ts +6 -7
- package/dist/types/modules/panels/model/market-dependency-update.d.ts +21 -0
- package/dist/types/modules/panels/model/market-dispatch.d.ts +1 -0
- package/dist/types/modules/panels/model/market-types.d.ts +1 -0
- package/dist/types/modules/panels/model/market-update-bundle.d.ts +25 -0
- package/dist/types/modules/panels/model/market-verify.d.ts +31 -0
- package/dist/types/modules/panels/unit.d.ts +3 -4
- package/dist/types/shared/api/bundle-install.d.ts +13 -0
- package/dist/types/shared/api/host/approval-gate.d.ts +39 -0
- package/dist/types/shared/api/host/bundle-routes.d.ts +2 -1
- package/dist/types/shared/api/host/diy-artifacts.d.ts +14 -0
- package/dist/types/shared/api/host/diy-modules.d.ts +41 -0
- package/dist/types/shared/api/host/host-routes.d.ts +13 -0
- package/dist/types/shared/api/host/permission-mode.d.ts +9 -0
- package/dist/types/shared/api/host/runtime-seed.d.ts +2 -0
- package/dist/types/shared/api/host/self-update.d.ts +9 -2
- package/dist/types/shared/api/host/sidebar-edition.d.ts +46 -0
- package/dist/types/shared/api/host/workspace-root.d.ts +13 -0
- package/dist/types/shared/api/sidebar-edition.d.ts +14 -0
- package/dist/types/shared/api/unit-board.d.ts +20 -0
- package/dist/types/shared/api/write-outcome.d.ts +15 -0
- package/dist/types/shared/components/IconModules.d.ts +8 -0
- package/dist/types/shared/components/blocker-action.d.ts +16 -0
- package/dist/types/shared/hooks/sidebar-edition.d.ts +7 -0
- package/dist/types/shared/hooks/use-capabilities.d.ts +5 -0
- package/dist/types/shared/hooks/use-capability-gate.d.ts +1 -2
- package/dist/types/shared/hooks/use-host-write.d.ts +1 -1
- package/dist/types/shared/hooks/use-unit-board.d.ts +1 -1
- package/docs/HANDOFF.md +3 -3
- package/docs/OPERATIONS.md +16 -5
- package/package.json +3 -3
- package/preset/diy.patch.yml +2 -2
- package/profile/isolation.patch.yml +11 -0
- package/skills/workbench-module-diy/BUILD.md +62 -131
- package/skills/workbench-module-diy/COPY.md +89 -0
- package/skills/workbench-module-diy/DATASOURCE.md +84 -112
- package/skills/workbench-module-diy/DESIGN.md +75 -109
- package/skills/workbench-module-diy/FAMILY.md +70 -54
- package/skills/workbench-module-diy/KIT.md +77 -133
- package/skills/workbench-module-diy/LINKAGE.md +66 -105
- package/skills/workbench-module-diy/PANEL.md +79 -171
- package/skills/workbench-module-diy/REVIEW.md +67 -81
- package/skills/workbench-module-diy/SKILL.md +57 -96
- package/skills/workbench-module-diy/STEPS.md +66 -69
- package/skills/workbench-module-diy/TOOLING.md +34 -51
- package/skills/workbench-module-diy/TOOLS.md +110 -103
- package/skills/workbench-module-diy/WIRING.md +51 -83
- package/skills/workbench-module-diy/WRITES.md +89 -142
- package/dist/types/app/layouts/config-sync/ConfigSyncSection.d.ts +0 -5
- package/dist/types/shared/api/host/diy-workshop.d.ts +0 -23
- package/dist/types/shared/api/host/workshop-root.d.ts +0 -16
- /package/dist/types/shared/{api/host/diy-workshop.test.d.ts → components/blocker-action.test.d.ts} +0 -0
|
@@ -1,219 +1,127 @@
|
|
|
1
|
-
#
|
|
1
|
+
# 面板:内容、配置、状态、样式
|
|
2
2
|
|
|
3
|
-
步骤 1
|
|
4
|
-
"这份配置存不存"有代码形状,那一节给写法。
|
|
3
|
+
步骤 1 的参考。
|
|
5
4
|
|
|
6
|
-
## 1
|
|
5
|
+
## 1 只放三类东西
|
|
7
6
|
|
|
8
|
-
|
|
|
7
|
+
| 类 | 例 | 承接 |
|
|
9
8
|
|---|---|---|
|
|
10
|
-
|
|
|
11
|
-
|
|
|
12
|
-
|
|
|
9
|
+
| 导航 | 换项目、切面板、折叠 | 界面自身 |
|
|
10
|
+
| 呈现 | 状态、数字、最近几条 | 只读 |
|
|
11
|
+
| 交代 | "交给 agent"、预填指令、动作按钮 | 转给 agent |
|
|
13
12
|
|
|
14
|
-
|
|
13
|
+
不放:平台写操作(评论、流转、发布)→ agent;详情 / 评论 / 日志 / 翻页 → "去平台看";
|
|
14
|
+
多步、长等、中途要人、失败要续 → 封成一个动作(一个按钮 + 一个交代入口)。
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
- 详情、评论、日志、翻页 → 给他一个"去平台看"的去处;
|
|
18
|
-
- 一次要动好几下、要等很久、中途要他登录或点头、失败还要接着来的 → **封成一个动作**,面板上只给他一个按钮 + 一个交代入口;中间那些来回留在对话里。
|
|
16
|
+
## 2 封动作还是交 agent
|
|
19
17
|
|
|
20
|
-
|
|
18
|
+
任一为是则封动作:要动平台好几下;要等分钟级;中途需用户本人(登录、点头、冲突);失败要续。
|
|
19
|
+
都不是 → 交给 agent。
|
|
21
20
|
|
|
22
|
-
|
|
21
|
+
## 3 什么算配置
|
|
23
22
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
3. 中途需要他本人(登录、点头、撞上冲突)?
|
|
27
|
-
4. 失败了要能接着来?
|
|
23
|
+
只有用户在本面板的偏好:看哪份、显示哪些、钉哪个环境、绑定哪个对象。碰平台的不算配置。
|
|
24
|
+
形态:一屏选完 + 保存前校验;不做分页向导、多步流程。
|
|
28
25
|
|
|
29
|
-
|
|
26
|
+
## 4 展示清单
|
|
30
27
|
|
|
31
|
-
|
|
28
|
+
每行三项:
|
|
32
29
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
碰平台的一律不是配置。
|
|
36
|
-
|
|
37
|
-
配置的形态是一个面里**一次选完 + 保存前替他校验**;不做分页向导、不做好几步的流程(他看不到全局,出错也难查)。
|
|
38
|
-
|
|
39
|
-
## 4 展示清单怎么写
|
|
40
|
-
|
|
41
|
-
每条一行,就这三样:
|
|
42
|
-
|
|
43
|
-
| 写什么 | 判据 |
|
|
30
|
+
| 项 | 标准 |
|
|
44
31
|
|---|---|
|
|
45
|
-
| 这一格是什么 |
|
|
46
|
-
|
|
|
47
|
-
| 点一下去哪 |
|
|
48
|
-
|
|
49
|
-
- 一屏不要塞太多:他要的结论放最上面,历史、明细沉到下面。
|
|
50
|
-
- 同一列里几张卡要长得一样(标题、刷新、设置、"去平台"的位置一致)。
|
|
51
|
-
- 面板上的每个数字,agent 都要能通过自己的能力拿到;每个按钮都要有一句等价的话。做不到就别放。
|
|
32
|
+
| 这一格是什么 | 用户会说的话;有平台术语就重写 |
|
|
33
|
+
| 一眼得出什么结论 | 能支撑决定;不能就不放 |
|
|
34
|
+
| 点一下去哪 | 去平台或交给 agent,至少一个 |
|
|
52
35
|
|
|
53
|
-
|
|
36
|
+
同列卡片结构一致(标题、刷新、设置、"去平台"位置)。每个数字都要有 agent 能力能取到;每个按钮都要有等价的一句话。
|
|
54
37
|
|
|
55
|
-
|
|
38
|
+
## 5 配置清单
|
|
56
39
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
| 默认 | 不给偏好时他看到的会是什么 |
|
|
61
|
-
| 能选什么 | 候选从**现在真实存在**的里列;过期的候选不列 |
|
|
62
|
-
| 选错会怎样 | 拒绝并说清(还认的候选有哪些),不悄悄换成一个别的 |
|
|
63
|
-
| 记多久、记在哪 | 按项目分别记;换项目不串;换仓库/换对象时旧选择作废并让他重选 |
|
|
64
|
-
| 怎么生效 | 他按下保存才生效;保存成功直接回到看板并立刻按新的显示;保存失败留在原地告诉他为什么 |
|
|
65
|
-
| 怎么清 | 他自己显式清;收起或卸载这块面板**不删**他的配置 |
|
|
66
|
-
|
|
67
|
-
### 5.1 两种配置写法,别混
|
|
40
|
+
每项七栏:管什么 / 默认 / 候选(只列现存) / 选错(拒绝并列出仍可选项,不静默替换) /
|
|
41
|
+
记录范围(按项目,换项目不串;换仓库或对象时作废旧选择并要求重选) / 生效(保存后生效,成功回看板刷新,失败留在原地说原因) /
|
|
42
|
+
清除(用户显式清;收起或卸载面板不删)。
|
|
68
43
|
|
|
69
|
-
|
|
70
|
-
`config[].persistence` 这一格写的就是这个(`prefs` = 存起来;`view` = 只选一下)。
|
|
44
|
+
### 5.1 persistence:`view` 还是 `prefs`
|
|
71
45
|
|
|
72
|
-
| 写法 |
|
|
46
|
+
| 写法 | 场景 | 刷新后 | 实现 |
|
|
73
47
|
|---|---|---|---|
|
|
74
|
-
| `view` |
|
|
75
|
-
| `prefs` |
|
|
48
|
+
| `view` | 卡片底部一次性选择(口径、天数) | 回默认 | 作 route 参数传给只读口;非法值写进 `wrongChoice` |
|
|
49
|
+
| `prefs` | 配一次长期有效(环境、忽略项、超时) | 保留 | `mount` 返回 `prefs: { resource, handle }`,`handle` 用 `deps.store` 落盘 |
|
|
76
50
|
|
|
77
|
-
|
|
51
|
+
宿主侧:
|
|
78
52
|
|
|
79
53
|
```ts
|
|
80
|
-
// mount(deps)
|
|
54
|
+
// mount(deps) 内;按项目分文件
|
|
81
55
|
const store = deps.store.for(UNIT_ID, workspace);
|
|
82
56
|
return {
|
|
83
|
-
// …
|
|
84
57
|
prefs: {
|
|
85
58
|
resource: 'your-module',
|
|
86
|
-
// 校验 + 落盘 +
|
|
87
|
-
handle: (payload) => applyPref(store, payload),
|
|
59
|
+
handle: (payload) => applyPref(store, payload), // 校验 + 落盘 + 返回整份新偏好
|
|
88
60
|
},
|
|
89
61
|
};
|
|
90
62
|
```
|
|
91
63
|
|
|
92
|
-
|
|
93
|
-
排版与内边距都是外壳给的默认(`Field` / `TextField`),**模块不需要为"能看"写 CSS**:
|
|
64
|
+
浏览器侧:写走 `prefs`,读取仍走模块只读口。布局与内边距用外壳默认(`Field` / `TextField`),不必为可读性写 CSS。
|
|
94
65
|
|
|
95
66
|
```tsx
|
|
96
67
|
const write = useHostWrite({ channel: 'prefs', resource: 'your-module' });
|
|
97
|
-
|
|
98
|
-
write.send({ ignored, timeoutSeconds, workspace });
|
|
68
|
+
write.send({ ignored, timeoutSeconds, workspace }); // 控件:Field + TextField / ChoiceGroup;容器 SettingsSection;保存 SaveBar
|
|
99
69
|
```
|
|
100
70
|
|
|
101
|
-
`handle`
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
-
|
|
117
|
-
-
|
|
118
|
-
-
|
|
119
|
-
-
|
|
120
|
-
-
|
|
121
|
-
-
|
|
122
|
-
-
|
|
123
|
-
**它自带的样子就是唯一一份,别去掉箭头、别换箭头、别自己调**(没有 `icon` 这个口子)——
|
|
124
|
-
全仓的链接必须长得一样。
|
|
125
|
-
模块源码里手写 `<a>` / `h('a', …)` 会被「样式归属」判据**直接判红**。
|
|
126
|
-
**文案里也不许自带箭头**(`'去网关看账单 →'` 这种)—— 箭头由组件给,自带的话页面上就是两颗。
|
|
127
|
-
它内部已经把 dsh 的图标原语包好了,所以模块**不用**为它声明 `client.external`。
|
|
128
|
-
- **哪几种手写 `<a>` 不算 `Link`(判据不该咬、也别硬迁)**:判据钉的是**"手写 `<a>` 这件事本身"**
|
|
129
|
-
(`Link` 是唯一出处),下面三类**有意**留着,因为它们**不是"正文链接"**——
|
|
130
|
-
- **图标链**(icon-only 的 `<a>`,靠 `title` / `aria-label` 顶着):`Link` 一定会多画一颗 ↗,
|
|
131
|
-
套进去就是两颗,尺寸与槽位它也表达不了 ⇒ 留 `<a>`。
|
|
132
|
-
- **按钮皮的链**(`.anchorButton` 那类 28 高 / 描边的"看起来像按钮、实际是链接"):**必须是链接的动作
|
|
133
|
-
留真 `<a>`** —— `href` 带来的是中键新开、右键复制链接、悬停看 URL;塞成
|
|
134
|
-
`onClick: () => window.open(…)` 的按钮,这三件一起丢。
|
|
135
|
-
- **整行链**(一行整体可点,`flex: 1` / `color: inherit`):它是**那条行的布局槽**,不是正文里的字。
|
|
136
|
-
**要放宽这一条就走棘轮**:那张已知豁免表(`module-tools` 的 `style` 判据里,`ANCHOR_EXEMPT`)
|
|
137
|
-
**只许减不许加**(迁一处删一行);真要加一格,那是**改判据口径**,得写清"为什么 `Link` 表达不了它"。
|
|
138
|
-
口径的权威那份是 `style.mjs` 里 `BARE_ANCHOR` 那一段注释(`ANCHOR_EXEMPT` 上面)
|
|
139
|
-
与 `module-tools/README.md` 的 `style` 那一行。
|
|
140
|
-
- **"去看某处"用哪个**:跳**整张卡对应的系统** → 卡头那颗图标按钮(`CardHead.platformHref`,给这一个就够);
|
|
141
|
-
跳**一个具体页面 / 一条具体记录** → `Link`(正文里的文字链接);**触发一个动作**(刷新、重建、去登录)→
|
|
142
|
-
dsh 的 `Button`,或阻断屏里的 `action`。区别在"跳去哪"和"它是不是一个动作",不在好看不好看。
|
|
143
|
-
- **标签 + 输入框用 `Field` + `TextField`**(排布与内边距是外壳的默认,别自己写 CSS,见 §5.1)。
|
|
144
|
-
- **要做什么用哪件,照 [KIT.md](KIT.md) 抄**("要做什么 → 用哪件 → 最小写法"的表)。
|
|
145
|
-
下面几条是口径,KIT.md 是写法。
|
|
146
|
-
- **字号与重点**:走那把刻度(`--dsw-font-*`:11 / 12 / 13 / 14 / 16 / 20 / 24),
|
|
147
|
-
**但不许"整张卡一样大"** —— 要有重点。最该大的那个数字(余额、总数、还剩多少)
|
|
148
|
-
就用刻度里最大那档 `--dsw-font-xl-24`(24/32、600 重),它旁边的说明 12。
|
|
149
|
-
这一档是**给重点留的、鼓励用**:卡里最大的字比正文大一倍,比全卡 12 号好读得多。
|
|
150
|
-
刻度外非要一个字面值(28/32 那种)时,在模块 `README.md` 里写一句为什么,别静悄悄写。
|
|
151
|
-
成列的数字加 `font-variant-numeric: tabular-nums`。
|
|
152
|
-
**别为了"统一"把重点压回正文大小**——那才是不合口径。
|
|
153
|
-
- **颜色与间距也走令牌**(`--dsw-*` / `--wb-*`);自己写 CSS 只写布局(flex / grid / gap / 对齐)。
|
|
154
|
-
|
|
155
|
-
## 7 状态矩阵怎么写
|
|
156
|
-
|
|
157
|
-
把每种状态都走一遍,一个不落:
|
|
158
|
-
|
|
159
|
-
没有绑定 / 还没接入 / **分不清是哪一份** / 正在读 / 有数据 / 正在做 / 卡住了(要登录、没权限、超时、能力没装好)/ 读到了但是空 / 数字是上一轮的。
|
|
160
|
-
|
|
161
|
-
每一格写三样:
|
|
162
|
-
|
|
163
|
-
| 列 | 写法 |
|
|
164
|
-
|---|---|
|
|
165
|
-
| 他看到什么 | 屏幕上是什么(哪句话、哪个画面、哪颗点) |
|
|
166
|
-
| 他能做什么 | 一个动作(去哪补、点哪个、重试) |
|
|
167
|
-
| agent 能接着做什么 | 一句 agent 能照做的话 |
|
|
71
|
+
`handle` 规则:未设置 ≠ 空(首次进入"第一次选");清空 = 回默认并删文件;按工作区分文件;
|
|
72
|
+
未知值报错并列出候选;去重、保留用户顺序。
|
|
73
|
+
保存成功后卡片按新偏好显示(写偏好 bump 该单元的事实,[LINKAGE.md](LINKAGE.md) §8);失败留在原地说原因。
|
|
74
|
+
|
|
75
|
+
## 6 界面规则
|
|
76
|
+
|
|
77
|
+
文案(主句 / 原文、通俗、zh / en)见 [COPY.md](COPY.md) §3。
|
|
78
|
+
|
|
79
|
+
- 有默认可读的数据就直接显示,不先弹设置;只有分不清时才摆选择。
|
|
80
|
+
- 候选 ≤3 个时平铺,不放进下拉。
|
|
81
|
+
- 历史、明细默认折叠,露出最近一条;只有一条时不给折叠控件。
|
|
82
|
+
- 状态点只有四义:在做 / 完成 / 出错 / 未运行。
|
|
83
|
+
- 外链一律 `Link`(`h(Link, { href }, 文案)`;`h` 从 `react` 引):新窗口 + `rel` + 箭头,唯一形态,
|
|
84
|
+
没有 `icon` 口子;文案里不自带箭头。手写 `<a>` / `h('a')` 会被 `style` 判据判红。
|
|
85
|
+
例外仅三类非正文链接:图标链、按钮样式的链、整行链。放宽走 `ANCHOR_EXEMPT`,只减不加。
|
|
86
|
+
- 跳整张卡对应的系统 → 卡头 `CardHead.platformHref`;跳具体页面 / 记录 → `Link`;触发动作 → dsh `Button` 或阻断屏 `action`。
|
|
87
|
+
- 标签 + 输入框用 `Field` + `TextField`,不自写 CSS。
|
|
88
|
+
- 组件选型照 [KIT.md](KIT.md)。
|
|
89
|
+
- **字号与重点**:走刻度(`--dsw-font-*`:11 / 12 / 13 / 14 / 16 / 20 / 24),不整卡同字号。
|
|
90
|
+
最重点的数字用 `--dsw-font-xl-24`(24/32、600),旁注 12;刻度外字面值需在模块 `README.md` 说明。
|
|
91
|
+
成列数字加 `font-variant-numeric: tabular-nums`。
|
|
92
|
+
- 颜色与间距走令牌(`--dsw-*` / `--wb-*`);自写 CSS 只写布局(flex / grid / gap / 对齐)。
|
|
168
93
|
|
|
169
|
-
|
|
94
|
+
## 7 状态矩阵
|
|
170
95
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
- **读不到就说读不到**,并说清为什么(例:手上这份能力太旧);**绝不显示 0**。
|
|
174
|
-
- 有确定答案就不打扰他(能按默认读出来就别弹设置面)。
|
|
175
|
-
- 真机上造不出来的状态也要**在设计上**画出来(照这一格写清)—— 模块自己的 `plugin.test.ts` 把五态各喂一遍就够(`check --only cards` 会拿**七种外壳侧输入**各喂一遍 —— 它只问"退化得干不干净",**不断言**"画的是哪一态那一屏")。
|
|
96
|
+
状态全集:没有绑定 / 未接入 / 分不清是哪一份 / 正在读 / 有数据 / 正在做 / 卡住(登录、权限、超时、能力未装) /
|
|
97
|
+
读到但空 / 数字是上一轮。
|
|
176
98
|
|
|
177
|
-
|
|
99
|
+
每格三列:看到什么(哪句话、哪个画面、哪颗点)/ 能做什么(去哪补、点哪、重试)/ agent 能接着做什么(可照做的一句)。
|
|
178
100
|
|
|
179
|
-
|
|
101
|
+
规则:每句可照做;平台没给的格不留占位;读不到就说读不到并给原因,不显示 0;有确定答案就不打扰。
|
|
102
|
+
真机造不出的状态也要在设计里画;`plugin.test.ts` 覆盖五态(`check --only cards` 用七种外壳侧输入各跑一遍,
|
|
103
|
+
只判"是否干净退化",不判画的是哪一态)。
|
|
180
104
|
|
|
181
|
-
|
|
182
|
-
- **空态**(图标 + 一句话,居中,**没有按钮**)
|
|
183
|
-
- **阻断 / 卡住**(**整张卡换成这一屏**:图标 + 一句话 + 按钮)
|
|
184
|
-
- **提示**(卡片照常画数据,只在最上面多一条细提示行)
|
|
185
|
-
- **骨架**(几行灰条:正在读、还没有数据)
|
|
186
|
-
- **在转**(列表照常在,只有卡片头那颗刷新在转)
|
|
187
|
-
- **一行里那些记号挨着的样子**(状态点 + 编号 + 元信息 + 行尾两颗)
|
|
188
|
-
- **状态点的几档**(只有颜色不同;**撞色的那两档要在图下点明靠什么分开**)
|
|
189
|
-
- **可点的筛选**(几颗、选中的那颗什么样)
|
|
190
|
-
- **只在某种模式出现的东西**
|
|
191
|
-
- **审批弹窗**(哪一行是套件给的、哪一行是系统给的、按钮在哪)
|
|
105
|
+
### 7.1 图例
|
|
192
106
|
|
|
193
|
-
|
|
107
|
+
矩阵左列写图号,图按图号排。至少这些屏:有数据 · 空态(图标 + 一句话,无按钮)· 阻断(整卡替换:图标 + 话 + 按钮)·
|
|
108
|
+
提示(数据照常,顶部一条)· 骨架 · 在转(列表在,卡头刷新转)· 行内记号(状态点 + 编号 + 元信息 + 行尾两颗)·
|
|
109
|
+
状态点各档(撞色两档在图下注明区分方式)· 可点筛选 · 仅某模式出现 · 审批弹窗(每行谁给的)。
|
|
194
110
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
- **画不成的才写词**:动作、agent 的下一步、时间性的"不变 / 自己变",写成词并说清意思。
|
|
198
|
-
- **真机上造不出来的状态**:沟通时照样画(画的是设计意图);实现时**要让它能用真实输入走到**(换个空目录、换个坏路径、先不选),模块自己的 `plugin.test.ts` 把五态各喂一遍就够。
|
|
111
|
+
图里用界面真实文案;不用符号代替画面(形状与位置才是识别点);画不成的写词并定义。
|
|
112
|
+
真机造不出的照样画;实现时用真实输入走到(空目录、坏路径、未选择)。
|
|
199
113
|
|
|
200
|
-
## 8
|
|
114
|
+
## 8 范例
|
|
201
115
|
|
|
202
|
-
|
|
203
|
-
(`template-diy/` / `template/`)与装机模块的源码都可以直接读。
|
|
116
|
+
`template-diy/`(带数据源)与 `template/`(空壳)。
|
|
204
117
|
|
|
205
|
-
## 9
|
|
118
|
+
## 9 kit 不够时
|
|
206
119
|
|
|
207
|
-
|
|
208
|
-
kit 里确实没有、而你要的又是标准控件(按钮、选择器、设置区块那种)时,可以引 dsh 的客户端原语 ——
|
|
209
|
-
**有哪些**问 `dsh-wb-module check --only primitives`(它还会把"kit 里已有"的那批挑出来):
|
|
120
|
+
先查 kit(`check --only kit`)。确无且需要标准控件时,可引 dsh 客户端原语(清单:`check --only primitives`):
|
|
210
121
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
* 宿主侧(`src/host.ts`)**一个字都不许碰** —— `check` 的源码边界判据会红;宿主侧 import
|
|
216
|
-
`src/components/**` 还会被 `arch` 按跨运行时(S23)判红 —— 组件整片算 client 面。
|
|
122
|
+
- 只在浏览器侧引(`src/client.tsx`、`src/components/**`)。
|
|
123
|
+
- `dsh.client.external` 声明 `@deepseek-ai/dsh-client-ui-primitives`;`devDependencies` 用与外壳一致的精确版。
|
|
124
|
+
改完 `pnpm install`。
|
|
125
|
+
- 宿主侧不引:`source` 判据红;宿主 import `src/components/**` 还会被 `arch` 的 S23 判红。
|
|
217
126
|
|
|
218
|
-
|
|
219
|
-
自己画的不会。
|
|
127
|
+
kit 优先:kit 跟随外壳主题与语言。
|
|
@@ -1,95 +1,82 @@
|
|
|
1
|
-
#
|
|
1
|
+
# 门禁:判据、修法、取证
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
运行 `dsh-wb-module check` 或 `check --only <判据>`。红即修,不转给用户。
|
|
4
4
|
|
|
5
|
-
| 判据 |
|
|
5
|
+
| 判据 | 检查 | 修法 |
|
|
6
6
|
|---|---|---|
|
|
7
|
-
| `contracts` |
|
|
8
|
-
| `protocol` | `dsh.workbench`
|
|
9
|
-
| `bundles` |
|
|
10
|
-
| `source` |
|
|
11
|
-
| `primitives` | 声明 `external`
|
|
12
|
-
| `kit` | 用了 peer
|
|
13
|
-
| `cards` |
|
|
14
|
-
| `standalone` |
|
|
15
|
-
| `markers` | 内网域名 /
|
|
16
|
-
| `alias` | `@/`
|
|
17
|
-
| `style` | 模块定义 `.wb
|
|
18
|
-
| `arch` |
|
|
19
|
-
| `lint` |
|
|
20
|
-
|
|
21
|
-
## 第十二条 `arch
|
|
22
|
-
|
|
23
|
-
|
|
7
|
+
| `contracts` | 清单 ↔ 代码 ↔ `design.json` 漂移;dsh 组合期不校验清单 | 按报错改:`unit` 重名换名;`dsh.workbenchFaces` 两个源码入口;六个脚本;`private: true`。`dsh.workbench.tools` 与 `registerTools()` 一致;`design.json` 对键名;生成物过期跑 `sync` |
|
|
8
|
+
| `protocol` | `dsh.workbench` 版本 / 形状 / 多余键(外壳静默忽略生字段) | 补 `"apiVersion": 1`;`unit` / `card` / `tools` / `host` 写全(无卡片 `null`、无工具 `[]`);删协议外键(`faces` 在 `dsh.workbenchFaces`;不写 `scope`) |
|
|
9
|
+
| `bundles` | 运行时互串:浏览器产物含 node 内置 / 宿主产物含 DOM、react | 不 import 对方那侧 |
|
|
10
|
+
| `source` | 非种子 `@deepseek-ai/*`;宿主碰 dsh 浏览器包;`@/` 指外壳;根入口取运行值;客户端引 `/host` | 宿主只用 Node 侧;种子词仅在 client 可达文件;`@/` 只指自己 `src/`;运行值:浏览器 `kit`、宿主 `shared/host` |
|
|
11
|
+
| `primitives` | 声明 `external` 但产物无物证(原语被内联) | `dsh.client.external` 声明;devDependency 精确版对齐;产物中为 `require(...)` |
|
|
12
|
+
| `kit` | 用了 peer 下限外壳没有的成员(首帧 `Element type is invalid`) | 只用 peer 范围内成员;下限抬到实际使用版 |
|
|
13
|
+
| `cards` | 七种外壳侧输入 × `zh` / `en` 下崩溃 / 空白 / 脏值 | 五态可画;外层 `Card`;`titleKey` 与卡片用到的键双语齐。不断言具体态(归 `plugin.test.ts`) |
|
|
14
|
+
| `standalone` | 依赖工作台源码才能构建 | 不引用工作台源码;`tsconfig.paths` 用相对路径 |
|
|
15
|
+
| `markers` | 内网域名 / 企业名进入公开包 | 不进包;配置落到模块配置面 |
|
|
16
|
+
| `alias` | `@/` 指向工作台源码 | `@/` 只指自己 `src/` |
|
|
17
|
+
| `style` | 模块定义 `.wb-*`;手写行 / 操作区 / 表单(F1–F4) | 样式走 `*.module.css`(无 `wb-` 前缀);借外壳类用 `:global(.wb-…)`;行 / 操作区用 `FormRow(s)` / `FormActions`,表单用 `Form`([KIT.md](KIT.md) §5)。F4:裸 `<form` 或手写 `wb-formRow` / `wb-formRows` / `wb-field` |
|
|
18
|
+
| `arch` | 结构:巨文件 / 反向依赖 / 跨运行时 / 表外目录 / 模型无测试 | 见「第十二条」 |
|
|
19
|
+
| `lint` | 语法:`as any` / `console` / `debugger` / 颜色字面量 / `!important` / react-hooks | 见「第十三条」 |
|
|
20
|
+
|
|
21
|
+
## 第十二条 `arch`
|
|
22
|
+
|
|
23
|
+
只跑带 `arch.config.mjs` 的模块;无文件 = 不适用(skip),不是红。
|
|
24
24
|
|
|
25
25
|
```js
|
|
26
26
|
import { moduleArch } from '@dsh-workbench/module-tools/arch';
|
|
27
27
|
export default moduleArch();
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
报错格式 `<包名>: <文件>:<行> <说明>(<规则>)—— <hint>`;仅 `error` 阻断(`warn` 提示);配置 import / 语法错也红。
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
✔ 模块架构(分层 / 边界 / 设计系统) 1/1 个模块包带 arch.config.mjs · 7 个源文件 · 58 条规则在跑
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
红了逐条是 `<包名>: <文件>:<行> <说明>(<规则>) —— <hint>`;括号里那个规则号是下表的键;只有 `error` 挡门禁(`warn` 只提示);配置自己跑不起来(import / 语法错)也判红。
|
|
37
|
-
|
|
38
|
-
| 常见红(规则) | 它在说什么 | 怎么修 |
|
|
32
|
+
| 规则 | 含义 | 修法 |
|
|
39
33
|
|---|---|---|
|
|
40
|
-
| `
|
|
41
|
-
| `
|
|
42
|
-
| `
|
|
43
|
-
| `
|
|
44
|
-
| `
|
|
45
|
-
| `
|
|
46
|
-
| `
|
|
47
|
-
| `
|
|
34
|
+
| `S01` 表外目录 | 文件不在层序表(如 `src/utils/`) | 移入 `model/` / `components/`,或用 `layers` / `roles` 声明 |
|
|
35
|
+
| `S21` 反向依赖 | 低层引高层(组件引 `../host`) | 被引项下沉 `model/`;只依赖层号 ≤ 自身 |
|
|
36
|
+
| `S23` 跨运行时 | 宿主 import `src/components/**` 或反向 | 组件归 client 面;两侧经服务名 |
|
|
37
|
+
| `S16` 超长 | 文件 >200 行 / 函数 >80(测试豁免) | 拆;或传 `fileLines` / `functionLines`;单文件用 `exceptions` |
|
|
38
|
+
| `M08` 无测试 | `src/model/**` 无配对测试 | 补 `src/model/X.test.ts` |
|
|
39
|
+
| `D12` 刻度外值 | 手写不在刻度的尺寸 | 用 `--dsw-*` 或刻度值 |
|
|
40
|
+
| `D09` `!important` | 只允许 `src/components/vendor/` | 改选择器 / 层级 |
|
|
41
|
+
| `D17` 未使用类 | `*.module.css` 定义未使用 | 删除 |
|
|
48
42
|
|
|
49
|
-
|
|
43
|
+
放宽从参数进:`moduleArch({ fileLines, deps, layers, roles, structure, exceptions })`;`exceptions` 每条需 `reason`:
|
|
50
44
|
|
|
51
45
|
```js
|
|
52
46
|
export default moduleArch({
|
|
53
47
|
layers: { host: 10 },
|
|
54
48
|
roles: [{ id: 'lib:platform', pattern: 'src/platform/**', layer: 1 }],
|
|
55
|
-
exceptions: [{ rule: 'S16', glob: 'src/host/service.ts', reason: '
|
|
49
|
+
exceptions: [{ rule: 'S16', glob: 'src/host/service.ts', reason: '…' }],
|
|
56
50
|
});
|
|
57
51
|
```
|
|
58
52
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
## 第十三条 `lint`:模块自己的语法卫生
|
|
53
|
+
层序表与 `dsh.workbenchFaces` 所指两个面不可调;改动会先红 `contracts` / `source`。
|
|
62
54
|
|
|
63
|
-
`
|
|
55
|
+
## 第十三条 `lint`
|
|
64
56
|
|
|
65
|
-
|
|
57
|
+
`arch` 管文件间,`lint` 管文件内。只跑带 `eslint.config.mjs` 的模块;无文件 = 不适用,不是红。
|
|
66
58
|
|
|
67
59
|
```js
|
|
68
60
|
import { moduleLint } from '@dsh-workbench/module-tools/lint';
|
|
69
61
|
export default moduleLint({ rootDir: import.meta.dirname });
|
|
70
62
|
```
|
|
71
63
|
|
|
72
|
-
`rootDir`
|
|
73
|
-
|
|
74
|
-
**怎么读**:`dsh-wb-module check --only lint`。通过长这样(部分模块上车时多一句 `其余 N 个没有 eslint.config.mjs(不适用)`):
|
|
64
|
+
`rootDir` 钉 typescript-eslint 的 `tsconfigRootDir`(工作区可能有其他 eslint 配置;不传会报
|
|
65
|
+
`No tsconfigRootDir was set…`)。
|
|
75
66
|
|
|
76
|
-
|
|
77
|
-
✔ 模块代码卫生(eslint):1/1 个模块包带 eslint.config.mjs · 8 个文件 · 0 error · 0 warn
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
红了逐条是 `名字: 文件:行:列 规则 —— 一句话`(压成单行、截 200 字)。**只有 `error` 算红**,`warn` 只计数(单跑时列在 `warn(不挡门禁):` 下);聚合最多列 40 条,`--only lint` 列全;配置跑不起来也判红(同 `arch`)。
|
|
67
|
+
仅 `error` 算红;`warn` 计数。聚合最多 40 条,`--only lint` 全列;配置跑不起来也红。
|
|
81
68
|
|
|
82
|
-
|
|
|
69
|
+
| 规则 | 含义 | 修法 |
|
|
83
70
|
|---|---|---|
|
|
84
|
-
|
|
|
85
|
-
| `no-console` | `src/**`
|
|
86
|
-
| `no-debugger` |
|
|
87
|
-
| `no-restricted-syntax` |
|
|
88
|
-
| `react-hooks
|
|
89
|
-
|
|
|
90
|
-
|
|
|
71
|
+
| `no-explicit-any` | `as any` / `: any` | 写真实类型;或在 `moduleLint({ rules })` 放行 |
|
|
72
|
+
| `no-console` | `src/**` 的 `console.log` / `info` / `debug`(`warn` / `error` 放行) | 删除;`scripts/**` 不判 |
|
|
73
|
+
| `no-debugger` | 残留 `debugger` | 删除 |
|
|
74
|
+
| `no-restricted-syntax` | 颜色字面量(`#ff0000` / `rgb(` / `hsl(`)、字符串 `!important` | 用令牌与 `*.module.css` |
|
|
75
|
+
| `react-hooks/*` | 条件 hook / 渲染期写 ref / 漏依赖 | 提到顶层;副作用进 `useEffect`;补依赖 |
|
|
76
|
+
| `no-unused-vars` | 死代码(`^_` 放行) | 删除或改 `_x` |
|
|
77
|
+
| 其他 `recommended` / `react/*` | 语法规则 | 按 eslint 原文 |
|
|
91
78
|
|
|
92
|
-
|
|
79
|
+
放宽从命名参数(`ignores` / `rules`);按目录追加一块:
|
|
93
80
|
|
|
94
81
|
```js
|
|
95
82
|
export default [
|
|
@@ -98,31 +85,30 @@ export default [
|
|
|
98
85
|
];
|
|
99
86
|
```
|
|
100
87
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
**`--fix`**:`dsh-wb-module lint --fix`(模块里是 `pnpm lint -- --fix`)写回能自动修的、打印「修了 N 条 / 还剩 M 条」。**`check` 永远不动手改文件**。
|
|
104
|
-
|
|
105
|
-
## 什么时候该怀疑门禁本身
|
|
106
|
-
|
|
107
|
-
判据自己也有正反例,正常不误报。但**骨架刚 `init` 出来、一行没改却红了** —— 那是模板 / 工具坏了,不是你的。
|
|
88
|
+
不改方言:判据将 `moduleLint()` 的整份 8 块与配置逐块比(名字 / `files` / `rules`;`/overrides`、`/root` 不比),
|
|
89
|
+
全局 ignores 按超集比。少块、重名、改规则值、只抄名字、`export default []`、`.filter(…)` 均红。
|
|
108
90
|
|
|
109
|
-
|
|
91
|
+
`dsh-wb-module lint --fix` 写回可自动修项;`check` 不改文件。
|
|
110
92
|
|
|
111
|
-
|
|
93
|
+
## 怀疑门禁
|
|
112
94
|
|
|
113
|
-
|
|
114
|
-
2. **改完没热换** → 宿主侧秒级热换;客户端刷新页面。[WIRING.md](WIRING.md) §4
|
|
115
|
-
3. **"再装一遍"** → 日常迭代只重建、不重装。[WIRING.md](WIRING.md) §3
|
|
116
|
-
4. **引了 dsh 原语却 `tsc` 报"找不到模块"** → 两处声明 + `pnpm install`([KIT.md](KIT.md) §8)。
|
|
95
|
+
骨架刚 `init`、未改动却红 → 模板或工具问题,不是模块问题。
|
|
117
96
|
|
|
118
|
-
##
|
|
97
|
+
## 卡片故障:四步取证
|
|
119
98
|
|
|
120
|
-
|
|
99
|
+
先取证再改代码;某步有结论就停在对应侧修。
|
|
121
100
|
|
|
122
|
-
1.
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
101
|
+
1. `workbench_diy_panel`:每卡的读取状态(宿主码与原文)、是否崩过(原因、次数)。有结论即止。
|
|
102
|
+
2. 看卡片:`workbench_diy_screenshot` / `_html` / `_find` / `_eval`,作用于用户当前页的该卡(`unit=…`)。
|
|
103
|
+
这一族(14 把 + `logs_*`)需先 `workbench_diy_debug_start`(`unit=…`,审批一次),否则拒绝;
|
|
104
|
+
`_panel` / `_status` / `read=` 档不需要。用完 `_pause`,收工 `_stop`。
|
|
105
|
+
3. `workbench_diy_status`(`unit=…`):看"起得来"行(装配错误 / 声明被拒原文)。
|
|
106
|
+
4. 直接请求路由:`curl '<工作台地址>/workbench/api/<unit>/<route>'`(默认 `http://127.0.0.1:3081`)。
|
|
107
|
+
接口对 → 渲染侧;接口错 → 宿主侧(按 [DATASOURCE.md](DATASOURCE.md) 重探)。需要在页面内请求时用
|
|
108
|
+
`_eval`(`read=<站点>`)。控制台:`_logs_watch` → 操作 → `_logs_read`(每页 200 条 / 单条 400 字,
|
|
109
|
+
刷新即失;用 `_logs_stop` 卸载)。`opencli browser … console` 是空桩(恒空、exit 0),不用。
|
|
110
|
+
宿主热换 / 装载错误在启动工作台的终端。
|
|
127
111
|
|
|
128
|
-
|
|
112
|
+
不要求用户截图或转述报错。验收由 agent 用上述工具逐条走三张表:读数、动作返回、收发包、日志均算证据;
|
|
113
|
+
走通才 `design accept`,走不通记"未验"。参数与返回为 opencli 原样([FAMILY.md](FAMILY.md))。
|
|
114
|
+
面板运行态由用户页面上报;第 1 步为空时,先让用户切到该工作区并刷新一次。
|