opencode-docker-panel 0.4.8 → 0.5.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 CHANGED
@@ -1,45 +1,70 @@
1
- # Changelog
2
-
3
- All notable changes to this plugin, by version and date. The version is the one in `package.json` at
4
- that commit.
5
-
6
- ## 0.4.8 - 2026-10-04
7
-
8
- - The package now ships precompiled ESM: `npm run build` transpiles the sources with the same
9
- Solid options OpenTUI's own transform uses, and `exports["./tui"]` points at `dist/tui.js`
10
- - `react` dropped: the panel never imported it, and the host rewrites `@opentui/solid` and
11
- `solid-js` to its own runtime when a package under `node_modules` ships JavaScript
12
- - Peer dependencies stay optional, so npm never writes a second Solid or OpenTUI copy next to
13
- the plugin
14
- - `check-build` verifies the built entry imports, claims `sidebar.content`, and releases it on
15
- cleanup
16
-
17
- ## 0.4.1 — 2026-10-04
18
-
19
- - `react` added to peer dependencies, so the panel loads from npm
20
-
21
- ## 0.4.0 — 2026-10-04
22
-
23
- - Sidebar draws running containers only, at most five, with the header opening the full list
24
- - `Pin` and `Unpin` per container, stored by the host and surviving a TUI restart
25
- - `Up stack` starts a compose project from the agent directory, only when the file provably declares
26
- the clicked container's project
27
- - An unstarted stack in the agent directory gets its own line under the rows
28
- - Packaged for npm: `files` allowlist, peer dependencies, repository metadata, npm install docs
29
- - Readme trimmed to what a user needs, with the working install path first
30
-
31
- ## 0.3.0 — 2026-09-30
32
-
33
- - `Start`, `Restart`, `Stop` and `Down compose project` per container, with `Down` confirming first
34
- - Log view in the same dialog, `docker logs --timestamps --tail 200`, streams merged by timestamp
35
- - Terminal recording added to the readme
36
- - CI running typecheck and parser checks on both Linux and Windows
37
-
38
- ## 0.2.0 — 2026-09-29
39
-
40
- - Loads as a CLI-only plugin, no `@opencode/plugin` import at runtime
41
- - A poll that reports no containers clears the panel instead of keeping stale rows
42
-
43
- ## 0.1.0 — 2026-09-29
44
-
1
+ # Changelog
2
+
3
+ All notable changes to this plugin, by version and date. The version is the one in `package.json` at
4
+ that commit.
5
+
6
+ ## 0.5.0 - 2026-10-07
7
+
8
+ - The panel can start and stop Docker Desktop: `Start Docker Desktop` is a clickable line in the
9
+ sidebar, `Stop Docker Desktop` is the last entry of the container list and is available even with no
10
+ containers at all
11
+ - `Stop` confirms first and names the running containers it can see, because an app-level stop ends
12
+ every container of every project
13
+ - Engine state comes from a `docker desktop status` probe rather than from `docker ps`, which reports a
14
+ stopped engine as an unavailable socket and cannot tell it apart from a missing CLI
15
+ - The probe waits up to nine seconds: measured, the CLI plugin takes 3.5 to 4.5 seconds to answer when
16
+ Docker is stopped, and a shorter timeout turned a provable `stopped` into an unknown state with no
17
+ buttons at all
18
+ - Log polling stops while the engine is down instead of spawning a doomed `docker logs` every two
19
+ seconds; the window keeps its last lines and does not resume by itself
20
+ - Readme trimmed to install and verification, with the behaviour, the demos and the limits moved to
21
+ `docs/features.md` and `docs/features.ru.md`
22
+ - Compose project names derived from a directory are normalized the way compose normalizes them, so an
23
+ uppercase directory like `CarManufacturersMVC` starts as `carmanufacturersmvc` instead of being
24
+ rejected as an invalid project name
25
+ - A compose project name that compose would reject, or one that normalizes to nothing, no longer
26
+ offers a button at all
27
+ - A stopped engine is read from `docker ps` failing on a missing `dockerDesktopLinuxEngine` pipe, which
28
+ takes a quarter of a second instead of the four seconds `docker desktop status` needs, so the
29
+ `Start Docker Desktop` line shows up right away
30
+
31
+ ## 0.4.8 - 2026-10-04
32
+
33
+ - The package now ships precompiled ESM: `npm run build` transpiles the sources with the same
34
+ Solid options OpenTUI's own transform uses, and `exports["./tui"]` points at `dist/tui.js`
35
+ - `react` dropped: the panel never imported it, and the host rewrites `@opentui/solid` and
36
+ `solid-js` to its own runtime when a package under `node_modules` ships JavaScript
37
+ - Peer dependencies stay optional, so npm never writes a second Solid or OpenTUI copy next to
38
+ the plugin
39
+ - `check-build` verifies the built entry imports, claims `sidebar.content`, and releases it on
40
+ cleanup
41
+
42
+ ## 0.4.1 — 2026-10-04
43
+
44
+ - `react` added to peer dependencies, so the panel loads from npm
45
+
46
+ ## 0.4.0 — 2026-10-04
47
+
48
+ - Sidebar draws running containers only, at most five, with the header opening the full list
49
+ - `Pin` and `Unpin` per container, stored by the host and surviving a TUI restart
50
+ - `Up stack` starts a compose project from the agent directory, only when the file provably declares
51
+ the clicked container's project
52
+ - An unstarted stack in the agent directory gets its own line under the rows
53
+ - Packaged for npm: `files` allowlist, peer dependencies, repository metadata, npm install docs
54
+ - Readme trimmed to what a user needs, with the working install path first
55
+
56
+ ## 0.3.0 — 2026-09-30
57
+
58
+ - `Start`, `Restart`, `Stop` and `Down compose project` per container, with `Down` confirming first
59
+ - Log view in the same dialog, `docker logs --timestamps --tail 200`, streams merged by timestamp
60
+ - Terminal recording added to the readme
61
+ - CI running typecheck and parser checks on both Linux and Windows
62
+
63
+ ## 0.2.0 — 2026-09-29
64
+
65
+ - Loads as a CLI-only plugin, no `@opencode/plugin` import at runtime
66
+ - A poll that reports no containers clears the panel instead of keeping stale rows
67
+
68
+ ## 0.1.0 — 2026-09-29
69
+
45
70
  - First version: Docker containers in the `sidebar.content` slot, polled from `docker ps`
package/README.md CHANGED
@@ -1,108 +1,20 @@
1
1
  # opencode-docker-panel
2
2
 
3
3
  [![CI](https://github.com/victor-ochenin/opencodeDockerPlugin/actions/workflows/ci.yml/badge.svg)](https://github.com/victor-ochenin/opencodeDockerPlugin/actions/workflows/ci.yml)
4
+ [![npm](https://img.shields.io/npm/v/opencode-docker-panel.svg)](https://www.npmjs.com/package/opencode-docker-panel)
4
5
 
5
- A Docker container panel for the OpenCode 2 TUI sidebar.
6
+ A Docker container panel for the OpenCode 2 TUI sidebar, with Docker Desktop control.
6
7
 
7
- The panel appends itself to the `sidebar.content` slot, polls `docker ps --all --format "{{json .}}"`, and lets you act on a container from the row itself. Clicking a row opens a dialog with the actions docker accepts for that container's current state; `Down` is the only one that asks for confirmation.
8
+ ![The Docker panel in a session sidebar](docs/demo2.gif)
8
9
 
9
- Русская версия этого файла: [README.ru.md](README.ru.md)
10
-
11
- ![The Docker panel in the session sidebar, with an unstarted compose stack from the agent directory](docs/demo2.gif)
12
-
13
- ## Contents
14
-
15
- - [What it does](#what-it-does)
16
- - [Compose stacks](#compose-stacks)
17
- - [Logs](#logs)
18
- - [What it shows](#what-it-shows)
19
- - [Requirements](#requirements)
20
- - [Install](#install)
21
- - [Option A: let an LLM do it](#option-a-let-an-llm-do-it)
22
- - [Option B: manual setup](#option-b-manual-setup)
23
- - [From a local checkout](#from-a-local-checkout)
24
- - [Verification](#verification)
25
- - [Options](#options)
26
- - [Known limits](#known-limits)
27
- - [Changelog](#changelog)
28
- - [License](#license)
29
-
30
- ## What it does
31
-
32
- ```text
33
- Docker (2)
34
- • api 0.0.0.0:8080->8080/tcp · shop
35
- 1 more, click for all
36
- Up stack · storefront is not running here
37
- ```
38
-
39
- | Container state | Actions offered |
40
- |---|---|
41
- | `running`, `restarting`, `paused` | `Restart`, `Stop`, and `Down` when the container belongs to a compose project |
42
- | `created`, `exited`, `dead` | `Start`, `Up stack` when the agent directory holds a matching compose file, and `Down` when the container belongs to a compose project |
43
- | anything else | none |
44
-
45
- | Action | Command |
46
- |---|---|
47
- | Start | `docker start -- <name>` |
48
- | Up stack | `docker compose -f <file> -p <project> up -d` |
49
- | Restart | `docker restart -- <name>` |
50
- | Stop | `docker stop -- <name>` |
51
- | Down | `docker compose -p <project> down` |
52
-
53
- `--` is not optional: a container name may start with a dash, and without the separator docker reads it as a flag. Every option shows its exact command in the dialog footer, so the destructive one is never a surprise.
54
-
55
- ## Compose stacks
56
-
57
- `Up stack` starts a whole compose project instead of one container, using the compose file that sits in the agent directory. That file is executable content: it carries `build`, `command` and `entrypoint`, which is why the dialog shows the exact command before you run it, and why `up` needs no confirmation while `down` does.
58
-
59
- The button appears only when the file provably belongs to the project of the container you clicked. The project name is read the way compose v2 reads it: a top-level `name:` if there is one, otherwise the name of the directory holding the file. It must equal the `com.docker.compose.project` label on the container, and the container must not be running already. Anything else and the button is simply absent, because a wrong stack is worse than no button.
60
-
61
- A stack that has no containers at all is the normal state of something never started, and it gets its own way in. When the agent directory holds a compose file and no container on the machine carries that project label, the panel adds a line under the rows:
62
-
63
- ```text
64
- Up stack · storefront is not running here
65
- ```
66
-
67
- Clicking it asks once, showing the exact command before anything runs, because a compose file is executable content and this stack has no container to name it. The line disappears as soon as one container of that project shows up, because from then on the per-container `Up stack` is the way in. Nothing is offered for a Dockerfile on its own: there is no image name to run, so the panel would be guessing.
68
-
69
- The project is passed twice, as `-f <file>` and `-p <project>`. The name inside a compose file can be templated or overridden by the environment, and `-p` makes sure the stack you start is the one the panel was already showing rather than a second copy of it.
70
-
71
- Candidate file names are tried in compose's own order: `compose.yaml`, `compose.yml`, `docker-compose.yaml`, `docker-compose.yml`. The first file that exists wins even when it declares another project, because that is the file compose itself would use, so falling through to the next candidate would offer a stack the CLI ignores.
72
-
73
- `Down` runs `docker compose down` against the compose project the container carries in its labels, which stops every container of that project and removes their networks. Volumes are kept, and the confirmation dialog says so. A container with no compose project never gets the option, and `buildArgs` refuses it as well.
74
-
75
- The result of every action arrives as a toast, and the panel refreshes immediately instead of waiting for the next poll. While a command runs the header shows `working` and further clicks are ignored, so a double click cannot launch two commands.
76
-
77
- ## Logs
78
-
79
- `Logs` in the same menu replaces the dialog contents with a log view for that container, so the log and the actions share one window. It closes with `esc` or by clicking the footer line.
80
-
81
- The view is `docker logs --timestamps --tail 200 -- <name>`, refreshed every two seconds while it is open. Docker interleaves the container's two streams, so the two buffers are parsed separately and merged back by timestamp; without that the log reads all of stdout first. ANSI sequences and lone `CR` are stripped, because the terminal would otherwise run them as control codes. A fixed window of fifteen lines is scrolled with the mouse wheel.
82
-
83
- ## What it shows
84
-
85
- The dot is coloured by container state: green for `running`, yellow for `paused` and `restarting`, red for `dead`, muted for everything else. The panel draws running containers and nothing else, at most five rows in the order docker reports them, so the list does not jump between polls. Stopped containers never get a row of their own: the header opens a dialog with every container, and picking one there opens the same actions as a click on its row. A `N more, click for all` line appears under the rows when something is still hidden. With rows to show, the header collapses and expands them instead.
86
-
87
- `Pin` in a container's menu keeps that container visible whatever its state, and it spends the five row budget when it happens to run, so pinning everything shows everything. A pin is stored by the host, so it survives a TUI restart and applies to every session; `Unpin` in the same menu drops it. Pinned rows are marked `pinned` next to their ports and project.
88
-
89
- | State | Panel output |
90
- |---|---|
91
- | Docker up with containers | `Docker (N)` plus one row per container |
92
- | Docker up, nothing created | `no containers` |
93
- | Docker Desktop not running | `docker desktop not running` |
94
- | Docker not installed | `docker not installed` |
95
- | `docker ps` timed out | last known rows with a `stale` marker |
96
- | No permission on the Docker socket | `no permission to talk to docker` |
97
-
98
- A missing or stopped Docker is a normal state, not a plugin failure, so it is reported as a muted line rather than an error. Any failed poll, whether a timeout or a dead daemon, keeps the last known rows with a `stale` marker instead of blanking the panel; a successful poll that reports no containers clears the list.
10
+ What it does, with demos: [docs/features.md](docs/features.md). Русская версия этого файла:
11
+ [README.ru.md](README.ru.md), демонстрации на русском — [docs/features.ru.md](docs/features.ru.md).
99
12
 
100
13
  ## Requirements
101
14
 
102
15
  - OpenCode 2 runtime with plugin slots (`opencode2`)
103
- - `docker` on `PATH`: Docker Desktop on Windows, Docker Engine on Linux and macOS
104
-
105
- The panel's own strings are English only; the documentation is bilingual.
16
+ - `docker` on `PATH`. Starting and stopping Docker Desktop needs its `docker desktop` CLI plugin
17
+ and works on Windows only
106
18
 
107
19
  ## Install
108
20
 
@@ -117,7 +29,8 @@ https://github.com/victor-ochenin/opencodeDockerPlugin#installation
117
29
 
118
30
  ### Option B: manual setup
119
31
 
120
- Add the plugin to `~/.config/opencode/cli.json`. Create the file if it does not exist and keep whatever is already in it.
32
+ Add the plugin to `~/.config/opencode/cli.json`. Create the file if it does not exist and keep
33
+ whatever is already in it.
121
34
 
122
35
  ```jsonc
123
36
  {
@@ -128,43 +41,33 @@ Add the plugin to `~/.config/opencode/cli.json`. Create the file if it does not
128
41
 
129
42
  Two things trip people up here, so they are worth stating plainly:
130
43
 
131
- - **It goes in `cli.json`, not `opencode.json`.** This is a terminal-only plugin: it draws in the sidebar, and `cli.json` is the file the terminal client reads.
132
- - **There is no login step and no provider to configure.** It talks to the local `docker` CLI and nothing else.
133
-
134
- Restart the TUI afterwards. The host installs the package on the next start; nothing to copy and nothing to build.
135
-
136
- Pin a version when you want a known state: `{ "package": "opencode-docker-panel@0.4.1" }`.
44
+ - **It goes in `cli.json`, not `opencode.json`.** This is a terminal-only plugin: it draws in the
45
+ sidebar, and `cli.json` is the file the terminal client reads.
46
+ - **There is no login step and no provider to configure.** It talks to the local `docker` CLI and
47
+ nothing else.
137
48
 
138
- ### From a local checkout
49
+ Restart the TUI afterwards. The host installs the package on the next start; nothing to copy and
50
+ nothing to build.
139
51
 
140
- To run the plugin straight from a clone instead, copy the files into the OpenCode config directory. On Windows that is `%USERPROFILE%\.config\opencode\plugins\docker-panel\`.
141
-
142
- ```powershell
143
- $src = "path\to\opencodeDockerPlugin"
144
- $dst = "$HOME\.config\opencode\plugins\docker-panel"
145
- New-Item -ItemType Directory -Force -Path $dst | Out-Null
146
- Copy-Item "$src\*.ts","$src\*.tsx","$src\package.json" -Destination $dst -Force
147
- ```
148
-
149
- ```jsonc
150
- {
151
- "$schema": "https://opencode.ai/v2/cli.json",
152
- "plugins": [{ "package": "./plugins/docker-panel", "options": { "intervalMs": 3000 } }]
153
- }
154
- ```
155
-
156
- The package ships TypeScript sources and OpenCode resolves them at runtime, so there is no build step. `solid-js`, the OpenTUI packages and the OpenCode SDK are peer dependencies rather than hard dependencies, so a second copy of the SDK cannot shadow the one the host is running.
52
+ Pin a version when you want a known state: `{ "package": "opencode-docker-panel@0.5.0" }`.
157
53
 
158
54
  ### Verification
159
55
 
160
- There is no CLI check for this one: the plugin draws in the terminal UI, so `opencode run` will never show it. Verify in the TUI.
56
+ There is no CLI check for this one: the plugin draws in the terminal UI, so `opencode run` will
57
+ never show it. Verify in the TUI.
161
58
 
162
- 1. `docker ps` returns at least one container. If it fails, the panel has nothing to draw and says so.
59
+ 1. `docker ps` returns at least one container. If it fails, the panel has nothing to draw and says
60
+ so.
163
61
  2. Restart the TUI and open a session.
164
- 3. The sidebar gets a `Docker` header with a container count. Running containers appear as rows, at most five of them, with a `N more, click for all` line under them when something is still hidden.
165
- 4. Collapse the list with a click on `Docker`, then click it again to open the full list. Pick a container to get its actions menu.
62
+ 3. The sidebar gets a `Docker` header with a container count. Running containers appear as rows, at
63
+ most five of them, with a `N more, click for all` line under them when something is still hidden.
64
+ 4. Click `Docker` to collapse the list, then click it again to open the full list. Pick a container
65
+ to get its actions menu, and the last entry there is `Stop Docker Desktop`.
166
66
 
167
- If the header never appears, the plugin did not load: check that the entry is in `cli.json` under `plugins`, and check `~/.local/share/opencode/log/opencode.log` for a load error.
67
+ Stop Docker Desktop and the sidebar gets a clickable `Start Docker Desktop` line instead of a line of text.
68
+
69
+ If the header never appears, the plugin did not load: check that the entry is in `cli.json` under
70
+ `plugins`, and check `~/.local/share/opencode/log/opencode.log` for a load error.
168
71
 
169
72
  ## Options
170
73
 
@@ -172,18 +75,8 @@ If the header never appears, the plugin did not load: check that the entry is in
172
75
  |---|---|---|
173
76
  | `intervalMs` | `3000` | Poll interval, clamped to 1000..60000 |
174
77
 
175
- ## Known limits
176
-
177
- - The sidebar draws containers that are `running` and nothing else. A `paused` or `restarting` container gets no row even though docker still counts it as alive; pin it to see it.
178
- - OpenCode 2 is in beta, so slot names and theme tokens may change.
179
- - A repaint workaround resets the collapsed state and closes an open log view when the container list really changes.
180
- - The poll spawns `docker ps` on an interval. On a host with hundreds of containers, raise `intervalMs` to 5000 or higher.
181
- - At most five running containers get a row, and the five is a constant rather than an option: a host with thirty containers shows five and leaves the rest to the dialog. Pinning is the only way to promote a sixth.
182
- - The sidebar itself cannot scroll, so the containers past the five live in the dialog rather than in the panel.
183
- - No exec, no volume or image actions, no restart history. `Down` is offered per container but acts on the whole compose project. The log view is a fixed window over the last 200 lines with no history beyond that.
184
- - `Up stack` only ever starts a stack whose compose file sits in the agent directory. A project that was created somewhere else can still be torn down with `Down`, but it can only be started with `Start` on a single container.
185
- - `Up stack` may stay hidden when the compose file declares its project in a form the panel cannot read, such as an indented `name:` or a quoted value. That is a refusal rather than a wrong stack.
186
- - Actions are mouse-only; the plugin registers no keymap layer.
78
+
79
+ Everything else lives in [docs/features.md](docs/features.md).
187
80
 
188
81
  ## Changelog
189
82
 
package/README.ru.md CHANGED
@@ -1,108 +1,19 @@
1
1
  # opencode-docker-panel
2
2
 
3
3
  [![CI](https://github.com/victor-ochenin/opencodeDockerPlugin/actions/workflows/ci.yml/badge.svg)](https://github.com/victor-ochenin/opencodeDockerPlugin/actions/workflows/ci.yml)
4
+ [![npm](https://img.shields.io/npm/v/opencode-docker-panel.svg)](https://www.npmjs.com/package/opencode-docker-panel)
4
5
 
5
- Панель контейнеров Docker для бокового сайдбара OpenCode 2.
6
-
7
- Плагин добавляет себя в слот `sidebar.content`, опрашивает `docker ps --all --format "{{json .}}"` и позволяет действовать с контейнером прямо из строки. Клик по строке открывает диалог с командами, которые docker принимает в текущем состоянии контейнера, и только `Down` спрашивает подтверждение.
8
-
9
- English version of this file: [README.md](README.md)
6
+ Панель контейнеров Docker для бокового сайдбара OpenCode 2, с управлением Docker Desktop.
10
7
 
11
8
  ![Панель Docker в сайдбаре сессии с незапущенным compose-стеком из каталога агента](docs/demo2.gif)
12
9
 
13
- ## Содержание
14
-
15
- - [Что показывает панель](#что-показывает-панель)
16
- - [Действия](#действия)
17
- - [Compose-стек](#compose-стек)
18
- - [Логи](#логи)
19
- - [Требования](#требования)
20
- - [Установка](#установка)
21
- - [Вариант A: пусть сделает LLM](#вариант-a-пусть-сделает-llm)
22
- - [Вариант B: вручную](#вариант-b-вручную)
23
- - [Из локального клона](#из-локального-клона)
24
- - [Проверка](#проверка)
25
- - [Опции](#опции)
26
- - [Ограничения](#ограничения)
27
- - [Изменения](#изменения)
28
- - [Лицензия](#лицензия)
29
-
30
- ## Что показывает панель
31
-
32
- ```text
33
- Docker (2)
34
- • api 0.0.0.0:8080->8080/tcp · shop
35
- 1 more, click for all
36
- Up stack · storefront is not running here
37
- ```
38
-
39
- Цвет точки зависит от состояния: зелёный для `running`, жёлтый для `paused` и `restarting`, красный для `dead`, приглушённый для остальных. Панель рисует только запущенные контейнеры, не больше пяти строк в том порядке, в котором их отдаёт docker, поэтому список не прыгает между опросами. Остановленным контейнерам строки не достаётся: вход в них — заголовок, он открывает диалог со всеми контейнерами, а выбор контейнера там открывает те же действия, что и клик по его строке. Строка `N more, click for all` стоит под строками, если что-то ещё скрыто. Когда строки есть, заголовок сворачивает и разворачивает их.
40
-
41
- Пункт `Pin` в меню контейнера оставляет контейнер видимым независимо от состояния, и на запущенном он занимает место в бюджете из пяти строк, поэтому закрепив всё, видно всё. Закрепление хранит хост, поэтому оно переживает перезапуск TUI и действует во всех сессиях; пункт `Unpin` в том же меню снимает его. Закреплённые строки помечены `pinned` рядом с портами и проектом.
42
-
43
- | Состояние панели | Что видно |
44
- |---|---|
45
- | Docker работает, есть контейнеры | `Docker (N)` и по строке на контейнер |
46
- | Docker работает, контейнеров нет | `no containers` |
47
- | Docker Desktop не запущен | `docker desktop not running` |
48
- | Docker не установлен | `docker not installed` |
49
- | `docker ps` не ответил вовремя | последние известные строки с пометкой `stale` |
50
- | Нет прав на сокет Docker | `no permission to talk to docker` |
51
-
52
- Остановленный или отсутствующий Docker — это нормальное состояние, а не поломка плагина, поэтому оно показывается приглушённой строкой, а не ошибкой. Любой неудачный опрос, будь то таймаут или мёртвый демон, сохраняет последние известные строки с пометкой `stale`; успешный опрос без контейнеров очищает список.
53
-
54
- ## Действия
55
-
56
- | Состояние контейнера | Какие действия предлагаются |
57
- |---|---|
58
- | `running`, `restarting`, `paused` | `Restart`, `Stop` и `Down`, если контейнер принадлежит compose-проекту |
59
- | `created`, `exited`, `dead` | `Start`, `Up stack`, если в каталоге агента лежит подходящий compose-файл, и `Down`, если контейнер принадлежит compose-проекту |
60
- | любое другое | ничего |
61
-
62
- | Действие | Команда |
63
- |---|---|
64
- | Start | `docker start -- <имя>` |
65
- | Up stack | `docker compose -f <файл> -p <проект> up -d` |
66
- | Restart | `docker restart -- <имя>` |
67
- | Stop | `docker stop -- <имя>` |
68
- | Down | `docker compose -p <проект> down` |
69
-
70
- Разделитель `--` обязателен: имя контейнера может начинаться с дефиса, и без разделителя docker примет его за флаг. Точная команда показана в подписи каждого пункта, поэтому разрушительная не выглядит сюрпризом.
71
-
72
- `Down` выполняет `docker compose down` для compose-проекта из лейблов контейнера: останавливает все контейнеры проекта и удаляет их сети. Тома остаются, о чём и говорит диалог подтверждения. Контейнеру без compose-проекта пункт не предлагается, и `buildArgs` его тоже отклоняет.
73
-
74
- Результат каждого действия приходит тостом, а панель обновляется сразу, не дожидаясь следующего опроса. Пока команда выполняется, в заголовке горит `working` и повторные клики игнорируются, так что двойной клик не запустит две команды.
75
-
76
- ## Compose-стек
77
-
78
- `Up stack` поднимает весь compose-проект, а не один контейнер, и берёт compose-файл из каталога агента. Такой файл — исполняемое содержимое: в нём бывают `build`, `command` и `entrypoint`, поэтому диалог сначала показывает точную команду и подтверждения, в отличие от `down`, не требует.
79
-
80
- Пункт появляется только когда файл доказуемно принадлежит проекту контейнера, по которому кликнули. Имя проекта читается так же, как это делает compose v2: явное `name:` верхнего уровня, если оно есть, иначе имя каталога, где лежит файл. Оно должно совпасть с лейблом `com.docker.compose.project` контейнера, а сам контейнер не должен быть уже запущен. Во всех остальных случаях пункта просто нет, потому что не тот стек хуже, чем отсутствие кнопки.
81
-
82
- Проект передаётся дважды, как `-f <файл>` и `-p <проект>`. Имя внутри файла может быть шаблонным или перебитым окружением, а `-p` гарантирует, что поднимется тот самый проект, который панель уже показывает, а не его вторая копия.
83
-
84
- Стек, у которого нет ни одного контейнера, — обычное состояние того, что никогда не запускали, и для него сделана отдельная входная точка. Когда в каталоге агента лежит compose-файл и на машине нет ни одного контейнера с таким лейблом проекта, под строками появляется строка:
85
-
86
- ```text
87
- Up stack · storefront is not running here
88
- ```
89
-
90
- Клик по ней один раз спрашивает, показывая точную команду до запуска: compose-файл это исполняемое содержимое, а у стека нет контейнера, которым можно назвать действие. Как только появится хоть один контейнер этого проекта, строка исчезает: дальше входом служит `Up stack` у самого контейнера. Один Dockerfile без compose-файла ничего не предлагает: запускать нечего без имени образа, и панель догадывалась бы.
91
-
92
- Кандидаты проверяются в том же порядке, что и у compose: `compose.yaml`, `compose.yml`, `docker-compose.yaml`, `docker-compose.yml`. Первый существующий файл побеждает, даже если объявляет другой проект, потому что именно его использовал бы сам compose: если продолжить поиск, кнопка предложила бы стек, который CLI игнорирует.
93
-
94
- ## Логи
95
-
96
- Пункт `Logs` в том же меню перезаписывает содержимое окна логами контейнера, то есть логи и действия делят одно окно. Закрывается через `esc` или кликом по нижней строке.
97
-
98
- Просмотр — это `docker logs --timestamps --tail 200 -- <имя>`, обновление раз в две секунды, пока окно открыто. Docker пишет потоки контейнера вперемешку, поэтому буферы разбираются отдельно и снова сливаются по времени: без этого лог читался бы сначала целиком из stdout. ANSI-последовательности и одиночные `CR` вырезаются, иначе терминал выполнил бы их как управляющие коды. Окно фиксированной высоты в пятнадцать строк прокручивается колесом мыши.
10
+ Что она умеет, с демонстрациями: [docs/features.ru.md](docs/features.ru.md). English version of this file:
11
+ [README.md](README.md), demos in English — [docs/features.md](docs/features.md).
99
12
 
100
13
  ## Требования
101
14
 
102
15
  - Рантайм OpenCode 2 со слотами плагинов (`opencode2`)
103
- - `docker` в `PATH`: Docker Desktop на Windows, Docker Engine на Linux и macOS
104
-
105
- Строки панели только английские, документация двуязычная.
16
+ - `docker` в `PATH`. Запуск и остановка Docker Desktop требуют CLI-плагина `docker desktop` и работают только на Windows
106
17
 
107
18
  ## Установка
108
19
 
@@ -133,27 +44,7 @@ https://github.com/victor-ochenin/opencodeDockerPlugin#installation
133
44
 
134
45
  После этого перезапусти TUI: хост сам поставит пакет при следующем старте, копировать и собирать ничего не нужно.
135
46
 
136
- Если нужна зафиксированная версия, укажи её явно: `{ "package": "opencode-docker-panel@0.4.1" }`.
137
-
138
- ### Из локального клона
139
-
140
- Чтобы запускать плагин прямо из клона, скопируй файлы в конфиг-каталог OpenCode. На Windows это `%USERPROFILE%\.config\opencode\plugins\docker-panel\`.
141
-
142
- ```powershell
143
- $src = "path\to\opencodeDockerPlugin"
144
- $dst = "$HOME\.config\opencode\plugins\docker-panel"
145
- New-Item -ItemType Directory -Force -Path $dst | Out-Null
146
- Copy-Item "$src\*.ts","$src\*.tsx","$src\package.json" -Destination $dst -Force
147
- ```
148
-
149
- ```jsonc
150
- {
151
- "$schema": "https://opencode.ai/v2/cli.json",
152
- "plugins": [{ "package": "./plugins/docker-panel", "options": { "intervalMs": 3000 } }]
153
- }
154
- ```
155
-
156
- Пакет уходит исходниками на TypeScript, их резолвит сам OpenCode, поэтому собирать нечего. `solid-js`, пакеты OpenTUI и SDK OpenCode объявлены пирами, а не жёсткими зависимостями, поэтому вторая копия SDK не перекроет ту, которой работает хост.
47
+ Если нужна зафиксированная версия, укажи её явно: `{ "package": "opencode-docker-panel@0.5.0" }`.
157
48
 
158
49
  ### Проверка
159
50
 
@@ -161,8 +52,10 @@ CLI-проверки у этого плагина нет: он рисуется
161
52
 
162
53
  1. `docker ps` возвращает хотя бы один контейнер. Если команда падает, панели нечего рисовать, и она так и скажет.
163
54
  2. Перезапусти TUI и открой сессию.
164
- 3. В сайдбаре появится заголовок `Docker` со счётчиком контейнеров. Запущенные контейнеры станут строками, не больше пяти, а под ними — строка `N more, click for all`, если что-то ещё скрыто.
165
- 4. Кликни по `Docker`, чтобы свернуть список, и ещё раз, чтобы открыть полный. Выбери контейнер — откроется меню его действий.
55
+ 3. В сайдбаре появится заголовок `Docker` со счётчиком контейнеров. Запущенные контейнеры станут строками, не больше пяти, а под ними — строка `N more, click for all`, если что-то ещё скрыто. Если Docker остановлен, под заголовком будет кликабельная строка `Start Docker Desktop` вместо текста.
56
+ 4. Кликни по `Docker`, чтобы свернуть список, и ещё раз, чтобы открыть полный. Выбери контейнер — откроется меню его действий, а последней позицией в том же списке будет `Stop Docker Desktop`.
57
+
58
+ Останови Docker Desktop — вместо текста в сайдбаре появится кликабельная строка `Start Docker Desktop`.
166
59
 
167
60
  Если заголовок так и не появился, плагин не загрузился: проверь, что запись лежит в `cli.json` в секции `plugins`, и посмотри `~/.local/share/opencode/log/opencode.log` на предмет ошибки загрузки.
168
61
 
@@ -172,18 +65,8 @@ CLI-проверки у этого плагина нет: он рисуется
172
65
  |---|---|---|
173
66
  | `intervalMs` | `3000` | Интервал опроса, ограничивается диапазоном 1000..60000 |
174
67
 
175
- ## Ограничения
176
-
177
- - Сайдбар рисует только контейнеры в состоянии `running`. `paused` и `restarting` строки не получают, хотя docker считает их живыми, — чтобы увидеть такой контейнер, закрепи его.
178
- - OpenCode 2 находится в бета-фазе, поэтому имена слотов и токены темы могут измениться.
179
- - Обходное решение с перерисовкой сбрасывает свёрнутое состояние и закрывает открытое окно логов, когда список контейнеров действительно меняется.
180
- - Опрос порождает `docker ps` с интервалом. На машине с сотнями контейнеров подними `intervalMs` до 5000 или выше.
181
- - Строк не больше пяти, и пять — константа, а не опция: на машине с тридцатью контейнерами панель покажет пять, а остальные останутся в диалоге. Единственный способ вывести шестой — закрепить его.
182
- - Сам сайдбар не прокручивается, поэтому контейнеры за пределами пяти живут в диалоге, а не в панели.
183
- - Нет exec, работы с томами и образами, истории перезапусков. `Down` предлагается у контейнера, но действует на весь compose-проект. Окно логов — фиксированное окно поверх последних 200 строк, истории глубже нет.
184
- - `Up stack` поднимает только стек, чей compose-файл лежит в каталоге агента. Проект, созданный в другом месте, всё равно можно снести через `Down`, но поднять его можно только `Start` на одном контейнере.
185
- - `Up stack` может остаться скрытым, когда compose-файл объявляет проект в форме, которую панель прочитать не может: например, `name:` с отступом или в кавычках. Это отказ, а не неверный запуск.
186
- - Действия только мышью; слой клавиш плагин не регистрирует.
68
+
69
+ Всё остальное — в [docs/features.ru.md](docs/features.ru.md).
187
70
 
188
71
  ## Изменения
189
72
 
package/dist/commands.js CHANGED
@@ -10,12 +10,12 @@ export const ACTION_LABEL = {
10
10
  down: "Down compose project"
11
11
  };
12
12
 
13
- /** The name is passed after `--` because a container name may start with a dash and docker would read it as a flag. */
13
+ /** The name goes after `--` because a container name may start with a dash and docker reads it as a flag */
14
14
  export function buildArgs(action, container, target) {
15
15
  if (action === "up") {
16
16
  if (!target) throw new Error(`container ${container.name} has no resolved compose target`);
17
- // Both flags are explicit: the project name in the file can be templated or overridden by the
18
- // environment, and this way `up` acts on the very project the panel is already showing.
17
+ // Both flags are explicit because the project's `name:` can be templated or overridden by the
18
+ // environment, and this way `up` acts on the project the panel is already showing
19
19
  return ["compose", "-f", target.file, "-p", target.project, "up", "-d"];
20
20
  }
21
21
  if (action === "down") {
@@ -26,7 +26,7 @@ export function buildArgs(action, container, target) {
26
26
  return [action, "--", container.name];
27
27
  }
28
28
 
29
- /** Only offers what docker accepts for the current state, with the destructive action last. */
29
+ /** Only what docker accepts for the current state, with the destructive action last */
30
30
  export function availableActions(container, target) {
31
31
  const down = container.composeProject ? ["down"] : [];
32
32
  const up = container.composeProject && target ? ["up"] : [];
@@ -49,8 +49,10 @@ function firstLine(text) {
49
49
  return line.length > 80 ? `${line.slice(0, 77)}...` : line;
50
50
  }
51
51
  /**
52
- * Runs an already-built argument list. `up` has no container behind it, so the boundary takes the
53
- * argv rather than a container the caller would have to invent to satisfy the type.
52
+ * Runs an already-built argument list.
53
+ *
54
+ * `up` has no container behind it, so the boundary takes the argv rather than a container the caller
55
+ * would have to invent to satisfy the type.
54
56
  */
55
57
  export function runDockerArgs(args) {
56
58
  return new Promise(resolve => {