claude-nomad 0.29.1 → 0.30.0
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/CHANGELOG.md +12 -0
- package/README.md +3 -2
- package/package.json +1 -1
- package/src/commands.doctor.checks.deps.ts +97 -0
- package/src/commands.doctor.ts +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.30.0](https://github.com/funkadelic/claude-nomad/compare/v0.29.1...v0.30.0) (2026-05-29)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Added
|
|
7
|
+
|
|
8
|
+
* **doctor:** report gh and curl presence in Version Checks ([#175](https://github.com/funkadelic/claude-nomad/issues/175)) ([5163833](https://github.com/funkadelic/claude-nomad/commit/516383301dbd9c64cfc8f1c7a654655b61c29280))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
* widen npm-publish smoke-test propagation window ([#176](https://github.com/funkadelic/claude-nomad/issues/176)) ([f8b1eef](https://github.com/funkadelic/claude-nomad/commit/f8b1eef18dcee91fb894d2036c42356f82c76f79))
|
|
14
|
+
|
|
3
15
|
## [0.29.1](https://github.com/funkadelic/claude-nomad/compare/v0.29.0...v0.29.1) (2026-05-29)
|
|
4
16
|
|
|
5
17
|
|
package/README.md
CHANGED
|
@@ -380,10 +380,11 @@ Read these before adopting so you opt in with eyes open.
|
|
|
380
380
|
|
|
381
381
|
- `gh` ([GitHub CLI](https://cli.github.com/)), used only by `nomad init` to auto-disable Actions on
|
|
382
382
|
the private repo; if it is missing or unauthenticated, init prints a manual fallback tip and
|
|
383
|
-
continues
|
|
383
|
+
continues. `nomad doctor` reports its presence in the Version Checks section.
|
|
384
384
|
- [curl](https://curl.se/), used by the version/update check (the `nomad doctor` latest-release line
|
|
385
385
|
and the post-`nomad update` check) and by `nomad doctor --check-schema`; it degrades silently when
|
|
386
|
-
curl is absent or offline, so the rest of the CLI works without it
|
|
386
|
+
curl is absent or offline, so the rest of the CLI works without it. `nomad doctor` reports its
|
|
387
|
+
presence in the Version Checks section.
|
|
387
388
|
|
|
388
389
|
## Setup
|
|
389
390
|
|
package/package.json
CHANGED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { execFileSync } from 'node:child_process';
|
|
2
|
+
|
|
3
|
+
import { green, okGlyph, warnGlyph, yellow } from './color.ts';
|
|
4
|
+
import { addItem, type DoctorSection } from './commands.doctor.format.ts';
|
|
5
|
+
import type { SpawnSyncFn } from './gh-actions.ts';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Optional-dependency presence reporter for `nomad doctor`. Probes for `gh`
|
|
9
|
+
* and `curl` (both optional CLIs used by nomad features) and emits one row
|
|
10
|
+
* per binary in the Version Checks section:
|
|
11
|
+
* - present with parsed version: `okGlyph gh: X.Y.Z`
|
|
12
|
+
* - present but version unparseable: `okGlyph gh: present`
|
|
13
|
+
* - not installed (ENOENT): `warnGlyph gh: not installed (optional; ...)`
|
|
14
|
+
*
|
|
15
|
+
* This reporter MUST NOT set `process.exitCode`: absent optional deps are
|
|
16
|
+
* informational only (D-02). Both probes always run unconditionally.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Regex to extract the first X.Y.Z version token from a string. Each segment
|
|
21
|
+
* is bounded (`{1,9}`) rather than `+` so the pattern is provably linear: a
|
|
22
|
+
* `--version` line never has a segment longer than a few digits, and bounding
|
|
23
|
+
* the repetition removes the super-linear backtracking an unbounded
|
|
24
|
+
* `\d+\.\d+\.\d+` carries on a degenerate all-digit input.
|
|
25
|
+
*/
|
|
26
|
+
const VERSION_TOKEN = /(\d{1,9}\.\d{1,9}\.\d{1,9})/;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Extract the first X.Y.Z-shaped version token from a string.
|
|
30
|
+
*
|
|
31
|
+
* @param line - A single line of --version output (already trimmed).
|
|
32
|
+
* @returns The first version token, or `null` if none found.
|
|
33
|
+
*/
|
|
34
|
+
function parseFirstVersion(line: string): string | null {
|
|
35
|
+
const m = VERSION_TOKEN.exec(line);
|
|
36
|
+
return m ? m[1] : null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Discriminated union for binary probe results. */
|
|
40
|
+
type DepProbeResult = { status: 'present'; version: string | null } | { status: 'not-installed' };
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Probe a binary by running `bin --version` and parsing the first output line.
|
|
44
|
+
* Returns a DepProbeResult: present (with optional version token) or
|
|
45
|
+
* not-installed (ENOENT). Non-ENOENT errors are treated as present with no
|
|
46
|
+
* version (D-03: "never FAIL on unexpected --version output").
|
|
47
|
+
*
|
|
48
|
+
* @param bin - The binary name to probe (e.g. `gh` or `curl`).
|
|
49
|
+
* @param run - Injectable subprocess runner; defaults to `execFileSync`.
|
|
50
|
+
*/
|
|
51
|
+
function probeOptionalDep(bin: string, run: SpawnSyncFn): DepProbeResult {
|
|
52
|
+
try {
|
|
53
|
+
const firstLine = run(bin, ['--version'], { stdio: ['ignore', 'pipe', 'pipe'] })
|
|
54
|
+
.toString()
|
|
55
|
+
.split('\n')[0]
|
|
56
|
+
.trim();
|
|
57
|
+
const version = parseFirstVersion(firstLine);
|
|
58
|
+
return { status: 'present', version };
|
|
59
|
+
} catch (err) {
|
|
60
|
+
if ((err as NodeJS.ErrnoException).code === 'ENOENT') {
|
|
61
|
+
return { status: 'not-installed' };
|
|
62
|
+
}
|
|
63
|
+
// Non-ENOENT: binary may exist but --version misbehaved; report as present.
|
|
64
|
+
return { status: 'present', version: null };
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Emit presence rows for the optional `gh` and `curl` CLIs into the given
|
|
70
|
+
* doctor section. Each row shows the binary's install status and version (if
|
|
71
|
+
* parseable). Absent binaries emit a WARN naming the features they enable.
|
|
72
|
+
* Never sets `process.exitCode` (D-02): both deps are optional.
|
|
73
|
+
*
|
|
74
|
+
* @param section - The Version Checks section to append rows to.
|
|
75
|
+
* @param run - Injectable subprocess runner; defaults to `execFileSync`.
|
|
76
|
+
*/
|
|
77
|
+
export function reportOptionalDeps(section: DoctorSection, run: SpawnSyncFn = execFileSync): void {
|
|
78
|
+
const gh = probeOptionalDep('gh', run);
|
|
79
|
+
if (gh.status === 'present') {
|
|
80
|
+
addItem(section, `${green(okGlyph)} gh: ${gh.version ?? 'present'}`);
|
|
81
|
+
} else {
|
|
82
|
+
addItem(
|
|
83
|
+
section,
|
|
84
|
+
`${yellow(warnGlyph)} gh: not installed (optional; needed for nomad init Actions auto-disable + mirror-Actions drift check)`,
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const curl = probeOptionalDep('curl', run);
|
|
89
|
+
if (curl.status === 'present') {
|
|
90
|
+
addItem(section, `${green(okGlyph)} curl: ${curl.version ?? 'present'}`);
|
|
91
|
+
} else {
|
|
92
|
+
addItem(
|
|
93
|
+
section,
|
|
94
|
+
`${yellow(warnGlyph)} curl: not installed (optional; needed for release-version staleness check + nomad doctor --check-schema)`,
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
}
|
package/src/commands.doctor.ts
CHANGED
|
@@ -25,6 +25,7 @@ import { REPO_HOME, type PathMap } from './config.ts';
|
|
|
25
25
|
import { reportNodeEngineCheck } from './commands.doctor.engine.ts';
|
|
26
26
|
import { readJsonSafe, renderDoctor, section } from './commands.doctor.format.ts';
|
|
27
27
|
import { reportGitleaksVersionCheck } from './commands.doctor.gitleaks-version.ts';
|
|
28
|
+
import { reportOptionalDeps } from './commands.doctor.checks.deps.ts';
|
|
28
29
|
import { reportMirrorActions } from './commands.doctor.mirror-actions.ts';
|
|
29
30
|
import { reportVersionCheck } from './commands.doctor.version.ts';
|
|
30
31
|
|
|
@@ -85,6 +86,7 @@ export function cmdDoctor(opts: { checkShared?: boolean; checkSchema?: boolean }
|
|
|
85
86
|
reportVersionCheck(version);
|
|
86
87
|
reportNodeEngineCheck(version);
|
|
87
88
|
reportGitleaksVersionCheck(version);
|
|
89
|
+
reportOptionalDeps(version);
|
|
88
90
|
|
|
89
91
|
const sharedScan = section('Shared scan');
|
|
90
92
|
// Reuse the Repository-section readiness probe so reportCheckShared does not
|