Skip to content

CLI JSON output

Alexis edited this page Aug 8, 2026 · 11 revisions

Note

Last updated for: v0.3.0

I am working through adding support for enabling JSON output to the CLI, allowing light-phone-cli-tui to be more easily used as a dependency in non-Python projects.

--json support roadmap

The intended pattern for third-party consumers is:

  • Run a destructive command with --dry-run --json flags to preview what would change
  • Render your own confirmation UI from that preview
  • Re-run with --yes --json to apply it (skip the interactive prompt)

This roadmap tracks which commands actually support that pattern today versus which still only have an interactive path.

Stable

Read commands (fully wired, safe to depend on)

  • music list
  • podcasts list
  • notes list
  • tools list
  • devices list

Unstable

  • music update
    • Supports selection by ID and autoapplying edits (--new{title,artist,album}, --yes), but no full --json --dry-run support
  • podcasts delete
    • This supports deletion by ID, but has no --dry-run or --yes flag.

Unimplemented

No --json/--yes/--dry-run for these yet.

  • music upload
  • music delete-all
  • music delete (regex path; the interactive picker path is human-only by nature)
  • music sort (non-destructive, but silent - no --json acknowledgment of what changed)
  • podcasts add (no render() at all - plain console.print)
  • notes add, notes download
  • tools remove

Output format

Schema

A schema.json is provided in the repo root you to autogenerate types. You can also generate this yourself with light schema.

The schema includes a $hash field for detecting when the saved schema goes out of sync with the CLI's actual output. It is recommended to do a check on this in CI or at runtime to catch drift, e.g.

import { execFileSync } from "node:child_process";
import { readFileSync } from "node:fs";

const savedSchema = JSON.parse(readFileSync("schema.json", "utf-8"));
const currentHash = execFileSync("light", ["schema", "--hash"], { encoding: "utf-8" }).trim();

if (savedSchema["$hash"] !== currentHash) {
  console.warn("schema.json is stale - regenerate with `light schema > schema.json`, and regenerate types");
}

Payload

Every --json-enabled command wraps its output as:

{ "data": <command-specific payload>, "error": null }

On failure, data is null and error is a human-readable message:

{ "data": null, "error": "No podcast found with title: Foo" }

Clone this wiki locally