dataface 0.1.2__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 (455) hide show
  1. d3_format/__init__.py +14 -0
  2. d3_format/errors.py +19 -0
  3. d3_format/format.py +551 -0
  4. d3_format/spec.py +159 -0
  5. dataface/DATAFACE_SYNTAX.md +1135 -0
  6. dataface/__init__.py +93 -0
  7. dataface/_docs_site.py +20 -0
  8. dataface/_install_hint.py +26 -0
  9. dataface/agent_api/__init__.py +79 -0
  10. dataface/agent_api/_init_templates/__init__.py +0 -0
  11. dataface/agent_api/_init_templates/agents_dft_snippet.md +26 -0
  12. dataface/agent_api/_init_templates/dataface.yml +15 -0
  13. dataface/agent_api/_init_templates/faces-dataface.yml +144 -0
  14. dataface/agent_api/_init_templates/index.md +24 -0
  15. dataface/agent_api/_paths.py +118 -0
  16. dataface/agent_api/_project_agents_md.py +43 -0
  17. dataface/agent_api/_session_store.py +486 -0
  18. dataface/agent_api/_state.py +28 -0
  19. dataface/agent_api/chat.py +221 -0
  20. dataface/agent_api/dashboards.py +257 -0
  21. dataface/agent_api/describe.py +366 -0
  22. dataface/agent_api/describe_query.py +120 -0
  23. dataface/agent_api/docs/__init__.py +25 -0
  24. dataface/agent_api/docs/_loader.py +292 -0
  25. dataface/agent_api/docs/yaml-reference.md +2757 -0
  26. dataface/agent_api/file_refs.py +118 -0
  27. dataface/agent_api/init.py +126 -0
  28. dataface/agent_api/inspect.py +128 -0
  29. dataface/agent_api/mcp_install.py +170 -0
  30. dataface/agent_api/query.py +274 -0
  31. dataface/agent_api/schema.py +658 -0
  32. dataface/agent_api/schema_search.py +284 -0
  33. dataface/agent_api/search.py +270 -0
  34. dataface/agent_api/skill_install.py +141 -0
  35. dataface/agent_api/skill_render.py +90 -0
  36. dataface/agent_api/skills.py +293 -0
  37. dataface/agent_api/surface_aliases.yaml +128 -0
  38. dataface/agent_api/validate.py +175 -0
  39. dataface/agent_api/validate_query.py +84 -0
  40. dataface/ai/__init__.py +39 -0
  41. dataface/ai/agent.py +139 -0
  42. dataface/ai/context.py +45 -0
  43. dataface/ai/events.py +62 -0
  44. dataface/ai/external_mcp.py +610 -0
  45. dataface/ai/generate_sql.py +96 -0
  46. dataface/ai/llm.py +403 -0
  47. dataface/ai/mcp/__init__.py +51 -0
  48. dataface/ai/mcp/server.py +289 -0
  49. dataface/ai/memories.py +85 -0
  50. dataface/ai/prompts.py +177 -0
  51. dataface/ai/schema_context.py +138 -0
  52. dataface/ai/skills/before-after-comparison/SKILL.md +102 -0
  53. dataface/ai/skills/before-after-comparison/examples/before-after-comparison.yml +24 -0
  54. dataface/ai/skills/dashboard-build/SKILL.md +212 -0
  55. dataface/ai/skills/dashboard-build/examples/_smoke.yml +15 -0
  56. dataface/ai/skills/dashboard-design/SKILL.md +182 -0
  57. dataface/ai/skills/dashboard-review/SKILL.md +113 -0
  58. dataface/ai/skills/dashboard-structural-review/SKILL.md +173 -0
  59. dataface/ai/skills/dashboard-visual-review/SKILL.md +139 -0
  60. dataface/ai/skills/dataface-mcp-setup/SKILL.md +177 -0
  61. dataface/ai/skills/dataface-troubleshooting/SKILL.md +225 -0
  62. dataface/ai/skills/drill-down-link/SKILL.md +112 -0
  63. dataface/ai/skills/drill-down-link/examples/drill-down-link.yml +27 -0
  64. dataface/ai/skills/faceted-small-multiples/SKILL.md +116 -0
  65. dataface/ai/skills/faceted-small-multiples/examples/faceted-small-multiples.yml +33 -0
  66. dataface/ai/skills/filter-bar-with-variables/SKILL.md +105 -0
  67. dataface/ai/skills/filter-bar-with-variables/examples/filter-bar-with-variables.yml +49 -0
  68. dataface/ai/skills/kpi-row/SKILL.md +101 -0
  69. dataface/ai/skills/kpi-row/examples/kpi-row.yml +55 -0
  70. dataface/ai/skills/report-design/SKILL.md +184 -0
  71. dataface/ai/skills/single-metric-bignum/SKILL.md +90 -0
  72. dataface/ai/skills/single-metric-bignum/examples/single-metric-bignum.yml +27 -0
  73. dataface/ai/skills/table-heavy-ops-dashboard/SKILL.md +114 -0
  74. dataface/ai/skills/table-heavy-ops-dashboard/examples/table-heavy-ops-dashboard.yml +48 -0
  75. dataface/ai/skills/time-series-trend/SKILL.md +93 -0
  76. dataface/ai/skills/time-series-trend/examples/time-series-trend.yml +26 -0
  77. dataface/ai/skills/top-n-with-detail/SKILL.md +98 -0
  78. dataface/ai/skills/top-n-with-detail/examples/top-n-with-detail.yml +45 -0
  79. dataface/ai/skills/two-by-two-grid-overview/SKILL.md +78 -0
  80. dataface/ai/skills/two-by-two-grid-overview/examples/two-by-two-grid-overview.yml +64 -0
  81. dataface/ai/tool_schemas.py +132 -0
  82. dataface/ai/tools/__init__.py +312 -0
  83. dataface/ai/yaml_utils.py +57 -0
  84. dataface/cli/__init__.py +3 -0
  85. dataface/cli/_console.py +48 -0
  86. dataface/cli/_error_format.py +83 -0
  87. dataface/cli/_extras.py +190 -0
  88. dataface/cli/_json_output.py +8 -0
  89. dataface/cli/_parsing.py +17 -0
  90. dataface/cli/_version_info.py +56 -0
  91. dataface/cli/commands/__init__.py +3 -0
  92. dataface/cli/commands/_agent_input.py +205 -0
  93. dataface/cli/commands/_agent_server.py +115 -0
  94. dataface/cli/commands/chat.py +645 -0
  95. dataface/cli/commands/describe.py +107 -0
  96. dataface/cli/commands/docs.py +131 -0
  97. dataface/cli/commands/extension.py +179 -0
  98. dataface/cli/commands/init.py +240 -0
  99. dataface/cli/commands/inspect.py +94 -0
  100. dataface/cli/commands/mcp_init.py +167 -0
  101. dataface/cli/commands/query.py +386 -0
  102. dataface/cli/commands/render.py +291 -0
  103. dataface/cli/commands/schema.py +411 -0
  104. dataface/cli/commands/search.py +49 -0
  105. dataface/cli/commands/serve.py +114 -0
  106. dataface/cli/commands/skills.py +133 -0
  107. dataface/cli/commands/skills_init.py +161 -0
  108. dataface/cli/commands/validate.py +63 -0
  109. dataface/cli/main.py +1501 -0
  110. dataface/core/__init__.py +75 -0
  111. dataface/core/compile/__init__.py +244 -0
  112. dataface/core/compile/_jinja_helpers.py +78 -0
  113. dataface/core/compile/channel.py +222 -0
  114. dataface/core/compile/chart_focus.py +101 -0
  115. dataface/core/compile/chart_resolved.py +169 -0
  116. dataface/core/compile/chart_type_detection.py +489 -0
  117. dataface/core/compile/chart_update.py +261 -0
  118. dataface/core/compile/colors.py +64 -0
  119. dataface/core/compile/compiler.py +904 -0
  120. dataface/core/compile/config.py +823 -0
  121. dataface/core/compile/custom_chart_types.py +208 -0
  122. dataface/core/compile/data_table_attachment.py +1287 -0
  123. dataface/core/compile/detect.py +110 -0
  124. dataface/core/compile/errors.py +302 -0
  125. dataface/core/compile/filter_injection.py +319 -0
  126. dataface/core/compile/introspection.py +527 -0
  127. dataface/core/compile/jinja.py +511 -0
  128. dataface/core/compile/labels_env.py +52 -0
  129. dataface/core/compile/markdown.py +154 -0
  130. dataface/core/compile/meta.py +388 -0
  131. dataface/core/compile/models/__init__.py +0 -0
  132. dataface/core/compile/models/chart/__init__.py +0 -0
  133. dataface/core/compile/models/chart/authored.py +2137 -0
  134. dataface/core/compile/models/chart/compiled.py +398 -0
  135. dataface/core/compile/models/config.py +347 -0
  136. dataface/core/compile/models/face/__init__.py +0 -0
  137. dataface/core/compile/models/face/authored.py +659 -0
  138. dataface/core/compile/models/face/compiled.py +522 -0
  139. dataface/core/compile/models/factories.py +201 -0
  140. dataface/core/compile/models/markers.py +40 -0
  141. dataface/core/compile/models/palette.py +36 -0
  142. dataface/core/compile/models/primitives.py +415 -0
  143. dataface/core/compile/models/query/__init__.py +0 -0
  144. dataface/core/compile/models/query/authored.py +246 -0
  145. dataface/core/compile/models/query/compiled.py +710 -0
  146. dataface/core/compile/models/refs.py +137 -0
  147. dataface/core/compile/models/source.py +611 -0
  148. dataface/core/compile/models/style/__init__.py +0 -0
  149. dataface/core/compile/models/style/authored.py +481 -0
  150. dataface/core/compile/models/style/compiled.py +3399 -0
  151. dataface/core/compile/models/style/merged.py +1682 -0
  152. dataface/core/compile/models/theme.py +362 -0
  153. dataface/core/compile/models/variable/__init__.py +0 -0
  154. dataface/core/compile/models/variable/authored.py +254 -0
  155. dataface/core/compile/models/vega_lite/__init__.py +0 -0
  156. dataface/core/compile/models/vega_lite/config.py +510 -0
  157. dataface/core/compile/models/vega_lite/contracts.py +171 -0
  158. dataface/core/compile/normalize_charts.py +494 -0
  159. dataface/core/compile/normalize_layout.py +1000 -0
  160. dataface/core/compile/normalize_queries.py +297 -0
  161. dataface/core/compile/normalize_variables.py +489 -0
  162. dataface/core/compile/normalizer.py +543 -0
  163. dataface/core/compile/palette.py +1100 -0
  164. dataface/core/compile/parameterized.py +658 -0
  165. dataface/core/compile/parser.py +228 -0
  166. dataface/core/compile/schema.py +20 -0
  167. dataface/core/compile/schema_renderers/__init__.py +0 -0
  168. dataface/core/compile/schema_renderers/json_schema.py +163 -0
  169. dataface/core/compile/schema_renderers/prompt.py +152 -0
  170. dataface/core/compile/schema_renderers/vscode_schema.py +301 -0
  171. dataface/core/compile/sizing.py +2126 -0
  172. dataface/core/compile/sources.py +518 -0
  173. dataface/core/compile/sql_authoring_lint.py +56 -0
  174. dataface/core/compile/style_cascade.py +471 -0
  175. dataface/core/compile/typography.py +299 -0
  176. dataface/core/compile/validator.py +301 -0
  177. dataface/core/compile/variables.py +53 -0
  178. dataface/core/compile/vega_config.py +98 -0
  179. dataface/core/compile/vega_lite/__init__.py +6 -0
  180. dataface/core/compile/vega_lite/validation.py +95 -0
  181. dataface/core/compile/yaml_error_formatter.py +838 -0
  182. dataface/core/connections.py +38 -0
  183. dataface/core/dashboard.py +358 -0
  184. dataface/core/defaults/default_config.yml +101 -0
  185. dataface/core/defaults/palettes/categorical/category-10-dark.yml +32 -0
  186. dataface/core/defaults/palettes/categorical/category-10-light.yml +43 -0
  187. dataface/core/defaults/palettes/categorical/category-10.yml +31 -0
  188. dataface/core/defaults/palettes/categorical/category-6-tonal-blue.yml +22 -0
  189. dataface/core/defaults/palettes/categorical/category-6-tonal-brown.yml +29 -0
  190. dataface/core/defaults/palettes/categorical/category-6-tonal-green.yml +20 -0
  191. dataface/core/defaults/palettes/categorical/category-6-tonal-orange.yml +21 -0
  192. dataface/core/defaults/palettes/categorical/category-6-tonal-purple.yml +20 -0
  193. dataface/core/defaults/palettes/categorical/editorial-10-dark.yml +32 -0
  194. dataface/core/defaults/palettes/categorical/editorial-10.yml +40 -0
  195. dataface/core/defaults/palettes/categorical/hero-6.yml +17 -0
  196. dataface/core/defaults/palettes/categorical/single-blue.yml +11 -0
  197. dataface/core/defaults/palettes/categorical/tableau.yml +20 -0
  198. dataface/core/defaults/palettes/data/xkcd_colors.json +3803 -0
  199. dataface/core/defaults/palettes/diverging/blue-red.yml +25 -0
  200. dataface/core/defaults/palettes/diverging/coolwarm.yml +24 -0
  201. dataface/core/defaults/palettes/diverging/crimson-green.yml +23 -0
  202. dataface/core/defaults/palettes/diverging/orange-teal.yml +23 -0
  203. dataface/core/defaults/palettes/diverging/sunset.yml +24 -0
  204. dataface/core/defaults/palettes/scaffold/dft-creams.yml +38 -0
  205. dataface/core/defaults/palettes/scaffold/dft-grays.yml +53 -0
  206. dataface/core/defaults/palettes/sequential/amber.yml +22 -0
  207. dataface/core/defaults/palettes/sequential/blue.yml +22 -0
  208. dataface/core/defaults/palettes/sequential/brown.yml +22 -0
  209. dataface/core/defaults/palettes/sequential/gray.yml +22 -0
  210. dataface/core/defaults/palettes/sequential/green.yml +22 -0
  211. dataface/core/defaults/palettes/sequential/purple.yml +22 -0
  212. dataface/core/defaults/palettes/sequential/rust.yml +22 -0
  213. dataface/core/defaults/palettes/sequential/teal.yml +22 -0
  214. dataface/core/defaults/palettes/tone/negative.yml +32 -0
  215. dataface/core/defaults/palettes/tone/positive.yml +22 -0
  216. dataface/core/defaults/palettes/tone/warning.yml +22 -0
  217. dataface/core/defaults/themes/_base.yaml +786 -0
  218. dataface/core/defaults/themes/bi.yaml +16 -0
  219. dataface/core/defaults/themes/carbong100.yaml +41 -0
  220. dataface/core/defaults/themes/cream.yaml +122 -0
  221. dataface/core/defaults/themes/dark.yaml +40 -0
  222. dataface/core/defaults/themes/diagnostics-title-angle-extreme.yaml +9 -0
  223. dataface/core/defaults/themes/diagnostics-title-baseline-extreme.yaml +9 -0
  224. dataface/core/defaults/themes/diagnostics-title-baseline.yaml +24 -0
  225. dataface/core/defaults/themes/diagnostics-title-center.yaml +8 -0
  226. dataface/core/defaults/themes/diagnostics-title-color-extreme.yaml +24 -0
  227. dataface/core/defaults/themes/diagnostics-title-font-extreme.yaml +25 -0
  228. dataface/core/defaults/themes/diagnostics-title-left.yaml +8 -0
  229. dataface/core/defaults/themes/diagnostics-title-offset-extreme.yaml +9 -0
  230. dataface/core/defaults/themes/diagnostics-title-size-extreme.yaml +24 -0
  231. dataface/core/defaults/themes/diagnostics-title-weight-extreme.yaml +24 -0
  232. dataface/core/defaults/themes/editorial.yaml +147 -0
  233. dataface/core/defaults/themes/light.yaml +30 -0
  234. dataface/core/defaults/themes/looker.yaml +17 -0
  235. dataface/core/defaults/themes/stark.yaml +134 -0
  236. dataface/core/errors/__init__.py +67 -0
  237. dataface/core/errors/codes_compile.py +56 -0
  238. dataface/core/errors/codes_execute.py +177 -0
  239. dataface/core/errors/codes_render.py +106 -0
  240. dataface/core/errors/codes_unknown.py +15 -0
  241. dataface/core/errors/hints.py +74 -0
  242. dataface/core/errors/registry.py +42 -0
  243. dataface/core/errors/structured.py +92 -0
  244. dataface/core/execute/__init__.py +91 -0
  245. dataface/core/execute/adapters/__init__.py +49 -0
  246. dataface/core/execute/adapters/adapter_registry.py +400 -0
  247. dataface/core/execute/adapters/base.py +245 -0
  248. dataface/core/execute/adapters/csv_adapter.py +239 -0
  249. dataface/core/execute/adapters/dbt_adapter.py +283 -0
  250. dataface/core/execute/adapters/dbt_adapter_factory.py +212 -0
  251. dataface/core/execute/adapters/dbt_macro_loader.py +95 -0
  252. dataface/core/execute/adapters/dbt_utils.py +150 -0
  253. dataface/core/execute/adapters/http_adapter.py +224 -0
  254. dataface/core/execute/adapters/metricflow_adapter.py +94 -0
  255. dataface/core/execute/adapters/schema_resolver_adapter.py +144 -0
  256. dataface/core/execute/adapters/sql_adapter.py +710 -0
  257. dataface/core/execute/adapters/values_adapter.py +58 -0
  258. dataface/core/execute/batch.py +744 -0
  259. dataface/core/execute/cache_backend.py +135 -0
  260. dataface/core/execute/cache_keys.py +66 -0
  261. dataface/core/execute/dbt_jinja.py +21 -0
  262. dataface/core/execute/dialects/__init__.py +121 -0
  263. dataface/core/execute/dialects/athena.py +75 -0
  264. dataface/core/execute/dialects/base.py +302 -0
  265. dataface/core/execute/dialects/bigquery.py +38 -0
  266. dataface/core/execute/dialects/databricks.py +68 -0
  267. dataface/core/execute/dialects/duckdb.py +35 -0
  268. dataface/core/execute/dialects/mysql.py +68 -0
  269. dataface/core/execute/dialects/postgres.py +39 -0
  270. dataface/core/execute/dialects/redshift.py +12 -0
  271. dataface/core/execute/dialects/snowflake.py +51 -0
  272. dataface/core/execute/dialects/sqlserver.py +92 -0
  273. dataface/core/execute/duckdb_cache.py +712 -0
  274. dataface/core/execute/duckdb_config.py +26 -0
  275. dataface/core/execute/errors.py +213 -0
  276. dataface/core/execute/executor.py +1249 -0
  277. dataface/core/execute/parallel.py +162 -0
  278. dataface/core/execute/setup_sql.py +58 -0
  279. dataface/core/execute/source_registry.py +72 -0
  280. dataface/core/execute/source_resolver.py +255 -0
  281. dataface/core/execute/sql_guard.py +387 -0
  282. dataface/core/execute/sql_literals.py +199 -0
  283. dataface/core/fonts.py +52 -0
  284. dataface/core/inspect/__init__.py +32 -0
  285. dataface/core/inspect/cache_factory.py +98 -0
  286. dataface/core/inspect/db_types.py +162 -0
  287. dataface/core/inspect/dbt_schema.py +96 -0
  288. dataface/core/inspect/defaults.yml +37 -0
  289. dataface/core/inspect/fanout_risk.py +109 -0
  290. dataface/core/inspect/manifest_utils.py +77 -0
  291. dataface/core/inspect/partials/categorical.yml +40 -0
  292. dataface/core/inspect/partials/date.yml +40 -0
  293. dataface/core/inspect/partials/numeric.yml +55 -0
  294. dataface/core/inspect/partition_types.py +38 -0
  295. dataface/core/inspect/query_validator.py +975 -0
  296. dataface/core/inspect/renderer.py +354 -0
  297. dataface/core/inspect/resolver.py +808 -0
  298. dataface/core/inspect/search.py +461 -0
  299. dataface/core/inspect/sources/__init__.py +32 -0
  300. dataface/core/inspect/sources/dbt.py +738 -0
  301. dataface/core/inspect/sources/duckdb_utils.py +66 -0
  302. dataface/core/inspect/templates/__init__.py +1 -0
  303. dataface/core/inspect/templates/categorical_column.yml +196 -0
  304. dataface/core/inspect/templates/charts.yml +109 -0
  305. dataface/core/inspect/templates/date_column.yml +248 -0
  306. dataface/core/inspect/templates/model.yml +138 -0
  307. dataface/core/inspect/templates/numeric_column.yml +261 -0
  308. dataface/core/inspect/templates/quality.yml +80 -0
  309. dataface/core/inspect/templates/string_column.yml +263 -0
  310. dataface/core/project_roots.py +165 -0
  311. dataface/core/render/__init__.py +87 -0
  312. dataface/core/render/board_links.py +176 -0
  313. dataface/core/render/chart/__init__.py +27 -0
  314. dataface/core/render/chart/arc_attached_table.py +251 -0
  315. dataface/core/render/chart/artifacts.py +16 -0
  316. dataface/core/render/chart/callout.py +225 -0
  317. dataface/core/render/chart/decisions.py +358 -0
  318. dataface/core/render/chart/geo.py +700 -0
  319. dataface/core/render/chart/kpi.py +916 -0
  320. dataface/core/render/chart/labels.py +76 -0
  321. dataface/core/render/chart/pipeline.py +818 -0
  322. dataface/core/render/chart/presentation.py +36 -0
  323. dataface/core/render/chart/profile.py +3438 -0
  324. dataface/core/render/chart/render_single.py +347 -0
  325. dataface/core/render/chart/renderers.py +193 -0
  326. dataface/core/render/chart/rendering.py +565 -0
  327. dataface/core/render/chart/serialization.py +90 -0
  328. dataface/core/render/chart/spark.py +496 -0
  329. dataface/core/render/chart/spark_bar.py +370 -0
  330. dataface/core/render/chart/spec_builders.py +154 -0
  331. dataface/core/render/chart/standard_renderer.py +2645 -0
  332. dataface/core/render/chart/table.py +2957 -0
  333. dataface/core/render/chart/table_support.py +1452 -0
  334. dataface/core/render/chart/tick_values.py +66 -0
  335. dataface/core/render/chart/time_unit_detect.py +809 -0
  336. dataface/core/render/chart/title_overflow.py +157 -0
  337. dataface/core/render/chart/type_inference.py +122 -0
  338. dataface/core/render/chart/validation.py +99 -0
  339. dataface/core/render/chart/vega_lite.py +125 -0
  340. dataface/core/render/chart/vega_lite_types.py +268 -0
  341. dataface/core/render/chart/vl_field_maps.py +346 -0
  342. dataface/core/render/chart_interactivity.py +24 -0
  343. dataface/core/render/control_registry.py +287 -0
  344. dataface/core/render/converters/__init__.py +24 -0
  345. dataface/core/render/converters/chart.py +276 -0
  346. dataface/core/render/converters/html.py +98 -0
  347. dataface/core/render/converters/pdf.py +40 -0
  348. dataface/core/render/converters/png.py +41 -0
  349. dataface/core/render/errors.py +144 -0
  350. dataface/core/render/face_api.py +160 -0
  351. dataface/core/render/faces.py +1194 -0
  352. dataface/core/render/font_measurement.py +48 -0
  353. dataface/core/render/font_support.py +197 -0
  354. dataface/core/render/fonts/DFTSansTabular-Regular.ttf +0 -0
  355. dataface/core/render/fonts/DFTSansTabular-Regular.woff2 +0 -0
  356. dataface/core/render/fonts/DFTSerifOldstyleProportional-Regular.ttf +0 -0
  357. dataface/core/render/fonts/DFTSerifOldstyleTabular-Regular.ttf +0 -0
  358. dataface/core/render/fonts/InterVariable.ttf +0 -0
  359. dataface/core/render/fonts/InterVariable.woff2 +0 -0
  360. dataface/core/render/fonts/NOTO_COLOR_EMOJI_LICENSE.txt +93 -0
  361. dataface/core/render/fonts/NOTO_EMOJI_LICENSE.txt +93 -0
  362. dataface/core/render/fonts/NotoColorEmoji-Regular.ttf +0 -0
  363. dataface/core/render/fonts/NotoColorEmoji-Regular.woff2 +0 -0
  364. dataface/core/render/fonts/NotoEmoji-Regular.ttf +0 -0
  365. dataface/core/render/fonts/NotoEmoji-Regular.woff2 +0 -0
  366. dataface/core/render/fonts/SOURCE_CODE_PRO_LICENSE.txt +93 -0
  367. dataface/core/render/fonts/SOURCE_SERIF_4_LICENSE.txt +98 -0
  368. dataface/core/render/fonts/SourceCodePro-Regular.ttf +0 -0
  369. dataface/core/render/fonts/SourceSerif4-Regular.ttf +0 -0
  370. dataface/core/render/fonts/_emoji_font_face.css +43 -0
  371. dataface/core/render/fonts/source-serif-4-variable-latin.woff2 +0 -0
  372. dataface/core/render/format_utils.py +329 -0
  373. dataface/core/render/geo_defaults.yml +28 -0
  374. dataface/core/render/json_format.py +146 -0
  375. dataface/core/render/layout_sizing.py +865 -0
  376. dataface/core/render/layouts.py +541 -0
  377. dataface/core/render/markdown_defaults.yml +16 -0
  378. dataface/core/render/missing_vars_prompt.py +79 -0
  379. dataface/core/render/placeholder.py +389 -0
  380. dataface/core/render/render_result.py +14 -0
  381. dataface/core/render/renderer.py +467 -0
  382. dataface/core/render/script_embedding.py +16 -0
  383. dataface/core/render/svg_utils.py +212 -0
  384. dataface/core/render/template_loader.py +69 -0
  385. dataface/core/render/templates/controls/_styles.css +606 -0
  386. dataface/core/render/templates/controls/checkbox.html +16 -0
  387. dataface/core/render/templates/controls/date.html +16 -0
  388. dataface/core/render/templates/controls/number.html +19 -0
  389. dataface/core/render/templates/controls/readonly.html +9 -0
  390. dataface/core/render/templates/controls/select.html +21 -0
  391. dataface/core/render/templates/controls/slider.html +22 -0
  392. dataface/core/render/templates/controls/text.html +16 -0
  393. dataface/core/render/templates/scripts/chart_interactivity.js +191 -0
  394. dataface/core/render/templates/scripts/variables.js +976 -0
  395. dataface/core/render/templates/svg/grid_pattern.svg +3 -0
  396. dataface/core/render/templates/svg/styles.css +51 -0
  397. dataface/core/render/terminal.py +311 -0
  398. dataface/core/render/terminal_charts.py +563 -0
  399. dataface/core/render/terminal_defaults.yml +2 -0
  400. dataface/core/render/terminal_layouts.py +299 -0
  401. dataface/core/render/terminal_text.py +31 -0
  402. dataface/core/render/text/__init__.py +1 -0
  403. dataface/core/render/text/case.py +113 -0
  404. dataface/core/render/text_format.py +129 -0
  405. dataface/core/render/utils.py +106 -0
  406. dataface/core/render/variable_controls.py +946 -0
  407. dataface/core/render/variable_input_refinement.py +140 -0
  408. dataface/core/render/warnings/__init__.py +15 -0
  409. dataface/core/render/warnings/bar_color_1_to_1_with_x.py +80 -0
  410. dataface/core/render/warnings/base.py +44 -0
  411. dataface/core/render/warnings/fanout_risk.py +15 -0
  412. dataface/core/render/warnings/from_query_diagnostic.py +56 -0
  413. dataface/core/render/warnings/missing_join_predicate.py +13 -0
  414. dataface/core/render/warnings/query_parse_error.py +14 -0
  415. dataface/core/render/warnings/query_returned_zero_rows.py +42 -0
  416. dataface/core/render/warnings/reaggregation.py +14 -0
  417. dataface/core/render/warnings/registry.py +45 -0
  418. dataface/core/render/warnings/suppression.py +46 -0
  419. dataface/core/render/warnings/temporal_single_point.py +63 -0
  420. dataface/core/render/warnings/unreferenced_chart.py +15 -0
  421. dataface/core/render/warnings/y_encoding_mostly_null.py +76 -0
  422. dataface/core/render/yaml_format.py +167 -0
  423. dataface/core/resolve_face.py +195 -0
  424. dataface/core/schema/__init__.py +0 -0
  425. dataface/core/schema/guidance.py +151 -0
  426. dataface/core/scoped_paths.py +59 -0
  427. dataface/core/serve/__init__.py +14 -0
  428. dataface/core/serve/bootstrap.py +39 -0
  429. dataface/core/serve/embedded.py +57 -0
  430. dataface/core/serve/port.py +129 -0
  431. dataface/core/serve/server.py +938 -0
  432. dataface/core/serve/templates/__init__.py +0 -0
  433. dataface/core/serve/templates/directory.yml +6 -0
  434. dataface/core/serve/templates/error.html.j2 +217 -0
  435. dataface/core/utils.py +121 -0
  436. dataface/core/validate.py +64 -0
  437. dataface/integrations/__init__.py +0 -0
  438. dataface/integrations/highlighting.py +351 -0
  439. dataface/integrations/markdown.py +537 -0
  440. dataface/py.typed +0 -0
  441. dataface-0.1.2.dist-info/METADATA +375 -0
  442. dataface-0.1.2.dist-info/RECORD +455 -0
  443. dataface-0.1.2.dist-info/WHEEL +4 -0
  444. dataface-0.1.2.dist-info/entry_points.txt +2 -0
  445. dataface-0.1.2.dist-info/licenses/LICENSE +202 -0
  446. mdsvg/__init__.py +168 -0
  447. mdsvg/fonts.py +656 -0
  448. mdsvg/images.py +299 -0
  449. mdsvg/parser.py +629 -0
  450. mdsvg/playground.py +284 -0
  451. mdsvg/py.typed +2 -0
  452. mdsvg/renderer.py +1623 -0
  453. mdsvg/style.py +355 -0
  454. mdsvg/types.py +200 -0
  455. mdsvg/utils.py +86 -0
@@ -0,0 +1,173 @@
1
+ ---
2
+ name: dashboard-structural-review
3
+ kind: workflow
4
+ description: >
5
+ Review a Dataface face's YAML structure and content choices without rendering.
6
+ Reads the face file, runs schema validation, then evaluates the YAML against
7
+ a design checklist (chart-data shape match, layout intent, variable wiring,
8
+ descriptive naming, anti-patterns). Use when asked to 'review this
9
+ dashboard', 'check this face', 'is this YAML well-shaped', 'find problems in
10
+ this dashboard', or after editing a face before delivery. Cheap — no
11
+ rendering, no PNG, no LLM judge in the loop. Do NOT use for visual problems
12
+ that need to be seen (use dashboard-visual-review). Do NOT use as a YAML
13
+ linter substitute — schema validation already covers that.
14
+ metadata:
15
+ author: fivetran
16
+ ---
17
+
18
+ # Dashboard Structural Review
19
+
20
+ Read the face's YAML, run `{{ s_validate_dashboard }}`,
21
+ then evaluate the design choices encoded in the YAML against a checklist.
22
+ Produces a markdown findings list with severity tags. No rendering required —
23
+ this is the cheap pass.
24
+
25
+ ## When to use
26
+
27
+ - Post-build sanity check before delivering a new face
28
+ - Post-edit verification after adding charts, queries, or variables
29
+ - Pre-PR review of a face change
30
+ - First pass inside the `dashboard-review` orchestrator
31
+
32
+ ## When NOT to use
33
+
34
+ - Schema validation alone — `{{ s_validate_dashboard }}`
35
+ is the right tool, this skill calls it
36
+ - Visual problems ("the legend is overlapping the title") — use
37
+ `dashboard-visual-review`
38
+ - Comparing two versions of a face — use `looker-compare-diff` pattern instead
39
+
40
+ ## Protocol
41
+
42
+ 1. **Validate.** Run `{{ s_validate_dashboard }}`
43
+ on the face path:
44
+
45
+ {{ s_validate_example }}
46
+
47
+ If validation reports errors, surface them and stop — there's nothing to
48
+ review until the schema is valid.
49
+
50
+ 2. **Read the face YAML** with the agent's file-reading tool.
51
+
52
+ 3. **Evaluate against the checklist below.** For each finding, emit a row with
53
+ severity, the YAML path or chart name, and a concrete fix.
54
+
55
+ ## Checklist
56
+
57
+ ### Layout intent
58
+
59
+ - [ ] Top of the face is a summary (KPI row, hero metric) — not a detail table
60
+ - [ ] Reading order (top-down, left-to-right) tells a story: headline → trend →
61
+ breakdowns → detail
62
+ - [ ] Related charts are grouped (same `cols:` row or adjacent rows)
63
+ - [ ] No more than 8 visualizations on one face
64
+
65
+ ### Chart-data shape match
66
+
67
+ - [ ] `type: kpi` queries return **exactly 1 row** (aggregate, not raw)
68
+ - [ ] `type: pie` queries are pre-aggregated and have **2–3 segments** (use
69
+ `bar` for 4+)
70
+ - [ ] `type: line` / `area` use a temporal x-axis
71
+ - [ ] `type: bar` has a categorical x-axis (not a continuous date)
72
+ - [ ] `type: table` columns make sense as a list — no 1-row tables, no
73
+ single-column tables that should be KPIs
74
+ - [ ] No single-bar bar charts (one bar = use a KPI)
75
+
76
+ ### Variables and parameterization
77
+
78
+ - [ ] Filters declared in `variables:` are referenced by at least one query
79
+ - [ ] Queries don't hardcode values that should be variables (date ranges,
80
+ categorical filters)
81
+ - [ ] Variable defaults are sensible (last 30 days, most common segment)
82
+ - [ ] Executive / always-on dashboards have **no** filter variables
83
+
84
+ ### Descriptive metadata
85
+
86
+ - [ ] Every query has a `description:` (what it returns and why)
87
+ - [ ] Every chart has a `description:` (what question it answers)
88
+ - [ ] Every variable has a `description:` (how it should be used)
89
+ - [ ] Chart names communicate intent (`revenue_trend`, not `chart_1`)
90
+ - [ ] Titles state what the chart answers (`"Revenue by Region, Last 30 Days"`,
91
+ not `"Sales"`)
92
+
93
+ ### Anti-patterns
94
+
95
+ - [ ] No `kpi` displaying a string column (KPIs are numeric)
96
+ - [ ] No chart that exists without a clear question it answers
97
+ - [ ] No duplicated queries (same SQL repeated under different names)
98
+ - [ ] No raw / unaggregated data feeding a chart that requires pre-aggregation
99
+
100
+ ### Formatting
101
+
102
+ - [ ] No raw D3 format strings — use named presets (`currency_compact`, not `"$,.2s"`)
103
+ - [ ] No explicit `format:` when auto-detection already produces the correct result (see auto-detection rules below)
104
+ - [ ] Currency columns without `$`-triggering names (`arr`, `mrr`, `acv`, etc.) have an explicit `format: currency*` preset set
105
+ - [ ] Integer columns where exact counts matter use `format: integer` (auto for large integers produces SI compact `~s`)
106
+
107
+ **Preset reference**
108
+
109
+ | Preset | D3 equivalent | Example |
110
+ |--------|--------------|---------|
111
+ | `integer` | `",.0f"` | `1,234` |
112
+ | `number` | `",.2f"` | `1,234.56` |
113
+ | `currency` | `"$,.2f"` | `$1,234.56` |
114
+ | `currency_whole` | `"$,.0f"` | `$1,234` |
115
+ | `currency_compact` | `"$,.2s"` | `$1.2M` |
116
+ | `percent` | `".1%"` | `2.3%` |
117
+ | `percent_whole` | `".0%"` | `2%` |
118
+ | `percent_delta` | `"+.1%"` | `+2.3%` |
119
+ | `compact` | `",.2s"` | `1.2M` |
120
+ | `date_short` | `"%-d %b %Y"` | `26 May 2026` |
121
+
122
+ **Auto-detection rules** (apply when no explicit `format:` is set)
123
+
124
+ - Column name matches `*_pct`, `*_rate`, `*_ratio`, `*_share`, `*_proportion` → renders as `percent` (`.1%`)
125
+ - Column name matches `*revenue*`, `*amount*`, `*cost*`, `*price*`, `*spend*`, `*profit*`, `*fee*` → renders as currency with `$`
126
+ - Integer DB type + value ≥ 10K → SI compact `~s` (no `$`, no commas) — override with `format: integer` when exact counts matter
127
+ - Integer DB type + value < 10K → `integer` format (`,.0f`)
128
+ - Columns named `arr`, `mrr`, `acv`, etc. do **not** trigger currency auto-detection — always set an explicit `format: currency*` preset
129
+
130
+ ## Output format
131
+
132
+ A markdown bulleted list, severity-tagged. Group by severity, most severe first:
133
+
134
+ ```markdown
135
+ **Findings**
136
+
137
+ - `blocker` `charts.revenue_kpi`: query returns 12 rows but `type: kpi` requires
138
+ exactly 1. Aggregate with `SUM()` or take the latest row only.
139
+ - `warning` `charts.region_pie`: 7 segments in a pie chart — humans compare
140
+ angles poorly past 3. Switch to `type: bar` ordered by value.
141
+ - `warning` `queries.orders`: no `description:` field. Add one sentence stating
142
+ what the query returns.
143
+ - `nit` `charts.chart_1`: generic name. Rename to indicate intent
144
+ (e.g. `daily_active_users`).
145
+ ```
146
+
147
+ If there are no findings: emit exactly `**No findings.**` so the orchestrator
148
+ can short-circuit.
149
+
150
+ ## Severity rubric
151
+
152
+ | Tag | Meaning | Examples |
153
+ |---|---|---|
154
+ | `blocker` | The face will render wrong, error, or mislead | KPI on multi-row query; bar chart on raw rows when GROUP BY is expected |
155
+ | `warning` | The face renders but violates a clear design principle | Pie with >3 segments; missing descriptions; generic titles |
156
+ | `nit` | Stylistic — author can take or leave | Suboptimal chart name; consistent-but-verbose pattern |
157
+
158
+ ## Common mistakes
159
+
160
+ | Mistake | Fix |
161
+ |---|---|
162
+ | Returning "looks fine" without validating first | Always run `{{ s_validate_dashboard }}` — if it fails, there's nothing to review |
163
+ | Padding findings with `nit`-level noise | Cap at 5 findings total; promote the most severe |
164
+ | Emitting findings without a concrete fix | Every finding needs an actionable suggestion |
165
+ | Inventing rules not in the checklist | Stay anchored to the checklist; if you discover a real gap, file a follow-up to extend the skill |
166
+
167
+ ## Rationalizations to resist
168
+
169
+ | Excuse | Reality |
170
+ |---|---|
171
+ | "The user knows what they're doing" | Reviewing is the job. Apply the checklist. |
172
+ | "I'll just suggest the fix without the severity tag" | Severity is how the orchestrator ranks and the user prioritizes. Always tag. |
173
+ | "If I can't find anything, I'll find something" | If the face passes the checklist, say so. Padding erodes the skill's signal. |
@@ -0,0 +1,139 @@
1
+ ---
2
+ name: dashboard-visual-review
3
+ kind: workflow
4
+ description: >
5
+ Render a Dataface face to PNG and review the image against a visual-design
6
+ checklist using the agent's own vision capability. Catches problems that
7
+ YAML inspection can't see — overlapping text, contrast failures, axis-label
8
+ collisions, whitespace imbalance, KPI precision mismatches. Use when asked
9
+ to 'visually review', 'check how it looks', 'is this rendered correctly',
10
+ 'review the rendered output', or when structural review surfaces ambiguous
11
+ 'feels off but I can't say why' findings. More expensive than structural
12
+ review (rendering time + vision-token cost). Do NOT use for YAML schema or
13
+ data-shape problems (use dashboard-structural-review). Do NOT use for
14
+ comparing two versions of the same face (use the looker-compare-diff
15
+ pattern).
16
+ metadata:
17
+ author: fivetran
18
+ ---
19
+
20
+ # Dashboard Visual Review
21
+
22
+ Render the face to PNG, then evaluate the image against a visual-design
23
+ checklist. The agent host (Claude, GPT-4o, Gemini) provides the vision
24
+ capability — no external API call.
25
+
26
+ ## When to use
27
+
28
+ - Final pre-delivery polish pass
29
+ - When structural review surfaces "feels wrong but I can't say why" findings
30
+ - When the user reports a layout / readability complaint
31
+ - Second pass inside the `dashboard-review` orchestrator after structural
32
+
33
+ ## When NOT to use
34
+
35
+ - YAML schema or data-shape problems — use `dashboard-structural-review`
36
+ - Comparing two versions of a face — out of scope for this skill
37
+ - Pixel-exact regression testing — vision is the wrong tool; brittle
38
+
39
+ ## Protocol
40
+
41
+ 1. **Render the face to PNG.** Call `{{ s_render_dashboard }}`:
42
+
43
+ {{ s_render_png_example }}
44
+
45
+ If render fails, report the error and stop — there's nothing visual to
46
+ review.
47
+
48
+ 2. **Read the PNG** with the agent's image-loading capability.
49
+
50
+ 3. **Evaluate against the checklist below.** Emit findings in the same format
51
+ as `dashboard-structural-review` so the orchestrator can merge them.
52
+
53
+ ## Checklist
54
+
55
+ ### Visual hierarchy
56
+
57
+ - [ ] Eye is drawn to the most important element first (largest KPI, headline
58
+ chart, top-left position)
59
+ - [ ] Reading flow is top-down / left-to-right — no important data in
60
+ bottom-right that should be top-left
61
+ - [ ] Whitespace separates groups without leaving large dead zones
62
+
63
+ ### Text legibility
64
+
65
+ - [ ] No text overflow (clipped numbers, ellipsized labels that hide the value)
66
+ - [ ] No wrap thrash (axis labels wrapping awkwardly mid-word)
67
+ - [ ] Axis tick labels readable at rendered size (rotate if cramped)
68
+ - [ ] Legend labels match the chart's encoding (no orphan legend entries)
69
+
70
+ ### Color and contrast
71
+
72
+ - [ ] Foreground text meets WCAG AA contrast against its background
73
+ - [ ] Color palette is consistent across charts (same series = same color)
74
+ - [ ] No clashing or vibrating color pairs (red on green, complementary hues
75
+ at full saturation)
76
+ - [ ] Conditional formatting communicates severity, not decoration
77
+
78
+ ### KPIs and numbers
79
+
80
+ - [ ] KPI values render with appropriate precision (revenue in `$1.2M`, not
81
+ `1247392.7438`)
82
+ - [ ] Units are consistent (don't mix `1,247` and `1.2K` in the same row)
83
+ - [ ] Prior-period deltas have a sign and a directional cue (▲ / ▼ / color)
84
+ - [ ] Currency / percent suffixes are present where expected
85
+
86
+ ### Composition and balance
87
+
88
+ - [ ] No crammed corners — every chart has padding within its cell
89
+ - [ ] Row heights match the visual weight of their content (KPIs short,
90
+ charts tall)
91
+ - [ ] Tables don't overflow the page width (horizontal scroll only if
92
+ unavoidable)
93
+ - [ ] Empty / null states render gracefully (no raw `None` or empty rectangles)
94
+
95
+ ## Output format
96
+
97
+ Same shape as `dashboard-structural-review` so findings merge cleanly:
98
+
99
+ ```markdown
100
+ **Findings**
101
+
102
+ - `blocker` `charts.revenue_kpi`: KPI shows `1247392.74` — should be `$1.2M`.
103
+ Add `format: currency_compact` to the chart.
104
+ - `warning` `charts.regions_bar`: x-axis labels overlap at rendered width.
105
+ Rotate to -45° or shorten labels.
106
+ - `warning` `chart sequence`: revenue trend (most important) sits bottom-right
107
+ while a smaller breakdown sits top-left. Swap positions.
108
+ - `nit` `charts.users_pie`: colors are vibrant and clash. Switch to a muted
109
+ qualitative palette.
110
+ ```
111
+
112
+ If there are no findings: emit exactly `**No findings.**`.
113
+
114
+ ## Severity rubric
115
+
116
+ Use the same tags as `dashboard-structural-review`:
117
+
118
+ | Tag | Meaning |
119
+ |---|---|
120
+ | `blocker` | User cannot read or trust the rendered output |
121
+ | `warning` | Renders, but violates a clear visual principle |
122
+ | `nit` | Stylistic — author can take or leave |
123
+
124
+ ## Common mistakes
125
+
126
+ | Mistake | Fix |
127
+ |---|---|
128
+ | Reviewing without rendering | The PNG is the artifact under review — render first, no shortcuts |
129
+ | Critiquing the YAML instead of the image | That's structural review's job — stay on visual signals only |
130
+ | Inventing visual problems that aren't in the rendered output | Anchor every finding to what's visible in the PNG |
131
+ | Re-flagging issues already raised by structural review | Visual review covers what YAML inspection can't see; trust the orchestrator to dedupe |
132
+
133
+ ## Rationalizations to resist
134
+
135
+ | Excuse | Reality |
136
+ |---|---|
137
+ | "I can guess what it looks like from the YAML" | You can't — that's why visual review exists. Render or skip the pass. |
138
+ | "Contrast looks fine to me" | If you're unsure, flag it as a `warning`. Accessibility is not subjective when it fails WCAG. |
139
+ | "The vision model is expensive, I'll skim" | Don't run the skill at all if you're going to skim — the orchestrator can route to structural-only. |
@@ -0,0 +1,177 @@
1
+ ---
2
+ name: dataface-mcp-setup
3
+ kind: workflow
4
+ surfaces: [cli]
5
+ description: >
6
+ Set up the Dataface MCP server for AI assistant integration. Use when
7
+ running 'dft init mcp', installing Dataface, configuring MCP for Cursor,
8
+ Claude Desktop, VS Code, Codex, Copilot, or any MCP-compatible client,
9
+ or troubleshooting MCP connection issues like 'server not starting',
10
+ 'tools not appearing', 'MCP requires additional dependencies'. Do NOT
11
+ use for building dashboards (use dashboard-build). Do NOT
12
+ use for dashboard errors (use dataface-troubleshooting).
13
+ metadata:
14
+ author: fivetran
15
+ ---
16
+
17
+ # Configuring Dataface MCP Server
18
+
19
+ Set up the Dataface MCP server to give AI assistants access to dashboard tools and resources.
20
+
21
+ > This skill is **CLI-only** (`surfaces: [cli]`) — it walks a human operator
22
+ > through installing the MCP server from a shell. An already-connected MCP
23
+ > agent does not need to read it.
24
+
25
+ ## Quick Setup
26
+
27
+ The fastest way — auto-detects your AI clients and configures them:
28
+
29
+ ```bash
30
+ pip install "dataface[mcp]"
31
+ dft init mcp
32
+ ```
33
+
34
+ This detects Cursor, VS Code, Claude Desktop, Claude Code, Copilot, and Codex, then writes the appropriate config files.
35
+
36
+ ### Target a Specific Client
37
+
38
+ ```bash
39
+ dft init mcp cursor # Configure Cursor only
40
+ dft init mcp vscode # Configure VS Code only
41
+ dft init mcp claude # Configure Claude Desktop only
42
+ dft init mcp claude-code # Configure Claude Code only
43
+ dft init mcp codex # Configure Codex CLI only
44
+ dft init mcp copilot # Configure GitHub Copilot Coding Agent only
45
+ dft init mcp --all # Write every supported config file
46
+ dft init mcp print # Print JSON config to stdout (manual setup)
47
+ ```
48
+
49
+ ### Force Update
50
+
51
+ ```bash
52
+ dft init mcp cursor -f # Overwrite existing config
53
+ ```
54
+
55
+ After running `dft init mcp`, restart your AI client for changes to take effect.
56
+
57
+ ## Manual Configuration
58
+
59
+ If you prefer manual setup, add this to your client's MCP config.
60
+
61
+ For JSON-based clients (Cursor, VS Code, Claude Desktop, Claude Code, Copilot):
62
+
63
+ ```json
64
+ {
65
+ "mcpServers": {
66
+ "dataface": {
67
+ "command": "/path/to/dft",
68
+ "args": ["mcp", "serve"]
69
+ }
70
+ }
71
+ }
72
+ ```
73
+
74
+ For Codex (TOML — `.codex/config.toml`):
75
+
76
+ ```toml
77
+ [mcp_servers.dataface]
78
+ command = "/path/to/dft"
79
+ args = ["mcp", "serve"]
80
+ ```
81
+
82
+ If your Dataface or dbt project lives in a subdirectory of the workspace your
83
+ AI client opens (or the server otherwise won't be launched with cwd at the
84
+ project root), append `"--project-dir", "/abs/path/to/your/project"` to `args`.
85
+ `dft init mcp` will add this for you when its `--project-dir` flag is used or
86
+ when it detects that the workspace and project roots diverge.
87
+
88
+ Config file locations:
89
+ - **Cursor**: `.cursor/mcp.json`
90
+ - **VS Code / Copilot agent mode**: `.vscode/mcp.json` with a `servers` root key
91
+ - **Claude Desktop**: `~/.config/claude/config.json`
92
+ - **Claude Code**: `.mcp.json` at the project root
93
+ - **Codex**: `.codex/config.toml` (project must be trusted by Codex) — globally, `~/.codex/config.toml`
94
+ - **GitHub Copilot Coding Agent**: `.github/copilot/mcp.json` with a `servers` root key
95
+
96
+ Use the absolute path to `dft` in the `command` field. Find it with `which dft`.
97
+
98
+ ## Available Tools
99
+
100
+ After setup, your AI assistant has access to these tools:
101
+
102
+ | Tool | Purpose |
103
+ |------|---------|
104
+ | `validate_dashboard` | Fast YAML schema and cross-reference validation — use after every file edit |
105
+ | `render_dashboard` | Compile, execute queries, and generate visual HTML/text output |
106
+ | `query_face` | Run one named query from a saved face and inspect columns/sample rows |
107
+ | `execute_query` | Run ad-hoc SQL queries while exploring data or testing SQL |
108
+ | `describe_query` | Return column schema for a SQL string without fetching rows |
109
+ | `schema` | Drill the data hierarchy: source → schema → table → column. Use `--json \| jq` at the CLI for ad-hoc cross-cutting queries; use `dft schema -s <kw>` for keyword/predicate corpus search, or `schema(source=S, schema=N, table_search="pattern")` at level 3 to filter the table list by regexp (table name or cached column name match). |
110
+ | `schema_search` | Full-text + filter search across the schema corpus (CLI equivalent: `dft schema -s <kw>`) |
111
+ | `docs` | Browse the packaged YAML reference corpus offline |
112
+ | `list_skills` / `get_skill` | Discover and read packaged Dataface authoring skills — `get_skill` returns the full body including example YAML |
113
+
114
+ ## Available Resources
115
+
116
+ | Resource | Content |
117
+ |----------|---------|
118
+ | `dataface://docs/all` | Complete DATAFACE_SYNTAX.md (whole reference, unsliced) |
119
+ | `dataface://docs/{topic}` | One H2 section by slug (`cheatsheet`, `face`, `charts`, `queries`, `variables`, `layout`, `errors`) |
120
+ | `dataface://guide/dashboard-design` | Dashboard design principles and patterns |
121
+ | `dataface://guide/report-design` | Report design principles and narrative structure |
122
+ | `dataface://guide/dashboard-build` | Build-test-iterate workflow best practices |
123
+ | `dataface://guide/dashboard-review` | Self-review checklist for a finished face |
124
+ | `dataface://dashboards` | List of all dashboards in the project |
125
+ | `dataface://dashboard/{path}` | YAML content and compiled structure of a specific dashboard |
126
+
127
+ ## Troubleshooting
128
+
129
+ ### "MCP server requires additional dependencies"
130
+
131
+ Install the MCP extras:
132
+
133
+ ```bash
134
+ pip install "dataface[mcp]"
135
+ ```
136
+
137
+ ### MCP server not starting
138
+
139
+ 1. Verify `dft` is accessible: `which dft`
140
+ 2. Ensure the path in MCP config is absolute, not relative
141
+ 3. Check that your Python environment has `dataface[mcp]` installed
142
+ 4. Try running `dft mcp serve` manually to see error output
143
+
144
+ ### "No AI client directories detected"
145
+
146
+ `dft init mcp` looks for `.cursor/`, `.codex/`, `.vscode/`, `.github/`, `CLAUDE.md`, `AGENTS.md`, or `~/.config/claude/` to auto-detect clients. If none exist yet, specify the client explicitly:
147
+
148
+ ```bash
149
+ dft init mcp cursor
150
+ ```
151
+
152
+ ### Tools not appearing in AI client
153
+
154
+ 1. Restart the AI client after running `dft init mcp`
155
+ 2. Verify the config file was written: check `.cursor/mcp.json` or equivalent
156
+ 3. Ensure the `command` path in the config points to the correct `dft` binary
157
+
158
+ ## Verifying the Setup
159
+
160
+ After configuration, test by asking your AI assistant:
161
+
162
+ - "List available data sources" → should invoke `schema` (no args)
163
+ - "Show me the database schema" → should invoke `schema(source=...)`
164
+ - "Validate this dashboard YAML file" → should invoke `validate_dashboard`
165
+
166
+ If the assistant doesn't recognize these tools, the MCP server isn't connected — check the troubleshooting steps above.
167
+
168
+ ## Authoring Metadata Convention
169
+
170
+ When the assistant edits Dataface YAML through MCP tools, require `description` metadata on:
171
+
172
+ - `queries.*.description`
173
+ - `charts.*.description`
174
+ - `variables.*.description`
175
+ - Layout objects (`rows`/`cols`/`grid.items`/`tabs.items`) where meaningful
176
+
177
+ This improves downstream AI search/context quality and enables optional UI tooltips.