* docs(napkin): record embedded-Grafana bearer-auth failure finding
* feat(raw): authenticate embedded Grafana with a service account token
The `raw grafana …` commands target app.groundcover.com/grafana/api/*, an
embedded Grafana behind a session-gated proxy that ignores the gcsa bearer
token: every call returned the ~980KB Grafana SPA index.html instead of JSON.
Route WebApp (grafana) commands through a plain HTTP client that sets
Authorization: Bearer <glsa_...> from GROUNDCOVER_GRAFANA_SERVICE_ACCOUNT_TOKEN
(or --grafana-token), bypassing the SDK transport that would clobber the header
with the gcsa key. Non-grafana raw commands are unchanged (gcsa + X-Backend-Id
via SDK transport, plus X-Tenant-UUID when set).
Verified live: `raw grafana search` and `folders list` return real JSON.
* docs(napkin): record grafana service account token resolution
* feat(raw): guide grafana token setup when it is missing
Running any `raw grafana ...` command without a Grafana service account token
now prints an actionable setup guide instead of a one-line error: how to
generate a glsa_ token with groundcover's official CLI (install, auth login,
auth generate-service-account-token) and hand it to this CLI.
The official CLI also ships a `groundcover` binary; its installer puts it in
~/.groundcover/bin and prepends that dir to PATH, shadowing this CLI. The guide
calls that out and steers users to invoke the official binary by full path.
Removes the now-superseded config.RequireGrafanaToken (terse message) in favor
of the raw-layer guide. Tests cover the guide content and the missing-token
short-circuit.
* docs(napkin): record official-CLI binary-name collision + token-gen flow
* docs(skill): correct stale X-Tenant-UUID note (grafana uses glsa, not tenant header)
Add a "Building & editing dashboards" section covering the preset JSON
string, the 24-col grid layout, sections with children[], and the
currentRevision optimistic-concurrency update contract.
Document the two opaque-400 validation rules learned the hard way:
stat widgets only validate as flat top-level layout entries (never
inside a section's children), and section color is limited to
gray/purple/teal.
Add the stat-panel "No Results" trap for lagging (polled-integration)
metrics and the last_over_time([30m]) fix, a UI-less API verification
recipe, and a polled-integration label-scheme note (lag, stat
dimension, integration-named env label).
Also note the observed CLI instant-query 400 caveat in Common issues.
Add `groundcover auth` commands for managing named credential profiles.
API keys are stored in the OS keyring (Keychain / libsecret / Credential
Manager); only non-secret metadata (backend ID, base URL, tenant UUID) is
written to ~/.config/groundcover/profiles.yaml.
Credential precedence: explicit --api-key/GROUNDCOVER_API_KEY env, then
--profile <name>, then the default profile. Combining an explicit key with
--profile is rejected as ambiguous. Env-var auth remains the simple/CI path
and takes precedence over stored profiles.
Commands: auth login/list/default/logout/token/status. login validates the
key against the API before persisting. First profile added becomes default.
Design mirrors schpet/linear-cli (file holds no secrets) adapted to Go:
go-keyring backend behind a Backend interface for test injection, YAML to
match the existing yaml.v3 dep.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Go CLI for the Groundcover APIs. SDK-backed commands for stable endpoints,
plus raw HAR-derived passthrough for webapp endpoints the SDK does not expose.