@carllee1983/dbcli 1.51.2 → 1.52.1
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/.cursor/rules/dbcli.mdc +34 -27
- package/.cursor/skills/dbcli/reference.md +290 -16
- package/.github/skills/dbcli/SKILL.md +31 -24
- package/.github/skills/dbcli/reference.md +290 -16
- package/CHANGELOG.md +37 -0
- package/README.md +1 -0
- package/README.zh-TW.md +1 -0
- package/assets/SKILL.md +31 -24
- package/assets/SKILL.zh-TW.md +44 -29
- package/assets/reference.md +290 -16
- package/assets/tasks/design-review.md +42 -0
- package/dist/cli-runtime.mjs +109629 -0
- package/dist/cli.mjs +140 -108817
- package/dist/core.d.ts +8 -0
- package/package.json +4 -1
- package/plugins/dbcli-agent/skills/dbcli/SKILL.md +31 -24
- package/plugins/dbcli-agent/skills/dbcli/reference.md +290 -16
- package/skills/dbcli/SKILL.md +31 -24
- package/skills/dbcli/reference.md +290 -16
|
@@ -4,6 +4,66 @@ Companion to [SKILL.md](SKILL.md). Exhaustive flags, copy-paste examples, `shell
|
|
|
4
4
|
|
|
5
5
|
For cross-engine support status, see `docs/feature-matrix.md` in the repository.
|
|
6
6
|
|
|
7
|
+
## Index
|
|
8
|
+
|
|
9
|
+
Jump straight to what you need — this file is long, and reading it end to end is
|
|
10
|
+
never the right move.
|
|
11
|
+
|
|
12
|
+
| Section | What is in it |
|
|
13
|
+
|---|---|
|
|
14
|
+
| [Global options and placement](#global-options-and-placement) | Flags that must precede the command (`--use`, `--config`), and [redirecting output](#redirecting-output). |
|
|
15
|
+
| [Commands](#commands) | Every command, one `###` each — see the command list below. |
|
|
16
|
+
| [Recovery Cookbook](#recovery-cookbook-agent-walkthroughs) | Failure-to-fix walkthroughs S1–S6, the [scenario index](#scenario-index), [risk gate cheat sheet](#risk-gate-cheat-sheet), and [common pitfalls](#common-pitfalls). |
|
|
17
|
+
| [Interactive HTML dashboard](#interactive-html-dashboard) | `--ui` / `--format html`: [entry points](#entry-points), [data injection contract](#data-injection-contract), [`meta` shape](#meta-shape). |
|
|
18
|
+
| [MongoDB Support](#mongodb-support) | Connection shapes, JSON query bodies, write-stage guard. |
|
|
19
|
+
| [Redis Support](#redis-support) | Command permission tiers, size guards, key masking. |
|
|
20
|
+
| [Elasticsearch Support](#elasticsearch-support) | DSL and Lucene queries, scroll export, mapping flattening. |
|
|
21
|
+
|
|
22
|
+
**Commands** —
|
|
23
|
+
[init](#init) ·
|
|
24
|
+
[use](#use) ·
|
|
25
|
+
[list](#list) ·
|
|
26
|
+
[schema](#schema) ·
|
|
27
|
+
[query](#query) ·
|
|
28
|
+
[explain](#explain) ·
|
|
29
|
+
[lint](#lint) ·
|
|
30
|
+
[plan](#plan) ·
|
|
31
|
+
[q](#q) ·
|
|
32
|
+
[queries](#queries) ·
|
|
33
|
+
[insert](#insert) ·
|
|
34
|
+
[update](#update) ·
|
|
35
|
+
[delete](#delete) ·
|
|
36
|
+
[export](#export) ·
|
|
37
|
+
[blacklist](#blacklist) ·
|
|
38
|
+
[check](#check) ·
|
|
39
|
+
[diff](#diff) ·
|
|
40
|
+
[design](#design) ·
|
|
41
|
+
[snapshot](#snapshot) ·
|
|
42
|
+
[assert](#assert) ·
|
|
43
|
+
[proxy](#proxy) ·
|
|
44
|
+
[status](#status) ·
|
|
45
|
+
[inspect](#inspect) ·
|
|
46
|
+
[report](#report) ·
|
|
47
|
+
[guide](#guide) ·
|
|
48
|
+
[recovery](#recovery) ·
|
|
49
|
+
[recover](#recover) ·
|
|
50
|
+
[audit](#audit) ·
|
|
51
|
+
[verify](#verify) ·
|
|
52
|
+
[verification](#verification) ·
|
|
53
|
+
[backfill](#backfill) ·
|
|
54
|
+
[doctor](#doctor) ·
|
|
55
|
+
[completion](#completion) ·
|
|
56
|
+
[upgrade](#upgrade) ·
|
|
57
|
+
[shell](#dbcli-shell) ·
|
|
58
|
+
[migrate](#migrate) ·
|
|
59
|
+
[semantic](#semantic) ·
|
|
60
|
+
[skill](#skill) ·
|
|
61
|
+
[skill context](#skill-context) ·
|
|
62
|
+
[skill tasks](#skill-tasks-agent-task-packs)
|
|
63
|
+
|
|
64
|
+
Also worth knowing before you connect:
|
|
65
|
+
[Agent configuration trust boundary](#agent-configuration-trust-boundary).
|
|
66
|
+
|
|
7
67
|
## Global options and placement
|
|
8
68
|
|
|
9
69
|
These options are available on the root `dbcli` command. Root-level options must
|
|
@@ -220,9 +280,44 @@ dbcli query "SELECT day, dau FROM dau_daily" --ui # open in brows
|
|
|
220
280
|
dbcli query "SELECT * FROM orders" --format html > orders.html # pipe to stdout
|
|
221
281
|
```
|
|
222
282
|
|
|
223
|
-
**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`), `--fields <list>`, `--truncate <number>` / `--no-truncate`, `-f, --query-file <path>`, `--use <name[,name]>`, `--recovery`
|
|
283
|
+
**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`), `--fields <list>`, `--truncate <number>` / `--no-truncate`, `-f, --query-file <path>`, `--use <name[,name]>`, `--slow-ms <number>`, `--recovery`
|
|
224
284
|
**Permission:** query-only+ (Redis: per-command; Elasticsearch: per HTTP method/path)
|
|
225
285
|
|
|
286
|
+
#### Passive slow-query hint (`--slow-ms`)
|
|
287
|
+
|
|
288
|
+
`query` and `q` read the execution time they already measured for a finished
|
|
289
|
+
query and, at or above the threshold, add a hint. Default `1000`; `--slow-ms 0`
|
|
290
|
+
disables it for that invocation. This is **not** the `proxy` / `proxy analyze`
|
|
291
|
+
flag of the same name — that one flags events in the proxy log; this one only
|
|
292
|
+
annotates a single command's own result.
|
|
293
|
+
|
|
294
|
+
The hint performs no extra work: it never runs `EXPLAIN`, reads a schema, or
|
|
295
|
+
issues a second request. It is suppressed entirely under `--recovery`, so the
|
|
296
|
+
recovery envelope keeps its exact machine contract.
|
|
297
|
+
|
|
298
|
+
- `--format table` appends `Performance hint: <recommendation>` to the footer.
|
|
299
|
+
- `--format json` adds `metadata.performanceAdvisory`:
|
|
300
|
+
|
|
301
|
+
```json
|
|
302
|
+
{
|
|
303
|
+
"metadata": {
|
|
304
|
+
"statement": "SELECT",
|
|
305
|
+
"performanceAdvisory": {
|
|
306
|
+
"code": "SLOW_QUERY",
|
|
307
|
+
"executionTimeMs": 1250,
|
|
308
|
+
"thresholdMs": 1000,
|
|
309
|
+
"recommendation": "Review safely with: dbcli guide slow-query --format markdown. This hint runs no additional database diagnostics."
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
The recommendation is engine-aware: PostgreSQL, MySQL, MariaDB, and Redis are
|
|
316
|
+
pointed at `dbcli guide slow-query`, because that goal resolves to real
|
|
317
|
+
diagnostic snippets for them. MongoDB and Elasticsearch ship no snippet for its
|
|
318
|
+
intents, so their hint states the timing and says so instead of naming a command
|
|
319
|
+
that would come back empty. `csv` and `html` output are unchanged.
|
|
320
|
+
|
|
226
321
|
Below `admin`, SQL holding more than one statement is rejected, because only the
|
|
227
322
|
first statement would decide the permission check while a driver on the simple
|
|
228
323
|
query protocol executes them all. Semicolons inside string literals, backtick
|
|
@@ -526,12 +621,15 @@ dbcli q @analytics/revenue --param days=30 --format html > report.html
|
|
|
526
621
|
- `--ui` — open the rendered HTML dashboard in the system browser (implies `--format html`; writes to a temp file then invokes `open` / `xdg-open` / `start`)
|
|
527
622
|
- `--param <key=value>` — pass a parameter (repeatable)
|
|
528
623
|
- `--param-file <path>` — JSON object whose keys are param names
|
|
529
|
-
- `--no-limit` — skip the `SELECT * FROM (…) AS _dbcli_guard LIMIT
|
|
624
|
+
- `--no-limit` — skip the `SELECT * FROM (…) AS _dbcli_guard LIMIT 1001` wrap (the effective cap is 1000; one extra row is fetched to detect truncation)
|
|
530
625
|
- `--dry-run` — print the bound SQL + values without executing
|
|
531
|
-
- `--
|
|
626
|
+
- `--slow-ms <number>` — passive slow-query hint threshold (default `1000`; `0` disables). Same contract as `query` — see "Passive slow-query hint" there
|
|
532
627
|
- `--recovery` — emit a `RecoveryEnvelope` on failure (see `recover`)
|
|
533
628
|
- `--verify` — run the snippet's verification assertions after execution (only if the snippet defines them)
|
|
534
629
|
|
|
630
|
+
`q` has no command-level `--use`. To run a snippet against a v2 named connection,
|
|
631
|
+
use the global form: `dbcli --use <name> q @<snippet>`.
|
|
632
|
+
|
|
535
633
|
**Permission:** query-only+
|
|
536
634
|
|
|
537
635
|
#### Snippet file format
|
|
@@ -655,8 +753,9 @@ Size guard: `LRANGE` / `ZRANGE` stop overridden when `< 0` or `> 1000`; `SCAN` /
|
|
|
655
753
|
##### MongoDB snippets
|
|
656
754
|
|
|
657
755
|
File extension: `.mongodb.sql`. Frontmatter must declare `engine: mongodb` and
|
|
658
|
-
`operation: find` or `operation: aggregate`. `target: <collection>`
|
|
659
|
-
collection
|
|
756
|
+
`operation: find` or `operation: aggregate`. `target: <collection>` declares the
|
|
757
|
+
collection the snippet runs against; the CLI has no flag to override it, so a different
|
|
758
|
+
collection means a different snippet. The body is JSON: an object
|
|
660
759
|
for `find` and an array for `aggregate`. Each `{{param}}` placeholder is JSON-encoded
|
|
661
760
|
at substitution time — strings are quoted and escaped, so an attacker-supplied string
|
|
662
761
|
cannot escape into operator position.
|
|
@@ -1077,6 +1176,178 @@ Both parameters are required. Keep each expansion as one quoted shell argument;
|
|
|
1077
1176
|
never use `eval`, and consider `--execute` only after the plan and captured DDL
|
|
1078
1177
|
have been reviewed.
|
|
1079
1178
|
|
|
1179
|
+
### design
|
|
1180
|
+
|
|
1181
|
+
Author, validate, render, and review a version-controlled SQL database design
|
|
1182
|
+
kept beside the code as `dbcli.design.json`. Every subcommand is offline: none
|
|
1183
|
+
opens a database connection, executes DDL, or calls an LLM. `design init` is the
|
|
1184
|
+
only writer, and it writes only to the explicit `--output` path.
|
|
1185
|
+
|
|
1186
|
+
```text
|
|
1187
|
+
dbcli design init --output <path> [--dialect <dialect>]
|
|
1188
|
+
dbcli design validate [--file <path>] [--format <format>]
|
|
1189
|
+
dbcli design render [--file <path>] [--format <format>]
|
|
1190
|
+
dbcli design diff (--against-cache | --against-orm <paths>) [options]
|
|
1191
|
+
dbcli design propose (--against-cache | --against-orm <paths>) [options]
|
|
1192
|
+
```
|
|
1193
|
+
|
|
1194
|
+
```bash
|
|
1195
|
+
# Writes only to this explicit, missing path; edit the starter before validating.
|
|
1196
|
+
dbcli design init --output ./dbcli.design.json --dialect postgresql
|
|
1197
|
+
|
|
1198
|
+
dbcli design validate --format json
|
|
1199
|
+
dbcli design render --format mermaid
|
|
1200
|
+
dbcli design diff --against-cache --format markdown
|
|
1201
|
+
dbcli design diff --against-orm ./prisma/schema.prisma --format markdown
|
|
1202
|
+
dbcli design propose --against-orm ./prisma/schema.prisma --format markdown
|
|
1203
|
+
```
|
|
1204
|
+
|
|
1205
|
+
| Option | Applies to | Default | Meaning |
|
|
1206
|
+
|---|---|---|---|
|
|
1207
|
+
| `--output <path>` | `init` | required | Destination for the new artifact; refuses to overwrite an existing file. |
|
|
1208
|
+
| `--dialect <postgresql\|mysql\|mariadb>` | `init` | `postgresql` | Target SQL dialect recorded in the artifact. |
|
|
1209
|
+
| `--file <path>` | all but `init` | `dbcli.design.json` | Design artifact to read. |
|
|
1210
|
+
| `--format <format>` | all but `init` | see below | `validate`/`propose`: `json`, `markdown`. `render`: `json`, `markdown`, `mermaid` (default `markdown`). `diff`: `json` (default), `table`, `markdown`. |
|
|
1211
|
+
| `--against-cache` | `diff`, `propose` | off | Compare with the local schema cache; requires a configured PostgreSQL/MySQL/MariaDB connection whose system matches the artifact dialect, and a non-empty cache (run `dbcli schema` first). |
|
|
1212
|
+
| `--against-orm <paths>` | `diff`, `propose` | none | Compare with local ORM definition(s); repeatable or comma-separated, DDL paths support globs. Needs no config and no connection. |
|
|
1213
|
+
| `--orm-format <format>` | `diff`, `propose` | auto-detect | Force `prisma`, `ddl`, `json`, `drizzle`, `typeorm`, or `sequelize`. |
|
|
1214
|
+
| `--ignore <globs>` | `diff`, `propose` | none | Comma-separated table globs excluded from drift. |
|
|
1215
|
+
|
|
1216
|
+
`diff` and `propose` require **exactly one** comparison target; passing both or
|
|
1217
|
+
neither is an error.
|
|
1218
|
+
|
|
1219
|
+
#### Artifact shape
|
|
1220
|
+
|
|
1221
|
+
This example validates clean (0 errors, 0 warnings):
|
|
1222
|
+
|
|
1223
|
+
```json
|
|
1224
|
+
{
|
|
1225
|
+
"version": 1,
|
|
1226
|
+
"dialect": "postgresql",
|
|
1227
|
+
"models": [
|
|
1228
|
+
{
|
|
1229
|
+
"name": "orders",
|
|
1230
|
+
"table": "orders",
|
|
1231
|
+
"description": "Completed purchases.",
|
|
1232
|
+
"fields": [
|
|
1233
|
+
{ "name": "id", "type": "bigint", "nullable": false, "primaryKey": true, "unique": true },
|
|
1234
|
+
{ "name": "customer_id", "type": "bigint", "nullable": false },
|
|
1235
|
+
{ "name": "created_at", "type": "timestamptz", "nullable": false }
|
|
1236
|
+
],
|
|
1237
|
+
"indexes": [
|
|
1238
|
+
{ "name": "orders_customer_idx", "columns": ["customer_id", "created_at"], "unique": false }
|
|
1239
|
+
]
|
|
1240
|
+
},
|
|
1241
|
+
{
|
|
1242
|
+
"name": "customers",
|
|
1243
|
+
"table": "customers",
|
|
1244
|
+
"fields": [
|
|
1245
|
+
{ "name": "id", "type": "bigint", "nullable": false, "primaryKey": true, "unique": true }
|
|
1246
|
+
]
|
|
1247
|
+
}
|
|
1248
|
+
],
|
|
1249
|
+
"relationships": [
|
|
1250
|
+
{
|
|
1251
|
+
"name": "orders-customer",
|
|
1252
|
+
"from": { "model": "orders", "field": "customer_id" },
|
|
1253
|
+
"to": { "model": "customers", "field": "id" },
|
|
1254
|
+
"cardinality": "many-to-one"
|
|
1255
|
+
}
|
|
1256
|
+
],
|
|
1257
|
+
"accessPatterns": [{ "model": "orders", "filters": ["customer_id"], "sort": ["created_at"] }],
|
|
1258
|
+
"decisions": [{ "name": "single-currency", "rationale": "Amounts are stored in minor units, USD only." }]
|
|
1259
|
+
}
|
|
1260
|
+
```
|
|
1261
|
+
|
|
1262
|
+
It holds no SQL, credentials, rows, or provider configuration. `design init`
|
|
1263
|
+
emits this envelope with empty `models`, `relationships`, `accessPatterns`, and
|
|
1264
|
+
`decisions`.
|
|
1265
|
+
|
|
1266
|
+
#### Naming and limits
|
|
1267
|
+
|
|
1268
|
+
Two different naming rules apply, and mixing them up is the most common way an
|
|
1269
|
+
artifact fails before any review rule runs.
|
|
1270
|
+
|
|
1271
|
+
| Applies to | Rule |
|
|
1272
|
+
|---|---|
|
|
1273
|
+
| `models[].name`, `relationships[].name`, `relationships[].from/to.model`, `accessPatterns[].model`, `decisions[].name` | lowercase kebab-case, `^[a-z][a-z0-9-]*$` — underscores are rejected |
|
|
1274
|
+
| `models[].table`, `fields[].name`, `indexes[].name`, `indexes[].columns[]`, `filters[]`, `sort[]` | SQL identifier, `^[A-Za-z_][A-Za-z0-9_]*$` |
|
|
1275
|
+
|
|
1276
|
+
Relationship endpoints reference a **model name**, not a table name. Every object
|
|
1277
|
+
is strict: an unknown key is an error, not ignored. `description` and `rationale`
|
|
1278
|
+
are 1–1000 characters and must not contain SQL keywords or a connection string —
|
|
1279
|
+
"rows we delete after 30 days" is rejected for the word `delete`. `fields[].type`
|
|
1280
|
+
is at most 100 characters with no `;` or newline. `primaryKey`, `unique`,
|
|
1281
|
+
`indexes`, `filters`, `sort`, `relationships`, `accessPatterns`, and `decisions`
|
|
1282
|
+
may all be omitted.
|
|
1283
|
+
|
|
1284
|
+
Limits: file 256 KiB, 100 models, 100 fields per model, 200 relationships,
|
|
1285
|
+
200 access patterns, 100 decisions, 1–16 columns per index, ≤16 entries in
|
|
1286
|
+
`filters` and `sort`.
|
|
1287
|
+
|
|
1288
|
+
#### Review findings
|
|
1289
|
+
|
|
1290
|
+
`validate` is fail-closed: any `error` finding exits `1`, and `render`, `diff`,
|
|
1291
|
+
and `propose` refuse to do their work while errors remain.
|
|
1292
|
+
|
|
1293
|
+
Structural problems — malformed JSON, an unknown key, a naming or type violation,
|
|
1294
|
+
a missing file, or a file over 256 KiB — are rejected before review runs and are
|
|
1295
|
+
reported as a single `INVALID_ARTIFACT` finding (`error`) whose `path` points at
|
|
1296
|
+
the offending JSON location. None of the codes below appear in that case.
|
|
1297
|
+
|
|
1298
|
+
| Severity | Codes |
|
|
1299
|
+
|---|---|
|
|
1300
|
+
| `error` | `NO_MODELS`, `DUPLICATE_MODEL`, `DUPLICATE_TABLE`, `DUPLICATE_FIELD`, `PRIMARY_KEY_COUNT`, `NULLABLE_PRIMARY_KEY`, `UNKNOWN_INDEX_FIELD`, `DUPLICATE_RELATIONSHIP`, `REVERSE_RELATIONSHIP`, `UNKNOWN_RELATIONSHIP_MODEL`, `UNKNOWN_RELATIONSHIP_FIELD`, `RELATIONSHIP_TYPE_MISMATCH`, `MANY_TO_MANY_REQUIRES_BRIDGE`, `ONE_TO_ONE_REQUIRES_UNIQUE_FK`, `UNKNOWN_ACCESS_MODEL`, `UNKNOWN_ACCESS_FIELD` |
|
|
1301
|
+
| `warn` | `DUPLICATE_INDEX`, `REDUNDANT_PRIMARY_KEY_INDEX`, `PREFIX_REDUNDANT_INDEX`, `ACCESS_PATTERN_INDEX` |
|
|
1302
|
+
|
|
1303
|
+
`REVERSE_RELATIONSHIP` fires when the same endpoints are declared again in the
|
|
1304
|
+
opposite direction; `PREFIX_REDUNDANT_INDEX` fires when a non-unique index is a
|
|
1305
|
+
leading-column prefix of a longer index. `v1` requires exactly one primary-key
|
|
1306
|
+
field per model and an explicit bridge model for `many-to-many`.
|
|
1307
|
+
|
|
1308
|
+
#### `design propose` (review-only)
|
|
1309
|
+
|
|
1310
|
+
`propose` turns drift into a plan a human reviews; it never applies a write. Each
|
|
1311
|
+
entry carries a `safety` of `dry-run` (an existing `migrate` command can represent
|
|
1312
|
+
the change losslessly) or `migration-review` (everything else), plus `preflight`,
|
|
1313
|
+
`rollback`, and `verification` steps:
|
|
1314
|
+
|
|
1315
|
+
```json
|
|
1316
|
+
{
|
|
1317
|
+
"table": "orders",
|
|
1318
|
+
"object": "total_cents",
|
|
1319
|
+
"safety": "migration-review",
|
|
1320
|
+
"commands": ["..."],
|
|
1321
|
+
"preflight": [
|
|
1322
|
+
"dbcli blacklist list",
|
|
1323
|
+
"Confirm the exact affected table with: dbcli schema <exact-table> --format json"
|
|
1324
|
+
],
|
|
1325
|
+
"rollback": "Capture the current schema and generated DDL before any approved write; define the inverse migration before execution.",
|
|
1326
|
+
"verification": [
|
|
1327
|
+
"After an approved write, run: dbcli schema <exact-table> --format json",
|
|
1328
|
+
"Re-run this same design diff command and review the remaining drift."
|
|
1329
|
+
]
|
|
1330
|
+
}
|
|
1331
|
+
```
|
|
1332
|
+
|
|
1333
|
+
**Workflows:**
|
|
1334
|
+
|
|
1335
|
+
- **New project** — `design init` → edit the artifact → `design validate` →
|
|
1336
|
+
`design render`. If application models already exist, use the offline
|
|
1337
|
+
`design diff --against-orm <path>` to reconcile the artifact and the ORM before
|
|
1338
|
+
any database exists.
|
|
1339
|
+
- **Existing database** — `blacklist list` → refresh the cache with
|
|
1340
|
+
`schema --format json` → `design diff --against-cache` →
|
|
1341
|
+
`design propose --against-cache`. Review the plan, perform any approved
|
|
1342
|
+
migration separately, then refresh the schema and rerun the same diff.
|
|
1343
|
+
|
|
1344
|
+
**Exit codes:** `0` when no errors, `1` when the artifact has review errors, an
|
|
1345
|
+
invalid target selection, an unreadable file, or reported drift errors.
|
|
1346
|
+
|
|
1347
|
+
An external coding agent may draft the artifact, but a human should review it
|
|
1348
|
+
before it is relied upon. Do not create or rewrite `dbcli.design.json` without an
|
|
1349
|
+
explicit human request.
|
|
1350
|
+
|
|
1080
1351
|
### snapshot
|
|
1081
1352
|
|
|
1082
1353
|
Capture a **result fingerprint** of a query (not schema): `rowCount` plus per-column
|
|
@@ -1128,7 +1399,7 @@ Opt-in flag trio that persists a **VerificationArtifact JSON** (schema v1) under
|
|
|
1128
1399
|
| Flag | Required | Description |
|
|
1129
1400
|
| :--- | :--- | :--- |
|
|
1130
1401
|
| `--write-verification-artifact` | opt-in | Trigger artifact write. No-op when no verdict has been produced. |
|
|
1131
|
-
| `--verification-subject <kind:name>` | yes (when flag is set) | Subject identifier. Format: `<kind>:<name>`. Allowed kinds: `recovery`, `task-pack`, `assertion`, `migration`, `backfill`, `manual`. |
|
|
1402
|
+
| `--verification-subject <kind:name>` | yes (when flag is set) | Subject identifier. Format: `<kind>:<name>`. Allowed kinds: `recovery`, `task-pack`, `assertion`, `migration`, `backfill`, `table`, `manual`. |
|
|
1132
1403
|
| `--verification-summary <text>` | no | Free-text summary line stored in the artifact. Default when pass: "Assertion verified the expected state." Default when fail: "Assertion did not verify the expected state." |
|
|
1133
1404
|
|
|
1134
1405
|
**Output contract:**
|
|
@@ -1390,7 +1661,7 @@ Examples:
|
|
|
1390
1661
|
|
|
1391
1662
|
Boundaries:
|
|
1392
1663
|
- Recovery only **suggests** commands; agents (or humans) execute them. No automatic remediation in v1.15.0.
|
|
1393
|
-
-
|
|
1664
|
+
- `--recovery` is honored on `query`, `q`, `insert`, `update`, `delete`, `export`, `schema`, `inspect`, `lint`, and `diff`. Other commands (`report`, `guide`, `doctor`, `migrate`, `init`, `use`, `status`, `list`, `check`, `plan`, `shell`, `blacklist`, `completion`, `upgrade`, `skill`) keep their existing error behavior.
|
|
1394
1665
|
- `dbcli inspect --require-schema-cache` throws `SCHEMA_CACHE_MISSING` when the active SQL connection has no usable schema cache. Combine with `--recovery` for the structured envelope.
|
|
1395
1666
|
- `BLACKLIST_COLUMN_WRITE` and `PERMISSION_DENIED` envelopes prepend a `risk: 'dry-run'` step (e.g. `dbcli insert <table> --dry-run`) when the failing operation was an INSERT / UPDATE / DELETE.
|
|
1396
1667
|
- Recovery steps reuse the v1.14.0 `GuideStep` shape, including the full `risk` enum (`readonly` / `dry-run` / `write` / `unknown`).
|
|
@@ -1424,7 +1695,7 @@ Boundaries:
|
|
|
1424
1695
|
|---|---|---|
|
|
1425
1696
|
| `readonly` | local read-only | `dbcli inspect`, `dbcli doctor`, `dbcli blacklist list`, `dbcli schema <table>` |
|
|
1426
1697
|
| `dry-run` | write subcommand invoked with `--dry-run` | `dbcli update orders --where id=1 --dry-run`, `dbcli q @x --dry-run` |
|
|
1427
|
-
| `local-write` | writes local config / cache / blacklist | `dbcli blacklist remove <table>`, `dbcli use <name>`, `dbcli schema --refresh` |
|
|
1698
|
+
| `local-write` | writes local config / cache / blacklist | `dbcli blacklist table remove <table>`, `dbcli use <name>`, `dbcli schema --refresh` |
|
|
1428
1699
|
| `db-write` | mutates the connected database | `dbcli update orders --where id=1 --set …` (no `--dry-run`), `dbcli q @x` (no `--dry-run`) |
|
|
1429
1700
|
| `interactive` | requires TTY | `dbcli init`, `dbcli init --force` |
|
|
1430
1701
|
|
|
@@ -1577,7 +1848,7 @@ dbcli recover --next --after-step 1 --result '{"status":"ok"}' --format markdown
|
|
|
1577
1848
|
|
|
1578
1849
|
(v1.20.0+) Inspect, query, and manage the per-connection audit log written to `.dbcli/audit/<connection>.jsonl`.
|
|
1579
1850
|
|
|
1580
|
-
Audit entries are metadata-only by design — never raw SQL bodies, `--param` values, or result cell contents (D3 lock). Redaction is sourced from `
|
|
1851
|
+
Audit entries are metadata-only by design — never raw SQL bodies, `--param` values, or result cell contents (D3 lock). Redaction is sourced from `src/utils/redaction.ts` (same source as `inspect` / `guide` / `recover` agent contracts).
|
|
1581
1852
|
|
|
1582
1853
|
#### Subcommands
|
|
1583
1854
|
|
|
@@ -1614,7 +1885,9 @@ Examples:
|
|
|
1614
1885
|
| `<id-prefix>` | Positional. UUID or prefix ≥ 4 characters; ambiguous prefix exits 1 with disambiguation hint; prefix < 4 chars exits 1. | — |
|
|
1615
1886
|
| `--recovery-ref <id>` | Find the audit entry whose `recovery_ref` field matches this id (exact, not prefix). Mutually exclusive with positional `<id-prefix>` (D-38). | — |
|
|
1616
1887
|
| `--all` | Search across all connections. Output is an envelope `{ connection, entry }` (single-hit also envelope, for shape stability — D-36). | off |
|
|
1617
|
-
| `--
|
|
1888
|
+
| `--brief` | Trim `metadata` and `redacted_query` from the entry. | off |
|
|
1889
|
+
| `--for-agent` | Shortcut for `--format json --brief`. | off |
|
|
1890
|
+
| `--no-brief` | Disable brief mode when a higher-level default enables it (e.g. `--for-agent`). | off |
|
|
1618
1891
|
| `--format <fmt>` | `table` \| `json`. | `table` |
|
|
1619
1892
|
|
|
1620
1893
|
Examples:
|
|
@@ -1648,7 +1921,7 @@ Output reports: writer enabled/disabled, last write result, file-lock state, rot
|
|
|
1648
1921
|
#### Boundaries
|
|
1649
1922
|
|
|
1650
1923
|
- Entries are append-only JSONL; rotation triggers at `~10 MB` or `~1000` entries (whichever first). Previous segment is preserved as `.jsonl.1`.
|
|
1651
|
-
- Bi-directional `recovery_ref` / `audit_ref` linkage is wired on every command that accepts `--recovery`: `query`, `inspect`, `insert`, `update`, `delete`, `export`, `q`, and `schema`. Use `audit
|
|
1924
|
+
- Bi-directional `recovery_ref` / `audit_ref` linkage is wired on every command that accepts `--recovery`: `query`, `inspect`, `insert`, `update`, `delete`, `export`, `q`, and `schema`. Use `audit show --recovery-ref <id>` to find the audit entry an envelope was emitted alongside.
|
|
1652
1925
|
- Audit writer failures are non-fatal (D6): main command result and exit code are preserved; a stderr warning is emitted. `audit health` surfaces the failure reason.
|
|
1653
1926
|
- Reader truncation tolerance: a crash-truncated last line is skipped with a stderr warn `[dbcli audit] skipping truncated last line in <file>`; a mid-file non-JSON line is treated as corruption, exits 1, and points at `dbcli audit clear`.
|
|
1654
1927
|
|
|
@@ -1909,7 +2182,7 @@ dbcli verification list --include-invalid --format json
|
|
|
1909
2182
|
| `--format <json\|table>` | Output format. | `json` |
|
|
1910
2183
|
| `--limit <n>` | Maximum number of entries to return. | `20` |
|
|
1911
2184
|
| `--status <status>` | Filter by status. One of: `verified`, `not_verified`, `indeterminate`, `blocked`. | all |
|
|
1912
|
-
| `--subject <kind[:name]>` | Filter by subject kind or exact `kind:name`. Allowed kinds: `recovery`, `task-pack`, `assertion`, `migration`, `backfill`, `manual`. | all |
|
|
2185
|
+
| `--subject <kind[:name]>` | Filter by subject kind or exact `kind:name`. Allowed kinds: `recovery`, `task-pack`, `assertion`, `migration`, `backfill`, `table`, `manual`. | all |
|
|
1913
2186
|
| `--include-invalid` | Surface malformed artifact files (normally skipped silently). Invalid files are returned as a separate top-level `invalid` array in JSON output, each entry shaped `{ "path": "...", "filename": "...", "error": "..." }`. When off, `invalid` is `[]`. | off |
|
|
1914
2187
|
|
|
1915
2188
|
**Missing directory:** if `.dbcli/verification/` does not exist, exits `0` with an
|
|
@@ -2023,6 +2296,7 @@ includes `storageDir`, `dryRun`, `cutoff`, `criteria`, `protected`, `candidates`
|
|
|
2023
2296
|
| `assertion` | General-purpose inline assertions. |
|
|
2024
2297
|
| `migration` | Schema migration pre/post checks. |
|
|
2025
2298
|
| `backfill` | Data backfill verification assertions. |
|
|
2299
|
+
| `table` | `verify constraint` artifacts — the subject name is the table checked. |
|
|
2026
2300
|
| `manual` | Manually triggered or ad-hoc verification runs. |
|
|
2027
2301
|
|
|
2028
2302
|
**Storage root:** `<cwd>/.dbcli/verification/` (cwd-relative; independent of `--config`).
|
|
@@ -2855,9 +3129,9 @@ Permission is derived from the command's first token (case-insensitive). Unknown
|
|
|
2855
3129
|
|
|
2856
3130
|
| Tier | Commands |
|
|
2857
3131
|
|------|----------|
|
|
2858
|
-
| `query-only` | `GET`, `MGET`, `STRLEN`, `EXISTS`, `TTL`, `PTTL`, `TYPE`, `SCAN`, `HGET`, `HGETALL`, `HKEYS`, `HVALS`, `HLEN`, `HEXISTS`, `HMGET`, `LRANGE`, `LLEN`, `LINDEX`, `SMEMBERS`, `SCARD`, `SISMEMBER`, `ZRANGE`, `ZREVRANGE`, `ZRANGEBYSCORE`, `ZCARD`, `ZSCORE`, `PING`, `ECHO` |
|
|
2859
|
-
| `read-write` | `SET`, `SETEX`, `SETNX`, `PSETEX`, `MSET`, `MSETNX`, `APPEND`, `INCR`/`INCRBY`, `DECR`/`DECRBY`, `HSET`/`HSETNX`/`HMSET`/`HINCRBY`, `LPUSH`/`RPUSH`/`LPOP`/`RPOP`/`LSET`, `SADD`/`SREM`, `ZADD`/`ZREM`, `EXPIRE`/`EXPIREAT`/`PEXPIRE`/`PERSIST`, `RENAME` |
|
|
2860
|
-
| `data-admin` | `DEL`, `UNLINK`, `HDEL` |
|
|
3132
|
+
| `query-only` | `GET`, `MGET`, `STRLEN`, `EXISTS`, `TTL`, `PTTL`, `TYPE`, `SCAN`, `HGET`, `HGETALL`, `HKEYS`, `HVALS`, `HLEN`, `HEXISTS`, `HMGET`, `LRANGE`, `LLEN`, `LINDEX`, `SMEMBERS`, `SCARD`, `SISMEMBER`, `ZRANGE`, `ZREVRANGE`, `ZRANGEBYSCORE`, `ZCARD`, `ZSCORE`, `XLEN`, `XREAD`, `XRANGE`, `XREVRANGE`, `PING`, `ECHO` |
|
|
3133
|
+
| `read-write` | `SET`, `SETEX`, `SETNX`, `PSETEX`, `MSET`, `MSETNX`, `APPEND`, `INCR`/`INCRBY`, `DECR`/`DECRBY`, `HSET`/`HSETNX`/`HMSET`/`HINCRBY`, `LPUSH`/`RPUSH`/`LPOP`/`RPOP`/`LSET`/`LREM`, `SADD`/`SREM`, `ZADD`/`ZREM`, `XADD`, `EXPIRE`/`EXPIREAT`/`PEXPIRE`/`PERSIST`, `RENAME` |
|
|
3134
|
+
| `data-admin` | `DEL`, `UNLINK`, `HDEL`, `XDEL` |
|
|
2861
3135
|
| `admin` | `FLUSHDB`, `FLUSHALL`, `CONFIG`, `INFO`, `CLIENT`, `DEBUG`, `SHUTDOWN`, `KEYS`, `MONITOR`, `SAVE`, `BGSAVE`, `BGREWRITEAOF`, `REPLICAOF`, `SLAVEOF`, `ACL` |
|
|
2862
3136
|
|
|
2863
3137
|
### Schema inspection
|
|
@@ -3068,5 +3342,5 @@ GET /orders/_search
|
|
|
3068
3342
|
|
|
3069
3343
|
- Writes (`insert`/`update`/`delete`) are not exposed yet — the adapter implements them, but the CLI currently only routes them for SQL and MongoDB. Read-only `export` (v1.22) and the interactive `shell` (v1.22) are available.
|
|
3070
3344
|
- No `_search/scroll` or PIT pagination at the CLI layer; large pulls need a saved external script.
|
|
3071
|
-
- `check`, `diff`,
|
|
3345
|
+
- `check`, `diff`, and `migrate` are SQL-only and exit with errors (or fall through to a generic "unsupported" path). `q` **is** supported — Elasticsearch snippets use the `.elasticsearch.sql` extension (see `@diag/es-cluster-health`).
|
|
3072
3346
|
- Blacklist column rules are applied to flattened hit rows on `query`; table-level blacklist rejects an index up front.
|