@graphit/cli 0.2.42 → 0.2.50

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.
Files changed (33) hide show
  1. package/.claude-plugin/marketplace.json +3 -3
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.codex-plugin/plugin.json +1 -1
  4. package/bin/graphit +1 -1
  5. package/bin/graphit.ps1 +1 -1
  6. package/dist/api/client.d.ts +18 -0
  7. package/dist/api/client.js +88 -36
  8. package/dist/api/client.js.map +1 -1
  9. package/dist/commands/dashboard.js +26 -0
  10. package/dist/commands/dashboard.js.map +1 -1
  11. package/dist/commands/ds.js +39 -7
  12. package/dist/commands/ds.js.map +1 -1
  13. package/dist/commands/kb-constraints.d.ts +14 -0
  14. package/dist/commands/kb-constraints.js +53 -0
  15. package/dist/commands/kb-constraints.js.map +1 -0
  16. package/dist/commands/kb.js +65 -35
  17. package/dist/commands/kb.js.map +1 -1
  18. package/dist/commands/query.js +1 -1
  19. package/dist/commands/query.js.map +1 -1
  20. package/package.json +1 -1
  21. package/skills/graphit/SKILL.md +7 -4
  22. package/skills/graphit/VERSION.json +1 -1
  23. package/skills/graphit/references/dashboard-planning.md +1 -1
  24. package/skills/graphit/references/data-sources.md +3 -1
  25. package/skills/graphit/references/filters-advanced.md +2 -2
  26. package/skills/graphit/references/filters.md +2 -2
  27. package/skills/graphit/references/governance.md +2 -2
  28. package/skills/graphit/references/kb-discovery.md +2 -0
  29. package/skills/graphit/references/kb-traversal.md +1 -1
  30. package/skills/graphit/references/parameterized-metrics.md +1 -1
  31. package/skills/graphit/references/presentations.md +2 -2
  32. package/skills/graphit/references/runtime.md +13 -9
  33. package/skills/graphit/references/sql-reference.md +1 -1
@@ -1,9 +1,9 @@
1
1
  <!--
2
2
  SIZE EXEMPTION (reference file)
3
3
  Hard limit: 7,168 chars | Exempted ceiling: 14,336 chars
4
- Current: 12,478 chars (content) - intentionally over the base reference limit.
4
+ Current: ~12,990 chars (content) - intentionally over the base reference limit.
5
5
  Rationale: runtime.md is the consolidated build-time data + entity contract. Its core - the live-data API, the data-graphit-* entity contract, the first-paint loading state, the helper index, and the canonical example - is a single co-load unit: building one live element needs all of it together, so by the co-load test (split a reference only where the agent needs one part without the other) it cannot be split without creating refs that always load together, which the test forbids. The one use-case-clean seam (cache-friendly resolve SQL + the rate-limit budget, needed only for interactive or large dashboards) was deliberately kept inline to preserve the single authoritative contract. This ref loads only on HTML-deliverable turns (just-in-time, not every turn), so the cache cost is bounded.
6
- Reviewed: 2026-06-17
6
+ Reviewed: 2026-06-23
7
7
  Next review: 2026-09-17
8
8
  -->
9
9
  # Canvas Runtime: Live Data and the Entity Contract
@@ -27,15 +27,17 @@ The iframe provides `graphit.resolve()` to fetch live data from cached data sour
27
27
  ```js
28
28
  const result = await graphit.resolve({
29
29
  sql: "SELECT region, SUM(revenue) AS rev FROM ORDERS_DS GROUP BY region",
30
- dataSourceId: "ds_abc123",
30
+ dataSourceId: "ORDERS_DS",
31
31
  target: "#chart-container",
32
32
  maxRows: 10000
33
33
  });
34
34
  // Returns: { columns: string[], data: object[], rowCount: number, truncated: boolean }
35
35
  ```
36
36
 
37
- - `dataSourceId` is the ID from `graphit ds list`.
37
+ - `dataSourceId` is the data source name (the same table you SELECT FROM); its id or a unique id-prefix also works.
38
38
  - `target` (optional, a CSS selector or element) shows a blur and spinner overlay while loading and removes it on completion.
39
+ - `targetEntityIds` (optional, `string[]`) - the `data-graphit-id`s of OTHER graphs this one result also renders into; the platform records the live filtered query for each so their details panels reflect filters, not just the `target` graph.
40
+ - `sourceEntityId` (optional) - the `data-graphit-id` of the graph that owns this query, for a `target`-less resolve that feeds several graphs (pair with `targetEntityIds`).
39
41
  - `maxRows` (optional) defaults to **10,000 rows** and may be raised up to a cap of **50,000 rows**. A dashboard query should aggregate to a chartable grain well under the default; reach for a higher value only for a genuine row-level export, and never above the cap.
40
42
  - `result.data` is an array of row objects you render however you want.
41
43
 
@@ -51,7 +53,7 @@ Every visible element - chart, KPI card, table, text section - must be wrapped s
51
53
  <div data-graphit-id="revenue-trend"
52
54
  data-graphit-label="Revenue Trend"
53
55
  data-graphit-sql="SELECT {{dim:REGION}} AS region, {{metric:REVENUE}} AS revenue FROM ORDERS_DS GROUP BY region"
54
- data-graphit-ds="ds_abc123">
56
+ data-graphit-ds="ORDERS_DS">
55
57
  <!-- chart, KPI, or table content here -->
56
58
  </div>
57
59
  ```
@@ -61,7 +63,7 @@ Every visible element - chart, KPI card, table, text section - must be wrapped s
61
63
  | `data-graphit-id` | Unique kebab-case | `"spend-by-source"` |
62
64
  | `data-graphit-label` | Human-readable name | `"Ad Spend by Source"` |
63
65
  | `data-graphit-sql` | Executable SQL (HTML-encode the characters `<`, `>`, `&`, `"`) | `"SELECT ..."` |
64
- | `data-graphit-ds` | Data source ID from `graphit ds list` | `"ds_abc123"` |
66
+ | `data-graphit-ds` | Data source name (same as the FROM table) or id | `"ORDERS_DS"` |
65
67
 
66
68
  KB asset references are derived automatically from `{{metric:X}}` / `{{dim:X}}` templates in the SQL; the governance compiler resolves these and shows KB asset chips in the entity details panel. Missing any one attribute breaks the entity; missing the wrapper entirely makes the element invisible to the platform.
67
69
 
@@ -72,6 +74,8 @@ KB asset references are derived automatically from `{{metric:X}}` / `{{dim:X}}`
72
74
 
73
75
  **Label equals the visible title.** The `data-graphit-label` MUST match the card's visible heading exactly. Users find their chart by that label in @ mention dropdowns and entity panels - a mismatch means they cannot find it.
74
76
 
77
+ **Editing one existing entity.** Edit a single element surgically rather than rewriting the page: `graphit dashboard list-entities <id>` lists every entity (id, label, KB refs, data source) to find the right `data-graphit-id`; `graphit dashboard get-entity <id> <entityId>` returns just that entity's inner HTML - the exact fragment `graphit dashboard update-entity <id> <entityId>` accepts - which you change and write back. Reach for full-page `get-html` / `update-html` only when restructuring the whole layout.
78
+
75
79
  ## First-paint loading state
76
80
 
77
81
  The dashboard HTML paints before the SDK connects (iframe load plus handshake), so the SDK's own spinner cannot cover the first moments. Bake a pure-CSS overlay into the HTML so every chart shows a spinner from the first frame; the SDK adopts that overlay and removes it when the element's `graphit.resolve()` settles (success or error).
@@ -123,7 +127,7 @@ A resolve query that follows these shapes serves from a semantic cache in roughl
123
127
 
124
128
  - **Single refresh function.** Put all queries in ONE `Promise.all` inside one `refresh()` function so they share the same time window. NEVER scatter `graphit.resolve()` across independent event handlers or timeouts - that turns one user action into several bursts.
125
129
  - **Count queries per interaction.** 6 charts is 6 requests per filter change, about 20 changes per minute of budget; 12 charts is about 10 changes per minute. With 10 or more charts and 3 or more filters, debounce filter changes (300ms) so rapid clicks do not each trigger a full refresh.
126
- - **Reuse trend data for KPIs.** If you already fetch a weekly time series, derive the KPI total and its sparkline from that result in JS instead of running a separate aggregate query - one query serves both.
130
+ - **Reuse trend data for KPIs.** If you already fetch a weekly time series, derive the KPI total and its sparkline from that result in JS instead of running a separate aggregate query - one query serves both. When one result serves several graphs like this, anchor every graph it feeds with `targetEntityIds` (keep `target` on the primary) so each graph's details panel shows the live filtered query, not stale base SQL.
127
131
  - **Avoid redundant refreshes.** If a filter affects only some charts, split into targeted refresh functions (`refreshKPIs()`, `refreshCharts()`) so unchanged sections do not re-query.
128
132
  - **No polling.** NEVER use `setInterval(refresh, ...)`. Data sources update on their own schedule; a polling dashboard burns the entire budget.
129
133
 
@@ -151,7 +155,7 @@ You have full creative freedom: build charts with inline SVG, CSS, and HTML tabl
151
155
  <div data-graphit-id="spend-by-source"
152
156
  data-graphit-label="Ad Spend by Source"
153
157
  data-graphit-sql="SELECT {{dim:MEDIA_SOURCE_DIMENSION}} AS source, {{metric:TOTAL_AD_SPEND}} AS spend FROM MARKETING_UA_DS GROUP BY source ORDER BY spend DESC"
154
- data-graphit-ds="ds_abc123">
158
+ data-graphit-ds="MARKETING_UA_DS">
155
159
  <div id="spend-chart" class="gh-loading">
156
160
  <!-- gh-loading-overlay spinner from the First-paint section -->
157
161
  </div>
@@ -160,7 +164,7 @@ You have full creative freedom: build charts with inline SVG, CSS, and HTML tabl
160
164
  (async function() {
161
165
  var r = await graphit.resolve({
162
166
  sql: "SELECT MEDIA_SOURCE, SUM(APPSFLYER_COST) AS spend FROM MARKETING_UA_DS GROUP BY MEDIA_SOURCE ORDER BY spend DESC",
163
- dataSourceId: "ds_abc123",
167
+ dataSourceId: "MARKETING_UA_DS",
164
168
  target: "#spend-chart"
165
169
  });
166
170
  graphit.chart("#spend-chart", {
@@ -117,7 +117,7 @@ When the query feeds a canvas `graphit.resolve()` call, write it in the cache-fr
117
117
 
118
118
  ## Data source routing
119
119
 
120
- Always prefer a cached data source (`graphit query "SQL" --ds <id>`, roughly 100ms via DuckDB) over a live warehouse query (`graphit query "SQL" --warehouse --connection <id>`, roughly 10s via Snowflake). The full routing table, the `ds list` output template, and the source-shape guidance live in `data-sources.md`.
120
+ Always prefer a cached data source (`graphit query "SQL" --ds <NAME>`, roughly 100ms via DuckDB) over a live warehouse query (`graphit query "SQL" --warehouse --connection <id>`, roughly 10s via Snowflake). Pass the data source name to `--ds` - the same name you SELECT FROM (a full id or unique id-prefix also works). The full routing table, the `ds list` output template, and the source-shape guidance live in `data-sources.md`.
121
121
 
122
122
  ## Percent scaling
123
123