@hyzyn/dsh-docker 0.6.1 → 0.6.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/README.en.md +6 -3
- package/README.md +8 -3
- package/client.js +26 -23
- package/lib/index.js +19 -19
- package/lib/index.js.map +1 -1
- package/lib/ssh-exec.js +1 -1
- package/lib/ssh-exec.js.map +1 -1
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
- **"Needs attention" reads authoritative fields**: unhealthy / repeatedly restarting / OOM-killed / non-zero exit / dead; OOM and the real exit code come from one `docker inspect` — the 137 in a `docker ps` summary cannot separate an OOM kill from a manual kill, so filtering on the summary alone must misreport.
|
|
12
12
|
- **Four long-lived SSE streams on one substrate**: log FOLLOW, `docker stats`, `docker events` and `docker pull` all run through the same `openSseStream` (heartbeat / active-stream registry / teardown on disconnect) and differ only in how they end — logs and pulls finish on their own, stats and events are aborted by the browser. Multi-select merged logs recover true cross-container ordering from the `--timestamps` prefix; "pause" freezes rendering only (the stream keeps receiving and flushes in one batch on resume).
|
|
13
13
|
- **Read-only by default, capability switches in three tiers**: start / stop / remove, exec and image mutations are independent switches; while one is off the agent tools are **not registered** and the HTTP routes return 403 (the capability does not exist, rather than failing when called). Container names and IDs pass a whitelist, every command is built as argv with single-quote escaping, and passwords / passphrases are referenced as `env:NAME` (resolved through the official credential layer, falling back to the environment) and never sent back to the browser.
|
|
14
|
-
- **Right-click a log into the agent**: select the failing lines in the log view, then right-click for "send to the current session / fill the input box so I can edit first" — the selection travels with its target, container, time window and 20 lines of context on each side (the menu states plainly that the content enters the model context and may carry credentials). Delivery reports itself twice: a **viewport-level toast** (attached to `body`, above the panel and the terminal modal), and — when the terminal panel is open — an **automatic fold of the terminal** (`minimize()` on the `ttyPanel` v2 contract; sessions keep running and the sidebar "Terminal" entry's badge restores it), so the conversation is simply there. On older tty without that call it degrades to the toast's "the conversation is behind the panel" hint. To edit first, use the draft action — **the session input box is the only editing surface** (multi-line, with the full context in view, and exactly what the agent receives), instead of a second, weaker card editor.
|
|
14
|
+
- **Right-click a log into the agent**: select the failing lines in the log view, then right-click for "send to the current session / fill the input box so I can edit first" — the selection travels with its target, container, time window and 20 lines of context on each side (the menu states plainly that the content enters the model context and may carry credentials). Delivery reports itself twice: a **viewport-level toast** (attached to `body`, above the panel and the terminal modal), and — when the terminal panel is open — an **automatic fold of the terminal** (`minimize()` on the `ttyPanel` v2 contract; sessions keep running and the sidebar "Terminal" entry's badge restores it), so the conversation is simply there. On older tty without that call it degrades to the toast's "the conversation is behind the panel" hint. To edit first, use the draft action — **the session input box is the only editing surface** (multi-line, with the full context in view, and exactly what the agent receives), instead of a second, weaker card editor. Locating the target session is version-tolerant: **≤0.1.5** reads `current` off the `sessions.list` snapshot, while **since 0.1.6** that field moved out of the session domain together with view selection, so it reads `retainedBy.mainView > 0` instead (the same test `dsh-client-ui-session` and this repo's codegraph use) — trusting only the legacy field greys out both menu items as "no session open". The same read drives "carry the containers tab across a session switch".
|
|
15
15
|
- **Data-level reuse of dsh-tty, no code coupling**: no tty code is imported and tty needs no source change, so the two install and upgrade independently; with tty present three optional extension points are consumed — connection-bar actions (`ttyConnbar`), the terminal host (`ttyTerminal`: a new tab under the tab/dock carriers, an in-place drawer under the modal) and the terminal-side dock (`ttyPanel.mountPane`, used only by the fallback path) — and each degrades silently without tty or below the required version.
|
|
16
16
|
|
|
17
17
|
## Relationship with dsh-tty
|
|
@@ -80,7 +80,7 @@ on the right, without getting in the way of watching it work.
|
|
|
80
80
|
| Carrier | When | Behaviour |
|
|
81
81
|
| --- | --- | --- |
|
|
82
82
|
| **Session right-sidebar tab** (default) | the host provides `sidebarRight` / `sidebarRightTabs` | side by side with the conversation; collapsing hides it without losing state (panel-level state lives in a module store, see below); the right sidebar's fullscreen mode gives it the whole viewport |
|
|
83
|
-
| **Dock right of the terminal** | arriving from the **terminal connection bar's** "Containers" button (that button sits on the tty modal, which would hide a tab), or no right-sidebar service / `localStorage['dsh-docker:carrier'] = 'modal'` with tty ≥ 0.16 and its panel open | docked to the right of the terminal panel (resize / collapse / ✕ provided by tty, the terminal stays usable); one dock at a time — docking this plugin takes down the previous occupant (for example tty's own SFTP) |
|
|
83
|
+
| **Dock right of the terminal** | arriving from the **terminal connection bar's** "Containers" button (that button sits on the tty modal, which would hide a tab), or no right-sidebar service / `localStorage['dsh-docker:carrier'] = 'modal'` with tty ≥ 0.16 and its panel open | docked to the right of the terminal panel (resize / collapse / ✕ provided by tty, the terminal stays usable); one dock at a time — docking this plugin takes down the previous occupant (for example tty's own SFTP); since tty 0.18.4 the pane is **owned by the tab it was opened from**: switching tabs hides it, switching back restores it and closing that tab tears it down (while hidden the React tree and polling keep running) |
|
|
84
84
|
| **Full-screen modal** (fallback) | neither of the above | its own backdrop, closes on outside click; the panel sits above tty's modal in z-order |
|
|
85
85
|
|
|
86
86
|
Rolling back to the old shape is one console line: `localStorage.setItem('dsh-docker:carrier', 'modal')`
|
|
@@ -97,7 +97,10 @@ already open with `tail`, so history refills itself.
|
|
|
97
97
|
and `rightbar.session` both declare `scope: 'session'`), so a tab opened in session A does not exist in session B.
|
|
98
98
|
The panel inspects hosts, though, and losing it on a session switch is pure loss — so the plugin additionally
|
|
99
99
|
keeps a "the user wants this open" intent: **switching sessions reopens the tab in the new session**, and only
|
|
100
|
-
clicking the tab's ✕ stops that. The panel follows the person, not the session.
|
|
100
|
+
clicking the tab's ✕ stops that. The panel follows the person, not the session. That ✕ is executed by the
|
|
101
|
+
**host** (`sidebarRight` closes the tab itself), so the plugin learns about it through
|
|
102
|
+
`registerCloseHandler` — relying on the panel's own `onClose` alone would miss the close, and every session
|
|
103
|
+
switch would bring the tab back after the user had just dismissed it.
|
|
101
104
|
|
|
102
105
|
**Dock fallback carrier** (right of the terminal):
|
|
103
106
|
|
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
## 特性
|
|
8
8
|
|
|
9
9
|
- **常驻会话右侧栏**:面板作为会话右侧栏标签(`sidebar.right.pane.tab`)与对话**同屏**——发完错误交给 Agent 后日志留在右边,不影响看它干活;折叠即退出视野、不占屏。面板级状态(目标 / 视图 / 过滤词 / 选中容器及它的页签)**跨会话保留**,而折叠会主动断流、把 SSH 通道还回去。拿不到右侧栏服务的老宿主自动退回原有的 dock / 模态,行为与旧版一致。
|
|
10
|
-
- **日志右键交给 Agent**:日志页拖选报错行 → 右键「直接发送到当前会话 / 填入输入框,我先改改」,把「选中的行 + 目标 / 容器 / 时间窗 + 前后各 20 行上下文」交给会话(内容会进模型上下文,菜单里明写了留意凭证)。投递成功有两处回执:**视口级 toast**(挂 `body`,盖过面板与终端弹窗),以及——终端面板正开着时——**自动折起终端**(`ttyPanel` 契约 v2 的 `minimize()`;会话继续跑,恢复靠侧边栏「终端」入口的徽标),让会话直接露出来。老版本 tty 没有这个能力时退化成 toast 里「会话在面板后面」的指引。需要改稿就先「填入输入框」——**编辑面只有会话输入框一个**(它多行、能看到完整上下文,Agent
|
|
10
|
+
- **日志右键交给 Agent**:日志页拖选报错行 → 右键「直接发送到当前会话 / 填入输入框,我先改改」,把「选中的行 + 目标 / 容器 / 时间窗 + 前后各 20 行上下文」交给会话(内容会进模型上下文,菜单里明写了留意凭证)。投递成功有两处回执:**视口级 toast**(挂 `body`,盖过面板与终端弹窗),以及——终端面板正开着时——**自动折起终端**(`ttyPanel` 契约 v2 的 `minimize()`;会话继续跑,恢复靠侧边栏「终端」入口的徽标),让会话直接露出来。老版本 tty 没有这个能力时退化成 toast 里「会话在面板后面」的指引。需要改稿就先「填入输入框」——**编辑面只有会话输入框一个**(它多行、能看到完整上下文,Agent 收到的就是它),不再另开一张更弱的卡片编辑器。目标会话的定位跨宿主版本:≤0.1.5 读 `sessions.list` 快照的 `current`,**0.1.6 起**该字段随「视图选中项」一起搬出了会话域,改看 `retainedBy.mainView > 0`(官方 `dsh-client-ui-session` 与本地 codegraph 的同一判据)——只认老字段会让菜单判成「当前没有打开的会话」而整组置灰;同一份取值也驱动「切会话把容器标签带过去」。
|
|
11
11
|
- **多目标聚合取数**:总览页对全部 `targets[]` 并行请求,单个目标不可达只污染自己那一格;agent 侧同一口径由 `docker_ps target:"*"` / `docker_attention target:"*"` 暴露,跨目标不互相阻塞。
|
|
12
12
|
- **「需关注」读权威字段**:不健康 / 反复重启 / OOM 被杀 / 非零退出 / 僵死;OOM 与真实退出码由一次 `docker inspect` 补齐——`docker ps` 摘要里的 137 分不出 OOM 与手动 kill,只按摘要筛必然误报。
|
|
13
13
|
- **四条 SSE 长流共用一套基建**:日志 FOLLOW、`docker stats`、`docker events`、`docker pull` 走同一个 `openSseStream`(心跳 / 活跃流登记 / 断开清理),差异只在收尾语义——日志与拉取自然结束,统计与事件由前端主动断。多选聚合日志按 `--timestamps` 前缀还原跨容器真实时序,「暂停」只冻结渲染(流继续接收,恢复时一次性补齐)。
|
|
@@ -70,13 +70,16 @@ add。装完重启 `dsh web`,侧边栏出现「容器」入口;设置 →
|
|
|
70
70
|
视口,开标签会被整个挡住、看着像「点了没反应」。目标照旧带进面板并重挂到那台主机。
|
|
71
71
|
于是规则是「**入口决定承载**」:框架侧边栏点 → 右侧栏标签(与对话同屏);
|
|
72
72
|
终端弹窗里点 → 终端右侧 dock(与终端同屏)。
|
|
73
|
+
dock 面板**归属点它的那个标签**(tty ≥ 0.18.4):切到别的 SSH 标签时整块收起
|
|
74
|
+
(React 树与轮询都保活,切回来恢复原样),关掉该标签则一并收掉;别的标签上再点
|
|
75
|
+
「容器」会用那台主机的目标重开一块。收起 ≠ 关掉:tty 不重挂,面板状态不丢。
|
|
73
76
|
|
|
74
77
|
### 承载形态
|
|
75
78
|
|
|
76
79
|
| 承载 | 何时用 | 行为 |
|
|
77
80
|
| --- | --- | --- |
|
|
78
81
|
| **会话右侧栏标签**(默认) | 宿主提供 `sidebarRight` / `sidebarRightTabs` | 与会话同屏;折叠=退出视野但不丢状态(面板级状态按模块保留,见下);支持右侧栏的 fullscreen 铺满 |
|
|
79
|
-
| **终端右侧 dock** | 从**终端连接栏**的「容器」按钮进来(按钮就在 tty 弹窗上,标签会被它挡住),或拿不到右侧栏服务 / `localStorage['dsh-docker:carrier'] = 'modal'` 且 tty ≥ 0.16 面板开着 | 挂在终端面板右侧(拖宽 / 折叠 / ✕ 由 tty 提供,终端继续可用);同一时刻只挂一个,挂上去会收掉前一个(例如 tty 自己的 SFTP
|
|
82
|
+
| **终端右侧 dock** | 从**终端连接栏**的「容器」按钮进来(按钮就在 tty 弹窗上,标签会被它挡住),或拿不到右侧栏服务 / `localStorage['dsh-docker:carrier'] = 'modal'` 且 tty ≥ 0.16 面板开着 | 挂在终端面板右侧(拖宽 / 折叠 / ✕ 由 tty 提供,终端继续可用);同一时刻只挂一个,挂上去会收掉前一个(例如 tty 自己的 SFTP);tty ≥ 0.18.4 起**归属点它的那个标签**:切走收起、切回恢复、标签关掉一并收掉(收起期间 React 树与轮询保活) |
|
|
80
83
|
| **全屏模态**(兜底) | 上面两条都不成立 | 自带 backdrop、点击外部关闭;面板 z-index 高于 tty 弹窗 |
|
|
81
84
|
|
|
82
85
|
回滚到旧形态只要在控制台执行 `localStorage.setItem('dsh-docker:carrier', 'modal')`
|
|
@@ -92,7 +95,9 @@ add。装完重启 `dsh web`,侧边栏出现「容器」入口;设置 →
|
|
|
92
95
|
`rightbar.session` 都声明 `scope: 'session'`),A 会话开的标签在 B 会话里并不存在。可
|
|
93
96
|
容器面板看的是主机,「切个会话它就没了」是纯损失,所以插件额外记了一个「用户希望它开着」
|
|
94
97
|
的意图:**切会话时自动在新会话里把标签重开**,只有你点了标签的 ✕ 才停止——也就是
|
|
95
|
-
|
|
98
|
+
「面板跟人走,而不是跟会话走」。那个 ✕ 是**宿主**执行的(`sidebarRight` 自己摘标签),
|
|
99
|
+
所以「用户关掉了」这件事必须经 `registerCloseHandler` 登记才收得到:只靠面板自己的
|
|
100
|
+
`onClose` 会漏掉它,于是刚关掉的标签会在每次切会话时自己回来。
|
|
96
101
|
|
|
97
102
|
**dock 兜底形态**(终端右侧栏):
|
|
98
103
|
|