@andy2639/jest-context 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +23 -1
  3. package/dist/bin/console-context.cjs +6 -5
  4. package/dist/bin/console-context.cjs.map +1 -1
  5. package/dist/bin/console-context.mjs +2 -2
  6. package/dist/bin/coverage-context.cjs +43 -41
  7. package/dist/bin/coverage-context.cjs.map +1 -1
  8. package/dist/bin/coverage-context.mjs +2 -2
  9. package/dist/bin/jest-context-init.cjs +142 -0
  10. package/dist/bin/jest-context-init.cjs.map +1 -0
  11. package/dist/bin/jest-context-init.d.mts +1 -0
  12. package/dist/bin/jest-context-init.d.ts +1 -0
  13. package/dist/bin/jest-context-init.mjs +14 -0
  14. package/dist/bin/jest-context-init.mjs.map +1 -0
  15. package/dist/bin/test-context.cjs +6 -5
  16. package/dist/bin/test-context.cjs.map +1 -1
  17. package/dist/bin/test-context.mjs +2 -2
  18. package/dist/{chunk-JNCQ7S23.mjs → chunk-5QGDUTB3.mjs} +4 -4
  19. package/dist/chunk-5QGDUTB3.mjs.map +1 -0
  20. package/dist/{chunk-Z3YG7H6H.mjs → chunk-GV4AYRBZ.mjs} +10 -29
  21. package/dist/chunk-GV4AYRBZ.mjs.map +1 -0
  22. package/dist/{chunk-27OKLHXI.mjs → chunk-RCPJ7B43.mjs} +4 -4
  23. package/dist/{chunk-27OKLHXI.mjs.map → chunk-RCPJ7B43.mjs.map} +1 -1
  24. package/dist/chunk-UPBDVC5T.mjs +71 -0
  25. package/dist/chunk-UPBDVC5T.mjs.map +1 -0
  26. package/dist/{chunk-WW44K3NX.mjs → chunk-WEP26C5H.mjs} +10 -11
  27. package/dist/chunk-WEP26C5H.mjs.map +1 -0
  28. package/dist/index.cjs +82 -40
  29. package/dist/index.cjs.map +1 -1
  30. package/dist/index.d.mts +3 -1
  31. package/dist/index.d.ts +3 -1
  32. package/dist/index.mjs +8 -4
  33. package/package.json +3 -3
  34. package/dist/chunk-JNCQ7S23.mjs.map +0 -1
  35. package/dist/chunk-WW44K3NX.mjs.map +0 -1
  36. package/dist/chunk-Z3YG7H6H.mjs.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.2
4
+
5
+ - Remove `cli-progress` usage and standardize all commands on spinner loaders
6
+ - Update banners to `JEST TEST`, `JEST COVERAGE`, and `JEST CONSOLE`
7
+ - Add `jest-context-init` CLI to inject context scripts into project `package.json`
8
+ - Remove `cli-progress` dependency from the package
9
+
3
10
  ## 1.0.1
4
11
 
5
12
  - Add safe UI fallbacks when spinner/progress dependencies are incompatible at runtime
package/README.md CHANGED
@@ -7,7 +7,8 @@ CLI and core utilities to extract Jest context in LLM-friendly format.
7
7
  - `test-context`: summarize failed tests
8
8
  - `coverage-context`: show files below coverage threshold
9
9
  - `console-context`: collect console warnings/errors from tests
10
- - terminal UX with `ora`, `cli-progress`, and `cfonts`
10
+ - `jest-context-init`: inject context scripts into project `package.json`
11
+ - terminal UX with `ora` and `cfonts`
11
12
 
12
13
  ## Installation
13
14
 
@@ -21,6 +22,27 @@ pnpm add -D @andy2639/jest-context
21
22
  test-context --all
22
23
  coverage-context --threshold=90
23
24
  console-context --all --only-errors
25
+ jest-context-init
26
+ ```
27
+
28
+ ## Bootstrap Scripts
29
+
30
+ Run this in any project where you want the context scripts:
31
+
32
+ ```bash
33
+ npx @andy2639/jest-context jest-context-init
34
+ ```
35
+
36
+ It creates/updates:
37
+
38
+ ```json
39
+ {
40
+ "scripts": {
41
+ "console:context": "console-context",
42
+ "coverage:context": "coverage-context",
43
+ "test:context": "test-context"
44
+ }
45
+ }
24
46
  ```
25
47
 
26
48
  ## Flags
@@ -87,7 +87,7 @@ async function execCommand(cmd, args = [], options = {}) {
87
87
  return new Promise((resolve, reject) => {
88
88
  const resolvedCmd = resolveCommand(cmd);
89
89
  const child = (0, import_node_child_process.spawn)(resolvedCmd, args, {
90
- shell: options.shell ?? process.platform === "win32"
90
+ shell: options.shell ?? false
91
91
  });
92
92
  let stdout = "";
93
93
  let stderr = "";
@@ -167,6 +167,7 @@ async function runJest(args = [], options = {}) {
167
167
  disableVerbose = false
168
168
  } = options;
169
169
  const jestCmd = getJestCommand(packageManager);
170
+ const command = resolveCommand(jestCmd[0]);
170
171
  const jestArgs = [...jestCmd.slice(1)];
171
172
  if (verbose && !disableVerbose) {
172
173
  jestArgs.push("--verbose");
@@ -184,8 +185,8 @@ async function runJest(args = [], options = {}) {
184
185
  }
185
186
  jestArgs.push(...args);
186
187
  return new Promise((resolve, reject) => {
187
- const child = (0, import_node_child_process2.spawn)(jestCmd[0], jestArgs, {
188
- shell: isWindows()
188
+ const child = (0, import_node_child_process2.spawn)(command, jestArgs, {
189
+ shell: false
189
190
  });
190
191
  let stdout = "";
191
192
  let stderr = "";
@@ -657,8 +658,8 @@ async function runConsoleContext(argv = process.argv.slice(2)) {
657
658
  const showUI = shouldShowUI(exportFormat, noBanner);
658
659
  if (showUI) {
659
660
  displayBanner({
660
- text: "CONSOLE",
661
- subtitle: "WARNINGS",
661
+ text: "JEST",
662
+ subtitle: "CONSOLE",
662
663
  info: {
663
664
  Mode: mode,
664
665
  Filter: filter ?? "none"
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/console-context.ts","../../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","../../src/bin/console-context.ts"],"sourcesContent":["import path from \"node:path\";\n\nimport {\n buildJestArgsForMode,\n CONSOLE_LOG_TYPES,\n createSpinner,\n displayBanner,\n displayHelp,\n exitWithError,\n extractConsoleType,\n getDisplayTimestamp,\n handleExportOrDisplay,\n isCodeSnippetLine,\n isConsoleTypeLine,\n isStackTraceLine,\n JEST_PATTERNS,\n logWarning,\n parseExportCliArgs,\n runJest,\n shouldShowUI,\n stripAnsi,\n validateCliArgs,\n VALID_MODES,\n} from \"../core\";\n\ntype ParsedWarning = {\n type: string;\n testFile: string;\n messages: string[];\n};\n\nfunction parseConsoleWarnings(rawOutput: string): ParsedWarning[] {\n const lines = rawOutput.split(\"\\n\");\n const warnings: ParsedWarning[] = [];\n\n const state: {\n currentTestFile: string | null;\n currentWarning: ParsedWarning | null;\n pendingWarnings: ParsedWarning[];\n } = {\n currentTestFile: null,\n currentWarning: null,\n pendingWarnings: [],\n };\n\n const flushCurrentWarning = () => {\n if (!state.currentWarning) return;\n\n if (state.currentWarning.testFile === \"unknown\" && state.currentTestFile) {\n state.currentWarning.testFile = state.currentTestFile;\n }\n\n warnings.push(state.currentWarning);\n state.pendingWarnings.push(state.currentWarning);\n state.currentWarning = null;\n };\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n if (JEST_PATTERNS.TEST_FILE.test(trimmed)) {\n const match = trimmed.match(JEST_PATTERNS.TEST_FILE);\n if (match) {\n state.currentTestFile = path.basename(match[2]);\n for (const warning of state.pendingWarnings) {\n if (warning.testFile === \"unknown\") warning.testFile = state.currentTestFile;\n }\n }\n flushCurrentWarning();\n continue;\n }\n\n if (trimmed === \"● Console\") {\n continue;\n }\n\n if (isConsoleTypeLine(line)) {\n flushCurrentWarning();\n state.currentWarning = {\n type: extractConsoleType(line) ?? \"console.warn\",\n testFile: state.currentTestFile ?? \"unknown\",\n messages: [],\n };\n continue;\n }\n\n if (!state.currentWarning) continue;\n if (isCodeSnippetLine(line)) continue;\n if (isStackTraceLine(line)) continue;\n\n const cleanMessage = stripAnsi(line).trim();\n if (cleanMessage.length > 0) {\n state.currentWarning.messages.push(cleanMessage);\n }\n }\n\n flushCurrentWarning();\n\n return warnings;\n}\n\nfunction filterWarningsByType(warnings: ParsedWarning[], filter: \"errors\" | \"warns\" | null): ParsedWarning[] {\n if (filter === \"errors\") {\n return warnings.filter((w) => w.type === CONSOLE_LOG_TYPES.ERROR);\n }\n if (filter === \"warns\") {\n return warnings.filter((w) => w.type === CONSOLE_LOG_TYPES.WARN);\n }\n\n return warnings;\n}\n\nfunction groupByTestFile(warnings: ParsedWarning[]): Record<string, ParsedWarning[]> {\n const grouped: Record<string, ParsedWarning[]> = {};\n\n for (const warning of warnings) {\n const file = warning.testFile;\n if (!grouped[file]) grouped[file] = [];\n grouped[file].push(warning);\n }\n\n return grouped;\n}\n\nfunction sortFilesByWarningCount(grouped: Record<string, ParsedWarning[]>): Array<[string, ParsedWarning[]]> {\n const entries = Object.entries(grouped);\n entries.sort((a, b) => b[1].length - a[1].length);\n\n return entries;\n}\n\nfunction formatWarningsOutput(\n grouped: Record<string, ParsedWarning[]>,\n timestamp: string,\n stats: { total: number; byType: Record<string, number> }\n): string {\n const lines: string[] = [];\n lines.push(\"=== CONSOLE WARNINGS CONTEXT BEGIN ===\", \"\", `📅 Run Date: ${timestamp}`, \"\");\n\n const sortedEntries = sortFilesByWarningCount(grouped);\n const totalFiles = sortedEntries.length;\n\n if (totalFiles === 0) {\n lines.push(\"✅ No console warnings found!\");\n } else {\n lines.push(\n `⚠️ Found ${stats.total} warning(s) in ${totalFiles} test file(s)`,\n \"\",\n \"📊 Summary by Type:\",\n ` - console.error: ${stats.byType[CONSOLE_LOG_TYPES.ERROR] ?? 0} occurrence(s)`,\n ` - console.warn: ${stats.byType[CONSOLE_LOG_TYPES.WARN] ?? 0} occurrence(s)`,\n \"\",\n \"=\".repeat(60),\n \"\"\n );\n\n for (const [file, warnings] of sortedEntries) {\n lines.push(`📄 File: ${file}`, ` Total Warnings: ${warnings.length}`, \"\");\n\n warnings.forEach((warning, idx) => {\n lines.push(` ${idx + 1}. ${warning.type}`, \"\");\n\n if (warning.messages.length > 0) {\n lines.push(\" 📝 Message:\");\n warning.messages.forEach((msg) => lines.push(` ${msg}`));\n lines.push(\"\");\n }\n\n if (idx < warnings.length - 1) {\n lines.push(\" \" + \"-\".repeat(50), \"\");\n }\n });\n\n lines.push(\"=\".repeat(60), \"\");\n }\n }\n\n lines.push(\"=== CONSOLE WARNINGS CONTEXT END ===\");\n\n return `${lines.join(\"\\n\")}\\n`;\n}\n\nfunction calculateStatistics(warnings: ParsedWarning[]) {\n const stats = {\n total: warnings.length,\n byType: {\n [CONSOLE_LOG_TYPES.ERROR]: 0,\n [CONSOLE_LOG_TYPES.WARN]: 0,\n },\n };\n\n for (const warning of warnings) {\n if (warning.type === CONSOLE_LOG_TYPES.ERROR) {\n stats.byType[CONSOLE_LOG_TYPES.ERROR]++;\n } else if (warning.type === CONSOLE_LOG_TYPES.WARN) {\n stats.byType[CONSOLE_LOG_TYPES.WARN]++;\n }\n }\n\n return stats;\n}\n\nexport async function runConsoleContext(argv = process.argv.slice(2)): Promise<void> {\n if (argv.includes(\"-h\") || argv.includes(\"--help\")) {\n displayHelp(\"Console Context Script\", {\n description: \"Capture and format console warnings/errors from Jest output.\",\n usage: [\n \"console-context -- --all\",\n \"console-context -- --related\",\n \"console-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 \"--only-errors Show only console.error warnings\",\n \"--only-warns Show only console.warn warnings\",\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: [\n \"console-context -- --related --only-errors\",\n \"console-context -- --all --export=md\",\n ],\n });\n }\n\n const noBanner = argv.includes(\"--no-banner\");\n const args = argv.filter((arg) => arg !== \"--no-banner\");\n\n const { exportFormat, exportArgs } = parseExportCliArgs(args);\n const { parsed, unknownArgs } = validateCliArgs(args, {\n mode: {\n values: [...VALID_MODES],\n default: \"--all\",\n exclusive: true,\n },\n filter: {\n values: [\"--only-errors\", \"--only-warns\"],\n exclusive: true,\n },\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 mode = parsed.mode ?? \"--all\";\n const filter = parsed.filter === \"--only-errors\" ? \"errors\" : parsed.filter === \"--only-warns\" ? \"warns\" : null;\n\n const showUI = shouldShowUI(exportFormat, noBanner);\n if (showUI) {\n displayBanner({\n text: \"CONSOLE\",\n subtitle: \"WARNINGS\",\n info: {\n Mode: mode,\n Filter: filter ?? \"none\",\n },\n colors: [\"yellow\", \"red\"],\n });\n }\n\n const modeKey = mode.replace(\"--\", \"\") as \"all\" | \"related\" | \"tests\";\n\n let jestArgs: string[] = [];\n try {\n jestArgs = await buildJestArgsForMode(modeKey);\n } catch (error) {\n exitWithError((error as Error).message);\n }\n\n const spinner = showUI ? createSpinner(\"Capturing console warnings...\", \"yellow\") : null;\n spinner?.start();\n\n const result = await runJest(jestArgs, {\n disableVerbose: true,\n ignoreErrors: true,\n });\n\n let warnings = parseConsoleWarnings(result.output);\n warnings = filterWarningsByType(warnings, filter);\n\n if (spinner) {\n if (warnings.length > 0) {\n spinner.warn(`Found ${warnings.length} warning(s)`);\n } else {\n spinner.succeed(\"No console warnings found\");\n }\n }\n\n const grouped = groupByTestFile(warnings);\n const stats = calculateStatistics(warnings);\n const timestamp = getDisplayTimestamp();\n const formatted = formatWarningsOutput(grouped, timestamp, stats);\n\n handleExportOrDisplay(formatted, {\n exportFormat,\n prefix: \"export-console-context\",\n title: \"Console Warnings Context\",\n });\n}\n","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 ?? process.platform === \"win32\",\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 { getJestCommand, type PackageManager } from \"./package-manager\";\nimport { isWindows } from \"./platform\";\nimport { filterTestFiles, getStagedFiles } from \"./git\";\nimport type { ExecutionMode, ExecResult, RunJestOptions } from \"../types\";\n\nexport async function runJest(args: string[] = [], options: RunJestOptions = {}): Promise<ExecResult> {\n const {\n verbose = false,\n coverage = false,\n packageManager = null,\n ignoreErrors = true,\n disableVerbose = false,\n } = options;\n\n const jestCmd = getJestCommand(packageManager as PackageManager | null);\n const jestArgs = [...jestCmd.slice(1)];\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(jestCmd[0], jestArgs, {\n shell: isWindows(),\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 try {\n const cliProgress = require(\"cli-progress\") as {\n SingleBar: new (options: Record<string, unknown>, preset: unknown) => {\n start: (maxValue: number, startValue: number, payload?: Record<string, string>) => void;\n update: (value: number, payload?: Record<string, string>) => void;\n stop: () => void;\n };\n Presets: {\n shades_classic: unknown;\n };\n };\n\n const bar = new cliProgress.SingleBar(\n {\n format: \"{task} [{bar}] {percentage}% | {status}\",\n barCompleteChar: \"█\",\n barIncompleteChar: \"░\",\n hideCursor: true,\n barsize: 24,\n },\n cliProgress.Presets.shades_classic\n );\n\n bar.start(total, 0, {\n task,\n status: \"Starting...\",\n });\n\n return {\n update: (value: number, payload?: Record<string, string>) => bar.update(value, payload),\n stop: () => bar.stop(),\n };\n } catch {\n if (!hasWarnedProgressFallback) {\n hasWarnedProgressFallback = true;\n console.warn(\"Warning: progress bar UI unavailable, continuing without progress bar.\");\n }\n\n return NOOP_PROGRESS_BAR;\n }\n}\n","#!/usr/bin/env node\n\nimport { runConsoleContext } from \"../commands/console-context\";\n\nrunConsoleContext().catch((error) => {\n console.error(`❌ ${(error as Error).message}`);\n process.exit(1);\n});\n"],"mappings":"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","names":["import_node_path","import_node_child_process","path","path"]}
1
+ {"version":3,"sources":["../../src/commands/console-context.ts","../../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","../../src/bin/console-context.ts"],"sourcesContent":["import path from \"node:path\";\n\nimport {\n buildJestArgsForMode,\n CONSOLE_LOG_TYPES,\n createSpinner,\n displayBanner,\n displayHelp,\n exitWithError,\n extractConsoleType,\n getDisplayTimestamp,\n handleExportOrDisplay,\n isCodeSnippetLine,\n isConsoleTypeLine,\n isStackTraceLine,\n JEST_PATTERNS,\n logWarning,\n parseExportCliArgs,\n runJest,\n shouldShowUI,\n stripAnsi,\n validateCliArgs,\n VALID_MODES,\n} from \"../core\";\n\ntype ParsedWarning = {\n type: string;\n testFile: string;\n messages: string[];\n};\n\nfunction parseConsoleWarnings(rawOutput: string): ParsedWarning[] {\n const lines = rawOutput.split(\"\\n\");\n const warnings: ParsedWarning[] = [];\n\n const state: {\n currentTestFile: string | null;\n currentWarning: ParsedWarning | null;\n pendingWarnings: ParsedWarning[];\n } = {\n currentTestFile: null,\n currentWarning: null,\n pendingWarnings: [],\n };\n\n const flushCurrentWarning = () => {\n if (!state.currentWarning) return;\n\n if (state.currentWarning.testFile === \"unknown\" && state.currentTestFile) {\n state.currentWarning.testFile = state.currentTestFile;\n }\n\n warnings.push(state.currentWarning);\n state.pendingWarnings.push(state.currentWarning);\n state.currentWarning = null;\n };\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n if (JEST_PATTERNS.TEST_FILE.test(trimmed)) {\n const match = trimmed.match(JEST_PATTERNS.TEST_FILE);\n if (match) {\n state.currentTestFile = path.basename(match[2]);\n for (const warning of state.pendingWarnings) {\n if (warning.testFile === \"unknown\") warning.testFile = state.currentTestFile;\n }\n }\n flushCurrentWarning();\n continue;\n }\n\n if (trimmed === \"● Console\") {\n continue;\n }\n\n if (isConsoleTypeLine(line)) {\n flushCurrentWarning();\n state.currentWarning = {\n type: extractConsoleType(line) ?? \"console.warn\",\n testFile: state.currentTestFile ?? \"unknown\",\n messages: [],\n };\n continue;\n }\n\n if (!state.currentWarning) continue;\n if (isCodeSnippetLine(line)) continue;\n if (isStackTraceLine(line)) continue;\n\n const cleanMessage = stripAnsi(line).trim();\n if (cleanMessage.length > 0) {\n state.currentWarning.messages.push(cleanMessage);\n }\n }\n\n flushCurrentWarning();\n\n return warnings;\n}\n\nfunction filterWarningsByType(warnings: ParsedWarning[], filter: \"errors\" | \"warns\" | null): ParsedWarning[] {\n if (filter === \"errors\") {\n return warnings.filter((w) => w.type === CONSOLE_LOG_TYPES.ERROR);\n }\n if (filter === \"warns\") {\n return warnings.filter((w) => w.type === CONSOLE_LOG_TYPES.WARN);\n }\n\n return warnings;\n}\n\nfunction groupByTestFile(warnings: ParsedWarning[]): Record<string, ParsedWarning[]> {\n const grouped: Record<string, ParsedWarning[]> = {};\n\n for (const warning of warnings) {\n const file = warning.testFile;\n if (!grouped[file]) grouped[file] = [];\n grouped[file].push(warning);\n }\n\n return grouped;\n}\n\nfunction sortFilesByWarningCount(grouped: Record<string, ParsedWarning[]>): Array<[string, ParsedWarning[]]> {\n const entries = Object.entries(grouped);\n entries.sort((a, b) => b[1].length - a[1].length);\n\n return entries;\n}\n\nfunction formatWarningsOutput(\n grouped: Record<string, ParsedWarning[]>,\n timestamp: string,\n stats: { total: number; byType: Record<string, number> }\n): string {\n const lines: string[] = [];\n lines.push(\"=== CONSOLE WARNINGS CONTEXT BEGIN ===\", \"\", `📅 Run Date: ${timestamp}`, \"\");\n\n const sortedEntries = sortFilesByWarningCount(grouped);\n const totalFiles = sortedEntries.length;\n\n if (totalFiles === 0) {\n lines.push(\"✅ No console warnings found!\");\n } else {\n lines.push(\n `⚠️ Found ${stats.total} warning(s) in ${totalFiles} test file(s)`,\n \"\",\n \"📊 Summary by Type:\",\n ` - console.error: ${stats.byType[CONSOLE_LOG_TYPES.ERROR] ?? 0} occurrence(s)`,\n ` - console.warn: ${stats.byType[CONSOLE_LOG_TYPES.WARN] ?? 0} occurrence(s)`,\n \"\",\n \"=\".repeat(60),\n \"\"\n );\n\n for (const [file, warnings] of sortedEntries) {\n lines.push(`📄 File: ${file}`, ` Total Warnings: ${warnings.length}`, \"\");\n\n warnings.forEach((warning, idx) => {\n lines.push(` ${idx + 1}. ${warning.type}`, \"\");\n\n if (warning.messages.length > 0) {\n lines.push(\" 📝 Message:\");\n warning.messages.forEach((msg) => lines.push(` ${msg}`));\n lines.push(\"\");\n }\n\n if (idx < warnings.length - 1) {\n lines.push(\" \" + \"-\".repeat(50), \"\");\n }\n });\n\n lines.push(\"=\".repeat(60), \"\");\n }\n }\n\n lines.push(\"=== CONSOLE WARNINGS CONTEXT END ===\");\n\n return `${lines.join(\"\\n\")}\\n`;\n}\n\nfunction calculateStatistics(warnings: ParsedWarning[]) {\n const stats = {\n total: warnings.length,\n byType: {\n [CONSOLE_LOG_TYPES.ERROR]: 0,\n [CONSOLE_LOG_TYPES.WARN]: 0,\n },\n };\n\n for (const warning of warnings) {\n if (warning.type === CONSOLE_LOG_TYPES.ERROR) {\n stats.byType[CONSOLE_LOG_TYPES.ERROR]++;\n } else if (warning.type === CONSOLE_LOG_TYPES.WARN) {\n stats.byType[CONSOLE_LOG_TYPES.WARN]++;\n }\n }\n\n return stats;\n}\n\nexport async function runConsoleContext(argv = process.argv.slice(2)): Promise<void> {\n if (argv.includes(\"-h\") || argv.includes(\"--help\")) {\n displayHelp(\"Console Context Script\", {\n description: \"Capture and format console warnings/errors from Jest output.\",\n usage: [\n \"console-context -- --all\",\n \"console-context -- --related\",\n \"console-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 \"--only-errors Show only console.error warnings\",\n \"--only-warns Show only console.warn warnings\",\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: [\n \"console-context -- --related --only-errors\",\n \"console-context -- --all --export=md\",\n ],\n });\n }\n\n const noBanner = argv.includes(\"--no-banner\");\n const args = argv.filter((arg) => arg !== \"--no-banner\");\n\n const { exportFormat, exportArgs } = parseExportCliArgs(args);\n const { parsed, unknownArgs } = validateCliArgs(args, {\n mode: {\n values: [...VALID_MODES],\n default: \"--all\",\n exclusive: true,\n },\n filter: {\n values: [\"--only-errors\", \"--only-warns\"],\n exclusive: true,\n },\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 mode = parsed.mode ?? \"--all\";\n const filter = parsed.filter === \"--only-errors\" ? \"errors\" : parsed.filter === \"--only-warns\" ? \"warns\" : null;\n\n const showUI = shouldShowUI(exportFormat, noBanner);\n if (showUI) {\n displayBanner({\n text: \"JEST\",\n subtitle: \"CONSOLE\",\n info: {\n Mode: mode,\n Filter: filter ?? \"none\",\n },\n colors: [\"yellow\", \"red\"],\n });\n }\n\n const modeKey = mode.replace(\"--\", \"\") as \"all\" | \"related\" | \"tests\";\n\n let jestArgs: string[] = [];\n try {\n jestArgs = await buildJestArgsForMode(modeKey);\n } catch (error) {\n exitWithError((error as Error).message);\n }\n\n const spinner = showUI ? createSpinner(\"Capturing console warnings...\", \"yellow\") : null;\n spinner?.start();\n\n const result = await runJest(jestArgs, {\n disableVerbose: true,\n ignoreErrors: true,\n });\n\n let warnings = parseConsoleWarnings(result.output);\n warnings = filterWarningsByType(warnings, filter);\n\n if (spinner) {\n if (warnings.length > 0) {\n spinner.warn(`Found ${warnings.length} warning(s)`);\n } else {\n spinner.succeed(\"No console warnings found\");\n }\n }\n\n const grouped = groupByTestFile(warnings);\n const stats = calculateStatistics(warnings);\n const timestamp = getDisplayTimestamp();\n const formatted = formatWarningsOutput(grouped, timestamp, stats);\n\n handleExportOrDisplay(formatted, {\n exportFormat,\n prefix: \"export-console-context\",\n title: \"Console Warnings Context\",\n });\n}\n","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\";\n\nimport { getJestCommand, type PackageManager } from \"./package-manager\";\nimport { isWindows, resolveCommand } from \"./platform\";\nimport { filterTestFiles, getStagedFiles } from \"./git\";\nimport type { ExecutionMode, ExecResult, RunJestOptions } from \"../types\";\n\nexport async function runJest(args: string[] = [], options: RunJestOptions = {}): Promise<ExecResult> {\n const {\n verbose = false,\n coverage = false,\n packageManager = null,\n ignoreErrors = true,\n disableVerbose = false,\n } = options;\n\n const jestCmd = getJestCommand(packageManager as PackageManager | null);\n const command = resolveCommand(jestCmd[0]);\n const jestArgs = [...jestCmd.slice(1)];\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","#!/usr/bin/env node\n\nimport { runConsoleContext } from \"../commands/console-context\";\n\nrunConsoleContext().catch((error) => {\n console.error(`❌ ${(error as Error).message}`);\n process.exit(1);\n});\n"],"mappings":"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","names":["import_node_path","import_node_child_process","path","path"]}
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runConsoleContext
4
- } from "../chunk-27OKLHXI.mjs";
5
- import "../chunk-Z3YG7H6H.mjs";
4
+ } from "../chunk-RCPJ7B43.mjs";
5
+ import "../chunk-GV4AYRBZ.mjs";
6
6
 
7
7
  // src/bin/console-context.ts
8
8
  runConsoleContext().catch((error) => {
@@ -42,6 +42,18 @@ var JEST_PATTERNS = {
42
42
  function isWindows() {
43
43
  return process.platform === "win32";
44
44
  }
45
+ function resolveCommand(cmd) {
46
+ if (!isWindows()) return cmd;
47
+ const windowsCommands = {
48
+ git: "git.exe",
49
+ node: "node.exe",
50
+ npm: "npm.cmd",
51
+ npx: "npx.cmd",
52
+ yarn: "yarn.cmd",
53
+ pnpm: "pnpm.cmd"
54
+ };
55
+ return windowsCommands[cmd] ?? cmd;
56
+ }
45
57
 
46
58
  // src/core/package-manager.ts
47
59
  function detectPackageManager() {
@@ -75,6 +87,7 @@ async function runJest(args = [], options = {}) {
75
87
  disableVerbose = false
76
88
  } = options;
77
89
  const jestCmd = getJestCommand(packageManager);
90
+ const command = resolveCommand(jestCmd[0]);
78
91
  const jestArgs = [...jestCmd.slice(1)];
79
92
  if (verbose && !disableVerbose) {
80
93
  jestArgs.push("--verbose");
@@ -92,8 +105,8 @@ async function runJest(args = [], options = {}) {
92
105
  }
93
106
  jestArgs.push(...args);
94
107
  return new Promise((resolve, reject) => {
95
- const child = (0, import_node_child_process2.spawn)(jestCmd[0], jestArgs, {
96
- shell: isWindows()
108
+ const child = (0, import_node_child_process2.spawn)(command, jestArgs, {
109
+ shell: false
97
110
  });
98
111
  let stdout = "";
99
112
  let stderr = "";
@@ -272,13 +285,7 @@ function logWarning(message) {
272
285
  }
273
286
 
274
287
  // src/core/ui.ts
275
- var NOOP_PROGRESS_BAR = {
276
- update: () => {
277
- },
278
- stop: () => {
279
- }
280
- };
281
- var hasWarnedProgressFallback = false;
288
+ var hasWarnedSpinnerFallback = false;
282
289
  function shouldShowUI(exportMode, noBanner = false) {
283
290
  return !exportMode && !noBanner && Boolean(process.stdout.isTTY);
284
291
  }
@@ -323,35 +330,31 @@ function displayBanner(config) {
323
330
  });
324
331
  console.log(boxed);
325
332
  }
326
- function createProgressBar(total = 100, task = "Progress") {
333
+ function createSpinner(text, color = "cyan") {
327
334
  try {
328
- const cliProgress = require("cli-progress");
329
- const bar = new cliProgress.SingleBar(
330
- {
331
- format: "{task} [{bar}] {percentage}% | {status}",
332
- barCompleteChar: "\u2588",
333
- barIncompleteChar: "\u2591",
334
- hideCursor: true,
335
- barsize: 24
336
- },
337
- cliProgress.Presets.shades_classic
338
- );
339
- bar.start(total, 0, {
340
- task,
341
- status: "Starting..."
342
- });
343
- return {
344
- update: (value, payload) => bar.update(value, payload),
345
- stop: () => bar.stop()
346
- };
335
+ const ora = require("ora");
336
+ return ora({ text, color, spinner: "dots" });
347
337
  } catch {
348
- if (!hasWarnedProgressFallback) {
349
- hasWarnedProgressFallback = true;
350
- console.warn("Warning: progress bar UI unavailable, continuing without progress bar.");
338
+ if (!hasWarnedSpinnerFallback) {
339
+ hasWarnedSpinnerFallback = true;
340
+ console.warn("Warning: spinner UI unavailable, continuing without spinner.");
351
341
  }
352
- return NOOP_PROGRESS_BAR;
342
+ return {
343
+ start: () => NOOP_SPINNER,
344
+ stop: () => NOOP_SPINNER,
345
+ succeed: () => NOOP_SPINNER,
346
+ warn: () => NOOP_SPINNER,
347
+ fail: () => NOOP_SPINNER
348
+ };
353
349
  }
354
350
  }
351
+ var NOOP_SPINNER = {
352
+ start: () => NOOP_SPINNER,
353
+ stop: () => NOOP_SPINNER,
354
+ succeed: () => NOOP_SPINNER,
355
+ warn: () => NOOP_SPINNER,
356
+ fail: () => NOOP_SPINNER
357
+ };
355
358
 
356
359
  // src/commands/coverage-context.ts
357
360
  function parseCoverage(text) {
@@ -457,25 +460,24 @@ async function runCoverageContext(argv = process.argv.slice(2)) {
457
460
  const showUI = shouldShowUI(exportFormat, noBanner);
458
461
  if (showUI) {
459
462
  displayBanner({
460
- text: "COVERAGE",
463
+ text: "JEST",
464
+ subtitle: "COVERAGE",
461
465
  info: {
462
466
  Threshold: `>=${threshold}%`
463
467
  },
464
468
  colors: ["magenta", "blue"]
465
469
  });
466
470
  }
467
- const bar = showUI ? createProgressBar(100, "Running coverage") : null;
468
- bar?.update(10, { status: "Running Jest..." });
471
+ const spinner = showUI ? createSpinner("Running Jest coverage...", "magenta") : null;
472
+ spinner?.start();
469
473
  const result = await runJest([], {
470
474
  coverage: true,
471
475
  coverageReporters: ["text", "text-summary"],
472
476
  ignoreErrors: true
473
477
  });
474
- bar?.update(70, { status: "Parsing output..." });
475
478
  const rows = parseCoverage(result.output);
476
479
  if (rows.length === 0) {
477
- bar?.update(100, { status: "Done" });
478
- bar?.stop();
480
+ spinner?.warn("No coverage rows parsed");
479
481
  handleExportOrDisplay("No coverage rows parsed from Jest output.", {
480
482
  exportFormat,
481
483
  prefix: "export-coverage-context",
@@ -485,9 +487,8 @@ async function runCoverageContext(argv = process.argv.slice(2)) {
485
487
  }
486
488
  const incomplete = filterIncomplete(rows, threshold);
487
489
  const grouped = groupByFolder(incomplete);
488
- bar?.update(100, { status: "Done" });
489
- bar?.stop();
490
490
  if (Object.keys(grouped).length === 0) {
491
+ spinner?.succeed(`All files meet threshold >= ${threshold}%`);
491
492
  handleExportOrDisplay(`All files meet threshold >= ${threshold}%`, {
492
493
  exportFormat,
493
494
  prefix: "export-coverage-context",
@@ -496,6 +497,7 @@ async function runCoverageContext(argv = process.argv.slice(2)) {
496
497
  return;
497
498
  }
498
499
  const formatted = formatCoverageOutput(grouped);
500
+ spinner?.warn(`Found ${incomplete.length} file(s) below threshold`);
499
501
  handleExportOrDisplay(formatted, {
500
502
  exportFormat,
501
503
  prefix: "export-coverage-context",