Skip to content

feat: Terminalwire.CLI — Thor-style command router#2

Merged
bradgessler merged 1 commit into
mainfrom
cli-dsl
Jun 22, 2026
Merged

feat: Terminalwire.CLI — Thor-style command router#2
bradgessler merged 1 commit into
mainfrom
cli-dsl

Conversation

@bradgessler

Copy link
Copy Markdown
Contributor

Adds use Terminalwire.CLI: public functions become commands, params become args, @desc becomes help — the Elixir analog of Thor's desc/def. Sugar over the existing run/1 handler (still usable for custom parsing). New cli_test.exs (96% module coverage); README/moduledoc/CHANGELOG now lead with the DSL and the value prop is sharpened (no API + no client + no auto-update infra). Full suite 115 passed, total coverage 92%.

Defining a CLI meant a `run(ctx)` handler with a hand-rolled `case Context.args`
dispatch — workable, but nowhere near as clean as Ruby/Thor's `desc`/`def`. Add a
small macro so the module reads like the commands themselves:

    defmodule MyApp.CLI do
      use Terminalwire.CLI, name: "my-app"

      @desc "Greet someone by name"
      def hello(name), do: puts("Hello, #{name}!")
    end

Public functions become commands, their parameters become positional arguments, and
@desc becomes generated `help`. `use` generates `run/1` (mount it on WebSock as
before). Inside a command, puts/print/warn/gets/read_secret/env are imported and
bound to the session context (via the per-session process); `context/0` reaches the
rest (files, browser, raw terminal). Unknown command / wrong arity exits non-zero
with a usage hint. It's sugar over the plain handler, which still works for custom
parsing (Optimus, OptionParser).

- lib/terminalwire/cli.ex — the router (on_definition collects @desc'd defs +
  their arg names for help; before_compile generates run/1).
- test/cli_test.exs — dispatch, multi-arg, exit codes, help, unknown/arity errors,
  the imported helpers, the context guard, introspection (96% module coverage).
- README / moduledoc / CHANGELOG lead with the DSL; README value prop sharpened
  (no API + no client + no release/auto-update pipeline to build).

Total coverage 92%; full suite 115 passed.
@bradgessler bradgessler merged commit 6a3a226 into main Jun 22, 2026
1 check passed
@bradgessler bradgessler deleted the cli-dsl branch June 22, 2026 07:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant