@codapult/guard 0.1.0 → 0.3.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.
@@ -2,29 +2,31 @@ import { z } from 'zod';
2
2
  const severity = z.enum(['error', 'warning', 'info']);
3
3
  const status = z.enum(['active', 'proposed']);
4
4
  export const guardRuleSchema = z.object({
5
- id: z.string(),
6
- description: z.string(),
5
+ id: z.string().trim().min(1),
6
+ description: z.string().trim().min(1),
7
7
  severity,
8
8
  kind: z.enum(['forbidden-import', 'client-forbidden-import']),
9
- patterns: z.array(z.string()),
10
- files: z.array(z.string()).optional(),
9
+ patterns: z.array(z.string().trim().min(1)).min(1),
10
+ files: z.array(z.string().trim().min(1)).optional(),
11
11
  status: status.optional(),
12
12
  confidence: z.enum(['high', 'medium', 'low']).optional(),
13
13
  evidence: z.array(z.string()).optional(),
14
14
  });
15
15
  export const guardContractSchema = z.object({
16
- id: z.string(),
17
- statement: z.string(),
18
- kind: z.enum(['guidance', 'import-boundary', 'required-call']).optional(),
16
+ id: z.string().trim().min(1),
17
+ statement: z.string().trim().min(1),
18
+ kind: z.enum(['guidance', 'import-boundary', 'required-call', 'package-boundary']).optional(),
19
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(),
20
+ scope: z.array(z.string().trim().min(1)).optional(),
21
+ entrypoints: z.array(z.string().trim().min(1)).optional(),
22
+ exclude: z.array(z.string().trim().min(1)).optional(),
23
+ guidance: z.array(z.string().trim().min(1)).optional(),
24
+ references: z.array(z.string().trim().min(1)).optional(),
25
+ mustImport: z.array(z.string().trim().min(1)).optional(),
26
+ mustNotImport: z.array(z.string().trim().min(1)).optional(),
27
+ mustCall: z.array(z.string().trim().min(1)).optional(),
28
+ fromPackages: z.array(z.string().trim().min(1)).optional(),
29
+ mustNotImportPackages: z.array(z.string().trim().min(1)).optional(),
28
30
  status: status.optional(),
29
31
  confidence: z.enum(['high', 'medium', 'low']).optional(),
30
32
  evidence: z.array(z.string()).optional(),
@@ -39,7 +41,7 @@ export const guardContractsFileSchema = z.object({
39
41
  contracts: z.array(guardContractSchema),
40
42
  });
41
43
  export const guardProposalDecisionSchema = z.object({
42
- id: z.string(),
44
+ id: z.string().trim().min(1),
43
45
  type: z.enum(['rule', 'contract']),
44
46
  decision: z.enum(['approved', 'rejected']),
45
47
  decidedAt: z.string(),
@@ -62,7 +64,9 @@ export const guardProposalSchema = z.object({
62
64
  export const guardAgentConfigSchema = z.object({
63
65
  version: z.literal(1),
64
66
  tools: z.enum(['auto', 'on', 'off']),
65
- tooling: z.record(z.string(), z.object({ script: z.string(), enabled: z.boolean() })).default({}),
67
+ tooling: z
68
+ .record(z.string().trim().min(1), z.object({ script: z.string().trim().min(1), enabled: z.boolean() }))
69
+ .default({}),
66
70
  completionGate: z.object({
67
71
  enabled: z.boolean(),
68
72
  maxIterations: z.number().int().min(1).max(10),
@@ -1,16 +1,21 @@
1
1
  import { type CommandResult } from '../../adapters/command.js';
2
2
  import { type GuardAdapter, type ProjectCheck, type ProjectCheckResults, type ProjectRuntimeDiagnostics } from '../../adapters/project-checks.js';
3
3
  import { type GuardToolMode, type GuardContractIssue, type GuardReport } from '../guard.js';
4
+ import { type GuardImpactAnalysis } from '../analysis/impact.js';
4
5
  export type GuardVerificationCheck = ProjectCheck;
5
6
  export interface GuardVerificationResult {
6
7
  status: 'ok' | 'fail' | 'not-configured';
7
8
  outcome: 'pass' | 'fail' | 'warning' | 'needs-review' | 'not-configured';
9
+ errorCode?: 'GUARD_NOT_CONFIGURED' | 'GUARD_CONFIG_INVALID';
10
+ recoverable?: boolean;
8
11
  tools?: GuardToolMode;
9
12
  checks: ProjectCheckResults;
10
13
  workspaceChecks: Record<string, ProjectCheckResults>;
11
14
  adapters: Partial<Record<GuardAdapter, CommandResult>>;
12
15
  runtime: ProjectRuntimeDiagnostics;
16
+ configError?: string;
13
17
  architecture?: GuardReport;
18
+ impact?: GuardImpactAnalysis;
14
19
  contractIssues: GuardContractIssue[];
15
20
  requirement: {
16
21
  status: 'delegated-to-review';
@@ -1,8 +1,8 @@
1
1
  import { runProjectAdapters, runProjectChecks, runWorkspaceProjectChecks, inspectProjectRuntime, } from '../../adapters/project-checks.js';
2
2
  import { loadBaseline, loadGuardAgentConfig, loadGuardConfig, scanGuard, classifyGuardOutcome, validateGuardContracts, } from '../guard.js';
3
+ import { analyzeProjectImpact } from '../analysis/impact.js';
3
4
  import { discoverProject } from '../discovery/discovery.js';
4
5
  export function runGuardVerification(root, options = {}) {
5
- const config = loadGuardConfig(root);
6
6
  const requirement = {
7
7
  status: 'delegated-to-review',
8
8
  provided: Boolean(options.requirement?.trim()),
@@ -11,10 +11,31 @@ export function runGuardVerification(root, options = {}) {
11
11
  : 'Requirement satisfaction is evaluated by guard review using the task and diff.',
12
12
  };
13
13
  const runtime = inspectProjectRuntime(root);
14
+ let config;
15
+ try {
16
+ config = loadGuardConfig(root);
17
+ }
18
+ catch (error) {
19
+ return {
20
+ status: 'fail',
21
+ outcome: 'fail',
22
+ errorCode: 'GUARD_CONFIG_INVALID',
23
+ recoverable: true,
24
+ checks: {},
25
+ workspaceChecks: {},
26
+ adapters: {},
27
+ runtime,
28
+ configError: error instanceof Error ? error.message : String(error),
29
+ contractIssues: [],
30
+ requirement,
31
+ };
32
+ }
14
33
  if (!config)
15
34
  return {
16
35
  status: 'not-configured',
17
36
  outcome: 'not-configured',
37
+ errorCode: 'GUARD_NOT_CONFIGURED',
38
+ recoverable: true,
18
39
  checks: {},
19
40
  workspaceChecks: {},
20
41
  adapters: {},
@@ -27,6 +48,9 @@ export function runGuardVerification(root, options = {}) {
27
48
  const checks = projectChecks ? (options.checks ?? agentConfig.completionGate.checks) : [];
28
49
  const results = runProjectChecks(root, checks, { timeout: options.timeout });
29
50
  const workspaceModel = discoverProject(root);
51
+ const impact = analyzeProjectImpact(workspaceModel, options.changedOnly === false
52
+ ? workspaceModel.modules.map((module) => module.path)
53
+ : workspaceModel.git.changedFiles, config.contracts ?? []);
30
54
  const workspaceChecks = runWorkspaceProjectChecks(root, workspaceModel.project.workspacePackages ?? [], checks, {
31
55
  timeout: options.timeout,
32
56
  rootResults: results,
@@ -71,6 +95,7 @@ export function runGuardVerification(root, options = {}) {
71
95
  adapters,
72
96
  runtime,
73
97
  architecture,
98
+ impact,
74
99
  contractIssues,
75
100
  requirement,
76
101
  };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  /** Public, framework-agnostic Guard API. */
2
2
  export * from './core/guard.js';
3
+ export * from './core/errors.js';
3
4
  export * from './core/discovery/discovery.js';
4
5
  export { runGuardVerification } from './core/verification/verify.js';
5
6
  export type { GuardVerificationCheck, GuardVerificationResult, } from './core/verification/verify.js';
@@ -7,4 +8,5 @@ export * from './core/history/history.js';
7
8
  export * from './core/output/sarif.js';
8
9
  export * from './core/analysis/doctor.js';
9
10
  export * from './core/analysis/packs.js';
11
+ export * from './core/analysis/impact.js';
10
12
  export * from './adapters/project-checks.js';
package/dist/index.js CHANGED
@@ -1,9 +1,11 @@
1
1
  /** Public, framework-agnostic Guard API. */
2
2
  export * from './core/guard.js';
3
+ export * from './core/errors.js';
3
4
  export * from './core/discovery/discovery.js';
4
5
  export { runGuardVerification } from './core/verification/verify.js';
5
6
  export * from './core/history/history.js';
6
7
  export * from './core/output/sarif.js';
7
8
  export * from './core/analysis/doctor.js';
8
9
  export * from './core/analysis/packs.js';
10
+ export * from './core/analysis/impact.js';
9
11
  export * from './adapters/project-checks.js';
@@ -1,4 +1,6 @@
1
- import { buildArchitectureMemory, buildConventionsMemory, buildGeneratedGuardConfig, buildGuardProposals, buildGuardReviewPacket, discoverProject, discoverProjectWithMetrics, findGuardRoot, GUARD_ARCHITECTURE_FILE, GUARD_CONVENTIONS_FILE, loadBaseline, loadGuardArtifact, loadGuardConfig, loadGuardAgentConfig, loadGuardProposals, getGuardProposalFreshness, loadProjectModel, writeGuardProposals, initializeGuard, GuardAlreadyInitializedError, recordGuardProposalDecision, writeGuardConfig, scanGuard, validateGuardContracts, classifyGuardOutcome, } from '../../core/guard.js';
1
+ import { buildArchitectureMemory, buildConventionsMemory, buildGeneratedGuardConfig, buildGuardProposals, buildGuardReviewPacket, discoverProject, discoverProjectWithMetrics, fingerprintProjectModel, findGuardRoot, GUARD_ARCHITECTURE_FILE, GUARD_CONVENTIONS_FILE, loadBaseline, loadGuardArtifact, loadGuardConfig, loadGuardAgentConfig, loadGuardProposals, getPendingGuardProposals, getGuardProposalFreshness, loadProjectModel, writeGuardProposals, initializeGuard, GuardAlreadyInitializedError, recordGuardProposalDecision, writeGuardConfig, writeGuardMemory, writeProjectModel, writeProjectSnapshot, scanGuard, validateGuardContracts, classifyGuardOutcome, } from '../../core/guard.js';
2
+ import { guardErrorPayload } from '../../core/errors.js';
3
+ import { analyzeProjectImpact } from '../../core/analysis/impact.js';
2
4
  import { z } from 'zod';
3
5
  import { runGuardVerification } from '../../core/verification/verify.js';
4
6
  const rootSchema = z.string().trim().min(1).optional().describe('Project path or workspace root.');
@@ -11,7 +13,135 @@ function jsonToolResult(value, isError = false) {
11
13
  ...(isError ? { isError: true } : {}),
12
14
  };
13
15
  }
16
+ function notConfiguredToolResult() {
17
+ return jsonToolResult({
18
+ status: 'error',
19
+ outcome: 'not-configured',
20
+ configured: false,
21
+ errorCode: 'GUARD_NOT_CONFIGURED',
22
+ message: 'Guard is not initialized.',
23
+ recoverable: true,
24
+ }, true);
25
+ }
26
+ function loadConfigSafely(root) {
27
+ try {
28
+ return { config: loadGuardConfig(root) };
29
+ }
30
+ catch (error) {
31
+ return {
32
+ error: jsonToolResult(guardErrorPayload('GUARD_CONFIG_INVALID', error instanceof Error ? error.message : String(error), {
33
+ configured: false,
34
+ outcome: 'error',
35
+ recoverable: true,
36
+ hint: 'Repair the invalid Guard artifact, then run codapult-guard doctor.',
37
+ }), true),
38
+ };
39
+ }
40
+ }
14
41
  export function registerGuardTools(server) {
42
+ server.registerTool('codapult_guard_analyze', {
43
+ title: 'Refresh Guard Model',
44
+ description: 'Refresh persisted project facts and snapshots without changing rules, contracts, or baseline.',
45
+ inputSchema: {
46
+ root: rootSchema,
47
+ confirm: z
48
+ .boolean()
49
+ .default(false)
50
+ .describe('Required before writing refreshed Guard state.'),
51
+ },
52
+ }, ({ root: requestedRoot, confirm }) => {
53
+ const root = getGuardRoot(requestedRoot);
54
+ if (!confirm)
55
+ return jsonToolResult({ status: 'needs-confirmation', action: 'analyze' });
56
+ const discovery = discoverProjectWithMetrics(root, { persistCache: true });
57
+ writeProjectModel(root, discovery.model);
58
+ writeGuardMemory(root, discovery.model);
59
+ const revision = writeProjectSnapshot(root, discovery.model);
60
+ return jsonToolResult({
61
+ status: 'ok',
62
+ action: 'analyze',
63
+ revision,
64
+ discovery: discovery.metrics,
65
+ });
66
+ });
67
+ server.registerTool('codapult_guard_next_action', {
68
+ title: 'Guard Next Action',
69
+ description: 'Return the next bounded action for an AI coding-agent loop without modifying project files.',
70
+ inputSchema: { root: rootSchema },
71
+ }, ({ root: requestedRoot }) => {
72
+ const root = getGuardRoot(requestedRoot);
73
+ const loaded = loadConfigSafely(root);
74
+ if (loaded.error)
75
+ return loaded.error;
76
+ const config = loaded.config;
77
+ if (!config) {
78
+ return jsonToolResult({
79
+ status: 'needs-setup',
80
+ action: 'init',
81
+ reason: 'Guard policy is not initialized.',
82
+ });
83
+ }
84
+ const project = discoverProject(root);
85
+ const persisted = loadProjectModel(root);
86
+ if (persisted &&
87
+ 'project' in persisted &&
88
+ fingerprintProjectModel(persisted) !== fingerprintProjectModel(project)) {
89
+ return jsonToolResult({
90
+ status: 'needs-refresh',
91
+ action: 'analyze',
92
+ reason: 'Persisted Guard project facts are stale after repository changes.',
93
+ canRetry: false,
94
+ });
95
+ }
96
+ const proposals = loadGuardProposals(root);
97
+ const proposedCount = getPendingGuardProposals(proposals).length;
98
+ if (proposals && getGuardProposalFreshness(project, proposals) === 'stale') {
99
+ return jsonToolResult({
100
+ status: 'needs-decision',
101
+ action: 'propose',
102
+ reason: 'Guard proposals are stale after project changes.',
103
+ canRetry: false,
104
+ });
105
+ }
106
+ if (proposedCount > 0) {
107
+ return jsonToolResult({
108
+ status: 'needs-decision',
109
+ action: 'policy-review',
110
+ reason: `${proposedCount} proposed policy item(s) await explicit approval or rejection.`,
111
+ canRetry: false,
112
+ });
113
+ }
114
+ const report = scanGuard(root, config, {
115
+ changedOnly: true,
116
+ baseline: loadBaseline(root),
117
+ includeArchitectureInsights: true,
118
+ });
119
+ const contractIssues = validateGuardContracts(root, config.contracts ?? []);
120
+ if (report.findings.some((finding) => finding.severity === 'error')) {
121
+ return jsonToolResult({
122
+ status: 'needs-repair',
123
+ action: 'repair',
124
+ reason: 'Active architecture findings remain in changed files.',
125
+ findings: report.findings,
126
+ canRetry: true,
127
+ });
128
+ }
129
+ if (contractIssues.length > 0) {
130
+ return jsonToolResult({
131
+ status: 'needs-decision',
132
+ action: 'policy-repair',
133
+ reason: 'Guard contracts are stale or invalid.',
134
+ contractIssues,
135
+ canRetry: false,
136
+ });
137
+ }
138
+ return jsonToolResult({
139
+ status: 'ready-for-verification',
140
+ action: 'verify',
141
+ reason: 'No changed-file architecture regressions remain.',
142
+ canRetry: true,
143
+ });
144
+ });
15
145
  server.registerTool('codapult_guard_context', {
16
146
  title: 'Guard Context',
17
147
  description: 'Read the discovered project model, architecture insights, and local rules used by Codapult Guard. Works before init by discovering the project on demand.',
@@ -24,7 +154,10 @@ export function registerGuardTools(server) {
24
154
  },
25
155
  }, ({ root: requestedRoot, refresh }) => {
26
156
  const root = getGuardRoot(requestedRoot);
27
- const config = loadGuardConfig(root);
157
+ const loaded = loadConfigSafely(root);
158
+ if (loaded.error)
159
+ return loaded.error;
160
+ const config = loaded.config;
28
161
  const agentConfig = loadGuardAgentConfig(root);
29
162
  const discovery = refresh
30
163
  ? discoverProjectWithMetrics(root, { persistCache: true })
@@ -72,7 +205,10 @@ export function registerGuardTools(server) {
72
205
  if (persist && !confirm)
73
206
  return jsonToolResult({ status: 'needs-confirmation', persist: true });
74
207
  const project = discoverProject(root);
75
- const config = loadGuardConfig(root) ?? buildGeneratedGuardConfig(project);
208
+ const loaded = loadConfigSafely(root);
209
+ if (loaded.error)
210
+ return loaded.error;
211
+ const config = loaded.config ?? buildGeneratedGuardConfig(project);
76
212
  const proposals = buildGuardProposals(project, config);
77
213
  const previous = loadGuardProposals(root);
78
214
  if (persist) {
@@ -146,7 +282,10 @@ export function registerGuardTools(server) {
146
282
  if (!confirm)
147
283
  return jsonToolResult({ status: 'needs-confirmation', decision, ids });
148
284
  if (decision === 'approved') {
149
- const config = loadGuardConfig(root) ?? { version: 1, rules: [], contracts: [] };
285
+ const loaded = loadConfigSafely(root);
286
+ if (loaded.error)
287
+ return loaded.error;
288
+ const config = loaded.config ?? { version: 1, rules: [], contracts: [] };
150
289
  const nextRules = [...config.rules];
151
290
  const nextContracts = [...(config.contracts ?? [])];
152
291
  for (const item of selected) {
@@ -224,17 +363,12 @@ export function registerGuardTools(server) {
224
363
  inputSchema: { root: rootSchema },
225
364
  }, ({ root: requestedRoot }) => {
226
365
  const root = getGuardRoot(requestedRoot);
227
- const config = loadGuardConfig(root);
366
+ const loaded = loadConfigSafely(root);
367
+ if (loaded.error)
368
+ return loaded.error;
369
+ const config = loaded.config;
228
370
  if (!config) {
229
- return {
230
- content: [
231
- {
232
- type: 'text',
233
- text: JSON.stringify({ configured: false, outcome: 'not-configured' }, null, 2),
234
- },
235
- ],
236
- isError: true,
237
- };
371
+ return notConfiguredToolResult();
238
372
  }
239
373
  const report = scanGuard(root, config, { includeArchitectureInsights: true });
240
374
  const contractIssues = validateGuardContracts(root, config.contracts ?? []);
@@ -270,17 +404,12 @@ export function registerGuardTools(server) {
270
404
  },
271
405
  }, ({ root: requestedRoot, changed_only, max_diff_chars, requirement, base }) => {
272
406
  const root = getGuardRoot(requestedRoot);
273
- const config = loadGuardConfig(root);
407
+ const loaded = loadConfigSafely(root);
408
+ if (loaded.error)
409
+ return loaded.error;
410
+ const config = loaded.config;
274
411
  if (!config) {
275
- return {
276
- content: [
277
- {
278
- type: 'text',
279
- text: JSON.stringify({ configured: false, outcome: 'not-configured' }, null, 2),
280
- },
281
- ],
282
- isError: true,
283
- };
412
+ return notConfiguredToolResult();
284
413
  }
285
414
  const packet = buildGuardReviewPacket(root, config, changed_only ? loadBaseline(root) : new Set(), max_diff_chars, changed_only, requirement, base);
286
415
  return jsonToolResult({ ...packet, status: packet.diffError ? 'fail' : 'needs-review' }, Boolean(packet.diffError));
@@ -291,17 +420,12 @@ export function registerGuardTools(server) {
291
420
  inputSchema: { root: rootSchema, changed_only: z.boolean().optional() },
292
421
  }, ({ root: requestedRoot, changed_only }) => {
293
422
  const root = getGuardRoot(requestedRoot);
294
- const config = loadGuardConfig(root);
423
+ const loaded = loadConfigSafely(root);
424
+ if (loaded.error)
425
+ return loaded.error;
426
+ const config = loaded.config;
295
427
  if (!config) {
296
- return {
297
- content: [
298
- {
299
- type: 'text',
300
- text: JSON.stringify({ configured: false, outcome: 'not-configured' }, null, 2),
301
- },
302
- ],
303
- isError: true,
304
- };
428
+ return notConfiguredToolResult();
305
429
  }
306
430
  const report = scanGuard(root, config, {
307
431
  changedOnly: changed_only,
@@ -330,20 +454,13 @@ export function registerGuardTools(server) {
330
454
  }, ({ root: requestedRoot, files }) => {
331
455
  const root = getGuardRoot(requestedRoot);
332
456
  const model = discoverProject(root);
333
- const changed = new Set(files);
334
- const paths = model.insights.impactPaths.filter((impact) => impact.files.some((file) => changed.has(file)) || changed.has(impact.entrypoint));
335
- const modules = model.modules.filter((module) => changed.has(module.path) || module.resolvedImports.some((file) => changed.has(file)));
336
- const capabilities = Object.entries(model.capabilities)
337
- .filter(([, signal]) => signal.files.some((file) => changed.has(file)))
338
- .map(([id]) => id);
339
- const contracts = (loadGuardConfig(root)?.contracts ?? []).filter((contract) => [...(contract.scope ?? []), ...(contract.entrypoints ?? [])].some((scope) => [...changed].some((file) => file === scope || file.startsWith(`${scope}/`))));
457
+ const loaded = loadConfigSafely(root);
458
+ if (loaded.error)
459
+ return loaded.error;
460
+ const impact = analyzeProjectImpact(model, files, loaded.config?.contracts ?? []);
340
461
  return jsonToolResult({
341
462
  status: 'ok',
342
- files,
343
- affectedModules: modules.map((module) => module.path),
344
- impactPaths: paths,
345
- capabilities,
346
- relevantContracts: contracts,
463
+ ...impact,
347
464
  });
348
465
  });
349
466
  server.registerTool('codapult_guard_explain', {
@@ -355,7 +472,10 @@ export function registerGuardTools(server) {
355
472
  },
356
473
  }, ({ root: requestedRoot, id }) => {
357
474
  const root = getGuardRoot(requestedRoot);
358
- const config = loadGuardConfig(root);
475
+ const loaded = loadConfigSafely(root);
476
+ if (loaded.error)
477
+ return loaded.error;
478
+ const config = loaded.config;
359
479
  const item = [...(config?.rules ?? []), ...(config?.contracts ?? [])].find((candidate) => candidate.id === id);
360
480
  if (!item)
361
481
  return jsonToolResult({ status: 'not-found', id }, true);
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@codapult/guard",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "Local-first architecture guardrails for JavaScript and TypeScript projects, with first-class support for Next.js SaaS and AI-assisted development",
5
5
  "license": "MIT",
6
- "packageManager": "pnpm@11.22.0+sha512.1ff870c4c6133dfd88fb2afc46dd13d47f09c9794b438c6fdb47ca98caf3bc16381ee0be93a091b8e3824cf01f889f46d7d9e20910fb0be1ab0fb5baa80dd621",
6
+ "packageManager": "pnpm@12.4.2+sha512.08adc6613180275c7c9edada39dcf08c9c61ad4e7eaf330a4f3461f102b0f907423454d117f98e72d47fef0616070644d7bffc973a6a57f5090a6d7c368b07c9",
7
7
  "engines": {
8
8
  "node": ">=20.19.0"
9
9
  },
@@ -60,7 +60,12 @@
60
60
  "test:guard:fixtures": "pnpm build && node scripts/guard-fixture-smoke.mjs",
61
61
  "test:guard:fixtures:regression": "pnpm build && node scripts/guard-fixture-regression.mjs",
62
62
  "test:guard:fixtures:native": "pnpm build && node scripts/guard-fixture-native.mjs",
63
+ "test:guard:fixtures:adversarial": "pnpm build && node scripts/guard-fixture-adversarial.mjs",
64
+ "test:guard:fixtures:all": "pnpm build && node scripts/guard-fixture-suite.mjs",
65
+ "test:guard:fixtures:full": "pnpm build && node scripts/guard-fixture-suite.mjs --all",
66
+ "test:guard:concurrent": "pnpm build && node scripts/guard-concurrent-state.mjs",
63
67
  "test:guard:pr": "pnpm build && node scripts/guard-pr-review.mjs",
68
+ "test:guard:benchmark": "pnpm build && node scripts/guard-benchmark.mjs",
64
69
  "test:guard:golden": "pnpm build && node scripts/guard-golden-demo.mjs",
65
70
  "test:watch": "vitest",
66
71
  "typecheck": "tsc --noEmit",
@@ -95,23 +100,23 @@
95
100
  "semver": "^7.8.5",
96
101
  "ts-morph": "^28.0.0",
97
102
  "typescript": "npm:@typescript/typescript6@^6.0.2",
98
- "zod": "^4.4.3"
103
+ "zod": "^4.6.5"
99
104
  },
100
105
  "devDependencies": {
101
106
  "@js-toolkit/config-utils": "^1.0.1",
102
- "@js-toolkit/eslint-config": "^1.1.4",
107
+ "@js-toolkit/eslint-config": "^1.3.0",
103
108
  "@js-toolkit/prettier-config": "^1.0.1",
104
109
  "@js-toolkit/tsconfig": "^1.0.1",
105
- "@release-it/conventional-changelog": "^12.0.0",
106
- "@types/node": "^26.2.0",
110
+ "@release-it/conventional-changelog": "^12.0.2",
111
+ "@types/node": "^26.6.1",
107
112
  "@typescript/native": "npm:typescript@^7.0.2",
108
- "@vitest/coverage-v8": "^4.1.11",
109
- "eslint": "^9.39.4",
113
+ "@vitest/coverage-v8": "^5.0.1",
114
+ "eslint": "^10.10.0",
110
115
  "eslint-config-prettier": "^10.1.8",
111
116
  "eslint-plugin-prettier": "^5.5.6",
112
- "prettier": "^3.9.6",
113
- "release-it": "^21.0.2",
114
- "typescript-eslint": "^8.67.0",
115
- "vitest": "^4.1.11"
117
+ "prettier": "^3.9.7",
118
+ "release-it": "^21.0.3",
119
+ "typescript-eslint": "^8.70.0",
120
+ "vitest": "^5.0.1"
116
121
  }
117
122
  }