@epoint-testtech/ep-stage-skill 0.0.3-alpha.2 → 0.0.4-alpha.1
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/SKILL.md +2 -2
- package/codex-skill/ep-stage/.omc/state/sessions/d636ad35-5fc9-4d5e-85b0-2bcad7d86ee5/pre-tool-advisory-throttle.json +10 -0
- package/codex-skill/ep-stage/glue-create-project/SKILL.md +206 -0
- package/codex-skill/ep-stage/glue-generate-testcase/SKILL.md +274 -0
- package/codex-skill/ep-stage/glue-generate-testcase/references/testcase-schema.md +112 -0
- package/codex-skill/ep-stage/glue-generate-testcase/references/testcase-tpl.md +72 -0
- package/codex-skill/ep-stage/glue-run-test/SKILL.md +289 -0
- package/codex-skill/ep-stage/glue-run-test/references/crud-pipeline.md +145 -0
- package/codex-skill/ep-stage/{glue-test → glue-run-test}/scripts/generate-crud-spec.mjs +3 -3
- package/codex-skill/ep-stage/recording-to-glue/SKILL.md +1 -0
- package/codex-skill/ep-stage/scripts/validate-skill.mjs +29 -7
- package/dist/src/cli/dev/extract-contract.d.ts +14 -0
- package/dist/src/cli/dev/extract-contract.d.ts.map +1 -0
- package/dist/src/cli/dev/extract-contract.js +114 -0
- package/dist/src/cli/generate-crud-contract.js +7 -77
- package/dist/src/cli/generate-playwright-tests.d.ts +0 -28
- package/dist/src/cli/generate-playwright-tests.d.ts.map +1 -1
- package/dist/src/cli/generate-playwright-tests.js +4 -81
- package/dist/src/cli/generate-testcase.d.ts +84 -0
- package/dist/src/cli/generate-testcase.d.ts.map +1 -0
- package/dist/src/cli/generate-testcase.js +300 -0
- package/dist/src/cli/index.d.ts +26 -0
- package/dist/src/cli/index.d.ts.map +1 -0
- package/dist/src/cli/index.js +75 -0
- package/dist/src/cli/probe.d.ts +46 -0
- package/dist/src/cli/probe.d.ts.map +1 -0
- package/dist/src/cli/probe.js +447 -0
- package/dist/src/cli/run-gap-pipeline.js +4 -0
- package/dist/src/cli/run.d.ts +63 -0
- package/dist/src/cli/run.d.ts.map +1 -0
- package/dist/src/cli/run.js +116 -0
- package/dist/src/cli/spec.d.ts +48 -0
- package/dist/src/cli/spec.d.ts.map +1 -0
- package/dist/src/cli/spec.js +102 -0
- package/dist/src/context/stage-context.d.ts +72 -8
- package/dist/src/context/stage-context.d.ts.map +1 -1
- package/dist/src/context/stage-context.js +61 -15
- package/dist/src/contracts/inference-trace.d.ts +223 -0
- package/dist/src/contracts/inference-trace.d.ts.map +1 -0
- package/dist/src/contracts/inference-trace.js +12 -0
- package/dist/src/extractors/code-list.d.ts +3 -3
- package/dist/src/extractors/code-list.d.ts.map +1 -1
- package/dist/src/extractors/code-list.js +46 -11
- package/dist/src/generators/stage-skeleton-script.d.ts.map +1 -1
- package/dist/src/generators/stage-skeleton-script.js +9 -0
- package/dist/src/index.d.ts +7 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -1
- package/dist/src/inference/module-hints-inference.d.ts +30 -0
- package/dist/src/inference/module-hints-inference.d.ts.map +1 -0
- package/dist/src/inference/module-hints-inference.js +363 -0
- package/dist/src/inference/source-analysis.d.ts +26 -0
- package/dist/src/inference/source-analysis.d.ts.map +1 -0
- package/dist/src/inference/source-analysis.js +258 -0
- package/dist/src/testcase/testcase-generator.d.ts.map +1 -1
- package/dist/src/testcase/testcase-generator.js +4 -0
- package/dist/src/testcase/testcase-v2.d.ts +50 -0
- package/dist/src/testcase/testcase-v2.d.ts.map +1 -0
- package/dist/src/testcase/testcase-v2.js +1 -0
- package/dist/src/util/credentials.d.ts +12 -0
- package/dist/src/util/credentials.d.ts.map +1 -0
- package/dist/src/util/credentials.js +19 -0
- package/dist/src/util/i18n-testcase.d.ts +8 -0
- package/dist/src/util/i18n-testcase.d.ts.map +1 -0
- package/dist/src/util/i18n-testcase.js +55 -0
- package/dist/src/util/softlink.d.ts +33 -0
- package/dist/src/util/softlink.d.ts.map +1 -0
- package/dist/src/util/softlink.js +43 -0
- package/dist/src/validation/credentials.d.ts +19 -0
- package/dist/src/validation/credentials.d.ts.map +1 -0
- package/dist/src/validation/credentials.js +38 -0
- package/dist/src/validation/index.d.ts +6 -0
- package/dist/src/validation/index.d.ts.map +1 -0
- package/dist/src/validation/index.js +4 -0
- package/dist/src/validation/inference-trace.d.ts +13 -0
- package/dist/src/validation/inference-trace.d.ts.map +1 -0
- package/dist/src/validation/inference-trace.js +31 -0
- package/dist/src/validation/projects-index.d.ts +13 -0
- package/dist/src/validation/projects-index.d.ts.map +1 -0
- package/dist/src/validation/projects-index.js +37 -0
- package/dist/src/validation/testcase.d.ts +13 -0
- package/dist/src/validation/testcase.d.ts.map +1 -0
- package/dist/src/validation/testcase.js +53 -0
- package/dist/test/cli/extract-contract.test.d.ts +2 -0
- package/dist/test/cli/extract-contract.test.d.ts.map +1 -0
- package/dist/test/cli/extract-contract.test.js +32 -0
- package/dist/test/cli/generate-testcase-inference.test.d.ts +2 -0
- package/dist/test/cli/generate-testcase-inference.test.d.ts.map +1 -0
- package/dist/test/cli/generate-testcase-inference.test.js +63 -0
- package/dist/test/cli/generate-testcase-paths.test.d.ts +2 -0
- package/dist/test/cli/generate-testcase-paths.test.d.ts.map +1 -0
- package/dist/test/cli/generate-testcase-paths.test.js +165 -0
- package/dist/test/cli/generate-testcase-requirements.test.d.ts +2 -0
- package/dist/test/cli/generate-testcase-requirements.test.d.ts.map +1 -0
- package/dist/test/cli/generate-testcase-requirements.test.js +229 -0
- package/dist/test/cli/generate-testcase.test.d.ts +2 -0
- package/dist/test/cli/generate-testcase.test.d.ts.map +1 -0
- package/dist/test/cli/generate-testcase.test.js +130 -0
- package/dist/test/cli/index.test.d.ts +2 -0
- package/dist/test/cli/index.test.d.ts.map +1 -0
- package/dist/test/cli/index.test.js +113 -0
- package/dist/test/cli/probe.test.d.ts +2 -0
- package/dist/test/cli/probe.test.d.ts.map +1 -0
- package/dist/test/cli/probe.test.js +31 -0
- package/dist/test/cli/run.test.d.ts +2 -0
- package/dist/test/cli/run.test.d.ts.map +1 -0
- package/dist/test/cli/run.test.js +149 -0
- package/dist/test/cli/spec-boundary.test.d.ts +2 -0
- package/dist/test/cli/spec-boundary.test.d.ts.map +1 -0
- package/dist/test/cli/spec-boundary.test.js +198 -0
- package/dist/test/cli/spec.test.d.ts +2 -0
- package/dist/test/cli/spec.test.d.ts.map +1 -0
- package/dist/test/cli/spec.test.js +196 -0
- package/dist/test/code-list.test.d.ts +2 -0
- package/dist/test/code-list.test.d.ts.map +1 -0
- package/dist/test/code-list.test.js +39 -0
- package/dist/test/crud-contract.test.js +12 -32
- package/dist/test/inference/module-hints-inference.test.d.ts +2 -0
- package/dist/test/inference/module-hints-inference.test.d.ts.map +1 -0
- package/dist/test/inference/module-hints-inference.test.js +25 -0
- package/dist/test/inference/source-analysis.test.d.ts +2 -0
- package/dist/test/inference/source-analysis.test.d.ts.map +1 -0
- package/dist/test/inference/source-analysis.test.js +23 -0
- package/dist/test/material-inventory.test.js +13 -0
- package/dist/test/observable-pipeline.test.js +12 -3
- package/dist/test/stage-context.test.js +145 -13
- package/dist/test/util/credentials.test.d.ts +2 -0
- package/dist/test/util/credentials.test.d.ts.map +1 -0
- package/dist/test/util/credentials.test.js +64 -0
- package/dist/test/util/i18n-testcase.test.d.ts +2 -0
- package/dist/test/util/i18n-testcase.test.d.ts.map +1 -0
- package/dist/test/util/i18n-testcase.test.js +119 -0
- package/dist/test/util/softlink.test.d.ts +2 -0
- package/dist/test/util/softlink.test.d.ts.map +1 -0
- package/dist/test/util/softlink.test.js +82 -0
- package/dist/test/validation/credentials.test.d.ts +2 -0
- package/dist/test/validation/credentials.test.d.ts.map +1 -0
- package/dist/test/validation/credentials.test.js +72 -0
- package/dist/test/validation/projects-index.test.d.ts +2 -0
- package/dist/test/validation/projects-index.test.d.ts.map +1 -0
- package/dist/test/validation/projects-index.test.js +48 -0
- package/dist/test/validation/testcase.test.d.ts +2 -0
- package/dist/test/validation/testcase.test.d.ts.map +1 -0
- package/dist/test/validation/testcase.test.js +129 -0
- package/docs/README.md +6 -6
- package/docs/mvp-usage-guide.md +3 -3
- package/package.json +9 -4
- package/codex-skill/ep-stage/create-project/SKILL.md +0 -59
- package/codex-skill/ep-stage/glue-test/SKILL.md +0 -258
- package/codex-skill/ep-stage/glue-test/references/crud-pipeline.md +0 -139
- package/codex-skill/ep-stage/glue-testcase/SKILL.md +0 -31
- package/codex-skill/ep-stage/glue-testcase/references/testcase-schema.md +0 -67
- /package/codex-skill/ep-stage/{glue-testcase → glue-generate-testcase}/examples/observable-testcase.json +0 -0
- /package/codex-skill/ep-stage/{glue-test → glue-run-test}/references/gap-review-protocol.md +0 -0
- /package/codex-skill/ep-stage/{glue-test → glue-run-test}/references/harness-principles.md +0 -0
package/SKILL.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ep-stage-skill-package
|
|
3
|
-
description: 使用时机:当需要维护 @epoint/ep-stage-skill 包源码、CLI 提取器、CRUD 契约生成器,或面向 Codex 的 ep-stage skill 资产时使用。
|
|
3
|
+
description: 使用时机:当需要维护 @epoint-testtech/ep-stage-skill 包源码、CLI 提取器、CRUD 契约生成器,或面向 Codex 的 ep-stage skill 资产时使用。
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# @epoint/ep-stage-skill 包
|
|
6
|
+
# @epoint-testtech/ep-stage-skill 包
|
|
7
7
|
|
|
8
8
|
本包负责面向 Codex 的 `ep-stage` skill 背后的确定性工具链:
|
|
9
9
|
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"entries": {
|
|
4
|
+
"79a93d4a2f8f50b95f852280616242fee1855dc99a3c75211917f55e72e95fae": {
|
|
5
|
+
"last_emitted_at_ms": 1782437222409,
|
|
6
|
+
"message": "Use parallel execution for independent tasks. Use run_in_background for long operations (npm install, builds, tests)."
|
|
7
|
+
}
|
|
8
|
+
},
|
|
9
|
+
"updated_at": "2026-06-26T01:27:02.409Z"
|
|
10
|
+
}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: glue-create-project
|
|
3
|
+
description: 使用时机:当用户表达「创建胶水项目 / 测试脚手架 / 新建 glue 项目」或显式触发 `/glue-create-project [名称或路径]` 时使用。本 skill 只创建胶水模式(glue)Playwright 测试脚手架,不收集登录信息,不写 .env / stage-context.md。
|
|
4
|
+
version: 2026-06-25+6e9e357
|
|
5
|
+
argument-hint: "<脚手架项目名或脚手架项目路径>"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# ep-stage: glue-create-project
|
|
9
|
+
|
|
10
|
+
本 skill 引导 Agent **包装** `@epoint-testtech/stage-create` CLI 的 glue 模式,不重新实现脚手架。用户视角全中文,不暴露 CLI 名称。
|
|
11
|
+
|
|
12
|
+
> CLI 自 0.0.4-alpha.0 起已中性化:不再收集业务系统登录信息,不再写 `<projectDir>/.env`,也不再写 `<projectDir>/stage-context.md`。项目元信息全部沉到 `~/.ep-stage/projects.index.json5`(含 `stageCreateVersion`)。登录凭据由下游 `glue-generate-testcase` / `glue-run-test` 在需求级 `credentials.json5` 中收集。
|
|
13
|
+
|
|
14
|
+
## 1. 自然语言映射规则
|
|
15
|
+
|
|
16
|
+
用户在 Claude Code / Codex 里触发 skill 的典型形式:
|
|
17
|
+
|
|
18
|
+
```text
|
|
19
|
+
/glue-create-project my-project # 裸名 → 落 <pwd>/e2e-test/my-project
|
|
20
|
+
/glue-create-project path/my-project # 含 / → 原样落点
|
|
21
|
+
/glue-create-project /abs/path/my-project # 绝对路径 → 原样落点
|
|
22
|
+
/glue-create-project # 无参数 → 问项目名
|
|
23
|
+
/glue-create-project my-project --debug # 调试模式 → 跑本地 monorepo 的 stage-create dist
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
> **`--debug` flag**:正常调用走远程 `npx @epoint-testtech/stage-create@latest`。开发期想测试未发布的本地代码时传 `--debug`,skill 在 Step 3 改用 `node <repo>/packages/stage-create/dist/index.js`。前提:cwd 在 ep-stage monorepo 内(向上能找到 `pnpm-workspace.yaml`);找不到时直接 exit 1 报错,不静默 fallback 到 npx。
|
|
27
|
+
|
|
28
|
+
### 1.1 目标位置与项目名(路径解析三段式)
|
|
29
|
+
|
|
30
|
+
CLI 接收 `[project-name]` 参数,内部用 `path.basename` 取项目名、`path.resolve` 取输出目录(基于 Agent cwd):
|
|
31
|
+
|
|
32
|
+
| 用户输入 | skill 传给 CLI 的值 | 最终落点 |
|
|
33
|
+
|---------------------------------------------|---------------------------------------------|-----------------------------------------|
|
|
34
|
+
| 含 `/` 或绝对路径 | 原样透传 | `<cwd>/...` 或绝对路径;项目名取 basename |
|
|
35
|
+
| 裸名(无 `/`) | 拼成 `e2e-test/<name>` | `<cwd>/e2e-test/<name>` |
|
|
36
|
+
| 无参数 | 先问 `<name>`,再拼 `e2e-test/<name>` | `<cwd>/e2e-test/<name>` |
|
|
37
|
+
|
|
38
|
+
**逃生口**:想在当前 cwd 根直接建裸名(不进 `e2e-test/`),用 `./my-project`(含 `/`)。
|
|
39
|
+
|
|
40
|
+
中文目录名 macOS/Linux 能建,但 npm scope 校验和跨平台兼容差。Agent 收到中文名时,AskUserQuestion 二选一:保留中文 / 换 kebab-case 建议(如 `我的项目` → `my-project`)。
|
|
41
|
+
|
|
42
|
+
### 1.2 模式 — 固定 glue
|
|
43
|
+
|
|
44
|
+
本 skill 只创建 glue 项目,固定传 `--mode glue`,不暴露 default 模式入口。
|
|
45
|
+
|
|
46
|
+
### 1.3 工作目录 (cwd) 确认
|
|
47
|
+
|
|
48
|
+
Agent 在调用 CLI 前必须:跑 `pwd` → 按 §1.1 算最终落点 → 中文复述"将在 `<最终落点>` 下创建项目,确认吗?" → 用户否认 → 让用户给绝对路径或先 `cd` 切换。
|
|
49
|
+
|
|
50
|
+
典型陷阱:cwd 是 git 仓库根(存在 `.git/`)时必须额外二次确认,避免污染该仓库工作树。
|
|
51
|
+
|
|
52
|
+
## 2. Agent 执行剧本(7 步任务清单协议)
|
|
53
|
+
|
|
54
|
+
**任务清单协议(REQ-UX-01)**:
|
|
55
|
+
|
|
56
|
+
- 加载 skill 后**立即**打印初始任务清单(Step 0)。
|
|
57
|
+
- 每完成一步,输出单行状态更新 `✅ 第 N 步 — <中文名> 已完成,进入第 N+1 步 — <下一中文名>...`(不重写完整清单)。
|
|
58
|
+
- Step 7 输出全勾选终态清单 + 完成摘要。
|
|
59
|
+
|
|
60
|
+
### Step 0 — 打印任务清单
|
|
61
|
+
|
|
62
|
+
```markdown
|
|
63
|
+
📋 **创建胶水测试项目任务清单**
|
|
64
|
+
|
|
65
|
+
- [ ] 第 1 步 — 抽取项目名与落点
|
|
66
|
+
- [ ] 第 2 步 — 补齐核心参数(含 cwd 确认)
|
|
67
|
+
- [ ] 第 3 步 — 调用脚手架 CLI
|
|
68
|
+
- [ ] 第 4 步 — 验证脚手架产物
|
|
69
|
+
- [ ] 第 5 步 — 安装依赖
|
|
70
|
+
- [ ] 第 6 步 — 写入项目索引
|
|
71
|
+
- [ ] 第 7 步 — 输出摘要
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Step 1 — 抽取项目名与落点
|
|
75
|
+
|
|
76
|
+
从用户原始消息 / args 抽取目标路径/项目名(规则见 §1)。模式固定 glue。中文复述识别结果:
|
|
77
|
+
|
|
78
|
+
> 已识别:项目名 = `xxx`,模式 = `胶水模式 (glue)`,落点 = `<pwd>/e2e-test/xxx`。
|
|
79
|
+
|
|
80
|
+
识别失败/不确定 → Step 2 补齐。
|
|
81
|
+
|
|
82
|
+
### Step 2 — 补齐核心参数(含 cwd 确认)
|
|
83
|
+
|
|
84
|
+
只在缺失/有疑时触发,全中文:
|
|
85
|
+
|
|
86
|
+
- 缺 `projectName`(无参数)→ free text 询问"请告诉我新项目的名称",按 §1.1 拼 `e2e-test/<name>`。
|
|
87
|
+
- 中文项目名 → AskUserQuestion 二选一:保留中文 / 换 `<kebab-case 建议>`。
|
|
88
|
+
- cwd 是 git 仓库根 → AskUserQuestion 二选一:在此 cwd 创建 / 取消并手动 cd。
|
|
89
|
+
|
|
90
|
+
> 本 skill 固定 glue 模式,不再收集登录信息,无需就模式或登录配置询问。
|
|
91
|
+
|
|
92
|
+
### Step 3 — 调用脚手架 CLI
|
|
93
|
+
|
|
94
|
+
固定流程(不 which、不扫 monorepo、不 cd 进项目、**不喂 stdin**)。`<targetPath>` 由 §1.1 算出。
|
|
95
|
+
|
|
96
|
+
**正常模式**(用户 args 无 `--debug`):
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
npx -y @epoint-testtech/stage-create@latest "<targetPath>" --mode glue
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**调试模式**(用户 args 含 `--debug`,要求 cwd 在 ep-stage monorepo 内;详见 §1 `--debug` flag 说明):
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
D="$PWD"; REPO=""
|
|
106
|
+
while [ "$D" != "/" ]; do
|
|
107
|
+
if [ -f "$D/pnpm-workspace.yaml" ] && [ -f "$D/packages/stage-create/dist/index.js" ]; then
|
|
108
|
+
REPO="$D"; break
|
|
109
|
+
fi
|
|
110
|
+
D="$(dirname "$D")"
|
|
111
|
+
done
|
|
112
|
+
[ -z "$REPO" ] && { echo "❌ --debug 但找不到本地 monorepo(需 cwd 在 ep-stage 仓库内向上能找到 pnpm-workspace.yaml + packages/stage-create/dist/index.js)"; exit 1; }
|
|
113
|
+
echo "▸ 调试模式:本地 $REPO/packages/stage-create/dist/index.js"
|
|
114
|
+
node "$REPO/packages/stage-create/dist/index.js" "<targetPath>" --mode glue
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
CLI 中性化后**不读 stdin**,不询问登录 URL / 用户名 / 密码 / 知识库根。
|
|
118
|
+
|
|
119
|
+
### Step 4 — 验证脚手架产物
|
|
120
|
+
|
|
121
|
+
按 §4 验证产物。验证失败 → §3 错误处理报告,不发完成提示。
|
|
122
|
+
|
|
123
|
+
### Step 5 — 安装依赖
|
|
124
|
+
|
|
125
|
+
1. 先 `pnpm ping` 检测 registry 连通性:
|
|
126
|
+
- 连不上(超时/报错)→ 跳过自动安装,提示 `网络不通,依赖未自动安装,请手动执行: pnpm install --dir <projectDir>`。
|
|
127
|
+
- 连通 → 进入下一步。
|
|
128
|
+
2. `pnpm install --dir "<projectDir>"`(**禁用 `cd`** 进入项目目录,必须用 `--dir`)。若 `<projectDir>` 位于某个 pnpm workspace 内(向上能找到 `pnpm-workspace.yaml`),改用 `pnpm install --dir "<projectDir>" --ignore-workspace` 做独立安装。
|
|
129
|
+
3. **必须实时透传 pnpm 输出**(进度条、日志),不得静默执行。安装失败 → 如实报告 stderr,不谎报成功;骨架已生成,用户可手动重跑。
|
|
130
|
+
|
|
131
|
+
### Step 6 — 写入项目索引
|
|
132
|
+
|
|
133
|
+
CLI 0.0.4-alpha.0 已在 `~/.ep-stage/projects.index.json5` 的 `projects[]` 数组末尾追加本项目条目(字段精简,含 `stageCreateVersion`,**不含** `envPath/stageContextPath/knowledgeRoot/codeListPaths`)。Agent 校验:
|
|
134
|
+
|
|
135
|
+
- 文件存在
|
|
136
|
+
- 末尾条目 `projectDir` 与本次创建一致
|
|
137
|
+
- 字段含 `projectName / projectDir / mode='glue' / createdAt / stageCreateVersion / requirements=[]`
|
|
138
|
+
|
|
139
|
+
JSON5 项目条目范例(CLI 自动写):
|
|
140
|
+
|
|
141
|
+
```json5
|
|
142
|
+
// ~/.ep-stage/projects.index.json5 项目条目范例(CLI 自动写,无 stageContextPath/envPath/knowledgeRoot)
|
|
143
|
+
{
|
|
144
|
+
projectName: '<projectName>',
|
|
145
|
+
projectDir: '<绝对路径>',
|
|
146
|
+
mode: 'glue',
|
|
147
|
+
createdAt: '2026-06-25T...',
|
|
148
|
+
stageCreateVersion: '0.0.4-alpha.0',
|
|
149
|
+
requirements: [],
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
条目缺失 → 提示"索引文件未登记本项目,后续 ep-stage skills/CLI 无法发现,请检查 stage-create CLI 版本(应 ≥ 0.0.4-alpha.0)"。
|
|
154
|
+
|
|
155
|
+
### Step 7 — 输出摘要
|
|
156
|
+
|
|
157
|
+
打印全勾选终态清单 + §5 完成提示。
|
|
158
|
+
|
|
159
|
+
## 3. 错误处理
|
|
160
|
+
|
|
161
|
+
| CLI 错误(原文) | 触发时机 | Agent 中文呈现 + 建议 |
|
|
162
|
+
|-----------------------------------|-------------|----------------------------------------------------------------------------------------------------------------------|
|
|
163
|
+
| `目录已存在: <path>` (exit 1) | Step 3 前置 | "目录 `<path>` 已存在。我不会主动删除任何已存在目录。" → AskUserQuestion 三选一:换名重来 / 改 cwd / 取消 |
|
|
164
|
+
| npm `404 / ENOTFOUND / ETIMEDOUT` | npx 拉包失败 | "无法从 npm 拉取 @epoint-testtech/stage-create" → 建议 ① 检查网络 ② `npm config get registry` ③ `npm i -g` 预装 |
|
|
165
|
+
| 其他 exit !== 0 | CLI 崩溃 | 把 stderr 原文中文转述并贴出,建议复制错误私聊开发 |
|
|
166
|
+
|
|
167
|
+
**半成品回滚**:CLI 在校验失败时(目录已存在)在 `mkdirSync` 之前退出,无副作用。若 CLI 已 `mkdirSync` 后中途崩,Agent **不主动 `rm`**,提示用户手动检查 `<path>` 后决定是否 `rm -rf` 重试。理由:cwd 不一定可信,盲删可能误伤。
|
|
168
|
+
|
|
169
|
+
**用户中途取消**:AskUserQuestion 阶段等待不超时;自然对话阶段说「算了/取消/stop」立即终止不调 CLI;已调 CLI 后用户取消 → CLI 无中途取消信号,等 CLI 退出后再复述结果。
|
|
170
|
+
|
|
171
|
+
## 4. 验证清单
|
|
172
|
+
|
|
173
|
+
CLI 退出后必须用 `ls` / `Read` 校验产物。验证失败视为整体失败,不要谎报成功。
|
|
174
|
+
|
|
175
|
+
| 路径 | 说明 |
|
|
176
|
+
|-------------------------------------|-------------------------------|
|
|
177
|
+
| `<projectDir>/package.json` | 模板渲染产出 |
|
|
178
|
+
| `<projectDir>/playwright.config.ts` | Playwright 基础配置 |
|
|
179
|
+
| `<projectDir>/tsconfig.json` | TS 配置 |
|
|
180
|
+
| `<projectDir>/src/skeletons/` | 业务骨架目录(非空) |
|
|
181
|
+
| `<projectDir>/src/web/component/` | 页面组件目录 |
|
|
182
|
+
| `<projectDir>/src/report/` | 报告辅助目录 |
|
|
183
|
+
| `~/.ep-stage/projects.index.json5` | 用户级索引,应新增本项目条目 |
|
|
184
|
+
|
|
185
|
+
> **不再校验** `<projectDir>/.env`(CLI 不再写)和 `<projectDir>/stage-context.md`(CLI 不再写,元信息已沉到 projects.index.json5)。
|
|
186
|
+
|
|
187
|
+
**不验证什么**:模板占位符 `{{projectName}}` 是否替换(已由 stage-create prepublish 校验);业务系统登录配置(中性化后不再涉及)。
|
|
188
|
+
|
|
189
|
+
## 5. 完成提示
|
|
190
|
+
|
|
191
|
+
Step 7 验证与依赖安装都通过后,按以下中文格式呈现结果。不要用英文 success/done/created:
|
|
192
|
+
|
|
193
|
+
> ✅ 项目创建完成,依赖已安装
|
|
194
|
+
>
|
|
195
|
+
> 路径:`<projectDir 绝对路径>`
|
|
196
|
+
> 模式:胶水模式 (glue)
|
|
197
|
+
> 索引登记:`~/.ep-stage/projects.index.json5`(含 stageCreateVersion)
|
|
198
|
+
> 依赖:已 `pnpm install` 完成
|
|
199
|
+
> 下一步:对某需求跑 `/glue-generate-testcase <需求目录路径>` 生成用例
|
|
200
|
+
|
|
201
|
+
**失败时不要发完成提示**:第 4 节任一验证项失败或依赖安装失败 → 按 §3 报告,不允许在失败信息里混合"项目创建完成"字样。
|
|
202
|
+
|
|
203
|
+
## 6. 引导场景
|
|
204
|
+
|
|
205
|
+
- **A(缺脚手架)**:N/A — 本 skill 本身即建脚手架的入口,不存在"缺脚手架"前置。
|
|
206
|
+
- **其他**:cwd 是 git 仓库根 → Step 2 二次确认;中文目录名 → Step 2 建议改 kebab-case。
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: glue-generate-testcase
|
|
3
|
+
description: 使用时机:当用户对某需求要「生成用例 / 准备测试场景 / 钻探上游需求生成胶水冒烟用例」或显式触发 `/glue-generate-testcase <code_list.md路径>` 时使用。本 skill 包装 `@epoint-testtech/ep-stage-skill` CLI 的 `testcase` 子命令,并负责自然语言映射、缺数据引导、Step 5 凭据交互确认。
|
|
4
|
+
version: 2026-06-26+58fd337
|
|
5
|
+
argument-hint: "<code_list.md绝对/相对路径>"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# ep-stage: glue-generate-testcase
|
|
9
|
+
|
|
10
|
+
本 skill 引导 Agent **包装** `@epoint-testtech/ep-stage-skill` CLI 的 `testcase` 子命令,不重新实现钻探与用例生成。CLI 内部完成物料解析 + contract 提取(内嵌)+ coverage 分析 + testcase v2 装配 + credentials.template 生成 + code_list.md 软链。skill 负责:`code_list.md` 路径解析、反查项目脚手架、缺数据引导、Step 5 平台对话确认凭据、审阅引导。用户视角全中文,不暴露 CLI 名称。
|
|
11
|
+
|
|
12
|
+
> 钻探前置:v2 顶层(schemaVersion + scenario + menuPath + requiredSystems + requiredRoles + coveredActions + uncoveredCandidates)由 CLI 一次写入。scenario 3 档决策(REQ-SCENE-01):①CLI `--scenario` ②ModuleHints 推断 ③默认 `crud`;scenario 作为**产物**(非输入)写入顶层。
|
|
13
|
+
|
|
14
|
+
## 1. 自然语言映射
|
|
15
|
+
|
|
16
|
+
```text
|
|
17
|
+
/glue-generate-testcase /abs/path/.../014-测试需求10-20260622/code_list.md # 绝对路径
|
|
18
|
+
/glue-generate-testcase ../knowledge-project/.../014-测试需求10-20260622/code_list.md # 相对路径
|
|
19
|
+
/glue-generate-testcase # 无参数 → 问 code_list.md 路径
|
|
20
|
+
/glue-generate-testcase /abs/path/.../014-测试需求10-20260622/code_list.md --debug # 调试模式 → 跑本地 ep-stage-skill dist
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
> **`--debug` flag**:正常调用走远程 `npx @epoint-testtech/ep-stage-skill@latest`。开发期想测试未发布的本地代码时传 `--debug`,skill 在 Step 4 改用 `node <repo>/packages/ep-stage-skill/dist/src/cli/index.js`。前提:cwd 在 ep-stage monorepo 内(向上能找到 `pnpm-workspace.yaml`);找不到时直接 exit 1 报错,不静默 fallback 到 npx。
|
|
24
|
+
|
|
25
|
+
`--hints` 仅保留为 CLI 开发调试覆盖参数,skill 正常路径不得要求用户提供。
|
|
26
|
+
|
|
27
|
+
skill 把 `code_list.md` 入参 `path.resolve` 绝对化,用其父目录 basename 取「需求名」作为 `<projectDir>/src/tests/<需求名>` 子目录。**projectDir 不接受参数**,全部从 `~/.ep-stage/projects.index.json5` 反查最新 `mode: 'glue'` 条目(多条 AskUserQuestion 让用户挑);索引缺失走引导场景 A。
|
|
28
|
+
|
|
29
|
+
## 2. Agent 执行剧本(8 步任务清单协议)
|
|
30
|
+
|
|
31
|
+
**任务清单协议(REQ-UX-01)**:load 后**立即**打印初始任务清单(Step 0);每完成一步输出单行 `✅ 第 N 步 — <中文名> 已完成,进入第 N+1 步 — <下一中文名>...`;Step 8 输出全勾选终态清单 + 摘要。
|
|
32
|
+
|
|
33
|
+
### Step 0 — 打印任务清单
|
|
34
|
+
|
|
35
|
+
```markdown
|
|
36
|
+
📋 **生成胶水测试用例任务清单**
|
|
37
|
+
|
|
38
|
+
- [ ] 第 1 步 — 解析 code_list 路径
|
|
39
|
+
- [ ] 第 2 步 — 反查项目脚手架
|
|
40
|
+
- [ ] 第 3 步 — 校验 code_list.md 输入
|
|
41
|
+
- [ ] 第 4 步 — 调用钻探与用例生成 CLI
|
|
42
|
+
- [ ] 第 5 步 — 与研发人员交互确认推断结果
|
|
43
|
+
- [ ] 第 6 步 — 校验产物完整性 + AI 渲染表格化 testcase.md
|
|
44
|
+
- [ ] 第 7 步 — 写入需求条目到项目索引
|
|
45
|
+
- [ ] 第 8 步 — 输出审阅引导摘要
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Step 1 — 解析 code_list 路径
|
|
49
|
+
|
|
50
|
+
从用户消息 / args 抽取 `code_list.md` 路径,绝对化后得到 `codeListPath`,再用其父目录 basename 作为需求名。中文复述识别结果:"已识别:code_list.md = `<abs>`,需求名 = `<basename>`"。入参缺失 → free text 询问"请给我 code_list.md 的绝对或相对路径"。
|
|
51
|
+
|
|
52
|
+
### Step 2 — 反查项目脚手架(缺 → 引导 A)
|
|
53
|
+
|
|
54
|
+
读 `~/.ep-stage/projects.index.json5`:文件不存在 / 无 glue 条目 → **引导场景 A**:中文提示"未发现胶水测试脚手架。请先跑 `/glue-create-project <项目名>` 创建脚手架后再回来",退出不调 CLI。多条匹配 → AskUserQuestion 挑 projectDir。单条 → 直接拼 `--tests-dir` 根。
|
|
55
|
+
|
|
56
|
+
### Step 3 — 校验 code_list.md 输入(缺 → 引导 D)
|
|
57
|
+
|
|
58
|
+
校验 `codeListPath` 是否存在,且 `code_list.md` 内至少给出:
|
|
59
|
+
- `knowledgeRoot: /abs/path`,或
|
|
60
|
+
- `> 整理目录:\`/abs/path\``
|
|
61
|
+
|
|
62
|
+
其余物料路径默认视为相对该根目录的路径;若某项缺失或不存在,再进入交互补齐。`codeListPath` 本身缺失 → **引导场景 D**,AskUserQuestion 三选一:
|
|
63
|
+
|
|
64
|
+
1. **提供 code_list.md 路径**:让用户给绝对路径,skill 改用该路径继续。
|
|
65
|
+
2. **读 PRD 草稿生成 code_list.md**:在需求目录找 PRD / spec.yaml,AI 推断 `knowledgeRoot` / `menu` / 文件清单写一份 code_list.md 草稿,提示"已生成草稿,请人审后再跑",退出。
|
|
66
|
+
3. **取消**:直接退出,不调 CLI。
|
|
67
|
+
|
|
68
|
+
### Step 4 — 调用钻探与用例生成 CLI
|
|
69
|
+
|
|
70
|
+
固定流程(不 which、不扫 monorepo、不 cd、**不喂 stdin**)。
|
|
71
|
+
|
|
72
|
+
**正常模式**(用户 args 无 `--debug`):
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
npx -y @epoint-testtech/ep-stage-skill@latest testcase \
|
|
76
|
+
--code-list <codeListPath> \
|
|
77
|
+
--tests-dir <projectDir>/src/tests/<需求名> \
|
|
78
|
+
--requirement-dir <codeListPath 的父目录> \
|
|
79
|
+
--project-dir <projectDir> \
|
|
80
|
+
[--scenario <值>]
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**调试模式**(用户 args 含 `--debug`,要求 cwd 在 ep-stage monorepo 内;详见 §1 `--debug` flag 说明):
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
D="$PWD"; REPO=""
|
|
87
|
+
while [ "$D" != "/" ]; do
|
|
88
|
+
if [ -f "$D/pnpm-workspace.yaml" ] && [ -f "$D/packages/ep-stage-skill/dist/src/cli/index.js" ]; then
|
|
89
|
+
REPO="$D"; break
|
|
90
|
+
fi
|
|
91
|
+
D="$(dirname "$D")"
|
|
92
|
+
done
|
|
93
|
+
[ -z "$REPO" ] && { echo "❌ --debug 但找不到本地 monorepo(需 cwd 在 ep-stage 仓库内向上能找到 pnpm-workspace.yaml + packages/ep-stage-skill/dist/src/cli/index.js)"; exit 1; }
|
|
94
|
+
echo "▸ 调试模式:本地 $REPO/packages/ep-stage-skill/dist/src/cli/index.js"
|
|
95
|
+
node "$REPO/packages/ep-stage-skill/dist/src/cli/index.js" testcase \
|
|
96
|
+
--code-list <codeListPath> \
|
|
97
|
+
--tests-dir <projectDir>/src/tests/<需求名> \
|
|
98
|
+
--requirement-dir <codeListPath 的父目录> \
|
|
99
|
+
--project-dir <projectDir> \
|
|
100
|
+
[--scenario <值>]
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
CLI 内部:先按 scenario 3 档决策(①`--scenario` ②ModuleHints ③默认 `crud`),按 scenario 选 extractor → 物料解析 + contract 提取 + coverage 分析 → 装配 testcase v2(最终 scenario 写入 `testcase.json5` 顶层)→ 写 testcase.json5 / testcase.md(i18n 中文)/ credentials.template.json5 / `.ep-stage/contract.json` / `.ep-stage/inference-trace.json` → 软链上游 code_list.md。CLI 非 0 退出 → 复述 stderr,不发完成提示,不进 Step 5。
|
|
104
|
+
|
|
105
|
+
### Step 5 — 与研发人员交互确认推断结果(REQ-UX-02)
|
|
106
|
+
|
|
107
|
+
Step 4 成功后,skill 读 testcase.json5 顶层 `requiredSystems[]` / `requiredRoles[]`,再读 `~/.ep-stage/projects.index.json5` 的 `systems[]` 算 `cachedSystemsHit`(url 命中的列表)。用**平台对话能力**(Claude Code 用 `AskUserQuestion` / Codex 用对应交互机制)跟用户对话:
|
|
108
|
+
|
|
109
|
+
> 推断出 **N 个系统** + **M 个角色**(如 建设单位 / 施工单位 / 监理单位)。请选择:
|
|
110
|
+
> 1. **现在交互输入**(推荐:≤3 角色场景)— 我逐个角色问 URL / 用户名 / 密码 / systemName,**直接写 `credentials.json5`**
|
|
111
|
+
> 2. **仅生成 template,自己后续填** — 退出后请拷贝 `credentials.template.json5` → `credentials.json5` 并填值
|
|
112
|
+
> 3. **跳过,使用全局 systems[] 缓存复用** — 自动从 `cachedSystemsHit` 命中缓存生成 `credentials.json5`(缺失角色 fallback 引导 C,留给 glue-run-test)
|
|
113
|
+
|
|
114
|
+
三分支处理:
|
|
115
|
+
|
|
116
|
+
- **选 1**:skill 顺序问每条角色的 URL/username/password/systemName(free text),直接写 `<需求名>/credentials.json5`(gitignore,非 template),**回写**全局 `~/.ep-stage/projects.index.json5` 的 `systems[].credentialsCache`(按 url 归并,跨需求复用)。
|
|
117
|
+
- **选 2**:保留 template;提示"请编辑 `credentials.json5` 后再跑 `/glue-run-test`",进入 Step 6。
|
|
118
|
+
- **选 3**:从 `systems[].credentialsCache` 拼出 credentials.json5,缺失角色用 template 占位符保留。
|
|
119
|
+
|
|
120
|
+
### Step 6 — 校验产物完整性 + AI 渲染审阅视图 testcase.md
|
|
121
|
+
|
|
122
|
+
**Step 6.1 — 校验产物完整性**
|
|
123
|
+
|
|
124
|
+
按 §3 验证清单 `ls` / `Read` 校验 CLI 产物存在(除 `testcase.md` 外其他全部,缺任意一项视为整体失败,按 §4 报告):
|
|
125
|
+
|
|
126
|
+
- `testcase.json5`、`credentials.template.json5`(或 `credentials.json5`)、`code_list.md` 软链、`.ep-stage/contract.json`、`.ep-stage/inference-trace.json`
|
|
127
|
+
|
|
128
|
+
> 注意:CLI 当前会先产一份 bullet 格式的 `testcase.md`(来自 `renderTestcaseMarkdown`);本 Step 6.2 会**覆盖**它为表格化审阅视图。先校验该 CLI 产物存在即可,不审格式。
|
|
129
|
+
|
|
130
|
+
**Step 6.2 — AI 基于 tpl 渲染表格化 testcase.md(核心人审视图)**
|
|
131
|
+
|
|
132
|
+
1. **读三个数据源(全部 `Read`,绝不修改其内容)**:
|
|
133
|
+
- `<testsDir>/testcase.json5`:事实源 — cases 数量 / `caseId` / `title` / `reviewStatus` / `requiredRole` / 顶层 `schemaVersion` / `scenario` / `moduleId` / `moduleName` / `menuPath` / `requiredRoles` 必须**逐字取自此**。
|
|
134
|
+
- `<testsDir>/.ep-stage/contract.json`:业务槽位 — 步骤/断言/前置条件中的具体标签(菜单 / 列表页 / 按钮文字 / 查询字段 / 删除策略)必须**逐字取自此**对应路径(`contract.pages.list.title` / `contract.flows.create.entryButton.label` 等)。
|
|
135
|
+
- `<testsDir>/credentials.json5`(如不存在则用 `credentials.template.json5`):登录地址 / 账号;密码**不写入** testcase.md。
|
|
136
|
+
|
|
137
|
+
2. **读 tpl**:`packages/ep-stage-skill/codex-skill/ep-stage/glue-generate-testcase/references/testcase-tpl.md`(本 skill 的同级 `references/testcase-tpl.md`,按 frontmatter + 环境信息 section + 5 列 CRUD 表格 + 审阅引导组装;模板内 `<!-- ... -->` 注释含详细填充规则,AI 必须读完后再渲染)。
|
|
138
|
+
|
|
139
|
+
3. **按 tpl 填充,写盘到 `<testsDir>/testcase.md`(覆盖 CLI 那份 bullet 版本)**:
|
|
140
|
+
- frontmatter 4 字段(schemaVersion / scenario / moduleId / contractVersion)逐字取数据源
|
|
141
|
+
- 「环境信息」section:登录地址/账号从 credentials;菜单/列表页/查询字段/操作角色/未解析槽位从 testcase.json5 + contract.json
|
|
142
|
+
- 「CRUD 冒烟用例」表格:cases[] **一条 = 一行**(数量必须严格等于 `testcase.json5.cases.length`,不得增删),按 caseId 后缀(.create / .read / .update / .delete)走 tpl 内注释列出的步骤/断言/前置条件填充规则;非 CRUD 用例按 cases[].businessIntent / assertionExpectation 直译,缺时填「待人工补充」、不发挥
|
|
143
|
+
- 表格中**不展示 evidence 列**(人审不需要技术性溯源)
|
|
144
|
+
- 「审阅引导」section:原样复制 tpl 末尾的 3 条引导(替换其中引用的具体路径)
|
|
145
|
+
|
|
146
|
+
4. **AI 忠实性自检(写盘前必做)**:
|
|
147
|
+
- testcase.md 表格行数 - 1 (表头) == testcase.json5 cases.length
|
|
148
|
+
- 每行 `用例 ID` 列 == testcase.json5 cases[i].caseId
|
|
149
|
+
- 每行 `标题` 列 == testcase.json5 cases[i].title
|
|
150
|
+
- 步骤/断言/前置条件中所有「{contract.xxx}」型槽位标签真实存在于 contract.json(grep 验证)
|
|
151
|
+
- **任一项不通过**:不写盘,按 §4 报告「忠实性自检失败」+ 具体差异 + 停 Step 6.2,不进 Step 7
|
|
152
|
+
|
|
153
|
+
5. **重跑覆盖语义**:每次跑 skill 都重新执行 Step 6.2,testcase.md 完全覆盖前一次产物;人审意见**只写进 testcase.json5**(JSON5 `// 注释`),**不写 testcase.md**。
|
|
154
|
+
|
|
155
|
+
**Step 6.3 — 复核环境信息可执行性(可选)**
|
|
156
|
+
|
|
157
|
+
如 Step 5 已交互写入 credentials.json5:环境信息 section 的「登录地址」应是真实 URL(非占位 `<请填登录页 URL>`)。占位状态下完成提示中提醒用户补 credentials.json5 后再跑 `/glue-run-test`。
|
|
158
|
+
|
|
159
|
+
### Step 7 — 写入需求条目到项目索引
|
|
160
|
+
|
|
161
|
+
CLI testcase 子命令在传入 `--project-dir` 时,自动往 `~/.ep-stage/projects.index.json5` 对应 `projects[].requirements[]` 追加本需求条目(含 `name / requirementDir / testsDir / lastRunStatus: "never"`,同名需求去重更新);未传 `--project-dir` 则跳过(不维护 index)。skill Step 4 命令总带 `--project-dir`,故正常流程 CLI 必追加。skill 校验:条目存在;`name` 与 Step 1 一致;`testsDir` 指向 `<projectDir>/src/tests/<需求名>`。
|
|
162
|
+
|
|
163
|
+
### Step 8 — 输出审阅引导摘要
|
|
164
|
+
|
|
165
|
+
打印全勾选终态清单 + §5 完成提示(含审阅引导链:审 testcase.md → 编辑 testcase.json5 → 填 credentials.json5 → 跑 `/glue-run-test`)。
|
|
166
|
+
|
|
167
|
+
## 3. 验证清单
|
|
168
|
+
|
|
169
|
+
| 路径 | 说明 |
|
|
170
|
+
|--------------------------------------------------------------|--------------------------------------------------------|
|
|
171
|
+
| `<projectDir>/src/tests/<需求名>/testcase.json5` | v2 schema(含 scenario / menuPath / requiredSystems 等),**事实源** |
|
|
172
|
+
| `<projectDir>/src/tests/<需求名>/testcase.md` | **AI 基于 `references/testcase-tpl.md` 渲染的审阅视图**(5 列表格 + 环境信息 + 审阅引导,重跑覆盖;CLI 先产 bullet 版,Step 6.2 覆盖之) |
|
|
173
|
+
| `<projectDir>/src/tests/<需求名>/credentials.template.json5` | 行数 = `requiredRoles.length` |
|
|
174
|
+
| `<projectDir>/src/tests/<需求名>/code_list.md` | 软链 / hardlink / copy 到上游 |
|
|
175
|
+
| `<projectDir>/src/tests/<需求名>/.ep-stage/contract.json` | 内部产物,机器专用,禁手编 |
|
|
176
|
+
| `<projectDir>/src/tests/<需求名>/.ep-stage/inference-trace.json` | 推理追踪总账,只供排查和审阅,不作为 spec 主输入 |
|
|
177
|
+
| `~/.ep-stage/projects.index.json5` | 已追加 `projects[].requirements[]` |
|
|
178
|
+
|
|
179
|
+
> 常态不生成 `source-spec.json` 或 `module-hints.inferred.json5`;二者只作为显式调试导出,非正常产物。
|
|
180
|
+
|
|
181
|
+
## 4. 错误处理
|
|
182
|
+
|
|
183
|
+
| 触发时机 | Agent 中文呈现 + 建议 |
|
|
184
|
+
|-----------------------------------------|----------------------------------------------------------------------|
|
|
185
|
+
| 引导 A(缺脚手架) | 中文提示+退出,引导先跑 `/glue-create-project` |
|
|
186
|
+
| 引导 D(缺 code_list.md) | AskUserQuestion 三选一:建软链 / 读 PRD 草稿 / 取消 |
|
|
187
|
+
| CLI exit ≠ 0 | 复述 stderr 中文转述,不发完成提示,不进 Step 5 |
|
|
188
|
+
| testcase.json5 缺 `schemaVersion: "v2"` | 报"产物 schema 校验失败,请重跑 `/glue-generate-testcase <code_list.md路径>`" |
|
|
189
|
+
| Step 5 选 1 用户中途取消 | 保留 template,提示"凭据未写入,请稍后拷贝 template 自填" |
|
|
190
|
+
| Step 6.2 忠实性自检失败 | 不写 testcase.md,复述差异(行数不匹配 / caseId 错位 / 槽位标签 contract 中不存在),引导审阅 testcase.json5 与 contract.json 后重跑 |
|
|
191
|
+
|
|
192
|
+
## 5. 完成提示
|
|
193
|
+
|
|
194
|
+
Step 8 全部通过后,按以下中文格式呈现(不要用 success/done/generated):
|
|
195
|
+
|
|
196
|
+
> ✅ 用例生成完成
|
|
197
|
+
>
|
|
198
|
+
> 需求:`<需求名>`
|
|
199
|
+
> 项目:`<projectDir>`
|
|
200
|
+
> 产物目录:`<projectDir>/src/tests/<需求名>/`(testcase.json5 v2 + testcase.md + credentials.template.json5 + credentials.json5(如选 1/3)+ code_list.md 软链 + .ep-stage/contract.json + .ep-stage/inference-trace.json)
|
|
201
|
+
> 项目索引:`~/.ep-stage/projects.index.json5` 已追加需求条目
|
|
202
|
+
>
|
|
203
|
+
> 下一步审阅引导链:
|
|
204
|
+
> 1. 打开 `testcase.md` 审阅推断结果与未确认项
|
|
205
|
+
> 2. 如需调整,编辑 `testcase.json5`(JSON5 支持 `// 注释`,审阅意见可直接写注释)
|
|
206
|
+
> 3. 检查 / 填好 `credentials.json5`(如未在 Step 5 选 1/3 写入)
|
|
207
|
+
> 4. 跑 `/glue-run-test <需求目录路径>` 组装并执行 spec
|
|
208
|
+
|
|
209
|
+
## 6. 引导场景
|
|
210
|
+
|
|
211
|
+
- **A(缺脚手架)**:Step 2 反查 projects.index.json5 无 glue 条目 → 提示先跑 `/glue-create-project` 退出。
|
|
212
|
+
- **D(缺 code_list.md)**:Step 3 缺失 → AskUserQuestion 三选一(建软链 / 读 PRD 草稿 / 取消)。
|
|
213
|
+
- **B / C**:由下游 `glue-run-test` 处理。
|
|
214
|
+
|
|
215
|
+
## 7. 输入字段约定
|
|
216
|
+
|
|
217
|
+
```markdown
|
|
218
|
+
<!-- code_list.md 字段约定(REQ-FILE-02 / REQ-MENU-01) -->
|
|
219
|
+
knowledgeRoot: /abs/path/to/knowledge-project/xxx <!-- 推荐:结构化根目录 -->
|
|
220
|
+
|
|
221
|
+
> 整理目录:`/abs/path/to/knowledge-project/xxx` <!-- 兼容旧格式;其余相对路径默认相对该目录 -->
|
|
222
|
+
> 菜单:一级菜单>二级菜单 <!-- 人工读写首选:中文键「菜单」,与「整理目录」同风格;可选,缺时引导补,最终写入 testcase.json5.menuPath -->
|
|
223
|
+
menu: 一级菜单>二级菜单 <!-- 英文键兼容:裸行 menu / menuPath 仍可解析(blockquote「>」形式仅认「菜单」)。CLI 内部字段名仍为 menu -->
|
|
224
|
+
|
|
225
|
+
`_docs/.../spec.yaml`
|
|
226
|
+
`src/main/webapp/.../*.html`
|
|
227
|
+
`src/main/java/.../*Action.java`
|
|
228
|
+
|
|
229
|
+
<!-- module-hints 是 CLI 基于上游物料推理的过程产物(落入 .ep-stage/inference-trace.json),
|
|
230
|
+
不是 code_list 该列的输入物料;旧 examples/zwplace.module-hints.json 仅作历史 fixture(REQ-INFER-010)。 -->
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## 8. 内嵌数据契约范例
|
|
234
|
+
|
|
235
|
+
`<需求名>/testcase.json5` v2 顶层骨架(详见 references/testcase-schema.md):
|
|
236
|
+
|
|
237
|
+
```json5
|
|
238
|
+
{
|
|
239
|
+
schemaVersion: "v2",
|
|
240
|
+
scenario: "crud", // 产物:CLI 3 档决策后写入
|
|
241
|
+
moduleId: "zwplace", moduleName: "场所窗口信息管理",
|
|
242
|
+
menuPath: "场所窗口信息管理>场所窗口信息列表",
|
|
243
|
+
requiredSystems: [{ url: "http://...", systemName: "主业务系统" }],
|
|
244
|
+
requiredRoles: [{ role: "admin", hint: "默认操作员" }],
|
|
245
|
+
coveredActions: [{ actionId: "zwplace.create", kind: "create", evidence: ["html=...", "java=..."] }],
|
|
246
|
+
uncoveredCandidates: [{ actionId: "zwplace.sync", status: "planned", requiredRole: "admin", businessIntent: "...", assertionExpectation: "...", evidence: ["..."] }],
|
|
247
|
+
cases: [{ caseId: "zwplace.create", title: "新增", scenario: "crud.single-page", reviewStatus: "confirmed", requiredRole: "admin", evidence: ["..."], steps: [], assertions: [], unresolved: [] }],
|
|
248
|
+
reasoningSummary: { conclusion: "...", evidenceChain: [], alternatives: [], confidence: "high", risks: [], needsHumanReview: false }
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
`<需求名>/credentials.template.json5`(行数 = `requiredRoles.length`) + `~/.ep-stage/projects.index.json5` 需求条目(CLI 追加到 `projects[].requirements[]`):
|
|
253
|
+
|
|
254
|
+
```json5
|
|
255
|
+
// credentials.template.json5
|
|
256
|
+
[ { url: "<请填登录页 URL>", username: "<请填>", password: "<请填>", role: "admin", systemName: "主业务系统" } ]
|
|
257
|
+
|
|
258
|
+
// projects.index.json5 → projects[].requirements[<i>]
|
|
259
|
+
{ name: "014-测试需求10-20260622", requirementDir: "/abs/.../014-测试需求10-20260622", testsDir: "<projectDir>/src/tests/014-测试需求10-20260622", lastRunStatus: "never" }
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
## 9. 按需加载
|
|
263
|
+
|
|
264
|
+
- 用例 schema 详解:`references/testcase-schema.md`(v2)
|
|
265
|
+
- **testcase.md 渲染模板:`references/testcase-tpl.md`(Step 6.2 必读)**
|
|
266
|
+
- 既有工作流参考:`references/workflow.md`
|
|
267
|
+
|
|
268
|
+
## 10. 关键约束
|
|
269
|
+
|
|
270
|
+
- 顶层 `reviewStatus` 字段**永远不引入**(REQ-DATA-04);审阅意见请直接在 `testcase.json5` 加 JSON5 `// 注释`。
|
|
271
|
+
- `cases[].reviewStatus = needs_review` 的用例不得进入 spec 组装(spec 组装阶段按 case 粒度阻断)。
|
|
272
|
+
- 嵌套 CRUD 一期仅作为候选用例进入 testcase,不写入正式 CRUD 契约。
|
|
273
|
+
- testcase.md 每次重跑完全覆盖,不保留人工编辑(事实源是 testcase.json5)。**testcase.md 由 skill Step 6.2 基于 `references/testcase-tpl.md` AI 渲染**(CLI 当前先产一份 bullet 版作为兜底,Step 6.2 覆盖之);步骤/断言/前置条件中的具体槽位标签必须逐字取自 contract.json,AI 只组织自然语言句式,不得新增/捏造槽位。
|
|
274
|
+
- 对话中展示可审阅推理摘要和证据链,不展示原始隐式思维链。
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# glue-testcase schema (v2)
|
|
2
|
+
|
|
3
|
+
`testcase.json5` 顶层 schema:
|
|
4
|
+
|
|
5
|
+
```json5
|
|
6
|
+
{
|
|
7
|
+
schemaVersion: "v2",
|
|
8
|
+
scenario: "crud", // ★ v2 新增(REQ-SCENE-01):场景类型。**由 testcase 子命令运行时决定后写入此字段**(产物,非输入)。决策优先级:①--scenario CLI 参数 ②ModuleHints 推断 ③默认 "crud"
|
|
9
|
+
moduleId: "zwplace",
|
|
10
|
+
moduleName: "场所窗口信息管理",
|
|
11
|
+
menuPath: "场所窗口信息管理>场所窗口信息列表", // ★ v2 新增(REQ-MENU-01):从 code_list.md 搬到 testcase 扎口
|
|
12
|
+
|
|
13
|
+
// ★ v2 新增:上游推断的需求系统/角色集
|
|
14
|
+
requiredSystems: [
|
|
15
|
+
{ url: "http://192.168.x.x:8100/.../login", systemName: "主业务系统" }
|
|
16
|
+
],
|
|
17
|
+
requiredRoles: [
|
|
18
|
+
{ role: "admin", hint: "默认操作员" }
|
|
19
|
+
],
|
|
20
|
+
|
|
21
|
+
// ★ v2 新增:骨架命中清单(run 阶段直接组装)
|
|
22
|
+
// evidence 格式约定:<kind>=<ref>,kind ∈ {html, java, spec, contract, skeleton, hint}
|
|
23
|
+
coveredActions: [
|
|
24
|
+
{
|
|
25
|
+
actionId: "zwplace.create",
|
|
26
|
+
kind: "create",
|
|
27
|
+
evidence: [
|
|
28
|
+
"html=src/main/webapp/.../gxhzwplaceadd.html",
|
|
29
|
+
"java=src/main/java/.../ZwplaceAction.java"
|
|
30
|
+
]
|
|
31
|
+
},
|
|
32
|
+
{ actionId: "zwplace.read", kind: "read", evidence: ["html=src/main/webapp/.../gxhzwplacelist.html", "java=..."] },
|
|
33
|
+
{ actionId: "zwplace.update", kind: "update", evidence: ["html=...", "java=..."] },
|
|
34
|
+
{ actionId: "zwplace.delete", kind: "delete", evidence: ["html=...", "java=..."] }
|
|
35
|
+
],
|
|
36
|
+
|
|
37
|
+
// ★ v2 新增:骨架未命中候选(run 阶段 AI 推理)
|
|
38
|
+
uncoveredCandidates: [
|
|
39
|
+
{
|
|
40
|
+
actionId: "zwplace.sync",
|
|
41
|
+
label: "同步窗口管理系统",
|
|
42
|
+
status: "planned", // planned | candidate | unresolved | resolved
|
|
43
|
+
requiredRole: "admin", // ★ v2 新增:AI 推理时知道用哪个角色操作
|
|
44
|
+
businessIntent: "同步窗口数据",
|
|
45
|
+
assertionExpectation: "同步完成提示",
|
|
46
|
+
evidence: ["html=...", "hint=ModuleHints.customWorkflows.zwplace.sync"]
|
|
47
|
+
}
|
|
48
|
+
],
|
|
49
|
+
|
|
50
|
+
// 既有 v1 字段(cases 内部行为不变)
|
|
51
|
+
cases: [
|
|
52
|
+
{
|
|
53
|
+
caseId: "zwplace.create",
|
|
54
|
+
title: "新增场所窗口信息管理",
|
|
55
|
+
scenario: "crud.single-page",
|
|
56
|
+
reviewStatus: "confirmed", // v1 字段保留:confirmed | needs_review | blocked
|
|
57
|
+
requiredRole: "admin", // ★ v2 新增:该用例由哪个角色操作
|
|
58
|
+
evidence: ["skeleton=crud.skeleton-testcase/v1", "contract=crud-business-module/v1"],
|
|
59
|
+
steps: ["进入菜单", "点击新增", "填写并保存测试数据"],
|
|
60
|
+
assertions: ["新增后可查询到记录"],
|
|
61
|
+
unresolved: []
|
|
62
|
+
}
|
|
63
|
+
],
|
|
64
|
+
|
|
65
|
+
reasoningSummary: {
|
|
66
|
+
conclusion: "生成 4 条 CRUD 胶水测试用例。",
|
|
67
|
+
evidenceChain: [],
|
|
68
|
+
alternatives: ["crud.single-page"],
|
|
69
|
+
confidence: "high",
|
|
70
|
+
risks: [],
|
|
71
|
+
needsHumanReview: false
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## v1 → v2 升级点
|
|
77
|
+
|
|
78
|
+
- 顶层新增 `schemaVersion: "v2"`
|
|
79
|
+
- 顶层新增 `scenario`(REQ-SCENE-01)
|
|
80
|
+
- 顶层新增 `menuPath`(REQ-MENU-01 修订)
|
|
81
|
+
- 顶层新增 `requiredSystems[]` / `requiredRoles[]`
|
|
82
|
+
- 顶层新增 `coveredActions[]` / `uncoveredCandidates[]`(钻探产物前移)
|
|
83
|
+
- `cases[]` 新增 `requiredRole`
|
|
84
|
+
- `uncoveredCandidates[]` 新增 `requiredRole`
|
|
85
|
+
- `evidence` 字段格式约定 `<kind>=<ref>`
|
|
86
|
+
- **顶层不引入** `reviewStatus`(REQ-DATA-04);仅 `cases[].reviewStatus` 保留
|
|
87
|
+
|
|
88
|
+
## 字段说明(v2 新增字段)
|
|
89
|
+
|
|
90
|
+
- `schemaVersion`:必为字符串 `"v2"`。Task 1.1 `validateTestcase` 强制校验;其他值或缺失会拒绝并提示重跑 `glue-generate-testcase`。
|
|
91
|
+
- `scenario`:场景类型(**产物**,非输入)。由 testcase 子命令运行时按 3 档优先级决定:① CLI `--scenario` 显式参数 → ② 从 `ModuleHints` 推断 → ③ 默认 `"crud"`。本轮仅支持 `"crud"`;未来 `"statistic"` / `"approval"` 等场景扩展时不增加新 CLI 命令,仅扩展 testcase 内部分发(REQ-SCENE-01)。
|
|
92
|
+
- `menuPath`:菜单路径,从 `code_list.md` 搬到 testcase 扎口(REQ-MENU-01 修订)。glue-run-test 的 spec 子命令从此读取,不再从 code_list 二次解析。
|
|
93
|
+
- `requiredSystems[]`:上游钻探推断的需求涉及的系统集,每项 `{ url, systemName? }`。驱动 `credentials.template.json5` 生成 + 引导用户在 glue-generate-testcase 第 5 步交互确认(REQ-UX-02)。
|
|
94
|
+
- `requiredRoles[]`:上游钻探推断的需求涉及的角色集,每项 `{ role, hint? }`。同上驱动 template + 确认。
|
|
95
|
+
- `coveredActions[]`:骨架命中清单。run 阶段直接组装胶水部分 spec,按 `evidence` 引用源码与契约。
|
|
96
|
+
- `uncoveredCandidates[]`:骨架未命中候选;`status` 取 `planned`(可进 AI 推理)/ `candidate`(不得进 spec,要求补 hints)/ `unresolved`(缺证据)/ `resolved`(已通过推理)。
|
|
97
|
+
- `uncoveredCandidates[].requiredRole`:AI 推理时该动作由哪个角色操作(多角色场景必需)。
|
|
98
|
+
- `cases[].requiredRole`:该用例由哪个角色操作。spec 子命令据此映射 credentials.json5 + cases 登录切换。
|
|
99
|
+
- `evidence`:字符串数组,每项格式 `<kind>=<ref>`。`kind` ∈ `{html, java, spec, contract, skeleton, hint}`。
|
|
100
|
+
|
|
101
|
+
## 既有 v1 字段说明(保留语义)
|
|
102
|
+
|
|
103
|
+
- `cases[].reviewStatus`:`confirmed` / `needs_review` / `blocked`。`needs_review` 的用例不得进入 spec assembly(run 阶段按 case 粒度阻断)。
|
|
104
|
+
- `caseId`:spec assembly 需要与生成脚本工作流粒度一致。CRUD 用例固定为 `<moduleId>.create` / `.read` / `.update` / `.delete`。
|
|
105
|
+
- `unresolved`:未确认项(如嵌套 CRUD 子表保存后断言)。必须落盘,不能只在对话解释。
|
|
106
|
+
- `reasoningSummary`:与 `.stage/trace/<run-id>/testcase-generation.json` 同构。
|
|
107
|
+
|
|
108
|
+
## Schema 演化策略
|
|
109
|
+
|
|
110
|
+
- 破坏性升级走 major 版本号(如 v2 → v3)
|
|
111
|
+
- CLI 读取时校验 `schemaVersion`:不匹配抛结构化错误(含期望版本 + 修复建议「重跑 `glue-generate-testcase <需求路径>`」)
|
|
112
|
+
- 顶层 `reviewStatus` 字段**永远不引入**(REQ-DATA-04);审阅意见请直接在 `testcase.json5` 加 JSON5 `// 注释`
|