OXYGENHUB

0.1.1: review comments anchored to atoms through the API; regenerated types 486c15b00314

Author
Andy McCall @andymccall <[email protected]>
When
· 2026-09-27 21:51 UTC
Signature
✔ signed by Andy McCall
Hash
486c15b00314c09e79fc67bc32afe955fa4bb0c3c6be7ca88ac548324362ae2e
Depends on
f0b06deac4b9
Depended on by
991516a107fa d21a85954a34 85a87a2d7d5b d8ac8f93fd34 bd69712343d2 263de209e5ba 5888949525ec e04950748142 092b8bf9f2ac 1cc0ff44e5ca 95f69b4a3ac2 b2dd082c57e4 bf73998c5198 52cef00143db
In bookmarks
main
In tags
v0.10.0 v0.10.1 v0.10.2 v0.11.0 v0.11.1 v0.11.2 v0.13.0
Edits
22 atoms, 0 tree operations, 5 files

Browse the tree at this change

modified CHANGELOG.md +5 −0
1 1
# Changelog
2 2
3 +
## 0.1.1
4 +
5 +
- Review replies and new threads are anchored to the line's atom through the hub API, so they follow the line through rebases.
6 +
- Hub API types regenerated (releases, anchored comments).
7 +
3 8
## 0.1.0
4 9
5 10
- Sign in to a hub with a personal access token (an `oxygenhub` authentication provider).
…
6 unchanged lines
modified package.json +253 −50
…
1 unchanged lines
2 2
  "name": "oxygenhub-vscode",
3 3
  "displayName": "Oxygenhub",
4 4
  "description": "Proposals, reviews, issues and checks from an Oxygenhub, in the editor. Builds on the Oxygen extension.",
5 -
  "version": "0.1.0",
5 +
  "version": "0.1.1",
6 6
  "publisher": "andymccall",
7 7
  "license": "MIT OR Apache-2.0",
8 8
  "icon": "assets/images/oxygenhub.png",
9 9
  "engines": {
10 10
    "vscode": "^1.137.0"
11 11
  },
12 -
  "categories": ["SCM Providers", "Other"],
13 -
  "keywords": ["oxygen", "oxygenhub", "review", "proposals", "issues"],
14 -
  "extensionDependencies": ["andymccall.oxygen-vscode"],
15 -
  "activationEvents": ["workspaceContains:.oxy/format", "onAuthenticationRequest:oxygenhub", "onStartupFinished"],
12 +
  "categories": [
13 +
    "SCM Providers",
14 +
    "Other"
15 +
  ],
16 +
  "keywords": [
17 +
    "oxygen",
18 +
    "oxygenhub",
19 +
    "review",
20 +
    "proposals",
21 +
    "issues"
22 +
  ],
23 +
  "extensionDependencies": [
24 +
    "andymccall.oxygen-vscode"
25 +
  ],
26 +
  "activationEvents": [
27 +
    "workspaceContains:.oxy/format",
28 +
    "onAuthenticationRequest:oxygenhub",
29 +
    "onStartupFinished"
30 +
  ],
16 31
  "main": "./dist/extension.js",
17 32
  "contributes": {
18 -
    "authentication": [{ "id": "oxygenhub", "label": "Oxygenhub" }],
33 +
    "authentication": [
34 +
      {
35 +
        "id": "oxygenhub",
36 +
        "label": "Oxygenhub"
37 +
      }
38 +
    ],
19 39
    "configuration": {
20 40
      "title": "Oxygenhub",
21 41
      "properties": {
22 -
        "oxygenhub.hubs": { "type": "array", "items": { "type": "string" }, "default": [], "description": "Base URLs of hubs you use (learnt from sign in too)." },
23 -
        "oxygenhub.proposalBookmarkPrefix": { "type": "string", "default": "proposal/", "description": "Prefix of the local bookmark created when checking out a proposal." },
24 -
        "oxygenhub.autoRefresh": { "type": "number", "default": 60, "description": "Seconds between view refreshes; 0 disables." }
42 +
        "oxygenhub.hubs": {
43 +
          "type": "array",
44 +
          "items": {
45 +
            "type": "string"
46 +
          },
47 +
          "default": [],
48 +
          "description": "Base URLs of hubs you use (learnt from sign in too)."
49 +
        },
50 +
        "oxygenhub.proposalBookmarkPrefix": {
51 +
          "type": "string",
52 +
          "default": "proposal/",
53 +
          "description": "Prefix of the local bookmark created when checking out a proposal."
54 +
        },
55 +
        "oxygenhub.autoRefresh": {
56 +
          "type": "number",
57 +
          "default": 60,
58 +
          "description": "Seconds between view refreshes; 0 disables."
59 +
        }
25 60
      }
26 61
    },
27 62
    "viewsContainers": {
28 -
      "activitybar": [{ "id": "oxygenhub", "title": "Oxygenhub", "icon": "assets/images/oxygenhub.svg" }]
63 +
      "activitybar": [
64 +
        {
65 +
          "id": "oxygenhub",
66 +
          "title": "Oxygenhub",
67 +
          "icon": "assets/images/oxygenhub.svg"
68 +
        }
69 +
      ]
29 70
    },
30 71
    "views": {
31 72
      "oxygenhub": [
32 -
        { "id": "oxygenhub.proposals", "name": "Proposals" },
33 -
        { "id": "oxygenhub.issues", "name": "Issues" }
73 +
        {
74 +
          "id": "oxygenhub.proposals",
75 +
          "name": "Proposals"
76 +
        },
77 +
        {
78 +
          "id": "oxygenhub.issues",
79 +
          "name": "Issues"
80 +
        }
34 81
      ]
35 82
    },
36 83
    "viewsWelcome": [
37 -
      { "view": "oxygenhub.proposals", "contents": "Sign in to an Oxygenhub to see proposals.\n[Sign in](command:oxygenhub.signIn)" }
84 +
      {
85 +
        "view": "oxygenhub.proposals",
86 +
        "contents": "Sign in to an Oxygenhub to see proposals.\n[Sign in](command:oxygenhub.signIn)"
87 +
      }
38 88
    ],
39 89
    "commands": [
40 -
      { "command": "oxygenhub.signIn", "title": "Sign in", "category": "Oxygenhub" },
41 -
      { "command": "oxygenhub.signOut", "title": "Sign out", "category": "Oxygenhub" },
42 -
      { "command": "oxygenhub.refresh", "title": "Refresh", "category": "Oxygenhub", "icon": "$(refresh)" },
43 -
      { "command": "oxygenhub.openProposal", "title": "Open Proposal", "category": "Oxygenhub" },
44 -
      { "command": "oxygenhub.openOnHub", "title": "Open on Hub", "category": "Oxygenhub", "icon": "$(link-external)" },
45 -
      { "command": "oxygenhub.checkoutProposal", "title": "Check Out Proposal", "category": "Oxygenhub", "icon": "$(git-branch)" },
46 -
      { "command": "oxygenhub.review", "title": "Review…", "category": "Oxygenhub", "icon": "$(comment-discussion)" },
47 -
      { "command": "oxygenhub.sealApproval", "title": "Seal My Approval (oxy seal --proposal)", "category": "Oxygenhub" },
48 -
      { "command": "oxygenhub.land", "title": "Land Proposal", "category": "Oxygenhub" },
49 -
      { "command": "oxygenhub.closeProposal", "title": "Close Proposal", "category": "Oxygenhub" },
50 -
      { "command": "oxygenhub.createProposal", "title": "Propose Current Bookmark…", "category": "Oxygenhub" },
51 -
      { "command": "oxygenhub.newIssue", "title": "New Issue…", "category": "Oxygenhub", "icon": "$(add)" },
52 -
      { "command": "oxygenhub.openIssue", "title": "Open Issue", "category": "Oxygenhub" },
53 -
      { "command": "oxygenhub.commentIssue", "title": "Comment on Issue…", "category": "Oxygenhub" },
54 -
      { "command": "oxygenhub.closeIssue", "title": "Close Issue", "category": "Oxygenhub" },
55 -
      { "command": "oxygenhub.reopenIssue", "title": "Reopen Issue", "category": "Oxygenhub" },
56 -
      { "command": "oxygenhub.assignMe", "title": "Assign to Me", "category": "Oxygenhub" },
57 -
      { "command": "oxygenhub.newThread", "title": "Start Review Thread", "category": "Oxygenhub" },
58 -
      { "command": "oxygenhub.reply", "title": "Reply", "category": "Oxygenhub" },
59 -
      { "command": "oxygenhub.resolveThread", "title": "Resolve", "category": "Oxygenhub" }
90 +
      {
91 +
        "command": "oxygenhub.signIn",
92 +
        "title": "Sign in",
93 +
        "category": "Oxygenhub"
94 +
      },
95 +
      {
96 +
        "command": "oxygenhub.signOut",
97 +
        "title": "Sign out",
98 +
        "category": "Oxygenhub"
99 +
      },
100 +
      {
101 +
        "command": "oxygenhub.refresh",
102 +
        "title": "Refresh",
103 +
        "category": "Oxygenhub",
104 +
        "icon": "$(refresh)"
105 +
      },
106 +
      {
107 +
        "command": "oxygenhub.openProposal",
108 +
        "title": "Open Proposal",
109 +
        "category": "Oxygenhub"
110 +
      },
111 +
      {
112 +
        "command": "oxygenhub.openOnHub",
113 +
        "title": "Open on Hub",
114 +
        "category": "Oxygenhub",
115 +
        "icon": "$(link-external)"
116 +
      },
117 +
      {
118 +
        "command": "oxygenhub.checkoutProposal",
119 +
        "title": "Check Out Proposal",
120 +
        "category": "Oxygenhub",
121 +
        "icon": "$(git-branch)"
122 +
      },
123 +
      {
124 +
        "command": "oxygenhub.review",
125 +
        "title": "Review\u2026",
126 +
        "category": "Oxygenhub",
127 +
        "icon": "$(comment-discussion)"
128 +
      },
129 +
      {
130 +
        "command": "oxygenhub.sealApproval",
131 +
        "title": "Seal My Approval (oxy seal --proposal)",
132 +
        "category": "Oxygenhub"
133 +
      },
134 +
      {
135 +
        "command": "oxygenhub.land",
136 +
        "title": "Land Proposal",
137 +
        "category": "Oxygenhub"
138 +
      },
139 +
      {
140 +
        "command": "oxygenhub.closeProposal",
141 +
        "title": "Close Proposal",
142 +
        "category": "Oxygenhub"
143 +
      },
144 +
      {
145 +
        "command": "oxygenhub.createProposal",
146 +
        "title": "Propose Current Bookmark\u2026",
147 +
        "category": "Oxygenhub"
148 +
      },
149 +
      {
150 +
        "command": "oxygenhub.newIssue",
151 +
        "title": "New Issue\u2026",
152 +
        "category": "Oxygenhub",
153 +
        "icon": "$(add)"
154 +
      },
155 +
      {
156 +
        "command": "oxygenhub.openIssue",
157 +
        "title": "Open Issue",
158 +
        "category": "Oxygenhub"
159 +
      },
160 +
      {
161 +
        "command": "oxygenhub.commentIssue",
162 +
        "title": "Comment on Issue\u2026",
163 +
        "category": "Oxygenhub"
164 +
      },
165 +
      {
166 +
        "command": "oxygenhub.closeIssue",
167 +
        "title": "Close Issue",
168 +
        "category": "Oxygenhub"
169 +
      },
170 +
      {
171 +
        "command": "oxygenhub.reopenIssue",
172 +
        "title": "Reopen Issue",
173 +
        "category": "Oxygenhub"
174 +
      },
175 +
      {
176 +
        "command": "oxygenhub.assignMe",
177 +
        "title": "Assign to Me",
178 +
        "category": "Oxygenhub"
179 +
      },
180 +
      {
181 +
        "command": "oxygenhub.newThread",
182 +
        "title": "Start Review Thread",
183 +
        "category": "Oxygenhub"
184 +
      },
185 +
      {
186 +
        "command": "oxygenhub.reply",
187 +
        "title": "Reply",
188 +
        "category": "Oxygenhub"
189 +
      },
190 +
      {
191 +
        "command": "oxygenhub.resolveThread",
192 +
        "title": "Resolve",
193 +
        "category": "Oxygenhub"
194 +
      }
60 195
    ],
61 196
    "menus": {
62 197
      "view/title": [
63 -
        { "command": "oxygenhub.refresh", "when": "view == oxygenhub.proposals || view == oxygenhub.issues", "group": "navigation" },
64 -
        { "command": "oxygenhub.createProposal", "when": "view == oxygenhub.proposals", "group": "navigation" },
65 -
        { "command": "oxygenhub.newIssue", "when": "view == oxygenhub.issues", "group": "navigation" }
198 +
        {
199 +
          "command": "oxygenhub.refresh",
200 +
          "when": "view == oxygenhub.proposals || view == oxygenhub.issues",
201 +
          "group": "navigation"
202 +
        },
203 +
        {
204 +
          "command": "oxygenhub.createProposal",
205 +
          "when": "view == oxygenhub.proposals",
206 +
          "group": "navigation"
207 +
        },
208 +
        {
209 +
          "command": "oxygenhub.newIssue",
210 +
          "when": "view == oxygenhub.issues",
211 +
          "group": "navigation"
212 +
        }
66 213
      ],
67 214
      "view/item/context": [
68 -
        { "command": "oxygenhub.openOnHub", "when": "view == oxygenhub.proposals && viewItem == proposal", "group": "inline" },
69 -
        { "command": "oxygenhub.checkoutProposal", "when": "view == oxygenhub.proposals && viewItem == proposal", "group": "inline" },
70 -
        { "command": "oxygenhub.review", "when": "view == oxygenhub.proposals && viewItem == proposal", "group": "inline" },
71 -
        { "command": "oxygenhub.sealApproval", "when": "view == oxygenhub.proposals && viewItem == proposal", "group": "actions@1" },
72 -
        { "command": "oxygenhub.land", "when": "view == oxygenhub.proposals && viewItem == proposal", "group": "actions@2" },
73 -
        { "command": "oxygenhub.closeProposal", "when": "view == oxygenhub.proposals && viewItem == proposal", "group": "actions@3" },
74 -
        { "command": "oxygenhub.openOnHub", "when": "view == oxygenhub.issues && viewItem == issue", "group": "inline" },
75 -
        { "command": "oxygenhub.commentIssue", "when": "view == oxygenhub.issues && viewItem == issue", "group": "actions@1" },
76 -
        { "command": "oxygenhub.assignMe", "when": "view == oxygenhub.issues && viewItem == issue", "group": "actions@2" },
77 -
        { "command": "oxygenhub.closeIssue", "when": "view == oxygenhub.issues && viewItem == issue", "group": "actions@3" },
78 -
        { "command": "oxygenhub.reopenIssue", "when": "view == oxygenhub.issues && viewItem == issue", "group": "actions@3" }
215 +
        {
216 +
          "command": "oxygenhub.openOnHub",
217 +
          "when": "view == oxygenhub.proposals && viewItem == proposal",
218 +
          "group": "inline"
219 +
        },
220 +
        {
221 +
          "command": "oxygenhub.checkoutProposal",
222 +
          "when": "view == oxygenhub.proposals && viewItem == proposal",
223 +
          "group": "inline"
224 +
        },
225 +
        {
226 +
          "command": "oxygenhub.review",
227 +
          "when": "view == oxygenhub.proposals && viewItem == proposal",
228 +
          "group": "inline"
229 +
        },
230 +
        {
231 +
          "command": "oxygenhub.sealApproval",
232 +
          "when": "view == oxygenhub.proposals && viewItem == proposal",
233 +
          "group": "actions@1"
234 +
        },
235 +
        {
236 +
          "command": "oxygenhub.land",
237 +
          "when": "view == oxygenhub.proposals && viewItem == proposal",
238 +
          "group": "actions@2"
239 +
        },
240 +
        {
241 +
          "command": "oxygenhub.closeProposal",
242 +
          "when": "view == oxygenhub.proposals && viewItem == proposal",
243 +
          "group": "actions@3"
244 +
        },
245 +
        {
246 +
          "command": "oxygenhub.openOnHub",
247 +
          "when": "view == oxygenhub.issues && viewItem == issue",
248 +
          "group": "inline"
249 +
        },
250 +
        {
251 +
          "command": "oxygenhub.commentIssue",
252 +
          "when": "view == oxygenhub.issues && viewItem == issue",
253 +
          "group": "actions@1"
254 +
        },
255 +
        {
256 +
          "command": "oxygenhub.assignMe",
257 +
          "when": "view == oxygenhub.issues && viewItem == issue",
258 +
          "group": "actions@2"
259 +
        },
260 +
        {
261 +
          "command": "oxygenhub.closeIssue",
262 +
          "when": "view == oxygenhub.issues && viewItem == issue",
263 +
          "group": "actions@3"
264 +
        },
265 +
        {
266 +
          "command": "oxygenhub.reopenIssue",
267 +
          "when": "view == oxygenhub.issues && viewItem == issue",
268 +
          "group": "actions@3"
269 +
        }
79 270
      ],
80 271
      "comments/commentThread/context": [
81 -
        { "command": "oxygenhub.reply", "when": "commentController == oxygenhub", "group": "inline" },
82 -
        { "command": "oxygenhub.newThread", "when": "commentController == oxygenhub && commentThreadIsEmpty", "group": "inline" }
272 +
        {
273 +
          "command": "oxygenhub.reply",
274 +
          "when": "commentController == oxygenhub",
275 +
          "group": "inline"
276 +
        },
277 +
        {
278 +
          "command": "oxygenhub.newThread",
279 +
          "when": "commentController == oxygenhub && commentThreadIsEmpty",
280 +
          "group": "inline"
281 +
        }
83 282
      ],
84 283
      "comments/commentThread/title": [
85 -
        { "command": "oxygenhub.resolveThread", "when": "commentController == oxygenhub", "group": "navigation" }
284 +
        {
285 +
          "command": "oxygenhub.resolveThread",
286 +
          "when": "commentController == oxygenhub",
287 +
          "group": "navigation"
288 +
        }
86 289
      ]
87 290
    }
88 291
  },
…
18 unchanged lines
modified src/hub.ts +3 −2
…
90 unchanged lines
91 91
    return this.request("GET", `/repos/${owner}/${name}/proposals/${number}/comments`);
92 92
  }
93 93
94 -
  commentProposal(owner: string, name: string, number: number, body: string): Promise<api.Comment> {
95 -
    return this.request("POST", `/repos/${owner}/${name}/proposals/${number}/comments`, { body });
94 +
  /** A comment; with `path` and `line` it is anchored to that line's atom in the projected state. */
95 +
  commentProposal(owner: string, name: string, number: number, body: string, path?: string, line?: number): Promise<api.Comment> {
96 +
    return this.request("POST", `/repos/${owner}/${name}/proposals/${number}/comments`, { body, path: path ?? null, line: line ?? null });
96 97
  }
97 98
98 99
  reviews(owner: string, name: string, number: number): Promise<api.Review[]> {
…
86 unchanged lines
modified src/hubapi.d.ts +33 −0
…
316 unchanged lines
317 317
318 318
export type NewComment = {
319 319
  body: string;
320 +
  line?: number | null;
321 +
  path?: string | null;
320 322
};
321 323
322 324
export type NewProposal = {
…
29 unchanged lines
352 354
  number: number;
353 355
};
354 356
357 +
export type ReleaseAsset = {
358 +
  content_type: string;
359 +
  downloads: number;
360 +
  hash: string;
361 +
  name: string;
362 +
  size: number;
363 +
  url: string;
364 +
};
365 +
366 +
export type Release = {
367 +
  archives: string[];
368 +
  assets: ReleaseAsset[];
369 +
  author: string;
370 +
  created_ms: number;
371 +
  heads: string[];
372 +
  latest: boolean;
373 +
  notes: string;
374 +
  prerelease: boolean;
375 +
  signer?: string | null;
376 +
  tag: string;
377 +
  title: string;
378 +
  url: string;
379 +
};
380 +
381 +
export type NewRelease = {
382 +
  notes?: string | null;
383 +
  prerelease?: boolean;
384 +
  tag: string;
385 +
  title: string;
386 +
};
387 +
modified src/review.ts +3 −3
…
72 unchanged lines
73 73
    }
74 74
    const rel = reply.thread.uri.fsPath.slice(a.repo.handle.root.length + 1);
75 75
    const line = reply.thread.range?.start.line ?? 0;
76 -
    // The hub anchors by line number of the projected state; send the path and line.
76 +
    // The hub resolves the line to its atom, so the thread follows the line through rebases.
77 77
    await postLineComment(this.auth, a.repo, a.number, rel, line + 1, reply.text);
78 78
    await this.load(a.repo, a.number);
79 79
  }
…
14 unchanged lines
94 94
  return { body: new vscode.MarkdownString(c.body), mode: vscode.CommentMode.Preview, author: { name: c.author }, label: c.resolved ? "resolved" : undefined, timestamp: new Date(c.created_ms) };
95 95
}
96 96
97 -
/** The hub's form endpoint accepts a path and line; the API accepts general comments only, so line comments go through the form with the API token as a bearer is not enough: use the API's general comment with a path marker until the API grows an anchored variant. */
97 +
/** A comment anchored to the atom at `path:line` of the projected state. */
98 98
async function postLineComment(auth: HubAuth, repo: HubRepo, number: number, path: string, line: number, body: string): Promise<void> {
99 -
  await auth.clientFor(repo.base).commentProposal(repo.owner, repo.name, number, `${body}\n\n_on ${path}:${line}_`);
99 +
  await auth.clientFor(repo.base).commentProposal(repo.owner, repo.name, number, body, path, line);
100 100
}