VS Code companion (vscode/) #1

Open
opened 2026-11-12 01:50:50 +01:00 by thatrichan · 6 comments
Owner

Moved from thatrichan/revue#69.

A VS Code extension, Revue Companion, doing what the JetBrains plugin (jetbrains/) does: the repository's pull requests from Revue inside the editor, and the way back, with Revue opening a pull request in the VS Code window that has its branch.

It should also run in the editors built on VS Code (VSCodium, Cursor, Windsurf…), so it's published on both the VS Code Marketplace and Open VSX.

Features (as in the JetBrains plugin)

  • Revue: Open or Create Pull Request (Command Palette, Source Control title bar, status bar item): opens the current branch's pull request in Revue, or its New pull request page; revue --pull-request <folder>.
  • A Pull Requests view in its own activity bar container: the repository's open pull requests as Revue sees them (revue --pulls with --show, drafts, search, more pages), in Revue's sections (This branch, To review, Mine, Others), favorites first. Selecting one opens its details in a webview: review, checks, conflicts, files, conversation, Slack threads, stack (revue --pull), with Open in Revue, Open in browser, Copy link, Switch to Branch, Create Worktree (--worktree), Fetch branch (--fetch-branch).
  • In the editor: the branch's pull request's changes and pending comments marked in the gutter (--branch-pull, --pending), Open File in Pull Request at the cursor's line (LINK --file … --line …), Add Pending Comment on the selection (--comment), Go to Pull Request File (a quick pick of its files).
  • Status bar: the branch's pull request number and state; a click opens it.
  • Settings: revueCompanion.path (the revue executable; empty: PATH, then the install places the JetBrains plugin looks in), and what to do when Revue isn't running (once thatrichan/revue#66 lands: answer anyway, or offer to start it).
  • Several Git repositories in a workspace: a picker, as the JetBrains tool window has.

It talks to Revue only through the revue command (Revue's docs/command-line.md, "What editors can ask"), and checks revue --version's editor <N> line before using it, as the JetBrains plugin does. No tokens enter the editor.

The way back: Revue reaching a running VS Code

JetBrains IDEs answer on their built-in server (/api/revue-projects, /api/revue-open). VS Code has no such server, so:

  • The extension registers itself: on activation it listens on 127.0.0.1 on a free port, and writes <Revue's data folder>/companions/vscode-<pid>.json: { "kind": "vscode", "app": "Visual Studio Code" | "Cursor" | …, "pid", "port", "token", "version" }. It removes the file on deactivation; Revue ignores a file whose pid isn't running or whose port refuses.
  • The same two requests as the JetBrains plugin: GET /revue-projects (the window's workspace folders, each repository's root, branch and remotes, and whether the window is focused) and GET /revue-open?path=&repo=&branch=&file=&line= (focus this window if it has the branch, else vscode.openFolder in a new window, then the file at the line). Each request carries the token from the file, so no other local program can drive the editor.
  • One server per window (every VS Code window is its own extension host), so Revue picks the window, as with JetBrains.
  • In Revue (thatrichan/revue): a companions module that reads the folder alongside the JetBrains port scan, giving the editor chooser (thatrichan/revue#68) one list of running companions of every kind. The registration format is shared with the Neovim companion.

Where it lives

vscode/ in this repository (TypeScript, @vscode/vsce and ovsx for packaging and publishing): build, test (@vscode/test-electron against a fake revue that prints fixture JSON), package (.vsix), and a release-vscode workflow started by hand (patch, minor, major), like release-jetbrains. Publisher: cleangamedev (display name Clean Gamedev, the JetBrains plugin's vendor), the same ID as the Open VSX namespace, so the extension is cleangamedev.revue-companion.

Publishing

  • The workflow tags vscode-vX.Y.Z, builds the .vsix once, attaches it to the Forgejo release, and publishes it to Open VSX with ovsx publish (Forgejo secret OPEN_VSX_TOKEN, passed as OVSX_PAT).
  • VS Code Marketplace: uploaded by hand for now: the same .vsix from the release, at https://marketplace.visualstudio.com/manage → cleangamedev → Update. Automated publishing isn't available without Azure: Azure DevOps personal access tokens for the Marketplace are global PATs, retired on 2026-12-01, and a new Azure DevOps organization needs an Azure subscription. The release's summary says the upload is left to do.
  • Later, if manual uploads get tedious: either vsce publish --azure-credential with an Entra ID service principal (needs a Pay-As-You-Go Azure subscription, no cost; secrets AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET), or vsce publish --oidc trusted publishing from a GitHub Actions mirror (GitHub only; could share a mirror with #5).

Plan

  1. The registration folder and companions module in Revue, with tests (a fake registration file, a stale one, a wrong token).
  2. The extension's skeleton: finding revue, --version, Open or Create Pull Request, the status bar item.
  3. The Pull Requests view and the details webview.
  4. Editor markers, Open File in Pull Request, Add Pending Comment, Go to Pull Request File.
  5. The local server and /revue-open, then thatrichan/revue#68 choosing it.
  6. Docs: Revue's docs/editors.md gets a VS Code section; publishing as above.
*Moved from thatrichan/revue#69.* A VS Code extension, **Revue Companion**, doing what the JetBrains plugin ([`jetbrains/`](../src/branch/main/jetbrains)) does: the repository's pull requests from Revue inside the editor, and the way back, with Revue opening a pull request in the VS Code window that has its branch. It should also run in the editors built on VS Code (VSCodium, Cursor, Windsurf…), so it's published on both the **VS Code Marketplace** and **Open VSX**. ## Features (as in the JetBrains plugin) - **Revue: Open or Create Pull Request** (Command Palette, Source Control title bar, status bar item): opens the current branch's pull request in Revue, or its New pull request page; `revue --pull-request <folder>`. - **A Pull Requests view** in its own activity bar container: the repository's open pull requests as Revue sees them (`revue --pulls` with `--show`, drafts, search, more pages), in Revue's sections (This branch, To review, Mine, Others), favorites first. Selecting one opens its details in a webview: review, checks, conflicts, files, conversation, Slack threads, stack (`revue --pull`), with Open in Revue, Open in browser, Copy link, Switch to Branch, Create Worktree (`--worktree`), Fetch branch (`--fetch-branch`). - **In the editor:** the branch's pull request's changes and pending comments marked in the gutter (`--branch-pull`, `--pending`), **Open File in Pull Request** at the cursor's line (`LINK --file … --line …`), **Add Pending Comment** on the selection (`--comment`), **Go to Pull Request File** (a quick pick of its files). - **Status bar:** the branch's pull request number and state; a click opens it. - **Settings:** `revueCompanion.path` (the `revue` executable; empty: PATH, then the install places the JetBrains plugin looks in), and what to do when Revue isn't running (once thatrichan/revue#66 lands: answer anyway, or offer to start it). - Several Git repositories in a workspace: a picker, as the JetBrains tool window has. It talks to Revue only through the `revue` command (Revue's `docs/command-line.md`, "What editors can ask"), and checks `revue --version`'s `editor <N>` line before using it, as the JetBrains plugin does. No tokens enter the editor. ## The way back: Revue reaching a running VS Code JetBrains IDEs answer on their built-in server (`/api/revue-projects`, `/api/revue-open`). VS Code has no such server, so: - **The extension registers itself:** on activation it listens on `127.0.0.1` on a free port, and writes `<Revue's data folder>/companions/vscode-<pid>.json`: `{ "kind": "vscode", "app": "Visual Studio Code" | "Cursor" | …, "pid", "port", "token", "version" }`. It removes the file on deactivation; Revue ignores a file whose pid isn't running or whose port refuses. - **The same two requests** as the JetBrains plugin: `GET /revue-projects` (the window's workspace folders, each repository's root, branch and remotes, and whether the window is focused) and `GET /revue-open?path=&repo=&branch=&file=&line=` (focus this window if it has the branch, else `vscode.openFolder` in a new window, then the file at the line). Each request carries the `token` from the file, so no other local program can drive the editor. - **One server per window** (every VS Code window is its own extension host), so Revue picks the window, as with JetBrains. - **In Revue (thatrichan/revue):** a `companions` module that reads the folder alongside the JetBrains port scan, giving the editor chooser (thatrichan/revue#68) one list of running companions of every kind. The registration format is shared with the Neovim companion. ## Where it lives `vscode/` in this repository (TypeScript, `@vscode/vsce` and `ovsx` for packaging and publishing): build, test (`@vscode/test-electron` against a fake `revue` that prints fixture JSON), package (`.vsix`), and a `release-vscode` workflow started by hand (patch, minor, major), like `release-jetbrains`. Publisher: `cleangamedev` (display name Clean Gamedev, the JetBrains plugin's vendor), the same ID as the Open VSX namespace, so the extension is `cleangamedev.revue-companion`. ## Publishing - **The workflow** tags `vscode-vX.Y.Z`, builds the `.vsix` once, attaches it to the Forgejo release, and publishes it to **Open VSX** with `ovsx publish` (Forgejo secret `OPEN_VSX_TOKEN`, passed as `OVSX_PAT`). - **VS Code Marketplace: uploaded by hand** for now: the same `.vsix` from the release, at https://marketplace.visualstudio.com/manage → `cleangamedev` → Update. Automated publishing isn't available without Azure: Azure DevOps personal access tokens for the Marketplace are global PATs, retired on 2026-12-01, and a new Azure DevOps organization needs an Azure subscription. The release's summary says the upload is left to do. - **Later, if manual uploads get tedious:** either `vsce publish --azure-credential` with an Entra ID service principal (needs a Pay-As-You-Go Azure subscription, no cost; secrets `AZURE_TENANT_ID`, `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`), or `vsce publish --oidc` trusted publishing from a GitHub Actions mirror (GitHub only; could share a mirror with #5). ## Plan 1. The registration folder and `companions` module in Revue, with tests (a fake registration file, a stale one, a wrong token). 2. The extension's skeleton: finding `revue`, `--version`, Open or Create Pull Request, the status bar item. 3. The Pull Requests view and the details webview. 4. Editor markers, Open File in Pull Request, Add Pending Comment, Go to Pull Request File. 5. The local server and `/revue-open`, then thatrichan/revue#68 choosing it. 6. Docs: Revue's `docs/editors.md` gets a VS Code section; publishing as above.
Author
Owner

The skeleton is in (merged in cbec851):

  • vscode/: TypeScript bundled with esbuild, cleangamedev.revue-companion 0.1.0.
  • Finding revue (revueCompanion.path, PATH, then the JetBrains plugin's install places), gating on editor N, --headless from editor 2.
  • Revue: Open or Create Pull Request in the Command Palette and the Source Control title, and the branch's pull request in the status bar (#7 Open, Draft, Merged, Closed, or Create Pull Request).
  • revueCompanion.whenNotRunning (answer, offer, start), as in JetBrains.
  • task vscode:unit-test, vscode:test (in a real VS Code against the JetBrains fake revue; VSCODE_EXECUTABLE for an installed VS Code or VSCodium), vscode:package (.vsix).

26 unit tests and 6 editor tests pass (VSCodium 1.143). Next: the Pull Requests view. The way back needs thatrichan/revue#80 first.

The skeleton is in (merged in cbec851): - `vscode/`: TypeScript bundled with esbuild, `cleangamedev.revue-companion` 0.1.0. - Finding `revue` (`revueCompanion.path`, PATH, then the JetBrains plugin's install places), gating on `editor N`, `--headless` from `editor 2`. - **Revue: Open or Create Pull Request** in the Command Palette and the Source Control title, and the branch's pull request in the status bar (`#7 Open`, Draft, Merged, Closed, or Create Pull Request). - `revueCompanion.whenNotRunning` (answer, offer, start), as in JetBrains. - `task vscode:unit-test`, `vscode:test` (in a real VS Code against the JetBrains fake `revue`; `VSCODE_EXECUTABLE` for an installed VS Code or VSCodium), `vscode:package` (.vsix). 26 unit tests and 6 editor tests pass (VSCodium 1.143). Next: the Pull Requests view. The way back needs thatrichan/revue#80 first.
Author
Owner

The Pull Requests view is in (merged in 2165e27):

  • Its own activity bar container: the branch's card, then the repository's pull requests in Revue's sections, favorites first; search, Revue's filters, drafts, more on scroll, a repository chooser when the workspace has several; refreshed on a branch switch and every 3 minutes.
  • A pull request's page in the same view: state, author, branches, Open in Revue / in the browser, copy links, Switch to Branch (fetching it first), Create Worktree, the star, and the tabs (how it stands, files, conversation, Slack threads, stack). Escape goes back.
  • Colors from VS Code's theme, a strict CSP, nothing from Revue inserted as HTML.
  • The shared fake revue got Slack threads and a stack for #7 / #13.

55 unit and 12 editor tests pass (VSCodium 1.143, against the fake). Next: the UI walk with pictures, then the editor phase (changes, Open File in Pull Request, Add Pending Comment).

The Pull Requests view is in (merged in 2165e27): - Its own activity bar container: the branch's card, then the repository's pull requests in Revue's sections, favorites first; search, Revue's filters, drafts, more on scroll, a repository chooser when the workspace has several; refreshed on a branch switch and every 3 minutes. - A pull request's page in the same view: state, author, branches, Open in Revue / in the browser, copy links, Switch to Branch (fetching it first), Create Worktree, the star, and the tabs (how it stands, files, conversation, Slack threads, stack). Escape goes back. - Colors from VS Code's theme, a strict CSP, nothing from Revue inserted as HTML. - The shared fake `revue` got Slack threads and a stack for #7 / #13. 55 unit and 12 editor tests pass (VSCodium 1.143, against the fake). Next: the UI walk with pictures, then the editor phase (changes, Open File in Pull Request, Add Pending Comment).
Author
Owner

The editor phase is in (merged in abeec26):

  • The pull request's changes in the gutter, through VS Code's own quick diff against the file before the pull request (--sides, editor 3): stripes, peek, next / previous change. Shown only while the checkout is at the pull request's head, as in JetBrains.
  • Show Pull Request Diff, Open File in Pull Request at the cursor's line, Go to Pull Request File…, Add Pending Comment… on the selection; menus only on the pull request's files.
  • Your pending comments marked on their lines, with a hover that opens them in Revue, and counted in the status bar's tooltip.
  • task vscode:ui-test: walks the extension in VS Code, light and dark, a picture of each step in vscode/build/ui-screenshots/. Its first pictures caught three layout bugs in the Files tab and the page, fixed.

65 unit and 20 editor tests pass (VSCodium 1.143). To check: that the second quick diff draws in VS Code 1.95 (the oldest supported), Cursor and Windsurf, and whether the empty "Revue Pull Request" row it adds in Source Control is acceptable. Next: Review in IDE.

The editor phase is in (merged in abeec26): - The pull request's changes in the gutter, through VS Code's own quick diff against the file before the pull request (`--sides`, editor 3): stripes, peek, next / previous change. Shown only while the checkout is at the pull request's head, as in JetBrains. - **Show Pull Request Diff**, **Open File in Pull Request** at the cursor's line, **Go to Pull Request File…**, **Add Pending Comment…** on the selection; menus only on the pull request's files. - Your pending comments marked on their lines, with a hover that opens them in Revue, and counted in the status bar's tooltip. - `task vscode:ui-test`: walks the extension in VS Code, light and dark, a picture of each step in `vscode/build/ui-screenshots/`. Its first pictures caught three layout bugs in the Files tab and the page, fixed. 65 unit and 20 editor tests pass (VSCodium 1.143). To check: that the second quick diff draws in VS Code 1.95 (the oldest supported), Cursor and Windsurf, and whether the empty "Revue Pull Request" row it adds in Source Control is acceptable. Next: Review in IDE.
Author
Owner

The way back is in (merged in 9b356c8), against thatrichan/revue#80 (editor 9):

  • With Revue at editor 9 or later, each window listens on 127.0.0.1 with a fresh token, registers with revue --companion vscode … --app <editor name>, and takes it back (--companion-gone) on deactivation.
  • GET /revue-projects: this window's workspace folders and their repositories, and whether it has (or last had) the focus. GET /revue-open: the window with the repository on that branch focuses and opens the file at the line; otherwise the folder opens in a new window, which opens the file once it starts. No or a wrong X-Revue-Token gets 401.
  • The shared fake revue answers editor 9 and checks registrations as the contract says.

85 unit and 27 editor tests pass (7 for the way back). To check with a real Revue on a desktop: that Open in editor picks VS Code, that workbench.action.focusWindow brings the window forward (window managers may refuse), and Cursor, Windsurf and VS Code 1.95.

The way back is in (merged in 9b356c8), against thatrichan/revue#80 (`editor 9`): - With Revue at `editor 9` or later, each window listens on 127.0.0.1 with a fresh token, registers with `revue --companion vscode … --app <editor name>`, and takes it back (`--companion-gone`) on deactivation. - `GET /revue-projects`: this window's workspace folders and their repositories, and whether it has (or last had) the focus. `GET /revue-open`: the window with the repository on that branch focuses and opens the file at the line; otherwise the folder opens in a new window, which opens the file once it starts. No or a wrong `X-Revue-Token` gets 401. - The shared fake `revue` answers `editor 9` and checks registrations as the contract says. 85 unit and 27 editor tests pass (7 for the way back). To check with a real Revue on a desktop: that Open in editor picks VS Code, that `workbench.action.focusWindow` brings the window forward (window managers may refuse), and Cursor, Windsurf and VS Code 1.95.
Author
Owner

Review in IDE, the Revue account and the release are in (merged in 4c42dc0):

  • Review in IDE (from a pull request's page or Revue: Review Pull Request): the files in the multi-file diff editor (text from the clone's Git, else --sides); conversations and drafts as comment threads on their lines — reply, resolve / reopen, edit, delete, reactions (editor 8), @ completion from mentionable, a new comment from the gutter's +, a suggestion's Apply to Your Copy.
  • Revue Review view: Submit Review, the files as a tree with status, lines, open conversations and a Viewed checkbox (editor 7); Mark Viewed in a file's diff title.
  • Finish your review: a panel from --submit-options (Write / Preview summary with @, what goes with it, resolve yours, Notify in Slack), verdicts with why they're disabled.
  • Revue: Account and Revue: Sign in to Revue (editor 6); the not-signed-in notice offers signing in.
  • Release: .forgejo/workflows/release-vscode.yml (by hand, patch / minor / major): tags vscode-vX.Y.Z, builds the .vsix once, attaches it to the Forgejo release and publishes to Open VSX (secret OPEN_VSX_TOKEN); the Marketplace upload stays by hand. vscode/README.md is the stores' page.

117 unit, 33 editor and 14 UI-walk steps pass in VSCodium. Left: the first Open VSX / Marketplace listing and the OPEN_VSX_TOKEN secret; checking against a real Revue, and in VS Code 1.95, Cursor and Windsurf.

Review in IDE, the Revue account and the release are in (merged in 4c42dc0): - **Review in IDE** (from a pull request's page or **Revue: Review Pull Request**): the files in the multi-file diff editor (text from the clone's Git, else `--sides`); conversations and drafts as comment threads on their lines — reply, resolve / reopen, edit, delete, reactions (editor 8), `@` completion from `mentionable`, a new comment from the gutter's +, a suggestion's **Apply to Your Copy**. - **Revue Review** view: Submit Review, the files as a tree with status, lines, open conversations and a Viewed checkbox (editor 7); **Mark Viewed** in a file's diff title. - **Finish your review**: a panel from `--submit-options` (Write / Preview summary with `@`, what goes with it, resolve yours, Notify in Slack), verdicts with why they're disabled. - **Revue: Account** and **Revue: Sign in to Revue** (editor 6); the not-signed-in notice offers signing in. - **Release**: `.forgejo/workflows/release-vscode.yml` (by hand, patch / minor / major): tags `vscode-vX.Y.Z`, builds the .vsix once, attaches it to the Forgejo release and publishes to Open VSX (secret `OPEN_VSX_TOKEN`); the Marketplace upload stays by hand. `vscode/README.md` is the stores' page. 117 unit, 33 editor and 14 UI-walk steps pass in VSCodium. Left: the first Open VSX / Marketplace listing and the `OPEN_VSX_TOKEN` secret; checking against a real Revue, and in VS Code 1.95, Cursor and Windsurf.
Author
Owner

Released as vscode 0.1.0 on Open VSX and the Forgejo release; Revue 0.44 has what it needs (editor 8 to 10). CI now runs its tests on every push (vscode.yml). What is left (the Marketplace upload, trying it in Cursor, Windsurf and VS Code 1.95 against a real Revue) is in #9.

Released as **vscode 0.1.0** on Open VSX and the [Forgejo release](https://forgejo.cleangame.dev/thatrichan/revue-companion/releases/tag/vscode-v0.1.0); Revue 0.44 has what it needs (editor 8 to 10). CI now runs its tests on every push (`vscode.yml`). What is left (the Marketplace upload, trying it in Cursor, Windsurf and VS Code 1.95 against a real Revue) is in #9.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
thatrichan/revue-companion#1
No description provided.