@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,73 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { compareObservableRuns, summarizeGeneralizationRun, } from '../src/index.js';
3
- /**
4
- * 泛化评估测试。
5
- *
6
- * 验证 summarizeGeneralizationRun 把单次 run 汇总为可对比指标,
7
- * compareObservableRuns 计算两个系统的场景差异/coverage delta/物料解析分歧。
8
- */
9
- describe('generalization evaluation', () => {
10
- it('summarizes a single run into comparable metrics', () => {
11
- const metricsA = summarizeGeneralizationRun({
12
- moduleId: 'zwplace',
13
- resolvedInputs: {
14
- moduleId: { status: 'resolved', value: 'zwplace', evidence: '' },
15
- docsDir: { status: 'resolved', path: '/a/docs', evidence: '' },
16
- webappDir: { status: 'resolved', path: '/a/webapp', evidence: '' },
17
- javaActionsDir: { status: 'resolved', path: '/a/java', evidence: '' },
18
- hintsPath: { status: 'resolved', path: '/a/hints.json', evidence: '' },
19
- menu: { status: 'resolved', value: 'm', evidence: '' },
20
- },
21
- scenario: {
22
- moduleId: 'zwplace',
23
- candidates: [
24
- { scenario: 'crud.single-page', confidence: 'high', evidenceRefs: [], matchedSkeletonCapabilities: [], unresolved: [] },
25
- { scenario: 'crud.nested', confidence: 'medium', evidenceRefs: [], matchedSkeletonCapabilities: [], unresolved: [] },
26
- ],
27
- gate: { status: 'confirmed', confirmedBy: 'human', reason: 'ok' },
28
- reasoningSummary: { conclusion: '', evidenceChain: [], alternatives: [], confidence: 'high', risks: [], needsHumanReview: false },
29
- },
30
- coverageDiff: {
31
- moduleId: 'zwplace',
32
- skeletonCoverageId: 'crud-plus-export/v1',
33
- baseline: { plannedWorkflows: ['w1'], candidateWorkflows: ['w2'], unresolvedWorkflows: [] },
34
- covered: [{ actionId: 'a', label: 'l', pageId: 'p', status: 'covered', reason: '' }],
35
- partiallyCovered: [],
36
- gapCandidates: [],
37
- unresolved: [],
38
- nestedCrudCandidates: [{ pageId: 'p', evidence: [], supportedActions: [], unresolvedReason: 'r' }],
39
- comparison: { both: [], onlyBaseline: [], onlyGeneralized: [] },
40
- reasoningSummary: { conclusion: '', evidenceChain: [], alternatives: [], confidence: 'medium', risks: [], needsHumanReview: true },
41
- },
42
- });
43
- expect(metricsA).toMatchObject({
44
- moduleId: 'zwplace',
45
- scenarios: ['crud.single-page', 'crud.nested'],
46
- coverage: { covered: 1, gapCandidate: 0, nestedCrud: 1 },
47
- baselineWorkflowCount: 2,
48
- materialResolution: { docsDir: 'resolved', webappDir: 'resolved', javaActionsDir: 'resolved', hintsPath: 'resolved' },
49
- });
50
- });
51
- it('compares two systems by observability metrics', () => {
52
- const metricsA = {
53
- moduleId: 'zwplace',
54
- materialResolution: { docsDir: 'resolved', webappDir: 'resolved', javaActionsDir: 'resolved', hintsPath: 'resolved' },
55
- scenarios: ['crud.single-page', 'crud.nested'],
56
- coverage: { covered: 1, gapCandidate: 0, nestedCrud: 1 },
57
- baselineWorkflowCount: 2,
58
- };
59
- const metricsB = {
60
- moduleId: 'other',
61
- materialResolution: { docsDir: 'missing', webappDir: 'resolved', javaActionsDir: 'resolved', hintsPath: 'missing' },
62
- scenarios: ['crud.single-page', 'export'],
63
- coverage: { covered: 3, gapCandidate: 2, nestedCrud: 0 },
64
- baselineWorkflowCount: 5,
65
- };
66
- const cmp = compareObservableRuns(metricsA, metricsB);
67
- expect(cmp.scenariosOnlyInA).toEqual(['crud.nested']);
68
- expect(cmp.scenariosOnlyInB).toEqual(['export']);
69
- expect(cmp.coverageDelta).toEqual({ covered: -2, gapCandidate: -2, nestedCrud: 1 });
70
- expect(cmp.materialResolutionDivergence).toContain('docsDir');
71
- expect(cmp.materialResolutionDivergence).toContain('hintsPath');
72
- });
73
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=module-hints-inference.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"module-hints-inference.test.d.ts","sourceRoot":"","sources":["../../../test/inference/module-hints-inference.test.ts"],"names":[],"mappings":""}
@@ -1,25 +0,0 @@
1
- import { dirname, join, resolve } from 'node:path';
2
- import { fileURLToPath } from 'node:url';
3
- import { describe, expect, it } from 'vitest';
4
- import { extractCodeListSummary, extractHtmlPage, extractJavaAction } from '../../src/index.js';
5
- import { buildSourceAnalysis } from '../../src/inference/source-analysis.js';
6
- import { inferModuleHintsFromMaterials } from '../../src/inference/module-hints-inference.js';
7
- const repoRoot = resolve(dirname(fileURLToPath(import.meta.url)), '../../../..');
8
- const knowledgeRoot = join(repoRoot, 'knowledge-project/epoint-web-v9.5.2');
9
- const requirementDir = join(knowledgeRoot, '_docs/014-测试需求10-20260622');
10
- const webappDir = join(knowledgeRoot, 'src/main/webapp/perpage/zwplace');
11
- const javaActionsDir = join(knowledgeRoot, 'src/main/java/com/epoint/zwplace/action');
12
- describe('inferModuleHintsFromMaterials', () => {
13
- it('不依赖 module-hints 文件也能推理 zwplace 的基础骨架槽位', () => {
14
- const codeListPath = join(requirementDir, 'code_list.md');
15
- const codeList = extractCodeListSummary(codeListPath);
16
- const pages = ['gxhzwplacelist.html', 'gxhzwplaceadd.html', 'gxhzwplaceedit.html'].map((file) => extractHtmlPage(join(webappDir, file)));
17
- const actions = ['GxhZwPlaceListAction.java', 'GxhZwPlaceAddAction.java', 'GxhZwPlaceEditAction.java'].map((file) => extractJavaAction(join(javaActionsDir, file)));
18
- const sourceAnalysis = buildSourceAnalysis({ codeListPath, docsDir: requirementDir, codeList, pages, actions });
19
- const result = inferModuleHintsFromMaterials({ sourceAnalysis, pages, actions });
20
- expect(result.hints.dataKey?.selectedField).toBe('placename');
21
- expect(result.hints.searchConditions?.[0]?.field).toBe('placename');
22
- expect(result.inference.mode).toBe('inferred');
23
- expect(result.inference.customWorkflows.map((workflow) => workflow.label)).toContain('同步窗口管理系统');
24
- });
25
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=source-analysis.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"source-analysis.test.d.ts","sourceRoot":"","sources":["../../../test/inference/source-analysis.test.ts"],"names":[],"mappings":""}
@@ -1,23 +0,0 @@
1
- import { dirname, join, resolve } from 'node:path';
2
- import { fileURLToPath } from 'node:url';
3
- import { describe, expect, it } from 'vitest';
4
- import { extractCodeListSummary, extractHtmlPage, extractJavaAction } from '../../src/index.js';
5
- import { buildSourceAnalysis } from '../../src/inference/source-analysis.js';
6
- const repoRoot = resolve(dirname(fileURLToPath(import.meta.url)), '../../../..');
7
- const knowledgeRoot = join(repoRoot, 'knowledge-project/epoint-web-v9.5.2');
8
- const requirementDir = join(knowledgeRoot, '_docs/014-测试需求10-20260622');
9
- const webappDir = join(knowledgeRoot, 'src/main/webapp/perpage/zwplace');
10
- const javaActionsDir = join(knowledgeRoot, 'src/main/java/com/epoint/zwplace/action');
11
- describe('buildSourceAnalysis', () => {
12
- it('标记 014 真实物料为 prd+html+java 源分析', () => {
13
- const codeListPath = join(requirementDir, 'code_list.md');
14
- const codeList = extractCodeListSummary(codeListPath);
15
- const pages = ['gxhzwplacelist.html', 'gxhzwplaceadd.html'].map((file) => extractHtmlPage(join(webappDir, file)));
16
- const actions = ['GxhZwPlaceListAction.java', 'GxhZwPlaceAddAction.java'].map((file) => extractJavaAction(join(javaActionsDir, file)));
17
- const analysis = buildSourceAnalysis({ codeListPath, docsDir: requirementDir, codeList, pages, actions });
18
- expect(analysis.mode).toBe('prd+html+java');
19
- expect(analysis.sources.map((source) => source.kind)).toContain('prd_markdown');
20
- expect(analysis.uiSignals.length).toBeGreaterThan(0);
21
- expect(analysis.backendSignals.length).toBeGreaterThan(0);
22
- });
23
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=material-inventory.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"material-inventory.test.d.ts","sourceRoot":"","sources":["../../test/material-inventory.test.ts"],"names":[],"mappings":""}
@@ -1,154 +0,0 @@
1
- import { mkdirSync, mkdtempSync, writeFileSync } from 'node:fs';
2
- import os from 'node:os';
3
- import path from 'node:path';
4
- import { fileURLToPath } from 'node:url';
5
- import { describe, expect, it } from 'vitest';
6
- import { extractCodeListSummary, resolveMaterialInventory, } from '../src/index.js';
7
- describe('material inventory resolver', () => {
8
- it('maps code_list material refs to contract generation inputs', () => {
9
- const root = mkdtempSync(path.join(os.tmpdir(), 'ep-stage-material-'));
10
- const codeListPath = path.join(root, '_docs', 'code_list.md');
11
- const specPath = path.join(root, '_docs', '003-场所窗口信息管理-20260518', 'spec.yaml');
12
- const htmlPath = path.join(root, 'src/main/webapp/perpage/zwplace/gxhzwplacelist.html');
13
- const javaPath = path.join(root, 'src/main/java/com/epoint/zwplace/action/GxhZwPlaceListAction.java');
14
- const hintsPath = path.join(root, '_docs', 'zwplace.module-hints.json');
15
- mkdirSync(path.dirname(specPath), { recursive: true });
16
- mkdirSync(path.dirname(htmlPath), { recursive: true });
17
- mkdirSync(path.dirname(javaPath), { recursive: true });
18
- writeFileSync(specPath, 'module:\n id: zwplace\n');
19
- writeFileSync(htmlPath, '<html></html>');
20
- writeFileSync(javaPath, 'class GxhZwPlaceListAction {}');
21
- writeFileSync(hintsPath, '{}');
22
- writeFileSync(codeListPath, [
23
- '# 场所窗口信息管理代码清单',
24
- `> 整理目录:\`${root}\``,
25
- 'menu: 场所窗口信息管理>场所窗口信息列表',
26
- '`_docs/003-场所窗口信息管理-20260518/spec.yaml`',
27
- '`src/main/webapp/perpage/zwplace/gxhzwplacelist.html`',
28
- '`src/main/java/com/epoint/zwplace/action/GxhZwPlaceListAction.java`',
29
- '`_docs/zwplace.module-hints.json`',
30
- ].join('\n'), 'utf8');
31
- const codeList = extractCodeListSummary(codeListPath);
32
- const result = resolveMaterialInventory({
33
- codeListPath,
34
- codeList,
35
- debugOverrides: {},
36
- stageContext: {
37
- projectName: 'glue-project',
38
- projectDir: root,
39
- mode: 'glue',
40
- envPath: '.env',
41
- envFilePath: path.join(root, '.env'),
42
- knowledgeRoot: root,
43
- codeListPaths: [codeListPath],
44
- stageContextPath: path.join(root, 'stage-context.md'),
45
- },
46
- });
47
- expect(result.resolvedInputs).toMatchObject({
48
- moduleId: { status: 'resolved', value: 'zwplace' },
49
- docsDir: { status: 'resolved', path: path.dirname(specPath) },
50
- webappDir: { status: 'resolved', path: path.dirname(htmlPath) },
51
- javaActionsDir: { status: 'resolved', path: path.dirname(javaPath) },
52
- hintsPath: { status: 'resolved', path: hintsPath },
53
- menu: { status: 'resolved', value: '场所窗口信息管理>场所窗口信息列表' },
54
- });
55
- expect(result.gate.status).toBe('confirmed');
56
- });
57
- it('does not infer knowledgeRoot from _docs hierarchy when code_list lacks structured root info', () => {
58
- const root = mkdtempSync(path.join(os.tmpdir(), 'ep-stage-material-no-root-'));
59
- const codeListPath = path.join(root, '_docs', '014-测试需求10-20260622', 'code_list.md');
60
- mkdirSync(path.dirname(codeListPath), { recursive: true });
61
- writeFileSync(codeListPath, [
62
- '# 场所窗口信息管理代码清单',
63
- '`src/main/webapp/perpage/zwplace/gxhzwplacelist.html`',
64
- ].join('\n'), 'utf8');
65
- const codeList = extractCodeListSummary(codeListPath);
66
- expect(codeList.knowledgeRoot).toBeUndefined();
67
- expect(codeList.knowledgeRootSource).toBe('none');
68
- });
69
- it('stops at material gate when webapp or java actions cannot be resolved', () => {
70
- const root = mkdtempSync(path.join(os.tmpdir(), 'ep-stage-material-missing-'));
71
- const codeListPath = path.join(root, 'code_list.md');
72
- writeFileSync(codeListPath, '# 空代码清单\n');
73
- const result = resolveMaterialInventory({
74
- codeListPath,
75
- codeList: extractCodeListSummary(codeListPath),
76
- debugOverrides: {},
77
- });
78
- expect(result.gate).toMatchObject({
79
- status: 'needs_review',
80
- });
81
- expect(result.resolvedInputs.webappDir.status).toBe('missing');
82
- expect(result.resolvedInputs.javaActionsDir.status).toBe('missing');
83
- });
84
- it('supports a writable external code_list that already contains write-back fields', () => {
85
- const root = mkdtempSync(path.join(os.tmpdir(), 'ep-stage-material-writeback-'));
86
- const knowledgeRoot = path.join(root, 'knowledge-project', 'zwplace');
87
- const writableDir = path.join(root, 'agent-input');
88
- const docsPath = path.join(writableDir, 'zwplace-observable-docs', 'zwplace.context.md');
89
- const hintsPath = path.join(writableDir, 'zwplace.module-hints.json');
90
- const htmlPath = path.join(knowledgeRoot, 'src', 'main', 'webapp', 'perpage', 'zwplace', 'gxhzwplacelist.html');
91
- const javaPath = path.join(knowledgeRoot, 'src', 'main', 'java', 'com', 'epoint', 'zwplace', 'action', 'GxhZwPlaceListAction.java');
92
- const codeListPath = path.join(writableDir, 'zwplace.observable.code_list.md');
93
- mkdirSync(path.dirname(docsPath), { recursive: true });
94
- mkdirSync(path.dirname(htmlPath), { recursive: true });
95
- mkdirSync(path.dirname(javaPath), { recursive: true });
96
- writeFileSync(docsPath, '# zwplace context\n');
97
- writeFileSync(hintsPath, '{}');
98
- writeFileSync(htmlPath, '<html></html>');
99
- writeFileSync(javaPath, 'class GxhZwPlaceListAction {}');
100
- writeFileSync(codeListPath, [
101
- '# 场所窗口信息管理代码清单',
102
- `knowledgeRoot: ${knowledgeRoot}`,
103
- 'menu: 场所窗口信息管理>场所窗口信息列表',
104
- '`./zwplace-observable-docs/zwplace.context.md`',
105
- '`src/main/webapp/perpage/zwplace/gxhzwplacelist.html`',
106
- '`src/main/java/com/epoint/zwplace/action/GxhZwPlaceListAction.java`',
107
- '`./zwplace.module-hints.json`',
108
- ].join('\n'), 'utf8');
109
- const codeList = extractCodeListSummary(codeListPath);
110
- const result = resolveMaterialInventory({
111
- codeListPath,
112
- codeList,
113
- debugOverrides: {},
114
- });
115
- expect(codeList.knowledgeRoot).toBe(knowledgeRoot);
116
- expect(codeList.knowledgeRootSource).toBe('code_list');
117
- expect(codeList.menu).toBe('场所窗口信息管理>场所窗口信息列表');
118
- expect(result.resolvedInputs).toMatchObject({
119
- docsDir: { status: 'resolved', path: path.dirname(docsPath) },
120
- webappDir: { status: 'resolved', path: path.dirname(htmlPath) },
121
- javaActionsDir: { status: 'resolved', path: path.dirname(javaPath) },
122
- hintsPath: { status: 'resolved', path: hintsPath },
123
- menu: { status: 'resolved', value: '场所窗口信息管理>场所窗口信息列表' },
124
- });
125
- });
126
- it('resolves the checked-in writable schemeresource code_list example', () => {
127
- const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
128
- const examplesDir = path.join(packageRoot, 'examples');
129
- const codeListPath = path.join(examplesDir, 'schemeresource.observable.code_list.md');
130
- const knowledgeRoot = path.resolve(examplesDir, '../../../knowledge-project/epoint-web-v9.5.2');
131
- const docsDir = path.join(examplesDir, 'schemeresource-observable-docs');
132
- const webappDir = path.join(knowledgeRoot, 'src', 'main', 'webapp', 'perpage', 'schemeresource');
133
- const javaActionsDir = path.join(knowledgeRoot, 'src', 'main', 'java', 'com', 'epoint', 'schemeresource', 'action');
134
- const hintsPath = path.join(examplesDir, 'schemeresource.module-hints.json');
135
- const codeList = extractCodeListSummary(codeListPath);
136
- const result = resolveMaterialInventory({
137
- codeListPath,
138
- codeList,
139
- debugOverrides: {},
140
- });
141
- expect(codeList.knowledgeRoot).toBe(knowledgeRoot);
142
- expect(codeList.knowledgeRootSource).toBe('code_list');
143
- expect(codeList.menu).toBe('方案资源文档>方案资源文档列表');
144
- expect(result.resolvedInputs).toMatchObject({
145
- moduleId: { status: 'resolved', value: 'schemeresource' },
146
- docsDir: { status: 'resolved', path: docsDir },
147
- webappDir: { status: 'resolved', path: webappDir },
148
- javaActionsDir: { status: 'resolved', path: javaActionsDir },
149
- hintsPath: { status: 'resolved', path: hintsPath },
150
- menu: { status: 'resolved', value: '方案资源文档>方案资源文档列表' },
151
- });
152
- expect(result.gate.status).toBe('confirmed');
153
- });
154
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=observable-chain.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"observable-chain.test.d.ts","sourceRoot":"","sources":["../../test/observable-chain.test.ts"],"names":[],"mappings":""}
@@ -1,123 +0,0 @@
1
- import { mkdtempSync, readFileSync, existsSync } from 'node:fs';
2
- import os from 'node:os';
3
- import path from 'node:path';
4
- import { describe, expect, it } from 'vitest';
5
- import { createTraceWriter, renderReviewSummary, } from '../src/index.js';
6
- describe('observable glue chain trace writer', () => {
7
- function createScenarioPayload() {
8
- return {
9
- stage: 'scenario-inference',
10
- stageLabel: '场景推理追踪',
11
- inputs: [{ kind: 'code_list', path: '/repo/knowledge/_docs/code_list.md' }],
12
- outputs: [{ kind: 'scenario', path: 'scenario-inference.json' }],
13
- reasoningSummary: {
14
- conclusion: '当前页面是嵌套 CRUD 候选。',
15
- evidenceChain: [
16
- {
17
- source: 'html',
18
- path: '/repo/webapp/gxhzwplaceadd.html',
19
- text: '弹窗页面中存在 mini-datagrid 与 添加窗口 按钮',
20
- },
21
- ],
22
- alternatives: ['crud.single-page', 'crud.nested'],
23
- confidence: 'medium',
24
- risks: ['子表保存后断言未确认'],
25
- needsHumanReview: true,
26
- },
27
- candidateCount: 1,
28
- unresolvedCount: 1,
29
- gate: {
30
- status: 'needs_review',
31
- reason: '需要人工确认嵌套 CRUD 是否进入 testcase。',
32
- },
33
- };
34
- }
35
- it('writes stage json and summary markdown with reviewable reasoning', () => {
36
- const projectDir = mkdtempSync(path.join(os.tmpdir(), 'ep-stage-trace-'));
37
- const writer = createTraceWriter({
38
- projectDir,
39
- runId: '20260616T120000Z-demo',
40
- codeListPath: '/repo/knowledge/_docs/code_list.md',
41
- });
42
- const payload = createScenarioPayload();
43
- const stagePath = writer.writeStage('scenario-inference', payload);
44
- const summaryPath = writer.writeSummary([
45
- {
46
- stage: 'scenario-inference',
47
- stageLabel: '场景推理追踪',
48
- status: 'needs_review',
49
- conclusion: payload.reasoningSummary?.conclusion ?? '',
50
- needsHumanReview: true,
51
- },
52
- ]);
53
- const traceDir = path.join(projectDir, '.stage', 'trace', '20260616T120000Z-demo');
54
- expect(writer.runId).toBe('20260616T120000Z-demo');
55
- expect(stagePath).toBe(path.join(traceDir, 'scenario-inference.json'));
56
- expect(summaryPath).toBe(path.join(traceDir, 'summary.md'));
57
- expect(existsSync(path.join(traceDir, 'scenario-inference.json'))).toBe(true);
58
- expect(JSON.parse(readFileSync(path.join(traceDir, 'scenario-inference.json'), 'utf8'))).toMatchObject({
59
- stage: 'scenario-inference',
60
- reasoningSummary: {
61
- confidence: 'medium',
62
- needsHumanReview: true,
63
- },
64
- });
65
- expect(readFileSync(path.join(traceDir, 'summary.md'), 'utf8')).toContain('场景推理追踪');
66
- expect(readFileSync(path.join(traceDir, 'summary.md'), 'utf8')).toContain('需要人工确认');
67
- });
68
- it('rejects stage write when file stage does not match payload stage', () => {
69
- const projectDir = mkdtempSync(path.join(os.tmpdir(), 'ep-stage-trace-'));
70
- const writer = createTraceWriter({
71
- projectDir,
72
- runId: '20260616T120000Z-demo',
73
- codeListPath: '/repo/knowledge/_docs/code_list.md',
74
- });
75
- expect(() => writer.writeStage('coverage-diff', createScenarioPayload())).toThrow('trace stage mismatch');
76
- });
77
- it('rejects unsafe run id path segments', () => {
78
- const projectDir = mkdtempSync(path.join(os.tmpdir(), 'ep-stage-trace-'));
79
- const unsafeRunIds = ['../escape', 'nested/run', '/tmp/escape', 'trace..escape', '.', ''];
80
- for (const runId of unsafeRunIds) {
81
- expect(() => createTraceWriter({
82
- projectDir,
83
- runId,
84
- codeListPath: '/repo/knowledge/_docs/code_list.md',
85
- })).toThrow('invalid trace runId');
86
- }
87
- });
88
- it('renders human-readable review summary for conversation output', () => {
89
- const text = renderReviewSummary({
90
- title: '场景推理需要确认',
91
- reasoningSummary: {
92
- conclusion: '当前页面是嵌套 CRUD 候选。',
93
- evidenceChain: [
94
- { source: 'html', path: 'gxhzwplaceadd.html', text: 'mini-datagrid + 添加窗口' },
95
- ],
96
- alternatives: ['crud.single-page', 'crud.nested'],
97
- confidence: 'medium',
98
- risks: ['子表保存后断言未确认'],
99
- needsHumanReview: true,
100
- },
101
- nextAction: 'confirm / correct / add-evidence / skip',
102
- });
103
- expect(text).toContain('结论:当前页面是嵌套 CRUD 候选。');
104
- expect(text).toContain('证据链:');
105
- expect(text).toContain('待确认项:子表保存后断言未确认');
106
- expect(text).toContain('下一步:confirm / correct / add-evidence / skip');
107
- });
108
- it('renders empty evidence chain explicitly for review summary', () => {
109
- const text = renderReviewSummary({
110
- title: '场景推理需要确认',
111
- reasoningSummary: {
112
- conclusion: '当前证据不足。',
113
- evidenceChain: [],
114
- alternatives: [],
115
- confidence: 'low',
116
- risks: [],
117
- needsHumanReview: true,
118
- },
119
- nextAction: 'add-evidence',
120
- });
121
- expect(text).toContain('证据链:\n- 无');
122
- });
123
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=observable-pipeline.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"observable-pipeline.test.d.ts","sourceRoot":"","sources":["../../test/observable-pipeline.test.ts"],"names":[],"mappings":""}