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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ dist/
.claude/
.cursor/
.obsidian/
CLAUDE.md
---
# Keep lockfile out of the repo — biome's optionalDependencies need to
# resolve at install time per platform, and a macOS-generated lockfile
Expand Down
30 changes: 26 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,24 @@ Installed by `buron setup` into every editor folder you select.
| `buron file move <from> <to>` | Move or rename a file |
| `buron file replace <path>` | Find and replace text in a file |

#### Data

You query by picking metrics, dimensions, and filters from a dataset — there is no query language. Add `--json` to any read command for pipeable output.

| Command | Purpose |
|---------|---------|
| `buron datasets list` | List datasets this team can query, with availability |
| `buron datasets describe <id>` | Show a dataset's metrics, dimensions, and filter operators |
| `buron datasets query <id>` | Run a query (`-m` measures, `-d` dimensions, `-f field:op:value`, `--from/--to/--granularity`, `--sort`, `--limit`, or `--spec <file\|->`) |
| `buron sql <statement>` | Read-only SELECT against your warehouse (escape hatch; prefer `datasets query`) |
| `buron queries list` | List saved queries (`--dataset <id>` to filter) |
| `buron queries create <name> --spec <file\|->` | Save a structured query from a SemanticQuery spec |
| `buron queries run <id>` | Run a saved query and return fresh results |
| `buron dashboards list` | List available dashboards |
| `buron dashboards run <id> --from --to` | Run a dashboard for a date range |
| `buron dashboards add <dashboardId> <queryId>` | Add a saved query as a tile on a custom dashboard |
| `buron integration <provider>` | Check an integration's connection status |

#### Skills

| Command | Purpose |
Expand All @@ -113,10 +131,14 @@ buron file read /wiki/launches/2025-05-onboarding-flow/blog.md \
buron file read /wiki/launches/2025-05-onboarding-flow/changelog.md \
> CHANGELOG.md

# Check which ad creatives are performing best before a redesign
buron query "SELECT ad_group_ad.ad.name, metrics.conversions, metrics.cost_micros
FROM ad_group_ad WHERE segments.date DURING LAST_30_DAYS
ORDER BY metrics.conversions DESC LIMIT 10" --source gaql
# Discover what data you can query, then pick fields — no query language
buron datasets list
buron datasets describe cross-channel-ads

# Which ad creatives are performing best before a redesign
buron datasets query cross-channel-ads \
-m cost,conversions -d ad_name \
--from 2026-06-01 --to 2026-06-30 --sort conversions:desc --limit 10

# See what competitors are doing
buron file grep "positioning" --directory /wiki/entities/competitors/
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@buron/cli",
"version": "0.2.5",
"version": "0.3.0",
"description": "Turn code changes into launch-ready marketing. Capture what you ship, and let Buron's agents generate content, update campaigns, and track performance.",
"type": "module",
"bin": {
Expand Down
72 changes: 59 additions & 13 deletions src/bin.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import { Command } from "commander";
import {
dashboardsAddCommand,
dashboardsListCommand,
dashboardsRunCommand,
datasetsDescribeCommand,
datasetsListCommand,
datasetsQueryCommand,
integrationCommand,
queriesCreateCommand,
queriesListCommand,
queriesRunCommand,
queryCommand,
sqlCommand,
} from "./commands/data.js";
import {
fileAppendCommand,
Expand Down Expand Up @@ -107,15 +111,47 @@ file
.option("-a, --all", "Replace all occurrences (default: first only)")
.action(fileReplaceCommand);

// ── query ───────────────────────────────────────────────────────────
// ── datasets ────────────────────────────────────────────────────────

program
.command("query <queryString>")
.description("Execute an ad-hoc query against a connected data source")
.requiredOption("-s, --source <source>", "Query source (e.g. gaql)")
function collect(value: string, previous: string[]): string[] {
return previous.concat([value]);
}

const datasets = program.command("datasets").description("Discover and query your data");

datasets
.command("list")
.description("List datasets this team can query, with availability")
.option("--json", "Output raw JSON")
.action(datasetsListCommand);

datasets
.command("describe <id>")
.description("Show a dataset's metrics, dimensions, and filter operators")
.action(datasetsDescribeCommand);

datasets
.command("query <id>")
.description("Run a query by picking measures, dimensions, and filters — no SQL")
.option("-m, --measures <a,b>", "Metric field keys (comma-separated)")
.option("-d, --dimensions <x,y>", "Dimension field keys (comma-separated)")
.option("-f, --filter <field:op:value>", "Filter (repeatable)", collect, [])
.option("--from <date>", "Start date (YYYY-MM-DD)")
.option("--to <date>", "End date (YYYY-MM-DD)")
.action(queryCommand);
.option("--granularity <grain>", "day|week|month|quarter|year")
.option("--sort <field:dir>", "Sort (repeatable)", collect, [])
.option("--limit <n>", "Max rows")
.option("--spec <file|->", "Full SemanticQuery JSON (overrides flags)")
.option("--json", "Output raw JSON")
.action(datasetsQueryCommand);

// ── sql (warehouse escape hatch) ────────────────────────────────────

program
.command("sql <statement>")
.description("Run a read-only SELECT against your warehouse (prefer datasets query)")
.option("--json", "Output raw JSON")
.action(sqlCommand);

// ── queries ─────────────────────────────────────────────────────────

Expand All @@ -124,27 +160,32 @@ const queries = program.command("queries").description("Manage saved queries");
queries
.command("list")
.description("List saved queries")
.option("-s, --source <source>", "Filter by source")
.option("--dataset <id>", "Filter by dataset id")
.option("--json", "Output raw JSON")
.action(queriesListCommand);

queries
.command("create <name>")
.description("Create a saved query")
.requiredOption("-s, --source <source>", "Query source (e.g. gaql)")
.requiredOption("-q, --query <queryString>", "The query string")
.option("--config <json>", "Chart/display config as JSON")
.description("Save a structured query from a SemanticQuery spec")
.requiredOption("--spec <file|->", "SemanticQuery JSON (dataset + picks)")
.option("--chart <kind>", "table|line|bar|area|donut")
.action(queriesCreateCommand);

queries
.command("run <id>")
.description("Execute a saved query and return fresh results")
.option("--json", "Output raw JSON")
.action(queriesRunCommand);

// ── dashboards ──────────────────────────────────────────────────────

const dashboards = program.command("dashboards").description("View and run dashboards");

dashboards.command("list").description("List available dashboards").action(dashboardsListCommand);
dashboards
.command("list")
.description("List available dashboards")
.option("--json", "Output raw JSON")
.action(dashboardsListCommand);

dashboards
.command("run <id>")
Expand All @@ -154,6 +195,11 @@ dashboards
.option("--fresh", "Bypass cache")
.action(dashboardsRunCommand);

dashboards
.command("add <dashboardId> <queryId>")
.description("Add a saved query as a tile on a custom dashboard")
.action(dashboardsAddCommand);

// ── integration ─────────────────────────────────────────────────────

program
Expand Down
Loading
Loading