dashboard
**Scope**: Dashboard-as-Code (DaC) patterns, Go/CUE SDK usage, percli CLI, variables, panels, and datasource wiring. Does not cover operator CRDs or plugin development. **Version range**: Perses v0.47+ (CRD v1alpha2, Go SDK v0.47+) **Generated**: 2026-05-09 — verify against
$ npx -y skills add notque/vexjoy-agent --agent claude-codeHow it fires
How this agent gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
Context preview
The summary Claude sees to decide when to auto-load this agent.
**Scope**: Dashboard-as-Code (DaC) patterns, Go/CUE SDK usage, percli CLI, variables, panels, and datasource wiring. Does not cover operator CRDs or plugin development. **Version range**: Perses v0.47+ (CRD v1alpha2, Go SDK v0.47+) **Generated**: 2026-05-09 — verify against
Agent definition
dashboard.mdPerses Dashboard Reference
> **Scope**: Dashboard-as-Code (DaC) patterns, Go/CUE SDK usage, percli CLI, variables, panels, and datasource wiring. Does not cover operator CRDs or plugin development. > **Version range**: Perses v0.47+ (CRD v1alpha2, Go SDK v0.47+) > **Generated**: 2026-05-09 — verify against https://github.com/perses/perses/releases
---
Overview
Perses dashboards are defined as JSON/YAML documents validated against CUE schemas. Dashboard-as-Code (DaC) lets you generate these documents programmatically using the Go SDK or CUE, avoiding hand-edited JSON drift. The most common failure mode is referencing a datasource name or variable name that doesn't match the project's registered datasources — Perses fails silently on missing refs.
---
Pattern Table
| Pattern | Version | Use When | Avoid When | |---------|---------|----------|------------| | Go SDK (`go/sdk`) | `v0.47+` | Generating dashboards from code | The dashboard is one-off or manually curated | | CUE schemas | all | Validating dashboard JSON | You need Go type safety across multiple dashboards | | `percli apply -f` | all | Pushing dashboards to a live server | Dry-runs — use `--dry-run` flag | | `percli export` | all | Pulling existing dashboards to DaC | Initial migration from UI-created dashboards | | `percli migrate` | `v0.40+` | Converting Grafana dashboards | Only Grafana JSON v8+ is supported |
---
Dashboard-as-Code: Go SDK
Minimal working dashboard
import (
"github.com/perses/perses/go/sdk/dashboard"
"github.com/perses/perses/go/sdk/panel/timeseries"
listvar "github.com/perses/perses/go/sdk/variable/listvar"
prometheustarget "github.com/perses/perses/go/sdk/prometheus/query"
)
builder, err := dashboard.New("My Dashboard",
dashboard.ProjectName("my-project"),
dashboard.Duration("1h"),
dashboard.RefreshInterval("30s"),
dashboard.AddVariable(
listvar.New("namespace",
listvar.DisplayName("Namespace"),
listvar.CapturingRegexp("(.+)"),
listvar.AllowAllValue(true),
listvar.AllowMultiple(false),
),
),
dashboard.AddPanelGroup("Overview",
dashboard.AddPanel("Requests/sec",
timeseries.New("Requests/sec",
timeseries.WithPrometheusTarget(
`rate(http_requests_total{namespace="$namespace"}[5m])`,
prometheustarget.Legend("{{handler}}"),
),
),
),
),
)**Why**: The SDK enforces schema at compile time. Mistyped field names are caught before `percli apply` runs.
---
Variable types
// Text variable — free-form input
textvar.New("cluster",
textvar.DisplayName("Cluster"),
textvar.Value("prod"), // default value
)
// List variable — query-driven options
listvar.New("namespace",
listvar.PrometheusLabelValuesQuery("namespace", "kube_pod_info"),
listvar.AllowAllValue(true),
listvar.AllowMultiple(true),
listvar.Sort(listvar.AlphabeticalAsc),
)
// Constant variable — fixed value, often hidden
constantvar.New("datasource",
constantvar.Value("PrometheusDemo"),
constantvar.Hide(true),
)**Why**: List variables using `AllowMultiple(true)` must use `=~` (regex match) in PromQL, not `=`. Mixing `=` with a multi-value variable silently uses only the first selected value.
---
Panel types and imports
| Panel | Import path suffix | Key option | |-------|-------------|-----------| | TimeSeriesChart | `panel/timeseries` | `.WithPrometheusTarget()` | | GaugeChart | `panel/gauge` | `.Thresholds()` | | StatChart | `panel/stat` | `.Format()`, `.Sparkline()` | | BarChart | `panel/barchart` | `.XAxis()` | | Markdown | `panel/markdown` | `.Text()` | | ScatterChart | `panel/scatterchart` | `.WithPrometheusTarget()` | | Table | `panel/table` | `.ColumnSettings()` |
---
Pattern Catalog: Detection and Fixes
Hardcoded datasource name (breaks across projects)
**Detection**:
grep -rn '"default"' --include="*.go" | grep -i datasource
grep -rn 'datasource.*"prometheus"' --include="*.cue"
rg 'datasourceName.*"[A-Za-z]+"' --type go
**Signal**:
// Hardcoded datasource name — breaks when deployed to a project
// that registered the datasource under a different name
timeseries.WithPrometheusTarget(
"up",
prometheustarget.Datasource("default"), // "default" may not exist
)**Why it matters**: Datasource names are scoped to a project. A dashboard deployed to project `team-a` expecting `"default"` fails if that project registered the datasource as `"prometheus-prod"`. The panel renders empty with no error in the UI.
**Preferred action**:
// Use a variable reference for datasource selection
constantvar.New("datasource", constantvar.Value("PrometheusDemo"))
// Then reference it:
prometheustarget.Datasource("$datasource")---
Multi-value variable with equality operator
**Detection**:
grep -rn 'AllowMultiple(true)' --include="*.go" -A5 | grep -v '=~'
rg '\$\w+[^~]' --type json | grep -i 'expr\|query'
**Signal**:
listvar.New("namespace", listvar.AllowMultiple(true))
// ...then in query:
`kube_pod_info{namespace="$namespace"}` // = operator, not =~**Why it matters**: When multiple namespaces are selected, `$namespace` expands to `ns1|ns2|ns3`. The `=` operator treats this as a literal string match, always returning no results. The `=~` operator applies regex matching.
**Preferred action**:
`kube_pod_info{namespace=~"$namespace"}` // regex match for multi-value---
Missing `dashboard.Duration` / `RefreshInterval`
**Detection**:
rg 'dashboard\.New\(' --type go -A 10 | grep -c 'Duration\|Refresh'
grep -rn 'dashboard.New(' --include="*.go" -A 8 | grep -v 'Duration'**Signal**:
dashboard.New("My Dashboard",
dashboard.ProjectName("my-project"),
// No Duration or RefreshInterval — uses server defaults (may be 6h)
)**Why it matters**: Wit
Read more
Perses Dashboard Reference
> **Scope**: Dashboard-as-Code (DaC) patterns, Go/CUE SDK usage, percli CLI, variables, panels, and datasource wiring. Does not cover operator CRDs or plugin development. > **Version range**: Perses v0.47+ (CRD v1alpha2, Go SDK v0.47+) > **Generated**: 2026-05-09 — verify against https://github.com/perses/perses/releases
---
Overview
Perses dashboards are defined as JSON/YAML documents validated against CUE schemas. Dashboard-as-Code (DaC) lets you generate these documents programmatically using the Go SDK or CUE, avoiding hand-edited JSON drift. The most common failure mode is referencing a datasource name or variable name that doesn't match the project's registered datasources — Perses fails silently on missing refs.
---
Pattern Table
| Pattern | Version | Use When | Avoid When | |---------|---------|----------|------------| | Go SDK (`go/sdk`) | `v0.47+` | Generating dashboards from code | The dashboard is one-off or manually curated | | CUE schemas | all | Validating dashboard JSON | You need Go type safety across multiple dashboards | | `percli apply -f` | all | Pushing dashboards to a live server | Dry-runs — use `--dry-run` flag | | `percli export` | all | Pulling existing dashboards to DaC | Initial migration from UI-created dashboards | | `percli migrate` | `v0.40+` | Converting Grafana dashboards | Only Grafana JSON v8+ is supported |
---
Dashboard-as-Code: Go SDK
Minimal working dashboard
import (
"github.com/perses/perses/go/sdk/dashboard"
"github.com/perses/perses/go/sdk/panel/timeseries"
listvar "github.com/perses/perses/go/sdk/variable/listvar"
prometheustarget "github.com/perses/perses/go/sdk/prometheus/query"
)
builder, err := dashboard.New("My Dashboard",
dashboard.ProjectName("my-project"),
dashboard.Duration("1h"),
dashboard.RefreshInterval("30s"),
dashboard.AddVariable(
listvar.New("namespace",
listvar.DisplayName("Namespace"),
listvar.CapturingRegexp("(.+)"),
listvar.AllowAllValue(true),
listvar.AllowMultiple(false),
),
),
dashboard.AddPanelGroup("Overview",
dashboard.AddPanel("Requests/sec",
timeseries.New("Requests/sec",
timeseries.WithPrometheusTarget(
`rate(http_requests_total{namespace="$namespace"}[5m])`,
prometheustarget.Legend("{{handler}}"),
),
),
),
),
)**Why**: The SDK enforces schema at compile time. Mistyped field names are caught before `percli apply` runs.
---
Variable types
// Text variable — free-form input
textvar.New("cluster",
textvar.DisplayName("Cluster"),
textvar.Value("prod"), // default value
)
// List variable — query-driven options
listvar.New("namespace",
listvar.PrometheusLabelValuesQuery("namespace", "kube_pod_info"),
listvar.AllowAllValue(true),
listvar.AllowMultiple(true),
listvar.Sort(listvar.AlphabeticalAsc),
)
// Constant variable — fixed value, often hidden
constantvar.New("datasource",
constantvar.Value("PrometheusDemo"),
constantvar.Hide(true),
)**Why**: List variables using `AllowMultiple(true)` must use `=~` (regex match) in PromQL, not `=`. Mixing `=` with a multi-value variable silently uses only the first selected value.
---
Panel types and imports
| Panel | Import path suffix | Key option | |-------|-------------|-----------| | TimeSeriesChart | `panel/timeseries` | `.WithPrometheusTarget()` | | GaugeChart | `panel/gauge` | `.Thresholds()` | | StatChart | `panel/stat` | `.Format()`, `.Sparkline()` | | BarChart | `panel/barchart` | `.XAxis()` | | Markdown | `panel/markdown` | `.Text()` | | ScatterChart | `panel/scatterchart` | `.WithPrometheusTarget()` | | Table | `panel/table` | `.ColumnSettings()` |
---
Pattern Catalog: Detection and Fixes
Hardcoded datasource name (breaks across projects)
**Detection**:
grep -rn '"default"' --include="*.go" | grep -i datasource grep -rn 'datasource.*"prometheus"' --include="*.cue" rg 'datasourceName.*"[A-Za-z]+"' --type go
**Signal**:
// Hardcoded datasource name — breaks when deployed to a project
// that registered the datasource under a different name
timeseries.WithPrometheusTarget(
"up",
prometheustarget.Datasource("default"), // "default" may not exist
)**Why it matters**: Datasource names are scoped to a project. A dashboard deployed to project `team-a` expecting `"default"` fails if that project registered the datasource as `"prometheus-prod"`. The panel renders empty with no error in the UI.
**Preferred action**:
// Use a variable reference for datasource selection
constantvar.New("datasource", constantvar.Value("PrometheusDemo"))
// Then reference it:
prometheustarget.Datasource("$datasource")---
Multi-value variable with equality operator
**Detection**:
grep -rn 'AllowMultiple(true)' --include="*.go" -A5 | grep -v '=~' rg '\$\w+[^~]' --type json | grep -i 'expr\|query'
**Signal**:
listvar.New("namespace", listvar.AllowMultiple(true))
// ...then in query:
`kube_pod_info{namespace="$namespace"}` // = operator, not =~**Why it matters**: When multiple namespaces are selected, `$namespace` expands to `ns1|ns2|ns3`. The `=` operator treats this as a literal string match, always returning no results. The `=~` operator applies regex matching.
**Preferred action**:
`kube_pod_info{namespace=~"$namespace"}` // regex match for multi-value---
Missing `dashboard.Duration` / `RefreshInterval`
**Detection**:
rg 'dashboard\.New\(' --type go -A 10 | grep -c 'Duration\|Refresh'
grep -rn 'dashboard.New(' --include="*.go" -A 8 | grep -v 'Duration'**Signal**:
dashboard.New("My Dashboard",
dashboard.ProjectName("my-project"),
// No Duration or RefreshInterval — uses server defaults (may be 6h)
)**Why it matters**: Wit
Essays and writing behind this toolkit live at vexjoy.com. AI agents skip steps. "Looks correct" replaces running tests. "Trivial change" replaces verification.
Repo: notque/vexjoy-agent
Other agents on vexjoy-agent.
- ansible-automation-engineer
Ansible automation: playbooks, roles, collections, Molecule testing, Vault security.
Open agent - modules
**Scope**: Module selection patterns, builtin vs command/shell decisions, collection modules, and version-specific module changes **Version range**: ansible-core 2.14+ / Ansible Collections (community.general 7.0+) **Generated**: 2026-04-04 — verify against current Ansible
Open agent - testing
**Scope**: Molecule test scenarios, ansible-lint rules, idempotency validation, and check-mode patterns **Version range**: Molecule 6.0+ / ansible-lint 6.0+ / ansible-core 2.14+ **Generated**: 2026-04-04 — verify against current Molecule and ansible-lint documentation
Open agent - base-instructions
Universal operational rules injected by /do at agent dispatch. Domain-specific rules live in each agent's .md file.
Open agent - communication-patterns
**Scope**: Failure modes in agent output style — over-reporting, self-congratulation, verbose narration, and hedging. Covers what to detect and how to fix each. **Version range**: all versions **Generated**: 2026-05-11
Open agent - combat-effects-upgrade
Zero-dependency combat visual upgrades: CSS particle replacement, Framer Motion combat juice, CSS 3D card transforms.
Open agent

