Skip to main content
Welcome. This site supports keyboard navigation and screen readers. Press ? at any time for keyboard shortcuts. Press [ to focus the sidebar, ] to focus the content. High-contrast themes are available via the toolbar.
serard@dev00:~/cv

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:

  1. -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.
  2. list → render every registered task across every plugin, sorted alphabetically by fullName, with each task's description and originating plugin id.
  3. No colon in the first argument → invalid; the dispatcher refuses with exit code 1.
  4. Task lookup: walk the plugins (sorted by priority, then id), find the first task whose fullName matches. Not found → exit code 1 with a hint to run ddd list.
  5. 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);

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').


  • Hosts every CLI plugin — each plugin contributes a bundle of tasks.
  • Built on the CLI Kernel — the DddCliTask, DddCliPlugin, sortPlugins, findTask primitives.
  • A task may dispatch a @CliTask, forwarding through the @Mediator to a @CommandHandler — the corpus's CLI uses the same dispatch shape as its HTTP and message-bus paths.

Back to the series index.

⬇ Download