@eddacraft/anvil-core 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/antipattern/index.d.ts +11 -0
- package/dist/antipattern/index.d.ts.map +1 -0
- package/dist/antipattern/index.js +31 -0
- package/dist/antipattern/patterns-css.d.ts +17 -0
- package/dist/antipattern/patterns-css.d.ts.map +1 -0
- package/dist/antipattern/patterns-css.js +72 -0
- package/dist/antipattern/patterns-html.d.ts +21 -0
- package/dist/antipattern/patterns-html.d.ts.map +1 -0
- package/dist/antipattern/patterns-html.js +139 -0
- package/dist/antipattern/patterns.d.ts +72 -0
- package/dist/antipattern/patterns.d.ts.map +1 -0
- package/dist/antipattern/patterns.js +301 -0
- package/dist/antipattern/scanner.d.ts +32 -0
- package/dist/antipattern/scanner.d.ts.map +1 -0
- package/dist/antipattern/scanner.js +89 -0
- package/dist/antipattern/types.d.ts +318 -0
- package/dist/antipattern/types.d.ts.map +1 -0
- package/dist/antipattern/types.js +278 -0
- package/dist/architecture/analyzer.d.ts +123 -0
- package/dist/architecture/analyzer.d.ts.map +1 -0
- package/dist/architecture/analyzer.js +321 -0
- package/dist/architecture/baseline.d.ts +112 -0
- package/dist/architecture/baseline.d.ts.map +1 -0
- package/dist/architecture/baseline.js +245 -0
- package/dist/architecture/compiler.d.ts +24 -0
- package/dist/architecture/compiler.d.ts.map +1 -0
- package/dist/architecture/compiler.js +57 -0
- package/dist/architecture/context.d.ts +129 -0
- package/dist/architecture/context.d.ts.map +1 -0
- package/dist/architecture/context.js +116 -0
- package/dist/architecture/dc-generator.d.ts +9 -0
- package/dist/architecture/dc-generator.d.ts.map +1 -0
- package/dist/architecture/dc-generator.js +220 -0
- package/dist/architecture/definition-schema.d.ts +128 -0
- package/dist/architecture/definition-schema.d.ts.map +1 -0
- package/dist/architecture/definition-schema.js +94 -0
- package/dist/architecture/edge-detector-html.d.ts +6 -0
- package/dist/architecture/edge-detector-html.d.ts.map +1 -0
- package/dist/architecture/edge-detector-html.js +5 -0
- package/dist/architecture/edge-detector-web.d.ts +32 -0
- package/dist/architecture/edge-detector-web.d.ts.map +1 -0
- package/dist/architecture/edge-detector-web.js +133 -0
- package/dist/architecture/edge-detector.d.ts +116 -0
- package/dist/architecture/edge-detector.d.ts.map +1 -0
- package/dist/architecture/edge-detector.js +229 -0
- package/dist/architecture/entry-detector.d.ts +44 -0
- package/dist/architecture/entry-detector.d.ts.map +1 -0
- package/dist/architecture/entry-detector.js +263 -0
- package/dist/architecture/index.d.ts +21 -0
- package/dist/architecture/index.d.ts.map +1 -0
- package/dist/architecture/index.js +48 -0
- package/dist/architecture/layer-detector.d.ts +60 -0
- package/dist/architecture/layer-detector.d.ts.map +1 -0
- package/dist/architecture/layer-detector.js +331 -0
- package/dist/architecture/rego-generator.d.ts +25 -0
- package/dist/architecture/rego-generator.d.ts.map +1 -0
- package/dist/architecture/rego-generator.js +229 -0
- package/dist/architecture/templates/index.d.ts +39 -0
- package/dist/architecture/templates/index.d.ts.map +1 -0
- package/dist/architecture/templates/index.js +124 -0
- package/dist/architecture/types.d.ts +280 -0
- package/dist/architecture/types.d.ts.map +1 -0
- package/dist/architecture/types.js +269 -0
- package/dist/architecture/yaml-parser.d.ts +13 -0
- package/dist/architecture/yaml-parser.d.ts.map +1 -0
- package/dist/architecture/yaml-parser.js +234 -0
- package/dist/config/constants.d.ts +9 -0
- package/dist/config/constants.d.ts.map +1 -0
- package/dist/config/constants.js +20 -0
- package/dist/config/index.d.ts +9 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +8 -0
- package/dist/config/loader.d.ts +41 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +76 -0
- package/dist/config/nudge-config.d.ts +35 -0
- package/dist/config/nudge-config.d.ts.map +1 -0
- package/dist/config/nudge-config.js +34 -0
- package/dist/config/types.d.ts +30 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +4 -0
- package/dist/contracts/index.d.ts +14 -0
- package/dist/contracts/index.d.ts.map +1 -0
- package/dist/contracts/index.js +13 -0
- package/dist/contracts/schemas/aps.schema.d.ts +269 -0
- package/dist/contracts/schemas/aps.schema.d.ts.map +1 -0
- package/dist/contracts/schemas/aps.schema.js +183 -0
- package/dist/contracts/schemas/index.d.ts +12 -0
- package/dist/contracts/schemas/index.d.ts.map +1 -0
- package/dist/contracts/schemas/index.js +14 -0
- package/dist/contracts/schemas/json-schema.d.ts +14 -0
- package/dist/contracts/schemas/json-schema.d.ts.map +1 -0
- package/dist/contracts/schemas/json-schema.js +31 -0
- package/dist/contracts/schemas/warning.schema.d.ts +171 -0
- package/dist/contracts/schemas/warning.schema.d.ts.map +1 -0
- package/dist/contracts/schemas/warning.schema.js +123 -0
- package/dist/contracts/types/gate.types.d.ts +194 -0
- package/dist/contracts/types/gate.types.d.ts.map +1 -0
- package/dist/contracts/types/gate.types.js +19 -0
- package/dist/contracts/types/index.d.ts +9 -0
- package/dist/contracts/types/index.d.ts.map +1 -0
- package/dist/contracts/types/index.js +8 -0
- package/dist/crypto/hash.d.ts +47 -0
- package/dist/crypto/hash.d.ts.map +1 -0
- package/dist/crypto/hash.js +110 -0
- package/dist/crypto/index.d.ts +7 -0
- package/dist/crypto/index.d.ts.map +1 -0
- package/dist/crypto/index.js +6 -0
- package/dist/drift/index.d.ts +6 -0
- package/dist/drift/index.d.ts.map +1 -0
- package/dist/drift/index.js +5 -0
- package/dist/drift/report-generator.d.ts +21 -0
- package/dist/drift/report-generator.d.ts.map +1 -0
- package/dist/drift/report-generator.js +240 -0
- package/dist/drift/snapshot-capture.d.ts +26 -0
- package/dist/drift/snapshot-capture.d.ts.map +1 -0
- package/dist/drift/snapshot-capture.js +195 -0
- package/dist/drift/snapshot-compare.d.ts +50 -0
- package/dist/drift/snapshot-compare.d.ts.map +1 -0
- package/dist/drift/snapshot-compare.js +142 -0
- package/dist/drift/snapshot-schema.d.ts +197 -0
- package/dist/drift/snapshot-schema.d.ts.map +1 -0
- package/dist/drift/snapshot-schema.js +193 -0
- package/dist/drift/snapshot-storage.d.ts +25 -0
- package/dist/drift/snapshot-storage.d.ts.map +1 -0
- package/dist/drift/snapshot-storage.js +179 -0
- package/dist/explain/antipattern-explainer.d.ts +4 -0
- package/dist/explain/antipattern-explainer.d.ts.map +1 -0
- package/dist/explain/antipattern-explainer.js +196 -0
- package/dist/explain/boundary-explainer.d.ts +5 -0
- package/dist/explain/boundary-explainer.d.ts.map +1 -0
- package/dist/explain/boundary-explainer.js +261 -0
- package/dist/explain/explain-service.d.ts +19 -0
- package/dist/explain/explain-service.d.ts.map +1 -0
- package/dist/explain/explain-service.js +106 -0
- package/dist/explain/index.d.ts +7 -0
- package/dist/explain/index.d.ts.map +1 -0
- package/dist/explain/index.js +5 -0
- package/dist/explain/template-loader.d.ts +9 -0
- package/dist/explain/template-loader.d.ts.map +1 -0
- package/dist/explain/template-loader.js +51 -0
- package/dist/explain/types.d.ts +46 -0
- package/dist/explain/types.d.ts.map +1 -0
- package/dist/explain/types.js +31 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +37 -0
- package/dist/provenance/collector.d.ts +86 -0
- package/dist/provenance/collector.d.ts.map +1 -0
- package/dist/provenance/collector.js +425 -0
- package/dist/provenance/git-ai-standard/git-notes.d.ts +85 -0
- package/dist/provenance/git-ai-standard/git-notes.d.ts.map +1 -0
- package/dist/provenance/git-ai-standard/git-notes.js +292 -0
- package/dist/provenance/git-ai-standard/index.d.ts +44 -0
- package/dist/provenance/git-ai-standard/index.d.ts.map +1 -0
- package/dist/provenance/git-ai-standard/index.js +47 -0
- package/dist/provenance/git-ai-standard/serializer.d.ts +54 -0
- package/dist/provenance/git-ai-standard/serializer.d.ts.map +1 -0
- package/dist/provenance/git-ai-standard/serializer.js +224 -0
- package/dist/provenance/git-ai-standard/session.d.ts +51 -0
- package/dist/provenance/git-ai-standard/session.d.ts.map +1 -0
- package/dist/provenance/git-ai-standard/session.js +118 -0
- package/dist/provenance/git-ai-standard/types.d.ts +173 -0
- package/dist/provenance/git-ai-standard/types.d.ts.map +1 -0
- package/dist/provenance/git-ai-standard/types.js +109 -0
- package/dist/provenance/index.d.ts +5 -0
- package/dist/provenance/index.d.ts.map +1 -0
- package/dist/provenance/index.js +6 -0
- package/dist/provenance/store.d.ts +83 -0
- package/dist/provenance/store.d.ts.map +1 -0
- package/dist/provenance/store.js +248 -0
- package/dist/provenance/types.d.ts +160 -0
- package/dist/provenance/types.d.ts.map +1 -0
- package/dist/provenance/types.js +112 -0
- package/dist/suppression/index.d.ts +4 -0
- package/dist/suppression/index.d.ts.map +1 -0
- package/dist/suppression/index.js +3 -0
- package/dist/suppression/parser.d.ts +31 -0
- package/dist/suppression/parser.d.ts.map +1 -0
- package/dist/suppression/parser.js +219 -0
- package/dist/suppression/service.d.ts +29 -0
- package/dist/suppression/service.d.ts.map +1 -0
- package/dist/suppression/service.js +132 -0
- package/dist/suppression/store.d.ts +61 -0
- package/dist/suppression/store.d.ts.map +1 -0
- package/dist/suppression/store.js +169 -0
- package/dist/utils/debug.d.ts +48 -0
- package/dist/utils/debug.d.ts.map +1 -0
- package/dist/utils/debug.js +100 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +3 -0
- package/dist/utils/path-safety.d.ts +21 -0
- package/dist/utils/path-safety.d.ts.map +1 -0
- package/dist/utils/path-safety.js +49 -0
- package/dist/utils/severity.d.ts +37 -0
- package/dist/utils/severity.d.ts.map +1 -0
- package/dist/utils/severity.js +22 -0
- package/dist/validation/aps-validator.d.ts +66 -0
- package/dist/validation/aps-validator.d.ts.map +1 -0
- package/dist/validation/aps-validator.js +173 -0
- package/dist/validation/errors.d.ts +52 -0
- package/dist/validation/errors.d.ts.map +1 -0
- package/dist/validation/errors.js +115 -0
- package/dist/validation/index.d.ts +8 -0
- package/dist/validation/index.d.ts.map +1 -0
- package/dist/validation/index.js +13 -0
- package/dist/warnings/index.d.ts +2 -0
- package/dist/warnings/index.d.ts.map +1 -0
- package/dist/warnings/index.js +1 -0
- package/dist/warnings/warning-id.d.ts +180 -0
- package/dist/warnings/warning-id.d.ts.map +1 -0
- package/dist/warnings/warning-id.js +257 -0
- package/package.json +79 -0
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { ProvenanceRecordSchema, ProvenanceIndexSchema } from './types.js';
|
|
4
|
+
import { createDebugger } from '../utils/debug.js';
|
|
5
|
+
import { sanitizeIdentifier } from '../utils/path-safety.js';
|
|
6
|
+
const debug = createDebugger('provenance');
|
|
7
|
+
const PROVENANCE_DIR = '.anvil';
|
|
8
|
+
const HISTORY_DIR = 'history';
|
|
9
|
+
const INDEX_FILE = 'index.json';
|
|
10
|
+
const MAX_RECORDS = 1000; // Maximum records to keep in history
|
|
11
|
+
/**
|
|
12
|
+
* ProvenanceStore - manages provenance records on disk
|
|
13
|
+
*/
|
|
14
|
+
export class ProvenanceStore {
|
|
15
|
+
baseDir;
|
|
16
|
+
historyDir;
|
|
17
|
+
indexPath;
|
|
18
|
+
constructor(workspaceRoot) {
|
|
19
|
+
this.baseDir = join(workspaceRoot, PROVENANCE_DIR);
|
|
20
|
+
this.historyDir = join(this.baseDir, HISTORY_DIR);
|
|
21
|
+
this.indexPath = join(this.historyDir, INDEX_FILE);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Ensures the provenance directories exist
|
|
25
|
+
*/
|
|
26
|
+
ensureDirectories() {
|
|
27
|
+
if (!existsSync(this.baseDir)) {
|
|
28
|
+
mkdirSync(this.baseDir, { recursive: true });
|
|
29
|
+
}
|
|
30
|
+
if (!existsSync(this.historyDir)) {
|
|
31
|
+
mkdirSync(this.historyDir, { recursive: true });
|
|
32
|
+
}
|
|
33
|
+
// Create .gitignore in .anvil if it doesn't exist
|
|
34
|
+
const gitignorePath = join(this.baseDir, '.gitignore');
|
|
35
|
+
if (!existsSync(gitignorePath)) {
|
|
36
|
+
writeFileSync(gitignorePath, `# Anvil local data
|
|
37
|
+
history/
|
|
38
|
+
*.local.json
|
|
39
|
+
`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Loads the provenance index
|
|
44
|
+
*/
|
|
45
|
+
createEmptyIndex() {
|
|
46
|
+
return {
|
|
47
|
+
version: 1,
|
|
48
|
+
last_updated: new Date().toISOString(),
|
|
49
|
+
records: [],
|
|
50
|
+
statistics: {
|
|
51
|
+
total_checks: 0,
|
|
52
|
+
total_passed: 0,
|
|
53
|
+
total_failed: 0,
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
loadIndex() {
|
|
58
|
+
if (!existsSync(this.indexPath)) {
|
|
59
|
+
return this.createEmptyIndex();
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
const content = readFileSync(this.indexPath, 'utf-8');
|
|
63
|
+
const parsed = JSON.parse(content);
|
|
64
|
+
const result = ProvenanceIndexSchema.safeParse(parsed);
|
|
65
|
+
if (!result.success) {
|
|
66
|
+
debug('Index validation failed, starting fresh', result.error);
|
|
67
|
+
return this.createEmptyIndex();
|
|
68
|
+
}
|
|
69
|
+
return result.data;
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
debug('Failed to load provenance index', error);
|
|
73
|
+
return this.createEmptyIndex();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Saves the provenance index
|
|
78
|
+
*/
|
|
79
|
+
saveIndex(index) {
|
|
80
|
+
this.ensureDirectories();
|
|
81
|
+
index.last_updated = new Date().toISOString();
|
|
82
|
+
writeFileSync(this.indexPath, JSON.stringify(index, null, 2));
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Saves a provenance record
|
|
86
|
+
*/
|
|
87
|
+
save(record) {
|
|
88
|
+
this.ensureDirectories();
|
|
89
|
+
// Save the full record
|
|
90
|
+
const safeId = sanitizeIdentifier(record.id);
|
|
91
|
+
const recordPath = join(this.historyDir, `${safeId}.json`);
|
|
92
|
+
writeFileSync(recordPath, JSON.stringify(record, null, 2));
|
|
93
|
+
// Update the index
|
|
94
|
+
const index = this.loadIndex();
|
|
95
|
+
// Add to records (prepend for most recent first)
|
|
96
|
+
index.records.unshift({
|
|
97
|
+
id: record.id,
|
|
98
|
+
timestamp: record.timestamp,
|
|
99
|
+
passed: record.overall_passed,
|
|
100
|
+
scope: record.scope,
|
|
101
|
+
files_count: record.files_count,
|
|
102
|
+
commit: record.git?.commit?.substring(0, 8),
|
|
103
|
+
});
|
|
104
|
+
if (index.records.length > MAX_RECORDS) {
|
|
105
|
+
index.records.splice(MAX_RECORDS);
|
|
106
|
+
}
|
|
107
|
+
// Update statistics
|
|
108
|
+
index.statistics.total_checks++;
|
|
109
|
+
if (record.overall_passed) {
|
|
110
|
+
index.statistics.total_passed++;
|
|
111
|
+
index.statistics.last_pass = record.timestamp;
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
index.statistics.total_failed++;
|
|
115
|
+
index.statistics.last_fail = record.timestamp;
|
|
116
|
+
}
|
|
117
|
+
this.saveIndex(index);
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Gets a specific provenance record by ID
|
|
121
|
+
*/
|
|
122
|
+
get(id) {
|
|
123
|
+
const safeId = sanitizeIdentifier(id);
|
|
124
|
+
const recordPath = join(this.historyDir, `${safeId}.json`);
|
|
125
|
+
if (!existsSync(recordPath)) {
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
try {
|
|
129
|
+
const content = readFileSync(recordPath, 'utf-8');
|
|
130
|
+
const parsed = JSON.parse(content);
|
|
131
|
+
const result = ProvenanceRecordSchema.safeParse(parsed);
|
|
132
|
+
if (!result.success) {
|
|
133
|
+
debug(`Record ${id} validation failed`, result.error);
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
return result.data;
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
debug(`Failed to load provenance record ${id}`, error);
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Gets the most recent provenance record
|
|
145
|
+
*/
|
|
146
|
+
getLatest() {
|
|
147
|
+
const index = this.loadIndex();
|
|
148
|
+
if (index.records.length === 0) {
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
return this.get(index.records[0].id);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Gets the provenance index with statistics
|
|
155
|
+
*/
|
|
156
|
+
getIndex() {
|
|
157
|
+
return this.loadIndex();
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Lists recent provenance records
|
|
161
|
+
*/
|
|
162
|
+
list(options) {
|
|
163
|
+
const index = this.loadIndex();
|
|
164
|
+
let records = index.records;
|
|
165
|
+
// Filter by passed/failed
|
|
166
|
+
if (options?.passed !== undefined) {
|
|
167
|
+
records = records.filter((r) => r.passed === options.passed);
|
|
168
|
+
}
|
|
169
|
+
// Filter by date
|
|
170
|
+
if (options?.since) {
|
|
171
|
+
const sinceTime = options.since.getTime();
|
|
172
|
+
records = records.filter((r) => new Date(r.timestamp).getTime() >= sinceTime);
|
|
173
|
+
}
|
|
174
|
+
// Apply limit
|
|
175
|
+
const limit = options?.limit || 10;
|
|
176
|
+
records = records.slice(0, limit);
|
|
177
|
+
// Load full records
|
|
178
|
+
return records.map((r) => this.get(r.id)).filter((r) => r !== null);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Finds records by git commit
|
|
182
|
+
*/
|
|
183
|
+
findByCommit(commitPrefix) {
|
|
184
|
+
const index = this.loadIndex();
|
|
185
|
+
const matching = index.records.filter((r) => r.commit?.startsWith(commitPrefix));
|
|
186
|
+
return matching.map((r) => this.get(r.id)).filter((r) => r !== null);
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Gets statistics about provenance history
|
|
190
|
+
*/
|
|
191
|
+
getStatistics() {
|
|
192
|
+
const index = this.loadIndex();
|
|
193
|
+
const stats = index.statistics;
|
|
194
|
+
const lastRecord = index.records[0];
|
|
195
|
+
return {
|
|
196
|
+
total: stats.total_checks,
|
|
197
|
+
passed: stats.total_passed,
|
|
198
|
+
failed: stats.total_failed,
|
|
199
|
+
passRate: stats.total_checks > 0 ? (stats.total_passed / stats.total_checks) * 100 : 0,
|
|
200
|
+
lastCheck: lastRecord?.timestamp || null,
|
|
201
|
+
lastPass: stats.last_pass || null,
|
|
202
|
+
lastFail: stats.last_fail || null,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Exports provenance history as JSON
|
|
207
|
+
*/
|
|
208
|
+
export(options) {
|
|
209
|
+
const records = this.list(options);
|
|
210
|
+
const stats = this.getStatistics();
|
|
211
|
+
return JSON.stringify({
|
|
212
|
+
exported_at: new Date().toISOString(),
|
|
213
|
+
statistics: stats,
|
|
214
|
+
records,
|
|
215
|
+
}, null, 2);
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Clears all provenance history
|
|
219
|
+
*/
|
|
220
|
+
clear() {
|
|
221
|
+
const index = this.loadIndex();
|
|
222
|
+
for (const record of index.records) {
|
|
223
|
+
const safeId = sanitizeIdentifier(record.id);
|
|
224
|
+
const recordPath = join(this.historyDir, `${safeId}.json`);
|
|
225
|
+
try {
|
|
226
|
+
if (existsSync(recordPath)) {
|
|
227
|
+
unlinkSync(recordPath);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
catch (error) {
|
|
231
|
+
debug(`Failed to delete record file ${record.id}`, error);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
this.saveIndex(this.createEmptyIndex());
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Checks if provenance tracking is initialised
|
|
238
|
+
*/
|
|
239
|
+
isInitialised() {
|
|
240
|
+
return existsSync(this.historyDir);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Creates a provenance store for the given workspace
|
|
245
|
+
*/
|
|
246
|
+
export function createProvenanceStore(workspaceRoot) {
|
|
247
|
+
return new ProvenanceStore(workspaceRoot);
|
|
248
|
+
}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* AI Tool detection - what generated this code?
|
|
4
|
+
*/
|
|
5
|
+
export declare const AIToolSchema: z.ZodObject<{
|
|
6
|
+
name: z.ZodEnum<{
|
|
7
|
+
unknown: "unknown";
|
|
8
|
+
manual: "manual";
|
|
9
|
+
cursor: "cursor";
|
|
10
|
+
copilot: "copilot";
|
|
11
|
+
"claude-code": "claude-code";
|
|
12
|
+
chatgpt: "chatgpt";
|
|
13
|
+
codewhisperer: "codewhisperer";
|
|
14
|
+
tabnine: "tabnine";
|
|
15
|
+
}>;
|
|
16
|
+
version: z.ZodOptional<z.ZodString>;
|
|
17
|
+
confidence: z.ZodEnum<{
|
|
18
|
+
high: "high";
|
|
19
|
+
medium: "medium";
|
|
20
|
+
low: "low";
|
|
21
|
+
inferred: "inferred";
|
|
22
|
+
}>;
|
|
23
|
+
indicators: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
24
|
+
}, z.core.$strip>;
|
|
25
|
+
/**
|
|
26
|
+
* Environment context - where was this check run?
|
|
27
|
+
*/
|
|
28
|
+
export declare const EnvironmentSchema: z.ZodObject<{
|
|
29
|
+
os: z.ZodString;
|
|
30
|
+
node_version: z.ZodString;
|
|
31
|
+
anvil_version: z.ZodString;
|
|
32
|
+
cwd: z.ZodString;
|
|
33
|
+
ci: z.ZodBoolean;
|
|
34
|
+
ci_provider: z.ZodOptional<z.ZodString>;
|
|
35
|
+
}, z.core.$strip>;
|
|
36
|
+
/**
|
|
37
|
+
* Git context - what was the repo state?
|
|
38
|
+
*/
|
|
39
|
+
export declare const GitContextSchema: z.ZodObject<{
|
|
40
|
+
repository: z.ZodOptional<z.ZodString>;
|
|
41
|
+
branch: z.ZodOptional<z.ZodString>;
|
|
42
|
+
commit: z.ZodOptional<z.ZodString>;
|
|
43
|
+
commit_message: z.ZodOptional<z.ZodString>;
|
|
44
|
+
author: z.ZodOptional<z.ZodString>;
|
|
45
|
+
dirty: z.ZodBoolean;
|
|
46
|
+
staged_files: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
47
|
+
modified_files: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
48
|
+
}, z.core.$strip>;
|
|
49
|
+
/**
|
|
50
|
+
* Check result summary for provenance
|
|
51
|
+
*/
|
|
52
|
+
export declare const CheckSummarySchema: z.ZodObject<{
|
|
53
|
+
name: z.ZodString;
|
|
54
|
+
passed: z.ZodBoolean;
|
|
55
|
+
score: z.ZodOptional<z.ZodNumber>;
|
|
56
|
+
issues_count: z.ZodOptional<z.ZodNumber>;
|
|
57
|
+
duration_ms: z.ZodOptional<z.ZodNumber>;
|
|
58
|
+
}, z.core.$strip>;
|
|
59
|
+
/**
|
|
60
|
+
* Full provenance record for a check run
|
|
61
|
+
*/
|
|
62
|
+
export declare const ProvenanceRecordSchema: z.ZodObject<{
|
|
63
|
+
id: z.ZodString;
|
|
64
|
+
timestamp: z.ZodString;
|
|
65
|
+
scope: z.ZodEnum<{
|
|
66
|
+
files: "files";
|
|
67
|
+
directory: "directory";
|
|
68
|
+
staged: "staged";
|
|
69
|
+
plan: "plan";
|
|
70
|
+
}>;
|
|
71
|
+
files_checked: z.ZodArray<z.ZodString>;
|
|
72
|
+
files_count: z.ZodNumber;
|
|
73
|
+
overall_passed: z.ZodBoolean;
|
|
74
|
+
overall_score: z.ZodNumber;
|
|
75
|
+
checks: z.ZodArray<z.ZodObject<{
|
|
76
|
+
name: z.ZodString;
|
|
77
|
+
passed: z.ZodBoolean;
|
|
78
|
+
score: z.ZodOptional<z.ZodNumber>;
|
|
79
|
+
issues_count: z.ZodOptional<z.ZodNumber>;
|
|
80
|
+
duration_ms: z.ZodOptional<z.ZodNumber>;
|
|
81
|
+
}, z.core.$strip>>;
|
|
82
|
+
environment: z.ZodObject<{
|
|
83
|
+
os: z.ZodString;
|
|
84
|
+
node_version: z.ZodString;
|
|
85
|
+
anvil_version: z.ZodString;
|
|
86
|
+
cwd: z.ZodString;
|
|
87
|
+
ci: z.ZodBoolean;
|
|
88
|
+
ci_provider: z.ZodOptional<z.ZodString>;
|
|
89
|
+
}, z.core.$strip>;
|
|
90
|
+
git: z.ZodOptional<z.ZodObject<{
|
|
91
|
+
repository: z.ZodOptional<z.ZodString>;
|
|
92
|
+
branch: z.ZodOptional<z.ZodString>;
|
|
93
|
+
commit: z.ZodOptional<z.ZodString>;
|
|
94
|
+
commit_message: z.ZodOptional<z.ZodString>;
|
|
95
|
+
author: z.ZodOptional<z.ZodString>;
|
|
96
|
+
dirty: z.ZodBoolean;
|
|
97
|
+
staged_files: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
98
|
+
modified_files: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
99
|
+
}, z.core.$strip>>;
|
|
100
|
+
ai_tool: z.ZodOptional<z.ZodObject<{
|
|
101
|
+
name: z.ZodEnum<{
|
|
102
|
+
unknown: "unknown";
|
|
103
|
+
manual: "manual";
|
|
104
|
+
cursor: "cursor";
|
|
105
|
+
copilot: "copilot";
|
|
106
|
+
"claude-code": "claude-code";
|
|
107
|
+
chatgpt: "chatgpt";
|
|
108
|
+
codewhisperer: "codewhisperer";
|
|
109
|
+
tabnine: "tabnine";
|
|
110
|
+
}>;
|
|
111
|
+
version: z.ZodOptional<z.ZodString>;
|
|
112
|
+
confidence: z.ZodEnum<{
|
|
113
|
+
high: "high";
|
|
114
|
+
medium: "medium";
|
|
115
|
+
low: "low";
|
|
116
|
+
inferred: "inferred";
|
|
117
|
+
}>;
|
|
118
|
+
indicators: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
119
|
+
}, z.core.$strip>>;
|
|
120
|
+
plan_id: z.ZodOptional<z.ZodString>;
|
|
121
|
+
parent_id: z.ZodOptional<z.ZodString>;
|
|
122
|
+
trigger: z.ZodEnum<{
|
|
123
|
+
api: "api";
|
|
124
|
+
manual: "manual";
|
|
125
|
+
watch: "watch";
|
|
126
|
+
ci: "ci";
|
|
127
|
+
"pre-commit": "pre-commit";
|
|
128
|
+
}>;
|
|
129
|
+
duration_ms: z.ZodNumber;
|
|
130
|
+
user: z.ZodOptional<z.ZodString>;
|
|
131
|
+
}, z.core.$strip>;
|
|
132
|
+
/**
|
|
133
|
+
* Provenance index for quick lookups
|
|
134
|
+
*/
|
|
135
|
+
export declare const ProvenanceIndexSchema: z.ZodObject<{
|
|
136
|
+
version: z.ZodNumber;
|
|
137
|
+
last_updated: z.ZodString;
|
|
138
|
+
records: z.ZodArray<z.ZodObject<{
|
|
139
|
+
id: z.ZodString;
|
|
140
|
+
timestamp: z.ZodString;
|
|
141
|
+
passed: z.ZodBoolean;
|
|
142
|
+
scope: z.ZodString;
|
|
143
|
+
files_count: z.ZodNumber;
|
|
144
|
+
commit: z.ZodOptional<z.ZodString>;
|
|
145
|
+
}, z.core.$strip>>;
|
|
146
|
+
statistics: z.ZodObject<{
|
|
147
|
+
total_checks: z.ZodNumber;
|
|
148
|
+
total_passed: z.ZodNumber;
|
|
149
|
+
total_failed: z.ZodNumber;
|
|
150
|
+
last_pass: z.ZodOptional<z.ZodString>;
|
|
151
|
+
last_fail: z.ZodOptional<z.ZodString>;
|
|
152
|
+
}, z.core.$strip>;
|
|
153
|
+
}, z.core.$strip>;
|
|
154
|
+
export type AITool = z.infer<typeof AIToolSchema>;
|
|
155
|
+
export type Environment = z.infer<typeof EnvironmentSchema>;
|
|
156
|
+
export type GitContext = z.infer<typeof GitContextSchema>;
|
|
157
|
+
export type CheckSummary = z.infer<typeof CheckSummarySchema>;
|
|
158
|
+
export type ProvenanceRecord = z.infer<typeof ProvenanceRecordSchema>;
|
|
159
|
+
export type ProvenanceIndex = z.infer<typeof ProvenanceIndexSchema>;
|
|
160
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/provenance/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;GAEG;AACH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;iBAkBvB,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,iBAAiB;;;;;;;iBAO5B,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;iBAS3B,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,kBAAkB;;;;;;iBAM7B,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA8BjC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;iBAwBhC,CAAC;AAGH,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAClD,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC5D,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC1D,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAC9D,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AACtE,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* AI Tool detection - what generated this code?
|
|
4
|
+
*/
|
|
5
|
+
export const AIToolSchema = z.object({
|
|
6
|
+
name: z
|
|
7
|
+
.enum([
|
|
8
|
+
'cursor',
|
|
9
|
+
'copilot',
|
|
10
|
+
'claude-code',
|
|
11
|
+
'chatgpt',
|
|
12
|
+
'codewhisperer',
|
|
13
|
+
'tabnine',
|
|
14
|
+
'unknown',
|
|
15
|
+
'manual',
|
|
16
|
+
])
|
|
17
|
+
.describe('Detected AI coding tool'),
|
|
18
|
+
version: z.string().optional().describe('Version of the AI tool if detectable'),
|
|
19
|
+
confidence: z
|
|
20
|
+
.enum(['high', 'medium', 'low', 'inferred'])
|
|
21
|
+
.describe('Confidence level of detection'),
|
|
22
|
+
indicators: z.array(z.string()).optional().describe('What indicated this tool was used'),
|
|
23
|
+
});
|
|
24
|
+
/**
|
|
25
|
+
* Environment context - where was this check run?
|
|
26
|
+
*/
|
|
27
|
+
export const EnvironmentSchema = z.object({
|
|
28
|
+
os: z.string().describe('Operating system'),
|
|
29
|
+
node_version: z.string().describe('Node.js version'),
|
|
30
|
+
anvil_version: z.string().describe('Anvil CLI version'),
|
|
31
|
+
cwd: z.string().describe('Current working directory'),
|
|
32
|
+
ci: z.boolean().describe('Whether running in CI environment'),
|
|
33
|
+
ci_provider: z.string().optional().describe('CI provider name if detected'),
|
|
34
|
+
});
|
|
35
|
+
/**
|
|
36
|
+
* Git context - what was the repo state?
|
|
37
|
+
*/
|
|
38
|
+
export const GitContextSchema = z.object({
|
|
39
|
+
repository: z.string().optional().describe('Repository URL or name'),
|
|
40
|
+
branch: z.string().optional().describe('Current branch'),
|
|
41
|
+
commit: z.string().optional().describe('Current commit SHA'),
|
|
42
|
+
commit_message: z.string().optional().describe('Current commit message'),
|
|
43
|
+
author: z.string().optional().describe('Commit author'),
|
|
44
|
+
dirty: z.boolean().describe('Whether there are uncommitted changes'),
|
|
45
|
+
staged_files: z.array(z.string()).optional().describe('Files staged for commit'),
|
|
46
|
+
modified_files: z.array(z.string()).optional().describe('Modified files'),
|
|
47
|
+
});
|
|
48
|
+
/**
|
|
49
|
+
* Check result summary for provenance
|
|
50
|
+
*/
|
|
51
|
+
export const CheckSummarySchema = z.object({
|
|
52
|
+
name: z.string().describe('Check name'),
|
|
53
|
+
passed: z.boolean().describe('Whether the check passed'),
|
|
54
|
+
score: z.number().optional().describe('Score if applicable'),
|
|
55
|
+
issues_count: z.number().optional().describe('Number of issues found'),
|
|
56
|
+
duration_ms: z.number().optional().describe('How long the check took'),
|
|
57
|
+
});
|
|
58
|
+
/**
|
|
59
|
+
* Full provenance record for a check run
|
|
60
|
+
*/
|
|
61
|
+
export const ProvenanceRecordSchema = z.object({
|
|
62
|
+
// Identification
|
|
63
|
+
id: z.string().describe('Unique provenance record ID'),
|
|
64
|
+
timestamp: z.string().datetime().describe('When the check was run'),
|
|
65
|
+
// What was checked
|
|
66
|
+
scope: z.enum(['directory', 'staged', 'files', 'plan']).describe('What scope was checked'),
|
|
67
|
+
files_checked: z.array(z.string()).describe('List of files that were checked'),
|
|
68
|
+
files_count: z.number().describe('Total number of files checked'),
|
|
69
|
+
// Results
|
|
70
|
+
overall_passed: z.boolean().describe('Whether all checks passed'),
|
|
71
|
+
overall_score: z.number().describe('Overall score (0-100)'),
|
|
72
|
+
checks: z.array(CheckSummarySchema).describe('Summary of each check'),
|
|
73
|
+
// Context
|
|
74
|
+
environment: EnvironmentSchema.describe('Environment information'),
|
|
75
|
+
git: GitContextSchema.optional().describe('Git repository context'),
|
|
76
|
+
ai_tool: AIToolSchema.optional().describe('Detected AI tool'),
|
|
77
|
+
// Linking
|
|
78
|
+
plan_id: z.string().optional().describe('Associated plan ID if applicable'),
|
|
79
|
+
parent_id: z.string().optional().describe('Previous provenance record ID'),
|
|
80
|
+
// Metadata
|
|
81
|
+
trigger: z
|
|
82
|
+
.enum(['manual', 'pre-commit', 'ci', 'watch', 'api'])
|
|
83
|
+
.describe('What triggered this check'),
|
|
84
|
+
duration_ms: z.number().describe('Total duration of the check run'),
|
|
85
|
+
user: z.string().optional().describe('User who ran the check'),
|
|
86
|
+
});
|
|
87
|
+
/**
|
|
88
|
+
* Provenance index for quick lookups
|
|
89
|
+
*/
|
|
90
|
+
export const ProvenanceIndexSchema = z.object({
|
|
91
|
+
version: z.number().describe('Index format version'),
|
|
92
|
+
last_updated: z.string().datetime().describe('When the index was last updated'),
|
|
93
|
+
records: z
|
|
94
|
+
.array(z.object({
|
|
95
|
+
id: z.string(),
|
|
96
|
+
timestamp: z.string(),
|
|
97
|
+
passed: z.boolean(),
|
|
98
|
+
scope: z.string(),
|
|
99
|
+
files_count: z.number(),
|
|
100
|
+
commit: z.string().optional(),
|
|
101
|
+
}))
|
|
102
|
+
.describe('Summary of all provenance records'),
|
|
103
|
+
statistics: z
|
|
104
|
+
.object({
|
|
105
|
+
total_checks: z.number(),
|
|
106
|
+
total_passed: z.number(),
|
|
107
|
+
total_failed: z.number(),
|
|
108
|
+
last_pass: z.string().optional(),
|
|
109
|
+
last_fail: z.string().optional(),
|
|
110
|
+
})
|
|
111
|
+
.describe('Aggregate statistics'),
|
|
112
|
+
});
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { parseSuppressions, isExpired, suppressionMatches, findMatchingSuppression, ParsedSuppressionSchema, type ParsedSuppression, type SuppressionScope, type SuppressionParseError, type ParseResult, } from './parser.js';
|
|
2
|
+
export { SuppressionStore, SuppressionStoreDataSchema, type SuppressionStoreData, type SuppressionMatch, } from './store.js';
|
|
3
|
+
export { SuppressionService, type SuppressionStats, type FileSuppressions } from './service.js';
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/suppression/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,SAAS,EACT,kBAAkB,EAClB,uBAAuB,EACvB,uBAAuB,EACvB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,WAAW,GACjB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,gBAAgB,EAChB,0BAA0B,EAC1B,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,GACtB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,kBAAkB,EAAE,KAAK,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export type SuppressionScope = 'line' | 'statement' | 'file';
|
|
3
|
+
export declare const ParsedSuppressionSchema: z.ZodObject<{
|
|
4
|
+
warningId: z.ZodString;
|
|
5
|
+
reason: z.ZodString;
|
|
6
|
+
expiresAt: z.ZodOptional<z.ZodDate>;
|
|
7
|
+
line: z.ZodNumber;
|
|
8
|
+
column: z.ZodOptional<z.ZodNumber>;
|
|
9
|
+
scope: z.ZodEnum<{
|
|
10
|
+
file: "file";
|
|
11
|
+
line: "line";
|
|
12
|
+
statement: "statement";
|
|
13
|
+
}>;
|
|
14
|
+
raw: z.ZodString;
|
|
15
|
+
}, z.core.$strip>;
|
|
16
|
+
export type ParsedSuppression = z.infer<typeof ParsedSuppressionSchema>;
|
|
17
|
+
export interface SuppressionParseError {
|
|
18
|
+
line: number;
|
|
19
|
+
column?: number;
|
|
20
|
+
message: string;
|
|
21
|
+
raw: string;
|
|
22
|
+
}
|
|
23
|
+
export interface ParseResult {
|
|
24
|
+
suppressions: ParsedSuppression[];
|
|
25
|
+
errors: SuppressionParseError[];
|
|
26
|
+
}
|
|
27
|
+
export declare function parseSuppressions(content: string, _filePath?: string): ParseResult;
|
|
28
|
+
export declare function isExpired(suppression: ParsedSuppression, now?: Date): boolean;
|
|
29
|
+
export declare function suppressionMatches(suppression: ParsedSuppression, warningId: string, warningLine: number): boolean;
|
|
30
|
+
export declare function findMatchingSuppression(suppressions: ParsedSuppression[], warningId: string, warningLine: number, now?: Date): ParsedSuppression | null;
|
|
31
|
+
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/suppression/parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;AAE7D,eAAO,MAAM,uBAAuB;;;;;;;;;;;;iBAWlC,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,iBAAiB,EAAE,CAAC;IAClC,MAAM,EAAE,qBAAqB,EAAE,CAAC;CACjC;AAkKD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,WAAW,CA8ClF;AAED,wBAAgB,SAAS,CAAC,WAAW,EAAE,iBAAiB,EAAE,GAAG,GAAE,IAAiB,GAAG,OAAO,CAKzF;AAED,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,iBAAiB,EAC9B,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAClB,OAAO,CAkBT;AAED,wBAAgB,uBAAuB,CACrC,YAAY,EAAE,iBAAiB,EAAE,EACjC,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,GAAG,GAAE,IAAiB,GACrB,iBAAiB,GAAG,IAAI,CAY1B"}
|