@carllee1983/dbcli 1.45.1 → 1.47.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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dbcli-agent",
3
- "version": "1.45.1",
3
+ "version": "1.47.0",
4
4
  "description": "Database CLI skill and command reference for AI agents.",
5
5
  "author": {
6
6
  "name": "Carl Lee",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dbcli-agent",
3
- "version": "1.45.1",
3
+ "version": "1.47.0",
4
4
  "description": "Database CLI skill and command reference for AI agents",
5
5
  "author": {
6
6
  "name": "Carl Lee",
@@ -77,7 +77,10 @@ When reporting a check's outcome use the vocabulary `verified` (evidence matched
77
77
  `not_verified` (check ran and contradicted) / `indeterminate` (ran but ambiguous) /
78
78
  `blocked` (could not run due to config, permission, schema, placeholder, or safety gate).
79
79
 
80
- Prefer `--format json` for agent-friendly output.
80
+ Prefer `--format json` for agent-friendly output. Diagnostics (auto-limit notices,
81
+ warnings) go to stderr so stdout stays parseable — when piping JSON into a parser,
82
+ use `2>/dev/null` or leave stderr alone. **Never `2>&1`**: it merges those lines back
83
+ into stdout and the parse fails.
81
84
 
82
85
  ## Agent Task Packs
83
86
 
@@ -229,11 +232,13 @@ dbcli init --system postgresql --host localhost --port 5432 \
229
232
  # Reuse an existing .env (DATABASE_URL=postgresql://user:pw@host:5432/db)
230
233
  dbcli init # parses .env in cwd
231
234
 
232
- # MongoDB — full URI (Atlas / replica sets / authSource)
235
+ # MongoDB — field-by-field (no auth = omit --user/--password)
236
+ dbcli init --system mongodb --host localhost --port 27017 --name mydb
237
+ dbcli init --system mongodb --host localhost --port 27017 \
238
+ --user admin --password '<secret>' --auth-source admin --name mydb
239
+ # MongoDB — full URI (advanced escape hatch: multi-host, non-standard driver options)
233
240
  dbcli init --system mongodb \
234
241
  --uri "mongodb+srv://user:pw@cluster.example.mongodb.net/mydb?authSource=admin"
235
- # MongoDB — discrete params (no auth = omit --user/--password)
236
- dbcli init --system mongodb --host localhost --port 27017 --name mydb
237
242
 
238
243
  # Redis — `--name` is the LOGICAL DB INDEX ("0".."15"), not a database name
239
244
  dbcli init --system redis --host localhost --port 6379 --password '<secret>' --name 0
@@ -301,10 +306,25 @@ as a `$env` ref. In a **non-interactive / CI** run you **must** pass all five `-
301
306
  flags; otherwise `init` exits with an error — it never silently falls back to plaintext.
302
307
  `--env-file <path>` is the path to the env file, independent of the `$env` key names.
303
308
 
309
+ **MongoDB is the exception**: only `--env-host` is required non-interactively.
310
+ `--env-port` / `--env-user` / `--env-password` / `--env-database` are optional — an
311
+ omitted one is written as a literal value (empty string for `user` / `password`, the
312
+ resolved value for `port` / `database`) instead of an `$env` ref, so a field the
313
+ connection never needed doesn't later fail closed on an undefined variable. `init`
314
+ also skips the connection test in this mode regardless of `--skip-test` — the `$env`
315
+ refs have no value to connect with yet.
316
+
304
317
  ### Common gotchas
305
318
 
306
319
  - **MongoDB `mongodb+srv://`** — `dbcli doctor` reports whether SRV resolves
307
320
  natively or via the DoH fallback; useful when the runtime restricts DNS.
321
+ - **MongoDB `authSource` / `replicaSet` / `tls` / `srv`** — `init` asks for
322
+ these interactively (`authSource` only when a user is set; `replicaSet` /
323
+ `tls` behind an "advanced options?" prompt); `--auth-source <db>` is the
324
+ only one with a dedicated non-interactive flag, so set `replicaSet` / `tls`
325
+ interactively or edit `.dbcli` afterward. If a config has both `uri` and
326
+ per-field values, `uri` wins silently — `dbcli doctor` flags this and also
327
+ warns when `srv: true` is combined with a non-default `port`.
308
328
  - **MySQL/Postgres password with `@` `:` `/`** — when using `DATABASE_URL`,
309
329
  percent-encode (`@` → `%40`); discrete `--password` flags do not need encoding.
310
330
  - **Redis `--name`** — accepts only the logical DB index string; non-numeric
@@ -536,4 +556,4 @@ schema. Raw `query` / `export` invocations render a sortable table only.
536
556
  - Blacklisted tables and columns are redacted from query output.
537
557
  - `schema` reports `estimatedRowCount` and `sizeCategory` (small / medium / large / huge). For large/huge tables add `WHERE` or `LIMIT` — bands in reference.md.
538
558
  - `doctor` on `mongodb+srv://` reports whether SRV resolves natively or through the DoH fallback — useful when the runtime restricts DNS.
539
- - **Global flags:** `--version`, `--config <path>`, `--global`, `--use <name>`, `-v` / `--verbose` / `-vv`, `-q` / `--quiet`, `--no-color` (also honours `NO_COLOR`). Root-level flags must precede the command unless the command explicitly declares a command-level option.
559
+ - **Global flags:** `--version`, `--config <path>`, `--global`, `--use <name>`, `--timeout <ms>`, `-v` / `--verbose` / `-vv`, `-q` / `--quiet`, `--no-color` (also honours `NO_COLOR`). Root-level flags must precede the command unless the command explicitly declares a command-level option.
@@ -19,6 +19,28 @@ command-level option is only valid after the command that declares it.
19
19
  | `--config <path>` | Select the `.dbcli` configuration path. |
20
20
  | `--global` | Select the user-global registry at `~/.config/dbcli/config.json` instead of the current project's `.dbcli` config. Place it before the command path. |
21
21
  | `--use <connection>` | Select a named connection for this invocation; place it before the command path unless that command explicitly lists a command-level `--use`. |
22
+ | `--timeout <ms>` | Connection timeout in milliseconds (integer, 100–600000), overriding the connection config's `timeout` field for this invocation. Applies to every engine adapter. Without either the flag or the config field, adapters fall back to their built-in 5000ms default. |
23
+
24
+ `--timeout` is applied only when the adapter is constructed for this invocation — it is
25
+ never written back to `config.json`. Set the connection's `timeout` field instead for a
26
+ value that persists across runs. On PostgreSQL, the same value is also used as the
27
+ session's `statement_timeout` (not just the connection timeout), so a low value can cut
28
+ off a long-running query with an error that looks like a connection timeout; the 100ms
29
+ floor exists specifically to keep that failure mode from being too easy to trigger.
30
+ Elasticsearch applies its timeout per request rather than once for the whole connection.
31
+ The `timeout` field itself always takes a literal number — unlike other connection
32
+ fields, it does not accept an `{"$env": "..."}` reference.
33
+
34
+ ### Redirecting output
35
+
36
+ Results go to stdout; diagnostics (auto-limit notices, warnings, update hints) go to
37
+ stderr. That split is what keeps `--format json` machine-parseable, so do not collapse
38
+ it with `2>&1` — the diagnostic lines land in front of the JSON document and the parse
39
+ fails. Pipe stdout alone, or add `2>/dev/null` when the diagnostics are not wanted:
40
+
41
+ ```bash
42
+ dbcli query '{}' --collection events --format json 2>/dev/null | jq '.rows | length'
43
+ ```
22
44
 
23
45
  ## Commands
24
46
 
@@ -32,10 +54,11 @@ dbcli init --system mysql --host localhost --port 3306 --user root --name mydb
32
54
  dbcli init --use-env-refs # Store env var references
33
55
  dbcli init --no-interactive --force # Non-interactive mode
34
56
 
35
- # MongoDB
36
- dbcli init --system mongodb --uri "mongodb://user:pass@host:27017/mydb?authSource=admin"
37
- dbcli init --system mongodb --host localhost --port 27017 --user admin --password secret --name mydb
57
+ # MongoDB — field-by-field (primary path, same shape as SQL)
58
+ dbcli init --system mongodb --host localhost --port 27017 --user admin --password secret --auth-source admin --name mydb
38
59
  dbcli init --system mongodb --host localhost --port 27017 --name mydb # No auth
60
+ # MongoDB — full URI (advanced fallback: multi-host, non-standard driver options)
61
+ dbcli init --system mongodb --uri "mongodb://user:pass@host:27017/mydb?authSource=admin"
39
62
 
40
63
  # Redis (database = logical DB index)
41
64
  dbcli init --system redis --host localhost --port 6379
@@ -62,7 +85,7 @@ dbcli --global use --list
62
85
 
63
86
  **Environment-reference options:** `--env-host <var>`, `--env-port <var>`, `--env-user <var>`, `--env-password <var>`, `--env-database <var>`
64
87
 
65
- **MongoDB-specific options:** `--uri <uri>` (full connection URI), `--auth-source <db>` (auth database, default: `admin` when user/password set)
88
+ **MongoDB-specific options:** `--uri <uri>` (full connection URI — advanced fallback), `--auth-source <db>` (auth database, default: `admin` when user/password set). Interactive `init` also asks for `replicaSet` and `tls` under an "advanced options?" prompt; there is no dedicated non-interactive flag for either yet — set them interactively or edit `.dbcli` afterward. `srv` (boolean, builds `mongodb+srv://` and resolves hosts via DNS SRV, ignoring `port`) is asked right after `host`, before `port`, since it decides whether `port` is even relevant.
66
89
 
67
90
  **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`.
68
91
 
@@ -117,6 +140,10 @@ agent mode disabled. A host that needs protection from a same-user hostile
117
140
  process can set `DBCLI_CONFIG_INTEGRITY_ANCHOR_DIR` to a protected or read-only
118
141
  directory; trusted writes publish detached digests there.
119
142
 
143
+ When a connection's config fails schema validation, dbcli reports the specific field
144
+ path(s) that are wrong for that connection's declared `system` — not the raw Zod union
145
+ error tree — so a broken `.dbcli` can be fixed without guessing which branch applies.
146
+
120
147
  ### list
121
148
 
122
149
  List all tables (SQL), collections (MongoDB), keys (Redis), or indices (Elasticsearch).
@@ -2025,7 +2052,9 @@ dbcli doctor --format json # JSON output for AI agents
2025
2052
  - Configuration: config file exists/valid, permission level, blacklist completeness (detects unprotected sensitive columns)
2026
2053
  - Connection & Data: database connectivity, schema cache freshness (warns if > 7 days), large table warnings (> 1M rows)
2027
2054
 
2028
- > **MongoDB SRV diagnostics:** When the active connection uses `mongodb+srv://`, `doctor` reports whether the current runtime can resolve SRV records directly or only through the DNS-over-HTTPS fallback used by dbcli. This helps spot execution-environment DNS restrictions even when Compass can connect.
2055
+ > **MongoDB SRV diagnostics:** When the active connection uses `mongodb+srv://` (via a full `uri` or the per-field `srv: true`), `doctor` reports whether the current runtime can resolve SRV records directly or only through the DNS-over-HTTPS fallback used by dbcli. This helps spot execution-environment DNS restrictions even when Compass can connect.
2056
+
2057
+ > **MongoDB connection-field warnings:** `doctor` also warns when a config has both `uri` and per-field values (`host` / `user`) present — `uri` silently wins and the per-field values are ignored — and when `srv: true` is combined with a non-default `port`, since SRV records carry their own ports.
2029
2058
 
2030
2059
  **Exit code:** 0 if all pass or warnings only, 1 if any error
2031
2060
  **Options:** `--format <text|json>`, `--remediation`
@@ -2600,7 +2629,9 @@ Parser behaviour (`src/core/saved-queries/parser.ts::normaliseVisual`):
2600
2629
 
2601
2630
  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.
2602
2631
 
2603
- Atlas-style `mongodb+srv://` URIs are supported. `list` and `query` run against the database configured for the connection, and `query` always requires `--collection <name>`.
2632
+ `init --system mongodb` defaults to a field-by-field wizard (`host`, `srv`, `port`, `user`, `password` + `authSource`, then optional `replicaSet` / `tls`); a full `uri` is an explicit advanced choice in the interactive flow and the unchanged non-interactive path via `--uri`. Optional fields `authSource`, `replicaSet`, `tls`, and `srv` express what previously required embedding options in the `uri` query string. Atlas-style `mongodb+srv://` URIs are supported both as a full `uri` and via the per-field `srv: true` option. `list` and `query` run against the database configured for the connection, and `query` always requires `--collection <name>`.
2633
+
2634
+ The 5000ms default server-selection timeout is often too tight for a connection over a VPN or to Atlas. Set a `timeout` field (ms) in the connection config, or override it per invocation with root-level `--timeout`, e.g. `dbcli --timeout 20000 --use <conn> list`.
2604
2635
 
2605
2636
  **Supported commands:** `init`, `use`, `list`, `schema`, `query`, `q`, `insert`, `update`, `delete`, `export`, `status`, `shell`, `doctor`, `upgrade`, `completion`
2606
2637
 
@@ -2623,7 +2654,10 @@ Atlas-style `mongodb+srv://` URIs are supported. `list` and `query` run against
2623
2654
  ### MongoDB-specific workflow
2624
2655
 
2625
2656
  ```bash
2626
- # 1. Initialize (URI or individual params)
2657
+ # 1. Initialize field-by-field (primary path)
2658
+ dbcli init --system mongodb --host localhost --port 27017 \
2659
+ --user admin --password '<secret>' --auth-source admin --name mydb
2660
+ # ...or a full URI (advanced fallback, e.g. Atlas SRV clusters)
2627
2661
  dbcli init --system mongodb --uri "mongodb+srv://user:pass@cluster.example.mongodb.net/mydb"
2628
2662
 
2629
2663
  # 2. List collections
@@ -2663,7 +2697,7 @@ Redis connections speak Redis commands rather than SQL. The adapter uses Bun's n
2663
2697
 
2664
2698
  - Required fields: `system: redis`, `host`, `port`. `password` and `database` are optional.
2665
2699
  - `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.
2666
- - `connection.timeout` (ms, default 5000) maps to the client's `connectionTimeout`.
2700
+ - `connection.timeout` (ms, default 5000) maps to the client's `connectionTimeout`; root-level `--timeout <ms>` overrides it for a single invocation.
2667
2701
 
2668
2702
  ### Permission classification
2669
2703
 
@@ -2793,7 +2827,7 @@ Elasticsearch connections speak the REST API. The adapter is fetch-based (no SDK
2793
2827
  - Either `host` + `port` (default `https://localhost:9200`) or `nodes: [...]` (first node is used) or `cloudId`.
2794
2828
  - Auth precedence: `apiKey` → `user`/`password` (HTTP Basic). Leave both unset for an open cluster.
2795
2829
  - `protocol` defaults to `https`. For TLS quirks: `caPath` (path to a PEM bundle) and `rejectUnauthorized: false` (last resort).
2796
- - `connection.timeout` (ms, default 5000) is wired to `AbortController` on every request.
2830
+ - `connection.timeout` (ms, default 5000) is wired to `AbortController` on every request; root-level `--timeout <ms>` overrides it for a single invocation.
2797
2831
 
2798
2832
  ### Permission classification
2799
2833
 
@@ -2,7 +2,7 @@
2
2
  "name": "dbcli-agent",
3
3
  "displayName": "dbcli Agent",
4
4
  "description": "Database CLI skill and command reference for AI agents.",
5
- "version": "1.45.1",
5
+ "version": "1.47.0",
6
6
  "author": {
7
7
  "name": "Carl Lee",
8
8
  "url": "https://github.com/CarlLee1983"
@@ -77,7 +77,10 @@ When reporting a check's outcome use the vocabulary `verified` (evidence matched
77
77
  `not_verified` (check ran and contradicted) / `indeterminate` (ran but ambiguous) /
78
78
  `blocked` (could not run due to config, permission, schema, placeholder, or safety gate).
79
79
 
80
- Prefer `--format json` for agent-friendly output.
80
+ Prefer `--format json` for agent-friendly output. Diagnostics (auto-limit notices,
81
+ warnings) go to stderr so stdout stays parseable — when piping JSON into a parser,
82
+ use `2>/dev/null` or leave stderr alone. **Never `2>&1`**: it merges those lines back
83
+ into stdout and the parse fails.
81
84
 
82
85
  ## Agent Task Packs
83
86
 
@@ -229,11 +232,13 @@ dbcli init --system postgresql --host localhost --port 5432 \
229
232
  # Reuse an existing .env (DATABASE_URL=postgresql://user:pw@host:5432/db)
230
233
  dbcli init # parses .env in cwd
231
234
 
232
- # MongoDB — full URI (Atlas / replica sets / authSource)
235
+ # MongoDB — field-by-field (no auth = omit --user/--password)
236
+ dbcli init --system mongodb --host localhost --port 27017 --name mydb
237
+ dbcli init --system mongodb --host localhost --port 27017 \
238
+ --user admin --password '<secret>' --auth-source admin --name mydb
239
+ # MongoDB — full URI (advanced escape hatch: multi-host, non-standard driver options)
233
240
  dbcli init --system mongodb \
234
241
  --uri "mongodb+srv://user:pw@cluster.example.mongodb.net/mydb?authSource=admin"
235
- # MongoDB — discrete params (no auth = omit --user/--password)
236
- dbcli init --system mongodb --host localhost --port 27017 --name mydb
237
242
 
238
243
  # Redis — `--name` is the LOGICAL DB INDEX ("0".."15"), not a database name
239
244
  dbcli init --system redis --host localhost --port 6379 --password '<secret>' --name 0
@@ -301,10 +306,25 @@ as a `$env` ref. In a **non-interactive / CI** run you **must** pass all five `-
301
306
  flags; otherwise `init` exits with an error — it never silently falls back to plaintext.
302
307
  `--env-file <path>` is the path to the env file, independent of the `$env` key names.
303
308
 
309
+ **MongoDB is the exception**: only `--env-host` is required non-interactively.
310
+ `--env-port` / `--env-user` / `--env-password` / `--env-database` are optional — an
311
+ omitted one is written as a literal value (empty string for `user` / `password`, the
312
+ resolved value for `port` / `database`) instead of an `$env` ref, so a field the
313
+ connection never needed doesn't later fail closed on an undefined variable. `init`
314
+ also skips the connection test in this mode regardless of `--skip-test` — the `$env`
315
+ refs have no value to connect with yet.
316
+
304
317
  ### Common gotchas
305
318
 
306
319
  - **MongoDB `mongodb+srv://`** — `dbcli doctor` reports whether SRV resolves
307
320
  natively or via the DoH fallback; useful when the runtime restricts DNS.
321
+ - **MongoDB `authSource` / `replicaSet` / `tls` / `srv`** — `init` asks for
322
+ these interactively (`authSource` only when a user is set; `replicaSet` /
323
+ `tls` behind an "advanced options?" prompt); `--auth-source <db>` is the
324
+ only one with a dedicated non-interactive flag, so set `replicaSet` / `tls`
325
+ interactively or edit `.dbcli` afterward. If a config has both `uri` and
326
+ per-field values, `uri` wins silently — `dbcli doctor` flags this and also
327
+ warns when `srv: true` is combined with a non-default `port`.
308
328
  - **MySQL/Postgres password with `@` `:` `/`** — when using `DATABASE_URL`,
309
329
  percent-encode (`@` → `%40`); discrete `--password` flags do not need encoding.
310
330
  - **Redis `--name`** — accepts only the logical DB index string; non-numeric
@@ -536,4 +556,4 @@ schema. Raw `query` / `export` invocations render a sortable table only.
536
556
  - Blacklisted tables and columns are redacted from query output.
537
557
  - `schema` reports `estimatedRowCount` and `sizeCategory` (small / medium / large / huge). For large/huge tables add `WHERE` or `LIMIT` — bands in reference.md.
538
558
  - `doctor` on `mongodb+srv://` reports whether SRV resolves natively or through the DoH fallback — useful when the runtime restricts DNS.
539
- - **Global flags:** `--version`, `--config <path>`, `--global`, `--use <name>`, `-v` / `--verbose` / `-vv`, `-q` / `--quiet`, `--no-color` (also honours `NO_COLOR`). Root-level flags must precede the command unless the command explicitly declares a command-level option.
559
+ - **Global flags:** `--version`, `--config <path>`, `--global`, `--use <name>`, `--timeout <ms>`, `-v` / `--verbose` / `-vv`, `-q` / `--quiet`, `--no-color` (also honours `NO_COLOR`). Root-level flags must precede the command unless the command explicitly declares a command-level option.
@@ -19,6 +19,28 @@ command-level option is only valid after the command that declares it.
19
19
  | `--config <path>` | Select the `.dbcli` configuration path. |
20
20
  | `--global` | Select the user-global registry at `~/.config/dbcli/config.json` instead of the current project's `.dbcli` config. Place it before the command path. |
21
21
  | `--use <connection>` | Select a named connection for this invocation; place it before the command path unless that command explicitly lists a command-level `--use`. |
22
+ | `--timeout <ms>` | Connection timeout in milliseconds (integer, 100–600000), overriding the connection config's `timeout` field for this invocation. Applies to every engine adapter. Without either the flag or the config field, adapters fall back to their built-in 5000ms default. |
23
+
24
+ `--timeout` is applied only when the adapter is constructed for this invocation — it is
25
+ never written back to `config.json`. Set the connection's `timeout` field instead for a
26
+ value that persists across runs. On PostgreSQL, the same value is also used as the
27
+ session's `statement_timeout` (not just the connection timeout), so a low value can cut
28
+ off a long-running query with an error that looks like a connection timeout; the 100ms
29
+ floor exists specifically to keep that failure mode from being too easy to trigger.
30
+ Elasticsearch applies its timeout per request rather than once for the whole connection.
31
+ The `timeout` field itself always takes a literal number — unlike other connection
32
+ fields, it does not accept an `{"$env": "..."}` reference.
33
+
34
+ ### Redirecting output
35
+
36
+ Results go to stdout; diagnostics (auto-limit notices, warnings, update hints) go to
37
+ stderr. That split is what keeps `--format json` machine-parseable, so do not collapse
38
+ it with `2>&1` — the diagnostic lines land in front of the JSON document and the parse
39
+ fails. Pipe stdout alone, or add `2>/dev/null` when the diagnostics are not wanted:
40
+
41
+ ```bash
42
+ dbcli query '{}' --collection events --format json 2>/dev/null | jq '.rows | length'
43
+ ```
22
44
 
23
45
  ## Commands
24
46
 
@@ -32,10 +54,11 @@ dbcli init --system mysql --host localhost --port 3306 --user root --name mydb
32
54
  dbcli init --use-env-refs # Store env var references
33
55
  dbcli init --no-interactive --force # Non-interactive mode
34
56
 
35
- # MongoDB
36
- dbcli init --system mongodb --uri "mongodb://user:pass@host:27017/mydb?authSource=admin"
37
- dbcli init --system mongodb --host localhost --port 27017 --user admin --password secret --name mydb
57
+ # MongoDB — field-by-field (primary path, same shape as SQL)
58
+ dbcli init --system mongodb --host localhost --port 27017 --user admin --password secret --auth-source admin --name mydb
38
59
  dbcli init --system mongodb --host localhost --port 27017 --name mydb # No auth
60
+ # MongoDB — full URI (advanced fallback: multi-host, non-standard driver options)
61
+ dbcli init --system mongodb --uri "mongodb://user:pass@host:27017/mydb?authSource=admin"
39
62
 
40
63
  # Redis (database = logical DB index)
41
64
  dbcli init --system redis --host localhost --port 6379
@@ -62,7 +85,7 @@ dbcli --global use --list
62
85
 
63
86
  **Environment-reference options:** `--env-host <var>`, `--env-port <var>`, `--env-user <var>`, `--env-password <var>`, `--env-database <var>`
64
87
 
65
- **MongoDB-specific options:** `--uri <uri>` (full connection URI), `--auth-source <db>` (auth database, default: `admin` when user/password set)
88
+ **MongoDB-specific options:** `--uri <uri>` (full connection URI — advanced fallback), `--auth-source <db>` (auth database, default: `admin` when user/password set). Interactive `init` also asks for `replicaSet` and `tls` under an "advanced options?" prompt; there is no dedicated non-interactive flag for either yet — set them interactively or edit `.dbcli` afterward. `srv` (boolean, builds `mongodb+srv://` and resolves hosts via DNS SRV, ignoring `port`) is asked right after `host`, before `port`, since it decides whether `port` is even relevant.
66
89
 
67
90
  **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`.
68
91
 
@@ -117,6 +140,10 @@ agent mode disabled. A host that needs protection from a same-user hostile
117
140
  process can set `DBCLI_CONFIG_INTEGRITY_ANCHOR_DIR` to a protected or read-only
118
141
  directory; trusted writes publish detached digests there.
119
142
 
143
+ When a connection's config fails schema validation, dbcli reports the specific field
144
+ path(s) that are wrong for that connection's declared `system` — not the raw Zod union
145
+ error tree — so a broken `.dbcli` can be fixed without guessing which branch applies.
146
+
120
147
  ### list
121
148
 
122
149
  List all tables (SQL), collections (MongoDB), keys (Redis), or indices (Elasticsearch).
@@ -2025,7 +2052,9 @@ dbcli doctor --format json # JSON output for AI agents
2025
2052
  - Configuration: config file exists/valid, permission level, blacklist completeness (detects unprotected sensitive columns)
2026
2053
  - Connection & Data: database connectivity, schema cache freshness (warns if > 7 days), large table warnings (> 1M rows)
2027
2054
 
2028
- > **MongoDB SRV diagnostics:** When the active connection uses `mongodb+srv://`, `doctor` reports whether the current runtime can resolve SRV records directly or only through the DNS-over-HTTPS fallback used by dbcli. This helps spot execution-environment DNS restrictions even when Compass can connect.
2055
+ > **MongoDB SRV diagnostics:** When the active connection uses `mongodb+srv://` (via a full `uri` or the per-field `srv: true`), `doctor` reports whether the current runtime can resolve SRV records directly or only through the DNS-over-HTTPS fallback used by dbcli. This helps spot execution-environment DNS restrictions even when Compass can connect.
2056
+
2057
+ > **MongoDB connection-field warnings:** `doctor` also warns when a config has both `uri` and per-field values (`host` / `user`) present — `uri` silently wins and the per-field values are ignored — and when `srv: true` is combined with a non-default `port`, since SRV records carry their own ports.
2029
2058
 
2030
2059
  **Exit code:** 0 if all pass or warnings only, 1 if any error
2031
2060
  **Options:** `--format <text|json>`, `--remediation`
@@ -2600,7 +2629,9 @@ Parser behaviour (`src/core/saved-queries/parser.ts::normaliseVisual`):
2600
2629
 
2601
2630
  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.
2602
2631
 
2603
- Atlas-style `mongodb+srv://` URIs are supported. `list` and `query` run against the database configured for the connection, and `query` always requires `--collection <name>`.
2632
+ `init --system mongodb` defaults to a field-by-field wizard (`host`, `srv`, `port`, `user`, `password` + `authSource`, then optional `replicaSet` / `tls`); a full `uri` is an explicit advanced choice in the interactive flow and the unchanged non-interactive path via `--uri`. Optional fields `authSource`, `replicaSet`, `tls`, and `srv` express what previously required embedding options in the `uri` query string. Atlas-style `mongodb+srv://` URIs are supported both as a full `uri` and via the per-field `srv: true` option. `list` and `query` run against the database configured for the connection, and `query` always requires `--collection <name>`.
2633
+
2634
+ The 5000ms default server-selection timeout is often too tight for a connection over a VPN or to Atlas. Set a `timeout` field (ms) in the connection config, or override it per invocation with root-level `--timeout`, e.g. `dbcli --timeout 20000 --use <conn> list`.
2604
2635
 
2605
2636
  **Supported commands:** `init`, `use`, `list`, `schema`, `query`, `q`, `insert`, `update`, `delete`, `export`, `status`, `shell`, `doctor`, `upgrade`, `completion`
2606
2637
 
@@ -2623,7 +2654,10 @@ Atlas-style `mongodb+srv://` URIs are supported. `list` and `query` run against
2623
2654
  ### MongoDB-specific workflow
2624
2655
 
2625
2656
  ```bash
2626
- # 1. Initialize (URI or individual params)
2657
+ # 1. Initialize field-by-field (primary path)
2658
+ dbcli init --system mongodb --host localhost --port 27017 \
2659
+ --user admin --password '<secret>' --auth-source admin --name mydb
2660
+ # ...or a full URI (advanced fallback, e.g. Atlas SRV clusters)
2627
2661
  dbcli init --system mongodb --uri "mongodb+srv://user:pass@cluster.example.mongodb.net/mydb"
2628
2662
 
2629
2663
  # 2. List collections
@@ -2663,7 +2697,7 @@ Redis connections speak Redis commands rather than SQL. The adapter uses Bun's n
2663
2697
 
2664
2698
  - Required fields: `system: redis`, `host`, `port`. `password` and `database` are optional.
2665
2699
  - `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.
2666
- - `connection.timeout` (ms, default 5000) maps to the client's `connectionTimeout`.
2700
+ - `connection.timeout` (ms, default 5000) maps to the client's `connectionTimeout`; root-level `--timeout <ms>` overrides it for a single invocation.
2667
2701
 
2668
2702
  ### Permission classification
2669
2703
 
@@ -2793,7 +2827,7 @@ Elasticsearch connections speak the REST API. The adapter is fetch-based (no SDK
2793
2827
  - Either `host` + `port` (default `https://localhost:9200`) or `nodes: [...]` (first node is used) or `cloudId`.
2794
2828
  - Auth precedence: `apiKey` → `user`/`password` (HTTP Basic). Leave both unset for an open cluster.
2795
2829
  - `protocol` defaults to `https`. For TLS quirks: `caPath` (path to a PEM bundle) and `rejectUnauthorized: false` (last resort).
2796
- - `connection.timeout` (ms, default 5000) is wired to `AbortController` on every request.
2830
+ - `connection.timeout` (ms, default 5000) is wired to `AbortController` on every request; root-level `--timeout <ms>` overrides it for a single invocation.
2797
2831
 
2798
2832
  ### Permission classification
2799
2833
 
package/CHANGELOG.md CHANGED
@@ -5,6 +5,43 @@ 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.47.0] - 2026-08-05 - 連線逾時可設定
9
+
10
+ 決策記錄:`docs/adr/0003-connection-timeout-override-resolved-at-adapter-construction.md`。
11
+
12
+ ### Added
13
+
14
+ - **新的 root-level 全域旗標 `--timeout <ms>`。** 覆寫連線設定中的 `timeout`;兩者都沒有時沿用各 adapter 內建的 5000ms。合法值為 100~600000 的整數,須放在子指令之前(和 `--global` / `--use` 一樣是 root-level flag)。對所有引擎有效,典型用途是 MongoDB 跨 VPN 或連 Atlas 時,預設 5 秒的 server selection timeout 太緊:`dbcli --timeout 20000 --use <conn> list`。這個覆寫只在建立連線時套用,不會寫回設定檔;要永久生效請在連線設定裡寫 `timeout` 欄位。
15
+ - **連線設定檔新增 `timeout` 欄位。** 四種連線 schema 皆支援,毫秒、100~600000 整數、可省略。
16
+
17
+ ### Changed
18
+
19
+ - **設定檔驗證失敗的錯誤訊息改為可讀格式。** 過去會吐出整包 Zod `unionErrors` 巢狀 JSON;現在只列出與該連線 `system` 相符的分支問題,逐欄列出欄位路徑。
20
+ - **文件明確禁止 `2>&1`。** 診斷訊息走 stderr、結果走 stdout,合併兩者會讓 `--format json` 的輸出無法解析;SKILL 與 reference 都補上導管寫法。
21
+
22
+ ## [1.46.0] - 2026-08-04 - MongoDB 逐欄連線設定
23
+
24
+ 決策記錄:`docs/adr/0002-mongodb-connection-field-first-config.md`;規格:`docs/specs/2026-08-04-mongodb-field-first-connection.md`。
25
+
26
+ ### Changed
27
+
28
+ - **⚠️ BREAKING(互動流程):`dbcli init` 對 MongoDB 改為先問「連線設定方式」。** 過去第一個提問是 MongoDB URI,留空才退回逐欄詢問 —— 於是逐欄路徑事實上沒人走,所有文件也只教「整條 URI 貼進去」。現在預設是「逐欄填寫」,貼 URI 降為明示的進階選項。**設定檔格式向下相容**,既有含 `uri` 的設定不需修改;`--uri`、`--no-interactive` 等非互動用法行為完全不變,只有互動提問的順序改變。
29
+ - **逐欄模式在有帳號時會明確寫出 `authSource`。** 過去只有帶 `--auth-source` 才會(而且寫了也會被 schema 丟掉),現在未指定時會寫入 `admin`。連線結果與過去等價(adapter 本來就以 `admin` 為預設),但設定檔內容會多這一行 —— 包含 `--no-interactive` 的既有腳本。
30
+ - **`uri` 與逐欄欄位仍是 `uri` 優先,但不再靜默。** 兩者同時存在時 `dbcli doctor` 會發出 warning 指出逐欄值被忽略;`srv: true` 又指定非預設 `port` 也會 warning。這兩種設定過去都是「改了欄位卻沒生效」而無從診斷。
31
+
32
+ ### Added
33
+
34
+ - **MongoDB 連線設定新增 `authSource` / `replicaSet` / `tls` / `srv` 四個欄位。** 過去這些選項只能塞進 `uri` 的 query string —— 這正是逐欄路徑不堪用的根因。其中 `authSource` 更微妙:runtime 型別與 `init --auth-source` flag 都存在,但 zod schema 沒有此鍵,`z.object` 會 strip 掉未知欄位,於是它落盤即遺失,只有 init 當下那次連線測試吃得到,等同一個死 flag。`srv: true` 會組出 `mongodb+srv://` 並沿用既有的 DNS SRV 展開(含 DoH fallback),讓 Atlas 這類最常見的雲端場景也能逐欄設定。`authSource` 與 `replicaSet` 支援 `{"$env": "..."}` 參照。
35
+ - **MongoDB 逐欄分支支援 `--use-env-refs`。** 過去 mongo 在 init 的 early-return 發生在 env-ref 分支之前,想用環境變數參照只能手改 `config.json`。現在五個 `--env-*` 旗標對 mongo 全部生效,密碼不必明文落盤。與 SQL 路徑的差異:mongo 只要求 `--env-host`,其餘留空即寫入字面值而不產生 `$env` —— 因為未定義的 `$env` 會讓之後每一個指令 fail closed,對無認證連線而言那是壞掉的設定。env-ref 模式同樣跳過連線測試(參照此時還沒有值可連),與 SQL 路徑一致。
36
+ - **連線失敗訊息按成因分類。** 認證失敗提示檢查 `authSource`(並說明 Atlas 與多數自架環境為 `admin`)、DNS/SRV 解析失敗提示 `srv` 設定與網路 DNS、TLS 握手失敗提示 `tls` 欄位與自簽憑證情境。原本三種情況共用同兩條泛用訊息。
37
+
38
+ ### Fixed
39
+
40
+ - **逐欄模式的連線字串跳脫不完整。** `buildUri()` 原本只對 `password` 做 `encodeURIComponent`,`user` 與 `database` 直接字串拼接 —— 帳號含 `@`、資料庫名含 `/` 都會讓 driver 把 authority 切在錯的位置。現在三者一致跳脫,`host` 則改為驗證不含 `/@?#` 並在違反時明確報錯。
41
+ - **`host` 為空字串或含埠號、空白時會產出壞掉的連線字串。** `mongodb://:27017/db` 與 `mongodb://h:1234:27017/db` 過去都會被送進 driver,換來一個難懂的錯誤。現在在組字串前就擋下並說明埠號該填在 `port` 欄位。IPv6 位址需加方括號(`[::1]`),與 driver 的要求一致 —— 未加方括號的 `::1` 過去會組出 `mongodb://::1:27017/db`。同理 `authSource` 為空字串時會退回 `admin`,不再送出 `authSource=`。
42
+ - **連線失敗分類會被連線字串本身誤導。** driver 的錯誤訊息經常回吐原始 URI,而 `mongodb+srv://` 與這次新增的 `?tls=true` 正好含有 `SRV` 與 `TLS` 字樣 —— 用裸字串比對會讓一個單純的連線被拒歸類成 DNS 或 TLS 問題。改為優先讀 driver 的結構化 error code,訊息比對則收斂成 driver 實際會產生的片語。
43
+ - **只填 `user` 沒填 `password` 會靜默降級成無認證連線。** 原本的 `if (user && password)` 在密碼缺漏時直接落到無認證分支,錯誤會延後到伺服器端才浮現、且看起來像是權限問題。現在直接拋 `ConnectionError`,訊息說明補上密碼或一併清空 `user`。
44
+
8
45
  ## [1.45.1] - 2026-08-04 - Windows 上的 agent mode 修復
9
46
 
10
47
  ### Fixed
package/assets/SKILL.md CHANGED
@@ -77,7 +77,10 @@ When reporting a check's outcome use the vocabulary `verified` (evidence matched
77
77
  `not_verified` (check ran and contradicted) / `indeterminate` (ran but ambiguous) /
78
78
  `blocked` (could not run due to config, permission, schema, placeholder, or safety gate).
79
79
 
80
- Prefer `--format json` for agent-friendly output.
80
+ Prefer `--format json` for agent-friendly output. Diagnostics (auto-limit notices,
81
+ warnings) go to stderr so stdout stays parseable — when piping JSON into a parser,
82
+ use `2>/dev/null` or leave stderr alone. **Never `2>&1`**: it merges those lines back
83
+ into stdout and the parse fails.
81
84
 
82
85
  ## Agent Task Packs
83
86
 
@@ -229,11 +232,13 @@ dbcli init --system postgresql --host localhost --port 5432 \
229
232
  # Reuse an existing .env (DATABASE_URL=postgresql://user:pw@host:5432/db)
230
233
  dbcli init # parses .env in cwd
231
234
 
232
- # MongoDB — full URI (Atlas / replica sets / authSource)
235
+ # MongoDB — field-by-field (no auth = omit --user/--password)
236
+ dbcli init --system mongodb --host localhost --port 27017 --name mydb
237
+ dbcli init --system mongodb --host localhost --port 27017 \
238
+ --user admin --password '<secret>' --auth-source admin --name mydb
239
+ # MongoDB — full URI (advanced escape hatch: multi-host, non-standard driver options)
233
240
  dbcli init --system mongodb \
234
241
  --uri "mongodb+srv://user:pw@cluster.example.mongodb.net/mydb?authSource=admin"
235
- # MongoDB — discrete params (no auth = omit --user/--password)
236
- dbcli init --system mongodb --host localhost --port 27017 --name mydb
237
242
 
238
243
  # Redis — `--name` is the LOGICAL DB INDEX ("0".."15"), not a database name
239
244
  dbcli init --system redis --host localhost --port 6379 --password '<secret>' --name 0
@@ -301,10 +306,25 @@ as a `$env` ref. In a **non-interactive / CI** run you **must** pass all five `-
301
306
  flags; otherwise `init` exits with an error — it never silently falls back to plaintext.
302
307
  `--env-file <path>` is the path to the env file, independent of the `$env` key names.
303
308
 
309
+ **MongoDB is the exception**: only `--env-host` is required non-interactively.
310
+ `--env-port` / `--env-user` / `--env-password` / `--env-database` are optional — an
311
+ omitted one is written as a literal value (empty string for `user` / `password`, the
312
+ resolved value for `port` / `database`) instead of an `$env` ref, so a field the
313
+ connection never needed doesn't later fail closed on an undefined variable. `init`
314
+ also skips the connection test in this mode regardless of `--skip-test` — the `$env`
315
+ refs have no value to connect with yet.
316
+
304
317
  ### Common gotchas
305
318
 
306
319
  - **MongoDB `mongodb+srv://`** — `dbcli doctor` reports whether SRV resolves
307
320
  natively or via the DoH fallback; useful when the runtime restricts DNS.
321
+ - **MongoDB `authSource` / `replicaSet` / `tls` / `srv`** — `init` asks for
322
+ these interactively (`authSource` only when a user is set; `replicaSet` /
323
+ `tls` behind an "advanced options?" prompt); `--auth-source <db>` is the
324
+ only one with a dedicated non-interactive flag, so set `replicaSet` / `tls`
325
+ interactively or edit `.dbcli` afterward. If a config has both `uri` and
326
+ per-field values, `uri` wins silently — `dbcli doctor` flags this and also
327
+ warns when `srv: true` is combined with a non-default `port`.
308
328
  - **MySQL/Postgres password with `@` `:` `/`** — when using `DATABASE_URL`,
309
329
  percent-encode (`@` → `%40`); discrete `--password` flags do not need encoding.
310
330
  - **Redis `--name`** — accepts only the logical DB index string; non-numeric
@@ -536,4 +556,4 @@ schema. Raw `query` / `export` invocations render a sortable table only.
536
556
  - Blacklisted tables and columns are redacted from query output.
537
557
  - `schema` reports `estimatedRowCount` and `sizeCategory` (small / medium / large / huge). For large/huge tables add `WHERE` or `LIMIT` — bands in reference.md.
538
558
  - `doctor` on `mongodb+srv://` reports whether SRV resolves natively or through the DoH fallback — useful when the runtime restricts DNS.
539
- - **Global flags:** `--version`, `--config <path>`, `--global`, `--use <name>`, `-v` / `--verbose` / `-vv`, `-q` / `--quiet`, `--no-color` (also honours `NO_COLOR`). Root-level flags must precede the command unless the command explicitly declares a command-level option.
559
+ - **Global flags:** `--version`, `--config <path>`, `--global`, `--use <name>`, `--timeout <ms>`, `-v` / `--verbose` / `-vv`, `-q` / `--quiet`, `--no-color` (also honours `NO_COLOR`). Root-level flags must precede the command unless the command explicitly declares a command-level option.
@@ -60,7 +60,9 @@ legacy 單檔 `.dbcli`。若要防護同一 OS 使用者的惡意 process,host
60
60
 
61
61
  回報驗證結果時使用詞彙:`verified`(證據符合)/ `not_verified`(驗證執行但結果矛盾)/ `indeterminate`(執行但證據不明確)/ `blocked`(因 config、權限、schema、placeholder 或安全閘門導致無法執行)。
62
62
 
63
- 優先用 `--format json` 取得代理友善的輸出。
63
+ 優先用 `--format json` 取得代理友善的輸出。診斷訊息(auto-limit 提示、警告)一律走 stderr,
64
+ stdout 保持可解析——把 JSON 導進 parser 時請用 `2>/dev/null` 或不要動 stderr。
65
+ **絕對不要用 `2>&1`**:那會把那些訊息併回 stdout,解析必定失敗。
64
66
 
65
67
  ## Agent Task Packs
66
68
 
@@ -426,4 +428,4 @@ dbcli export "SELECT * FROM orders" --format html --output orders.html
426
428
  - 被 blacklist 的 table / column 會從查詢輸出中遮蔽。
427
429
  - `schema` 回報 `estimatedRowCount` 與 `sizeCategory`(small / medium / large / huge)。大 / 巨大表要加 `WHERE` 或 `LIMIT` — 分界值見 reference.md。
428
430
  - 對 `mongodb+srv://` 連線,`doctor` 會回報 SRV 是用原生解析或走 DoH fallback — 在執行環境限制 DNS 時很有用。
429
- - **全域旗標:** `--version`、`--config <path>`、`--global`、`--use <name>`、`-v` / `--verbose` / `-vv`、`-q` / `--quiet`、`--no-color`(也尊重 `NO_COLOR`)。除非指令明確宣告 command-level 選項,否則 root-level 旗標必須放在指令之前。
431
+ - **全域旗標:** `--version`、`--config <path>`、`--global`、`--use <name>`、`--timeout <ms>`、`-v` / `--verbose` / `-vv`、`-q` / `--quiet`、`--no-color`(也尊重 `NO_COLOR`)。除非指令明確宣告 command-level 選項,否則 root-level 旗標必須放在指令之前。