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,190 +0,0 @@
1
- import fs from "node:fs/promises";
2
- import path from "node:path";
3
- import { Glob } from "bun";
4
- import type { EntryPointConfig } from "../config/types.js";
5
-
6
- export interface ExpandedEntryPoint {
7
- path: string; // The specific directory (e.g., "engines/billing")
8
- config: EntryPointConfig; // The config that generated this (e.g., "engines/*")
9
- }
10
-
11
- export class EntryPointExpander {
12
- async expand(
13
- entryPoints: EntryPointConfig[],
14
- changedFiles: string[],
15
- ): Promise<ExpandedEntryPoint[]> {
16
- const results: ExpandedEntryPoint[] = [];
17
- const rootEntryPoint = entryPoints.find((ep) => ep.path === ".");
18
-
19
- // Always include root entry point if configured and there are ANY changes
20
- if (changedFiles.length > 0) {
21
- const rootConfig = rootEntryPoint ?? { path: "." };
22
- // Apply exclusion filtering for root if configured
23
- const filteredRootChanges = this.filterExcludedFiles(
24
- changedFiles,
25
- rootConfig.exclude,
26
- );
27
-
28
- if (filteredRootChanges.length > 0) {
29
- results.push({ path: ".", config: rootConfig });
30
- }
31
- }
32
-
33
- for (const ep of entryPoints) {
34
- if (ep.path === ".") continue; // Handled above
35
-
36
- // Apply exclusion filtering first!
37
- const filteredChanges = this.filterExcludedFiles(
38
- changedFiles,
39
- ep.exclude,
40
- );
41
-
42
- // If no relevant files remain, skip this entry point
43
- if (filteredChanges.length === 0) continue;
44
-
45
- if (ep.path.endsWith("*") && !ep.path.includes("**")) {
46
- // Single-level wildcard directory (e.g., "engines/*")
47
- const parentDir = ep.path.slice(0, -2); // "engines"
48
- const expandedPaths = await this.expandWildcard(
49
- parentDir,
50
- filteredChanges,
51
- );
52
-
53
- for (const subDir of expandedPaths) {
54
- results.push({
55
- path: subDir,
56
- config: ep,
57
- });
58
- }
59
- } else if (this.isGlobPattern(ep.path)) {
60
- // Glob pattern (e.g., "openspec/changes/**/tasks.md")
61
- if (this.hasMatchingFiles(ep.path, filteredChanges)) {
62
- results.push({
63
- path: ep.path,
64
- config: ep,
65
- });
66
- }
67
- } else {
68
- // Fixed directory (e.g., "apps/api")
69
- if (this.hasChangesInDir(ep.path, filteredChanges)) {
70
- results.push({
71
- path: ep.path,
72
- config: ep,
73
- });
74
- }
75
- }
76
- }
77
-
78
- return results;
79
- }
80
-
81
- async expandAll(
82
- entryPoints: EntryPointConfig[],
83
- ): Promise<ExpandedEntryPoint[]> {
84
- const results: ExpandedEntryPoint[] = [];
85
-
86
- for (const ep of entryPoints) {
87
- if (ep.path === ".") {
88
- results.push({ path: ".", config: ep });
89
- continue;
90
- }
91
-
92
- if (ep.path.endsWith("*") && !ep.path.includes("**")) {
93
- // Single-level wildcard directory (e.g., "engines/*")
94
- const parentDir = ep.path.slice(0, -2);
95
- const subDirs = await this.listSubDirectories(parentDir);
96
- for (const subDir of subDirs) {
97
- results.push({ path: subDir, config: ep });
98
- }
99
- } else if (this.isGlobPattern(ep.path)) {
100
- // Glob pattern (e.g., "openspec/changes/**/tasks.md")
101
- // Include as-is for expandAll since it's a virtual entry point
102
- results.push({ path: ep.path, config: ep });
103
- } else {
104
- results.push({ path: ep.path, config: ep });
105
- }
106
- }
107
-
108
- return results;
109
- }
110
-
111
- private filterExcludedFiles(files: string[], patterns?: string[]): string[] {
112
- if (!patterns || patterns.length === 0) {
113
- return files;
114
- }
115
-
116
- // Pre-compile globs
117
- const globs: Glob[] = [];
118
- const prefixes: string[] = [];
119
-
120
- for (const pattern of patterns) {
121
- if (pattern.match(/[*?[{]/)) {
122
- globs.push(new Glob(pattern));
123
- } else {
124
- prefixes.push(pattern);
125
- }
126
- }
127
-
128
- return files.filter((file) => {
129
- // If matches ANY pattern, exclude it
130
- const isExcluded =
131
- prefixes.some((p) => file === p || file.startsWith(`${p}/`)) ||
132
- globs.some((g) => g.match(file));
133
-
134
- return !isExcluded;
135
- });
136
- }
137
-
138
- private async expandWildcard(
139
- parentDir: string,
140
- changedFiles: string[],
141
- ): Promise<string[]> {
142
- const affectedSubDirs = new Set<string>();
143
-
144
- // Filter changes that are inside this parent directory
145
- const relevantChanges = changedFiles.filter((f) =>
146
- f.startsWith(`${parentDir}/`),
147
- );
148
-
149
- for (const file of relevantChanges) {
150
- // file: "engines/billing/src/foo.ts", parentDir: "engines"
151
- // relPath: "billing/src/foo.ts"
152
- const relPath = file.slice(parentDir.length + 1);
153
- const subDirName = relPath.split("/")[0];
154
-
155
- if (subDirName) {
156
- affectedSubDirs.add(path.join(parentDir, subDirName));
157
- }
158
- }
159
-
160
- return Array.from(affectedSubDirs);
161
- }
162
-
163
- private async listSubDirectories(parentDir: string): Promise<string[]> {
164
- try {
165
- const dirents = await fs.readdir(parentDir, { withFileTypes: true });
166
- return dirents
167
- .filter((d) => d.isDirectory())
168
- .map((d) => path.join(parentDir, d.name));
169
- } catch {
170
- return [];
171
- }
172
- }
173
-
174
- private hasChangesInDir(dirPath: string, changedFiles: string[]): boolean {
175
- // Check if any changed file starts with the dirPath
176
- // Need to ensure exact match or subdirectory (e.g. "app" should not match "apple")
177
- const dirPrefix = dirPath.endsWith("/") ? dirPath : `${dirPath}/`;
178
- return changedFiles.some((f) => f === dirPath || f.startsWith(dirPrefix));
179
- }
180
-
181
- private isGlobPattern(pattern: string): boolean {
182
- // Check if the pattern contains glob characters
183
- return /[*?[{]/.test(pattern);
184
- }
185
-
186
- private hasMatchingFiles(pattern: string, changedFiles: string[]): boolean {
187
- const glob = new Glob(pattern);
188
- return changedFiles.some((file) => glob.match(file));
189
- }
190
- }
package/src/core/job.ts DELETED
@@ -1,96 +0,0 @@
1
- import type {
2
- CheckGateConfig,
3
- LoadedConfig,
4
- LoadedReviewGateConfig,
5
- } from "../config/types.js";
6
- import type { ExpandedEntryPoint } from "./entry-point.js";
7
-
8
- export type JobType = "check" | "review";
9
-
10
- export interface Job {
11
- id: string; // unique id for logging/tracking
12
- type: JobType;
13
- name: string;
14
- entryPoint: string;
15
- gateConfig: CheckGateConfig | LoadedReviewGateConfig;
16
- workingDirectory: string;
17
- }
18
-
19
- export class JobGenerator {
20
- constructor(private config: LoadedConfig) {}
21
-
22
- generateJobs(expandedEntryPoints: ExpandedEntryPoint[]): Job[] {
23
- const jobs: Job[] = [];
24
- const seenJobs = new Set<string>();
25
- const isCI =
26
- process.env.CI === "true" || process.env.GITHUB_ACTIONS === "true";
27
-
28
- for (const ep of expandedEntryPoints) {
29
- // 1. Process Checks
30
- if (ep.config.checks) {
31
- for (const checkName of ep.config.checks) {
32
- const checkConfig = this.config.checks[checkName];
33
- if (!checkConfig) {
34
- console.warn(
35
- `Warning: Check gate '${checkName}' configured in entry point '${ep.path}' but not found in checks definitions.`,
36
- );
37
- continue;
38
- }
39
-
40
- // Filter based on environment
41
- if (isCI && !checkConfig.run_in_ci) continue;
42
- if (!isCI && !checkConfig.run_locally) continue;
43
-
44
- const workingDirectory =
45
- checkConfig.working_directory === "entrypoint"
46
- ? ep.path
47
- : checkConfig.working_directory || ep.path;
48
- const jobKey = `check:${checkName}:${workingDirectory}`;
49
-
50
- // Skip if we've already created a job for this check/working-directory combination
51
- if (seenJobs.has(jobKey)) {
52
- continue;
53
- }
54
- seenJobs.add(jobKey);
55
-
56
- jobs.push({
57
- id: `check:${workingDirectory}:${checkName}`,
58
- type: "check",
59
- name: checkName,
60
- entryPoint: ep.path,
61
- gateConfig: checkConfig,
62
- workingDirectory: workingDirectory,
63
- });
64
- }
65
- }
66
-
67
- // 2. Process Reviews
68
- if (ep.config.reviews) {
69
- for (const reviewName of ep.config.reviews) {
70
- const reviewConfig = this.config.reviews[reviewName];
71
- if (!reviewConfig) {
72
- console.warn(
73
- `Warning: Review gate '${reviewName}' configured in entry point '${ep.path}' but not found in reviews definitions.`,
74
- );
75
- continue;
76
- }
77
-
78
- // Filter based on environment
79
- if (isCI && !reviewConfig.run_in_ci) continue;
80
- if (!isCI && !reviewConfig.run_locally) continue;
81
-
82
- jobs.push({
83
- id: `review:${ep.path}:${reviewName}`,
84
- type: "review",
85
- name: reviewName,
86
- entryPoint: ep.path,
87
- gateConfig: reviewConfig,
88
- workingDirectory: ep.path, // Reviews always run in context of entry point
89
- });
90
- }
91
- }
92
- }
93
-
94
- return jobs;
95
- }
96
- }