dsh-remote 0.8.60 → 0.8.62
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/README.en.md +4 -3
- package/README.md +5 -4
- package/lib/client.js +4019 -3852
- package/lib/index.js +73 -2
- package/package.json +3 -3
package/lib/index.js
CHANGED
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
import { createHostKeyGuard, isHostKeyKnown as _isHostKeyKnown } from './hostkey.js'
|
|
35
35
|
import { compileIgnore, ignorePatternsFor, DEFAULT_IGNORE } from './ignore.js'
|
|
36
36
|
import { friendlyMessage } from './errors.js'
|
|
37
|
-
import {
|
|
37
|
+
import { listAliases, sshConfigPath, readSshConfigText, resolveMachineSshConfig, resolveLiteralSshConfig, readRawSshConfig, upsertManagedHostBlock, removeManagedHostBlock, writeSshConfig } from './sshconfig.js'
|
|
38
38
|
import { createRemoteFileReference, installFileReferenceOverlay, DEFAULT_EXCLUDED_DIRECTORIES } from './file-reference.js'
|
|
39
39
|
import { getSecret, deleteSecret, platformBackend, persistPassword } from './credential.js'
|
|
40
40
|
import { syncTree, pushTree, loadSyncState, saveSyncState, pushOneFile } from './sync.js'
|
|
@@ -3816,6 +3816,62 @@ export async function apply(ctx, config) {
|
|
|
3816
3816
|
...(sshConfigWarning ? { sshConfigWarning } : {}),
|
|
3817
3817
|
})
|
|
3818
3818
|
}
|
|
3819
|
+
// Issue #73: one click on a host listed from ~/.ssh/config. The settings
|
|
3820
|
+
// page no longer asks the user to understand "alias" vs "copy": it lists
|
|
3821
|
+
// the file's hosts and this action adopts one — upsert an alias machine
|
|
3822
|
+
// (never a duplicate), make it the current machine, and let the caller
|
|
3823
|
+
// connect/probe next. Nothing about the user's file is rewritten here:
|
|
3824
|
+
// the alias IS the source of truth (issue #50).
|
|
3825
|
+
if (action === 'from-ssh-config') {
|
|
3826
|
+
const alias = String(body.alias || body.host || '').trim()
|
|
3827
|
+
if (!alias) return sendJson(res, 400, { ok: false, error: 'alias required' })
|
|
3828
|
+
const known = listAliases(sshConfigText()).find((a) => a.alias === alias)
|
|
3829
|
+
if (!known) {
|
|
3830
|
+
return sendJson(res, 404, {
|
|
3831
|
+
ok: false,
|
|
3832
|
+
error: `~/.ssh/config 里没有 "${alias}"(改完文件后重新打开设置页即可刷新)`,
|
|
3833
|
+
})
|
|
3834
|
+
}
|
|
3835
|
+
const existing = machines.find((m) => m.useSshConfig && String(m.host) === alias)
|
|
3836
|
+
let rec = existing
|
|
3837
|
+
if (!rec) {
|
|
3838
|
+
rec = {
|
|
3839
|
+
id: machineId(),
|
|
3840
|
+
name: alias,
|
|
3841
|
+
host: alias,
|
|
3842
|
+
useSshConfig: true,
|
|
3843
|
+
port: Number(known.port) || 22,
|
|
3844
|
+
username: String(known.user || ''),
|
|
3845
|
+
password: '',
|
|
3846
|
+
privateKeyPath: '',
|
|
3847
|
+
passphrase: '',
|
|
3848
|
+
workspace: '',
|
|
3849
|
+
hostKeyMode: '',
|
|
3850
|
+
useAgent: false,
|
|
3851
|
+
keyboardInteractive: false,
|
|
3852
|
+
backend: 'native',
|
|
3853
|
+
sshBinary: '',
|
|
3854
|
+
credentialBackend: 'plain',
|
|
3855
|
+
recentWorkspaces: [],
|
|
3856
|
+
lastConnectedAt: null,
|
|
3857
|
+
latencyMs: null,
|
|
3858
|
+
}
|
|
3859
|
+
machines.push(rec)
|
|
3860
|
+
saveMachines(machines, store.currentId, false)
|
|
3861
|
+
}
|
|
3862
|
+
// Making it current is the whole point of the click: the picker and
|
|
3863
|
+
// every session route then act on this machine.
|
|
3864
|
+
const okSet = await setCurrent(rec.id)
|
|
3865
|
+
if (!okSet) return sendJson(res, 500, { ok: false, error: 'could not activate the machine' })
|
|
3866
|
+
return sendJson(res, 200, {
|
|
3867
|
+
ok: true,
|
|
3868
|
+
created: !existing,
|
|
3869
|
+
machine: sanitizeMachine(rec),
|
|
3870
|
+
machines: machinesForClient(),
|
|
3871
|
+
currentId: store.currentId,
|
|
3872
|
+
...status(),
|
|
3873
|
+
})
|
|
3874
|
+
}
|
|
3819
3875
|
if (action === 'delete') {
|
|
3820
3876
|
const i = machineIndex(String(body.id || ''))
|
|
3821
3877
|
if (i < 0) return sendJson(res, 404, { ok: false, error: 'machine not found' })
|
|
@@ -4104,7 +4160,22 @@ export async function apply(ctx, config) {
|
|
|
4104
4160
|
if (req.method !== 'GET') return sendJson(res, 405, { ok: false, error: 'method not allowed' })
|
|
4105
4161
|
try {
|
|
4106
4162
|
const text = readSshConfigText()
|
|
4107
|
-
|
|
4163
|
+
// Issue #73: the settings page lists the hosts of ~/.ssh/config the way
|
|
4164
|
+
// VSCode Remote-SSH does, so this must include EVERY concrete alias —
|
|
4165
|
+
// `importableEntries` filtered out a bare `Host mybox` with no options,
|
|
4166
|
+
// which is a perfectly normal entry to connect to. `host` is kept as an
|
|
4167
|
+
// alias of `alias` so existing callers keep working.
|
|
4168
|
+
const entries = listAliases(text).map((a) => ({
|
|
4169
|
+
host: a.alias,
|
|
4170
|
+
alias: a.alias,
|
|
4171
|
+
hostName: a.hostName || a.alias,
|
|
4172
|
+
user: a.user || '',
|
|
4173
|
+
port: Number(a.port) || 22,
|
|
4174
|
+
identityFile: a.identityFile || '',
|
|
4175
|
+
proxyJump: a.proxyJump || '',
|
|
4176
|
+
proxyCommand: a.proxyCommand || '',
|
|
4177
|
+
}))
|
|
4178
|
+
return sendJson(res, 200, { ok: true, file: sshConfigPath(), present: !!text, entries })
|
|
4108
4179
|
} catch (err) {
|
|
4109
4180
|
return sendJson(res, 500, { ok: false, error: String((err && err.message) || err) })
|
|
4110
4181
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-remote",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.62",
|
|
4
4
|
"description": "Remote-work assistant for DeepSeek Harness: connect SSH (password/key/agent/keyboard-interactive, multi-hop ProxyJump), pick a remote workspace, operate on it with 22 rw_* tools, conflict-aware mirror sync, an embedded PTY terminal, one-click remote dsh deploy + web UI attach, port forwarding, host grouping, remote sandbox fencing, audit log, keychain passwords.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "flymysql <flyphp@outlook.com>",
|
|
@@ -92,8 +92,8 @@
|
|
|
92
92
|
"semver": "^7.8.5"
|
|
93
93
|
},
|
|
94
94
|
"scripts": {
|
|
95
|
-
"test": "node --import ./test/setup-telemetry-off.mjs --test --test-timeout=40000 --test-force-exit",
|
|
96
|
-
"test:coverage": "node scripts/coverage-union.mjs",
|
|
95
|
+
"test": "node --import ./test/setup-telemetry-off.mjs --test --test-timeout=40000 --test-force-exit",
|
|
96
|
+
"test:coverage": "node scripts/coverage-union.mjs",
|
|
97
97
|
"test:coverage:gate": "node scripts/coverage-union.mjs --gate 70"
|
|
98
98
|
}
|
|
99
99
|
}
|