-
Notifications
You must be signed in to change notification settings - Fork 0
CLI JSON output
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.
Read commands (fully wired, safe to depend on)
music listpodcasts listnotes listtools listdevices list
-
music update— has--yes, but it's bespoke: never checksis_json_mode(), severalconsole.print()calls run unconditionally (would corrupt--jsonstdout), no--dry-run, and the final result isn'trender()-wrapped. Passing--json --yestoday will not give you clean output. -
podcasts delete— just got--idsupport, but confirmation is a plainclick.confirm()— no--yes/--dry-run/--jsonat all yet (this is what we're mid-way through wiring up).
No --json/--yes/--dry-run for these yet.
music uploadmusic delete-all-
music delete(regex path; the interactive picker path is human-only by nature) -
music sort(non-destructive, but silent — no--jsonacknowledgment of what changed) -
podcasts add(norender()at all — plainconsole.print) -
notes add,notes download tools remove
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 runtime check on this, 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");
}Run this once at startup (or in CI) to catch drift before it causes confusing runtime errors.
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" }Commands that modify data (upload, delete, update, etc.) normally prompt for confirmation before proceeding. Since an interactive prompt can't be answered by a script, --json requires pairing with one of:
-
--yes- skip confirmation and apply the change immediately. -
--dry-run- preview what would change, without applying it.
A typical integration flow:
// 1. Preview what would happen
const preview = runLight<UploadPlan>(["music", "upload", "track.mp3", "--dry-run"]);
// 2. Render your own confirmation UI from `preview`
// 3. Apply it
runLight<UploadPlan>(["music", "upload", "track.mp3", "--yes"]);