@vantaloom/runtime-linux-x64 0.1.24 → 0.3.6
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/VERSION +1 -1
- package/bin/vantaloom-agent +0 -0
- package/bin/vantaloom-api +0 -0
- package/bin/vantaloomctl +0 -0
- package/cli/config.json +3 -2
- package/cli/package.json +1 -1
- package/cli/src/cli.mjs +357 -35
- package/manifest.json +2 -2
- package/package.json +1 -1
- package/web/404.html +1 -1
- package/web/__next.__PAGE__.txt +2 -2
- package/web/__next._full.txt +3 -3
- package/web/__next._head.txt +1 -1
- package/web/__next._index.txt +2 -2
- package/web/__next._tree.txt +2 -2
- package/web/_next/static/chunks/73d2c788f1076e9a.css +2 -0
- package/web/_next/static/chunks/7d5ab4ba8d474929.js +52 -0
- package/web/_not-found/__next._full.txt +2 -2
- package/web/_not-found/__next._head.txt +1 -1
- package/web/_not-found/__next._index.txt +2 -2
- package/web/_not-found/{__next._not-found.__PAGE__.txt → __next._not-found/__PAGE__.txt} +1 -1
- package/web/_not-found/__next._not-found.txt +1 -1
- package/web/_not-found/__next._tree.txt +2 -2
- package/web/_not-found.html +1 -1
- package/web/_not-found.txt +2 -2
- package/web/index.html +1 -31
- package/web/index.txt +3 -3
- package/web/_next/static/chunks/5922011684321db3.css +0 -2
- package/web/_next/static/chunks/bb819ea11a2befeb.js +0 -49
- /package/web/_next/static/{pPjXTcU0jyBCIxzhfecWl → 2kPL4gOT89qnDZSfX50Rn}/_buildManifest.js +0 -0
- /package/web/_next/static/{pPjXTcU0jyBCIxzhfecWl → 2kPL4gOT89qnDZSfX50Rn}/_clientMiddlewareManifest.json +0 -0
- /package/web/_next/static/{pPjXTcU0jyBCIxzhfecWl → 2kPL4gOT89qnDZSfX50Rn}/_ssgManifest.js +0 -0
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
532507a
|
package/bin/vantaloom-agent
CHANGED
|
Binary file
|
package/bin/vantaloom-api
CHANGED
|
Binary file
|
package/bin/vantaloomctl
CHANGED
|
Binary file
|
package/cli/config.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
2
|
+
"sourceRoot": "D:\\Projects\\Vantaloom-ui",
|
|
3
|
+
"remote": "git@github-vantaloom:Timefiles404/Vantaloom-next.git",
|
|
3
4
|
"repo": "Timefiles404/Vantaloom-next",
|
|
4
5
|
"releaseTag": "runtime-latest",
|
|
5
|
-
"runtimePackage": "@vantaloom/runtime-
|
|
6
|
+
"runtimePackage": "@vantaloom/runtime-win32-x64",
|
|
6
7
|
"runtimeVersion": "latest",
|
|
7
8
|
"npmRegistry": "https://registry.npmjs.org"
|
|
8
9
|
}
|
package/cli/package.json
CHANGED
package/cli/src/cli.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { execFileSync, spawnSync } from "node:child_process"
|
|
2
2
|
import {
|
|
3
|
+
appendFileSync,
|
|
3
4
|
chmodSync,
|
|
4
5
|
existsSync,
|
|
5
6
|
mkdirSync,
|
|
@@ -20,11 +21,45 @@ const installedConfigPath = path.join(cliRoot, "config.json")
|
|
|
20
21
|
const defaultReleaseTag = "runtime-latest"
|
|
21
22
|
const defaultRepo = "Timefiles404/Vantaloom-next"
|
|
22
23
|
const defaultNpmRegistry = "https://registry.npmjs.org"
|
|
24
|
+
const fallbackNpmRegistries = [
|
|
25
|
+
"https://registry.npmmirror.com",
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
// Inherit strict-ssl=false from npm/npx config, or respect NODE_TLS_REJECT_UNAUTHORIZED.
|
|
29
|
+
// When npm runs us via npx with strict-ssl disabled, it sets npm_config_strict_ssl="false".
|
|
30
|
+
// Also check user .npmrc for strict-ssl=false (common in China behind proxies).
|
|
31
|
+
function shouldDisableTLS() {
|
|
32
|
+
if (process.env.NODE_TLS_REJECT_UNAUTHORIZED === "0") return true
|
|
33
|
+
if (process.env.npm_config_strict_ssl === "false") return true
|
|
34
|
+
if (process.env.npm_config_strict_ssl === "") return true
|
|
35
|
+
try {
|
|
36
|
+
const npmrcPath = path.join(os.homedir(), ".npmrc")
|
|
37
|
+
if (existsSync(npmrcPath)) {
|
|
38
|
+
const content = readFileSync(npmrcPath, "utf8")
|
|
39
|
+
if (/^\s*strict-ssl\s*=\s*false/m.test(content)) return true
|
|
40
|
+
}
|
|
41
|
+
} catch {}
|
|
42
|
+
return false
|
|
43
|
+
}
|
|
44
|
+
if (shouldDisableTLS()) {
|
|
45
|
+
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const cliVersion = readJSONIfExists(path.join(cliRoot, "package.json")).version ?? "unknown"
|
|
23
49
|
|
|
24
50
|
export async function main(argv) {
|
|
25
51
|
const command = argv[0] ?? "help"
|
|
26
52
|
const options = parseOptions(argv.slice(1))
|
|
27
53
|
|
|
54
|
+
// --no-strict-ssl flag disables TLS certificate verification for fetch calls
|
|
55
|
+
if (options.noStrictSsl) {
|
|
56
|
+
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (command === "install" || command === "update") {
|
|
60
|
+
console.log(`vantaloom-cli v${cliVersion} (${platformId()})`)
|
|
61
|
+
}
|
|
62
|
+
|
|
28
63
|
switch (command) {
|
|
29
64
|
case "install":
|
|
30
65
|
if (options.package) {
|
|
@@ -91,6 +126,7 @@ async function installFromSource(options) {
|
|
|
91
126
|
|
|
92
127
|
console.log(`${options.update ? "updated" : "installed"} Vantaloom: ${prefix}`)
|
|
93
128
|
console.log(`version: ${version}`)
|
|
129
|
+
ensureInPath(prefix)
|
|
94
130
|
console.log(`run: ${displayCommand(prefix)} status`)
|
|
95
131
|
}
|
|
96
132
|
|
|
@@ -104,16 +140,19 @@ async function installFromPackage(options) {
|
|
|
104
140
|
|
|
105
141
|
console.log(`${options.update ? "updated" : "installed"} Vantaloom: ${prefix}`)
|
|
106
142
|
console.log(`version: ${version}`)
|
|
143
|
+
ensureInPath(prefix)
|
|
107
144
|
console.log(`run: ${displayCommand(prefix)} status`)
|
|
108
145
|
}
|
|
109
146
|
|
|
110
147
|
async function packageRuntime(options) {
|
|
111
148
|
const sourceRoot = findSourceRoot(options.source)
|
|
149
|
+
const targetPlatform = options.target ?? platformId()
|
|
112
150
|
const packageRoot = safeDirectory(
|
|
113
|
-
options.output ?? path.join(sourceRoot, "artifacts", "packages", `vantaloom-${
|
|
151
|
+
options.output ?? path.join(sourceRoot, "artifacts", "packages", `vantaloom-${targetPlatform}`)
|
|
114
152
|
)
|
|
115
153
|
const { platform: builtPlatform, version } = await buildRuntimePackage(sourceRoot, packageRoot, {
|
|
116
154
|
buildWeb: options.buildWeb,
|
|
155
|
+
target: targetPlatform,
|
|
117
156
|
})
|
|
118
157
|
|
|
119
158
|
if (options.npmPackage) {
|
|
@@ -140,16 +179,22 @@ async function packageRuntime(options) {
|
|
|
140
179
|
|
|
141
180
|
async function buildRuntimePackage(sourceRoot, packageRoot, options) {
|
|
142
181
|
const version = gitVersion(sourceRoot)
|
|
143
|
-
const platform = platformId()
|
|
182
|
+
const platform = options.target ?? platformId()
|
|
144
183
|
const buildBin = path.join(packageRoot, "bin")
|
|
145
184
|
const buildWeb = path.join(packageRoot, "web")
|
|
146
185
|
|
|
147
186
|
removeKnownPath(packageRoot, path.dirname(packageRoot))
|
|
148
187
|
mkdirSync(buildBin, { recursive: true })
|
|
149
188
|
|
|
150
|
-
buildGo(sourceRoot, buildBin, "vantaloom-api")
|
|
151
|
-
buildGo(sourceRoot, buildBin, "vantaloom-agent")
|
|
152
|
-
buildGo(sourceRoot, buildBin, "vantaloomctl")
|
|
189
|
+
buildGo(sourceRoot, buildBin, "vantaloom-api", platform)
|
|
190
|
+
buildGo(sourceRoot, buildBin, "vantaloom-agent", platform)
|
|
191
|
+
buildGo(sourceRoot, buildBin, "vantaloomctl", platform)
|
|
192
|
+
// Tray app requires CGO (systray), only buildable natively on Windows.
|
|
193
|
+
if (platform.startsWith("win32") && process.platform === "win32") {
|
|
194
|
+
try {
|
|
195
|
+
buildGo(sourceRoot, buildBin, "vantaloom-tray", platform)
|
|
196
|
+
} catch { /* optional: skip if systray build fails */ }
|
|
197
|
+
}
|
|
153
198
|
|
|
154
199
|
if (options.buildWeb) {
|
|
155
200
|
runPnpm(["--filter", "vantaloom-app", "build"], { cwd: sourceRoot })
|
|
@@ -178,15 +223,49 @@ async function applyPackage(packageRoot, prefix, options) {
|
|
|
178
223
|
spawnSync(existingCtl, ["stop", "--prefix", prefix], { stdio: "inherit" })
|
|
179
224
|
}
|
|
180
225
|
|
|
226
|
+
// Kill lingering tray process that may hold locks on bin/ (older versions
|
|
227
|
+
// don't write tray.pid, so vantaloomctl stop won't find them).
|
|
228
|
+
killTrayProcess(prefix)
|
|
229
|
+
|
|
230
|
+
// Copy package contents to install prefix
|
|
181
231
|
for (const name of ["bin", "web", "cli"]) {
|
|
182
|
-
|
|
183
|
-
|
|
232
|
+
const src = path.join(packageRoot, name)
|
|
233
|
+
const dst = path.join(prefix, name)
|
|
234
|
+
if (!existsSync(src)) {
|
|
235
|
+
console.error(` warning: package missing ${name}/ directory`)
|
|
236
|
+
continue
|
|
237
|
+
}
|
|
238
|
+
removeKnownPath(dst, prefix)
|
|
239
|
+
await cp(src, dst, {
|
|
184
240
|
recursive: true,
|
|
185
241
|
force: true,
|
|
186
242
|
dereference: false,
|
|
187
243
|
})
|
|
188
244
|
}
|
|
189
245
|
|
|
246
|
+
// Ensure binaries are executable on Unix (cross-compiled from Windows they lose +x)
|
|
247
|
+
const binDir = path.join(prefix, "bin")
|
|
248
|
+
if (process.platform !== "win32" && existsSync(binDir)) {
|
|
249
|
+
for (const entry of readdirSync(binDir)) {
|
|
250
|
+
const binPath = path.join(binDir, entry)
|
|
251
|
+
try { chmodSync(binPath, 0o755) } catch {}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Verify vantaloomctl binary exists before trying to run it
|
|
256
|
+
const ctlBin = path.join(prefix, "bin", binaryName("vantaloomctl"))
|
|
257
|
+
if (!existsSync(ctlBin)) {
|
|
258
|
+
const binContents = existsSync(binDir) ? readdirSync(binDir) : []
|
|
259
|
+
const srcBinContents = existsSync(path.join(packageRoot, "bin")) ? readdirSync(path.join(packageRoot, "bin")) : []
|
|
260
|
+
throw new Error(
|
|
261
|
+
`vantaloomctl binary not found at ${ctlBin}\n` +
|
|
262
|
+
` installed bin/: [${binContents.join(", ")}]\n` +
|
|
263
|
+
` package bin/: [${srcBinContents.join(", ")}]\n` +
|
|
264
|
+
` platform: ${platformId()}\n` +
|
|
265
|
+
` This may indicate a corrupt download. Try again or install from source.`
|
|
266
|
+
)
|
|
267
|
+
}
|
|
268
|
+
|
|
190
269
|
await writeLauncher(prefix)
|
|
191
270
|
await writeText(path.join(prefix, "cli", "config.json"), `${JSON.stringify(mergedConfig, null, 2)}\n`)
|
|
192
271
|
await writeText(path.join(prefix, "VERSION"), `${version}\n`)
|
|
@@ -194,7 +273,7 @@ async function applyPackage(packageRoot, prefix, options) {
|
|
|
194
273
|
force: true,
|
|
195
274
|
})
|
|
196
275
|
|
|
197
|
-
run(
|
|
276
|
+
run(ctlBin, [
|
|
198
277
|
"install",
|
|
199
278
|
"--prefix",
|
|
200
279
|
prefix,
|
|
@@ -203,7 +282,7 @@ async function applyPackage(packageRoot, prefix, options) {
|
|
|
203
282
|
])
|
|
204
283
|
|
|
205
284
|
if (!options.noStart) {
|
|
206
|
-
run(
|
|
285
|
+
run(ctlBin, [
|
|
207
286
|
"start",
|
|
208
287
|
"--prefix",
|
|
209
288
|
prefix,
|
|
@@ -216,9 +295,13 @@ async function applyPackage(packageRoot, prefix, options) {
|
|
|
216
295
|
async function syncFromNpmRegistry(options, action) {
|
|
217
296
|
const prefix = safeDirectory(options.prefix ?? defaultPrefix())
|
|
218
297
|
const installedConfig = readInstalledConfig(prefix)
|
|
219
|
-
|
|
298
|
+
// Always derive runtimePackage from current platform — never trust stale config
|
|
299
|
+
// from a different platform (e.g. win32 config baked into a darwin package).
|
|
300
|
+
// Only explicit --runtime-package flag can override.
|
|
301
|
+
const runtimePackage = options.runtimePackage || runtimePackageName(platformId())
|
|
220
302
|
const runtimeVersion = options.runtimeVersion || installedConfig.runtimeVersion || "latest"
|
|
221
|
-
const
|
|
303
|
+
const explicitRegistry = options.npmRegistry || installedConfig.npmRegistry
|
|
304
|
+
const registry = normalizeRegistry(explicitRegistry || detectNpmRegistry() || defaultNpmRegistry)
|
|
222
305
|
const tempRoot = mkdtempSync(path.join(os.tmpdir(), "vantaloom-npm-"))
|
|
223
306
|
|
|
224
307
|
try {
|
|
@@ -226,7 +309,11 @@ async function syncFromNpmRegistry(options, action) {
|
|
|
226
309
|
const archive = path.join(tempRoot, `${packageBasename(runtimePackage)}-${runtimeVersion}.tgz`)
|
|
227
310
|
mkdirSync(extractRoot, { recursive: true })
|
|
228
311
|
|
|
229
|
-
const resolved = await
|
|
312
|
+
const resolved = await resolveNpmPackageWithFallback({
|
|
313
|
+
registries: explicitRegistry ? [registry] : [registry, ...fallbackNpmRegistries.map(normalizeRegistry)],
|
|
314
|
+
name: runtimePackage,
|
|
315
|
+
version: runtimeVersion,
|
|
316
|
+
})
|
|
230
317
|
await downloadNpmTarball({
|
|
231
318
|
tarballUrl: resolved.tarball,
|
|
232
319
|
target: archive,
|
|
@@ -240,13 +327,15 @@ async function syncFromNpmRegistry(options, action) {
|
|
|
240
327
|
noStart: options.noStart,
|
|
241
328
|
runtimePackage,
|
|
242
329
|
runtimeVersion: options.runtimeVersion ? resolved.version : "latest",
|
|
243
|
-
npmRegistry: registry,
|
|
330
|
+
npmRegistry: resolved.registry,
|
|
244
331
|
update: action === "update",
|
|
245
332
|
})
|
|
246
333
|
|
|
247
334
|
console.log(`${action === "update" ? "updated" : "installed"} Vantaloom: ${prefix}`)
|
|
248
335
|
console.log(`version: ${version}`)
|
|
249
336
|
console.log(`source: ${runtimePackage}@${resolved.version}`)
|
|
337
|
+
console.log(`registry: ${resolved.registry}`)
|
|
338
|
+
ensureInPath(prefix)
|
|
250
339
|
console.log(`run: ${displayCommand(prefix)} status`)
|
|
251
340
|
} finally {
|
|
252
341
|
removeKnownPath(tempRoot, os.tmpdir())
|
|
@@ -288,6 +377,7 @@ async function syncFromRelease(options, action) {
|
|
|
288
377
|
console.log(`${action === "update" ? "updated" : "installed"} Vantaloom: ${prefix}`)
|
|
289
378
|
console.log(`version: ${version}`)
|
|
290
379
|
console.log(`source: ${repo}@${releaseTag}`)
|
|
380
|
+
ensureInPath(prefix)
|
|
291
381
|
console.log(`run: ${displayCommand(prefix)} status`)
|
|
292
382
|
} finally {
|
|
293
383
|
removeKnownPath(tempRoot, os.tmpdir())
|
|
@@ -338,14 +428,114 @@ async function downloadReleaseAsset({ repo, releaseTag, assetName, target, token
|
|
|
338
428
|
await writeFile(target, buffer)
|
|
339
429
|
}
|
|
340
430
|
|
|
431
|
+
function detectNpmRegistry() {
|
|
432
|
+
// 1. NPM_CONFIG_REGISTRY env var (highest priority, set by npm/npx when running)
|
|
433
|
+
if (process.env.NPM_CONFIG_REGISTRY) {
|
|
434
|
+
return process.env.npm_config_registry || process.env.NPM_CONFIG_REGISTRY
|
|
435
|
+
}
|
|
436
|
+
// npm also sets the lowercase variant
|
|
437
|
+
if (process.env.npm_config_registry) {
|
|
438
|
+
return process.env.npm_config_registry
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
// 2. Read user .npmrc
|
|
442
|
+
try {
|
|
443
|
+
const npmrcPaths = [
|
|
444
|
+
path.join(os.homedir(), ".npmrc"),
|
|
445
|
+
]
|
|
446
|
+
// Also check project-level .npmrc
|
|
447
|
+
const localNpmrc = path.resolve(".npmrc")
|
|
448
|
+
if (localNpmrc !== npmrcPaths[0]) {
|
|
449
|
+
npmrcPaths.unshift(localNpmrc)
|
|
450
|
+
}
|
|
451
|
+
for (const npmrcPath of npmrcPaths) {
|
|
452
|
+
if (existsSync(npmrcPath)) {
|
|
453
|
+
const content = readFileSync(npmrcPath, "utf8")
|
|
454
|
+
const match = content.match(/^\s*registry\s*=\s*(.+)/m)
|
|
455
|
+
if (match) {
|
|
456
|
+
return match[1].trim()
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
} catch {
|
|
461
|
+
// Ignore .npmrc read errors
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
return ""
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
async function resolveNpmPackageWithFallback({ registries, name, version }) {
|
|
468
|
+
const errors = []
|
|
469
|
+
for (const registry of registries) {
|
|
470
|
+
try {
|
|
471
|
+
const result = await resolveNpmPackage({ registry, name, version })
|
|
472
|
+
return { ...result, registry }
|
|
473
|
+
} catch (error) {
|
|
474
|
+
const causeCode = error?.cause?.code || ""
|
|
475
|
+
const isNetworkError = causeCode === "ECONNREFUSED"
|
|
476
|
+
|| causeCode === "ENOTFOUND"
|
|
477
|
+
|| causeCode === "ETIMEDOUT"
|
|
478
|
+
|| causeCode === "ECONNRESET"
|
|
479
|
+
|| causeCode === "UND_ERR_CONNECT_TIMEOUT"
|
|
480
|
+
|| (error instanceof TypeError && error.message === "fetch failed")
|
|
481
|
+
const isSslError = causeCode === "UNABLE_TO_GET_ISSUER_CERT_LOCALLY"
|
|
482
|
+
|| causeCode === "CERT_HAS_EXPIRED"
|
|
483
|
+
|| causeCode === "DEPTH_ZERO_SELF_SIGNED_CERT"
|
|
484
|
+
|| causeCode === "SELF_SIGNED_CERT_IN_CHAIN"
|
|
485
|
+
|| causeCode === "ERR_TLS_CERT_ALTNAME_INVALID"
|
|
486
|
+
const isRetryable = isNetworkError || isSslError
|
|
487
|
+
errors.push({ registry, error, isRetryable, isSslError })
|
|
488
|
+
|
|
489
|
+
if (isRetryable && registries.length > 1) {
|
|
490
|
+
const hint = isSslError ? " (SSL certificate error)" : ""
|
|
491
|
+
console.error(`vantaloom: ${registry} unreachable${hint}, trying next registry...`)
|
|
492
|
+
continue
|
|
493
|
+
}
|
|
494
|
+
if (isSslError) {
|
|
495
|
+
throw new Error(
|
|
496
|
+
`SSL certificate error connecting to ${registry}: ${causeCode}\n` +
|
|
497
|
+
` Fix: run with --no-strict-ssl, or set npm config: npm config set strict-ssl false`
|
|
498
|
+
)
|
|
499
|
+
}
|
|
500
|
+
// Non-network error (404, parse error, etc.) — don't try fallbacks
|
|
501
|
+
throw error
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
// All registries failed
|
|
506
|
+
const hasSslError = errors.some((e) => e.isSslError)
|
|
507
|
+
const tried = errors.map((e) => e.registry).join(", ")
|
|
508
|
+
const sslHint = hasSslError
|
|
509
|
+
? `\n SSL fix: run with --no-strict-ssl, or set npm config: npm config set strict-ssl false`
|
|
510
|
+
: ""
|
|
511
|
+
throw new Error(
|
|
512
|
+
`all registries unreachable (tried: ${tried}). ` +
|
|
513
|
+
`Check your network or specify --npm-registry <url>${sslHint}`
|
|
514
|
+
)
|
|
515
|
+
}
|
|
516
|
+
|
|
341
517
|
async function resolveNpmPackage({ registry, name, version }) {
|
|
342
518
|
const metadataUrl = `${registry}/${encodeURIComponent(name).replace("%2F", "%2f")}`
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
519
|
+
let response
|
|
520
|
+
try {
|
|
521
|
+
response = await fetch(metadataUrl, {
|
|
522
|
+
headers: {
|
|
523
|
+
Accept: "application/vnd.npm.install-v1+json",
|
|
524
|
+
"User-Agent": "vantaloom-cli",
|
|
525
|
+
},
|
|
526
|
+
signal: AbortSignal.timeout(15000),
|
|
527
|
+
})
|
|
528
|
+
} catch (error) {
|
|
529
|
+
if (error instanceof TypeError && error.message === "fetch failed") {
|
|
530
|
+
const causeCode = error.cause?.code || ""
|
|
531
|
+
const causeMsg = causeCode || error.cause?.message || String(error.cause || "")
|
|
532
|
+
throw Object.assign(
|
|
533
|
+
new Error(`cannot reach registry ${registry} (${causeMsg})`),
|
|
534
|
+
{ cause: error.cause }
|
|
535
|
+
)
|
|
536
|
+
}
|
|
537
|
+
throw error
|
|
538
|
+
}
|
|
349
539
|
if (!response.ok) {
|
|
350
540
|
const detail = await response.text().catch(() => "")
|
|
351
541
|
throw new Error(`failed to inspect npm package ${name}: HTTP ${response.status}${detail ? ` ${detail.slice(0, 200)}` : ""}`)
|
|
@@ -365,11 +555,22 @@ async function resolveNpmPackage({ registry, name, version }) {
|
|
|
365
555
|
}
|
|
366
556
|
|
|
367
557
|
async function downloadNpmTarball({ tarballUrl, target, packageName, version }) {
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
558
|
+
console.log(` downloading ${packageName}@${version}...`)
|
|
559
|
+
let response
|
|
560
|
+
try {
|
|
561
|
+
response = await fetch(tarballUrl, {
|
|
562
|
+
headers: {
|
|
563
|
+
"User-Agent": "vantaloom-cli",
|
|
564
|
+
},
|
|
565
|
+
signal: AbortSignal.timeout(120000),
|
|
566
|
+
})
|
|
567
|
+
} catch (error) {
|
|
568
|
+
const causeCode = error?.cause?.code || ""
|
|
569
|
+
const causeMsg = causeCode || error?.cause?.message || error.message || ""
|
|
570
|
+
const isSsl = causeCode.includes("CERT") || causeCode === "UNABLE_TO_GET_ISSUER_CERT_LOCALLY"
|
|
571
|
+
const hint = isSsl ? `\n Fix: run with --no-strict-ssl` : ""
|
|
572
|
+
throw new Error(`failed to download ${packageName}@${version} from ${tarballUrl}: ${causeMsg}${hint}`)
|
|
573
|
+
}
|
|
373
574
|
if (!response.ok) {
|
|
374
575
|
const detail = await response.text().catch(() => "")
|
|
375
576
|
throw new Error(`failed to download ${packageName}@${version}: HTTP ${response.status}${detail ? ` ${detail.slice(0, 200)}` : ""}`)
|
|
@@ -377,6 +578,7 @@ async function downloadNpmTarball({ tarballUrl, target, packageName, version })
|
|
|
377
578
|
|
|
378
579
|
const buffer = Buffer.from(await response.arrayBuffer())
|
|
379
580
|
await writeFile(target, buffer)
|
|
581
|
+
console.log(` downloaded ${(buffer.length / 1024 / 1024).toFixed(1)} MB`)
|
|
380
582
|
}
|
|
381
583
|
|
|
382
584
|
function shouldUseSourceInstall(options) {
|
|
@@ -440,9 +642,9 @@ function mergeRuntimeConfig(packageConfig, existingConfig, overrides) {
|
|
|
440
642
|
if (!merged.releaseTag) {
|
|
441
643
|
merged.releaseTag = defaultReleaseTag
|
|
442
644
|
}
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
645
|
+
// Always force runtimePackage to match the running platform — a cross-compiled
|
|
646
|
+
// package may carry a config for a different platform (e.g. win32 inside darwin).
|
|
647
|
+
merged.runtimePackage = runtimePackageName(platformId())
|
|
446
648
|
if (!merged.runtimeVersion) {
|
|
447
649
|
merged.runtimeVersion = "latest"
|
|
448
650
|
}
|
|
@@ -462,7 +664,7 @@ function runtimeConfigFromSource(sourceRoot) {
|
|
|
462
664
|
releaseTag: defaultReleaseTag,
|
|
463
665
|
runtimePackage: runtimePackageName(platformId()),
|
|
464
666
|
runtimeVersion: "latest",
|
|
465
|
-
npmRegistry: defaultNpmRegistry,
|
|
667
|
+
npmRegistry: detectNpmRegistry() || defaultNpmRegistry,
|
|
466
668
|
}
|
|
467
669
|
}
|
|
468
670
|
|
|
@@ -598,13 +800,20 @@ function printPaths(options) {
|
|
|
598
800
|
console.log(JSON.stringify({ sourceRoot, prefix }, null, 2))
|
|
599
801
|
}
|
|
600
802
|
|
|
601
|
-
function buildGo(sourceRoot, buildBin, name) {
|
|
803
|
+
function buildGo(sourceRoot, buildBin, name, targetPlatform) {
|
|
804
|
+
const goEnv = targetPlatform ? platformToGoEnv(targetPlatform) : {}
|
|
805
|
+
const isWindowsTarget = targetPlatform
|
|
806
|
+
? targetPlatform.startsWith("win32")
|
|
807
|
+
: process.platform === "win32"
|
|
808
|
+
const ext = isWindowsTarget ? ".exe" : ""
|
|
809
|
+
const ldflags = name === "vantaloom-tray" ? "-s -w -H windowsgui" : "-s -w"
|
|
602
810
|
run("go", [
|
|
603
811
|
"build",
|
|
812
|
+
"-ldflags", ldflags,
|
|
604
813
|
"-o",
|
|
605
|
-
path.join(buildBin,
|
|
814
|
+
path.join(buildBin, `${name}${ext}`),
|
|
606
815
|
`./apps/api/cmd/${name}`,
|
|
607
|
-
], { cwd: sourceRoot })
|
|
816
|
+
], { cwd: sourceRoot, env: { ...process.env, ...goEnv } })
|
|
608
817
|
}
|
|
609
818
|
|
|
610
819
|
async function copyDir(source, destination, options = {}) {
|
|
@@ -621,6 +830,10 @@ async function copyDir(source, destination, options = {}) {
|
|
|
621
830
|
}
|
|
622
831
|
|
|
623
832
|
function writeBuildManifest(buildRoot, version, platform) {
|
|
833
|
+
const components = ["api", "agent", "web", "ctl"]
|
|
834
|
+
if (platform.startsWith("win32")) {
|
|
835
|
+
components.push("tray")
|
|
836
|
+
}
|
|
624
837
|
writeFileSync(path.join(buildRoot, "VERSION"), `${version}\n`)
|
|
625
838
|
writeFileSync(
|
|
626
839
|
path.join(buildRoot, "manifest.json"),
|
|
@@ -630,7 +843,7 @@ function writeBuildManifest(buildRoot, version, platform) {
|
|
|
630
843
|
version,
|
|
631
844
|
platform,
|
|
632
845
|
updatedAt: new Date().toISOString(),
|
|
633
|
-
components
|
|
846
|
+
components,
|
|
634
847
|
},
|
|
635
848
|
null,
|
|
636
849
|
2
|
|
@@ -748,9 +961,18 @@ function parseOptions(args) {
|
|
|
748
961
|
case "npm-package":
|
|
749
962
|
options.npmPackage = true
|
|
750
963
|
break
|
|
964
|
+
case "target":
|
|
965
|
+
options.target = inlineValue ?? args[++index]
|
|
966
|
+
if (!options.target) {
|
|
967
|
+
throw new Error("missing value for --target")
|
|
968
|
+
}
|
|
969
|
+
break
|
|
751
970
|
case "local":
|
|
752
971
|
options.local = true
|
|
753
972
|
break
|
|
973
|
+
case "no-strict-ssl":
|
|
974
|
+
options.noStrictSsl = true
|
|
975
|
+
break
|
|
754
976
|
default:
|
|
755
977
|
throw new Error(`unknown option --${key}`)
|
|
756
978
|
}
|
|
@@ -799,8 +1021,22 @@ function runPnpm(args, options = {}) {
|
|
|
799
1021
|
run("pnpm", args, options)
|
|
800
1022
|
}
|
|
801
1023
|
|
|
802
|
-
function binaryName(name) {
|
|
803
|
-
|
|
1024
|
+
function binaryName(name, targetPlatform) {
|
|
1025
|
+
const isWindows = targetPlatform
|
|
1026
|
+
? targetPlatform.startsWith("win32")
|
|
1027
|
+
: process.platform === "win32"
|
|
1028
|
+
return isWindows ? `${name}.exe` : name
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
function platformToGoEnv(platform) {
|
|
1032
|
+
const { os: runtimeOS, cpu } = parsePlatformId(platform)
|
|
1033
|
+
const goosMap = { win32: "windows", linux: "linux", darwin: "darwin" }
|
|
1034
|
+
const goarchMap = { x64: "amd64", arm64: "arm64" }
|
|
1035
|
+
return {
|
|
1036
|
+
GOOS: goosMap[runtimeOS] ?? runtimeOS,
|
|
1037
|
+
GOARCH: goarchMap[cpu] ?? cpu,
|
|
1038
|
+
CGO_ENABLED: "0",
|
|
1039
|
+
}
|
|
804
1040
|
}
|
|
805
1041
|
|
|
806
1042
|
function platformId() {
|
|
@@ -858,6 +1094,92 @@ async function writeText(filePath, content) {
|
|
|
858
1094
|
await writeFile(filePath, content)
|
|
859
1095
|
}
|
|
860
1096
|
|
|
1097
|
+
// ensureInPath adds the Vantaloom install directory to the user's shell PATH
|
|
1098
|
+
// on macOS and Linux, so `vantaloom` can be run directly after install.
|
|
1099
|
+
// On Windows this is not needed (vantaloom.cmd is run by full path or added via installer).
|
|
1100
|
+
function ensureInPath(prefix) {
|
|
1101
|
+
if (process.platform === "win32") return
|
|
1102
|
+
|
|
1103
|
+
// Check if already in PATH
|
|
1104
|
+
const pathDirs = (process.env.PATH || "").split(":")
|
|
1105
|
+
if (pathDirs.includes(prefix)) return
|
|
1106
|
+
|
|
1107
|
+
// Determine shell profile file
|
|
1108
|
+
const home = os.homedir()
|
|
1109
|
+
const shell = process.env.SHELL || ""
|
|
1110
|
+
let profilePath
|
|
1111
|
+
if (shell.endsWith("/zsh") || existsSync(path.join(home, ".zshrc"))) {
|
|
1112
|
+
profilePath = path.join(home, ".zshrc")
|
|
1113
|
+
} else if (shell.endsWith("/bash")) {
|
|
1114
|
+
// On macOS, bash uses .bash_profile; on Linux, .bashrc
|
|
1115
|
+
profilePath = process.platform === "darwin"
|
|
1116
|
+
? path.join(home, ".bash_profile")
|
|
1117
|
+
: path.join(home, ".bashrc")
|
|
1118
|
+
} else if (existsSync(path.join(home, ".profile"))) {
|
|
1119
|
+
profilePath = path.join(home, ".profile")
|
|
1120
|
+
} else {
|
|
1121
|
+
profilePath = path.join(home, ".profile")
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
// Use $HOME-relative path for portability
|
|
1125
|
+
const homeRelative = prefix.startsWith(home)
|
|
1126
|
+
? `$HOME${prefix.slice(home.length)}`
|
|
1127
|
+
: prefix
|
|
1128
|
+
const exportLine = `export PATH="${homeRelative}:$PATH"`
|
|
1129
|
+
const marker = "# vantaloom"
|
|
1130
|
+
|
|
1131
|
+
// Check if already added to profile
|
|
1132
|
+
try {
|
|
1133
|
+
if (existsSync(profilePath)) {
|
|
1134
|
+
const content = readFileSync(profilePath, "utf8")
|
|
1135
|
+
if (content.includes("vantaloom") && content.includes("PATH")) return
|
|
1136
|
+
}
|
|
1137
|
+
} catch {}
|
|
1138
|
+
|
|
1139
|
+
// Append to profile
|
|
1140
|
+
try {
|
|
1141
|
+
const entry = `\n${marker}\n${exportLine}\n`
|
|
1142
|
+
appendFileSync(profilePath, entry)
|
|
1143
|
+
console.log(`PATH: added ${prefix} to ${profilePath}`)
|
|
1144
|
+
console.log(` run: source ${profilePath} (or open a new terminal)`)
|
|
1145
|
+
} catch (error) {
|
|
1146
|
+
console.log(`PATH: could not update ${profilePath}: ${error.message}`)
|
|
1147
|
+
console.log(` add manually: ${exportLine}`)
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
function killTrayProcess(prefix) {
|
|
1152
|
+
if (process.platform === "win32") {
|
|
1153
|
+
// Try PID file first (new tray versions write runtime/tray.pid).
|
|
1154
|
+
const pidFile = path.join(prefix, "runtime", "tray.pid")
|
|
1155
|
+
if (existsSync(pidFile)) {
|
|
1156
|
+
const pid = readFileSync(pidFile, "utf8").trim()
|
|
1157
|
+
if (pid) {
|
|
1158
|
+
spawnSync("taskkill", ["/PID", pid, "/F"], { stdio: "ignore" })
|
|
1159
|
+
try { rmSync(pidFile, { force: true }) } catch {}
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
// Fallback: kill by image name if the binary is inside our prefix.
|
|
1163
|
+
const result = spawnSync("tasklist", ["/FI", "IMAGENAME eq vantaloom-tray.exe", "/FO", "CSV", "/NH"], {
|
|
1164
|
+
encoding: "utf8",
|
|
1165
|
+
windowsHide: true,
|
|
1166
|
+
})
|
|
1167
|
+
if (result.stdout) {
|
|
1168
|
+
for (const line of result.stdout.split("\n")) {
|
|
1169
|
+
const match = line.match(/"vantaloom-tray\.exe","(\d+)"/)
|
|
1170
|
+
if (match) {
|
|
1171
|
+
spawnSync("taskkill", ["/PID", match[1], "/F"], { stdio: "ignore" })
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
// Brief pause to let file handles release.
|
|
1176
|
+
spawnSync("timeout", ["/t", "1", "/nobreak"], { stdio: "ignore", windowsHide: true })
|
|
1177
|
+
} else {
|
|
1178
|
+
// Unix: pkill by name (best-effort).
|
|
1179
|
+
spawnSync("pkill", ["-f", "vantaloom-tray"], { stdio: "ignore" })
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
|
|
861
1183
|
function printHelp() {
|
|
862
1184
|
console.log(`Vantaloom CLI
|
|
863
1185
|
|
|
@@ -866,7 +1188,7 @@ Usage:
|
|
|
866
1188
|
vantaloom install --local [--prefix <dir>] [--source <repo>] [--build-web] [--no-start]
|
|
867
1189
|
vantaloom update [--prefix <dir>] [--runtime-version <version>] [--npm-registry <url>] [--no-start]
|
|
868
1190
|
vantaloom update --local [--prefix <dir>] [--source <repo>] [--build-web] [--no-start]
|
|
869
|
-
vantaloom package [--source <repo>] [--output <dir>] [--build-web] [--archive] [--npm-package]
|
|
1191
|
+
vantaloom package [--source <repo>] [--output <dir>] [--build-web] [--archive] [--npm-package] [--target <platform>]
|
|
870
1192
|
vantaloom start [--prefix <dir>] [--component all|api|agent|web]
|
|
871
1193
|
vantaloom stop [--prefix <dir>] [--component all|api|agent|web]
|
|
872
1194
|
vantaloom restart [--prefix <dir>] [--component all|api|agent|web]
|
package/manifest.json
CHANGED