@eddacraft/anvil-runtime 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.
- package/LICENSE +14 -0
- package/dist/cache/cache-key.d.ts +45 -0
- package/dist/cache/cache-key.d.ts.map +1 -0
- package/dist/cache/cache-key.js +135 -0
- package/dist/cache/index.d.ts +27 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +38 -0
- package/dist/cache/providers/file-cache.d.ts +63 -0
- package/dist/cache/providers/file-cache.d.ts.map +1 -0
- package/dist/cache/providers/file-cache.js +369 -0
- package/dist/cache/providers/memory-cache.d.ts +52 -0
- package/dist/cache/providers/memory-cache.d.ts.map +1 -0
- package/dist/cache/providers/memory-cache.js +197 -0
- package/dist/cache/providers/null-cache.d.ts +26 -0
- package/dist/cache/providers/null-cache.d.ts.map +1 -0
- package/dist/cache/providers/null-cache.js +50 -0
- package/dist/cache/types.d.ts +114 -0
- package/dist/cache/types.d.ts.map +1 -0
- package/dist/cache/types.js +4 -0
- package/dist/concurrency/agent.d.ts +137 -0
- package/dist/concurrency/agent.d.ts.map +1 -0
- package/dist/concurrency/agent.js +440 -0
- package/dist/concurrency/atomic.d.ts +93 -0
- package/dist/concurrency/atomic.d.ts.map +1 -0
- package/dist/concurrency/atomic.js +281 -0
- package/dist/concurrency/git-agent.d.ts +114 -0
- package/dist/concurrency/git-agent.d.ts.map +1 -0
- package/dist/concurrency/git-agent.js +313 -0
- package/dist/concurrency/index.d.ts +95 -0
- package/dist/concurrency/index.d.ts.map +1 -0
- package/dist/concurrency/index.js +127 -0
- package/dist/concurrency/lock-manager.d.ts +170 -0
- package/dist/concurrency/lock-manager.d.ts.map +1 -0
- package/dist/concurrency/lock-manager.js +525 -0
- package/dist/concurrency/queue-manager.d.ts +166 -0
- package/dist/concurrency/queue-manager.d.ts.map +1 -0
- package/dist/concurrency/queue-manager.js +442 -0
- package/dist/concurrency/types.d.ts +382 -0
- package/dist/concurrency/types.d.ts.map +1 -0
- package/dist/concurrency/types.js +204 -0
- package/dist/export/constraint-collector.d.ts +175 -0
- package/dist/export/constraint-collector.d.ts.map +1 -0
- package/dist/export/constraint-collector.js +203 -0
- package/dist/export/formatters/llms-txt-formatter.d.ts +89 -0
- package/dist/export/formatters/llms-txt-formatter.d.ts.map +1 -0
- package/dist/export/formatters/llms-txt-formatter.js +249 -0
- package/dist/export/formatters/mcp-resource-formatter.d.ts +186 -0
- package/dist/export/formatters/mcp-resource-formatter.d.ts.map +1 -0
- package/dist/export/formatters/mcp-resource-formatter.js +139 -0
- package/dist/export/formatters/prompt-formatter.d.ts +83 -0
- package/dist/export/formatters/prompt-formatter.d.ts.map +1 -0
- package/dist/export/formatters/prompt-formatter.js +256 -0
- package/dist/export/index.d.ts +10 -0
- package/dist/export/index.d.ts.map +1 -0
- package/dist/export/index.js +9 -0
- package/dist/gate/check.interface.d.ts +15 -0
- package/dist/gate/check.interface.d.ts.map +1 -0
- package/dist/gate/check.interface.js +18 -0
- package/dist/gate/checks/antipattern.check.d.ts +27 -0
- package/dist/gate/checks/antipattern.check.d.ts.map +1 -0
- package/dist/gate/checks/antipattern.check.js +140 -0
- package/dist/gate/checks/architecture/circular-detector.d.ts +33 -0
- package/dist/gate/checks/architecture/circular-detector.d.ts.map +1 -0
- package/dist/gate/checks/architecture/circular-detector.js +71 -0
- package/dist/gate/checks/architecture/dependency-analyzer.d.ts +81 -0
- package/dist/gate/checks/architecture/dependency-analyzer.d.ts.map +1 -0
- package/dist/gate/checks/architecture/dependency-analyzer.js +136 -0
- package/dist/gate/checks/architecture/layer-validator.d.ts +75 -0
- package/dist/gate/checks/architecture/layer-validator.d.ts.map +1 -0
- package/dist/gate/checks/architecture/layer-validator.js +193 -0
- package/dist/gate/checks/architecture.check.d.ts +56 -0
- package/dist/gate/checks/architecture.check.d.ts.map +1 -0
- package/dist/gate/checks/architecture.check.js +394 -0
- package/dist/gate/checks/command-safety.check.d.ts +12 -0
- package/dist/gate/checks/command-safety.check.d.ts.map +1 -0
- package/dist/gate/checks/command-safety.check.js +230 -0
- package/dist/gate/checks/coverage.check.d.ts +9 -0
- package/dist/gate/checks/coverage.check.d.ts.map +1 -0
- package/dist/gate/checks/coverage.check.js +81 -0
- package/dist/gate/checks/dependency.check.d.ts +17 -0
- package/dist/gate/checks/dependency.check.d.ts.map +1 -0
- package/dist/gate/checks/dependency.check.js +342 -0
- package/dist/gate/checks/eslint.check.d.ts +14 -0
- package/dist/gate/checks/eslint.check.d.ts.map +1 -0
- package/dist/gate/checks/eslint.check.js +79 -0
- package/dist/gate/checks/policy.check.d.ts +78 -0
- package/dist/gate/checks/policy.check.d.ts.map +1 -0
- package/dist/gate/checks/policy.check.js +457 -0
- package/dist/gate/checks/secret/entropy-detector.d.ts +44 -0
- package/dist/gate/checks/secret/entropy-detector.d.ts.map +1 -0
- package/dist/gate/checks/secret/entropy-detector.js +76 -0
- package/dist/gate/checks/secret/git-scanner.d.ts +36 -0
- package/dist/gate/checks/secret/git-scanner.d.ts.map +1 -0
- package/dist/gate/checks/secret/git-scanner.js +90 -0
- package/dist/gate/checks/secret/secret-patterns.d.ts +42 -0
- package/dist/gate/checks/secret/secret-patterns.d.ts.map +1 -0
- package/dist/gate/checks/secret/secret-patterns.js +137 -0
- package/dist/gate/checks/secret.check.d.ts +56 -0
- package/dist/gate/checks/secret.check.d.ts.map +1 -0
- package/dist/gate/checks/secret.check.js +245 -0
- package/dist/gate/config/command-safety-config.d.ts +5 -0
- package/dist/gate/config/command-safety-config.d.ts.map +1 -0
- package/dist/gate/config/command-safety-config.js +69 -0
- package/dist/gate/config/index.d.ts +2 -0
- package/dist/gate/config/index.d.ts.map +1 -0
- package/dist/gate/config/index.js +1 -0
- package/dist/gate/formatters/command-safety-formatter.d.ts +10 -0
- package/dist/gate/formatters/command-safety-formatter.d.ts.map +1 -0
- package/dist/gate/formatters/command-safety-formatter.js +64 -0
- package/dist/gate/formatters/index.d.ts +2 -0
- package/dist/gate/formatters/index.d.ts.map +1 -0
- package/dist/gate/formatters/index.js +1 -0
- package/dist/gate/gate-config.d.ts +44 -0
- package/dist/gate/gate-config.d.ts.map +1 -0
- package/dist/gate/gate-config.js +334 -0
- package/dist/gate/gate-runner.d.ts +160 -0
- package/dist/gate/gate-runner.d.ts.map +1 -0
- package/dist/gate/gate-runner.js +531 -0
- package/dist/gate/index.d.ts +20 -0
- package/dist/gate/index.d.ts.map +1 -0
- package/dist/gate/index.js +14 -0
- package/dist/gate/parsers/command-parser.d.ts +18 -0
- package/dist/gate/parsers/command-parser.d.ts.map +1 -0
- package/dist/gate/parsers/command-parser.js +363 -0
- package/dist/gate/parsers/index.d.ts +2 -0
- package/dist/gate/parsers/index.d.ts.map +1 -0
- package/dist/gate/parsers/index.js +1 -0
- package/dist/gate/policy/index.d.ts +12 -0
- package/dist/gate/policy/index.d.ts.map +1 -0
- package/dist/gate/policy/index.js +10 -0
- package/dist/gate/rules/default-filesystem-rules.d.ts +3 -0
- package/dist/gate/rules/default-filesystem-rules.d.ts.map +1 -0
- package/dist/gate/rules/default-filesystem-rules.js +201 -0
- package/dist/gate/rules/default-git-rules.d.ts +3 -0
- package/dist/gate/rules/default-git-rules.d.ts.map +1 -0
- package/dist/gate/rules/default-git-rules.js +192 -0
- package/dist/gate/rules/index.d.ts +5 -0
- package/dist/gate/rules/index.d.ts.map +1 -0
- package/dist/gate/rules/index.js +3 -0
- package/dist/gate/rules/rule-matcher.d.ts +27 -0
- package/dist/gate/rules/rule-matcher.d.ts.map +1 -0
- package/dist/gate/rules/rule-matcher.js +228 -0
- package/dist/gate/rules/types.d.ts +250 -0
- package/dist/gate/rules/types.d.ts.map +1 -0
- package/dist/gate/rules/types.js +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +35 -0
- package/dist/types/gate.types.d.ts +42 -0
- package/dist/types/gate.types.d.ts.map +1 -0
- package/dist/types/gate.types.js +94 -0
- package/dist/watch/debouncer.d.ts +90 -0
- package/dist/watch/debouncer.d.ts.map +1 -0
- package/dist/watch/debouncer.js +135 -0
- package/dist/watch/file-watcher.d.ts +73 -0
- package/dist/watch/file-watcher.d.ts.map +1 -0
- package/dist/watch/file-watcher.js +121 -0
- package/dist/watch/git-status.d.ts +98 -0
- package/dist/watch/git-status.d.ts.map +1 -0
- package/dist/watch/git-status.js +266 -0
- package/dist/watch/index.d.ts +16 -0
- package/dist/watch/index.d.ts.map +1 -0
- package/dist/watch/index.js +15 -0
- package/dist/watch/orchestrator.d.ts +113 -0
- package/dist/watch/orchestrator.d.ts.map +1 -0
- package/dist/watch/orchestrator.js +409 -0
- package/dist/watch/types.d.ts +190 -0
- package/dist/watch/types.d.ts.map +1 -0
- package/dist/watch/types.js +76 -0
- package/package.json +60 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CommandSafetyFinding, CommandAnalysisSummary, CommandSafetyOutputConfig } from '../rules/types.js';
|
|
2
|
+
export interface FormatOptions {
|
|
3
|
+
verbose?: boolean;
|
|
4
|
+
showSuggestions?: boolean;
|
|
5
|
+
showReferences?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function formatBlockedCommands(blocked: CommandSafetyFinding[], options?: FormatOptions | CommandSafetyOutputConfig): string;
|
|
8
|
+
export declare function formatWarningCommands(warnings: CommandSafetyFinding[], options?: FormatOptions | CommandSafetyOutputConfig): string;
|
|
9
|
+
export declare function formatSummary(summary: CommandAnalysisSummary): string;
|
|
10
|
+
//# sourceMappingURL=command-safety-formatter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-safety-formatter.d.ts","sourceRoot":"","sources":["../../../src/gate/formatters/command-safety-formatter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oBAAoB,EACpB,sBAAsB,EACtB,yBAAyB,EAC1B,MAAM,mBAAmB,CAAC;AAK3B,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAQD,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,oBAAoB,EAAE,EAC/B,OAAO,CAAC,EAAE,aAAa,GAAG,yBAAyB,GAClD,MAAM,CAyBR;AAED,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,oBAAoB,EAAE,EAChC,OAAO,CAAC,EAAE,aAAa,GAAG,yBAAyB,GAClD,MAAM,CAsBR;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,sBAAsB,GAAG,MAAM,CAmBrE"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { createDebugger } from '@eddacraft/anvil-core';
|
|
2
|
+
const debug = createDebugger('gate');
|
|
3
|
+
const DEFAULT_FORMAT_OPTIONS = {
|
|
4
|
+
verbose: true,
|
|
5
|
+
showSuggestions: true,
|
|
6
|
+
showReferences: true,
|
|
7
|
+
};
|
|
8
|
+
export function formatBlockedCommands(blocked, options) {
|
|
9
|
+
debug(`formatBlockedCommands: count=${blocked.length}`);
|
|
10
|
+
if (blocked.length === 0) {
|
|
11
|
+
return '';
|
|
12
|
+
}
|
|
13
|
+
const opts = { ...DEFAULT_FORMAT_OPTIONS, ...options };
|
|
14
|
+
const lines = [`Blocked ${blocked.length} dangerous command(s):`, ''];
|
|
15
|
+
for (let i = 0; i < blocked.length; i++) {
|
|
16
|
+
const finding = blocked[i];
|
|
17
|
+
lines.push(`${i + 1}. ${finding.command}`);
|
|
18
|
+
if (opts.verbose) {
|
|
19
|
+
lines.push(` Reason: ${finding.reason}`);
|
|
20
|
+
}
|
|
21
|
+
if (opts.showSuggestions && finding.suggestion) {
|
|
22
|
+
lines.push(` Suggestion: ${finding.suggestion}`);
|
|
23
|
+
}
|
|
24
|
+
if (opts.showReferences && finding.references && finding.references.length > 0) {
|
|
25
|
+
lines.push(` Reference: ${finding.references[0]}`);
|
|
26
|
+
}
|
|
27
|
+
lines.push('');
|
|
28
|
+
}
|
|
29
|
+
return lines.join('\n');
|
|
30
|
+
}
|
|
31
|
+
export function formatWarningCommands(warnings, options) {
|
|
32
|
+
debug(`formatWarningCommands: count=${warnings.length}`);
|
|
33
|
+
if (warnings.length === 0) {
|
|
34
|
+
return '';
|
|
35
|
+
}
|
|
36
|
+
const opts = { ...DEFAULT_FORMAT_OPTIONS, ...options };
|
|
37
|
+
const lines = [`Found ${warnings.length} potentially dangerous command(s):`, ''];
|
|
38
|
+
for (let i = 0; i < warnings.length; i++) {
|
|
39
|
+
const finding = warnings[i];
|
|
40
|
+
lines.push(`${i + 1}. ${finding.command}`);
|
|
41
|
+
if (opts.verbose) {
|
|
42
|
+
lines.push(` Reason: ${finding.reason}`);
|
|
43
|
+
}
|
|
44
|
+
if (opts.showSuggestions && finding.suggestion) {
|
|
45
|
+
lines.push(` Suggestion: ${finding.suggestion}`);
|
|
46
|
+
}
|
|
47
|
+
lines.push('');
|
|
48
|
+
}
|
|
49
|
+
return lines.join('\n');
|
|
50
|
+
}
|
|
51
|
+
export function formatSummary(summary) {
|
|
52
|
+
debug(`formatSummary: total=${summary.total} blocked=${summary.blocked} warned=${summary.warned}`);
|
|
53
|
+
const { total, blocked, warned } = summary;
|
|
54
|
+
if (total === 0) {
|
|
55
|
+
return 'No commands to analyse';
|
|
56
|
+
}
|
|
57
|
+
if (blocked === 0 && warned === 0) {
|
|
58
|
+
return `All ${total} command(s) passed safety check`;
|
|
59
|
+
}
|
|
60
|
+
if (blocked === 0) {
|
|
61
|
+
return `${total} command(s) analysed: ${warned} warning(s)`;
|
|
62
|
+
}
|
|
63
|
+
return `Command safety check failed: ${blocked} blocked, ${warned} warning(s) of ${total} total`;
|
|
64
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/gate/formatters/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,aAAa,EACb,KAAK,aAAa,GACnB,MAAM,+BAA+B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { formatBlockedCommands, formatWarningCommands, formatSummary, } from './command-safety-formatter.js';
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { GateConfig, GateCheck } from '../types/gate.types.js';
|
|
2
|
+
import { type WatchConfig } from '../watch/types.js';
|
|
3
|
+
export interface ConfigLoadResult {
|
|
4
|
+
config: GateConfig;
|
|
5
|
+
path: string | null;
|
|
6
|
+
isDefault: boolean;
|
|
7
|
+
errors: string[];
|
|
8
|
+
}
|
|
9
|
+
export declare class GateConfigManager {
|
|
10
|
+
private configPath;
|
|
11
|
+
private workspaceRoot;
|
|
12
|
+
constructor(workspaceRoot: string);
|
|
13
|
+
/**
|
|
14
|
+
* Find the first existing config file from priority locations
|
|
15
|
+
*/
|
|
16
|
+
private findConfigFile;
|
|
17
|
+
/**
|
|
18
|
+
* Get the path where config will be saved (prefers existing location, defaults to .anvilrc)
|
|
19
|
+
*/
|
|
20
|
+
getConfigPath(): string;
|
|
21
|
+
/**
|
|
22
|
+
* Get all possible config locations
|
|
23
|
+
*/
|
|
24
|
+
getConfigLocations(): string[];
|
|
25
|
+
loadConfig(): GateConfig;
|
|
26
|
+
/**
|
|
27
|
+
* Load configuration with detailed result including path and validation errors
|
|
28
|
+
*/
|
|
29
|
+
loadConfigWithDetails(): ConfigLoadResult;
|
|
30
|
+
saveConfig(config: GateConfig): void;
|
|
31
|
+
getDefaultConfig(): GateConfig;
|
|
32
|
+
/**
|
|
33
|
+
* Validate and normalise configuration with detailed error tracking
|
|
34
|
+
*/
|
|
35
|
+
private validateAndNormalizeConfigWithErrors;
|
|
36
|
+
/**
|
|
37
|
+
* Get watch configuration (parsed and validated)
|
|
38
|
+
*/
|
|
39
|
+
getWatchConfig(): WatchConfig | undefined;
|
|
40
|
+
updateCheck(name: string, updates: Partial<GateCheck>): void;
|
|
41
|
+
enableCheck(name: string): void;
|
|
42
|
+
disableCheck(name: string): void;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=gate-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate-config.d.ts","sourceRoot":"","sources":["../../src/gate/gate-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAA6B,MAAM,wBAAwB,CAAC;AAG1F,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAaxE,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,UAAU,CAAC;IACnB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,aAAa,CAAS;gBAElB,aAAa,EAAE,MAAM;IAMjC;;OAEG;IACH,OAAO,CAAC,cAAc;IAYtB;;OAEG;IACH,aAAa,IAAI,MAAM;IAIvB;;OAEG;IACH,kBAAkB,IAAI,MAAM,EAAE;IAI9B,UAAU,IAAI,UAAU;IAKxB;;OAEG;IACH,qBAAqB,IAAI,gBAAgB;IA0CzC,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;IAcpC,gBAAgB,IAAI,UAAU;IAuE9B;;OAEG;IACH,OAAO,CAAC,oCAAoC;IA2J5C;;OAEG;IACH,cAAc,IAAI,WAAW,GAAG,SAAS;IAMzC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,IAAI;IAkB5D,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI/B,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;CAGjC"}
|
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
import { readFileSync, existsSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
2
|
+
import { join, dirname } from 'node:path';
|
|
3
|
+
import { WatchConfigSchema } from '../watch/types.js';
|
|
4
|
+
import { createDebugger } from '@eddacraft/anvil-core';
|
|
5
|
+
const debug = createDebugger('gate');
|
|
6
|
+
/**
|
|
7
|
+
* Configuration file locations in priority order
|
|
8
|
+
*/
|
|
9
|
+
const CONFIG_LOCATIONS = [
|
|
10
|
+
'.anvilrc', // Root level (primary)
|
|
11
|
+
'.anvil/config.json', // .anvil directory (alternative)
|
|
12
|
+
];
|
|
13
|
+
export class GateConfigManager {
|
|
14
|
+
configPath = null;
|
|
15
|
+
workspaceRoot;
|
|
16
|
+
constructor(workspaceRoot) {
|
|
17
|
+
this.workspaceRoot = workspaceRoot;
|
|
18
|
+
this.configPath = this.findConfigFile();
|
|
19
|
+
debug(`GateConfigManager: workspace=${workspaceRoot} configPath=${this.configPath}`);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Find the first existing config file from priority locations
|
|
23
|
+
*/
|
|
24
|
+
findConfigFile() {
|
|
25
|
+
for (const location of CONFIG_LOCATIONS) {
|
|
26
|
+
const fullPath = join(this.workspaceRoot, location);
|
|
27
|
+
if (existsSync(fullPath)) {
|
|
28
|
+
debug(`findConfigFile: found ${fullPath}`);
|
|
29
|
+
return fullPath;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
debug('findConfigFile: no config found, will use defaults');
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Get the path where config will be saved (prefers existing location, defaults to .anvilrc)
|
|
37
|
+
*/
|
|
38
|
+
getConfigPath() {
|
|
39
|
+
return this.configPath || join(this.workspaceRoot, '.anvilrc');
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Get all possible config locations
|
|
43
|
+
*/
|
|
44
|
+
getConfigLocations() {
|
|
45
|
+
return CONFIG_LOCATIONS.map((loc) => join(this.workspaceRoot, loc));
|
|
46
|
+
}
|
|
47
|
+
loadConfig() {
|
|
48
|
+
const result = this.loadConfigWithDetails();
|
|
49
|
+
return result.config;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Load configuration with detailed result including path and validation errors
|
|
53
|
+
*/
|
|
54
|
+
loadConfigWithDetails() {
|
|
55
|
+
debug(`loadConfigWithDetails: path=${this.configPath}`);
|
|
56
|
+
if (!this.configPath) {
|
|
57
|
+
debug('loadConfigWithDetails: using default config');
|
|
58
|
+
return {
|
|
59
|
+
config: this.getDefaultConfig(),
|
|
60
|
+
path: null,
|
|
61
|
+
isDefault: true,
|
|
62
|
+
errors: [],
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
try {
|
|
66
|
+
const content = readFileSync(this.configPath, 'utf-8');
|
|
67
|
+
const rawConfig = JSON.parse(content);
|
|
68
|
+
const { config, errors } = this.validateAndNormalizeConfigWithErrors(rawConfig);
|
|
69
|
+
debug(`loadConfigWithDetails: loaded ${config.checks.length} checks, ${errors.length} errors`);
|
|
70
|
+
return {
|
|
71
|
+
config,
|
|
72
|
+
path: this.configPath,
|
|
73
|
+
isDefault: false,
|
|
74
|
+
errors,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
79
|
+
console.warn(`Failed to load gate config from ${this.configPath}, using defaults:`, errorMessage);
|
|
80
|
+
return {
|
|
81
|
+
config: this.getDefaultConfig(),
|
|
82
|
+
path: this.configPath,
|
|
83
|
+
isDefault: true,
|
|
84
|
+
errors: [`Failed to parse config: ${errorMessage}`],
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
saveConfig(config) {
|
|
89
|
+
const savePath = this.getConfigPath();
|
|
90
|
+
debug(`saveConfig: path=${savePath} checks=${config.checks.length}`);
|
|
91
|
+
const content = JSON.stringify(config, null, 2);
|
|
92
|
+
// Ensure directory exists before writing file
|
|
93
|
+
const dir = dirname(savePath);
|
|
94
|
+
if (!existsSync(dir)) {
|
|
95
|
+
mkdirSync(dir, { recursive: true });
|
|
96
|
+
}
|
|
97
|
+
writeFileSync(savePath, content, 'utf-8');
|
|
98
|
+
// Update configPath to the saved location
|
|
99
|
+
this.configPath = savePath;
|
|
100
|
+
}
|
|
101
|
+
getDefaultConfig() {
|
|
102
|
+
return {
|
|
103
|
+
version: 1,
|
|
104
|
+
checks: [
|
|
105
|
+
{
|
|
106
|
+
name: 'eslint',
|
|
107
|
+
description: 'Code quality checks',
|
|
108
|
+
enabled: true,
|
|
109
|
+
config: {
|
|
110
|
+
min_score: 80,
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
name: 'coverage',
|
|
115
|
+
description: 'Test coverage validation',
|
|
116
|
+
enabled: true,
|
|
117
|
+
config: {
|
|
118
|
+
min_score: 80,
|
|
119
|
+
thresholds: {
|
|
120
|
+
lines: 80,
|
|
121
|
+
functions: 80,
|
|
122
|
+
branches: 80,
|
|
123
|
+
statements: 80,
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
name: 'secret',
|
|
129
|
+
description: 'Secret scanning',
|
|
130
|
+
enabled: true,
|
|
131
|
+
config: {},
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
name: 'dependency',
|
|
135
|
+
description: 'Dependency vulnerability scanning',
|
|
136
|
+
enabled: true,
|
|
137
|
+
config: {
|
|
138
|
+
min_severity: 'moderate',
|
|
139
|
+
fail_on_critical: true,
|
|
140
|
+
fail_on_high: true,
|
|
141
|
+
fail_on_moderate: false,
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
name: 'policy',
|
|
146
|
+
description: 'OPA/Rego policy evaluation',
|
|
147
|
+
enabled: false, // Disabled by default until policies are configured
|
|
148
|
+
config: {
|
|
149
|
+
policy_dir: '.anvil/policies',
|
|
150
|
+
severity_threshold: 'error',
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
name: 'architecture',
|
|
155
|
+
description: 'Architecture validation using dependency-cruiser',
|
|
156
|
+
enabled: false, // Disabled by default until dependency-cruiser is installed
|
|
157
|
+
config: {
|
|
158
|
+
config_file: '.anvil/dependency-cruiser.js',
|
|
159
|
+
scope: 'affected',
|
|
160
|
+
severity_threshold: 'error',
|
|
161
|
+
fail_on_circular: true,
|
|
162
|
+
fail_on_orphan: false,
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
],
|
|
166
|
+
thresholds: {
|
|
167
|
+
overall_score: 80,
|
|
168
|
+
},
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Validate and normalise configuration with detailed error tracking
|
|
173
|
+
*/
|
|
174
|
+
validateAndNormalizeConfigWithErrors(config) {
|
|
175
|
+
const errors = [];
|
|
176
|
+
// Type guard to ensure config is an object
|
|
177
|
+
if (typeof config !== 'object' || config === null) {
|
|
178
|
+
errors.push('Configuration must be an object');
|
|
179
|
+
return { config: this.getDefaultConfig(), errors };
|
|
180
|
+
}
|
|
181
|
+
const configObj = config;
|
|
182
|
+
// Validate version
|
|
183
|
+
if (!configObj.version) {
|
|
184
|
+
errors.push('Missing required field: version (defaulting to 1)');
|
|
185
|
+
configObj.version = 1;
|
|
186
|
+
}
|
|
187
|
+
else if (typeof configObj.version !== 'number') {
|
|
188
|
+
errors.push(`Invalid version type: expected number, got ${typeof configObj.version}`);
|
|
189
|
+
configObj.version = 1;
|
|
190
|
+
}
|
|
191
|
+
// Validate checks
|
|
192
|
+
if (!configObj.checks) {
|
|
193
|
+
errors.push('Missing required field: checks (defaulting to empty array)');
|
|
194
|
+
configObj.checks = [];
|
|
195
|
+
}
|
|
196
|
+
else if (!Array.isArray(configObj.checks)) {
|
|
197
|
+
errors.push(`Invalid checks type: expected array, got ${typeof configObj.checks}`);
|
|
198
|
+
configObj.checks = [];
|
|
199
|
+
}
|
|
200
|
+
// Validate thresholds
|
|
201
|
+
if (!configObj.thresholds) {
|
|
202
|
+
errors.push('Missing required field: thresholds (using default overall_score: 80)');
|
|
203
|
+
configObj.thresholds = { overall_score: 80 };
|
|
204
|
+
}
|
|
205
|
+
else if (typeof configObj.thresholds !== 'object' || configObj.thresholds === null) {
|
|
206
|
+
errors.push(`Invalid thresholds type: expected object, got ${typeof configObj.thresholds}`);
|
|
207
|
+
configObj.thresholds = { overall_score: 80 };
|
|
208
|
+
}
|
|
209
|
+
// Validate each check
|
|
210
|
+
const checksArray = Array.isArray(configObj.checks) ? configObj.checks : [];
|
|
211
|
+
const validatedChecks = checksArray.map((check, index) => {
|
|
212
|
+
if (typeof check !== 'object' || check === null) {
|
|
213
|
+
errors.push(`checks[${index}]: expected object, got ${typeof check}`);
|
|
214
|
+
return {
|
|
215
|
+
name: 'unknown',
|
|
216
|
+
description: '',
|
|
217
|
+
enabled: false,
|
|
218
|
+
config: {},
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
const checkObj = check;
|
|
222
|
+
// Validate check name
|
|
223
|
+
if (typeof checkObj.name !== 'string' || !checkObj.name) {
|
|
224
|
+
errors.push(`checks[${index}].name: missing or invalid name`);
|
|
225
|
+
}
|
|
226
|
+
// Validate check config if present
|
|
227
|
+
if (checkObj.config !== undefined &&
|
|
228
|
+
(typeof checkObj.config !== 'object' || checkObj.config === null)) {
|
|
229
|
+
errors.push(`checks[${index}].config: expected object, got ${typeof checkObj.config}`);
|
|
230
|
+
}
|
|
231
|
+
return {
|
|
232
|
+
name: typeof checkObj.name === 'string' ? checkObj.name : 'unknown',
|
|
233
|
+
description: typeof checkObj.description === 'string' ? checkObj.description : '',
|
|
234
|
+
enabled: checkObj.enabled !== false,
|
|
235
|
+
config: typeof checkObj.config === 'object' && checkObj.config !== null
|
|
236
|
+
? checkObj.config
|
|
237
|
+
: {},
|
|
238
|
+
};
|
|
239
|
+
});
|
|
240
|
+
// Parse watch config if present
|
|
241
|
+
let watchConfig;
|
|
242
|
+
if (configObj.watch !== undefined) {
|
|
243
|
+
try {
|
|
244
|
+
watchConfig = WatchConfigSchema.parse(configObj.watch);
|
|
245
|
+
}
|
|
246
|
+
catch (watchError) {
|
|
247
|
+
errors.push(`watch: invalid configuration - ${watchError instanceof Error ? watchError.message : 'unknown error'}`);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
// Pass through policy config if present (bundles, verification settings)
|
|
251
|
+
let policyConfig;
|
|
252
|
+
if (configObj.policy !== undefined &&
|
|
253
|
+
typeof configObj.policy === 'object' &&
|
|
254
|
+
configObj.policy !== null) {
|
|
255
|
+
policyConfig = configObj.policy;
|
|
256
|
+
}
|
|
257
|
+
// Parse stack config if present (STACK-012)
|
|
258
|
+
let stackConfig;
|
|
259
|
+
if (configObj.stack !== undefined &&
|
|
260
|
+
typeof configObj.stack === 'object' &&
|
|
261
|
+
configObj.stack !== null) {
|
|
262
|
+
const stack = configObj.stack;
|
|
263
|
+
// Validate layer configs
|
|
264
|
+
for (const layer of ['kindling', 'ember', 'edda']) {
|
|
265
|
+
if (stack[layer] !== undefined) {
|
|
266
|
+
if (typeof stack[layer] !== 'object' || stack[layer] === null) {
|
|
267
|
+
errors.push(`stack.${layer}: expected object`);
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
const layerConfig = stack[layer];
|
|
271
|
+
if (layerConfig.enabled !== undefined && typeof layerConfig.enabled !== 'boolean') {
|
|
272
|
+
errors.push(`stack.${layer}.enabled: expected boolean`);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
// Validate validation config
|
|
278
|
+
if (stack.validation !== undefined) {
|
|
279
|
+
if (typeof stack.validation !== 'object' || stack.validation === null) {
|
|
280
|
+
errors.push('stack.validation: expected object');
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
const validation = stack.validation;
|
|
284
|
+
for (const key of ['check_provenance_integrity', 'check_schema_compatibility']) {
|
|
285
|
+
if (validation[key] !== undefined && typeof validation[key] !== 'boolean') {
|
|
286
|
+
errors.push(`stack.validation.${key}: expected boolean`);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
stackConfig = stack;
|
|
292
|
+
}
|
|
293
|
+
const validatedConfig = {
|
|
294
|
+
version: configObj.version,
|
|
295
|
+
checks: validatedChecks,
|
|
296
|
+
thresholds: configObj.thresholds,
|
|
297
|
+
global_config: configObj.global_config,
|
|
298
|
+
watch: watchConfig,
|
|
299
|
+
policy: policyConfig,
|
|
300
|
+
stack: stackConfig,
|
|
301
|
+
};
|
|
302
|
+
return { config: validatedConfig, errors };
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Get watch configuration (parsed and validated)
|
|
306
|
+
*/
|
|
307
|
+
getWatchConfig() {
|
|
308
|
+
const config = this.loadConfig();
|
|
309
|
+
// Internal config may have defaults applied - cast to base type
|
|
310
|
+
return config.watch;
|
|
311
|
+
}
|
|
312
|
+
updateCheck(name, updates) {
|
|
313
|
+
const config = this.loadConfig();
|
|
314
|
+
const checkIndex = config.checks.findIndex((c) => c.name === name);
|
|
315
|
+
if (checkIndex >= 0) {
|
|
316
|
+
config.checks[checkIndex] = { ...config.checks[checkIndex], ...updates };
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
config.checks.push({
|
|
320
|
+
name,
|
|
321
|
+
description: updates.description || '',
|
|
322
|
+
enabled: updates.enabled !== false,
|
|
323
|
+
config: updates.config || {},
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
this.saveConfig(config);
|
|
327
|
+
}
|
|
328
|
+
enableCheck(name) {
|
|
329
|
+
this.updateCheck(name, { enabled: true });
|
|
330
|
+
}
|
|
331
|
+
disableCheck(name) {
|
|
332
|
+
this.updateCheck(name, { enabled: false });
|
|
333
|
+
}
|
|
334
|
+
}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { Check } from './check.interface.js';
|
|
2
|
+
import { GateConfig, GateResult, GateRunResult, PlanData } from '../types/gate.types.js';
|
|
3
|
+
import { type ProvenanceRecord } from '@eddacraft/anvil-core';
|
|
4
|
+
import type { CacheProvider } from '../cache/types.js';
|
|
5
|
+
import type { Warning, WarningResult } from '@eddacraft/anvil-core/antipattern';
|
|
6
|
+
import { type SuppressionStats, SuppressionStore } from '@eddacraft/anvil-core/suppression';
|
|
7
|
+
/**
|
|
8
|
+
* Progress event types
|
|
9
|
+
*/
|
|
10
|
+
export type ProgressEventType = 'check:start' | 'check:complete' | 'check:error';
|
|
11
|
+
/**
|
|
12
|
+
* Progress event data
|
|
13
|
+
*/
|
|
14
|
+
export interface ProgressEvent {
|
|
15
|
+
type: ProgressEventType;
|
|
16
|
+
checkName: string;
|
|
17
|
+
/** Current check index (1-based) */
|
|
18
|
+
current: number;
|
|
19
|
+
/** Total number of checks to run */
|
|
20
|
+
total: number;
|
|
21
|
+
/** Result (only for check:complete and check:error) */
|
|
22
|
+
result?: GateResult;
|
|
23
|
+
/** Whether result was from cache */
|
|
24
|
+
cached?: boolean;
|
|
25
|
+
/** Execution time in ms */
|
|
26
|
+
executionTimeMs?: number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Progress callback function
|
|
30
|
+
*/
|
|
31
|
+
export type ProgressCallback = (event: ProgressEvent) => void;
|
|
32
|
+
/**
|
|
33
|
+
* Provenance recording options — controls whether gate execution
|
|
34
|
+
* creates a persistent provenance record in the .anvil directory
|
|
35
|
+
*/
|
|
36
|
+
export interface ProvenanceOptions {
|
|
37
|
+
/** Enable provenance recording (default: false) */
|
|
38
|
+
enabled: boolean;
|
|
39
|
+
/** What triggered this gate run */
|
|
40
|
+
trigger: 'manual' | 'pre-commit' | 'ci' | 'watch' | 'api';
|
|
41
|
+
/** Scope of the check */
|
|
42
|
+
scope: 'directory' | 'staged' | 'files' | 'plan';
|
|
43
|
+
/** Files being checked (for the provenance record) */
|
|
44
|
+
filesChecked?: string[];
|
|
45
|
+
/** Associated plan ID if plan-driven */
|
|
46
|
+
planId?: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Options for running gates
|
|
50
|
+
*/
|
|
51
|
+
export interface GateRunOptions {
|
|
52
|
+
/** Checks to skip */
|
|
53
|
+
skipChecks?: string[];
|
|
54
|
+
/** Only run these checks */
|
|
55
|
+
onlyChecks?: string[];
|
|
56
|
+
/** Stop on first failure */
|
|
57
|
+
failFast?: boolean;
|
|
58
|
+
/** Cache provider (defaults to NullCacheProvider) */
|
|
59
|
+
cache?: CacheProvider;
|
|
60
|
+
/** Maximum parallel checks (0 = sequential, undefined = all parallel) */
|
|
61
|
+
parallelLimit?: number;
|
|
62
|
+
/** Force bypass cache for this run */
|
|
63
|
+
noCache?: boolean;
|
|
64
|
+
/** Progress callback for real-time updates */
|
|
65
|
+
onProgress?: ProgressCallback;
|
|
66
|
+
/** Full codebase scan mode (no plan-based scoping) */
|
|
67
|
+
fullScan?: boolean;
|
|
68
|
+
/** Provenance recording options */
|
|
69
|
+
provenance?: ProvenanceOptions;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Extended gate result with cache metadata
|
|
73
|
+
*/
|
|
74
|
+
export interface GateRunResultWithCache extends GateRunResult {
|
|
75
|
+
/** Cache statistics for this run */
|
|
76
|
+
cacheStats?: {
|
|
77
|
+
/** Number of cache hits */
|
|
78
|
+
hits: number;
|
|
79
|
+
/** Number of cache misses */
|
|
80
|
+
misses: number;
|
|
81
|
+
/** Estimated time saved by cache hits (ms) */
|
|
82
|
+
timeSavedMs: number;
|
|
83
|
+
};
|
|
84
|
+
/** Execution timing */
|
|
85
|
+
timing?: {
|
|
86
|
+
/** Total execution time (ms) */
|
|
87
|
+
totalMs: number;
|
|
88
|
+
/** Per-check timing */
|
|
89
|
+
checks: Record<string, number>;
|
|
90
|
+
};
|
|
91
|
+
/** Provenance record ID (present when provenance recording is enabled) */
|
|
92
|
+
provenance_id?: string;
|
|
93
|
+
/** Full provenance record (present when provenance recording is enabled) */
|
|
94
|
+
provenanceRecord?: ProvenanceRecord;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Options for analyzeFiles() - planless file analysis mode
|
|
98
|
+
*/
|
|
99
|
+
export interface AnalyzeOptions {
|
|
100
|
+
/** Cache provider (defaults to NullCacheProvider) */
|
|
101
|
+
cache?: CacheProvider;
|
|
102
|
+
/** Force bypass cache for this run */
|
|
103
|
+
noCache?: boolean;
|
|
104
|
+
/** Which checks to run (defaults to ['architecture', 'antipattern']) */
|
|
105
|
+
checks?: ('architecture' | 'antipattern')[];
|
|
106
|
+
/** Max parallel checks (1 = sequential) */
|
|
107
|
+
parallelLimit?: number;
|
|
108
|
+
/** Check-specific configuration */
|
|
109
|
+
checkConfig?: Record<string, unknown>;
|
|
110
|
+
/** Optional hook for streaming warnings to IDEs or reporters */
|
|
111
|
+
onWarning?: (warning: Warning) => void;
|
|
112
|
+
/** Optional hook invoked when analysis completes */
|
|
113
|
+
onResult?: (result: AnalyzeResult) => void;
|
|
114
|
+
/** Enable suppression checking (default: true) */
|
|
115
|
+
suppressions?: boolean;
|
|
116
|
+
/** Pre-configured suppression store (created internally if not provided) */
|
|
117
|
+
suppressionStore?: SuppressionStore;
|
|
118
|
+
/** Provenance recording options */
|
|
119
|
+
provenance?: ProvenanceOptions;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Result from analyzeFiles() - focused on warnings
|
|
123
|
+
*/
|
|
124
|
+
export interface AnalyzeResult {
|
|
125
|
+
/** Aggregated warnings from all checks */
|
|
126
|
+
warnings: WarningResult;
|
|
127
|
+
/** Execution timing in ms */
|
|
128
|
+
executionTimeMs: number;
|
|
129
|
+
/** Which checks were run */
|
|
130
|
+
checksRun: string[];
|
|
131
|
+
/** Whether any blocking warnings (severity: error, not suppressed) exist */
|
|
132
|
+
hasBlockingWarnings: boolean;
|
|
133
|
+
/** Suppression statistics (only present if suppressions enabled) */
|
|
134
|
+
suppressionStats?: SuppressionStats;
|
|
135
|
+
/** Provenance record ID (present when provenance recording is enabled) */
|
|
136
|
+
provenance_id?: string;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Creates a minimal valid PlanData object for use in planless/full-codebase
|
|
140
|
+
* gate runs where no real plan exists. Avoids unsafe double type-casts.
|
|
141
|
+
*/
|
|
142
|
+
export declare function createEmptyPlan(): PlanData;
|
|
143
|
+
export declare class GateRunner {
|
|
144
|
+
private checks;
|
|
145
|
+
private defaultCache;
|
|
146
|
+
constructor();
|
|
147
|
+
/**
|
|
148
|
+
* Set default cache provider
|
|
149
|
+
*/
|
|
150
|
+
setDefaultCache(cache: CacheProvider): void;
|
|
151
|
+
registerCheck(check: Check): void;
|
|
152
|
+
unregisterCheck(name: string): void;
|
|
153
|
+
getAvailableChecks(): string[];
|
|
154
|
+
analyzeFiles(files: string[], workspaceRoot: string, options?: AnalyzeOptions): Promise<AnalyzeResult>;
|
|
155
|
+
runGate(plan: PlanData, config: GateConfig, workspaceRoot: string, options?: GateRunOptions): Promise<GateRunResultWithCache>;
|
|
156
|
+
private executeChecks;
|
|
157
|
+
private runCheckWithCache;
|
|
158
|
+
private registerDefaultChecks;
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=gate-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate-runner.d.ts","sourceRoot":"","sources":["../../src/gate/gate-runner.ts"],"names":[],"mappings":"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"}
|