centralu 0.1.0-beta.23 → 0.1.0-beta.24
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/centralu.mjs +24 -1
- package/bin/node-floor.mjs +42 -0
- package/package.json +7 -6
package/bin/centralu.mjs
CHANGED
|
@@ -56,6 +56,7 @@ import {
|
|
|
56
56
|
SERVE_HELP,
|
|
57
57
|
} from './serve.mjs'
|
|
58
58
|
import { swapInto } from './swap.mjs'
|
|
59
|
+
import { belowFloor, floorOf, oldNodeSentence } from './node-floor.mjs'
|
|
59
60
|
import { chmodSync, cpSync, existsSync, mkdirSync, readdirSync, readFileSync, realpathSync, renameSync, rmSync, writeFileSync } from 'node:fs'
|
|
60
61
|
import { createRequire } from 'node:module'
|
|
61
62
|
import { homedir } from 'node:os'
|
|
@@ -65,6 +66,8 @@ const require = createRequire(import.meta.url)
|
|
|
65
66
|
const pkg = require('../package.json')
|
|
66
67
|
|
|
67
68
|
const APP_NAME = 'Centralu'
|
|
69
|
+
/** The oldest Node the host runs on: this package's own `engines.node` (node-floor.mjs) */
|
|
70
|
+
const NODE_FLOOR = floorOf(pkg.engines.node)
|
|
68
71
|
const BUNDLE = `${APP_NAME}.app`
|
|
69
72
|
/*
|
|
70
73
|
* `CENTRALU_INSTALLED_COPY` points `install` and the copy checks at another bundle path. It exists
|
|
@@ -591,7 +594,7 @@ const HELP = `${APP_NAME} ${pkg.version}
|
|
|
591
594
|
to reach over SSH (\`centralu serve --help\`)
|
|
592
595
|
centralu --version Prints the version
|
|
593
596
|
|
|
594
|
-
Requires: Node
|
|
597
|
+
Requires: Node ${NODE_FLOOR}+, and the claude or codex CLI (the app's first screen reports the status)`
|
|
595
598
|
|
|
596
599
|
const [cmd, ...rest] = process.argv.slice(2)
|
|
597
600
|
switch (cmd) {
|
|
@@ -621,6 +624,26 @@ switch (cmd) {
|
|
|
621
624
|
process.exitCode = rotateToken({ env: process.env, home: HOME })
|
|
622
625
|
break
|
|
623
626
|
}
|
|
627
|
+
/*
|
|
628
|
+
* Before anything spawns a host: under a Node below the floor the host crashes on its first
|
|
629
|
+
* database call, with nothing in its log (issue #699). `--detach` also answers in the line the
|
|
630
|
+
* hub reads, so it can offer its managed install instead of quoting a crash. `--autostart on`
|
|
631
|
+
* writes a boot entry that would start that host. `--connection`, `--stop`, `--autostart
|
|
632
|
+
* off|status` and `--rotate-token` start no host and keep working, so the hub can still ask this
|
|
633
|
+
* machine what Node it has.
|
|
634
|
+
*/
|
|
635
|
+
const startsHost = args.mode === 'serve' || args.mode === 'detach' || (args.mode === 'autostart' && args.autostart === 'on')
|
|
636
|
+
if (startsHost && belowFloor(process.versions.node, NODE_FLOOR)) {
|
|
637
|
+
const message = oldNodeSentence(process.versions.node, NODE_FLOOR)
|
|
638
|
+
console.error(`centralu serve: ${message}`)
|
|
639
|
+
if (args.mode === 'detach') {
|
|
640
|
+
const line = { v: 1, detach: { ok: false, how: null, reason: 'node_too_old', message, node: process.versions.node, floor: NODE_FLOOR } }
|
|
641
|
+
process.stdout.write(`${JSON.stringify(line)}\n`)
|
|
642
|
+
}
|
|
643
|
+
// Not process.exit: the line above is on a pipe, and exiting at once may cut it
|
|
644
|
+
process.exitCode = 1
|
|
645
|
+
break
|
|
646
|
+
}
|
|
624
647
|
// A launcher `--detach` started: what it carried (the data folder, a host entry) applies before
|
|
625
648
|
// anything below reads the environment
|
|
626
649
|
const spec = args.child !== undefined ? decodeChildSpec(args.child) : null
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The oldest Node the bundled host runs on, and what the launcher says when it is run on an older one.
|
|
3
|
+
*
|
|
4
|
+
* **The floor is `engines.node` of this package, read here and nowhere restated.** The host's native
|
|
5
|
+
* database module (better-sqlite3 13) declares Node-API 10, which Node has from 22.14.0. Under an
|
|
6
|
+
* older 22.x (and under 20) it loads, then crashes on its first use with an access violation
|
|
7
|
+
* (`0xC0000005`, exit 3221225477, on Windows) or SIGSEGV (measured on 22.12.0, Windows and macOS,
|
|
8
|
+
* issue #699), before the host logs a line. The hub reads the same value from its copy of this
|
|
9
|
+
* package's `package.json` (`packages/agent-host/src/links/node-floor.ts`), and
|
|
10
|
+
* `tooling/engines.test.ts` keeps the other declarations equal to it.
|
|
11
|
+
*
|
|
12
|
+
* Lives in its own file so it can be tested (tooling/launcher-node-floor.test.ts): the launcher
|
|
13
|
+
* itself runs commands at import time. Plain JavaScript on Node's own modules and `semver.mjs`.
|
|
14
|
+
*/
|
|
15
|
+
import { isNewer } from './semver.mjs'
|
|
16
|
+
|
|
17
|
+
/** `>=22.14.0` or `>=22.14` → `22.14.0`; throws on any other shape, which `engines` must not take */
|
|
18
|
+
export function floorOf(range) {
|
|
19
|
+
const m = /^>=\s*(\d+)\.(\d+)(?:\.(\d+))?$/.exec(String(range).trim())
|
|
20
|
+
if (!m) throw new Error(`engines.node must be a plain floor like ">=22.14.0", not ${JSON.stringify(range)}`)
|
|
21
|
+
return `${m[1]}.${m[2]}.${m[3] ?? '0'}`
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** Whether `found` (`22.12.0` or `v22.12.0`) is older than `floor`; a version that does not parse is let through */
|
|
25
|
+
export function belowFloor(found, floor) {
|
|
26
|
+
const v = String(found).trim().replace(/^v/i, '')
|
|
27
|
+
if (!/^\d+\.\d+\.\d+/.test(v)) return false
|
|
28
|
+
return isNewer(floor, v)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The one sentence for a launcher that will not start the host on this Node: the Node it found, the
|
|
33
|
+
* floor, and the two ways out. It names no command, since it is also what the hub reads out of the
|
|
34
|
+
* `--detach` answer.
|
|
35
|
+
*/
|
|
36
|
+
export function oldNodeSentence(found, floor) {
|
|
37
|
+
const v = String(found).replace(/^v/i, '')
|
|
38
|
+
return (
|
|
39
|
+
`centralu serve needs Node ${floor} or newer and this is Node ${v}: update Node on this machine, ` +
|
|
40
|
+
'or link this machine from a Centralu window on another computer, which installs a Node of its own there.'
|
|
41
|
+
)
|
|
42
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "centralu",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.24",
|
|
4
4
|
"description": "Run, watch and steer several Claude Code and Codex CLI sessions from one window",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "ijun17",
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"windows",
|
|
22
22
|
"desktop"
|
|
23
23
|
],
|
|
24
|
+
"protocolVersion": 1,
|
|
24
25
|
"type": "module",
|
|
25
26
|
"bin": {
|
|
26
27
|
"centralu": "bin/centralu.mjs"
|
|
@@ -29,7 +30,7 @@
|
|
|
29
30
|
"bin"
|
|
30
31
|
],
|
|
31
32
|
"engines": {
|
|
32
|
-
"node": ">=22"
|
|
33
|
+
"node": ">=22.14.0"
|
|
33
34
|
},
|
|
34
35
|
"os": [
|
|
35
36
|
"darwin",
|
|
@@ -37,9 +38,9 @@
|
|
|
37
38
|
"win32"
|
|
38
39
|
],
|
|
39
40
|
"optionalDependencies": {
|
|
40
|
-
"@centralu/darwin-arm64": "0.1.0-beta.
|
|
41
|
-
"@centralu/linux-arm64": "0.1.0-beta.
|
|
42
|
-
"@centralu/linux-x64": "0.1.0-beta.
|
|
43
|
-
"@centralu/win32-x64": "0.1.0-beta.
|
|
41
|
+
"@centralu/darwin-arm64": "0.1.0-beta.24",
|
|
42
|
+
"@centralu/linux-arm64": "0.1.0-beta.24",
|
|
43
|
+
"@centralu/linux-x64": "0.1.0-beta.24",
|
|
44
|
+
"@centralu/win32-x64": "0.1.0-beta.24"
|
|
44
45
|
}
|
|
45
46
|
}
|