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.md CHANGED
@@ -1,3 +1,666 @@
1
- # Temporary Holding Version
1
+ # oc-pilot
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Local AI code review, failing-test analysis, documentation generation, and secret scanning for agent CLIs.
4
+
5
+ `oc-pilot` is a small CLI and MCP server for developers who write code with AI agents. It reviews an uncommitted diff, follows the project beyond the changed lines, catches leaked credentials before they reach a model, explains a failing test, and returns findings as human-readable Markdown or machine-readable JSON.
6
+
7
+ It works with OpenCode out of the box, with any OpenAI-compatible API (OpenAI, DeepSeek, Groq, OpenRouter, Ollama), and with any MCP-capable agent: Claude Code, OpenAI Codex CLI, Cursor CLI, Gemini CLI, and others.
8
+
9
+ [Русская документация](README.ru.md)
10
+
11
+ ## Why
12
+
13
+ Agents are good at producing code and bad at reviewing their own work. A normal chat turn does not:
14
+
15
+ - inspect the surrounding files and call sites;
16
+ - distinguish an introduced bug from pre-existing code;
17
+ - stop secrets from being sent to a third-party model;
18
+ - fail CI when a critical finding appears;
19
+ - return a stable schema that another agent can consume.
20
+
21
+ `oc-pilot` adds that layer without a PR bot, a hosted dashboard, or a vendor account.
22
+
23
+ ## Requirements
24
+
25
+ - Node.js 22 or newer.
26
+ - OpenCode 2.x for the default repo-aware engine, **or** an OpenAI-compatible API endpoint and key.
27
+ - Any MCP client for the server workflow.
28
+
29
+ ## Install
30
+
31
+ From GitHub, pinned to a release tag (works before the first npm release):
32
+
33
+ ```bash
34
+ npm install -g https://github.com/MyNameIsNikki/oc-pilot/archive/refs/tags/v0.5.1.tar.gz
35
+ ```
36
+
37
+ From npm, once published:
38
+
39
+ ```bash
40
+ npm install -g oc-pilot
41
+ ```
42
+
43
+ For development:
44
+
45
+ ```bash
46
+ git clone https://github.com/MyNameIsNikki/oc-pilot.git
47
+ cd oc-pilot
48
+ npm install
49
+ npm run build
50
+ npm install -g .
51
+ ```
52
+
53
+ Verify:
54
+
55
+ ```bash
56
+ oc-pilot --version
57
+ oc-pilot-mcp --version
58
+ oc-pilot mcp --version
59
+ ```
60
+
61
+ For development, run `node dist/cli.js` and `node dist/mcp.js` directly.
62
+
63
+ ## Quick start (OpenCode)
64
+
65
+ ```bash
66
+ cd /path/to/project
67
+
68
+ # Configure every MCP client detected on this machine
69
+ oc-pilot setup
70
+
71
+ # Check installation, engine, key, git and MCP configs
72
+ oc-pilot doctor
73
+
74
+ # Fast offline gate, then model-backed review
75
+ oc-pilot scan
76
+ oc-pilot review --staged --fail-on-secrets
77
+ oc-pilot review --base main --fail-on warning --json
78
+
79
+ # No OpenCode? Use any OpenAI-compatible endpoint
80
+ export OC_PILOT_API_KEY="..."
81
+ oc-pilot review --engine openai --model deepseek-chat
82
+
83
+ # Explain a failing test and propose a tested patch
84
+ oc-pilot test-fix
85
+ oc-pilot fix --apply --command "npm test"
86
+
87
+ # Generate docs
88
+ oc-pilot docgen "src/**/*.ts"
89
+ ```
90
+
91
+ The default model prompt is English. Use `--lang ru` for Russian findings and docs, or set `lang` in config.
92
+
93
+ ## How it works
94
+
95
+ 1. `oc-pilot` collects the diff and project metadata.
96
+ 2. It scans added lines for secrets and replaces detected values with `[REDACTED:<kind>]`.
97
+ 3. It loads project rules from `.oc-pilot/rules.md` (optional).
98
+ 4. It builds an input with `PROJECT_TYPE`, `RECIPE`, repository context, rules, the secret report, and `GIT_DIFF`.
99
+ 5. With the OpenCode engine, a read-only agent can use `read`, `glob`, and `grep` to inspect call sites and contracts. `edit`, `shell`, web access, and external directories are denied.
100
+ 6. The model returns a fixed Markdown schema. `oc-pilot` parses severity and emits JSON on request.
101
+ 7. `--fail-on` and `--fail-on-secrets` turn findings into CI exit codes.
102
+
103
+ With `--no-repo-context`, the agent gets no tools. `oc-pilot` instead includes full changed files (`FULL_FILE_CONTEXT`) within the context budget.
104
+
105
+ ## Engines
106
+
107
+ Choose where the model call goes. `opencode` is the default and gives the best review because the agent can read call sites and contracts. `openai` removes the OpenCode dependency: it calls any OpenAI-compatible `/chat/completions` endpoint and automatically includes the full changed files as context.
108
+
109
+ ```bash
110
+ # Default: repo-aware OpenCode agent
111
+ oc-pilot review
112
+
113
+ # Any OpenAI-compatible API, no OpenCode required
114
+ export OC_PILOT_API_KEY="..."
115
+ oc-pilot review --engine openai --model deepseek-chat \
116
+ --base-url https://api.deepseek.com/v1
117
+
118
+ # Local model through Ollama (no key needed on loopback)
119
+ oc-pilot review --engine openai --model qwen2.5-coder \
120
+ --base-url http://127.0.0.1:11434/v1
121
+ ```
122
+
123
+ | Engine | Best for | Repository tools | Requires |
124
+ | --- | --- | --- | --- |
125
+ | `opencode` | Cross-file bugs and contract changes | Read, glob, grep (read-only) | OpenCode + provider auth |
126
+ | `openai` | Zero extra CLIs, CI, DeepSeek/OpenRouter/local models | No; full changed files are included | API endpoint and key |
127
+
128
+ The key is read from `OC_PILOT_API_KEY`, or `OPENAI_API_KEY` when the default variable name is used. Set `apiKeyEnv` to use another variable. Logs and errors never print the key. With the `openai` engine, `repoContext` is forced off and `FULL_FILE_CONTEXT` is added automatically.
129
+
130
+ ## Commands
131
+
132
+ ### `review`
133
+
134
+ Reviews a git diff. By default it reviews all uncommitted changes (`git diff HEAD`).
135
+
136
+ ```bash
137
+ oc-pilot review
138
+ oc-pilot review --staged
139
+ oc-pilot review --base main
140
+ oc-pilot review --include-untracked
141
+ oc-pilot review src/wallet.go --context "Balance must never be negative"
142
+ git diff | oc-pilot review --stdin
143
+ ```
144
+
145
+ | Option | Purpose |
146
+ | --- | --- |
147
+ | `--staged` / `--unstaged` | Limit the diff to one side |
148
+ | `--base <ref>` | Review `<ref>...HEAD` |
149
+ | `--diff <file\|->` | Read a prepared unified diff |
150
+ | `--stdin` | Read the diff from stdin |
151
+ | `--include-untracked` | Add new files to the diff |
152
+ | `--context <text\|@file>` | Extra context for the model |
153
+ | `--no-secret-scan` | Disable secret scanning and redaction |
154
+ | `--fail-on-secrets` | Exit 3 on critical secrets |
155
+
156
+ ### `test-fix`
157
+
158
+ Runs the detected test command, or reads a log, then explains the root cause and proposes a minimal fix.
159
+
160
+ ```bash
161
+ oc-pilot test-fix
162
+ oc-pilot test-fix --command "go test ./..."
163
+ oc-pilot test-fix --log failures.log
164
+ npm test 2> failures.log; oc-pilot test-fix --log failures.log
165
+ ```
166
+
167
+ A passing test run is skipped unless `--force` is used.
168
+
169
+ ### `fix`
170
+
171
+ Asks the model for a unified diff, checks that it applies, and optionally applies it in the project. This is the only command that can modify your working tree, and only with `--apply`.
172
+
173
+ ```bash
174
+ # Show the proposed patch and do not touch files
175
+ oc-pilot fix --diff changes.diff
176
+
177
+ # Apply, run tests, and keep the patch only when tests pass
178
+ oc-pilot fix --apply --command "npm test"
179
+
180
+ # Apply but keep the patch even when tests fail
181
+ oc-pilot fix --apply --command "go test ./..." --keep-on-test-failure
182
+
183
+ # Emit GitHub Actions annotations for the findings
184
+ oc-pilot review --github
185
+ ```
186
+
187
+ | Option | Purpose |
188
+ | --- | --- |
189
+ | `--apply` | Apply the patch to the working tree |
190
+ | `--command <cmd>` | Test command after applying; defaults to `testCommand` or auto-detection |
191
+ | `--no-tests` | Apply without running tests |
192
+ | `--keep-on-test-failure` | Do not revert a patch when tests fail |
193
+
194
+ `fix` never commits or pushes. The patch is reverted when tests fail unless `--keep-on-test-failure` is used. Unrelated working-tree changes are not reverted.
195
+
196
+ ### `docgen`
197
+
198
+ Generates GoDoc, RustDoc, JSDoc, Python docstrings, and similar comments without changing the code.
199
+
200
+ ```bash
201
+ oc-pilot docgen src/core/prompt.ts
202
+ oc-pilot docgen "src/**/*.ts" --symbol buildPrompt
203
+ ```
204
+
205
+ ### `custom`
206
+
207
+ Runs a free-form analysis with an optional diff and context.
208
+
209
+ ```bash
210
+ oc-pilot custom "Find data races" --git-diff
211
+ oc-pilot custom "Explain this module" --context @ARCHITECTURE.md
212
+ ```
213
+
214
+ ### `scan`
215
+
216
+ Offline secret scan. No model call.
217
+
218
+ ```bash
219
+ oc-pilot scan
220
+ oc-pilot scan --staged --json
221
+ git diff main...HEAD | oc-pilot scan --stdin
222
+ ```
223
+
224
+ Exit 1 means critical secrets were found. `--strict` also fails on warnings.
225
+
226
+ ### `setup`
227
+
228
+ Configures an MCP client to launch `oc-pilot-mcp`. Existing server entries and unrelated settings are preserved. It writes configs for Claude Code, Codex, Cursor, Gemini CLI, OpenCode, VS Code, Windsurf, ZCode, and any client that reads `.agents/mcp.json`. By default it points at the current installation; `--npx` writes a version-pinned `npx -y oc-pilot@<version> mcp` entry instead. Generated servers start read-only; add `--allow-write` if the agent should apply patches and run tests.
229
+
230
+ ```bash
231
+ # Project-local Claude Code config (.mcp.json)
232
+ oc-pilot setup --client claude --local
233
+
234
+ # OpenCode and Cursor in one run
235
+ oc-pilot setup --client opencode --client cursor --local
236
+
237
+ # Global config, or print without writing
238
+ oc-pilot setup --client codex --global
239
+ oc-pilot setup --client claude --local --print
240
+
241
+ # Remote HTTP server with a bearer token
242
+ oc-pilot setup --client claude --local \
243
+ --http https://oc-pilot.example.com/mcp --token "$OC_PILOT_MCP_TOKEN"
244
+ ```
245
+
246
+ | Option | Purpose |
247
+ | --- | --- |
248
+ | `--client <name>` | `claude`, `codex`, `cursor`, `gemini`, `opencode`, `vscode`, `windsurf`, `zcode`, `agents`; repeatable |
249
+ | `--all` | Configure every supported client |
250
+ | `--global` | Write user-level config (project is the default) |
251
+ | `--local` | Force the current installation path |
252
+ | `--npx` | Force a version-pinned `npx` command |
253
+ | `--allow-write` | Let the client apply patches and run tests |
254
+ | `--print` | Print the config instead of writing it |
255
+ | `--json` | JSON plan for automation |
256
+ | `--http <url>` | Configure a remote Streamable HTTP endpoint |
257
+ | `--token <value>` | Enable bearer auth; the client reads the secret from `OC_PILOT_MCP_TOKEN` |
258
+ | `--cwd <dir>` | Project directory stored in the server args |
259
+ | `--force` | Replace an existing `oc-pilot` entry |
260
+
261
+ `setup` never writes the bearer token into a client config. It writes an `OC_PILOT_MCP_TOKEN` reference; export the secret in the environment that launches the client.
262
+
263
+ `setup` writes only MCP client config. It does not install packages or change your source. With no `--client`, it detects Claude Code, Codex, Cursor, Gemini CLI, OpenCode, VS Code, Windsurf, ZCode, and `.agents` clients from installed commands and config directories.
264
+
265
+ ### `doctor`
266
+
267
+ One command that explains why a setup is not working:
268
+
269
+ ```bash
270
+ oc-pilot doctor
271
+ oc-pilot doctor --json
272
+ oc-pilot doctor --engine openai --model deepseek-chat
273
+ ```
274
+
275
+ It checks Node, the active engine, API credentials, git and repository state, the detected test command, project rules, and every MCP client config. Errors return exit code 1; `--strict` also fails on warnings. No secret values are printed.
276
+
277
+ ### `init`
278
+
279
+ ```bash
280
+ oc-pilot init
281
+ ```
282
+
283
+ Creates `.oc-pilot.json`. It does not overwrite an existing config unless `--force` is passed.
284
+
285
+ ## Common options
286
+
287
+ | Option | Default | Purpose |
288
+ | --- | --- | --- |
289
+ | `-C, --cwd <dir>` | current directory | Project directory |
290
+ | `-m, --model <id>` | engine default | Model id (`provider/model` for OpenCode) |
291
+ | `--engine <name>` | `opencode` | `opencode` or `openai` (any compatible API) |
292
+ | `--base-url <url>` | `https://api.openai.com/v1` | OpenAI-compatible endpoint |
293
+ | `--api-key-env <name>` | `OC_PILOT_API_KEY` | Environment variable holding the API key |
294
+ | `--agent <name>` | `oc-pilot` | Use another OpenCode agent |
295
+ | `--lang <en\|ru>` | `en` | Model-facing prompt and output language |
296
+ | `--no-repo-context` | off | Diff-only mode; no repository tools |
297
+ | `--rules <path>` | `.oc-pilot/rules.md` | Project rules file |
298
+ | `--fail-on <level>` | `none` | Exit 3 on `critical`, `warning`, or `style` findings |
299
+ | `--max-diff <size>` | `120000` | Diff/context budget |
300
+ | `--max-file <size>` | `60000` | Per-file budget for docgen |
301
+ | `--timeout <duration>` | `300` | Model/test timeout; supports `5m` |
302
+ | `-o, --output <path>` | stdout | Write the result to a file |
303
+ | `--json` | off | Machine-readable output |
304
+ | `--dry-run` | off | Print the prompt without calling a model |
305
+ | `--strict` | off | Exit 3 when the output schema is invalid |
306
+ | `--verbose` | off | Stream OpenCode diagnostics |
307
+
308
+ ## Project rules
309
+
310
+ Add a `.oc-pilot/rules.md` at the project root, or point to one with `--rules` / the `rules` config field:
311
+
312
+ ```markdown
313
+ - Keep handlers thin; business logic belongs in services.
314
+ - Errors must wrap the original cause.
315
+ - Never log request bodies or tokens.
316
+ - Prefer table-driven tests.
317
+ ```
318
+
319
+ Rules are added to every recipe. They are scanned and redacted like any other project content, unless `--no-secret-scan` is used.
320
+
321
+ ## Secret scanning
322
+
323
+ The scanner looks at added diff lines and common source-file patterns:
324
+
325
+ - private key blocks;
326
+ - OpenAI, Anthropic, Hugging Face, Groq, Google, GitHub, GitLab, npm, PyPI, Slack, Discord, Telegram, Stripe, SendGrid, DigitalOcean, and AWS keys;
327
+ - Azure storage account keys;
328
+ - JWTs, credentials in URLs, and sensitive `.env` assignments.
329
+
330
+ Detected values never appear in full in logs or JSON. The model receives `[REDACTED:<kind>]` and a masked preview. Review the provider's data policy before sending proprietary code.
331
+
332
+ `--no-secret-scan` and `redactSecrets: false` disable this protection for the diff, rules, and `FULL_FILE_CONTEXT`. Use them deliberately.
333
+
334
+ ## Output and exit codes
335
+
336
+ Markdown response:
337
+
338
+ ```markdown
339
+ ### Analysis: Short conclusion.
340
+
341
+ #### Findings / Actions
342
+ - **🔴 Critical `wallet.go:10`**: nil pointer dereference.
343
+
344
+ #### Solution
345
+ ```go
346
+ // minimal fix
347
+ ```
348
+ ```
349
+
350
+ `--lang ru` uses the Russian schema (`### Анализ:`, `#### Замечания / Действия`, `#### Решение`).
351
+
352
+ `--json` returns:
353
+
354
+ ```json
355
+ {
356
+ "recipe": "review",
357
+ "projectType": "Go",
358
+ "analysis": "### Analysis: ...",
359
+ "findings": [
360
+ { "severity": "critical", "location": "wallet.go:10", "text": "nil pointer dereference" }
361
+ ],
362
+ "secrets": [],
363
+ "meta": {
364
+ "engine": "opencode",
365
+ "agent": "oc-pilot",
366
+ "model": "openai/gpt-5.5",
367
+ "lang": "en",
368
+ "repoContext": true,
369
+ "formatValid": true,
370
+ "formatWarnings": [],
371
+ "findings": { "critical": 1, "warning": 0, "style": 0 }
372
+ }
373
+ }
374
+ ```
375
+
376
+ | Code | Meaning |
377
+ | --- | --- |
378
+ | 0 | Success, no failing policy |
379
+ | 1 | Runtime error, or critical secret from `scan` |
380
+ | 2 | Argument/configuration error |
381
+ | 3 | Policy gate: `--fail-on`, `--fail-on-secrets`, or `--strict` |
382
+
383
+ ## Configuration
384
+
385
+ `oc-pilot` reads `.oc-pilot.json` from the project directory or an ancestor, then environment variables, then CLI flags.
386
+
387
+ ```json
388
+ {
389
+ "engine": "opencode",
390
+ "model": "anthropic/claude-sonnet-4-5",
391
+ "agent": "oc-pilot",
392
+ "lang": "en",
393
+ "repoContext": true,
394
+ "failOn": "none",
395
+ "maxDiffChars": 120000,
396
+ "maxOutputChars": 40000,
397
+ "maxFileChars": 60000,
398
+ "timeoutSeconds": 300,
399
+ "redactSecrets": true,
400
+ "testCommand": "npm test"
401
+ }
402
+ ```
403
+
404
+ For the API engine, set `"engine": "openai"`, `"model": "deepseek-chat"`, `"baseUrl": "https://api.deepseek.com/v1"`, and optionally `"apiKeyEnv": "DEEPSEEK_API_KEY"` in the same file.
405
+
406
+ Environment variables: `OC_PILOT_ENGINE`, `OC_PILOT_BASE_URL`, `OC_PILOT_API_KEY_ENV`, `OC_PILOT_MODEL`, `OC_PILOT_AGENT`, `OC_PILOT_LANG`, `OC_PILOT_REPO_CONTEXT`, `OC_PILOT_FAIL_ON`, `OC_PILOT_RULES`, `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`.
407
+
408
+ ## MCP server
409
+
410
+ `oc-pilot-mcp` exposes the same recipes as MCP tools over stdio. This is the recommended way to embed oc-pilot in an agent: the agent calls a tool, and no prompt needs to be copied.
411
+
412
+ Tools: `review`, `test_fix`, `fix`, `docgen`, `custom`, `scan`. The server is read-only by default; start it with `--allow-write` to permit `fix` with `apply: true` and `test_fix` with a command.
413
+
414
+ Configure a client automatically:
415
+
416
+ ```bash
417
+ oc-pilot setup # every detected client
418
+ oc-pilot setup --client claude --local
419
+ oc-pilot setup --client cursor --global
420
+ ```
421
+
422
+ The MCP server uses the configured engine. With `engine: "openai"` and `OC_PILOT_API_KEY` exported in the client's environment, no OpenCode installation is needed.
423
+
424
+ ZCode can import existing Claude Code, Codex, OpenCode, or `.agents` MCP servers directly, or write its native config with `oc-pilot setup --client zcode`.
425
+
426
+ Start the server manually with an explicit project directory:
427
+
428
+ ```bash
429
+ oc-pilot-mcp --cwd /absolute/path/to/project
430
+ # after the npm release, pinned for reproducibility:
431
+ npx -y oc-pilot@0.5.1 mcp --cwd /absolute/path/to/project
432
+ ```
433
+
434
+ The `diff` and `log` tool arguments are text, not file paths. `paths` and `files` are project-relative and cannot escape the project directory. `context` is literal text, not an `@file` reference. `base` must be a git ref. `lang`, `fail_on`, `repo_context`, and `no_secret_scan` are available where the corresponding CLI command supports them.
435
+
436
+ The MCP server does not add its own file access: it runs the same CLI with `--cwd` fixed at startup. A client cannot point it at another directory through a tool argument.
437
+
438
+ ### Claude Code
439
+
440
+ ```bash
441
+ claude mcp add oc-pilot -- oc-pilot-mcp --cwd /absolute/path/to/project
442
+ ```
443
+
444
+ Project `.mcp.json`:
445
+
446
+ ```json
447
+ {
448
+ "mcpServers": {
449
+ "oc-pilot": {
450
+ "command": "oc-pilot-mcp",
451
+ "args": ["--cwd", "/absolute/path/to/project"]
452
+ }
453
+ }
454
+ }
455
+ ```
456
+
457
+ ### OpenAI Codex CLI
458
+
459
+ `~/.codex/config.toml`:
460
+
461
+ ```toml
462
+ [mcp_servers.oc_pilot]
463
+ command = "oc-pilot-mcp"
464
+ args = ["--cwd", "/absolute/path/to/project"]
465
+ ```
466
+
467
+ ### Cursor
468
+
469
+ `.cursor/mcp.json`:
470
+
471
+ ```json
472
+ {
473
+ "mcpServers": {
474
+ "oc-pilot": {
475
+ "command": "oc-pilot-mcp",
476
+ "args": ["--cwd", "/absolute/path/to/project"]
477
+ }
478
+ }
479
+ }
480
+ ```
481
+
482
+ ### Gemini CLI
483
+
484
+ `~/.gemini/settings.json`:
485
+
486
+ ```json
487
+ {
488
+ "mcpServers": {
489
+ "oc-pilot": {
490
+ "command": "oc-pilot-mcp",
491
+ "args": ["--cwd", "/absolute/path/to/project"]
492
+ }
493
+ }
494
+ }
495
+ ```
496
+
497
+ ### OpenCode
498
+
499
+ `opencode.json`:
500
+
501
+ ```json
502
+ {
503
+ "mcp": {
504
+ "servers": {
505
+ "oc-pilot": {
506
+ "type": "local",
507
+ "command": ["oc-pilot-mcp", "--cwd", "/absolute/path/to/project"]
508
+ }
509
+ }
510
+ }
511
+ }
512
+ ```
513
+
514
+ ### DeepSeek Harness
515
+
516
+ DeepSeek Harness (`dsh`) mounts MCP servers through `@deepseek-ai/dsh-mcp-client` in `~/.dsh/profiles/web/cordis.patch.yml`:
517
+
518
+ ```yaml
519
+ - insert:
520
+ - id: mcp-oc-pilot
521
+ name: '@deepseek-ai/dsh-mcp-client'
522
+ config:
523
+ serverName: oc_pilot
524
+ transport: stdio
525
+ command: oc-pilot-mcp
526
+ args: ['--cwd', '/absolute/path/to/project']
527
+ toolCallTimeoutMs: 300000
528
+ ```
529
+
530
+ For a remote read-only server:
531
+
532
+ ```yaml
533
+ - insert:
534
+ - id: mcp-oc-pilot
535
+ name: '@deepseek-ai/dsh-mcp-client'
536
+ config:
537
+ serverName: oc_pilot
538
+ transport: streamable-http
539
+ url: https://oc-pilot.example.com/mcp
540
+ headers:
541
+ Authorization: !!js 'Bearer ' + process.env.OC_PILOT_MCP_TOKEN
542
+ ```
543
+
544
+ Add `'--allow-write'` to `args` only if the harness may apply patches and run tests. DeepSeek Harness labels the tools as `mcp__oc_pilot__review`, `mcp__oc_pilot__scan`, and so on.
545
+
546
+ ### Streamable HTTP
547
+
548
+ For containers and remote agents, run the same server over HTTP instead of stdio:
549
+
550
+ ```bash
551
+ export OC_PILOT_MCP_TOKEN="$(openssl rand -hex 24)"
552
+ oc-pilot-mcp --http --host 127.0.0.1 --port 8787 --path /mcp \
553
+ --cwd /workspace --token "$OC_PILOT_MCP_TOKEN"
554
+ curl http://127.0.0.1:8787/health
555
+ ```
556
+
557
+ MCP is **read-only by default**, over both stdio and HTTP: `scan`, `review`, `docgen`, `custom`, and patch-proposal `fix` work; `fix` with `apply: true` and `test_fix` that runs a new command are rejected. Add `--allow-write` only for a trusted local client or an authenticated deployment. `oc-pilot setup --allow-write` adds the flag to generated client config.
558
+
559
+ The MCP endpoint sets `Mcp-Session-Id` on initialize. When `--token` is set, every request needs `Authorization: Bearer <token>` except `GET /health`. A non-loopback bind **refuses to start** without a token of at least 16 characters. Put a TLS-terminating reverse proxy in front of any public deployment.
560
+
561
+ ### Docker
562
+
563
+ ```bash
564
+ export OC_PILOT_MCP_TOKEN="$(openssl rand -hex 24)"
565
+ docker build -t oc-pilot-mcp .
566
+ docker run --rm -p 8787:8787 \
567
+ -e OC_PILOT_MCP_TOKEN="$OC_PILOT_MCP_TOKEN" \
568
+ -e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" \
569
+ -v "$PWD:/workspace" \
570
+ oc-pilot-mcp
571
+ ```
572
+
573
+ Or use `docker-compose up`; the compose file requires `OC_PILOT_MCP_TOKEN`. The image mounts the current directory at `/workspace` and exposes port 8787. It is read-only over HTTP; set `OC_PILOT_MCP_READ_ONLY=false` only when you trust every client that can reach the endpoint. The image includes OpenCode, so model-backed tools work; `scan` needs no model.
574
+
575
+ ### Agent skills
576
+
577
+ `skills/oc-pilot/SKILL.md` is an Agent Skill for Claude Code, Codex, and OpenCode. It teaches an agent when to call `scan`, `review`, `test-fix`, `fix`, and `docgen` through MCP or the CLI. Copy the `skills/oc-pilot` directory into your skills directory, or point the client at this repository.
578
+
579
+ See [docs/integrations.md](docs/integrations.md) for protocols, result shapes, setup details, and shell-only fallbacks.
580
+
581
+ ## GitHub Action
582
+
583
+ The repository ships a composite action, so a pull request gate can be three lines:
584
+
585
+ ```yaml
586
+ name: review
587
+ on: [pull_request]
588
+ jobs:
589
+ oc-pilot:
590
+ runs-on: ubuntu-latest
591
+ steps:
592
+ - uses: actions/checkout@v4
593
+ with:
594
+ fetch-depth: 0
595
+ - uses: MyNameIsNikki/oc-pilot@v0.5.1
596
+ with:
597
+ command: scan
598
+ args: --base origin/${{ github.base_ref }} --fail-on-secrets
599
+ ```
600
+
601
+ Inputs: `command` (`scan`, `review`, `test-fix`, `docgen`, `custom`), `args`, `working-directory`, `annotations`, and `version` (install a published npm version instead of the action checkout). `scan` needs no API key. For a model-backed review, set the engine and provider environment variables on the step.
602
+
603
+ ## CI
604
+
605
+ ```yaml
606
+ name: oc-pilot
607
+ on: [pull_request]
608
+ jobs:
609
+ review:
610
+ runs-on: ubuntu-latest
611
+ steps:
612
+ - uses: actions/checkout@v4
613
+ with:
614
+ fetch-depth: 0
615
+ - uses: actions/setup-node@v4
616
+ with:
617
+ node-version: 22
618
+ - run: npm install -g https://github.com/MyNameIsNikki/oc-pilot/archive/refs/tags/v0.5.1.tar.gz
619
+ - run: oc-pilot scan --base origin/${{ github.base_ref }}
620
+ - run: oc-pilot review --base origin/${{ github.base_ref }} --fail-on warning --fail-on-secrets --github
621
+ env:
622
+ ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
623
+ ```
624
+
625
+ `--github` turns parsed findings into inline `::error file=...,line=...` and `::warning` annotations. `scan` needs no API key and is suitable for a fast first gate. Add `--json` instead when a later step needs the structured report.
626
+
627
+ ## Security model
628
+
629
+ - The built-in repo-context agent is read-only: `read`, `glob`, and `grep` only. `edit`, `shell`, `subagent`, web tools, and external directories are denied.
630
+ - Known secret files (`.env`, keys, SSH/AWS credentials, `.npmrc`, `.pypirc`) are denied.
631
+ - `--no-repo-context` uses an isolated temporary project with all tools denied and adds full changed files as text.
632
+ - Diff, rules, and full-file content are scanned before being sent to the model.
633
+ - Project rules and code comments are data, not instructions. The system prompt explicitly treats injected instructions as untrusted.
634
+ - The repo-context agent runs inside the analyzed project, so project-level OpenCode config and plugins may load. Use `--no-repo-context` for untrusted repositories.
635
+ - Only `fix --apply` writes to the working tree. It rejects patches that touch files outside the reviewed diff, checks the patch with `git apply --check`, runs the configured tests, and reverts the patch when they fail. It never commits or pushes.
636
+ - The HTTP transport uses the MCP session header and an optional bearer token. Plain HTTP has no transport encryption; use a TLS proxy for remote deployments, and do not expose it without a token.
637
+ - No file is modified by `review`, `test-fix`, `docgen`, or `custom`.
638
+
639
+ ## Limitations
640
+
641
+ - The quality of the review depends on the selected model and the context budget.
642
+ - A diff-only review cannot see every caller; use the OpenCode engine or repo context for contract changes. The `openai` engine sees the full changed files, not arbitrary call sites.
643
+ - Secret detection is pattern-based and can miss novel formats or produce false positives.
644
+ - Auto-detection of test commands may need `--command` / `testCommand`.
645
+ - Project-level OpenCode config is not loaded in isolated `--no-repo-context` mode.
646
+ - The CLI UI is currently Russian; the model prompt and output are available in English and Russian.
647
+ - `fix` works best with text patches. Binary files, renames, and CRLF-sensitive repositories may need a manual `git apply`.
648
+ - The HTTP server is single-tenant: anyone with the token can analyze and apply fixes in the mounted workspace. Run one container per trust boundary.
649
+ - `setup` edits MCP client config only; it does not install Node, OpenCode, or provider credentials.
650
+
651
+ ## Development
652
+
653
+ ```bash
654
+ npm install
655
+ npm run check
656
+ npm test
657
+ npm run prompt:export
658
+ ```
659
+
660
+ `npm test` builds first and runs `node --test "dist/**/*.test.js"`.
661
+
662
+ The project has no runtime dependencies. Dev dependencies are TypeScript and `@types/node`.
663
+
664
+ ## License
665
+
666
+ MIT