lacuna-cli 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/README.md +451 -0
  2. package/bin/run.js +5 -0
  3. package/dist/agent/context.d.ts +25 -0
  4. package/dist/agent/context.d.ts.map +1 -0
  5. package/dist/agent/context.js +366 -0
  6. package/dist/agent/context.js.map +1 -0
  7. package/dist/agent/fix-loop.d.ts +20 -0
  8. package/dist/agent/fix-loop.d.ts.map +1 -0
  9. package/dist/agent/fix-loop.js +466 -0
  10. package/dist/agent/fix-loop.js.map +1 -0
  11. package/dist/agent/generator.d.ts +35 -0
  12. package/dist/agent/generator.d.ts.map +1 -0
  13. package/dist/agent/generator.js +220 -0
  14. package/dist/agent/generator.js.map +1 -0
  15. package/dist/agent/loop.d.ts +23 -0
  16. package/dist/agent/loop.d.ts.map +1 -0
  17. package/dist/agent/loop.js +394 -0
  18. package/dist/agent/loop.js.map +1 -0
  19. package/dist/agent/project-memory.d.ts +10 -0
  20. package/dist/agent/project-memory.d.ts.map +1 -0
  21. package/dist/agent/project-memory.js +57 -0
  22. package/dist/agent/project-memory.js.map +1 -0
  23. package/dist/agent/prompts.d.ts +44 -0
  24. package/dist/agent/prompts.d.ts.map +1 -0
  25. package/dist/agent/prompts.js +377 -0
  26. package/dist/agent/prompts.js.map +1 -0
  27. package/dist/ci/comment.d.ts +2 -0
  28. package/dist/ci/comment.d.ts.map +1 -0
  29. package/dist/ci/comment.js +97 -0
  30. package/dist/ci/comment.js.map +1 -0
  31. package/dist/ci/parse-outputs.d.ts +2 -0
  32. package/dist/ci/parse-outputs.d.ts.map +1 -0
  33. package/dist/ci/parse-outputs.js +30 -0
  34. package/dist/ci/parse-outputs.js.map +1 -0
  35. package/dist/commands/analyze.d.ts +13 -0
  36. package/dist/commands/analyze.d.ts.map +1 -0
  37. package/dist/commands/analyze.js +151 -0
  38. package/dist/commands/analyze.js.map +1 -0
  39. package/dist/commands/fix.d.ts +15 -0
  40. package/dist/commands/fix.d.ts.map +1 -0
  41. package/dist/commands/fix.js +106 -0
  42. package/dist/commands/fix.js.map +1 -0
  43. package/dist/commands/generate.d.ts +18 -0
  44. package/dist/commands/generate.d.ts.map +1 -0
  45. package/dist/commands/generate.js +129 -0
  46. package/dist/commands/generate.js.map +1 -0
  47. package/dist/commands/init.d.ts +7 -0
  48. package/dist/commands/init.d.ts.map +1 -0
  49. package/dist/commands/init.js +131 -0
  50. package/dist/commands/init.js.map +1 -0
  51. package/dist/commands/run.d.ts +10 -0
  52. package/dist/commands/run.d.ts.map +1 -0
  53. package/dist/commands/run.js +45 -0
  54. package/dist/commands/run.js.map +1 -0
  55. package/dist/lib/config.d.ts +58 -0
  56. package/dist/lib/config.d.ts.map +1 -0
  57. package/dist/lib/config.js +68 -0
  58. package/dist/lib/config.js.map +1 -0
  59. package/dist/lib/coverage/gaps.d.ts +12 -0
  60. package/dist/lib/coverage/gaps.d.ts.map +1 -0
  61. package/dist/lib/coverage/gaps.js +186 -0
  62. package/dist/lib/coverage/gaps.js.map +1 -0
  63. package/dist/lib/coverage/index.d.ts +7 -0
  64. package/dist/lib/coverage/index.d.ts.map +1 -0
  65. package/dist/lib/coverage/index.js +24 -0
  66. package/dist/lib/coverage/index.js.map +1 -0
  67. package/dist/lib/coverage/json.d.ts +3 -0
  68. package/dist/lib/coverage/json.d.ts.map +1 -0
  69. package/dist/lib/coverage/json.js +24 -0
  70. package/dist/lib/coverage/json.js.map +1 -0
  71. package/dist/lib/coverage/lcov.d.ts +3 -0
  72. package/dist/lib/coverage/lcov.d.ts.map +1 -0
  73. package/dist/lib/coverage/lcov.js +58 -0
  74. package/dist/lib/coverage/lcov.js.map +1 -0
  75. package/dist/lib/coverage/types.d.ts +27 -0
  76. package/dist/lib/coverage/types.d.ts.map +1 -0
  77. package/dist/lib/coverage/types.js +2 -0
  78. package/dist/lib/coverage/types.js.map +1 -0
  79. package/dist/lib/coverage-spinner.d.ts +6 -0
  80. package/dist/lib/coverage-spinner.d.ts.map +1 -0
  81. package/dist/lib/coverage-spinner.js +101 -0
  82. package/dist/lib/coverage-spinner.js.map +1 -0
  83. package/dist/lib/detector.d.ts +13 -0
  84. package/dist/lib/detector.d.ts.map +1 -0
  85. package/dist/lib/detector.js +106 -0
  86. package/dist/lib/detector.js.map +1 -0
  87. package/dist/lib/extract-error.d.ts +2 -0
  88. package/dist/lib/extract-error.d.ts.map +1 -0
  89. package/dist/lib/extract-error.js +116 -0
  90. package/dist/lib/extract-error.js.map +1 -0
  91. package/dist/lib/providers/anthropic.d.ts +8 -0
  92. package/dist/lib/providers/anthropic.d.ts.map +1 -0
  93. package/dist/lib/providers/anthropic.js +38 -0
  94. package/dist/lib/providers/anthropic.js.map +1 -0
  95. package/dist/lib/providers/index.d.ts +6 -0
  96. package/dist/lib/providers/index.d.ts.map +1 -0
  97. package/dist/lib/providers/index.js +27 -0
  98. package/dist/lib/providers/index.js.map +1 -0
  99. package/dist/lib/providers/openai-compatible.d.ts +11 -0
  100. package/dist/lib/providers/openai-compatible.d.ts.map +1 -0
  101. package/dist/lib/providers/openai-compatible.js +93 -0
  102. package/dist/lib/providers/openai-compatible.js.map +1 -0
  103. package/dist/lib/providers/types.d.ts +17 -0
  104. package/dist/lib/providers/types.d.ts.map +1 -0
  105. package/dist/lib/providers/types.js +97 -0
  106. package/dist/lib/providers/types.js.map +1 -0
  107. package/dist/lib/report-upload.d.ts +3 -0
  108. package/dist/lib/report-upload.d.ts.map +1 -0
  109. package/dist/lib/report-upload.js +15 -0
  110. package/dist/lib/report-upload.js.map +1 -0
  111. package/dist/lib/reporter.d.ts +51 -0
  112. package/dist/lib/reporter.d.ts.map +1 -0
  113. package/dist/lib/reporter.js +172 -0
  114. package/dist/lib/reporter.js.map +1 -0
  115. package/dist/lib/runner.d.ts +9 -0
  116. package/dist/lib/runner.d.ts.map +1 -0
  117. package/dist/lib/runner.js +50 -0
  118. package/dist/lib/runner.js.map +1 -0
  119. package/dist/lib/skeleton.d.ts +8 -0
  120. package/dist/lib/skeleton.d.ts.map +1 -0
  121. package/dist/lib/skeleton.js +122 -0
  122. package/dist/lib/skeleton.js.map +1 -0
  123. package/dist/lib/streaming-viewer.d.ts +14 -0
  124. package/dist/lib/streaming-viewer.d.ts.map +1 -0
  125. package/dist/lib/streaming-viewer.js +80 -0
  126. package/dist/lib/streaming-viewer.js.map +1 -0
  127. package/dist/lib/tips.d.ts +16 -0
  128. package/dist/lib/tips.d.ts.map +1 -0
  129. package/dist/lib/tips.js +76 -0
  130. package/dist/lib/tips.js.map +1 -0
  131. package/dist/lib/typecheck.d.ts +3 -0
  132. package/dist/lib/typecheck.d.ts.map +1 -0
  133. package/dist/lib/typecheck.js +28 -0
  134. package/dist/lib/typecheck.js.map +1 -0
  135. package/dist/lib/validate.d.ts +7 -0
  136. package/dist/lib/validate.d.ts.map +1 -0
  137. package/dist/lib/validate.js +82 -0
  138. package/dist/lib/validate.js.map +1 -0
  139. package/dist/lib/worker-display.d.ts +45 -0
  140. package/dist/lib/worker-display.d.ts.map +1 -0
  141. package/dist/lib/worker-display.js +168 -0
  142. package/dist/lib/worker-display.js.map +1 -0
  143. package/oclif.manifest.json +295 -0
  144. package/package.json +62 -0
@@ -0,0 +1,97 @@
1
+ import { readFile } from 'fs/promises';
2
+ import { buildMarkdownReport } from '../lib/reporter.js';
3
+ const COMMENT_MARKER = '<!-- lacuna-coverage-report -->';
4
+ async function githubFetch(path, options = {}) {
5
+ const token = process.env.GITHUB_TOKEN;
6
+ if (!token)
7
+ throw new Error('GITHUB_TOKEN is not set');
8
+ return fetch(`https://api.github.com${path}`, {
9
+ ...options,
10
+ headers: {
11
+ Authorization: `Bearer ${token}`,
12
+ Accept: 'application/vnd.github+json',
13
+ 'X-GitHub-Api-Version': '2022-11-28',
14
+ 'Content-Type': 'application/json',
15
+ ...(options.headers ?? {}),
16
+ },
17
+ });
18
+ }
19
+ async function findExistingComment(repo, prNumber) {
20
+ const res = await githubFetch(`/repos/${repo}/issues/${prNumber}/comments?per_page=100`);
21
+ if (!res.ok)
22
+ return null;
23
+ const comments = (await res.json());
24
+ const existing = comments.find((c) => c.body.includes(COMMENT_MARKER));
25
+ return existing?.id ?? null;
26
+ }
27
+ async function upsertComment(repo, prNumber, body) {
28
+ const existingId = await findExistingComment(repo, prNumber);
29
+ if (existingId) {
30
+ await githubFetch(`/repos/${repo}/issues/comments/${existingId}`, {
31
+ method: 'PATCH',
32
+ body: JSON.stringify({ body }),
33
+ });
34
+ console.log(`Updated existing PR comment #${existingId}`);
35
+ }
36
+ else {
37
+ await githubFetch(`/repos/${repo}/issues/${prNumber}/comments`, {
38
+ method: 'POST',
39
+ body: JSON.stringify({ body }),
40
+ });
41
+ console.log('Posted new PR comment');
42
+ }
43
+ }
44
+ async function main() {
45
+ const repo = process.env.GITHUB_REPOSITORY;
46
+ const prNumber = process.env.GITHUB_PR_NUMBER;
47
+ const reportFile = process.env.LACUNA_REPORT_FILE ?? 'lacuna-report.json';
48
+ if (!repo || !prNumber) {
49
+ console.log('Not a PR context — skipping comment.');
50
+ return;
51
+ }
52
+ let report;
53
+ try {
54
+ const raw = await readFile(reportFile, 'utf-8');
55
+ report = JSON.parse(raw);
56
+ }
57
+ catch {
58
+ console.error(`Could not read ${reportFile}`);
59
+ process.exit(1);
60
+ }
61
+ const coverage = report.coverage;
62
+ const threshold = report.threshold ?? 80;
63
+ const input = {
64
+ type: report.type,
65
+ threshold,
66
+ untouchedCount: report.untouchedCount ?? 0,
67
+ generate: report.type === 'generate'
68
+ ? {
69
+ filesProcessed: report.filesProcessed ?? 0,
70
+ testsWritten: report.testsWritten ?? 0,
71
+ coverageBefore: coverage?.before ?? 0,
72
+ coverageAfter: coverage?.after ?? 0,
73
+ hasCoverage: coverage?.before !== undefined,
74
+ errors: report.errors ?? [],
75
+ }
76
+ : undefined,
77
+ analyze: report.type === 'analyze'
78
+ ? {
79
+ testRunner: report.testRunner ?? '',
80
+ language: report.language ?? '',
81
+ threshold,
82
+ coveragePct: coverage?.lines ?? 0,
83
+ functionCoveragePct: coverage?.functions ?? 0,
84
+ gaps: [],
85
+ untouchedCount: 0,
86
+ passed: report.passed ?? false,
87
+ }
88
+ : undefined,
89
+ };
90
+ const markdown = COMMENT_MARKER + '\n' + buildMarkdownReport(input);
91
+ await upsertComment(repo, prNumber, markdown);
92
+ }
93
+ main().catch((err) => {
94
+ console.error('Failed to post comment:', err.message);
95
+ process.exit(1);
96
+ });
97
+ //# sourceMappingURL=comment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comment.js","sourceRoot":"","sources":["../../src/ci/comment.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=parse-outputs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-outputs.d.ts","sourceRoot":"","sources":["../../src/ci/parse-outputs.ts"],"names":[],"mappings":""}
@@ -0,0 +1,30 @@
1
+ import { readFile, appendFile } from 'fs/promises';
2
+ async function main() {
3
+ const reportPath = process.env.LACUNA_REPORT_FILE ?? 'lacuna-report.json';
4
+ const outputFile = process.env.GITHUB_OUTPUT;
5
+ let report;
6
+ try {
7
+ const raw = await readFile(reportPath, 'utf-8');
8
+ report = JSON.parse(raw);
9
+ }
10
+ catch {
11
+ console.error(`Could not read ${reportPath}`);
12
+ process.exit(1);
13
+ }
14
+ const coverage = report.coverage;
15
+ const before = coverage?.before ?? coverage?.lines ?? 0;
16
+ const after = coverage?.after ?? coverage?.lines ?? 0;
17
+ const passed = report.passed ? 'true' : 'false';
18
+ if (outputFile) {
19
+ await appendFile(outputFile, `coverage-before=${before.toFixed(1)}\n`);
20
+ await appendFile(outputFile, `coverage-after=${after.toFixed(1)}\n`);
21
+ await appendFile(outputFile, `passed=${passed}\n`);
22
+ }
23
+ else {
24
+ console.log(`coverage-before=${before.toFixed(1)}`);
25
+ console.log(`coverage-after=${after.toFixed(1)}`);
26
+ console.log(`passed=${passed}`);
27
+ }
28
+ }
29
+ main();
30
+ //# sourceMappingURL=parse-outputs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-outputs.js","sourceRoot":"","sources":["../../src/ci/parse-outputs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAElD,KAAK,UAAU,IAAI;IACjB,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,oBAAoB,CAAA;IACzE,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAA;IAE5C,IAAI,MAA+B,CAAA;IACnC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAA;QAC/C,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,KAAK,CAAC,kBAAkB,UAAU,EAAE,CAAC,CAAA;QAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,CAAC,QAA8C,CAAA;IACtE,MAAM,MAAM,GAAG,QAAQ,EAAE,MAAM,IAAI,QAAQ,EAAE,KAAK,IAAI,CAAC,CAAA;IACvD,MAAM,KAAK,GAAG,QAAQ,EAAE,KAAK,IAAI,QAAQ,EAAE,KAAK,IAAI,CAAC,CAAA;IACrD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAA;IAE/C,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,UAAU,CAAC,UAAU,EAAE,mBAAmB,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;QACtE,MAAM,UAAU,CAAC,UAAU,EAAE,kBAAkB,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;QACpE,MAAM,UAAU,CAAC,UAAU,EAAE,UAAU,MAAM,IAAI,CAAC,CAAA;IACpD,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,mBAAmB,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;QACnD,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;QACjD,OAAO,CAAC,GAAG,CAAC,UAAU,MAAM,EAAE,CAAC,CAAA;IACjC,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAA"}
@@ -0,0 +1,13 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class Analyze extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ threshold: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
+ format: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
8
+ output: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
+ verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
+ };
11
+ run(): Promise<void>;
12
+ }
13
+ //# sourceMappingURL=analyze.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyze.d.ts","sourceRoot":"","sources":["../../src/commands/analyze.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAS,MAAM,aAAa,CAAA;AAW5C,MAAM,CAAC,OAAO,OAAO,OAAQ,SAAQ,OAAO;IAC1C,MAAM,CAAC,WAAW,SAA+D;IAEjF,MAAM,CAAC,QAAQ,WAKd;IAED,MAAM,CAAC,KAAK;;;;;MAoBX;IAEK,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAuH3B"}
@@ -0,0 +1,151 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import { writeFile } from 'fs/promises';
3
+ import chalk from 'chalk';
4
+ import { loadConfig } from '../lib/config.js';
5
+ import { detectEnvironment } from '../lib/detector.js';
6
+ import { runCommand } from '../lib/runner.js';
7
+ import { startCoverageSpinner } from '../lib/coverage-spinner.js';
8
+ import { loadCoverage, extractGaps, filterTestableGaps, findUncoveredFiles } from '../lib/coverage/index.js';
9
+ import { reportTerminal, buildJsonReport, buildMarkdownReport, getExitCode } from '../lib/reporter.js';
10
+ export default class Analyze extends Command {
11
+ static description = 'Analyze test coverage and show gaps — no files are changed';
12
+ static examples = [
13
+ '$ lacuna analyze',
14
+ '$ lacuna analyze --threshold 90',
15
+ '$ lacuna analyze --format json',
16
+ '$ lacuna analyze --format markdown',
17
+ ];
18
+ static flags = {
19
+ threshold: Flags.integer({
20
+ char: 't',
21
+ description: 'Minimum coverage percentage',
22
+ }),
23
+ format: Flags.string({
24
+ char: 'F',
25
+ description: 'Output format',
26
+ options: ['terminal', 'json', 'markdown'],
27
+ default: 'terminal',
28
+ }),
29
+ output: Flags.string({
30
+ char: 'o',
31
+ description: 'Write report to file instead of stdout',
32
+ }),
33
+ verbose: Flags.boolean({
34
+ char: 'v',
35
+ description: 'Show uncovered line numbers per file',
36
+ default: false,
37
+ }),
38
+ };
39
+ async run() {
40
+ const { flags } = await this.parse(Analyze);
41
+ const config = await loadConfig();
42
+ const env = await detectEnvironment(process.cwd(), config.testRunner);
43
+ const threshold = flags.threshold ?? config.threshold;
44
+ if (flags.format === 'terminal') {
45
+ this.log(chalk.bold('\nlacuna analyze\n'));
46
+ }
47
+ if (env.testRunner === 'unknown') {
48
+ this.warn('Could not detect test runner. Run `lacuna init` to configure.');
49
+ this.exit(2);
50
+ }
51
+ if (flags.format === 'terminal') {
52
+ this.log(`${chalk.dim('Detected:')} ${chalk.cyan(env.testRunner)} (${env.language})`);
53
+ this.log(`${chalk.dim('Threshold:')} ${threshold}%\n`);
54
+ }
55
+ const spinner = startCoverageSpinner(chalk.dim(` Running: ${env.coverageCommand}`), env.testRunner);
56
+ const result = await runCommand(env.coverageCommand, process.cwd(), config.coverageTimeout * 1000, spinner.onLine);
57
+ spinner.stop();
58
+ if (result.timedOut) {
59
+ this.log(chalk.red(`\nTest suite timed out after ${config.coverageTimeout}s.`));
60
+ this.log(chalk.yellow('\nThis usually means a test has an open handle (unclosed server, timer, or connection).'));
61
+ this.log(chalk.dim(`\nIncrease the timeout in .lacuna.json: { "coverageTimeout": ${config.coverageTimeout * 2} }`));
62
+ this.exit(2);
63
+ }
64
+ // only bail if literally zero tests ran (suites crashed on load)
65
+ const zeroTests = /Tests:\s+0 total|no tests found/i.test(result.stdout + result.stderr);
66
+ if (zeroTests) {
67
+ this.log(chalk.red('\nYour test suites are failing before any tests run.'));
68
+ this.log(chalk.yellow('\nThis usually means:'));
69
+ this.log(' • A missing environment variable (check .env / .env.test)');
70
+ this.log(' • A broken import or missing module');
71
+ this.log(' • A setup file failing (DB connection, mock config, etc.)\n');
72
+ this.log(chalk.dim('Run this to see the actual error:'));
73
+ this.log(chalk.cyan(` ${env.testCommand} 2>&1 | head -80`));
74
+ this.exit(2);
75
+ }
76
+ // partial failures are fine — coverage is still collected for passing tests
77
+ let report;
78
+ try {
79
+ report = await loadCoverage(config);
80
+ }
81
+ catch {
82
+ this.log(chalk.red(`Could not read coverage report from ./${config.coverageDir}/\n`));
83
+ this.log(chalk.yellow('Make sure your vitest config has coverage enabled:'));
84
+ this.log(chalk.dim(' // vitest.config.ts'));
85
+ this.log(chalk.dim(' test: { coverage: { reporter: ["lcov", "text-summary"] } }'));
86
+ this.exit(2);
87
+ }
88
+ const gaps = await filterTestableGaps(extractGaps(report, threshold), config.ignore);
89
+ // append files that never appeared in the coverage report (never imported by any test)
90
+ const untouchedFiles = await findUncoveredFiles(report, config.sourceDir, process.cwd(), config.ignore);
91
+ const existingPaths = new Set(gaps.map((g) => g.filePath));
92
+ let untouchedCount = 0;
93
+ for (const g of untouchedFiles) {
94
+ if (!existingPaths.has(g.filePath)) {
95
+ gaps.push(g);
96
+ untouchedCount++;
97
+ }
98
+ }
99
+ const coveragePct = report.totalLineRate * 100;
100
+ const functionCoveragePct = report.totalFunctionRate * 100;
101
+ const passed = coveragePct >= threshold;
102
+ const input = {
103
+ type: 'analyze',
104
+ threshold,
105
+ untouchedCount,
106
+ analyze: {
107
+ testRunner: env.testRunner,
108
+ language: env.language,
109
+ threshold,
110
+ coveragePct,
111
+ functionCoveragePct,
112
+ gaps,
113
+ untouchedCount,
114
+ passed,
115
+ },
116
+ };
117
+ if (flags.format === 'json') {
118
+ const out = JSON.stringify(buildJsonReport(input), null, 2);
119
+ if (flags.output) {
120
+ await writeFile(flags.output, out, 'utf-8');
121
+ this.log(`Report written to ${flags.output}`);
122
+ }
123
+ else {
124
+ this.log(out);
125
+ }
126
+ }
127
+ else if (flags.format === 'markdown') {
128
+ const out = buildMarkdownReport(input);
129
+ if (flags.output) {
130
+ await writeFile(flags.output, out, 'utf-8');
131
+ this.log(`Report written to ${flags.output}`);
132
+ }
133
+ else {
134
+ this.log(out);
135
+ }
136
+ }
137
+ else {
138
+ reportTerminal(input);
139
+ if (flags.verbose && gaps.length > 0) {
140
+ for (const gap of gaps) {
141
+ if (gap.uncoveredLines.length > 0) {
142
+ const short = gap.filePath.replace(process.cwd() + '/', '');
143
+ this.log(chalk.dim(` ${short} lines: ${gap.uncoveredLines.slice(0, 20).join(', ')}${gap.uncoveredLines.length > 20 ? '…' : ''}`));
144
+ }
145
+ }
146
+ }
147
+ }
148
+ this.exit(getExitCode(input));
149
+ }
150
+ }
151
+ //# sourceMappingURL=analyze.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyze.js","sourceRoot":"","sources":["../../src/commands/analyze.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class Fix extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ 'dry-run': import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
+ file: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
+ verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
+ model: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
+ workers: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
11
+ fresh: import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
+ };
13
+ run(): Promise<void>;
14
+ }
15
+ //# sourceMappingURL=fix.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fix.d.ts","sourceRoot":"","sources":["../../src/commands/fix.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAS,MAAM,aAAa,CAAA;AAM5C,MAAM,CAAC,OAAO,OAAO,GAAI,SAAQ,OAAO;IACtC,MAAM,CAAC,WAAW,SAAgG;IAElH,MAAM,CAAC,QAAQ,WAKd;IAED,MAAM,CAAC,KAAK;;;;;;;MA2BX;IAEK,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAiE3B"}
@@ -0,0 +1,106 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import chalk from 'chalk';
3
+ import { loadConfig, applyModelOverride } from '../lib/config.js';
4
+ import { detectEnvironment } from '../lib/detector.js';
5
+ import { runFixLoop } from '../agent/fix-loop.js';
6
+ export default class Fix extends Command {
7
+ static description = 'Find and fix failing tests using AI — preserves existing tests, only repairs what is broken';
8
+ static examples = [
9
+ '$ lacuna fix',
10
+ '$ lacuna fix --workers 4',
11
+ '$ lacuna fix --file src/utils/math.test.ts',
12
+ '$ lacuna fix --dry-run',
13
+ ];
14
+ static flags = {
15
+ 'dry-run': Flags.boolean({
16
+ description: 'Show what would be changed without writing files',
17
+ default: false,
18
+ }),
19
+ file: Flags.string({
20
+ char: 'f',
21
+ description: 'Target a specific test file instead of all failing tests',
22
+ }),
23
+ verbose: Flags.boolean({
24
+ char: 'v',
25
+ description: 'Show model output and full test runner logs',
26
+ default: false,
27
+ }),
28
+ model: Flags.string({
29
+ char: 'm',
30
+ description: 'Model to use (overrides .lacuna.json)',
31
+ }),
32
+ workers: Flags.integer({
33
+ char: 'w',
34
+ description: 'Number of parallel workers (each handles one file at a time)',
35
+ default: 1,
36
+ }),
37
+ fresh: Flags.boolean({
38
+ description: 'Re-run the full test suite even if a recent failing-files cache exists',
39
+ default: false,
40
+ }),
41
+ };
42
+ async run() {
43
+ const { flags } = await this.parse(Fix);
44
+ const config = await loadConfig();
45
+ if (flags.model)
46
+ applyModelOverride(config, flags.model);
47
+ const env = await detectEnvironment(process.cwd(), config.testRunner);
48
+ this.log(chalk.bold('\nlacuna fix\n'));
49
+ this.log(`${chalk.dim('Model:')} ${chalk.cyan(config.model)}`);
50
+ this.log(`${chalk.dim('Runner:')} ${chalk.cyan(env.testRunner)}`);
51
+ if (flags.workers > 1)
52
+ this.log(`${chalk.dim('Workers:')} ${flags.workers}`);
53
+ if (flags['dry-run'])
54
+ this.log(chalk.yellow(' [dry-run — no files will be written]'));
55
+ if (flags.file)
56
+ this.log(`${chalk.dim('Target:')} ${flags.file}`);
57
+ if (env.testRunner === 'unknown') {
58
+ this.warn('Could not detect test runner. Run `lacuna init` to configure.');
59
+ this.exit(2);
60
+ }
61
+ let result;
62
+ try {
63
+ result = await runFixLoop({
64
+ config,
65
+ env,
66
+ cwd: process.cwd(),
67
+ dryRun: flags['dry-run'],
68
+ verbose: flags.verbose,
69
+ targetFile: flags.file,
70
+ workers: flags.workers,
71
+ fresh: flags.fresh,
72
+ log: (msg) => this.log(msg),
73
+ });
74
+ }
75
+ catch (err) {
76
+ this.error(err instanceof Error ? err.message : String(err));
77
+ }
78
+ this.log('');
79
+ this.log(chalk.bold('Results'));
80
+ this.log(` ${chalk.dim('Files processed:')} ${result.filesProcessed}`);
81
+ this.log(` ${chalk.dim('Files fixed:')} ${chalk.green(String(result.filesFixed))}`);
82
+ const stillFailing = result.filesProcessed - result.filesFixed;
83
+ if (stillFailing > 0) {
84
+ this.log(` ${chalk.dim('Still failing:')} ${chalk.red(String(stillFailing))}`);
85
+ }
86
+ if (result.errors.length > 0) {
87
+ this.log(chalk.red(`\n ${result.errors.length} error(s):`));
88
+ for (const err of result.errors) {
89
+ const lines = err.split('\n').slice(0, 8);
90
+ this.log(chalk.dim(' ' + lines.join('\n ')));
91
+ }
92
+ }
93
+ if (result.filesProcessed === 0) {
94
+ this.exit(0);
95
+ }
96
+ else if (result.filesFixed === result.filesProcessed) {
97
+ this.log(chalk.green('\n All failing tests fixed.'));
98
+ this.exit(0);
99
+ }
100
+ else {
101
+ this.log(chalk.yellow(`\n ${stillFailing} file(s) still failing. Re-run lacuna fix or check errors above.`));
102
+ this.exit(1);
103
+ }
104
+ }
105
+ }
106
+ //# sourceMappingURL=fix.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fix.js","sourceRoot":"","sources":["../../src/commands/fix.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class Generate extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ 'dry-run': import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
+ file: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
+ verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
+ model: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
+ threshold: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ format: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
12
+ output: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
+ workers: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
14
+ fresh: import("@oclif/core/interfaces").BooleanFlag<boolean>;
15
+ };
16
+ run(): Promise<void>;
17
+ }
18
+ //# sourceMappingURL=generate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAS,MAAM,aAAa,CAAA;AAS5C,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,OAAO;IAC3C,MAAM,CAAC,WAAW,SAA4E;IAE9F,MAAM,CAAC,QAAQ,WAKd;IAED,MAAM,CAAC,KAAK;;;;;;;;;;MAyCX;IAEK,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAoE3B"}
@@ -0,0 +1,129 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import { writeFile } from 'fs/promises';
3
+ import chalk from 'chalk';
4
+ import { loadConfig, applyModelOverride } from '../lib/config.js';
5
+ import { detectEnvironment } from '../lib/detector.js';
6
+ import { runAgentLoop } from '../agent/loop.js';
7
+ import { reportTerminal, buildJsonReport, buildMarkdownReport, getExitCode } from '../lib/reporter.js';
8
+ export default class Generate extends Command {
9
+ static description = 'Run the full agent loop: analyze gaps, generate tests, verify they pass';
10
+ static examples = [
11
+ '$ lacuna generate',
12
+ '$ lacuna generate --dry-run',
13
+ '$ lacuna generate --file src/utils/math.ts',
14
+ '$ lacuna generate --format json --output report.json',
15
+ ];
16
+ static flags = {
17
+ 'dry-run': Flags.boolean({
18
+ description: 'Print what would be written without touching the filesystem',
19
+ default: false,
20
+ }),
21
+ file: Flags.string({
22
+ char: 'f',
23
+ description: 'Target a specific source file instead of the whole project',
24
+ }),
25
+ verbose: Flags.boolean({
26
+ char: 'v',
27
+ description: 'Show model output and full test runner logs',
28
+ default: false,
29
+ }),
30
+ model: Flags.string({
31
+ char: 'm',
32
+ description: 'Model to use (overrides .lacuna.json)',
33
+ }),
34
+ threshold: Flags.integer({
35
+ char: 't',
36
+ description: 'Override coverage threshold',
37
+ }),
38
+ format: Flags.string({
39
+ char: 'F',
40
+ description: 'Output format for the final report',
41
+ options: ['terminal', 'json', 'markdown'],
42
+ default: 'terminal',
43
+ }),
44
+ output: Flags.string({
45
+ char: 'o',
46
+ description: 'Write report to file instead of stdout',
47
+ }),
48
+ workers: Flags.integer({
49
+ char: 'w',
50
+ description: 'Number of parallel workers (each handles one file at a time)',
51
+ default: 1,
52
+ }),
53
+ fresh: Flags.boolean({
54
+ description: 'Force a fresh coverage run even if a recent report already exists',
55
+ default: false,
56
+ }),
57
+ };
58
+ async run() {
59
+ const { flags } = await this.parse(Generate);
60
+ const config = await loadConfig();
61
+ if (flags.model)
62
+ applyModelOverride(config, flags.model);
63
+ if (flags.threshold)
64
+ config.threshold = flags.threshold;
65
+ const env = await detectEnvironment(process.cwd(), config.testRunner);
66
+ this.log(chalk.bold('\nlacuna generate\n'));
67
+ this.log(`${chalk.dim('Model:')} ${chalk.cyan(config.model)}`);
68
+ this.log(`${chalk.dim('Runner:')} ${chalk.cyan(env.testRunner)}`);
69
+ this.log(`${chalk.dim('Threshold:')} ${config.threshold}%`);
70
+ if (flags.workers > 1)
71
+ this.log(`${chalk.dim('Workers:')} ${flags.workers}`);
72
+ if (flags['dry-run'])
73
+ this.log(chalk.yellow(' [dry-run — no files will be written]'));
74
+ if (flags.file)
75
+ this.log(`${chalk.dim('Target:')} ${flags.file}`);
76
+ if (env.testRunner === 'unknown') {
77
+ this.warn('Could not detect test runner. Run `lacuna init` to configure.');
78
+ this.exit(2);
79
+ }
80
+ let loopResult;
81
+ try {
82
+ loopResult = await runAgentLoop({
83
+ config,
84
+ env,
85
+ cwd: process.cwd(),
86
+ dryRun: flags['dry-run'],
87
+ verbose: flags.verbose,
88
+ targetFile: flags.file,
89
+ workers: flags.workers,
90
+ fresh: flags.fresh,
91
+ log: (msg) => this.log(msg),
92
+ });
93
+ }
94
+ catch (err) {
95
+ this.error(err instanceof Error ? err.message : String(err));
96
+ }
97
+ const input = {
98
+ type: 'generate',
99
+ threshold: config.threshold,
100
+ untouchedCount: 0,
101
+ generate: loopResult,
102
+ };
103
+ if (flags.format === 'json') {
104
+ const out = JSON.stringify(buildJsonReport(input), null, 2);
105
+ if (flags.output) {
106
+ await writeFile(flags.output, out, 'utf-8');
107
+ this.log(`\nReport written to ${flags.output}`);
108
+ }
109
+ else {
110
+ this.log('\n' + out);
111
+ }
112
+ }
113
+ else if (flags.format === 'markdown') {
114
+ const out = buildMarkdownReport(input);
115
+ if (flags.output) {
116
+ await writeFile(flags.output, out, 'utf-8');
117
+ this.log(`\nReport written to ${flags.output}`);
118
+ }
119
+ else {
120
+ this.log('\n' + out);
121
+ }
122
+ }
123
+ else {
124
+ reportTerminal(input);
125
+ }
126
+ this.exit(getExitCode(input));
127
+ }
128
+ }
129
+ //# sourceMappingURL=generate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.js","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class Init extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ run(): Promise<void>;
6
+ }
7
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AASrC,MAAM,CAAC,OAAO,OAAO,IAAK,SAAQ,OAAO;IACvC,MAAM,CAAC,WAAW,SAAiE;IACnF,MAAM,CAAC,QAAQ,WAAoB;IAE7B,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAyI3B"}