@carllee1983/dbcli 1.37.1 → 1.38.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,103 +1,76 @@
1
1
  ---
2
2
  name: dbcli
3
- description: AI 代理設計、具權限控管的資料庫 CLI。可用於建立連線、查詢、檢視 schema、insert/update/delete、匯出結果,以及對敏感欄位/資料表設定 blacklist。支援 MySQLPostgreSQLMariaDBMongoDBRedis Elasticsearch,並可在單一專案中管理多個命名連線與自訂 env 檔。當需要設定資料庫連線(`.dbcli` / `.env`)、在 v1 單一連線與 v2 多連線格式之間選擇、挑選認證方式(URIenv 參照、Cloud IDAPI key)、執行 SQL / MongoDB JSON / Redis 指令 / Elasticsearch DSL、探索表格 / collection / key / index 結構、切換資料庫環境、保護敏感資料免受 AI 存取,或在指令失敗後執行自動化復原與引導修復時,觸發此 skill。完整旗標與範例請閱讀同層的 `reference.md`。
3
+ description: Database CLI for AI agents with permission-based access control. Use to set up new connections, query, inspect schemas, insert/update/delete, export results, and blacklist sensitive columns/tables. Supports MySQL, PostgreSQL, MariaDB, MongoDB, Redis, and Elasticsearch with multiple named connections per project and custom env files. Trigger when configuring a database connection (`.dbcli` / `.env`), choosing between v1 single and v2 multi-connection layouts, picking auth modes (URI, env refs, Cloud ID, API key), running SQL / MongoDB JSON / Redis commands / Elasticsearch DSL, exploring table/collection/key/index structures, switching database environments, protecting sensitive data from AI access, or performing automated recovery and guided remediation after command failures. For exhaustive flags and examples, read the sibling `reference.md`.
4
4
  ---
5
5
 
6
- **Languages:** [English](./SKILL.md) | [繁體中文](./SKILL.zh-TW.md)
7
-
8
6
  # dbcli
9
7
 
10
8
  為 AI 代理設計、具權限控管的資料庫 CLI。
11
9
 
12
- ## AI 代理工作流程(依序執行)
13
-
14
- 0. `dbcli skill context --format xml` — LLM 提示詞脈絡載荷:將連線中介資料、Schema 快取和已儲存查詢序列化為高度壓縮的 XML/JSON 結構以進行 Prompt 注入。
15
- 1. `dbcli inspect --for-agent` — 有界快照:連線、權限、blacklist、物件、snippets、建議的下一個指令。
16
- 2. `dbcli report --format json` 使用內建 snippets 產出診斷報告(health / capacity / perf)。
17
- 3. `dbcli guide <goal> --format json` — 針對固定目標產出確定性的下一步指令計畫(`slow-query`、`capacity`、`health`、`index-usage`、`permissions`、`schema-overview`)。執行 `dbcli guide --list` 查看所有目標。
18
- 4. `dbcli recovery --code <CODE>` 針對已知錯誤代碼(如 `CONN_REFUSED`、`PERMISSION_DENIED`、`SNIPPET_NOT_FOUND`)查詢結構化的復原指令。把 `--recovery` 傳給 `dbcli query` / `dbcli q`,失敗時可直接得到 `RecoveryEnvelope`。在 v1.16.0 中,`--recovery` 旗標也被 `dbcli insert`、`dbcli update`、`dbcli delete`、`dbcli export`、`dbcli schema` 與 `dbcli inspect` 支援(後者另新增 `--require-schema-cache` 對應 `SCHEMA_CACHE_MISSING` 路徑)。
19
- - **v1.17.0** `dbcli recover` 讀取由先前 `--recovery` 失敗自動寫入的信封(`.dbcli/last-recovery.json`)。可單純檢視(預設 Markdown),或用 `--apply` 在風險門控下執行儲存的計畫。
20
- - **v1.17.0** `dbcli recover --apply` 預設只執行 `risk=readonly` 與 `risk=dry-run` 步驟。可用 `--allow-write=readonly-cmd` 開放一層門控(執行本機端寫入,如 `blacklist remove`),或 `--allow-write=write-cmd`(也允許異動所連資料庫的步驟)。`--from <file>` 指定外部信封,取代自動儲存的那一個。`--format json` 輸出彙整後的機器可讀結果。
21
- - 退出碼:`0` 成功、`1` 步驟失敗、`2` 信封缺失或格式錯誤、`3` 所有步驟皆被跳過(請開啟 `--allow-write` 或修正 interactive / placeholder)。
22
- - 代理應遵守的 GuideStep 可選欄位:
23
- - `interactive: true` — 步驟需要 TTY(`dbcli init` 家族)。`dbcli recover --apply` 會以 `skipped:interactive` 略過。
24
- - `dbWrite: true` — 步驟會異動所連資料庫。鎖定最高風險層;保留給未來的寫入端復原步驟。
25
- - `placeholders: ['<token>', ...]` — 代理必須在 `--apply` 執行前替換這些 token,否則會以 `skipped:placeholder` 略過。
26
- - **v1.17.0 P4 Verification(驗證)。** `--apply` 主要計畫結束後,dbcli 會多跑 **一個唯讀步驟**(`envelope.verify`),偵測原始失敗是否已修復。輸出新增 `verifyResult`(執行的步驟)與 `verifyStatus`:
27
- - `passed` 驗證器以 0 退出,且(適用時)符合預期的 JSON 形狀。
28
- - `failed` — 驗證器以非零退出或逾時。
29
- - `indeterminate` 驗證器以 0 退出,但啟發式判斷無法確認修復(JSON 解析失敗、欄位缺失、門控略過)。
30
- Verify **僅在** `finalStatus === 'ok'` 時執行。傳 `--no-verify` 可略過。啟發式刻意輕量;正確性重要時,代理仍應自行對原始失敗操作再驗證一次。
31
-
32
- 驗證結果詞彙:只有在必要證據符合預期時才使用 `verified`;檢查已執行但結果違反預期時使用
33
- `not_verified`;檢查已執行但證據不足或模糊時使用 `indeterminate`;因 config、權限、schema、
34
- placeholder 或安全閘門導致驗證無法執行時使用 `blocked`。
35
-
36
- - **v1.17.0 P2 Multi-turn `--next`(多輪逐步執行)。** `--apply` 顆粒度過粗(interactive 卡住、計畫需要逐步檢視,或代理希望用自有工具驅動復原)時,可逐步執行步驟並向 dbcli 詢問下一步:
37
-
38
- ```bash
39
- # 代理從信封讀取 step 1,執行後向 dbcli 取得 step 2:
40
- dbcli recover --next --after-step 1 --result '{"status":"ok","exitCode":0}'
41
- # 回傳 NextResult 信封:
42
- # {
43
- # "schemaVersion": 1,
44
- # "kind": "step",
45
- # "errorCode": "BLACKLIST_TABLE",
46
- # "cursor": 2,
47
- # "totalSteps": 3,
48
- # "step": { "order": 2, "command": "dbcli inspect --for-agent", ... }
49
- # }
50
- # 最後一步結束後,dbcli 回傳 kind: "done"。
51
- ```
52
-
53
- `--result` 接受 inline JSON `StepResultSummary`,或 `@<path>` 從檔案讀取。`stdoutSummary` 與 `stderrSummary` 各上限 4 KB — 請先把結果截到 **最後** 4 KB 再傳入。`--next` 與 `--apply` 互斥。每次呼叫獨立(不持久化 cursor)— 代理自行追蹤 `--after-step`。
54
-
55
- **連線錯誤分支。** 針對 `CONN_*` 代碼,envelope 會額外帶 `branches` 與 `branchFork`。步驟 1(`dbcli doctor --format json`)即為分支點:把 doctor JSON 透過 `--result.stdoutSummary` 傳入,`--next` 會挑選四個分支之一(`doctor-clean` / `doctor-config-missing` / `doctor-auth-error` / `doctor-network-error`)。NextResult 會帶 `branchId` 與 `branchDescription`;後續呼叫必須以 `--branch <id>` 走訪該分支。解析失敗或關鍵字不匹配時回落為線性 `recovery`。`--apply` 不使用 `branches`。
56
- 5. `dbcli blacklist list` — 敏感資料邊界。
57
- 6. `dbcli schema <table> --format json` — 取得真實欄位名稱(SQL / Mongo / ES)或 `schema <key>`(Redis)。**禁止猜測。**
58
- 7. 在允許的權限範圍內執行 `query` / `insert` / `update` / `delete` / `export`。
59
- 8. 所有寫入:`--dry-run`(SQL / Mongo)→ 實際執行 → `query` 回讀確認。
60
- - **v1.21.0 自我驗證循環(Self-Verification Loops)**:如果 snippet 在其 frontmatter 中定義了 `verify` 區塊,使用 `dbcli q @name --verify` 來執行該 snippet,即可自動跑完主要變更、執行驗證查詢並驗證斷言。
61
-
62
- 代理友善的輸出請優先用 `--format json`。
63
-
64
- ## Agent Task Packs(代理任務套件)
65
-
66
- 當使用者要求一個資料庫工作流(例如「診斷這個慢查詢」、「審計權限」、「審視長時間執行的操作」),優先選用已發布的任務模板,而非憑記憶自行組合步驟。
10
+ 如果 `dbcli` 執行檔不在 `PATH` 中,請以 `bunx @carllee1983/dbcli <command>` 作為指令前綴。這是 Codex plugin 安裝時的預期 fallback 方式 — skill 由 plugin 安裝,但 CLI 套件尚未全域安裝。
11
+
12
+ ## 如何使用 dbcli
13
+
14
+ **安全底線每次操作都要遵守:**
15
+
16
+ 1. `dbcli blacklist list`確認敏感資料邊界。
17
+ 2. `dbcli schema <object> --format json` 確認真實欄位名稱。**禁止猜測。**
18
+ 3. 所有寫入:`--dry-run`(SQL / Mongo)→ 實際執行 `query` 回讀確認。
19
+
20
+ > `report` 與 `guide` 已內嵌 `inspect` 快照 — **不需要**先跑 `dbcli inspect`。只有在需要 audit-recent 脈絡或診斷連線問題時,才手動跑 `dbcli inspect --for-agent`。
21
+
22
+ **依任務路由:**
23
+
24
+ | 任務 | 路徑 |
25
+ | --- | --- |
26
+ | 有名稱的工作流程符合(「診斷慢查詢」、「審計權限」) | `skill tasks list` → `skill tasks plan <pack>` **優先選用;不要自己組合步驟** |
27
+ | 固定診斷目標 | `guide <goal>`(`slow-query` / `capacity` / `health` / `index-usage` / `permissions` / `schema-overview`;`guide --list`) |
28
+ | 設定連線 | **連線設定** |
29
+ | 其他情況 | 手動執行指令;參考 **開發者工作流** 速查表 |
30
+
31
+ 慢查詢診斷有三條標準路徑(依已掌握的資訊選擇):
32
+
33
+ - 已知慢 SQL → `skill tasks plan diagnose-slow-query --param query="<SQL>"` → `guide missing-index-for "<SQL>"`
34
+ - 已知熱點資料表 `skill tasks plan analyze-table-perf --param table=<table>`
35
+ - 全環境掃描 → `report --section perf` → `guide slow-query`
36
+
37
+ `report --section perf` 已涵蓋 slow-query、index-usage cache-hit 診斷 — 之後只需補上它未涵蓋的 `@diag/*`(`missing-indexes`、`locks`、`connections`、`table-sizes`)。一旦鎖定特定慢語句,`explain --analyze "<SQL>"` 可顯示執行計畫。
38
+
39
+ **失敗時:** `query` / `q` / `insert` / `update` / `delete` / `export` / `schema` / `inspect` 加上 `--recovery`。指令會把 `RecoveryEnvelope` 輸出到 stdout 並儲存到 `.dbcli/last-recovery.json`;然後用 `dbcli recover` 檢視、`dbcli recover --apply` 在風險門控下執行儲存的計畫。Multi-turn `--next`、連線分支與 post-apply 驗證探針詳見 reference.md §Recovery Cookbook。
40
+
41
+ 回報驗證結果時使用詞彙:`verified`(證據符合)/ `not_verified`(驗證執行但結果矛盾)/ `indeterminate`(執行但證據不明確)/ `blocked`(因 config、權限、schema、placeholder 或安全閘門導致無法執行)。
42
+
43
+ 優先用 `--format json` 取得代理友善的輸出。
44
+
45
+ ## Agent Task Packs
46
+
47
+ 當使用者要求一個資料庫工作流(例如「診斷這個慢查詢」、「審計權限」、「審視長時間執行的操作」),**優先選用已發布的任務模板,而非憑記憶自行組合步驟。**
67
48
 
68
49
  ```bash
69
- dbcli skill tasks list --format json # 探索
70
- dbcli skill tasks show <task> # 檢視
71
- dbcli skill tasks plan <task> --param key=value --format json # 產生計畫
50
+ dbcli skill tasks list --format json # discover
51
+ dbcli skill tasks show <task> # inspect
52
+ dbcli skill tasks plan <task> --param key=value --format json # generate plan
72
53
  ```
73
54
 
74
55
  計畫輸出是一組附帶說明與風險標籤的 dbcli 指令序列。請逐一執行 — 任務計畫**不會**繞過 blacklist、schema、dry-run 或確認等要求。
75
56
 
76
- 內建套件:`diagnose-slow-query` 與 **(v1.23)** `analyze-table-perf` — 後者是 read-only 的 `plan-only` 套件,需帶入必填的 `table` 參數,依序執行 `blacklist list` → `schema <table> --format json` → `guide index-usage`。`dbcli inspect` 會針對近期 audit 活動中最熱門的資料表自動建議 `analyze-table-perf`。其他唯讀套件:`audit-permissions`、`safe-backfill`、`schema-drift-review`、`connection-health` — `dbcli skill tasks list` 瀏覽完整清單。
77
-
78
- 審查與驗證套件:`pr-database-review`(評估 PR 變更的查詢、遷移與 blacklist 風險)、
79
- `migration-review`(擷取變更前 schema 並預覽 DDL)、`safe-backfill-verify`(backfill 規劃
80
- 搭配 read-back `assert`),以及 `slow-endpoint-investigation`(串接 `proxy analyze` →
81
- `explain` → `guide missing-index-for`)。全部為唯讀 `plan-only` — 先選擇符合使用者情境的
82
- 套件再行動,任何索引/DDL 提案都應先經 `migration-review` 再寫入。
57
+ 內建套件:`diagnose-slow-query`(針對特定 SQL)、`analyze-table-perf`(針對特定資料表;`dbcli inspect` 會針對近期 audit 活動中最熱門的資料表自動建議此套件)、`audit-permissions`、`safe-backfill`、`schema-drift-review`、`connection-health`。審查與驗證套件:`pr-database-review`、`migration-review`、`safe-backfill-verify`、`slow-endpoint-investigation`。全部為唯讀 `plan-only`選擇符合使用者情境的套件,任何索引 / DDL 提案都應先經 `migration-review` 再寫入。
83
58
 
84
- 任務檔放在 `assets/tasks/`(內建)、`.dbcli-shared/tasks/`(共享)與 `.dbcli/tasks/`(本地覆寫)。
59
+ 任務檔放在 `assets/tasks/`(內建)、`.dbcli-shared/tasks/`(共享)與 `.dbcli/tasks/`(本地覆寫)。
85
60
 
86
61
  ## 開發者工作流
87
62
 
88
- 當資料庫影響隱含在開發任務中時使用這些流程。保留一般 dbcli 安全規則:優先使用 `--format json`,碰觸敏感資料前先跑 `blacklist list`,用 `schema` 確認名稱,寫入先 dry-run,失敗後使用 `--recovery` / `recover`。
63
+ 當資料庫影響隱含在開發任務中時使用這些流程。**如何使用 dbcli** 中的安全底線仍然適用。
89
64
 
90
- | 情境 | 使用 dbcli 的目的 | 最小安全路徑 |
91
- | --- | --- | --- |
92
- | DB-backed 功能 | 編輯程式碼前先把產品/程式語彙對應到真實資料物件。 | `inspect --for-agent` -> `blacklist list` -> `schema <object>` -> `queries suggest <intent>` |
93
- | 應用程式資料錯誤 | 分離資料庫事實與應用程式推論。 | `inspect --for-agent` -> `audit tail --for-agent --n 10` -> `blacklist list` -> `schema <object>` -> 最小查詢/snippet |
94
- | ORM 或 migration | 用 live schema 證據支撐 model 與 migration 修改。 | `schema --format json` -> `diff --snapshot <name>` -> `migrate add-index`/`add-column` 產生 DDL(預覽 SQL)-> `diff --against <snapshot>` |
95
- | PR 資料庫風險審查 | 檢查 query、write、migration、export、fixture 與 blacklist 風險。 | 審查變更的 persistence path,並針對每個重要主張提出具體 `schema`、`plan`、`dry-run`、`report` 或 `guide` 指令。 |
96
- | 慢 endpoint 或查詢 | 在提出 index 前優先使用 read-only diagnostics。 | `report --section perf` -> task pack `analyze-table-perf` -> `guide missing-index-for "<query>"`;有 proxy log 時使用 `proxy analyze`。 |
97
- | 安全資料回填 | 先界定受影響資料範圍並預覽 mutation。 | `blacklist list` -> `schema <object>` -> count/scope query -> `update ... --dry-run` -> read-back 或 snippet `--verify`。 |
98
- | 環境設定驗證 | 不洩漏 secrets 地檢查 config shape 與 connectivity。 | `status --format json` -> `doctor --format json` -> `inspect --for-agent --no-connect --format json`。 |
99
-
100
- 可直接複製的指令錨點:
65
+ | 情境 | 最小安全路徑 |
66
+ | --- | --- |
67
+ | DB-backed 功能 | `blacklist list` `schema <object>` `queries suggest <intent>` |
68
+ | 應用程式資料錯誤 | `audit tail --for-agent --n 10` `blacklist list` `schema <object>` 最小查詢 |
69
+ | ORM 或 migration | `schema --format json` `diff --snapshot <name>` `migrate add-index`/`add-column`(預覽 SQL)→ `diff --against <snapshot>` |
70
+ | PR 資料庫風險審查 | 審查變更的 persistence path,並針對每個重要主張提出具體 `schema`、`plan`、`dry-run`、`report` 或 `guide` 指令。 |
71
+ | 慢 endpoint 或查詢 | `report --section perf` task pack `analyze-table-perf` `guide missing-index-for "<query>"`;有 proxy log 時使用 `proxy analyze`。 |
72
+ | 安全資料回填 | `blacklist list` `schema <object>` count/scope query `update --dry-run` read-back 或 snippet `--verify`。 |
73
+ | 環境設定驗證 | `status --format json` `doctor --format json` `inspect --for-agent --no-connect`。 |
101
74
 
102
75
  ```bash
103
76
  dbcli inspect --for-agent --format json
@@ -105,370 +78,277 @@ dbcli blacklist list --format json
105
78
  dbcli schema <object> --format json
106
79
  dbcli queries suggest <intent> --format json
107
80
  dbcli audit tail --for-agent --n 10
108
- dbcli schema --format json
109
81
  dbcli diff --snapshot <name>
110
- dbcli migrate add-index <table>
111
- dbcli diff --against <snapshot>
112
82
  dbcli report --section perf --format json
113
83
  dbcli skill tasks plan analyze-table-perf --param table=<table> --format json
114
84
  dbcli guide missing-index-for "<query>" --format json
115
- dbcli proxy analyze --format json
116
- dbcli query "<count/scope query>" --format json
117
85
  dbcli update <object> --where "<bounded predicate>" --set '<json>' --dry-run --format json
118
- dbcli status --format json
119
- dbcli doctor --format json
120
86
  dbcli inspect --for-agent --no-connect --format json
121
87
  ```
122
88
 
123
- 開發者工作流守門規則:
89
+ 守門規則:
124
90
 
125
- - 不要猜測 table、collection、key、index 或 field 名稱。先用 `schema` 確認,再編寫依賴這些名稱的程式碼。
126
- - 分離資料庫事實與應用程式推論。回報是哪個 dbcli 輸出影響了程式修改或 review 結論。
127
- - 寫入與 backfill 必須包含 scope count、dry-run preview、execution command,以及 read-back 或 snippet verification
91
+ - 不要猜測 table、collection、key、index 或 field 名稱。先用 `schema` 確認。
92
+ - 分離資料庫事實與應用程式推論;回報是哪個 dbcli 輸出影響了結論。
93
+ - 寫入與 backfill 必須包含 scope count、dry-run preview、execution command,以及 read-back。
128
94
  - 不要直接從 performance suggestion 建 index;應轉成經過 review 的 migration。
129
95
  - 不要列印 credentials、複製的連線字串或 blacklisted 值。
130
- - 若需持久化 read-back 斷言的結果佐證,執行 `assert ... --write-verification-artifact --verification-subject <kind:name>`(允許的 kind:`recovery`、`task-pack`、`assertion`、`migration`、`backfill`、`manual`)。
131
- - 檢視驗證佐證(唯讀):`dbcli verification summary --format json`
132
- (亦可用 `verification list` / `verification show <id>`)。以 `dbcli verification prune --older-than 30d` 回收舊文物(dry-run;加上 `--execute --force` 才刪除)。
133
- - `tasks plan safe-backfill-verify` — 當使用者只需要計畫時使用。
134
- - `verify safe-backfill` — 在真實 backfill 前(preflight)及執行後(`--after-write`)使用,需要持久佐證時必用。永不執行寫入。
135
- - `tasks plan migration-review` — 當使用者只需要 migration 計畫時使用(僅輸出計畫,不執行 DDL)。
136
- - `verify migration` — 預檢 schema migration(分析 DDL、執行防護),並在外部套用 migration 後(`--after-write`)記錄佐證。永不執行 DDL。
137
- - `verify rollback --kind <ddl|dml>` — 驗證「還原變更」是否讓資料庫回到先前狀態:preflight 透過 `--statement` 分析還原用的 `ALTER TABLE`(`--kind ddl`)或 `UPDATE`(`--kind dml`),並於外部套用後以 `--after-write` 記錄佐證。永不執行該語句。
138
- - `verification show <id>` — 引用最終文物。
139
-
140
- 完整旗標、每個指令的可貼上範例、`migrate` DDL、互動式 `shell` 與 MongoDB / Redis / ES 教學在 [reference.md](reference.md)(安裝時與本檔放在一起)。
96
+ - 持久化佐證:`assert --write-verification-artifact --verification-subject <kind:name>`;以 `verification summary` / `list` / `show <id>` 檢視。`verify safe-backfill` / `migration` / `rollback --kind <ddl|dml>` / `constraint --check <fk|not-null|unique|custom>` 系列執行 preflight + `--after-write` 驗證,**永不執行寫入**。完整旗標與每個指令的區塊詳見 reference.md。
141
97
 
142
98
  ## Audit Log 使用
143
99
 
144
- 當需要跨 session 或事後 forensics 重建工具歷史時,請優先使用 audit log,而非從零開始查詢 DB 狀態。
145
-
146
- **情境 1 — Session handoff(接手前一個 agent 的工作):**
100
+ session 歷史或失敗鑑識時,優先使用 audit log,而非重新查詢 live DB 狀態。
147
101
 
148
102
  ```bash
149
- dbcli audit tail --for-agent --n 10 # 最近 10 (JSON envelope)
150
- dbcli audit tail --all --for-agent --n 20 # 跨連線合併(D4)
103
+ dbcli audit tail --for-agent --n 10 # last N entries (JSON envelope, metadata-only)
104
+ dbcli audit show <id-prefix> # full entry by id prefix (≥4 chars)
105
+ dbcli audit show --recovery-ref <env-id> # find the entry that emitted an envelope
151
106
  ```
152
107
 
153
- 取回 agent-facing JSON envelope,包含 `session_id` / `engine` / `command` / `target` / `success`,協助新 agent 快速掌握前一段工作脈絡。技術細節:metadata-only,**不**包含原始 SQL body / cell / params(D3 鎖定)
154
-
155
- **情境 2 — Forensics(重建失敗現場):**
156
-
157
- ```bash
158
- dbcli recover --format json # 觀察 audit_recent 嵌入 + recovery_ref
159
- dbcli audit show <id-prefix> # 完整單筆 entry(≥4 字元 prefix)
160
- dbcli audit show --recovery-ref <envelope-id> # 反向找出觸發 envelope 的 audit entry
161
- ```
162
-
163
- `inspect` / `guide` / `recover` / `recover --apply` 的 agent JSON 內嵌 `audit_recent: AuditEntryBrief[]`(最近 5 筆),無須額外呼叫 audit CLI 即可看到歷史脈絡。Envelope 的 `audit_ref` 與 audit entry 的 `recovery_ref` 互為雙向指標。
164
-
165
- **完整雙向覆蓋(v1.20.1+):** `recovery_ref` / `audit_ref` 雙向連結已在所有支援 `--recovery` 的指令上佈線:`query`、`inspect`、`insert`、`update`、`delete`、`export`、`q`、`schema`。Agent 可透過 `dbcli audit tail --recovery-ref <id>` 從 envelope 反查 audit entry(反方向用 `dbcli audit show --recovery-ref <id>`)。v1.20.0 中 6 個 DML/DDL 指令的部分覆蓋缺口已於 v1.20.1 關閉。
166
-
167
- 詳細指令參考:[`reference.md`](./reference.md) §audit(英文)。完整 agent 復原 walkthrough(各錯誤碼 end-to-end 情境、`--next` 多輪逐步、envelope ⇄ audit pivot、risk gate cheat sheet)見 [`reference.md`](./reference.md) §Recovery Cookbook(英文)。
108
+ `inspect` / `guide` / `recover` agent JSON 內嵌 `audit_recent`(最近 5 筆)— 新 session 立即有歷史。Envelope 的 `audit_ref` audit entry 的 `recovery_ref` 互為雙向指標,可從任一方向 pivot。Audit 預設開啟(`audit.enabled = false` 可關閉);entry 僅含 metadata(不含 SQL body、`--param` 值或結果 cell),並在約 10 MB / 1000 筆時輪替。完整旗標:reference.md §audit
168
109
 
169
110
  ## 快速開始
170
111
 
171
112
  ```bash
172
- dbcli init # 建立 .dbcli 設定(自動解析 .env)
173
- dbcli schema # 掃描所有資料表 → .dbcli/schemas/
174
- dbcli query "SELECT * FROM users" # 執行 SQL(自動加上 LIMIT 1000)
113
+ dbcli init # Create .dbcli config (parses .env automatically)
114
+ dbcli schema # Scan all tables → .dbcli/schemas/
115
+ dbcli query "SELECT * FROM users" # Execute SQL (auto LIMIT 1000)
175
116
  ```
176
117
 
177
- 如果 `.dbcli` 尚未存在,請先走下方的 **連線設定** 流程,再碰 `schema` / `query`。
118
+ 如果 `.dbcli` 尚未存在,請先走下方的 **連線設定** 流程,再碰 `schema` / `query`。
178
119
 
179
- ## 連線設定(協助使用者把資料庫接上來)
120
+ ## 連線設定(協助使用者把資料庫接上來)
180
121
 
181
- 當使用者問「我要怎麼連到 X?」、「幫我把 dbcli 接到 staging DB」,或 `doctor` / `status` 回報缺失或無效的設定時,依此流程處理。
122
+ 當使用者問「我要怎麼連到 X?」、「幫我把 dbcli 接到 staging DB」,或 `doctor` / `status` 回報缺失或無效的設定時,依此流程處理。
182
123
 
183
- > **預設「引導」而非「直接執行」。** `init` 會把憑證寫到磁碟。**僅在** 使用者明確授權且確認過實際值後再代為執行。
184
- > 如果 `.dbcli` 中已含有 `{"$env": "..."}` 形式的環境變數參照,**不要** 為了「把它填好」而重跑 `init` — env-ref 形式是 CI / multi-env 的刻意設計。
124
+ > **預設「引導」而非「直接執行」。** `init` 會把憑證寫到磁碟。**僅在**使用者明確授權且確認過實際值後再代為執行。
125
+ > 如果 `.dbcli` 中已含有 `{"$env": "..."}` 形式的環境變數參照,**不要**為了「把它填好」而重跑 `init` — env-ref 形式是 CI / multi-env 的刻意設計。
185
126
 
186
- ### 決策樹(先問再寫)
127
+ ### 決策樹(先問再寫)
187
128
 
188
- 1. **一個 DB 還是多個環境?** 一個 → v1(單一連線)。多環境 / tenant / replica → v2(`--conn-name <name>`,必要時搭配每個連線專屬的 `--env-file <path>`)。
189
- 2. **憑證放在哪裡?**
190
- - 已在 `.env`(`DATABASE_URL` 或 `DB_HOST` / `DB_PORT` / `DB_USER` /
191
- `DB_PASSWORD` / `DB_NAME` | `DB_DATABASE`)→ `init` 自動解析。
192
- - 機密需要排除在 `.dbcli` 之外(CI/CD、multi-env)→ 使用 `--use-env-refs`,
193
- 並搭配 `--env-host` / `--env-port` / `--env-user` / `--env-password` / `--env-database`。
194
- - 可以直接放明文 → 傳 `--host` / `--port` / `--user` / `--password` / `--name`(與 `--system`)。
195
- 3. **要哪一個權限層?** 預設取**最低**夠用的:
196
- `query-only` → `read-write` → `data-admin` → `admin`。透過 `--permission` 設定。
197
- 4. **驗證、不要假設。** init 結束後跑 `dbcli status`(系統 + 權限 + blacklist 摘要、不含憑證)與 `dbcli doctor --format json`(env、設定形狀、連線、schema-cache 年齡、Mongo SRV 路徑)。
129
+ 1. **一個 DB 還是多個環境?** 一個 → v1(單一連線)。多環境 / tenant / replica → v2(`--conn-name <name>`,必要時搭配每個連線專屬的 `--env-file <path>`)。
130
+ 2. **憑證放在哪裡?**
131
+ - 已在 `.env`(`DATABASE_URL` 或 `DB_HOST` / `DB_PORT` / `DB_USER` /
132
+ `DB_PASSWORD` / `DB_NAME` | `DB_DATABASE`)→ `init` 自動解析。
133
+ - 機密需要排除在 `.dbcli` 之外(CI/CD、multi-env)→ `--use-env-refs`(見下方)。
134
+ - 可以直接放明文 → 傳 `--host` / `--port` / `--user` /
135
+ `--password` / `--name`(與 `--system`)。
136
+ 3. **要哪一個權限層?** 預設取**最低**夠用的:
137
+ `query-only` → `read-write` → `data-admin` → `admin`。透過 `--permission` 設定
138
+ (預設 `query-only`)。
139
+ 4. **驗證、不要假設。** init 結束後跑 `dbcli status`(系統 + 權限 + blacklist 摘要、不含憑證)與 `dbcli doctor --format json`(env、設定形狀、連線、schema-cache 年齡、Mongo SRV 路徑)。
198
140
 
199
141
  ### 每個引擎的必備指令
200
142
 
201
143
  ```bash
202
- # PostgreSQL / MySQL / MariaDB(v1,明文值)
144
+ # PostgreSQL / MySQL / MariaDB (v1, plain values)
203
145
  dbcli init --system postgresql --host localhost --port 5432 \
204
146
  --user app --password '<secret>' --name appdb --permission query-only
205
147
 
206
- # 重用既有 .env(DATABASE_URL=postgresql://user:pw@host:5432/db)
207
- dbcli init # 解析 cwd .env
148
+ # Reuse an existing .env (DATABASE_URL=postgresql://user:pw@host:5432/db)
149
+ dbcli init # parses .env in cwd
208
150
 
209
- # MongoDB — 完整 URI(Atlas / replica sets / authSource)
151
+ # MongoDB — full URI (Atlas / replica sets / authSource)
210
152
  dbcli init --system mongodb \
211
153
  --uri "mongodb+srv://user:pw@cluster.example.mongodb.net/mydb?authSource=admin"
212
- # MongoDB — 分項參數(無認證 = 省略 --user / --password)
154
+ # MongoDB — discrete params (no auth = omit --user/--password)
213
155
  dbcli init --system mongodb --host localhost --port 27017 --name mydb
214
156
 
215
- # Redis — `--name` LOGICAL DB INDEX("0".."15"),不是資料庫名稱
157
+ # Redis — `--name` is the LOGICAL DB INDEX ("0".."15"), not a database name
216
158
  dbcli init --system redis --host localhost --port 6379 --password '<secret>' --name 0
217
159
 
218
- # Elasticsearch — basic authCloud ID API key
160
+ # Elasticsearch — basic auth, Cloud ID, or API key
219
161
  dbcli init --system elasticsearch --host localhost --port 9200 \
220
162
  --user elastic --password '<secret>'
221
163
  dbcli init --system elasticsearch \
222
164
  --cloud-id "myCluster:dXMtZWFzdC0xLmF3..." --api-key "<base64>"
223
- # Multi-node / 自訂 CA / 自簽:請直接編輯 `.dbcli`,加上
224
- # `nodes: [...]`、`protocol: https`、`caPath`、`rejectUnauthorized: false`。
165
+ # Multi-node / custom CA / self-signed: edit `.dbcli` directly to add
166
+ # `nodes: [...]`, `protocol: https`, `caPath`, `rejectUnauthorized: false`.
225
167
  ```
226
168
 
227
- ### Multi-connection(v2 多連線)
169
+ ### 多連線(v2
228
170
 
229
171
  ```bash
230
172
  dbcli init --conn-name staging --env-file .env.staging --permission query-only
231
173
  dbcli init --conn-name prod --env-file .env.production --use-env-refs --skip-test
232
- dbcli use --list # 顯示所有連線,* 標示預設
233
- dbcli use prod # 切換預設
234
- dbcli query --use staging "SELECT 1" # 單次覆寫
235
- dbcli init --rename staging:stg # 重新命名
236
- dbcli init --remove stg # 移除
174
+ dbcli use --list # show all, * marks default
175
+ dbcli use prod # switch default
176
+ dbcli query --use staging "SELECT 1" # one-shot override on any subcommand
177
+ dbcli init --rename staging:stg # rename
178
+ dbcli init --remove stg # remove
237
179
  ```
238
180
 
239
- 每個連線的 schema cache 存於 `.dbcli/schemas/<connection>/`。在 `schema <table>` 前,每個連線都先跑一次 `dbcli schema --use <name>` — 否則 cache 可能回傳到其他連線的欄位。
181
+ 每個命名連線的 schema cache 存於 `.dbcli/schemas/<connection>/`。在 `schema <table>` 前,每個連線都先跑一次 `dbcli schema --use <name>` — 否則 cache 可能回傳到別的連線欄位。`schema --refresh` / `--reset` 管理 cache(reference.md)。`--skip-test` 跳過 init 時的 TCP 連線測試;使用 `--use-env-refs` 時會自動隱含(`$env` refs 尚無值可連線)。`--system` 在 v2 中為選填 — 若省略,引擎會從 `--env-file` / `.env`(`DATABASE_URL` scheme)推斷,預設為 `postgresql`。
182
+
183
+ ### env-refs(把機密排除在 `.dbcli` 之外)
240
184
 
241
- ### env-refs(把機密排除在 `.dbcli` 之外)
185
+ `{ "$env": "VAR" }` 參照形式儲存憑證,在執行時解析,永不以明文存放:
242
186
 
243
187
  ```bash
244
- dbcli init --use-env-refs \
245
- --env-host DB_HOST --env-port DB_PORT \
246
- --env-user DB_USER --env-password DB_PASSWORD --env-database DB_NAME
188
+ # Default key names: DB_HOST / DB_PORT / DB_USER / DB_PASSWORD / DB_DATABASE
189
+ dbcli init --use-env-refs
190
+
191
+ # Non-default key names — name each one explicitly (required in CI):
192
+ dbcli init --conn-name prod --env-file .env.production --use-env-refs --skip-test \
193
+ --env-host PROD_DB_HOST --env-port PROD_DB_PORT \
194
+ --env-user PROD_DB_USER --env-password PROD_DB_PASSWORD --env-database PROD_DB_NAME
247
195
  ```
248
196
 
249
- 會以 `{ "$env": "DB_HOST" }` 等形式存入,並在執行時解析。搭配 `--env-file <path>`(v2)讓每個連線有自己的 env 檔。
197
+ 在**互動式終端機**中,省略 `--env-*` 旗標會逐一提示輸入 key 名稱(預設如上)— 可輸入非預設名稱如 `PROD_DB_PASSWORD`,它會以 `$env` ref 形式儲存。在**非互動式 / CI** 環境中,**必須**傳齊全部五個 `--env-*` 旗標;否則 `init` 會以錯誤退出 — 不會靜默 fallback 為明文。`--env-file <path>` env 檔路徑,與 `$env` key 名稱無關。
250
198
 
251
199
  ### 常見陷阱
252
200
 
253
- - **MongoDB `mongodb+srv://`** — `dbcli doctor` 會回報 SRV 是用原生方式解析還是走 DoH fallback;在執行環境限制 DNS 時很有用。
254
- - **MySQL/Postgres 密碼含 `@` `:` `/`** — 使用 `DATABASE_URL` 時要 percent-encode(`@` → `%40`);分項的 `--password` 旗標不需編碼。
255
- - **Redis `--name`** — 僅接受 logical DB index 字串;非數字會被拒絕。
256
- - **Elasticsearch TLS** — `caPath` 與 `rejectUnauthorized` 沒有對應旗標;`init` 後直接編輯 `.dbcli` 加上。
257
- - **重跑 `init`** — 沒有 `--force` 拒絕覆寫;千萬不要為了「修好」一個含 `{ "$env": "..." }` 參照的設定而用 `--force`。
201
+ - **MongoDB `mongodb+srv://`** — `dbcli doctor` 回報 SRV 是用原生方式解析還是走 DoH fallback;在執行環境限制 DNS 時很有用。
202
+ - **MySQL/Postgres 密碼含 `@` `:` `/`** — 使用 `DATABASE_URL` 時要 percent-encode(`@` → `%40`);分項的 `--password` 旗標不需編碼。
203
+ - **Redis `--name`** — 僅接受 logical DB index 字串;非數字會被拒絕。
204
+ - **Elasticsearch TLS** — `caPath` 與 `rejectUnauthorized` 沒有對應旗標;`init` 後直接編輯 `.dbcli` 加上。
205
+ - **重跑 `init`** — 沒有 `--force` 拒絕覆寫;千萬不要為了「修好」一個含 `{ "$env": "..." }` 參照的設定而用 `--force`。
258
206
 
259
207
  完整旗標與邊界案例見 [reference.md](reference.md) `init` 段落。
260
208
 
261
209
  ## 指令總覽 (Command overview)
262
210
 
263
- | 指令 | 最低權限 | 摘要 |
211
+ | Command | Min permission | Summary |
264
212
  |---------|-----------------|---------|
265
- | `init` | n/a | 建立 `.dbcli`(v1 單一或 v2 多連線,透過 `--conn-name` / `--env-file`)。**通常由真人執行** — 不要為了清掉 `{"$env"}` 參照而重跑;該格式是刻意設計。 |
266
- | `use` | n/a | 顯示 / 切換預設命名連線(僅 v2)。 |
267
- | `list` | query-only+ | 資料表(SQL)、collections(MongoDB)、keys(Redis)或 indices(Elasticsearch)。 |
268
- | `schema` | query-only+ | SQL:單表或全掃描存入 `.dbcli/schemas/`。MongoDB:sampled。ES:flattened mapping。Redis:僅單一 key(type / TTL / size)。支援 `--recovery`。 |
269
- | `query` | query-only+ | SQL、Mongo JSON(`--collection`)、Redis 指令、ES DSL / Lucene(`--collection`)。`--format table\|json\|csv\|html`、`--ui` 開啟瀏覽器互動式 dashboard。支援 `--recovery`。 |
270
- | `explain` | query-only+ | **(v1.23)** 唯讀查詢計畫並附註解。僅 SQL。單一查詢、`@saved-query`、`@file.sql` 或 `--bulk @glob/*`。`--analyze`(EXPLAIN ANALYZE / MariaDB ANALYZE SELECT)、`--format markdown\|json\|table`。 |
271
- | `plan` | n/a | 靜態 SQL 風險分析器(`--format text\|json`);不連線即可分類語句。 |
213
+ | `init` | n/a | 建立 `.dbcli`(v1 單一或 v2 多連線,透過 `--conn-name` / `--env-file`)。**通常由真人執行** — 不要為了清掉 `{"$env"}` 參照而重跑;該格式是刻意設計。 |
214
+ | `use` | n/a | 顯示 / 切換預設命名連線(僅 v2)。 |
215
+ | `list` | query-only+ | 資料表(SQL)、collectionsMongoDB)、keysRedis)或 indicesElasticsearch)。 |
216
+ | `schema` | query-only+ | SQL:單表或全掃描存入 `.dbcli/schemas/`。MongoDBsampled。ESflattened mapping。Redis:僅單一 keytype / TTL / size)。支援 `--recovery`。 |
217
+ | `query` | query-only+ | SQL、Mongo JSON(`--collection`)、Redis 指令、ES DSL / Lucene(`--collection`)。`--format table\|json\|csv\|html`、`--ui` 開啟瀏覽器互動式 dashboard。支援 `--recovery`。 |
218
+ | `explain` | query-only+ | **(v1.23)** 唯讀查詢計畫並附註解。僅 SQL。單一查詢、`@saved-query`、`@file.sql` 或 `--bulk @glob/*`。`--analyze`(EXPLAIN ANALYZE / MariaDB ANALYZE SELECT)、`--format markdown\|json\|table`。 |
219
+ | `plan` | n/a | 靜態 SQL 風險分析器(`--format text\|json`);不連線即可分類語句。 |
272
220
  | `q` | query-only+ | 以 `@name` 執行已儲存 snippet,搭配 `--param k=v`。支援 `--verify` 以執行斷言。 |
273
- | `queries` | n/a | 管理已儲存 snippet:`list` / `show` / `search` / `suggest` / `new` / `edit` / `check` / `delete` / `rename` / `copy` / `import` / `export`。 |
274
- | `insert` / `update` | read-write+ | 僅 SQL 與 MongoDB。JSON `--data` / `--set`;`update` 必填 `--where`;先 `--dry-run`。Redis 寫入透過 `query`。支援 `--recovery`。 |
275
- | `delete` | data-admin+ | 僅 SQL 與 MongoDB。必填 `--where`;先 `--dry-run`。支援 `--recovery`。 |
276
- | `export` | query-only+ | SQL MongoDB。Query → `--format json\|jsonl\|csv\|html` 檔案或 stdout。`html` 輸出獨立可互動 dashboard。支援 `--recovery`。 |
277
- | `blacklist` | n/a | `list` / `table` / `column` 子指令,從查詢結果中遮蔽敏感資料。 |
278
- | `check` | query-only+ | 僅 SQL(在 MySQL / MariaDB 最佳)。 |
221
+ | `queries` | n/a | 管理已儲存 snippet:`list` / `show` / `search` / `suggest` / `new` / `edit` / `check` / `delete` / `rename` / `copy` / `import` / `export`。 |
222
+ | `insert` / `update` | read-write+ | 僅 SQL 與 MongoDB。JSON `--data` / `--set`;`update` 必填 `--where`;先 `--dry-run`。Redis 寫入透過 `query`。支援 `--recovery`。 |
223
+ | `delete` | data-admin+ | 僅 SQL 與 MongoDB;Redis 有基本實作(見 Redis 段落)。必填 `--where`;先 `--dry-run`。支援 `--recovery`。 |
224
+ | `export` | query-only+ | SQL、MongoDB **(v1.22)** Elasticsearch(DSL `--index` 或全 index scroll)。Query → `--format json\|jsonl\|csv\|html` 檔案或 stdout。`html` 輸出獨立可互動 dashboard。支援 `--recovery`。 |
225
+ | `blacklist` | n/a | `list` / `table` / `column` 子指令,從查詢結果中遮蔽敏感資料。 |
226
+ | `check` | query-only+ | 僅 SQL(在 MySQL / MariaDB 最佳)。 |
279
227
  | `diff` | query-only+ | 僅 SQL。儲存 / 比較 schema snapshot。 |
280
- | `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` 的基準。 |
281
- | `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>`。 |
282
- | `verification` | n/a | 檢視與管理本機驗證 artifact。`list`/`show`/`summary` 為唯讀檢視;`prune` 預設 dry-run,僅在 `--execute --force` 時刪除。讀取 `<cwd>/.dbcli/verification/`;不需 DB 連線,不寫入 audit log。 |
283
- | `proxy` | n/a | **(v1.26)** 僅 MySQL/MariaDB/PostgreSQL。本地端開發觀測代理 — 中繼應用程式流量至真實資料庫,並將查詢 / 延遲 / 位元組 / 錯誤事件附加到 `.dbcli/proxy/events.jsonl`。子指令:`mysql` \| `mariadb` \| `postgresql`。`--listen`、`--target`、`--events`(預設 `.dbcli/proxy/events.jsonl`)、`--slow-ms`(預設 `1000`)、`--redact none\|literals`(預設 `none`)。僅作觀測,不改寫或封鎖。 |
284
- | `status` | query-only+ | 安全 JSON / 文字摘要(不含憑證)。 |
285
- | `inspect` | query-only+ | 唯讀脈絡快照(連線、權限、blacklist、物件、snippets、建議指令)。`--for-agent` / `--no-connect` / `--require-schema-cache`。支援 `--recovery`。 |
286
- | `report` | query-only+ | 以 `@diag/*` snippet 組成的診斷報告(health / capacity / perf)。`--section`、`--brief`、`--for-agent`、`--no-connect`。 |
287
- | `guide` | query-only+ | 針對固定目標產出確定性下一步指令計畫(`slow-query`、`capacity`、`health`、`index-usage`、`permissions`、`schema-overview`)。`--list` 列舉所有目標。 |
288
- | `recovery` | n/a | 對已知錯誤代碼查詢結構化 `RecoveryEnvelope`(`--code <CODE>` 或 `--list`)。獨立合成器;不需真實失敗。 |
289
- | `recover` | n/a | 檢視(預設)或 `--apply` 執行 `.dbcli/last-recovery.json` 中自動儲存的復原計畫。`--allow-write=readonly-cmd\|write-cmd`、`--no-verify`、`--from <file>`、`--next --after-step <n> --result <json\|@file>` 多輪逐步執行。 |
290
- | `doctor` | n/a | 環境、設定、連線、SRV 診斷(Mongo)、schema cache 年齡。 |
228
+ | `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` 的基準。 |
229
+ | `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>`。 |
230
+ | `verification` | n/a | 檢視與管理本機驗證 artifact。`list` / `show <id-or-path>` / `summary` 為唯讀;`prune` 預設 dry-run,僅在 `--execute --force` 時刪除。讀取 `<cwd>/.dbcli/verification/`;不需 DB 連線,不寫入 audit log。 |
231
+ | `proxy` | n/a | **(v1.26)** 僅 MySQL/MariaDB/PostgreSQL。本地端開發觀測代理 — 中繼應用程式流量至真實資料庫,並將查詢 / 延遲 / 位元組 / 錯誤事件附加到 `.dbcli/proxy/events.jsonl`。子指令:`mysql` \| `mariadb` \| `postgresql`。`--listen`、`--target`、`--events`、`--slow-ms`(預設 `1000`)、`--redact none\|literals`。僅作觀測。**(v1.27)** `proxy analyze` 離線彙整事件 log 為 JSON / 文字報表(summary、byFingerprint 含 suggestedCommands、slowest、errors、hotTables、N+1)— 若無事件則報錯。 |
232
+ | `status` | query-only+ | 安全 JSON / 文字摘要(不含憑證)。 |
233
+ | `inspect` | query-only+ | 唯讀脈絡快照(連線、權限、blacklist、物件、snippets、建議指令,以及 **(v1.23)** 人類可讀 `hints`)。`--for-agent` / `--brief` / `--no-connect` / `--require-schema-cache`。支援 `--recovery`。 |
234
+ | `report` | query-only+ | 以 `@diag/*` snippet 組成的診斷報告。`--section <health\|capacity\|perf>`(可用逗號組合)、`--brief`、`--for-agent`、`--no-connect`。 |
235
+ | `guide` | query-only+ | 針對固定目標產出確定性下一步指令計畫(`slow-query`、`capacity`、`health`、`index-usage`、`permissions`、`schema-overview`)。`--list` 列舉所有目標。**(v1.23)** `guide missing-index-for <query>` 為單一 SELECT 建議複合索引(`--format yaml\|json\|markdown`、`--min-confidence`)。 |
236
+ | `recovery` | n/a | 對已知錯誤代碼查詢結構化 `RecoveryEnvelope`(`--code <CODE>` 或 `--list`)。獨立合成器;不需真實失敗。 |
237
+ | `recover` | n/a | 檢視(預設)或 `--apply` 執行 `.dbcli/last-recovery.json` 中自動儲存的復原計畫。`--allow-write=readonly-cmd\|write-cmd`、`--no-verify`、`--from <file>`、`--next --after-step <n> --result <json\|@file>` 多輪逐步執行。 |
238
+ | `doctor` | n/a | 環境、設定、連線、SRV 診斷(Mongo)、schema cache 年齡。 |
291
239
  | `completion` | n/a | bash / zsh / fish 腳本。 |
292
- | `upgrade` | n/a | 從 npm 自我更新;每個指令都帶 24h 快取的版本提示。 |
293
- | `shell` | (與 query 同) | 互動式 REPL。支援 SQL 引擎、MongoDB 與 Redis(單行;`.no-limit on/off`) |
294
- | `skill` | n/a | 產出 / 安裝 AI skill 文件(`--install <claude\|gemini\|antigravity\|copilot\|cursor\|codex\|windsurf>`);`skill tasks list/show/plan` 提供 Agent Task Packs;`skill context` 提供 LLM 提示詞脈絡載荷。 |
295
- | `migrate` | admin | 僅 SQL。**DDL;預設 dry-run** — 需 `--execute` 才會真的執行。 |
240
+ | `upgrade` | n/a | 從 npm 自我更新;每個指令都帶 24h 快取的版本提示。 |
241
+ | `shell` | (與 query 同) | 互動式 REPLSQL 引擎、MongoDB 與 Redis(單行;`.no-limit on/off`)。**(v1.22)** Elasticsearch 開啟 Kibana Dev Tools 風格的 REPL(`<METHOD> /<path>` + 可選 JSON body,空白行送出)。 |
242
+ | `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,正常操作不需要)。 |
243
+ | `migrate` | admin | 僅 SQL。**DDL;預設 dry-run** — 需 `--execute`。 |
244
+
245
+ 任何子指令上的 `--use <name>` 可在不改變預設值的情況下,把目標切到 v2 連線。`--recovery` 被 `query`、`q`、`insert`、`update`、`delete`、`export`、`schema` 與 `inspect` 支援(見上方**失敗時**)。
246
+
247
+ **寫入與查詢旗標語意**(SQL / Mongo `insert`/`update`):
296
248
 
297
- 任何子指令上的 `--use <name>` 都會把目標切到對應的 v2 連線,但不改變預設值。
298
- `--recovery` `query`、`q`、`insert`、`update`、`delete`、`export`、`schema` `inspect` 支援;失敗時這些指令會把 `RecoveryEnvelope` JSON 輸出到 stdout、抑制人類可讀的 stderr 訊息,並原子性地把信封寫入 `.dbcli/last-recovery.json` `dbcli recover` 使用。
249
+ - `--set`(update)/ `--data`(insert)接受 **JSON 物件字串**,而非 SQL 片段:`dbcli update users --where "id=42" --set '{"email":"new@example.com"}'`。MongoDB 中,不含 `$` 運算子的 JSON 會自動包裝為 `$set`;明確傳入的運算子則直接傳遞。`insert --data` 也可從 stdin 讀取物件。
250
+ - `--where`(SQL)僅接受 `col=val` `col1=val1 AND col2=val2` **不**支援完整 SQL(不支援 `>=`、`!=`、`LIKE`、`OR`)。MongoDB `--where` 接受完整 JSON filter(`'{"status":"pending"}'`),若不是合法 JSON 則 fallback 為 `col=val`。
251
+ - `--dry-run` 輸出參數化 SQL(使用 `$1` / `?` 佔位符,非真實值)與 `rows_affected: 0`;確認 `status:"success"` 且 SQL 形狀符合預期的 `--where` / `--set` 後再執行。MongoDB 輸出 shell 風格預覽。
252
+ - `--recovery` 建議用於自動化 agent pipeline(讓失敗後可執行 `dbcli recover --apply`);手動一次性寫入可選用。
299
253
 
300
254
  ## 權限等級 (Permission levels)
301
255
 
302
- | 等級 | 允許的操作 |
256
+ | Level | Allowed |
303
257
  |-------|---------|
304
258
  | query-only | SELECT、list、schema、export |
305
259
  | read-write | + INSERT、UPDATE |
306
- | data-admin | + DELETE(DML,不含 DDL) |
307
- | admin | + 透過 `migrate` 執行 DDL,以及破壞性操作 |
308
-
309
- ## Multi-connection(v2 多連線)
310
-
311
- - 每個命名連線都有自己的 schema 目錄:`.dbcli/schemas/<connection>/`。
312
- - 在 `schema <table>` 之前,每個連線都先跑一次 `dbcli schema --use <name>` — 否則 cache 可能回傳到別的連線欄位。
313
- - `schema --refresh` / `--reset` 管理 cache;詳見 reference.md。
260
+ | data-admin | + DELETEDML,不含 DDL |
261
+ | admin | + 透過 `migrate` 執行 DDL,以及破壞性操作 |
314
262
 
315
263
  ## MongoDB
316
264
 
317
- - JSON filter 物件(`find`)或 JSON 陣列(`aggregate`);SQL 會被拒絕。`query` 必填 `--collection <name>`。
318
- - **支援:** `init`、`list`、`schema`(sampled)、`query`、`insert`、`update`、`delete`、`export`、`q`(saved queries)、`status`、`use`、`shell`、`doctor`、`upgrade`、`completion`。
319
- - **不支援:** `diff`、`migrate`、`check`。
320
- - Schema `$sample` **採樣**(預設 100 份文件,上限 1000)。可加 `--sample-method natural` 改用 `find().limit()`。欄位以 dot-path 呈現(如 `profile.tokens.access`),附帶 `presence`(0..1)與命中黑名單時的 `redacted: true`。
321
- - **寫入規劃器分層:** `$set`/`$unset` → `ALLOW`;`$rename` → `WARN`(資訊提示);`$inc`/`$mul`/`$min`/`$max`/`$currentDate` → `WARN`;`$push`/`$pull`/`$pullAll`/`$pop`/`$addToSet` → `WARN`;`$bit` → `WARN`;`$where` 與未知運算子 → `BLOCK`。
322
- - **巢狀黑名單:** `blacklist.columns[<collection>]` 接受點分路徑(`profile.email`)與結尾萬用字元(`profile.tokens.*`);中間萬用字元會在 `dbcli blacklist list` 警告並略過。讀取路徑會將命中值取代為字串字面值 `[REDACTED]`。
323
- - **儲存查詢:** snippet 檔名以 `.mongodb.sql` 結尾。Frontmatter 必填 `engine: mongodb` 與 `operation: find` 或 `operation: aggregate`。`target: <collection>` 為預設集合,可由 `--collection` 覆蓋。主體為 JSON(`find` 為物件、`aggregate` 為陣列);`{{param}}` 佔位符會 JSON 編碼。
324
- - 完整語法與範例見 reference.md MongoDB 段落。
265
+ - `query` 接受 JSON filter 物件(`find`)或陣列(`aggregate`);SQL 會被拒絕。`--collection <name>` 在 `query` 上為必填。
266
+ - **支援:** `init`、`list`、`schema`(sampled)、`query`、`insert`、`update`、`delete`、`export`、`q`、`status`、`use`、`shell`、`doctor`。**不支援:** `diff`、`migrate`、`check`。
267
+ - Schema 由 `$sample` **採樣**(預設 100 份文件,上限 1000;`--sample-method natural` 改用 `find().limit()`)。欄位以 dot-path 呈現(如 `profile.tokens.access`),附帶 `presence`(0..1)與 `redacted` 旗標。
268
+ - 寫入:`--set` / `--data` JSON 在無 `$` 運算子時自動包裝為 `$set`;明確傳入的運算子(`$set`/`$inc`/`$push`/…)則直接傳遞。巢狀黑名單接受 dot-path(`profile.email`)與結尾萬用字元(`profile.tokens.*`)。Saved snippet 以 `.mongodb.sql` 結尾(frontmatter `engine: mongodb`,`operation: find|aggregate`)。完整寫入規劃分層與語法:reference.md MongoDB 段落。
325
269
 
326
270
  ## Redis
327
271
 
328
- - 指令式執行;`query` 跑白名單內的 Redis 指令(例如 `GET`、`HSET`、`DEL`)
329
- - **支援:** `init`、`list`(透過 SCAN 列 keys)、`schema <key>`(type / TTL / size / sample)、`query`、`shell`、`status`、`use`、`doctor`、`upgrade`、`completion`。
330
- - **不支援:** `schema` 全掃描、`insert`、`update`、`delete`、`export`、`check`、`diff`、`migrate`、`q`。
331
- 寫入請走 `query "DEL <key>"` 等 — 同樣經過權限門檻。
332
- - 權限分層對應指令:讀取類 `query-only`;mutator(`SET`、`HSET`、...)→ `read-write`;`DEL` / `UNLINK` `data-admin`。
333
- - `database` 欄位是 logical DB index(預設 `0`);`list` 透過 SCAN 最多回傳 100 000 個 keys。
334
- - **大小防護(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)略過。
335
- - **黑名單:** `dbcli blacklist add 'secrets:*'` 註冊 Redis 原生 key glob。命中規則的讀寫會被拒絕(`BlacklistRejection`,稽核記錄含 `metadata.matched_pattern`);與規則重疊的 `KEYS`/`SCAN MATCH` 會被拒絕;未重疊的列舉會濾掉黑名單 keys。
336
- - **Shell:** Redis 連線執行 `dbcli shell` 會開啟單行 REPL(歷史、指令與 key 前綴 tab 補全、`.no-limit on/off`)。
337
- - 詳見 reference.md Redis 段落。
272
+ - `query` 執行單一**白名單內**的 Redis 指令(如 `GET`、`SET`、`HSET`、`DEL`)。完整白名單與每個指令的權限層詳見 reference.md
273
+ - **支援:** `init`、`list`(透過 SCAN 列 keys)、`schema <key>`(type / TTL / size / sample)、`query`、`q`(saved snippet — **僅唯讀命令**)、`delete`(基本實作:`DEL` / `HDEL` / `LREM` / `SREM` / `ZREM`,需 `data-admin`;`query "DEL <key>"` 亦可)、`shell`、`status`、`use`、`doctor`。**不支援:** `schema` 全掃描、`insert`、`update`、`check`、`diff`、`migrate`。
274
+ - **權限分層:** 讀取類(`GET`/`HGET`/`SCAN`/…)→ `query-only`;mutator(`SET`/`HSET`/`INCR`/`EXPIRE`/`SETEX`/`RENAME`/…)→ `read-write`;`DEL`/`UNLINK`/`HDEL`/`XDEL` → `data-admin`。白名單外的指令一律拒絕。
275
+ - **Redis `query` `--dry-run`** — 寫入安全來自權限門檻與 key 黑名單(命中的讀寫會被拒絕)。如需預覽刪除,請用 `delete <key> --dry-run`。
276
+ - `database` logical DB index(預設 `0`)。`dbcli blacklist add 'secrets:*'` 註冊 key glob;可選的 `redis.mask` 區塊在讀取時遮罩值。大小防護(SCAN/HGETALL 截斷,`--no-limit` 可略過)與遮罩細節:reference.md Redis 段落。
338
277
 
339
278
  ## Elasticsearch
340
279
 
341
- - DSL(JSON body)或 Lucene query string;`query` 必填 `--collection <index>`。
342
- - **支援:** `init`、`list`(含文件數的索引清單)、`schema [index]`(flattened mapping)、`query`、`status`、`use`、`doctor`、`upgrade`、`completion`。
343
- - **不支援:** `insert`、`update`、`delete`、`export`、`check`、`diff`、`migrate`、`q`。
344
- 專屬寫入子指令尚未開放 若叢集允許,可用 `query` 或外部工具。
345
- - Query-only 模式上限 1000 hits;`--no-limit` 也僅放寬到 10 000。
346
- - Schema 會 flatten 巢狀欄位(`a.b.c`),並列出 `.fields` multi-fields。
347
- - 詳見 reference.md Elasticsearch 段落。
280
+ - `query` 接受 DSLJSON body)或 Lucene query string;`--collection <index>` 為必填。
281
+ - **支援:** `init`、`list`(含文件數的索引清單)、`schema [index]`(flattened mapping)、`query`、`export`(v1.22)、`shell`(v1.22)、`status`、`use`、`doctor`。**不支援:** `insert`、`update`、`delete`、`check`、`diff`、`migrate`。
282
+ - `export` 接受含 `--index <index>` 的 search DSL,或以 index 名稱作為查詢來透過 `match_all` scroll 整個 index。Query-only 上限 1000 hits;`--no-limit` 放寬至 10,000。
283
+ - Schema flatten 巢狀欄位(`a.b.c`),並列出 `.fields` multi-fields。`shell` 開啟 Kibana Dev Tools 風格的 REPL。完整語法與範例:reference.md Elasticsearch 段落。
348
284
 
349
- ## Saved queries(已儲存查詢)
285
+ ## Saved queries
350
286
 
351
- 執行可重用、帶參數的 SELECT 片段,存於你的 repo
287
+ 執行存放於 repo 中、可重用的參數化 snippet
352
288
 
353
- | 步驟 | 指令 |
289
+ | Step | Command |
354
290
  |------|---------|
355
- | 1. 探索 | `dbcli queries list` |
291
+ | 1. 探索 | `dbcli queries list`(或 `queries search <keywords>` / `queries suggest <intent>`) |
356
292
  | 2. 檢視 | `dbcli queries show @<name>` |
357
- | 3. 執行 | `dbcli q @<name> --param k=v` |
293
+ | 3. 執行 | `dbcli q @<name> --param k=v`(blacklist 永遠強制) |
358
294
 
359
- ### 不知道要跑哪一個 query
295
+ 常見 intent:`perf.slow-query`、`perf.cache-hit`、`capacity.size`、`safety.connections`、`monitor.cluster-health`。
360
296
 
361
- 1. `dbcli queries search <keywords>` 自然關鍵字、fuzzy 排序
362
- 2. `dbcli queries suggest <intent>` — 依類別瀏覽
363
- 常見 intent:perf.slow-query、perf.cache-hit、capacity.size、
364
- safety.connections、monitor.cluster-health
365
- 3. 找到後:`dbcli q @<name>`(blacklist 永遠強制)
297
+ Snippet 從三層解析,**local > shared > builtin**(本地優先):`builtin`(內建 `@diag/*`,唯讀)/ `.dbcli-shared/queries/`(團隊)/ `.dbcli/queries/`(個人)。透過 `queries new | edit | delete | rename | copy | import | export` 管理本地 snippet。每個 `.sql` 檔在 `-- ---` 區塊中宣告 YAML frontmatter(name、description、engine、params、tags、可選 `intent`、可選 `visual`)。
366
298
 
367
- Snippet 從三層解析,**local > shared > builtin**(本地優先):
368
- - `builtin` — 內建於 dbcli(例如 `@diag/*`);執行時唯讀
369
- - `.dbcli-shared/queries/` — 已 commit、團隊共享
370
- - `.dbcli/queries/` — 已 gitignore、個人覆寫
299
+ 每個引擎的 body 格式由 `engine` frontmatter 欄位決定:
371
300
 
372
- 管理本地 snippets 透過 `queries new | edit | delete | rename | copy | import | export`
373
- (見 reference.md)。用 `copy` / `import` 把 builtin 或 shared snippet fork 到本地層編輯。
374
-
375
- 每個 `.sql` 檔可在 `-- ---` 區塊中宣告 YAML frontmatter
376
- (name、description、engine、params、tags、可選 `intent`、可選 `visual`)。
377
- `visual:` 區塊驅動互動式 dashboard(見下方「互動式 HTML dashboard」)。
378
- 機器可讀契約見 `dbcli queries show @<name> --format json`。
379
-
380
- ### 每個引擎的 body 格式
381
-
382
- 每個 snippet 的 body 格式由 `engine` frontmatter 欄位決定:
383
-
384
- | 引擎 | Body 格式 | 備註 |
301
+ | Engine | Body format | Notes |
385
302
  |-------------------|------------------------|-------|
386
- | postgres / mysql | 單一 SELECT WITH | `:name` → driver bind(`$1` / `?`) |
387
- | elasticsearch | JSON DSL | `:name` → JSON-aware 取代;必填 `index:` |
388
- | redis | 單一 Redis 指令 | `:name` → raw text;僅允許讀取指令 |
303
+ | postgres / mysql | Single SELECT or WITH | `:name` → driver bind (`$1` / `?`) |
304
+ | elasticsearch | JSON DSL | `:name` → JSON-aware substitution; `index:` field required |
305
+ | redis | Single Redis command | `:name` → raw text; **only read commands allowed** |
389
306
 
390
- 跨家族的 `engine` 陣列(例如 `[postgres, elasticsearch]`)在 parse 階段就被拒絕。
307
+ 跨家族的 `engine` 陣列(如 `[postgres, elasticsearch]`)在 parse 階段就被拒絕。
391
308
 
392
309
  ### 內建診斷 snippets
393
310
 
394
- dbcli 內附現成的診斷查詢。用 `dbcli q @diag/<topic>` 執行:
395
-
396
- | key | 用途 |
397
- |-------------------------|-------------------------------------------|
398
- | `@diag/connections` | 活躍 session |
399
- | `@diag/long-running` | 超過 `min_seconds`(預設 30)的查詢 |
400
- | `@diag/table-sizes` | 帶 row 數的 table data / index 大小 |
401
- | `@diag/index-usage` | scan 次數排序的索引 |
402
- | `@diag/missing-indexes` | sequential scan 為主的資料表 |
403
- | `@diag/locks` | lock-wait chain |
404
- | `@diag/db-size` | 資料庫大小摘要 |
405
- | `@diag/cache-hit` | buffer cache 命中率 |
406
- | `@diag/es-cluster-health` | 每個 index 的文件數(ES 連線) |
407
- | `@diag/redis-key-stats` | keyspace 上的 SCAN 取樣(Redis 連線) |
408
-
409
- 依目前連線自動挑選引擎變體。把同名檔案放到 `.dbcli-shared/queries/`
410
- 或 `.dbcli/queries/` 即可覆寫任何一個。
311
+ `dbcli q @diag/<topic>` 執行(引擎變體依目前連線自動選取):
312
+
313
+ | key | purpose |
314
+ |-------------------------|------------------------------------------|
315
+ | `@diag/connections` | active sessions |
316
+ | `@diag/long-running` | queries above `min_seconds` (`--param min_seconds=N`, default 30) |
317
+ | `@diag/table-sizes` | table data/index size with row counts |
318
+ | `@diag/index-usage` | indexes by scan count |
319
+ | `@diag/missing-indexes` | tables dominated by sequential scans |
320
+ | `@diag/locks` | lock-wait chains |
321
+ | `@diag/db-size` | database size summary |
322
+ | `@diag/cache-hit` | buffer cache hit ratios |
323
+ | `@diag/es-cluster-health` | document counts per index (ES) |
324
+ | `@diag/redis-key-stats` | sample SCAN over keyspace (Redis) |
411
325
 
412
326
  ## 互動式 HTML dashboard
413
327
 
414
- `query`、`q` 與 `export` 可把結果渲染為獨立、自包含的 HTML 報表,由內建的 React + Recharts 模板(`assets/ui-template.html`)驅動,
415
- 經由硬化的 `window.__DBCLI_PAYLOAD__ = {...}` 區塊注入(`<` 會被跳脫以中和 `</script>` payload)。
328
+ `query`、`q` 與 `export` 可把結果渲染為獨立、自包含的 HTML 報表(內建 React + Recharts 模板)。
416
329
 
417
330
  ```bash
418
- # 在瀏覽器中開啟(先寫到 temp 檔,再 `open` / `xdg-open` / `start`)
419
- dbcli query "SELECT day, dau FROM dau_daily" --ui
420
- dbcli q @analytics/revenue --param days=30 --ui
421
-
422
- # 把 HTML pipe 到 stdout(CI 產出、email、靜態主機)
423
- dbcli query "SELECT * FROM orders" --format html > orders.html
424
-
425
- # 匯出到檔案(與 json / jsonl / csv 可互換)
331
+ dbcli query "SELECT day, dau FROM dau_daily" --ui # open in browser
332
+ dbcli query "SELECT * FROM orders" --format html > out.html # pipe HTML to stdout
426
333
  dbcli export "SELECT * FROM orders" --format html --output orders.html
427
334
  ```
428
335
 
429
- `--ui` 隱含 `--format html` 並開啟檔案;`--format html` 單獨使用則寫到 stdout。Blacklist 遮蔽在渲染**之前**套用 dashboard 永遠看不到被遮蔽的欄位。
430
-
431
- ### Snippet `visual:` 區塊
432
-
433
- 要在結果中得到 KPI 與圖表(而非僅 sortable table),請在 snippet 的 frontmatter 加上 `visual:` 區塊。column 名稱必須存在於結果列中。
434
-
435
- ```sql
436
- -- ---
437
- -- name: Revenue Trend
438
- -- engine: postgres
439
- -- params:
440
- -- days: { type: int, default: 30 }
441
- -- visual:
442
- -- title: Revenue (last :days days)
443
- -- kpis:
444
- -- - { label: Total Revenue, value_column: total_revenue, format: currency }
445
- -- - { label: Orders, value_column: order_count, format: number }
446
- -- - { label: Conversion, value_column: conv_rate, format: percent }
447
- -- charts:
448
- -- - { type: line, title: Daily Revenue, x: day, y: [revenue] }
449
- -- - { type: bar, title: By Channel, x: channel, y: [revenue, refunds] }
450
- -- ---
451
- SELECT ...
452
- ```
453
-
454
- - `kpis[].format`:`currency` / `number` / `percent`(省略即顯示原值)。
455
- - `charts[].type`:`line` / `bar` / `area` / `pie` / `scatter`。
456
- - 不走 snippet 的原始 `query` 指令只能渲染 sortable / filterable table — 沒有 `visual:` 可掛載。
336
+ `--ui` 隱含 `--format html` 並開啟檔案;`--format html` 單獨使用則寫到 stdout。Blacklist 遮蔽在渲染**之前**套用。若要取得 KPI 與圖表而非純 table,請在 snippet frontmatter 加上 `visual:` 區塊(`title`、`kpis[]`、`charts[]`)— 完整 `visual:` schema 見 reference.md。原始 `query` 呼叫只能渲染 sortable table。
457
337
 
458
338
  ## 常見工作流程
459
339
 
460
- - **除錯異常狀態:** `schema` → `check` → 帶緊湊 `WHERE` 的 `query` → 順著 schema JSON 的 FK 追蹤。證據先於理論。
461
- - **INSERT / UPDATE 之後:** `--dry-run` → 實際執行 → `query` 回讀;用 triggers、預設值或 blacklist 解釋落差。
462
- - **Migrations:** `diff --snapshot` → `migrate`(dry-run → `--execute`)→ `diff --against` → 對受影響資料表跑 `check`。DROP 需 `--force`。
463
- - **健康 / 成長:** `check --all`(除非加 `--include-large`,否則略過巨大表);做 ad-hoc query 前先看 schema 的 `sizeCategory`。
464
- - **從活線 DB 產生程式:** `schema --format json` 餵給 ORM;再用 `dbcli query` 交叉驗證一次。
465
- - **整合事實:** 前 `query` → 跑應用 → 後 `query`。單元測試 mock 不能替代。
466
- - **自然語言請求**(例如「把訂單更新為 shipped」):先決定要 `query` 還是 DML,透過 `schema` 把詞彙映到欄位(值用 enum),尊重 blacklist 與 `sizeCategory`,**寫入永遠先 `--dry-run`**。
340
+ - **除錯異常狀態:** `schema` → `check` → 帶緊湊 `WHERE` 的 `query` → 順著 schema JSON 的 FK 追蹤。證據先於理論。
341
+ - **INSERT / UPDATE 之後:** 依照**如何使用 dbcli**的寫入序列(`--dry-run` → 執行 → `query` 回讀);用 triggers、預設值或 blacklist 解釋落差。
342
+ - **Migrations:** `diff --snapshot` → `migrate`(dry-run → `--execute`)→ `diff --against` → 對受影響資料表跑 `check`。DROP 需 `--force`。
343
+ - **健康 / 成長:** `check --all`(除非加 `--include-large`,否則略過巨大表);做 ad-hoc query 前先看 schema 的 `sizeCategory`。
344
+ - **從活線 DB 產生程式:** `schema --format json` 餵給 ORM;再用 `dbcli query` 交叉驗證一次。
345
+ - **整合事實:** 前 `query` → 跑應用 → 後 `query`。單元測試 mock 不能替代。
346
+ - **自然語言請求**(如「把訂單更新為 shipped」):先決定要 `query` 還是 DML,透過 `schema` 把詞彙映到欄位(值用 enum 資料),尊重 blacklist 與 `sizeCategory`,**寫入永遠先 `--dry-run`**。
467
347
 
468
348
  ## 備註
469
349
 
470
- - Query-only 模式自動補 `LIMIT 1000`;查 `information_schema` 或會被 `LIMIT` 破壞的語句請加 `--no-limit`。
350
+ - Query-only 模式自動補 `LIMIT 1000`;查 `information_schema` 或會被 `LIMIT` 破壞的語句請加 `--no-limit`。
471
351
  - 被 blacklist 的 table / column 會從查詢輸出中遮蔽。
472
- - `schema` 回報 `estimatedRowCount` 與 `sizeCategory`(small / medium / large / huge)。大 / 巨大表要加 `WHERE` 或 `LIMIT` — 分界值見 reference.md。
473
- - 對 `mongodb+srv://` 連線,`doctor` 會回報 SRV 是用原生解析或走 DoH fallback — 在執行環境限制 DNS 時很有用。
474
- - **全域旗標:** `--config <path>`、`--use <name>`、`-v` / `-vv` / `-q`、`--no-color`(也尊重 `NO_COLOR`)。
352
+ - `schema` 回報 `estimatedRowCount` 與 `sizeCategory`(small / medium / large / huge)。大 / 巨大表要加 `WHERE` 或 `LIMIT` — 分界值見 reference.md。
353
+ - 對 `mongodb+srv://` 連線,`doctor` 會回報 SRV 是用原生解析或走 DoH fallback — 在執行環境限制 DNS 時很有用。
354
+ - **全域旗標:** `--config <path>`、`--use <name>`、`-v` / `-vv` / `-q`、`--no-color`(也尊重 `NO_COLOR`)。