@carllee1983/dbcli 1.47.0 → 1.48.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.47.0",
3
+ "version": "1.48.0",
4
4
  "description": "Database CLI skill and command reference for AI agents.",
5
5
  "contextFileName": "AGENTS.md"
6
6
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@carllee1983/dbcli",
3
- "version": "1.47.0",
3
+ "version": "1.48.0",
4
4
  "description": "Database CLI for AI agents",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -47,6 +47,7 @@
47
47
  },
48
48
  "files": [
49
49
  "dist/",
50
+ "!dist/.build-stamp",
50
51
  "assets/",
51
52
  "plugins/",
52
53
  "skills/",
@@ -68,7 +69,7 @@
68
69
  "release:check": "bash scripts/release-check.sh",
69
70
  "plugin:sync": "bun run scripts/sync-plugin-assets.ts --write",
70
71
  "plugin:check": "bun run scripts/sync-plugin-assets.ts",
71
- "test": "bun test",
72
+ "test": "bun test --timeout 30000",
72
73
  "test:unit": "bun test tests/unit tests/core",
73
74
  "test:integration": "bun test tests/integration",
74
75
  "test:docker": "docker compose -f docker-compose.test.yml up -d --wait && bun test tests/integration/adapters; docker compose -f docker-compose.test.yml down",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dbcli-agent",
3
- "version": "1.47.0",
3
+ "version": "1.48.0",
4
4
  "description": "Database CLI skill and command reference for AI agents",
5
5
  "author": {
6
6
  "name": "Carl Lee",
@@ -217,7 +217,10 @@ or `doctor` / `status` reports a missing or invalid config, follow this flow.
217
217
  `--password` / `--name` (and `--system`).
218
218
  3. **What permission tier?** Default to the **lowest** that satisfies the task:
219
219
  `query-only` → `read-write` → `data-admin` → `admin`. Set with `--permission`
220
- (defaults to `query-only`).
220
+ (defaults to `query-only`). Tiers judge what a statement does, not how it
221
+ opens: below `admin`, multi-statement SQL is rejected; snippets must be free
222
+ of write and DDL keywords; MongoDB `$out` / `$merge` need `data-admin` and are
223
+ refused entirely in snippets and `export`.
221
224
  4. **Verify, never assume.** After init: `dbcli status` (system + permission +
222
225
  blacklist summary, no creds) and `dbcli doctor --format json` (env, config
223
226
  shape, connectivity, schema-cache age, Mongo SRV path).
@@ -223,6 +223,13 @@ dbcli query "SELECT * FROM orders" --format html > orders.html # pipe to stdou
223
223
  **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`
224
224
  **Permission:** query-only+ (Redis: per-command; Elasticsearch: per HTTP method/path)
225
225
 
226
+ Below `admin`, SQL holding more than one statement is rejected, because only the
227
+ first statement would decide the permission check while a driver on the simple
228
+ query protocol executes them all. Semicolons inside string literals, backtick
229
+ identifiers, and `#` comments are not separators. A MongoDB pipeline containing
230
+ `$out` or `$merge` requires `data-admin`, and is rejected outright on `export`,
231
+ in snippets, and in multi-connection fan-out.
232
+
226
233
  #### Field projection (`--fields`)
227
234
 
228
235
  ```bash
@@ -279,7 +286,7 @@ instead of silently running its only connection.
279
286
  An explicit comma-separated `--use primary,staging` fans one query out to several named
280
287
  connections. `DBCLI_CONNECTION` always names one literal connection and never enables
281
288
  fan-out. SQL permits `SELECT`, `SHOW`, `DESCRIBE`, and `EXPLAIN`; MongoDB permits filters and
282
- read-only pipelines without top-level `$out` / `$merge`; Elasticsearch permits searches.
289
+ read-only pipelines without `$out` / `$merge`; Elasticsearch permits searches.
283
290
  Redis, writes, `--recovery`, `--ui`, CSV, and HTML are rejected before execution. Each
284
291
  connection keeps its own blacklist, limit metadata, audit entry, and error. Aggregate exit
285
292
  codes are `0` when all succeed, `2` for mixed outcomes, and `1` when all fail or preflight
@@ -531,6 +538,13 @@ dbcli q @analytics/revenue --param days=30 --format html > report.html
531
538
 
532
539
  Each `.sql` file is plain SQL with optional YAML frontmatter inside a leading `-- ---` block. Lines outside frontmatter form the SQL body.
533
540
 
541
+ Snippets are read-only by contract, at every permission level including `admin`.
542
+ A body must be a single statement opening with `SELECT` or `WITH` **and** free of
543
+ write or DDL keywords, so a data-modifying CTE (`WITH x AS (DELETE … RETURNING *)
544
+ SELECT * FROM x`) and `SELECT … INTO` are rejected at parse time rather than at
545
+ execution. A MongoDB body may not contain `$out` or `$merge`. The same rule
546
+ applies to `verify.query` in frontmatter, which `q --verify` executes verbatim.
547
+
534
548
  ```sql
535
549
  -- ---
536
550
  -- name: DAU
@@ -217,7 +217,10 @@ or `doctor` / `status` reports a missing or invalid config, follow this flow.
217
217
  `--password` / `--name` (and `--system`).
218
218
  3. **What permission tier?** Default to the **lowest** that satisfies the task:
219
219
  `query-only` → `read-write` → `data-admin` → `admin`. Set with `--permission`
220
- (defaults to `query-only`).
220
+ (defaults to `query-only`). Tiers judge what a statement does, not how it
221
+ opens: below `admin`, multi-statement SQL is rejected; snippets must be free
222
+ of write and DDL keywords; MongoDB `$out` / `$merge` need `data-admin` and are
223
+ refused entirely in snippets and `export`.
221
224
  4. **Verify, never assume.** After init: `dbcli status` (system + permission +
222
225
  blacklist summary, no creds) and `dbcli doctor --format json` (env, config
223
226
  shape, connectivity, schema-cache age, Mongo SRV path).
@@ -223,6 +223,13 @@ dbcli query "SELECT * FROM orders" --format html > orders.html # pipe to stdou
223
223
  **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`
224
224
  **Permission:** query-only+ (Redis: per-command; Elasticsearch: per HTTP method/path)
225
225
 
226
+ Below `admin`, SQL holding more than one statement is rejected, because only the
227
+ first statement would decide the permission check while a driver on the simple
228
+ query protocol executes them all. Semicolons inside string literals, backtick
229
+ identifiers, and `#` comments are not separators. A MongoDB pipeline containing
230
+ `$out` or `$merge` requires `data-admin`, and is rejected outright on `export`,
231
+ in snippets, and in multi-connection fan-out.
232
+
226
233
  #### Field projection (`--fields`)
227
234
 
228
235
  ```bash
@@ -279,7 +286,7 @@ instead of silently running its only connection.
279
286
  An explicit comma-separated `--use primary,staging` fans one query out to several named
280
287
  connections. `DBCLI_CONNECTION` always names one literal connection and never enables
281
288
  fan-out. SQL permits `SELECT`, `SHOW`, `DESCRIBE`, and `EXPLAIN`; MongoDB permits filters and
282
- read-only pipelines without top-level `$out` / `$merge`; Elasticsearch permits searches.
289
+ read-only pipelines without `$out` / `$merge`; Elasticsearch permits searches.
283
290
  Redis, writes, `--recovery`, `--ui`, CSV, and HTML are rejected before execution. Each
284
291
  connection keeps its own blacklist, limit metadata, audit entry, and error. Aggregate exit
285
292
  codes are `0` when all succeed, `2` for mixed outcomes, and `1` when all fail or preflight
@@ -531,6 +538,13 @@ dbcli q @analytics/revenue --param days=30 --format html > report.html
531
538
 
532
539
  Each `.sql` file is plain SQL with optional YAML frontmatter inside a leading `-- ---` block. Lines outside frontmatter form the SQL body.
533
540
 
541
+ Snippets are read-only by contract, at every permission level including `admin`.
542
+ A body must be a single statement opening with `SELECT` or `WITH` **and** free of
543
+ write or DDL keywords, so a data-modifying CTE (`WITH x AS (DELETE … RETURNING *)
544
+ SELECT * FROM x`) and `SELECT … INTO` are rejected at parse time rather than at
545
+ execution. A MongoDB body may not contain `$out` or `$merge`. The same rule
546
+ applies to `verify.query` in frontmatter, which `q --verify` executes verbatim.
547
+
534
548
  ```sql
535
549
  -- ---
536
550
  -- name: DAU