# gcx — Agent & Developer Entry Point

> Lightweight map for autonomous coding agents. Read this first, then navigate to specific docs on demand.

## Quick Start

**gcx** is a unified CLI for managing Grafana resources. It operates in two tiers: (1) a **K8s resource tier** that uses Grafana 12+'s Kubernetes-compatible API via `k8s.io/client-go` for dashboards, folders, and other K8s-native resources, and (2) a **Cloud provider tier** with pluggable providers for Grafana Cloud products (SLO, Synthetic Monitoring, IRM, Fleet Management, etc.) that use product-specific REST APIs. Built in Go, it uses Cobra for CLI structure.

## Documentation Map

| File | Purpose |
|------|---------|
| [VISION.md](VISION.md) | Goals, product surface, roadmap themes, release timeline |
| [CONSTITUTION.md](CONSTITUTION.md) | Invariants — things that cannot change without explicit human approval |
| [ARCHITECTURE.md](ARCHITECTURE.md) | System overview (all 7 subsystems), pipeline diagrams, ADR index |
| [DESIGN.md](DESIGN.md) | CLI UX design: command grammar, output model, exit codes |
| [CONTRIBUTING.md](CONTRIBUTING.md) | Dev setup, testing environment, contribution workflow |
| [docs/architecture/](docs/architecture/) | Deep-dive architecture docs (patterns, resource model, CLI layer, data flows, …) |
| [docs/design/](docs/design/) | Prescriptive UX implementation rules (output, errors, agent mode, naming, …) |
| [docs/reference/](docs/reference/) | Provider guides, CLI reference, migration analysis |
| [docs/_templates/](docs/_templates/) | Spec and planning templates (feature, bugfix, refactor, ADR, research) |

## Architecture at a Glance

Two tiers: **K8s resource tier** (dashboards, folders via `/apis`) and **Cloud provider tier** (SLO, SM, IRM, etc. via product REST APIs). See [ARCHITECTURE.md](ARCHITECTURE.md) for pipeline diagrams and extension pipelines.

## Key Conventions

> Authoritative source: [CONSTITUTION.md](CONSTITUTION.md) (invariants) and [DESIGN.md](DESIGN.md) (UX rules). This is the quick-reference summary.

- **Options pattern**: Every command uses `opts struct` + `setup(flags)` + `Validate()` + constructor
- **Processor pipeline**: `Processor.Process(*Resource) error` — composable transformations for push/pull
- **errgroup concurrency**: Bounded parallelism (default 10) for all batch I/O operations
- **Folder-before-dashboard**: Push pipeline does topological sort — folders pushed level-by-level before other resources
- **Config = kubectl kubeconfig**: Named contexts with server/auth/namespace, env var overrides
- **Format-agnostic data fetching**: Commands fetch all data regardless of `--output` format; codecs control display, not data acquisition (see Pattern 13 in `docs/architecture/patterns.md`)
- **PromQL via promql-builder**: Use `github.com/grafana/promql-builder/go/promql` for PromQL construction, not string formatting (see Pattern 14 in `docs/architecture/patterns.md`)
- **Datasource query reuse**: Datasource clients that call Grafana's unified datasource query API (`/apis/query.grafana.app/.../query`, with `/api/ds/query` fallback) should reuse `internal/query/grafanaquery` for HTTP transport and `internal/query/dataframe` for Grafana data frame wire types. Do not duplicate POST/fallback/response-limit logic or `GrafanaQueryResponse`/`DataFrame` structs in each datasource package.
- **Portable agent skills live under `claude-plugin/skills/`**: Treat that tree as the canonical portable Agent Skills bundle. Do not add distributable gcx skills under repo-local `.agents/skills/` — that changes repo-context discovery semantics for tools that scan `.agents`.

## Essential Commands

```bash
mise run build       # Build to bin/gcx
mise run tests       # Run all tests with race detection
mise run lint        # Run golangci-lint
mise run all         # lint + tests + build + docs
mise run docs        # Generate + build all documentation
```

**Without mise**: replace with direct Go commands — `go build -buildvcs=false -o bin/gcx ./cmd/gcx/` and `go test ./...`. Always build to `bin/gcx`.

> **Agent environments**: always prefix with `GCX_AGENT_MODE=false` — agent-mode auto-detection changes output defaults in `mise run docs`, producing wrong CLI reference docs.

## Testing

```bash
go test ./internal/providers/traces/...   # Run one package
go test -run TestQueryCodec ./internal/... # Run matching tests across packages
go test -race -count=1 ./...              # Full suite with race detection (same as mise run tests)
```

Prefer table-driven tests. See existing `_test.go` files for patterns.

## Package Map

> Full map with sub-packages: [docs/architecture/project-structure.md](docs/architecture/project-structure.md)

```
cmd/gcx/
  root/         CLI root (logging, global flags)
  login/        Unified login command (token + OAuth PKCE, interactive prompts)
  config/       Config management (set, use-context, view, check)
  resources/    Resource commands (get, schemas, push, pull, delete, edit, validate)
  datasources/  Datasource commands (list, get, query, per-type subcommands via DatasourceProvider)
  providers/    Provider list command
  assistant/    Assistant commands (AI-powered investigations)
  api/          Raw API passthrough
  linter/       Linting (mounted under dev lint)
  commands/     Commands catalog (agent metadata)
  helptree/     Help tree for agent context
  setup/        Onboarding (gcx setup status)
  instrumentation/  Instrumentation Hub commands (clusters, services, setup wizard, status)
  skills/       Portable Agent Skills installer for .agents-compatible tools
  dev/          Developer tools (import, scaffold, generate, lint, serve)
  fail/         Structured error conversion

internal/
├── auth/        OAuth PKCE flow, token refresh transport
│   └── adaptive/  Shared adaptive telemetry auth (GCOM caching, Basic auth — used by signal providers)
├── login/       Login orchestration (target detection, auth resolution, connectivity validation, sentinel-retry flow)
├── config/      Config types, loader, editor, rest.Config builder, stack-id discovery, context name helpers (auto-migrates plaintext token-shaped secrets into the OS keychain via internal/credentials)
├── credentials/ OS-keychain backend (zalando/go-keyring) for token-shaped secrets; sentinel format + Store interface; auto-disabled under `go test`
├── cloud/       GCOM HTTP client for Grafana Cloud stack discovery
├── fleet/       Shared fleet base client (HTTP, auth, config — used by fleet provider and instrumentation provider)
├── resources/
│   ├── *.go     Core types: Resource, Selector, Filter, Descriptor, Resources collection
│   ├── adapter/    ResourceAdapter interface, Factory, ResourceClientRouter, self-registration, slug-ID helpers
│   ├── discovery/  API resource discovery, registry index, GVK resolution, OpenAPI schema fetcher
│   ├── dynamic/    k8s dynamic client wrapper (namespaced + versioned)
│   ├── local/      FSReader, FSWriter (disk I/O)
│   ├── process/    Processors: ManagerFields, ServerFields, Namespace
│   └── remote/     Pusher, Puller, Deleter, FolderHierarchy, Summary
├── providers/   Provider plugin system (interface, registry, self-registration)
│   ├── alert/      Alert provider (rules, groups — read-only)
│   ├── dashboards/ Dashboards provider (CRUD, search, versions, snapshot)
│   ├── faro/       Frontend Observability provider (apps CRUD, sourcemaps sub-resource) — CLI: `gcx frontend`
│   ├── fleet/      Fleet Management provider (pipeline and collector resources)
│   ├── instrumentation/  Instrumentation Hub provider (typed connect-go client, RMW with optimistic-lock, output codecs, helm formatter, enumerate helper)
│   │   ├── enumerate/  Cluster enumeration helper (RunK8sMonitoring ⋃ ListPipelines merge)
│   │   ├── helm/       Helm command formatter for the setup wizard
│   │   ├── output/     View types and codecs (clusters, apps, services; wait/mutation envelopes)
│   │   └── rmw/        Read-modify-write helper with optimistic-lock guard (ConflictError)
│   ├── irm/        IRM provider (OnCall + Incidents — schedules, integrations, escalation chains, incidents; rich K8s-envelope types for AlertGroup/Alert in rich.go, ADR-019)
│   ├── k6/         k6 Cloud provider (projects, tests, runs, envvars)
│   ├── kg/         Knowledge Graph (Asserts) provider
│   ├── logs/       Logs signal provider (Loki queries + Adaptive Logs commands)
│   ├── metrics/    Metrics signal provider (Prometheus queries + Adaptive Metrics commands)
│   ├── appo11y/    App Observability provider (overrides, settings — singleton resources)
│   ├── profiles/   Profiles signal provider (Pyroscope queries + adaptive stub)
│   ├── aio11y/     AI Observability provider (conversations, agents, generations, evaluators, rules, hook-rules (guards), templates, scores, judge, saved-conversations, collections, experiments — via grafana-sigil-app plugin API)
│   ├── slo/        SLO provider (definitions, reports)
│   ├── synth/      Synthetic Monitoring provider (checks, probes)
│   └── traces/     Traces signal provider (Tempo queries + Adaptive Traces commands)
├── deeplink/    Deep link URL template registry and browser opener
├── dashboards/  Dashboard Image Renderer client (PNG snapshots)
├── datasources/ Datasource HTTP client, DatasourceProvider interface + registry
│   ├── clickhouse/  ClickHouse datasource commands (query, list-tables, describe-table, explore)
│   ├── cloudwatch/  CloudWatch CLI commands (query, list-namespaces, list-metrics, list-dimensions, list-regions, list-accounts)
│   ├── influxdb/  InfluxDB datasource command layer (query, field-keys, measurements)
│   └── query/   Shared query CLI utils (time parsing, codecs, opts, resolve helpers — used by signal providers and GenericCmd)
├── query/       Datasource query clients
│   ├── dataframe/   Shared Grafana data frame wire types for unified datasource query API responses
│   ├── grafanaquery/ Shared POST transport for `/apis/query.grafana.app/.../query` with `/api/ds/query` fallback
│   ├── cloudwatch/  CloudWatch HTTP query client (metric queries, resource listing)
│   ├── prometheus/  Prometheus HTTP query client
│   ├── influxdb/    InfluxDB HTTP query client
│   ├── infinity/    Infinity HTTP query client
│   ├── loki/        Loki HTTP query client
│   └── clickhouse/  ClickHouse HTTP query client
├── signals/     Shared signal command and datasource-provider mounting (metrics/logs/traces/profiles)
├── queryerror/  Typed API error for datasource query failures (APIError type, New/FromBody constructors, IsParseError helper)
├── assistant/   Assistant client (A2A streaming, prompt, state management)
│   ├── assistanthttp/  Base HTTP client for grafana-assistant-app plugin API
│   └── investigations/ Investigation CRUD commands, table codecs, API client
├── agent/       Agent mode detection, command annotations, known-resource registry with operation hints
├── agentlog/    Agent invocation failure logger (opt-in JSONL disk log, XDG state dir — wired into handleError in cmd/gcx/main.go)
├── style/       Terminal styling (Grafana Neon Dark theme, TableBuilder, ASCII banner, glamour help)
├── terminal/    TTY/pipe detection (IsPiped, NoTruncate, Detect) for output suppression
├── linter/      Linting engine (Rego rules, report aggregation, PromQL validator)
├── graph/       Terminal chart rendering (ntcharts + lipgloss)
├── testutils/   Shared test utilities
├── server/      Live dev server (Chi router, reverse proxy, websocket reload)
├── grafana/     OpenAPI client (health checks, version detection)
├── output/      Output codec registry (json, yaml, text, wide, agents — field selection, discovery, k8s unstructured handling, temp-file spill)
├── format/      JSON/YAML codecs with format auto-detection
├── retry/       Retry transport (429, 502/503/504, transient connection errors — wraps all HTTP tiers)
├── httputils/   HTTP helpers (used by serve command's proxy)
├── version/     Global version string (Set once from main; provides UserAgent() for HTTP clients)
├── secrets/     Redactor for config view
├── logs/        slog/klog integration
├── notifier/    Update notifications (skills + gcx version checks; XDG state, throttling, message rendering — wired into root PersistentPostRun)
├── skills/      Portable Agent Skills installer primitives (BundledSkillNames, Install, Update — extracted from cmd/gcx/skills)
├── strcase/     String case conversion (snake_case, kebab-case, PascalCase)
├── xdg/         XDG Base Directory paths (config home, state home, config dirs)
└── shared/      Shared utilities (date handling, duration, etc.) to be shared across integrations.
```

## What to Read Before You Start

| Task | Read first | Then |
|------|-----------|------|
| **Adding a new command** | [DESIGN.md](DESIGN.md) (grammar, output model) | [docs/design/](docs/design/) for implementation rules, [ARCHITECTURE.md](ARCHITECTURE.md) § CLI layer |
| **Adding a new provider** | [ARCHITECTURE.md](ARCHITECTURE.md) § Provider System | [docs/reference/provider-guide.md](docs/reference/provider-guide.md), [docs/design/provider-checklist.md](docs/design/provider-checklist.md) |
| **Adding a signal provider command** | [ARCHITECTURE.md](ARCHITECTURE.md) § Signal Providers | Existing signal provider code for the SharedOpts pattern |
| **Modifying resource handling** | [ARCHITECTURE.md](ARCHITECTURE.md) § Resources Pipeline | [docs/architecture/resource-model.md](docs/architecture/resource-model.md), [docs/architecture/data-flows.md](docs/architecture/data-flows.md) |
| **Changing config or auth** | [ARCHITECTURE.md](ARCHITECTURE.md) § Configuration + § Auth | [docs/architecture/config-system.md](docs/architecture/config-system.md), [docs/architecture/client-api-layer.md](docs/architecture/client-api-layer.md) |
| **Fixing a bug** | [ARCHITECTURE.md](ARCHITECTURE.md) for the relevant subsystem | Jump directly to the deep-dive doc for that domain |
| **Planning a new feature** | [VISION.md](VISION.md) (does it belong?), [CONSTITUTION.md](CONSTITUTION.md) (can we build it within the rules?) | [DESIGN.md](DESIGN.md) for UX, [ARCHITECTURE.md](ARCHITECTURE.md) for structure |
| **Reviewing a PR** | [Compliance Hierarchy](#compliance-hierarchy) below | Check all 4 levels in order |

## Compliance Hierarchy

Check work against these docs during planning, design, and implementation — in order of strictness.

| # | Doc | Strictness | What to check | If violated |
|---|-----|-----------|---------------|-------------|
| 1 | [CONSTITUTION.md](CONSTITUTION.md) | **Hard invariant** — violation is a bug | Architecture invariants, dependency rules, provider registration, CLI grammar, typed resource requirements | Stop. Fix before proceeding. Violation requires explicit human approval to waive. |
| 2 | [VISION.md](VISION.md) | **Strategic alignment** — violation is wasted work | Does this belong in gcx? Does it align with dual-purpose design, core beliefs, product surface? | Pause. Confirm direction with a human before investing more effort. |
| 3 | [DESIGN.md](DESIGN.md) | **UX rules** — violation is a UX defect | Output model, exit codes, safety patterns, taste rules in [docs/design/](docs/design/) | Fix. New code must comply. |
| 4 | [ARCHITECTURE.md](ARCHITECTURE.md) | **Structural guidance** — violation is tech debt | Pipeline placement, package boundaries, patterns in [docs/architecture/](docs/architecture/README.md) | Prefer compliance. Deviation is acceptable with rationale (document in commit or ADR). |

**When to check:**
- **Planning/design**: Check VISION (2) and CONSTITUTION (1) — are we building the right thing, and can we build it within the rules?
- **Implementation**: Check DESIGN (3) and ARCHITECTURE (4) — does the code follow UX rules and structural patterns?
- **Pre-flight** (below): Final sweep across all four before pushing.

## Releasing

Automated via `mise run tag`. Requires `claude` CLI and [`svu`](https://github.com/caarlos0/svu).

```bash
mise run tag -- patch   # or minor, major
```

This generates a changelog entry (via Claude), updates `CHANGELOG.md` and `.release-notes.md`, commits on a `release/vX.Y.Z` branch, and pushes the branch. Then:

1. Open a PR and merge it (the script prints the exact command)
2. After merge, tag the commit on main and push the tag:
   ```bash
   git checkout main && git pull
   git tag v0.X.Y
   git push origin v0.X.Y
   ```

The tag push triggers the GoReleaser workflow.

## Mandatory Pull Request Checklist

You MUST run this checklist when creating a PR or updating an existing PR with new work (addressing PR reviews or fixing bugs). This is distinct from the Mandatory Pre-Commit Checklist below — `mise run all` in step 3 subsumes the individual pre-commit steps; do not substitute the pre-commit checklist here.

1. **Compliance check** — verify changes against the [compliance hierarchy](#compliance-hierarchy) above. CONSTITUTION and DESIGN violations must be fixed. VISION misalignment must be flagged. ARCHITECTURE deviations must be documented.
2. **Sync with base branch**
   ```bash
   git fetch origin main && git rebase origin/main
   ```
3. **Quality gates pass** — `mise run docs` auto-detects agent mode from env vars (`CLAUDECODE`, `CLAUDE_CODE`) and flips output defaults, producing wrong docs. Always override:
   ```bash
   GCX_AGENT_MODE=false mise run all
   ```
4. **Doc maintenance gate** — run the structural checks in [docs/reference/doc-maintenance.md](docs/reference/doc-maintenance.md). Update `CLAUDE.md` (package map), `ARCHITECTURE.md` (ADR table), and relevant `docs/architecture/` files if any are stale.
5. **Push**
   ```bash
   git push
   git status   # must show "up to date with origin"
   ```
   Work is not done until push succeeds. If it fails, resolve and retry.
6. **Beads** (if in use) — close completed issues and sync:
   ```bash
   bd close <id>      # from repo root, not worktrees
   bd dolt push
   ```

## Mandatory Pre-Commit Checklist

Run this checklist **before every commit** (not only before PR/push):

1. **Format touched files**
   ```bash
   gofmt -w <touched-go-files>
   ```
2. **Lint passes**
   ```bash
   mise run lint
   ```
3. **Targeted tests pass** for changed packages
   ```bash
   go test ./path/to/changed/package/...
   ```
4. **Full test suite passes**
   ```bash
   go test ./...
   ```
5. **Reference docs regenerated** (CI runs `mise run reference-drift` which fails on any drift)
   ```bash
   GCX_AGENT_MODE=false mise run reference
   ```
   This regenerates CLI reference, env-var reference, config reference, and linter-rules reference. Required when changes touch commands, flags, config fields, env vars, or linter rules.
6. **Docs build succeeds** (CI runs `mise run docs` after the drift check)
   ```bash
   mise run docs
   ```
   If `mise`/`mkdocs` is unavailable, skip — CI will catch build failures.
7. **No unstaged surprises**
   ```bash
   git status
   ```

## GitHub Issues

When creating or commenting on GitHub issues, **always anonymize system-specific details**. Replace real values with placeholders:

- Stack names / context names → `<my-context>`, `<stack>`
- URLs with stack or region identifiers → `https://example-<region>.grafana.net`
- Hosted IDs, stack IDs, org IDs → `12345`, `99999`
- Datasource names with stack slugs → `grafanacloud-<stack>-prom`
- API tokens, credentials → never include, even partially

This applies to issue bodies, comments, and code snippets embedded in issues.

## Beads Issue Tracker (optional)

This project can use **bd (beads)** for issue tracking. Run `bd prime` for full command reference.

```bash
bd ready                  # Find available work
bd show <id>              # View issue details
bd update <id> --claim    # Claim work
bd close <id>             # Complete work
bd dolt push              # Sync to Dolt remote (run from repo root, not worktrees)
```
