@carllee1983/dbcli 1.39.1 → 1.39.2

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/dist/core.mjs CHANGED
@@ -17423,6 +17423,7 @@ class SessionIdService {
17423
17423
 
17424
17424
  // src/core/config-binding.ts
17425
17425
  import { createHash } from "crypto";
17426
+ import { mkdir as mkdir4, unlink } from "fs/promises";
17426
17427
  import { homedir } from "os";
17427
17428
  import { basename, join as join3, resolve } from "path";
17428
17429
  var BINDING_FILE_NAME = "config.json";
@@ -17467,8 +17468,8 @@ async function writeProjectBinding(projectPath, storagePath = getProjectStorageP
17467
17468
  createdAt: new Date().toISOString()
17468
17469
  }
17469
17470
  };
17470
- await Bun.$`mkdir -p ${projectPath}`;
17471
- await Bun.$`mkdir -p ${storagePath}`;
17471
+ await mkdir4(projectPath, { recursive: true });
17472
+ await mkdir4(storagePath, { recursive: true });
17472
17473
  await Bun.file(join3(projectPath, BINDING_FILE_NAME)).write(JSON.stringify(binding, null, 2));
17473
17474
  return binding;
17474
17475
  }
@@ -21624,6 +21625,7 @@ async function loadEnvFile(filePath) {
21624
21625
 
21625
21626
  // src/core/config-v2.ts
21626
21627
  import { join as join4 } from "path";
21628
+ import { mkdir as mkdir5, rename as rename3 } from "fs/promises";
21627
21629
  function detectConfigVersion(raw) {
21628
21630
  if (typeof raw === "object" && raw !== null && "version" in raw && raw.version === 2 && "connections" in raw) {
21629
21631
  return 2;
@@ -21667,10 +21669,10 @@ async function writeV2Config(path, config) {
21667
21669
  const storagePath = await resolveConfigStoragePath(path);
21668
21670
  const configPath = join4(storagePath, "config.json");
21669
21671
  const tmpPath = `${configPath}.tmp`;
21670
- await Bun.$`mkdir -p ${storagePath}`;
21672
+ await mkdir5(storagePath, { recursive: true });
21671
21673
  const json = JSON.stringify(config, null, 2);
21672
21674
  await Bun.write(tmpPath, json);
21673
- await Bun.$`mv -f ${tmpPath} ${configPath}`;
21675
+ await rename3(tmpPath, configPath);
21674
21676
  }
21675
21677
  function listConnections(config) {
21676
21678
  return Object.entries(config.connections).map(([name, conn]) => {
@@ -21689,6 +21691,7 @@ function listConnections(config) {
21689
21691
 
21690
21692
  // src/core/config.ts
21691
21693
  import { join as join9 } from "path";
21694
+ import { mkdir as mkdir6 } from "fs/promises";
21692
21695
  var _globalConnectionName;
21693
21696
  function getGlobalConnectionName() {
21694
21697
  return _globalConnectionName;
@@ -21898,7 +21901,7 @@ var configModule = {
21898
21901
  isDirectory = false;
21899
21902
  }
21900
21903
  if (isDirectory || path.endsWith(".dbcli") || path === storagePath && isDirectory) {
21901
- await Bun.$`mkdir -p ${storagePath}`;
21904
+ await mkdir6(storagePath, { recursive: true });
21902
21905
  const hasEnvReferences = isEnvReference(config.connection.password);
21903
21906
  if (hasEnvReferences) {
21904
21907
  const configPath = join9(storagePath, "config.json");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@carllee1983/dbcli",
3
- "version": "1.39.1",
3
+ "version": "1.39.2",
4
4
  "description": "Database CLI for AI agents",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dbcli-agent",
3
- "version": "1.31.0",
3
+ "version": "1.39.2",
4
4
  "description": "Database CLI skill and command reference for AI agents",
5
5
  "author": {
6
6
  "name": "Carl Lee",
@@ -18,7 +18,16 @@ the CLI package has not been installed globally.
18
18
 
19
19
  1. `dbcli blacklist list` — confirm sensitive-data boundaries.
20
20
  2. `dbcli schema <object> --format json` — confirm real column/field names. **Never guess.**
21
- 3. All writes: `--dry-run` (SQL/Mongo) → run → `query` read-back to confirm.
21
+ 3. All writes: `--dry-run` (SQL/Mongo) → run → `query` read-back to confirm. Redis
22
+ `query` has **no `--dry-run`** (see **Redis**); Elasticsearch is **read-only**.
23
+
24
+ **`update` / `delete` `--where` is equality-only (SQL).** It accepts **only** `col=val` or
25
+ `col1=v1 AND col2=v2`. A comparison / pattern operator (`>`, `>=`, `<`, `!=`, `LIKE`, `IN`)
26
+ is a **parse error**; worse, `OR` is **silently swallowed into the value** — `a=1 OR b=2`
27
+ parses as `a = "1 OR b=2"` and matches the wrong rows (or none). For a range or compound
28
+ condition, first `query` / `export` the target rows' primary keys, then run one
29
+ `update` / `delete --where "id=<pk>"` per key — or escalate to a human. (MongoDB `--where`
30
+ takes a full JSON filter and is exempt.)
22
31
 
23
32
  > `report` and `guide` already embed an `inspect` snapshot — you do **not** need to run
24
33
  > `dbcli inspect` first. Run `dbcli inspect --for-agent` manually only when you want the
@@ -364,12 +373,18 @@ without changing the default. `--recovery` is honoured by `query`, `q`, `insert`
364
373
  → `data-admin`. A command not in the whitelist is refused.
365
374
  - **No `--dry-run` for Redis `query`** — write safety comes from the permission gate and key
366
375
  blacklist (matching reads/writes are rejected). To preview a delete, use `delete <key> --dry-run`.
367
- - `database` is the logical DB index (default `0`). `dbcli blacklist add 'secrets:*'`
376
+ - `database` is the logical DB index (default `0`). `dbcli blacklist table add 'secrets:*'`
368
377
  registers a key glob; an optional `redis.mask` block masks values on read. Size guards
369
378
  (SCAN/HGETALL truncation, `--no-limit` to bypass) and masking details: reference.md Redis section.
370
379
 
371
380
  ## Elasticsearch
372
381
 
382
+ **dbcli is read-only against Elasticsearch — `insert` / `update` / `delete` are not supported.**
383
+
384
+ ```bash
385
+ dbcli query '{"query":{"match":{"status":"active"}}}' --collection orders
386
+ ```
387
+
373
388
  - `query` takes a DSL (JSON body) or Lucene query string; `--collection <index>` is required.
374
389
  - **Supported:** `init`, `list` (indices with doc count), `schema [index]` (flattened mapping),
375
390
  `query`, `export` (v1.22), `shell` (v1.22), `status`, `use`, `doctor`. **Not supported:**
@@ -249,6 +249,7 @@ dbcli q @analytics/revenue --param days=30 --format html > report.html
249
249
  - `--dry-run` — print the bound SQL + values without executing
250
250
  - `--use <name>` — pick a v2 named connection
251
251
  - `--recovery` — emit a `RecoveryEnvelope` on failure (see `recover`)
252
+ - `--verify` — run the snippet's verification assertions after execution (only if the snippet defines them)
252
253
 
253
254
  **Permission:** query-only+
254
255
 
@@ -474,9 +475,10 @@ Insert data into a table.
474
475
  dbcli insert users --data '{"name":"Alice","email":"alice@example.com"}'
475
476
  dbcli insert users --data '{"name":"Alice"}' --dry-run
476
477
  dbcli insert users --data '{"name":"Alice"}' --force
478
+ dbcli insert users --data '{"name":"Alice"}' --plan --format json # risk analysis only; no DB connection
477
479
  ```
478
480
 
479
- **Options:** `--data <json>`, `--dry-run`, `--force`
481
+ **Options:** `--data <json>`, `--dry-run`, `--force`, `--plan` (analyze risk without connecting or executing), `--format <text|json>` (`--plan` output), `--recovery`
480
482
  **Permission:** read-write+
481
483
 
482
484
  ### update
@@ -486,11 +488,19 @@ Update existing data.
486
488
  ```bash
487
489
  dbcli update users --where "id=1" --set '{"name":"Bob"}'
488
490
  dbcli update users --where "id=1" --set '{"name":"Bob"}' --dry-run
491
+ dbcli update users --where "id=1" --set '{"name":"Bob"}' --plan --format json # risk analysis only; no DB connection
489
492
  ```
490
493
 
491
- **Options:** `--where <condition>` (required), `--set <json>` (required), `--dry-run`, `--force`
494
+ **Options:** `--where <condition>` (required), `--set <json>` (required), `--dry-run`, `--force`, `--plan` (analyze risk without connecting or executing), `--format <text|json>` (`--plan` output), `--recovery`
492
495
  **Permission:** read-write+
493
496
 
497
+ > **`--where` grammar (SQL `update` / `delete`)** — equality only: `col=val` or
498
+ > `col1=v1 AND col2=v2`. Comparison / pattern operators (`>`, `>=`, `<`, `!=`, `LIKE`, `IN`)
499
+ > raise a parse error, and `OR` is **silently folded into the value** (`a=1 OR b=2` parses as
500
+ > `a = "1 OR b=2"`, matching nothing intended). For ranges or compound predicates, select the
501
+ > target primary keys first, then issue one `update` / `delete --where "id=<pk>"` per key.
502
+ > (MongoDB `--where` accepts a full JSON filter and is exempt.)
503
+
494
504
  ### delete
495
505
 
496
506
  Delete data from a table.
@@ -499,9 +509,10 @@ Delete data from a table.
499
509
  dbcli delete users --where "id=1"
500
510
  dbcli delete users --where "id=1" --dry-run
501
511
  dbcli delete users --where "id=1" --force
512
+ dbcli delete users --where "id=1" --plan --format json # risk analysis only; no DB connection
502
513
  ```
503
514
 
504
- **Options:** `--where <condition>` (required), `--dry-run`, `--force`
515
+ **Options:** `--where <condition>` (required), `--dry-run`, `--force`, `--plan` (analyze risk without connecting or executing), `--format <text|json>` (`--plan` output), `--recovery`
505
516
  **Permission:** data-admin+
506
517
 
507
518
  ### export
@@ -521,7 +532,7 @@ dbcli export orders --format csv --output orders.csv # index name as query
521
532
  dbcli export orders --no-limit --format jsonl # scroll the whole index in batches
522
533
  ```
523
534
 
524
- **Options:** `--format <json|jsonl|csv|html>` (required), `--output <path>`, `--force`, `--recovery`, `--index <name>` (Elasticsearch), `--no-limit` (Elasticsearch full-index scroll)
535
+ **Options:** `--format <json|jsonl|csv|html>` (required), `--output <path>`, `--force`, `--recovery`, `--collection <name>` (MongoDB collection) / `--index <name>` (Elasticsearch index; alias for `--collection`), `--limit <number>` (overrides auto-limit), `--no-limit` (Elasticsearch full-index scroll)
525
536
  **Permission:** query-only+ — SQL, MongoDB, and **(v1.22)** Elasticsearch.
526
537
 
527
538
  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.
@@ -892,6 +903,7 @@ Boundaries:
892
903
  | `--from <path>` | Read the envelope from this file instead of `.dbcli/last-recovery.json`. Accepts raw `RecoveryEnvelope` or `SavedRecoveryEnvelope`. | — |
893
904
  | `--allow-write <tier>` | Open the risk gate. Values: `readonly-cmd` (local-side writes) \| `write-cmd` (database writes). | `none` |
894
905
  | `--no-verify` | Skip the verify step appended after a successful `--apply`. | off (verify runs by default) |
906
+ | `--write-verification-artifact` | After a successful `--apply`, persist a secret-free `VerificationArtifact` JSON under `.dbcli/verification/`. | off |
895
907
  | `--format <format>` | `markdown` \| `json`. | `markdown` for inspect, `json` for `--apply` |
896
908
 
897
909
  #### Plan source resolution
@@ -1650,6 +1662,7 @@ dbcli skill --install codex # install to ~/.codex/skills/dbcli/
1650
1662
  **Options:**
1651
1663
  - `--install <platform>` — `claude` | `gemini` | `antigravity` | `copilot` | `cursor` | `codex` | `windsurf`. Writes `SKILL.md` plus `reference.md` next to it so the agent gets progressive disclosure.
1652
1664
  - `--output <path>` — write `SKILL.md` to a file instead of stdout. Does not install `reference.md`.
1665
+ - `--lang <en|zh-TW>` — source language for the emitted SKILL content (default `en`). It selects `assets/SKILL.md` vs `assets/SKILL.zh-TW.md`; the install/output filename stays `SKILL.md` regardless.
1653
1666
 
1654
1667
  **Notes:**
1655
1668
  - 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.
@@ -1662,6 +1675,21 @@ dbcli skill --install codex # install to ~/.codex/skills/dbcli/
1662
1675
 
1663
1676
  **Permission:** n/a.
1664
1677
 
1678
+ ### skill context
1679
+
1680
+ Emit an AI-friendly snapshot of the connected database's schema and saved-query snippets (blacklist-filtered) so an agent can be primed with the current context.
1681
+
1682
+ ```bash
1683
+ dbcli skill context # XML (default)
1684
+ dbcli skill context --format json
1685
+ dbcli skill context --format markdown
1686
+ ```
1687
+
1688
+ **Options:**
1689
+ - `--format <xml|json|markdown>` — output format (default: `xml`)
1690
+
1691
+ **Permission:** query-only+ — read-only; blacklisted objects are never emitted.
1692
+
1665
1693
  ### skill tasks (Agent Task Packs)
1666
1694
 
1667
1695
  ```bash
@@ -2201,7 +2229,7 @@ Rewrites emit a `REDIS_SIZE_REWRITE` warning; truncations emit `REDIS_SIZE_TRUNC
2201
2229
  Blacklist rules are enforced as **Redis-native key globs** (`*`, `?`, `[abc]`, `[a-z]`):
2202
2230
 
2203
2231
  ```bash
2204
- dbcli blacklist add 'secrets:*' # register a key-glob rule
2232
+ dbcli blacklist table add 'secrets:*' # register a key-glob rule
2205
2233
  dbcli query "GET secrets:api_key" # → BlacklistRejection (exit non-zero)
2206
2234
  dbcli query "MGET safe:k secrets:api" # → rejected (any matching key fails the whole command)
2207
2235
  dbcli query "KEYS secrets:*" # → rejected (pattern overlaps a rule)
@@ -18,7 +18,16 @@ the CLI package has not been installed globally.
18
18
 
19
19
  1. `dbcli blacklist list` — confirm sensitive-data boundaries.
20
20
  2. `dbcli schema <object> --format json` — confirm real column/field names. **Never guess.**
21
- 3. All writes: `--dry-run` (SQL/Mongo) → run → `query` read-back to confirm.
21
+ 3. All writes: `--dry-run` (SQL/Mongo) → run → `query` read-back to confirm. Redis
22
+ `query` has **no `--dry-run`** (see **Redis**); Elasticsearch is **read-only**.
23
+
24
+ **`update` / `delete` `--where` is equality-only (SQL).** It accepts **only** `col=val` or
25
+ `col1=v1 AND col2=v2`. A comparison / pattern operator (`>`, `>=`, `<`, `!=`, `LIKE`, `IN`)
26
+ is a **parse error**; worse, `OR` is **silently swallowed into the value** — `a=1 OR b=2`
27
+ parses as `a = "1 OR b=2"` and matches the wrong rows (or none). For a range or compound
28
+ condition, first `query` / `export` the target rows' primary keys, then run one
29
+ `update` / `delete --where "id=<pk>"` per key — or escalate to a human. (MongoDB `--where`
30
+ takes a full JSON filter and is exempt.)
22
31
 
23
32
  > `report` and `guide` already embed an `inspect` snapshot — you do **not** need to run
24
33
  > `dbcli inspect` first. Run `dbcli inspect --for-agent` manually only when you want the
@@ -364,12 +373,18 @@ without changing the default. `--recovery` is honoured by `query`, `q`, `insert`
364
373
  → `data-admin`. A command not in the whitelist is refused.
365
374
  - **No `--dry-run` for Redis `query`** — write safety comes from the permission gate and key
366
375
  blacklist (matching reads/writes are rejected). To preview a delete, use `delete <key> --dry-run`.
367
- - `database` is the logical DB index (default `0`). `dbcli blacklist add 'secrets:*'`
376
+ - `database` is the logical DB index (default `0`). `dbcli blacklist table add 'secrets:*'`
368
377
  registers a key glob; an optional `redis.mask` block masks values on read. Size guards
369
378
  (SCAN/HGETALL truncation, `--no-limit` to bypass) and masking details: reference.md Redis section.
370
379
 
371
380
  ## Elasticsearch
372
381
 
382
+ **dbcli is read-only against Elasticsearch — `insert` / `update` / `delete` are not supported.**
383
+
384
+ ```bash
385
+ dbcli query '{"query":{"match":{"status":"active"}}}' --collection orders
386
+ ```
387
+
373
388
  - `query` takes a DSL (JSON body) or Lucene query string; `--collection <index>` is required.
374
389
  - **Supported:** `init`, `list` (indices with doc count), `schema [index]` (flattened mapping),
375
390
  `query`, `export` (v1.22), `shell` (v1.22), `status`, `use`, `doctor`. **Not supported:**
@@ -249,6 +249,7 @@ dbcli q @analytics/revenue --param days=30 --format html > report.html
249
249
  - `--dry-run` — print the bound SQL + values without executing
250
250
  - `--use <name>` — pick a v2 named connection
251
251
  - `--recovery` — emit a `RecoveryEnvelope` on failure (see `recover`)
252
+ - `--verify` — run the snippet's verification assertions after execution (only if the snippet defines them)
252
253
 
253
254
  **Permission:** query-only+
254
255
 
@@ -474,9 +475,10 @@ Insert data into a table.
474
475
  dbcli insert users --data '{"name":"Alice","email":"alice@example.com"}'
475
476
  dbcli insert users --data '{"name":"Alice"}' --dry-run
476
477
  dbcli insert users --data '{"name":"Alice"}' --force
478
+ dbcli insert users --data '{"name":"Alice"}' --plan --format json # risk analysis only; no DB connection
477
479
  ```
478
480
 
479
- **Options:** `--data <json>`, `--dry-run`, `--force`
481
+ **Options:** `--data <json>`, `--dry-run`, `--force`, `--plan` (analyze risk without connecting or executing), `--format <text|json>` (`--plan` output), `--recovery`
480
482
  **Permission:** read-write+
481
483
 
482
484
  ### update
@@ -486,11 +488,19 @@ Update existing data.
486
488
  ```bash
487
489
  dbcli update users --where "id=1" --set '{"name":"Bob"}'
488
490
  dbcli update users --where "id=1" --set '{"name":"Bob"}' --dry-run
491
+ dbcli update users --where "id=1" --set '{"name":"Bob"}' --plan --format json # risk analysis only; no DB connection
489
492
  ```
490
493
 
491
- **Options:** `--where <condition>` (required), `--set <json>` (required), `--dry-run`, `--force`
494
+ **Options:** `--where <condition>` (required), `--set <json>` (required), `--dry-run`, `--force`, `--plan` (analyze risk without connecting or executing), `--format <text|json>` (`--plan` output), `--recovery`
492
495
  **Permission:** read-write+
493
496
 
497
+ > **`--where` grammar (SQL `update` / `delete`)** — equality only: `col=val` or
498
+ > `col1=v1 AND col2=v2`. Comparison / pattern operators (`>`, `>=`, `<`, `!=`, `LIKE`, `IN`)
499
+ > raise a parse error, and `OR` is **silently folded into the value** (`a=1 OR b=2` parses as
500
+ > `a = "1 OR b=2"`, matching nothing intended). For ranges or compound predicates, select the
501
+ > target primary keys first, then issue one `update` / `delete --where "id=<pk>"` per key.
502
+ > (MongoDB `--where` accepts a full JSON filter and is exempt.)
503
+
494
504
  ### delete
495
505
 
496
506
  Delete data from a table.
@@ -499,9 +509,10 @@ Delete data from a table.
499
509
  dbcli delete users --where "id=1"
500
510
  dbcli delete users --where "id=1" --dry-run
501
511
  dbcli delete users --where "id=1" --force
512
+ dbcli delete users --where "id=1" --plan --format json # risk analysis only; no DB connection
502
513
  ```
503
514
 
504
- **Options:** `--where <condition>` (required), `--dry-run`, `--force`
515
+ **Options:** `--where <condition>` (required), `--dry-run`, `--force`, `--plan` (analyze risk without connecting or executing), `--format <text|json>` (`--plan` output), `--recovery`
505
516
  **Permission:** data-admin+
506
517
 
507
518
  ### export
@@ -521,7 +532,7 @@ dbcli export orders --format csv --output orders.csv # index name as query
521
532
  dbcli export orders --no-limit --format jsonl # scroll the whole index in batches
522
533
  ```
523
534
 
524
- **Options:** `--format <json|jsonl|csv|html>` (required), `--output <path>`, `--force`, `--recovery`, `--index <name>` (Elasticsearch), `--no-limit` (Elasticsearch full-index scroll)
535
+ **Options:** `--format <json|jsonl|csv|html>` (required), `--output <path>`, `--force`, `--recovery`, `--collection <name>` (MongoDB collection) / `--index <name>` (Elasticsearch index; alias for `--collection`), `--limit <number>` (overrides auto-limit), `--no-limit` (Elasticsearch full-index scroll)
525
536
  **Permission:** query-only+ — SQL, MongoDB, and **(v1.22)** Elasticsearch.
526
537
 
527
538
  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.
@@ -892,6 +903,7 @@ Boundaries:
892
903
  | `--from <path>` | Read the envelope from this file instead of `.dbcli/last-recovery.json`. Accepts raw `RecoveryEnvelope` or `SavedRecoveryEnvelope`. | — |
893
904
  | `--allow-write <tier>` | Open the risk gate. Values: `readonly-cmd` (local-side writes) \| `write-cmd` (database writes). | `none` |
894
905
  | `--no-verify` | Skip the verify step appended after a successful `--apply`. | off (verify runs by default) |
906
+ | `--write-verification-artifact` | After a successful `--apply`, persist a secret-free `VerificationArtifact` JSON under `.dbcli/verification/`. | off |
895
907
  | `--format <format>` | `markdown` \| `json`. | `markdown` for inspect, `json` for `--apply` |
896
908
 
897
909
  #### Plan source resolution
@@ -1650,6 +1662,7 @@ dbcli skill --install codex # install to ~/.codex/skills/dbcli/
1650
1662
  **Options:**
1651
1663
  - `--install <platform>` — `claude` | `gemini` | `antigravity` | `copilot` | `cursor` | `codex` | `windsurf`. Writes `SKILL.md` plus `reference.md` next to it so the agent gets progressive disclosure.
1652
1664
  - `--output <path>` — write `SKILL.md` to a file instead of stdout. Does not install `reference.md`.
1665
+ - `--lang <en|zh-TW>` — source language for the emitted SKILL content (default `en`). It selects `assets/SKILL.md` vs `assets/SKILL.zh-TW.md`; the install/output filename stays `SKILL.md` regardless.
1653
1666
 
1654
1667
  **Notes:**
1655
1668
  - 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.
@@ -1662,6 +1675,21 @@ dbcli skill --install codex # install to ~/.codex/skills/dbcli/
1662
1675
 
1663
1676
  **Permission:** n/a.
1664
1677
 
1678
+ ### skill context
1679
+
1680
+ Emit an AI-friendly snapshot of the connected database's schema and saved-query snippets (blacklist-filtered) so an agent can be primed with the current context.
1681
+
1682
+ ```bash
1683
+ dbcli skill context # XML (default)
1684
+ dbcli skill context --format json
1685
+ dbcli skill context --format markdown
1686
+ ```
1687
+
1688
+ **Options:**
1689
+ - `--format <xml|json|markdown>` — output format (default: `xml`)
1690
+
1691
+ **Permission:** query-only+ — read-only; blacklisted objects are never emitted.
1692
+
1665
1693
  ### skill tasks (Agent Task Packs)
1666
1694
 
1667
1695
  ```bash
@@ -2201,7 +2229,7 @@ Rewrites emit a `REDIS_SIZE_REWRITE` warning; truncations emit `REDIS_SIZE_TRUNC
2201
2229
  Blacklist rules are enforced as **Redis-native key globs** (`*`, `?`, `[abc]`, `[a-z]`):
2202
2230
 
2203
2231
  ```bash
2204
- dbcli blacklist add 'secrets:*' # register a key-glob rule
2232
+ dbcli blacklist table add 'secrets:*' # register a key-glob rule
2205
2233
  dbcli query "GET secrets:api_key" # → BlacklistRejection (exit non-zero)
2206
2234
  dbcli query "MGET safe:k secrets:api" # → rejected (any matching key fails the whole command)
2207
2235
  dbcli query "KEYS secrets:*" # → rejected (pattern overlaps a rule)