2 description = "Diagonal: Dia-style tab groups for Brave, named by Apple's on-device model";
4 inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
6 outputs = { self, nixpkgs, ... }:
8 systems = [ "aarch64-darwin" "x86_64-linux" "aarch64-linux" ];
9 forAll = f: nixpkgs.lib.genAttrs systems (s: f nixpkgs.legacyPackages.${s});
10 extensionId = nixpkgs.lib.strings.trim (builtins.readFile ./extension-id);
13 packages = forAll (pkgs: rec {
14 # The unpacked extension (dist/). Load it from brave://extensions → Load unpacked.
15 extension = pkgs.buildNpmPackage {
16 pname = "diagonal-extension";
19 npmDeps = pkgs.importNpmLock { npmRoot = ./.; };
20 npmConfigHook = pkgs.importNpmLock.npmConfigHook;
21 npmBuildScript = "build";
22 installPhase = "cp -r dist $out";
25 # The native host: host/ copied whole, the shebang pinned to Nix's python3.
26 diagonal-host = pkgs.stdenvNoCC.mkDerivation {
27 pname = "diagonal-host";
32 mkdir -p $out/libexec/diagonal-host $out/bin
33 cp diagonal-host.py prompts.py validate.py emoji.txt $out/libexec/diagonal-host/
34 substituteInPlace $out/libexec/diagonal-host/diagonal-host.py \
35 --replace-fail "#!/usr/bin/env python3" "#!${pkgs.python3}/bin/python3"
36 chmod +x $out/libexec/diagonal-host/diagonal-host.py
37 ln -s $out/libexec/diagonal-host/diagonal-host.py $out/bin/diagonal-host
39 doInstallCheck = true;
40 installCheckPhase = "$out/bin/diagonal-host --version";
43 default = diagonal-host;
46 devShells = forAll (pkgs: {
47 default = pkgs.mkShell {
48 packages = with pkgs; [ nodejs pnpm typescript esbuild python3 openssl ];
52 homeManagerModules.default = { config, pkgs, lib, ... }:
54 cfg = config.programs.diagonal;
55 host = self.packages.${pkgs.stdenv.hostPlatform.system}.diagonal-host;
57 name = "io.diagonal.host";
58 description = "Diagonal: names tab groups with Apple's on-device model";
59 path = "${host}/bin/diagonal-host";
61 allowed_origins = [ "chrome-extension://${cfg.extensionId}/" ];
65 options.programs.diagonal = {
66 enable = lib.mkEnableOption "the Diagonal native messaging host for Brave";
67 extensionId = lib.mkOption {
69 default = extensionId;
70 description = "Pinned extension ID (from scripts/gen-key.sh). The host itself checks the ID baked into host/diagonal-host.py, so change both together by re-running gen-key.sh.";
72 channels = lib.mkOption {
73 type = lib.types.listOf (lib.types.enum [ "Brave-Browser" "Brave-Browser-Beta" "Brave-Browser-Nightly" ]);
74 default = [ "Brave-Browser" ];
75 description = "Brave channels to install the host manifest for.";
79 config = lib.mkIf cfg.enable {
80 home.packages = [ host ];
81 home.file = lib.listToAttrs (map
82 (ch: lib.nameValuePair
83 "Library/Application Support/BraveSoftware/${ch}/NativeMessagingHosts/io.diagonal.host.json"
84 { text = builtins.toJSON manifest; })
86 # `|| true`: a Mac without Apple Intelligence still activates.
87 home.activation.diagonalSchemas = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
88 ${host}/bin/diagonal-host --install-schemas || true
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list