@carllee1983/dbcli 11.0.0 → 12.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.
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.cursor/skills/dbcli/reference.md +5 -2
- package/.cursor-plugin/plugin.json +1 -1
- package/.github/skills/dbcli/reference.md +5 -2
- package/CHANGELOG.md +70 -0
- package/assets/reference.md +5 -2
- package/assets/tasks/README.md +1 -1
- package/assets/tasks/analyze-table-perf.md +1 -1
- package/assets/tasks/audit-permissions.md +1 -1
- package/assets/tasks/connection-health.md +1 -2
- package/assets/tasks/design-review.md +1 -1
- package/assets/tasks/diagnose-slow-query.md +1 -1
- package/assets/tasks/migration-review.md +5 -3
- package/assets/tasks/mongo-safe-backfill.md +1 -1
- package/assets/tasks/mongo-schema-drift-review.md +1 -1
- package/assets/tasks/orm-drift-review.md +1 -1
- package/assets/tasks/pr-database-review.md +1 -1
- package/assets/tasks/safe-backfill-verify.md +1 -1
- package/assets/tasks/safe-backfill.md +13 -7
- package/assets/tasks/schema-drift-review.md +1 -1
- package/assets/tasks/slow-endpoint-investigation.md +1 -1
- package/dist/cli-runtime.mjs +13642 -22069
- package/dist/cli.mjs +1 -1
- package/dist/core.d.ts +9 -1
- package/dist/core.mjs +72 -0
- package/gemini-extension.json +1 -1
- package/package.json +1 -1
- package/plugins/dbcli-agent/.codex-plugin/plugin.json +1 -1
- package/plugins/dbcli-agent/skills/dbcli/reference.md +5 -2
- package/skills/dbcli/reference.md +5 -2
package/dist/cli.mjs
CHANGED
package/dist/core.d.ts
CHANGED
|
@@ -101,6 +101,8 @@ export interface ColumnSchema {
|
|
|
101
101
|
* Complete schema information for a table
|
|
102
102
|
*/
|
|
103
103
|
export interface TableSchema {
|
|
104
|
+
/** Some metadata was omitted to protect blacklisted identities. No protected names. */
|
|
105
|
+
metadataOmitted?: boolean;
|
|
104
106
|
/** Table name */
|
|
105
107
|
name: string;
|
|
106
108
|
/** Exact database schema/catalog namespace, when reliably available */
|
|
@@ -126,6 +128,8 @@ export interface TableSchema {
|
|
|
126
128
|
name: string;
|
|
127
129
|
columns: string[];
|
|
128
130
|
unique: boolean;
|
|
131
|
+
/** False when expressions/predicates prevent complete column-only representation. */
|
|
132
|
+
columnsComplete?: boolean;
|
|
129
133
|
}>;
|
|
130
134
|
/** Column count (used by listTables when full column details are not loaded) */
|
|
131
135
|
columnCount?: number;
|
|
@@ -134,7 +138,7 @@ export interface TableSchema {
|
|
|
134
138
|
/** Type of table (table or view) */
|
|
135
139
|
tableType?: "table" | "view";
|
|
136
140
|
}
|
|
137
|
-
type ConnectionErrorCode = "ECONNREFUSED" | "ETIMEDOUT" | "AUTH_FAILED" | "ENOTFOUND" | "EHOSTUNREACH" | "CONNECTION_LOST" | "TOO_MANY_CONNECTIONS" | "TLS_ERROR" | "SERVER_NOT_READY" | "CONNECTION_REJECTED" | "SQL_SYNTAX_ERROR" | "STATEMENT_TIMEOUT" | "TABLE_NOT_FOUND" | "COLUMN_NOT_FOUND" | "QUERY_ONLY_BOUNDARY_FAILED" | "UNKNOWN";
|
|
141
|
+
type ConnectionErrorCode = "ECONNREFUSED" | "ETIMEDOUT" | "AUTH_FAILED" | "DB_PERMISSION_DENIED" | "ENOTFOUND" | "EHOSTUNREACH" | "CONNECTION_LOST" | "TOO_MANY_CONNECTIONS" | "TLS_ERROR" | "SERVER_NOT_READY" | "CONNECTION_REJECTED" | "SQL_SYNTAX_ERROR" | "STATEMENT_TIMEOUT" | "TABLE_NOT_FOUND" | "COLUMN_NOT_FOUND" | "QUERY_ONLY_BOUNDARY_FAILED" | "UNKNOWN";
|
|
138
142
|
export declare class ConnectionError extends Error {
|
|
139
143
|
/** Error category code */
|
|
140
144
|
code: ConnectionErrorCode;
|
|
@@ -196,6 +200,10 @@ type RedisWarning = {
|
|
|
196
200
|
count: number;
|
|
197
201
|
};
|
|
198
202
|
interface TableSchemaOptions {
|
|
203
|
+
/** Single-object schema command: validate presence/type and mark incomplete index metadata. */
|
|
204
|
+
metadataProtection?: boolean;
|
|
205
|
+
/** Explicit SQL namespace; local tableName remains literal. Never performs an exact count. */
|
|
206
|
+
namespace?: string;
|
|
199
207
|
/** MongoDB: 取樣文件數 */
|
|
200
208
|
sampleSize?: number;
|
|
201
209
|
/** MongoDB: 取樣方式 */
|
package/dist/core.mjs
CHANGED
|
@@ -1028,6 +1028,7 @@ var COMMAND_CAPABILITY_KEYS = Object.freeze([
|
|
|
1028
1028
|
"update",
|
|
1029
1029
|
"delete",
|
|
1030
1030
|
"export",
|
|
1031
|
+
"blacklistRead",
|
|
1031
1032
|
"blacklist",
|
|
1032
1033
|
"check",
|
|
1033
1034
|
"diff",
|
|
@@ -1096,6 +1097,7 @@ var SQL_BASE = {
|
|
|
1096
1097
|
update: cap("supported", "db-write", "Dedicated UPDATE command is supported."),
|
|
1097
1098
|
delete: cap("supported", "db-write", "Dedicated DELETE command is supported."),
|
|
1098
1099
|
export: cap("supported", "readonly", "SQL export is supported."),
|
|
1100
|
+
blacklistRead: cap("supported", "readonly", "Reads the configured blacklist rules."),
|
|
1099
1101
|
blacklist: cap("supported", "local-write", "Blacklist management and enforcement are supported."),
|
|
1100
1102
|
check: cap("supported", "readonly", "Data health checks are SQL-only."),
|
|
1101
1103
|
diff: cap("supported", "readonly", "Relational schema snapshots are supported."),
|
|
@@ -1196,6 +1198,7 @@ var ENGINE_CAPABILITIES = Object.freeze({
|
|
|
1196
1198
|
update: cap("limited", "db-write", "Document update is supported with Mongo-specific behavior."),
|
|
1197
1199
|
delete: cap("limited", "db-write", "Document delete is supported with Mongo-specific behavior."),
|
|
1198
1200
|
export: cap("limited", "readonly", "MongoDB export is supported with document-query syntax."),
|
|
1201
|
+
blacklistRead: cap("limited", "readonly", "Reads the engine-specific blacklist rules."),
|
|
1199
1202
|
blacklist: cap("limited", "local-write", "Rule management works; enforcement differs from SQL column enforcement."),
|
|
1200
1203
|
check: cap("unsupported", "none", "Data health check is SQL-only."),
|
|
1201
1204
|
diff: cap("unsupported", "none", "Schema snapshots are relational only."),
|
|
@@ -1216,6 +1219,7 @@ var ENGINE_CAPABILITIES = Object.freeze({
|
|
|
1216
1219
|
update: cap("unsupported", "none", "Dedicated write subcommand is not exposed."),
|
|
1217
1220
|
delete: cap("limited", "db-write", "Basic delete via DEL/HDEL/LREM/SREM/ZREM (needs data-admin); supports --dry-run."),
|
|
1218
1221
|
export: cap("unsupported", "none", "Redis export is not supported."),
|
|
1222
|
+
blacklistRead: cap("limited", "readonly", "Reads the engine-specific blacklist rules."),
|
|
1219
1223
|
blacklist: cap("limited", "local-write", "Key-glob rejection (Redis-native pattern) plus value/hash-field masking ([REDACTED])."),
|
|
1220
1224
|
check: cap("unsupported", "none", "Data health check is SQL-only."),
|
|
1221
1225
|
diff: cap("unsupported", "none", "Schema snapshots are relational only."),
|
|
@@ -1236,6 +1240,7 @@ var ENGINE_CAPABILITIES = Object.freeze({
|
|
|
1236
1240
|
update: cap("unsupported", "none", "Dedicated write subcommand is not exposed."),
|
|
1237
1241
|
delete: cap("unsupported", "none", "Dedicated write subcommand is not exposed."),
|
|
1238
1242
|
export: cap("limited", "readonly", "Exports DSL hits or a full index via scroll, capped at 1000 rows (use --no-limit)."),
|
|
1243
|
+
blacklistRead: cap("limited", "readonly", "Reads the engine-specific blacklist rules."),
|
|
1239
1244
|
blacklist: cap("limited", "local-write", "Index-level and flattened-column enforcement differ from SQL."),
|
|
1240
1245
|
check: cap("unsupported", "none", "Data health check is SQL-only."),
|
|
1241
1246
|
diff: cap("unsupported", "none", "Schema snapshots are relational only."),
|
|
@@ -1264,6 +1269,7 @@ var messages_default = {
|
|
|
1264
1269
|
mongo_uri_conflicts_fields: "--uri cannot be combined with {flags}: the connection string already carries those settings. Use one or the other (--name may be combined to override the database name).",
|
|
1265
1270
|
mongo_uri_with_env_refs: "--uri cannot be combined with --use-env-refs: the connection string is decomposed into config fields, and its credentials are not moved into environment variables. Either remove --use-env-refs so dbcli decomposes the string into the field config, or use the --env-* flags (--env-host, --env-user, --env-password, ...) to name one variable per field.",
|
|
1266
1271
|
mongo_uri_fallback_warning: "\u26A0\uFE0F This connection string {reasons}, so it cannot become fields. It is stored as-is in uri, and its credentials will sit in plaintext in the config file.",
|
|
1272
|
+
mongo_uri_reason_unix_socket: "uses a Unix domain socket",
|
|
1267
1273
|
mongo_uri_reason_multi_host: "contains more than one host (a field config holds only one)",
|
|
1268
1274
|
mongo_uri_reason_secret_option: "contains secret option(s) ({keys}) that would land in plaintext options",
|
|
1269
1275
|
mongo_uri_reason_duplicate_key: "repeats the query key(s) {keys} (a field config can hold only one value per key)",
|
|
@@ -1617,6 +1623,7 @@ var messages_default2 = {
|
|
|
1617
1623
|
mongo_uri_conflicts_fields: "--uri \u4E0D\u80FD\u8207 {flags} \u4E26\u7528\uFF1A\u9023\u7DDA\u5B57\u4E32\u5DF2\u5305\u542B\u9019\u4E9B\u8A2D\u5B9A\u3002\u8ACB\u64C7\u4E00\u4F7F\u7528\uFF08--name \u53EF\u4E26\u7528\uFF0C\u7528\u4F86\u8986\u84CB\u8CC7\u6599\u5EAB\u540D\u7A31\uFF09\u3002",
|
|
1618
1624
|
mongo_uri_with_env_refs: "--uri \u4E0D\u80FD\u8207 --use-env-refs \u4E26\u7528\uFF1A\u9023\u7DDA\u5B57\u4E32\u6703\u88AB\u62C6\u89E3\u6210\u6B04\u4F4D\u8A2D\u5B9A\u5BEB\u5165\uFF0C\u5E33\u5BC6\u4E0D\u6703\u88AB\u62BD\u6210\u74B0\u5883\u8B8A\u6578\u53C3\u7167\u3002\u8ACB\u6539\u8D70\u4E0B\u5217\u4EFB\u4E00\u505A\u6CD5\uFF1A\u62FF\u6389 --use-env-refs\uFF0C\u8B93 dbcli \u62C6\u89E3\u5B57\u4E32\u5BEB\u5165\u6B04\u4F4D\u8A2D\u5B9A\uFF1B\u6216\u6539\u7528 --env-* flag\uFF08--env-host\u3001--env-user\u3001--env-password \u7B49\uFF09\u9010\u6B04\u7D66\u8B8A\u6578\u540D\u7A31\u3002",
|
|
1619
1625
|
mongo_uri_fallback_warning: "\u26A0\uFE0F \u6B64\u9023\u7DDA\u5B57\u4E32{reasons}\uFF0C\u7121\u6CD5\u62C6\u6210\u6B04\u4F4D\u8A2D\u5B9A\uFF0C\u5DF2\u539F\u6A23\u5B58\u5165 uri\uFF1B\u5E33\u5BC6\u5C07\u660E\u6587\u5B58\u653E\u65BC\u8A2D\u5B9A\u6A94\u3002",
|
|
1626
|
+
mongo_uri_reason_unix_socket: "\u4F7F\u7528 Unix domain socket\uFF08\u672C\u6A5F\u901A\u8A0A\u7AEF\uFF09",
|
|
1620
1627
|
mongo_uri_reason_multi_host: "\u542B\u591A\u7D44 host\uFF08\u6B04\u4F4D\u8A2D\u5B9A\u53EA\u80FD\u8868\u9054\u4E00\u7D44\uFF09",
|
|
1621
1628
|
mongo_uri_reason_secret_option: "\u542B\u6A5F\u5BC6 option\uFF08{keys}\uFF09\uFF0C\u62C6\u9032 options \u6703\u660E\u6587\u843D\u76E4",
|
|
1622
1629
|
mongo_uri_reason_duplicate_key: "\u542B\u91CD\u8907\u7684 query \u9375\uFF08{keys}\uFF09\uFF08\u6B04\u4F4D\u8A2D\u5B9A\u6BCF\u500B\u9375\u53EA\u80FD\u5B58\u4E00\u500B\u503C\uFF09",
|
|
@@ -2200,6 +2207,61 @@ var messageLoader = MessageLoader.getInstance();
|
|
|
2200
2207
|
var t = (key) => messageLoader.t(key);
|
|
2201
2208
|
var t_vars = (key, vars) => messageLoader.interpolate(key, vars);
|
|
2202
2209
|
|
|
2210
|
+
// src/adapters/grant-redaction.ts
|
|
2211
|
+
var PRIVILEGES = new Set([
|
|
2212
|
+
"ALL",
|
|
2213
|
+
"ALL PRIVILEGES",
|
|
2214
|
+
"ALTER",
|
|
2215
|
+
"ALTER ROUTINE",
|
|
2216
|
+
"BINLOG ADMIN",
|
|
2217
|
+
"BINLOG MONITOR",
|
|
2218
|
+
"BINLOG REPLAY",
|
|
2219
|
+
"CONNECTION ADMIN",
|
|
2220
|
+
"CREATE",
|
|
2221
|
+
"CREATE ROUTINE",
|
|
2222
|
+
"CREATE TABLESPACE",
|
|
2223
|
+
"CREATE TEMPORARY TABLES",
|
|
2224
|
+
"CREATE USER",
|
|
2225
|
+
"CREATE VIEW",
|
|
2226
|
+
"DELETE",
|
|
2227
|
+
"DELETE HISTORY",
|
|
2228
|
+
"DROP",
|
|
2229
|
+
"EVENT",
|
|
2230
|
+
"EXECUTE",
|
|
2231
|
+
"FEDERATED ADMIN",
|
|
2232
|
+
"FILE",
|
|
2233
|
+
"GRANT OPTION",
|
|
2234
|
+
"INDEX",
|
|
2235
|
+
"INSERT",
|
|
2236
|
+
"LOCK TABLES",
|
|
2237
|
+
"PROCESS",
|
|
2238
|
+
"READ ONLY ADMIN",
|
|
2239
|
+
"RELOAD",
|
|
2240
|
+
"REPLICATION CLIENT",
|
|
2241
|
+
"REPLICATION MASTER ADMIN",
|
|
2242
|
+
"REPLICATION SLAVE",
|
|
2243
|
+
"REPLICATION SLAVE ADMIN",
|
|
2244
|
+
"REFERENCES",
|
|
2245
|
+
"SELECT",
|
|
2246
|
+
"SET USER",
|
|
2247
|
+
"SHOW CREATE ROUTINE",
|
|
2248
|
+
"SHOW DATABASES",
|
|
2249
|
+
"SHOW VIEW",
|
|
2250
|
+
"SHUTDOWN",
|
|
2251
|
+
"SLAVE MONITOR",
|
|
2252
|
+
"SUPER",
|
|
2253
|
+
"TRIGGER",
|
|
2254
|
+
"UPDATE",
|
|
2255
|
+
"USAGE"
|
|
2256
|
+
]);
|
|
2257
|
+
var RESOURCE_OPTIONS = new Set([
|
|
2258
|
+
"MAX_QUERIES_PER_HOUR",
|
|
2259
|
+
"MAX_UPDATES_PER_HOUR",
|
|
2260
|
+
"MAX_CONNECTIONS_PER_HOUR",
|
|
2261
|
+
"MAX_USER_CONNECTIONS",
|
|
2262
|
+
"MAX_STATEMENT_TIME"
|
|
2263
|
+
]);
|
|
2264
|
+
|
|
2203
2265
|
// src/utils/case-fold.ts
|
|
2204
2266
|
function foldCase(text) {
|
|
2205
2267
|
const lowered = (text.includes("\u0130") ? text.replaceAll("\u0130", "i") : text).toLowerCase();
|
|
@@ -9928,6 +9990,15 @@ var DECLARATIONS = [
|
|
|
9928
9990
|
permission: "query-only",
|
|
9929
9991
|
requiresConnection: true
|
|
9930
9992
|
},
|
|
9993
|
+
{
|
|
9994
|
+
id: "blacklist.read",
|
|
9995
|
+
key: "blacklistRead",
|
|
9996
|
+
command: "blacklist list",
|
|
9997
|
+
description: "Read the configured table, column and key rules that hide sensitive data.",
|
|
9998
|
+
permission: "query-only",
|
|
9999
|
+
requiresConnection: false,
|
|
10000
|
+
mutatesConfiguration: false
|
|
10001
|
+
},
|
|
9931
10002
|
{
|
|
9932
10003
|
id: "blacklist.manage",
|
|
9933
10004
|
key: "blacklist",
|
|
@@ -10242,6 +10313,7 @@ var COMMAND_SURFACE = Object.freeze({
|
|
|
10242
10313
|
"delete",
|
|
10243
10314
|
"export",
|
|
10244
10315
|
"check",
|
|
10316
|
+
"blacklist list",
|
|
10245
10317
|
"inspect",
|
|
10246
10318
|
"report",
|
|
10247
10319
|
"guide",
|
package/gemini-extension.json
CHANGED
package/package.json
CHANGED
|
@@ -1868,8 +1868,11 @@ at execution time, and no human has agreed to anything. `admin` in a config file
|
|
|
1868
1868
|
is a permission level, not a DBA sign-off.
|
|
1869
1869
|
|
|
1870
1870
|
`schema.read` is available under `DBCLI_AGENT_MODE=1`, and `dbcli schema` runs
|
|
1871
|
-
there: storing the schema cache is not a configuration change.
|
|
1872
|
-
|
|
1871
|
+
there: storing the schema cache is not a configuration change. `blacklist.read`
|
|
1872
|
+
(`blacklist list`) is available there too, so read-only Task Packs that inspect
|
|
1873
|
+
the blacklist can plan; `blacklist.manage`, which adds and removes rules, is
|
|
1874
|
+
refused. Agent mode still refuses every change to connection identity,
|
|
1875
|
+
permission and credentials.
|
|
1873
1876
|
|
|
1874
1877
|
**Permission:** query-only+ (no connection is made)
|
|
1875
1878
|
|
|
@@ -1868,8 +1868,11 @@ at execution time, and no human has agreed to anything. `admin` in a config file
|
|
|
1868
1868
|
is a permission level, not a DBA sign-off.
|
|
1869
1869
|
|
|
1870
1870
|
`schema.read` is available under `DBCLI_AGENT_MODE=1`, and `dbcli schema` runs
|
|
1871
|
-
there: storing the schema cache is not a configuration change.
|
|
1872
|
-
|
|
1871
|
+
there: storing the schema cache is not a configuration change. `blacklist.read`
|
|
1872
|
+
(`blacklist list`) is available there too, so read-only Task Packs that inspect
|
|
1873
|
+
the blacklist can plan; `blacklist.manage`, which adds and removes rules, is
|
|
1874
|
+
refused. Agent mode still refuses every change to connection identity,
|
|
1875
|
+
permission and credentials.
|
|
1873
1876
|
|
|
1874
1877
|
**Permission:** query-only+ (no connection is made)
|
|
1875
1878
|
|