agent-feedbacker 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +16 -0
- package/.claude-plugin/plugin.json +8 -0
- package/.mcp.json +8 -0
- package/LICENSE +21 -0
- package/README.md +161 -2
- package/bin/feedbacker.mjs +78 -0
- package/package.json +53 -4
- package/skills/review/SKILL.md +33 -0
- package/src/core.mjs +281 -0
- package/src/dist/THIRD_PARTY_LICENSES.txt +307 -0
- package/src/dist/app.css +1 -0
- package/src/dist/app.js +16 -0
- package/src/dist/favicon.svg +5 -0
- package/src/dist/fonts/atkinson-hyperlegible-next-latin-ext-wght-normal-2N3YVG5Z.woff2 +0 -0
- package/src/dist/fonts/atkinson-hyperlegible-next-latin-wght-normal-VX3WN42K.woff2 +0 -0
- package/src/dist/fonts/jetbrains-mono-cyrillic-ext-wght-normal-BUWC6ZS3.woff2 +0 -0
- package/src/dist/fonts/jetbrains-mono-cyrillic-wght-normal-ENSFVLK4.woff2 +0 -0
- package/src/dist/fonts/jetbrains-mono-greek-wght-normal-Y3BRZMJV.woff2 +0 -0
- package/src/dist/fonts/jetbrains-mono-latin-ext-wght-normal-TSLVDSQR.woff2 +0 -0
- package/src/dist/fonts/jetbrains-mono-latin-wght-normal-VBS632QH.woff2 +0 -0
- package/src/dist/fonts/jetbrains-mono-vietnamese-wght-normal-SP6EBKAH.woff2 +0 -0
- package/src/mcp.mjs +140 -0
- package/src/page.html +14 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "feedbacker",
|
|
3
|
+
"owner": {
|
|
4
|
+
"name": "Pavel Polivka"
|
|
5
|
+
},
|
|
6
|
+
"metadata": {
|
|
7
|
+
"description": "Feedbacker: review a coding agent's changes across several git repos in a local MR-style page."
|
|
8
|
+
},
|
|
9
|
+
"plugins": [
|
|
10
|
+
{
|
|
11
|
+
"name": "feedbacker",
|
|
12
|
+
"source": "./",
|
|
13
|
+
"description": "Review an agent's changes across several git repos in a local MR-style page and send line comments back to it."
|
|
14
|
+
}
|
|
15
|
+
]
|
|
16
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "feedbacker",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Review an agent's changes across several git repos in a local MR-style page and send line comments back to it.",
|
|
5
|
+
"author": { "name": "Pavel Polivka" },
|
|
6
|
+
"repository": "https://github.com/PavlikPolivka/feedbacker",
|
|
7
|
+
"license": "MIT"
|
|
8
|
+
}
|
package/.mcp.json
ADDED
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Pavel Polivka
|
|
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
CHANGED
|
@@ -1,3 +1,162 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Feedbacker
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A local, merge-request-style review page for coding agents. The agent passes the git repos it changed, a summary and optionally some questions. You see the diffs of **all of them on one page**, comment on lines, answer the questions, and click **Approve** or **Request changes**. The agent gets your feedback back as markdown it can act on.
|
|
4
|
+
|
|
5
|
+
- **Multi-repo and worktrees**: any repos anywhere on disk, each with its own base; `--worktrees` pulls in every git worktree of a repo, so parallel agents' work is reviewed together.
|
|
6
|
+
- **Simple**: one Node process with no runtime dependencies; nothing to install or build to use it. The page is a small React 19 app whose bundle (with highlight.js) is committed in `src/dist/`.
|
|
7
|
+
- **Local**: binds to `127.0.0.1` with a random token in the URL. Nothing leaves your machine, and git is only read.
|
|
8
|
+
- **Three ways in**: a Claude Code plugin (MCP tool + skill), a plain MCP server for other agents, and a CLI for anything with a shell.
|
|
9
|
+
|
|
10
|
+

|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
### Claude Code plugin
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
claude plugin marketplace add PavlikPolivka/feedbacker
|
|
18
|
+
claude plugin install feedbacker@feedbacker
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
This gives Claude:
|
|
22
|
+
|
|
23
|
+
- the MCP tool `request_review` (it shows up as `mcp__plugin_feedbacker_feedbacker__request_review`)
|
|
24
|
+
- the skill `/feedbacker:review`, which tells Claude when and how to ask for a review
|
|
25
|
+
|
|
26
|
+
Then just say "let me review it" or run `/feedbacker:review`. To try it from a checkout without installing: `claude --plugin-dir /path/to/feedbacker`.
|
|
27
|
+
|
|
28
|
+
### Any MCP client
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"mcpServers": {
|
|
33
|
+
"feedbacker": { "command": "npx", "args": ["-y", "agent-feedbacker", "mcp"] }
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### CLI
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm install -g agent-feedbacker # or run it once with: npx agent-feedbacker
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The npm package is `agent-feedbacker`; the command is `feedbacker`. Node 22 or newer; git on `PATH`. From a checkout, `node bin/feedbacker.mjs` works too.
|
|
45
|
+
|
|
46
|
+
## Use
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
feedbacker ~/Projects/api ~/Projects/web@main \
|
|
50
|
+
-m "Bind the API to localhost; document the port" \
|
|
51
|
+
-q "Should the port also be a CLI flag?"
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
- `repo` diffs the working tree (staged, unstaged and untracked files) against `HEAD`.
|
|
55
|
+
- `repo@base` diffs against any commit, branch or tag, so work the agent already committed is included. With a branch, the diff starts where `HEAD` forked from it (like a merge request), so newer commits on that branch don't show up reversed.
|
|
56
|
+
- A worktree path works like any repo. `-w` / `--worktrees` adds every worktree of each repo (main and linked, each labelled with its branch), all against the same base:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
feedbacker ~/Projects/api@main --worktrees # main checkout + every agent's worktree
|
|
60
|
+
```
|
|
61
|
+
- The command blocks until you submit, then prints the feedback (`--json` for JSON) and exits 0. Exit 2 means there was nothing to review.
|
|
62
|
+
- `feedbacker list` prints the URLs of reviews waiting for you, for when the browser didn't open (MCP clients usually hide a server's output).
|
|
63
|
+
- `--no-open` only prints the URL; `--port` fixes the port.
|
|
64
|
+
|
|
65
|
+
In the browser:
|
|
66
|
+
|
|
67
|
+
- Click a line number to comment on that line (a highlighter "+" shows where); shift-click a second one to comment on a range. Ctrl+Enter saves, Esc cancels.
|
|
68
|
+
- With several repos, the picker in the top bar switches between all of them and a single one (the summary, questions and your comments in other repos stay). The top bar also shows the size of the change and keeps **Approve** and **Request changes** in reach; files can be collapsed, and the file tree shows where your comments are.
|
|
69
|
+
- Comments, answers and the general comment are kept in the browser's local storage until you submit, so a refresh loses nothing.
|
|
70
|
+
- **Approve** or **Request changes** sends everything to the agent and closes the server.
|
|
71
|
+
|
|
72
|
+
## MCP tool
|
|
73
|
+
|
|
74
|
+
`request_review`:
|
|
75
|
+
|
|
76
|
+
| Argument | Type | |
|
|
77
|
+
|---|---|---|
|
|
78
|
+
| `repos` | `[{ path, base?, worktrees? }]` | Required. Absolute paths; `base` defaults to `HEAD`; `worktrees: true` adds all worktrees of that repo. |
|
|
79
|
+
| `summary` | string | Shown at the top of the page. |
|
|
80
|
+
| `questions` | string[] | Shown with an answer box each. |
|
|
81
|
+
|
|
82
|
+
It blocks until the user submits (Claude Code keeps long MCP calls open; it sends progress notifications every 30 s for clients that need them) and returns markdown like:
|
|
83
|
+
|
|
84
|
+
````markdown
|
|
85
|
+
# Review feedback
|
|
86
|
+
|
|
87
|
+
Verdict: **changes requested**
|
|
88
|
+
|
|
89
|
+
## General
|
|
90
|
+
|
|
91
|
+
Almost there.
|
|
92
|
+
|
|
93
|
+
## Answers
|
|
94
|
+
|
|
95
|
+
**Q: Should the port also be a CLI flag?**
|
|
96
|
+
|
|
97
|
+
No, env is enough.
|
|
98
|
+
|
|
99
|
+
## Comments
|
|
100
|
+
|
|
101
|
+
### /home/me/Projects/api
|
|
102
|
+
|
|
103
|
+
**src/server.ts:6** (new side)
|
|
104
|
+
|
|
105
|
+
```diff
|
|
106
|
+
+ server.listen(port, "127.0.0.1");
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Make the host configurable too.
|
|
110
|
+
````
|
|
111
|
+
|
|
112
|
+
Each comment carries the code it refers to, so line numbers drifting doesn't lose the context. Cancelling the tool call closes the review page.
|
|
113
|
+
|
|
114
|
+
## How it works
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
agent ──request_review / CLI──▶ feedbacker ──git diff per repo──▶ review in memory
|
|
118
|
+
feedbacker ──opens──▶ http://127.0.0.1:PORT/?t=TOKEN ──you submit──▶ feedbacker
|
|
119
|
+
feedbacker ──markdown (tool result / stdout)──▶ agent
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
| File | |
|
|
123
|
+
|---|---|
|
|
124
|
+
| `src/core.mjs` | Reads diffs (`git diff <base>` plus untracked files), parses them, serves the page, formats feedback. |
|
|
125
|
+
| `src/page.html` | Page shell: styles, and the bundle from `src/dist/`. |
|
|
126
|
+
| `src/ui/` | The review page in React 19 (JSX): diff table, inline comments, questions, submit; highlight.js for syntax, `styles.css` for the look (light and dark, colour tokens at the top). |
|
|
127
|
+
| `src/dist/` | The committed bundle (JS, CSS and fonts), built from `src/ui/` by `build.mjs` (esbuild). |
|
|
128
|
+
| `src/mcp.mjs` | Minimal MCP server over stdio (JSON-RPC), one tool. |
|
|
129
|
+
| `bin/feedbacker.mjs` | CLI: review, `list`, `mcp`. |
|
|
130
|
+
| `skills/review/SKILL.md`, `.mcp.json`, `.claude-plugin/` | The Claude Code plugin and its marketplace entry. |
|
|
131
|
+
|
|
132
|
+
Open reviews write a small file (URL, repos, pid) to `$XDG_STATE_HOME/feedbacker/` (default `~/.local/state/feedbacker/`, mode 0600) and remove it when they finish; `list` reads them.
|
|
133
|
+
|
|
134
|
+
## Development
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
pnpm install # dev dependencies only: React, highlight.js, fonts, esbuild
|
|
138
|
+
pnpm build # after changing src/ui: rebuilds src/dist (commit it)
|
|
139
|
+
pnpm test
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Using Feedbacker needs none of this; only working on the page does. A test fails when `src/dist` doesn't match `src/ui`.
|
|
143
|
+
|
|
144
|
+
The tests use real temporary git repos. They cover diff parsing, the HTTP server, the MCP protocol over stdio, and an end-to-end run that drives the page in headless Chromium (skipped when no Chromium is found; set `CHROMIUM=/path` to pick one).
|
|
145
|
+
|
|
146
|
+
CI runs the tests on Node 22 and 24 for every push and pull request (`.github/workflows/ci.yml`).
|
|
147
|
+
|
|
148
|
+
### Releasing
|
|
149
|
+
|
|
150
|
+
Publishing to npm is done by GitHub Actions (`.github/workflows/publish.yml`) with npm trusted publishing, so no npm token is stored anywhere and each version gets a provenance statement.
|
|
151
|
+
|
|
152
|
+
1. Bump `version` in `package.json` (and `.claude-plugin/plugin.json`), commit, push.
|
|
153
|
+
2. Create a GitHub release with the tag `vX.Y.Z` matching that version: `gh release create v0.2.0 --generate-notes`.
|
|
154
|
+
3. The workflow checks the tag, runs the tests and publishes.
|
|
155
|
+
|
|
156
|
+
One-time setup: on npmjs.com, add a trusted publisher for the package (GitHub Actions, repository `PavlikPolivka/feedbacker`, workflow `publish.yml`). npm only offers that once the package exists, so the very first version is published by hand with `npm publish --access public`.
|
|
157
|
+
|
|
158
|
+
Plans: [ROADMAP.md](ROADMAP.md).
|
|
159
|
+
|
|
160
|
+
## Licence
|
|
161
|
+
|
|
162
|
+
MIT. The bundle in `src/dist/` includes React, ReactDOM and scheduler (MIT), highlight.js (BSD-3-Clause), and the Atkinson Hyperlegible Next and JetBrains Mono fonts (OFL-1.1); their licences are in `src/dist/THIRD_PARTY_LICENSES.txt`. The fonts are served locally, so the page never loads anything from the internet.
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Feedbacker CLI: `feedbacker [repos...]` opens a review page and prints the
|
|
3
|
+
// feedback when the user submits; `feedbacker mcp` runs the MCP server.
|
|
4
|
+
|
|
5
|
+
import { buildReview, hasChanges, listReviews, startReview, toMarkdown } from '../src/core.mjs';
|
|
6
|
+
import { runMcp } from '../src/mcp.mjs';
|
|
7
|
+
|
|
8
|
+
const USAGE = `Usage: feedbacker [options] [repo[@base] ...]
|
|
9
|
+
feedbacker list
|
|
10
|
+
feedbacker mcp
|
|
11
|
+
|
|
12
|
+
Opens a review page for the changes in each repo (default: current directory)
|
|
13
|
+
and prints the feedback to stdout when the user submits.
|
|
14
|
+
|
|
15
|
+
repo[@base] Repo or worktree path; diff the working tree (including
|
|
16
|
+
untracked files) against base. Default base: HEAD. With a
|
|
17
|
+
branch as base, the diff starts where HEAD forked from it.
|
|
18
|
+
-w, --worktrees Also review every other worktree of each repo.
|
|
19
|
+
-m, --summary TXT What the agent changed, shown at the top.
|
|
20
|
+
-q, --question TXT A question for the user (repeatable).
|
|
21
|
+
--json Print JSON instead of markdown.
|
|
22
|
+
--port N Port to listen on (default: random).
|
|
23
|
+
--no-open Don't open the browser; only print the URL to stderr.
|
|
24
|
+
-h, --help Show this help.
|
|
25
|
+
|
|
26
|
+
list Show the URLs of reviews that are waiting for you.
|
|
27
|
+
mcp Run as an MCP server on stdio (tool: request_review).`;
|
|
28
|
+
|
|
29
|
+
function fail(msg) {
|
|
30
|
+
console.error(`feedbacker: ${msg}`);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function parseArgs(argv) {
|
|
35
|
+
const opts = { repos: [], questions: [], summary: '', worktrees: false, json: false, port: 0, open: true };
|
|
36
|
+
for (let i = 0; i < argv.length; i++) {
|
|
37
|
+
const a = argv[i];
|
|
38
|
+
const next = () => {
|
|
39
|
+
if (i + 1 >= argv.length) fail(`${a} needs a value`);
|
|
40
|
+
return argv[++i];
|
|
41
|
+
};
|
|
42
|
+
if (a === '-h' || a === '--help') { console.log(USAGE); process.exit(0); }
|
|
43
|
+
else if (a === '-m' || a === '--summary') opts.summary = next();
|
|
44
|
+
else if (a === '-q' || a === '--question') opts.questions.push(next());
|
|
45
|
+
else if (a === '-w' || a === '--worktrees') opts.worktrees = true;
|
|
46
|
+
else if (a === '--json') opts.json = true;
|
|
47
|
+
else if (a === '--port') opts.port = Number(next());
|
|
48
|
+
else if (a === '--no-open') opts.open = false;
|
|
49
|
+
else if (a.startsWith('-')) fail(`unknown option ${a}\n\n${USAGE}`);
|
|
50
|
+
else opts.repos.push(a);
|
|
51
|
+
}
|
|
52
|
+
if (!opts.repos.length) opts.repos.push('.');
|
|
53
|
+
return opts;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Exit cleanly on signals so open reviews remove their state files.
|
|
57
|
+
for (const sig of ['SIGINT', 'SIGTERM', 'SIGHUP']) process.on(sig, () => process.exit(130));
|
|
58
|
+
|
|
59
|
+
const argv = process.argv.slice(2);
|
|
60
|
+
if (argv[0] === 'mcp') {
|
|
61
|
+
runMcp();
|
|
62
|
+
} else if (argv[0] === 'list') {
|
|
63
|
+
const reviews = listReviews();
|
|
64
|
+
if (!reviews.length) console.log('No reviews waiting.');
|
|
65
|
+
for (const r of reviews) console.log(`${r.url}\n ${r.started} ${r.repos.join(', ')}${r.summary ? `\n ${r.summary}` : ''}`);
|
|
66
|
+
} else {
|
|
67
|
+
const opts = parseArgs(argv);
|
|
68
|
+
const review = buildReview(opts);
|
|
69
|
+
for (const r of review.repos) if (r.error) console.error(`feedbacker: ${r.path}: ${r.error}`);
|
|
70
|
+
if (!hasChanges(review) && !review.questions.length) {
|
|
71
|
+
console.error('feedbacker: no changes to review');
|
|
72
|
+
process.exit(2);
|
|
73
|
+
}
|
|
74
|
+
const { url, feedback } = await startReview(review, { port: opts.port, open: opts.open });
|
|
75
|
+
console.error(`feedbacker: waiting for review at ${url}`);
|
|
76
|
+
const fb = await feedback;
|
|
77
|
+
process.stdout.write(opts.json ? JSON.stringify(fb, null, 2) + '\n' : toMarkdown(review, fb));
|
|
78
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,55 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-feedbacker",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A local merge-request-style review page that coding agents open to collect your line comments and answers, across several git repos.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"feedbacker": "bin/feedbacker.mjs"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin",
|
|
11
|
+
"src/*.mjs",
|
|
12
|
+
"src/page.html",
|
|
13
|
+
"src/dist",
|
|
14
|
+
"skills",
|
|
15
|
+
".claude-plugin",
|
|
16
|
+
".mcp.json"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "node build.mjs",
|
|
20
|
+
"test": "node --test test/*.test.mjs"
|
|
21
|
+
},
|
|
22
|
+
"engines": {
|
|
23
|
+
"node": ">=22"
|
|
24
|
+
},
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "git+https://github.com/PavlikPolivka/feedbacker.git"
|
|
28
|
+
},
|
|
29
|
+
"keywords": [
|
|
30
|
+
"claude-code",
|
|
31
|
+
"mcp",
|
|
32
|
+
"code-review",
|
|
33
|
+
"diff",
|
|
34
|
+
"agent"
|
|
35
|
+
],
|
|
36
|
+
"author": "Pavel Polivka",
|
|
37
|
+
"license": "MIT",
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@fontsource-variable/atkinson-hyperlegible-next": "^5.3.0",
|
|
40
|
+
"@fontsource-variable/jetbrains-mono": "^5.3.0",
|
|
41
|
+
"esbuild": "^0.28.2",
|
|
42
|
+
"highlight.js": "^11.12.0",
|
|
43
|
+
"react": "^19.3.1",
|
|
44
|
+
"react-dom": "^19.3.1"
|
|
45
|
+
},
|
|
46
|
+
"pnpm": {
|
|
47
|
+
"onlyBuiltDependencies": [
|
|
48
|
+
"esbuild"
|
|
49
|
+
]
|
|
50
|
+
},
|
|
51
|
+
"homepage": "https://github.com/PavlikPolivka/feedbacker#readme",
|
|
52
|
+
"bugs": {
|
|
53
|
+
"url": "https://github.com/PavlikPolivka/feedbacker/issues"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: review
|
|
3
|
+
description: Ask the user to review your changes in a local merge-request-style page and get their line comments, answers and verdict back. Use when the user asks for a review ("let me review", "show me the diff", "feedbacker"), or after finishing a non-trivial change, especially one that spans several git repos, before you commit, push or call the work done.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Review with Feedbacker
|
|
7
|
+
|
|
8
|
+
Feedbacker opens a review page in the user's browser with the diffs of the repos you pass. The user comments on lines, answers your questions and clicks **Approve** or **Request changes**. You get their feedback back as markdown.
|
|
9
|
+
|
|
10
|
+
## How
|
|
11
|
+
|
|
12
|
+
1. List **every git repo and worktree you changed in this session**, as absolute paths. Include repos outside the current directory. If the work is spread over several worktrees of one repo (e.g. parallel agents), pass one of them with `"worktrees": true` instead of listing each.
|
|
13
|
+
2. Pick a base per repo:
|
|
14
|
+
- Uncommitted changes only: leave `base` out (it defaults to `HEAD`).
|
|
15
|
+
- You committed during the session: use the commit the session started from (`git log` to find it) or the branch you forked from, e.g. `main`.
|
|
16
|
+
3. Call the `request_review` tool of the `feedbacker` MCP server with:
|
|
17
|
+
- `repos`: `[{ "path": "/abs/path", "base": "main", "worktrees": false }, ...]`
|
|
18
|
+
- `summary`: two to five sentences on what you changed and why.
|
|
19
|
+
- `questions`: only real decisions you want the user to make (optional).
|
|
20
|
+
4. Before the call, tell the user a review page is opening in their browser. If it doesn't appear, they can run `node "${CLAUDE_PLUGIN_ROOT}/bin/feedbacker.mjs" list` to get its URL. The tool returns once they submit, however long that takes.
|
|
21
|
+
|
|
22
|
+
If the MCP tool isn't available, run the CLI in the background instead, so the shell timeout doesn't kill it, and read its output when it exits:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
node "${CLAUDE_PLUGIN_ROOT}/bin/feedbacker.mjs" /abs/repo-a /abs/repo-b@main \
|
|
26
|
+
-m "What changed" -q "A question?"
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## After the review
|
|
30
|
+
|
|
31
|
+
- **Changes requested:** address every comment. Each one names the repo, file, line range and the code it refers to. Answer comments you disagree with instead of silently skipping them. Then offer another review round.
|
|
32
|
+
- **Approved:** carry on (commit, push, or whatever was next), taking any comments and answers into account.
|
|
33
|
+
- Use the answers to your questions as decisions; don't ask them again.
|