@andy2639/jest-context 1.0.4 → 1.0.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/CHANGELOG.md +11 -0
- package/dist/bin/console-context.cjs +99 -19
- package/dist/bin/console-context.cjs.map +1 -1
- package/dist/bin/console-context.mjs +2 -2
- package/dist/bin/coverage-context.cjs +100 -20
- package/dist/bin/coverage-context.cjs.map +1 -1
- package/dist/bin/coverage-context.mjs +2 -2
- package/dist/bin/jest-context-init.cjs +9 -7
- package/dist/bin/jest-context-init.cjs.map +1 -1
- package/dist/bin/jest-context-init.mjs +2 -2
- package/dist/bin/test-context.cjs +97 -17
- package/dist/bin/test-context.cjs.map +1 -1
- package/dist/bin/test-context.mjs +2 -2
- package/dist/{chunk-YIYGGZAF.mjs → chunk-4N7XPTHJ.mjs} +2 -2
- package/dist/{chunk-X72LRXXX.mjs → chunk-7F4YL67U.mjs} +2 -2
- package/dist/{chunk-PUB2BNCX.mjs → chunk-KGUQFDCB.mjs} +96 -16
- package/dist/chunk-KGUQFDCB.mjs.map +1 -0
- package/dist/{chunk-F2MVPD3S.mjs → chunk-UE2DJICK.mjs} +2 -2
- package/dist/{chunk-OIPQSWTX.mjs → chunk-YEVAAYN5.mjs} +2 -2
- package/dist/index.cjs +107 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +5 -5
- package/package.json +1 -1
- package/dist/chunk-PUB2BNCX.mjs.map +0 -1
- /package/dist/{chunk-YIYGGZAF.mjs.map → chunk-4N7XPTHJ.mjs.map} +0 -0
- /package/dist/{chunk-X72LRXXX.mjs.map → chunk-7F4YL67U.mjs.map} +0 -0
- /package/dist/{chunk-F2MVPD3S.mjs.map → chunk-UE2DJICK.mjs.map} +0 -0
- /package/dist/{chunk-OIPQSWTX.mjs.map → chunk-YEVAAYN5.mjs.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/constants.ts","../../src/core/platform.ts","../../src/core/exec.ts","../../src/core/git.ts","../../src/core/jest.ts","../../src/core/parsing.ts","../../src/core/export.ts","../../src/core/cli.ts","../../src/core/ui.ts","../../src/commands/test-context.ts","../../src/bin/test-context.ts"],"sourcesContent":["export const VALID_MODES = [\"--all\", \"--related\", \"--tests\"] as const;\n\nexport const VALID_EXPORT_FORMATS = [\"txt\", \"md\"] as const;\n\nexport const VALID_TEST_EXTENSIONS = /\\.(test|spec)\\.(ts|tsx|js|jsx)$/;\n\nexport const CONSOLE_LOG_TYPES = {\n ERROR: \"console.error\",\n WARN: \"console.warn\",\n LOG: \"console.log\",\n DEBUG: \"console.debug\",\n} as const;\n\nexport const JEST_PATTERNS = {\n FAIL_LINE: /^FAIL\\s+/,\n PASS_LINE: /^PASS\\s+/,\n TEST_FILE: /^(PASS|FAIL)\\s+(.+\\.(test|spec)\\.tsx?)/,\n COVERAGE_LINE:\n /^(.+?)\\s+\\|\\s+([\\d.]+)\\s+\\|\\s+([\\d.]+)\\s+\\|\\s+([\\d.]+)\\s+\\|\\s+([\\d.]+)(?:\\s+\\|\\s+(.+))?$/,\n BULLET_POINT: /^●\\s+/,\n CODE_LINE: /^>?\\s*\\d*\\s*\\|/,\n STACK_TRACE: /^\\s+at\\s+/,\n};\n","export function getPlatform(): NodeJS.Platform {\n return process.platform;\n}\n\nexport function isWindows(): boolean {\n return process.platform === \"win32\";\n}\n\nexport function isMac(): boolean {\n return process.platform === \"darwin\";\n}\n\nexport function isLinux(): boolean {\n return process.platform === \"linux\";\n}\n\nexport function resolveCommand(cmd: string): string {\n if (!isWindows()) return cmd;\n\n const windowsCommands: Record<string, string> = {\n git: \"git.exe\",\n node: \"node.exe\",\n npm: \"npm.cmd\",\n npx: \"npx.cmd\",\n yarn: \"yarn.cmd\",\n pnpm: \"pnpm.cmd\",\n };\n\n return windowsCommands[cmd] ?? cmd;\n}\n","import { spawn } from \"node:child_process\";\n\nimport { resolveCommand } from \"./platform\";\nimport type { ExecResult } from \"../types\";\n\nexport async function execCommand(\n cmd: string,\n args: string[] = [],\n options: { shell?: boolean; ignoreErrors?: boolean } = {}\n): Promise<ExecResult> {\n return new Promise((resolve, reject) => {\n const resolvedCmd = resolveCommand(cmd);\n const child = spawn(resolvedCmd, args, {\n shell: options.shell ?? false,\n });\n\n let stdout = \"\";\n let stderr = \"\";\n\n child.stdout?.on(\"data\", (d) => {\n stdout += d.toString();\n });\n\n child.stderr?.on(\"data\", (d) => {\n stderr += d.toString();\n });\n\n child.on(\"close\", (code) => {\n const result: ExecResult = {\n stdout,\n stderr,\n output: `${stdout}\\n${stderr}`,\n code,\n };\n\n if (code !== 0 && !options.ignoreErrors) {\n reject(new Error(`Command failed with code ${code}: ${cmd} ${args.join(\" \")}`));\n return;\n }\n\n resolve(result);\n });\n\n child.on(\"error\", (error) => {\n reject(new Error(`Failed to execute command: ${error.message}`));\n });\n });\n}\n","import { execCommand } from \"./exec\";\nimport { VALID_TEST_EXTENSIONS } from \"./constants\";\n\nlet cachedGitAvailability: boolean | null = null;\nlet cachedStagedFiles: string[] | null = null;\nlet cachedStagedFilesAt = 0;\nconst STAGED_FILES_CACHE_TTL_MS = 1000;\n\nexport async function hasGit(): Promise<boolean> {\n if (cachedGitAvailability !== null) {\n return cachedGitAvailability;\n }\n\n try {\n const result = await execCommand(\"git\", [\"--version\"], { ignoreErrors: true });\n cachedGitAvailability = result.code === 0;\n\n return cachedGitAvailability;\n } catch {\n cachedGitAvailability = false;\n\n return false;\n }\n}\n\nexport async function getStagedFiles(): Promise<string[]> {\n const now = Date.now();\n if (cachedStagedFiles && now - cachedStagedFilesAt <= STAGED_FILES_CACHE_TTL_MS) {\n return cachedStagedFiles;\n }\n\n const gitAvailable = await hasGit();\n if (!gitAvailable) {\n throw new Error(\"Git is not installed or not available in PATH\");\n }\n\n const result = await execCommand(\"git\", [\"diff\", \"--name-only\", \"--cached\"], {\n ignoreErrors: true,\n });\n\n const files = result.stdout\n .split(\"\\n\")\n .map((f) => f.trim())\n .filter(Boolean);\n\n cachedStagedFiles = files;\n cachedStagedFilesAt = now;\n\n return files;\n}\n\nexport function filterTestFiles(files: string[]): string[] {\n return files.filter((file) => VALID_TEST_EXTENSIONS.test(file));\n}\n","import { spawn } from \"node:child_process\";\n\nimport { isWindows } from \"./platform\";\nimport { filterTestFiles, getStagedFiles } from \"./git\";\nimport type { ExecutionMode, ExecResult, RunJestOptions } from \"../types\";\n\nfunction resolveJestBinPath(): string {\n try {\n return require.resolve(\"jest/bin/jest.js\", { paths: [process.cwd()] });\n } catch {\n throw new Error(\n \"Could not resolve Jest from the current project. Install `jest@^29` in this project (for example: `npm i -D jest@^29`, `pnpm add -D jest@^29`, or `yarn add -D jest@^29`).\"\n );\n }\n}\n\nexport async function runJest(args: string[] = [], options: RunJestOptions = {}): Promise<ExecResult> {\n const {\n verbose = false,\n coverage = false,\n ignoreErrors = true,\n disableVerbose = false,\n } = options;\n\n const jestBinPath = resolveJestBinPath();\n const command = process.execPath;\n const jestArgs = [jestBinPath];\n\n if (verbose && !disableVerbose) {\n jestArgs.push(\"--verbose\");\n }\n\n if (coverage) {\n jestArgs.push(\"--coverage\");\n\n if (options.coverageReporters) {\n for (const reporter of options.coverageReporters) {\n jestArgs.push(`--coverageReporters=${reporter}`);\n }\n }\n }\n\n if (isWindows()) {\n jestArgs.push(\"--no-watchman\");\n }\n\n jestArgs.push(...args);\n\n return new Promise((resolve, reject) => {\n const child = spawn(command, jestArgs, {\n shell: false,\n });\n\n let stdout = \"\";\n let stderr = \"\";\n\n child.stdout.on(\"data\", (d) => {\n stdout += d.toString();\n });\n\n child.stderr.on(\"data\", (d) => {\n stderr += d.toString();\n });\n\n child.on(\"close\", (code) => {\n const result: ExecResult = {\n stdout,\n stderr,\n output: `${stdout}\\n${stderr}`,\n code,\n };\n\n if (code !== 0 && !ignoreErrors) {\n reject(new Error(`Jest failed with code ${code}`));\n return;\n }\n\n resolve(result);\n });\n\n child.on(\"error\", reject);\n });\n}\n\nexport async function buildJestArgsForMode(mode: ExecutionMode): Promise<string[]> {\n if (mode === \"all\") {\n return [];\n }\n\n const staged = await getStagedFiles();\n if (staged.length === 0) {\n throw new Error(`No staged files found for mode: ${mode}`);\n }\n\n if (mode === \"tests\") {\n const testFiles = filterTestFiles(staged);\n if (testFiles.length === 0) {\n throw new Error(\"No test files found in staged files\");\n }\n\n return testFiles;\n }\n\n return [\"--findRelatedTests\", ...staged];\n}\n","import { CONSOLE_LOG_TYPES, JEST_PATTERNS } from \"./constants\";\n\nexport function stripAnsi(text: string): string {\n return text.replace(/\\x1b\\[[0-9;]*m/g, \"\");\n}\n\nexport function isCodeSnippetLine(line: string): boolean {\n return JEST_PATTERNS.CODE_LINE.test(stripAnsi(line).trim());\n}\n\nexport function isStackTraceLine(line: string): boolean {\n return JEST_PATTERNS.STACK_TRACE.test(stripAnsi(line));\n}\n\nexport function isConsoleTypeLine(line: string): boolean {\n const clean = stripAnsi(line).trim();\n return Object.values(CONSOLE_LOG_TYPES).includes(clean as (typeof CONSOLE_LOG_TYPES)[keyof typeof CONSOLE_LOG_TYPES]);\n}\n\nexport function extractConsoleType(line: string): string | null {\n const clean = stripAnsi(line).trim();\n return Object.values(CONSOLE_LOG_TYPES).find((type) => type === clean) ?? null;\n}\n","import { writeFileSync } from \"node:fs\";\nimport path from \"node:path\";\n\nimport { VALID_EXPORT_FORMATS } from \"./constants\";\nimport type { ExportFormat, OutputOptions } from \"../types\";\n\nexport function getDisplayTimestamp(locale = \"en-US\"): string {\n return new Date().toLocaleString(locale, {\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\",\n hour12: false,\n });\n}\n\nexport function getFilenameTimestamp(): string {\n const now = new Date();\n const pad = (value: number) => String(value).padStart(2, \"0\");\n\n return (\n [now.getFullYear(), pad(now.getMonth() + 1), pad(now.getDate())].join(\"-\") +\n \"_\" +\n [pad(now.getHours()), pad(now.getMinutes()), pad(now.getSeconds())].join(\"-\")\n );\n}\n\nexport function buildTimestampedPath(prefix: string, extension: string, dir = process.cwd()): string {\n const timestamp = getFilenameTimestamp();\n const filename = `${prefix}-${timestamp}.${extension}`;\n\n return path.resolve(dir, filename);\n}\n\nexport function formatAsMarkdown(content: string, title: string, timestamp: string | null = null): string {\n const lines = [`# ${title}`, \"\"];\n\n if (timestamp) {\n lines.push(`Generated: ${timestamp}`, \"\");\n }\n\n lines.push(\"```text\", content.trimEnd(), \"```\", \"\");\n\n return lines.join(\"\\n\");\n}\n\nexport function exportToFile(\n content: string,\n options: { prefix: string; format: ExportFormat; title?: string; dir?: string }\n): string {\n const { prefix, format, title, dir = process.cwd() } = options;\n const filePath = buildTimestampedPath(prefix, format, dir);\n\n let finalContent = content;\n if (format === \"md\" && title) {\n finalContent = formatAsMarkdown(content, title, getDisplayTimestamp());\n }\n\n writeFileSync(filePath, finalContent, \"utf-8\");\n\n return filePath;\n}\n\nexport function parseExportCliArgs(args: string[]): { exportFormat: ExportFormat | null; exportArgs: string[] } {\n let exportFormat: ExportFormat | null = null;\n const exportArgs: string[] = [];\n\n for (const arg of args) {\n if (arg === \"--export\") {\n exportFormat = \"txt\";\n exportArgs.push(arg);\n continue;\n }\n\n if (!arg.startsWith(\"--export=\")) {\n continue;\n }\n\n const value = arg.slice(\"--export=\".length).trim().toLowerCase();\n if (!value || !VALID_EXPORT_FORMATS.includes(value as ExportFormat)) {\n throw new Error(`Invalid value for --export: ${value || \"(empty)\"}. Valid values: txt, md`);\n }\n\n exportFormat = value as ExportFormat;\n exportArgs.push(arg);\n }\n\n return { exportFormat, exportArgs };\n}\n\nexport function handleExportOrDisplay(content: string, config: OutputOptions): string | null {\n const { exportFormat, prefix, title } = config;\n\n if (!exportFormat) {\n console.log(content);\n\n return null;\n }\n\n const outputPath = exportToFile(content, {\n prefix,\n format: exportFormat,\n title,\n });\n\n console.log(`Output exported to: ${outputPath}`);\n\n return outputPath;\n}\n","type SchemaEntry = {\n values?: string[];\n default?: string;\n exclusive?: boolean;\n prefix?: string;\n allowedValues?: string[];\n};\n\nexport function validateCliArgs(\n args: string[],\n schema: Record<string, SchemaEntry>\n): { parsed: Record<string, string | undefined>; unknownArgs: string[] } {\n const parsed: Record<string, string | undefined> = {};\n const unknownArgs: string[] = [];\n\n for (const [key, config] of Object.entries(schema)) {\n if (config.default !== undefined) {\n parsed[key] = config.default;\n }\n }\n\n for (const arg of args) {\n let matched = false;\n\n for (const [key, config] of Object.entries(schema)) {\n if (config.values?.includes(arg)) {\n if (config.exclusive && parsed[key] !== undefined && parsed[key] !== config.default) {\n throw new Error(`Multiple values provided for ${key}: ${parsed[key]} and ${arg}`);\n }\n\n parsed[key] = arg;\n matched = true;\n break;\n }\n\n if (config.prefix && arg.startsWith(config.prefix)) {\n const value = arg.slice(config.prefix.length).trim().toLowerCase();\n\n if (!value) {\n parsed[key] = \"true\";\n matched = true;\n break;\n }\n\n if (config.allowedValues && !config.allowedValues.includes(value)) {\n throw new Error(\n `Invalid value for ${config.prefix}: ${value}. Valid values: ${config.allowedValues.join(\", \")}`\n );\n }\n\n parsed[key] = value;\n matched = true;\n break;\n }\n }\n\n if (!matched && arg.startsWith(\"--\")) {\n unknownArgs.push(arg);\n }\n }\n\n return { parsed, unknownArgs };\n}\n\nexport function displayHelp(\n title: string,\n content: { description?: string; usage?: string[]; options?: string[]; examples?: string[] }\n): never {\n console.log(`\\n${title}\\n`);\n\n if (content.description) {\n console.log(`${content.description}\\n`);\n }\n\n if (content.usage?.length) {\n console.log(\"Usage:\");\n content.usage.forEach((line) => console.log(` ${line}`));\n console.log(\"\");\n }\n\n if (content.options?.length) {\n console.log(\"Options:\");\n content.options.forEach((line) => console.log(` ${line}`));\n console.log(\"\");\n }\n\n if (content.examples?.length) {\n console.log(\"Examples:\");\n content.examples.forEach((line) => console.log(` ${line}`));\n console.log(\"\");\n }\n\n process.exit(0);\n}\n\nexport function exitWithError(message: string, code = 1): never {\n console.error(`❌ ${message}`);\n process.exit(code);\n}\n\nexport function logWarning(message: string): void {\n console.warn(`⚠️ ${message}`);\n}\n\nexport function logInfo(message: string): void {\n console.log(`ℹ️ ${message}`);\n}\n\nexport function logSuccess(message: string): void {\n console.log(`✅ ${message}`);\n}\n","import { getDisplayTimestamp } from \"./export\";\n\ntype Spinner = {\n start: () => Spinner;\n stop: () => Spinner;\n succeed: (message?: string) => Spinner;\n warn: (message?: string) => Spinner;\n fail: (message?: string) => Spinner;\n};\n\ntype ProgressBar = {\n update: (value: number, payload?: Record<string, string>) => void;\n stop: () => void;\n};\n\nconst NOOP_PROGRESS_BAR: ProgressBar = {\n update: () => {},\n stop: () => {},\n};\n\nlet hasWarnedSpinnerFallback = false;\nlet hasWarnedProgressFallback = false;\n\nexport function shouldShowUI(exportMode: string | null, noBanner = false): boolean {\n return !exportMode && !noBanner && Boolean(process.stdout.isTTY);\n}\n\nexport function displayBanner(config: {\n text: string;\n subtitle?: string;\n info?: Record<string, string>;\n colors?: string[];\n font?: string;\n}): void {\n const { text, subtitle, info = {}, colors = [\"cyan\"], font = \"block\" } = config;\n const bannerText = [text, subtitle].filter(Boolean).join(\" \").trim();\n\n // Lazy load to avoid breaking non-interactive execution.\n const cfonts = require(\"cfonts\") as {\n render: (message: string, options: Record<string, unknown>) => { string: string };\n };\n const boxenModule = require(\"boxen\") as\n | ((text: string, options: Record<string, unknown>) => string)\n | { default: (text: string, options: Record<string, unknown>) => string };\n const boxen = typeof boxenModule === \"function\" ? boxenModule : boxenModule.default;\n\n const renderedBanner = cfonts.render(bannerText, {\n font,\n colors,\n align: \"left\",\n background: \"transparent\",\n letterSpacing: 1,\n lineHeight: 1,\n space: false,\n maxLength: \"0\",\n env: \"node\",\n });\n\n const infoLine = Object.entries(info)\n .map(([key, value]) => `${key}: ${value}`)\n .join(\" | \");\n\n const contentLines = [renderedBanner.string.trimEnd()];\n if (infoLine) {\n contentLines.push(\"\", ` ${infoLine}`);\n }\n contentLines.push(` Date: ${getDisplayTimestamp()}`);\n\n const boxed = boxen(contentLines.join(\"\\n\"), {\n padding: {\n top: 0,\n right: 1,\n bottom: 0,\n left: 1,\n },\n margin: {\n top: 0,\n right: 0,\n bottom: 1,\n left: 0,\n },\n borderStyle: \"round\",\n borderColor: colors[0] ?? \"cyan\",\n });\n\n console.log(boxed);\n}\n\nexport function createSpinner(text: string, color: string = \"cyan\"): Spinner {\n try {\n const ora = require(\"ora\") as (config: Record<string, unknown>) => Spinner;\n\n return ora({ text, color, spinner: \"dots\" });\n } catch {\n if (!hasWarnedSpinnerFallback) {\n hasWarnedSpinnerFallback = true;\n console.warn(\"Warning: spinner UI unavailable, continuing without spinner.\");\n }\n\n return {\n start: () => NOOP_SPINNER,\n stop: () => NOOP_SPINNER,\n succeed: () => NOOP_SPINNER,\n warn: () => NOOP_SPINNER,\n fail: () => NOOP_SPINNER,\n } as Spinner;\n }\n}\n\nconst NOOP_SPINNER: Spinner = {\n start: () => NOOP_SPINNER,\n stop: () => NOOP_SPINNER,\n succeed: () => NOOP_SPINNER,\n warn: () => NOOP_SPINNER,\n fail: () => NOOP_SPINNER,\n};\n\nexport function createProgressBar(total = 100, task = \"Progress\"): ProgressBar {\n if (!hasWarnedProgressFallback) {\n hasWarnedProgressFallback = true;\n console.warn(\n `Warning: progress bar UI is no longer used. Ignoring createProgressBar(${total}, ${JSON.stringify(task)}).`\n );\n }\n\n return NOOP_PROGRESS_BAR;\n}\n","import {\n buildJestArgsForMode,\n displayBanner,\n exitWithError,\n extractConsoleType,\n handleExportOrDisplay,\n JEST_PATTERNS,\n parseExportCliArgs,\n runJest,\n shouldShowUI,\n stripAnsi,\n validateCliArgs,\n VALID_MODES,\n createSpinner,\n displayHelp,\n logWarning,\n} from \"../core\";\n\ntype FailureBlock = {\n file: string;\n tests: string[];\n};\n\nexport function extractFailures(raw: string): FailureBlock[] {\n const lines = raw.split(\"\\n\");\n const temp: FailureBlock[] = [];\n let current: FailureBlock | null = null;\n\n for (const line of lines) {\n if (JEST_PATTERNS.FAIL_LINE.test(line)) {\n if (current) {\n temp.push(current);\n }\n current = {\n file: line.replace(\"FAIL \", \"\").trim(),\n tests: [],\n };\n continue;\n }\n\n if (JEST_PATTERNS.BULLET_POINT.test(line.trim())) {\n current?.tests.push(line.trim().slice(1).trim());\n }\n }\n\n if (current) {\n temp.push(current);\n }\n\n const merged: Record<string, FailureBlock> = {};\n for (const item of temp) {\n if (!merged[item.file]) {\n merged[item.file] = {\n file: item.file,\n tests: [],\n };\n }\n merged[item.file].tests.push(...item.tests);\n }\n\n for (const value of Object.values(merged)) {\n value.tests = Array.from(new Set(value.tests));\n }\n\n return Object.values(merged);\n}\n\nexport async function runTestContext(argv = process.argv.slice(2)): Promise<void> {\n if (argv.includes(\"-h\") || argv.includes(\"--help\")) {\n displayHelp(\"Test Context Script\", {\n description: \"Run Jest and print failures in LLM-friendly format.\",\n usage: [\n \"test-context -- --all\",\n \"test-context -- --related\",\n \"test-context -- --tests\",\n ],\n options: [\n \"--all Run all tests (default)\",\n \"--related Run tests related to staged files\",\n \"--tests Run only staged test files\",\n \"--export Export output as txt\",\n \"--export=txt|md Export output in selected format\",\n \"--no-banner Disable fancy terminal UI\",\n \"-h, --help Show this help\",\n ],\n examples: [\"test-context -- --related --export=md\"],\n });\n }\n\n const noBanner = argv.includes(\"--no-banner\");\n const args = argv.filter((arg) => arg !== \"--no-banner\");\n\n let exportFormat: \"txt\" | \"md\" | null;\n let exportArgs: string[];\n let parsed: Record<string, string | undefined>;\n let unknownArgs: string[];\n\n try {\n ({ exportFormat, exportArgs } = parseExportCliArgs(args));\n ({ parsed, unknownArgs } = validateCliArgs(args, {\n mode: {\n values: [...VALID_MODES],\n default: \"--all\",\n exclusive: true,\n },\n }));\n } catch (error) {\n exitWithError((error as Error).message);\n }\n\n const exportArgSet = new Set(exportArgs);\n const filteredUnknownArgs = unknownArgs.filter((arg) => !exportArgSet.has(arg));\n if (filteredUnknownArgs.length > 0) {\n logWarning(`Unknown arguments ignored: ${filteredUnknownArgs.join(\", \")}`);\n }\n\n const modeArg = parsed.mode ?? \"--all\";\n const mode = modeArg === \"--related\" ? \"related\" : modeArg === \"--tests\" ? \"tests\" : \"all\";\n\n const showUI = shouldShowUI(exportFormat, noBanner);\n if (showUI) {\n displayBanner({\n text: \"JEST\",\n subtitle: \"TEST\",\n info: {\n Mode: mode,\n },\n colors: [\"cyan\", \"blue\"],\n });\n }\n\n let jestArgs: string[] = [];\n try {\n jestArgs = await buildJestArgsForMode(mode);\n } catch (error) {\n exitWithError((error as Error).message);\n }\n\n const spinner = showUI ? createSpinner(\"Running Jest tests...\") : null;\n spinner?.start();\n\n const result = await runJest(jestArgs, {\n verbose: true,\n ignoreErrors: true,\n });\n\n const output = stripAnsi(result.output);\n const hadFailures = output.includes(\"FAIL\") || output.includes(\"●\");\n\n if (spinner) {\n if (hadFailures) {\n spinner.warn(\"Tests completed with failures\");\n } else {\n spinner.succeed(\"All tests passed!\");\n }\n }\n\n if (!hadFailures) {\n const passMessage = \"All tests passed!\";\n handleExportOrDisplay(passMessage, {\n exportFormat,\n prefix: \"export-test-context\",\n title: \"Test Context\",\n });\n\n return;\n }\n\n const failures = extractFailures(output);\n const lines = [\"=== LLM TEST CONTEXT BEGIN ===\", \"\"];\n\n if (failures.length === 0) {\n lines.push(\"No test failures could be parsed from Jest output.\");\n lines.push(\"This may happen if Jest failed before running tests.\", \"\");\n }\n\n for (const fail of failures) {\n lines.push(`File: ${fail.file}`);\n lines.push(\"Failures:\");\n for (const test of fail.tests) {\n lines.push(`- ${test}`);\n }\n lines.push(\"\");\n }\n\n lines.push(\"=== LLM TEST CONTEXT END ===\");\n\n handleExportOrDisplay(lines.join(\"\\n\"), {\n exportFormat,\n prefix: \"export-test-context\",\n title: \"Test Context\",\n });\n}\n","#!/usr/bin/env node\n\nimport { runTestContext } from \"../commands/test-context\";\n\nrunTestContext().catch((error) => {\n console.error(`❌ ${(error as Error).message}`);\n process.exit(1);\n});\n"],"mappings":"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","names":["import_node_child_process","path"]}
|
|
1
|
+
{"version":3,"sources":["../../src/core/constants.ts","../../src/core/platform.ts","../../src/core/exec.ts","../../src/core/git.ts","../../src/core/jest.ts","../../src/core/parsing.ts","../../src/core/export.ts","../../src/core/cli.ts","../../src/core/ui.ts","../../src/commands/test-context.ts","../../src/bin/test-context.ts"],"sourcesContent":["export const VALID_MODES = [\"--all\", \"--related\", \"--tests\"] as const;\n\nexport const VALID_EXPORT_FORMATS = [\"txt\", \"md\"] as const;\n\nexport const VALID_TEST_EXTENSIONS = /\\.(test|spec)\\.(ts|tsx|js|jsx)$/;\n\nexport const CONSOLE_LOG_TYPES = {\n ERROR: \"console.error\",\n WARN: \"console.warn\",\n LOG: \"console.log\",\n DEBUG: \"console.debug\",\n} as const;\n\nexport const JEST_PATTERNS = {\n FAIL_LINE: /^FAIL\\s+/,\n PASS_LINE: /^PASS\\s+/,\n TEST_FILE: /^(PASS|FAIL)\\s+(.+\\.(test|spec)\\.tsx?)/,\n COVERAGE_LINE:\n /^(.+?)\\s+\\|\\s+([\\d.]+)\\s+\\|\\s+([\\d.]+)\\s+\\|\\s+([\\d.]+)\\s+\\|\\s+([\\d.]+)(?:\\s+\\|\\s+(.+))?$/,\n BULLET_POINT: /^●\\s+/,\n CODE_LINE: /^>?\\s*\\d*\\s*\\|/,\n STACK_TRACE: /^\\s+at\\s+/,\n};\n","export function getPlatform(): NodeJS.Platform {\n return process.platform;\n}\n\nexport function isWindows(): boolean {\n return process.platform === \"win32\";\n}\n\nexport function isMac(): boolean {\n return process.platform === \"darwin\";\n}\n\nexport function isLinux(): boolean {\n return process.platform === \"linux\";\n}\n\nexport function resolveCommand(cmd: string): string {\n if (!isWindows()) return cmd;\n\n const windowsCommands: Record<string, string> = {\n git: \"git.exe\",\n node: \"node.exe\",\n npm: \"npm.cmd\",\n npx: \"npx.cmd\",\n yarn: \"yarn.cmd\",\n pnpm: \"pnpm.cmd\",\n };\n\n return windowsCommands[cmd] ?? cmd;\n}\n","import { spawn } from \"node:child_process\";\n\nimport { resolveCommand } from \"./platform\";\nimport type { ExecResult } from \"../types\";\n\nexport async function execCommand(\n cmd: string,\n args: string[] = [],\n options: { shell?: boolean; ignoreErrors?: boolean } = {}\n): Promise<ExecResult> {\n return new Promise((resolve, reject) => {\n const resolvedCmd = resolveCommand(cmd);\n const child = spawn(resolvedCmd, args, {\n shell: options.shell ?? false,\n });\n\n let stdout = \"\";\n let stderr = \"\";\n\n child.stdout?.on(\"data\", (d) => {\n stdout += d.toString();\n });\n\n child.stderr?.on(\"data\", (d) => {\n stderr += d.toString();\n });\n\n child.on(\"close\", (code) => {\n const result: ExecResult = {\n stdout,\n stderr,\n output: `${stdout}\\n${stderr}`,\n code,\n };\n\n if (code !== 0 && !options.ignoreErrors) {\n reject(new Error(`Command failed with code ${code}: ${cmd} ${args.join(\" \")}`));\n return;\n }\n\n resolve(result);\n });\n\n child.on(\"error\", (error) => {\n reject(new Error(`Failed to execute command: ${error.message}`));\n });\n });\n}\n","import { execCommand } from \"./exec\";\nimport { VALID_TEST_EXTENSIONS } from \"./constants\";\n\nlet cachedGitAvailability: boolean | null = null;\nlet cachedStagedFiles: string[] | null = null;\nlet cachedStagedFilesAt = 0;\nconst STAGED_FILES_CACHE_TTL_MS = 1000;\n\nexport async function hasGit(): Promise<boolean> {\n if (cachedGitAvailability !== null) {\n return cachedGitAvailability;\n }\n\n try {\n const result = await execCommand(\"git\", [\"--version\"], { ignoreErrors: true });\n cachedGitAvailability = result.code === 0;\n\n return cachedGitAvailability;\n } catch {\n cachedGitAvailability = false;\n\n return false;\n }\n}\n\nexport async function getStagedFiles(): Promise<string[]> {\n const now = Date.now();\n if (cachedStagedFiles && now - cachedStagedFilesAt <= STAGED_FILES_CACHE_TTL_MS) {\n return cachedStagedFiles;\n }\n\n const gitAvailable = await hasGit();\n if (!gitAvailable) {\n throw new Error(\"Git is not installed or not available in PATH\");\n }\n\n const result = await execCommand(\"git\", [\"diff\", \"--name-only\", \"--cached\"], {\n ignoreErrors: true,\n });\n\n const files = result.stdout\n .split(\"\\n\")\n .map((f) => f.trim())\n .filter(Boolean);\n\n cachedStagedFiles = files;\n cachedStagedFilesAt = now;\n\n return files;\n}\n\nexport function filterTestFiles(files: string[]): string[] {\n return files.filter((file) => VALID_TEST_EXTENSIONS.test(file));\n}\n","import { spawn } from \"node:child_process\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport path from \"node:path\";\n\nimport { isWindows } from \"./platform\";\nimport { filterTestFiles, getStagedFiles } from \"./git\";\nimport type { ExecutionMode, ExecResult, RunJestOptions } from \"../types\";\n\ntype ResolvedJestRunner = {\n command: string;\n argsPrefix: string[];\n};\n\nfunction resolveJestRunner(): ResolvedJestRunner {\n const cwd = process.cwd();\n const attempts: string[] = [];\n\n try {\n const jestPackageJsonPath = require.resolve(\"jest/package.json\", { paths: [cwd] });\n attempts.push(`Resolved jest package: ${jestPackageJsonPath}`);\n\n const jestPackageDir = path.dirname(jestPackageJsonPath);\n const jestPackage = JSON.parse(readFileSync(jestPackageJsonPath, \"utf-8\")) as {\n bin?: string | Record<string, string>;\n };\n\n const binField = jestPackage.bin;\n let binEntry: string | undefined;\n if (typeof binField === \"string\") {\n binEntry = binField;\n } else if (binField && typeof binField === \"object\") {\n binEntry = binField.jest ?? Object.values(binField)[0];\n }\n\n if (binEntry) {\n const binPath = path.resolve(jestPackageDir, binEntry);\n if (existsSync(binPath)) {\n return {\n command: process.execPath,\n argsPrefix: [binPath],\n };\n }\n attempts.push(`Jest bin from package.json not found: ${binPath}`);\n } else {\n attempts.push(\"Jest package.json has no usable bin field.\");\n }\n } catch {\n attempts.push(\"Could not resolve jest/package.json from current cwd.\");\n }\n\n try {\n const legacyBinPath = require.resolve(\"jest/bin/jest.js\", { paths: [cwd] });\n attempts.push(`Resolved legacy jest bin: ${legacyBinPath}`);\n return {\n command: process.execPath,\n argsPrefix: [legacyBinPath],\n };\n } catch {\n attempts.push(\"Could not resolve legacy path jest/bin/jest.js.\");\n }\n\n const localBinPath = path.resolve(cwd, \"node_modules\", \".bin\", isWindows() ? \"jest.cmd\" : \"jest\");\n if (existsSync(localBinPath)) {\n attempts.push(`Resolved local .bin executable: ${localBinPath}`);\n return {\n command: localBinPath,\n argsPrefix: [],\n };\n }\n attempts.push(`Local .bin executable not found: ${localBinPath}`);\n\n throw new Error(\n [\n \"Could not resolve Jest from the current project.\",\n \"Install `jest@^29` in the package where you run this command.\",\n \"Examples: `npm i -D jest@^29`, `pnpm add -D jest@^29`, `yarn add -D jest@^29`.\",\n `cwd: ${cwd}`,\n ...attempts,\n ].join(\"\\n\")\n );\n}\n\nexport async function runJest(args: string[] = [], options: RunJestOptions = {}): Promise<ExecResult> {\n const {\n verbose = false,\n coverage = false,\n ignoreErrors = true,\n disableVerbose = false,\n } = options;\n\n const runner = resolveJestRunner();\n const command = runner.command;\n const jestArgs = [...runner.argsPrefix];\n\n if (verbose && !disableVerbose) {\n jestArgs.push(\"--verbose\");\n }\n\n if (coverage) {\n jestArgs.push(\"--coverage\");\n\n if (options.coverageReporters) {\n for (const reporter of options.coverageReporters) {\n jestArgs.push(`--coverageReporters=${reporter}`);\n }\n }\n }\n\n if (isWindows()) {\n jestArgs.push(\"--no-watchman\");\n }\n\n jestArgs.push(...args);\n\n return new Promise((resolve, reject) => {\n const child = spawn(command, jestArgs, {\n shell: false,\n });\n\n let stdout = \"\";\n let stderr = \"\";\n\n child.stdout.on(\"data\", (d) => {\n stdout += d.toString();\n });\n\n child.stderr.on(\"data\", (d) => {\n stderr += d.toString();\n });\n\n child.on(\"close\", (code) => {\n const result: ExecResult = {\n stdout,\n stderr,\n output: `${stdout}\\n${stderr}`,\n code,\n };\n\n if (code !== 0 && !ignoreErrors) {\n reject(new Error(`Jest failed with code ${code}`));\n return;\n }\n\n resolve(result);\n });\n\n child.on(\"error\", reject);\n });\n}\n\nexport async function buildJestArgsForMode(mode: ExecutionMode): Promise<string[]> {\n if (mode === \"all\") {\n return [];\n }\n\n const staged = await getStagedFiles();\n if (staged.length === 0) {\n throw new Error(`No staged files found for mode: ${mode}`);\n }\n\n if (mode === \"tests\") {\n const testFiles = filterTestFiles(staged);\n if (testFiles.length === 0) {\n throw new Error(\"No test files found in staged files\");\n }\n\n return testFiles;\n }\n\n return [\"--findRelatedTests\", ...staged];\n}\n","import { CONSOLE_LOG_TYPES, JEST_PATTERNS } from \"./constants\";\n\nexport function stripAnsi(text: string): string {\n return text.replace(/\\x1b\\[[0-9;]*m/g, \"\");\n}\n\nexport function isCodeSnippetLine(line: string): boolean {\n return JEST_PATTERNS.CODE_LINE.test(stripAnsi(line).trim());\n}\n\nexport function isStackTraceLine(line: string): boolean {\n return JEST_PATTERNS.STACK_TRACE.test(stripAnsi(line));\n}\n\nexport function isConsoleTypeLine(line: string): boolean {\n const clean = stripAnsi(line).trim();\n return Object.values(CONSOLE_LOG_TYPES).includes(clean as (typeof CONSOLE_LOG_TYPES)[keyof typeof CONSOLE_LOG_TYPES]);\n}\n\nexport function extractConsoleType(line: string): string | null {\n const clean = stripAnsi(line).trim();\n return Object.values(CONSOLE_LOG_TYPES).find((type) => type === clean) ?? null;\n}\n","import { writeFileSync } from \"node:fs\";\nimport path from \"node:path\";\n\nimport { VALID_EXPORT_FORMATS } from \"./constants\";\nimport type { ExportFormat, OutputOptions } from \"../types\";\n\nexport function getDisplayTimestamp(locale = \"en-US\"): string {\n return new Date().toLocaleString(locale, {\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\",\n hour12: false,\n });\n}\n\nexport function getFilenameTimestamp(): string {\n const now = new Date();\n const pad = (value: number) => String(value).padStart(2, \"0\");\n\n return (\n [now.getFullYear(), pad(now.getMonth() + 1), pad(now.getDate())].join(\"-\") +\n \"_\" +\n [pad(now.getHours()), pad(now.getMinutes()), pad(now.getSeconds())].join(\"-\")\n );\n}\n\nexport function buildTimestampedPath(prefix: string, extension: string, dir = process.cwd()): string {\n const timestamp = getFilenameTimestamp();\n const filename = `${prefix}-${timestamp}.${extension}`;\n\n return path.resolve(dir, filename);\n}\n\nexport function formatAsMarkdown(content: string, title: string, timestamp: string | null = null): string {\n const lines = [`# ${title}`, \"\"];\n\n if (timestamp) {\n lines.push(`Generated: ${timestamp}`, \"\");\n }\n\n lines.push(\"```text\", content.trimEnd(), \"```\", \"\");\n\n return lines.join(\"\\n\");\n}\n\nexport function exportToFile(\n content: string,\n options: { prefix: string; format: ExportFormat; title?: string; dir?: string }\n): string {\n const { prefix, format, title, dir = process.cwd() } = options;\n const filePath = buildTimestampedPath(prefix, format, dir);\n\n let finalContent = content;\n if (format === \"md\" && title) {\n finalContent = formatAsMarkdown(content, title, getDisplayTimestamp());\n }\n\n writeFileSync(filePath, finalContent, \"utf-8\");\n\n return filePath;\n}\n\nexport function parseExportCliArgs(args: string[]): { exportFormat: ExportFormat | null; exportArgs: string[] } {\n let exportFormat: ExportFormat | null = null;\n const exportArgs: string[] = [];\n\n for (const arg of args) {\n if (arg === \"--export\") {\n exportFormat = \"txt\";\n exportArgs.push(arg);\n continue;\n }\n\n if (!arg.startsWith(\"--export=\")) {\n continue;\n }\n\n const value = arg.slice(\"--export=\".length).trim().toLowerCase();\n if (!value || !VALID_EXPORT_FORMATS.includes(value as ExportFormat)) {\n throw new Error(`Invalid value for --export: ${value || \"(empty)\"}. Valid values: txt, md`);\n }\n\n exportFormat = value as ExportFormat;\n exportArgs.push(arg);\n }\n\n return { exportFormat, exportArgs };\n}\n\nexport function handleExportOrDisplay(content: string, config: OutputOptions): string | null {\n const { exportFormat, prefix, title } = config;\n\n if (!exportFormat) {\n console.log(content);\n\n return null;\n }\n\n const outputPath = exportToFile(content, {\n prefix,\n format: exportFormat,\n title,\n });\n\n console.log(`Output exported to: ${outputPath}`);\n\n return outputPath;\n}\n","type SchemaEntry = {\n values?: string[];\n default?: string;\n exclusive?: boolean;\n prefix?: string;\n allowedValues?: string[];\n};\n\nexport function validateCliArgs(\n args: string[],\n schema: Record<string, SchemaEntry>\n): { parsed: Record<string, string | undefined>; unknownArgs: string[] } {\n const parsed: Record<string, string | undefined> = {};\n const unknownArgs: string[] = [];\n\n for (const [key, config] of Object.entries(schema)) {\n if (config.default !== undefined) {\n parsed[key] = config.default;\n }\n }\n\n for (const arg of args) {\n let matched = false;\n\n for (const [key, config] of Object.entries(schema)) {\n if (config.values?.includes(arg)) {\n if (config.exclusive && parsed[key] !== undefined && parsed[key] !== config.default) {\n throw new Error(`Multiple values provided for ${key}: ${parsed[key]} and ${arg}`);\n }\n\n parsed[key] = arg;\n matched = true;\n break;\n }\n\n if (config.prefix && arg.startsWith(config.prefix)) {\n const value = arg.slice(config.prefix.length).trim().toLowerCase();\n\n if (!value) {\n parsed[key] = \"true\";\n matched = true;\n break;\n }\n\n if (config.allowedValues && !config.allowedValues.includes(value)) {\n throw new Error(\n `Invalid value for ${config.prefix}: ${value}. Valid values: ${config.allowedValues.join(\", \")}`\n );\n }\n\n parsed[key] = value;\n matched = true;\n break;\n }\n }\n\n if (!matched && arg.startsWith(\"--\")) {\n unknownArgs.push(arg);\n }\n }\n\n return { parsed, unknownArgs };\n}\n\nexport function displayHelp(\n title: string,\n content: { description?: string; usage?: string[]; options?: string[]; examples?: string[] }\n): never {\n console.log(`\\n${title}\\n`);\n\n if (content.description) {\n console.log(`${content.description}\\n`);\n }\n\n if (content.usage?.length) {\n console.log(\"Usage:\");\n content.usage.forEach((line) => console.log(` ${line}`));\n console.log(\"\");\n }\n\n if (content.options?.length) {\n console.log(\"Options:\");\n content.options.forEach((line) => console.log(` ${line}`));\n console.log(\"\");\n }\n\n if (content.examples?.length) {\n console.log(\"Examples:\");\n content.examples.forEach((line) => console.log(` ${line}`));\n console.log(\"\");\n }\n\n process.exit(0);\n}\n\nexport function exitWithError(message: string, code = 1): never {\n console.error(`❌ ${message}`);\n process.exit(code);\n}\n\nexport function logWarning(message: string): void {\n console.warn(`⚠️ ${message}`);\n}\n\nexport function logInfo(message: string): void {\n console.log(`ℹ️ ${message}`);\n}\n\nexport function logSuccess(message: string): void {\n console.log(`✅ ${message}`);\n}\n","import { getDisplayTimestamp } from \"./export\";\n\ntype Spinner = {\n start: () => Spinner;\n stop: () => Spinner;\n succeed: (message?: string) => Spinner;\n warn: (message?: string) => Spinner;\n fail: (message?: string) => Spinner;\n};\n\ntype ProgressBar = {\n update: (value: number, payload?: Record<string, string>) => void;\n stop: () => void;\n};\n\nconst NOOP_PROGRESS_BAR: ProgressBar = {\n update: () => {},\n stop: () => {},\n};\n\nlet hasWarnedSpinnerFallback = false;\nlet hasWarnedProgressFallback = false;\n\nexport function shouldShowUI(exportMode: string | null, noBanner = false): boolean {\n return !exportMode && !noBanner && Boolean(process.stdout.isTTY);\n}\n\nexport function displayBanner(config: {\n text: string;\n subtitle?: string;\n info?: Record<string, string>;\n colors?: string[];\n font?: string;\n}): void {\n const { text, subtitle, info = {}, colors = [\"cyan\"], font = \"block\" } = config;\n\n // Lazy load to avoid breaking non-interactive execution.\n const cfonts = require(\"cfonts\") as {\n render: (message: string, options: Record<string, unknown>) => { string: string };\n };\n const boxenModule = require(\"boxen\") as\n | ((text: string, options: Record<string, unknown>) => string)\n | { default: (text: string, options: Record<string, unknown>) => string };\n const boxen = typeof boxenModule === \"function\" ? boxenModule : boxenModule.default;\n\n const renderedTitle = cfonts.render(text, {\n font,\n colors: [colors[0] ?? \"cyan\"],\n align: \"left\",\n background: \"transparent\",\n letterSpacing: 1,\n lineHeight: 1,\n space: false,\n maxLength: \"0\",\n env: \"node\",\n });\n\n const renderedSubtitle = subtitle\n ? cfonts.render(subtitle, {\n font,\n colors: [colors[1] ?? colors[0] ?? \"cyan\"],\n align: \"left\",\n background: \"transparent\",\n letterSpacing: 1,\n lineHeight: 1,\n space: false,\n maxLength: \"0\",\n env: \"node\",\n })\n : null;\n\n const stripAnsi = (value: string): string => value.replace(/\\x1b\\[[0-9;]*m/g, \"\");\n const centerLines = (lines: string[], width: number): string[] => {\n return lines.map((line) => {\n const visibleLength = stripAnsi(line).length;\n const leftPad = Math.max(0, Math.floor((width - visibleLength) / 2));\n\n return `${\" \".repeat(leftPad)}${line}`;\n });\n };\n\n const titleLines = renderedTitle.string.trimEnd().split(\"\\n\");\n const subtitleLines = renderedSubtitle ? renderedSubtitle.string.trimEnd().split(\"\\n\") : [];\n const centeredWidth = Math.max(\n ...titleLines.map((line) => stripAnsi(line).length),\n ...(subtitleLines.length > 0 ? subtitleLines : [\"\"]).map((line) => stripAnsi(line).length)\n );\n\n const infoLine = Object.entries(info)\n .map(([key, value]) => `${key}: ${value}`)\n .join(\" | \");\n\n const contentLines = [...centerLines(titleLines, centeredWidth)];\n if (subtitleLines.length > 0) {\n contentLines.push(\"\", ...centerLines(subtitleLines, centeredWidth));\n }\n\n contentLines.push(\"\");\n if (infoLine) {\n contentLines.push(` ${infoLine}`);\n }\n contentLines.push(` Date: ${getDisplayTimestamp()}`);\n\n const boxed = boxen(contentLines.join(\"\\n\"), {\n padding: {\n top: 0,\n right: 1,\n bottom: 0,\n left: 1,\n },\n margin: {\n top: 0,\n right: 0,\n bottom: 1,\n left: 0,\n },\n borderStyle: \"round\",\n borderColor: colors[0] ?? \"cyan\",\n });\n\n console.log(boxed);\n}\n\nexport function createSpinner(text: string, color: string = \"cyan\"): Spinner {\n try {\n const ora = require(\"ora\") as (config: Record<string, unknown>) => Spinner;\n\n return ora({ text, color, spinner: \"dots\" });\n } catch {\n if (!hasWarnedSpinnerFallback) {\n hasWarnedSpinnerFallback = true;\n console.warn(\"Warning: spinner UI unavailable, continuing without spinner.\");\n }\n\n return {\n start: () => NOOP_SPINNER,\n stop: () => NOOP_SPINNER,\n succeed: () => NOOP_SPINNER,\n warn: () => NOOP_SPINNER,\n fail: () => NOOP_SPINNER,\n } as Spinner;\n }\n}\n\nconst NOOP_SPINNER: Spinner = {\n start: () => NOOP_SPINNER,\n stop: () => NOOP_SPINNER,\n succeed: () => NOOP_SPINNER,\n warn: () => NOOP_SPINNER,\n fail: () => NOOP_SPINNER,\n};\n\nexport function createProgressBar(total = 100, task = \"Progress\"): ProgressBar {\n if (!hasWarnedProgressFallback) {\n hasWarnedProgressFallback = true;\n console.warn(\n `Warning: progress bar UI is no longer used. Ignoring createProgressBar(${total}, ${JSON.stringify(task)}).`\n );\n }\n\n return NOOP_PROGRESS_BAR;\n}\n","import {\n buildJestArgsForMode,\n displayBanner,\n exitWithError,\n extractConsoleType,\n handleExportOrDisplay,\n JEST_PATTERNS,\n parseExportCliArgs,\n runJest,\n shouldShowUI,\n stripAnsi,\n validateCliArgs,\n VALID_MODES,\n createSpinner,\n displayHelp,\n logWarning,\n} from \"../core\";\n\ntype FailureBlock = {\n file: string;\n tests: string[];\n};\n\nexport function extractFailures(raw: string): FailureBlock[] {\n const lines = raw.split(\"\\n\");\n const temp: FailureBlock[] = [];\n let current: FailureBlock | null = null;\n\n for (const line of lines) {\n if (JEST_PATTERNS.FAIL_LINE.test(line)) {\n if (current) {\n temp.push(current);\n }\n current = {\n file: line.replace(\"FAIL \", \"\").trim(),\n tests: [],\n };\n continue;\n }\n\n if (JEST_PATTERNS.BULLET_POINT.test(line.trim())) {\n current?.tests.push(line.trim().slice(1).trim());\n }\n }\n\n if (current) {\n temp.push(current);\n }\n\n const merged: Record<string, FailureBlock> = {};\n for (const item of temp) {\n if (!merged[item.file]) {\n merged[item.file] = {\n file: item.file,\n tests: [],\n };\n }\n merged[item.file].tests.push(...item.tests);\n }\n\n for (const value of Object.values(merged)) {\n value.tests = Array.from(new Set(value.tests));\n }\n\n return Object.values(merged);\n}\n\nexport async function runTestContext(argv = process.argv.slice(2)): Promise<void> {\n if (argv.includes(\"-h\") || argv.includes(\"--help\")) {\n displayHelp(\"Test Context Script\", {\n description: \"Run Jest and print failures in LLM-friendly format.\",\n usage: [\n \"test-context -- --all\",\n \"test-context -- --related\",\n \"test-context -- --tests\",\n ],\n options: [\n \"--all Run all tests (default)\",\n \"--related Run tests related to staged files\",\n \"--tests Run only staged test files\",\n \"--export Export output as txt\",\n \"--export=txt|md Export output in selected format\",\n \"--no-banner Disable fancy terminal UI\",\n \"-h, --help Show this help\",\n ],\n examples: [\"test-context -- --related --export=md\"],\n });\n }\n\n const noBanner = argv.includes(\"--no-banner\");\n const args = argv.filter((arg) => arg !== \"--no-banner\");\n\n let exportFormat: \"txt\" | \"md\" | null;\n let exportArgs: string[];\n let parsed: Record<string, string | undefined>;\n let unknownArgs: string[];\n\n try {\n ({ exportFormat, exportArgs } = parseExportCliArgs(args));\n ({ parsed, unknownArgs } = validateCliArgs(args, {\n mode: {\n values: [...VALID_MODES],\n default: \"--all\",\n exclusive: true,\n },\n }));\n } catch (error) {\n exitWithError((error as Error).message);\n }\n\n const exportArgSet = new Set(exportArgs);\n const filteredUnknownArgs = unknownArgs.filter((arg) => !exportArgSet.has(arg));\n if (filteredUnknownArgs.length > 0) {\n logWarning(`Unknown arguments ignored: ${filteredUnknownArgs.join(\", \")}`);\n }\n\n const modeArg = parsed.mode ?? \"--all\";\n const mode = modeArg === \"--related\" ? \"related\" : modeArg === \"--tests\" ? \"tests\" : \"all\";\n\n const showUI = shouldShowUI(exportFormat, noBanner);\n if (showUI) {\n displayBanner({\n text: \"JEST\",\n subtitle: \"TEST\",\n info: {\n Mode: mode,\n },\n colors: [\"cyan\", \"blue\"],\n });\n }\n\n let jestArgs: string[] = [];\n try {\n jestArgs = await buildJestArgsForMode(mode);\n } catch (error) {\n exitWithError((error as Error).message);\n }\n\n const spinner = showUI ? createSpinner(\"Running Jest tests...\") : null;\n spinner?.start();\n\n const result = await runJest(jestArgs, {\n verbose: true,\n ignoreErrors: true,\n });\n\n const output = stripAnsi(result.output);\n const hadFailures = output.includes(\"FAIL\") || output.includes(\"●\");\n\n if (spinner) {\n if (hadFailures) {\n spinner.warn(\"Tests completed with failures\");\n } else {\n spinner.succeed(\"All tests passed!\");\n }\n }\n\n if (!hadFailures) {\n const passMessage = \"All tests passed!\";\n handleExportOrDisplay(passMessage, {\n exportFormat,\n prefix: \"export-test-context\",\n title: \"Test Context\",\n });\n\n return;\n }\n\n const failures = extractFailures(output);\n const lines = [\"=== LLM TEST CONTEXT BEGIN ===\", \"\"];\n\n if (failures.length === 0) {\n lines.push(\"No test failures could be parsed from Jest output.\");\n lines.push(\"This may happen if Jest failed before running tests.\", \"\");\n }\n\n for (const fail of failures) {\n lines.push(`File: ${fail.file}`);\n lines.push(\"Failures:\");\n for (const test of fail.tests) {\n lines.push(`- ${test}`);\n }\n lines.push(\"\");\n }\n\n lines.push(\"=== LLM TEST CONTEXT END ===\");\n\n handleExportOrDisplay(lines.join(\"\\n\"), {\n exportFormat,\n prefix: \"export-test-context\",\n title: \"Test Context\",\n });\n}\n","#!/usr/bin/env node\n\nimport { runTestContext } from \"../commands/test-context\";\n\nrunTestContext().catch((error) => {\n console.error(`❌ ${(error as Error).message}`);\n process.exit(1);\n});\n"],"mappings":"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","names":["import_node_child_process","path","import_node_fs","import_node_path","path","stripAnsi"]}
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
shouldShowUI,
|
|
20
20
|
stripAnsi,
|
|
21
21
|
validateCliArgs
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-KGUQFDCB.mjs";
|
|
23
23
|
|
|
24
24
|
// src/commands/console-context.ts
|
|
25
25
|
import path from "path";
|
|
@@ -249,4 +249,4 @@ async function runConsoleContext(argv = process.argv.slice(2)) {
|
|
|
249
249
|
export {
|
|
250
250
|
runConsoleContext
|
|
251
251
|
};
|
|
252
|
-
//# sourceMappingURL=chunk-
|
|
252
|
+
//# sourceMappingURL=chunk-4N7XPTHJ.mjs.map
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
runJest,
|
|
10
10
|
shouldShowUI,
|
|
11
11
|
validateCliArgs
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-KGUQFDCB.mjs";
|
|
13
13
|
|
|
14
14
|
// src/commands/coverage-context.ts
|
|
15
15
|
import path from "path";
|
|
@@ -164,4 +164,4 @@ async function runCoverageContext(argv = process.argv.slice(2)) {
|
|
|
164
164
|
export {
|
|
165
165
|
runCoverageContext
|
|
166
166
|
};
|
|
167
|
-
//# sourceMappingURL=chunk-
|
|
167
|
+
//# sourceMappingURL=chunk-7F4YL67U.mjs.map
|
|
@@ -146,14 +146,66 @@ function filterTestFiles(files) {
|
|
|
146
146
|
|
|
147
147
|
// src/core/jest.ts
|
|
148
148
|
import { spawn as spawn2 } from "child_process";
|
|
149
|
-
|
|
149
|
+
import { existsSync, readFileSync } from "fs";
|
|
150
|
+
import path from "path";
|
|
151
|
+
function resolveJestRunner() {
|
|
152
|
+
const cwd = process.cwd();
|
|
153
|
+
const attempts = [];
|
|
150
154
|
try {
|
|
151
|
-
|
|
155
|
+
const jestPackageJsonPath = __require.resolve("jest/package.json", { paths: [cwd] });
|
|
156
|
+
attempts.push(`Resolved jest package: ${jestPackageJsonPath}`);
|
|
157
|
+
const jestPackageDir = path.dirname(jestPackageJsonPath);
|
|
158
|
+
const jestPackage = JSON.parse(readFileSync(jestPackageJsonPath, "utf-8"));
|
|
159
|
+
const binField = jestPackage.bin;
|
|
160
|
+
let binEntry;
|
|
161
|
+
if (typeof binField === "string") {
|
|
162
|
+
binEntry = binField;
|
|
163
|
+
} else if (binField && typeof binField === "object") {
|
|
164
|
+
binEntry = binField.jest ?? Object.values(binField)[0];
|
|
165
|
+
}
|
|
166
|
+
if (binEntry) {
|
|
167
|
+
const binPath = path.resolve(jestPackageDir, binEntry);
|
|
168
|
+
if (existsSync(binPath)) {
|
|
169
|
+
return {
|
|
170
|
+
command: process.execPath,
|
|
171
|
+
argsPrefix: [binPath]
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
attempts.push(`Jest bin from package.json not found: ${binPath}`);
|
|
175
|
+
} else {
|
|
176
|
+
attempts.push("Jest package.json has no usable bin field.");
|
|
177
|
+
}
|
|
152
178
|
} catch {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
179
|
+
attempts.push("Could not resolve jest/package.json from current cwd.");
|
|
180
|
+
}
|
|
181
|
+
try {
|
|
182
|
+
const legacyBinPath = __require.resolve("jest/bin/jest.js", { paths: [cwd] });
|
|
183
|
+
attempts.push(`Resolved legacy jest bin: ${legacyBinPath}`);
|
|
184
|
+
return {
|
|
185
|
+
command: process.execPath,
|
|
186
|
+
argsPrefix: [legacyBinPath]
|
|
187
|
+
};
|
|
188
|
+
} catch {
|
|
189
|
+
attempts.push("Could not resolve legacy path jest/bin/jest.js.");
|
|
190
|
+
}
|
|
191
|
+
const localBinPath = path.resolve(cwd, "node_modules", ".bin", isWindows() ? "jest.cmd" : "jest");
|
|
192
|
+
if (existsSync(localBinPath)) {
|
|
193
|
+
attempts.push(`Resolved local .bin executable: ${localBinPath}`);
|
|
194
|
+
return {
|
|
195
|
+
command: localBinPath,
|
|
196
|
+
argsPrefix: []
|
|
197
|
+
};
|
|
156
198
|
}
|
|
199
|
+
attempts.push(`Local .bin executable not found: ${localBinPath}`);
|
|
200
|
+
throw new Error(
|
|
201
|
+
[
|
|
202
|
+
"Could not resolve Jest from the current project.",
|
|
203
|
+
"Install `jest@^29` in the package where you run this command.",
|
|
204
|
+
"Examples: `npm i -D jest@^29`, `pnpm add -D jest@^29`, `yarn add -D jest@^29`.",
|
|
205
|
+
`cwd: ${cwd}`,
|
|
206
|
+
...attempts
|
|
207
|
+
].join("\n")
|
|
208
|
+
);
|
|
157
209
|
}
|
|
158
210
|
async function runJest(args = [], options = {}) {
|
|
159
211
|
const {
|
|
@@ -162,9 +214,9 @@ async function runJest(args = [], options = {}) {
|
|
|
162
214
|
ignoreErrors = true,
|
|
163
215
|
disableVerbose = false
|
|
164
216
|
} = options;
|
|
165
|
-
const
|
|
166
|
-
const command =
|
|
167
|
-
const jestArgs = [
|
|
217
|
+
const runner = resolveJestRunner();
|
|
218
|
+
const command = runner.command;
|
|
219
|
+
const jestArgs = [...runner.argsPrefix];
|
|
168
220
|
if (verbose && !disableVerbose) {
|
|
169
221
|
jestArgs.push("--verbose");
|
|
170
222
|
}
|
|
@@ -248,7 +300,7 @@ function extractConsoleType(line) {
|
|
|
248
300
|
|
|
249
301
|
// src/core/export.ts
|
|
250
302
|
import { writeFileSync } from "fs";
|
|
251
|
-
import
|
|
303
|
+
import path2 from "path";
|
|
252
304
|
function getDisplayTimestamp(locale = "en-US") {
|
|
253
305
|
return (/* @__PURE__ */ new Date()).toLocaleString(locale, {
|
|
254
306
|
year: "numeric",
|
|
@@ -268,7 +320,7 @@ function getFilenameTimestamp() {
|
|
|
268
320
|
function buildTimestampedPath(prefix, extension, dir = process.cwd()) {
|
|
269
321
|
const timestamp = getFilenameTimestamp();
|
|
270
322
|
const filename = `${prefix}-${timestamp}.${extension}`;
|
|
271
|
-
return
|
|
323
|
+
return path2.resolve(dir, filename);
|
|
272
324
|
}
|
|
273
325
|
function formatAsMarkdown(content, title, timestamp = null) {
|
|
274
326
|
const lines = [`# ${title}`, ""];
|
|
@@ -420,13 +472,12 @@ function shouldShowUI(exportMode, noBanner = false) {
|
|
|
420
472
|
}
|
|
421
473
|
function displayBanner(config) {
|
|
422
474
|
const { text, subtitle, info = {}, colors = ["cyan"], font = "block" } = config;
|
|
423
|
-
const bannerText = [text, subtitle].filter(Boolean).join(" ").trim();
|
|
424
475
|
const cfonts = __require("cfonts");
|
|
425
476
|
const boxenModule = __require("boxen");
|
|
426
477
|
const boxen = typeof boxenModule === "function" ? boxenModule : boxenModule.default;
|
|
427
|
-
const
|
|
478
|
+
const renderedTitle = cfonts.render(text, {
|
|
428
479
|
font,
|
|
429
|
-
colors,
|
|
480
|
+
colors: [colors[0] ?? "cyan"],
|
|
430
481
|
align: "left",
|
|
431
482
|
background: "transparent",
|
|
432
483
|
letterSpacing: 1,
|
|
@@ -435,10 +486,39 @@ function displayBanner(config) {
|
|
|
435
486
|
maxLength: "0",
|
|
436
487
|
env: "node"
|
|
437
488
|
});
|
|
489
|
+
const renderedSubtitle = subtitle ? cfonts.render(subtitle, {
|
|
490
|
+
font,
|
|
491
|
+
colors: [colors[1] ?? colors[0] ?? "cyan"],
|
|
492
|
+
align: "left",
|
|
493
|
+
background: "transparent",
|
|
494
|
+
letterSpacing: 1,
|
|
495
|
+
lineHeight: 1,
|
|
496
|
+
space: false,
|
|
497
|
+
maxLength: "0",
|
|
498
|
+
env: "node"
|
|
499
|
+
}) : null;
|
|
500
|
+
const stripAnsi2 = (value) => value.replace(/\x1b\[[0-9;]*m/g, "");
|
|
501
|
+
const centerLines = (lines, width) => {
|
|
502
|
+
return lines.map((line) => {
|
|
503
|
+
const visibleLength = stripAnsi2(line).length;
|
|
504
|
+
const leftPad = Math.max(0, Math.floor((width - visibleLength) / 2));
|
|
505
|
+
return `${" ".repeat(leftPad)}${line}`;
|
|
506
|
+
});
|
|
507
|
+
};
|
|
508
|
+
const titleLines = renderedTitle.string.trimEnd().split("\n");
|
|
509
|
+
const subtitleLines = renderedSubtitle ? renderedSubtitle.string.trimEnd().split("\n") : [];
|
|
510
|
+
const centeredWidth = Math.max(
|
|
511
|
+
...titleLines.map((line) => stripAnsi2(line).length),
|
|
512
|
+
...(subtitleLines.length > 0 ? subtitleLines : [""]).map((line) => stripAnsi2(line).length)
|
|
513
|
+
);
|
|
438
514
|
const infoLine = Object.entries(info).map(([key, value]) => `${key}: ${value}`).join(" | ");
|
|
439
|
-
const contentLines = [
|
|
515
|
+
const contentLines = [...centerLines(titleLines, centeredWidth)];
|
|
516
|
+
if (subtitleLines.length > 0) {
|
|
517
|
+
contentLines.push("", ...centerLines(subtitleLines, centeredWidth));
|
|
518
|
+
}
|
|
519
|
+
contentLines.push("");
|
|
440
520
|
if (infoLine) {
|
|
441
|
-
contentLines.push(
|
|
521
|
+
contentLines.push(` ${infoLine}`);
|
|
442
522
|
}
|
|
443
523
|
contentLines.push(` Date: ${getDisplayTimestamp()}`);
|
|
444
524
|
const boxed = boxen(contentLines.join("\n"), {
|
|
@@ -536,4 +616,4 @@ export {
|
|
|
536
616
|
createSpinner,
|
|
537
617
|
createProgressBar
|
|
538
618
|
};
|
|
539
|
-
//# sourceMappingURL=chunk-
|
|
619
|
+
//# sourceMappingURL=chunk-KGUQFDCB.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/constants.ts","../src/core/platform.ts","../src/core/package-manager.ts","../src/core/exec.ts","../src/core/git.ts","../src/core/jest.ts","../src/core/parsing.ts","../src/core/export.ts","../src/core/cli.ts","../src/core/ui.ts"],"sourcesContent":["export const VALID_MODES = [\"--all\", \"--related\", \"--tests\"] as const;\n\nexport const VALID_EXPORT_FORMATS = [\"txt\", \"md\"] as const;\n\nexport const VALID_TEST_EXTENSIONS = /\\.(test|spec)\\.(ts|tsx|js|jsx)$/;\n\nexport const CONSOLE_LOG_TYPES = {\n ERROR: \"console.error\",\n WARN: \"console.warn\",\n LOG: \"console.log\",\n DEBUG: \"console.debug\",\n} as const;\n\nexport const JEST_PATTERNS = {\n FAIL_LINE: /^FAIL\\s+/,\n PASS_LINE: /^PASS\\s+/,\n TEST_FILE: /^(PASS|FAIL)\\s+(.+\\.(test|spec)\\.tsx?)/,\n COVERAGE_LINE:\n /^(.+?)\\s+\\|\\s+([\\d.]+)\\s+\\|\\s+([\\d.]+)\\s+\\|\\s+([\\d.]+)\\s+\\|\\s+([\\d.]+)(?:\\s+\\|\\s+(.+))?$/,\n BULLET_POINT: /^●\\s+/,\n CODE_LINE: /^>?\\s*\\d*\\s*\\|/,\n STACK_TRACE: /^\\s+at\\s+/,\n};\n","export function getPlatform(): NodeJS.Platform {\n return process.platform;\n}\n\nexport function isWindows(): boolean {\n return process.platform === \"win32\";\n}\n\nexport function isMac(): boolean {\n return process.platform === \"darwin\";\n}\n\nexport function isLinux(): boolean {\n return process.platform === \"linux\";\n}\n\nexport function resolveCommand(cmd: string): string {\n if (!isWindows()) return cmd;\n\n const windowsCommands: Record<string, string> = {\n git: \"git.exe\",\n node: \"node.exe\",\n npm: \"npm.cmd\",\n npx: \"npx.cmd\",\n yarn: \"yarn.cmd\",\n pnpm: \"pnpm.cmd\",\n };\n\n return windowsCommands[cmd] ?? cmd;\n}\n","export type PackageManager = \"npm\" | \"yarn\" | \"pnpm\";\n\nexport function detectPackageManager(): PackageManager {\n if (process.env.npm_execpath?.includes(\"yarn\")) return \"yarn\";\n if (process.env.npm_execpath?.includes(\"pnpm\")) return \"pnpm\";\n\n return \"npm\";\n}\n\nexport function getJestCommand(packageManager: PackageManager | null = null): [string, string] {\n const pm = packageManager ?? detectPackageManager();\n\n switch (pm) {\n case \"yarn\":\n return [\"yarn\", \"jest\"];\n case \"pnpm\":\n return [\"pnpm\", \"jest\"];\n default:\n return [\"npx\", \"jest\"];\n }\n}\n","import { spawn } from \"node:child_process\";\n\nimport { resolveCommand } from \"./platform\";\nimport type { ExecResult } from \"../types\";\n\nexport async function execCommand(\n cmd: string,\n args: string[] = [],\n options: { shell?: boolean; ignoreErrors?: boolean } = {}\n): Promise<ExecResult> {\n return new Promise((resolve, reject) => {\n const resolvedCmd = resolveCommand(cmd);\n const child = spawn(resolvedCmd, args, {\n shell: options.shell ?? false,\n });\n\n let stdout = \"\";\n let stderr = \"\";\n\n child.stdout?.on(\"data\", (d) => {\n stdout += d.toString();\n });\n\n child.stderr?.on(\"data\", (d) => {\n stderr += d.toString();\n });\n\n child.on(\"close\", (code) => {\n const result: ExecResult = {\n stdout,\n stderr,\n output: `${stdout}\\n${stderr}`,\n code,\n };\n\n if (code !== 0 && !options.ignoreErrors) {\n reject(new Error(`Command failed with code ${code}: ${cmd} ${args.join(\" \")}`));\n return;\n }\n\n resolve(result);\n });\n\n child.on(\"error\", (error) => {\n reject(new Error(`Failed to execute command: ${error.message}`));\n });\n });\n}\n","import { execCommand } from \"./exec\";\nimport { VALID_TEST_EXTENSIONS } from \"./constants\";\n\nlet cachedGitAvailability: boolean | null = null;\nlet cachedStagedFiles: string[] | null = null;\nlet cachedStagedFilesAt = 0;\nconst STAGED_FILES_CACHE_TTL_MS = 1000;\n\nexport async function hasGit(): Promise<boolean> {\n if (cachedGitAvailability !== null) {\n return cachedGitAvailability;\n }\n\n try {\n const result = await execCommand(\"git\", [\"--version\"], { ignoreErrors: true });\n cachedGitAvailability = result.code === 0;\n\n return cachedGitAvailability;\n } catch {\n cachedGitAvailability = false;\n\n return false;\n }\n}\n\nexport async function getStagedFiles(): Promise<string[]> {\n const now = Date.now();\n if (cachedStagedFiles && now - cachedStagedFilesAt <= STAGED_FILES_CACHE_TTL_MS) {\n return cachedStagedFiles;\n }\n\n const gitAvailable = await hasGit();\n if (!gitAvailable) {\n throw new Error(\"Git is not installed or not available in PATH\");\n }\n\n const result = await execCommand(\"git\", [\"diff\", \"--name-only\", \"--cached\"], {\n ignoreErrors: true,\n });\n\n const files = result.stdout\n .split(\"\\n\")\n .map((f) => f.trim())\n .filter(Boolean);\n\n cachedStagedFiles = files;\n cachedStagedFilesAt = now;\n\n return files;\n}\n\nexport function filterTestFiles(files: string[]): string[] {\n return files.filter((file) => VALID_TEST_EXTENSIONS.test(file));\n}\n","import { spawn } from \"node:child_process\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport path from \"node:path\";\n\nimport { isWindows } from \"./platform\";\nimport { filterTestFiles, getStagedFiles } from \"./git\";\nimport type { ExecutionMode, ExecResult, RunJestOptions } from \"../types\";\n\ntype ResolvedJestRunner = {\n command: string;\n argsPrefix: string[];\n};\n\nfunction resolveJestRunner(): ResolvedJestRunner {\n const cwd = process.cwd();\n const attempts: string[] = [];\n\n try {\n const jestPackageJsonPath = require.resolve(\"jest/package.json\", { paths: [cwd] });\n attempts.push(`Resolved jest package: ${jestPackageJsonPath}`);\n\n const jestPackageDir = path.dirname(jestPackageJsonPath);\n const jestPackage = JSON.parse(readFileSync(jestPackageJsonPath, \"utf-8\")) as {\n bin?: string | Record<string, string>;\n };\n\n const binField = jestPackage.bin;\n let binEntry: string | undefined;\n if (typeof binField === \"string\") {\n binEntry = binField;\n } else if (binField && typeof binField === \"object\") {\n binEntry = binField.jest ?? Object.values(binField)[0];\n }\n\n if (binEntry) {\n const binPath = path.resolve(jestPackageDir, binEntry);\n if (existsSync(binPath)) {\n return {\n command: process.execPath,\n argsPrefix: [binPath],\n };\n }\n attempts.push(`Jest bin from package.json not found: ${binPath}`);\n } else {\n attempts.push(\"Jest package.json has no usable bin field.\");\n }\n } catch {\n attempts.push(\"Could not resolve jest/package.json from current cwd.\");\n }\n\n try {\n const legacyBinPath = require.resolve(\"jest/bin/jest.js\", { paths: [cwd] });\n attempts.push(`Resolved legacy jest bin: ${legacyBinPath}`);\n return {\n command: process.execPath,\n argsPrefix: [legacyBinPath],\n };\n } catch {\n attempts.push(\"Could not resolve legacy path jest/bin/jest.js.\");\n }\n\n const localBinPath = path.resolve(cwd, \"node_modules\", \".bin\", isWindows() ? \"jest.cmd\" : \"jest\");\n if (existsSync(localBinPath)) {\n attempts.push(`Resolved local .bin executable: ${localBinPath}`);\n return {\n command: localBinPath,\n argsPrefix: [],\n };\n }\n attempts.push(`Local .bin executable not found: ${localBinPath}`);\n\n throw new Error(\n [\n \"Could not resolve Jest from the current project.\",\n \"Install `jest@^29` in the package where you run this command.\",\n \"Examples: `npm i -D jest@^29`, `pnpm add -D jest@^29`, `yarn add -D jest@^29`.\",\n `cwd: ${cwd}`,\n ...attempts,\n ].join(\"\\n\")\n );\n}\n\nexport async function runJest(args: string[] = [], options: RunJestOptions = {}): Promise<ExecResult> {\n const {\n verbose = false,\n coverage = false,\n ignoreErrors = true,\n disableVerbose = false,\n } = options;\n\n const runner = resolveJestRunner();\n const command = runner.command;\n const jestArgs = [...runner.argsPrefix];\n\n if (verbose && !disableVerbose) {\n jestArgs.push(\"--verbose\");\n }\n\n if (coverage) {\n jestArgs.push(\"--coverage\");\n\n if (options.coverageReporters) {\n for (const reporter of options.coverageReporters) {\n jestArgs.push(`--coverageReporters=${reporter}`);\n }\n }\n }\n\n if (isWindows()) {\n jestArgs.push(\"--no-watchman\");\n }\n\n jestArgs.push(...args);\n\n return new Promise((resolve, reject) => {\n const child = spawn(command, jestArgs, {\n shell: false,\n });\n\n let stdout = \"\";\n let stderr = \"\";\n\n child.stdout.on(\"data\", (d) => {\n stdout += d.toString();\n });\n\n child.stderr.on(\"data\", (d) => {\n stderr += d.toString();\n });\n\n child.on(\"close\", (code) => {\n const result: ExecResult = {\n stdout,\n stderr,\n output: `${stdout}\\n${stderr}`,\n code,\n };\n\n if (code !== 0 && !ignoreErrors) {\n reject(new Error(`Jest failed with code ${code}`));\n return;\n }\n\n resolve(result);\n });\n\n child.on(\"error\", reject);\n });\n}\n\nexport async function buildJestArgsForMode(mode: ExecutionMode): Promise<string[]> {\n if (mode === \"all\") {\n return [];\n }\n\n const staged = await getStagedFiles();\n if (staged.length === 0) {\n throw new Error(`No staged files found for mode: ${mode}`);\n }\n\n if (mode === \"tests\") {\n const testFiles = filterTestFiles(staged);\n if (testFiles.length === 0) {\n throw new Error(\"No test files found in staged files\");\n }\n\n return testFiles;\n }\n\n return [\"--findRelatedTests\", ...staged];\n}\n","import { CONSOLE_LOG_TYPES, JEST_PATTERNS } from \"./constants\";\n\nexport function stripAnsi(text: string): string {\n return text.replace(/\\x1b\\[[0-9;]*m/g, \"\");\n}\n\nexport function isCodeSnippetLine(line: string): boolean {\n return JEST_PATTERNS.CODE_LINE.test(stripAnsi(line).trim());\n}\n\nexport function isStackTraceLine(line: string): boolean {\n return JEST_PATTERNS.STACK_TRACE.test(stripAnsi(line));\n}\n\nexport function isConsoleTypeLine(line: string): boolean {\n const clean = stripAnsi(line).trim();\n return Object.values(CONSOLE_LOG_TYPES).includes(clean as (typeof CONSOLE_LOG_TYPES)[keyof typeof CONSOLE_LOG_TYPES]);\n}\n\nexport function extractConsoleType(line: string): string | null {\n const clean = stripAnsi(line).trim();\n return Object.values(CONSOLE_LOG_TYPES).find((type) => type === clean) ?? null;\n}\n","import { writeFileSync } from \"node:fs\";\nimport path from \"node:path\";\n\nimport { VALID_EXPORT_FORMATS } from \"./constants\";\nimport type { ExportFormat, OutputOptions } from \"../types\";\n\nexport function getDisplayTimestamp(locale = \"en-US\"): string {\n return new Date().toLocaleString(locale, {\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\",\n hour12: false,\n });\n}\n\nexport function getFilenameTimestamp(): string {\n const now = new Date();\n const pad = (value: number) => String(value).padStart(2, \"0\");\n\n return (\n [now.getFullYear(), pad(now.getMonth() + 1), pad(now.getDate())].join(\"-\") +\n \"_\" +\n [pad(now.getHours()), pad(now.getMinutes()), pad(now.getSeconds())].join(\"-\")\n );\n}\n\nexport function buildTimestampedPath(prefix: string, extension: string, dir = process.cwd()): string {\n const timestamp = getFilenameTimestamp();\n const filename = `${prefix}-${timestamp}.${extension}`;\n\n return path.resolve(dir, filename);\n}\n\nexport function formatAsMarkdown(content: string, title: string, timestamp: string | null = null): string {\n const lines = [`# ${title}`, \"\"];\n\n if (timestamp) {\n lines.push(`Generated: ${timestamp}`, \"\");\n }\n\n lines.push(\"```text\", content.trimEnd(), \"```\", \"\");\n\n return lines.join(\"\\n\");\n}\n\nexport function exportToFile(\n content: string,\n options: { prefix: string; format: ExportFormat; title?: string; dir?: string }\n): string {\n const { prefix, format, title, dir = process.cwd() } = options;\n const filePath = buildTimestampedPath(prefix, format, dir);\n\n let finalContent = content;\n if (format === \"md\" && title) {\n finalContent = formatAsMarkdown(content, title, getDisplayTimestamp());\n }\n\n writeFileSync(filePath, finalContent, \"utf-8\");\n\n return filePath;\n}\n\nexport function parseExportCliArgs(args: string[]): { exportFormat: ExportFormat | null; exportArgs: string[] } {\n let exportFormat: ExportFormat | null = null;\n const exportArgs: string[] = [];\n\n for (const arg of args) {\n if (arg === \"--export\") {\n exportFormat = \"txt\";\n exportArgs.push(arg);\n continue;\n }\n\n if (!arg.startsWith(\"--export=\")) {\n continue;\n }\n\n const value = arg.slice(\"--export=\".length).trim().toLowerCase();\n if (!value || !VALID_EXPORT_FORMATS.includes(value as ExportFormat)) {\n throw new Error(`Invalid value for --export: ${value || \"(empty)\"}. Valid values: txt, md`);\n }\n\n exportFormat = value as ExportFormat;\n exportArgs.push(arg);\n }\n\n return { exportFormat, exportArgs };\n}\n\nexport function handleExportOrDisplay(content: string, config: OutputOptions): string | null {\n const { exportFormat, prefix, title } = config;\n\n if (!exportFormat) {\n console.log(content);\n\n return null;\n }\n\n const outputPath = exportToFile(content, {\n prefix,\n format: exportFormat,\n title,\n });\n\n console.log(`Output exported to: ${outputPath}`);\n\n return outputPath;\n}\n","type SchemaEntry = {\n values?: string[];\n default?: string;\n exclusive?: boolean;\n prefix?: string;\n allowedValues?: string[];\n};\n\nexport function validateCliArgs(\n args: string[],\n schema: Record<string, SchemaEntry>\n): { parsed: Record<string, string | undefined>; unknownArgs: string[] } {\n const parsed: Record<string, string | undefined> = {};\n const unknownArgs: string[] = [];\n\n for (const [key, config] of Object.entries(schema)) {\n if (config.default !== undefined) {\n parsed[key] = config.default;\n }\n }\n\n for (const arg of args) {\n let matched = false;\n\n for (const [key, config] of Object.entries(schema)) {\n if (config.values?.includes(arg)) {\n if (config.exclusive && parsed[key] !== undefined && parsed[key] !== config.default) {\n throw new Error(`Multiple values provided for ${key}: ${parsed[key]} and ${arg}`);\n }\n\n parsed[key] = arg;\n matched = true;\n break;\n }\n\n if (config.prefix && arg.startsWith(config.prefix)) {\n const value = arg.slice(config.prefix.length).trim().toLowerCase();\n\n if (!value) {\n parsed[key] = \"true\";\n matched = true;\n break;\n }\n\n if (config.allowedValues && !config.allowedValues.includes(value)) {\n throw new Error(\n `Invalid value for ${config.prefix}: ${value}. Valid values: ${config.allowedValues.join(\", \")}`\n );\n }\n\n parsed[key] = value;\n matched = true;\n break;\n }\n }\n\n if (!matched && arg.startsWith(\"--\")) {\n unknownArgs.push(arg);\n }\n }\n\n return { parsed, unknownArgs };\n}\n\nexport function displayHelp(\n title: string,\n content: { description?: string; usage?: string[]; options?: string[]; examples?: string[] }\n): never {\n console.log(`\\n${title}\\n`);\n\n if (content.description) {\n console.log(`${content.description}\\n`);\n }\n\n if (content.usage?.length) {\n console.log(\"Usage:\");\n content.usage.forEach((line) => console.log(` ${line}`));\n console.log(\"\");\n }\n\n if (content.options?.length) {\n console.log(\"Options:\");\n content.options.forEach((line) => console.log(` ${line}`));\n console.log(\"\");\n }\n\n if (content.examples?.length) {\n console.log(\"Examples:\");\n content.examples.forEach((line) => console.log(` ${line}`));\n console.log(\"\");\n }\n\n process.exit(0);\n}\n\nexport function exitWithError(message: string, code = 1): never {\n console.error(`❌ ${message}`);\n process.exit(code);\n}\n\nexport function logWarning(message: string): void {\n console.warn(`⚠️ ${message}`);\n}\n\nexport function logInfo(message: string): void {\n console.log(`ℹ️ ${message}`);\n}\n\nexport function logSuccess(message: string): void {\n console.log(`✅ ${message}`);\n}\n","import { getDisplayTimestamp } from \"./export\";\n\ntype Spinner = {\n start: () => Spinner;\n stop: () => Spinner;\n succeed: (message?: string) => Spinner;\n warn: (message?: string) => Spinner;\n fail: (message?: string) => Spinner;\n};\n\ntype ProgressBar = {\n update: (value: number, payload?: Record<string, string>) => void;\n stop: () => void;\n};\n\nconst NOOP_PROGRESS_BAR: ProgressBar = {\n update: () => {},\n stop: () => {},\n};\n\nlet hasWarnedSpinnerFallback = false;\nlet hasWarnedProgressFallback = false;\n\nexport function shouldShowUI(exportMode: string | null, noBanner = false): boolean {\n return !exportMode && !noBanner && Boolean(process.stdout.isTTY);\n}\n\nexport function displayBanner(config: {\n text: string;\n subtitle?: string;\n info?: Record<string, string>;\n colors?: string[];\n font?: string;\n}): void {\n const { text, subtitle, info = {}, colors = [\"cyan\"], font = \"block\" } = config;\n\n // Lazy load to avoid breaking non-interactive execution.\n const cfonts = require(\"cfonts\") as {\n render: (message: string, options: Record<string, unknown>) => { string: string };\n };\n const boxenModule = require(\"boxen\") as\n | ((text: string, options: Record<string, unknown>) => string)\n | { default: (text: string, options: Record<string, unknown>) => string };\n const boxen = typeof boxenModule === \"function\" ? boxenModule : boxenModule.default;\n\n const renderedTitle = cfonts.render(text, {\n font,\n colors: [colors[0] ?? \"cyan\"],\n align: \"left\",\n background: \"transparent\",\n letterSpacing: 1,\n lineHeight: 1,\n space: false,\n maxLength: \"0\",\n env: \"node\",\n });\n\n const renderedSubtitle = subtitle\n ? cfonts.render(subtitle, {\n font,\n colors: [colors[1] ?? colors[0] ?? \"cyan\"],\n align: \"left\",\n background: \"transparent\",\n letterSpacing: 1,\n lineHeight: 1,\n space: false,\n maxLength: \"0\",\n env: \"node\",\n })\n : null;\n\n const stripAnsi = (value: string): string => value.replace(/\\x1b\\[[0-9;]*m/g, \"\");\n const centerLines = (lines: string[], width: number): string[] => {\n return lines.map((line) => {\n const visibleLength = stripAnsi(line).length;\n const leftPad = Math.max(0, Math.floor((width - visibleLength) / 2));\n\n return `${\" \".repeat(leftPad)}${line}`;\n });\n };\n\n const titleLines = renderedTitle.string.trimEnd().split(\"\\n\");\n const subtitleLines = renderedSubtitle ? renderedSubtitle.string.trimEnd().split(\"\\n\") : [];\n const centeredWidth = Math.max(\n ...titleLines.map((line) => stripAnsi(line).length),\n ...(subtitleLines.length > 0 ? subtitleLines : [\"\"]).map((line) => stripAnsi(line).length)\n );\n\n const infoLine = Object.entries(info)\n .map(([key, value]) => `${key}: ${value}`)\n .join(\" | \");\n\n const contentLines = [...centerLines(titleLines, centeredWidth)];\n if (subtitleLines.length > 0) {\n contentLines.push(\"\", ...centerLines(subtitleLines, centeredWidth));\n }\n\n contentLines.push(\"\");\n if (infoLine) {\n contentLines.push(` ${infoLine}`);\n }\n contentLines.push(` Date: ${getDisplayTimestamp()}`);\n\n const boxed = boxen(contentLines.join(\"\\n\"), {\n padding: {\n top: 0,\n right: 1,\n bottom: 0,\n left: 1,\n },\n margin: {\n top: 0,\n right: 0,\n bottom: 1,\n left: 0,\n },\n borderStyle: \"round\",\n borderColor: colors[0] ?? \"cyan\",\n });\n\n console.log(boxed);\n}\n\nexport function createSpinner(text: string, color: string = \"cyan\"): Spinner {\n try {\n const ora = require(\"ora\") as (config: Record<string, unknown>) => Spinner;\n\n return ora({ text, color, spinner: \"dots\" });\n } catch {\n if (!hasWarnedSpinnerFallback) {\n hasWarnedSpinnerFallback = true;\n console.warn(\"Warning: spinner UI unavailable, continuing without spinner.\");\n }\n\n return {\n start: () => NOOP_SPINNER,\n stop: () => NOOP_SPINNER,\n succeed: () => NOOP_SPINNER,\n warn: () => NOOP_SPINNER,\n fail: () => NOOP_SPINNER,\n } as Spinner;\n }\n}\n\nconst NOOP_SPINNER: Spinner = {\n start: () => NOOP_SPINNER,\n stop: () => NOOP_SPINNER,\n succeed: () => NOOP_SPINNER,\n warn: () => NOOP_SPINNER,\n fail: () => NOOP_SPINNER,\n};\n\nexport function createProgressBar(total = 100, task = \"Progress\"): ProgressBar {\n if (!hasWarnedProgressFallback) {\n hasWarnedProgressFallback = true;\n console.warn(\n `Warning: progress bar UI is no longer used. Ignoring createProgressBar(${total}, ${JSON.stringify(task)}).`\n );\n }\n\n return NOOP_PROGRESS_BAR;\n}\n"],"mappings":"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","names":["spawn","spawn","path","path","stripAnsi"]}
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
exitWithError,
|
|
4
4
|
logInfo,
|
|
5
5
|
logSuccess
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-KGUQFDCB.mjs";
|
|
7
7
|
|
|
8
8
|
// src/commands/init-context-scripts.ts
|
|
9
9
|
import { readFileSync, writeFileSync } from "fs";
|
|
@@ -68,4 +68,4 @@ function runInitContextScripts(argv = process.argv.slice(2)) {
|
|
|
68
68
|
export {
|
|
69
69
|
runInitContextScripts
|
|
70
70
|
};
|
|
71
|
-
//# sourceMappingURL=chunk-
|
|
71
|
+
//# sourceMappingURL=chunk-UE2DJICK.mjs.map
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
shouldShowUI,
|
|
14
14
|
stripAnsi,
|
|
15
15
|
validateCliArgs
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-KGUQFDCB.mjs";
|
|
17
17
|
|
|
18
18
|
// src/commands/test-context.ts
|
|
19
19
|
function extractFailures(raw) {
|
|
@@ -166,4 +166,4 @@ export {
|
|
|
166
166
|
extractFailures,
|
|
167
167
|
runTestContext
|
|
168
168
|
};
|
|
169
|
-
//# sourceMappingURL=chunk-
|
|
169
|
+
//# sourceMappingURL=chunk-YEVAAYN5.mjs.map
|