agent-gauntlet 0.10.0 → 0.11.0

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 (71) hide show
  1. package/README.md +25 -23
  2. package/dist/index.js +9226 -0
  3. package/dist/index.js.map +65 -0
  4. package/dist/scripts/status.js +280 -0
  5. package/dist/scripts/status.js.map +10 -0
  6. package/package.json +22 -8
  7. package/src/built-in-reviews/code-quality.md +0 -25
  8. package/src/built-in-reviews/index.ts +0 -28
  9. package/src/bun-plugins.d.ts +0 -4
  10. package/src/cli-adapters/claude.ts +0 -327
  11. package/src/cli-adapters/codex.ts +0 -290
  12. package/src/cli-adapters/cursor.ts +0 -128
  13. package/src/cli-adapters/gemini.ts +0 -510
  14. package/src/cli-adapters/github-copilot.ts +0 -141
  15. package/src/cli-adapters/index.ts +0 -250
  16. package/src/cli-adapters/thinking-budget.ts +0 -23
  17. package/src/commands/check.ts +0 -311
  18. package/src/commands/ci/index.ts +0 -15
  19. package/src/commands/ci/init.ts +0 -96
  20. package/src/commands/ci/list-jobs.ts +0 -90
  21. package/src/commands/clean.ts +0 -54
  22. package/src/commands/detect.ts +0 -173
  23. package/src/commands/health.ts +0 -169
  24. package/src/commands/help.ts +0 -34
  25. package/src/commands/index.ts +0 -13
  26. package/src/commands/init.ts +0 -1878
  27. package/src/commands/list.ts +0 -33
  28. package/src/commands/review.ts +0 -311
  29. package/src/commands/run.ts +0 -29
  30. package/src/commands/shared.ts +0 -267
  31. package/src/commands/stop-hook.ts +0 -567
  32. package/src/commands/validate.ts +0 -20
  33. package/src/commands/wait-ci.ts +0 -518
  34. package/src/config/ci-loader.ts +0 -33
  35. package/src/config/ci-schema.ts +0 -28
  36. package/src/config/global.ts +0 -87
  37. package/src/config/loader.ts +0 -301
  38. package/src/config/schema.ts +0 -165
  39. package/src/config/stop-hook-config.ts +0 -130
  40. package/src/config/types.ts +0 -65
  41. package/src/config/validator.ts +0 -592
  42. package/src/core/change-detector.ts +0 -137
  43. package/src/core/diff-stats.ts +0 -442
  44. package/src/core/entry-point.ts +0 -190
  45. package/src/core/job.ts +0 -96
  46. package/src/core/run-executor.ts +0 -621
  47. package/src/core/runner.ts +0 -290
  48. package/src/gates/check.ts +0 -118
  49. package/src/gates/resolve-check-command.ts +0 -21
  50. package/src/gates/result.ts +0 -54
  51. package/src/gates/review.ts +0 -1333
  52. package/src/hooks/adapters/claude-stop-hook.ts +0 -99
  53. package/src/hooks/adapters/cursor-stop-hook.ts +0 -122
  54. package/src/hooks/adapters/types.ts +0 -94
  55. package/src/hooks/stop-hook-handler.ts +0 -748
  56. package/src/index.ts +0 -47
  57. package/src/output/app-logger.ts +0 -214
  58. package/src/output/console-log.ts +0 -168
  59. package/src/output/console.ts +0 -359
  60. package/src/output/logger.ts +0 -126
  61. package/src/output/sinks/console-sink.ts +0 -59
  62. package/src/output/sinks/file-sink.ts +0 -110
  63. package/src/scripts/status.ts +0 -433
  64. package/src/templates/workflow.yml +0 -79
  65. package/src/types/gauntlet-status.ts +0 -79
  66. package/src/utils/debug-log.ts +0 -392
  67. package/src/utils/diff-parser.ts +0 -103
  68. package/src/utils/execution-state.ts +0 -472
  69. package/src/utils/log-parser.ts +0 -696
  70. package/src/utils/sanitizer.ts +0 -3
  71. package/src/utils/session-ref.ts +0 -91
@@ -1,173 +0,0 @@
1
- import chalk from "chalk";
2
- import type { Command } from "commander";
3
- import { loadConfig } from "../config/loader.js";
4
- import { ChangeDetector } from "../core/change-detector.js";
5
- import { EntryPointExpander } from "../core/entry-point.js";
6
- import { type Job, JobGenerator } from "../core/job.js";
7
- import {
8
- readExecutionState,
9
- resolveFixBase,
10
- } from "../utils/execution-state.js";
11
- import {
12
- hasExistingLogs,
13
- performAutoClean,
14
- shouldAutoClean,
15
- } from "./shared.js";
16
-
17
- interface ChangeOptions {
18
- commit?: string;
19
- uncommitted?: boolean;
20
- fixBase?: string;
21
- }
22
-
23
- async function autoCleanIfNeeded(
24
- logDir: string,
25
- baseBranch: string,
26
- ): Promise<void> {
27
- const result = await shouldAutoClean(logDir, baseBranch);
28
- if (result.clean) {
29
- await performAutoClean(logDir, result);
30
- }
31
- }
32
-
33
- async function resolveFreshFixBase(
34
- logDir: string,
35
- baseBranch: string,
36
- ): Promise<string | undefined> {
37
- const state = await readExecutionState(logDir);
38
- if (!state) return undefined;
39
- return (await resolveFixBase(state, baseBranch)).fixBase ?? undefined;
40
- }
41
-
42
- /**
43
- * Resolve change detection options using the same logic as run-executor.
44
- * Handles rerun mode (existing logs → uncommitted-only diff) and fixBase resolution.
45
- */
46
- async function resolveChangeOptions(
47
- logDir: string,
48
- baseBranch: string,
49
- cliOptions: { commit?: string; uncommitted?: boolean },
50
- ): Promise<ChangeOptions> {
51
- await autoCleanIfNeeded(logDir, baseBranch);
52
-
53
- const logsExist = await hasExistingLogs(logDir);
54
- const isRerun = logsExist && !cliOptions.commit;
55
-
56
- const opts: ChangeOptions = {};
57
- if (isRerun) {
58
- const state = await readExecutionState(logDir);
59
- opts.uncommitted = true;
60
- opts.fixBase = state?.working_tree_ref;
61
- } else if (!logsExist) {
62
- const fixBase = await resolveFreshFixBase(logDir, baseBranch);
63
- if (fixBase) opts.fixBase = fixBase;
64
- }
65
-
66
- if (cliOptions.commit || cliOptions.uncommitted) {
67
- return {
68
- commit: cliOptions.commit,
69
- uncommitted: cliOptions.uncommitted,
70
- fixBase: opts.fixBase,
71
- };
72
- }
73
- return opts;
74
- }
75
-
76
- export function registerDetectCommand(program: Command): void {
77
- program
78
- .command("detect")
79
- .description(
80
- "Show what gates would run for detected changes (without executing them)",
81
- )
82
- .option(
83
- "-b, --base-branch <branch>",
84
- "Override base branch for change detection",
85
- )
86
- .option("-c, --commit <sha>", "Use diff for a specific commit")
87
- .option(
88
- "-u, --uncommitted",
89
- "Use diff for current uncommitted changes (staged and unstaged)",
90
- )
91
- .action(async (options) => {
92
- try {
93
- const config = await loadConfig();
94
-
95
- // Priority: CLI override > CI env var > config
96
- const effectiveBaseBranch =
97
- options.baseBranch ||
98
- (process.env.GITHUB_BASE_REF &&
99
- (process.env.CI === "true" || process.env.GITHUB_ACTIONS === "true")
100
- ? process.env.GITHUB_BASE_REF
101
- : null) ||
102
- config.project.base_branch;
103
-
104
- const changeOptions = await resolveChangeOptions(
105
- config.project.log_dir,
106
- effectiveBaseBranch,
107
- { commit: options.commit, uncommitted: options.uncommitted },
108
- );
109
-
110
- const changeDetector = new ChangeDetector(
111
- effectiveBaseBranch,
112
- changeOptions,
113
- );
114
- const expander = new EntryPointExpander();
115
- const jobGen = new JobGenerator(config);
116
-
117
- console.log(chalk.dim("Detecting changes..."));
118
- const changes = await changeDetector.getChangedFiles();
119
-
120
- if (changes.length === 0) {
121
- console.log(chalk.green("No changes detected."));
122
- return;
123
- }
124
-
125
- console.log(chalk.dim(`Found ${changes.length} changed files:`));
126
- for (const file of changes) {
127
- console.log(chalk.dim(` - ${file}`));
128
- }
129
- console.log();
130
-
131
- const entryPoints = await expander.expand(
132
- config.project.entry_points,
133
- changes,
134
- );
135
- const jobs = jobGen.generateJobs(entryPoints);
136
-
137
- if (jobs.length === 0) {
138
- console.log(chalk.yellow("No applicable gates for these changes."));
139
- return;
140
- }
141
-
142
- console.log(chalk.bold(`Would run ${jobs.length} gate(s):\n`));
143
- printJobsByWorkDir(jobs);
144
- } catch (error: unknown) {
145
- const err = error as { message?: string };
146
- console.error(chalk.red("Error:"), err.message);
147
- process.exit(1);
148
- }
149
- });
150
- }
151
-
152
- function groupByWorkDir(jobs: Job[]): Map<string, Job[]> {
153
- const map = new Map<string, Job[]>();
154
- for (const job of jobs) {
155
- if (!map.has(job.workingDirectory)) {
156
- map.set(job.workingDirectory, []);
157
- }
158
- map.get(job.workingDirectory)?.push(job);
159
- }
160
- return map;
161
- }
162
-
163
- function printJobsByWorkDir(jobs: Job[]): void {
164
- for (const [workDir, wdJobs] of groupByWorkDir(jobs).entries()) {
165
- console.log(chalk.cyan(`Working directory: ${workDir}`));
166
- for (const job of wdJobs) {
167
- const typeLabel =
168
- job.type === "check" ? chalk.yellow("check") : chalk.blue("review");
169
- console.log(` ${typeLabel} ${chalk.bold(job.name)}`);
170
- }
171
- console.log();
172
- }
173
- }
@@ -1,169 +0,0 @@
1
- import path from "node:path";
2
- import chalk from "chalk";
3
- import type { Command } from "commander";
4
- import { getAdapter, getAllAdapters } from "../cli-adapters/index.js";
5
- import { loadConfig } from "../config/loader.js";
6
- import { validateConfig } from "../config/validator.js";
7
-
8
- export function registerHealthCommand(program: Command): void {
9
- program
10
- .command("health")
11
- .description("Check CLI tool availability")
12
- .action(async () => {
13
- // 1. Config validation
14
- console.log(chalk.bold("Config validation:"));
15
- const validationResult = await validateConfig();
16
-
17
- if (validationResult.filesChecked.length === 0) {
18
- console.log(chalk.yellow(" No config files found"));
19
- } else {
20
- // List all files checked
21
- for (const file of validationResult.filesChecked) {
22
- const relativePath = path.relative(process.cwd(), file);
23
- console.log(chalk.dim(` ${relativePath}`));
24
- }
25
-
26
- // Show validation results
27
- if (validationResult.valid && validationResult.issues.length === 0) {
28
- console.log(chalk.green(" ✓ All config files are valid"));
29
- } else {
30
- // Group issues by file
31
- const issuesByFile = new Map<
32
- string,
33
- typeof validationResult.issues
34
- >();
35
- for (const issue of validationResult.issues) {
36
- const relativeFile = path.relative(process.cwd(), issue.file);
37
- if (!issuesByFile.has(relativeFile)) {
38
- issuesByFile.set(relativeFile, []);
39
- }
40
- issuesByFile.get(relativeFile)?.push(issue);
41
- }
42
-
43
- // Display issues
44
- for (const [file, issues] of issuesByFile.entries()) {
45
- for (const issue of issues) {
46
- const icon =
47
- issue.severity === "error" ? chalk.red("✗") : chalk.yellow("⚠");
48
- const fieldInfo = issue.field
49
- ? chalk.dim(` (${issue.field})`)
50
- : "";
51
- console.log(` ${icon} ${file}${fieldInfo}`);
52
- console.log(` ${issue.message}`);
53
- }
54
- }
55
- }
56
- }
57
-
58
- console.log();
59
-
60
- // 2. CLI Tool Health Check
61
- console.log(chalk.bold("CLI Tool Health Check:"));
62
-
63
- try {
64
- const config = await loadConfig();
65
-
66
- // Check for reviews configuration
67
- const reviewEntries = Object.entries(config.reviews);
68
-
69
- if (reviewEntries.length === 0) {
70
- console.log(chalk.yellow(" No CLI tools configured"));
71
- console.log(
72
- chalk.dim(
73
- " No review gates found. Add review gates with cli_preference to check tool availability.",
74
- ),
75
- );
76
- return;
77
- }
78
-
79
- // Collect all unique agent names from review gate cli_preference settings
80
- const preferredAgents = new Set<string>();
81
- const reviewsWithEmptyPreference: string[] = [];
82
-
83
- reviewEntries.forEach(([reviewName, review]) => {
84
- if (!review.cli_preference || review.cli_preference.length === 0) {
85
- reviewsWithEmptyPreference.push(reviewName);
86
- } else {
87
- review.cli_preference.forEach((agent) => {
88
- preferredAgents.add(agent);
89
- });
90
- }
91
- });
92
-
93
- // Report Empty Preferences (Loader should handle this via default merging, but good to check)
94
- if (reviewsWithEmptyPreference.length > 0) {
95
- console.log(chalk.yellow(" ⚠️ Misconfiguration detected:"));
96
- reviewsWithEmptyPreference.forEach((name) => {
97
- console.log(
98
- chalk.yellow(
99
- ` Review gate "${name}" has empty cli_preference`,
100
- ),
101
- );
102
- });
103
- console.log();
104
- }
105
-
106
- // If no agents are configured, show message
107
- if (preferredAgents.size === 0) {
108
- console.log(chalk.yellow(" No CLI tools configured"));
109
- console.log(
110
- chalk.dim(
111
- " All review gates have empty cli_preference. Add tools to cli_preference to check availability.",
112
- ),
113
- );
114
- return;
115
- }
116
-
117
- // Check the configured agents
118
- for (const agentName of Array.from(preferredAgents).sort()) {
119
- const adapter = getAdapter(agentName);
120
- if (adapter) {
121
- const health = await adapter.checkHealth();
122
- let statusStr = "";
123
-
124
- switch (health.status) {
125
- case "healthy":
126
- statusStr = chalk.green("Installed");
127
- break;
128
- case "missing":
129
- statusStr = chalk.red("Missing");
130
- break;
131
- case "unhealthy":
132
- statusStr = chalk.red(`${health.message || "Unhealthy"}`);
133
- break;
134
- }
135
-
136
- console.log(` ${adapter.name.padEnd(10)} : ${statusStr}`);
137
- } else {
138
- console.log(
139
- ` ${agentName.padEnd(10)} : ${chalk.yellow("Unknown")}`,
140
- );
141
- }
142
- }
143
- } catch (_error: unknown) {
144
- // If config can't be loaded, fall back to checking all adapters
145
- const adapters = getAllAdapters();
146
- console.log(
147
- chalk.dim(" (Config not found, checking all supported agents)"),
148
- );
149
-
150
- for (const adapter of adapters) {
151
- const health = await adapter.checkHealth();
152
- let statusStr = "";
153
-
154
- switch (health.status) {
155
- case "healthy":
156
- statusStr = chalk.green("Installed");
157
- break;
158
- case "missing":
159
- statusStr = chalk.red("Missing");
160
- break;
161
- case "unhealthy":
162
- statusStr = chalk.red(`${health.message || "Unhealthy"}`);
163
- break;
164
- }
165
- console.log(` ${adapter.name.padEnd(10)} : ${statusStr}`);
166
- }
167
- }
168
- });
169
- }
@@ -1,34 +0,0 @@
1
- import chalk from "chalk";
2
- import type { Command } from "commander";
3
-
4
- export function registerHelpCommand(program: Command): void {
5
- program
6
- .command("help")
7
- .description("Show help information")
8
- .action(() => {
9
- console.log(chalk.bold("Agent Gauntlet - AI-assisted quality gates\n"));
10
- console.log(
11
- "Agent Gauntlet runs quality gates (checks + AI reviews) for only the parts",
12
- );
13
- console.log(
14
- "of your repo that changed, based on a configurable set of entry points.\n",
15
- );
16
- console.log(chalk.bold("Commands:\n"));
17
- console.log(" run Run gates for detected changes");
18
- console.log(" check Run only applicable checks");
19
- console.log(" review Run only applicable reviews");
20
- console.log(" clean Archive logs (move current logs into previous/)");
21
- console.log(
22
- " detect Show what gates would run (without executing them)",
23
- );
24
- console.log(" list List configured gates");
25
- console.log(" health Check CLI tool availability");
26
- console.log(" init Initialize .gauntlet configuration");
27
- console.log(" ci CI integration commands (init, list-jobs)");
28
- console.log(" help Show this help message\n");
29
- console.log(
30
- "For more information, see: https://github.com/your-repo/agent-gauntlet",
31
- );
32
- console.log("Or run: agent-gauntlet <command> --help");
33
- });
34
- }
@@ -1,13 +0,0 @@
1
- export { registerCheckCommand } from "./check.js";
2
- export { registerCICommand } from "./ci/index.js";
3
- export { registerCleanCommand } from "./clean.js";
4
- export { registerDetectCommand } from "./detect.js";
5
- export { registerHealthCommand } from "./health.js";
6
- export { registerHelpCommand } from "./help.js";
7
- export { registerInitCommand } from "./init.js";
8
- export { registerListCommand } from "./list.js";
9
- export { registerReviewCommand } from "./review.js";
10
- export { registerRunCommand } from "./run.js";
11
- export { registerStopHookCommand } from "./stop-hook.js";
12
- export { registerValidateCommand } from "./validate.js";
13
- export { registerWaitCICommand } from "./wait-ci.js";