oc-pilot 0.0.0-stage → 0.5.1

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.
Files changed (123) hide show
  1. package/CHANGELOG.md +78 -0
  2. package/CONTRIBUTING.md +43 -0
  3. package/Dockerfile +32 -0
  4. package/LICENSE +21 -0
  5. package/README.md +665 -2
  6. package/README.ru.md +523 -0
  7. package/SECURITY.md +42 -0
  8. package/action.yml +68 -0
  9. package/dist/cli.js +120 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/cli.test.js +559 -0
  12. package/dist/cli.test.js.map +1 -0
  13. package/dist/commands/custom.js +87 -0
  14. package/dist/commands/custom.js.map +1 -0
  15. package/dist/commands/docgen.js +256 -0
  16. package/dist/commands/docgen.js.map +1 -0
  17. package/dist/commands/doctor.js +334 -0
  18. package/dist/commands/doctor.js.map +1 -0
  19. package/dist/commands/fix.js +282 -0
  20. package/dist/commands/fix.js.map +1 -0
  21. package/dist/commands/init.js +59 -0
  22. package/dist/commands/init.js.map +1 -0
  23. package/dist/commands/review.js +77 -0
  24. package/dist/commands/review.js.map +1 -0
  25. package/dist/commands/scan.js +102 -0
  26. package/dist/commands/scan.js.map +1 -0
  27. package/dist/commands/setup.js +443 -0
  28. package/dist/commands/setup.js.map +1 -0
  29. package/dist/commands/test-fix.js +181 -0
  30. package/dist/commands/test-fix.js.map +1 -0
  31. package/dist/core/command.js +69 -0
  32. package/dist/core/command.js.map +1 -0
  33. package/dist/core/config.js +277 -0
  34. package/dist/core/config.js.map +1 -0
  35. package/dist/core/config.test.js +145 -0
  36. package/dist/core/config.test.js.map +1 -0
  37. package/dist/core/diff-source.js +98 -0
  38. package/dist/core/diff-source.js.map +1 -0
  39. package/dist/core/diff.js +168 -0
  40. package/dist/core/diff.js.map +1 -0
  41. package/dist/core/diff.test.js +94 -0
  42. package/dist/core/diff.test.js.map +1 -0
  43. package/dist/core/engine.js +179 -0
  44. package/dist/core/engine.js.map +1 -0
  45. package/dist/core/engine.test.js +143 -0
  46. package/dist/core/engine.test.js.map +1 -0
  47. package/dist/core/errors.js +21 -0
  48. package/dist/core/errors.js.map +1 -0
  49. package/dist/core/file-context.js +58 -0
  50. package/dist/core/file-context.js.map +1 -0
  51. package/dist/core/file-context.test.js +58 -0
  52. package/dist/core/file-context.test.js.map +1 -0
  53. package/dist/core/findings.js +110 -0
  54. package/dist/core/findings.js.map +1 -0
  55. package/dist/core/findings.test.js +62 -0
  56. package/dist/core/findings.test.js.map +1 -0
  57. package/dist/core/format.js +31 -0
  58. package/dist/core/format.js.map +1 -0
  59. package/dist/core/format.test.js +26 -0
  60. package/dist/core/format.test.js.map +1 -0
  61. package/dist/core/git.js +137 -0
  62. package/dist/core/git.js.map +1 -0
  63. package/dist/core/io.js +57 -0
  64. package/dist/core/io.js.map +1 -0
  65. package/dist/core/lang.js +17 -0
  66. package/dist/core/lang.js.map +1 -0
  67. package/dist/core/log.js +40 -0
  68. package/dist/core/log.js.map +1 -0
  69. package/dist/core/opencode.js +345 -0
  70. package/dist/core/opencode.js.map +1 -0
  71. package/dist/core/opencode.test.js +59 -0
  72. package/dist/core/opencode.test.js.map +1 -0
  73. package/dist/core/options.js +142 -0
  74. package/dist/core/options.js.map +1 -0
  75. package/dist/core/parse.js +54 -0
  76. package/dist/core/parse.js.map +1 -0
  77. package/dist/core/patch.js +155 -0
  78. package/dist/core/patch.js.map +1 -0
  79. package/dist/core/patch.test.js +70 -0
  80. package/dist/core/patch.test.js.map +1 -0
  81. package/dist/core/process.js +27 -0
  82. package/dist/core/process.js.map +1 -0
  83. package/dist/core/project.js +191 -0
  84. package/dist/core/project.js.map +1 -0
  85. package/dist/core/project.test.js +75 -0
  86. package/dist/core/project.test.js.map +1 -0
  87. package/dist/core/prompt.js +255 -0
  88. package/dist/core/prompt.js.map +1 -0
  89. package/dist/core/prompt.test.js +106 -0
  90. package/dist/core/prompt.test.js.map +1 -0
  91. package/dist/core/rules.js +64 -0
  92. package/dist/core/rules.js.map +1 -0
  93. package/dist/core/rules.test.js +72 -0
  94. package/dist/core/rules.test.js.map +1 -0
  95. package/dist/core/run.js +255 -0
  96. package/dist/core/run.js.map +1 -0
  97. package/dist/core/secrets.js +331 -0
  98. package/dist/core/secrets.js.map +1 -0
  99. package/dist/core/secrets.test.js +121 -0
  100. package/dist/core/secrets.test.js.map +1 -0
  101. package/dist/core/snippets.js +130 -0
  102. package/dist/core/snippets.js.map +1 -0
  103. package/dist/core/snippets.test.js +55 -0
  104. package/dist/core/snippets.test.js.map +1 -0
  105. package/dist/mcp-http.test.js +146 -0
  106. package/dist/mcp-http.test.js.map +1 -0
  107. package/dist/mcp.js +913 -0
  108. package/dist/mcp.js.map +1 -0
  109. package/dist/mcp.test.js +128 -0
  110. package/dist/mcp.test.js.map +1 -0
  111. package/dist/setup.test.js +215 -0
  112. package/dist/setup.test.js.map +1 -0
  113. package/dist/types.js +2 -0
  114. package/dist/types.js.map +1 -0
  115. package/dist/version.js +2 -0
  116. package/dist/version.js.map +1 -0
  117. package/docker-compose.yml +18 -0
  118. package/docs/integrations.md +467 -0
  119. package/package.json +76 -4
  120. package/prompts/oc-pilot.en.md +104 -0
  121. package/prompts/oc-pilot.ru.md +106 -0
  122. package/server.json +21 -0
  123. package/skills/oc-pilot/SKILL.md +47 -0
package/README.ru.md ADDED
@@ -0,0 +1,523 @@
1
+ # oc-pilot
2
+
3
+ [English version](README.md)
4
+
5
+ AI-ассистент разработчика для терминала: ревью git-diff, разбор падающих тестов, генерация документации и офлайн-поиск секретов. Работает поверх [OpenCode](https://opencode.ai) CLI или любого OpenAI-совместимого API, читает файлы проекта только для контекста и не меняет их. Доступен как MCP-сервер `oc-pilot-mcp` для Claude Code, Codex, Cursor, Gemini CLI, DeepSeek Harness и OpenCode.
6
+
7
+ ```
8
+ oc-pilot review # баги, уязвимости, идиомы языка
9
+ oc-pilot test-fix # первопричина падения тестов + минимальный фикс
10
+ oc-pilot docgen src/** # GoDoc / RustDoc / JSDoc / docstrings
11
+ oc-pilot scan # секреты в diff без вызова модели
12
+ ```
13
+
14
+ ## Требования
15
+
16
+ - Node.js **22+**
17
+ - OpenCode CLI **2.x** в `PATH` (`opencode --version`) для движка по умолчанию **или** OpenAI-совместимый endpoint и ключ
18
+ - Настроенная модель и авторизация выбранного движка
19
+ - Для MCP-режима — любой агент с поддержкой MCP (Claude Code, Codex, Cursor, Gemini CLI, DeepSeek Harness, OpenCode)
20
+
21
+ ## Установка
22
+
23
+ Из GitHub, с фиксацией на теге релиза (работает до первого релиза в npm):
24
+
25
+ ```bash
26
+ npm install -g https://github.com/MyNameIsNikki/oc-pilot/archive/refs/tags/v0.5.1.tar.gz
27
+ ```
28
+
29
+ Из npm, после публикации:
30
+
31
+ ```bash
32
+ npm install -g oc-pilot
33
+ ```
34
+
35
+ Для разработки:
36
+
37
+ ```bash
38
+ git clone https://github.com/MyNameIsNikki/oc-pilot.git
39
+ cd oc-pilot
40
+ npm install
41
+ npm run build
42
+ npm install -g .
43
+ ```
44
+
45
+ Для разработки без глобальной установки:
46
+
47
+ ```bash
48
+ npm link
49
+ oc-pilot --version
50
+ ```
51
+
52
+ ## Быстрый старт
53
+
54
+ ```bash
55
+ cd /path/to/your-project
56
+
57
+ oc-pilot setup # настроить все найденные MCP-клиенты
58
+ oc-pilot doctor # проверить установку, движок, ключи, git и MCP
59
+ oc-pilot scan # офлайн-проверка секретов
60
+ oc-pilot review # diff HEAD (staged + unstaged)
61
+ oc-pilot review --staged
62
+ oc-pilot review --base main
63
+ git diff | oc-pilot review --stdin
64
+
65
+ # Без OpenCode:
66
+ export OC_PILOT_API_KEY="..."
67
+ oc-pilot review --engine openai --model deepseek-chat
68
+
69
+ oc-pilot test-fix # разобрать падающий тест
70
+ oc-pilot fix --apply --command "npm test" # патч + тесты
71
+ ```
72
+
73
+ `review` только предлагает изменения: он не применяет патчи и не редактирует файлы. Писать в рабочее дерево умеет только `fix --apply`.
74
+
75
+ ## Как это работает
76
+
77
+ 1. `oc-pilot` собирает diff: `git diff HEAD`, `--staged`, `--base <ref>`, файл или stdin.
78
+ 2. Определяет язык по изменённым файлам и манифестам проекта.
79
+ 3. Сканирует **добавленные строки** на секреты и заменяет найденные значения маркерами `[REDACTED:<kind>]`.
80
+ 4. Движок `opencode` (по умолчанию) запускает `opencode run --format json` и передаёт входные данные через stdin. Движок `openai` вызывает `/chat/completions` любого совместимого API и не требует OpenCode.
81
+ 5. Встроенный агент OpenCode `oc-pilot` получает настоящий system prompt через `OPENCODE_CONFIG_CONTENT` и `--standalone`. В режиме по умолчанию ему разрешены только `read`, `glob`, `grep`; `edit`, `shell`, `webfetch`, `external_directory` и доступ к `.env`/ключам запрещены. Модель может проверить сигнатуры и вызовы в репозитории, но не изменить файлы.
82
+ 6. С флагом `--no-repo-context` или движком `openai` создаётся изолированный контекст без инструментов. В промпт дополнительно попадает `FULL_FILE_CONTEXT` — полные изменённые файлы (до 60 000 символов, секреты редактируются), поэтому модель видит контекст функции без доступа к репозиторию.
83
+ 7. Ответ печатается в stdout как Markdown; диагностика и предупреждения идут в stderr. `--fail-on` превращает найденные замечания в exit code 3 для CI.
84
+
85
+ Системные промпты лежат в [`prompts/oc-pilot.en.md`](prompts/oc-pilot.en.md), [`prompts/oc-pilot.ru.md`](prompts/oc-pilot.ru.md) и в [`src/core/prompt.ts`](src/core/prompt.ts). Готовая конфигурация агента для OpenCode — [`.opencode/agents/oc-pilot.md`](.opencode/agents/oc-pilot.md).
86
+
87
+ ### Свой агент
88
+
89
+ По умолчанию используется встроенный `oc-pilot`. Флаг `--agent <name>` переключает на любой существующий агент OpenCode; в этом режиме системный промпт передаётся в сообщении пользователя, а права и инструменты определяются выбранным агентом. Это расширенный режим: провайдер может отфильтровать большой промпт как попытку инъекции, а `--no-repo-context` не сможет отозвать права чужого агента.
90
+
91
+ ## Движки
92
+
93
+ `opencode` (по умолчанию) даёт лучшее ревью: агент читает вызовы и контракты в репозитории. `openai` убирает зависимость от OpenCode и работает с OpenAI, DeepSeek, Groq, OpenRouter, Ollama и любым совместимым endpoint; полные изменённые файлы передаются в промпт автоматически.
94
+
95
+ ```bash
96
+ # OpenCode, read-only контекст репозитория
97
+ oc-pilot review
98
+
99
+ # Любой OpenAI-совместимый API
100
+ export OC_PILOT_API_KEY="..."
101
+ oc-pilot review --engine openai --model deepseek-chat \
102
+ --base-url https://api.deepseek.com/v1
103
+
104
+ # Локальная модель через Ollama (ключ для localhost не нужен)
105
+ oc-pilot review --engine openai --model qwen2.5-coder \
106
+ --base-url http://127.0.0.1:11434/v1
107
+ ```
108
+
109
+ Ключ читается из `OC_PILOT_API_KEY` или `OPENAI_API_KEY`; переменную можно переименовать через `--api-key-env` / `apiKeyEnv`. Ключ не попадает в логи и ошибки.
110
+
111
+ ## Команды
112
+
113
+ ### `review`
114
+
115
+ ```bash
116
+ oc-pilot review [пути...] [опции]
117
+ ```
118
+
119
+ | Опция | Назначение |
120
+ | --- | --- |
121
+ | `--staged` | только staged-изменения |
122
+ | `--unstaged` | только unstaged-изменения |
123
+ | `--base <ref>` | diff `<ref>...HEAD` для PR |
124
+ | `--diff <file\|->` | готовый diff из файла или stdin |
125
+ | `--stdin` | читать diff из stdin |
126
+ | `--include-untracked` | добавить новые файлы (до 200) |
127
+ | `--context <text\|@file>` | дополнительный контекст |
128
+ | `--lang <en\|ru>` | язык системного промпта и ответа (по умолчанию `en`) |
129
+ | `--engine <opencode\|openai>` | движок модели (по умолчанию `opencode`) |
130
+ | `--base-url <url>` | OpenAI-совместимый endpoint |
131
+ | `--api-key-env <name>` | переменная с API-ключом (по умолчанию `OC_PILOT_API_KEY`) |
132
+ | `--no-repo-context` | не давать агенту читать файлы (только diff) |
133
+ | `--rules <path>` | файл правил проекта |
134
+ | `--fail-on <level>` | exit 3 при замечаниях `critical`, `warning` или `style` |
135
+ | `--fail-on-secrets` | exit 3 при critical-секретах |
136
+ | `--no-secret-scan` | не искать секреты и не редактировать diff |
137
+
138
+ ### `test-fix`
139
+
140
+ ```bash
141
+ oc-pilot test-fix
142
+ oc-pilot test-fix --command "go test ./..."
143
+ oc-pilot test-fix --log failures.log
144
+ oc-pilot test-fix --log - --exit-code 1
145
+ ```
146
+
147
+ Команда тестов определяется автоматически по `package.json`, `go.mod`, `Cargo.toml`, `pyproject.toml`, `pom.xml`, Gradle, `Package.swift`, `mix.exs`, `pubspec.yaml`, `Gemfile`, `composer.json`, `*.csproj` или `Makefile`. Если определить не удалось — укажите `--command` или `testCommand` в конфиге.
148
+
149
+ `test-fix` прикладывает diff (если это git-репозиторий), выдержки из файлов, найденных в стеке, и последние строки вывода. Успешный прогон не анализируется, если не передан `--force`.
150
+
151
+ ### `fix`
152
+
153
+ Просит модель вернуть unified diff, проверяет его через `git apply --check` и с `--apply` применяет в рабочем дереве. Это единственная команда, которая меняет файлы.
154
+
155
+ ```bash
156
+ oc-pilot fix --diff changes.diff # только показать патч
157
+ oc-pilot fix --apply --command "npm test" # применить и проверить
158
+ oc-pilot fix --apply --command "go test ./..." --keep-on-test-failure
159
+ oc-pilot review --github # аннотации GitHub Actions
160
+ ```
161
+
162
+ | Опция | Назначение |
163
+ | --- | --- |
164
+ | `--apply` | применить патч к рабочему дереву |
165
+ | `--command <cmd>` | тесты после применения; иначе `testCommand` или автоопределение |
166
+ | `--no-tests` | применить без запуска тестов |
167
+ | `--keep-on-test-failure` | не откатывать патч при падении тестов |
168
+
169
+ `fix` не делает commit и push. При падении тестов патч откатывается, если не указан `--keep-on-test-failure`. Чужие незакоммиченные изменения не откатываются.
170
+
171
+ ### `docgen`
172
+
173
+ ```bash
174
+ oc-pilot docgen src/core/prompt.ts
175
+ oc-pilot docgen "src/**/*.ts" --symbol buildPrompt
176
+ oc-pilot docgen internal/wallet --context "GoDoc, без markdown"
177
+ ```
178
+
179
+ Поддерживаются файлы, директории и маски (`*`, `**`, `?`). Скрытые и служебные директории (`node_modules`, `dist`, `target`, `.git` и т.п.) пропускаются. Команда возвращает документацию в ответе; файлы не перезаписываются. Ограничения: `--max-file` (60k символов на файл), `--max-diff` (общий бюджет контекста).
180
+
181
+ ### `custom`
182
+
183
+ ```bash
184
+ oc-pilot custom "Предложи, как разбить этот модуль" --git-diff
185
+ oc-pilot custom "Найди гонки данных" --diff changes.patch
186
+ oc-pilot custom "Объясни архитектуру" --context @ARCHITECTURE.md
187
+ ```
188
+
189
+ Свободный запрос с необязательным diff (`--git-diff`, `--diff`, `--stdin`, `--staged`, `--base`).
190
+
191
+ ## Правила проекта
192
+
193
+ Создайте `.oc-pilot/rules.md` в корне проекта (или укажите путь через `--rules` / `rules` в конфиге). Файл автоматически ищется вверх по дереву и добавляется в каждый запрос как `PROJECT_RULES`:
194
+
195
+ ```markdown
196
+ # Правила ревью
197
+
198
+ - Все ошибки оборачивать через `fmt.Errorf("...: %w", err)`.
199
+ - Не логировать PII и токены.
200
+ - Для новых публичных функций обязателен GoDoc.
201
+ - Не предлагать новые зависимости без явного запроса.
202
+ ```
203
+
204
+ Правила тоже сканируются на секреты и редактируются. Лимит — 20 000 символов. Это не заменяет `AGENTS.md`: OpenCode загружает его сам, а `PROJECT_RULES` гарантированно попадает в промпт oc-pilot.
205
+
206
+ ### `scan`
207
+
208
+ Офлайн-сканер секретов, модель не вызывается.
209
+
210
+ ```bash
211
+ oc-pilot scan
212
+ oc-pilot scan --staged --strict
213
+ git diff main...HEAD | oc-pilot scan --stdin --json
214
+ ```
215
+
216
+ Код возврата `1` при critical-находках (или при любых с `--strict`), `0` — чисто, `--no-fail` — всегда `0`.
217
+
218
+ ### `setup`
219
+
220
+ Настраивает MCP-клиент на запуск `oc-pilot-mcp`, сохраняя чужие серверы и настройки. По умолчанию используется текущая установка (`node dist/mcp.js`); `--npx` записывает `npx -y oc-pilot@<version> mcp`, `--local` принудительно выбирает локальный путь. Сгенерированный сервер read-only; `--allow-write` разрешает агенту применять патчи и запускать тесты.
221
+
222
+ ```bash
223
+ oc-pilot setup # все найденные клиенты
224
+ oc-pilot setup --client claude --local
225
+ oc-pilot setup --client opencode --client cursor --local
226
+ oc-pilot setup --client codex --global
227
+ oc-pilot setup --client claude --local --print
228
+ oc-pilot setup --client claude --local \
229
+ --http https://oc-pilot.example.com/mcp --token "$OC_PILOT_MCP_TOKEN"
230
+ ```
231
+
232
+ Клиенты: `claude`, `codex`, `cursor`, `gemini`, `opencode`, `vscode`, `windsurf`, `zcode`, `agents`. Без `--client` `setup` сам находит установленные клиенты по командам и каталогам конфигов. Опции: `--all`, `--client` (повторяемый), `--global` (иначе проект), `--local` (абсолютный путь текущей установки), `--npx` (команда `npx` с закреплённой версией), `--allow-write`, `--print`, `--json`, `--http`, `--token`, `--cwd`, `--force`. `setup` меняет только конфиг MCP-клиента и не устанавливает пакеты. Bearer-токен не записывается в конфиг: клиент читает его из `OC_PILOT_MCP_TOKEN`.
233
+
234
+ ### `doctor`
235
+
236
+ Проверяет установку и объясняет, что мешает работе:
237
+
238
+ ```bash
239
+ oc-pilot doctor
240
+ oc-pilot doctor --json
241
+ oc-pilot doctor --engine openai --model deepseek-chat
242
+ ```
243
+
244
+ Проверки: Node, движок, ключ API, git и репозиторий, тестовая команда, правила проекта и конфиги MCP-клиентов. Ошибки дают exit 1; `--strict` также падает на предупреждениях. Секреты не печатаются.
245
+
246
+ ### `init`
247
+
248
+ ```bash
249
+ oc-pilot init
250
+ oc-pilot init --force
251
+ ```
252
+
253
+ Создаёт `.oc-pilot.json` с настройками по умолчанию.
254
+
255
+ ## Конфигурация
256
+
257
+ `oc-pilot` ищет `.oc-pilot.json` в текущей директории и выше (до 32 уровней). Приоритет: **CLI > переменные окружения > файл > значения по умолчанию**.
258
+
259
+ ```json
260
+ {
261
+ "engine": "opencode",
262
+ "agent": "oc-pilot",
263
+ "model": "anthropic/claude-sonnet-4-5",
264
+ "maxDiffChars": 120000,
265
+ "maxOutputChars": 40000,
266
+ "maxFileChars": 60000,
267
+ "timeoutSeconds": 300,
268
+ "testCommand": "npm test",
269
+ "redactSecrets": true,
270
+ "repoContext": true,
271
+ "failOn": "none"
272
+ }
273
+ ```
274
+
275
+ | Поле | По умолчанию | Описание |
276
+ | --- | --- | --- |
277
+ | `agent` | `oc-pilot` | агент OpenCode |
278
+ | `model` | модель OpenCode | `provider/model#variant` |
279
+ | `maxDiffChars` | `120000` | лимит diff |
280
+ | `maxOutputChars` | `40000` | лимит вывода тестов |
281
+ | `maxFileChars` | `60000` | лимит одного файла для `docgen` |
282
+ | `timeoutSeconds` | `300` | таймаут тестов и запроса |
283
+ | `testCommand` | авто | команда для `test-fix` |
284
+ | `redactSecrets` | `true` | заменять секреты маркерами |
285
+ | `repoContext` | `true` | read-only доступ агента к файлам проекта |
286
+ | `failOn` | `none` | exit 3 при замечаниях: `critical`, `warning`, `style`, `none` |
287
+ | `rules` | авто | путь к файлу правил (иначе `.oc-pilot/rules.md` вверх по дереву) |
288
+
289
+ Для API-движка: `"engine": "openai"`, `"model": "deepseek-chat"`, `"baseUrl": "https://api.deepseek.com/v1"` и при необходимости `"apiKeyEnv": "DEEPSEEK_API_KEY"`.
290
+
291
+ Переменные окружения: `OC_PILOT_ENGINE`, `OC_PILOT_BASE_URL`, `OC_PILOT_API_KEY_ENV`, `OC_PILOT_MODEL`, `OC_PILOT_AGENT`, `OC_PILOT_MAX_DIFF_CHARS`, `OC_PILOT_MAX_OUTPUT_CHARS`, `OC_PILOT_MAX_FILE_CHARS`, `OC_PILOT_TIMEOUT_SECONDS`, `OC_PILOT_TEST_COMMAND`, `OC_PILOT_REDACT_SECRETS`, `OC_PILOT_REPO_CONTEXT`, `OC_PILOT_FAIL_ON`, `OC_PILOT_RULES`.
292
+
293
+ ## Безопасность
294
+
295
+ - Сканер ищет AWS/GitHub/GitLab/Slack/Stripe/Google/OpenAI/Anthropic/npm/Hugging Face/Groq/Discord/SendGrid/DigitalOcean/PyPI/Azure-токены, Telegram-бот-токены, JWT, приватные ключи, credentials в URL, generic-присваивания (`password: "..."`) и `.env`-строки (`DB_PASSWORD=...`).
296
+ - Проверяются только **добавленные** строки diff; удалённые и контекстные строки не считаются утечкой.
297
+ - Найденные значения заменяются маркерами до отправки модели. В отчётах показывается только маска вида `AKIA…MPLE`.
298
+ - Блок приватного ключа редактируется целиком, включая тело.
299
+ - `--no-secret-scan` и `redactSecrets: false` отключают защиту: секреты из diff, `PROJECT_RULES` и `FULL_FILE_CONTEXT` могут уйти провайдеру модели.
300
+ - Сканер — быстрый эвристический слой, а не замена gitleaks/detect-secrets. Для CI используйте специализированный сканер и ротацию ключей.
301
+ - Вывод тестов и произвольный `--context` не проходят redaction; не передавайте туда секреты. `PROJECT_RULES` сканируется и редактируется.
302
+ - В режиме `repoContext` агенту разрешены только `read`, `glob`, `grep`. Запрещены `edit`, `shell`, `subagent`, `webfetch`, `websearch`, `external_directory`, чтение `.env`, приватных ключей, `.ssh`, `.aws`, `.git` и типичных credential-файлов. Это ограничение задаётся permissions OpenCode и не является sandbox уровня ОС.
303
+ - Проект может содержать собственные `opencode.json`/плагины/`AGENTS.md`; `--standalone` загружает их. Для недоверенного репозитория используйте `--no-repo-context`.
304
+
305
+ ## Вывод
306
+
307
+ - Текстовый режим — Markdown в stdout, служебные сообщения в stderr.
308
+ - `--json` — объект:
309
+
310
+ ```json
311
+ {
312
+ "recipe": "review",
313
+ "projectType": "Go",
314
+ "analysis": "### Анализ: ...",
315
+ "findings": [
316
+ { "severity": "critical", "location": "wallet.go:10", "text": "nil pointer dereference" }
317
+ ],
318
+ "secrets": [
319
+ { "file": "wallet.go", "line": 14, "kind": "OpenAI API key", "severity": "critical", "preview": "sk-p…ABCD" }
320
+ ],
321
+ "meta": {
322
+ "agent": "oc-pilot",
323
+ "model": null,
324
+ "durationMs": 12345,
325
+ "filesChanged": 1,
326
+ "formatValid": true,
327
+ "formatWarnings": [],
328
+ "repoContext": true,
329
+ "rules": ".oc-pilot/rules.md",
330
+ "findings": { "critical": 1, "warning": 0, "style": 0 }
331
+ }
332
+ }
333
+ ```
334
+
335
+ `findings` парсятся из секции `#### Замечания / Действия` (русский) или `#### Findings / Actions` (английский); `--fail-on <level>` использует их для exit code 3. JSON стабилен для CI, но текст `analysis` остаётся основным результатом.
336
+
337
+ `--dry-run` печатает системный промпт и входные данные, не вызывая модель. Удобно для отладки и CI-проверок.
338
+
339
+ ## Коды возврата
340
+
341
+ | Код | Значение |
342
+ | --- | --- |
343
+ | `0` | успех |
344
+ | `1` | ошибка выполнения, сбой OpenCode или critical-секрет в `scan` |
345
+ | `2` | ошибка аргументов/конфигурации |
346
+ | `3` | нарушена политика: `--fail-on-secrets`, `--fail-on` или `--strict` |
347
+
348
+ ## MCP-сервер
349
+
350
+ `oc-pilot-mcp` — MCP-сервер для Claude Code, Codex, Cursor, Gemini CLI, OpenCode, ZCode и любых клиентов с `.agents/mcp.json`. Он даёт агенту инструменты `review`, `test_fix`, `fix`, `docgen`, `custom`, `scan`, а модель и доступ к репозиторию остаются в вашем CLI.
351
+
352
+ Автонастройка клиента:
353
+
354
+ ```bash
355
+ oc-pilot setup --client claude --local
356
+ oc-pilot setup --client cursor --global
357
+ ```
358
+
359
+ ZCode импортирует серверы из Claude Code, Codex, OpenCode и `.agents`, либо пишет нативный конфиг через `oc-pilot setup --client zcode`.
360
+
361
+ Запуск вручную:
362
+
363
+ ```bash
364
+ oc-pilot-mcp --cwd "C:\path\to\project"
365
+ # после релиза в npm, версия зафиксирована:
366
+ npx -y oc-pilot@0.5.1 mcp --cwd "C:\path\to\project"
367
+ ```
368
+
369
+ Пример для Claude Code (`.mcp.json`):
370
+
371
+ ```json
372
+ {
373
+ "mcpServers": {
374
+ "oc-pilot": {
375
+ "command": "oc-pilot-mcp",
376
+ "args": ["--cwd", "."]
377
+ }
378
+ }
379
+ }
380
+ ```
381
+
382
+ DeepSeek Harness (`dsh`) подключает сервер через `@deepseek-ai/dsh-mcp-client` в `~/.dsh/profiles/web/cordis.patch.yml`; готовый YAML для stdio и Streamable HTTP есть в [docs/integrations.md](docs/integrations.md#deepseek-harness). Для применения патчей добавьте `'--allow-write'` в `args`.
383
+
384
+ ### Streamable HTTP и Docker
385
+
386
+ Для контейнеров и удалённых агентов:
387
+
388
+ ```bash
389
+ oc-pilot-mcp --http --host 127.0.0.1 --port 8787 --path /mcp \
390
+ --cwd /workspace --token "$OC_PILOT_MCP_TOKEN"
391
+ curl http://127.0.0.1:8787/health
392
+ ```
393
+
394
+ Сервер возвращает `Mcp-Session-Id` при initialize; его нужно передавать в следующих запросах. При `--token` все запросы кроме `GET /health` требуют `Authorization: Bearer <token>`. Без токена длиной от 16 символов сервер не запустится на не-loopback хосте. Для публичного доступа ставьте TLS-прокси.
395
+
396
+ MCP по умолчанию **read-only** и для stdio, и для HTTP: `fix` с `apply:true` и `test_fix`, запускающий новую команду, отклоняются. Для доверенного локального клиента или аутентифицированного окружения добавьте `--allow-write` (в `setup` — `oc-pilot setup --allow-write`) или `OC_PILOT_MCP_READ_ONLY=false`.
397
+
398
+ ```bash
399
+ export OC_PILOT_MCP_TOKEN="$(openssl rand -hex 24)"
400
+ docker build -t oc-pilot-mcp .
401
+ docker run --rm -p 8787:8787 \
402
+ -e OC_PILOT_MCP_TOKEN="$OC_PILOT_MCP_TOKEN" \
403
+ -e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" \
404
+ -v "$PWD:/workspace" oc-pilot-mcp
405
+ ```
406
+
407
+ Или `docker-compose up`. Образ включает OpenCode; `scan` работает без модели.
408
+
409
+ Agent Skill для Claude Code/Codex/OpenCode лежит в [`skills/oc-pilot/SKILL.md`](skills/oc-pilot/SKILL.md): он объясняет агенту, когда вызывать `scan`, `review`, `test-fix`, `fix` и `docgen`.
410
+
411
+ Конфигурации для Codex, Cursor, Gemini CLI и OpenCode, формат результата и CI-примеры — в [docs/integrations.md](docs/integrations.md). Инструменты принимают `diff` и `log` как текст, а `paths` — относительно `--cwd`.
412
+
413
+ ## GitHub Action
414
+
415
+ В репозитории есть composite action: gate для pull request настраивается в три строки.
416
+
417
+ ```yaml
418
+ name: review
419
+ on: [pull_request]
420
+ jobs:
421
+ oc-pilot:
422
+ runs-on: ubuntu-latest
423
+ steps:
424
+ - uses: actions/checkout@v4
425
+ with:
426
+ fetch-depth: 0
427
+ - uses: MyNameIsNikki/oc-pilot@v0.5.1
428
+ with:
429
+ command: scan
430
+ args: --base origin/${{ github.base_ref }} --fail-on-secrets
431
+ ```
432
+
433
+ Входы: `command` (`scan`, `review`, `test-fix`, `docgen`, `custom`), `args`, `working-directory`, `annotations`, `version`. `scan` не требует API-ключа; для review задайте движок и переменные провайдера на шаге.
434
+
435
+ ## CI
436
+
437
+ GitHub Actions:
438
+
439
+ ```yaml
440
+ name: oc-pilot
441
+ on: pull_request
442
+ jobs:
443
+ review:
444
+ runs-on: ubuntu-latest
445
+ permissions:
446
+ contents: read
447
+ steps:
448
+ - uses: actions/checkout@v4
449
+ with:
450
+ fetch-depth: 0
451
+ - uses: actions/setup-node@v4
452
+ with:
453
+ node-version: 22
454
+ - run: npm install -g opencode-ai
455
+ - run: npm ci && npm run build
456
+ working-directory: oc-pilot
457
+ - run: node dist/cli.js scan --base "origin/${{ github.base_ref }}"
458
+ working-directory: oc-pilot
459
+ - run: node dist/cli.js review --base "origin/${{ github.base_ref }}" --fail-on warning --fail-on-secrets --github
460
+ working-directory: oc-pilot
461
+ env:
462
+ OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
463
+ ```
464
+
465
+ `--github` печатает inline-аннотации `::error file=...,line=...` и `::warning`. Для машинного отчёта используйте `--json --output review.json`. Провайдер и переменные авторизации зависят от вашей конфигурации OpenCode. В CI заранее выполните `opencode auth` или передайте ключ провайдера через секреты.
466
+
467
+ ## Ограничения
468
+
469
+ - Diff обрезается до `maxDiffChars`; при переполнении файлы усекаются, в diff появляется маркер.
470
+ - Untracked-файлы не попадают в diff без `--include-untracked`.
471
+ - `review`/`test-fix`/`docgen` не меняют файлы; применять патчи умеет только `fix --apply`. Патчи, затрагивающие файлы вне diff, отклоняются.
472
+ - `fix` лучше работает с текстовыми патчами; бинарные файлы, переименования и CRLF-репозитории могут потребовать ручного `git apply`.
473
+ - HTTP-сервер рассчитан на одного арендатора. По умолчанию он read-only; `--allow-write` разрешает `fix.apply` и запуск новых тестовых команд в смонтированном workspace.
474
+ - Автоопределение команды тестов может ошибаться в нестандартных проектах.
475
+ - `repoContext` запускает агента в проекте через `--standalone`, поэтому проектные `opencode.json`, плагины и `AGENTS.md` загружаются. Для недоверенного кода используйте `--no-repo-context`.
476
+ - Read-only права задаются permissions OpenCode, а не изоляцией ОС: не запускайте инструмент на коде, которому не доверяете.
477
+ - `--fail-on` извлекает замечания из Markdown-секции; при нестандартном ответе используйте `--strict`, чтобы поймать нарушение схемы.
478
+ - Правила проекта ограничены 20 000 символов и не заменяют `AGENTS.md`.
479
+ - Качество и стиль ответа зависят от выбранной модели; `--strict` проверяет только наличие заголовков OUTPUT SCHEMA.
480
+ - Данные diff отправляются выбранному провайдеру модели. Для приватного кода используйте локальную модель или прокси.
481
+
482
+ ## Разработка
483
+
484
+ ```bash
485
+ npm run check # tsc --noEmit
486
+ npm test # build + node:test
487
+ npm run prompt:export # синхронизировать prompts/oc-pilot.en.md, prompts/oc-pilot.ru.md и .opencode/agents/oc-pilot.md
488
+ ```
489
+
490
+ Структура:
491
+
492
+ ```
493
+ src/
494
+ cli.ts точка входа и help
495
+ commands/ review, test-fix, docgen, custom, scan, init
496
+ core/
497
+ config.ts .oc-pilot.json + env
498
+ diff.ts парсинг, статистика, обрезка diff
499
+ diff-source.ts git / файл / stdin
500
+ file-context.ts полные файлы для --no-repo-context
501
+ findings.ts парсинг замечаний и --fail-on
502
+ git.ts git diff, untracked
503
+ rules.ts .oc-pilot/rules.md
504
+ secrets.ts правила, redaction, отчёты
505
+ prompt.ts системный промпт и INPUT
506
+ opencode.ts запуск агента и парсинг JSON-событий
507
+ snippets.ts выдержки из стека тестов
508
+ project.ts язык и команда тестов
509
+ run.ts общий executor и политика
510
+ mcp.ts MCP stdio-сервер (oc-pilot-mcp)
511
+ mcp.test.ts интеграционные тесты MCP
512
+ scripts/export-prompt.mjs
513
+ docs/integrations.md
514
+ prompts/oc-pilot.en.md
515
+ prompts/oc-pilot.ru.md
516
+ .opencode/agents/oc-pilot.md
517
+ README.md
518
+ README.ru.md
519
+ ```
520
+
521
+ ## Лицензия
522
+
523
+ MIT. См. [LICENSE](LICENSE).
package/SECURITY.md ADDED
@@ -0,0 +1,42 @@
1
+ # Security
2
+
3
+ ## Reporting a vulnerability
4
+
5
+ Do not open a public issue for a vulnerability. Use a private GitHub Security Advisory:
6
+
7
+ https://github.com/MyNameIsNikki/oc-pilot/security/advisories/new
8
+
9
+ Include the affected version, a minimal reproduction, and the impact. Do not include real API keys, tokens, private keys, or customer data. Replace credentials with synthetic values.
10
+
11
+ Supported versions: the latest release on npm. Security fixes are released as patch versions.
12
+
13
+ ## Trust model
14
+
15
+ `oc-pilot` is a local developer tool and a single-tenant MCP server. It is not a multi-user service, a sandbox, or a secret store.
16
+
17
+ - The CLI reads the project, the diff, and files explicitly passed on the command line. It sends selected content to the OpenCode provider configured by the user.
18
+ - The built-in OpenCode agent is read-only: `read`, `glob`, and `grep` are allowed; `edit`, `shell`, web access, and external directories are denied. Sensitive paths such as `.env`, private keys, `.ssh`, `.aws`, and `.git` are denied.
19
+ - Secret scanning is best-effort. Findings are redacted before model calls when `redactSecrets` is enabled, but a missed secret is still sent to the provider. Never rely on this as the only control.
20
+ - `fix --apply` writes to the working tree. It rejects patches that touch files outside the reviewed diff, checks the patch with `git apply --check`, and reverts it when tests fail unless `--keep-on-test-failure` is used. It never commits or pushes.
21
+ - `test-fix` and `fix` run the detected or supplied test command with the user's privileges. Treat the command as code execution.
22
+
23
+ ## MCP server
24
+
25
+ - stdio is for a local client and inherits the local user's privileges.
26
+ - MCP is read-only by default for both stdio and HTTP: `fix apply` and running new test commands are rejected. Use `--allow-write` only for a trusted local client or a trusted, authenticated deployment. Generated `setup` configs stay read-only unless `--allow-write` is passed.
27
+ - A non-loopback HTTP bind refuses to start without a token of at least 16 characters. Tokens are compared in constant time. `GET /health` is unauthenticated and returns only status, name, and version.
28
+ - MCP path and file arguments are confined to the project directory. `context` is literal text, not an `@file` reference. `base` must be a git ref.
29
+ - The server is single-tenant. Do not share one instance between mutually untrusted users or repositories. Run one container per trust boundary.
30
+ - Container deployments must mount only the intended workspace and provider credentials. Prefer a read-only mount and `OC_PILOT_MCP_READ_ONLY=true` when writes are not required.
31
+ - Put a TLS-terminating reverse proxy in front of any public endpoint, and keep the token out of URLs and logs.
32
+
33
+ ## Supply chain
34
+
35
+ Releases are published from GitHub Actions with npm provenance (`--provenance`). The package has no runtime dependencies. CI runs type checking, the full test suite, CodeQL, and package-content checks. Dependabot monitors npm, Docker, and GitHub Actions.
36
+
37
+ Verify a published release:
38
+
39
+ ```bash
40
+ npm view oc-pilot@<version> dist.integrity
41
+ npm audit signatures
42
+ ```
package/action.yml ADDED
@@ -0,0 +1,68 @@
1
+ name: oc-pilot
2
+ description: Local secret scan, AI code review and fail-on gate for pull requests
3
+ author: MyNameIsNikki
4
+
5
+ branding:
6
+ icon: shield
7
+ color: blue
8
+
9
+ inputs:
10
+ command:
11
+ description: "Command to run: scan, review, test-fix, docgen or custom"
12
+ required: false
13
+ default: scan
14
+ args:
15
+ description: "Extra arguments passed to the command, e.g. --staged --fail-on-secrets"
16
+ required: false
17
+ default: ""
18
+ working-directory:
19
+ description: "Directory to analyze"
20
+ required: false
21
+ default: "."
22
+ version:
23
+ description: "Install this oc-pilot version from npm. Empty installs the action checkout."
24
+ required: false
25
+ default: ""
26
+ annotations:
27
+ description: "Emit GitHub annotations for review findings (adds --github)"
28
+ required: false
29
+ default: "false"
30
+
31
+ runs:
32
+ using: composite
33
+ steps:
34
+ - name: Set up Node.js
35
+ uses: actions/setup-node@v4
36
+ with:
37
+ node-version: "22"
38
+
39
+ - name: Install oc-pilot
40
+ shell: bash
41
+ env:
42
+ OC_PILOT_ACTION_VERSION: ${{ inputs.version }}
43
+ run: |
44
+ set -euo pipefail
45
+ if [ -n "${OC_PILOT_ACTION_VERSION}" ]; then
46
+ npm install -g "oc-pilot@${OC_PILOT_ACTION_VERSION}"
47
+ else
48
+ npm install -g "${GITHUB_ACTION_PATH}"
49
+ fi
50
+
51
+ - name: Run analysis
52
+ shell: bash
53
+ working-directory: ${{ inputs.working-directory }}
54
+ env:
55
+ INPUT_COMMAND: ${{ inputs.command }}
56
+ INPUT_ARGS: ${{ inputs.args }}
57
+ INPUT_ANNOTATIONS: ${{ inputs.annotations }}
58
+ run: |
59
+ set -euo pipefail
60
+ args=()
61
+ if [ -n "${INPUT_ARGS}" ]; then
62
+ # word splitting is intentional: args is a command-line fragment
63
+ read -r -a args <<< "${INPUT_ARGS}"
64
+ fi
65
+ if [ "${INPUT_ANNOTATIONS}" = "true" ] && [ "${INPUT_COMMAND}" = "review" ]; then
66
+ args+=(--github)
67
+ fi
68
+ oc-pilot "${INPUT_COMMAND}" "${args[@]}"