Install
$ agentstack add skill-xobotyi-cc-foundry-dashboards ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Grafana Dashboards
Dashboards are JSON: panels on a 24-column grid, fed by data-source queries, shaped by client-side transformations, styled by standard options and overrides, parameterized by template variables, connected through annotations and links. Data shape drives the visualization; variables make dashboards reusable; links carry context across navigation.
Scope
- In scope: dashboard JSON (Classic and V2 schemas), panel selection and configuration, standard options,
thresholds, value mappings, field overrides, transformations, all variable types, repeating panels/rows/tabs, annotations, dashboard/panel/data links, library panels, version history, panel editor and inspector.
- Out of scope:
- Data source query languages —
promql,logsql,metricsqlare sibling skills. This skill governs how queries
wire into panels, not query syntax.
- Grafana Alerting — alert rules, contact points, notification policies belong to the
alertingsibling skill.
Panel-attached alert rules and the panel editor's Alert tab are integration points only.
- Provisioning, file-based dashboards, dashboards-as-code tooling — Terraform, Grizzly, Foundation SDK, Helm
charts, provisioning/dashboards/*.yaml belong to the provisioning sibling skill. This skill covers the JSON those tools emit.
References
- Dashboard JSON model (Classic + V2) — [
${CLAUDE_SKILL_DIR}/references/json-model.md] Top-level fields, panel
object structure, gridPos, timepicker/templating/annotations blocks, library panel JSON shape, V2 Resource kinds, schema versioning, direct JSON edit mechanics.
- Panels and visualizations — [
${CLAUDE_SKILL_DIR}/references/panels.md] Visualization-selection rules, panel-type
catalog with type IDs, panel editor and inspector structure, library panel lifecycle, panel styles.
- Panel deep dives (time series, stat, table) — [
${CLAUDE_SKILL_DIR}/references/panel-deep-dives.md] Per-panel
configuration: time-series graph styles (line width, fill opacity, gradient mode, interpolation), axis placement, legend, tooltip, special overrides (Transform, Fill below to); stat value options, text modes, color and graph modes; table cell types, column filtering, sorting, tooltip-from-field, footer calculations.
- Panel options — [
${CLAUDE_SKILL_DIR}/references/panel-options.md] Standard options (unit, min/max, decimals,
color scheme, display name), thresholds, value mappings, field overrides, override precedence, display-name expressions.
- Variables — [
${CLAUDE_SKILL_DIR}/references/variables.md] All variable types, syntax, format options, selection
options, multi-value interpolation, multi-property variables, chained variables, regex filtering, global built-ins, URL sync, repeating panels/rows/tabs.
- Transformations — [
${CLAUDE_SKILL_DIR}/references/transformations.md] Full catalog grouped by purpose (adding
fields, filtering, reshaping, grouping, histograms, time-series modeling), common patterns, debugging mechanics.
- Annotations and links — [
${CLAUDE_SKILL_DIR}/references/annotations-links.md] Native annotations, annotation
queries, time regions, dashboard/panel/data links, data link variables, cross-dashboard navigation patterns.
Dashboard structure
Six top-level concerns:
- Identity —
uid(stable; externalize references via this),title,tags,version,schemaVersion. Never
hand-edit schemaVersion or version.
- Time —
time.from/time.to,timezone,refresh,timepicker(refresh intervals + quick ranges). templating.list— template variables. Array order = render order left-to-right.annotations.list— annotation queries. Built-in-- Grafana --query is always present.panels— panel objects. Layout viagridPos(24 columns × 30px per row unit).links— dashboard-level links (top of dashboard or controls menu).
Two schemas. Classic is the historical default and what grafana.com dashboards use. V2 Resource (Kubernetes-style apiVersion: dashboard.grafana.app/v2beta1) supports advanced layouts and conditional rendering and is the preferred format for new dashboards-as-code. See json-model.md for both schemas and the full panel object spec.
Panel selection
Match data shape to visualization. Grafana's auto-suggestion reads shape, not intent — don't accept it blindly.
- Time-stamped numeric series → Time series
- Categorical numeric (one value per category) → Bar chart
- Distribution of values → Histogram (point-in-time) or Heatmap (over time)
- Discrete state changes over time → State timeline
- Periodic state snapshots → Status history
- Headline number with optional sparkline → Stat
- One value vs. min/max (radial) → Gauge
- Multiple values vs. min/max → Bar gauge (gauges scale poorly past 2–3 metrics)
- Proportional parts of a whole, segment count ≤ 7 → Pie chart; for ranking use Bar chart
- Tabular rows → Table; use the
sparklinecell type with the Time series to table transformation for per-row
trends
- Sequential numeric x that is not time → Trend
- Arbitrary x/y scatter → XY chart
- Logs/traces/profiles/geospatial/graph → Logs / Traces / Flame graph / Geomap / Node graph
- Markdown, HTML, or RSS → Text / News
Panel type IDs in JSON: timeseries, stat, gauge, bargauge, barchart, histogram, heatmap, piechart, table, logs, nodeGraph, traces, flamegraph, canvas, geomap, text, news, dashlist, alertlist, annolist, state-timeline, status-history, candlestick, trend, xychart.
Panel configuration
Display pipeline order:
- Queries return data frames.
- Transformations reshape frames (client-side, ordered).
- Standard options apply per-field (unit, min/max, decimals, color scheme, display name).
- Value mappings translate values to display text and color.
- Thresholds drive conditional colors (and lines/regions on supporting panels).
- Field overrides apply per-field property changes. Last write wins.
- Visualization renders.
Standard options rules
- Always set base units. Pick from the catalog (
Time → seconds,Data → bytes,Throughput → reqps). Don't
pre-scale in queries — let Grafana scale for display.
- For seconds-since-epoch timestamps, multiply by 1000 with
Add field from calculation→Binary operationbefore
applying a Date & time unit. Grafana's date/time formats expect milliseconds.
Stringunit displays all decimals when you need exact values without rounding.- Color scheme by intent:
- Categorical / series-name-stable →
Classic palette - Series names change run-to-run →
Classic palette (by series name) - Value-driven →
From thresholds (by value)orSingle/Multiple continuous colors (by value) No value— set a placeholder (-,N/A,0) so blank panels are unambiguous.
Thresholds rules
- Defaults:
Base = green,80 = red,Mode = Absolute. Override per panel — don't ship the default unchanged. Absolutewhen threshold values are real-domain numbers.Percentageonly when comparing to dynamic
min/max.
- On time-series-like panels, set
Show thresholdsexplicitly (As lines,As filled regions) — default isOff. - Table panels apply threshold colors only when cell display mode is
Color textorColor background.
Value mappings rules
- Mappings bypass unit formatting for matched values. Don't combine a mapped value with a unit suffix and expect
both.
- Order matters. Grafana checks mappings top-to-bottom; first match wins.
Special → Null→ "N/A" to make missing data unambiguous in Stat/Table.
Field overrides rules
- Match by name (exact), regex, type, query refId, or values (reducer condition).
- Don't rename via override.
Display namechanges the rendered label only; for actual field renaming use **Rename
by regex**.
- Precedence:
defaults → standard options → value mappings → thresholds → overrides. Reorder in the Overrides
tab when later rules need to win.
Transformations
Run in listed order; each step sees the previous output. Text fields accept dashboard variables (interpolated before execution).
- Default order for "shape and aggregate":
Filter data by values/Filter fields by name— drop unneeded data first.Convert field type/Extract fields— coerce types.Add field from calculation— derive fields.Group by/Reduce— aggregate.Organize fields by name— final naming/ordering.
- Always wrap counters in
rate()orincrease()at the query level before transformations —Reduceon raw
counters is meaningless. (Query-language concern; see promql.)
Join by fieldonTime(Outer join, time series) aligns multiple queries before visualizing as Table or
computing cross-query expressions.
Partition by valuesinstead of N queries with differentWHEREclauses.Time series to table transformfor "row per entity, sparkline in the last column" tables.- Debug with the bug icon (input vs. output frames) or eye icon (disable to bisect). Toggle Table view in the
panel preview to see raw post-transformation frames.
- Remove unused transformations. Disabled-but-present steps still cost CPU.
Variables
Variables interpolate before queries reach the data source, with data-source-specific escaping (regex for Prometheus/InfluxDB, Lucene for Elasticsearch, glob for Graphite). Use ${var:raw} to bypass.
Variable type selection
- Query — options from a data-source query. Default for label/tag/host enumeration.
- Custom — static list (CSV or JSON). Faster than a query for values that never change.
- Text box — free input. For high-cardinality fields you can't enumerate.
- Constant — hidden, fixed value. For path prefixes that change on export/import.
- Data source — switch a dashboard's data source instance (multi-environment dashboards).
- Interval —
1m,1h,1dtime spans. Reference as$myintervalin group-by/summarize. - Filters (formerly ad-hoc) — auto-applied key/value filters. Prometheus, Loki, InfluxDB, Elasticsearch, OpenSearch,
and the special Dashboard data source.
- Switch — two-state toggle for conditional query logic.
Variable rules
$varnamefor standalone references;${varname}to interpolate inside a larger expression. Never use deprecated
[[varname]].
Refresh: On time range changeonly when the variable query depends on time. OtherwiseOn dashboard load—
saves a refetch per range change.
- Order variables by dependency: parents before children. Grafana renders dropdowns left-to-right in list order.
Custom all valueis not escaped — match the data source's syntax:.+or.*for Prometheus/Loki regex;*
for Graphite glob; (.*) for an explicit regex group.
- Use
$__rate_intervalfor Prometheusrate()— handles the 4× scrape-interval rule automatically. - For ms-epoch URLs, use
${__from}/${__to}. For ISO, use${__from:date:iso}. For UTC, use:dateor
:date:iso (other formats use browser time).
- Multi-property variables (custom JSON, some query types) — define once, reference properties as
${var.aws},
${var.azure}. Prefer over parallel variables for the same concept.
skipUrlSync: truewhen the variable shouldn't be URL-overridable (sensitive values, shared dashboards).
Constants default to this.
- Repeating panels — set
Repeat by variableto a multi-value variable.Horizontalpanels can't share a row with
non-repeating panels; Vertical matches the source panel's width. Put the variable in the panel title (CPU — $host) for clarity.
Annotations
- Native annotations added via click in time series, state timeline, candlestick panels (Ctrl/Cmd-click for a point;
Ctrl/Cmd-click-drag for a region). Stored in Grafana's database.
- Annotation queries fetch events from any data source. Configured in
Settings → Annotations. Each query has its
own toggle, color, and Show in: All panels / Selected panels / All panels except scope.
- Built-in
-- Grafana --query is always present. By default filters bydashboardId— Save As does not carry
over manual annotations. To survive duplication, tag annotations and use a tag-filtered query.
- **Tag-filtered annotation queries on externally-shared dashboards leak annotations from all dashboards in the
organization.** Audit before enabling external sharing on a dashboard with tag filtering.
- Time regions shade recurring windows (business hours, weekends). Configure via
Query type: Time regions;
supports Cron syntax in the Advanced toggle.
Links
Three link types, three scopes.
- Dashboard links (Settings → Links) — top of dashboard or controls menu. For navigation between dashboards that
share variables, or "Dashboards with tag X" dropdowns.
- Panel links (Panel options → Panel links) — header-icon URLs per panel. For "open the upstream runbook" or "open
source system." Cannot reference field/value variables.
- Data links (Data links and actions) — per-field click targets including value, series, and labels under the
cursor. For drilldowns and panel-to-panel filtering.
Data link rules
__url_time_rangedoes not auto-insert?or&— build the query string yourself.${__all_variables}appends every current template variable. Place before any explicitvar-=...so
explicit values override the wildcard.
- Linking to another dashboard — target must have a variable with the same name (not label). Otherwise map
explicitly: &var-host=${server}.
__field.displayNamewhen fields have been renamed;__field.namefor the raw name.- Actions trigger unauthenticated browser-originated API calls. Treat URL and body as user-visible. Gate the target
API with its own auth or proxy through short-lived tokens.
One clickskips the context menu; only one data link per panel can have it enabled.
Library panels
Reusable panel definitions referenced by libraryPanel: { uid, name } instead of inline config.
- Create from a panel →
More → New library panel. Source panel becomes a library-panel reference; save the
dashboard to persist.
- Edits propagate to every instance on next load.
- Unlink breaks the binding for one instance (restores inline config).
- Replace swaps one library panel for another at a specific instance.
- Permissions follow the parent folder (and explicit RBAC overrides where enabled).
- Delete only when no dashboards reference the panel.
- Use library panels for the 2–3 panels you want identical everywhere (single uptime stat, standard request-rate graph).
Don't libraryize panels you'll specialize per dashboard.
Version history
- Grafana keeps the last 20 versions by default. Override with
[dashboards] versions_to_keep. Settings → Versions— pick two andCompare versionsfor text + JSON diff.Restorecreates a new version with old content — old versions remain in history.- JSON Model tab in Settings edits raw JSON. Saving runs schema migration if needed.
Application
When writing dashboards:
- Pick panel type from data shape, not Grafana's auto-suggestion.
- Always set units; let Grafana handle scaling.
- Add at least one threshold on health-signaling panels; ship
Show thresholds: As linesorAs filled regionson
time-series-like panels instead of the default Off.
- Use variables for environments, namespaces, services — anything you'd otherwise duplicate. Order so dependencies
render left to right.
- Use
$__rate_interval(Pr
…
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: xobotyi
- Source: xobotyi/cc-foundry
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.