@aicraftalchemy/aca 0.0.6 → 0.0.8
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/cli-wrapper.cjs +49 -8
- package/package.json +1 -1
package/cli-wrapper.cjs
CHANGED
|
@@ -1,18 +1,59 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* ACA launcher. This is the `bin` entry npm links as `aca`. It
|
|
4
|
-
* compiled binary that install.cjs
|
|
5
|
-
* and stdio, and exits with the
|
|
3
|
+
* ACA launcher. This is the `bin` entry npm links as `aca`. It applies any
|
|
4
|
+
* staged auto-update, then execs the compiled binary that install.cjs
|
|
5
|
+
* downloaded into bin/, forwarding all args and stdio, and exits with the
|
|
6
|
+
* binary's exit code.
|
|
6
7
|
*/
|
|
7
8
|
const { spawnSync } = require('node:child_process')
|
|
8
9
|
const path = require('node:path')
|
|
9
10
|
const fs = require('node:fs')
|
|
10
11
|
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
const binDir = path.join(__dirname, 'bin')
|
|
13
|
+
const isWin = process.platform === 'win32'
|
|
14
|
+
const bin = path.join(binDir, isWin ? 'aca.exe' : 'aca')
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Apply a staged auto-update. The running binary downloads a new version to
|
|
18
|
+
* `<name>.pending` in the background (see autoUpdater.stagePendingUpdate); here
|
|
19
|
+
* — BEFORE the binary is spawned, so nothing this launch has open is locked —
|
|
20
|
+
* we swap it in. On Windows a running file (a concurrent session) can still be
|
|
21
|
+
* RENAMED aside even while locked, so the swap is safe; deleting the parked
|
|
22
|
+
* `.old` is best-effort and retried on the next launch. The `.aca-pending-version`
|
|
23
|
+
* marker gates the swap, so a half-downloaded binary is never applied.
|
|
24
|
+
*/
|
|
25
|
+
function applyStagedUpdate() {
|
|
26
|
+
const marker = path.join(binDir, '.aca-pending-version')
|
|
27
|
+
if (!fs.existsSync(marker)) return
|
|
28
|
+
const acaPending = path.join(binDir, isWin ? 'aca.exe.pending' : 'aca.pending')
|
|
29
|
+
if (!fs.existsSync(acaPending)) {
|
|
30
|
+
// Marker without a binary — stale/partial. Clear it and move on.
|
|
31
|
+
try { fs.rmSync(marker, { force: true }) } catch {}
|
|
32
|
+
return
|
|
33
|
+
}
|
|
34
|
+
const swap = name => {
|
|
35
|
+
const pending = path.join(binDir, name + '.pending')
|
|
36
|
+
if (!fs.existsSync(pending)) return
|
|
37
|
+
const real = path.join(binDir, name)
|
|
38
|
+
const old = path.join(binDir, name + '.old')
|
|
39
|
+
try { fs.rmSync(old, { force: true }) } catch {}
|
|
40
|
+
try { if (fs.existsSync(real)) fs.renameSync(real, old) } catch {}
|
|
41
|
+
fs.renameSync(pending, real)
|
|
42
|
+
if (!isWin) { try { fs.chmodSync(real, 0o755) } catch {} }
|
|
43
|
+
try { fs.rmSync(old, { force: true }) } catch {}
|
|
44
|
+
}
|
|
45
|
+
try {
|
|
46
|
+
swap(isWin ? 'aca.exe' : 'aca')
|
|
47
|
+
swap(isWin ? 'rg.exe' : 'rg')
|
|
48
|
+
try { fs.rmSync(marker, { force: true }) } catch {}
|
|
49
|
+
} catch (err) {
|
|
50
|
+
// Swap failed (e.g. transient FS error) — leave the pending files in place
|
|
51
|
+
// so the next launch retries; fall through and run the current binary.
|
|
52
|
+
console.error(`ACA: could not apply staged update (${err.message}); continuing.`)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
applyStagedUpdate()
|
|
16
57
|
|
|
17
58
|
if (!fs.existsSync(bin)) {
|
|
18
59
|
console.error(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aicraftalchemy/aca",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.8",
|
|
4
4
|
"description": "ACA — agentic coding CLI. Any model, any provider (Claude, Gemini, OpenAI, NVIDIA, Groq, Cerebras, OpenRouter, Hugging Face). Developed by Aicraftalchemy.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"bin": {
|