revdeck 0.0.0-stage → 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 +58 -0
- package/CONTRIBUTING.md +108 -0
- package/LICENSE +21 -0
- package/README.md +262 -2
- package/README.ru.md +249 -0
- package/SECURITY.md +45 -0
- package/dist/cli.js +3226 -0
- package/dist/cli.js.map +7 -0
- package/dist/daemon.js +4002 -0
- package/dist/daemon.js.map +7 -0
- package/dist/mcp.js +901 -0
- package/dist/mcp.js.map +7 -0
- package/dist/ui/assets/index-BAejn_X6.js +10 -0
- package/dist/ui/assets/index-xv-zA2Sf.css +1 -0
- package/dist/ui/favicon.svg +4 -0
- package/dist/ui/index.html +16 -0
- package/docs/README.md +17 -0
- package/docs/adr/0001-daemon-first.md +64 -0
- package/docs/architecture.md +92 -0
- package/docs/configuration.md +123 -0
- package/docs/integrations.md +123 -0
- package/docs/protocol.md +102 -0
- package/docs/ru/README.md +17 -0
- package/docs/ru/adr/0001-daemon-first.md +62 -0
- package/docs/ru/architecture.md +92 -0
- package/docs/ru/configuration.md +121 -0
- package/docs/ru/integrations.md +122 -0
- package/docs/ru/protocol.md +102 -0
- package/docs/ru/threat-model.md +52 -0
- package/docs/screenshot.png +0 -0
- package/docs/screenshot.ru.png +0 -0
- package/docs/threat-model.md +53 -0
- package/examples/monorepo.yml +38 -0
- package/examples/simple.yml +36 -0
- package/examples/web-chat-core.yml +45 -0
- package/package.json +79 -4
- package/skills/revdeck/en/Criteria.md +265 -0
- package/skills/revdeck/en/Feedback.md +64 -0
- package/skills/revdeck/en/Review.md +157 -0
- package/skills/revdeck/en/Rules.md +75 -0
- package/skills/revdeck/en/SKILL.md +78 -0
- package/skills/revdeck/en/Sources.md +47 -0
- package/skills/revdeck/en/agents/openai.yaml +4 -0
- package/skills/revdeck/ru/Criteria.md +249 -0
- package/skills/revdeck/ru/Feedback.md +64 -0
- package/skills/revdeck/ru/Review.md +148 -0
- package/skills/revdeck/ru/Rules.md +69 -0
- package/skills/revdeck/ru/SKILL.md +73 -0
- package/skills/revdeck/ru/Sources.md +46 -0
- package/skills/revdeck/ru/agents/openai.yaml +4 -0
package/README.ru.md
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
# revdeck
|
|
2
|
+
|
|
3
|
+
[English](README.md) | Русский · [Документация](docs/ru/README.md)
|
|
4
|
+
|
|
5
|
+
Локальный код-ревью для GitLab и GitHub, сделанный вокруг агента: агент читает контекст и пишет
|
|
6
|
+
черновики, человек подтверждает и публикует. Работает как MCP-сервер, CLI и веб-интерфейс; токены
|
|
7
|
+
платформ остаются на хосте.
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
агент (MCP/CLI) ──unix socket──▶ revdeck daemon ──glab/gh──▶ GitLab / GitHub
|
|
11
|
+
│
|
|
12
|
+
SQLite + Svelte UI ◀── человек
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+

|
|
16
|
+
|
|
17
|
+
## Зачем
|
|
18
|
+
|
|
19
|
+
- **Правила вместо догадок.** Для каждого изменённого пути revdeck выбирает документы репозитория и
|
|
20
|
+
конкретные секции (`AGENTS.md`, архитектура, гайды, ADR). Агент получает детерминированный контекст,
|
|
21
|
+
а не «отревьюй PR по best practices».
|
|
22
|
+
- **Публикация только человеком.** Агент пишет черновики ответов и замечаний. В UI видно ровно то, что
|
|
23
|
+
уйдёт в платформу; публикация выполняется по подтверждению, привязанному к хешу плана, и повторно
|
|
24
|
+
не отправляет уже отправленное.
|
|
25
|
+
- **Токены не уезжают агенту.** Демон вызывает `glab`/`gh` на хосте и вычищает токены из окружения
|
|
26
|
+
дочерних процессов. Агент в песочнице получает только RPC и не видит ни токена, ни конфигурации
|
|
27
|
+
платформы.
|
|
28
|
+
- **GitLab и GitHub.** Одна модель: MR/PR, треды, diff, резолв, реакции, комментарии к строкам, вложения.
|
|
29
|
+
- **Несколько ревью.** Демон хранит открытые ревью в SQLite; UI — очередь с поиском и горячими
|
|
30
|
+
клавишами.
|
|
31
|
+
|
|
32
|
+
## Установка
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm install -g revdeck
|
|
36
|
+
# или разово:
|
|
37
|
+
npx revdeck@latest init
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Требования: Node.js ≥ 22.13 (рекомендуется Node 24 LTS: в 22.x `node:sqlite` экспериментален), `git`, для GitLab — `glab` с выполненным `glab auth login`, для
|
|
41
|
+
GitHub — `gh` с `gh auth login`. Токены revdeck не читает и не хранит.
|
|
42
|
+
|
|
43
|
+
В проекте:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
cd /path/to/repo
|
|
47
|
+
revdeck init # .revdeck.yml, skill в .agents/.claude, MCP-конфиг
|
|
48
|
+
revdeck doctor # проверка окружения и адаптеров
|
|
49
|
+
revdeck open 42 # открыть MR/PR по номеру
|
|
50
|
+
revdeck ui # ссылка на локальный интерфейс
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
`revdeck init` не перезаписывает существующий конфиг без `--force` и не трогает чужие ключи в
|
|
54
|
+
`.mcp.json`. Обратная операция — `revdeck eject`: удаляет конфиг, установленные скиллы и файлы команд,
|
|
55
|
+
запись `revdeck` в MCP и локальный кеш `.revdeck/`, не трогая чужие файлы и другие MCP-серверы. По
|
|
56
|
+
умолчанию команда только показывает план; применить — с `--yes` (`--keep-config` оставляет
|
|
57
|
+
`.revdeck.yml`). Автозапуск демона при входе в систему — `revdeck daemon install`: создаёт systemd user unit
|
|
58
|
+
(Linux) или launchd plist (macOS) и печатает команду включения. Для автозапуска ставьте пакет глобально:
|
|
59
|
+
путь в кеше `npx` может быть очищен.
|
|
60
|
+
|
|
61
|
+
## Языки
|
|
62
|
+
|
|
63
|
+
Продукт двуязычный (русский и английский), причём языки независимы:
|
|
64
|
+
|
|
65
|
+
- **Интерфейс и CLI** следуют `--lang ru|en`, затем `REVDECK_LANG`, затем системной локали. В UI есть
|
|
66
|
+
переключатель RU/EN в сайдбаре, выбор запоминается.
|
|
67
|
+
- **Язык результатов ревью** (замечания, ответы, выжимка) — `output.language: auto | ru | en` в
|
|
68
|
+
`.revdeck.yml`. `auto` следует языку описания MR и обсуждений: русская команда может ревьюить
|
|
69
|
+
английский репозиторий и получать русские комментарии (и наоборот).
|
|
70
|
+
- **Skill**: `revdeck init --lang en` ставит английскую процедуру; без флага язык берётся из
|
|
71
|
+
`REVDECK_LANG`/системной локали, по умолчанию английский.
|
|
72
|
+
- **Правила проекта** могут быть на любом языке: revdeck читает UTF-8 и сопоставляет заголовки
|
|
73
|
+
(включая кириллицу) без перевода. Правила цитируются как есть.
|
|
74
|
+
- **MCP-описания инструментов** на английском — это машинный слой для модели; тексты промптов
|
|
75
|
+
следуют `REVDECK_LANG`. Демон читает язык при старте: после смены языка перезапустите его
|
|
76
|
+
(`revdeck daemon restart`).
|
|
77
|
+
|
|
78
|
+
## Команды
|
|
79
|
+
|
|
80
|
+
| Команда | Что делает |
|
|
81
|
+
|---|---|
|
|
82
|
+
| `revdeck init` | конфиг, адаптеры, MCP |
|
|
83
|
+
| `revdeck eject [--yes]` | удалить конфиг, адаптеры и MCP-запись revdeck |
|
|
84
|
+
| `revdeck devcontainer [--write]` | смонтировать сокет/state демона хоста в devcontainer |
|
|
85
|
+
| `revdeck doctor` | окружение, `glab`/`gh`, демон, адаптеры |
|
|
86
|
+
| `revdeck list [--remote]` | локальные или открытые на платформе ревью |
|
|
87
|
+
| `revdeck open <N│URL>` | загрузить ревью |
|
|
88
|
+
| `revdeck context <N>` | контекст для агента: правила, файлы, треды, замечания |
|
|
89
|
+
| `revdeck diff <N> [--file]` | файлы и hunks |
|
|
90
|
+
| `revdeck threads <N>` | обсуждения |
|
|
91
|
+
| `revdeck findings <N> set --file f.json` | записать замечания |
|
|
92
|
+
| `revdeck reply <N> --thread <id> --body …` | черновик ответа |
|
|
93
|
+
| `revdeck publish <N> [--yes]` | план или публикация после подтверждения |
|
|
94
|
+
| `revdeck notes <N> …` | комментарии человека к строкам |
|
|
95
|
+
| `revdeck react <N> --note <id> --emoji <name>` | поставить или снять реакцию на комментарий платформы |
|
|
96
|
+
| `revdeck attach <N> --file <картинка-или-видео>` | загрузить вложение и вывести markdown-ссылку |
|
|
97
|
+
| `revdeck rules [--explain <path>]` | эффективные правила |
|
|
98
|
+
| `revdeck checks <N> [--run --yes]` | проверки проекта |
|
|
99
|
+
| `revdeck export/import <N>` | обмен с файловым форматом |
|
|
100
|
+
| `revdeck ui [N]` | локальный интерфейс |
|
|
101
|
+
| `revdeck daemon <start│stop│status│logs│install>` | управление демоном |
|
|
102
|
+
| `revdeck mcp` | MCP-сервер (stdio) |
|
|
103
|
+
|
|
104
|
+
Общие флаги: `--json`, `--root`, `--review`, `--platform`, `--project`, `--host`, `--lang ru|en`.
|
|
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
|
+
|
|
135
|
+
## MCP
|
|
136
|
+
|
|
137
|
+
```json
|
|
138
|
+
{
|
|
139
|
+
"mcpServers": {
|
|
140
|
+
"revdeck": {
|
|
141
|
+
"command": "npx",
|
|
142
|
+
"args": ["-y", "revdeck", "mcp"],
|
|
143
|
+
"env": { "REVDECK_LANG": "en" }
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Инструменты: `revdeck_status`, `revdeck_list`, `revdeck_open`, `revdeck_context`,
|
|
150
|
+
`revdeck_threads`, `revdeck_diff`, `revdeck_rules`, `revdeck_draft_reply`,
|
|
151
|
+
`revdeck_draft_findings`, `revdeck_set_summary`, `revdeck_notes`, `revdeck_publish_preview`,
|
|
152
|
+
`revdeck_publish`. Публикация требует `approval_id`, который агент получить не может: его выдаёт
|
|
153
|
+
человек в UI или CLI с `--yes`.
|
|
154
|
+
|
|
155
|
+
Промпты `review-mr` и `close-feedback` доступны в клиентах, поддерживающих MCP prompts. В харнессах
|
|
156
|
+
без MCP используйте CLI — возможности те же. Матрица адаптеров и `/`-команд: [docs/ru/integrations.md](docs/ru/integrations.md).
|
|
157
|
+
|
|
158
|
+
## Правила проекта
|
|
159
|
+
|
|
160
|
+
`.revdeck.yml` в корне репозитория:
|
|
161
|
+
|
|
162
|
+
```yaml
|
|
163
|
+
version: 1
|
|
164
|
+
output:
|
|
165
|
+
language: auto # auto | ru | en — язык замечаний и ответов
|
|
166
|
+
provider:
|
|
167
|
+
type: gitlab # auto | gitlab | github
|
|
168
|
+
host: gitlab.example.com
|
|
169
|
+
project: group/project
|
|
170
|
+
base: develop
|
|
171
|
+
rules:
|
|
172
|
+
sources: [AGENTS.md, CONTRIBUTING.md]
|
|
173
|
+
map:
|
|
174
|
+
- match: "src/**"
|
|
175
|
+
docs: [docs/Architecture.md, docs/Styleguide.md#Базовый стиль]
|
|
176
|
+
- match: "src/state/**"
|
|
177
|
+
docs: [docs/StateManagement.md]
|
|
178
|
+
- match: "docs/**"
|
|
179
|
+
docs: [AGENTS.md#Размещение-технических-знаний]
|
|
180
|
+
ignore: ["**/generated/**"]
|
|
181
|
+
checks:
|
|
182
|
+
- id: lint
|
|
183
|
+
argv: [npm, run, lint]
|
|
184
|
+
when: ["src/**"]
|
|
185
|
+
publish:
|
|
186
|
+
requireApproval: true
|
|
187
|
+
maxComments: 50
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Селектор документа: `docs/File.md`, `docs/File.md#Заголовок` или `docs/File.md#L10-L25`. Без конфига
|
|
191
|
+
revdeck ищет `AGENTS.md`, `CLAUDE.md`, `CONTRIBUTING.md` и `docs/*` и предупреждает, если правил не
|
|
192
|
+
нашлось. Полная схема — [docs/ru/configuration.md](docs/ru/configuration.md).
|
|
193
|
+
|
|
194
|
+
## Безопасность
|
|
195
|
+
|
|
196
|
+
- Демон слушает только loopback и unix-сокет (0600), UI — с одноразовым токеном запуска, cookie
|
|
197
|
+
`HttpOnly`/`SameSite=Strict`, проверкой `Host`/`Origin` и CSP.
|
|
198
|
+
- `glab`/`gh` вызываются без shell, с `cwd` вне рабочей копии и вычищенным окружением; секреты
|
|
199
|
+
редактируются в логах и ошибках.
|
|
200
|
+
- Комментарии проверяются на быстрые команды GitLab, HTML, скрытые/bidi-символы, `@all` и внешние
|
|
201
|
+
внешние картинки (разрешены только загрузки с хоста платформы).
|
|
202
|
+
- Текст MR — недоверенные данные; агентские инструкции это оговаривают.
|
|
203
|
+
|
|
204
|
+
Подробно: [docs/ru/threat-model.md](docs/ru/threat-model.md). Гарантия формулируется так: токен не
|
|
205
|
+
пересекает границу песочницы и не отдаётся по RPC. Если у процесса есть чтение домашнего каталога
|
|
206
|
+
пользователя, он может прочитать конфигурацию `glab`/`gh` — для этого и нужна изоляция агента.
|
|
207
|
+
|
|
208
|
+
## Архитектура
|
|
209
|
+
|
|
210
|
+
| Путь | Что внутри |
|
|
211
|
+
|---|---|
|
|
212
|
+
| `src/core` | модели, парсер diff, правила, findings, санитайзер, безопасный exec |
|
|
213
|
+
| `src/providers` | GitLab и GitHub через `glab`/`gh`, нормализация в общую модель |
|
|
214
|
+
| `src/daemon` | SQLite, сервис, RPC по сокету, HTTP/SSE, одобрения |
|
|
215
|
+
| `src/cli` | команды, `init`, `doctor`, экспорт/импорт |
|
|
216
|
+
| `src/mcp` | MCP-сервер (stdio) |
|
|
217
|
+
| `ui` | Svelte 5 + Vite |
|
|
218
|
+
| `skills/revdeck` | процедуры ревью (SKILL, Review, Feedback, Criteria, Rules, Sources, `agents/openai.yaml`) |
|
|
219
|
+
|
|
220
|
+
Подробно: [docs/ru/architecture.md](docs/ru/architecture.md), [docs/ru/protocol.md](docs/ru/protocol.md),
|
|
221
|
+
[ADR-0001](docs/ru/adr/0001-daemon-first.md).
|
|
222
|
+
|
|
223
|
+
## Разработка
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
npm install
|
|
227
|
+
npm run typecheck # tsc + svelte-check
|
|
228
|
+
npm test # vitest
|
|
229
|
+
npm run build # dist/cli.js, dist/daemon.js, dist/mcp.js, dist/ui
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Демон в разработке: `npm run dev:daemon`, UI: `npm run dev:ui` (сборка UI отдаётся демоном из
|
|
233
|
+
`dist/ui`). Тесты провайдеров работают на записанных ответах CLI и не требуют сети.
|
|
234
|
+
|
|
235
|
+
## Ограничения текущей версии
|
|
236
|
+
|
|
237
|
+
- Публикация идёт обычными комментариями; native drafts (GitLab draft notes, GitHub pending review)
|
|
238
|
+
ещё не используются, хотя провайдеры к этому готовы.
|
|
239
|
+
- Проверки проекта агент только планирует; запуск — `revdeck checks --run --yes`.
|
|
240
|
+
- UI не открывает новое ревью по номеру: это делает CLI, ревью появляется в списке.
|
|
241
|
+
- Резолв тредов есть в карточке треда; реакции доступны на комментариях тредов в UI и через
|
|
242
|
+
`revdeck react`.
|
|
243
|
+
- У GitHub нет публичного API загрузки вложений: кнопка «Прикрепить» там отключена; загрузка работает
|
|
244
|
+
в GitLab.
|
|
245
|
+
- Поддержаны Linux и macOS для автозапуска; Windows — запуск вручную.
|
|
246
|
+
|
|
247
|
+
## Лицензия
|
|
248
|
+
|
|
249
|
+
MIT.
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Security policy
|
|
2
|
+
|
|
3
|
+
## Supported versions
|
|
4
|
+
|
|
5
|
+
| Version | Supported |
|
|
6
|
+
|---|---|
|
|
7
|
+
| 0.1.x | yes |
|
|
8
|
+
|
|
9
|
+
Pre-1.0 releases get fixes on the latest minor line.
|
|
10
|
+
|
|
11
|
+
## Reporting a vulnerability
|
|
12
|
+
|
|
13
|
+
Please **do not** open a public issue. Use GitHub's private vulnerability reporting:
|
|
14
|
+
|
|
15
|
+
<https://github.com/katrov/revdeck/security/advisories/new>
|
|
16
|
+
|
|
17
|
+
Include:
|
|
18
|
+
|
|
19
|
+
- affected version (`revdeck --version`) and Node.js version;
|
|
20
|
+
- platform (GitLab/GitHub) and, if relevant, the provider configuration;
|
|
21
|
+
- steps to reproduce, expected and actual behavior;
|
|
22
|
+
- whether a token, a published comment, or repository content is involved;
|
|
23
|
+
- logs with secrets removed (`revdeck daemon logs`).
|
|
24
|
+
|
|
25
|
+
You will get an acknowledgement within a few days. Please give us time to ship a fix before public
|
|
26
|
+
disclosure.
|
|
27
|
+
|
|
28
|
+
## Scope
|
|
29
|
+
|
|
30
|
+
In scope:
|
|
31
|
+
|
|
32
|
+
- token handling and redaction, daemon/socket permissions, UI authentication (launch token, cookie,
|
|
33
|
+
`Host`/`Origin`, CSP);
|
|
34
|
+
- the approval and idempotency model for publishing;
|
|
35
|
+
- prompt injection in review text that leads to unintended actions;
|
|
36
|
+
- path traversal, symlink handling, unsafe `exec`, malicious repository config;
|
|
37
|
+
- supply-chain issues in the published package.
|
|
38
|
+
|
|
39
|
+
Out of scope:
|
|
40
|
+
|
|
41
|
+
- an attacker who already controls the user's OS account or can read `$HOME` — isolate the agent;
|
|
42
|
+
- vulnerabilities in `glab`, `gh`, GitLab or GitHub themselves;
|
|
43
|
+
- denial of service by a local user against their own daemon.
|
|
44
|
+
|
|
45
|
+
The design assumptions and residual risks are documented in [docs/threat-model.md](docs/threat-model.md).
|