agent-database-cli 0.2.7

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.
Files changed (73) hide show
  1. package/AI_INSTALL.md +72 -0
  2. package/LICENSE +21 -0
  3. package/README.md +340 -0
  4. package/README_EN.md +341 -0
  5. package/SKILL.md +252 -0
  6. package/config/docker-test.json +40 -0
  7. package/dist/adapters/base-sql.d.ts +12 -0
  8. package/dist/adapters/base-sql.js +22 -0
  9. package/dist/adapters/base-sql.js.map +1 -0
  10. package/dist/adapters/factory.d.ts +2 -0
  11. package/dist/adapters/factory.js +26 -0
  12. package/dist/adapters/factory.js.map +1 -0
  13. package/dist/adapters/mongodb.d.ts +14 -0
  14. package/dist/adapters/mongodb.js +137 -0
  15. package/dist/adapters/mongodb.js.map +1 -0
  16. package/dist/adapters/mysql.d.ts +12 -0
  17. package/dist/adapters/mysql.js +38 -0
  18. package/dist/adapters/mysql.js.map +1 -0
  19. package/dist/adapters/oracle-sqlcl.d.ts +19 -0
  20. package/dist/adapters/oracle-sqlcl.js +334 -0
  21. package/dist/adapters/oracle-sqlcl.js.map +1 -0
  22. package/dist/adapters/oracle.d.ts +13 -0
  23. package/dist/adapters/oracle.js +47 -0
  24. package/dist/adapters/oracle.js.map +1 -0
  25. package/dist/adapters/postgres.d.ts +12 -0
  26. package/dist/adapters/postgres.js +40 -0
  27. package/dist/adapters/postgres.js.map +1 -0
  28. package/dist/adapters/redis.d.ts +15 -0
  29. package/dist/adapters/redis.js +91 -0
  30. package/dist/adapters/redis.js.map +1 -0
  31. package/dist/cli.d.ts +2 -0
  32. package/dist/cli.js +118 -0
  33. package/dist/cli.js.map +1 -0
  34. package/dist/config.d.ts +8 -0
  35. package/dist/config.js +147 -0
  36. package/dist/config.js.map +1 -0
  37. package/dist/connection-manager.d.ts +24 -0
  38. package/dist/connection-manager.js +91 -0
  39. package/dist/connection-manager.js.map +1 -0
  40. package/dist/daemon/client.d.ts +3 -0
  41. package/dist/daemon/client.js +33 -0
  42. package/dist/daemon/client.js.map +1 -0
  43. package/dist/daemon/config-manager.d.ts +15 -0
  44. package/dist/daemon/config-manager.js +44 -0
  45. package/dist/daemon/config-manager.js.map +1 -0
  46. package/dist/daemon/control.d.ts +9 -0
  47. package/dist/daemon/control.js +53 -0
  48. package/dist/daemon/control.js.map +1 -0
  49. package/dist/daemon/paths.d.ts +5 -0
  50. package/dist/daemon/paths.js +18 -0
  51. package/dist/daemon/paths.js.map +1 -0
  52. package/dist/daemon/server.d.ts +1 -0
  53. package/dist/daemon/server.js +119 -0
  54. package/dist/daemon/server.js.map +1 -0
  55. package/dist/output.d.ts +2 -0
  56. package/dist/output.js +39 -0
  57. package/dist/output.js.map +1 -0
  58. package/dist/runtime.d.ts +5 -0
  59. package/dist/runtime.js +25 -0
  60. package/dist/runtime.js.map +1 -0
  61. package/dist/security.d.ts +8 -0
  62. package/dist/security.js +239 -0
  63. package/dist/security.js.map +1 -0
  64. package/dist/ssh-tunnel.d.ts +8 -0
  65. package/dist/ssh-tunnel.js +231 -0
  66. package/dist/ssh-tunnel.js.map +1 -0
  67. package/dist/types.d.ts +69 -0
  68. package/dist/types.js +2 -0
  69. package/dist/types.js.map +1 -0
  70. package/dist/utils/masking.d.ts +2 -0
  71. package/dist/utils/masking.js +14 -0
  72. package/dist/utils/masking.js.map +1 -0
  73. package/package.json +50 -0
package/README_EN.md ADDED
@@ -0,0 +1,341 @@
1
+ <div align="center">
2
+
3
+ # agent-database-cli
4
+
5
+ A CLI-based multi-database tool that packages common database connection, query, metadata inspection, and connection reuse capabilities as local commands callable by agents.
6
+
7
+ MySQL · PostgreSQL · Redis · Oracle · MongoDB · Read-only mode · Command blocklist · SQLcl Oracle · Local daemon
8
+
9
+ <p>
10
+ <img src="https://img.shields.io/badge/CLI-agent--database--cli-2ea44f" alt="CLI agent-database-cli">
11
+ <img src="https://img.shields.io/badge/License-MIT-green" alt="License MIT">
12
+ <img src="https://img.shields.io/badge/Node.js-%3E%3D20-339933?logo=node.js&logoColor=white" alt="Node.js >=20">
13
+ <img src="https://img.shields.io/badge/npm-%3E%3D10-CB3837?logo=npm&logoColor=white" alt="npm >=10">
14
+ <img src="https://img.shields.io/badge/Windows-MacOS-0078D6?labelColor=0078D6&color=C0C0C0" alt="Windows/MacOS">
15
+ <img src="https://img.shields.io/badge/release-v0.2.6-blue" alt="release v0.2.6">
16
+ </p>
17
+
18
+ [AI One-Click Installation](#ai-one-click-installation) · [Installation](#installation) · [Configuration](#configuration) · [Permission Configuration](#permission-configuration) · [Oracle SQLcl](#oracle-sqlcl) · [License](#license) · [Friendly Links](#friendly-links)
19
+
20
+ [中文](README.md) | English
21
+
22
+ </div>
23
+
24
+ ## Introduction
25
+
26
+ `agent-database-cli` references the database adapter, config loading, safety checking, and connection management layering of [Anarkh-Lee/universal-db-mcp](https://github.com/Anarkh-Lee/universal-db-mcp), then rewrites it into a standalone CLI form without MCP, HTTP, or SSE services.
27
+
28
+ What it can do:
29
+
30
+ - List currently supported database types and locally configured connections
31
+ - Execute SQL, Redis commands, or MongoDB JSON commands against a specified database
32
+ - Query database metadata such as tables, columns, collections, and Redis keys
33
+ - Enable read-only mode and command blocklists per database configuration
34
+ - Auto-start the local daemon on demand; the daemon exits after `300` idle seconds by default
35
+ - Keep connections alive through the local daemon; each database connection is released after `180` idle seconds by default
36
+ - Switch Oracle between `oracledb` and SQLcl drivers
37
+ - Never store or print unmasked passwords, tokens, or secrets
38
+ - Use named pipes on Windows and Unix sockets on macOS/Linux for the daemon
39
+
40
+ Driver configuration table:
41
+
42
+ | Database | `type` | Default driver | Driver switch configuration | Common configuration |
43
+ | --- | --- | --- | --- | --- |
44
+ | MySQL | `mysql` | npm package `mysql2` | Not switchable yet | `readonly`, `blacklist`, `keepAliveSeconds` |
45
+ | PostgreSQL | `postgres` | npm package `pg` | Not switchable yet | `readonly`, `blacklist`, `keepAliveSeconds` |
46
+ | Redis standalone | `redis` | npm package `redis` | Configure `url` only | `readonly`, `blacklist`, `keepAliveSeconds` |
47
+ | Redis cluster | `redis` | npm package `redis` | Configure both `url` and `redisCluster.nodes` | `readonly`, `blacklist`, `keepAliveSeconds` |
48
+ | Oracle | `oracle` | npm package `oracledb` | `oracleDriver: "oracledb" \| "sqlcl"`; SQLcl mode can configure `sqlclPath` and `javaHome`. SQLcl is recommended for older Oracle versions | `readonly`, `blacklist`, `keepAliveSeconds` |
49
+ | MongoDB | `mongodb` | npm package `mongodb` | Not switchable yet; `database` can be configured as the default database | `readonly`, `blacklist`, `keepAliveSeconds` |
50
+
51
+ ## Installation
52
+
53
+ ### Requirements
54
+
55
+ - Node.js `>= 20`
56
+ - npm `>= 10`
57
+ - Local network access to the target database
58
+ - Docker and Docker Compose if you run integration tests
59
+ - SQLcl and Java installed locally if Oracle uses SQLcl
60
+
61
+ ### AI One-Click Installation
62
+
63
+ ```text
64
+ Please read https://github.com/sleepinginsummer/agent-database-cli/blob/main/AI_INSTALL.md, install the CLI as instructed, and add `SKILL.md`.
65
+ ```
66
+
67
+ ### Manual Global Installation
68
+
69
+ ```bash
70
+ npm install -g agent-database-cli
71
+ agent-database-cli --help
72
+ ```
73
+
74
+ If npm package installation is restricted, use the equivalent source installation flow:
75
+
76
+ ```powershell
77
+ git clone https://github.com/sleepinginsummer/agent-database-cli.git
78
+ cd agent-database-cli
79
+ npm install
80
+ npm run build
81
+ npm link
82
+ agent-database-cli --help
83
+ ```
84
+
85
+ Add `SKILL.md` to the agent that needs to use this tool.
86
+
87
+ ## Configuration
88
+
89
+ Default configuration file:
90
+
91
+ ```text
92
+ ~/.agent-database-cli/config.json
93
+ ```
94
+
95
+ You can override the configuration path with an environment variable:
96
+
97
+ ```bash
98
+ AGENT_DATABASE_CLI_CONFIG=/path/to/config.json agent-database-cli list
99
+ ```
100
+
101
+ The configuration file is an object. Each key under `databases` is a database connection name:
102
+
103
+ - `type`: Database type, supports `mysql`, `postgres`, `redis`, `oracle`, and `mongodb`
104
+ - `url`: Database connection URL. In Redis standalone mode it is the direct target. In Redis cluster mode it is used as the entry node URL
105
+ - `redisCluster`: Optional Redis cluster configuration. When configured, cluster mode is used
106
+ - `sshTunnel`: Optional SSH tunnel configuration. In standalone mode, the database URL host and port are forwarded through SSH. In Redis cluster mode, a local forwarding port is created for each configured cluster node
107
+ - `database`: Optional default MongoDB database name
108
+ - `readonly`: Whether read-only mode is enabled, default `true`; only explicitly set `false` when write access is really required
109
+ - `blacklist`: Command blocklist array, case-insensitive
110
+ - `keepAliveSeconds`: Idle release timeout in seconds for a single database connection, default `180`
111
+ - `oracleDriver`: Oracle driver, supports `oracledb` or `sqlcl`
112
+ - `sqlclPath`: SQLcl executable path, used only when `oracleDriver` is `sqlcl`
113
+ - `javaHome`: Optional `JAVA_HOME` used by SQLcl
114
+
115
+ `redisCluster` currently supports:
116
+
117
+ - `nodes`: Array of Redis cluster node URLs. At least one node is required. `redis://` and `rediss://` are supported
118
+
119
+ Redis cluster notes:
120
+
121
+ - In the current implementation, Redis cluster mode requires both `url` and `redisCluster.nodes`
122
+ - `url` is used as the cluster entry node. It is recommended to use any stable reachable cluster node URL
123
+ - `redisCluster.nodes` is used as the cluster node list. With SSH tunneling, it is also used to create per-node local forwarding and address mapping
124
+ - When `redisCluster.nodes` is configured, the client switches to Redis Cluster mode
125
+ - When `sshTunnel` is also configured, the program creates a local forwarded port for each cluster node and uses address mapping for cluster redirects
126
+ - With SSH tunneling, `redisCluster.nodes` should cover the cluster node addresses that the client may be redirected to
127
+
128
+ `sshTunnel` supports password, private key, password plus private key, and passphrase-protected private key authentication:
129
+
130
+ - `host`: SSH jump host address
131
+ - `port`: SSH port, default `22`
132
+ - `username`: SSH username
133
+ - `password`: Optional SSH password
134
+ - `privateKeyPath`: Optional private key file path, supports `~`
135
+ - `privateKey`: Optional private key content, mutually exclusive with `privateKeyPath`
136
+ - `passphrase`: Optional private key passphrase, only valid when a private key is configured
137
+ - `readyTimeout`: Optional SSH connection timeout in milliseconds
138
+
139
+ The blocklist and read-only mode work together with a fixed priority: check the blocklist first, reject immediately on match, and only check read-only mode when no blocklist rule matches.
140
+
141
+ Read-only mode notes:
142
+
143
+ - Read-only mode is enabled by default; write operations are still rejected when `readonly` is omitted
144
+ - It is recommended to keep all database connections read-only by default. When data changes are needed, let AI generate the SQL or command first, then execute it after your confirmation
145
+ - Only set `readonly: false` on a specific connection when write access is truly required
146
+
147
+ Reference configuration:
148
+
149
+ ```json
150
+ {
151
+ "databases": {
152
+ "local-mysql": {
153
+ "type": "mysql",
154
+ "url": "mysql://user:password@localhost:3306/app",
155
+ "readonly": true,
156
+ "blacklist": ["drop", "truncate", "delete"],
157
+ "keepAliveSeconds": 180
158
+ },
159
+ "remote-mysql": {
160
+ "type": "mysql",
161
+ "url": "mysql://user:password@db.internal:3306/app",
162
+ "sshTunnel": {
163
+ "host": "jump.example.com",
164
+ "port": 22,
165
+ "username": "deploy",
166
+ "privateKeyPath": "~/.ssh/id_rsa",
167
+ "passphrase": "key-passphrase"
168
+ },
169
+ "readonly": true,
170
+ "keepAliveSeconds": 180
171
+ },
172
+ "redis-standalone": {
173
+ "type": "redis",
174
+ "url": "redis://localhost:6379",
175
+ "readonly": false,
176
+ "blacklist": ["flushall", "flushdb"],
177
+ "keepAliveSeconds": 180
178
+ },
179
+ "redis-cluster": {
180
+ "type": "redis",
181
+ "url": "redis://10.0.0.11:7001",
182
+ "redisCluster": {
183
+ "nodes": [
184
+ "redis://10.0.0.11:7001",
185
+ "redis://10.0.0.12:7001",
186
+ "redis://10.0.0.13:7001"
187
+ ]
188
+ },
189
+ "readonly": true,
190
+ "blacklist": ["flushall", "flushdb"],
191
+ "keepAliveSeconds": 180
192
+ },
193
+ "redis-cluster-via-ssh": {
194
+ "type": "redis",
195
+ "url": "redis://10.0.0.11:7001",
196
+ "redisCluster": {
197
+ "nodes": [
198
+ "redis://10.0.0.11:7001",
199
+ "redis://10.0.0.12:7001",
200
+ "redis://10.0.0.13:7001"
201
+ ]
202
+ },
203
+ "sshTunnel": {
204
+ "host": "jump.example.com",
205
+ "port": 22,
206
+ "username": "deploy",
207
+ "privateKeyPath": "~/.ssh/id_rsa"
208
+ },
209
+ "readonly": true,
210
+ "blacklist": ["flushall", "flushdb"],
211
+ "keepAliveSeconds": 180
212
+ },
213
+ "oracle-test": {
214
+ "type": "oracle",
215
+ "url": "oracle://USER:password@127.0.0.1:1521/qftest201",
216
+ "oracleDriver": "sqlcl",
217
+ "sqlclPath": "/opt/homebrew/Caskroom/sqlcl/26.1.0.086.1709/sqlcl/bin/sql",
218
+ "javaHome": "/Applications/IntelliJ IDEA Ultimate.app/Contents/jbr/Contents/Home",
219
+ "readonly": true,
220
+ "blacklist": ["drop", "truncate", "delete", "update", "insert", "merge", "alter", "create"],
221
+ "keepAliveSeconds": 180
222
+ }
223
+ }
224
+ }
225
+ ```
226
+
227
+ ## Permission Configuration
228
+
229
+ It is recommended to use both `readonly` and `blacklist` together for permission control. Do not rely on only one of them.
230
+
231
+ ### Read-only Mode
232
+
233
+ - The default value is `true`
234
+ - When `readonly` is omitted, the connection is still treated as read-only
235
+ - It is recommended to keep all day-to-day query connections read-only by default
236
+ - When data changes are needed, let AI generate the SQL or command first, then execute it after your confirmation
237
+ - Only dedicated writable connections should explicitly set `readonly: false`
238
+
239
+ ### Command Blocklist
240
+
241
+ - The blocklist has higher priority than read-only mode
242
+ - A command is rejected immediately once it matches the blocklist
243
+ - It is suitable for blocking high-risk commands such as dropping data, schema changes, mass writes, and cache-clearing operations
244
+ - It is recommended for production databases, shared test databases, and online Redis instances
245
+
246
+ ### Execution Order
247
+
248
+ 1. Check `blacklist` first
249
+ 2. Reject immediately on match
250
+ 3. Check `readonly` only when not matched
251
+ 4. When `readonly` is enabled, only read commands are allowed
252
+
253
+ ### Common High-Risk Commands
254
+
255
+ Common high-risk SQL for MySQL / PostgreSQL / Oracle:
256
+
257
+ ```json
258
+ ["drop", "truncate", "delete", "update", "insert", "merge", "alter", "create", "replace", "grant", "revoke"]
259
+ ```
260
+
261
+ Common high-risk Redis commands:
262
+
263
+ ```json
264
+ ["flushall", "flushdb", "del", "unlink", "set", "mset", "expire", "rename", "hset", "lpush", "rpush", "sadd", "zadd"]
265
+ ```
266
+
267
+ Common high-risk MongoDB commands:
268
+
269
+ ```json
270
+ ["insertOne", "insertMany", "updateOne", "updateMany", "replaceOne", "deleteOne", "deleteMany", "findAndModify", "findOneAndUpdate", "findOneAndDelete", "drop", "dropDatabase", "createIndex", "dropIndex"]
271
+ ```
272
+
273
+ ### Recommended Configuration Examples
274
+
275
+ Recommended for production databases:
276
+
277
+ ```json
278
+ {
279
+ "type": "mysql",
280
+ "url": "mysql://user:password@prod-db:3306/app",
281
+ "readonly": true,
282
+ "blacklist": ["drop", "truncate", "delete", "update", "insert", "alter", "create"],
283
+ "keepAliveSeconds": 180
284
+ }
285
+ ```
286
+
287
+ Recommended for a dedicated writable connection:
288
+
289
+ ```json
290
+ {
291
+ "type": "postgres",
292
+ "url": "postgres://user:password@write-db:5432/app",
293
+ "readonly": false,
294
+ "blacklist": ["drop", "truncate", "alter"],
295
+ "keepAliveSeconds": 180
296
+ }
297
+ ```
298
+
299
+ ## Oracle SQLcl
300
+
301
+ Official link: https://www.oracle.com/database/sqldeveloper/technologies/sqlcl/
302
+
303
+ Oracle uses the npm package `oracledb` by default. If the target Oracle version is older, Thin mode compatibility errors such as `NJS-138` may appear. In that case, switch a single Oracle connection to SQLcl:
304
+
305
+ ```json
306
+ {
307
+ "type": "oracle",
308
+ "url": "oracle://USER:password@127.0.0.1:1521/qftest201",
309
+ "oracleDriver": "sqlcl",
310
+ "sqlclPath": "/opt/homebrew/Caskroom/sqlcl/26.1.0.086.1709/sqlcl/bin/sql",
311
+ "javaHome": "/Applications/IntelliJ IDEA Ultimate.app/Contents/jbr/Contents/Home",
312
+ "readonly": true,
313
+ "blacklist": ["drop", "truncate", "delete", "update", "insert", "merge", "alter", "create"]
314
+ }
315
+ ```
316
+
317
+ SQLcl mode passes the connection script through stdin to avoid exposing the password in process arguments. Security checks still happen before execution, and both blocklist and read-only mode remain effective.
318
+
319
+ ## Update
320
+
321
+ ```bash
322
+ npm install -g agent-database-cli@latest
323
+ ```
324
+
325
+ ## Uninstall and Cleanup
326
+
327
+ Uninstall and clean local configuration:
328
+
329
+ ```bash
330
+ npm uninstall -g agent-database-cli
331
+ npm cache clean --force
332
+ rm -rf ~/.agent-database-cli
333
+ ```
334
+
335
+ ## License
336
+
337
+ [MIT](LICENSE)
338
+
339
+ ## Friendly Links
340
+
341
+ - [LINUX DO - A New Ideal Community](https://linux.do/)
package/SKILL.md ADDED
@@ -0,0 +1,252 @@
1
+ ---
2
+ name: agent-database-cli
3
+ description: 使用本地 agent-database-cli 安全操作已配置的数据库。适用于列出数据库连接、测试连接、执行 SQL/Redis/MongoDB 命令、查询表/列/集合/keys 元信息、管理本地连接 daemon,以及验证只读模式和命令黑名单的场景。
4
+ ---
5
+
6
+ # agent-database-cli 使用说明
7
+
8
+ `agent-database-cli` 是一个基于本地配置的多数据库命令行工具,用于让 AI 或用户安全地操作数据库。
9
+
10
+ 它能做的事:
11
+
12
+ - 列出支持的数据库类型和本地已配置数据库连接
13
+ - 测试指定数据库连接
14
+ - 执行 SQL、Redis 命令或 MongoDB JSON 命令
15
+ - 查询表、列、集合、Redis keys 等元信息
16
+ - 按单个数据库配置执行命令黑名单和只读模式
17
+ - 普通命令会按需自动启动本地 daemon,daemon 默认空闲 `300` 秒后自动退出
18
+ - 通过本地 daemon 短时间保持连接,单个数据库连接默认空闲 `180` 秒释放
19
+ - daemon 在 Windows 使用 named pipe,在 macOS/Linux 使用 Unix socket
20
+ - Oracle 支持 `oracledb` 和 SQLcl 两种连接方式
21
+
22
+ 它不做的事:
23
+
24
+ - 不扫描网络或发现数据库,只使用配置文件中的连接
25
+ - 不绕过配置中的黑名单和只读模式
26
+ - 不输出未脱敏的密码、token、secret
27
+ - 不默认执行写入、删除、DDL 或其它危险命令
28
+
29
+ ## 安全确认
30
+
31
+ 执行任何可能写入、删除、修改结构或影响数据完整性的命令前,必须先确认目标数据库配置是否启用了 `readonly` 和 `blacklist`。
32
+
33
+ 危险操作包括:
34
+
35
+ - DDL:`drop`、`truncate`、`alter`、`create`
36
+ - DML 写入:`insert`、`update`、`delete`、`merge`
37
+ - Redis 清空或写入:`flushall`、`flushdb`、`set`、`del`
38
+ - MongoDB 写入或删除:`insertOne`、`updateOne`、`deleteMany`、`drop`、`dropDatabase`
39
+ - 任何不可逆、影响生产数据、影响结构或权限的命令
40
+
41
+ 如果用户明确要求执行危险命令,先说明目标数据库名、命令、可能影响,并等待用户明确同意。即使用户同意,也不能绕过本项目配置中的黑名单和只读模式。
42
+
43
+ 黑名单优先级高于只读模式。命令执行前先检查 `blacklist`,命中后直接拒绝;未命中时再检查 `readonly`。
44
+
45
+ 读取配置文件json前需要用户确认,防止密钥泄露。
46
+
47
+ ## 环境校验
48
+
49
+ 调用前优先检查 CLI 是否可用:
50
+
51
+ ```bash
52
+ agent-database-cli --help
53
+ ```
54
+
55
+
56
+ 如果上面的命令失败,检查基础环境:
57
+
58
+ ```bash
59
+ node --version
60
+ npm --version
61
+ ```
62
+
63
+ 如果依赖或构建产物缺失,在项目目录中执行:
64
+
65
+ ```bash
66
+ npm install
67
+ npm run build
68
+ ```
69
+
70
+ 默认配置文件:
71
+
72
+ ```text
73
+ ~/.agent-database-cli/config.json
74
+ ```
75
+
76
+ 指定其它配置文件:
77
+
78
+ ```bash
79
+ AGENT_DATABASE_CLI_CONFIG=/path/to/config.json agent-database-cli list
80
+ ```
81
+
82
+ ## 配置格式
83
+
84
+ 配置文件是 JSON 对象,根字段为 `databases`:
85
+
86
+ ```json
87
+ {
88
+ "databases": {
89
+ "local-mysql": {
90
+ "type": "mysql",
91
+ "url": "mysql://user:password@localhost:3306/app",
92
+ "readonly": true,
93
+ "blacklist": ["drop", "truncate", "delete"],
94
+ "keepAliveSeconds": 180
95
+ }
96
+ }
97
+ }
98
+ ```
99
+
100
+ 字段:
101
+
102
+ - `type`: `mysql`、`postgres`、`redis`、`oracle`、`mongodb`
103
+ - `url`: 数据库连接 URL
104
+ - `database`: MongoDB 默认数据库名,可选
105
+ - `readonly`: 是否启用只读模式
106
+ - `blacklist`: 命令黑名单数组,大小写不敏感
107
+ - `keepAliveSeconds`: daemon 连接空闲释放秒数,默认 `180`
108
+ - `oracleDriver`: Oracle 驱动,可选 `oracledb` 或 `sqlcl`
109
+ - `sqlclPath`: SQLcl 可执行文件路径
110
+ - `javaHome`: SQLcl 使用的 `JAVA_HOME`
111
+
112
+ ## 全局参数
113
+
114
+ - `--format <format>`: 输出格式,支持 `json` 或 `table`,默认 `json`
115
+ - `--help`, `-h`: 输出帮助
116
+ - `--version`, `-V`: 输出版本
117
+
118
+ 配置路径通过环境变量传递:
119
+
120
+ ```bash
121
+ AGENT_DATABASE_CLI_CONFIG=/path/to/config.json
122
+ ```
123
+
124
+ ## list
125
+
126
+ 列出支持的数据库类型、已配置连接和配置文件路径。
127
+
128
+ ```bash
129
+ agent-database-cli list
130
+ agent-database-cli --format table list
131
+ ```
132
+
133
+
134
+ 返回值:
135
+
136
+ - 成功时 stdout 输出 JSON 或表格
137
+ - 输出包含 `supported`、`configured`、`configPath`
138
+ - 配置文件不存在时仍会输出支持列表,`configured` 为空
139
+ - 退出码为 `0`
140
+
141
+ ## test
142
+
143
+ 测试指定数据库连接。
144
+
145
+ ```bash
146
+ agent-database-cli test --db "<databaseName>"
147
+ ```
148
+
149
+ 返回值:
150
+
151
+ - 成功时 stdout 输出 `{ "ok": true }`
152
+ - 连接失败、配置缺失或认证失败时 stderr 输出错误,退出码为 `1`
153
+
154
+ ## exec
155
+
156
+ 统一执行 SQL、Redis 命令或 MongoDB JSON 命令。
157
+
158
+ ```bash
159
+ agent-database-cli exec --db "<databaseName>" --command "<command>"
160
+ ```
161
+
162
+ 示例:
163
+
164
+ ```bash
165
+ agent-database-cli exec --db local-mysql --command "select 1"
166
+ agent-database-cli exec --db cache --command "GET user:1"
167
+ agent-database-cli exec --db local-mongodb --command '{"find":{"collection":"users","filter":{},"limit":1}}'
168
+ ```
169
+
170
+ 返回值:
171
+
172
+ - 成功时 stdout 输出 `rows`、`fields`、`rowCount`
173
+ - 命中黑名单、违反只读模式、命令执行失败时 stderr 输出错误,退出码为 `1`
174
+ - SQLcl Oracle 模式返回 SQLcl 文本输出,字段名为 `output`
175
+
176
+ ## meta
177
+
178
+ 查询数据库元信息。
179
+
180
+ ```bash
181
+ agent-database-cli meta --db "<databaseName>" --type tables
182
+ agent-database-cli meta --db "<databaseName>" --type columns --table users
183
+ agent-database-cli meta --db "<databaseName>" --type collections
184
+ agent-database-cli meta --db "<databaseName>" --type keys --pattern "user:*"
185
+ ```
186
+
187
+ 参数:
188
+
189
+ - `--db <name>`: 数据库配置名
190
+ - `--type <type>`: `tables`、`columns`、`collections`、`keys`
191
+ - `--table <table>`: `columns` 查询所需表名
192
+ - `--pattern <pattern>`: Redis keys 匹配模式
193
+
194
+ 返回值:
195
+
196
+ - 成功时 stdout 输出查询结果
197
+ - 当前数据库不支持的元信息类型会失败并返回错误
198
+
199
+ ## daemon
200
+
201
+ 管理本地连接守护进程。普通 `test`、`exec`、`meta`、`reset` 命令会在 daemon 未运行时自动启动 daemon,已运行时直接复用,不会重复启动。daemon 使用 Unix socket,不暴露网络端口,默认空闲 `300` 秒后自动退出。
202
+
203
+ ```bash
204
+ agent-database-cli daemon start
205
+ agent-database-cli daemon status
206
+ agent-database-cli daemon stop
207
+ ```
208
+
209
+ 返回值:
210
+
211
+ - `start` 成功时输出 socket 路径
212
+ - `status` 成功时输出当前连接列表
213
+ - `stop` 成功时输出停止结果
214
+
215
+ ## reset
216
+
217
+ 重置指定数据库连接。
218
+
219
+ ```bash
220
+ agent-database-cli reset --db "<databaseName>"
221
+ ```
222
+
223
+ 如果 daemon 正在运行,会断开并清理该数据库连接;下一次命令会重新连接。
224
+
225
+ ## Oracle SQLcl
226
+
227
+ 当 Oracle `oracledb` Thin mode 不支持目标库版本时,可以改用 SQLcl。
228
+
229
+ ```json
230
+ {
231
+ "type": "oracle",
232
+ "url": "oracle://USER:password@192.0.2.20:1521/qftest201",
233
+ "oracleDriver": "sqlcl",
234
+ "sqlclPath": "/opt/homebrew/Caskroom/sqlcl/26.1.0.086.1709/sqlcl/bin/sql",
235
+ "javaHome": "/Applications/IntelliJ IDEA Ultimate.app/Contents/jbr/Contents/Home",
236
+ "readonly": true,
237
+ "blacklist": ["drop", "truncate", "delete", "update", "insert", "merge", "alter", "create"]
238
+ }
239
+ ```
240
+
241
+ SQLcl 模式通过 stdin 传入连接脚本,避免密码出现在命令行参数列表中。执行前仍会先走本地黑名单和只读检查。
242
+
243
+ ## 错误规则
244
+
245
+ - 配置文件 JSON 无效时失败
246
+ - `databases` 缺失或数据库配置名不存在时失败
247
+ - 未知 `type`、未知 `oracleDriver` 或非法 `keepAliveSeconds` 会失败
248
+ - `exec` 缺少 `--db` 或 `--command` 会失败
249
+ - `meta columns` 缺少 `--table` 会失败
250
+ - 命中黑名单时失败,错误中包含 `黑名单拒绝执行命令`
251
+ - 违反只读模式时失败,错误中包含 `只读模式拒绝执行命令`
252
+ - 所有失败统一在 stderr 输出错误信息,退出码为 `1`
@@ -0,0 +1,40 @@
1
+ {
2
+ "databases": {
3
+ "local-mysql": {
4
+ "type": "mysql",
5
+ "url": "mysql://test:test@127.0.0.1:3306/app",
6
+ "readonly": false,
7
+ "blacklist": ["drop", "truncate"],
8
+ "keepAliveSeconds": 180
9
+ },
10
+ "local-postgres": {
11
+ "type": "postgres",
12
+ "url": "postgres://test:test@127.0.0.1:5432/app",
13
+ "readonly": false,
14
+ "blacklist": ["drop", "truncate"],
15
+ "keepAliveSeconds": 180
16
+ },
17
+ "local-redis": {
18
+ "type": "redis",
19
+ "url": "redis://127.0.0.1:6379",
20
+ "readonly": false,
21
+ "blacklist": ["flushall", "flushdb"],
22
+ "keepAliveSeconds": 180
23
+ },
24
+ "local-mongodb": {
25
+ "type": "mongodb",
26
+ "url": "mongodb://test:test@127.0.0.1:27017/app?authSource=admin",
27
+ "database": "app",
28
+ "readonly": false,
29
+ "blacklist": ["drop", "dropDatabase", "deleteMany"],
30
+ "keepAliveSeconds": 180
31
+ },
32
+ "local-oracle": {
33
+ "type": "oracle",
34
+ "url": "oracle://test:test@127.0.0.1:1521/FREEPDB1",
35
+ "readonly": false,
36
+ "blacklist": ["drop", "truncate"],
37
+ "keepAliveSeconds": 180
38
+ }
39
+ }
40
+ }
@@ -0,0 +1,12 @@
1
+ import type { DatabaseAdapter, MetadataRequest, QueryResult } from "../types.js";
2
+ export declare abstract class BaseSqlAdapter implements DatabaseAdapter {
3
+ protected connected: boolean;
4
+ abstract connect(): Promise<void>;
5
+ abstract disconnect(): Promise<void>;
6
+ abstract execute(command: string): Promise<QueryResult>;
7
+ protected abstract listTables(): Promise<QueryResult>;
8
+ protected abstract listColumns(table: string): Promise<QueryResult>;
9
+ test(): Promise<void>;
10
+ metadata(request: MetadataRequest): Promise<QueryResult>;
11
+ protected testQuery(): string;
12
+ }
@@ -0,0 +1,22 @@
1
+ export class BaseSqlAdapter {
2
+ connected = false;
3
+ async test() {
4
+ await this.execute(this.testQuery());
5
+ }
6
+ async metadata(request) {
7
+ if (request.type === "tables") {
8
+ return this.listTables();
9
+ }
10
+ if (request.type === "columns") {
11
+ if (!request.table) {
12
+ throw new Error("columns 元信息查询必须提供 --table");
13
+ }
14
+ return this.listColumns(request.table);
15
+ }
16
+ throw new Error(`当前数据库不支持元信息类型: ${request.type}`);
17
+ }
18
+ testQuery() {
19
+ return "select 1";
20
+ }
21
+ }
22
+ //# sourceMappingURL=base-sql.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-sql.js","sourceRoot":"","sources":["../../src/adapters/base-sql.ts"],"names":[],"mappings":"AAEA,MAAM,OAAgB,cAAc;IACxB,SAAS,GAAG,KAAK,CAAC;IAQ5B,KAAK,CAAC,IAAI;QACR,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,OAAwB;QACrC,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC;QAC3B,CAAC;QACD,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC/B,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;gBACnB,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;YAC/C,CAAC;YACD,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACzC,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,kBAAkB,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACpD,CAAC;IAES,SAAS;QACjB,OAAO,UAAU,CAAC;IACpB,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ import type { DatabaseAdapter, DatabaseConfig } from "../types.js";
2
+ export declare function createAdapter(config: DatabaseConfig, url?: string): DatabaseAdapter;