Skip to content

Commit 0b91abf

Browse files
Refactor manifests into base + browser overrides; update docs
- Extract shared manifest fields into manifest-base.json - Slim manifest-chrome.json and manifest-firefox.json to overrides only - Remove stale cross-browser keys (gecko from Chrome, minimum_chrome_version from Firefox) - Add deep merge in copy.js with sorted key output for easy diffing - Remove bump.js (version bumped manually for actual releases) - README: fix "Bookmarks" → "Bookmarked", Firefox 128→142, add release section - BUILD.md: update manifest architecture description Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 977c5b8 commit 0b91abf

8 files changed

Lines changed: 132 additions & 228 deletions

File tree

BUILD.md

Lines changed: 10 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -34,45 +34,24 @@ npm run build
3434

3535
## Build System Architecture
3636

37-
### Why Two Manifest Files?
37+
### Manifest: Base + Browser Overrides
3838

39-
This extension maintains **separate manifest files** due to incompatible Manifest V3 implementations:
39+
Chrome and Firefox have incompatible Manifest V3 fields, so the extension uses a base manifest
40+
with browser-specific overrides:
4041

41-
**Chrome** (`extension/manifest-chrome.json`):
42-
```json
43-
"background": {
44-
"service_worker": "assets/background.js",
45-
"type": "module"
46-
}
47-
```
48-
49-
**Firefox** (`extension/manifest-firefox.json`):
50-
```json
51-
"background": {
52-
"scripts": ["assets/background.js"],
53-
"type": "module"
54-
},
55-
"browser_specific_settings": {
56-
"gecko": {
57-
"id": "github-bookmarked-issues@extensions",
58-
"strict_min_version": "142.0",
59-
"data_collection_permissions": {"required": ["none"]}
60-
}
61-
}
62-
```
42+
- `extension/manifest-base.json` — shared fields (permissions, icons, content scripts, etc.)
43+
- `extension/manifest-chrome.json``$schema`, `key`, `minimum_chrome_version`, `background.service_worker`
44+
- `extension/manifest-firefox.json``browser_specific_settings.gecko`, `background.scripts`
6345

64-
**Key Differences**:
65-
- Chrome uses `service_worker` (string), Firefox uses `scripts` (array)
66-
- Firefox requires `browser_specific_settings.gecko.id` for extension persistence
67-
- Firefox-specific `data_collection_permissions` declaration
68-
- Chrome manifest includes `$schema` for IDE validation (Firefox rejects this field)
46+
At build time, `copy.js` deep-merges the base with the browser override to produce
47+
`build/{browser}/manifest.json`.
6948

7049
### Build Pipeline (3 Stages)
7150

7251
#### 1. `scripts/copy.js` - File Preparation
7352
- Copies `extension/``build/{browser}/`
74-
- Skips `manifest-*.json` and `vendor/` (handled separately)
75-
- Copies browser-specific manifest (`manifest-{browser}.json`), renames to `manifest.json`
53+
- Skips manifest files and `vendor/` (handled separately)
54+
- Merges `manifest-base.json` with `manifest-{browser}.json` overrides, writes `manifest.json`
7655

7756
#### 2. `scripts/build.js` - Dependency Bundling
7857
- Bundles `@github/relative-time-element` into `assets/vendor/`

README.md

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,31 @@
11
## Features
22

3-
- **Bookmark button** on GitHub issue pages
4-
- **Popup** - View bookmarks, copy as markdown, import from URLs
5-
- **Bookmarks View** - Custom view at `github.com/issues/bookmarked` (requires login)
6-
- **Options** - Configure GitHub PAT for higher API rate limits
3+
- Bookmark button on GitHub issue pages
4+
- Bookmarked view - Custom view at `github.com/issues/bookmarked`
5+
- Toolbar popup - View bookmarks, import/export as Markdown lists
6+
- Options - Configure GitHub PAT for higher API rate limits
77

88
## Install
99

1010
Manual install, until Chrome Web Store and Firefox Add-On signing.
1111

1212
Download the extension ZIP or XPI from [release assets](https://github.com/richardkmichael/github-bookmarked-issues/releases).
1313

14-
**Chrome**: `chrome://extensions`, enable `Developer mode`, drag and drop the `ZIP`.
15-
**Firefox**: `about:debugging#/runtime/this-firefox`, `Load temporary Add-on`, select the `XPI`.
14+
Chrome: `chrome://extensions`, enable `Developer mode`, `Load unpacked`, select the `build/chrome` directory
15+
Firefox: `about:debugging#/runtime/this-firefox`, `Load temporary Add-on`, select the `XPI`.
1616

1717
## How it works
1818

19-
The Bookmarks view (at `github.com/issues/bookmarked`) uses GitHub's internal GraphQL API via
19+
The Bookmarked view (at `github.com/issues/bookmarked`) uses GitHub's internal GraphQL API via
2020
the content script — no rate limits for logged-in users.
2121

2222
The popup toolbar uses REST API, which is rate-limited. Configure a GitHub PAT in the
2323
extension options for higher limits (5,000/hr vs 60/hr unauthenticated).
2424

25-
The Bookmarks view discovers GraphQL query hashes automatically by intercepting HTTP headers
25+
The Bookmarked view discovers GraphQL query hashes automatically by intercepting HTTP headers
2626
when you navigate to any `github.com` page. This discovery only happens on `github.com` tabs.
27-
If the Bookmarks view shows a rate-limit warning despite being logged in, navigate to any
28-
GitHub page to trigger discovery, then reload the Bookmarks view.
27+
If the Bookmarked view shows a rate-limit warning despite being logged in, navigate to any
28+
GitHub page to trigger discovery, then reload the Bookmarked view.
2929

3030
See [GITHUB_OPERATION.md](GITHUB_OPERATION.md) for technical details.
3131

@@ -42,6 +42,25 @@ npm run dev:watch # Auto-rebuild on changes
4242
npm test # Run Playwright tests
4343
```
4444

45+
## Release and version
46+
47+
Releases are driven by annotated git tags (e.g., `v1.0.0`, `v1.0.0-rc3`).
48+
49+
The manifest `version` field is numeric-only (`X.Y.Z`) as required by both Chrome Web Store and
50+
Firefox AMO. It is bumped manually for actual releases, not for pre-release (`-rcX`) tags.
51+
52+
Chrome supports a separate `version_name` field for human-readable version strings. The build
53+
system auto-generates this from git state:
54+
55+
| Build context | version_name |
56+
|--------------------------|-------------------------------------|
57+
| Tagged commit | `1.0.0-rc1` (from tag `v1.0.0-rc1`) |
58+
| Development (clean) | `1.0.0-development_abc1234` |
59+
| Development (dirty) | `1.0.0-development_abc1234-dirty` |
60+
61+
Firefox has no equivalent to `version_name`; the build writes a `.version_name` file for use in
62+
package filenames instead.
63+
4564
## Data Storage
4665

4766
| Key | Storage | Description |
@@ -67,13 +86,13 @@ npm test # Run Playwright tests
6786
|-----------------|--------|-----------------------------|
6887
| Chrome | 123+ | Tested |
6988
| Edge | 123+ | Chromium-based, should work |
70-
| Firefox Desktop | 128+ | Tested |
89+
| Firefox | 142+ | Tested |
7190
| Firefox Android | - | No `storage.sync` support |
7291
| Safari | - | Not investigated |
7392

7493
## Known Limitations
7594

76-
- **Bookmarks view navigation**: Must navigate from a built-in view (e.g., `/issues/created`), then click "Bookmarked". Direct URL navigation to `/issues/bookmarked` returns 404 (GitHub's React router doesn't know the route).
77-
- **GraphQL discovery requires a github.com tab**: The extension discovers GraphQL query hashes by intercepting HTTP headers from `github.com` page loads. Without discovery (e.g. if you haven't visited GitHub since installing), the Bookmarks view falls back to REST API with rate limits. Workaround: navigate to any `github.com` page, or configure a PAT in Settings.
78-
- **Popup always uses REST API**: Due to browser security restrictions (`Sec-Fetch-Site` header), the popup cannot use GitHub's internal GraphQL API. Without a PAT, it is limited to 60 requests/hour (unauthenticated). With many bookmarks, this can cause issues to fail to load. Configure a PAT in Settings for 5,000 requests/hour.
79-
- **Not cross-browser**: Local and browser-specific storage only, e.g. Google Account, Firefox Account
95+
- Bookmarked view navigation: Must navigate from a built-in view (e.g., `/issues/created`), then click "Bookmarked". Direct URL navigation to `/issues/bookmarked` returns 404 (GitHub's React router doesn't know the route).
96+
- GraphQL discovery requires a github.com tab: The extension discovers GraphQL query hashes by intercepting HTTP headers from `github.com` page loads. Without discovery (e.g. if you haven't visited GitHub since installing), the Bookmarked view falls back to REST API with rate limits. Workaround: navigate to any `github.com` page, or configure a PAT in Settings.
97+
- Popup always uses REST API: Due to browser security restrictions (`Sec-Fetch-Site` header), the popup cannot use GitHub's internal GraphQL API. Without a PAT, it is limited to 60 requests/hour (unauthenticated). With many bookmarks, this can cause issues to fail to load. Configure a PAT in Settings for 5,000 requests/hour.
98+
- Not cross-browser: Local and browser-specific storage only, e.g. Google Account, Firefox Account

extension/manifest-base.json

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
{
2+
"name": "GitHub Bookmarked Issues",
3+
"version": "1.0.0",
4+
"description": "Track your bookmarked GitHub issues across all repositories with cross-device sync",
5+
"manifest_version": 3,
6+
"permissions": [
7+
"storage",
8+
"webRequest"
9+
],
10+
"host_permissions": [
11+
"https://github.com/*",
12+
"https://api.github.com/*"
13+
],
14+
"action": {
15+
"default_popup": "assets/popup.html",
16+
"default_icon": {
17+
"16": "assets/icon-16.png",
18+
"32": "assets/icon-32.png",
19+
"48": "assets/icon-48.png",
20+
"128": "assets/icon-128.png"
21+
}
22+
},
23+
"options_ui": {
24+
"page": "assets/options.html",
25+
"open_in_tab": false
26+
},
27+
"icons": {
28+
"16": "assets/icon-16.png",
29+
"32": "assets/icon-32.png",
30+
"48": "assets/icon-48.png",
31+
"128": "assets/icon-128.png"
32+
},
33+
"content_scripts": [
34+
{
35+
"run_at": "document_end",
36+
"matches": [
37+
"https://github.com/*/*"
38+
],
39+
"js": [
40+
"assets/shared.js",
41+
"assets/content.js"
42+
]
43+
},
44+
{
45+
"run_at": "document_end",
46+
"matches": [
47+
"https://github.com/issues",
48+
"https://github.com/issues/*",
49+
"https://github.com/*/*"
50+
],
51+
"js": [
52+
"assets/shared.js",
53+
"assets/content-issues-list.js"
54+
]
55+
}
56+
]
57+
}

extension/manifest-chrome.json

Lines changed: 1 addition & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,9 @@
11
{
22
"$schema": "https://json.schemastore.org/chrome-manifest",
3-
"name": "GitHub Bookmarked Issues",
4-
"version": "1.0.0",
5-
"description": "Track your bookmarked GitHub issues across all repositories with cross-device sync",
6-
"manifest_version": 3,
73
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5hoPyLiaL270ncRXJdvWf8QjbNEV4TfsjYTO7Y11PAYJeshGzlYWTNtkcn7JUAZJQFKFjicmF9O8IUpyCaPo9nxdAmhk8EsZnoh47ueo0wyUAhFEGRNlYOPEIMmSeRVDbABIlMOReDJLAfVYMYOOX2Q14E8w0/TrypEthPKYSMunVEo60rTXCF+bFx+MWeBBimB1bSYSnCRNch2iU1Iug/yrlqhbqwWrSTDqQWllf4jhJdLDmX/eVCcoFiz+ejTfcEKElXmMWJJnLNDU6jPntLJJZ8gtbJMGhO3CUAkLPLX4DcHzgtq4VX/V9lz9CcmlskdW9SfFTSir917PGfHIVwIDAQAB",
84
"minimum_chrome_version": "123",
9-
"browser_specific_settings": {
10-
"gecko": {
11-
"id": "github-bookmarked-issues@extensions",
12-
"strict_min_version": "128.0"
13-
}
14-
},
15-
"permissions": [
16-
"storage",
17-
"webRequest"
18-
],
19-
"host_permissions": [
20-
"https://github.com/*",
21-
"https://api.github.com/*"
22-
],
23-
"action": {
24-
"default_popup": "assets/popup.html",
25-
"default_icon": {
26-
"16": "assets/icon-16.png",
27-
"32": "assets/icon-32.png",
28-
"48": "assets/icon-48.png",
29-
"128": "assets/icon-128.png"
30-
}
31-
},
32-
"options_ui": {
33-
"page": "assets/options.html",
34-
"open_in_tab": false
35-
},
36-
"icons": {
37-
"16": "assets/icon-16.png",
38-
"32": "assets/icon-32.png",
39-
"48": "assets/icon-48.png",
40-
"128": "assets/icon-128.png"
41-
},
425
"background": {
436
"service_worker": "assets/background.js",
447
"type": "module"
45-
},
46-
"content_scripts": [
47-
{
48-
"run_at": "document_end",
49-
"matches": [
50-
"https://github.com/*/*"
51-
],
52-
"js": [
53-
"assets/shared.js",
54-
"assets/content.js"
55-
]
56-
},
57-
{
58-
"run_at": "document_end",
59-
"matches": [
60-
"https://github.com/issues",
61-
"https://github.com/issues/*",
62-
"https://github.com/*/*"
63-
],
64-
"js": [
65-
"assets/shared.js",
66-
"assets/content-issues-list.js"
67-
]
68-
}
69-
]
8+
}
709
}

extension/manifest-firefox.json

Lines changed: 1 addition & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
11
{
2-
"name": "GitHub Bookmarked Issues",
3-
"version": "1.0.0",
4-
"description": "Track your bookmarked GitHub issues across all repositories with cross-device sync",
5-
"manifest_version": 3,
6-
"minimum_chrome_version": "123",
72
"browser_specific_settings": {
83
"gecko": {
94
"id": "github-bookmarked-issues@extensions",
@@ -13,60 +8,8 @@
138
}
149
}
1510
},
16-
"permissions": [
17-
"storage",
18-
"webRequest"
19-
],
20-
"host_permissions": [
21-
"https://github.com/*",
22-
"https://api.github.com/*"
23-
],
24-
"action": {
25-
"default_popup": "assets/popup.html",
26-
"default_icon": {
27-
"16": "assets/icon-16.png",
28-
"32": "assets/icon-32.png",
29-
"48": "assets/icon-48.png",
30-
"128": "assets/icon-128.png"
31-
}
32-
},
33-
"options_ui": {
34-
"page": "assets/options.html",
35-
"open_in_tab": false,
36-
"browser_style": false
37-
},
38-
"icons": {
39-
"16": "assets/icon-16.png",
40-
"32": "assets/icon-32.png",
41-
"48": "assets/icon-48.png",
42-
"128": "assets/icon-128.png"
43-
},
4411
"background": {
4512
"scripts": ["assets/background.js"],
4613
"type": "module"
47-
},
48-
"content_scripts": [
49-
{
50-
"run_at": "document_end",
51-
"matches": [
52-
"https://github.com/*/*"
53-
],
54-
"js": [
55-
"assets/shared.js",
56-
"assets/content.js"
57-
]
58-
},
59-
{
60-
"run_at": "document_end",
61-
"matches": [
62-
"https://github.com/issues",
63-
"https://github.com/issues/*",
64-
"https://github.com/*/*"
65-
],
66-
"js": [
67-
"assets/shared.js",
68-
"assets/content-issues-list.js"
69-
]
70-
}
71-
]
14+
}
7215
}

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
"test:chrome": "playwright test --project=chromium",
1818
"test:visual": "playwright test --grep @visual",
1919
"test:visual:update": "playwright test --grep @visual --update-snapshots",
20-
"version:bump": "node scripts/bump.js",
2120
"package": "npm run build"
2221
},
2322
"dependencies": {

0 commit comments

Comments
 (0)