@carllee1983/dbcli 1.10.1 → 1.11.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.
Files changed (31) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/assets/SKILL.md +8 -0
  3. package/assets/snippets/diag/blocking-queries.postgres.sql +17 -0
  4. package/assets/snippets/diag/cache-hit.mysql.sql +1 -0
  5. package/assets/snippets/diag/cache-hit.postgres.sql +1 -0
  6. package/assets/snippets/diag/client-list.redis.sql +8 -0
  7. package/assets/snippets/diag/cluster-info.redis.sql +8 -0
  8. package/assets/snippets/diag/connections.mysql.sql +1 -0
  9. package/assets/snippets/diag/connections.postgres.sql +1 -0
  10. package/assets/snippets/diag/db-size.mysql.sql +1 -0
  11. package/assets/snippets/diag/db-size.postgres.sql +1 -0
  12. package/assets/snippets/diag/es-cluster-health.elasticsearch.sql +1 -0
  13. package/assets/snippets/diag/hot-threads.elasticsearch.sql +9 -0
  14. package/assets/snippets/diag/index-stats.elasticsearch.sql +16 -0
  15. package/assets/snippets/diag/index-usage.mysql.sql +1 -0
  16. package/assets/snippets/diag/index-usage.postgres.sql +1 -0
  17. package/assets/snippets/diag/locks.mysql.sql +1 -0
  18. package/assets/snippets/diag/locks.postgres.sql +1 -0
  19. package/assets/snippets/diag/long-running.mysql.sql +1 -0
  20. package/assets/snippets/diag/long-running.postgres.sql +1 -0
  21. package/assets/snippets/diag/memory-usage.redis.sql +8 -0
  22. package/assets/snippets/diag/missing-indexes.mysql.sql +1 -0
  23. package/assets/snippets/diag/missing-indexes.postgres.sql +1 -0
  24. package/assets/snippets/diag/pending-tasks.elasticsearch.sql +9 -0
  25. package/assets/snippets/diag/redis-key-stats.redis.sql +1 -0
  26. package/assets/snippets/diag/slowlog.redis.sql +12 -0
  27. package/assets/snippets/diag/table-sizes.mysql.sql +1 -0
  28. package/assets/snippets/diag/table-sizes.postgres.sql +1 -0
  29. package/assets/snippets/diag/unassigned-shards.elasticsearch.sql +9 -0
  30. package/dist/cli.mjs +742 -211
  31. package/package.json +12 -14
package/CHANGELOG.md CHANGED
@@ -5,6 +5,22 @@ 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.11.0] - 2026-05-08
9
+
10
+ ### Added
11
+
12
+ - `dbcli queries search <keywords>` — fuzzy keyword search across saved queries.
13
+ - `dbcli queries suggest <intent>` — intent-prefix suggestion.
14
+ - Optional `intent` frontmatter field on snippets.
15
+ - 9 new diagnostic snippets: ES x4 (hot-threads, index-stats, unassigned-shards, pending-tasks); Redis x4 (slowlog, client-list, memory-usage, cluster-info); SQL x1 (blocking-queries.postgres).
16
+ - "When you don't know which query to run" section in SKILL.md.
17
+
18
+ ### Changed
19
+
20
+ - All 18 existing built-in diagnostic snippets backfilled with `intent`.
21
+ - `foldVariants` extracted from `src/commands/queries.ts` to `src/core/saved-queries/fold.ts`.
22
+ - Redis read-only allowlist gained `CLIENT`, `INFO`, `CLUSTER`, `SLOWLOG` for diagnostic snippets.
23
+
8
24
  ## [1.10.1] - 2026-05-08
9
25
 
10
26
  ### Fixed
package/assets/SKILL.md CHANGED
@@ -224,6 +224,14 @@ Run reusable parameterised SELECT snippets stored in your repo.
224
224
  | 2. Inspect | `dbcli queries show @<name>` |
225
225
  | 3. Run | `dbcli q @<name> --param k=v` |
226
226
 
227
+ ### When you don't know which query to run
228
+
229
+ 1. `dbcli queries search <keywords>` — natural keywords, fuzzy ranked
230
+ 2. `dbcli queries suggest <intent>` — browse a category
231
+ Common intents: perf.slow-query, perf.cache-hit, capacity.size,
232
+ safety.connections, monitor.cluster-health
233
+ 3. Once you find one: `dbcli q @<name>` (blacklist always enforced)
234
+
227
235
  Snippets resolve from three layers, **local > shared > builtin** (local wins):
228
236
  - `builtin` — bundled with dbcli (e.g. `@diag/*`); read-only at runtime
229
237
  - `.dbcli-shared/queries/` — committed, team-shared
@@ -0,0 +1,17 @@
1
+ -- ---
2
+ -- name: blocking-queries.postgres
3
+ -- description: Top queries blocking others, with blocker/blocked PIDs
4
+ -- engine: postgres
5
+ -- intent: safety.locks
6
+ -- tags: [diag, postgres, safety]
7
+ -- ---
8
+ SELECT blocked.pid AS blocked_pid,
9
+ blocked.usename AS blocked_user,
10
+ blocking.pid AS blocking_pid,
11
+ blocking.usename AS blocking_user,
12
+ blocked.query AS blocked_query,
13
+ blocking.query AS blocking_query
14
+ FROM pg_stat_activity blocked
15
+ JOIN pg_stat_activity blocking
16
+ ON blocking.pid = ANY(pg_blocking_pids(blocked.pid))
17
+ WHERE blocked.wait_event_type IS NOT NULL;
@@ -2,6 +2,7 @@
2
2
  -- name: InnoDB buffer pool hit ratio (mysql)
3
3
  -- description: Reads from disk vs. read requests from the buffer pool.
4
4
  -- engine: mysql
5
+ -- intent: perf.cache-hit
5
6
  -- ---
6
7
  SELECT
7
8
  (SELECT VARIABLE_VALUE FROM performance_schema.global_status
@@ -2,6 +2,7 @@
2
2
  -- name: Cache hit ratio (postgres)
3
3
  -- description: Heap and index buffer cache hit ratios across user tables.
4
4
  -- engine: postgres
5
+ -- intent: perf.cache-hit
5
6
  -- ---
6
7
  SELECT SUM(heap_blks_read) AS heap_read,
7
8
  SUM(heap_blks_hit) AS heap_hit,
@@ -0,0 +1,8 @@
1
+ -- ---
2
+ -- name: client-list.redis
3
+ -- description: Active Redis client connections
4
+ -- engine: redis
5
+ -- intent: safety.connections
6
+ -- tags: [diag, redis, safety]
7
+ -- ---
8
+ CLIENT LIST
@@ -0,0 +1,8 @@
1
+ -- ---
2
+ -- name: cluster-info.redis
3
+ -- description: Redis cluster status (node count, slots, state)
4
+ -- engine: redis
5
+ -- intent: monitor.cluster-health
6
+ -- tags: [diag, redis]
7
+ -- ---
8
+ CLUSTER INFO
@@ -2,6 +2,7 @@
2
2
  -- name: Active connections (mysql)
3
3
  -- description: Non-sleep processes ordered by elapsed time.
4
4
  -- engine: mysql
5
+ -- intent: safety.connections
5
6
  -- ---
6
7
  SELECT id,
7
8
  user,
@@ -2,6 +2,7 @@
2
2
  -- name: Active connections (postgres)
3
3
  -- description: Active sessions excluding idle, ordered by query start.
4
4
  -- engine: postgres
5
+ -- intent: safety.connections
5
6
  -- ---
6
7
  SELECT pid,
7
8
  usename AS user,
@@ -2,6 +2,7 @@
2
2
  -- name: Database size (mysql)
3
3
  -- description: Total data + index size per schema in MB.
4
4
  -- engine: mysql
5
+ -- intent: capacity.size
5
6
  -- ---
6
7
  SELECT table_schema AS `database`,
7
8
  ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS size_mb
@@ -2,6 +2,7 @@
2
2
  -- name: Database size (postgres)
3
3
  -- description: Each database with pretty-printed total size.
4
4
  -- engine: postgres
5
+ -- intent: capacity.size
5
6
  -- ---
6
7
  SELECT datname AS database,
7
8
  pg_size_pretty(pg_database_size(datname)) AS size
@@ -2,6 +2,7 @@
2
2
  -- name: es-cluster-health
3
3
  -- description: Document counts per index across the cluster
4
4
  -- engine: elasticsearch
5
+ -- intent: monitor.cluster-health
5
6
  -- index: '*'
6
7
  -- tags: [diag, elasticsearch]
7
8
  -- ---
@@ -0,0 +1,9 @@
1
+ -- ---
2
+ -- name: hot-threads.elasticsearch
3
+ -- description: ES nodes hot threads — surface CPU bottlenecks
4
+ -- engine: elasticsearch
5
+ -- index: '_nodes/hot_threads'
6
+ -- intent: monitor.cluster-health
7
+ -- tags: [diag, elasticsearch, perf]
8
+ -- ---
9
+ { "size": 0 }
@@ -0,0 +1,16 @@
1
+ -- ---
2
+ -- name: index-stats.elasticsearch
3
+ -- description: doc count + store size per index (top by store size)
4
+ -- engine: elasticsearch
5
+ -- index: '*'
6
+ -- intent: capacity.size
7
+ -- tags: [diag, elasticsearch, capacity]
8
+ -- ---
9
+ {
10
+ "size": 0,
11
+ "aggs": {
12
+ "by_index": {
13
+ "terms": { "field": "_index", "size": 50, "order": { "_count": "desc" } }
14
+ }
15
+ }
16
+ }
@@ -2,6 +2,7 @@
2
2
  -- name: Index usage (mysql)
3
3
  -- description: Index I/O wait counts ordered by total uses.
4
4
  -- engine: mysql
5
+ -- intent: perf.index-usage
5
6
  -- ---
6
7
  SELECT object_schema AS `schema`,
7
8
  object_name AS `table`,
@@ -2,6 +2,7 @@
2
2
  -- name: Index usage (postgres)
3
3
  -- description: Indexes ordered by scan count (low scans = candidates to drop).
4
4
  -- engine: postgres
5
+ -- intent: perf.index-usage
5
6
  -- ---
6
7
  SELECT schemaname AS schema,
7
8
  relname AS table,
@@ -2,6 +2,7 @@
2
2
  -- name: Lock waits (mysql)
3
3
  -- description: InnoDB lock waits with waiting and blocking transactions.
4
4
  -- engine: mysql
5
+ -- intent: safety.locks
5
6
  -- ---
6
7
  SELECT waiting.trx_mysql_thread_id AS waiting_thread,
7
8
  waiting.trx_query AS waiting_query,
@@ -2,6 +2,7 @@
2
2
  -- name: Lock waits (postgres)
3
3
  -- description: Sessions blocked by other sessions with both queries shown.
4
4
  -- engine: postgres
5
+ -- intent: safety.locks
5
6
  -- ---
6
7
  SELECT blocked.pid AS blocked_pid,
7
8
  blocked.usename AS blocked_user,
@@ -2,6 +2,7 @@
2
2
  -- name: Long-running queries (mysql)
3
3
  -- description: Non-sleep processes whose elapsed time exceeds min_seconds.
4
4
  -- engine: mysql
5
+ -- intent: perf.slow-query
5
6
  -- params:
6
7
  -- min_seconds:
7
8
  -- type: int
@@ -2,6 +2,7 @@
2
2
  -- name: Long-running queries (postgres)
3
3
  -- description: Queries running longer than min_seconds.
4
4
  -- engine: postgres
5
+ -- intent: perf.slow-query
5
6
  -- params:
6
7
  -- min_seconds:
7
8
  -- type: int
@@ -0,0 +1,8 @@
1
+ -- ---
2
+ -- name: memory-usage.redis
3
+ -- description: Redis memory usage breakdown
4
+ -- engine: redis
5
+ -- intent: capacity.memory
6
+ -- tags: [diag, redis, capacity]
7
+ -- ---
8
+ INFO memory
@@ -2,6 +2,7 @@
2
2
  -- name: Missing indexes (mysql)
3
3
  -- description: Tables with significant full-scan I/O and no index used.
4
4
  -- engine: mysql
5
+ -- intent: perf.index-usage
5
6
  -- ---
6
7
  SELECT object_schema AS `schema`,
7
8
  object_name AS `table`,
@@ -2,6 +2,7 @@
2
2
  -- name: Missing indexes (postgres)
3
3
  -- description: User tables where seq scans dominate over index scans (>1k rows).
4
4
  -- engine: postgres
5
+ -- intent: perf.index-usage
5
6
  -- ---
6
7
  SELECT schemaname AS schema,
7
8
  relname AS table,
@@ -0,0 +1,9 @@
1
+ -- ---
2
+ -- name: pending-tasks.elasticsearch
3
+ -- description: Cluster pending tasks queue depth and ages
4
+ -- engine: elasticsearch
5
+ -- index: '_cluster/pending_tasks'
6
+ -- intent: monitor.cluster-health
7
+ -- tags: [diag, elasticsearch]
8
+ -- ---
9
+ { "size": 0 }
@@ -2,6 +2,7 @@
2
2
  -- name: redis-key-stats
3
3
  -- description: Sample keyspace via SCAN with explicit COUNT bound
4
4
  -- engine: redis
5
+ -- intent: capacity.size
5
6
  -- params:
6
7
  -- match:
7
8
  -- type: string
@@ -0,0 +1,12 @@
1
+ -- ---
2
+ -- name: slowlog.redis
3
+ -- description: Recent Redis slow log entries
4
+ -- engine: redis
5
+ -- intent: perf.slow-query
6
+ -- tags: [diag, redis, perf]
7
+ -- params:
8
+ -- count:
9
+ -- type: int
10
+ -- default: 50
11
+ -- ---
12
+ SLOWLOG GET :count
@@ -2,6 +2,7 @@
2
2
  -- name: Table sizes (mysql)
3
3
  -- description: Data + index size in MB with estimated row count.
4
4
  -- engine: mysql
5
+ -- intent: capacity.size
5
6
  -- ---
6
7
  SELECT table_schema AS `schema`,
7
8
  table_name AS `table`,
@@ -2,6 +2,7 @@
2
2
  -- name: Table sizes (postgres)
3
3
  -- description: Total / table / index size with estimated row count.
4
4
  -- engine: postgres
5
+ -- intent: capacity.size
5
6
  -- ---
6
7
  SELECT schemaname AS schema,
7
8
  tablename AS table,
@@ -0,0 +1,9 @@
1
+ -- ---
2
+ -- name: unassigned-shards.elasticsearch
3
+ -- description: Shards stuck in UNASSIGNED state
4
+ -- engine: elasticsearch
5
+ -- index: '_cluster/allocation/explain'
6
+ -- intent: monitor.cluster-health
7
+ -- tags: [diag, elasticsearch, safety]
8
+ -- ---
9
+ { "size": 0 }