{
  "markdown": "# groundcover-cli\n\nGo CLI for Groundcover APIs.\n\nIt uses the official `github.com/groundcover-com/groundcover-sdk-go` where that SDK has a stable contract, and keeps HAR-derived raw commands for webapp endpoints the SDK does not expose.\n\n## Install\n\n```sh\nbrew tap paymog/tap\nbrew install groundcover\n```\n\nThe formula builds from source, so Homebrew installs a Go toolchain as a build dependency.\n\nGo install:\n\n```sh\ngo install github.com/paymog/groundcover-cli/cmd/groundcover@latest\n```\n\nLocal build:\n\n```sh\ngo build ./cmd/groundcover\n```\n\n## Auth\n\nThe simplest setup is environment variables (recommended for CI):\n\n```sh\nexport GROUNDCOVER_API_KEY=...\nexport GROUNDCOVER_BACKEND_ID=...\n```\n\nAlso accepted: `GC_API_KEY`, `GC_BACKEND_ID`, `GROUNDCOVER_TENANT_UUID`, `GC_TENANT_UUID`, `GROUNDCOVER_BASE_URL`, `GC_BASE_URL`, `GROUNDCOVER_GRAFANA_SERVICE_ACCOUNT_TOKEN`, `GC_GRAFANA_SERVICE_ACCOUNT_TOKEN`.\n\n### Stored profiles\n\nFor day-to-day use you can store credentials in named profiles. The API key is\nkept in your OS keyring (macOS Keychain, Linux libsecret/secret-service, Windows\nCredential Manager); only non-secret metadata (backend ID, base URL, tenant UUID)\nis written to `~/.config/groundcover/profiles.yaml` (XDG-aware; `%AppData%` on\nWindows).\n\n```sh\ngroundcover auth login              # prompts for the API key; profile \"default\"\ngroundcover auth login prod --backend-id my-backend --key lin_...\ngroundcover auth list               # table; * marks the default\ngroundcover auth default prod       # set the default profile\ngroundcover --profile prod monitors list   # use a profile for one command\ngroundcover auth status             # show which source resolved\ngroundcover auth token              # print the resolved API key\ngroundcover auth logout prod        # remove a profile (-f to skip confirm)\n```\n\n`login` validates the key against the API before saving it. The first profile\nadded becomes the default.\n\n**Credential precedence** (highest first):\n\n1. `--api-key` flag / `GROUNDCOVER_API_KEY` env var\n2. `--profile <name>` → stored profile\n3. default profile → stored profile\n\nCombining an explicit key with `--profile` is rejected as ambiguous. If no keyring\nis available, fall back to `GROUNDCOVER_API_KEY`.\n\nDefaults (override the env or flag for your own backend/tenant):\n\n- Base URL: `https://api.groundcover.com`\n- Backend ID: `groundcover` (`GROUNDCOVER_BACKEND_ID` / `--backend-id`)\n- Tenant UUID: none. Set `GROUNDCOVER_TENANT_UUID` / `--tenant-uuid` to send `X-Tenant-UUID` on raw HAR-derived requests; the SDK transport already implies tenant from the API key.\n- Grafana service account token: none. The embedded Grafana (`raw grafana …`) endpoints are session-gated and ignore the API key, so they need a Grafana service account token (`glsa_…`). Set `GROUNDCOVER_GRAFANA_SERVICE_ACCOUNT_TOKEN` / `--grafana-token`. It is only used for `raw grafana …` commands. Running one without a token prints setup steps; generate a token with groundcover's official CLI (`~/.groundcover/bin/groundcover auth generate-service-account-token`, needs tenant admin).\n\n## SDK-backed commands\n\n```sh\ngroundcover dashboards list\ngroundcover dashboards get <id>\ngroundcover dashboards create --body-file dashboard.json\ngroundcover dashboards update <id> --body-file dashboard.json\ngroundcover dashboards delete <id>\n\ngroundcover monitors list --query 'monitor_name = \"cpu\"'\ngroundcover monitors get <id>\ngroundcover monitors create --body-file monitor.yaml\ngroundcover monitors update <id> --body-file monitor.yaml\ngroundcover monitors delete <id>\n\ngroundcover silences list --active\ngroundcover silences create --body-file silence.json\ngroundcover silences delete <id>\n\ngroundcover dashboards archive <id>\ngroundcover dashboards restore <id>\n\ngroundcover recurring-silences list\ngroundcover recurring-silences create --body-file silence.json\n\ngroundcover connected-apps list --query 'type:slack-webhook'\ngroundcover connected-apps get <id>\ngroundcover connected-apps create --body-file app.json\ngroundcover connected-apps update <id> --body-file app.json\ngroundcover connected-apps delete <id>\n\ngroundcover notification-routes list --query 'prod'\ngroundcover notification-routes get <id>\ngroundcover notification-routes create --body-file route.json\ngroundcover notification-routes update <id> --body-file route.json\ngroundcover notification-routes delete <id>\n\n# Auth / RBAC\ngroundcover api-keys list\ngroundcover api-keys create --body-file key.json\ngroundcover service-accounts list\ngroundcover service-accounts create --body-file sa.json\ngroundcover ingestion-keys list\ngroundcover policies list\ngroundcover policies apply --body-file policy.json\ngroundcover policies audit-trail <id>\n\n# Synthetics, secrets, workflows\ngroundcover synthetics list\ngroundcover synthetics create --body-file test.json\ngroundcover secrets create --body-file secret.json\ngroundcover secrets hash <id>\ngroundcover workflows list\ngroundcover workflows create --body-file workflow.yaml\n\n# Pipeline configs (singleton get/create/update/delete)\ngroundcover logs-pipeline get\ngroundcover metrics-pipeline get\ngroundcover traces-pipeline get\ngroundcover metrics-aggregator get\n\n# Integrations (typed)\ngroundcover integrations list\ngroundcover integrations describe <type>\ngroundcover integrations create <type> --body-file config.json\ngroundcover integrations update <type> <id> --body-file config.json\n\n# Read/query\ngroundcover logs search --body-file search.json\ngroundcover traces search --body-file search.json\ngroundcover metrics query --body-file query.json\ngroundcover metrics names --body-file body.json\ngroundcover search discovery --body-file body.json\ngroundcover k8s clusters --body-file body.json\ngroundcover k8s workloads --body-file body.json\ngroundcover k8s events-search --body-file body.json\n```\n\n## Raw HAR-derived commands\n\n```sh\ngroundcover raw list\ngroundcover raw list k8s\ngroundcover raw k8s clusters list\ngroundcover raw dashboards get --dashboard-id <id>\ngroundcover raw metrics query-range --body-file body.json\ngroundcover raw prometheus api query --query query='up'\ngroundcover raw grafana dashboards get --dashboard-uid <uid>\ngroundcover raw grafana dashboards save --body-file dashboard.json\ngroundcover raw grafana folders list\ngroundcover raw grafana ds query --body-file query.json\n```\n\nStorage management uses one endpoint per data type:\n\n```sh\ngroundcover raw storage-management get --data-type logs --raw \\\n  | jq '{retention,version,cold_move_duration,cold_volume,custom_rules:(.custom_rules // [])}' \\\n  > storage.json\n# Edit storage.json, preserving every writable field and the complete rule list.\ngroundcover raw storage-management update --data-type logs --body-file storage.json\n```\n\nSupported data types are `logs`, `traces`, `events`, `measurements`, and `monitor_instance`. Updates use optimistic concurrency and replace the writable settings document: start from `get`, pass its current `version`, and preserve `retention`, `cold_move_duration`, `cold_volume`, and the full `custom_rules` list. Omitting `custom_rules` removes existing rules.\n\n\nRaw commands support:\n\n- `--body-json '<json>'`\n- `--body-file path.json`\n- `--body-file path.yaml`\n- `--set dotted.path=value`\n- `--query key=value`\n- path flags generated from captured UUIDs, for example `--dashboard-id <id>`\n- `--raw`\n\n## Regenerate raw commands\n\n```sh\ngo run ./scripts/generate-commands.go ~/Downloads/app.groundcover.com.har\n```\n\nGenerated commands are written to `internal/raw/commands_generated.go`.\n\n## Shape\n\n- `internal/sdkcmd`: first-class commands backed by the official SDK.\n- `internal/raw`: best-effort command registry and runner for HAR-derived endpoints.\n- `internal/config`: shared auth, base URL, timeout, and SDK transport setup.\n\n## Claude Code skill\n\nThis repo ships a [Claude Code](https://claude.com/claude-code) skill that teaches the\nagent how to drive the CLI (auth, the SDK-vs-raw split, and ready-made request-body\ntemplates for logs/traces/metrics/k8s). It lives in [`skills/groundcover-cli`](skills/groundcover-cli).\n\nInstall it with [`npx skills`](https://github.com/vercel-labs/skills) (Vercel's agent-skills tool):\n\n```sh\n# install into the current project (.claude/skills/)\nnpx skills add paymog/groundcover-cli\n\n# or install globally for your user, skipping prompts\nnpx skills add paymog/groundcover-cli --global --yes\n```\n\nUseful flags: `--list` to preview without installing, `--skill groundcover-cli` to target it\nexplicitly, `-a claude-code` to pick the agent.\n\nOr install manually:\n\n```sh\ngit clone https://github.com/paymog/groundcover-cli\ncp -r groundcover-cli/skills/groundcover-cli ~/.claude/skills/groundcover-cli\n```\n\nThen ask Claude Code to query logs, manage monitors, debug a prod issue, etc., and it will\ninvoke `groundcover`.\n\n## Release\n\nReleases are tag-driven:\n\n```sh\ngit tag v0.1.0\ngit push origin v0.1.0\n```\n\nGitHub Actions runs GoReleaser, then updates the source-build formula in `paymog/homebrew-tap`. The workflow pushes to the tap over SSH using a deploy key stored as the `HOMEBREW_TAP_DEPLOY_KEY` secret (the public half is a read-write deploy key on the tap repo).\n",
  "bytes": 9135,
  "sha": "768729226f03df59c99b675b96bc96a67b2f689524bd1059579da862545c479b",
  "repo_slug": "paymog/groundcover-cli",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/skl_paymog_groundcover_cli_groundcover_cli_b1c526a7/readme"
}