oh-my-knowledge 0.0.1 → 0.19.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 (216) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +600 -322
  3. package/README.zh.md +724 -0
  4. package/dist/src/analysis/coverage-analyzer.d.ts +57 -0
  5. package/dist/src/analysis/coverage-analyzer.d.ts.map +1 -0
  6. package/dist/src/analysis/coverage-analyzer.js +262 -0
  7. package/dist/src/analysis/coverage-analyzer.js.map +1 -0
  8. package/dist/src/analysis/gap-analyzer.d.ts +114 -0
  9. package/dist/src/analysis/gap-analyzer.d.ts.map +1 -0
  10. package/dist/src/analysis/gap-analyzer.js +439 -0
  11. package/dist/src/analysis/gap-analyzer.js.map +1 -0
  12. package/dist/src/analysis/hedging-classifier.d.ts +34 -0
  13. package/dist/src/analysis/hedging-classifier.d.ts.map +1 -0
  14. package/dist/src/analysis/hedging-classifier.js +144 -0
  15. package/dist/src/analysis/hedging-classifier.js.map +1 -0
  16. package/dist/src/analysis/report-diagnostics.d.ts +9 -0
  17. package/dist/src/analysis/report-diagnostics.d.ts.map +1 -0
  18. package/dist/src/analysis/report-diagnostics.js +631 -0
  19. package/dist/src/analysis/report-diagnostics.js.map +1 -0
  20. package/dist/src/authoring/evolver.d.ts +64 -0
  21. package/dist/src/authoring/evolver.d.ts.map +1 -0
  22. package/dist/src/authoring/evolver.js +275 -0
  23. package/dist/src/authoring/evolver.js.map +1 -0
  24. package/dist/src/authoring/generator.d.ts +13 -0
  25. package/dist/src/authoring/generator.d.ts.map +1 -0
  26. package/dist/src/authoring/generator.js +60 -0
  27. package/dist/src/authoring/generator.js.map +1 -0
  28. package/dist/src/cli.d.ts +3 -0
  29. package/dist/src/cli.d.ts.map +1 -0
  30. package/dist/src/cli.js +1012 -0
  31. package/dist/src/cli.js.map +1 -0
  32. package/dist/src/eval-core/cache.d.ts +11 -0
  33. package/dist/src/eval-core/cache.d.ts.map +1 -0
  34. package/dist/src/eval-core/cache.js +53 -0
  35. package/dist/src/eval-core/cache.js.map +1 -0
  36. package/dist/src/eval-core/ci-gates.d.ts +17 -0
  37. package/dist/src/eval-core/ci-gates.d.ts.map +1 -0
  38. package/dist/src/eval-core/ci-gates.js +42 -0
  39. package/dist/src/eval-core/ci-gates.js.map +1 -0
  40. package/dist/src/eval-core/dependency-checker.d.ts +37 -0
  41. package/dist/src/eval-core/dependency-checker.d.ts.map +1 -0
  42. package/dist/src/eval-core/dependency-checker.js +280 -0
  43. package/dist/src/eval-core/dependency-checker.js.map +1 -0
  44. package/dist/src/eval-core/evaluation-execution.d.ts +26 -0
  45. package/dist/src/eval-core/evaluation-execution.d.ts.map +1 -0
  46. package/dist/src/eval-core/evaluation-execution.js +196 -0
  47. package/dist/src/eval-core/evaluation-execution.js.map +1 -0
  48. package/dist/src/eval-core/evaluation-job.d.ts +50 -0
  49. package/dist/src/eval-core/evaluation-job.d.ts.map +1 -0
  50. package/dist/src/eval-core/evaluation-job.js +114 -0
  51. package/dist/src/eval-core/evaluation-job.js.map +1 -0
  52. package/dist/src/eval-core/evaluation-reporting.d.ts +28 -0
  53. package/dist/src/eval-core/evaluation-reporting.d.ts.map +1 -0
  54. package/dist/src/eval-core/evaluation-reporting.js +123 -0
  55. package/dist/src/eval-core/evaluation-reporting.js.map +1 -0
  56. package/dist/src/eval-core/execution-strategy.d.ts +11 -0
  57. package/dist/src/eval-core/execution-strategy.d.ts.map +1 -0
  58. package/dist/src/eval-core/execution-strategy.js +121 -0
  59. package/dist/src/eval-core/execution-strategy.js.map +1 -0
  60. package/dist/src/eval-core/fact-checker.d.ts +25 -0
  61. package/dist/src/eval-core/fact-checker.d.ts.map +1 -0
  62. package/dist/src/eval-core/fact-checker.js +66 -0
  63. package/dist/src/eval-core/fact-checker.js.map +1 -0
  64. package/dist/src/eval-core/schema.d.ts +30 -0
  65. package/dist/src/eval-core/schema.d.ts.map +1 -0
  66. package/dist/src/eval-core/schema.js +195 -0
  67. package/dist/src/eval-core/schema.js.map +1 -0
  68. package/dist/src/eval-core/statistics.d.ts +86 -0
  69. package/dist/src/eval-core/statistics.d.ts.map +1 -0
  70. package/dist/src/eval-core/statistics.js +210 -0
  71. package/dist/src/eval-core/statistics.js.map +1 -0
  72. package/dist/src/eval-core/task-planner.d.ts +4 -0
  73. package/dist/src/eval-core/task-planner.d.ts.map +1 -0
  74. package/dist/src/eval-core/task-planner.js +33 -0
  75. package/dist/src/eval-core/task-planner.js.map +1 -0
  76. package/dist/src/eval-workflows/each-evaluation-workflow.d.ts +137 -0
  77. package/dist/src/eval-workflows/each-evaluation-workflow.d.ts.map +1 -0
  78. package/dist/src/eval-workflows/each-evaluation-workflow.js +174 -0
  79. package/dist/src/eval-workflows/each-evaluation-workflow.js.map +1 -0
  80. package/dist/src/eval-workflows/evaluation-pipeline.d.ts +42 -0
  81. package/dist/src/eval-workflows/evaluation-pipeline.d.ts.map +1 -0
  82. package/dist/src/eval-workflows/evaluation-pipeline.js +218 -0
  83. package/dist/src/eval-workflows/evaluation-pipeline.js.map +1 -0
  84. package/dist/src/eval-workflows/evaluation-preparation.d.ts +64 -0
  85. package/dist/src/eval-workflows/evaluation-preparation.d.ts.map +1 -0
  86. package/dist/src/eval-workflows/evaluation-preparation.js +90 -0
  87. package/dist/src/eval-workflows/evaluation-preparation.js.map +1 -0
  88. package/dist/src/eval-workflows/run-evaluation.d.ts +111 -0
  89. package/dist/src/eval-workflows/run-evaluation.d.ts.map +1 -0
  90. package/dist/src/eval-workflows/run-evaluation.js +272 -0
  91. package/dist/src/eval-workflows/run-evaluation.js.map +1 -0
  92. package/dist/src/executors/anthropic-api.d.ts +3 -0
  93. package/dist/src/executors/anthropic-api.d.ts.map +1 -0
  94. package/dist/src/executors/anthropic-api.js +43 -0
  95. package/dist/src/executors/anthropic-api.js.map +1 -0
  96. package/dist/src/executors/claude-cli.d.ts +3 -0
  97. package/dist/src/executors/claude-cli.d.ts.map +1 -0
  98. package/dist/src/executors/claude-cli.js +103 -0
  99. package/dist/src/executors/claude-cli.js.map +1 -0
  100. package/dist/src/executors/claude-sdk-trace.d.ts +10 -0
  101. package/dist/src/executors/claude-sdk-trace.d.ts.map +1 -0
  102. package/dist/src/executors/claude-sdk-trace.js +100 -0
  103. package/dist/src/executors/claude-sdk-trace.js.map +1 -0
  104. package/dist/src/executors/claude-sdk.d.ts +3 -0
  105. package/dist/src/executors/claude-sdk.d.ts.map +1 -0
  106. package/dist/src/executors/claude-sdk.js +160 -0
  107. package/dist/src/executors/claude-sdk.js.map +1 -0
  108. package/dist/src/executors/gemini.d.ts +3 -0
  109. package/dist/src/executors/gemini.d.ts.map +1 -0
  110. package/dist/src/executors/gemini.js +78 -0
  111. package/dist/src/executors/gemini.js.map +1 -0
  112. package/dist/src/executors/index.d.ts +7 -0
  113. package/dist/src/executors/index.d.ts.map +1 -0
  114. package/dist/src/executors/index.js +22 -0
  115. package/dist/src/executors/index.js.map +1 -0
  116. package/dist/src/executors/openai-api.d.ts +3 -0
  117. package/dist/src/executors/openai-api.d.ts.map +1 -0
  118. package/dist/src/executors/openai-api.js +40 -0
  119. package/dist/src/executors/openai-api.js.map +1 -0
  120. package/dist/src/executors/openai-cli.d.ts +3 -0
  121. package/dist/src/executors/openai-cli.d.ts.map +1 -0
  122. package/dist/src/executors/openai-cli.js +60 -0
  123. package/dist/src/executors/openai-cli.js.map +1 -0
  124. package/dist/src/executors/script.d.ts +3 -0
  125. package/dist/src/executors/script.d.ts.map +1 -0
  126. package/dist/src/executors/script.js +63 -0
  127. package/dist/src/executors/script.js.map +1 -0
  128. package/dist/src/executors/shared.d.ts +117 -0
  129. package/dist/src/executors/shared.d.ts.map +1 -0
  130. package/dist/src/executors/shared.js +49 -0
  131. package/dist/src/executors/shared.js.map +1 -0
  132. package/dist/src/grading/assertions.d.ts +18 -0
  133. package/dist/src/grading/assertions.d.ts.map +1 -0
  134. package/dist/src/grading/assertions.js +239 -0
  135. package/dist/src/grading/assertions.js.map +1 -0
  136. package/dist/src/grading/index.d.ts +26 -0
  137. package/dist/src/grading/index.d.ts.map +1 -0
  138. package/dist/src/grading/index.js +98 -0
  139. package/dist/src/grading/index.js.map +1 -0
  140. package/dist/src/grading/judge.d.ts +13 -0
  141. package/dist/src/grading/judge.d.ts.map +1 -0
  142. package/dist/src/grading/judge.js +98 -0
  143. package/dist/src/grading/judge.js.map +1 -0
  144. package/dist/src/grading/layered-scores.d.ts +13 -0
  145. package/dist/src/grading/layered-scores.d.ts.map +1 -0
  146. package/dist/src/grading/layered-scores.js +62 -0
  147. package/dist/src/grading/layered-scores.js.map +1 -0
  148. package/dist/src/inputs/eval-config.d.ts +13 -0
  149. package/dist/src/inputs/eval-config.d.ts.map +1 -0
  150. package/dist/src/inputs/eval-config.js +136 -0
  151. package/dist/src/inputs/eval-config.js.map +1 -0
  152. package/dist/src/inputs/load-samples.d.ts +16 -0
  153. package/dist/src/inputs/load-samples.d.ts.map +1 -0
  154. package/dist/src/inputs/load-samples.js +51 -0
  155. package/dist/src/inputs/load-samples.js.map +1 -0
  156. package/dist/src/inputs/mcp-resolver.d.ts +50 -0
  157. package/dist/src/inputs/mcp-resolver.d.ts.map +1 -0
  158. package/dist/src/inputs/mcp-resolver.js +307 -0
  159. package/dist/src/inputs/mcp-resolver.js.map +1 -0
  160. package/dist/src/inputs/skill-loader.d.ts +18 -0
  161. package/dist/src/inputs/skill-loader.d.ts.map +1 -0
  162. package/dist/src/inputs/skill-loader.js +222 -0
  163. package/dist/src/inputs/skill-loader.js.map +1 -0
  164. package/dist/src/inputs/url-fetcher.d.ts +19 -0
  165. package/dist/src/inputs/url-fetcher.d.ts.map +1 -0
  166. package/dist/src/inputs/url-fetcher.js +241 -0
  167. package/dist/src/inputs/url-fetcher.js.map +1 -0
  168. package/dist/src/observability/skill-health-analyzer.d.ts +83 -0
  169. package/dist/src/observability/skill-health-analyzer.d.ts.map +1 -0
  170. package/dist/src/observability/skill-health-analyzer.js +238 -0
  171. package/dist/src/observability/skill-health-analyzer.js.map +1 -0
  172. package/dist/src/observability/trace-adapter.d.ts +75 -0
  173. package/dist/src/observability/trace-adapter.d.ts.map +1 -0
  174. package/dist/src/observability/trace-adapter.js +367 -0
  175. package/dist/src/observability/trace-adapter.js.map +1 -0
  176. package/dist/src/renderer/html-renderer.d.ts +9 -0
  177. package/dist/src/renderer/html-renderer.d.ts.map +1 -0
  178. package/dist/src/renderer/html-renderer.js +360 -0
  179. package/dist/src/renderer/html-renderer.js.map +1 -0
  180. package/dist/src/renderer/layout.d.ts +13 -0
  181. package/dist/src/renderer/layout.d.ts.map +1 -0
  182. package/dist/src/renderer/layout.js +582 -0
  183. package/dist/src/renderer/layout.js.map +1 -0
  184. package/dist/src/renderer/skill-health-renderer.d.ts +20 -0
  185. package/dist/src/renderer/skill-health-renderer.d.ts.map +1 -0
  186. package/dist/src/renderer/skill-health-renderer.js +253 -0
  187. package/dist/src/renderer/skill-health-renderer.js.map +1 -0
  188. package/dist/src/renderer/summary.d.ts +21 -0
  189. package/dist/src/renderer/summary.d.ts.map +1 -0
  190. package/dist/src/renderer/summary.js +1072 -0
  191. package/dist/src/renderer/summary.js.map +1 -0
  192. package/dist/src/renderer/table.d.ts +3 -0
  193. package/dist/src/renderer/table.d.ts.map +1 -0
  194. package/dist/src/renderer/table.js +134 -0
  195. package/dist/src/renderer/table.js.map +1 -0
  196. package/dist/src/renderer/trends.d.ts +6 -0
  197. package/dist/src/renderer/trends.d.ts.map +1 -0
  198. package/dist/src/renderer/trends.js +127 -0
  199. package/dist/src/renderer/trends.js.map +1 -0
  200. package/dist/src/server/job-store.d.ts +4 -0
  201. package/dist/src/server/job-store.d.ts.map +1 -0
  202. package/dist/src/server/job-store.js +68 -0
  203. package/dist/src/server/job-store.js.map +1 -0
  204. package/dist/src/server/report-server.d.ts +17 -0
  205. package/dist/src/server/report-server.d.ts.map +1 -0
  206. package/dist/src/server/report-server.js +591 -0
  207. package/dist/src/server/report-server.js.map +1 -0
  208. package/dist/src/server/report-store.d.ts +44 -0
  209. package/dist/src/server/report-store.d.ts.map +1 -0
  210. package/dist/src/server/report-store.js +190 -0
  211. package/dist/src/server/report-store.js.map +1 -0
  212. package/dist/src/types.d.ts +559 -0
  213. package/dist/src/types.d.ts.map +1 -0
  214. package/dist/src/types.js +2 -0
  215. package/dist/src/types.js.map +1 -0
  216. package/package.json +53 -5
@@ -0,0 +1,75 @@
1
+ /**
2
+ * cc session JSONL → omk ResultEntry adapter (v0.18 skill-health)。
3
+ *
4
+ * 核心职责:
5
+ * 1. 读 cc session JSONL 文件 / 目录
6
+ * 2. 按 session 拆分、按 skill 信号切段(见 docs/skill-health-spec.md §四)
7
+ * 3. 每段输出为一个 ResultEntry, variant key = skill 名
8
+ *
9
+ * skill 归属信号(spec §四):
10
+ * - 信号 1: tool_use name="Skill" 的 input.skill
11
+ * - 信号 2: user message 里的 <command-name>/X</command-name>
12
+ * - 无任何信号 → 'general'(裸 cc 对话,不丢弃)
13
+ *
14
+ * v0.18 不处理:
15
+ * - Skill tool 嵌套调用(扁平切段)
16
+ * - 信号 3 (Read .claude/skills/X/SKILL.md,留 v0.19)
17
+ * - 版本对齐(全部归到 skill 名下)
18
+ */
19
+ import type { ResultEntry, ToolCallInfo, TurnInfo } from '../types.js';
20
+ export interface CcSession {
21
+ sessionId: string;
22
+ sourcePath: string;
23
+ records: unknown[];
24
+ cwd?: string;
25
+ gitBranch?: string;
26
+ startTimestamp?: string;
27
+ endTimestamp?: string;
28
+ }
29
+ export interface SkillSegment {
30
+ skillName: string;
31
+ sessionId: string;
32
+ segmentIndex: number;
33
+ startTimestamp: string;
34
+ endTimestamp: string;
35
+ cwd?: string;
36
+ turns: TurnInfo[];
37
+ toolCalls: ToolCallInfo[];
38
+ metrics: {
39
+ durationMs: number;
40
+ inputTokens: number;
41
+ outputTokens: number;
42
+ cacheReadTokens: number;
43
+ cacheCreationTokens: number;
44
+ numTurns: number;
45
+ numToolCalls: number;
46
+ numToolFailures: number;
47
+ };
48
+ }
49
+ /**
50
+ * 加载一个目录(或单个 JSONL 文件)下的所有 cc session。目录递归只一层(cc 的实际布局)。
51
+ */
52
+ export declare function loadCcSessions(path: string): CcSession[];
53
+ /**
54
+ * 扫描 session records, 按 skill 信号把 tool calls 切成多段。
55
+ * 一个 session 可能产生 1-N 个 SkillSegment。
56
+ */
57
+ export declare function segmentBySkill(session: CcSession): SkillSegment[];
58
+ /**
59
+ * SkillSegment[] → ResultEntry[] (omk 内部分析路径的标准输入)。
60
+ *
61
+ * 映射规则(详见 docs/skill-health-spec.md):
62
+ * - 每 segment 一个 ResultEntry
63
+ * - sample_id = `${sessionId}:${segmentIndex}`
64
+ * - variant key = skill 名(复用 omk 的 variant 维度作为 skill 分组维度)
65
+ */
66
+ export declare function segmentsToResultEntries(segments: SkillSegment[]): ResultEntry[];
67
+ /**
68
+ * 一站式:目录 → ResultEntry[]。
69
+ */
70
+ export declare function ccTracesToResultEntries(path: string): {
71
+ entries: ResultEntry[];
72
+ sessions: CcSession[];
73
+ segments: SkillSegment[];
74
+ };
75
+ //# sourceMappingURL=trace-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace-adapter.d.ts","sourceRoot":"","sources":["../../../src/observability/trace-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAiB,MAAM,aAAa,CAAC;AA+DtF,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IAInB,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,OAAO,EAAE;QACP,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,eAAe,EAAE,MAAM,CAAC;QACxB,mBAAmB,EAAE,MAAM,CAAC;QAC5B,QAAQ,EAAE,MAAM,CAAC;QACjB,YAAY,EAAE,MAAM,CAAC;QACrB,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;CACH;AAID;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,CASxD;AAkHD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,SAAS,GAAG,YAAY,EAAE,CAqHjE;AAkDD;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,WAAW,EAAE,CAO/E;AAgCD;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,WAAW,EAAE,CAAC;IAAC,QAAQ,EAAE,SAAS,EAAE,CAAC;IAAC,QAAQ,EAAE,YAAY,EAAE,CAAA;CAAE,CAKjI"}
@@ -0,0 +1,367 @@
1
+ /**
2
+ * cc session JSONL → omk ResultEntry adapter (v0.18 skill-health)。
3
+ *
4
+ * 核心职责:
5
+ * 1. 读 cc session JSONL 文件 / 目录
6
+ * 2. 按 session 拆分、按 skill 信号切段(见 docs/skill-health-spec.md §四)
7
+ * 3. 每段输出为一个 ResultEntry, variant key = skill 名
8
+ *
9
+ * skill 归属信号(spec §四):
10
+ * - 信号 1: tool_use name="Skill" 的 input.skill
11
+ * - 信号 2: user message 里的 <command-name>/X</command-name>
12
+ * - 无任何信号 → 'general'(裸 cc 对话,不丢弃)
13
+ *
14
+ * v0.18 不处理:
15
+ * - Skill tool 嵌套调用(扁平切段)
16
+ * - 信号 3 (Read .claude/skills/X/SKILL.md,留 v0.19)
17
+ * - 版本对齐(全部归到 skill 名下)
18
+ */
19
+ import { readFileSync, readdirSync, statSync } from 'node:fs';
20
+ import { join } from 'node:path';
21
+ // ---------- Load ----------
22
+ /**
23
+ * 加载一个目录(或单个 JSONL 文件)下的所有 cc session。目录递归只一层(cc 的实际布局)。
24
+ */
25
+ export function loadCcSessions(path) {
26
+ const stat = statSync(path);
27
+ if (stat.isFile()) {
28
+ return [parseCcSessionFile(path)];
29
+ }
30
+ const entries = readdirSync(path)
31
+ .filter((f) => f.endsWith('.jsonl'))
32
+ .map((f) => join(path, f));
33
+ return entries.map(parseCcSessionFile).filter((s) => s !== null);
34
+ }
35
+ function parseCcSessionFile(filePath) {
36
+ const content = readFileSync(filePath, 'utf-8');
37
+ const records = [];
38
+ for (const line of content.split('\n')) {
39
+ const trimmed = line.trim();
40
+ if (!trimmed)
41
+ continue;
42
+ try {
43
+ records.push(JSON.parse(trimmed));
44
+ }
45
+ catch {
46
+ // malformed line → skip. cc 有罕见的截断 record, 不让单行 fail 整个 session
47
+ }
48
+ }
49
+ const first = records.find((r) => 'sessionId' in r && typeof r.sessionId === 'string');
50
+ const last = [...records].reverse().find((r) => 'timestamp' in r && typeof r.timestamp === 'string');
51
+ return {
52
+ sessionId: first?.sessionId ?? filePath.split('/').pop().replace('.jsonl', ''),
53
+ sourcePath: filePath,
54
+ records,
55
+ cwd: first?.cwd,
56
+ gitBranch: first?.gitBranch,
57
+ startTimestamp: first?.timestamp,
58
+ endTimestamp: last?.timestamp,
59
+ };
60
+ }
61
+ // ---------- Skill signal detection ----------
62
+ const COMMAND_NAME_RE = /<command-name>\/([^<]+)<\/command-name>/;
63
+ // cc 内置 CLI 命令(不是 skill)。dogfood 数据中这些词频繁以 <command-name> 出现,
64
+ // 必须过滤掉才能得到真实 skill 分布。列表基于实测 + cc 常规命令集。
65
+ const CC_BUILTIN_COMMANDS = new Set([
66
+ 'clear', 'exit', 'quit', 'help', 'fast', 'effort', 'model',
67
+ 'plugin', 'stats', 'doctor', 'compact', 'cost', 'agents', 'init',
68
+ 'config', 'permissions', 'resume', 'continue', 'memory',
69
+ ]);
70
+ /**
71
+ * 归一化 skill 名: 去掉 plugin 前缀, 过滤 cc 内置命令。
72
+ * - "impeccable:audit" → "audit"
73
+ * - "pbakaus/impeccable:audit" → "audit"
74
+ * - "clear" / "exit" 等 → null(表示不是 skill)
75
+ */
76
+ function normalizeSkillName(raw) {
77
+ // plugin-prefixed: pbakaus/impeccable:audit / impeccable:audit → 取最后一段
78
+ const colonIdx = raw.lastIndexOf(':');
79
+ const name = colonIdx >= 0 ? raw.slice(colonIdx + 1) : raw;
80
+ if (CC_BUILTIN_COMMANDS.has(name))
81
+ return null;
82
+ return name;
83
+ }
84
+ /**
85
+ * 从 user message 里提取 slash-command skill 名字(信号 2)。
86
+ * 返回 null 表示没命中。
87
+ */
88
+ function extractCommandSkill(record) {
89
+ const content = record.message.content;
90
+ let raw = null;
91
+ if (typeof content === 'string') {
92
+ const m = COMMAND_NAME_RE.exec(content);
93
+ raw = m ? m[1] : null;
94
+ }
95
+ else {
96
+ for (const part of content) {
97
+ if (part.type === 'text') {
98
+ const m = COMMAND_NAME_RE.exec(part.text);
99
+ if (m) {
100
+ raw = m[1];
101
+ break;
102
+ }
103
+ }
104
+ }
105
+ }
106
+ return raw ? normalizeSkillName(raw) : null;
107
+ }
108
+ /**
109
+ * 从 assistant message 的 tool_use 里提取 Skill tool 调用的 skill 名字(信号 1)。
110
+ * 返回 null 表示没命中。
111
+ */
112
+ function extractSkillToolUse(record) {
113
+ for (const part of record.message.content) {
114
+ if (part.type === 'tool_use' && part.name === 'Skill') {
115
+ const skill = part.input?.skill;
116
+ if (typeof skill === 'string')
117
+ return normalizeSkillName(skill);
118
+ }
119
+ }
120
+ return null;
121
+ }
122
+ const SKILL_READ_FILE_RE = /\.claude\/skills\/([^/]+)\/SKILL\.md$/;
123
+ /**
124
+ * 从 assistant message 的 Read tool_use 里提取 skill 名字(信号 3, fallback)。
125
+ * 匹配 file_path 形如 ".claude/skills/<name>/SKILL.md" 的模式。
126
+ * 返回 null 表示没命中。
127
+ */
128
+ function extractSkillReadFile(record) {
129
+ for (const part of record.message.content) {
130
+ if (part.type === 'tool_use' && part.name === 'Read') {
131
+ const filePath = part.input?.file_path;
132
+ if (typeof filePath === 'string') {
133
+ const m = SKILL_READ_FILE_RE.exec(filePath);
134
+ if (m)
135
+ return normalizeSkillName(m[1]);
136
+ }
137
+ }
138
+ }
139
+ return null;
140
+ }
141
+ // ---------- Segment by skill ----------
142
+ /**
143
+ * 扫描 session records, 按 skill 信号把 tool calls 切成多段。
144
+ * 一个 session 可能产生 1-N 个 SkillSegment。
145
+ */
146
+ export function segmentBySkill(session) {
147
+ const segments = [];
148
+ let currentSkill = 'general';
149
+ let currentSegment = createEmptySegment(session, currentSkill, 0);
150
+ let segmentIndex = 0;
151
+ // 用 tool_use_id → ToolCallInfo 的映射, 收到 tool_result 时回填 output / success
152
+ const pendingToolUses = new Map();
153
+ const flushCurrent = () => {
154
+ if (currentSegment.turns.length > 0 || currentSegment.toolCalls.length > 0) {
155
+ segments.push(currentSegment);
156
+ return true;
157
+ }
158
+ return false;
159
+ };
160
+ const startNewSegment = (skillName, timestamp) => {
161
+ // 空段被新信号替换时,不推进 segmentIndex(保持整洁的 0-based 编号)
162
+ const wasNonEmpty = flushCurrent();
163
+ if (wasNonEmpty)
164
+ segmentIndex += 1;
165
+ currentSegment = createEmptySegment(session, skillName, segmentIndex, timestamp);
166
+ currentSkill = skillName;
167
+ };
168
+ for (const raw of session.records) {
169
+ // records 是 unknown[], 按 type 字段做 structural type guard
170
+ if (!raw || typeof raw !== 'object' || !('type' in raw))
171
+ continue;
172
+ const rec = raw;
173
+ if (rec.type === 'user') {
174
+ const u = rec;
175
+ // 检测 skill 信号 2 (slash command)
176
+ const cmdSkill = extractCommandSkill(u);
177
+ if (cmdSkill && cmdSkill !== currentSkill) {
178
+ startNewSegment(cmdSkill, u.timestamp);
179
+ }
180
+ // 处理 tool_result(回填之前的 tool_use)
181
+ if (typeof u.message.content !== 'string') {
182
+ for (const part of u.message.content) {
183
+ if (part.type === 'tool_result') {
184
+ const pending = pendingToolUses.get(part.tool_use_id);
185
+ if (pending) {
186
+ pending.toolCall.output = part.content;
187
+ pending.toolCall.success = part.is_error !== true;
188
+ if (part.is_error === true) {
189
+ pending.segmentRef.metrics.numToolFailures += 1;
190
+ }
191
+ pendingToolUses.delete(part.tool_use_id);
192
+ }
193
+ }
194
+ }
195
+ }
196
+ // user text 合并到 tool turn(简化处理, 不强区分角色)
197
+ const textContent = extractUserText(u);
198
+ if (textContent) {
199
+ currentSegment.turns.push({ role: 'tool', content: textContent });
200
+ currentSegment.metrics.numTurns += 1;
201
+ }
202
+ updateSegmentTimestamp(currentSegment, u.timestamp);
203
+ continue;
204
+ }
205
+ if (rec.type === 'assistant') {
206
+ const a = rec;
207
+ // 检测 skill 信号 1 (Skill tool_use); 信号 3 (Read SKILL.md) 作 fallback,
208
+ // 仅在当前段仍是 'general'(未被信号 1/2 命中过)时触发,避免压过更强信号。
209
+ const skillTool = extractSkillToolUse(a);
210
+ if (skillTool && skillTool !== currentSkill) {
211
+ startNewSegment(skillTool, a.timestamp);
212
+ }
213
+ else if (!skillTool && currentSkill === 'general') {
214
+ const readSkill = extractSkillReadFile(a);
215
+ if (readSkill) {
216
+ startNewSegment(readSkill, a.timestamp);
217
+ }
218
+ }
219
+ // 提取 tool_use → ToolCallInfo(success 先标 true, 等 tool_result 回填)
220
+ const toolCalls = [];
221
+ let assistantText = '';
222
+ for (const part of a.message.content) {
223
+ if (part.type === 'text' && part.text)
224
+ assistantText += part.text;
225
+ if (part.type === 'tool_use' && part.id && part.name) {
226
+ const tc = {
227
+ tool: part.name,
228
+ input: part.input ?? {},
229
+ output: '',
230
+ success: true,
231
+ };
232
+ toolCalls.push(tc);
233
+ pendingToolUses.set(part.id, { toolCall: tc, segmentRef: currentSegment });
234
+ }
235
+ }
236
+ if (toolCalls.length > 0 || assistantText) {
237
+ currentSegment.turns.push({
238
+ role: 'assistant',
239
+ content: assistantText,
240
+ toolCalls: toolCalls.length > 0 ? toolCalls : undefined,
241
+ });
242
+ currentSegment.metrics.numTurns += 1;
243
+ currentSegment.toolCalls.push(...toolCalls);
244
+ currentSegment.metrics.numToolCalls += toolCalls.length;
245
+ }
246
+ // 累加 token usage
247
+ const usage = a.message.usage;
248
+ if (usage) {
249
+ currentSegment.metrics.inputTokens += usage.input_tokens ?? 0;
250
+ currentSegment.metrics.outputTokens += usage.output_tokens ?? 0;
251
+ currentSegment.metrics.cacheReadTokens += usage.cache_read_input_tokens ?? 0;
252
+ currentSegment.metrics.cacheCreationTokens += usage.cache_creation_input_tokens ?? 0;
253
+ }
254
+ updateSegmentTimestamp(currentSegment, a.timestamp);
255
+ continue;
256
+ }
257
+ // 其他 type(permission-mode / file-history-snapshot) 直接 skip
258
+ }
259
+ flushCurrent();
260
+ // 孤儿 tool_use(没对应 tool_result 的)保持 success=true, 但标记为未闭合
261
+ return segments;
262
+ }
263
+ function createEmptySegment(session, skillName, index, timestamp) {
264
+ const ts = timestamp ?? session.startTimestamp ?? new Date().toISOString();
265
+ return {
266
+ skillName,
267
+ sessionId: session.sessionId,
268
+ segmentIndex: index,
269
+ startTimestamp: ts,
270
+ endTimestamp: ts,
271
+ cwd: session.cwd,
272
+ turns: [],
273
+ toolCalls: [],
274
+ metrics: {
275
+ durationMs: 0,
276
+ inputTokens: 0,
277
+ outputTokens: 0,
278
+ cacheReadTokens: 0,
279
+ cacheCreationTokens: 0,
280
+ numTurns: 0,
281
+ numToolCalls: 0,
282
+ numToolFailures: 0,
283
+ },
284
+ };
285
+ }
286
+ function updateSegmentTimestamp(seg, timestamp) {
287
+ if (!timestamp)
288
+ return;
289
+ if (!seg.endTimestamp || timestamp > seg.endTimestamp)
290
+ seg.endTimestamp = timestamp;
291
+ // 重算 durationMs
292
+ try {
293
+ const start = new Date(seg.startTimestamp).getTime();
294
+ const end = new Date(seg.endTimestamp).getTime();
295
+ if (!Number.isNaN(start) && !Number.isNaN(end))
296
+ seg.metrics.durationMs = Math.max(0, end - start);
297
+ }
298
+ catch { /* skip */ }
299
+ }
300
+ function extractUserText(record) {
301
+ const content = record.message.content;
302
+ if (typeof content === 'string')
303
+ return content;
304
+ const parts = [];
305
+ for (const p of content) {
306
+ if (p.type === 'text')
307
+ parts.push(p.text);
308
+ if (p.type === 'tool_result' && typeof p.content === 'string')
309
+ parts.push(p.content);
310
+ }
311
+ return parts.join('\n');
312
+ }
313
+ // ---------- Segment → ResultEntry ----------
314
+ /**
315
+ * SkillSegment[] → ResultEntry[] (omk 内部分析路径的标准输入)。
316
+ *
317
+ * 映射规则(详见 docs/skill-health-spec.md):
318
+ * - 每 segment 一个 ResultEntry
319
+ * - sample_id = `${sessionId}:${segmentIndex}`
320
+ * - variant key = skill 名(复用 omk 的 variant 维度作为 skill 分组维度)
321
+ */
322
+ export function segmentsToResultEntries(segments) {
323
+ return segments.map((seg) => ({
324
+ sample_id: `${seg.sessionId}:${seg.segmentIndex}`,
325
+ variants: {
326
+ [seg.skillName]: buildVariantResult(seg),
327
+ },
328
+ }));
329
+ }
330
+ function buildVariantResult(seg) {
331
+ const totalTokens = seg.metrics.inputTokens + seg.metrics.outputTokens;
332
+ const toolSuccessRate = seg.metrics.numToolCalls > 0
333
+ ? (seg.metrics.numToolCalls - seg.metrics.numToolFailures) / seg.metrics.numToolCalls
334
+ : 1;
335
+ return {
336
+ ok: true,
337
+ durationMs: seg.metrics.durationMs,
338
+ durationApiMs: seg.metrics.durationMs,
339
+ inputTokens: seg.metrics.inputTokens,
340
+ outputTokens: seg.metrics.outputTokens,
341
+ totalTokens,
342
+ cacheReadTokens: seg.metrics.cacheReadTokens,
343
+ cacheCreationTokens: seg.metrics.cacheCreationTokens,
344
+ execCostUSD: 0,
345
+ judgeCostUSD: 0,
346
+ costUSD: 0,
347
+ numTurns: seg.metrics.numTurns,
348
+ numToolCalls: seg.metrics.numToolCalls,
349
+ numToolFailures: seg.metrics.numToolFailures,
350
+ toolSuccessRate,
351
+ toolNames: Array.from(new Set(seg.toolCalls.map((tc) => tc.tool))),
352
+ outputPreview: null,
353
+ turns: seg.turns,
354
+ toolCalls: seg.toolCalls,
355
+ };
356
+ }
357
+ // ---------- 顶层便捷入口 ----------
358
+ /**
359
+ * 一站式:目录 → ResultEntry[]。
360
+ */
361
+ export function ccTracesToResultEntries(path) {
362
+ const sessions = loadCcSessions(path);
363
+ const segments = sessions.flatMap(segmentBySkill);
364
+ const entries = segmentsToResultEntries(segments);
365
+ return { entries, sessions, segments };
366
+ }
367
+ //# sourceMappingURL=trace-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace-adapter.js","sourceRoot":"","sources":["../../../src/observability/trace-adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * HTML report renderer — orchestrates sub-modules.
3
+ */
4
+ import type { Report, Lang } from '../types.js';
5
+ export declare function renderRunList(runs: Report[], lang?: Lang): string;
6
+ export declare function renderRunDetail(report: Report | null, lang?: Lang): string;
7
+ export declare function renderEachRunDetail(report: Report | null, lang?: Lang): string;
8
+ export declare function renderTrendsPage(variantName: string, runs: Report[], lang?: Lang): string;
9
+ //# sourceMappingURL=html-renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html-renderer.d.ts","sourceRoot":"","sources":["../../../src/renderer/html-renderer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAYH,OAAO,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAMhD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,GAAE,IAAmB,GAAG,MAAM,CAwH/E;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,GAAE,IAAmB,GAAG,MAAM,CAgJxF;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,GAAE,IAAmB,GAAG,MAAM,CAgG5F;AAED,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,GAAE,IAAmB,GAAG,MAAM,CAGvG"}