@vodmal/vdx-cli 0.2.0 → 0.2.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 +44 -32
- package/package.json +3 -3
- package/src/audit.ts +12 -4
- package/src/facts.ts +1 -1
package/README.md
CHANGED
|
@@ -1,51 +1,63 @@
|
|
|
1
|
-
# vdx-cli —
|
|
1
|
+
# @vodmal/vdx-cli — vdx evaluator + MCP server
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Native predicate evaluator for `vdx-rubric-vodmal` + MCP stdio server for the
|
|
4
|
+
Claude Code `vdx` plugin. Decision basis: [docs/decisions.md](../docs/decisions.md)
|
|
5
|
+
D10 (native evaluator, not OPA).
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
Published on npm as **[@vodmal/vdx-cli](https://www.npmjs.com/package/@vodmal/vdx-cli)**.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
7
10
|
|
|
8
11
|
```bash
|
|
9
|
-
|
|
10
|
-
npm install
|
|
12
|
+
# global install
|
|
13
|
+
npm install -g @vodmal/vdx-cli
|
|
14
|
+
|
|
15
|
+
# or one-shot via npx (no install)
|
|
16
|
+
npx -y -p @vodmal/vdx-cli vdx audit /path/to/project
|
|
11
17
|
```
|
|
12
18
|
|
|
13
|
-
##
|
|
19
|
+
## Use
|
|
14
20
|
|
|
15
21
|
```bash
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
22
|
+
vdx audit <project-path> [--json] [--rubric <path>] [--stack <id>]
|
|
23
|
+
vdx init <project-path> [--baseline github.com/org/repo@vX.Y] [--dry-run] [--force]
|
|
24
|
+
vdx-mcp --project <path> # MCP stdio server (used by the plugin)
|
|
19
25
|
```
|
|
20
26
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
`--rubric
|
|
27
|
+
By default the bundled `rubric/vdx-rubric.yaml` is used (a mirror of canonical
|
|
28
|
+
[vdx-rubric-vodmal](https://github.com/VoDmAl/vdx-rubric-vodmal) at the time of
|
|
29
|
+
each CLI release). Override via `--rubric <path>` or the env var `VDX_RUBRIC`.
|
|
24
30
|
|
|
25
|
-
##
|
|
31
|
+
## Dev
|
|
26
32
|
|
|
27
33
|
```bash
|
|
28
|
-
|
|
34
|
+
git clone https://github.com/VoDmAl/vdx
|
|
35
|
+
cd vdx/cli
|
|
36
|
+
npm install
|
|
37
|
+
npm run audit -- /path/to/project --json
|
|
38
|
+
npm run smoke # gauge against 3 calibration references
|
|
39
|
+
npm run typecheck
|
|
29
40
|
```
|
|
30
41
|
|
|
31
|
-
|
|
32
|
-
(telegram / t23b / bookmap). Ожидаемо все capped at L2 на оси `ci`.
|
|
33
|
-
|
|
34
|
-
## Структура
|
|
42
|
+
## Structure
|
|
35
43
|
|
|
36
|
-
- `src/rubric.ts` —
|
|
37
|
-
- `src/manifest.ts` —
|
|
38
|
-
- `src/facts.ts` — fact source loaders (tasks, packages, configs)
|
|
39
|
-
- `src/predicates.ts` — registry
|
|
40
|
-
- `src/evaluator.ts` —
|
|
41
|
-
- `src/scoring.ts` — delta-style
|
|
42
|
-
- `src/audit.ts` —
|
|
43
|
-
- `src/report.ts` — markdown / JSON
|
|
44
|
+
- `src/rubric.ts` — types + YAML loader
|
|
45
|
+
- `src/manifest.ts` — parser for `[vdx]` block in `mise.toml` + `.vdx-overrides.yml`
|
|
46
|
+
- `src/facts.ts` — fact source loaders (tasks, packages, configs, sub-package detection)
|
|
47
|
+
- `src/predicates.ts` — predicate registry (11 functions)
|
|
48
|
+
- `src/evaluator.ts` — recursive evaluator + sugar notation
|
|
49
|
+
- `src/scoring.ts` — delta-style levels, flags for orthogonal axes
|
|
50
|
+
- `src/audit.ts` — orchestrator: overrides + applies_to filter + subpackage-ctx
|
|
51
|
+
- `src/report.ts` — markdown / JSON output
|
|
44
52
|
- `src/index.ts` — CLI entry
|
|
53
|
+
- `src/mcp-server.ts` — MCP stdio server (9 tools)
|
|
54
|
+
- `src/defaults.ts` — bundled rubric resolution
|
|
55
|
+
- `bin/vdx.cjs`, `bin/vdx-mcp.cjs` — Node wrappers (tsx ESM loader in-process)
|
|
45
56
|
|
|
46
|
-
##
|
|
57
|
+
## Not implemented yet
|
|
47
58
|
|
|
48
|
-
- `config_value
|
|
49
|
-
-
|
|
50
|
-
|
|
51
|
-
-
|
|
59
|
+
- `config_value`/`command_succeeds` predicates are stubs (warning at evaluation).
|
|
60
|
+
- Baseline loading from a git ref is documented but evaluator still reads file
|
|
61
|
+
paths only — `baseline:` in `mise.toml` is recorded but does not auto-fetch.
|
|
62
|
+
- Watermark drift (phase 2 of `drift-algorithm.md`).
|
|
63
|
+
- O25/O26/O27/O33/O34 — see [docs/decisions.md](../docs/decisions.md).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vodmal/vdx-cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
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",
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
},
|
|
24
24
|
"type": "module",
|
|
25
25
|
"bin": {
|
|
26
|
-
"vdx": "
|
|
27
|
-
"vdx-mcp": "
|
|
26
|
+
"vdx": "bin/vdx.cjs",
|
|
27
|
+
"vdx-mcp": "bin/vdx-mcp.cjs"
|
|
28
28
|
},
|
|
29
29
|
"files": [
|
|
30
30
|
"src",
|
package/src/audit.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as fs from 'node:fs';
|
|
2
2
|
import * as path from 'node:path';
|
|
3
3
|
import type { Rubric, LevelName } from './rubric.ts';
|
|
4
|
-
import { findSubPackages, type Ctx } from './facts.ts';
|
|
4
|
+
import { findSubPackages, stackForDir, type Ctx } from './facts.ts';
|
|
5
5
|
import type { Override, VdxManifest } from './manifest.ts';
|
|
6
6
|
import { evalAxis, projectLevel, type AxisResult } from './scoring.ts';
|
|
7
7
|
|
|
@@ -33,12 +33,14 @@ function resolveSubpackageCtx(
|
|
|
33
33
|
manifest: VdxManifest | null,
|
|
34
34
|
): { ctx: Ctx; relPath: string | null } {
|
|
35
35
|
let relPath: string | null = null;
|
|
36
|
+
let subpackageStack: string | null = null;
|
|
36
37
|
|
|
37
38
|
if (manifest?.primary_subpackage) {
|
|
38
39
|
const p = manifest.primary_subpackage;
|
|
39
40
|
const abs = path.join(ctx.projectRoot, p);
|
|
40
41
|
if (fs.existsSync(abs)) {
|
|
41
42
|
relPath = p;
|
|
43
|
+
subpackageStack = stackForDir(abs);
|
|
42
44
|
} else {
|
|
43
45
|
process.stderr.write(
|
|
44
46
|
`warning: primary_subpackage "${p}" does not exist — falling back to root\n`,
|
|
@@ -49,6 +51,12 @@ function resolveSubpackageCtx(
|
|
|
49
51
|
const matching = subs.filter((s) => s.stack === ctx.stack);
|
|
50
52
|
if (matching.length === 1) {
|
|
51
53
|
relPath = matching[0]!.relPath;
|
|
54
|
+
subpackageStack = matching[0]!.stack;
|
|
55
|
+
} else if (matching.length === 0 && subs.length === 1) {
|
|
56
|
+
// O33: single sub-package with a stack different from ctx.stack —
|
|
57
|
+
// adopt it so applies_to-axes for that stack can evaluate.
|
|
58
|
+
relPath = subs[0]!.relPath;
|
|
59
|
+
subpackageStack = subs[0]!.stack;
|
|
52
60
|
}
|
|
53
61
|
}
|
|
54
62
|
|
|
@@ -56,7 +64,7 @@ function resolveSubpackageCtx(
|
|
|
56
64
|
return {
|
|
57
65
|
ctx: {
|
|
58
66
|
projectRoot: path.join(ctx.projectRoot, relPath),
|
|
59
|
-
stack: ctx.stack,
|
|
67
|
+
stack: subpackageStack ?? ctx.stack,
|
|
60
68
|
cache: new Map(),
|
|
61
69
|
},
|
|
62
70
|
relPath,
|
|
@@ -96,7 +104,8 @@ export function audit(
|
|
|
96
104
|
});
|
|
97
105
|
continue;
|
|
98
106
|
}
|
|
99
|
-
|
|
107
|
+
const evalCtx = axis.applies_to ? subpackageCtx : ctx;
|
|
108
|
+
if (axis.applies_to && !axis.applies_to.includes(evalCtx.stack)) {
|
|
100
109
|
perAxis.push({
|
|
101
110
|
axis_id: axis.id,
|
|
102
111
|
class: axis.class,
|
|
@@ -106,7 +115,6 @@ export function audit(
|
|
|
106
115
|
});
|
|
107
116
|
continue;
|
|
108
117
|
}
|
|
109
|
-
const evalCtx = axis.applies_to ? subpackageCtx : ctx;
|
|
110
118
|
const achieved = evalAxis(axis, evalCtx);
|
|
111
119
|
const ov = overrideByAxis.get(axis.id);
|
|
112
120
|
const target = (ov?.target as LevelName) ?? axis.default_target;
|
package/src/facts.ts
CHANGED
|
@@ -216,7 +216,7 @@ const MANIFEST_TO_STACK: Array<[string, string]> = [
|
|
|
216
216
|
['requirements.txt', 'python'],
|
|
217
217
|
];
|
|
218
218
|
|
|
219
|
-
function stackForDir(dir: string): string | null {
|
|
219
|
+
export function stackForDir(dir: string): string | null {
|
|
220
220
|
for (const [manifest, stack] of MANIFEST_TO_STACK) {
|
|
221
221
|
if (fs.existsSync(path.join(dir, manifest))) return stack;
|
|
222
222
|
}
|