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.
- d3_format/__init__.py +14 -0
- d3_format/errors.py +19 -0
- d3_format/format.py +551 -0
- d3_format/spec.py +159 -0
- dataface/DATAFACE_SYNTAX.md +1135 -0
- dataface/__init__.py +93 -0
- dataface/_docs_site.py +20 -0
- dataface/_install_hint.py +26 -0
- dataface/agent_api/__init__.py +79 -0
- dataface/agent_api/_init_templates/__init__.py +0 -0
- dataface/agent_api/_init_templates/agents_dft_snippet.md +26 -0
- dataface/agent_api/_init_templates/dataface.yml +15 -0
- dataface/agent_api/_init_templates/faces-dataface.yml +144 -0
- dataface/agent_api/_init_templates/index.md +24 -0
- dataface/agent_api/_paths.py +118 -0
- dataface/agent_api/_project_agents_md.py +43 -0
- dataface/agent_api/_session_store.py +486 -0
- dataface/agent_api/_state.py +28 -0
- dataface/agent_api/chat.py +221 -0
- dataface/agent_api/dashboards.py +257 -0
- dataface/agent_api/describe.py +366 -0
- dataface/agent_api/describe_query.py +120 -0
- dataface/agent_api/docs/__init__.py +25 -0
- dataface/agent_api/docs/_loader.py +292 -0
- dataface/agent_api/docs/yaml-reference.md +2757 -0
- dataface/agent_api/file_refs.py +118 -0
- dataface/agent_api/init.py +126 -0
- dataface/agent_api/inspect.py +128 -0
- dataface/agent_api/mcp_install.py +170 -0
- dataface/agent_api/query.py +274 -0
- dataface/agent_api/schema.py +658 -0
- dataface/agent_api/schema_search.py +284 -0
- dataface/agent_api/search.py +270 -0
- dataface/agent_api/skill_install.py +141 -0
- dataface/agent_api/skill_render.py +90 -0
- dataface/agent_api/skills.py +293 -0
- dataface/agent_api/surface_aliases.yaml +128 -0
- dataface/agent_api/validate.py +175 -0
- dataface/agent_api/validate_query.py +84 -0
- dataface/ai/__init__.py +39 -0
- dataface/ai/agent.py +139 -0
- dataface/ai/context.py +45 -0
- dataface/ai/events.py +62 -0
- dataface/ai/external_mcp.py +610 -0
- dataface/ai/generate_sql.py +96 -0
- dataface/ai/llm.py +403 -0
- dataface/ai/mcp/__init__.py +51 -0
- dataface/ai/mcp/server.py +289 -0
- dataface/ai/memories.py +85 -0
- dataface/ai/prompts.py +177 -0
- dataface/ai/schema_context.py +138 -0
- dataface/ai/skills/before-after-comparison/SKILL.md +102 -0
- dataface/ai/skills/before-after-comparison/examples/before-after-comparison.yml +24 -0
- dataface/ai/skills/dashboard-build/SKILL.md +212 -0
- dataface/ai/skills/dashboard-build/examples/_smoke.yml +15 -0
- dataface/ai/skills/dashboard-design/SKILL.md +182 -0
- dataface/ai/skills/dashboard-review/SKILL.md +113 -0
- dataface/ai/skills/dashboard-structural-review/SKILL.md +173 -0
- dataface/ai/skills/dashboard-visual-review/SKILL.md +139 -0
- dataface/ai/skills/dataface-mcp-setup/SKILL.md +177 -0
- dataface/ai/skills/dataface-troubleshooting/SKILL.md +225 -0
- dataface/ai/skills/drill-down-link/SKILL.md +112 -0
- dataface/ai/skills/drill-down-link/examples/drill-down-link.yml +27 -0
- dataface/ai/skills/faceted-small-multiples/SKILL.md +116 -0
- dataface/ai/skills/faceted-small-multiples/examples/faceted-small-multiples.yml +33 -0
- dataface/ai/skills/filter-bar-with-variables/SKILL.md +105 -0
- dataface/ai/skills/filter-bar-with-variables/examples/filter-bar-with-variables.yml +49 -0
- dataface/ai/skills/kpi-row/SKILL.md +101 -0
- dataface/ai/skills/kpi-row/examples/kpi-row.yml +55 -0
- dataface/ai/skills/report-design/SKILL.md +184 -0
- dataface/ai/skills/single-metric-bignum/SKILL.md +90 -0
- dataface/ai/skills/single-metric-bignum/examples/single-metric-bignum.yml +27 -0
- dataface/ai/skills/table-heavy-ops-dashboard/SKILL.md +114 -0
- dataface/ai/skills/table-heavy-ops-dashboard/examples/table-heavy-ops-dashboard.yml +48 -0
- dataface/ai/skills/time-series-trend/SKILL.md +93 -0
- dataface/ai/skills/time-series-trend/examples/time-series-trend.yml +26 -0
- dataface/ai/skills/top-n-with-detail/SKILL.md +98 -0
- dataface/ai/skills/top-n-with-detail/examples/top-n-with-detail.yml +45 -0
- dataface/ai/skills/two-by-two-grid-overview/SKILL.md +78 -0
- dataface/ai/skills/two-by-two-grid-overview/examples/two-by-two-grid-overview.yml +64 -0
- dataface/ai/tool_schemas.py +132 -0
- dataface/ai/tools/__init__.py +312 -0
- dataface/ai/yaml_utils.py +57 -0
- dataface/cli/__init__.py +3 -0
- dataface/cli/_console.py +48 -0
- dataface/cli/_error_format.py +83 -0
- dataface/cli/_extras.py +190 -0
- dataface/cli/_json_output.py +8 -0
- dataface/cli/_parsing.py +17 -0
- dataface/cli/_version_info.py +56 -0
- dataface/cli/commands/__init__.py +3 -0
- dataface/cli/commands/_agent_input.py +205 -0
- dataface/cli/commands/_agent_server.py +115 -0
- dataface/cli/commands/chat.py +645 -0
- dataface/cli/commands/describe.py +107 -0
- dataface/cli/commands/docs.py +131 -0
- dataface/cli/commands/extension.py +179 -0
- dataface/cli/commands/init.py +240 -0
- dataface/cli/commands/inspect.py +94 -0
- dataface/cli/commands/mcp_init.py +167 -0
- dataface/cli/commands/query.py +386 -0
- dataface/cli/commands/render.py +291 -0
- dataface/cli/commands/schema.py +411 -0
- dataface/cli/commands/search.py +49 -0
- dataface/cli/commands/serve.py +114 -0
- dataface/cli/commands/skills.py +133 -0
- dataface/cli/commands/skills_init.py +161 -0
- dataface/cli/commands/validate.py +63 -0
- dataface/cli/main.py +1501 -0
- dataface/core/__init__.py +75 -0
- dataface/core/compile/__init__.py +244 -0
- dataface/core/compile/_jinja_helpers.py +78 -0
- dataface/core/compile/channel.py +222 -0
- dataface/core/compile/chart_focus.py +101 -0
- dataface/core/compile/chart_resolved.py +169 -0
- dataface/core/compile/chart_type_detection.py +489 -0
- dataface/core/compile/chart_update.py +261 -0
- dataface/core/compile/colors.py +64 -0
- dataface/core/compile/compiler.py +904 -0
- dataface/core/compile/config.py +823 -0
- dataface/core/compile/custom_chart_types.py +208 -0
- dataface/core/compile/data_table_attachment.py +1287 -0
- dataface/core/compile/detect.py +110 -0
- dataface/core/compile/errors.py +302 -0
- dataface/core/compile/filter_injection.py +319 -0
- dataface/core/compile/introspection.py +527 -0
- dataface/core/compile/jinja.py +511 -0
- dataface/core/compile/labels_env.py +52 -0
- dataface/core/compile/markdown.py +154 -0
- dataface/core/compile/meta.py +388 -0
- dataface/core/compile/models/__init__.py +0 -0
- dataface/core/compile/models/chart/__init__.py +0 -0
- dataface/core/compile/models/chart/authored.py +2137 -0
- dataface/core/compile/models/chart/compiled.py +398 -0
- dataface/core/compile/models/config.py +347 -0
- dataface/core/compile/models/face/__init__.py +0 -0
- dataface/core/compile/models/face/authored.py +659 -0
- dataface/core/compile/models/face/compiled.py +522 -0
- dataface/core/compile/models/factories.py +201 -0
- dataface/core/compile/models/markers.py +40 -0
- dataface/core/compile/models/palette.py +36 -0
- dataface/core/compile/models/primitives.py +415 -0
- dataface/core/compile/models/query/__init__.py +0 -0
- dataface/core/compile/models/query/authored.py +246 -0
- dataface/core/compile/models/query/compiled.py +710 -0
- dataface/core/compile/models/refs.py +137 -0
- dataface/core/compile/models/source.py +611 -0
- dataface/core/compile/models/style/__init__.py +0 -0
- dataface/core/compile/models/style/authored.py +481 -0
- dataface/core/compile/models/style/compiled.py +3399 -0
- dataface/core/compile/models/style/merged.py +1682 -0
- dataface/core/compile/models/theme.py +362 -0
- dataface/core/compile/models/variable/__init__.py +0 -0
- dataface/core/compile/models/variable/authored.py +254 -0
- dataface/core/compile/models/vega_lite/__init__.py +0 -0
- dataface/core/compile/models/vega_lite/config.py +510 -0
- dataface/core/compile/models/vega_lite/contracts.py +171 -0
- dataface/core/compile/normalize_charts.py +494 -0
- dataface/core/compile/normalize_layout.py +1000 -0
- dataface/core/compile/normalize_queries.py +297 -0
- dataface/core/compile/normalize_variables.py +489 -0
- dataface/core/compile/normalizer.py +543 -0
- dataface/core/compile/palette.py +1100 -0
- dataface/core/compile/parameterized.py +658 -0
- dataface/core/compile/parser.py +228 -0
- dataface/core/compile/schema.py +20 -0
- dataface/core/compile/schema_renderers/__init__.py +0 -0
- dataface/core/compile/schema_renderers/json_schema.py +163 -0
- dataface/core/compile/schema_renderers/prompt.py +152 -0
- dataface/core/compile/schema_renderers/vscode_schema.py +301 -0
- dataface/core/compile/sizing.py +2126 -0
- dataface/core/compile/sources.py +518 -0
- dataface/core/compile/sql_authoring_lint.py +56 -0
- dataface/core/compile/style_cascade.py +471 -0
- dataface/core/compile/typography.py +299 -0
- dataface/core/compile/validator.py +301 -0
- dataface/core/compile/variables.py +53 -0
- dataface/core/compile/vega_config.py +98 -0
- dataface/core/compile/vega_lite/__init__.py +6 -0
- dataface/core/compile/vega_lite/validation.py +95 -0
- dataface/core/compile/yaml_error_formatter.py +838 -0
- dataface/core/connections.py +38 -0
- dataface/core/dashboard.py +358 -0
- dataface/core/defaults/default_config.yml +101 -0
- dataface/core/defaults/palettes/categorical/category-10-dark.yml +32 -0
- dataface/core/defaults/palettes/categorical/category-10-light.yml +43 -0
- dataface/core/defaults/palettes/categorical/category-10.yml +31 -0
- dataface/core/defaults/palettes/categorical/category-6-tonal-blue.yml +22 -0
- dataface/core/defaults/palettes/categorical/category-6-tonal-brown.yml +29 -0
- dataface/core/defaults/palettes/categorical/category-6-tonal-green.yml +20 -0
- dataface/core/defaults/palettes/categorical/category-6-tonal-orange.yml +21 -0
- dataface/core/defaults/palettes/categorical/category-6-tonal-purple.yml +20 -0
- dataface/core/defaults/palettes/categorical/editorial-10-dark.yml +32 -0
- dataface/core/defaults/palettes/categorical/editorial-10.yml +40 -0
- dataface/core/defaults/palettes/categorical/hero-6.yml +17 -0
- dataface/core/defaults/palettes/categorical/single-blue.yml +11 -0
- dataface/core/defaults/palettes/categorical/tableau.yml +20 -0
- dataface/core/defaults/palettes/data/xkcd_colors.json +3803 -0
- dataface/core/defaults/palettes/diverging/blue-red.yml +25 -0
- dataface/core/defaults/palettes/diverging/coolwarm.yml +24 -0
- dataface/core/defaults/palettes/diverging/crimson-green.yml +23 -0
- dataface/core/defaults/palettes/diverging/orange-teal.yml +23 -0
- dataface/core/defaults/palettes/diverging/sunset.yml +24 -0
- dataface/core/defaults/palettes/scaffold/dft-creams.yml +38 -0
- dataface/core/defaults/palettes/scaffold/dft-grays.yml +53 -0
- dataface/core/defaults/palettes/sequential/amber.yml +22 -0
- dataface/core/defaults/palettes/sequential/blue.yml +22 -0
- dataface/core/defaults/palettes/sequential/brown.yml +22 -0
- dataface/core/defaults/palettes/sequential/gray.yml +22 -0
- dataface/core/defaults/palettes/sequential/green.yml +22 -0
- dataface/core/defaults/palettes/sequential/purple.yml +22 -0
- dataface/core/defaults/palettes/sequential/rust.yml +22 -0
- dataface/core/defaults/palettes/sequential/teal.yml +22 -0
- dataface/core/defaults/palettes/tone/negative.yml +32 -0
- dataface/core/defaults/palettes/tone/positive.yml +22 -0
- dataface/core/defaults/palettes/tone/warning.yml +22 -0
- dataface/core/defaults/themes/_base.yaml +786 -0
- dataface/core/defaults/themes/bi.yaml +16 -0
- dataface/core/defaults/themes/carbong100.yaml +41 -0
- dataface/core/defaults/themes/cream.yaml +122 -0
- dataface/core/defaults/themes/dark.yaml +40 -0
- dataface/core/defaults/themes/diagnostics-title-angle-extreme.yaml +9 -0
- dataface/core/defaults/themes/diagnostics-title-baseline-extreme.yaml +9 -0
- dataface/core/defaults/themes/diagnostics-title-baseline.yaml +24 -0
- dataface/core/defaults/themes/diagnostics-title-center.yaml +8 -0
- dataface/core/defaults/themes/diagnostics-title-color-extreme.yaml +24 -0
- dataface/core/defaults/themes/diagnostics-title-font-extreme.yaml +25 -0
- dataface/core/defaults/themes/diagnostics-title-left.yaml +8 -0
- dataface/core/defaults/themes/diagnostics-title-offset-extreme.yaml +9 -0
- dataface/core/defaults/themes/diagnostics-title-size-extreme.yaml +24 -0
- dataface/core/defaults/themes/diagnostics-title-weight-extreme.yaml +24 -0
- dataface/core/defaults/themes/editorial.yaml +147 -0
- dataface/core/defaults/themes/light.yaml +30 -0
- dataface/core/defaults/themes/looker.yaml +17 -0
- dataface/core/defaults/themes/stark.yaml +134 -0
- dataface/core/errors/__init__.py +67 -0
- dataface/core/errors/codes_compile.py +56 -0
- dataface/core/errors/codes_execute.py +177 -0
- dataface/core/errors/codes_render.py +106 -0
- dataface/core/errors/codes_unknown.py +15 -0
- dataface/core/errors/hints.py +74 -0
- dataface/core/errors/registry.py +42 -0
- dataface/core/errors/structured.py +92 -0
- dataface/core/execute/__init__.py +91 -0
- dataface/core/execute/adapters/__init__.py +49 -0
- dataface/core/execute/adapters/adapter_registry.py +400 -0
- dataface/core/execute/adapters/base.py +245 -0
- dataface/core/execute/adapters/csv_adapter.py +239 -0
- dataface/core/execute/adapters/dbt_adapter.py +283 -0
- dataface/core/execute/adapters/dbt_adapter_factory.py +212 -0
- dataface/core/execute/adapters/dbt_macro_loader.py +95 -0
- dataface/core/execute/adapters/dbt_utils.py +150 -0
- dataface/core/execute/adapters/http_adapter.py +224 -0
- dataface/core/execute/adapters/metricflow_adapter.py +94 -0
- dataface/core/execute/adapters/schema_resolver_adapter.py +144 -0
- dataface/core/execute/adapters/sql_adapter.py +710 -0
- dataface/core/execute/adapters/values_adapter.py +58 -0
- dataface/core/execute/batch.py +744 -0
- dataface/core/execute/cache_backend.py +135 -0
- dataface/core/execute/cache_keys.py +66 -0
- dataface/core/execute/dbt_jinja.py +21 -0
- dataface/core/execute/dialects/__init__.py +121 -0
- dataface/core/execute/dialects/athena.py +75 -0
- dataface/core/execute/dialects/base.py +302 -0
- dataface/core/execute/dialects/bigquery.py +38 -0
- dataface/core/execute/dialects/databricks.py +68 -0
- dataface/core/execute/dialects/duckdb.py +35 -0
- dataface/core/execute/dialects/mysql.py +68 -0
- dataface/core/execute/dialects/postgres.py +39 -0
- dataface/core/execute/dialects/redshift.py +12 -0
- dataface/core/execute/dialects/snowflake.py +51 -0
- dataface/core/execute/dialects/sqlserver.py +92 -0
- dataface/core/execute/duckdb_cache.py +712 -0
- dataface/core/execute/duckdb_config.py +26 -0
- dataface/core/execute/errors.py +213 -0
- dataface/core/execute/executor.py +1249 -0
- dataface/core/execute/parallel.py +162 -0
- dataface/core/execute/setup_sql.py +58 -0
- dataface/core/execute/source_registry.py +72 -0
- dataface/core/execute/source_resolver.py +255 -0
- dataface/core/execute/sql_guard.py +387 -0
- dataface/core/execute/sql_literals.py +199 -0
- dataface/core/fonts.py +52 -0
- dataface/core/inspect/__init__.py +32 -0
- dataface/core/inspect/cache_factory.py +98 -0
- dataface/core/inspect/db_types.py +162 -0
- dataface/core/inspect/dbt_schema.py +96 -0
- dataface/core/inspect/defaults.yml +37 -0
- dataface/core/inspect/fanout_risk.py +109 -0
- dataface/core/inspect/manifest_utils.py +77 -0
- dataface/core/inspect/partials/categorical.yml +40 -0
- dataface/core/inspect/partials/date.yml +40 -0
- dataface/core/inspect/partials/numeric.yml +55 -0
- dataface/core/inspect/partition_types.py +38 -0
- dataface/core/inspect/query_validator.py +975 -0
- dataface/core/inspect/renderer.py +354 -0
- dataface/core/inspect/resolver.py +808 -0
- dataface/core/inspect/search.py +461 -0
- dataface/core/inspect/sources/__init__.py +32 -0
- dataface/core/inspect/sources/dbt.py +738 -0
- dataface/core/inspect/sources/duckdb_utils.py +66 -0
- dataface/core/inspect/templates/__init__.py +1 -0
- dataface/core/inspect/templates/categorical_column.yml +196 -0
- dataface/core/inspect/templates/charts.yml +109 -0
- dataface/core/inspect/templates/date_column.yml +248 -0
- dataface/core/inspect/templates/model.yml +138 -0
- dataface/core/inspect/templates/numeric_column.yml +261 -0
- dataface/core/inspect/templates/quality.yml +80 -0
- dataface/core/inspect/templates/string_column.yml +263 -0
- dataface/core/project_roots.py +165 -0
- dataface/core/render/__init__.py +87 -0
- dataface/core/render/board_links.py +176 -0
- dataface/core/render/chart/__init__.py +27 -0
- dataface/core/render/chart/arc_attached_table.py +251 -0
- dataface/core/render/chart/artifacts.py +16 -0
- dataface/core/render/chart/callout.py +225 -0
- dataface/core/render/chart/decisions.py +358 -0
- dataface/core/render/chart/geo.py +700 -0
- dataface/core/render/chart/kpi.py +916 -0
- dataface/core/render/chart/labels.py +76 -0
- dataface/core/render/chart/pipeline.py +818 -0
- dataface/core/render/chart/presentation.py +36 -0
- dataface/core/render/chart/profile.py +3438 -0
- dataface/core/render/chart/render_single.py +347 -0
- dataface/core/render/chart/renderers.py +193 -0
- dataface/core/render/chart/rendering.py +565 -0
- dataface/core/render/chart/serialization.py +90 -0
- dataface/core/render/chart/spark.py +496 -0
- dataface/core/render/chart/spark_bar.py +370 -0
- dataface/core/render/chart/spec_builders.py +154 -0
- dataface/core/render/chart/standard_renderer.py +2645 -0
- dataface/core/render/chart/table.py +2957 -0
- dataface/core/render/chart/table_support.py +1452 -0
- dataface/core/render/chart/tick_values.py +66 -0
- dataface/core/render/chart/time_unit_detect.py +809 -0
- dataface/core/render/chart/title_overflow.py +157 -0
- dataface/core/render/chart/type_inference.py +122 -0
- dataface/core/render/chart/validation.py +99 -0
- dataface/core/render/chart/vega_lite.py +125 -0
- dataface/core/render/chart/vega_lite_types.py +268 -0
- dataface/core/render/chart/vl_field_maps.py +346 -0
- dataface/core/render/chart_interactivity.py +24 -0
- dataface/core/render/control_registry.py +287 -0
- dataface/core/render/converters/__init__.py +24 -0
- dataface/core/render/converters/chart.py +276 -0
- dataface/core/render/converters/html.py +98 -0
- dataface/core/render/converters/pdf.py +40 -0
- dataface/core/render/converters/png.py +41 -0
- dataface/core/render/errors.py +144 -0
- dataface/core/render/face_api.py +160 -0
- dataface/core/render/faces.py +1194 -0
- dataface/core/render/font_measurement.py +48 -0
- dataface/core/render/font_support.py +197 -0
- dataface/core/render/fonts/DFTSansTabular-Regular.ttf +0 -0
- dataface/core/render/fonts/DFTSansTabular-Regular.woff2 +0 -0
- dataface/core/render/fonts/DFTSerifOldstyleProportional-Regular.ttf +0 -0
- dataface/core/render/fonts/DFTSerifOldstyleTabular-Regular.ttf +0 -0
- dataface/core/render/fonts/InterVariable.ttf +0 -0
- dataface/core/render/fonts/InterVariable.woff2 +0 -0
- dataface/core/render/fonts/NOTO_COLOR_EMOJI_LICENSE.txt +93 -0
- dataface/core/render/fonts/NOTO_EMOJI_LICENSE.txt +93 -0
- dataface/core/render/fonts/NotoColorEmoji-Regular.ttf +0 -0
- dataface/core/render/fonts/NotoColorEmoji-Regular.woff2 +0 -0
- dataface/core/render/fonts/NotoEmoji-Regular.ttf +0 -0
- dataface/core/render/fonts/NotoEmoji-Regular.woff2 +0 -0
- dataface/core/render/fonts/SOURCE_CODE_PRO_LICENSE.txt +93 -0
- dataface/core/render/fonts/SOURCE_SERIF_4_LICENSE.txt +98 -0
- dataface/core/render/fonts/SourceCodePro-Regular.ttf +0 -0
- dataface/core/render/fonts/SourceSerif4-Regular.ttf +0 -0
- dataface/core/render/fonts/_emoji_font_face.css +43 -0
- dataface/core/render/fonts/source-serif-4-variable-latin.woff2 +0 -0
- dataface/core/render/format_utils.py +329 -0
- dataface/core/render/geo_defaults.yml +28 -0
- dataface/core/render/json_format.py +146 -0
- dataface/core/render/layout_sizing.py +865 -0
- dataface/core/render/layouts.py +541 -0
- dataface/core/render/markdown_defaults.yml +16 -0
- dataface/core/render/missing_vars_prompt.py +79 -0
- dataface/core/render/placeholder.py +389 -0
- dataface/core/render/render_result.py +14 -0
- dataface/core/render/renderer.py +467 -0
- dataface/core/render/script_embedding.py +16 -0
- dataface/core/render/svg_utils.py +212 -0
- dataface/core/render/template_loader.py +69 -0
- dataface/core/render/templates/controls/_styles.css +606 -0
- dataface/core/render/templates/controls/checkbox.html +16 -0
- dataface/core/render/templates/controls/date.html +16 -0
- dataface/core/render/templates/controls/number.html +19 -0
- dataface/core/render/templates/controls/readonly.html +9 -0
- dataface/core/render/templates/controls/select.html +21 -0
- dataface/core/render/templates/controls/slider.html +22 -0
- dataface/core/render/templates/controls/text.html +16 -0
- dataface/core/render/templates/scripts/chart_interactivity.js +191 -0
- dataface/core/render/templates/scripts/variables.js +976 -0
- dataface/core/render/templates/svg/grid_pattern.svg +3 -0
- dataface/core/render/templates/svg/styles.css +51 -0
- dataface/core/render/terminal.py +311 -0
- dataface/core/render/terminal_charts.py +563 -0
- dataface/core/render/terminal_defaults.yml +2 -0
- dataface/core/render/terminal_layouts.py +299 -0
- dataface/core/render/terminal_text.py +31 -0
- dataface/core/render/text/__init__.py +1 -0
- dataface/core/render/text/case.py +113 -0
- dataface/core/render/text_format.py +129 -0
- dataface/core/render/utils.py +106 -0
- dataface/core/render/variable_controls.py +946 -0
- dataface/core/render/variable_input_refinement.py +140 -0
- dataface/core/render/warnings/__init__.py +15 -0
- dataface/core/render/warnings/bar_color_1_to_1_with_x.py +80 -0
- dataface/core/render/warnings/base.py +44 -0
- dataface/core/render/warnings/fanout_risk.py +15 -0
- dataface/core/render/warnings/from_query_diagnostic.py +56 -0
- dataface/core/render/warnings/missing_join_predicate.py +13 -0
- dataface/core/render/warnings/query_parse_error.py +14 -0
- dataface/core/render/warnings/query_returned_zero_rows.py +42 -0
- dataface/core/render/warnings/reaggregation.py +14 -0
- dataface/core/render/warnings/registry.py +45 -0
- dataface/core/render/warnings/suppression.py +46 -0
- dataface/core/render/warnings/temporal_single_point.py +63 -0
- dataface/core/render/warnings/unreferenced_chart.py +15 -0
- dataface/core/render/warnings/y_encoding_mostly_null.py +76 -0
- dataface/core/render/yaml_format.py +167 -0
- dataface/core/resolve_face.py +195 -0
- dataface/core/schema/__init__.py +0 -0
- dataface/core/schema/guidance.py +151 -0
- dataface/core/scoped_paths.py +59 -0
- dataface/core/serve/__init__.py +14 -0
- dataface/core/serve/bootstrap.py +39 -0
- dataface/core/serve/embedded.py +57 -0
- dataface/core/serve/port.py +129 -0
- dataface/core/serve/server.py +938 -0
- dataface/core/serve/templates/__init__.py +0 -0
- dataface/core/serve/templates/directory.yml +6 -0
- dataface/core/serve/templates/error.html.j2 +217 -0
- dataface/core/utils.py +121 -0
- dataface/core/validate.py +64 -0
- dataface/integrations/__init__.py +0 -0
- dataface/integrations/highlighting.py +351 -0
- dataface/integrations/markdown.py +537 -0
- dataface/py.typed +0 -0
- dataface-0.1.2.dist-info/METADATA +375 -0
- dataface-0.1.2.dist-info/RECORD +455 -0
- dataface-0.1.2.dist-info/WHEEL +4 -0
- dataface-0.1.2.dist-info/entry_points.txt +2 -0
- dataface-0.1.2.dist-info/licenses/LICENSE +202 -0
- mdsvg/__init__.py +168 -0
- mdsvg/fonts.py +656 -0
- mdsvg/images.py +299 -0
- mdsvg/parser.py +629 -0
- mdsvg/playground.py +284 -0
- mdsvg/py.typed +2 -0
- mdsvg/renderer.py +1623 -0
- mdsvg/style.py +355 -0
- mdsvg/types.py +200 -0
- 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.
|