Rules-based browser launcher for TUI + GNOME. switchyard.aly.codes
tui gnome bowser go
0

Configure Feed

Select the types of activity you want to include in your feed.

add webextension

Aly Raffauf (May 23, 2026, 5:55 PM EDT) b6d2003e 8c54fd10

+74 -5
+13 -1
.github/workflows/ci.yml
··· 26 26 echo '```' >> $GITHUB_STEP_SUMMARY 27 27 go tool cover -func=coverage.out >> $GITHUB_STEP_SUMMARY 28 28 echo '```' >> $GITHUB_STEP_SUMMARY 29 + - name: Bundle browser extension 30 + run: just bundle-extension 31 + - name: Upload extension artifact 32 + uses: actions/upload-artifact@v4 33 + with: 34 + name: switchyard-webextension 35 + path: switchyard-webextension.zip 29 36 - name: Upload coverage report 30 37 uses: actions/upload-artifact@v4 31 38 with: ··· 57 64 release: 58 65 name: "Create Release" 59 66 if: startsWith(github.ref, 'refs/tags/') 60 - needs: flatpak 67 + needs: [flatpak, test] 61 68 runs-on: ubuntu-latest 62 69 permissions: 63 70 contents: write ··· 67 74 with: 68 75 pattern: io.github.alyraffauf.Switchyard.Devel-${{ github.sha }}-*.flatpak 69 76 merge-multiple: true 77 + - name: Download extension artifact 78 + uses: actions/download-artifact@v4 79 + with: 80 + name: switchyard-webextension 70 81 71 82 - name: Create Release 72 83 uses: softprops/action-gh-release@v2 73 84 with: 74 85 files: | 75 86 *.flatpak 87 + switchyard-webextension.zip 76 88 draft: false 77 89 prerelease: false 78 90 generate_release_notes: true
+1
.gitignore
··· 12 12 coverage.out 13 13 repo/ 14 14 switchyard 15 + switchyard-webextension.zip
+7
docs/WebExtension.md
··· 1 + # Switchyard Browser Extension 2 + 3 + A companion browser extension is available that allows you to open any page in Switchyard with one click. For now, the extension uses our URI scheme under the hood. It redirects the current tab to a `switchyard://open` URL, handing off to Switchyard for browser selection. 4 + 5 + The extension lives in the `webextension/` directory and ships as a standard WebExtension compatible with both Firefox and Chromium browsers. It is included in GitHub releases as `switchyard-webextension.zip`. 6 + 7 + The intent is to add deeper integration with the desktop app. Eventually, it will be submitted to the Chrome Web Store and Mozilla.
+22 -4
justfile
··· 66 66 flatpak: 67 67 flatpak run org.flatpak.Builder --user --install --force-clean --repo=build-repo build-dir flatpak/{{APPID}}.Devel.yml 68 68 69 + # Bundle the browser extension into a zip archive 70 + bundle-extension: 71 + #!/usr/bin/env bash 72 + set -euo pipefail 73 + root="{{justfile_directory()}}" 74 + extdir="${root}/webextension" 75 + outfile="${root}/switchyard-webextension.zip" 76 + rm -f "${outfile}" 77 + cd "${extdir}" && zip -r "${outfile}" . -x '.git*' 78 + echo "Extension bundled: switchyard-webextension.zip" 79 + 69 80 # Cut a new release: bump version, commit, tag, and push master + tag 70 81 release version: 71 82 #!/usr/bin/env bash ··· 73 84 version="{{version}}" 74 85 tag="v${version}" 75 86 metainfo="data/{{APPID}}.metainfo.xml" 87 + manifest="webextension/manifest.json" 76 88 77 89 if ! [[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?(\+[0-9A-Za-z.-]+)?$ ]]; then 78 90 echo "error: '$version' is not valid semver (expected X.Y.Z)" >&2 ··· 85 97 exit 1 86 98 fi 87 99 88 - # Allow src/app.go and the metainfo file to be dirty; nothing else. 89 - dirty="$(git status --porcelain -- ':!src/app.go' ":!${metainfo}")" 100 + # Allow src/app.go, metainfo, and extension manifest to be dirty; nothing else. 101 + dirty="$(git status --porcelain -- ':!src/app.go' ":!${metainfo}" ":!${manifest}")" 90 102 if [ -n "$dirty" ]; then 91 - echo "error: working tree has changes outside src/app.go and ${metainfo}:" >&2 103 + echo "error: working tree has changes outside src/app.go, ${metainfo}, ${manifest}:" >&2 92 104 echo "$dirty" >&2 93 105 exit 1 94 106 fi ··· 110 122 exit 1 111 123 fi 112 124 113 - git add src/app.go "${metainfo}" 125 + sed -i -E 's/^(\s*"version"\s*:\s*)"[^"]+"/\1"'"${version}"'"/' "${manifest}" 126 + if ! grep -qE '"version"\s*:\s*"'"${version}"'"' "${manifest}"; then 127 + echo "error: failed to update version in ${manifest}" >&2 128 + exit 1 129 + fi 130 + 131 + git add src/app.go "${metainfo}" "${manifest}" 114 132 git commit -m "update for ${tag}" 115 133 git tag -a "${tag}" -m "${tag}" 116 134 git push origin master
+5
webextension/background.js
··· 1 + chrome.action.onClicked.addListener((tab) => { 2 + const encoded = encodeURIComponent(tab.url); 3 + const switchyardURL = `switchyard://open?url=${encoded}`; 4 + chrome.tabs.update(tab.id, { url: switchyardURL }); 5 + });
webextension/icons/switchyard-128.png

This is a binary file and will not be displayed.

webextension/icons/switchyard-16.png

This is a binary file and will not be displayed.

webextension/icons/switchyard-48.png

This is a binary file and will not be displayed.

+26
webextension/manifest.json
··· 1 + { 2 + "manifest_version": 3, 3 + "name": "Open in Switchyard", 4 + "version": "0.14.0", 5 + "description": "Open the current page in Switchyard for browser selection", 6 + "homepage_url": "https://github.com/alyraffauf/Switchyard", 7 + "permissions": [ 8 + "activeTab" 9 + ], 10 + "action": { 11 + "default_title": "Open in Switchyard", 12 + "default_icon": { 13 + "16": "icons/switchyard-16.png", 14 + "48": "icons/switchyard-48.png", 15 + "128": "icons/switchyard-128.png" 16 + } 17 + }, 18 + "background": { 19 + "service_worker": "background.js" 20 + }, 21 + "browser_specific_settings": { 22 + "gecko": { 23 + "id": "switchyard@alyraffauf.github.io" 24 + } 25 + } 26 + }