@vodmal/vdx-cli 0.24.0 → 0.26.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 +5 -4
- package/package.json +10 -1
- package/rubric/vdx-rubric.yaml +76 -32
- package/src/ai.ts +221 -76
- package/src/audit.ts +19 -9
- package/src/author.ts +27 -8
- package/src/clone-checks.ts +14 -9
- package/src/conversations.ts +48 -22
- package/src/doctor.ts +14 -15
- package/src/evaluator.ts +21 -20
- package/src/facts.ts +71 -56
- package/src/gha.ts +38 -27
- package/src/hooks.ts +78 -43
- package/src/index.ts +56 -41
- package/src/init.ts +22 -61
- package/src/manifest.ts +25 -4
- package/src/mcp-server.ts +40 -39
- package/src/narrow.ts +56 -0
- package/src/personal-hooks.ts +16 -5
- package/src/predicates.ts +12 -16
- package/src/publish.ts +38 -31
- package/src/report.ts +1 -3
- package/src/rubric.ts +2 -2
- package/src/run.ts +5 -8
- package/src/scoring.ts +2 -8
- package/src/vocabulary.ts +13 -12
package/README.md
CHANGED
|
@@ -77,8 +77,9 @@ vdx test # → mise run test (which calls `vitest run` or whatever wa
|
|
|
77
77
|
# 3. Ship a new minor release of a Node lib
|
|
78
78
|
vdx publish minor # npm login if expired → bump package.json + lock → npm publish (OTP or browser) → commit + tag → push → wait for the registry
|
|
79
79
|
|
|
80
|
-
# 4. Start the agent here, continuing its last conversation (--new: a new one
|
|
81
|
-
# another machine's conversation is continued on
|
|
80
|
+
# 4. Start the agent here, continuing its last conversation (--new: a new one,
|
|
81
|
+
# next to a running agent; another machine's conversation is continued on
|
|
82
|
+
# that machine);
|
|
82
83
|
# re-run to attach; an agent without the profile's flags is a question:
|
|
83
84
|
# Enter attaches as is, r restarts it; --restart applies a changed profile
|
|
84
85
|
vdx ai
|
|
@@ -90,7 +91,7 @@ vdx ai@m3
|
|
|
90
91
|
`vdx ai` reads a personal profile, never a bundled one: `$VDX_ENVIRONMENT`, else
|
|
91
92
|
`~/.vdx-environment.yaml`, else a plain `claude`/`codex` with no flags. Format:
|
|
92
93
|
[docs/specs/environment-format.md](../docs/specs/environment-format.md).
|
|
93
|
-
The session's `{project}` is `[vdx] name` from the project's `mise.toml`, else the
|
|
94
|
+
The session's `{project}` is `[_.vdx] name` (or the older `[vdx]`) from the project's `mise.toml`, else the
|
|
94
95
|
first file in the profile's `session.project_names` that has one, else the repo
|
|
95
96
|
name. `vdx ai@<host>` runs the same command on `<host>` over ssh — that machine's vdx,
|
|
96
97
|
profile and tmux, the path taken under its home directory; `--detach` only
|
|
@@ -125,7 +126,7 @@ npm run typecheck
|
|
|
125
126
|
## Structure
|
|
126
127
|
|
|
127
128
|
- `src/rubric.ts` — types + YAML loader
|
|
128
|
-
- `src/manifest.ts` — parser for `[vdx]` block in `mise.toml` + `.vdx-overrides.yml`
|
|
129
|
+
- `src/manifest.ts` — parser for the `[_.vdx]` block in `mise.toml` (the older `[vdx]` too) + `.vdx-overrides.yml`
|
|
129
130
|
- `src/facts.ts` — fact source loaders (tasks, packages, configs, sub-package detection)
|
|
130
131
|
- `src/predicates.ts` — predicate registry; true / false / unknown with a reason (schema 0.3)
|
|
131
132
|
- `src/evaluator.ts` — recursive evaluator + sugar notation
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vodmal/vdx-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.26.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",
|
|
@@ -39,6 +39,10 @@
|
|
|
39
39
|
"audit": "tsx src/index.ts audit",
|
|
40
40
|
"smoke": "bash smoke.sh",
|
|
41
41
|
"typecheck": "tsc --noEmit",
|
|
42
|
+
"format:check": "prettier --check .",
|
|
43
|
+
"lint": "eslint .",
|
|
44
|
+
"check": "npm run typecheck && npm run format:check && npm run lint",
|
|
45
|
+
"fix": "eslint --fix . && prettier --write .",
|
|
42
46
|
"test": "vitest run",
|
|
43
47
|
"test:unit": "vitest run tests/unit",
|
|
44
48
|
"coverage": "vitest run --coverage"
|
|
@@ -54,11 +58,16 @@
|
|
|
54
58
|
"zod": "^3.23.0"
|
|
55
59
|
},
|
|
56
60
|
"devDependencies": {
|
|
61
|
+
"@eslint/js": "^10.0.1",
|
|
57
62
|
"@types/js-yaml": "^4.0.9",
|
|
58
63
|
"@types/marked-terminal": "^6.1.1",
|
|
59
64
|
"@types/node": "^22.0.0",
|
|
60
65
|
"@vitest/coverage-v8": "^4.1.7",
|
|
66
|
+
"eslint": "^10.12.0",
|
|
67
|
+
"eslint-config-prettier": "^10.1.8",
|
|
68
|
+
"prettier": "^3.9.10",
|
|
61
69
|
"typescript": "^5.6.0",
|
|
70
|
+
"typescript-eslint": "^8.71.2",
|
|
62
71
|
"vitest": "^4.1.7"
|
|
63
72
|
},
|
|
64
73
|
"publishConfig": {
|
package/rubric/vdx-rubric.yaml
CHANGED
|
@@ -11,7 +11,7 @@ schema_version: "0.3"
|
|
|
11
11
|
|
|
12
12
|
metadata:
|
|
13
13
|
name: vdx-rubric-vodmal
|
|
14
|
-
version: "1.
|
|
14
|
+
version: "1.4.2"
|
|
15
15
|
description: "Personal maturity rubric for multi-stack projects (vodmal)"
|
|
16
16
|
owner: vodmal
|
|
17
17
|
homepage: "https://github.com/vodmal/vdx-rubric"
|
|
@@ -35,7 +35,7 @@ axes:
|
|
|
35
35
|
|
|
36
36
|
- id: lifecycle-interface
|
|
37
37
|
class: critical
|
|
38
|
-
description: "Стандартный словарь глаголов up/down/build/test/check/fix"
|
|
38
|
+
description: "Стандартный словарь глаголов up/down/build/test/check/fix (up/down — не у библиотек)"
|
|
39
39
|
storage: level
|
|
40
40
|
default_target: L4
|
|
41
41
|
fact_sources: [mise.toml, composer.json, package.json, Makefile]
|
|
@@ -59,14 +59,39 @@ axes:
|
|
|
59
59
|
- has_task: check
|
|
60
60
|
- has_task: fix
|
|
61
61
|
L3:
|
|
62
|
+
# v1.4.0: up/down — глаголы приложения. Библиотека (lib-intent, D12)
|
|
63
|
+
# выпускается, а не поднимается: от неё L3 требует только остальные четыре.
|
|
62
64
|
requires:
|
|
63
65
|
all_of:
|
|
64
|
-
- has_task: up
|
|
65
|
-
- has_task: down
|
|
66
66
|
- has_task: build
|
|
67
67
|
- has_task: test
|
|
68
68
|
- has_task: check
|
|
69
69
|
- has_task: fix
|
|
70
|
+
- any_of:
|
|
71
|
+
# lib-intent — проект заявляет, что публикует артефакт (O35).
|
|
72
|
+
# Одно определение на сет: release-artifact.applies_when — ссылка сюда.
|
|
73
|
+
- &lib_intent
|
|
74
|
+
any_of:
|
|
75
|
+
# Node-сторона: НЕ private И есть хоть один entry-point/publish-signal.
|
|
76
|
+
- all_of:
|
|
77
|
+
- has_file: package.json
|
|
78
|
+
- not:
|
|
79
|
+
config_value: { path: package.json, jsonpath: "private", equals: true }
|
|
80
|
+
- any_of:
|
|
81
|
+
- config_value: { path: package.json, jsonpath: "publishConfig", op: present }
|
|
82
|
+
- config_value: { path: package.json, jsonpath: "bin", op: present }
|
|
83
|
+
- config_value: { path: package.json, jsonpath: "main", op: present }
|
|
84
|
+
- config_value: { path: package.json, jsonpath: "exports", op: present }
|
|
85
|
+
- config_value: { path: package.json, jsonpath: "module", op: present }
|
|
86
|
+
# PHP-сторона: composer.json есть, name задан, type ≠ project (project = app).
|
|
87
|
+
- all_of:
|
|
88
|
+
- has_file: composer.json
|
|
89
|
+
- config_value: { path: composer.json, jsonpath: "name", op: present }
|
|
90
|
+
- not:
|
|
91
|
+
config_value: { path: composer.json, jsonpath: "type", op: equals, equals: "project" }
|
|
92
|
+
- all_of:
|
|
93
|
+
- has_task: up
|
|
94
|
+
- has_task: down
|
|
70
95
|
L4:
|
|
71
96
|
requires:
|
|
72
97
|
any_of:
|
|
@@ -168,17 +193,24 @@ axes:
|
|
|
168
193
|
predicate: { tsc_flag: { name: noImplicitOverride, equals: true } }
|
|
169
194
|
- id: eslint_flat
|
|
170
195
|
weight: 1.0
|
|
171
|
-
|
|
196
|
+
# Имена flat-конфига — те, что ищет ESLint 10 (lib/config/config-loader.js).
|
|
197
|
+
# Одно определение на сет: code-style ссылается сюда (v1.4.1).
|
|
198
|
+
predicate: &eslint_flat_config
|
|
172
199
|
any_of:
|
|
173
200
|
- has_file: eslint.config.js
|
|
174
201
|
- has_file: eslint.config.mjs
|
|
202
|
+
- has_file: eslint.config.cjs
|
|
175
203
|
- has_file: eslint.config.ts
|
|
204
|
+
- has_file: eslint.config.mts
|
|
205
|
+
- has_file: eslint.config.cts
|
|
176
206
|
- id: eslint_type_checked
|
|
177
207
|
weight: 1.0
|
|
178
208
|
predicate:
|
|
179
209
|
file_contains:
|
|
180
|
-
paths: [eslint.config.js, eslint.config.mjs, eslint.config.ts]
|
|
181
|
-
|
|
210
|
+
paths: [eslint.config.js, eslint.config.mjs, eslint.config.cjs, eslint.config.ts, eslint.config.mts, eslint.config.cts]
|
|
211
|
+
# typescript-eslint во flat-конфиге — recommendedTypeChecked / strictTypeChecked,
|
|
212
|
+
# в .eslintrc было recommended-type-checked (v1.4.1).
|
|
213
|
+
pattern: "(recommended|strict)-?[Tt]ype-?[Cc]hecked"
|
|
182
214
|
level_thresholds: { L4: 0.85, L3: 0.65, L2: 0.35, L1: 0.10 }
|
|
183
215
|
|
|
184
216
|
- id: ci
|
|
@@ -291,9 +323,31 @@ axes:
|
|
|
291
323
|
- has_file: ecs.php
|
|
292
324
|
- has_file: .php-cs-fixer.php
|
|
293
325
|
- has_file: phpcs.xml.dist
|
|
294
|
-
|
|
295
|
-
-
|
|
296
|
-
|
|
326
|
+
# Форматтер: имена конфига — те, что ищет Prettier 3.9, и Biome (v1.4.1).
|
|
327
|
+
- &formatter_config
|
|
328
|
+
any_of:
|
|
329
|
+
- has_file: .prettierrc
|
|
330
|
+
- has_file: .prettierrc.json
|
|
331
|
+
- has_file: .prettierrc.yaml
|
|
332
|
+
- has_file: .prettierrc.yml
|
|
333
|
+
- has_file: .prettierrc.json5
|
|
334
|
+
- has_file: .prettierrc.toml
|
|
335
|
+
- has_file: .prettierrc.js
|
|
336
|
+
- has_file: .prettierrc.mjs
|
|
337
|
+
- has_file: .prettierrc.cjs
|
|
338
|
+
- has_file: .prettierrc.ts
|
|
339
|
+
- has_file: .prettierrc.mts
|
|
340
|
+
- has_file: .prettierrc.cts
|
|
341
|
+
- has_file: prettier.config.js
|
|
342
|
+
- has_file: prettier.config.mjs
|
|
343
|
+
- has_file: prettier.config.cjs
|
|
344
|
+
- has_file: prettier.config.ts
|
|
345
|
+
- has_file: prettier.config.mts
|
|
346
|
+
- has_file: prettier.config.cts
|
|
347
|
+
- config_value: { path: package.json, jsonpath: "prettier", op: present }
|
|
348
|
+
- has_file: biome.json
|
|
349
|
+
- has_file: biome.jsonc
|
|
350
|
+
- *eslint_flat_config
|
|
297
351
|
L3:
|
|
298
352
|
requires:
|
|
299
353
|
any_of:
|
|
@@ -308,8 +362,8 @@ axes:
|
|
|
308
362
|
- has_file: ecs.php
|
|
309
363
|
- has_file: phpcs.xml.dist
|
|
310
364
|
- all_of:
|
|
311
|
-
-
|
|
312
|
-
-
|
|
365
|
+
- *formatter_config
|
|
366
|
+
- *eslint_flat_config
|
|
313
367
|
|
|
314
368
|
- id: dependency-hygiene
|
|
315
369
|
class: supporting
|
|
@@ -519,10 +573,17 @@ axes:
|
|
|
519
573
|
requires:
|
|
520
574
|
any_of:
|
|
521
575
|
- file_contains: { path: scripts/docker-up.sh, pattern: "(traefik|nginx-proxy)" }
|
|
576
|
+
# Манифест vdx — в [_.vdx] (vdx 0.26+) или в старом [vdx]; оба места — с v1.4.2.
|
|
577
|
+
- config_value: { path: mise.toml, jsonpath: "_.vdx.shared_infra.precheck", equals: true }
|
|
522
578
|
- config_value: { path: mise.toml, jsonpath: "vdx.shared_infra.precheck", equals: true }
|
|
523
579
|
L4:
|
|
524
580
|
requires:
|
|
525
581
|
any_of:
|
|
582
|
+
- config_value:
|
|
583
|
+
path: mise.toml
|
|
584
|
+
jsonpath: "_.vdx.shared_infra.provider"
|
|
585
|
+
op: matches
|
|
586
|
+
pattern: "github.com/.+@v\\d+"
|
|
526
587
|
- config_value:
|
|
527
588
|
path: mise.toml
|
|
528
589
|
jsonpath: "vdx.shared_infra.provider"
|
|
@@ -564,26 +625,9 @@ axes:
|
|
|
564
625
|
applies_to: [node, php, ruby, python]
|
|
565
626
|
# O35 (v0.3.1): ось применяется только если проект декларирует намерение
|
|
566
627
|
# публиковать артефакт. Чистые app'ы (private:true в package.json или
|
|
567
|
-
# composer type:project) → excluded.
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
# Node-сторона: НЕ private И есть хоть один entry-point/publish-signal.
|
|
571
|
-
- all_of:
|
|
572
|
-
- has_file: package.json
|
|
573
|
-
- not:
|
|
574
|
-
config_value: { path: package.json, jsonpath: "private", equals: true }
|
|
575
|
-
- any_of:
|
|
576
|
-
- config_value: { path: package.json, jsonpath: "publishConfig", op: present }
|
|
577
|
-
- config_value: { path: package.json, jsonpath: "bin", op: present }
|
|
578
|
-
- config_value: { path: package.json, jsonpath: "main", op: present }
|
|
579
|
-
- config_value: { path: package.json, jsonpath: "exports", op: present }
|
|
580
|
-
- config_value: { path: package.json, jsonpath: "module", op: present }
|
|
581
|
-
# PHP-сторона: composer.json есть, name задан, type ≠ project (project = app).
|
|
582
|
-
- all_of:
|
|
583
|
-
- has_file: composer.json
|
|
584
|
-
- config_value: { path: composer.json, jsonpath: "name", op: present }
|
|
585
|
-
- not:
|
|
586
|
-
config_value: { path: composer.json, jsonpath: "type", op: equals, equals: "project" }
|
|
628
|
+
# composer type:project) → excluded. Определение lib-intent — в
|
|
629
|
+
# lifecycle-interface.L3 (якорь, v1.4.0).
|
|
630
|
+
applies_when: *lib_intent
|
|
587
631
|
storage: level
|
|
588
632
|
default_target: L4
|
|
589
633
|
fact_sources:
|