@carllee1983/dbcli 1.20.2 → 1.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,126 @@ All notable changes to dbcli are documented here.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [Unreleased]
9
+
10
+ ## [1.25.0] - 2026-05-29 - Data-Layer Verification
11
+
12
+ ### Added
13
+
14
+ - **`dbcli snapshot <query>` — 結果指紋。** 將任一查詢結果轉成確定性、黑名單安全的 `ResultSnapshot`(`rowCount` + 每欄聚合:null/distinct 計數、min/max/sum、順序無關的 checksum)。預設落檔至 `.dbcli/snapshots/snap-<timestamp>.json`,亦支援 `--out`、`--stdout`、`--rows`(連同遮罩後的列一併存檔)、`--format`、`--no-limit`。
15
+ - **`dbcli assert <query>` — 行內不變量檢查。** 三種模式:`--expect`(`rows > 0`、`value == 5000`、`col:email not null`、`col:id unique`、`col:amount between 0 and 100`、`col:age >= 18`)、`--vs <query> --compare rows|value`(跨查詢對帳)、`--against <snapshot> --tolerance <pct>`(對既有快照基準比對)。預設失敗時 `exit 1`,可用 `--no-fail` 僅報告不改變 exit code。
16
+ - 兩個指令均沿用既有 adapter / QueryExecutor / blacklist / audit 堆疊,黑名單欄位由 QueryExecutor 在源頭遮罩,指紋天生安全。目前支援 SQL 引擎(PostgreSQL / MySQL / MariaDB)。
17
+
18
+ ## [1.24.0] - 2026-05-29 - Antigravity CLI Skill Target
19
+
20
+ ### Added
21
+
22
+ - **`dbcli skill --install antigravity` 新增 Antigravity CLI 安裝目標。** Antigravity CLI 是 Google Gemini CLI 的後繼者;skill 會寫入 CLI 範疇的全域路徑 `~/.gemini/antigravity-cli/skills/dbcli/SKILL.md`(同目錄附帶 `reference.md`)。`SUPPORTED_PLATFORMS` 一併納入 `antigravity`,故 `dbcli upgrade` 的 skill 過期檢查也會涵蓋此平台。
23
+
24
+ ### Changed
25
+
26
+ - `gemini`(Gemini CLI)安裝目標暫予保留,但已標示為即將淘汰,建議改用 `antigravity`。README(en/zh-TW)、`assets/SKILL.md`、`assets/SKILL.zh-TW.md`、`assets/reference.md` 與 `docs/user` 的平台清單同步更新。
27
+
28
+ ## [1.23.1] - 2026-05-29 - Skill Docs Sync
29
+
30
+ ### Changed
31
+
32
+ - 補齊 `assets/SKILL.md` 與 `assets/reference.md`,涵蓋 v1.22(Redis `redis.mask` 遮罩、Elasticsearch export/shell)與 v1.23(`explain`、`guide missing-index-for`、`inspect` 情境感知 `suggestedCommands` + `hints`、內建 task pack `analyze-table-perf`)的指令與旗標說明,使 `dbcli skill --install` 產出的文件與實際行為一致
33
+
34
+ ## [1.23.0] - 2026-05-29 - Source-Driven Performance Review Tooling
35
+
36
+ ### Added
37
+
38
+ - **`dbcli explain` 一級指令。** 把 `EXPLAIN` / `ANALYZE SELECT` / `EXPLAIN (ANALYZE, BUFFERS) SELECT` 包成統一介面,單條 query、`@saved-query`、`@file.sql`、`@glob/*` 通吃。輸出統一的 `ExplainRow` schema,附 5 條 actionable annotations(`full-scan` / `temp-table` / `filesort` / `cost-estimate-skew` / `nested-loop-large`)。輸出格式 markdown(預設)/ json / table。支援 `--bulk` 多筆批次。MariaDB + MySQL + PostgreSQL。(v1.23 P2)
39
+ - **`dbcli guide missing-index-for` 單條 query 複合索引顧問。** 解析一條 `SELECT`,結合真實 `EXPLAIN` 計畫與既有索引,輸出帶 `confidence`(high/medium/low)與 `reason` 的索引候選;偵測既有索引碰撞(single-col 可擴成 composite),並把函式/運算式欄位與無法解析的 SQL 列為 `warnings`。輸出格式 yaml(預設)/ json / markdown,支援 `--min-confidence` 過濾。唯讀(僅 EXPLAIN + 索引內省)。(v1.23 P3)
40
+ - **`dbcli inspect` 情境感知 `suggestedCommands` 與新的 `hints` 欄位。** `suggestedCommands` 改為三層加權(bootstrap / context-aware / discovery):collector 讀近 10 條 audit 找出最熱門資料表,有 task pack 時自動建議 `skill tasks plan analyze-table-perf --param table=<table>` 與 `skill tasks list`。新增與 `suggestedCommands` 平行的 `hints` 欄位(JSON 機器可讀 + markdown `## Hints`),提示最熱門資料表、可用 task pack 數量與 schema 快取概況。新增內建 task pack `analyze-table-perf`(唯讀 `plan-only`,吃必填 `table` 參數)。audit 讀取唯讀且永不 throw。(v1.23 P4)
41
+
42
+ ### Fixed
43
+
44
+ - query-only 模式不再對 `SHOW`/`DESCRIBE`/`EXPLAIN`/`ANALYZE SELECT` 注入 `LIMIT`,避免 server 拒絕(v1.23 P1, issue #1)
45
+ - MariaDB `ANALYZE SELECT` 與 PostgreSQL `EXPLAIN (ANALYZE, BUFFERS) SELECT` 視為 read-only,query-only 模式可執行(v1.23 P1, issue #2)
46
+ - driver 在 execute 階段丟出的 SQL 錯誤(語法錯、table 不存在、column 不存在)不再被誤包成 `Connection failed`;訊息附 actionable hints 與 fuzzy table 候選(v1.23 P1, issue #3)
47
+ - `dbcli schema --refresh` 首次 bootstrap 不再要求 `--force`(v1.23 P1, issue #7)
48
+ - query-only 模式拒絕未知 SQL 時的訊息明確化:加入當前 permission level 與 issue 連結
49
+
50
+ ### Changed
51
+
52
+ - `ConnectionError.code` union 新增 `SQL_SYNTAX_ERROR` / `TABLE_NOT_FOUND` / `COLUMN_NOT_FOUND`(向後相容;既有 consumer 只匹配 `UNKNOWN` 仍 fallback)
53
+
54
+ ## [1.22.0] - 2026-05-21 - Elasticsearch Shell/Export + Redis Masking
55
+
56
+ ### Added
57
+
58
+ - **Elasticsearch interactive shell.** `dbcli shell` 對 ES 連線開啟 Kibana Dev Tools 風格 REPL:輸入請求行 `<METHOD> /<path>` 加上可選的多行 JSON body,以空白行送出整個區塊,回應以美化 JSON 呈現。以讀取為主 — index 層級黑名單於前端直接拒絕受保護 index;`_search` 若 body 未指定 `size` 自動上限 1000 筆。(P1)
59
+ - **Elasticsearch export.** `dbcli export` 對 ES 連線支援兩種形式:傳入 search DSL 並以 `--index` 指定索引以匯出命中結果,或直接以 index 名稱當作查詢、透過 `match_all` + scroll 匯出整個索引。輸出 JSON / JSONL / CSV,預設上限 1000 筆(`--no-limit` 匯出全索引,以 scroll 分批串流)。匯出前套用索引層級黑名單檢查,並寫入稽核紀錄。(P2)
60
+ - **Redis value / hash-field 遮罩。** 新增 `.dbcli` `redis.mask` 設定區塊:key 命中 `keyPattern` glob 者,其值(或指定的 hash `fields`)於讀取時(`GET`、`GETRANGE`、`HGETALL`、`HGET`、`HMGET`、`HVALS`)回傳 `[REDACTED]`。遮罩與既有 key-glob 拒絕黑名單並存,且**拒絕一律優先於遮罩**。(P3)
61
+
62
+ ### Fixed
63
+
64
+ - **Redis shell 單行指令路由。** 在 `dbcli shell` 對 Redis 連線輸入不帶結尾 `;` 的單行指令(`GET mykey`、`SCAN 0`、`HGETALL h`)現可正確執行,修正先前被誤判為未知 dbcli 指令的路由瑕疵。SQL 的分號 / 多行語意不變。(P4)
65
+
66
+ ### Changed
67
+
68
+ - `src/adapters/capabilities.ts`:ES `export` 由 unsupported 改為 limited(readonly);Redis `blacklist` note 補上 value/hash-field 遮罩;Redis `shell` 單行說明修正。
69
+
70
+ ### Docs
71
+
72
+ - 雙語 user docs(`docs/user/en` / `docs/user/zh-TW`,md + html)新增 ES shell、ES export、Redis 遮罩段落;`docs/feature-matrix.md` 同步 ES export 與 Redis blacklist 儲存格。
73
+
74
+ ## [1.21.0] - 2026-05-20 - Redis-Parity Pack
75
+
76
+ ### Added
77
+
78
+ - **Redis shell.** `dbcli shell` 現對 Redis 連線開啟互動式 REPL,具備歷史、readline、tab 補全(指令 + key 前綴)與 `.no-limit on/off` meta 指令。單行語意。
79
+ - **Redis size guard.** `SCAN` / `HSCAN` / `SSCAN` / `ZSCAN` 在缺少時補上 `COUNT 1000`;`LRANGE` / `ZRANGE` / `ZREVRANGE` 夾限 `stop`;`ZRANGEBYSCORE` 補上 `LIMIT 0 1000`。`HGETALL` / `HKEYS` / `HVALS` / `SMEMBERS` / `KEYS` 的無上限回覆在 client 端截斷至 1000 並帶 `REDIS_SIZE_TRUNCATE` 警告。`--no-limit` 略過所有防護。
80
+ - **Redis blacklist 強制。** `dbcli blacklist add 'pattern'` 現會封鎖 key 命中的 Redis 讀寫。採 Redis 原生 glob(`*`、`?`、`[abc]`、`[a-z]`)。與黑名單重疊的 `KEYS` / `SCAN MATCH` 會被拒絕;未重疊的掃描則濾掉黑名單 keys 並帶 `REDIS_BLACKLIST_FILTERED` 警告。稽核記錄含 `metadata.rejection_reason: 'blacklist'` 與 `matched_pattern`。
81
+
82
+ ### Changed
83
+
84
+ - `ExecutionResult.warnings` 現為公開型別的一部分(optional),目前僅由 Redis 發出。
85
+ - `src/adapters/capabilities.ts` Redis row 更新:`shell` → `interactive`、`query auto-limit` → `limited`、`blacklist` → `limited`。
86
+
87
+ ### Out of scope
88
+
89
+ - Elasticsearch shell、Redis/ES export、Redis value/hash-field 遮罩 — 延後至 v1.22 或之後。
90
+
91
+ ## [1.20.2] - 2026-05-19
92
+
93
+ ### Added
94
+
95
+ - **MongoDB MVP 全套支援。** `q` 指令現以 limited-supported 等級納入 MongoDB(`find` / `aggregate` 兩種 snippet body),路由經過專屬分支與 field-masker;`schema` 採 `$sample` + 遞迴 path 偵測(含 BSON 型別),新增 `--sample-method` 旗標;`query` / `export` 套用 `maskMongoRows` 對巢狀結構遞迴遮罩。
96
+ - **MongoDB blacklist 強化。** 新增 path-matcher(exact / dotted / suffix-wildcard)、field-masker 遞迴遮罩、insert / update 在寫入前強制套用 nested-path blacklist;`blacklist list` 對 collection 上的 middle-`*` pattern 發出警告。
97
+ - **MongoDB 安全模型升級。** update operator 從硬性 allowlist 改為分級安全(tiered operator safety);schema 對 blacklist 欄位直接 redact;`cache` / `doctor` 暴露 `sampleMethod`。
98
+ - **MongoDB snippets 一級公民化。** 內建 reference snippets(find + aggregate)、`queries list/search/suggest` 將 MongoDB snippets 與 SQL 引擎並列;`mongoStrategy` 驗證 body 與 params 並支援 map 形式插值。
99
+ - **Recovery — per-code branching for connection codes (MVP)。** `recover --next` 對 connection 類錯誤碼支援多 branch 派發:新增 `buildConnectionBranches` factory(4 個 connection branch)、`matchConnectionBranch` resolver、`classify` emit `branches` / `branchFork`,並提供 `--branch <id>` 旗標讓 agent 顯式選擇 branch。輸出 `NextResult.branchId` 與 markdown 中的 branchId/description 一併呈現。
100
+
101
+ ### Changed
102
+
103
+ - **MongoDB `q` 文件升級。** `docs/feature-matrix.md` / 雙語 user docs 將 MongoDB `q` 從 unsupported 改為 limited supported(記載目前支援的 body 形式與限制)。
104
+ - **Recovery schema 新增 `branches` / `branchFork`。** 行為向下相容(無 branch 時與舊版一致);`GuideStep` / `NextResult` / `NextStepOutput` 全鏈打通 `branchId`;`shellQuote` 抽離為共用模組。
105
+
106
+ ### Security
107
+
108
+ - **Pin `brace-expansion ^5.0.6`** 修補 GHSA-jxxr-4gwj-5jf2 ReDoS。
109
+
110
+ ### Tests
111
+
112
+ - `tests/integration/` — MongoDB tier、blacklist、sampling、snippet 整合覆蓋。
113
+ - 新增 mongo plan + schema envelope shape 的 contract test。
114
+ - Recovery: doctor↔resolver keyword coupling contract test、connection envelope 6 變體 snapshot、`recover` E2E branching(fork / walk / fallback / `--apply` 不變)覆蓋。
115
+
116
+ ### Docs
117
+
118
+ - 雙語 user docs 新增 Agent 修復工作流段落(精簡 walkthrough)與 Recovery Cookbook。
119
+ - `assets/SKILL.md` / `assets/reference.md` 補 `--branch` 旗標與 `NextResult.branchId` 說明、MongoDB tier / operator / blacklist / sampling 行為。
120
+ - 統一 npm 套件名為 `@carllee1983/dbcli`;關閉 v1.20.0 Phase 23-04 已知限制段落。
121
+ - `.planning/PROJECT.md` 同步:`bun test`、已 ship 項目移出 OOS。
122
+
123
+ ### Internal
124
+
125
+ - `style: [recovery] format with prettier (printWidth 100)` / `style: [mongo] format with prettier (printWidth 100)` — 全面套用 prettier `printWidth 100`。
126
+ - `fix: [test] remove this alias in mongo sampling mock` — 修正 eslint `no-this-alias`。
127
+ - `refactor: [snippets] register mongo as a first-class engine family` / `refactor: [recovery] extract shellQuote to a shared module`。
8
128
 
9
129
  ## [1.20.1] - 2026-05-18
10
130
 
@@ -420,6 +540,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
420
540
  ### Stable Release
421
541
 
422
542
  dbcli v1.0.0 is the first stable release. All three milestones are complete:
543
+
423
544
  - **M1 (v0.6.0):** Smart REPL — interactive shell with SQL + dbcli commands
424
545
  - **M2 (v0.8.0):** Schema DDL — CREATE/DROP/ALTER TABLE, INDEX, CONSTRAINT, ENUM
425
546
  - **M3 (v1.0.0):** Stabilization — documentation, permission matrix, known limitations update
@@ -586,6 +707,7 @@ Added table and column-level blacklisting to protect sensitive data from AI agen
586
707
  ### Configuration
587
708
 
588
709
  Blacklist rules stored in `.dbcli`:
710
+
589
711
  ```json
590
712
  {
591
713
  "blacklist": {
package/README.md CHANGED
@@ -630,7 +630,8 @@ Generate or install AI agent skill documentation.
630
630
  dbcli skill # Output skill to stdout
631
631
  dbcli skill --output SKILL.md # Write to file
632
632
  dbcli skill --install claude # Install to Claude Code config
633
- dbcli skill --install gemini # Install to Gemini CLI
633
+ dbcli skill --install gemini # Install to Gemini CLI (being phased out)
634
+ dbcli skill --install antigravity # Install to Antigravity CLI (Gemini CLI's successor)
634
635
  dbcli skill --install copilot # Install to GitHub Copilot
635
636
  dbcli skill --install cursor # Install to Cursor IDE
636
637
  ```
@@ -654,6 +655,7 @@ dbcli skill
654
655
  # Install for all platforms
655
656
  dbcli skill --install claude && \
656
657
  dbcli skill --install gemini && \
658
+ dbcli skill --install antigravity && \
657
659
  dbcli skill --install copilot && \
658
660
  dbcli skill --install cursor
659
661
  ```
@@ -766,6 +768,50 @@ dbcli diff --against ./schema-before.json --format table
766
768
 
767
769
  ---
768
770
 
771
+ #### `dbcli snapshot`
772
+
773
+ Capture a **result fingerprint** of a query (distinct from `diff`, which snapshots *schema*): row count plus per-column aggregates (null/distinct counts, min/max/sum) and an order-independent checksum. Blacklisted columns are masked at the source, so the snapshot is safe to store. Use it as a baseline for `dbcli assert --against`. SQL engines only.
774
+
775
+ **Usage:**
776
+ ```bash
777
+ dbcli snapshot "SELECT * FROM orders WHERE created_at >= '2026-05-01'" # → .dbcli/snapshots/snap-<timestamp>.json
778
+ dbcli snapshot @analytics/daily-revenue --out base.json
779
+ dbcli snapshot "SELECT status, count(*) FROM orders GROUP BY status" --stdout
780
+ ```
781
+
782
+ **Options:**
783
+ - `--out <path>` — Output path (default: `.dbcli/snapshots/snap-<timestamp>.json`)
784
+ - `--rows` — Also store the full (blacklist-masked) rows
785
+ - `--stdout` — Print snapshot JSON to stdout instead of writing a file
786
+ - `--format json|table` — Output format for `--stdout` (default: `json`)
787
+ - `--no-limit` — Disable the automatic query-only LIMIT
788
+
789
+ ---
790
+
791
+ #### `dbcli assert`
792
+
793
+ Assert an **invariant** on a query result. Exits `1` on failure (composes in scripts/CI) unless `--no-fail`. SQL engines only.
794
+
795
+ **Usage:**
796
+ ```bash
797
+ dbcli assert "SELECT count(*) FROM orders" --expect "value > 0"
798
+ dbcli assert "SELECT * FROM orders WHERE total < 0" --expect "rows == 0"
799
+ dbcli assert "SELECT email FROM users" --expect "col:email not null"
800
+ dbcli assert "SELECT sum(amount) FROM ledger_a" --vs "SELECT sum(amount) FROM ledger_b" --compare value
801
+ dbcli assert "SELECT * FROM orders" --against base.json --tolerance 0.01
802
+ ```
803
+
804
+ **Options:**
805
+ - `--expect <condition>` — `rows > 0`, `value == 5000`, `col:email not null`, `col:id unique`, `col:amount between 0 and 100`, `col:age >= 18`
806
+ - `--vs <query>` — Reconcile against a second query
807
+ - `--compare rows|value` — Comparison mode for `--vs` (default: `value`)
808
+ - `--against <path>` — Compare the current result fingerprint to a saved snapshot
809
+ - `--tolerance <pct>` — Allowed relative drift for `--against` (e.g. `0.01`; default: `0` = exact checksum match)
810
+ - `--no-fail` — Always exit 0; report pass/fail in output only
811
+ - `--format json|table` — Output format (default: `json`)
812
+
813
+ ---
814
+
769
815
  #### `dbcli status`
770
816
 
771
817
  Show non-sensitive configuration summary (permission level, DB system, blacklist counts, config metadata version). Does not print connection credentials — intended for AI agents.
package/README.zh-TW.md CHANGED
@@ -528,7 +528,8 @@ dbcli export "SELECT * FROM users WHERE active=true" --format json | jq '.data |
528
528
  dbcli skill # 輸出至 stdout
529
529
  dbcli skill --output SKILL.md # 寫入檔案
530
530
  dbcli skill --install claude # 安裝至 Claude Code 設定
531
- dbcli skill --install gemini # 安裝至 Gemini CLI
531
+ dbcli skill --install gemini # 安裝至 Gemini CLI(即將淘汰)
532
+ dbcli skill --install antigravity # 安裝至 Antigravity CLI(Gemini CLI 後繼者)
532
533
  dbcli skill --install copilot # 安裝至 GitHub Copilot
533
534
  dbcli skill --install cursor # 安裝至 Cursor IDE
534
535
  ```
@@ -552,6 +553,7 @@ dbcli skill
552
553
  # 為多平台安裝
553
554
  dbcli skill --install claude && \
554
555
  dbcli skill --install gemini && \
556
+ dbcli skill --install antigravity && \
555
557
  dbcli skill --install copilot && \
556
558
  dbcli skill --install cursor
557
559
  ```
@@ -665,6 +667,50 @@ dbcli diff --against ./schema-before.json --format table
665
667
 
666
668
  ---
667
669
 
670
+ #### `dbcli snapshot`
671
+
672
+ 擷取查詢的**結果指紋**(與 `diff` 不同,`diff` 快照的是 *schema*):rowCount 加上每欄聚合(null/distinct 計數、min/max/sum)與順序無關的 checksum。黑名單欄位在源頭遮罩,因此快照可安全保存。作為 `dbcli assert --against` 的基準。僅支援 SQL 引擎。
673
+
674
+ **用法:**
675
+ ```bash
676
+ dbcli snapshot "SELECT * FROM orders WHERE created_at >= '2026-05-01'" # → .dbcli/snapshots/snap-<timestamp>.json
677
+ dbcli snapshot @analytics/daily-revenue --out base.json
678
+ dbcli snapshot "SELECT status, count(*) FROM orders GROUP BY status" --stdout
679
+ ```
680
+
681
+ **選項:**
682
+ - `--out <path>` — 輸出路徑(預設:`.dbcli/snapshots/snap-<timestamp>.json`)
683
+ - `--rows` — 連同遮罩後的完整列一併存檔
684
+ - `--stdout` — 將快照 JSON 印到 stdout 而非寫檔
685
+ - `--format json|table` — `--stdout` 的輸出格式(預設:`json`)
686
+ - `--no-limit` — 停用查詢限定模式的自動 LIMIT
687
+
688
+ ---
689
+
690
+ #### `dbcli assert`
691
+
692
+ 對查詢結果驗證**不變量**。失敗時 `exit 1`(可組合進腳本 / CI),除非加上 `--no-fail`。僅支援 SQL 引擎。
693
+
694
+ **用法:**
695
+ ```bash
696
+ dbcli assert "SELECT count(*) FROM orders" --expect "value > 0"
697
+ dbcli assert "SELECT * FROM orders WHERE total < 0" --expect "rows == 0"
698
+ dbcli assert "SELECT email FROM users" --expect "col:email not null"
699
+ dbcli assert "SELECT sum(amount) FROM ledger_a" --vs "SELECT sum(amount) FROM ledger_b" --compare value
700
+ dbcli assert "SELECT * FROM orders" --against base.json --tolerance 0.01
701
+ ```
702
+
703
+ **選項:**
704
+ - `--expect <condition>` — `rows > 0`、`value == 5000`、`col:email not null`、`col:id unique`、`col:amount between 0 and 100`、`col:age >= 18`
705
+ - `--vs <query>` — 與第二個查詢對帳
706
+ - `--compare rows|value` — `--vs` 的比較模式(預設:`value`)
707
+ - `--against <path>` — 將目前結果指紋與已存快照比對
708
+ - `--tolerance <pct>` — `--against` 容許的相對漂移(例如 `0.01`;預設 `0` = 完全相符 checksum)
709
+ - `--no-fail` — 永遠 exit 0;僅在輸出中報告 pass/fail
710
+ - `--format json|table` — 輸出格式(預設:`json`)
711
+
712
+ ---
713
+
668
714
  #### `dbcli status`
669
715
 
670
716
  顯示不含連線憑證的設定摘要(權限、資料庫系統、黑名單筆數、設定中繼版本),適合提供給 AI 代理。
@@ -1177,11 +1223,14 @@ Redaction 沿用 v1.19.1 agent-facing JSON 合約的同一來源
1177
1223
  `recover --apply` 的 JSON 輸出會內嵌 `audit_recent: AuditEntryBrief[]`(最近 5 筆),
1178
1224
  讓新 session 立即擁有歷史脈絡。
1179
1225
 
1180
- **已知限制(v1.20.0):** Bi-directional 連結僅在 `query` / `inspect` / diagnostic
1181
- 表面寫入;DML 指令 `insert / update / delete / export / q / schema` 失敗時
1182
- emit envelope 暫未含 `audit_ref`,追蹤於 Phase 23-04 follow-up。完整對照表見
1226
+ **完整雙向覆蓋(v1.20.1+):** Recovery audit linkage 已在每一個
1227
+ `--recovery`-capable 指令落地 `query`、`inspect`、`insert`、`update`、`delete`、
1228
+ `export`、`q`、`schema` wired。失敗路徑上,audit entry `recovery_ref`
1229
+ envelope 的 `audit_ref` 互帶相同 UUID;agent 可從 envelope(`.dbcli/last-recovery.json`)
1230
+ 透過 `dbcli audit tail --recovery-ref <id>` 跳到對應的 audit entry,或反向以
1231
+ `dbcli audit show --recovery-ref <id>` 從 audit 找回 envelope。v1.20.0 在 6 個
1232
+ DML/DDL 指令上的部分覆蓋缺口已於 v1.20.1 結清,完整對照表見
1183
1233
  [`.planning/phases/25-recovery-envelope-bi-directional-linkage/25-J1-COVERAGE-MATRIX.md`](./.planning/phases/25-recovery-envelope-bi-directional-linkage/25-J1-COVERAGE-MATRIX.md)。
1184
- Recovery envelope 自身的 linkage 不受影響。
1185
1234
 
1186
1235
  進階 agent 工作流程(session handoff、forensics walk-through)詳見
1187
1236
  [`assets/SKILL.md`](./assets/SKILL.md) §Audit Log usage(英文)或
package/assets/SKILL.md CHANGED
@@ -9,6 +9,7 @@ Database CLI for AI agents with permission-based access control.
9
9
 
10
10
  ## AI agent workflow (follow in order)
11
11
 
12
+ 0. `dbcli skill context --format xml` — LLM prompt context payload: serializes connection metadata, schema caches, and saved queries into a compressed XML/JSON structure for prompt injection.
12
13
  1. `dbcli inspect --for-agent` — bounded snapshot: connection, permission, blacklist, objects, snippets, suggested next commands.
13
14
  2. `dbcli report --format json` — diagnostic report (health/capacity/perf) using built-in snippets.
14
15
  3. `dbcli guide <goal> --format json` — deterministic next-command plan for a fixed goal (`slow-query`, `capacity`, `health`, `index-usage`, `permissions`, `schema-overview`). Use `dbcli guide --list` to see goals.
@@ -49,6 +50,7 @@ Database CLI for AI agents with permission-based access control.
49
50
  6. `dbcli schema <table> --format json` — real column names (SQL/Mongo/ES) or `schema <key>` (Redis). **Never guess.**
50
51
  7. Run `query` / `insert` / `update` / `delete` / `export` within permission.
51
52
  8. All writes: `--dry-run` (SQL/Mongo) → run → `query` read-back to confirm.
53
+ - **v1.21.0 Self-Verification Loops**: If a snippet defines a `verify` block in its frontmatter, run the snippet with `dbcli q @name --verify` to automatically run primary changes, execute the verification query, and validate assertions.
52
54
 
53
55
  Prefer `--format json` for agent-friendly output.
54
56
 
@@ -68,6 +70,12 @@ The plan output is an ordered list of dbcli commands with rationale and risk
68
70
  labels. Execute them one at a time — task plans do **not** override blacklist,
69
71
  schema, dry-run, or confirmation requirements.
70
72
 
73
+ Builtin packs: `diagnose-slow-query` and **(v1.23)** `analyze-table-perf` — a
74
+ read-only `plan-only` pack taking a required `table` parameter that walks
75
+ `blacklist list` → `schema <table> --format json` → `guide index-usage`. `dbcli
76
+ inspect` suggests `analyze-table-perf` automatically for the hottest table in
77
+ recent audit activity.
78
+
71
79
  Tasks live under `assets/tasks/` (builtin), `.dbcli-shared/tasks/` (shared), and
72
80
  `.dbcli/tasks/` (local override).
73
81
 
@@ -232,26 +240,29 @@ Full flags and edge cases: see [reference.md](reference.md) `init` section.
232
240
  | `list` | query-only+ | Tables (SQL), collections (MongoDB), keys (Redis), or indices (Elasticsearch). |
233
241
  | `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`. |
234
242
  | `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`. |
243
+ | `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`. |
235
244
  | `plan` | n/a | Static SQL risk analyzer (`--format text\|json`); classifies a statement without connecting to the database. |
236
- | `q` | query-only+ | Run a saved snippet by `@name` with `--param k=v`. SQL / Elasticsearch DSL / read-only Redis bodies; blacklist enforced. `--format table\|json\|csv\|html`, `--ui` to open the interactive dashboard. Supports `--recovery`. |
245
+ | `q` | query-only+ | Run a saved snippet by `@name` with `--param k=v`. Supports `--verify` to run assertions. |
237
246
  | `queries` | n/a | Manage saved snippets: `list` / `show` / `search` / `suggest` / `new` / `edit` / `check` / `delete` / `rename` / `copy` / `import` / `export`. |
238
247
  | `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`. |
239
248
  | `delete` | data-admin+ | SQL or MongoDB only. `--where` required; `--dry-run` first. Supports `--recovery`. |
240
- | `export` | query-only+ | SQL or MongoDB only. Query → `--format json\|jsonl\|csv\|html` file or stdout. `html` emits a standalone interactive dashboard. Supports `--recovery`. |
249
+ | `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`. |
241
250
  | `blacklist` | n/a | `list` / `table` / `column` subcommands redact sensitive data from query results. |
242
251
  | `check` | query-only+ | SQL only (best on MySQL/MariaDB). |
243
252
  | `diff` | query-only+ | SQL only. Save/compare schema snapshots. |
253
+ | `snapshot` | query-only+ | **(v1.25)** SQL only. Capture a result fingerprint (`rowCount` + per-column null/distinct/min/max/sum + order-independent checksum). `--out` (default `.dbcli/snapshots/snap-<ts>.json`), `--rows`, `--stdout`, `--format`, `--no-limit`. Baseline for `assert --against`. |
254
+ | `assert` | query-only+ | **(v1.25)** SQL only. Verify an invariant; exit 1 on failure unless `--no-fail`. `--expect "rows>0\|value==X\|col:c not null\|unique\|between a and b\|>= n"`, `--vs <query> --compare rows\|value` (reconcile), `--against <snapshot> --tolerance <pct>`. |
244
255
  | `status` | query-only+ | Safe JSON/text summary (no credentials). |
245
- | `inspect` | query-only+ | Read-only context snapshot (connection, permission, blacklist, objects, snippets, suggested commands). `--for-agent` / `--no-connect` / `--require-schema-cache`. Supports `--recovery`. |
256
+ | `inspect` | query-only+ | Read-only context snapshot (connection, permission, blacklist, objects, snippets, context-aware `suggestedCommands`, and **(v1.23)** human-readable `hints`). `--for-agent` / `--brief` / `--no-connect` / `--require-schema-cache`. Supports `--recovery`. |
246
257
  | `report` | query-only+ | Diagnostic report (health / capacity / perf) built from `@diag/*` snippets. `--section`, `--brief`, `--for-agent`, `--no-connect`. |
247
- | `guide` | query-only+ | Deterministic next-command plan for a fixed goal (`slow-query`, `capacity`, `health`, `index-usage`, `permissions`, `schema-overview`). `--list` to enumerate. |
258
+ | `guide` | query-only+ | Deterministic next-command plan for a fixed goal (`slow-query`, `capacity`, `health`, `index-usage`, `permissions`, `schema-overview`). `--list` to enumerate. **(v1.23)** `guide missing-index-for <query>` suggests composite indexes for a single SELECT (`--format yaml\|json\|markdown`, `--min-confidence`). |
248
259
  | `recovery` | n/a | Look up the structured `RecoveryEnvelope` for a known error code (`--code <CODE>` or `--list`). Standalone synthesizer; does not require a real failure. |
249
260
  | `recover` | n/a | Inspect (default) or `--apply` the auto-saved recovery plan in `.dbcli/last-recovery.json`. `--allow-write=readonly-cmd\|write-cmd`, `--no-verify`, `--from <file>`, `--next --after-step <n> --result <json\|@file>` for multi-turn step-at-a-time. |
250
261
  | `doctor` | n/a | Environment, config, connection, SRV diagnostics (Mongo), schema cache age. |
251
262
  | `completion` | n/a | bash / zsh / fish scripts. |
252
263
  | `upgrade` | n/a | Self-update from npm; 24h-cached version hints on every command. |
253
- | `shell` | (same as query+) | Interactive REPL. SQL engines + MongoDB shell only. |
254
- | `skill` | n/a | Generate / install AI skill docs (`--install <claude\|gemini\|copilot\|cursor>`); `skill tasks list/show/plan` for Agent Task Packs. |
264
+ | `shell` | (same as query+) | Interactive REPL. SQL engines, MongoDB, and Redis (single-line; `.no-limit on/off`). **(v1.22)** Elasticsearch opens a Kibana Dev Tools-style REPL (`<METHOD> /<path>` + optional JSON body, blank line submits). |
265
+ | `skill` | n/a | Generate / install AI skill docs (`--install <claude\|gemini\|antigravity\|copilot\|cursor>`); `skill tasks list/show/plan` for Agent Task Packs; `skill context` for LLM prompt context payload. |
255
266
  | `migrate` | admin | SQL only. **DDL; dry-run by default** — needs `--execute`. |
256
267
 
257
268
  `--use <name>` on any subcommand targets a v2 connection without changing the default.
@@ -286,19 +297,25 @@ Full flags and edge cases: see [reference.md](reference.md) `init` section.
286
297
  ## Redis
287
298
 
288
299
  - Command-style execution; `query` runs a whitelisted Redis command (e.g. `GET`, `HSET`, `DEL`).
289
- - **Supported:** `init`, `list` (keys via SCAN), `schema <key>` (type / TTL / size / sample), `query`, `status`, `use`, `doctor`, `upgrade`, `completion`.
300
+ - **Supported:** `init`, `list` (keys via SCAN), `schema <key>` (type / TTL / size / sample), `query`, `shell`, `status`, `use`, `doctor`, `upgrade`, `completion`.
290
301
  - **Not supported:** `schema` full scan, `insert`, `update`, `delete`, `export`, `check`, `diff`, `migrate`, `q`.
291
302
  Use `query "DEL <key>"` etc. for writes — they go through the same permission gate.
292
303
  - Permission tiers map to commands: read commands → `query-only`; mutators (`SET`, `HSET`, ...) → `read-write`; `DEL` / `UNLINK` → `data-admin`.
293
304
  - `database` field is the logical DB index (default `0`); `list` returns ≤ 100 000 keys via SCAN.
305
+ - **Size guard:** `SCAN`/`HSCAN`/`SSCAN`/`ZSCAN` inject `COUNT 1000`; `LRANGE`/`ZRANGE` clamp `stop`; `ZRANGEBYSCORE` injects `LIMIT 0 1000`; `HGETALL`/`HKEYS`/`HVALS`/`SMEMBERS`/`KEYS` truncate at 1000. Results carry `warnings[]` (`REDIS_SIZE_REWRITE` / `REDIS_SIZE_TRUNCATE`). Pass `--no-limit` (CLI) or `.no-limit on` (shell) to bypass.
306
+ - **Blacklist:** `dbcli blacklist add 'secrets:*'` registers a Redis-native key glob. Reads/writes whose keys match are rejected (`BlacklistRejection`, audited with `metadata.matched_pattern`); `KEYS`/`SCAN MATCH` overlapping a rule are rejected; non-overlapping listings filter blacklisted keys.
307
+ - **Masking (v1.22):** add a `redis.mask` block to `.dbcli` — keys matching a `keyPattern` glob have their value (or named hash `fields`) returned as `[REDACTED]` on reads (`GET`, `GETRANGE`, `HGETALL`, `HGET`, `HMGET`, `HVALS`). Masking coexists with key-glob rejection, and **rejection always wins over masking**.
308
+ - **Shell:** `dbcli shell` on a Redis connection opens a single-line REPL (history, tab completion of commands + key prefixes, `.no-limit on/off`).
294
309
  - See reference.md Redis section.
295
310
 
296
311
  ## Elasticsearch
297
312
 
298
313
  - DSL (JSON body) or Lucene query string; `--collection <index>` is required on `query`.
299
- - **Supported:** `init`, `list` (indices with doc count), `schema [index]` (flattened mapping), `query`, `status`, `use`, `doctor`, `upgrade`, `completion`.
300
- - **Not supported:** `insert`, `update`, `delete`, `export`, `check`, `diff`, `migrate`, `q`.
314
+ - **Supported:** `init`, `list` (indices with doc count), `schema [index]` (flattened mapping), `query`, `export` (v1.22), `shell` (v1.22), `status`, `use`, `doctor`, `upgrade`, `completion`.
315
+ - **Not supported:** `insert`, `update`, `delete`, `check`, `diff`, `migrate`, `q`.
301
316
  Writes are not exposed via dedicated subcommands yet — use `query` if the cluster allows or external tools.
317
+ - **Export (v1.22):** `dbcli export` takes a search DSL with `--index <index>` to export hits, or an index name as the query to scroll the whole index via `match_all`. Outputs JSON / JSONL / CSV (default 1000 rows; `--no-limit` scrolls the full index in batches). Index-level blacklist + audit apply.
318
+ - **Shell (v1.22):** `dbcli shell` opens a Kibana Dev Tools-style REPL — request line `<METHOD> /<path>` plus an optional multi-line JSON body, submitted with a blank line; index-level blacklist rejects protected indices and `_search` auto-caps at 1000 when `size` is omitted.
302
319
  - Query-only mode caps at 1000 hits; `--no-limit` is bounded at 10 000.
303
320
  - Schema flattens nested fields (`a.b.c`) and surfaces `.fields` multi-fields.
304
321
  - See reference.md Elasticsearch section.
@@ -11,6 +11,7 @@ description: 為 AI 代理設計、具權限控管的資料庫 CLI。可用於
11
11
 
12
12
  ## AI 代理工作流程(依序執行)
13
13
 
14
+ 0. `dbcli skill context --format xml` — LLM 提示詞脈絡載荷:將連線中介資料、Schema 快取和已儲存查詢序列化為高度壓縮的 XML/JSON 結構以進行 Prompt 注入。
14
15
  1. `dbcli inspect --for-agent` — 有界快照:連線、權限、blacklist、物件、snippets、建議的下一個指令。
15
16
  2. `dbcli report --format json` — 使用內建 snippets 產出診斷報告(health / capacity / perf)。
16
17
  3. `dbcli guide <goal> --format json` — 針對固定目標產出確定性的下一步指令計畫(`slow-query`、`capacity`、`health`、`index-usage`、`permissions`、`schema-overview`)。執行 `dbcli guide --list` 查看所有目標。
@@ -51,6 +52,7 @@ description: 為 AI 代理設計、具權限控管的資料庫 CLI。可用於
51
52
  6. `dbcli schema <table> --format json` — 取得真實欄位名稱(SQL / Mongo / ES)或 `schema <key>`(Redis)。**禁止猜測。**
52
53
  7. 在允許的權限範圍內執行 `query` / `insert` / `update` / `delete` / `export`。
53
54
  8. 所有寫入:`--dry-run`(SQL / Mongo)→ 實際執行 → `query` 回讀確認。
55
+ - **v1.21.0 自我驗證循環(Self-Verification Loops)**:如果 snippet 在其 frontmatter 中定義了 `verify` 區塊,使用 `dbcli q @name --verify` 來執行該 snippet,即可自動跑完主要變更、執行驗證查詢並驗證斷言。
54
56
 
55
57
  代理友善的輸出請優先用 `--format json`。
56
58
 
@@ -199,7 +201,7 @@ dbcli init --use-env-refs \
199
201
  | `schema` | query-only+ | SQL:單表或全掃描存入 `.dbcli/schemas/`。MongoDB:sampled。ES:flattened mapping。Redis:僅單一 key(type / TTL / size)。支援 `--recovery`。 |
200
202
  | `query` | query-only+ | SQL、Mongo JSON(`--collection`)、Redis 指令、ES DSL / Lucene(`--collection`)。`--format table\|json\|csv\|html`、`--ui` 開啟瀏覽器互動式 dashboard。支援 `--recovery`。 |
201
203
  | `plan` | n/a | 靜態 SQL 風險分析器(`--format text\|json`);不連線即可分類語句。 |
202
- | `q` | query-only+ | 以 `@name` 執行已儲存 snippet,搭配 `--param k=v`。支援 SQL / Elasticsearch DSL / 唯讀 Redis 內容;blacklist 強制套用。`--format table\|json\|csv\|html`、`--ui` 開啟互動式 dashboard。支援 `--recovery`。 |
204
+ | `q` | query-only+ | 以 `@name` 執行已儲存 snippet,搭配 `--param k=v`。支援 `--verify` 以執行斷言。 |
203
205
  | `queries` | n/a | 管理已儲存 snippet:`list` / `show` / `search` / `suggest` / `new` / `edit` / `check` / `delete` / `rename` / `copy` / `import` / `export`。 |
204
206
  | `insert` / `update` | read-write+ | 僅 SQL 與 MongoDB。JSON `--data` / `--set`;`update` 必填 `--where`;先 `--dry-run`。Redis 寫入透過 `query`。支援 `--recovery`。 |
205
207
  | `delete` | data-admin+ | 僅 SQL 與 MongoDB。必填 `--where`;先 `--dry-run`。支援 `--recovery`。 |
@@ -207,6 +209,8 @@ dbcli init --use-env-refs \
207
209
  | `blacklist` | n/a | `list` / `table` / `column` 子指令,從查詢結果中遮蔽敏感資料。 |
208
210
  | `check` | query-only+ | 僅 SQL(在 MySQL / MariaDB 最佳)。 |
209
211
  | `diff` | query-only+ | 僅 SQL。儲存 / 比較 schema snapshot。 |
212
+ | `snapshot` | query-only+ | **(v1.25)** 僅 SQL。擷取結果指紋(`rowCount` + 每欄 null/distinct/min/max/sum + 順序無關 checksum)。`--out`(預設 `.dbcli/snapshots/snap-<ts>.json`)、`--rows`、`--stdout`、`--format`、`--no-limit`。作為 `assert --against` 的基準。 |
213
+ | `assert` | query-only+ | **(v1.25)** 僅 SQL。驗證不變量;失敗時 exit 1,除非 `--no-fail`。`--expect "rows>0\|value==X\|col:c not null\|unique\|between a and b\|>= n"`、`--vs <query> --compare rows\|value`(對帳)、`--against <snapshot> --tolerance <pct>`。 |
210
214
  | `status` | query-only+ | 安全 JSON / 文字摘要(不含憑證)。 |
211
215
  | `inspect` | query-only+ | 唯讀脈絡快照(連線、權限、blacklist、物件、snippets、建議指令)。`--for-agent` / `--no-connect` / `--require-schema-cache`。支援 `--recovery`。 |
212
216
  | `report` | query-only+ | 以 `@diag/*` snippet 組成的診斷報告(health / capacity / perf)。`--section`、`--brief`、`--for-agent`、`--no-connect`。 |
@@ -216,8 +220,8 @@ dbcli init --use-env-refs \
216
220
  | `doctor` | n/a | 環境、設定、連線、SRV 診斷(Mongo)、schema cache 年齡。 |
217
221
  | `completion` | n/a | bash / zsh / fish 腳本。 |
218
222
  | `upgrade` | n/a | 從 npm 自我更新;每個指令都帶 24h 快取的版本提示。 |
219
- | `shell` | (與 query 同) | 互動式 REPL。僅支援 SQL 引擎與 MongoDB shell。 |
220
- | `skill` | n/a | 產出 / 安裝 AI skill 文件(`--install <claude\|gemini\|copilot\|cursor>`);`skill tasks list/show/plan` 提供 Agent Task Packs |
223
+ | `shell` | (與 query 同) | 互動式 REPL。支援 SQL 引擎、MongoDB 與 Redis(單行;`.no-limit on/off`)。 |
224
+ | `skill` | n/a | 產出 / 安裝 AI skill 文件(`--install <claude\|gemini\|antigravity\|copilot\|cursor>`);`skill tasks list/show/plan` 提供 Agent Task Packs;`skill context` 提供 LLM 提示詞脈絡載荷。 |
221
225
  | `migrate` | admin | 僅 SQL。**DDL;預設 dry-run** — 需 `--execute` 才會真的執行。 |
222
226
 
223
227
  任何子指令上的 `--use <name>` 都會把目標切到對應的 v2 連線,但不改變預設值。
@@ -252,11 +256,14 @@ dbcli init --use-env-refs \
252
256
  ## Redis
253
257
 
254
258
  - 指令式執行;`query` 跑白名單內的 Redis 指令(例如 `GET`、`HSET`、`DEL`)。
255
- - **支援:** `init`、`list`(透過 SCAN 列 keys)、`schema <key>`(type / TTL / size / sample)、`query`、`status`、`use`、`doctor`、`upgrade`、`completion`。
259
+ - **支援:** `init`、`list`(透過 SCAN 列 keys)、`schema <key>`(type / TTL / size / sample)、`query`、`shell`、`status`、`use`、`doctor`、`upgrade`、`completion`。
256
260
  - **不支援:** `schema` 全掃描、`insert`、`update`、`delete`、`export`、`check`、`diff`、`migrate`、`q`。
257
261
  寫入請走 `query "DEL <key>"` 等 — 同樣經過權限門檻。
258
262
  - 權限分層對應指令:讀取類 → `query-only`;mutator(`SET`、`HSET`、...)→ `read-write`;`DEL` / `UNLINK` → `data-admin`。
259
263
  - `database` 欄位是 logical DB index(預設 `0`);`list` 透過 SCAN 最多回傳 100 000 個 keys。
264
+ - **大小防護(size guard):** `SCAN`/`HSCAN`/`SSCAN`/`ZSCAN` 自動補上 `COUNT 1000`;`LRANGE`/`ZRANGE` 夾限 `stop`;`ZRANGEBYSCORE` 補上 `LIMIT 0 1000`;`HGETALL`/`HKEYS`/`HVALS`/`SMEMBERS`/`KEYS` 在 1000 筆截斷。結果帶有 `warnings[]`(`REDIS_SIZE_REWRITE` / `REDIS_SIZE_TRUNCATE`)。以 `--no-limit`(CLI)或 `.no-limit on`(shell)略過。
265
+ - **黑名單:** `dbcli blacklist add 'secrets:*'` 註冊 Redis 原生 key glob。命中規則的讀寫會被拒絕(`BlacklistRejection`,稽核記錄含 `metadata.matched_pattern`);與規則重疊的 `KEYS`/`SCAN MATCH` 會被拒絕;未重疊的列舉會濾掉黑名單 keys。
266
+ - **Shell:** Redis 連線執行 `dbcli shell` 會開啟單行 REPL(歷史、指令與 key 前綴 tab 補全、`.no-limit on/off`)。
260
267
  - 詳見 reference.md Redis 段落。
261
268
 
262
269
  ## Elasticsearch