@vodmal/vdx-cli 0.5.0 → 0.6.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/README.md CHANGED
@@ -8,14 +8,22 @@ Published on npm as **[@vodmal/vdx-cli](https://www.npmjs.com/package/@vodmal/vd
8
8
 
9
9
  ## Install
10
10
 
11
+ Two equally supported paths:
12
+
11
13
  ```bash
12
- # global install
14
+ # A. Daily-use install — recommended when you run `vdx <verb>` many times per session
13
15
  npm install -g @vodmal/vdx-cli
16
+ vdx audit /path/to/project
14
17
 
15
- # or one-shot via npx (no install)
18
+ # B. Zero-install via npx — recommended for CI runners, one-shot trial, or fresh envs
16
19
  npx -y -p @vodmal/vdx-cli vdx audit /path/to/project
17
20
  ```
18
21
 
22
+ Same binary, same behavior. `npx` adds ~200–500 ms resolve overhead per
23
+ invocation; pick global when you'll run `vdx` repeatedly, npx when you
24
+ don't want anything in your global `node_modules` or you're in an
25
+ ephemeral environment.
26
+
19
27
  ## Use
20
28
 
21
29
  ```bash
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vodmal/vdx-cli",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
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",
@@ -46,12 +46,15 @@
46
46
  "dependencies": {
47
47
  "@modelcontextprotocol/sdk": "^1.29.0",
48
48
  "js-yaml": "^4.1.0",
49
+ "marked": "^15.0.12",
50
+ "marked-terminal": "^7.3.0",
49
51
  "smol-toml": "^1.3.0",
50
52
  "tsx": "^4.19.0",
51
53
  "zod": "^3.23.0"
52
54
  },
53
55
  "devDependencies": {
54
56
  "@types/js-yaml": "^4.0.9",
57
+ "@types/marked-terminal": "^6.1.1",
55
58
  "@types/node": "^22.0.0",
56
59
  "@vitest/coverage-v8": "^4.1.7",
57
60
  "typescript": "^5.6.0",
package/src/index.ts CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  renderResolveError,
12
12
  } from './run.ts';
13
13
  import { audit } from './audit.ts';
14
- import { reportMarkdown, reportJson } from './report.ts';
14
+ import { reportMarkdown, reportJson, reportAnsi } from './report.ts';
15
15
  import { planInit, writeInit, renderPlanSummary } from './init.ts';
16
16
  import {
17
17
  planPublish,
@@ -28,7 +28,7 @@ function usage(): never {
28
28
  process.stderr.write(
29
29
  `Usage:
30
30
  vdx <up|down|build|test|check|fix> run lifecycle verb (via mise run <verb>)
31
- vdx audit <project_path> [--rubric <path>] [--stack <stack>] [--json]
31
+ vdx audit <project_path> [--rubric <path>] [--stack <stack>] [--format=ansi|markdown|json] [--json]
32
32
  vdx init <project_path> [--stack <id>] [--baseline <ref>] [--dry-run] [--force]
33
33
  vdx publish <patch|minor|major> [--dry-run] [--force]
34
34
  `,
@@ -88,8 +88,19 @@ function cmdAudit(opts: ParsedArgs): void {
88
88
  const baselineRef = manifest?.baseline ?? `file://${rubricPath}`;
89
89
  const result = audit(rubric, ctx, overrides, baselineRef, manifest);
90
90
 
91
- if (opts.flags.json) {
91
+ const formatFlag =
92
+ typeof opts.flags.format === 'string' ? opts.flags.format : undefined;
93
+ const wantJson = opts.flags.json === true || formatFlag === 'json';
94
+ const wantMarkdown = formatFlag === 'markdown' || formatFlag === 'md';
95
+ const wantAnsi = formatFlag === 'ansi';
96
+ const isTty = process.stdout.isTTY === true;
97
+
98
+ if (wantJson) {
92
99
  process.stdout.write(reportJson(result) + '\n');
100
+ } else if (wantMarkdown) {
101
+ process.stdout.write(reportMarkdown(result));
102
+ } else if (wantAnsi || (isTty && !formatFlag)) {
103
+ process.stdout.write(reportAnsi(result));
93
104
  } else {
94
105
  process.stdout.write(reportMarkdown(result));
95
106
  }
package/src/report.ts CHANGED
@@ -1,5 +1,16 @@
1
+ import { Marked } from 'marked';
2
+ import { markedTerminal } from 'marked-terminal';
1
3
  import type { AuditResult } from './audit.ts';
2
4
 
5
+ let terminalMarked: Marked | null = null;
6
+ function getTerminalMarked(): Marked {
7
+ if (terminalMarked) return terminalMarked;
8
+ const m = new Marked();
9
+ m.use(markedTerminal({ reflowText: false, tab: 2 }) as never);
10
+ terminalMarked = m;
11
+ return m;
12
+ }
13
+
3
14
  const SYMBOL: Record<string, string> = {
4
15
  aligned: '✅',
5
16
  gap: '⚠️ ',
@@ -47,3 +58,9 @@ export function reportMarkdown(r: AuditResult): string {
47
58
  export function reportJson(r: AuditResult): string {
48
59
  return JSON.stringify(r, null, 2);
49
60
  }
61
+
62
+ export function reportAnsi(r: AuditResult): string {
63
+ const md = reportMarkdown(r);
64
+ const out = getTerminalMarked().parse(md) as string;
65
+ return out.endsWith('\n') ? out : out + '\n';
66
+ }