feat(cli): support space-separated multi-word verbs
`ncl groups config get` now works alongside `ncl groups config-get`. Parser joins all positionals with dashes; dispatcher falls back by trimming the last segment as a target ID (`ncl groups get abc123`). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -165,12 +165,9 @@ function parseArgv(argv: string[]): {
|
|||||||
process.exit(2);
|
process.exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
const command = positional.length >= 2 ? `${positional[0]}-${positional[1]}` : positional[0];
|
// Join all positionals with dashes. The dispatcher trims the last
|
||||||
|
// segment as a target ID if the full name isn't a registered command.
|
||||||
// Third positional is the target ID
|
const command = positional.join('-');
|
||||||
if (positional.length >= 3) {
|
|
||||||
args.id = positional[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
return { command, args, json };
|
return { command, args, json };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,20 +85,11 @@ function parseArgv(argv: string[]): {
|
|||||||
process.exit(2);
|
process.exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Single word: `ncl help`
|
// Join all positionals with dashes to form the command name.
|
||||||
// Two words: `ncl groups list`, `ncl groups help`
|
// If the full name isn't a command, the dispatcher will try trimming
|
||||||
// Three words: `ncl groups get abc123`
|
// the last segment and using it as the target ID (e.g. `groups get abc`
|
||||||
let command: string;
|
// → command "groups-get", id "abc").
|
||||||
if (positional.length === 1) {
|
const command = positional.join('-');
|
||||||
command = positional[0];
|
|
||||||
} else {
|
|
||||||
command = `${positional[0]}-${positional[1]}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Third positional is the target ID
|
|
||||||
if (positional.length >= 3) {
|
|
||||||
args.id = positional[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
return { command, args, json };
|
return { command, args, json };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,25 @@ import type { CallerContext, ErrorCode, RequestFrame, ResponseFrame } from './fr
|
|||||||
import { lookup } from './registry.js';
|
import { lookup } from './registry.js';
|
||||||
|
|
||||||
export async function dispatch(req: RequestFrame, ctx: CallerContext): Promise<ResponseFrame> {
|
export async function dispatch(req: RequestFrame, ctx: CallerContext): Promise<ResponseFrame> {
|
||||||
const cmd = lookup(req.command);
|
let cmd = lookup(req.command);
|
||||||
|
|
||||||
|
// Fallback: if the full command isn't registered, trim the last
|
||||||
|
// dash-segment and treat it as the target ID. This lets clients join
|
||||||
|
// all positional args with dashes (e.g. `ncl groups get abc123`
|
||||||
|
// → command "groups-get-abc123" → trim → "groups-get" + id "abc123").
|
||||||
|
if (!cmd) {
|
||||||
|
const idx = req.command.lastIndexOf('-');
|
||||||
|
if (idx > 0) {
|
||||||
|
const shortened = req.command.slice(0, idx);
|
||||||
|
const tail = req.command.slice(idx + 1);
|
||||||
|
const fallback = lookup(shortened);
|
||||||
|
if (fallback) {
|
||||||
|
cmd = fallback;
|
||||||
|
req = { ...req, command: shortened, args: { ...req.args, id: req.args.id ?? tail } };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!cmd) {
|
if (!cmd) {
|
||||||
return err(req.id, 'unknown-command', `no command "${req.command}"`);
|
return err(req.id, 'unknown-command', `no command "${req.command}"`);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user