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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/SKILL.md +2 -2
  2. package/codex-skill/ep-stage/.omc/state/sessions/d636ad35-5fc9-4d5e-85b0-2bcad7d86ee5/pre-tool-advisory-throttle.json +10 -0
  3. package/codex-skill/ep-stage/glue-create-project/SKILL.md +206 -0
  4. package/codex-skill/ep-stage/glue-generate-testcase/SKILL.md +274 -0
  5. package/codex-skill/ep-stage/glue-generate-testcase/references/testcase-schema.md +112 -0
  6. package/codex-skill/ep-stage/glue-generate-testcase/references/testcase-tpl.md +72 -0
  7. package/codex-skill/ep-stage/glue-run-test/SKILL.md +289 -0
  8. package/codex-skill/ep-stage/glue-run-test/references/crud-pipeline.md +145 -0
  9. package/codex-skill/ep-stage/{glue-test → glue-run-test}/scripts/generate-crud-spec.mjs +3 -3
  10. package/codex-skill/ep-stage/recording-to-glue/SKILL.md +1 -0
  11. package/codex-skill/ep-stage/scripts/validate-skill.mjs +29 -7
  12. package/dist/src/cli/dev/extract-contract.d.ts +14 -0
  13. package/dist/src/cli/dev/extract-contract.d.ts.map +1 -0
  14. package/dist/src/cli/dev/extract-contract.js +114 -0
  15. package/dist/src/cli/generate-crud-contract.js +7 -77
  16. package/dist/src/cli/generate-playwright-tests.d.ts +0 -28
  17. package/dist/src/cli/generate-playwright-tests.d.ts.map +1 -1
  18. package/dist/src/cli/generate-playwright-tests.js +4 -81
  19. package/dist/src/cli/generate-testcase.d.ts +84 -0
  20. package/dist/src/cli/generate-testcase.d.ts.map +1 -0
  21. package/dist/src/cli/generate-testcase.js +300 -0
  22. package/dist/src/cli/index.d.ts +26 -0
  23. package/dist/src/cli/index.d.ts.map +1 -0
  24. package/dist/src/cli/index.js +75 -0
  25. package/dist/src/cli/probe.d.ts +46 -0
  26. package/dist/src/cli/probe.d.ts.map +1 -0
  27. package/dist/src/cli/probe.js +447 -0
  28. package/dist/src/cli/run-gap-pipeline.js +4 -0
  29. package/dist/src/cli/run.d.ts +63 -0
  30. package/dist/src/cli/run.d.ts.map +1 -0
  31. package/dist/src/cli/run.js +116 -0
  32. package/dist/src/cli/spec.d.ts +48 -0
  33. package/dist/src/cli/spec.d.ts.map +1 -0
  34. package/dist/src/cli/spec.js +102 -0
  35. package/dist/src/context/stage-context.d.ts +72 -8
  36. package/dist/src/context/stage-context.d.ts.map +1 -1
  37. package/dist/src/context/stage-context.js +61 -15
  38. package/dist/src/contracts/inference-trace.d.ts +223 -0
  39. package/dist/src/contracts/inference-trace.d.ts.map +1 -0
  40. package/dist/src/contracts/inference-trace.js +12 -0
  41. package/dist/src/extractors/code-list.d.ts +3 -3
  42. package/dist/src/extractors/code-list.d.ts.map +1 -1
  43. package/dist/src/extractors/code-list.js +46 -11
  44. package/dist/src/generators/stage-skeleton-script.d.ts.map +1 -1
  45. package/dist/src/generators/stage-skeleton-script.js +9 -0
  46. package/dist/src/index.d.ts +7 -2
  47. package/dist/src/index.d.ts.map +1 -1
  48. package/dist/src/index.js +3 -1
  49. package/dist/src/inference/module-hints-inference.d.ts +30 -0
  50. package/dist/src/inference/module-hints-inference.d.ts.map +1 -0
  51. package/dist/src/inference/module-hints-inference.js +363 -0
  52. package/dist/src/inference/source-analysis.d.ts +26 -0
  53. package/dist/src/inference/source-analysis.d.ts.map +1 -0
  54. package/dist/src/inference/source-analysis.js +258 -0
  55. package/dist/src/testcase/testcase-generator.d.ts.map +1 -1
  56. package/dist/src/testcase/testcase-generator.js +4 -0
  57. package/dist/src/testcase/testcase-v2.d.ts +50 -0
  58. package/dist/src/testcase/testcase-v2.d.ts.map +1 -0
  59. package/dist/src/testcase/testcase-v2.js +1 -0
  60. package/dist/src/util/credentials.d.ts +12 -0
  61. package/dist/src/util/credentials.d.ts.map +1 -0
  62. package/dist/src/util/credentials.js +19 -0
  63. package/dist/src/util/i18n-testcase.d.ts +8 -0
  64. package/dist/src/util/i18n-testcase.d.ts.map +1 -0
  65. package/dist/src/util/i18n-testcase.js +55 -0
  66. package/dist/src/util/softlink.d.ts +33 -0
  67. package/dist/src/util/softlink.d.ts.map +1 -0
  68. package/dist/src/util/softlink.js +43 -0
  69. package/dist/src/validation/credentials.d.ts +19 -0
  70. package/dist/src/validation/credentials.d.ts.map +1 -0
  71. package/dist/src/validation/credentials.js +38 -0
  72. package/dist/src/validation/index.d.ts +6 -0
  73. package/dist/src/validation/index.d.ts.map +1 -0
  74. package/dist/src/validation/index.js +4 -0
  75. package/dist/src/validation/inference-trace.d.ts +13 -0
  76. package/dist/src/validation/inference-trace.d.ts.map +1 -0
  77. package/dist/src/validation/inference-trace.js +31 -0
  78. package/dist/src/validation/projects-index.d.ts +13 -0
  79. package/dist/src/validation/projects-index.d.ts.map +1 -0
  80. package/dist/src/validation/projects-index.js +37 -0
  81. package/dist/src/validation/testcase.d.ts +13 -0
  82. package/dist/src/validation/testcase.d.ts.map +1 -0
  83. package/dist/src/validation/testcase.js +53 -0
  84. package/dist/test/cli/extract-contract.test.d.ts +2 -0
  85. package/dist/test/cli/extract-contract.test.d.ts.map +1 -0
  86. package/dist/test/cli/extract-contract.test.js +32 -0
  87. package/dist/test/cli/generate-testcase-inference.test.d.ts +2 -0
  88. package/dist/test/cli/generate-testcase-inference.test.d.ts.map +1 -0
  89. package/dist/test/cli/generate-testcase-inference.test.js +63 -0
  90. package/dist/test/cli/generate-testcase-paths.test.d.ts +2 -0
  91. package/dist/test/cli/generate-testcase-paths.test.d.ts.map +1 -0
  92. package/dist/test/cli/generate-testcase-paths.test.js +165 -0
  93. package/dist/test/cli/generate-testcase-requirements.test.d.ts +2 -0
  94. package/dist/test/cli/generate-testcase-requirements.test.d.ts.map +1 -0
  95. package/dist/test/cli/generate-testcase-requirements.test.js +229 -0
  96. package/dist/test/cli/generate-testcase.test.d.ts +2 -0
  97. package/dist/test/cli/generate-testcase.test.d.ts.map +1 -0
  98. package/dist/test/cli/generate-testcase.test.js +130 -0
  99. package/dist/test/cli/index.test.d.ts +2 -0
  100. package/dist/test/cli/index.test.d.ts.map +1 -0
  101. package/dist/test/cli/index.test.js +113 -0
  102. package/dist/test/cli/probe.test.d.ts +2 -0
  103. package/dist/test/cli/probe.test.d.ts.map +1 -0
  104. package/dist/test/cli/probe.test.js +31 -0
  105. package/dist/test/cli/run.test.d.ts +2 -0
  106. package/dist/test/cli/run.test.d.ts.map +1 -0
  107. package/dist/test/cli/run.test.js +149 -0
  108. package/dist/test/cli/spec-boundary.test.d.ts +2 -0
  109. package/dist/test/cli/spec-boundary.test.d.ts.map +1 -0
  110. package/dist/test/cli/spec-boundary.test.js +198 -0
  111. package/dist/test/cli/spec.test.d.ts +2 -0
  112. package/dist/test/cli/spec.test.d.ts.map +1 -0
  113. package/dist/test/cli/spec.test.js +196 -0
  114. package/dist/test/code-list.test.d.ts +2 -0
  115. package/dist/test/code-list.test.d.ts.map +1 -0
  116. package/dist/test/code-list.test.js +39 -0
  117. package/dist/test/crud-contract.test.js +12 -32
  118. package/dist/test/inference/module-hints-inference.test.d.ts +2 -0
  119. package/dist/test/inference/module-hints-inference.test.d.ts.map +1 -0
  120. package/dist/test/inference/module-hints-inference.test.js +25 -0
  121. package/dist/test/inference/source-analysis.test.d.ts +2 -0
  122. package/dist/test/inference/source-analysis.test.d.ts.map +1 -0
  123. package/dist/test/inference/source-analysis.test.js +23 -0
  124. package/dist/test/material-inventory.test.js +13 -0
  125. package/dist/test/observable-pipeline.test.js +12 -3
  126. package/dist/test/stage-context.test.js +145 -13
  127. package/dist/test/util/credentials.test.d.ts +2 -0
  128. package/dist/test/util/credentials.test.d.ts.map +1 -0
  129. package/dist/test/util/credentials.test.js +64 -0
  130. package/dist/test/util/i18n-testcase.test.d.ts +2 -0
  131. package/dist/test/util/i18n-testcase.test.d.ts.map +1 -0
  132. package/dist/test/util/i18n-testcase.test.js +119 -0
  133. package/dist/test/util/softlink.test.d.ts +2 -0
  134. package/dist/test/util/softlink.test.d.ts.map +1 -0
  135. package/dist/test/util/softlink.test.js +82 -0
  136. package/dist/test/validation/credentials.test.d.ts +2 -0
  137. package/dist/test/validation/credentials.test.d.ts.map +1 -0
  138. package/dist/test/validation/credentials.test.js +72 -0
  139. package/dist/test/validation/projects-index.test.d.ts +2 -0
  140. package/dist/test/validation/projects-index.test.d.ts.map +1 -0
  141. package/dist/test/validation/projects-index.test.js +48 -0
  142. package/dist/test/validation/testcase.test.d.ts +2 -0
  143. package/dist/test/validation/testcase.test.d.ts.map +1 -0
  144. package/dist/test/validation/testcase.test.js +129 -0
  145. package/docs/README.md +6 -6
  146. package/docs/mvp-usage-guide.md +3 -3
  147. package/package.json +9 -4
  148. package/codex-skill/ep-stage/create-project/SKILL.md +0 -59
  149. package/codex-skill/ep-stage/glue-test/SKILL.md +0 -258
  150. package/codex-skill/ep-stage/glue-test/references/crud-pipeline.md +0 -139
  151. package/codex-skill/ep-stage/glue-testcase/SKILL.md +0 -31
  152. package/codex-skill/ep-stage/glue-testcase/references/testcase-schema.md +0 -67
  153. /package/codex-skill/ep-stage/{glue-testcase → glue-generate-testcase}/examples/observable-testcase.json +0 -0
  154. /package/codex-skill/ep-stage/{glue-test → glue-run-test}/references/gap-review-protocol.md +0 -0
  155. /package/codex-skill/ep-stage/{glue-test → glue-run-test}/references/harness-principles.md +0 -0
@@ -57,6 +57,24 @@ function extractDeclaredKnowledgeRoot(content, filePath) {
57
57
  const rawValue = cleanScalarValue(match[1]);
58
58
  return path.isAbsolute(rawValue) ? rawValue : path.resolve(path.dirname(filePath), rawValue);
59
59
  }
60
+ /**
61
+ * 解析 code_list.md 中“整理目录”声明的上游源码根。
62
+ *
63
+ * 支持格式:
64
+ * - `> 整理目录:`/abs/path``
65
+ * - `> 整理目录: /abs/path`
66
+ *
67
+ * @param content - code_list.md 文本内容。
68
+ * @returns 整理目录绝对路径;缺失或非绝对路径时返回 undefined。
69
+ */
70
+ function extractOrganizeRoot(content) {
71
+ const match = content.match(/^>\s*整理目录[::]\s*`?(.+?)`?\s*$/m);
72
+ if (!match?.[1]) {
73
+ return undefined;
74
+ }
75
+ const candidate = cleanScalarValue(match[1]);
76
+ return path.isAbsolute(candidate) ? candidate : undefined;
77
+ }
60
78
  /**
61
79
  * 提取 code_list.md 顶层标量字段。
62
80
  *
@@ -79,12 +97,27 @@ function cleanScalarValue(value) {
79
97
  /**
80
98
  * 解析 code_list.md 中声明的菜单路由。
81
99
  *
100
+ * 人工读写约定:code_list.md 用中文键「菜单」,与「整理目录」同风格,
101
+ * 支持 blockquote 形式 `> 菜单:一级菜单>二级菜单` 与裸行 `菜单: …`(反引号包裹可选)。
102
+ * 同时向后兼容英文键 menu / menuPath(编码内部字段名仍为 menu)。
103
+ *
82
104
  * @param content - code_list.md 文本内容。
83
105
  * @returns 菜单路由;未声明时返回 undefined。
84
106
  */
85
107
  function extractDeclaredMenu(content) {
86
- const match = extractScalar(content, 'menu') ?? extractScalar(content, 'menuPath');
87
- return match?.[1] ? cleanScalarValue(match[1]) : undefined;
108
+ // 优先:中文键「菜单」blockquote 形式(与「整理目录」同风格,反引号包裹可选)
109
+ const blockquoteMatch = content.match(/^>\s*菜单[::]\s*`?(.+?)`?\s*$/m);
110
+ if (blockquoteMatch?.[1]) {
111
+ const value = cleanScalarValue(blockquoteMatch[1]);
112
+ if (value) {
113
+ return value;
114
+ }
115
+ }
116
+ // 裸行标量形式:菜单 / menu / menuPath(向后兼容英文键)
117
+ const scalarMatch = extractScalar(content, '菜单') ??
118
+ extractScalar(content, 'menu') ??
119
+ extractScalar(content, 'menuPath');
120
+ return scalarMatch?.[1] ? cleanScalarValue(scalarMatch[1]) : undefined;
88
121
  }
89
122
  /**
90
123
  * 解析本次 code_list 应使用的上游物料根路径。
@@ -105,17 +138,20 @@ function resolveKnowledgeRoot(content, filePath, options) {
105
138
  source: 'code_list',
106
139
  };
107
140
  }
108
- if (options.knowledgeRoot) {
141
+ const organizeRoot = extractOrganizeRoot(content);
142
+ if (organizeRoot) {
143
+ if (!existsSync(organizeRoot)) {
144
+ throw new Error(`code_list.md 声明的整理目录不存在:${organizeRoot}`);
145
+ }
109
146
  return {
110
- knowledgeRoot: path.resolve(options.knowledgeRoot),
111
- source: 'input',
147
+ knowledgeRoot: organizeRoot,
148
+ source: 'code_list',
112
149
  };
113
150
  }
114
- const codeListDir = path.dirname(filePath);
115
- if (path.basename(codeListDir) === '_docs') {
151
+ if (options.knowledgeRoot) {
116
152
  return {
117
- knowledgeRoot: path.dirname(codeListDir),
118
- source: 'inferred',
153
+ knowledgeRoot: path.resolve(options.knowledgeRoot),
154
+ source: 'input',
119
155
  };
120
156
  }
121
157
  return {
@@ -123,7 +159,7 @@ function resolveKnowledgeRoot(content, filePath, options) {
123
159
  };
124
160
  }
125
161
  /**
126
- * 按 knowledge-root / code_list 所在目录 / `_docs/` 父目录的顺序产生候选根目录。
162
+ * 按 knowledgeRoot / code_list 所在目录顺序产生候选根目录。
127
163
  *
128
164
  * @param filePath - code_list.md 的绝对路径。
129
165
  * @param knowledgeRoot - 显式知识库根(可选)。
@@ -134,7 +170,6 @@ function materialRoots(filePath, knowledgeRoot) {
134
170
  return [
135
171
  ...(knowledgeRoot ? [knowledgeRoot] : []),
136
172
  codeListDir,
137
- ...(path.basename(codeListDir) === '_docs' ? [path.dirname(codeListDir)] : []),
138
173
  ];
139
174
  }
140
175
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"stage-skeleton-script.d.ts","sourceRoot":"","sources":["../../../src/generators/stage-skeleton-script.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,0BAA0B,EAAiF,MAAM,sCAAsC,CAAC;AAEtK,MAAM,MAAM,6BAA6B,GAAG,gBAAgB,GAAG,0BAA0B,CAAC;AAC1F,MAAM,MAAM,kCAAkC,GAAG,kBAAkB,GAAG,aAAa,CAAC;AAEpF,MAAM,MAAM,qCAAqC,GAAG;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,yCAAyC,GAAG;IACtD,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,kCAAkC,CAAC;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,2CAA2C,GAAG;IACxD,SAAS,EAAE,SAAS,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,CAAC,EAAE,qCAAqC,EAAE,CAAC;CAC5D,CAAC;AAEF,MAAM,MAAM,oCAAoC,GAC5C,yCAAyC,GACzC,2CAA2C,CAAC;AAEhD;;;;;GAKG;AACH,MAAM,MAAM,0BAA0B,GAAG;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,oCAAoC,EAAE,CAAC;IACzD,MAAM,EAAE;QACN,oBAAoB,EAAE,MAAM,CAAC;QAC7B,mBAAmB,EAAE,MAAM,CAAC;QAC5B,oBAAoB,EAAE,MAAM,CAAC;KAC9B,CAAC;IACF,QAAQ,EAAE;QACR,YAAY,EAAE,MAAM,CAAC;QACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,aAAa,EAAE,MAAM,CAAC;QACtB,gBAAgB,EAAE,MAAM,CAAC;QACzB,8BAA8B,EAAE,MAAM,CAAC;QACvC,6BAA6B,EAAE,MAAM,CAAC;QACtC,cAAc,EAAE,MAAM,CAAC;QACvB,4BAA4B,EAAE,MAAM,CAAC;QACrC,gBAAgB,EAAE,MAAM,CAAC;QACzB,mBAAmB,CAAC,EAAE,MAAM,CAAC;KAC9B,CAAC;IACF,UAAU,EAAE;QACV,YAAY,EAAE,6BAA6B,CAAC;QAC5C,oBAAoB,CAAC,EAAE,MAAM,CAAC;KAC/B,CAAC;CACH,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,0BAA0B,GAAG;IACvC,QAAQ,EAAE,0BAA0B,CAAC;IACrC,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AA+QF;;;;;;GAMG;AACH,wBAAgB,mCAAmC,CAAC,QAAQ,EAAE,0BAA0B,GAAG,0BAA0B,CA0CpH;AA6DD;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,0BAA0B,GAAG,MAAM,CAwBtF;AAwBD;;;;;;;;;GASG;AACH,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,0BAA0B,GAAG,MAAM,CAoMzF"}
1
+ {"version":3,"file":"stage-skeleton-script.d.ts","sourceRoot":"","sources":["../../../src/generators/stage-skeleton-script.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,0BAA0B,EAAiF,MAAM,sCAAsC,CAAC;AAEtK,MAAM,MAAM,6BAA6B,GAAG,gBAAgB,GAAG,0BAA0B,CAAC;AAC1F,MAAM,MAAM,kCAAkC,GAAG,kBAAkB,GAAG,aAAa,CAAC;AAEpF,MAAM,MAAM,qCAAqC,GAAG;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,yCAAyC,GAAG;IACtD,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,kCAAkC,CAAC;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,2CAA2C,GAAG;IACxD,SAAS,EAAE,SAAS,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,CAAC,EAAE,qCAAqC,EAAE,CAAC;CAC5D,CAAC;AAEF,MAAM,MAAM,oCAAoC,GAC5C,yCAAyC,GACzC,2CAA2C,CAAC;AAEhD;;;;;GAKG;AACH,MAAM,MAAM,0BAA0B,GAAG;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,oCAAoC,EAAE,CAAC;IACzD,MAAM,EAAE;QACN,oBAAoB,EAAE,MAAM,CAAC;QAC7B,mBAAmB,EAAE,MAAM,CAAC;QAC5B,oBAAoB,EAAE,MAAM,CAAC;KAC9B,CAAC;IACF,QAAQ,EAAE;QACR,YAAY,EAAE,MAAM,CAAC;QACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,aAAa,EAAE,MAAM,CAAC;QACtB,gBAAgB,EAAE,MAAM,CAAC;QACzB,8BAA8B,EAAE,MAAM,CAAC;QACvC,6BAA6B,EAAE,MAAM,CAAC;QACtC,cAAc,EAAE,MAAM,CAAC;QACvB,4BAA4B,EAAE,MAAM,CAAC;QACrC,gBAAgB,EAAE,MAAM,CAAC;QACzB,mBAAmB,CAAC,EAAE,MAAM,CAAC;KAC9B,CAAC;IACF,UAAU,EAAE;QACV,YAAY,EAAE,6BAA6B,CAAC;QAC5C,oBAAoB,CAAC,EAAE,MAAM,CAAC;KAC/B,CAAC;CACH,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,0BAA0B,GAAG;IACvC,QAAQ,EAAE,0BAA0B,CAAC;IACrC,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAuRF;;;;;;GAMG;AACH,wBAAgB,mCAAmC,CAAC,QAAQ,EAAE,0BAA0B,GAAG,0BAA0B,CA0CpH;AA6DD;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,0BAA0B,GAAG,MAAM,CAwBtF;AAwBD;;;;;;;;;GASG;AACH,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,0BAA0B,GAAG,MAAM,CAoMzF"}
@@ -184,6 +184,13 @@ function findBlockedDeleteMessage(contract) {
184
184
  /**
185
185
  * 将契约中的数据生成策略映射为骨架支持的策略。
186
186
  *
187
+ * 设计取舍:契约把"测试人员定"的策略标成 `human_required`(属于 unresolvedSlots,由 tester 决策)。
188
+ * 但 spec 组装阶段缺少喂策略的顺滑入口(spec CLI 不收 hints、contract 禁手编),
189
+ * 若硬抛错会导致测试人员审过用例后仍卡死。
190
+ * 故 `human_required` / 缺省时统一**默认到 `timestamp_prefix`**——这正是 unresolvedSlots
191
+ * `suggestedFormat` 自身给出的建议值,也是 CRUD 冒烟造唯一数据的标配;
192
+ * unresolvedSlots 仍保留作审计标记,测试人员后续可通过 ModuleHints 显式覆盖。
193
+ *
187
194
  * @param strategy 契约数据生成策略
188
195
  * @returns 骨架数据生成策略
189
196
  */
@@ -192,6 +199,8 @@ function mapDataStrategy(strategy) {
192
199
  return 'fixed_value';
193
200
  if (strategy === 'timestamp_prefix')
194
201
  return 'timestamp_prefix';
202
+ if (strategy === 'human_required' || strategy === undefined)
203
+ return 'timestamp_prefix';
195
204
  throw new Error(`当前数据生成策略无法自动映射到 CrudFlowSlots: ${strategy}`);
196
205
  }
197
206
  /**
@@ -15,8 +15,8 @@ export type { ActionCandidate, AgentInferredWorkflow, GapActionType, GapExplorat
15
15
  export type { ObservableArtifactRef, ObservableGate, ObservableStageName, ObservableStagePayload, ObservableStageSummary, ReasoningEvidence, ReasoningSummary, TraceWriterOptions } from './contracts/observable-chain.js';
16
16
  export { createTraceWriter, } from './trace/trace-writer.js';
17
17
  export type { TraceWriter, } from './trace/trace-writer.js';
18
- export { readStageContext, resolveStageContext, writeProjectIndex, } from './context/stage-context.js';
19
- export type { ProjectIndex, ProjectIndexEntry, ResolveStageContextInput, ResolveStageContextResult, StageContext, StageContextMode, } from './context/stage-context.js';
18
+ export { lookupProjectByRequirement, readStageContext, resolveStageContext, writeProjectIndex, } from './context/stage-context.js';
19
+ export type { LookupProjectByRequirementInput, ProjectIndex, ProjectIndexEntry, ProjectsIndex, RequirementEntry, ResolveStageContextInput, ResolveStageContextResult, StageContext, StageContextMode, SystemEntry, } from './context/stage-context.js';
20
20
  export { renderReviewSummary, } from './trace/review-summary.js';
21
21
  export type { ReviewSummaryInput, } from './trace/review-summary.js';
22
22
  export { collectActionCandidates, } from './gap-planner/action-candidates.js';
@@ -49,4 +49,9 @@ export { glueReportToTrace, glueSpecAssemblyToTrace, playwrightExecutionToTrace,
49
49
  export type { GlueReportSummary, GlueSpecAssemblySummary, PlaywrightExecutionSummary, } from './cli/run-gap-pipeline.js';
50
50
  export { compareObservableRuns, summarizeGeneralizationRun, } from './generalization/generalization-eval.js';
51
51
  export type { GeneralizationComparison, GeneralizationRunMetrics, MaterialResolutionStatus, SummarizeGeneralizationRunInput, } from './generalization/generalization-eval.js';
52
+ export { buildSourceAnalysis } from './inference/source-analysis.js';
53
+ export type { BuildSourceAnalysisInput } from './inference/source-analysis.js';
54
+ export { inferModuleHintsFromMaterials } from './inference/module-hints-inference.js';
55
+ export type { InferModuleHintsInput } from './inference/module-hints-inference.js';
56
+ export type { BackendSignal, CustomWorkflowInference, DataKeyInference, DeletePolicyInference, InferenceTraceV1, MaterialInventoryTrace, MaterialSlotStatus, ModuleHintsInference, SearchConditionInference, SourceAnalysis, SourceAnalysisEntry, SourceAnalysisMode, UiSignal } from './contracts/inference-trace.js';
52
57
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
package/dist/src/index.js CHANGED
@@ -5,7 +5,7 @@ export { extractJavaAction } from './extractors/java-action.js';
5
5
  export { buildCrudBusinessModuleContract } from './normalizers/crud-contract.js';
6
6
  export { generateStageSkeletonCrudSpec, mapContractToStageSkeletonCrudSlots, renderStageSkeletonCrudSlots } from './generators/stage-skeleton-script.js';
7
7
  export { createTraceWriter, } from './trace/trace-writer.js';
8
- export { readStageContext, resolveStageContext, writeProjectIndex, } from './context/stage-context.js';
8
+ export { lookupProjectByRequirement, readStageContext, resolveStageContext, writeProjectIndex, } from './context/stage-context.js';
9
9
  export { renderReviewSummary, } from './trace/review-summary.js';
10
10
  export { collectActionCandidates, } from './gap-planner/action-candidates.js';
11
11
  export { createSkeletonCoverage, } from './gap-planner/skeleton-coverage.js';
@@ -24,3 +24,5 @@ export { applyCodeListWriteBack, collectCodeListMaterialRefsFromPath, isProtecte
24
24
  export { createRuntimeFailureSummary, extractLoginSystemUrlFromEnvFile, parseRuntimeSummaryOutput, runtimeSummaryToTrace, } from './cli/run-gap-pipeline.js';
25
25
  export { glueReportToTrace, glueSpecAssemblyToTrace, playwrightExecutionToTrace, } from './cli/run-gap-pipeline.js';
26
26
  export { compareObservableRuns, summarizeGeneralizationRun, } from './generalization/generalization-eval.js';
27
+ export { buildSourceAnalysis } from './inference/source-analysis.js';
28
+ export { inferModuleHintsFromMaterials } from './inference/module-hints-inference.js';
@@ -0,0 +1,30 @@
1
+ import type { ExtractedHtmlPage, ExtractedJavaAction } from '../index.js';
2
+ import type { ModuleHints } from '../contracts/crud-business-module.js';
3
+ import type { ModuleHintsInference, SourceAnalysis } from '../contracts/inference-trace.js';
4
+ /**
5
+ * inferModuleHintsFromMaterials 的输入参数。
6
+ */
7
+ export type InferModuleHintsInput = {
8
+ sourceAnalysis: SourceAnalysis;
9
+ pages: ExtractedHtmlPage[];
10
+ actions: ExtractedJavaAction[];
11
+ explicitHints?: ModuleHints;
12
+ };
13
+ /**
14
+ * 基于上游物料推理 ModuleHints 动态槽位。
15
+ *
16
+ * 推理规则:
17
+ * - dataKey.selectedField 优先选同时出现在列表页搜索区、表格列、新增/编辑页表单的 input 字段。
18
+ * - searchConditions 至少包含 dataKey input 条件;listbox 条件缺取值时只进 unresolved。
19
+ * - buttonAliases 从页面按钮标签归类(新增、搜索、修改、删除、确定、导出)。
20
+ * - deletePolicy 若 Java messages 含"不可删除",推为 blocked_by_business_rule。
21
+ * - customWorkflows 收集 CRUD/Export 骨架之外的工具栏按钮;有 Java callback 时填 assertion,否则 unresolved。
22
+ *
23
+ * @param input - 输入参数(sourceAnalysis、pages、actions、可选 explicitHints)。
24
+ * @returns 推理出的 hints 与推理过程。
25
+ */
26
+ export declare function inferModuleHintsFromMaterials(input: InferModuleHintsInput): {
27
+ hints: ModuleHints;
28
+ inference: ModuleHintsInference;
29
+ };
30
+ //# sourceMappingURL=module-hints-inference.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module-hints-inference.d.ts","sourceRoot":"","sources":["../../../src/inference/module-hints-inference.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EACV,WAAW,EAEZ,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAIV,oBAAoB,EAEpB,cAAc,EACf,MAAM,iCAAiC,CAAC;AAEzC;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,cAAc,EAAE,cAAc,CAAC;IAC/B,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,aAAa,CAAC,EAAE,WAAW,CAAC;CAC7B,CAAC;AA4UF;;;;;;;;;;;;GAYG;AACH,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,qBAAqB,GAAG;IAC3E,KAAK,EAAE,WAAW,CAAC;IACnB,SAAS,EAAE,oBAAoB,CAAC;CACjC,CAoEA"}
@@ -0,0 +1,363 @@
1
+ /** CRUD 骨架与导出覆盖的标准按钮标签集合(归类用)。 */
2
+ const CRUD_BUTTON_LABELS = {
3
+ create: ['新增', '增加', '添加', '新建'],
4
+ search: ['搜索', '查询', '检索'],
5
+ edit: ['修改', '编辑'],
6
+ delete: ['删除', '删除选定', '批量删除'],
7
+ confirm: ['确定', '确认', '保存', '保存并关闭'],
8
+ export: ['导出', '导出选定', '批量导出']
9
+ };
10
+ /**
11
+ * 识别列表页。
12
+ *
13
+ * 优先选 pageId 以 `list` 结尾的页面(文件名约定);无则回落到第一个含 datagrid 的页面。
14
+ * 不能只用 grids.length > 0,因为 add/edit/detail 页也可能内嵌 datagrid(如 014 场景),
15
+ * 会导致搜索条件误从表单页抽取(regression:windowname 被当作搜索条件)。
16
+ *
17
+ * @param pages - 已抽取的 HTML 页面列表。
18
+ * @returns 列表页;无则返回 undefined。
19
+ */
20
+ function findListPage(pages) {
21
+ const byId = pages.find((page) => /list$/i.test(page.pageId));
22
+ if (byId)
23
+ return byId;
24
+ return pages.find((page) => page.grids.length > 0);
25
+ }
26
+ /**
27
+ * 收集列表页搜索区字段名(fui-condition 区的 input bind)。
28
+ *
29
+ * @param listPage - 列表页。
30
+ * @returns 搜索区字段名集合。
31
+ */
32
+ function collectSearchFields(listPage) {
33
+ const fields = new Set();
34
+ if (!listPage)
35
+ return fields;
36
+ for (const field of listPage.fields) {
37
+ fields.add(field.name);
38
+ }
39
+ return fields;
40
+ }
41
+ /**
42
+ * 收集列表页表格数据列 field。
43
+ *
44
+ * @param listPage - 列表页。
45
+ * @returns 表格列 field 集合。
46
+ */
47
+ function collectGridFields(listPage) {
48
+ const fields = new Set();
49
+ if (!listPage)
50
+ return fields;
51
+ for (const grid of listPage.grids) {
52
+ for (const column of grid.dataColumns) {
53
+ if (column.field) {
54
+ fields.add(column.field);
55
+ }
56
+ }
57
+ }
58
+ return fields;
59
+ }
60
+ /**
61
+ * 收集新增/编辑页表单字段名。
62
+ *
63
+ * @param pages - 所有页面。
64
+ * @returns 表单字段名集合。
65
+ */
66
+ function collectFormFields(pages) {
67
+ const fields = new Set();
68
+ for (const page of pages) {
69
+ for (const field of page.fields) {
70
+ if (field.name) {
71
+ fields.add(field.name);
72
+ }
73
+ }
74
+ }
75
+ return fields;
76
+ }
77
+ /**
78
+ * 推理 dataKey.selectedField。
79
+ *
80
+ * 规则:优先选同时出现在列表页搜索区、表格列、新增/编辑页表单的 input 字段。
81
+ * 若无三方交集,回落到搜索区与表格列的交集;再无则取表格第一列。
82
+ *
83
+ * @param listPage - 列表页。
84
+ * @param pages - 所有页面。
85
+ * @returns dataKey 推理过程。
86
+ */
87
+ function inferDataKey(listPage, pages) {
88
+ const searchFields = collectSearchFields(listPage);
89
+ const gridFields = collectGridFields(listPage);
90
+ const formFields = collectFormFields(pages);
91
+ // 三方交集
92
+ const tripleIntersection = Array.from(searchFields).filter((field) => gridFields.has(field) && formFields.has(field));
93
+ if (tripleIntersection.length > 0) {
94
+ return {
95
+ selectedField: tripleIntersection[0],
96
+ reason: '列表页搜索区、表格列、新增/编辑页表单同时出现该字段',
97
+ evidence: tripleIntersection.map((field) => `${field} 出现在搜索区+表格列+表单`)
98
+ };
99
+ }
100
+ // 搜索区与表格列交集
101
+ const dualIntersection = Array.from(searchFields).filter((field) => gridFields.has(field));
102
+ if (dualIntersection.length > 0) {
103
+ return {
104
+ selectedField: dualIntersection[0],
105
+ reason: '列表页搜索区与表格列同时出现该字段(表单未覆盖)',
106
+ evidence: dualIntersection.map((field) => `${field} 出现在搜索区+表格列`)
107
+ };
108
+ }
109
+ // 回落到表格第一列
110
+ if (listPage && listPage.grids.length > 0) {
111
+ const firstColumn = listPage.grids[0].dataColumns[0];
112
+ if (firstColumn?.field) {
113
+ return {
114
+ selectedField: firstColumn.field,
115
+ reason: '搜索区与表格列无交集,回落到表格第一列',
116
+ evidence: [`表格第一列 field=${firstColumn.field}`]
117
+ };
118
+ }
119
+ }
120
+ return {
121
+ reason: '无法从物料中推理出 dataKey',
122
+ evidence: []
123
+ };
124
+ }
125
+ /**
126
+ * 推理搜索条件。
127
+ *
128
+ * 规则:至少包含 dataKey input 条件;listbox 条件缺取值时只进 unresolved。
129
+ *
130
+ * @param listPage - 列表页。
131
+ * @param dataKeyField - 选定的 dataKey 字段。
132
+ * @returns 搜索条件推理过程数组。
133
+ */
134
+ function inferSearchConditions(listPage, dataKeyField) {
135
+ const conditions = [];
136
+ if (!listPage)
137
+ return conditions;
138
+ for (const field of listPage.fields) {
139
+ const isInput = field.controlType.includes('textbox') || field.controlType.includes('input');
140
+ const isListbox = field.controlType.includes('combobox') || field.controlType.includes('listbox');
141
+ if (isInput) {
142
+ conditions.push({
143
+ field: field.name,
144
+ component: 'input',
145
+ resolved: true
146
+ });
147
+ }
148
+ else if (isListbox) {
149
+ // listbox 缺取值时只进 unresolved,不阻断
150
+ conditions.push({
151
+ field: field.name,
152
+ component: 'listbox',
153
+ resolved: false,
154
+ reason: 'listbox 取值需人工或后续补齐'
155
+ });
156
+ }
157
+ }
158
+ // 确保 dataKey 字段在搜索条件中
159
+ if (dataKeyField && !conditions.some((condition) => condition.field === dataKeyField)) {
160
+ conditions.unshift({
161
+ field: dataKeyField,
162
+ component: 'input',
163
+ resolved: true
164
+ });
165
+ }
166
+ return conditions;
167
+ }
168
+ /**
169
+ * 从按钮标签归类 buttonAliases。
170
+ *
171
+ * @param pages - 所有页面。
172
+ * @returns 按钮别名归类映射。
173
+ */
174
+ function inferButtonAliases(pages) {
175
+ const aliases = {};
176
+ const allLabels = new Set();
177
+ for (const page of pages) {
178
+ for (const button of page.buttons) {
179
+ allLabels.add(button.label);
180
+ }
181
+ }
182
+ for (const [alias, patterns] of Object.entries(CRUD_BUTTON_LABELS)) {
183
+ const matched = Array.from(allLabels).filter((label) => patterns.some((pattern) => label.includes(pattern)));
184
+ if (matched.length > 0) {
185
+ aliases[alias] = matched;
186
+ }
187
+ }
188
+ return aliases;
189
+ }
190
+ /**
191
+ * 推理删除策略。
192
+ *
193
+ * 规则:Java messages 含"不可删除"类提示时推为 blocked_by_business_rule。
194
+ *
195
+ * @param actions - Java Action 列表。
196
+ * @returns 删除策略推理过程。
197
+ */
198
+ function inferDeletePolicy(actions) {
199
+ const blockMessages = [];
200
+ for (const action of actions) {
201
+ for (const message of action.messages) {
202
+ if (/不可删除|不允许删除|禁止删除/.test(message)) {
203
+ blockMessages.push(message);
204
+ }
205
+ }
206
+ }
207
+ if (blockMessages.length > 0) {
208
+ return {
209
+ value: 'blocked_by_business_rule',
210
+ reason: 'Java Action 存在不可删除提示',
211
+ evidence: blockMessages
212
+ };
213
+ }
214
+ return {
215
+ reason: '未发现删除限制证据,默认允许删除',
216
+ evidence: []
217
+ };
218
+ }
219
+ /** 已被 CRUD 骨架与导出覆盖的按钮标签模式(customWorkflows 排除用)。 */
220
+ const SKELETON_BUTTON_PATTERNS = [
221
+ ...CRUD_BUTTON_LABELS.create,
222
+ ...CRUD_BUTTON_LABELS.search,
223
+ ...CRUD_BUTTON_LABELS.edit,
224
+ ...CRUD_BUTTON_LABELS.delete,
225
+ ...CRUD_BUTTON_LABELS.confirm,
226
+ ...CRUD_BUTTON_LABELS.export,
227
+ '重置', '关闭', '返回', '取消', '刷新'
228
+ ];
229
+ /**
230
+ * 收集 CRUD/Export 骨架之外的自定义工作流(工具栏按钮)。
231
+ *
232
+ * 规则:有 Java callback message 时填 assertion,否则 unresolved。
233
+ *
234
+ * @param pages - 所有页面。
235
+ * @param actions - Java Action 列表。
236
+ * @returns 自定义工作流推理过程数组。
237
+ */
238
+ function inferCustomWorkflows(pages, actions) {
239
+ // 收集所有 Java callback 消息,用于匹配断言
240
+ const allMessages = [];
241
+ for (const action of actions) {
242
+ allMessages.push(...action.messages);
243
+ }
244
+ const workflows = [];
245
+ const seen = new Set();
246
+ for (const page of pages) {
247
+ for (const button of page.buttons) {
248
+ const label = button.label;
249
+ if (seen.has(label))
250
+ continue;
251
+ const isSkeleton = SKELETON_BUTTON_PATTERNS.some((pattern) => label.includes(pattern));
252
+ if (isSkeleton)
253
+ continue;
254
+ seen.add(label);
255
+ // 尝试从 Java messages 中找到与按钮相关的断言
256
+ const relatedMessage = allMessages.find((message) => {
257
+ // 按钮标签的关键词出现在消息里,或消息里的动作动词与按钮相关
258
+ const keywords = label.replace(/管理系统|信息管理|数据/g, '').trim();
259
+ return keywords.length > 0 && message.includes(keywords);
260
+ });
261
+ if (relatedMessage) {
262
+ workflows.push({
263
+ label,
264
+ actionAlias: button.onclick ? [button.onclick] : undefined,
265
+ expectedIntent: label,
266
+ expectedAssertion: relatedMessage,
267
+ resolved: true,
268
+ evidence: [
269
+ `按钮 onclick=${button.onclick ?? '(未声明)'}`,
270
+ `Java callback: ${relatedMessage}`
271
+ ]
272
+ });
273
+ }
274
+ else {
275
+ workflows.push({
276
+ label,
277
+ actionAlias: button.onclick ? [button.onclick] : undefined,
278
+ expectedIntent: label,
279
+ resolved: false,
280
+ reason: '未找到对应 Java callback 断言',
281
+ evidence: [`按钮 onclick=${button.onclick ?? '(未声明)'}`]
282
+ });
283
+ }
284
+ }
285
+ }
286
+ return workflows;
287
+ }
288
+ /**
289
+ * 基于上游物料推理 ModuleHints 动态槽位。
290
+ *
291
+ * 推理规则:
292
+ * - dataKey.selectedField 优先选同时出现在列表页搜索区、表格列、新增/编辑页表单的 input 字段。
293
+ * - searchConditions 至少包含 dataKey input 条件;listbox 条件缺取值时只进 unresolved。
294
+ * - buttonAliases 从页面按钮标签归类(新增、搜索、修改、删除、确定、导出)。
295
+ * - deletePolicy 若 Java messages 含"不可删除",推为 blocked_by_business_rule。
296
+ * - customWorkflows 收集 CRUD/Export 骨架之外的工具栏按钮;有 Java callback 时填 assertion,否则 unresolved。
297
+ *
298
+ * @param input - 输入参数(sourceAnalysis、pages、actions、可选 explicitHints)。
299
+ * @returns 推理出的 hints 与推理过程。
300
+ */
301
+ export function inferModuleHintsFromMaterials(input) {
302
+ const listPage = findListPage(input.pages);
303
+ const dataKeyInference = inferDataKey(listPage, input.pages);
304
+ const searchConditionInferences = inferSearchConditions(listPage, dataKeyInference.selectedField);
305
+ const buttonAliases = inferButtonAliases(input.pages);
306
+ const deletePolicyInference = inferDeletePolicy(input.actions);
307
+ const customWorkflows = inferCustomWorkflows(input.pages, input.actions);
308
+ // 组装 hints(与 ModuleHints 类型对齐)
309
+ const hints = {
310
+ dataKey: dataKeyInference.selectedField
311
+ ? {
312
+ selectedField: dataKeyInference.selectedField,
313
+ candidateFields: input.sourceAnalysis.fields
314
+ }
315
+ : undefined,
316
+ searchConditions: searchConditionInferences
317
+ .filter((condition) => condition.resolved)
318
+ .map((condition) => ({
319
+ field: condition.field,
320
+ component: condition.component
321
+ })),
322
+ buttonAliases,
323
+ deletePolicy: deletePolicyInference.value,
324
+ customWorkflows: customWorkflows.map((workflow) => ({
325
+ label: workflow.label,
326
+ actionAlias: workflow.actionAlias,
327
+ expectedIntent: workflow.expectedIntent,
328
+ expectedAssertion: workflow.expectedAssertion,
329
+ include: workflow.resolved,
330
+ excludeReason: workflow.resolved ? undefined : '未找到对应断言证据'
331
+ }))
332
+ };
333
+ // 组装 unresolved
334
+ const unresolved = [];
335
+ if (!dataKeyInference.selectedField) {
336
+ unresolved.push('dataKey.selectedField');
337
+ }
338
+ for (const condition of searchConditionInferences) {
339
+ if (!condition.resolved) {
340
+ unresolved.push(`searchConditions.${condition.field}`);
341
+ }
342
+ }
343
+ for (const workflow of customWorkflows) {
344
+ if (!workflow.resolved) {
345
+ unresolved.push(`customWorkflows.${workflow.label}`);
346
+ }
347
+ }
348
+ // 合并显式 hints(若有)
349
+ const mode = input.explicitHints ? 'merged' : 'inferred';
350
+ const confidence = unresolved.length === 0 ? 'high' : unresolved.length <= 2 ? 'medium' : 'low';
351
+ const inference = {
352
+ mode,
353
+ confidence,
354
+ dataKey: dataKeyInference,
355
+ searchConditions: searchConditionInferences,
356
+ buttonAliases,
357
+ deletePolicy: deletePolicyInference,
358
+ assertionPolicy: {},
359
+ customWorkflows,
360
+ unresolved
361
+ };
362
+ return { hints, inference };
363
+ }
@@ -0,0 +1,26 @@
1
+ import type { ExtractedCodeListSummary, ExtractedHtmlPage, ExtractedJavaAction } from '../index.js';
2
+ import type { SourceAnalysis } from '../contracts/inference-trace.js';
3
+ /**
4
+ * buildSourceAnalysis 的输入参数。
5
+ */
6
+ export type BuildSourceAnalysisInput = {
7
+ codeListPath: string;
8
+ docsDir: string;
9
+ codeList: ExtractedCodeListSummary;
10
+ pages: ExtractedHtmlPage[];
11
+ actions: ExtractedJavaAction[];
12
+ };
13
+ /**
14
+ * 构建 sourceAnalysis 章节。
15
+ *
16
+ * 实现规则:
17
+ * - docsDir 下存在 PRD markdown(文件名含 prd 或正文含 `## 4. 功能需求`)时登记 prd_markdown source。
18
+ * - HTML 页面登记为 uiSignals(字段、按钮、表格列、弹窗)。
19
+ * - Java Action 登记为 backendSignals(方法名、callback 消息)。
20
+ * - 无 spec.yaml 时 mode='prd+html+java';有 spec.yaml 时 mode='extracted'。
21
+ *
22
+ * @param input - 输入参数(codeListPath、docsDir、codeList、pages、actions)。
23
+ * @returns 源分析快照。
24
+ */
25
+ export declare function buildSourceAnalysis(input: BuildSourceAnalysisInput): SourceAnalysis;
26
+ //# sourceMappingURL=source-analysis.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-analysis.d.ts","sourceRoot":"","sources":["../../../src/inference/source-analysis.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,wBAAwB,EACxB,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAEV,cAAc,EAGf,MAAM,iCAAiC,CAAC;AAEzC;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,wBAAwB,CAAC;IACnC,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,OAAO,EAAE,mBAAmB,EAAE,CAAC;CAChC,CAAC;AAgLF;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,wBAAwB,GAAG,cAAc,CAkFnF"}