dataface 0.1.4.dev6__py3-none-any.whl → 0.1.5.dev88__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.
- dataface/DATAFACE_SYNTAX.md +17 -5
- dataface/agent_api/_init_templates/{index.md → README.md} +2 -2
- dataface/agent_api/_project_agents_md.py +1 -1
- dataface/agent_api/_session_store.py +3 -3
- dataface/agent_api/dashboards.py +2 -2
- dataface/agent_api/describe.py +3 -3
- dataface/agent_api/describe_query.py +1 -1
- dataface/agent_api/docs/yaml-reference.md +68 -29
- dataface/agent_api/init.py +24 -11
- dataface/agent_api/inspect.py +2 -2
- dataface/agent_api/mcp_install.py +4 -4
- dataface/agent_api/pack.py +4 -2
- dataface/agent_api/query.py +1 -1
- dataface/agent_api/schema.py +1 -1
- dataface/agent_api/search.py +1 -1
- dataface/agent_api/surface_aliases.yaml +1 -1
- dataface/ai/external_mcp.py +2 -2
- dataface/ai/memories.py +1 -1
- dataface/ai/prompts.py +3 -3
- dataface/ai/skills/dataface-troubleshooting/SKILL.md +4 -1
- dataface/cli/commands/chat.py +1 -1
- dataface/cli/commands/init.py +14 -4
- dataface/cli/commands/query.py +1 -1
- dataface/cli/main.py +10 -3
- dataface/core/compile/__init__.py +3 -3
- dataface/core/compile/chart_focus.py +5 -1
- dataface/core/compile/compiler.py +11 -12
- dataface/core/compile/config.py +8 -4
- dataface/core/compile/data_table_attachment.py +18 -18
- dataface/core/compile/introspection.py +1 -1
- dataface/core/compile/markdown.py +29 -35
- dataface/core/compile/models/chart/authored.py +2 -2
- dataface/core/compile/models/chart/{compiled.py → normalized.py} +1 -1
- dataface/core/compile/{chart_resolved.py → models/chart/resolved.py} +7 -5
- dataface/core/compile/models/config.py +1 -1
- dataface/core/compile/models/face/authored.py +6 -2
- dataface/core/compile/models/face/{compiled.py → normalized.py} +25 -111
- dataface/core/compile/models/face/resolved.py +111 -0
- dataface/core/compile/models/primitives.py +8 -8
- dataface/core/compile/models/source.py +10 -2
- dataface/core/compile/models/style/authored.py +223 -11
- dataface/core/compile/models/style/{merged.py → resolved.py} +171 -100
- dataface/core/compile/models/style/{compiled.py → theme.py} +221 -308
- dataface/core/compile/normalize_charts.py +6 -4
- dataface/core/compile/normalize_layout.py +32 -9
- dataface/core/compile/normalize_queries.py +7 -6
- dataface/core/compile/normalize_variables.py +6 -3
- dataface/core/compile/normalizer.py +23 -19
- dataface/core/compile/sizing.py +29 -27
- dataface/core/compile/sources.py +35 -26
- dataface/core/compile/style_cascade.py +21 -21
- dataface/core/compile/typography.py +10 -6
- dataface/core/compile/variables.py +1 -1
- dataface/core/compile/vega_config.py +2 -2
- dataface/core/dashboard.py +3 -0
- dataface/core/defaults/themes/_base.yaml +26 -1
- dataface/core/defaults/themes/cream.yaml +11 -0
- dataface/core/defaults/themes/editorial.yaml +11 -0
- dataface/core/defaults/themes/stark.yaml +12 -0
- dataface/core/errors/codes_compile.py +16 -0
- dataface/core/execute/adapters/adapter_registry.py +3 -3
- dataface/core/execute/adapters/base.py +2 -2
- dataface/core/execute/adapters/csv_adapter.py +2 -2
- dataface/core/execute/adapters/dbt_adapter.py +45 -25
- dataface/core/execute/adapters/dbt_adapter_factory.py +8 -0
- dataface/core/execute/adapters/http_adapter.py +2 -2
- dataface/core/execute/adapters/metricflow_adapter.py +2 -2
- dataface/core/execute/adapters/schema_resolver_adapter.py +2 -2
- dataface/core/execute/adapters/sql_adapter.py +64 -11
- dataface/core/execute/adapters/values_adapter.py +2 -2
- dataface/core/execute/batch.py +3 -3
- dataface/core/execute/duckdb_cache.py +32 -68
- dataface/core/execute/executor.py +6 -3
- dataface/core/execute/parallel.py +5 -2
- dataface/core/execute/setup_sql.py +1 -1
- dataface/core/inspect/dbt_schema.py +1 -1
- dataface/core/inspect/manifest_utils.py +4 -2
- dataface/core/pack/models.py +1 -1
- dataface/core/pack/proposal_store.py +6 -3
- dataface/core/project_roots.py +86 -12
- dataface/core/render/chart/callout.py +6 -6
- dataface/core/render/chart/decisions.py +1 -1
- dataface/core/render/chart/geo.py +11 -5
- dataface/core/render/chart/kpi.py +12 -9
- dataface/core/render/chart/pipeline.py +25 -16
- dataface/core/render/chart/profile.py +45 -19
- dataface/core/render/chart/render_single.py +6 -6
- dataface/core/render/chart/renderers.py +9 -9
- dataface/core/render/chart/rendering.py +19 -16
- dataface/core/render/chart/serialization.py +1 -1
- dataface/core/render/chart/spark.py +7 -7
- dataface/core/render/chart/spark_bar.py +6 -6
- dataface/core/render/chart/spec_builders.py +5 -3
- dataface/core/render/chart/standard_renderer.py +39 -39
- dataface/core/render/chart/table.py +22 -16
- dataface/core/render/chart/table_support.py +5 -3
- dataface/core/render/chart/validation.py +4 -1
- dataface/core/render/chart/vega_lite.py +9 -7
- dataface/core/render/chart/vega_lite_types.py +1 -1
- dataface/core/render/chart_interactivity.py +41 -3
- dataface/core/render/control_registry.py +6 -4
- dataface/core/render/converters/chart.py +3 -3
- dataface/core/render/converters/html.py +5 -2
- dataface/core/render/dir_context.py +267 -0
- dataface/core/render/face_api.py +8 -5
- dataface/core/render/faces.py +25 -25
- dataface/core/render/font_support.py +13 -44
- dataface/core/render/json_format.py +4 -1
- dataface/core/render/layout_sizing.py +9 -5
- dataface/core/render/layouts.py +11 -11
- dataface/core/render/placeholder.py +1 -1
- dataface/core/render/renderer.py +26 -5
- dataface/core/render/svg_utils.py +3 -3
- dataface/core/render/template_loader.py +1 -1
- dataface/core/render/templates/controls/_styles.css +4 -0
- dataface/core/render/templates/scripts/chart_interactivity.js +15 -16
- dataface/core/render/terminal.py +2 -2
- dataface/core/render/terminal_charts.py +1 -1
- dataface/core/render/terminal_layouts.py +4 -1
- dataface/core/render/text/case.py +3 -3
- dataface/core/render/text_format.py +4 -1
- dataface/core/render/utils.py +1 -1
- dataface/core/render/variable_controls.py +13 -10
- dataface/core/render/warnings/bar_color_1_to_1_with_x.py +3 -3
- dataface/core/render/warnings/base.py +1 -1
- dataface/core/render/warnings/redundant_encoding.py +69 -0
- dataface/core/render/warnings/registry.py +2 -0
- dataface/core/render/yaml_format.py +4 -1
- dataface/core/resolve_face.py +22 -22
- dataface/core/serve/port.py +1 -1
- dataface/core/serve/server.py +26 -16
- {dataface-0.1.4.dev6.dist-info → dataface-0.1.5.dev88.dist-info}/METADATA +50 -18
- {dataface-0.1.4.dev6.dist-info → dataface-0.1.5.dev88.dist-info}/RECORD +138 -135
- {dataface-0.1.4.dev6.dist-info → dataface-0.1.5.dev88.dist-info}/WHEEL +1 -1
- /dataface/agent_api/_init_templates/{faces-dataface.yml → guide.yml} +0 -0
- /dataface/core/compile/models/query/{compiled.py → normalized.py} +0 -0
- {dataface-0.1.4.dev6.dist-info → dataface-0.1.5.dev88.dist-info}/entry_points.txt +0 -0
- {dataface-0.1.4.dev6.dist-info → dataface-0.1.5.dev88.dist-info}/licenses/LICENSE +0 -0
dataface/DATAFACE_SYNTAX.md
CHANGED
|
@@ -461,7 +461,6 @@ charts:
|
|
|
461
461
|
|
|
462
462
|
# Style + behavior
|
|
463
463
|
sort: { by: total, order: desc }
|
|
464
|
-
stack: zero # false | zero | normalize | center
|
|
465
464
|
format: integer # named alias or raw D3 spec (e.g. ",.0f")
|
|
466
465
|
x_label: "Month"
|
|
467
466
|
y_label: "Revenue (USD)"
|
|
@@ -470,7 +469,7 @@ charts:
|
|
|
470
469
|
|
|
471
470
|
style: # Chart-local style patch (typed; not raw CSS) — paint only
|
|
472
471
|
orientation: vertical # style: does NOT accept height or aspect_ratio
|
|
473
|
-
stack: true
|
|
472
|
+
stack: zero # false | true | zero | normalize | center
|
|
474
473
|
```
|
|
475
474
|
|
|
476
475
|
### Chart types (29 total)
|
|
@@ -523,7 +522,6 @@ All chart types accept the channels and style fields below — but each type rej
|
|
|
523
522
|
| `longitude` | string | Longitude field (point/bubble map) |
|
|
524
523
|
| `background` | string \| object | Background channel — color, `{value}`, `{field, scale/when}`, or map layer |
|
|
525
524
|
| `sort` | object | `{by, order}` — categorical sort |
|
|
526
|
-
| `stack` | bool \| enum | `false`, `zero`, `normalize`, or `center` |
|
|
527
525
|
| `link` | string | Click-through URL template for drill-down links |
|
|
528
526
|
| `filters` | object | Post-execution row filters: `{col: var_name}` (implicit `eq`) or `{col: {op: var}}` where op is one of `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `like`, `ilike`, `in`, `not_in`, `between`. Implicit-eq values may also be Jinja templates (e.g. `"{{ region }}"`) resolved at execute time. A filter is skipped when the variable is `None`, `""`, or renders to `"none"`. |
|
|
529
527
|
| `layers` | list | Layer definitions for `type: layered` (see [Composition](#composition)) |
|
|
@@ -561,7 +559,8 @@ color: segment # Optional: one line per segment
|
|
|
561
559
|
type: area
|
|
562
560
|
x: date
|
|
563
561
|
y: value
|
|
564
|
-
|
|
562
|
+
style:
|
|
563
|
+
stack: normalize # 100% stacked
|
|
565
564
|
|
|
566
565
|
# scatter — x and y numeric
|
|
567
566
|
type: scatter
|
|
@@ -1113,17 +1112,30 @@ Active code categories (see `dataface/core/errors/codes_*.py` for the authoritat
|
|
|
1113
1112
|
|
|
1114
1113
|
| Prefix | Meaning |
|
|
1115
1114
|
|--------|---------|
|
|
1115
|
+
| `DF-COMPILE-*` | Compile-time errors (missing fields, unknown references, malformed YAML) |
|
|
1116
1116
|
| `DF-RENDER-*` | Chart rendering errors (wrong row counts, unknown chart types, format issues) |
|
|
1117
1117
|
| `DF-EXECUTE-*` | Query execution errors (missing sources, inline-source policy, source typing) |
|
|
1118
1118
|
| `DF-UNKNOWN-*` | Fallback codes for legacy string-message errors not yet migrated |
|
|
1119
1119
|
|
|
1120
|
-
The registry is being filled out incrementally —
|
|
1120
|
+
The registry is being filled out incrementally — some compile-time and variable-resolution errors still raise as plain `DatafaceError` without a structured code. Today's typed codes:
|
|
1121
|
+
|
|
1122
|
+
### Compile errors
|
|
1123
|
+
|
|
1124
|
+
- **`DF-COMPILE-SOURCE-REQUIRED`** — a SQL query has no `source:` and no default is configured. Set the source on the query (`source: my_db`), at the face level (`source:` or `sources.default`), or project-wide via `sources.default` in `dataface.yml`.
|
|
1125
|
+
- **`DF-COMPILE-UNKNOWN-QUERY`** — a chart's `query:` references a name that does not appear under `queries:`. Check for a typo or add the missing query.
|
|
1126
|
+
- **`DF-COMPILE-EXTRA-FIELD`** — the face YAML contains a field not recognised by the schema. Remove it or check the schema for supported keys.
|
|
1127
|
+
- **`DF-COMPILE-SQL-LITERAL-NEWLINES`** — a SQL field contains a literal `\n` (backslash + n) from single-quoted YAML. Use a YAML block scalar (`sql: |`) to write multiline SQL.
|
|
1128
|
+
|
|
1129
|
+
### Render errors
|
|
1121
1130
|
|
|
1122
1131
|
- **`DF-RENDER-KPI-MULTIROW`** — a KPI chart's query returned more than one row but `value` is a column reference. Add `LIMIT 1` or aggregate down to one row.
|
|
1123
1132
|
- **`DF-RENDER-UNKNOWN-CHART-TYPE`** — `type:` is not a recognized chart type. See the [Charts](#charts) section for the list.
|
|
1124
1133
|
- **`DF-RENDER-FORMAT-UNSUPPORTED`** — the render `format` argument is not one of `svg`/`html`/`png`.
|
|
1125
1134
|
- **`DF-RENDER-NO-LAYOUT`** — the face has no `rows`/`cols`/`grid`/`tabs` and nothing to render.
|
|
1126
1135
|
- **`DF-RENDER-INPUT-INVALID`** — the render call received structurally invalid input (e.g. both `path` and `yaml_content`).
|
|
1136
|
+
|
|
1137
|
+
### Execute errors
|
|
1138
|
+
|
|
1127
1139
|
- **`DF-EXECUTE-SOURCE-NOT-FOUND`** / **`-NOT-FOUND-EMPTY`** — the query's `source:` (or default source) is not configured in `dataface.yml`.
|
|
1128
1140
|
- **`DF-EXECUTE-NO-DEFAULT-SOURCE`** — multiple sources are defined and no `default_source` was set.
|
|
1129
1141
|
- **`DF-EXECUTE-SOURCE-INLINE-FORBIDDEN`** / **`-CROSS-FILE-FORBIDDEN`** — inline source definitions are restricted by project policy.
|
|
@@ -11,14 +11,14 @@ for your data project.
|
|
|
11
11
|
## Authoring modes
|
|
12
12
|
|
|
13
13
|
**YAML (`.yml`)** — structured dashboards with queries, charts, and layout.
|
|
14
|
-
See the [dataface guide](
|
|
14
|
+
See the [dataface guide](guide) for a working example covering queries, charts, and variables.
|
|
15
15
|
|
|
16
16
|
**Markdown (`.md`)** — prose pages like this one. Add YAML frontmatter for
|
|
17
17
|
queries and charts, then embed them inline with `{% raw %}{{ chart my_chart }}{% endraw %}`.
|
|
18
18
|
|
|
19
19
|
## Next steps
|
|
20
20
|
|
|
21
|
-
1. Open `faces/
|
|
21
|
+
1. Open `faces/guide.yml` and tweak the content.
|
|
22
22
|
2. Run `dft serve` and open the URL it prints.
|
|
23
23
|
3. Add new `.yml` or `.md` files under `faces/` — they appear automatically.
|
|
24
24
|
4. Run `dft validate` to validate your face YAML for errors.
|
|
@@ -15,7 +15,7 @@ _TEMPLATES = importlib.resources.files("dataface.agent_api._init_templates")
|
|
|
15
15
|
|
|
16
16
|
def load_agents_snippet() -> str:
|
|
17
17
|
"""Return the packaged markdown blurb (includes marker comments)."""
|
|
18
|
-
return _TEMPLATES.joinpath("agents_dft_snippet.md").read_text()
|
|
18
|
+
return _TEMPLATES.joinpath("agents_dft_snippet.md").read_text(encoding="utf-8")
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
def has_dataface_markers(text: str) -> bool:
|
|
@@ -198,7 +198,7 @@ class SessionIndex:
|
|
|
198
198
|
def _load(self) -> dict[str, list[SessionMeta]]:
|
|
199
199
|
if self._path.exists():
|
|
200
200
|
try:
|
|
201
|
-
raw = json.loads(self._path.read_text())
|
|
201
|
+
raw = json.loads(self._path.read_text(encoding="utf-8"))
|
|
202
202
|
if isinstance(raw, dict):
|
|
203
203
|
return raw
|
|
204
204
|
logger.warning("sessions/index.json has unexpected shape; rebuilding")
|
|
@@ -208,7 +208,7 @@ class SessionIndex:
|
|
|
208
208
|
|
|
209
209
|
def _save(self) -> None:
|
|
210
210
|
self._path.parent.mkdir(parents=True, exist_ok=True)
|
|
211
|
-
self._path.write_text(json.dumps(self._data, indent=2))
|
|
211
|
+
self._path.write_text(json.dumps(self._data, indent=2), encoding="utf-8")
|
|
212
212
|
|
|
213
213
|
def _rebuild(self) -> dict[str, list[SessionMeta]]:
|
|
214
214
|
"""Scan all JSONL files under ~/.dft/sessions/ and reconstruct the index."""
|
|
@@ -234,7 +234,7 @@ class SessionIndex:
|
|
|
234
234
|
data.setdefault(cwd, []).append(entry)
|
|
235
235
|
# Persist the rebuilt index
|
|
236
236
|
self._path.parent.mkdir(parents=True, exist_ok=True)
|
|
237
|
-
self._path.write_text(json.dumps(data, indent=2))
|
|
237
|
+
self._path.write_text(json.dumps(data, indent=2), encoding="utf-8")
|
|
238
238
|
return data
|
|
239
239
|
|
|
240
240
|
|
dataface/agent_api/dashboards.py
CHANGED
|
@@ -148,7 +148,7 @@ def list_dashboards(
|
|
|
148
148
|
if yaml_file.name.startswith("_"):
|
|
149
149
|
continue
|
|
150
150
|
try:
|
|
151
|
-
content = yaml.safe_load(yaml_file.read_text())
|
|
151
|
+
content = yaml.safe_load(yaml_file.read_text(encoding="utf-8"))
|
|
152
152
|
if not isinstance(content, dict):
|
|
153
153
|
skipped.append(
|
|
154
154
|
SkippedFile(
|
|
@@ -235,7 +235,7 @@ def get_dashboard(
|
|
|
235
235
|
)
|
|
236
236
|
|
|
237
237
|
try:
|
|
238
|
-
raw_yaml = file_path.read_text()
|
|
238
|
+
raw_yaml = file_path.read_text(encoding="utf-8")
|
|
239
239
|
except OSError as e:
|
|
240
240
|
return CompiledDashboard(
|
|
241
241
|
success=False,
|
dataface/agent_api/describe.py
CHANGED
|
@@ -7,11 +7,11 @@ from typing import Any
|
|
|
7
7
|
|
|
8
8
|
from pydantic import BaseModel, Field
|
|
9
9
|
|
|
10
|
-
from dataface.core.compile.models.chart.
|
|
10
|
+
from dataface.core.compile.models.chart.normalized import (
|
|
11
11
|
Chart,
|
|
12
12
|
)
|
|
13
|
-
from dataface.core.compile.models.face.
|
|
14
|
-
from dataface.core.compile.models.query.
|
|
13
|
+
from dataface.core.compile.models.face.normalized import Layout
|
|
14
|
+
from dataface.core.compile.models.query.normalized import (
|
|
15
15
|
CsvQuery,
|
|
16
16
|
DbtModelQuery,
|
|
17
17
|
HttpQuery,
|
|
@@ -109,7 +109,7 @@ def _duckdb_describe(
|
|
|
109
109
|
sql: str, source: str | None, adapter_registry: AdapterRegistry
|
|
110
110
|
) -> list[DescribeQueryColumn]:
|
|
111
111
|
"""Run DESCRIBE ({sql}) via the registry's read-only SqlAdapter."""
|
|
112
|
-
from dataface.core.compile.models.query.
|
|
112
|
+
from dataface.core.compile.models.query.normalized import SqlQuery
|
|
113
113
|
|
|
114
114
|
result = adapter_registry.execute(SqlQuery(sql=f"DESCRIBE ({sql})", source=source))
|
|
115
115
|
if result.error:
|
|
@@ -15,7 +15,7 @@ AuthoredFace (dataface) definition from YAML.
|
|
|
15
15
|
| `source` | str | ✓ | Default source name shorthand (equivalent to sources.default). Sets the connection for all queries. |
|
|
16
16
|
| `variables` | dict[str, [Variable](#variable) \| VariableRef] | ✓ | Variable definitions for dynamic filtering and UI controls. |
|
|
17
17
|
| `queries` | dict[str, [Query](#query) \| QueryRef] | ✓ | Named query definitions (SQL, CSV, MetricFlow, HTTP, etc.). |
|
|
18
|
-
| `charts` | dict[str, [BarChart](#barchart) \| [LineChart](#linechart) \| [AreaChart](#areachart) \| [ScatterChart](#scatterchart) \| [HeatmapChart](#heatmapchart) \| [PieChart](#piechart) \| [KpiChart](#kpichart) \| [TableChart](#tablechart) \| [PointMapChart](#pointmapchart) \| [GeoshapeChart](#geoshapechart) \| [LayeredChart](#layeredchart) \| [CalloutChart](#calloutchart) \| [SparkBarChart](#sparkbarchart) \| ChartRef] | ✓ | Named chart definitions
|
|
18
|
+
| `charts` | dict[str, [BarChart](#barchart) \| [LineChart](#linechart) \| [AreaChart](#areachart) \| [ScatterChart](#scatterchart) \| [HeatmapChart](#heatmapchart) \| [PieChart](#piechart) \| [KpiChart](#kpichart) \| [TableChart](#tablechart) \| [PointMapChart](#pointmapchart) \| [GeoshapeChart](#geoshapechart) \| [LayeredChart](#layeredchart) \| [CalloutChart](#calloutchart) \| [SparkBarChart](#sparkbarchart) \| ChartRef] | ✓ | Named chart definitions. When no explicit layout is present, charts render as an implicit row layout in authored order. |
|
|
19
19
|
| `rows` | list[str \| [Face](#face) \| [BarChart](#barchart) \| [LineChart](#linechart) \| [AreaChart](#areachart) \| [ScatterChart](#scatterchart) \| [HeatmapChart](#heatmapchart) \| [PieChart](#piechart) \| [KpiChart](#kpichart) \| [TableChart](#tablechart) \| [PointMapChart](#pointmapchart) \| [GeoshapeChart](#geoshapechart) \| [LayeredChart](#layeredchart) \| [CalloutChart](#calloutchart) \| [SparkBarChart](#sparkbarchart) \| [ForeachItem](#foreachitem) \| dict[str, [BarChart](#barchart) \| [LineChart](#linechart) \| [AreaChart](#areachart) \| [ScatterChart](#scatterchart) \| [HeatmapChart](#heatmapchart) \| [PieChart](#piechart) \| [KpiChart](#kpichart) \| [TableChart](#tablechart) \| [PointMapChart](#pointmapchart) \| [GeoshapeChart](#geoshapechart) \| [LayeredChart](#layeredchart) \| [CalloutChart](#calloutchart) \| [SparkBarChart](#sparkbarchart)]] | ✓ | Vertical stack layout: list of chart names or inline chart/face definitions. |
|
|
20
20
|
| `cols` | list[str \| [Face](#face) \| [BarChart](#barchart) \| [LineChart](#linechart) \| [AreaChart](#areachart) \| [ScatterChart](#scatterchart) \| [HeatmapChart](#heatmapchart) \| [PieChart](#piechart) \| [KpiChart](#kpichart) \| [TableChart](#tablechart) \| [PointMapChart](#pointmapchart) \| [GeoshapeChart](#geoshapechart) \| [LayeredChart](#layeredchart) \| [CalloutChart](#calloutchart) \| [SparkBarChart](#sparkbarchart) \| [ForeachItem](#foreachitem) \| dict[str, [BarChart](#barchart) \| [LineChart](#linechart) \| [AreaChart](#areachart) \| [ScatterChart](#scatterchart) \| [HeatmapChart](#heatmapchart) \| [PieChart](#piechart) \| [KpiChart](#kpichart) \| [TableChart](#tablechart) \| [PointMapChart](#pointmapchart) \| [GeoshapeChart](#geoshapechart) \| [LayeredChart](#layeredchart) \| [CalloutChart](#calloutchart) \| [SparkBarChart](#sparkbarchart)]] | ✓ | Horizontal layout: list of chart names or inline chart/face definitions. |
|
|
21
21
|
| `grid` | [GridLayout](#gridlayout) | ✓ | CSS-grid style layout with explicit row/column placement. |
|
|
@@ -646,13 +646,14 @@ HTTP/REST API source configuration.
|
|
|
646
646
|
|
|
647
647
|
<a id="dbtprofilesourceconfig"></a>
|
|
648
648
|
## DbtProfileSourceConfig
|
|
649
|
-
Reference to a dbt profile
|
|
649
|
+
Reference to a dbt profile.
|
|
650
650
|
|
|
651
651
|
| Field | Type | Optional | Description |
|
|
652
652
|
|-------|------|:--------:|-------------|
|
|
653
653
|
| `type` | enum: "dbt_profile" | | Source type identifier. |
|
|
654
654
|
| `profile` | str | | dbt profile name from profiles.yml. |
|
|
655
655
|
| `target` | str | ✓ | dbt target to use; defaults to the profile's default target. |
|
|
656
|
+
| `profiles_dir` | str | ✓ | Directory containing profiles.yml, relative to the dataface project root. Use when profiles.yml is in a subdirectory (e.g. services/dbt). Resolution order: profiles_dir → $DBT_PROFILES_DIR → project root → ~/.dbt. |
|
|
656
657
|
|
|
657
658
|
<a id="variableoptions"></a>
|
|
658
659
|
## VariableOptions
|
|
@@ -758,7 +759,7 @@ Authored overlay for BarChartStyle. Bar chart style: chart-level fields + marks
|
|
|
758
759
|
| `number_format` | str | ✓ | Default number format for axes and tooltips (D3 format string); None inherits from theme. |
|
|
759
760
|
| `time_format` | str | ✓ | Default time format for temporal axes (D3 time format string); None inherits from theme. |
|
|
760
761
|
| `scale` | [ScaleStyle](#scalestyle) | ✓ | Chart-type encoding scale overrides applied to both x and y; None means no override. |
|
|
761
|
-
| `range` |
|
|
762
|
+
| `range` | [RangeStyle](#rangestyle) | ✓ | Color range/palette overrides for this chart type; None means no override. |
|
|
762
763
|
| `data_table` | [DataTableStyle](#datatablestyle) | ✓ | Per-chart-type data_table style override; None uses the universal style.charts.data_table. |
|
|
763
764
|
| `orientation` | enum: "horizontal", "vertical", "auto" | ✓ | Preferred bar orientation; None uses the renderer default (vertical). |
|
|
764
765
|
| `stack` | enum: "zero", "normalize", "center" | ✓ | Default stack mode for bar charts; None uses the renderer default (VL stacks by default). |
|
|
@@ -795,7 +796,7 @@ Authored overlay for LineChartStyle. Line chart style: chart-level fields + mark
|
|
|
795
796
|
| `number_format` | str | ✓ | Default number format for axes and tooltips (D3 format string); None inherits from theme. |
|
|
796
797
|
| `time_format` | str | ✓ | Default time format for temporal axes (D3 time format string); None inherits from theme. |
|
|
797
798
|
| `scale` | [ScaleStyle](#scalestyle) | ✓ | Chart-type encoding scale overrides applied to both x and y; None means no override. |
|
|
798
|
-
| `range` |
|
|
799
|
+
| `range` | [RangeStyle](#rangestyle) | ✓ | Color range/palette overrides for this chart type; None means no override. |
|
|
799
800
|
| `data_table` | [DataTableStyle](#datatablestyle) | ✓ | Per-chart-type data_table style override; None uses the universal style.charts.data_table. |
|
|
800
801
|
| `endpoint_labels` | [EndpointLabelsConfig](#endpointlabelsconfig) | ✓ | Endpoint label pane configuration for line charts. |
|
|
801
802
|
| `marks` | [LineChartMarksStyle](#linechartmarksstyle) | ✓ | Line-family mark overrides. |
|
|
@@ -829,7 +830,7 @@ Authored overlay for AreaChartStyle. Area chart style: chart-level fields + mark
|
|
|
829
830
|
| `number_format` | str | ✓ | Default number format for axes and tooltips (D3 format string); None inherits from theme. |
|
|
830
831
|
| `time_format` | str | ✓ | Default time format for temporal axes (D3 time format string); None inherits from theme. |
|
|
831
832
|
| `scale` | [ScaleStyle](#scalestyle) | ✓ | Chart-type encoding scale overrides applied to both x and y; None means no override. |
|
|
832
|
-
| `range` |
|
|
833
|
+
| `range` | [RangeStyle](#rangestyle) | ✓ | Color range/palette overrides for this chart type; None means no override. |
|
|
833
834
|
| `data_table` | [DataTableStyle](#datatablestyle) | ✓ | Per-chart-type data_table style override; None uses the universal style.charts.data_table. |
|
|
834
835
|
| `stack` | enum: "zero", "normalize", "center" | ✓ | Default stack mode for area charts; False overlaps silhouettes. |
|
|
835
836
|
| `endpoint_labels` | [EndpointLabelsConfig](#endpointlabelsconfig) | ✓ | Endpoint label pane configuration for area charts. |
|
|
@@ -864,7 +865,7 @@ Authored overlay for ScatterChartStyle. Scatter chart style: chart-level fields
|
|
|
864
865
|
| `number_format` | str | ✓ | Default number format for axes and tooltips (D3 format string); None inherits from theme. |
|
|
865
866
|
| `time_format` | str | ✓ | Default time format for temporal axes (D3 time format string); None inherits from theme. |
|
|
866
867
|
| `scale` | [ScaleStyle](#scalestyle) | ✓ | Chart-type encoding scale overrides applied to both x and y; None means no override. |
|
|
867
|
-
| `range` |
|
|
868
|
+
| `range` | [RangeStyle](#rangestyle) | ✓ | Color range/palette overrides for this chart type; None means no override. |
|
|
868
869
|
| `data_table` | [DataTableStyle](#datatablestyle) | ✓ | Per-chart-type data_table style override; None uses the universal style.charts.data_table. |
|
|
869
870
|
| `marks` | [ScatterChartMarksStyle](#scatterchartmarksstyle) | ✓ | Scatter-family mark overrides. |
|
|
870
871
|
|
|
@@ -897,7 +898,7 @@ Authored overlay for HeatmapChartStyle. Heatmap chart style.
|
|
|
897
898
|
| `number_format` | str | ✓ | Default number format for axes and tooltips (D3 format string); None inherits from theme. |
|
|
898
899
|
| `time_format` | str | ✓ | Default time format for temporal axes (D3 time format string); None inherits from theme. |
|
|
899
900
|
| `scale` | [ScaleStyle](#scalestyle) | ✓ | Chart-type encoding scale overrides applied to both x and y; None means no override. |
|
|
900
|
-
| `range` |
|
|
901
|
+
| `range` | [RangeStyle](#rangestyle) | ✓ | Color range/palette overrides for this chart type; None means no override. |
|
|
901
902
|
| `data_table` | [DataTableStyle](#datatablestyle) | ✓ | Per-chart-type data_table style override; None uses the universal style.charts.data_table. |
|
|
902
903
|
| `cell_padding` | float | ✓ | Padding between heatmap cells in pixels. |
|
|
903
904
|
| `color_scheme` | str | ✓ | Color scheme name for heatmap gradient (e.g. 'blues', 'viridis'). |
|
|
@@ -1129,7 +1130,7 @@ Flat style patch for layered multi-mark charts.
|
|
|
1129
1130
|
| `number_format` | str | ✓ | Default number format for axes and tooltips (D3 format string); None inherits from theme. |
|
|
1130
1131
|
| `time_format` | str | ✓ | Default time format for temporal axes (D3 time format string); None inherits from theme. |
|
|
1131
1132
|
| `scale` | ScaleStyle | ✓ | Chart-type encoding scale overrides applied to both x and y; None means no override. |
|
|
1132
|
-
| `range` |
|
|
1133
|
+
| `range` | [RangeStyle](#rangestyle) | ✓ | Color range/palette overrides for this chart type; None means no override. |
|
|
1133
1134
|
| `data_table` | [DataTableStyle](#datatablestyle) | ✓ | Per-chart-type data_table style override; None uses the universal style.charts.data_table. |
|
|
1134
1135
|
| `orientation` | enum: "horizontal", "vertical", "auto" | ✓ | Preferred bar orientation; None uses the renderer default (vertical). |
|
|
1135
1136
|
| `stack` | enum: "zero", "normalize", "center" | ✓ | Default stack mode for bar/area charts. |
|
|
@@ -1485,11 +1486,21 @@ Authored overlay for LegendStyle.
|
|
|
1485
1486
|
|
|
1486
1487
|
<a id="tooltipstyle"></a>
|
|
1487
1488
|
## TooltipStyle
|
|
1488
|
-
Authored overlay for TooltipStyle. Tooltip
|
|
1489
|
+
Authored overlay for TooltipStyle. Tooltip box style — all cascade keys for the hover bubble.
|
|
1489
1490
|
|
|
1490
1491
|
| Field | Type | Optional | Description |
|
|
1491
1492
|
|-------|------|:--------:|-------------|
|
|
1492
1493
|
| `format` | str | ✓ | Default tooltip value format string; theme always provides this. |
|
|
1494
|
+
| `background` | str | ✓ | Tooltip background color (CSS color string); theme always provides this. |
|
|
1495
|
+
| `line_height` | float | ✓ | Tooltip line-height multiplier; theme always provides this. |
|
|
1496
|
+
| `max_width` | float | ✓ | Maximum tooltip width in pixels; theme always provides this. |
|
|
1497
|
+
| `gap` | float | ✓ | Gap in pixels between label and value columns; theme always provides this. |
|
|
1498
|
+
| `font` | [FontStyle](#fontstyle) | ✓ | Tooltip font overrides (size etc.); cascade fills missing fields. |
|
|
1499
|
+
| `padding` | [PaddingStyle](#paddingstyle) | ✓ | Tooltip inner padding (4 sides in pixels); theme always provides this. |
|
|
1500
|
+
| `label` | [TooltipSlotStyle](#tooltipslotstyle) | ✓ | Label-column font overrides (color, weight). |
|
|
1501
|
+
| `value` | [TooltipSlotStyle](#tooltipslotstyle) | ✓ | Value-column font overrides (color, weight). |
|
|
1502
|
+
| `border` | [TooltipBorderStyle](#tooltipborderstyle) | ✓ | Tooltip border style; theme always provides this. |
|
|
1503
|
+
| `shadow` | [TooltipShadowStyle](#tooltipshadowstyle) | ✓ | Tooltip drop-shadow config; theme always provides this. |
|
|
1493
1504
|
|
|
1494
1505
|
<a id="stylecolorconfig"></a>
|
|
1495
1506
|
## StyleColorConfig
|
|
@@ -1545,6 +1556,17 @@ Authored overlay for ScaleStyle. Scale configuration primitive.
|
|
|
1545
1556
|
| `nice` | bool | ✓ | Round scale domain to nice values; None uses Vega-Lite's default. |
|
|
1546
1557
|
| `padding` | float | ✓ | Unified scale padding shortcut; dispatches to band, point, or continuous padding per scale type. |
|
|
1547
1558
|
|
|
1559
|
+
<a id="rangestyle"></a>
|
|
1560
|
+
## RangeStyle
|
|
1561
|
+
Chart-local palette/range overlay — no theme cascade.
|
|
1562
|
+
|
|
1563
|
+
| Field | Type | Optional | Description |
|
|
1564
|
+
|-------|------|:--------:|-------------|
|
|
1565
|
+
| `category` | list[str] | ✓ | Per-chart categorical color palette (list of CSS color strings). |
|
|
1566
|
+
| `diverging` | list[str] | ✓ | Per-chart diverging color scale colors. |
|
|
1567
|
+
| `heatmap` | list[str] | ✓ | Per-chart heatmap color scale colors. |
|
|
1568
|
+
| `ramp` | list[str] | ✓ | Per-chart sequential color ramp colors. |
|
|
1569
|
+
|
|
1548
1570
|
<a id="datatablestyle"></a>
|
|
1549
1571
|
## DataTableStyle
|
|
1550
1572
|
Authored overlay for DataTableStyle. Attached data_table style. Lives at style.charts.data_table.*.
|
|
@@ -1729,7 +1751,7 @@ Authored overlay for TableTitleStyle.
|
|
|
1729
1751
|
|
|
1730
1752
|
<a id="paginationconfig"></a>
|
|
1731
1753
|
## PaginationConfig
|
|
1732
|
-
|
|
1754
|
+
Table pagination configuration.
|
|
1733
1755
|
|
|
1734
1756
|
| Field | Type | Optional | Description |
|
|
1735
1757
|
|-------|------|:--------:|-------------|
|
|
@@ -1738,7 +1760,7 @@ Authored overlay for PaginationConfig. Table pagination configuration.
|
|
|
1738
1760
|
|
|
1739
1761
|
<a id="tablecolumndefaultsconfig"></a>
|
|
1740
1762
|
## TableColumnDefaultsConfig
|
|
1741
|
-
|
|
1763
|
+
Table-level defaults applied to every column unless overridden per-column.
|
|
1742
1764
|
|
|
1743
1765
|
| Field | Type | Optional | Description |
|
|
1744
1766
|
|-------|------|:--------:|-------------|
|
|
@@ -2019,8 +2041,8 @@ Scatter chart style: chart-level fields + marks sub-block.
|
|
|
2019
2041
|
| `number_format` | str | ✓ | Default number format for axes and tooltips (D3 format string); None inherits from theme. |
|
|
2020
2042
|
| `time_format` | str | ✓ | Default time format for temporal axes (D3 time format string); None inherits from theme. |
|
|
2021
2043
|
| `scale` | ScaleStyle | ✓ | Chart-type encoding scale overrides applied to both x and y; None means no override. |
|
|
2022
|
-
| `range` |
|
|
2023
|
-
| `data_table` |
|
|
2044
|
+
| `range` | [RangeStyle](#rangestyle) | ✓ | Color range/palette overrides for this chart type; None means no override. |
|
|
2045
|
+
| `data_table` | [DataTableStyle](#datatablestyle) | ✓ | Per-chart-type data_table style override; None uses the universal style.charts.data_table. |
|
|
2024
2046
|
| `marks` | ScatterChartMarksStyle | ✓ | Scatter-family mark overrides. |
|
|
2025
2047
|
|
|
2026
2048
|
<a id="histogramchartstyle"></a>
|
|
@@ -2052,7 +2074,7 @@ Authored overlay for HistogramChartStyle. Histogram chart style.
|
|
|
2052
2074
|
| `number_format` | str | ✓ | Default number format for axes and tooltips (D3 format string); None inherits from theme. |
|
|
2053
2075
|
| `time_format` | str | ✓ | Default time format for temporal axes (D3 time format string); None inherits from theme. |
|
|
2054
2076
|
| `scale` | [ScaleStyle](#scalestyle) | ✓ | Chart-type encoding scale overrides applied to both x and y; None means no override. |
|
|
2055
|
-
| `range` |
|
|
2077
|
+
| `range` | [RangeStyle](#rangestyle) | ✓ | Color range/palette overrides for this chart type; None means no override. |
|
|
2056
2078
|
| `data_table` | [DataTableStyle](#datatablestyle) | ✓ | Per-chart-type data_table style override; None uses the universal style.charts.data_table. |
|
|
2057
2079
|
| `bin_maxbins` | int | ✓ | Maximum number of bins for auto-binning. |
|
|
2058
2080
|
| `marks` | [HistogramChartMarksStyle](#histogramchartmarksstyle) | ✓ | Histogram-family mark overrides. |
|
|
@@ -2086,8 +2108,8 @@ Boxplot chart style.
|
|
|
2086
2108
|
| `number_format` | str | ✓ | Default number format for axes and tooltips (D3 format string); None inherits from theme. |
|
|
2087
2109
|
| `time_format` | str | ✓ | Default time format for temporal axes (D3 time format string); None inherits from theme. |
|
|
2088
2110
|
| `scale` | ScaleStyle | ✓ | Chart-type encoding scale overrides applied to both x and y; None means no override. |
|
|
2089
|
-
| `range` |
|
|
2090
|
-
| `data_table` |
|
|
2111
|
+
| `range` | [RangeStyle](#rangestyle) | ✓ | Color range/palette overrides for this chart type; None means no override. |
|
|
2112
|
+
| `data_table` | [DataTableStyle](#datatablestyle) | ✓ | Per-chart-type data_table style override; None uses the universal style.charts.data_table. |
|
|
2091
2113
|
| `marks` | BoxplotChartMarksStyle | ✓ | Boxplot-family mark overrides. |
|
|
2092
2114
|
|
|
2093
2115
|
<a id="errorbarchartstyle"></a>
|
|
@@ -2119,8 +2141,8 @@ Error bar chart style.
|
|
|
2119
2141
|
| `number_format` | str | ✓ | Default number format for axes and tooltips (D3 format string); None inherits from theme. |
|
|
2120
2142
|
| `time_format` | str | ✓ | Default time format for temporal axes (D3 time format string); None inherits from theme. |
|
|
2121
2143
|
| `scale` | ScaleStyle | ✓ | Chart-type encoding scale overrides applied to both x and y; None means no override. |
|
|
2122
|
-
| `range` |
|
|
2123
|
-
| `data_table` |
|
|
2144
|
+
| `range` | [RangeStyle](#rangestyle) | ✓ | Color range/palette overrides for this chart type; None means no override. |
|
|
2145
|
+
| `data_table` | [DataTableStyle](#datatablestyle) | ✓ | Per-chart-type data_table style override; None uses the universal style.charts.data_table. |
|
|
2124
2146
|
| `marks` | ErrorbarChartMarksStyle | ✓ | Errorbar-family mark overrides. |
|
|
2125
2147
|
|
|
2126
2148
|
<a id="errorbandchartstyle"></a>
|
|
@@ -2152,8 +2174,8 @@ Error band chart style.
|
|
|
2152
2174
|
| `number_format` | str | ✓ | Default number format for axes and tooltips (D3 format string); None inherits from theme. |
|
|
2153
2175
|
| `time_format` | str | ✓ | Default time format for temporal axes (D3 time format string); None inherits from theme. |
|
|
2154
2176
|
| `scale` | ScaleStyle | ✓ | Chart-type encoding scale overrides applied to both x and y; None means no override. |
|
|
2155
|
-
| `range` |
|
|
2156
|
-
| `data_table` |
|
|
2177
|
+
| `range` | [RangeStyle](#rangestyle) | ✓ | Color range/palette overrides for this chart type; None means no override. |
|
|
2178
|
+
| `data_table` | [DataTableStyle](#datatablestyle) | ✓ | Per-chart-type data_table style override; None uses the universal style.charts.data_table. |
|
|
2157
2179
|
| `marks` | ErrorbandChartMarksStyle | ✓ | Errorband-family mark overrides. |
|
|
2158
2180
|
|
|
2159
2181
|
<a id="serieslabelstyle"></a>
|
|
@@ -2266,6 +2288,32 @@ Authored overlay for LegendElementStyle.
|
|
|
2266
2288
|
| `font` | [FontStyle](#fontstyle) | ✓ | Legend element font style overrides. |
|
|
2267
2289
|
| `padding` | float | ✓ | Padding between legend symbol and element text in pixels. |
|
|
2268
2290
|
|
|
2291
|
+
<a id="tooltipslotstyle"></a>
|
|
2292
|
+
## TooltipSlotStyle
|
|
2293
|
+
Authored overlay for TooltipSlotStyle. Typography for a single tooltip slot (label or value).
|
|
2294
|
+
|
|
2295
|
+
| Field | Type | Optional | Description |
|
|
2296
|
+
|-------|------|:--------:|-------------|
|
|
2297
|
+
| `font` | [FontStyle](#fontstyle) | ✓ | Font overrides for this tooltip slot (color, weight). |
|
|
2298
|
+
|
|
2299
|
+
<a id="tooltipborderstyle"></a>
|
|
2300
|
+
## TooltipBorderStyle
|
|
2301
|
+
Authored overlay for TooltipBorderStyle. Tooltip box border — all fields required; theme YAML supplies defaults.
|
|
2302
|
+
|
|
2303
|
+
| Field | Type | Optional | Description |
|
|
2304
|
+
|-------|------|:--------:|-------------|
|
|
2305
|
+
| `color` | str | ✓ | Border color as a CSS color string. |
|
|
2306
|
+
| `width` | float | ✓ | Border width in pixels. |
|
|
2307
|
+
| `radius` | float | ✓ | Border corner radius in pixels. |
|
|
2308
|
+
|
|
2309
|
+
<a id="tooltipshadowstyle"></a>
|
|
2310
|
+
## TooltipShadowStyle
|
|
2311
|
+
Authored overlay for TooltipShadowStyle. Tooltip drop-shadow toggle. JS applies the shadow expression when visible=true.
|
|
2312
|
+
|
|
2313
|
+
| Field | Type | Optional | Description |
|
|
2314
|
+
|-------|------|:--------:|-------------|
|
|
2315
|
+
| `visible` | bool | ✓ | Show a drop-shadow on the tooltip box; theme always provides this. |
|
|
2316
|
+
|
|
2269
2317
|
<a id="scaletargetconfig"></a>
|
|
2270
2318
|
## ScaleTargetConfig
|
|
2271
2319
|
Scale configuration for a single style target (background or color).
|
|
@@ -2765,12 +2813,3 @@ Discriminated union of per-family chart patches. type: is mandatory; missing or
|
|
|
2765
2813
|
| `longitude` | str | ✓ | Field containing longitude values for point/bubble maps. |
|
|
2766
2814
|
| `basemap` | [BasemapConfig](#basemapconfig) | ✓ | Tile-layer configuration for the map background. |
|
|
2767
2815
|
| `x_domain` | enum: "union", "primary" | ✓ | Controls how x-values from multiple layer queries are combined. |
|
|
2768
|
-
|
|
2769
|
-
<a id="paginationconfig"></a>
|
|
2770
|
-
## PaginationConfig
|
|
2771
|
-
Table pagination configuration.
|
|
2772
|
-
|
|
2773
|
-
| Field | Type | Optional | Description |
|
|
2774
|
-
|-------|------|:--------:|-------------|
|
|
2775
|
-
| `enabled` | bool | ✓ | Enable client-side pagination for table charts. |
|
|
2776
|
-
| `page_size` | int | ✓ | Rows per page. When enabled and None, the renderer auto-fits page size to the cell — set explicitly to pin the page size. |
|
dataface/agent_api/init.py
CHANGED
|
@@ -51,9 +51,18 @@ def init_project(
|
|
|
51
51
|
(root / "faces" / "partials").mkdir(exist_ok=True)
|
|
52
52
|
|
|
53
53
|
scaffolds: list[tuple[str, str]] = [
|
|
54
|
-
(
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
(
|
|
55
|
+
"dataface.yml",
|
|
56
|
+
_TEMPLATES.joinpath("dataface.yml").read_text(encoding="utf-8"),
|
|
57
|
+
),
|
|
58
|
+
(
|
|
59
|
+
"faces/README.md",
|
|
60
|
+
_TEMPLATES.joinpath("README.md").read_text(encoding="utf-8"),
|
|
61
|
+
),
|
|
62
|
+
(
|
|
63
|
+
"faces/guide.yml",
|
|
64
|
+
_TEMPLATES.joinpath("guide.yml").read_text(encoding="utf-8"),
|
|
65
|
+
),
|
|
57
66
|
("faces/partials/.gitkeep", ""),
|
|
58
67
|
]
|
|
59
68
|
|
|
@@ -62,10 +71,10 @@ def init_project(
|
|
|
62
71
|
if target.exists() and not force:
|
|
63
72
|
result.skipped_files.append(Path(rel))
|
|
64
73
|
elif target.exists():
|
|
65
|
-
target.write_text(content)
|
|
74
|
+
target.write_text(content, encoding="utf-8")
|
|
66
75
|
result.refreshed_files.append(Path(rel))
|
|
67
76
|
else:
|
|
68
|
-
target.write_text(content)
|
|
77
|
+
target.write_text(content, encoding="utf-8")
|
|
69
78
|
result.created_files.append(Path(rel))
|
|
70
79
|
|
|
71
80
|
_ensure_gitignore_entries(root, result)
|
|
@@ -74,10 +83,12 @@ def init_project(
|
|
|
74
83
|
snippet = load_agents_snippet()
|
|
75
84
|
agents_md_path = root / "AGENTS.md"
|
|
76
85
|
existing: str | None = (
|
|
77
|
-
agents_md_path.read_text()
|
|
86
|
+
agents_md_path.read_text(encoding="utf-8")
|
|
87
|
+
if agents_md_path.exists()
|
|
88
|
+
else None
|
|
78
89
|
)
|
|
79
90
|
final_text, action = merge_agents_snippet(existing, snippet)
|
|
80
|
-
agents_md_path.write_text(final_text)
|
|
91
|
+
agents_md_path.write_text(final_text, encoding="utf-8")
|
|
81
92
|
if action == "created":
|
|
82
93
|
result.created_files.append(Path("AGENTS.md"))
|
|
83
94
|
elif action == "refreshed":
|
|
@@ -88,7 +99,7 @@ def init_project(
|
|
|
88
99
|
if write_claude_md:
|
|
89
100
|
claude_md_path = root / "CLAUDE.md"
|
|
90
101
|
if not claude_md_path.exists():
|
|
91
|
-
claude_md_path.write_text("@AGENTS.md\n")
|
|
102
|
+
claude_md_path.write_text("@AGENTS.md\n", encoding="utf-8")
|
|
92
103
|
result.created_files.append(Path("CLAUDE.md"))
|
|
93
104
|
|
|
94
105
|
if eject_inspect:
|
|
@@ -111,16 +122,18 @@ def init_project(
|
|
|
111
122
|
def _ensure_gitignore_entries(root: Path, result: InitResult) -> None:
|
|
112
123
|
gitignore = root / ".gitignore"
|
|
113
124
|
if not gitignore.exists():
|
|
114
|
-
gitignore.write_text("\n".join(GITIGNORE_ENTRIES) + "\n")
|
|
125
|
+
gitignore.write_text("\n".join(GITIGNORE_ENTRIES) + "\n", encoding="utf-8")
|
|
115
126
|
result.created_files.append(Path(".gitignore"))
|
|
116
127
|
return
|
|
117
128
|
|
|
118
|
-
text = gitignore.read_text()
|
|
129
|
+
text = gitignore.read_text(encoding="utf-8")
|
|
119
130
|
existing = set(text.splitlines())
|
|
120
131
|
missing = [e for e in GITIGNORE_ENTRIES if e not in existing]
|
|
121
132
|
if not missing:
|
|
122
133
|
return
|
|
123
134
|
|
|
124
135
|
separator = "" if not text or text.endswith("\n") else "\n"
|
|
125
|
-
gitignore.write_text(
|
|
136
|
+
gitignore.write_text(
|
|
137
|
+
f"{text}{separator}" + "\n".join(missing) + "\n", encoding="utf-8"
|
|
138
|
+
)
|
|
126
139
|
result.refreshed_files.append(Path(".gitignore"))
|
dataface/agent_api/inspect.py
CHANGED
|
@@ -78,9 +78,9 @@ def eject_templates(
|
|
|
78
78
|
if target_file.exists() and not force:
|
|
79
79
|
continue
|
|
80
80
|
|
|
81
|
-
content = source_file.read_text()
|
|
81
|
+
content = source_file.read_text(encoding="utf-8")
|
|
82
82
|
source_hash = sha256(content.encode("utf-8")).hexdigest()
|
|
83
|
-
target_file.write_text(content)
|
|
83
|
+
target_file.write_text(content, encoding="utf-8")
|
|
84
84
|
|
|
85
85
|
manifest_templates[name] = {
|
|
86
86
|
"filename": f"{name}.yml",
|
|
@@ -126,7 +126,7 @@ def _upsert_mcp_config(
|
|
|
126
126
|
existing: dict[str, Any] = {}
|
|
127
127
|
if config_path.exists():
|
|
128
128
|
try:
|
|
129
|
-
existing = json.loads(config_path.read_text())
|
|
129
|
+
existing = json.loads(config_path.read_text(encoding="utf-8"))
|
|
130
130
|
if not isinstance(existing, dict):
|
|
131
131
|
existing = {}
|
|
132
132
|
except (json.JSONDecodeError, OSError):
|
|
@@ -140,7 +140,7 @@ def _upsert_mcp_config(
|
|
|
140
140
|
|
|
141
141
|
existing.setdefault(servers_key, {})
|
|
142
142
|
existing[servers_key]["dataface"] = server_entry
|
|
143
|
-
config_path.write_text(json.dumps(existing, indent=2) + "\n")
|
|
143
|
+
config_path.write_text(json.dumps(existing, indent=2) + "\n", encoding="utf-8")
|
|
144
144
|
return f" {'Updated' if already_has else 'Added dataface to'} {config_path}"
|
|
145
145
|
|
|
146
146
|
|
|
@@ -158,7 +158,7 @@ def _upsert_toml_mcp_config(
|
|
|
158
158
|
|
|
159
159
|
existing: dict[str, Any] = {}
|
|
160
160
|
if config_path.exists():
|
|
161
|
-
existing = tomllib.loads(config_path.read_text())
|
|
161
|
+
existing = tomllib.loads(config_path.read_text(encoding="utf-8"))
|
|
162
162
|
|
|
163
163
|
already_has = "dataface" in existing.get(servers_key, {})
|
|
164
164
|
if already_has and not force:
|
|
@@ -166,5 +166,5 @@ def _upsert_toml_mcp_config(
|
|
|
166
166
|
|
|
167
167
|
existing.setdefault(servers_key, {})
|
|
168
168
|
existing[servers_key]["dataface"] = server_entry
|
|
169
|
-
config_path.write_text(tomli_w.dumps(existing))
|
|
169
|
+
config_path.write_text(tomli_w.dumps(existing), encoding="utf-8")
|
|
170
170
|
return f" {'Updated' if already_has else 'Added dataface to'} {config_path}"
|
dataface/agent_api/pack.py
CHANGED
|
@@ -291,7 +291,8 @@ def _write_face(path: Path, face_dict: dict) -> None:
|
|
|
291
291
|
path.write_text(
|
|
292
292
|
yaml.dump(
|
|
293
293
|
face_dict, default_flow_style=False, sort_keys=False, allow_unicode=True
|
|
294
|
-
)
|
|
294
|
+
),
|
|
295
|
+
encoding="utf-8",
|
|
295
296
|
)
|
|
296
297
|
|
|
297
298
|
|
|
@@ -417,7 +418,8 @@ def apply_proposal(
|
|
|
417
418
|
# Write a minimal partial YAML comment block
|
|
418
419
|
partial_path.write_text(
|
|
419
420
|
f"# Shared partial: {partial_filename}\n"
|
|
420
|
-
f"# Add shared query fragments, variables, or chart definitions here.\n"
|
|
421
|
+
f"# Add shared query fragments, variables, or chart definitions here.\n",
|
|
422
|
+
encoding="utf-8",
|
|
421
423
|
)
|
|
422
424
|
result.created_files.append(rel)
|
|
423
425
|
|
dataface/agent_api/query.py
CHANGED
|
@@ -7,7 +7,7 @@ from pydantic import BaseModel, ConfigDict, Field
|
|
|
7
7
|
|
|
8
8
|
from dataface.agent_api._paths import resolve_scoped_path
|
|
9
9
|
from dataface.core.compile import compile_file
|
|
10
|
-
from dataface.core.compile.models.query.
|
|
10
|
+
from dataface.core.compile.models.query.normalized import SqlQuery
|
|
11
11
|
from dataface.core.execute.adapters import AdapterRegistry
|
|
12
12
|
from dataface.core.validate import normalize_data_for_json
|
|
13
13
|
|
dataface/agent_api/schema.py
CHANGED
|
@@ -646,7 +646,7 @@ def _project_uses_direct_file_queries(project_root: Path) -> bool:
|
|
|
646
646
|
|
|
647
647
|
for dashboard in list_dashboards(directory=project_root, recursive=True).dashboards:
|
|
648
648
|
try:
|
|
649
|
-
content = dashboard.absolute_path.read_text()
|
|
649
|
+
content = dashboard.absolute_path.read_text(encoding="utf-8")
|
|
650
650
|
except OSError:
|
|
651
651
|
continue
|
|
652
652
|
if (
|
dataface/agent_api/search.py
CHANGED
|
@@ -124,7 +124,7 @@ def _build_index(directory: Path) -> list[dict[str, Any]]:
|
|
|
124
124
|
for dash in listing.dashboards:
|
|
125
125
|
abs_path = dash.absolute_path
|
|
126
126
|
try:
|
|
127
|
-
content = yaml.safe_load(abs_path.read_text())
|
|
127
|
+
content = yaml.safe_load(abs_path.read_text(encoding="utf-8"))
|
|
128
128
|
except (yaml.YAMLError, OSError):
|
|
129
129
|
continue
|
|
130
130
|
|
dataface/ai/external_mcp.py
CHANGED
|
@@ -234,7 +234,7 @@ def _parse_json_config(
|
|
|
234
234
|
if not path.exists():
|
|
235
235
|
return
|
|
236
236
|
try:
|
|
237
|
-
data = json.loads(path.read_text())
|
|
237
|
+
data = json.loads(path.read_text(encoding="utf-8"))
|
|
238
238
|
except json.JSONDecodeError:
|
|
239
239
|
_console.print(f"[yellow]MCP: {path} has invalid JSON; skipping[/yellow]")
|
|
240
240
|
return
|
|
@@ -271,7 +271,7 @@ def _parse_toml_config(
|
|
|
271
271
|
if not path.exists():
|
|
272
272
|
return
|
|
273
273
|
try:
|
|
274
|
-
data = tomllib.loads(path.read_text())
|
|
274
|
+
data = tomllib.loads(path.read_text(encoding="utf-8"))
|
|
275
275
|
except (tomllib.TOMLDecodeError, OSError) as exc:
|
|
276
276
|
_console.print(
|
|
277
277
|
f"[yellow]MCP: {path} has invalid TOML: {exc}; skipping[/yellow]"
|
dataface/ai/memories.py
CHANGED
|
@@ -17,7 +17,7 @@ def load_memories(base_dir: Path | None = None) -> list[dict[str, Any]]:
|
|
|
17
17
|
if not path.exists():
|
|
18
18
|
return []
|
|
19
19
|
|
|
20
|
-
payload = yaml.safe_load(path.read_text()) or {}
|
|
20
|
+
payload = yaml.safe_load(path.read_text(encoding="utf-8")) or {}
|
|
21
21
|
rows = payload.get("memories") if isinstance(payload, dict) else None
|
|
22
22
|
if not isinstance(rows, list):
|
|
23
23
|
return []
|