@carllee1983/dbcli 1.41.0 → 1.43.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.cursor/rules/dbcli.mdc +30 -6
- package/.cursor/skills/dbcli/reference.md +138 -8
- package/.cursor-plugin/plugin.json +1 -1
- package/.github/skills/dbcli/SKILL.md +30 -6
- package/.github/skills/dbcli/reference.md +138 -8
- package/CHANGELOG.md +49 -0
- package/README.dev.md +1 -1
- package/README.md +72 -10
- package/README.zh-TW.md +70 -10
- package/assets/SKILL.md +30 -6
- package/assets/SKILL.zh-TW.md +28 -5
- package/assets/reference.md +138 -8
- package/assets/ui-template.html +19 -19
- package/dist/agent-core.d.ts +32 -0
- package/dist/agent-core.mjs +92 -0
- package/dist/cli.mjs +2540 -11994
- package/dist/core.d.ts +23 -0
- package/dist/core.mjs +323 -76
- package/dist/ui-style.css +1 -1
- package/gemini-extension.json +1 -1
- package/package.json +9 -3
- package/plugins/dbcli-agent/.codex-plugin/plugin.json +1 -1
- package/plugins/dbcli-agent/skills/dbcli/SKILL.md +30 -6
- package/plugins/dbcli-agent/skills/dbcli/reference.md +138 -8
- package/skills/dbcli/SKILL.md +30 -6
- package/skills/dbcli/reference.md +138 -8
|
@@ -112,7 +112,7 @@ dbcli schema --use prod # Scan prod DB; saves to .dbcli/schemas/prod
|
|
|
112
112
|
|
|
113
113
|
### query
|
|
114
114
|
|
|
115
|
-
Execute SQL
|
|
115
|
+
Execute a SQL statement, MongoDB filter/pipeline, allow-listed Redis command, or Elasticsearch DSL/Lucene query.
|
|
116
116
|
|
|
117
117
|
```bash
|
|
118
118
|
# SQL databases
|
|
@@ -143,13 +143,84 @@ dbcli query "SELECT day, dau FROM dau_daily" --ui # open in brows
|
|
|
143
143
|
dbcli query "SELECT * FROM orders" --format html > orders.html # pipe to stdout
|
|
144
144
|
```
|
|
145
145
|
|
|
146
|
-
**Options:** `--format <table|json|csv|html>`, `--ui` (open the dashboard in the system browser; implies `--format html`), `--limit <number>`, `--no-limit`, `--collection <name>` (MongoDB / Elasticsearch), `--index <name>` (Elasticsearch alias for `--collection`), `--recovery`
|
|
146
|
+
**Options:** `--format <table|json|csv|html>`, `--ui` (open the dashboard in the system browser; implies `--format html`), `--limit <number>`, `--no-limit`, `--collection <name>` (MongoDB / Elasticsearch), `--index <name>` (Elasticsearch alias for `--collection`), `--fields <list>`, `--truncate <number>` / `--no-truncate`, `-f, --query-file <path>`, `--use <name[,name]>`, `--recovery`
|
|
147
147
|
**Permission:** query-only+ (Redis: per-command; Elasticsearch: per HTTP method/path)
|
|
148
148
|
|
|
149
|
+
#### Field projection (`--fields`)
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
dbcli query "SELECT * FROM bet_log" --fields sn,currency,bet
|
|
153
|
+
dbcli query "SELECT * FROM bet_log" --fields=-raw_response,-created_at # exclusion
|
|
154
|
+
dbcli query '{"station_code":"cmg9998"}' --collection raw_bet_log --fields sn,bet
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Include and exclude forms cannot be mixed. Dotted paths (`user.email`) are supported.
|
|
158
|
+
On MongoDB the selection becomes a driver-level `projection` (find) or a trailing
|
|
159
|
+
`$project` stage (aggregate), so the omitted fields never leave the server; `_id` is
|
|
160
|
+
excluded unless listed explicitly. On SQL the rows are projected after fetch — write
|
|
161
|
+
an explicit column list in the `SELECT` when you also want to cut transfer cost.
|
|
162
|
+
Blacklisted columns stay blacklisted: naming one in `--fields` yields no value and the
|
|
163
|
+
result still carries the blacklist `securityNotification`. A requested field that does
|
|
164
|
+
not exist in the result comes back as `null`.
|
|
165
|
+
|
|
166
|
+
#### Cell truncation (`--truncate`)
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
dbcli query "SELECT sn, raw_response FROM bet_log" # table: 120-char default
|
|
170
|
+
dbcli query "SELECT sn, raw_response FROM bet_log" --truncate 40
|
|
171
|
+
dbcli query "SELECT sn, raw_response FROM bet_log" --no-truncate
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Table output truncates each serialized cell at 120 Unicode code points by default and
|
|
175
|
+
appends `…(+N chars)`; counting by code point keeps multi-byte characters and emoji
|
|
176
|
+
intact. `--truncate <n>` sets the width, `--no-truncate` disables it. Explicit truncation
|
|
177
|
+
flags are rejected with JSON, CSV, HTML, and `--ui` output.
|
|
178
|
+
|
|
179
|
+
#### Query from a file or stdin (`-f`)
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
dbcli query -f report.sql
|
|
183
|
+
dbcli query --collection raw_bet_log -f - <<'EOF'
|
|
184
|
+
[{"$match": {"sn": {"$regex": "^SN0000"}}}, {"$group": {"_id": "$currency", "n": {"$sum": 1}}}]
|
|
185
|
+
EOF
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Avoids shell quoting entirely — the usual reason a Mongo pipeline containing `$regex`
|
|
189
|
+
or nested date objects fails. Supplying both `--query-file` and positional query text
|
|
190
|
+
is an error rather than a silent choice, and an empty file or empty stdin is refused.
|
|
191
|
+
`-f -` requires piped input: on an interactive terminal dbcli refuses immediately
|
|
192
|
+
instead of waiting silently for input that is never coming.
|
|
193
|
+
|
|
194
|
+
#### One-shot connection selection and read-only fan-out
|
|
195
|
+
|
|
196
|
+
Selection precedence is explicit `--use`, then `DBCLI_CONNECTION`, then the saved default.
|
|
197
|
+
`query`, `schema`, `list`, `export`, and `check` accept command-level `--use`; for other
|
|
198
|
+
commands use root-level `dbcli --use <name> <command>`. One-shot selectors never update the
|
|
199
|
+
saved default and require a v2 config. A legacy v1 single-connection config rejects them
|
|
200
|
+
instead of silently running its only connection.
|
|
201
|
+
|
|
202
|
+
An explicit comma-separated `--use primary,staging` fans one query out to several named
|
|
203
|
+
connections. `DBCLI_CONNECTION` always names one literal connection and never enables
|
|
204
|
+
fan-out. SQL permits `SELECT`, `SHOW`, `DESCRIBE`, and `EXPLAIN`; MongoDB permits filters and
|
|
205
|
+
read-only pipelines without top-level `$out` / `$merge`; Elasticsearch permits searches.
|
|
206
|
+
Redis, writes, `--recovery`, `--ui`, CSV, and HTML are rejected before execution. Each
|
|
207
|
+
connection keeps its own blacklist, limit metadata, audit entry, and error. Aggregate exit
|
|
208
|
+
codes are `0` when all succeed, `2` for mixed outcomes, and `1` when all fail or preflight
|
|
209
|
+
rejects the request.
|
|
210
|
+
|
|
211
|
+
#### Truncation is stated, not implied
|
|
212
|
+
|
|
213
|
+
When the query-only auto-limit trims the result, the table footer reads
|
|
214
|
+
`Rows: 1000 (truncated; limit 1000)`, `--format json` carries
|
|
215
|
+
`metadata.truncated` and `metadata.limit_applied`, and CSV appends a `#` comment line.
|
|
216
|
+
dbcli fetches one row past the cap to decide this, so a result of exactly 1000 rows is
|
|
217
|
+
reported as `truncated: false` — never infer truncation from a round row count.
|
|
218
|
+
|
|
149
219
|
> **MongoDB notes:**
|
|
150
220
|
> - SQL syntax is rejected — use JSON object (filter) or JSON array (pipeline)
|
|
151
221
|
> - `--collection <name>` is required
|
|
152
|
-
> -
|
|
222
|
+
> - Query-only auto-limit applies to filters and to pipelines without their own
|
|
223
|
+
> `$limit`; the applied cap and truncation are reported in the result metadata
|
|
153
224
|
|
|
154
225
|
> **Redis notes:**
|
|
155
226
|
> - The first token must be an allow-listed command (`GET`/`SET`/`HGET`/`HSET`/`DEL`/...). Unknown commands are refused.
|
|
@@ -661,9 +732,13 @@ dbcli export orders --no-limit --format jsonl # scroll the whole ind
|
|
|
661
732
|
**Options:** `--format <json|jsonl|csv|html>` (required), `--output <path>`, `--force`, `--recovery`, `--collection <name>` (MongoDB collection) / `--index <name>` (Elasticsearch index; alias for `--collection`), `--limit <number>` (overrides auto-limit), `--no-limit` (Elasticsearch full-index scroll)
|
|
662
733
|
**Permission:** query-only+ — SQL, MongoDB, and **(v1.22)** Elasticsearch.
|
|
663
734
|
|
|
735
|
+
If the query-only auto-limit would omit rows, export fails closed with exit code `1` and
|
|
736
|
+
writes no partial file. Re-run with `--no-limit` to export everything, or `--limit N` to
|
|
737
|
+
accept a bounded export explicitly. This applies to SQL, MongoDB, and Elasticsearch.
|
|
738
|
+
|
|
664
739
|
The `html` format emits the same self-contained dashboard as `query --ui` (see [Interactive HTML dashboard](#interactive-html-dashboard)). Because `export` runs raw SQL (no snippet metadata), the HTML report is always rendered as a sortable / filterable table — no KPIs or charts. Use `dbcli q @<name> --format html` (or `--ui`) for the charted view.
|
|
665
740
|
|
|
666
|
-
> **Elasticsearch export (v1.22):** pass a search DSL with `--index <index>` to export the hits, or pass an index name as the query to scroll the whole index via `match_all`. Default cap is 1000 rows; `--no-limit` streams the full index via scroll in batches. Index-level blacklist is checked before export and an audit record is written.
|
|
741
|
+
> **Elasticsearch export (v1.22):** pass a search DSL with `--index <index>` to export the hits, or pass an index name as the query to scroll the whole index via `match_all`. Default cap is 1000 rows; reaching it fails closed unless the caller explicitly uses `--limit N`, while `--no-limit` streams the full index via scroll in batches. Index-level blacklist is checked before export and an audit record is written.
|
|
667
742
|
|
|
668
743
|
### blacklist
|
|
669
744
|
|
|
@@ -722,6 +797,10 @@ separate `--snapshot` / `--against` workflow.
|
|
|
722
797
|
dbcli diff --against-orm prisma/schema.prisma --format json
|
|
723
798
|
dbcli diff --against-orm schema.normalized.json --orm-format json --format table
|
|
724
799
|
|
|
800
|
+
# Drizzle requires a PostgreSQL drizzle-kit v7 snapshot (generate it first)
|
|
801
|
+
drizzle-kit generate
|
|
802
|
+
dbcli diff --against-orm drizzle/meta/0001_snapshot.json --orm-format drizzle --format table
|
|
803
|
+
|
|
725
804
|
# DDL accepts repeatable or comma-separated paths and real filesystem globs
|
|
726
805
|
dbcli diff --against-orm "migrations/*.sql" --format markdown
|
|
727
806
|
dbcli diff --against-orm migrations/base.sql,migrations/accounts.sql \
|
|
@@ -731,11 +810,60 @@ dbcli diff --against-orm migrations/base.sql,migrations/accounts.sql \
|
|
|
731
810
|
dbcli diff --against-orm prisma/schema.prisma --ignore 'public.audit_*,public.Legacy'
|
|
732
811
|
```
|
|
733
812
|
|
|
813
|
+
##### TypeORM
|
|
814
|
+
|
|
815
|
+
TypeORM entities are not parsed directly. `schema:log` prints the SQL that
|
|
816
|
+
`schema:sync` would execute without applying it; `-d` is the required data-source
|
|
817
|
+
path. Generate that DDL, then select the `typeorm` alias so the report is tagged
|
|
818
|
+
`ormSource: typeorm`:
|
|
819
|
+
|
|
820
|
+
```bash
|
|
821
|
+
bunx typeorm schema:log -d <path/to/datasource> > schema.sql
|
|
822
|
+
dbcli diff --against-orm schema.sql --orm-format typeorm --format table
|
|
823
|
+
```
|
|
824
|
+
|
|
825
|
+
With `--orm-format typeorm`, `typeorm_metadata` and `migrations` are
|
|
826
|
+
default-ignored and appear as `unmanaged` rather than scored drift. Passing a
|
|
827
|
+
TypeORM `.ts`, `.js`, `.mjs`, or `.cjs` source file is rejected with the
|
|
828
|
+
`schema:log` command to run. See the
|
|
829
|
+
[TypeORM CLI documentation](https://typeorm.io/docs/using-cli) and
|
|
830
|
+
[`SchemaLogCommand`](https://github.com/typeorm/typeorm/blob/master/src/commands/SchemaLogCommand.ts).
|
|
831
|
+
|
|
832
|
+
##### Sequelize
|
|
833
|
+
|
|
834
|
+
Sequelize CLI does not provide a universal `db:migrate --dry-run`. Point the
|
|
835
|
+
project's existing Sequelize configuration at an empty scratch database, apply
|
|
836
|
+
the migrations there, and dump definitions without row data:
|
|
837
|
+
|
|
838
|
+
```bash
|
|
839
|
+
# Configure Sequelize for an empty scratch database first
|
|
840
|
+
bunx sequelize-cli db:migrate
|
|
841
|
+
|
|
842
|
+
# PostgreSQL scratch database
|
|
843
|
+
pg_dump --schema-only <scratch-database> > schema.sql
|
|
844
|
+
|
|
845
|
+
# MySQL scratch database
|
|
846
|
+
mysqldump --no-data <database> > schema.sql
|
|
847
|
+
|
|
848
|
+
dbcli diff --against-orm schema.sql --orm-format sequelize --format json
|
|
849
|
+
```
|
|
850
|
+
|
|
851
|
+
With `--orm-format sequelize`, `SequelizeMeta` is default-ignored and appears as
|
|
852
|
+
`unmanaged` rather than scored drift. Passing a Sequelize `.ts`, `.js`, `.mjs`,
|
|
853
|
+
or `.cjs` model file is rejected with the scratch-database and schema-only dump
|
|
854
|
+
recipe. See the
|
|
855
|
+
[Sequelize CLI migration command](https://github.com/sequelize/cli/blob/main/src/commands/migrate.js),
|
|
856
|
+
[PostgreSQL `pg_dump`](https://www.postgresql.org/docs/current/app-pgdump.html),
|
|
857
|
+
and [MySQL `mysqldump`](https://dev.mysql.com/doc/refman/8.4/en/mysqldump-definition-data-dumps.html)
|
|
858
|
+
references.
|
|
859
|
+
|
|
734
860
|
| Option | Behavior |
|
|
735
861
|
| :--- | :--- |
|
|
736
|
-
| `--against-orm <paths>` | Repeatable or comma-separated input. DDL inputs support real filesystem globs; matches are deduplicated and put in deterministic path order, then parsed as one shared ordered context so an index in a later file can attach to a table declared in an earlier file. Prisma
|
|
737
|
-
|
|
|
738
|
-
|
|
|
862
|
+
| `--against-orm <paths>` | Repeatable or comma-separated input. DDL-family inputs (raw DDL, TypeORM, and Sequelize) support real filesystem globs; matches are deduplicated and put in deterministic path order, then parsed as one shared ordered context so an index in a later file can attach to a table declared in an earlier file. Prisma, normalized JSON, and Drizzle accept exactly one file, and globs are rejected for those formats. |
|
|
863
|
+
| Drizzle input | Run `drizzle-kit generate`, then pass the PostgreSQL drizzle-kit v7 snapshot at `drizzle/meta/<NNNN>_snapshot.json`. TypeScript ORM schema sources (`.ts` or `.TS`) are rejected with that snapshot-generation hint; dbcli does not parse them directly. |
|
|
864
|
+
| TypeORM / Sequelize input | Generate DDL with the ORM/database tooling, then pass the SQL file with the matching `typeorm` or `sequelize` alias. Entity/model source files are rejected rather than parsed. |
|
|
865
|
+
| `--orm-format prisma\|ddl\|json\|drizzle\|typeorm\|sequelize` | Override extension/content detection. The `typeorm` and `sequelize` aliases use the DDL adapter while preserving the source tag and ORM-specific default ignores. Without an override, dbcli detects Prisma, raw DDL, normalized JSON, or a Drizzle snapshot from the path and content. |
|
|
866
|
+
| `--ignore <globs>` | Comma-separated, case-sensitive table globs. Patterns match the qualified display identity (for example `public.Users`). `_prisma_migrations` is always unmanaged; the TypeORM alias additionally ignores `typeorm_metadata` and `migrations`, and the Sequelize alias additionally ignores `SequelizeMeta`. |
|
|
739
867
|
| `--format json\|table\|markdown` | Select machine JSON, human table, or Markdown output. Markdown is available only in ORM drift mode. |
|
|
740
868
|
| `--recovery` | On an I/O, configuration, empty-cache, invalid-format, or unsupported-engine failure, emit and save a structured recovery envelope. Invalid Prisma/DDL constructs normally become `unparsed` entries instead of throwing. |
|
|
741
869
|
|
|
@@ -783,9 +911,11 @@ another.
|
|
|
783
911
|
columns, multi-schema datasource configuration, malformed declarations, unknown
|
|
784
912
|
attributes, and unsupported native mappings are never guessed.
|
|
785
913
|
|
|
786
|
-
Prisma and
|
|
914
|
+
Prisma, DDL, and Drizzle constructs outside the supported subset are retained in
|
|
787
915
|
`unparsed` with a `blocked:` reason. These entries are separate from scored drift:
|
|
788
916
|
inspect and resolve them before treating an otherwise clean summary as complete.
|
|
917
|
+
Drizzle enums and other unsupported snapshot constructs therefore appear as blocked
|
|
918
|
+
`unparsed` entries rather than managed tables or columns.
|
|
789
919
|
Multi-file DDL is consumed as one deterministic shared ordered statement context,
|
|
790
920
|
so later `CREATE INDEX` statements can reference tables declared in earlier
|
|
791
921
|
files. PostgreSQL `PARTITION BY` and MySQL/MariaDB table engine, charset, and
|