From 054064e8e008ebd269f209a46305dd1d700ea427 Mon Sep 17 00:00:00 2001 From: DTTerastar Date: Sat, 25 Apr 2026 18:06:18 -0400 Subject: [PATCH] feat!: drop --json shortcut, default --format to "markdown" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per quantcli shared contract §4, every CLI uses a single --format flag, not a mix of --format and per-format boolean shortcuts. liftoff just made the same change in PR #19; this brings crono in line. https://github.com/quantcli/common/blob/main/CONTRACT.md#4-output-format BREAKING: - --json shortcut is removed. Migration: --json → --format json. - Default --format value is "markdown" (was "md"); the help text and prime/README now use "markdown" as the canonical name. "md" is still accepted as a compatibility alias. This finishes flag-name harmonization across the three CLIs: - liftoff: --format markdown|json - crono: --format markdown|json - withings: --format markdown|json|csv Co-Authored-By: Claude Opus 4.7 (1M context) --- README.md | 6 +++--- cmd/format.go | 17 ++++++++--------- cmd/prime.go | 19 +++++++++---------- cmd/root.go | 4 ++-- 4 files changed, 22 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index ca905f3..087c499 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Export your personal nutrition, biometric, and food-log data from [Cronometer](h ## Features - **Five export endpoints** — servings (per-food log with full nutrient breakdown), nutrition (daily totals), biometrics (weight, body fat, custom metrics), exercises, and notes -- **Markdown by default, JSON on demand** — narrow fitdown-style markdown reads well in chat and terminals; pass `--json` for the full structured row to pipe through `jq` +- **Markdown by default, JSON on demand** — narrow fitdown-style markdown reads well in chat and terminals; pass `--format json` for the full structured row to pipe through `jq` - **Date selection** — `--since` / `--until` accepting `today`, `yesterday`, `YYYY-MM-DD`, or `Nd`/`Nw`/`Nm`/`Ny` on every subcommand - **Single static binary** — no Python or Node runtime; drop it in `~/bin/` and go - **Credentials via env** — `CRONOMETER_USERNAME` / `CRONOMETER_PASSWORD`, no config file needed @@ -153,11 +153,11 @@ crono-export notes --since 30d Default output is narrow, [Fitdown](https://github.com/datavis-tech/fitdown)-style markdown — date-grouped headings, one bullet per non-zero field, no wide tables. Markdown reads well in chat and on a terminal and is easy for an LLM to consume inline. -For programmatic use, pass `--json` (or `--format json`) to get the full structured row as a JSON array on stdout — nothing suppressed, easy to pipe through `jq`. Errors always go to stderr, so JSON output stays clean for piping. +For programmatic use, pass `--format json` to get the full structured row as a JSON array on stdout — nothing suppressed, easy to pipe through `jq`. Errors always go to stderr, so JSON output stays clean for piping. ```sh crono-export servings --since today # markdown, default -crono-export servings --since today --json | jq '[.[] | {food: .FoodName, protein: .ProteinG}]' +crono-export servings --since today --format json | jq '[.[] | {food: .FoodName, protein: .ProteinG}]' ``` LLM agents: run `crono-export prime` for a one-screen orientation describing both formats, all subcommands, the date flags, and `jq` recipes. diff --git a/cmd/format.go b/cmd/format.go index c5ad521..0cfd3b6 100644 --- a/cmd/format.go +++ b/cmd/format.go @@ -23,24 +23,23 @@ const ( kindNotes ) -// AddFormatFlags registers --format and --json on every export subcommand. +// AddFormatFlags registers --format on every export subcommand, per the +// quantcli shared contract §4. +// https://github.com/quantcli/common/blob/main/CONTRACT.md#4-output-format func AddFormatFlags(cmd *cobra.Command) { - cmd.Flags().String("format", "md", "output format: md|json") - cmd.Flags().Bool("json", false, "shortcut for --format json") + cmd.Flags().String("format", "markdown", + "Output format: markdown (default, fitdown-style) or json") } func chosenFormat(cmd *cobra.Command) (string, error) { f, _ := cmd.Flags().GetString("format") - if j, _ := cmd.Flags().GetBool("json"); j { - f = "json" - } switch f { - case "md", "markdown": - return "md", nil + case "", "markdown", "md": + return "markdown", nil case "json": return "json", nil default: - return "", fmt.Errorf("unknown --format %q (want md or json)", f) + return "", fmt.Errorf("unknown --format %q (use markdown or json)", f) } } diff --git a/cmd/prime.go b/cmd/prime.go index 8441816..1ca53af 100644 --- a/cmd/prime.go +++ b/cmd/prime.go @@ -18,10 +18,9 @@ OUTPUT FORMATS bullet per non-zero field, easy to skim and easy for an LLM to consume inline. Zero-valued nutrients are suppressed in markdown. - --json (or --format json) Pretty-printed JSON ARRAY of full rows. - Use this when you want the complete row, - when piping to jq, or when round-tripping - into other tools. Nothing is suppressed. + --format json Pretty-printed JSON ARRAY of full rows. Use this when + you want the complete row, when piping to jq, or when + round-tripping into other tools. Nothing is suppressed. Errors go to stderr. You do NOT need '2>&1'. Exit code is 0 on success and non-zero on auth or network failure. An empty result is @@ -77,20 +76,20 @@ EXAMPLES crono-export nutrition --since today # Today's macros, parsed (numbers via tonumber) - crono-export nutrition --since today --json | jq '.[] | { + crono-export nutrition --since today --format json | jq '.[] | { date: .Date, kcal: (."Energy (kcal)" | tonumber), protein: (."Protein (g)" | tonumber) }' # 7-day protein total (servings is typed — no tonumber needed) - crono-export servings --since 7d --json | jq '[.[] | .ProteinG] | add' + crono-export servings --since 7d --format json | jq '[.[] | .ProteinG] | add' # All foods from today's breakfast - crono-export servings --since today --json | jq '[.[] | select(.Group == "Breakfast") | .FoodName]' + crono-export servings --since today --format json | jq '[.[] | select(.Group == "Breakfast") | .FoodName]' # Latest weight reading in a 30-day window - crono-export biometrics --since 30d --json | jq 'map(select(.Metric == "Weight")) | sort_by(.RecordedTime) | last' + crono-export biometrics --since 30d --format json | jq 'map(select(.Metric == "Weight")) | sort_by(.RecordedTime) | last' GOTCHAS - "Today" is your LOCAL calendar day, not UTC. @@ -98,7 +97,7 @@ GOTCHAS 'jq tonumber' when doing math. 'servings', 'biometrics', 'exercises' JSON values are already typed numbers. - Markdown drops zero-valued nutrients to stay readable. If you need - every column (including zeros), use --json. + every column (including zeros), use --format json. - Cronometer logs by calendar day; nothing here is real-time. Two '--since today' calls moments apart return the same data. ` @@ -107,7 +106,7 @@ var primeCmd = &cobra.Command{ Use: "prime", Short: "Print an LLM-targeted primer (output formats, subcommands, jq recipes)", Long: `Print a one-screen primer aimed at LLM agents calling this CLI as a tool. -Covers the output formats (markdown by default, --json for structured), +Covers the output formats (markdown by default, --format json for structured), auth env vars, the subcommands and what their rows look like, the shared date flags, and a few jq recipes for common questions.`, RunE: func(cmd *cobra.Command, _ []string) error { diff --git a/cmd/root.go b/cmd/root.go index 6c81783..9da3341 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -13,8 +13,8 @@ var rootCmd = &cobra.Command{ Short: "Export Cronometer nutrition, biometrics, and food log data", Long: `crono-export reads your personal Cronometer data via the same export endpoints the web app uses and prints it on stdout. Default output is -narrow, fitdown-style markdown; pass --json (or --format json) for the -full structured row. +narrow, fitdown-style markdown; pass --format json for the full +structured row. Credentials must be supplied via environment variables: CRONOMETER_USERNAME your Cronometer email