@codapult/guard 0.1.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 (45) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +290 -0
  3. package/dist/adapters/agents/agent-integration.d.ts +9 -0
  4. package/dist/adapters/agents/agent-integration.js +62 -0
  5. package/dist/adapters/command.d.ts +21 -0
  6. package/dist/adapters/command.js +60 -0
  7. package/dist/adapters/project-checks.d.ts +37 -0
  8. package/dist/adapters/project-checks.js +149 -0
  9. package/dist/cli/commands/guard.d.ts +55 -0
  10. package/dist/cli/commands/guard.js +510 -0
  11. package/dist/cli/index.d.ts +2 -0
  12. package/dist/cli/index.js +75 -0
  13. package/dist/cli/ui.d.ts +6 -0
  14. package/dist/cli/ui.js +7 -0
  15. package/dist/commands/guard.d.ts +2 -0
  16. package/dist/commands/guard.js +2 -0
  17. package/dist/core/analysis/doctor.d.ts +12 -0
  18. package/dist/core/analysis/doctor.js +85 -0
  19. package/dist/core/analysis/packs.d.ts +21 -0
  20. package/dist/core/analysis/packs.js +251 -0
  21. package/dist/core/config.d.ts +6 -0
  22. package/dist/core/config.js +6 -0
  23. package/dist/core/discovery/discovery.d.ts +134 -0
  24. package/dist/core/discovery/discovery.js +816 -0
  25. package/dist/core/guard.d.ts +189 -0
  26. package/dist/core/guard.js +936 -0
  27. package/dist/core/history/history.d.ts +24 -0
  28. package/dist/core/history/history.js +65 -0
  29. package/dist/core/output/sarif.d.ts +35 -0
  30. package/dist/core/output/sarif.js +29 -0
  31. package/dist/core/policy/schemas.d.ts +272 -0
  32. package/dist/core/policy/schemas.js +72 -0
  33. package/dist/core/verification/verify.d.ts +29 -0
  34. package/dist/core/verification/verify.js +77 -0
  35. package/dist/index.d.ts +10 -0
  36. package/dist/index.js +9 -0
  37. package/dist/mcp/prompts.d.ts +2 -0
  38. package/dist/mcp/prompts.js +54 -0
  39. package/dist/mcp/resources.d.ts +2 -0
  40. package/dist/mcp/resources.js +64 -0
  41. package/dist/mcp/server.d.ts +1 -0
  42. package/dist/mcp/server.js +17 -0
  43. package/dist/mcp/tools/guard.d.ts +2 -0
  44. package/dist/mcp/tools/guard.js +375 -0
  45. package/package.json +117 -0
@@ -0,0 +1,24 @@
1
+ export interface GuardSnapshotSummary {
2
+ revision: string;
3
+ path: string;
4
+ files: number;
5
+ modules: number;
6
+ capabilities: string[];
7
+ cycles: number;
8
+ }
9
+ export interface GuardHistoryDiff {
10
+ from: string;
11
+ to: string;
12
+ addedFiles: string[];
13
+ removedFiles: string[];
14
+ addedDependencies: string[];
15
+ removedDependencies: string[];
16
+ addedCapabilities: string[];
17
+ removedCapabilities: string[];
18
+ cycles: {
19
+ from: number;
20
+ to: number;
21
+ };
22
+ }
23
+ export declare function listGuardSnapshots(root: string): GuardSnapshotSummary[];
24
+ export declare function diffGuardSnapshots(root: string, from: string, to: string): GuardHistoryDiff | undefined;
@@ -0,0 +1,65 @@
1
+ import { existsSync, readdirSync, readFileSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+ import { GUARD_HISTORY_DIR } from '../guard.js';
4
+ function readSnapshot(root, revision) {
5
+ if (!/^[A-Za-z0-9._-]+$/.test(revision))
6
+ return undefined;
7
+ try {
8
+ return JSON.parse(readFileSync(resolve(root, GUARD_HISTORY_DIR, `${revision}.json`), 'utf8'));
9
+ }
10
+ catch {
11
+ return undefined;
12
+ }
13
+ }
14
+ export function listGuardSnapshots(root) {
15
+ const directory = resolve(root, GUARD_HISTORY_DIR);
16
+ if (!existsSync(directory))
17
+ return [];
18
+ return readdirSync(directory)
19
+ .filter((file) => file.endsWith('.json'))
20
+ .sort()
21
+ .flatMap((file) => {
22
+ const revision = file.slice(0, -5);
23
+ const model = readSnapshot(root, revision);
24
+ return model
25
+ ? [
26
+ {
27
+ revision,
28
+ path: `${GUARD_HISTORY_DIR}/${file}`,
29
+ files: model.files.length,
30
+ modules: model.modules.length,
31
+ capabilities: Object.keys(model.capabilities).sort(),
32
+ cycles: model.insights.cycles.length,
33
+ },
34
+ ]
35
+ : [];
36
+ });
37
+ }
38
+ export function diffGuardSnapshots(root, from, to) {
39
+ const before = readSnapshot(root, from);
40
+ const after = readSnapshot(root, to);
41
+ if (!before || !after)
42
+ return undefined;
43
+ const difference = (left, right) => right.filter((value) => !left.includes(value)).sort();
44
+ const beforeFiles = before.files.map((file) => file.path);
45
+ const afterFiles = after.files.map((file) => file.path);
46
+ const beforeDependencies = Object.keys({
47
+ ...before.project.dependencies,
48
+ ...before.project.devDependencies,
49
+ });
50
+ const afterDependencies = Object.keys({
51
+ ...after.project.dependencies,
52
+ ...after.project.devDependencies,
53
+ });
54
+ return {
55
+ from,
56
+ to,
57
+ addedFiles: difference(beforeFiles, afterFiles),
58
+ removedFiles: difference(afterFiles, beforeFiles),
59
+ addedDependencies: difference(beforeDependencies, afterDependencies),
60
+ removedDependencies: difference(afterDependencies, beforeDependencies),
61
+ addedCapabilities: difference(Object.keys(before.capabilities), Object.keys(after.capabilities)),
62
+ removedCapabilities: difference(Object.keys(after.capabilities), Object.keys(before.capabilities)),
63
+ cycles: { from: before.insights.cycles.length, to: after.insights.cycles.length },
64
+ };
65
+ }
@@ -0,0 +1,35 @@
1
+ import type { GuardFinding } from '../guard.js';
2
+ interface SarifResult {
3
+ ruleId: string;
4
+ level: 'error' | 'warning' | 'note';
5
+ message: {
6
+ text: string;
7
+ };
8
+ locations: [
9
+ {
10
+ physicalLocation: {
11
+ artifactLocation: {
12
+ uri: string;
13
+ };
14
+ region: {
15
+ startLine: number;
16
+ };
17
+ };
18
+ }
19
+ ];
20
+ }
21
+ export interface SarifLog {
22
+ version: '2.1.0';
23
+ $schema: string;
24
+ runs: [{
25
+ tool: {
26
+ driver: {
27
+ name: string;
28
+ informationUri: string;
29
+ };
30
+ };
31
+ results: SarifResult[];
32
+ }];
33
+ }
34
+ export declare function guardFindingsToSarif(findings: GuardFinding[]): SarifLog;
35
+ export {};
@@ -0,0 +1,29 @@
1
+ export function guardFindingsToSarif(findings) {
2
+ return {
3
+ version: '2.1.0',
4
+ $schema: 'https://json.schemastore.org/sarif-2.1.0.json',
5
+ runs: [
6
+ {
7
+ tool: {
8
+ driver: {
9
+ name: 'Codapult Guard',
10
+ informationUri: 'https://codapult.dev/docs/developer-tools/guard',
11
+ },
12
+ },
13
+ results: findings.map((finding) => ({
14
+ ruleId: finding.ruleId,
15
+ level: finding.severity === 'info' ? 'note' : finding.severity,
16
+ message: { text: finding.message },
17
+ locations: [
18
+ {
19
+ physicalLocation: {
20
+ artifactLocation: { uri: finding.file },
21
+ region: { startLine: finding.line },
22
+ },
23
+ },
24
+ ],
25
+ })),
26
+ },
27
+ ],
28
+ };
29
+ }
@@ -0,0 +1,272 @@
1
+ import { z } from 'zod';
2
+ export declare const guardRuleSchema: z.ZodObject<{
3
+ id: z.ZodString;
4
+ description: z.ZodString;
5
+ severity: z.ZodEnum<{
6
+ error: "error";
7
+ info: "info";
8
+ warning: "warning";
9
+ }>;
10
+ kind: z.ZodEnum<{
11
+ "client-forbidden-import": "client-forbidden-import";
12
+ "forbidden-import": "forbidden-import";
13
+ }>;
14
+ patterns: z.ZodArray<z.ZodString>;
15
+ files: z.ZodOptional<z.ZodArray<z.ZodString>>;
16
+ status: z.ZodOptional<z.ZodEnum<{
17
+ active: "active";
18
+ proposed: "proposed";
19
+ }>>;
20
+ confidence: z.ZodOptional<z.ZodEnum<{
21
+ high: "high";
22
+ low: "low";
23
+ medium: "medium";
24
+ }>>;
25
+ evidence: z.ZodOptional<z.ZodArray<z.ZodString>>;
26
+ }, z.core.$strip>;
27
+ export declare const guardContractSchema: z.ZodObject<{
28
+ id: z.ZodString;
29
+ statement: z.ZodString;
30
+ kind: z.ZodOptional<z.ZodEnum<{
31
+ guidance: "guidance";
32
+ "import-boundary": "import-boundary";
33
+ "required-call": "required-call";
34
+ }>>;
35
+ severity: z.ZodOptional<z.ZodEnum<{
36
+ error: "error";
37
+ info: "info";
38
+ warning: "warning";
39
+ }>>;
40
+ scope: z.ZodOptional<z.ZodArray<z.ZodString>>;
41
+ entrypoints: z.ZodOptional<z.ZodArray<z.ZodString>>;
42
+ exclude: z.ZodOptional<z.ZodArray<z.ZodString>>;
43
+ guidance: z.ZodOptional<z.ZodArray<z.ZodString>>;
44
+ references: z.ZodOptional<z.ZodArray<z.ZodString>>;
45
+ mustImport: z.ZodOptional<z.ZodArray<z.ZodString>>;
46
+ mustNotImport: z.ZodOptional<z.ZodArray<z.ZodString>>;
47
+ mustCall: z.ZodOptional<z.ZodArray<z.ZodString>>;
48
+ status: z.ZodOptional<z.ZodEnum<{
49
+ active: "active";
50
+ proposed: "proposed";
51
+ }>>;
52
+ confidence: z.ZodOptional<z.ZodEnum<{
53
+ high: "high";
54
+ low: "low";
55
+ medium: "medium";
56
+ }>>;
57
+ evidence: z.ZodOptional<z.ZodArray<z.ZodString>>;
58
+ }, z.core.$strip>;
59
+ export declare const guardConfigSchema: z.ZodObject<{
60
+ version: z.ZodLiteral<1>;
61
+ rules: z.ZodArray<z.ZodObject<{
62
+ id: z.ZodString;
63
+ description: z.ZodString;
64
+ severity: z.ZodEnum<{
65
+ error: "error";
66
+ info: "info";
67
+ warning: "warning";
68
+ }>;
69
+ kind: z.ZodEnum<{
70
+ "client-forbidden-import": "client-forbidden-import";
71
+ "forbidden-import": "forbidden-import";
72
+ }>;
73
+ patterns: z.ZodArray<z.ZodString>;
74
+ files: z.ZodOptional<z.ZodArray<z.ZodString>>;
75
+ status: z.ZodOptional<z.ZodEnum<{
76
+ active: "active";
77
+ proposed: "proposed";
78
+ }>>;
79
+ confidence: z.ZodOptional<z.ZodEnum<{
80
+ high: "high";
81
+ low: "low";
82
+ medium: "medium";
83
+ }>>;
84
+ evidence: z.ZodOptional<z.ZodArray<z.ZodString>>;
85
+ }, z.core.$strip>>;
86
+ contracts: z.ZodOptional<z.ZodArray<z.ZodObject<{
87
+ id: z.ZodString;
88
+ statement: z.ZodString;
89
+ kind: z.ZodOptional<z.ZodEnum<{
90
+ guidance: "guidance";
91
+ "import-boundary": "import-boundary";
92
+ "required-call": "required-call";
93
+ }>>;
94
+ severity: z.ZodOptional<z.ZodEnum<{
95
+ error: "error";
96
+ info: "info";
97
+ warning: "warning";
98
+ }>>;
99
+ scope: z.ZodOptional<z.ZodArray<z.ZodString>>;
100
+ entrypoints: z.ZodOptional<z.ZodArray<z.ZodString>>;
101
+ exclude: z.ZodOptional<z.ZodArray<z.ZodString>>;
102
+ guidance: z.ZodOptional<z.ZodArray<z.ZodString>>;
103
+ references: z.ZodOptional<z.ZodArray<z.ZodString>>;
104
+ mustImport: z.ZodOptional<z.ZodArray<z.ZodString>>;
105
+ mustNotImport: z.ZodOptional<z.ZodArray<z.ZodString>>;
106
+ mustCall: z.ZodOptional<z.ZodArray<z.ZodString>>;
107
+ status: z.ZodOptional<z.ZodEnum<{
108
+ active: "active";
109
+ proposed: "proposed";
110
+ }>>;
111
+ confidence: z.ZodOptional<z.ZodEnum<{
112
+ high: "high";
113
+ low: "low";
114
+ medium: "medium";
115
+ }>>;
116
+ evidence: z.ZodOptional<z.ZodArray<z.ZodString>>;
117
+ }, z.core.$strip>>>;
118
+ }, z.core.$strip>;
119
+ export declare const guardContractsFileSchema: z.ZodObject<{
120
+ version: z.ZodLiteral<1>;
121
+ contracts: z.ZodArray<z.ZodObject<{
122
+ id: z.ZodString;
123
+ statement: z.ZodString;
124
+ kind: z.ZodOptional<z.ZodEnum<{
125
+ guidance: "guidance";
126
+ "import-boundary": "import-boundary";
127
+ "required-call": "required-call";
128
+ }>>;
129
+ severity: z.ZodOptional<z.ZodEnum<{
130
+ error: "error";
131
+ info: "info";
132
+ warning: "warning";
133
+ }>>;
134
+ scope: z.ZodOptional<z.ZodArray<z.ZodString>>;
135
+ entrypoints: z.ZodOptional<z.ZodArray<z.ZodString>>;
136
+ exclude: z.ZodOptional<z.ZodArray<z.ZodString>>;
137
+ guidance: z.ZodOptional<z.ZodArray<z.ZodString>>;
138
+ references: z.ZodOptional<z.ZodArray<z.ZodString>>;
139
+ mustImport: z.ZodOptional<z.ZodArray<z.ZodString>>;
140
+ mustNotImport: z.ZodOptional<z.ZodArray<z.ZodString>>;
141
+ mustCall: z.ZodOptional<z.ZodArray<z.ZodString>>;
142
+ status: z.ZodOptional<z.ZodEnum<{
143
+ active: "active";
144
+ proposed: "proposed";
145
+ }>>;
146
+ confidence: z.ZodOptional<z.ZodEnum<{
147
+ high: "high";
148
+ low: "low";
149
+ medium: "medium";
150
+ }>>;
151
+ evidence: z.ZodOptional<z.ZodArray<z.ZodString>>;
152
+ }, z.core.$strip>>;
153
+ }, z.core.$strip>;
154
+ export declare const guardProposalDecisionSchema: z.ZodObject<{
155
+ id: z.ZodString;
156
+ type: z.ZodEnum<{
157
+ contract: "contract";
158
+ rule: "rule";
159
+ }>;
160
+ decision: z.ZodEnum<{
161
+ approved: "approved";
162
+ rejected: "rejected";
163
+ }>;
164
+ decidedAt: z.ZodString;
165
+ proposalId: z.ZodOptional<z.ZodString>;
166
+ proposalFingerprint: z.ZodOptional<z.ZodString>;
167
+ revision: z.ZodOptional<z.ZodNumber>;
168
+ }, z.core.$strip>;
169
+ export declare const guardProposalSchema: z.ZodObject<{
170
+ version: z.ZodLiteral<1>;
171
+ generatedAt: z.ZodString;
172
+ proposalId: z.ZodOptional<z.ZodString>;
173
+ projectFingerprint: z.ZodOptional<z.ZodString>;
174
+ revision: z.ZodOptional<z.ZodNumber>;
175
+ contentFingerprint: z.ZodOptional<z.ZodString>;
176
+ rules: z.ZodArray<z.ZodObject<{
177
+ id: z.ZodString;
178
+ description: z.ZodString;
179
+ severity: z.ZodEnum<{
180
+ error: "error";
181
+ info: "info";
182
+ warning: "warning";
183
+ }>;
184
+ kind: z.ZodEnum<{
185
+ "client-forbidden-import": "client-forbidden-import";
186
+ "forbidden-import": "forbidden-import";
187
+ }>;
188
+ patterns: z.ZodArray<z.ZodString>;
189
+ files: z.ZodOptional<z.ZodArray<z.ZodString>>;
190
+ status: z.ZodOptional<z.ZodEnum<{
191
+ active: "active";
192
+ proposed: "proposed";
193
+ }>>;
194
+ confidence: z.ZodOptional<z.ZodEnum<{
195
+ high: "high";
196
+ low: "low";
197
+ medium: "medium";
198
+ }>>;
199
+ evidence: z.ZodOptional<z.ZodArray<z.ZodString>>;
200
+ }, z.core.$strip>>;
201
+ contracts: z.ZodArray<z.ZodObject<{
202
+ id: z.ZodString;
203
+ statement: z.ZodString;
204
+ kind: z.ZodOptional<z.ZodEnum<{
205
+ guidance: "guidance";
206
+ "import-boundary": "import-boundary";
207
+ "required-call": "required-call";
208
+ }>>;
209
+ severity: z.ZodOptional<z.ZodEnum<{
210
+ error: "error";
211
+ info: "info";
212
+ warning: "warning";
213
+ }>>;
214
+ scope: z.ZodOptional<z.ZodArray<z.ZodString>>;
215
+ entrypoints: z.ZodOptional<z.ZodArray<z.ZodString>>;
216
+ exclude: z.ZodOptional<z.ZodArray<z.ZodString>>;
217
+ guidance: z.ZodOptional<z.ZodArray<z.ZodString>>;
218
+ references: z.ZodOptional<z.ZodArray<z.ZodString>>;
219
+ mustImport: z.ZodOptional<z.ZodArray<z.ZodString>>;
220
+ mustNotImport: z.ZodOptional<z.ZodArray<z.ZodString>>;
221
+ mustCall: z.ZodOptional<z.ZodArray<z.ZodString>>;
222
+ status: z.ZodOptional<z.ZodEnum<{
223
+ active: "active";
224
+ proposed: "proposed";
225
+ }>>;
226
+ confidence: z.ZodOptional<z.ZodEnum<{
227
+ high: "high";
228
+ low: "low";
229
+ medium: "medium";
230
+ }>>;
231
+ evidence: z.ZodOptional<z.ZodArray<z.ZodString>>;
232
+ }, z.core.$strip>>;
233
+ questions: z.ZodArray<z.ZodString>;
234
+ decisions: z.ZodOptional<z.ZodArray<z.ZodObject<{
235
+ id: z.ZodString;
236
+ type: z.ZodEnum<{
237
+ contract: "contract";
238
+ rule: "rule";
239
+ }>;
240
+ decision: z.ZodEnum<{
241
+ approved: "approved";
242
+ rejected: "rejected";
243
+ }>;
244
+ decidedAt: z.ZodString;
245
+ proposalId: z.ZodOptional<z.ZodString>;
246
+ proposalFingerprint: z.ZodOptional<z.ZodString>;
247
+ revision: z.ZodOptional<z.ZodNumber>;
248
+ }, z.core.$strip>>>;
249
+ }, z.core.$strip>;
250
+ export declare const guardAgentConfigSchema: z.ZodObject<{
251
+ version: z.ZodLiteral<1>;
252
+ tools: z.ZodEnum<{
253
+ auto: "auto";
254
+ off: "off";
255
+ on: "on";
256
+ }>;
257
+ tooling: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
258
+ script: z.ZodString;
259
+ enabled: z.ZodBoolean;
260
+ }, z.core.$strip>>>;
261
+ completionGate: z.ZodObject<{
262
+ enabled: z.ZodBoolean;
263
+ maxIterations: z.ZodNumber;
264
+ projectChecks: z.ZodBoolean;
265
+ checks: z.ZodArray<z.ZodEnum<{
266
+ build: "build";
267
+ lint: "lint";
268
+ test: "test";
269
+ typecheck: "typecheck";
270
+ }>>;
271
+ }, z.core.$strip>;
272
+ }, z.core.$strip>;
@@ -0,0 +1,72 @@
1
+ import { z } from 'zod';
2
+ const severity = z.enum(['error', 'warning', 'info']);
3
+ const status = z.enum(['active', 'proposed']);
4
+ export const guardRuleSchema = z.object({
5
+ id: z.string(),
6
+ description: z.string(),
7
+ severity,
8
+ kind: z.enum(['forbidden-import', 'client-forbidden-import']),
9
+ patterns: z.array(z.string()),
10
+ files: z.array(z.string()).optional(),
11
+ status: status.optional(),
12
+ confidence: z.enum(['high', 'medium', 'low']).optional(),
13
+ evidence: z.array(z.string()).optional(),
14
+ });
15
+ export const guardContractSchema = z.object({
16
+ id: z.string(),
17
+ statement: z.string(),
18
+ kind: z.enum(['guidance', 'import-boundary', 'required-call']).optional(),
19
+ severity: severity.optional(),
20
+ scope: z.array(z.string()).optional(),
21
+ entrypoints: z.array(z.string()).optional(),
22
+ exclude: z.array(z.string()).optional(),
23
+ guidance: z.array(z.string()).optional(),
24
+ references: z.array(z.string()).optional(),
25
+ mustImport: z.array(z.string()).optional(),
26
+ mustNotImport: z.array(z.string()).optional(),
27
+ mustCall: z.array(z.string()).optional(),
28
+ status: status.optional(),
29
+ confidence: z.enum(['high', 'medium', 'low']).optional(),
30
+ evidence: z.array(z.string()).optional(),
31
+ });
32
+ export const guardConfigSchema = z.object({
33
+ version: z.literal(1),
34
+ rules: z.array(guardRuleSchema),
35
+ contracts: z.array(guardContractSchema).optional(),
36
+ });
37
+ export const guardContractsFileSchema = z.object({
38
+ version: z.literal(1),
39
+ contracts: z.array(guardContractSchema),
40
+ });
41
+ export const guardProposalDecisionSchema = z.object({
42
+ id: z.string(),
43
+ type: z.enum(['rule', 'contract']),
44
+ decision: z.enum(['approved', 'rejected']),
45
+ decidedAt: z.string(),
46
+ proposalId: z.string().optional(),
47
+ proposalFingerprint: z.string().optional(),
48
+ revision: z.number().optional(),
49
+ });
50
+ export const guardProposalSchema = z.object({
51
+ version: z.literal(1),
52
+ generatedAt: z.string(),
53
+ proposalId: z.string().optional(),
54
+ projectFingerprint: z.string().optional(),
55
+ revision: z.number().int().positive().optional(),
56
+ contentFingerprint: z.string().optional(),
57
+ rules: z.array(guardRuleSchema),
58
+ contracts: z.array(guardContractSchema),
59
+ questions: z.array(z.string()),
60
+ decisions: z.array(guardProposalDecisionSchema).optional(),
61
+ });
62
+ export const guardAgentConfigSchema = z.object({
63
+ version: z.literal(1),
64
+ tools: z.enum(['auto', 'on', 'off']),
65
+ tooling: z.record(z.string(), z.object({ script: z.string(), enabled: z.boolean() })).default({}),
66
+ completionGate: z.object({
67
+ enabled: z.boolean(),
68
+ maxIterations: z.number().int().min(1).max(10),
69
+ projectChecks: z.boolean(),
70
+ checks: z.array(z.enum(['lint', 'typecheck', 'test', 'build'])),
71
+ }),
72
+ });
@@ -0,0 +1,29 @@
1
+ import { type CommandResult } from '../../adapters/command.js';
2
+ import { type GuardAdapter, type ProjectCheck, type ProjectCheckResults, type ProjectRuntimeDiagnostics } from '../../adapters/project-checks.js';
3
+ import { type GuardToolMode, type GuardContractIssue, type GuardReport } from '../guard.js';
4
+ export type GuardVerificationCheck = ProjectCheck;
5
+ export interface GuardVerificationResult {
6
+ status: 'ok' | 'fail' | 'not-configured';
7
+ outcome: 'pass' | 'fail' | 'warning' | 'needs-review' | 'not-configured';
8
+ tools?: GuardToolMode;
9
+ checks: ProjectCheckResults;
10
+ workspaceChecks: Record<string, ProjectCheckResults>;
11
+ adapters: Partial<Record<GuardAdapter, CommandResult>>;
12
+ runtime: ProjectRuntimeDiagnostics;
13
+ architecture?: GuardReport;
14
+ contractIssues: GuardContractIssue[];
15
+ requirement: {
16
+ status: 'delegated-to-review';
17
+ provided: boolean;
18
+ message: string;
19
+ };
20
+ }
21
+ export declare function runGuardVerification(root: string, options?: {
22
+ checks?: GuardVerificationCheck[];
23
+ changedOnly?: boolean;
24
+ timeout?: number;
25
+ requirement?: string;
26
+ tools?: GuardToolMode;
27
+ strict?: boolean;
28
+ projectChecks?: boolean;
29
+ }): GuardVerificationResult;
@@ -0,0 +1,77 @@
1
+ import { runProjectAdapters, runProjectChecks, runWorkspaceProjectChecks, inspectProjectRuntime, } from '../../adapters/project-checks.js';
2
+ import { loadBaseline, loadGuardAgentConfig, loadGuardConfig, scanGuard, classifyGuardOutcome, validateGuardContracts, } from '../guard.js';
3
+ import { discoverProject } from '../discovery/discovery.js';
4
+ export function runGuardVerification(root, options = {}) {
5
+ const config = loadGuardConfig(root);
6
+ const requirement = {
7
+ status: 'delegated-to-review',
8
+ provided: Boolean(options.requirement?.trim()),
9
+ message: options.requirement?.trim()
10
+ ? 'Requirement text is included in semantic review input; deterministic verify does not judge natural-language acceptance criteria.'
11
+ : 'Requirement satisfaction is evaluated by guard review using the task and diff.',
12
+ };
13
+ const runtime = inspectProjectRuntime(root);
14
+ if (!config)
15
+ return {
16
+ status: 'not-configured',
17
+ outcome: 'not-configured',
18
+ checks: {},
19
+ workspaceChecks: {},
20
+ adapters: {},
21
+ runtime,
22
+ contractIssues: [],
23
+ requirement,
24
+ };
25
+ const agentConfig = loadGuardAgentConfig(root);
26
+ const projectChecks = options.projectChecks ?? agentConfig.completionGate.projectChecks;
27
+ const checks = projectChecks ? (options.checks ?? agentConfig.completionGate.checks) : [];
28
+ const results = runProjectChecks(root, checks, { timeout: options.timeout });
29
+ const workspaceModel = discoverProject(root);
30
+ const workspaceChecks = runWorkspaceProjectChecks(root, workspaceModel.project.workspacePackages ?? [], checks, {
31
+ timeout: options.timeout,
32
+ rootResults: results,
33
+ });
34
+ const toolMode = options.tools ?? agentConfig.tools;
35
+ const adapters = toolMode === 'off'
36
+ ? {}
37
+ : runProjectAdapters(root, {
38
+ mode: toolMode,
39
+ timeout: options.timeout,
40
+ tooling: agentConfig.tooling,
41
+ });
42
+ const architecture = scanGuard(root, config, {
43
+ changedOnly: options.changedOnly,
44
+ baseline: loadBaseline(root),
45
+ includeArchitectureInsights: true,
46
+ });
47
+ const contractIssues = validateGuardContracts(root, config.contracts ?? []);
48
+ const commandFailed = Object.values(results).some((result) => result.status === 'failed');
49
+ const workspaceCommandFailed = Object.values(workspaceChecks).some((packageResults) => Object.values(packageResults).some((result) => result.status === 'failed'));
50
+ const adapterFailed = Object.values(adapters).some((result) => result.status === 'failed');
51
+ const missingRequiredTools = options.strict &&
52
+ [...Object.values(results), ...Object.values(adapters)].some((result) => result.status === 'not-configured');
53
+ const architectureFailed = architecture.findings.some((finding) => finding.severity === 'error');
54
+ const architectureWarnings = architecture.findings.some((finding) => finding.severity === 'warning');
55
+ const failed = (projectChecks && !runtime.compatible) ||
56
+ commandFailed ||
57
+ workspaceCommandFailed ||
58
+ adapterFailed ||
59
+ architectureFailed ||
60
+ contractIssues.length > 0 ||
61
+ missingRequiredTools;
62
+ return {
63
+ status: failed ? 'fail' : 'ok',
64
+ outcome: classifyGuardOutcome({
65
+ errors: failed ? 1 : 0,
66
+ warnings: architectureWarnings ? 1 : 0,
67
+ }),
68
+ tools: toolMode,
69
+ checks: results,
70
+ workspaceChecks,
71
+ adapters,
72
+ runtime,
73
+ architecture,
74
+ contractIssues,
75
+ requirement,
76
+ };
77
+ }
@@ -0,0 +1,10 @@
1
+ /** Public, framework-agnostic Guard API. */
2
+ export * from './core/guard.js';
3
+ export * from './core/discovery/discovery.js';
4
+ export { runGuardVerification } from './core/verification/verify.js';
5
+ export type { GuardVerificationCheck, GuardVerificationResult, } from './core/verification/verify.js';
6
+ export * from './core/history/history.js';
7
+ export * from './core/output/sarif.js';
8
+ export * from './core/analysis/doctor.js';
9
+ export * from './core/analysis/packs.js';
10
+ export * from './adapters/project-checks.js';
package/dist/index.js ADDED
@@ -0,0 +1,9 @@
1
+ /** Public, framework-agnostic Guard API. */
2
+ export * from './core/guard.js';
3
+ export * from './core/discovery/discovery.js';
4
+ export { runGuardVerification } from './core/verification/verify.js';
5
+ export * from './core/history/history.js';
6
+ export * from './core/output/sarif.js';
7
+ export * from './core/analysis/doctor.js';
8
+ export * from './core/analysis/packs.js';
9
+ export * from './adapters/project-checks.js';
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerGuardPrompts(server: McpServer): void;