@carllee1983/dbcli 1.42.0 → 1.43.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/README.md CHANGED
@@ -149,8 +149,9 @@ dbcli export "SELECT * FROM users" --format html --output report.html
149
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
150
 
151
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.
152
+ - **`visual:` block**: Snippet frontmatter can define KPIs and charts (Line, Bar, Area, Pie) to drive the dashboard.
153
153
  - **Security**: Result sets are redacted by the blacklist before injection, and data is safely escaped for HTML.
154
+ - **Completeness warnings**: Truncation and security metadata are shown before KPIs, charts, and the raw table so incomplete or masked data is never presented as a complete result.
154
155
 
155
156
  ### Recovery & Guided Remediation
156
157
 
@@ -291,7 +292,7 @@ dbcli init --rename staging:production
291
292
 
292
293
  ### Using a Specific Connection Temporarily
293
294
 
294
- You can use the `--use <name>` global flag to execute any command against a specific connection without changing the default.
295
+ You can use the `--use <name>` global flag, the supported command-level form, or `DBCLI_CONNECTION` to execute against a specific connection without changing the default. Selection precedence is explicit `--use`, then `DBCLI_CONNECTION`, then the configured default. A selector is rejected for legacy v1 single-connection configuration instead of being silently ignored.
295
296
 
296
297
  ```bash
297
298
  # Query the production database once
@@ -299,8 +300,21 @@ dbcli query "SELECT count(*) FROM users" --use prod
299
300
 
300
301
  # Check staging table health
301
302
  dbcli check users --use staging
303
+
304
+ # Select one connection for this process
305
+ DBCLI_CONNECTION=prod dbcli query "SELECT count(*) FROM users"
302
306
  ```
303
307
 
308
+ `query`, `schema`, `list`, `export`, and `check` accept the command-level `--use` form shown above. Other commands use the global form before the subcommand.
309
+
310
+ For read-only comparisons, an explicit comma-separated `--use` fans one query out to multiple named connections:
311
+
312
+ ```bash
313
+ dbcli query --use primary,staging "SELECT count(*) FROM users" --format json
314
+ ```
315
+
316
+ SQL fan-out permits `SELECT`, `SHOW`, `DESCRIBE`, and `EXPLAIN`; MongoDB permits filters and read-only pipelines; Elasticsearch permits search. Redis, writes, `--recovery`, `--ui`, CSV, and HTML are rejected. Connections run independently: JSON returns an ordered `results` array, table output labels each section, and one failure does not cancel the others. Exit codes are `0` for all success, `2` for mixed outcomes, and `1` for all failures or a preflight rejection. `DBCLI_CONNECTION` always names one literal connection and never enables fan-out.
317
+
304
318
  ---
305
319
 
306
320
 
@@ -453,24 +467,33 @@ dbcli schema
453
467
 
454
468
  ---
455
469
 
456
- #### `dbcli query "SQL"`
470
+ #### `dbcli query [query]`
457
471
 
458
- Execute SQL query and return results.
472
+ Execute a SQL statement, MongoDB filter/pipeline, allow-listed Redis command, or Elasticsearch DSL/Lucene query and return results.
459
473
 
460
474
  **Usage:**
461
475
  ```bash
462
476
  dbcli query "SELECT * FROM users"
477
+ dbcli query --query-file ./queries/active-users.sql
463
478
  ```
464
479
 
465
480
  **Options:**
466
- - `--format json|table|csv` — Output format (default: table)
481
+ - `--format json|table|csv|html` — Output format (default: table)
482
+ - `--ui` — Render HTML to a temporary file and open it in the system browser
467
483
  - `--limit <number>` — Cap rows (overrides the automatic limit in query-only mode)
468
484
  - `--no-limit` — Disable the automatic 1000-row cap in query-only mode
485
+ - `-f, --query-file <path>` — Read a UTF-8 query from a file; use `-` for piped stdin
486
+ - `--fields <list>` — Include `a,b` or exclude `-a,-b` fields from SQL/MongoDB results
487
+ - `--truncate <number>` — Set the table cell limit in Unicode code points (default: 120)
488
+ - `--no-truncate` — Show complete table cells
469
489
 
470
490
  **Behavior:**
471
491
  - Enforces permission-based restrictions (Query-only mode blocks INSERT/UPDATE/DELETE)
472
- - Auto-limits results to 1000 rows in Query-only mode (notification shown), unless `--no-limit` or `--limit` applies
473
- - Returns structured results with metadata (row count, execution time)
492
+ - Requires exactly one query source: positional text, `--query-file <path>`, or piped stdin through `--query-file -`
493
+ - Auto-limits results to 1000 rows in Query-only mode, unless `--no-limit` or `--limit` applies
494
+ - Uses a one-row lookahead for dbcli-owned limits. Truncated tables say so in the footer, JSON returns `metadata.truncated` and `metadata.limit_applied`, and CSV appends a truncation comment
495
+ - Applies `--fields` after SQL execution and pushes it into MongoDB find/pipeline operations. Blacklist masking remains authoritative
496
+ - Truncates table cells only; JSON and CSV rows remain lossless. Explicit truncation flags with JSON, CSV, HTML, or `--ui` are rejected
474
497
  - To write CSV/JSON to a file, use shell redirection or the `export` command
475
498
 
476
499
  **Examples:**
@@ -489,6 +512,17 @@ dbcli query "SELECT * FROM products" --format json | jq '.data[] | .name'
489
512
 
490
513
  # Large result sets (paginate with LIMIT/OFFSET)
491
514
  dbcli query "SELECT * FROM users LIMIT 100 OFFSET 0"
515
+
516
+ # Multiline SQL from stdin
517
+ dbcli query --query-file - <<'SQL'
518
+ SELECT id, email
519
+ FROM users
520
+ WHERE status = 'active';
521
+ SQL
522
+
523
+ # Include or exclude fields (use = when the value starts with a hyphen)
524
+ dbcli query "SELECT * FROM users" --fields id,email,status
525
+ dbcli query "SELECT * FROM users" --fields=-password_hash,-raw_payload
492
526
  ```
493
527
 
494
528
  ---
@@ -598,9 +632,12 @@ dbcli export "SELECT * FROM users" --format json --output users.json
598
632
  **Options:**
599
633
  - `--format json|csv` — Output format
600
634
  - `--output file` — Write to file (default: stdout for piping)
635
+ - `--limit <number>` — Deliberately accept a bounded export
636
+ - `--no-limit` — Export the complete result
601
637
 
602
638
  **Behavior:**
603
- - Query-only permission limited to 1000 rows per export
639
+ - Query-only mode still applies its automatic 1000-row limit, but reaching it fails closed with exit code `1` and writes no partial file
640
+ - Re-run with `--no-limit` for the complete export or `--limit N` to accept a cap explicitly
604
641
  - Generates RFC 4180 compliant CSV
605
642
  - Creates well-formed JSON arrays
606
643
 
@@ -754,19 +791,24 @@ dbcli check --all --checks nulls,duplicates --format json
754
791
 
755
792
  #### `dbcli diff`
756
793
 
757
- Save a schema snapshot or compare the live database to a previous snapshot (tables, columns, indexes).
794
+ Save a schema snapshot, compare the live database to a previous snapshot, or compare an ORM definition with the local SQL schema cache. ORM drift is cache-only: it does not connect, refresh the cache, or execute proposals.
758
795
 
759
796
  **Usage:**
760
797
  ```bash
761
798
  dbcli diff --snapshot ./schema-before.json
762
799
  dbcli diff --against ./schema-before.json
763
800
  dbcli diff --against ./schema-before.json --format table
801
+ dbcli diff --against-orm prisma/schema.prisma --format json
802
+ dbcli diff --against-orm drizzle/meta/0001_snapshot.json --orm-format drizzle --format table
803
+ dbcli diff --against-orm schema.sql --orm-format typeorm --format table
764
804
  ```
765
805
 
766
806
  **Options:**
767
807
  - `--snapshot <path>` — Write the current schema to a JSON file
768
808
  - `--against <path>` — Diff live schema vs. the saved snapshot
769
- - `--format json|table`Output format (default: `json`)
809
+ - `--against-orm <path>`Compare Prisma, Drizzle snapshot, TypeORM/Sequelize DDL, raw DDL, or normalized JSON with the cached SQL schema
810
+ - `--orm-format prisma|drizzle|typeorm|sequelize|ddl|json` — Override ORM input detection
811
+ - `--format json|table|markdown` — Output format (default: `json`)
770
812
  - `--config <path>` — Config path (default: `.dbcli`)
771
813
 
772
814
  ---
@@ -983,6 +1025,12 @@ dbcli migrate drop-enum status --execute --force
983
1025
 
984
1026
  ## Query Risk Planning
985
1027
 
1028
+ Use `lint` for read-only static advice about SQL anti-patterns and optional rewrite drafts. It accepts inline SQL, saved queries, files, globs, and bulk input; it never connects or applies a rewrite:
1029
+
1030
+ ```bash
1031
+ dbcli lint "SELECT * FROM users WHERE LOWER(email) = 'a@example.com'" --format json
1032
+ ```
1033
+
986
1034
  Use `plan` to inspect SQL safety before execution. It reads local dbcli config, permissions, blacklist rules, and cached schema metadata only; it does not connect to the database.
987
1035
 
988
1036
  ```bash
@@ -1596,6 +1644,20 @@ chmod +x dist/cli.mjs
1596
1644
 
1597
1645
  ## Development
1598
1646
 
1647
+ Package consumers building agent CLIs can import the semver-stable, database-independent interface from `@carllee1983/dbcli/agent-core`:
1648
+
1649
+ ```ts
1650
+ import {
1651
+ loadEnvFile,
1652
+ parseConnectionNames,
1653
+ resolveConnectionSelector,
1654
+ resolveEnvRef,
1655
+ trimAppliedLimit,
1656
+ } from '@carllee1983/dbcli/agent-core'
1657
+ ```
1658
+
1659
+ The broader `@carllee1983/dbcli/core` interface remains dbcli-specific. CLI option factories, config-storage binding, and connection-string parsing are intentionally outside `agent-core`.
1660
+
1599
1661
  ```bash
1600
1662
  bun test # full test suite (Bun test runner)
1601
1663
  bun run typecheck # TypeScript compile-time validation
package/README.zh-TW.md CHANGED
@@ -134,8 +134,9 @@ dbcli export "SELECT * FROM users" --format html --output report.html
134
134
  `dbcli` 可將查詢結果算繪為完全互動、獨立的 HTML 儀表板。這些報表由 React + Recharts 驅動且具備「零依賴」特性 — 整個應用程式與資料皆被內嵌於單一 HTML 檔案中。
135
135
 
136
136
  - **`--ui` 旗標**:自動產生暫時性報表並在預設瀏覽器中開啟。
137
- - **`visual:` 區塊**:可在查詢片段的 frontmatter 中定義 KPI 與圖表 (Line, Bar, Area, Pie, Scatter)。
137
+ - **`visual:` 區塊**:可在查詢片段的 frontmatter 中定義 KPI 與圖表 (Line, Bar, Area, Pie)。
138
138
  - **安全性**:資料在注入前會先經過黑名單過濾,且針對 HTML 進行了安全跳脫處理。
139
+ - **完整性警示**:KPI、圖表與 raw table 之前會先顯示截斷與 security metadata,避免把不完整或已遮蔽的資料誤認為完整結果。
139
140
 
140
141
  ---
141
142
 
@@ -189,14 +190,25 @@ dbcli init --rename staging:production # 更名(格式:舊名:新名)
189
190
 
190
191
  ### 臨時指定連線(不改預設)
191
192
 
192
- 任何子指令皆可加全域 **`--use <名稱>`**,僅本次使用該連線:
193
+ 可使用全域 **`--use <名稱>`**、支援的指令層級寫法或 `DBCLI_CONNECTION`,僅本次使用指定連線而不改預設。選擇優先序為明確的 `--use`、`DBCLI_CONNECTION`、最後才是設定檔預設連線。舊版 v1 單連線設定沒有具名連線可選,因此 selector 會被明確拒絕,不會遭到靜默忽略。
193
194
 
194
195
  ```bash
195
196
  dbcli query "SELECT count(*) FROM users" --use prod
196
197
  dbcli check users --use staging
197
198
  dbcli list --use prod
199
+ DBCLI_CONNECTION=prod dbcli query "SELECT count(*) FROM users"
198
200
  ```
199
201
 
202
+ `query`、`schema`、`list`、`export`、`check` 支援上面的指令層級 `--use`;其他指令請將全域 selector 放在子指令之前。
203
+
204
+ 若要比較多個環境,可透過明確的逗號分隔 `--use`,將同一個唯讀 query 扇出至多個具名連線:
205
+
206
+ ```bash
207
+ dbcli query --use primary,staging "SELECT count(*) FROM users" --format json
208
+ ```
209
+
210
+ SQL fan-out 允許 `SELECT`、`SHOW`、`DESCRIBE`、`EXPLAIN`;MongoDB 允許 filter 與唯讀 pipeline;Elasticsearch 允許 search。Redis、寫入、`--recovery`、`--ui`、CSV 與 HTML 都會被拒絕。各連線獨立執行:JSON 依序回傳 `results` array,table 為每個連線標示區段,單一失敗不會取消其他連線。全部成功 exit `0`、混合結果 exit `2`、全部失敗或 preflight 拒絕 exit `1`。`DBCLI_CONNECTION` 永遠代表單一完整連線名稱,不會啟用 fan-out。
211
+
200
212
  若同時需要自訂設定路徑,可與 **`--config <路徑>`** 併用(仍指向含 `config.json` 的 `.dbcli` 目錄)。
201
213
 
202
214
  ---
@@ -351,24 +363,33 @@ dbcli schema
351
363
 
352
364
  ---
353
365
 
354
- #### `dbcli query "SQL"`
366
+ #### `dbcli query [query]`
355
367
 
356
- 執行 SQL 查詢並回傳結果。
368
+ 執行 SQL statement、MongoDB filter/pipeline、allow-listed Redis command 或 Elasticsearch DSL/Lucene query 並回傳結果。
357
369
 
358
370
  **用法:**
359
371
  ```bash
360
372
  dbcli query "SELECT * FROM users"
373
+ dbcli query --query-file ./queries/active-users.sql
361
374
  ```
362
375
 
363
376
  **選項:**
364
- - `--format json|table|csv` — 輸出格式(預設:table)
377
+ - `--format json|table|csv|html` — 輸出格式(預設:table)
378
+ - `--ui` — 將 HTML 算繪至暫存檔並在系統瀏覽器開啟
365
379
  - `--limit <數字>` — 限制列數(覆寫 query-only 下的自動上限)
366
380
  - `--no-limit` — 在 query-only 模式下關閉自動 1000 列上限
381
+ - `-f, --query-file <路徑>` — 從 UTF-8 檔案讀取 query;以 `-` 讀取 piped stdin
382
+ - `--fields <清單>` — 在 SQL/MongoDB 結果中納入 `a,b` 或排除 `-a,-b` 欄位
383
+ - `--truncate <數字>` — 設定 table cell 的 Unicode code point 上限(預設 120)
384
+ - `--no-truncate` — 顯示完整 table cell
367
385
 
368
386
  **行為:**
369
387
  - 依權限限制操作(Query-only 會阻擋 INSERT/UPDATE/DELETE)
370
- - Query-only 模式預設自動限制最多 1000 列(並顯示提示),除非使用 `--no-limit` `--limit`
371
- - 回傳含中繼資料的結構化結果(列數、執行時間等)
388
+ - 必須且只能指定一種 query 來源:positional 文字、`--query-file <路徑>`,或透過 `--query-file -` 傳入 piped stdin
389
+ - Query-only 模式預設自動限制最多 1000 列,除非使用 `--no-limit` 或 `--limit`
390
+ - dbcli 自己套用上限時會多取一列 lookahead;截斷的 table footer 會明示,JSON 回傳 `metadata.truncated` 與 `metadata.limit_applied`,CSV 則附加截斷註解
391
+ - SQL 執行後套用 `--fields`,MongoDB 則下推至 find/pipeline;blacklist masking 仍是最終權限邊界
392
+ - 只截斷 table cell;JSON 與 CSV rows 維持無損。JSON、CSV、HTML 或 `--ui` 若明確給定截斷旗標會被拒絕
372
393
  - 若要將 CSV/JSON 寫入檔案,請用 shell 重新導向或 `export` 指令
373
394
 
374
395
  **範例:**
@@ -387,6 +408,17 @@ dbcli query "SELECT * FROM products" --format json | jq '.data[] | .name'
387
408
 
388
409
  # 大量結果(以 LIMIT/OFFSET 分頁)
389
410
  dbcli query "SELECT * FROM users LIMIT 100 OFFSET 0"
411
+
412
+ # 從 stdin 傳入多行 SQL
413
+ dbcli query --query-file - <<'SQL'
414
+ SELECT id, email
415
+ FROM users
416
+ WHERE status = 'active';
417
+ SQL
418
+
419
+ # 納入或排除欄位(值以 hyphen 開頭時使用 =)
420
+ dbcli query "SELECT * FROM users" --fields id,email,status
421
+ dbcli query "SELECT * FROM users" --fields=-password_hash,-raw_payload
390
422
  ```
391
423
 
392
424
  ---
@@ -496,9 +528,12 @@ dbcli export "SELECT * FROM users" --format json --output users.json
496
528
  **選項:**
497
529
  - `--format json|csv` — 輸出格式
498
530
  - `--output file` — 寫入檔案(預設 stdout 供管道使用)
531
+ - `--limit <數字>` — 明確接受有界匯出
532
+ - `--no-limit` — 匯出完整結果
499
533
 
500
534
  **行為:**
501
- - Query-only 權限下每次匯出最多 1000
535
+ - Query-only 模式仍會套用自動 1000 列上限,但真的撞到上限時會 fail closed,以 exit code `1` 結束且不寫入不完整檔案
536
+ - 使用 `--no-limit` 匯出完整結果,或用 `--limit N` 明確接受上限
502
537
  - 產生符合 RFC 4180 的 CSV
503
538
  - 產生結構良好的 JSON 陣列
504
539
 
@@ -652,19 +687,24 @@ dbcli check --all --checks nulls,duplicates --format json
652
687
 
653
688
  #### `dbcli diff`
654
689
 
655
- 儲存 schema 快照,或將目前資料庫與先前快照比對(表、欄位、索引)。
690
+ 儲存 schema 快照、將目前資料庫與先前快照比對,或把 ORM 定義與本地 SQL schema cache 比對。ORM drift 只讀 cache:不連線、不更新 cache,也不執行提案。
656
691
 
657
692
  **用法:**
658
693
  ```bash
659
694
  dbcli diff --snapshot ./schema-before.json
660
695
  dbcli diff --against ./schema-before.json
661
696
  dbcli diff --against ./schema-before.json --format table
697
+ dbcli diff --against-orm prisma/schema.prisma --format json
698
+ dbcli diff --against-orm drizzle/meta/0001_snapshot.json --orm-format drizzle --format table
699
+ dbcli diff --against-orm schema.sql --orm-format typeorm --format table
662
700
  ```
663
701
 
664
702
  **選項:**
665
703
  - `--snapshot <path>` — 將目前 schema 寫入 JSON 檔
666
704
  - `--against <path>` — 與已存快照比對差異
667
- - `--format json|table`輸出格式(預設:`json`)
705
+ - `--against-orm <path>`將 Prisma、Drizzle snapshot、TypeORM/Sequelize DDL、raw DDL 或 normalized JSON 與 SQL schema cache 比對
706
+ - `--orm-format prisma|drizzle|typeorm|sequelize|ddl|json` — 覆寫 ORM 輸入格式偵測
707
+ - `--format json|table|markdown` — 輸出格式(預設:`json`)
668
708
  - `--config <path>` — 設定路徑(預設:`.dbcli`)
669
709
 
670
710
  ---
@@ -881,6 +921,12 @@ dbcli migrate drop-enum status --execute --force
881
921
 
882
922
  ## 查詢風險規劃
883
923
 
924
+ 使用 `lint` 對 SQL anti-pattern 與可選 rewrite draft 做唯讀靜態分析。支援 inline SQL、saved query、檔案、glob 與 bulk input;不會連線,也不會套用 rewrite:
925
+
926
+ ```bash
927
+ dbcli lint "SELECT * FROM users WHERE LOWER(email) = 'a@example.com'" --format json
928
+ ```
929
+
884
930
  使用 `plan` 在執行前檢查 SQL 安全性。它只讀取本機 dbcli 設定、權限、黑名單規則與已快取的 schema metadata;不會連線到資料庫。
885
931
 
886
932
  ```bash
@@ -1481,6 +1527,20 @@ chmod +x dist/cli.mjs
1481
1527
 
1482
1528
  ## 開發
1483
1529
 
1530
+ 開發 agent CLI 的套件使用者,可從 `@carllee1983/dbcli/agent-core` 匯入遵循 semver、與資料庫無關的穩定介面:
1531
+
1532
+ ```ts
1533
+ import {
1534
+ loadEnvFile,
1535
+ parseConnectionNames,
1536
+ resolveConnectionSelector,
1537
+ resolveEnvRef,
1538
+ trimAppliedLimit,
1539
+ } from '@carllee1983/dbcli/agent-core'
1540
+ ```
1541
+
1542
+ 較廣的 `@carllee1983/dbcli/core` 仍是 dbcli 專用介面。CLI option factory、config storage binding 與連線字串解析刻意不納入 `agent-core`。
1543
+
1484
1544
  ```bash
1485
1545
  bun test # 完整測試(Bun test runner)
1486
1546
  bun run test:unit # 僅單元與 core 測試
package/assets/SKILL.md CHANGED
@@ -239,8 +239,10 @@ dbcli init --system elasticsearch \
239
239
  dbcli init --conn-name staging --env-file .env.staging --permission query-only
240
240
  dbcli init --conn-name prod --env-file .env.production --use-env-refs --skip-test
241
241
  dbcli use --list # show all, * marks default
242
- dbcli use prod # switch default
242
+ dbcli use prod # switch default (persists — avoid for one-off queries)
243
243
  dbcli query --use staging "SELECT 1" # one-shot override on any subcommand
244
+ DBCLI_CONNECTION=staging dbcli query "SELECT 1" # one-shot via env; parallel-safe
245
+ dbcli --use staging,prod query "SELECT count(*) FROM users" # read-only fan-out
244
246
  dbcli init --rename staging:stg # rename
245
247
  dbcli init --remove stg # remove
246
248
  ```
@@ -296,7 +298,7 @@ Full flags and edge cases: see [reference.md](reference.md) `init` section.
296
298
  | `use` | n/a | Show/switch default named connection (v2 only). |
297
299
  | `list` | query-only+ | Tables (SQL), collections (MongoDB), keys (Redis), or indices (Elasticsearch). |
298
300
  | `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`. |
299
- | `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`. |
301
+ | `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. `--fields` (projection), `--truncate` (cell width), `-f/--query-file` (read query from file or stdin), `--use a,b` (read-only fan-out). Supports `--recovery`. See **Query workflow flags**. |
300
302
  | `explain` | query-only+ | **(v1.23)** Read-only query plan with annotations. SQL only. Single query, `@saved-query`, `@file.sql`, or `--bulk @glob/*`. `--analyze` (EXPLAIN ANALYZE / MariaDB ANALYZE SELECT), `--format markdown\|json\|table`. |
301
303
  | `lint` | n/a | Static SQL anti-pattern advisor (no DB connection). 9 rules incl. schema-aware implicit-cast / NOT IN-nullable checks via the layered `.dbcli/schemas/` cache; global `--use <conn>` selects a named cache. Findings carry rewrite drafts + guarded `explain` verify commands (`--analyze` only for proven read-only SQL) — report-only, never executes. `--format text\|json\|markdown`, `--min-severity`, `--no-schema`, `--bulk`. Supports `--recovery`. |
302
304
  | `plan` | n/a | Static SQL risk analyzer (`--format text\|json`); classifies a statement without connecting to the database. |
@@ -304,7 +306,7 @@ Full flags and edge cases: see [reference.md](reference.md) `init` section.
304
306
  | `queries` | n/a | Manage saved snippets: `list` / `show` / `search` / `suggest` / `new` / `edit` / `check` / `delete` / `rename` / `copy` / `import` / `export`. |
305
307
  | `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`. |
306
308
  | `delete` | data-admin+ | SQL or MongoDB; Redis has a basic implementation (see Redis section). `--where` required; `--dry-run` first. Supports `--recovery`. |
307
- | `export` | query-only+ | SQL, MongoDB, or **(v1.22)** Elasticsearch (DSL `--index` or whole-index scroll). Query → `--format json\|jsonl\|csv\|html` file or stdout. `html` emits a standalone interactive dashboard. Supports `--recovery`. |
309
+ | `export` | query-only+ | SQL, MongoDB, or **(v1.22)** Elasticsearch (DSL `--index` or whole-index scroll). Query → `--format json\|jsonl\|csv\|html` file or stdout. `html` emits a standalone interactive dashboard. **Fails closed rather than truncating silently**: if the auto-limit would drop rows, the export errors out and you must pass `--no-limit` or `--limit N`. Supports `--recovery`. |
308
310
  | `blacklist` | n/a | `list` / `table` / `column` subcommands redact sensitive data from query results. |
309
311
  | `check` | query-only+ | SQL only (best on MySQL/MariaDB). |
310
312
  | `diff` | query-only+ | SQL only. Save/compare schema snapshots. **(P1b)** `--against-orm <path>` compares a Prisma schema / DDL file / normalized JSON against the local schema cache (no DB connection): categorized drift (`missing_in_db` = error, `missing_in_orm` = warn, `mismatch` per tolerance table, `unmanaged`) with dry-run `migrate` proposals; exit 1 on error-level drift. `--orm-format prisma\|ddl\|json\|drizzle\|typeorm\|sequelize`, `--ignore <globs>`, `--format json\|table\|markdown`. Drizzle: point at `drizzle/meta/<NNNN>_snapshot.json` (run `drizzle-kit generate` first; `.ts` sources are rejected with a hint). TypeORM/Sequelize: feed tool-generated DDL (`schema:log` / a schema-only dump); source files are rejected with the exact generation command to run. |
@@ -325,8 +327,9 @@ Full flags and edge cases: see [reference.md](reference.md) `init` section.
325
327
  | `skill` | n/a | Generate / install AI skill docs (`--install <claude\|gemini\|antigravity\|copilot\|cursor\|codex\|windsurf>`); `skill tasks list/show/plan` for Agent Task Packs; `skill context` for an LLM prompt-context payload (for injecting into another LLM, not needed for normal operation). |
326
328
  | `migrate` | admin | SQL only. **DDL; dry-run by default** — needs `--execute`. |
327
329
 
328
- `--use <name>` on any subcommand (including `status` / `doctor`) targets a v2 connection
329
- without changing the default. `--recovery` is honoured by `query`, `q`, `insert`, `update`,
330
+ Use root-level `dbcli --use <name> <command>` for any command; `query`, `schema`, `list`,
331
+ `export`, and `check` also accept command-level `--use`. Both target a v2 connection without
332
+ changing the default. `--recovery` is honoured by `query`, `q`, `insert`, `update`,
330
333
  `delete`, `export`, `schema`, `inspect`, `lint`, and `diff --against-orm` (see **On failure** above).
331
334
 
332
335
  **Write & query flag semantics** (SQL/Mongo `insert`/`update`):
@@ -344,6 +347,27 @@ without changing the default. `--recovery` is honoured by `query`, `q`, `insert`
344
347
  - `--recovery` is recommended for automated agent pipelines (enables `dbcli recover --apply`
345
348
  after a failure); optional for one-off manual writes.
346
349
 
350
+ ## Query workflow flags
351
+
352
+ These exist so you do not have to pipe output through `head` / `jq` / `python3`
353
+ to make it usable. Reach for them instead of post-processing.
354
+
355
+ | Need | Flag | Notes |
356
+ |------|------|-------|
357
+ | Only some columns | `--fields sn,bet,created_at` | SQL and MongoDB. Mongo pushes a real `projection` / `$project` to the driver; `_id` is dropped unless you ask for it. A field the result lacks comes back as `null`, so verify spellings with `schema` before reading meaning into an all-null column. |
358
+ | Everything except a huge column | `--fields=-raw_response` | Exclusion form. Include and exclude cannot be mixed. |
359
+ | One field is a giant JSON blob | `--truncate 120` | Table output truncates cells at 120 chars **by default** and marks them `…(+3412 chars)`. `--no-truncate` disables it. Explicit truncation flags are rejected on JSON, CSV, HTML, and `--ui` output. |
360
+ | Query has quotes / newlines / `$regex` | `-f pipeline.json` or `-f -` | Reads the query from a file or stdin; use a heredoc for Mongo pipelines. Passing both a file and positional query text is an error, never a silent pick. `-f -` needs piped input — it refuses an interactive terminal rather than hanging. |
361
+ | Same query across connections | `--use hub-prod,site-a` | Read-only fan-out. Per-connection results, one failure does not cancel the others. Exit `0` all-ok, `2` mixed, `1` all-failed. Rejects writes, `--recovery`, `--ui`, CSV/HTML. |
362
+ | Pick a connection for one call | `DBCLI_CONNECTION=hub-prod dbcli query …` | Env var, or `--use` on the subcommand. Priority: `--use` > `DBCLI_CONNECTION` > saved default. Neither writes the default back to disk, so parallel shells never fight. Requires a v2 config — a single-connection (v1) project rejects both rather than silently running its only connection. **Do not** use `dbcli use <name>` just to switch for one query. |
363
+
364
+ **Truncation is reported, never implied.** When the query-only auto-limit trims a
365
+ result, the table footer reads `Rows: 1000 (truncated; limit 1000)`, `--format json`
366
+ carries `metadata.truncated` / `metadata.limit_applied`, and CSV appends a `#`
367
+ comment. `Rows: 1000` with no marker means exactly 1000 rows exist — do not infer
368
+ truncation from a round number. This applies to `query` and to `q` snippets
369
+ (whose own 1000-row guard reports the same way). `export` refuses to truncate at all. Redis replies trimmed by the size guard report the same way, and each size-guard warning is printed on stderr.
370
+
347
371
  ## Permission levels
348
372
 
349
373
  | Level | Allowed |
@@ -192,8 +192,10 @@ dbcli init --system elasticsearch \
192
192
  dbcli init --conn-name staging --env-file .env.staging --permission query-only
193
193
  dbcli init --conn-name prod --env-file .env.production --use-env-refs --skip-test
194
194
  dbcli use --list # show all, * marks default
195
- dbcli use prod # switch default
195
+ dbcli use prod # switch default(會持久化 — 單次查詢別用)
196
196
  dbcli query --use staging "SELECT 1" # one-shot override on any subcommand
197
+ DBCLI_CONNECTION=staging dbcli query "SELECT 1" # 單次指定,env 版;平行安全
198
+ dbcli --use staging,prod query "SELECT count(*) FROM users" # 唯讀扇出
197
199
  dbcli init --rename staging:stg # rename
198
200
  dbcli init --remove stg # remove
199
201
  ```
@@ -234,7 +236,7 @@ dbcli init --conn-name prod --env-file .env.production --use-env-refs --skip-tes
234
236
  | `use` | n/a | 顯示 / 切換預設命名連線(僅 v2)。 |
235
237
  | `list` | query-only+ | 資料表(SQL)、collections(MongoDB)、keys(Redis)或 indices(Elasticsearch)。 |
236
238
  | `schema` | query-only+ | SQL:單表或全掃描存入 `.dbcli/schemas/`。MongoDB:sampled。ES:flattened mapping。Redis:僅單一 key(type / TTL / size)。支援 `--recovery`。 |
237
- | `query` | query-only+ | SQL、Mongo JSON(`--collection`)、Redis 指令、ES DSL / Lucene(`--collection`)。`--format table\|json\|csv\|html`、`--ui` 開啟瀏覽器互動式 dashboard。支援 `--recovery`。 |
239
+ | `query` | query-only+ | SQL、Mongo JSON(`--collection`)、Redis 指令、ES DSL / Lucene(`--collection`)。`--format table\|json\|csv\|html`、`--ui` 開啟瀏覽器互動式 dashboard。`--fields`(欄位投影)、`--truncate`(欄位值寬度)、`-f/--query-file`(從檔案或 stdin 讀查詢)、`--use a,b`(唯讀扇出)。支援 `--recovery`。見 **查詢工作流程旗標**。 |
238
240
  | `explain` | query-only+ | **(v1.23)** 唯讀查詢計畫並附註解。僅 SQL。單一查詢、`@saved-query`、`@file.sql` 或 `--bulk @glob/*`。`--analyze`(EXPLAIN ANALYZE / MariaDB ANALYZE SELECT)、`--format markdown\|json\|table`。 |
239
241
  | `lint` | n/a | 靜態 SQL 反模式顧問(不連線 DB)。共 9 條規則,包含透過分層 `.dbcli/schemas/` 快取進行的 schema-aware implicit-cast / NOT IN-nullable 檢查;全域 `--use <conn>` 會選擇命名連線的快取。Finding 可附 rewrite 草稿與受保護的 `explain` 驗證指令;只有已證明唯讀的 SQL 才會加上 `--analyze`,且只回報、絕不執行。`--format text\|json\|markdown`、`--min-severity`、`--no-schema`、`--bulk`。支援 `--recovery`。 |
240
242
  | `plan` | n/a | 靜態 SQL 風險分析器(`--format text\|json`);不連線即可分類語句。 |
@@ -242,7 +244,7 @@ dbcli init --conn-name prod --env-file .env.production --use-env-refs --skip-tes
242
244
  | `queries` | n/a | 管理已儲存 snippet:`list` / `show` / `search` / `suggest` / `new` / `edit` / `check` / `delete` / `rename` / `copy` / `import` / `export`。 |
243
245
  | `insert` / `update` | read-write+ | 僅 SQL 與 MongoDB。JSON `--data` / `--set`;`update` 必填 `--where`;先 `--dry-run`。Redis 寫入透過 `query`。支援 `--recovery`。 |
244
246
  | `delete` | data-admin+ | 僅 SQL 與 MongoDB;Redis 有基本實作(見 Redis 段落)。必填 `--where`;先 `--dry-run`。支援 `--recovery`。 |
245
- | `export` | query-only+ | SQL、MongoDB 或 **(v1.22)** Elasticsearch(DSL `--index` 或全 index scroll)。Query → `--format json\|jsonl\|csv\|html` 檔案或 stdout。`html` 輸出獨立可互動 dashboard。支援 `--recovery`。 |
247
+ | `export` | query-only+ | SQL、MongoDB 或 **(v1.22)** Elasticsearch(DSL `--index` 或全 index scroll)。Query → `--format json\|jsonl\|csv\|html` 檔案或 stdout。`html` 輸出獨立可互動 dashboard。**寧可失敗也不靜默截斷**:若 auto-limit 會砍掉資料列,匯出直接報錯,必須改用 `--no-limit` 或 `--limit N`。支援 `--recovery`。 |
246
248
  | `blacklist` | n/a | `list` / `table` / `column` 子指令,從查詢結果中遮蔽敏感資料。 |
247
249
  | `check` | query-only+ | 僅 SQL(在 MySQL / MariaDB 最佳)。 |
248
250
  | `diff` | query-only+ | 僅 SQL。儲存 / 比較 schema snapshot。**(P1b)** `--against-orm <path>` 會將 Prisma schema / DDL 檔 / normalized JSON 與本地 schema cache 比對(不連線 DB):分類為 `missing_in_db`(error)、`missing_in_orm`(warn)、依 tolerance 表判定的 `mismatch`、以及 `unmanaged`,並提供 dry-run `migrate` 提案;出現 error-level drift 時 exit 1。`--orm-format prisma\|ddl\|json\|drizzle\|typeorm\|sequelize`、`--ignore <globs>`、`--format json\|table\|markdown`。Drizzle:請指向 `drizzle/meta/<NNNN>_snapshot.json`(先執行 `drizzle-kit generate`;`.ts` source 會被拒絕並顯示提示)。TypeORM/Sequelize:傳入工具產生的 DDL(`schema:log` / schema-only dump);source file 會被拒絕,並顯示要執行的精確產生指令。 |
@@ -263,7 +265,7 @@ dbcli init --conn-name prod --env-file .env.production --use-env-refs --skip-tes
263
265
  | `skill` | n/a | 產出 / 安裝 AI skill 文件(`--install <claude\|gemini\|antigravity\|copilot\|cursor\|codex\|windsurf>`);`skill tasks list/show/plan` 提供 Agent Task Packs;`skill context` 提供 LLM 提示詞脈絡載荷(用於注入其他 LLM,正常操作不需要)。 |
264
266
  | `migrate` | admin | 僅 SQL。**DDL;預設 dry-run** — 需 `--execute`。 |
265
267
 
266
- 任何子指令上的 `--use <name>` 可在不改變預設值的情況下,把目標切到 v2 連線。`--recovery` 被 `query`、`q`、`insert`、`update`、`delete`、`export`、`schema`、`inspect`、`lint` 與 `diff --against-orm` 支援(見上方**失敗時**)。
268
+ 任何指令都可使用 root 層級的 `dbcli --use <name> <command>`;`query`、`schema`、`list`、`export`、`check` 也接受指令層級的 `--use`。兩種寫法都只把本次目標切到 v2 連線,不改變預設值。`--recovery` 被 `query`、`q`、`insert`、`update`、`delete`、`export`、`schema`、`inspect`、`lint` 與 `diff --against-orm` 支援(見上方**失敗時**)。
267
269
 
268
270
  **寫入與查詢旗標語意**(SQL / Mongo `insert`/`update`):
269
271
 
@@ -272,6 +274,27 @@ dbcli init --conn-name prod --env-file .env.production --use-env-refs --skip-tes
272
274
  - `--dry-run` 輸出參數化 SQL(使用 `$1` / `?` 佔位符,非真實值)與 `rows_affected: 0`;確認 `status:"success"` 且 SQL 形狀符合預期的 `--where` / `--set` 後再執行。MongoDB 輸出 shell 風格預覽。
273
275
  - `--recovery` 建議用於自動化 agent pipeline(讓失敗後可執行 `dbcli recover --apply`);手動一次性寫入可選用。
274
276
 
277
+ ## 查詢工作流程旗標 (Query workflow flags)
278
+
279
+ 這些旗標的存在,就是為了讓你不必再把輸出 pipe 給 `head` / `jq` / `python3`
280
+ 才能用。優先用它們,不要事後加工。
281
+
282
+ | 需求 | 旗標 | 說明 |
283
+ |------|------|------|
284
+ | 只要某幾個欄位 | `--fields sn,bet,created_at` | SQL 與 MongoDB 皆可。Mongo 會把真正的 `projection` / `$project` 下推給 driver;除非明確指定,否則不回傳 `_id`。結果中不存在的欄位會回傳 `null`,所以看到整欄 null 時先用 `schema` 核對欄位名。 |
285
+ | 除了某個巨大欄位以外都要 | `--fields=-raw_response` | 排除形式。include 與 exclude 不能混用。 |
286
+ | 某欄位是一大包 JSON | `--truncate 120` | table 輸出**預設**就在 120 字截斷,並標記 `…(+3412 chars)`。`--no-truncate` 可關閉。JSON、CSV、HTML 與 `--ui` 輸出會拒絕明確的截斷旗標。 |
287
+ | 查詢含引號 / 換行 / `$regex` | `-f pipeline.json` 或 `-f -` | 從檔案或 stdin 讀查詢;Mongo pipeline 建議用 heredoc。同時給檔案與位置參數會直接報錯,不會靜默擇一。`-f -` 需要 piped input——遇到互動式終端會直接拒絕而不是空等。 |
288
+ | 同一查詢跨多個連線 | `--use hub-prod,site-a` | 唯讀扇出。各連線各自出結果,其中一個失敗不會取消其他。exit `0` 全成功、`2` 部分失敗、`1` 全失敗。拒絕寫入、`--recovery`、`--ui`、CSV/HTML。 |
289
+ | 單次指定連線 | `DBCLI_CONNECTION=hub-prod dbcli query …` | 環境變數,或在子指令上加 `--use`。優先序:`--use` > `DBCLI_CONNECTION` > 已存的預設值。兩者都不會把預設值寫回磁碟,所以平行的 shell 不會互相干擾。需要 v2 設定——單一連線 (v1) 專案會直接拒絕,而不是靜默改跑那唯一的連線。**不要**為了單次查詢去跑 `dbcli use <name>`。 |
290
+
291
+ **截斷一律明說,絕不靠推測。** query-only 的 auto-limit 砍掉結果時,table footer
292
+ 會顯示 `Rows: 1000 (truncated; limit 1000)`,`--format json` 會帶
293
+ `metadata.truncated` / `metadata.limit_applied`,CSV 則附加 `#` 註解行。
294
+ `Rows: 1000` 沒有標記就代表資料**剛好**是 1000 筆——不要因為數字是整數就推論它被截斷。
295
+ `query` 與 `q` snippet(其自身的 1000 筆 guard 也用同樣方式回報)皆適用。
296
+ `export` 則是根本拒絕截斷。Redis 被 size guard 裁切的回覆同樣依此回報,每則 size-guard warning 也會印到 stderr。
297
+
275
298
  ## 權限等級 (Permission levels)
276
299
 
277
300
  | Level | Allowed |
@@ -112,7 +112,7 @@ dbcli schema --use prod # Scan prod DB; saves to .dbcli/schemas/prod
112
112
 
113
113
  ### query
114
114
 
115
- Execute SQL query (MySQL/PostgreSQL/MariaDB) or JSON filter/pipeline (MongoDB).
115
+ Execute a SQL statement, MongoDB filter/pipeline, allow-listed Redis command, or Elasticsearch DSL/Lucene query.
116
116
 
117
117
  ```bash
118
118
  # SQL databases
@@ -143,13 +143,84 @@ dbcli query "SELECT day, dau FROM dau_daily" --ui # open in brows
143
143
  dbcli query "SELECT * FROM orders" --format html > orders.html # pipe to stdout
144
144
  ```
145
145
 
146
- **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`
146
+ **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`
147
147
  **Permission:** query-only+ (Redis: per-command; Elasticsearch: per HTTP method/path)
148
148
 
149
+ #### Field projection (`--fields`)
150
+
151
+ ```bash
152
+ dbcli query "SELECT * FROM bet_log" --fields sn,currency,bet
153
+ dbcli query "SELECT * FROM bet_log" --fields=-raw_response,-created_at # exclusion
154
+ dbcli query '{"station_code":"cmg9998"}' --collection raw_bet_log --fields sn,bet
155
+ ```
156
+
157
+ Include and exclude forms cannot be mixed. Dotted paths (`user.email`) are supported.
158
+ On MongoDB the selection becomes a driver-level `projection` (find) or a trailing
159
+ `$project` stage (aggregate), so the omitted fields never leave the server; `_id` is
160
+ excluded unless listed explicitly. On SQL the rows are projected after fetch — write
161
+ an explicit column list in the `SELECT` when you also want to cut transfer cost.
162
+ Blacklisted columns stay blacklisted: naming one in `--fields` yields no value and the
163
+ result still carries the blacklist `securityNotification`. A requested field that does
164
+ not exist in the result comes back as `null`.
165
+
166
+ #### Cell truncation (`--truncate`)
167
+
168
+ ```bash
169
+ dbcli query "SELECT sn, raw_response FROM bet_log" # table: 120-char default
170
+ dbcli query "SELECT sn, raw_response FROM bet_log" --truncate 40
171
+ dbcli query "SELECT sn, raw_response FROM bet_log" --no-truncate
172
+ ```
173
+
174
+ Table output truncates each serialized cell at 120 Unicode code points by default and
175
+ appends `…(+N chars)`; counting by code point keeps multi-byte characters and emoji
176
+ intact. `--truncate <n>` sets the width, `--no-truncate` disables it. Explicit truncation
177
+ flags are rejected with JSON, CSV, HTML, and `--ui` output.
178
+
179
+ #### Query from a file or stdin (`-f`)
180
+
181
+ ```bash
182
+ dbcli query -f report.sql
183
+ dbcli query --collection raw_bet_log -f - <<'EOF'
184
+ [{"$match": {"sn": {"$regex": "^SN0000"}}}, {"$group": {"_id": "$currency", "n": {"$sum": 1}}}]
185
+ EOF
186
+ ```
187
+
188
+ Avoids shell quoting entirely — the usual reason a Mongo pipeline containing `$regex`
189
+ or nested date objects fails. Supplying both `--query-file` and positional query text
190
+ is an error rather than a silent choice, and an empty file or empty stdin is refused.
191
+ `-f -` requires piped input: on an interactive terminal dbcli refuses immediately
192
+ instead of waiting silently for input that is never coming.
193
+
194
+ #### One-shot connection selection and read-only fan-out
195
+
196
+ Selection precedence is explicit `--use`, then `DBCLI_CONNECTION`, then the saved default.
197
+ `query`, `schema`, `list`, `export`, and `check` accept command-level `--use`; for other
198
+ commands use root-level `dbcli --use <name> <command>`. One-shot selectors never update the
199
+ saved default and require a v2 config. A legacy v1 single-connection config rejects them
200
+ instead of silently running its only connection.
201
+
202
+ An explicit comma-separated `--use primary,staging` fans one query out to several named
203
+ connections. `DBCLI_CONNECTION` always names one literal connection and never enables
204
+ fan-out. SQL permits `SELECT`, `SHOW`, `DESCRIBE`, and `EXPLAIN`; MongoDB permits filters and
205
+ read-only pipelines without top-level `$out` / `$merge`; Elasticsearch permits searches.
206
+ Redis, writes, `--recovery`, `--ui`, CSV, and HTML are rejected before execution. Each
207
+ connection keeps its own blacklist, limit metadata, audit entry, and error. Aggregate exit
208
+ codes are `0` when all succeed, `2` for mixed outcomes, and `1` when all fail or preflight
209
+ rejects the request.
210
+
211
+ #### Truncation is stated, not implied
212
+
213
+ When the query-only auto-limit trims the result, the table footer reads
214
+ `Rows: 1000 (truncated; limit 1000)`, `--format json` carries
215
+ `metadata.truncated` and `metadata.limit_applied`, and CSV appends a `#` comment line.
216
+ dbcli fetches one row past the cap to decide this, so a result of exactly 1000 rows is
217
+ reported as `truncated: false` — never infer truncation from a round row count.
218
+
149
219
  > **MongoDB notes:**
150
220
  > - SQL syntax is rejected — use JSON object (filter) or JSON array (pipeline)
151
221
  > - `--collection <name>` is required
152
- > - Auto-limit does not apply; use `$limit` in your pipeline if needed
222
+ > - Query-only auto-limit applies to filters and to pipelines without their own
223
+ > `$limit`; the applied cap and truncation are reported in the result metadata
153
224
 
154
225
  > **Redis notes:**
155
226
  > - The first token must be an allow-listed command (`GET`/`SET`/`HGET`/`HSET`/`DEL`/...). Unknown commands are refused.
@@ -661,9 +732,13 @@ dbcli export orders --no-limit --format jsonl # scroll the whole ind
661
732
  **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)
662
733
  **Permission:** query-only+ — SQL, MongoDB, and **(v1.22)** Elasticsearch.
663
734
 
735
+ If the query-only auto-limit would omit rows, export fails closed with exit code `1` and
736
+ writes no partial file. Re-run with `--no-limit` to export everything, or `--limit N` to
737
+ accept a bounded export explicitly. This applies to SQL, MongoDB, and Elasticsearch.
738
+
664
739
  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.
665
740
 
666
- > **Elasticsearch export (v1.22):** pass a search DSL with `--index <index>` to export the hits, or pass an index name as the query to scroll the whole index via `match_all`. Default cap is 1000 rows; `--no-limit` streams the full index via scroll in batches. Index-level blacklist is checked before export and an audit record is written.
741
+ > **Elasticsearch export (v1.22):** pass a search DSL with `--index <index>` to export the hits, or pass an index name as the query to scroll the whole index via `match_all`. Default cap is 1000 rows; reaching it fails closed unless the caller explicitly uses `--limit N`, while `--no-limit` streams the full index via scroll in batches. Index-level blacklist is checked before export and an audit record is written.
667
742
 
668
743
  ### blacklist
669
744