Agent skill
reports
Report generation with .report.json format, interactive chart types (bar, line, area, pie, donut, radar, scatter, funnel), panel sizes, filter types, inline chat reports, and post-report checklist.
Install this agent skill to your Project
npx add-skill https://github.com/DenchHQ/DenchClaw/tree/main/skills/crm/reports
Metadata
Additional technical details for this skill
- openclaw
-
{ "emoji": "\ud83d\udcc8", "always": true, "inject": true }
SKILL.md
CRM Reports
This skill covers report generation and inline chat charts. For workspace fundamentals, see the parent crm skill (crm/SKILL.md). For DuckDB queries used in report SQL, see duckdb-operations (crm/duckdb-operations/SKILL.md).
Report Generation (Analytics / Charts)
Reports are JSON config files (.report.json) that the web app renders as live interactive dashboards using Recharts. The agent creates these files to give the user visual analytics over their CRM data.
Report file format
Store reports as .report.json files in {{WORKSPACE_PATH}}/** (wherever appropriate / create directories if you need for better structure). The JSON schema:
{
"version": 1,
"title": "Report Title",
"description": "Brief description of what this report shows",
"panels": [
{
"id": "unique-panel-id",
"title": "Panel Title",
"type": "bar",
"sql": "SELECT ... FROM v_{object} ...",
"mapping": { "xAxis": "column_name", "yAxis": ["value_column"] },
"size": "half"
}
],
"filters": [
{
"id": "filter-id",
"type": "dateRange",
"label": "Date Range",
"column": "created_at"
}
]
}
Chart types
| Type | Best for | Required mapping |
|---|---|---|
bar |
Comparing categories | xAxis, yAxis |
line |
Trends over time | xAxis, yAxis |
area |
Volume trends | xAxis, yAxis |
pie |
Distribution/share | nameKey, valueKey |
donut |
Distribution (with center) | nameKey, valueKey |
radar |
Multi-dimensional comparison | xAxis (or nameKey), yAxis |
scatter |
Correlation | xAxis, yAxis |
funnel |
Pipeline/conversion | nameKey, valueKey |
Panel sizes
"full"— spans full width (6 columns)"half"— spans half width (3 columns) — default"third"— spans one third (2 columns)
Filter types
dateRange— date picker (from/to), filters oncolumnselect— single-select dropdown, needssqlto fetch optionsmultiSelect— multi-select chips, needssqlto fetch optionsnumber— min/max numeric range
SQL query rules for reports
- Always use the auto-generated
v_{object}PIVOT views — never raw EAV queries - SQL must be SELECT-only (no INSERT/UPDATE/DELETE)
- Cast numeric fields:
"Amount"::NUMERICorCAST("Amount" AS NUMERIC) - Use
DATE_TRUNC('month', created_at)for time-series grouping - Always include
ORDER BYfor consistent chart rendering - Use aggregate functions:
COUNT(*),SUM(...),AVG(...),MIN(...),MAX(...) - Double-quote field names with spaces:
"Full Name","Email Address","Assigned To" - Verify the PIVOT view exists before writing report SQL: run
SELECT COUNT(*) FROM v_{object}first. If the view doesn't exist, create it (see duckdb-operations skill).
Before writing a report
- Verify the PIVOT view exists:
duckdb {{WORKSPACE_PATH}}/workspace.duckdb "SELECT COUNT(*) FROM v_{object}"— if this fails, the view needs to be created first. - Check the view columns:
duckdb {{WORKSPACE_PATH}}/workspace.duckdb -json "SELECT * FROM v_{object} LIMIT 1"— use the actual column names in your SQL (they are case-sensitive and may contain spaces). - Test each panel's SQL individually: Run each query to confirm it returns data before assembling the report JSON.
Handling empty data
If a view exists but returns 0 rows, the chart will render but show nothing. This is fine — no special handling needed. However, if the user asks "why is the chart empty?", check:
- Are there entries in the object?
SELECT COUNT(*) FROM entries WHERE object_id = (SELECT id FROM objects WHERE name = '{object}') - Do entries have field values?
SELECT COUNT(*) FROM entry_fields WHERE entry_id IN (SELECT id FROM entries WHERE object_id = ...)
Example Reports
Pipeline Funnel
{
"version": 1,
"title": "Deal Pipeline",
"description": "Deal count and value by stage",
"panels": [
{
"id": "deals-by-stage",
"title": "Deals by Stage",
"type": "funnel",
"sql": "SELECT \"Stage\", COUNT(*) as count FROM v_deal GROUP BY \"Stage\" ORDER BY count DESC",
"mapping": { "nameKey": "Stage", "valueKey": "count" },
"size": "half"
},
{
"id": "revenue-by-stage",
"title": "Revenue by Stage",
"type": "bar",
"sql": "SELECT \"Stage\", SUM(\"Amount\"::NUMERIC) as total FROM v_deal GROUP BY \"Stage\" ORDER BY total DESC",
"mapping": { "xAxis": "Stage", "yAxis": ["total"] },
"size": "half"
}
],
"filters": [
{ "id": "date", "type": "dateRange", "label": "Created", "column": "created_at" },
{
"id": "assignee",
"type": "select",
"label": "Assigned To",
"sql": "SELECT DISTINCT \"Assigned To\" as value FROM v_deal WHERE \"Assigned To\" IS NOT NULL",
"column": "Assigned To"
}
]
}
Contact Growth
{
"version": 1,
"title": "Contact Growth",
"description": "New contacts over time",
"panels": [
{
"id": "growth-trend",
"title": "Contacts Over Time",
"type": "area",
"sql": "SELECT DATE_TRUNC('month', created_at) as month, COUNT(*) as count FROM v_people GROUP BY month ORDER BY month",
"mapping": { "xAxis": "month", "yAxis": ["count"] },
"size": "full"
}
]
}
Inline Chat Reports
When a user asks for analytics in chat (without explicitly asking to save a report), emit the report JSON inside a fenced code block with language report-json. The web UI will render interactive charts inline:
Here's your pipeline analysis:
```report-json
{"version":1,"title":"Deals by Stage","panels":[{"id":"p1","title":"Deal Count","type":"bar","sql":"SELECT \"Stage\", COUNT(*) as count FROM v_deal GROUP BY \"Stage\" ORDER BY count DESC","mapping":{"xAxis":"Stage","yAxis":["count"]},"size":"full"}]}
```
Most deals are currently in the Discovery stage.
The user can then "Pin" the inline report to save it as a .report.json file.
Post-Report Checklist
After creating a .report.json file:
- Verify the PIVOT view exists:
duckdb {{WORKSPACE_PATH}}/workspace.duckdb "SELECT COUNT(*) FROM v_{object}"— create the view if missing - Test each panel's SQL individually: Run each query against the DB to confirm it returns valid data
- Verify the report JSON is valid (proper JSON syntax, no trailing commas)
- Choose which directory the report should be created in
{{WORKSPACE_PATH}}based on the context of the conversation, if nothing very relevant, create/use the{{WORKSPACE_PATH}}/reports/directory. - Write the file:
{{WORKSPACE_PATH}}/**/{slug}.report.json - Tell the user they can view it in the workspace sidebar under whichever directory it was rightfully placed in based on the context.
Choosing the Right Chart Type
- Comparing categories (status breakdown, source distribution):
barorpie - Time series (growth, trends, revenue over time):
lineorarea - Pipeline/conversion (deal stages, lead funnel):
funnel - Distribution/proportion (market share, segment split):
pieordonut - Multi-metric comparison (performance scores):
radar - Correlation (price vs. size, score vs. revenue):
scatter - When in doubt,
baris the safest default
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
dench-integrations
Connected app integration recipes for Dench Integrations (Gmail, Slack, GitHub, Notion, Google Calendar, Linear, Stripe, YouTube, and 500+ more)
gstack-workflow
Structured AI-assisted development workflow with specialist roles — Think, Plan, Build, Review, Test, Ship, Reflect. Adapted from garrytan/gstack (MIT).
plan-ceo-review
CEO/founder-mode plan review. Rethink the problem, find the 10-star product, challenge premises. Four modes: SCOPE EXPANSION, SELECTIVE EXPANSION, HOLD SCOPE, SCOPE REDUCTION. Use when reviewing strategy, questioning scope, or before engineering review.
investigate
Systematic root-cause debugging. Four phases: investigate, analyze, hypothesize, implement. Iron Law: no fixes without root cause investigation first. Use when debugging errors, unexpected behavior, or troubleshooting.
design-consultation
Build a complete design system from scratch. Research the landscape, propose safe choices AND creative risks, generate DESIGN.md. Use when creating a new design system or establishing design foundations for a project.
land-and-deploy
Merge the PR, wait for CI and deploy, verify production health. Takes over after ship. One command from "approved" to "verified in production."
Didn't find tool you were looking for?