@carllee1983/dbcli 1.7.0 → 1.9.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 +34 -0
- package/README.md +39 -1
- package/README.zh-TW.md +1 -1
- package/assets/SKILL.md +56 -17
- package/assets/reference.md +212 -4
- package/assets/tasks/README.md +30 -0
- package/assets/tasks/diagnose-slow-query.md +33 -0
- package/dist/cli.mjs +12757 -941
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,40 @@ 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
|
+
## [1.9.0] - 2026-05-06
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Agent Task Packs(plan-only 第一版)**:`dbcli skill tasks list/show/plan` 讓 AI agent 可探索團隊定義的資料庫任務範本並產生安全可審查的執行計畫。
|
|
13
|
+
- 三層儲存:`assets/tasks/`(內建)< `.dbcli-shared/tasks/`(團隊共享)< `.dbcli/tasks/`(個人覆蓋)。
|
|
14
|
+
- Task 檔為 `.md`:YAML frontmatter(name/description/tags/engines/params/safety/steps)+ markdown agent notes。
|
|
15
|
+
- 嚴格 schema:`safety.mode` 僅接受 `plan-only`、`step.type` 僅接受 `command`,未知欄位直接 fail 解析而非靜默忽略。
|
|
16
|
+
- `plan` 輸出包含原始 `command`、`resolvedCommand`、`argv`(shell-aware 切分),方便 agent 直接消費。
|
|
17
|
+
- 內建第一版 `diagnose-slow-query` 任務作為範例。
|
|
18
|
+
- 文件:`assets/SKILL.md` 與 `assets/reference.md` 同步加入 Agent Task Packs 章節;`docs/feature-matrix.md` 補充 `skill tasks` 子命令說明。
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- `src/core/saved-queries/yaml-mini.ts`:擴充支援 YAML block list 語法(`- scalar`、`- key: value` 起始的 sub-map),以承載 Agent Task Packs 的 frontmatter;既有 saved-queries 解析行為不變、66 個既有測試全綠。
|
|
23
|
+
|
|
24
|
+
## [1.8.0] - 2026-05-06
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
|
|
28
|
+
- **Redis 與 Elasticsearch 支援**:`init`、`list`、`schema`、`query`、`status`、`use`、`doctor`、`upgrade`、`completion` 在兩個系統皆真實可用。
|
|
29
|
+
- Redis:`list` 透過 SCAN 取 keys;`schema <key>` 顯示 type/TTL/size/sample;`query` 執行白名單 Redis 指令並走原本權限與黑名單檢查。
|
|
30
|
+
- Elasticsearch:`list` 顯示 indices 與文件數;`schema [index]` 攤平 mapping、揭露 `.fields` multi-fields;`query` 接受 DSL JSON 或 Lucene 字串。
|
|
31
|
+
- 文件:`assets/SKILL.md` 與 `assets/reference.md` 同步加入 Redis / Elasticsearch 章節。
|
|
32
|
+
|
|
33
|
+
### Fixed
|
|
34
|
+
|
|
35
|
+
- **`insert` / `update` / `delete` / `export` / `diff` 對 Redis / Elasticsearch 的早期錯誤訊息**:先前會落入 SQL DataExecutor 出現「Column ... not found in table」之類誤導訊息,現在直接回傳明確的「不支援」JSON,並指引正確替代路徑(Redis 改用 `query`、Elasticsearch 改用外部工具或 `query --index`)。
|
|
36
|
+
- **TypeScript 嚴格度**:`bun run typecheck` 從 43 個錯誤降為 0。
|
|
37
|
+
- `ConnectionConfig` union 加入 `ElasticsearchConnectionConfig`。
|
|
38
|
+
- `ResolvedConnection.connection.system`、`ReplContext.system` 涵蓋 `'elasticsearch'`。
|
|
39
|
+
- `ExecutionResult` 補上 optional `rowCount` / `columnNames`。
|
|
40
|
+
- `getDefaultsForSystem` 涵蓋 redis (6379) / elasticsearch (9200) 預設值。
|
|
41
|
+
|
|
8
42
|
## [1.7.0] - 2026-05-04
|
|
9
43
|
|
|
10
44
|
### Added
|
package/README.md
CHANGED
|
@@ -114,7 +114,45 @@ dbcli query '{"status":"active"}' --collection users --use atlas
|
|
|
114
114
|
|
|
115
115
|
For MongoDB, `list` and `query` operate on the database configured for the connection, and `query` requires `--collection <name>`.
|
|
116
116
|
|
|
117
|
-
For a command-by-command support matrix across PostgreSQL, MySQL, MariaDB, and
|
|
117
|
+
For a command-by-command support matrix across PostgreSQL, MySQL, MariaDB, MongoDB, Redis, and Elasticsearch, see [docs/feature-matrix.md](./docs/feature-matrix.md).
|
|
118
|
+
|
|
119
|
+
### Redis & Elasticsearch Support
|
|
120
|
+
|
|
121
|
+
dbcli extends its unified interface to Redis and Elasticsearch, providing consistent discovery and querying.
|
|
122
|
+
|
|
123
|
+
#### Redis
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
# Connect to Redis
|
|
127
|
+
dbcli init --system redis --host localhost --port 6379
|
|
128
|
+
|
|
129
|
+
# List keys (uses SCAN)
|
|
130
|
+
dbcli list
|
|
131
|
+
|
|
132
|
+
# Inspect a key (type, TTL, size, sample)
|
|
133
|
+
dbcli schema my-key
|
|
134
|
+
|
|
135
|
+
# Run Redis commands (whitelisted)
|
|
136
|
+
dbcli query "GET my-key"
|
|
137
|
+
dbcli query "HGETALL user:1"
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
#### Elasticsearch
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
# Connect to Elasticsearch
|
|
144
|
+
dbcli init --system elasticsearch --host localhost --port 9200
|
|
145
|
+
|
|
146
|
+
# List indices and document counts
|
|
147
|
+
dbcli list
|
|
148
|
+
|
|
149
|
+
# Show mapping/structure of an index
|
|
150
|
+
dbcli schema my-index
|
|
151
|
+
|
|
152
|
+
# Query using Lucene or DSL JSON
|
|
153
|
+
dbcli query "status:active" --index my-index
|
|
154
|
+
dbcli query '{"query": {"match_all": {}}}' --index my-index
|
|
155
|
+
```
|
|
118
156
|
|
|
119
157
|
---
|
|
120
158
|
|
package/README.zh-TW.md
CHANGED
|
@@ -189,7 +189,7 @@ dbcli init [OPTIONS]
|
|
|
189
189
|
```
|
|
190
190
|
|
|
191
191
|
**選項 (基本):**
|
|
192
|
-
- `--system <type>` — 資料庫系統:`postgresql`、`mysql`、`mariadb`、`mongodb`
|
|
192
|
+
- `--system <type>` — 資料庫系統:`postgresql`、`mysql`、`mariadb`、`mongodb`、`redis`、`elasticsearch`
|
|
193
193
|
- `--host <host>` — 主機
|
|
194
194
|
- `--port <port>` — 埠號
|
|
195
195
|
- `--user <user>` — 使用者
|
package/assets/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: dbcli
|
|
3
|
-
description: Database CLI for AI agents with permission-based access control. Use to query, inspect schemas, insert/update/delete, export results, and blacklist sensitive columns/tables. Supports MySQL, PostgreSQL, MariaDB, and
|
|
3
|
+
description: Database CLI for AI agents with permission-based access control. Use to 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 working with databases, running SQL / MongoDB JSON / Redis commands / Elasticsearch DSL, exploring table/collection/key/index structures, switching database environments, or protecting sensitive data from AI access. For exhaustive flags and examples, read the sibling `reference.md`.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# dbcli
|
|
@@ -11,13 +11,32 @@ Database CLI for AI agents with permission-based access control.
|
|
|
11
11
|
|
|
12
12
|
1. `dbcli status` — permission level and system summary (no credentials).
|
|
13
13
|
2. `dbcli blacklist list` — sensitive data boundaries.
|
|
14
|
-
3. `dbcli schema <table> --format json` — real column names. **Never guess.**
|
|
14
|
+
3. `dbcli schema <table> --format json` — real column names (SQL/Mongo/ES) or `schema <key>` (Redis). **Never guess.**
|
|
15
15
|
4. Run `query` / `insert` / `update` / `delete` / `export` within permission.
|
|
16
|
-
5. All writes: `--dry-run` → run → `query` read-back to confirm.
|
|
16
|
+
5. All writes: `--dry-run` (SQL/Mongo) → run → `query` read-back to confirm.
|
|
17
17
|
|
|
18
18
|
Prefer `--format json` for agent-friendly output.
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
## Agent Task Packs
|
|
21
|
+
|
|
22
|
+
When the user asks for a database workflow (e.g. "diagnose this slow query", "audit
|
|
23
|
+
permissions", "review long-running operations"), prefer published task templates
|
|
24
|
+
over inventing steps from memory.
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
dbcli skill tasks list --format json # discover
|
|
28
|
+
dbcli skill tasks show <task> # inspect
|
|
29
|
+
dbcli skill tasks plan <task> --param key=value --format json # generate plan
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
The plan output is an ordered list of dbcli commands with rationale and risk
|
|
33
|
+
labels. Execute them one at a time — task plans do **not** override blacklist,
|
|
34
|
+
schema, dry-run, or confirmation requirements.
|
|
35
|
+
|
|
36
|
+
Tasks live under `assets/tasks/` (builtin), `.dbcli-shared/tasks/` (shared), and
|
|
37
|
+
`.dbcli/tasks/` (local override).
|
|
38
|
+
|
|
39
|
+
Full flags, per-command copy-paste blocks, `migrate` DDL, interactive `shell`, and MongoDB/Redis/ES walkthroughs are in [reference.md](reference.md) (installed next to this file).
|
|
21
40
|
|
|
22
41
|
## Quick start
|
|
23
42
|
|
|
@@ -33,21 +52,21 @@ dbcli query "SELECT * FROM users" # Execute SQL (auto LIMIT 1000)
|
|
|
33
52
|
|---------|-----------------|---------|
|
|
34
53
|
| `init` | n/a | Create `.dbcli` (v1 single or v2 multi via `--conn-name` / `--env-file`). **Usually run by the human** — do NOT re-run to strip `{"$env"}` references; that format is intentional. |
|
|
35
54
|
| `use` | n/a | Show/switch default named connection (v2 only). |
|
|
36
|
-
| `list` | query-only+ | Tables (SQL)
|
|
37
|
-
| `schema` | query-only+ |
|
|
38
|
-
| `query` | query-only+ | SQL,
|
|
39
|
-
| `insert` / `update` | read-write+ | JSON `--data` / `--set`; `--where` required on `update`; `--dry-run` first. |
|
|
40
|
-
| `delete` | data-admin+ | `--where` required; `--dry-run` first. |
|
|
41
|
-
| `export` | query-only+ | Query → CSV/JSON file or stdout. |
|
|
55
|
+
| `list` | query-only+ | Tables (SQL), collections (MongoDB), keys (Redis), or indices (Elasticsearch). |
|
|
56
|
+
| `schema` | query-only+ | SQL: per-table or full scan into `.dbcli/schemas/`. MongoDB: sampled. ES: flattened mapping. Redis: per-key only (type/TTL/size). |
|
|
57
|
+
| `query` | query-only+ | SQL, Mongo JSON (`--collection`), Redis command, or ES DSL/Lucene (`--collection`). |
|
|
58
|
+
| `insert` / `update` | read-write+ | SQL or MongoDB only. JSON `--data` / `--set`; `--where` required on `update`; `--dry-run` first. Redis writes go through `query`. |
|
|
59
|
+
| `delete` | data-admin+ | SQL or MongoDB only. `--where` required; `--dry-run` first. |
|
|
60
|
+
| `export` | query-only+ | SQL or MongoDB only. Query → CSV/JSON(L) file or stdout. |
|
|
42
61
|
| `blacklist` | n/a | `list` / `table` / `column` subcommands redact sensitive data from query results. |
|
|
43
|
-
| `check` | query-only+ |
|
|
44
|
-
| `diff` | query-only+ | Save/compare schema snapshots. |
|
|
62
|
+
| `check` | query-only+ | SQL only (best on MySQL/MariaDB). |
|
|
63
|
+
| `diff` | query-only+ | SQL only. Save/compare schema snapshots. |
|
|
45
64
|
| `status` | query-only+ | Safe JSON/text summary (no credentials). |
|
|
46
65
|
| `doctor` | n/a | Environment, config, connection, SRV diagnostics (Mongo), schema cache age. |
|
|
47
66
|
| `completion` | n/a | bash / zsh / fish scripts. |
|
|
48
67
|
| `upgrade` | n/a | Self-update from npm; 24h-cached version hints on every command. |
|
|
49
|
-
| `shell` | (same as query+) | Interactive REPL. |
|
|
50
|
-
| `migrate` | admin | **DDL; dry-run by default** — needs `--execute
|
|
68
|
+
| `shell` | (same as query+) | Interactive REPL. SQL engines + MongoDB shell only. |
|
|
69
|
+
| `migrate` | admin | SQL only. **DDL; dry-run by default** — needs `--execute`. |
|
|
51
70
|
|
|
52
71
|
`--use <name>` on any subcommand targets a v2 connection without changing the default.
|
|
53
72
|
|
|
@@ -69,11 +88,31 @@ dbcli query "SELECT * FROM users" # Execute SQL (auto LIMIT 1000)
|
|
|
69
88
|
## MongoDB
|
|
70
89
|
|
|
71
90
|
- JSON filter object (`find`) or JSON array (`aggregate`); SQL is rejected. `--collection <name>` is required on `query`.
|
|
72
|
-
- **Supported:** `init`, `list`, `query`, `status`, `use`, `shell`, `doctor`, `upgrade`, `completion`.
|
|
73
|
-
- **Not supported:** `
|
|
74
|
-
-
|
|
91
|
+
- **Supported:** `init`, `list`, `schema` (sampled), `query`, `insert`, `update`, `delete`, `export`, `status`, `use`, `shell`, `doctor`, `upgrade`, `completion`.
|
|
92
|
+
- **Not supported:** `q` (saved queries), `diff`, `migrate`, `check`.
|
|
93
|
+
- Schema is **sampled** (default 50 docs); types are JS `typeof` strings.
|
|
75
94
|
- See reference.md MongoDB section for full syntax and examples.
|
|
76
95
|
|
|
96
|
+
## Redis
|
|
97
|
+
|
|
98
|
+
- Command-style execution; `query` runs a whitelisted Redis command (e.g. `GET`, `HSET`, `DEL`).
|
|
99
|
+
- **Supported:** `init`, `list` (keys via SCAN), `schema <key>` (type / TTL / size / sample), `query`, `status`, `use`, `doctor`, `upgrade`, `completion`.
|
|
100
|
+
- **Not supported:** `schema` full scan, `insert`, `update`, `delete`, `export`, `check`, `diff`, `migrate`, `q`.
|
|
101
|
+
Use `query "DEL <key>"` etc. for writes — they go through the same permission gate.
|
|
102
|
+
- Permission tiers map to commands: read commands → `query-only`; mutators (`SET`, `HSET`, ...) → `read-write`; `DEL` / `UNLINK` → `data-admin`.
|
|
103
|
+
- `database` field is the logical DB index (default `0`); `list` returns ≤ 100 000 keys via SCAN.
|
|
104
|
+
- See reference.md Redis section.
|
|
105
|
+
|
|
106
|
+
## Elasticsearch
|
|
107
|
+
|
|
108
|
+
- DSL (JSON body) or Lucene query string; `--collection <index>` is required on `query`.
|
|
109
|
+
- **Supported:** `init`, `list` (indices with doc count), `schema [index]` (flattened mapping), `query`, `status`, `use`, `doctor`, `upgrade`, `completion`.
|
|
110
|
+
- **Not supported:** `insert`, `update`, `delete`, `export`, `check`, `diff`, `migrate`, `q`.
|
|
111
|
+
Writes are not exposed via dedicated subcommands yet — use `query` if the cluster allows or external tools.
|
|
112
|
+
- Query-only mode caps at 1000 hits; `--no-limit` is bounded at 10 000.
|
|
113
|
+
- Schema flattens nested fields (`a.b.c`) and surfaces `.fields` multi-fields.
|
|
114
|
+
- See reference.md Elasticsearch section.
|
|
115
|
+
|
|
77
116
|
## Saved queries
|
|
78
117
|
|
|
79
118
|
Run reusable parameterised SELECT snippets stored in your repo.
|
package/assets/reference.md
CHANGED
|
@@ -21,6 +21,14 @@ dbcli init --system mongodb --uri "mongodb://user:pass@host:27017/mydb?authSourc
|
|
|
21
21
|
dbcli init --system mongodb --host localhost --port 27017 --user admin --password secret --name mydb
|
|
22
22
|
dbcli init --system mongodb --host localhost --port 27017 --name mydb # No auth
|
|
23
23
|
|
|
24
|
+
# Redis (database = logical DB index)
|
|
25
|
+
dbcli init --system redis --host localhost --port 6379
|
|
26
|
+
dbcli init --system redis --host localhost --port 6379 --password secret --name 0
|
|
27
|
+
|
|
28
|
+
# Elasticsearch
|
|
29
|
+
dbcli init --system elasticsearch --host localhost --port 9200 --user elastic --password changeme
|
|
30
|
+
dbcli init --system elasticsearch --cloud-id "myCluster:dXMtZWFzdC0xLmF3..." --api-key "<base64>"
|
|
31
|
+
|
|
24
32
|
# Multi-connection (v2 format)
|
|
25
33
|
dbcli init --conn-name staging --env-file .env.staging # Named connection with custom env file
|
|
26
34
|
dbcli init --conn-name prod --env-file .env.production --use-env-refs --skip-test
|
|
@@ -32,6 +40,10 @@ dbcli init --rename staging:production # Rename a connection
|
|
|
32
40
|
|
|
33
41
|
**MongoDB-specific options:** `--uri <uri>` (full connection URI), `--auth-source <db>` (auth database, default: `admin` when user/password set)
|
|
34
42
|
|
|
43
|
+
**Elasticsearch-specific options:** `--cloud-id <id>` (Elastic Cloud), `--api-key <key>` (ApiKey auth). Other ES fields (`nodes[]`, `protocol`, `caPath`, `rejectUnauthorized`) can be edited directly in `.dbcli`.
|
|
44
|
+
|
|
45
|
+
**Redis note:** the `database` (or `--name`) field is the logical DB index (`"0"` … `"15"`), not a database name.
|
|
46
|
+
|
|
35
47
|
**Multi-connection:** Using `--conn-name` or `--env-file` creates a v2 config with named connections. Each connection can have its own env file and permission level. Existing v1 configs are automatically imported as the `default` connection when upgrading.
|
|
36
48
|
|
|
37
49
|
> **AI agent note on `--use-env-refs`:** If an existing `.dbcli` config contains `{"$env": "DB_HOST"}` style references, the connection values are read from environment variables at runtime. Do NOT re-run `init` to replace these references with actual values — the env-ref format is intentional for CI/CD and multi-environment setups.
|
|
@@ -57,16 +69,19 @@ dbcli list --use prod
|
|
|
57
69
|
|
|
58
70
|
### list
|
|
59
71
|
|
|
60
|
-
List all tables (SQL)
|
|
72
|
+
List all tables (SQL), collections (MongoDB), keys (Redis), or indices (Elasticsearch).
|
|
61
73
|
|
|
62
74
|
```bash
|
|
63
75
|
dbcli list
|
|
64
76
|
dbcli list --format json
|
|
77
|
+
dbcli list --include-system # Elasticsearch: include `.system` indices
|
|
65
78
|
```
|
|
66
79
|
|
|
67
80
|
**Permission:** query-only+
|
|
68
81
|
|
|
69
|
-
> **MongoDB:** Lists collections with estimated document count
|
|
82
|
+
> **MongoDB:** Lists collections with estimated document count.
|
|
83
|
+
> **Redis:** Returns up to 100 000 keys via `SCAN MATCH * COUNT 1000`. The header reads `Keys in db <n> (redis):` where `<n>` is the logical DB index.
|
|
84
|
+
> **Elasticsearch:** Returns indices with `documentCount` from `/_stats/docs`; aliases are tagged separately. System indices (names starting with `.`) are hidden unless `--include-system` is passed.
|
|
70
85
|
|
|
71
86
|
### schema
|
|
72
87
|
|
|
@@ -90,6 +105,9 @@ dbcli schema --use prod # Scan prod DB; saves to .dbcli/schemas/prod
|
|
|
90
105
|
|
|
91
106
|
**Schema storage (v1.4+):** Schema is persisted as layered files under `.dbcli/schemas/`. With v2 multi-connection config each connection gets its own subdirectory (`.dbcli/schemas/<connection>/`). Run `dbcli schema --use <connection>` once per connection before querying it — otherwise `schema <table>` may return data from the wrong connection's cache.
|
|
92
107
|
|
|
108
|
+
> **Redis:** `schema <key>` is required (no full scan). The output exposes `type`, `ttl`, `size`, and a small `sample` (e.g. first 5 hash keys). `--reset` / `--refresh` are rejected — Redis caches no schema.
|
|
109
|
+
> **Elasticsearch:** `schema [index]` flattens the `_mapping` properties (nested `a.b.c`) and emits each `.fields` multi-field as a separate column (e.g. `text` + `text.keyword`). Full scan iterates all non-system indices and stores per-connection caches alongside SQL engines.
|
|
110
|
+
|
|
93
111
|
### query
|
|
94
112
|
|
|
95
113
|
Execute SQL query (MySQL/PostgreSQL/MariaDB) or JSON filter/pipeline (MongoDB).
|
|
@@ -106,16 +124,38 @@ dbcli query '{"age": {"$gt": 18}}' --collection users --format json
|
|
|
106
124
|
|
|
107
125
|
# MongoDB: aggregation pipeline
|
|
108
126
|
dbcli query '[{"$match": {"status": "active"}}, {"$group": {"_id": "$role", "count": {"$sum": 1}}}]' --collection users
|
|
127
|
+
|
|
128
|
+
# Redis: any whitelisted command (permission-gated by command)
|
|
129
|
+
dbcli query "GET session:abc"
|
|
130
|
+
dbcli query "HGETALL user:42" --format json
|
|
131
|
+
dbcli query "SCAN 0 MATCH user:* COUNT 100"
|
|
132
|
+
dbcli query "SET feature:flag enabled" # requires read-write+
|
|
133
|
+
dbcli query "DEL stale:key" # requires data-admin+
|
|
134
|
+
|
|
135
|
+
# Elasticsearch: DSL body or Lucene q-string
|
|
136
|
+
dbcli query '{"query":{"match":{"status":"active"}}}' --collection orders
|
|
137
|
+
dbcli query 'status:active AND amount:>100' --index orders --limit 50
|
|
109
138
|
```
|
|
110
139
|
|
|
111
|
-
**Options:** `--format <table|json|csv>`, `--limit <number>`, `--no-limit`, `--collection <name>` (MongoDB
|
|
112
|
-
**Permission:** query-only+
|
|
140
|
+
**Options:** `--format <table|json|csv>`, `--limit <number>`, `--no-limit`, `--collection <name>` (MongoDB / Elasticsearch), `--index <name>` (Elasticsearch alias for `--collection`)
|
|
141
|
+
**Permission:** query-only+ (Redis: per-command; Elasticsearch: per HTTP method/path)
|
|
113
142
|
|
|
114
143
|
> **MongoDB notes:**
|
|
115
144
|
> - SQL syntax is rejected — use JSON object (filter) or JSON array (pipeline)
|
|
116
145
|
> - `--collection <name>` is required
|
|
117
146
|
> - Auto-limit does not apply; use `$limit` in your pipeline if needed
|
|
118
147
|
|
|
148
|
+
> **Redis notes:**
|
|
149
|
+
> - The first token must be an allow-listed command (`GET`/`SET`/`HGET`/`HSET`/`DEL`/...). Unknown commands are refused.
|
|
150
|
+
> - Permission tier is derived from the command (read → `query-only`, write → `read-write`, delete → `data-admin`, `KEYS`/`FLUSHDB`/`CONFIG`/... → `admin`).
|
|
151
|
+
> - Output is always shaped into rows: scalar replies become `{value: ...}`; arrays become indexed rows; `HGETALL` is folded into a single object.
|
|
152
|
+
|
|
153
|
+
> **Elasticsearch notes:**
|
|
154
|
+
> - `--collection` (or `--index`) is required.
|
|
155
|
+
> - A body that begins with `{` is sent as DSL via `POST /<index>/_search`; otherwise the value is URL-encoded into `?q=...` (Lucene query string) via `GET`.
|
|
156
|
+
> - Hits are flattened: each result row contains `_id` plus dotted-path fields from `_source`. Pass `--format json` to keep nested structures readable.
|
|
157
|
+
> - Query-only mode caps at 1000 hits; `--no-limit` is internally capped at 10 000 (use saved searches / `search_after` for deeper pagination).
|
|
158
|
+
|
|
119
159
|
### q
|
|
120
160
|
|
|
121
161
|
Run a saved query snippet by `@name`. Snippets are parameterised SELECT/WITH statements resolved from three layers, with **local > shared > builtin** precedence (a local file always shadows shared and builtin variants of the same key):
|
|
@@ -458,6 +498,33 @@ dbcli migrate drop-enum status --execute --force
|
|
|
458
498
|
|
|
459
499
|
**AI agent note:** Always use dry-run first (no `--execute`) to preview generated SQL. Only add `--execute` after confirming the SQL is correct. For DROP operations, both `--execute` and `--force` are required.
|
|
460
500
|
|
|
501
|
+
### skill tasks (Agent Task Packs)
|
|
502
|
+
|
|
503
|
+
```bash
|
|
504
|
+
dbcli skill tasks list # human table
|
|
505
|
+
dbcli skill tasks list --format json --tag diagnostics
|
|
506
|
+
dbcli skill tasks list --engine postgres --source builtin
|
|
507
|
+
dbcli skill tasks show diagnose-slow-query
|
|
508
|
+
dbcli skill tasks show diagnose-slow-query --format json
|
|
509
|
+
dbcli skill tasks plan diagnose-slow-query --param query="SELECT 1"
|
|
510
|
+
dbcli skill tasks plan diagnose-slow-query --param query="..." --format json
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
- **list filters:** `--tag <tag>`, `--engine <postgres|mysql|mongodb|redis|elasticsearch>`, `--source <builtin|shared|local>`, `--format <table|json>`.
|
|
514
|
+
- **show:** prints the full task definition (frontmatter + Agent Notes). Use `--format json` for an agent-friendly contract.
|
|
515
|
+
- **plan:** resolves `{{param}}` placeholders, validates required parameters, and emits a stable plan. Plans are **plan-only** in this version — dbcli will never execute the resulting commands automatically.
|
|
516
|
+
|
|
517
|
+
Task storage layers:
|
|
518
|
+
|
|
519
|
+
| Source | Path | Notes |
|
|
520
|
+
| --- | --- | --- |
|
|
521
|
+
| builtin | `assets/tasks/` | shipped with dbcli |
|
|
522
|
+
| shared | `.dbcli-shared/tasks/` | team-managed, version-controlled |
|
|
523
|
+
| local | `.dbcli/tasks/` | personal, gitignored |
|
|
524
|
+
|
|
525
|
+
Higher tiers override lower tiers by task name. Task name is derived from the
|
|
526
|
+
file path under the tier root (e.g. `diag/inspect.md` → `diag/inspect`).
|
|
527
|
+
|
|
461
528
|
## MongoDB Support
|
|
462
529
|
|
|
463
530
|
MongoDB connections use a JSON-based query model instead of SQL. Treat MongoDB support as a narrower document-database path, not as a full SQL feature equivalent.
|
|
@@ -508,3 +575,144 @@ dbcli delete orders --where '{"status":"cancelled"}' --force
|
|
|
508
575
|
| Field filter | `'{"field": "value"}'` |
|
|
509
576
|
| Comparison | `'{"age": {"$gt": 18}}'` |
|
|
510
577
|
| Aggregation | `'[{"$match": {...}}, {"$group": {...}}]'` |
|
|
578
|
+
|
|
579
|
+
## Redis Support
|
|
580
|
+
|
|
581
|
+
Redis connections speak Redis commands rather than SQL. The adapter uses the `ioredis` driver and exposes a narrow, permission-gated surface.
|
|
582
|
+
|
|
583
|
+
**Supported commands:** `init`, `use`, `list`, `schema`, `query`, `status`, `doctor`, `upgrade`, `completion`
|
|
584
|
+
|
|
585
|
+
**Not supported (exit with error or unsupported error):** `insert`, `update`, `delete`, `export`, `check`, `diff`, `migrate`, `q` (saved queries), `shell`. For writes, run the equivalent Redis command via `query` — the same permission gate applies.
|
|
586
|
+
|
|
587
|
+
### Connection and configuration
|
|
588
|
+
|
|
589
|
+
- Required fields: `system: redis`, `host`, `port`. `password` and `database` are optional.
|
|
590
|
+
- `database` is the **logical DB index** (`"0"` … `"15"`), kept as a string to play nicely with env-ref bindings. `list` and the connection metadata both label it as the active DB.
|
|
591
|
+
- `connection.timeout` (ms, default 5000) maps to ioredis's `connectTimeout`.
|
|
592
|
+
|
|
593
|
+
### Permission classification
|
|
594
|
+
|
|
595
|
+
Permission is derived from the command's first token (case-insensitive). Unknown commands are denied even at `admin` tier — they must be added to the allow-list.
|
|
596
|
+
|
|
597
|
+
| Tier | Commands |
|
|
598
|
+
|------|----------|
|
|
599
|
+
| `query-only` | `GET`, `MGET`, `STRLEN`, `EXISTS`, `TTL`, `PTTL`, `TYPE`, `SCAN`, `HGET`, `HGETALL`, `HKEYS`, `HVALS`, `HLEN`, `HEXISTS`, `HMGET`, `LRANGE`, `LLEN`, `LINDEX`, `SMEMBERS`, `SCARD`, `SISMEMBER`, `ZRANGE`, `ZREVRANGE`, `ZRANGEBYSCORE`, `ZCARD`, `ZSCORE`, `PING`, `ECHO` |
|
|
600
|
+
| `read-write` | `SET`, `SETEX`, `SETNX`, `PSETEX`, `MSET`, `MSETNX`, `APPEND`, `INCR`/`INCRBY`, `DECR`/`DECRBY`, `HSET`/`HSETNX`/`HMSET`/`HINCRBY`, `LPUSH`/`RPUSH`/`LPOP`/`RPOP`/`LSET`, `SADD`/`SREM`, `ZADD`/`ZREM`, `EXPIRE`/`EXPIREAT`/`PEXPIRE`/`PERSIST`, `RENAME` |
|
|
601
|
+
| `data-admin` | `DEL`, `UNLINK`, `HDEL` |
|
|
602
|
+
| `admin` | `FLUSHDB`, `FLUSHALL`, `CONFIG`, `INFO`, `CLIENT`, `DEBUG`, `SHUTDOWN`, `KEYS`, `MONITOR`, `SAVE`, `BGSAVE`, `BGREWRITEAOF`, `REPLICAOF`, `SLAVEOF`, `ACL` |
|
|
603
|
+
|
|
604
|
+
### Schema inspection
|
|
605
|
+
|
|
606
|
+
`schema <key>` returns one synthetic row per key with these columns:
|
|
607
|
+
|
|
608
|
+
| column | meaning |
|
|
609
|
+
|--------|---------|
|
|
610
|
+
| `type` | Redis type (`string` / `hash` / `list` / `set` / `zset` / `stream` / `none`) |
|
|
611
|
+
| `ttl` | `<n>s`, `no expiry`, or `missing` |
|
|
612
|
+
| `size` | `STRLEN` / `HLEN` / `LLEN` / `SCARD` / `ZCARD` / `XLEN` depending on type |
|
|
613
|
+
| `sample` | First 5 hash field names (hash only) |
|
|
614
|
+
|
|
615
|
+
`schema` (no key) and `--refresh` / `--reset` are rejected — there is no full-database schema cache for Redis.
|
|
616
|
+
|
|
617
|
+
### Recommended `query` patterns
|
|
618
|
+
|
|
619
|
+
```bash
|
|
620
|
+
# Read
|
|
621
|
+
dbcli query "GET feature:flag"
|
|
622
|
+
dbcli query "HGETALL user:42" --format json
|
|
623
|
+
dbcli query "LRANGE queue:jobs 0 9"
|
|
624
|
+
|
|
625
|
+
# Iterate keys (paginated; never use KEYS — admin-only)
|
|
626
|
+
dbcli query "SCAN 0 MATCH session:* COUNT 200"
|
|
627
|
+
|
|
628
|
+
# Write (requires read-write+)
|
|
629
|
+
dbcli query "SET counter 1"
|
|
630
|
+
dbcli query "EXPIRE session:abc 3600"
|
|
631
|
+
dbcli query "HSET user:42 name Alice"
|
|
632
|
+
|
|
633
|
+
# Delete (requires data-admin+)
|
|
634
|
+
dbcli query "DEL temp:lock"
|
|
635
|
+
dbcli query "HDEL user:42 lastLogin"
|
|
636
|
+
```
|
|
637
|
+
|
|
638
|
+
### Limitations
|
|
639
|
+
|
|
640
|
+
- No `--dry-run` for writes — Redis commands execute immediately. Pair writes with a confirming read (`GET`, `HGETALL`, `EXISTS`).
|
|
641
|
+
- No transaction wrapping (`MULTI`/`EXEC`). Submit one command at a time.
|
|
642
|
+
- `KEYS` requires `admin`. Prefer `SCAN` for routine work.
|
|
643
|
+
- Blacklist rules are not enforced for Redis (there is no concept of "column" / "table" the validator can map). Be careful with sensitive key prefixes.
|
|
644
|
+
|
|
645
|
+
## Elasticsearch Support
|
|
646
|
+
|
|
647
|
+
Elasticsearch connections speak the REST API. The adapter is fetch-based (no SDK) and supports HTTPS, custom CA, API key, basic auth, and Cloud ID.
|
|
648
|
+
|
|
649
|
+
**Supported commands:** `init`, `use`, `list`, `schema`, `query`, `status`, `doctor`, `upgrade`, `completion`
|
|
650
|
+
|
|
651
|
+
**Not supported (use external tooling):** `insert`, `update`, `delete`, `export`, `check`, `diff`, `migrate`, `q`, `shell`. The permission classifier already understands `_doc` / `_update` / `_bulk` so future write surfaces can be wired in without changing tiers.
|
|
652
|
+
|
|
653
|
+
### Connection and configuration
|
|
654
|
+
|
|
655
|
+
- Either `host` + `port` (default `https://localhost:9200`) or `nodes: [...]` (first node is used) or `cloudId`.
|
|
656
|
+
- Auth precedence: `apiKey` → `user`/`password` (HTTP Basic). Leave both unset for an open cluster.
|
|
657
|
+
- `protocol` defaults to `https`. For TLS quirks: `caPath` (path to a PEM bundle) and `rejectUnauthorized: false` (last resort).
|
|
658
|
+
- `connection.timeout` (ms, default 5000) is wired to `AbortController` on every request.
|
|
659
|
+
|
|
660
|
+
### Permission classification
|
|
661
|
+
|
|
662
|
+
Each REST request is mapped to a SQL-shaped tier based on method + path:
|
|
663
|
+
|
|
664
|
+
| ES surface | Mapped to | Permission |
|
|
665
|
+
|------------|-----------|------------|
|
|
666
|
+
| `GET _search` / `_count` / `_mapping` / `_settings` / `_alias` / `GET _doc` / `_source` | `SELECT` | `query-only` |
|
|
667
|
+
| `POST _update` / `POST _doc` | `UPDATE` | `read-write` |
|
|
668
|
+
| `PUT _doc` / `_create` | `INSERT` | `read-write` |
|
|
669
|
+
| `DELETE` (any) | `DELETE` | `data-admin` |
|
|
670
|
+
| `_bulk` | highest tier among the NDJSON actions (`delete` ⇒ `data-admin`) | derived |
|
|
671
|
+
| Anything else | `DROP` | `admin` (deny by default) |
|
|
672
|
+
|
|
673
|
+
### Schema inspection
|
|
674
|
+
|
|
675
|
+
`schema [index]` calls `GET /<index>/_mapping` and flattens nested properties into dotted-path columns. Multi-fields under `.fields` (e.g. `text` → `text.keyword`) are emitted as separate columns. All fields are reported as nullable. There is no PK / FK / index info.
|
|
676
|
+
|
|
677
|
+
`schema` (no argument) iterates all non-system indices through the standard full-scan code path and writes per-connection caches under `.dbcli/schemas/<connection>/`.
|
|
678
|
+
|
|
679
|
+
### Query semantics
|
|
680
|
+
|
|
681
|
+
- `--collection <index>` (or `--index <index>`) is required.
|
|
682
|
+
- Body that starts with `{` → sent as JSON DSL via `POST /<index>/_search`. Body otherwise → URL-encoded into `?q=...` (Lucene query string) on `GET`.
|
|
683
|
+
- Hits are flattened: each row carries `_id` plus dotted-path fields lifted from `_source`. Use `--format json` to inspect raw nested structure.
|
|
684
|
+
- Query-only mode caps `size` at 1000. `--no-limit` is internally capped at 10 000; for deeper pagination use the API directly with `search_after` or PIT.
|
|
685
|
+
|
|
686
|
+
### Recommended `query` patterns
|
|
687
|
+
|
|
688
|
+
```bash
|
|
689
|
+
# DSL match
|
|
690
|
+
dbcli query '{"query":{"match":{"status":"active"}}}' --collection orders --format json
|
|
691
|
+
|
|
692
|
+
# DSL with sort + size
|
|
693
|
+
dbcli query '{"query":{"range":{"created_at":{"gte":"2026-01-01"}}},"sort":[{"created_at":"desc"}],"size":50}' \
|
|
694
|
+
--collection orders
|
|
695
|
+
|
|
696
|
+
# Aggregation
|
|
697
|
+
dbcli query '{"size":0,"aggs":{"by_status":{"terms":{"field":"status.keyword"}}}}' \
|
|
698
|
+
--collection orders --format json
|
|
699
|
+
|
|
700
|
+
# Lucene query string
|
|
701
|
+
dbcli query 'status:active AND amount:>100' --index orders --limit 100
|
|
702
|
+
```
|
|
703
|
+
|
|
704
|
+
### Doctor and diagnostics
|
|
705
|
+
|
|
706
|
+
`dbcli doctor` runs a dedicated Elasticsearch path:
|
|
707
|
+
|
|
708
|
+
- Verifies REST connectivity to `GET /`.
|
|
709
|
+
- Reads `version.number` and runs the standard version freshness check.
|
|
710
|
+
- Walks every index via `listTables()` + `getTableSchema()` to feed the blacklist completeness check and the large-table heuristic (using `documentCount`).
|
|
711
|
+
- Standard schema-cache freshness using `schemaLastUpdated`.
|
|
712
|
+
|
|
713
|
+
### Limitations
|
|
714
|
+
|
|
715
|
+
- Writes (`insert`/`update`/`delete`/`export`) are not exposed yet — the adapter implements them, but the CLI currently only routes them for SQL and MongoDB.
|
|
716
|
+
- No `_search/scroll` or PIT pagination at the CLI layer; large pulls need a saved external script.
|
|
717
|
+
- `check`, `diff`, `migrate`, and `q` are SQL-only and exit with errors (or fall through to a generic "unsupported" path).
|
|
718
|
+
- Blacklist column rules are applied to flattened hit rows on `query`; table-level blacklist rejects an index up front.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# dbcli Agent Tasks (built-in)
|
|
2
|
+
|
|
3
|
+
Built-in task templates shipped with dbcli for AI agents.
|
|
4
|
+
|
|
5
|
+
## Resolution order
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
assets/tasks/ # builtin (lowest)
|
|
9
|
+
.dbcli-shared/tasks/ # shared, version-controlled
|
|
10
|
+
.dbcli/tasks/ # local, gitignored (highest)
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
A task with the same name in a higher tier overrides the lower one. Use this to
|
|
14
|
+
customize built-in workflows without modifying dbcli source.
|
|
15
|
+
|
|
16
|
+
## File format
|
|
17
|
+
|
|
18
|
+
Each task is a `.md` file with a YAML frontmatter block:
|
|
19
|
+
|
|
20
|
+
- `name` (required, must match the file path without `.md`)
|
|
21
|
+
- `description`, `tags`, `engines`
|
|
22
|
+
- `params` (map of name → `{ type, required?, default?, description?, enum? }`)
|
|
23
|
+
- `safety.mode` — only `plan-only` is supported in this version
|
|
24
|
+
- `steps[]` — each step is `{ type: command, command, reason?, risk? }`
|
|
25
|
+
|
|
26
|
+
Use block-style YAML (no inline `{ ... }` maps) — the built-in YAML parser does
|
|
27
|
+
not support inline maps.
|
|
28
|
+
|
|
29
|
+
The markdown body below the frontmatter is `Agent Notes` and is shown in
|
|
30
|
+
`dbcli skill tasks show <name>`.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: diagnose-slow-query
|
|
3
|
+
description: Diagnose slow query causes using safe read-only dbcli steps.
|
|
4
|
+
tags: [diagnostics, performance, readonly]
|
|
5
|
+
engines: [postgres, mysql]
|
|
6
|
+
params:
|
|
7
|
+
query:
|
|
8
|
+
type: string
|
|
9
|
+
required: true
|
|
10
|
+
description: The slow SQL query or query fingerprint to inspect.
|
|
11
|
+
safety:
|
|
12
|
+
mode: plan-only
|
|
13
|
+
requires:
|
|
14
|
+
- blacklist-list
|
|
15
|
+
- schema-check
|
|
16
|
+
steps:
|
|
17
|
+
- type: command
|
|
18
|
+
command: blacklist list
|
|
19
|
+
reason: Confirm sensitive tables and columns are protected before inspection.
|
|
20
|
+
risk: readonly
|
|
21
|
+
- type: command
|
|
22
|
+
command: plan "{{query}}"
|
|
23
|
+
reason: Analyze SQL risk without executing the query.
|
|
24
|
+
risk: readonly
|
|
25
|
+
- type: command
|
|
26
|
+
command: q @diag/long-running --format json
|
|
27
|
+
reason: Inspect active long-running queries through a saved diagnostic snippet.
|
|
28
|
+
risk: readonly
|
|
29
|
+
---
|
|
30
|
+
# Agent Notes
|
|
31
|
+
|
|
32
|
+
Use this task when the user reports a slow SQL query and wants safe diagnostic next steps.
|
|
33
|
+
Do not run write operations.
|