Agent SkillsMapleTechLabs/maple › dashboard-builder

dashboard-builder

GitHub

指导Agent构建Maple可观测性仪表板。要求先通过测试工具验证数据查询有效性,再添加统计、表格或图表组件,确保可视化内容基于真实数据并处理空数据情况。

apps/slack-agent/agent/skills/dashboard-builder/SKILL.md MapleTechLabs/maple

Trigger Scenarios

用户请求创建或编辑仪表盘 用户需要添加或修复仪表板组件

Install

npx skills add MapleTechLabs/maple --skill dashboard-builder -g -y
More Options

Non-standard path

npx skills add https://github.com/MapleTechLabs/maple/tree/main/apps/slack-agent/agent/skills/dashboard-builder -g -y

Use without installing

npx skills use MapleTechLabs/maple@dashboard-builder

指定 Agent (Claude Code)

npx skills add MapleTechLabs/maple --skill dashboard-builder -a claude-code -g -y

安装 repo 全部 skill

npx skills add MapleTechLabs/maple --all -g -y

预览 repo 内 skill

npx skills add MapleTechLabs/maple --list

SKILL.md

Frontmatter
{
    "name": "dashboard-builder",
    "description": "Use when the user asks to build, add, edit, or fix Maple dashboards or dashboard widgets (stats, tables, charts, lists)."
}

Dashboard builder

You are building Maple dashboards: understand what the user wants to visualize, query their observability data first to see what's available, then propose widgets backed by real data. Tool names below are short names — call them with the maple__ prefix (e.g. maple__test_widget_query).

MANDATORY: Test-Before-Propose Workflow

Before proposing ANY widget with add_dashboard_widget, you MUST first test the exact query using the test_widget_query tool. This runs the same query the widget will use and shows you the actual data.

Workflow for every widget:

  1. Build the widget config mentally (endpoint, params, transform)
  2. Call test_widget_query with the exact same endpoint, params, and transform you plan to use
  3. Read the results:
    • If "data exists" → proceed to add_dashboard_widget
    • If "No data returned" or "EMPTY" → do NOT propose the widget. Tell the user what's missing and suggest alternatives.
  4. Briefly summarize the test results (e.g., "Tested errors_summary — found 42 errors at 2.1% error rate")
  5. Call add_dashboard_widget with the validated config

For chart widgets (custom_query_builder_timeseries):

  • Call test_widget_query with endpoint="custom_query_builder_timeseries" and the full params including queries[]
  • The tool will run each query and show data point counts, series keys, and value ranges
  • For metrics queries: call list_metrics FIRST to discover exact metricName, metricType, metricUnit, and isMonotonic before testing
  • Every chart must have a specific non-empty title

When data is empty:

  • Do NOT propose the widget
  • Tell the user what you tested and what was missing
  • Suggest alternatives based on what data IS available (e.g., "No metrics found, but I see traces for 3 services — want a latency chart instead?")

Efficiency for multi-widget dashboards:

  • For "build me a dashboard" requests, start with service_overview to understand what services exist
  • You can test multiple widget configs in sequence, then propose them all
  • One test_widget_query call per widget is the standard — it's fast and confirms the exact query works

Widget Types

stat — Single-value display

Best for: KPIs, counters, rates. Shows one number prominently.

Common configurations:

  • Total Traces: endpoint="service_usage", transform.reduceToValue={field:"totalTraces", aggregate:"sum"}, unit="number"
  • Total Logs: endpoint="service_usage", transform.reduceToValue={field:"totalLogs", aggregate:"sum"}, unit="number"
  • Error Rate: endpoint="errors_summary", transform.reduceToValue={field:"errorRate", aggregate:"first"}, unit="percent"
  • Total Errors: endpoint="errors_summary", transform.reduceToValue={field:"totalErrors", aggregate:"first"}, unit="number"
  • Active Services: endpoint="service_usage", transform.reduceToValue={field:"serviceName", aggregate:"count"}, unit="number"

table — Tabular data

Best for: lists of records, comparisons, detailed breakdowns.

Common configurations:

  • Recent Traces: endpoint="list_traces", params={limit:5}, transform={limit:5}, columns=[{field:"rootSpanName",header:"Root Span"},{field:"durationMs",header:"Duration",unit:"duration_ms",align:"right"},{field:"hasError",header:"Status",align:"right"}]
  • Errors by Type: endpoint="errors_by_type", params={limit:5}, transform={limit:5}, columns=[{field:"errorType",header:"Error Type"},{field:"count",header:"Count",unit:"number",align:"right"},{field:"affectedServicesCount",header:"Services",align:"right"}]
  • Service Overview: endpoint="service_overview", columns=[{field:"serviceName",header:"Service"},{field:"p95LatencyMs",header:"P95",unit:"duration_ms",align:"right"},{field:"errorRate",header:"Error Rate",unit:"percent",align:"right"},{field:"throughput",header:"Throughput",unit:"requests_per_sec",align:"right"}]

chart — Time series charts

Best for: trends over time, comparisons across services, latency/throughput patterns. Use endpoint="custom_query_builder_timeseries" with appropriate params. Available chartId values: "query-builder-bar", "query-builder-area", "query-builder-line"

Chart selection rules:

  • use "query-builder-area" for throughput, error count, error rate, counter rate, or increase charts
  • use "query-builder-line" for latency, percentiles, gauges, utilization, saturation, and most single-series metric trends
  • use "query-builder-bar" only when the user explicitly wants bars or when comparing a small number of grouped series over time

For traces query-builder charts:

  • internal aggregation values: count, avg_duration, p50_duration, p95_duration, p99_duration, error_rate
  • user-facing wording in titles and legends: requests, avg latency, p50 latency, p95 latency, p99 latency, error rate
  • omit stepInterval unless the user explicitly asks for a specific granularity
  • default groupBy to "none" unless the user explicitly wants a comparison split such as by service or by status code

For metrics query-builder charts:

  • sum + isMonotonic=true usually means a counter; prefer aggregation="rate" for ongoing throughput and aggregation="increase" for change over time
  • do NOT use raw aggregation="sum" for monotonic counters unless the user explicitly asks for cumulative bucket sums
  • gauges usually want avg, max, or min
  • histograms and exponential_histograms usually want avg, max, or min; avoid sum unless the user explicitly asks for it
  • never guess metricName or metricType
  • carry isMonotonic in the query when list_metrics provides it
  • default groupBy to "none" unless the user explicitly wants a service or attribute comparison

Required shape for custom_query_builder_timeseries params:

{
  "queries": [
    {
      "id": "uuid",
      "name": "A",
      "enabled": true,
      "dataSource": "traces|logs|metrics",
      "aggregation": "...",
      "whereClause": "...",
      "groupBy": "...",
      "addOns": { "groupBy": true, "having": false, "orderBy": false, "limit": false, "legend": false },
      "metricName": "",
      "metricType": "sum|gauge|histogram|exponential_histogram",
      "having": "",
      "orderBy": "",
      "limit": "",
      "legend": "",
      "orderByDirection": "desc",
      "signalSource": "default"
    }
  ],
  "formulas": [],
  "comparison": { "mode": "none", "includePercentChange": true },
  "debug": false
}

list — Recent items display

Best for: showing recent traces or logs with clickable links to detail pages.

Configuration:

  • visualization: "list"
  • endpoint: "list_traces" or "list_logs"
  • display.listDataSource: "traces" or "logs"
  • display.listLimit: number (default 10, max 50)
  • Optional: display.listWhereClause for filtering, display.listRootOnly for traces
  • No chartId needed.

Common Mistakes

WRONG: endpoint="custom_timeseries" with source/metric/filters flat params RIGHT: endpoint="custom_query_builder_timeseries" with queries[] array

WRONG: aggregation="sum" or "avg" for a monotonic sum counter RIGHT: aggregation="rate" for ongoing throughput, "increase" for cumulative change

WRONG: title="http.server.duration" or "effect_fiber_lifetimes (avg)" RIGHT: title="HTTP Server Duration" or "Avg Latency"

WRONG: No unit on a latency chart or missing unit on error rate RIGHT: unit="duration_ms" for latency, unit="percent" for error rate, unit="bytes" for memory

Metric Units

When list_metrics returns a metricUnit, map it to display units:

  • "ms" → duration_ms, "s" → duration_s, "us" → duration_us, "ns" → duration_ns
  • "By" → bytes, "%" → percent, "1" → number For trace charts: latency aggregations → duration_ms, error_rate → percent, count → number

Data Source Endpoints

  • service_usage: Per-service usage stats (totalTraces, totalLogs, serviceName)
  • service_overview: All services with p95LatencyMs, errorRate, throughput
  • service_apdex_time_series: Apdex score over time for a service
  • list_traces: Individual traces with rootSpanName, durationMs, hasError, serviceName
  • traces_facets: Facet counts for trace filtering
  • traces_duration_stats: Duration percentiles (p50, p95, p99)
  • list_logs: Log records with severity, body, serviceName
  • logs_count: Total log count with filters
  • errors_summary: Aggregate error stats (totalErrors, errorRate, affectedServices)
  • errors_by_type: Errors grouped by type with count, affectedServicesCount
  • error_detail_traces: Sample traces for a specific error type
  • error_rate_by_service: Error rate per service
  • list_metrics: Available metrics with type, unit, monotonicity, and data point counts
  • metrics_summary: Summary counts by metric type
  • custom_query_builder_timeseries: Query builder for chart/stat timeseries widgets
  • custom_query_builder_breakdown: Query builder for breakdown widgets

NOTE: Do NOT use custom_timeseries or custom_breakdown endpoints. Always use custom_query_builder_timeseries or custom_query_builder_breakdown instead.

Transform Options

  • reduceToValue: {field, aggregate} — Collapse rows to single value. Aggregates: sum, first, count, avg, max, min
  • limit: number — Limit result rows
  • sortBy: {field, direction} — Sort by field (asc/desc)
  • fieldMap: Record<string,string> — Rename fields
  • flattenSeries: {valueField} — Flatten time series with multiple series keys

Units

number, percent, duration_ms, duration_us, duration_s, duration_ns, bytes, requests_per_sec, short, none

Guidelines

  • ALWAYS validate data before proposing any widget. No exceptions.
  • ALWAYS use add_dashboard_widget to propose widgets — never describe JSON configs in text
  • Choose the most appropriate visualization type: trends over time → chart, single metric → stat, detailed records → table
  • Use descriptive, human-readable titles. Never use raw metric names with dots or underscores as titles. "HTTP Server Duration" not "http.server.duration". "P95 Latency" not "p95_duration".
  • You can propose multiple widgets in sequence for comprehensive views
  • When the user wants to monitor a specific service, propose a mix of stat + table + chart widgets for that service
  • For metrics charts, call list_metrics first to discover exact metricName and metricType. Never guess metric names.
  • Never output a metrics query without both metricName and metricType.
  • Prefer one clean series over a noisy split. Only group by service/attribute when the user actually wants a comparison.
  • Briefly state what the data showed before proposing each widget.

Fixing an existing widget

When the user reports a broken or wrong widget ("the p95 widget on the checkout dashboard is broken"), repair it surgically — do not rebuild it:

  1. Fetch the current state with get_dashboard (use list_dashboards first if the dashboard is ambiguous) and locate the widget by the title or id the user gave. Never guess a widget's current config.
  2. Treat the fetched widget JSON as the single source of truth. Diagnose what is wrong from the user's description and the config; modify only what the fix requires.
  3. Do NOT change id, layout, or visualization unless the fix explicitly requires it. Preserve display.title and other display config that is not implicated by the problem.
  4. If the fix touches the query (endpoint, params, transform), validate it with test_widget_query first — the test-before-propose rule applies to fixes too.
  5. Call update_dashboard_widget with dashboard_id, widget_id, and a complete corrected widget_json (the full widget object as a JSON string), not just the changed fields.
  6. After the user approves, briefly confirm what changed and why.

Approvals

add_dashboard_widget and the other dashboard mutations pause for a Slack approve/deny prompt; on approve they execute for real. Never imitate the approval prompt in prose, and never retry a denied action without a new directive.

Response Style

  • Be concise. State what you found, then propose the widget.
  • DO NOT narrate your tool calls or explain your investigation process in detail
  • After adding widgets, confirm what was added in one sentence, with a link to the dashboard

Version History

  • 6578edf Current 2026-07-31 11:20

Same Skill Collection

.agents/skills/clickhouse-architecture-advisor/SKILL.md
.agents/skills/clickhouse-best-practices/SKILL.md
.agents/skills/clickhousectl-cloud-deploy/SKILL.md
.agents/skills/clickhousectl-local-dev/SKILL.md
.agents/skills/coss-particles/SKILL.md
.agents/skills/coss/SKILL.md
.agents/skills/react-doctor/SKILL.md
.agents/skills/tinybird-cli-guidelines/SKILL.md
.agents/skills/tinybird-python-sdk-guidelines/SKILL.md
.agents/skills/tinybird-typescript-sdk-guidelines/SKILL.md
.agents/skills/tinybird/SKILL.md
.context/effect/.agents/skills/grill-me/SKILL.md
.context/effect/.agents/skills/jsdocs/SKILL.md
.context/effect/.agents/skills/scratchpad/SKILL.md
.factory/skills/react-doctor/SKILL.md
apps/slack-agent/agent/skills/incident-investigation/SKILL.md
skills/maple-audit/SKILL.md
skills/maple-csharp-style/SKILL.md
skills/maple-effect-style/SKILL.md
skills/maple-go-style/SKILL.md
skills/maple-java-style/SKILL.md
skills/maple-kotlin-style/SKILL.md
skills/maple-nextjs-style/SKILL.md
skills/maple-nodejs-style/SKILL.md
skills/maple-onboard/SKILL.md
skills/maple-onboarding-style/SKILL.md
skills/maple-python-style/SKILL.md
skills/maple-rust-style/SKILL.md
.agents/skills/chdb-datastore/SKILL.md
.agents/skills/chdb-sql/SKILL.md
.agents/skills/maple-telemetry-conventions/SKILL.md
.agents/skills/onboarding-cro/SKILL.md
skills/maple-dashboard-widgets/SKILL.md
skills/maple-otel-spec-review/SKILL.md

Metadata

Files
0
Version
a80abb5
Hash
d3bb57ef
Indexed
2026-07-31 11:20

Home - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-08-03 22:16
浙ICP备14020137号-1 $Map of visitor$