Can you read this tweet: https://x.com/ericzakariasson/status/2036762680401223946
Can you take a look at our CLI and based on some of the recommendations in the article, make some recommendations on how to harden our CLI to be more agent friendly.
I couldn’t read the X page directly, but I recovered the linked article from a public mirror. The title was Building CLIs for agents, and the main themes were: make commands fully non-interactive, make --help locally discoverable and example-heavy, accept stdin, fail fast with actionable errors, keep mutating commands idempotent, add --dry-run, use predictable naming, and return structured output.
What’s Already Good
share, list, setup, and remove skills already have solid JSON envelopes with ok/data/error, which is a strong base for agent usage: cli/src/commands/share.ts:721, cli/src/commands/list.ts:197, cli/src/commands/setup.ts:710, cli/src/commands/remove-skills.ts:383share already has good headless-discovery ideas: explicit selectors, env hints, and --list fallback: docs/cli.md:111--key and TRACES_API_KEY, not just browser login: docs/cli.md:83cli/src/commands/setup.ts:644, cli/src/commands/hooks.ts:127Biggest Hardening Gaps
cli/src/commands/share-options.ts:3, cli/src/commands/list-options.ts:13, cli/src/commands/setup-options.ts:3, cli/src/commands/remove-skills-options.ts:3--help, and examples are sparse: cli/src/index.ts:150, cli/src/commands/setup.ts:400status, doctor, whoami, namespace, and transfer: cli/src/commands/status.ts:66, cli/src/commands/doctor.ts:319, cli/src/commands/whoami.ts:20, cli/src/commands/namespace.ts:159, cli/src/commands/transfer.ts:5--dry-run, and confirmation behavior is inconsistent: cli/src/commands/reset.ts:58, cli/src/commands/remove-skills.ts:280, cli/src/commands/hooks.ts:201, cli/src/index.ts:265cli/src/commands/reset.ts:44Recommended Order
INVALID_ARGUMENTS with a suggestion like “did you mean --cwd?”. Right now an agent typo can silently do the wrong thing.traces <command> --help for every nontrivial command, with 2–4 concrete examples each. setup --help is the right direction; apply it everywhere.--json to every automation-relevant command and standardize on one contract: payload on stdout, diagnostics on stderr, stable ok/data/error.code/error.message.--non-interactive mode. In that mode, any prompt should become a structured error telling the caller which flags are required instead.--dry-run to all mutating/destructive commands: reset, remove skills, remove git, setup git, transfer, and uninstall.--trace-id -, --to -, or a shared --input json mode.share --cwd vs list --dir is harder for agents to infer than it needs to be; same with --key vs a clearer alias like --api-key.2 for invalid args in some commands; make that universal.If I were prioritizing purely for agent-friendliness, I’d do these first:
If you want, I can turn this into a concrete implementation plan for cli/ with command-by-command changes and suggested output schemas.
argument parsing strict < what does this mean? give example
Strict argument parsing means: if the caller passes anything invalid, the CLI errors immediately instead of silently ignoring it.
Right now some of your parsers are permissive. For example, cli/src/commands/share-options.ts:3 and cli/src/commands/list-options.ts:13 skip unknown flags, and you even test for that in cli/src/commands/share-options.test.ts:93.
Concrete example:
Current behavior:
What happens now:
--jsno is ignoredStrict behavior:
Why this matters for agents:
A few more examples of “strict”:
permissive: ignores typo, may open an interactive confirm prompt and hang automation
strict: Unknown option --yees. Did you mean --yes?
Missing value
strict: Missing value for --trace-id
Invalid enum
strict: Invalid value for --visibility. Use public, direct, or private.
Extra positional args
Unexpected argument extraYou already do some strict validation later in cli/src/commands/share.ts:467 for things like invalid --visibility or conflicting selectors. My recommendation was to push that strictness down into the parsing layer too, especially for unknown flags and missing values.
If you want, I can sketch what a stricter parser API would look like for share, list, and remove skills.
okay i like all your recommendations. 6 and 7 might break existsing clients so backcompat is required.
Yep — I’d treat 6 and 7 as additive, not replacements.
stdin support: keep current flags exactly as-is, and only read stdin when the caller opts in explicitly
Good backcompat pattern:
traces share --trace-id - -> read one trace id from stdintraces transfer --to team --trace-id - -> read id from stdin--from-stdin / --input json as new opt-in flagsAvoid auto-reading piped stdin just because input exists; that’s what usually breaks existing scripts
Naming normalization: add aliases, keep current names canonical internally
Good backcompat pattern:
--cwd, add --dir as alias for share--dir, add --cwd as alias for list--key, add --api-key and maybe --token as aliasesParse all aliases into the same internal field, and keep existing docs/examples working
A safe rollout would be:
--help--jsonExample of strict + backcompat together:
This should work because --api-key is an alias for --key.
But this should fail:
with:
That gives you stricter agent behavior without breaking existing clients.
If you want, I can turn the recommendations into:
Do 1
Lets create a worktree and do this work in there