zelari-code 1.3.0 → 1.4.1
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/README.md +67 -3
- package/dist/cli/main.bundled.js +336 -23
- package/dist/cli/main.bundled.js.map +4 -4
- package/dist/cli/main.js +75 -3
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/slashHandlers/updater.js +27 -3
- package/dist/cli/slashHandlers/updater.js.map +1 -1
- package/dist/cli/utils/doctor.js +23 -0
- package/dist/cli/utils/doctor.js.map +1 -1
- package/dist/cli/utils/prereqChecks.js +362 -0
- package/dist/cli/utils/prereqChecks.js.map +1 -0
- package/package.json +2 -2
- package/scripts/postinstall.mjs +46 -1
package/dist/cli/main.js
CHANGED
|
@@ -36,6 +36,69 @@ export const VERSION = getCurrentVersion();
|
|
|
36
36
|
* Disabled in dev mode (`ANATHEMA_DEV=1`) to avoid noise during local
|
|
37
37
|
* development where the bundled version is the source repo.
|
|
38
38
|
*/
|
|
39
|
+
/**
|
|
40
|
+
* Boot-time prerequisite gate (v1.4.0).
|
|
41
|
+
*
|
|
42
|
+
* Probes node/git/bash THROUGH the agent's resolved shell — not the main
|
|
43
|
+
* process — because the agent runs `npm`/`tsc`/build scripts inside the
|
|
44
|
+
* resolved bash (Git Bash on Windows), which inherits a different PATH
|
|
45
|
+
* than this Node process. A user can have node visible to the main process
|
|
46
|
+
* yet invisible to the agent's bash; without this check zelari-code boots
|
|
47
|
+
* happily and the failure surfaces only mid-task (`node: not found`), which
|
|
48
|
+
* is exactly what blocked the Anathema-Studio council run on 2026-07-07.
|
|
49
|
+
*
|
|
50
|
+
* Severity:
|
|
51
|
+
* - node unreachable from agent shell → hard-fail (exit 1). Without node
|
|
52
|
+
* the agent cannot run npm/build/tsc — there is nothing useful it can do.
|
|
53
|
+
* - git / bash missing → warn to stderr, continue. Features degrade but
|
|
54
|
+
* the agent still works for non-git, non-POSIX tasks.
|
|
55
|
+
*
|
|
56
|
+
* Bypass: `ZELARI_SKIP_PREFLIGHT=1` or `--skip-checks`. Intended for CI,
|
|
57
|
+
* sandboxes, and emergency recovery — not normal use.
|
|
58
|
+
*
|
|
59
|
+
* Runs AFTER `pickRootComponent()` (so `--version`/`--help`/`--doctor` keep
|
|
60
|
+
* working on a broken install) but BEFORE skill loading and the TUI render.
|
|
61
|
+
* Never throws — `runPrereqChecks` already swallows per-check errors.
|
|
62
|
+
*
|
|
63
|
+
* @see src/cli/utils/prereqChecks.ts — the probe implementation.
|
|
64
|
+
*/
|
|
65
|
+
function runPreflight() {
|
|
66
|
+
if (process.env.ZELARI_SKIP_PREFLIGHT === "1")
|
|
67
|
+
return;
|
|
68
|
+
if (process.argv.includes("--skip-checks"))
|
|
69
|
+
return;
|
|
70
|
+
if (process.env.ANATHEMA_DEV === "1")
|
|
71
|
+
return; // dev: avoid noise on a source checkout.
|
|
72
|
+
const { runPrereqChecks } =
|
|
73
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
74
|
+
require("./utils/prereqChecks.js");
|
|
75
|
+
const { results, hasCriticalFail, warnings } = runPrereqChecks({
|
|
76
|
+
mode: "preflight",
|
|
77
|
+
});
|
|
78
|
+
for (const w of warnings) {
|
|
79
|
+
// eslint-disable-next-line no-console
|
|
80
|
+
console.error(`\x1b[33m[zelari-code] ⚠ ${w.tool}: ${w.message}\x1b[0m`);
|
|
81
|
+
}
|
|
82
|
+
if (hasCriticalFail) {
|
|
83
|
+
const critical = results.find((r) => !r.ok && r.severity === "critical");
|
|
84
|
+
// eslint-disable-next-line no-console
|
|
85
|
+
console.error("");
|
|
86
|
+
// eslint-disable-next-line no-console
|
|
87
|
+
console.error("\x1b[31m" +
|
|
88
|
+
"==============================================================\n" +
|
|
89
|
+
" zelari-code cannot start: a critical prerequisite is missing.\n" +
|
|
90
|
+
"==============================================================\x1b[0m");
|
|
91
|
+
if (critical) {
|
|
92
|
+
// eslint-disable-next-line no-console
|
|
93
|
+
console.error(`\n ${critical.tool}: ${critical.message}`);
|
|
94
|
+
}
|
|
95
|
+
// eslint-disable-next-line no-console
|
|
96
|
+
console.error("\n Run `zelari-code --doctor` for the full diagnostic report.\n" +
|
|
97
|
+
" Bypass this check with ZELARI_SKIP_PREFLIGHT=1 (NOT recommended —\n" +
|
|
98
|
+
" the agent will still fail when it tries to run npm/build/tsc).");
|
|
99
|
+
process.exit(1);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
39
102
|
async function backgroundUpdateCheck() {
|
|
40
103
|
if (process.env.ANATHEMA_DEV === "1")
|
|
41
104
|
return;
|
|
@@ -115,7 +178,10 @@ function pickRootComponent() {
|
|
|
115
178
|
"Options:\n" +
|
|
116
179
|
" --version, -v Print version and exit\n" +
|
|
117
180
|
" --help, -h Print this help and exit\n" +
|
|
118
|
-
" --doctor Diagnose install health (shim, bundle, PATH, deps
|
|
181
|
+
" --doctor Diagnose install health (shim, bundle, PATH, deps,\n" +
|
|
182
|
+
" node/git/bash in the agent shell)\n" +
|
|
183
|
+
" --skip-checks Skip the boot-time prerequisite check\n" +
|
|
184
|
+
" (alias for ZELARI_SKIP_PREFLIGHT=1)\n" +
|
|
119
185
|
" --no-wizard Skip the first-run wizard\n" +
|
|
120
186
|
" --reset-config Re-run the wizard (clears provider.json on commit)\n" +
|
|
121
187
|
" --headless Run a single task without mounting the TUI\n" +
|
|
@@ -126,8 +192,9 @@ function pickRootComponent() {
|
|
|
126
192
|
" --model <id> Model override (default: provider default)\n" +
|
|
127
193
|
"\n" +
|
|
128
194
|
"Environment:\n" +
|
|
129
|
-
" ZELARI_NO_WIZARD=1
|
|
130
|
-
"
|
|
195
|
+
" ZELARI_NO_WIZARD=1 Skip the first-run wizard\n" +
|
|
196
|
+
" ZELARI_SKIP_PREFLIGHT=1 Skip the boot prerequisite check\n" +
|
|
197
|
+
" ANATHEMA_DEV=1 Disable background update check + preflight\n");
|
|
131
198
|
process.exit(0);
|
|
132
199
|
}
|
|
133
200
|
// Headless mode: short-circuit TUI entirely. Must be checked BEFORE
|
|
@@ -189,6 +256,11 @@ function main() {
|
|
|
189
256
|
const picked = pickRootComponent();
|
|
190
257
|
if (picked.kind === "done")
|
|
191
258
|
return; // --version or --help printed + exited
|
|
259
|
+
// v1.4.0: verify node/git/bash BEFORE mounting the TUI or running a headless
|
|
260
|
+
// task. Hard-fails on missing node (the agent cannot run npm/build without it),
|
|
261
|
+
// warns on missing git/bash. Skipped for --version/--help/--doctor (handled
|
|
262
|
+
// above) so a broken install can still be diagnosed. See `runPreflight`.
|
|
263
|
+
runPreflight();
|
|
192
264
|
loadUserSkills();
|
|
193
265
|
if (picked.kind === "headless") {
|
|
194
266
|
void runHeadless(picked.headlessOpts).then((code) => {
|
package/dist/cli/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"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"}
|
|
@@ -24,9 +24,33 @@ export async function handleUpdatePerform(ctx) {
|
|
|
24
24
|
const { performUpdate } = await import("../updater.js");
|
|
25
25
|
const res = await performUpdate();
|
|
26
26
|
if (res.ok) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
// v1.4.0: after a successful update, re-run the prerequisite probes so
|
|
28
|
+
// the user learns about a broken environment NOW rather than on the
|
|
29
|
+
// next boot (which hard-fails on missing node). These checks read the
|
|
30
|
+
// system PATH, which is independent of the running process version,
|
|
31
|
+
// so they predict the post-restart state accurately. Non-blocking:
|
|
32
|
+
// warnings only — a critical node failure here is still surfaced by
|
|
33
|
+
// the boot preflight after restart, which is the right place to block.
|
|
34
|
+
let prereqBlock = "";
|
|
35
|
+
try {
|
|
36
|
+
const { runPrereqChecks } = await import("../utils/prereqChecks.js");
|
|
37
|
+
const { warnings } = runPrereqChecks({ mode: "preflight" });
|
|
38
|
+
if (warnings.length > 0) {
|
|
39
|
+
prereqBlock =
|
|
40
|
+
"\n\n⚠ Prerequisite warnings (the agent may be limited after restart):\n" +
|
|
41
|
+
warnings
|
|
42
|
+
.map((w) => ` - ${w.tool}: ${w.message.replace(/\n/g, "\n ")}`)
|
|
43
|
+
.join("\n") +
|
|
44
|
+
"\n Run `zelari-code --doctor` after restart for the full report.";
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// prereqChecks is best-effort here — never block an update success message.
|
|
49
|
+
}
|
|
50
|
+
appendSystem(ctx.setMessages, "[update] ✅ installed successfully\n\n" +
|
|
51
|
+
"Please restart zelari-code manually to use the new version.\n" +
|
|
52
|
+
"(exit with /exit or Ctrl+C, then run `zelari-code` again)" +
|
|
53
|
+
prereqBlock);
|
|
30
54
|
}
|
|
31
55
|
else {
|
|
32
56
|
// v1.0.3: show the FULL npm output (not just the last error line) so
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"updater.js","sourceRoot":"","sources":["../../../src/cli/slashHandlers/updater.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAiB1D,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,GAAwB;IAExB,IAAI,CAAC;QACH,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC;QACzD,MAAM,IAAI,GAAG,MAAM,cAAc,EAAE,CAAC;QACpC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,0BAA0B,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QACxE,CAAC;aAAM,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YAChC,YAAY,CACV,GAAG,CAAC,WAAW,EACf,2BAA2B,IAAI,CAAC,aAAa,wBAAwB,IAAI,CAAC,cAAc,KAAK;gBAC3F,iFAAiF,CACpF,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,YAAY,CACV,GAAG,CAAC,WAAW,EACf,wBAAwB,IAAI,CAAC,cAAc,GAAG,CAC/C,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,YAAY,CACV,GAAG,CAAC,WAAW,EACf,kBAAkB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CACrE,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,GAAwB;IAExB,YAAY,CACV,GAAG,CAAC,WAAW,EACf,yDAAyD,CAC1D,CAAC;IACF,IAAI,CAAC;QACH,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC;QACxD,MAAM,GAAG,GAAG,MAAM,aAAa,EAAE,CAAC;QAClC,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC;YACX,YAAY,CACV,GAAG,CAAC,WAAW,EACf,uCAAuC;gBACrC,+DAA+D;gBAC/D,
|
|
1
|
+
{"version":3,"file":"updater.js","sourceRoot":"","sources":["../../../src/cli/slashHandlers/updater.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/utils/doctor.js
CHANGED
|
@@ -32,6 +32,7 @@ import { existsSync, readFileSync, readlinkSync, statSync } from "node:fs";
|
|
|
32
32
|
import { createRequire } from "node:module";
|
|
33
33
|
import { fileURLToPath } from "node:url";
|
|
34
34
|
import path from "node:path";
|
|
35
|
+
import { checkAgentNode, checkAgentGit, checkAgentBash, } from "./prereqChecks.js";
|
|
35
36
|
const require = createRequire(import.meta.url);
|
|
36
37
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
37
38
|
// src/cli/utils/doctor.ts → <pkg>/src/cli/utils/doctor.ts
|
|
@@ -217,6 +218,19 @@ function checkPath() {
|
|
|
217
218
|
` fix (POSIX): export PATH="$(npm prefix -g)/bin:$PATH"\n` +
|
|
218
219
|
` fix (Windows): $env:Path = "$(npm prefix -g);$env:Path"`);
|
|
219
220
|
}
|
|
221
|
+
/**
|
|
222
|
+
* Adapt a `PrereqResult` (from prereqChecks.ts) into doctor's `CheckResult`.
|
|
223
|
+
* The shapes are isomorphic — this is a pure pass-through that lets the
|
|
224
|
+
* agent-shell-aware checks share the doctor's report formatting + summary.
|
|
225
|
+
* Keep severity semantics intact: 'critical' FAILs the report, 'warn' is advisory.
|
|
226
|
+
*/
|
|
227
|
+
function prereqToCheckResult(r) {
|
|
228
|
+
if (r.ok)
|
|
229
|
+
return OK(r.message);
|
|
230
|
+
return r.severity === "critical"
|
|
231
|
+
? FAIL(r.message, "critical")
|
|
232
|
+
: WARN(r.message);
|
|
233
|
+
}
|
|
220
234
|
/**
|
|
221
235
|
* Run all checks and print results. Returns true if install is healthy
|
|
222
236
|
* (no critical failures), false otherwise. Never throws.
|
|
@@ -225,11 +239,20 @@ export function runDoctor() {
|
|
|
225
239
|
const pkg = readPackageJson();
|
|
226
240
|
const pkgName = pkg?.name ?? "zelari-code";
|
|
227
241
|
const checks = [
|
|
242
|
+
// --- install-health checks (main-process probes) ---
|
|
228
243
|
{ name: "node", run: () => checkNode(pkg) },
|
|
229
244
|
{ name: "bin shim", run: () => checkShim(pkgName) },
|
|
230
245
|
{ name: "cli bundle", run: () => checkBundle() },
|
|
231
246
|
{ name: "runtime deps", run: () => checkRuntimeDeps() },
|
|
232
247
|
{ name: "PATH", run: () => checkPath() },
|
|
248
|
+
// --- agent-shell checks (v1.4.0) ---
|
|
249
|
+
// These probe node/git/bash THROUGH the resolved shell the agent uses.
|
|
250
|
+
// A pass on "node" + a FAIL on "node (agent shell)" is the tell-tale
|
|
251
|
+
// signature of the PATH-mismatch bug (node visible to the main process,
|
|
252
|
+
// invisible to Git Bash) that silently breaks council builds.
|
|
253
|
+
{ name: "node (agent shell)", run: () => prereqToCheckResult(checkAgentNode()) },
|
|
254
|
+
{ name: "git (agent shell)", run: () => prereqToCheckResult(checkAgentGit()) },
|
|
255
|
+
{ name: "bash", run: () => prereqToCheckResult(checkAgentBash()) },
|
|
233
256
|
];
|
|
234
257
|
// eslint-disable-next-line no-console
|
|
235
258
|
console.log(`zelari-code doctor (v${pkg?.version ?? "unknown"})`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../src/cli/utils/doctor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../src/cli/utils/doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* prereqChecks.ts — prerequisite detection that mirrors the agent's shell.
|
|
3
|
+
*
|
|
4
|
+
* Why this exists separately from `doctor.ts`:
|
|
5
|
+
* The legacy `checkNode()` in doctor.ts probes `node --version` from the
|
|
6
|
+
* zelari-code main process. On Windows that main process is a native Node
|
|
7
|
+
* binary whose PATH always contains node (otherwise zelari-code wouldn't
|
|
8
|
+
* be running). But the AGENT — the thing that actually runs `npm`,
|
|
9
|
+
* `tsc`, build scripts — launches commands through the resolved shell
|
|
10
|
+
* (Git Bash on Windows, see `resolveShell()` in shellResolver.ts), which
|
|
11
|
+
* inherits a DIFFERENT PATH. A user can have node visible to the main
|
|
12
|
+
* process yet invisible to the agent's bash (e.g. Node installed for
|
|
13
|
+
* "current user" only, while Git Bash inherits the system PATH). The
|
|
14
|
+
* legacy doctor check passes in that case and never warns — until the
|
|
15
|
+
* agent tries `npm run build` and gets `node: not found`, mid-task.
|
|
16
|
+
*
|
|
17
|
+
* These checks probe THROUGH the same shell the agent will use, so they
|
|
18
|
+
* detect the real mismatch before it bites. They power:
|
|
19
|
+
* - the boot-time preflight (src/cli/main.ts `runPreflight`),
|
|
20
|
+
* - the `--doctor` "agent shell" rows (src/cli/utils/doctor.ts),
|
|
21
|
+
* - the post-update prerequisite warnings (slashHandlers/updater.ts).
|
|
22
|
+
*
|
|
23
|
+
* Design contract (inherited from doctor.ts):
|
|
24
|
+
* - NEVER throws. Every check catches its own errors and returns a
|
|
25
|
+
* FAIL/WARN result. A broken prereq check must never crash the CLI.
|
|
26
|
+
* - Sync API: doctor's `run()` loop is sync and we keep that shape.
|
|
27
|
+
* - No dependency on @zelari/core: the bash-resolution chain is
|
|
28
|
+
* replicated here (see `resolveAgentShellSync` below) so this module
|
|
29
|
+
* works even when the core bundle is broken — which is exactly when a
|
|
30
|
+
* user needs `--doctor` to diagnose the breakage.
|
|
31
|
+
*
|
|
32
|
+
* @see packages/core/src/core/tools/builtin/shellResolver.ts — the canonical
|
|
33
|
+
* resolver; keep `resolveAgentShellSync` in sync with its detection chain.
|
|
34
|
+
* @see src/cli/utils/doctor.ts — the opt-in `zelari-code doctor` command.
|
|
35
|
+
*/
|
|
36
|
+
import { execSync, spawnSync } from "node:child_process";
|
|
37
|
+
import { existsSync } from "node:fs";
|
|
38
|
+
/** Minimum Node major version (mirrors `engines.node` ">=20.0.0" in package.json). */
|
|
39
|
+
const MIN_NODE_MAJOR = 20;
|
|
40
|
+
/** Standard Git for Windows bash locations (mirrors shellResolver.STANDARD_BASH_PATHS). */
|
|
41
|
+
const STANDARD_BASH_PATHS = [
|
|
42
|
+
"C:\\Program Files\\Git\\bin\\bash.exe",
|
|
43
|
+
"C:\\Program Files\\Git\\usr\\bin\\bash.exe",
|
|
44
|
+
"C:\\Program Files (x86)\\Git\\bin\\bash.exe",
|
|
45
|
+
"C:\\Program Files (x86)\\Git\\usr\\bin\\bash.exe",
|
|
46
|
+
];
|
|
47
|
+
/**
|
|
48
|
+
* Resolve the shell the agent will use — SYNC version of `resolveShell()`.
|
|
49
|
+
*
|
|
50
|
+
* Replicated (not imported) so this module has no runtime dependency on
|
|
51
|
+
* @zelari/core. The detection order MUST stay in lockstep with
|
|
52
|
+
* `packages/core/src/core/tools/builtin/shellResolver.ts:resolveBashWindows`:
|
|
53
|
+
* 1. ZELARI_SHELL env var (explicit override)
|
|
54
|
+
* 2. SHELL env var (set by Git Bash / MSYS2 sessions)
|
|
55
|
+
* 3. Standard Git for Windows install paths (existsSync probe)
|
|
56
|
+
* 4. `where bash` (PATH lookup)
|
|
57
|
+
* 5. Fallback: cmd.exe on win32, /bin/sh on POSIX
|
|
58
|
+
*/
|
|
59
|
+
function resolveAgentShellSync() {
|
|
60
|
+
// POSIX: Node's `shell: true` already uses /bin/sh — bash-compatible enough.
|
|
61
|
+
if (process.platform !== "win32") {
|
|
62
|
+
return { bashPath: null, isBash: true, via: "/bin/sh" };
|
|
63
|
+
}
|
|
64
|
+
// 1. Explicit override.
|
|
65
|
+
const envShell = process.env.ZELARI_SHELL;
|
|
66
|
+
if (envShell && envShell.trim().length > 0 && existsSyncSafe(envShell)) {
|
|
67
|
+
return { bashPath: envShell, isBash: true, via: `bash (${envShell})` };
|
|
68
|
+
}
|
|
69
|
+
// 2. SHELL env var (Git Bash / MSYS2 sessions).
|
|
70
|
+
const sessionShell = process.env.SHELL;
|
|
71
|
+
if (sessionShell &&
|
|
72
|
+
sessionShell.trim().length > 0 &&
|
|
73
|
+
existsSyncSafe(sessionShell)) {
|
|
74
|
+
return {
|
|
75
|
+
bashPath: sessionShell,
|
|
76
|
+
isBash: true,
|
|
77
|
+
via: `bash (${sessionShell})`,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
// 3. Standard install paths.
|
|
81
|
+
for (const p of STANDARD_BASH_PATHS) {
|
|
82
|
+
if (existsSyncSafe(p)) {
|
|
83
|
+
return { bashPath: p, isBash: true, via: `bash (${p})` };
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// 4. `where bash` — PATH lookup. `where` ships with Windows as a real .exe.
|
|
87
|
+
try {
|
|
88
|
+
const result = spawnSync("where", ["bash"], {
|
|
89
|
+
encoding: "utf8",
|
|
90
|
+
windowsHide: true,
|
|
91
|
+
});
|
|
92
|
+
if (result.status === 0 && result.stdout) {
|
|
93
|
+
const first = result.stdout
|
|
94
|
+
.split(/\r?\n/)
|
|
95
|
+
.find((l) => l.trim().length > 0);
|
|
96
|
+
if (first && existsSyncSafe(first)) {
|
|
97
|
+
const trimmed = first.trim();
|
|
98
|
+
return { bashPath: trimmed, isBash: true, via: `bash (${trimmed})` };
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
// `where` unavailable or failed — fall through to cmd.exe.
|
|
104
|
+
}
|
|
105
|
+
// 5. Fallback: cmd.exe. POSIX commands (ls, which, $VAR) may fail here.
|
|
106
|
+
return { bashPath: null, isBash: false, via: "cmd.exe" };
|
|
107
|
+
}
|
|
108
|
+
/** existsSync that swallows edge-case errors (invalid chars on win32, etc.). */
|
|
109
|
+
function existsSyncSafe(p) {
|
|
110
|
+
try {
|
|
111
|
+
return existsSync(p);
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Probe `<tool> --version` through the agent's resolved shell.
|
|
119
|
+
*
|
|
120
|
+
* Returns the raw stdout (trimmed) and parsed semver, or empty strings when
|
|
121
|
+
* the tool isn't reachable. Never throws.
|
|
122
|
+
*/
|
|
123
|
+
function probeTool(tool) {
|
|
124
|
+
const shell = resolveAgentShellSync();
|
|
125
|
+
let stdout = "";
|
|
126
|
+
if (shell.bashPath) {
|
|
127
|
+
// Real bash (win32 Git Bash or explicit ZELARI_SHELL): spawn directly
|
|
128
|
+
// with `-c` so we get the EXACT environment the agent's `bash` tool
|
|
129
|
+
// gets — this is what catches the "node visible to main, invisible to
|
|
130
|
+
// bash" mismatch.
|
|
131
|
+
try {
|
|
132
|
+
const r = spawnSync(shell.bashPath, ["-c", `${tool} --version`], {
|
|
133
|
+
encoding: "utf8",
|
|
134
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
135
|
+
windowsHide: true,
|
|
136
|
+
});
|
|
137
|
+
if (r.status === 0)
|
|
138
|
+
stdout = (r.stdout || "").trim();
|
|
139
|
+
// status !== 0 means the tool isn't on bash's PATH (or errored) — leave stdout empty.
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
// spawn failure (e.g. bashPath stale) — fall through to empty.
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
else if (process.platform === "win32") {
|
|
146
|
+
// cmd.exe fallback (no Git Bash found). execSync with shell:true → cmd.exe.
|
|
147
|
+
try {
|
|
148
|
+
stdout = execSync(`${tool} --version`, {
|
|
149
|
+
encoding: "utf8",
|
|
150
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
151
|
+
}).trim();
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
// not on cmd's PATH either
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
// POSIX non-bash (shouldn't happen — resolveAgentShellSync returns isBash:true on POSIX).
|
|
159
|
+
try {
|
|
160
|
+
stdout = execSync(`${tool} --version`, {
|
|
161
|
+
encoding: "utf8",
|
|
162
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
163
|
+
}).trim();
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
// ignore
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
const m = stdout.match(/(\d+)\.(\d+)\.(\d+)/);
|
|
170
|
+
return {
|
|
171
|
+
found: stdout.length > 0,
|
|
172
|
+
version: m ? `${m[1]}.${m[2]}.${m[3]}` : "",
|
|
173
|
+
raw: stdout,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Actionable fix hint when node isn't visible to the agent shell.
|
|
178
|
+
* OS-specific because the root cause differs (system vs user PATH on Windows;
|
|
179
|
+
* nvm symlink on macOS/Linux; missing install entirely).
|
|
180
|
+
*/
|
|
181
|
+
function nodeMissingHint() {
|
|
182
|
+
const shell = resolveAgentShellSync();
|
|
183
|
+
if (process.platform === "win32") {
|
|
184
|
+
return (`node is not reachable from the agent's shell (${shell.via}).\n` +
|
|
185
|
+
` This usually means Node was installed for "current user" only,\n` +
|
|
186
|
+
` while Git Bash inherits the SYSTEM Path. Fix (pick one):\n` +
|
|
187
|
+
` - Reinstall Node (https://nodejs.org) and choose\n` +
|
|
188
|
+
` "Add to PATH for all users", OR\n` +
|
|
189
|
+
` - Add C:\\Program Files\\nodejs\\ to the SYSTEM Path\n` +
|
|
190
|
+
` (System Properties → Environment Variables → Path), OR\n` +
|
|
191
|
+
` - Set ZELARI_SHELL to a bash that already sees node.`);
|
|
192
|
+
}
|
|
193
|
+
return (`node is not on the agent's shell PATH.\n` +
|
|
194
|
+
` Install Node >= ${MIN_NODE_MAJOR} (https://nodejs.org) or, if you use\n` +
|
|
195
|
+
` nvm, run \`nvm use <version>\` and reopen this terminal.`);
|
|
196
|
+
}
|
|
197
|
+
/** Check `node` is reachable from the agent shell and meets the minimum version. */
|
|
198
|
+
export function checkAgentNode() {
|
|
199
|
+
const probe = probeTool("node");
|
|
200
|
+
if (!probe.found) {
|
|
201
|
+
return {
|
|
202
|
+
ok: false,
|
|
203
|
+
severity: "critical",
|
|
204
|
+
tool: "node",
|
|
205
|
+
message: nodeMissingHint(),
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
const major = Number(probe.version.split(".")[0]);
|
|
209
|
+
if (!probe.version || Number.isNaN(major)) {
|
|
210
|
+
// node IS on PATH but version string looks weird — degrade to warn, don't hard-fail.
|
|
211
|
+
return {
|
|
212
|
+
ok: false,
|
|
213
|
+
severity: "warn",
|
|
214
|
+
tool: "node",
|
|
215
|
+
message: `could not parse node version from "${probe.raw}" (node is reachable, but version check skipped)`,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
if (major < MIN_NODE_MAJOR) {
|
|
219
|
+
return {
|
|
220
|
+
ok: false,
|
|
221
|
+
severity: "critical",
|
|
222
|
+
tool: "node",
|
|
223
|
+
message: `node ${probe.version} is older than the required >= ${MIN_NODE_MAJOR}.0.0 (from engines.node). Upgrade: https://nodejs.org`,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
return {
|
|
227
|
+
ok: true,
|
|
228
|
+
severity: "critical",
|
|
229
|
+
tool: "node",
|
|
230
|
+
message: `node ${probe.version} (agent shell)`,
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
/** Check `git` is reachable from the agent shell. Soft prereq (warn, not block). */
|
|
234
|
+
export function checkAgentGit() {
|
|
235
|
+
const probe = probeTool("git");
|
|
236
|
+
if (!probe.found) {
|
|
237
|
+
const hint = process.platform === "win32"
|
|
238
|
+
? `Install Git for Windows: https://git-scm.com/download/win`
|
|
239
|
+
: `Install git (e.g. \`brew install git\` on macOS, \`apt install git\` on Debian)`;
|
|
240
|
+
return {
|
|
241
|
+
ok: false,
|
|
242
|
+
severity: "warn",
|
|
243
|
+
tool: "git",
|
|
244
|
+
message: `git not found on the agent's shell PATH — /diff, /undo and the git sidebar will be disabled. ${hint}`,
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
return {
|
|
248
|
+
ok: true,
|
|
249
|
+
severity: "warn",
|
|
250
|
+
tool: "git",
|
|
251
|
+
message: `git ${probe.version} (agent shell)`,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Check that a real bash is available on Windows. When the resolver falls
|
|
256
|
+
* back to cmd.exe, POSIX commands (`ls`, `which`, `$VAR`, `&&`) will fail
|
|
257
|
+
* inside the agent's `bash` tool — confusing and hard to debug. Warn only.
|
|
258
|
+
*/
|
|
259
|
+
export function checkAgentBash() {
|
|
260
|
+
if (process.platform !== "win32") {
|
|
261
|
+
return {
|
|
262
|
+
ok: true,
|
|
263
|
+
severity: "warn",
|
|
264
|
+
tool: "bash",
|
|
265
|
+
message: "POSIX shell always available on this platform",
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
const shell = resolveAgentShellSync();
|
|
269
|
+
if (shell.isBash) {
|
|
270
|
+
return {
|
|
271
|
+
ok: true,
|
|
272
|
+
severity: "warn",
|
|
273
|
+
tool: "bash",
|
|
274
|
+
message: `real bash available (${shell.via})`,
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
return {
|
|
278
|
+
ok: false,
|
|
279
|
+
severity: "warn",
|
|
280
|
+
tool: "bash",
|
|
281
|
+
message: `no Git Bash found — the agent's \`bash\` tool falls back to cmd.exe,\n` +
|
|
282
|
+
` where POSIX commands (ls, which, $VAR, &&) may fail. Install Git\n` +
|
|
283
|
+
` for Windows (https://git-scm.com/download/win) or set ZELARI_SHELL\n` +
|
|
284
|
+
` to your bash binary.`,
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Probe `node --version` from the zelari-code main process (NOT the agent
|
|
289
|
+
* shell). Kept for differential diagnostics: if this passes but
|
|
290
|
+
* `checkAgentNode` fails, the problem is a PATH mismatch between the main
|
|
291
|
+
* process and the agent's bash — not a missing Node install.
|
|
292
|
+
*/
|
|
293
|
+
export function checkMainNode() {
|
|
294
|
+
try {
|
|
295
|
+
const raw = execSync("node --version", {
|
|
296
|
+
encoding: "utf8",
|
|
297
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
298
|
+
}).trim();
|
|
299
|
+
const m = raw.match(/(\d+)\.(\d+)\.(\d+)/);
|
|
300
|
+
const version = m ? `${m[1]}.${m[2]}.${m[3]}` : "";
|
|
301
|
+
const major = Number(version.split(".")[0]);
|
|
302
|
+
if (version && !Number.isNaN(major) && major >= MIN_NODE_MAJOR) {
|
|
303
|
+
return {
|
|
304
|
+
ok: true,
|
|
305
|
+
severity: "critical",
|
|
306
|
+
tool: "node",
|
|
307
|
+
message: `node ${version} (main process)`,
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
return {
|
|
311
|
+
ok: false,
|
|
312
|
+
severity: "warn",
|
|
313
|
+
tool: "node",
|
|
314
|
+
message: `node present in main process but version unparseable or < ${MIN_NODE_MAJOR}: "${raw}"`,
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
catch {
|
|
318
|
+
return {
|
|
319
|
+
ok: false,
|
|
320
|
+
severity: "critical",
|
|
321
|
+
tool: "node",
|
|
322
|
+
message: "node not found on the main process PATH (zelari-code itself runs on node — this is unexpected)",
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Run all prerequisite checks and aggregate. Never throws.
|
|
328
|
+
*
|
|
329
|
+
* @param opts.mode 'preflight' = boot-time gate (node critical, git/bash warn);
|
|
330
|
+
* 'full' = same checks, used by `--doctor` for the full report.
|
|
331
|
+
* Currently identical; the flag is reserved for future
|
|
332
|
+
* heavier checks that shouldn't run on every boot.
|
|
333
|
+
*/
|
|
334
|
+
export function runPrereqChecks(opts = { mode: "preflight" }) {
|
|
335
|
+
const checks = [
|
|
336
|
+
() => checkAgentNode(),
|
|
337
|
+
() => checkAgentGit(),
|
|
338
|
+
() => checkAgentBash(),
|
|
339
|
+
];
|
|
340
|
+
const results = [];
|
|
341
|
+
for (const run of checks) {
|
|
342
|
+
try {
|
|
343
|
+
results.push(run());
|
|
344
|
+
}
|
|
345
|
+
catch (err) {
|
|
346
|
+
// Defensive: a check throwing is itself a failure, never a crash.
|
|
347
|
+
results.push({
|
|
348
|
+
ok: false,
|
|
349
|
+
severity: "warn",
|
|
350
|
+
tool: "node",
|
|
351
|
+
message: `prereq check crashed: ${err instanceof Error ? err.message : String(err)}`,
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
const hasCriticalFail = results.some((r) => !r.ok && r.severity === "critical");
|
|
356
|
+
const warnings = results.filter((r) => !r.ok && r.severity === "warn");
|
|
357
|
+
// Reference opts.mode so it stays meaningful even while behaviour is identical
|
|
358
|
+
// across modes today (reserved for future full-only checks).
|
|
359
|
+
void opts.mode;
|
|
360
|
+
return { results, hasCriticalFail, warnings };
|
|
361
|
+
}
|
|
362
|
+
//# sourceMappingURL=prereqChecks.js.map
|