# How to Debug Generated CLI Commands Using JSON Output and Trace Flags in CLI-Anything

> Debug generated CLI commands using JSON output and trace flags in CLI-Anything. Leverage machine-readable output and targeted troubleshooting for efficient debugging.

- Repository: [✨Data Intelligence Lab@HKU✨/CLI-Anything](https://github.com/HKUDS/CLI-Anything)
- Tags: how-to-guide
- Published: 2026-05-18

---

**CLI-Anything provides orthogonal debugging mechanisms through the `--json` flag for machine-readable output and trace flags (`--trace`, `--debug`) for targeted troubleshooting across all agent harnesses.**

The HKUDS/CLI-Anything repository generates unified command-line interfaces for diverse applications like Zotero, Unreal Insights, and Zoom. When building or troubleshooting these generated CLIs, you need reliable ways to inspect command behavior, capture structured data, and trace execution paths. This guide explains the exact implementation patterns found in [`zotero_cli.py`](https://github.com/HKUDS/CLI-Anything/blob/main/zotero_cli.py) and [`unrealinsights_cli.py`](https://github.com/HKUDS/CLI-Anything/blob/main/unrealinsights_cli.py) to debug generated CLI commands using JSON output and trace flags.

## Understanding the Core Debugging Architecture

CLI-Anything implements two orthogonal systems for debugging: machine-readable JSON output for programmatic inspection, and trace-oriented flags for runtime behavior analysis. Both mechanisms rely on Click's context object (`ctx.obj`) to propagate settings across commands and sessions.

### Machine-Readable Output with `--json`

The `--json` flag appears as a top-level option in every agent harness. In [`zotero/agent-harness/cli_anything/zotero/zotero_cli.py`](https://github.com/HKUDS/CLI-Anything/blob/main/zotero/agent-harness/cli_anything/zotero/zotero_cli.py) at line 183, the flag is defined using `@click.option("--json", is_flag=True, help="")`. Similarly, [`unrealinsights/agent-harness/cli_anything/unrealinsights/unrealinsights_cli.py`](https://github.com/HKUDS/CLI-Anything/blob/main/unrealinsights/agent-harness/cli_anything/unrealinsights/unrealinsights_cli.py) defines this option at line 289 alongside other debugging flags.

When parsing occurs, the flag value is stored in the Click context object. The Zotero harness stores it at lines 189-199:

```python
ctx.obj["json_output"] = json_output

```

The Unreal Insights harness stores it similarly at lines 17-19 within the `cli()` function. This context storage makes the setting reachable from any sub-command, including in REPL mode.

Output routing happens through helper functions. The `emit()` function in [`zotero_cli.py`](https://github.com/HKUDS/CLI-Anything/blob/main/zotero_cli.py) (lines 129-143) checks the flag and either prints JSON or a human-readable message:

```python
def emit(ctx, payload, message):
    if root_json_output(ctx):
        print(json.dumps(payload))
    else:
        print(message)

```

### Trace and Debug Flags for Targeted Troubleshooting

For tools operating on trace files, the Unreal Insights harness provides additional flags. The `--trace` option at line 289 allows you to specify an existing trace file path rather than letting the CLI discover one automatically.

The trace path is stored in a session object via `session.set_trace(trace)`. Sub-commands retrieve it using `_require_trace()` at lines 92-100, which validates file existence and raises a `ClickException` if the trace is missing:

```python
def _require_trace(ctx):
    session = ctx.obj["session"]
    trace = session.get_trace()
    if not trace:
        raise click.ClickException("No trace file specified")
    return trace

```

The `--debug` flag, defined at line 291, toggles verbose error reporting. When enabled, the central error handler `_handle_exc` at lines 291-298 prints full tracebacks instead of concise error messages, making it invaluable for development and CI pipelines.

## Context Propagation and Session Management

Debugging settings persist across command invocations through a shared session pattern. The `Session` object is attached to `ctx.obj["session"]` at lines 13-18 in [`unrealinsights_cli.py`](https://github.com/HKUDS/CLI-Anything/blob/main/unrealinsights_cli.py), ensuring that JSON, trace, and debug settings remain active in REPL mode.

This propagation mechanism means that once you enable `--json` or `--debug` in a command, subsequent commands in the same session inherit those settings. The context dictionary serves as the single source of truth for output formatting preferences throughout the application lifecycle.

## Practical Implementation Examples

Below are minimal implementations demonstrating the debugging patterns used throughout the repository.

### Basic JSON Output Routing

This pattern from [`zotero_cli.py`](https://github.com/HKUDS/CLI-Anything/blob/main/zotero_cli.py) shows how to route output based on the JSON flag:

```python
@click.command()
@click.pass_context
def list_items(ctx):
    # Simulated backend query

    payload = {"items": ["a", "b", "c"], "count": 3}
    
    # Route through emit helper

    emit(ctx, payload, message="Found 3 items: a, b, c")

```

### Trace File Handling with Debug Mode

This example from the Unreal Insights harness demonstrates trace validation and debug error handling:

```python
@click.command()
@click.pass_context
def analyze_trace(ctx):
    # Validates --trace was provided and file exists

    trace_path = _require_trace(ctx)
    
    try:
        result = run_analysis(trace_path)
        _output(ctx, result, _human_analyze_summary)
    except Exception as exc:
        # Respects --debug flag for traceback verbosity

        _handle_exc(ctx, exc)

```

### Running the Examples

Execute these commands to see the debugging flags in action:

```bash

# Human-readable output (default)

cli-anything-zotero collection list

# Machine-readable JSON for piping to jq

cli-anything-zotero collection list --json

# Trace-specific analysis with JSON output

cli-anything-unrealinsights analyze --trace mygame.utrace --json

# Full traceback on errors

cli-anything-unrealinsights analyze --debug

# CI pipeline combination: structured output with full error details

cli-anything-unrealinsights analyze --trace mygame.utrace --json --debug

```

## Debugging Workflows by Use Case

Combine these flags to address specific debugging scenarios:

- **Inspect command structure**: Omit `--json` to see the human-readable command string the CLI would execute.
- **Integrate with scripts**: Add `--json` to emit raw JSON suitable for downstream processing with tools like `jq`.
- **Force specific input**: Use `--trace <path>` to bypass automatic discovery and test against a known file.
- **Surface execution errors**: Add `--debug` to print full Python tracebacks instead of user-friendly error messages.
- **CI/CD debugging**: Combine `--json --debug` to get structured output alongside complete stack traces when exceptions occur.

## Summary

- **`--json` flag**: Defined in agent harnesses like [`zotero_cli.py`](https://github.com/HKUDS/CLI-Anything/blob/main/zotero_cli.py) (line 183), stored in `ctx.obj["json_output"]`, and processed by `emit()` helpers (lines 129-143) to toggle between human-readable and machine-readable output.
- **Trace flags**: The `--trace` option in [`unrealinsights_cli.py`](https://github.com/HKUDS/CLI-Anything/blob/main/unrealinsights_cli.py) (line 289) stores paths in session objects, validated by `_require_trace()` (lines 92-100) for commands requiring trace file inputs.
- **Debug mode**: The `--debug` flag controls traceback verbosity through `_handle_exc` (lines 291-298), showing full stack traces when enabled.
- **Context persistence**: Settings propagate via `ctx.obj` and the `Session` object (lines 13-18), ensuring debugging flags persist across REPL commands and sub-command invocations.

## Frequently Asked Questions

### How do I capture machine-readable output from CLI-Anything commands?

Add the `--json` flag to any command. The flag is defined at the top level of each agent harness (e.g., line 183 in [`zotero_cli.py`](https://github.com/HKUDS/CLI-Anything/blob/main/zotero_cli.py)) and stored in `ctx.obj["json_output"]`. When enabled, helper functions like `emit()` print raw JSON via `json.dumps()` instead of formatted text, making it easy to pipe results to other tools or parse them programmatically.

### What is the difference between the `--trace` and `--debug` flags?

The `--trace` flag specifies an input file path for tools that analyze trace data (like Unreal Insights), storing the value in `session.set_trace()` and validating it via `_require_trace()`. The `--debug` flag is a boolean toggle that modifies error handling behavior; when set, the `_handle_exc()` function prints full Python tracebacks rather than concise error messages, helping you diagnose code-level issues.

### Where does the CLI store debugging configuration between commands?

Debugging settings persist in the Click context object (`ctx.obj`) and the `Session` object attached to it, as implemented in [`unrealinsights_cli.py`](https://github.com/HKUDS/CLI-Anything/blob/main/unrealinsights_cli.py) lines 13-18. This architecture ensures that enabling `--json`, `--debug`, or `--trace` in one command maintains those settings for subsequent commands within the same REPL session or script execution.

### Can I combine JSON output with full error tracebacks?

Yes. Combine `--json` and `--debug` flags in the same invocation. The `--json` flag ensures successful output is formatted as JSON, while `--debug` ensures that any exceptions trigger `_handle_exc()` to display the full traceback before exiting. This combination is particularly useful in CI pipelines where you need structured data alongside detailed failure diagnostics.