@loreai/gateway 0.14.0 → 0.15.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/dist/bin.cjs +27 -0
- package/dist/index.cjs +1058 -0
- package/dist/index.d.cts +21 -0
- package/package.json +10 -10
- package/dist/index.js +0 -50087
- package/src/auth.ts +0 -133
- package/src/batch-queue.ts +0 -575
- package/src/cache-analytics.ts +0 -344
- package/src/cli/agents.ts +0 -107
- package/src/cli/bin.ts +0 -11
- package/src/cli/help.ts +0 -55
- package/src/cli/lib/binary.ts +0 -353
- package/src/cli/lib/bspatch.ts +0 -306
- package/src/cli/lib/delta-upgrade.ts +0 -790
- package/src/cli/lib/errors.ts +0 -48
- package/src/cli/lib/ghcr.ts +0 -389
- package/src/cli/lib/patch-cache.ts +0 -342
- package/src/cli/lib/upgrade.ts +0 -454
- package/src/cli/lib/version-check.ts +0 -385
- package/src/cli/main.ts +0 -152
- package/src/cli/run.ts +0 -181
- package/src/cli/start.ts +0 -82
- package/src/cli/upgrade.ts +0 -311
- package/src/cli/version.ts +0 -22
- package/src/compaction.ts +0 -195
- package/src/config.ts +0 -199
- package/src/idle.ts +0 -240
- package/src/index.ts +0 -41
- package/src/llm-adapter.ts +0 -182
- package/src/pipeline.ts +0 -1681
- package/src/recall.ts +0 -433
- package/src/recorder.ts +0 -192
- package/src/server.ts +0 -250
- package/src/session.ts +0 -207
- package/src/stream/anthropic.ts +0 -708
- package/src/temporal-adapter.ts +0 -310
- package/src/translate/anthropic.ts +0 -469
- package/src/translate/openai.ts +0 -536
- package/src/translate/types.ts +0 -222
- package/src/worker-model.ts +0 -408
package/src/cli/lib/upgrade.ts
DELETED
|
@@ -1,454 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Upgrade Module
|
|
3
|
-
*
|
|
4
|
-
* Orchestrates binary self-upgrade: version fetching, delta patch
|
|
5
|
-
* application with full-download fallback, and binary replacement.
|
|
6
|
-
*
|
|
7
|
-
* Lore is distributed as a standalone binary only — no package manager
|
|
8
|
-
* detection or Homebrew support needed. The upgrade flow is:
|
|
9
|
-
*
|
|
10
|
-
* 1. Check latest version (GitHub Releases for stable, GHCR for nightly)
|
|
11
|
-
* 2. Try delta upgrade (tiny patches instead of full ~30MB binary)
|
|
12
|
-
* 3. Fall back to full .gz download if no patches available
|
|
13
|
-
* 4. Verify binary, set permissions, replace self atomically
|
|
14
|
-
*
|
|
15
|
-
* Adapted from Sentry CLI's upgrade.ts — stripped of brew/npm/pnpm/yarn
|
|
16
|
-
* detection, setup spawning, and Sentry SDK telemetry.
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
import { chmodSync, statSync, unlinkSync } from "node:fs";
|
|
20
|
-
import { homedir } from "node:os";
|
|
21
|
-
import { dirname, join } from "node:path";
|
|
22
|
-
|
|
23
|
-
import {
|
|
24
|
-
acquireLock,
|
|
25
|
-
cleanupOldBinary,
|
|
26
|
-
fetchWithUpgradeError,
|
|
27
|
-
getBinaryFilename,
|
|
28
|
-
getBinaryPaths,
|
|
29
|
-
getConfigDir,
|
|
30
|
-
getGitHubHeaders,
|
|
31
|
-
getPlatformBinaryName,
|
|
32
|
-
GITHUB_RELEASES_URL,
|
|
33
|
-
getBinaryDownloadUrl,
|
|
34
|
-
isNightlyVersion,
|
|
35
|
-
KNOWN_CURL_DIRS,
|
|
36
|
-
releaseLock,
|
|
37
|
-
replaceBinarySync,
|
|
38
|
-
} from "./binary";
|
|
39
|
-
import { VERSION } from "../version";
|
|
40
|
-
import { attemptDeltaUpgrade, type DeltaResult } from "./delta-upgrade";
|
|
41
|
-
import { UpgradeError } from "./errors";
|
|
42
|
-
import {
|
|
43
|
-
downloadNightlyBlob,
|
|
44
|
-
fetchManifest,
|
|
45
|
-
fetchNightlyManifest,
|
|
46
|
-
findLayerByFilename,
|
|
47
|
-
getAnonymousToken,
|
|
48
|
-
getNightlyVersion,
|
|
49
|
-
} from "./ghcr";
|
|
50
|
-
import { clearPatchCache } from "./patch-cache";
|
|
51
|
-
|
|
52
|
-
/** Regex to strip 'v' prefix from version strings */
|
|
53
|
-
export const VERSION_PREFIX_REGEX = /^v/;
|
|
54
|
-
|
|
55
|
-
/** The git tag used for the rolling nightly GitHub release */
|
|
56
|
-
export const NIGHTLY_TAG = "nightly";
|
|
57
|
-
|
|
58
|
-
/** Release channel type */
|
|
59
|
-
export type ReleaseChannel = "stable" | "nightly";
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* How the current upgrade reached the offline code path.
|
|
63
|
-
*/
|
|
64
|
-
export type OfflineMode = false | "explicit" | "network-fallback";
|
|
65
|
-
|
|
66
|
-
// ---------------------------------------------------------------------------
|
|
67
|
-
// Channel persistence
|
|
68
|
-
// ---------------------------------------------------------------------------
|
|
69
|
-
|
|
70
|
-
const CHANNEL_FILE = "channel";
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Read the persisted release channel from ~/.lore/channel.
|
|
74
|
-
* Returns "stable" if not set or on any error.
|
|
75
|
-
*/
|
|
76
|
-
export function getReleaseChannel(): ReleaseChannel {
|
|
77
|
-
try {
|
|
78
|
-
const content = require("node:fs")
|
|
79
|
-
.readFileSync(join(getConfigDir(), CHANNEL_FILE), "utf-8")
|
|
80
|
-
.trim();
|
|
81
|
-
if (content === "nightly") return "nightly";
|
|
82
|
-
} catch {
|
|
83
|
-
// File doesn't exist or unreadable — default to stable
|
|
84
|
-
}
|
|
85
|
-
return "stable";
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Persist the release channel to ~/.lore/channel.
|
|
90
|
-
*/
|
|
91
|
-
export function setReleaseChannel(channel: ReleaseChannel): void {
|
|
92
|
-
try {
|
|
93
|
-
const fs = require("node:fs");
|
|
94
|
-
const dir = getConfigDir();
|
|
95
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
96
|
-
fs.writeFileSync(join(dir, CHANNEL_FILE), channel, "utf-8");
|
|
97
|
-
} catch {
|
|
98
|
-
// Best-effort — don't fail the upgrade if persistence fails
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// ---------------------------------------------------------------------------
|
|
103
|
-
// Install path resolution
|
|
104
|
-
// ---------------------------------------------------------------------------
|
|
105
|
-
|
|
106
|
-
const sep = require("node:path").sep;
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Known curl install paths, resolved at runtime against the user's home.
|
|
110
|
-
*/
|
|
111
|
-
const KNOWN_CURL_PATHS = KNOWN_CURL_DIRS.map(
|
|
112
|
-
(dir: string) => join(homedir(), dir) + sep,
|
|
113
|
-
);
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Get file paths for the curl-installed binary.
|
|
117
|
-
*/
|
|
118
|
-
export function getCurlInstallPaths(): {
|
|
119
|
-
installPath: string;
|
|
120
|
-
tempPath: string;
|
|
121
|
-
oldPath: string;
|
|
122
|
-
lockPath: string;
|
|
123
|
-
} {
|
|
124
|
-
// Check if we're running from a known curl install location
|
|
125
|
-
for (const dir of KNOWN_CURL_PATHS) {
|
|
126
|
-
if (process.execPath.startsWith(dir)) {
|
|
127
|
-
return getBinaryPaths(process.execPath);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// Fallback to default path
|
|
132
|
-
const defaultPath = join(homedir(), ".lore", "bin", getBinaryFilename());
|
|
133
|
-
return getBinaryPaths(defaultPath);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Start cleanup of .old binary. Called on CLI startup. Fire-and-forget.
|
|
138
|
-
*/
|
|
139
|
-
export function startCleanupOldBinary(): void {
|
|
140
|
-
const { oldPath } = getCurlInstallPaths();
|
|
141
|
-
cleanupOldBinary(oldPath);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// ---------------------------------------------------------------------------
|
|
145
|
-
// Version Fetching
|
|
146
|
-
// ---------------------------------------------------------------------------
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Fetch the latest stable version from GitHub releases.
|
|
150
|
-
*/
|
|
151
|
-
export async function fetchLatestFromGitHub(
|
|
152
|
-
signal?: AbortSignal,
|
|
153
|
-
): Promise<string> {
|
|
154
|
-
const response = await fetchWithUpgradeError(
|
|
155
|
-
`${GITHUB_RELEASES_URL}/latest`,
|
|
156
|
-
{ headers: getGitHubHeaders(), signal },
|
|
157
|
-
"GitHub",
|
|
158
|
-
);
|
|
159
|
-
|
|
160
|
-
if (!response.ok) {
|
|
161
|
-
throw new UpgradeError(
|
|
162
|
-
"network_error",
|
|
163
|
-
`Failed to fetch from GitHub: ${response.status}`,
|
|
164
|
-
);
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
const data = (await response.json()) as { tag_name?: string };
|
|
168
|
-
|
|
169
|
-
if (!data.tag_name) {
|
|
170
|
-
throw new UpgradeError(
|
|
171
|
-
"network_error",
|
|
172
|
-
"No version found in GitHub release",
|
|
173
|
-
);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
return data.tag_name.replace(VERSION_PREFIX_REGEX, "");
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Fetch the latest nightly version from GHCR.
|
|
181
|
-
*/
|
|
182
|
-
export async function fetchLatestNightlyVersion(
|
|
183
|
-
signal?: AbortSignal,
|
|
184
|
-
): Promise<string> {
|
|
185
|
-
if (signal?.aborted) throw new Error("Aborted");
|
|
186
|
-
|
|
187
|
-
const token = await getAnonymousToken(signal);
|
|
188
|
-
|
|
189
|
-
if (signal?.aborted) throw new Error("Aborted");
|
|
190
|
-
|
|
191
|
-
const manifest = await fetchNightlyManifest(token);
|
|
192
|
-
return getNightlyVersion(manifest);
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* Fetch the latest available version based on channel.
|
|
197
|
-
*/
|
|
198
|
-
export function fetchLatestVersion(
|
|
199
|
-
channel: ReleaseChannel = "stable",
|
|
200
|
-
signal?: AbortSignal,
|
|
201
|
-
): Promise<string> {
|
|
202
|
-
if (channel === "nightly") {
|
|
203
|
-
return fetchLatestNightlyVersion(signal);
|
|
204
|
-
}
|
|
205
|
-
return fetchLatestFromGitHub(signal);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* Check if a specific version exists in the appropriate registry.
|
|
210
|
-
*/
|
|
211
|
-
export async function versionExists(
|
|
212
|
-
version: string,
|
|
213
|
-
channel: ReleaseChannel,
|
|
214
|
-
): Promise<boolean> {
|
|
215
|
-
if (isNightlyVersion(version) || channel === "nightly") {
|
|
216
|
-
try {
|
|
217
|
-
const token = await getAnonymousToken();
|
|
218
|
-
await fetchManifest(token, `nightly-${version}`);
|
|
219
|
-
return true;
|
|
220
|
-
} catch (error) {
|
|
221
|
-
if (
|
|
222
|
-
error instanceof UpgradeError &&
|
|
223
|
-
(error.message.includes("HTTP 404") ||
|
|
224
|
-
error.message.includes("HTTP 403"))
|
|
225
|
-
) {
|
|
226
|
-
return false;
|
|
227
|
-
}
|
|
228
|
-
throw error;
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
const response = await fetchWithUpgradeError(
|
|
233
|
-
`${GITHUB_RELEASES_URL}/tags/${version}`,
|
|
234
|
-
{ method: "HEAD", headers: getGitHubHeaders() },
|
|
235
|
-
"GitHub",
|
|
236
|
-
);
|
|
237
|
-
return response.ok;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
// ---------------------------------------------------------------------------
|
|
241
|
-
// Download
|
|
242
|
-
// ---------------------------------------------------------------------------
|
|
243
|
-
|
|
244
|
-
export type DownloadResult = {
|
|
245
|
-
tempBinaryPath: string;
|
|
246
|
-
lockPath: string;
|
|
247
|
-
patchBytes?: number;
|
|
248
|
-
};
|
|
249
|
-
|
|
250
|
-
/**
|
|
251
|
-
* Stream a response body through gzip decompression to disk.
|
|
252
|
-
*/
|
|
253
|
-
async function streamDecompressToFile(
|
|
254
|
-
body: ReadableStream<Uint8Array>,
|
|
255
|
-
destPath: string,
|
|
256
|
-
): Promise<void> {
|
|
257
|
-
const stream = body.pipeThrough(
|
|
258
|
-
new DecompressionStream("gzip") as unknown as TransformStream<Uint8Array, Uint8Array>,
|
|
259
|
-
);
|
|
260
|
-
const writer = Bun.file(destPath).writer();
|
|
261
|
-
try {
|
|
262
|
-
for await (const chunk of stream) {
|
|
263
|
-
writer.write(chunk);
|
|
264
|
-
}
|
|
265
|
-
} finally {
|
|
266
|
-
await writer.end();
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
function getNightlyGzFilename(): string {
|
|
271
|
-
return `${getPlatformBinaryName()}.gz`;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
/**
|
|
275
|
-
* Download a nightly binary from GHCR and decompress it.
|
|
276
|
-
*/
|
|
277
|
-
async function downloadNightlyToPath(
|
|
278
|
-
destPath: string,
|
|
279
|
-
version?: string,
|
|
280
|
-
): Promise<void> {
|
|
281
|
-
const token = await getAnonymousToken();
|
|
282
|
-
const manifest = version
|
|
283
|
-
? await fetchManifest(token, `nightly-${version}`)
|
|
284
|
-
: await fetchNightlyManifest(token);
|
|
285
|
-
const filename = getNightlyGzFilename();
|
|
286
|
-
const layer = findLayerByFilename(manifest, filename);
|
|
287
|
-
const response = await downloadNightlyBlob(token, layer.digest);
|
|
288
|
-
|
|
289
|
-
if (!response.body) {
|
|
290
|
-
throw new UpgradeError(
|
|
291
|
-
"execution_failed",
|
|
292
|
-
"GHCR blob response had no body",
|
|
293
|
-
);
|
|
294
|
-
}
|
|
295
|
-
await streamDecompressToFile(response.body, destPath);
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
/**
|
|
299
|
-
* Download a stable binary from GitHub Releases.
|
|
300
|
-
* Tries gzip first, falls back to raw binary.
|
|
301
|
-
*/
|
|
302
|
-
async function downloadStableToPath(
|
|
303
|
-
version: string,
|
|
304
|
-
destPath: string,
|
|
305
|
-
): Promise<void> {
|
|
306
|
-
const url = getBinaryDownloadUrl(version);
|
|
307
|
-
const headers = getGitHubHeaders();
|
|
308
|
-
|
|
309
|
-
// Try gzip-compressed download first (~60% smaller)
|
|
310
|
-
try {
|
|
311
|
-
const gzResponse = await fetchWithUpgradeError(
|
|
312
|
-
`${url}.gz`,
|
|
313
|
-
{ headers },
|
|
314
|
-
"GitHub",
|
|
315
|
-
);
|
|
316
|
-
if (gzResponse.ok && gzResponse.body) {
|
|
317
|
-
await streamDecompressToFile(gzResponse.body, destPath);
|
|
318
|
-
return;
|
|
319
|
-
}
|
|
320
|
-
} catch {
|
|
321
|
-
// Fall through to raw download
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
const response = await fetchWithUpgradeError(url, { headers }, "GitHub");
|
|
325
|
-
|
|
326
|
-
if (!response.ok) {
|
|
327
|
-
throw new UpgradeError(
|
|
328
|
-
"execution_failed",
|
|
329
|
-
`Failed to download binary: HTTP ${response.status}`,
|
|
330
|
-
);
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
const body = await response.arrayBuffer();
|
|
334
|
-
await Bun.write(destPath, body);
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
/** Max probe attempts before giving up */
|
|
338
|
-
const VERIFY_MAX_ATTEMPTS = 6;
|
|
339
|
-
const VERIFY_BASE_DELAY_MS = 100;
|
|
340
|
-
|
|
341
|
-
function probeBinaryFile(path: string): number | null {
|
|
342
|
-
const stats = statSync(path, { throwIfNoEntry: false });
|
|
343
|
-
if (stats?.isFile() && stats.size > 0) return stats.size;
|
|
344
|
-
return null;
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
/**
|
|
348
|
-
* Wait for a freshly written binary to become visible by path.
|
|
349
|
-
* Handles Windows filesystem visibility race.
|
|
350
|
-
*/
|
|
351
|
-
async function waitForBinaryVisible(path: string): Promise<number> {
|
|
352
|
-
for (let attempt = 1; attempt <= VERIFY_MAX_ATTEMPTS; attempt++) {
|
|
353
|
-
const size = probeBinaryFile(path);
|
|
354
|
-
if (size !== null) return size;
|
|
355
|
-
if (attempt === VERIFY_MAX_ATTEMPTS) break;
|
|
356
|
-
const delay = VERIFY_BASE_DELAY_MS * 2 ** (attempt - 1);
|
|
357
|
-
await Bun.sleep(delay);
|
|
358
|
-
}
|
|
359
|
-
throw new UpgradeError(
|
|
360
|
-
"execution_failed",
|
|
361
|
-
`Downloaded binary is missing or empty at ${path}. ` +
|
|
362
|
-
"This is usually transient — rerun `lore upgrade` to retry.",
|
|
363
|
-
);
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
function formatBytes(bytes: number): string {
|
|
367
|
-
if (bytes < 1024) return `${bytes} B`;
|
|
368
|
-
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
369
|
-
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
/**
|
|
373
|
-
* Download the new binary to a temporary path and return its location.
|
|
374
|
-
*
|
|
375
|
-
* Tries delta upgrade first, falls back to full download.
|
|
376
|
-
* The lock is held on success so concurrent upgrades are blocked.
|
|
377
|
-
*/
|
|
378
|
-
export async function downloadBinaryToTemp(
|
|
379
|
-
version: string,
|
|
380
|
-
downloadTag?: string,
|
|
381
|
-
offline?: OfflineMode,
|
|
382
|
-
): Promise<DownloadResult> {
|
|
383
|
-
const { tempPath, lockPath } = getCurlInstallPaths();
|
|
384
|
-
|
|
385
|
-
acquireLock(lockPath);
|
|
386
|
-
|
|
387
|
-
try {
|
|
388
|
-
// Clean up leftover temp file
|
|
389
|
-
try {
|
|
390
|
-
unlinkSync(tempPath);
|
|
391
|
-
} catch {
|
|
392
|
-
// Ignore
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
// Try delta upgrade first
|
|
396
|
-
const deltaResult = await attemptDeltaUpgrade(
|
|
397
|
-
version,
|
|
398
|
-
process.execPath,
|
|
399
|
-
tempPath,
|
|
400
|
-
!!offline,
|
|
401
|
-
);
|
|
402
|
-
|
|
403
|
-
let patchBytes: number | undefined;
|
|
404
|
-
if (deltaResult) {
|
|
405
|
-
patchBytes = deltaResult.patchBytes;
|
|
406
|
-
} else if (offline) {
|
|
407
|
-
throw new UpgradeError(
|
|
408
|
-
"offline_cache_miss",
|
|
409
|
-
offline === "explicit"
|
|
410
|
-
? `Cannot upgrade to ${version} in offline mode — no pre-downloaded update is available. ` +
|
|
411
|
-
"Run `lore upgrade` without `--offline` to download the update directly."
|
|
412
|
-
: `Cannot upgrade to ${version} — the network is unavailable and no pre-downloaded update was found. ` +
|
|
413
|
-
"Check your internet connection and try again.",
|
|
414
|
-
);
|
|
415
|
-
} else {
|
|
416
|
-
// Full download
|
|
417
|
-
if (isNightlyVersion(version)) {
|
|
418
|
-
await downloadNightlyToPath(tempPath, version);
|
|
419
|
-
} else {
|
|
420
|
-
await downloadStableToPath(downloadTag ?? version, tempPath);
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
const verifiedSize = await waitForBinaryVisible(tempPath);
|
|
425
|
-
console.error(`[lore] Binary verified (${formatBytes(verifiedSize)})`);
|
|
426
|
-
|
|
427
|
-
// Clear consumed patch cache
|
|
428
|
-
clearPatchCache().catch(() => {});
|
|
429
|
-
|
|
430
|
-
// Set executable permission (Unix only)
|
|
431
|
-
if (process.platform !== "win32") {
|
|
432
|
-
chmodSync(tempPath, 0o755);
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
return { tempBinaryPath: tempPath, lockPath, patchBytes };
|
|
436
|
-
} catch (error) {
|
|
437
|
-
releaseLock(lockPath);
|
|
438
|
-
throw error;
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
/**
|
|
443
|
-
* Execute the full upgrade: download binary, replace self.
|
|
444
|
-
*
|
|
445
|
-
* Returns the download result with paths for the caller to
|
|
446
|
-
* handle lock release.
|
|
447
|
-
*/
|
|
448
|
-
export async function executeUpgrade(
|
|
449
|
-
version: string,
|
|
450
|
-
downloadTag?: string,
|
|
451
|
-
offline?: OfflineMode,
|
|
452
|
-
): Promise<DownloadResult> {
|
|
453
|
-
return downloadBinaryToTemp(version, downloadTag, offline);
|
|
454
|
-
}
|