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

Configure Feed

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

website: fix icons and document browser extensions

Aly Raffauf (Jun 22, 2026, 1:42 PM EDT) 681bdd77 dd9373bf

+734 -121
+1 -1
flake/hm-module.nix
··· 21 21 }; 22 22 23 23 settings = lib.mkOption { 24 - type = toml.type; 24 + inherit (toml) type; 25 25 default = {}; 26 26 description = '' 27 27 Contents of {file}`$XDG_CONFIG_HOME/switchyard/config.toml`.
+1 -1
flake/packages.nix
··· 14 14 version = "dev"; 15 15 src = ../browser-setup; 16 16 pyproject = true; 17 - build-system = with pkgs.python3.pkgs; [ setuptools ]; 17 + build-system = with pkgs.python3.pkgs; [setuptools]; 18 18 }; 19 19 20 20 switchyard = pkgs.buildGoModule {
+10 -2
webextension/src/background.ts
··· 26 26 chrome.contextMenus.onClicked.addListener((info, tab) => { 27 27 const tabId = tab?.id; 28 28 if (tabId == null) return; 29 - if (info.menuItemId === "open-link" && info.linkUrl && ROUTABLE.test(info.linkUrl)) { 29 + if ( 30 + info.menuItemId === "open-link" && 31 + info.linkUrl && 32 + ROUTABLE.test(info.linkUrl) 33 + ) { 30 34 openInSwitchyard(info.linkUrl, tabId); 31 - } else if (info.menuItemId === "open-page" && tab?.url && ROUTABLE.test(tab.url)) { 35 + } else if ( 36 + info.menuItemId === "open-page" && 37 + tab?.url && 38 + ROUTABLE.test(tab.url) 39 + ) { 32 40 openInSwitchyard(tab.url, tabId); 33 41 } 34 42 });
+5 -1
website/astro.config.mjs
··· 1 1 import { defineConfig } from "astro/config"; 2 2 import tailwindcss from "@tailwindcss/vite"; 3 3 import sitemap from "@astrojs/sitemap"; 4 + import icon from "astro-icon"; 4 5 5 6 export default defineConfig({ 6 7 site: "https://switchyard.aly.codes", 7 - integrations: [sitemap()], 8 + integrations: [ 9 + sitemap(), 10 + icon(), 11 + ], 8 12 vite: { 9 13 plugins: [tailwindcss()], 10 14 },
+596 -4
website/package-lock.json
··· 9 9 "version": "0.0.0", 10 10 "dependencies": { 11 11 "@astrojs/sitemap": "^3.7.3", 12 - "astro": "^7.0.0" 12 + "@iconify-json/lucide": "^1.2.114", 13 + "@iconify-json/simple-icons": "^1.2.87", 14 + "astro": "^7.0.0", 15 + "astro-icon": "^1.1.5" 13 16 }, 14 17 "devDependencies": { 15 18 "@eslint/js": "^9.39.4", ··· 24 27 "tailwindcss": "^4.3.1", 25 28 "typescript": "^6.0.3", 26 29 "typescript-eslint": "^8.61.1" 30 + } 31 + }, 32 + "node_modules/@antfu/install-pkg": { 33 + "version": "1.1.0", 34 + "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-1.1.0.tgz", 35 + "integrity": "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==", 36 + "license": "MIT", 37 + "dependencies": { 38 + "package-manager-detector": "^1.3.0", 39 + "tinyexec": "^1.0.1" 40 + }, 41 + "funding": { 42 + "url": "https://github.com/sponsors/antfu" 43 + } 44 + }, 45 + "node_modules/@antfu/utils": { 46 + "version": "8.1.1", 47 + "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-8.1.1.tgz", 48 + "integrity": "sha512-Mex9nXf9vR6AhcXmMrlz/HVgYYZpVGJ6YlPgwl7UnaFpnshXs6EK/oa5Gpf3CzENMjkvEx2tQtntGnb7UtSTOQ==", 49 + "license": "MIT", 50 + "funding": { 51 + "url": "https://github.com/sponsors/antfu" 27 52 } 28 53 }, 29 54 "node_modules/@astrojs/compiler": { ··· 710 735 "url": "https://github.com/sponsors/nzakas" 711 736 } 712 737 }, 738 + "node_modules/@iconify-json/lucide": { 739 + "version": "1.2.114", 740 + "resolved": "https://registry.npmjs.org/@iconify-json/lucide/-/lucide-1.2.114.tgz", 741 + "integrity": "sha512-NbvH3B1BYo6wBtS7joLi7f2UVQOqK2dtZodMFf3kkBs+Tnh9TkRuy8oVHr1RM8UK6bUtvAXxfNlGAah0CuvPCw==", 742 + "license": "ISC", 743 + "dependencies": { 744 + "@iconify/types": "*" 745 + } 746 + }, 747 + "node_modules/@iconify-json/simple-icons": { 748 + "version": "1.2.87", 749 + "resolved": "https://registry.npmjs.org/@iconify-json/simple-icons/-/simple-icons-1.2.87.tgz", 750 + "integrity": "sha512-8YciStObhSji3OZFmWAWK6kBujyqO5bLCxeDwLxf3CR3F4PVelq7keC2LBvgTqviWzSTysj5/g4PCFLiAMVGsw==", 751 + "license": "CC0-1.0", 752 + "dependencies": { 753 + "@iconify/types": "*" 754 + } 755 + }, 756 + "node_modules/@iconify/tools": { 757 + "version": "4.2.0", 758 + "resolved": "https://registry.npmjs.org/@iconify/tools/-/tools-4.2.0.tgz", 759 + "integrity": "sha512-WRxPva/ipxYkqZd1+CkEAQmd86dQmrwH0vwK89gmp2Kh2WyyVw57XbPng0NehP3x4V1LzLsXUneP1uMfTMZmUA==", 760 + "license": "MIT", 761 + "dependencies": { 762 + "@iconify/types": "^2.0.0", 763 + "@iconify/utils": "^2.3.0", 764 + "cheerio": "^1.1.2", 765 + "domhandler": "^5.0.3", 766 + "extract-zip": "^2.0.1", 767 + "local-pkg": "^1.1.2", 768 + "pathe": "^2.0.3", 769 + "svgo": "^3.3.2", 770 + "tar": "^7.5.2" 771 + } 772 + }, 773 + "node_modules/@iconify/tools/node_modules/commander": { 774 + "version": "7.2.0", 775 + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", 776 + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", 777 + "license": "MIT", 778 + "engines": { 779 + "node": ">= 10" 780 + } 781 + }, 782 + "node_modules/@iconify/tools/node_modules/css-tree": { 783 + "version": "2.3.1", 784 + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", 785 + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", 786 + "license": "MIT", 787 + "dependencies": { 788 + "mdn-data": "2.0.30", 789 + "source-map-js": "^1.0.1" 790 + }, 791 + "engines": { 792 + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" 793 + } 794 + }, 795 + "node_modules/@iconify/tools/node_modules/mdn-data": { 796 + "version": "2.0.30", 797 + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", 798 + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", 799 + "license": "CC0-1.0" 800 + }, 801 + "node_modules/@iconify/tools/node_modules/svgo": { 802 + "version": "3.3.3", 803 + "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.3.tgz", 804 + "integrity": "sha512-+wn7I4p7YgJhHs38k2TNjy1vCfPIfLIJWR5MnCStsN8WuuTcBnRKcMHQLMM2ijxGZmDoZwNv8ipl5aTTen62ng==", 805 + "license": "MIT", 806 + "dependencies": { 807 + "commander": "^7.2.0", 808 + "css-select": "^5.1.0", 809 + "css-tree": "^2.3.1", 810 + "css-what": "^6.1.0", 811 + "csso": "^5.0.5", 812 + "picocolors": "^1.0.0", 813 + "sax": "^1.5.0" 814 + }, 815 + "bin": { 816 + "svgo": "bin/svgo" 817 + }, 818 + "engines": { 819 + "node": ">=14.0.0" 820 + }, 821 + "funding": { 822 + "type": "opencollective", 823 + "url": "https://opencollective.com/svgo" 824 + } 825 + }, 826 + "node_modules/@iconify/types": { 827 + "version": "2.0.0", 828 + "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", 829 + "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==", 830 + "license": "MIT" 831 + }, 832 + "node_modules/@iconify/utils": { 833 + "version": "2.3.0", 834 + "resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-2.3.0.tgz", 835 + "integrity": "sha512-GmQ78prtwYW6EtzXRU1rY+KwOKfz32PD7iJh6Iyqw68GiKuoZ2A6pRtzWONz5VQJbp50mEjXh/7NkumtrAgRKA==", 836 + "license": "MIT", 837 + "dependencies": { 838 + "@antfu/install-pkg": "^1.0.0", 839 + "@antfu/utils": "^8.1.0", 840 + "@iconify/types": "^2.0.0", 841 + "debug": "^4.4.0", 842 + "globals": "^15.14.0", 843 + "kolorist": "^1.8.0", 844 + "local-pkg": "^1.0.0", 845 + "mlly": "^1.7.4" 846 + } 847 + }, 848 + "node_modules/@iconify/utils/node_modules/globals": { 849 + "version": "15.15.0", 850 + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", 851 + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", 852 + "license": "MIT", 853 + "engines": { 854 + "node": ">=18" 855 + }, 856 + "funding": { 857 + "url": "https://github.com/sponsors/sindresorhus" 858 + } 859 + }, 713 860 "node_modules/@img/colour": { 714 861 "version": "1.1.0", 715 862 "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", ··· 1224 1371 "url": "https://opencollective.com/libvips" 1225 1372 } 1226 1373 }, 1374 + "node_modules/@isaacs/fs-minipass": { 1375 + "version": "4.0.1", 1376 + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", 1377 + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", 1378 + "license": "ISC", 1379 + "dependencies": { 1380 + "minipass": "^7.0.4" 1381 + }, 1382 + "engines": { 1383 + "node": ">=18.0.0" 1384 + } 1385 + }, 1227 1386 "node_modules/@jridgewell/gen-mapping": { 1228 1387 "version": "0.3.13", 1229 1388 "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", ··· 2337 2496 "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", 2338 2497 "license": "MIT" 2339 2498 }, 2499 + "node_modules/@types/yauzl": { 2500 + "version": "2.10.3", 2501 + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", 2502 + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", 2503 + "license": "MIT", 2504 + "optional": true, 2505 + "dependencies": { 2506 + "@types/node": "*" 2507 + } 2508 + }, 2340 2509 "node_modules/@typescript-eslint/eslint-plugin": { 2341 2510 "version": "8.61.1", 2342 2511 "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.61.1.tgz", ··· 2629 2798 "version": "8.17.0", 2630 2799 "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz", 2631 2800 "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==", 2632 - "dev": true, 2633 2801 "license": "MIT", 2634 2802 "bin": { 2635 2803 "acorn": "bin/acorn" ··· 2824 2992 "@astrojs/markdown-remark": { 2825 2993 "optional": true 2826 2994 } 2995 + } 2996 + }, 2997 + "node_modules/astro-icon": { 2998 + "version": "1.1.5", 2999 + "resolved": "https://registry.npmjs.org/astro-icon/-/astro-icon-1.1.5.tgz", 3000 + "integrity": "sha512-CJYS5nWOw9jz4RpGWmzNQY7D0y2ZZacH7atL2K9DeJXJVaz7/5WrxeyIxO8KASk1jCM96Q4LjRx/F3R+InjJrw==", 3001 + "license": "MIT", 3002 + "dependencies": { 3003 + "@iconify/tools": "^4.0.5", 3004 + "@iconify/types": "^2.0.0", 3005 + "@iconify/utils": "^2.1.30" 2827 3006 } 2828 3007 }, 2829 3008 "node_modules/astro/node_modules/@esbuild/aix-ppc64": { ··· 3363 3542 "concat-map": "0.0.1" 3364 3543 } 3365 3544 }, 3545 + "node_modules/buffer-crc32": { 3546 + "version": "0.2.13", 3547 + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", 3548 + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", 3549 + "license": "MIT", 3550 + "engines": { 3551 + "node": "*" 3552 + } 3553 + }, 3366 3554 "node_modules/callsites": { 3367 3555 "version": "3.1.0", 3368 3556 "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", ··· 3430 3618 "url": "https://github.com/sponsors/wooorm" 3431 3619 } 3432 3620 }, 3621 + "node_modules/cheerio": { 3622 + "version": "1.2.0", 3623 + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.2.0.tgz", 3624 + "integrity": "sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==", 3625 + "license": "MIT", 3626 + "dependencies": { 3627 + "cheerio-select": "^2.1.0", 3628 + "dom-serializer": "^2.0.0", 3629 + "domhandler": "^5.0.3", 3630 + "domutils": "^3.2.2", 3631 + "encoding-sniffer": "^0.2.1", 3632 + "htmlparser2": "^10.1.0", 3633 + "parse5": "^7.3.0", 3634 + "parse5-htmlparser2-tree-adapter": "^7.1.0", 3635 + "parse5-parser-stream": "^7.1.2", 3636 + "undici": "^7.19.0", 3637 + "whatwg-mimetype": "^4.0.0" 3638 + }, 3639 + "engines": { 3640 + "node": ">=20.18.1" 3641 + }, 3642 + "funding": { 3643 + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" 3644 + } 3645 + }, 3646 + "node_modules/cheerio-select": { 3647 + "version": "2.1.0", 3648 + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", 3649 + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", 3650 + "license": "BSD-2-Clause", 3651 + "dependencies": { 3652 + "boolbase": "^1.0.0", 3653 + "css-select": "^5.1.0", 3654 + "css-what": "^6.1.0", 3655 + "domelementtype": "^2.3.0", 3656 + "domhandler": "^5.0.3", 3657 + "domutils": "^3.0.1" 3658 + }, 3659 + "funding": { 3660 + "url": "https://github.com/sponsors/fb55" 3661 + } 3662 + }, 3433 3663 "node_modules/chokidar": { 3434 3664 "version": "5.0.0", 3435 3665 "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", ··· 3443 3673 }, 3444 3674 "funding": { 3445 3675 "url": "https://paulmillr.com/funding/" 3676 + } 3677 + }, 3678 + "node_modules/chownr": { 3679 + "version": "3.0.0", 3680 + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", 3681 + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", 3682 + "license": "BlueOak-1.0.0", 3683 + "engines": { 3684 + "node": ">=18" 3446 3685 } 3447 3686 }, 3448 3687 "node_modules/ci-info": { ··· 3524 3763 "dev": true, 3525 3764 "license": "MIT" 3526 3765 }, 3766 + "node_modules/confbox": { 3767 + "version": "0.2.4", 3768 + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.4.tgz", 3769 + "integrity": "sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==", 3770 + "license": "MIT" 3771 + }, 3527 3772 "node_modules/cookie": { 3528 3773 "version": "1.1.1", 3529 3774 "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", ··· 3691 3936 "version": "4.4.3", 3692 3937 "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", 3693 3938 "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", 3694 - "dev": true, 3695 3939 "license": "MIT", 3696 3940 "dependencies": { 3697 3941 "ms": "^2.1.3" ··· 3856 4100 "node": ">=10.0.0" 3857 4101 } 3858 4102 }, 4103 + "node_modules/encoding-sniffer": { 4104 + "version": "0.2.1", 4105 + "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz", 4106 + "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==", 4107 + "license": "MIT", 4108 + "dependencies": { 4109 + "iconv-lite": "^0.6.3", 4110 + "whatwg-encoding": "^3.1.1" 4111 + }, 4112 + "funding": { 4113 + "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" 4114 + } 4115 + }, 4116 + "node_modules/end-of-stream": { 4117 + "version": "1.4.5", 4118 + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", 4119 + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", 4120 + "license": "MIT", 4121 + "dependencies": { 4122 + "once": "^1.4.0" 4123 + } 4124 + }, 3859 4125 "node_modules/enhanced-resolve": { 3860 4126 "version": "5.21.6", 3861 4127 "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.21.6.tgz", ··· 4074 4340 "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", 4075 4341 "license": "MIT" 4076 4342 }, 4343 + "node_modules/exsolve": { 4344 + "version": "1.1.0", 4345 + "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.1.0.tgz", 4346 + "integrity": "sha512-D+42+T12DdIlJM3uepa55qGiL3sYdLBOxIl2ifQCzCHz4c7eiolaHsi3BIqEr7JxBzxv2pYZQX9kw16ziMcEmw==", 4347 + "license": "MIT" 4348 + }, 4077 4349 "node_modules/extend": { 4078 4350 "version": "3.0.2", 4079 4351 "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", 4080 4352 "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", 4081 4353 "license": "MIT" 4354 + }, 4355 + "node_modules/extract-zip": { 4356 + "version": "2.0.1", 4357 + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", 4358 + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", 4359 + "license": "BSD-2-Clause", 4360 + "dependencies": { 4361 + "debug": "^4.1.1", 4362 + "get-stream": "^5.1.0", 4363 + "yauzl": "^2.10.0" 4364 + }, 4365 + "bin": { 4366 + "extract-zip": "cli.js" 4367 + }, 4368 + "engines": { 4369 + "node": ">= 10.17.0" 4370 + }, 4371 + "optionalDependencies": { 4372 + "@types/yauzl": "^2.9.1" 4373 + } 4082 4374 }, 4083 4375 "node_modules/fast-deep-equal": { 4084 4376 "version": "3.1.3", ··· 4125 4417 "fast-string-width": "^3.0.2" 4126 4418 } 4127 4419 }, 4420 + "node_modules/fd-slicer": { 4421 + "version": "1.1.0", 4422 + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", 4423 + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", 4424 + "license": "MIT", 4425 + "dependencies": { 4426 + "pend": "~1.2.0" 4427 + } 4428 + }, 4128 4429 "node_modules/fdir": { 4129 4430 "version": "6.5.0", 4130 4431 "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", ··· 4242 4543 ], 4243 4544 "engines": { 4244 4545 "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 4546 + } 4547 + }, 4548 + "node_modules/get-stream": { 4549 + "version": "5.2.0", 4550 + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", 4551 + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", 4552 + "license": "MIT", 4553 + "dependencies": { 4554 + "pump": "^3.0.0" 4555 + }, 4556 + "engines": { 4557 + "node": ">=8" 4558 + }, 4559 + "funding": { 4560 + "url": "https://github.com/sponsors/sindresorhus" 4245 4561 } 4246 4562 }, 4247 4563 "node_modules/get-tsconfig": { ··· 4458 4774 "url": "https://github.com/sponsors/wooorm" 4459 4775 } 4460 4776 }, 4777 + "node_modules/htmlparser2": { 4778 + "version": "10.1.0", 4779 + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz", 4780 + "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==", 4781 + "funding": [ 4782 + "https://github.com/fb55/htmlparser2?sponsor=1", 4783 + { 4784 + "type": "github", 4785 + "url": "https://github.com/sponsors/fb55" 4786 + } 4787 + ], 4788 + "license": "MIT", 4789 + "dependencies": { 4790 + "domelementtype": "^2.3.0", 4791 + "domhandler": "^5.0.3", 4792 + "domutils": "^3.2.2", 4793 + "entities": "^7.0.1" 4794 + } 4795 + }, 4796 + "node_modules/htmlparser2/node_modules/entities": { 4797 + "version": "7.0.1", 4798 + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", 4799 + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", 4800 + "license": "BSD-2-Clause", 4801 + "engines": { 4802 + "node": ">=0.12" 4803 + }, 4804 + "funding": { 4805 + "url": "https://github.com/fb55/entities?sponsor=1" 4806 + } 4807 + }, 4461 4808 "node_modules/http-cache-semantics": { 4462 4809 "version": "4.2.0", 4463 4810 "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", 4464 4811 "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", 4465 4812 "license": "BSD-2-Clause" 4813 + }, 4814 + "node_modules/iconv-lite": { 4815 + "version": "0.6.3", 4816 + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", 4817 + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", 4818 + "license": "MIT", 4819 + "dependencies": { 4820 + "safer-buffer": ">= 2.1.2 < 3.0.0" 4821 + }, 4822 + "engines": { 4823 + "node": ">=0.10.0" 4824 + } 4466 4825 }, 4467 4826 "node_modules/ignore": { 4468 4827 "version": "5.3.2", ··· 4673 5032 "dependencies": { 4674 5033 "json-buffer": "3.0.1" 4675 5034 } 5035 + }, 5036 + "node_modules/kolorist": { 5037 + "version": "1.8.0", 5038 + "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", 5039 + "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==", 5040 + "license": "MIT" 4676 5041 }, 4677 5042 "node_modules/levn": { 4678 5043 "version": "0.4.1", ··· 4960 5325 "unicode-trie": "^2.0.0" 4961 5326 } 4962 5327 }, 5328 + "node_modules/local-pkg": { 5329 + "version": "1.2.1", 5330 + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.2.1.tgz", 5331 + "integrity": "sha512-++gUqRDEvcnN6Zhqrr+y/CkVEHhlrR96vZn3nZZPYzMcBUyBtTKzB9NadClFIsIVSsu+3i9tfk/erqy9kAmt7Q==", 5332 + "license": "MIT", 5333 + "dependencies": { 5334 + "mlly": "^1.7.4", 5335 + "pkg-types": "^2.3.0", 5336 + "quansync": "^0.2.11" 5337 + }, 5338 + "engines": { 5339 + "node": ">=14" 5340 + }, 5341 + "funding": { 5342 + "url": "https://github.com/sponsors/antfu" 5343 + } 5344 + }, 4963 5345 "node_modules/locate-path": { 4964 5346 "version": "6.0.0", 4965 5347 "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", ··· 5132 5514 "node": "*" 5133 5515 } 5134 5516 }, 5517 + "node_modules/minipass": { 5518 + "version": "7.1.3", 5519 + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", 5520 + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", 5521 + "license": "BlueOak-1.0.0", 5522 + "engines": { 5523 + "node": ">=16 || 14 >=14.17" 5524 + } 5525 + }, 5526 + "node_modules/minizlib": { 5527 + "version": "3.1.0", 5528 + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", 5529 + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", 5530 + "license": "MIT", 5531 + "dependencies": { 5532 + "minipass": "^7.1.2" 5533 + }, 5534 + "engines": { 5535 + "node": ">= 18" 5536 + } 5537 + }, 5538 + "node_modules/mlly": { 5539 + "version": "1.8.2", 5540 + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.2.tgz", 5541 + "integrity": "sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==", 5542 + "license": "MIT", 5543 + "dependencies": { 5544 + "acorn": "^8.16.0", 5545 + "pathe": "^2.0.3", 5546 + "pkg-types": "^1.3.1", 5547 + "ufo": "^1.6.3" 5548 + } 5549 + }, 5550 + "node_modules/mlly/node_modules/confbox": { 5551 + "version": "0.1.8", 5552 + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", 5553 + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", 5554 + "license": "MIT" 5555 + }, 5556 + "node_modules/mlly/node_modules/pkg-types": { 5557 + "version": "1.3.1", 5558 + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", 5559 + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", 5560 + "license": "MIT", 5561 + "dependencies": { 5562 + "confbox": "^0.1.8", 5563 + "mlly": "^1.7.4", 5564 + "pathe": "^2.0.1" 5565 + } 5566 + }, 5135 5567 "node_modules/mrmime": { 5136 5568 "version": "2.0.1", 5137 5569 "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", ··· 5145 5577 "version": "2.1.3", 5146 5578 "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 5147 5579 "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 5148 - "dev": true, 5149 5580 "license": "MIT" 5150 5581 }, 5151 5582 "node_modules/nanoid": { ··· 5257 5688 "resolved": "https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz", 5258 5689 "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==", 5259 5690 "license": "MIT" 5691 + }, 5692 + "node_modules/once": { 5693 + "version": "1.4.0", 5694 + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 5695 + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 5696 + "license": "ISC", 5697 + "dependencies": { 5698 + "wrappy": "1" 5699 + } 5260 5700 }, 5261 5701 "node_modules/oniguruma-parser": { 5262 5702 "version": "0.12.2", ··· 5402 5842 "url": "https://github.com/inikulin/parse5?sponsor=1" 5403 5843 } 5404 5844 }, 5845 + "node_modules/parse5-htmlparser2-tree-adapter": { 5846 + "version": "7.1.0", 5847 + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", 5848 + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", 5849 + "license": "MIT", 5850 + "dependencies": { 5851 + "domhandler": "^5.0.3", 5852 + "parse5": "^7.0.0" 5853 + }, 5854 + "funding": { 5855 + "url": "https://github.com/inikulin/parse5?sponsor=1" 5856 + } 5857 + }, 5858 + "node_modules/parse5-parser-stream": { 5859 + "version": "7.1.2", 5860 + "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", 5861 + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", 5862 + "license": "MIT", 5863 + "dependencies": { 5864 + "parse5": "^7.0.0" 5865 + }, 5866 + "funding": { 5867 + "url": "https://github.com/inikulin/parse5?sponsor=1" 5868 + } 5869 + }, 5405 5870 "node_modules/path-exists": { 5406 5871 "version": "4.0.0", 5407 5872 "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", ··· 5422 5887 "node": ">=8" 5423 5888 } 5424 5889 }, 5890 + "node_modules/pathe": { 5891 + "version": "2.0.3", 5892 + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", 5893 + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", 5894 + "license": "MIT" 5895 + }, 5896 + "node_modules/pend": { 5897 + "version": "1.2.0", 5898 + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", 5899 + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", 5900 + "license": "MIT" 5901 + }, 5425 5902 "node_modules/piccolore": { 5426 5903 "version": "0.1.3", 5427 5904 "resolved": "https://registry.npmjs.org/piccolore/-/piccolore-0.1.3.tgz", ··· 5446 5923 "url": "https://github.com/sponsors/jonschlinkert" 5447 5924 } 5448 5925 }, 5926 + "node_modules/pkg-types": { 5927 + "version": "2.3.1", 5928 + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.1.tgz", 5929 + "integrity": "sha512-y+ichcgc2LrADuhLNAx8DFjVfgz91pRxfZdI3UDhxHvcVEZsenLO+7XaU5vOp0u/7V/wZ+plyuQxtrDlZJ+yeg==", 5930 + "license": "MIT", 5931 + "dependencies": { 5932 + "confbox": "^0.2.4", 5933 + "exsolve": "^1.0.8", 5934 + "pathe": "^2.0.3" 5935 + } 5936 + }, 5449 5937 "node_modules/postcss": { 5450 5938 "version": "8.5.15", 5451 5939 "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", ··· 5550 6038 "url": "https://github.com/sponsors/wooorm" 5551 6039 } 5552 6040 }, 6041 + "node_modules/pump": { 6042 + "version": "3.0.4", 6043 + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", 6044 + "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", 6045 + "license": "MIT", 6046 + "dependencies": { 6047 + "end-of-stream": "^1.1.0", 6048 + "once": "^1.3.1" 6049 + } 6050 + }, 5553 6051 "node_modules/punycode": { 5554 6052 "version": "2.3.1", 5555 6053 "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", ··· 5559 6057 "engines": { 5560 6058 "node": ">=6" 5561 6059 } 6060 + }, 6061 + "node_modules/quansync": { 6062 + "version": "0.2.11", 6063 + "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz", 6064 + "integrity": "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==", 6065 + "funding": [ 6066 + { 6067 + "type": "individual", 6068 + "url": "https://github.com/sponsors/antfu" 6069 + }, 6070 + { 6071 + "type": "individual", 6072 + "url": "https://github.com/sponsors/sxzz" 6073 + } 6074 + ], 6075 + "license": "MIT" 5562 6076 }, 5563 6077 "node_modules/radix3": { 5564 6078 "version": "1.1.2", ··· 5723 6237 "dev": true, 5724 6238 "license": "MIT" 5725 6239 }, 6240 + "node_modules/safer-buffer": { 6241 + "version": "2.1.2", 6242 + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 6243 + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", 6244 + "license": "MIT" 6245 + }, 5726 6246 "node_modules/sass-formatter": { 5727 6247 "version": "0.7.9", 5728 6248 "resolved": "https://registry.npmjs.org/sass-formatter/-/sass-formatter-0.7.9.tgz", ··· 6060 6580 "funding": { 6061 6581 "type": "opencollective", 6062 6582 "url": "https://opencollective.com/webpack" 6583 + } 6584 + }, 6585 + "node_modules/tar": { 6586 + "version": "7.5.16", 6587 + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.16.tgz", 6588 + "integrity": "sha512-56adEpPMouktRlBLXiaYFFzZ/3+JXa8P9n7WbR+ibIjtviN55mEaOkiysCnPnWm+7kkui1Dn8J9l+g6zV8731w==", 6589 + "license": "BlueOak-1.0.0", 6590 + "dependencies": { 6591 + "@isaacs/fs-minipass": "^4.0.0", 6592 + "chownr": "^3.0.0", 6593 + "minipass": "^7.1.2", 6594 + "minizlib": "^3.1.0", 6595 + "yallist": "^5.0.0" 6596 + }, 6597 + "engines": { 6598 + "node": ">=18" 6063 6599 } 6064 6600 }, 6065 6601 "node_modules/tiny-inflate": { ··· 6211 6747 "integrity": "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==", 6212 6748 "license": "MIT" 6213 6749 }, 6750 + "node_modules/undici": { 6751 + "version": "7.28.0", 6752 + "resolved": "https://registry.npmjs.org/undici/-/undici-7.28.0.tgz", 6753 + "integrity": "sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==", 6754 + "license": "MIT", 6755 + "engines": { 6756 + "node": ">=20.18.1" 6757 + } 6758 + }, 6214 6759 "node_modules/undici-types": { 6215 6760 "version": "8.3.0", 6216 6761 "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz", ··· 6589 7134 "url": "https://github.com/sponsors/wooorm" 6590 7135 } 6591 7136 }, 7137 + "node_modules/whatwg-encoding": { 7138 + "version": "3.1.1", 7139 + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", 7140 + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", 7141 + "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", 7142 + "license": "MIT", 7143 + "dependencies": { 7144 + "iconv-lite": "0.6.3" 7145 + }, 7146 + "engines": { 7147 + "node": ">=18" 7148 + } 7149 + }, 7150 + "node_modules/whatwg-mimetype": { 7151 + "version": "4.0.0", 7152 + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", 7153 + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", 7154 + "license": "MIT", 7155 + "engines": { 7156 + "node": ">=18" 7157 + } 7158 + }, 6592 7159 "node_modules/which": { 6593 7160 "version": "2.0.2", 6594 7161 "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", ··· 6624 7191 "node": ">=0.10.0" 6625 7192 } 6626 7193 }, 7194 + "node_modules/wrappy": { 7195 + "version": "1.0.2", 7196 + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 7197 + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 7198 + "license": "ISC" 7199 + }, 6627 7200 "node_modules/xxhash-wasm": { 6628 7201 "version": "1.1.0", 6629 7202 "resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-1.1.0.tgz", 6630 7203 "integrity": "sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==", 6631 7204 "license": "MIT" 6632 7205 }, 7206 + "node_modules/yallist": { 7207 + "version": "5.0.0", 7208 + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", 7209 + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", 7210 + "license": "BlueOak-1.0.0", 7211 + "engines": { 7212 + "node": ">=18" 7213 + } 7214 + }, 6633 7215 "node_modules/yargs-parser": { 6634 7216 "version": "22.0.0", 6635 7217 "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", ··· 6637 7219 "license": "ISC", 6638 7220 "engines": { 6639 7221 "node": "^20.19.0 || ^22.12.0 || >=23" 7222 + } 7223 + }, 7224 + "node_modules/yauzl": { 7225 + "version": "2.10.0", 7226 + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", 7227 + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", 7228 + "license": "MIT", 7229 + "dependencies": { 7230 + "buffer-crc32": "~0.2.3", 7231 + "fd-slicer": "~1.1.0" 6640 7232 } 6641 7233 }, 6642 7234 "node_modules/yocto-queue": {
+4 -1
website/package.json
··· 14 14 }, 15 15 "dependencies": { 16 16 "@astrojs/sitemap": "^3.7.3", 17 - "astro": "^7.0.0" 17 + "@iconify-json/lucide": "^1.2.114", 18 + "@iconify-json/simple-icons": "^1.2.87", 19 + "astro": "^7.0.0", 20 + "astro-icon": "^1.1.5" 18 21 }, 19 22 "devDependencies": { 20 23 "@eslint/js": "^9.39.4",
-22
website/src/components/Icon.astro
··· 1 - --- 2 - import { getIconPath } from "../icons"; 3 - import type { IconName } from "../icons"; 4 - 5 - interface Props { 6 - name: IconName; 7 - filled?: boolean; 8 - class?: string; 9 - } 10 - 11 - const { name, filled = false, class: className } = Astro.props; 12 - --- 13 - 14 - <svg 15 - class={className} 16 - viewBox="0 0 24 24" 17 - fill={filled ? "currentColor" : "none"} 18 - stroke={filled ? undefined : "currentColor"} 19 - stroke-width={filled ? undefined : "2"} 20 - > 21 - <path d={getIconPath(name)}></path> 22 - </svg>
+5 -4
website/src/components/SiteFooter.astro
··· 11 11 12 12 <footer 13 13 class:list={[ 14 - isDocs 15 - ? "border-t border-border bg-bg py-5" 16 - : "py-8 md:py-12 bg-bg-alt", 14 + isDocs ? "border-t border-border bg-bg py-5" : "py-8 md:py-12 bg-bg-alt", 17 15 ]} 18 16 > 19 17 <div ··· 41 39 <nav class="flex flex-wrap gap-5 md:gap-8" aria-label="Footer"> 42 40 { 43 41 footerLinks.map((link) => ( 44 - <a href={link.href} class="text-text-muted text-sm hover:text-primary"> 42 + <a 43 + href={link.href} 44 + class="text-text-muted text-sm hover:text-primary" 45 + > 45 46 {link.label} 46 47 </a> 47 48 ))
+5 -4
website/src/components/SiteHeader.astro
··· 1 1 --- 2 - import Icon from "./Icon.astro"; 3 - import type { IconName } from "../icons"; 2 + import { Icon } from "astro-icon/components"; 4 3 5 4 interface BreadcrumbItem { 6 5 href: string; 7 6 label: string; 8 - icon?: IconName; 7 + icon?: string; 9 8 switchyardIcon?: boolean; 10 9 current?: boolean; 11 10 } ··· 17 16 const { items } = Astro.props; 18 17 --- 19 18 20 - <header class="sticky top-0 z-50 bg-bg/95 backdrop-blur-sm border-b border-border"> 19 + <header 20 + class="sticky top-0 z-50 bg-bg/95 backdrop-blur-sm border-b border-border" 21 + > 21 22 <nav 22 23 class="max-w-[1200px] mx-auto px-4 md:px-8 py-2.5 flex flex-wrap items-center gap-x-2 gap-y-1 text-sm" 23 24 aria-label="Breadcrumb"
+4 -4
website/src/content/docs/home-manager.md
··· 39 39 40 40 ## Options 41 41 42 - - **`enable`** *(bool, default `false`)* — Install Switchyard and enable the module. 43 - - **`package`** *(package, default `switchyard`)* — The Switchyard derivation to install. 44 - - **`setAsDefaultBrowser`** *(bool, default `true`)* — Register Switchyard as the default handler for `x-scheme-handler/http`, `x-scheme-handler/https`, and `text/html` via `xdg.mimeApps`. 45 - - **`settings`** *(TOML, default `{}`)* — Contents of `~/.config/switchyard/config.toml`. Freeform; any key from Switchyard's `Config` struct is accepted, omitted keys fall back to built-in defaults. 42 + - **`enable`** _(bool, default `false`)_ — Install Switchyard and enable the module. 43 + - **`package`** _(package, default `switchyard`)_ — The Switchyard derivation to install. 44 + - **`setAsDefaultBrowser`** _(bool, default `true`)_ — Register Switchyard as the default handler for `x-scheme-handler/http`, `x-scheme-handler/https`, and `text/html` via `xdg.mimeApps`. 45 + - **`settings`** _(TOML, default `{}`)_ — Contents of `~/.config/switchyard/config.toml`. Freeform; any key from Switchyard's `Config` struct is accepted, omitted keys fall back to built-in defaults. 46 46 47 47 ## Declarative Configuration 48 48
+5 -2
website/src/content/docs/webextension.md
··· 4 4 order: 40 5 5 --- 6 6 7 - A companion browser extension that lets you open any page in Switchyard with one click. It lives in the `webextension/` directory, ships as a standard WebExtension compatible with Firefox and Chromium, and is included in GitHub releases as `switchyard-webextension.zip`. 7 + A companion browser extension that lets you open any page in Switchyard with one click. It lives in the `webextension/` directory, ships as a standard WebExtension compatible with Firefox and Chromium, and is available on the [Firefox Add-ons](https://addons.mozilla.org/firefox/addon/switchyard/) and [Chrome Web Store](https://chromewebstore.google.com/detail/switchyard/ncehhpikkabfdcceimdhjjjodogflokc). 8 + 9 + - [Get for Firefox](https://addons.mozilla.org/firefox/addon/switchyard/) 10 + - [Get for Chrome](https://chromewebstore.google.com/detail/switchyard/ncehhpikkabfdcceimdhjjjodogflokc) 8 11 9 - The intent is to add deeper integration with the desktop app. Eventually, it will be submitted to the Chrome Web Store and Mozilla. 12 + The source is also bundled in GitHub releases as `switchyard-webextension.zip` if you prefer to load it manually. 10 13 11 14 ## How It Works 12 15
-27
website/src/icons.ts
··· 1 - const iconPaths = { 2 - github: 3 - "M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z", 4 - heart: 5 - "M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z", 6 - checkCircle: "M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z", 7 - sliders: 8 - "M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4", 9 - nixos: 10 - "M7.352 1.592l-1.364.002L5.32 2.75l1.557 2.713-3.137-.008-1.32 2.34H14.11l-1.353-2.332-3.192-.006-2.214-3.865zm6.175 0l-2.687.025 5.846 10.127 1.341-2.34-1.59-2.765 2.24-3.85-.683-1.182h-1.336l-1.57 2.705-1.56-2.72zm6.887 4.195l-5.846 10.125 2.696-.008 1.601-2.76 4.453.016.682-1.183-.666-1.157-3.13-.008L21.778 8.1l-1.365-2.313zM9.432 8.086l-2.696.008-1.601 2.76-4.453-.016L0 12.02l.666 1.157 3.13.008-1.575 2.71 1.365 2.315L9.432 8.086zM7.33 12.25l-.006.01-.002-.004-1.342 2.34 1.59 2.765-2.24 3.85.684 1.182H7.35l.004-.006h.001l1.567-2.698 1.558 2.72 2.688-.026-.004-.006h.01L7.33 12.25zm2.55 3.93l1.354 2.332 3.192.006 2.215 3.865 1.363-.002.668-1.156-1.557-2.713 3.137.008 1.32-2.34H9.881Z", 11 - flatpak: 12 - "M12 0c-.556 0-1.111.144-1.61.432l-7.603 4.39a3.217 3.217 0 0 0-1.61 2.788v8.78c0 1.151.612 2.212 1.61 2.788l7.603 4.39a3.217 3.217 0 0 0 3.22 0l7.603-4.39a3.217 3.217 0 0 0 1.61-2.788V7.61a3.217 3.217 0 0 0-1.61-2.788L13.61.432A3.218 3.218 0 0 0 12 0Zm0 2.358c.15 0 .299.039.431.115l7.604 4.39c.132.077.24.187.315.316L12 12v9.642a.863.863 0 0 1-.431-.116l-7.604-4.39a.866.866 0 0 1-.431-.746V7.61c0-.153.041-.302.116-.43L12 12Z", 13 - download: 14 - "M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20zm0 14l-4-4h2.5V8h3v4H16l-4 4z", 15 - book: "M4 19.5A2.5 2.5 0 0 1 6.5 17H20 M4 19.5A2.5 2.5 0 0 0 6.5 22H20V2H6.5A2.5 2.5 0 0 0 4 4.5v15z M8 6h8", 16 - link: "M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1", 17 - shuffle: "M16 3h5v5m0-5l-6 6m-2 8l8 8m0-5v5h-5M4 4l5 5m11 11l-5-5M4 20l5-5", 18 - star: "M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z", 19 - zap: "M13 10V3L4 14h7v7l9-11h-7z", 20 - rose: "M17 10h-1a4 4 0 1 1 4-4v.534 M17 6h1a4 4 0 0 1 1.42 7.74l-2.29.87a6 6 0 0 1-5.339-10.68l2.069-1.31 M4.5 17c2.8-.5 4.4 0 5.5.8s1.8 2.2 2.3 3.7c-2 .4-3.5.4-4.8-.3-1.2-.6-2.3-1.9-3-4.2 M9.77 12C4 15 2 22 2 22 M15 8a2 2 0 1 0 4 0a2 2 0 1 0-4 0", 21 - } as const; 22 - 23 - export type IconName = keyof typeof iconPaths; 24 - 25 - export function getIconPath(name: IconName): string { 26 - return iconPaths[name]; 27 - }
+1 -1
website/src/layouts/DocsLayout.astro
··· 33 33 <body class="min-h-screen flex flex-col"> 34 34 <SiteHeader 35 35 items={[ 36 - { href: DEV_URL, label: "Aly Raffauf", icon: "rose" }, 36 + { href: DEV_URL, label: "Aly Raffauf", icon: "lucide:rose" }, 37 37 { href: "/", label: "Switchyard", switchyardIcon: true }, 38 38 { href: "/docs/", label: "Docs", current: true }, 39 39 ]}
+93 -47
website/src/pages/index.astro
··· 1 1 --- 2 2 import "../styles/index.css"; 3 - import Icon from "../components/Icon.astro"; 3 + import { Icon } from "astro-icon/components"; 4 4 import SiteFooter from "../components/SiteFooter.astro"; 5 5 import SiteHeader from "../components/SiteHeader.astro"; 6 6 import { Image } from "astro:assets"; 7 7 import imgLauncher from "../assets/screenshots/launcher.png"; 8 8 import imgBrowserRules from "../assets/screenshots/browser-rules.png"; 9 9 import imgLinkRedirections from "../assets/screenshots/link-redirections.png"; 10 - import { DEV_URL, DONATE_URL, FLATHUB_URL, REPO_URL } from "../site"; 10 + import { 11 + DEV_URL, 12 + DONATE_URL, 13 + FLATHUB_URL, 14 + REPO_URL, 15 + FIREFOX_ADDON_URL, 16 + CHROME_WEBSTORE_URL, 17 + } from "../site"; 18 + import { codeToHtml } from "shiki"; 11 19 12 20 const screenshots = [ 13 21 { src: imgLauncher, alt: "Browser launcher" }, ··· 16 24 ] as const; 17 25 18 26 const heroButtons = [ 19 - { href: FLATHUB_URL, label: "Flathub", icon: "flatpak", primary: true }, 20 - { href: "/docs/", label: "Docs", icon: "book" }, 21 - { href: DONATE_URL, label: "Donate", icon: "heart" }, 27 + { href: FLATHUB_URL, label: "Flathub", icon: "simple-icons:flatpak", primary: true }, 28 + { href: "/docs/", label: "Docs", icon: "lucide:book-open" }, 29 + { href: DONATE_URL, label: "Donate", icon: "lucide:heart" }, 22 30 ] as const; 23 31 24 32 const features = [ 25 33 { 26 - icon: "checkCircle", 34 + icon: "lucide:circle-check", 27 35 title: "Automatic Routing", 28 36 description: 29 37 "Create rules by domain or regex. Links open in the right browser automatically.", 30 38 }, 31 39 { 32 - icon: "sliders", 40 + icon: "lucide:sliders-horizontal", 33 41 title: "Browser Launcher", 34 42 description: 35 43 "No matching rule? Launch a browser with a quick keystroke or mouse click.", 36 44 }, 37 45 { 38 - icon: "shuffle", 46 + icon: "lucide:shuffle", 39 47 title: "Link Redirections", 40 48 description: 41 49 "Rewrite URLs before they open. Strip trackers, swap domains, and more.", 42 50 }, 43 51 { 44 - icon: "link", 52 + icon: "lucide:link", 45 53 title: "Custom URLs", 46 54 description: 47 55 "Encode rules directly with switchyard:// links. Perfect for notes and to-dos.", 48 56 }, 49 57 { 50 - icon: "star", 58 + icon: "lucide:star", 51 59 title: "Favorite Browser", 52 60 description: 53 61 "Pin your favorite browser to appear first and act as fallback.", 54 62 }, 55 63 { 56 - icon: "zap", 64 + icon: "lucide:zap", 57 65 title: "Fast & Native", 58 66 description: 59 67 "A native GNOME app that launches instantly. No background services.", 60 68 }, 61 69 ] as const; 62 70 63 - const showcases = [ 71 + const showcasesRaw = [ 64 72 { 65 73 screenshot: screenshots[1], 66 74 title: "Point-and-Click Setup", ··· 90 98 description: 91 99 "Prefer text editors? Define rules in a simple TOML file. Easy to version control, share, and back up.", 92 100 }, 93 - ] as const; 101 + ]; 102 + 103 + const showcases = showcasesRaw.map((s) => 104 + "code" in s && s.code 105 + ? { 106 + ...s, 107 + codeHtml: codeToHtml(s.code, { lang: "toml", theme: "github-dark" }), 108 + } 109 + : s, 110 + ); 94 111 95 112 const installOptions = [ 96 113 { 97 - icon: "flatpak", 114 + icon: "simple-icons:flatpak", 98 115 title: "Flatpak", 99 - description: "Recommended for most users", 116 + description: "Recommended for most users.", 100 117 link: FLATHUB_URL, 101 118 linkText: "View on Flathub", 102 119 }, 103 120 { 104 - icon: "nixos", 105 - title: "Nix Flake", 106 - description: "Run directly or add to your config", 107 - command: "nix run github:alyraffauf/switchyard", 121 + icon: "simple-icons:nixos", 122 + title: "Nix", 123 + description: "Run directly or add to your config.", 124 + link: "/docs/home-manager/", 125 + linkText: "View in Docs", 108 126 }, 127 + ] as const; 128 + 129 + const extensionOptions = [ 109 130 { 110 - icon: "github", 111 - title: "Build from Source", 112 - description: "Requires Go 1.25+ and GTK4", 113 - link: REPO_URL, 114 - linkText: "View on GitHub", 131 + icon: "simple-icons:firefoxbrowser", 132 + title: "Firefox", 133 + link: FIREFOX_ADDON_URL, 134 + linkText: "Firefox", 135 + }, 136 + { 137 + icon: "simple-icons:googlechrome", 138 + title: "Chrome", 139 + link: CHROME_WEBSTORE_URL, 140 + linkText: "Chrome", 115 141 }, 116 142 ] as const; 117 143 ··· 171 197 <body> 172 198 <SiteHeader 173 199 items={[ 174 - { href: DEV_URL, label: "Aly Raffauf", icon: "rose" }, 200 + { href: DEV_URL, label: "Aly Raffauf", icon: "lucide:rose" }, 175 201 { 176 202 href: "/", 177 203 label: "Switchyard", ··· 237 263 : "bg-transparent text-text border-2 border-border hover:border-primary hover:text-primary" 238 264 }`} 239 265 > 240 - {btn.icon && <Icon name={btn.icon} filled class="w-5 h-5" />} 266 + {btn.icon && <Icon name={btn.icon} class="w-5 h-5" />} 241 267 {btn.label} 242 268 </a> 243 269 )) ··· 306 332 class="w-full max-w-[600px] h-auto rounded-xl md:rounded-2xl border border-border shadow-lg cursor-pointer transition-transform duration-300 hover:scale-[1.02] focus-visible:outline-2 focus-visible:outline-primary focus-visible:outline-offset-2 mx-auto order-first md:order-none" 307 333 /> 308 334 )} 309 - {showcase.code && ( 310 - <pre class="bg-bg-alt rounded-xl px-4 py-3 md:px-5 md:py-4 overflow-x-auto shadow-default border border-border text-left"> 311 - <code class="block font-mono text-xs md:text-sm leading-relaxed text-text whitespace-pre"> 312 - {showcase.code} 313 - </code> 314 - </pre> 335 + {"codeHtml" in showcase && showcase.codeHtml && ( 336 + <div 337 + class="rounded-xl overflow-x-auto shadow-default border border-border text-left text-xs md:text-sm [&_pre]:bg-bg-alt [&_pre]:px-4 [&_pre]:py-3 md:[&_pre]:px-5 md:[&_pre]:py-4 [&_pre]:m-0 [&_code]:font-mono [&_code]:leading-relaxed" 338 + set:html={showcase.codeHtml} 339 + /> 315 340 )} 316 341 <div 317 342 class:list={[ 318 343 "text-center md:text-left", 319 344 { "md:order-first": index % 2 !== 0 }, 345 + { "text-left": "codeHtml" in showcase }, 320 346 ]} 321 347 > 322 348 <h2 class="text-xl md:text-2xl font-bold mb-4 tracking-tight"> ··· 345 371 { 346 372 installOptions.map((option) => ( 347 373 <div class="bg-bg p-5 md:p-8 rounded-2xl border border-border transition-all duration-300 hover:shadow-default hover:-translate-y-0.5"> 348 - <div class="w-9 h-9 md:w-10 md:h-10 mb-4 text-primary"> 349 - <Icon name={option.icon} filled class="w-full h-full" /> 374 + <div class="flex items-center gap-3 mb-4"> 375 + <div class="w-8 h-8 md:w-9 md:h-9 shrink-0 text-primary"> 376 + <Icon name={option.icon} class="w-full h-full" /> 377 + </div> 378 + <h3 class="text-base md:text-lg font-bold">{option.title}</h3> 350 379 </div> 351 - <h3 class="text-base md:text-lg font-bold mb-1"> 352 - {option.title} 353 - </h3> 354 380 <p class="text-text-muted text-sm mb-4">{option.description}</p> 355 - {"command" in option ? ( 356 - <code class="block bg-bg-alt px-3 py-3 md:px-4 rounded-xl text-xs font-mono overflow-x-auto border border-border"> 357 - {option.command} 358 - </code> 359 - ) : ( 381 + <a 382 + href={option.link} 383 + class="block bg-primary text-white px-4 py-3 rounded-xl text-sm font-semibold text-center transition-colors duration-200 hover:bg-primary-light hover:text-white focus-visible:outline-2 focus-visible:outline-primary focus-visible:outline-offset-2" 384 + > 385 + {option.linkText} 386 + </a> 387 + </div> 388 + )) 389 + } 390 + <div 391 + class="bg-bg p-5 md:p-8 rounded-2xl border border-border transition-all duration-300 hover:shadow-default hover:-translate-y-0.5" 392 + > 393 + <div class="flex items-center gap-3 mb-4"> 394 + <div class="w-8 h-8 md:w-9 md:h-9 shrink-0 text-primary"> 395 + <Icon name="lucide:app-window" class="w-full h-full" /> 396 + </div> 397 + <h3 class="text-base md:text-lg font-bold">Browser Extension</h3> 398 + </div> 399 + <p class="text-text-muted text-sm mb-4"> 400 + Open in Switchyard with one click. 401 + </p> 402 + <div class="grid grid-cols-2 gap-3"> 403 + { 404 + extensionOptions.map((option) => ( 360 405 <a 361 406 href={option.link} 362 - class="block bg-primary text-white px-4 py-3 rounded-xl text-sm font-semibold text-center transition-colors duration-200 hover:bg-primary-light hover:text-white focus-visible:outline-2 focus-visible:outline-primary focus-visible:outline-offset-2" 407 + class="inline-flex items-center justify-center gap-2 bg-primary text-white px-3 py-2.5 rounded-xl text-sm font-semibold text-center transition-colors duration-200 hover:bg-primary-light hover:text-white focus-visible:outline-2 focus-visible:outline-primary focus-visible:outline-offset-2" 363 408 > 409 + <Icon name={option.icon} class="w-4 h-4" /> 364 410 {option.linkText} 365 411 </a> 366 - )} 367 - </div> 368 - )) 369 - } 412 + )) 413 + } 414 + </div> 415 + </div> 370 416 </div> 371 417 </div> 372 418 </section>
+4
website/src/site.ts
··· 3 3 export const FLATHUB_URL = 4 4 "https://flathub.org/apps/io.github.alyraffauf.Switchyard"; 5 5 export const DEV_URL = "https://aly.codes"; 6 + export const FIREFOX_ADDON_URL = 7 + "https://addons.mozilla.org/firefox/addon/switchyard/"; 8 + export const CHROME_WEBSTORE_URL = 9 + "https://chromewebstore.google.com/detail/switchyard/ncehhpikkabfdcceimdhjjjodogflokc"; 6 10 7 11 export const footerLinks = [ 8 12 { href: "/docs/", label: "Docs" },