@carllee1983/dbcli 9.1.2 → 10.0.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": "9.1.2",
3
+ "version": "10.0.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": "9.1.2",
3
+ "version": "10.0.0",
4
4
  "description": "Database CLI skill and command reference for AI agents",
5
5
  "author": {
6
6
  "name": "Carl Lee",
@@ -328,9 +328,10 @@ or `doctor` / `status` reports a missing or invalid config, follow this flow.
328
328
 
329
329
  ### Decision tree (ask before writing)
330
330
 
331
- 1. **One DB or many environments?** One → v1 (single connection). Multiple
332
- environments / tenants / replicas → v2 (`--conn-name <name>`, optionally
333
- `--env-file <path>` per connection).
331
+ 1. **What is the connection name?** Every new connection uses named v2, even
332
+ for one DB. Confirm a nonblank `--conn-name <name>` (optionally an
333
+ `--env-file <path>` per connection). `--name` means the database, not the
334
+ connection. Existing v1 configs remain readable and support named v2 import.
334
335
  2. **Where do credentials live?**
335
336
  - Already in a `.env` (`DATABASE_URL` or `DB_HOST` / `DB_PORT` / `DB_USER` /
336
337
  `DB_PASSWORD` / `DB_NAME` | `DB_DATABASE`) → `init` parses it automatically.
@@ -347,31 +348,41 @@ or `doctor` / `status` reports a missing or invalid config, follow this flow.
347
348
  blacklist summary, no creds) and `dbcli doctor --format json` (env, config
348
349
  shape, connectivity, schema-cache age, Mongo SRV path).
349
350
 
351
+ `init` asks for a connection name in an interactive TTY when `--conn-name` is
352
+ omitted, without suggesting `default`. Blank prompt answers are explained and
353
+ re-prompted; cancellation/end of input stops before testing or writing. An explicit
354
+ nonblank name skips this prompt; `--conn-name default` is valid. An explicitly
355
+ blank `--conn-name` is an error in every mode before testing or writing. Non-TTY, `--no-interactive`,
356
+ and complete `--use-env-refs`/`--env-*` automatic noninteractive mode require an
357
+ explicit nonblank `--conn-name` or fail before database access or config/credential
358
+ writes. Plain `init` and explicit `--config` paths both create named v2, never new
359
+ unnamed v1. `--remove` and `--rename` do not prompt for a new connection name.
360
+
350
361
  ### Per-engine essentials
351
362
 
352
363
  ```bash
353
- # PostgreSQL / MySQL / MariaDB (v1, plain values)
354
- dbcli init --system postgresql --host localhost --port 5432 \
364
+ # PostgreSQL / MySQL / MariaDB (named v2, plain values)
365
+ dbcli init --conn-name local --system postgresql --host localhost --port 5432 \
355
366
  --user app --password '<secret>' --name appdb --permission query-only
356
367
 
357
368
  # Reuse an existing .env (DATABASE_URL=postgresql://user:pw@host:5432/db)
358
369
  dbcli init # parses .env in cwd
359
370
 
360
371
  # MongoDB — field-by-field (no auth = omit --user/--password)
361
- dbcli init --system mongodb --host localhost --port 27017 --name mydb
362
- dbcli init --system mongodb --host localhost --port 27017 \
372
+ dbcli init --conn-name local --system mongodb --host localhost --port 27017 --name mydb
373
+ dbcli init --conn-name local --system mongodb --host localhost --port 27017 \
363
374
  --user admin --password '<secret>' --auth-source admin --name mydb
364
375
  # MongoDB — full URI (advanced escape hatch: multi-host, non-standard driver options)
365
- dbcli init --system mongodb \
376
+ dbcli init --conn-name local --system mongodb \
366
377
  --uri "mongodb+srv://user:pw@cluster.example.mongodb.net/mydb?authSource=admin"
367
378
 
368
379
  # Redis — `--name` is the LOGICAL DB INDEX ("0".."15"), not a database name
369
- dbcli init --system redis --host localhost --port 6379 --password '<secret>' --name 0
380
+ dbcli init --conn-name local --system redis --host localhost --port 6379 --password '<secret>' --name 0
370
381
 
371
382
  # Elasticsearch — basic auth, Cloud ID, or API key
372
- dbcli init --system elasticsearch --host localhost --port 9200 \
383
+ dbcli init --conn-name local --system elasticsearch --host localhost --port 9200 \
373
384
  --user elastic --password '<secret>'
374
- dbcli init --system elasticsearch \
385
+ dbcli init --conn-name local --system elasticsearch \
375
386
  --cloud-id "myCluster:dXMtZWFzdC0xLmF3..." --api-key "<base64>"
376
387
  # Multi-node / custom CA / self-signed: edit `.dbcli` directly to add
377
388
  # `nodes: [...]`, `protocol: https`, `caPath`, `rejectUnauthorized: false`.
@@ -384,13 +395,37 @@ dbcli init --conn-name staging --env-file .env.staging --permission query-only
384
395
  dbcli init --conn-name prod --env-file .env.production --use-env-refs --skip-test
385
396
  dbcli use --list --format json # safe identity inventory: name/env/permission/server/database
386
397
  dbcli use prod # switch default (persists — avoid for one-off queries)
387
- dbcli query --use staging "SELECT 1" # one-shot override on any subcommand
398
+ dbcli use --unset # clear the saved default (v2 only; approved config mutation)
399
+ dbcli --use staging query "SELECT 1" # root-level one-shot selector before any subcommand
388
400
  DBCLI_CONNECTION=staging dbcli query "SELECT 1" # one-shot via env; parallel-safe
389
401
  dbcli --use staging,prod query "SELECT count(*) FROM users" # read-only fan-out
390
402
  dbcli init --rename staging:stg # rename
391
403
  dbcli init --remove stg # remove
392
404
  ```
393
405
 
406
+ V2 may omit `default`; if present, it must be a nonempty existing connection
407
+ name, never `null` or `""`. Without a default, connection-dependent commands
408
+ require `--use` or `DBCLI_CONNECTION` and fail before database access with an
409
+ available-name list, never endpoints or credentials. Do not pick the first name
410
+ to bypass that choice. Priority remains `--use` > `DBCLI_CONNECTION` > saved
411
+ default; conflicting root/command selectors and blank CLI selectors are errors,
412
+ while a blank environment selector is absent. Unknown-name and production
413
+ selection protections still apply.
414
+
415
+ `use --unset` removes only the saved default, reports it cleared, and succeeds
416
+ when already absent without changing connections. It rejects a name, `--list`,
417
+ `--confirm-production`, or `--format json` without writing, and never converts or
418
+ overwrites v1. This is an approved, integrity-protected config mutation, blocked
419
+ in agent mode. `use` describes no default; text inventory has no default marker
420
+ and JSON has `isDefault: false` throughout. `doctor` accepts this v2 shape; select
421
+ a connection explicitly for its connection checks (`dbcli --use staging doctor`).
422
+ Removing the default with `init --remove` clears it and reports that change,
423
+ without choosing a replacement. Other removals preserve the current default or
424
+ its absence; the last connection cannot be deleted. Renaming preserves no
425
+ default, or updates the default name when appropriate. The first explicitly named
426
+ connection defaults a new registry; additions preserve an existing default or
427
+ no-default state. Existing v1 imports and production confirmation rules are unchanged.
428
+
394
429
  Rotating one connection's password — nothing else in the config moves:
395
430
 
396
431
  ```bash
@@ -440,11 +475,12 @@ dbcli init --conn-name prod --env-file .env.production --use-env-refs --skip-tes
440
475
 
441
476
  In an **interactive terminal**, omitting the `--env-*` flags prompts for each key name
442
477
  (defaults above) — you can type a non-default name like `PROD_DB_PASSWORD` and it is stored
443
- as a `$env` ref. In a **non-interactive / CI** run you **must** pass all five `--env-*`
478
+ as a `$env` ref. In a **non-interactive / CI** run you **must** pass `--conn-name` and all five `--env-*`
444
479
  flags; otherwise `init` exits with an error — it never silently falls back to plaintext.
445
480
  `--env-file <path>` is the path to the env file, independent of the `$env` key names.
446
481
 
447
- **MongoDB is the exception**: only `--env-host` is required non-interactively.
482
+ **MongoDB has fewer required env-reference flags**: besides `--conn-name`, only
483
+ `--env-host` is required non-interactively.
448
484
  `--env-port` / `--env-user` / `--env-password` / `--env-database` are optional — an
449
485
  omitted one is written as a literal value (empty string for `user` / `password`, the
450
486
  resolved value for `port` / `database`) instead of an `$env` ref, so a field the
@@ -469,8 +505,10 @@ refs have no value to connect with yet.
469
505
  values are rejected.
470
506
  - **Elasticsearch TLS** — `caPath` and `rejectUnauthorized` are not exposed as
471
507
  flags; edit `.dbcli` after `init` to add them.
472
- - **Re-running `init`** — refuses to overwrite without `--force`; never use
473
- `--force` to "fix" a config full of `{ "$env": "..." }` refs.
508
+ - **Re-running `init` with the same name** — requires interactive overwrite
509
+ confirmation or `--force`; a noninteractive duplicate without `--force` or a
510
+ declined confirmation leaves files untouched. Never use `--force` to "fix"
511
+ a config full of `{ "$env": "..." }` refs or choose a name for the user.
474
512
 
475
513
  Full flags and edge cases: see [reference.md](../skills/dbcli/reference.md#init).
476
514
 
@@ -478,7 +516,7 @@ Full flags and edge cases: see [reference.md](../skills/dbcli/reference.md#init)
478
516
 
479
517
  | Command | Min permission | Summary |
480
518
  |---------|-----------------|---------|
481
- | `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. |
519
+ | `init` | n/a | Create a named v2 connection (`--conn-name` required outside an interactive TTY). **Usually run by the human** — do NOT re-run to strip `{"$env"}` references; that format is intentional. |
482
520
  | `use` | n/a | Show/switch default named connection (v2 only). |
483
521
  | `capabilities` | n/a | Static capability catalog + `check --require <ids>` requirement gate. No database connection. `--format text\|json\|markdown` (`check` is `text\|json`). Exit `0`/`1`/`2`. |
484
522
  | `list` | query-only+ | Tables (SQL), collections (MongoDB), keys (Redis), or indices (Elasticsearch). |
@@ -119,24 +119,24 @@ dbcli query '{}' --collection events --format json 2>/dev/null | jq '.rows | len
119
119
  Initialize `.dbcli` configuration file. Typically run manually by the developer — avoid running on behalf of the user unless explicitly requested.
120
120
 
121
121
  ```bash
122
- dbcli init # Single connection (v1 format)
123
- dbcli init --system mysql --host localhost --port 3306 --user root --name mydb
122
+ dbcli init # Prompt for a name; create named v2
123
+ dbcli init --conn-name local --system mysql --host localhost --port 3306 --user root --name mydb
124
124
  dbcli init --use-env-refs # Store env var references
125
- dbcli init --no-interactive --force # Non-interactive mode
125
+ dbcli init --conn-name local --no-interactive --force # Non-interactive; credentials from environment
126
126
 
127
127
  # MongoDB — field-by-field (primary path, same shape as SQL)
128
- dbcli init --system mongodb --host localhost --port 27017 --user admin --password secret --auth-source admin --name mydb
129
- dbcli init --system mongodb --host localhost --port 27017 --name mydb # No auth
128
+ dbcli init --conn-name local --system mongodb --host localhost --port 27017 --user admin --password secret --auth-source admin --name mydb
129
+ dbcli init --conn-name local --system mongodb --host localhost --port 27017 --name mydb # No auth
130
130
  # MongoDB — full URI (advanced fallback: multi-host, non-standard driver options)
131
- dbcli init --system mongodb --uri "mongodb://user:pass@host:27017/mydb?authSource=admin"
131
+ dbcli init --conn-name local --system mongodb --uri "mongodb://user:pass@host:27017/mydb?authSource=admin"
132
132
 
133
133
  # Redis (database = logical DB index)
134
- dbcli init --system redis --host localhost --port 6379
135
- dbcli init --system redis --host localhost --port 6379 --password secret --name 0
134
+ dbcli init --conn-name local --system redis --host localhost --port 6379
135
+ dbcli init --conn-name local --system redis --host localhost --port 6379 --password secret --name 0
136
136
 
137
137
  # Elasticsearch
138
- dbcli init --system elasticsearch --host localhost --port 9200 --user elastic --password changeme
139
- dbcli init --system elasticsearch --cloud-id "myCluster:dXMtZWFzdC0xLmF3..." --api-key "<base64>"
138
+ dbcli init --conn-name local --system elasticsearch --host localhost --port 9200 --user elastic --password changeme
139
+ dbcli init --conn-name local --system elasticsearch --cloud-id "myCluster:dXMtZWFzdC0xLmF3..." --api-key "<base64>"
140
140
 
141
141
  # Multi-connection (v2 format)
142
142
  dbcli init --conn-name staging --env-file .env.staging # Named connection with custom env file
@@ -151,6 +151,12 @@ dbcli --global init --conn-name shared --system postgresql --host db.example.com
151
151
  dbcli --global use --list
152
152
  ```
153
153
 
154
+ Every new or additional connection needs a nonblank connection name. Pass `--conn-name <name>`, or run `dbcli init` in an interactive terminal to be asked for one. The name prompt has no suggested `default`; empty or whitespace-only answers explain the requirement and prompt again. Cancelling or ending the name prompt stops before any connection test or configuration/credential write. An explicit nonblank `--conn-name` skips this prompt, and `--conn-name default` is valid. An explicitly blank `--conn-name` is an error in every mode, before connection tests or writes. `--name` still means the database name (the logical DB index for Redis), never the connection name.
155
+
156
+ Without a TTY, with `--no-interactive`, or when `--use-env-refs` plus all five `--env-*` options automatically disables interaction, a missing or blank `--conn-name` fails with guidance to supply it, before database access or configuration/credential writes. Complete credentials, `--name`, `--env-file`, and `--force` do not supply a connection name.
157
+
158
+ New initialization always creates named v2 configuration, including plain `init` and explicit `--config` paths; it no longer creates an unnamed v1 configuration. Existing v1 configurations remain readable and their established named v2 import is retained. The first explicitly named connection is still the default in a new registry; adding a connection preserves an existing registry's default or no-default state. An explicitly chosen duplicate name still requires interactive overwrite confirmation or `--force`; a noninteractive duplicate without `--force`, or a declined confirmation, leaves files untouched. `--remove` and `--rename` do not ask for a new connection name.
159
+
154
160
  **Key options:** `--system`, `--permission`, `--use-env-refs`, `--skip-test`, `--no-interactive`, `--force`, `--conn-name <name>`, `--env-file <path>`, `--remove <name>`, `--rename <old:new>`
155
161
 
156
162
  **Environment-reference options:** `--env-host <var>`, `--env-port <var>`, `--env-user <var>`, `--env-password <var>`, `--env-database <var>`
@@ -161,7 +167,27 @@ dbcli --global use --list
161
167
 
162
168
  **Redis note:** the `database` (or `--name`) field is the logical DB index (`"0"` … `"15"`), not a database name.
163
169
 
164
- **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.
170
+ **Multi-connection:** Every newly created connection uses v2 with an explicitly supplied or interactively entered name. Each connection can have its own env file and permission level; `--env-file` does not replace the name requirement. Existing v1 configs are automatically imported as the `default` connection when upgrading.
171
+
172
+ V2 may omit the top-level `default` field; if supplied, it must be a nonempty
173
+ string naming an existing connection. `null`, `""`, and nonexistent names are
174
+ invalid. The first explicitly named connection defaults a new registry; adding
175
+ another preserves the existing default or no-default state. Existing v1 reads
176
+ and named v1 imports remain supported; neither configuration version changes.
177
+
178
+ Legacy project configuration compatibility: adding a connection cannot import a
179
+ direct-project v2 registry when an existing connection uses an `envFile` other
180
+ than `.env.local`. `init` refuses before writing and retains the existing config
181
+ and env files. An administrator must migrate the registry and custom env files
182
+ to supported home storage before retrying. Bound/home-storage v2 configs and
183
+ direct-project v2 configs with no `envFile` or only `.env.local` remain supported.
184
+
185
+ `init --remove <name>` clears `default` and reports that change when removing its
186
+ connection; it never chooses another connection. Removing a non-default keeps
187
+ the saved default, and removing a connection from a no-default config keeps that
188
+ state. The public `removeConnection` helper follows the same rules. Deleting
189
+ the last connection is rejected without changing the config. Renaming preserves
190
+ the no-default state, or updates the default name when renaming that connection.
165
191
 
166
192
  Use root-level `--global` with `init`, `use`, `status`, `query`, or any other command to read or mutate the user-global v2 registry at `~/.config/dbcli/config.json`. Without it, the current project binding remains the source of truth. The global registry uses the same private file mode and integrity record as project home storage.
167
193
 
@@ -169,11 +195,12 @@ Use root-level `--global` with `init`, `use`, `status`, `query`, or any other co
169
195
 
170
196
  ### use
171
197
 
172
- Switch or display the default database connection (v2 multi-connection config).
198
+ Set, clear, or display the default database connection (v2 multi-connection config).
173
199
 
174
200
  ```bash
175
- dbcli use # Show current default connection
201
+ dbcli use # Show the current default, or describe no default
176
202
  dbcli use staging # Switch default to 'staging'
203
+ dbcli use --unset # Clear the saved default; connections are unchanged
177
204
  dbcli use --list # List all connections (* marks default)
178
205
  dbcli use --list --format json # Credential-free connection identity inventory
179
206
  ```
@@ -188,17 +215,43 @@ Cloud ID-only Elasticsearch connections also return `null` instead of default
188
215
  placeholders. It deliberately excludes user names, passwords, URIs, Cloud IDs,
189
216
  API keys, and env variable names.
190
217
  Misspelled selectors suggest nearby configured connection names.
218
+ Without a default, text inventory marks no connection as default and every JSON
219
+ item has `isDefault: false`. Inventory remains usable, and `doctor` accepts an
220
+ omitted default as valid v2 configuration. Its connection checks still require
221
+ an explicit selector, for example `dbcli --use staging doctor`.
191
222
 
192
- Any command can also use `--use <name>` to temporarily select a connection without changing the default:
223
+ Any command can also use root-level `--use <name>` before the command to
224
+ temporarily select a connection without changing the default. `query`, `schema`,
225
+ `list`, `export`, and `check` also accept it after the command:
193
226
 
194
227
  ```bash
195
228
  dbcli query --use staging "SELECT * FROM users LIMIT 10"
196
229
  dbcli list --use prod
197
230
  ```
198
231
 
232
+ Selection precedence is explicit `--use`, then `DBCLI_CONNECTION`, then the
233
+ saved default. Conflicting root-level and command-level selectors are an error;
234
+ blank CLI selectors are invalid, while a blank environment selector is ignored.
235
+ Without a default, connection-dependent commands require an explicit `--use` or
236
+ `DBCLI_CONNECTION` selection. Otherwise they fail before database access with
237
+ an error naming both selectors and listing available connection names, never
238
+ endpoints or credentials. No caller selects the first connection automatically.
239
+ Unknown names and production targets retain their validation and explicit
240
+ selection safeguards.
241
+
242
+ `use --unset` removes only the persisted v2 `default` field and reports that it
243
+ was cleared. It also succeeds when the field is already absent without changing
244
+ connections. It rejects a connection name, `--list`, `--confirm-production`, or
245
+ `--format json` in the same invocation before writing, and never converts or
246
+ overwrites v1. It uses the existing approved, integrity-protected configuration
247
+ write path and is blocked under `DBCLI_AGENT_MODE=1`. To set a default again, use
248
+ `dbcli use <name>`; production defaults still require the exact name repeated in
249
+ `--confirm-production <name>`, and production database access still requires an
250
+ explicit selector even if that connection is the saved default.
251
+
199
252
  **Requires v2 config** (created with `dbcli init --conn-name`).
200
253
 
201
- **Options:** `--list`, `--format <text|json>`, `--confirm-production <name>` (required when explicitly selecting a production connection as the default).
254
+ **Options:** `--list`, `--unset`, `--format <text|json>`, `--confirm-production <name>` (required when explicitly selecting a production connection as the default).
202
255
 
203
256
  ### password
204
257
 
@@ -3591,7 +3644,7 @@ Parser behaviour (`src/core/saved-queries/parser.ts::normaliseVisual`):
3591
3644
 
3592
3645
  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.
3593
3646
 
3594
- `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>`.
3647
+ `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 non-interactive path via `--uri` (with the required `--conn-name`). 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>`.
3595
3648
 
3596
3649
  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`.
3597
3650
 
@@ -3617,10 +3670,10 @@ The 5000ms default server-selection timeout is often too tight for a connection
3617
3670
 
3618
3671
  ```bash
3619
3672
  # 1. Initialize — field-by-field (primary path)
3620
- dbcli init --system mongodb --host localhost --port 27017 \
3673
+ dbcli init --conn-name local --system mongodb --host localhost --port 27017 \
3621
3674
  --user admin --password '<secret>' --auth-source admin --name mydb
3622
3675
  # ...or a full URI (advanced fallback, e.g. Atlas SRV clusters)
3623
- dbcli init --system mongodb --uri "mongodb+srv://user:pass@cluster.example.mongodb.net/mydb"
3676
+ dbcli init --conn-name local --system mongodb --uri "mongodb+srv://user:pass@cluster.example.mongodb.net/mydb"
3624
3677
 
3625
3678
  # 2. List collections
3626
3679
  dbcli list --format json
@@ -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": "9.1.2",
5
+ "version": "10.0.0",
6
6
  "author": {
7
7
  "name": "Carl Lee",
8
8
  "url": "https://github.com/CarlLee1983"
@@ -328,9 +328,10 @@ or `doctor` / `status` reports a missing or invalid config, follow this flow.
328
328
 
329
329
  ### Decision tree (ask before writing)
330
330
 
331
- 1. **One DB or many environments?** One → v1 (single connection). Multiple
332
- environments / tenants / replicas → v2 (`--conn-name <name>`, optionally
333
- `--env-file <path>` per connection).
331
+ 1. **What is the connection name?** Every new connection uses named v2, even
332
+ for one DB. Confirm a nonblank `--conn-name <name>` (optionally an
333
+ `--env-file <path>` per connection). `--name` means the database, not the
334
+ connection. Existing v1 configs remain readable and support named v2 import.
334
335
  2. **Where do credentials live?**
335
336
  - Already in a `.env` (`DATABASE_URL` or `DB_HOST` / `DB_PORT` / `DB_USER` /
336
337
  `DB_PASSWORD` / `DB_NAME` | `DB_DATABASE`) → `init` parses it automatically.
@@ -347,31 +348,41 @@ or `doctor` / `status` reports a missing or invalid config, follow this flow.
347
348
  blacklist summary, no creds) and `dbcli doctor --format json` (env, config
348
349
  shape, connectivity, schema-cache age, Mongo SRV path).
349
350
 
351
+ `init` asks for a connection name in an interactive TTY when `--conn-name` is
352
+ omitted, without suggesting `default`. Blank prompt answers are explained and
353
+ re-prompted; cancellation/end of input stops before testing or writing. An explicit
354
+ nonblank name skips this prompt; `--conn-name default` is valid. An explicitly
355
+ blank `--conn-name` is an error in every mode before testing or writing. Non-TTY, `--no-interactive`,
356
+ and complete `--use-env-refs`/`--env-*` automatic noninteractive mode require an
357
+ explicit nonblank `--conn-name` or fail before database access or config/credential
358
+ writes. Plain `init` and explicit `--config` paths both create named v2, never new
359
+ unnamed v1. `--remove` and `--rename` do not prompt for a new connection name.
360
+
350
361
  ### Per-engine essentials
351
362
 
352
363
  ```bash
353
- # PostgreSQL / MySQL / MariaDB (v1, plain values)
354
- dbcli init --system postgresql --host localhost --port 5432 \
364
+ # PostgreSQL / MySQL / MariaDB (named v2, plain values)
365
+ dbcli init --conn-name local --system postgresql --host localhost --port 5432 \
355
366
  --user app --password '<secret>' --name appdb --permission query-only
356
367
 
357
368
  # Reuse an existing .env (DATABASE_URL=postgresql://user:pw@host:5432/db)
358
369
  dbcli init # parses .env in cwd
359
370
 
360
371
  # MongoDB — field-by-field (no auth = omit --user/--password)
361
- dbcli init --system mongodb --host localhost --port 27017 --name mydb
362
- dbcli init --system mongodb --host localhost --port 27017 \
372
+ dbcli init --conn-name local --system mongodb --host localhost --port 27017 --name mydb
373
+ dbcli init --conn-name local --system mongodb --host localhost --port 27017 \
363
374
  --user admin --password '<secret>' --auth-source admin --name mydb
364
375
  # MongoDB — full URI (advanced escape hatch: multi-host, non-standard driver options)
365
- dbcli init --system mongodb \
376
+ dbcli init --conn-name local --system mongodb \
366
377
  --uri "mongodb+srv://user:pw@cluster.example.mongodb.net/mydb?authSource=admin"
367
378
 
368
379
  # Redis — `--name` is the LOGICAL DB INDEX ("0".."15"), not a database name
369
- dbcli init --system redis --host localhost --port 6379 --password '<secret>' --name 0
380
+ dbcli init --conn-name local --system redis --host localhost --port 6379 --password '<secret>' --name 0
370
381
 
371
382
  # Elasticsearch — basic auth, Cloud ID, or API key
372
- dbcli init --system elasticsearch --host localhost --port 9200 \
383
+ dbcli init --conn-name local --system elasticsearch --host localhost --port 9200 \
373
384
  --user elastic --password '<secret>'
374
- dbcli init --system elasticsearch \
385
+ dbcli init --conn-name local --system elasticsearch \
375
386
  --cloud-id "myCluster:dXMtZWFzdC0xLmF3..." --api-key "<base64>"
376
387
  # Multi-node / custom CA / self-signed: edit `.dbcli` directly to add
377
388
  # `nodes: [...]`, `protocol: https`, `caPath`, `rejectUnauthorized: false`.
@@ -384,13 +395,37 @@ dbcli init --conn-name staging --env-file .env.staging --permission query-only
384
395
  dbcli init --conn-name prod --env-file .env.production --use-env-refs --skip-test
385
396
  dbcli use --list --format json # safe identity inventory: name/env/permission/server/database
386
397
  dbcli use prod # switch default (persists — avoid for one-off queries)
387
- dbcli query --use staging "SELECT 1" # one-shot override on any subcommand
398
+ dbcli use --unset # clear the saved default (v2 only; approved config mutation)
399
+ dbcli --use staging query "SELECT 1" # root-level one-shot selector before any subcommand
388
400
  DBCLI_CONNECTION=staging dbcli query "SELECT 1" # one-shot via env; parallel-safe
389
401
  dbcli --use staging,prod query "SELECT count(*) FROM users" # read-only fan-out
390
402
  dbcli init --rename staging:stg # rename
391
403
  dbcli init --remove stg # remove
392
404
  ```
393
405
 
406
+ V2 may omit `default`; if present, it must be a nonempty existing connection
407
+ name, never `null` or `""`. Without a default, connection-dependent commands
408
+ require `--use` or `DBCLI_CONNECTION` and fail before database access with an
409
+ available-name list, never endpoints or credentials. Do not pick the first name
410
+ to bypass that choice. Priority remains `--use` > `DBCLI_CONNECTION` > saved
411
+ default; conflicting root/command selectors and blank CLI selectors are errors,
412
+ while a blank environment selector is absent. Unknown-name and production
413
+ selection protections still apply.
414
+
415
+ `use --unset` removes only the saved default, reports it cleared, and succeeds
416
+ when already absent without changing connections. It rejects a name, `--list`,
417
+ `--confirm-production`, or `--format json` without writing, and never converts or
418
+ overwrites v1. This is an approved, integrity-protected config mutation, blocked
419
+ in agent mode. `use` describes no default; text inventory has no default marker
420
+ and JSON has `isDefault: false` throughout. `doctor` accepts this v2 shape; select
421
+ a connection explicitly for its connection checks (`dbcli --use staging doctor`).
422
+ Removing the default with `init --remove` clears it and reports that change,
423
+ without choosing a replacement. Other removals preserve the current default or
424
+ its absence; the last connection cannot be deleted. Renaming preserves no
425
+ default, or updates the default name when appropriate. The first explicitly named
426
+ connection defaults a new registry; additions preserve an existing default or
427
+ no-default state. Existing v1 imports and production confirmation rules are unchanged.
428
+
394
429
  Rotating one connection's password — nothing else in the config moves:
395
430
 
396
431
  ```bash
@@ -440,11 +475,12 @@ dbcli init --conn-name prod --env-file .env.production --use-env-refs --skip-tes
440
475
 
441
476
  In an **interactive terminal**, omitting the `--env-*` flags prompts for each key name
442
477
  (defaults above) — you can type a non-default name like `PROD_DB_PASSWORD` and it is stored
443
- as a `$env` ref. In a **non-interactive / CI** run you **must** pass all five `--env-*`
478
+ as a `$env` ref. In a **non-interactive / CI** run you **must** pass `--conn-name` and all five `--env-*`
444
479
  flags; otherwise `init` exits with an error — it never silently falls back to plaintext.
445
480
  `--env-file <path>` is the path to the env file, independent of the `$env` key names.
446
481
 
447
- **MongoDB is the exception**: only `--env-host` is required non-interactively.
482
+ **MongoDB has fewer required env-reference flags**: besides `--conn-name`, only
483
+ `--env-host` is required non-interactively.
448
484
  `--env-port` / `--env-user` / `--env-password` / `--env-database` are optional — an
449
485
  omitted one is written as a literal value (empty string for `user` / `password`, the
450
486
  resolved value for `port` / `database`) instead of an `$env` ref, so a field the
@@ -469,8 +505,10 @@ refs have no value to connect with yet.
469
505
  values are rejected.
470
506
  - **Elasticsearch TLS** — `caPath` and `rejectUnauthorized` are not exposed as
471
507
  flags; edit `.dbcli` after `init` to add them.
472
- - **Re-running `init`** — refuses to overwrite without `--force`; never use
473
- `--force` to "fix" a config full of `{ "$env": "..." }` refs.
508
+ - **Re-running `init` with the same name** — requires interactive overwrite
509
+ confirmation or `--force`; a noninteractive duplicate without `--force` or a
510
+ declined confirmation leaves files untouched. Never use `--force` to "fix"
511
+ a config full of `{ "$env": "..." }` refs or choose a name for the user.
474
512
 
475
513
  Full flags and edge cases: see [reference.md](reference.md#init).
476
514
 
@@ -478,7 +516,7 @@ Full flags and edge cases: see [reference.md](reference.md#init).
478
516
 
479
517
  | Command | Min permission | Summary |
480
518
  |---------|-----------------|---------|
481
- | `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. |
519
+ | `init` | n/a | Create a named v2 connection (`--conn-name` required outside an interactive TTY). **Usually run by the human** — do NOT re-run to strip `{"$env"}` references; that format is intentional. |
482
520
  | `use` | n/a | Show/switch default named connection (v2 only). |
483
521
  | `capabilities` | n/a | Static capability catalog + `check --require <ids>` requirement gate. No database connection. `--format text\|json\|markdown` (`check` is `text\|json`). Exit `0`/`1`/`2`. |
484
522
  | `list` | query-only+ | Tables (SQL), collections (MongoDB), keys (Redis), or indices (Elasticsearch). |