@skillsmith/cli 0.3.4 → 0.3.6
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.
- package/dist/.tsbuildinfo +1 -1
- package/dist/src/commands/ab-test.d.ts +28 -0
- package/dist/src/commands/ab-test.d.ts.map +1 -0
- package/dist/src/commands/ab-test.js +217 -0
- package/dist/src/commands/ab-test.js.map +1 -0
- package/dist/src/commands/ab-test.test.d.ts +7 -0
- package/dist/src/commands/ab-test.test.d.ts.map +1 -0
- package/dist/src/commands/ab-test.test.js +255 -0
- package/dist/src/commands/ab-test.test.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-1916: A/B Testing Command (Team+ tier feature)
|
|
3
|
+
*
|
|
4
|
+
* Runs controlled A/B tests comparing original vs optimized skills.
|
|
5
|
+
* This feature is gated to Team and Enterprise tier users.
|
|
6
|
+
*/
|
|
7
|
+
import { Command } from 'commander';
|
|
8
|
+
/**
|
|
9
|
+
* Options for the ab-test command
|
|
10
|
+
*/
|
|
11
|
+
export interface AbTestOptions {
|
|
12
|
+
skill: string | undefined;
|
|
13
|
+
iterations: number | undefined;
|
|
14
|
+
output: string | undefined;
|
|
15
|
+
json: boolean | undefined;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Run the A/B test experiment
|
|
19
|
+
*
|
|
20
|
+
* @param options - Test options
|
|
21
|
+
*/
|
|
22
|
+
export declare function runAbTest(options: AbTestOptions): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Create the ab-test command
|
|
25
|
+
*/
|
|
26
|
+
export declare function createAbTestCommand(): Command;
|
|
27
|
+
export default createAbTestCommand;
|
|
28
|
+
//# sourceMappingURL=ab-test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ab-test.d.ts","sourceRoot":"","sources":["../../../src/commands/ab-test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAMnC;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;IACzB,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;IAC9B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,IAAI,EAAE,OAAO,GAAG,SAAS,CAAA;CAC1B;AAyGD;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA2FrE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CA6B7C;AAED,eAAe,mBAAmB,CAAA"}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-1916: A/B Testing Command (Team+ tier feature)
|
|
3
|
+
*
|
|
4
|
+
* Runs controlled A/B tests comparing original vs optimized skills.
|
|
5
|
+
* This feature is gated to Team and Enterprise tier users.
|
|
6
|
+
*/
|
|
7
|
+
import { Command } from 'commander';
|
|
8
|
+
import chalk from 'chalk';
|
|
9
|
+
import { tryLoadEnterpriseValidator } from '../utils/license-validation.js';
|
|
10
|
+
import { sanitizeError } from '../utils/sanitize.js';
|
|
11
|
+
/**
|
|
12
|
+
* Check if the current user has access to the A/B testing feature
|
|
13
|
+
*
|
|
14
|
+
* @returns Access result with tier information
|
|
15
|
+
*/
|
|
16
|
+
async function checkAbTestingAccess() {
|
|
17
|
+
const validator = await tryLoadEnterpriseValidator();
|
|
18
|
+
if (!validator) {
|
|
19
|
+
// Enterprise package not available = community tier
|
|
20
|
+
return { allowed: false, tier: 'community' };
|
|
21
|
+
}
|
|
22
|
+
const licenseKey = process.env['SKILLSMITH_LICENSE_KEY'];
|
|
23
|
+
if (!licenseKey) {
|
|
24
|
+
return { allowed: false, tier: 'community' };
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
const result = await validator.validate(licenseKey);
|
|
28
|
+
if (!result.valid || !result.license) {
|
|
29
|
+
return { allowed: false, tier: 'community' };
|
|
30
|
+
}
|
|
31
|
+
const tier = result.license.tier;
|
|
32
|
+
// ab_testing is available for team and enterprise tiers
|
|
33
|
+
const allowed = tier === 'team' || tier === 'enterprise';
|
|
34
|
+
return { allowed, tier };
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return { allowed: false, tier: 'community' };
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Display upgrade prompt for users without A/B testing access
|
|
42
|
+
*
|
|
43
|
+
* @param currentTier - The user's current tier
|
|
44
|
+
*/
|
|
45
|
+
function showUpgradePrompt(currentTier) {
|
|
46
|
+
console.log();
|
|
47
|
+
console.log(chalk.yellow('\u2501'.repeat(60)));
|
|
48
|
+
console.log(chalk.yellow.bold(' A/B Testing requires Team tier or higher'));
|
|
49
|
+
console.log(chalk.yellow('\u2501'.repeat(60)));
|
|
50
|
+
console.log();
|
|
51
|
+
console.log(chalk.dim(` Current tier: ${currentTier}`));
|
|
52
|
+
console.log();
|
|
53
|
+
console.log(' ' + chalk.cyan('Team tier') + chalk.dim(' ($25/user/mo)'));
|
|
54
|
+
console.log(' \u2022 A/B testing for skill optimization');
|
|
55
|
+
console.log(' \u2022 Team workspaces & private skills');
|
|
56
|
+
console.log(' \u2022 Usage analytics & priority support');
|
|
57
|
+
console.log();
|
|
58
|
+
console.log(' ' + chalk.magenta('Enterprise tier') + chalk.dim(' ($55/user/mo)'));
|
|
59
|
+
console.log(' \u2022 Everything in Team, plus:');
|
|
60
|
+
console.log(' \u2022 SSO/SAML, RBAC, audit logging');
|
|
61
|
+
console.log(' \u2022 Private registry & custom integrations');
|
|
62
|
+
console.log();
|
|
63
|
+
console.log(chalk.bold(' Upgrade: ') + chalk.underline('https://skillsmith.app/pricing'));
|
|
64
|
+
console.log();
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Display upgrade prompt as JSON for programmatic consumption
|
|
68
|
+
*
|
|
69
|
+
* @param currentTier - The user's current tier
|
|
70
|
+
*/
|
|
71
|
+
function showUpgradePromptJson(currentTier) {
|
|
72
|
+
const response = {
|
|
73
|
+
error: 'upgrade_required',
|
|
74
|
+
message: 'A/B Testing requires Team tier or higher',
|
|
75
|
+
currentTier,
|
|
76
|
+
requiredTier: 'team',
|
|
77
|
+
feature: 'ab_testing',
|
|
78
|
+
upgradeUrl: 'https://skillsmith.app/pricing',
|
|
79
|
+
tiers: {
|
|
80
|
+
team: {
|
|
81
|
+
price: '$25/user/mo',
|
|
82
|
+
features: [
|
|
83
|
+
'A/B testing for skill optimization',
|
|
84
|
+
'Team workspaces & private skills',
|
|
85
|
+
'Usage analytics & priority support',
|
|
86
|
+
],
|
|
87
|
+
},
|
|
88
|
+
enterprise: {
|
|
89
|
+
price: '$55/user/mo',
|
|
90
|
+
features: [
|
|
91
|
+
'Everything in Team',
|
|
92
|
+
'SSO/SAML, RBAC, audit logging',
|
|
93
|
+
'Private registry & custom integrations',
|
|
94
|
+
],
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
console.log(JSON.stringify(response, null, 2));
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Run the A/B test experiment
|
|
102
|
+
*
|
|
103
|
+
* @param options - Test options
|
|
104
|
+
*/
|
|
105
|
+
export async function runAbTest(options) {
|
|
106
|
+
const isJson = options.json ?? false;
|
|
107
|
+
// Feature gate check
|
|
108
|
+
const { allowed, tier } = await checkAbTestingAccess();
|
|
109
|
+
if (!allowed) {
|
|
110
|
+
if (isJson) {
|
|
111
|
+
showUpgradePromptJson(tier);
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
showUpgradePrompt(tier);
|
|
115
|
+
}
|
|
116
|
+
process.exit(1);
|
|
117
|
+
}
|
|
118
|
+
// Team/Enterprise: Proceed with A/B testing
|
|
119
|
+
if (!isJson) {
|
|
120
|
+
console.log();
|
|
121
|
+
console.log(chalk.blue.bold('\u2501'.repeat(50)));
|
|
122
|
+
console.log(chalk.blue.bold(' Skillsmith A/B Testing'));
|
|
123
|
+
console.log(chalk.blue.bold('\u2501'.repeat(50)));
|
|
124
|
+
console.log();
|
|
125
|
+
}
|
|
126
|
+
// Validate required options
|
|
127
|
+
if (!options.skill) {
|
|
128
|
+
if (isJson) {
|
|
129
|
+
console.log(JSON.stringify({ error: 'Skill name is required. Use --skill <name>' }));
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
console.error(chalk.red('Error: Skill name is required. Use --skill <name>'));
|
|
133
|
+
}
|
|
134
|
+
process.exit(1);
|
|
135
|
+
}
|
|
136
|
+
const iterations = options.iterations ?? 10;
|
|
137
|
+
const outputDir = options.output ?? 'docs/research/ab-test';
|
|
138
|
+
if (!isJson) {
|
|
139
|
+
console.log(chalk.dim(` Tier: ${tier}`));
|
|
140
|
+
console.log(chalk.dim(` Skill: ${options.skill}`));
|
|
141
|
+
console.log(chalk.dim(` Iterations: ${iterations}`));
|
|
142
|
+
console.log(chalk.dim(` Output: ${outputDir}`));
|
|
143
|
+
console.log();
|
|
144
|
+
}
|
|
145
|
+
try {
|
|
146
|
+
// A/B test runner implementation placeholder
|
|
147
|
+
// The actual experiment runner will be implemented in a separate module
|
|
148
|
+
// For now, provide guidance on manual execution
|
|
149
|
+
if (isJson) {
|
|
150
|
+
console.log(JSON.stringify({
|
|
151
|
+
status: 'ready',
|
|
152
|
+
message: 'A/B test infrastructure ready. Use scripts/run-large-skill-experiments.ts for experiments.',
|
|
153
|
+
skill: options.skill,
|
|
154
|
+
iterations,
|
|
155
|
+
outputDir,
|
|
156
|
+
manualCommand: `docker exec skillsmith-dev-1 npx tsx scripts/run-large-skill-experiments.ts --skill ${options.skill} --iterations ${iterations}`,
|
|
157
|
+
}));
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
console.log(chalk.green('A/B testing infrastructure is ready.'));
|
|
161
|
+
console.log();
|
|
162
|
+
console.log(chalk.dim('The A/B testing experiment will:'));
|
|
163
|
+
console.log(chalk.dim(' 1. Download original skill from the registry'));
|
|
164
|
+
console.log(chalk.dim(' 2. Apply Skillsmith transformations'));
|
|
165
|
+
console.log(chalk.dim(' 3. Run comparative benchmarks'));
|
|
166
|
+
console.log(chalk.dim(' 4. Generate detailed analysis report'));
|
|
167
|
+
console.log();
|
|
168
|
+
console.log(chalk.cyan('For manual execution, run:'));
|
|
169
|
+
console.log(chalk.white(` docker exec skillsmith-dev-1 npx tsx scripts/run-large-skill-experiments.ts --skill ${options.skill} --iterations ${iterations}`));
|
|
170
|
+
}
|
|
171
|
+
if (!isJson) {
|
|
172
|
+
console.log();
|
|
173
|
+
console.log(chalk.dim('─'.repeat(50)));
|
|
174
|
+
console.log(chalk.dim('Note: Full A/B test runner coming soon.'));
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
catch (error) {
|
|
178
|
+
if (isJson) {
|
|
179
|
+
console.error(JSON.stringify({ error: sanitizeError(error) }));
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
console.error(chalk.red('A/B test failed:'), sanitizeError(error));
|
|
183
|
+
}
|
|
184
|
+
process.exit(1);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Create the ab-test command
|
|
189
|
+
*/
|
|
190
|
+
export function createAbTestCommand() {
|
|
191
|
+
const cmd = new Command('ab-test')
|
|
192
|
+
.description('Run A/B testing experiments comparing original vs optimized skills (Team+ tier)')
|
|
193
|
+
.option('-s, --skill <name>', 'Name of the skill to test')
|
|
194
|
+
.option('-i, --iterations <number>', 'Number of test iterations', '10')
|
|
195
|
+
.option('-o, --output <directory>', 'Output directory for results', 'docs/research/ab-test')
|
|
196
|
+
.option('-j, --json', 'Output results as JSON')
|
|
197
|
+
.addHelpText('after', `
|
|
198
|
+
Examples:
|
|
199
|
+
$ skillsmith ab-test --skill governance
|
|
200
|
+
$ skillsmith ab-test --skill commit --iterations 20
|
|
201
|
+
$ skillsmith ab-test --skill react-best-practices --json
|
|
202
|
+
|
|
203
|
+
Note: This feature requires Team tier ($25/user/mo) or higher.
|
|
204
|
+
Visit https://skillsmith.app/pricing to upgrade.
|
|
205
|
+
`)
|
|
206
|
+
.action(async (opts) => {
|
|
207
|
+
await runAbTest({
|
|
208
|
+
skill: opts['skill'],
|
|
209
|
+
iterations: opts['iterations'] ? parseInt(opts['iterations'], 10) : 10,
|
|
210
|
+
output: opts['output'],
|
|
211
|
+
json: opts['json'] === true,
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
return cmd;
|
|
215
|
+
}
|
|
216
|
+
export default createAbTestCommand;
|
|
217
|
+
//# sourceMappingURL=ab-test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ab-test.js","sourceRoot":"","sources":["../../../src/commands/ab-test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ab-test.test.d.ts","sourceRoot":"","sources":["../../../src/commands/ab-test.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-1916: A/B Testing Command Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests for the ab-test CLI command with tier-based feature gating.
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
7
|
+
import { createAbTestCommand, runAbTest } from './ab-test.js';
|
|
8
|
+
// Mock the license validation module
|
|
9
|
+
vi.mock('../utils/license-validation.js', () => ({
|
|
10
|
+
tryLoadEnterpriseValidator: vi.fn(),
|
|
11
|
+
}));
|
|
12
|
+
// Mock sanitizeError
|
|
13
|
+
vi.mock('../utils/sanitize.js', () => ({
|
|
14
|
+
sanitizeError: vi.fn((err) => (err instanceof Error ? err.message : String(err))),
|
|
15
|
+
}));
|
|
16
|
+
// Import mocked module
|
|
17
|
+
import { tryLoadEnterpriseValidator } from '../utils/license-validation.js';
|
|
18
|
+
const mockTryLoadEnterpriseValidator = vi.mocked(tryLoadEnterpriseValidator);
|
|
19
|
+
describe('ab-test command', () => {
|
|
20
|
+
let consoleLogSpy;
|
|
21
|
+
let consoleErrorSpy;
|
|
22
|
+
let processExitSpy;
|
|
23
|
+
let originalEnv;
|
|
24
|
+
beforeEach(() => {
|
|
25
|
+
// Save original env
|
|
26
|
+
originalEnv = { ...process.env };
|
|
27
|
+
// Spy on console methods
|
|
28
|
+
consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
|
|
29
|
+
consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => { });
|
|
30
|
+
// Mock process.exit to throw instead of exiting
|
|
31
|
+
processExitSpy = vi
|
|
32
|
+
.spyOn(process, 'exit')
|
|
33
|
+
.mockImplementation((code) => {
|
|
34
|
+
throw new Error(`process.exit(${code})`);
|
|
35
|
+
});
|
|
36
|
+
// Reset mocks
|
|
37
|
+
vi.clearAllMocks();
|
|
38
|
+
});
|
|
39
|
+
afterEach(() => {
|
|
40
|
+
// Restore original env
|
|
41
|
+
process.env = originalEnv;
|
|
42
|
+
// Restore spies
|
|
43
|
+
consoleLogSpy.mockRestore();
|
|
44
|
+
consoleErrorSpy.mockRestore();
|
|
45
|
+
processExitSpy.mockRestore();
|
|
46
|
+
});
|
|
47
|
+
describe('createAbTestCommand', () => {
|
|
48
|
+
it('should create a command with correct name and description', () => {
|
|
49
|
+
const cmd = createAbTestCommand();
|
|
50
|
+
expect(cmd.name()).toBe('ab-test');
|
|
51
|
+
expect(cmd.description()).toContain('A/B testing experiments');
|
|
52
|
+
expect(cmd.description()).toContain('Team+ tier');
|
|
53
|
+
});
|
|
54
|
+
it('should have required options', () => {
|
|
55
|
+
const cmd = createAbTestCommand();
|
|
56
|
+
const options = cmd.options;
|
|
57
|
+
const optionNames = options.map((opt) => opt.long);
|
|
58
|
+
expect(optionNames).toContain('--skill');
|
|
59
|
+
expect(optionNames).toContain('--iterations');
|
|
60
|
+
expect(optionNames).toContain('--output');
|
|
61
|
+
expect(optionNames).toContain('--json');
|
|
62
|
+
});
|
|
63
|
+
it('should have default values for iterations and output', () => {
|
|
64
|
+
const cmd = createAbTestCommand();
|
|
65
|
+
const options = cmd.options;
|
|
66
|
+
const iterationsOpt = options.find((opt) => opt.long === '--iterations');
|
|
67
|
+
const outputOpt = options.find((opt) => opt.long === '--output');
|
|
68
|
+
expect(iterationsOpt?.defaultValue).toBe('10');
|
|
69
|
+
expect(outputOpt?.defaultValue).toBe('docs/research/ab-test');
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
describe('runAbTest - tier gating', () => {
|
|
73
|
+
const defaultOptions = {
|
|
74
|
+
skill: 'governance',
|
|
75
|
+
iterations: 10,
|
|
76
|
+
output: 'docs/research/ab-test',
|
|
77
|
+
json: false,
|
|
78
|
+
};
|
|
79
|
+
it('should show upgrade prompt for community tier (no license key)', async () => {
|
|
80
|
+
// No license key
|
|
81
|
+
delete process.env['SKILLSMITH_LICENSE_KEY'];
|
|
82
|
+
mockTryLoadEnterpriseValidator.mockResolvedValue(null);
|
|
83
|
+
await expect(runAbTest(defaultOptions)).rejects.toThrow('process.exit(1)');
|
|
84
|
+
// Verify upgrade prompt was shown
|
|
85
|
+
const logCalls = consoleLogSpy.mock.calls.flat().join('\n');
|
|
86
|
+
expect(logCalls).toContain('A/B Testing requires Team tier or higher');
|
|
87
|
+
expect(logCalls).toContain('community');
|
|
88
|
+
expect(logCalls).toContain('Team tier');
|
|
89
|
+
expect(logCalls).toContain('$25/user/mo');
|
|
90
|
+
});
|
|
91
|
+
it('should show JSON upgrade prompt when --json flag is set', async () => {
|
|
92
|
+
delete process.env['SKILLSMITH_LICENSE_KEY'];
|
|
93
|
+
mockTryLoadEnterpriseValidator.mockResolvedValue(null);
|
|
94
|
+
const jsonOptions = { ...defaultOptions, json: true };
|
|
95
|
+
await expect(runAbTest(jsonOptions)).rejects.toThrow('process.exit(1)');
|
|
96
|
+
// Verify JSON output
|
|
97
|
+
const logCalls = consoleLogSpy.mock.calls.flat();
|
|
98
|
+
const jsonOutput = logCalls.find((call) => typeof call === 'string' && call.includes('{'));
|
|
99
|
+
expect(jsonOutput).toBeDefined();
|
|
100
|
+
const parsed = JSON.parse(jsonOutput);
|
|
101
|
+
expect(parsed.error).toBe('upgrade_required');
|
|
102
|
+
expect(parsed.feature).toBe('ab_testing');
|
|
103
|
+
expect(parsed.requiredTier).toBe('team');
|
|
104
|
+
});
|
|
105
|
+
it('should show upgrade prompt for individual tier', async () => {
|
|
106
|
+
process.env['SKILLSMITH_LICENSE_KEY'] = 'test-key';
|
|
107
|
+
const mockValidator = {
|
|
108
|
+
validate: vi.fn().mockResolvedValue({
|
|
109
|
+
valid: true,
|
|
110
|
+
license: { tier: 'individual', features: [] },
|
|
111
|
+
}),
|
|
112
|
+
};
|
|
113
|
+
mockTryLoadEnterpriseValidator.mockResolvedValue(mockValidator);
|
|
114
|
+
await expect(runAbTest(defaultOptions)).rejects.toThrow('process.exit(1)');
|
|
115
|
+
const logCalls = consoleLogSpy.mock.calls.flat().join('\n');
|
|
116
|
+
expect(logCalls).toContain('A/B Testing requires Team tier or higher');
|
|
117
|
+
expect(logCalls).toContain('individual');
|
|
118
|
+
});
|
|
119
|
+
it('should allow team tier users', async () => {
|
|
120
|
+
process.env['SKILLSMITH_LICENSE_KEY'] = 'team-key';
|
|
121
|
+
const mockValidator = {
|
|
122
|
+
validate: vi.fn().mockResolvedValue({
|
|
123
|
+
valid: true,
|
|
124
|
+
license: { tier: 'team', features: ['ab_testing'] },
|
|
125
|
+
}),
|
|
126
|
+
};
|
|
127
|
+
mockTryLoadEnterpriseValidator.mockResolvedValue(mockValidator);
|
|
128
|
+
// Should not throw - team tier has access
|
|
129
|
+
await runAbTest(defaultOptions);
|
|
130
|
+
const logCalls = consoleLogSpy.mock.calls.flat().join('\n');
|
|
131
|
+
expect(logCalls).toContain('A/B testing infrastructure is ready');
|
|
132
|
+
expect(logCalls).toContain('Tier: team');
|
|
133
|
+
});
|
|
134
|
+
it('should allow enterprise tier users', async () => {
|
|
135
|
+
process.env['SKILLSMITH_LICENSE_KEY'] = 'enterprise-key';
|
|
136
|
+
const mockValidator = {
|
|
137
|
+
validate: vi.fn().mockResolvedValue({
|
|
138
|
+
valid: true,
|
|
139
|
+
license: { tier: 'enterprise', features: ['ab_testing'] },
|
|
140
|
+
}),
|
|
141
|
+
};
|
|
142
|
+
mockTryLoadEnterpriseValidator.mockResolvedValue(mockValidator);
|
|
143
|
+
await runAbTest(defaultOptions);
|
|
144
|
+
const logCalls = consoleLogSpy.mock.calls.flat().join('\n');
|
|
145
|
+
expect(logCalls).toContain('A/B testing infrastructure is ready');
|
|
146
|
+
expect(logCalls).toContain('Tier: enterprise');
|
|
147
|
+
});
|
|
148
|
+
it('should treat invalid license as community tier', async () => {
|
|
149
|
+
process.env['SKILLSMITH_LICENSE_KEY'] = 'invalid-key';
|
|
150
|
+
const mockValidator = {
|
|
151
|
+
validate: vi.fn().mockResolvedValue({
|
|
152
|
+
valid: false,
|
|
153
|
+
error: { code: 'INVALID_TOKEN', message: 'Invalid' },
|
|
154
|
+
}),
|
|
155
|
+
};
|
|
156
|
+
mockTryLoadEnterpriseValidator.mockResolvedValue(mockValidator);
|
|
157
|
+
await expect(runAbTest(defaultOptions)).rejects.toThrow('process.exit(1)');
|
|
158
|
+
const logCalls = consoleLogSpy.mock.calls.flat().join('\n');
|
|
159
|
+
expect(logCalls).toContain('community');
|
|
160
|
+
});
|
|
161
|
+
it('should handle validator errors gracefully', async () => {
|
|
162
|
+
process.env['SKILLSMITH_LICENSE_KEY'] = 'test-key';
|
|
163
|
+
const mockValidator = {
|
|
164
|
+
validate: vi.fn().mockRejectedValue(new Error('Network error')),
|
|
165
|
+
};
|
|
166
|
+
mockTryLoadEnterpriseValidator.mockResolvedValue(mockValidator);
|
|
167
|
+
await expect(runAbTest(defaultOptions)).rejects.toThrow('process.exit(1)');
|
|
168
|
+
const logCalls = consoleLogSpy.mock.calls.flat().join('\n');
|
|
169
|
+
expect(logCalls).toContain('community');
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
describe('runAbTest - input validation', () => {
|
|
173
|
+
beforeEach(() => {
|
|
174
|
+
// Set up team tier for these tests
|
|
175
|
+
process.env['SKILLSMITH_LICENSE_KEY'] = 'team-key';
|
|
176
|
+
const mockValidator = {
|
|
177
|
+
validate: vi.fn().mockResolvedValue({
|
|
178
|
+
valid: true,
|
|
179
|
+
license: { tier: 'team', features: ['ab_testing'] },
|
|
180
|
+
}),
|
|
181
|
+
};
|
|
182
|
+
mockTryLoadEnterpriseValidator.mockResolvedValue(mockValidator);
|
|
183
|
+
});
|
|
184
|
+
it('should require skill name', async () => {
|
|
185
|
+
const optionsWithoutSkill = {
|
|
186
|
+
skill: undefined,
|
|
187
|
+
iterations: 10,
|
|
188
|
+
output: 'docs/research/ab-test',
|
|
189
|
+
json: false,
|
|
190
|
+
};
|
|
191
|
+
await expect(runAbTest(optionsWithoutSkill)).rejects.toThrow('process.exit(1)');
|
|
192
|
+
const errorCalls = consoleErrorSpy.mock.calls.flat().join('\n');
|
|
193
|
+
expect(errorCalls).toContain('Skill name is required');
|
|
194
|
+
});
|
|
195
|
+
it('should return JSON error when skill missing with --json', async () => {
|
|
196
|
+
const optionsWithoutSkill = {
|
|
197
|
+
skill: undefined,
|
|
198
|
+
iterations: 10,
|
|
199
|
+
output: 'docs/research/ab-test',
|
|
200
|
+
json: true,
|
|
201
|
+
};
|
|
202
|
+
await expect(runAbTest(optionsWithoutSkill)).rejects.toThrow('process.exit(1)');
|
|
203
|
+
const logCalls = consoleLogSpy.mock.calls.flat();
|
|
204
|
+
const jsonOutput = logCalls.find((call) => typeof call === 'string' && call.includes('error'));
|
|
205
|
+
expect(jsonOutput).toBeDefined();
|
|
206
|
+
const parsed = JSON.parse(jsonOutput);
|
|
207
|
+
expect(parsed.error).toContain('Skill name is required');
|
|
208
|
+
});
|
|
209
|
+
it('should use default iterations when not specified', async () => {
|
|
210
|
+
const options = {
|
|
211
|
+
skill: 'test-skill',
|
|
212
|
+
iterations: undefined,
|
|
213
|
+
output: 'docs/research/ab-test',
|
|
214
|
+
json: true,
|
|
215
|
+
};
|
|
216
|
+
await runAbTest(options);
|
|
217
|
+
const logCalls = consoleLogSpy.mock.calls.flat();
|
|
218
|
+
const jsonOutput = logCalls.find((call) => typeof call === 'string' && call.includes('iterations'));
|
|
219
|
+
expect(jsonOutput).toBeDefined();
|
|
220
|
+
const parsed = JSON.parse(jsonOutput);
|
|
221
|
+
expect(parsed.iterations).toBe(10);
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
describe('runAbTest - JSON output', () => {
|
|
225
|
+
beforeEach(() => {
|
|
226
|
+
process.env['SKILLSMITH_LICENSE_KEY'] = 'team-key';
|
|
227
|
+
const mockValidator = {
|
|
228
|
+
validate: vi.fn().mockResolvedValue({
|
|
229
|
+
valid: true,
|
|
230
|
+
license: { tier: 'team', features: ['ab_testing'] },
|
|
231
|
+
}),
|
|
232
|
+
};
|
|
233
|
+
mockTryLoadEnterpriseValidator.mockResolvedValue(mockValidator);
|
|
234
|
+
});
|
|
235
|
+
it('should output valid JSON when --json flag is set', async () => {
|
|
236
|
+
const options = {
|
|
237
|
+
skill: 'governance',
|
|
238
|
+
iterations: 5,
|
|
239
|
+
output: 'custom/output',
|
|
240
|
+
json: true,
|
|
241
|
+
};
|
|
242
|
+
await runAbTest(options);
|
|
243
|
+
const logCalls = consoleLogSpy.mock.calls.flat();
|
|
244
|
+
const jsonOutput = logCalls.find((call) => typeof call === 'string' && call.includes('{'));
|
|
245
|
+
expect(jsonOutput).toBeDefined();
|
|
246
|
+
const parsed = JSON.parse(jsonOutput);
|
|
247
|
+
expect(parsed.status).toBe('ready');
|
|
248
|
+
expect(parsed.skill).toBe('governance');
|
|
249
|
+
expect(parsed.iterations).toBe(5);
|
|
250
|
+
expect(parsed.outputDir).toBe('custom/output');
|
|
251
|
+
expect(parsed.manualCommand).toContain('governance');
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
//# sourceMappingURL=ab-test.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ab-test.test.js","sourceRoot":"","sources":["../../../src/commands/ab-test.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skillsmith/cli",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.6",
|
|
4
4
|
"description": "CLI tools for Skillsmith skill discovery",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@inquirer/prompts": "7.10.1",
|
|
19
|
-
"@skillsmith/core": "0.4.
|
|
19
|
+
"@skillsmith/core": "0.4.3",
|
|
20
20
|
"chalk": "5.6.2",
|
|
21
21
|
"cli-table3": "0.6.5",
|
|
22
22
|
"commander": "12.1.0",
|