Single entrypoint for the standalone Taskweft binary (issue #53).
Unifies the two historical entrypoints — the C++ cli/main.cpp planner
and the Elixir mix taskweft.mcp server — behind one dispatcher so a
Burrito-packaged binary can serve both without a dev toolchain.
Subcommands
taskweft plan <domain.jsonld> plan from a self-contained file
taskweft plan --problem <domain> <problem> plan from split domain + problem
taskweft plan plan from JSON-LD on stdin
taskweft replan <fail_step> <domain> [problem] replan after a step failure (JSON)
taskweft mcp [--http] [--port N] [--host H] run the MCP server (stdio / HTTP)
taskweft version print version + build commit
taskweft help print this usageThe legacy --replan / --problem flag forms from the C++ CLI are accepted
as aliases, and a bare taskweft <domain.jsonld> (no subcommand) plans that
file, so existing callers keep working.
I/O contract
plan prints the bare JSON array of steps ([["a", "arg"], ...]) that the
C++ CLI emitted, so byte-for-byte callers are unaffected. replan prints
the planner's JSON envelope. Domain + problem pairs are merged the same way
the C++ TwLoader::load_file_pair
merges them: problem variables override domain state by name, problem
methods / actions / goal_methods extend or override the domain, and a
non-empty problem tasks replaces the domain task list.
Structure
run/1 is pure with respect to process control — it returns a tagged
result and never writes to a device or halts, so it is unit-testable.
main/1 is the release entrypoint: it resolves argv (via Burrito when
packaged), calls run/1, prints, and halts.
Summary
Functions
Burrito/release entrypoint. Resolves argv, dispatches, prints, and halts.
Dispatch argv to a subcommand and return its outcome without doing IO.
Types
@type outcome() :: {:ok, iodata()} | {:error, iodata(), non_neg_integer()} | {:mcp, keyword()}
Outcome of run/1 — never performs IO or halts the VM.