dsh-ssh-vault 0.0.0-stage → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +404 -0
- package/CHANGELOG.zh-CN.md +352 -0
- package/CONTRIBUTING.md +179 -0
- package/CONTRIBUTING.zh-CN.md +167 -0
- package/LICENSE +21 -0
- package/README.md +452 -2
- package/README.zh-CN.md +450 -0
- package/SECURITY.md +42 -0
- package/SECURITY.zh-CN.md +38 -0
- package/assets/banner.png +0 -0
- package/assets/icon-180.png +0 -0
- package/assets/screenshot-1.png +0 -0
- package/client.js +1134 -0
- package/cordis.patch.yml +4 -0
- package/icon.svg +11 -0
- package/index.js +1180 -0
- package/lib/background.js +65 -0
- package/lib/i18n.js +589 -0
- package/lib/locales/ssh.js +130 -0
- package/lib/platform.js +68 -0
- package/lib/ssh.js +723 -0
- package/lib/vault-api.js +417 -0
- package/lib/vault.js +397 -0
- package/locale/en.json +4 -0
- package/locale/zh.json +4 -0
- package/package.json +75 -4
- package/scripts/dhcp-reserve-kali.ps1 +81 -0
- package/scripts/make-market-icon.py +63 -0
- package/scripts/set-secret.mjs +127 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
**English** | [简体中文](CHANGELOG.zh-CN.md)
|
|
4
|
+
|
|
5
|
+
All notable changes to this project are documented here. The format follows
|
|
6
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project adheres to
|
|
7
|
+
[Semantic Versioning](https://semver.org/).
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
## [2.0.0] - 2026-10-25
|
|
12
|
+
|
|
13
|
+
### Removed
|
|
14
|
+
|
|
15
|
+
- **Linux and macOS support is gone — by declaration and by code.** The vault data key relies on
|
|
16
|
+
Windows DPAPI and the `SSH_ASKPASS` helper is a Windows `.cmd`; off Windows the previous code
|
|
17
|
+
silently wrote the data key to `key.json` as plaintext. That is a security downgrade, not support.
|
|
18
|
+
The package now declares `os: ["win32"]`, so installation is rejected elsewhere, and both
|
|
19
|
+
`apply()` and the `Vault` constructor refuse to run.
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- **Everything says Windows only**: `package.json` description and `meta`, `locale/{en,zh}.json`,
|
|
24
|
+
the marketplace entry, and both READMEs (overview, requirements, limitations, FAQ).
|
|
25
|
+
- The new `lib/platform.js` owns the supported-platform list, friendly platform names, and the
|
|
26
|
+
refusal message; `test/platform.mjs` pins the declaration to `package.json`.
|
|
27
|
+
- `test/host-apply.mjs` exercises the refusal path when the suite runs on a non-Windows host.
|
|
28
|
+
- Regression cover for the settings-route fence: the settings-API suite checks 401/403 bodies and
|
|
29
|
+
no-store headers, that rejection happens **before** method and body handling, that a rejected
|
|
30
|
+
request never writes to the vault, and that the integration wiring passes the host `connection`
|
|
31
|
+
service through (`test/vault-api.mjs`, `test/host-apply.mjs`). 321 tests total.
|
|
32
|
+
- The marketplace entry points at the v2.0.0 tarball.
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
|
|
36
|
+
- **The README promised Linux/macOS while the implementation could only degrade there.** The
|
|
37
|
+
documentation/code mismatch is closed in the honest direction: no plaintext fallback exists on
|
|
38
|
+
any platform, and unsupported platforms fail loudly at install and at load.
|
|
39
|
+
- **The settings routes now cross the Host Connection trust fence.** Every `/ssh-vault/*` request
|
|
40
|
+
first asks `ctx.connection.requestRejection(req)` — the same Host/Origin check and browser-
|
|
41
|
+
session authentication used by `/api` — before it looks at the method, the body or the vault.
|
|
42
|
+
Rejected requests get `401`/`403` and cannot read host data, trigger a probe, or even learn
|
|
43
|
+
whether an action exists. A vault-and-credential endpoint should not rely solely on the
|
|
44
|
+
surrounding server, as the review pointed out.
|
|
45
|
+
- **Re-uploading a private key for an existing host no longer fails on Windows.** The previous
|
|
46
|
+
upload's copy is hardened with `icacls` into a user-read-only ACL, which also denies the write
|
|
47
|
+
needed to overwrite it. The save path now resets the file's ACL (`icacls /reset` on Windows,
|
|
48
|
+
chmod 0600 elsewhere) before rewriting, so the second upload lands.
|
|
49
|
+
|
|
50
|
+
## [1.15.0] - 2026-10-24
|
|
51
|
+
|
|
52
|
+
### Added
|
|
53
|
+
|
|
54
|
+
- **The plugin follows the DSH interface language.** With DSH switched to English, the
|
|
55
|
+
Settings page, the `/` menu entries, the in-conversation SSH cards, `/hosts` results,
|
|
56
|
+
transport diagnostics and Settings-API errors are English too; switching back changes them
|
|
57
|
+
immediately, with no page reload or restart.
|
|
58
|
+
- The Client half registers an `ssh-vault` dictionary with the host's locale service, so
|
|
59
|
+
slot-rendered copy tracks the active locale.
|
|
60
|
+
- The Host half reads `locale.preference` from the host settings document (the value the
|
|
61
|
+
language picker persists) and follows `settings/document-updated`; `Accept-Language` is
|
|
62
|
+
used only when no explicit preference exists.
|
|
63
|
+
- Model-facing definitions — tool names, descriptions and parameter schemas — stay in
|
|
64
|
+
English, because they are part of the model interface rather than the UI.
|
|
65
|
+
- `test/i18n.mjs`, `test/host-apply.mjs` and `test/client-smoke.mjs` cover dictionary
|
|
66
|
+
completeness (placeholder parity, no untranslated English entries), the host activation and
|
|
67
|
+
locale-switch path, and the client slot/dictionary wiring.
|
|
68
|
+
|
|
69
|
+
### Changed
|
|
70
|
+
|
|
71
|
+
- Host-side copy moved into `lib/i18n.js` plus `lib/locales/ssh.js`; the Chinese values are
|
|
72
|
+
byte-for-byte the previous strings, so existing behaviour and tests are unchanged.
|
|
73
|
+
- **`/hosts` is re-registered only when the interface language changes.** The command's
|
|
74
|
+
`description` and `input.hint` are static strings captured at registration; timers never
|
|
75
|
+
touch the definition (that was the historical cause of a composer losing its command
|
|
76
|
+
context mid-typing), but a locale switch is a deliberate Settings action with no command
|
|
77
|
+
being typed, so replacing the definition there is safe.
|
|
78
|
+
- The `/hosts` hint now says that pressing Enter again lists the hosts, which makes the
|
|
79
|
+
two-step menu-pick behaviour explicit.
|
|
80
|
+
|
|
81
|
+
### Fixed
|
|
82
|
+
|
|
83
|
+
- **A bare `/hosts` no longer appears to hang.** On a cold health cache the command used to
|
|
84
|
+
probe every host sequentially with the 15s settings timeout, so five unreachable hosts meant
|
|
85
|
+
up to 75 seconds of no visible result — and the result then landed above a message the user
|
|
86
|
+
had sent in the meantime. Probes now run in parallel with a 4s budget for the list form.
|
|
87
|
+
- **`/hosts` results are visible before the first message.** DSH classifies a transcript
|
|
88
|
+
containing only command rows as an inactive view, so in a brand-new conversation the command
|
|
89
|
+
ran and logged its result but nothing rendered; the cards only appeared (above the new
|
|
90
|
+
message) once the first prompt was sent. The plugin now mirrors those command nodes —
|
|
91
|
+
including the running state — in the composer dock while the session is still blank, and
|
|
92
|
+
steps aside as soon as the transcript has real content.
|
|
93
|
+
|
|
94
|
+
## [1.14.2] - 2026-10-19
|
|
95
|
+
|
|
96
|
+
### Fixed
|
|
97
|
+
|
|
98
|
+
- **PowerShell error output is plain text again.** -OutputFormat Text governs stdout only:
|
|
99
|
+
powershell.exe still serialized the error stream as CLIXML onto stderr and echoed the
|
|
100
|
+
entire script back as error context, burying real messages under XML. The script now merges
|
|
101
|
+
the error stream into stdout itself and flattens each ErrorRecord to a single
|
|
102
|
+
[error] … line, with Out-String -Stream keeping object and table output intact.
|
|
103
|
+
|
|
104
|
+
## [1.14.1] - 2026-10-19
|
|
105
|
+
|
|
106
|
+
### Fixed
|
|
107
|
+
|
|
108
|
+
- **PowerShell no longer floods stderr with CLIXML.** Once the script moved to
|
|
109
|
+
`-EncodedCommand`, PowerShell serialized its progress stream into CLIXML and wrote that to
|
|
110
|
+
stderr, burying real errors under a wall of XML. The script now sets
|
|
111
|
+
`\Continue = 'SilentlyContinue'` and the invocation passes -OutputFormat Text.
|
|
112
|
+
|
|
113
|
+
## [1.14.0] - 2026-10-19
|
|
114
|
+
|
|
115
|
+
### Fixed
|
|
116
|
+
|
|
117
|
+
- **Multi-line PowerShell no longer fails silently.** `-Command -` reads stdin line by line,
|
|
118
|
+
so a here-string (`@'…'@`) or a `foreach (…) {…}` block was split apart mid-parse. The
|
|
119
|
+
resulting syntax errors did not come back as a non-zero exit, so the caller was told the
|
|
120
|
+
command had run when it had not. PowerShell targets now receive the whole script through
|
|
121
|
+
`-EncodedCommand` (Base64 UTF-16LE) and are parsed in one pass; `[Console]::OutputEncoding`
|
|
122
|
+
is fixed at the head of the script so non-ASCII output stays readable.
|
|
123
|
+
- **`ssh_transfer` no longer misattributes a broken connection.** The path hint fired even
|
|
124
|
+
when the transfer died on a connection reset, sending diagnosis toward the wrong layer.
|
|
125
|
+
- **Account lock is now a named cause.** Windows OpenSSH disconnects a locked account outright
|
|
126
|
+
instead of returning `Permission denied`, so "port open, banner fine, still cannot connect"
|
|
127
|
+
previously pointed only at firewalls. It now names account lock as a candidate and says how
|
|
128
|
+
to check it (`net user` on Windows, `faillock` on Linux).
|
|
129
|
+
|
|
130
|
+
### Added
|
|
131
|
+
|
|
132
|
+
- **Connections to the same host are serialised.** Every call opens a fresh SSH connection; a
|
|
133
|
+
burst of them, especially concurrent `scp`, trips sshd's connection limits and accumulates
|
|
134
|
+
failed-auth counters toward an account lock. Background jobs stay outside the queue so a
|
|
135
|
+
long task cannot block that host for everything else.
|
|
136
|
+
- `ssh_transfer` creates the local parent directory before a download.
|
|
137
|
+
- A warning before commands that change account state or lockout policy, since locking the
|
|
138
|
+
management account also kills key-based login.
|
|
139
|
+
|
|
140
|
+
### Changed
|
|
141
|
+
|
|
142
|
+
- `shellArgv` takes the script and returns `-EncodedCommand` for PowerShell; POSIX and `cmd`
|
|
143
|
+
targets still receive their script over stdin.
|
|
144
|
+
|
|
145
|
+
## [1.13.0] - 2026-10-17
|
|
146
|
+
|
|
147
|
+
### Added
|
|
148
|
+
|
|
149
|
+
- **`/hosts` distinguishes commands from prose.** Text after the semicolon that reads as
|
|
150
|
+
natural language is no longer executed as shell; the command stops and hands the sentence
|
|
151
|
+
back to the conversation, because command output never reaches the model.
|
|
152
|
+
- `scripts/dhcp-reserve-kali.ps1`, an idempotent helper that pins a VM's MAC to a fixed
|
|
153
|
+
address in VMware's DHCP configuration.
|
|
154
|
+
|
|
155
|
+
### Changed
|
|
156
|
+
|
|
157
|
+
- **Documentation rewritten.** Both READMEs are now reference documents rather than a
|
|
158
|
+
narrative of the build-out, with badges, a Mermaid data-flow diagram, and sections for
|
|
159
|
+
architecture, extension points, lifecycle, limits and the security boundary.
|
|
160
|
+
- **English is the primary language for every top-level document.** `CHANGELOG`,
|
|
161
|
+
`CONTRIBUTING` and `SECURITY` used to carry Chinese in the unsuffixed `.md` with English in
|
|
162
|
+
an `.en.md`; all three now match the README convention — bare name is English, the
|
|
163
|
+
translation carries the `.zh-CN` suffix.
|
|
164
|
+
|
|
165
|
+
## [1.12.3] - 2026-10-17
|
|
166
|
+
|
|
167
|
+
### Fixed
|
|
168
|
+
|
|
169
|
+
- The section label in a `/hosts` card is centred, instead of lining up with a failure badge
|
|
170
|
+
on the right.
|
|
171
|
+
|
|
172
|
+
## [1.12.2] - 2026-10-17
|
|
173
|
+
|
|
174
|
+
### Fixed
|
|
175
|
+
|
|
176
|
+
- **Each `/hosts` card lights its own status.** Both cards previously read one flag derived
|
|
177
|
+
from the whole command, so a reachable host with a failing command turned the connectivity
|
|
178
|
+
card red as well.
|
|
179
|
+
|
|
180
|
+
## [1.12.1] - 2026-10-17
|
|
181
|
+
|
|
182
|
+
### Added
|
|
183
|
+
|
|
184
|
+
- `/hosts` output splits into two cards: reachability and command execution.
|
|
185
|
+
|
|
186
|
+
## [1.12.0] - 2026-10-17
|
|
187
|
+
|
|
188
|
+
### Added
|
|
189
|
+
|
|
190
|
+
- **The text after the semicolon is executed on every reachable host.** `/hosts kali; apt
|
|
191
|
+
update` probes kali and then runs the command there. A command starting with `sudo` primes
|
|
192
|
+
the sudo cache from the vault first, so a non-interactive session does not wait for a
|
|
193
|
+
password until the timeout.
|
|
194
|
+
|
|
195
|
+
## [1.11.1] - 2026-10-17
|
|
196
|
+
|
|
197
|
+
### Fixed
|
|
198
|
+
|
|
199
|
+
- The full-width comma `,` separates host aliases, alongside the ASCII one.
|
|
200
|
+
|
|
201
|
+
## [1.11.0] - 2026-10-17
|
|
202
|
+
|
|
203
|
+
### Added
|
|
204
|
+
|
|
205
|
+
- **A connection can be renamed from the settings form.** Credentials, private-key path,
|
|
206
|
+
note and tags move with it. The host writes the new record before removing the old one, so
|
|
207
|
+
a failure in between leaves a duplicate rather than a lost configuration.
|
|
208
|
+
|
|
209
|
+
## [1.10.1] - 2026-10-17
|
|
210
|
+
|
|
211
|
+
### Changed
|
|
212
|
+
|
|
213
|
+
- The `/hosts` output is plain text again, and a single dot in the card header carries the
|
|
214
|
+
outcome. Emoji circles duplicated what that dot already said, and read worse.
|
|
215
|
+
|
|
216
|
+
## [1.10.0] - 2026-10-17
|
|
217
|
+
|
|
218
|
+
### Added
|
|
219
|
+
|
|
220
|
+
- **`/hosts` has its own terminal row**, taken from the `conversation.chat.commandview` slot.
|
|
221
|
+
The generic command card folded its output into an unstyled `<pre>` and hid it behind a
|
|
222
|
+
disclosure.
|
|
223
|
+
- The full-width semicolon `;` ends the argument list, alongside the ASCII one.
|
|
224
|
+
|
|
225
|
+
## [1.9.6] - 2026-10-17
|
|
226
|
+
|
|
227
|
+
### Changed
|
|
228
|
+
|
|
229
|
+
- `/hosts` output uses coloured dots rather than check, cross and question marks, which read
|
|
230
|
+
as verdicts instead of status.
|
|
231
|
+
|
|
232
|
+
## [1.9.5] - 2026-10-17
|
|
233
|
+
|
|
234
|
+
### Fixed
|
|
235
|
+
|
|
236
|
+
- **Arguments are parsed as comma-separated aliases ending at a semicolon.** Splitting on
|
|
237
|
+
whitespace turned every word after the alias into a host lookup, so a trailing note
|
|
238
|
+
produced several failed lookups and repeated the same error.
|
|
239
|
+
- Unknown aliases are resolved against the vault first and reported once, instead of being
|
|
240
|
+
folded in with real connection failures.
|
|
241
|
+
|
|
242
|
+
## [1.9.4] - 2026-10-17
|
|
243
|
+
|
|
244
|
+
### Changed
|
|
245
|
+
|
|
246
|
+
- **The `/ssh` command is now `/hosts`.** The composer is a Lexical editor whose plain text
|
|
247
|
+
nodes are subject to browser spellcheck; `ssh` is not a dictionary word and got underlined,
|
|
248
|
+
while `hosts` is.
|
|
249
|
+
|
|
250
|
+
## [1.9.3] - 2026-10-17
|
|
251
|
+
|
|
252
|
+
### Fixed
|
|
253
|
+
|
|
254
|
+
- **The command is registered once and never re-registered.** Re-registering disposes the
|
|
255
|
+
current definition, and the composer holds it while the user types arguments — swapping it
|
|
256
|
+
out broke input (backspace stopped working) and needed a UI restart.
|
|
257
|
+
|
|
258
|
+
## [1.9.2] - 2026-10-17
|
|
259
|
+
|
|
260
|
+
### Fixed
|
|
261
|
+
|
|
262
|
+
- **The health dot follows every test.** The card's "Test connection" button updated only the
|
|
263
|
+
detail area and never the dot, so a successful test left it red; editing a connection did
|
|
264
|
+
not re-test it either, because the automatic sweep keyed off the alias list, which a change
|
|
265
|
+
of address does not alter.
|
|
266
|
+
|
|
267
|
+
## [1.9.1] - 2026-10-17
|
|
268
|
+
|
|
269
|
+
### Fixed
|
|
270
|
+
|
|
271
|
+
- **The settings probe times out at 15 seconds, not 8.** A probe really connects over SSH, and
|
|
272
|
+
a host that is up without a listening `sshd` burns the whole window in TCP connect.
|
|
273
|
+
- A timeout is reported as a timeout, naming the two likely causes (port closed, address
|
|
274
|
+
changed) instead of surfacing as a bare `(no output)` that looks like a plugin failure.
|
|
275
|
+
|
|
276
|
+
## [1.9.0] - 2026-10-17
|
|
277
|
+
|
|
278
|
+
### Added
|
|
279
|
+
|
|
280
|
+
- The `/ssh` input hint lists the hosts that answered the last health check, and running it
|
|
281
|
+
with no arguments prints the hosts split into online and offline.
|
|
282
|
+
|
|
283
|
+
## [1.8.0] - 2026-10-17
|
|
284
|
+
|
|
285
|
+
### Added
|
|
286
|
+
|
|
287
|
+
- **Each connection is probed when its card appears**, and the card carries a status dot:
|
|
288
|
+
grey before the check, yellow while it runs, green on success, red on failure. Checks run
|
|
289
|
+
serially so a batch of concurrent SSH connections cannot pile onto one unreachable host.
|
|
290
|
+
|
|
291
|
+
## [1.7.1] - 2026-10-17
|
|
292
|
+
|
|
293
|
+
### Fixed
|
|
294
|
+
|
|
295
|
+
- The terminal header shows the exit status. A non-zero remote exit is a normal return for
|
|
296
|
+
these tools rather than an error, so a failed command looked identical to a successful one.
|
|
297
|
+
|
|
298
|
+
## [1.7.0] - 2026-10-17
|
|
299
|
+
|
|
300
|
+
### Added
|
|
301
|
+
|
|
302
|
+
- **SSH tool calls render as a scrollable terminal in the conversation**, registered on
|
|
303
|
+
`tool.call.toolview` for `ssh_run`, `ssh_probe` and `ssh_transfer`. None of those key names
|
|
304
|
+
were occupied, so nothing shipped is shadowed.
|
|
305
|
+
|
|
306
|
+
## [1.6.9] - 2026-10-17
|
|
307
|
+
|
|
308
|
+
### Fixed
|
|
309
|
+
|
|
310
|
+
- Tool output falls back to a `console`-fenced code block. `presentCall` / `presentResult` —
|
|
311
|
+
the documented terminal-card hooks — turned out to have no consumer anywhere in the
|
|
312
|
+
installed tree, so they cannot be the sole presentation path.
|
|
313
|
+
|
|
314
|
+
## [1.6.8] - 2026-10-17
|
|
315
|
+
|
|
316
|
+
### Added
|
|
317
|
+
|
|
318
|
+
- `presentCall` / `presentResult` hooks on the three terminal-style tools. See 1.6.9 and
|
|
319
|
+
1.7.0: these hooks have no consumer in this DSH version, and real presentation arrived
|
|
320
|
+
through a slot.
|
|
321
|
+
|
|
322
|
+
## [1.6.7] - 2026-10-17
|
|
323
|
+
|
|
324
|
+
### Added
|
|
325
|
+
|
|
326
|
+
- **Uploaded private keys are restricted and pre-checked.** The browser inspects the chosen
|
|
327
|
+
file before uploading anything and rejects a public key, a PuTTY `.ppk`, a file without a
|
|
328
|
+
PEM header, or an implausibly large file. The host requires an actual PEM header instead of
|
|
329
|
+
merely containing the words `PRIVATE KEY`.
|
|
330
|
+
- The key form gained a passphrase field, for a key that is itself encrypted.
|
|
331
|
+
|
|
332
|
+
## [1.6.6] - 2026-10-17
|
|
333
|
+
|
|
334
|
+
### Fixed
|
|
335
|
+
|
|
336
|
+
- The result of "Open in file manager" is reported beside the button. The failure message used
|
|
337
|
+
to appear only at the top of the page, so pressing the button looked like it did nothing.
|
|
338
|
+
|
|
339
|
+
## [1.6.5] - 2026-10-17
|
|
340
|
+
|
|
341
|
+
### Fixed
|
|
342
|
+
|
|
343
|
+
- The edit form expands under its own card instead of at the top of the page, which used to
|
|
344
|
+
push the card being edited out of view.
|
|
345
|
+
|
|
346
|
+
## [1.6.4] - 2026-10-17
|
|
347
|
+
|
|
348
|
+
### Added
|
|
349
|
+
|
|
350
|
+
- The vault path sits on its own line with an "Open in file manager" button, backed by an
|
|
351
|
+
`openVault` route that accepts no path argument at all — it can only open the plugin's own
|
|
352
|
+
vault directory.
|
|
353
|
+
|
|
354
|
+
## [1.6.3] - 2026-10-17
|
|
355
|
+
|
|
356
|
+
### Fixed
|
|
357
|
+
|
|
358
|
+
- The vault metadata line no longer wraps at its full-width separators.
|
|
359
|
+
- The plugin version is read per request rather than cached, so a client-only change cannot
|
|
360
|
+
leave the displayed version one release behind.
|
|
361
|
+
|
|
362
|
+
## [1.6.2] - 2026-10-17
|
|
363
|
+
|
|
364
|
+
### Fixed
|
|
365
|
+
|
|
366
|
+
- **The settings route is registered at `/ssh-vault` without a trailing slash.**
|
|
367
|
+
`kind: 'prefix'` matches the registered path or that path plus a slash, so registering
|
|
368
|
+
`/ssh-vault/` meant `/ssh-vault/list` matched neither and every request fell through to the
|
|
369
|
+
fallback handler.
|
|
370
|
+
|
|
371
|
+
## [1.6.1] - 2026-10-17
|
|
372
|
+
|
|
373
|
+
### Fixed
|
|
374
|
+
|
|
375
|
+
- Secondary buttons use the host's own button tokens. The earlier version guessed at token
|
|
376
|
+
semantics and produced light-on-light buttons in the dark theme.
|
|
377
|
+
|
|
378
|
+
## [1.6.0] - 2026-10-17
|
|
379
|
+
|
|
380
|
+
### Added
|
|
381
|
+
|
|
382
|
+
- **Connection management in Settings**: list, add, edit and delete hosts, with password or
|
|
383
|
+
private-key authentication and a one-click connection test. A password entered there travels
|
|
384
|
+
in a same-origin POST body and never enters the session log.
|
|
385
|
+
- **The `/ssh` command**: list hosts, or probe one or several by alias.
|
|
386
|
+
- `test/vault-api.mjs`, pinning the settings API's validation, masking and response shape.
|
|
387
|
+
|
|
388
|
+
## [1.5.0] - 2026-10-16
|
|
389
|
+
|
|
390
|
+
### Added
|
|
391
|
+
|
|
392
|
+
- Encrypted SSH host vault: AES-256-GCM with the data key protected by DPAPI on Windows or
|
|
393
|
+
derived from a master passphrase via scrypt elsewhere.
|
|
394
|
+
- Model-facing tools `ssh_hosts`, `ssh_run`, `ssh_transfer` and `ssh_probe`, all addressing
|
|
395
|
+
hosts by alias only.
|
|
396
|
+
- Background job support for commands that outlive one tool call.
|
|
397
|
+
- A private `known_hosts` inside the vault directory with `HashKnownHosts` enabled, so the
|
|
398
|
+
user's `~/.ssh` is never touched.
|
|
399
|
+
- Offline password entry through `scripts/set-secret.mjs`.
|
|
400
|
+
|
|
401
|
+
### Security
|
|
402
|
+
|
|
403
|
+
- A password reaches the local ssh client only through `SSH_ASKPASS`, and a remote `sudo` is
|
|
404
|
+
primed over stdin; neither appears on a command line or in a process list.
|