What you get free
Everything in this section is automatic when you call murliCobra.Execute(root), murliCli.Run(app, args), or murliCli.Wrap(app). No additional code is required.
TTY detection and output routing
When stdout is connected to a terminal, commands produce formatted human-readable output. When stdout is piped, commands produce JSON. The --agent flag forces JSON mode at a TTY for testing or explicit agent invocation.
# TTY — formatted $ mytool query foo Found 1 result # Piped — JSON automatically $ mytool query foo | jq .result # Force JSON at TTY $ mytool query foo --agent
This routing requires no code in your handlers. murli detects the TTY state when NewWriter is called and sets the output format accordingly.
Auto-injected flags
The following flags are added to every command in your CLI automatically:
| Flag | Effect |
|---|---|
| --agent | Forces JSON output regardless of TTY state |
| --schema | Prints the command schema as JSON and exits |
| --force, --yes | Bypasses non-interactive confirmation guards. Handlers check w.IsForced(). |
| --dry-run | Signals dry-run intent. Handlers check w.IsDryRun() and call w.WritePlan(). |
| --profile <name> | Loads a named flag profile before the handler runs |
Auto-mounted subcommands
Three subcommands are mounted on the root command automatically:
| Subcommand | Output |
|---|---|
| describe | Full command tree as a single JSON document. Includes every subcommand, flag, return schema, examples, and capabilities. See Schema · describe. |
| doctor | Health and configuration check output as JSON. Useful for verifying the integration is correctly wired. Only mounted when built with -tags murlidev; excluded from release binaries by default. |
| profile | Profile management subcommands: list, set, use, delete. |
# Full command tree — one JSON document $ mytool describe | jq . # Per-command schema $ mytool query --schema | jq . # Health check (requires -tags murlidev) $ mytool doctor
Structured error envelopes
Any error returned from a command handler is wrapped into an AgentError envelope automatically. The envelope includes an exit code, error type, message, and recoverability signal. Errors are written to stderr; the process exits with the appropriate code.
{
"status": "error",
"code": 1,
"error": "user_error",
"message": "flag --top: invalid value \"abc\" for int flag",
"suggestion": "Check command usage with --schema or --help.",
"recoverable": true,
"schema_version": "1.0",
"tool_version": "1.0.2"
}
Log deduplication
The Logger used by w.Log() and w.Progress() suppresses consecutive identical lines. If your command loops and emits the same status message repeatedly, only the first occurrence is written to stderr. This prevents token waste in agent sessions that run many commands.