@satanwagen/reviewkit 0.1.3 → 0.1.4

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 CHANGED
@@ -1,5 +1,58 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.4 — 2026-09-02
4
+
5
+ ### Added
6
+
7
+ - **`reviewkit` terminal CLI** (in `@satanwagen/reviewkit-cli`, zero deps,
8
+ Node 21+): `cd repo && reviewkit` opens an interactive live view of every
9
+ review item across the site's pages: presence (who is online, in their
10
+ colours), arrow-key navigation, Enter for actions (detail, apply with
11
+ Claude Code, copy prompt, set status, delete), `a` to hand all open items
12
+ to Claude Code, filters, live toasts for new / changed / deleted items.
13
+ Piped output falls back to a plain table plus event stream. `list`, `show`,
14
+ `status`, `delete`, `watch`, `export`, `prompt`, `rooms`, `projects`, `key`.
15
+ Project resolution: `-p name` → `.reviewkit/project.json` (walks up from
16
+ cwd) → `.reviewkit/emblema-sync.json` → global active project.
17
+ - **One-click pairing.** `reviewkit setup` detects the site's sync settings in
18
+ the repo, listens on loopback (127.0.0.1:48780–48783) and the review panel's
19
+ new **Connect terminal / agent…** dialog finds it and pushes the connection.
20
+ Nothing to copy. A copyable `rkc_…` key remains for remote machines
21
+ (`reviewkit connect <key>`). CSP: the panel needs `connect-src
22
+ http://127.0.0.1:*` for this (already required by the Emblema bridge).
23
+ - **MCP bridge for coding agents.** `reviewkit mcp` is a stdio MCP server
24
+ with `reviewkit_prompt`, `reviewkit_list`, `reviewkit_show`,
25
+ `reviewkit_set_status`, `reviewkit_delete`, `reviewkit_export`,
26
+ `reviewkit_rooms`, `reviewkit_projects`. `setup` / `mcp-install` register it
27
+ in Claude Code (`claude mcp add`) and Cursor (`~/.cursor/mcp.json`).
28
+ Statuses set by the agent appear live in reviewers' browsers.
29
+ - **Sync server: `rooms` request** (protocol v1, additive). Returns the routes
30
+ of the connection's origin that have review data, live or on disk, with item
31
+ counts and online peers. Needed by the CLI. Deployed on the satanwagen
32
+ server, reachable again at `wss://2-59-219-26.sslip.io/rk-sync` (sslip.io
33
+ hostname, no domain to expire) — and the client's default `syncUrl` again.
34
+ - Panel gear menu: **Connect terminal / agent…** (enabled when live sync is on).
35
+
36
+ ### Changed
37
+
38
+ - **One word does everything: `<ReviewKit token="…" />`.** Live collaboration
39
+ is on by default: `syncUrl` defaults to the public ReviewKit server
40
+ `wss://2-59-219-26.sslip.io/rk-sync` (sslip.io hostname → VPS IP, nothing to
41
+ expire) and `syncToken` defaults to `token`. The server is now
42
+ **self-serve**: any token of at least 8 characters gets its own private set
43
+ of rooms (keyed by origin + route + hash(token)), so no account and no
44
+ server-side step exist. New prop `sync={false}` forces solo mode;
45
+ `syncToken` stays as an override when the room secret should differ from
46
+ the review link. Existing installs that set `token` but no `syncToken`
47
+ start syncing on upgrade — pass `sync={false}` to keep the old solo mode.
48
+ Same in the CLI: `init --sync-url` is optional, state files still carrying
49
+ the retired host fall back to the default with a warning, and `reviewkit
50
+ setup` picks up the review token from the repo as the room secret.
51
+ - `@satanwagen/reviewkit-cli` now ships two tools. `npx -y
52
+ @satanwagen/reviewkit-cli …` runs `reviewkit`; the Emblema agent is
53
+ `npx -p @satanwagen/reviewkit-cli reviewkit-emblema …` (docs and in-app
54
+ hints updated).
55
+
3
56
  ## 0.1.3 — 2026-09-02
4
57
 
5
58
  Defaults tightened so a production build behaves the way its code reads.
@@ -24,7 +77,7 @@ each has a one-line migration below.
24
77
  stays disabled until both `--sync-url` and `--sync-token` are configured).
25
78
  - **CLI moved to `@satanwagen/reviewkit-cli`.** The main package no longer
26
79
  ships a `bin`, so a host `npm install` does not pull the Emblema agent.
27
- Migration: `npx @satanwagen/reviewkit-cli init …` / `serve` (the command
80
+ Migration: `npx -p @satanwagen/reviewkit-cli reviewkit-emblema init …` / `serve` (the command
28
81
  inside is still `reviewkit-emblema`).
29
82
  - **`emblema.repoPath` is optional.** The repo path is Emblema's local
30
83
  knowledge (advertised in its `/intake/ping` answer, and present in
package/README.md CHANGED
@@ -17,10 +17,10 @@ import { ReviewKit } from '@satanwagen/reviewkit/lazy'; // Vite, CRA, Remix
17
17
  // import { ReviewKit } from '@satanwagen/reviewkit/next'; // Next.js App Router ('use client' built in)
18
18
 
19
19
  // anywhere in your tree, rendered once:
20
- <ReviewKit token={import.meta.env.VITE_REVIEW_TOKEN} />
20
+ <ReviewKit token="pick-any-word" />
21
21
  ```
22
22
 
23
- That's it. The component renders `null` unless review mode is active, and all UI lives in a shadow root appended to `document.body` — your CSS never leaks in, reviewkit's CSS never leaks out. Safe to ship in production builds.
23
+ That's it — one word. Reviewers open `https://your-site/?review=pick-any-word`; the same word is also the secret of your private rooms on the public ReviewKit sync server, so presence, live cursors, shared items, the terminal CLI and the Claude Code bridge all work with no server-side step. The component renders `null` unless review mode is active, and all UI lives in a shadow root appended to `document.body` — your CSS never leaks in, reviewkit's CSS never leaks out. Safe to ship in production builds. Want it offline? `sync={false}`.
24
24
 
25
25
  Three entries, same props:
26
26
 
@@ -49,8 +49,9 @@ if (shouldActivate({ token: TOKEN })) void import('./reviewHost');
49
49
  | `enabled` | `boolean` | Master switch, default `true`. `false` renders nothing, installs nothing. Lets you write `enabled={Boolean(TOKEN)}` instead of `if (!TOKEN) return null`. |
50
50
  | `devAutoOn` | `boolean` | Force the layer on for this page load, no link needed. Host-controlled dev convenience (`devAutoOn={import.meta.env.DEV}`); the library never reads `NODE_ENV`. Still subject to `enabled`, `allowedHosts` and `?review=off`. |
51
51
  | `allowedHosts` | `string[]` | Hostname allowlist with `*` wildcards (`['localhost', '*.staging.example']`). Outside it nothing activates, token or not. Unset = any host (with a one-time console warning on URL activation on a public host). |
52
- | `syncUrl` | `string` | WebSocket endpoint of your sync server (`realtime/server`), e.g. `wss://your-site.tld/rk-sync`. **No default.** |
53
- | `syncToken` | `string` | Shared secret of the sync server. Live collaboration (presence, cursors, shared items) runs only when **both** `syncUrl` and `syncToken` are set; otherwise solo mode, no network. Public in the bundle by nature — a gate against casual visitors, not a secret. |
52
+ | `syncUrl` | `string` | WebSocket endpoint of the sync server. Default: the public ReviewKit server `wss://2-59-219-26.sslip.io/rk-sync`, so live collaboration needs no server of your own. Override for a self-hosted `realtime/server`. |
53
+ | `sync` | `boolean` | Live collaboration switch, default `true`. `false` = solo mode, no network. |
54
+ | `syncToken` | `string` | Secret of your rooms on the sync server, **defaults to `token`**. Any string of 8+ characters gets its own private rooms on the public server. Override only if the room secret should differ from the review link. Public in the bundle by nature. |
54
55
  | `emblema` | `{ repoPath?: string; port?: number }` | Enables the Emblema bridge (`emblema={{}}` is enough). See "Pairing with Emblema". |
55
56
  | `defaultAuthor` | `string` | Pre-fills the reviewer name. |
56
57
  | `fxAssetsUrl` | `string` | Base URL for the `/` effect soundtracks (`<base>/rick.mp3` for `/ondro`). Default: the public ReviewKit assets host `https://2-59-219-26.sslip.io/rk-assets`. Override to self-host. Needs `media-src` in CSP. |
@@ -95,18 +96,16 @@ The sticky session is per tab (`sessionStorage`), bound to the token and renewed
95
96
  enabled={Boolean(TOKEN)}
96
97
  token={TOKEN}
97
98
  allowedHosts={['staging.your-site.tld', '*.preview.your-site.tld']}
98
- syncUrl="wss://your-site.tld/rk-sync"
99
- syncToken={SYNC_TOKEN}
100
99
  />
101
100
  ```
102
101
 
103
- `token` + `allowedHosts` together: the token says *who*, the allowlist says *where*. Without `allowedHosts` a URL activation on a non-loopback host logs one console warning. `TOKEN`/`SYNC_TOKEN` are public in the bundle by design; use the `/lazy` or `/next` entry so they at least live in the review chunk, not the main one.
102
+ `token` + `allowedHosts` together: the token says *who*, the allowlist says *where*. Without `allowedHosts` a URL activation on a non-loopback host logs one console warning. `TOKEN` is public in the bundle by design; use the `/lazy` or `/next` entry so it at least lives in the review chunk, not the main one.
104
103
 
105
104
  ### CSP
106
105
 
107
106
  If the host sends a `Content-Security-Policy`, `connect-src` must allow:
108
107
 
109
- - the sync server origin, as `wss://your-site.tld` (or the `ws:` origin in dev),
108
+ - the sync server origin: `https://2-59-219-26.sslip.io` for the default server (or your own `syncUrl` origin / `ws:` in dev),
110
109
  - `http://127.0.0.1:*` when the `emblema` prop is set (intake ports 48752–48755, pairing agent 48770–48773).
111
110
 
112
111
  and `media-src` must allow `https://2-59-219-26.sslip.io` (or your `fxAssetsUrl`) for the `/` effect sounds; without it the effects run silent.
@@ -267,17 +266,17 @@ Step by step, for any site on any hosting (nginx, IIS, Vercel, …).
267
266
 
268
267
  Run `npm run build` inside ReviewKit at least once for the `file:`/git variants (the package resolves to `dist/`). With React 18 add `resolve.dedupe: ['react','react-dom']` to your bundler config when using a `file:` link.
269
268
 
270
- **2. Integrate — two lines, done:**
269
+ **2. Integrate — one line, done:**
271
270
 
272
271
  ```tsx
273
272
  import { ReviewKit } from '@satanwagen/reviewkit/lazy';
274
273
 
275
- <ReviewKit token="my-site-token" syncUrl="wss://your-site.tld/rk-sync" syncToken="<the sync server's shared secret>" />
274
+ <ReviewKit token="my-site-token" />
276
275
  ```
277
276
 
278
- Live collaboration (presence, live cursors, instantly shared items) runs only when **both** `syncUrl` and `syncToken` are set there is no default server. Rooms are keyed by the page's origin + path, so different sites never see each other's feedback or presence. If the server is unreachable the tool silently runs local-only (no console errors); omit either prop to disable networking entirely.
277
+ Live collaboration (presence, live cursors, instantly shared items) is on by default: `syncUrl` points at the public ReviewKit server `wss://2-59-219-26.sslip.io/rk-sync` and the room secret is your `token` (8+ characters; `syncToken` overrides it). The server is self-serve: every token gets its own private rooms, no account, no registration. Rooms are keyed by the page's origin + path, so different sites never see each other's feedback or presence. If the server is unreachable the tool silently runs local-only (no console errors); omit either prop to disable networking entirely.
279
278
 
280
- **What a shared server implies (honesty section):** the token and `syncToken` are readable in the browser bundle, so anyone holding a review URL can join and create rooms. Run the server for your own sites only; it is guarded by the shared token, per-connection rate limits (40 msg/s, burst 80), 1 MiB frame cap, 16 clients and 2000 items per room, and a live-room ceiling (`RK_SYNC_MAX_ROOMS`, default 500).
279
+ **What a shared server implies (honesty section):** the token is readable in the browser bundle and in every review link, so anyone holding the link can join your rooms that is the point of a review link. Rooms of different tokens never mix. The public server is guarded by per-connection rate limits (40 msg/s, burst 80), 1 MiB frame cap, 16 clients and 2000 items per room, and a live-room ceiling (`RK_SYNC_MAX_ROOMS`, default 500).
281
280
 
282
281
  **3. Run the sync server** — `realtime/server/`: `npm run build`, run `dist/server.js` with `RK_SYNC_TOKEN` (+ optional `RK_SYNC_PORT`, `RK_SYNC_DATA`, `RK_SYNC_MAX_ROOMS`, and `RK_SYNC_ORIGINS` if you *want* an origin allowlist — empty/unset means any origin, which is the default deployment) as a service, point `syncUrl` at it, then put a WebSocket-aware reverse proxy in front:
283
282
 
@@ -301,6 +300,30 @@ Live collaboration (presence, live cursors, instantly shared items) runs only wh
301
300
 
302
301
  **5. Verify it works:** open `https://your-site/?review=<token>` — the Review badge appears; the panel header shows **live** (green dot) when the sync server accepted you, or *local only* when not. In the Network tab you should see one WebSocket to `/rk-sync` with a `welcome` frame. Open the same URL in a second browser: avatars, live cursors and instantly-appearing items confirm collaboration.
303
302
 
303
+ ## Terminal & coding agents (`reviewkit` CLI)
304
+
305
+ Review comments do not have to stay in the browser. The `reviewkit` CLI reads the same live rooms, and doubles as the MCP bridge for Claude Code, Cursor and any other MCP client, so an agent can read every comment and mark items applied while reviewers watch the status flip live.
306
+
307
+ ```sh
308
+ npm install -g @satanwagen/reviewkit-cli
309
+ cd my-site
310
+ reviewkit # first run pairs the repo (one click in the review panel), then the live view
311
+ ```
312
+
313
+ **Pairing is one click, no copy-paste.** Bare `reviewkit` in an unpaired repo runs `setup` first; it detects the site's `token` (and a custom `syncToken` / `syncUrl`, if any) in the repo, opens a loopback port and waits. In the browser open the review panel → gear → **Connect terminal / agent…** → **Connect**: the panel finds the waiting terminal and pushes the connection into `<repo>/.reviewkit/project.json` (gitignored). `setup` also registers the MCP server in Claude Code and Cursor when it finds them. The dialog keeps a copyable key as the fallback for a terminal on another machine.
314
+
315
+ The live view is interactive: arrow keys walk the items, Enter opens actions (detail, apply this item with Claude Code, copy as prompt, mark applied / accepted / rejected / reopen, delete), `a` hands every open item to Claude Code in the repo, and the header shows who is reviewing right now in their own colours. Everything is the shared room state, so a status flipped in the terminal or by an agent changes in reviewers' browsers instantly, and vice versa.
316
+
317
+ Everyday commands: `reviewkit list --status open`, `reviewkit show <id>`, `reviewkit status <id> applied`, `reviewkit watch`, `reviewkit export -o review.json`, `reviewkit prompt` (agent-ready work list), `reviewkit rooms`, `reviewkit projects` / `-p <name>` to act on another paired site. Full table in [`cli/README.md`](./cli/README.md).
318
+
319
+ **Agents.** With the bridge registered, "apply the reviewkit feedback" is enough: the agent calls `reviewkit_prompt`, edits code, then `reviewkit_set_status(id, "applied")` per item. Manual registration:
320
+
321
+ ```sh
322
+ claude mcp add --scope user reviewkit -- npx -y @satanwagen/reviewkit-cli mcp
323
+ ```
324
+
325
+ Requirements: the site has live sync on (the default), Node 21+. The CLI reads shared rooms, never a reviewer's local browser storage. The sync server gained a `rooms` request (protocol v1, additive) so the CLI can find every page with review data; run the 0.1.4 server build.
326
+
304
327
  ## Pairing with Emblema
305
328
 
306
329
  ReviewKit pairs with the [Emblema](https://emblema.app) desktop app: once paired, the local sync agent streams review items to Emblema, and the paired Emblema shows them as findings in its ReviewKit tile (statuses flow back to the page).
@@ -314,8 +337,8 @@ Sync is automatic and realtime — no manual step. With `emblema={{}}` in the `R
314
337
  **Set up and generate a key** (in the project repo; the CLI is its own package so host installs stay CLI-free):
315
338
 
316
339
  ```sh
317
- npx @satanwagen/reviewkit-cli init --origin https://your-site --sync-url wss://your-site/rk-sync --sync-token <secret>
318
- npx @satanwagen/reviewkit-cli serve # local API + realtime bridge (bridge needs both sync flags)
340
+ npx -p @satanwagen/reviewkit-cli reviewkit-emblema init --origin https://your-site --sync-url wss://your-site/rk-sync --sync-token <secret>
341
+ npx -p @satanwagen/reviewkit-cli reviewkit-emblema serve # local API + realtime bridge (bridge needs both sync flags)
319
342
  ```
320
343
 
321
344
  Paste the printed key into Emblema. From the page UI the same lives in the panel's gear menu → **Connect to Emblema…** — the menu entry shows the live pairing status at a glance (green dot = paired, amber = the local agent isn't answering, red = key revoked, grey = not paired), and the dialog has **New key (rotate)**, **Copy key** and **Delete key (revoke)**.
@@ -323,9 +346,9 @@ Paste the printed key into Emblema. From the page UI the same lives in the panel
323
346
  **Rotate / revoke from the CLI:**
324
347
 
325
348
  ```sh
326
- npx @satanwagen/reviewkit-cli key # print the current key
327
- npx @satanwagen/reviewkit-cli rotate # issue a new secret — the old key stops working immediately
328
- npx @satanwagen/reviewkit-cli revoke # disable the pairing entirely (rotate re-enables)
349
+ npx -p @satanwagen/reviewkit-cli reviewkit-emblema key # print the current key
350
+ npx -p @satanwagen/reviewkit-cli reviewkit-emblema rotate # issue a new secret — the old key stops working immediately
351
+ npx -p @satanwagen/reviewkit-cli reviewkit-emblema revoke # disable the pairing entirely (rotate re-enables)
329
352
  ```
330
353
 
331
354
  Rotate and revoke take effect immediately, including against an already-running `serve` process — authenticated requests always check the current on-disk key, so a rotated or revoked key can never keep authenticating.
@@ -340,7 +363,7 @@ npm install
340
363
  npm run dev # http://localhost:3010 — devAutoOn keeps the layer on in dev
341
364
  ```
342
365
 
343
- Also try `http://localhost:3010/?review=demo` to exercise URL activation. `examples/next-demo` is the same site on Next.js (App Router, `/next` entry, CSP headers) on port 3011.
366
+ Also try `http://localhost:3010/?review=demo-review` to exercise URL activation. `examples/next-demo` is the same site on Next.js (App Router, `/next` entry, CSP headers) on port 3011.
344
367
 
345
368
  ## Development
346
369