dsh-dbhub-live 5.1.0 → 5.2.0-dev.3
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.md +116 -254
- package/README.en.md +96 -11
- package/README.md +97 -12
- package/doc/ARCHITECTURE.md +108 -0
- package/doc/CLIENT.md +124 -0
- package/doc/DESENSITIZE.md +56 -0
- package/doc/DEVELOPMENT.md +139 -0
- package/doc/IMPACT-MATRIX.md +36 -0
- package/doc/RELEASE.md +93 -0
- package/doc/REQUIREMENTS.md +41 -3
- package/lib/client.js +704 -27
- package/lib/config.mjs +3 -0
- package/lib/i18n.mjs +14 -4
- package/lib/index.mjs +107 -0
- package/lib/meta.mjs +267 -0
- package/lib/options.mjs +16 -1
- package/lib/policy.mjs +92 -0
- package/lib/tools.mjs +4 -1
- package/lib/update.mjs +244 -0
- package/package.json +32 -9
- package/scripts/desensitize-check.mjs +10 -3
- package/scripts/desensitize.config.mjs +18 -10
- package/scripts/docs-check.mjs +214 -0
- package/scripts/release-preflight.mjs +180 -0
- package/scripts/render-check.mjs +286 -2
- package/test/client-format.test.mjs +89 -5
- package/test/meta.test.mjs +234 -0
- package/test/options.test.mjs +28 -15
- package/test/policy.test.mjs +132 -0
- package/test/update.test.mjs +270 -0
package/README.en.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
[](https://www.npmjs.com/package/dsh-dbhub-live)
|
|
9
9
|
[](https://dsh-plugin.org/plugins/mr-mihu/dsh-dbhub-live)
|
|
10
10
|
|
|
11
|
-
> Let the AI inside [DeepSeek Harness](https://github.com/deepseek-ai/DeepSeek-Harness) query your databases directly — **
|
|
11
|
+
> Let the AI inside [DeepSeek Harness](https://github.com/deepseek-ai/DeepSeek-Harness) query your databases directly — **the password is typed in the UI, not passed to the model as a tool argument**.
|
|
12
12
|
|
|
13
13
|
Install it and you can simply tell the AI "show me the last 10 rows of the orders table". The AI runs SQL through [DBHub](https://dbhub.ai) (a database MCP server), but all it ever knows is *which environment of which workspace*, plus metadata such as `mysql://host:3306/db`; **passwords, accounts and full connection strings always stay on your machine**, typed only into the box in front of you.
|
|
14
14
|
|
|
@@ -23,7 +23,7 @@ Install it and you can simply tell the AI "show me the last 10 rows of the order
|
|
|
23
23
|
|
|
24
24
|
| | |
|
|
25
25
|
| --- | --- |
|
|
26
|
-
| 🔒 **
|
|
26
|
+
| 🔒 **Credentials stay out of tool arguments** | The model only sees type / host / port / database; the password and the full DSN are not accepted as tool arguments — they are typed in the UI |
|
|
27
27
|
| ⚡ **One-shot process** | No resident dbhub service: every call is its own process, killed the moment it finishes; a failed query only affects itself, and parallel instances never kill each other |
|
|
28
28
|
| 🧮 **Always 4 tools** | However many environments you add, the model context never grows |
|
|
29
29
|
| 🗂 **Per workspace × environment** | One workspace can hold `default` / `prod` / `dev`… (environment names may be Chinese), told apart by their `source` — never the wrong database |
|
|
@@ -33,19 +33,63 @@ Install it and you can simply tell the AI "show me the last 10 rows of the order
|
|
|
33
33
|
|
|
34
34
|
Supports **MySQL · PostgreSQL · MariaDB · SQLite · SQL Server**.
|
|
35
35
|
|
|
36
|
+
<!-- release-test:versions:begin -->
|
|
37
|
+
## Supported version range
|
|
38
|
+
|
|
39
|
+
**From DSH 0.1.5 (lines 0.1.5 / 0.1.6 / 0.1.7 / 0.2.0 / 0.2.1, prereleases included)** — 6 declared versions verified (last verified 2026-10-24).
|
|
40
|
+
|
|
41
|
+
<details>
|
|
42
|
+
<summary>Per-version verification details (expand)</summary>
|
|
43
|
+
|
|
44
|
+
| DSH version | UI | Boot | Hard checks | Result | Last verified |
|
|
45
|
+
| --- | --- | --- | --- | --- | --- |
|
|
46
|
+
| `0.1.5-rc.3` | legacy | 7.3s | 19 | ⚠️ pass with notes · manual | 2026-10-24 · 4f6a854a |
|
|
47
|
+
| `0.1.6-alpha.2` | legacy | 3.5s | 19 | ⚠️ pass with notes · manual | 2026-10-24 · 4f6a854a |
|
|
48
|
+
| `0.1.7-rc.2` | legacy | 4.7s | 20 | ⚠️ pass with notes · manual | 2026-10-24 · 4f6a854a |
|
|
49
|
+
| `0.2.0-rc.2` | legacy | 4.9s | 20 | ⚠️ pass with notes · manual | 2026-10-24 · 4f6a854a |
|
|
50
|
+
| `0.2.1-alpha.1` | modern | 5.1s | 20 | ⚠️ pass with notes · manual | 2026-10-24 · 4f6a854a |
|
|
51
|
+
| `0.2.1-rc.2` | modern | 5.3s | 20 | ⚠️ pass with notes · manual | 2026-10-24 · 4f6a854a |
|
|
52
|
+
|
|
53
|
+
</details>
|
|
54
|
+
|
|
55
|
+
Full evidence, review rules and known drift live in [doc/SUPPORT-MATRIX.md](doc/SUPPORT-MATRIX.md).
|
|
56
|
+
<!-- release-test:versions:end -->
|
|
57
|
+
|
|
36
58
|
## Installation
|
|
37
59
|
|
|
38
60
|
```bash
|
|
39
|
-
# dsh
|
|
61
|
+
# web (dsh web)
|
|
40
62
|
dsh plugin --profile web add dsh-dbhub-live
|
|
41
63
|
|
|
42
|
-
#
|
|
64
|
+
# desktop
|
|
65
|
+
dsh plugin --profile desktop add dsh-dbhub-live
|
|
66
|
+
|
|
67
|
+
# no dsh yet (use npx): same commands, prefix them with npx @deepseek-ai/dsh
|
|
43
68
|
npx @deepseek-ai/dsh plugin --profile web add dsh-dbhub-live
|
|
69
|
+
npx @deepseek-ai/dsh plugin --profile desktop add dsh-dbhub-live
|
|
44
70
|
```
|
|
45
71
|
|
|
72
|
+
On desktop you can also **install entirely through the UI**: **left menu → Plugins → Add → type `dsh-dbhub-live` (or search the plugin marketplace) → Install**. **The same plugin works on both the web profile and the desktop profile**, with the same UI and behaviour; installing, updating and uninstalling on desktop can all be done on that Plugins page.
|
|
73
|
+
|
|
46
74
|
Once installed, **restart `dsh web`** and open **Settings → DBHub Database Tools** to see the configure page (there is also a sidebar shortcut, and the Configure control on the plugin's row on the Plugins page — all three entries lead to the same page).
|
|
47
75
|
|
|
48
|
-
> Requirements: every `dsh` release line from 0.1.5 on (0.2.x included); Node.js ≥ 18 is recommended locally (it is used to install dbhub automatically). **Read-only mode and SSH tunnels need dbhub 1.4.0+** — the plugin detects this and gives you upgrade guidance.
|
|
76
|
+
> Requirements: every `dsh` release line from 0.1.5 on (0.2.x included); **the new UI needs 0.2.1+** (0.2.1 prereleases included) — the wide full page, the version/update header and the inline read-only switch only render on 0.2.1 and later; **0.1.x is still supported but keeps the old layout and behaviour**. Node.js ≥ 18 is recommended locally (it is used to install dbhub automatically). **Read-only mode and SSH tunnels need dbhub 1.4.0+** — the plugin detects this and gives you upgrade guidance. Per-version verification results live in [doc/SUPPORT-MATRIX.md](doc/SUPPORT-MATRIX.md) (generated by the release test, which must pass before every release).
|
|
77
|
+
|
|
78
|
+
## Updating
|
|
79
|
+
|
|
80
|
+
**Web** (command line):
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
dsh plugin --profile web up dsh-dbhub-live@<latest version>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Then **restart `dsh web`**.
|
|
87
|
+
|
|
88
|
+
**Desktop**: uninstall the plugin on the **left menu → Plugins** page and reinstall the latest version (desktop updates go through the visual Plugins page). **Connections and credentials survive the reinstall** — they live in `~/.dsh/storages/dsh-dbhub-live`, independent of the module directory.
|
|
89
|
+
|
|
90
|
+
**No need to remember version numbers**: the configure page header shows the plugin name and the current version; when a newer version exists a quiet "**↑ Upgrade to <latest>**" text link appears and **clicking it copies** `dsh-dbhub-live@<latest>`; the "Check for updates" button next to it checks on demand. Opening the page also triggers one automatic check (throttled, so it does not hit the network on every open). Checks use the **npm registry first, with GitHub Releases as the fallback**; release notes live in [GitHub Releases](https://github.com/mr-mihu/dsh-dbhub-live/releases).
|
|
91
|
+
|
|
92
|
+
> The version/update hint is part of the new UI and needs plugin 5.2.0+ and DSH 0.2.1+; on 0.1.x it is not shown (see "Configure Page").
|
|
49
93
|
|
|
50
94
|
## Quick Start
|
|
51
95
|
|
|
@@ -67,6 +111,8 @@ AI: … (query results)
|
|
|
67
111
|
|
|
68
112
|
The password is only ever typed into the box in front of you. If you give only part of the picture (say "connect to mydb on 192.0.2.10"), the plugin **probes with those non-sensitive facts first**: if it connects, the connection is saved straight away (password-less databases need no input at all); if only the password is missing it asks just for "account (when unknown) + password"; only when the information is incomplete do you choose a full method (enter a DSN / fill in fields / authorise a scan of project config files).
|
|
69
113
|
|
|
114
|
+
> **Do not paste a password into the chat.** The plugin itself does not hand the password to the model, but **anything you paste into the conversation does enter the context** — the plugin cannot prevent that, and cannot take it back.
|
|
115
|
+
|
|
70
116
|
When the workspace already has `mise env` or a `.env` (`DSN` / `DB_*`), the plugin discovers it automatically — no manual configuration needed.
|
|
71
117
|
|
|
72
118
|
## Tools
|
|
@@ -81,6 +127,23 @@ When the workspace already has `mise env` or a `.env` (`DSN` / `DB_*`), the plug
|
|
|
81
127
|
> **Every source belongs to exactly one workspace**: to reuse a connection from another workspace, copy it over with `dbhub_configure`'s `copyFrom` — do not query another workspace's source directly.
|
|
82
128
|
> `search_objects` is currently available for SQLite only; for MySQL / PostgreSQL etc. use `dbhub_execute_sql` (e.g. `SHOW TABLES`).
|
|
83
129
|
|
|
130
|
+
## Model-facing database access policy
|
|
131
|
+
|
|
132
|
+
While the plugin is enabled it contributes a **system-prompt section** (about 400 characters) that keeps database access on this plugin and states how it coexists with **other database plugins**:
|
|
133
|
+
|
|
134
|
+
- **One authorized route — scoped to this plugin's own connections**: every database listed by `dbhub_list_sources` goes through the `dbhub_*` tools; no `psql` / `mysql` / `sqlite3` / `sqlcmd` / `pg_dump` command-line client, throwaway script, driver, other MCP, or **other database plugin** is used to reach them, and the agent does not go looking for such an executable on the host.
|
|
135
|
+
- **A workspace "recipe" is not authorization**: direct-connection instructions found in project docs, scripts, or `AGENTS.md` (for example a psql recipe an earlier session wrote itself) are never followed — the system prompt outranks workspace instructions.
|
|
136
|
+
- **Read-only is the user's safety boundary**: after a `READONLY_VIOLATION` the agent must not complete the write by any other route (**including another database plugin**); it reports the reason and the impact instead.
|
|
137
|
+
- **Databases this plugin does not cover stay with the plugin that does**: dbhub speaks MySQL / PostgreSQL / MariaDB / SQLite / SQL Server only. MongoDB / Redis / Oracle and any instance **you never configured here** are explicitly handed to the other database plugin you installed — the agent must not refuse them for the sake of "everything through this plugin", and must not fall back to a command-line connection either.
|
|
138
|
+
- **The same database configured in both plugins**: the default is this plugin's source (read-only and tunnel settings live here); the agent switches only when you explicitly ask for the other tool, and asks you when it cannot tell.
|
|
139
|
+
- **Operations this plugin cannot do**: backups and non-SQL administration commands are reported as a limitation, and the agent asks you for an authorized route instead of improvising.
|
|
140
|
+
|
|
141
|
+
**Switch**: "Announce the database-access policy to the model" in the settings (expanded inline in the wide page's settings block; in the modal layout it sits behind the ⚙ Settings strip), **on by default**; a deployment can also pin it with `config: { announceAccessPolicy: false }` in `cordis.patch.yml`. Turning it off only removes that text — tools, read-only, tunnels and every other setting keep working.
|
|
142
|
+
|
|
143
|
+
**No plugin suppression**: this plugin does not (and cannot) disable another database plugin you installed. The conflict is resolved by the three rules above — scope, a default for overlapping targets, and asking you when it cannot tell. Which plugin to disable is your decision, made on the Plugins page.
|
|
144
|
+
|
|
145
|
+
**Honest boundary**: this policy is a **prompt-level (soft) constraint**; read-only itself is **hard-rejected** by dbhub inside the plugin. A shell-level connection that bypasses the plugin is outside the plugin's control — the policy names it explicitly, but it relies on the model complying rather than blocking it.
|
|
146
|
+
|
|
84
147
|
## Configure Page
|
|
85
148
|
|
|
86
149
|
<details>
|
|
@@ -90,19 +153,32 @@ When the workspace already has `mise env` or a `.env` (`DSN` / `DB_*`), the plug
|
|
|
90
153
|
|
|
91
154
|
</details>
|
|
92
155
|
|
|
93
|
-
|
|
94
|
-
|
|
156
|
+
The same component offers **three layouts**, picked automatically from the host surface and the window width (the new UI needs plugin 5.2.0+ and **DSH 0.2.1+**; on DSH 0.1.x the old layout and behaviour are kept, see the end of this section):
|
|
157
|
+
|
|
158
|
+
| Layout | How to reach it | Shape |
|
|
159
|
+
| --- | --- | --- |
|
|
160
|
+
| Modal | **Settings → DBHub Database Tools** | A narrow modal, same density as before, settings behind the "Settings" disclosure on the status line |
|
|
161
|
+
| Wide page | The **DBHub** entry in the left menu / the Configure control on the Plugins row | A full page in a wide column, with the version and upgrade entry in the header and settings rows expanded inline |
|
|
162
|
+
| Small screen | A mobile browser, width < ~700px | Stacked and compact, controls sized for touch |
|
|
163
|
+
|
|
164
|
+
**Header: version and upgrade entry**: the title is the plugin name with the current version (small, muted) right next to it; when a newer version exists a quiet "**↑ Upgrade to <latest>**" text link appears on the right, and **clicking it expands** the update notes — the `dsh-dbhub-live@<latest>` spec (click to copy), the update command / steps for this deployment, and a link to the release notes; the "↻" button checks on demand. Opening the page also triggers an automatic check (throttled). Checks use the npm registry first, with GitHub Releases as the fallback. **An update is neutral news, never styled as an error.**
|
|
165
|
+
|
|
166
|
+
- **Status line**: it shows only "running / disabled · N connections". Implementation facts — tool count, one-shot execution mode, dbhub version — live in the collapsed "ⓘ Details & diagnostics" block at the bottom of the page.
|
|
167
|
+
- **Connection list**: organised by workspace. When every workspace has a single environment the rows render as flat cards; as soon as one workspace owns several environments they fold into per-workspace groups (click a group head to expand; the most recently used one is open by default). Each connection takes one line: environment name · type / host / port / **database** · **read-only switch** · the `source` handle (click it to copy) · test / edit / delete. In a narrow window the host and port are truncated first, while **the database name always stays visible**.
|
|
168
|
+
- **Settings (DSH-native style, deliberately quiet)**: on the wide page the four controls collapse into **one compact settings line** — `Plugin settings · Enable plugin [enabled] · Sidebar entry [shown] · Access policy [on] · Auto-update [7] days [save] · ⓘ details`; the modal and the phone use compact stacked rows. Fonts and switches are kept small so the **connection list** stays the main content. The controls are DSH's own switches (theme/skin aware, with state words); every explanatory paragraph lives in "ⓘ Details & diagnostics".
|
|
169
|
+
- **Read-only switch (outside the edit form in all three layouts)**: right next to the datasource on every connection row there is a small "RO" toggle — one click flips it (open lock + "Writable" = writable; closed lock + "RO" = read-only) without opening the edit form; the modal and the phone layout have it too. The tick-box in the edit form stays as well; both are the same state. **The connection string itself no longer carries a lock icon** — it used to read like "this row needs a password" and clashed with the read-only lock.
|
|
95
170
|
- **Add / edit / delete**: use ✏ on a row to change the connection string or the environment name; "+ Add connection" accepts Chinese environment names. **Saving onto an environment name that already exists asks "overwrite?" first** — cancel and not a single byte is written.
|
|
96
171
|
- **Connection test**: runs `SELECT 1` over **the effective connection that environment will really use** (read-only / tunnel included) and shows the elapsed time while it runs. The result is one-shot feedback: nothing is persisted and no connection state changes.
|
|
97
|
-
- **Settings strip** (⚙ Settings): the auto-update interval, and the "Show the sidebar entry" switch.
|
|
98
172
|
|
|
99
173
|
**"Show the sidebar entry" is not disabling the plugin**: switching it off merely hides the sidebar shortcut — the plugin keeps working and the model can still query; use "Disable" to stop the plugin as a whole (a disabled plugin always hides the entry). In either state, **the settings page and the Plugins row's Configure control always stay reachable**, so the change can be undone at any time.
|
|
100
174
|
|
|
175
|
+
**Compatibility path for DSH 0.1.x**: the header version / upgrade entry, the wide full page, the row read-only chip and the settings rows all render only on **DSH 0.2.1+** (prereleases included); on 0.1.x the plugin keeps its previous layout and behaviour and **shows no upgrade hint** — that is deliberate, not a defect.
|
|
176
|
+
|
|
101
177
|
## 🔒 Read-only Mode and SSH Tunnels
|
|
102
178
|
|
|
103
179
|
Both are **per-environment** connection options executed by dbhub's native features. Once either is on, every execution in that environment switches to a **temporary, generated dbhub configuration** (the file holds only `${…}` placeholders and no password at all — the real values reach the child process through its environment) and is deleted as soon as the call ends; every other environment is unaffected.
|
|
104
180
|
|
|
105
|
-
**Read-only mode**:
|
|
181
|
+
**Read-only mode**: in all three layouts the connection row carries a small "RO" switch next to the datasource — one click flips it (you can also click ✏ and tick it in the edit form; the model can enable it for an environment too). dbhub then lets read statements through only (measured on MySQL: `select/with/explain/show/describe/desc`), and writes come straight back as `READONLY_VIOLATION`; object search keeps working. **Turning read-only off is something only you can do on the configure page** — an attempt by the model is refused. A read-only environment's name gains a small "RO" badge.
|
|
106
182
|
|
|
107
183
|
**SSH tunnel** (configured by hand, for databases sitting behind a bastion):
|
|
108
184
|
|
|
@@ -136,14 +212,20 @@ All configuration and credentials live outside the module directory; delete that
|
|
|
136
212
|
~/.dsh/storages/dsh-dbhub-live/
|
|
137
213
|
```
|
|
138
214
|
|
|
139
|
-
Isolated per `DSH_HOME` and shared by multiple profiles of the same instance (the same convention as dsh's own `workspace.json`). Connections are stored per "workspace × environment"; old formats and leftovers from manual edits are cleaned up and migrated in one pass at startup, and the plugin does not crash if the runtime directory is deleted by accident or a write is blocked. **There is no resident process and no shared configuration file**, so several instances running at once on one machine never interfere.
|
|
215
|
+
Isolated per `DSH_HOME` and shared by multiple profiles of the same instance (the same convention as dsh's own `workspace.json`). Connections are stored per "workspace × environment"; old formats and leftovers from manual edits are cleaned up and migrated in one pass at startup, and the plugin does not crash if the runtime directory is deleted by accident or a write is blocked. **There is no resident process and no shared configuration file**, so several instances running at once on one machine never interfere. **Upgrading, reinstalling or uninstalling the plugin never touches this directory** — including the desktop upgrade path of "uninstall, then reinstall the latest": connections, read-only / tunnel settings and credentials are all preserved.
|
|
140
216
|
|
|
141
217
|
## Uninstall
|
|
142
218
|
|
|
143
219
|
```bash
|
|
220
|
+
# web
|
|
144
221
|
dsh plugin --profile web remove dsh-dbhub-live
|
|
222
|
+
|
|
223
|
+
# desktop
|
|
224
|
+
dsh plugin --profile desktop remove dsh-dbhub-live
|
|
145
225
|
```
|
|
146
226
|
|
|
227
|
+
On desktop you can also uninstall directly on the **left menu → Plugins** page. Uninstalling does not delete connections or credentials (see "Data Location"); to wipe everything, delete `~/.dsh/storages/dsh-dbhub-live` by hand.
|
|
228
|
+
|
|
147
229
|
## Troubleshooting
|
|
148
230
|
|
|
149
231
|
| Symptom | Fix |
|
|
@@ -155,7 +237,10 @@ dsh plugin --profile web remove dsh-dbhub-live
|
|
|
155
237
|
| A write reports `READONLY_VIOLATION` after read-only was turned on | Not a fault — read-only is doing its job. To write, clear that environment's "Read-only mode" on the configure page (the model cannot turn it off). |
|
|
156
238
|
| The read-only / SSH controls are greyed out, or dbhub is reported as too old | Both need dbhub 1.4.0+: upgrade dbhub, or delete `~/.dsh/storages/dsh-dbhub-live` so the plugin installs a version that satisfies it. |
|
|
157
239
|
| A connection test fails and you cannot tell why | Read the **end** of the message (the diagnostic is the tail of dbhub's output and marks the layer: [SSH layer] / [database layer] / [plugin layer]). **A [database layer] report means the tunnel is already up**; with a tunnel configured, press "Test SSH tunnel" first to verify the SSH layer on its own. |
|
|
158
|
-
| The configure page is not visible | Check the plugin is installed
|
|
240
|
+
| The configure page is not visible | Check the plugin is installed: restart `dsh web` on the web side; on desktop use the Configure control on the Plugins row or the DBHub entry in the left menu. The page only shows in the Web / desktop UI and does not affect tool usage in terminal environments. |
|
|
241
|
+
| The old UI is still shown after upgrading | The new UI needs **DSH 0.2.1+** (prereleases included) and plugin 5.2.0+; restart after upgrading dsh. On DSH 0.1.x the plugin deliberately keeps the old layout and behaviour and shows no update hint. |
|
|
242
|
+
| No "Upgrade to …" hint appears in the header | You may already be on the latest version, or this check could not reach the npm registry / GitHub Releases; press "Check for updates" to retry. A failed check is only a hint and does not affect plugin functionality. |
|
|
243
|
+
| How do I upgrade on desktop | Uninstall on the **left menu → Plugins** page, then reinstall the latest version; connections and credentials live in `~/.dsh/storages/dsh-dbhub-live` and are still there after the reinstall. |
|
|
159
244
|
| After a dsh upgrade the plugin is reported as incompatible | Upgrade the plugin to 5.0.0+ (it supports both 0.1.x and 0.2.x); forcing it through with `allow-version` buys nothing. |
|
|
160
245
|
| Automatic dbhub updates are not wanted | Set "Auto-update interval (days)" to `0` on the configure page and save, or set `DSH_DBHUB_UPDATE_DAYS=0`. |
|
|
161
246
|
|
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
[](https://www.npmjs.com/package/dsh-dbhub-live)
|
|
9
9
|
[](https://dsh-plugin.org/zh/plugins/mr-mihu/dsh-dbhub-live)
|
|
10
10
|
|
|
11
|
-
> 让 [DeepSeek Harness](https://github.com/deepseek-ai/DeepSeek-Harness) 里的 AI
|
|
11
|
+
> 让 [DeepSeek Harness](https://github.com/deepseek-ai/DeepSeek-Harness) 里的 AI 直接查你的数据库——**密码只在界面里输入,不作为工具参数交给模型**。
|
|
12
12
|
|
|
13
13
|
装上它,你就能直接对 AI 说「查一下 orders 表最近 10 条」。AI 通过 [DBHub](https://dbhub.ai)(数据库 MCP 服务器)执行 SQL,但它只知道「哪个工作区的哪个环境」,以及 `mysql://host:3306/db` 这类元数据;**密码、账号、完整连接串始终留在你本机**,只在你面前的输入框里敲。
|
|
14
14
|
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
|
|
24
24
|
| | |
|
|
25
25
|
| --- | --- |
|
|
26
|
-
| 🔒
|
|
26
|
+
| 🔒 **凭据不进工具参数** | 模型只见类型 / 主机 / 端口 / 库名;密码与完整 DSN 不作为工具参数接收,只在界面输入 |
|
|
27
27
|
| ⚡ **一次性进程** | 无常驻 dbhub 服务:每次调用一条独立进程、跑完即杀;一次查询失败只影响它自己,多实例并行不互杀 |
|
|
28
28
|
| 🧮 **工具恒定 4 个** | 环境再多也不膨胀模型上下文 |
|
|
29
29
|
| 🗂 **按工作区 × 环境管理** | 一个工作区可配 `default` / `prod` / `dev`…(环境名支持中文),用 `source` 区分,绝不串库 |
|
|
@@ -33,19 +33,63 @@
|
|
|
33
33
|
|
|
34
34
|
支持 **MySQL · PostgreSQL · MariaDB · SQLite · SQL Server**。
|
|
35
35
|
|
|
36
|
+
<!-- release-test:versions:begin -->
|
|
37
|
+
## 支持的版本范围
|
|
38
|
+
|
|
39
|
+
**DSH 0.1.5 起(0.1.5 / 0.1.6 / 0.1.7 / 0.2.0 / 0.2.1 共 5 条版本线,含预发布)** — 6 个声明版本已实测通过(最近验证 2026-10-24)。
|
|
40
|
+
|
|
41
|
+
<details>
|
|
42
|
+
<summary>逐版本实测明细(点开查看)</summary>
|
|
43
|
+
|
|
44
|
+
| DSH 版本 | 界面 | 启动 | 硬检查 | 结论 | 最近验证 |
|
|
45
|
+
| --- | --- | --- | --- | --- | --- |
|
|
46
|
+
| `0.1.5-rc.3` | 旧版 | 7.3s | 19 | ⚠️ 通过(有告警) · 手工装配 | 2026-10-24 · 4f6a854a |
|
|
47
|
+
| `0.1.6-alpha.2` | 旧版 | 3.5s | 19 | ⚠️ 通过(有告警) · 手工装配 | 2026-10-24 · 4f6a854a |
|
|
48
|
+
| `0.1.7-rc.2` | 旧版 | 4.7s | 20 | ⚠️ 通过(有告警) · 手工装配 | 2026-10-24 · 4f6a854a |
|
|
49
|
+
| `0.2.0-rc.2` | 旧版 | 4.9s | 20 | ⚠️ 通过(有告警) · 手工装配 | 2026-10-24 · 4f6a854a |
|
|
50
|
+
| `0.2.1-alpha.1` | 新版 | 5.1s | 20 | ⚠️ 通过(有告警) · 手工装配 | 2026-10-24 · 4f6a854a |
|
|
51
|
+
| `0.2.1-rc.2` | 新版 | 5.3s | 20 | ⚠️ 通过(有告警) · 手工装配 | 2026-10-24 · 4f6a854a |
|
|
52
|
+
|
|
53
|
+
</details>
|
|
54
|
+
|
|
55
|
+
完整证据、判定规则与已知偏差见 [doc/SUPPORT-MATRIX.md](doc/SUPPORT-MATRIX.md)。
|
|
56
|
+
<!-- release-test:versions:end -->
|
|
57
|
+
|
|
36
58
|
## 安装
|
|
37
59
|
|
|
38
60
|
```bash
|
|
39
|
-
#
|
|
61
|
+
# web 端(dsh web)
|
|
40
62
|
dsh plugin --profile web add dsh-dbhub-live
|
|
41
63
|
|
|
42
|
-
#
|
|
64
|
+
# 桌面端
|
|
65
|
+
dsh plugin --profile desktop add dsh-dbhub-live
|
|
66
|
+
|
|
67
|
+
# 没装 dsh(用 npx):命令相同,前缀换成 npx @deepseek-ai/dsh
|
|
43
68
|
npx @deepseek-ai/dsh plugin --profile web add dsh-dbhub-live
|
|
69
|
+
npx @deepseek-ai/dsh plugin --profile desktop add dsh-dbhub-live
|
|
44
70
|
```
|
|
45
71
|
|
|
46
|
-
|
|
72
|
+
桌面端也可以**全程用界面装**:**左侧菜单 → 插件 → 新增 → 输入 `dsh-dbhub-live`(或从插件市场搜索)→ 安装**。**同一个插件在 web profile 与 desktop profile 上都能用**,界面与行为一致;桌面端的安装 / 更新 / 卸载都可以在这张「插件」页里完成。
|
|
73
|
+
|
|
74
|
+
装完 web 端**重启 `dsh web`**,打开 **设置 → DBHub 数据库工具** 即可看到配置页(也有左侧栏快捷入口和插件页那行的「配置」,三个入口是同一个页面)。
|
|
75
|
+
|
|
76
|
+
> 环境要求:`dsh` 0.1.5 起的全部版本线(含 0.2.x);**新界面需要 0.2.1+**(含 0.2.1 的预发布版)——宽屏整页、页头版本与升级提示、行内只读开关都只在 0.2.1 及以上出现;**0.1.x 仍受支持,但保持旧版布局与行为**。建议本机有 Node.js ≥ 18(用于自动安装 dbhub)。**只读模式与 SSH 隧道需要 dbhub 1.4.0+**,插件会自动检测并给出升级指引。每个版本的实测记录见 [doc/SUPPORT-MATRIX.md](doc/SUPPORT-MATRIX.md)(由发布测试自动生成,发版前必跑)。
|
|
47
77
|
|
|
48
|
-
|
|
78
|
+
## 更新
|
|
79
|
+
|
|
80
|
+
**Web 端**(命令行):
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
dsh plugin --profile web up dsh-dbhub-live@<最新版本号>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
然后**重启 `dsh web`**。
|
|
87
|
+
|
|
88
|
+
**桌面端**:在 **左侧菜单 → 插件** 页里卸载该插件,再重新安装最新版本(桌面端更新走可视化插件页)。**连接与凭据不会被重装清掉**——它们都在 `~/.dsh/storages/dsh-dbhub-live`,与模块目录无关。
|
|
89
|
+
|
|
90
|
+
**不用自己记版本号**:配置页页头显示插件名与当前版本,检测到更新时会出现一行低调的「**↑ 可升级到 <latest>**」文字链接,**点一下就会复制** `dsh-dbhub-live@<latest>`;旁边的「检查更新」按钮可以随时手动检查。打开页面时也会自动检查一次(有节流,不会每次打开都打网络)。检查以 **npm registry 为主、GitHub Releases 为兜底**,发布说明见 [GitHub Releases](https://github.com/mr-mihu/dsh-dbhub-live/releases)。
|
|
91
|
+
|
|
92
|
+
> 版本与升级提示属于新界面,需要插件 5.2.0+ 且 DSH 0.2.1+;0.1.x 上不显示(见「配置页」)。
|
|
49
93
|
|
|
50
94
|
## 快速开始
|
|
51
95
|
|
|
@@ -67,6 +111,8 @@ AI:…(返回查询结果)
|
|
|
67
111
|
|
|
68
112
|
密码全程只在你面前的输入框里敲。若你只说了一部分信息(比如「连一下 192.0.2.10 上的 mydb」),插件会**先用这些非敏感信息试连**:能连上就直接保存(不需要密码的库全程零输入),只差密码就只问你「账号(未知时)+ 密码」,信息不全才让你选完整方式(输入 DSN / 填写分项 / 授权扫描项目配置文件)。
|
|
69
113
|
|
|
114
|
+
> **别把密码直接粘进对话。** 插件自己不把密码交给模型,但**你亲手粘进对话的内容一定会进入上下文**——这一条插件拦不住,也收不回来。
|
|
115
|
+
|
|
70
116
|
工作区里已有 `mise env` 或 `.env`(`DSN` / `DB_*`)时,插件会自动发现,无需手动配置。
|
|
71
117
|
|
|
72
118
|
## 工具
|
|
@@ -81,6 +127,23 @@ AI:…(返回查询结果)
|
|
|
81
127
|
> **每条 source 只属于一个工作区**:跨工作区复用连接请用 `dbhub_configure` 的 `copyFrom` 复制过来,不要直接拿别的工作区的 source 查询。
|
|
82
128
|
> `search_objects` 目前仅对 SQLite 开放;MySQL / PostgreSQL 等请用 `dbhub_execute_sql`(如 `SHOW TABLES`)。
|
|
83
129
|
|
|
130
|
+
## 模型侧数据库访问策略
|
|
131
|
+
|
|
132
|
+
插件启用期间会向模型注入一条**系统提示词**(约 400 字),把数据库访问收敛到本插件,并写清它与**其它数据库插件共存**时的边界:
|
|
133
|
+
|
|
134
|
+
- **唯一授权途径(只针对本插件已配置的连接)**:`dbhub_list_sources` 里出现的库一律走 `dbhub_*` 工具;不用 `psql` / `mysql` / `sqlite3` / `sqlcmd` / `pg_dump` 等命令行客户端、临时脚本、驱动、其它 MCP 或**其它数据库插件**去连这些库,也不去宿主机上寻找这类可执行文件。
|
|
135
|
+
- **工作区里的"配方"不构成授权**:项目文档、脚本或 `AGENTS.md` 中出现的直连数据库写法(例如某次会话自己写下的 psql 配方)一律不照做——系统提示词的效力高于工作区说明。
|
|
136
|
+
- **只读是用户的安全边界**:命中 `READONLY_VIOLATION` 后不得改用任何其它途径完成写入(**包括换用另一个数据库插件**),只能把原因与影响告知你。
|
|
137
|
+
- **本插件不支持的库让位**:dbhub 只支持 MySQL / PostgreSQL / MariaDB / SQLite / SQL Server。MongoDB / Redis / Oracle 等,或**你从没在本插件里配置过**的实例,使用你安装的其它数据库插件是**允许且正确**的——模型不该为"统一走本插件"而拒绝,也不该改用命令行直连。
|
|
138
|
+
- **同一个库两种插件都装了**:默认用本插件的 source(只读 / 隧道等安全设置在这里);你明确要求换另一个工具时才换;判断不了会先问你,不自行换路。
|
|
139
|
+
- **插件做不到的操作**:备份、非 SQL 管理命令等,先说明限制并请你给出授权方案,不自行绕过。
|
|
140
|
+
|
|
141
|
+
**开关**:设置里的「向模型注入数据库访问策略」(宽屏页直接展开在设置区;弹窗模式在 ⚙ 设置 里),**默认开启**;也可以在 `cordis.patch.yml` 里用 `config: { announceAccessPolicy: false }` 固定。关闭只是不再注入这段文字——工具、只读、隧道与其它设置全部照常工作。
|
|
142
|
+
|
|
143
|
+
**不压制同类插件**:插件不会(也无法)禁用你安装的其它数据库插件。冲突靠上面三条收敛:作用域(只管自己配置的连接)、重叠目标的默认优先级、判断不了就问用户。插件页要关掉哪一个由你决定。
|
|
144
|
+
|
|
145
|
+
**诚实边界**:这条策略是**提示词层面的约束**(软约束);只读本身由 dbhub 在插件内**硬拒绝**。绕开插件的 shell 级直连不受插件管制,策略明确禁止了这条路,但它靠模型遵守,不是硬拦截。
|
|
146
|
+
|
|
84
147
|
## 配置页
|
|
85
148
|
|
|
86
149
|
<details>
|
|
@@ -90,19 +153,32 @@ AI:…(返回查询结果)
|
|
|
90
153
|
|
|
91
154
|
</details>
|
|
92
155
|
|
|
93
|
-
|
|
94
|
-
|
|
156
|
+
同一套组件提供**三种布局**,按承载位与窗口宽度自动切换(新界面需要插件 5.2.0+ 且 **DSH 0.2.1+**;DSH 0.1.x 上保持旧版布局与行为,见本节末尾):
|
|
157
|
+
|
|
158
|
+
| 布局 | 进入方式 | 形态 |
|
|
159
|
+
| --- | --- | --- |
|
|
160
|
+
| 弹窗模式 | **设置 → DBHub 数据库工具** | 窄列弹窗,密度与旧版一致,设置收在状态行的「设置」折叠里 |
|
|
161
|
+
| 宽屏模式 | 左侧菜单的 **DBHub** 入口 / 插件页该行的「配置」 | 整页宽列,页头带版本与升级入口,设置行直接展开 |
|
|
162
|
+
| 小屏模式 | 手机浏览器,宽度 < ~700px | 纵向堆叠的紧凑布局,控件按触摸尺寸 |
|
|
163
|
+
|
|
164
|
+
**页头:版本与升级入口**:标题是插件名,紧跟当前版本(灰色小字);有更新时右侧出现一行低调的「**↑ 可升级到 <latest>**」文字链接,**点开才展开**更新说明——里面是 `dsh-dbhub-live@<latest>`(点击复制)、按部署方式给的更新命令 / 步骤,以及更新说明链接;「↻」按钮随时手动检查一次。打开页面时也会自动检查(有节流)。检查以 npm registry 为主、GitHub Releases 为兜底。**更新是中性提示,不会用报错红。**
|
|
165
|
+
|
|
166
|
+
- **状态行**:只显示「运行中 / 已停用 · N 个连接」。工具数量、一次性执行模式、dbhub 版本这类实现细节收进页面底部的「ⓘ 说明与技术详情」折叠区,默认不展开。
|
|
167
|
+
- **连接列表**:按工作区组织。所有工作区都只有一个环境时用平铺卡片;任一工作区有多个环境时按工作区分组折叠(点组头展开,默认展开最近使用的那个)。每个连接只占一行:环境名 · 类型 / 主机 / 端口 / **库名** · **只读开关** · `source` 句柄(点它即复制) · 测试 / 修改 / 删除。窄窗口下先截断主机端口,**库名始终可见**。
|
|
168
|
+
- **设置区(DSH 主体样式,刻意弱化)**:宽屏把四项收成**一行紧凑设置条**——`插件设置 · 启用插件[启用] · 侧边栏入口[显示] · 访问策略[开启] · 自动更新[7]天[保存] · ⓘ说明`;弹窗与手机是紧凑设置行。字号与开关都收小,让**连接列表**成为页面主体。控件用 DSH 自己的开关(跟随主题 / 皮肤,带汉字状态词);解释性长文字都在「ⓘ 说明与技术详情」里。
|
|
169
|
+
- **只读开关(三种布局都在外面)**:每条连接行的数据源旁边就是该环境的「只读」小开关,点一下即改(开锁图标 + 「可写」= 可写;闭锁图标 + 「只读」= 已只读),不必打开编辑表单;弹窗 / 手机同样可用。编辑表单里的勾选也保留,两处是同一个状态。**连接串本身不再带锁形图标**——过去容易被误读成"需要密码",也和只读锁冲突。
|
|
95
170
|
- **增删改**:行内 ✏ 改连接串或环境名;「+ 添加连接」支持中文环境名。**同名环境保存前会先问「是否覆盖」**,取消则一个字都不写。
|
|
96
171
|
- **连接测试**:按该环境**真正会被使用的有效连接**(含只读 / 隧道)执行 `SELECT 1`,测试中显示已耗时。结果是一次性反馈,不持久化、不改变连接状态。
|
|
97
|
-
- **设置条**(⚙ 设置):自动更新间隔;「在侧边栏显示入口」开关。
|
|
98
172
|
|
|
99
173
|
**「在侧边栏显示入口」不是禁用插件**:关掉它只是隐藏左侧栏的快捷入口,插件照常工作、模型照常可以查询;想整体停用才用「禁用」(禁用后入口一律隐藏)。无论哪种状态,**设置页与插件页那行的「配置」始终能进**,随时可以撤销。
|
|
100
174
|
|
|
175
|
+
**DSH 0.1.x 的兼容路径**:页头版本 / 升级提示、宽屏整页、行内只读开关与开关样式的设置区都只在 **DSH 0.2.1+**(含预发布版)渲染;0.1.x 上插件保持原有布局与行为,**不显示升级提示**——这是刻意保留的,不是缺陷。
|
|
176
|
+
|
|
101
177
|
## 🔒 只读模式与 SSH 隧道
|
|
102
178
|
|
|
103
179
|
两项都是**按环境**设置的连接选项,由 dbhub 原生能力执行。开启后,该环境的每次执行改用一份**临时生成的 dbhub 配置**(文件里只有 `${…}` 占位符、不含任何密码,真值只经子进程环境传入),用完即删;其余环境不受影响。
|
|
104
180
|
|
|
105
|
-
|
|
181
|
+
**只读模式**:三种布局里,连接行数据源旁都有一个「只读」开关,点一下即改(也可以打开 ✏ 在编辑表单里勾选;模型也能为某环境开启)。开启后 dbhub 只放行只读语句(MySQL 实测为 `select/with/explain/show/describe/desc`),写操作直接返回 `READONLY_VIOLATION`;对象搜索照常可用。**关闭只读只能由你在配置页操作**——模型尝试关闭会被拒绝。只读环境的环境名后会多一个「只读」小标。
|
|
106
182
|
|
|
107
183
|
**SSH 隧道**(手动配置,适用于库在跳板机后面的场景):
|
|
108
184
|
|
|
@@ -136,14 +212,20 @@ AI:…(返回查询结果)
|
|
|
136
212
|
~/.dsh/storages/dsh-dbhub-live/
|
|
137
213
|
```
|
|
138
214
|
|
|
139
|
-
按 `DSH_HOME` 实例隔离,同一实例的多个 profile 共享(与 dsh 自身 `workspace.json` 同一约定)。连接按「工作区 ×
|
|
215
|
+
按 `DSH_HOME` 实例隔离,同一实例的多个 profile 共享(与 dsh 自身 `workspace.json` 同一约定)。连接按「工作区 × 环境」存储;旧格式与手改遗留会在启动时自动清洗并一次性迁移,运行目录被误删或写入被拦截时不会崩溃。**没有常驻进程、没有共享配置文件**,同机多实例并发运行互不干扰。**升级、重装或卸载插件都不会动这里**——包括桌面端「卸载后重装最新版」的升级方式:连接、只读 / 隧道设置与凭据都原样保留。
|
|
140
216
|
|
|
141
217
|
## 卸载
|
|
142
218
|
|
|
143
219
|
```bash
|
|
220
|
+
# web 端
|
|
144
221
|
dsh plugin --profile web remove dsh-dbhub-live
|
|
222
|
+
|
|
223
|
+
# 桌面端
|
|
224
|
+
dsh plugin --profile desktop remove dsh-dbhub-live
|
|
145
225
|
```
|
|
146
226
|
|
|
227
|
+
桌面端也可以在 **左侧菜单 → 插件** 页里直接卸载。卸载不会删除连接与凭据(见「数据位置」);需要彻底清空时手动删除 `~/.dsh/storages/dsh-dbhub-live`。
|
|
228
|
+
|
|
147
229
|
## 故障排查
|
|
148
230
|
|
|
149
231
|
| 现象 | 处理 |
|
|
@@ -155,7 +237,10 @@ dsh plugin --profile web remove dsh-dbhub-live
|
|
|
155
237
|
| 开启只读后写操作报 `READONLY_VIOLATION` | 不是故障,是只读在生效。需要写入时在配置页取消该环境的「只读模式」(模型关不掉)。 |
|
|
156
238
|
| 只读 / SSH 控件是灰的,或提示 dbhub 版本过旧 | 两项都需要 dbhub 1.4.0+:升级 dbhub,或删除 `~/.dsh/storages/dsh-dbhub-live` 让插件自动装一个满足要求的版本。 |
|
|
157
239
|
| 连接测试失败,看不出原因 | 读提示的**末尾**(诊断给的是 dbhub 输出的尾部,会标出【SSH 层】/【数据库层】/【插件层】)。**报【数据库层】就说明隧道已经通了**;有隧道时先点「测试 SSH 隧道」把 SSH 层单独验一遍。 |
|
|
158
|
-
| 看不到配置页 |
|
|
240
|
+
| 看不到配置页 | 确认插件已安装:web 端重启过 `dsh web`;桌面端在「插件」页该行点「配置」,或从左侧菜单的 DBHub 入口进。配置页只在 Web / 桌面界面显示,终端环境下不影响工具使用。 |
|
|
241
|
+
| 升级到新版本后仍是旧界面 | 新界面需要 **DSH 0.2.1+**(含其预发布版)且插件 5.2.0+;升级 dsh 后重启。DSH 0.1.x 上插件有意保持旧布局与行为,也不显示升级提示。 |
|
|
242
|
+
| 页头没有出现「升级到 …」提示 | 可能已是最新版本,或这次检查没连上 npm registry / GitHub Releases;点「检查更新」重试即可。检查失败只是提示,不影响插件功能。 |
|
|
243
|
+
| 桌面端怎么升级 | 在 **左侧菜单 → 插件** 页卸载后重装最新版本;连接与凭据在 `~/.dsh/storages/dsh-dbhub-live`,重装后仍在。 |
|
|
159
244
|
| 升级 dsh 后提示插件与本版不兼容 | 升级插件到 5.0.0+(同时支持 0.1.x 与 0.2.x);用 `allow-version` 强行豁免没有意义。 |
|
|
160
245
|
| 不希望自动更新 dbhub | 配置页「自动更新间隔(天)」填 `0` 保存,或设环境变量 `DSH_DBHUB_UPDATE_DAYS=0`。 |
|
|
161
246
|
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# 架构理由与踩坑记录(按需加载)
|
|
2
|
+
|
|
3
|
+
> AGENTS.md 只记**结论**;这里记**原因**——每条红线的由来、当时踩到的坑、以及"为什么不能那样改"的判断依据。
|
|
4
|
+
> 改红线或质疑红线前读对应章节。操作步骤见 [DEVELOPMENT.md](DEVELOPMENT.md) / [CLIENT.md](CLIENT.md) / [RELEASE.md](RELEASE.md)。
|
|
5
|
+
|
|
6
|
+
## 零知识边界
|
|
7
|
+
|
|
8
|
+
- 模型上下文就是泄露面:任何进 context 的字符串都会被摘要、日志和后续轮次复制。所以规则不是"少给"而是"永不给"——工具参数不接受 DSN(模型传 DSN 等于把密码写进对话),输出一律经 `connLabel` / `scrubSecrets`。
|
|
9
|
+
- dbhub 的启动横幅**只把密码掩成 `****`,用户名原样打印**;而连接测试的诊断文本正是这段输出。所以清洗必须折叠任意 URL 形态连接串的整个 userinfo(`://user:pass@`、`://user@` → `://****:****@`),只掩密码不够。
|
|
10
|
+
- 仓库被视为公开分发面:这些真实值曾随 npm 包与公开仓库分发过一次,公开即视为泄露、无法追回(详见 [DESENSITIZE.md](DESENSITIZE.md))。
|
|
11
|
+
|
|
12
|
+
## 一次性进程的理由
|
|
13
|
+
|
|
14
|
+
- 常驻 dbhub 服务器会带来一整套生命周期问题:端口/stdio 归属、配置变更重启、指纹与 mtime 监听、空闲回收、孤儿进程、多实例互杀——5.0 之前这些都真实出现过。最终选择"每次调用一条进程":天然并发隔离、一条进程挂只坏它自己、多实例无共享状态、没有常驻资源可泄漏。
|
|
15
|
+
- 代价是每次的启动延迟(spawn + initialize),换来的是可预测性。**不要以"优化启动"为名把常驻服务装回来。**
|
|
16
|
+
|
|
17
|
+
## 一次性TOML的由来
|
|
18
|
+
|
|
19
|
+
- `--dsn` 与 `--config` 互斥,而 dbhub 只有 TOML 方言能表达环境级只读(`[[tools]] readonly`)与 SSH 隧道(`ssh_*`)。所以只有"需要这两个特性"的环境走临时 TOML,其余**逐字节保持** `--dsn`(历史行为,密码在 argv)。
|
|
20
|
+
- 三个踩过的坑:
|
|
21
|
+
1. 秘密不能落文件 → 文件只写 `${DSH_DBHUB_SEC_*}` 占位符,真值走子进程 env。**dbhub 取不到变量时不报错**,会把 `${VAR}` 原样留在 DSN 里(于是连了一个字面量叫 `${VAR}` 的目标,或出现"神秘失败")——所以"文本引用的变量集合 == env 键集合"是硬断言。
|
|
22
|
+
2. `[[tools]]` 是**白名单不是补丁**:只要出现任意一条,dbhub 就不再自动挂 `execute_sql` + `search_objects`。只写一条 read_only 会让该环境的 `search_objects` 直接消失(`Tool search_objects not found`)。
|
|
23
|
+
3. source 级 `read_only` 写法会被**静默忽略**,比报错危险得多 → 绝不生成未实测的旧写法。1.4.0 是实测版本,`< 1.0.0` 明确拒绝。
|
|
24
|
+
- Windows 上 dbhub 会 watch 这个临时文件,删除可能 EBUSY → `finally` 尽力删 + boot 时 `sweepTempToml()` 清残留。
|
|
25
|
+
|
|
26
|
+
## 环境选项与执行预算
|
|
27
|
+
|
|
28
|
+
- 选项**没有版本号也没有迁移函数**是刻意的:`normalizeStore` 保留未知字段,给 env 条目加可选字段不需要迁移;旧文件读回来就是"无只读、无隧道"。别为了"规范"加迁移。
|
|
29
|
+
- `setWorkspaceEnv` 的 opts **缺省必须保留**既有选项:`dbhub_configure` 只更新 DSN 的场景下,若默认清空就会把用户的安全开关静默关掉——这是"只读/隧道莫名丢失"的根因。
|
|
30
|
+
- 安全不对称必须在**工具路径**拦截而不是 store:模型只能收窄不能放宽,但浏览器必须能自由关,否则用户永远关不掉自己开的只读。
|
|
31
|
+
- 预算与看门狗的三角关系:客户端看门狗必须**严格大于**宿主探测预算,否则客户端先放弃、界面报"测试超时",而宿主那条 dbhub 还在跑;宿主再加 +500ms 兜底,处理 spawn 本身永不 settle 的情况。三个数字必须一起改,`test/adhoc-toml.test.mjs` 会断言。
|
|
32
|
+
|
|
33
|
+
## envSlug事故
|
|
34
|
+
|
|
35
|
+
- 早期实现把非 ASCII 环境名统一 slug 化成一个值,`线上` 与 `测试` 拿到同一个 source 句柄 → 解析时**静默查错库**(模型以为在测环境,实际打线上)。现在:`default` 裸值、纯 ASCII 保留原 slug(既有 source 不变)、非 ASCII 取 `env-<shortHash>`。这是回归红线,不是风格问题。
|
|
36
|
+
|
|
37
|
+
## 状态通道与inject根因
|
|
38
|
+
|
|
39
|
+
> **为什么不能改回 inject(5.0 移植的根因)**:dsh 0.1.7 用 Config 表单取代了 settings 命名空间,0.2.x 又删掉浏览器侧 `settingsScope`。旧客户端 `inject: ['slots', 'settingsScope']` 在 0.2.x 上永远等不到服务 → 整个浏览器半区 pending、**无任何报错**,表现就是「配置页 / 侧边栏 / 插件页卡片静默消失」。所以这一层必须做成运行时探测 + 双实现(`legacyFace` / `httpFace`),而不是声明式依赖。
|
|
40
|
+
|
|
41
|
+
- 第二个静默失败面:**注入回调是独立作用域**。在回调里引用 `apply()` 的局部变量会 ReferenceError,而错误发生在发布链路上——页面只剩静态值、无任何可见报错。需要的服务必须 `ctx.get(...)` 就地获取。
|
|
42
|
+
- 两条通道都发布同一个 view 是刻意的:客户端只写一份渲染逻辑,通道差异收敛在 `legacyFace` / `httpFace` 两个适配器里。
|
|
43
|
+
|
|
44
|
+
## 诊断为什么取尾部
|
|
45
|
+
|
|
46
|
+
- dbhub 失败时致命行在输出末尾(前面是启动横幅与重试日志),取开头只能得到 `connecting…`。所以 `diagnosticTail` 取尾部 600 字符、丢 `at …` 栈帧与折行残片、按行边界截断(否则会截出半行 JSON/半个错误)。
|
|
47
|
+
- 分层前缀的意义:SSH 层与数据库层的可诊断性不同——只有**独立的 SSH 探测**能证明"隧道起来了";反向不成立,所以 db 层失败的措辞必须谨慎,不能写成"隧道断了"。
|
|
48
|
+
|
|
49
|
+
## 即时回推与扫描单飞
|
|
50
|
+
|
|
51
|
+
- `collectSources` 每次都要重扫全部工作区(无持久化 `default` 的工作区各起一次 `mise env`),一次写入原本要等 1–2s。更糟的是**并发扫描互相覆盖**:探针回执触发的扫描可能在写入前开始、写入后结束,把新行刷掉——表现就是"立刻出现又消失"。
|
|
52
|
+
- 结论:写入路径返回本次补丁并 `publishFast` 同步镜像;探针只镜像不扫描;扫描单飞并重放扫描期间到达的补丁;`rename` 补丁必须幂等(否则重放会丢行)。一次点击 = 1 次扫描 + 2 次纯内存镜像。
|
|
53
|
+
|
|
54
|
+
## 自动发现的代价与unref教训
|
|
55
|
+
|
|
56
|
+
- `mise env` 探测没有总超时会出事:曾有一个不退出的 `mise env` 让整轮扫描永不返回,而 `dbhub_list_sources` 正走这条同步路径,模型侧看到 `Interrupted`。所以每次探测必须有总超时(`graceMs` 只是 SIGTERM→SIGKILL 宽限,**不是超时**),结果按 TTL 缓存,工作区之间并发。
|
|
57
|
+
- **预算计时器绝不 `unref()`**:unref 计时器在"它是唯一待办"时不触发——事件循环排空、进程先退,超时形同虚设。该缺陷**只在 Linux CI 暴露**(整文件 cancelled),本地 Windows 会侥幸通过:本地全绿不能当发布依据。
|
|
58
|
+
|
|
59
|
+
## 布局取舍
|
|
60
|
+
|
|
61
|
+
- 行内只放图标、来源不做徽章、库名不截断,三条来自同一约束:每个连接只占一行,宽度是稀缺资源。文字按钮吃掉半行;"来源"徽章几乎每行相同却最抢眼;库名被截断是最高频的抱怨。
|
|
62
|
+
- 三面布局的两个阈值(700 / 720):实测出现过 710px 视口既不算手机(>= 700)也不够宽(< 720)的**空档**,布局判定落空。两阈值之间的窄桌面列必须走紧凑设置条,不能退回竖排。
|
|
63
|
+
- 现代面与 legacy 面必须能同时存在:`render-check` 的旧断言写死了 0.1.x 的 DOM,新界面只能挂在 `dshModern` 下;否则一次"统一界面"就会让旧线渲染异常。
|
|
64
|
+
|
|
65
|
+
## 覆盖门为什么先问
|
|
66
|
+
|
|
67
|
+
- `setWorkspaceEnv` 是**无条件写入**:新增或改名落到已存在的环境会静默替换原连接,而客户端无法回滚。所以写入前必须比较,命中就弹确认卡;比较前必须过 `normalizeEnvForCompare`(镜像宿主 `normalizeEnvName`),否则「prod 」与「prod」这种同键异写会漏判。取消 → 零 op 且保留表单内容。
|
|
68
|
+
|
|
69
|
+
## 脱敏的不可逆性
|
|
70
|
+
|
|
71
|
+
- 详见 [DESENSITIZE.md](DESENSITIZE.md)。一句话:真实值曾随 npm 包与公开仓库分发过一次,公开即无法追回;所以门禁是硬门,示例主机只用回环/RFC 5737,示例密码只用 `CHANGE_ME`,任何人不得把本机绝对路径写进受版本控制的文件。
|
|
72
|
+
|
|
73
|
+
## 版本门与更新检查
|
|
74
|
+
|
|
75
|
+
- `dshModern` 门(>= 0.2.1,含预发布)不是"只有新版本测过",而是"新界面依赖的 slot/DOM 能力在这个版本才稳定"。运行版本解析不到时回退为 desktop=true / web=false——桌面端总是新版、旧 web 线保持 legacy,比猜一个值安全。
|
|
76
|
+
- 更新检查**绝不抛错**:它只是页头一行提示,失败必须只体现为 `error` 字段,不得影响插件任何功能。
|
|
77
|
+
|
|
78
|
+
## 模块地图
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
lib/
|
|
82
|
+
index.mjs 入口:name/inject/apply、Config(volatile)、发布核心 createHostCore(walk/row-mirror/runOp/view)、
|
|
83
|
+
双通道接线(0.1.x settings 命名空间 / connection.fetch HTTP 桥)、settings 表单策略与选项写回、configOp 命令处理
|
|
84
|
+
meta.mjs 插件版本(读 package.json)、DSH 运行时版本探测、semver 比较、dshModern 门
|
|
85
|
+
update.mjs 最新版本检查:npm registry 为主 → GitHub Releases 兜底;内存节流、force、绝不抛错
|
|
86
|
+
bridge.mjs /api/dsh-dbhub-live 四条 exact Fetch 路由的请求/响应编解码(纯函数)
|
|
87
|
+
config.mjs 路径与原子持久化(store/runtime/prefs)、DSN 解析、工作区发现、环境选项(readOnly/ssh 归一化、默认密钥)、
|
|
88
|
+
零知识助手(describeConn/connLabel/scrubSecrets)、configure 决策纯函数(decideConfigureStep/argsChangedEndpoint/emptyUserDenied)
|
|
89
|
+
i18n.mjs 宿主侧文案表与插值
|
|
90
|
+
state.mjs 运行时状态机 enabled/phase/toolCount/lastError/mode + 订阅发布
|
|
91
|
+
options.mjs 部署开关:updateIntervalDays / showSidebarEntry / announceAccessPolicy;层叠 Config > prefs.json > 0.1.x 设置文档 > 环境变量 > 内置默认
|
|
92
|
+
runtime.mjs dbhub 可执行文件发现、按需自动安装、定期自动更新
|
|
93
|
+
capability.mjs 上游能力探测(文件级,不 spawn):[[tools]] readonly 与 ssh_* 需 1.4.0+
|
|
94
|
+
toml.mjs 一次性 TOML 生成器 buildDbhubToml/writeTempToml/removeTempToml/sweepTempToml(文本绝不含秘密)
|
|
95
|
+
mcp.mjs MCP JSON-RPC 客户端、工具注册表、来源发现 collectSources/resolveSource、摘要缓存、测试快路径 resolveTestDsn
|
|
96
|
+
adhoc.mjs 唯一执行引擎:一次性 dbhub 进程(描述符 {dsn,ro,ssh})、--dsn 或临时 TOML、stderr 清洗、
|
|
97
|
+
probeConnection、probeSshTunnel、diagnosticTail/DIAG_TAIL_MAX=600/failureLayerOf
|
|
98
|
+
collect.mjs 授权扫描项目配置文件(mise/.env)提取 DSN 候选,含 askUser 桥接
|
|
99
|
+
tools.mjs 4 个工具的定义与注册;configure 探连优先
|
|
100
|
+
policy.mjs 模型侧访问策略:唯一的 system prompt 段(order 8900)
|
|
101
|
+
client.js Web 半(手写 lazy-CJS bundle,无构建):settings.section + 侧边栏面板 + plugins.row.config(summary/page)
|
|
102
|
+
test/ node:test 单测(纯逻辑 + bridge/客户端契约 + 零知识泄漏门)
|
|
103
|
+
scripts/ desensitize.config.mjs(槽位表=单一事实源) / desensitize-check.mjs / docs-check.mjs / render-check.mjs / release-preflight.mjs
|
|
104
|
+
release-test/ 版本矩阵实测:matrix.json(唯一声明) / run.mjs / support-matrix.mjs / mise.toml
|
|
105
|
+
.github/ workflows/quality.yml(CI gate) + release-matrix.yml(定时 support:check)
|
|
106
|
+
doc/ REQUIREMENTS.md / ARCHITECTURE.md / DEVELOPMENT.md / CLIENT.md / RELEASE.md / DESENSITIZE.md / SUPPORT-MATRIX.md / images/
|
|
107
|
+
+ 本地文档(PLAN-*、implementation-notes、RELEASE-NOTES-*,均 gitignore 排除)
|
|
108
|
+
```
|