@vodmal/vdx-cli 0.15.0 → 0.16.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 +3 -0
- package/package.json +1 -1
- package/src/index.ts +47 -1
package/README.md
CHANGED
|
@@ -49,6 +49,7 @@ vdx doctor [--format=ansi|markdown|json]
|
|
|
49
49
|
|
|
50
50
|
# Start your agent in a project per your profile (~/.vdx-environment.yaml or $VDX_ENVIRONMENT)
|
|
51
51
|
vdx ai[@host] [project-path] [--new] [--restart] [--detach] [--dry-run] # default: cwd; @host: over ssh, in tmux there
|
|
52
|
+
vdx ai --help # flags, where launch flags live, exit codes
|
|
52
53
|
|
|
53
54
|
# Print the installed version
|
|
54
55
|
vdx --version
|
|
@@ -87,6 +88,8 @@ name. `vdx ai@<host>` runs the same command on `<host>` over ssh — that machin
|
|
|
87
88
|
profile and tmux, the path taken under its home directory; `--detach` only
|
|
88
89
|
starts it. The machine's own label (`$VDX_HOST`) runs here. Where git knows no
|
|
89
90
|
commit author, `vdx ai` proposes one (Enter writes it into `.git/config`).
|
|
91
|
+
`vdx ai --help` (`-h`) prints the help; an unknown option or a second path is
|
|
92
|
+
refused with exit 2, and nothing starts.
|
|
90
93
|
|
|
91
94
|
By default the bundled `rubric/vdx-rubric.yaml` is used (a mirror of canonical
|
|
92
95
|
[vdx-rubric-vodmal](https://github.com/VoDmAl/vdx-rubric-vodmal) at the time of
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vodmal/vdx-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.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",
|
package/src/index.ts
CHANGED
|
@@ -42,12 +42,46 @@ function usage(): never {
|
|
|
42
42
|
vdx publish <patch|minor|major> [--dry-run] [--force]
|
|
43
43
|
vdx doctor [--format=ansi|markdown|json] [--json]
|
|
44
44
|
vdx ai[@host] [project_path] [--new] [--restart] [--detach] [--dry-run] (default: cwd; @host: over ssh, in tmux there)
|
|
45
|
+
vdx ai --help (launch flags, profile, exit codes)
|
|
45
46
|
vdx --version
|
|
46
47
|
`,
|
|
47
48
|
);
|
|
48
49
|
process.exit(1);
|
|
49
50
|
}
|
|
50
51
|
|
|
52
|
+
const AI_USAGE_LINE = 'Usage: vdx ai[@host] [project_path] [--new] [--restart] [--detach] [--dry-run]';
|
|
53
|
+
|
|
54
|
+
const AI_HELP = `${AI_USAGE_LINE}
|
|
55
|
+
|
|
56
|
+
Starts your agent in the project, or attaches to the one already running there.
|
|
57
|
+
Which agent, its flags and whether it runs in tmux come from your profile:
|
|
58
|
+
$VDX_ENVIRONMENT, else ~/.vdx-environment.yaml, else a plain claude/codex.
|
|
59
|
+
|
|
60
|
+
Launch flags live in the profile, not in a command to type: agent.args for
|
|
61
|
+
every project, agent.when[] for a class of projects (a rubric predicate over
|
|
62
|
+
the project's files). Hand a person \`vdx ai\`, not \`<agent> --<flag>\`.
|
|
63
|
+
|
|
64
|
+
project_path the project (default: cwd); its git toplevel is used
|
|
65
|
+
@host the same command on <host> over ssh: its vdx, profile and tmux
|
|
66
|
+
--new a new conversation instead of continuing the last one
|
|
67
|
+
--restart restart the running agent in its pane — applies a changed profile
|
|
68
|
+
--detach start without attaching; print the command that attaches
|
|
69
|
+
--dry-run print the plan and the project's running agents; start nothing
|
|
70
|
+
-h, --help this help
|
|
71
|
+
|
|
72
|
+
Exit codes: 0 the agent runs per the profile; 2 profile or usage error;
|
|
73
|
+
3 the running agent lacks profile flags (rerun with --restart); 4 the start
|
|
74
|
+
was not confirmed.
|
|
75
|
+
Profile format: https://github.com/VoDmAl/vdx/blob/main/docs/specs/environment-format.md
|
|
76
|
+
`;
|
|
77
|
+
|
|
78
|
+
const AI_FLAGS = ['new', 'restart', 'resume', 'detach', 'dry-run', 'help'];
|
|
79
|
+
|
|
80
|
+
function aiUsageError(message: string): never {
|
|
81
|
+
process.stderr.write(`vdx ai: ${message}\n${AI_USAGE_LINE}\nMore: vdx ai --help\n`);
|
|
82
|
+
process.exit(2);
|
|
83
|
+
}
|
|
84
|
+
|
|
51
85
|
interface ParsedArgs {
|
|
52
86
|
cmd: string;
|
|
53
87
|
positionals: string[];
|
|
@@ -264,7 +298,7 @@ function cmdDoctor(opts: ParsedArgs): void {
|
|
|
264
298
|
|
|
265
299
|
function cmdAi(opts: ParsedArgs): void {
|
|
266
300
|
// parseArgs hands the token after a bare flag to that flag as its value;
|
|
267
|
-
// these flags take none, so such a token is the project path.
|
|
301
|
+
// these flags take none, so such a token is the project path (or `-h`).
|
|
268
302
|
const positionals = [...opts.positionals];
|
|
269
303
|
const bool = (name: string): boolean => {
|
|
270
304
|
const v = opts.flags[name];
|
|
@@ -278,6 +312,18 @@ function cmdAi(opts: ParsedArgs): void {
|
|
|
278
312
|
bool('resume');
|
|
279
313
|
const detach = bool('detach');
|
|
280
314
|
const dryRun = bool('dry-run');
|
|
315
|
+
// `vdx ai` starts an agent, so a misread argument must not run it: an agent
|
|
316
|
+
// that tried `vdx ai --help` got a launch in the current directory.
|
|
317
|
+
if (bool('help') || positionals.includes('-h')) {
|
|
318
|
+
process.stdout.write(AI_HELP);
|
|
319
|
+
process.exit(0);
|
|
320
|
+
}
|
|
321
|
+
const unknown = [
|
|
322
|
+
...Object.keys(opts.flags).filter((f) => !AI_FLAGS.includes(f)).map((f) => `--${f}`),
|
|
323
|
+
...positionals.filter((p) => p.startsWith('-')),
|
|
324
|
+
];
|
|
325
|
+
if (unknown.length > 0) aiUsageError(`unknown option ${unknown.join(', ')}`);
|
|
326
|
+
if (positionals.length > 1) aiUsageError(`unexpected argument ${positionals.slice(1).join(' ')}`);
|
|
281
327
|
const options = { path: positionals[0] ?? '.', restart, fresh, detach, dryRun };
|
|
282
328
|
// `ai@m3`: the same command on another machine. Its own label runs here.
|
|
283
329
|
const host = opts.cmd.startsWith('ai@') ? opts.cmd.slice(3) : null;
|