robin-review 2.4.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/LICENSE +21 -0
- package/README.md +321 -0
- package/bin/robin-review.js +89 -0
- package/package.json +65 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Anton Gulin
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
# Robin
|
|
2
|
+
|
|
3
|
+
Free AI code reviews for every pull request. You bring an API key; Robin reviews show up like a teammate left comments.
|
|
4
|
+
|
|
5
|
+
[](https://github.com/antongulin/robin/actions/workflows/self-test.yml)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
[](action.yml)
|
|
8
|
+
|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
## What you get
|
|
12
|
+
|
|
13
|
+
- A review when you open a pull request (or when someone comments `/robin`)
|
|
14
|
+
- A short summary plus inline comments on changed lines
|
|
15
|
+
- Your choice of AI provider — including **free** options
|
|
16
|
+
|
|
17
|
+
When there's nothing worth flagging, Robin says so instead of inventing nitpicks:
|
|
18
|
+
|
|
19
|
+

|
|
20
|
+
|
|
21
|
+
You are **not** signing up for a separate review bot service. The workflow runs in your repo and calls the AI URL you configure.
|
|
22
|
+
|
|
23
|
+
## For AI coding agents
|
|
24
|
+
|
|
25
|
+
Using Cursor, Copilot, Claude Code, or similar? Copy this prompt after secrets are set:
|
|
26
|
+
|
|
27
|
+
```text
|
|
28
|
+
Add Robin to this repository.
|
|
29
|
+
- Workflow file: .github/workflows/robin.yml
|
|
30
|
+
- Reusable workflow: antongulin/robin/.github/workflows/review.yml@main
|
|
31
|
+
- Action ref if needed: antongulin/robin@main
|
|
32
|
+
- Secrets: LLM_API_KEY, LLM_BASE_URL, LLM_MODEL
|
|
33
|
+
- Do NOT use @v0 or any v0 tag
|
|
34
|
+
- Do NOT use pull_request_target or synchronize on pull_request
|
|
35
|
+
Read AGENTS.md in the robin repo for full rules.
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Quick install
|
|
39
|
+
|
|
40
|
+
In a terminal, from your project folder, run either:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npx robin-review
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
or, without Node.js:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
curl -fsSL https://robinreview.dev/install.sh | bash
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Either one creates `.github/workflows/robin.yml` for you (it never overwrites an existing
|
|
53
|
+
file) and installs the [companion chat skill](#robin-in-your-editor) into your coding agents.
|
|
54
|
+
You still need to add the three secrets — do **Steps 1 and 2** below, then commit and push.
|
|
55
|
+
You can **skip Step 3**: the installer already did it.
|
|
56
|
+
|
|
57
|
+
**Auto-updates:** the generated workflow references `antongulin/robin@main`, so every
|
|
58
|
+
review runs the latest Robin automatically — nothing to bump or re-install. Prefer fixed
|
|
59
|
+
versions? Pin a tag with `ROBIN_REF=v2 npx robin-review` (see [Version pins](#version-pins)).
|
|
60
|
+
|
|
61
|
+
Prefer to do it by hand, or read the installer first? It's
|
|
62
|
+
[bin/robin-review.js](bin/robin-review.js) (npm) / [scripts/install.sh](scripts/install.sh)
|
|
63
|
+
(curl) — or follow the manual 3 steps instead.
|
|
64
|
+
|
|
65
|
+
## Setup in 3 steps
|
|
66
|
+
|
|
67
|
+
### Step 1 — Get an API key (free option)
|
|
68
|
+
|
|
69
|
+
The easiest free setup uses [OpenRouter](https://openrouter.ai/):
|
|
70
|
+
|
|
71
|
+
1. Create an account at [openrouter.ai](https://openrouter.ai/).
|
|
72
|
+
2. Create an API key in the dashboard.
|
|
73
|
+
3. Use these values for your GitHub secrets:
|
|
74
|
+
|
|
75
|
+
| Secret name | Value |
|
|
76
|
+
| --- | --- |
|
|
77
|
+
| `LLM_API_KEY` | Your OpenRouter key (`sk-or-...`) |
|
|
78
|
+
| `LLM_BASE_URL` | `https://openrouter.ai/api/v1` |
|
|
79
|
+
| `LLM_MODEL` | `openrouter/free` |
|
|
80
|
+
|
|
81
|
+
> [!TIP]
|
|
82
|
+
> `openrouter/free` picks a free model for each review — **$0 from OpenRouter**. OpenRouter rotates which model runs; **leave this secret as `openrouter/free`** — the action retries and uses provider fallbacks when a route is temporarily unavailable. You only spend [GitHub Actions](https://docs.github.com/en/billing/concepts/product-billing/github-actions) minutes while the job runs (often a few minutes per review).
|
|
83
|
+
>
|
|
84
|
+
> GitHub Free includes about **2,000 Actions minutes/month** (public and private repos); [GitHub Pro](https://docs.github.com/en/billing/concepts/product-billing/github-actions) includes about **3,000 minutes/month** (check your plan for current limits). Reviews usually take a few minutes each.
|
|
85
|
+
|
|
86
|
+
Other providers (OpenAI, Groq, Ollama, etc.) work too. See [Supported providers](#supported-providers) or [docs/ADVANCED.md](docs/ADVANCED.md).
|
|
87
|
+
|
|
88
|
+
### Step 2 — Add secrets on GitHub
|
|
89
|
+
|
|
90
|
+
1. Open **your** repository on GitHub (not this one).
|
|
91
|
+
2. Go to **Settings** → **Secrets and variables** → **Actions**.
|
|
92
|
+
3. Click **New repository secret** and add each name from the table above.
|
|
93
|
+
|
|
94
|
+
> [!WARNING]
|
|
95
|
+
> Never put API keys inside workflow files, pull request comments, or chat with an AI. Only use GitHub Secrets.
|
|
96
|
+
|
|
97
|
+
### Step 3 — Add the workflow file
|
|
98
|
+
|
|
99
|
+
> [!NOTE]
|
|
100
|
+
> **Ran the Quick install one-liner above?** Skip this step — the script already created
|
|
101
|
+
> this file. Just finish Steps 1 and 2 (the secrets), then commit and push.
|
|
102
|
+
|
|
103
|
+
Create a new file in your repo:
|
|
104
|
+
|
|
105
|
+
**Path:** `.github/workflows/robin.yml`
|
|
106
|
+
|
|
107
|
+
**Contents:** copy this exactly:
|
|
108
|
+
|
|
109
|
+
```yaml
|
|
110
|
+
name: Robin
|
|
111
|
+
|
|
112
|
+
on:
|
|
113
|
+
pull_request:
|
|
114
|
+
types: [opened, reopened, ready_for_review]
|
|
115
|
+
issue_comment:
|
|
116
|
+
types: [created]
|
|
117
|
+
|
|
118
|
+
permissions:
|
|
119
|
+
contents: read
|
|
120
|
+
pull-requests: write
|
|
121
|
+
|
|
122
|
+
jobs:
|
|
123
|
+
review:
|
|
124
|
+
uses: antongulin/robin/.github/workflows/review.yml@main
|
|
125
|
+
secrets:
|
|
126
|
+
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
|
|
127
|
+
LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }}
|
|
128
|
+
LLM_MODEL: ${{ secrets.LLM_MODEL }}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Commit and push. Open a pull request — you should see a review within a few minutes.
|
|
132
|
+
|
|
133
|
+
> [!IMPORTANT]
|
|
134
|
+
> Use **`@main`** for the latest fixes, or pin a release tag (for example `@v1` or `@v1.0.0`) after [releases](https://github.com/antongulin/robin/releases) exist. Do **not** use `@v0`. See [Version pins](#version-pins) below.
|
|
135
|
+
|
|
136
|
+
## Running on a self-hosted runner
|
|
137
|
+
|
|
138
|
+
By default, the reusable workflow runs on GitHub's hosted `ubuntu-latest` runner:
|
|
139
|
+
|
|
140
|
+
```yaml
|
|
141
|
+
with:
|
|
142
|
+
runner: '"ubuntu-latest"'
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
To run reviews on your own machine, Mac mini, home server, local Linux box, or Coolify runner, pass `runner` as valid JSON. Use a JSON string for one label or a JSON array for multiple labels.
|
|
146
|
+
|
|
147
|
+
To create a local runner, go to:
|
|
148
|
+
|
|
149
|
+
```text
|
|
150
|
+
Repository Settings -> Actions -> Runners -> New self-hosted runner
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Then add labels such as `local`, `linux`, `mac`, or `coolify`, and reference those labels through the `runner` input.
|
|
154
|
+
|
|
155
|
+
### Does the runner need to run all the time?
|
|
156
|
+
|
|
157
|
+
A matching self-hosted runner must be online when GitHub starts the review job. It can be a local runner process (`./run.sh`), a service (`./svc.sh start`), a Docker container, or a Coolify-managed service. Docker is optional; it is just one way to run the GitHub Actions runner.
|
|
158
|
+
|
|
159
|
+
If no matching runner is online, GitHub queues the job until one comes online. It will not fall back to `ubuntu-latest` unless you add a separate fallback job. For reliable PR reviews, keep an always-on runner available, such as a Mac mini, home server, VPS, or Coolify service. A laptop runner only works while the laptop is awake and the runner process or service is running.
|
|
160
|
+
|
|
161
|
+
> [!WARNING]
|
|
162
|
+
> Self-hosted runners can execute arbitrary workflow code.
|
|
163
|
+
> Do not use them for untrusted public pull requests.
|
|
164
|
+
> Prefer repo-owned private repos or trusted collaborators only.
|
|
165
|
+
> Consider ephemeral runners for stronger isolation.
|
|
166
|
+
|
|
167
|
+
Local machine runner:
|
|
168
|
+
|
|
169
|
+
```yaml
|
|
170
|
+
jobs:
|
|
171
|
+
review:
|
|
172
|
+
uses: antongulin/robin/.github/workflows/review.yml@main
|
|
173
|
+
with:
|
|
174
|
+
runner: '["self-hosted", "local"]'
|
|
175
|
+
secrets:
|
|
176
|
+
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
|
|
177
|
+
LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }}
|
|
178
|
+
LLM_MODEL: ${{ secrets.LLM_MODEL }}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Coolify runner:
|
|
182
|
+
|
|
183
|
+
```yaml
|
|
184
|
+
jobs:
|
|
185
|
+
review:
|
|
186
|
+
uses: antongulin/robin/.github/workflows/review.yml@main
|
|
187
|
+
with:
|
|
188
|
+
runner: '["self-hosted", "linux", "coolify"]'
|
|
189
|
+
secrets:
|
|
190
|
+
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
|
|
191
|
+
LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }}
|
|
192
|
+
LLM_MODEL: ${{ secrets.LLM_MODEL }}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## Using it day to day
|
|
196
|
+
|
|
197
|
+
| When | What happens |
|
|
198
|
+
| --- | --- |
|
|
199
|
+
| You open a PR | Review runs once automatically |
|
|
200
|
+
| You push more commits | No new review (saves time and API usage) |
|
|
201
|
+
| You want another review | Comment `/robin` on the PR (first line of the comment) |
|
|
202
|
+
| You want a short overview only | Comment `/summary` |
|
|
203
|
+
| You need help | Comment `/help` |
|
|
204
|
+
|
|
205
|
+
`/review` still works as an alias for `/robin`. Only people with **write** access (or higher) on the repo can run these commands by default.
|
|
206
|
+
|
|
207
|
+
## Example
|
|
208
|
+
|
|
209
|
+
The bot posts a status comment, then a review with severity counts:
|
|
210
|
+
|
|
211
|
+
```md
|
|
212
|
+
## 🏹 Robin
|
|
213
|
+
|
|
214
|
+
🚨 **1 High** | ⚠️ **1 Medium** | 💡 **2 Suggestions**
|
|
215
|
+
|
|
216
|
+
### Summary
|
|
217
|
+
Focused change. Main risk: timeout errors are not handled clearly.
|
|
218
|
+
|
|
219
|
+
### Findings Not Posted Inline
|
|
220
|
+
**1 (`src/example.ts:24`)** — Retries exist but timeout failures lack context.
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## Robin in your editor
|
|
224
|
+
|
|
225
|
+
The one-line installer also installs a small **companion skill** into every coding agent
|
|
226
|
+
on your machine (Claude Code, Cursor, Copilot, Windsurf, …) via the cross-platform
|
|
227
|
+
[skills CLI](https://skills.sh) — `npx skills add https://github.com/antongulin/robin --all --global`. It
|
|
228
|
+
ships with Robin; there's nothing separate to sign up for. (Skip it with `ROBIN_SKILL=0`,
|
|
229
|
+
or install it by hand with that command.) Once it's there, you can say things like:
|
|
230
|
+
|
|
231
|
+
> "review this PR with Robin" · "robin this PR" · "fix the Robin feedback and merge"
|
|
232
|
+
|
|
233
|
+
…and the agent drives a bounded review → fix → re-review → merge loop: it waits for
|
|
234
|
+
Robin's review, fixes only the findings it can verify (skipping noise from weaker free
|
|
235
|
+
models), replies to each comment, resolves threads, and merges when green — capped at
|
|
236
|
+
five passes. Source: [skills/robin/SKILL.md](skills/robin/SKILL.md).
|
|
237
|
+
|
|
238
|
+
## Supported providers
|
|
239
|
+
|
|
240
|
+
| Provider | `LLM_BASE_URL` | `LLM_MODEL` example |
|
|
241
|
+
| --- | --- | --- |
|
|
242
|
+
| **OpenRouter (free)** | `https://openrouter.ai/api/v1` | `openrouter/free` |
|
|
243
|
+
| OpenAI | `https://api.openai.com/v1` | `gpt-4o` |
|
|
244
|
+
| Groq | `https://api.groq.com/openai/v1` | `llama-3.3-70b-versatile` |
|
|
245
|
+
| Ollama (your server) | `http://YOUR_SERVER:11434/v1` | `llama3.2` |
|
|
246
|
+
|
|
247
|
+
GitHub’s servers cannot reach `localhost` on your laptop. For Ollama at home, use a public server, a tunnel, or a [self-hosted runner](docs/ADVANCED.md#save-github-actions-minutes).
|
|
248
|
+
|
|
249
|
+
## Optional: config and custom rules
|
|
250
|
+
|
|
251
|
+
Copy [`.github/robin.yml.example`](.github/robin.yml.example) to `.github/robin.yml` to set `max-diff-size`, skip extra paths, and more. Details: [docs/ADVANCED.md](docs/ADVANCED.md#repository-config-file).
|
|
252
|
+
|
|
253
|
+
Add `.github/code-reviewer.md` in your repo:
|
|
254
|
+
|
|
255
|
+
```md
|
|
256
|
+
# Reviewer rules
|
|
257
|
+
|
|
258
|
+
- Focus on bugs and security, not formatting.
|
|
259
|
+
- Ask for tests when business logic changes.
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
## Something went wrong?
|
|
263
|
+
|
|
264
|
+
| Problem | What to try |
|
|
265
|
+
| --- | --- |
|
|
266
|
+
| Workflow fails immediately | Check all three secrets exist and the workflow uses `@main` |
|
|
267
|
+
| `Input required: model` or `llm-base-url` | Add missing secrets (Step 2) |
|
|
268
|
+
| Review never appears | Open **Actions** tab → open the failed run → read the error |
|
|
269
|
+
| `/robin` does nothing | Put `/robin` on the **first** line; you need write access on the repo. On `@v1`, pin `@v1.4.0`+ or use `/review` if the tag predates v1.4.0 |
|
|
270
|
+
| Review is very short | PR may be huge — see [docs/ADVANCED.md](docs/ADVANCED.md) (`max-diff-size`) |
|
|
271
|
+
| `Empty response from LLM` | Free routers sometimes return no text — the action retries automatically; comment `/robin` again |
|
|
272
|
+
| `OpenRouter stall` / job runs 15 min with no review | Auto-router hung — action now aborts after 45s with no stream and retries | Watch Actions log for `LLM resolved model` (routing OK); pin `@v2` or `@main` for the fix |
|
|
273
|
+
| `404 Provider returned error` | Normal for `openrouter/free` when one provider is down — the action retries up to 5 times; keep `LLM_MODEL=openrouter/free` |
|
|
274
|
+
|
|
275
|
+
More fixes: [docs/ADVANCED.md#troubleshooting](docs/ADVANCED.md#troubleshooting)
|
|
276
|
+
|
|
277
|
+
## Version pins
|
|
278
|
+
|
|
279
|
+
| Pin | When to use |
|
|
280
|
+
| --- | --- |
|
|
281
|
+
| `@main` | Latest changes on the default branch |
|
|
282
|
+
| `@v1` | Latest `1.x` release (updated on each release) |
|
|
283
|
+
| `@v1.0.0` | Exact version (most predictable) |
|
|
284
|
+
| Full commit SHA | Maximum supply-chain safety |
|
|
285
|
+
|
|
286
|
+
```yaml
|
|
287
|
+
uses: antongulin/robin/.github/workflows/review.yml@v1
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
Releases and notes are published automatically from [CHANGELOG.md](CHANGELOG.md) when changes land on `main`. See [CONTRIBUTING.md](CONTRIBUTING.md) for commit message format.
|
|
291
|
+
|
|
292
|
+
## Learn more
|
|
293
|
+
|
|
294
|
+
- [docs/ADVANCED.md](docs/ADVANCED.md) — all settings, strict mode, manual-only reviews, security notes
|
|
295
|
+
- [CONTRIBUTING.md](CONTRIBUTING.md) — run tests and send pull requests
|
|
296
|
+
- [CHANGELOG.md](CHANGELOG.md) — release history
|
|
297
|
+
|
|
298
|
+
## Support
|
|
299
|
+
|
|
300
|
+
Robin is free and open source (MIT). If it saves you money on code review, you can help keep it maintained:
|
|
301
|
+
|
|
302
|
+
- ⭐ Star the repo — it's the cheapest way to help others find it.
|
|
303
|
+
- 💛 [Sponsor the project](https://github.com/sponsors/antongulin) to support ongoing work.
|
|
304
|
+
- 🐛 [Open an issue](https://github.com/antongulin/robin/issues) for bugs or ideas.
|
|
305
|
+
|
|
306
|
+
Built by [Anton Gulin](https://github.com/antongulin), AI Architect building AI systems, agent workflows, and software automation. Need a custom AI agent, code-review pipeline, or QA automation? Visit [Anton.QA](https://www.anton.qa).
|
|
307
|
+
|
|
308
|
+
## Development
|
|
309
|
+
|
|
310
|
+
```bash
|
|
311
|
+
git clone https://github.com/antongulin/robin.git
|
|
312
|
+
cd robin
|
|
313
|
+
npm ci
|
|
314
|
+
npm run lint
|
|
315
|
+
npm test
|
|
316
|
+
npm run build
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
Runtime code lives in `dist/index.js`; run `npm run build` before releasing. A full build removes intermediate files under `dist/` after bundling so only `index.js` remains locally (same file CI checks against).
|
|
320
|
+
|
|
321
|
+
If you ran `tsc` alone and see extra files under `dist/`, run `npm run clean`.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* npx robin-review — adds the Robin code-review workflow to the current repo.
|
|
4
|
+
* Node port of scripts/install.sh, so it works anywhere npx does (incl. Windows).
|
|
5
|
+
*
|
|
6
|
+
* Writes one file (.github/workflows/robin.yml), never overwrites an existing
|
|
7
|
+
* one, then best-effort installs the Robin companion skill for coding agents.
|
|
8
|
+
* Env overrides: ROBIN_REF=v1 (action ref), ROBIN_SKILL=0 (skip skill install).
|
|
9
|
+
*/
|
|
10
|
+
const fs = require("fs");
|
|
11
|
+
const path = require("path");
|
|
12
|
+
const cp = require("child_process");
|
|
13
|
+
|
|
14
|
+
const info = (msg) => console.log("\x1b[0;32m🏹 " + msg + "\x1b[0m");
|
|
15
|
+
const warn = (msg) => console.log("\x1b[0;33m🏹 " + msg + "\x1b[0m");
|
|
16
|
+
const die = (msg) => {
|
|
17
|
+
console.error("\x1b[0;31m🏹 " + msg + "\x1b[0m");
|
|
18
|
+
process.exit(1);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const ref = process.env.ROBIN_REF || "main";
|
|
22
|
+
if (!/^[A-Za-z0-9._/-]{1,100}$/.test(ref)) die("Invalid ROBIN_REF: " + JSON.stringify(ref));
|
|
23
|
+
|
|
24
|
+
let root;
|
|
25
|
+
try {
|
|
26
|
+
root = cp
|
|
27
|
+
.execSync("git rev-parse --show-toplevel", { stdio: ["ignore", "pipe", "ignore"] })
|
|
28
|
+
.toString()
|
|
29
|
+
.trim();
|
|
30
|
+
} catch {
|
|
31
|
+
die("Not a git repository. cd into your repo and run again.");
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const workflowPath = path.join(root, ".github", "workflows", "robin.yml");
|
|
35
|
+
const workflow = `name: Robin
|
|
36
|
+
|
|
37
|
+
on:
|
|
38
|
+
pull_request:
|
|
39
|
+
types: [opened, reopened, ready_for_review]
|
|
40
|
+
issue_comment:
|
|
41
|
+
types: [created]
|
|
42
|
+
|
|
43
|
+
permissions:
|
|
44
|
+
contents: read
|
|
45
|
+
pull-requests: write
|
|
46
|
+
|
|
47
|
+
jobs:
|
|
48
|
+
review:
|
|
49
|
+
uses: antongulin/robin/.github/workflows/review.yml@${ref}
|
|
50
|
+
secrets:
|
|
51
|
+
LLM_API_KEY: \${{ secrets.LLM_API_KEY }}
|
|
52
|
+
LLM_BASE_URL: \${{ secrets.LLM_BASE_URL }}
|
|
53
|
+
LLM_MODEL: \${{ secrets.LLM_MODEL }}
|
|
54
|
+
`;
|
|
55
|
+
|
|
56
|
+
if (fs.existsSync(workflowPath)) {
|
|
57
|
+
warn(workflowPath + " already exists — leaving it untouched.");
|
|
58
|
+
} else {
|
|
59
|
+
fs.mkdirSync(path.dirname(workflowPath), { recursive: true });
|
|
60
|
+
fs.writeFileSync(workflowPath, workflow);
|
|
61
|
+
info("Created " + path.relative(root, workflowPath));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (process.env.ROBIN_SKILL !== "0") {
|
|
65
|
+
info("Installing the Robin chat skill for coding agents…");
|
|
66
|
+
try {
|
|
67
|
+
cp.execSync(
|
|
68
|
+
'npx -y skills add https://github.com/antongulin/robin --skill robin --agent "*" --global --yes',
|
|
69
|
+
{ stdio: "ignore", timeout: 180000 }
|
|
70
|
+
);
|
|
71
|
+
info('Robin chat skill installed (all agents). Say "review with Robin".');
|
|
72
|
+
} catch {
|
|
73
|
+
warn(
|
|
74
|
+
"Couldn't auto-install the skill. Run: npx -y skills add https://github.com/antongulin/robin --skill robin --agent \"*\" --global --yes"
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
info("Next steps:");
|
|
80
|
+
console.log(`
|
|
81
|
+
1. Add three repository secrets (Settings → Secrets and variables → Actions):
|
|
82
|
+
LLM_API_KEY — e.g. your OpenRouter key (sk-or-…)
|
|
83
|
+
LLM_BASE_URL — e.g. https://openrouter.ai/api/v1
|
|
84
|
+
LLM_MODEL — e.g. openrouter/free
|
|
85
|
+
2. Commit and push .github/workflows/robin.yml
|
|
86
|
+
3. Open a PR — Robin reviews it automatically. Comment /robin to re-run.
|
|
87
|
+
|
|
88
|
+
Docs: https://github.com/antongulin/robin#readme
|
|
89
|
+
`);
|
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "robin-review",
|
|
3
|
+
"version": "2.4.1",
|
|
4
|
+
"description": "Free AI code reviews for every PR. BYOK, works with OpenRouter free tier.",
|
|
5
|
+
"bin": {
|
|
6
|
+
"robin-review": "bin/robin-review.js"
|
|
7
|
+
},
|
|
8
|
+
"files": [
|
|
9
|
+
"bin/"
|
|
10
|
+
],
|
|
11
|
+
"engines": {
|
|
12
|
+
"node": ">=18"
|
|
13
|
+
},
|
|
14
|
+
"publishConfig": {
|
|
15
|
+
"access": "public"
|
|
16
|
+
},
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/antongulin/robin.git"
|
|
20
|
+
},
|
|
21
|
+
"bugs": {
|
|
22
|
+
"url": "https://github.com/antongulin/robin/issues"
|
|
23
|
+
},
|
|
24
|
+
"homepage": "https://github.com/antongulin/robin#readme",
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsc && ncc build dist/index.js -o dist && npm run clean",
|
|
27
|
+
"clean": "node scripts/clean-dist.js",
|
|
28
|
+
"dev": "ts-node src/main.ts",
|
|
29
|
+
"lint": "eslint src/**/*.ts",
|
|
30
|
+
"test": "jest",
|
|
31
|
+
"package": "ncc build dist/index.js -o dist --license licenses.txt && npm run clean"
|
|
32
|
+
},
|
|
33
|
+
"keywords": [
|
|
34
|
+
"github-action",
|
|
35
|
+
"code-review",
|
|
36
|
+
"llm",
|
|
37
|
+
"ai",
|
|
38
|
+
"openai",
|
|
39
|
+
"ollama",
|
|
40
|
+
"self-hosted"
|
|
41
|
+
],
|
|
42
|
+
"author": "antongulin",
|
|
43
|
+
"license": "MIT",
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"@actions/core": "^1.10.1",
|
|
46
|
+
"@actions/github": "^6.0.0",
|
|
47
|
+
"@octokit/rest": "^20.0.2",
|
|
48
|
+
"openai": "^4.28.4"
|
|
49
|
+
},
|
|
50
|
+
"overrides": {
|
|
51
|
+
"undici": "^7.25.0"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@types/jest": "^29.5.12",
|
|
55
|
+
"@types/node": "^20.11.19",
|
|
56
|
+
"@typescript-eslint/eslint-plugin": "^7.0.2",
|
|
57
|
+
"@typescript-eslint/parser": "^7.0.2",
|
|
58
|
+
"@vercel/ncc": "^0.38.1",
|
|
59
|
+
"eslint": "^8.56.0",
|
|
60
|
+
"jest": "^29.7.0",
|
|
61
|
+
"ts-jest": "^29.1.2",
|
|
62
|
+
"ts-node": "^10.9.2",
|
|
63
|
+
"typescript": "^5.3.3"
|
|
64
|
+
}
|
|
65
|
+
}
|