@vodmal/vdx-cli 0.8.0 → 0.8.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vodmal/vdx-cli",
3
- "version": "0.8.0",
3
+ "version": "0.8.2",
4
4
  "description": "vdx — unified lifecycle interface (up/down/build/test/check/fix) + versioned maturity audit with drift detection. Pairs with the vdx Claude Code plugin.",
5
5
  "keywords": [
6
6
  "vdx",
package/src/doctor.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import * as fs from 'node:fs';
2
2
  import * as os from 'node:os';
3
3
  import * as path from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
4
5
  import { execFileSync } from 'node:child_process';
5
6
 
6
7
  export type CheckStatus = 'ok' | 'warning' | 'missing';
@@ -15,12 +16,27 @@ export interface CheckResult {
15
16
  }
16
17
 
17
18
  export interface DoctorReport {
19
+ cliVersion: string;
18
20
  checks: CheckResult[];
19
21
  ok: number;
20
22
  warning: number;
21
23
  missing: number;
22
24
  }
23
25
 
26
+ function readCliVersion(): string {
27
+ try {
28
+ const pkgPath = path.resolve(
29
+ path.dirname(fileURLToPath(import.meta.url)),
30
+ '..',
31
+ 'package.json',
32
+ );
33
+ const raw = JSON.parse(fs.readFileSync(pkgPath, 'utf8')) as { version?: string };
34
+ return raw.version ?? 'unknown';
35
+ } catch {
36
+ return 'unknown';
37
+ }
38
+ }
39
+
24
40
  function probeVersion(binary: string, args: string[] = ['--version']): string | null {
25
41
  try {
26
42
  const out = execFileSync(binary, args, { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] });
@@ -160,25 +176,53 @@ function findOnPath(name: string): string | null {
160
176
  return null;
161
177
  }
162
178
 
179
+ function isEphemeralPath(p: string): 'npx-cache' | 'local-bin' | null {
180
+ if (p.includes(`${path.sep}.npm${path.sep}_npx${path.sep}`)) return 'npx-cache';
181
+ if (p.includes(`${path.sep}node_modules${path.sep}.bin${path.sep}`)) return 'local-bin';
182
+ return null;
183
+ }
184
+
163
185
  function checkVdxOnPath(): CheckResult {
164
186
  const found = findOnPath('vdx');
165
- if (found) {
187
+ if (!found) {
166
188
  return {
167
189
  id: 'vdx-on-path',
168
- label: 'vdx on PATH',
190
+ label: 'vdx install',
191
+ status: 'warning',
192
+ level: 1,
193
+ message:
194
+ '`vdx` not on PATH at check time. If you use a shell alias it is also fine — doctor cannot detect aliases.',
195
+ remedy:
196
+ 'npm i -g @vodmal/vdx-cli OR alias vdx="npx -y -p @vodmal/vdx-cli vdx" OR keep using `npx -y -p @vodmal/vdx-cli vdx …` ad-hoc',
197
+ };
198
+ }
199
+ const ephemeral = isEphemeralPath(found);
200
+ if (ephemeral === 'npx-cache') {
201
+ return {
202
+ id: 'vdx-on-path',
203
+ label: 'vdx install',
169
204
  status: 'ok',
170
- level: 4,
171
- message: found,
205
+ level: 3,
206
+ message:
207
+ `via npx cache: ${found} — invoked-only (shell command \`vdx\` will not resolve outside npx). ` +
208
+ `For shell-global command run: npm i -g @vodmal/vdx-cli OR alias vdx="npx -y -p @vodmal/vdx-cli vdx".`,
209
+ };
210
+ }
211
+ if (ephemeral === 'local-bin') {
212
+ return {
213
+ id: 'vdx-on-path',
214
+ label: 'vdx install',
215
+ status: 'ok',
216
+ level: 2,
217
+ message: `local node_modules: ${found} (works inside this project only)`,
172
218
  };
173
219
  }
174
220
  return {
175
221
  id: 'vdx-on-path',
176
- label: 'vdx on PATH',
177
- status: 'warning',
178
- level: 1,
179
- message: 'binary not on PATH — `vdx <verb>` will not work directly in shell',
180
- remedy:
181
- 'npm i -g @vodmal/vdx-cli (or alias vdx="npx -y -p @vodmal/vdx-cli vdx")',
222
+ label: 'vdx install',
223
+ status: 'ok',
224
+ level: 4,
225
+ message: `global: ${found}`,
182
226
  };
183
227
  }
184
228
 
@@ -235,7 +279,7 @@ export function runDoctor(): DoctorReport {
235
279
  const ok = checks.filter((c) => c.status === 'ok').length;
236
280
  const warning = checks.filter((c) => c.status === 'warning').length;
237
281
  const missing = checks.filter((c) => c.status === 'missing').length;
238
- return { checks, ok, warning, missing };
282
+ return { cliVersion: readCliVersion(), checks, ok, warning, missing };
239
283
  }
240
284
 
241
285
  const PROJECT_MARKER_FILES = [
package/src/report.ts CHANGED
@@ -76,6 +76,7 @@ export function reportDoctorMarkdown(r: DoctorReport): string {
76
76
  const lines: string[] = [];
77
77
  lines.push('# vdx doctor report');
78
78
  lines.push('');
79
+ lines.push(`- **@vodmal/vdx-cli version**: \`${r.cliVersion}\``);
79
80
  lines.push(
80
81
  `- **OK**: ${r.ok} **Warning**: ${r.warning} **Missing**: ${r.missing}`,
81
82
  );