@epoint-testtech/ep-stage-skill 0.0.4-alpha.1 → 0.0.6

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 (213) hide show
  1. package/SKILL.md +27 -27
  2. package/codex-skill/ep-stage/glue-create-project/SKILL.md +223 -206
  3. package/codex-skill/ep-stage/glue-generate-testcase/SKILL.md +275 -274
  4. package/codex-skill/ep-stage/glue-generate-testcase/examples/observable-testcase.json +40 -40
  5. package/codex-skill/ep-stage/glue-generate-testcase/references/testcase-schema.md +95 -112
  6. package/codex-skill/ep-stage/glue-generate-testcase/references/testcase-tpl.md +72 -72
  7. package/codex-skill/ep-stage/glue-run-test/SKILL.md +295 -289
  8. package/codex-skill/ep-stage/glue-run-test/references/ai-runtime-loop.md +30 -0
  9. package/codex-skill/ep-stage/glue-run-test/references/crud-pipeline.md +132 -145
  10. package/codex-skill/ep-stage/glue-run-test/references/gap-review-protocol.md +44 -43
  11. package/codex-skill/ep-stage/glue-run-test/references/harness-principles.md +46 -46
  12. package/codex-skill/ep-stage/glue-run-test/references/playwright-cli-odav.md +166 -0
  13. package/codex-skill/ep-stage/glue-run-test/scripts/extract-page-elements-eval.mjs +233 -0
  14. package/codex-skill/ep-stage/glue-run-test/scripts/generate-crud-spec.mjs +149 -149
  15. package/codex-skill/ep-stage/page-element-scan/SKILL.md +91 -0
  16. package/codex-skill/ep-stage/page-element-scan/evals/evals.json +37 -0
  17. package/codex-skill/ep-stage/page-element-scan/evals/fixtures/sample-list-page.html +85 -0
  18. package/codex-skill/ep-stage/page-element-scan/references/pagination-controls.md +153 -0
  19. package/codex-skill/ep-stage/page-element-scan/scripts/extract-page-elements-eval.mjs +233 -0
  20. package/codex-skill/ep-stage/page-element-scan/scripts/extract-page-elements.mjs +298 -0
  21. package/codex-skill/ep-stage/page-element-scan/scripts/scan-page.mjs +749 -0
  22. package/codex-skill/ep-stage/recording-to-glue/SKILL.md +28 -28
  23. package/codex-skill/ep-stage/scripts/validate-skill.mjs +98 -95
  24. package/dist/src/cli/generate-testcase.d.ts +17 -51
  25. package/dist/src/cli/generate-testcase.d.ts.map +1 -1
  26. package/dist/src/cli/generate-testcase.js +74 -181
  27. package/dist/src/cli/index.d.ts +3 -2
  28. package/dist/src/cli/index.d.ts.map +1 -1
  29. package/dist/src/cli/index.js +51 -17
  30. package/dist/src/cli/run.d.ts +136 -29
  31. package/dist/src/cli/run.d.ts.map +1 -1
  32. package/dist/src/cli/run.js +507 -65
  33. package/dist/src/cli/spec.d.ts +17 -13
  34. package/dist/src/cli/spec.d.ts.map +1 -1
  35. package/dist/src/cli/spec.js +59 -33
  36. package/dist/src/contracts/crud-business-module.d.ts +6 -0
  37. package/dist/src/contracts/crud-business-module.d.ts.map +1 -1
  38. package/dist/src/contracts/glue-contract-v1.d.ts +98 -0
  39. package/dist/src/contracts/glue-contract-v1.d.ts.map +1 -0
  40. package/dist/src/contracts/glue-contract-v1.js +9 -0
  41. package/dist/src/contracts/observable-chain.d.ts +4 -0
  42. package/dist/src/contracts/observable-chain.d.ts.map +1 -1
  43. package/dist/src/extractors/code-list-json5.d.ts +192 -0
  44. package/dist/src/extractors/code-list-json5.d.ts.map +1 -0
  45. package/dist/src/extractors/code-list-json5.js +91 -0
  46. package/dist/src/extractors/html-page.d.ts +9 -0
  47. package/dist/src/extractors/html-page.d.ts.map +1 -1
  48. package/dist/src/extractors/html-page.js +26 -2
  49. package/dist/src/extractors/prd-extractor.d.ts +70 -0
  50. package/dist/src/extractors/prd-extractor.d.ts.map +1 -0
  51. package/dist/src/extractors/prd-extractor.js +248 -0
  52. package/dist/src/generators/agent-inferred-workflow-script.js +66 -66
  53. package/dist/src/generators/stage-skeleton-script.d.ts +87 -20
  54. package/dist/src/generators/stage-skeleton-script.d.ts.map +1 -1
  55. package/dist/src/generators/stage-skeleton-script.js +647 -238
  56. package/dist/src/index.d.ts +2 -2
  57. package/dist/src/index.d.ts.map +1 -1
  58. package/dist/src/index.js +1 -1
  59. package/dist/src/normalizers/crud-contract.d.ts +3 -0
  60. package/dist/src/normalizers/crud-contract.d.ts.map +1 -1
  61. package/dist/src/normalizers/crud-contract.js +3 -0
  62. package/dist/src/runtime/ai-runtime-trace.d.ts +88 -0
  63. package/dist/src/runtime/ai-runtime-trace.d.ts.map +1 -0
  64. package/dist/src/runtime/ai-runtime-trace.js +119 -0
  65. package/dist/src/testcase/button-interaction-inference.d.ts +37 -0
  66. package/dist/src/testcase/button-interaction-inference.d.ts.map +1 -0
  67. package/dist/src/testcase/button-interaction-inference.js +385 -0
  68. package/dist/src/testcase/contract-testcase-assembler.d.ts +44 -0
  69. package/dist/src/testcase/contract-testcase-assembler.d.ts.map +1 -0
  70. package/dist/src/testcase/contract-testcase-assembler.js +806 -0
  71. package/dist/src/testcase/prd-button-mapper.d.ts +72 -0
  72. package/dist/src/testcase/prd-button-mapper.d.ts.map +1 -0
  73. package/dist/src/testcase/prd-button-mapper.js +148 -0
  74. package/dist/src/testcase/runtime-context.d.ts +9 -0
  75. package/dist/src/testcase/runtime-context.d.ts.map +1 -0
  76. package/dist/src/testcase/runtime-context.js +1 -0
  77. package/dist/src/testcase/test-access.d.ts +38 -0
  78. package/dist/src/testcase/test-access.d.ts.map +1 -0
  79. package/dist/src/testcase/test-access.js +106 -0
  80. package/dist/src/testcase/testcase-execution-fields.d.ts +10 -0
  81. package/dist/src/testcase/testcase-execution-fields.d.ts.map +1 -0
  82. package/dist/src/testcase/testcase-execution-fields.js +1 -0
  83. package/dist/src/testcase/testcase-generator.d.ts.map +1 -1
  84. package/dist/src/testcase/testcase-generator.js +6 -0
  85. package/dist/src/testcase/testcase-markdown.d.ts +11 -0
  86. package/dist/src/testcase/testcase-markdown.d.ts.map +1 -0
  87. package/dist/src/testcase/testcase-markdown.js +181 -0
  88. package/dist/src/testcase/testcase-skeleton.d.ts +4 -0
  89. package/dist/src/testcase/testcase-skeleton.d.ts.map +1 -1
  90. package/dist/src/testcase/testcase-spec-assembly.d.ts +4 -0
  91. package/dist/src/testcase/testcase-spec-assembly.d.ts.map +1 -1
  92. package/dist/src/testcase/testcase-v1-draft.d.ts +58 -0
  93. package/dist/src/testcase/testcase-v1-draft.d.ts.map +1 -0
  94. package/dist/src/testcase/testcase-v1-draft.js +13 -0
  95. package/dist/src/validation/contract.d.ts +14 -0
  96. package/dist/src/validation/contract.d.ts.map +1 -0
  97. package/dist/src/validation/contract.js +132 -0
  98. package/dist/src/validation/credentials.d.ts +7 -2
  99. package/dist/src/validation/credentials.d.ts.map +1 -1
  100. package/dist/src/validation/credentials.js +15 -4
  101. package/dist/src/validation/index.d.ts +1 -0
  102. package/dist/src/validation/index.d.ts.map +1 -1
  103. package/dist/src/validation/index.js +1 -0
  104. package/dist/src/validation/testcase.d.ts +9 -7
  105. package/dist/src/validation/testcase.d.ts.map +1 -1
  106. package/dist/src/validation/testcase.js +181 -34
  107. package/docs/README.md +124 -134
  108. package/docs/mvp-usage-guide.md +298 -298
  109. package/examples/schemeresource-observable-docs/schemeresource.context.md +20 -20
  110. package/examples/schemeresource.module-hints.json +38 -38
  111. package/examples/schemeresource.observable.code_list.md +37 -37
  112. package/examples/zwplace-observable-docs/zwplace.context.md +16 -16
  113. package/examples/zwplace-placecategory-validation.json +29 -29
  114. package/examples/zwplace.module-hints.json +69 -69
  115. package/examples/zwplace.observable.code_list.md +37 -37
  116. package/package.json +2 -2
  117. package/codex-skill/ep-stage/.omc/state/sessions/d636ad35-5fc9-4d5e-85b0-2bcad7d86ee5/pre-tool-advisory-throttle.json +0 -10
  118. package/dist/test/cli/extract-contract.test.d.ts +0 -2
  119. package/dist/test/cli/extract-contract.test.d.ts.map +0 -1
  120. package/dist/test/cli/extract-contract.test.js +0 -32
  121. package/dist/test/cli/generate-testcase-inference.test.d.ts +0 -2
  122. package/dist/test/cli/generate-testcase-inference.test.d.ts.map +0 -1
  123. package/dist/test/cli/generate-testcase-inference.test.js +0 -63
  124. package/dist/test/cli/generate-testcase-paths.test.d.ts +0 -2
  125. package/dist/test/cli/generate-testcase-paths.test.d.ts.map +0 -1
  126. package/dist/test/cli/generate-testcase-paths.test.js +0 -165
  127. package/dist/test/cli/generate-testcase-requirements.test.d.ts +0 -2
  128. package/dist/test/cli/generate-testcase-requirements.test.d.ts.map +0 -1
  129. package/dist/test/cli/generate-testcase-requirements.test.js +0 -229
  130. package/dist/test/cli/generate-testcase.test.d.ts +0 -2
  131. package/dist/test/cli/generate-testcase.test.d.ts.map +0 -1
  132. package/dist/test/cli/generate-testcase.test.js +0 -130
  133. package/dist/test/cli/index.test.d.ts +0 -2
  134. package/dist/test/cli/index.test.d.ts.map +0 -1
  135. package/dist/test/cli/index.test.js +0 -113
  136. package/dist/test/cli/probe.test.d.ts +0 -2
  137. package/dist/test/cli/probe.test.d.ts.map +0 -1
  138. package/dist/test/cli/probe.test.js +0 -31
  139. package/dist/test/cli/run.test.d.ts +0 -2
  140. package/dist/test/cli/run.test.d.ts.map +0 -1
  141. package/dist/test/cli/run.test.js +0 -149
  142. package/dist/test/cli/spec-boundary.test.d.ts +0 -2
  143. package/dist/test/cli/spec-boundary.test.d.ts.map +0 -1
  144. package/dist/test/cli/spec-boundary.test.js +0 -198
  145. package/dist/test/cli/spec.test.d.ts +0 -2
  146. package/dist/test/cli/spec.test.d.ts.map +0 -1
  147. package/dist/test/cli/spec.test.js +0 -196
  148. package/dist/test/code-list.test.d.ts +0 -2
  149. package/dist/test/code-list.test.d.ts.map +0 -1
  150. package/dist/test/code-list.test.js +0 -39
  151. package/dist/test/crud-contract.test.d.ts +0 -2
  152. package/dist/test/crud-contract.test.d.ts.map +0 -1
  153. package/dist/test/crud-contract.test.js +0 -799
  154. package/dist/test/gap-inference.test.d.ts +0 -2
  155. package/dist/test/gap-inference.test.d.ts.map +0 -1
  156. package/dist/test/gap-inference.test.js +0 -597
  157. package/dist/test/generalization.test.d.ts +0 -2
  158. package/dist/test/generalization.test.d.ts.map +0 -1
  159. package/dist/test/generalization.test.js +0 -73
  160. package/dist/test/inference/module-hints-inference.test.d.ts +0 -2
  161. package/dist/test/inference/module-hints-inference.test.d.ts.map +0 -1
  162. package/dist/test/inference/module-hints-inference.test.js +0 -25
  163. package/dist/test/inference/source-analysis.test.d.ts +0 -2
  164. package/dist/test/inference/source-analysis.test.d.ts.map +0 -1
  165. package/dist/test/inference/source-analysis.test.js +0 -23
  166. package/dist/test/material-inventory.test.d.ts +0 -2
  167. package/dist/test/material-inventory.test.d.ts.map +0 -1
  168. package/dist/test/material-inventory.test.js +0 -154
  169. package/dist/test/observable-chain.test.d.ts +0 -2
  170. package/dist/test/observable-chain.test.d.ts.map +0 -1
  171. package/dist/test/observable-chain.test.js +0 -123
  172. package/dist/test/observable-pipeline.test.d.ts +0 -2
  173. package/dist/test/observable-pipeline.test.d.ts.map +0 -1
  174. package/dist/test/observable-pipeline.test.js +0 -470
  175. package/dist/test/page-structure.test.d.ts +0 -2
  176. package/dist/test/page-structure.test.d.ts.map +0 -1
  177. package/dist/test/page-structure.test.js +0 -45
  178. package/dist/test/scenario-inference.test.d.ts +0 -2
  179. package/dist/test/scenario-inference.test.d.ts.map +0 -1
  180. package/dist/test/scenario-inference.test.js +0 -73
  181. package/dist/test/stage-context.test.d.ts +0 -2
  182. package/dist/test/stage-context.test.d.ts.map +0 -1
  183. package/dist/test/stage-context.test.js +0 -395
  184. package/dist/test/testcase-generator.test.d.ts +0 -2
  185. package/dist/test/testcase-generator.test.d.ts.map +0 -1
  186. package/dist/test/testcase-generator.test.js +0 -276
  187. package/dist/test/testcase-skeleton.test.d.ts +0 -2
  188. package/dist/test/testcase-skeleton.test.d.ts.map +0 -1
  189. package/dist/test/testcase-skeleton.test.js +0 -185
  190. package/dist/test/testcase-spec-assembly.test.d.ts +0 -2
  191. package/dist/test/testcase-spec-assembly.test.d.ts.map +0 -1
  192. package/dist/test/testcase-spec-assembly.test.js +0 -105
  193. package/dist/test/util/credentials.test.d.ts +0 -2
  194. package/dist/test/util/credentials.test.d.ts.map +0 -1
  195. package/dist/test/util/credentials.test.js +0 -64
  196. package/dist/test/util/i18n-testcase.test.d.ts +0 -2
  197. package/dist/test/util/i18n-testcase.test.d.ts.map +0 -1
  198. package/dist/test/util/i18n-testcase.test.js +0 -119
  199. package/dist/test/util/softlink.test.d.ts +0 -2
  200. package/dist/test/util/softlink.test.d.ts.map +0 -1
  201. package/dist/test/util/softlink.test.js +0 -82
  202. package/dist/test/validation/credentials.test.d.ts +0 -2
  203. package/dist/test/validation/credentials.test.d.ts.map +0 -1
  204. package/dist/test/validation/credentials.test.js +0 -72
  205. package/dist/test/validation/projects-index.test.d.ts +0 -2
  206. package/dist/test/validation/projects-index.test.d.ts.map +0 -1
  207. package/dist/test/validation/projects-index.test.js +0 -48
  208. package/dist/test/validation/testcase.test.d.ts +0 -2
  209. package/dist/test/validation/testcase.test.d.ts.map +0 -1
  210. package/dist/test/validation/testcase.test.js +0 -129
  211. package/dist/vitest.config.d.ts +0 -3
  212. package/dist/vitest.config.d.ts.map +0 -1
  213. package/dist/vitest.config.js +0 -7
@@ -1,165 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
2
- import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';
3
- import os from 'node:os';
4
- import path from 'node:path';
5
- import JSON5 from 'json5';
6
- /**
7
- * HOME 隔离 + 预填 projects.index.json5,让 runGenerateTestcase 的 requirement 追加不报错、不污染真实环境。
8
- * 仅服务于本文件的路径解析断言;requirement 追加的正确性由 generate-testcase-requirements.test.ts 覆盖。
9
- */
10
- function seedIsolatedHomeWithProject(homeDir, projectDir) {
11
- const indexPath = path.join(homeDir, '.ep-stage', 'projects.index.json5');
12
- mkdirSync(path.dirname(indexPath), { recursive: true });
13
- writeFileSync(indexPath, `${JSON5.stringify({
14
- projects: [
15
- {
16
- projectName: 'test-paths',
17
- projectDir,
18
- mode: 'glue',
19
- stageCreateVersion: '0.0.0-test',
20
- requirements: [],
21
- },
22
- ],
23
- systems: [],
24
- }, null, 2)}\n`, 'utf8');
25
- }
26
- const probe = vi.hoisted(() => ({
27
- runProbeAndCoverage: vi.fn(() => ({
28
- contract: { contractVersion: 'crud-business-module/v1', module: { id: 'm1', label: '模块' } },
29
- testcaseV2: {
30
- schemaVersion: 'v2',
31
- scenario: 'crud.single-page',
32
- moduleId: 'm1',
33
- moduleName: '模块',
34
- menuPath: '一级>二级',
35
- requiredSystems: [{ url: '', systemName: undefined }],
36
- requiredRoles: [{ role: 'admin', hint: undefined }],
37
- coveredActions: [],
38
- uncoveredCandidates: [],
39
- cases: [],
40
- reasoningSummary: {
41
- conclusion: 'ok',
42
- evidenceChain: [],
43
- alternatives: [],
44
- confidence: 'high',
45
- risks: [],
46
- needsHumanReview: false,
47
- },
48
- },
49
- inferenceTrace: {
50
- schemaVersion: 'inference-trace/v1',
51
- codeListPath: 'mock',
52
- generatedAt: '2026-06-25T00:00:00.000Z',
53
- materialInventory: {
54
- knowledgeRoot: '',
55
- moduleId: { status: 'resolved', value: 'm1' },
56
- menu: { status: 'resolved', value: '一级>二级' },
57
- htmlFiles: [],
58
- javaActionFiles: [],
59
- docsFiles: [],
60
- missing: [],
61
- },
62
- sourceAnalysis: {
63
- mode: 'inferred',
64
- confidence: 'medium',
65
- sources: [],
66
- fields: [],
67
- businessRules: [],
68
- uiSignals: [],
69
- backendSignals: [],
70
- unresolved: [],
71
- },
72
- moduleHintsInference: {
73
- mode: 'inferred',
74
- confidence: 'medium',
75
- dataKey: { evidence: [] },
76
- searchConditions: [],
77
- buttonAliases: {},
78
- deletePolicy: { evidence: [] },
79
- assertionPolicy: {},
80
- customWorkflows: [],
81
- unresolved: [],
82
- },
83
- coverageDiff: {
84
- coveredActions: [],
85
- uncoveredCandidates: [],
86
- needsReview: [],
87
- },
88
- reasoningSummary: {
89
- conclusion: 'ok',
90
- confidence: 'high',
91
- risks: [],
92
- needsHumanReview: false,
93
- },
94
- },
95
- })),
96
- }));
97
- const softlink = vi.hoisted(() => ({
98
- createSoftlinkWithFallback: vi.fn(() => ({ strategy: 'symlink' })),
99
- }));
100
- vi.mock('../../src/cli/probe.js', () => probe);
101
- vi.mock('../../src/util/softlink.js', () => softlink);
102
- const { runGenerateTestcase } = await import('../../src/cli/generate-testcase.js');
103
- describe('runGenerateTestcase 路径解析', () => {
104
- let tmpDir;
105
- let tmpHome;
106
- const originalHome = process.env.HOME;
107
- beforeEach(() => {
108
- tmpDir = mkdtempSync(path.join(os.tmpdir(), 'generate-testcase-paths-'));
109
- tmpHome = mkdtempSync(path.join(os.tmpdir(), 'ep-stage-paths-home-'));
110
- process.env.HOME = tmpHome;
111
- vi.clearAllMocks();
112
- });
113
- afterEach(() => {
114
- process.env.HOME = originalHome;
115
- rmSync(tmpHome, { recursive: true, force: true });
116
- rmSync(tmpDir, { recursive: true, force: true });
117
- });
118
- it('根据 code_list.md 的整理目录与物料路径推导 probe 输入,而不是误用 requirementDir', () => {
119
- const knowledgeRoot = path.join(tmpDir, 'knowledge-project', 'sample-app');
120
- const requirementDir = path.join(knowledgeRoot, '_docs', '014-测试需求10-20260622');
121
- const testsDir = path.join(tmpDir, 'project', 'src', 'tests', '014-测试需求10-20260622');
122
- const codeListPath = path.join(requirementDir, 'code_list.md');
123
- const htmlDir = path.join(knowledgeRoot, 'src', 'main', 'webapp', 'perpage', 'zwplace');
124
- const javaDir = path.join(knowledgeRoot, 'src', 'main', 'java', 'com', 'epoint', 'zwplace', 'action');
125
- const htmlPath = path.join(htmlDir, 'gxhzwplacelist.html');
126
- const javaPath = path.join(javaDir, 'GxhZwPlaceListAction.java');
127
- const docsDir = path.join(knowledgeRoot, '_docs', 'zwplace-observable-docs');
128
- const docsPath = path.join(docsDir, 'spec.yaml');
129
- const hintsPath = path.join(knowledgeRoot, '_docs', 'zwplace.module-hints.json');
130
- mkdirSync(requirementDir, { recursive: true });
131
- mkdirSync(htmlDir, { recursive: true });
132
- mkdirSync(javaDir, { recursive: true });
133
- mkdirSync(docsDir, { recursive: true });
134
- writeFileSync(htmlPath, '<html></html>\n', 'utf8');
135
- writeFileSync(javaPath, 'public class GxhZwPlaceListAction {}\n', 'utf8');
136
- writeFileSync(docsPath, 'module:\n id: zwplace\n', 'utf8');
137
- writeFileSync(hintsPath, '{}\n', 'utf8');
138
- writeFileSync(codeListPath, `# 测试模块代码清单
139
-
140
- > 整理目录:\`${knowledgeRoot}\`
141
-
142
- menu: 一级>二级
143
-
144
- | 文件路径 |
145
- |---------|
146
- | \`_docs/zwplace-observable-docs/spec.yaml\` |
147
- | \`src/main/webapp/perpage/zwplace/gxhzwplacelist.html\` |
148
- | \`src/main/java/com/epoint/zwplace/action/GxhZwPlaceListAction.java\` |
149
- | \`_docs/zwplace.module-hints.json\` |
150
- `, 'utf8');
151
- // HOME 隔离 + 预填 index(projectDir = <tmpDir>/project,与 testsDir 反推一致),避开末尾 requirement 追加校验。
152
- seedIsolatedHomeWithProject(tmpHome, path.join(tmpDir, 'project'));
153
- runGenerateTestcase({
154
- codeList: codeListPath,
155
- testsDir,
156
- requirementDir,
157
- });
158
- expect(probe.runProbeAndCoverage).toHaveBeenCalledWith(expect.objectContaining({
159
- docsDir,
160
- webappDir: htmlDir,
161
- javaActionsDir: javaDir,
162
- hintsPath,
163
- }));
164
- });
165
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=generate-testcase-requirements.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"generate-testcase-requirements.test.d.ts","sourceRoot":"","sources":["../../../test/cli/generate-testcase-requirements.test.ts"],"names":[],"mappings":""}
@@ -1,229 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
2
- import { mkdtempSync, mkdirSync, rmSync, writeFileSync, readFileSync } from 'node:fs';
3
- import os from 'node:os';
4
- import path from 'node:path';
5
- import JSON5 from 'json5';
6
- // mock probe 避开真实钻探;requirements 追加逻辑不 mock,真实跑。
7
- const probe = vi.hoisted(() => ({
8
- runProbeAndCoverage: vi.fn(() => ({
9
- contract: { contractVersion: 'crud-business-module/v1', module: { id: 'm1', label: '模块' } },
10
- testcaseV2: {
11
- schemaVersion: 'v2',
12
- scenario: 'crud.single-page',
13
- moduleId: 'm1',
14
- moduleName: '模块',
15
- menuPath: '一级>二级',
16
- requiredSystems: [{ url: '', systemName: undefined }],
17
- requiredRoles: [{ role: 'admin', hint: undefined }],
18
- coveredActions: [],
19
- uncoveredCandidates: [],
20
- cases: [],
21
- reasoningSummary: {
22
- conclusion: 'ok',
23
- evidenceChain: [],
24
- alternatives: [],
25
- confidence: 'high',
26
- risks: [],
27
- needsHumanReview: false,
28
- },
29
- },
30
- inferenceTrace: {
31
- schemaVersion: 'inference-trace/v1',
32
- codeListPath: 'mock',
33
- generatedAt: '2026-06-26T00:00:00.000Z',
34
- materialInventory: {
35
- knowledgeRoot: '',
36
- moduleId: { status: 'resolved', value: 'm1' },
37
- menu: { status: 'resolved', value: '一级>二级' },
38
- htmlFiles: [],
39
- javaActionFiles: [],
40
- docsFiles: [],
41
- missing: [],
42
- },
43
- sourceAnalysis: {
44
- mode: 'inferred',
45
- confidence: 'medium',
46
- sources: [],
47
- fields: [],
48
- businessRules: [],
49
- uiSignals: [],
50
- backendSignals: [],
51
- unresolved: [],
52
- },
53
- moduleHintsInference: {
54
- mode: 'inferred',
55
- confidence: 'medium',
56
- dataKey: { evidence: [] },
57
- searchConditions: [],
58
- buttonAliases: {},
59
- deletePolicy: { evidence: [] },
60
- assertionPolicy: {},
61
- customWorkflows: [],
62
- unresolved: [],
63
- },
64
- coverageDiff: {
65
- coveredActions: [],
66
- uncoveredCandidates: [],
67
- needsReview: [],
68
- },
69
- reasoningSummary: {
70
- conclusion: 'ok',
71
- confidence: 'high',
72
- risks: [],
73
- needsHumanReview: false,
74
- },
75
- },
76
- })),
77
- }));
78
- const softlink = vi.hoisted(() => ({
79
- createSoftlinkWithFallback: vi.fn(() => ({ strategy: 'symlink' })),
80
- }));
81
- vi.mock('../../src/cli/probe.js', () => probe);
82
- vi.mock('../../src/util/softlink.js', () => softlink);
83
- const { runGenerateTestcase } = await import('../../src/cli/generate-testcase.js');
84
- const REQUIREMENT_NAME = '014-测试需求10-20260622';
85
- /**
86
- * 构造一组能让 resolveProbeInputsFromCodeList 成功的最小物料 fixture
87
- * (复用 generate-testcase-paths.test.ts 验证过的目录结构)。
88
- */
89
- function buildMaterialFixture(workDir) {
90
- const knowledgeRoot = path.join(workDir, 'knowledge-project', 'sample-app');
91
- const requirementDir = path.join(knowledgeRoot, '_docs', REQUIREMENT_NAME);
92
- const codeListPath = path.join(requirementDir, 'code_list.md');
93
- const htmlDir = path.join(knowledgeRoot, 'src', 'main', 'webapp', 'perpage', 'zwplace');
94
- const javaDir = path.join(knowledgeRoot, 'src', 'main', 'java', 'com', 'epoint', 'zwplace', 'action');
95
- const htmlPath = path.join(htmlDir, 'gxhzwplacelist.html');
96
- const javaPath = path.join(javaDir, 'GxhZwPlaceListAction.java');
97
- const docsDir = path.join(knowledgeRoot, '_docs', 'zwplace-observable-docs');
98
- const docsPath = path.join(docsDir, 'spec.yaml');
99
- const hintsPath = path.join(knowledgeRoot, '_docs', 'zwplace.module-hints.json');
100
- mkdirSync(requirementDir, { recursive: true });
101
- mkdirSync(htmlDir, { recursive: true });
102
- mkdirSync(javaDir, { recursive: true });
103
- mkdirSync(docsDir, { recursive: true });
104
- writeFileSync(htmlPath, '<html></html>\n', 'utf8');
105
- writeFileSync(javaPath, 'public class GxhZwPlaceListAction {}\n', 'utf8');
106
- writeFileSync(docsPath, 'module:\n id: zwplace\n', 'utf8');
107
- writeFileSync(hintsPath, '{}\n', 'utf8');
108
- writeFileSync(codeListPath, `# 测试模块代码清单
109
-
110
- > 整理目录:\`${knowledgeRoot}\`
111
-
112
- menu: 一级>二级
113
-
114
- | 文件路径 |
115
- |---------|
116
- | \`_docs/zwplace-observable-docs/spec.yaml\` |
117
- | \`src/main/webapp/perpage/zwplace/gxhzwplacelist.html\` |
118
- | \`src/main/java/com/epoint/zwplace/action/GxhZwPlaceListAction.java\` |
119
- | \`_docs/zwplace.module-hints.json\` |
120
- `, 'utf8');
121
- return { codeListPath, requirementDir };
122
- }
123
- /**
124
- * 在临时 HOME 下造一个最小可用的 projects.index.json5(含一条 project + 一条 system),
125
- * 用于验证 requirements 追加不丢 systems。
126
- */
127
- function seedIndex(homeDir, projectDir) {
128
- const indexPath = path.join(homeDir, '.ep-stage', 'projects.index.json5');
129
- mkdirSync(path.dirname(indexPath), { recursive: true });
130
- writeFileSync(indexPath, `${JSON5.stringify({
131
- projects: [
132
- {
133
- projectName: 'demo-glue',
134
- projectDir,
135
- mode: 'glue',
136
- stageCreateVersion: '0.0.0-test',
137
- requirements: [],
138
- },
139
- ],
140
- systems: [
141
- {
142
- url: 'http://demo.example.com',
143
- knownRoles: ['admin'],
144
- credentialsCache: {
145
- admin: {
146
- username: 'demo',
147
- password: 'secret',
148
- lastUsed: '2026-06-26T00:00:00.000Z',
149
- },
150
- },
151
- },
152
- ],
153
- }, null, 2)}\n`, 'utf8');
154
- }
155
- function readIndex(homeDir) {
156
- const indexPath = path.join(homeDir, '.ep-stage', 'projects.index.json5');
157
- return JSON5.parse(readFileSync(indexPath, 'utf8'));
158
- }
159
- describe('runGenerateTestcase 追加 requirement 到 projects.index', () => {
160
- let tmpHome;
161
- let tmpWork;
162
- const originalHome = process.env.HOME;
163
- beforeEach(() => {
164
- tmpHome = mkdtempSync(path.join(os.tmpdir(), 'ep-stage-req-home-'));
165
- tmpWork = mkdtempSync(path.join(os.tmpdir(), 'ep-stage-req-work-'));
166
- // 关键:HOME 隔离,绝对不污染真实 ~/.ep-stage
167
- process.env.HOME = tmpHome;
168
- vi.clearAllMocks();
169
- });
170
- afterEach(() => {
171
- process.env.HOME = originalHome;
172
- rmSync(tmpHome, { recursive: true, force: true });
173
- rmSync(tmpWork, { recursive: true, force: true });
174
- });
175
- it('跑完后向对应 project.requirements 追加一条 name=<basename(testsDir)>, lastRunStatus=never', () => {
176
- const { codeListPath, requirementDir } = buildMaterialFixture(tmpWork);
177
- const projectDir = path.join(tmpWork, 'glue-project');
178
- const testsDir = path.join(projectDir, 'src', 'tests', REQUIREMENT_NAME);
179
- seedIndex(tmpHome, projectDir);
180
- runGenerateTestcase({ codeList: codeListPath, testsDir, requirementDir, projectDir });
181
- const index = readIndex(tmpHome);
182
- const project = index.projects[0];
183
- expect(project.projectDir).toBe(projectDir);
184
- expect(project.requirements).toHaveLength(1);
185
- const req = project.requirements[0];
186
- expect(req.name).toBe(REQUIREMENT_NAME);
187
- expect(req.testsDir).toBe(testsDir);
188
- expect(req.requirementDir).toBe(requirementDir);
189
- expect(req.lastRunStatus).toBe('never');
190
- });
191
- it('重跑同名需求不重复追加(去重更新)', () => {
192
- const { codeListPath, requirementDir } = buildMaterialFixture(tmpWork);
193
- const projectDir = path.join(tmpWork, 'glue-project');
194
- const testsDir = path.join(projectDir, 'src', 'tests', REQUIREMENT_NAME);
195
- seedIndex(tmpHome, projectDir);
196
- runGenerateTestcase({ codeList: codeListPath, testsDir, requirementDir, projectDir });
197
- runGenerateTestcase({ codeList: codeListPath, testsDir, requirementDir, projectDir });
198
- const index = readIndex(tmpHome);
199
- const project = index.projects[0];
200
- expect(project.requirements).toHaveLength(1);
201
- });
202
- it('不丢 systems(整体覆写后 systems 仍在)', () => {
203
- const { codeListPath, requirementDir } = buildMaterialFixture(tmpWork);
204
- const projectDir = path.join(tmpWork, 'glue-project');
205
- const testsDir = path.join(projectDir, 'src', 'tests', REQUIREMENT_NAME);
206
- seedIndex(tmpHome, projectDir);
207
- runGenerateTestcase({ codeList: codeListPath, testsDir, requirementDir, projectDir });
208
- const index = readIndex(tmpHome);
209
- expect(index.systems).toHaveLength(1);
210
- const sys = index.systems[0];
211
- expect(sys.url).toBe('http://demo.example.com');
212
- expect(sys.credentialsCache.admin.username).toBe('demo');
213
- });
214
- it('projectDir 不在 index 时抛中文错误并引导先跑 /glue-create-project', () => {
215
- const { codeListPath, requirementDir } = buildMaterialFixture(tmpWork);
216
- const projectDir = path.join(tmpWork, 'unknown-project');
217
- const testsDir = path.join(projectDir, 'src', 'tests', REQUIREMENT_NAME);
218
- // seed 的是另一个 projectDir
219
- seedIndex(tmpHome, path.join(tmpWork, 'another-project'));
220
- expect(() => runGenerateTestcase({ codeList: codeListPath, testsDir, requirementDir, projectDir })).toThrowError(/未在.*projects\.index\.json5.*glue-create-project/u);
221
- });
222
- it('index 文件不存在时也按 projectDir 不在 index 处理并抛中文错误', () => {
223
- const { codeListPath, requirementDir } = buildMaterialFixture(tmpWork);
224
- const projectDir = path.join(tmpWork, 'glue-project');
225
- const testsDir = path.join(projectDir, 'src', 'tests', REQUIREMENT_NAME);
226
- // 不 seedIndex,连 index 文件都不存在
227
- expect(() => runGenerateTestcase({ codeList: codeListPath, testsDir, requirementDir, projectDir })).toThrowError(/未在.*projects\.index\.json5.*glue-create-project/u);
228
- });
229
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=generate-testcase.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"generate-testcase.test.d.ts","sourceRoot":"","sources":["../../../test/cli/generate-testcase.test.ts"],"names":[],"mappings":""}
@@ -1,130 +0,0 @@
1
- /**
2
- * generate-testcase.ts 单元测试。
3
- *
4
- * 覆盖:
5
- * - parseGenerateTestcaseArgs 缺参 / 非法参数对 / -- 分隔符
6
- * - decideScenario 3 档优先级(CLI 参数 / hints / 默认)
7
- * - renderTestcaseMarkdown:i18n 字段名 / 状态值;硬编码「未确认项」标题;
8
- * `unresolved` 字段标题与状态值映射不冲突。
9
- *
10
- * 端到端 testcase 子命令(含 probe / 文件落盘)依赖主仓 knowledge-project 物料,
11
- * 由 Phase 5 真机验收覆盖,此处不重复。
12
- */
13
- import { describe, expect, it } from 'vitest';
14
- import { decideScenario, parseGenerateTestcaseArgs, renderTestcaseMarkdown, } from '../../src/cli/generate-testcase.js';
15
- function makeTestcase(overrides = {}) {
16
- return {
17
- schemaVersion: 'v2',
18
- scenario: 'crud.single-page',
19
- moduleId: 'zwplace',
20
- moduleName: '场所窗口信息管理',
21
- menuPath: '业务管理 > 场所窗口信息',
22
- requiredSystems: [{ url: 'https://example.com', systemName: '示例系统' }],
23
- requiredRoles: [{ role: 'admin', hint: '后台管理员' }],
24
- coveredActions: [
25
- { actionId: 'create', kind: '新增', evidence: ['contract=crud-business-module/v1'] },
26
- ],
27
- uncoveredCandidates: [
28
- {
29
- actionId: 'export',
30
- label: '导出 CSV',
31
- status: 'planned',
32
- requiredRole: 'admin',
33
- businessIntent: '导出列表为 CSV 文件',
34
- assertionExpectation: '下载完成且文件非空',
35
- evidence: ['contract=crud-business-module/v1'],
36
- },
37
- ],
38
- cases: [
39
- {
40
- caseId: 'zwplace.create',
41
- title: '新增场所窗口',
42
- scenario: 'crud.single-page',
43
- reviewStatus: 'needs_review',
44
- requiredRole: 'admin',
45
- evidence: ['contract=crud-business-module/v1'],
46
- steps: ['打开新增弹窗', '提交表单'],
47
- assertions: ['弹窗关闭', '列表多一条'],
48
- unresolved: ['菜单路径待确认'],
49
- },
50
- ],
51
- reasoningSummary: {
52
- conclusion: '基于契约推理生成 1 条用例',
53
- evidenceChain: ['contract=crud-business-module/v1'],
54
- alternatives: [],
55
- confidence: 'medium',
56
- risks: [],
57
- needsHumanReview: true,
58
- },
59
- ...overrides,
60
- };
61
- }
62
- describe('parseGenerateTestcaseArgs', () => {
63
- it('缺 --code-list 时抛错', () => {
64
- expect(() => parseGenerateTestcaseArgs(['--tests-dir', '/x'])).toThrow(/缺少 --code-list/);
65
- });
66
- it('缺 --tests-dir 时抛错', () => {
67
- expect(() => parseGenerateTestcaseArgs(['--code-list', '/x'])).toThrow(/缺少 --tests-dir/);
68
- });
69
- it('参数对非法时抛错', () => {
70
- expect(() => parseGenerateTestcaseArgs(['--code-list'])).toThrow(/无效参数对/);
71
- });
72
- it('-- 分隔符被忽略', () => {
73
- const args = parseGenerateTestcaseArgs(['--', '--code-list', '/a', '--tests-dir', '/b']);
74
- expect(args.codeList).toBe('/a');
75
- expect(args.testsDir).toBe('/b');
76
- });
77
- it('解析 scenario / hints / project-dir / requirement-dir', () => {
78
- const args = parseGenerateTestcaseArgs([
79
- '--code-list', '/a',
80
- '--tests-dir', '/b',
81
- '--scenario', 'statistic',
82
- '--hints', '/h.json',
83
- '--project-dir', '/p',
84
- '--requirement-dir', '/r',
85
- ]);
86
- expect(args.scenario).toBe('statistic');
87
- expect(args.hints).toBe('/h.json');
88
- expect(args.projectDir).toBe('/p');
89
- expect(args.requirementDir).toBe('/r');
90
- });
91
- });
92
- describe('decideScenario 3 档优先级', () => {
93
- it('①档 --scenario CLI 参数优先', () => {
94
- expect(decideScenario({ codeList: '', testsDir: '', scenario: 'approval', hints: '/path?scenario=statistic' })).toBe('approval');
95
- });
96
- it('②档 hints 路径含 scenario=', () => {
97
- expect(decideScenario({ codeList: '', testsDir: '', hints: '/path?scenario=statistic.kpi' })).toBe('statistic.kpi');
98
- });
99
- it('③档默认 crud.single-page', () => {
100
- expect(decideScenario({ codeList: '', testsDir: '' })).toBe('crud.single-page');
101
- });
102
- it('hints 路径不含 scenario= 时回落默认', () => {
103
- expect(decideScenario({ codeList: '', testsDir: '', hints: '/h.json' })).toBe('crud.single-page');
104
- });
105
- });
106
- describe('renderTestcaseMarkdown', () => {
107
- it('字段名翻译为中文', () => {
108
- const md = renderTestcaseMarkdown(makeTestcase());
109
- expect(md).toMatch(/场景类型:单页 CRUD/);
110
- expect(md).toMatch(/菜单路径:业务管理/);
111
- expect(md).toMatch(/操作角色:admin/);
112
- expect(md).toMatch(/骨架已命中动作/);
113
- expect(md).toMatch(/骨架未命中候选/);
114
- });
115
- it('状态值翻译为中文', () => {
116
- const md = renderTestcaseMarkdown(makeTestcase());
117
- expect(md).toMatch(/状态:已计划/); // planned
118
- expect(md).toMatch(/审阅状态:待审阅/); // needs_review
119
- });
120
- it('未确认项字段标题硬编码「未确认项」(不被状态值映射污染)', () => {
121
- const md = renderTestcaseMarkdown(makeTestcase());
122
- expect(md).toMatch(/未确认项:菜单路径待确认/);
123
- // i18nTestcase('unresolved') 仍为「未解决」,不允许出现在字段标题位置
124
- expect(md).not.toMatch(/^\s*-\s+未解决:/m);
125
- });
126
- it('无 uncoveredCandidates 时显示「(无)」', () => {
127
- const md = renderTestcaseMarkdown(makeTestcase({ uncoveredCandidates: [] }));
128
- expect(md).toMatch(/骨架未命中候选\n(无)/);
129
- });
130
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=index.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../../test/cli/index.test.ts"],"names":[],"mappings":""}
@@ -1,113 +0,0 @@
1
- /**
2
- * src/cli/index.ts 路由测试(REQ-CLI-02 修订)。
3
- *
4
- * 覆盖:
5
- * - --help / -h 打印 testcase / spec / run 3 子命令且不含 contract
6
- * - 未知子命令 → process.exit(1)
7
- * - 路由到 parseGenerateTestcaseArgs / parseSpecArgs / parseRunArgs
8
- *
9
- * 用 vi.mock 替换 generate-testcase / spec / run 模块,避免占位 throw 干扰路由判定。
10
- */
11
- import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
12
- import { mkdtempSync, mkdirSync, rmSync, writeFileSync, symlinkSync } from 'node:fs';
13
- import os from 'node:os';
14
- import path from 'node:path';
15
- import { pathToFileURL } from 'node:url';
16
- const generateTestcase = vi.hoisted(() => ({
17
- parseGenerateTestcaseArgs: vi.fn((argv) => ({ codeList: 'parsed', testsDir: argv.join(' ') })),
18
- runGenerateTestcase: vi.fn(() => 'TESTCASE_OK'),
19
- }));
20
- const spec = vi.hoisted(() => ({
21
- parseSpecArgs: vi.fn((argv) => ({ testcase: 'parsed', out: argv.join(' ') })),
22
- runSpec: vi.fn(() => 'SPEC_OK'),
23
- }));
24
- const run = vi.hoisted(() => ({
25
- parseRunArgs: vi.fn((argv) => ({ spec: 'parsed', testcase: argv.join(' '), headless: true })),
26
- runRun: vi.fn(async () => 'RUN_OK'),
27
- }));
28
- vi.mock('../../src/cli/generate-testcase.js', () => generateTestcase);
29
- vi.mock('../../src/cli/spec.js', () => spec);
30
- vi.mock('../../src/cli/run.js', () => run);
31
- const { main, printHelp } = await import('../../src/cli/index.js');
32
- describe('ep-stage-skill CLI 路由', () => {
33
- let logSpy;
34
- let errSpy;
35
- let exitSpy;
36
- beforeEach(() => {
37
- logSpy = vi.spyOn(console, 'log').mockImplementation(() => undefined);
38
- errSpy = vi.spyOn(console, 'error').mockImplementation(() => undefined);
39
- exitSpy = vi.spyOn(process, 'exit').mockImplementation(((code) => {
40
- throw new Error(`__exit_${code ?? 0}__`);
41
- }));
42
- });
43
- afterEach(() => {
44
- logSpy.mockRestore();
45
- errSpy.mockRestore();
46
- exitSpy.mockRestore();
47
- vi.clearAllMocks();
48
- });
49
- it('--help 打印 3 子命令 testcase/spec/run 且不注册 contract 子命令', async () => {
50
- await main(['node', 'cli', '--help']);
51
- const printed = logSpy.mock.calls.flat().join('\n');
52
- expect(printed).toMatch(/ep-stage-skill testcase /);
53
- expect(printed).toMatch(/ep-stage-skill spec /);
54
- expect(printed).toMatch(/ep-stage-skill run /);
55
- // 反向断言:不存在 `ep-stage-skill contract` 子命令入口
56
- expect(printed).not.toMatch(/ep-stage-skill contract\b/);
57
- });
58
- it('-h 等价于 --help', async () => {
59
- await main(['node', 'cli', '-h']);
60
- expect(logSpy.mock.calls.flat().join('\n')).toMatch(/testcase/);
61
- });
62
- it('无参数时打印 help(不 exit)', async () => {
63
- await main(['node', 'cli']);
64
- expect(logSpy.mock.calls.flat().join('\n')).toMatch(/testcase/);
65
- expect(exitSpy).not.toHaveBeenCalled();
66
- });
67
- it('printHelp 不注册 contract 子命令', () => {
68
- printHelp();
69
- expect(logSpy.mock.calls.flat().join('\n')).not.toMatch(/ep-stage-skill contract\b/);
70
- });
71
- it('未知子命令 exit 1 + stderr', async () => {
72
- await expect(main(['node', 'cli', 'unknown-cmd'])).rejects.toThrow(/__exit_1__/);
73
- expect(errSpy.mock.calls.flat().join('\n')).toMatch(/未知子命令/);
74
- });
75
- it('testcase 子命令路由到 runGenerateTestcase', async () => {
76
- const result = await main(['node', 'cli', 'testcase', '--code-list', '/x']);
77
- expect(generateTestcase.parseGenerateTestcaseArgs).toHaveBeenCalledWith(['--code-list', '/x']);
78
- expect(generateTestcase.runGenerateTestcase).toHaveBeenCalled();
79
- expect(result).toBe('TESTCASE_OK');
80
- });
81
- it('spec 子命令路由到 runSpec', async () => {
82
- const result = await main(['node', 'cli', 'spec', '--testcase', '/t', '--out', '/o']);
83
- expect(spec.parseSpecArgs).toHaveBeenCalledWith(['--testcase', '/t', '--out', '/o']);
84
- expect(spec.runSpec).toHaveBeenCalled();
85
- expect(result).toBe('SPEC_OK');
86
- });
87
- it('run 子命令路由到 runRun', async () => {
88
- const result = await main(['node', 'cli', 'run', '--spec', '/s', '--testcase', '/t']);
89
- expect(run.parseRunArgs).toHaveBeenCalledWith(['--spec', '/s', '--testcase', '/t']);
90
- expect(run.runRun).toHaveBeenCalled();
91
- expect(result).toBe('RUN_OK');
92
- });
93
- it('-- 分隔符被忽略', async () => {
94
- await main(['node', 'cli', 'testcase', '--', '--code-list', '/x']);
95
- expect(generateTestcase.parseGenerateTestcaseArgs).toHaveBeenCalledWith(['--code-list', '/x']);
96
- });
97
- it('软链 CLI 入口也应识别为直接执行', async () => {
98
- const mod = await import('../../src/cli/index.js');
99
- const tmpDir = mkdtempSync(path.join(os.tmpdir(), 'ep-stage-skill-cli-'));
100
- const realEntry = path.join(tmpDir, 'dist', 'src', 'cli', 'index.js');
101
- const binEntry = path.join(tmpDir, '.bin', 'ep-stage-skill');
102
- try {
103
- mkdirSync(path.dirname(realEntry), { recursive: true });
104
- mkdirSync(path.dirname(binEntry), { recursive: true });
105
- writeFileSync(realEntry, '// mock cli entry\n', 'utf8');
106
- symlinkSync(realEntry, binEntry);
107
- expect(mod.isDirectExecution(pathToFileURL(realEntry).href, binEntry)).toBe(true);
108
- }
109
- finally {
110
- rmSync(tmpDir, { recursive: true, force: true });
111
- }
112
- });
113
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=probe.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"probe.test.d.ts","sourceRoot":"","sources":["../../../test/cli/probe.test.ts"],"names":[],"mappings":""}