@carllee1983/dbcli 1.17.0 → 1.19.0
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.
- package/CHANGELOG.md +20 -0
- package/README.md +19 -0
- package/README.zh-TW.md +19 -0
- package/assets/SKILL.md +58 -5
- package/assets/reference.md +184 -4
- package/assets/ui-template.html +306 -0
- package/dist/cli.mjs +1660 -63497
- package/dist/ui-style.css +3 -0
- package/package.json +11 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,26 @@ All notable changes to dbcli are documented here.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.19.0] - 2026-05-11
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Expanded Antigravity Protocol**: Added Phase 0 (Scout) for research and Phase 3 (Auditor) for validation to the core agentic workflow.
|
|
13
|
+
- **Enhanced Agent Support**: `dbcli skill --install` now supports **Codex (OMX)** and **Windsurf**.
|
|
14
|
+
- **Cursor Rules Update**: `dbcli skill --install cursor` now uses the modern `.cursor/rules/*.mdc` project-local format.
|
|
15
|
+
- New `GEMINI.md` project-level instruction file with full Antigravity lifecycle guidance.
|
|
16
|
+
|
|
17
|
+
## [1.18.0] - 2026-05-11
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- **Interactive HTML Dashboards**: `query`, `q`, and `export` can now render results as fully interactive, standalone HTML reports.
|
|
22
|
+
- New `--ui` flag to open dashboards directly in the system browser.
|
|
23
|
+
- New `html` format for `stdout` and file-based report generation.
|
|
24
|
+
- Snippet `visual:` block in frontmatter for KPI and chart configuration (Line, Bar, Area, Pie, Scatter).
|
|
25
|
+
- Secure payload injection with automatic HTML escaping and blacklist redaction.
|
|
26
|
+
- Bundled React + Recharts + Tailwind UI template for zero-dependency portability.
|
|
27
|
+
|
|
8
28
|
## [1.17.0] - 2026-05-10
|
|
9
29
|
|
|
10
30
|
### Added
|
package/README.md
CHANGED
|
@@ -133,6 +133,25 @@ The planner is cache-first (no network); add `--probe` to refresh the
|
|
|
133
133
|
underlying inspect context. Use `--list` to see all goals,
|
|
134
134
|
`--format markdown` for human reading, or `--for-agent` for compact JSON.
|
|
135
135
|
|
|
136
|
+
### Interactive HTML Dashboards
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
# Open results in browser
|
|
140
|
+
dbcli query "SELECT * FROM orders" --ui
|
|
141
|
+
|
|
142
|
+
# Run a saved snippet with visualization metadata
|
|
143
|
+
dbcli q @analytics/revenue --ui
|
|
144
|
+
|
|
145
|
+
# Export query results as a standalone HTML file
|
|
146
|
+
dbcli export "SELECT * FROM users" --format html --output report.html
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
`dbcli` can render query results as fully interactive, standalone HTML dashboards. These reports are powered by React + Recharts and are zero-dependency — the entire application and data are inlined into a single HTML file.
|
|
150
|
+
|
|
151
|
+
- **`--ui` flag**: Automatically generates a temporary report and opens it in your default browser.
|
|
152
|
+
- **`visual:` block**: Snippet frontmatter can define KPIs and charts (Line, Bar, Area, Pie, Scatter) to drive the dashboard.
|
|
153
|
+
- **Security**: Result sets are redacted by the blacklist before injection, and data is safely escaped for HTML.
|
|
154
|
+
|
|
136
155
|
### Recovery & Guided Remediation
|
|
137
156
|
|
|
138
157
|
```bash
|
package/README.zh-TW.md
CHANGED
|
@@ -118,6 +118,25 @@ dbcli query '{"status":"active"}' --collection users --use atlas
|
|
|
118
118
|
|
|
119
119
|
對 MongoDB 而言,`list` 與 `query` 會使用該連線設定中的資料庫;`query` 也必須指定 `--collection <名稱>`。
|
|
120
120
|
|
|
121
|
+
### 互動式 HTML 儀表板 (Interactive HTML Dashboards)
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
# 在瀏覽器中開啟查詢結果
|
|
125
|
+
dbcli query "SELECT * FROM orders" --ui
|
|
126
|
+
|
|
127
|
+
# 執行具備視覺化中繼資料的片段
|
|
128
|
+
dbcli q @analytics/revenue --ui
|
|
129
|
+
|
|
130
|
+
# 將結果匯出為獨立的 HTML 檔案
|
|
131
|
+
dbcli export "SELECT * FROM users" --format html --output report.html
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
`dbcli` 可將查詢結果算繪為完全互動、獨立的 HTML 儀表板。這些報表由 React + Recharts 驅動且具備「零依賴」特性 — 整個應用程式與資料皆被內嵌於單一 HTML 檔案中。
|
|
135
|
+
|
|
136
|
+
- **`--ui` 旗標**:自動產生暫時性報表並在預設瀏覽器中開啟。
|
|
137
|
+
- **`visual:` 區塊**:可在查詢片段的 frontmatter 中定義 KPI 與圖表 (Line, Bar, Area, Pie, Scatter)。
|
|
138
|
+
- **安全性**:資料在注入前會先經過黑名單過濾,且針對 HTML 進行了安全跳脫處理。
|
|
139
|
+
|
|
121
140
|
---
|
|
122
141
|
|
|
123
142
|
## 多重連線支援 (v2)
|
package/assets/SKILL.md
CHANGED
|
@@ -188,13 +188,13 @@ Full flags and edge cases: see [reference.md](reference.md) `init` section.
|
|
|
188
188
|
| `use` | n/a | Show/switch default named connection (v2 only). |
|
|
189
189
|
| `list` | query-only+ | Tables (SQL), collections (MongoDB), keys (Redis), or indices (Elasticsearch). |
|
|
190
190
|
| `schema` | query-only+ | SQL: per-table or full scan into `.dbcli/schemas/`. MongoDB: sampled. ES: flattened mapping. Redis: per-key only (type/TTL/size). Supports `--recovery`. |
|
|
191
|
-
| `query` | query-only+ | SQL, Mongo JSON (`--collection`), Redis command, or ES DSL/Lucene (`--collection`). Supports `--recovery`. |
|
|
191
|
+
| `query` | query-only+ | SQL, Mongo JSON (`--collection`), Redis command, or ES DSL/Lucene (`--collection`). `--format table\|json\|csv\|html`, `--ui` to open the interactive dashboard in a browser. Supports `--recovery`. |
|
|
192
192
|
| `plan` | n/a | Static SQL risk analyzer (`--format text\|json`); classifies a statement without connecting to the database. |
|
|
193
|
-
| `q` | query-only+ | Run a saved snippet by `@name` with `--param k=v`. SQL / Elasticsearch DSL / read-only Redis bodies; blacklist enforced. Supports `--recovery`. |
|
|
193
|
+
| `q` | query-only+ | Run a saved snippet by `@name` with `--param k=v`. SQL / Elasticsearch DSL / read-only Redis bodies; blacklist enforced. `--format table\|json\|csv\|html`, `--ui` to open the interactive dashboard. Supports `--recovery`. |
|
|
194
194
|
| `queries` | n/a | Manage saved snippets: `list` / `show` / `search` / `suggest` / `new` / `edit` / `check` / `delete` / `rename` / `copy` / `import` / `export`. |
|
|
195
195
|
| `insert` / `update` | read-write+ | SQL or MongoDB only. JSON `--data` / `--set`; `--where` required on `update`; `--dry-run` first. Redis writes go through `query`. Supports `--recovery`. |
|
|
196
196
|
| `delete` | data-admin+ | SQL or MongoDB only. `--where` required; `--dry-run` first. Supports `--recovery`. |
|
|
197
|
-
| `export` | query-only+ | SQL or MongoDB only. Query →
|
|
197
|
+
| `export` | query-only+ | SQL or MongoDB only. Query → `--format json\|jsonl\|csv\|html` file or stdout. `html` emits a standalone interactive dashboard. Supports `--recovery`. |
|
|
198
198
|
| `blacklist` | n/a | `list` / `table` / `column` subcommands redact sensitive data from query results. |
|
|
199
199
|
| `check` | query-only+ | SQL only (best on MySQL/MariaDB). |
|
|
200
200
|
| `diff` | query-only+ | SQL only. Save/compare schema snapshots. |
|
|
@@ -285,8 +285,9 @@ Manage local snippets with `queries new | edit | delete | rename | copy | import
|
|
|
285
285
|
local layer for editing.
|
|
286
286
|
|
|
287
287
|
Each `.sql` file may declare YAML frontmatter inside `-- ---` blocks
|
|
288
|
-
(name, description, engine, params, tags
|
|
289
|
-
|
|
288
|
+
(name, description, engine, params, tags, optional `intent`, optional `visual`).
|
|
289
|
+
The `visual:` block drives the interactive dashboard (see "Interactive HTML dashboard"
|
|
290
|
+
below). See `dbcli queries show @<name> --format json` for the machine-readable contract.
|
|
290
291
|
|
|
291
292
|
### Engine-specific bodies
|
|
292
293
|
|
|
@@ -321,6 +322,58 @@ Engine variants are picked automatically based on the active connection.
|
|
|
321
322
|
Override any of them by placing a same-named file under `.dbcli-shared/queries/`
|
|
322
323
|
or `.dbcli/queries/`.
|
|
323
324
|
|
|
325
|
+
## Interactive HTML dashboard
|
|
326
|
+
|
|
327
|
+
`query`, `q`, and `export` can render results as a standalone, self-contained HTML
|
|
328
|
+
report powered by a bundled React + Recharts template (`assets/ui-template.html`,
|
|
329
|
+
injected via a hardened `window.__DBCLI_PAYLOAD__ = {...}` block — `<` is escaped
|
|
330
|
+
to neutralise `</script>` payloads).
|
|
331
|
+
|
|
332
|
+
```bash
|
|
333
|
+
# Open in browser (writes to a temp file, then `open`/`xdg-open`/`start`)
|
|
334
|
+
dbcli query "SELECT day, dau FROM dau_daily" --ui
|
|
335
|
+
dbcli q @analytics/revenue --param days=30 --ui
|
|
336
|
+
|
|
337
|
+
# Pipe HTML to stdout (CI artifacts, email, static hosting)
|
|
338
|
+
dbcli query "SELECT * FROM orders" --format html > orders.html
|
|
339
|
+
|
|
340
|
+
# Export to a file (interchangeable with json/jsonl/csv)
|
|
341
|
+
dbcli export "SELECT * FROM orders" --format html --output orders.html
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
`--ui` implies `--format html` and opens the file; `--format html` alone prints to
|
|
345
|
+
stdout. Blacklist redaction is applied **before** rendering — the dashboard never
|
|
346
|
+
sees masked columns.
|
|
347
|
+
|
|
348
|
+
### Snippet `visual:` block
|
|
349
|
+
|
|
350
|
+
To get KPIs and charts (rather than just a sortable table), add a `visual:` block
|
|
351
|
+
to the snippet's frontmatter. Column names must exist in the result row.
|
|
352
|
+
|
|
353
|
+
```sql
|
|
354
|
+
-- ---
|
|
355
|
+
-- name: Revenue Trend
|
|
356
|
+
-- engine: postgres
|
|
357
|
+
-- params:
|
|
358
|
+
-- days: { type: int, default: 30 }
|
|
359
|
+
-- visual:
|
|
360
|
+
-- title: Revenue (last :days days)
|
|
361
|
+
-- kpis:
|
|
362
|
+
-- - { label: Total Revenue, value_column: total_revenue, format: currency }
|
|
363
|
+
-- - { label: Orders, value_column: order_count, format: number }
|
|
364
|
+
-- - { label: Conversion, value_column: conv_rate, format: percent }
|
|
365
|
+
-- charts:
|
|
366
|
+
-- - { type: line, title: Daily Revenue, x: day, y: [revenue] }
|
|
367
|
+
-- - { type: bar, title: By Channel, x: channel, y: [revenue, refunds] }
|
|
368
|
+
-- ---
|
|
369
|
+
SELECT ...
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
- `kpis[].format`: `currency` / `number` / `percent` (omit for raw value).
|
|
373
|
+
- `charts[].type`: `line` / `bar` / `area` / `pie` / `scatter`.
|
|
374
|
+
- Raw `query` invocations (no snippet) render a sortable/filterable table only —
|
|
375
|
+
there is no `visual:` to attach.
|
|
376
|
+
|
|
324
377
|
## Common workflows
|
|
325
378
|
|
|
326
379
|
- **Debug odd state:** `schema` → `check` → `query` with tight `WHERE` → follow FKs from schema JSON. Evidence over theory.
|
package/assets/reference.md
CHANGED
|
@@ -135,9 +135,13 @@ dbcli query "DEL stale:key" # requires data-admin+
|
|
|
135
135
|
# Elasticsearch: DSL body or Lucene q-string
|
|
136
136
|
dbcli query '{"query":{"match":{"status":"active"}}}' --collection orders
|
|
137
137
|
dbcli query 'status:active AND amount:>100' --index orders --limit 50
|
|
138
|
+
|
|
139
|
+
# Interactive HTML dashboard (see "Interactive HTML dashboard" below)
|
|
140
|
+
dbcli query "SELECT day, dau FROM dau_daily" --ui # open in browser
|
|
141
|
+
dbcli query "SELECT * FROM orders" --format html > orders.html # pipe to stdout
|
|
138
142
|
```
|
|
139
143
|
|
|
140
|
-
**Options:** `--format <table|json|csv>`, `--limit <number>`, `--no-limit`, `--collection <name>` (MongoDB / Elasticsearch), `--index <name>` (Elasticsearch alias for `--collection`)
|
|
144
|
+
**Options:** `--format <table|json|csv|html>`, `--ui` (open the dashboard in the system browser; implies `--format html`), `--limit <number>`, `--no-limit`, `--collection <name>` (MongoDB / Elasticsearch), `--index <name>` (Elasticsearch alias for `--collection`), `--recovery`
|
|
141
145
|
**Permission:** query-only+ (Redis: per-command; Elasticsearch: per HTTP method/path)
|
|
142
146
|
|
|
143
147
|
> **MongoDB notes:**
|
|
@@ -156,6 +160,31 @@ dbcli query 'status:active AND amount:>100' --index orders --limit 50
|
|
|
156
160
|
> - Hits are flattened: each result row contains `_id` plus dotted-path fields from `_source`. Pass `--format json` to keep nested structures readable.
|
|
157
161
|
> - Query-only mode caps at 1000 hits; `--no-limit` is internally capped at 10 000 (use saved searches / `search_after` for deeper pagination).
|
|
158
162
|
|
|
163
|
+
### plan
|
|
164
|
+
|
|
165
|
+
Static SQL risk analyzer. Classifies a statement into the same permission tiers
|
|
166
|
+
used by `query` (`query-only` / `read-write` / `data-admin` / `admin`) and lists
|
|
167
|
+
the underlying signals (DML / DDL / multi-statement / unsafe constructs) without
|
|
168
|
+
ever connecting to the database.
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
dbcli plan "SELECT * FROM users"
|
|
172
|
+
dbcli plan "UPDATE users SET name='x'" # human-readable text classification
|
|
173
|
+
dbcli plan "DROP TABLE users" --format json # machine-readable risk report
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
**Options:** `--format <text|json>` (default `text`).
|
|
177
|
+
**Permission:** n/a (offline analyzer; no connection opened).
|
|
178
|
+
|
|
179
|
+
Use cases:
|
|
180
|
+
- Agents that want to decide whether to call `query` vs `insert` / `update` /
|
|
181
|
+
`delete` before sending SQL.
|
|
182
|
+
- Pre-flight safety check before binding parameters into a saved snippet.
|
|
183
|
+
- Lint hook for code review pipelines that store SQL in source.
|
|
184
|
+
|
|
185
|
+
`plan` does not enforce blacklist or auto-`LIMIT`; those still apply when the
|
|
186
|
+
SQL is actually executed via `query` / `q`.
|
|
187
|
+
|
|
159
188
|
### q
|
|
160
189
|
|
|
161
190
|
Run a saved query snippet by `@name`. Snippets are parameterised SELECT/WITH statements resolved from three layers, with **local > shared > builtin** precedence (a local file always shadows shared and builtin variants of the same key):
|
|
@@ -172,15 +201,19 @@ dbcli q @dau --param days=30 --format json # override a param
|
|
|
172
201
|
dbcli q @analytics/revenue --param-file params.json
|
|
173
202
|
dbcli q @dau --dry-run # show final SQL + bind values
|
|
174
203
|
dbcli q @dau --no-limit # disable size guard wrap
|
|
204
|
+
dbcli q @analytics/revenue --param days=30 --ui # open dashboard
|
|
205
|
+
dbcli q @analytics/revenue --param days=30 --format html > report.html
|
|
175
206
|
```
|
|
176
207
|
|
|
177
208
|
**Options:**
|
|
178
|
-
- `--format <table|json|csv>` — output format (default: `table`)
|
|
209
|
+
- `--format <table|json|csv|html>` — output format (default: `table`)
|
|
210
|
+
- `--ui` — open the rendered HTML dashboard in the system browser (implies `--format html`; writes to a temp file then invokes `open` / `xdg-open` / `start`)
|
|
179
211
|
- `--param <key=value>` — pass a parameter (repeatable)
|
|
180
212
|
- `--param-file <path>` — JSON object whose keys are param names
|
|
181
213
|
- `--no-limit` — skip the `SELECT * FROM (…) AS _dbcli_guard LIMIT 1000` wrap
|
|
182
214
|
- `--dry-run` — print the bound SQL + values without executing
|
|
183
215
|
- `--use <name>` — pick a v2 named connection
|
|
216
|
+
- `--recovery` — emit a `RecoveryEnvelope` on failure (see `recover`)
|
|
184
217
|
|
|
185
218
|
**Permission:** query-only+
|
|
186
219
|
|
|
@@ -201,6 +234,13 @@ Each `.sql` file is plain SQL with optional YAML frontmatter inside a leading `-
|
|
|
201
234
|
-- description: lookback window in days
|
|
202
235
|
-- enum: [7, 30, 90]
|
|
203
236
|
-- tags: [analytics]
|
|
237
|
+
-- intent: perf.slow-query # optional; consumed by `queries suggest`
|
|
238
|
+
-- visual: # optional; consumed by `--ui` / `--format html`
|
|
239
|
+
-- title: Daily Active Users
|
|
240
|
+
-- kpis:
|
|
241
|
+
-- - { label: DAU, value_column: dau, format: number }
|
|
242
|
+
-- charts:
|
|
243
|
+
-- - { type: line, title: DAU trend, x: day, y: [dau] }
|
|
204
244
|
-- ---
|
|
205
245
|
SELECT COUNT(DISTINCT user_id) AS dau
|
|
206
246
|
FROM events
|
|
@@ -209,6 +249,8 @@ WHERE created_at > NOW() - (:days || ' days')::interval;
|
|
|
209
249
|
|
|
210
250
|
Param placeholders use `:name`. They are rewritten to `$1, $2, …` (Postgres) or `?, ?, …` (MySQL) at execution time and passed as bind values — string interpolation is never used.
|
|
211
251
|
|
|
252
|
+
The `visual:` block is documented in detail under [Interactive HTML dashboard](#interactive-html-dashboard) below. Unknown / malformed fields are silently dropped at parse time; the snippet still runs and the dashboard falls back to a sortable table.
|
|
253
|
+
|
|
212
254
|
#### Param type coercion
|
|
213
255
|
|
|
214
256
|
| Declared `type` | Accepts |
|
|
@@ -299,6 +341,10 @@ dbcli queries list --tag analytics --engine postgres --format json
|
|
|
299
341
|
dbcli queries list --source local # only personal overrides
|
|
300
342
|
dbcli queries show @dau # frontmatter + SQL
|
|
301
343
|
dbcli queries show @dau --format json # MCP-shaped contract
|
|
344
|
+
dbcli queries search slow query # fuzzy-ranked keyword search across snippets
|
|
345
|
+
dbcli queries search cache --engine postgres --source builtin --limit 5
|
|
346
|
+
dbcli queries suggest perf # browse snippets by intent prefix (v1.11+)
|
|
347
|
+
dbcli queries suggest perf.cache-hit --format json
|
|
302
348
|
|
|
303
349
|
# Authoring
|
|
304
350
|
dbcli queries new @new/sample # scaffold under .dbcli-shared/queries/
|
|
@@ -319,8 +365,10 @@ dbcli queries export @dau --output dau.sql # write snippet body to a fi
|
|
|
319
365
|
dbcli queries export @diag/connections --engine postgres # pick a variant when multiple engines exist
|
|
320
366
|
```
|
|
321
367
|
|
|
322
|
-
**`list` options:** `--format <table|json|csv>`, `--tag <tag>`, `--engine <postgres|mysql>`, `--source <local|shared>`
|
|
368
|
+
**`list` options:** `--format <table|json|csv>`, `--tag <tag>`, `--engine <postgres|mysql|redis|elasticsearch|all>`, `--source <local|shared|builtin|all>`
|
|
323
369
|
**`show` options:** `--format <table|json|csv>`
|
|
370
|
+
**`search` options:** `--format <table|json>`, `--engine <postgres|mysql|redis|elasticsearch|all>`, `--source <local|shared|builtin|all>`, `--limit <n>` (default 10), `--include-internal` (show fuzzy ranking score). Keyword(s) are fuzzy-matched against name, description, tags, intent.
|
|
371
|
+
**`suggest` options:** `--format <table|json>`, `--engine <postgres|mysql|redis|elasticsearch|all>`, `--source <local|shared|builtin|all>`. Intent prefix-matched against the snippet's `intent` frontmatter field. Common intents: `perf.slow-query`, `perf.cache-hit`, `capacity.size`, `safety.connections`, `monitor.cluster-health`.
|
|
324
372
|
**`new` options:** `--local`, `--edit`
|
|
325
373
|
**`edit` options:** `--shared`
|
|
326
374
|
**`check` options:** `--strict`, `--format <table|json|csv>`
|
|
@@ -378,11 +426,15 @@ Export query results to file or stdout.
|
|
|
378
426
|
dbcli export "SELECT * FROM users" --format csv --output users.csv
|
|
379
427
|
dbcli export "SELECT * FROM users" --format csv --output users.csv --force # Skip overwrite confirmation
|
|
380
428
|
dbcli export "SELECT * FROM users" --format json | jq '.[]'
|
|
429
|
+
dbcli export "SELECT * FROM users" --format jsonl --output users.ndjson
|
|
430
|
+
dbcli export "SELECT * FROM orders" --format html --output orders.html # standalone dashboard
|
|
381
431
|
```
|
|
382
432
|
|
|
383
|
-
**Options:** `--format <json|csv>` (required), `--output <path>`, `--force`
|
|
433
|
+
**Options:** `--format <json|jsonl|csv|html>` (required), `--output <path>`, `--force`, `--recovery`
|
|
384
434
|
**Permission:** query-only+
|
|
385
435
|
|
|
436
|
+
The `html` format emits the same self-contained dashboard as `query --ui` (see [Interactive HTML dashboard](#interactive-html-dashboard)). Because `export` runs raw SQL (no snippet metadata), the HTML report is always rendered as a sortable / filterable table — no KPIs or charts. Use `dbcli q @<name> --format html` (or `--ui`) for the charted view.
|
|
437
|
+
|
|
386
438
|
### blacklist
|
|
387
439
|
|
|
388
440
|
Manage sensitive data blacklist to prevent AI access to restricted tables/columns.
|
|
@@ -850,6 +902,32 @@ dbcli migrate drop-enum status --execute --force
|
|
|
850
902
|
|
|
851
903
|
**AI agent note:** Always use dry-run first (no `--execute`) to preview generated SQL. Only add `--execute` after confirming the SQL is correct. For DROP operations, both `--execute` and `--force` are required.
|
|
852
904
|
|
|
905
|
+
### skill
|
|
906
|
+
|
|
907
|
+
Emit `SKILL.md` (and the companion `reference.md`) to stdout, a file, or one of
|
|
908
|
+
four AI-agent platform directories. The skill is the source of truth that lets
|
|
909
|
+
Claude Code / Gemini / Copilot / Cursor know how to drive dbcli safely.
|
|
910
|
+
|
|
911
|
+
```bash
|
|
912
|
+
dbcli skill # print SKILL.md to stdout
|
|
913
|
+
dbcli skill --output ./SKILL.md # write to a file (no platform install)
|
|
914
|
+
dbcli skill --install claude # install to ~/.claude/skills/dbcli/
|
|
915
|
+
dbcli skill --install gemini # install to ~/.gemini/skills/dbcli/
|
|
916
|
+
dbcli skill --install copilot # install to .github/skills/dbcli/ (repo-local)
|
|
917
|
+
dbcli skill --install cursor # install to .cursor/skills/dbcli/ (repo-local)
|
|
918
|
+
```
|
|
919
|
+
|
|
920
|
+
**Options:**
|
|
921
|
+
- `--install <platform>` — `claude` | `gemini` | `copilot` | `cursor`. Writes `SKILL.md` plus `reference.md` next to it so the agent gets progressive disclosure.
|
|
922
|
+
- `--output <path>` — write `SKILL.md` to a file instead of stdout. Does not install `reference.md`.
|
|
923
|
+
|
|
924
|
+
**Notes:**
|
|
925
|
+
- Both files come straight from `assets/SKILL.md` + `assets/reference.md` inside the dbcli package — no runtime rendering. Keep these in sync when shipping a release.
|
|
926
|
+
- `claude` / `gemini` install paths are user-global; `copilot` / `cursor` are repo-local under `.github/` / `.cursor/`.
|
|
927
|
+
- Re-running `--install` overwrites the existing skill atomically; no prompt.
|
|
928
|
+
|
|
929
|
+
**Permission:** n/a.
|
|
930
|
+
|
|
853
931
|
### skill tasks (Agent Task Packs)
|
|
854
932
|
|
|
855
933
|
```bash
|
|
@@ -877,6 +955,108 @@ Task storage layers:
|
|
|
877
955
|
Higher tiers override lower tiers by task name. Task name is derived from the
|
|
878
956
|
file path under the tier root (e.g. `diag/inspect.md` → `diag/inspect`).
|
|
879
957
|
|
|
958
|
+
## Interactive HTML dashboard
|
|
959
|
+
|
|
960
|
+
`query`, `q`, and `export` can render results as a single, fully self-contained
|
|
961
|
+
HTML file backed by a bundled React + Recharts template. The template lives at
|
|
962
|
+
`assets/ui-template.html` and is installed alongside the binary; no external
|
|
963
|
+
network, CDN, or runtime is required to view the report.
|
|
964
|
+
|
|
965
|
+
### Entry points
|
|
966
|
+
|
|
967
|
+
| Command form | Behaviour |
|
|
968
|
+
|--------------|-----------|
|
|
969
|
+
| `dbcli query "<sql>" --ui` | Render to a temp file under `$TMPDIR/dbcli-query-<ts>.html` and open with `open` / `xdg-open` / `start`. |
|
|
970
|
+
| `dbcli q @<name> --ui` | Same, with snippet metadata (`name`, `description`, `visual:` block). |
|
|
971
|
+
| `dbcli query "<sql>" --format html` | Print HTML to stdout (pipe, redirect, attach). |
|
|
972
|
+
| `dbcli q @<name> --format html` | Same, snippet-aware. |
|
|
973
|
+
| `dbcli export "<sql>" --format html --output report.html` | Write HTML to an explicit path; respects `--force` / overwrite confirmation. |
|
|
974
|
+
|
|
975
|
+
`--ui` is a convenience flag — it implies `--format html` and then opens the
|
|
976
|
+
file. `--ui` and `--format` are mutually compatible; passing both is allowed and
|
|
977
|
+
behaves as `--ui`.
|
|
978
|
+
|
|
979
|
+
### Data injection contract
|
|
980
|
+
|
|
981
|
+
The template ships with a single placeholder, `/*DBCLI_PAYLOAD*/`, which dbcli
|
|
982
|
+
replaces with:
|
|
983
|
+
|
|
984
|
+
```js
|
|
985
|
+
window.__DBCLI_PAYLOAD__ = { "meta": {...}, "rows": [...] };
|
|
986
|
+
```
|
|
987
|
+
|
|
988
|
+
Hardening rules applied before injection:
|
|
989
|
+
|
|
990
|
+
- Payload is `JSON.stringify(...)`-encoded.
|
|
991
|
+
- Every `<` is replaced with `<` so a malicious row containing `</script>`
|
|
992
|
+
cannot terminate the inline script tag.
|
|
993
|
+
- Blacklist redaction (`dbcli blacklist`) runs **before** the formatter — masked
|
|
994
|
+
columns never reach the dashboard.
|
|
995
|
+
- The replacement uses a function callback (`html.replace(..., () => injection)`)
|
|
996
|
+
so `$&`-style backreferences in the payload are not interpreted.
|
|
997
|
+
|
|
998
|
+
### `meta` shape
|
|
999
|
+
|
|
1000
|
+
`meta` is the `SavedQueryMeta` object (see `dbcli queries show @<name> --format json`):
|
|
1001
|
+
|
|
1002
|
+
```jsonc
|
|
1003
|
+
{
|
|
1004
|
+
"name": "Revenue Trend", // display title
|
|
1005
|
+
"key": "@analytics/revenue", // snippet key, or "raw-sql" / "export"
|
|
1006
|
+
"description": "...", // free text (SQL preview for raw query)
|
|
1007
|
+
"params": [...], // ParamSpec[]
|
|
1008
|
+
"tags": ["analytics"],
|
|
1009
|
+
"intent": "perf.slow-query",
|
|
1010
|
+
"visual": { ... } // optional, see below
|
|
1011
|
+
}
|
|
1012
|
+
```
|
|
1013
|
+
|
|
1014
|
+
For raw `query` / `export` invocations, `meta.params` is `[]` and
|
|
1015
|
+
`meta.visual` is absent — the dashboard renders a sortable / filterable table.
|
|
1016
|
+
|
|
1017
|
+
### `visual:` block (snippet frontmatter)
|
|
1018
|
+
|
|
1019
|
+
```yaml
|
|
1020
|
+
visual:
|
|
1021
|
+
title: Revenue (last :days days) # optional override of meta.name
|
|
1022
|
+
kpis:
|
|
1023
|
+
- label: Total Revenue
|
|
1024
|
+
value_column: total_revenue # must exist in result rows
|
|
1025
|
+
format: currency # currency | number | percent (optional)
|
|
1026
|
+
- label: Orders
|
|
1027
|
+
value_column: order_count
|
|
1028
|
+
format: number
|
|
1029
|
+
charts:
|
|
1030
|
+
- type: line # line | bar | area | pie | scatter
|
|
1031
|
+
title: Daily Revenue
|
|
1032
|
+
x: day # column for X axis
|
|
1033
|
+
y: [revenue] # 1..N columns for series
|
|
1034
|
+
- type: bar
|
|
1035
|
+
title: By Channel
|
|
1036
|
+
x: channel
|
|
1037
|
+
y: [revenue, refunds]
|
|
1038
|
+
```
|
|
1039
|
+
|
|
1040
|
+
Parser behaviour (`src/core/saved-queries/parser.ts::normaliseVisual`):
|
|
1041
|
+
|
|
1042
|
+
- The block is **optional**. Missing → table-only render.
|
|
1043
|
+
- Items missing required fields (`kpi.label` + `kpi.value_column`, or
|
|
1044
|
+
`chart.type` + `chart.x` + `chart.y[]`) are silently dropped.
|
|
1045
|
+
- Unknown `format` / `type` values are forwarded as strings; the dashboard
|
|
1046
|
+
decides how to render them (unknown chart types fall back gracefully).
|
|
1047
|
+
- The snippet still executes as a normal SQL/DSL query — `visual:` only affects
|
|
1048
|
+
the HTML renderer.
|
|
1049
|
+
|
|
1050
|
+
### Limitations
|
|
1051
|
+
|
|
1052
|
+
- The dashboard is read-only; there is no in-page editor or re-run button.
|
|
1053
|
+
- Raw `query` / `export` HTML output never shows KPIs or charts (no snippet
|
|
1054
|
+
metadata is available). Use `dbcli q @<name>` for the charted view.
|
|
1055
|
+
- Engine support follows the underlying command: SQL, MongoDB (`--collection`),
|
|
1056
|
+
Redis, and Elasticsearch (`--collection`) all render through the same template.
|
|
1057
|
+
- Very wide / very long result sets render as a single client-side table; for
|
|
1058
|
+
>10k rows prefer `--format csv` / `--format jsonl` and a downstream tool.
|
|
1059
|
+
|
|
880
1060
|
## MongoDB Support
|
|
881
1061
|
|
|
882
1062
|
MongoDB connections use a JSON-based query model instead of SQL. Treat MongoDB support as a narrower document-database path, not as a full SQL feature equivalent.
|