centralu 0.1.0-beta.2 → 0.1.0-beta.21
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 +440 -108
- package/bin/platform.mjs +359 -0
- package/bin/semver.mjs +84 -0
- package/bin/serve.mjs +1709 -0
- package/bin/swap.mjs +48 -0
- package/package.json +8 -4
package/bin/swap.mjs
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Replacing an installed copy of the app without a moment where there is none.
|
|
3
|
+
*
|
|
4
|
+
* Lives apart from `centralu.mjs` for the same reason `platform.mjs` does: the launcher runs a
|
|
5
|
+
* command at import time, so a test cannot import it. The paths come in as arguments, so
|
|
6
|
+
* `tooling/launcher-swap.test.ts` runs this against temporary folders instead of `/Applications`.
|
|
7
|
+
*/
|
|
8
|
+
import { existsSync, renameSync, rmSync } from 'node:fs'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Puts a new copy at `target`: `fill(staging)` writes it beside the old one, the old one is
|
|
12
|
+
* renamed aside, the new one is renamed in, and only then is the old one deleted.
|
|
13
|
+
*
|
|
14
|
+
* The old copy is never deleted before the new one is complete. Deleting first and copying
|
|
15
|
+
* after left a person whose copy failed (a full disk, a permission, an interrupted `ditto`)
|
|
16
|
+
* with no app at all, from a command they ran to update it. A copy that fails here leaves the
|
|
17
|
+
* old install untouched, and a rename that fails puts the old one back.
|
|
18
|
+
*
|
|
19
|
+
* Returns whether something was replaced, and where the old copy was left if it could not be
|
|
20
|
+
* deleted (null when it was).
|
|
21
|
+
*/
|
|
22
|
+
export function swapInto(target, fill, now = Date.now()) {
|
|
23
|
+
const staging = `${target}.new`
|
|
24
|
+
const aside = `${target}.old-${now}`
|
|
25
|
+
rmSync(staging, { recursive: true, force: true })
|
|
26
|
+
try {
|
|
27
|
+
fill(staging)
|
|
28
|
+
} catch (e) {
|
|
29
|
+
rmSync(staging, { recursive: true, force: true })
|
|
30
|
+
throw e
|
|
31
|
+
}
|
|
32
|
+
const replaced = existsSync(target)
|
|
33
|
+
if (replaced) renameSync(target, aside)
|
|
34
|
+
try {
|
|
35
|
+
renameSync(staging, target)
|
|
36
|
+
} catch (e) {
|
|
37
|
+
if (replaced) renameSync(aside, target)
|
|
38
|
+
rmSync(staging, { recursive: true, force: true })
|
|
39
|
+
throw e
|
|
40
|
+
}
|
|
41
|
+
if (!replaced) return { replaced, leftAt: null }
|
|
42
|
+
try {
|
|
43
|
+
rmSync(aside, { recursive: true, force: true })
|
|
44
|
+
return { replaced, leftAt: null }
|
|
45
|
+
} catch {
|
|
46
|
+
return { replaced, leftAt: aside }
|
|
47
|
+
}
|
|
48
|
+
}
|
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.21",
|
|
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",
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"agent",
|
|
19
19
|
"macos",
|
|
20
20
|
"linux",
|
|
21
|
+
"windows",
|
|
21
22
|
"desktop"
|
|
22
23
|
],
|
|
23
24
|
"type": "module",
|
|
@@ -32,10 +33,13 @@
|
|
|
32
33
|
},
|
|
33
34
|
"os": [
|
|
34
35
|
"darwin",
|
|
35
|
-
"linux"
|
|
36
|
+
"linux",
|
|
37
|
+
"win32"
|
|
36
38
|
],
|
|
37
39
|
"optionalDependencies": {
|
|
38
|
-
"centralu
|
|
39
|
-
"centralu
|
|
40
|
+
"@centralu/darwin-arm64": "0.1.0-beta.21",
|
|
41
|
+
"@centralu/linux-arm64": "0.1.0-beta.21",
|
|
42
|
+
"@centralu/linux-x64": "0.1.0-beta.21",
|
|
43
|
+
"@centralu/win32-x64": "0.1.0-beta.21"
|
|
40
44
|
}
|
|
41
45
|
}
|