@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.
Files changed (44) hide show
  1. package/.agents/skills/story-development/SKILL.md +70 -0
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.codex-plugin/plugin.json +1 -1
  4. package/.cursor/rules/dbcli.mdc +65 -2
  5. package/.cursor/skills/dbcli/reference.md +197 -5
  6. package/.cursor-plugin/plugin.json +1 -1
  7. package/.github/skills/dbcli/SKILL.md +65 -2
  8. package/.github/skills/dbcli/reference.md +197 -5
  9. package/CHANGELOG.md +299 -0
  10. package/assets/SKILL.md +65 -2
  11. package/assets/SKILL.zh-TW.md +60 -2
  12. package/assets/integration-kit/README.md +43 -0
  13. package/assets/integration-kit/external-consumers.ts +9 -0
  14. package/assets/integration-kit/skill-author-consumer.ts +77 -0
  15. package/assets/integration-kit/task-pack.md +18 -0
  16. package/assets/reference.md +197 -5
  17. package/assets/tasks/README.md +6 -0
  18. package/assets/tasks/analyze-table-perf.md +3 -3
  19. package/assets/tasks/audit-permissions.md +2 -2
  20. package/assets/tasks/connection-health.md +2 -2
  21. package/assets/tasks/design-review.md +3 -3
  22. package/assets/tasks/diagnose-slow-query.md +3 -3
  23. package/assets/tasks/migration-review.md +3 -3
  24. package/assets/tasks/mongo-safe-backfill.md +2 -2
  25. package/assets/tasks/mongo-schema-drift-review.md +2 -2
  26. package/assets/tasks/orm-drift-review.md +3 -3
  27. package/assets/tasks/pr-database-review.md +3 -3
  28. package/assets/tasks/safe-backfill-verify.md +3 -3
  29. package/assets/tasks/safe-backfill.md +3 -3
  30. package/assets/tasks/schema-drift-review.md +3 -3
  31. package/assets/tasks/slow-endpoint-investigation.md +19 -6
  32. package/assets/ui-template.html +18 -18
  33. package/dist/cli-runtime.mjs +25533 -22188
  34. package/dist/cli.mjs +7 -4
  35. package/dist/core.d.ts +297 -2
  36. package/dist/core.mjs +2075 -3
  37. package/dist/ui-style.css +1 -1
  38. package/gemini-extension.json +1 -1
  39. package/package.json +6 -3
  40. package/plugins/dbcli-agent/.codex-plugin/plugin.json +1 -1
  41. package/plugins/dbcli-agent/skills/dbcli/SKILL.md +65 -2
  42. package/plugins/dbcli-agent/skills/dbcli/reference.md +197 -5
  43. package/skills/dbcli/SKILL.md +65 -2
  44. package/skills/dbcli/reference.md +197 -5
@@ -0,0 +1,70 @@
1
+ ---
2
+ name: story-development
3
+ description: Implement an approved ForgeFlow Story when a request names a Story ID or asks to build work from specs/stories, including tests, verification, repair, and delivery reporting.
4
+ ---
5
+
6
+ # Story Development
7
+
8
+ Treat the approved Story as the intent boundary and repository verification as
9
+ the completion authority.
10
+
11
+ ## Develop the Story
12
+
13
+ 1. Locate `specs/stories/<story-id>/story.md` and
14
+ `acceptance.md`. Read any optional `task.md` as progress
15
+ context only. If the Story is missing, ambiguous, or conflicts with another
16
+ requirement, identify the exact blocker before changing code.
17
+ 2. Extract the Goal, in-scope behavior, out-of-scope boundary, inputs, outputs,
18
+ business rules, expected errors, constraints, and every acceptance item. The
19
+ implementation contract is complete when each acceptance item maps to an
20
+ observable behavior or verification check. When the Story is security
21
+ sensitive, treat every row of its security fixture matrix as a required case
22
+ with an exact payload and expected persisted output; when it declares
23
+ superseded behavior, change the named tests deliberately instead of treating
24
+ the conflict as a defect.
25
+ 3. Read the repository agent guide and inspect the relevant architecture, code,
26
+ tests, dependencies, and documented commands. Project tooling is the source
27
+ of truth for technology-specific mechanics.
28
+ 4. Form a dependency-ordered implementation plan for the smallest coherent
29
+ end-to-end change. Keep requirement decisions with the human; ask only when a
30
+ missing decision materially changes behavior or risk.
31
+ 5. Implement within the Story boundary. Add or update tests at the lowest useful
32
+ boundary for changed behavior, including stable regression coverage for
33
+ repaired defects.
34
+ 6. Run useful focused checks while developing, then run `make verify`
35
+ from the repository root.
36
+
37
+ ## Repair Verification Failures
38
+
39
+ When verification fails, use its output to find the root cause, repair the
40
+ implementation or valid test defect, and run `make verify` again.
41
+ Preserve the approved Story, acceptance criteria, and required checks throughout
42
+ the loop.
43
+
44
+ Stop only when:
45
+
46
+ - `make verify` exits successfully; or
47
+ - a genuine specification blocker requires human intent before safe progress is
48
+ possible.
49
+
50
+ Verification failure by itself is not a specification blocker.
51
+
52
+ ## Deliver
53
+
54
+ After PASS, report:
55
+
56
+ - changed files
57
+ - implementation summary
58
+ - tests added or changed
59
+ - the exact verification command and result
60
+ - assumptions
61
+ - remaining risks
62
+
63
+ When the work changes hands, record the handoff lifecycle block: exactly one
64
+ current Story, exactly one next Story or `pending`, completed Story IDs, the
65
+ repository baseline commit and worktree state, and the last verification command
66
+ and result. State that selection is pending rather than implying it by ordering.
67
+
68
+ If specification-blocked, report the conflicting or missing requirement,
69
+ evidence already inspected, and the smallest human decision needed. Do not
70
+ claim completion.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dbcli-agent",
3
- "version": "7.0.0",
3
+ "version": "8.0.0",
4
4
  "description": "Database CLI skill and command reference for AI agents.",
5
5
  "author": {
6
6
  "name": "Carl Lee",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dbcli-agent",
3
- "version": "7.0.0",
3
+ "version": "8.0.0",
4
4
  "description": "Database CLI skill and command reference for AI agents",
5
5
  "author": {
6
6
  "name": "Carl Lee",
@@ -127,7 +127,11 @@ still stop where those gates require human confirmation.
127
127
 
128
128
  **Business-language discovery:** When a user uses a business alias, metric, recurring
129
129
  term, or relationship/join intent instead of a physical table or field name, first run
130
- `dbcli skill context --format json`. If it includes `semantic`, treat that reviewed
130
+ `dbcli skill context --context-version 2 --format json`. This offline, bounded contract
131
+ does not read project source, open a connection, scan Redis, or interpret natural language.
132
+ Read project code only through this agent's own workspace safety checks; never pass source
133
+ paths or contents to dbcli. If `gaps` reports missing evidence, do not guess metadata: inspect
134
+ permitted code or ask for it. If it includes `semantic`, treat that reviewed
131
135
  section as the governed vocabulary; use `dbcli semantic search <terms> --format json`
132
136
  to look up a specific term. If `contracts` is present, use only its approved terms and
133
137
  their descriptive evidence policy; it never authorizes an assertion or query. If no semantic section exists or search returns no result, fall back to `blacklist` → `schema` mapping and tell the user that optional
@@ -135,6 +139,64 @@ their descriptive evidence policy; it never authorizes an assertion or query. If
135
139
  migrate that file without an explicit human request; semantic vocabulary never replaces
136
140
  schema confirmation or the normal query/write safety gates.
137
141
 
142
+ ## Capability discovery
143
+
144
+ Before composing a workflow, ask dbcli what it can do here rather than assuming. The
145
+ catalog is static and the check reads only the local config — **neither opens a database
146
+ connection.**
147
+
148
+ ```bash
149
+ dbcli capabilities --format json # full catalog
150
+ dbcli capabilities --format markdown # table for docs
151
+ dbcli capabilities check --require schema.read,query.read # gate your workflow
152
+ dbcli capabilities check --require data.delete --format json # machine-readable
153
+ ```
154
+
155
+ For a copyable Bun/TypeScript consumer with strict parsing, schema pins, exit handling,
156
+ Operation Envelope handling, Task Pack `safety.requires`, and correlation/evidence guidance,
157
+ start with `assets/integration-kit/README.md`.
158
+
159
+ A capability is one atomic dbcli ability (`schema.read`, `data.delete`), never a job or a
160
+ method. `dba.tune-production` and `crud.scaffold` belong to the Role or Method Skill that
161
+ composes dbcli — this Tool Skill only covers operating dbcli safely.
162
+
163
+ - `schemaVersion` is the capability contract version, **not** the npm package version.
164
+ - Statuses are `available`, `unavailable` (reason `engine`, `agent-mode`, `permission`,
165
+ `context-unavailable` or `context-unresolvable`) and `unknown`. A misspelled id fails
166
+ closed and is never guessed.
167
+ - Under `DBCLI_AGENT_MODE=1`, capabilities that change configuration are `unavailable`
168
+ with reason `agent-mode` whatever the permission level says.
169
+ - Exit codes: `0` all available, `1` any unavailable or unknown, `2` bad input.
170
+ - **`available` is not approval.** Blacklist, write gate, confirmation and audit still run
171
+ at execution time, and `admin` in a config file is a permission level, not a DBA sign-off.
172
+ - v1 covers the commands the engine capability matrix governs; anything outside it returns
173
+ `unknown` rather than an unaudited engine claim.
174
+
175
+ **Agent output v1 (PLAT-005):** use `dbcli --agent-output capabilities` or
176
+ `dbcli --agent-output capabilities check --require <ids>`; the root flag must precede the
177
+ subcommand, and no other operation is supported yet. It writes one compact UTF-8 JSON envelope plus
178
+ newline to stdout, with empty stderr. Its ten keys are `schemaVersion`, `ok`, `operation`, `status`,
179
+ `context`, `data`, `warnings`, `evidence`, `recovery`, and `error`; `schemaVersion` is `1`,
180
+ `operation` is `capabilities.list` or `capabilities.check`, and `status` is `succeeded` or `failed`.
181
+ Do not combine it with explicit `--format` or `--for-agent`: conflicts, invalid placement/input, and
182
+ unsupported operations exit `2`; success exits `0`; unmet requirements and internal failures exit `1`.
183
+ The envelope is capped at 64 KiB including newline, and consumers use field names rather than order.
184
+ The optional root `--correlation-id <id>` must also precede the subcommand. It accepts 1–160 ASCII
185
+ letters, numbers, `.`, `_`, `:`, or `-`; never put secrets or free-form input in it.
186
+ For supported non-static output it appears as `context.correlationId` and existing audit
187
+ `metadata.correlation_id`; command summaries redact it. Static capabilities stays `context: null`.
188
+ It creates no evidence receipt.
189
+
190
+ Code/message vocabulary is locale-independent English: errors are
191
+ `INVALID_AGENT_OUTPUT_OPTIONS` (invalid/misplaced/conflicting options),
192
+ `INVALID_CORRELATION_ID` (invalid or missing `--correlation-id` value),
193
+ `UNSUPPORTED_AGENT_OUTPUT_OPERATION` (outside PLAT-004), `INVALID_CAPABILITY_REQUIREMENTS`
194
+ (invalid `--require`), `CAPABILITY_REQUIREMENTS_UNMET` (completed negative result),
195
+ `AGENT_OUTPUT_LIMIT_EXCEEDED` (64 KiB limit), and `AGENT_OUTPUT_INTERNAL_ERROR` (unexpected
196
+ safe failure). Warnings are `DUPLICATE_CAPABILITY_REQUIREMENT`,
197
+ `CAPABILITY_CONTEXT_UNAVAILABLE`, `CAPABILITY_CONTEXT_UNRESOLVABLE`, and
198
+ `AGENT_MODE_RESTRICTION_ACTIVE`.
199
+
138
200
  ## Agent Task Packs
139
201
 
140
202
  When the user asks for a database workflow ("diagnose this slow query", "audit
@@ -418,6 +480,7 @@ Full flags and edge cases: see [reference.md](../skills/dbcli/reference.md#init)
418
480
  |---------|-----------------|---------|
419
481
  | `init` | n/a | Create `.dbcli` (v1 single or v2 multi via `--conn-name` / `--env-file`). **Usually run by the human** — do NOT re-run to strip `{"$env"}` references; that format is intentional. |
420
482
  | `use` | n/a | Show/switch default named connection (v2 only). |
483
+ | `capabilities` | n/a | Static capability catalog + `check --require <ids>` requirement gate. No database connection. `--format text\|json\|markdown` (`check` is `text\|json`). Exit `0`/`1`/`2`. |
421
484
  | `list` | query-only+ | Tables (SQL), collections (MongoDB), keys (Redis), or indices (Elasticsearch). |
422
485
  | `schema` | query-only+ | SQL: per-table or full scan into `.dbcli/schemas/`. MongoDB: sampled. ES: flattened mapping. Redis: per-key only (type/TTL/size). Supports `--recovery`. |
423
486
  | `query` | query-only+ | SQL, Mongo JSON (`--collection`), Redis command, or ES DSL/Lucene (`--collection`). `--format table\|json\|csv\|html`, `--ui` to open the interactive dashboard in a browser. `--fields` (projection), `--truncate` (cell width), `-f/--query-file` (read query from file or stdin), `--use a,b` (read-only fan-out). Supports `--recovery`. `--slow-ms <n>` sets the passive slow-query hint threshold (default 1000, `0` off): at or above it, table output gains a `Performance hint` footer and JSON gains `metadata.performanceAdvisory`; it runs no extra diagnostics and is suppressed under `--recovery`. Distinct from the `proxy` flag of the same name. See **Query workflow flags**. |
@@ -639,7 +702,7 @@ schema. Raw `query` / `export` invocations render a sortable table only.
639
702
  ## Notes
640
703
 
641
704
  - Query-only mode auto-appends `LIMIT 1000`; add `--no-limit` for `information_schema` or statements that break with `LIMIT`.
642
- - Blacklisted tables and columns are redacted from query output.
705
+ - Blacklisted tables and columns are redacted from query output. Every entry in `blacklist.tables` and `blacklist.columns` is a glob (`*`, `?`, `[a-z]`) on every engine, and a rule is compared against the whole dotted path case-insensitively — a rule spelled `password` also covers `Password`, and `profile.ssn` covers `profile.SSN`; a table literally named `report*` has to be written `report\*` to match literally again. `--fields` is unaffected and still matches exactly. A rule that cannot mean anything is rejected when the config loads rather than silently protecting nothing: a column entry qualified with its own table (`{"users": ["users.password"]}`) fails to load, and an unparsable rule makes every `dbcli es` request fail until it is fixed.
643
706
  - `schema` reports `estimatedRowCount` and `sizeCategory` (small / medium / large / huge). For large/huge tables add `WHERE` or `LIMIT` — bands in [reference.md](../skills/dbcli/reference.md#schema).
644
707
  - `doctor` on `mongodb+srv://` reports whether SRV resolves natively or through the DoH fallback — useful when the runtime restricts DNS.
645
708
  - **Global flags:** `--version`, `--config <path>`, `--global`, `--use <name>`, `--timeout <ms>`, `--statement-timeout <ms>`, `-v` / `--verbose` / `-vv`, `-q` / `--quiet`, `--no-color` (also honours `NO_COLOR`). Root-level flags must precede the command unless the command explicitly declares a command-level option.
@@ -43,6 +43,7 @@ never the right move.
43
43
  [snapshot](#snapshot) ·
44
44
  [assert](#assert) ·
45
45
  [proxy](#proxy) ·
46
+ [capabilities](#capabilities) ·
46
47
  [status](#status) ·
47
48
  [inspect](#inspect) ·
48
49
  [report](#report) ·
@@ -85,6 +86,8 @@ command-level option is only valid after the command that declares it.
85
86
  | `--use <connection>` | Select a named connection for this invocation; place it before the command path unless that command explicitly lists a command-level `--use`. |
86
87
  | `--timeout <ms>` | Connection timeout in milliseconds (integer, 100–600000), overriding the connection config's `timeout` field for this invocation. Applies to every engine adapter. Without either the flag or the config field, adapters fall back to their built-in 5000ms default. |
87
88
  | `--statement-timeout <ms>` | How long a single statement may run, in milliseconds (integer, 0–3600000; `0` removes the limit), overriding the connection config's `statementTimeout` field. Independent of the connection timeout — raising it does not slow down detection of an unreachable host. Falls back to `--timeout` when unset, and to the server's own setting when neither is given. |
89
+ | `--agent-output` | Request the PLAT-005 v1 Operation Envelope. It must precede the subcommand and currently supports `capabilities` and `capabilities check`; it conflicts with explicit `--format` and command-local `--for-agent`. |
90
+ | `--correlation-id <id>` | Associate one invocation with a Story, incident, change request, migration, or backfill. Place it before the subcommand. IDs are 1–160 ASCII letters, numbers, dots, underscores, colons, or hyphens; never use sensitive or free-form data. |
88
91
 
89
92
  `--timeout` is applied only when the adapter is constructed for this invocation — it is
90
93
  never written back to `config.json`. Set the connection's `timeout` field instead for a
@@ -1102,6 +1105,26 @@ dbcli blacklist column remove users.password
1102
1105
 
1103
1106
  **Subcommands:** `list`, `table add <name>`, `table remove <name>`, `column add <table.column>`, `column remove <table.column>`
1104
1107
 
1108
+ **Matching semantics (7.0.0):** every entry in `blacklist.tables` and `blacklist.columns` is a
1109
+ glob (`*`, `?`, `[abc]`, `[a-z]`) on **every** engine, not only Redis and Elasticsearch — `tables:
1110
+ ["secrets*"]` blocks the SQL table `secrets_2026` and the MongoDB collection `secrets_2026` alike.
1111
+ A table literally named `report*` has to be written `report\*` to match literally again. Rules and
1112
+ returned names are compared over the **whole dotted path, case-insensitively**, so `password` also
1113
+ covers `Password` and `profile.ssn` covers `profile.SSN`; folding happens at the comparison and the
1114
+ config keeps rules as written. The cost is deliberate over-rejection: where PostgreSQL holds both
1115
+ `"Password"` and `"password"`, a rule naming either redacts both. `--fields` is unaffected and still
1116
+ matches exactly — it names keys in the document in front of the operator, not a protection rule.
1117
+
1118
+ Column-level entries are a **display filter, not an access control**: masking matches returned
1119
+ names, so `SELECT password_hash AS x` still returns the value. Table-level entries are the
1120
+ enforceable half.
1121
+
1122
+ A rule that cannot mean anything fails loudly instead of silently protecting nothing: a column entry
1123
+ qualified with its own table (`{"users": ["users.password"]}`) fails to load, and a rule the
1124
+ Elasticsearch shell cannot parse (`pass[word`, `a.**`) makes every `dbcli es` request fail until the
1125
+ config is fixed. Entries are trimmed and unquoted, and a rule filed under `public.users` applies to
1126
+ `SELECT * FROM users` and the reverse.
1127
+
1105
1128
  **`list` options:** `--config <path>`, `--format <text|json>` (default: `text`). JSON writes one
1106
1129
  document to stdout: `{ "tables": string[], "columns": Record<string, string[]>, "warnings":
1107
1130
  [{ "collection", "raw", "reason" }] }`. Invalid MongoDB blacklist patterns appear in `warnings`;
@@ -1278,6 +1301,10 @@ The normalized JSON escape hatch is Zod-validated and uses an array of tables
1278
1301
  with explicit exact `identity` objects; optional parsed identifiers must include
1279
1302
  their `quoted` flags, and every normalized JSON `unparsed.reason` must start with
1280
1303
  `blocked:`.
1304
+ A Drizzle snapshot or normalized JSON artifact that is not valid JSON, and a
1305
+ normalized JSON artifact that violates that contract, fail closed: the error
1306
+ names the offending file and lists the fields at fault, bounded with a count of
1307
+ the remainder, rather than degrading to `unparsed`.
1281
1308
 
1282
1309
  ```json
1283
1310
  {
@@ -1649,6 +1676,150 @@ Every actionable block carries machine-readable next steps so an agent can move
1649
1676
  **Engines:** MySQL / MariaDB / PostgreSQL
1650
1677
  **Permission:** n/a (acts as a TCP relay; does not use dbcli's SQL permission model)
1651
1678
 
1679
+ ### capabilities
1680
+
1681
+ Discovery. Lists the static dbcli capability catalog — what this tool can do,
1682
+ described in a versioned shape an external Skill can parse before it starts
1683
+ working. It never opens a database connection and never writes anything.
1684
+
1685
+ A **capability** names one atomic dbcli ability (`schema.read`, `data.delete`).
1686
+ It is not a job and not a method: `dba.tune-production` or `crud.scaffold`
1687
+ belong to the Role or Method Skill that composes dbcli, never to dbcli itself.
1688
+
1689
+ ```bash
1690
+ dbcli capabilities # human-readable (default)
1691
+ dbcli capabilities --format json # for agents and Skills
1692
+ dbcli capabilities --format markdown # table, for docs
1693
+ ```
1694
+
1695
+ Each entry carries `id`, `description`, `command`, `risk`, `sideEffect`,
1696
+ `engines`, `limitedEngines`, `engineIndependent`, `minimumPermission`,
1697
+ `requiresConnection`, `mutatesConfiguration`, `supportsJson` and
1698
+ `supportsEvidence`. `limitedEngines` is the subset of `engines` the support
1699
+ matrix marks *limited* rather than fully supported. Output is sorted by `id`, so two runs of
1700
+ the same build are byte-identical.
1701
+
1702
+ `schemaVersion` is the **capability contract** version, not the npm package
1703
+ version. Pin `schemaVersion`, never `7.x`.
1704
+
1705
+ **Scope:** the catalog covers every public command, including `explain`, `plan`,
1706
+ `impact assess`, `assert`, `snapshot`, `verify`, `verification`, `evidence`,
1707
+ `contract`, `semantic`, `design`, `proxy`, `recovery`, `backfill artifact`,
1708
+ `password`, and `capabilities` itself. An id it does not know is still
1709
+ `unknown`, which fails closed.
1710
+
1711
+ Every engine claim was read out of the implementation. Where the code refuses a
1712
+ non-SQL connection outright — `explain`, `plan`, `assert`, `snapshot`, `verify`,
1713
+ `proxy` — the entry is `unsupported` for MongoDB, Redis and Elasticsearch and
1714
+ the note names the gate. Where only one *mode* needs SQL — `--against-cache` for
1715
+ `impact assess`, `design diff` and `design propose`, and `draft validate` for
1716
+ `semantic` — the entry is `limited` there, because the rest of the command runs
1717
+ fine. Where a command never opens a connection at all, it is
1718
+ engine-independent. Nothing is marked supported on an engine the code does not
1719
+ settle.
1720
+
1721
+ **Permission:** query-only+ (no connection is made)
1722
+
1723
+ #### capabilities check
1724
+
1725
+ Asks whether the capabilities you need are available *here* — against this
1726
+ machine's local configuration only. It reads engine and permission from the
1727
+ config; it does not connect to the database to find out.
1728
+
1729
+ ```bash
1730
+ dbcli capabilities check --require schema.read,query.read
1731
+ dbcli capabilities check --require schema.read,data.delete --format json
1732
+ dbcli --use staging capabilities check --require schema.read --format json
1733
+ dbcli --agent-output capabilities check --require schema.read
1734
+ ```
1735
+
1736
+ For a copyable Bun/TypeScript consumer that strictly parses this contract, pins schema
1737
+ versions, handles exit codes and Operation Envelopes, and includes Task Pack and
1738
+ correlation/evidence examples, see `assets/integration-kit/README.md`.
1739
+
1740
+ #### Agent output v1 (PLAT-005)
1741
+
1742
+ `dbcli --agent-output capabilities` and `dbcli --agent-output capabilities check --require <ids>`
1743
+ are the supported operations. Either emits one compact UTF-8 JSON document followed by one newline
1744
+ on stdout, with stderr empty. The envelope always has, in stable order, `schemaVersion`, `ok`,
1745
+ `operation`, `status`, `context`, `data`, `warnings`, `evidence`, `recovery`, and `error`; consumers
1746
+ must use the names, not the order. `schemaVersion` is `1`, `operation` is `capabilities.list` or
1747
+ `capabilities.check`, and `status` is `succeeded` or `failed`. The full document, including newline,
1748
+ is capped at 64 KiB.
1749
+
1750
+ The flag must be before the subcommand and conflicts with explicitly supplied `--format` or
1751
+ `--for-agent`. Invalid placement/input and unsupported operations exit `2`; success exits `0`;
1752
+ unmet requirements and internal failures exit `1`. This output is ephemeral: it is not evidence and
1753
+ adds no timestamp. `--correlation-id <id>` is an optional root option. For supported non-static
1754
+ agent output, it appears as `context.correlationId` and in the existing audit entry as
1755
+ `metadata.correlation_id`; command summaries redact it. Static `capabilities` output remains
1756
+ `context: null`, and the option creates or changes no evidence receipt.
1757
+
1758
+ Code/message vocabulary is locale-independent English. Stable error codes mean:
1759
+
1760
+ | Code | Meaning |
1761
+ |---|---|
1762
+ | `INVALID_AGENT_OUTPUT_OPTIONS` | The agent-output option is invalid, misplaced, or conflicts with explicit output options. |
1763
+ | `UNSUPPORTED_AGENT_OUTPUT_OPERATION` | The requested operation is outside PLAT-005 support. |
1764
+ | `INVALID_CAPABILITY_REQUIREMENTS` | `--require` is missing, empty, or malformed. |
1765
+ | `CAPABILITY_REQUIREMENTS_UNMET` | A completed check found one or more unavailable or unknown requirements. |
1766
+ | `AGENT_OUTPUT_LIMIT_EXCEEDED` | The otherwise valid serialized envelope exceeded 64 KiB. |
1767
+ | `AGENT_OUTPUT_INTERNAL_ERROR` | An unexpected failure was replaced with the safe agent-output failure. |
1768
+ | `INVALID_CORRELATION_ID` | The root correlation ID is absent or does not match the allowed identifier grammar. |
1769
+
1770
+ Stable warning codes mean:
1771
+
1772
+ | Code | Meaning |
1773
+ |---|---|
1774
+ | `DUPLICATE_CAPABILITY_REQUIREMENT` | A repeated required id was de-duplicated in first-seen order. |
1775
+ | `CAPABILITY_CONTEXT_UNAVAILABLE` | No local configuration was available to evaluate. |
1776
+ | `CAPABILITY_CONTEXT_UNRESOLVABLE` | Configuration exists but cannot yield an engine and permission. |
1777
+ | `AGENT_MODE_RESTRICTION_ACTIVE` | `DBCLI_AGENT_MODE=1` refuses configuration, permission, and credential changes. |
1778
+
1779
+ | Flag | Purpose |
1780
+ |---|---|
1781
+ | `--require <ids>` | Comma-separated capability ids. Required; an empty list is refused rather than reported as ok. |
1782
+ | `--format <type>` | `text` (default) or `json`. |
1783
+
1784
+ Each result is `available`, `unavailable` or `unknown`:
1785
+
1786
+ | Status | Reason | Means |
1787
+ |---|---|---|
1788
+ | `available` | `null` | The configured engine and permission would not refuse it. |
1789
+ | `unavailable` | `engine` | The configured engine does not support it. |
1790
+ | `unavailable` | `permission` | The configured permission level is below its minimum. |
1791
+ | `unavailable` | `agent-mode` | `DBCLI_AGENT_MODE=1` is set and the capability changes configuration, permission or credentials — refused unconditionally. |
1792
+ | `unavailable` | `context-unavailable` | No local config here, so there is nothing to evaluate against. |
1793
+ | `unavailable` | `context-unresolvable` | A config exists but could not be resolved into an engine and a permission — an `{"$env": "..."}` reference pointing at an unset variable, for instance. Distinct from "no config", because saying there is none would be false. |
1794
+ | `unknown` | `unknown-capability` | No such capability id. Never guessed at — a typo is refused, not resolved to a neighbour. |
1795
+
1796
+ A duplicate id in `--require` is de-duplicated in first-seen order and reported
1797
+ in `warnings`; `required` and `results` each hold it once.
1798
+
1799
+ `required` and `results` hold the ids you asked for in first-seen input order,
1800
+ so `results[i]` answers `required[i]` and you never have to re-index by id to
1801
+ read your own answer. Reordering the arguments therefore reorders the output and
1802
+ the two byte streams differ; what reordering never changes is a capability's
1803
+ status, its reason, or the overall `ok`. Identical input is byte-identical
1804
+ output.
1805
+
1806
+ **Exit codes:** `0` every requirement available · `1` any unavailable or
1807
+ unknown · `2` invalid input or an unreadable format.
1808
+
1809
+ Blockers are reported least-fixable first — engine, then agent mode, then
1810
+ permission — so `reason` names the one actually in the way.
1811
+
1812
+ **`available` is not approval.** It says the gate would not refuse on engine,
1813
+ agent-mode and permission grounds. Blacklist, write gate, confirmation and audit all still run
1814
+ at execution time, and no human has agreed to anything. `admin` in a config file
1815
+ is a permission level, not a DBA sign-off.
1816
+
1817
+ `schema.read` is available under `DBCLI_AGENT_MODE=1`, and `dbcli schema` runs
1818
+ there: storing the schema cache is not a configuration change. Agent mode still
1819
+ refuses every change to connection identity, permission and credentials.
1820
+
1821
+ **Permission:** query-only+ (no connection is made)
1822
+
1652
1823
  ### status
1653
1824
 
1654
1825
  Show current configuration status (safe for AI agents, no credentials exposed).
@@ -2928,14 +3099,18 @@ The strict v1 artifact contains `version` and `contracts`. Each contract has a u
2928
3099
  canonical `name`, `status` (`draft`, `approved`, or `deprecated`), bounded plain-text
2929
3100
  `description` and `owner`, one or more canonical semantic `subjects`, optional aliases,
2930
3101
  and an `evidencePolicy` of `none`, `receipt-required`, or `verification-required`.
2931
- Subjects must remain in the existing visible semantic registry; protected identifiers,
2932
- unknown keys, duplicate names or subjects, SQL-like text, credentials, and stale
2933
- references fail closed without exposing protected names.
3102
+ Each subject must use one of the canonical `model:` / `field:` / `relationship:` /
3103
+ `metric:` forms and must remain in the existing visible semantic registry; protected
3104
+ identifiers, unknown keys, duplicate names or subjects, SQL-like text, credentials, and
3105
+ stale references fail closed without exposing protected names. Diagnostics name the
3106
+ offending property or subject position, never a rejected key, value, or local path taken
3107
+ from the artifact or the local configuration.
2934
3108
 
2935
3109
  `contract validate` requires an explicit valid artifact. `contract context` and
2936
3110
  `contract search` return only valid approved contracts; draft and deprecated contracts
2937
3111
  remain local review artifacts. `contract drift` reports `valid`, `stale`, `invalid`, or
2938
- `unavailable` evidence offline and exits non-zero except for `valid`. A missing default
3112
+ `unavailable` evidence offline and exits non-zero except for `valid`; a subject whose form
3113
+ is unsupported is `invalid`, while a well-formed subject that no longer exists is `stale`. A missing default
2939
3114
  file is allowed by `skill context` and leaves ordinary semantic context unchanged; a
2940
3115
  present invalid file fails closed. No contract command writes a file, opens a database
2941
3116
  connection, widens a `QueryDraft`, or changes permission/blacklist behavior.
@@ -2983,12 +3158,23 @@ Emit an AI-friendly snapshot of the connected database's schema and saved-query
2983
3158
  dbcli skill context # XML (default)
2984
3159
  dbcli skill context --format json
2985
3160
  dbcli skill context --format markdown
3161
+ dbcli skill context --context-version 2 --format json
2986
3162
  ```
2987
3163
 
2988
3164
  **Options:**
2989
3165
  - `--format <xml|json|markdown>` — output format (default: `xml`)
3166
+ - `--context-version <version>` — explicit agent contract; version `2` supports
3167
+ PostgreSQL, MySQL, MariaDB, Elasticsearch, and Redis. Omit it for byte-compatible v1.
2990
3168
 
2991
- **Permission:** query-only+ — read-only; blacklisted objects are never emitted.
3169
+ Version 2 is offline and bounded: it emits only visible cached SQL tables/fields,
3170
+ flattened Elasticsearch fields, or declared Redis key families, plus safe capability,
3171
+ snippet, semantic, contract, and data-access metadata. It never connects, scans Redis,
3172
+ reads documents or project source, or emits values, credentials, query bodies/defaults,
3173
+ source paths, counts, or raw mappings. Missing evidence is reported in `gaps`; invalid
3174
+ evidence fails with a stable `INVALID_*` code. MongoDB rejects explicit v2.
3175
+
3176
+ **Permission:** query-only+ — read-only; blacklisted objects are never emitted outside
3177
+ the blacklist policy.
2992
3178
 
2993
3179
  ### skill tasks (Agent Task Packs)
2994
3180
 
@@ -3547,6 +3733,12 @@ dbcli query "KEYS *" # → returns only non-blacklisted key
3547
3733
 
3548
3734
  Rejections are written to the audit log with `success: false` and `metadata.rejection_reason: 'blacklist'` + `matched_pattern`.
3549
3735
 
3736
+ Enforcement covers `q` and `report` as well (7.0.0). Before that, saved queries and the built-in
3737
+ `@diag/redis-key-stats` diagnostic ran on an adapter that carried the connection but none of its
3738
+ rules, so `dbcli q @<name>` could read a protected key in plaintext and a report could persist
3739
+ protected key names. Both now resolve their key targets before execution, apply the connection's
3740
+ blacklist and `redis.mask` rules, and drop protected key names from `SCAN` evidence.
3741
+
3550
3742
  ### Value / hash-field masking (v1.22)
3551
3743
 
3552
3744
  Where the key-glob blacklist *rejects*, masking instead *redacts*: a matched read still
@@ -2,7 +2,7 @@
2
2
  "name": "dbcli-agent",
3
3
  "displayName": "dbcli Agent",
4
4
  "description": "Database CLI skill and command reference for AI agents.",
5
- "version": "7.0.0",
5
+ "version": "8.0.0",
6
6
  "author": {
7
7
  "name": "Carl Lee",
8
8
  "url": "https://github.com/CarlLee1983"
@@ -127,7 +127,11 @@ still stop where those gates require human confirmation.
127
127
 
128
128
  **Business-language discovery:** When a user uses a business alias, metric, recurring
129
129
  term, or relationship/join intent instead of a physical table or field name, first run
130
- `dbcli skill context --format json`. If it includes `semantic`, treat that reviewed
130
+ `dbcli skill context --context-version 2 --format json`. This offline, bounded contract
131
+ does not read project source, open a connection, scan Redis, or interpret natural language.
132
+ Read project code only through this agent's own workspace safety checks; never pass source
133
+ paths or contents to dbcli. If `gaps` reports missing evidence, do not guess metadata: inspect
134
+ permitted code or ask for it. If it includes `semantic`, treat that reviewed
131
135
  section as the governed vocabulary; use `dbcli semantic search <terms> --format json`
132
136
  to look up a specific term. If `contracts` is present, use only its approved terms and
133
137
  their descriptive evidence policy; it never authorizes an assertion or query. If no semantic section exists or search returns no result, fall back to `blacklist` → `schema` mapping and tell the user that optional
@@ -135,6 +139,64 @@ their descriptive evidence policy; it never authorizes an assertion or query. If
135
139
  migrate that file without an explicit human request; semantic vocabulary never replaces
136
140
  schema confirmation or the normal query/write safety gates.
137
141
 
142
+ ## Capability discovery
143
+
144
+ Before composing a workflow, ask dbcli what it can do here rather than assuming. The
145
+ catalog is static and the check reads only the local config — **neither opens a database
146
+ connection.**
147
+
148
+ ```bash
149
+ dbcli capabilities --format json # full catalog
150
+ dbcli capabilities --format markdown # table for docs
151
+ dbcli capabilities check --require schema.read,query.read # gate your workflow
152
+ dbcli capabilities check --require data.delete --format json # machine-readable
153
+ ```
154
+
155
+ For a copyable Bun/TypeScript consumer with strict parsing, schema pins, exit handling,
156
+ Operation Envelope handling, Task Pack `safety.requires`, and correlation/evidence guidance,
157
+ start with `assets/integration-kit/README.md`.
158
+
159
+ A capability is one atomic dbcli ability (`schema.read`, `data.delete`), never a job or a
160
+ method. `dba.tune-production` and `crud.scaffold` belong to the Role or Method Skill that
161
+ composes dbcli — this Tool Skill only covers operating dbcli safely.
162
+
163
+ - `schemaVersion` is the capability contract version, **not** the npm package version.
164
+ - Statuses are `available`, `unavailable` (reason `engine`, `agent-mode`, `permission`,
165
+ `context-unavailable` or `context-unresolvable`) and `unknown`. A misspelled id fails
166
+ closed and is never guessed.
167
+ - Under `DBCLI_AGENT_MODE=1`, capabilities that change configuration are `unavailable`
168
+ with reason `agent-mode` whatever the permission level says.
169
+ - Exit codes: `0` all available, `1` any unavailable or unknown, `2` bad input.
170
+ - **`available` is not approval.** Blacklist, write gate, confirmation and audit still run
171
+ at execution time, and `admin` in a config file is a permission level, not a DBA sign-off.
172
+ - v1 covers the commands the engine capability matrix governs; anything outside it returns
173
+ `unknown` rather than an unaudited engine claim.
174
+
175
+ **Agent output v1 (PLAT-005):** use `dbcli --agent-output capabilities` or
176
+ `dbcli --agent-output capabilities check --require <ids>`; the root flag must precede the
177
+ subcommand, and no other operation is supported yet. It writes one compact UTF-8 JSON envelope plus
178
+ newline to stdout, with empty stderr. Its ten keys are `schemaVersion`, `ok`, `operation`, `status`,
179
+ `context`, `data`, `warnings`, `evidence`, `recovery`, and `error`; `schemaVersion` is `1`,
180
+ `operation` is `capabilities.list` or `capabilities.check`, and `status` is `succeeded` or `failed`.
181
+ Do not combine it with explicit `--format` or `--for-agent`: conflicts, invalid placement/input, and
182
+ unsupported operations exit `2`; success exits `0`; unmet requirements and internal failures exit `1`.
183
+ The envelope is capped at 64 KiB including newline, and consumers use field names rather than order.
184
+ The optional root `--correlation-id <id>` must also precede the subcommand. It accepts 1–160 ASCII
185
+ letters, numbers, `.`, `_`, `:`, or `-`; never put secrets or free-form input in it.
186
+ For supported non-static output it appears as `context.correlationId` and existing audit
187
+ `metadata.correlation_id`; command summaries redact it. Static capabilities stays `context: null`.
188
+ It creates no evidence receipt.
189
+
190
+ Code/message vocabulary is locale-independent English: errors are
191
+ `INVALID_AGENT_OUTPUT_OPTIONS` (invalid/misplaced/conflicting options),
192
+ `INVALID_CORRELATION_ID` (invalid or missing `--correlation-id` value),
193
+ `UNSUPPORTED_AGENT_OUTPUT_OPERATION` (outside PLAT-004), `INVALID_CAPABILITY_REQUIREMENTS`
194
+ (invalid `--require`), `CAPABILITY_REQUIREMENTS_UNMET` (completed negative result),
195
+ `AGENT_OUTPUT_LIMIT_EXCEEDED` (64 KiB limit), and `AGENT_OUTPUT_INTERNAL_ERROR` (unexpected
196
+ safe failure). Warnings are `DUPLICATE_CAPABILITY_REQUIREMENT`,
197
+ `CAPABILITY_CONTEXT_UNAVAILABLE`, `CAPABILITY_CONTEXT_UNRESOLVABLE`, and
198
+ `AGENT_MODE_RESTRICTION_ACTIVE`.
199
+
138
200
  ## Agent Task Packs
139
201
 
140
202
  When the user asks for a database workflow ("diagnose this slow query", "audit
@@ -418,6 +480,7 @@ Full flags and edge cases: see [reference.md](reference.md#init).
418
480
  |---------|-----------------|---------|
419
481
  | `init` | n/a | Create `.dbcli` (v1 single or v2 multi via `--conn-name` / `--env-file`). **Usually run by the human** — do NOT re-run to strip `{"$env"}` references; that format is intentional. |
420
482
  | `use` | n/a | Show/switch default named connection (v2 only). |
483
+ | `capabilities` | n/a | Static capability catalog + `check --require <ids>` requirement gate. No database connection. `--format text\|json\|markdown` (`check` is `text\|json`). Exit `0`/`1`/`2`. |
421
484
  | `list` | query-only+ | Tables (SQL), collections (MongoDB), keys (Redis), or indices (Elasticsearch). |
422
485
  | `schema` | query-only+ | SQL: per-table or full scan into `.dbcli/schemas/`. MongoDB: sampled. ES: flattened mapping. Redis: per-key only (type/TTL/size). Supports `--recovery`. |
423
486
  | `query` | query-only+ | SQL, Mongo JSON (`--collection`), Redis command, or ES DSL/Lucene (`--collection`). `--format table\|json\|csv\|html`, `--ui` to open the interactive dashboard in a browser. `--fields` (projection), `--truncate` (cell width), `-f/--query-file` (read query from file or stdin), `--use a,b` (read-only fan-out). Supports `--recovery`. `--slow-ms <n>` sets the passive slow-query hint threshold (default 1000, `0` off): at or above it, table output gains a `Performance hint` footer and JSON gains `metadata.performanceAdvisory`; it runs no extra diagnostics and is suppressed under `--recovery`. Distinct from the `proxy` flag of the same name. See **Query workflow flags**. |
@@ -639,7 +702,7 @@ schema. Raw `query` / `export` invocations render a sortable table only.
639
702
  ## Notes
640
703
 
641
704
  - Query-only mode auto-appends `LIMIT 1000`; add `--no-limit` for `information_schema` or statements that break with `LIMIT`.
642
- - Blacklisted tables and columns are redacted from query output.
705
+ - Blacklisted tables and columns are redacted from query output. Every entry in `blacklist.tables` and `blacklist.columns` is a glob (`*`, `?`, `[a-z]`) on every engine, and a rule is compared against the whole dotted path case-insensitively — a rule spelled `password` also covers `Password`, and `profile.ssn` covers `profile.SSN`; a table literally named `report*` has to be written `report\*` to match literally again. `--fields` is unaffected and still matches exactly. A rule that cannot mean anything is rejected when the config loads rather than silently protecting nothing: a column entry qualified with its own table (`{"users": ["users.password"]}`) fails to load, and an unparsable rule makes every `dbcli es` request fail until it is fixed.
643
706
  - `schema` reports `estimatedRowCount` and `sizeCategory` (small / medium / large / huge). For large/huge tables add `WHERE` or `LIMIT` — bands in [reference.md](reference.md#schema).
644
707
  - `doctor` on `mongodb+srv://` reports whether SRV resolves natively or through the DoH fallback — useful when the runtime restricts DNS.
645
708
  - **Global flags:** `--version`, `--config <path>`, `--global`, `--use <name>`, `--timeout <ms>`, `--statement-timeout <ms>`, `-v` / `--verbose` / `-vv`, `-q` / `--quiet`, `--no-color` (also honours `NO_COLOR`). Root-level flags must precede the command unless the command explicitly declares a command-level option.