Plugin Dispatch and Help Surface
@frenchexdev/ddd-cli is the framework that hosts the corpus's CLI. The shape is unambiguous: a Symfony 1.4-style namespace:task addressing, plugins contributing tasks by name convention, the dispatcher resolving tasks deterministically by priority then id. The framework itself does not own DDD patterns; it owns the plumbing every plugin shares.
What ddd-cli Reifies
The framework is corpus tooling, not a DDD pattern. There is no analyzer, no codegen, no decorator — the package surface is two exports: the DispatchResult shape that names what happened after a dispatch, and the dispatch(argv, plugins) function that does the dispatching.
The addressing scheme — <namespace>:<task> — is borrowed from Symfony 1.4's sfBaseTask family. The format makes the namespace visible to the user (ddd compliance:report, ddd codegen:run, ddd scaffold:pattern), groups related tasks under the same prefix, and gives plugins a deterministic registration shape: every task in a plugin shares the plugin's namespace by convention.
The Runtime: ddd-cli
dispatcher.ts is the entire framework. The function does five things in order:
-h/--help/help→ render the help surface. The help lists the framework's three intrinsic verbs (<ns>:<task>,list,help) and the count of loaded plugins.list→ render every registered task across every plugin, sorted alphabetically byfullName, with each task's description and originating plugin id.- No colon in the first argument → invalid; the dispatcher refuses with exit code 1.
- Task lookup: walk the plugins (sorted by priority, then id), find the first task whose
fullNamematches. Not found → exit code 1 with a hint to runddd list. - Execute: call
task.execute(argv.slice(1), {})and propagate its exit code.
The return value is a DispatchResult carrying status, exit code, and output. The caller (a thin bin/ddd.ts typically) prints the output and exits with the code.
// Sketch of a bin/ddd.ts entry point:
import { dispatch } from '@frenchexdev/ddd-cli';
import { plugins } from './plugins.js';
const result = await dispatch(process.argv.slice(2), plugins);
console.log(result.output);
process.exit(result.exitCode);// Sketch of a bin/ddd.ts entry point:
import { dispatch } from '@frenchexdev/ddd-cli';
import { plugins } from './plugins.js';
const result = await dispatch(process.argv.slice(2), plugins);
console.log(result.output);
process.exit(result.exitCode);The framework owes the caller deterministic ordering, exhaustive help, and meaningful exit codes. Everything else — what a task actually does, how it parses arguments, where it logs — is the task's responsibility (and the plugins').
Cross-Links
- Hosts every CLI plugin — each plugin contributes a bundle of tasks.
- Built on the CLI Kernel — the
DddCliTask,DddCliPlugin,sortPlugins,findTaskprimitives. - A task may dispatch a
@CliTask, forwarding through the@Mediatorto a@CommandHandler— the corpus's CLI uses the same dispatch shape as its HTTP and message-bus paths.
Back to the series index.