@carllee1983/dbcli 7.0.0 → 8.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/.agents/skills/story-development/SKILL.md +70 -0
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.cursor/rules/dbcli.mdc +65 -2
- package/.cursor/skills/dbcli/reference.md +197 -5
- package/.cursor-plugin/plugin.json +1 -1
- package/.github/skills/dbcli/SKILL.md +65 -2
- package/.github/skills/dbcli/reference.md +197 -5
- package/CHANGELOG.md +299 -0
- package/assets/SKILL.md +65 -2
- package/assets/SKILL.zh-TW.md +60 -2
- package/assets/integration-kit/README.md +43 -0
- package/assets/integration-kit/external-consumers.ts +9 -0
- package/assets/integration-kit/skill-author-consumer.ts +77 -0
- package/assets/integration-kit/task-pack.md +18 -0
- package/assets/reference.md +197 -5
- package/assets/tasks/README.md +6 -0
- package/assets/tasks/analyze-table-perf.md +3 -3
- package/assets/tasks/audit-permissions.md +2 -2
- package/assets/tasks/connection-health.md +2 -2
- package/assets/tasks/design-review.md +3 -3
- package/assets/tasks/diagnose-slow-query.md +3 -3
- package/assets/tasks/migration-review.md +3 -3
- package/assets/tasks/mongo-safe-backfill.md +2 -2
- package/assets/tasks/mongo-schema-drift-review.md +2 -2
- package/assets/tasks/orm-drift-review.md +3 -3
- package/assets/tasks/pr-database-review.md +3 -3
- package/assets/tasks/safe-backfill-verify.md +3 -3
- package/assets/tasks/safe-backfill.md +3 -3
- package/assets/tasks/schema-drift-review.md +3 -3
- package/assets/tasks/slow-endpoint-investigation.md +19 -6
- package/assets/ui-template.html +18 -18
- package/dist/cli-runtime.mjs +25533 -22188
- package/dist/cli.mjs +7 -4
- package/dist/core.d.ts +297 -2
- package/dist/core.mjs +2075 -3
- package/dist/ui-style.css +1 -1
- package/gemini-extension.json +1 -1
- package/package.json +6 -3
- package/plugins/dbcli-agent/.codex-plugin/plugin.json +1 -1
- package/plugins/dbcli-agent/skills/dbcli/SKILL.md +65 -2
- package/plugins/dbcli-agent/skills/dbcli/reference.md +197 -5
- package/skills/dbcli/SKILL.md +65 -2
- package/skills/dbcli/reference.md +197 -5
package/dist/cli.mjs
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// package.json
|
|
4
4
|
var package_default = {
|
|
5
5
|
name: "@carllee1983/dbcli",
|
|
6
|
-
version: "
|
|
6
|
+
version: "8.0.0",
|
|
7
7
|
description: "Database CLI for AI agents",
|
|
8
8
|
type: "module",
|
|
9
9
|
publishConfig: {
|
|
@@ -70,6 +70,7 @@ var package_default = {
|
|
|
70
70
|
build: "bun run scripts/build.ts",
|
|
71
71
|
"build:determinism": "bun run scripts/check-build-determinism.ts",
|
|
72
72
|
prepublishOnly: "bun run build",
|
|
73
|
+
audit: "bun run scripts/audit.ts",
|
|
73
74
|
"release:check": "bash scripts/release-check.sh",
|
|
74
75
|
"plugin:sync": "bun run scripts/sync-plugin-assets.ts --write",
|
|
75
76
|
"plugin:check": "bun run scripts/sync-plugin-assets.ts",
|
|
@@ -88,6 +89,7 @@ var package_default = {
|
|
|
88
89
|
"agent-core:check": "bun run scripts/check-agent-core-purity.ts",
|
|
89
90
|
"core-stdout:check": "bun run scripts/check-core-no-stdout.ts",
|
|
90
91
|
"plan:check": "bun run scripts/check-plan-acceptance.ts",
|
|
92
|
+
"forgeflow:check": "bun run scripts/check-forgeflow-adoption.ts && bun run scripts/check-forgeflow-handoff.ts",
|
|
91
93
|
typecheck: "tsc --noEmit --pretty false",
|
|
92
94
|
"typecheck:tests": "tsc --noEmit --pretty false -p tsconfig.tests.json",
|
|
93
95
|
"test:perf": "bun test ./tests/perf/*.bench.ts",
|
|
@@ -103,7 +105,7 @@ var package_default = {
|
|
|
103
105
|
"lru-cache": "^11.4.0",
|
|
104
106
|
"lucide-react": "^1.16.0",
|
|
105
107
|
mongodb: "^7.2.0",
|
|
106
|
-
mysql2: "^3.
|
|
108
|
+
mysql2: "^3.24.3",
|
|
107
109
|
"node-sql-parser": "5",
|
|
108
110
|
open: "^11.0.0",
|
|
109
111
|
pg: "^8.21.0",
|
|
@@ -125,7 +127,7 @@ var package_default = {
|
|
|
125
127
|
"@types/react-dom": "^19.2.3",
|
|
126
128
|
autoprefixer: "^10.5.0",
|
|
127
129
|
"dts-bundle-generator": "^9.5.1",
|
|
128
|
-
eslint: "^10.
|
|
130
|
+
eslint: "^10.9.1",
|
|
129
131
|
"happy-dom": "^20.10.6",
|
|
130
132
|
postcss: "^8.5.26",
|
|
131
133
|
prettier: "^3.8.3",
|
|
@@ -134,6 +136,7 @@ var package_default = {
|
|
|
134
136
|
"typescript-eslint": "^8.59.4"
|
|
135
137
|
},
|
|
136
138
|
overrides: {
|
|
139
|
+
"@humanfs/node": "^0.16.8",
|
|
137
140
|
"brace-expansion": "^5.0.9",
|
|
138
141
|
browserslist: "^4.28.7",
|
|
139
142
|
postcss: "^8.5.26",
|
|
@@ -146,7 +149,7 @@ function isStandaloneVersionRequest(args) {
|
|
|
146
149
|
return args.length === 1 && (args[0] === "--version" || args[0] === "-V");
|
|
147
150
|
}
|
|
148
151
|
var program;
|
|
149
|
-
if (import.meta.main && isStandaloneVersionRequest(process.argv.slice(2))) {
|
|
152
|
+
if (import.meta.main && !process.argv.slice(2).includes("--agent-output") && isStandaloneVersionRequest(process.argv.slice(2))) {
|
|
150
153
|
console.log(package_default.version);
|
|
151
154
|
} else {
|
|
152
155
|
const runtimePath = "./cli-runtime";
|
package/dist/core.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { z } from 'zod';
|
|
|
8
8
|
*/
|
|
9
9
|
export type DatabaseSystem = "postgresql" | "mysql" | "mariadb" | "mongodb" | "redis" | "elasticsearch";
|
|
10
10
|
type SqlDatabaseSystem = Extract<DatabaseSystem, "postgresql" | "mysql" | "mariadb">;
|
|
11
|
+
type SqlExecutionMode = "normal" | "native-read-only";
|
|
11
12
|
type QueryableDatabaseSystem = Exclude<DatabaseSystem, SqlDatabaseSystem>;
|
|
12
13
|
/**
|
|
13
14
|
* Connection configuration for database adapters
|
|
@@ -129,7 +130,7 @@ export interface TableSchema {
|
|
|
129
130
|
/** Type of table (table or view) */
|
|
130
131
|
tableType?: "table" | "view";
|
|
131
132
|
}
|
|
132
|
-
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" | "UNKNOWN";
|
|
133
|
+
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";
|
|
133
134
|
export declare class ConnectionError extends Error {
|
|
134
135
|
/** Error category code */
|
|
135
136
|
code: ConnectionErrorCode;
|
|
@@ -141,6 +142,8 @@ export declare class ConnectionError extends Error {
|
|
|
141
142
|
* it to tell an agent what `--statement-timeout <ms>` it was already up against.
|
|
142
143
|
*/
|
|
143
144
|
limitMs?: number | undefined;
|
|
145
|
+
/** Whether an interactive caller may safely retry the statement after reconnecting. */
|
|
146
|
+
readonly retrySafe: boolean;
|
|
144
147
|
constructor(
|
|
145
148
|
/** Error category code */
|
|
146
149
|
code: ConnectionErrorCode,
|
|
@@ -153,7 +156,9 @@ export declare class ConnectionError extends Error {
|
|
|
153
156
|
* consumers can state it without parsing `message`; the recovery envelope needs
|
|
154
157
|
* it to tell an agent what `--statement-timeout <ms>` it was already up against.
|
|
155
158
|
*/
|
|
156
|
-
limitMs?: number | undefined
|
|
159
|
+
limitMs?: number | undefined,
|
|
160
|
+
/** Whether an interactive caller may safely retry the statement after reconnecting. */
|
|
161
|
+
retrySafe?: boolean);
|
|
157
162
|
}
|
|
158
163
|
/**
|
|
159
164
|
* Result of a database query or command execution
|
|
@@ -224,6 +229,7 @@ export interface DatabaseAdapter {
|
|
|
224
229
|
*/
|
|
225
230
|
execute<T>(sql: string, params?: (string | number | boolean | null)[], options?: {
|
|
226
231
|
noLimit?: boolean;
|
|
232
|
+
sqlMode?: SqlExecutionMode;
|
|
227
233
|
}): Promise<ExecutionResult<T>>;
|
|
228
234
|
/**
|
|
229
235
|
* List all tables in the connected database
|
|
@@ -255,6 +261,7 @@ export interface DatabaseAdapter {
|
|
|
255
261
|
*/
|
|
256
262
|
getServerVersion(): Promise<string>;
|
|
257
263
|
}
|
|
264
|
+
type SideEffectTier = "readonly" | "dry-run" | "local-write" | "db-write" | "interactive" | "none";
|
|
258
265
|
interface BlacklistConfig {
|
|
259
266
|
/** Table names to block all operations on */
|
|
260
267
|
tables: string[];
|
|
@@ -3281,6 +3288,294 @@ export declare function isGlobalConfigPath(path: string): boolean;
|
|
|
3281
3288
|
export declare function getProjectStoragePath(projectPath: string): string;
|
|
3282
3289
|
export declare function resolveConfigStoragePath(path: string): Promise<string>;
|
|
3283
3290
|
export declare function writeProjectBinding(projectPath: string, storagePath?: string): Promise<ProjectConfigBinding>;
|
|
3291
|
+
export declare const CAPABILITY_CONTRACT_SCHEMA_VERSION: 1;
|
|
3292
|
+
/**
|
|
3293
|
+
* Risk vocabulary, reused verbatim from the Agent Task Pack contract
|
|
3294
|
+
* (`AgentTaskRisk`) so a pack's step risk and a capability's risk are the same
|
|
3295
|
+
* four words. `sideEffect` carries the finer existing `SideEffectTier` beside
|
|
3296
|
+
* it, because collapsing `local-write` and `db-write` into `write` would hide
|
|
3297
|
+
* the one distinction a caller most needs.
|
|
3298
|
+
*/
|
|
3299
|
+
export type CapabilityRisk = "readonly" | "dry-run" | "write" | "unknown";
|
|
3300
|
+
export interface Capability {
|
|
3301
|
+
/** Stable dotted id, e.g. `schema.read`. The value external Skills pin. */
|
|
3302
|
+
readonly id: string;
|
|
3303
|
+
readonly description: string;
|
|
3304
|
+
/** Space-separated live CLI command path, e.g. `audit tail`. */
|
|
3305
|
+
readonly command: string;
|
|
3306
|
+
readonly risk: CapabilityRisk;
|
|
3307
|
+
/** The precise pre-existing side-effect tier this risk was derived from. */
|
|
3308
|
+
readonly sideEffect: SideEffectTier;
|
|
3309
|
+
/** Engines on which the capability is supported or limited, sorted. */
|
|
3310
|
+
readonly engines: readonly DatabaseSystem[];
|
|
3311
|
+
/**
|
|
3312
|
+
* The subset of `engines` the matrix marks `limited` rather than `supported`.
|
|
3313
|
+
*
|
|
3314
|
+
* Carried separately because folding it into `engines` would discard
|
|
3315
|
+
* information the matrix already holds: `data.delete` works on Redis, but not
|
|
3316
|
+
* the way it works on PostgreSQL, and a caller choosing an engine deserves to
|
|
3317
|
+
* know which before it commits.
|
|
3318
|
+
*/
|
|
3319
|
+
readonly limitedEngines: readonly DatabaseSystem[];
|
|
3320
|
+
/** True when the capability works irrespective of the configured engine. */
|
|
3321
|
+
readonly engineIndependent: boolean;
|
|
3322
|
+
readonly minimumPermission: Permission;
|
|
3323
|
+
readonly requiresConnection: boolean;
|
|
3324
|
+
/**
|
|
3325
|
+
* True when the capability changes connection identity, permission or
|
|
3326
|
+
* credentials — the class of change `DBCLI_AGENT_MODE=1` refuses outright.
|
|
3327
|
+
*/
|
|
3328
|
+
readonly mutatesConfiguration: boolean;
|
|
3329
|
+
readonly supportsJson: boolean;
|
|
3330
|
+
readonly supportsEvidence: boolean;
|
|
3331
|
+
}
|
|
3332
|
+
export interface CapabilityCatalog {
|
|
3333
|
+
readonly schemaVersion: typeof CAPABILITY_CONTRACT_SCHEMA_VERSION;
|
|
3334
|
+
readonly capabilities: readonly Capability[];
|
|
3335
|
+
}
|
|
3336
|
+
export type CapabilityCheckStatus = "available" | "unavailable" | "unknown";
|
|
3337
|
+
/**
|
|
3338
|
+
* Why a capability is not available. `null` only ever accompanies `available`.
|
|
3339
|
+
*
|
|
3340
|
+
* `context-unavailable` is distinct from `engine`/`permission` on purpose: with
|
|
3341
|
+
* no local config there is nothing to evaluate against, and reporting that as
|
|
3342
|
+
* an engine mismatch would invent a fact. It is still not `available` — absence
|
|
3343
|
+
* of context never reads as permission to act.
|
|
3344
|
+
*
|
|
3345
|
+
* `context-unresolvable` is a *different* fact from `context-unavailable`, and
|
|
3346
|
+
* conflating them was a real defect: a config whose `{"$env": "..."}` password
|
|
3347
|
+
* reference points at an unset variable is present and perfectly readable, and
|
|
3348
|
+
* reporting "no configuration was readable" there states something false. This
|
|
3349
|
+
* command needs no credential, but the one config reader resolves them before
|
|
3350
|
+
* it will answer, so the honest report is "a config exists and could not be
|
|
3351
|
+
* turned into an evaluable context" — never "there is no config".
|
|
3352
|
+
*
|
|
3353
|
+
* `agent-mode` is an environment gate, not an execution-time one. Under
|
|
3354
|
+
* `DBCLI_AGENT_MODE=1` every configuration, permission and credential change is
|
|
3355
|
+
* refused unconditionally, and that is fully knowable without connecting. The
|
|
3356
|
+
* "available is not approval" disclaimer does not cover it: blacklist and human
|
|
3357
|
+
* consent are decided at execution time, whereas this is decided here, and the
|
|
3358
|
+
* contract's primary consumer is exactly the agent the flag describes.
|
|
3359
|
+
*/
|
|
3360
|
+
export type CapabilityUnavailableReason = "unknown-capability" | "context-unavailable" | "context-unresolvable" | "engine" | "agent-mode" | "permission";
|
|
3361
|
+
export interface CapabilityCheckContext {
|
|
3362
|
+
readonly engine: DatabaseSystem;
|
|
3363
|
+
readonly permission: Permission;
|
|
3364
|
+
/** Named v2 connection in effect, or null for a v1/single-connection config. */
|
|
3365
|
+
readonly connectionName: string | null;
|
|
3366
|
+
/** `DBCLI_AGENT_MODE=1`: configuration changes are refused unconditionally. */
|
|
3367
|
+
readonly agentMode: boolean;
|
|
3368
|
+
}
|
|
3369
|
+
/**
|
|
3370
|
+
* Why there is no context, when there is none.
|
|
3371
|
+
*
|
|
3372
|
+
* `absent` means nothing is configured here. `unresolvable` means something is,
|
|
3373
|
+
* and it could not be turned into an engine and a permission. Only the first
|
|
3374
|
+
* justifies telling a caller there is no configuration.
|
|
3375
|
+
*/
|
|
3376
|
+
export type CapabilityContextFailure = "absent" | "unresolvable";
|
|
3377
|
+
export interface CapabilityCheckResultEntry {
|
|
3378
|
+
readonly id: string;
|
|
3379
|
+
readonly status: CapabilityCheckStatus;
|
|
3380
|
+
readonly reason: CapabilityUnavailableReason | null;
|
|
3381
|
+
}
|
|
3382
|
+
export interface CapabilityCheckReport {
|
|
3383
|
+
readonly schemaVersion: typeof CAPABILITY_CONTRACT_SCHEMA_VERSION;
|
|
3384
|
+
readonly ok: boolean;
|
|
3385
|
+
/** The de-duplicated requirement list, in first-seen order. */
|
|
3386
|
+
readonly required: readonly string[];
|
|
3387
|
+
readonly context: CapabilityCheckContext | null;
|
|
3388
|
+
readonly results: readonly CapabilityCheckResultEntry[];
|
|
3389
|
+
readonly warnings: readonly string[];
|
|
3390
|
+
}
|
|
3391
|
+
/**
|
|
3392
|
+
* Every capability, sorted by id.
|
|
3393
|
+
*
|
|
3394
|
+
* Sorting is the whole determinism guarantee: two builds of the same version
|
|
3395
|
+
* emit byte-identical catalogs regardless of declaration order, so a consumer
|
|
3396
|
+
* can diff two outputs and see only real changes.
|
|
3397
|
+
*/
|
|
3398
|
+
export declare const CAPABILITIES: readonly Capability[];
|
|
3399
|
+
export declare function findCapability(id: string): Capability | undefined;
|
|
3400
|
+
export declare function listCapabilityIds(): readonly string[];
|
|
3401
|
+
/** The catalog as an external consumer receives it. */
|
|
3402
|
+
export declare function buildCapabilityCatalog(): {
|
|
3403
|
+
schemaVersion: typeof CAPABILITY_CONTRACT_SCHEMA_VERSION;
|
|
3404
|
+
capabilities: readonly Capability[];
|
|
3405
|
+
};
|
|
3406
|
+
export declare class CapabilityRequirementError extends Error {
|
|
3407
|
+
constructor(message: string);
|
|
3408
|
+
}
|
|
3409
|
+
interface ParsedRequirements {
|
|
3410
|
+
readonly ids: readonly string[];
|
|
3411
|
+
readonly warnings: readonly string[];
|
|
3412
|
+
}
|
|
3413
|
+
/**
|
|
3414
|
+
* Parse `--require a,b,a` into an ordered, unique id list.
|
|
3415
|
+
*
|
|
3416
|
+
* A repeated id is de-duplicated rather than refused, and the duplication is
|
|
3417
|
+
* reported as a warning. Refusing would punish the common case of two Skills
|
|
3418
|
+
* concatenating their requirement lists, and answering the same id twice would
|
|
3419
|
+
* make `results` a multiset that a consumer has to fold itself. Neither
|
|
3420
|
+
* behaviour is guessable, so it is stated here and in the spec.
|
|
3421
|
+
*
|
|
3422
|
+
* Empty input, or any empty element, is refused: a requirement list that
|
|
3423
|
+
* accidentally evaluated to "nothing required" would report `ok: true` and read
|
|
3424
|
+
* as a green light.
|
|
3425
|
+
*/
|
|
3426
|
+
export declare function parseRequirements(raw: string): ParsedRequirements;
|
|
3427
|
+
export declare function checkCapabilities(required: readonly string[], context: CapabilityCheckContext | null, warnings?: readonly string[], contextFailure?: CapabilityContextFailure): CapabilityCheckReport;
|
|
3428
|
+
export declare class CapabilityContractError extends Error {
|
|
3429
|
+
constructor(message: string);
|
|
3430
|
+
}
|
|
3431
|
+
export declare function parseCapabilityCatalog(value: unknown): CapabilityCatalog;
|
|
3432
|
+
export declare function parseCapabilityCheckReport(value: unknown): CapabilityCheckReport;
|
|
3433
|
+
type GuideRisk = "readonly" | "dry-run" | "write" | "unknown";
|
|
3434
|
+
interface GuideStep {
|
|
3435
|
+
/** 1-based ordinal in the emitted plan. */
|
|
3436
|
+
order: number;
|
|
3437
|
+
/** Exact dbcli command the agent should run next, e.g. `dbcli q @diag/long-running --format json`. */
|
|
3438
|
+
command: string;
|
|
3439
|
+
/** One-sentence justification for this step. */
|
|
3440
|
+
rationale: string;
|
|
3441
|
+
/** Forward-compatible risk tag; v1.14.0 always emits `readonly`. */
|
|
3442
|
+
risk: GuideRisk;
|
|
3443
|
+
/** Short description of expected output shape (helps agents know when to bail). */
|
|
3444
|
+
expects: string;
|
|
3445
|
+
/** Snippet key when the step came from a saved query (e.g. `@diag/long-running`). */
|
|
3446
|
+
snippet?: string;
|
|
3447
|
+
/** Snippet `intent` taxonomy slot when applicable. */
|
|
3448
|
+
intent?: string;
|
|
3449
|
+
/** v1.17.0+: step requires interactive TTY (e.g. `dbcli init`). `dbcli recover --apply` skips these. */
|
|
3450
|
+
interactive?: boolean;
|
|
3451
|
+
/** v1.17.0+: true when the step mutates the connected database. Gates `--apply --allow-write=write-cmd`. */
|
|
3452
|
+
dbWrite?: boolean;
|
|
3453
|
+
/** v1.17.0+: placeholder tokens that must be resolved before `--apply` can execute this step (e.g. `['<table>']`). */
|
|
3454
|
+
placeholders?: string[];
|
|
3455
|
+
/** Set only on steps inside `branches[id].steps`. Agents may ignore. */
|
|
3456
|
+
branchId?: string;
|
|
3457
|
+
}
|
|
3458
|
+
declare const RECOVERY_SCHEMA_VERSION: 1;
|
|
3459
|
+
declare const RECOVERY_CODES: readonly [
|
|
3460
|
+
"CONFIG_MISSING",
|
|
3461
|
+
"CONN_REFUSED",
|
|
3462
|
+
"CONN_AUTH_FAILED",
|
|
3463
|
+
"CONN_TIMEOUT",
|
|
3464
|
+
"CONN_HOST_NOT_FOUND",
|
|
3465
|
+
"CONN_UNKNOWN",
|
|
3466
|
+
"PERMISSION_DENIED",
|
|
3467
|
+
"BLACKLIST_TABLE",
|
|
3468
|
+
"BLACKLIST_COLUMN_WRITE",
|
|
3469
|
+
"SNIPPET_NOT_FOUND",
|
|
3470
|
+
"SNIPPET_AMBIGUOUS",
|
|
3471
|
+
"SNIPPET_PARAM_MISSING",
|
|
3472
|
+
"SCHEMA_CACHE_MISSING",
|
|
3473
|
+
"UNKNOWN"
|
|
3474
|
+
];
|
|
3475
|
+
type RecoveryCode = (typeof RECOVERY_CODES)[number];
|
|
3476
|
+
type RecoveryCategory = "config" | "connection" | "permission" | "blacklist" | "snippet" | "schema-cache" | "unknown";
|
|
3477
|
+
interface RecoveryError {
|
|
3478
|
+
/** Stable code from RECOVERY_CODES. */
|
|
3479
|
+
code: RecoveryCode;
|
|
3480
|
+
category: RecoveryCategory;
|
|
3481
|
+
/** User-safe message; never includes hostnames, ports, or secrets. */
|
|
3482
|
+
message: string;
|
|
3483
|
+
/**
|
|
3484
|
+
* Bounded set of structured details for agents. Allowed keys are intentionally
|
|
3485
|
+
* limited so the envelope shape stays predictable across versions.
|
|
3486
|
+
*/
|
|
3487
|
+
details?: {
|
|
3488
|
+
table?: string;
|
|
3489
|
+
columns?: string;
|
|
3490
|
+
requiredPermission?: string;
|
|
3491
|
+
connectionCode?: ConnectionErrorCode;
|
|
3492
|
+
snippet?: string;
|
|
3493
|
+
intent?: string;
|
|
3494
|
+
paramName?: string;
|
|
3495
|
+
};
|
|
3496
|
+
}
|
|
3497
|
+
type BranchId = string;
|
|
3498
|
+
interface BranchPlan {
|
|
3499
|
+
/** Human-readable summary; agents can show this to the user. */
|
|
3500
|
+
description: string;
|
|
3501
|
+
/** Steps inside the branch. `order` is 1-based WITHIN the branch. */
|
|
3502
|
+
steps: GuideStep[];
|
|
3503
|
+
}
|
|
3504
|
+
interface BranchFork {
|
|
3505
|
+
/** 1-based step order in `recovery` after which a fork may happen. v1: always 1. */
|
|
3506
|
+
after: number;
|
|
3507
|
+
/** Enumeration of possible branchIds; must equal Object.keys(branches). */
|
|
3508
|
+
branchIds: BranchId[];
|
|
3509
|
+
}
|
|
3510
|
+
interface RecoveryEnvelope {
|
|
3511
|
+
schemaVersion: typeof RECOVERY_SCHEMA_VERSION;
|
|
3512
|
+
/** ISO-8601 UTC timestamp at envelope construction. */
|
|
3513
|
+
generatedAt: string;
|
|
3514
|
+
/** Always `false` — the envelope is only emitted on failure. Reserved for future success-shape symmetry. */
|
|
3515
|
+
ok: false;
|
|
3516
|
+
error: RecoveryError;
|
|
3517
|
+
/** Ordered, deterministic recovery plan. Capped by `MAX_RECOVERY_STEPS` (6). */
|
|
3518
|
+
recovery: GuideStep[];
|
|
3519
|
+
/** v1.17.0 P4: optional read-only probe appended by classifyError; runs only after `--apply` succeeds. */
|
|
3520
|
+
verify?: GuideStep;
|
|
3521
|
+
/** Optional branch plans keyed by BranchId. Present iff `branchFork` is present. */
|
|
3522
|
+
branches?: Record<BranchId, BranchPlan>;
|
|
3523
|
+
/** Optional fork descriptor. Present iff `branches` is present. */
|
|
3524
|
+
branchFork?: BranchFork;
|
|
3525
|
+
}
|
|
3526
|
+
export declare const OPERATION_ENVELOPE_SCHEMA_VERSION: 1;
|
|
3527
|
+
export type OperationEnvelopeOperation = "capabilities.check" | "capabilities.list";
|
|
3528
|
+
export type OperationEnvelopeStatus = "succeeded" | "failed";
|
|
3529
|
+
export type OperationEnvelopeEvidenceKind = "receipt" | "audit" | "verification-artifact";
|
|
3530
|
+
export interface OperationEnvelopeContext {
|
|
3531
|
+
readonly engine: DatabaseSystem;
|
|
3532
|
+
readonly permission: Permission;
|
|
3533
|
+
readonly connectionName: string | null;
|
|
3534
|
+
readonly agentMode: boolean;
|
|
3535
|
+
readonly correlationId?: string;
|
|
3536
|
+
}
|
|
3537
|
+
export interface OperationEnvelopeCapabilityResult {
|
|
3538
|
+
readonly id: string;
|
|
3539
|
+
readonly status: "available" | "unavailable" | "unknown";
|
|
3540
|
+
readonly reason: "unknown-capability" | "context-unavailable" | "context-unresolvable" | "engine" | "agent-mode" | "permission" | null;
|
|
3541
|
+
}
|
|
3542
|
+
export interface OperationEnvelopeCapabilitiesCheckData {
|
|
3543
|
+
readonly required: readonly string[];
|
|
3544
|
+
readonly results: readonly OperationEnvelopeCapabilityResult[];
|
|
3545
|
+
}
|
|
3546
|
+
export interface OperationEnvelopeWarning {
|
|
3547
|
+
readonly code: string;
|
|
3548
|
+
readonly message: string;
|
|
3549
|
+
}
|
|
3550
|
+
export interface OperationEnvelopeEvidenceReference {
|
|
3551
|
+
readonly kind: OperationEnvelopeEvidenceKind;
|
|
3552
|
+
readonly id: string;
|
|
3553
|
+
readonly digest?: string;
|
|
3554
|
+
}
|
|
3555
|
+
export interface OperationEnvelopeError {
|
|
3556
|
+
readonly code: string;
|
|
3557
|
+
readonly message: string;
|
|
3558
|
+
}
|
|
3559
|
+
export interface OperationEnvelope {
|
|
3560
|
+
readonly schemaVersion: typeof OPERATION_ENVELOPE_SCHEMA_VERSION;
|
|
3561
|
+
readonly ok: boolean;
|
|
3562
|
+
readonly operation: OperationEnvelopeOperation;
|
|
3563
|
+
readonly status: OperationEnvelopeStatus;
|
|
3564
|
+
readonly context: OperationEnvelopeContext | null;
|
|
3565
|
+
readonly data: OperationEnvelopeCapabilitiesCheckData | CapabilityCatalog | null;
|
|
3566
|
+
readonly warnings: readonly OperationEnvelopeWarning[];
|
|
3567
|
+
readonly evidence: readonly OperationEnvelopeEvidenceReference[];
|
|
3568
|
+
readonly recovery: RecoveryEnvelope | null;
|
|
3569
|
+
readonly error: OperationEnvelopeError | null;
|
|
3570
|
+
}
|
|
3571
|
+
export type OperationEnvelopeParseResult = {
|
|
3572
|
+
readonly ok: true;
|
|
3573
|
+
readonly value: OperationEnvelope;
|
|
3574
|
+
} | {
|
|
3575
|
+
readonly ok: false;
|
|
3576
|
+
readonly reason: string;
|
|
3577
|
+
};
|
|
3578
|
+
export declare function parseOperationEnvelope(input: unknown): OperationEnvelopeParseResult;
|
|
3284
3579
|
/**
|
|
3285
3580
|
* Read and fully resolve a `.dbcli` project config: handles project-binding
|
|
3286
3581
|
* indirection, v1/v2 formats, per-connection `.env` loading and `{$env}`
|