revdeck 0.1.0 → 0.2.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
@@ -6,6 +6,31 @@ All notable changes to this project are documented here. The format is based on
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.2.0] - 2026-11-12
10
+
11
+ ### Added
12
+
13
+ - Reactions on platform comments: thread cards in the UI, `revdeck react --note <id> --emoji <name>`,
14
+ and the `reactions.list` / `reactions.toggle` RPC methods. Existing reactions and the current user's
15
+ choice are shown for GitLab and GitHub.
16
+ - `revdeck eject`: removes the config, installed skills and command files, the `revdeck` MCP entry and
17
+ the local cache from a repository. It is preview-only without `--yes` and leaves foreign files and
18
+ other MCP servers intact.
19
+ - Attachments for comments: the UI **Attach** button and `revdeck attach` upload images and videos
20
+ through the host daemon. GitLab project uploads return absolute URLs, relative `/uploads/` links are
21
+ normalized to the platform host during publish, and the sanitizer allows images only from that host.
22
+ Only raster images and videos with matching extension, MIME and file signature are accepted.
23
+ - Devcontainer support: `revdeck devcontainer --write` mounts the host runtime and state directories,
24
+ sets `REVDECK_*` variables and marks the container, so revdeck reuses the host daemon and never runs
25
+ `gh`/`glab` inside. `revdeck doctor` checks the host daemon in this mode; `revdeck daemon start
26
+ --host` exposes the HTTP UI, and `revdeck eject` removes the generated mounts/env.
27
+
28
+ ### Fixed
29
+
30
+ - `revdeck init` keeps one canonical skill in `.agents/skills/revdeck` (now including
31
+ `agents/openai.yaml`) and links `.claude/skills/revdeck` to it instead of copying the procedure files.
32
+ A copy is used only on platforms without symlink support.
33
+
9
34
  ## [0.1.0] - 2026-11-11
10
35
 
11
36
  First public release.
package/CONTRIBUTING.md CHANGED
@@ -56,8 +56,9 @@ Rules of thumb:
56
56
 
57
57
  ## Adding a harness adapter
58
58
 
59
- Add a `SPECS` entry in `src/cli/init.ts` with the skill target, MCP config path or command file, then
60
- document it in `docs/integrations.md`. `init` must never overwrite files it does not own.
59
+ Add a `SPECS` entry in `src/cli/init.ts` with the MCP config path, command file or `linkSkill` flag, then
60
+ document it in `docs/integrations.md`. The canonical skill is always `.agents/skills/revdeck`; adapters
61
+ link to it instead of copying the procedure files. `init` must never overwrite files it does not own.
61
62
 
62
63
  ## Translations
63
64
 
@@ -87,11 +88,20 @@ npm version minor
87
88
  git push --follow-tags
88
89
  ```
89
90
 
90
- The `release` workflow publishes to npm with provenance and creates a GitHub release. It needs an
91
- `NPM_TOKEN` repository secret: a granular npm token with read/write access to `revdeck` and
92
- **Bypass 2FA** enabled (or a classic Automation token). Without it the publish step fails with
93
- `ENEEDAUTH`; the workflow now reports that explicitly before publishing. The version in
94
- `src/version.ts` must match `package.json`. `prepublishOnly` re-runs build, typecheck and tests.
91
+ The `release` workflow publishes to npm with provenance and creates a GitHub release. It uses
92
+ [trusted publishing](https://docs.npmjs.com/trusted-publishers): GitHub Actions gets a short-lived
93
+ OIDC token, so no npm token is stored in the repository and provenance is generated automatically.
94
+
95
+ Requirements, all configured once on npmjs.com (package `revdeck` → Settings → Trusted publishing):
96
+
97
+ - publisher `katrov/revdeck`, workflow file `release.yml`, environment left empty;
98
+ - "stage only" disabled, so tagged releases publish straight away.
99
+
100
+ The workflow runs on Node 24 and installs npm >= 11.15 because trusted publishing requires npm
101
+ 11.5.1 or newer. If `id-token` is not writable the "Verify OIDC permissions" step fails with a
102
+ clear error; `ENEEDAUTH` from npm means the trusted publisher entry does not match the repo,
103
+ workflow file or environment. The version in `src/version.ts` must match `package.json`.
104
+ `prepublishOnly` re-runs build, typecheck and tests.
95
105
 
96
106
  ## Security
97
107
 
package/README.md CHANGED
@@ -24,7 +24,7 @@ and a web UI. Platform tokens stay on the host.
24
24
  bound to a hash of the plan and is idempotent. There is no “agent approved its own comment” path.
25
25
  - **Tokens never reach the agent.** The daemon calls `glab`/`gh` on the host and scrubs platform tokens
26
26
  from child environments. A sandboxed agent only gets an RPC.
27
- - **GitLab and GitHub.** One model: MR/PR, threads, diff, resolve, reactions, line comments.
27
+ - **GitLab and GitHub.** One model: MR/PR, threads, diff, resolve, reactions, line comments, attachments.
28
28
  - **Many reviews.** The daemon keeps them in SQLite; the UI is a triage queue with keyboard shortcuts.
29
29
  - **Any harness.** MCP tools for MCP clients, the same capabilities over CLI, and a skill that carries
30
30
  the review procedure.
@@ -62,8 +62,11 @@ revdeck ui # open the local UI
62
62
  ```
63
63
 
64
64
  `init` never overwrites an existing config without `--force`, and it merges `.mcp.json` instead of
65
- replacing it. Auto-start on login: `revdeck daemon install` (systemd user unit on Linux, launchd plist
66
- on macOS). Use a global install for this — an `npx` cache path can be evicted.
65
+ replacing it. `revdeck eject` is the inverse: it removes the config, installed skills and command files,
66
+ the `revdeck` MCP entry and the local `.revdeck/` cache, leaving foreign files and other MCP servers
67
+ untouched. It only shows the plan by default; add `--yes` to apply (`--keep-config` keeps
68
+ `.revdeck.yml`). Auto-start on login: `revdeck daemon install` (systemd user unit on Linux, launchd
69
+ plist on macOS). Use a global install for this — an `npx` cache path can be evicted.
67
70
 
68
71
  ## Languages
69
72
 
@@ -91,6 +94,8 @@ Russian READMEs live in this repository; translation fixes are welcome.
91
94
  | Command | What it does |
92
95
  |---|---|
93
96
  | `revdeck init` | config, harness adapters, MCP |
97
+ | `revdeck eject [--yes]` | remove revdeck-owned config, adapters and MCP entry |
98
+ | `revdeck devcontainer [--write]` | mount the host daemon socket/state into a devcontainer |
94
99
  | `revdeck doctor` | environment, `glab`/`gh` auth, daemon, adapters |
95
100
  | `revdeck list [--remote]` | tracked reviews or open ones from the platform |
96
101
  | `revdeck open <N\|URL>` | load a review |
@@ -101,6 +106,8 @@ Russian READMEs live in this repository; translation fixes are welcome.
101
106
  | `revdeck reply <N> --thread <id> --body …` | draft a reply |
102
107
  | `revdeck publish <N> [--yes]` | preview or publish after confirmation |
103
108
  | `revdeck notes <N> …` | line comments from the human |
109
+ | `revdeck react <N> --note <id> --emoji <name>` | toggle a reaction on a platform comment |
110
+ | `revdeck attach <N> --file <image-or-video>` | upload an attachment and print its markdown link |
104
111
  | `revdeck rules [--explain <path>]` | effective rules |
105
112
  | `revdeck checks <N> [--run --yes]` | project checks |
106
113
  | `revdeck export/import <N>` | legacy file exchange |
@@ -110,6 +117,36 @@ Russian READMEs live in this repository; translation fixes are welcome.
110
117
 
111
118
  Common flags: `--json`, `--root`, `--review`, `--platform`, `--project`, `--host`, `--lang ru|en`.
112
119
 
120
+ ## Attachments
121
+
122
+ The UI has an **Attach** button next to reply, finding and line-comment editors; the CLI equivalent is
123
+ `revdeck attach <N> --file shot.png`. The file is uploaded by the daemon on the host, and the editor
124
+ receives a markdown link with an absolute platform URL, so GitLab renders images and videos in the
125
+ original MR. Relative GitLab `/uploads/...` links in existing drafts are rewritten to
126
+ `https://<host>/uploads/...` during the publish preview.
127
+
128
+ GitLab is supported through project uploads (requires a `glab` with `--form` support). GitHub has no
129
+ public attachment API, so the button is disabled there and a link must be pasted manually. Only raster
130
+ images and videos (PNG, JPEG, GIF, WebP, AVIF, MP4, WebM, OGV, MOV) are accepted; SVG and arbitrary
131
+ files are rejected.
132
+
133
+ ## Devcontainer
134
+
135
+ The daemon, `glab` and `gh` stay on the host. From the repository root:
136
+
137
+ ```bash
138
+ revdeck devcontainer # print the mounts and environment
139
+ revdeck devcontainer --write # merge them into .devcontainer/devcontainer.json
140
+ ```
141
+
142
+ The command mounts the host runtime directory at `/run/revdeck` (socket) and the state directory at
143
+ `/var/lib/revdeck` (read-only `daemon.json`), and sets `REVDECK_RUNTIME_DIR`, `REVDECK_STATE_DIR`,
144
+ `REVDECK_DEV_CONTAINER=1` and `REVDECK_UI_HOST`. After rebuilding the container, start the daemon on
145
+ the host. Inside the container revdeck never starts a local daemon, so `gh`/`glab` are never invoked
146
+ there; if the host socket is missing it fails with a clear `DEVCONTAINER` error. `revdeck doctor` is
147
+ aware of this mode. For the UI from the container, start the host daemon with
148
+ `revdeck daemon start --host 0.0.0.0`.
149
+
113
150
  ## MCP
114
151
 
115
152
  ```json
@@ -175,7 +212,7 @@ found. Full schema: [docs/configuration.md](docs/configuration.md).
175
212
  - `glab`/`gh` run without a shell, with `cwd` outside the working copy and a scrubbed environment;
176
213
  secrets are redacted from logs and errors.
177
214
  - Comments are checked for GitLab quick actions, HTML, hidden/bidi characters, mass mentions and
178
- external images.
215
+ external images (only uploads from the platform host are allowed).
179
216
  - Review text is untrusted data; agent instructions say so explicitly.
180
217
 
181
218
  Details: [docs/threat-model.md](docs/threat-model.md). The guarantee is: the token does not cross the
@@ -192,7 +229,7 @@ read the CLI configuration — isolate the agent.
192
229
  | `src/cli` | commands, `init`, `doctor`, export/import |
193
230
  | `src/mcp` | MCP server over stdio |
194
231
  | `ui` | Svelte 5 + Vite |
195
- | `skills/revdeck` | review procedures (SKILL, Review, Feedback, Criteria, Rules, Sources) |
232
+ | `skills/revdeck` | review procedures (SKILL, Review, Feedback, Criteria, Rules, Sources, `agents/openai.yaml`) |
196
233
 
197
234
  More: [docs/architecture.md](docs/architecture.md), [docs/protocol.md](docs/protocol.md),
198
235
  [ADR-0001](docs/adr/0001-daemon-first.md).
@@ -216,7 +253,9 @@ Provider tests use recorded CLI responses and need no network. See [CONTRIBUTING
216
253
  used yet, though the provider interface is ready.
217
254
  - Project checks are planned by the agent; running them requires `revdeck checks --run --yes`.
218
255
  - The UI does not open a new review by number; use the CLI and the review appears in the list.
219
- - Thread resolution is in the thread card; reactions exist in providers but are not exposed in the UI.
256
+ - Thread resolution is in the thread card; reactions are available on thread notes in the UI and through
257
+ `revdeck react`.
258
+ - GitHub has no public attachment API: the Attach button is disabled there; uploads work in GitLab.
220
259
  - Auto-start is supported on Linux and macOS; on Windows run the daemon manually.
221
260
 
222
261
  ## License
package/README.ru.md CHANGED
@@ -25,7 +25,7 @@
25
25
  - **Токены не уезжают агенту.** Демон вызывает `glab`/`gh` на хосте и вычищает токены из окружения
26
26
  дочерних процессов. Агент в песочнице получает только RPC и не видит ни токена, ни конфигурации
27
27
  платформы.
28
- - **GitLab и GitHub.** Одна модель: MR/PR, треды, diff, резолв, реакции, комментарии к строкам.
28
+ - **GitLab и GitHub.** Одна модель: MR/PR, треды, diff, резолв, реакции, комментарии к строкам, вложения.
29
29
  - **Несколько ревью.** Демон хранит открытые ревью в SQLite; UI — очередь с поиском и горячими
30
30
  клавишами.
31
31
 
@@ -51,7 +51,10 @@ revdeck ui # ссылка на локальный интерфейс
51
51
  ```
52
52
 
53
53
  `revdeck init` не перезаписывает существующий конфиг без `--force` и не трогает чужие ключи в
54
- `.mcp.json`. Автозапуск демона при входе в систему — `revdeck daemon install`: создаёт systemd user unit
54
+ `.mcp.json`. Обратная операция — `revdeck eject`: удаляет конфиг, установленные скиллы и файлы команд,
55
+ запись `revdeck` в MCP и локальный кеш `.revdeck/`, не трогая чужие файлы и другие MCP-серверы. По
56
+ умолчанию команда только показывает план; применить — с `--yes` (`--keep-config` оставляет
57
+ `.revdeck.yml`). Автозапуск демона при входе в систему — `revdeck daemon install`: создаёт systemd user unit
55
58
  (Linux) или launchd plist (macOS) и печатает команду включения. Для автозапуска ставьте пакет глобально:
56
59
  путь в кеше `npx` может быть очищен.
57
60
 
@@ -77,6 +80,8 @@ revdeck ui # ссылка на локальный интерфейс
77
80
  | Команда | Что делает |
78
81
  |---|---|
79
82
  | `revdeck init` | конфиг, адаптеры, MCP |
83
+ | `revdeck eject [--yes]` | удалить конфиг, адаптеры и MCP-запись revdeck |
84
+ | `revdeck devcontainer [--write]` | смонтировать сокет/state демона хоста в devcontainer |
80
85
  | `revdeck doctor` | окружение, `glab`/`gh`, демон, адаптеры |
81
86
  | `revdeck list [--remote]` | локальные или открытые на платформе ревью |
82
87
  | `revdeck open <N│URL>` | загрузить ревью |
@@ -87,6 +92,8 @@ revdeck ui # ссылка на локальный интерфейс
87
92
  | `revdeck reply <N> --thread <id> --body …` | черновик ответа |
88
93
  | `revdeck publish <N> [--yes]` | план или публикация после подтверждения |
89
94
  | `revdeck notes <N> …` | комментарии человека к строкам |
95
+ | `revdeck react <N> --note <id> --emoji <name>` | поставить или снять реакцию на комментарий платформы |
96
+ | `revdeck attach <N> --file <картинка-или-видео>` | загрузить вложение и вывести markdown-ссылку |
90
97
  | `revdeck rules [--explain <path>]` | эффективные правила |
91
98
  | `revdeck checks <N> [--run --yes]` | проверки проекта |
92
99
  | `revdeck export/import <N>` | обмен с файловым форматом |
@@ -96,6 +103,35 @@ revdeck ui # ссылка на локальный интерфейс
96
103
 
97
104
  Общие флаги: `--json`, `--root`, `--review`, `--platform`, `--project`, `--host`, `--lang ru|en`.
98
105
 
106
+ ## Вложения
107
+
108
+ В UI рядом с редакторами ответа, замечания и комментария к строке есть кнопка **Прикрепить**; в CLI —
109
+ `revdeck attach <N> --file shot.png`. Файл загружает демон на хосте, а в редактор попадает
110
+ markdown-ссылка с абсолютным URL платформы, поэтому GitLab показывает картинки и видео в исходном MR.
111
+ Относительные ссылки GitLab `/uploads/...` в уже написанных черновиках при предпросмотре публикации
112
+ переписываются в `https://<host>/uploads/...`.
113
+
114
+ GitLab поддержан через project uploads (нужен `glab` с поддержкой `--form`). У GitHub нет публичного
115
+ API загрузки вложений, поэтому кнопка там отключена, а ссылку нужно вставить вручную. Принимаются
116
+ только растровые картинки и видео (PNG, JPEG, GIF, WebP, AVIF, MP4, WebM, OGV, MOV); SVG и
117
+ произвольные файлы отклоняются.
118
+
119
+ ## Devcontainer
120
+
121
+ Демон, `glab` и `gh` остаются на хосте. Из корня репозитория:
122
+
123
+ ```bash
124
+ revdeck devcontainer # показать mounts и окружение
125
+ revdeck devcontainer --write # добавить их в .devcontainer/devcontainer.json
126
+ ```
127
+
128
+ Команда монтирует runtime-каталог хоста в `/run/revdeck` (сокет) и state-каталог в `/var/lib/revdeck`
129
+ (только чтение, `daemon.json`) и выставляет `REVDECK_RUNTIME_DIR`, `REVDECK_STATE_DIR`,
130
+ `REVDECK_DEV_CONTAINER=1` и `REVDECK_UI_HOST`. После пересборки контейнера запустите демон на хосте.
131
+ В контейнере revdeck никогда не запускает свой демон, поэтому `gh`/`glab` там не вызываются; если
132
+ сокет хоста недоступен, команда падает с понятной ошибкой `DEVCONTAINER`. `revdeck doctor` знает об
133
+ этом режиме. Для UI из контейнера запустите демон на хосте с `revdeck daemon start --host 0.0.0.0`.
134
+
99
135
  ## MCP
100
136
 
101
137
  ```json
@@ -162,7 +198,7 @@ revdeck ищет `AGENTS.md`, `CLAUDE.md`, `CONTRIBUTING.md` и `docs/*` и пр
162
198
  - `glab`/`gh` вызываются без shell, с `cwd` вне рабочей копии и вычищенным окружением; секреты
163
199
  редактируются в логах и ошибках.
164
200
  - Комментарии проверяются на быстрые команды GitLab, HTML, скрытые/bidi-символы, `@all` и внешние
165
- картинки.
201
+ внешние картинки (разрешены только загрузки с хоста платформы).
166
202
  - Текст MR — недоверенные данные; агентские инструкции это оговаривают.
167
203
 
168
204
  Подробно: [docs/ru/threat-model.md](docs/ru/threat-model.md). Гарантия формулируется так: токен не
@@ -179,7 +215,7 @@ revdeck ищет `AGENTS.md`, `CLAUDE.md`, `CONTRIBUTING.md` и `docs/*` и пр
179
215
  | `src/cli` | команды, `init`, `doctor`, экспорт/импорт |
180
216
  | `src/mcp` | MCP-сервер (stdio) |
181
217
  | `ui` | Svelte 5 + Vite |
182
- | `skills/revdeck` | процедуры ревью (SKILL, Review, Feedback, Criteria, Rules, Sources) |
218
+ | `skills/revdeck` | процедуры ревью (SKILL, Review, Feedback, Criteria, Rules, Sources, `agents/openai.yaml`) |
183
219
 
184
220
  Подробно: [docs/ru/architecture.md](docs/ru/architecture.md), [docs/ru/protocol.md](docs/ru/protocol.md),
185
221
  [ADR-0001](docs/ru/adr/0001-daemon-first.md).
@@ -202,7 +238,10 @@ npm run build # dist/cli.js, dist/daemon.js, dist/mcp.js, dist/ui
202
238
  ещё не используются, хотя провайдеры к этому готовы.
203
239
  - Проверки проекта агент только планирует; запуск — `revdeck checks --run --yes`.
204
240
  - UI не открывает новое ревью по номеру: это делает CLI, ревью появляется в списке.
205
- - Резолв тредов есть в карточке треда; реакции реализованы в провайдерах, но пока не выведены в UI.
241
+ - Резолв тредов есть в карточке треда; реакции доступны на комментариях тредов в UI и через
242
+ `revdeck react`.
243
+ - У GitHub нет публичного API загрузки вложений: кнопка «Прикрепить» там отключена; загрузка работает
244
+ в GitLab.
206
245
  - Поддержаны Linux и macOS для автозапуска; Windows — запуск вручную.
207
246
 
208
247
  ## Лицензия