@marsken/dsh-studio 0.1.2 → 0.1.4
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/AGENTS.md +1 -1
- package/README.md +65 -0
- package/client.js +17 -17
- package/dist/client.js +17 -17
- package/docs/compatibility.md +1 -1
- package/docs/publish.md +2 -0
- package/index.js +8 -0
- package/package.json +1 -1
- package/src/host/db-runner.js +56 -0
- package/src/host/domain.js +23 -10
- package/src/host/events.js +26 -0
- package/src/host/executor.js +28 -3
- package/src/host/limits.js +19 -0
- package/src/host/routes/tasks.js +6 -3
- package/src/host/runners.js +26 -0
- package/src/host/shell-case.js +16 -0
- package/src/host/shell-runner.js +42 -0
- package/src/host/webhooks.js +45 -0
package/AGENTS.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
| 路径 | 是什么 | 谁能改 |
|
|
8
8
|
| --- | --- | --- |
|
|
9
9
|
| `index.js` | 宿主半边:`apply(ctx)`、39 个 `studio_*` 工具、`/studio-api/*` 路由、SQLite 存储、派单引擎、门禁 | ✅ 直接改 |
|
|
10
|
-
| `src/host/*.js` | 宿主层模块:`cases.js`(跨卡用例聚合与回归汇总:`collectCases` / `groupCaseKeys` / `summarizeRun`,纯函数)、`team-memory.js`(专家团的团级记忆,存 side 键)、`quality.js`(AI 质量:返工识别与按专家汇总,纯函数)、`gitlab-facts.js`(执行记录 vs MR 事实的对账,纯函数)、`impact.js`(需求改版的影响面:受影响的卡与要重跑的用例,纯函数)、`design.js`(设计评审记录与进开发前的闸门,纯函数)、`domain.js`(板列/数据形状/`sanitize*`/默认配置,纯函数)、`dispatcher.js`(派单引擎)、`executor.js`(用例执行、代码事实核对、健康检查)、`store.js`(`StudioStore`/`SecretStore`:SQLite 台账 + 快照 + 登录会话)、`integrations.js`(GitLab / 飞书 / 平台健康)、`routes/*.js`(按前缀拆出的 HTTP 处理:`exports.js` 导出 CSV、`auth.js` 统一登录、`tasks.js` 卡片/专家/列、`requirements.js` 需求/文档/公开提单、`releases.js` 版本/灰度/部署、`insights.js` 指标与工作台、`skills.js` 技能库读写上传、`admin.js` 配置/权限成员/审计/快照、`connect.js` 市场/集成健康/GitLab/仓库/飞书、`agents.js` 派单运行态与起停、`coding.js` 执行记录/失败重试/worktree/项目配置、`tools.js` 39 个 `studio_*` 工具) | ✅ 直接改,新逻辑优先放这里 |
|
|
10
|
+
| `src/host/*.js` | 宿主层模块:`cases.js`(跨卡用例聚合与回归汇总:`collectCases` / `groupCaseKeys` / `summarizeRun`,纯函数)、`team-memory.js`(专家团的团级记忆,存 side 键)、`quality.js`(AI 质量:返工识别与按专家汇总,纯函数)、`gitlab-facts.js`(执行记录 vs MR 事实的对账,纯函数)、`impact.js`(需求改版的影响面:受影响的卡与要重跑的用例,纯函数)、`design.js`(设计评审记录与进开发前的闸门,纯函数)、`shell-runner.js`(shell 用例执行器,默认关闭)、`shell-case.js`(shell 用例的数据形状,纯函数)、`runners.js`(用例执行器注册表:match + run,加新执行方式不用动 runOneCase)、`limits.js`(数量上限的默认值与清洗,可配置)、`db-runner.js`(SQLite 用例执行器与数据形状,默认关闭)、`events.js`(进程内事件总线,同步扇出)、`webhooks.js`(事件 → 出站 webhook,失败不重试)、`domain.js`(板列/数据形状/`sanitize*`/默认配置,纯函数)、`dispatcher.js`(派单引擎)、`executor.js`(用例执行、代码事实核对、健康检查)、`store.js`(`StudioStore`/`SecretStore`:SQLite 台账 + 快照 + 登录会话)、`integrations.js`(GitLab / 飞书 / 平台健康)、`routes/*.js`(按前缀拆出的 HTTP 处理:`exports.js` 导出 CSV、`auth.js` 统一登录、`tasks.js` 卡片/专家/列、`requirements.js` 需求/文档/公开提单、`releases.js` 版本/灰度/部署、`insights.js` 指标与工作台、`skills.js` 技能库读写上传、`admin.js` 配置/权限成员/审计/快照、`connect.js` 市场/集成健康/GitLab/仓库/飞书、`agents.js` 派单运行态与起停、`coding.js` 执行记录/失败重试/worktree/项目配置、`tools.js` 39 个 `studio_*` 工具) | ✅ 直接改,新逻辑优先放这里 |
|
|
11
11
|
| `client.src.js` | 浏览器半边的手写源码(通过 `window.__ModuleLoader__` 注册面板) | ✅ 直接改(前端逻辑) |
|
|
12
12
|
| `web/src/**` | shadcn/Radix 组件、样式、`legacy.js` 桥;`web/src/studio/*.js` 是从 `client.src.js` 抬出来的纯模块(`markdown.js` 渲染器、`format.js` 日期格式、`labels.js` 标签表、`roster.js` 负责人与候选人、`fields.js` 表单适配层、`shell.js` 共享抽屉、`card.js` 看板卡片、`board.js` 看板本体、`mentions.js` @ 选择器、`cases.js` 多步用例解析、`drawer.js` 卡片详情抽屉、`editor.js` 通用编辑器、`palette.js` 命令面板(⌘K 全局搜索卡片/需求/版本/专家/专家团/项目/技能 + 动作项 + Ctrl/⌘+Alt+Shift+N/T/D 全局快捷键;带 Shift 是为了避开宿主的 Ctrl+Alt+N 新会话)、`charts.js` 进度条与燃尽图、`context.js` 共享上下文(`provideClient`/`client`)、`panels/*.js` 设置页 17 个面板、`pages/*.js` 六个页面组件(看板之外的工作台/需求/用例/版本/效能/自助提单);**`StudioPage` 是组合根,故意留在 `client.src.js`**,它负责顶栏、页签与「+ 新建」菜单并调用 `provideClient()`,别为了行数把它搬走),由 `make-legacy` 生成的 `legacy.js` 顶部统一 import | ✅ 直接改(样式与组件) |
|
|
13
13
|
| `dist/client.js` | `pnpm build` 的产物(单文件 IIFE,注意在仓库根 `dist/`,不是 `web/dist/`) | ❌ 生成物 |
|
package/README.md
CHANGED
|
@@ -310,6 +310,71 @@ sudo systemctl restart dsh-web
|
|
|
310
310
|
- **跑之前平台自己先探环境**(2026-11-13):开跑前对 `baseUrl` 发一个请求,连不上就直接回「测试环境「X」不可达(ECONNREFUSED):一条用例都没跑」,**不会把整批用例刷成失败**。任何 HTTP 响应(含 404/500)都算活着——那是服务在跑,只是接口不对。
|
|
311
311
|
|
|
312
312
|
|
|
313
|
+
## shell 用例(默认关闭)
|
|
314
|
+
|
|
315
|
+
用例除了打接口,还能跑一条命令并断言结果——补上「单测 / 脚本类」用例长期只能手工回填的缺口。
|
|
316
|
+
|
|
317
|
+
**打开方式**:设置 → 测试执行 → 打开「允许 shell 用例」(`config.testing.allowShell`)。
|
|
318
|
+
|
|
319
|
+
> ⚠️ 打开它等于承认:**能打开看板的人可以在宿主机上执行任意命令**。只在信任使用者时开启;默认关闭,关闭时 shell 用例会明确失败并说明原因,不会静默跳过。
|
|
320
|
+
|
|
321
|
+
| 字段 | 作用 |
|
|
322
|
+
| --- | --- |
|
|
323
|
+
| `command` | 要跑的命令(必填) |
|
|
324
|
+
| `cwd` | 工作目录;留空用设置里的默认值 |
|
|
325
|
+
| `timeoutMs` | 超时,默认 30s,上限 120s |
|
|
326
|
+
| `expectExit` | 期望退出码,默认 0 |
|
|
327
|
+
| `expectContains` / `expectNotContains` | 输出里必须出现 / 不能出现的内容 |
|
|
328
|
+
|
|
329
|
+
两个入口:卡片抽屉用例区的 **「+ shell」**(命令 + 期望输出两步录入),或调 `POST /studio-api/task/case` 直接写 `shell: { … }`。
|
|
330
|
+
## 数据库用例(默认关闭)
|
|
331
|
+
|
|
332
|
+
第三种执行方式:对着一个 SQLite 库跑一条语句,断言行数与首行某列的值。适合「库存不能被扣成负数」这类只有查库才能确认的验收。
|
|
333
|
+
|
|
334
|
+
**打开方式**:设置 → 测试执行 → 打开「允许数据库用例」(`config.testing.allowDb`)。默认**只读**打开,要写入必须显式 `readOnly: false`。
|
|
335
|
+
|
|
336
|
+
```json
|
|
337
|
+
{ "title": "库存不能超卖", "db": {
|
|
338
|
+
"file": "/tmp/test.db",
|
|
339
|
+
"sql": "select count(*) as n from orders where stock < 0",
|
|
340
|
+
"expectRows": 1, "expectColumn": "n", "expectValue": "0" } }
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
| 字段 | 作用 |
|
|
344
|
+
| --- | --- |
|
|
345
|
+
| `file` / `sql` | 必填;库文件路径与语句 |
|
|
346
|
+
| `params` | 绑定参数(`?` 占位) |
|
|
347
|
+
| `expectRows` | 期望行数;不填不校验 |
|
|
348
|
+
| `expectColumn` + `expectValue` | 校验首行某一列的值 |
|
|
349
|
+
| `readOnly` | 默认 `true`;要改数据才设 `false` |
|
|
350
|
+
|
|
351
|
+
## 出站 webhook(把变化告诉外部系统)
|
|
352
|
+
|
|
353
|
+
卡片流转、用例失败、派单失败都会发事件,配了 webhook 就 POST 出去:
|
|
354
|
+
|
|
355
|
+
```json
|
|
356
|
+
{ "webhooks": [{ "id": "ci", "url": "https://ci.example/hook",
|
|
357
|
+
"events": ["task/moved", "case/failed"], "enabled": true }] }
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
事件长这样:
|
|
361
|
+
|
|
362
|
+
```json
|
|
363
|
+
{ "type": "task/moved", "at": 1794585755429,
|
|
364
|
+
"payload": { "taskId": "t-…", "from": "clarify", "to": "accept", "by": "agent" } }
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
约定三条:**调用方不重试**(外部抖动是常态,事件本身已进台账)、**5 秒超时**、**订阅者之间互不影响**(一个 hook 抛错不影响其它 hook,也不影响正在写库的请求)。
|
|
368
|
+
|
|
369
|
+
## 数量上限(可配)
|
|
370
|
+
|
|
371
|
+
以前写死在路由里:一张卡 60 条用例、一次批量跑 60 条、一张卡 40 个交付物——**超了静默丢**。现在读配置,超了会明确报错(套件回归仍然继续跑,但会标记 `truncated`):
|
|
372
|
+
|
|
373
|
+
```json
|
|
374
|
+
{ "limits": { "casesPerTask": 60, "runKeys": 60, "artifactsPerTask": 40 } }
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
范围 1–500,写非法值会退回默认。
|
|
313
378
|
## 用例自动生成(从功能点长出来,不是凭空写)
|
|
314
379
|
|
|
315
380
|
测试用例不用一条条手敲:需求拆了功能点、每个功能点带验收条件,平台就能照着生成。
|