@skillmark/cli 0.1.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 (101) hide show
  1. package/dist/cli-entry-point.d.ts +3 -0
  2. package/dist/cli-entry-point.d.ts.map +1 -0
  3. package/dist/cli-entry-point.js +207 -0
  4. package/dist/cli-entry-point.js.map +1 -0
  5. package/dist/commands/auth-setup-and-token-storage-command.d.ts +21 -0
  6. package/dist/commands/auth-setup-and-token-storage-command.d.ts.map +1 -0
  7. package/dist/commands/auth-setup-and-token-storage-command.js +166 -0
  8. package/dist/commands/auth-setup-and-token-storage-command.js.map +1 -0
  9. package/dist/commands/publish-results-command.d.ts +21 -0
  10. package/dist/commands/publish-results-command.d.ts.map +1 -0
  11. package/dist/commands/publish-results-command.js +256 -0
  12. package/dist/commands/publish-results-command.js.map +1 -0
  13. package/dist/commands/run-benchmark-command.d.ts +6 -0
  14. package/dist/commands/run-benchmark-command.d.ts.map +1 -0
  15. package/dist/commands/run-benchmark-command.js +331 -0
  16. package/dist/commands/run-benchmark-command.js.map +1 -0
  17. package/dist/commands/view-leaderboard-command.d.ts +8 -0
  18. package/dist/commands/view-leaderboard-command.d.ts.map +1 -0
  19. package/dist/commands/view-leaderboard-command.js +169 -0
  20. package/dist/commands/view-leaderboard-command.js.map +1 -0
  21. package/dist/config/api-key-config-reader.d.ts +14 -0
  22. package/dist/config/api-key-config-reader.d.ts.map +1 -0
  23. package/dist/config/api-key-config-reader.js +107 -0
  24. package/dist/config/api-key-config-reader.js.map +1 -0
  25. package/dist/config/api-key-config-reader.test.d.ts +2 -0
  26. package/dist/config/api-key-config-reader.test.d.ts.map +1 -0
  27. package/dist/config/api-key-config-reader.test.js +21 -0
  28. package/dist/config/api-key-config-reader.test.js.map +1 -0
  29. package/dist/engine/claude-cli-executor.d.ts +33 -0
  30. package/dist/engine/claude-cli-executor.d.ts.map +1 -0
  31. package/dist/engine/claude-cli-executor.js +251 -0
  32. package/dist/engine/claude-cli-executor.js.map +1 -0
  33. package/dist/engine/concept-accuracy-scorer.d.ts +24 -0
  34. package/dist/engine/concept-accuracy-scorer.d.ts.map +1 -0
  35. package/dist/engine/concept-accuracy-scorer.js +186 -0
  36. package/dist/engine/concept-accuracy-scorer.js.map +1 -0
  37. package/dist/engine/concept-accuracy-scorer.test.d.ts +2 -0
  38. package/dist/engine/concept-accuracy-scorer.test.d.ts.map +1 -0
  39. package/dist/engine/concept-accuracy-scorer.test.js +230 -0
  40. package/dist/engine/concept-accuracy-scorer.test.js.map +1 -0
  41. package/dist/engine/enhanced-test-prompt-builder.d.ts +30 -0
  42. package/dist/engine/enhanced-test-prompt-builder.d.ts.map +1 -0
  43. package/dist/engine/enhanced-test-prompt-builder.js +134 -0
  44. package/dist/engine/enhanced-test-prompt-builder.js.map +1 -0
  45. package/dist/engine/markdown-test-definition-parser.d.ts +18 -0
  46. package/dist/engine/markdown-test-definition-parser.d.ts.map +1 -0
  47. package/dist/engine/markdown-test-definition-parser.js +525 -0
  48. package/dist/engine/markdown-test-definition-parser.js.map +1 -0
  49. package/dist/engine/markdown-test-definition-parser.test.d.ts +2 -0
  50. package/dist/engine/markdown-test-definition-parser.test.d.ts.map +1 -0
  51. package/dist/engine/markdown-test-definition-parser.test.js +265 -0
  52. package/dist/engine/markdown-test-definition-parser.test.js.map +1 -0
  53. package/dist/engine/retry-with-degrade-utils.d.ts +58 -0
  54. package/dist/engine/retry-with-degrade-utils.d.ts.map +1 -0
  55. package/dist/engine/retry-with-degrade-utils.js +86 -0
  56. package/dist/engine/retry-with-degrade-utils.js.map +1 -0
  57. package/dist/engine/skill-content-collector.d.ts +53 -0
  58. package/dist/engine/skill-content-collector.d.ts.map +1 -0
  59. package/dist/engine/skill-content-collector.js +157 -0
  60. package/dist/engine/skill-content-collector.js.map +1 -0
  61. package/dist/engine/skill-creator-invoker.d.ts +36 -0
  62. package/dist/engine/skill-creator-invoker.d.ts.map +1 -0
  63. package/dist/engine/skill-creator-invoker.js +222 -0
  64. package/dist/engine/skill-creator-invoker.js.map +1 -0
  65. package/dist/engine/transcript-jsonl-parser.d.ts +28 -0
  66. package/dist/engine/transcript-jsonl-parser.d.ts.map +1 -0
  67. package/dist/engine/transcript-jsonl-parser.js +175 -0
  68. package/dist/engine/transcript-jsonl-parser.js.map +1 -0
  69. package/dist/sources/git-repository-skill-source-handler.d.ts +18 -0
  70. package/dist/sources/git-repository-skill-source-handler.d.ts.map +1 -0
  71. package/dist/sources/git-repository-skill-source-handler.js +119 -0
  72. package/dist/sources/git-repository-skill-source-handler.js.map +1 -0
  73. package/dist/sources/local-skill-source-handler.d.ts +21 -0
  74. package/dist/sources/local-skill-source-handler.d.ts.map +1 -0
  75. package/dist/sources/local-skill-source-handler.js +138 -0
  76. package/dist/sources/local-skill-source-handler.js.map +1 -0
  77. package/dist/sources/local-skill-source-handler.test.d.ts +2 -0
  78. package/dist/sources/local-skill-source-handler.test.d.ts.map +1 -0
  79. package/dist/sources/local-skill-source-handler.test.js +55 -0
  80. package/dist/sources/local-skill-source-handler.test.js.map +1 -0
  81. package/dist/sources/skillsh-registry-source-handler.d.ts +18 -0
  82. package/dist/sources/skillsh-registry-source-handler.d.ts.map +1 -0
  83. package/dist/sources/skillsh-registry-source-handler.js +130 -0
  84. package/dist/sources/skillsh-registry-source-handler.js.map +1 -0
  85. package/dist/sources/unified-skill-source-resolver.d.ts +20 -0
  86. package/dist/sources/unified-skill-source-resolver.d.ts.map +1 -0
  87. package/dist/sources/unified-skill-source-resolver.js +64 -0
  88. package/dist/sources/unified-skill-source-resolver.js.map +1 -0
  89. package/dist/sources/unified-skill-source-resolver.test.d.ts +2 -0
  90. package/dist/sources/unified-skill-source-resolver.test.d.ts.map +1 -0
  91. package/dist/sources/unified-skill-source-resolver.test.js +84 -0
  92. package/dist/sources/unified-skill-source-resolver.test.js.map +1 -0
  93. package/dist/types/benchmark-types.d.ts +142 -0
  94. package/dist/types/benchmark-types.d.ts.map +1 -0
  95. package/dist/types/benchmark-types.js +5 -0
  96. package/dist/types/benchmark-types.js.map +1 -0
  97. package/dist/types/index.d.ts +5 -0
  98. package/dist/types/index.d.ts.map +1 -0
  99. package/dist/types/index.js +5 -0
  100. package/dist/types/index.js.map +1 -0
  101. package/package.json +38 -0
@@ -0,0 +1,36 @@
1
+ /** Analysis result from skill-creator */
2
+ export interface SkillAnalysis {
3
+ /** Core capabilities of the skill */
4
+ capabilities: string[];
5
+ /** Key concepts/topics the skill covers */
6
+ keyConcepts: string[];
7
+ /** Potential failure scenarios to test */
8
+ edgeCases: string[];
9
+ /** Claude Code testing patterns and best practices */
10
+ testingPatterns: string[];
11
+ /** Expected tool invocations when using the skill */
12
+ toolInvocationExpectations: string[];
13
+ }
14
+ /**
15
+ * Check if skill-creator is installed and return its path.
16
+ * Installs it if missing.
17
+ */
18
+ export declare function ensureSkillCreatorInstalled(): Promise<string>;
19
+ /**
20
+ * Invoke skill-creator to analyze a skill.
21
+ *
22
+ * Uses Claude CLI with skill-creator to extract capabilities, concepts,
23
+ * edge cases, and testing patterns. The prompt includes a reference to
24
+ * @"claude-code-guide (agent)" to get Claude Code-specific testing guidance.
25
+ *
26
+ * @param skillPath - Path to the skill directory
27
+ * @param skillCreatorPath - Path to skill-creator installation
28
+ * @param timeoutMs - Timeout in milliseconds (default: 120000)
29
+ * @returns SkillAnalysis or null if invocation fails
30
+ */
31
+ export declare function invokeSkillCreator(skillPath: string, skillCreatorPath: string, timeoutMs?: number): Promise<SkillAnalysis | null>;
32
+ /**
33
+ * Get empty analysis for graceful degradation.
34
+ */
35
+ export declare function getEmptyAnalysis(): SkillAnalysis;
36
+ //# sourceMappingURL=skill-creator-invoker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-creator-invoker.d.ts","sourceRoot":"","sources":["../../src/engine/skill-creator-invoker.ts"],"names":[],"mappings":"AAiBA,yCAAyC;AACzC,MAAM,WAAW,aAAa;IAC5B,qCAAqC;IACrC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,2CAA2C;IAC3C,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,0CAA0C;IAC1C,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,sDAAsD;IACtD,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,qDAAqD;IACrD,0BAA0B,EAAE,MAAM,EAAE,CAAC;CACtC;AAkBD;;;GAGG;AACH,wBAAsB,2BAA2B,IAAI,OAAO,CAAC,MAAM,CAAC,CAkBnE;AA8ED;;;;;;;;;;;GAWG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,EACxB,SAAS,GAAE,MAAe,GACzB,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CA4F/B;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,aAAa,CAEhD"}
@@ -0,0 +1,222 @@
1
+ /**
2
+ * Skill-creator invoker for enhanced test generation.
3
+ *
4
+ * Invokes the skill-creator skill with embedded @claude-code-guide reference
5
+ * to analyze skills and extract capabilities, concepts, edge cases, and
6
+ * testing patterns for generating high-quality tests.
7
+ */
8
+ import { spawn } from 'node:child_process';
9
+ import { stat } from 'node:fs/promises';
10
+ import { exec } from 'node:child_process';
11
+ import { promisify } from 'node:util';
12
+ import { join } from 'node:path';
13
+ import { homedir } from 'node:os';
14
+ import { getStoredToken } from '../commands/auth-setup-and-token-storage-command.js';
15
+ const execAsync = promisify(exec);
16
+ /** Default empty analysis for graceful degradation */
17
+ const EMPTY_ANALYSIS = {
18
+ capabilities: [],
19
+ keyConcepts: [],
20
+ edgeCases: [],
21
+ testingPatterns: [],
22
+ toolInvocationExpectations: [],
23
+ };
24
+ /** Skill-creator installation info */
25
+ const SKILL_CREATOR_CONFIG = {
26
+ defaultPath: join(homedir(), '.claude/skills/skill-creator'),
27
+ installCommand: 'npx skills add https://github.com/anthropics/claudekit-skills --skill skill-creator -a claude-code -g -y',
28
+ };
29
+ /**
30
+ * Check if skill-creator is installed and return its path.
31
+ * Installs it if missing.
32
+ */
33
+ export async function ensureSkillCreatorInstalled() {
34
+ const skillPath = SKILL_CREATOR_CONFIG.defaultPath;
35
+ try {
36
+ await stat(join(skillPath, 'SKILL.md'));
37
+ return skillPath;
38
+ }
39
+ catch {
40
+ console.log('Installing skill-creator...');
41
+ try {
42
+ await execAsync(SKILL_CREATOR_CONFIG.installCommand, {
43
+ timeout: 60000,
44
+ });
45
+ console.log('skill-creator installed successfully');
46
+ return skillPath;
47
+ }
48
+ catch (error) {
49
+ throw new Error(`Failed to install skill-creator: ${error.message}`);
50
+ }
51
+ }
52
+ }
53
+ /**
54
+ * Build the analysis prompt that includes @claude-code-guide reference.
55
+ *
56
+ * Uses prompt engineering to leverage Claude's built-in subagent routing
57
+ * for getting Claude Code testing patterns.
58
+ */
59
+ function buildAnalysisPrompt(skillPath) {
60
+ return `Analyze the skill at ${skillPath}.
61
+
62
+ Use @"claude-code-guide (agent)" to understand Claude Code CLI patterns for testing skills.
63
+
64
+ Extract and return ONLY a JSON object with this structure:
65
+ {
66
+ "capabilities": ["what the skill can do - list 3-6 core capabilities"],
67
+ "keyConcepts": ["key topics/keywords the skill covers - list 5-10 concepts"],
68
+ "edgeCases": ["failure scenarios to test - list 3-5 edge cases"],
69
+ "testingPatterns": ["Claude Code testing best practices from claude-code-guide"],
70
+ "toolInvocationExpectations": ["expected tool calls when using this skill"]
71
+ }
72
+
73
+ Rules:
74
+ - Read the SKILL.md file thoroughly
75
+ - Extract concepts from Key Concepts Index if present
76
+ - Identify what tools the skill might invoke (Read, Write, Bash, etc.)
77
+ - Consider common failure modes (missing files, invalid input, etc.)
78
+ - Include testing patterns from @"claude-code-guide (agent)"
79
+
80
+ Respond with ONLY the JSON object, no markdown formatting.`;
81
+ }
82
+ /**
83
+ * Parse skill analysis from Claude CLI response.
84
+ */
85
+ function parseAnalysisResponse(stdout) {
86
+ try {
87
+ // Parse outer Claude CLI JSON wrapper
88
+ const outer = JSON.parse(stdout);
89
+ // Extract inner result
90
+ const result = outer.result;
91
+ if (!result) {
92
+ return null;
93
+ }
94
+ // Result might be string or object
95
+ let analysis;
96
+ if (typeof result === 'string') {
97
+ // Try to extract JSON from the string
98
+ const jsonMatch = result.match(/\{[\s\S]*\}/);
99
+ if (!jsonMatch) {
100
+ return null;
101
+ }
102
+ analysis = JSON.parse(jsonMatch[0]);
103
+ }
104
+ else {
105
+ analysis = result;
106
+ }
107
+ // Validate required fields exist
108
+ if (!analysis.capabilities || !Array.isArray(analysis.capabilities)) {
109
+ return null;
110
+ }
111
+ // Fill in defaults for optional fields
112
+ return {
113
+ capabilities: analysis.capabilities || [],
114
+ keyConcepts: analysis.keyConcepts || [],
115
+ edgeCases: analysis.edgeCases || [],
116
+ testingPatterns: analysis.testingPatterns || [],
117
+ toolInvocationExpectations: analysis.toolInvocationExpectations || [],
118
+ };
119
+ }
120
+ catch {
121
+ return null;
122
+ }
123
+ }
124
+ /**
125
+ * Invoke skill-creator to analyze a skill.
126
+ *
127
+ * Uses Claude CLI with skill-creator to extract capabilities, concepts,
128
+ * edge cases, and testing patterns. The prompt includes a reference to
129
+ * @"claude-code-guide (agent)" to get Claude Code-specific testing guidance.
130
+ *
131
+ * @param skillPath - Path to the skill directory
132
+ * @param skillCreatorPath - Path to skill-creator installation
133
+ * @param timeoutMs - Timeout in milliseconds (default: 120000)
134
+ * @returns SkillAnalysis or null if invocation fails
135
+ */
136
+ export async function invokeSkillCreator(skillPath, skillCreatorPath, timeoutMs = 120000) {
137
+ const prompt = buildAnalysisPrompt(skillPath);
138
+ // Get stored OAuth token
139
+ const storedToken = await getStoredToken();
140
+ const env = { ...process.env };
141
+ if (storedToken) {
142
+ env.CLAUDE_CODE_OAUTH_TOKEN = storedToken;
143
+ }
144
+ return new Promise((resolve) => {
145
+ const args = [
146
+ '-p',
147
+ prompt,
148
+ '--allowedTools',
149
+ `Skill(${skillCreatorPath}),Read,Glob,Task`,
150
+ '--output-format',
151
+ 'json',
152
+ '--model',
153
+ 'haiku',
154
+ '--dangerously-skip-permissions',
155
+ ];
156
+ console.log('Invoking skill-creator for skill analysis...');
157
+ const proc = spawn('claude', args, {
158
+ env,
159
+ stdio: ['ignore', 'pipe', 'pipe'],
160
+ });
161
+ let stdout = '';
162
+ let stderr = '';
163
+ proc.stdout.on('data', (data) => {
164
+ stdout += data.toString();
165
+ });
166
+ proc.stderr.on('data', (data) => {
167
+ stderr += data.toString();
168
+ });
169
+ const timeout = setTimeout(() => {
170
+ proc.kill('SIGTERM');
171
+ console.warn(`skill-creator timeout after ${timeoutMs}ms`);
172
+ resolve(null);
173
+ }, timeoutMs);
174
+ proc.on('error', (error) => {
175
+ clearTimeout(timeout);
176
+ console.warn(`skill-creator error: ${error.message}`);
177
+ resolve(null);
178
+ });
179
+ proc.on('close', (code) => {
180
+ clearTimeout(timeout);
181
+ // Check for auth errors in JSON response (Claude CLI returns error in JSON)
182
+ if (stdout) {
183
+ try {
184
+ const parsed = JSON.parse(stdout);
185
+ if (parsed.is_error && parsed.result) {
186
+ const errorMsg = parsed.result;
187
+ if (errorMsg.includes('Invalid API key') || errorMsg.includes('/login')) {
188
+ console.warn(`Authentication required: ${errorMsg}. Run 'claude /login' to authenticate.`);
189
+ }
190
+ else {
191
+ console.warn(`skill-creator error: ${errorMsg}`);
192
+ }
193
+ resolve(null);
194
+ return;
195
+ }
196
+ }
197
+ catch {
198
+ // Not JSON, continue
199
+ }
200
+ }
201
+ if (code !== 0) {
202
+ const errorDetail = stderr || stdout.slice(0, 200) || 'No error details';
203
+ console.warn(`skill-creator exited with code ${code}: ${errorDetail}`);
204
+ resolve(null);
205
+ return;
206
+ }
207
+ const analysis = parseAnalysisResponse(stdout);
208
+ if (analysis) {
209
+ console.log(`Skill analysis complete: ${analysis.capabilities.length} capabilities, ` +
210
+ `${analysis.keyConcepts.length} concepts, ${analysis.edgeCases.length} edge cases`);
211
+ }
212
+ resolve(analysis);
213
+ });
214
+ });
215
+ }
216
+ /**
217
+ * Get empty analysis for graceful degradation.
218
+ */
219
+ export function getEmptyAnalysis() {
220
+ return { ...EMPTY_ANALYSIS };
221
+ }
222
+ //# sourceMappingURL=skill-creator-invoker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-creator-invoker.js","sourceRoot":"","sources":["../../src/engine/skill-creator-invoker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { TranscriptEntry, BenchmarkMetrics } from '../types/index.js';
2
+ /** Parsed transcript data */
3
+ export interface ParsedTranscript {
4
+ entries: TranscriptEntry[];
5
+ metrics: BenchmarkMetrics;
6
+ response: string;
7
+ model: string;
8
+ toolCalls: ToolCall[];
9
+ }
10
+ /** Tool call extracted from transcript */
11
+ export interface ToolCall {
12
+ name: string;
13
+ input: Record<string, unknown>;
14
+ result?: string;
15
+ }
16
+ /**
17
+ * Parse a JSONL transcript file
18
+ */
19
+ export declare function parseTranscriptFile(filePath: string): Promise<ParsedTranscript>;
20
+ /**
21
+ * Parse JSONL transcript content
22
+ */
23
+ export declare function parseTranscriptContent(content: string): ParsedTranscript;
24
+ /**
25
+ * Extract all assistant text responses (not just final)
26
+ */
27
+ export declare function extractAllResponses(entries: TranscriptEntry[]): string[];
28
+ //# sourceMappingURL=transcript-jsonl-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript-jsonl-parser.d.ts","sourceRoot":"","sources":["../../src/engine/transcript-jsonl-parser.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE3E,6BAA6B;AAC7B,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,OAAO,EAAE,gBAAgB,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,QAAQ,EAAE,CAAC;CACvB;AAED,0CAA0C;AAC1C,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAGrF;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,CAmBxE;AAoID;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,MAAM,EAAE,CAsBxE"}
@@ -0,0 +1,175 @@
1
+ /**
2
+ * JSONL transcript parser - extracts metrics and data from Claude CLI transcripts
3
+ */
4
+ import { readFile } from 'node:fs/promises';
5
+ /**
6
+ * Parse a JSONL transcript file
7
+ */
8
+ export async function parseTranscriptFile(filePath) {
9
+ const content = await readFile(filePath, 'utf-8');
10
+ return parseTranscriptContent(content);
11
+ }
12
+ /**
13
+ * Parse JSONL transcript content
14
+ */
15
+ export function parseTranscriptContent(content) {
16
+ const entries = [];
17
+ const lines = content.split('\n').filter((line) => line.trim());
18
+ for (const line of lines) {
19
+ try {
20
+ const entry = JSON.parse(line);
21
+ entries.push(entry);
22
+ }
23
+ catch {
24
+ // Skip non-JSON lines (like progress indicators)
25
+ }
26
+ }
27
+ const metrics = calculateMetrics(entries);
28
+ const response = extractFinalResponse(entries);
29
+ const model = extractModel(entries);
30
+ const toolCalls = extractToolCalls(entries);
31
+ return { entries, metrics, response, model, toolCalls };
32
+ }
33
+ /**
34
+ * Calculate aggregate metrics from transcript entries
35
+ */
36
+ function calculateMetrics(entries) {
37
+ let tokensInput = 0;
38
+ let tokensOutput = 0;
39
+ let costUsd = 0;
40
+ let durationMs = 0;
41
+ let toolCount = 0;
42
+ for (const entry of entries) {
43
+ // Accumulate tokens
44
+ if (entry.inputTokens)
45
+ tokensInput += entry.inputTokens;
46
+ if (entry.outputTokens)
47
+ tokensOutput += entry.outputTokens;
48
+ if (entry.cacheCreationInputTokens)
49
+ tokensInput += entry.cacheCreationInputTokens;
50
+ if (entry.cacheReadInputTokens)
51
+ tokensInput += entry.cacheReadInputTokens;
52
+ // Accumulate cost
53
+ if (entry.costUSD)
54
+ costUsd += entry.costUSD;
55
+ // Accumulate duration
56
+ if (entry.durationMs)
57
+ durationMs += entry.durationMs;
58
+ // Count tool uses in assistant messages
59
+ if (entry.type === 'assistant' && entry.message?.content) {
60
+ const content = entry.message.content;
61
+ if (Array.isArray(content)) {
62
+ toolCount += content.filter((c) => c.type === 'tool_use').length;
63
+ }
64
+ }
65
+ }
66
+ const tokensTotal = tokensInput + tokensOutput;
67
+ return {
68
+ accuracy: 0, // Calculated separately by scorer
69
+ tokensTotal,
70
+ tokensInput,
71
+ tokensOutput,
72
+ durationMs,
73
+ toolCount,
74
+ costUsd,
75
+ };
76
+ }
77
+ /**
78
+ * Extract the final response text from transcript
79
+ */
80
+ function extractFinalResponse(entries) {
81
+ // Iterate backwards to find last assistant message with text
82
+ for (let i = entries.length - 1; i >= 0; i--) {
83
+ const entry = entries[i];
84
+ if (entry.type === 'assistant' && entry.message?.content) {
85
+ const content = entry.message.content;
86
+ if (typeof content === 'string') {
87
+ return content;
88
+ }
89
+ if (Array.isArray(content)) {
90
+ const textParts = content
91
+ .filter((c) => c.type === 'text' && c.text)
92
+ .map((c) => c.text);
93
+ if (textParts.length > 0) {
94
+ return textParts.join('\n');
95
+ }
96
+ }
97
+ }
98
+ }
99
+ return '';
100
+ }
101
+ /**
102
+ * Extract model from transcript
103
+ */
104
+ function extractModel(entries) {
105
+ for (const entry of entries) {
106
+ if (entry.message?.model) {
107
+ return entry.message.model;
108
+ }
109
+ }
110
+ return 'unknown';
111
+ }
112
+ /**
113
+ * Extract tool calls from transcript
114
+ */
115
+ function extractToolCalls(entries) {
116
+ const toolCalls = [];
117
+ const pendingCalls = new Map();
118
+ for (const entry of entries) {
119
+ if (entry.type === 'assistant' && entry.message?.content) {
120
+ const content = entry.message.content;
121
+ if (Array.isArray(content)) {
122
+ for (const item of content) {
123
+ if (item.type === 'tool_use') {
124
+ const call = {
125
+ name: item.name,
126
+ input: item.input,
127
+ };
128
+ const id = item.id;
129
+ pendingCalls.set(id, call);
130
+ toolCalls.push(call);
131
+ }
132
+ }
133
+ }
134
+ }
135
+ // Match tool results
136
+ if (entry.type === 'result' && entry.message?.content) {
137
+ const content = entry.message.content;
138
+ if (Array.isArray(content)) {
139
+ for (const item of content) {
140
+ if (item.type === 'tool_result' && item.tool_use_id) {
141
+ const call = pendingCalls.get(item.tool_use_id);
142
+ if (call) {
143
+ call.result = item.text;
144
+ }
145
+ }
146
+ }
147
+ }
148
+ }
149
+ }
150
+ return toolCalls;
151
+ }
152
+ /**
153
+ * Extract all assistant text responses (not just final)
154
+ */
155
+ export function extractAllResponses(entries) {
156
+ const responses = [];
157
+ for (const entry of entries) {
158
+ if (entry.type === 'assistant' && entry.message?.content) {
159
+ const content = entry.message.content;
160
+ if (typeof content === 'string') {
161
+ responses.push(content);
162
+ }
163
+ else if (Array.isArray(content)) {
164
+ const textParts = content
165
+ .filter((c) => c.type === 'text' && c.text)
166
+ .map((c) => c.text);
167
+ if (textParts.length > 0) {
168
+ responses.push(textParts.join('\n'));
169
+ }
170
+ }
171
+ }
172
+ }
173
+ return responses;
174
+ }
175
+ //# sourceMappingURL=transcript-jsonl-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript-jsonl-parser.js","sourceRoot":"","sources":["../../src/engine/transcript-jsonl-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { SkillSource } from '../types/index.js';
2
+ /**
3
+ * Check if a source is a git URL
4
+ */
5
+ export declare function isGitSource(source: string): boolean;
6
+ /**
7
+ * Resolve a git skill source by cloning the repository
8
+ */
9
+ export declare function resolveGitSource(source: string): Promise<SkillSource>;
10
+ /**
11
+ * Clean up git cache
12
+ */
13
+ export declare function cleanGitCache(): Promise<void>;
14
+ /**
15
+ * Clone a specific branch or tag
16
+ */
17
+ export declare function resolveGitSourceWithRef(source: string, ref: string): Promise<SkillSource>;
18
+ //# sourceMappingURL=git-repository-skill-source-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-repository-skill-source-handler.d.ts","sourceRoot":"","sources":["../../src/sources/git-repository-skill-source-handler.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAerD;;GAEG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CA6B3E;AA4CD;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAMnD;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,WAAW,CAAC,CAiBtB"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Git repository skill source handler - clones and manages skills from git URLs
3
+ */
4
+ import { mkdir, rm } from 'node:fs/promises';
5
+ import { join } from 'node:path';
6
+ import { simpleGit } from 'simple-git';
7
+ /** Git URL patterns */
8
+ const GIT_URL_PATTERNS = [
9
+ /^https?:\/\/github\.com\//,
10
+ /^https?:\/\/gitlab\.com\//,
11
+ /^https?:\/\/bitbucket\.org\//,
12
+ /^git@/,
13
+ /^git:\/\//,
14
+ /\.git$/,
15
+ ];
16
+ /** Cache directory for cloned repos */
17
+ const CACHE_DIR = join(process.env.HOME || '/tmp', '.skillmark', 'git-cache');
18
+ /**
19
+ * Check if a source is a git URL
20
+ */
21
+ export function isGitSource(source) {
22
+ return GIT_URL_PATTERNS.some((pattern) => pattern.test(source));
23
+ }
24
+ /**
25
+ * Resolve a git skill source by cloning the repository
26
+ */
27
+ export async function resolveGitSource(source) {
28
+ // Parse git URL to extract name
29
+ const name = extractRepoName(source);
30
+ const cacheId = generateCacheId(source);
31
+ const localPath = join(CACHE_DIR, cacheId);
32
+ // Create cache directory
33
+ await mkdir(CACHE_DIR, { recursive: true });
34
+ // Check if already cloned (use existing cache)
35
+ const git = simpleGit();
36
+ try {
37
+ // Try to update existing clone
38
+ const existingGit = simpleGit(localPath);
39
+ await existingGit.fetch();
40
+ await existingGit.pull();
41
+ }
42
+ catch {
43
+ // Clone fresh
44
+ await rm(localPath, { recursive: true, force: true });
45
+ await git.clone(source, localPath, ['--depth', '1']);
46
+ }
47
+ return {
48
+ type: 'git',
49
+ original: source,
50
+ localPath,
51
+ name,
52
+ };
53
+ }
54
+ /**
55
+ * Extract repository name from git URL
56
+ */
57
+ function extractRepoName(url) {
58
+ // Remove .git suffix
59
+ let cleaned = url.replace(/\.git$/, '');
60
+ // Extract last path segment
61
+ const segments = cleaned.split('/').filter(Boolean);
62
+ const name = segments[segments.length - 1] || 'unknown';
63
+ // Handle git@ format
64
+ if (name.includes(':')) {
65
+ return name.split(':').pop() || 'unknown';
66
+ }
67
+ return name;
68
+ }
69
+ /**
70
+ * Generate a cache ID for a git URL
71
+ */
72
+ function generateCacheId(url) {
73
+ // Create a deterministic but short ID from the URL
74
+ const name = extractRepoName(url);
75
+ const hash = simpleHash(url).toString(16).slice(0, 8);
76
+ return `${name}-${hash}`;
77
+ }
78
+ /**
79
+ * Simple hash function for generating cache IDs
80
+ */
81
+ function simpleHash(str) {
82
+ let hash = 0;
83
+ for (let i = 0; i < str.length; i++) {
84
+ const char = str.charCodeAt(i);
85
+ hash = (hash << 5) - hash + char;
86
+ hash = hash & hash; // Convert to 32-bit integer
87
+ }
88
+ return Math.abs(hash);
89
+ }
90
+ /**
91
+ * Clean up git cache
92
+ */
93
+ export async function cleanGitCache() {
94
+ try {
95
+ await rm(CACHE_DIR, { recursive: true, force: true });
96
+ }
97
+ catch {
98
+ // Ignore errors
99
+ }
100
+ }
101
+ /**
102
+ * Clone a specific branch or tag
103
+ */
104
+ export async function resolveGitSourceWithRef(source, ref) {
105
+ const name = extractRepoName(source);
106
+ const cacheId = `${generateCacheId(source)}-${ref}`;
107
+ const localPath = join(CACHE_DIR, cacheId);
108
+ await mkdir(CACHE_DIR, { recursive: true });
109
+ await rm(localPath, { recursive: true, force: true });
110
+ const git = simpleGit();
111
+ await git.clone(source, localPath, ['--depth', '1', '--branch', ref]);
112
+ return {
113
+ type: 'git',
114
+ original: `${source}#${ref}`,
115
+ localPath,
116
+ name: `${name}@${ref}`,
117
+ };
118
+ }
119
+ //# sourceMappingURL=git-repository-skill-source-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-repository-skill-source-handler.js","sourceRoot":"","sources":["../../src/sources/git-repository-skill-source-handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { SkillSource } from '../types/index.js';
2
+ /**
3
+ * Check if a path is a local skill source
4
+ */
5
+ export declare function isLocalSource(source: string): boolean;
6
+ /**
7
+ * Resolve a local skill source
8
+ */
9
+ export declare function resolveLocalSource(source: string): Promise<SkillSource>;
10
+ /**
11
+ * Find test files in a skill directory
12
+ */
13
+ export declare function findTestsInSkillDir(skillPath: string): Promise<string[]>;
14
+ /**
15
+ * Read skill metadata from SKILL.md or README.md
16
+ */
17
+ export declare function readSkillMetadata(skillPath: string): Promise<{
18
+ name: string;
19
+ description: string;
20
+ } | null>;
21
+ //# sourceMappingURL=local-skill-source-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-skill-source-handler.d.ts","sourceRoot":"","sources":["../../src/sources/local-skill-source-handler.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAKrD;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CASrD;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAkD7E;AA+BD;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAoB9E;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAwBvD"}