oh-my-knowledge 0.0.1 → 0.18.0

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 (215) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +537 -332
  3. package/dist/src/analysis/coverage-analyzer.d.ts +57 -0
  4. package/dist/src/analysis/coverage-analyzer.d.ts.map +1 -0
  5. package/dist/src/analysis/coverage-analyzer.js +262 -0
  6. package/dist/src/analysis/coverage-analyzer.js.map +1 -0
  7. package/dist/src/analysis/gap-analyzer.d.ts +114 -0
  8. package/dist/src/analysis/gap-analyzer.d.ts.map +1 -0
  9. package/dist/src/analysis/gap-analyzer.js +439 -0
  10. package/dist/src/analysis/gap-analyzer.js.map +1 -0
  11. package/dist/src/analysis/hedging-classifier.d.ts +34 -0
  12. package/dist/src/analysis/hedging-classifier.d.ts.map +1 -0
  13. package/dist/src/analysis/hedging-classifier.js +144 -0
  14. package/dist/src/analysis/hedging-classifier.js.map +1 -0
  15. package/dist/src/analysis/report-diagnostics.d.ts +9 -0
  16. package/dist/src/analysis/report-diagnostics.d.ts.map +1 -0
  17. package/dist/src/analysis/report-diagnostics.js +631 -0
  18. package/dist/src/analysis/report-diagnostics.js.map +1 -0
  19. package/dist/src/authoring/evolver.d.ts +64 -0
  20. package/dist/src/authoring/evolver.d.ts.map +1 -0
  21. package/dist/src/authoring/evolver.js +275 -0
  22. package/dist/src/authoring/evolver.js.map +1 -0
  23. package/dist/src/authoring/generator.d.ts +13 -0
  24. package/dist/src/authoring/generator.d.ts.map +1 -0
  25. package/dist/src/authoring/generator.js +60 -0
  26. package/dist/src/authoring/generator.js.map +1 -0
  27. package/dist/src/cli.d.ts +3 -0
  28. package/dist/src/cli.d.ts.map +1 -0
  29. package/dist/src/cli.js +1004 -0
  30. package/dist/src/cli.js.map +1 -0
  31. package/dist/src/eval-core/cache.d.ts +11 -0
  32. package/dist/src/eval-core/cache.d.ts.map +1 -0
  33. package/dist/src/eval-core/cache.js +53 -0
  34. package/dist/src/eval-core/cache.js.map +1 -0
  35. package/dist/src/eval-core/ci-gates.d.ts +17 -0
  36. package/dist/src/eval-core/ci-gates.d.ts.map +1 -0
  37. package/dist/src/eval-core/ci-gates.js +42 -0
  38. package/dist/src/eval-core/ci-gates.js.map +1 -0
  39. package/dist/src/eval-core/dependency-checker.d.ts +37 -0
  40. package/dist/src/eval-core/dependency-checker.d.ts.map +1 -0
  41. package/dist/src/eval-core/dependency-checker.js +280 -0
  42. package/dist/src/eval-core/dependency-checker.js.map +1 -0
  43. package/dist/src/eval-core/evaluation-execution.d.ts +26 -0
  44. package/dist/src/eval-core/evaluation-execution.d.ts.map +1 -0
  45. package/dist/src/eval-core/evaluation-execution.js +196 -0
  46. package/dist/src/eval-core/evaluation-execution.js.map +1 -0
  47. package/dist/src/eval-core/evaluation-job.d.ts +48 -0
  48. package/dist/src/eval-core/evaluation-job.d.ts.map +1 -0
  49. package/dist/src/eval-core/evaluation-job.js +112 -0
  50. package/dist/src/eval-core/evaluation-job.js.map +1 -0
  51. package/dist/src/eval-core/evaluation-reporting.d.ts +28 -0
  52. package/dist/src/eval-core/evaluation-reporting.d.ts.map +1 -0
  53. package/dist/src/eval-core/evaluation-reporting.js +123 -0
  54. package/dist/src/eval-core/evaluation-reporting.js.map +1 -0
  55. package/dist/src/eval-core/execution-strategy.d.ts +11 -0
  56. package/dist/src/eval-core/execution-strategy.d.ts.map +1 -0
  57. package/dist/src/eval-core/execution-strategy.js +121 -0
  58. package/dist/src/eval-core/execution-strategy.js.map +1 -0
  59. package/dist/src/eval-core/fact-checker.d.ts +25 -0
  60. package/dist/src/eval-core/fact-checker.d.ts.map +1 -0
  61. package/dist/src/eval-core/fact-checker.js +66 -0
  62. package/dist/src/eval-core/fact-checker.js.map +1 -0
  63. package/dist/src/eval-core/schema.d.ts +30 -0
  64. package/dist/src/eval-core/schema.d.ts.map +1 -0
  65. package/dist/src/eval-core/schema.js +195 -0
  66. package/dist/src/eval-core/schema.js.map +1 -0
  67. package/dist/src/eval-core/statistics.d.ts +86 -0
  68. package/dist/src/eval-core/statistics.d.ts.map +1 -0
  69. package/dist/src/eval-core/statistics.js +210 -0
  70. package/dist/src/eval-core/statistics.js.map +1 -0
  71. package/dist/src/eval-core/task-planner.d.ts +4 -0
  72. package/dist/src/eval-core/task-planner.d.ts.map +1 -0
  73. package/dist/src/eval-core/task-planner.js +33 -0
  74. package/dist/src/eval-core/task-planner.js.map +1 -0
  75. package/dist/src/eval-workflows/each-evaluation-workflow.d.ts +133 -0
  76. package/dist/src/eval-workflows/each-evaluation-workflow.d.ts.map +1 -0
  77. package/dist/src/eval-workflows/each-evaluation-workflow.js +169 -0
  78. package/dist/src/eval-workflows/each-evaluation-workflow.js.map +1 -0
  79. package/dist/src/eval-workflows/evaluation-pipeline.d.ts +38 -0
  80. package/dist/src/eval-workflows/evaluation-pipeline.d.ts.map +1 -0
  81. package/dist/src/eval-workflows/evaluation-pipeline.js +214 -0
  82. package/dist/src/eval-workflows/evaluation-pipeline.js.map +1 -0
  83. package/dist/src/eval-workflows/evaluation-preparation.d.ts +64 -0
  84. package/dist/src/eval-workflows/evaluation-preparation.d.ts.map +1 -0
  85. package/dist/src/eval-workflows/evaluation-preparation.js +90 -0
  86. package/dist/src/eval-workflows/evaluation-preparation.js.map +1 -0
  87. package/dist/src/eval-workflows/run-evaluation.d.ts +105 -0
  88. package/dist/src/eval-workflows/run-evaluation.d.ts.map +1 -0
  89. package/dist/src/eval-workflows/run-evaluation.js +264 -0
  90. package/dist/src/eval-workflows/run-evaluation.js.map +1 -0
  91. package/dist/src/executors/anthropic-api.d.ts +3 -0
  92. package/dist/src/executors/anthropic-api.d.ts.map +1 -0
  93. package/dist/src/executors/anthropic-api.js +43 -0
  94. package/dist/src/executors/anthropic-api.js.map +1 -0
  95. package/dist/src/executors/claude-cli.d.ts +3 -0
  96. package/dist/src/executors/claude-cli.d.ts.map +1 -0
  97. package/dist/src/executors/claude-cli.js +103 -0
  98. package/dist/src/executors/claude-cli.js.map +1 -0
  99. package/dist/src/executors/claude-sdk-trace.d.ts +10 -0
  100. package/dist/src/executors/claude-sdk-trace.d.ts.map +1 -0
  101. package/dist/src/executors/claude-sdk-trace.js +100 -0
  102. package/dist/src/executors/claude-sdk-trace.js.map +1 -0
  103. package/dist/src/executors/claude-sdk.d.ts +3 -0
  104. package/dist/src/executors/claude-sdk.d.ts.map +1 -0
  105. package/dist/src/executors/claude-sdk.js +160 -0
  106. package/dist/src/executors/claude-sdk.js.map +1 -0
  107. package/dist/src/executors/gemini.d.ts +3 -0
  108. package/dist/src/executors/gemini.d.ts.map +1 -0
  109. package/dist/src/executors/gemini.js +78 -0
  110. package/dist/src/executors/gemini.js.map +1 -0
  111. package/dist/src/executors/index.d.ts +7 -0
  112. package/dist/src/executors/index.d.ts.map +1 -0
  113. package/dist/src/executors/index.js +22 -0
  114. package/dist/src/executors/index.js.map +1 -0
  115. package/dist/src/executors/openai-api.d.ts +3 -0
  116. package/dist/src/executors/openai-api.d.ts.map +1 -0
  117. package/dist/src/executors/openai-api.js +40 -0
  118. package/dist/src/executors/openai-api.js.map +1 -0
  119. package/dist/src/executors/openai-cli.d.ts +3 -0
  120. package/dist/src/executors/openai-cli.d.ts.map +1 -0
  121. package/dist/src/executors/openai-cli.js +60 -0
  122. package/dist/src/executors/openai-cli.js.map +1 -0
  123. package/dist/src/executors/script.d.ts +3 -0
  124. package/dist/src/executors/script.d.ts.map +1 -0
  125. package/dist/src/executors/script.js +63 -0
  126. package/dist/src/executors/script.js.map +1 -0
  127. package/dist/src/executors/shared.d.ts +117 -0
  128. package/dist/src/executors/shared.d.ts.map +1 -0
  129. package/dist/src/executors/shared.js +49 -0
  130. package/dist/src/executors/shared.js.map +1 -0
  131. package/dist/src/grading/assertions.d.ts +18 -0
  132. package/dist/src/grading/assertions.d.ts.map +1 -0
  133. package/dist/src/grading/assertions.js +239 -0
  134. package/dist/src/grading/assertions.js.map +1 -0
  135. package/dist/src/grading/index.d.ts +26 -0
  136. package/dist/src/grading/index.d.ts.map +1 -0
  137. package/dist/src/grading/index.js +98 -0
  138. package/dist/src/grading/index.js.map +1 -0
  139. package/dist/src/grading/judge.d.ts +13 -0
  140. package/dist/src/grading/judge.d.ts.map +1 -0
  141. package/dist/src/grading/judge.js +98 -0
  142. package/dist/src/grading/judge.js.map +1 -0
  143. package/dist/src/grading/layered-scores.d.ts +13 -0
  144. package/dist/src/grading/layered-scores.d.ts.map +1 -0
  145. package/dist/src/grading/layered-scores.js +62 -0
  146. package/dist/src/grading/layered-scores.js.map +1 -0
  147. package/dist/src/inputs/eval-config.d.ts +13 -0
  148. package/dist/src/inputs/eval-config.d.ts.map +1 -0
  149. package/dist/src/inputs/eval-config.js +136 -0
  150. package/dist/src/inputs/eval-config.js.map +1 -0
  151. package/dist/src/inputs/load-samples.d.ts +16 -0
  152. package/dist/src/inputs/load-samples.d.ts.map +1 -0
  153. package/dist/src/inputs/load-samples.js +51 -0
  154. package/dist/src/inputs/load-samples.js.map +1 -0
  155. package/dist/src/inputs/mcp-resolver.d.ts +50 -0
  156. package/dist/src/inputs/mcp-resolver.d.ts.map +1 -0
  157. package/dist/src/inputs/mcp-resolver.js +307 -0
  158. package/dist/src/inputs/mcp-resolver.js.map +1 -0
  159. package/dist/src/inputs/skill-loader.d.ts +18 -0
  160. package/dist/src/inputs/skill-loader.d.ts.map +1 -0
  161. package/dist/src/inputs/skill-loader.js +222 -0
  162. package/dist/src/inputs/skill-loader.js.map +1 -0
  163. package/dist/src/inputs/url-fetcher.d.ts +19 -0
  164. package/dist/src/inputs/url-fetcher.d.ts.map +1 -0
  165. package/dist/src/inputs/url-fetcher.js +241 -0
  166. package/dist/src/inputs/url-fetcher.js.map +1 -0
  167. package/dist/src/observability/production-analyzer.d.ts +61 -0
  168. package/dist/src/observability/production-analyzer.d.ts.map +1 -0
  169. package/dist/src/observability/production-analyzer.js +183 -0
  170. package/dist/src/observability/production-analyzer.js.map +1 -0
  171. package/dist/src/observability/trace-adapter.d.ts +75 -0
  172. package/dist/src/observability/trace-adapter.d.ts.map +1 -0
  173. package/dist/src/observability/trace-adapter.js +341 -0
  174. package/dist/src/observability/trace-adapter.js.map +1 -0
  175. package/dist/src/renderer/html-renderer.d.ts +9 -0
  176. package/dist/src/renderer/html-renderer.d.ts.map +1 -0
  177. package/dist/src/renderer/html-renderer.js +338 -0
  178. package/dist/src/renderer/html-renderer.js.map +1 -0
  179. package/dist/src/renderer/layout.d.ts +13 -0
  180. package/dist/src/renderer/layout.d.ts.map +1 -0
  181. package/dist/src/renderer/layout.js +476 -0
  182. package/dist/src/renderer/layout.js.map +1 -0
  183. package/dist/src/renderer/skill-health-renderer.d.ts +20 -0
  184. package/dist/src/renderer/skill-health-renderer.d.ts.map +1 -0
  185. package/dist/src/renderer/skill-health-renderer.js +218 -0
  186. package/dist/src/renderer/skill-health-renderer.js.map +1 -0
  187. package/dist/src/renderer/summary.d.ts +21 -0
  188. package/dist/src/renderer/summary.d.ts.map +1 -0
  189. package/dist/src/renderer/summary.js +1072 -0
  190. package/dist/src/renderer/summary.js.map +1 -0
  191. package/dist/src/renderer/table.d.ts +3 -0
  192. package/dist/src/renderer/table.d.ts.map +1 -0
  193. package/dist/src/renderer/table.js +134 -0
  194. package/dist/src/renderer/table.js.map +1 -0
  195. package/dist/src/renderer/trends.d.ts +6 -0
  196. package/dist/src/renderer/trends.d.ts.map +1 -0
  197. package/dist/src/renderer/trends.js +127 -0
  198. package/dist/src/renderer/trends.js.map +1 -0
  199. package/dist/src/server/job-store.d.ts +4 -0
  200. package/dist/src/server/job-store.d.ts.map +1 -0
  201. package/dist/src/server/job-store.js +68 -0
  202. package/dist/src/server/job-store.js.map +1 -0
  203. package/dist/src/server/report-server.d.ts +16 -0
  204. package/dist/src/server/report-server.d.ts.map +1 -0
  205. package/dist/src/server/report-server.js +196 -0
  206. package/dist/src/server/report-server.js.map +1 -0
  207. package/dist/src/server/report-store.d.ts +44 -0
  208. package/dist/src/server/report-store.d.ts.map +1 -0
  209. package/dist/src/server/report-store.js +190 -0
  210. package/dist/src/server/report-store.js.map +1 -0
  211. package/dist/src/types.d.ts +553 -0
  212. package/dist/src/types.d.ts.map +1 -0
  213. package/dist/src/types.js +2 -0
  214. package/dist/src/types.js.map +1 -0
  215. package/package.json +44 -3
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Knowledge coverage analyzer.
3
+ * Computes coverage rates by comparing consumed knowledge against the full index.
4
+ */
5
+ import type { ToolCallInfo, ResultEntry, Report } from '../types.js';
6
+ export interface KnowledgeEntry {
7
+ path: string;
8
+ type: 'principle' | 'semantic' | 'design' | 'script' | 'code' | 'other';
9
+ lineCount?: number;
10
+ }
11
+ export interface KnowledgeIndex {
12
+ entries: KnowledgeEntry[];
13
+ totalFiles: number;
14
+ totalLines: number;
15
+ }
16
+ export interface KnowledgeConsumption {
17
+ filesRead: string[];
18
+ grepPatterns: Array<{
19
+ pattern: string;
20
+ path?: string;
21
+ }>;
22
+ bashGrepPatterns: Array<{
23
+ pattern: string;
24
+ path?: string;
25
+ }>;
26
+ }
27
+ export declare function extractReferencedPaths(artifactContent: string): string[];
28
+ export declare function buildKnowledgeIndex(cwd: string): KnowledgeIndex;
29
+ export declare function buildFullKnowledgeIndex(artifactContent: string | null, cwd: string | null): KnowledgeIndex;
30
+ export declare function extractKnowledgeConsumption(toolCalls: ToolCallInfo[]): KnowledgeConsumption;
31
+ export declare function normalizeKnowledgePath(filePath: string, cwd?: string | null): string;
32
+ export interface CoverageEntry {
33
+ path: string;
34
+ type: KnowledgeEntry['type'];
35
+ accessed: boolean;
36
+ accessCount: number;
37
+ lineCount?: number;
38
+ }
39
+ export interface CoverageReport {
40
+ entries: CoverageEntry[];
41
+ filesCovered: number;
42
+ filesTotal: number;
43
+ fileCoverageRate: number;
44
+ uncoveredFiles: string[];
45
+ grepPatternsUsed: number;
46
+ overallRate: number;
47
+ }
48
+ /**
49
+ * Compute knowledge coverage for a single variant across all samples.
50
+ */
51
+ export declare function computeCoverage(results: ResultEntry[], variant: string, index: KnowledgeIndex, cwd?: string | null): CoverageReport;
52
+ /**
53
+ * Compute coverage reports for all variants in a report.
54
+ * Returns a map of variant → CoverageReport.
55
+ */
56
+ export declare function computeReportCoverage(report: Report, artifactContents: Record<string, string | null>, cwds: Record<string, string | null>): Record<string, CoverageReport>;
57
+ //# sourceMappingURL=coverage-analyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coverage-analyzer.d.ts","sourceRoot":"","sources":["../../../src/analysis/coverage-analyzer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErE,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,WAAW,GAAG,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,YAAY,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxD,gBAAgB,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC7D;AAWD,wBAAgB,sBAAsB,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,EAAE,CAqBxE;AA8BD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CA0B/D;AAED,wBAAgB,uBAAuB,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,cAAc,CAmD1G;AAED,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,oBAAoB,CAkC3F;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAWpF;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IAC7B,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,WAAW,EAAE,EACtB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,cAAc,EACrB,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,GAClB,cAAc,CA0DhB;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,EACd,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,EAC/C,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,GAClC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAehC"}
@@ -0,0 +1,262 @@
1
+ /**
2
+ * Knowledge coverage analyzer.
3
+ * Computes coverage rates by comparing consumed knowledge against the full index.
4
+ */
5
+ import { basename, join, resolve } from 'node:path';
6
+ import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
7
+ function classifyEntry(path) {
8
+ if (/principle/i.test(path))
9
+ return 'principle';
10
+ if (/semantic[-_]?index/i.test(path))
11
+ return 'semantic';
12
+ if (/design\.md/i.test(path))
13
+ return 'design';
14
+ if (/\.sh$|scripts?\//i.test(path))
15
+ return 'script';
16
+ if (/\.(ts|js|tsx|jsx)$/i.test(path))
17
+ return 'code';
18
+ return 'other';
19
+ }
20
+ export function extractReferencedPaths(artifactContent) {
21
+ const paths = new Set();
22
+ const pathPatterns = [
23
+ /\.claude\/[a-zA-Z0-9_/.-]+\.md/g,
24
+ /\.claude\/[a-zA-Z0-9_/.-]+\.sh/g,
25
+ /repos\/[a-zA-Z0-9_/-]+/g,
26
+ ];
27
+ for (const pattern of pathPatterns) {
28
+ for (const match of artifactContent.matchAll(pattern)) {
29
+ paths.add(match[0]);
30
+ }
31
+ }
32
+ for (const match of artifactContent.matchAll(/\b([a-zA-Z0-9_-]+\.md)\b/g)) {
33
+ const name = match[1];
34
+ if (/^(README|CHANGELOG|LICENSE|package)\.md$/i.test(name))
35
+ continue;
36
+ paths.add(name);
37
+ }
38
+ return [...paths];
39
+ }
40
+ function scanKnowledgeDir(dir, prefix = '') {
41
+ if (!existsSync(dir))
42
+ return [];
43
+ const entries = [];
44
+ for (const name of readdirSync(dir)) {
45
+ if (name.startsWith('.'))
46
+ continue;
47
+ const fullPath = join(dir, name);
48
+ const relativePath = prefix ? `${prefix}/${name}` : name;
49
+ const stat = statSync(fullPath);
50
+ if (stat.isDirectory()) {
51
+ entries.push(...scanKnowledgeDir(fullPath, relativePath));
52
+ }
53
+ else if (/\.(md|sh)$/.test(name)) {
54
+ let lineCount;
55
+ try {
56
+ lineCount = readFileSync(fullPath, 'utf-8').split('\n').length;
57
+ }
58
+ catch { }
59
+ entries.push({
60
+ path: relativePath,
61
+ type: classifyEntry(relativePath),
62
+ lineCount,
63
+ });
64
+ }
65
+ }
66
+ return entries;
67
+ }
68
+ export function buildKnowledgeIndex(cwd) {
69
+ const knowledgeDirs = [
70
+ { dir: join(cwd, '.claude', 'knowledge'), prefix: '.claude/knowledge' },
71
+ { dir: join(cwd, '.claude', 'skills'), prefix: '.claude/skills' },
72
+ ];
73
+ const entries = [];
74
+ for (const { dir, prefix } of knowledgeDirs) {
75
+ entries.push(...scanKnowledgeDir(dir, prefix));
76
+ }
77
+ const claudeMd = join(cwd, 'CLAUDE.md');
78
+ if (existsSync(claudeMd)) {
79
+ let lineCount;
80
+ try {
81
+ lineCount = readFileSync(claudeMd, 'utf-8').split('\n').length;
82
+ }
83
+ catch { }
84
+ entries.push({ path: 'CLAUDE.md', type: 'principle', lineCount });
85
+ }
86
+ const totalLines = entries.reduce((sum, entry) => sum + (entry.lineCount || 0), 0);
87
+ return {
88
+ entries,
89
+ totalFiles: entries.length,
90
+ totalLines,
91
+ };
92
+ }
93
+ export function buildFullKnowledgeIndex(artifactContent, cwd) {
94
+ const entriesMap = new Map();
95
+ if (artifactContent) {
96
+ if (cwd) {
97
+ const knowledgeDir = join(cwd, '.claude', 'knowledge');
98
+ for (const entry of scanKnowledgeDir(knowledgeDir, '.claude/knowledge')) {
99
+ entriesMap.set(entry.path, entry);
100
+ }
101
+ const claudeMd = join(cwd, 'CLAUDE.md');
102
+ if (existsSync(claudeMd)) {
103
+ let lineCount;
104
+ try {
105
+ lineCount = readFileSync(claudeMd, 'utf-8').split('\n').length;
106
+ }
107
+ catch { }
108
+ entriesMap.set('CLAUDE.md', { path: 'CLAUDE.md', type: 'principle', lineCount });
109
+ }
110
+ }
111
+ const refPaths = extractReferencedPaths(artifactContent);
112
+ for (const path of refPaths) {
113
+ if (!entriesMap.has(path)) {
114
+ const existing = [...entriesMap.values()].find((entry) => entry.path.endsWith('/' + path) || entry.path === path);
115
+ if (!existing) {
116
+ let lineCount;
117
+ if (cwd) {
118
+ const fullPath = resolve(cwd, path);
119
+ try {
120
+ if (existsSync(fullPath) && statSync(fullPath).isFile()) {
121
+ lineCount = readFileSync(fullPath, 'utf-8').split('\n').length;
122
+ }
123
+ }
124
+ catch { }
125
+ }
126
+ entriesMap.set(path, { path, type: classifyEntry(path), lineCount });
127
+ }
128
+ }
129
+ }
130
+ }
131
+ else if (cwd) {
132
+ const dirIndex = buildKnowledgeIndex(cwd);
133
+ for (const entry of dirIndex.entries) {
134
+ entriesMap.set(entry.path, entry);
135
+ }
136
+ }
137
+ const entries = [...entriesMap.values()];
138
+ const totalLines = entries.reduce((sum, entry) => sum + (entry.lineCount || 0), 0);
139
+ return {
140
+ entries,
141
+ totalFiles: entries.length,
142
+ totalLines,
143
+ };
144
+ }
145
+ export function extractKnowledgeConsumption(toolCalls) {
146
+ const filesRead = [];
147
+ const grepPatterns = [];
148
+ const bashGrepPatterns = [];
149
+ for (const toolCall of toolCalls) {
150
+ const input = toolCall.input;
151
+ if (!input)
152
+ continue;
153
+ switch (toolCall.tool) {
154
+ case 'Read': {
155
+ const filePath = input.file_path;
156
+ if (filePath)
157
+ filesRead.push(filePath);
158
+ break;
159
+ }
160
+ case 'Grep': {
161
+ const pattern = input.pattern;
162
+ const path = input.path;
163
+ if (pattern)
164
+ grepPatterns.push({ pattern, path });
165
+ break;
166
+ }
167
+ case 'Bash': {
168
+ const command = input.command;
169
+ if (!command)
170
+ break;
171
+ const grepMatch = command.match(/(?:grep|rg)\s+(?:-[a-zA-Z]+\s+)*["']?([^"'\s|]+)["']?\s+([^\s|>]+)/);
172
+ if (grepMatch) {
173
+ bashGrepPatterns.push({ pattern: grepMatch[1], path: grepMatch[2] });
174
+ }
175
+ break;
176
+ }
177
+ }
178
+ }
179
+ return { filesRead: [...new Set(filesRead)], grepPatterns, bashGrepPatterns };
180
+ }
181
+ export function normalizeKnowledgePath(filePath, cwd) {
182
+ if (cwd && filePath.startsWith(cwd)) {
183
+ const relative = filePath.slice(cwd.endsWith('/') ? cwd.length : cwd.length + 1);
184
+ return relative;
185
+ }
186
+ const patterns = ['.claude/knowledge/', '.claude/skills/'];
187
+ for (const pattern of patterns) {
188
+ const index = filePath.indexOf(pattern);
189
+ if (index !== -1)
190
+ return filePath.slice(index);
191
+ }
192
+ return basename(filePath);
193
+ }
194
+ /**
195
+ * Compute knowledge coverage for a single variant across all samples.
196
+ */
197
+ export function computeCoverage(results, variant, index, cwd) {
198
+ // Aggregate all tool calls for this variant across samples
199
+ const allToolCalls = [];
200
+ for (const result of results) {
201
+ const vr = result.variants?.[variant];
202
+ if (vr?.toolCalls)
203
+ allToolCalls.push(...vr.toolCalls);
204
+ }
205
+ const consumption = extractKnowledgeConsumption(allToolCalls);
206
+ // Normalize consumed file paths
207
+ const consumedNormalized = new Set(consumption.filesRead.map((f) => normalizeKnowledgePath(f, cwd)));
208
+ // Match index entries against consumed files
209
+ const entries = index.entries.map((entry) => {
210
+ // Check if this entry was accessed — match by exact path or by filename
211
+ const accessed = consumedNormalized.has(entry.path) ||
212
+ [...consumedNormalized].some((consumed) => consumed.endsWith('/' + entry.path) || consumed.endsWith(entry.path));
213
+ const accessCount = accessed
214
+ ? consumption.filesRead.filter((f) => {
215
+ const norm = normalizeKnowledgePath(f, cwd);
216
+ return norm === entry.path || norm.endsWith('/' + entry.path) || norm.endsWith(entry.path);
217
+ }).length
218
+ : 0;
219
+ return {
220
+ path: entry.path,
221
+ type: entry.type,
222
+ accessed,
223
+ accessCount,
224
+ lineCount: entry.lineCount,
225
+ };
226
+ });
227
+ const filesCovered = entries.filter((e) => e.accessed).length;
228
+ const filesTotal = entries.length;
229
+ const fileCoverageRate = filesTotal > 0 ? Number((filesCovered / filesTotal).toFixed(2)) : 0;
230
+ const uncoveredFiles = entries.filter((e) => !e.accessed).map((e) => e.path);
231
+ const grepPatternsUsed = consumption.grepPatterns.length + consumption.bashGrepPatterns.length;
232
+ // Overall rate: file coverage 60% + grep activity bonus 40%
233
+ const grepBonus = grepPatternsUsed > 0 ? Math.min(1, grepPatternsUsed / Math.max(5, filesTotal)) : 0;
234
+ const overallRate = Number((fileCoverageRate * 0.6 + grepBonus * 0.4).toFixed(2));
235
+ return {
236
+ entries,
237
+ filesCovered,
238
+ filesTotal,
239
+ fileCoverageRate,
240
+ uncoveredFiles,
241
+ grepPatternsUsed,
242
+ overallRate,
243
+ };
244
+ }
245
+ /**
246
+ * Compute coverage reports for all variants in a report.
247
+ * Returns a map of variant → CoverageReport.
248
+ */
249
+ export function computeReportCoverage(report, artifactContents, cwds) {
250
+ const coverageMap = {};
251
+ for (const variant of report.meta.variants) {
252
+ const content = artifactContents[variant] || null;
253
+ const cwd = cwds[variant] || null;
254
+ // Build knowledge index for this variant
255
+ const index = buildFullKnowledgeIndex(content, cwd);
256
+ if (index.totalFiles === 0)
257
+ continue;
258
+ coverageMap[variant] = computeCoverage(report.results, variant, index, cwd);
259
+ }
260
+ return coverageMap;
261
+ }
262
+ //# sourceMappingURL=coverage-analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coverage-analyzer.js","sourceRoot":"","sources":["../../../src/analysis/coverage-analyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Knowledge gap signal analyzer.
3
+ *
4
+ * Implements the v0.1 detection pipeline defined in
5
+ * docs/knowledge-gap-signal-spec.md:
6
+ *
7
+ * gap_rate = (samples with ≥1 gap signal) / (successfully-executed samples)
8
+ *
9
+ * Four signal types are extracted per sample:
10
+ * 1. failed_search — Grep/Read/Bash search that returned empty or failed
11
+ * 2. explicit_marker — 【推断】【知识缺口】【未知】 markers in agent output
12
+ * 3. hedging — hedging language in agent output (accepts FP in v0.1)
13
+ * 4. repeated_failure — ≥3 consecutive failed searches of the same tool type
14
+ *
15
+ * Intentionally does NOT touch report rendering, trends, or CI — those are
16
+ * step-3 work. This module only computes the structured GapReport.
17
+ */
18
+ import type { ExecutorFn, GapReport, GapSignalRef, ResultEntry, ToolCallInfo, TurnInfo, VariantResult } from '../types.js';
19
+ import { type ClassifyOptions } from './hedging-classifier.js';
20
+ export type GapSignalType = GapSignalRef['type'];
21
+ export type GapSignal = GapSignalRef;
22
+ /**
23
+ * v0.2 severity weights (spec §6).
24
+ *
25
+ * Strong (1.0): 硬证据类——agent 工具层真的撞墙了
26
+ * - failed_search: Grep/Read 返回空或失败,确定性 miss
27
+ * - repeated_failure: 同一类查询连续 ≥3 次失败,已不是偶然
28
+ *
29
+ * Weak (0.5): 自我陈述类——依赖模型配合,可能假阳
30
+ * - explicit_marker: 依赖 agent 按约定打【推断】等标记,可能漏标
31
+ * - hedging: 字符串匹配 "我不确定/可能是"等,假阳率已知较高(spec §2.8)
32
+ *
33
+ * Aggregation: 每个样本取其信号的最高权重作"样本严重度",平均到 weightedGapRate。
34
+ * weightedGapRate ≤ gapRate,差值反映"软信号占比"——读者据此判断结果可信度。
35
+ */
36
+ export declare const SIGNAL_WEIGHTS: Record<GapSignalType, number>;
37
+ /**
38
+ * Decide whether a tool call counts as a "failed search" signal.
39
+ *
40
+ * Covers:
41
+ * - Read with success: false
42
+ * - Grep with success: false
43
+ * - Grep with success but empty/"No matches found" output (still a miss)
44
+ * - Bash with grep/rg/find in the command and either failure or empty output
45
+ */
46
+ export declare function isFailedSearchTool(tc: ToolCallInfo): boolean;
47
+ /**
48
+ * Extract failed-search signals from a flat tool call sequence.
49
+ * Deduplicates consecutive duplicates (same tool + same pattern) so an agent
50
+ * that retries the exact same Grep 5 times counts as one signal, not five.
51
+ */
52
+ export declare function extractFailedSearchSignals(toolCalls: ToolCallInfo[]): GapSignal[];
53
+ /**
54
+ * Find explicit "I'm inferring / I don't know" markers in agent output text.
55
+ * Each marker occurrence produces one signal; dedupe is at the sample level
56
+ * (handled by the aggregator, not here).
57
+ */
58
+ export declare function extractMarkerSignals(text: string): GapSignal[];
59
+ /**
60
+ * Match hedging-language phrases in agent output text.
61
+ * v0.1 emits at most one hedging signal per sample — the aggregator upgrades
62
+ * this from "per pattern" to "per sample", since multiple hedges in the same
63
+ * turn are usually coming from the same epistemic state.
64
+ */
65
+ export declare function extractHedgingSignals(text: string): GapSignal[];
66
+ /**
67
+ * Detect ≥N consecutive failed searches of the same tool type within a turn
68
+ * sequence. Each qualifying run emits exactly one signal anchored at the
69
+ * first failure in the run.
70
+ */
71
+ export declare function extractRepeatedFailureSignals(turns: TurnInfo[] | undefined): GapSignal[];
72
+ /**
73
+ * Run all four signal extractors on a single variant's result for one sample.
74
+ * Output signals carry the provided sampleId.
75
+ */
76
+ export declare function extractGapSignalsFromSample(variantResult: VariantResult, sampleId: string): GapSignal[];
77
+ /**
78
+ * Compute the gap report for one variant across all samples in a report.
79
+ *
80
+ * Denominator rule (spec §5): samples with `ok: false` (the variant completely
81
+ * failed to execute) are EXCLUDED from both numerator and denominator.
82
+ * gap_rate is computed only on samples that actually produced a trace.
83
+ */
84
+ export declare function computeGapReport(results: ResultEntry[], variant: string): GapReport;
85
+ /**
86
+ * Compute gap reports for every variant in a Report. Convenience wrapper.
87
+ */
88
+ export declare function computeReportGapRates(results: ResultEntry[], variants: string[]): Record<string, GapReport>;
89
+ /**
90
+ * 对一份 GapReport 做 hedging classifier 二次过滤(spec §四.3, v0.2)。
91
+ * 流程:
92
+ * 1) 收集 signals 中所有 type='hedging' 的 candidate
93
+ * 2) 调 classifyHedgingCandidates 拿 verdict
94
+ * 3) verdict.isUncertainty=false 的 signal 丢弃
95
+ * 4) verdict.isUncertainty=true 的保留并挂 classifierVerdict
96
+ * 5) recompute samplesWithGap / gapRate / weightedGapRate / byType
97
+ *
98
+ * 失败降级在 classifier 层:单批失败 → 该 batch 全部 isUncertainty=true (保守保留)。
99
+ * 调用方拿到的 report 永远是合法的,不会因 classifier 失败而崩。
100
+ */
101
+ export declare function applyHedgingClassifier(report: GapReport, executor: ExecutorFn, opts?: ClassifyOptions): Promise<{
102
+ report: GapReport;
103
+ costUSD: number;
104
+ truncated: boolean;
105
+ }>;
106
+ /**
107
+ * 批量为一组 variant 的 gap reports 跑 classifier。
108
+ * 串行(不并行)避免 rate limit + 让 cache hit 在第一批后被后续 batch 复用。
109
+ */
110
+ export declare function applyHedgingClassifierToReports(reports: Record<string, GapReport>, executor: ExecutorFn, opts?: ClassifyOptions): Promise<{
111
+ reports: Record<string, GapReport>;
112
+ costUSD: number;
113
+ }>;
114
+ //# sourceMappingURL=gap-analyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gap-analyzer.d.ts","sourceRoot":"","sources":["../../../src/analysis/gap-analyzer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC3H,OAAO,EAA6B,KAAK,eAAe,EAAyB,MAAM,yBAAyB,CAAC;AAEjH,MAAM,MAAM,aAAa,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;AACjD,MAAM,MAAM,SAAS,GAAG,YAAY,CAAC;AA8BrC;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAKxD,CAAC;AAIF;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,YAAY,GAAG,OAAO,CAqB5D;AAkBD;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,SAAS,EAAE,CAqBjF;AAgBD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,CAoB9D;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,CAiB/D;AAID;;;;GAIG;AACH,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,SAAS,GAAG,SAAS,EAAE,CAoCxF;AAID;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,aAAa,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,CAuBvG;AAID;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,CA+CnF;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAM3G;AAmCD;;;;;;;;;;;GAWG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,SAAS,EACjB,QAAQ,EAAE,UAAU,EACpB,IAAI,CAAC,EAAE,eAAe,GACrB,OAAO,CAAC;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC,CAuCrE;AAED;;;GAGG;AACH,wBAAsB,+BAA+B,CACnD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EAClC,QAAQ,EAAE,UAAU,EACpB,IAAI,CAAC,EAAE,eAAe,GACrB,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CASlE"}