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.
- package/CHANGELOG.md +78 -0
- package/CONTRIBUTING.md +43 -0
- package/Dockerfile +32 -0
- package/LICENSE +21 -0
- package/README.md +665 -2
- package/README.ru.md +523 -0
- package/SECURITY.md +42 -0
- package/action.yml +68 -0
- package/dist/cli.js +120 -0
- package/dist/cli.js.map +1 -0
- package/dist/cli.test.js +559 -0
- package/dist/cli.test.js.map +1 -0
- package/dist/commands/custom.js +87 -0
- package/dist/commands/custom.js.map +1 -0
- package/dist/commands/docgen.js +256 -0
- package/dist/commands/docgen.js.map +1 -0
- package/dist/commands/doctor.js +334 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/fix.js +282 -0
- package/dist/commands/fix.js.map +1 -0
- package/dist/commands/init.js +59 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/review.js +77 -0
- package/dist/commands/review.js.map +1 -0
- package/dist/commands/scan.js +102 -0
- package/dist/commands/scan.js.map +1 -0
- package/dist/commands/setup.js +443 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/test-fix.js +181 -0
- package/dist/commands/test-fix.js.map +1 -0
- package/dist/core/command.js +69 -0
- package/dist/core/command.js.map +1 -0
- package/dist/core/config.js +277 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/config.test.js +145 -0
- package/dist/core/config.test.js.map +1 -0
- package/dist/core/diff-source.js +98 -0
- package/dist/core/diff-source.js.map +1 -0
- package/dist/core/diff.js +168 -0
- package/dist/core/diff.js.map +1 -0
- package/dist/core/diff.test.js +94 -0
- package/dist/core/diff.test.js.map +1 -0
- package/dist/core/engine.js +179 -0
- package/dist/core/engine.js.map +1 -0
- package/dist/core/engine.test.js +143 -0
- package/dist/core/engine.test.js.map +1 -0
- package/dist/core/errors.js +21 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/file-context.js +58 -0
- package/dist/core/file-context.js.map +1 -0
- package/dist/core/file-context.test.js +58 -0
- package/dist/core/file-context.test.js.map +1 -0
- package/dist/core/findings.js +110 -0
- package/dist/core/findings.js.map +1 -0
- package/dist/core/findings.test.js +62 -0
- package/dist/core/findings.test.js.map +1 -0
- package/dist/core/format.js +31 -0
- package/dist/core/format.js.map +1 -0
- package/dist/core/format.test.js +26 -0
- package/dist/core/format.test.js.map +1 -0
- package/dist/core/git.js +137 -0
- package/dist/core/git.js.map +1 -0
- package/dist/core/io.js +57 -0
- package/dist/core/io.js.map +1 -0
- package/dist/core/lang.js +17 -0
- package/dist/core/lang.js.map +1 -0
- package/dist/core/log.js +40 -0
- package/dist/core/log.js.map +1 -0
- package/dist/core/opencode.js +345 -0
- package/dist/core/opencode.js.map +1 -0
- package/dist/core/opencode.test.js +59 -0
- package/dist/core/opencode.test.js.map +1 -0
- package/dist/core/options.js +142 -0
- package/dist/core/options.js.map +1 -0
- package/dist/core/parse.js +54 -0
- package/dist/core/parse.js.map +1 -0
- package/dist/core/patch.js +155 -0
- package/dist/core/patch.js.map +1 -0
- package/dist/core/patch.test.js +70 -0
- package/dist/core/patch.test.js.map +1 -0
- package/dist/core/process.js +27 -0
- package/dist/core/process.js.map +1 -0
- package/dist/core/project.js +191 -0
- package/dist/core/project.js.map +1 -0
- package/dist/core/project.test.js +75 -0
- package/dist/core/project.test.js.map +1 -0
- package/dist/core/prompt.js +255 -0
- package/dist/core/prompt.js.map +1 -0
- package/dist/core/prompt.test.js +106 -0
- package/dist/core/prompt.test.js.map +1 -0
- package/dist/core/rules.js +64 -0
- package/dist/core/rules.js.map +1 -0
- package/dist/core/rules.test.js +72 -0
- package/dist/core/rules.test.js.map +1 -0
- package/dist/core/run.js +255 -0
- package/dist/core/run.js.map +1 -0
- package/dist/core/secrets.js +331 -0
- package/dist/core/secrets.js.map +1 -0
- package/dist/core/secrets.test.js +121 -0
- package/dist/core/secrets.test.js.map +1 -0
- package/dist/core/snippets.js +130 -0
- package/dist/core/snippets.js.map +1 -0
- package/dist/core/snippets.test.js +55 -0
- package/dist/core/snippets.test.js.map +1 -0
- package/dist/mcp-http.test.js +146 -0
- package/dist/mcp-http.test.js.map +1 -0
- package/dist/mcp.js +913 -0
- package/dist/mcp.js.map +1 -0
- package/dist/mcp.test.js +128 -0
- package/dist/mcp.test.js.map +1 -0
- package/dist/setup.test.js +215 -0
- package/dist/setup.test.js.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/docker-compose.yml +18 -0
- package/docs/integrations.md +467 -0
- package/package.json +76 -4
- package/prompts/oc-pilot.en.md +104 -0
- package/prompts/oc-pilot.ru.md +106 -0
- package/server.json +21 -0
- package/skills/oc-pilot/SKILL.md +47 -0
package/README.md
CHANGED
|
@@ -1,3 +1,666 @@
|
|
|
1
|
-
#
|
|
1
|
+
# oc-pilot
|
|
2
2
|
|
|
3
|
-
|
|
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
|