Skip to content

Commit a6bd8d0

Browse files
DTTerastarclaude
andauthored
fix: emit [] for empty JSON; correct workouts category prime note (#11)
Two gaps the new 'prime' subcommand surfaced when its examples and the output-formats contract were exercised end-to-end: - Every subcommand's --format json was emitting 'null' on empty windows (the underlying slice was nil, which encoding/json marshals as null). The prime promises "empty result ... JSON prints '[]'", and 'null' also breaks the prime's sleep-efficiency jq pipeline. Special-case nil slices in printJSON via reflect so all five subcommands emit '[]' on empty. - The workouts gotcha implied JSON carried both a string 'category' and a numeric 'category_code', but JSON only carries the integer 'category' (the string mapping happens in markdown/CSV). Rewrite the gotcha to describe actual behavior and list the common code values inline so an LLM can filter by 'category == 16' without round-tripping through markdown. Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
1 parent b6bb49e commit a6bd8d0

2 files changed

Lines changed: 12 additions & 3 deletions

File tree

cmd/prime.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,11 @@ GOTCHAS
135135
(250ms between calls); ad-hoc loops should do the same.
136136
- Sleep score and apnea fields are populated only on supported devices.
137137
'data.sleep_score' is null on unsupported wakeup-light models.
138-
- 'workouts' category codes are integers; common ones are mapped to
139-
string names (walk/run/bicycling/...) but unknown codes pass through
140-
as 'unknown' with the numeric category_code preserved.
138+
- 'workouts' category is a Withings integer code in JSON (1=walk,
139+
2=run, 6=bicycling, 16=lift_weights, ...). Markdown and CSV map
140+
common codes to string names ('lift_weights', 'walk', ...) and
141+
unknown codes render as 'unknown'; CSV also keeps the raw integer
142+
in a 'category_code' column.
141143
`
142144

143145
var primeCmd = &cobra.Command{

cmd/shared.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"encoding/json"
55
"fmt"
66
"os"
7+
"reflect"
78
"strconv"
89
"strings"
910
"time"
@@ -108,6 +109,12 @@ func untilDayOrToday(s string) (time.Time, error) {
108109
}
109110

110111
func printJSON(v any) error {
112+
// A nil slice marshals as "null"; force "[]" so empty windows match the
113+
// prime contract (and don't blow up jq pipelines).
114+
if rv := reflect.ValueOf(v); rv.Kind() == reflect.Slice && rv.IsNil() {
115+
_, err := os.Stdout.WriteString("[]\n")
116+
return err
117+
}
111118
enc := json.NewEncoder(os.Stdout)
112119
enc.SetIndent("", " ")
113120
if err := enc.Encode(v); err != nil {

0 commit comments

Comments
 (0)