@goodandready/dsh-remote-workspace 0.3.2 → 0.3.4

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.
@@ -7,7 +7,7 @@ emote_fs,
7
7
  emote_sync,
8
8
  emote_tunnel).
9
9
  - **Аудитория**: Разработчики и инженеры, использующие DSH для работы с проектами на VPS, удаленных серверах, облачных инстансах и MiniPC.
10
- - **Статус**: Стабильный релиз v0.3.2 (One-Click Updater, Cross-Plugin API, Clean Tokens, Modular Routes).
10
+ - **Статус**: Стабильный релиз v0.3.3 (One-Click Updater, Cross-Plugin API, Clean Tokens, Modular Routes).
11
11
 
12
12
  ## User Surfaces
13
13
  - **Web/UI**: Нативная карточка настроек профилей хостов (settings.plugin.item), удаленный SFTP браузер каталогов, чип статуса подключения в шапке сессии (conversation.session.header.utilities).
@@ -69,3 +69,17 @@ emote_tunnel: создание/остановка/листинг туннеле
69
69
  - Защита всех мутирующих эндпоинтов проверкой isTrustedSettingsRequest(req) (защита от cross-site атак).
70
70
  - Безопасное чтение Cordis сервисов через .get() с fallback.
71
71
  - Изоляция жизненного цикла стримов в TunnelService (прослушивание сокетных и потоковых ошибок).
72
+
73
+ ### v0.3.3 Client Architecture Modularization (Refs: #14)
74
+ - Client-side code decomposed into modular ES components under `src/client/`:
75
+ - `src/client/styles.js` — CSS styling with DSH theme variables
76
+ - `src/client/locales.js` — English and Chinese translation dictionaries
77
+ - `src/client/env-editor.js` — Remote .env manager tab component
78
+ - `src/client/docker.js` — Container inspector tab component
79
+ - `src/client/terminal.js` — Web terminal tab component
80
+ - `src/client/file-browser.js` — Remote file explorer tab component
81
+ - `src/client/settings-view.js` — Profiles, tunnels, and sync settings component
82
+ - `src/client/updater-section.js` — One-click updater section component
83
+ - `src/client/plugin-card.js` — Plugin card and status chip components
84
+ - `src/client/entry.js` — Cordis client plugin apply and slot registration
85
+ - Added native builder `scripts/build-client.mjs` hooked into `prepack` and `npm test`.
package/lib/client.js CHANGED
@@ -7,6 +7,9 @@ window.__ModuleLoader__.load({
7
7
  const React = require('react')
8
8
 
9
9
  const NS = 'dsh-remote-workspace'
10
+ // Plugins page row seat (DSH 0.1.6-alpha.2): key = '<package name>#<row id>'.
11
+ const ROW_ID = 'dsh-remote-workspace'
12
+ const ROW_CONFIG_KEY = '@goodandready/dsh-remote-workspace#' + ROW_ID
10
13
 
11
14
  function ensureCss() {
12
15
  if (typeof document === 'undefined') return
@@ -435,6 +438,7 @@ window.__ModuleLoader__.load({
435
438
 
436
439
 
437
440
  // --- Sub-component: Remote Environment Tab (New in v0.3.1) ---
441
+
438
442
  function EnvTab(props) {
439
443
  const { activeProfile, t } = props
440
444
  const [envEntries, setEnvEntries] = React.useState([])
@@ -538,6 +542,7 @@ window.__ModuleLoader__.load({
538
542
  }
539
543
 
540
544
  // --- Sub-component: Docker Containers Tab ---
545
+
541
546
  function ContainersTab(props) {
542
547
  const { activeProfile, t } = props
543
548
  const [containers, setContainers] = React.useState([])
@@ -688,6 +693,7 @@ window.__ModuleLoader__.load({
688
693
  }
689
694
 
690
695
  // --- Sub-component: Web Terminal Tab ---
696
+
691
697
  function TerminalTab(props) {
692
698
  const { activeProfile, t } = props
693
699
  const [connected, setConnected] = React.useState(false)
@@ -893,6 +899,7 @@ window.__ModuleLoader__.load({
893
899
  }
894
900
 
895
901
  // --- Sub-component: Remote File Explorer Tab ---
902
+
896
903
  function ExplorerTab(props) {
897
904
  const { activeProfile, t } = props
898
905
  const [currentPath, setCurrentPath] = React.useState(activeProfile?.remoteWorkspace || '/')
@@ -2071,6 +2078,7 @@ window.__ModuleLoader__.load({
2071
2078
  }
2072
2079
 
2073
2080
  // Accordion item for Settings -> Plugins section
2081
+
2074
2082
  function UpdaterSection(props) {
2075
2083
  const t = props.t || ((k) => k);
2076
2084
  const [updateStatus, setUpdateStatus] = React.useState(null);
@@ -2186,16 +2194,23 @@ window.__ModuleLoader__.load({
2186
2194
  }
2187
2195
 
2188
2196
  function PluginCard(props) {
2189
- const [open, setOpen] = React.useState(false)
2197
+ const page = !!(props && props.view === 'page')
2198
+ const [open, setOpen] = React.useState(!!page)
2190
2199
  const t = props.t || (props.locale === 'zh' ? makeT(zh, en) : makeT(en, zh))
2191
2200
 
2192
2201
  React.useEffect(() => {
2193
2202
  ensureCss()
2194
2203
  }, [])
2195
2204
 
2205
+ // Row seat (plugins.row.config): the host page draws title/icon/crumb and the
2206
+ // padding, so the summary is a one-liner and the page drops our card chrome.
2207
+ if (props && props.view === 'summary') {
2208
+ return React.createElement('span', { style: { fontSize: '13px', color: 'var(--dsw-alias-label-secondary)' } }, t('subtitle'))
2209
+ }
2210
+
2196
2211
  return React.createElement(
2197
- 'li',
2198
- { className: 'drw-card', style: { listStyle: 'none', marginBottom: '12px' } },
2212
+ page ? 'div' : 'li',
2213
+ { className: page ? 'drw-page' : 'drw-card', style: page ? undefined : { listStyle: 'none', marginBottom: '12px' } },
2199
2214
  React.createElement(
2200
2215
  'button',
2201
2216
  {
@@ -2204,13 +2219,13 @@ window.__ModuleLoader__.load({
2204
2219
  background: 'none',
2205
2220
  border: 'none',
2206
2221
  cursor: 'pointer',
2207
- display: 'flex',
2222
+ display: page ? 'none' : 'flex',
2208
2223
  alignItems: 'center',
2209
2224
  width: '100%',
2210
2225
  padding: 0,
2211
2226
  textAlign: 'left',
2212
2227
  },
2213
- 'aria-expanded': open,
2228
+ 'aria-expanded': page ? true : open,
2214
2229
  onClick: () => setOpen((v) => !v),
2215
2230
  },
2216
2231
  React.createElement('span', { style: { fontSize: '20px', marginRight: '12px' } }, '🌐'),
@@ -2227,7 +2242,7 @@ window.__ModuleLoader__.load({
2227
2242
  React.createElement(FallbackChevron)
2228
2243
  )
2229
2244
  ),
2230
- open
2245
+ (page || open)
2231
2246
  ? React.createElement(
2232
2247
  'div',
2233
2248
  { style: { marginTop: '16px', borderTop: '1px solid var(--dsw-alias-border-l2)', paddingTop: '16px' } },
@@ -2285,6 +2300,19 @@ window.__ModuleLoader__.load({
2285
2300
  }
2286
2301
 
2287
2302
  if (ctx.slots && typeof ctx.slots.inject === 'function') {
2303
+ // Row seat first (the seat the current core renders), legacy seat after it.
2304
+ ctx.slots.inject('plugins.row.config', () =>
2305
+ ctx.slots.register(
2306
+ {
2307
+ name: 'plugins.row.config',
2308
+ key: ROW_CONFIG_KEY,
2309
+ locale: NS,
2310
+ inject: () => ({ ctx })
2311
+ },
2312
+ (props) => React.createElement(PluginCard, Object.assign({}, props, { ctx }))
2313
+ )
2314
+ )
2315
+
2288
2316
  ctx.slots.inject('settings.plugin.item', () =>
2289
2317
  ctx.slots.register(
2290
2318
  {
@@ -2312,5 +2340,6 @@ window.__ModuleLoader__.load({
2312
2340
 
2313
2341
  module.exports = { apply, inject: ['slots', 'locale'] }
2314
2342
  return module.exports
2315
- }
2343
+
2344
+ },
2316
2345
  })
@@ -276,12 +276,13 @@ function json(response, statusCode, value) {
276
276
 
277
277
  export function registerPluginUpdater(ctx, options) {
278
278
  let installing = false
279
- if (typeof ctx?.webServer?.register !== 'function') {
279
+ const webServer = ctx?.get ? (ctx.get('webServer') ?? ctx?.webServer) : ctx?.webServer;
280
+ if (!webServer || typeof webServer.register !== 'function') {
280
281
  ctx?.logger?.warn?.('[dsh-remote-workspace] webServer service unavailable, updater skipped')
281
282
  return () => {}
282
283
  }
283
284
 
284
- return ctx.webServer.register({
285
+ return webServer.register({
285
286
  kind: 'exact',
286
287
  path: options.endpoint,
287
288
  handler: async (request, response) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goodandready/dsh-remote-workspace",
3
- "version": "0.3.2",
3
+ "version": "0.3.4",
4
4
  "description": "Enterprise Remote Workspace Plugin for DeepSeek Harness: SSH2 connection pool, SFTP operations, 3-way conflict-aware mirror sync, port forwarding, and native DSH UI.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -21,7 +21,9 @@
21
21
  ],
22
22
  "scripts": {
23
23
  "build": "tsup",
24
- "test": "node --test test/*.test.mjs"
24
+ "test": "node scripts/build-client.mjs && node --test test/*.test.mjs test/*.test.js",
25
+ "build:client": "node scripts/build-client.mjs",
26
+ "prepack": "node scripts/build-client.mjs"
25
27
  },
26
28
  "keywords": [
27
29
  "deepseek-harness",