@bonnard/cli 0.1.9 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/bon.mjs +9 -11
- package/dist/docs/topics/dashboards.components.md +137 -0
- package/dist/docs/topics/dashboards.examples.md +130 -0
- package/dist/docs/topics/dashboards.md +83 -0
- package/dist/docs/topics/dashboards.queries.md +117 -0
- package/dist/templates/claude/skills/bonnard-get-started/SKILL.md +189 -0
- package/dist/templates/cursor/rules/bonnard-get-started.mdc +188 -0
- package/dist/templates/shared/bonnard.md +1 -2
- package/package.json +2 -2
- package/dist/templates/claude/skills/bonnard-cli/SKILL.md +0 -59
- package/dist/templates/claude/skills/bonnard-queries/SKILL.md +0 -68
- package/dist/templates/cursor/rules/bonnard-cli.mdc +0 -47
- package/dist/templates/cursor/rules/bonnard-queries.mdc +0 -49
package/dist/bin/bon.mjs
CHANGED
|
@@ -564,23 +564,18 @@ function createAgentTemplates(cwd, env) {
|
|
|
564
564
|
const claudeRulesDir = path.join(cwd, ".claude", "rules");
|
|
565
565
|
const claudeSkillsDir = path.join(cwd, ".claude", "skills");
|
|
566
566
|
fs.mkdirSync(claudeRulesDir, { recursive: true });
|
|
567
|
-
fs.mkdirSync(path.join(claudeSkillsDir, "bonnard-
|
|
568
|
-
fs.mkdirSync(path.join(claudeSkillsDir, "bonnard-queries"), { recursive: true });
|
|
567
|
+
fs.mkdirSync(path.join(claudeSkillsDir, "bonnard-get-started"), { recursive: true });
|
|
569
568
|
writeTemplateFile(sharedBonnard, path.join(claudeRulesDir, "bonnard.md"), createdFiles);
|
|
570
|
-
writeTemplateFile(loadTemplate("claude/skills/bonnard-
|
|
571
|
-
writeTemplateFile(loadTemplate("claude/skills/bonnard-queries/SKILL.md"), path.join(claudeSkillsDir, "bonnard-queries", "SKILL.md"), createdFiles);
|
|
569
|
+
writeTemplateFile(loadTemplate("claude/skills/bonnard-get-started/SKILL.md"), path.join(claudeSkillsDir, "bonnard-get-started", "SKILL.md"), createdFiles);
|
|
572
570
|
mergeSettingsJson(loadJsonTemplate("claude/settings.json"), path.join(cwd, ".claude", "settings.json"), createdFiles);
|
|
573
571
|
const cursorRulesDir = path.join(cwd, ".cursor", "rules");
|
|
574
572
|
fs.mkdirSync(cursorRulesDir, { recursive: true });
|
|
575
573
|
writeTemplateFile(withCursorFrontmatter(sharedBonnard, "Bonnard semantic layer project context", true), path.join(cursorRulesDir, "bonnard.mdc"), createdFiles);
|
|
576
|
-
writeTemplateFile(loadTemplate("cursor/rules/bonnard-
|
|
577
|
-
writeTemplateFile(loadTemplate("cursor/rules/bonnard-queries.mdc"), path.join(cursorRulesDir, "bonnard-queries.mdc"), createdFiles);
|
|
574
|
+
writeTemplateFile(loadTemplate("cursor/rules/bonnard-get-started.mdc"), path.join(cursorRulesDir, "bonnard-get-started.mdc"), createdFiles);
|
|
578
575
|
const codexSkillsDir = path.join(cwd, ".agents", "skills");
|
|
579
|
-
fs.mkdirSync(path.join(codexSkillsDir, "bonnard-
|
|
580
|
-
fs.mkdirSync(path.join(codexSkillsDir, "bonnard-queries"), { recursive: true });
|
|
576
|
+
fs.mkdirSync(path.join(codexSkillsDir, "bonnard-get-started"), { recursive: true });
|
|
581
577
|
writeTemplateFile(sharedBonnard, path.join(cwd, "AGENTS.md"), createdFiles);
|
|
582
|
-
writeTemplateFile(loadTemplate("claude/skills/bonnard-
|
|
583
|
-
writeTemplateFile(loadTemplate("claude/skills/bonnard-queries/SKILL.md"), path.join(codexSkillsDir, "bonnard-queries", "SKILL.md"), createdFiles);
|
|
578
|
+
writeTemplateFile(loadTemplate("claude/skills/bonnard-get-started/SKILL.md"), path.join(codexSkillsDir, "bonnard-get-started", "SKILL.md"), createdFiles);
|
|
584
579
|
return createdFiles;
|
|
585
580
|
}
|
|
586
581
|
async function initCommand() {
|
|
@@ -1786,7 +1781,10 @@ async function queryPostgres(config, credentials, sql, options = {}) {
|
|
|
1786
1781
|
try {
|
|
1787
1782
|
await client.connect();
|
|
1788
1783
|
const schema = options.schema || config.schema;
|
|
1789
|
-
if (schema)
|
|
1784
|
+
if (schema) {
|
|
1785
|
+
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(schema)) throw new Error("Invalid schema name");
|
|
1786
|
+
await client.query(`SET search_path TO "${schema}"`);
|
|
1787
|
+
}
|
|
1790
1788
|
const result = await client.query(sql);
|
|
1791
1789
|
await client.end();
|
|
1792
1790
|
const columns = result.fields?.map((f) => f.name) || [];
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# dashboards.components
|
|
2
|
+
|
|
3
|
+
> Chart and display components for rendering query results in dashboards.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Components are self-closing HTML-style tags that render query results as charts, tables, or KPI cards. Each component takes a `data` prop referencing a named query.
|
|
8
|
+
|
|
9
|
+
## Syntax
|
|
10
|
+
|
|
11
|
+
```markdown
|
|
12
|
+
<ComponentName data={query_name} prop="value" />
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
- Components are self-closing (`/>`)
|
|
16
|
+
- `data` uses curly braces: `data={query_name}`
|
|
17
|
+
- Other props use quotes: `x="field_name"`
|
|
18
|
+
- Boolean props can be shorthand: `horizontal`
|
|
19
|
+
|
|
20
|
+
## Component Reference
|
|
21
|
+
|
|
22
|
+
### BigValue
|
|
23
|
+
|
|
24
|
+
Displays a single KPI metric as a large number.
|
|
25
|
+
|
|
26
|
+
```markdown
|
|
27
|
+
<BigValue data={total_revenue} value="total_revenue" title="Revenue" />
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
| Prop | Type | Required | Description |
|
|
31
|
+
|------|------|----------|-------------|
|
|
32
|
+
| `data` | query ref | Yes | Query name (should return a single row) |
|
|
33
|
+
| `value` | string | Yes | Measure field name to display |
|
|
34
|
+
| `title` | string | No | Label above the value |
|
|
35
|
+
|
|
36
|
+
### LineChart
|
|
37
|
+
|
|
38
|
+
Renders a line chart, typically for time series.
|
|
39
|
+
|
|
40
|
+
```markdown
|
|
41
|
+
<LineChart data={monthly_revenue} x="created_at" y="total_revenue" title="Revenue Trend" />
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
| Prop | Type | Required | Description |
|
|
45
|
+
|------|------|----------|-------------|
|
|
46
|
+
| `data` | query ref | Yes | Query name |
|
|
47
|
+
| `x` | string | Yes | Field for x-axis (typically a time dimension) |
|
|
48
|
+
| `y` | string | Yes | Field for y-axis (typically a measure) |
|
|
49
|
+
| `title` | string | No | Chart title |
|
|
50
|
+
|
|
51
|
+
### BarChart
|
|
52
|
+
|
|
53
|
+
Renders a vertical bar chart. Add `horizontal` for horizontal bars.
|
|
54
|
+
|
|
55
|
+
```markdown
|
|
56
|
+
<BarChart data={revenue_by_city} x="city" y="total_revenue" />
|
|
57
|
+
<BarChart data={revenue_by_city} x="city" y="total_revenue" horizontal />
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
| Prop | Type | Required | Description |
|
|
61
|
+
|------|------|----------|-------------|
|
|
62
|
+
| `data` | query ref | Yes | Query name |
|
|
63
|
+
| `x` | string | Yes | Field for category axis |
|
|
64
|
+
| `y` | string | Yes | Field for value axis |
|
|
65
|
+
| `title` | string | No | Chart title |
|
|
66
|
+
| `horizontal` | boolean | No | Render as horizontal bar chart |
|
|
67
|
+
|
|
68
|
+
### AreaChart
|
|
69
|
+
|
|
70
|
+
Renders a filled area chart.
|
|
71
|
+
|
|
72
|
+
```markdown
|
|
73
|
+
<AreaChart data={monthly_revenue} x="created_at" y="total_revenue" />
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
| Prop | Type | Required | Description |
|
|
77
|
+
|------|------|----------|-------------|
|
|
78
|
+
| `data` | query ref | Yes | Query name |
|
|
79
|
+
| `x` | string | Yes | Field for x-axis |
|
|
80
|
+
| `y` | string | Yes | Field for y-axis |
|
|
81
|
+
| `title` | string | No | Chart title |
|
|
82
|
+
|
|
83
|
+
### PieChart
|
|
84
|
+
|
|
85
|
+
Renders a pie/donut chart.
|
|
86
|
+
|
|
87
|
+
```markdown
|
|
88
|
+
<PieChart data={by_status} name="status" value="count" title="Order Status" />
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
| Prop | Type | Required | Description |
|
|
92
|
+
|------|------|----------|-------------|
|
|
93
|
+
| `data` | query ref | Yes | Query name |
|
|
94
|
+
| `name` | string | Yes | Field for slice labels |
|
|
95
|
+
| `value` | string | Yes | Field for slice values |
|
|
96
|
+
| `title` | string | No | Chart title |
|
|
97
|
+
|
|
98
|
+
### DataTable
|
|
99
|
+
|
|
100
|
+
Renders query results as a table.
|
|
101
|
+
|
|
102
|
+
```markdown
|
|
103
|
+
<DataTable data={top_products} />
|
|
104
|
+
<DataTable data={top_products} columns="name,revenue,count" />
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
| Prop | Type | Required | Description |
|
|
108
|
+
|------|------|----------|-------------|
|
|
109
|
+
| `data` | query ref | Yes | Query name |
|
|
110
|
+
| `columns` | string | No | Comma-separated list of columns to show (default: all) |
|
|
111
|
+
| `title` | string | No | Table title |
|
|
112
|
+
|
|
113
|
+
## Layout: Grid
|
|
114
|
+
|
|
115
|
+
Wrap components in a `<Grid>` tag to arrange them in columns:
|
|
116
|
+
|
|
117
|
+
```markdown
|
|
118
|
+
<Grid cols="3">
|
|
119
|
+
<BigValue data={total_orders} value="count" title="Orders" />
|
|
120
|
+
<BigValue data={total_revenue} value="total_revenue" title="Revenue" />
|
|
121
|
+
<BigValue data={avg_order} value="avg_order_value" title="Avg Order" />
|
|
122
|
+
</Grid>
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
| Prop | Type | Default | Description |
|
|
126
|
+
|------|------|---------|-------------|
|
|
127
|
+
| `cols` | string | `"2"` | Number of columns in the grid |
|
|
128
|
+
|
|
129
|
+
## Field Names
|
|
130
|
+
|
|
131
|
+
Component field names (e.g. `x="city"`, `value="total_revenue"`) use the **unqualified** measure or dimension name — the same names defined in your cube. For example, if your cube has `measures: [{ name: total_revenue, ... }]`, use `value="total_revenue"`.
|
|
132
|
+
|
|
133
|
+
## See Also
|
|
134
|
+
|
|
135
|
+
- dashboards.queries
|
|
136
|
+
- dashboards.examples
|
|
137
|
+
- dashboards
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# dashboards.examples
|
|
2
|
+
|
|
3
|
+
> Complete dashboard examples showing common patterns.
|
|
4
|
+
|
|
5
|
+
## Revenue Overview Dashboard
|
|
6
|
+
|
|
7
|
+
A KPI + trend + breakdown dashboard:
|
|
8
|
+
|
|
9
|
+
```markdown
|
|
10
|
+
---
|
|
11
|
+
title: Revenue Overview
|
|
12
|
+
description: Monthly revenue trends and breakdowns
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Revenue Overview
|
|
16
|
+
|
|
17
|
+
` ``query total_revenue
|
|
18
|
+
cube: orders
|
|
19
|
+
measures: [total_revenue]
|
|
20
|
+
` ``
|
|
21
|
+
|
|
22
|
+
` ``query order_count
|
|
23
|
+
cube: orders
|
|
24
|
+
measures: [count]
|
|
25
|
+
` ``
|
|
26
|
+
|
|
27
|
+
` ``query avg_order
|
|
28
|
+
cube: orders
|
|
29
|
+
measures: [avg_order_value]
|
|
30
|
+
` ``
|
|
31
|
+
|
|
32
|
+
<Grid cols="3">
|
|
33
|
+
<BigValue data={total_revenue} value="total_revenue" title="Total Revenue" />
|
|
34
|
+
<BigValue data={order_count} value="count" title="Orders" />
|
|
35
|
+
<BigValue data={avg_order} value="avg_order_value" title="Avg Order" />
|
|
36
|
+
</Grid>
|
|
37
|
+
|
|
38
|
+
## Monthly Trend
|
|
39
|
+
|
|
40
|
+
` ``query monthly_revenue
|
|
41
|
+
cube: orders
|
|
42
|
+
measures: [total_revenue]
|
|
43
|
+
timeDimension:
|
|
44
|
+
dimension: created_at
|
|
45
|
+
granularity: month
|
|
46
|
+
dateRange: [2025-01-01, 2025-12-31]
|
|
47
|
+
` ``
|
|
48
|
+
|
|
49
|
+
<LineChart data={monthly_revenue} x="created_at" y="total_revenue" title="Monthly Revenue" />
|
|
50
|
+
|
|
51
|
+
## By Category
|
|
52
|
+
|
|
53
|
+
` ``query by_category
|
|
54
|
+
cube: orders
|
|
55
|
+
measures: [total_revenue, count]
|
|
56
|
+
dimensions: [category]
|
|
57
|
+
orderBy:
|
|
58
|
+
total_revenue: desc
|
|
59
|
+
` ``
|
|
60
|
+
|
|
61
|
+
<BarChart data={by_category} x="category" y="total_revenue" title="Revenue by Category" />
|
|
62
|
+
<DataTable data={by_category} />
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Sales Pipeline Dashboard
|
|
66
|
+
|
|
67
|
+
Filtered data with pie chart:
|
|
68
|
+
|
|
69
|
+
```markdown
|
|
70
|
+
---
|
|
71
|
+
title: Sales Pipeline
|
|
72
|
+
description: Order status breakdown and city analysis
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
# Sales Pipeline
|
|
76
|
+
|
|
77
|
+
` ``query by_status
|
|
78
|
+
cube: orders
|
|
79
|
+
measures: [count]
|
|
80
|
+
dimensions: [status]
|
|
81
|
+
` ``
|
|
82
|
+
|
|
83
|
+
<PieChart data={by_status} name="status" value="count" title="Order Status" />
|
|
84
|
+
|
|
85
|
+
## Top Cities
|
|
86
|
+
|
|
87
|
+
` ``query top_cities
|
|
88
|
+
cube: orders
|
|
89
|
+
measures: [total_revenue, count]
|
|
90
|
+
dimensions: [city]
|
|
91
|
+
orderBy:
|
|
92
|
+
total_revenue: desc
|
|
93
|
+
limit: 10
|
|
94
|
+
` ``
|
|
95
|
+
|
|
96
|
+
<BarChart data={top_cities} x="city" y="total_revenue" horizontal />
|
|
97
|
+
<DataTable data={top_cities} />
|
|
98
|
+
|
|
99
|
+
## Completed Orders Over Time
|
|
100
|
+
|
|
101
|
+
` ``query completed_trend
|
|
102
|
+
cube: orders
|
|
103
|
+
measures: [total_revenue]
|
|
104
|
+
timeDimension:
|
|
105
|
+
dimension: created_at
|
|
106
|
+
granularity: week
|
|
107
|
+
dateRange: [2025-01-01, 2025-06-30]
|
|
108
|
+
filters:
|
|
109
|
+
- dimension: status
|
|
110
|
+
operator: equals
|
|
111
|
+
values: [completed]
|
|
112
|
+
` ``
|
|
113
|
+
|
|
114
|
+
<AreaChart data={completed_trend} x="created_at" y="total_revenue" title="Completed Order Revenue" />
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Tips
|
|
118
|
+
|
|
119
|
+
- **Start with KPIs**: Use `BigValue` in a `Grid` at the top for key metrics
|
|
120
|
+
- **One query per chart**: Each component gets its own query — keep them focused
|
|
121
|
+
- **Use views**: Prefer view names over cube names when available for cleaner field names
|
|
122
|
+
- **Name queries descriptively**: `monthly_revenue` is better than `q1`
|
|
123
|
+
- **Limit large datasets**: Add `limit` to dimension queries to avoid oversized charts
|
|
124
|
+
- **Time series**: Always use `timeDimension` with `granularity` for time-based charts
|
|
125
|
+
|
|
126
|
+
## See Also
|
|
127
|
+
|
|
128
|
+
- dashboards
|
|
129
|
+
- dashboards.queries
|
|
130
|
+
- dashboards.components
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# dashboards
|
|
2
|
+
|
|
3
|
+
> Build interactive dashboards from markdown with embedded semantic layer queries.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Dashboards are markdown files with YAML frontmatter, query blocks, and chart components. Write them as `.md` files, deploy with `bon dashboard deploy`, and view them in the Bonnard web app.
|
|
8
|
+
|
|
9
|
+
## Format
|
|
10
|
+
|
|
11
|
+
A dashboard file has three parts:
|
|
12
|
+
|
|
13
|
+
1. **Frontmatter** — YAML metadata between `---` delimiters
|
|
14
|
+
2. **Query blocks** — Named data queries in ` ```query ` code fences
|
|
15
|
+
3. **Content** — Markdown text and chart component tags
|
|
16
|
+
|
|
17
|
+
## Minimal Example
|
|
18
|
+
|
|
19
|
+
```markdown
|
|
20
|
+
---
|
|
21
|
+
title: Order Summary
|
|
22
|
+
description: Key metrics for the orders pipeline
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
# Order Summary
|
|
26
|
+
|
|
27
|
+
` ``query order_count
|
|
28
|
+
cube: orders
|
|
29
|
+
measures: [count]
|
|
30
|
+
` ``
|
|
31
|
+
|
|
32
|
+
<BigValue data={order_count} value="count" title="Total Orders" />
|
|
33
|
+
|
|
34
|
+
` ``query by_status
|
|
35
|
+
cube: orders
|
|
36
|
+
measures: [count]
|
|
37
|
+
dimensions: [status]
|
|
38
|
+
` ``
|
|
39
|
+
|
|
40
|
+
<BarChart data={by_status} x="status" y="count" />
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Frontmatter
|
|
44
|
+
|
|
45
|
+
The YAML frontmatter is required and must include `title`:
|
|
46
|
+
|
|
47
|
+
```yaml
|
|
48
|
+
---
|
|
49
|
+
title: Revenue Dashboard # Required
|
|
50
|
+
description: Monthly trends # Optional
|
|
51
|
+
slug: revenue-dashboard # Optional (derived from title if omitted)
|
|
52
|
+
---
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
| Field | Required | Description |
|
|
56
|
+
|-------|----------|-------------|
|
|
57
|
+
| `title` | Yes | Dashboard title displayed in the viewer and listings |
|
|
58
|
+
| `description` | No | Short description shown in dashboard listings |
|
|
59
|
+
| `slug` | No | URL-safe identifier. Auto-derived from title if omitted |
|
|
60
|
+
|
|
61
|
+
## Deployment
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# Deploy a single dashboard
|
|
65
|
+
bon dashboard deploy revenue.md
|
|
66
|
+
|
|
67
|
+
# Deploy all dashboards in a directory
|
|
68
|
+
bon dashboard deploy dashboards/
|
|
69
|
+
|
|
70
|
+
# List deployed dashboards
|
|
71
|
+
bon dashboard list
|
|
72
|
+
|
|
73
|
+
# Remove a dashboard
|
|
74
|
+
bon dashboard remove revenue-dashboard
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Via MCP tools, agents can use `deploy_dashboard` with the markdown content as a string.
|
|
78
|
+
|
|
79
|
+
## See Also
|
|
80
|
+
|
|
81
|
+
- dashboards.queries
|
|
82
|
+
- dashboards.components
|
|
83
|
+
- dashboards.examples
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# dashboards.queries
|
|
2
|
+
|
|
3
|
+
> Define data queries in dashboard markdown using YAML code fences.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Query blocks fetch data from the semantic layer. Each query has a unique name and maps to a `QueryOptions` shape. Query results are referenced by chart components using `data={query_name}`.
|
|
8
|
+
|
|
9
|
+
## Syntax
|
|
10
|
+
|
|
11
|
+
Query blocks use fenced code with the `query` language tag followed by a name:
|
|
12
|
+
|
|
13
|
+
````markdown
|
|
14
|
+
```query revenue_trend
|
|
15
|
+
cube: orders
|
|
16
|
+
measures: [total_revenue]
|
|
17
|
+
timeDimension:
|
|
18
|
+
dimension: created_at
|
|
19
|
+
granularity: month
|
|
20
|
+
dateRange: [2025-01-01, 2025-12-31]
|
|
21
|
+
```
|
|
22
|
+
````
|
|
23
|
+
|
|
24
|
+
## Query Properties
|
|
25
|
+
|
|
26
|
+
| Property | Type | Required | Description |
|
|
27
|
+
|----------|------|----------|-------------|
|
|
28
|
+
| `cube` | string | Yes | The cube or view to query (e.g. `orders`) |
|
|
29
|
+
| `measures` | string[] | No | Measures to aggregate (e.g. `[count, total_revenue]`) |
|
|
30
|
+
| `dimensions` | string[] | No | Dimensions to group by (e.g. `[status, city]`) |
|
|
31
|
+
| `filters` | Filter[] | No | Row-level filters |
|
|
32
|
+
| `timeDimension` | object | No | Time-based grouping and date range |
|
|
33
|
+
| `orderBy` | object | No | Sort specification (e.g. `{total_revenue: desc}`) |
|
|
34
|
+
| `limit` | number | No | Maximum rows to return |
|
|
35
|
+
|
|
36
|
+
### timeDimension
|
|
37
|
+
|
|
38
|
+
| Property | Type | Required | Description |
|
|
39
|
+
|----------|------|----------|-------------|
|
|
40
|
+
| `dimension` | string | Yes | Time dimension name (e.g. `created_at`) |
|
|
41
|
+
| `granularity` | string | No | `day`, `week`, `month`, `quarter`, or `year` |
|
|
42
|
+
| `dateRange` | string[] | No | `[start, end]` in `YYYY-MM-DD` format |
|
|
43
|
+
|
|
44
|
+
### filters
|
|
45
|
+
|
|
46
|
+
Each filter is an object with:
|
|
47
|
+
|
|
48
|
+
| Property | Type | Description |
|
|
49
|
+
|----------|------|-------------|
|
|
50
|
+
| `dimension` | string | Dimension to filter on |
|
|
51
|
+
| `operator` | string | `equals`, `notEquals`, `contains`, `gt`, `gte`, `lt`, `lte` |
|
|
52
|
+
| `values` | array | Values to filter by |
|
|
53
|
+
|
|
54
|
+
## Examples
|
|
55
|
+
|
|
56
|
+
### Simple aggregation
|
|
57
|
+
|
|
58
|
+
````markdown
|
|
59
|
+
```query total_orders
|
|
60
|
+
cube: orders
|
|
61
|
+
measures: [count]
|
|
62
|
+
```
|
|
63
|
+
````
|
|
64
|
+
|
|
65
|
+
### Grouped by dimension
|
|
66
|
+
|
|
67
|
+
````markdown
|
|
68
|
+
```query revenue_by_city
|
|
69
|
+
cube: orders
|
|
70
|
+
measures: [total_revenue]
|
|
71
|
+
dimensions: [city]
|
|
72
|
+
orderBy:
|
|
73
|
+
total_revenue: desc
|
|
74
|
+
limit: 10
|
|
75
|
+
```
|
|
76
|
+
````
|
|
77
|
+
|
|
78
|
+
### Time series
|
|
79
|
+
|
|
80
|
+
````markdown
|
|
81
|
+
```query monthly_revenue
|
|
82
|
+
cube: orders
|
|
83
|
+
measures: [total_revenue]
|
|
84
|
+
timeDimension:
|
|
85
|
+
dimension: created_at
|
|
86
|
+
granularity: month
|
|
87
|
+
dateRange: [2025-01-01, 2025-12-31]
|
|
88
|
+
```
|
|
89
|
+
````
|
|
90
|
+
|
|
91
|
+
### With filters
|
|
92
|
+
|
|
93
|
+
````markdown
|
|
94
|
+
```query completed_orders
|
|
95
|
+
cube: orders
|
|
96
|
+
measures: [count, total_revenue]
|
|
97
|
+
dimensions: [category]
|
|
98
|
+
filters:
|
|
99
|
+
- dimension: status
|
|
100
|
+
operator: equals
|
|
101
|
+
values: [completed]
|
|
102
|
+
```
|
|
103
|
+
````
|
|
104
|
+
|
|
105
|
+
## Rules
|
|
106
|
+
|
|
107
|
+
- Query names must be valid identifiers (letters, numbers, `_`, `$`)
|
|
108
|
+
- Query names must be unique within a dashboard
|
|
109
|
+
- Every query must specify a `cube`
|
|
110
|
+
- Field names are unqualified (use `count` not `orders.count`) — the `cube` provides the context
|
|
111
|
+
- Components reference queries by name: `data={query_name}`
|
|
112
|
+
|
|
113
|
+
## See Also
|
|
114
|
+
|
|
115
|
+
- dashboards.components
|
|
116
|
+
- dashboards
|
|
117
|
+
- workflow.query
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bonnard-get-started
|
|
3
|
+
description: Guide a user through setting up their first semantic layer after bon init. Use when user says "get started", "what next", "help me set up", or has just run bon init.
|
|
4
|
+
allowed-tools: Bash(bon *)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Get Started with Bonnard
|
|
8
|
+
|
|
9
|
+
This skill guides you through building and deploying a semantic layer.
|
|
10
|
+
The user has already run `bon init`. Walk through each phase in order,
|
|
11
|
+
confirming progress before moving on.
|
|
12
|
+
|
|
13
|
+
## Phase 1: Connect a Data Source
|
|
14
|
+
|
|
15
|
+
Check if the user has dbt:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Import from dbt (if they use it)
|
|
19
|
+
bon datasource add --from-dbt
|
|
20
|
+
|
|
21
|
+
# Or add manually (interactive)
|
|
22
|
+
bon datasource add
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Then verify the connection works:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
bon datasource test <name>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
If the test fails, common issues:
|
|
32
|
+
- Wrong credentials — re-run `bon datasource add`
|
|
33
|
+
- Network/firewall — check warehouse allows connections from this machine
|
|
34
|
+
- SSL issues (Postgres) — may need `sslmode` in connection config
|
|
35
|
+
|
|
36
|
+
## Phase 2: Explore the Data
|
|
37
|
+
|
|
38
|
+
Use `bon preview` to understand what tables and columns are available:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# List tables (Postgres)
|
|
42
|
+
bon preview <datasource> "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'"
|
|
43
|
+
|
|
44
|
+
# List tables (Snowflake)
|
|
45
|
+
bon preview <datasource> "SHOW TABLES"
|
|
46
|
+
|
|
47
|
+
# Sample a table
|
|
48
|
+
bon preview <datasource> "SELECT * FROM orders" --limit 10
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
This helps you understand the schema before writing cubes.
|
|
52
|
+
|
|
53
|
+
## Phase 3: Create Your First Cube
|
|
54
|
+
|
|
55
|
+
Create a file in `bonnard/cubes/` for the most important table. A cube
|
|
56
|
+
typically maps directly to a database table — define measures for the metrics
|
|
57
|
+
you want to track and dimensions for the attributes you want to filter and
|
|
58
|
+
group by.
|
|
59
|
+
|
|
60
|
+
Example — `bonnard/cubes/orders.yaml`:
|
|
61
|
+
|
|
62
|
+
```yaml
|
|
63
|
+
cubes:
|
|
64
|
+
- name: orders
|
|
65
|
+
sql_table: public.orders
|
|
66
|
+
|
|
67
|
+
measures:
|
|
68
|
+
- name: count
|
|
69
|
+
type: count
|
|
70
|
+
description: Total number of orders
|
|
71
|
+
|
|
72
|
+
- name: total_revenue
|
|
73
|
+
type: sum
|
|
74
|
+
sql: amount
|
|
75
|
+
description: Sum of order amounts
|
|
76
|
+
|
|
77
|
+
dimensions:
|
|
78
|
+
- name: id
|
|
79
|
+
type: number
|
|
80
|
+
sql: id
|
|
81
|
+
primary_key: true
|
|
82
|
+
|
|
83
|
+
- name: status
|
|
84
|
+
type: string
|
|
85
|
+
sql: status
|
|
86
|
+
description: Order status (pending, completed, cancelled)
|
|
87
|
+
|
|
88
|
+
- name: created_at
|
|
89
|
+
type: time
|
|
90
|
+
sql: created_at
|
|
91
|
+
description: When the order was placed
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Key rules:
|
|
95
|
+
- Every cube needs a `primary_key` dimension
|
|
96
|
+
- Every measure and dimension should have a `description`
|
|
97
|
+
- Use `sql_table` for simple table references, `sql` for complex queries
|
|
98
|
+
|
|
99
|
+
Use `bon docs cubes` for the full reference, `bon docs cubes.measures.types`
|
|
100
|
+
for all 12 measure types, `bon docs cubes.dimensions.types` for dimension types.
|
|
101
|
+
|
|
102
|
+
## Phase 4: Create a View
|
|
103
|
+
|
|
104
|
+
Views expose a curated subset of measures and dimensions for consumers.
|
|
105
|
+
Create a file in `bonnard/views/`:
|
|
106
|
+
|
|
107
|
+
Example — `bonnard/views/orders_overview.yaml`:
|
|
108
|
+
|
|
109
|
+
```yaml
|
|
110
|
+
views:
|
|
111
|
+
- name: orders_overview
|
|
112
|
+
description: High-level order metrics and attributes
|
|
113
|
+
cubes:
|
|
114
|
+
- join_path: orders
|
|
115
|
+
includes:
|
|
116
|
+
- count
|
|
117
|
+
- total_revenue
|
|
118
|
+
- status
|
|
119
|
+
- created_at
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Use `bon docs views` for the full reference.
|
|
123
|
+
|
|
124
|
+
## Phase 5: Validate
|
|
125
|
+
|
|
126
|
+
Check for errors:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
bon validate
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Fix any errors before proceeding. Common issues:
|
|
133
|
+
- Missing required fields (`name`, `type`, `sql`)
|
|
134
|
+
- Unknown measure/dimension types (e.g., `text` should be `string`)
|
|
135
|
+
- Bad YAML indentation
|
|
136
|
+
|
|
137
|
+
Optionally test the datasource connection too:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
bon validate --test-connection
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Phase 6: Deploy
|
|
144
|
+
|
|
145
|
+
Log in (if not already) and deploy:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
bon login
|
|
149
|
+
bon deploy
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Deploy validates, tests connections, uploads cubes/views, and syncs datasource
|
|
153
|
+
credentials (encrypted) to Bonnard.
|
|
154
|
+
|
|
155
|
+
## Phase 7: Test with a Query
|
|
156
|
+
|
|
157
|
+
Verify the deployment works:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
# Simple count
|
|
161
|
+
bon query '{"measures": ["orders.count"]}'
|
|
162
|
+
|
|
163
|
+
# Group by a dimension
|
|
164
|
+
bon query '{"measures": ["orders.count"], "dimensions": ["orders.status"]}'
|
|
165
|
+
|
|
166
|
+
# SQL format
|
|
167
|
+
bon query --sql "SELECT status, MEASURE(count) FROM orders GROUP BY 1"
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Phase 8: Connect AI Agents (Optional)
|
|
171
|
+
|
|
172
|
+
Set up MCP so AI agents can query the semantic layer:
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
bon mcp
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
This shows setup instructions for Claude Desktop, ChatGPT, Cursor, VS Code,
|
|
179
|
+
and other MCP clients. The MCP URL is `https://mcp.bonnard.dev/mcp`.
|
|
180
|
+
|
|
181
|
+
## Next Steps
|
|
182
|
+
|
|
183
|
+
After the first cube is working:
|
|
184
|
+
|
|
185
|
+
- Add more cubes for other tables
|
|
186
|
+
- Add joins between cubes (`bon docs cubes.joins`)
|
|
187
|
+
- Add calculated measures (`bon docs cubes.measures.calculated`)
|
|
188
|
+
- Add segments for common filters (`bon docs cubes.segments`)
|
|
189
|
+
- Build dashboards (`bon docs dashboards`)
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Guide a user through setting up their first semantic layer after bon init. Use when user says 'get started', 'what next', 'help me set up', or has just run bon init."
|
|
3
|
+
alwaysApply: false
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Get Started with Bonnard
|
|
7
|
+
|
|
8
|
+
This skill guides you through building and deploying a semantic layer.
|
|
9
|
+
The user has already run `bon init`. Walk through each phase in order,
|
|
10
|
+
confirming progress before moving on.
|
|
11
|
+
|
|
12
|
+
## Phase 1: Connect a Data Source
|
|
13
|
+
|
|
14
|
+
Check if the user has dbt:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# Import from dbt (if they use it)
|
|
18
|
+
bon datasource add --from-dbt
|
|
19
|
+
|
|
20
|
+
# Or add manually (interactive)
|
|
21
|
+
bon datasource add
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Then verify the connection works:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
bon datasource test <name>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
If the test fails, common issues:
|
|
31
|
+
- Wrong credentials — re-run `bon datasource add`
|
|
32
|
+
- Network/firewall — check warehouse allows connections from this machine
|
|
33
|
+
- SSL issues (Postgres) — may need `sslmode` in connection config
|
|
34
|
+
|
|
35
|
+
## Phase 2: Explore the Data
|
|
36
|
+
|
|
37
|
+
Use `bon preview` to understand what tables and columns are available:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# List tables (Postgres)
|
|
41
|
+
bon preview <datasource> "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'"
|
|
42
|
+
|
|
43
|
+
# List tables (Snowflake)
|
|
44
|
+
bon preview <datasource> "SHOW TABLES"
|
|
45
|
+
|
|
46
|
+
# Sample a table
|
|
47
|
+
bon preview <datasource> "SELECT * FROM orders" --limit 10
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
This helps you understand the schema before writing cubes.
|
|
51
|
+
|
|
52
|
+
## Phase 3: Create Your First Cube
|
|
53
|
+
|
|
54
|
+
Create a file in `bonnard/cubes/` for the most important table. A cube
|
|
55
|
+
typically maps directly to a database table — define measures for the metrics
|
|
56
|
+
you want to track and dimensions for the attributes you want to filter and
|
|
57
|
+
group by.
|
|
58
|
+
|
|
59
|
+
Example — `bonnard/cubes/orders.yaml`:
|
|
60
|
+
|
|
61
|
+
```yaml
|
|
62
|
+
cubes:
|
|
63
|
+
- name: orders
|
|
64
|
+
sql_table: public.orders
|
|
65
|
+
|
|
66
|
+
measures:
|
|
67
|
+
- name: count
|
|
68
|
+
type: count
|
|
69
|
+
description: Total number of orders
|
|
70
|
+
|
|
71
|
+
- name: total_revenue
|
|
72
|
+
type: sum
|
|
73
|
+
sql: amount
|
|
74
|
+
description: Sum of order amounts
|
|
75
|
+
|
|
76
|
+
dimensions:
|
|
77
|
+
- name: id
|
|
78
|
+
type: number
|
|
79
|
+
sql: id
|
|
80
|
+
primary_key: true
|
|
81
|
+
|
|
82
|
+
- name: status
|
|
83
|
+
type: string
|
|
84
|
+
sql: status
|
|
85
|
+
description: Order status (pending, completed, cancelled)
|
|
86
|
+
|
|
87
|
+
- name: created_at
|
|
88
|
+
type: time
|
|
89
|
+
sql: created_at
|
|
90
|
+
description: When the order was placed
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Key rules:
|
|
94
|
+
- Every cube needs a `primary_key` dimension
|
|
95
|
+
- Every measure and dimension should have a `description`
|
|
96
|
+
- Use `sql_table` for simple table references, `sql` for complex queries
|
|
97
|
+
|
|
98
|
+
Use `bon docs cubes` for the full reference, `bon docs cubes.measures.types`
|
|
99
|
+
for all 12 measure types, `bon docs cubes.dimensions.types` for dimension types.
|
|
100
|
+
|
|
101
|
+
## Phase 4: Create a View
|
|
102
|
+
|
|
103
|
+
Views expose a curated subset of measures and dimensions for consumers.
|
|
104
|
+
Create a file in `bonnard/views/`:
|
|
105
|
+
|
|
106
|
+
Example — `bonnard/views/orders_overview.yaml`:
|
|
107
|
+
|
|
108
|
+
```yaml
|
|
109
|
+
views:
|
|
110
|
+
- name: orders_overview
|
|
111
|
+
description: High-level order metrics and attributes
|
|
112
|
+
cubes:
|
|
113
|
+
- join_path: orders
|
|
114
|
+
includes:
|
|
115
|
+
- count
|
|
116
|
+
- total_revenue
|
|
117
|
+
- status
|
|
118
|
+
- created_at
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Use `bon docs views` for the full reference.
|
|
122
|
+
|
|
123
|
+
## Phase 5: Validate
|
|
124
|
+
|
|
125
|
+
Check for errors:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
bon validate
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Fix any errors before proceeding. Common issues:
|
|
132
|
+
- Missing required fields (`name`, `type`, `sql`)
|
|
133
|
+
- Unknown measure/dimension types (e.g., `text` should be `string`)
|
|
134
|
+
- Bad YAML indentation
|
|
135
|
+
|
|
136
|
+
Optionally test the datasource connection too:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
bon validate --test-connection
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Phase 6: Deploy
|
|
143
|
+
|
|
144
|
+
Log in (if not already) and deploy:
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
bon login
|
|
148
|
+
bon deploy
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Deploy validates, tests connections, uploads cubes/views, and syncs datasource
|
|
152
|
+
credentials (encrypted) to Bonnard.
|
|
153
|
+
|
|
154
|
+
## Phase 7: Test with a Query
|
|
155
|
+
|
|
156
|
+
Verify the deployment works:
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
# Simple count
|
|
160
|
+
bon query '{"measures": ["orders.count"]}'
|
|
161
|
+
|
|
162
|
+
# Group by a dimension
|
|
163
|
+
bon query '{"measures": ["orders.count"], "dimensions": ["orders.status"]}'
|
|
164
|
+
|
|
165
|
+
# SQL format
|
|
166
|
+
bon query --sql "SELECT status, MEASURE(count) FROM orders GROUP BY 1"
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Phase 8: Connect AI Agents (Optional)
|
|
170
|
+
|
|
171
|
+
Set up MCP so AI agents can query the semantic layer:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
bon mcp
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
This shows setup instructions for Claude Desktop, ChatGPT, Cursor, VS Code,
|
|
178
|
+
and other MCP clients. The MCP URL is `https://mcp.bonnard.dev/mcp`.
|
|
179
|
+
|
|
180
|
+
## Next Steps
|
|
181
|
+
|
|
182
|
+
After the first cube is working:
|
|
183
|
+
|
|
184
|
+
- Add more cubes for other tables
|
|
185
|
+
- Add joins between cubes (`bon docs cubes.joins`)
|
|
186
|
+
- Add calculated measures (`bon docs cubes.measures.calculated`)
|
|
187
|
+
- Add segments for common filters (`bon docs cubes.segments`)
|
|
188
|
+
- Build dashboards (`bon docs dashboards`)
|
|
@@ -78,5 +78,4 @@ Topics follow dot notation (e.g., `cubes.dimensions.time`). Use `--recursive` to
|
|
|
78
78
|
4. **Validate** — `bon validate --test-connection`
|
|
79
79
|
5. **Deploy** — `bon login` then `bon deploy`
|
|
80
80
|
|
|
81
|
-
For
|
|
82
|
-
For YAML patterns: `/bonnard-queries`
|
|
81
|
+
For a guided walkthrough: `/bonnard-get-started`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bonnard/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"bon": "./dist/bin/bon.mjs"
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"dist"
|
|
10
10
|
],
|
|
11
11
|
"scripts": {
|
|
12
|
-
"build": "tsdown src/bin/bon.ts --format esm --out-dir dist/bin && cp -r src/templates dist/ && mkdir -p dist/docs/topics dist/docs/schemas && cp ../content/index.md dist/docs/_index.md && cp ../content/modeling/*.md dist/docs/topics/",
|
|
12
|
+
"build": "tsdown src/bin/bon.ts --format esm --out-dir dist/bin && cp -r src/templates dist/ && mkdir -p dist/docs/topics dist/docs/schemas && cp ../content/index.md dist/docs/_index.md && cp ../content/modeling/*.md dist/docs/topics/ && cp ../content/dashboards/*.md dist/docs/topics/",
|
|
13
13
|
"dev": "tsdown src/bin/bon.ts --format esm --out-dir dist/bin --watch",
|
|
14
14
|
"test": "vitest run"
|
|
15
15
|
},
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: bonnard-cli
|
|
3
|
-
description: Bonnard CLI reference. Use when user needs help with bon commands, data sources, or deployments.
|
|
4
|
-
allowed-tools: Bash(bon *)
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Bonnard CLI
|
|
8
|
-
|
|
9
|
-
## Commands
|
|
10
|
-
|
|
11
|
-
### Project Setup
|
|
12
|
-
```bash
|
|
13
|
-
bon init # Initialize new project
|
|
14
|
-
bon login # Authenticate with Bonnard
|
|
15
|
-
bon logout # Clear credentials
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
### Data Sources
|
|
19
|
-
```bash
|
|
20
|
-
bon datasource add # Add new data source (interactive)
|
|
21
|
-
bon datasource list # List all data sources
|
|
22
|
-
bon datasource test <name> # Test connection
|
|
23
|
-
bon datasource remove <name> # Remove data source
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
### Development
|
|
27
|
-
```bash
|
|
28
|
-
bon validate # Validate cubes and views
|
|
29
|
-
bon deploy # Deploy to Bonnard
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
### Data Exploration (Local)
|
|
33
|
-
```bash
|
|
34
|
-
bon preview <datasource> "<sql>" # Preview data with raw SQL
|
|
35
|
-
bon preview <datasource> "<sql>" --format json # JSON output
|
|
36
|
-
bon preview <datasource> "<sql>" --limit 100 # Limit rows
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
### Semantic Layer Queries (Deployed)
|
|
40
|
-
```bash
|
|
41
|
-
# JSON format (default)
|
|
42
|
-
bon query '{"measures": ["orders.count"]}'
|
|
43
|
-
bon query '{"measures": ["orders.total_revenue"], "dimensions": ["orders.status"]}'
|
|
44
|
-
|
|
45
|
-
# SQL format
|
|
46
|
-
bon query --sql "SELECT status, MEASURE(count) FROM orders GROUP BY 1"
|
|
47
|
-
bon query --sql "SELECT city, SUM(amount) FROM orders GROUP BY 1" --limit 10
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
### Documentation
|
|
51
|
-
```bash
|
|
52
|
-
bon docs # Show all topics
|
|
53
|
-
bon docs <topic> # View topic (e.g., cubes.measures)
|
|
54
|
-
bon docs <topic> --recursive # Topic + all children
|
|
55
|
-
bon docs --search "<query>" # Search all docs
|
|
56
|
-
bon docs <topic> --format json # Structured output
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
**Key topics:** `cubes`, `cubes.measures`, `cubes.dimensions`, `cubes.joins`, `views`, `pre-aggregations`, `syntax`
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: bonnard-queries
|
|
3
|
-
description: How to write queries and work with cubes and views. Use when user asks about metrics, dimensions, or data modeling.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Bonnard Query Patterns
|
|
7
|
-
|
|
8
|
-
## Cube Structure (YAML)
|
|
9
|
-
|
|
10
|
-
```yaml
|
|
11
|
-
cubes:
|
|
12
|
-
- name: orders
|
|
13
|
-
sql: SELECT * FROM public.orders
|
|
14
|
-
|
|
15
|
-
measures:
|
|
16
|
-
- name: count
|
|
17
|
-
type: count
|
|
18
|
-
description: Total number of orders
|
|
19
|
-
|
|
20
|
-
- name: total_amount
|
|
21
|
-
type: sum
|
|
22
|
-
sql: amount
|
|
23
|
-
description: Sum of order amounts in dollars
|
|
24
|
-
|
|
25
|
-
dimensions:
|
|
26
|
-
- name: status
|
|
27
|
-
type: string
|
|
28
|
-
sql: status
|
|
29
|
-
description: Order status (pending, completed, cancelled)
|
|
30
|
-
|
|
31
|
-
- name: created_at
|
|
32
|
-
type: time
|
|
33
|
-
sql: created_at
|
|
34
|
-
description: When the order was placed
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
## View Structure (YAML)
|
|
38
|
-
|
|
39
|
-
```yaml
|
|
40
|
-
views:
|
|
41
|
-
- name: orders_overview
|
|
42
|
-
cubes:
|
|
43
|
-
- join_path: orders
|
|
44
|
-
includes:
|
|
45
|
-
- count
|
|
46
|
-
- total_amount
|
|
47
|
-
- status
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
## Workflow
|
|
51
|
-
|
|
52
|
-
1. Define cubes in `bonnard/cubes/*.yaml`
|
|
53
|
-
2. Define views in `bonnard/views/*.yaml`
|
|
54
|
-
3. Run `bon validate` to check syntax
|
|
55
|
-
4. Run `bon deploy` to publish
|
|
56
|
-
|
|
57
|
-
## Learn More
|
|
58
|
-
|
|
59
|
-
Use `bon docs` for comprehensive documentation:
|
|
60
|
-
|
|
61
|
-
```bash
|
|
62
|
-
bon docs cubes.measures.types # All 12 measure types
|
|
63
|
-
bon docs cubes.dimensions.types # All 6 dimension types
|
|
64
|
-
bon docs cubes.joins # Relationship types
|
|
65
|
-
bon docs cubes.segments # Predefined filters
|
|
66
|
-
bon docs views.cubes # View composition
|
|
67
|
-
bon docs --search "rolling" # Search for concepts
|
|
68
|
-
```
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: "Bonnard CLI reference. Use when user needs help with bon commands, data sources, or deployments."
|
|
3
|
-
alwaysApply: false
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Bonnard CLI
|
|
7
|
-
|
|
8
|
-
## Commands
|
|
9
|
-
|
|
10
|
-
### Project Setup
|
|
11
|
-
```bash
|
|
12
|
-
bon init # Initialize new project
|
|
13
|
-
bon login # Authenticate with Bonnard
|
|
14
|
-
bon logout # Clear credentials
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
### Data Sources
|
|
18
|
-
```bash
|
|
19
|
-
bon datasource add # Add new data source (interactive)
|
|
20
|
-
bon datasource list # List all data sources
|
|
21
|
-
bon datasource test <name> # Test connection
|
|
22
|
-
bon datasource remove <name> # Remove data source
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
### Development
|
|
26
|
-
```bash
|
|
27
|
-
bon validate # Validate cubes and views
|
|
28
|
-
bon deploy # Deploy to Bonnard
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
### Data Exploration (Local)
|
|
32
|
-
```bash
|
|
33
|
-
bon preview <datasource> "<sql>" # Preview data with raw SQL
|
|
34
|
-
bon preview <datasource> "<sql>" --format json # JSON output
|
|
35
|
-
bon preview <datasource> "<sql>" --limit 100 # Limit rows
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
### Semantic Layer Queries (Deployed)
|
|
39
|
-
```bash
|
|
40
|
-
# JSON format (default)
|
|
41
|
-
bon query '{"measures": ["orders.count"]}'
|
|
42
|
-
bon query '{"measures": ["orders.total_revenue"], "dimensions": ["orders.status"]}'
|
|
43
|
-
|
|
44
|
-
# SQL format
|
|
45
|
-
bon query --sql "SELECT status, MEASURE(count) FROM orders GROUP BY 1"
|
|
46
|
-
bon query --sql "SELECT city, SUM(amount) FROM orders GROUP BY 1" --limit 10
|
|
47
|
-
```
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: "How to write queries and work with cubes and views. Use when user asks about metrics, dimensions, or data modeling."
|
|
3
|
-
alwaysApply: false
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Bonnard Query Patterns
|
|
7
|
-
|
|
8
|
-
## Cube Structure (YAML)
|
|
9
|
-
|
|
10
|
-
```yaml
|
|
11
|
-
cubes:
|
|
12
|
-
- name: orders
|
|
13
|
-
sql: SELECT * FROM public.orders
|
|
14
|
-
|
|
15
|
-
measures:
|
|
16
|
-
- name: count
|
|
17
|
-
type: count
|
|
18
|
-
- name: total_amount
|
|
19
|
-
type: sum
|
|
20
|
-
sql: amount
|
|
21
|
-
|
|
22
|
-
dimensions:
|
|
23
|
-
- name: status
|
|
24
|
-
type: string
|
|
25
|
-
sql: status
|
|
26
|
-
- name: created_at
|
|
27
|
-
type: time
|
|
28
|
-
sql: created_at
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
## View Structure (YAML)
|
|
32
|
-
|
|
33
|
-
```yaml
|
|
34
|
-
views:
|
|
35
|
-
- name: orders_overview
|
|
36
|
-
cubes:
|
|
37
|
-
- join_path: orders
|
|
38
|
-
includes:
|
|
39
|
-
- count
|
|
40
|
-
- total_amount
|
|
41
|
-
- status
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
## Workflow
|
|
45
|
-
|
|
46
|
-
1. Define cubes in `bonnard/cubes/*.yaml`
|
|
47
|
-
2. Define views in `bonnard/views/*.yaml`
|
|
48
|
-
3. Run `bon validate` to check syntax
|
|
49
|
-
4. Run `bon deploy` to publish
|