@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,169 @@
1
+ /**
2
+ * View leaderboard command - displays skill rankings from API
3
+ */
4
+ import chalk from 'chalk';
5
+ import ora from 'ora';
6
+ /** Default API endpoint */
7
+ const DEFAULT_ENDPOINT = 'https://skillmark.sh/api';
8
+ /**
9
+ * Execute the leaderboard command
10
+ */
11
+ export async function viewLeaderboard(skillName, options = {}) {
12
+ const spinner = ora();
13
+ try {
14
+ const endpoint = options.endpoint || DEFAULT_ENDPOINT;
15
+ const limit = options.limit || 20;
16
+ if (skillName) {
17
+ // Show specific skill details
18
+ spinner.start(`Fetching details for ${skillName}...`);
19
+ const skill = await fetchSkillDetails(skillName, endpoint);
20
+ spinner.stop();
21
+ displaySkillDetails(skill);
22
+ }
23
+ else {
24
+ // Show leaderboard
25
+ spinner.start('Fetching leaderboard...');
26
+ const entries = await fetchLeaderboard(endpoint, limit);
27
+ spinner.stop();
28
+ displayLeaderboard(entries);
29
+ }
30
+ }
31
+ catch (error) {
32
+ spinner.fail('Failed to fetch leaderboard');
33
+ throw error;
34
+ }
35
+ }
36
+ /**
37
+ * Fetch leaderboard from API
38
+ */
39
+ async function fetchLeaderboard(endpoint, limit) {
40
+ const url = `${endpoint}/leaderboard?limit=${limit}`;
41
+ const response = await fetch(url);
42
+ if (!response.ok) {
43
+ throw new Error(`API error (${response.status}): ${response.statusText}`);
44
+ }
45
+ const data = await response.json();
46
+ return data.entries || [];
47
+ }
48
+ /**
49
+ * Fetch specific skill details from API
50
+ */
51
+ async function fetchSkillDetails(skillName, endpoint) {
52
+ const url = `${endpoint}/skill/${encodeURIComponent(skillName)}`;
53
+ const response = await fetch(url);
54
+ if (!response.ok) {
55
+ if (response.status === 404) {
56
+ throw new Error(`Skill not found: ${skillName}`);
57
+ }
58
+ throw new Error(`API error (${response.status}): ${response.statusText}`);
59
+ }
60
+ return response.json();
61
+ }
62
+ /**
63
+ * Display leaderboard table
64
+ */
65
+ function displayLeaderboard(entries) {
66
+ if (entries.length === 0) {
67
+ console.log(chalk.yellow('\nNo benchmark results found.\n'));
68
+ console.log('Run a benchmark and publish results to appear on the leaderboard:');
69
+ console.log(chalk.gray(' skillmark run <skill-path>'));
70
+ console.log(chalk.gray(' skillmark publish ./skillmark-results/result.json --api-key <key>'));
71
+ return;
72
+ }
73
+ console.log(chalk.bold('\n═══ Skillmark Leaderboard ═══\n'));
74
+ // Header
75
+ console.log(chalk.gray(padRight('#', 4) +
76
+ padRight('Skill', 30) +
77
+ padRight('Accuracy', 10) +
78
+ padRight('Model', 10) +
79
+ padRight('Tokens', 12) +
80
+ padRight('Cost', 10) +
81
+ 'Last Tested'));
82
+ console.log(chalk.gray('─'.repeat(100)));
83
+ // Rows
84
+ entries.forEach((entry, index) => {
85
+ const rank = String(index + 1);
86
+ const accuracy = `${entry.bestAccuracy.toFixed(1)}%`;
87
+ const tokens = entry.avgTokens.toLocaleString();
88
+ const cost = `$${entry.avgCost.toFixed(4)}`;
89
+ const lastTested = formatDate(entry.lastTested);
90
+ // Color accuracy
91
+ const accuracyColored = entry.bestAccuracy >= 90
92
+ ? chalk.green(accuracy)
93
+ : entry.bestAccuracy >= 70
94
+ ? chalk.yellow(accuracy)
95
+ : chalk.red(accuracy);
96
+ console.log(padRight(rank, 4) +
97
+ padRight(truncate(entry.skillName, 28), 30) +
98
+ padRight(accuracyColored, 10 + (accuracyColored.length - accuracy.length)) +
99
+ padRight(entry.bestModel, 10) +
100
+ padRight(tokens, 12) +
101
+ padRight(cost, 10) +
102
+ chalk.gray(lastTested));
103
+ });
104
+ console.log(chalk.gray('\n─'.repeat(100)));
105
+ console.log(chalk.gray(`Showing top ${entries.length} skills\n`));
106
+ }
107
+ /**
108
+ * Display skill details
109
+ */
110
+ function displaySkillDetails(skill) {
111
+ console.log(chalk.bold(`\n═══ ${skill.skillName} ═══\n`));
112
+ console.log(`${chalk.gray('Source:')} ${skill.source}`);
113
+ console.log(`${chalk.gray('Best Accuracy:')} ${chalk.green(skill.bestAccuracy.toFixed(1) + '%')}`);
114
+ console.log(`${chalk.gray('Best Model:')} ${skill.bestModel}`);
115
+ console.log(`${chalk.gray('Avg Tokens:')} ${skill.avgTokens.toLocaleString()}`);
116
+ console.log(`${chalk.gray('Avg Cost:')} $${skill.avgCost.toFixed(4)}`);
117
+ console.log(`${chalk.gray('Total Runs:')} ${skill.totalRuns}`);
118
+ console.log(`${chalk.gray('Last Tested:')} ${formatDate(skill.lastTested)}`);
119
+ // Show history if available
120
+ if (skill.history && skill.history.length > 0) {
121
+ console.log(chalk.bold('\nRecent Results:\n'));
122
+ for (const h of skill.history.slice(0, 10)) {
123
+ const bar = '█'.repeat(Math.round(h.accuracy / 5));
124
+ const accuracyColor = h.accuracy >= 90 ? chalk.green : h.accuracy >= 70 ? chalk.yellow : chalk.red;
125
+ console.log(` ${chalk.gray(formatDate(h.date))} ${accuracyColor(bar)} ${h.accuracy.toFixed(1)}%`);
126
+ }
127
+ }
128
+ console.log('');
129
+ }
130
+ /**
131
+ * Pad string to right
132
+ */
133
+ function padRight(str, length) {
134
+ return str.padEnd(length);
135
+ }
136
+ /**
137
+ * Truncate string with ellipsis
138
+ */
139
+ function truncate(str, maxLength) {
140
+ if (str.length <= maxLength)
141
+ return str;
142
+ return str.slice(0, maxLength - 1) + '…';
143
+ }
144
+ /**
145
+ * Format ISO date to readable format
146
+ */
147
+ function formatDate(isoDate) {
148
+ try {
149
+ const date = new Date(isoDate);
150
+ const now = new Date();
151
+ const diffMs = now.getTime() - date.getTime();
152
+ const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
153
+ if (diffDays === 0)
154
+ return 'today';
155
+ if (diffDays === 1)
156
+ return 'yesterday';
157
+ if (diffDays < 7)
158
+ return `${diffDays}d ago`;
159
+ if (diffDays < 30)
160
+ return `${Math.floor(diffDays / 7)}w ago`;
161
+ if (diffDays < 365)
162
+ return `${Math.floor(diffDays / 30)}mo ago`;
163
+ return `${Math.floor(diffDays / 365)}y ago`;
164
+ }
165
+ catch {
166
+ return isoDate;
167
+ }
168
+ }
169
+ //# sourceMappingURL=view-leaderboard-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"view-leaderboard-command.js","sourceRoot":"","sources":["../../src/commands/view-leaderboard-command.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export interface ApiKeyConfig {
2
+ apiKey: string;
3
+ source: 'env' | 'skillmarkrc' | 'claude-env';
4
+ }
5
+ /**
6
+ * Read API key from configured sources
7
+ * Priority: env > ~/.skillmarkrc > ~/.claude/.env
8
+ */
9
+ export declare function readApiKeyConfig(): Promise<ApiKeyConfig | null>;
10
+ /**
11
+ * Get human-readable description of config source
12
+ */
13
+ export declare function getConfigSourceDescription(source: ApiKeyConfig['source']): string;
14
+ //# sourceMappingURL=api-key-config-reader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-key-config-reader.d.ts","sourceRoot":"","sources":["../../src/config/api-key-config-reader.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,KAAK,GAAG,aAAa,GAAG,YAAY,CAAC;CAC9C;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAkCrE;AAuDD;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,YAAY,CAAC,QAAQ,CAAC,GAAG,MAAM,CASjF"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * API key configuration reader for Skillmark CLI
3
+ * Reads API key from multiple sources with priority:
4
+ * 1. SKILLMARK_API_KEY environment variable
5
+ * 2. ~/.skillmarkrc config file
6
+ * 3. ~/.claude/.env file
7
+ */
8
+ import { readFile } from 'node:fs/promises';
9
+ import { join } from 'node:path';
10
+ import { homedir } from 'node:os';
11
+ const ENV_VAR_NAME = 'SKILLMARK_API_KEY';
12
+ const SKILLMARKRC_FILE = '.skillmarkrc';
13
+ const CLAUDE_ENV_FILE = '.claude/.env';
14
+ /**
15
+ * Read API key from configured sources
16
+ * Priority: env > ~/.skillmarkrc > ~/.claude/.env
17
+ */
18
+ export async function readApiKeyConfig() {
19
+ // 1. Check environment variable
20
+ const envKey = process.env[ENV_VAR_NAME];
21
+ if (envKey && envKey.trim()) {
22
+ return { apiKey: envKey.trim(), source: 'env' };
23
+ }
24
+ const home = homedir();
25
+ // 2. Check ~/.skillmarkrc
26
+ try {
27
+ const skillmarkrcPath = join(home, SKILLMARKRC_FILE);
28
+ const content = await readFile(skillmarkrcPath, 'utf-8');
29
+ const key = parseConfigFile(content);
30
+ if (key) {
31
+ return { apiKey: key, source: 'skillmarkrc' };
32
+ }
33
+ }
34
+ catch {
35
+ // File doesn't exist or can't be read, continue
36
+ }
37
+ // 3. Check ~/.claude/.env
38
+ try {
39
+ const claudeEnvPath = join(home, CLAUDE_ENV_FILE);
40
+ const content = await readFile(claudeEnvPath, 'utf-8');
41
+ const key = parseEnvFile(content, ENV_VAR_NAME);
42
+ if (key) {
43
+ return { apiKey: key, source: 'claude-env' };
44
+ }
45
+ }
46
+ catch {
47
+ // File doesn't exist or can't be read, continue
48
+ }
49
+ return null;
50
+ }
51
+ /**
52
+ * Parse skillmarkrc config file
53
+ * Format: key=value or api_key=value
54
+ */
55
+ function parseConfigFile(content) {
56
+ const lines = content.split('\n');
57
+ for (const line of lines) {
58
+ const trimmed = line.trim();
59
+ // Skip comments and empty lines
60
+ if (!trimmed || trimmed.startsWith('#')) {
61
+ continue;
62
+ }
63
+ // Parse key=value
64
+ const match = trimmed.match(/^(?:api_key|apiKey|key)\s*=\s*(.+)$/i);
65
+ if (match) {
66
+ const value = match[1].trim();
67
+ // Remove quotes if present
68
+ return value.replace(/^["']|["']$/g, '');
69
+ }
70
+ }
71
+ return null;
72
+ }
73
+ /**
74
+ * Parse .env file for specific key
75
+ */
76
+ function parseEnvFile(content, keyName) {
77
+ const lines = content.split('\n');
78
+ for (const line of lines) {
79
+ const trimmed = line.trim();
80
+ // Skip comments and empty lines
81
+ if (!trimmed || trimmed.startsWith('#')) {
82
+ continue;
83
+ }
84
+ // Parse KEY=value
85
+ const match = trimmed.match(/^([^=]+)=(.*)$/);
86
+ if (match && match[1].trim() === keyName) {
87
+ const value = match[2].trim();
88
+ // Remove quotes if present
89
+ return value.replace(/^["']|["']$/g, '');
90
+ }
91
+ }
92
+ return null;
93
+ }
94
+ /**
95
+ * Get human-readable description of config source
96
+ */
97
+ export function getConfigSourceDescription(source) {
98
+ switch (source) {
99
+ case 'env':
100
+ return `SKILLMARK_API_KEY environment variable`;
101
+ case 'skillmarkrc':
102
+ return `~/${SKILLMARKRC_FILE}`;
103
+ case 'claude-env':
104
+ return `~/${CLAUDE_ENV_FILE}`;
105
+ }
106
+ }
107
+ //# sourceMappingURL=api-key-config-reader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-key-config-reader.js","sourceRoot":"","sources":["../../src/config/api-key-config-reader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=api-key-config-reader.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-key-config-reader.test.d.ts","sourceRoot":"","sources":["../../src/config/api-key-config-reader.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Tests for api-key-config-reader.ts
3
+ * Verifies API key config source descriptions and priority logic
4
+ */
5
+ import { describe, it, expect } from 'vitest';
6
+ import { getConfigSourceDescription } from './api-key-config-reader.js';
7
+ describe('getConfigSourceDescription', () => {
8
+ it('returns env variable description for env source', () => {
9
+ const result = getConfigSourceDescription('env');
10
+ expect(result).toBe('SKILLMARK_API_KEY environment variable');
11
+ });
12
+ it('returns skillmarkrc path for skillmarkrc source', () => {
13
+ const result = getConfigSourceDescription('skillmarkrc');
14
+ expect(result).toBe('~/.skillmarkrc');
15
+ });
16
+ it('returns claude env path for claude-env source', () => {
17
+ const result = getConfigSourceDescription('claude-env');
18
+ expect(result).toBe('~/.claude/.env');
19
+ });
20
+ });
21
+ //# sourceMappingURL=api-key-config-reader.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-key-config-reader.test.js","sourceRoot":"","sources":["../../src/config/api-key-config-reader.test.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAExE,QAAQ,CAAC,4BAA4B,EAAE,GAAG,EAAE;IAC1C,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,MAAM,GAAG,0BAA0B,CAAC,KAAK,CAAC,CAAC;QACjD,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,MAAM,GAAG,0BAA0B,CAAC,aAAa,CAAC,CAAC;QACzD,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,MAAM,GAAG,0BAA0B,CAAC,YAAY,CAAC,CAAC;QACxD,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,33 @@
1
+ import type { TestDefinition, TranscriptEntry } from '../types/index.js';
2
+ /** Result from executing a single test */
3
+ export interface ExecutionResult {
4
+ /** Claude's response text */
5
+ response: string;
6
+ /** Path to JSONL transcript */
7
+ transcriptPath: string;
8
+ /** Parsed transcript entries */
9
+ transcript: TranscriptEntry[];
10
+ /** Total input tokens */
11
+ inputTokens: number;
12
+ /** Total output tokens */
13
+ outputTokens: number;
14
+ /** Total cost in USD */
15
+ costUsd: number;
16
+ /** Duration in milliseconds */
17
+ durationMs: number;
18
+ /** Number of tool calls */
19
+ toolCount: number;
20
+ /** Whether execution succeeded */
21
+ success: boolean;
22
+ /** Error message if failed */
23
+ error?: string;
24
+ }
25
+ /**
26
+ * Execute a test against Claude CLI with a skill
27
+ */
28
+ export declare function executeTest(test: TestDefinition, skillPath: string, model: 'haiku' | 'sonnet' | 'opus', workDir: string): Promise<ExecutionResult>;
29
+ /**
30
+ * Clean up temporary transcript files
31
+ */
32
+ export declare function cleanupTranscripts(workDir: string): Promise<void>;
33
+ //# sourceMappingURL=claude-cli-executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-cli-executor.d.ts","sourceRoot":"","sources":["../../src/engine/claude-cli-executor.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGzE,0CAA0C;AAC1C,MAAM,WAAW,eAAe;IAC9B,6BAA6B;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,+BAA+B;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,gCAAgC;IAChC,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,yBAAyB;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,0BAA0B;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,wBAAwB;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,+BAA+B;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,2BAA2B;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,kCAAkC;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AASD;;GAEG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,cAAc,EACpB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,EAClC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,eAAe,CAAC,CAyD1B;AA8ND;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOvE"}
@@ -0,0 +1,251 @@
1
+ /**
2
+ * Claude CLI executor - invokes Claude CLI and captures output
3
+ */
4
+ import { spawn } from 'node:child_process';
5
+ import { randomUUID } from 'node:crypto';
6
+ import { mkdir, rm } from 'node:fs/promises';
7
+ import { join } from 'node:path';
8
+ import { getStoredToken } from '../commands/auth-setup-and-token-storage-command.js';
9
+ /** Model name mapping for Claude CLI */
10
+ const MODEL_MAP = {
11
+ haiku: 'claude-3-5-haiku-latest',
12
+ sonnet: 'claude-sonnet-4-20250514',
13
+ opus: 'claude-opus-4-20250514',
14
+ };
15
+ /**
16
+ * Execute a test against Claude CLI with a skill
17
+ */
18
+ export async function executeTest(test, skillPath, model, workDir) {
19
+ const sessionId = randomUUID();
20
+ const transcriptDir = join(workDir, '.skillmark-transcripts');
21
+ const transcriptPath = join(transcriptDir, `${sessionId}.jsonl`);
22
+ await mkdir(transcriptDir, { recursive: true });
23
+ const startTime = Date.now();
24
+ const modelId = MODEL_MAP[model];
25
+ // Build Claude CLI command
26
+ // -p is the print mode flag that takes the prompt as argument
27
+ const args = [
28
+ '-p', test.prompt, // Print mode with prompt - non-interactive
29
+ '--model', modelId,
30
+ '--output-format', 'json',
31
+ '--max-turns', '50',
32
+ '--dangerously-skip-permissions', // Skip permission prompts for benchmarks
33
+ ];
34
+ // Add skill if provided
35
+ if (skillPath) {
36
+ args.push('--allowedTools', `Skill(${skillPath})`);
37
+ }
38
+ try {
39
+ const result = await runClaudeCli(args, workDir, test.timeout * 1000);
40
+ const durationMs = Date.now() - startTime;
41
+ // Parse the JSON result from Claude CLI
42
+ const cliResult = parseCliResult(result.stdout);
43
+ return {
44
+ response: cliResult.response,
45
+ transcriptPath,
46
+ transcript: [], // Simplified - we use the result JSON directly
47
+ inputTokens: cliResult.inputTokens,
48
+ outputTokens: cliResult.outputTokens,
49
+ costUsd: cliResult.costUsd,
50
+ durationMs,
51
+ toolCount: cliResult.toolCount,
52
+ success: true,
53
+ };
54
+ }
55
+ catch (error) {
56
+ return {
57
+ response: '',
58
+ transcriptPath,
59
+ transcript: [],
60
+ inputTokens: 0,
61
+ outputTokens: 0,
62
+ costUsd: 0,
63
+ durationMs: Date.now() - startTime,
64
+ toolCount: 0,
65
+ success: false,
66
+ error: error instanceof Error ? error.message : String(error),
67
+ };
68
+ }
69
+ }
70
+ /**
71
+ * Run Claude CLI as a subprocess
72
+ */
73
+ async function runClaudeCli(args, cwd, timeoutMs) {
74
+ // Get stored OAuth token
75
+ const storedToken = await getStoredToken();
76
+ // Prepare environment with token if available
77
+ const env = { ...process.env };
78
+ if (storedToken) {
79
+ env.CLAUDE_CODE_OAUTH_TOKEN = storedToken;
80
+ }
81
+ return new Promise((resolve, reject) => {
82
+ const proc = spawn('claude', args, {
83
+ cwd,
84
+ env,
85
+ stdio: ['ignore', 'pipe', 'pipe'], // ignore stdin to prevent hanging
86
+ });
87
+ let stdout = '';
88
+ let stderr = '';
89
+ proc.stdout.on('data', (data) => {
90
+ stdout += data.toString();
91
+ });
92
+ proc.stderr.on('data', (data) => {
93
+ stderr += data.toString();
94
+ });
95
+ const timeout = setTimeout(() => {
96
+ proc.kill('SIGTERM');
97
+ reject(new Error(`Execution timed out after ${timeoutMs}ms`));
98
+ }, timeoutMs);
99
+ proc.on('close', (code) => {
100
+ clearTimeout(timeout);
101
+ // Check for auth errors in JSON response (Claude CLI returns error in JSON, not stderr)
102
+ if (stdout) {
103
+ try {
104
+ const result = JSON.parse(stdout);
105
+ if (result.is_error && result.result) {
106
+ const errorMsg = result.result;
107
+ if (errorMsg.includes('Invalid API key') || errorMsg.includes('/login')) {
108
+ reject(new Error(`Authentication required. Run 'skillmark auth' to authenticate.`));
109
+ return;
110
+ }
111
+ if (result.is_error) {
112
+ reject(new Error(`Claude CLI error: ${errorMsg}`));
113
+ return;
114
+ }
115
+ }
116
+ }
117
+ catch {
118
+ // Not JSON, continue with normal handling
119
+ }
120
+ }
121
+ if (code === 0) {
122
+ resolve({ stdout, stderr });
123
+ }
124
+ else {
125
+ // Include stdout in error for better diagnostics when stderr is empty
126
+ const errorDetail = stderr || stdout.slice(0, 200) || 'No error details';
127
+ reject(new Error(`Claude CLI exited with code ${code}: ${errorDetail}`));
128
+ }
129
+ });
130
+ proc.on('error', (err) => {
131
+ clearTimeout(timeout);
132
+ reject(err);
133
+ });
134
+ });
135
+ }
136
+ /**
137
+ * Parse Claude CLI JSON result output
138
+ */
139
+ function parseCliResult(output) {
140
+ try {
141
+ // Find the JSON result in the output (may have other text before it)
142
+ const jsonMatch = output.match(/\{[\s\S]*"type"\s*:\s*"result"[\s\S]*\}/);
143
+ if (!jsonMatch) {
144
+ // Fallback: try parsing the whole output as JSON
145
+ const parsed = JSON.parse(output.trim());
146
+ return extractFromCliResult(parsed);
147
+ }
148
+ const parsed = JSON.parse(jsonMatch[0]);
149
+ return extractFromCliResult(parsed);
150
+ }
151
+ catch {
152
+ // Return empty result if parsing fails
153
+ return { response: '', inputTokens: 0, outputTokens: 0, costUsd: 0, toolCount: 0 };
154
+ }
155
+ }
156
+ function extractFromCliResult(result) {
157
+ const usage = result.usage || {};
158
+ const inputTokens = (usage.input_tokens || 0) +
159
+ (usage.cache_creation_input_tokens || 0) +
160
+ (usage.cache_read_input_tokens || 0);
161
+ return {
162
+ response: result.result || '',
163
+ inputTokens,
164
+ outputTokens: usage.output_tokens || 0,
165
+ costUsd: result.total_cost_usd || 0,
166
+ toolCount: result.num_turns || 0, // num_turns as proxy for tool usage
167
+ };
168
+ }
169
+ /**
170
+ * Parse JSONL output from Claude CLI (legacy)
171
+ */
172
+ function parseJsonlOutput(output) {
173
+ const entries = [];
174
+ const lines = output.split('\n').filter((line) => line.trim());
175
+ for (const line of lines) {
176
+ try {
177
+ const entry = JSON.parse(line);
178
+ entries.push(entry);
179
+ }
180
+ catch {
181
+ // Skip non-JSON lines
182
+ }
183
+ }
184
+ return entries;
185
+ }
186
+ /**
187
+ * Extract metrics from transcript entries
188
+ */
189
+ function extractMetrics(transcript) {
190
+ let inputTokens = 0;
191
+ let outputTokens = 0;
192
+ let costUsd = 0;
193
+ let toolCount = 0;
194
+ for (const entry of transcript) {
195
+ if (entry.inputTokens)
196
+ inputTokens += entry.inputTokens;
197
+ if (entry.outputTokens)
198
+ outputTokens += entry.outputTokens;
199
+ if (entry.cacheCreationInputTokens)
200
+ inputTokens += entry.cacheCreationInputTokens;
201
+ if (entry.cacheReadInputTokens)
202
+ inputTokens += entry.cacheReadInputTokens;
203
+ if (entry.costUSD)
204
+ costUsd += entry.costUSD;
205
+ // Count tool uses
206
+ if (entry.type === 'assistant' && entry.message?.content) {
207
+ const content = entry.message.content;
208
+ if (Array.isArray(content)) {
209
+ toolCount += content.filter((c) => c.type === 'tool_use').length;
210
+ }
211
+ }
212
+ }
213
+ return { inputTokens, outputTokens, costUsd, toolCount };
214
+ }
215
+ /**
216
+ * Extract final response text from transcript
217
+ */
218
+ function extractResponse(transcript) {
219
+ // Get last assistant message
220
+ for (let i = transcript.length - 1; i >= 0; i--) {
221
+ const entry = transcript[i];
222
+ if (entry.type === 'assistant' && entry.message?.content) {
223
+ const content = entry.message.content;
224
+ if (typeof content === 'string') {
225
+ return content;
226
+ }
227
+ if (Array.isArray(content)) {
228
+ const textParts = content
229
+ .filter((c) => c.type === 'text' && c.text)
230
+ .map((c) => c.text)
231
+ .join('\n');
232
+ if (textParts)
233
+ return textParts;
234
+ }
235
+ }
236
+ }
237
+ return '';
238
+ }
239
+ /**
240
+ * Clean up temporary transcript files
241
+ */
242
+ export async function cleanupTranscripts(workDir) {
243
+ const transcriptDir = join(workDir, '.skillmark-transcripts');
244
+ try {
245
+ await rm(transcriptDir, { recursive: true, force: true });
246
+ }
247
+ catch {
248
+ // Ignore cleanup errors
249
+ }
250
+ }
251
+ //# sourceMappingURL=claude-cli-executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-cli-executor.js","sourceRoot":"","sources":["../../src/engine/claude-cli-executor.ts"],"names":[],"mappings":"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"}