Major Changes
-
e1f2e28: feat(DST-1819): default the CLI to JSON output when stdout is not a terminal
When
--formatis omitted,docs,list,search,examples,doctorandvalidatenow printjsonwhenever their output is piped or captured, as it is for an AI agent, a script, CI or a redirect to a file. In an interactive terminal nothing changes:docs,list,searchandexamplesstill printmarkdown, anddoctorandvalidatestill printtext. An explicit--formatalways wins.Breaking: a script that reads the default output of one of these commands through a pipe now receives JSON. Pass
--format markdown,--format plainor--format textto keep the previous output. The programmaticrun*()exports are unchanged and keep theirmarkdown/textfallback.
Minor Changes
-
a7c4d00: feat: align the CLI with the Command Line Interface Guidelines (clig.dev)
- First-run telemetry notice. Because telemetry is opt-out, the CLI now prints a one-time disclosure (to
stderr, so JSON/stdout stays clean) explaining that anonymous usage data is collected and how to opt out (marigold telemetry disableorDO_NOT_TRACK=1). Mirrors the .NET SDK model. The "shown" flag is persisted only after the notice actually prints on an interactive terminal, so agent/pipe runs never consume it before a human sees it. The invocation that shows the notice is itself not tracked: no data leaves the machine before the user has seen the disclosure and had a chance to opt out. Tracking begins on the next run. - "Did you mean?" suggestions. Unknown commands now suggest the nearest valid command via edit distance (e.g.
marigold serach→ Did you mean "search"?), matching the error-recovery pattern used bygit/cargo/npm.
- First-run telemetry notice. Because telemetry is opt-out, the CLI now prints a one-time disclosure (to
-
a7c4d00: feat: make CLI telemetry identifier-free, and document it in full
Telemetry stays on by default, but it no longer carries anything that can single out a machine, user, or session. This is what makes the opt-out default defensible under GDPR and ePrivacy: with no identifier there is no personal data to have a lawful basis for, and the CLI no longer stores an identifier on the user's device, which would otherwise require consent under ePrivacy Art. 5(3) / § 25 TDDDG.
- Removed the
anonymousId. The persistent per-machine UUID is gone from the event payload, fromUserConfig, and from the server schema. A stale value written by an older CLI is stripped on the next config read and erased from disk. The trade is deliberate: we can now count invocations, not people, and unique-user numbers come from public npm download counts instead. - Corrected the first-run notice. It previously claimed that no arguments and no personal data were collected, while the event did carry
argsand a persistent UUID. The notice now states exactly what is sent and links to the telemetry section of the CLI docs. - Clamped
args. Enum flags are recorded as their validated value or asinvalid, so a mistyped--format=jsonnis no longer echoed back verbatim.--limitis recorded only as a positive integer. A name passed as a positional or--categoryis never forwarded as typed: once it resolves against the docs manifest, the manifest's slug is recorded, and anything else is recorded asunknown. Free-text search terms remain recorded asused. - Hour-granular timestamps, not expiry.
receivedAtis truncated to the hour, and so is the ID each event is stored under, in a stream of its own, so events cannot be stitched back into per-session sequences by timing once the identifier is gone. That is also what lets events be kept for long-run usage trends rather than expiring: with no identifier in a record, an old event says no more about you than a new one. The reasoning is in the telemetry endpoint README. - Strict event schema. The endpoint rejects unknown top-level keys rather than stripping them, so a stale
anonymousIdgets a visible 400 instead of a silent drop. Keys insideargsare bounded in length and count. The guarantee that no identifier is sent lives in the CLI, which buildsargsonly from validated values. - Endpoint-wide rate limit only. The former per-
anonymousIdquota is gone, since there is no longer a client identifier to key one on, which leaves the endpoint-wide ceiling as the CLI's only bound. That ceiling is a cost backstop, not a security control. Bounding a single misbehaving caller belongs behind WAF rate limiting, which needs no identifier in the body. - Full disclosure in the docs. The
marigold telemetrysection of the CLI page now documents every field sent, what is never sent, why the default is opt-out, and every way to turn it off. It lives there rather than on a standalone privacy page, which nobody would navigate to.marigold --helplinks the anchor, so non-interactive users have a discoverable disclosure too.
- Removed the
Patch Changes
- Updated dependencies [ab9b05e]
- Updated dependencies [b67903a]
- Updated dependencies [d6b5d77]
- Updated dependencies [d1b1f15]
- Updated dependencies [947b7a9]
- Updated dependencies [2319875]
- Updated dependencies [ec15520]
- Updated dependencies [e9df73e]
- Updated dependencies [44533cd]
- Updated dependencies [8bf58b2]
- Updated dependencies [25b45b3]
- Updated dependencies [e9324b2]
- Updated dependencies [f4e2236]
- Updated dependencies [c860eb4]
- Updated dependencies [ce5eaec]
- @marigold/components@18.3.0
- @marigold/theme-rui@6.2.1