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.
- package/dist/__tests__/autopilot.test.d.ts +7 -0
- package/dist/__tests__/autopilot.test.d.ts.map +1 -0
- package/dist/__tests__/autopilot.test.js +156 -0
- package/dist/__tests__/tier-config.test.d.ts +9 -0
- package/dist/__tests__/tier-config.test.d.ts.map +1 -0
- package/dist/__tests__/tier-config.test.js +230 -0
- package/dist/__tests__/utils/hash-inline.test.d.ts +2 -0
- package/dist/__tests__/utils/hash-inline.test.d.ts.map +1 -0
- package/dist/__tests__/utils/hash-inline.test.js +62 -0
- package/dist/__tests__/utils/hash.test.d.ts +3 -0
- package/dist/__tests__/utils/hash.test.d.ts.map +1 -0
- package/dist/__tests__/utils/hash.test.js +95 -0
- package/dist/__tests__/utils/simple.test.d.ts +1 -0
- package/dist/__tests__/utils/simple.test.d.ts.map +1 -0
- package/dist/__tests__/utils/simple.test.js +10 -0
- package/dist/__tests__/utils/utils-simple.test.d.ts +1 -0
- package/dist/__tests__/utils/utils-simple.test.d.ts.map +1 -0
- package/dist/__tests__/utils/utils-simple.test.js +6 -0
- package/dist/__tests__/utils/utils.test.d.ts +15 -0
- package/dist/__tests__/utils/utils.test.d.ts.map +1 -0
- package/dist/__tests__/utils/utils.test.js +172 -0
- package/dist/autopilot/autopilot-runner.d.ts +33 -0
- package/dist/autopilot/autopilot-runner.d.ts.map +1 -0
- package/dist/autopilot/autopilot-runner.js +479 -0
- package/dist/autopilot/index.d.ts +6 -0
- package/dist/autopilot/index.d.ts.map +1 -0
- package/dist/autopilot/index.js +25 -0
- package/dist/autopilot/types.d.ts +102 -0
- package/dist/autopilot/types.d.ts.map +1 -0
- package/dist/autopilot/types.js +18 -0
- package/dist/cache/index.d.ts +7 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +22 -0
- package/dist/cache/redis-cache.d.ts +145 -0
- package/dist/cache/redis-cache.d.ts.map +1 -0
- package/dist/cache/redis-cache.js +459 -0
- package/dist/ci/github-actions.d.ts +77 -0
- package/dist/ci/github-actions.d.ts.map +1 -0
- package/dist/ci/github-actions.js +277 -0
- package/dist/ci/index.d.ts +12 -0
- package/dist/ci/index.d.ts.map +1 -0
- package/dist/ci/index.js +27 -0
- package/dist/ci/pre-commit.d.ts +65 -0
- package/dist/ci/pre-commit.d.ts.map +1 -0
- package/dist/ci/pre-commit.js +286 -0
- package/dist/entitlements.d.ts +149 -0
- package/dist/entitlements.d.ts.map +1 -0
- package/dist/entitlements.js +464 -0
- package/dist/env.d.ts +113 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +204 -0
- package/dist/fix-packs/__tests__/generate-fix-packs.test.d.ts +7 -0
- package/dist/fix-packs/__tests__/generate-fix-packs.test.d.ts.map +1 -0
- package/dist/fix-packs/__tests__/generate-fix-packs.test.js +250 -0
- package/dist/fix-packs/generate-fix-packs.d.ts +15 -0
- package/dist/fix-packs/generate-fix-packs.d.ts.map +1 -0
- package/dist/fix-packs/generate-fix-packs.js +505 -0
- package/dist/fix-packs/index.d.ts +8 -0
- package/dist/fix-packs/index.d.ts.map +1 -0
- package/dist/fix-packs/index.js +23 -0
- package/dist/fix-packs/types.d.ts +113 -0
- package/dist/fix-packs/types.d.ts.map +1 -0
- package/dist/fix-packs/types.js +71 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/metrics/prometheus.d.ts +99 -0
- package/dist/metrics/prometheus.d.ts.map +1 -0
- package/dist/metrics/prometheus.js +306 -0
- package/dist/quota-ledger.d.ts +119 -0
- package/dist/quota-ledger.d.ts.map +1 -0
- package/dist/quota-ledger.js +462 -0
- package/dist/rbac/__tests__/permissions.test.d.ts +8 -0
- package/dist/rbac/__tests__/permissions.test.d.ts.map +1 -0
- package/dist/rbac/__tests__/permissions.test.js +350 -0
- package/dist/rbac/index.d.ts +9 -0
- package/dist/rbac/index.d.ts.map +1 -0
- package/dist/rbac/index.js +32 -0
- package/dist/rbac/permissions.d.ts +71 -0
- package/dist/rbac/permissions.d.ts.map +1 -0
- package/dist/rbac/permissions.js +247 -0
- package/dist/rbac/types.d.ts +69 -0
- package/dist/rbac/types.d.ts.map +1 -0
- package/dist/rbac/types.js +213 -0
- package/dist/tier-config.d.ts +203 -0
- package/dist/tier-config.d.ts.map +1 -0
- package/dist/tier-config.js +675 -0
- package/dist/types.d.ts +365 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/utils.d.ts +36 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +127 -0
- package/dist/verified-autofix/__tests__/format-validator.test.d.ts +11 -0
- package/dist/verified-autofix/__tests__/format-validator.test.d.ts.map +1 -0
- package/dist/verified-autofix/__tests__/format-validator.test.js +285 -0
- package/dist/verified-autofix/__tests__/pipeline.test.d.ts +11 -0
- package/dist/verified-autofix/__tests__/pipeline.test.d.ts.map +1 -0
- package/dist/verified-autofix/__tests__/pipeline.test.js +389 -0
- package/dist/verified-autofix/__tests__/repo-fingerprint.test.d.ts +11 -0
- package/dist/verified-autofix/__tests__/repo-fingerprint.test.d.ts.map +1 -0
- package/dist/verified-autofix/__tests__/repo-fingerprint.test.js +236 -0
- package/dist/verified-autofix/__tests__/workspace.test.d.ts +11 -0
- package/dist/verified-autofix/__tests__/workspace.test.d.ts.map +1 -0
- package/dist/verified-autofix/__tests__/workspace.test.js +314 -0
- package/dist/verified-autofix/format-validator.d.ts +101 -0
- package/dist/verified-autofix/format-validator.d.ts.map +1 -0
- package/dist/verified-autofix/format-validator.js +446 -0
- package/dist/verified-autofix/index.d.ts +14 -0
- package/dist/verified-autofix/index.d.ts.map +1 -0
- package/dist/verified-autofix/index.js +39 -0
- package/dist/verified-autofix/pipeline.d.ts +68 -0
- package/dist/verified-autofix/pipeline.d.ts.map +1 -0
- package/dist/verified-autofix/pipeline.js +330 -0
- package/dist/verified-autofix/repo-fingerprint.d.ts +56 -0
- package/dist/verified-autofix/repo-fingerprint.d.ts.map +1 -0
- package/dist/verified-autofix/repo-fingerprint.js +396 -0
- package/dist/verified-autofix/workspace.d.ts +83 -0
- package/dist/verified-autofix/workspace.d.ts.map +1 -0
- package/dist/verified-autofix/workspace.js +454 -0
- package/dist/verified-autofix.d.ts +182 -0
- package/dist/verified-autofix.d.ts.map +1 -0
- package/dist/verified-autofix.js +1021 -0
- package/dist/visualization/dependency-graph.d.ts +79 -0
- package/dist/visualization/dependency-graph.d.ts.map +1 -0
- package/dist/visualization/dependency-graph.js +399 -0
- package/dist/visualization/index.d.ts +5 -0
- package/dist/visualization/index.d.ts.map +1 -0
- package/dist/visualization/index.js +20 -0
- package/package.json +29 -0
- package/src/__tests__/autopilot.test.ts +196 -0
- package/src/__tests__/tier-config.test.ts +289 -0
- package/src/__tests__/utils/hash-inline.test.ts +76 -0
- package/src/__tests__/utils/hash.test.ts +119 -0
- package/src/__tests__/utils/simple.test.ts +10 -0
- package/src/__tests__/utils/utils-simple.test.ts +5 -0
- package/src/__tests__/utils/utils.test.ts +203 -0
- package/src/autopilot/autopilot-runner.ts +503 -0
- package/src/autopilot/index.ts +6 -0
- package/src/autopilot/types.ts +119 -0
- package/src/cache/index.ts +7 -0
- package/src/cache/redis-cache.d.ts +155 -0
- package/src/cache/redis-cache.d.ts.map +1 -0
- package/src/cache/redis-cache.ts +517 -0
- package/src/ci/github-actions.ts +335 -0
- package/src/ci/index.ts +12 -0
- package/src/ci/pre-commit.ts +338 -0
- package/src/db/usage-schema.prisma +114 -0
- package/src/entitlements.ts +570 -0
- package/src/env.d.ts +68 -0
- package/src/env.d.ts.map +1 -0
- package/src/env.ts +247 -0
- package/src/fix-packs/__tests__/generate-fix-packs.test.ts +317 -0
- package/src/fix-packs/generate-fix-packs.ts +577 -0
- package/src/fix-packs/index.ts +8 -0
- package/src/fix-packs/types.ts +206 -0
- package/src/index.d.ts +7 -0
- package/src/index.d.ts.map +1 -0
- package/src/index.ts +12 -0
- package/src/metrics/prometheus.d.ts +104 -0
- package/src/metrics/prometheus.d.ts.map +1 -0
- package/src/metrics/prometheus.ts +446 -0
- package/src/quota-ledger.ts +548 -0
- package/src/rbac/__tests__/permissions.test.ts +446 -0
- package/src/rbac/index.ts +46 -0
- package/src/rbac/permissions.ts +301 -0
- package/src/rbac/types.ts +298 -0
- package/src/tier-config.json +157 -0
- package/src/tier-config.ts +815 -0
- package/src/types.d.ts +365 -0
- package/src/types.d.ts.map +1 -0
- package/src/types.ts +441 -0
- package/src/utils.d.ts +36 -0
- package/src/utils.d.ts.map +1 -0
- package/src/utils.ts +140 -0
- package/src/verified-autofix/__tests__/format-validator.test.ts +335 -0
- package/src/verified-autofix/__tests__/pipeline.test.ts +419 -0
- package/src/verified-autofix/__tests__/repo-fingerprint.test.ts +241 -0
- package/src/verified-autofix/__tests__/workspace.test.ts +373 -0
- package/src/verified-autofix/format-validator.ts +517 -0
- package/src/verified-autofix/index.ts +63 -0
- package/src/verified-autofix/pipeline.ts +403 -0
- package/src/verified-autofix/repo-fingerprint.ts +459 -0
- package/src/verified-autofix/workspace.ts +531 -0
- package/src/verified-autofix.ts +1187 -0
- package/src/visualization/dependency-graph.d.ts +85 -0
- package/src/visualization/dependency-graph.d.ts.map +1 -0
- package/src/visualization/dependency-graph.ts +495 -0
- package/src/visualization/index.ts +5 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repo Fingerprint Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests for project detection and configuration:
|
|
5
|
+
* - Package manager detection
|
|
6
|
+
* - Build tool detection
|
|
7
|
+
* - Framework detection
|
|
8
|
+
* - Test runner detection
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=repo-fingerprint.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repo-fingerprint.test.d.ts","sourceRoot":"","sources":["../../../src/verified-autofix/__tests__/repo-fingerprint.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Repo Fingerprint Tests
|
|
4
|
+
*
|
|
5
|
+
* Tests for project detection and configuration:
|
|
6
|
+
* - Package manager detection
|
|
7
|
+
* - Build tool detection
|
|
8
|
+
* - Framework detection
|
|
9
|
+
* - Test runner detection
|
|
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
|
+
const fs = __importStar(require("fs"));
|
|
46
|
+
const path = __importStar(require("path"));
|
|
47
|
+
const os = __importStar(require("os"));
|
|
48
|
+
const repo_fingerprint_1 = require("../repo-fingerprint");
|
|
49
|
+
describe('fingerprintRepo', () => {
|
|
50
|
+
let tempDir;
|
|
51
|
+
beforeEach(async () => {
|
|
52
|
+
tempDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'fingerprint-test-'));
|
|
53
|
+
});
|
|
54
|
+
afterEach(async () => {
|
|
55
|
+
await fs.promises.rm(tempDir, { recursive: true, force: true });
|
|
56
|
+
});
|
|
57
|
+
it('detects pnpm from lock file', async () => {
|
|
58
|
+
await fs.promises.writeFile(path.join(tempDir, 'pnpm-lock.yaml'), '');
|
|
59
|
+
await fs.promises.writeFile(path.join(tempDir, 'package.json'), JSON.stringify({
|
|
60
|
+
name: 'test',
|
|
61
|
+
dependencies: {},
|
|
62
|
+
}));
|
|
63
|
+
const { fingerprint } = (0, repo_fingerprint_1.fingerprintRepo)(tempDir);
|
|
64
|
+
expect(fingerprint.packageManager).toBe('pnpm');
|
|
65
|
+
});
|
|
66
|
+
it('detects yarn from lock file', async () => {
|
|
67
|
+
await fs.promises.writeFile(path.join(tempDir, 'yarn.lock'), '');
|
|
68
|
+
await fs.promises.writeFile(path.join(tempDir, 'package.json'), JSON.stringify({
|
|
69
|
+
name: 'test',
|
|
70
|
+
}));
|
|
71
|
+
const { fingerprint } = (0, repo_fingerprint_1.fingerprintRepo)(tempDir);
|
|
72
|
+
expect(fingerprint.packageManager).toBe('yarn');
|
|
73
|
+
});
|
|
74
|
+
it('detects npm from lock file', async () => {
|
|
75
|
+
await fs.promises.writeFile(path.join(tempDir, 'package-lock.json'), '{}');
|
|
76
|
+
await fs.promises.writeFile(path.join(tempDir, 'package.json'), JSON.stringify({
|
|
77
|
+
name: 'test',
|
|
78
|
+
}));
|
|
79
|
+
const { fingerprint } = (0, repo_fingerprint_1.fingerprintRepo)(tempDir);
|
|
80
|
+
expect(fingerprint.packageManager).toBe('npm');
|
|
81
|
+
});
|
|
82
|
+
it('detects Next.js framework', async () => {
|
|
83
|
+
await fs.promises.writeFile(path.join(tempDir, 'package.json'), JSON.stringify({
|
|
84
|
+
name: 'test',
|
|
85
|
+
dependencies: { next: '^14.0.0', react: '^18.0.0' },
|
|
86
|
+
}));
|
|
87
|
+
const { fingerprint } = (0, repo_fingerprint_1.fingerprintRepo)(tempDir);
|
|
88
|
+
expect(fingerprint.framework).toBe('next');
|
|
89
|
+
});
|
|
90
|
+
it('detects Vite framework', async () => {
|
|
91
|
+
await fs.promises.writeFile(path.join(tempDir, 'package.json'), JSON.stringify({
|
|
92
|
+
name: 'test',
|
|
93
|
+
devDependencies: { vite: '^5.0.0' },
|
|
94
|
+
}));
|
|
95
|
+
const { fingerprint } = (0, repo_fingerprint_1.fingerprintRepo)(tempDir);
|
|
96
|
+
expect(fingerprint.framework).toBe('vite');
|
|
97
|
+
});
|
|
98
|
+
it('detects Jest test runner', async () => {
|
|
99
|
+
await fs.promises.writeFile(path.join(tempDir, 'package.json'), JSON.stringify({
|
|
100
|
+
name: 'test',
|
|
101
|
+
devDependencies: { jest: '^29.0.0' },
|
|
102
|
+
}));
|
|
103
|
+
const { fingerprint } = (0, repo_fingerprint_1.fingerprintRepo)(tempDir);
|
|
104
|
+
expect(fingerprint.testRunner).toBe('jest');
|
|
105
|
+
});
|
|
106
|
+
it('detects Vitest test runner', async () => {
|
|
107
|
+
await fs.promises.writeFile(path.join(tempDir, 'package.json'), JSON.stringify({
|
|
108
|
+
name: 'test',
|
|
109
|
+
devDependencies: { vitest: '^1.0.0' },
|
|
110
|
+
}));
|
|
111
|
+
const { fingerprint } = (0, repo_fingerprint_1.fingerprintRepo)(tempDir);
|
|
112
|
+
expect(fingerprint.testRunner).toBe('vitest');
|
|
113
|
+
});
|
|
114
|
+
it('detects TypeScript', async () => {
|
|
115
|
+
await fs.promises.writeFile(path.join(tempDir, 'tsconfig.json'), '{}');
|
|
116
|
+
await fs.promises.writeFile(path.join(tempDir, 'package.json'), JSON.stringify({
|
|
117
|
+
name: 'test',
|
|
118
|
+
}));
|
|
119
|
+
const { fingerprint } = (0, repo_fingerprint_1.fingerprintRepo)(tempDir);
|
|
120
|
+
expect(fingerprint.hasTypeScript).toBe(true);
|
|
121
|
+
});
|
|
122
|
+
it('detects Turbo build tool', async () => {
|
|
123
|
+
await fs.promises.writeFile(path.join(tempDir, 'turbo.json'), '{}');
|
|
124
|
+
await fs.promises.writeFile(path.join(tempDir, 'package.json'), JSON.stringify({
|
|
125
|
+
name: 'test',
|
|
126
|
+
}));
|
|
127
|
+
const { fingerprint } = (0, repo_fingerprint_1.fingerprintRepo)(tempDir);
|
|
128
|
+
expect(fingerprint.buildTool).toBe('turbo');
|
|
129
|
+
});
|
|
130
|
+
it('detects monorepo from workspaces', async () => {
|
|
131
|
+
await fs.promises.writeFile(path.join(tempDir, 'package.json'), JSON.stringify({
|
|
132
|
+
name: 'monorepo',
|
|
133
|
+
workspaces: ['packages/*'],
|
|
134
|
+
}));
|
|
135
|
+
const { fingerprint } = (0, repo_fingerprint_1.fingerprintRepo)(tempDir);
|
|
136
|
+
expect(fingerprint.isMonorepo).toBe(true);
|
|
137
|
+
expect(fingerprint.workspaces).toContain('packages/*');
|
|
138
|
+
});
|
|
139
|
+
it('detects build script', async () => {
|
|
140
|
+
await fs.promises.writeFile(path.join(tempDir, 'package.json'), JSON.stringify({
|
|
141
|
+
name: 'test',
|
|
142
|
+
scripts: { build: 'tsc' },
|
|
143
|
+
}));
|
|
144
|
+
const { fingerprint } = (0, repo_fingerprint_1.fingerprintRepo)(tempDir);
|
|
145
|
+
expect(fingerprint.hasBuildScript).toBe(true);
|
|
146
|
+
});
|
|
147
|
+
it('handles missing package.json gracefully', () => {
|
|
148
|
+
const { fingerprint, confidence, detectionNotes } = (0, repo_fingerprint_1.fingerprintRepo)(tempDir);
|
|
149
|
+
expect(fingerprint.packageManager).toBe('unknown');
|
|
150
|
+
expect(confidence).toBeLessThan(100);
|
|
151
|
+
expect(detectionNotes).toContain('No package.json found');
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
describe('command helpers', () => {
|
|
155
|
+
it('returns correct install command for pnpm', () => {
|
|
156
|
+
expect((0, repo_fingerprint_1.getInstallCommand)('pnpm')).toBe('pnpm install --frozen-lockfile');
|
|
157
|
+
});
|
|
158
|
+
it('returns correct install command for yarn', () => {
|
|
159
|
+
expect((0, repo_fingerprint_1.getInstallCommand)('yarn')).toBe('yarn install --frozen-lockfile');
|
|
160
|
+
});
|
|
161
|
+
it('returns correct install command for npm', () => {
|
|
162
|
+
expect((0, repo_fingerprint_1.getInstallCommand)('npm')).toBe('npm ci');
|
|
163
|
+
});
|
|
164
|
+
it('returns turbo build command when turbo detected', () => {
|
|
165
|
+
const fingerprint = {
|
|
166
|
+
buildTool: 'turbo',
|
|
167
|
+
hasBuildScript: true,
|
|
168
|
+
hasTypeScript: true,
|
|
169
|
+
packageManager: 'pnpm',
|
|
170
|
+
framework: 'next',
|
|
171
|
+
testRunner: 'jest',
|
|
172
|
+
hasESLint: true,
|
|
173
|
+
hasPrettier: true,
|
|
174
|
+
hasTestScript: true,
|
|
175
|
+
isMonorepo: true,
|
|
176
|
+
workspaces: ['packages/*'],
|
|
177
|
+
dependencies: {},
|
|
178
|
+
devDependencies: {},
|
|
179
|
+
};
|
|
180
|
+
expect((0, repo_fingerprint_1.getBuildCommand)(fingerprint)).toBe('npx turbo run build');
|
|
181
|
+
});
|
|
182
|
+
it('returns vitest command for vitest runner', () => {
|
|
183
|
+
const fingerprint = {
|
|
184
|
+
testRunner: 'vitest',
|
|
185
|
+
hasTestScript: true,
|
|
186
|
+
buildTool: 'none',
|
|
187
|
+
hasBuildScript: false,
|
|
188
|
+
hasTypeScript: false,
|
|
189
|
+
packageManager: 'npm',
|
|
190
|
+
framework: 'none',
|
|
191
|
+
hasESLint: false,
|
|
192
|
+
hasPrettier: false,
|
|
193
|
+
isMonorepo: false,
|
|
194
|
+
workspaces: [],
|
|
195
|
+
dependencies: {},
|
|
196
|
+
devDependencies: {},
|
|
197
|
+
};
|
|
198
|
+
expect((0, repo_fingerprint_1.getTestCommand)(fingerprint)).toBe('npx vitest run');
|
|
199
|
+
});
|
|
200
|
+
it('returns typecheck command when TypeScript present', () => {
|
|
201
|
+
const fingerprint = {
|
|
202
|
+
hasTypeScript: true,
|
|
203
|
+
testRunner: 'none',
|
|
204
|
+
hasTestScript: false,
|
|
205
|
+
buildTool: 'none',
|
|
206
|
+
hasBuildScript: false,
|
|
207
|
+
packageManager: 'npm',
|
|
208
|
+
framework: 'none',
|
|
209
|
+
hasESLint: false,
|
|
210
|
+
hasPrettier: false,
|
|
211
|
+
isMonorepo: false,
|
|
212
|
+
workspaces: [],
|
|
213
|
+
dependencies: {},
|
|
214
|
+
devDependencies: {},
|
|
215
|
+
};
|
|
216
|
+
expect((0, repo_fingerprint_1.getTypecheckCommand)(fingerprint)).toBe('npx tsc --noEmit');
|
|
217
|
+
});
|
|
218
|
+
it('returns null typecheck command when no TypeScript', () => {
|
|
219
|
+
const fingerprint = {
|
|
220
|
+
hasTypeScript: false,
|
|
221
|
+
testRunner: 'none',
|
|
222
|
+
hasTestScript: false,
|
|
223
|
+
buildTool: 'none',
|
|
224
|
+
hasBuildScript: false,
|
|
225
|
+
packageManager: 'npm',
|
|
226
|
+
framework: 'none',
|
|
227
|
+
hasESLint: false,
|
|
228
|
+
hasPrettier: false,
|
|
229
|
+
isMonorepo: false,
|
|
230
|
+
workspaces: [],
|
|
231
|
+
dependencies: {},
|
|
232
|
+
devDependencies: {},
|
|
233
|
+
};
|
|
234
|
+
expect((0, repo_fingerprint_1.getTypecheckCommand)(fingerprint)).toBeNull();
|
|
235
|
+
});
|
|
236
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace Tests - Temp Workspace Manager
|
|
3
|
+
*
|
|
4
|
+
* Tests for isolated workspace verification:
|
|
5
|
+
* - Workspace creation (copy and worktree)
|
|
6
|
+
* - Diff application via git apply
|
|
7
|
+
* - Verification command execution
|
|
8
|
+
* - Top 3 failure context extraction
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=workspace.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace.test.d.ts","sourceRoot":"","sources":["../../../src/verified-autofix/__tests__/workspace.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Workspace Tests - Temp Workspace Manager
|
|
4
|
+
*
|
|
5
|
+
* Tests for isolated workspace verification:
|
|
6
|
+
* - Workspace creation (copy and worktree)
|
|
7
|
+
* - Diff application via git apply
|
|
8
|
+
* - Verification command execution
|
|
9
|
+
* - Top 3 failure context extraction
|
|
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
|
+
const fs = __importStar(require("fs"));
|
|
46
|
+
const path = __importStar(require("path"));
|
|
47
|
+
const os = __importStar(require("os"));
|
|
48
|
+
const child_process_1 = require("child_process");
|
|
49
|
+
const workspace_1 = require("../workspace");
|
|
50
|
+
describe('TempWorkspace', () => {
|
|
51
|
+
let tempDir;
|
|
52
|
+
let workspace;
|
|
53
|
+
beforeEach(async () => {
|
|
54
|
+
tempDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'workspace-test-'));
|
|
55
|
+
workspace = new workspace_1.TempWorkspace();
|
|
56
|
+
// Create minimal project structure
|
|
57
|
+
await fs.promises.writeFile(path.join(tempDir, 'package.json'), JSON.stringify({
|
|
58
|
+
name: 'test-project',
|
|
59
|
+
version: '1.0.0',
|
|
60
|
+
scripts: {
|
|
61
|
+
build: 'echo "build complete"',
|
|
62
|
+
test: 'echo "tests passed"',
|
|
63
|
+
},
|
|
64
|
+
}));
|
|
65
|
+
// Create a source file
|
|
66
|
+
await fs.promises.mkdir(path.join(tempDir, 'src'), { recursive: true });
|
|
67
|
+
await fs.promises.writeFile(path.join(tempDir, 'src', 'index.ts'), 'export const version = "1.0.0";\n');
|
|
68
|
+
});
|
|
69
|
+
afterEach(async () => {
|
|
70
|
+
await workspace.cleanupAll();
|
|
71
|
+
await fs.promises.rm(tempDir, { recursive: true, force: true });
|
|
72
|
+
});
|
|
73
|
+
describe('create', () => {
|
|
74
|
+
it('creates workspace via copy when not a git repo', async () => {
|
|
75
|
+
const info = await workspace.create({
|
|
76
|
+
projectPath: tempDir,
|
|
77
|
+
useWorktree: true, // Will fall back to copy since no .git
|
|
78
|
+
});
|
|
79
|
+
expect(info.type).toBe('copy');
|
|
80
|
+
expect(fs.existsSync(info.path)).toBe(true);
|
|
81
|
+
expect(fs.existsSync(path.join(info.path, 'package.json'))).toBe(true);
|
|
82
|
+
expect(fs.existsSync(path.join(info.path, 'src', 'index.ts'))).toBe(true);
|
|
83
|
+
});
|
|
84
|
+
it('excludes node_modules from copy', async () => {
|
|
85
|
+
// Create fake node_modules
|
|
86
|
+
await fs.promises.mkdir(path.join(tempDir, 'node_modules', 'lodash'), { recursive: true });
|
|
87
|
+
await fs.promises.writeFile(path.join(tempDir, 'node_modules', 'lodash', 'index.js'), 'module.exports = {};');
|
|
88
|
+
const info = await workspace.create({
|
|
89
|
+
projectPath: tempDir,
|
|
90
|
+
});
|
|
91
|
+
expect(fs.existsSync(path.join(info.path, 'node_modules'))).toBe(false);
|
|
92
|
+
});
|
|
93
|
+
it('excludes .git from copy', async () => {
|
|
94
|
+
// Create fake .git
|
|
95
|
+
await fs.promises.mkdir(path.join(tempDir, '.git'), { recursive: true });
|
|
96
|
+
await fs.promises.writeFile(path.join(tempDir, '.git', 'config'), '');
|
|
97
|
+
const info = await workspace.create({
|
|
98
|
+
projectPath: tempDir,
|
|
99
|
+
useWorktree: false, // Force copy mode
|
|
100
|
+
});
|
|
101
|
+
expect(fs.existsSync(path.join(info.path, '.git'))).toBe(false);
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
describe('applyDiff', () => {
|
|
105
|
+
it('applies simple hunk to file', async () => {
|
|
106
|
+
const info = await workspace.create({ projectPath: tempDir });
|
|
107
|
+
const hunks = [{
|
|
108
|
+
file: 'src/index.ts',
|
|
109
|
+
oldStart: 1,
|
|
110
|
+
oldLines: 1,
|
|
111
|
+
newStart: 1,
|
|
112
|
+
newLines: 2,
|
|
113
|
+
content: `@@ -1,1 +1,2 @@
|
|
114
|
+
export const version = "1.0.0";
|
|
115
|
+
+export const name = "test";`,
|
|
116
|
+
}];
|
|
117
|
+
const diff = `--- a/src/index.ts
|
|
118
|
+
+++ b/src/index.ts
|
|
119
|
+
@@ -1,1 +1,2 @@
|
|
120
|
+
export const version = "1.0.0";
|
|
121
|
+
+export const name = "test";`;
|
|
122
|
+
const result = await workspace.applyDiff(info.path, diff, hunks);
|
|
123
|
+
expect(result.success).toBe(true);
|
|
124
|
+
expect(result.applied).toBe(1);
|
|
125
|
+
expect(result.errors).toHaveLength(0);
|
|
126
|
+
// Verify file was modified
|
|
127
|
+
const content = await fs.promises.readFile(path.join(info.path, 'src', 'index.ts'), 'utf8');
|
|
128
|
+
expect(content).toContain('export const name = "test"');
|
|
129
|
+
});
|
|
130
|
+
it('creates new file from diff', async () => {
|
|
131
|
+
const info = await workspace.create({ projectPath: tempDir });
|
|
132
|
+
const hunks = [{
|
|
133
|
+
file: 'src/utils.ts',
|
|
134
|
+
oldStart: 0,
|
|
135
|
+
oldLines: 0,
|
|
136
|
+
newStart: 1,
|
|
137
|
+
newLines: 1,
|
|
138
|
+
content: `@@ -0,0 +1,1 @@
|
|
139
|
+
+export const add = (a: number, b: number) => a + b;`,
|
|
140
|
+
}];
|
|
141
|
+
const diff = `--- /dev/null
|
|
142
|
+
+++ b/src/utils.ts
|
|
143
|
+
@@ -0,0 +1,1 @@
|
|
144
|
+
+export const add = (a: number, b: number) => a + b;`;
|
|
145
|
+
const result = await workspace.applyDiff(info.path, diff, hunks);
|
|
146
|
+
expect(result.applied).toBeGreaterThan(0);
|
|
147
|
+
expect(fs.existsSync(path.join(info.path, 'src', 'utils.ts'))).toBe(true);
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
describe('verify', () => {
|
|
151
|
+
it('runs verification commands based on fingerprint', async () => {
|
|
152
|
+
const info = await workspace.create({ projectPath: tempDir });
|
|
153
|
+
const fingerprint = {
|
|
154
|
+
packageManager: 'npm',
|
|
155
|
+
buildTool: 'none',
|
|
156
|
+
framework: 'none',
|
|
157
|
+
testRunner: 'none',
|
|
158
|
+
hasTypeScript: false,
|
|
159
|
+
hasESLint: false,
|
|
160
|
+
hasPrettier: false,
|
|
161
|
+
hasBuildScript: true,
|
|
162
|
+
hasTestScript: true,
|
|
163
|
+
isMonorepo: false,
|
|
164
|
+
workspaces: [],
|
|
165
|
+
dependencies: {},
|
|
166
|
+
devDependencies: {},
|
|
167
|
+
};
|
|
168
|
+
const result = await workspace.verify(info.path, fingerprint, {
|
|
169
|
+
skipTests: true,
|
|
170
|
+
});
|
|
171
|
+
// Build should pass (echo command)
|
|
172
|
+
expect(result.passed).toBe(true);
|
|
173
|
+
expect(result.checks.length).toBeGreaterThan(0);
|
|
174
|
+
});
|
|
175
|
+
it('extracts top 3 failure context on error', async () => {
|
|
176
|
+
const info = await workspace.create({ projectPath: tempDir });
|
|
177
|
+
// Create a failing build script
|
|
178
|
+
await fs.promises.writeFile(path.join(info.path, 'package.json'), JSON.stringify({
|
|
179
|
+
name: 'test',
|
|
180
|
+
scripts: {
|
|
181
|
+
build: 'echo "error TS2322: Type mismatch" && echo "error TS2345: Wrong arg" && echo "error TS2339: Missing prop" && exit 1',
|
|
182
|
+
},
|
|
183
|
+
}));
|
|
184
|
+
const fingerprint = {
|
|
185
|
+
packageManager: 'npm',
|
|
186
|
+
buildTool: 'none',
|
|
187
|
+
framework: 'none',
|
|
188
|
+
testRunner: 'none',
|
|
189
|
+
hasTypeScript: false,
|
|
190
|
+
hasESLint: false,
|
|
191
|
+
hasPrettier: false,
|
|
192
|
+
hasBuildScript: true,
|
|
193
|
+
hasTestScript: false,
|
|
194
|
+
isMonorepo: false,
|
|
195
|
+
workspaces: [],
|
|
196
|
+
dependencies: {},
|
|
197
|
+
devDependencies: {},
|
|
198
|
+
};
|
|
199
|
+
const result = await workspace.verify(info.path, fingerprint, {
|
|
200
|
+
skipTests: true,
|
|
201
|
+
});
|
|
202
|
+
expect(result.passed).toBe(false);
|
|
203
|
+
expect(result.failureContext.length).toBeLessThanOrEqual(3);
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
describe('copyBack', () => {
|
|
207
|
+
it('copies modified files back to project', async () => {
|
|
208
|
+
const info = await workspace.create({ projectPath: tempDir });
|
|
209
|
+
// Modify file in workspace
|
|
210
|
+
await fs.promises.writeFile(path.join(info.path, 'src', 'index.ts'), 'export const version = "2.0.0";\n');
|
|
211
|
+
await workspace.copyBack(info.path, tempDir, ['src/index.ts']);
|
|
212
|
+
// Verify original project was updated
|
|
213
|
+
const content = await fs.promises.readFile(path.join(tempDir, 'src', 'index.ts'), 'utf8');
|
|
214
|
+
expect(content).toBe('export const version = "2.0.0";\n');
|
|
215
|
+
});
|
|
216
|
+
it('creates backup before overwriting', async () => {
|
|
217
|
+
const info = await workspace.create({ projectPath: tempDir });
|
|
218
|
+
// Modify file in workspace
|
|
219
|
+
await fs.promises.writeFile(path.join(info.path, 'src', 'index.ts'), 'export const version = "2.0.0";\n');
|
|
220
|
+
await workspace.copyBack(info.path, tempDir, ['src/index.ts']);
|
|
221
|
+
// Backup should exist
|
|
222
|
+
const backupPath = path.join(tempDir, 'src', 'index.ts.guardrail-backup');
|
|
223
|
+
expect(fs.existsSync(backupPath)).toBe(true);
|
|
224
|
+
const backupContent = await fs.promises.readFile(backupPath, 'utf8');
|
|
225
|
+
expect(backupContent).toBe('export const version = "1.0.0";\n');
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
describe('cleanup', () => {
|
|
229
|
+
it('removes workspace directory', async () => {
|
|
230
|
+
const info = await workspace.create({ projectPath: tempDir });
|
|
231
|
+
const workspacePath = info.path;
|
|
232
|
+
expect(fs.existsSync(workspacePath)).toBe(true);
|
|
233
|
+
await workspace.cleanup(info.id);
|
|
234
|
+
expect(fs.existsSync(workspacePath)).toBe(false);
|
|
235
|
+
});
|
|
236
|
+
});
|
|
237
|
+
});
|
|
238
|
+
describe('TempWorkspace with git repo', () => {
|
|
239
|
+
let tempDir;
|
|
240
|
+
let workspace;
|
|
241
|
+
let isGitAvailable;
|
|
242
|
+
beforeAll(() => {
|
|
243
|
+
// Check if git is available
|
|
244
|
+
try {
|
|
245
|
+
(0, child_process_1.execSync)('git --version', { stdio: 'pipe' });
|
|
246
|
+
isGitAvailable = true;
|
|
247
|
+
}
|
|
248
|
+
catch {
|
|
249
|
+
isGitAvailable = false;
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
beforeEach(async () => {
|
|
253
|
+
if (!isGitAvailable)
|
|
254
|
+
return;
|
|
255
|
+
tempDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'workspace-git-test-'));
|
|
256
|
+
workspace = new workspace_1.TempWorkspace();
|
|
257
|
+
// Initialize git repo
|
|
258
|
+
(0, child_process_1.execSync)('git init', { cwd: tempDir, stdio: 'pipe' });
|
|
259
|
+
(0, child_process_1.execSync)('git config user.email "test@test.com"', { cwd: tempDir, stdio: 'pipe' });
|
|
260
|
+
(0, child_process_1.execSync)('git config user.name "Test"', { cwd: tempDir, stdio: 'pipe' });
|
|
261
|
+
// Create and commit a file
|
|
262
|
+
await fs.promises.writeFile(path.join(tempDir, 'file.ts'), 'const x = 1;\n');
|
|
263
|
+
(0, child_process_1.execSync)('git add .', { cwd: tempDir, stdio: 'pipe' });
|
|
264
|
+
(0, child_process_1.execSync)('git commit -m "initial"', { cwd: tempDir, stdio: 'pipe' });
|
|
265
|
+
});
|
|
266
|
+
afterEach(async () => {
|
|
267
|
+
if (!isGitAvailable)
|
|
268
|
+
return;
|
|
269
|
+
await workspace.cleanupAll();
|
|
270
|
+
await fs.promises.rm(tempDir, { recursive: true, force: true });
|
|
271
|
+
});
|
|
272
|
+
it('uses git worktree when available', async () => {
|
|
273
|
+
if (!isGitAvailable) {
|
|
274
|
+
console.log('Skipping git worktree test - git not available');
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
const info = await workspace.create({
|
|
278
|
+
projectPath: tempDir,
|
|
279
|
+
useWorktree: true,
|
|
280
|
+
});
|
|
281
|
+
expect(info.type).toBe('worktree');
|
|
282
|
+
expect(fs.existsSync(path.join(info.path, 'file.ts'))).toBe(true);
|
|
283
|
+
});
|
|
284
|
+
it('applies diff with git apply', async () => {
|
|
285
|
+
if (!isGitAvailable) {
|
|
286
|
+
console.log('Skipping git apply test - git not available');
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
const info = await workspace.create({
|
|
290
|
+
projectPath: tempDir,
|
|
291
|
+
useWorktree: true,
|
|
292
|
+
});
|
|
293
|
+
const diff = `--- a/file.ts
|
|
294
|
+
+++ b/file.ts
|
|
295
|
+
@@ -1 +1,2 @@
|
|
296
|
+
const x = 1;
|
|
297
|
+
+const y = 2;
|
|
298
|
+
`;
|
|
299
|
+
const hunks = [{
|
|
300
|
+
file: 'file.ts',
|
|
301
|
+
oldStart: 1,
|
|
302
|
+
oldLines: 1,
|
|
303
|
+
newStart: 1,
|
|
304
|
+
newLines: 2,
|
|
305
|
+
content: `@@ -1 +1,2 @@
|
|
306
|
+
const x = 1;
|
|
307
|
+
+const y = 2;`,
|
|
308
|
+
}];
|
|
309
|
+
const result = await workspace.applyDiff(info.path, diff, hunks);
|
|
310
|
+
expect(result.success).toBe(true);
|
|
311
|
+
const content = await fs.promises.readFile(path.join(info.path, 'file.ts'), 'utf8');
|
|
312
|
+
expect(content).toContain('const y = 2');
|
|
313
|
+
});
|
|
314
|
+
});
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format Validator - Strict Output Protocol Enforcement
|
|
3
|
+
*
|
|
4
|
+
* Validates AI agent output format:
|
|
5
|
+
* 1. JSON shape validation (guardrail-v1 format)
|
|
6
|
+
* 2. Unified diff validity checking
|
|
7
|
+
* 3. Markdown fence stripping (forgiving)
|
|
8
|
+
* 4. Path safety validation
|
|
9
|
+
* 5. Stub/placeholder detection
|
|
10
|
+
*/
|
|
11
|
+
export interface GuardrailV1Output {
|
|
12
|
+
format: 'guardrail-v1';
|
|
13
|
+
diff: string;
|
|
14
|
+
commands: string[];
|
|
15
|
+
tests: string[];
|
|
16
|
+
notes: string;
|
|
17
|
+
}
|
|
18
|
+
export interface ValidationResult {
|
|
19
|
+
valid: boolean;
|
|
20
|
+
errors: string[];
|
|
21
|
+
warnings: string[];
|
|
22
|
+
sanitized?: GuardrailV1Output;
|
|
23
|
+
}
|
|
24
|
+
export interface DiffValidationResult {
|
|
25
|
+
valid: boolean;
|
|
26
|
+
errors: string[];
|
|
27
|
+
hunks: ParsedHunk[];
|
|
28
|
+
filesAffected: string[];
|
|
29
|
+
}
|
|
30
|
+
export interface ParsedHunk {
|
|
31
|
+
file: string;
|
|
32
|
+
oldStart: number;
|
|
33
|
+
oldLines: number;
|
|
34
|
+
newStart: number;
|
|
35
|
+
newLines: number;
|
|
36
|
+
content: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Strip markdown code fences from raw agent output (forgiving mode)
|
|
40
|
+
*/
|
|
41
|
+
export declare function stripMarkdownFences(raw: string): string;
|
|
42
|
+
/**
|
|
43
|
+
* Validate the guardrail-v1 JSON shape
|
|
44
|
+
*/
|
|
45
|
+
export declare function validateJsonShape(obj: unknown): ValidationResult;
|
|
46
|
+
/**
|
|
47
|
+
* Parse and validate unified diff format
|
|
48
|
+
*/
|
|
49
|
+
export declare function validateUnifiedDiff(diff: string): DiffValidationResult;
|
|
50
|
+
/**
|
|
51
|
+
* Validate that file paths are safe (no traversal, no system paths)
|
|
52
|
+
*/
|
|
53
|
+
export declare function validatePathSafety(paths: string[], projectRoot: string): {
|
|
54
|
+
safe: boolean;
|
|
55
|
+
issues: string[];
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Validate that commands are safe to run
|
|
59
|
+
*/
|
|
60
|
+
export declare function validateCommandSafety(commands: string[]): {
|
|
61
|
+
safe: boolean;
|
|
62
|
+
issues: string[];
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Detect placeholder/stub code in diff additions
|
|
66
|
+
*/
|
|
67
|
+
export declare function detectStubs(diff: string): {
|
|
68
|
+
hasStubs: boolean;
|
|
69
|
+
stubs: string[];
|
|
70
|
+
};
|
|
71
|
+
export interface FullValidationResult {
|
|
72
|
+
valid: boolean;
|
|
73
|
+
errors: string[];
|
|
74
|
+
warnings: string[];
|
|
75
|
+
output?: GuardrailV1Output;
|
|
76
|
+
diffValidation?: DiffValidationResult;
|
|
77
|
+
pathSafety?: {
|
|
78
|
+
safe: boolean;
|
|
79
|
+
issues: string[];
|
|
80
|
+
};
|
|
81
|
+
commandSafety?: {
|
|
82
|
+
safe: boolean;
|
|
83
|
+
issues: string[];
|
|
84
|
+
};
|
|
85
|
+
stubDetection?: {
|
|
86
|
+
hasStubs: boolean;
|
|
87
|
+
stubs: string[];
|
|
88
|
+
};
|
|
89
|
+
wasMarkdownWrapped?: boolean;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Full validation pipeline for agent output
|
|
93
|
+
*/
|
|
94
|
+
export declare function validateAgentOutput(raw: string, projectRoot: string, options?: {
|
|
95
|
+
strictMarkdown?: boolean;
|
|
96
|
+
}): FullValidationResult;
|
|
97
|
+
/**
|
|
98
|
+
* Quick check if output is markdown-wrapped (for error messages)
|
|
99
|
+
*/
|
|
100
|
+
export declare function isMarkdownWrapped(raw: string): boolean;
|
|
101
|
+
//# sourceMappingURL=format-validator.d.ts.map
|