OXYGENHUB
# 85a87a2d7d5b oxygenhub-vscode / docs / spec.md
11.4 KiB · Markdown · last changed Write the forge's name as OxygenHub in everything people read 1 month ago renderedsource blame history raw
092b8bf9 Andy McCall ↶ 1
# OxygenHub for Visual Studio Code
f0b06dea Andy McCall 2
3
| | |
4
|---|---|
5
| **Status** | Draft 0.1 |
092b8bf9 Andy McCall ↶ 6
| **Scope** | The forge in the editor: sign in to an OxygenHub, see and review proposals with comments anchored to atoms, approve with a seal, land, work with issues, watch checks, and open anything on the hub. The counterpart of the GitHub Pull Requests and Issues extension. |
7
| **Depends on** | `oxygen-vscode` ≥ 0.7.0 (its exported API and remote providers), OxygenHub ≥ 0.5 (`/api/v1`), `oxy` with `seal --proposal` and `proposal land` |
f0b06dea Andy McCall 8
| **Date** | 2026-09-27 |
9
10
## 1. Goals
11
12
1. **Everything the hub can do about a proposal or an issue is reachable without leaving the editor**, and everything that changes history still goes through `oxy` on the user's machine with the user's key: sealing an approval and landing run `oxy`, never a hub-side signature.
13
2. **Build on oxygen-vscode, never beside it.** Repositories, status, bookmarks and remotes come from its exported API; this extension registers a remote provider so "Open on Remote" works for hubs.
14
3. **Review where the code is.** Proposal comments appear as VS Code comment threads on the projected state's files, anchored to atoms exactly as the hub stores them, so they follow the line through rebases.
15
4. **Honest about identity.** An approval shows as pending until the hub confirms the seal; a check shows what the hub reports.
16
17
Non-goals for 1.0: creating repositories or organisations, administration, notifications beyond the status bar count, editing files on the hub.
18
19
## 2. How it compares
20
092b8bf9 Andy McCall ↶ 21
| GitHub Pull Requests and Issues | OxygenHub for VS Code |
f0b06dea Andy McCall 22
|---|---|
23
| Sign in with GitHub (OAuth) | Sign in with a personal access token; an authentication provider `oxygenhub` other extensions can request |
24
| Pull Requests view: waiting for my review, created by me, all | Proposals view: **Assigned to me** (review requested or approval needed), **Mine**, **Open**, per repository |
25
| Checkout PR branch | Fetch the proposal's changes and check out its projected state into a bookmark (`oxy` fetch + bookmark set) |
26
| Review comments in the diff, threads | Comment threads on the projected state's files via the Comments API, anchored to atoms |
27
| Approve, Request changes | Same; **Approve** also offers to run `oxy seal --proposal` so it counts |
28
| Merge button | **Land** runs `oxy proposal land` (or the hub lands when it has no policy) |
29
| Issues view, create issue | Same, with labels, assignees and milestone |
30
| Checks under the PR | Checks on the projected state, live over the hub's event stream |
31
| Open on GitHub | Open on Remote, through the remote provider |
32
33
## 3. Architecture
34
35
```
36
src/
37
  extension.ts      activation, wiring, commands
38
  auth.ts           AuthenticationProvider "oxygenhub": sessions = {hub base URL, token}, stored in SecretStorage
39
  hub.ts            HubClient: typed fetch over /api/v1 using hub-api's generated types (src/hubapi.d.ts, copied by `npm run types`)
40
  provider.ts       the RemoteProvider registered with oxygen-vscode: matches a session's base URL, builds hub URLs
41
  proposals.ts      TreeDataProvider: proposals by repository and bucket; detail webview; actions
42
  review.ts         CommentController over oxy: content of the projected state, threads placed by atom, reply/resolve
43
  issues.ts         TreeDataProvider: issues; create, comment, close
44
  checks.ts         status bar: checks of the current bookmark's proposal; SSE subscription
45
  hubapi.d.ts       generated from the hub (do not edit)
46
```
47
48
Pure modules (`hub.ts` URL building and parsing, `provider.ts`) are tested with Node against a real hub started from the oxygenhub binary when present; the rest is exercised manually.
49
50
## 4. Sign in
51
52
`oxygenhub.signIn` asks for the hub URL (default: the first remote that looks like a hub, `https://…/owner/name` minus the last two segments) and a personal access token (Settings › Tokens on the hub; scopes `repo:read repo:write proposals:write issues:write`). The token is kept in `SecretStorage` under the base URL; sessions are exposed through `vscode.authentication` so oxygen-vscode or others can reuse them. `oxygenhub.signOut` forgets it.
53
54
## 5. Proposals
55
092b8bf9 Andy McCall ↶ 56
The **OxygenHub: Proposals** view lists, per repository that has a hub remote, proposals in three groups: needing me (open, not mine, where I have not approved or where my approval is pending a seal), mine, and other open ones. Each row shows number, title, author, target, state chips (draft, conflicted, landable) and the check summary. Actions: open detail, open on hub, check out, review (comment / request changes / approve), seal approval, land, close.
f0b06dea Andy McCall 57
58
**Detail** is a webview: description, blockers, approvals (sealed or pending), checks, the changes list with signatures, and buttons for the actions. **Check out** fetches from the hub remote and sets a local bookmark `proposal/N` to the projected heads, then switches to it, so the files in the editor are the projected state; review threads then appear in place.
59
bf73998c Andy McCall ↶ 60
### 5.1 Diff editors
61
62
Each proposal row expands to the files it changes (`GET …/proposals/N/files`), with a diff icon per kind and `+added −removed`. Clicking a file opens VS Code's own diff editor; **View Changes** on the row (or in the detail) opens every file in one multi-file diff editor (`vscode.changes`). Both sides are read-only documents of the `oxygenhub-proposal` scheme, served from `GET …/proposals/N/content/{base|head}/{path}`: the target bookmark's state on the left, the projected state on the right, so a proposal can be read and reviewed without checking it out. A side where the file does not exist is empty; a rename shows its old path on the left. Open sides reload on refresh, since a proposal gains changes when its source bookmark moves.
63
f0b06dea Andy McCall 64
## 6. Review threads
65
66
A `CommentController` for the checked-out proposal. Threads come from `GET …/proposals/N/comments`; each anchored comment is placed by asking oxy for the current line of its atom (`oxy blame --json` gives atoms per line; the extension finds the line whose `(hash, index)` matches). Replying posts a comment anchored to the same atom; a new thread on a line posts with the line's atom. Resolve toggles the hub's resolved flag. Threads whose atom is no longer live are shown in a separate "outdated" list in the view.
67
bf73998c Andy McCall ↶ 68
In the diff editors (§5.1) the same controller places threads on the projected side only, at the line the hub reports for each anchored comment (the API's `line`, found by blame on the projected state), so no checkout or local `oxy` call is needed. A new thread or reply there posts the file and line; the hub anchors it to that line's atom.
69
f902d5b8 Andy McCall ↶ 70
### 6.2 References while typing
71
72
In the Oxygen commit box and in comment editors, `#` completes the repository's issues and proposals (one number space, open ones first, newest first; the title is shown and matched) and `@` completes people: the authors and assignees of those issues and proposals, and the signed-in user. Hovering a `#N` shows its kind, state, title and author with a link to the hub. The commit box's repository is the one its source control names (`rootUri`); a comment editor uses the workspace's hub repository when there is exactly one. The lists are fetched per repository and reused for a minute, and cleared on refresh.
73
f0b06dea Andy McCall 74
## 7. Approvals and landing
75
76
**Approve** posts the review, then offers to run `oxy seal --proposal <url>` in the repository's terminal so the approval is backed by the user's seal; the row shows "pending seal" until the hub reports it sealed. **Land** runs `oxy proposal land <url>` in a terminal (the hub's own landing is offered when the hub reports it can land, for repositories without a policy). Both use the integrated terminal so the user sees exactly what runs with their key.
77
78
## 8. Issues
79
092b8bf9 Andy McCall ↶ 80
The **OxygenHub: Issues** view lists open issues per repository (assigned to me first). Actions: open detail (webview with the timeline and a comment box), open on hub, create issue (title and body inputs), close, reopen, assign to me.
f0b06dea Andy McCall 81
95f69b4a Andy McCall ↶ 82
### 8.1 Issues from the editor
83
84
**New Issue from Selection** (editor context menu) opens an issue quoting the selected lines, or the current line when nothing is selected, under a permalink to them on the hub: to the bookmark's head when it has exactly one and the file is saved, otherwise to the bookmark, with a note that the lines may move. A `TODO`, `FIXME`, `XXX` or `HACK` line suggests the title, and after the issue is opened the extension offers to write its number into the line (`TODO(#12): …`). The new issue opens in the editor.
85
1cc0ff44 Andy McCall ↶ 86
### 8.2 Releases
87
88
The **Releases** view lists each repository's releases, newest first (`GET /repos/{o}/{n}/releases`): title, tag, `latest` or `pre-release`, date; the tooltip shows the start of the notes. Expanding a release lists its uploaded assets (size, downloads) and the hub's source archives; picking one downloads it through the browser, picking the release opens it on the hub.
89
90
**Draft Release…** (the view's title bar, or inline on a repository) releases a tag that has none yet: pick the tag (`GET /tags`, minus those already released), confirm a title (the tag's message by default), and choose release or pre-release (a tag such as `v2.0-rc1` or `1.0.0-beta.2` suggests pre-release). The notes are generated: the changes in the tag's history that the newest full release's tag does not have, newest first, one line each with the message's subject and a short hash. The release is created with `POST /releases`; assets are uploaded on the hub or with `oxy`. Editing notes after creation happens on the hub.
91
f0b06dea Andy McCall 92
## 9. Checks and status bar
93
94
A status bar item shows, for the current repository's current bookmark, the open proposal whose source it is and the state of its checks (✔ n passed, ✘ failing, … running). It subscribes to the hub's proposal event stream and refreshes on `check` events; clicking opens the proposal.
95
b2dd082c Andy McCall ↶ 96
### 9.1 Notifications
97
98
A bell in the status bar shows the unread count summed over every signed-in hub (`GET /notifications`, polled on `oxygenhub.autoRefresh`). When the count rises, a message names the newest entry (or the number of new ones) with **Open Inbox**; `oxygenhub.announceNotifications` turns that off. **Open Inbox** is a quick pick of the newest entries, unread first, with **Mark all as read** at the top. Picking one marks it read and opens it in the editor when it is a proposal or issue of a repository in the workspace (the proposal detail or the issue view), otherwise on the hub. A hub whose token lacks `user:read` is skipped and named in the bell's tooltip.
99
f0b06dea Andy McCall 100
## 10. Configuration
101
102
`oxygenhub.hubs`: known hub base URLs (also learnt from sign in). `oxygenhub.proposalBookmarkPrefix`: `proposal/`. `oxygenhub.autoRefresh`: seconds between view refreshes (60).
103
104
## 11. Milestones
105
106
| | Delivers |
107
|---|---|
108
| **0.1** | Sign in, hub client with generated types, remote provider (Open on Remote works), proposals view with detail and open-on-hub, issues view with create and comment |
109
| **0.2** | Check out a proposal, review threads on atoms, reviews, seal and land through the terminal, checks in the status bar with live events |
110
| **0.3** | Issues: labels, assignees, milestones; notifications count; create proposal from the current bookmark |
111
| **1.0** | Marketplace listing beside oxygen-vscode, three-platform tests |
112
113
## 12. Open questions
114
115
1. Whether to render the proposal diff in a native diff editor (base vs projected content via an `oxyhub:` content provider) instead of the webview's file list. Likely yes in 0.2, since threads need real editors anyway.
116
2. Token scopes: the extension could ask for a narrower token per action. Not for 1.0.