@carllee1983/dbcli 1.11.0 → 1.17.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.
@@ -439,6 +439,302 @@ dbcli status --format text # Human-readable text output
439
439
  **Output:** `permission`, `system`, `blacklist` summary, `version`
440
440
  **Permission:** query-only+
441
441
 
442
+ ### inspect
443
+
444
+ Read-only snapshot for AI agents. Never emits credentials or blacklisted values.
445
+
446
+ | Flag | Purpose |
447
+ |------|---------|
448
+ | `--format <json\|markdown>` | Output format (default `json`) |
449
+ | `--brief` | Drop sample arrays and trim suggested commands to ≤3 |
450
+ | `--for-agent` | Shortcut for `--format json --brief` |
451
+ | `--no-connect` | Skip the cheap version/object probe (no DB traffic) |
452
+ | `--probe-timeout <ms>` | Hard timeout for the version/object probe (default 1500) |
453
+
454
+ Example:
455
+
456
+ ```bash
457
+ dbcli inspect --for-agent
458
+ ```
459
+
460
+ Output schema is locked at `schemaVersion: 1`. Sections: `connection`, `permission`, `blacklist`, `objects`, `schemaCache`, `snippets`, `suggestedCommands`, `warnings`.
461
+
462
+ **Permission:** query-only+
463
+
464
+ ### report
465
+
466
+ Diagnostic report built on top of `inspect`. Reuses inspect context (connection,
467
+ permission, blacklist, snippet inventory) and additionally runs curated built-in
468
+ `@diag/*` snippets grouped into sections.
469
+
470
+ Flags:
471
+ - `--format json|markdown` (default: json)
472
+ - `--section health,capacity,perf` (default: all three)
473
+ - `--brief` — drop evidence rows; keep counts and statuses
474
+ - `--for-agent` — shortcut for `--format json --brief`
475
+ - `--no-connect` — context-only snapshot (skip diagnostics + inspect probe)
476
+ - `--per-snippet-timeout <ms>` (default 3000)
477
+ - `--max-rows-per-evidence <n>` (default 50)
478
+ - `--probe-timeout <ms>` (default 1500, inherited from inspect)
479
+
480
+ Examples:
481
+
482
+ dbcli report --format json
483
+ dbcli report --format markdown --section health,capacity
484
+ dbcli report --for-agent
485
+ dbcli report --no-connect
486
+
487
+ Boundaries:
488
+ - Read-only. Skips snippets whose required params have no default value.
489
+ - Never connects in `--no-connect` mode.
490
+ - MongoDB and no-config workspaces emit a context-only snapshot with a warning.
491
+
492
+ **Permission:** query-only+
493
+
494
+ ### guide
495
+
496
+ Deterministic next-command planner for a fixed set of database goals. Reuses
497
+ `inspect` context (cache-first) and the workspace's saved-query inventory to
498
+ emit an ordered, read-only plan that an AI agent can follow step-by-step.
499
+
500
+ Goals (fixed list):
501
+ - `slow-query` — diagnose slow queries (long-running, locks, cache, indexes).
502
+ - `capacity` — audit storage and memory.
503
+ - `health` — connections, locks, cluster status.
504
+ - `index-usage` — index effectiveness audit.
505
+ - `permissions` — review permission level, blacklist, snippet inventory.
506
+ - `schema-overview` — orient in an unfamiliar database.
507
+
508
+ Flags:
509
+ - `--format json|markdown` (default: json)
510
+ - `--brief` — drop rationale + expects fields
511
+ - `--for-agent` — shortcut for `--format json --brief`
512
+ - `--list` — list available goals and exit
513
+ - `--probe` — refresh inspect context via live probe (default: cache-first)
514
+ - `--probe-timeout <ms>` (default 1500, inherited from inspect)
515
+
516
+ Examples:
517
+
518
+ dbcli guide slow-query
519
+ dbcli guide capacity --format markdown
520
+ dbcli guide --list
521
+ dbcli guide health --for-agent
522
+ dbcli guide schema-overview --probe
523
+
524
+ Boundaries:
525
+ - Read-only. Guide plans commands; it does not execute them.
526
+ - Goal vocabulary is fixed in v1.14.0; user-supplied goals are rejected.
527
+ - Each step carries `risk: 'readonly'` in v1.14.0 (forward-compatible with v1.15.0 recovery).
528
+ - Coexists with `dbcli skill tasks plan` (template-driven). Use guide for ad-hoc goals; use task packs for repeatable workflows.
529
+
530
+ **Permission:** query-only+
531
+
532
+ ### recovery
533
+
534
+ Machine-readable error envelope. Two surfaces share one `RecoveryEnvelope`
535
+ shape (`schemaVersion: 1`):
536
+
537
+ 1. **Standalone lookup**: `dbcli recovery --code <CODE>` synthesizes an
538
+ envelope for any known recovery code without needing a real failure.
539
+ 2. **Failing-command opt-in**: pass `--recovery` to `dbcli query` or
540
+ `dbcli q`. On failure, the envelope is written to stdout as JSON, the
541
+ human stderr message is suppressed, and the process exits non-zero.
542
+
543
+ Recovery codes (fixed in v1.15.0):
544
+ - `CONFIG_MISSING` — no `.dbcli` config; run `dbcli init`.
545
+ - `CONN_REFUSED` / `CONN_AUTH_FAILED` / `CONN_TIMEOUT` / `CONN_HOST_NOT_FOUND` / `CONN_UNKNOWN` — connection failure variants.
546
+ - `PERMISSION_DENIED` — active permission level forbids the operation.
547
+ - `BLACKLIST_TABLE` / `BLACKLIST_COLUMN_WRITE` — blacklist violations.
548
+ - `SNIPPET_NOT_FOUND` / `SNIPPET_AMBIGUOUS` / `SNIPPET_PARAM_MISSING` — saved-query failures.
549
+ - `SCHEMA_CACHE_MISSING` — local schema cache missing or stale.
550
+ - `UNKNOWN` — fallback for unclassified errors.
551
+
552
+ Flags (lookup mode):
553
+ - `--code <CODE>` — required unless `--list` is set.
554
+ - `--list` — list all codes and exit.
555
+ - `--format json|markdown` (default: json).
556
+ - `--brief` — drop `rationale` + `expects` from steps.
557
+ - `--for-agent` — shortcut for `--format json --brief`.
558
+ - `--hint <text>` — bind into placeholder steps.
559
+ - `--snippet <name>` — bind snippet placeholder.
560
+ - `--table <name>` — bind table placeholder.
561
+
562
+ Examples:
563
+
564
+ dbcli recovery --code CONN_REFUSED
565
+ dbcli recovery --code BLACKLIST_TABLE --table users --format markdown
566
+ dbcli recovery --list --for-agent
567
+ dbcli query "SELECT * FROM users" --recovery
568
+ dbcli q @diag/missing --recovery
569
+
570
+ Boundaries:
571
+ - Recovery only **suggests** commands; agents (or humans) execute them. No automatic remediation in v1.15.0.
572
+ - As of v1.16.0, `--recovery` is honored on `query`, `q`, `insert`, `update`, `delete`, `export`, `schema`, and `inspect`. Other commands (`report`, `guide`, `doctor`, `migrate`, `init`, `use`, `status`, `list`, `check`, `diff`, `plan`, `shell`, `blacklist`, `completion`, `upgrade`, `skill`) keep their existing error behavior.
573
+ - `dbcli inspect --require-schema-cache` throws `SCHEMA_CACHE_MISSING` when the active SQL connection has no usable schema cache. Combine with `--recovery` for the structured envelope.
574
+ - `BLACKLIST_COLUMN_WRITE` and `PERMISSION_DENIED` envelopes prepend a `risk: 'dry-run'` step (e.g. `dbcli insert <table> --dry-run`) when the failing operation was an INSERT / UPDATE / DELETE.
575
+ - Recovery steps reuse the v1.14.0 `GuideStep` shape, including the full `risk` enum (`readonly` / `dry-run` / `write` / `unknown`).
576
+
577
+ **Permission:** n/a
578
+
579
+ ### recover
580
+
581
+ (v1.17.0+) Inspect or apply the last recovery plan saved by `--recovery`.
582
+
583
+ | Flag | Purpose | Default |
584
+ |---|---|---|
585
+ | `--apply` | Execute the saved plan under risk gating. | off (inspect only) |
586
+ | `--from <path>` | Read the envelope from this file instead of `.dbcli/last-recovery.json`. Accepts raw `RecoveryEnvelope` or `SavedRecoveryEnvelope`. | — |
587
+ | `--allow-write <tier>` | Open the risk gate. Values: `readonly-cmd` (local-side writes) \| `write-cmd` (database writes). | `none` |
588
+ | `--no-verify` | Skip the verify step appended after a successful `--apply`. | off (verify runs by default) |
589
+ | `--format <format>` | `markdown` \| `json`. | `markdown` for inspect, `json` for `--apply` |
590
+
591
+ #### Plan source resolution
592
+
593
+ 1. `--from <path>` if provided. The file must be either a raw `RecoveryEnvelope` or a `SavedRecoveryEnvelope` wrapper. When the file is a `SavedRecoveryEnvelope`, its `cwd` is reused for child-process execution. Strict zod validation; malformed → exit 2 with structured reason.
594
+ 2. Otherwise, `.dbcli/last-recovery.json` (auto-saved on every recovery emission). Validated with the same schema; missing fields, unknown `error.code`, or `cwd` that no longer exists → exit 2.
595
+ 3. Otherwise, exits 2 with `No recovery plan available. Run a command with --recovery to generate one, or pass --from <file>.`
596
+
597
+ #### Code-owned tier (trust boundary)
598
+
599
+ `--apply` derives the canonical execution tier from the per-`error.code` allowlist after parsing argv, **not** from the envelope's `risk` / `dbWrite` / `interactive` fields. Envelope hints can only widen safety (skip more steps); they cannot escalate execution.
600
+
601
+ | Allowlist tier | Meaning | Example commands |
602
+ |---|---|---|
603
+ | `readonly` | local read-only | `dbcli inspect`, `dbcli doctor`, `dbcli blacklist list`, `dbcli schema <table>` |
604
+ | `dry-run` | write subcommand invoked with `--dry-run` | `dbcli update orders --where id=1 --dry-run`, `dbcli q @x --dry-run` |
605
+ | `local-write` | writes local config / cache / blacklist | `dbcli blacklist remove <table>`, `dbcli use <name>`, `dbcli schema --refresh` |
606
+ | `db-write` | mutates the connected database | `dbcli update orders --where id=1 --set …` (no `--dry-run`), `dbcli q @x` (no `--dry-run`) |
607
+ | `interactive` | requires TTY | `dbcli init`, `dbcli init --force` |
608
+
609
+ `insert` / `update` / `delete` / `q` are tier `dry-run` only when argv contains `--dry-run`; otherwise they are tier `db-write` regardless of envelope `risk` claim.
610
+
611
+ #### Risk gate matrix
612
+
613
+ | Allowlist tier | Default | `--allow-write=readonly-cmd` | `--allow-write=write-cmd` |
614
+ |---|---|---|---|
615
+ | `readonly` | run | run | run |
616
+ | `dry-run` | run | run | run |
617
+ | `local-write` | `skipped:risk` | run | run |
618
+ | `db-write` | `skipped:risk` | `skipped:risk` | run |
619
+ | `interactive` | `skipped:interactive` | `skipped:interactive` | `skipped:interactive` |
620
+ | unresolved placeholder in `command` | `skipped:placeholder` | `skipped:placeholder` | `skipped:placeholder` |
621
+ | command fails parse / allowlist | `skipped:unsafe-command` | `skipped:unsafe-command` | `skipped:unsafe-command` |
622
+
623
+ Precedence: envelope `interactive: true` > `placeholder` > `unsafe-command` > allowlist `interactive` > tier-based gating.
624
+
625
+ #### Exit codes
626
+
627
+ | Code | Condition |
628
+ |---|---|
629
+ | 0 | At least one step ran successfully and no step failed. |
630
+ | 1 | A step exited non-zero (fail-fast); see `stoppedAt`. |
631
+ | 2 | Envelope missing or malformed (failed schema validation, or saved `cwd` missing). |
632
+ | 3 | Every step was skipped — open `--allow-write` or fill placeholders. |
633
+
634
+ #### Auto-saved envelope
635
+
636
+ Every command that emits a `RecoveryEnvelope` (`query`, `q`, `insert`, `update`, `delete`, `export`, `schema`, `inspect` — all with `--recovery`) atomically writes the envelope to `.dbcli/last-recovery.json`. The wrapper carries `schemaVersion`, `savedAt`, a sanitized `command` summary, the workspace `cwd`, and the envelope itself. SQL text and `--where` / `--set` / `--data` / `--param` values are redacted as `<sql>` or `<redacted>`. `.dbcli/` is gitignored.
637
+
638
+ #### Verification (P4)
639
+
640
+ Each `RecoveryEnvelope` now carries an optional `verify: GuideStep` (always
641
+ `risk: 'readonly'`, never carries placeholders). `dbcli recover --apply` runs
642
+ the verify step after the main plan, only when `finalStatus === 'ok'` and
643
+ `--no-verify` is not set.
644
+
645
+ | Recovery code | Verify command | Heuristic |
646
+ |---|---|---|
647
+ | CONFIG_MISSING | `dbcli inspect --no-connect --format json` | `connection.name` truthy → passed |
648
+ | CONN_REFUSED / CONN_TIMEOUT / CONN_UNKNOWN / CONN_AUTH_FAILED / CONN_HOST_NOT_FOUND | `dbcli doctor --format json` | exit 0 → passed |
649
+ | PERMISSION_DENIED | `dbcli inspect --for-agent` | exit 0 → passed |
650
+ | BLACKLIST_TABLE | `dbcli inspect --for-agent` | exit 0 → passed |
651
+ | BLACKLIST_COLUMN_WRITE | `dbcli inspect --for-agent` | exit 0 → passed |
652
+ | SNIPPET_NOT_FOUND / SNIPPET_AMBIGUOUS / SNIPPET_PARAM_MISSING | `dbcli queries list --format json` | exit 0 → passed |
653
+ | SCHEMA_CACHE_MISSING | `dbcli inspect --format json` | `schemaCache.available === true` → passed |
654
+ | UNKNOWN | `dbcli doctor --format json` | exit 0 → passed |
655
+
656
+ `verifyStatus` values:
657
+
658
+ - `passed` — heuristic confirmed.
659
+ - `failed` — verifier exited non-zero or timed out.
660
+ - `indeterminate` — verifier exited 0 but expected shape not present, or the
661
+ step was gated (placeholder / unsafe-command); agents should re-check.
662
+
663
+ Exit codes are unchanged — `verifyStatus` is signal, not gate.
664
+
665
+ **Schema additions.** `RecoveryEnvelope.verify?: GuideStep` is additive (no
666
+ `schemaVersion` bump). v1.16 consumers ignore the field.
667
+
668
+ #### Multi-turn `--next` (P2)
669
+
670
+ `dbcli recover --next` returns the single next step in a saved recovery plan,
671
+ given which step the agent just executed and the result of that step. v1 walks
672
+ the plan linearly; future codes may branch on `prevResult.stdoutSummary`
673
+ deterministically.
674
+
675
+ | Flag | Required | Description |
676
+ |---|---|---|
677
+ | `--next` | yes | Activate the multi-turn lookup. |
678
+ | `--after-step <n>` | yes | 1-based order of the step the agent just executed. Range: `[1, envelope.recovery.length]`. |
679
+ | `--result <value>` | yes | JSON `StepResultSummary` (inline) or `@<path>` to read from a file. |
680
+ | `--from <path>` | no | Override the auto-saved envelope. |
681
+ | `--format <fmt>` | no | `json` (default) or `markdown`. |
682
+
683
+ `--next` and `--apply` cannot be combined. `--allow-write` and `--no-verify`
684
+ are silently ignored under `--next` (no execution, no verification).
685
+
686
+ **`StepResultSummary` shape**
687
+
688
+ ```ts
689
+ interface StepResultSummary {
690
+ status: 'ok' | 'failed' | 'skipped'
691
+ exitCode?: number
692
+ stdoutSummary?: string // last 4 KB; longer rejected
693
+ stderrSummary?: string // last 4 KB; longer rejected
694
+ }
695
+ ```
696
+
697
+ `@<path>` resolves relative to the dbcli invocation cwd. File whole-size cap is
698
+ 64 KB; per-field 4 KB cap still applies.
699
+
700
+ **`NextResult` shape (output)**
701
+
702
+ ```ts
703
+ interface NextResult {
704
+ schemaVersion: 1
705
+ kind: 'step' | 'done'
706
+ source: { kind: 'auto' | 'from'; path: string }
707
+ errorCode: RecoveryCode
708
+ cursor: number // step.order when kind='step'; totalSteps when 'done'
709
+ totalSteps: number
710
+ step?: GuideStep // present iff kind='step'
711
+ }
712
+ ```
713
+
714
+ **Exit codes**
715
+
716
+ | Exit | Condition |
717
+ |---|---|
718
+ | 0 | Returned a step or `done`. |
719
+ | 2 | Envelope missing/malformed; `--after-step` missing/out-of-range; `--result` missing/malformed; `--next` combined with `--apply`. |
720
+
721
+ **Examples**
722
+
723
+ ```bash
724
+ # Walk a 3-step plan to completion
725
+ dbcli recover --next --after-step 1 --result '{"status":"ok"}' # → step 2
726
+ dbcli recover --next --after-step 2 --result '{"status":"ok"}' # → step 3
727
+ dbcli recover --next --after-step 3 --result '{"status":"ok"}' # → done
728
+
729
+ # Result read from file (when stdout is large)
730
+ dbcli recover --next --after-step 1 --result @/tmp/r1.json
731
+
732
+ # Markdown for human inspection
733
+ dbcli recover --next --after-step 1 --result '{"status":"ok"}' --format markdown
734
+ ```
735
+
736
+ **Permission:** n/a (always-allowed lookup; child processes inherit the active permission level).
737
+
442
738
  ### doctor
443
739
 
444
740
  Run diagnostic checks on environment, configuration, connection, and data.