dataface 0.4.1.dev224__py3-none-any.whl → 0.4.1.dev304__py3-none-any.whl

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 (288) hide show
  1. dataface/DATAFACE_SYNTAX.md +9 -9
  2. dataface/__init__.py +7 -7
  3. dataface/agent_api/__init__.py +23 -20
  4. dataface/agent_api/_init_templates/README.md +3 -3
  5. dataface/agent_api/_init_templates/guide.yaml +1 -1
  6. dataface/agent_api/_init_templates/meta.yaml +1 -1
  7. dataface/agent_api/_link_scan.py +7 -7
  8. dataface/agent_api/_paths.py +14 -14
  9. dataface/agent_api/board_artifact.py +3 -3
  10. dataface/agent_api/{dashboards.py → boards.py} +24 -24
  11. dataface/agent_api/cache.py +1 -1
  12. dataface/agent_api/data_paths.py +2 -3
  13. dataface/agent_api/describe.py +25 -17
  14. dataface/agent_api/docs/yaml-reference.md +16 -17
  15. dataface/agent_api/file_refs.py +1 -1
  16. dataface/agent_api/files.py +21 -21
  17. dataface/agent_api/init.py +11 -9
  18. dataface/agent_api/migrate.py +7 -6
  19. dataface/agent_api/pack.py +18 -17
  20. dataface/agent_api/project_session.py +11 -11
  21. dataface/agent_api/query.py +8 -8
  22. dataface/agent_api/search.py +31 -29
  23. dataface/agent_api/serve.py +2 -2
  24. dataface/agent_api/skills.py +1 -1
  25. dataface/agent_api/surface_aliases.yaml +27 -27
  26. dataface/agent_api/validate.py +40 -32
  27. dataface/ai/__init__.py +4 -13
  28. dataface/ai/agent.py +6 -6
  29. dataface/ai/context.py +10 -5
  30. dataface/ai/llm.py +77 -11
  31. dataface/ai/mcp/__init__.py +8 -8
  32. dataface/ai/mcp/server.py +16 -16
  33. dataface/ai/prompts.py +9 -9
  34. dataface/ai/skills/analyst-runbook/SKILL.md +5 -5
  35. dataface/ai/skills/{dashboard-build → board-build}/SKILL.md +21 -27
  36. dataface/ai/skills/{dashboard-design → board-design}/SKILL.md +6 -12
  37. dataface/ai/skills/{dashboard-pack-scaffolding → board-pack-scaffolding}/SKILL.md +14 -14
  38. dataface/ai/skills/{dashboard-replicate → board-replicate}/SKILL.md +7 -15
  39. dataface/ai/skills/{dashboard-review → board-review}/SKILL.md +10 -14
  40. dataface/ai/skills/{dashboard-structural-review → board-structural-review}/SKILL.md +10 -10
  41. dataface/ai/skills/{dashboard-visual-review → board-visual-review}/SKILL.md +8 -8
  42. dataface/ai/skills/data-exploration/SKILL.md +1 -1
  43. dataface/ai/skills/dataface-mcp-setup/SKILL.md +10 -10
  44. dataface/ai/skills/dataface-troubleshooting/SKILL.md +7 -7
  45. dataface/ai/skills/drill-down-link/SKILL.md +1 -1
  46. dataface/ai/skills/report-design/SKILL.md +3 -3
  47. dataface/ai/tool_schemas.py +36 -43
  48. dataface/ai/tools/__init__.py +26 -67
  49. dataface/cli/_error_format.py +3 -4
  50. dataface/cli/_extras.py +23 -10
  51. dataface/cli/_project.py +11 -10
  52. dataface/cli/commands/init.py +1 -1
  53. dataface/cli/commands/inspect.py +4 -3
  54. dataface/cli/commands/mcp_init.py +5 -5
  55. dataface/cli/commands/migrate.py +2 -2
  56. dataface/cli/commands/query.py +5 -5
  57. dataface/cli/commands/render.py +8 -8
  58. dataface/cli/commands/search.py +1 -1
  59. dataface/cli/commands/serve.py +3 -3
  60. dataface/cli/filesystem_project.py +7 -7
  61. dataface/cli/main.py +44 -44
  62. dataface/core/__init__.py +8 -8
  63. dataface/core/{dashboard.py → board.py} +36 -36
  64. dataface/core/compile/__init__.py +16 -16
  65. dataface/core/compile/authoring_warnings.py +1 -1
  66. dataface/core/compile/board_artifact.py +11 -11
  67. dataface/core/compile/chart_focus.py +5 -5
  68. dataface/core/compile/compiler.py +94 -89
  69. dataface/core/compile/config.py +36 -37
  70. dataface/core/compile/data_table.py +31 -1
  71. dataface/core/compile/face_warnings.py +11 -11
  72. dataface/core/compile/introspection.py +9 -9
  73. dataface/core/compile/markdown.py +3 -3
  74. dataface/core/compile/merge.py +68 -35
  75. dataface/core/compile/meta.py +6 -6
  76. dataface/core/compile/migrations/__init__.py +2 -0
  77. dataface/core/compile/migrations/migrations.py +459 -50
  78. dataface/core/compile/migrations/versions/__init__.py +0 -16
  79. dataface/core/compile/migrations/versions/current.py +29 -0
  80. dataface/core/compile/migrations/versions/v0_4_0.py +2 -2
  81. dataface/core/compile/migrations/versions/v0_5_0.py +40 -0
  82. dataface/core/compile/models/{face → board}/authored.py +20 -20
  83. dataface/core/compile/models/{face → board}/normalized.py +45 -43
  84. dataface/core/compile/models/{face → board}/patch.py +8 -8
  85. dataface/core/compile/models/{face → board}/resolved.py +9 -9
  86. dataface/core/compile/models/cache.py +2 -2
  87. dataface/core/compile/models/chart/resolved/_base.py +2 -2
  88. dataface/core/compile/models/chart/resolved/_channel.py +1 -1
  89. dataface/core/compile/models/config.py +7 -7
  90. dataface/core/compile/models/primitives.py +10 -10
  91. dataface/core/compile/models/query/authored.py +2 -2
  92. dataface/core/compile/models/refs.py +3 -3
  93. dataface/core/compile/models/source.py +3 -3
  94. dataface/core/compile/models/style/authored/table.py +1 -1
  95. dataface/core/compile/models/style/context.py +20 -16
  96. dataface/core/compile/models/style/resolved/__init__.py +9 -52
  97. dataface/core/compile/models/style/resolved/_base.py +2 -3
  98. dataface/core/compile/models/style/resolved/_marks.py +3 -2
  99. dataface/core/compile/models/style/theme/board.py +4 -4
  100. dataface/core/compile/models/style/theme/legend.py +0 -3
  101. dataface/core/compile/models/style/theme/style.py +1 -1
  102. dataface/core/compile/normalize_charts.py +5 -5
  103. dataface/core/compile/normalize_layout.py +35 -35
  104. dataface/core/compile/normalize_queries.py +4 -4
  105. dataface/core/compile/normalize_variables.py +13 -13
  106. dataface/core/compile/normalizer.py +46 -48
  107. dataface/core/compile/parser.py +15 -15
  108. dataface/core/compile/resolve/__init__.py +9 -32
  109. dataface/core/compile/resolve/chart/__init__.py +56 -0
  110. dataface/core/compile/resolve/{_axes.py → chart/_axes.py} +119 -36
  111. dataface/core/compile/resolve/{_channels.py → chart/_channels.py} +8 -8
  112. dataface/core/compile/resolve/{_dispatch.py → chart/_dispatch.py} +11 -11
  113. dataface/core/compile/resolve/{_domain.py → chart/_domain.py} +40 -29
  114. dataface/core/compile/resolve/{_kwargs.py → chart/_kwargs.py} +3 -6
  115. dataface/core/compile/resolve/{_layers.py → chart/_layers.py} +3 -3
  116. dataface/core/compile/resolve/{_links.py → chart/_links.py} +1 -1
  117. dataface/core/compile/resolve/{_marks.py → chart/_marks.py} +1 -3
  118. dataface/core/compile/resolve/{_palette.py → chart/_palette.py} +7 -5
  119. dataface/core/compile/resolve/{_table.py → chart/_table.py} +7 -9
  120. dataface/core/compile/resolve/{adaptive_stroke.py → chart/adaptive_stroke.py} +1 -1
  121. dataface/core/compile/resolve/{area.py → chart/area.py} +44 -28
  122. dataface/core/compile/resolve/{bar.py → chart/bar.py} +69 -21
  123. dataface/core/compile/resolve/{geo.py → chart/geo.py} +5 -5
  124. dataface/core/compile/resolve/{heatmap.py → chart/heatmap.py} +21 -19
  125. dataface/core/compile/resolve/{line.py → chart/line.py} +106 -49
  126. dataface/core/compile/resolve/{pie.py → chart/pie.py} +9 -9
  127. dataface/core/compile/resolve/{pie_attachment.py → chart/pie_attachment.py} +7 -7
  128. dataface/core/compile/resolve/{scatter.py → chart/scatter.py} +14 -11
  129. dataface/core/compile/resolve/{simple.py → chart/simple.py} +7 -10
  130. dataface/core/compile/resolve/style/__init__.py +49 -0
  131. dataface/core/compile/resolve/style/axis_cascade.py +943 -0
  132. dataface/core/compile/resolve/style/board.py +524 -0
  133. dataface/core/compile/{style_cascade.py → resolve/style/chart_context.py} +10 -451
  134. dataface/core/compile/{inherit_graph.py → resolve/style/inherit_graph.py} +2 -2
  135. dataface/core/compile/{inherit_resolver.py → resolve/style/inherit_resolver.py} +1 -1
  136. dataface/core/compile/resolve/style/scale.py +183 -0
  137. dataface/core/compile/resolve/style/tokens.py +298 -0
  138. dataface/core/compile/{typography.py → resolve/style/typography.py} +4 -4
  139. dataface/core/compile/schema_renderers/board_resolved.py +11 -11
  140. dataface/core/compile/schema_renderers/highlight_manifest.py +2 -2
  141. dataface/core/compile/schema_renderers/prompt.py +3 -3
  142. dataface/core/compile/schema_renderers/textmate_grammar.py +1 -1
  143. dataface/core/compile/schema_renderers/vscode_schema.py +4 -2
  144. dataface/core/compile/schema_renderers/yaml_schema.py +3 -3
  145. dataface/core/compile/schema_renderers/yaml_schema_catalog.py +20 -2
  146. dataface/core/compile/single_series_allocation.py +8 -8
  147. dataface/core/compile/sizing.py +6 -6
  148. dataface/core/compile/source_map.py +1 -1
  149. dataface/core/compile/validate_formats.py +6 -6
  150. dataface/core/compile/validator.py +23 -23
  151. dataface/core/compile/variables.py +1 -1
  152. dataface/core/compile/vega_lite/mapping.py +6 -8
  153. dataface/core/compile/yaml_error_formatter.py +14 -4
  154. dataface/core/compile/yaml_patch.py +5 -5
  155. dataface/core/defaults/default_config.yml +6 -6
  156. dataface/core/defaults/themes/_base.yaml +0 -6
  157. dataface/core/defaults/themes/editorial.yaml +1 -1
  158. dataface/core/defaults/themes/stark.yaml +1 -1
  159. dataface/core/diagnostics/__init__.py +2 -0
  160. dataface/core/diagnostics/codes_compile.py +15 -15
  161. dataface/core/diagnostics/codes_execute.py +5 -5
  162. dataface/core/diagnostics/codes_render.py +32 -3
  163. dataface/core/diagnostics/execution.py +1 -1
  164. dataface/core/diagnostics/suppression.py +3 -3
  165. dataface/core/execute/__init__.py +2 -2
  166. dataface/core/execute/_duckdb_cache_base.py +26 -9
  167. dataface/core/execute/adapters/adapter_registry.py +5 -5
  168. dataface/core/execute/adapters/base.py +1 -1
  169. dataface/core/execute/adapters/dbt_adapter.py +1 -1
  170. dataface/core/execute/adapters/duckdb_adapter.py +2 -2
  171. dataface/core/execute/adapters/http_adapter.py +1 -1
  172. dataface/core/execute/adapters/schema_adapter.py +1 -1
  173. dataface/core/execute/adapters/sql_adapter.py +2 -2
  174. dataface/core/execute/adapters/sqlite_adapter.py +4 -3
  175. dataface/core/execute/adapters/values_adapter.py +1 -1
  176. dataface/core/execute/cache_backend.py +4 -4
  177. dataface/core/execute/chart_data_provider.py +1 -1
  178. dataface/core/execute/chart_resolution.py +9 -2
  179. dataface/core/execute/collect.py +4 -4
  180. dataface/core/execute/duckdb_cache.py +3 -3
  181. dataface/core/execute/executor.py +9 -9
  182. dataface/core/execute/file_source_materializer.py +1 -1
  183. dataface/core/execute/parallel.py +1 -1
  184. dataface/core/execute/recording.py +4 -4
  185. dataface/core/execute/replay_provider.py +1 -1
  186. dataface/core/execute/source_resolver.py +2 -2
  187. dataface/core/execute/trivial_local_cache.py +3 -3
  188. dataface/core/fonts.py +74 -17
  189. dataface/core/inspect/renderer.py +1 -1
  190. dataface/core/inspect/resolver.py +2 -3
  191. dataface/core/numeric.py +1 -1
  192. dataface/core/pack/models.py +8 -8
  193. dataface/core/pack/planner.py +8 -7
  194. dataface/core/project.py +32 -16
  195. dataface/core/project_roots.py +10 -8
  196. dataface/core/registered_views/expander.py +9 -9
  197. dataface/core/registered_views/query_runner.py +1 -1
  198. dataface/core/registered_views/render_pipeline.py +13 -13
  199. dataface/core/registered_views/variable_planner.py +3 -3
  200. dataface/core/render/__init__.py +3 -3
  201. dataface/core/render/board_replay.py +8 -8
  202. dataface/core/render/chart/auto_link.py +5 -5
  203. dataface/core/render/chart/emitters/_cartesian.py +60 -20
  204. dataface/core/render/chart/emitters/_channels.py +1 -1
  205. dataface/core/render/chart/emitters/_measured_label_padding.py +1 -1
  206. dataface/core/render/chart/emitters/_overlay.py +86 -30
  207. dataface/core/render/chart/emitters/area.py +9 -0
  208. dataface/core/render/chart/emitters/bar.py +31 -3
  209. dataface/core/render/chart/emitters/line.py +13 -2
  210. dataface/core/render/chart/emitters/pie.py +3 -3
  211. dataface/core/render/chart/emitters/scatter.py +8 -10
  212. dataface/core/render/chart/features/__init__.py +0 -3
  213. dataface/core/render/chart/features/endpoint_labels.py +269 -9
  214. dataface/core/render/chart/features/mirror_axis.py +1 -1
  215. dataface/core/render/chart/features/value_labels.py +1 -1
  216. dataface/core/render/chart/rendering.py +15 -15
  217. dataface/core/render/chart/spec.py +1 -5
  218. dataface/core/render/chart/table.py +313 -69
  219. dataface/core/render/chart/table_overflow.py +1 -1
  220. dataface/core/render/chart/table_static_pagination.py +79 -0
  221. dataface/core/render/chart/table_support.py +1 -1
  222. dataface/core/render/chart/translate.py +2 -86
  223. dataface/core/render/chart/type_inference.py +1 -1
  224. dataface/core/render/chart/validation.py +6 -2
  225. dataface/core/render/chart/vega_lite.py +17 -3
  226. dataface/core/render/chart/vl_field_maps.py +16 -1
  227. dataface/core/render/column_packer.py +1 -1
  228. dataface/core/render/converters/chart.py +7 -0
  229. dataface/core/render/data_format.py +7 -7
  230. dataface/core/render/dir_context.py +12 -12
  231. dataface/core/render/face_resolve.py +169 -58
  232. dataface/core/render/face_to_dict.py +7 -7
  233. dataface/core/render/faces.py +18 -18
  234. dataface/core/render/fonts/NotoEmoji-Regular.ttf +0 -0
  235. dataface/core/render/fonts/NotoEmoji-Regular.woff2 +0 -0
  236. dataface/core/render/fonts/_font_face.css +14 -16
  237. dataface/core/render/json_format.py +3 -3
  238. dataface/core/render/layout_sizing.py +41 -26
  239. dataface/core/render/layouts.py +12 -13
  240. dataface/core/render/prose.py +1 -1
  241. dataface/core/render/renderer.py +116 -55
  242. dataface/core/render/sizing.py +206 -80
  243. dataface/core/render/svg_utils.py +3 -3
  244. dataface/core/render/templates/scripts/table_pagination.js +42 -0
  245. dataface/core/render/templates/svg/styles.css +1 -1
  246. dataface/core/render/terminal.py +7 -7
  247. dataface/core/render/terminal_charts.py +1 -1
  248. dataface/core/render/terminal_layouts.py +1 -1
  249. dataface/core/render/text_format.py +4 -4
  250. dataface/core/render/variables_resolve.py +2 -2
  251. dataface/core/render/warnings/base.py +12 -3
  252. dataface/core/render/warnings/facet_panel_width_below_minimum.py +1 -1
  253. dataface/core/render/warnings/palette_unsupported.py +2 -2
  254. dataface/core/render/warnings/registry.py +40 -8
  255. dataface/core/render/warnings/static_pagination_capped.py +37 -0
  256. dataface/core/render/yaml_format.py +4 -4
  257. dataface/core/render_format.py +2 -2
  258. dataface/core/serve/alias_index.py +18 -18
  259. dataface/core/serve/port.py +9 -7
  260. dataface/core/serve/server.py +66 -65
  261. dataface/core/utils.py +45 -0
  262. dataface/data/schemas/board-resolved/board-resolved.schema.json +233 -252
  263. dataface/data/schemas/yaml/0.5.0.json +1 -0
  264. dataface/data/schemas/yaml/manifest.json +7 -0
  265. dataface/integrations/markdown.py +16 -11
  266. {dataface-0.4.1.dev224.dist-info → dataface-0.4.1.dev304.dist-info}/METADATA +11 -11
  267. {dataface-0.4.1.dev224.dist-info → dataface-0.4.1.dev304.dist-info}/RECORD +281 -276
  268. dataface/core/compile/chart_update.py +0 -205
  269. dataface/core/compile/models/style/resolved/_cascade.py +0 -1440
  270. dataface/core/compile/vega_config.py +0 -39
  271. dataface/core/render/chart/features/legend_toggle.py +0 -43
  272. dataface/core/render/fonts/NOTO_COLOR_EMOJI_LICENSE.txt +0 -93
  273. dataface/core/render/fonts/NotoColorEmoji-Regular.ttf +0 -0
  274. dataface/core/render/fonts/NotoColorEmoji-Regular.woff2 +0 -0
  275. /dataface/agent_api/_init_templates/{dataface.yml → dbt_charts.yml} +0 -0
  276. /dataface/ai/skills/{dashboard-build → board-build}/examples/_smoke.yml +0 -0
  277. /dataface/core/compile/models/{face → board}/__init__.py +0 -0
  278. /dataface/core/compile/resolve/{_chart_rows.py → chart/_chart_rows.py} +0 -0
  279. /dataface/core/compile/{channel.py → resolve/chart/channel.py} +0 -0
  280. /dataface/core/compile/{enrich.py → resolve/chart/enrich.py} +0 -0
  281. /dataface/core/compile/{label_data.py → resolve/chart/label_data.py} +0 -0
  282. /dataface/core/compile/{link_keys.py → resolve/chart/link_keys.py} +0 -0
  283. /dataface/core/compile/{tick_values.py → resolve/chart/tick_values.py} +0 -0
  284. /dataface/core/compile/{inherit_registry.yaml → resolve/style/inherit_registry.yaml} +0 -0
  285. /dataface/core/compile/{palette.py → resolve/style/palette.py} +0 -0
  286. {dataface-0.4.1.dev224.dist-info → dataface-0.4.1.dev304.dist-info}/WHEEL +0 -0
  287. {dataface-0.4.1.dev224.dist-info → dataface-0.4.1.dev304.dist-info}/entry_points.txt +0 -0
  288. {dataface-0.4.1.dev224.dist-info → dataface-0.4.1.dev304.dist-info}/licenses/LICENSE +0 -0
@@ -11,7 +11,7 @@ Dataface workflow — from a dbt project to a running dashboard.
11
11
  ### Step 1 — Validate your YAML
12
12
 
13
13
  ```bash
14
- dft validate faces/my_dashboard.yml
14
+ dft validate charts/my_dashboard.yml
15
15
  ```
16
16
 
17
17
  `dft validate` performs YAML schema + cross-reference validation. It checks that every field, chart reference, query name, and variable is correctly structured. **No database connection is required.**
@@ -62,8 +62,8 @@ rows:
62
62
  Then validate and render:
63
63
 
64
64
  ```bash
65
- dft validate faces/my_dashboard.yml
66
- dft render faces/my_dashboard.yml
65
+ dft validate charts/my_dashboard.yml
66
+ dft render charts/my_dashboard.yml
67
67
  ```
68
68
 
69
69
  Add each additional chart after the previous one validates and renders cleanly.
@@ -189,7 +189,7 @@ title: "Sales Overview"
189
189
  description: "Monthly KPIs and trend"
190
190
  tags: [sales, weekly]
191
191
 
192
- source: my_profile # Default source (a name from dataface.yml's sources: registry)
192
+ source: my_profile # Default source (a name from dbt_charts.yml's sources: registry)
193
193
 
194
194
  variables: # Optional — interactive controls
195
195
  queries: # Named queries
@@ -220,7 +220,7 @@ Top-level fields (22 total):
220
220
  | `description` | string | Description text |
221
221
  | `tags` | list[string] | Tags for categorization/search |
222
222
  | `text` | string | Markdown body for text-only faces |
223
- | `source` | string | Default source name for every query below (from `dataface.yml`'s `sources:` registry), or an inline file path for a single colocated CSV/JSON/Parquet file. Inheritable via the `meta.yaml` cascade. |
223
+ | `source` | string | Default source name for every query below (from `dbt_charts.yml`'s `sources:` registry), or an inline file path for a single colocated CSV/JSON/Parquet file. Inheritable via the `meta.yaml` cascade. |
224
224
  | `variables` | object | See [Variables](#variables) |
225
225
  | `queries` | object | See [Queries](#queries) |
226
226
  | `charts` | object | See [Charts](#charts) |
@@ -265,7 +265,7 @@ query param of the same name — which the face then reads as its variable. Thi
265
265
  gives a single detail face a clean per-entity URL:
266
266
 
267
267
  ```yaml
268
- # faces/milestone.yml (canonical URL: /milestone)
268
+ # charts/milestone.yml (canonical URL: /milestone)
269
269
  aliases:
270
270
  - /milestones/<name>
271
271
  variables:
@@ -284,7 +284,7 @@ and `milestone.yml` renders with `name` bound to `m3-public-launch`.
284
284
  treated as patterns.
285
285
 
286
286
  There are two ways to override a data/inspector route for a given path:
287
- - **Face file at that path** — create `faces/data/warehouse/schema/table.yml` and the server renders it directly (no redirect).
287
+ - **Face file at that path** — create `charts/data/warehouse/schema/table.yml` and the server renders it directly (no redirect).
288
288
  - **`aliases:` entry** — any face can declare `/data/…/` as an alias; the server issues a 302 to the declaring face's canonical URL.
289
289
 
290
290
  Both approaches work. A face file wins without a redirect round-trip; an alias lets a face live anywhere and still capture a system-view URL.
@@ -411,7 +411,7 @@ Common fields (all query types):
411
411
  | Field | Description |
412
412
  |-------|-------------|
413
413
  | `description` | Metadata sentence for AI search and tooltips |
414
- | `source` | Source name (from `dataface.yml`'s `sources:` registry), or an inline file path (`./data/x.csv`) for a single colocated CSV/JSON/Parquet. An inline connection dict (`{type: postgres, ...}`) is rejected — reference a named source instead. Not accepted on `http` queries. |
414
+ | `source` | Source name (from `dbt_charts.yml`'s `sources:` registry), or an inline file path (`./data/x.csv`) for a single colocated CSV/JSON/Parquet. An inline connection dict (`{type: postgres, ...}`) is rejected — reference a named source instead. Not accepted on `http` queries. |
415
415
  | `target` | dbt target name (defaults to `dev`) |
416
416
  | `filters` | Post-execution result filters |
417
417
  | `limit` | Maximum rows returned |
@@ -424,7 +424,7 @@ HTTP fields: `url`, `method`, `headers`, `params`, `body`, `json_path`.
424
424
  dbt-model fields: `model`, `columns`.
425
425
  Inline-values fields: `columns`, `values` (or `rows` for record-shape).
426
426
 
427
- Connection source types (named in the project root `dataface.yml`'s `sources:`
427
+ Connection source types (named in the project root `dbt_charts.yml`'s `sources:`
428
428
  registry — never inline in a face): `postgres`, `snowflake`, `bigquery`,
429
429
  `redshift`, `mysql`, `duckdb`, `sqlite`, `csv`, `json`, `parquet`, `http`, `dbt_profile`.
430
430
  CSV/JSON/Parquet may instead be referenced inline as a `source:` file path
dataface/__init__.py CHANGED
@@ -16,7 +16,7 @@ Quick Start:
16
16
  >>> from dataface import compile, Executor, render
17
17
  >>> from dataface.core.execute.adapters import build_adapter_registry
18
18
  >>>
19
- >>> # Compile YAML to Face
19
+ >>> # Compile YAML to Board
20
20
  >>> result = compile(yaml_content)
21
21
  >>> if result.success:
22
22
  ... face = result.face
@@ -53,10 +53,10 @@ if TYPE_CHECKING:
53
53
  from dataface.core import validate as validate
54
54
  from dataface.core.compile import (
55
55
  AnyQuery as AnyQuery,
56
- AuthoredFace as AuthoredFace,
56
+ AuthoredBoard as AuthoredBoard,
57
+ Board as Board,
57
58
  CompilationError as CompilationError,
58
59
  CompileResult as CompileResult,
59
- Face as Face,
60
60
  Layout as Layout,
61
61
  LayoutItem as LayoutItem,
62
62
  Variable as Variable,
@@ -80,11 +80,11 @@ __all__ = [
80
80
  "compile",
81
81
  "compile_file",
82
82
  "CompileResult",
83
- "Face",
83
+ "Board",
84
84
  "AnyQuery",
85
85
  "Layout",
86
86
  "LayoutItem",
87
- "AuthoredFace",
87
+ "AuthoredBoard",
88
88
  "Variable",
89
89
  "CompilationError",
90
90
  # Execute
@@ -105,10 +105,10 @@ __all__ = [
105
105
  _LAZY_ATTRS: dict[str, tuple[str, str]] = {
106
106
  "validate": ("dataface.core", "validate"),
107
107
  "AnyQuery": ("dataface.core.compile", "AnyQuery"),
108
- "AuthoredFace": ("dataface.core.compile", "AuthoredFace"),
108
+ "AuthoredBoard": ("dataface.core.compile", "AuthoredBoard"),
109
109
  "CompilationError": ("dataface.core.compile", "CompilationError"),
110
110
  "CompileResult": ("dataface.core.compile", "CompileResult"),
111
- "Face": ("dataface.core.compile", "Face"),
111
+ "Board": ("dataface.core.compile", "Board"),
112
112
  "Layout": ("dataface.core.compile", "Layout"),
113
113
  "LayoutItem": ("dataface.core.compile", "LayoutItem"),
114
114
  "Variable": ("dataface.core.compile", "Variable"),
@@ -50,9 +50,9 @@ if TYPE_CHECKING:
50
50
  project_sources_for_face as project_sources_for_face,
51
51
  )
52
52
  from dataface.agent_api.describe import (
53
- DescribeFaceArgs as DescribeFaceArgs,
53
+ DescribeBoardArgs as DescribeBoardArgs,
54
54
  DescribeFaceResult as DescribeFaceResult,
55
- describe_face as describe_face,
55
+ describe_board as describe_board,
56
56
  )
57
57
  from dataface.agent_api.docs import (
58
58
  DocsArgs as DocsArgs,
@@ -72,15 +72,20 @@ if TYPE_CHECKING:
72
72
  from dataface.agent_api.project_session import ProjectSession as ProjectSession
73
73
  from dataface.agent_api.query import (
74
74
  QueryFaceResult as QueryFaceResult,
75
- query_face as query_face,
75
+ query_board as query_board,
76
76
  )
77
77
  from dataface.agent_api.schema_hints import SchemaHints as SchemaHints
78
78
  from dataface.agent_api.validate import (
79
- ValidateDashboardArgs as ValidateDashboardArgs,
79
+ ValidateBoardArgs as ValidateBoardArgs,
80
80
  ValidateResult as ValidateResult,
81
81
  )
82
82
  from dataface.agent_api.validate_query import QueryDiagnostic as QueryDiagnostic
83
83
  from dataface.core.attribution import set_surface as set_surface
84
+ from dataface.core.board import (
85
+ BoardRenderResult as BoardRenderResult,
86
+ RenderFormat as RenderFormat,
87
+ render_dashboard as render_dashboard,
88
+ )
84
89
  from dataface.core.compile.compiler import (
85
90
  CompileResult as CompileResult,
86
91
  compile as compile,
@@ -88,11 +93,6 @@ if TYPE_CHECKING:
88
93
  from dataface.core.compile.config import (
89
94
  ProjectSourcesConfig as ProjectSourcesConfig,
90
95
  )
91
- from dataface.core.dashboard import (
92
- RenderedDashboard as RenderedDashboard,
93
- RenderFormat as RenderFormat,
94
- render_dashboard as render_dashboard,
95
- )
96
96
  from dataface.core.diagnostics import Diagnostic as Diagnostic
97
97
  from dataface.core.execute.cache_backend import (
98
98
  QueryResultCache as QueryResultCache,
@@ -110,6 +110,7 @@ if TYPE_CHECKING:
110
110
  FaceFile as FaceFile,
111
111
  InMemoryFace as InMemoryFace,
112
112
  Project as Project,
113
+ posix_relpath as posix_relpath,
113
114
  )
114
115
  from dataface.core.render.board_links import LinkContext as LinkContext
115
116
  from dataface.core.render.errors import RenderError as RenderError
@@ -117,7 +118,7 @@ if TYPE_CHECKING:
117
118
  __all__ = [
118
119
  "compile",
119
120
  "CompileResult",
120
- "DescribeFaceArgs",
121
+ "DescribeBoardArgs",
121
122
  "DescribeFaceResult",
122
123
  "Diagnostic",
123
124
  "DocsArgs",
@@ -132,15 +133,16 @@ __all__ = [
132
133
  "Project",
133
134
  "ProjectSession",
134
135
  "set_surface",
136
+ "posix_relpath",
135
137
  "ProjectSourcesConfig",
136
138
  "QueryDiagnostic",
137
139
  "QueryFaceResult",
138
- "RenderedDashboard",
140
+ "BoardRenderResult",
139
141
  "RenderError",
140
142
  "RenderFormat",
141
143
  "SchemaHints",
142
144
  "Topic",
143
- "ValidateDashboardArgs",
145
+ "ValidateBoardArgs",
144
146
  "ValidateResult",
145
147
  # Execution extension seams
146
148
  "AllowlistedSourceResolver",
@@ -148,11 +150,11 @@ __all__ = [
148
150
  "QueryResultCache",
149
151
  "SourceResolver",
150
152
  "WarehouseObserver",
151
- "describe_face",
153
+ "describe_board",
152
154
  "get_fonts_dir",
153
155
  "init_project",
154
156
  "migrate_paths",
155
- "query_face",
157
+ "query_board",
156
158
  "render_dashboard",
157
159
  ]
158
160
 
@@ -177,9 +179,9 @@ _LAZY_ATTRS: dict[str, tuple[str, str]] = {
177
179
  "dataface.agent_api._paths",
178
180
  "project_sources_for_face",
179
181
  ),
180
- "DescribeFaceArgs": ("dataface.agent_api.describe", "DescribeFaceArgs"),
182
+ "DescribeBoardArgs": ("dataface.agent_api.describe", "DescribeBoardArgs"),
181
183
  "DescribeFaceResult": ("dataface.agent_api.describe", "DescribeFaceResult"),
182
- "describe_face": ("dataface.agent_api.describe", "describe_face"),
184
+ "describe_board": ("dataface.agent_api.describe", "describe_board"),
183
185
  "DocsArgs": ("dataface.agent_api.docs", "DocsArgs"),
184
186
  "DocsResult": ("dataface.agent_api.docs", "DocsResult"),
185
187
  "DocsSearchHit": ("dataface.agent_api.docs", "DocsSearchHit"),
@@ -191,18 +193,18 @@ _LAZY_ATTRS: dict[str, tuple[str, str]] = {
191
193
  "migrate_paths": ("dataface.agent_api.migrate", "migrate_paths"),
192
194
  "ProjectSession": ("dataface.agent_api.project_session", "ProjectSession"),
193
195
  "QueryFaceResult": ("dataface.agent_api.query", "QueryFaceResult"),
194
- "query_face": ("dataface.agent_api.query", "query_face"),
196
+ "query_board": ("dataface.agent_api.query", "query_board"),
195
197
  "SchemaHints": ("dataface.agent_api.schema_hints", "SchemaHints"),
196
- "ValidateDashboardArgs": ("dataface.agent_api.validate", "ValidateDashboardArgs"),
198
+ "ValidateBoardArgs": ("dataface.agent_api.validate", "ValidateBoardArgs"),
197
199
  "ValidateResult": ("dataface.agent_api.validate", "ValidateResult"),
198
200
  "QueryDiagnostic": ("dataface.agent_api.validate_query", "QueryDiagnostic"),
199
201
  "set_surface": ("dataface.core.attribution", "set_surface"),
200
202
  "compile": ("dataface.core.compile.compiler", "compile"),
201
203
  "CompileResult": ("dataface.core.compile.compiler", "CompileResult"),
202
204
  "ProjectSourcesConfig": ("dataface.core.compile.config", "ProjectSourcesConfig"),
203
- "RenderedDashboard": ("dataface.core.dashboard", "RenderedDashboard"),
205
+ "BoardRenderResult": ("dataface.core.board", "BoardRenderResult"),
204
206
  "RenderFormat": ("dataface.core.render_format", "RenderFormat"),
205
- "render_dashboard": ("dataface.core.dashboard", "render_dashboard"),
207
+ "render_dashboard": ("dataface.core.board", "render_dashboard"),
206
208
  "Diagnostic": ("dataface.core.diagnostics", "Diagnostic"),
207
209
  "QueryResultCache": ("dataface.core.execute.cache_backend", "QueryResultCache"),
208
210
  "WarehouseObserver": (
@@ -222,6 +224,7 @@ _LAZY_ATTRS: dict[str, tuple[str, str]] = {
222
224
  "FaceFile": ("dataface.core.project", "FaceFile"),
223
225
  "InMemoryFace": ("dataface.core.project", "InMemoryFace"),
224
226
  "Project": ("dataface.core.project", "Project"),
227
+ "posix_relpath": ("dataface.core.project", "posix_relpath"),
225
228
  "LinkContext": ("dataface.core.render.board_links", "LinkContext"),
226
229
  "RenderError": ("dataface.core.render.errors", "RenderError"),
227
230
  }
@@ -4,7 +4,7 @@ title: Dataface
4
4
 
5
5
  # Welcome to Dataface
6
6
 
7
- This is your project's landing page. Everything under `faces/` becomes a
7
+ This is your project's landing page. Everything under `charts/` becomes a
8
8
  served page — edit the files here to build dashboards, reports, and docs
9
9
  for your data project.
10
10
 
@@ -18,7 +18,7 @@ queries and charts, then embed them inline with `{% raw %}{{ chart my_chart }}{%
18
18
 
19
19
  ## Next steps
20
20
 
21
- 1. Open `faces/guide.yaml` and tweak the content.
21
+ 1. Open `charts/guide.yaml` and tweak the content.
22
22
  2. Run `dft serve` and open the URL it prints.
23
- 3. Add new `.yaml` or `.md` files under `faces/` — they appear automatically.
23
+ 3. Add new `.yaml` or `.md` files under `charts/` — they appear automatically.
24
24
  4. Run `dft validate` to validate your face YAML for errors.
@@ -21,7 +21,7 @@ text: |
21
21
  Welcome to **Dataface** — dashboards as YAML files.
22
22
 
23
23
  This file is your starter guide. Edit it, add new `.yaml` files under
24
- `faces/`, and run `dft serve` to preview everything in your browser.
24
+ `charts/`, and run `dft serve` to preview everything in your browser.
25
25
 
26
26
  # ── Queries ───────────────────────────────────────────────────────────────────
27
27
  # `type: values` embeds data directly — no database needed.
@@ -1,4 +1,4 @@
1
- # Directory defaults for every face under faces/
1
+ # Directory defaults for every face under charts/
2
2
  #
3
3
  # meta.yaml is a *partial face* — it uses the exact same authoring surface as a
4
4
  # face file (source, theme, queries, charts, style, variables), but without a
@@ -15,18 +15,18 @@ import re
15
15
 
16
16
  from pydantic import BaseModel, ConfigDict, Field
17
17
 
18
- from dataface.core.project import FACES_SUBDIR, Project
18
+ from dataface.core.project import CHARTS_SUBDIR, Project
19
19
 
20
- _FACES_GLOB = f"{FACES_SUBDIR}/**/*"
20
+ _FACES_GLOB = f"{CHARTS_SUBDIR}/**/*"
21
21
 
22
22
 
23
- def face_slug(relpath: str) -> str | None:
24
- """Return the dashboard slug for a ``faces/`` path (no prefix, no suffix).
23
+ def board_slug(relpath: str) -> str | None:
24
+ """Return the dashboard slug for a ``charts/`` path (no prefix, no suffix).
25
25
 
26
- ``faces/finance/rev.yml`` -> ``finance/rev``. Returns None for a path
27
- outside ``faces/`` -- link scanning only has meaning for dashboard slugs.
26
+ ``charts/finance/rev.yml`` -> ``finance/rev``. Returns None for a path
27
+ outside ``charts/`` -- link scanning only has meaning for dashboard slugs.
28
28
  """
29
- prefix = f"{FACES_SUBDIR}/"
29
+ prefix = f"{CHARTS_SUBDIR}/"
30
30
  if not relpath.startswith(prefix):
31
31
  return None
32
32
  tail = relpath[len(prefix) :]
@@ -16,7 +16,7 @@ from dataface.core.diagnostics import (
16
16
  )
17
17
  from dataface.core.diagnostics.base import DatafaceError
18
18
  from dataface.core.project import (
19
- FACES_SUBDIR,
19
+ CHARTS_SUBDIR as CHARTS_SUBDIR,
20
20
  FaceFile,
21
21
  Project,
22
22
  ProjectPath,
@@ -37,19 +37,19 @@ if TYPE_CHECKING:
37
37
  def resolve_face_relpath(relpath: PurePosixPath, project: Project) -> ProjectPath:
38
38
  """Project-relative face identity -> ProjectPath, with the faces-first retry.
39
39
 
40
- The relpath-native counterpart to ``resolve_face_path``: for callers that
40
+ The relpath-native counterpart to ``resolve_board_path``: for callers that
41
41
  already hold a project-relative face identity (Cloud's context strings)
42
42
  rather than a real filesystem path, this is the single owner of the
43
43
  face-relative vs root-relative reconciliation — a bare name like
44
- ``looker/x.yaml`` retries under ``FACES_SUBDIR`` when it doesn't exist at
45
- root, without producing a ``faces/faces/...`` double prefix when the
46
- caller already supplies the full ``faces/looker/x.yaml``.
44
+ ``looker/x.yaml`` retries under ``CHARTS_SUBDIR`` when it doesn't exist at
45
+ root, without producing a ``charts/charts/...`` double prefix when the
46
+ caller already supplies the full ``charts/looker/x.yaml``.
47
47
 
48
48
  Existence is checked via ``project.exists(...)`` so it works for all
49
49
  ``Project`` implementations (FilesystemProject, CloudManagedProject
50
50
  git-blob store, etc.) — not just the local filesystem. Paths that exist
51
51
  at root resolve from root — non-faces paths like ``models/schema.sql``
52
- are not rewritten under faces/. ``str`` is used only at the identity seam
52
+ are not rewritten under charts/. ``str`` is used only at the identity seam
53
53
  (``project.path`` / ``project.exists``); everything else is real
54
54
  ``PurePosixPath`` operations.
55
55
  """
@@ -57,8 +57,8 @@ def resolve_face_relpath(relpath: PurePosixPath, project: Project) -> ProjectPat
57
57
  assert_relpath(relpath_str)
58
58
  if project.exists(relpath_str):
59
59
  return project.path(relpath_str)
60
- if not relpath.parts or relpath.parts[0] != FACES_SUBDIR:
61
- candidate = PurePosixPath(FACES_SUBDIR) / relpath
60
+ if not relpath.parts or relpath.parts[0] != CHARTS_SUBDIR:
61
+ candidate = PurePosixPath(CHARTS_SUBDIR) / relpath
62
62
  candidate_str = str(candidate)
63
63
  if project.exists(candidate_str):
64
64
  return project.path(candidate_str)
@@ -78,7 +78,7 @@ def _relpath_for_fs_location(path: Path, project: Project) -> str:
78
78
  Two-try containment check (mirrors the pre-refactor behavior): ``resolve()``
79
79
  follows symlinks (handles e.g. ``/var`` -> ``/private/var`` on macOS); a
80
80
  symlink-blind ``normpath`` fallback accepts paths through intentional
81
- project-internal symlinks (e.g. ``faces/tasks/`` -> ``../../tasks/``).
81
+ project-internal symlinks (e.g. ``charts/tasks/`` -> ``../../tasks/``).
82
82
  Raises ``ValueError`` if neither check places *path* inside the root.
83
83
  """
84
84
  if not isinstance(project, FilesystemProject):
@@ -99,13 +99,13 @@ def _relpath_for_fs_location(path: Path, project: Project) -> str:
99
99
  raise ValueError(f"Path {path!r} is outside project root {root!r}") from None
100
100
 
101
101
 
102
- def resolve_face_path(path: Path, project: Project) -> ProjectPath:
102
+ def resolve_board_path(path: Path, project: Project) -> ProjectPath:
103
103
  """User/agent-supplied filesystem-shaped face path -> ProjectPath.
104
104
 
105
105
  Absolute and ``..``-leading paths are explicit locations: they relativize
106
106
  against a concrete ``FilesystemProject`` root (``_relpath_for_fs_location``,
107
107
  a leading ``..`` resolving against cwd for CLI shell-nav feel) and are
108
- returned as-is — no ``faces/`` retry, even when the exact path doesn't
108
+ returned as-is — no ``charts/`` retry, even when the exact path doesn't
109
109
  exist. A bare relative name (no explicit location) delegates to
110
110
  ``resolve_face_relpath`` for the faces-first retry, which works against
111
111
  any ``Project`` implementation.
@@ -131,7 +131,7 @@ def resolve_face_or_error(path: Path, project: Project) -> FaceFile | Diagnostic
131
131
  (``ERR-INTERNAL``) or a missing face (``ERR-FILE-NOT-FOUND``).
132
132
  """
133
133
  try:
134
- resolved = resolve_face_path(path, project)
134
+ resolved = resolve_board_path(path, project)
135
135
  except ValueError as exc:
136
136
  return DatafaceError.from_code(ERR_INTERNAL, message=str(exc)).to_diagnostic()
137
137
  if not resolved.exists():
@@ -238,11 +238,11 @@ def project_sources_for_face(face_path: Path) -> ProjectSourcesConfig:
238
238
  parse finding trustworthy enough to report.
239
239
 
240
240
  A face outside any project needs no special case: `find_project_root`
241
- falls back to the starting directory, which has no `dataface.yml`, and the
241
+ falls back to the starting directory, which has no `dbt_charts.yml`, and the
242
242
  registry comes back empty — compile then stays silent about SQL syntax
243
243
  rather than guessing a dialect.
244
244
 
245
- A `dataface.yml` that exists but does not load raises, deliberately. That
245
+ A `dbt_charts.yml` that exists but does not load raises, deliberately. That
246
246
  is a real fault at a real location, and swallowing it here would decide on
247
247
  the author's behalf that a broken project config is invisible — while
248
248
  handing the caller an empty registry indistinguishable from "no project".
@@ -1,7 +1,7 @@
1
1
  """Emit a resolved-board artifact + recording, and render one back.
2
2
 
3
3
  `emit_board_artifact` compiles, resolves, and executes a face, then writes the
4
- board's published `ResolvedFace` contract and a data sidecar (the rows it was
4
+ board's published `ResolvedBoard` contract and a data sidecar (the rows it was
5
5
  resolved against). `render_board_from_files` reads both back and renders
6
6
  without a compile step or a warehouse connection — the "skip the
7
7
  compilation" win the resolved-board artifact exists for.
@@ -22,7 +22,7 @@ from pydantic import BaseModel, ConfigDict
22
22
 
23
23
  from dataface.agent_api._paths import resolve_face_or_error
24
24
  from dataface.core.compile import compile_file
25
- from dataface.core.compile.models.face.resolved import ChartResolveFailure
25
+ from dataface.core.compile.models.board.resolved import ChartResolveFailure
26
26
  from dataface.core.compile.variables import normalize_multiselect_values
27
27
  from dataface.core.diagnostics import ERR_FILE_NOT_FOUND, Diagnostic
28
28
  from dataface.core.diagnostics.base import DatafaceError
@@ -89,7 +89,7 @@ def emit_board_artifact(
89
89
  ) -> EmitBoardArtifactResult:
90
90
  """Compile, resolve, and execute a face, then write its artifact + recording.
91
91
 
92
- Writes `artifact_path` (the published, data-free `ResolvedFace` contract)
92
+ Writes `artifact_path` (the published, data-free `ResolvedBoard` contract)
93
93
  and `recording_path` (the rows it was resolved against, the variable
94
94
  values, and a `recorded_at` stamp) — kept separate so the board contract
95
95
  carries no data payload.
@@ -21,11 +21,11 @@ else:
21
21
 
22
22
  from dataface.agent_api._paths import resolve_face_or_error
23
23
  from dataface.agent_api.query import VariableBinding, variables_to_dict as _vars_to_dict
24
- from dataface.core.compile import Face, compile_file
25
- from dataface.core.dashboard import RenderedDashboard as RenderedDashboard
24
+ from dataface.core.board import BoardRenderResult as BoardRenderResult
25
+ from dataface.core.compile import Board, compile_file
26
26
  from dataface.core.diagnostics import Diagnostic
27
27
  from dataface.core.project import (
28
- FACES_SUBDIR,
28
+ CHARTS_SUBDIR,
29
29
  Project,
30
30
  ProjectDirectory,
31
31
  ProjectPath,
@@ -39,7 +39,7 @@ DASHBOARD_KEYS = frozenset({"queries", "charts", "rows", "cols", "grid", "tabs"}
39
39
  # ---------------------------------------------------------------------------
40
40
 
41
41
 
42
- class DashboardSummary(BaseModel):
42
+ class BoardSummary(BaseModel):
43
43
  model_config = ConfigDict(
44
44
  arbitrary_types_allowed=True, populate_by_name=True, frozen=True
45
45
  )
@@ -69,12 +69,12 @@ class SkippedFile(BaseModel):
69
69
  return pf.relpath
70
70
 
71
71
 
72
- class ListDashboardsResult(BaseModel):
72
+ class ListBoardsResult(BaseModel):
73
73
  model_config = ConfigDict(arbitrary_types_allowed=True, frozen=True)
74
74
 
75
75
  success: bool
76
76
  errors: list[Diagnostic] = []
77
- dashboards: list[DashboardSummary] = []
77
+ boards: list[BoardSummary] = []
78
78
  count: int = 0
79
79
  directory: ProjectDirectory
80
80
  skipped_files: list[SkippedFile] = []
@@ -84,26 +84,26 @@ class ListDashboardsResult(BaseModel):
84
84
  return d.relpath
85
85
 
86
86
 
87
- class CompiledDashboard(BaseModel):
87
+ class CompiledBoard(BaseModel):
88
88
  model_config = ConfigDict(frozen=True)
89
89
 
90
90
  success: bool
91
- dashboard: Face | None = None
91
+ board: Board | None = None
92
92
  errors: list[Diagnostic] = []
93
93
  warnings: list[Diagnostic] = []
94
94
  raw_yaml: str | None = None
95
95
 
96
96
 
97
- class RenderDashboardArgs(BaseModel):
97
+ class RenderBoardArgs(BaseModel):
98
98
  """Validate, compile, and render a Dataface dashboard, returning resolved chart semantics + executed data for reasoning. Use this to verify YAML is valid, inspect query results, and iterate on a dashboard. When 'path' is provided, the response also includes a localhost URL the user can open in a browser to view the live dashboard (from the embedded HTTP server used by agent sessions). Pass `as_link=true` with a path to skip execution and return only the preview URL."""
99
99
 
100
100
  path: Path | None = Field(
101
101
  None,
102
102
  description=(
103
103
  "Path to dashboard YAML file (use this OR yaml_content). "
104
- "Face-relative (no faces/ prefix needed, e.g. 'looker/x.yaml') or "
105
- "root-relative (e.g. 'faces/looker/x.yaml') both resolve. If the "
106
- "path came from search_dashboards, use the hit's face_path."
104
+ "Face-relative (no charts/ prefix needed, e.g. 'looker/x.yaml') or "
105
+ "root-relative (e.g. 'charts/looker/x.yaml') both resolve. If the "
106
+ "path came from search_boards, use the hit's face_path."
107
107
  ),
108
108
  )
109
109
  yaml_content: str | None = Field(
@@ -171,14 +171,14 @@ class RenderDashboardArgs(BaseModel):
171
171
  # ---------------------------------------------------------------------------
172
172
 
173
173
 
174
- def list_dashboards(
174
+ def list_boards(
175
175
  project: Project,
176
176
  *,
177
- under: str = FACES_SUBDIR,
177
+ under: str = CHARTS_SUBDIR,
178
178
  recursive: bool = True,
179
- ) -> ListDashboardsResult:
179
+ ) -> ListBoardsResult:
180
180
  """List all available dashboards in a project."""
181
- dashboards: list[DashboardSummary] = []
181
+ dashboards: list[BoardSummary] = []
182
182
  skipped: list[SkippedFile] = []
183
183
 
184
184
  for pf in project.iter_faces(under=under, recursive=recursive):
@@ -193,7 +193,7 @@ def list_dashboards(
193
193
  continue
194
194
  stem = pf.stem
195
195
  dashboards.append(
196
- DashboardSummary(
196
+ BoardSummary(
197
197
  file=pf,
198
198
  title=content.get("title", stem),
199
199
  description=content.get("description", ""),
@@ -207,31 +207,31 @@ def list_dashboards(
207
207
  except OSError as e:
208
208
  skipped.append(SkippedFile(file=pf, reason=f"Read error: {e}"))
209
209
 
210
- return ListDashboardsResult(
210
+ return ListBoardsResult(
211
211
  success=True,
212
- dashboards=dashboards,
212
+ boards=dashboards,
213
213
  count=len(dashboards),
214
214
  directory=project.directory(under),
215
215
  skipped_files=skipped,
216
216
  )
217
217
 
218
218
 
219
- def get_dashboard(
219
+ def get_board(
220
220
  path: Path,
221
221
  *,
222
222
  project: Project,
223
223
  include_raw: bool = False,
224
- ) -> CompiledDashboard:
224
+ ) -> CompiledBoard:
225
225
  """Get the compiled structure of a dashboard."""
226
226
  # One faces-first resolve/exists/is-file seam, shared with the render path.
227
227
  face = resolve_face_or_error(path, project)
228
228
  if isinstance(face, Diagnostic):
229
- return CompiledDashboard(success=False, errors=[face])
229
+ return CompiledBoard(success=False, errors=[face])
230
230
  result = compile_file(face)
231
231
 
232
- return CompiledDashboard(
232
+ return CompiledBoard(
233
233
  success=result.success,
234
- dashboard=result.face if result.success else None,
234
+ board=result.face if result.success else None,
235
235
  errors=list(result.errors),
236
236
  warnings=result.warnings,
237
237
  raw_yaml=face.content if include_raw else None,
@@ -53,7 +53,7 @@ def project_cache_ctx(
53
53
  Precedence: ``no_cache=True`` (the CLI's ``--no-cache``) skips the cache
54
54
  entirely; ``cache_path`` (``--cache PATH``, or its ``DFT_CACHE_PATH`` env
55
55
  backing) opens that persistent file. Otherwise the project's
56
- ``dataface.yml`` ``cache:`` block picks the location — a configured ``path``
56
+ ``dbt_charts.yml`` ``cache:`` block picks the location — a configured ``path``
57
57
  opens that file (created if absent); no path opens the zero-config
58
58
  in-memory default. A project-level ``cache: false`` defaults the *cascade*
59
59
  to off without closing the door on a nearer scope's opt-in, so it still
@@ -6,7 +6,6 @@ from the validate path, which must stay connection-free.
6
6
 
7
7
  from __future__ import annotations
8
8
 
9
- from pathlib import Path
10
9
  from typing import TYPE_CHECKING
11
10
 
12
11
  if TYPE_CHECKING:
@@ -67,7 +66,7 @@ def validate_data_aliases(
67
66
 
68
67
 
69
68
  def data_alias_errors_for_file(
70
- face_file: Path,
69
+ face_file: str,
71
70
  source_names: frozenset[str],
72
71
  project: Project,
73
72
  ) -> list[str]:
@@ -83,7 +82,7 @@ def data_alias_errors_for_file(
83
82
  """
84
83
  from dataface.core.serve.alias_index import read_aliases_from_file
85
84
 
86
- project_path = project.path(face_file.as_posix())
85
+ project_path = project.path(face_file)
87
86
  try:
88
87
  aliases = read_aliases_from_file(project_path)
89
88
  except ValueError: