guardrail-core 1.0.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 (189) hide show
  1. package/dist/__tests__/autopilot.test.d.ts +7 -0
  2. package/dist/__tests__/autopilot.test.d.ts.map +1 -0
  3. package/dist/__tests__/autopilot.test.js +156 -0
  4. package/dist/__tests__/tier-config.test.d.ts +9 -0
  5. package/dist/__tests__/tier-config.test.d.ts.map +1 -0
  6. package/dist/__tests__/tier-config.test.js +230 -0
  7. package/dist/__tests__/utils/hash-inline.test.d.ts +2 -0
  8. package/dist/__tests__/utils/hash-inline.test.d.ts.map +1 -0
  9. package/dist/__tests__/utils/hash-inline.test.js +62 -0
  10. package/dist/__tests__/utils/hash.test.d.ts +3 -0
  11. package/dist/__tests__/utils/hash.test.d.ts.map +1 -0
  12. package/dist/__tests__/utils/hash.test.js +95 -0
  13. package/dist/__tests__/utils/simple.test.d.ts +1 -0
  14. package/dist/__tests__/utils/simple.test.d.ts.map +1 -0
  15. package/dist/__tests__/utils/simple.test.js +10 -0
  16. package/dist/__tests__/utils/utils-simple.test.d.ts +1 -0
  17. package/dist/__tests__/utils/utils-simple.test.d.ts.map +1 -0
  18. package/dist/__tests__/utils/utils-simple.test.js +6 -0
  19. package/dist/__tests__/utils/utils.test.d.ts +15 -0
  20. package/dist/__tests__/utils/utils.test.d.ts.map +1 -0
  21. package/dist/__tests__/utils/utils.test.js +172 -0
  22. package/dist/autopilot/autopilot-runner.d.ts +33 -0
  23. package/dist/autopilot/autopilot-runner.d.ts.map +1 -0
  24. package/dist/autopilot/autopilot-runner.js +479 -0
  25. package/dist/autopilot/index.d.ts +6 -0
  26. package/dist/autopilot/index.d.ts.map +1 -0
  27. package/dist/autopilot/index.js +25 -0
  28. package/dist/autopilot/types.d.ts +102 -0
  29. package/dist/autopilot/types.d.ts.map +1 -0
  30. package/dist/autopilot/types.js +18 -0
  31. package/dist/cache/index.d.ts +7 -0
  32. package/dist/cache/index.d.ts.map +1 -0
  33. package/dist/cache/index.js +22 -0
  34. package/dist/cache/redis-cache.d.ts +145 -0
  35. package/dist/cache/redis-cache.d.ts.map +1 -0
  36. package/dist/cache/redis-cache.js +459 -0
  37. package/dist/ci/github-actions.d.ts +77 -0
  38. package/dist/ci/github-actions.d.ts.map +1 -0
  39. package/dist/ci/github-actions.js +277 -0
  40. package/dist/ci/index.d.ts +12 -0
  41. package/dist/ci/index.d.ts.map +1 -0
  42. package/dist/ci/index.js +27 -0
  43. package/dist/ci/pre-commit.d.ts +65 -0
  44. package/dist/ci/pre-commit.d.ts.map +1 -0
  45. package/dist/ci/pre-commit.js +286 -0
  46. package/dist/entitlements.d.ts +149 -0
  47. package/dist/entitlements.d.ts.map +1 -0
  48. package/dist/entitlements.js +464 -0
  49. package/dist/env.d.ts +113 -0
  50. package/dist/env.d.ts.map +1 -0
  51. package/dist/env.js +204 -0
  52. package/dist/fix-packs/__tests__/generate-fix-packs.test.d.ts +7 -0
  53. package/dist/fix-packs/__tests__/generate-fix-packs.test.d.ts.map +1 -0
  54. package/dist/fix-packs/__tests__/generate-fix-packs.test.js +250 -0
  55. package/dist/fix-packs/generate-fix-packs.d.ts +15 -0
  56. package/dist/fix-packs/generate-fix-packs.d.ts.map +1 -0
  57. package/dist/fix-packs/generate-fix-packs.js +505 -0
  58. package/dist/fix-packs/index.d.ts +8 -0
  59. package/dist/fix-packs/index.d.ts.map +1 -0
  60. package/dist/fix-packs/index.js +23 -0
  61. package/dist/fix-packs/types.d.ts +113 -0
  62. package/dist/fix-packs/types.d.ts.map +1 -0
  63. package/dist/fix-packs/types.js +71 -0
  64. package/dist/index.d.ts +13 -0
  65. package/dist/index.d.ts.map +1 -0
  66. package/dist/index.js +28 -0
  67. package/dist/metrics/prometheus.d.ts +99 -0
  68. package/dist/metrics/prometheus.d.ts.map +1 -0
  69. package/dist/metrics/prometheus.js +306 -0
  70. package/dist/quota-ledger.d.ts +119 -0
  71. package/dist/quota-ledger.d.ts.map +1 -0
  72. package/dist/quota-ledger.js +462 -0
  73. package/dist/rbac/__tests__/permissions.test.d.ts +8 -0
  74. package/dist/rbac/__tests__/permissions.test.d.ts.map +1 -0
  75. package/dist/rbac/__tests__/permissions.test.js +350 -0
  76. package/dist/rbac/index.d.ts +9 -0
  77. package/dist/rbac/index.d.ts.map +1 -0
  78. package/dist/rbac/index.js +32 -0
  79. package/dist/rbac/permissions.d.ts +71 -0
  80. package/dist/rbac/permissions.d.ts.map +1 -0
  81. package/dist/rbac/permissions.js +247 -0
  82. package/dist/rbac/types.d.ts +69 -0
  83. package/dist/rbac/types.d.ts.map +1 -0
  84. package/dist/rbac/types.js +213 -0
  85. package/dist/tier-config.d.ts +203 -0
  86. package/dist/tier-config.d.ts.map +1 -0
  87. package/dist/tier-config.js +675 -0
  88. package/dist/types.d.ts +365 -0
  89. package/dist/types.d.ts.map +1 -0
  90. package/dist/types.js +5 -0
  91. package/dist/utils.d.ts +36 -0
  92. package/dist/utils.d.ts.map +1 -0
  93. package/dist/utils.js +127 -0
  94. package/dist/verified-autofix/__tests__/format-validator.test.d.ts +11 -0
  95. package/dist/verified-autofix/__tests__/format-validator.test.d.ts.map +1 -0
  96. package/dist/verified-autofix/__tests__/format-validator.test.js +285 -0
  97. package/dist/verified-autofix/__tests__/pipeline.test.d.ts +11 -0
  98. package/dist/verified-autofix/__tests__/pipeline.test.d.ts.map +1 -0
  99. package/dist/verified-autofix/__tests__/pipeline.test.js +389 -0
  100. package/dist/verified-autofix/__tests__/repo-fingerprint.test.d.ts +11 -0
  101. package/dist/verified-autofix/__tests__/repo-fingerprint.test.d.ts.map +1 -0
  102. package/dist/verified-autofix/__tests__/repo-fingerprint.test.js +236 -0
  103. package/dist/verified-autofix/__tests__/workspace.test.d.ts +11 -0
  104. package/dist/verified-autofix/__tests__/workspace.test.d.ts.map +1 -0
  105. package/dist/verified-autofix/__tests__/workspace.test.js +314 -0
  106. package/dist/verified-autofix/format-validator.d.ts +101 -0
  107. package/dist/verified-autofix/format-validator.d.ts.map +1 -0
  108. package/dist/verified-autofix/format-validator.js +446 -0
  109. package/dist/verified-autofix/index.d.ts +14 -0
  110. package/dist/verified-autofix/index.d.ts.map +1 -0
  111. package/dist/verified-autofix/index.js +39 -0
  112. package/dist/verified-autofix/pipeline.d.ts +68 -0
  113. package/dist/verified-autofix/pipeline.d.ts.map +1 -0
  114. package/dist/verified-autofix/pipeline.js +330 -0
  115. package/dist/verified-autofix/repo-fingerprint.d.ts +56 -0
  116. package/dist/verified-autofix/repo-fingerprint.d.ts.map +1 -0
  117. package/dist/verified-autofix/repo-fingerprint.js +396 -0
  118. package/dist/verified-autofix/workspace.d.ts +83 -0
  119. package/dist/verified-autofix/workspace.d.ts.map +1 -0
  120. package/dist/verified-autofix/workspace.js +454 -0
  121. package/dist/verified-autofix.d.ts +182 -0
  122. package/dist/verified-autofix.d.ts.map +1 -0
  123. package/dist/verified-autofix.js +1021 -0
  124. package/dist/visualization/dependency-graph.d.ts +79 -0
  125. package/dist/visualization/dependency-graph.d.ts.map +1 -0
  126. package/dist/visualization/dependency-graph.js +399 -0
  127. package/dist/visualization/index.d.ts +5 -0
  128. package/dist/visualization/index.d.ts.map +1 -0
  129. package/dist/visualization/index.js +20 -0
  130. package/package.json +29 -0
  131. package/src/__tests__/autopilot.test.ts +196 -0
  132. package/src/__tests__/tier-config.test.ts +289 -0
  133. package/src/__tests__/utils/hash-inline.test.ts +76 -0
  134. package/src/__tests__/utils/hash.test.ts +119 -0
  135. package/src/__tests__/utils/simple.test.ts +10 -0
  136. package/src/__tests__/utils/utils-simple.test.ts +5 -0
  137. package/src/__tests__/utils/utils.test.ts +203 -0
  138. package/src/autopilot/autopilot-runner.ts +503 -0
  139. package/src/autopilot/index.ts +6 -0
  140. package/src/autopilot/types.ts +119 -0
  141. package/src/cache/index.ts +7 -0
  142. package/src/cache/redis-cache.d.ts +155 -0
  143. package/src/cache/redis-cache.d.ts.map +1 -0
  144. package/src/cache/redis-cache.ts +517 -0
  145. package/src/ci/github-actions.ts +335 -0
  146. package/src/ci/index.ts +12 -0
  147. package/src/ci/pre-commit.ts +338 -0
  148. package/src/db/usage-schema.prisma +114 -0
  149. package/src/entitlements.ts +570 -0
  150. package/src/env.d.ts +68 -0
  151. package/src/env.d.ts.map +1 -0
  152. package/src/env.ts +247 -0
  153. package/src/fix-packs/__tests__/generate-fix-packs.test.ts +317 -0
  154. package/src/fix-packs/generate-fix-packs.ts +577 -0
  155. package/src/fix-packs/index.ts +8 -0
  156. package/src/fix-packs/types.ts +206 -0
  157. package/src/index.d.ts +7 -0
  158. package/src/index.d.ts.map +1 -0
  159. package/src/index.ts +12 -0
  160. package/src/metrics/prometheus.d.ts +104 -0
  161. package/src/metrics/prometheus.d.ts.map +1 -0
  162. package/src/metrics/prometheus.ts +446 -0
  163. package/src/quota-ledger.ts +548 -0
  164. package/src/rbac/__tests__/permissions.test.ts +446 -0
  165. package/src/rbac/index.ts +46 -0
  166. package/src/rbac/permissions.ts +301 -0
  167. package/src/rbac/types.ts +298 -0
  168. package/src/tier-config.json +157 -0
  169. package/src/tier-config.ts +815 -0
  170. package/src/types.d.ts +365 -0
  171. package/src/types.d.ts.map +1 -0
  172. package/src/types.ts +441 -0
  173. package/src/utils.d.ts +36 -0
  174. package/src/utils.d.ts.map +1 -0
  175. package/src/utils.ts +140 -0
  176. package/src/verified-autofix/__tests__/format-validator.test.ts +335 -0
  177. package/src/verified-autofix/__tests__/pipeline.test.ts +419 -0
  178. package/src/verified-autofix/__tests__/repo-fingerprint.test.ts +241 -0
  179. package/src/verified-autofix/__tests__/workspace.test.ts +373 -0
  180. package/src/verified-autofix/format-validator.ts +517 -0
  181. package/src/verified-autofix/index.ts +63 -0
  182. package/src/verified-autofix/pipeline.ts +403 -0
  183. package/src/verified-autofix/repo-fingerprint.ts +459 -0
  184. package/src/verified-autofix/workspace.ts +531 -0
  185. package/src/verified-autofix.ts +1187 -0
  186. package/src/visualization/dependency-graph.d.ts +85 -0
  187. package/src/visualization/dependency-graph.d.ts.map +1 -0
  188. package/src/visualization/dependency-graph.ts +495 -0
  189. package/src/visualization/index.ts +5 -0
@@ -0,0 +1,454 @@
1
+ "use strict";
2
+ /**
3
+ * Temp Workspace Manager - Isolated Verification Environment
4
+ *
5
+ * Creates isolated workspaces for testing patches:
6
+ * 1. Prefers git worktree when available
7
+ * 2. Falls back to directory copy
8
+ * 3. Applies diffs with git apply --check validation
9
+ * 4. Runs verification commands (typecheck, build, tests)
10
+ */
11
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ var desc = Object.getOwnPropertyDescriptor(m, k);
14
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
+ desc = { enumerable: true, get: function() { return m[k]; } };
16
+ }
17
+ Object.defineProperty(o, k2, desc);
18
+ }) : (function(o, m, k, k2) {
19
+ if (k2 === undefined) k2 = k;
20
+ o[k2] = m[k];
21
+ }));
22
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
23
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
24
+ }) : function(o, v) {
25
+ o["default"] = v;
26
+ });
27
+ var __importStar = (this && this.__importStar) || (function () {
28
+ var ownKeys = function(o) {
29
+ ownKeys = Object.getOwnPropertyNames || function (o) {
30
+ var ar = [];
31
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
32
+ return ar;
33
+ };
34
+ return ownKeys(o);
35
+ };
36
+ return function (mod) {
37
+ if (mod && mod.__esModule) return mod;
38
+ var result = {};
39
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
40
+ __setModuleDefault(result, mod);
41
+ return result;
42
+ };
43
+ })();
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ exports.tempWorkspace = exports.TempWorkspace = void 0;
46
+ const fs = __importStar(require("fs"));
47
+ const path = __importStar(require("path"));
48
+ const crypto = __importStar(require("crypto"));
49
+ const child_process_1 = require("child_process");
50
+ // ============================================================================
51
+ // CONSTANTS
52
+ // ============================================================================
53
+ const WORKSPACE_BASE_DIR = path.join(require('os').tmpdir(), 'guardrail-verified-autofix');
54
+ const DEFAULT_TIMEOUT = 120000; // 2 minutes per command
55
+ const MAX_OUTPUT_LINES = 100;
56
+ const EXCLUDE_PATTERNS = [
57
+ 'node_modules',
58
+ '.git',
59
+ 'dist',
60
+ 'build',
61
+ '.next',
62
+ '.nuxt',
63
+ '.output',
64
+ '__pycache__',
65
+ '.cache',
66
+ 'coverage',
67
+ '.turbo',
68
+ ];
69
+ // ============================================================================
70
+ // WORKSPACE MANAGER CLASS
71
+ // ============================================================================
72
+ class TempWorkspace {
73
+ workspaces = new Map();
74
+ /**
75
+ * Create an isolated workspace for verification
76
+ */
77
+ async create(options) {
78
+ const id = crypto.randomBytes(8).toString('hex');
79
+ const workspacePath = path.join(WORKSPACE_BASE_DIR, id);
80
+ await fs.promises.mkdir(workspacePath, { recursive: true });
81
+ let type = 'copy';
82
+ // Try git worktree first (much faster, shares objects)
83
+ if (options.useWorktree !== false) {
84
+ const worktreeCreated = await this.tryCreateWorktree(options.projectPath, workspacePath);
85
+ if (worktreeCreated) {
86
+ type = 'worktree';
87
+ }
88
+ }
89
+ // Fall back to copy
90
+ if (type === 'copy') {
91
+ await this.copyProject(options.projectPath, workspacePath);
92
+ }
93
+ // Install dependencies if requested
94
+ if (options.installDeps) {
95
+ await this.installDependencies(workspacePath, options.timeout);
96
+ }
97
+ const info = {
98
+ id,
99
+ path: workspacePath,
100
+ type,
101
+ projectPath: options.projectPath,
102
+ createdAt: new Date(),
103
+ };
104
+ this.workspaces.set(id, info);
105
+ return info;
106
+ }
107
+ /**
108
+ * Apply a unified diff to the workspace
109
+ */
110
+ async applyDiff(workspacePath, diff, hunks) {
111
+ const errors = [];
112
+ let applied = 0;
113
+ let failed = 0;
114
+ // First, try git apply --check to validate
115
+ const gitCheckResult = await this.tryGitApply(workspacePath, diff, true);
116
+ if (gitCheckResult.success) {
117
+ // Git apply --check passed, do the real apply
118
+ const gitApplyResult = await this.tryGitApply(workspacePath, diff, false);
119
+ if (gitApplyResult.success) {
120
+ return { success: true, applied: hunks.length, failed: 0, errors: [] };
121
+ }
122
+ errors.push(`git apply failed: ${gitApplyResult.error}`);
123
+ }
124
+ else {
125
+ errors.push(`git apply --check failed: ${gitCheckResult.error}`);
126
+ }
127
+ // Fall back to manual hunk application
128
+ for (const hunk of hunks) {
129
+ try {
130
+ await this.applyHunk(workspacePath, hunk);
131
+ applied++;
132
+ }
133
+ catch (e) {
134
+ failed++;
135
+ errors.push(`Failed to apply hunk to ${hunk.file}: ${e.message}`);
136
+ }
137
+ }
138
+ return {
139
+ success: failed === 0,
140
+ applied,
141
+ failed,
142
+ errors,
143
+ };
144
+ }
145
+ /**
146
+ * Run verification checks in the workspace
147
+ */
148
+ async verify(workspacePath, fingerprint, options) {
149
+ const startTime = Date.now();
150
+ const checks = [];
151
+ const timeout = options?.timeout || DEFAULT_TIMEOUT;
152
+ // Build verification command list based on fingerprint
153
+ const commands = this.getVerificationCommands(fingerprint, options?.skipTests);
154
+ for (const { name, command } of commands) {
155
+ const checkStart = Date.now();
156
+ let passed = false;
157
+ let output = '';
158
+ try {
159
+ const result = (0, child_process_1.execSync)(command, {
160
+ cwd: workspacePath,
161
+ encoding: 'utf8',
162
+ timeout,
163
+ stdio: ['pipe', 'pipe', 'pipe'],
164
+ env: {
165
+ ...process.env,
166
+ CI: 'true',
167
+ NODE_ENV: 'test',
168
+ },
169
+ });
170
+ passed = true;
171
+ output = this.truncateOutput(result);
172
+ }
173
+ catch (e) {
174
+ const err = e;
175
+ output = this.truncateOutput((err.stderr || '') + '\n' + (err.stdout || '') || err.message);
176
+ }
177
+ checks.push({
178
+ name,
179
+ command,
180
+ passed,
181
+ output,
182
+ duration: Date.now() - checkStart,
183
+ });
184
+ // Stop on first failure for faster feedback
185
+ if (!passed)
186
+ break;
187
+ }
188
+ // Extract top 3 failure contexts
189
+ const failureContext = this.extractFailureContext(checks);
190
+ return {
191
+ passed: checks.every(c => c.passed),
192
+ checks,
193
+ duration: Date.now() - startTime,
194
+ failureContext,
195
+ };
196
+ }
197
+ /**
198
+ * Copy changes back to the original project
199
+ */
200
+ async copyBack(workspacePath, projectPath, files) {
201
+ for (const file of files) {
202
+ const src = path.join(workspacePath, file);
203
+ const dest = path.join(projectPath, file);
204
+ try {
205
+ // Create backup
206
+ if (fs.existsSync(dest)) {
207
+ await fs.promises.copyFile(dest, `${dest}.guardrail-backup`);
208
+ }
209
+ // Copy new version
210
+ await fs.promises.mkdir(path.dirname(dest), { recursive: true });
211
+ await fs.promises.copyFile(src, dest);
212
+ }
213
+ catch (e) {
214
+ throw new Error(`Failed to copy ${file}: ${e.message}`);
215
+ }
216
+ }
217
+ }
218
+ /**
219
+ * Cleanup a workspace
220
+ */
221
+ async cleanup(workspaceId) {
222
+ const info = this.workspaces.get(workspaceId);
223
+ if (!info)
224
+ return;
225
+ // Remove git worktree if applicable
226
+ if (info.type === 'worktree') {
227
+ try {
228
+ (0, child_process_1.execSync)(`git worktree remove "${info.path}" --force`, {
229
+ cwd: info.projectPath,
230
+ stdio: 'pipe',
231
+ });
232
+ }
233
+ catch {
234
+ // Fall through to rm
235
+ }
236
+ }
237
+ // Remove directory
238
+ try {
239
+ await fs.promises.rm(info.path, { recursive: true, force: true });
240
+ }
241
+ catch {
242
+ // Ignore errors
243
+ }
244
+ this.workspaces.delete(workspaceId);
245
+ }
246
+ /**
247
+ * Cleanup all workspaces
248
+ */
249
+ async cleanupAll() {
250
+ for (const id of this.workspaces.keys()) {
251
+ await this.cleanup(id);
252
+ }
253
+ }
254
+ // ==========================================================================
255
+ // PRIVATE METHODS
256
+ // ==========================================================================
257
+ async tryCreateWorktree(projectPath, workspacePath) {
258
+ try {
259
+ const gitDir = path.join(projectPath, '.git');
260
+ if (!fs.existsSync(gitDir)) {
261
+ return false;
262
+ }
263
+ (0, child_process_1.execSync)(`git worktree add "${workspacePath}" HEAD --detach`, {
264
+ cwd: projectPath,
265
+ stdio: 'pipe',
266
+ });
267
+ return true;
268
+ }
269
+ catch {
270
+ return false;
271
+ }
272
+ }
273
+ async copyProject(src, dest) {
274
+ const entries = await fs.promises.readdir(src, { withFileTypes: true });
275
+ for (const entry of entries) {
276
+ if (EXCLUDE_PATTERNS.includes(entry.name)) {
277
+ continue;
278
+ }
279
+ const srcPath = path.join(src, entry.name);
280
+ const destPath = path.join(dest, entry.name);
281
+ if (entry.isDirectory()) {
282
+ await fs.promises.mkdir(destPath, { recursive: true });
283
+ await this.copyProject(srcPath, destPath);
284
+ }
285
+ else if (entry.isFile()) {
286
+ await fs.promises.copyFile(srcPath, destPath);
287
+ }
288
+ }
289
+ }
290
+ async installDependencies(workspacePath, timeout) {
291
+ const execOpts = {
292
+ cwd: workspacePath,
293
+ stdio: 'pipe',
294
+ timeout: timeout || DEFAULT_TIMEOUT,
295
+ };
296
+ // Detect package manager
297
+ if (fs.existsSync(path.join(workspacePath, 'pnpm-lock.yaml'))) {
298
+ (0, child_process_1.execSync)('pnpm install --frozen-lockfile', execOpts);
299
+ }
300
+ else if (fs.existsSync(path.join(workspacePath, 'yarn.lock'))) {
301
+ (0, child_process_1.execSync)('yarn install --frozen-lockfile', execOpts);
302
+ }
303
+ else if (fs.existsSync(path.join(workspacePath, 'package-lock.json'))) {
304
+ (0, child_process_1.execSync)('npm ci', execOpts);
305
+ }
306
+ }
307
+ async tryGitApply(workspacePath, diff, checkOnly) {
308
+ const tempFile = path.join(workspacePath, '.guardrail-patch.diff');
309
+ try {
310
+ await fs.promises.writeFile(tempFile, diff);
311
+ const cmd = checkOnly
312
+ ? `git apply --check "${tempFile}"`
313
+ : `git apply "${tempFile}"`;
314
+ (0, child_process_1.execSync)(cmd, {
315
+ cwd: workspacePath,
316
+ stdio: 'pipe',
317
+ });
318
+ return { success: true };
319
+ }
320
+ catch (e) {
321
+ const err = e;
322
+ return {
323
+ success: false,
324
+ error: err.stderr?.toString() || err.message,
325
+ };
326
+ }
327
+ finally {
328
+ try {
329
+ await fs.promises.unlink(tempFile);
330
+ }
331
+ catch {
332
+ // Ignore
333
+ }
334
+ }
335
+ }
336
+ async applyHunk(workspacePath, hunk) {
337
+ const filePath = path.join(workspacePath, hunk.file);
338
+ // Ensure directory exists
339
+ await fs.promises.mkdir(path.dirname(filePath), { recursive: true });
340
+ // Read existing content or empty for new files
341
+ let content = '';
342
+ try {
343
+ content = await fs.promises.readFile(filePath, 'utf8');
344
+ }
345
+ catch {
346
+ // New file
347
+ }
348
+ const lines = content.split('\n');
349
+ const hunkLines = hunk.content.split('\n').filter(l => !l.startsWith('@@'));
350
+ const result = [];
351
+ let srcIdx = 0;
352
+ // Copy lines before hunk
353
+ while (srcIdx < hunk.oldStart - 1 && srcIdx < lines.length) {
354
+ result.push(lines[srcIdx] || '');
355
+ srcIdx++;
356
+ }
357
+ // Process hunk
358
+ for (const line of hunkLines) {
359
+ if (line.startsWith('-')) {
360
+ srcIdx++; // Skip deleted line
361
+ }
362
+ else if (line.startsWith('+')) {
363
+ result.push(line.slice(1)); // Add new line
364
+ }
365
+ else if (line.startsWith(' ') || line === '') {
366
+ if (srcIdx < lines.length) {
367
+ result.push(lines[srcIdx] || '');
368
+ srcIdx++;
369
+ }
370
+ }
371
+ }
372
+ // Copy remaining lines
373
+ while (srcIdx < lines.length) {
374
+ result.push(lines[srcIdx] || '');
375
+ srcIdx++;
376
+ }
377
+ await fs.promises.writeFile(filePath, result.join('\n'));
378
+ }
379
+ getVerificationCommands(fingerprint, skipTests) {
380
+ const commands = [];
381
+ // TypeScript check
382
+ if (fingerprint.hasTypeScript) {
383
+ commands.push({
384
+ name: 'TypeScript',
385
+ command: 'npx tsc --noEmit',
386
+ });
387
+ }
388
+ // Build check based on framework
389
+ if (fingerprint.buildTool === 'turbo') {
390
+ commands.push({ name: 'Build (Turbo)', command: 'npx turbo run build' });
391
+ }
392
+ else if (fingerprint.buildTool === 'nx') {
393
+ commands.push({ name: 'Build (Nx)', command: 'npx nx run-many --target=build' });
394
+ }
395
+ else if (fingerprint.framework === 'next') {
396
+ commands.push({ name: 'Build (Next.js)', command: 'npm run build' });
397
+ }
398
+ else if (fingerprint.framework === 'vite') {
399
+ commands.push({ name: 'Build (Vite)', command: 'npm run build' });
400
+ }
401
+ else if (fingerprint.hasBuildScript) {
402
+ commands.push({ name: 'Build', command: 'npm run build' });
403
+ }
404
+ // Tests (optional)
405
+ if (!skipTests && fingerprint.testRunner) {
406
+ const testCmd = fingerprint.testRunner === 'vitest'
407
+ ? 'npx vitest run'
408
+ : fingerprint.testRunner === 'jest'
409
+ ? 'npx jest --passWithNoTests'
410
+ : 'npm test';
411
+ commands.push({ name: `Tests (${fingerprint.testRunner})`, command: testCmd });
412
+ }
413
+ return commands;
414
+ }
415
+ truncateOutput(output) {
416
+ const lines = output.split('\n');
417
+ if (lines.length <= MAX_OUTPUT_LINES) {
418
+ return output;
419
+ }
420
+ return lines.slice(0, MAX_OUTPUT_LINES).join('\n') + `\n... (${lines.length - MAX_OUTPUT_LINES} more lines)`;
421
+ }
422
+ extractFailureContext(checks) {
423
+ const failures = [];
424
+ for (const check of checks) {
425
+ if (check.passed)
426
+ continue;
427
+ const lines = check.output.split('\n');
428
+ const errorLines = [];
429
+ for (const line of lines) {
430
+ // TypeScript errors
431
+ if (line.includes('error TS') || line.includes(': error')) {
432
+ errorLines.push(line.trim());
433
+ }
434
+ // Build errors
435
+ else if (line.includes('Error:') || line.includes('error:')) {
436
+ errorLines.push(line.trim());
437
+ }
438
+ // Test failures
439
+ else if (line.includes('FAIL') || line.includes('✗') || line.includes('×')) {
440
+ errorLines.push(line.trim());
441
+ }
442
+ if (errorLines.length >= 3)
443
+ break;
444
+ }
445
+ failures.push(...errorLines);
446
+ if (failures.length >= 3)
447
+ break;
448
+ }
449
+ return failures.slice(0, 3);
450
+ }
451
+ }
452
+ exports.TempWorkspace = TempWorkspace;
453
+ // Export singleton
454
+ exports.tempWorkspace = new TempWorkspace();
@@ -0,0 +1,182 @@
1
+ /**
2
+ * Verified Autofix System - PRO+ Feature
3
+ *
4
+ * Core monetization feature that provides:
5
+ * 1. Strict Build Mode prompts requiring JSON output with unified diff
6
+ * 2. Validation of strict output protocol
7
+ * 3. Temp workspace application with full verification pipeline
8
+ * 4. Auto-reprompt on failure with tight failure context
9
+ * 5. Apply patch only if verification passes
10
+ *
11
+ * PRICING: This is a PRO+ feature. Prompts alone are free.
12
+ * Paid value = prompts + strict diff protocol + verification + apply-only-if-pass
13
+ */
14
+ export type FixPackType = 'route-integrity' | 'placeholders' | 'type-errors' | 'build-blockers' | 'test-failures';
15
+ export interface FixPackConfig {
16
+ type: FixPackType;
17
+ name: string;
18
+ description: string;
19
+ scanCommand: string;
20
+ verifyCommands: string[];
21
+ maxAttempts: number;
22
+ requiredTier: 'pro' | 'compliance' | 'enterprise';
23
+ }
24
+ export interface DiffHunk {
25
+ file: string;
26
+ oldStart: number;
27
+ oldLines: number;
28
+ newStart: number;
29
+ newLines: number;
30
+ content: string;
31
+ }
32
+ export interface StrictAgentOutput {
33
+ success: boolean;
34
+ explanation: string;
35
+ diffs: DiffHunk[];
36
+ filesModified: string[];
37
+ confidence: number;
38
+ warnings?: string[];
39
+ }
40
+ export interface VerificationResult {
41
+ passed: boolean;
42
+ checks: {
43
+ name: string;
44
+ passed: boolean;
45
+ message: string;
46
+ duration: number;
47
+ }[];
48
+ blockers: string[];
49
+ duration: number;
50
+ }
51
+ export interface AutofixResult {
52
+ success: boolean;
53
+ fixPack: FixPackType;
54
+ attempts: number;
55
+ maxAttempts: number;
56
+ duration: number;
57
+ verification: VerificationResult | null;
58
+ appliedDiffs: number;
59
+ filesModified: string[];
60
+ errors: string[];
61
+ generatedDiffs: DiffHunk[];
62
+ aiExplanation: string;
63
+ metrics: {
64
+ promptTokens: number;
65
+ completionTokens: number;
66
+ repromptCount: number;
67
+ verificationTime: number;
68
+ };
69
+ }
70
+ export interface AutofixOptions {
71
+ projectPath: string;
72
+ fixPack: FixPackType;
73
+ dryRun?: boolean;
74
+ verbose?: boolean;
75
+ maxAttempts?: number;
76
+ onProgress?: (stage: string, message: string) => void;
77
+ }
78
+ export declare const FIX_PACKS: Record<FixPackType, FixPackConfig>;
79
+ /**
80
+ * Validate strict agent output format
81
+ */
82
+ export declare function validateStrictOutput(output: unknown): {
83
+ valid: boolean;
84
+ errors: string[];
85
+ };
86
+ /**
87
+ * Generate strict Build Mode prompt for agent with file context
88
+ */
89
+ export declare function generateBuildModePromptWithContext(fixPack: FixPackType, scanOutput: string, context: {
90
+ projectPath: string;
91
+ framework?: string;
92
+ }): Promise<string>;
93
+ /**
94
+ * Generate strict Build Mode prompt for agent (sync version for compatibility)
95
+ */
96
+ export declare function generateBuildModePrompt(fixPack: FixPackType, scanOutput: string, context: {
97
+ projectPath: string;
98
+ framework?: string;
99
+ }): string;
100
+ /**
101
+ * Generate reprompt with failure context
102
+ */
103
+ export declare function generateRepromptWithFailures(originalPrompt: string, _previousOutput: StrictAgentOutput, verification: VerificationResult): string;
104
+ export declare class TempWorkspaceManager {
105
+ private baseDir;
106
+ private workspaces;
107
+ constructor();
108
+ /**
109
+ * Create isolated workspace using git worktree (preferred) or copy
110
+ */
111
+ createWorkspace(projectPath: string): Promise<string>;
112
+ /**
113
+ * Apply diffs to workspace
114
+ */
115
+ applyDiffs(workspacePath: string, diffs: DiffHunk[]): Promise<{
116
+ applied: number;
117
+ errors: string[];
118
+ }>;
119
+ /**
120
+ * Cleanup workspace
121
+ */
122
+ cleanup(workspacePath: string): Promise<void>;
123
+ private findProjectForWorkspace;
124
+ private copyProject;
125
+ private applyUnifiedDiff;
126
+ /**
127
+ * Check if this is a simple line addition/replacement
128
+ */
129
+ private isSimpleReplacement;
130
+ /**
131
+ * Apply a simple replacement/insertion
132
+ */
133
+ private applySimpleReplacement;
134
+ }
135
+ export declare class VerificationPipeline {
136
+ /**
137
+ * Run verification checks on workspace
138
+ */
139
+ verify(workspacePath: string, checks: string[], onProgress?: (check: string, status: 'running' | 'passed' | 'failed') => void): Promise<VerificationResult>;
140
+ /**
141
+ * Run additional security checks
142
+ */
143
+ securityChecks(workspacePath: string): Promise<{
144
+ passed: boolean;
145
+ issues: string[];
146
+ }>;
147
+ private findFiles;
148
+ }
149
+ export declare class VerifiedAutofixRunner {
150
+ private workspaceManager;
151
+ private verificationPipeline;
152
+ constructor();
153
+ /**
154
+ * Run verified autofix process
155
+ */
156
+ run(options: AutofixOptions): Promise<AutofixResult>;
157
+ /**
158
+ * Call AI agent using OpenAI or Anthropic API
159
+ * Prefers OpenAI if OPENAI_API_KEY is set, otherwise falls back to Anthropic
160
+ */
161
+ private callAgent;
162
+ /**
163
+ * Apply diffs to actual project
164
+ */
165
+ private applyToProject;
166
+ }
167
+ export interface CostEstimate {
168
+ model: string;
169
+ estimatedTokens: number;
170
+ estimatedCost: number;
171
+ currency: string;
172
+ }
173
+ export declare function estimateCost(promptLength: number, model?: string): CostEstimate;
174
+ export declare function listBackups(projectPath: string): Promise<string[]>;
175
+ export declare function restoreBackups(projectPath: string): Promise<{
176
+ restored: string[];
177
+ errors: string[];
178
+ }>;
179
+ export declare function cleanBackups(projectPath: string): Promise<number>;
180
+ export declare const verifiedAutofix: VerifiedAutofixRunner;
181
+ export declare const runVerifiedAutofix: (options: AutofixOptions) => Promise<AutofixResult>;
182
+ //# sourceMappingURL=verified-autofix.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verified-autofix.d.ts","sourceRoot":"","sources":["../src/verified-autofix.ts"],"names":[],"mappings":"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"}