Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- `dx -v` now prints the CLI version, matching the documented lowercase version flag. Version checks are also skipped for help/version output and global-option-only invocations, preventing update prompts from interfering with those commands.

### Updated

- Updated the skill, the `dx reports create/update` help text, and the blank report template created on `dx reports init`, to include the relevant context about variable usage.

## 0.5.5 - 2026-07-13

### Updated
Expand Down
8 changes: 8 additions & 0 deletions skills/dx-cli/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,14 @@ Use this for any question about DX itself rather than the user's own data: produ

**Exemption** — A time-bound approved pass on a failing check for a specific entity. A check result with a non-null `exemption_expires_at` is exempted: it may still be failing, but is not counted against the entity until the exemption expires.

### Data Studio terms

**Report** — A saved collection of tiles (see `dx studio reports`), organized on a dedicated page for dashboards and sharing.

**Tile** — A single saved query and chart configuration within a report. Each tile's SQL can reference report variables.

**Variable** — A named, `$`-prefixed placeholder (e.g. `$team_ids`) that a report's tile SQL can reference for interactive filtering. **Built-in variables** (`$service_ids`, `$team_ids`, `$tag_ids`, `$user_ids`, `$repo_ids`, `$start_date`, `$end_date`) are provided out of the box and just need to be toggled on. **Custom variables** are account-defined dropdown filters backed by a SQL query that returns `value` and `label` columns. Variables cannot be managed through the CLI/API — enabling/disabling built-ins and adding/updating/deleting custom variables must be done in the Data Studio UI — but once enabled on a report, any tile's SQL (including tiles set via `dx studio reports create`/`update`) can reference them.

## Reference Docs

- [Catalog management](./references/catalog-management.md) — Entities and entity types: listing, inspecting, creating, updating, and deleting.
Expand Down
28 changes: 28 additions & 0 deletions skills/dx-cli/references/report-creation.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,31 @@ Provide `editor_emails` only when `edit_access_type` is `specific_users`.
Supported tile `chart_type` values are `line`, `pie`, `stacked_bar`, `scatter`, and `table`.

`line`, `stacked_bar`, and `scatter` chart configs require `xAxis` and `yAxes`; `pie` chart configs require `labelColumn` and `valueColumn`; `table` chart configs can be `{}`.

---

## Variables

Tile `sql` can reference report variables to make a report interactive: place `$variable_name` anywhere in the query, and the selected value(s) are substituted in when the report runs.

### Built-in variables

- `$service_ids` — filter by specific services
- `$team_ids` — filter by team assignments
- `$tag_ids` — filter by attributes
- `$user_ids` — filter by individual users
- `$repo_ids` — filter by specific repositories
- `$start_date` and `$end_date` — filter by date range

### Custom variables

Custom variables are account-defined dropdown filters backed by a SQL query. Each has a title, a variable name (used as `$variable_name` in tile SQL), a description, and a SQL statement that must return exactly two columns: `value` (used in the substitution) and `label` (shown to users in the dropdown).

### Limitation: no CLI/API management

Variables cannot be created, updated, enabled, or disabled through this CLI or the API. There is no field for them in the report YAML.

- Built-in variables are toggled on/off per report in the Data Studio UI.
- Custom variables are added, edited, and deleted per account in the Data Studio UI.

Once a variable is enabled on a report (via the UI), any tile's `sql` — including tiles created or updated via `dx studio reports create`/`update` — can reference it as `$variable_name`.
46 changes: 46 additions & 0 deletions src/commandHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,52 @@ export function createExampleText(examples: Example[]): string {
return lines.join("\n");
}

export function createNoteText(paragraphs: string[]): string {
const width = getHelpWidth();
const indent = " ";
const output = [];

output.push(""); // separate from the rest of the help text
output.push("Notes:");

paragraphs.forEach((paragraph, index) => {
if (index > 0) {
output.push(""); // blank line between paragraphs
}
output.push(...wrapParagraph(paragraph, width, indent));
});

return output.join("\n");
}

function getHelpWidth(): number {
return process.stdout.isTTY && process.stdout.columns
? process.stdout.columns
: 80;
}

function wrapParagraph(text: string, width: number, indent: string): string[] {
const words = text.split(/\s+/).filter(Boolean);
const lines: string[] = [];
let current = "";

for (const word of words) {
const candidate = current ? `${current} ${word}` : word;
if (current && indent.length + candidate.length > width) {
lines.push(`${indent}${current}`);
current = word;
} else {
current = candidate;
}
}

if (current) {
lines.push(`${indent}${current}`);
}

return lines;
}

function inferContext(command?: Command, argv?: string[]): CliContext {
if (command) {
return getContext(command);
Expand Down
5 changes: 5 additions & 0 deletions src/commands/studio/report-blank-template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ edit_access_type: read_only
editor_emails: []

# Supported chart_type values: line, pie, stacked_bar, scatter, table
#
# Tile sql can reference report variables (e.g. $team_ids, $start_date, or a
# custom variable) as $variable_name. Variables themselves can't be managed
# from the CLI/API — enable built-in variables or add/edit custom ones for
# this report in the Data Studio UI, then reference them here.
tiles:
- title: ""
sql: |-
Expand Down
8 changes: 8 additions & 0 deletions src/commands/studio/reports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { parse as parseYaml, stringify as stringifyYaml } from "yaml";

import {
createExampleText,
createNoteText,
getContext,
parsePositiveIntOption,
wrapAction,
Expand All @@ -16,6 +17,11 @@ import { buildRuntime } from "../../runtime.js";
import type { Runtime } from "../../types.js";
import * as ui from "../../ui.js";

const VARIABLES_NOTE_TEXT = [
"Tile SQL can reference report variables using `$variable_name` syntax. Built-in variables — $service_ids, $team_ids, $tag_ids, $user_ids, $repo_ids, $start_date, $end_date — filter by service, team, attribute, user, repo, and date range, respectively. Custom variables are account-defined dropdown filters backed by a SQL query.",
"Variables cannot be created, updated, enabled, or disabled via this CLI or the API. Built-in variables must be toggled, and custom variables must be added, edited, or removed, from the report's settings in the Data Studio UI. Once a variable is enabled on a report, its `$variable_name` can be used in any tile's SQL via --from-file/--from-stdin.",
];

export function reportsCommand() {
const reports = new Command()
.name("reports")
Expand All @@ -32,6 +38,7 @@ export function reportsCommand() {
"--from-stdin",
"Read YAML from stdin and create a report from its contents",
)
.addHelpText("afterAll", createNoteText(VARIABLES_NOTE_TEXT))
.addHelpText(
"afterAll",
createExampleText([
Expand Down Expand Up @@ -252,6 +259,7 @@ export function reportsCommand() {
"--from-stdin",
"Read YAML from stdin and update the report with its contents",
)
.addHelpText("afterAll", createNoteText(VARIABLES_NOTE_TEXT))
.addHelpText(
"afterAll",
createExampleText([
Expand Down
Loading