@guanlin4924/devflow-pi 0.1.94 → 0.1.96

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 (245) hide show
  1. package/README.md +34 -4
  2. package/node_modules/@playwright/test/LICENSE +202 -0
  3. package/node_modules/@playwright/test/NOTICE +5 -0
  4. package/node_modules/@playwright/test/README.md +318 -0
  5. package/node_modules/@playwright/test/cli.js +19 -0
  6. package/node_modules/@playwright/test/index.d.ts +18 -0
  7. package/node_modules/@playwright/test/index.js +17 -0
  8. package/node_modules/@playwright/test/index.mjs +18 -0
  9. package/node_modules/@playwright/test/package.json +35 -0
  10. package/node_modules/@playwright/test/reporter.d.ts +17 -0
  11. package/node_modules/@playwright/test/reporter.js +17 -0
  12. package/node_modules/@playwright/test/reporter.mjs +17 -0
  13. package/node_modules/playwright/LICENSE +202 -0
  14. package/node_modules/playwright/NOTICE +5 -0
  15. package/node_modules/playwright/README.md +318 -0
  16. package/node_modules/playwright/ThirdPartyNotices.txt +14 -0
  17. package/node_modules/playwright/cli.js +19 -0
  18. package/node_modules/playwright/index.d.ts +17 -0
  19. package/node_modules/playwright/index.js +17 -0
  20. package/node_modules/playwright/index.mjs +18 -0
  21. package/node_modules/playwright/jsx-runtime.js +42 -0
  22. package/node_modules/playwright/jsx-runtime.mjs +21 -0
  23. package/node_modules/playwright/lib/agents/agentParser.js +89 -0
  24. package/node_modules/playwright/lib/agents/copilot-setup-steps.yml +34 -0
  25. package/node_modules/playwright/lib/agents/generateAgents.js +395 -0
  26. package/node_modules/playwright/lib/agents/playwright-test-coverage.prompt.md +31 -0
  27. package/node_modules/playwright/lib/agents/playwright-test-generate.prompt.md +8 -0
  28. package/node_modules/playwright/lib/agents/playwright-test-generator.agent.md +88 -0
  29. package/node_modules/playwright/lib/agents/playwright-test-heal.prompt.md +6 -0
  30. package/node_modules/playwright/lib/agents/playwright-test-healer.agent.md +56 -0
  31. package/node_modules/playwright/lib/agents/playwright-test-plan.prompt.md +9 -0
  32. package/node_modules/playwright/lib/agents/playwright-test-planner.agent.md +74 -0
  33. package/node_modules/playwright/lib/cli/reportActions.js +78 -0
  34. package/node_modules/playwright/lib/cli/testActions.js +214 -0
  35. package/node_modules/playwright/lib/common/index.js +2923 -0
  36. package/node_modules/playwright/lib/common/index.js.txt +34 -0
  37. package/node_modules/playwright/lib/errorContext.js +129 -0
  38. package/node_modules/playwright/lib/globals.js +58 -0
  39. package/node_modules/playwright/lib/index.js +815 -0
  40. package/node_modules/playwright/lib/isomorphic.js +260 -0
  41. package/node_modules/playwright/lib/isomorphic.js.txt +9 -0
  42. package/node_modules/playwright/lib/loader/loaderProcessEntry.js +34 -0
  43. package/node_modules/playwright/lib/loader/loaderProcessEntry.js.txt +9 -0
  44. package/node_modules/playwright/lib/matchers/expect.js +13490 -0
  45. package/node_modules/playwright/lib/matchers/expect.js.LICENSE +640 -0
  46. package/node_modules/playwright/lib/matchers/expect.js.txt +67 -0
  47. package/node_modules/playwright/lib/mcp/test/browserBackend.js +135 -0
  48. package/node_modules/playwright/lib/mcp/test/generatorTools.js +122 -0
  49. package/node_modules/playwright/lib/mcp/test/plannerTools.js +150 -0
  50. package/node_modules/playwright/lib/mcp/test/seed.js +82 -0
  51. package/node_modules/playwright/lib/mcp/test/streams.js +44 -0
  52. package/node_modules/playwright/lib/mcp/test/testBackend.js +99 -0
  53. package/node_modules/playwright/lib/mcp/test/testContext.js +306 -0
  54. package/node_modules/playwright/lib/mcp/test/testTool.js +30 -0
  55. package/node_modules/playwright/lib/mcp/test/testTools.js +98 -0
  56. package/node_modules/playwright/lib/package.js +47 -0
  57. package/node_modules/playwright/lib/program.js +241 -0
  58. package/node_modules/playwright/lib/runner/index.js +8527 -0
  59. package/node_modules/playwright/lib/runner/index.js.txt +61 -0
  60. package/node_modules/playwright/lib/transform/babelBundle.js +72274 -0
  61. package/node_modules/playwright/lib/transform/babelBundle.js.LICENSE +2384 -0
  62. package/node_modules/playwright/lib/transform/babelBundle.js.txt +325 -0
  63. package/node_modules/playwright/lib/transform/esmLoader.js +8054 -0
  64. package/node_modules/playwright/lib/transform/esmLoader.js.LICENSE +355 -0
  65. package/node_modules/playwright/lib/transform/esmLoader.js.txt +60 -0
  66. package/node_modules/playwright/lib/util.js +373 -0
  67. package/node_modules/playwright/lib/worker/workerProcessEntry.js +1861 -0
  68. package/node_modules/playwright/lib/worker/workerProcessEntry.js.txt +19 -0
  69. package/node_modules/playwright/package.json +55 -0
  70. package/node_modules/playwright/test.d.ts +18 -0
  71. package/node_modules/playwright/test.js +24 -0
  72. package/node_modules/playwright/test.mjs +35 -0
  73. package/node_modules/playwright/types/test.d.ts +11074 -0
  74. package/node_modules/playwright/types/testReporter.d.ts +950 -0
  75. package/node_modules/playwright-core/LICENSE +202 -0
  76. package/node_modules/playwright-core/NOTICE +5 -0
  77. package/node_modules/playwright-core/README.md +3 -0
  78. package/node_modules/playwright-core/ThirdPartyNotices.txt +13 -0
  79. package/node_modules/playwright-core/bin/install_media_pack.ps1 +5 -0
  80. package/node_modules/playwright-core/bin/install_webkit_wsl.ps1 +33 -0
  81. package/node_modules/playwright-core/bin/reinstall_chrome_beta_linux.sh +42 -0
  82. package/node_modules/playwright-core/bin/reinstall_chrome_beta_mac.sh +13 -0
  83. package/node_modules/playwright-core/bin/reinstall_chrome_beta_win.ps1 +24 -0
  84. package/node_modules/playwright-core/bin/reinstall_chrome_stable_linux.sh +42 -0
  85. package/node_modules/playwright-core/bin/reinstall_chrome_stable_mac.sh +12 -0
  86. package/node_modules/playwright-core/bin/reinstall_chrome_stable_win.ps1 +24 -0
  87. package/node_modules/playwright-core/bin/reinstall_msedge_beta_linux.sh +48 -0
  88. package/node_modules/playwright-core/bin/reinstall_msedge_beta_mac.sh +11 -0
  89. package/node_modules/playwright-core/bin/reinstall_msedge_beta_win.ps1 +23 -0
  90. package/node_modules/playwright-core/bin/reinstall_msedge_dev_linux.sh +48 -0
  91. package/node_modules/playwright-core/bin/reinstall_msedge_dev_mac.sh +11 -0
  92. package/node_modules/playwright-core/bin/reinstall_msedge_dev_win.ps1 +23 -0
  93. package/node_modules/playwright-core/bin/reinstall_msedge_stable_linux.sh +48 -0
  94. package/node_modules/playwright-core/bin/reinstall_msedge_stable_mac.sh +11 -0
  95. package/node_modules/playwright-core/bin/reinstall_msedge_stable_win.ps1 +24 -0
  96. package/node_modules/playwright-core/browsers.json +52 -0
  97. package/node_modules/playwright-core/cli.js +21 -0
  98. package/node_modules/playwright-core/index.d.ts +17 -0
  99. package/node_modules/playwright-core/index.js +17 -0
  100. package/node_modules/playwright-core/index.mjs +28 -0
  101. package/node_modules/playwright-core/lib/bootstrap.js +88 -0
  102. package/node_modules/playwright-core/lib/coreBundle.js +75813 -0
  103. package/node_modules/playwright-core/lib/entry/cliDaemon.js +5 -0
  104. package/node_modules/playwright-core/lib/entry/dashboardApp.js +3 -0
  105. package/node_modules/playwright-core/lib/entry/mcp.js +10 -0
  106. package/node_modules/playwright-core/lib/entry/oopBrowserDownload.js +3 -0
  107. package/node_modules/playwright-core/lib/package.js +50 -0
  108. package/node_modules/playwright-core/lib/server/chromium/appIcon.png +0 -0
  109. package/node_modules/playwright-core/lib/server/electron/loader.js +116 -0
  110. package/node_modules/playwright-core/lib/serverRegistry.js +1939 -0
  111. package/node_modules/playwright-core/lib/serverRegistry.js.LICENSE +65 -0
  112. package/node_modules/playwright-core/lib/tools/cli-client/channelSessions.js +141 -0
  113. package/node_modules/playwright-core/lib/tools/cli-client/cli.js +6 -0
  114. package/node_modules/playwright-core/lib/tools/cli-client/help.json +721 -0
  115. package/node_modules/playwright-core/lib/tools/cli-client/minimist.js +128 -0
  116. package/node_modules/playwright-core/lib/tools/cli-client/output.js +351 -0
  117. package/node_modules/playwright-core/lib/tools/cli-client/program.js +418 -0
  118. package/node_modules/playwright-core/lib/tools/cli-client/registry.js +180 -0
  119. package/node_modules/playwright-core/lib/tools/cli-client/session.js +259 -0
  120. package/node_modules/playwright-core/lib/tools/dashboard/appIcon.png +0 -0
  121. package/node_modules/playwright-core/lib/tools/skills/playwright-cli/SKILL.md +425 -0
  122. package/node_modules/playwright-core/lib/tools/skills/playwright-cli/references/element-attributes.md +23 -0
  123. package/node_modules/playwright-core/lib/tools/skills/playwright-cli/references/playwright-tests.md +39 -0
  124. package/node_modules/playwright-core/lib/tools/skills/playwright-cli/references/request-mocking.md +87 -0
  125. package/node_modules/playwright-core/lib/tools/skills/playwright-cli/references/running-code.md +241 -0
  126. package/node_modules/playwright-core/lib/tools/skills/playwright-cli/references/session-management.md +225 -0
  127. package/node_modules/playwright-core/lib/tools/skills/playwright-cli/references/storage-state.md +275 -0
  128. package/node_modules/playwright-core/lib/tools/skills/playwright-cli/references/test-generation.md +433 -0
  129. package/node_modules/playwright-core/lib/tools/skills/playwright-cli/references/tracing.md +139 -0
  130. package/node_modules/playwright-core/lib/tools/skills/playwright-cli/references/video-recording.md +143 -0
  131. package/node_modules/playwright-core/lib/tools/skills/playwright-component-testing/SKILL.md +136 -0
  132. package/node_modules/playwright-core/lib/tools/skills/playwright-component-testing/references/gallery-spec.md +144 -0
  133. package/node_modules/playwright-core/lib/tools/skills/playwright-component-testing/references/migration.md +89 -0
  134. package/node_modules/playwright-core/lib/tools/skills/playwright-component-testing/references/react.md +69 -0
  135. package/node_modules/playwright-core/lib/tools/skills/playwright-component-testing/references/typing.md +173 -0
  136. package/node_modules/playwright-core/lib/tools/skills/playwright-component-testing/references/vue.md +77 -0
  137. package/node_modules/playwright-core/lib/tools/skills/playwright-trace/SKILL.md +174 -0
  138. package/node_modules/playwright-core/lib/tools/utils/extension.js +112 -0
  139. package/node_modules/playwright-core/lib/tools/utils/socketConnection.js +108 -0
  140. package/node_modules/playwright-core/lib/utilsBundle.js +85357 -0
  141. package/node_modules/playwright-core/lib/utilsBundle.js.LICENSE +1890 -0
  142. package/node_modules/playwright-core/lib/vite/dashboard/assets/codeMirrorModule--QdMvsKi.css +1 -0
  143. package/node_modules/playwright-core/lib/vite/dashboard/assets/codeMirrorModule-CQ8RZGBm.js +32 -0
  144. package/node_modules/playwright-core/lib/vite/dashboard/assets/codicon-DCmgc-ay.ttf +0 -0
  145. package/node_modules/playwright-core/lib/vite/dashboard/assets/firefox-1bWoP6pv.svg +1 -0
  146. package/node_modules/playwright-core/lib/vite/dashboard/assets/firefox-beta-k3eOH_eK.svg +1 -0
  147. package/node_modules/playwright-core/lib/vite/dashboard/assets/firefox-nightly-Cp5nfeDT.svg +1 -0
  148. package/node_modules/playwright-core/lib/vite/dashboard/assets/index-AwgwcYie.css +1 -0
  149. package/node_modules/playwright-core/lib/vite/dashboard/assets/index-hRvO4yU2.js +12 -0
  150. package/node_modules/playwright-core/lib/vite/dashboard/assets/safari-na3_-uQk.svg +1 -0
  151. package/node_modules/playwright-core/lib/vite/dashboard/index.html +29 -0
  152. package/node_modules/playwright-core/lib/vite/dashboard/playwright-logo.svg +24 -0
  153. package/node_modules/playwright-core/lib/vite/htmlReport/index.html +16 -0
  154. package/node_modules/playwright-core/lib/vite/htmlReport/report.css +2 -0
  155. package/node_modules/playwright-core/lib/vite/htmlReport/report.js +32 -0
  156. package/node_modules/playwright-core/lib/vite/recorder/assets/codeMirrorModule--QdMvsKi.css +1 -0
  157. package/node_modules/playwright-core/lib/vite/recorder/assets/codeMirrorModule-CVQWJZAA.js +32 -0
  158. package/node_modules/playwright-core/lib/vite/recorder/assets/codicon-DCmgc-ay.ttf +0 -0
  159. package/node_modules/playwright-core/lib/vite/recorder/assets/index-BZpYJZ-P.css +1 -0
  160. package/node_modules/playwright-core/lib/vite/recorder/assets/index-hrlLqLtq.js +129 -0
  161. package/node_modules/playwright-core/lib/vite/recorder/index.html +29 -0
  162. package/node_modules/playwright-core/lib/vite/recorder/playwright-logo.svg +9 -0
  163. package/node_modules/playwright-core/lib/vite/traceViewer/assets/codeMirrorModule-BbkfBe3n.js +32 -0
  164. package/node_modules/playwright-core/lib/vite/traceViewer/assets/defaultSettingsView-Ds6CBOo0.js +182 -0
  165. package/node_modules/playwright-core/lib/vite/traceViewer/assets/urlMatch-L3liM589.js +1 -0
  166. package/node_modules/playwright-core/lib/vite/traceViewer/assets/xtermModule-DywYcAf8.js +7 -0
  167. package/node_modules/playwright-core/lib/vite/traceViewer/codeMirrorModule.-QdMvsKi.css +1 -0
  168. package/node_modules/playwright-core/lib/vite/traceViewer/codicon.DCmgc-ay.ttf +0 -0
  169. package/node_modules/playwright-core/lib/vite/traceViewer/defaultSettingsView.Bqk9acqE.css +1 -0
  170. package/node_modules/playwright-core/lib/vite/traceViewer/index.B4cLoZK3.js +1 -0
  171. package/node_modules/playwright-core/lib/vite/traceViewer/index.B_TqY17P.css +1 -0
  172. package/node_modules/playwright-core/lib/vite/traceViewer/index.html +44 -0
  173. package/node_modules/playwright-core/lib/vite/traceViewer/manifest.webmanifest +16 -0
  174. package/node_modules/playwright-core/lib/vite/traceViewer/playwright-logo.svg +9 -0
  175. package/node_modules/playwright-core/lib/vite/traceViewer/snapshot.B_Jk1wbt.js +1 -0
  176. package/node_modules/playwright-core/lib/vite/traceViewer/snapshot.html +10 -0
  177. package/node_modules/playwright-core/lib/vite/traceViewer/sw.bundle.js +4 -0
  178. package/node_modules/playwright-core/lib/vite/traceViewer/uiMode.CU5KtEkS.js +5 -0
  179. package/node_modules/playwright-core/lib/vite/traceViewer/uiMode.CyMfwkXJ.css +1 -0
  180. package/node_modules/playwright-core/lib/vite/traceViewer/uiMode.html +18 -0
  181. package/node_modules/playwright-core/lib/vite/traceViewer/xtermModule.kHJ-D0s7.css +1 -0
  182. package/node_modules/playwright-core/lib/webp_codec.LICENSE +173 -0
  183. package/node_modules/playwright-core/lib/webp_codec.wasm +0 -0
  184. package/node_modules/playwright-core/lib/xdg-open +1267 -0
  185. package/node_modules/playwright-core/package.json +34 -0
  186. package/node_modules/playwright-core/types/protocol.d.ts +24645 -0
  187. package/node_modules/playwright-core/types/structs.d.ts +52 -0
  188. package/node_modules/playwright-core/types/types.d.ts +26632 -0
  189. package/package.json +13 -2
  190. package/plugins/devflow-core/extensions/devflow-core.ts +432 -7
  191. package/plugins/devflow-core/runtime/hooks/hook_common.py +514 -0
  192. package/plugins/devflow-core/runtime/hooks/index_gate.py +47 -16
  193. package/plugins/devflow-core/skills/workflow-orchestrator/scripts/acceptance_test_runner.py +488 -71
  194. package/plugins/devflow-core/skills/workflow-orchestrator/scripts/advance_state.rb +51 -0
  195. package/plugins/devflow-core/skills/workflow-orchestrator/scripts/approval_pins.py +433 -0
  196. package/plugins/devflow-core/skills/workflow-orchestrator/scripts/approval_store.py +137 -0
  197. package/plugins/devflow-core/skills/workflow-orchestrator/scripts/dsl_coverage.py +87 -0
  198. package/plugins/devflow-core/skills/workflow-orchestrator/scripts/dsl_draft.py +53 -0
  199. package/plugins/devflow-core/skills/workflow-orchestrator/scripts/dsl_v1.py +318 -0
  200. package/plugins/devflow-core/skills/workflow-orchestrator/scripts/environment_profile.py +134 -0
  201. package/plugins/devflow-core/skills/workflow-orchestrator/scripts/execution_contract.rb +1 -0
  202. package/plugins/devflow-core/skills/workflow-orchestrator/scripts/execution_surface.py +138 -0
  203. package/plugins/devflow-core/skills/workflow-orchestrator/scripts/playwright_adapter.py +515 -0
  204. package/plugins/devflow-core/skills/workflow-orchestrator/scripts/tc_hash.py +132 -0
  205. package/plugins/devflow-core/skills/workflow-orchestrator/scripts/test_command_policy.py +102 -8
  206. package/plugins/devflow-core/skills/workflow-orchestrator/scripts/validate_state.rb +13 -0
  207. package/plugins/devflow-core/skills/workflow-orchestrator/templates/feature-development.yaml +13 -34
  208. package/plugins/devflow-core/skills/workflow-pipeline/SKILL.md +3 -1
  209. package/plugins/devflow-core/skills/workflow-pipeline/references/pipeline-flow.md +68 -140
  210. package/plugins/devflow-core/skills/workflow-project-context/scripts/validate_initialization_database.py +1 -1
  211. package/plugins/devflow-implementation/skills/workflow-execute-phase/references/execute-phase.md +3 -1
  212. package/plugins/devflow-intel/extensions/devflow-intel.ts +1 -1
  213. package/plugins/devflow-intel/skills/workflow-code-index/scripts/code_index.py +23 -4
  214. package/plugins/devflow-quality/runtime/playwright/devflow-test-dsl-v1.schema.json +872 -0
  215. package/plugins/devflow-quality/runtime/playwright/playwright.config.mjs +46 -0
  216. package/plugins/devflow-quality/runtime/playwright/reporter.mjs +311 -0
  217. package/plugins/devflow-quality/runtime/playwright/runner.spec.mjs +1308 -0
  218. package/plugins/devflow-quality/runtime/playwright/runtime-manifest.json +11 -0
  219. package/plugins/devflow-quality/skills/workflow-acceptance-test-design/SKILL.md +3 -0
  220. package/plugins/devflow-quality/skills/workflow-generate-mainflow-cases/SKILL.md +71 -58
  221. package/plugins/devflow-quality/skills/workflow-generate-mainflow-cases/references/api-mainflow-rules.md +20 -15
  222. package/plugins/devflow-quality/skills/workflow-generate-mainflow-cases/references/codebase-discovery.md +3 -1
  223. package/plugins/devflow-quality/skills/workflow-generate-mainflow-cases/references/intermediate-format.md +115 -192
  224. package/plugins/devflow-quality/skills/workflow-generate-mainflow-cases/references/mainflow-selection.md +27 -23
  225. package/plugins/devflow-quality/skills/workflow-generate-mainflow-cases/references/project-dsl-contract.md +78 -153
  226. package/plugins/devflow-quality/skills/workflow-generate-mainflow-cases/references/ui-mainflow-rules.md +36 -83
  227. package/plugins/devflow-quality/skills/workflow-generate-mainflow-cases/scripts/compile_dsl.py +497 -556
  228. package/plugins/devflow-quality/skills/workflow-generate-mainflow-cases/scripts/export_legacy_testagent.py +647 -0
  229. package/plugins/devflow-quality/skills/workflow-generate-mainflow-cases/scripts/normalize_case_payloads.py +10 -3
  230. package/plugins/devflow-quality/skills/workflow-generate-mainflow-cases/scripts/validate_case_payloads.py +165 -275
  231. package/plugins/devflow-quality/skills/workflow-human-acceptance/SKILL.md +63 -0
  232. package/plugins/devflow-quality/skills/workflow-release-closeout/SKILL.md +4 -4
  233. package/plugins/devflow-quality/skills/workflow-run-acceptance-tests/SKILL.md +17 -9
  234. package/src/approval-store.ts +340 -0
  235. package/src/cli.ts +10 -0
  236. package/src/constants.ts +1 -1
  237. package/src/doctor.ts +268 -2
  238. package/src/initialization-store.ts +48 -1
  239. package/src/mcp/auth.ts +103 -0
  240. package/src/mcp/core.ts +102 -0
  241. package/src/mcp/server.ts +193 -0
  242. package/src/mcp/types.ts +5 -0
  243. package/src/paths.ts +12 -1
  244. package/src/project-context.ts +24 -1
  245. package/templates/omp/hook-config.json +6 -0
@@ -1,190 +1,115 @@
1
- # Project DSL Contract
1
+ # Runtime DSL Contract (`devflow-test-dsl/v1`)
2
2
 
3
- Legacy normalization input is an object with metadata and cases:
3
+ `compile_dsl.py` 为每个冻结的自动化 `ui` / `api_flow` TC 写一个 DSL 文件:
4
4
 
5
- ```json
6
- {
7
- "metadata": {
8
- "feature": "Feature name",
9
- "phase": "01-Feature",
10
- "generated_by": "workflow-generate-mainflow-cases",
11
- "project_id": 1
12
- },
13
- "cases": [
14
- {
15
- "project_id": 1,
16
- "name": "Case name",
17
- "description": "Positive mainflow purpose and traceability.",
18
- "tags": ["api-mainflow"],
19
- "dsl_json": {
20
- "name": "Case name",
21
- "description": "Same behavior summary.",
22
- "tags": ["api-mainflow"],
23
- "variables": {},
24
- "steps": []
25
- },
26
- "source_evidence": [
27
- {
28
- "path": ".devflow/planning/features/Feature/后端技术方案.md",
29
- "line": 120,
30
- "reason": "API contract source"
31
- }
32
- ]
33
- }
34
- ]
35
- }
5
+ ```text
6
+ .devflow/planning/generated-cases/{feature}/TC-xxxx.json
36
7
  ```
37
8
 
38
- `cases[*]` must be compatible with backend `CaseCreate` after normalization:
9
+ DSL 是纯数据,由 Devflow Playwright Runtime 解释执行,Core 用同一份 Schema 校验。权威定义:`plugins/devflow-quality/runtime/playwright/devflow-test-dsl-v1.schema.json`(JSON Schema 2020-12,`additionalProperties: false`);Python 侧实现是 Core `dsl_v1.py`(Schema + 语义)与 `dsl_coverage.py`(`covers` 结构覆盖)。AI 不直接写这个文件,而是写 `case-descriptions.json`(`intermediate-format.md`),由编译器生成。
39
10
 
40
- - `project_id`: integer. If no project id is known, use `metadata.project_id` or `1` and record an import note.
41
- - `name`: non-empty string.
42
- - `description`: optional string.
43
- - `dsl_json`: object.
44
- - `tags`: exactly one of `["api-mainflow"]` or `["ui-mainflow"]` unless the case is intentionally mixed UI flow with API setup; mixed UI flows still use `["ui-mainflow"]`.
11
+ ## 文件与门禁的关系
45
12
 
46
- `source_evidence` is allowed in drafts. Normalization moves it to metadata and removes it from import payload cases.
13
+ - 一 TC 一文件,文件名必须是 `<tc_id>.json`,与 `acceptance-test-bindings.json` 里 `devflow_playwright` 绑定的 `dsl_file` 对应;
14
+ - `tc_sha256` = 冻结 TC `data` 的 JCS SHA-256(Core `tc_hash.py` 计算,编译器不接受 AI 提供的值);TC 变化后 DSL 必须重新编译;
15
+ - `dsl_sha256` = 该文件**原始字节**的 SHA-256。用户在 `/devflow` → “待审批”中批准的是这个具体文件:文件任何变化都会使对应 TC 的 `execution_plan` 批准失效;
16
+ - 没有有效 `execution_plan` 批准的 DSL 永远 `blocked(dsl_not_approved)`,不会执行、不会进入收口;
17
+ - 校验入口是整个 `generated-cases/{feature}` 目录(`validate_case_payloads.py`),目录里只有 `TC-xxxx.json` 被当作 DSL。`case-descriptions.json`、`codebase-discovery.json`、`source-map.md` 等是辅助文件,不是 DSL。
47
18
 
48
- ## DSL Step Shape
19
+ ## 顶层结构
49
20
 
50
- Each step needs:
21
+ ```json
22
+ {
23
+ "schema_version": "devflow-test-dsl/v1",
24
+ "tc_id": "TC-0001",
25
+ "tc_sha256": "<64 hex>",
26
+ "name": "登录后显示欢迎语",
27
+ "variables": {
28
+ "user": { "value": "qa-user" },
29
+ "password": { "secret": "QA_PASSWORD" }
30
+ },
31
+ "data": { "namespace": "${execution_id}", "setup": [], "cleanup": [] },
32
+ "steps": [ ]
33
+ }
34
+ ```
51
35
 
52
- - `id`
53
- - `name`
54
- - `driver`: `api`, `web`, or `ui`
55
- - `action`
56
- - `params`
57
- - `depends_on`
58
- - `assertions`
59
- - `timeout_ms`
60
- - `on_failure`
36
+ - 上述 7 个顶层键全部必填,不允许其他键;
37
+ - `variables`:`{ "value": <string|number|boolean>, "sensitive"?: bool }` 或 `{ "secret": "<ENV_KEY>" }`(运行时取自已批准 profile 的 `secret_env`,永远敏感)。不允许重定义内置变量 `execution_id`/`namespace`;
38
+ - `data.namespace` 必填,缺省由编译器写成 `${execution_id}`;`owner`、`accounts[]`、`repeatable` 可选;
39
+ - `data.setup[]` / `data.cleanup[]` **只允许 API 步骤**;`cleanup` 步骤不得带 `covers`;
40
+ - `steps[]`:1–200 个步骤,按序执行;任一步失败即停止主流程,cleanup 仍会执行,cleanup 失败使结果变为 blocked。
61
41
 
62
- API steps require `params.url`. Prefer variable placeholders such as `${base_url}` instead of environment-specific hosts when possible.
42
+ ## 步骤
63
43
 
64
- UI steps with `driver: "ui"` require:
44
+ 公共键:`id`(`[A-Za-z0-9][A-Za-z0-9_-]{0,63}`,全 DSL 唯一)、`driver`(`ui`|`api`)、`action`、`covers`、`timeout_ms`(100–600000)。
65
45
 
66
- - `strategy`: depends on step type (see below)
67
- - `target`: non-empty unless `strategy.mode` is `ai_only`
46
+ ### UI(`driver: "ui"`)
68
47
 
69
- ### Strategy Selection
48
+ | action | 键 |
49
+ |---|---|
50
+ | `goto` | `url` |
51
+ | `click`、`check`、`uncheck`、`assert_visible` | `target` |
52
+ | `fill` | `target`、`value`(字符串) |
53
+ | `select` | `target`、`value`(字符串或字符串数组) |
54
+ | `wait_for` | `target`、`state`(`visible`\|`hidden`\|`attached`\|`detached`);只做条件等待,无固定 sleep |
55
+ | `assert_text` | `target`、`match`(`exact`\|`contains`)、`expected`,可选 `normalize_whitespace`(缺省 true)、`case_sensitive`(缺省 true) |
56
+ | `assert_url` | `match`、`expected` |
57
+ | `screenshot` | 可选 `name`(`[A-Za-z0-9_-]{1,64}`)、`full_page` |
58
+
59
+ **不存在**:`hover`、`assert_url_contains`、`assert_any_visible`、固定等待、`evaluate_js`、任意脚本、`strategy`、`prompt`、`params`、`depends_on`、`on_failure`。
70
60
 
71
- **Action steps** (click, fill, select, hover) — `structured_first` + midscene fallback:
61
+ ### target(六选一,strict:多于一个匹配即失败)
72
62
 
73
63
  ```json
74
- { "strategy": { "mode": "structured_first", "fallback": "midscene" } }
64
+ { "testid": "login-submit" }
65
+ { "role": "button", "name": "登录", "exact": true }
66
+ { "label": "用户名", "exact": true }
67
+ { "placeholder": "请输入名称", "exact": true }
68
+ { "text": "欢迎", "exact": true }
69
+ { "css": "[data-qa='welcome']" }
75
70
  ```
76
71
 
77
- **Verification steps** (assert_text, assert_visible, wait for success/result) — prefer `ai_only`. Visual verification of transient UI (toast messages, success prompts, dialog confirmations) is an AI task:
72
+ `testid` 与 `css` 不带 `exact`。`xpath`、`near_text`、`by/value` 形式、AI 视觉定位均不存在。
78
73
 
79
- ```json
80
- { "strategy": { "mode": "ai_only" } }
81
- ```
74
+ ### API(`driver: "api"`, `action: "request"`)
82
75
 
83
76
  ```json
84
77
  {
85
- "id": "s06",
86
- "name": "验证编辑成功",
87
- "driver": "ui",
88
- "action": "act",
89
- "target": { "label": "操作成功" },
90
- "strategy": { "mode": "ai_only" },
91
- "prompt": "检查页面是否出现'操作成功'的提示消息,确认编辑操作已成功完成",
92
- "depends_on": ["s05"],
93
- "timeout_ms": 15000
78
+ "id": "a02", "driver": "api", "action": "request", "method": "GET",
79
+ "url": "/api/orders/${order_id}", "query": { "verbose": true },
80
+ "expect_status": 200,
81
+ "assertions": [ { "pointer": "/data/status", "op": "equals", "value": "created" } ],
82
+ "extract": { "order_id": { "pointer": "/data/id" } },
83
+ "covers": { "oracle": true }
94
84
  }
95
85
  ```
96
86
 
97
- ### Target Field Specification
98
-
99
- `target` is a **flat key-value object**. The key IS the locator type. The system resolves them in this priority: `css → xpath → label → placeholder → role+name → near_text`.
100
-
101
- **There is NO `by` field. Do NOT invent `{"by": "...", "value": "..."}` format.**
102
-
103
- #### Decision Table: Which Key for Which Scenario
104
-
105
- | 场景 | 选哪个 key | 示例 | 原因 |
106
- |---|---|---|---|
107
- | 页面唯一按钮/菜单/tab | `label` + `exact` | `{"label": "新增项目库", "exact": true}` | 文本最稳定,不受CSS重构影响 |
108
- | 表格行操作按钮(每行重复) | `css` 精确定位 | `{"css": "tr:nth-child(2) .edit-btn"}` | 必须定位到具体行,"编辑"不唯一 |
109
- | 对话框底部确定/取消 | `css` 限定作用域 | `{"css": ".el-dialog__footer .el-button--primary"}` | 防止dialog外也有同名按钮 |
110
- | 输入框(有唯一placeholder) | `placeholder` | `{"placeholder": "请输入后台名称"}` | 语义清晰,自动scope内唯一 |
111
- | 表单项旁边控件 | `near_text` | `{"near_text": "后台名称"}` | label文本定位,控件自动匹配 |
112
- | ARIA友好的按钮/组件 | `role` + `name` | `{"role": "button", "name": "确定"}` | 无障碍属性,可访问性最好 |
113
- | 无他法定位时 | `xpath` | `{"xpath": "//button[text()='确定']"}` | 最后的结构化手段 |
114
- | 以上均不稳定 | `ai_only` strategy | 不走target,用AI视觉识别 | 放弃结构化,交AI处理 |
87
+ - `method`:`GET`/`POST`/`PUT`/`PATCH`/`DELETE`;`url` 以 `/` 开头相对 profile 的 `api_base_url`(缺省 `base_url`),绝对 URL 的 origin 须在 profile `api_origins` 中;不自动跟随重定向;
88
+ - `headers`、`query`(标量)、`json`(任意 JSON,字符串叶子可引用变量);
89
+ - `expect_status`(100–599);`assertions[]` 的 `op` 为 `equals`/`not_equals`/`contains`/`exists`/`not_exists`,`pointer` 为 JSON Pointer,`exists`/`not_exists` 不带 `value`,其余必须带;
90
+ - `extract`:`{ name: { pointer, sensitive? } }`,之后的步骤可用 `${name}`,不得重定义已存在变量;
91
+ - `retry: { max_attempts: 2–5, on: [connection_error|timeout|rate_limited] }`,只重试传输失败;POST/PATCH 需 `idempotent: true`;默认不重试;
92
+ - 通过页面同一 BrowserContext 发送,与 UI 登录态共享 cookie;
93
+ - `Authorization`、`Cookie`、`X-Api-Key` 等敏感请求头只能由 secret/sensitive 变量拼成,如 `"Bearer ${auth_token}"`。
115
94
 
116
- #### Key Selection Priority for Generation
95
+ 变量引用 `${name}` 必须已定义(内置、`variables`、先前 `extract`)。不得出现凭据字面量:真实密码、token、cookie 用 `{ "secret": ... }` 变量,`validate_case_payloads.py` 会拒绝形似密钥的字面值。
117
96
 
118
- 1. **先看唯一性**:页面只有一个"新增项目库"按钮 → `label`;每行都有"编辑" → 不能只用 `label`
119
- 2. **再看作用域**:对话框内用 `css` 限定 `.el-dialog__footer .el-button--primary`
120
- 3. **input/textarea 优先用** `placeholder`
121
- 4. **表单项控件用** `near_text`
122
- 5. **都不行再用** `xpath` **或** `ai_only`
123
-
124
- #### Correct Format Examples
97
+ ## covers
125
98
 
126
99
  ```json
127
- // 页面唯一按钮 → label
128
- { "label": "新增项目库", "exact": true }
129
-
130
- // 表格行按钮 → css 精确定位
131
- { "css": "tr:nth-child(2) .edit-btn" }
132
-
133
- // 对话框确定按钮 → css 限定作用域
134
- { "css": ".el-dialog__footer .el-button--primary" }
135
-
136
- // 输入框 → placeholder
137
- { "placeholder": "请输入后台名称" }
100
+ { "covers": { "preconditions": [1], "steps": [2, 3], "oracle": true } }
138
101
  ```
139
102
 
140
- ### Assertion Rules
141
-
142
- **API steps** (`driver: "api"`) use `assertions[]` with these types:
143
-
144
- | Type | Behavior |
145
- |---|---|
146
- | `equals` | `actual == expected` |
147
- | `status_code` | HTTP 状态码 |
148
- | `contains` | `expected in actual` |
149
- | `json_path_equals` | JSONPath 取值相等 |
150
- | `json_path_exists` | JSONPath 路径存在 |
151
- | `regex` | 正则匹配 |
152
- | `not_equals` / `not_contains` / `greater_than` / `less_than` / `in` / `not_in` / `is_empty` / `is_not_empty` |
153
-
154
- **`"text"` is NOT a valid assertion type.** It will raise `ValueError: unsupported assertion type: text`.
103
+ 下标从 1 开始,指向冻结 TC 的 `preconditions[]` / `steps[]`。Core 硬校验:每个前置条件和步骤都被至少一个步骤覆盖;`oracle` 被至少一个非弱断言的主流程断言步骤覆盖(`wait_for`、`screenshot` 不是断言;弱断言指仅断言静态入口元素可见、断言自己刚操作的元素、仅检查 2xx 无响应体断言)。这只发现遗漏和明显弱断言,语义是否充分由独立 AI 审查(建议性)与人工批准(权威)判断。
155
104
 
156
- **Web/UI steps** (`driver: "web"` / `"ui"`) do NOT use `assertions[]` for text/visibility checks. Use assertion **actions** instead:
105
+ ## 校验命令
157
106
 
158
- ```json
159
- // UI verification — use AI-only, not structured
160
- {
161
- "id": "s06",
162
- "name": "验证操作成功",
163
- "driver": "ui",
164
- "action": "act",
165
- "target": { "label": "操作成功" },
166
- "strategy": { "mode": "ai_only" },
167
- "prompt": "检查页面是否出现'操作成功'的提示消息,确认操作已成功完成",
168
- "depends_on": ["s05"],
169
- "timeout_ms": 15000
170
- }
107
+ ```text
108
+ devflow_mainflow(action="validate", args=[".devflow/planning/generated-cases/{feature}", "--suite", ".devflow/planning/requirements/{feature}/tests.json", "--output", ".devflow/planning/generated-cases/{feature}/validation-report.md"])
171
109
  ```
172
110
 
173
- Valid assertion actions for web/ui (use ai_only for these): `assert_text`, `assert_visible`, `assert_url_contains`, `assert_any_visible`.
174
-
175
- For API steps, assertion example:
111
+ 校验是纯数据操作,不 import、不执行被测项目的任何代码(`--discovery` 已废弃并被忽略)。检查项:Schema、语义(唯一 ID、变量作用域、重试安全、敏感头)、密钥字面量、`tc_id` 存在于冻结 suite、文件名与 `tc_id` 一致、`tc_sha256` 与冻结 TC 一致、`covers` 结构覆盖、每个 TC 至多一个 DSL。目录内缺少 DSL 的自动化 `ui`/`api_flow` TC 会以警告列出(它们会在门禁被 `dsl_not_approved` 阻断)。
176
112
 
177
- ```json
178
- {
179
- "id": "api-login",
180
- "driver": "api",
181
- "action": "post",
182
- "params": { "url": "${base_url}/auth/login", "json": { "userid": "${userid}", "password": "${password}" } },
183
- "assertions": [
184
- { "type": "status_code", "expected": 200 },
185
- { "type": "json_path_exists", "path": "headers.X-Jwt-Token" }
186
- ]
187
- }
188
- ```
113
+ ## 旧 TestAgent 导入格式
189
114
 
190
- Do not include real credentials, tokens, cookies, passwords, API keys, or production secrets. Use variables like `${auth_token}` or placeholders like `<token>` only.
115
+ 旧的 TestAgent 导入载荷(`project_id` + `dsl_json`、`strategy`/Midscene、`params`、`depends_on`、xpath/near_text 等)**不是** Runtime DSL,不参与门禁,本 Skill 不再教授。仅当开发者明确要求 TestAgent 导入文件时,才运行 `scripts/export_legacy_testagent.py`;其产物不能绑定到 `devflow_playwright`、不能被批准为执行计划、不能计入验收结果,也不得写成 `TC-xxxx.json`。`case-import-payloads.json` 这个名字只属于该 legacy 导出,绝不是 Runtime DSL 产物。
@@ -1,110 +1,63 @@
1
1
  # UI Mainflow Rules
2
2
 
3
- UI cases validate successful user journeys through importable DSL.
3
+ UI 用例把冻结的、自动化的 `execution_surface: ui` TC(含存量推导为 `ui` 的 `page` TC)落成确定性的 `devflow-test-dsl/v1`。AI 写 `case-descriptions.json`(格式见 `intermediate-format.md`),`compile_dsl.py` 生成 `TC-xxxx.json`(形状见 `project-dsl-contract.md`)。
4
4
 
5
5
  ## Hard Rule: Source-Backed Terminology
6
6
 
7
- **All UI text in locators, step names, and descriptions MUST be exact strings from source code.** Never invent, translate, guess, or "improve" the text. If the code says "查询" (query button text), the step name and locator must say "查询" — not "搜索", not "查找".
7
+ **locator 与断言里的界面文本必须逐字来自源码。** 不得编造、翻译、猜测或“改进”。源码写“查询”就写“查询”,不写“搜索”“查找”。
8
8
 
9
- Extract locator values from:
10
- - Template/JSX: `<el-button>查询</el-button>` → `locator: "text:查询"`
11
- - Placeholder attrs: `placeholder="请输入名称"` → `locator: "placeholder:请输入名称"`
12
- - Dialog titles: `<el-dialog title="新增项目">` → verify text "新增项目"
13
- - Menu/router config: `{ path: '/Project/List', meta: { title: '项目管理' } }`
9
+ - 模板/JSX:`<el-button>查询</el-button>` → `role:button:查询` 或 `text:查询`
10
+ - placeholder:`placeholder="请输入名称"` → `placeholder:请输入名称`
11
+ - `data-testid`:`data-testid="save-btn"` → `testid:save-btn`
12
+ - 提示/标题文案:`<el-dialog title="新增项目">` → `assert_text` 的 `expected: "新增项目"`
13
+ - 菜单/路由配置:`{ path: '/Project/List', meta: { title: '项目管理' } }` → `goto` 的 `url` 与断言文案
14
14
 
15
- ### List Page Patterns: Query vs Search
15
+ 列表页“查询/筛选”(表格上方表单、不跳转)与全局“搜索”(header/侧边栏、触发路由)是不同模式,一律以源码文本为准,不按 URL 或行为重新命名。
16
16
 
17
- | 模式 | 按钮文本(源码) | URL特征 | 行为 |
18
- |---|---|---|---|
19
- | 列表查询/筛选 | "查询" 或 "筛选" | `/List`, `/list`, `/index` | 表格上方表单,过滤不跳转 |
20
- | 全局搜索 | "搜索" | header/侧边栏 | 触发路由跳转 |
17
+ ## TC 忠实性
21
18
 
22
- **Do not reclassify**: 源码写"查询"就生成"查询",源码写"搜索"就生成"搜索"。不要根据URL或行为推断应该叫什么。
19
+ - 一个 TC 一个 case;TC 的每个 `preconditions[i]`、`steps[i]` 都必须被某个 DSL 步骤的 `covers` 覆盖,`oracle` 必须被断言步骤覆盖(`covers: ["oracle"]`)。DSL 不得增删或改写 TC 的步骤与 oracle,源码只用来补充入口 URL、locator、测试数据。
20
+ - oracle 断言要断言**结果**:`assert_text`(`match: exact` 或 `contains`)、`assert_url`、对流程刚产生的元素做 `assert_visible`。只断言静态入口元素可见、或断言自己刚点过的元素,会被 Core 判为弱断言而拒绝。
21
+ - 生成范围是正向主流程:打开路由、创建/编辑/执行主记录、查看成功结果、保存预期状态。异常、权限、响应式/a11y、空状态、浏览器兼容、性能、纯视觉判断、无稳定 locator 或无法准备/隔离数据的 TC 不生成 DSL,改为在绑定阶段降级为 `manual`(需 `mode_override` 批准)或 `blocked`,并向用户说明。
23
22
 
24
23
  ## Step Rules
25
24
 
26
- - Prefer `driver: "ui"` for structured UI operations.
27
- - Use `driver: "web"` only for plain browser actions that do not need structured target dispatch.
28
- - `target` must be non-empty unless `strategy.mode` is `ai_only`.
29
- - Use API setup steps only when needed to make the UI journey deterministic.
25
+ - 只用 v1 UI 动作:`goto`、`click`、`fill`、`select`、`check`、`uncheck`、`wait_for`、`assert_visible`、`assert_text`、`assert_url`、`screenshot`。没有 `hover`、`wait`(固定/加载等待)、`verify`、`act`、`assert_url_contains`、`inject_token`、`evaluate_js`。
26
+ - 动作后需要等待时用 `wait_for`(locator + `state`),不要用固定 sleep;“URL 包含 X”用 `assert_url` + `match: "contains"`。
27
+ - 需要预置数据或登录态时,用 `data.setup` 的 API 请求步骤,或显式 UI 登录步骤(`goto` + `fill` + `click`);没有 `auth` 快捷方式。凭据写成 `variables` 里的 `{ "secret": "ENV_KEY" }`,绝不写字面量。
28
+ - 需要清理时写 `data.cleanup` 的 API 步骤。测试数据使用 `${namespace}`/`${execution_id}` 命名,避免多次运行互相污染。
29
+ - API 步骤也可以穿插在 UI 主流程里做旁路校验(共享 BrowserContext cookie)。
30
30
 
31
- ### Strategy Selection: Action vs Verification
31
+ ## Locator 决策
32
32
 
33
- **Operating steps** (click, fill, select, hover): use `structured_first` + midscene fallback.
33
+ 顺序:`testid` → `role` → `label` / `placeholder` → `text` → `css`(最后手段)。
34
34
 
35
- ```json
36
- { "strategy": { "mode": "structured_first", "fallback": "midscene" } }
37
- ```
38
-
39
- **Verification steps** (assert_text, assert_visible, wait for success/result): prefer `ai_only`. Visual verification is inherently an AI task — toast messages, success prompts, dialog confirmations are transient and their DOM structure varies. Structured locators waste time on the fallback path.
40
-
41
- ```json
42
- { "strategy": { "mode": "ai_only" } }
43
- ```
44
-
45
- ```json
46
- // CORRECT: AI-only verification after critical action
47
- {
48
- "id": "s06",
49
- "name": "验证编辑成功",
50
- "driver": "ui",
51
- "action": "act",
52
- "target": { "label": "操作成功" },
53
- "strategy": { "mode": "ai_only" },
54
- "prompt": "检查页面上是否出现'操作成功'的提示消息,确认编辑操作已成功完成",
55
- "depends_on": ["s05"],
56
- "timeout_ms": 15000
57
- }
58
- ```
59
-
60
- Use `structured` only when runtime validation proves the locator is unique and stable. Do NOT use `structured` for verification steps.
35
+ 1. 源码里有 `data-testid` 就用 `testid:`。没有而该元素是主流程的关键控件时,在 `source-map.md` 里记录“缺少 testid”,并建议开发者补上,不要靠猜。
36
+ 2. 有明确 ARIA 角色和可访问名称:`role:button:确定`。
37
+ 3. 表单控件:`label:用户名` 或 `placeholder:请输入名称`。
38
+ 4. 页面内唯一的可见文本:`text:xxx`。
39
+ 5. `css:` 只能用源码里确实存在的选择器,并在 `source-map.md` 注明出处;编译器对 `css` 及所有非 testid locator 打印警告。
61
40
 
62
- ### Target Format: Scenario → Key Decision Table
41
+ locator 是 strict 的:匹配多个元素就失败。表格每行重复的“编辑/删除/查看”、对话框里的“确定/取消”这类文本,`text:`/`role:` 几乎一定多匹配,编译器会警告;应改用行级/对话框内的 `data-testid`。`xpath:`、`near:`、`scope: row:N`/`dialog` 均不支持。禁止编造 CSS(含 `%`、纯容器类如 `.el-form-item__content`、`:nth-child` 位置选择器、过短选择器都会被拒绝)。
63
42
 
64
- `target` is a **flat key-value object** (no `by` field). The system resolves in priority: `css → xpath → label → placeholder → role+name → near_text`. Choose the right key based on the scenario:
43
+ ## Assertion Rules
65
44
 
66
- | 场景 | key | 示例 |
67
- |---|---|---|
68
- | 页面唯一按钮/菜单/tab | `label` + `exact` | `{"label": "新增项目库", "exact": true}` |
69
- | 表格行操作按钮(每行重复) | `css` 精确定位 | `{"css": "tr:nth-child(2) .edit-btn"}` |
70
- | 对话框底部确定/取消 | `css` 限定dialog | `{"css": ".el-dialog__footer .el-button--primary"}` |
71
- | 输入框(有唯一placeholder) | `placeholder` | `{"placeholder": "请输入后台名称"}` |
72
- | 表单项旁边控件 | `near_text` | `{"near_text": "后台名称"}` |
73
- | ARIA友好的按钮/组件 | `role` + `name` | `{"role": "button", "name": "确定"}` |
74
- | 无他法 | `xpath` 或 `ai_only` | `{"xpath": "//button[text()='确定']"}` |
75
-
76
- **Decision rule**: 先看唯一性(page-level唯一用label,行级重复用css),再看作用域(dialog内用css限定),input优先placeholder。不存在 `{"by": "xxx", "value": "yyy"}` 这种格式。
77
-
78
- ### Assertion Rules
79
-
80
- **Web/UI steps use assertion ACTIONS, not `assertions[]`:**
45
+ UI 断言只用断言动作,没有 `assertions[]`:
81
46
 
82
47
  ```json
83
- // CORRECT: 文本断言用 action
84
- { "action": "assert_text", "target": { "label": "操作成功" }, "params": { "text": "操作成功" } }
85
- { "action": "assert_visible", "target": { "css": ".el-dialog" } }
86
- { "action": "assert_url_contains", "params": { "text": "/sadmin/a/org/Project/Gift" } }
48
+ { "action": "assert_text", "locator": "testid:toast", "match": "contains", "expected": "保存成功", "covers": ["oracle"] }
49
+ { "action": "assert_url", "expected": "/projects/list", "match": "contains" }
50
+ { "action": "assert_visible", "locator": "testid:result-panel" }
87
51
  ```
88
52
 
89
- ```json
90
- // WRONG: "text" 不是合法断言类型,web/ui 不走 assertions[]
91
- { "assertions": [{ "type": "text", "expected": "礼物库" }] }
92
- { "assertions": [{ "type": "visible", "target": { "by": "css", "selector": ".el-dialog" } }] }
93
- ```
94
-
95
- Valid assertion actions: `assert_text`, `assert_visible`, `assert_url_contains`, `assert_any_visible`.
96
-
97
- API steps use `assertions[]` with types: `equals`, `contains`, `status_code`, `json_path_equals`, `json_path_exists`, `regex`, etc. See `project-dsl-contract.md` for the full list.
53
+ - 确定性:断言期望必须是源码/需求给出的确切文案,不使用 AI 视觉判断(`ai_only`、Midscene、prompt 都不存在)。
54
+ - 短暂提示(toast)可能一闪而过:先 `wait_for` 它 `visible`,再 `assert_text`;或改为断言持久化的结果(列表行文本、URL、详情页字段)。
55
+ - `wait_for` 与 `screenshot` 不算断言。
98
56
 
99
57
  ## Source Evidence
100
58
 
101
- Cite at least one planning artifact and one code artifact per case:
102
-
103
- - Planning: UI spec, frontend tech spec, feature breakdown, or change list.
104
- - Code: router, page/view, API client, and relevant component/store/hook files.
105
-
106
- ## Positive Mainflow Boundary
59
+ 每个 case 在 `source-map.md` 里至少引用一份规划产物(UI-SPEC、前端技术方案、功能点梳理或变更清单)和一份代码产物(路由、页面/视图、API client、相关组件/store)。证据放在 `source-map.md` 与 `source_evidence` 备注中;它不写入 DSL。
107
60
 
108
- Allowed: open route, create/edit/run primary record, view success result, save expected state.
61
+ ## After compile
109
62
 
110
- Not allowed: validation errors, permission differences, responsive/a11y-only checks, empty state checks, browser compatibility, performance timing, or destructive cleanup beyond normal test setup.
63
+ 编译通过后仍要:整个目录校验 → 独立 AI 审查每个 DSL(对照 TC oracle,建议性)→ 用 `devflow_approval` 提交 `execution_plan` → 用户在 `/devflow` → “待审批”逐 TC 批准。没有批准的 DSL 不会执行。见 `SKILL.md`。