@vibecheckai/cli 3.7.0 → 3.9.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/README.md +135 -63
- package/bin/_deprecations.js +447 -19
- package/bin/_router.js +1 -1
- package/bin/registry.js +347 -280
- package/bin/runners/context/generators/cursor-enhanced.js +2439 -0
- package/bin/runners/lib/agent-firewall/enforcement/gateway.js +1059 -0
- package/bin/runners/lib/agent-firewall/enforcement/index.js +98 -0
- package/bin/runners/lib/agent-firewall/enforcement/mode.js +318 -0
- package/bin/runners/lib/agent-firewall/enforcement/orchestrator.js +484 -0
- package/bin/runners/lib/agent-firewall/enforcement/proof-artifact.js +418 -0
- package/bin/runners/lib/agent-firewall/enforcement/schemas/change-event.schema.json +173 -0
- package/bin/runners/lib/agent-firewall/enforcement/schemas/intent.schema.json +181 -0
- package/bin/runners/lib/agent-firewall/enforcement/schemas/verdict.schema.json +222 -0
- package/bin/runners/lib/agent-firewall/enforcement/verdict-v2.js +333 -0
- package/bin/runners/lib/agent-firewall/index.js +200 -0
- package/bin/runners/lib/agent-firewall/integration/index.js +20 -0
- package/bin/runners/lib/agent-firewall/integration/ship-gate.js +437 -0
- package/bin/runners/lib/agent-firewall/intent/alignment-engine.js +634 -0
- package/bin/runners/lib/agent-firewall/intent/auto-detect.js +426 -0
- package/bin/runners/lib/agent-firewall/intent/index.js +102 -0
- package/bin/runners/lib/agent-firewall/intent/schema.js +352 -0
- package/bin/runners/lib/agent-firewall/intent/store.js +283 -0
- package/bin/runners/lib/agent-firewall/interception/fs-interceptor.js +502 -0
- package/bin/runners/lib/agent-firewall/interception/index.js +23 -0
- package/bin/runners/lib/agent-firewall/interceptor/base.js +7 -3
- package/bin/runners/lib/agent-firewall/session/collector.js +451 -0
- package/bin/runners/lib/agent-firewall/session/index.js +26 -0
- package/bin/runners/lib/artifact-envelope.js +540 -0
- package/bin/runners/lib/auth-shared.js +977 -0
- package/bin/runners/lib/checkpoint.js +941 -0
- package/bin/runners/lib/cleanup/engine.js +571 -0
- package/bin/runners/lib/cleanup/index.js +53 -0
- package/bin/runners/lib/cleanup/output.js +375 -0
- package/bin/runners/lib/cleanup/rules.js +1060 -0
- package/bin/runners/lib/doctor/diagnosis-receipt.js +454 -0
- package/bin/runners/lib/doctor/failure-signatures.js +526 -0
- package/bin/runners/lib/doctor/fix-script.js +336 -0
- package/bin/runners/lib/doctor/modules/build-tools.js +453 -0
- package/bin/runners/lib/doctor/modules/index.js +62 -3
- package/bin/runners/lib/doctor/modules/os-quirks.js +706 -0
- package/bin/runners/lib/doctor/modules/repo-integrity.js +485 -0
- package/bin/runners/lib/doctor/safe-repair.js +384 -0
- package/bin/runners/lib/engine/ast-cache.js +210 -210
- package/bin/runners/lib/engine/auth-extractor.js +211 -211
- package/bin/runners/lib/engine/billing-extractor.js +112 -112
- package/bin/runners/lib/engine/enforcement-extractor.js +100 -100
- package/bin/runners/lib/engine/env-extractor.js +207 -207
- package/bin/runners/lib/engine/express-extractor.js +208 -208
- package/bin/runners/lib/engine/extractors.js +849 -849
- package/bin/runners/lib/engine/index.js +207 -207
- package/bin/runners/lib/engine/repo-index.js +514 -514
- package/bin/runners/lib/engine/types.js +124 -124
- package/bin/runners/lib/engines/attack-detector.js +1192 -0
- package/bin/runners/lib/entitlements-v2.js +2 -2
- package/bin/runners/lib/missions/briefing.js +427 -0
- package/bin/runners/lib/missions/checkpoint.js +753 -0
- package/bin/runners/lib/missions/hardening.js +851 -0
- package/bin/runners/lib/missions/plan.js +421 -32
- package/bin/runners/lib/missions/safety-gates.js +645 -0
- package/bin/runners/lib/missions/schema.js +478 -0
- package/bin/runners/lib/packs/bundle.js +675 -0
- package/bin/runners/lib/packs/evidence-pack.js +671 -0
- package/bin/runners/lib/packs/pack-factory.js +837 -0
- package/bin/runners/lib/packs/permissions-pack.js +686 -0
- package/bin/runners/lib/packs/proof-graph-pack.js +779 -0
- package/bin/runners/lib/safelist/index.js +96 -0
- package/bin/runners/lib/safelist/integration.js +334 -0
- package/bin/runners/lib/safelist/matcher.js +696 -0
- package/bin/runners/lib/safelist/schema.js +948 -0
- package/bin/runners/lib/safelist/store.js +438 -0
- package/bin/runners/lib/schemas/ship-manifest.schema.json +251 -0
- package/bin/runners/lib/ship-gate.js +832 -0
- package/bin/runners/lib/ship-manifest.js +1153 -0
- package/bin/runners/lib/ship-output.js +1 -1
- package/bin/runners/lib/unified-cli-output.js +710 -383
- package/bin/runners/lib/upsell.js +3 -3
- package/bin/runners/lib/why-tree.js +650 -0
- package/bin/runners/runAllowlist.js +33 -4
- package/bin/runners/runApprove.js +240 -1122
- package/bin/runners/runAudit.js +692 -0
- package/bin/runners/runAuth.js +325 -29
- package/bin/runners/runCheckpoint.js +442 -494
- package/bin/runners/runCleanup.js +343 -0
- package/bin/runners/runDoctor.js +269 -19
- package/bin/runners/runFix.js +411 -32
- package/bin/runners/runForge.js +411 -0
- package/bin/runners/runIntent.js +906 -0
- package/bin/runners/runKickoff.js +878 -0
- package/bin/runners/runLaunch.js +2000 -0
- package/bin/runners/runLink.js +785 -0
- package/bin/runners/runMcp.js +1741 -837
- package/bin/runners/runPacks.js +2089 -0
- package/bin/runners/runPolish.js +41 -0
- package/bin/runners/runReality.js +178 -1
- package/bin/runners/runSafelist.js +1190 -0
- package/bin/runners/runScan.js +21 -9
- package/bin/runners/runShield.js +1282 -0
- package/bin/runners/runShip.js +395 -16
- package/bin/vibecheck.js +34 -6
- package/mcp-server/README.md +117 -158
- package/mcp-server/handlers/index.ts +2 -2
- package/mcp-server/handlers/tool-handler.ts +50 -11
- package/mcp-server/index.js +16 -0
- package/mcp-server/intent-firewall-interceptor.js +529 -0
- package/mcp-server/lib/executor.ts +5 -5
- package/mcp-server/lib/index.ts +14 -4
- package/mcp-server/lib/sandbox.test.ts +4 -4
- package/mcp-server/lib/sandbox.ts +2 -2
- package/mcp-server/manifest.json +473 -0
- package/mcp-server/package.json +1 -1
- package/mcp-server/registry/tool-registry.js +315 -523
- package/mcp-server/registry/tools.json +442 -428
- package/mcp-server/registry.test.ts +18 -12
- package/mcp-server/tier-auth.js +68 -11
- package/mcp-server/tools-v3.js +70 -16
- package/mcp-server/tsconfig.json +1 -0
- package/package.json +2 -1
- package/bin/runners/runProof.zip +0 -0
|
@@ -1,210 +1,210 @@
|
|
|
1
|
-
// bin/runners/lib/engine/ast-cache.js
|
|
2
|
-
// Shared AST cache with content-hash keying
|
|
3
|
-
|
|
4
|
-
const parser = require("@babel/parser");
|
|
5
|
-
const crypto = require("crypto");
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Compute SHA256 hash
|
|
9
|
-
* @param {string} content
|
|
10
|
-
* @returns {string}
|
|
11
|
-
*/
|
|
12
|
-
function sha256(content) {
|
|
13
|
-
return crypto.createHash("sha256").update(content).digest("hex");
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Default Babel parser options for maximum compatibility
|
|
18
|
-
*/
|
|
19
|
-
const DEFAULT_PARSER_OPTIONS = {
|
|
20
|
-
sourceType: "unambiguous",
|
|
21
|
-
errorRecovery: true,
|
|
22
|
-
allowImportExportEverywhere: true,
|
|
23
|
-
plugins: [
|
|
24
|
-
"typescript",
|
|
25
|
-
"jsx",
|
|
26
|
-
"dynamicImport",
|
|
27
|
-
"importMeta",
|
|
28
|
-
"topLevelAwait",
|
|
29
|
-
"classProperties",
|
|
30
|
-
"classPrivateProperties",
|
|
31
|
-
"classPrivateMethods",
|
|
32
|
-
"optionalChaining",
|
|
33
|
-
"nullishCoalescingOperator",
|
|
34
|
-
"decorators-legacy",
|
|
35
|
-
],
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* ASTCache - Content-hash keyed AST cache
|
|
40
|
-
*
|
|
41
|
-
* Usage:
|
|
42
|
-
* const cache = new ASTCache();
|
|
43
|
-
* const ast = cache.parse(content, filePath);
|
|
44
|
-
*
|
|
45
|
-
* // Later, same content will return cached AST
|
|
46
|
-
* const ast2 = cache.parse(content, filePath); // cache hit
|
|
47
|
-
*/
|
|
48
|
-
class ASTCache {
|
|
49
|
-
/**
|
|
50
|
-
* @param {Object} [options]
|
|
51
|
-
* @param {number} [options.maxEntries] - Max cache entries (default: 5000)
|
|
52
|
-
* @param {Object} [options.parserOptions] - Babel parser options override
|
|
53
|
-
*/
|
|
54
|
-
constructor(options = {}) {
|
|
55
|
-
this.maxEntries = options.maxEntries || 5000;
|
|
56
|
-
this.parserOptions = { ...DEFAULT_PARSER_OPTIONS, ...options.parserOptions };
|
|
57
|
-
|
|
58
|
-
/** @type {Map<string, { ast: any, accessCount: number }>} hash -> { ast, accessCount } */
|
|
59
|
-
this._cache = new Map();
|
|
60
|
-
|
|
61
|
-
this.stats = {
|
|
62
|
-
hits: 0,
|
|
63
|
-
misses: 0,
|
|
64
|
-
parseErrors: 0,
|
|
65
|
-
evictions: 0,
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Parse code and cache the AST
|
|
71
|
-
* @param {string} content - Source code
|
|
72
|
-
* @param {string} [filePath] - Optional file path for error messages
|
|
73
|
-
* @returns {{ ast: any, error: Error|null }}
|
|
74
|
-
*/
|
|
75
|
-
parse(content, filePath) {
|
|
76
|
-
const hash = sha256(content);
|
|
77
|
-
|
|
78
|
-
// Check cache
|
|
79
|
-
if (this._cache.has(hash)) {
|
|
80
|
-
const entry = this._cache.get(hash);
|
|
81
|
-
entry.accessCount++;
|
|
82
|
-
this.stats.hits++;
|
|
83
|
-
return { ast: entry.ast, error: null };
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
this.stats.misses++;
|
|
87
|
-
|
|
88
|
-
// Parse
|
|
89
|
-
let ast = null;
|
|
90
|
-
let error = null;
|
|
91
|
-
|
|
92
|
-
try {
|
|
93
|
-
ast = parser.parse(content, {
|
|
94
|
-
...this.parserOptions,
|
|
95
|
-
sourceFilename: filePath || undefined,
|
|
96
|
-
});
|
|
97
|
-
} catch (e) {
|
|
98
|
-
error = e;
|
|
99
|
-
this.stats.parseErrors++;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// Cache if successful
|
|
103
|
-
if (ast) {
|
|
104
|
-
this._cacheEntry(hash, ast);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
return { ast, error };
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Get cached AST by content hash
|
|
112
|
-
* @param {string} hash - Content hash
|
|
113
|
-
* @returns {any|null}
|
|
114
|
-
*/
|
|
115
|
-
getByHash(hash) {
|
|
116
|
-
const entry = this._cache.get(hash);
|
|
117
|
-
if (entry) {
|
|
118
|
-
entry.accessCount++;
|
|
119
|
-
this.stats.hits++;
|
|
120
|
-
return entry.ast;
|
|
121
|
-
}
|
|
122
|
-
return null;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Check if AST is cached
|
|
127
|
-
* @param {string} content
|
|
128
|
-
* @returns {boolean}
|
|
129
|
-
*/
|
|
130
|
-
has(content) {
|
|
131
|
-
return this._cache.has(sha256(content));
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Cache an entry with LRU eviction
|
|
136
|
-
* @param {string} hash
|
|
137
|
-
* @param {any} ast
|
|
138
|
-
*/
|
|
139
|
-
_cacheEntry(hash, ast) {
|
|
140
|
-
// Evict if at capacity
|
|
141
|
-
if (this._cache.size >= this.maxEntries) {
|
|
142
|
-
this._evictLRU();
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
this._cache.set(hash, { ast, accessCount: 1 });
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Evict least recently used entries
|
|
150
|
-
*/
|
|
151
|
-
_evictLRU() {
|
|
152
|
-
// Find entry with lowest access count
|
|
153
|
-
let minKey = null;
|
|
154
|
-
let minCount = Infinity;
|
|
155
|
-
|
|
156
|
-
for (const [key, entry] of this._cache) {
|
|
157
|
-
if (entry.accessCount < minCount) {
|
|
158
|
-
minCount = entry.accessCount;
|
|
159
|
-
minKey = key;
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
if (minKey) {
|
|
164
|
-
this._cache.delete(minKey);
|
|
165
|
-
this.stats.evictions++;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* Clear the cache
|
|
171
|
-
*/
|
|
172
|
-
clear() {
|
|
173
|
-
this._cache.clear();
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* Get cache size
|
|
178
|
-
* @returns {number}
|
|
179
|
-
*/
|
|
180
|
-
get size() {
|
|
181
|
-
return this._cache.size;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* Get cache stats summary
|
|
186
|
-
* @returns {Object}
|
|
187
|
-
*/
|
|
188
|
-
getSummary() {
|
|
189
|
-
const total = this.stats.hits + this.stats.misses;
|
|
190
|
-
const hitRate = total > 0 ? (this.stats.hits / total * 100).toFixed(1) : 0;
|
|
191
|
-
|
|
192
|
-
return {
|
|
193
|
-
...this.stats,
|
|
194
|
-
size: this._cache.size,
|
|
195
|
-
hitRate: `${hitRate}%`,
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Global shared AST cache instance
|
|
202
|
-
* Use this for cross-adapter/analyzer caching
|
|
203
|
-
*/
|
|
204
|
-
const globalASTCache = new ASTCache();
|
|
205
|
-
|
|
206
|
-
module.exports = {
|
|
207
|
-
ASTCache,
|
|
208
|
-
globalASTCache,
|
|
209
|
-
DEFAULT_PARSER_OPTIONS,
|
|
210
|
-
};
|
|
1
|
+
// bin/runners/lib/engine/ast-cache.js
|
|
2
|
+
// Shared AST cache with content-hash keying
|
|
3
|
+
|
|
4
|
+
const parser = require("@babel/parser");
|
|
5
|
+
const crypto = require("crypto");
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Compute SHA256 hash
|
|
9
|
+
* @param {string} content
|
|
10
|
+
* @returns {string}
|
|
11
|
+
*/
|
|
12
|
+
function sha256(content) {
|
|
13
|
+
return crypto.createHash("sha256").update(content).digest("hex");
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Default Babel parser options for maximum compatibility
|
|
18
|
+
*/
|
|
19
|
+
const DEFAULT_PARSER_OPTIONS = {
|
|
20
|
+
sourceType: "unambiguous",
|
|
21
|
+
errorRecovery: true,
|
|
22
|
+
allowImportExportEverywhere: true,
|
|
23
|
+
plugins: [
|
|
24
|
+
"typescript",
|
|
25
|
+
"jsx",
|
|
26
|
+
"dynamicImport",
|
|
27
|
+
"importMeta",
|
|
28
|
+
"topLevelAwait",
|
|
29
|
+
"classProperties",
|
|
30
|
+
"classPrivateProperties",
|
|
31
|
+
"classPrivateMethods",
|
|
32
|
+
"optionalChaining",
|
|
33
|
+
"nullishCoalescingOperator",
|
|
34
|
+
"decorators-legacy",
|
|
35
|
+
],
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* ASTCache - Content-hash keyed AST cache
|
|
40
|
+
*
|
|
41
|
+
* Usage:
|
|
42
|
+
* const cache = new ASTCache();
|
|
43
|
+
* const ast = cache.parse(content, filePath);
|
|
44
|
+
*
|
|
45
|
+
* // Later, same content will return cached AST
|
|
46
|
+
* const ast2 = cache.parse(content, filePath); // cache hit
|
|
47
|
+
*/
|
|
48
|
+
class ASTCache {
|
|
49
|
+
/**
|
|
50
|
+
* @param {Object} [options]
|
|
51
|
+
* @param {number} [options.maxEntries] - Max cache entries (default: 5000)
|
|
52
|
+
* @param {Object} [options.parserOptions] - Babel parser options override
|
|
53
|
+
*/
|
|
54
|
+
constructor(options = {}) {
|
|
55
|
+
this.maxEntries = options.maxEntries || 5000;
|
|
56
|
+
this.parserOptions = { ...DEFAULT_PARSER_OPTIONS, ...options.parserOptions };
|
|
57
|
+
|
|
58
|
+
/** @type {Map<string, { ast: any, accessCount: number }>} hash -> { ast, accessCount } */
|
|
59
|
+
this._cache = new Map();
|
|
60
|
+
|
|
61
|
+
this.stats = {
|
|
62
|
+
hits: 0,
|
|
63
|
+
misses: 0,
|
|
64
|
+
parseErrors: 0,
|
|
65
|
+
evictions: 0,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Parse code and cache the AST
|
|
71
|
+
* @param {string} content - Source code
|
|
72
|
+
* @param {string} [filePath] - Optional file path for error messages
|
|
73
|
+
* @returns {{ ast: any, error: Error|null }}
|
|
74
|
+
*/
|
|
75
|
+
parse(content, filePath) {
|
|
76
|
+
const hash = sha256(content);
|
|
77
|
+
|
|
78
|
+
// Check cache
|
|
79
|
+
if (this._cache.has(hash)) {
|
|
80
|
+
const entry = this._cache.get(hash);
|
|
81
|
+
entry.accessCount++;
|
|
82
|
+
this.stats.hits++;
|
|
83
|
+
return { ast: entry.ast, error: null };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
this.stats.misses++;
|
|
87
|
+
|
|
88
|
+
// Parse
|
|
89
|
+
let ast = null;
|
|
90
|
+
let error = null;
|
|
91
|
+
|
|
92
|
+
try {
|
|
93
|
+
ast = parser.parse(content, {
|
|
94
|
+
...this.parserOptions,
|
|
95
|
+
sourceFilename: filePath || undefined,
|
|
96
|
+
});
|
|
97
|
+
} catch (e) {
|
|
98
|
+
error = e;
|
|
99
|
+
this.stats.parseErrors++;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Cache if successful
|
|
103
|
+
if (ast) {
|
|
104
|
+
this._cacheEntry(hash, ast);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return { ast, error };
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Get cached AST by content hash
|
|
112
|
+
* @param {string} hash - Content hash
|
|
113
|
+
* @returns {any|null}
|
|
114
|
+
*/
|
|
115
|
+
getByHash(hash) {
|
|
116
|
+
const entry = this._cache.get(hash);
|
|
117
|
+
if (entry) {
|
|
118
|
+
entry.accessCount++;
|
|
119
|
+
this.stats.hits++;
|
|
120
|
+
return entry.ast;
|
|
121
|
+
}
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Check if AST is cached
|
|
127
|
+
* @param {string} content
|
|
128
|
+
* @returns {boolean}
|
|
129
|
+
*/
|
|
130
|
+
has(content) {
|
|
131
|
+
return this._cache.has(sha256(content));
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Cache an entry with LRU eviction
|
|
136
|
+
* @param {string} hash
|
|
137
|
+
* @param {any} ast
|
|
138
|
+
*/
|
|
139
|
+
_cacheEntry(hash, ast) {
|
|
140
|
+
// Evict if at capacity
|
|
141
|
+
if (this._cache.size >= this.maxEntries) {
|
|
142
|
+
this._evictLRU();
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
this._cache.set(hash, { ast, accessCount: 1 });
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Evict least recently used entries
|
|
150
|
+
*/
|
|
151
|
+
_evictLRU() {
|
|
152
|
+
// Find entry with lowest access count
|
|
153
|
+
let minKey = null;
|
|
154
|
+
let minCount = Infinity;
|
|
155
|
+
|
|
156
|
+
for (const [key, entry] of this._cache) {
|
|
157
|
+
if (entry.accessCount < minCount) {
|
|
158
|
+
minCount = entry.accessCount;
|
|
159
|
+
minKey = key;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (minKey) {
|
|
164
|
+
this._cache.delete(minKey);
|
|
165
|
+
this.stats.evictions++;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Clear the cache
|
|
171
|
+
*/
|
|
172
|
+
clear() {
|
|
173
|
+
this._cache.clear();
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Get cache size
|
|
178
|
+
* @returns {number}
|
|
179
|
+
*/
|
|
180
|
+
get size() {
|
|
181
|
+
return this._cache.size;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Get cache stats summary
|
|
186
|
+
* @returns {Object}
|
|
187
|
+
*/
|
|
188
|
+
getSummary() {
|
|
189
|
+
const total = this.stats.hits + this.stats.misses;
|
|
190
|
+
const hitRate = total > 0 ? (this.stats.hits / total * 100).toFixed(1) : 0;
|
|
191
|
+
|
|
192
|
+
return {
|
|
193
|
+
...this.stats,
|
|
194
|
+
size: this._cache.size,
|
|
195
|
+
hitRate: `${hitRate}%`,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Global shared AST cache instance
|
|
202
|
+
* Use this for cross-adapter/analyzer caching
|
|
203
|
+
*/
|
|
204
|
+
const globalASTCache = new ASTCache();
|
|
205
|
+
|
|
206
|
+
module.exports = {
|
|
207
|
+
ASTCache,
|
|
208
|
+
globalASTCache,
|
|
209
|
+
DEFAULT_PARSER_OPTIONS,
|
|
210
|
+
};
|