@attest-it/cli 0.0.1

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/output.ts","../src/utils/prompts.ts","../src/utils/exit-codes.ts","../src/commands/init.ts","../src/commands/status.ts","../src/commands/run.ts","../src/commands/keygen.ts","../src/commands/prune.ts","../src/commands/verify.ts","../src/index.ts"],"names":["pc","confirm","select","input","Command","path","fs","YAML","loadConfig","readAttestations","computeFingerprint","findAttestation","createAttestation","os","upsertAttestation","getDefaultPrivateKeyPath","fs2","writeSignedAttestations","parseShellCommand","resolve","spawn","checkOpenSSL","getDefaultPublicKeyPath","fs3","generateKeyPair","setKeyPermissions","fs4","result","verifyAttestations","toAttestItConfig"],"mappings":"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","file":"index.cjs","sourcesContent":["import pc from 'picocolors'\n\nexport interface OutputOptions {\n verbose?: boolean\n quiet?: boolean\n json?: boolean\n}\n\n// Singleton for global output options\nlet globalOptions: OutputOptions = {}\n\nexport function setOutputOptions(options: OutputOptions): void {\n globalOptions = options\n}\n\nexport function getOutputOptions(): OutputOptions {\n return globalOptions\n}\n\n// Logging functions\nexport function log(message: string): void {\n if (!globalOptions.quiet) {\n console.log(message)\n }\n}\n\nexport function verbose(message: string): void {\n if (globalOptions.verbose && !globalOptions.quiet) {\n console.log(pc.dim(message))\n }\n}\n\nexport function success(message: string): void {\n log(pc.green('✓ ' + message))\n}\n\nexport function error(message: string): void {\n console.error(pc.red('✗ ' + message))\n}\n\nexport function warn(message: string): void {\n if (!globalOptions.quiet) {\n console.warn(pc.yellow('⚠ ' + message))\n }\n}\n\nexport function info(message: string): void {\n log(pc.blue('ℹ ' + message))\n}\n\n// Table formatting for status display\nexport interface TableRow {\n suite: string\n status: string\n fingerprint: string\n age: string\n}\n\nexport function formatTable(rows: TableRow[]): string {\n // Calculate column widths\n const headers = ['Suite', 'Status', 'Fingerprint', 'Age']\n\n // Helper to get row values in consistent order\n const getRowValues = (row: TableRow): string[] => [\n row.suite,\n row.status,\n row.fingerprint,\n row.age,\n ]\n\n const widths = headers.map((h, i) => {\n const columnValues = rows.map((r) => {\n const values = getRowValues(r)\n // eslint-disable-next-line security/detect-object-injection -- i is from .map() index\n return values[i] ?? ''\n })\n const maxValueLength = Math.max(...columnValues.map((v) => v.length), 0)\n return Math.max(h.length, maxValueLength)\n })\n\n // Build table\n const separator = '─'\n const lines: string[] = []\n\n // Header\n // eslint-disable-next-line security/detect-object-injection -- i is from .map() index\n lines.push(headers.map((h, i) => h.padEnd(widths[i] ?? 0)).join(' │ '))\n lines.push(widths.map((w) => separator.repeat(w)).join('─┼─'))\n\n // Rows\n for (const row of rows) {\n const values = getRowValues(row)\n // eslint-disable-next-line security/detect-object-injection -- i is from .map() index\n lines.push(values.map((v, i) => v.padEnd(widths[i] ?? 0)).join(' │ '))\n }\n\n return lines.join('\\n')\n}\n\n// Status colorization\nexport function colorizeStatus(status: string): string {\n switch (status) {\n case 'VALID':\n return pc.green(status)\n case 'NEEDS_ATTESTATION':\n case 'FINGERPRINT_CHANGED':\n return pc.yellow(status)\n case 'EXPIRED':\n case 'INVALIDATED_BY_PARENT':\n return pc.red(status)\n case 'SIGNATURE_INVALID':\n return pc.red(pc.bold(status))\n default:\n return status\n }\n}\n\n// JSON output\nexport function outputJson(data: unknown): void {\n console.log(JSON.stringify(data, null, 2))\n}\n","import { confirm, input, select } from '@inquirer/prompts'\n\nexport interface ConfirmOptions {\n message: string\n default?: boolean\n}\n\nexport async function confirmAction(options: ConfirmOptions): Promise<boolean> {\n return confirm({\n message: options.message,\n default: options.default ?? false,\n })\n}\n\nexport interface SelectOptions<T extends string> {\n message: string\n choices: { value: T; name: string; description?: string }[]\n}\n\nexport async function selectOption<T extends string>(options: SelectOptions<T>): Promise<T> {\n return select({\n message: options.message,\n choices: options.choices,\n })\n}\n\nexport interface InputOptions {\n message: string\n default?: string\n validate?: (value: string) => boolean | string\n}\n\nexport async function getInput(options: InputOptions): Promise<string> {\n const inputConfig: {\n message: string\n default?: string\n validate?: (value: string) => boolean | string\n } = {\n message: options.message,\n }\n\n if (options.default !== undefined) {\n inputConfig.default = options.default\n }\n\n if (options.validate !== undefined) {\n inputConfig.validate = options.validate\n }\n\n return input(inputConfig)\n}\n","/**\n * Standard exit codes for the attest-it CLI.\n *\n * These codes follow Unix conventions and provide consistent error reporting\n * across all CLI commands.\n *\n * @packageDocumentation\n */\n\n/**\n * Standard exit codes for the attest-it CLI.\n * @public\n */\nexport const ExitCode = {\n /** Operation completed successfully */\n SUCCESS: 0,\n /** Tests failed or attestation invalid */\n FAILURE: 1,\n /** Configuration or validation error */\n CONFIG_ERROR: 2,\n /** User cancelled the operation */\n CANCELLED: 3,\n /** Missing required key file */\n MISSING_KEY: 4,\n} as const\n\n/**\n * Type representing all possible exit codes.\n * @public\n */\nexport type ExitCode = (typeof ExitCode)[keyof typeof ExitCode]\n","import { Command } from 'commander'\nimport * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport YAML from 'yaml'\nimport { log, success, error, info } from '../utils/output.js'\nimport { confirmAction, getInput, selectOption } from '../utils/prompts.js'\nimport { ExitCode } from '../utils/exit-codes.js'\n\nexport const initCommand = new Command('init')\n .description('Initialize attest-it configuration')\n .option('-p, --path <path>', 'Config file path', '.attest-it/config.yaml')\n .option('-f, --force', 'Overwrite existing config')\n .option('--json', 'Output JSON instead of YAML')\n .action(async (options: InitOptions) => {\n await runInit(options)\n })\n\ninterface InitOptions {\n path: string\n force?: boolean\n json?: boolean\n}\n\ninterface SuiteInput {\n name: string\n description: string\n packages: string[]\n command: string\n}\n\ninterface ConfigSuite {\n description?: string\n packages: string[]\n command: string\n}\n\ninterface Config {\n version: number\n settings: {\n maxAgeDays: number\n publicKeyPath: string\n attestationsPath: string\n algorithm: string\n }\n suites: Record<string, ConfigSuite>\n}\n\n/**\n * Run the init command to create a new attest-it configuration.\n *\n * Interactively prompts the user for settings and suite configurations,\n * then creates a configuration file in the specified location.\n *\n * @param options - Command options\n * @param options.path - Config file path (default: .attest-it/config.yaml)\n * @param options.force - Overwrite existing config without prompting\n * @param options.json - Output JSON instead of YAML\n * @public\n */\nasync function runInit(options: InitOptions): Promise<void> {\n try {\n // Check if config already exists\n const configPath = path.resolve(options.path)\n const configDir = path.dirname(configPath)\n\n if (fs.existsSync(configPath) && !options.force) {\n const overwrite = await confirmAction({\n message: `Config already exists at ${configPath}. Overwrite?`,\n default: false,\n })\n if (!overwrite) {\n error('Init cancelled')\n process.exit(ExitCode.CANCELLED)\n }\n }\n\n log('')\n info('Welcome to attest-it!')\n log('This will create a configuration file for human-gated test attestations.')\n log('')\n\n // Gather settings\n const maxAgeDays = await getInput({\n message: 'Maximum attestation age (days):',\n default: '30',\n validate: (v) => {\n const n = parseInt(v, 10)\n return !isNaN(n) && n > 0 ? true : 'Must be a positive number'\n },\n })\n\n const algorithm = await selectOption({\n message: 'Signing algorithm:',\n choices: [\n {\n value: 'ed25519',\n name: 'Ed25519 (Recommended)',\n description: 'Fast, modern, secure',\n },\n { value: 'rsa', name: 'RSA', description: 'Broader compatibility' },\n ],\n })\n\n // Gather suites\n const suites: SuiteInput[] = []\n let addMore = true\n\n log('')\n info('Now configure your test suites.')\n log('Suites are groups of tests that require human verification.')\n log('')\n\n while (addMore) {\n const suiteName = await getInput({\n message: 'Suite name:',\n validate: (v) => (v.length > 0 ? true : 'Required'),\n })\n\n const description = await getInput({\n message: 'Description (optional):',\n })\n\n const packagesInput = await getInput({\n message: 'Package paths (comma-separated):',\n default: `packages/${suiteName}`,\n validate: (v) => (v.length > 0 ? true : 'At least one package required'),\n })\n\n const command = await getInput({\n message: 'Test command:',\n default: `pnpm vitest ${packagesInput.split(',')[0]?.trim() ?? ''}`,\n })\n\n suites.push({\n name: suiteName,\n description,\n packages: packagesInput\n .split(',')\n .map((p) => p.trim())\n .filter(Boolean),\n command,\n })\n\n addMore = await confirmAction({\n message: 'Add another suite?',\n default: false,\n })\n }\n\n if (suites.length === 0) {\n error('At least one suite is required')\n process.exit(ExitCode.CONFIG_ERROR)\n }\n\n // Build config object\n const config: Config = {\n version: 1,\n settings: {\n maxAgeDays: parseInt(maxAgeDays, 10),\n publicKeyPath: '.attest-it/pubkey.pem',\n attestationsPath: '.attest-it/attestations.json',\n algorithm,\n },\n suites: Object.fromEntries(\n suites.map((s) => {\n const suite: ConfigSuite = {\n packages: s.packages,\n command: s.command,\n }\n // Only add description if it's not empty\n if (s.description) {\n suite.description = s.description\n }\n return [s.name, suite]\n }),\n ),\n }\n\n // Create directory\n await fs.promises.mkdir(configDir, { recursive: true })\n\n // Write config\n const content = options.json\n ? JSON.stringify(config, null, 2)\n : YAML.stringify(config, { indent: 2 })\n\n await fs.promises.writeFile(configPath, content, 'utf-8')\n\n // Create .gitkeep for attestations directory\n const attestDir = path.dirname(\n path.resolve(path.dirname(configPath), config.settings.attestationsPath),\n )\n await fs.promises.mkdir(attestDir, { recursive: true })\n\n success(`Configuration created at ${configPath}`)\n log('')\n log('Next steps:')\n log(' 1. Review and edit the configuration as needed')\n log(' 2. Run: attest-it keygen')\n log(' 3. Run: attest-it run --suite <suite-name>')\n log(' 4. Commit the attestation file')\n } catch (err) {\n if (err instanceof Error) {\n error(err.message)\n } else {\n error('Unknown error occurred')\n }\n process.exit(ExitCode.CONFIG_ERROR)\n }\n}\n\nexport { runInit }\n","import { Command } from 'commander'\nimport {\n loadConfig,\n computeFingerprint,\n readAttestations,\n findAttestation,\n type VerificationStatus,\n type AttestationsFile,\n type Attestation,\n} from '@attest-it/core'\nimport {\n log,\n success,\n error,\n formatTable,\n colorizeStatus,\n outputJson,\n type TableRow,\n} from '../utils/output.js'\nimport { ExitCode } from '../utils/exit-codes.js'\n\nexport const statusCommand = new Command('status')\n .description('Show attestation status for all suites')\n .option('-s, --suite <name>', 'Show status for specific suite only')\n .option('--json', 'Output JSON for machine parsing')\n .action(async (options: StatusOptions) => {\n await runStatus(options)\n })\n\ninterface StatusOptions {\n suite?: string\n json?: boolean\n}\n\ninterface SuiteStatus {\n name: string\n status: VerificationStatus\n currentFingerprint: string\n attestedFingerprint?: string | undefined\n attestedAt?: string | undefined\n age?: number | undefined\n}\n\n/**\n * Run the status command to show attestation status.\n *\n * Displays the current status of attestations for all suites or a specific suite,\n * including validation status, fingerprints, and age information.\n *\n * @param options - Command options\n * @param options.suite - Show status for specific suite only\n * @param options.json - Output JSON for machine parsing\n * @public\n */\nasync function runStatus(options: StatusOptions): Promise<void> {\n try {\n // Load config\n const config = await loadConfig()\n\n // Load attestations (may not exist)\n const attestationsPath = config.settings.attestationsPath\n let attestationsFile: AttestationsFile | null = null\n try {\n attestationsFile = await readAttestations(attestationsPath)\n } catch (err) {\n // Attestations file may not exist yet - that's okay\n if (err instanceof Error && !err.message.includes('ENOENT')) {\n throw err\n }\n }\n const attestations = attestationsFile?.attestations ?? []\n\n // Get suites to check\n const suiteNames = options.suite ? [options.suite] : Object.keys(config.suites)\n\n // Validate suite exists\n if (options.suite && !config.suites[options.suite]) {\n error(`Suite \"${options.suite}\" not found in config`)\n process.exit(ExitCode.CONFIG_ERROR)\n }\n\n // Check each suite\n const results: SuiteStatus[] = []\n let hasInvalid = false\n\n for (const suiteName of suiteNames) {\n // eslint-disable-next-line security/detect-object-injection\n const suiteConfig = config.suites[suiteName]\n if (!suiteConfig) continue\n\n // Compute current fingerprint\n const fingerprintResult = await computeFingerprint({\n packages: suiteConfig.packages,\n ...(suiteConfig.ignore && { ignore: suiteConfig.ignore }),\n })\n\n // Find existing attestation\n const attestation = findAttestation(\n {\n schemaVersion: '1',\n attestations,\n signature: '',\n },\n suiteName,\n )\n\n // Determine status\n const status = determineStatus(\n attestation ?? null,\n fingerprintResult.fingerprint,\n config.settings.maxAgeDays,\n )\n\n // Calculate age if attestation exists\n let age: number | undefined\n if (attestation) {\n const attestedAt = new Date(attestation.attestedAt)\n age = Math.floor((Date.now() - attestedAt.getTime()) / (1000 * 60 * 60 * 24))\n }\n\n if (status !== 'VALID') {\n hasInvalid = true\n }\n\n results.push({\n name: suiteName,\n status,\n currentFingerprint: fingerprintResult.fingerprint,\n attestedFingerprint: attestation?.fingerprint,\n attestedAt: attestation?.attestedAt,\n age,\n })\n }\n\n // Output results\n if (options.json) {\n outputJson(results)\n } else {\n displayStatusTable(results, hasInvalid)\n }\n\n process.exit(hasInvalid ? ExitCode.FAILURE : ExitCode.SUCCESS)\n } catch (err) {\n if (err instanceof Error) {\n error(err.message)\n } else {\n error('Unknown error occurred')\n }\n process.exit(ExitCode.CONFIG_ERROR)\n }\n}\n\nfunction determineStatus(\n attestation: Attestation | null,\n currentFingerprint: string,\n maxAgeDays: number,\n): VerificationStatus {\n if (!attestation) {\n return 'NEEDS_ATTESTATION'\n }\n\n if (attestation.fingerprint !== currentFingerprint) {\n return 'FINGERPRINT_CHANGED'\n }\n\n const attestedAt = new Date(attestation.attestedAt)\n const ageInDays = Math.floor((Date.now() - attestedAt.getTime()) / (1000 * 60 * 60 * 24))\n\n if (ageInDays > maxAgeDays) {\n return 'EXPIRED'\n }\n\n return 'VALID'\n}\n\nfunction displayStatusTable(results: SuiteStatus[], hasInvalid: boolean): void {\n const tableRows: TableRow[] = results.map((r) => ({\n suite: r.name,\n status: colorizeStatus(r.status),\n fingerprint: r.currentFingerprint.slice(0, 16) + '...',\n age: formatAge(r),\n }))\n\n log('')\n log(formatTable(tableRows))\n log('')\n\n if (hasInvalid) {\n log('Run `attest-it run --suite <name>` to update attestations')\n } else {\n success('All attestations valid')\n }\n}\n\nfunction formatAge(result: SuiteStatus): string {\n if (result.status === 'VALID') {\n return `${String(result.age ?? 0)} days`\n }\n\n if (result.status === 'FINGERPRINT_CHANGED') {\n return '(changed)'\n }\n\n if (result.status === 'NEEDS_ATTESTATION') {\n return '(none)'\n }\n\n if (result.status === 'EXPIRED') {\n return `${String(result.age ?? 0)} days (expired)`\n }\n\n return '-'\n}\n\nexport { runStatus }\n","/**\n * Run command implementation for attest-it CLI.\n */\n\nimport { Command } from 'commander'\nimport { spawn } from 'node:child_process'\nimport * as fs from 'node:fs'\nimport * as os from 'node:os'\nimport { parse as parseShellCommand } from 'shell-quote'\nimport {\n loadConfig,\n computeFingerprint,\n readAttestations,\n writeSignedAttestations,\n upsertAttestation,\n createAttestation,\n getDefaultPrivateKeyPath,\n type Config,\n} from '@attest-it/core'\nimport { log, success, error, warn, verbose } from '../utils/output.js'\nimport { confirmAction } from '../utils/prompts.js'\nimport { ExitCode } from '../utils/exit-codes.js'\n\nexport const runCommand = new Command('run')\n .description('Execute tests and create attestation')\n .option('-s, --suite <name>', 'Run specific suite (required unless --all)')\n .option('-a, --all', 'Run all suites needing attestation')\n .option('--no-attest', 'Run tests without creating attestation')\n .option('-y, --yes', 'Skip confirmation prompt')\n .action(async (options: RunOptions) => {\n await runTests(options)\n })\n\ninterface RunOptions {\n suite?: string\n all?: boolean\n attest?: boolean // Note: --no-attest sets this to false\n yes?: boolean\n}\n\n/**\n * Run tests and create attestations.\n *\n * Executes test commands for specified suite(s), computes fingerprints,\n * and creates signed attestations upon successful test completion.\n *\n * @param options - Command options\n * @param options.suite - Run specific suite (required unless --all)\n * @param options.all - Run all suites needing attestation\n * @param options.attest - Create attestation after tests (default: true)\n * @param options.yes - Skip confirmation prompt\n * @public\n */\nasync function runTests(options: RunOptions): Promise<void> {\n try {\n // Validate options\n if (!options.suite && !options.all) {\n error('Either --suite or --all is required')\n process.exit(ExitCode.CONFIG_ERROR)\n }\n\n // Load config\n const config = await loadConfig()\n\n // Determine which suites to run\n const suitesToRun = options.all\n ? Object.keys(config.suites)\n : options.suite\n ? [options.suite]\n : []\n\n // Validate suite exists\n if (options.suite && !config.suites[options.suite]) {\n error(`Suite \"${options.suite}\" not found in config`)\n process.exit(ExitCode.CONFIG_ERROR)\n }\n\n // Check for dirty working tree\n const isDirty = await checkDirtyWorkingTree()\n if (isDirty) {\n error('Working tree has uncommitted changes. Please commit or stash before attesting.')\n process.exit(ExitCode.CONFIG_ERROR)\n }\n\n // Process each suite\n for (const suiteName of suitesToRun) {\n // eslint-disable-next-line security/detect-object-injection -- suiteName is from validated config keys\n const suiteConfig = config.suites[suiteName]\n if (!suiteConfig) continue\n\n log(`\\n=== Running suite: ${suiteName} ===\\n`)\n\n // Compute fingerprint before running\n const fingerprintOptions = {\n packages: suiteConfig.packages,\n ...(suiteConfig.ignore && { ignore: suiteConfig.ignore }),\n }\n const fingerprintResult = await computeFingerprint(fingerprintOptions)\n verbose(`Fingerprint: ${fingerprintResult.fingerprint}`)\n verbose(`Files: ${String(fingerprintResult.fileCount)}`)\n\n // Build the test command\n const command = buildCommand(config, suiteConfig.command, suiteConfig.files)\n log(`Running: ${command}`)\n log('')\n\n // Execute tests\n const exitCode = await executeCommand(command)\n\n if (exitCode !== 0) {\n error(`Tests failed with exit code ${String(exitCode)}`)\n process.exit(ExitCode.FAILURE)\n }\n\n success('Tests passed!')\n\n // Skip attestation if --no-attest\n if (options.attest === false) {\n log('Skipping attestation (--no-attest)')\n continue\n }\n\n // Confirm attestation\n const shouldAttest =\n options.yes ??\n (await confirmAction({\n message: 'Create attestation?',\n default: true,\n }))\n\n if (!shouldAttest) {\n warn('Attestation cancelled')\n process.exit(ExitCode.CANCELLED)\n }\n\n // Create attestation\n const attestation = createAttestation({\n suite: suiteName,\n fingerprint: fingerprintResult.fingerprint,\n command,\n attestedBy: os.userInfo().username,\n })\n\n // Load existing attestations\n const attestationsPath = config.settings.attestationsPath\n const existingFile = await readAttestations(attestationsPath)\n const existingAttestations = existingFile?.attestations ?? []\n\n // Upsert the new attestation\n const newAttestations = upsertAttestation(existingAttestations, attestation)\n\n // Get private key path (from config or default)\n const privateKeyPath = getDefaultPrivateKeyPath()\n\n // Check if private key exists\n if (!fs.existsSync(privateKeyPath)) {\n error(`Private key not found: ${privateKeyPath}`)\n error('Run \"attest-it keygen\" first to generate a keypair.')\n process.exit(ExitCode.MISSING_KEY)\n }\n\n // Write signed attestations\n await writeSignedAttestations({\n filePath: attestationsPath,\n attestations: newAttestations,\n privateKeyPath,\n })\n\n success(`Attestation created for ${suiteName}`)\n log(` Fingerprint: ${fingerprintResult.fingerprint}`)\n log(` Attested by: ${attestation.attestedBy}`)\n log(` Attested at: ${attestation.attestedAt}`)\n }\n\n log('')\n success('All suites completed!')\n log(\n `\\nTo commit: git add ${config.settings.attestationsPath} && git commit -m \"Update attestations\"`,\n )\n } catch (err) {\n if (err instanceof Error) {\n error(err.message)\n } else {\n error('Unknown error occurred')\n }\n process.exit(ExitCode.CONFIG_ERROR)\n }\n}\n\n/**\n * Build the test command to execute.\n *\n * Uses suite-specific command if provided, otherwise falls back to\n * default command from settings. Substitutes ${files} placeholder\n * with suite file patterns.\n *\n * @param config - Configuration object\n * @param suiteCommand - Suite-specific command (optional)\n * @param suiteFiles - File patterns for suite (optional)\n * @returns Constructed command string\n * @public\n */\nfunction buildCommand(config: Config, suiteCommand?: string, suiteFiles?: string[]): string {\n // Use suite command if specified, otherwise default\n let command = suiteCommand ?? config.settings.defaultCommand\n\n if (!command) {\n error('No command specified for suite and no defaultCommand in settings')\n process.exit(ExitCode.CONFIG_ERROR)\n }\n\n // Substitute ${files} if present (replace all occurrences)\n if (command.includes('${files}') && suiteFiles) {\n const files = suiteFiles.join(' ')\n command = command.replaceAll('${files}', files)\n }\n\n return command\n}\n\n/**\n * Parsed command result.\n */\ninterface ParsedCommand {\n executable: string\n args: string[]\n}\n\n/**\n * Parse a command string into executable and arguments.\n *\n * Uses shell-quote to safely parse shell syntax without using shell: true.\n *\n * @param command - Command string to parse\n * @returns Parsed command with executable and arguments\n * @throws Error if command is empty or contains only control operators\n * @public\n */\nfunction parseCommand(command: string): ParsedCommand {\n const parsed = parseShellCommand(command)\n\n // shell-quote returns an array of strings and special control operators\n // We only want the string arguments\n const stringArgs = parsed.filter((token): token is string => {\n return typeof token === 'string'\n })\n\n if (stringArgs.length === 0) {\n throw new Error('Command string is empty or contains only control operators')\n }\n\n const [executable, ...args] = stringArgs\n // TypeScript doesn't know that stringArgs.length > 0 guarantees executable is defined\n // The check above ensures stringArgs[0] exists, but we assert it for type safety\n if (executable === undefined) {\n throw new Error('Command string is empty or contains only control operators')\n }\n\n return { executable, args }\n}\n\n/**\n * Execute a command and return its exit code.\n *\n * Spawns a child process and streams output to the terminal.\n *\n * @param command - Command string to execute\n * @returns Exit code from the command (0 for success)\n * @public\n */\nasync function executeCommand(command: string): Promise<number> {\n return new Promise((resolve) => {\n let parsed: ParsedCommand\n try {\n parsed = parseCommand(command)\n } catch (err) {\n if (err instanceof Error) {\n error(`Failed to parse command: ${err.message}`)\n } else {\n error('Failed to parse command: Unknown error')\n }\n resolve(1)\n return\n }\n\n const child = spawn(parsed.executable, parsed.args, {\n stdio: 'inherit', // Stream output to terminal\n })\n\n child.on('close', (code) => {\n resolve(code ?? 1)\n })\n\n child.on('error', (err) => {\n error(`Failed to execute command: ${err.message}`)\n resolve(1)\n })\n })\n}\n\n/**\n * Check if the git working tree has uncommitted changes.\n *\n * @returns True if there are uncommitted changes, false otherwise\n * @public\n */\nasync function checkDirtyWorkingTree(): Promise<boolean> {\n return new Promise((resolve) => {\n const child = spawn('git', ['status', '--porcelain'], {\n stdio: ['ignore', 'pipe', 'pipe'],\n })\n\n let output = ''\n child.stdout.on('data', (data: Buffer) => {\n output += data.toString()\n })\n\n child.on('close', () => {\n // If output is non-empty, there are uncommitted changes\n resolve(output.trim().length > 0)\n })\n\n child.on('error', () => {\n // If git not available, assume not dirty\n resolve(false)\n })\n })\n}\n\n// Export for testing\nexport { buildCommand, parseCommand, executeCommand, checkDirtyWorkingTree }\n","import { Command } from 'commander'\nimport * as fs from 'node:fs'\nimport {\n checkOpenSSL,\n generateKeyPair,\n getDefaultPrivateKeyPath,\n getDefaultPublicKeyPath,\n setKeyPermissions,\n type Algorithm,\n} from '@attest-it/core'\nimport { log, success, error, warn, info } from '../utils/output.js'\nimport { confirmAction } from '../utils/prompts.js'\nimport { ExitCode } from '../utils/exit-codes.js'\n\nexport const keygenCommand = new Command('keygen')\n .description('Generate a new keypair for signing attestations')\n .option('-a, --algorithm <alg>', 'Algorithm: ed25519 (default) or rsa', 'ed25519')\n .option('-o, --output <path>', 'Private key output path')\n .option('-p, --public <path>', 'Public key output path')\n .option('-f, --force', 'Overwrite existing keys')\n .action(async (options: KeygenOptions) => {\n await runKeygen(options)\n })\n\ninterface KeygenOptions {\n algorithm: string\n output?: string\n public?: string\n force?: boolean\n}\n\n/**\n * Run the keygen command to generate a new cryptographic keypair.\n *\n * Checks for OpenSSL availability, generates a keypair using the specified\n * algorithm, and sets appropriate permissions on the private key.\n *\n * @param options - Command options\n * @param options.algorithm - Signing algorithm (ed25519 or rsa)\n * @param options.output - Private key output path\n * @param options.public - Public key output path\n * @param options.force - Overwrite existing keys without prompting\n * @public\n */\nasync function runKeygen(options: KeygenOptions): Promise<void> {\n try {\n // Validate algorithm\n const algorithm = validateAlgorithm(options.algorithm)\n\n // Check OpenSSL\n log('Checking OpenSSL...')\n const version = await checkOpenSSL()\n info(`OpenSSL: ${version}`)\n\n // Determine paths\n const privatePath = options.output ?? getDefaultPrivateKeyPath()\n const publicPath = options.public ?? getDefaultPublicKeyPath()\n\n log(`Private key: ${privatePath}`)\n log(`Public key: ${publicPath}`)\n\n // Check if keys already exist\n const privateExists = fs.existsSync(privatePath)\n const publicExists = fs.existsSync(publicPath)\n\n if ((privateExists || publicExists) && !options.force) {\n if (privateExists) {\n warn(`Private key already exists: ${privatePath}`)\n }\n if (publicExists) {\n warn(`Public key already exists: ${publicPath}`)\n }\n\n const shouldOverwrite = await confirmAction({\n message: 'Overwrite existing keys?',\n default: false,\n })\n\n if (!shouldOverwrite) {\n error('Keygen cancelled')\n process.exit(ExitCode.CANCELLED)\n }\n }\n\n // Generate keypair\n log(`\\nGenerating ${algorithm.toUpperCase()} keypair...`)\n\n const result = await generateKeyPair({\n algorithm,\n privatePath,\n publicPath,\n force: true,\n })\n\n // Set permissions on private key\n await setKeyPermissions(result.privatePath)\n\n success('Keypair generated successfully!')\n log('')\n log('Private key (KEEP SECRET):')\n log(` ${result.privatePath}`)\n log('')\n log('Public key (commit to repo):')\n log(` ${result.publicPath}`)\n log('')\n info('Important: Back up your private key securely!')\n log('')\n log('Next steps:')\n log(` 1. git add ${result.publicPath}`)\n log(' 2. Update .attest-it/config.yaml publicKeyPath if needed')\n log(' 3. attest-it run --suite <suite-name>')\n } catch (err) {\n if (err instanceof Error) {\n error(err.message)\n } else {\n error('Unknown error occurred')\n }\n process.exit(ExitCode.CONFIG_ERROR)\n }\n}\n\n/**\n * Validate and normalize the algorithm string.\n *\n * @param alg - Algorithm string to validate (case-insensitive)\n * @returns Normalized algorithm name ('ed25519' or 'rsa')\n * @throws Exits process with error if algorithm is invalid\n * @public\n */\nfunction validateAlgorithm(alg: string): Algorithm {\n const normalized = alg.toLowerCase()\n if (normalized === 'ed25519' || normalized === 'rsa') {\n return normalized\n }\n error(`Invalid algorithm: ${alg}. Use 'ed25519' or 'rsa'.`)\n process.exit(ExitCode.CONFIG_ERROR)\n}\n\nexport { runKeygen, validateAlgorithm }\n","/**\n * Prune command implementation for attest-it CLI.\n */\n\nimport { Command } from 'commander'\nimport * as fs from 'node:fs'\nimport {\n loadConfig,\n readAttestations,\n writeSignedAttestations,\n computeFingerprint,\n getDefaultPrivateKeyPath,\n type Attestation,\n} from '@attest-it/core'\nimport { log, success, error, info, verbose } from '../utils/output.js'\nimport { ExitCode } from '../utils/exit-codes.js'\n\nexport const pruneCommand = new Command('prune')\n .description('Remove stale attestations')\n .option('-n, --dry-run', 'Show what would be removed without removing')\n .option('-k, --keep-days <n>', 'Keep attestations newer than n days', '30')\n .action(async (options: PruneOptions) => {\n await runPrune(options)\n })\n\ninterface PruneOptions {\n dryRun?: boolean\n keepDays: string\n}\n\n/**\n * Run the prune command to remove stale attestations.\n *\n * Removes attestations that are outdated (older than keepDays and\n * fingerprint doesn't match current code) or orphaned (suite no\n * longer exists in config). Re-signs the attestations file.\n *\n * @param options - Command options\n * @param options.dryRun - Show what would be removed without removing\n * @param options.keepDays - Keep attestations newer than n days\n * @public\n */\nasync function runPrune(options: PruneOptions): Promise<void> {\n try {\n const keepDays = parseInt(options.keepDays, 10)\n if (isNaN(keepDays) || keepDays < 1) {\n error('--keep-days must be a positive integer')\n process.exit(ExitCode.CONFIG_ERROR)\n return\n }\n\n // Load config\n const config = await loadConfig()\n\n // Load attestations\n const attestationsPath = config.settings.attestationsPath\n const file = await readAttestations(attestationsPath)\n\n if (!file || file.attestations.length === 0) {\n info('No attestations to prune')\n process.exit(ExitCode.SUCCESS)\n return\n }\n\n const now = Date.now()\n const keepMs = keepDays * 24 * 60 * 60 * 1000\n\n // Identify stale attestations\n const stale: Attestation[] = []\n const keep: Attestation[] = []\n\n for (const attestation of file.attestations) {\n const attestedAt = new Date(attestation.attestedAt).getTime()\n const ageMs = now - attestedAt\n const ageDays = Math.floor(ageMs / (1000 * 60 * 60 * 24))\n\n // Check if suite still exists in config\n const suiteExists = attestation.suite in config.suites\n\n // Check if fingerprint still matches current code\n let fingerprintMatches = false\n if (suiteExists) {\n const suiteConfig = config.suites[attestation.suite]\n if (suiteConfig) {\n const fingerprintOptions = {\n packages: suiteConfig.packages,\n ...(suiteConfig.ignore && { ignore: suiteConfig.ignore }),\n }\n const result = await computeFingerprint(fingerprintOptions)\n fingerprintMatches = result.fingerprint === attestation.fingerprint\n }\n }\n\n // Keep if:\n // 1. Age is within keepDays AND fingerprint matches, OR\n // 2. Fingerprint matches current code (regardless of age)\n const isStale = !fingerprintMatches && ageMs > keepMs\n const orphaned = !suiteExists\n\n if (isStale || orphaned) {\n stale.push(attestation)\n const reason = orphaned\n ? 'suite removed'\n : !fingerprintMatches\n ? 'fingerprint changed'\n : 'expired'\n verbose(`Stale: ${attestation.suite} (${reason}, ${String(ageDays)} days old)`)\n } else {\n keep.push(attestation)\n }\n }\n\n // Report what will be pruned\n if (stale.length === 0) {\n success('No stale attestations found')\n process.exit(ExitCode.SUCCESS)\n return\n }\n\n log(`Found ${String(stale.length)} stale attestation(s):`)\n for (const attestation of stale) {\n const ageDays = Math.floor(\n (now - new Date(attestation.attestedAt).getTime()) / (1000 * 60 * 60 * 24),\n )\n log(` - ${attestation.suite} (${String(ageDays)} days old)`)\n }\n\n if (options.dryRun) {\n info('Dry run - no changes made')\n process.exit(ExitCode.SUCCESS)\n return\n }\n\n // Check for private key\n const privateKeyPath = getDefaultPrivateKeyPath()\n if (!fs.existsSync(privateKeyPath)) {\n error(`Private key not found: ${privateKeyPath}`)\n error('Cannot re-sign attestations file.')\n process.exit(ExitCode.MISSING_KEY)\n return\n }\n\n // Write updated attestations\n await writeSignedAttestations({\n filePath: attestationsPath,\n attestations: keep,\n privateKeyPath,\n })\n\n success(`Pruned ${String(stale.length)} stale attestation(s)`)\n log(`Remaining: ${String(keep.length)} attestation(s)`)\n process.exit(ExitCode.SUCCESS)\n } catch (err) {\n if (err instanceof Error) {\n error(err.message)\n } else {\n error('Unknown error occurred')\n }\n process.exit(2)\n return\n }\n}\n\nexport { runPrune }\n","import { Command } from 'commander'\nimport {\n loadConfig,\n toAttestItConfig,\n verifyAttestations,\n type Config,\n type VerifyResult,\n type SuiteVerificationResult,\n} from '@attest-it/core'\nimport {\n log,\n success,\n error,\n warn,\n formatTable,\n colorizeStatus,\n outputJson,\n type TableRow,\n} from '../utils/output.js'\nimport { ExitCode } from '../utils/exit-codes.js'\n\nexport const verifyCommand = new Command('verify')\n .description('Verify all attestations (for CI)')\n .option('-s, --suite <name>', 'Verify specific suite only')\n .option('--json', 'Output JSON for machine parsing')\n .option('--strict', 'Fail on warnings (approaching expiry)')\n .action(async (options: VerifyOptions) => {\n await runVerify(options)\n })\n\ninterface VerifyOptions {\n suite?: string\n json?: boolean\n strict?: boolean\n}\n\n/**\n * Run the verify command to validate attestations.\n *\n * Verifies signature validity and checks attestation status for all suites\n * or a specific suite. Intended for CI/CD pipelines.\n *\n * @param options - Command options\n * @param options.suite - Verify specific suite only\n * @param options.json - Output JSON for machine parsing\n * @param options.strict - Fail on warnings (approaching expiry)\n * @public\n */\nasync function runVerify(options: VerifyOptions): Promise<void> {\n try {\n // Load config\n const config = await loadConfig()\n\n // Filter to specific suite if requested\n if (options.suite) {\n if (!config.suites[options.suite]) {\n error(`Suite \"${options.suite}\" not found in config`)\n process.exit(ExitCode.CONFIG_ERROR)\n }\n // Create filtered config\n const filteredSuiteEntry = config.suites[options.suite]\n if (!filteredSuiteEntry) {\n error(`Suite \"${options.suite}\" not found in config`)\n process.exit(ExitCode.CONFIG_ERROR)\n }\n const filteredConfig: Config = {\n version: config.version,\n settings: config.settings,\n suites: { [options.suite]: filteredSuiteEntry },\n }\n\n // Run verification with filtered config, converting from Zod Config to AttestItConfig\n const result = await verifyAttestations({ config: toAttestItConfig(filteredConfig) })\n\n // Output results\n if (options.json) {\n outputJson(result)\n } else {\n displayResults(result, filteredConfig.settings.maxAgeDays, options.strict)\n }\n\n // Determine exit code\n if (!result.success) {\n process.exit(ExitCode.FAILURE)\n return\n }\n\n if (options.strict && hasWarnings(result, filteredConfig.settings.maxAgeDays)) {\n process.exit(ExitCode.FAILURE)\n return\n }\n\n process.exit(ExitCode.SUCCESS)\n return\n }\n\n // Run verification with full config, converting from Zod Config to AttestItConfig\n const result = await verifyAttestations({ config: toAttestItConfig(config) })\n\n // Output results\n if (options.json) {\n outputJson(result)\n } else {\n displayResults(result, config.settings.maxAgeDays, options.strict)\n }\n\n // Determine exit code\n if (!result.success) {\n process.exit(ExitCode.FAILURE)\n }\n\n if (options.strict && hasWarnings(result, config.settings.maxAgeDays)) {\n process.exit(ExitCode.FAILURE)\n }\n\n process.exit(ExitCode.SUCCESS)\n } catch (err) {\n if (err instanceof Error) {\n error(err.message)\n } else {\n error('Unknown error occurred')\n }\n process.exit(2)\n }\n}\n\n/**\n * Display verification results in a formatted table.\n *\n * Shows signature status, errors, suite results, and remediation steps.\n *\n * @param result - Verification result from verifyAttestations\n * @param maxAgeDays - Maximum age in days before expiry\n * @param strict - Whether to show warnings as errors\n * @public\n */\nfunction displayResults(result: VerifyResult, maxAgeDays: number, strict?: boolean): void {\n log('')\n\n // Signature status\n if (!result.signatureValid) {\n error('Signature verification FAILED')\n log('The attestations file may have been tampered with.')\n log('')\n }\n\n // Errors\n for (const errorMsg of result.errors) {\n error(errorMsg)\n }\n if (result.errors.length > 0) {\n log('')\n }\n\n // Suite results as table\n const tableRows: TableRow[] = result.suites.map((s) => ({\n suite: s.suite,\n status: colorizeStatus(s.status),\n fingerprint: s.fingerprint.slice(0, 16) + '...',\n age: formatAgeColumn(s),\n }))\n\n log(formatTable(tableRows))\n log('')\n\n // Summary\n if (result.success) {\n success('All attestations valid')\n } else {\n // Show remediation steps\n const needsAttestation = result.suites.filter((s) => s.status !== 'VALID')\n\n if (needsAttestation.length > 0) {\n log('Remediation:')\n for (const suite of needsAttestation) {\n log(` attest-it run --suite ${suite.suite}`)\n if (suite.message) {\n log(` ${suite.message}`)\n }\n }\n }\n }\n\n // Warnings (approaching expiry)\n const warningThreshold = 7 // days before expiry to warn\n const nearExpiry = result.suites.filter(\n (s) => s.status === 'VALID' && (s.age ?? 0) > maxAgeDays - warningThreshold,\n )\n\n if (nearExpiry.length > 0) {\n log('')\n for (const suite of nearExpiry) {\n warn(`${suite.suite} attestation approaching expiry (${String(suite.age)} days old)`)\n }\n if (strict) {\n log('(--strict mode: warnings are treated as errors)')\n }\n }\n}\n\nfunction formatAgeColumn(s: SuiteVerificationResult): string {\n if (s.status === 'VALID') {\n return `${String(s.age ?? 0)} days`\n }\n\n if (s.status === 'NEEDS_ATTESTATION') {\n return '(none)'\n }\n\n if (s.status === 'EXPIRED') {\n return `${String(s.age ?? 0)} days (expired)`\n }\n\n if (s.status === 'FINGERPRINT_CHANGED') {\n return '(changed)'\n }\n\n if (s.status === 'INVALIDATED_BY_PARENT') {\n return '(invalidated)'\n }\n\n return '-'\n}\n\n/**\n * Check if verification result has warnings.\n *\n * Returns true if any valid attestations are approaching expiry\n * (within 7 days of maxAgeDays).\n *\n * @param result - Verification result to check\n * @param maxAgeDays - Maximum age in days before expiry\n * @returns True if warnings exist, false otherwise\n * @public\n */\nfunction hasWarnings(result: VerifyResult, maxAgeDays: number): boolean {\n const warningThreshold = 7 // days before expiry to warn\n return result.suites.some(\n (s) => s.status === 'VALID' && (s.age ?? 0) > maxAgeDays - warningThreshold,\n )\n}\n\nexport { runVerify, displayResults, hasWarnings }\n","import { Command } from 'commander'\nimport { initCommand } from './commands/init.js'\nimport { statusCommand } from './commands/status.js'\nimport { runCommand } from './commands/run.js'\nimport { keygenCommand } from './commands/keygen.js'\nimport { pruneCommand } from './commands/prune.js'\nimport { verifyCommand } from './commands/verify.js'\nimport { setOutputOptions } from './utils/output.js'\n\nconst program = new Command()\n\nprogram\n .name('attest-it')\n .description('Human-gated test attestation system')\n .version('0.0.1')\n .option('-c, --config <path>', 'Path to config file')\n .option('-v, --verbose', 'Verbose output')\n .option('-q, --quiet', 'Minimal output')\n\n// Register commands\nprogram.addCommand(initCommand)\nprogram.addCommand(statusCommand)\nprogram.addCommand(runCommand)\nprogram.addCommand(keygenCommand)\nprogram.addCommand(pruneCommand)\nprogram.addCommand(verifyCommand)\n\nexport function run(): void {\n // Parse options and set global output options\n program.parse()\n const options = program.opts<{ verbose?: boolean; quiet?: boolean }>()\n\n const outputOptions: { verbose?: boolean; quiet?: boolean } = {}\n if (options.verbose !== undefined) {\n outputOptions.verbose = options.verbose\n }\n if (options.quiet !== undefined) {\n outputOptions.quiet = options.quiet\n }\n\n setOutputOptions(outputOptions)\n}\n\nexport { program }\n"]}
@@ -0,0 +1,6 @@
1
+ import { Command } from 'commander';
2
+
3
+ declare const program: Command;
4
+ declare function run(): void;
5
+
6
+ export { program, run };
@@ -0,0 +1,6 @@
1
+ import { Command } from 'commander';
2
+
3
+ declare const program: Command;
4
+ declare function run(): void;
5
+
6
+ export { program, run };