@@ -28,6 +28,7 @@ The extension has two parts that communicate through per-tab results in
2828lives in ` browser.storage.local ` ).
2929
3030It runs on both Firefox and Chrome from a single source tree:
31+
3132- the manifest declares both ` background.scripts ` (Firefox event page) and
3233 ` background.service_worker ` (Chrome); each browser reads the key it supports;
3334- ` browser.js ` resolves the WebExtension API namespace — Firefox's standard
@@ -145,34 +146,36 @@ are *families* whose instances — public and self-hosted alike — are built wi
145146
146147Here is the interface for each forge:
147148
148- | Member | Purpose |
149- | ------------ | ------------------------------------------------------------------ |
150- | ` label ` | human-readable forge name |
151- | ` hostnames ` | array of hostnames matched against the page, exactly or as a subdomain (one per family instance) |
152- | ` base_url ` | API root URL the endpoint builders are hung off of |
153- | ` parseUrl ` | ` (URL) → { projectKey, repoSlug, filepath, origin } ` or ` null ` |
154- | ` listPRsUrl ` | API endpoint listing the repo's open PRs |
155- | ` pullRequests ` | ` (listResponse) → array of PR objects ` (unwraps paginated envelopes) |
156- | ` filesUrl ` | API endpoint listing a PR's modified files |
157- | ` filenames ` | filenames touched by a PR, from the files-endpoint response |
158- | ` prNumber ` | identifier of a PR (used in URLs and displayed) |
159- | ` prWebUrl ` | web (non-API) URL of a PR, for the popup links |
160- | ` nextPageUrl ` | ` (response, data) → URL ` of the next page of a paginated API response, or ` null ` on the last page |
161- | ` rateLimit ` | optional ` { header } ` : response header carrying the remaining request quota; ` null ` if unsupported |
162- | ` tokenStorageKey ` | optional ` storage.local ` key holding the user's token; omit for no auth |
163- | ` authHeader ` | optional ` (token) → headers ` sent with API requests; omit for no auth |
149+ | Member | Purpose |
150+ | ----------------- | -------------------------------- ------------------------------------------------------------------ |
151+ | ` label ` | human-readable forge name |
152+ | ` hostnames ` | array of hostnames matched against the page, exactly or as a subdomain (one per family instance) |
153+ | ` base_url ` | API root URL the endpoint builders are hung off of |
154+ | ` parseUrl ` | ` (URL) → { projectKey, repoSlug, filepath, origin } ` or ` null ` |
155+ | ` listPRsUrl ` | API endpoint listing the repo's open PRs |
156+ | ` pullRequests ` | ` (listResponse) → array of PR objects ` (unwraps paginated envelopes) |
157+ | ` filesUrl ` | API endpoint listing a PR's modified files |
158+ | ` filenames ` | filenames touched by a PR, from the files-endpoint response |
159+ | ` prNumber ` | identifier of a PR (used in URLs and displayed) |
160+ | ` prWebUrl ` | web (non-API) URL of a PR, for the popup links |
161+ | ` nextPageUrl ` | ` (response, data) → URL ` of the next page of a paginated API response, or ` null ` on the last page |
162+ | ` rateLimit ` | optional ` { header } ` : response header carrying the remaining request quota; ` null ` if unsupported |
163+ | ` tokenStorageKey ` | optional ` storage.local ` key holding the user's token; omit for no auth |
164+ | ` authHeader ` | optional ` (token) → headers ` sent with API requests; omit for no auth |
164165
165166A forge that omits ` tokenStorageKey ` /` authHeader ` simply stays unauthenticated;
166167declaring both opts it into the [ Authentication] ( #authentication ) flow and the
167168options-page token field.
168169
169170So, to add a new forge:
171+
170172- in ` forges.js ` , create a new object implementing this interface
171173- in ` forges.js ` , add the forge to ` staticForges `
172174- in ` manifest.json ` , add a ` host_permissions ` entry
173175- in ` tests/forges.test.js ` , add tests.
174176
175177Supported forges:
178+
176179- ** GitHub** : https://docs.github.com/en/rest/pulls
177180- ** Bitbucket** (Cloud): https://developer.atlassian.com/cloud/bitbucket/rest/api-group-pullrequests/
178181- ** Codeberg** (Forgejo, Gitea-compatible API): https://forgejo.org/docs/latest/user/api-usage/
@@ -198,6 +201,7 @@ it on removal (both need `optional_host_permissions`); the background script
198201skips an instance until its permission is granted.
199202
200203Supported self-hosted software:
204+
201205- ** GitLab** (CE/EE): https://docs.gitlab.com/ee/api/merge_requests.html
202206- ** Forgejo / Gitea** : https://forgejo.org/docs/latest/user/api-usage/
203207- ** Bitbucket Server / Data Center** : https://developer.atlassian.com/server/bitbucket/rest/latest/
@@ -213,15 +217,18 @@ Translations live in `_locales/<lang>/messages.json`. The default locale is
213217language if it exists.
214218
215219Strings are resolved two ways:
220+
216221- ` __MSG_<key>__ ` placeholders in page markup, swapped in at load time by the
217222 shared ` localize() ` in ` i18n.js ` (used by both the popup and options pages)
218223- ` browser.i18n.getMessage("<key>") ` (in ` popup.js ` and ` options.js ` ).
219224
220225To add a locale:
226+
221227- copy ` _locales/template.json ` to ` _locales/<lang>/messages.json `
222228- fill every ` message ` field.
223229
224230If you add a translatable string:
231+
225232- add the string to ` _locales/template.json `
226233- update ` _locales/en/messages.json ` with a description and a translation
227234
@@ -256,6 +263,7 @@ See https://extensionworkshop.com/documentation/develop/temporary-installation-i
256263### Chrome
257264
258265Load the repository folder as an unpacked extension:
266+
2592671 . ` chrome://extensions `
2602682 . enable * Developer mode*
2612693 . * Load unpacked*
@@ -265,9 +273,9 @@ See https://developer.chrome.com/docs/extensions/get-started/tutorial/hello-worl
265273
266274## Troubleshooting
267275
268- | Symptom | Likely cause / fix |
269- | --------------------------- | ------------------------------------------------------------ |
270- | Badge shows ` err ` | A request failed — often the rate limit. Check the console. |
271- | Badge/popup never updates | The page URL doesn't match the expected file path. |
272- | Rate limit reached quickly | Low anonymous API quota — set a token (see [ Authentication] ( #authentication ) ). |
273- | Private repo shows no PRs | Set a token whose access covers that repository. |
276+ | Symptom | Likely cause / fix |
277+ | -------------------------- | ------------------ ------------------------------------------------------------ |
278+ | Badge shows ` err ` | A request failed — often the rate limit. Check the console. |
279+ | Badge/popup never updates | The page URL doesn't match the expected file path. |
280+ | Rate limit reached quickly | Low anonymous API quota — set a token (see [ Authentication] ( #authentication ) ). |
281+ | Private repo shows no PRs | Set a token whose access covers that repository. |
0 commit comments