oh-my-knowledge 0.28.0 → 0.29.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 (79) hide show
  1. package/README.md +39 -0
  2. package/README.zh.md +39 -0
  3. package/dist/src/analysis/failure-clusterer.js +1 -1
  4. package/dist/src/analysis/failure-clusterer.js.map +1 -1
  5. package/dist/src/analysis/gap-analyzer.d.ts +8 -1
  6. package/dist/src/analysis/gap-analyzer.d.ts.map +1 -1
  7. package/dist/src/analysis/gap-analyzer.js +65 -33
  8. package/dist/src/analysis/gap-analyzer.js.map +1 -1
  9. package/dist/src/analysis/sample-diagnostics.js +14 -14
  10. package/dist/src/analysis/sample-diagnostics.js.map +1 -1
  11. package/dist/src/cli/commands/observe.d.ts.map +1 -1
  12. package/dist/src/cli/commands/observe.js +169 -0
  13. package/dist/src/cli/commands/observe.js.map +1 -1
  14. package/dist/src/cli/commands/registry.d.ts.map +1 -1
  15. package/dist/src/cli/commands/registry.js +9 -1
  16. package/dist/src/cli/commands/registry.js.map +1 -1
  17. package/dist/src/cli/commands/studio.d.ts.map +1 -1
  18. package/dist/src/cli/commands/studio.js +8 -0
  19. package/dist/src/cli/commands/studio.js.map +1 -1
  20. package/dist/src/cli/i18n-dict.d.ts +1 -1
  21. package/dist/src/cli/i18n-dict.d.ts.map +1 -1
  22. package/dist/src/cli/i18n-dict.js +125 -11
  23. package/dist/src/cli/i18n-dict.js.map +1 -1
  24. package/dist/src/grading/debias-validate.js +4 -4
  25. package/dist/src/grading/debias-validate.js.map +1 -1
  26. package/dist/src/grading/gold-cli.js +2 -2
  27. package/dist/src/grading/gold-cli.js.map +1 -1
  28. package/dist/src/observability/inbox-view-model.d.ts +17 -0
  29. package/dist/src/observability/inbox-view-model.d.ts.map +1 -0
  30. package/dist/src/observability/inbox-view-model.js +62 -0
  31. package/dist/src/observability/inbox-view-model.js.map +1 -0
  32. package/dist/src/observability/inbox.d.ts +100 -0
  33. package/dist/src/observability/inbox.d.ts.map +1 -0
  34. package/dist/src/observability/inbox.js +703 -0
  35. package/dist/src/observability/inbox.js.map +1 -0
  36. package/dist/src/observability/trace-adapter.d.ts +12 -64
  37. package/dist/src/observability/trace-adapter.d.ts.map +1 -1
  38. package/dist/src/observability/trace-adapter.js +9 -355
  39. package/dist/src/observability/trace-adapter.js.map +1 -1
  40. package/dist/src/observability/trace-attribution.d.ts +28 -0
  41. package/dist/src/observability/trace-attribution.d.ts.map +1 -0
  42. package/dist/src/observability/trace-attribution.js +104 -0
  43. package/dist/src/observability/trace-attribution.js.map +1 -0
  44. package/dist/src/observability/trace-segmenter.d.ts +42 -0
  45. package/dist/src/observability/trace-segmenter.d.ts.map +1 -0
  46. package/dist/src/observability/trace-segmenter.js +231 -0
  47. package/dist/src/observability/trace-segmenter.js.map +1 -0
  48. package/dist/src/observability/trace-source.d.ts +72 -0
  49. package/dist/src/observability/trace-source.d.ts.map +1 -0
  50. package/dist/src/observability/trace-source.js +142 -0
  51. package/dist/src/observability/trace-source.js.map +1 -0
  52. package/dist/src/renderer/html-renderer.d.ts.map +1 -1
  53. package/dist/src/renderer/html-renderer.js +107 -59
  54. package/dist/src/renderer/html-renderer.js.map +1 -1
  55. package/dist/src/renderer/layout.d.ts.map +1 -1
  56. package/dist/src/renderer/layout.js +58 -21
  57. package/dist/src/renderer/layout.js.map +1 -1
  58. package/dist/src/renderer/observation-inbox-renderer.d.ts +4 -0
  59. package/dist/src/renderer/observation-inbox-renderer.d.ts.map +1 -0
  60. package/dist/src/renderer/observation-inbox-renderer.js +900 -0
  61. package/dist/src/renderer/observation-inbox-renderer.js.map +1 -0
  62. package/dist/src/renderer/summary.d.ts +17 -0
  63. package/dist/src/renderer/summary.d.ts.map +1 -1
  64. package/dist/src/renderer/summary.js +277 -33
  65. package/dist/src/renderer/summary.js.map +1 -1
  66. package/dist/src/renderer/trends.d.ts.map +1 -1
  67. package/dist/src/renderer/trends.js +3 -1
  68. package/dist/src/renderer/trends.js.map +1 -1
  69. package/dist/src/server/report-server.d.ts +3 -1
  70. package/dist/src/server/report-server.d.ts.map +1 -1
  71. package/dist/src/server/report-server.js +35 -4
  72. package/dist/src/server/report-server.js.map +1 -1
  73. package/dist/src/shared/tool-search.d.ts +9 -0
  74. package/dist/src/shared/tool-search.d.ts.map +1 -0
  75. package/dist/src/shared/tool-search.js +104 -0
  76. package/dist/src/shared/tool-search.js.map +1 -0
  77. package/dist/src/types/executor.d.ts +4 -0
  78. package/dist/src/types/executor.d.ts.map +1 -1
  79. package/package.json +1 -1
@@ -0,0 +1,104 @@
1
+ /** Skill attribution rules for trace records. */
2
+ // ---------- Skill signal detection ----------
3
+ export function extractMarkdownLogSkill(text) {
4
+ const patterns = [
5
+ /\b(?:prefer|use|call|invoke)\s+`?([a-zA-Z0-9][\w.-]*)`?\s+skill\b/i,
6
+ /优先调用\s+`?([a-zA-Z0-9][\w.-]*)`?\s+skill/i,
7
+ /调用\s+`?([a-zA-Z0-9][\w.-]*)`?\s+skill/i,
8
+ /使用\s+`?([a-zA-Z0-9][\w.-]*)`?\s+skill/i,
9
+ /`([a-zA-Z0-9][\w.-]*)`\s+skill/i,
10
+ /\b([a-zA-Z0-9][\w.-]*-[\w.-]*)\s+skill\b/i,
11
+ ];
12
+ for (const pattern of patterns) {
13
+ const match = text.match(pattern);
14
+ const normalized = match?.[1] ? normalizeSkillName(match[1]) : null;
15
+ if (normalized)
16
+ return normalized;
17
+ }
18
+ return null;
19
+ }
20
+ const COMMAND_NAME_RE = /<command-name>\/([^<]+)<\/command-name>/;
21
+ // cc 内置 CLI 命令(不是 skill)。dogfood 数据中这些词频繁以 <command-name> 出现,
22
+ // 必须过滤掉才能得到真实 skill 分布。列表基于实测 + cc 常规命令集。
23
+ const CC_BUILTIN_COMMANDS = new Set([
24
+ 'clear', 'exit', 'quit', 'help', 'fast', 'effort', 'model',
25
+ 'plugin', 'stats', 'doctor', 'compact', 'cost', 'agents', 'init',
26
+ 'config', 'permissions', 'resume', 'continue', 'memory',
27
+ ]);
28
+ /**
29
+ * 归一化 skill 名: 去掉 plugin 前缀, 过滤 cc 内置命令。
30
+ * - "impeccable:audit" → "audit"
31
+ * - "pbakaus/impeccable:audit" → "audit"
32
+ * - "clear" / "exit" 等 → null(表示不是 skill)
33
+ */
34
+ export function normalizeSkillName(raw) {
35
+ // plugin-prefixed: pbakaus/impeccable:audit / impeccable:audit → 取最后一段
36
+ const colonIdx = raw.lastIndexOf(':');
37
+ const name = colonIdx >= 0 ? raw.slice(colonIdx + 1) : raw;
38
+ if (CC_BUILTIN_COMMANDS.has(name))
39
+ return null;
40
+ return name;
41
+ }
42
+ /**
43
+ * 从 user message 里提取 slash-command skill 名字(信号 2)。
44
+ * 返回 null 表示没命中。
45
+ */
46
+ export function extractCommandSkill(record) {
47
+ const content = record.message.content;
48
+ let raw = null;
49
+ if (typeof content === 'string') {
50
+ const m = COMMAND_NAME_RE.exec(content);
51
+ raw = m ? m[1] : null;
52
+ }
53
+ else {
54
+ for (const part of content) {
55
+ if (part.type === 'text') {
56
+ const m = COMMAND_NAME_RE.exec(part.text);
57
+ if (m) {
58
+ raw = m[1];
59
+ break;
60
+ }
61
+ }
62
+ }
63
+ }
64
+ return raw ? normalizeSkillName(raw) : null;
65
+ }
66
+ /**
67
+ * 从 assistant message 的 tool_use 里提取 Skill tool 调用的 skill 名字(信号 1)。
68
+ * 返回 null 表示没命中。
69
+ */
70
+ export function extractSkillToolUse(record) {
71
+ const content = Array.isArray(record.message.content) ? record.message.content : [];
72
+ for (const part of content) {
73
+ if (part.type === 'tool_use' && part.name === 'Skill') {
74
+ const skill = part.input?.skill;
75
+ if (typeof skill === 'string')
76
+ return normalizeSkillName(skill);
77
+ }
78
+ }
79
+ return null;
80
+ }
81
+ export function extractAttributionSkill(record) {
82
+ return record.attributionSkill ? normalizeSkillName(record.attributionSkill) : null;
83
+ }
84
+ const SKILL_READ_FILE_RE = /\.claude\/skills\/([^/]+)\/SKILL\.md$/;
85
+ /**
86
+ * 从 assistant message 的 Read tool_use 里提取 skill 名字(信号 3, fallback)。
87
+ * 匹配 file_path 形如 ".claude/skills/<name>/SKILL.md" 的模式。
88
+ * 返回 null 表示没命中。
89
+ */
90
+ export function extractSkillReadFile(record) {
91
+ const content = Array.isArray(record.message.content) ? record.message.content : [];
92
+ for (const part of content) {
93
+ if (part.type === 'tool_use' && part.name === 'Read') {
94
+ const filePath = part.input?.file_path;
95
+ if (typeof filePath === 'string') {
96
+ const m = SKILL_READ_FILE_RE.exec(filePath);
97
+ if (m)
98
+ return normalizeSkillName(m[1]);
99
+ }
100
+ }
101
+ }
102
+ return null;
103
+ }
104
+ //# sourceMappingURL=trace-attribution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace-attribution.js","sourceRoot":"","sources":["../../../src/observability/trace-attribution.ts"],"names":[],"mappings":"AAAA,iDAAiD;AAIjD,+CAA+C;AAE/C,MAAM,UAAU,uBAAuB,CAAC,IAAY;IAClD,MAAM,QAAQ,GAAG;QACf,oEAAoE;QACpE,0CAA0C;QAC1C,wCAAwC;QACxC,wCAAwC;QACxC,iCAAiC;QACjC,2CAA2C;KAC5C,CAAC;IACF,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAClC,MAAM,UAAU,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACpE,IAAI,UAAU;YAAE,OAAO,UAAU,CAAC;IACpC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,eAAe,GAAG,yCAAyC,CAAC;AAElE,8DAA8D;AAC9D,0CAA0C;AAC1C,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC;IAClC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO;IAC1D,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAChE,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ;CACxD,CAAC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC5C,uEAAuE;IACvE,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACtC,MAAM,IAAI,GAAG,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAC3D,IAAI,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC/C,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAoB;IACtD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;IACvC,IAAI,GAAG,GAAkB,IAAI,CAAC;IAC9B,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAChC,MAAM,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACxB,CAAC;SAAM,CAAC;QACN,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;YAC3B,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBACzB,MAAM,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC1C,IAAI,CAAC,EAAE,CAAC;oBAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;oBAAC,MAAM;gBAAC,CAAC;YAC/B,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC,CAAC,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAyB;IAC3D,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IACpF,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;QAC3B,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YACtD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC;YAChC,IAAI,OAAO,KAAK,KAAK,QAAQ;gBAAE,OAAO,kBAAkB,CAAC,KAAK,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,MAAyB;IAC/D,OAAO,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,kBAAkB,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACtF,CAAC;AAED,MAAM,kBAAkB,GAAG,uCAAuC,CAAC;AAEnE;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAyB;IAC5D,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IACpF,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;QAC3B,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC;YACvC,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBACjC,MAAM,CAAC,GAAG,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAC5C,IAAI,CAAC;oBAAE,OAAO,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,42 @@
1
+ /** Skill segmentation and ResultEntry projection for loaded traces. */
2
+ import type { ResultEntry, ToolCallInfo, TurnInfo } from '../types/index.js';
3
+ import type { CcSession } from './trace-source.js';
4
+ export interface SkillSegment {
5
+ skillName: string;
6
+ attribution?: {
7
+ source: 'skill-tool' | 'command-name' | 'read-skill-md' | 'general';
8
+ confidence: number;
9
+ };
10
+ sessionId: string;
11
+ segmentIndex: number;
12
+ startTimestamp: string;
13
+ endTimestamp: string;
14
+ cwd?: string;
15
+ turns: TurnInfo[];
16
+ toolCalls: ToolCallInfo[];
17
+ metrics: {
18
+ durationMs: number;
19
+ inputTokens: number;
20
+ outputTokens: number;
21
+ cacheReadTokens: number;
22
+ cacheCreationTokens: number;
23
+ numTurns: number;
24
+ numToolCalls: number;
25
+ numToolFailures: number;
26
+ };
27
+ }
28
+ /**
29
+ * 扫描 session records, 按 skill 信号把 tool calls 切成多段。
30
+ * 一个 session 可能产生 1-N 个 SkillSegment。
31
+ */
32
+ export declare function segmentBySkill(session: CcSession): SkillSegment[];
33
+ /**
34
+ * SkillSegment[] → ResultEntry[] (omk 内部分析路径的标准输入)。
35
+ *
36
+ * 映射规则(详见 docs/skill-health-spec.md):
37
+ * - 每 segment 一个 ResultEntry
38
+ * - sample_id = `${sessionId}:${segmentIndex}`
39
+ * - variant key = skill 名(复用 omk 的 variant 维度作为 skill 分组维度)
40
+ */
41
+ export declare function segmentsToResultEntries(segments: SkillSegment[]): ResultEntry[];
42
+ //# sourceMappingURL=trace-segmenter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace-segmenter.d.ts","sourceRoot":"","sources":["../../../src/observability/trace-segmenter.ts"],"names":[],"mappings":"AAAA,uEAAuE;AAEvE,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAiB,MAAM,mBAAmB,CAAC;AAC5F,OAAO,KAAK,EAAqB,SAAS,EAAgB,MAAM,mBAAmB,CAAC;AAGpF,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE;QACZ,MAAM,EAAE,YAAY,GAAG,cAAc,GAAG,eAAe,GAAG,SAAS,CAAC;QACpE,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,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;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,SAAS,GAAG,YAAY,EAAE,CA+HjE;AAmDD;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,WAAW,EAAE,CAO/E"}
@@ -0,0 +1,231 @@
1
+ /** Skill segmentation and ResultEntry projection for loaded traces. */
2
+ import { extractAttributionSkill, extractCommandSkill, extractSkillReadFile, extractSkillToolUse } from './trace-attribution.js';
3
+ // ---------- Segment by skill ----------
4
+ /**
5
+ * 扫描 session records, 按 skill 信号把 tool calls 切成多段。
6
+ * 一个 session 可能产生 1-N 个 SkillSegment。
7
+ */
8
+ export function segmentBySkill(session) {
9
+ const segments = [];
10
+ let currentSkill = 'general';
11
+ let currentSegment = createEmptySegment(session, currentSkill, 0);
12
+ let segmentIndex = 0;
13
+ // 用 tool_use_id → ToolCallInfo 的映射, 收到 tool_result 时回填 output / success
14
+ const pendingToolUses = new Map();
15
+ const flushCurrent = () => {
16
+ if (currentSegment.turns.length > 0 || currentSegment.toolCalls.length > 0) {
17
+ segments.push(currentSegment);
18
+ return true;
19
+ }
20
+ return false;
21
+ };
22
+ const startNewSegment = (skillName, timestamp, attribution) => {
23
+ // 空段被新信号替换时,不推进 segmentIndex(保持整洁的 0-based 编号)
24
+ const wasNonEmpty = flushCurrent();
25
+ if (wasNonEmpty)
26
+ segmentIndex += 1;
27
+ currentSegment = createEmptySegment(session, skillName, segmentIndex, timestamp, attribution);
28
+ currentSkill = skillName;
29
+ };
30
+ for (const [recordIndex, raw] of session.records.entries()) {
31
+ // records 是 unknown[], 按 type 字段做 structural type guard
32
+ if (!raw || typeof raw !== 'object' || !('type' in raw))
33
+ continue;
34
+ const rec = raw;
35
+ if (rec.type === 'user') {
36
+ const u = rec;
37
+ // 检测 skill 信号 2 (slash command)
38
+ const cmdSkill = extractCommandSkill(u);
39
+ if (cmdSkill && cmdSkill !== currentSkill) {
40
+ startNewSegment(cmdSkill, u.timestamp, { source: 'command-name', confidence: 0.85 });
41
+ }
42
+ // 处理 tool_result(回填之前的 tool_use)
43
+ if (typeof u.message.content !== 'string') {
44
+ for (const part of u.message.content) {
45
+ if (part.type === 'tool_result') {
46
+ const pending = pendingToolUses.get(part.tool_use_id);
47
+ if (pending) {
48
+ pending.toolCall.output = part.content;
49
+ pending.toolCall.success = part.is_error !== true;
50
+ if (part.is_error === true) {
51
+ pending.segmentRef.metrics.numToolFailures += 1;
52
+ }
53
+ pendingToolUses.delete(part.tool_use_id);
54
+ }
55
+ }
56
+ }
57
+ }
58
+ // user text 合并到 tool turn(简化处理, 不强区分角色)
59
+ const textContent = extractUserText(u);
60
+ if (textContent) {
61
+ currentSegment.turns.push({ role: 'tool', content: textContent });
62
+ currentSegment.metrics.numTurns += 1;
63
+ }
64
+ updateSegmentTimestamp(currentSegment, u.timestamp);
65
+ continue;
66
+ }
67
+ if (rec.type === 'assistant') {
68
+ const a = rec;
69
+ // 检测 skill 信号 1 (Skill tool_use); 信号 3 (Read SKILL.md) 作 fallback,
70
+ // 仅在当前段仍是 'general'(未被信号 1/2 命中过)时触发,避免压过更强信号。
71
+ const skillTool = extractSkillToolUse(a);
72
+ if (skillTool && skillTool !== currentSkill) {
73
+ startNewSegment(skillTool, a.timestamp, { source: 'skill-tool', confidence: 0.95 });
74
+ }
75
+ else if (!skillTool) {
76
+ const attrSkill = extractAttributionSkill(a);
77
+ if (attrSkill && attrSkill !== currentSkill) {
78
+ startNewSegment(attrSkill, a.timestamp, { source: 'command-name', confidence: 0.85 });
79
+ }
80
+ else if (currentSkill === 'general') {
81
+ const readSkill = extractSkillReadFile(a);
82
+ if (readSkill) {
83
+ startNewSegment(readSkill, a.timestamp, { source: 'read-skill-md', confidence: 0.5 });
84
+ }
85
+ }
86
+ }
87
+ // 提取 tool_use → ToolCallInfo(success 先标 true, 等 tool_result 回填)
88
+ const toolCalls = [];
89
+ let assistantText = '';
90
+ const assistantContent = Array.isArray(a.message.content) ? a.message.content : [];
91
+ for (const part of assistantContent) {
92
+ if (part.type === 'text' && part.text)
93
+ assistantText += part.text;
94
+ if (part.type === 'tool_use' && part.id && part.name) {
95
+ const tc = {
96
+ tool: part.name,
97
+ input: part.input ?? {},
98
+ output: '',
99
+ success: true,
100
+ messageIndex: recordIndex,
101
+ messageUuid: a.uuid,
102
+ toolUseId: part.id,
103
+ timestamp: a.timestamp,
104
+ };
105
+ toolCalls.push(tc);
106
+ pendingToolUses.set(part.id, { toolCall: tc, segmentRef: currentSegment });
107
+ }
108
+ }
109
+ if (toolCalls.length > 0 || assistantText) {
110
+ currentSegment.turns.push({
111
+ role: 'assistant',
112
+ content: assistantText,
113
+ toolCalls: toolCalls.length > 0 ? toolCalls : undefined,
114
+ });
115
+ currentSegment.metrics.numTurns += 1;
116
+ currentSegment.toolCalls.push(...toolCalls);
117
+ currentSegment.metrics.numToolCalls += toolCalls.length;
118
+ }
119
+ // 累加 token usage
120
+ const usage = a.message.usage;
121
+ if (usage) {
122
+ currentSegment.metrics.inputTokens += usage.input_tokens ?? 0;
123
+ currentSegment.metrics.outputTokens += usage.output_tokens ?? 0;
124
+ currentSegment.metrics.cacheReadTokens += usage.cache_read_input_tokens ?? 0;
125
+ currentSegment.metrics.cacheCreationTokens += usage.cache_creation_input_tokens ?? 0;
126
+ }
127
+ updateSegmentTimestamp(currentSegment, a.timestamp);
128
+ continue;
129
+ }
130
+ // 其他 type(permission-mode / file-history-snapshot) 直接 skip
131
+ }
132
+ flushCurrent();
133
+ // 孤儿 tool_use(没对应 tool_result 的)保持 success=true, 但标记为未闭合
134
+ return segments;
135
+ }
136
+ function createEmptySegment(session, skillName, index, timestamp, attribution) {
137
+ const ts = timestamp ?? session.startTimestamp ?? new Date().toISOString();
138
+ return {
139
+ skillName,
140
+ attribution: attribution ?? { source: 'general', confidence: 0.3 },
141
+ sessionId: session.sessionId,
142
+ segmentIndex: index,
143
+ startTimestamp: ts,
144
+ endTimestamp: ts,
145
+ cwd: session.cwd,
146
+ turns: [],
147
+ toolCalls: [],
148
+ metrics: {
149
+ durationMs: 0,
150
+ inputTokens: 0,
151
+ outputTokens: 0,
152
+ cacheReadTokens: 0,
153
+ cacheCreationTokens: 0,
154
+ numTurns: 0,
155
+ numToolCalls: 0,
156
+ numToolFailures: 0,
157
+ },
158
+ };
159
+ }
160
+ function updateSegmentTimestamp(seg, timestamp) {
161
+ if (!timestamp)
162
+ return;
163
+ if (!seg.endTimestamp || timestamp > seg.endTimestamp)
164
+ seg.endTimestamp = timestamp;
165
+ // 重算 durationMs
166
+ try {
167
+ const start = new Date(seg.startTimestamp).getTime();
168
+ const end = new Date(seg.endTimestamp).getTime();
169
+ if (!Number.isNaN(start) && !Number.isNaN(end))
170
+ seg.metrics.durationMs = Math.max(0, end - start);
171
+ }
172
+ catch { /* skip */ }
173
+ }
174
+ function extractUserText(record) {
175
+ const content = record.message.content;
176
+ if (typeof content === 'string')
177
+ return content;
178
+ const parts = [];
179
+ for (const p of content) {
180
+ if (p.type === 'text')
181
+ parts.push(p.text);
182
+ if (p.type === 'tool_result' && typeof p.content === 'string')
183
+ parts.push(p.content);
184
+ }
185
+ return parts.join('\n');
186
+ }
187
+ // ---------- Segment → ResultEntry ----------
188
+ /**
189
+ * SkillSegment[] → ResultEntry[] (omk 内部分析路径的标准输入)。
190
+ *
191
+ * 映射规则(详见 docs/skill-health-spec.md):
192
+ * - 每 segment 一个 ResultEntry
193
+ * - sample_id = `${sessionId}:${segmentIndex}`
194
+ * - variant key = skill 名(复用 omk 的 variant 维度作为 skill 分组维度)
195
+ */
196
+ export function segmentsToResultEntries(segments) {
197
+ return segments.map((seg) => ({
198
+ sample_id: `${seg.sessionId}:${seg.segmentIndex}`,
199
+ variants: {
200
+ [seg.skillName]: buildVariantResult(seg),
201
+ },
202
+ }));
203
+ }
204
+ function buildVariantResult(seg) {
205
+ const totalTokens = seg.metrics.inputTokens + seg.metrics.outputTokens;
206
+ const toolSuccessRate = seg.metrics.numToolCalls > 0
207
+ ? (seg.metrics.numToolCalls - seg.metrics.numToolFailures) / seg.metrics.numToolCalls
208
+ : 1;
209
+ return {
210
+ ok: true,
211
+ durationMs: seg.metrics.durationMs,
212
+ durationApiMs: seg.metrics.durationMs,
213
+ inputTokens: seg.metrics.inputTokens,
214
+ outputTokens: seg.metrics.outputTokens,
215
+ totalTokens,
216
+ cacheReadTokens: seg.metrics.cacheReadTokens,
217
+ cacheCreationTokens: seg.metrics.cacheCreationTokens,
218
+ execCostUSD: 0,
219
+ judgeCostUSD: 0,
220
+ costUSD: 0,
221
+ numTurns: seg.metrics.numTurns,
222
+ numToolCalls: seg.metrics.numToolCalls,
223
+ numToolFailures: seg.metrics.numToolFailures,
224
+ toolSuccessRate,
225
+ toolNames: Array.from(new Set(seg.toolCalls.map((tc) => tc.tool))),
226
+ outputPreview: null,
227
+ turns: seg.turns,
228
+ toolCalls: seg.toolCalls,
229
+ };
230
+ }
231
+ //# sourceMappingURL=trace-segmenter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace-segmenter.js","sourceRoot":"","sources":["../../../src/observability/trace-segmenter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,72 @@
1
+ /** Trace source loading and parsing for Claude JSONL / generic markdown logs. */
2
+ export interface CcAssistantContent {
3
+ type: 'thinking' | 'text' | 'tool_use';
4
+ thinking?: string;
5
+ text?: string;
6
+ id?: string;
7
+ name?: string;
8
+ input?: Record<string, unknown>;
9
+ }
10
+ export interface CcAssistantRecord {
11
+ type: 'assistant';
12
+ uuid: string;
13
+ parentUuid: string | null;
14
+ sessionId: string;
15
+ timestamp: string;
16
+ cwd?: string;
17
+ gitBranch?: string;
18
+ attributionSkill?: string;
19
+ message: {
20
+ role: 'assistant';
21
+ model?: string;
22
+ content: CcAssistantContent[];
23
+ stop_reason?: string;
24
+ usage?: {
25
+ input_tokens?: number;
26
+ output_tokens?: number;
27
+ cache_read_input_tokens?: number;
28
+ cache_creation_input_tokens?: number;
29
+ };
30
+ };
31
+ }
32
+ export interface CcUserToolResultContent {
33
+ type: 'tool_result';
34
+ tool_use_id: string;
35
+ content: string;
36
+ is_error?: boolean;
37
+ }
38
+ export interface CcUserTextContent {
39
+ type: 'text';
40
+ text: string;
41
+ }
42
+ export interface CcUserRecord {
43
+ type: 'user';
44
+ uuid: string;
45
+ parentUuid: string | null;
46
+ sessionId: string;
47
+ timestamp: string;
48
+ message: {
49
+ role: 'user';
50
+ content: string | Array<CcUserTextContent | CcUserToolResultContent>;
51
+ };
52
+ }
53
+ export type CcRecord = CcAssistantRecord | CcUserRecord | {
54
+ type: string;
55
+ [k: string]: unknown;
56
+ };
57
+ export interface CcSession {
58
+ sessionId: string;
59
+ sourcePath: string;
60
+ records: unknown[];
61
+ cwd?: string;
62
+ gitBranch?: string;
63
+ startTimestamp?: string;
64
+ endTimestamp?: string;
65
+ }
66
+ /**
67
+ * 加载一个目录(或单个 JSONL/agent markdown log 文件)下的所有 session。
68
+ * 递归扫描目录,覆盖 Claude Code 主 session 旁边的 subagents/*.jsonl,
69
+ * 也支持 agent workspace/logs/*.log 里的 Markdown 对话记录。
70
+ */
71
+ export declare function loadCcSessions(path: string): CcSession[];
72
+ //# sourceMappingURL=trace-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace-source.d.ts","sourceRoot":"","sources":["../../../src/observability/trace-source.ts"],"names":[],"mappings":"AAAA,iFAAiF;AAQjF,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,UAAU,GAAG,MAAM,GAAG,UAAU,CAAC;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,WAAW,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE;QACP,IAAI,EAAE,WAAW,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,kBAAkB,EAAE,CAAC;QAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE;YACN,YAAY,CAAC,EAAE,MAAM,CAAC;YACtB,aAAa,CAAC,EAAE,MAAM,CAAC;YACvB,uBAAuB,CAAC,EAAE,MAAM,CAAC;YACjC,2BAA2B,CAAC,EAAE,MAAM,CAAC;SACtC,CAAC;KACH,CAAC;CACH;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,aAAa,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,GAAG,KAAK,CAAC,iBAAiB,GAAG,uBAAuB,CAAC,CAAC;KACtE,CAAC;CACH;AAED,MAAM,MAAM,QAAQ,GAAG,iBAAiB,GAAG,YAAY,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CAAC;AAIjG,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;AAID;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,CAOxD"}
@@ -0,0 +1,142 @@
1
+ /** Trace source loading and parsing for Claude JSONL / generic markdown logs. */
2
+ import { readFileSync, readdirSync, statSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ import { extractMarkdownLogSkill } from './trace-attribution.js';
5
+ // ---------- Load ----------
6
+ /**
7
+ * 加载一个目录(或单个 JSONL/agent markdown log 文件)下的所有 session。
8
+ * 递归扫描目录,覆盖 Claude Code 主 session 旁边的 subagents/*.jsonl,
9
+ * 也支持 agent workspace/logs/*.log 里的 Markdown 对话记录。
10
+ */
11
+ export function loadCcSessions(path) {
12
+ const stat = statSync(path);
13
+ if (stat.isFile()) {
14
+ return parseTraceFile(path);
15
+ }
16
+ const entries = collectTraceFiles(path);
17
+ return entries.flatMap(parseTraceFile);
18
+ }
19
+ function collectTraceFiles(dir) {
20
+ const files = [];
21
+ for (const entry of readdirSync(dir)) {
22
+ if (entry === 'node_modules' || entry === '.git')
23
+ continue;
24
+ const entryPath = join(dir, entry);
25
+ let stat;
26
+ try {
27
+ stat = statSync(entryPath);
28
+ }
29
+ catch {
30
+ continue;
31
+ }
32
+ if (stat.isDirectory()) {
33
+ files.push(...collectTraceFiles(entryPath));
34
+ }
35
+ else if (entry.endsWith('.jsonl') || entry.endsWith('.log')) {
36
+ files.push(entryPath);
37
+ }
38
+ }
39
+ return files.sort();
40
+ }
41
+ function parseTraceFile(filePath) {
42
+ if (filePath.endsWith('.jsonl'))
43
+ return [parseCcSessionFile(filePath)];
44
+ if (filePath.endsWith('.log'))
45
+ return parseMarkdownLogFile(filePath);
46
+ return [];
47
+ }
48
+ function parseCcSessionFile(filePath) {
49
+ const content = readFileSync(filePath, 'utf-8');
50
+ const records = [];
51
+ for (const line of content.split('\n')) {
52
+ const trimmed = line.trim();
53
+ if (!trimmed)
54
+ continue;
55
+ try {
56
+ records.push(JSON.parse(trimmed));
57
+ }
58
+ catch {
59
+ // malformed line → skip. cc 有罕见的截断 record, 不让单行 fail 整个 session
60
+ }
61
+ }
62
+ const first = records.find((r) => 'sessionId' in r && typeof r.sessionId === 'string');
63
+ const last = [...records].reverse().find((r) => 'timestamp' in r && typeof r.timestamp === 'string');
64
+ return {
65
+ sessionId: first?.sessionId ?? filePath.split('/').pop().replace('.jsonl', ''),
66
+ sourcePath: filePath,
67
+ records,
68
+ cwd: first?.cwd,
69
+ gitBranch: first?.gitBranch,
70
+ startTimestamp: first?.timestamp,
71
+ endTimestamp: last?.timestamp,
72
+ };
73
+ }
74
+ const MARKDOWN_LOG_BLOCK_RE = /(?:^|\n)---\s*\n## \[([^\]]+)\] 对话记录[^\n]*\n([\s\S]*?)(?=\n---\s*\n## \[|$)/g;
75
+ function parseMarkdownLogFile(filePath) {
76
+ const content = readFileSync(filePath, 'utf-8');
77
+ if (!content.includes('### 用户输入') || !content.includes('### AI 回复'))
78
+ return [];
79
+ const sessions = [];
80
+ let index = 0;
81
+ for (const match of content.matchAll(MARKDOWN_LOG_BLOCK_RE)) {
82
+ const timestamp = markdownLogTimestampToIso(match[1]);
83
+ const body = match[2] ?? '';
84
+ const blockCwd = body.match(/^\*\*工作目录\*\*:\s*(.+)$/m)?.[1]?.trim();
85
+ const blockSessionId = body.match(/^\*\*会话 ID\*\*:\s*(.+)$/m)?.[1]?.trim();
86
+ const requestId = body.match(/^\*\*请求 ID\*\*:\s*(.+)$/m)?.[1]?.trim() ?? String(index);
87
+ const userText = extractMarkdownLogSection(body, '### 用户输入', '### AI 回复');
88
+ const assistantText = extractMarkdownLogSection(body, '### AI 回复');
89
+ if (!userText && !assistantText)
90
+ continue;
91
+ const sessionId = blockSessionId || `${filePath.split('/').pop().replace(/\.log$/, '')}:${requestId}`;
92
+ const cwd = blockCwd;
93
+ const skill = extractMarkdownLogSkill(`${userText}\n${assistantText}`);
94
+ const userContent = skill ? `<command-name>/${skill}</command-name>\n${userText}` : userText;
95
+ const records = [{
96
+ type: 'user',
97
+ uuid: `markdown-log-${requestId}-user-${index}`,
98
+ parentUuid: null,
99
+ sessionId,
100
+ timestamp,
101
+ message: { role: 'user', content: userContent },
102
+ }, {
103
+ type: 'assistant',
104
+ uuid: `markdown-log-${requestId}-assistant-${index}`,
105
+ parentUuid: `markdown-log-${requestId}-user-${index}`,
106
+ sessionId,
107
+ timestamp,
108
+ cwd,
109
+ attributionSkill: skill,
110
+ message: {
111
+ role: 'assistant',
112
+ content: assistantText ? [{ type: 'text', text: assistantText }] : [],
113
+ stop_reason: 'end_turn',
114
+ },
115
+ }];
116
+ sessions.push({
117
+ sessionId,
118
+ sourcePath: filePath,
119
+ records,
120
+ cwd,
121
+ startTimestamp: timestamp,
122
+ endTimestamp: timestamp,
123
+ });
124
+ index += 1;
125
+ }
126
+ return sessions;
127
+ }
128
+ function markdownLogTimestampToIso(value) {
129
+ const m = value.match(/^(\d{4})\/(\d{2})\/(\d{2})\s+(\d{2}):(\d{2}):(\d{2})$/);
130
+ if (!m)
131
+ return new Date().toISOString();
132
+ return `${m[1]}-${m[2]}-${m[3]}T${m[4]}:${m[5]}:${m[6]}+08:00`;
133
+ }
134
+ function extractMarkdownLogSection(body, startMarker, endMarker) {
135
+ const start = body.indexOf(startMarker);
136
+ if (start < 0)
137
+ return '';
138
+ const from = start + startMarker.length;
139
+ const end = endMarker ? body.indexOf(endMarker, from) : -1;
140
+ return body.slice(from, end >= 0 ? end : undefined).trim();
141
+ }
142
+ //# sourceMappingURL=trace-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace-source.js","sourceRoot":"","sources":["../../../src/observability/trace-source.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"html-renderer.d.ts","sourceRoot":"","sources":["../../../src/renderer/html-renderer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAmBH,OAAO,KAAK,EAAE,qBAAqB,EAAE,gBAAgB,EAA8B,MAAM,EAAE,cAAc,EAAE,IAAI,EAAkB,MAAM,mBAAmB,CAAC;AAmH3J,wBAAgB,aAAa,CAAC,IAAI,EAAE,cAAc,EAAE,EAAE,IAAI,GAAE,IAAmB,GAAG,MAAM,CAgMvF;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,EAAE,IAAI,GAAE,IAAmB,GAAG,MAAM,CA2KlG;AAED,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,qBAAqB,GAAG,IAAI,EAAE,IAAI,GAAE,IAAmB,GAAG,MAAM,CAiFnH;AAED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,EAAE,IAAI,GAAE,IAAmB,GAAG,MAAM,CAK3G;AAED,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,GAAE,IAAmB,GAAG,MAAM,CAGvG"}
1
+ {"version":3,"file":"html-renderer.d.ts","sourceRoot":"","sources":["../../../src/renderer/html-renderer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAkBH,OAAO,KAAK,EAAE,qBAAqB,EAAE,gBAAgB,EAA8B,MAAM,EAAE,cAAc,EAAE,IAAI,EAAkB,MAAM,mBAAmB,CAAC;AAqI3J,wBAAgB,aAAa,CAAC,IAAI,EAAE,cAAc,EAAE,EAAE,IAAI,GAAE,IAAmB,GAAG,MAAM,CAiMvF;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,EAAE,IAAI,GAAE,IAAmB,GAAG,MAAM,CA8LlG;AAED,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,qBAAqB,GAAG,IAAI,EAAE,IAAI,GAAE,IAAmB,GAAG,MAAM,CAqFnH;AAED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,EAAE,IAAI,GAAE,IAAmB,GAAG,MAAM,CAK3G;AAED,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,GAAE,IAAmB,GAAG,MAAM,CAGvG"}