Skip to content

agent friendliness #62

@kalil0321

Description

@kalil0321

After self-driving the CLI as if I were an agent (probing --help, error paths, JSON contracts, exit codes), here are the frictions I'd want fixed so another agent can reliably drive reverse-api-engineer for reverse engineering.

Status update (post #60, #63 merge): PR #60 (browser-use/stagehand removal) and PR #63 (tag system removal) have landed on main. PR #61 (the agent-friendly MVP this issue tracks follow-ups for) has been rebased onto the new main and is mergeable. Item #7 below ("tag system undocumented") is now obsolete since the tag system was removed entirely.

PR #61 lands the MVP (agent --json, --no-interactive, normalized payload, list/show JSON edge cases, run --no-interactive / --auto-install, README + --help epilogs). This issue tracks what's missing to make the rest of the surface coherently scriptable.


🔴 Blockers for scripted use

1. reverse-api-engineer (no subcommand) hangs without a TTY

Running the binary with no subcommand drops into the prompt_toolkit REPL. Without a TTY (e.g. a wrapper that forgets the subcommand, or a CI invocation), it blocks on stdin forever. I had to kill it with a timeout.

Fix idea: detect not sys.stdin.isatty() at REPL entry → print --help and sys.exit(2).

2. engineer has no --json or --no-interactive

The natural agent pipeline is:

agent --json  →  run_id  →  engineer <run_id>  →  run <run_id>

…but step 3 has no scripted output, so re-engineering an existing run breaks the contract. (Note: manual is intentionally interactive by design — capture requires a human in the loop — so it's lower priority than engineer.)

The cleanup PR #63 did add engineer --prompt and engineer --fresh, but not the JSON contract.

Fix idea: apply the same --json / --no-interactive / normalized payload to engineer. Same shape as agent --json (with a richer script_path / output_path field for the new client / docs file).


🟡 Medium-severity frictions

3. Top-level --help doesn't advertise scripted features

reverse-api-engineer --help doesn't mention that subcommands accept --json or --no-interactive. An agent inspecting only the top-level help misses the contract entirely.

Fix idea: one-line footer in the root command description, e.g. "Most subcommands accept --json and --no-interactive for scripted use; see <cmd> --help."

4. usage field is opaque / not stable across SDKs

README documents usage as {input_tokens, output_tokens, total_cost}, but the actual content is whatever the engineer SDK emits (Claude vs OpenCode vs Copilot may differ). An agent that reads usage.total_cost can break when the user switches SDK.

Fix idea: normalize usage in _build_agent_payload to a stable subset (e.g. always emit input_tokens, output_tokens, total_cost_usd, cache_read_tokens, cache_write_tokens); leave SDK-specific fields under usage.raw if needed.

5. No --dry-run / --validate on agent

A wrapper can't sanity-check its inputs (URL reachable? prompt non-empty? required API keys present? agent_provider deps installed?) without actually launching a browser. Useful when developing/testing a new wrapper.

Fix idea: agent --dry-run --json resolves the config, validates env (API keys, node version for chrome-mcp, etc.), and emits a manifest of "this is what would run" with status "ok" or "error" — without spinning anything up.

6. Errors leak Python reprs; no machine-readable error_kind

Today an OSError surfaces as "[Errno 13] Permission denied: '/nonexistent'" in the JSON payload's error field. An agent that wants to react differently to config issues vs transient runtime failures vs user input errors has to pattern-match on prose.

Fix idea: add an error_kind field with a small enum (misuse, config_invalid, permission_denied, network, engine_failure, interrupted, unknown) alongside the human-readable error.


🟢 Nice-to-have

7. Tag system undocumented in --help — RESOLVED

Removed in #63. The tag system no longer exists; capabilities live as first-class CLI flags / subcommands. No action needed here.

8. run has no --json

For the MVP it's reasonable that run streams the script's stdout. But for chaining multiple runs, a run --json that wraps {run_id, script, exit_code, stdout, stderr, duration_ms} would help.

9. No CLI surface for the JSON schema version

The payload includes schema_version: 1, good. But there's no way to query "what schema version does this binary support?" without running the command. A wrapper that wants to gate on schema version has to invoke a real run.

Fix idea: reverse-api-engineer --json-schema-version (or surface it in --version).


Suggested order of attack

# Item Impact Effort Status
1 TTY-detect at REPL entry → exit 2 High ~5 lines open
2 --json + --no-interactive on engineer High ~30 lines open
3 Normalize usage to a stable subset Med ~15 lines open
4 error_kind enum in error payloads Med ~10 lines open
5 agent --dry-run Med ~50 lines open
6 Top-level --help mentions --json / --no-interactive Low ~3 lines open
7 Document tags in agent epilog resolved by #63
8 run --json (wrapped) Low ~25 lines open
9 --json-schema-version Low ~5 lines open

Each item is independent and shippable on its own.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions