@graphit/cli 0.1.1 → 0.1.3
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/.claude-plugin/marketplace.json +25 -0
- package/.claude-plugin/plugin.json +23 -0
- package/.codex-plugin/plugin.json +22 -0
- package/package.json +4 -2
- package/{skill → skills/graphit}/SKILL.md +78 -23
- package/skills/graphit/cursor/graphit-chart-patterns.mdc +86 -0
- package/skills/graphit/graphit.mdc +117 -0
- package/skills/graphit/references/chart-patterns.md +80 -0
- package/dist/api/client.d.ts +0 -16
- package/dist/api/client.js +0 -67
- package/dist/api/client.js.map +0 -1
- package/dist/auth/credentials.d.ts +0 -15
- package/dist/auth/credentials.js +0 -34
- package/dist/auth/credentials.js.map +0 -1
- package/dist/auth/login.d.ts +0 -2
- package/dist/auth/login.js +0 -230
- package/dist/auth/login.js.map +0 -1
- package/dist/auth/token.d.ts +0 -5
- package/dist/auth/token.js +0 -42
- package/dist/auth/token.js.map +0 -1
- package/dist/commands/auth.d.ts +0 -2
- package/dist/commands/auth.js +0 -68
- package/dist/commands/auth.js.map +0 -1
- package/dist/commands/connector.d.ts +0 -2
- package/dist/commands/connector.js +0 -97
- package/dist/commands/connector.js.map +0 -1
- package/dist/commands/dashboard.d.ts +0 -2
- package/dist/commands/dashboard.js +0 -124
- package/dist/commands/dashboard.js.map +0 -1
- package/dist/commands/ds.d.ts +0 -2
- package/dist/commands/ds.js +0 -53
- package/dist/commands/ds.js.map +0 -1
- package/dist/commands/kb.d.ts +0 -2
- package/dist/commands/kb.js +0 -259
- package/dist/commands/kb.js.map +0 -1
- package/dist/commands/query.d.ts +0 -2
- package/dist/commands/query.js +0 -61
- package/dist/commands/query.js.map +0 -1
- package/dist/commands/setup.d.ts +0 -2
- package/dist/commands/setup.js +0 -173
- package/dist/commands/setup.js.map +0 -1
- package/dist/config.d.ts +0 -4
- package/dist/config.js +0 -9
- package/dist/config.js.map +0 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.js +0 -24
- package/dist/index.js.map +0 -1
- package/dist/output/format.d.ts +0 -8
- package/dist/output/format.js +0 -30
- package/dist/output/format.js.map +0 -1
- package/dist/output/json.d.ts +0 -1
- package/dist/output/json.js +0 -4
- package/dist/output/json.js.map +0 -1
- package/dist/output/table.d.ts +0 -2
- package/dist/output/table.js +0 -17
- package/dist/output/table.js.map +0 -1
- package/skill/cursor/graphit-chart-patterns.mdc +0 -148
- package/skill/graphit.mdc +0 -135
- package/skill/references/chart-patterns.md +0 -257
- /package/{skill → skills/graphit}/cursor/graphit-chart-selection.mdc +0 -0
- /package/{skill → skills/graphit}/cursor/graphit-dashboard-planning.mdc +0 -0
- /package/{skill → skills/graphit}/cursor/graphit-domain-lenses.mdc +0 -0
- /package/{skill → skills/graphit}/cursor/graphit-kb-exploration.mdc +0 -0
- /package/{skill → skills/graphit}/cursor/graphit-sql-reference.mdc +0 -0
- /package/{skill → skills/graphit}/cursor/graphit-style.mdc +0 -0
- /package/{skill → skills/graphit}/references/chart-selection.md +0 -0
- /package/{skill → skills/graphit}/references/dashboard-planning.md +0 -0
- /package/{skill → skills/graphit}/references/domain-lenses.md +0 -0
- /package/{skill → skills/graphit}/references/graphit-style.md +0 -0
- /package/{skill → skills/graphit}/references/kb-exploration.md +0 -0
- /package/{skill → skills/graphit}/references/sql-reference.md +0 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "graphit-cli",
|
|
3
|
+
"owner": {
|
|
4
|
+
"name": "Graphit",
|
|
5
|
+
"email": "support@graphit-app.com",
|
|
6
|
+
"url": "https://graphit-app.com"
|
|
7
|
+
},
|
|
8
|
+
"metadata": {
|
|
9
|
+
"description": "Graphit CLI plugin for AI coding assistants",
|
|
10
|
+
"version": "1.0.0"
|
|
11
|
+
},
|
|
12
|
+
"plugins": [
|
|
13
|
+
{
|
|
14
|
+
"name": "graphit",
|
|
15
|
+
"description": "Build custom HTML dashboards from real data. KB-aware queries, entity wrapping, cached data sources.",
|
|
16
|
+
"source": {
|
|
17
|
+
"type": "npm",
|
|
18
|
+
"package": "@graphit/cli"
|
|
19
|
+
},
|
|
20
|
+
"version": "0.1.3",
|
|
21
|
+
"category": "data-visualization",
|
|
22
|
+
"tags": ["bi", "dashboard", "sql", "data", "visualization"]
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "graphit",
|
|
3
|
+
"version": "0.1.3",
|
|
4
|
+
"description": "Build custom HTML dashboards from real data using the Graphit CLI. KB-aware queries, entity wrapping, cached data sources.",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Graphit",
|
|
7
|
+
"email": "support@graphit-app.com",
|
|
8
|
+
"url": "https://graphit-app.com"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://graphit-app.com",
|
|
11
|
+
"repository": "https://github.com/graphit-app/graphit-cli",
|
|
12
|
+
"license": "UNLICENSED",
|
|
13
|
+
"keywords": [
|
|
14
|
+
"graphit",
|
|
15
|
+
"bi",
|
|
16
|
+
"dashboard",
|
|
17
|
+
"custom-dashboard",
|
|
18
|
+
"data-visualization",
|
|
19
|
+
"knowledge-base",
|
|
20
|
+
"sql",
|
|
21
|
+
"cli"
|
|
22
|
+
]
|
|
23
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "graphit",
|
|
3
|
+
"version": "0.1.3",
|
|
4
|
+
"description": "Build custom HTML dashboards from real data using the Graphit CLI. KB-aware queries, entity wrapping, cached data sources.",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Graphit",
|
|
7
|
+
"email": "support@graphit-app.com",
|
|
8
|
+
"url": "https://graphit-app.com"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://graphit-app.com",
|
|
11
|
+
"repository": "https://github.com/graphit-app/graphit-cli",
|
|
12
|
+
"keywords": [
|
|
13
|
+
"graphit",
|
|
14
|
+
"bi",
|
|
15
|
+
"dashboard",
|
|
16
|
+
"custom-dashboard",
|
|
17
|
+
"data-visualization",
|
|
18
|
+
"knowledge-base",
|
|
19
|
+
"sql",
|
|
20
|
+
"cli"
|
|
21
|
+
]
|
|
22
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graphit/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Graphit CLI - Build custom dashboards from any AI coding assistant",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -16,7 +16,9 @@
|
|
|
16
16
|
},
|
|
17
17
|
"files": [
|
|
18
18
|
"dist",
|
|
19
|
-
"
|
|
19
|
+
"skills",
|
|
20
|
+
".claude-plugin",
|
|
21
|
+
".codex-plugin"
|
|
20
22
|
],
|
|
21
23
|
"keywords": [
|
|
22
24
|
"graphit",
|
|
@@ -4,13 +4,24 @@ description: >
|
|
|
4
4
|
Build HTML dashboards with Graphit. KB-aware queries, entity wrapping, cached data sources.
|
|
5
5
|
Triggers on: "dashboard", "graphit", "KB", "metric", "data source", "build a dashboard",
|
|
6
6
|
"explore the KB", "query data", "custom dashboard".
|
|
7
|
-
|
|
7
|
+
Do NOT activate for: editing platform-native dashboard widgets, non-HTML output formats,
|
|
8
|
+
general data analysis without a dashboard deliverable.
|
|
8
9
|
---
|
|
9
10
|
|
|
10
11
|
# Graphit CLI
|
|
11
12
|
|
|
12
13
|
Build custom HTML dashboards from real data using the Graphit CLI.
|
|
13
14
|
|
|
15
|
+
## Session Start
|
|
16
|
+
|
|
17
|
+
Run `graphit --version` at the start of every session to confirm the CLI is installed.
|
|
18
|
+
If the output includes an "Update available" banner, tell the user to update before proceeding and explain that outdated versions may be missing commands or bug fixes.
|
|
19
|
+
|
|
20
|
+
## Error Recovery
|
|
21
|
+
|
|
22
|
+
When any `graphit` command fails with an unexpected error (unknown command, unrecognized flag, non-zero exit with unclear message), suggest `npm update -g @graphit/cli` before investigating further. Outdated CLI versions are the most common cause of unexpected errors.
|
|
23
|
+
Do NOT suggest updating for normal operational failures (expired auth, bad SQL syntax, network timeout, entity not found).
|
|
24
|
+
|
|
14
25
|
## HARD CONSTRAINTS (violating these produces a broken dashboard)
|
|
15
26
|
|
|
16
27
|
### 1. ZERO external resources
|
|
@@ -21,8 +32,7 @@ Your HTML must NEVER contain:
|
|
|
21
32
|
- `<img src="https://...">` - no external images
|
|
22
33
|
|
|
23
34
|
If you use ANY `src=` or `href=` pointing to a URL, the dashboard will be blank.
|
|
24
|
-
|
|
25
|
-
All CSS in `<style>`, all JS in `<script>`, all fonts from system stack.
|
|
35
|
+
All CSS in `<style>`, all JS in `<script>`, all fonts from system stack. The iframe has a built-in runtime (`graphit.chart`, `graphit.table`, `graphit.kpi`) for standard visualizations - use it instead of importing libraries.
|
|
26
36
|
|
|
27
37
|
### 2. ALWAYS query through data sources
|
|
28
38
|
NEVER query the warehouse directly when a cached data source covers the table. Data sources return in ~100ms. Warehouse queries take ~10s and cost Snowflake credits.
|
|
@@ -59,15 +69,21 @@ Missing any attribute = broken entity. Missing wrapping entirely = invisible to
|
|
|
59
69
|
|
|
60
70
|
**Label = visible title.** The `data-graphit-label` MUST match the card's visible heading exactly. Users see the label in @ mention dropdowns and entity panels - if it doesn't match the title on screen, they can't find their chart.
|
|
61
71
|
|
|
72
|
+
### 4. ALWAYS use graphit.resolve() for live data
|
|
73
|
+
NEVER embed query results as static JS variables. The dashboard iframe provides `graphit.resolve()` which fetches live data from cached data sources on every page load.
|
|
74
|
+
|
|
75
|
+
**Wrong:** Running queries at build time, embedding results as `const data = [{...}, ...]` in the HTML.
|
|
76
|
+
**Right:** Using `graphit.resolve({sql, dataSourceId})` in a `<script>` block so data refreshes automatically.
|
|
77
|
+
|
|
62
78
|
---
|
|
63
79
|
|
|
64
80
|
## Workflow
|
|
65
81
|
|
|
66
82
|
1. **Ask the user** what dashboard they want. Don't start querying until you know what they need.
|
|
67
|
-
2. **Explore KB** to understand available metrics, dimensions, tables, and
|
|
83
|
+
2. **Explore KB** to understand available metrics, dimensions, tables, and rules.
|
|
68
84
|
3. **Find a data source** (`graphit ds list`) - prefer cached data sources (~100ms) over live warehouse (~10s).
|
|
69
|
-
4. **Query data** and
|
|
70
|
-
5. **Build HTML** -
|
|
85
|
+
4. **Query data to validate** - run queries via the CLI to verify SQL and preview results. Show the user what you found.
|
|
86
|
+
5. **Build HTML** - write `graphit.resolve()` calls for live data + `graphit.chart/table/kpi` for rendering. All CSS in `<style>`, all JS in `<script>`. Write to a local `.html` file.
|
|
71
87
|
6. **Save** with `graphit dashboard update-html <id> --file <path>`.
|
|
72
88
|
7. Give the user the dashboard URL so they can open it.
|
|
73
89
|
|
|
@@ -130,26 +146,65 @@ Found **12 metrics** and **8 dimensions** on table MARKETING_UA:
|
|
|
130
146
|
|
|
131
147
|
---
|
|
132
148
|
|
|
133
|
-
##
|
|
149
|
+
## graphit.resolve() - Live Data API
|
|
150
|
+
|
|
151
|
+
The iframe provides `graphit.resolve()` to fetch live data from cached data sources. This is how your HTML gets its data - never embed static query results.
|
|
152
|
+
|
|
153
|
+
```js
|
|
154
|
+
const result = await graphit.resolve({
|
|
155
|
+
sql: "SELECT region, SUM(revenue) as rev FROM orders GROUP BY region",
|
|
156
|
+
dataSourceId: "ds_abc123",
|
|
157
|
+
target: "#chart-container", // optional: shows loading spinner on element
|
|
158
|
+
maxRows: 10000 // optional: default 10K, max 10K
|
|
159
|
+
});
|
|
160
|
+
// Returns: { columns: string[], data: object[], rowCount: number, truncated: boolean }
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
The `dataSourceId` is the ID from `graphit ds list`. The `target` parameter (CSS selector or element) shows a blur + spinner overlay while loading and removes it on completion. `result.data` is an array of row objects you can render however you want.
|
|
134
164
|
|
|
135
|
-
**
|
|
165
|
+
**Error handling:** `graphit.resolve()` rejects on timeout (60s), bad SQL, or invalid data source ID. Wrap calls in try/catch and show a user-visible error message in the target element on failure. Verify SQL returns data via the CLI before embedding it in HTML.
|
|
136
166
|
|
|
137
|
-
|
|
138
|
-
|---|---|---|
|
|
139
|
-
| 1 temporal + 1 numeric | Line | SVG `<polyline>` with `viewBox` |
|
|
140
|
-
| 1 categorical + 1 numeric | Bar | CSS width% divs |
|
|
141
|
-
| Single number | KPI card | Styled div |
|
|
142
|
-
| Part-whole (max 5) | Donut | SVG arc paths |
|
|
143
|
-
| 2 numerics + optional size | Scatter / Bubble | SVG `<circle>` elements |
|
|
144
|
-
| Matrix / cohort | Heatmap | CSS grid + opacity |
|
|
145
|
-
| Stages | Funnel | CSS width% bars, narrowing |
|
|
146
|
-
| Time sparkline | Sparkline | Inline SVG `<polyline>` |
|
|
147
|
-
| Detail / raw data | Table | HTML table + hover rows |
|
|
167
|
+
### Rendering
|
|
148
168
|
|
|
149
|
-
|
|
169
|
+
You have full creative freedom for how to present data. Build charts with inline SVG, CSS, HTML tables, creative layouts - whatever fits the dashboard best.
|
|
150
170
|
|
|
151
|
-
|
|
152
|
-
|
|
171
|
+
The iframe also provides optional convenience helpers if you want quick standard charts:
|
|
172
|
+
|
|
173
|
+
| Helper | Usage |
|
|
174
|
+
|---|---|
|
|
175
|
+
| `graphit.chart(el, {type, data, x, y, ...})` | Bar, line, area, donut, scatter, stacked-bar, heatmap, funnel, gauge, sparkline |
|
|
176
|
+
| `graphit.table(el, {data, columns?, ...})` | Styled HTML table |
|
|
177
|
+
| `graphit.kpi(el, {value, label?, format?})` | KPI card with optional delta |
|
|
178
|
+
|
|
179
|
+
These are shortcuts, not requirements. Use them when a standard chart is all you need. Hand-roll when you want full control over the visualization.
|
|
180
|
+
|
|
181
|
+
`graphit.chart` types: `"bar"`, `"line"`, `"area"`, `"donut"` (alias `"pie"`), `"scatter"` (alias `"bubble"`), `"stacked-bar"` (alias `"stacked"`), `"heatmap"`, `"funnel"`, `"gauge"`, `"sparkline"`. Config: `x` (category field), `y` (value field), `series` (group-by field), `title`, `height` (140-900px), `valueFormat` (`"currency"` | `"percent"` | `"number"`), `colors` (array). Scatter adds: `size` (bubble radius field), `label` (tooltip field). Gauge adds: `min`, `max`, `format`. Sparkline adds: `width`, `showValue`.
|
|
182
|
+
|
|
183
|
+
`graphit.kpi` config: `value`, `label`, `format` (`"currency"` | `"percent"` | `"number"`), `compareValue`, `compareLabel`.
|
|
184
|
+
|
|
185
|
+
### Canonical pattern - entity with live data
|
|
186
|
+
|
|
187
|
+
```html
|
|
188
|
+
<div data-graphit-id="spend-by-source"
|
|
189
|
+
data-graphit-label="Ad Spend by Source"
|
|
190
|
+
data-graphit-kb="metric:CPI,dimension:MEDIA_SOURCE,table:MARKETING_UA"
|
|
191
|
+
data-graphit-sql="SELECT MEDIA_SOURCE, SUM(APPSFLYER_COST) as spend FROM MARKETING_UA GROUP BY MEDIA_SOURCE ORDER BY spend DESC">
|
|
192
|
+
<div id="spend-chart"></div>
|
|
193
|
+
</div>
|
|
194
|
+
<script>
|
|
195
|
+
(async function() {
|
|
196
|
+
var r = await graphit.resolve({
|
|
197
|
+
sql: "SELECT MEDIA_SOURCE, SUM(APPSFLYER_COST) as spend FROM MARKETING_UA GROUP BY MEDIA_SOURCE ORDER BY spend DESC",
|
|
198
|
+
dataSourceId: "ds_abc123",
|
|
199
|
+
target: "#spend-chart"
|
|
200
|
+
});
|
|
201
|
+
graphit.chart("#spend-chart", {
|
|
202
|
+
type: "bar", data: r.data, x: "MEDIA_SOURCE", y: "spend",
|
|
203
|
+
title: "Ad Spend by Source", valueFormat: "currency"
|
|
204
|
+
});
|
|
205
|
+
})();
|
|
206
|
+
</script>
|
|
207
|
+
```
|
|
153
208
|
|
|
154
209
|
---
|
|
155
210
|
|
|
@@ -165,4 +220,4 @@ Detailed knowledge lives in `references/`. Consult the relevant file when you ne
|
|
|
165
220
|
| `sql-reference.md` | Writing queries. DuckDB/Snowflake translation, formatting standards, gap-filling, JSON access, data source routing. |
|
|
166
221
|
| `domain-lenses.md` | Data matches a business domain. Marketing, finance, product/growth, ops, sales - signals, key metrics, must-have charts, anti-patterns. |
|
|
167
222
|
| `graphit-style.md` | Building the HTML. Design principles, typography scale, color system with usage rules, layout patterns (page structure, KPI cards, data tables). |
|
|
168
|
-
| `chart-patterns.md` |
|
|
223
|
+
| `chart-patterns.md` | Custom chart implementations. Inline SVG/CSS code for: scatter/bubble, heatmap, funnel, gauge, sparkline, stacked bar, and the shared tooltip pattern. |
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
---
|
|
2
|
+
alwaysApply: false
|
|
3
|
+
description: "Graphit: Runtime chart types via graphit.chart() and hand-rolled patterns. All data from graphit.resolve()."
|
|
4
|
+
globs: []
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Chart Patterns
|
|
8
|
+
|
|
9
|
+
All chart types are available via `graphit.chart()`. All data comes from `graphit.resolve()` - never embed static data.
|
|
10
|
+
|
|
11
|
+
**NEVER use `<canvas>`.** Canvas produces blurry charts inside the sandboxed iframe due to DPI scaling issues.
|
|
12
|
+
|
|
13
|
+
## Runtime chart types
|
|
14
|
+
|
|
15
|
+
### bar
|
|
16
|
+
SVG vertical bars. Multi-series: grouped side-by-side. Y-axis: 4 grid lines with formatted labels. X-axis: category labels (sampled if >12). Rounded top corners (rx=3). `<title>` tooltips per bar.
|
|
17
|
+
|
|
18
|
+
### line / area
|
|
19
|
+
SVG line with circle dots at each point. Area adds filled path below (opacity 0.18). Multi-series: separate colored paths. Y-axis scaled to data range (min to max). `<title>` tooltips per dot.
|
|
20
|
+
|
|
21
|
+
### donut / pie
|
|
22
|
+
SVG pie slices with center hole (58% of radius). Center shows formatted total. Legend below with color swatches.
|
|
23
|
+
|
|
24
|
+
### scatter / bubble
|
|
25
|
+
SVG circles positioned by x/y. Size field scales radius (sqrt, 3-40px). Fill opacity 0.6 with solid stroke. 4 horizontal grid lines. Capped at 200 points.
|
|
26
|
+
Config: `x`, `y`, `size` (optional radius), `label` (tooltip), `xFormat`.
|
|
27
|
+
|
|
28
|
+
### stacked-bar / stacked
|
|
29
|
+
SVG vertical stacked bars. Segments stacked bottom-to-top per category. Y-axis scaled to max total. Legend shows series names.
|
|
30
|
+
Config: requires `series` field for stacking groups.
|
|
31
|
+
|
|
32
|
+
### heatmap
|
|
33
|
+
CSS grid. X = columns, Y = rows. Background intensity scales linearly with theme accent token. Text flips to raised surface color at >55% intensity. Headers auto-generated. Capped at 40x40.
|
|
34
|
+
Config: `x` (column), `y` (row), `value` (intensity, falls back to `y`).
|
|
35
|
+
|
|
36
|
+
### funnel
|
|
37
|
+
CSS horizontal bars narrowing top-to-bottom. First bar = 100% width, rest proportional. Shows step-over-step conversion rate. Colors cycle through palette.
|
|
38
|
+
|
|
39
|
+
### gauge
|
|
40
|
+
CSS half-circle via `conic-gradient` + `clip-path`. Auto-colors: green (>=70%), yellow (>=40%), red (<40%). Override with `color` config (must be a valid CSS color token).
|
|
41
|
+
Config: `value`, `min` (default 0), `max` (default 100), `format`, `label`, `color`.
|
|
42
|
+
|
|
43
|
+
### sparkline
|
|
44
|
+
Inline SVG polyline for KPI cards or table cells. No axes, no grid - just trend shape. Single data point renders as a dot.
|
|
45
|
+
Config: `y`, `width` (default 120), `height` (default 32), `label`, `showValue` (default true), `valueFormat`.
|
|
46
|
+
|
|
47
|
+
## Color tokens
|
|
48
|
+
|
|
49
|
+
| Token | Usage |
|
|
50
|
+
|---|---|
|
|
51
|
+
| `var(--graphit-accent)` | Primary brand teal |
|
|
52
|
+
| `var(--graphit-success)` | Positive/good |
|
|
53
|
+
| `var(--graphit-warning)` | Caution |
|
|
54
|
+
| `var(--graphit-error)` | Negative/bad |
|
|
55
|
+
| `var(--graphit-fg)` | Primary text |
|
|
56
|
+
| `var(--graphit-fg-muted)` | Secondary text |
|
|
57
|
+
| `var(--graphit-fg-subtle)` | Labels, placeholders |
|
|
58
|
+
| `var(--graphit-border)` | Borders, grid lines |
|
|
59
|
+
| `var(--graphit-surface-raised)` | Card backgrounds |
|
|
60
|
+
| `var(--graphit-surface-sunken)` | Inset areas |
|
|
61
|
+
|
|
62
|
+
## Tooltip pattern (for hand-rolled charts)
|
|
63
|
+
|
|
64
|
+
Runtime charts use `<title>` elements for native browser tooltips. For hand-rolled charts, add ONE shared tooltip div and always escape user data before passing to `showTooltip()`:
|
|
65
|
+
|
|
66
|
+
```html
|
|
67
|
+
<div id="tooltip" style="position:fixed;pointer-events:none;z-index:100;
|
|
68
|
+
background:var(--graphit-surface-raised);color:var(--graphit-fg);
|
|
69
|
+
border:1px solid var(--graphit-border);border-radius:8px;
|
|
70
|
+
padding:10px 14px;font-size:13px;line-height:1.5;
|
|
71
|
+
box-shadow:0 4px 12px rgba(0,0,0,0.15);opacity:0;transition:opacity 0.15s;
|
|
72
|
+
max-width:240px"></div>
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
```js
|
|
76
|
+
var tooltip = document.getElementById('tooltip');
|
|
77
|
+
function showTooltip(e, html) {
|
|
78
|
+
tooltip.innerHTML = html;
|
|
79
|
+
tooltip.style.opacity = '1';
|
|
80
|
+
var tx = Math.min(e.clientX + 12, window.innerWidth - 260);
|
|
81
|
+
var ty = e.clientY - tooltip.offsetHeight - 8;
|
|
82
|
+
tooltip.style.left = tx + 'px';
|
|
83
|
+
tooltip.style.top = (ty < 4 ? e.clientY + 16 : ty) + 'px';
|
|
84
|
+
}
|
|
85
|
+
function hideTooltip() { tooltip.style.opacity = '0'; }
|
|
86
|
+
```
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
---
|
|
2
|
+
alwaysApply: false
|
|
3
|
+
description: "Build Graphit HTML dashboards with KB-aware queries, entity wrapping, and cached data sources"
|
|
4
|
+
globs: []
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Graphit CLI
|
|
8
|
+
|
|
9
|
+
Build custom HTML dashboards from real data using the Graphit CLI.
|
|
10
|
+
|
|
11
|
+
## HARD CONSTRAINTS (violating these produces a broken dashboard)
|
|
12
|
+
|
|
13
|
+
### 1. ZERO external resources
|
|
14
|
+
The dashboard renders in a sandboxed iframe with a strict CSP. External requests are BLOCKED.
|
|
15
|
+
Your HTML must NEVER contain:
|
|
16
|
+
- `<script src="...">` - no Chart.js, D3.js, Alpine.js, ANY external JS
|
|
17
|
+
- `<link href="...">` - no Tailwind CDN, Google Fonts, ANY external CSS
|
|
18
|
+
- `<img src="https://...">` - no external images
|
|
19
|
+
|
|
20
|
+
If you use ANY `src=` or `href=` pointing to a URL, the dashboard will be blank.
|
|
21
|
+
All CSS in `<style>`, all JS in `<script>`, all fonts from system stack. The iframe has a built-in runtime (`graphit.chart`, `graphit.table`, `graphit.kpi`) for standard visualizations - use it instead of importing libraries.
|
|
22
|
+
|
|
23
|
+
### 2. ALWAYS query through data sources
|
|
24
|
+
NEVER query the warehouse directly when a cached data source covers the table. Data sources return in ~100ms. Warehouse queries take ~10s and cost Snowflake credits.
|
|
25
|
+
|
|
26
|
+
Run `graphit ds list` FIRST. If a DS covers your table, use `graphit query "SQL" --ds <id>`. Only use `--warehouse` if NO data source exists and the user approves.
|
|
27
|
+
|
|
28
|
+
### 3. EVERY element must have entity wrapping
|
|
29
|
+
Without `data-graphit-*` attributes, elements are invisible to the platform. Every chart, KPI card, table, and text section needs ALL FOUR attributes:
|
|
30
|
+
|
|
31
|
+
```html
|
|
32
|
+
<div data-graphit-id="revenue-trend"
|
|
33
|
+
data-graphit-label="Revenue Trend"
|
|
34
|
+
data-graphit-kb="metric:REVENUE,dimension:REGION,table:ORDERS"
|
|
35
|
+
data-graphit-sql="SELECT region, SUM(revenue) FROM orders GROUP BY region">
|
|
36
|
+
<!-- chart/KPI/table content here -->
|
|
37
|
+
</div>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
| Attribute | Format | Example |
|
|
41
|
+
|-----------|--------|---------|
|
|
42
|
+
| `data-graphit-id` | Unique kebab-case | `"spend-by-source"` |
|
|
43
|
+
| `data-graphit-label` | Human-readable name | `"Ad Spend by Source"` |
|
|
44
|
+
| `data-graphit-kb` | `type:NAME` comma-separated | `"metric:CPI,dimension:MEDIA_SOURCE,table:MARKETING_UA"` |
|
|
45
|
+
| `data-graphit-sql` | SQL query (HTML-encode `<>&"`) | `"SELECT ..."` |
|
|
46
|
+
|
|
47
|
+
KB types: `metric`, `dimension`, `table`, `rule`. Names are UPPER_SNAKE_CASE matching the KB exactly.
|
|
48
|
+
|
|
49
|
+
**Label = visible title.** The `data-graphit-label` MUST match the card's visible heading exactly.
|
|
50
|
+
|
|
51
|
+
### 4. ALWAYS use graphit.resolve() for live data
|
|
52
|
+
NEVER embed query results as static JS variables. The dashboard iframe provides `graphit.resolve()` which fetches live data from cached data sources on every page load.
|
|
53
|
+
|
|
54
|
+
**Wrong:** Embedding results as `const data = [{...}, ...]` in the HTML.
|
|
55
|
+
**Right:** Using `graphit.resolve({sql, dataSourceId})` in a `<script>` block so data refreshes automatically.
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Workflow
|
|
60
|
+
|
|
61
|
+
1. **Ask the user** what dashboard they want.
|
|
62
|
+
2. **Explore KB** to understand available metrics, dimensions, tables, and rules.
|
|
63
|
+
3. **Find a data source** (`graphit ds list`) - prefer cached data sources over live warehouse.
|
|
64
|
+
4. **Query data to validate** - run queries via the CLI to verify SQL and preview results.
|
|
65
|
+
5. **Build HTML** - write `graphit.resolve()` calls for live data + `graphit.chart/table/kpi` for rendering. All CSS in `<style>`, all JS in `<script>`.
|
|
66
|
+
6. **Save** with `graphit dashboard update-html <id> --file <path>`.
|
|
67
|
+
7. Give the user the dashboard URL.
|
|
68
|
+
|
|
69
|
+
## graphit.resolve() - Live Data API
|
|
70
|
+
|
|
71
|
+
```js
|
|
72
|
+
const result = await graphit.resolve({
|
|
73
|
+
sql: "SELECT region, SUM(revenue) as rev FROM orders GROUP BY region",
|
|
74
|
+
dataSourceId: "ds_abc123",
|
|
75
|
+
target: "#chart-container", // optional: shows loading spinner
|
|
76
|
+
maxRows: 10000 // optional: default 10K, max 10K
|
|
77
|
+
});
|
|
78
|
+
// Returns: { columns: string[], data: object[], rowCount: number, truncated: boolean }
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**Error handling:** Rejects on timeout (60s), bad SQL, or invalid data source ID. Wrap in try/catch.
|
|
82
|
+
|
|
83
|
+
### Runtime chart helpers
|
|
84
|
+
|
|
85
|
+
| Helper | Usage |
|
|
86
|
+
|---|---|
|
|
87
|
+
| `graphit.chart(el, {type, data, x, y, ...})` | Bar, line, area, donut, scatter, stacked-bar, heatmap, funnel, gauge, sparkline |
|
|
88
|
+
| `graphit.table(el, {data, columns?, ...})` | Styled HTML table |
|
|
89
|
+
| `graphit.kpi(el, {value, label?, format?})` | KPI card with optional delta |
|
|
90
|
+
|
|
91
|
+
`graphit.chart` types: `"bar"`, `"line"`, `"area"`, `"donut"` (alias `"pie"`), `"scatter"` (alias `"bubble"`), `"stacked-bar"` (alias `"stacked"`), `"heatmap"`, `"funnel"`, `"gauge"`, `"sparkline"`. Config: `x` (category field), `y` (value field), `series` (group-by), `title`, `height` (140-900px), `valueFormat` (`"currency"` | `"percent"` | `"number"`), `colors` (array). Scatter adds: `size`, `label`. Gauge adds: `min`, `max`, `format`. Sparkline adds: `width`, `showValue`.
|
|
92
|
+
|
|
93
|
+
### Canonical pattern - entity with live data
|
|
94
|
+
|
|
95
|
+
```html
|
|
96
|
+
<div data-graphit-id="spend-by-source"
|
|
97
|
+
data-graphit-label="Ad Spend by Source"
|
|
98
|
+
data-graphit-kb="metric:CPI,dimension:MEDIA_SOURCE,table:MARKETING_UA"
|
|
99
|
+
data-graphit-sql="SELECT MEDIA_SOURCE, SUM(APPSFLYER_COST) as spend FROM MARKETING_UA GROUP BY MEDIA_SOURCE ORDER BY spend DESC">
|
|
100
|
+
<div id="spend-chart"></div>
|
|
101
|
+
</div>
|
|
102
|
+
<script>
|
|
103
|
+
(async function() {
|
|
104
|
+
var r = await graphit.resolve({
|
|
105
|
+
sql: "SELECT MEDIA_SOURCE, SUM(APPSFLYER_COST) as spend FROM MARKETING_UA GROUP BY MEDIA_SOURCE ORDER BY spend DESC",
|
|
106
|
+
dataSourceId: "ds_abc123",
|
|
107
|
+
target: "#spend-chart"
|
|
108
|
+
});
|
|
109
|
+
graphit.chart("#spend-chart", {
|
|
110
|
+
type: "bar", data: r.data, x: "MEDIA_SOURCE", y: "spend",
|
|
111
|
+
title: "Ad Spend by Source", valueFormat: "currency"
|
|
112
|
+
});
|
|
113
|
+
})();
|
|
114
|
+
</script>
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
For detailed chart selection logic, dashboard planning, SQL reference, domain-specific lenses, Graphit visual style, and chart pattern implementations, see the companion rule files (graphit-planning, graphit-sql, graphit-lenses, graphit-style, graphit-kb, graphit-patterns).
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Chart Patterns
|
|
2
|
+
|
|
3
|
+
All chart types are available via `graphit.chart()`. All data comes from `graphit.resolve()` - never embed static data.
|
|
4
|
+
|
|
5
|
+
**NEVER use `<canvas>`.** Canvas produces blurry charts inside the sandboxed iframe due to DPI scaling issues.
|
|
6
|
+
|
|
7
|
+
## Runtime chart types
|
|
8
|
+
|
|
9
|
+
### bar
|
|
10
|
+
SVG vertical bars. Multi-series: grouped side-by-side. Y-axis: 4 grid lines with formatted labels. X-axis: category labels (sampled if >12). Rounded top corners (rx=3). `<title>` tooltips per bar.
|
|
11
|
+
|
|
12
|
+
### line / area
|
|
13
|
+
SVG line with circle dots at each point. Area adds filled path below (opacity 0.18). Multi-series: separate colored paths. Y-axis scaled to data range (min to max). `<title>` tooltips per dot.
|
|
14
|
+
|
|
15
|
+
### donut / pie
|
|
16
|
+
SVG pie slices with center hole (58% of radius). Center shows formatted total. Legend below with color swatches. Each slice is a wedge path from center.
|
|
17
|
+
|
|
18
|
+
### scatter / bubble
|
|
19
|
+
SVG circles positioned by x/y. Size field scales radius (sqrt, 3-40px). Fill opacity 0.6 with solid stroke. 4 horizontal grid lines. Capped at 200 points.
|
|
20
|
+
Config: `x`, `y`, `size` (optional radius), `label` (tooltip), `xFormat`.
|
|
21
|
+
|
|
22
|
+
### stacked-bar / stacked
|
|
23
|
+
SVG vertical stacked bars. Segments stacked bottom-to-top per category. Y-axis scaled to max total. Legend shows series names.
|
|
24
|
+
Config: requires `series` field for stacking groups.
|
|
25
|
+
|
|
26
|
+
### heatmap
|
|
27
|
+
CSS grid. X = columns, Y = rows. Background intensity scales linearly (rgba teal, 0.08-0.98). Text flips white at >55% intensity. Headers auto-generated. Capped at 40x40.
|
|
28
|
+
Config: `x` (column), `y` (row), `value` (intensity, falls back to `y`).
|
|
29
|
+
|
|
30
|
+
### funnel
|
|
31
|
+
CSS horizontal bars narrowing top-to-bottom. First bar = 100% width, rest proportional. Shows step-over-step conversion rate. Colors cycle through palette.
|
|
32
|
+
|
|
33
|
+
### gauge
|
|
34
|
+
CSS half-circle via `conic-gradient` + `clip-path`. Auto-colors: green (>=70%), yellow (>=40%), red (<40%). Override with `color` config (must be a valid CSS color token).
|
|
35
|
+
Config: `value`, `min` (default 0), `max` (default 100), `format`, `label`, `color`.
|
|
36
|
+
|
|
37
|
+
### sparkline
|
|
38
|
+
Inline SVG polyline for KPI cards or table cells. No axes, no grid - just trend shape. Single data point renders as a dot.
|
|
39
|
+
Config: `y`, `width` (default 120), `height` (default 32), `label`, `showValue` (default true), `valueFormat`.
|
|
40
|
+
|
|
41
|
+
## Color tokens
|
|
42
|
+
|
|
43
|
+
| Token | Usage |
|
|
44
|
+
|---|---|
|
|
45
|
+
| `var(--graphit-accent)` | Primary brand teal |
|
|
46
|
+
| `var(--graphit-success)` | Positive/good |
|
|
47
|
+
| `var(--graphit-warning)` | Caution |
|
|
48
|
+
| `var(--graphit-error)` | Negative/bad |
|
|
49
|
+
| `var(--graphit-fg)` | Primary text |
|
|
50
|
+
| `var(--graphit-fg-muted)` | Secondary text |
|
|
51
|
+
| `var(--graphit-fg-subtle)` | Labels, placeholders |
|
|
52
|
+
| `var(--graphit-border)` | Borders, grid lines |
|
|
53
|
+
| `var(--graphit-surface-raised)` | Card backgrounds |
|
|
54
|
+
| `var(--graphit-surface-sunken)` | Inset areas |
|
|
55
|
+
|
|
56
|
+
## Tooltip pattern (for hand-rolled charts)
|
|
57
|
+
|
|
58
|
+
Runtime charts use `<title>` elements for native browser tooltips. For hand-rolled charts, add ONE shared tooltip div and always escape user data with a manual HTML escape function before passing to `showTooltip()`:
|
|
59
|
+
|
|
60
|
+
```html
|
|
61
|
+
<div id="tooltip" style="position:fixed;pointer-events:none;z-index:100;
|
|
62
|
+
background:var(--graphit-surface-raised);color:var(--graphit-fg);
|
|
63
|
+
border:1px solid var(--graphit-border);border-radius:8px;
|
|
64
|
+
padding:10px 14px;font-size:13px;line-height:1.5;
|
|
65
|
+
box-shadow:0 4px 12px rgba(0,0,0,0.15);opacity:0;transition:opacity 0.15s;
|
|
66
|
+
max-width:240px"></div>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
```js
|
|
70
|
+
var tooltip = document.getElementById('tooltip');
|
|
71
|
+
function showTooltip(e, html) {
|
|
72
|
+
tooltip.innerHTML = html;
|
|
73
|
+
tooltip.style.opacity = '1';
|
|
74
|
+
var tx = Math.min(e.clientX + 12, window.innerWidth - 260);
|
|
75
|
+
var ty = e.clientY - tooltip.offsetHeight - 8;
|
|
76
|
+
tooltip.style.left = tx + 'px';
|
|
77
|
+
tooltip.style.top = (ty < 4 ? e.clientY + 16 : ty) + 'px';
|
|
78
|
+
}
|
|
79
|
+
function hideTooltip() { tooltip.style.opacity = '0'; }
|
|
80
|
+
```
|
package/dist/api/client.d.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export interface ApiError {
|
|
2
|
-
status: number;
|
|
3
|
-
detail: string;
|
|
4
|
-
retry_after_seconds?: number;
|
|
5
|
-
}
|
|
6
|
-
declare class ApiClient {
|
|
7
|
-
request<T>(method: string, path: string, body?: unknown): Promise<T>;
|
|
8
|
-
postUnauthed<T>(path: string, body: unknown): Promise<T>;
|
|
9
|
-
get<T>(path: string): Promise<T>;
|
|
10
|
-
post<T>(path: string, body: unknown): Promise<T>;
|
|
11
|
-
put<T>(path: string, body: unknown): Promise<T>;
|
|
12
|
-
delete<T>(path: string): Promise<T>;
|
|
13
|
-
private _fetch;
|
|
14
|
-
}
|
|
15
|
-
export declare const apiClient: ApiClient;
|
|
16
|
-
export {};
|
package/dist/api/client.js
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { getValidIdToken } from "../auth/token.js";
|
|
2
|
-
import { getApiBaseUrl } from "../config.js";
|
|
3
|
-
const REQUEST_TIMEOUT_MS = 30_000;
|
|
4
|
-
class ApiClient {
|
|
5
|
-
async request(method, path, body) {
|
|
6
|
-
const { id_token } = await getValidIdToken();
|
|
7
|
-
return this._fetch(method, path, body, {
|
|
8
|
-
Authorization: `Bearer ${id_token}`,
|
|
9
|
-
});
|
|
10
|
-
}
|
|
11
|
-
async postUnauthed(path, body) {
|
|
12
|
-
return this._fetch("POST", path, body);
|
|
13
|
-
}
|
|
14
|
-
async get(path) {
|
|
15
|
-
return this.request("GET", path);
|
|
16
|
-
}
|
|
17
|
-
async post(path, body) {
|
|
18
|
-
return this.request("POST", path, body);
|
|
19
|
-
}
|
|
20
|
-
async put(path, body) {
|
|
21
|
-
return this.request("PUT", path, body);
|
|
22
|
-
}
|
|
23
|
-
async delete(path) {
|
|
24
|
-
return this.request("DELETE", path);
|
|
25
|
-
}
|
|
26
|
-
async _fetch(method, path, body, extraHeaders) {
|
|
27
|
-
const url = `${getApiBaseUrl()}${path}`;
|
|
28
|
-
const headers = {
|
|
29
|
-
"Content-Type": "application/json",
|
|
30
|
-
"X-Graphit-Source": "cli",
|
|
31
|
-
...extraHeaders,
|
|
32
|
-
};
|
|
33
|
-
const resp = await fetch(url, {
|
|
34
|
-
method,
|
|
35
|
-
headers,
|
|
36
|
-
body: body ? JSON.stringify(body) : undefined,
|
|
37
|
-
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
|
|
38
|
-
});
|
|
39
|
-
if (!resp.ok) {
|
|
40
|
-
let detail = `HTTP ${resp.status}`;
|
|
41
|
-
try {
|
|
42
|
-
const errBody = (await resp.json());
|
|
43
|
-
detail = errBody.detail || detail;
|
|
44
|
-
if (resp.status === 429) {
|
|
45
|
-
const retryAfter = parseInt(resp.headers.get("Retry-After") || "60", 10);
|
|
46
|
-
const err = {
|
|
47
|
-
status: 429,
|
|
48
|
-
detail,
|
|
49
|
-
retry_after_seconds: retryAfter,
|
|
50
|
-
};
|
|
51
|
-
throw err;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
catch (e) {
|
|
55
|
-
if (e.status === 429)
|
|
56
|
-
throw e;
|
|
57
|
-
}
|
|
58
|
-
const err = { status: resp.status, detail };
|
|
59
|
-
throw err;
|
|
60
|
-
}
|
|
61
|
-
if (resp.status === 204)
|
|
62
|
-
return undefined;
|
|
63
|
-
return (await resp.json());
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
export const apiClient = new ApiClient();
|
|
67
|
-
//# sourceMappingURL=client.js.map
|
package/dist/api/client.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export interface StoredCredentials {
|
|
2
|
-
refresh_token: string;
|
|
3
|
-
user_id: string;
|
|
4
|
-
email: string;
|
|
5
|
-
org_id: string;
|
|
6
|
-
org_name: string;
|
|
7
|
-
seat_type: string;
|
|
8
|
-
created_at: string;
|
|
9
|
-
id_token?: string;
|
|
10
|
-
id_token_expiry?: number;
|
|
11
|
-
}
|
|
12
|
-
export declare function getCredentialsPath(): string;
|
|
13
|
-
export declare function readCredentials(): Promise<StoredCredentials | null>;
|
|
14
|
-
export declare function writeCredentials(creds: StoredCredentials): Promise<void>;
|
|
15
|
-
export declare function deleteCredentials(): Promise<void>;
|