@goodandready/dsh-remote-workspace 0.3.7 → 0.3.9
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.md +49 -2
- package/README.ru.md +49 -2
- package/README.zh.md +49 -2
- package/lib/agent-endpoint.js +16 -0
- package/lib/client.js +1367 -418
- package/lib/cluster-service.js +57 -0
- package/lib/exec-retry.js +24 -0
- package/lib/file-transfer.js +56 -0
- package/lib/host-projection.js +42 -0
- package/lib/index.js +23 -4
- package/lib/jump-chain.js +56 -0
- package/lib/poll-gate.js +5 -0
- package/lib/profile-groups.js +60 -0
- package/lib/proxy-command.js +53 -0
- package/lib/remote-fs-service.js +25 -0
- package/lib/routes/files.js +75 -0
- package/lib/routes/profiles.js +82 -8
- package/lib/routes/terminal.js +19 -0
- package/lib/ssh-config-parser.js +111 -49
- package/lib/ssh-service.js +180 -21
- package/lib/terminal-font.js +12 -0
- package/lib/tools.js +52 -1
- package/lib/tunnel-service.js +3 -0
- package/lib/types.js +7 -0
- package/lib/updater-service.js +3 -18
- package/lib/workspace-mount.js +5 -0
- package/package.json +1 -2
- package/docs/design/DESIGN.md +0 -91
package/README.md
CHANGED
|
@@ -99,6 +99,11 @@ graph LR
|
|
|
99
99
|
- **Password Authentication**: Direct secure password authentication.
|
|
100
100
|
- **Diagnostic Health Probing**: Built-in `testConnection` executes latency measurements (ping in milliseconds) and detects remote OS architecture (`uname -srm`).
|
|
101
101
|
- **Resilience**: Heartbeat keep-alive packets prevent timeout disconnects from aggressive firewalls.
|
|
102
|
+
- **Proxy and jump hosts**: `proxyCommand` runs an OpenSSH-style command. Tokens are `%h`, `%p`, `%r`, `%n`, and `%%`. `jumpHosts` is an ordered list of profile ids. A comma-separated `jumpHostId` is the fallback. The first bastion comes from the pool. Each later bastion has its own connection, released when the target session ends.
|
|
103
|
+
- **Agent and one-time codes**: `agentPath` selects an agent socket. An empty value uses `SSH_AUTH_SOCK`, or Pageant on Windows when that is the configured path. A keyboard-interactive server shows its prompt on the card. The prompt expires after 60 seconds.
|
|
104
|
+
- **Idle pool**: a pooled connection with no tunnel and no running command closes after 30 minutes. The next command opens it again.
|
|
105
|
+
- **Reconnect before output**: if the connection drops before the command prints anything, the command runs again, up to three times. A command timeout, output that already started, or `idempotent: false` is not repeated.
|
|
106
|
+
- **Separate terminal session**: the terminal does not share the pooled connection. Closing the terminal closes only that SSH session.
|
|
102
107
|
|
|
103
108
|
### 2. `RemoteFsService` — Resilient SFTP Operations
|
|
104
109
|
- **Atomic File Writing**: Writes content to an ephemeral temporary file (`.tmp.<timestamp>.<hash>`) and renames it atomically upon complete upload, preventing partial or corrupted files.
|
|
@@ -122,13 +127,22 @@ Four orthogonal, high-leverage tools exposed directly to LLM agents:
|
|
|
122
127
|
- `remote_fs`: Read, write, inspect, list, create directories, or delete files on the remote filesystem.
|
|
123
128
|
- `remote_sync`: Synchronize files between the local mirror and remote server with conflict awareness and dry-run mode.
|
|
124
129
|
- `remote_tunnel`: Start, stop, or list SSH port-forwarding tunnels.
|
|
130
|
+
- `remote_hosts`: Return a compact markdown table of configured hosts. Secrets, private keys, and proxy commands are omitted. `query` is required; an empty query lists every host.
|
|
131
|
+
- `remote_cluster`: Run one command on every host that matches an environment, every requested tag, and an optional alias list. `maxWorkers` defaults to 8.
|
|
125
132
|
|
|
126
133
|
### 6. `client.js` — Native DSH Settings Card UI
|
|
127
134
|
- Designed strictly to DSH UX guidelines and styled after `dsh-clinebot`.
|
|
128
135
|
- **Segmented Auth Switcher**: Clean tabbed toggle between Private Key and Password authentication.
|
|
129
136
|
- **Remote Directory Browser Modal**: Interactive remote file browser with breadcrumb navigation and one-click path selection.
|
|
130
|
-
- **Connection Diagnostic Badge**: Real-time ping testing with visual latency indicators and remote OS display.
|
|
131
|
-
- **Action Triggers**: Quick buttons for directional synchronization and tunnel monitoring.
|
|
137
|
+
- **Connection Diagnostic Badge**: Real-time ping testing with visual latency indicators and remote OS display. The header badge follows `/dsh-remote-workspace/state`: it shows a loading, empty, ready, or unavailable connection instead of a permanent Ready label.
|
|
138
|
+
- **Action Triggers**: Quick buttons for directional synchronization and tunnel monitoring. A failed save, delete, activation, directory browse, or tunnel stop shows the server error in an alert on the card. Test Connection posts the profile fields, including `host`.
|
|
139
|
+
- **Plugin list label**: English `Remote Workspace` or Chinese `远程开发工作区`, taken from the dictionaries already loaded with the card.
|
|
140
|
+
- **Updater version**: the row shows the installed version returned by the status request. Before that response it shows "Version unknown".
|
|
141
|
+
- **Host groups**: profiles can carry `environment`, `tags`, `location`, and `description`. The card can list them flat, by environment, or by tag, and test one group together.
|
|
142
|
+
- **Files**: the Files tab uploads and downloads a remote file. Progress follows the bytes already moved, and Cancel stops the transfer. Files larger than 512MB are refused.
|
|
143
|
+
- **Terminal font**: `terminalFontFamily` is a CSS font family for the terminal. Leave it empty for the default monospace stack.
|
|
144
|
+
- **Hidden tab**: status polling pauses while the browser tab is hidden and refreshes when the tab returns.
|
|
145
|
+
- **Sidebar workspace**: a Remote button in the left navigation opens the center column with Hosts, Terminal, Files, Containers, Tunnels, and Cluster. Switching back to chat hides that column and keeps the open terminal.
|
|
132
146
|
|
|
133
147
|
---
|
|
134
148
|
|
|
@@ -187,6 +201,15 @@ dsh-remote-workspace:
|
|
|
187
201
|
| `profile.password` | `string` | `""` | Password for password-based authentication. |
|
|
188
202
|
| `profile.remoteWorkspace` | `string` | `""` | Base directory of the project on the remote machine. |
|
|
189
203
|
| `profile.localMirrorPath` | `string` | `""` | Local directory for mirror synchronization. |
|
|
204
|
+
| `profile.agentPath` | `string` | `""` | SSH agent socket. Empty uses `SSH_AUTH_SOCK`. |
|
|
205
|
+
| `profile.proxyCommand` | `string` | `""` | OpenSSH ProxyCommand. Tokens: `%h` `%p` `%r` `%n`. |
|
|
206
|
+
| `profile.jumpHosts` | `string[]` | `[]` | Bastion profile ids, first hop first. |
|
|
207
|
+
| `profile.jumpHostId` | `string` | `""` | Comma-separated bastion ids when `jumpHosts` is empty. |
|
|
208
|
+
| `profile.environment` | `string` | `""` | Group and cluster filter, compared case-insensitively. |
|
|
209
|
+
| `profile.tags` | `string[]` | `[]` | Labels. A cluster filter requires every tag. |
|
|
210
|
+
| `profile.location` | `string` | `""` | Free-form place label. |
|
|
211
|
+
| `profile.description` | `string` | `""` | Free-form note. |
|
|
212
|
+
| `terminalFontFamily` | `string` | `""` | Terminal CSS font family. Empty keeps the default monospace stack. |
|
|
190
213
|
|
|
191
214
|
---
|
|
192
215
|
|
|
@@ -225,6 +248,23 @@ Manages SSH local port forwarding tunnels.
|
|
|
225
248
|
- `tunnelId` (`string`, optional): Identifier of the tunnel to terminate (for `"stop"`).
|
|
226
249
|
- **Returns**: `{ tunnelId, localPort, remotePort }` or `{ tunnels: [...] }` or `{ success: boolean }`.
|
|
227
250
|
|
|
251
|
+
### `remote_hosts`
|
|
252
|
+
Lists configured hosts for the model without secrets.
|
|
253
|
+
- **Parameters**:
|
|
254
|
+
- `query` (`string`, required): Case-insensitive match against name, host, or id. An empty string lists every host.
|
|
255
|
+
- **Returns**: A markdown table. Password, private key, key path, passphrase, agent socket, and proxy command are omitted.
|
|
256
|
+
|
|
257
|
+
### `remote_cluster`
|
|
258
|
+
Runs one shell command on a filtered set of hosts.
|
|
259
|
+
- **Parameters**:
|
|
260
|
+
- `command` (`string`, required): Shell command.
|
|
261
|
+
- `environment` (`string`, optional): Exact environment name.
|
|
262
|
+
- `tags` (`string`, optional): Comma-separated tags. Every tag must match.
|
|
263
|
+
- `aliases` (`string`, optional): Comma-separated profile ids or names.
|
|
264
|
+
- `maxWorkers` (`number`, optional): Parallel connections. Default 8.
|
|
265
|
+
- **Returns**: One row per host with success, exit code, duration, stdout, stderr, and error.
|
|
266
|
+
- **Limit**: A host that fails to connect is reported on its own row. Other hosts still run.
|
|
267
|
+
|
|
228
268
|
---
|
|
229
269
|
|
|
230
270
|
## 🌐 HTTP API Routes Reference
|
|
@@ -240,6 +280,13 @@ All endpoints are hosted under `/dsh-remote-workspace`:
|
|
|
240
280
|
| `POST` | `/dsh-remote-workspace/test` | Test SSH connectivity and latency. | Profile JSON object |
|
|
241
281
|
| `POST` | `/dsh-remote-workspace/browse` | List directory contents for remote browser modal. | `{ profile: object, path: string }` |
|
|
242
282
|
| `POST` | `/dsh-remote-workspace/sync` | Trigger manual pull or push synchronization. | `{ direction: "pull" \| "push", dryRun?: boolean, force?: boolean }` |
|
|
283
|
+
| `POST` | `/dsh-remote-workspace/profiles/import-ssh-config` | Import `~/.ssh/config`, or the posted config text. | `{ content?: string }` |
|
|
284
|
+
| `POST` | `/dsh-remote-workspace/profiles/test-group` | Test the stored profiles whose ids are posted. | `{ ids: string[] }` |
|
|
285
|
+
| `POST` | `/dsh-remote-workspace/cluster` | Run one command on the filtered stored profiles. | `{ command, environment?, tags?, aliases?, maxWorkers? }` |
|
|
286
|
+
| `GET` | `/dsh-remote-workspace/file/download` | Stream a remote file. Query: `profileId`, `filePath`. | — |
|
|
287
|
+
| `POST` | `/dsh-remote-workspace/file/upload` | Upload a raw file body. Query: `profileId`, `filePath`. | file bytes |
|
|
288
|
+
| `POST` | `/dsh-remote-workspace/terminal/font` | Save the terminal font family. | `{ fontFamily: string }` |
|
|
289
|
+
| `POST` | `/dsh-remote-workspace/auth/keyboard` | Submit a keyboard-interactive code. | `{ id, answers }` |
|
|
243
290
|
|
|
244
291
|
---
|
|
245
292
|
|
package/README.ru.md
CHANGED
|
@@ -99,6 +99,11 @@ graph LR
|
|
|
99
99
|
- **Пароль (Password)**: Прямая безопасная аутентификация по логину и паролю.
|
|
100
100
|
- **Диагностический зонд**: Метод `testConnection` измеряет пинг в миллисекундах и определяет платформу удалённого хоста (`uname -srm`).
|
|
101
101
|
- **Защита от таймаутов**: Пакеты keep-alive предотвращают разрыв соединения корпоративными фаерволами.
|
|
102
|
+
- **Прокси и прыжки**: `proxyCommand` запускает команду в стиле OpenSSH. Токены: `%h`, `%p`, `%r`, `%n` и `%%`. `jumpHosts` — упорядоченный список идентификаторов профилей. Если массив пуст, используется `jumpHostId` через запятую. Первый бастион берётся из пула, следующие открывают отдельные соединения и закрываются вместе с целевой сессией.
|
|
103
|
+
- **Агент и одноразовый код**: `agentPath` задаёт сокет агента. Пустое значение использует `SSH_AUTH_SOCK`, а на Windows можно указать `pageant`. Запрос keyboard-interactive появляется на карточке и истекает через 60 секунд.
|
|
104
|
+
- **Простой пула**: соединение без туннеля и без выполняемой команды закрывается через 30 минут. Следующая команда открывает его снова.
|
|
105
|
+
- **Повтор до вывода**: если соединение оборвалось до первого вывода, команда повторяется до трёх раз. Таймаут команды, уже начатый вывод и `idempotent: false` не повторяются.
|
|
106
|
+
- **Отдельный терминал**: терминал не делит соединение пула. Закрытие терминала закрывает только его SSH-сессию.
|
|
102
107
|
|
|
103
108
|
### 2. `RemoteFsService` — Отказоустойчивый SFTP
|
|
104
109
|
- **Атомарная запись файлов**: Загрузка производится во временный файл (`.tmp.<timestamp>.<hash>`) с последующим атомарным переименованием. Разрыв соединения не повреждает целевой файл.
|
|
@@ -122,13 +127,22 @@ graph LR
|
|
|
122
127
|
- `remote_fs`: Операции чтения, записи, stat, листинга, создания директорий и удаления.
|
|
123
128
|
- `remote_sync`: Синхронизация между локальным зеркалом и сервером с отчётом о конфликтах и режимом dry-run.
|
|
124
129
|
- `remote_tunnel`: Управление SSH-туннелями (запуск, остановка, список).
|
|
130
|
+
- `remote_hosts`: Краткая markdown-таблица хостов без паролей, ключей и команд прокси. `query` обязателен; пустая строка показывает все хосты.
|
|
131
|
+
- `remote_cluster`: Одна команда на хостах, которые совпали по окружению, всем указанным меткам и необязательным псевдонимам. `maxWorkers` по умолчанию 8.
|
|
125
132
|
|
|
126
133
|
### 6. `client.js` — Нативный UI карточки настроек
|
|
127
134
|
- Полноценная интеграция в слот `settings.plugin.item` с ключом `dsh-remote-workspace`.
|
|
128
135
|
- **Сегментированный переключатель авторизации**: Удобное переключение между SSH-ключом и паролем.
|
|
129
136
|
- **Интерактивный браузер удалённых папок**: Модальное окно с навигацией по каталогам и выбором рабочей директории в один клик.
|
|
130
|
-
- **Индикатор статуса и задержки**: Проверка связи с отображением пинга и ОС удалённого узла.
|
|
131
|
-
- **Кнопки действий**: Быстрый запуск синхронизации и контроль туннелей прямо из настроек.
|
|
137
|
+
- **Индикатор статуса и задержки**: Проверка связи с отображением пинга и ОС удалённого узла. Бейдж шапки читает `/dsh-remote-workspace/state` и показывает проверку, отсутствие активного хоста, готовность или недоступность статуса.
|
|
138
|
+
- **Кнопки действий**: Быстрый запуск синхронизации и контроль туннелей прямо из настроек. Ошибка сохранения, удаления, выбора активного профиля, обзора каталога или остановки туннеля показывается в предупреждении на карточке. Проверка соединения отправляет поля профиля, включая `host`.
|
|
139
|
+
- **Подпись в списке плагинов**: английская `Remote Workspace` или китайская `远程开发工作区` из словарей карточки.
|
|
140
|
+
- **Версия в блоке обновления**: строка показывает установленную версию из ответа статуса. Пока ответ не пришёл, показывается нейтральная подпись неизвестной версии.
|
|
141
|
+
- **Группы хостов**: у профиля есть `environment`, `tags`, `location` и `description`. Карточка показывает плоский список, группы по окружению или по метке и может проверить группу целиком.
|
|
142
|
+
- **Файлы**: вкладка Files загружает и скачивает удалённый файл, показывает прогресс по байтам и даёт отменить передачу. Файл больше 512 МБ отклоняется.
|
|
143
|
+
- **Шрифт терминала**: `terminalFontFamily` — семейство шрифтов CSS. Пустое значение оставляет стандартный моноширинный набор.
|
|
144
|
+
- **Скрытая вкладка**: опрос состояния останавливается, пока вкладка браузера скрыта, и сразу обновляется, когда вкладка снова видна.
|
|
145
|
+
- **Боковая панель**: кнопка Remote слева открывает в центральной колонке хосты, терминал, файлы, контейнеры, туннели и кластер. Возврат в чат только скрывает колонку, буфер терминала сохраняется.
|
|
132
146
|
|
|
133
147
|
---
|
|
134
148
|
|
|
@@ -187,6 +201,15 @@ dsh-remote-workspace:
|
|
|
187
201
|
| `profile.password` | `string` | `""` | Пароль для входа по логину и паролю. |
|
|
188
202
|
| `profile.remoteWorkspace` | `string` | `""` | Путь к каталогу проекта на удалённом сервере. |
|
|
189
203
|
| `profile.localMirrorPath` | `string` | `""` | Путь к локальному зеркалу проекта. |
|
|
204
|
+
| `profile.agentPath` | `string` | `""` | Сокет SSH-агента. Пустое значение использует `SSH_AUTH_SOCK`. |
|
|
205
|
+
| `profile.proxyCommand` | `string` | `""` | OpenSSH ProxyCommand. Токены: `%h` `%p` `%r` `%n`. |
|
|
206
|
+
| `profile.jumpHosts` | `string[]` | `[]` | Идентификаторы бастионов, первый — вход. |
|
|
207
|
+
| `profile.jumpHostId` | `string` | `""` | Бастионы через запятую, если `jumpHosts` пуст. |
|
|
208
|
+
| `profile.environment` | `string` | `""` | Окружение для группы и фильтра кластера. |
|
|
209
|
+
| `profile.tags` | `string[]` | `[]` | Метки. Фильтр кластера требует совпадения каждой. |
|
|
210
|
+
| `profile.location` | `string` | `""` | Подпись места. |
|
|
211
|
+
| `profile.description` | `string` | `""` | Заметка. |
|
|
212
|
+
| `terminalFontFamily` | `string` | `""` | Семейство шрифта терминала. Пусто — стандартный моноширинный набор. |
|
|
190
213
|
|
|
191
214
|
---
|
|
192
215
|
|
|
@@ -225,6 +248,23 @@ dsh-remote-workspace:
|
|
|
225
248
|
- `tunnelId` (`string`, для stop): Идентификатор туннеля для закрытия.
|
|
226
249
|
- **Возвращает**: `{ tunnelId, localPort, remotePort }` или список туннелей `{ tunnels: [...] }`.
|
|
227
250
|
|
|
251
|
+
### `remote_hosts`
|
|
252
|
+
Список хостов для модели без секретов.
|
|
253
|
+
- **Параметры**:
|
|
254
|
+
- `query` (`string`, обязательно): Поиск по имени, хосту или идентификатору. Пустая строка показывает все.
|
|
255
|
+
- **Возвращает**: Markdown-таблицу. Пароль, ключ, путь к ключу, passphrase, сокет агента и proxy command не включаются.
|
|
256
|
+
|
|
257
|
+
### `remote_cluster`
|
|
258
|
+
Одна команда на отфильтрованном наборе хостов.
|
|
259
|
+
- **Параметры**:
|
|
260
|
+
- `command` (`string`, обязательно): Команда оболочки.
|
|
261
|
+
- `environment` (`string`): Точное имя окружения.
|
|
262
|
+
- `tags` (`string`): Метки через запятую. Нужны все.
|
|
263
|
+
- `aliases` (`string`): Идентификаторы или имена через запятую.
|
|
264
|
+
- `maxWorkers` (`number`): Параллельность, по умолчанию 8.
|
|
265
|
+
- **Возвращает**: Строку на каждый хост: успех, код выхода, длительность, stdout, stderr и ошибка.
|
|
266
|
+
- **Ограничение**: Сбой соединения одного хоста не останавливает остальные.
|
|
267
|
+
|
|
228
268
|
---
|
|
229
269
|
|
|
230
270
|
## 🌐 Справочник HTTP API
|
|
@@ -240,6 +280,13 @@ dsh-remote-workspace:
|
|
|
240
280
|
| `POST` | `/dsh-remote-workspace/test` | Проверка связи и замер пинга. | JSON профиля |
|
|
241
281
|
| `POST` | `/dsh-remote-workspace/browse` | Получение списка файлов для браузера папок. | `{ profile: object, path: string }` |
|
|
242
282
|
| `POST` | `/dsh-remote-workspace/sync` | Запуск синхронизации. | `{ direction: "pull" \| "push", dryRun?: boolean, force?: boolean }` |
|
|
283
|
+
| `POST` | `/dsh-remote-workspace/profiles/import-ssh-config` | Импорт `~/.ssh/config` или переданного текста. | `{ content?: string }` |
|
|
284
|
+
| `POST` | `/dsh-remote-workspace/profiles/test-group` | Проверка сохранённых профилей по списку id. | `{ ids: string[] }` |
|
|
285
|
+
| `POST` | `/dsh-remote-workspace/cluster` | Команда на отфильтрованных сохранённых профилях. | `{ command, environment?, tags?, aliases?, maxWorkers? }` |
|
|
286
|
+
| `GET` | `/dsh-remote-workspace/file/download` | Поток удалённого файла. Query: `profileId`, `filePath`. | — |
|
|
287
|
+
| `POST` | `/dsh-remote-workspace/file/upload` | Загрузка тела файла. Query: `profileId`, `filePath`. | байты файла |
|
|
288
|
+
| `POST` | `/dsh-remote-workspace/terminal/font` | Сохранение шрифта терминала. | `{ fontFamily: string }` |
|
|
289
|
+
| `POST` | `/dsh-remote-workspace/auth/keyboard` | Ответ keyboard-interactive. | `{ id, answers }` |
|
|
243
290
|
|
|
244
291
|
---
|
|
245
292
|
|
package/README.zh.md
CHANGED
|
@@ -99,6 +99,11 @@ graph LR
|
|
|
99
99
|
- **密码认证**:原生支持常规账号密码安全登录。
|
|
100
100
|
- **链路诊断探测**:内置 `testConnection` 方法,精确测定毫秒级网络延迟,并自动探测远程主机内核与架构(`uname -srm`)。
|
|
101
101
|
- **心跳保活机制**:主动发送 Keep-Alive 探测包,有效防止各类网络防火墙超时断开空闲连接。
|
|
102
|
+
- **代理命令与跳板**:`proxyCommand` 运行 OpenSSH 风格命令,令牌为 `%h`、`%p`、`%r`、`%n` 和 `%%`。`jumpHosts` 是按顺序排列的配置编号;`jumpHostId` 可以用逗号分隔作为后备。第一跳来自连接池,后续跳板使用独立连接,并在目标会话结束时关闭。
|
|
103
|
+
- **代理与一次性验证码**:`agentPath` 指定 SSH 代理套接字。留空则使用 `SSH_AUTH_SOCK`;在 Windows 上可填写 `pageant`。需要键盘交互时,验证码显示在设置卡片上,60 秒后失效。
|
|
104
|
+
- **空闲连接**:没有隧道、也没有正在执行的命令时,池中的连接在 30 分钟后关闭。下一次命令会重新连接。
|
|
105
|
+
- **输出前重连**:如果连接在命令产生任何输出之前断开,同一命令最多再试 3 次。命令超时、已经开始的输出,以及 `idempotent: false` 不会重试。
|
|
106
|
+
- **独立终端**:终端不共用连接池。关闭终端只关闭这一条 SSH 会话。
|
|
102
107
|
|
|
103
108
|
### 2. `RemoteFsService` — 原子高可用 SFTP 文件系统
|
|
104
109
|
- **原子安全写入**:文件首先上传至独立的临时文件(`.tmp.<timestamp>.<hash>`),上传完成校验后通过原子重命名完成替换,彻底避免因网络异常产生残缺文件。
|
|
@@ -122,13 +127,22 @@ graph LR
|
|
|
122
127
|
- `remote_fs`:执行远程文件的读、写、状态查询、目录列表、创建与删除。
|
|
123
128
|
- `remote_sync`:在本地镜像与远程目录间发起具备冲突感知的同步操作。
|
|
124
129
|
- `remote_tunnel`:开启、关闭或枚举 SSH 端口转发隧道。
|
|
130
|
+
- `remote_hosts`:返回不含密码、私钥和代理命令的主机 Markdown 表。`query` 必填,空字符串列出全部主机。
|
|
131
|
+
- `remote_cluster`:在符合环境、标签和别名的主机上运行同一条命令。`maxWorkers` 默认 8。
|
|
125
132
|
|
|
126
133
|
### 6. `client.js` — 原生 DSH 设置面板
|
|
127
134
|
- 深度适配 `settings.plugin.item` 插槽(Key: `dsh-remote-workspace`)。
|
|
128
135
|
- **分段式认证切换器**:优雅切换私钥认证与密码认证。
|
|
129
136
|
- **远程目录浏览器弹窗**:可视化浏览远程服务器目录树,支持面包屑导航与一键选取。
|
|
130
|
-
-
|
|
131
|
-
-
|
|
137
|
+
- **实时连接状态徽章**:可视化展示连通性、网络延迟以及远程操作系统信息。页眉徽章读取 `/dsh-remote-workspace/state`,分别表示正在检查、没有活动主机、主机已就绪或状态不可用,不再固定显示“就绪”。
|
|
138
|
+
- **快捷动作触发**:一键发起定向文件同步并监控隧道运行状态。保存、删除、设为活动、浏览目录或关闭隧道失败时,卡片上的警告会显示服务器返回的错误。连接测试提交的是配置本身,其中包含 `host`。
|
|
139
|
+
- **插件列表名称**:英文为 `Remote Workspace`,中文为 `远程开发工作区`,取自随卡片加载的词典。
|
|
140
|
+
- **更新版本**:该行显示状态接口返回的已安装版本。结果返回前显示“版本未知”。
|
|
141
|
+
- **主机分组**:配置可以填写 `environment`、`tags`、`location` 和 `description`。卡片可按平铺、环境或标签显示,并一次测试整组。
|
|
142
|
+
- **文件传输**:文件页可以上传和下载远程文件,按已传输字节显示进度,并可取消。超过 512MB 的文件会被拒绝。
|
|
143
|
+
- **终端字体**:`terminalFontFamily` 是终端的 CSS 字体族。留空则使用默认等宽字体。
|
|
144
|
+
- **隐藏页面**:浏览器标签隐藏时暂停状态轮询,回到页面后立即刷新。
|
|
145
|
+
- **侧栏工作区**:左侧导航的“远程”按钮在中央区域打开主机、终端、文件、容器、隧道和集群。返回聊天只是隐藏该区域,终端内容保留。
|
|
132
146
|
|
|
133
147
|
---
|
|
134
148
|
|
|
@@ -187,6 +201,15 @@ dsh-remote-workspace:
|
|
|
187
201
|
| `profile.password` | `string` | `""` | 密码认证模式下的登录密码。 |
|
|
188
202
|
| `profile.remoteWorkspace` | `string` | `""` | 远程服务器上的项目工作区根目录。 |
|
|
189
203
|
| `profile.localMirrorPath` | `string` | `""` | 对应远程项目的本地镜像工作目录。 |
|
|
204
|
+
| `profile.agentPath` | `string` | `""` | SSH 代理套接字。留空使用 `SSH_AUTH_SOCK`。 |
|
|
205
|
+
| `profile.proxyCommand` | `string` | `""` | OpenSSH ProxyCommand。令牌:`%h` `%p` `%r` `%n`。 |
|
|
206
|
+
| `profile.jumpHosts` | `string[]` | `[]` | 跳板配置编号,第一台为入口。 |
|
|
207
|
+
| `profile.jumpHostId` | `string` | `""` | `jumpHosts` 为空时的逗号分隔跳板编号。 |
|
|
208
|
+
| `profile.environment` | `string` | `""` | 分组和集群过滤,忽略大小写。 |
|
|
209
|
+
| `profile.tags` | `string[]` | `[]` | 标签。集群过滤要求每个标签都匹配。 |
|
|
210
|
+
| `profile.location` | `string` | `""` | 位置说明。 |
|
|
211
|
+
| `profile.description` | `string` | `""` | 备注。 |
|
|
212
|
+
| `terminalFontFamily` | `string` | `""` | 终端 CSS 字体族。留空使用默认等宽字体。 |
|
|
190
213
|
|
|
191
214
|
---
|
|
192
215
|
|
|
@@ -225,6 +248,23 @@ dsh-remote-workspace:
|
|
|
225
248
|
- `tunnelId` (`string`,停止时必填):需要关闭的隧道 ID。
|
|
226
249
|
- **返回数据**:`{ tunnelId, localPort, remotePort }` 或隧道清单 `{ tunnels: [...] }`。
|
|
227
250
|
|
|
251
|
+
### `remote_hosts`
|
|
252
|
+
向模型返回不含秘密的主机表。
|
|
253
|
+
- **输入参数**:
|
|
254
|
+
- `query` (`string`,必填):按名称、主机或编号匹配。空字符串列出全部。
|
|
255
|
+
- **返回数据**:Markdown 表。密码、私钥、密钥路径、口令、代理套接字和代理命令不会出现。
|
|
256
|
+
|
|
257
|
+
### `remote_cluster`
|
|
258
|
+
在筛选后的主机上运行同一条命令。
|
|
259
|
+
- **输入参数**:
|
|
260
|
+
- `command` (`string`,必填):Shell 命令。
|
|
261
|
+
- `environment` (`string`,可选):精确的环境名。
|
|
262
|
+
- `tags` (`string`,可选):逗号分隔的标签,必须全部匹配。
|
|
263
|
+
- `aliases` (`string`,可选):逗号分隔的配置编号或名称。
|
|
264
|
+
- `maxWorkers` (`number`,可选):并行数,默认 8。
|
|
265
|
+
- **返回数据**:每台主机一行,包含成功与否、退出码、耗时、标准输出、标准错误和错误。
|
|
266
|
+
- **限制**:一台主机连接失败只影响自己的结果行。
|
|
267
|
+
|
|
228
268
|
---
|
|
229
269
|
|
|
230
270
|
## 🌐 HTTP API 接口列表
|
|
@@ -240,6 +280,13 @@ dsh-remote-workspace:
|
|
|
240
280
|
| `POST` | `/dsh-remote-workspace/test` | 测试 SSH 连通性、延迟与系统信息。 | 主机配置 JSON |
|
|
241
281
|
| `POST` | `/dsh-remote-workspace/browse` | 获取指定远程路径下的子目录列表(供选择器使用)。 | `{ profile: object, path: string }` |
|
|
242
282
|
| `POST` | `/dsh-remote-workspace/sync` | 发起手动目录镜像同步。 | `{ direction: "pull" \| "push", dryRun?: boolean, force?: boolean }` |
|
|
283
|
+
| `POST` | `/dsh-remote-workspace/profiles/import-ssh-config` | 导入 `~/.ssh/config` 或提交的配置文本。 | `{ content?: string }` |
|
|
284
|
+
| `POST` | `/dsh-remote-workspace/profiles/test-group` | 测试提交的已保存配置编号。 | `{ ids: string[] }` |
|
|
285
|
+
| `POST` | `/dsh-remote-workspace/cluster` | 在筛选后的已保存主机上运行命令。 | `{ command, environment?, tags?, aliases?, maxWorkers? }` |
|
|
286
|
+
| `GET` | `/dsh-remote-workspace/file/download` | 流式下载远程文件。查询参数:`profileId`、`filePath`。 | — |
|
|
287
|
+
| `POST` | `/dsh-remote-workspace/file/upload` | 上传原始文件。查询参数:`profileId`、`filePath`。 | 文件字节 |
|
|
288
|
+
| `POST` | `/dsh-remote-workspace/terminal/font` | 保存终端字体。 | `{ fontFamily: string }` |
|
|
289
|
+
| `POST` | `/dsh-remote-workspace/auth/keyboard` | 提交键盘交互验证码。 | `{ id, answers }` |
|
|
243
290
|
|
|
244
291
|
---
|
|
245
292
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ssh2 agent endpoint for a profile. Pageant is the Windows name ssh2 understands.
|
|
3
|
+
* A private key is never read for this auth type.
|
|
4
|
+
* @param {any} profile
|
|
5
|
+
* @param {NodeJS.ProcessEnv} [env]
|
|
6
|
+
* @param {string} [platform]
|
|
7
|
+
*/
|
|
8
|
+
export function resolveAgentEndpoint(profile, env = process.env, platform = process.platform) {
|
|
9
|
+
if (profile?.authType !== 'agent') return undefined;
|
|
10
|
+
const raw = String(profile.agentPath || '').trim();
|
|
11
|
+
if (raw.toLowerCase() === 'pageant') return 'pageant';
|
|
12
|
+
if (raw) return raw;
|
|
13
|
+
if (env && env.SSH_AUTH_SOCK) return env.SSH_AUTH_SOCK;
|
|
14
|
+
if (platform === 'win32') return 'pageant';
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|