@rigour-labs/core 6.2.4 → 6.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.
- package/README.md +2 -0
- package/dist/deep/code-context.d.ts +28 -0
- package/dist/deep/code-context.js +93 -0
- package/dist/deep/code-context.test.d.ts +1 -0
- package/dist/deep/code-context.test.js +48 -0
- package/dist/deep/code-pass.d.ts +15 -0
- package/dist/deep/code-pass.js +44 -0
- package/dist/deep/code-review-prompt.d.ts +17 -0
- package/dist/deep/code-review-prompt.js +30 -0
- package/dist/deep/code-review-prompt.test.d.ts +1 -0
- package/dist/deep/code-review-prompt.test.js +20 -0
- package/dist/deep/code-verifier.d.ts +19 -0
- package/dist/deep/code-verifier.js +48 -0
- package/dist/deep/code-verifier.test.d.ts +1 -0
- package/dist/deep/code-verifier.test.js +46 -0
- package/dist/deep/fact-extractor.d.ts +7 -1
- package/dist/deep/fact-extractor.js +16 -8
- package/dist/deep/fact-extractor.test.js +34 -1
- package/dist/deep/facts-pass.d.ts +24 -0
- package/dist/deep/facts-pass.js +69 -0
- package/dist/deep/index.d.ts +6 -1
- package/dist/deep/index.js +5 -1
- package/dist/deep/parse-findings.d.ts +12 -0
- package/dist/deep/parse-findings.js +73 -0
- package/dist/deep/parse-findings.test.d.ts +1 -0
- package/dist/deep/parse-findings.test.js +25 -0
- package/dist/deep/prompts.d.ts +1 -1
- package/dist/deep/prompts.js +7 -8
- package/dist/deep/prompts.test.js +15 -0
- package/dist/discovery-signals.d.ts +27 -0
- package/dist/discovery-signals.js +96 -0
- package/dist/discovery.d.ts +1 -2
- package/dist/discovery.js +36 -49
- package/dist/discovery.test.js +84 -71
- package/dist/gates/context.js +7 -0
- package/dist/gates/deep-analysis.d.ts +33 -8
- package/dist/gates/deep-analysis.js +169 -306
- package/dist/gates/deep-analysis.test.d.ts +1 -0
- package/dist/gates/deep-analysis.test.js +86 -0
- package/dist/gates/deep-intent.d.ts +3 -0
- package/dist/gates/deep-intent.js +57 -0
- package/dist/gates/deep-intent.test.d.ts +1 -0
- package/dist/gates/deep-intent.test.js +51 -0
- package/dist/gates/deep-runner.d.ts +15 -0
- package/dist/gates/deep-runner.js +66 -0
- package/dist/gates/dependency.js +4 -0
- package/dist/gates/deprecated-apis-ast.d.ts +8 -0
- package/dist/gates/deprecated-apis-ast.js +25 -0
- package/dist/gates/deprecated-apis-rules-node.js +2 -8
- package/dist/gates/deprecated-apis.js +5 -1
- package/dist/gates/deprecated-apis.test.js +30 -0
- package/dist/gates/frontend-secret-exposure.js +5 -1
- package/dist/gates/frontend-secret-exposure.test.js +20 -0
- package/dist/gates/hallucinated-imports/framework-modules.d.ts +14 -0
- package/dist/gates/hallucinated-imports/framework-modules.js +75 -0
- package/dist/gates/hallucinated-imports/index.js +14 -6
- package/dist/gates/hallucinated-imports/js-resolver.d.ts +16 -12
- package/dist/gates/hallucinated-imports/js-resolver.js +65 -153
- package/dist/gates/hallucinated-imports/ts-path-target.js +16 -0
- package/dist/gates/hallucinated-imports/tsconfig-paths.d.ts +16 -0
- package/dist/gates/hallucinated-imports/tsconfig-paths.js +120 -0
- package/dist/gates/hallucinated-imports-sveltekit.test.d.ts +1 -0
- package/dist/gates/hallucinated-imports-sveltekit.test.js +108 -0
- package/dist/gates/logic-drift.js +7 -1
- package/dist/gates/runner.js +10 -40
- package/dist/gates/runner.test.js +37 -25
- package/dist/gates/scoped-gates.test.d.ts +1 -0
- package/dist/gates/scoped-gates.test.js +52 -0
- package/dist/gates/semantic-bugs.d.ts +23 -0
- package/dist/gates/semantic-bugs.js +48 -0
- package/dist/gates/semantic-bugs.test.d.ts +1 -0
- package/dist/gates/semantic-bugs.test.js +70 -0
- package/dist/gates/side-effect-analysis/index.js +11 -1
- package/dist/gates/side-effect-analysis.test.d.ts +1 -0
- package/dist/gates/side-effect-analysis.test.js +162 -0
- package/dist/gates/side-effect-helpers/pattern-detection.js +35 -7
- package/dist/gates/side-effect-helpers/resource-tracking.js +17 -10
- package/dist/gates/side-effect-helpers/scope-analysis.d.ts +6 -0
- package/dist/gates/side-effect-helpers/scope-analysis.js +20 -0
- package/dist/gates/style-drift.js +3 -0
- package/dist/index.d.ts +11 -2
- package/dist/index.js +10 -2
- package/dist/inference/http-download.d.ts +22 -0
- package/dist/inference/http-download.js +132 -0
- package/dist/inference/http-download.test.d.ts +1 -0
- package/dist/inference/http-download.test.js +109 -0
- package/dist/inference/index.d.ts +5 -1
- package/dist/inference/index.js +2 -1
- package/dist/inference/llama-engine.d.ts +27 -0
- package/dist/inference/llama-engine.js +152 -0
- package/dist/inference/llama-engine.test.d.ts +1 -0
- package/dist/inference/llama-engine.test.js +51 -0
- package/dist/inference/llama-process.d.ts +72 -0
- package/dist/inference/llama-process.js +126 -0
- package/dist/inference/llama-process.test.d.ts +1 -0
- package/dist/inference/llama-process.test.js +61 -0
- package/dist/inference/model-download.test.d.ts +1 -0
- package/dist/inference/model-download.test.js +73 -0
- package/dist/inference/model-manager.d.ts +14 -1
- package/dist/inference/model-manager.js +65 -80
- package/dist/inference/sidecar-provider.d.ts +19 -10
- package/dist/inference/sidecar-provider.js +125 -342
- package/dist/inference/types.d.ts +2 -0
- package/dist/semantic/ast.d.ts +29 -0
- package/dist/semantic/ast.js +122 -0
- package/dist/semantic/benchmark.d.ts +16 -0
- package/dist/semantic/benchmark.js +31 -0
- package/dist/semantic/benchmark.test.d.ts +1 -0
- package/dist/semantic/benchmark.test.js +18 -0
- package/dist/semantic/engine.d.ts +8 -0
- package/dist/semantic/engine.js +45 -0
- package/dist/semantic/intent/benchmark.d.ts +31 -0
- package/dist/semantic/intent/benchmark.js +74 -0
- package/dist/semantic/intent/intent-check.d.ts +43 -0
- package/dist/semantic/intent/intent-check.js +72 -0
- package/dist/semantic/intent/intent.test.d.ts +1 -0
- package/dist/semantic/intent/intent.test.js +46 -0
- package/dist/semantic/intent/parallel-reads.d.ts +23 -0
- package/dist/semantic/intent/parallel-reads.js +59 -0
- package/dist/semantic/learn/benchmark.d.ts +20 -0
- package/dist/semantic/learn/benchmark.js +71 -0
- package/dist/semantic/learn/compile.d.ts +4 -0
- package/dist/semantic/learn/compile.js +56 -0
- package/dist/semantic/learn/conditions.d.ts +22 -0
- package/dist/semantic/learn/conditions.js +93 -0
- package/dist/semantic/learn/extract.d.ts +30 -0
- package/dist/semantic/learn/extract.js +122 -0
- package/dist/semantic/learn/git-trees.d.ts +8 -0
- package/dist/semantic/learn/git-trees.js +32 -0
- package/dist/semantic/learn/identity.d.ts +18 -0
- package/dist/semantic/learn/identity.js +97 -0
- package/dist/semantic/learn/learn.d.ts +25 -0
- package/dist/semantic/learn/learn.js +109 -0
- package/dist/semantic/learn/learn.test.d.ts +1 -0
- package/dist/semantic/learn/learn.test.js +67 -0
- package/dist/semantic/learn/store.d.ts +4 -0
- package/dist/semantic/learn/store.js +39 -0
- package/dist/semantic/learn/types.d.ts +468 -0
- package/dist/semantic/learn/types.js +55 -0
- package/dist/semantic/origins.d.ts +42 -0
- package/dist/semantic/origins.js +149 -0
- package/dist/semantic/origins.test.d.ts +1 -0
- package/dist/semantic/origins.test.js +77 -0
- package/dist/semantic/program.d.ts +13 -0
- package/dist/semantic/program.js +62 -0
- package/dist/semantic/rules/credential-redirect.d.ts +2 -0
- package/dist/semantic/rules/credential-redirect.js +209 -0
- package/dist/semantic/rules/degraded-response-cached.d.ts +2 -0
- package/dist/semantic/rules/degraded-response-cached.js +271 -0
- package/dist/semantic/rules/in-memory-aggregation.d.ts +2 -0
- package/dist/semantic/rules/in-memory-aggregation.js +179 -0
- package/dist/semantic/summaries.d.ts +18 -0
- package/dist/semantic/summaries.js +33 -0
- package/dist/semantic/types.d.ts +32 -0
- package/dist/semantic/types.js +1 -0
- package/dist/storage/index.d.ts +1 -0
- package/dist/storage/index.js +1 -0
- package/dist/storage/team-diagnostics.d.ts +22 -0
- package/dist/storage/team-diagnostics.js +58 -0
- package/dist/storage/team-diagnostics.test.d.ts +1 -0
- package/dist/storage/team-diagnostics.test.js +51 -0
- package/dist/storage/team-schema.d.ts +6 -0
- package/dist/storage/team-schema.js +82 -0
- package/dist/storage/team-store.js +25 -72
- package/dist/templates/universal-config.js +4 -2
- package/dist/types/index.d.ts +114 -14
- package/dist/types/index.js +16 -2
- package/dist/utils/deep-status.d.ts +7 -0
- package/dist/utils/deep-status.js +11 -0
- package/dist/utils/diff.d.ts +3 -0
- package/dist/utils/diff.js +52 -0
- package/dist/utils/diff.test.d.ts +1 -0
- package/dist/utils/diff.test.js +38 -0
- package/dist/utils/scanner.js +13 -2
- package/dist/utils/scanner.test.js +22 -8
- package/dist/utils/scope.d.ts +15 -0
- package/dist/utils/scope.js +51 -0
- package/dist/utils/scope.test.d.ts +1 -0
- package/dist/utils/scope.test.js +38 -0
- package/package.json +6 -6
|
@@ -6,6 +6,7 @@ import path from 'path';
|
|
|
6
6
|
import fs from 'fs-extra';
|
|
7
7
|
import { createHash } from 'crypto';
|
|
8
8
|
import { RIGOUR_DIR } from '../storage/db.js';
|
|
9
|
+
import { downloadToFile } from './http-download.js';
|
|
9
10
|
import { MODELS, FALLBACK_MODELS, VERSION_CHECK_URL, BUNDLED_MODEL_VERSION, updateModelVersion } from './types.js';
|
|
10
11
|
const MODELS_DIR = path.join(RIGOUR_DIR, 'models');
|
|
11
12
|
const VERSION_CACHE_PATH = path.join(MODELS_DIR, '.latest_version.json');
|
|
@@ -76,13 +77,26 @@ async function isFileCached(model) {
|
|
|
76
77
|
* Check if any model for this tier is cached (fine-tuned or fallback).
|
|
77
78
|
*/
|
|
78
79
|
export async function isModelCached(tier) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
return (await getCachedModel(tier)) !== null;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* The verified model file for a tier, preferring the fine-tuned model over
|
|
84
|
+
* the stock fallback. Null when neither is cached and verified.
|
|
85
|
+
*/
|
|
86
|
+
export async function getCachedModel(tier) {
|
|
87
|
+
const primary = MODELS[tier];
|
|
88
|
+
if (await isFileCached(primary)) {
|
|
89
|
+
return { path: path.join(MODELS_DIR, primary.filename), info: primary, fallback: false };
|
|
90
|
+
}
|
|
91
|
+
const fallback = FALLBACK_MODELS[tier];
|
|
92
|
+
if (fallback.url !== primary.url && await isFileCached(fallback)) {
|
|
93
|
+
return { path: path.join(MODELS_DIR, fallback.filename), info: fallback, fallback: true };
|
|
94
|
+
}
|
|
95
|
+
return null;
|
|
83
96
|
}
|
|
84
97
|
/**
|
|
85
98
|
* Get the path to a cached model (prefers fine-tuned over fallback).
|
|
99
|
+
* Existence only; use getCachedModel() for a verified file.
|
|
86
100
|
*/
|
|
87
101
|
export function getModelPath(tier) {
|
|
88
102
|
const primary = path.join(MODELS_DIR, MODELS[tier].filename);
|
|
@@ -97,84 +111,55 @@ export function getModelInfo(tier) {
|
|
|
97
111
|
return MODELS[tier];
|
|
98
112
|
}
|
|
99
113
|
/**
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
|
|
103
|
-
async function streamToDisk(response, tempPath, model, onProgress) {
|
|
104
|
-
const contentLength = parseInt(response.headers.get('content-length') || '0', 10);
|
|
105
|
-
const reader = response.body?.getReader();
|
|
106
|
-
if (!reader)
|
|
107
|
-
throw new Error('No response body');
|
|
108
|
-
const writeStream = fs.createWriteStream(tempPath);
|
|
109
|
-
const hash = createHash('sha256');
|
|
110
|
-
let downloaded = 0;
|
|
111
|
-
let lastPct = 0;
|
|
112
|
-
while (true) {
|
|
113
|
-
const { done, value } = await reader.read();
|
|
114
|
-
if (done)
|
|
115
|
-
break;
|
|
116
|
-
const chunk = Buffer.from(value);
|
|
117
|
-
writeStream.write(chunk);
|
|
118
|
-
hash.update(chunk);
|
|
119
|
-
downloaded += value.length;
|
|
120
|
-
if (contentLength > 0) {
|
|
121
|
-
const pct = Math.round((downloaded / contentLength) * 100);
|
|
122
|
-
if (pct >= lastPct + 5) {
|
|
123
|
-
lastPct = pct;
|
|
124
|
-
onProgress?.(`Downloading ${model.name}: ${pct}%`, pct);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
writeStream.end();
|
|
129
|
-
await new Promise((resolve, reject) => {
|
|
130
|
-
writeStream.on('finish', resolve);
|
|
131
|
-
writeStream.on('error', reject);
|
|
132
|
-
});
|
|
133
|
-
return { sha256: hash.digest('hex'), downloaded };
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* Verify SHA256 against ETag, allowing LFS OID mismatches
|
|
137
|
-
* if the download size is reasonable.
|
|
114
|
+
* Reject a download whose SHA-256 differs from the one the server published.
|
|
115
|
+
* Hugging Face publishes the LFS object's SHA-256, which is the content hash,
|
|
116
|
+
* so any mismatch means a corrupt or tampered file.
|
|
138
117
|
*/
|
|
139
|
-
function verifySha256(expectedSha256, actualSha256,
|
|
118
|
+
function verifySha256(expectedSha256, actualSha256, model) {
|
|
140
119
|
if (!expectedSha256 || actualSha256 === expectedSha256)
|
|
141
120
|
return;
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
121
|
+
throw new Error(`Checksum mismatch for ${model.name}: expected ${expectedSha256}, got ${actualSha256}`);
|
|
122
|
+
}
|
|
123
|
+
function progressReporter(model, onProgress) {
|
|
124
|
+
let lastPct = -5;
|
|
125
|
+
return (downloaded, total) => {
|
|
126
|
+
const size = total ?? model.sizeBytes;
|
|
127
|
+
const pct = Math.min(99, Math.round((downloaded / size) * 100));
|
|
128
|
+
if (pct >= lastPct + 5) {
|
|
129
|
+
lastPct = pct;
|
|
130
|
+
onProgress?.(`Downloading ${model.name}: ${pct}%`, pct);
|
|
131
|
+
}
|
|
132
|
+
};
|
|
149
133
|
}
|
|
150
134
|
/**
|
|
151
|
-
* Download a
|
|
135
|
+
* Download a model to `<file>.download`, verify it, then move it into place
|
|
136
|
+
* with its metadata. A partial file survives network errors so the next run
|
|
137
|
+
* resumes it; a checksum mismatch deletes it.
|
|
152
138
|
*/
|
|
153
|
-
async function downloadFromUrl(
|
|
139
|
+
async function downloadFromUrl(model, onProgress, get) {
|
|
154
140
|
const destPath = path.join(MODELS_DIR, model.filename);
|
|
155
141
|
const tempPath = destPath + '.download';
|
|
142
|
+
const { sha256, bytes, etag } = await downloadToFile(model.url, tempPath, {
|
|
143
|
+
onProgress: progressReporter(model, onProgress),
|
|
144
|
+
get,
|
|
145
|
+
});
|
|
156
146
|
try {
|
|
157
|
-
|
|
158
|
-
if (!response.ok) {
|
|
159
|
-
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
160
|
-
}
|
|
161
|
-
const expectedSha = extractSha256FromEtag(response.headers.get('etag'));
|
|
162
|
-
const { sha256, downloaded } = await streamToDisk(response, tempPath, model, onProgress);
|
|
163
|
-
verifySha256(expectedSha, sha256, downloaded, model);
|
|
164
|
-
fs.renameSync(tempPath, destPath);
|
|
165
|
-
await writeModelMeta(model.filename, {
|
|
166
|
-
sha256, sizeBytes: downloaded,
|
|
167
|
-
verifiedAt: new Date().toISOString(),
|
|
168
|
-
sourceUrl: model.url,
|
|
169
|
-
sourceEtag: response.headers.get('etag') || undefined,
|
|
170
|
-
});
|
|
171
|
-
onProgress?.(`Model ${model.name} ready`, 100);
|
|
172
|
-
return destPath;
|
|
147
|
+
verifySha256(extractSha256FromEtag(etag), sha256, model);
|
|
173
148
|
}
|
|
174
149
|
catch (error) {
|
|
175
|
-
fs.
|
|
150
|
+
await fs.remove(tempPath);
|
|
176
151
|
throw error;
|
|
177
152
|
}
|
|
153
|
+
await fs.move(tempPath, destPath, { overwrite: true });
|
|
154
|
+
await writeModelMeta(model.filename, {
|
|
155
|
+
sha256,
|
|
156
|
+
sizeBytes: bytes,
|
|
157
|
+
verifiedAt: new Date().toISOString(),
|
|
158
|
+
sourceUrl: model.url,
|
|
159
|
+
sourceEtag: etag || undefined,
|
|
160
|
+
});
|
|
161
|
+
onProgress?.(`Model ${model.name} ready`, 100);
|
|
162
|
+
return destPath;
|
|
178
163
|
}
|
|
179
164
|
/**
|
|
180
165
|
* Check HuggingFace for a newer model version (like antivirus signature updates).
|
|
@@ -236,25 +221,25 @@ export async function checkForUpdates(onProgress) {
|
|
|
236
221
|
* Download a model from HuggingFace CDN.
|
|
237
222
|
* Checks for updates first, then tries fine-tuned model, falls back to stock Qwen.
|
|
238
223
|
*/
|
|
239
|
-
export async function downloadModel(tier, onProgress) {
|
|
224
|
+
export async function downloadModel(tier, onProgress, get) {
|
|
240
225
|
fs.ensureDirSync(MODELS_DIR);
|
|
241
226
|
// Check for newer model version (non-blocking, cached 24h)
|
|
242
227
|
await checkForUpdates(onProgress);
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
228
|
+
const cached = await getCachedModel(tier);
|
|
229
|
+
if (cached) {
|
|
230
|
+
onProgress?.(`Model ${cached.info.name} already cached`, 100);
|
|
231
|
+
return cached.path;
|
|
246
232
|
}
|
|
247
233
|
const model = MODELS[tier];
|
|
248
234
|
onProgress?.(`Downloading ${model.name} (${model.sizeHuman})...`, 0);
|
|
249
235
|
try {
|
|
250
|
-
return await downloadFromUrl(
|
|
236
|
+
return await downloadFromUrl(model, onProgress, get);
|
|
251
237
|
}
|
|
252
238
|
catch (error) {
|
|
253
|
-
// Fine-tuned model not available — try stock fallback
|
|
254
239
|
const fallback = FALLBACK_MODELS[tier];
|
|
255
240
|
if (fallback && fallback.url !== model.url) {
|
|
256
|
-
onProgress?.(`Fine-tuned model unavailable
|
|
257
|
-
return downloadFromUrl(
|
|
241
|
+
onProgress?.(`Fine-tuned model unavailable (${error?.message ?? 'unknown error'}); using stock ${fallback.name}`, 0);
|
|
242
|
+
return downloadFromUrl(fallback, onProgress, get);
|
|
258
243
|
}
|
|
259
244
|
throw error;
|
|
260
245
|
}
|
|
@@ -263,9 +248,9 @@ export async function downloadModel(tier, onProgress) {
|
|
|
263
248
|
* Ensure a model is available, downloading if needed.
|
|
264
249
|
*/
|
|
265
250
|
export async function ensureModel(tier, onProgress) {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
251
|
+
const cached = await getCachedModel(tier);
|
|
252
|
+
if (cached)
|
|
253
|
+
return cached.path;
|
|
269
254
|
return downloadModel(tier, onProgress);
|
|
270
255
|
}
|
|
271
256
|
/**
|
|
@@ -1,23 +1,32 @@
|
|
|
1
1
|
import type { InferenceProvider, InferenceOptions, ModelTier } from './types.js';
|
|
2
|
+
export interface ActiveModel {
|
|
3
|
+
name: string;
|
|
4
|
+
filename: string;
|
|
5
|
+
fallback: boolean;
|
|
6
|
+
}
|
|
2
7
|
export declare class SidecarProvider implements InferenceProvider {
|
|
3
8
|
readonly name = "sidecar";
|
|
4
9
|
private binaryPath;
|
|
5
|
-
private
|
|
10
|
+
private model;
|
|
11
|
+
private schemaPath;
|
|
6
12
|
private tier;
|
|
7
13
|
private threads;
|
|
8
14
|
constructor(tier?: ModelTier, threads?: number);
|
|
15
|
+
/** True when a llama-cli that actually runs is installed. */
|
|
9
16
|
isAvailable(): Promise<boolean>;
|
|
17
|
+
/** The llama-cli this provider would use and its version, or null if none runs. */
|
|
18
|
+
findEngine(): Promise<{
|
|
19
|
+
path: string;
|
|
20
|
+
version?: string;
|
|
21
|
+
} | null>;
|
|
22
|
+
/** Install the engine and model for this tier without running inference. */
|
|
23
|
+
prepare(onProgress?: (message: string) => void): Promise<void>;
|
|
10
24
|
setup(onProgress?: (message: string) => void): Promise<void>;
|
|
25
|
+
/** The model file setup() loaded, or null before setup. */
|
|
26
|
+
getActiveModel(): ActiveModel | null;
|
|
11
27
|
analyze(prompt: string, options?: InferenceOptions): Promise<string>;
|
|
12
28
|
dispose(): void;
|
|
13
|
-
|
|
14
|
-
private getPlatformPackageName;
|
|
29
|
+
/** First candidate binary that exists, is executable and passes the probe. */
|
|
15
30
|
private resolveBinaryPath;
|
|
16
|
-
|
|
17
|
-
* Download llama-cli directly from llama.cpp GitHub releases.
|
|
18
|
-
* Extracts the binary to ~/.rigour/bin/llama-cli
|
|
19
|
-
*/
|
|
20
|
-
private downloadLlamaCli;
|
|
21
|
-
/** Legacy: install via npm brain package */
|
|
22
|
-
private installSidecarBinary;
|
|
31
|
+
private candidateBinaries;
|
|
23
32
|
}
|