baro-ai 0.118.6 → 0.118.7
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/bin/baro +14 -2
- package/bin/self-update.mjs +122 -0
- package/dist/runner.mjs +1 -1
- package/package.json +1 -1
- package/scripts/postinstall.js +11 -2
package/bin/baro
CHANGED
|
@@ -3,9 +3,21 @@
|
|
|
3
3
|
// shebang, and a #!/bin/sh bin makes the Windows shim invoke sh.exe (absent on
|
|
4
4
|
// Windows). A node shebang yields correct cmd/ps1/sh shims on every platform.
|
|
5
5
|
import { spawnSync } from "node:child_process"
|
|
6
|
-
import { existsSync } from "node:fs"
|
|
6
|
+
import { existsSync, readFileSync } from "node:fs"
|
|
7
7
|
import { homedir } from "node:os"
|
|
8
8
|
import path from "node:path"
|
|
9
|
+
import { fileURLToPath } from "node:url"
|
|
10
|
+
|
|
11
|
+
import { selfUpdate } from "./self-update.mjs"
|
|
12
|
+
|
|
13
|
+
const argv = process.argv.slice(2)
|
|
14
|
+
try {
|
|
15
|
+
const packageJson = path.join(path.dirname(fileURLToPath(import.meta.url)), "..", "package.json")
|
|
16
|
+
const packageVersion = JSON.parse(readFileSync(packageJson, "utf8")).version
|
|
17
|
+
await selfUpdate({ packageVersion, argv })
|
|
18
|
+
} catch {
|
|
19
|
+
// An update that cannot be attempted never stops baro from starting.
|
|
20
|
+
}
|
|
9
21
|
|
|
10
22
|
const bin = path.join(
|
|
11
23
|
homedir(),
|
|
@@ -19,7 +31,7 @@ if (!existsSync(bin)) {
|
|
|
19
31
|
process.exit(1)
|
|
20
32
|
}
|
|
21
33
|
|
|
22
|
-
const result = spawnSync(bin,
|
|
34
|
+
const result = spawnSync(bin, argv, { stdio: "inherit" })
|
|
23
35
|
if (result.error) {
|
|
24
36
|
console.error(`baro: failed to launch binary: ${result.error.message}`)
|
|
25
37
|
process.exit(1)
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
// A hand-started baro brings itself up to date before it runs. The runner
|
|
2
|
+
// already did this for services; a person running `baro` stayed on whatever
|
|
3
|
+
// they had installed until they noticed the banner.
|
|
4
|
+
import { spawnSync } from "node:child_process"
|
|
5
|
+
import { mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs"
|
|
6
|
+
import { homedir } from "node:os"
|
|
7
|
+
import path from "node:path"
|
|
8
|
+
|
|
9
|
+
const CACHE_TTL_MS = 3 * 3600_000
|
|
10
|
+
const FETCH_TIMEOUT_MS = 2500
|
|
11
|
+
const QUICK_COMMANDS = new Set(["--version", "-V", "--help", "-h", "connect"])
|
|
12
|
+
|
|
13
|
+
export function semverLt(a, b) {
|
|
14
|
+
const parts = (v) => String(v).split(".").map((x) => Number.parseInt(x, 10) || 0)
|
|
15
|
+
const [pa, pb] = [parts(a), parts(b)]
|
|
16
|
+
for (let i = 0; i < 3; i++) {
|
|
17
|
+
if ((pa[i] ?? 0) !== (pb[i] ?? 0)) return (pa[i] ?? 0) < (pb[i] ?? 0)
|
|
18
|
+
}
|
|
19
|
+
return false
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Why this invocation must not update, or null when it may. Automation keeps
|
|
24
|
+
* the version it was given; the runner updates itself between runs; and the
|
|
25
|
+
* staged bundles are shared, so replacing them under a live run breaks it.
|
|
26
|
+
*/
|
|
27
|
+
export function skipReason({ argv, env, isTTY, liveRuns }) {
|
|
28
|
+
if (env.BARO_NO_SELF_UPDATE === "1") return "BARO_NO_SELF_UPDATE=1"
|
|
29
|
+
if (env.CI) return "CI"
|
|
30
|
+
if (!isTTY) return "not a terminal"
|
|
31
|
+
if (argv.includes("--headless")) return "headless"
|
|
32
|
+
if (argv.some((arg) => QUICK_COMMANDS.has(arg))) return "quick command"
|
|
33
|
+
if (liveRuns > 0) return "another baro run is active"
|
|
34
|
+
return null
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function baroHome() {
|
|
38
|
+
return path.join(homedir(), ".baro")
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function readJson(file) {
|
|
42
|
+
try {
|
|
43
|
+
return JSON.parse(readFileSync(file, "utf8"))
|
|
44
|
+
} catch {
|
|
45
|
+
return null
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** The version the binary and its bundles are actually staged at. */
|
|
50
|
+
export function installedVersion(packageVersion) {
|
|
51
|
+
return readJson(path.join(baroHome(), "bin", "bundle-version.json"))?.version ?? packageVersion
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function liveRunCount() {
|
|
55
|
+
try {
|
|
56
|
+
const dir = path.join(baroHome(), "live")
|
|
57
|
+
return readdirSync(dir).filter((name) => {
|
|
58
|
+
const pid = readJson(path.join(dir, name))?.pid
|
|
59
|
+
if (!Number.isInteger(pid)) return false
|
|
60
|
+
try {
|
|
61
|
+
process.kill(pid, 0)
|
|
62
|
+
return true
|
|
63
|
+
} catch (error) {
|
|
64
|
+
return error.code === "EPERM"
|
|
65
|
+
}
|
|
66
|
+
}).length
|
|
67
|
+
} catch {
|
|
68
|
+
return 0
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export async function latestVersion(now = Date.now()) {
|
|
73
|
+
const cachePath = path.join(baroHome(), "update-check.json")
|
|
74
|
+
const cached = readJson(cachePath)
|
|
75
|
+
if (cached?.latest && cached.checkedAt && now - cached.checkedAt < CACHE_TTL_MS) {
|
|
76
|
+
return cached.latest
|
|
77
|
+
}
|
|
78
|
+
try {
|
|
79
|
+
const response = await fetch("https://registry.npmjs.org/baro-ai/latest", {
|
|
80
|
+
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
|
|
81
|
+
})
|
|
82
|
+
const latest = (await response.json())?.version
|
|
83
|
+
if (typeof latest !== "string") return null
|
|
84
|
+
try {
|
|
85
|
+
mkdirSync(baroHome(), { recursive: true })
|
|
86
|
+
writeFileSync(cachePath, JSON.stringify({ latest, checkedAt: now }))
|
|
87
|
+
} catch {
|
|
88
|
+
// A read-only home only costs the next start another lookup.
|
|
89
|
+
}
|
|
90
|
+
return latest
|
|
91
|
+
} catch {
|
|
92
|
+
return null
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Update when a newer baro is published. Never throws and never blocks a run
|
|
98
|
+
* for long: offline, a failed install or a root-owned global prefix all fall
|
|
99
|
+
* through to the version already installed.
|
|
100
|
+
*/
|
|
101
|
+
export async function selfUpdate({ packageVersion, argv, env = process.env, isTTY = process.stdin.isTTY }) {
|
|
102
|
+
const reason = skipReason({ argv, env, isTTY: Boolean(isTTY), liveRuns: 0 })
|
|
103
|
+
if (reason) return { updated: false, reason }
|
|
104
|
+
const current = installedVersion(packageVersion)
|
|
105
|
+
const latest = await latestVersion()
|
|
106
|
+
if (!latest || !semverLt(current, latest)) return { updated: false, reason: "up to date" }
|
|
107
|
+
if (liveRunCount() > 0) {
|
|
108
|
+
console.error(`baro ${latest} is available; not updating while another baro run is active.`)
|
|
109
|
+
return { updated: false, reason: "another baro run is active" }
|
|
110
|
+
}
|
|
111
|
+
console.error(`Updating baro ${current} → ${latest}…`)
|
|
112
|
+
const result = spawnSync("npm", ["install", "-g", `baro-ai@${latest}`], {
|
|
113
|
+
stdio: ["ignore", "ignore", "inherit"],
|
|
114
|
+
shell: process.platform === "win32",
|
|
115
|
+
})
|
|
116
|
+
if (result.status !== 0 || installedVersion(packageVersion) !== latest) {
|
|
117
|
+
console.error(`Could not update baro automatically. Update with: npm i -g baro-ai@latest`)
|
|
118
|
+
return { updated: false, reason: "install failed" }
|
|
119
|
+
}
|
|
120
|
+
console.error(`baro ${latest} installed.`)
|
|
121
|
+
return { updated: true, reason: null }
|
|
122
|
+
}
|
package/dist/runner.mjs
CHANGED
|
@@ -3857,7 +3857,7 @@ var url = process.env.CONTROL_URL ?? "wss://api.baro.jigjoy.ai";
|
|
|
3857
3857
|
var token = process.env.RUNNER_TOKEN;
|
|
3858
3858
|
var httpBase = canonicalControlHttpOrigin(url);
|
|
3859
3859
|
var credsPath = join3(homedir2(), ".baro", "credentials.json");
|
|
3860
|
-
var VERSION = true ? "0.118.
|
|
3860
|
+
var VERSION = true ? "0.118.7" : "0.0.0-dev";
|
|
3861
3861
|
var RUNNER_VERSION = VERSION;
|
|
3862
3862
|
var selfUpdateEnabled = VERSION !== "0.0.0-dev" && process.env.BARO_RUN_ONCE !== "1" && process.env.BARO_NO_SELF_UPDATE !== "1";
|
|
3863
3863
|
var RUNNER_PROTOCOL_VERSION = 2;
|
package/package.json
CHANGED
package/scripts/postinstall.js
CHANGED
|
@@ -96,8 +96,17 @@ async function main() {
|
|
|
96
96
|
|
|
97
97
|
fs.mkdirSync(BARO_HOME, { recursive: true })
|
|
98
98
|
|
|
99
|
-
// Clean up old binary
|
|
100
|
-
|
|
99
|
+
// Clean up old binary. Windows cannot delete a running executable but can
|
|
100
|
+
// rename it, so an update started from baro itself moves it aside.
|
|
101
|
+
try {
|
|
102
|
+
fs.unlinkSync(binaryPath)
|
|
103
|
+
} catch (err) {
|
|
104
|
+
if (err.code !== "ENOENT") {
|
|
105
|
+
const aside = `${binaryPath}.old`
|
|
106
|
+
try { fs.unlinkSync(aside) } catch {}
|
|
107
|
+
try { fs.renameSync(binaryPath, aside) } catch {}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
101
110
|
|
|
102
111
|
try {
|
|
103
112
|
await download(url, binaryPath)
|