@bonnard/cli 0.2.16 → 0.3.0

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.
@@ -0,0 +1,173 @@
1
+ # Inputs
2
+
3
+ > Interactive filter inputs for dashboards — date range pickers and dropdown selectors.
4
+
5
+ ## Overview
6
+
7
+ Inputs add interactivity to dashboards. They render as a filter bar above the charts and re-execute queries when values change. Inspired by Evidence.dev's inputs pattern, adapted for the Cube semantic layer.
8
+
9
+ Two input types are available:
10
+
11
+ - **DateRange** — preset date range picker that overrides `timeDimension.dateRange`
12
+ - **Dropdown** — dimension value selector that adds/replaces filters
13
+
14
+ ## DateRange
15
+
16
+ Renders a date range preset picker. When changed, overrides `timeDimension.dateRange` on targeted queries.
17
+
18
+ ```markdown
19
+ <DateRange name="period" default="last-6-months" label="Time Period" />
20
+ ```
21
+
22
+ ### Props
23
+
24
+ | Prop | Type | Required | Description |
25
+ |------|------|----------|-------------|
26
+ | `name` | string | Yes | Unique input name |
27
+ | `default` | preset key | No | Initial preset (default: `last-6-months`) |
28
+ | `label` | string | No | Label shown above the picker |
29
+ | `queries` | string | No | Comma-separated query names to target |
30
+
31
+ ### Targeting
32
+
33
+ Targeting lets you control which queries a filter affects — useful when some charts should stay fixed while others respond to filter changes.
34
+
35
+ - **No `queries` prop** — applies to ALL queries that have a `timeDimension`
36
+ - **With `queries` prop** — only applies to the listed queries
37
+
38
+ ### Presets
39
+
40
+ | Key | Label |
41
+ |-----|-------|
42
+ | `last-7-days` | Last 7 Days |
43
+ | `last-30-days` | Last 30 Days |
44
+ | `last-3-months` | Last 3 Months |
45
+ | `last-6-months` | Last 6 Months |
46
+ | `last-12-months` | Last 12 Months |
47
+ | `month-to-date` | Month to Date |
48
+ | `year-to-date` | Year to Date |
49
+ | `last-year` | Last Year |
50
+ | `all-time` | All Time |
51
+
52
+ ## Dropdown
53
+
54
+ Renders a dropdown selector populated from a query's dimension values. Adds a filter on the specified dimension to targeted queries.
55
+
56
+ ```markdown
57
+ <Dropdown name="channel" dimension="orders.channel" data={channels} queries="main,trend" label="Channel" />
58
+ ```
59
+
60
+ ### Props
61
+
62
+ | Prop | Type | Required | Description |
63
+ |------|------|----------|-------------|
64
+ | `name` | string | Yes | Unique input name |
65
+ | `dimension` | string | Yes | Dimension to filter on |
66
+ | `data` | query ref | Yes | Query that provides the dropdown options |
67
+ | `queries` | string | Yes | Comma-separated query names to filter |
68
+ | `label` | string | No | Label shown above the dropdown |
69
+ | `default` | string | No | Initial selected value (default: All) |
70
+
71
+ ### Behavior
72
+
73
+ - Always includes an "All" option that removes the filter
74
+ - The dropdown's own `data` query is never filtered by itself (prevents circular dependencies)
75
+ - `queries` is required — the dropdown only filters explicitly listed queries
76
+
77
+ ## Examples
78
+
79
+ ### DateRange only
80
+
81
+ ```markdown
82
+ ---
83
+ title: Revenue Trends
84
+ ---
85
+
86
+ <DateRange name="period" default="last-6-months" label="Time Period" />
87
+
88
+ ` ``query monthly_revenue
89
+ measures: [orders.total_revenue]
90
+ timeDimension:
91
+ dimension: orders.created_at
92
+ granularity: month
93
+ ` ``
94
+
95
+ <LineChart data={monthly_revenue} x="orders.created_at" y="orders.total_revenue" />
96
+ ```
97
+
98
+ The DateRange automatically applies to `monthly_revenue` because it has a `timeDimension`. No hardcoded `dateRange` needed in the query.
99
+
100
+ ### Dropdown with query binding
101
+
102
+ ```markdown
103
+ ---
104
+ title: Sales by Channel
105
+ ---
106
+
107
+ ` ``query channels
108
+ dimensions: [orders.channel]
109
+ ` ``
110
+
111
+ <Dropdown name="ch" dimension="orders.channel" data={channels} queries="main" label="Channel" />
112
+
113
+ ` ``query main
114
+ measures: [orders.total_revenue]
115
+ dimensions: [orders.city]
116
+ ` ``
117
+
118
+ <BarChart data={main} x="orders.city" y="orders.total_revenue" />
119
+ ```
120
+
121
+ ### Combined inputs
122
+
123
+ ```markdown
124
+ ---
125
+ title: Sales Dashboard
126
+ ---
127
+
128
+ <DateRange name="period" default="last-6-months" label="Time Period" />
129
+ <Dropdown name="channel" dimension="orders.channel" data={channels} queries="trend,by_city" label="Channel" />
130
+
131
+ ` ``query channels
132
+ dimensions: [orders.channel]
133
+ ` ``
134
+
135
+ ` ``query trend
136
+ measures: [orders.total_revenue]
137
+ timeDimension:
138
+ dimension: orders.created_at
139
+ granularity: month
140
+ ` ``
141
+
142
+ <LineChart data={trend} x="orders.created_at" y="orders.total_revenue" />
143
+
144
+ ` ``query by_city
145
+ measures: [orders.total_revenue]
146
+ dimensions: [orders.city]
147
+ ` ``
148
+
149
+ <BarChart data={by_city} x="orders.city" y="orders.total_revenue" />
150
+ ```
151
+
152
+ Both inputs work together: the DateRange scopes the time window on `trend` (which has a timeDimension), and the Dropdown filters both `trend` and `by_city` by channel.
153
+
154
+ ## Shareable URLs
155
+
156
+ Input values automatically sync to URL query params. When a user changes a filter, the URL updates to reflect the current state — for example:
157
+
158
+ ```
159
+ /dashboards/sales?period=last-30-days&channel=Online
160
+ ```
161
+
162
+ - **Default values are omitted** from the URL for clean links
163
+ - **Sharing a URL** preserves the current filter state — recipients see exactly the same filtered view
164
+ - **Refreshing the page** restores the active filters from the URL
165
+ - The **Copy Link** button in the dashboard header copies the full URL including filter params
166
+
167
+ DateRange inputs store the preset key (e.g. `last-30-days`), so shared URLs stay relative to today. Dropdown inputs store the selected value string.
168
+
169
+ ## See Also
170
+
171
+ - [Dashboards](dashboards) — overview and deployment
172
+ - [Components](dashboards.components) — chart and display components
173
+ - [Examples](dashboards.examples) — complete dashboard examples
@@ -0,0 +1,112 @@
1
+ # Dashboards
2
+
3
+ > Build interactive dashboards from markdown with embedded semantic layer queries.
4
+
5
+ ## Overview
6
+
7
+ Dashboards let your team track key metrics without leaving the Bonnard app. Define queries once in markdown, deploy them, and every viewer gets live, governed data — no separate BI tool needed. Filters, formatting, and layout are all declared in the same file.
8
+
9
+ A dashboard is a markdown file with YAML frontmatter, query blocks, and chart components. Write it as a `.md` file, preview locally with `bon dashboard dev`, and deploy with `bon dashboard deploy`.
10
+
11
+ ## Format
12
+
13
+ A dashboard file has three parts:
14
+
15
+ 1. **Frontmatter** — YAML metadata between `---` delimiters
16
+ 2. **Query blocks** — Named data queries in ` ```query ` code fences
17
+ 3. **Content** — Markdown text and chart component tags
18
+
19
+ ## Minimal Example
20
+
21
+ ```markdown
22
+ ---
23
+ title: Order Summary
24
+ description: Key metrics for the orders pipeline
25
+ ---
26
+
27
+ # Order Summary
28
+
29
+ ` ``query order_count
30
+ measures: [orders.count]
31
+ ` ``
32
+
33
+ <BigValue data={order_count} value="orders.count" title="Total Orders" />
34
+
35
+ ` ``query by_status
36
+ measures: [orders.count]
37
+ dimensions: [orders.status]
38
+ ` ``
39
+
40
+ <BarChart data={by_status} x="orders.status" y="orders.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
+ ---
52
+ ```
53
+
54
+ | Field | Required | Description |
55
+ |-------|----------|-------------|
56
+ | `title` | Yes | Dashboard title displayed in the viewer and listings |
57
+ | `description` | No | Short description shown in dashboard listings |
58
+
59
+ ## Local Preview
60
+
61
+ Preview a dashboard locally with live reload before deploying. Requires `bon login`.
62
+
63
+ ```bash
64
+ bon dashboard dev revenue.md
65
+ ```
66
+
67
+ This starts a local server, opens your browser, and auto-reloads when you save changes. Queries run against your deployed semantic layer using your own credentials — governance policies apply.
68
+
69
+ ## Deployment
70
+
71
+ Deploy from the command line or via MCP tools. Each deploy auto-versions the dashboard so you can roll back if needed.
72
+
73
+ ```bash
74
+ # Deploy a markdown dashboard
75
+ bon dashboard deploy revenue.md
76
+
77
+ # List deployed dashboards
78
+ bon dashboard list
79
+
80
+ # Open in browser
81
+ bon dashboard open revenue
82
+
83
+ # Remove a dashboard
84
+ bon dashboard remove revenue
85
+ ```
86
+
87
+ Options:
88
+ - `--slug <slug>` — custom URL slug (default: derived from filename)
89
+ - `--title <title>` — dashboard title (default: from frontmatter)
90
+
91
+ Via MCP tools, agents can use `deploy_dashboard` with the markdown content as a string.
92
+
93
+ ## Versioning
94
+
95
+ Every deployment auto-increments the version number and saves a snapshot. You can view version history and restore previous versions via MCP tools (`get_dashboard` with version parameter, `deploy_dashboard` with `restore_version`).
96
+
97
+ Restoring a version creates a new version (e.g. restoring v2 from v5 creates v6 with v2's content). Version history is never deleted — only `remove_dashboard` deletes all history.
98
+
99
+ ## Governance
100
+
101
+ Dashboard queries respect the same governance policies as all other queries. When a user views a dashboard:
102
+
103
+ - **View-level access** — users only see data from views their governance groups allow
104
+ - **Row-level filtering** — user attributes (e.g. region, department) automatically filter query results
105
+ - All org members see the same dashboard list, but may see different data depending on their governance context
106
+
107
+ ## See Also
108
+
109
+ - [Queries](dashboards.queries) — query syntax and properties
110
+ - [Components](dashboards.components) — chart and display components
111
+ - [Inputs](dashboards.inputs) — interactive filters
112
+ - [Examples](dashboards.examples) — complete dashboard examples
@@ -0,0 +1,112 @@
1
+ # Queries
2
+
3
+ > Define data queries in dashboard markdown using YAML code fences.
4
+
5
+ ## Overview
6
+
7
+ Each query fetches data from your semantic layer and makes it available to chart components. Queries use the same measures and dimensions defined in your cubes and views — field names stay consistent whether you're querying from a dashboard, MCP, or the API.
8
+
9
+ Query blocks have a unique name and map to a `QueryOptions` shape. Components reference them using `data={query_name}`. All field names must be fully qualified with the cube or view name (e.g. `orders.count`, `orders.created_at`).
10
+
11
+ ## Syntax
12
+
13
+ Query blocks use fenced code with the `query` language tag followed by a name:
14
+
15
+ ````markdown
16
+ ```query revenue_trend
17
+ measures: [orders.total_revenue]
18
+ timeDimension:
19
+ dimension: orders.created_at
20
+ granularity: month
21
+ dateRange: [2025-01-01, 2025-12-31]
22
+ ```
23
+ ````
24
+
25
+ ## Query Properties
26
+
27
+ | Property | Type | Required | Description |
28
+ |----------|------|----------|-------------|
29
+ | `measures` | string[] | No | Fully qualified measures to aggregate (e.g. `[orders.count, orders.total_revenue]`) |
30
+ | `dimensions` | string[] | No | Fully qualified dimensions to group by (e.g. `[orders.status, orders.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. `{orders.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 | Fully qualified time dimension name (e.g. `orders.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
+ measures: [orders.count]
61
+ ```
62
+ ````
63
+
64
+ ### Grouped by dimension
65
+
66
+ ````markdown
67
+ ```query revenue_by_city
68
+ measures: [orders.total_revenue]
69
+ dimensions: [orders.city]
70
+ orderBy:
71
+ orders.total_revenue: desc
72
+ limit: 10
73
+ ```
74
+ ````
75
+
76
+ ### Time series
77
+
78
+ ````markdown
79
+ ```query monthly_revenue
80
+ measures: [orders.total_revenue]
81
+ timeDimension:
82
+ dimension: orders.created_at
83
+ granularity: month
84
+ dateRange: [2025-01-01, 2025-12-31]
85
+ ```
86
+ ````
87
+
88
+ ### With filters
89
+
90
+ ````markdown
91
+ ```query completed_orders
92
+ measures: [orders.count, orders.total_revenue]
93
+ dimensions: [orders.category]
94
+ filters:
95
+ - dimension: orders.status
96
+ operator: equals
97
+ values: [completed]
98
+ ```
99
+ ````
100
+
101
+ ## Rules
102
+
103
+ - Query names must be valid identifiers (letters, numbers, `_`, `$`)
104
+ - Query names must be unique within a dashboard
105
+ - All field names must be fully qualified with the cube or view name (e.g. `orders.count`, not `count`)
106
+ - Components reference queries by name: `data={query_name}`
107
+
108
+ ## See Also
109
+
110
+ - [Components](dashboards.components) — chart and display components
111
+ - [Dashboards](dashboards) — overview and deployment
112
+ - [Querying](querying) — query format reference
@@ -1,26 +1,15 @@
1
1
  ---
2
2
  name: bonnard-build-dashboard
3
- description: Guide a user through building and deploying a data dashboard using the Bonnard SDK and Chart.js. Use when user says "build a dashboard", "create a chart", "visualize data", or wants to deploy an HTML dashboard.
4
- allowed-tools: Bash(bon *)
3
+ description: Guide a user through building and deploying a markdown dashboard. Use when user says "build a dashboard", "create a chart", "visualize data", or wants to create a dashboard.
4
+ allowed-tools: Bash(bon *), Write, Edit, Read
5
5
  ---
6
6
 
7
- # Build & Deploy a Dashboard
7
+ # Build & Deploy a Markdown Dashboard
8
8
 
9
- This skill guides you through creating an HTML dashboard powered by the
10
- Bonnard SDK and deploying it as a hosted dashboard.
9
+ This skill guides you through creating a markdown dashboard with built-in
10
+ chart components and deploying it to Bonnard.
11
11
 
12
- ## Phase 1: Get the Starter Template
13
-
14
- Fetch the SDK + Chart.js starter template:
15
-
16
- ```bash
17
- bon docs sdk.chartjs
18
- ```
19
-
20
- This shows a working HTML template with `@bonnard/sdk` loaded from CDN and
21
- a Chart.js example. Copy this as your starting point.
22
-
23
- ## Phase 2: Explore Available Data
12
+ ## Phase 1: Explore Available Data
24
13
 
25
14
  Discover what measures and dimensions are available to query:
26
15
 
@@ -38,48 +27,97 @@ bon query --sql "SELECT MEASURE(total_revenue), date FROM sales_performance LIMI
38
27
  Ask the user what data they want to visualize. Match their request to
39
28
  available views and measures.
40
29
 
41
- ## Phase 3: Build the HTML File
30
+ ## Phase 2: Learn the Format
42
31
 
43
- Create an HTML file that:
44
- 1. Loads `@bonnard/sdk` from CDN (see the template from Phase 1)
45
- 2. Initializes the SDK with a publishable key placeholder
46
- 3. Queries the semantic layer for the data the user wants
47
- 4. Renders charts using Chart.js (or another chart library)
32
+ Review the dashboard format docs for reference:
33
+
34
+ ```bash
35
+ bon docs dashboards # Overview + format
36
+ bon docs dashboards.components # Chart components (BigValue, LineChart, BarChart, etc.)
37
+ bon docs dashboards.queries # Query block syntax
38
+ bon docs dashboards.inputs # Interactive filters (DateRange, Dropdown)
39
+ bon docs dashboards.examples # Complete examples
40
+ ```
41
+
42
+ ## Phase 3: Build the Markdown File
43
+
44
+ Create a `.md` file with three parts:
45
+
46
+ 1. **YAML frontmatter** — title and optional description
47
+ 2. **Query blocks** — ` ```query name ` code fences with YAML query options
48
+ 3. **Components** — `<BigValue />`, `<LineChart />`, `<BarChart />`, etc.
48
49
 
49
50
  Key points:
50
- - The SDK uses `Bonnard.query()` to fetch data from the deployed semantic layer
51
- - Use the view names and measure/dimension names from Phase 2
52
- - The publishable key will be provided by the user or can be created with `bon keys create`
53
- - Keep the HTML self-contained (inline CSS/JS, load libraries from CDN)
51
+ - All field names must be fully qualified: `orders.total_revenue`, not `total_revenue`
52
+ - Each component references a query by name: `data={query_name}`
53
+ - Consecutive `<BigValue>` components auto-group into a row
54
+ - Use `<Grid cols="2">` to place charts side by side
55
+ - Use `<DateRange>` and `<Dropdown>` for interactive filters
54
56
 
55
- Save the file (e.g., `dashboard.html`).
57
+ Example structure:
58
+
59
+ ```markdown
60
+ ---
61
+ title: Revenue Dashboard
62
+ description: Key revenue metrics and trends
63
+ ---
64
+
65
+ ` ``query total_revenue
66
+ measures: [orders.total_revenue]
67
+ ` ``
68
+
69
+ ` ``query order_count
70
+ measures: [orders.count]
71
+ ` ``
72
+
73
+ <BigValue data={total_revenue} value="orders.total_revenue" title="Revenue" fmt="eur2" />
74
+ <BigValue data={order_count} value="orders.count" title="Orders" />
75
+
76
+ ## Trend
77
+
78
+ ` ``query monthly
79
+ measures: [orders.total_revenue]
80
+ timeDimension:
81
+ dimension: orders.created_at
82
+ granularity: month
83
+ ` ``
84
+
85
+ <LineChart data={monthly} x="orders.created_at" y="orders.total_revenue" title="Monthly Revenue" yFmt="eur" />
86
+ ```
87
+
88
+ Save the file (e.g., `dashboard.md`).
56
89
 
57
90
  ## Phase 4: Preview Locally
58
91
 
59
- Let the user preview the file in their browser before deploying.
60
- They'll need to set a valid publishable key in the HTML first.
92
+ Preview the dashboard with live reload:
61
93
 
62
94
  ```bash
63
- # Create a publishable key if needed
64
- bon keys create --name "Dashboard" --type publishable
95
+ bon dashboard dev dashboard.md
65
96
  ```
66
97
 
98
+ This opens a browser with the rendered dashboard. Edit the `.md` file and
99
+ the preview updates automatically. Queries run against the deployed
100
+ semantic layer using the user's credentials.
101
+
102
+ Requires `bon login` — no API key needed.
103
+
67
104
  ## Phase 5: Deploy
68
105
 
69
- Deploy the HTML file as a hosted dashboard on Bonnard:
106
+ Deploy the dashboard to Bonnard:
70
107
 
71
108
  ```bash
72
- bon dashboard deploy dashboard.html
109
+ bon dashboard deploy dashboard.md
73
110
  ```
74
111
 
75
112
  This will:
76
- - Upload the HTML content
113
+ - Upload the markdown content
77
114
  - Assign a slug (derived from filename, or use `--slug`)
78
- - Print the public URL where the dashboard is accessible
115
+ - Extract the title from frontmatter
116
+ - Print the URL where the dashboard is accessible
79
117
 
80
118
  Options:
81
119
  - `--slug <slug>` — custom URL slug (default: derived from filename)
82
- - `--title <title>` — dashboard title (default: from `<title>` tag)
120
+ - `--title <title>` — override frontmatter title
83
121
 
84
122
  ## Phase 6: View Live
85
123
 
@@ -91,10 +129,10 @@ bon dashboard open dashboard
91
129
 
92
130
  ## Iteration
93
131
 
94
- To update the dashboard, edit the HTML file and redeploy:
132
+ To update, edit the `.md` file and redeploy:
95
133
 
96
134
  ```bash
97
- bon dashboard deploy dashboard.html
135
+ bon dashboard deploy dashboard.md
98
136
  ```
99
137
 
100
138
  Each deploy increments the version. Use `bon dashboard list` to see all