diff --git a/.claude/skills/regression/run.mjs b/.claude/skills/regression/run.mjs new file mode 100644 index 00000000..b089de3e --- /dev/null +++ b/.claude/skills/regression/run.mjs @@ -0,0 +1,21 @@ +#!/usr/bin/env node +// .claude/skills/regression/run.mjs +// Regression sweep orchestrator for the /regression skill. +// Design: docs/superpowers/specs/2026-05-16-regression-skill-design.md +import process from 'node:process'; + +// ── pure: platform binary resolution ─────────────────────────────── +export function resolveBinary(name, platform = process.platform) { + return platform === 'win32' ? `bin\\${name}.exe` : name; +} + +// ── pure: output header line ─────────────────────────────────────── +export function buildHeader(tier) { + const head = `─ /regression ${tier} `; + return head + '─'.repeat(Math.max(3, 48 - head.length)); +} + +// ── pure: exit-code token ────────────────────────────────────────── +export function parseExit(label, code) { + return `${label} ${code}`; +} diff --git a/.claude/skills/regression/run.test.mjs b/.claude/skills/regression/run.test.mjs new file mode 100644 index 00000000..4ab229b1 --- /dev/null +++ b/.claude/skills/regression/run.test.mjs @@ -0,0 +1,26 @@ +import test from 'node:test'; +import assert from 'node:assert/strict'; +import { + resolveBinary, buildHeader, parseExit, +} from './run.mjs'; + +test('resolveBinary: win32 → bin\\.exe', () => { + assert.equal(resolveBinary('gitleaks', 'win32'), 'bin\\gitleaks.exe'); +}); +test('resolveBinary: non-win32 → bare name on PATH', () => { + assert.equal(resolveBinary('lychee', 'linux'), 'lychee'); + assert.equal(resolveBinary('lychee', 'darwin'), 'lychee'); +}); + +test('buildHeader: starts with the tier banner', () => { + assert.ok(buildHeader('quick').startsWith('─ /regression quick ')); + assert.ok(buildHeader('full').startsWith('─ /regression full ')); +}); +test('buildHeader: is padded with dashes', () => { + assert.ok(buildHeader('full').length >= 30); +}); + +test('parseExit: builds "