@carllee1983/dbcli 1.1.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,35 @@ 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.2.1] - 2026-03-31
9
+
10
+ ### Fixed
11
+
12
+ - **Config Loader**: Fixed variable naming in `loadConnectionEnv` call, ensuring correct env files are loaded during connection resolution.
13
+
14
+ ## [1.2.0] - 2026-03-31
15
+
16
+ ### Added
17
+
18
+ - **Multi-connection Support (v2)**: Support for multiple named database connections in a single project.
19
+ - New `dbcli use` command to switch between connections.
20
+ - Named connections with custom `.env` files via `init --conn-name` and `--env-file`.
21
+ - Global `--use <name>` flag to execute commands against a specific connection.
22
+ - **Unified DDL Interface (`migrate`)**: Abstracted DDL operations that work across PostgreSQL, MySQL, and MariaDB.
23
+ - 12 subcommands for managing tables, columns, indexes, and constraints.
24
+ - Intelligent SQL generation per database dialect.
25
+ - Default dry-run mode for safety.
26
+ - **Enhanced Data Health Checks**: Added `rowCount` and `size` checks to the `dbcli check` command.
27
+ - **Comprehensive Documentation**: Updated README (en/zh-TW) with Internals & Strategy sections and new command references.
28
+
29
+ ### Changed
30
+
31
+ - **Schema Update Strategy**: Refined how and when the schema snapshot in `.dbcli` is updated.
32
+ - Automatic snapshot refresh after successful `migrate` operations.
33
+ - Real-time schema fetching for data modification commands without affecting the snapshot.
34
+
35
+ ---
36
+
8
37
  ## [1.1.0] - 2026-03-30
9
38
 
10
39
  ### Changed
package/README.md CHANGED
@@ -37,6 +37,7 @@ All messages, help text, error messages, and command output respond to the langu
37
37
 
38
38
  ```bash
39
39
  npm install -g @carllee1983/dbcli
40
+ # or: bun install -g @carllee1983/dbcli
40
41
  ```
41
42
 
42
43
  #### Zero-Install (No Installation Needed)
@@ -44,6 +45,7 @@ npm install -g @carllee1983/dbcli
44
45
  ```bash
45
46
  npx @carllee1983/dbcli init
46
47
  npx @carllee1983/dbcli query "SELECT * FROM users"
48
+ # or with Bun: bunx @carllee1983/dbcli init
47
49
  ```
48
50
 
49
51
  #### Update
@@ -59,12 +61,15 @@ npm update -g @carllee1983/dbcli
59
61
  #### Development Installation
60
62
 
61
63
  ```bash
62
- git clone <repository>
64
+ git clone https://github.com/CarlLee1983/dbcli.git
63
65
  cd dbcli
64
66
  bun install
65
- bun run dev -- --help
67
+ bun run src/cli.ts -- --help
68
+ # or: bun run dev -- --help
66
69
  ```
67
70
 
71
+ When `dbcli` is not on your `PATH`, use `bun run src/cli.ts <subcommand> ...` (same as `bun run dev -- <subcommand> ...`).
72
+
68
73
  ### First Steps
69
74
 
70
75
  ```bash
@@ -86,9 +91,57 @@ dbcli skill --install claude
86
91
 
87
92
  ---
88
93
 
89
- ## API Reference
94
+ ## Multi-connection Support (v2)
95
+
96
+ dbcli supports multiple named database connections within a single project. This is useful for managing different environments (development, staging, production) or multiple databases.
97
+
98
+ ### Initializing Named Connections
99
+
100
+ To create a named connection, use the `--conn-name` option during `init`. You can also specify a custom `.env` file for that connection.
101
+
102
+ ```bash
103
+ # Add a staging connection using .env.staging
104
+ dbcli init --conn-name staging --env-file .env.staging
105
+
106
+ # Add a production connection with environment variable references
107
+ dbcli init --conn-name prod --env-file .env.production --use-env-refs
108
+ ```
109
+
110
+ ### Managing Connections
111
+
112
+ Use the `dbcli use` command to switch between connections or list them.
113
+
114
+ ```bash
115
+ # List all connections (* marks the current default)
116
+ dbcli use --list
117
+
118
+ # Switch the default connection to 'staging'
119
+ dbcli use staging
120
+
121
+ # Show the current default connection
122
+ dbcli use
123
+
124
+ # Remove a connection
125
+ dbcli init --remove staging
126
+
127
+ # Rename a connection
128
+ dbcli init --rename staging:production
129
+ ```
130
+
131
+ ### Using a Specific Connection Temporarily
132
+
133
+ You can use the `--use <name>` global flag to execute any command against a specific connection without changing the default.
134
+
135
+ ```bash
136
+ # Query the production database once
137
+ dbcli query "SELECT count(*) FROM users" --use prod
138
+
139
+ # Check staging table health
140
+ dbcli check users --use staging
141
+ ```
142
+
143
+ ---
90
144
 
91
- ### Commands
92
145
 
93
146
  #### `dbcli init`
94
147
 
@@ -99,7 +152,7 @@ Initialize a new dbcli project with database connection configuration.
99
152
  dbcli init [OPTIONS]
100
153
  ```
101
154
 
102
- **Options:**
155
+ **Options (Basic):**
103
156
  - `--system <type>` — Database system: `postgresql`, `mysql`, `mariadb`
104
157
  - `--host <host>` — Database host
105
158
  - `--port <port>` — Database port
@@ -108,15 +161,16 @@ dbcli init [OPTIONS]
108
161
  - `--name <db>` — Database name
109
162
  - `--permission <level>` — Permission level: `query-only`, `read-write`, `data-admin`, `admin`
110
163
  - `--use-env-refs` — Store environment variable references instead of actual values in config
111
- - `--env-host <var>` — Env var name for host (with `--use-env-refs`)
112
- - `--env-port <var>` — Env var name for port (with `--use-env-refs`)
113
- - `--env-user <var>` — Env var name for user (with `--use-env-refs`)
114
- - `--env-password <var>` — Env var name for password (with `--use-env-refs`)
115
- - `--env-database <var>` — Env var name for database (with `--use-env-refs`)
116
164
  - `--skip-test` — Skip connection test
117
165
  - `--no-interactive` — Non-interactive mode (requires all options)
118
166
  - `--force` — Overwrite existing config without confirmation
119
167
 
168
+ **Options (Multi-connection v2):**
169
+ - `--conn-name <name>` — Create a named connection (e.g., `staging`, `prod`)
170
+ - `--env-file <path>` — Load credentials from a specific `.env` file for this connection
171
+ - `--remove <name>` — Remove a named connection from the config
172
+ - `--rename <old:new>` — Rename an existing connection (format: `old:new`)
173
+
120
174
  **Behavior:**
121
175
  - Reads `.env` file if present (auto-fills DATABASE_URL, DB_* variables)
122
176
  - Prompts for missing values (host, port, user, password, database name, permission level)
@@ -128,15 +182,9 @@ dbcli init [OPTIONS]
128
182
  # Interactive initialization
129
183
  dbcli init
130
184
 
131
- # With environment variables pre-set
132
- export DATABASE_URL="postgresql://user:pass@localhost/mydb"
133
- dbcli init
134
-
135
- # Specify permission level
136
- echo "PERMISSION_LEVEL=admin" >> .env && dbcli init
137
-
138
- # Store env var references instead of values (interactive)
139
- dbcli init --use-env-refs
185
+ # Multi-connection setup
186
+ dbcli init --conn-name staging --env-file .env.staging
187
+ dbcli init --conn-name prod --env-file .env.production --use-env-refs
140
188
 
141
189
  # Store env var references (non-interactive)
142
190
  dbcli init --use-env-refs --system mysql \
@@ -146,6 +194,34 @@ dbcli init --use-env-refs --system mysql \
146
194
  --no-interactive
147
195
  ```
148
196
 
197
+ ---
198
+
199
+ #### `dbcli use` (Requires v2 config)
200
+
201
+ Manage or switch the default database connection in multi-connection projects.
202
+
203
+ **Usage:**
204
+ ```bash
205
+ dbcli use [connection-name] [OPTIONS]
206
+ ```
207
+
208
+ **Options:**
209
+ - `--list` — List all connections and show the current default
210
+
211
+ **Examples:**
212
+ ```bash
213
+ # Show current default connection
214
+ dbcli use
215
+
216
+ # Switch default connection to 'prod'
217
+ dbcli use prod
218
+
219
+ # List all connections
220
+ dbcli use --list
221
+ ```
222
+
223
+ ---
224
+
149
225
  > **`--use-env-refs`:** When enabled, the config stores environment variable names (e.g., `{"$env": "DB_HOST"}`) instead of actual values. This avoids writing sensitive credentials into the config file, making it suitable for multi-environment deployments and CI/CD pipelines. At connection time, dbcli automatically reads the actual values from the referenced environment variables.
150
226
 
151
227
  ---
@@ -224,12 +300,14 @@ dbcli query "SELECT * FROM users"
224
300
 
225
301
  **Options:**
226
302
  - `--format json|table|csv` — Output format (default: table)
227
- - `--output file`Write to file instead of stdout
303
+ - `--limit <number>`Cap rows (overrides the automatic limit in query-only mode)
304
+ - `--no-limit` — Disable the automatic 1000-row cap in query-only mode
228
305
 
229
306
  **Behavior:**
230
307
  - Enforces permission-based restrictions (Query-only mode blocks INSERT/UPDATE/DELETE)
231
- - Auto-limits results to 1000 rows in Query-only mode (notification shown)
308
+ - Auto-limits results to 1000 rows in Query-only mode (notification shown), unless `--no-limit` or `--limit` applies
232
309
  - Returns structured results with metadata (row count, execution time)
310
+ - To write CSV/JSON to a file, use shell redirection or the `export` command
233
311
 
234
312
  **Examples:**
235
313
  ```bash
@@ -239,8 +317,8 @@ dbcli query "SELECT * FROM users"
239
317
  # JSON (for AI/programmatic parsing)
240
318
  dbcli query "SELECT * FROM users" --format json
241
319
 
242
- # CSV export
243
- dbcli query "SELECT * FROM users" --format csv --output users.csv
320
+ # CSV to stdout (redirect to a file)
321
+ dbcli query "SELECT * FROM users" --format csv > users.csv
244
322
 
245
323
  # Pipe to other tools
246
324
  dbcli query "SELECT * FROM products" --format json | jq '.data[] | .name'
@@ -316,9 +394,9 @@ dbcli update users --where "id=2" --set '{"email": "new@example.com"}' --force
316
394
 
317
395
  ---
318
396
 
319
- #### `dbcli delete [table]` (Requires Admin permission only)
397
+ #### `dbcli delete [table]` (Requires Data-Admin or Admin permission)
320
398
 
321
- Delete rows (admin-only for safety).
399
+ Delete rows (blocked for query-only and read-write; requires elevated DML permission).
322
400
 
323
401
  **Usage:**
324
402
  ```bash
@@ -472,6 +550,80 @@ DBCLI_OVERRIDE_BLACKLIST=true dbcli query "SELECT * FROM secrets_vault"
472
550
 
473
551
  ---
474
552
 
553
+ #### `dbcli check`
554
+
555
+ Run data-quality and health checks on tables.
556
+
557
+ **Usage:**
558
+ ```bash
559
+ dbcli check [table] [OPTIONS]
560
+ ```
561
+
562
+ **Options:**
563
+ - `--all` — Check every table (skips huge tables unless `--include-large`)
564
+ - `--include-large` — Include huge tables in `--all` scan
565
+ - `--checks <types>` — Comma-separated checks: `nulls`, `duplicates`, `orphans`, `emptyStrings`, `rowCount`, `size`
566
+ - `--sample <number>` — Sample size for large tables (default: 10000)
567
+ - `--format json|table` — Output format (default: json)
568
+
569
+ **Examples:**
570
+ ```bash
571
+ # Check users table
572
+ dbcli check users
573
+
574
+ # Run specific checks only
575
+ dbcli check orders --checks nulls,orphans --format table
576
+ # Scan all tables
577
+ dbcli check --all
578
+ ```
579
+
580
+ ---
581
+
582
+ **Examples:**
583
+ ```bash
584
+ dbcli check orders --format table
585
+ dbcli check --all --checks nulls,duplicates --format json
586
+ ```
587
+
588
+ ---
589
+
590
+ #### `dbcli diff`
591
+
592
+ Save a schema snapshot or compare the live database to a previous snapshot (tables, columns, indexes).
593
+
594
+ **Usage:**
595
+ ```bash
596
+ dbcli diff --snapshot ./schema-before.json
597
+ dbcli diff --against ./schema-before.json
598
+ dbcli diff --against ./schema-before.json --format table
599
+ ```
600
+
601
+ **Options:**
602
+ - `--snapshot <path>` — Write the current schema to a JSON file
603
+ - `--against <path>` — Diff live schema vs. the saved snapshot
604
+ - `--format json|table` — Output format (default: `json`)
605
+ - `--config <path>` — Config path (default: `.dbcli`)
606
+
607
+ ---
608
+
609
+ #### `dbcli status`
610
+
611
+ Show non-sensitive configuration summary (permission level, DB system, blacklist counts, config metadata version). Does not print connection credentials — intended for AI agents.
612
+
613
+ **Usage:**
614
+ ```bash
615
+ dbcli status
616
+ dbcli status --format text
617
+ dbcli status --format json
618
+ ```
619
+
620
+ **Options:**
621
+ - `--format text|json` — Output format (default: `json`)
622
+
623
+ **Note:** This command reads the default project config path `.dbcli` (not the global `--config` flag).
624
+
625
+ ---
626
+
475
627
  #### `dbcli doctor`
476
628
 
477
629
  Run diagnostic checks on environment, configuration, connection, and data.
@@ -600,6 +752,40 @@ All commands support these global options:
600
752
 
601
753
  ---
602
754
 
755
+ ## Internals & Strategy
756
+
757
+ ### Schema Update Strategy
758
+
759
+ dbcli maintains a schema snapshot in your `.dbcli` config file. This allows AI agents to understand the database structure without constant network overhead. Understanding when this cache updates is key:
760
+
761
+ 1. **Manual Updates:**
762
+ * `dbcli schema`: Performs a full scan of the database.
763
+ * `dbcli schema --refresh`: Incremental update. Detects changes and updates only the affected tables.
764
+ * `dbcli schema --reset`: Clears the cache and re-fetches everything.
765
+ 2. **Automatic Updates (DDL):**
766
+ * When you execute DDL through `dbcli migrate` (e.g., `add-column`), the CLI automatically re-scans the affected table and updates the `.dbcli` snapshot after successful execution.
767
+ 3. **Real-time Validation (Non-cached):**
768
+ * Commands like `insert`, `update`, `delete`, and `check` fetch the latest schema from the database immediately before execution to ensure data integrity, but they **do not** update the long-term snapshot in `.dbcli`.
769
+
770
+ > **Note:** If you change the database schema using external tools (like DBeaver or migration scripts), you **must** run `dbcli schema --refresh` to sync the snapshot so AI agents can see the changes.
771
+
772
+ ### How `dbcli migrate` Works
773
+
774
+ The `migrate` command follows a strict safety pipeline to prevent accidental database corruption:
775
+
776
+ 1. **Permission Check:** Verifies the user has `admin` privileges. DDL is blocked for all other levels.
777
+ 2. **Blacklist Check:** Ensures the operation isn't targeting a table restricted in the security blacklist.
778
+ 3. **Dialect-Specific Generation:** The `DDLGenerator` translates your request into the correct SQL for your system:
779
+ * **PostgreSQL:** Uses `SERIAL`, native `ENUM` types, and double-quoted identifiers.
780
+ * **MySQL/MariaDB:** Uses `AUTO_INCREMENT`, inline `ENUM` definitions, and backticked identifiers.
781
+ 4. **Dry-run (Default):** All commands output the generated SQL for review without executing it.
782
+ 5. **Execution & Confirmation:**
783
+ * Requires the `--execute` flag to run.
784
+ * Destructive operations (like `drop`) require both `--execute` and `--force`.
785
+ 6. **Snapshot Sync:** After successful execution, it automatically triggers a schema refresh for the modified table to keep your `.dbcli` file up to date.
786
+
787
+ ---
788
+
603
789
  ## Permission Model
604
790
 
605
791
  dbcli implements a coarse-grained permission system with three levels. Permission level is set during `dbcli init` and stored in `.dbcli` config file. The blacklist system works alongside permissions to provide fine-grained protection for sensitive tables and columns (see [Data Access Control](#data-access-control)).
@@ -619,8 +805,8 @@ Permission level is set during initialization:
619
805
 
620
806
  ```bash
621
807
  dbcli init
622
- # Prompts: "Permission level? (query-only / read-write / admin)"
623
- # Stored in ~/.dbcli as: "permissionLevel": "query-only"
808
+ # Prompts: permission level (query-only / read-write / data-admin / admin)
809
+ # Stored in project .dbcli/config.json as: "permission": "query-only"
624
810
  ```
625
811
 
626
812
  ### Permission-Based Examples
@@ -644,8 +830,8 @@ dbcli query "SELECT * FROM users"
644
830
  dbcli insert users --data '{"name": "Alice"}'
645
831
  dbcli update users --where "id=1" --set '{"name": "Bob"}'
646
832
 
647
- # Blocked: Delete (safety feature)
648
- dbcli delete users --where "id=1" # ERROR: Admin only
833
+ # Blocked: Delete (requires data-admin or admin)
834
+ dbcli delete users --where "id=1" # ERROR: Permission denied (read-write cannot DELETE)
649
835
  ```
650
836
 
651
837
  #### Admin Mode (Database Administrator)
@@ -768,7 +954,7 @@ After installation, the AI agent will have access to dbcli commands and can use
768
954
 
769
955
  #### Claude Code (Anthropic)
770
956
 
771
- 1. Install dbcli globally: `npm install -g dbcli`
957
+ 1. Install dbcli globally: `npm install -g @carllee1983/dbcli`
772
958
  2. Initialize: `dbcli init` (choose permission level)
773
959
  3. Install skill: `dbcli skill --install claude`
774
960
  4. Restart Claude Code extension
@@ -780,7 +966,7 @@ After installation, the AI agent will have access to dbcli commands and can use
780
966
 
781
967
  #### Gemini CLI (Google)
782
968
 
783
- 1. Install dbcli globally: `npm install -g dbcli`
969
+ 1. Install dbcli globally: `npm install -g @carllee1983/dbcli`
784
970
  2. Initialize: `dbcli init`
785
971
  3. Install skill: `dbcli skill --install gemini`
786
972
  4. Start Gemini: `gemini start`
@@ -792,7 +978,7 @@ After installation, the AI agent will have access to dbcli commands and can use
792
978
 
793
979
  #### GitHub Copilot CLI
794
980
 
795
- 1. Install dbcli globally: `npm install -g dbcli`
981
+ 1. Install dbcli globally: `npm install -g @carllee1983/dbcli`
796
982
  2. Initialize: `dbcli init`
797
983
  3. Install skill: `dbcli skill --install copilot`
798
984
  4. Install Copilot CLI: `npm install -g @github-next/github-copilot-cli`
@@ -804,7 +990,7 @@ After installation, the AI agent will have access to dbcli commands and can use
804
990
 
805
991
  #### Cursor IDE
806
992
 
807
- 1. Install dbcli globally: `npm install -g dbcli`
993
+ 1. Install dbcli globally: `npm install -g @carllee1983/dbcli`
808
994
  2. Initialize: `dbcli init`
809
995
  3. Install skill: `dbcli skill --install cursor`
810
996
  4. Open Cursor editor
@@ -820,7 +1006,7 @@ After installation, the AI agent will have access to dbcli commands and can use
820
1006
 
821
1007
  ```bash
822
1008
  # 1. Install and initialize
823
- npm install -g dbcli
1009
+ npm install -g @carllee1983/dbcli
824
1010
  dbcli init # Choose "query-only" for safety
825
1011
 
826
1012
  # 2. Install skill to Claude Code
@@ -841,7 +1027,7 @@ dbcli dynamically generates skills based on your current configuration:
841
1027
 
842
1028
  ```bash
843
1029
  # When permission level changes, skill updates automatically
844
- # Edit ~/.dbcli and change "permissionLevel" to "admin"
1030
+ # Edit .dbcli/config.json and set "permission" to "admin" (or re-run dbcli init)
845
1031
  dbcli skill # Now shows delete and admin commands
846
1032
 
847
1033
  # Re-install to push changes to AI platform
@@ -880,8 +1066,8 @@ Hostname resolution failed (typo or DNS issue).
880
1066
  **Solutions:**
881
1067
 
882
1068
  ```bash
883
- # Verify hostname in .dbcli
884
- cat ~/.dbcli | grep host
1069
+ # Verify hostname in project config (directory layout: .dbcli/config.json)
1070
+ grep host .dbcli/config.json
885
1071
 
886
1072
  # Test DNS resolution
887
1073
  ping your-hostname.com
@@ -901,18 +1087,18 @@ Trying to write with Query-only permission level.
901
1087
  **Solution:** Re-initialize with higher permission level:
902
1088
 
903
1089
  ```bash
904
- rm ~/.dbcli # Remove old config
905
- dbcli init # Re-run, choose "read-write" or "admin"
1090
+ rm -rf .dbcli # Remove project config (destructive — backup if needed)
1091
+ dbcli init # Re-run, choose "read-write", "data-admin", or "admin"
906
1092
  ```
907
1093
 
908
- #### "Permission denied: DELETE requires Admin"
1094
+ #### "Permission denied: DELETE operation requires Data-Admin or Admin"
909
1095
 
910
- Only Admin can delete rows (safety feature).
1096
+ DELETE is not allowed in query-only or read-write mode.
911
1097
 
912
- **Solution:** Re-initialize with Admin permission, or ask administrator.
1098
+ **Solution:** Use `data-admin` or `admin` permission (re-run `dbcli init`, or edit `.dbcli/config.json`), or ask an administrator.
913
1099
 
914
1100
  ```bash
915
- dbcli init # Choose "admin"
1101
+ dbcli init # Choose "data-admin" or "admin"
916
1102
  dbcli delete users --where "id=1" --force
917
1103
  ```
918
1104
 
@@ -975,11 +1161,11 @@ npx is downloading and caching package.
975
1161
  **Solution:** This is normal on first run. Subsequent runs are instant:
976
1162
 
977
1163
  ```bash
978
- npx dbcli init # First run: 30s (downloads)
979
- npx dbcli init # Second run: <1s (cached)
1164
+ npx @carllee1983/dbcli init # First run: 30s (downloads)
1165
+ npx @carllee1983/dbcli init # Second run: <1s (cached)
980
1166
 
981
1167
  # Or install globally for faster startup
982
- npm install -g dbcli
1168
+ npm install -g @carllee1983/dbcli
983
1169
  dbcli init # All future runs: <1s
984
1170
  ```
985
1171
 
@@ -996,8 +1182,8 @@ npm .cmd wrapper not created or PATH not updated.
996
1182
  ```bash
997
1183
  # Restart terminal to refresh PATH
998
1184
  # OR reinstall globally
999
- npm uninstall -g dbcli
1000
- npm install -g dbcli
1185
+ npm uninstall -g @carllee1983/dbcli
1186
+ npm install -g @carllee1983/dbcli
1001
1187
 
1002
1188
  # Verify installation
1003
1189
  where dbcli # Windows command to find executable
@@ -1039,7 +1225,12 @@ chmod +x dist/cli.mjs
1039
1225
 
1040
1226
  ## Development
1041
1227
 
1042
- See [CONTRIBUTING.md](./CONTRIBUTING.md) for development setup, testing, and release process.
1228
+ ```bash
1229
+ bun test # run test suite
1230
+ bun run build # bundle CLI to dist/ (used before publish)
1231
+ ```
1232
+
1233
+ See [CONTRIBUTING.md](./CONTRIBUTING.md) for full setup, testing, and release process.
1043
1234
 
1044
1235
  ---
1045
1236