@vantaloom/runtime-darwin-arm64 0.12.49 → 0.12.50
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/vantaloom-browser +0 -0
- package/bin/vantaloomctl +0 -0
- package/cli/package.json +1 -1
- package/cli/src/cli.mjs +460 -2100
- package/cli/src/lib/auth.mjs +155 -0
- package/cli/src/lib/constants.mjs +34 -0
- package/cli/src/lib/install.mjs +627 -0
- package/cli/src/lib/lifecycle.mjs +187 -0
- package/cli/src/lib/mesh.mjs +236 -0
- package/cli/src/lib/package.mjs +206 -0
- package/cli/src/lib/platform.mjs +165 -0
- package/cli/src/lib/registry.mjs +237 -0
- package/manifest.json +2 -2
- package/package.json +1 -1
- package/web/404.html +1 -1
- package/web/__next.__PAGE__.txt +1 -1
- package/web/__next._full.txt +1 -1
- package/web/__next._head.txt +1 -1
- package/web/__next._index.txt +1 -1
- package/web/__next._tree.txt +1 -1
- package/web/_not-found/__next._full.txt +1 -1
- package/web/_not-found/__next._head.txt +1 -1
- package/web/_not-found/__next._index.txt +1 -1
- package/web/_not-found/__next._not-found/__PAGE__.txt +1 -1
- package/web/_not-found/__next._not-found.txt +1 -1
- package/web/_not-found/__next._tree.txt +1 -1
- package/web/_not-found.html +1 -1
- package/web/_not-found.txt +1 -1
- package/web/index.html +1 -1
- package/web/index.txt +1 -1
- /package/web/_next/static/{jpoLF2PZ-dWfDd5NxkZG0 → fdvtf4murB4YOO6QLnYED}/_buildManifest.js +0 -0
- /package/web/_next/static/{jpoLF2PZ-dWfDd5NxkZG0 → fdvtf4murB4YOO6QLnYED}/_clientMiddlewareManifest.json +0 -0
- /package/web/_next/static/{jpoLF2PZ-dWfDd5NxkZG0 → fdvtf4murB4YOO6QLnYED}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import {
|
|
2
|
+
existsSync,
|
|
3
|
+
readFileSync,
|
|
4
|
+
} from "node:fs"
|
|
5
|
+
import os from "node:os"
|
|
6
|
+
import path from "node:path"
|
|
7
|
+
import readline from "node:readline"
|
|
8
|
+
import { DEFAULT_HUB_URL } from "./constants.mjs"
|
|
9
|
+
import {
|
|
10
|
+
readJSONIfExists,
|
|
11
|
+
safeDirectory,
|
|
12
|
+
defaultPrefix,
|
|
13
|
+
} from "./platform.mjs"
|
|
14
|
+
|
|
15
|
+
export function localApiBase(prefix) {
|
|
16
|
+
let port
|
|
17
|
+
try {
|
|
18
|
+
port = readFileSync(path.join(prefix, "runtime", "api.port"), "utf8").trim()
|
|
19
|
+
} catch {}
|
|
20
|
+
if (!port) {
|
|
21
|
+
const cfg = readJSONIfExists(path.join(prefix, "config", "local.json"))
|
|
22
|
+
port = cfg.apiPort ? String(cfg.apiPort) : "8780"
|
|
23
|
+
}
|
|
24
|
+
return `http://127.0.0.1:${port}`
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function localMachineInfo() {
|
|
28
|
+
const platMap = { win32: "windows", darwin: "darwin", linux: "linux" }
|
|
29
|
+
const archMap = { x64: "amd64", arm64: "arm64" }
|
|
30
|
+
return {
|
|
31
|
+
name: `${platMap[process.platform] ?? process.platform}-${os.hostname() || "unknown"}`,
|
|
32
|
+
platform: platMap[process.platform] ?? process.platform,
|
|
33
|
+
arch: archMap[process.arch] ?? process.arch,
|
|
34
|
+
localIp: "127.0.0.1",
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export async function hubFetch(url, { method = "GET", body, token } = {}) {
|
|
39
|
+
const headers = { "Content-Type": "application/json" }
|
|
40
|
+
if (token) headers.Authorization = `Bearer ${token}`
|
|
41
|
+
const res = await fetch(url, {
|
|
42
|
+
method,
|
|
43
|
+
headers,
|
|
44
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
45
|
+
})
|
|
46
|
+
const data = await res.json().catch(() => ({}))
|
|
47
|
+
if (!res.ok) {
|
|
48
|
+
throw new Error(data.error || `${url}: HTTP ${res.status}`)
|
|
49
|
+
}
|
|
50
|
+
return data
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function promptVisible(query) {
|
|
54
|
+
return new Promise((resolve) => {
|
|
55
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout })
|
|
56
|
+
rl.question(query, (answer) => {
|
|
57
|
+
rl.close()
|
|
58
|
+
resolve(answer.trim())
|
|
59
|
+
})
|
|
60
|
+
})
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function promptHidden(query) {
|
|
64
|
+
return new Promise((resolve) => {
|
|
65
|
+
const rl = readline.createInterface({
|
|
66
|
+
input: process.stdin,
|
|
67
|
+
output: process.stdout,
|
|
68
|
+
terminal: true,
|
|
69
|
+
})
|
|
70
|
+
process.stdout.write(query)
|
|
71
|
+
// Suppress echo so the password isn't shown as it's typed.
|
|
72
|
+
rl._writeToOutput = () => {}
|
|
73
|
+
rl.question("", (answer) => {
|
|
74
|
+
rl.close()
|
|
75
|
+
process.stdout.write("\n")
|
|
76
|
+
resolve(answer)
|
|
77
|
+
})
|
|
78
|
+
})
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export async function runLogin(options) {
|
|
82
|
+
const prefix = safeDirectory(options.prefix ?? defaultPrefix())
|
|
83
|
+
const existing = readJSONIfExists(path.join(prefix, "config", "local.json"))
|
|
84
|
+
const hubUrl = (options.hub ?? existing.hubUrl ?? DEFAULT_HUB_URL).replace(/\/+$/, "")
|
|
85
|
+
const localApi = localApiBase(prefix)
|
|
86
|
+
|
|
87
|
+
// The local runtime must be running: we need its stable hardware id (so the
|
|
88
|
+
// Hub dedups re-registrations) and it's what actually connects to the Hub.
|
|
89
|
+
let hardwareId = null
|
|
90
|
+
try {
|
|
91
|
+
const res = await fetch(`${localApi}/v1/hub/status`)
|
|
92
|
+
if (res.ok) hardwareId = (await res.json()).hardwareId ?? null
|
|
93
|
+
} catch {}
|
|
94
|
+
if (!hardwareId) {
|
|
95
|
+
throw new Error(
|
|
96
|
+
`local runtime not reachable at ${localApi}. Start it first with "vantaloom start", then retry "vantaloom login".`
|
|
97
|
+
)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const email = options.email ?? (await promptVisible("Hub email: "))
|
|
101
|
+
const password = options.password ?? (await promptHidden("Hub password: "))
|
|
102
|
+
if (!email || !password) {
|
|
103
|
+
throw new Error("email and password are required")
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
console.log(`logging in to ${hubUrl} ...`)
|
|
107
|
+
const login = await hubFetch(`${hubUrl}/api/auth/login`, {
|
|
108
|
+
method: "POST",
|
|
109
|
+
body: { email, password },
|
|
110
|
+
})
|
|
111
|
+
const userToken = login.token
|
|
112
|
+
if (!userToken) throw new Error("login failed: no token returned")
|
|
113
|
+
|
|
114
|
+
const { deviceToken } = await hubFetch(`${hubUrl}/api/machines/token`, {
|
|
115
|
+
method: "POST",
|
|
116
|
+
token: userToken,
|
|
117
|
+
})
|
|
118
|
+
const info = localMachineInfo()
|
|
119
|
+
const connect = await hubFetch(`${hubUrl}/api/connect`, {
|
|
120
|
+
method: "POST",
|
|
121
|
+
body: { deviceToken, hardwareId, ...info },
|
|
122
|
+
})
|
|
123
|
+
const machineId = connect.machine?.id
|
|
124
|
+
if (!machineId) throw new Error("machine registration failed: no machine id")
|
|
125
|
+
|
|
126
|
+
// Hand the credentials to the running runtime; it persists them to local.json
|
|
127
|
+
// and brings up the Hub WebSocket + heartbeat + mesh.
|
|
128
|
+
const res = await fetch(`${localApi}/v1/hub/connect`, {
|
|
129
|
+
method: "POST",
|
|
130
|
+
headers: { "Content-Type": "application/json" },
|
|
131
|
+
body: JSON.stringify({ hubUrl, hubToken: userToken, machineId }),
|
|
132
|
+
})
|
|
133
|
+
if (!res.ok) {
|
|
134
|
+
throw new Error(`runtime failed to connect to Hub: HTTP ${res.status}`)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
console.log(`\n✓ logged in as ${login.user?.email ?? email}`)
|
|
138
|
+
console.log(`✓ machine registered: ${info.name} (${machineId})`)
|
|
139
|
+
console.log(`✓ runtime connected to Hub at ${hubUrl}`)
|
|
140
|
+
console.log(`\nThis machine is now in your workgroup. It will reconnect automatically on restart.`)
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export async function runLogout(options) {
|
|
144
|
+
const prefix = safeDirectory(options.prefix ?? defaultPrefix())
|
|
145
|
+
const localApi = localApiBase(prefix)
|
|
146
|
+
try {
|
|
147
|
+
const res = await fetch(`${localApi}/v1/hub/disconnect`, { method: "POST" })
|
|
148
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`)
|
|
149
|
+
console.log("✓ disconnected from Hub (runtime keeps running locally).")
|
|
150
|
+
} catch (error) {
|
|
151
|
+
throw new Error(
|
|
152
|
+
`could not reach local runtime at ${localApi}: ${error.message}`
|
|
153
|
+
)
|
|
154
|
+
}
|
|
155
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import path from "node:path"
|
|
2
|
+
import { fileURLToPath } from "node:url"
|
|
3
|
+
|
|
4
|
+
export const cliRoot = path.resolve(fileURLToPath(import.meta.url), "..", "..", "..")
|
|
5
|
+
export const repoCandidate = path.resolve(cliRoot, "..", "..")
|
|
6
|
+
export const installedConfigPath = path.join(cliRoot, "config.json")
|
|
7
|
+
export const defaultReleaseTag = "runtime-latest"
|
|
8
|
+
export const defaultRepo = "Timefiles404/Vantaloom-next"
|
|
9
|
+
export const defaultNpmRegistry = "https://registry.npmjs.org"
|
|
10
|
+
export const fallbackNpmRegistries = [
|
|
11
|
+
"https://registry.npmmirror.com",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
// The mesh binaries the privileged service holds open while running. On Windows
|
|
15
|
+
// a file copy can't overwrite them in place, so the lock-safe `apply` path swaps
|
|
16
|
+
// them after stopping the service.
|
|
17
|
+
export const WINDOWS_MESH_BINARIES = ["easytier-core.exe", "easytier-cli.exe", "wintun.dll", "Packet.dll", "WinDivert64.sys", "vantaloom-mesh.exe"]
|
|
18
|
+
|
|
19
|
+
export const LOCK_ERROR_CODES = new Set(["EPERM", "EBUSY", "EACCES", "ETXTBSY"])
|
|
20
|
+
|
|
21
|
+
// ── Hub login (headless / no-web) ──
|
|
22
|
+
export const DEFAULT_HUB_URL = "http://vanta.timefiles.online"
|
|
23
|
+
|
|
24
|
+
// ── Runtime login-autostart (no elevation) ──
|
|
25
|
+
// Start the local runtime (api/agent/web/tray) at login/boot using only
|
|
26
|
+
// per-user mechanisms — no UAC/sudo. This is separate from the privileged mesh
|
|
27
|
+
// service: the mesh sidecar autostarts via the OS service manager; this brings
|
|
28
|
+
// up the unprivileged runtime that joins the mesh and serves the local API.
|
|
29
|
+
export const AUTOSTART_LABEL = "online.timefiles.vantaloom.runtime"
|
|
30
|
+
// PowerShell HKCU: drive path. Set-ItemProperty handles values with spaces and
|
|
31
|
+
// embedded quotes cleanly (reg.exe's /d escaping is brittle), and the Run key is
|
|
32
|
+
// not blocked by Controlled Folder Access the way the Startup folder is.
|
|
33
|
+
export const WINDOWS_RUN_KEY = "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"
|
|
34
|
+
export const WINDOWS_RUN_VALUE = "Vantaloom"
|