Compare commits

..

10 Commits

Author SHA1 Message Date
2a14d62d83 fix 2025-12-12 10:04:39 +00:00
4846c84d21 fix depreciation 2025-12-11 20:53:52 +00:00
fcfc996d3c refactor apps 2025-12-11 20:53:52 +00:00
5d7d490636 refactor 2025-12-11 20:49:12 +00:00
a0e4d98402 refactor 2025-12-11 20:49:12 +00:00
54940016c5 gitae landing 2025-12-11 20:41:05 +00:00
fa03b166a4 gitae landing 2025-12-11 20:39:26 +00:00
a99ae65e59 jj aliases 2025-12-11 20:36:57 +00:00
7e407cb189 lock up 2025-12-11 20:23:34 +00:00
edcf5b8eb9 oc exa 2025-12-11 20:21:48 +00:00
70 changed files with 738 additions and 873 deletions

View File

@@ -1,28 +1,7 @@
#!/usr/bin/env bash
set -euo pipefail
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
print_info() {
echo -e "${BLUE}📘${NC} $1"
}
print_success() {
echo -e "${GREEN}✅${NC} $1"
}
print_error() {
echo -e "${RED}❌${NC} $1"
}
print_warning() {
echo -e "${YELLOW}⚡${NC} $1"
}
source "$(dirname "$0")/../common.sh"
HOSTNAME="${1:-$(scutil --get LocalHostName 2>/dev/null || hostname -s)}"

View File

@@ -1,28 +1,7 @@
#!/usr/bin/env bash
set -euo pipefail
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
print_info() {
echo -e "${BLUE}📘${NC} $1"
}
print_success() {
echo -e "${GREEN}✅${NC} $1"
}
print_error() {
echo -e "${RED}❌${NC} $1"
}
print_warning() {
echo -e "${YELLOW}⚡${NC} $1"
}
source "$(dirname "$0")/../common.sh"
HOSTNAME="${1:-$(scutil --get LocalHostName 2>/dev/null || hostname -s)}"

View File

@@ -1,28 +1,7 @@
#!/usr/bin/env bash
set -euo pipefail
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
print_info() {
echo -e "${BLUE}📘${NC} $1"
}
print_success() {
echo -e "${GREEN}✅${NC} $1"
}
print_error() {
echo -e "${RED}❌${NC} $1"
}
print_warning() {
echo -e "${YELLOW}⚡${NC} $1"
}
source "$(dirname "$0")/../common.sh"
HOSTNAME="${1:-$(scutil --get LocalHostName 2>/dev/null || hostname -s)}"

View File

@@ -1,28 +1,7 @@
#!/usr/bin/env bash
set -euo pipefail
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
print_info() {
echo -e "${BLUE}📘${NC} $1"
}
print_success() {
echo -e "${GREEN}✅${NC} $1"
}
print_error() {
echo -e "${RED}❌${NC} $1"
}
print_warning() {
echo -e "${YELLOW}⚡${NC} $1"
}
source "$(dirname "$0")/../common.sh"
print_info "Available generations:"
darwin-rebuild --list-generations

23
apps/common.sh Normal file
View File

@@ -0,0 +1,23 @@
#!/usr/bin/env bash
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
print_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
print_success() {
echo -e "${GREEN}[OK]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}

View File

@@ -1,28 +1,7 @@
#!/usr/bin/env bash
set -euo pipefail
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
print_info() {
echo -e "${BLUE}📘${NC} $1"
}
print_success() {
echo -e "${GREEN}✅${NC} $1"
}
print_error() {
echo -e "${RED}❌${NC} $1"
}
print_warning() {
echo -e "${YELLOW}⚡${NC} $1"
}
source "$(dirname "$0")/../common.sh"
HOSTNAME="${1:-$(hostname)}"

View File

@@ -1,28 +1,7 @@
#!/usr/bin/env bash
set -euo pipefail
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
print_info() {
echo -e "${BLUE}📘${NC} $1"
}
print_success() {
echo -e "${GREEN}✅${NC} $1"
}
print_error() {
echo -e "${RED}❌${NC} $1"
}
print_warning() {
echo -e "${YELLOW}⚡${NC} $1"
}
source "$(dirname "$0")/../common.sh"
HOSTNAME="${1:-$(hostname)}"

View File

@@ -1,24 +1,7 @@
#!/usr/bin/env bash
set -euo pipefail
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
print_info() {
echo -e "${BLUE}📘${NC} $1"
}
print_success() {
echo -e "${GREEN}✅${NC} $1"
}
print_error() {
echo -e "${RED}❌${NC} $1"
}
source "$(dirname "$0")/../common.sh"
HOSTNAME="${1:-$(hostname)}"

View File

@@ -1,28 +1,7 @@
#!/usr/bin/env bash
set -euo pipefail
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
print_info() {
echo -e "${BLUE}📘${NC} $1"
}
print_success() {
echo -e "${GREEN}✅${NC} $1"
}
print_error() {
echo -e "${RED}❌${NC} $1"
}
print_warning() {
echo -e "${YELLOW}⚡${NC} $1"
}
source "$(dirname "$0")/../common.sh"
print_info "Available generations:"
if [[ "$EUID" -ne 0 ]]; then

88
flake.lock generated
View File

@@ -38,7 +38,7 @@
"blueprint": {
"inputs": {
"nixpkgs": [
"nix-ai-tools",
"llm-agents",
"nixpkgs"
],
"systems": "systems_2"
@@ -149,11 +149,11 @@
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1763759067,
"narHash": "sha256-LlLt2Jo/gMNYAwOgdRQBrsRoOz7BPRkzvNaI/fzXi2Q=",
"lastModified": 1765495779,
"narHash": "sha256-MhA7wmo/7uogLxiewwRRmIax70g6q1U/YemqTGoFHlM=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "2cccadc7357c0ba201788ae99c4dfa90728ef5e0",
"rev": "5635c32d666a59ec9a55cab87e898889869f7b71",
"type": "github"
},
"original": {
@@ -170,11 +170,11 @@
]
},
"locked": {
"lastModified": 1763759067,
"narHash": "sha256-LlLt2Jo/gMNYAwOgdRQBrsRoOz7BPRkzvNaI/fzXi2Q=",
"lastModified": 1765495779,
"narHash": "sha256-MhA7wmo/7uogLxiewwRRmIax70g6q1U/YemqTGoFHlM=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "2cccadc7357c0ba201788ae99c4dfa90728ef5e0",
"rev": "5635c32d666a59ec9a55cab87e898889869f7b71",
"type": "github"
},
"original": {
@@ -266,11 +266,11 @@
]
},
"locked": {
"lastModified": 1765337252,
"narHash": "sha256-HuWQp8fM25fyWflbuunQkQI62Hg0ecJxWD52FAgmxqY=",
"lastModified": 1765480374,
"narHash": "sha256-HlbvQAqLx7WqZFFQZ8nu5UUJAVlXiV/kqKbyueA8srw=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "13cc1efd78b943b98c08d74c9060a5b59bf86921",
"rev": "39cb677ed9e908e90478aa9fe5f3383dfc1a63f3",
"type": "github"
},
"original": {
@@ -282,11 +282,11 @@
"homebrew-cask": {
"flake": false,
"locked": {
"lastModified": 1765436475,
"narHash": "sha256-DFaPS71PknrRmGSJ7/acDHwvKDrj2SB85Lir6tpckus=",
"lastModified": 1765528246,
"narHash": "sha256-tF1QcJTTo22L5EQ/DoQYL0lQPQ/99E/vaAh6J7EoELU=",
"owner": "homebrew",
"repo": "homebrew-cask",
"rev": "723fa5c3329fb71daa1f258c2592da8a029d371e",
"rev": "fce756b7cae0c70705e01e89d17811a96c7f52ad",
"type": "github"
},
"original": {
@@ -298,11 +298,11 @@
"homebrew-core": {
"flake": false,
"locked": {
"lastModified": 1765439003,
"narHash": "sha256-akWPwBqM2QoCAulA+eE5G83KTkitMLZWHk0yW1AV3IM=",
"lastModified": 1765532319,
"narHash": "sha256-q6HrIOI19Gu84/x/6y1PfINc3p2c7pGfTViZaIzPP0k=",
"owner": "homebrew",
"repo": "homebrew-core",
"rev": "689a992c97bffeb817e3b11939867e2080607f2f",
"rev": "453aba70829547fb3596d5a4b0fd2da8fca6d3d8",
"type": "github"
},
"original": {
@@ -377,6 +377,26 @@
"url": "https://github.com/rsms/inter/releases/download/v4.1/Inter-4.1.zip"
}
},
"llm-agents": {
"inputs": {
"blueprint": "blueprint",
"nixpkgs": "nixpkgs_2",
"treefmt-nix": "treefmt-nix"
},
"locked": {
"lastModified": 1765508910,
"narHash": "sha256-rcNH6JgKo36ufvPJGUkZW4jktkVz0t8FBtPJv/gRUnQ=",
"owner": "numtide",
"repo": "llm-agents.nix",
"rev": "46c494b51cecf3476c20e54e772c6bc48f10e04d",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "llm-agents.nix",
"type": "github"
}
},
"lucide-src": {
"flake": false,
"locked": {
@@ -390,26 +410,6 @@
"url": "https://github.com/lucide-icons/lucide/releases/download/0.536.0/lucide-icons-0.536.0.zip"
}
},
"nix-ai-tools": {
"inputs": {
"blueprint": "blueprint",
"nixpkgs": "nixpkgs_2",
"treefmt-nix": "treefmt-nix"
},
"locked": {
"lastModified": 1765423017,
"narHash": "sha256-ZXiMZWSet5gpnTGpc02JQHygDaaBwBEWzgUPx0YEm0c=",
"owner": "numtide",
"repo": "nix-ai-tools",
"rev": "6a717d02c0ded2f96568da6a35ab74962cbbf807",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "nix-ai-tools",
"type": "github"
}
},
"nix-homebrew": {
"inputs": {
"brew-src": "brew-src"
@@ -493,11 +493,11 @@
},
"nixpkgs_4": {
"locked": {
"lastModified": 1765270179,
"narHash": "sha256-g2a4MhRKu4ymR4xwo+I+auTknXt/+j37Lnf0Mvfl1rE=",
"lastModified": 1765425892,
"narHash": "sha256-jlQpSkg2sK6IJVzTQBDyRxQZgKADC2HKMRfGCSgNMHo=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "677fbe97984e7af3175b6c121f3c39ee5c8d62c9",
"rev": "5d6bdbddb4695a62f0d00a3620b37a15275a5093",
"type": "github"
},
"original": {
@@ -530,11 +530,11 @@
"systems": "systems_3"
},
"locked": {
"lastModified": 1765413189,
"narHash": "sha256-CEXdMdYV6ETQF/ol8z2odP55b0P/+2UjZczNeBAxBOA=",
"lastModified": 1765532309,
"narHash": "sha256-/2w8cC+Bwut14P33SZydqni+DxvRpRLjq4dSjdfoJio=",
"owner": "nix-community",
"repo": "nixvim",
"rev": "f61667b37eed4f17e19a38eb1d31f0b6be6e52a8",
"rev": "8486f9144ecebdac9672a34b41e532f5a41fcb19",
"type": "github"
},
"original": {
@@ -552,7 +552,7 @@
"home-manager": "home-manager",
"homebrew-cask": "homebrew-cask",
"homebrew-core": "homebrew-core",
"nix-ai-tools": "nix-ai-tools",
"llm-agents": "llm-agents",
"nix-homebrew": "nix-homebrew",
"nixpkgs": "nixpkgs_3",
"nixvim": "nixvim",
@@ -723,7 +723,7 @@
"treefmt-nix": {
"inputs": {
"nixpkgs": [
"nix-ai-tools",
"llm-agents",
"nixpkgs"
]
},

View File

@@ -27,7 +27,7 @@
};
nixvim.url = "github:nix-community/nixvim";
zjstatus.url = "github:dj95/zjstatus";
nix-ai-tools.url = "github:numtide/nix-ai-tools";
llm-agents.url = "github:numtide/llm-agents.nix";
beads.url = "github:steveyegge/beads";
tangled = {
url = "git+https://tangled.org/tangled.org/core";

View File

@@ -6,14 +6,13 @@
...
}: {
imports = [
../../modules/core.nix
../../modules/darwin.nix
../../modules/darwin-syncthing.nix
../../modules/darwin-system.nix
../../modules/dock.nix
../../modules/homebrew.nix
../../modules/syncthing.nix
../../modules/tailscale.nix
../../profiles/core.nix
../../profiles/darwin.nix
../../profiles/dock.nix
../../profiles/homebrew.nix
../../profiles/syncthing.nix
../../profiles/tailscale.nix
inputs.sops-nix.darwinModules.sops
];
@@ -35,29 +34,29 @@
_module.args = {inherit user constants inputs;};
imports = [
inputs.nixvim.homeModules.nixvim
../../modules/atuin.nix
../../modules/bash.nix
../../modules/bat.nix
../../modules/direnv.nix
../../modules/eza.nix
../../modules/fish.nix
../../modules/fzf.nix
../../modules/ghostty.nix
../../modules/git.nix
../../modules/home.nix
../../modules/jjui.nix
../../modules/jujutsu.nix
../../modules/lazygit.nix
../../modules/mise.nix
../../modules/neovim
../../modules/opencode.nix
../../modules/ripgrep.nix
../../modules/ssh.nix
../../modules/starship.nix
../../modules/zellij.nix
../../modules/zk.nix
../../modules/zoxide.nix
../../modules/zsh.nix
../../profiles/atuin.nix
../../profiles/bash.nix
../../profiles/bat.nix
../../profiles/direnv.nix
../../profiles/eza.nix
../../profiles/fish.nix
../../profiles/fzf.nix
../../profiles/ghostty.nix
../../profiles/git.nix
../../profiles/home.nix
../../profiles/jjui.nix
../../profiles/jujutsu.nix
../../profiles/lazygit.nix
../../profiles/mise.nix
../../profiles/neovim
../../profiles/opencode.nix
../../profiles/ripgrep.nix
../../profiles/ssh.nix
../../profiles/starship.nix
../../profiles/zellij.nix
../../profiles/zk.nix
../../profiles/zoxide.nix
../../profiles/zsh.nix
];
fonts.fontconfig.enable = true;
programs.git.settings.user.email = "christoph@tuist.dev";

View File

@@ -4,14 +4,13 @@
...
}: {
imports = [
../../modules/core.nix
../../modules/darwin.nix
../../modules/darwin-syncthing.nix
../../modules/darwin-system.nix
../../modules/dock.nix
../../modules/homebrew.nix
../../modules/syncthing.nix
../../modules/tailscale.nix
../../profiles/core.nix
../../profiles/darwin.nix
../../profiles/dock.nix
../../profiles/homebrew.nix
../../profiles/syncthing.nix
../../profiles/tailscale.nix
inputs.sops-nix.darwinModules.sops
];
@@ -51,29 +50,29 @@
_module.args = {inherit user constants inputs;};
imports = [
inputs.nixvim.homeModules.nixvim
../../modules/atuin.nix
../../modules/bash.nix
../../modules/bat.nix
../../modules/direnv.nix
../../modules/eza.nix
../../modules/fish.nix
../../modules/fzf.nix
../../modules/ghostty.nix
../../modules/git.nix
../../modules/home.nix
../../modules/jjui.nix
../../modules/jujutsu.nix
../../modules/lazygit.nix
../../modules/mise.nix
../../modules/neovim
../../modules/opencode.nix
../../modules/ripgrep.nix
../../modules/ssh.nix
../../modules/starship.nix
../../modules/zellij.nix
../../modules/zk.nix
../../modules/zoxide.nix
../../modules/zsh.nix
../../profiles/atuin.nix
../../profiles/bash.nix
../../profiles/bat.nix
../../profiles/direnv.nix
../../profiles/eza.nix
../../profiles/fish.nix
../../profiles/fzf.nix
../../profiles/ghostty.nix
../../profiles/git.nix
../../profiles/home.nix
../../profiles/jjui.nix
../../profiles/jujutsu.nix
../../profiles/lazygit.nix
../../profiles/mise.nix
../../profiles/neovim
../../profiles/opencode.nix
../../profiles/ripgrep.nix
../../profiles/ssh.nix
../../profiles/starship.nix
../../profiles/zellij.nix
../../profiles/zk.nix
../../profiles/zoxide.nix
../../profiles/zsh.nix
];
fonts.fontconfig.enable = true;
programs.git.settings.user.email = "christoph@schmatzler.com";

View File

@@ -12,10 +12,10 @@
(modulesPath + "/profiles/qemu-guest.nix")
./disk-config.nix
./hardware-configuration.nix
../../modules/core.nix
../../modules/fail2ban.nix
../../modules/gitea.nix
../../modules/nixos.nix
../../profiles/core.nix
../../profiles/fail2ban.nix
../../profiles/gitea.nix
../../profiles/nixos.nix
inputs.disko.nixosModules.disko
];
@@ -27,22 +27,22 @@
_module.args = {inherit user constants inputs;};
imports = [
inputs.nixvim.homeModules.nixvim
../../modules/bash.nix
../../modules/bat.nix
../../modules/direnv.nix
../../modules/eza.nix
../../modules/fish.nix
../../modules/fzf.nix
../../modules/git.nix
../../modules/home.nix
../../modules/jjui.nix
../../modules/jujutsu.nix
../../modules/lazygit.nix
../../modules/neovim
../../modules/ripgrep.nix
../../modules/ssh.nix
../../modules/starship.nix
../../modules/zoxide.nix
../../profiles/bash.nix
../../profiles/bat.nix
../../profiles/direnv.nix
../../profiles/eza.nix
../../profiles/fish.nix
../../profiles/fzf.nix
../../profiles/git.nix
../../profiles/home.nix
../../profiles/jjui.nix
../../profiles/jujutsu.nix
../../profiles/lazygit.nix
../../profiles/neovim
../../profiles/ripgrep.nix
../../profiles/ssh.nix
../../profiles/starship.nix
../../profiles/zoxide.nix
];
};

View File

@@ -8,10 +8,10 @@
...
}: {
imports = [
../../modules/core.nix
../../modules/nixos.nix
../../modules/syncthing.nix
../../modules/tailscale.nix
../../profiles/core.nix
../../profiles/nixos.nix
../../profiles/syncthing.nix
../../profiles/tailscale.nix
inputs.sops-nix.nixosModules.sops
];
@@ -23,33 +23,33 @@
_module.args = {inherit user constants inputs;};
imports = [
inputs.nixvim.homeModules.nixvim
../../modules/atuin.nix
../../modules/bash.nix
../../modules/bat.nix
../../modules/direnv.nix
../../modules/eza.nix
../../modules/fish.nix
../../modules/fzf.nix
../../modules/git.nix
../../modules/home.nix
../../modules/jjui.nix
../../modules/jujutsu.nix
../../modules/lazygit.nix
../../modules/mise.nix
../../modules/neovim
../../modules/opencode.nix
../../modules/ripgrep.nix
../../modules/ssh.nix
../../modules/starship.nix
../../modules/zellij.nix
../../modules/zk.nix
../../modules/zoxide.nix
../../modules/zsh.nix
../../profiles/atuin.nix
../../profiles/bash.nix
../../profiles/bat.nix
../../profiles/direnv.nix
../../profiles/eza.nix
../../profiles/fish.nix
../../profiles/fzf.nix
../../profiles/git.nix
../../profiles/home.nix
../../profiles/jjui.nix
../../profiles/jujutsu.nix
../../profiles/lazygit.nix
../../profiles/mise.nix
../../profiles/neovim
../../profiles/opencode.nix
../../profiles/ripgrep.nix
../../profiles/ssh.nix
../../profiles/starship.nix
../../profiles/zellij.nix
../../profiles/zk.nix
../../profiles/zoxide.nix
../../profiles/zsh.nix
];
home.packages = [
inputs.beads.packages.${pkgs.system}.default
inputs.nix-ai-tools.packages.${pkgs.system}.amp
inputs.beads.packages.${pkgs.stdenv.hostPlatform.system}.default
inputs.llm-agents.packages.${pkgs.stdenv.hostPlatform.system}.amp
];
programs.git.settings.user.email = "christoph@schmatzler.com";

View File

@@ -1,437 +0,0 @@
{
config,
lib,
pkgs,
...
}:
with lib; let
cfg = config.services.syncthing;
settingsFormat = pkgs.formats.json {};
cleanedConfig = converge (filterAttrsRecursive (_: v: v != null && v != {})) cfg.settings;
isUnixGui = (builtins.substring 0 1 cfg.guiAddress) == "/";
curlAddressArgs = path:
if isUnixGui
then "--unix-socket ${cfg.guiAddress} http://.${path}"
else "${cfg.guiAddress}${path}";
devices = mapAttrsToList (_: device: device // {deviceID = device.id;}) cfg.settings.devices;
anyAutoAccept = builtins.any (dev: dev.autoAcceptFolders) devices;
folders =
mapAttrsToList (_: folder:
folder
// {
devices = let
folderDevices = folder.devices;
in
map (
device:
if builtins.isString device
then {deviceId = cfg.settings.devices.${device}.id;}
else if builtins.isAttrs device
then {deviceId = cfg.settings.devices.${device.name}.id;} // device
else throw "Invalid type for devices in folder; expected list or attrset."
)
folderDevices;
}) (filterAttrs (_: folder: folder.enable) cfg.settings.folders);
jq = "${pkgs.jq}/bin/jq";
updateConfig =
pkgs.writers.writeBash "merge-syncthing-config" (
''
set -efu
umask 0077
curl() {
while
! ${pkgs.libxml2}/bin/xmllint \
--xpath 'string(configuration/gui/apikey)' \
${cfg.configDir}/config.xml \
>"$TMPDIR/api_key"
do sleep 1; done
(printf "X-API-Key: "; cat "$TMPDIR/api_key") >"$TMPDIR/headers"
${pkgs.curl}/bin/curl -sSLk -H "@$TMPDIR/headers" \
--retry 1000 --retry-delay 1 --retry-all-errors \
"$@"
}
''
+ (lib.pipe {
devs = {
new_conf_IDs = map (v: v.id) devices;
GET_IdAttrName = "deviceID";
override = cfg.overrideDevices;
conf = devices;
baseAddress = curlAddressArgs "/rest/config/devices";
};
dirs = {
new_conf_IDs = map (v: v.id) folders;
GET_IdAttrName = "id";
override = cfg.overrideFolders;
conf = folders;
baseAddress = curlAddressArgs "/rest/config/folders";
};
} [
(mapAttrs (
conf_type: s:
lib.pipe s.conf [
(map (
new_cfg: let
jsonPreSecretsFile =
pkgs.writeTextFile {
name = "${conf_type}-${new_cfg.id}-conf-pre-secrets.json";
text = builtins.toJSON new_cfg;
};
injectSecretsJqCmd =
{
"devs" = "${jq} .";
"dirs" = let
folder = new_cfg;
devicesWithSecrets =
lib.pipe folder.devices [
(lib.filter (device: (builtins.isAttrs device) && device ? encryptionPasswordFile))
(map (device: {
deviceId = device.deviceId;
variableName = "secret_${builtins.hashString "sha256" device.encryptionPasswordFile}";
secretPath = device.encryptionPasswordFile;
}))
];
jqUpdates =
map (device: ''
.devices[] |= (
if .deviceId == "${device.deviceId}" then
del(.encryptionPasswordFile) |
.encryptionPassword = ''$${device.variableName}
else
.
end
)
'')
devicesWithSecrets;
jqRawFiles = map (device: "--rawfile ${device.variableName} ${lib.escapeShellArg device.secretPath}") devicesWithSecrets;
in "${jq} ${lib.concatStringsSep " " jqRawFiles} ${lib.escapeShellArg (lib.concatStringsSep "|" (["."] ++ jqUpdates))}";
}.${
conf_type
};
in ''
${injectSecretsJqCmd} ${jsonPreSecretsFile} | curl --json @- -X POST ${s.baseAddress}
''
))
(lib.concatStringsSep "\n")
]
+ lib.optionalString s.override ''
stale_${conf_type}_ids="$(curl -X GET ${s.baseAddress} | ${jq} \
--argjson new_ids ${lib.escapeShellArg (builtins.toJSON s.new_conf_IDs)} \
--raw-output \
'[.[].${s.GET_IdAttrName}] - $new_ids | .[]'
)"
for id in ''${stale_${conf_type}_ids}; do
>&2 echo "Deleting stale device: $id"
curl -X DELETE ${s.baseAddress}/$id
done
''
))
builtins.attrValues
(lib.concatStringsSep "\n")
])
+ (lib.pipe cleanedConfig [
builtins.attrNames
(lib.subtractLists ["folders" "devices"])
(map (subOption: ''
curl -X PUT -d ${lib.escapeShellArg (builtins.toJSON cleanedConfig.${subOption})} ${curlAddressArgs "/rest/config/${subOption}"}
''))
(lib.concatStringsSep "\n")
])
+ ''
if curl ${curlAddressArgs "/rest/config/restart-required"} |
${jq} -e .requiresRestart > /dev/null; then
curl -X POST ${curlAddressArgs "/rest/system/restart"}
fi
''
);
in {
options = {
services.syncthing = {
enable = mkEnableOption "Syncthing, a self-hosted open-source alternative to Dropbox and Bittorrent Sync";
cert =
mkOption {
type = types.nullOr types.str;
default = null;
description = "Path to the cert.pem file, which will be copied into Syncthing's configDir.";
};
key =
mkOption {
type = types.nullOr types.str;
default = null;
description = "Path to the key.pem file, which will be copied into Syncthing's configDir.";
};
overrideDevices =
mkOption {
type = types.bool;
default = true;
description = "Whether to delete the devices which are not configured via the devices option.";
};
overrideFolders =
mkOption {
type = types.bool;
default = !anyAutoAccept;
description = "Whether to delete the folders which are not configured via the folders option.";
};
settings =
mkOption {
type =
types.submodule {
freeformType = settingsFormat.type;
options = {
options =
mkOption {
default = {};
description = "The options element contains all other global configuration options";
type =
types.submodule {
freeformType = settingsFormat.type;
options = {
localAnnounceEnabled =
mkOption {
type = types.nullOr types.bool;
default = null;
description = "Whether to send announcements to the local LAN.";
};
globalAnnounceEnabled =
mkOption {
type = types.nullOr types.bool;
default = null;
description = "Whether to send announcements to the global discovery servers.";
};
relaysEnabled =
mkOption {
type = types.nullOr types.bool;
default = null;
description = "When true, relays will be connected to and potentially used for device to device connections.";
};
urAccepted =
mkOption {
type = types.nullOr types.int;
default = null;
description = "Whether the user has accepted to submit anonymous usage data.";
};
};
};
};
devices =
mkOption {
default = {};
description = "Peers/devices which Syncthing should communicate with.";
type =
types.attrsOf (types.submodule ({name, ...}: {
freeformType = settingsFormat.type;
options = {
name =
mkOption {
type = types.str;
default = name;
description = "The name of the device.";
};
id =
mkOption {
type = types.str;
description = "The device ID.";
};
autoAcceptFolders =
mkOption {
type = types.bool;
default = false;
description = "Automatically create or share folders that this device advertises at the default path.";
};
};
}));
};
folders =
mkOption {
default = {};
description = "Folders which should be shared by Syncthing.";
type =
types.attrsOf (types.submodule ({name, ...}: {
freeformType = settingsFormat.type;
options = {
enable =
mkOption {
type = types.bool;
default = true;
description = "Whether to share this folder.";
};
path =
mkOption {
type = types.str;
default = name;
description = "The path to the folder which should be shared.";
};
id =
mkOption {
type = types.str;
default = name;
description = "The ID of the folder. Must be the same on all devices.";
};
label =
mkOption {
type = types.str;
default = name;
description = "The label of the folder.";
};
type =
mkOption {
type = types.enum ["sendreceive" "sendonly" "receiveonly" "receiveencrypted"];
default = "sendreceive";
description = "Controls how the folder is handled by Syncthing.";
};
devices =
mkOption {
type =
types.listOf (types.oneOf [
types.str
(types.submodule {
freeformType = settingsFormat.type;
options = {
name =
mkOption {
type = types.str;
description = "The name of a device defined in the devices option.";
};
encryptionPasswordFile =
mkOption {
type = types.nullOr types.path;
default = null;
description = "Path to encryption password file.";
};
};
})
]);
default = [];
description = "The devices this folder should be shared with.";
};
};
}));
};
};
};
default = {};
description = "Extra configuration options for Syncthing.";
};
guiAddress =
mkOption {
type = types.str;
default = "127.0.0.1:8384";
description = "The address to serve the web interface at.";
};
user =
mkOption {
type = types.str;
default = "syncthing";
description = "The user to run Syncthing as.";
};
group =
mkOption {
type = types.str;
default = "syncthing";
description = "The group to run Syncthing under.";
};
dataDir =
mkOption {
type = types.path;
default = "/var/lib/syncthing";
description = "The path where synchronised directories will exist.";
};
configDir =
mkOption {
type = types.path;
default = cfg.dataDir + "/.config/syncthing";
description = "The path where the settings and keys will exist.";
};
openDefaultPorts =
mkOption {
type = types.bool;
default = false;
description = "Whether to open the default ports in the firewall (not applicable on Darwin).";
};
package = mkPackageOption pkgs "syncthing" {};
};
};
config =
mkIf cfg.enable {
assertions = [
{
assertion = !(cfg.overrideFolders && anyAutoAccept);
message = "services.syncthing.overrideFolders will delete auto-accepted folders from the configuration, creating path conflicts.";
}
];
environment.systemPackages = [cfg.package];
launchd.user.agents.syncthing = {
serviceConfig = {
ProgramArguments = [
"${cfg.package}/bin/syncthing"
"--no-browser"
"--gui-address=${
if isUnixGui
then "unix://"
else ""
}${cfg.guiAddress}"
"--config=${cfg.configDir}"
"--data=${cfg.configDir}"
];
EnvironmentVariables = {
STNORESTART = "yes";
STNOUPGRADE = "yes";
};
KeepAlive = true;
RunAtLoad = true;
ProcessType = "Background";
StandardOutPath = "${cfg.configDir}/syncthing.log";
StandardErrorPath = "${cfg.configDir}/syncthing.log";
};
};
launchd.user.agents.syncthing-init =
mkIf (cleanedConfig != {}) {
serviceConfig = {
ProgramArguments = ["${updateConfig}"];
RunAtLoad = true;
KeepAlive = false;
ProcessType = "Background";
StandardOutPath = "${cfg.configDir}/syncthing-init.log";
StandardErrorPath = "${cfg.configDir}/syncthing-init.log";
};
};
system.activationScripts.syncthing =
mkIf (cfg.cert != null || cfg.key != null) ''
echo "Setting up Syncthing certificates..."
mkdir -p ${cfg.configDir}
${optionalString (cfg.cert != null) ''
cp ${toString cfg.cert} ${cfg.configDir}/cert.pem
chmod 644 ${cfg.configDir}/cert.pem
''}
${optionalString (cfg.key != null) ''
cp ${toString cfg.key} ${cfg.configDir}/key.pem
chmod 600 ${cfg.configDir}/key.pem
''}
'';
};
}

View File

@@ -1,32 +0,0 @@
{
system.defaults = {
NSGlobalDomain = {
# null equals "Light"
AppleInterfaceStyle = null;
AppleShowAllExtensions = true;
ApplePressAndHoldEnabled = false;
KeyRepeat = 2;
InitialKeyRepeat = 15;
"com.apple.mouse.tapBehavior" = 1;
"com.apple.sound.beep.volume" = 0.0;
"com.apple.sound.beep.feedback" = 0;
};
dock = {
autohide = true;
show-recents = false;
launchanim = true;
orientation = "bottom";
tilesize = 60;
};
finder = {
_FXShowPosixPathInTitle = false;
};
trackpad = {
Clicking = true;
TrackpadThreeFingerDrag = true;
};
};
}

View File

@@ -1,29 +0,0 @@
{
constants,
pkgs,
user,
...
}: {
system = {
primaryUser = user;
stateVersion = constants.stateVersions.darwin;
};
nix = {
settings.trusted-users = ["@admin" "${user}"];
gc.interval = {
Weekday = 0;
Hour = 2;
Minute = 0;
};
};
users.users.${user} = {
name = "${user}";
home = "/Users/${user}";
isHidden = false;
shell = pkgs.fish;
};
home-manager.useGlobalPkgs = true;
}

View File

@@ -1,53 +1,437 @@
{
user,
config,
lib,
pkgs,
...
}: let
isDarwin = pkgs.stdenv.isDarwin;
homeDir =
if isDarwin
then "/Users/${user}"
else "/home/${user}";
group =
if isDarwin
then "staff"
else "users";
}:
with lib; let
cfg = config.services.syncthing;
settingsFormat = pkgs.formats.json {};
cleanedConfig = converge (filterAttrsRecursive (_: v: v != null && v != {})) cfg.settings;
isUnixGui = (builtins.substring 0 1 cfg.guiAddress) == "/";
curlAddressArgs = path:
if isUnixGui
then "--unix-socket ${cfg.guiAddress} http://.${path}"
else "${cfg.guiAddress}${path}";
devices = mapAttrsToList (_: device: device // {deviceID = device.id;}) cfg.settings.devices;
anyAutoAccept = builtins.any (dev: dev.autoAcceptFolders) devices;
folders =
mapAttrsToList (_: folder:
folder
// {
devices = let
folderDevices = folder.devices;
in
map (
device:
if builtins.isString device
then {deviceId = cfg.settings.devices.${device}.id;}
else if builtins.isAttrs device
then {deviceId = cfg.settings.devices.${device.name}.id;} // device
else throw "Invalid type for devices in folder; expected list or attrset."
)
folderDevices;
}) (filterAttrs (_: folder: folder.enable) cfg.settings.folders);
jq = "${pkgs.jq}/bin/jq";
updateConfig =
pkgs.writers.writeBash "merge-syncthing-config" (
''
set -efu
umask 0077
curl() {
while
! ${pkgs.libxml2}/bin/xmllint \
--xpath 'string(configuration/gui/apikey)' \
${cfg.configDir}/config.xml \
>"$TMPDIR/api_key"
do sleep 1; done
(printf "X-API-Key: "; cat "$TMPDIR/api_key") >"$TMPDIR/headers"
${pkgs.curl}/bin/curl -sSLk -H "@$TMPDIR/headers" \
--retry 1000 --retry-delay 1 --retry-all-errors \
"$@"
}
''
+ (lib.pipe {
devs = {
new_conf_IDs = map (v: v.id) devices;
GET_IdAttrName = "deviceID";
override = cfg.overrideDevices;
conf = devices;
baseAddress = curlAddressArgs "/rest/config/devices";
};
dirs = {
new_conf_IDs = map (v: v.id) folders;
GET_IdAttrName = "id";
override = cfg.overrideFolders;
conf = folders;
baseAddress = curlAddressArgs "/rest/config/folders";
};
} [
(mapAttrs (
conf_type: s:
lib.pipe s.conf [
(map (
new_cfg: let
jsonPreSecretsFile =
pkgs.writeTextFile {
name = "${conf_type}-${new_cfg.id}-conf-pre-secrets.json";
text = builtins.toJSON new_cfg;
};
injectSecretsJqCmd =
{
"devs" = "${jq} .";
"dirs" = let
folder = new_cfg;
devicesWithSecrets =
lib.pipe folder.devices [
(lib.filter (device: (builtins.isAttrs device) && device ? encryptionPasswordFile))
(map (device: {
deviceId = device.deviceId;
variableName = "secret_${builtins.hashString "sha256" device.encryptionPasswordFile}";
secretPath = device.encryptionPasswordFile;
}))
];
jqUpdates =
map (device: ''
.devices[] |= (
if .deviceId == "${device.deviceId}" then
del(.encryptionPasswordFile) |
.encryptionPassword = ''$${device.variableName}
else
.
end
)
'')
devicesWithSecrets;
jqRawFiles = map (device: "--rawfile ${device.variableName} ${lib.escapeShellArg device.secretPath}") devicesWithSecrets;
in "${jq} ${lib.concatStringsSep " " jqRawFiles} ${lib.escapeShellArg (lib.concatStringsSep "|" (["."] ++ jqUpdates))}";
}.${
conf_type
};
in ''
${injectSecretsJqCmd} ${jsonPreSecretsFile} | curl --json @- -X POST ${s.baseAddress}
''
))
(lib.concatStringsSep "\n")
]
+ lib.optionalString s.override ''
stale_${conf_type}_ids="$(curl -X GET ${s.baseAddress} | ${jq} \
--argjson new_ids ${lib.escapeShellArg (builtins.toJSON s.new_conf_IDs)} \
--raw-output \
'[.[].${s.GET_IdAttrName}] - $new_ids | .[]'
)"
for id in ''${stale_${conf_type}_ids}; do
>&2 echo "Deleting stale device: $id"
curl -X DELETE ${s.baseAddress}/$id
done
''
))
builtins.attrValues
(lib.concatStringsSep "\n")
])
+ (lib.pipe cleanedConfig [
builtins.attrNames
(lib.subtractLists ["folders" "devices"])
(map (subOption: ''
curl -X PUT -d ${lib.escapeShellArg (builtins.toJSON cleanedConfig.${subOption})} ${curlAddressArgs "/rest/config/${subOption}"}
''))
(lib.concatStringsSep "\n")
])
+ ''
if curl ${curlAddressArgs "/rest/config/restart-required"} |
${jq} -e .requiresRestart > /dev/null; then
curl -X POST ${curlAddressArgs "/rest/system/restart"}
fi
''
);
in {
options = {
services.syncthing = {
enable = true;
openDefaultPorts = !isDarwin;
dataDir = "${homeDir}/.local/share/syncthing";
configDir = "${homeDir}/.config/syncthing";
user = "${user}";
group = group;
guiAddress = "0.0.0.0:8384";
overrideFolders = true;
overrideDevices = true;
enable = mkEnableOption "Syncthing, a self-hosted open-source alternative to Dropbox and Bittorrent Sync";
settings = {
devices = {
"tahani" = {
id = "6B7OZZF-TEAMUGO-FBOELXP-Z4OY7EU-5ZHLB5T-V6Z3UDB-Q2DYR43-QBYW6QM";
addresses = ["tcp://tahani:22000"];
cert =
mkOption {
type = types.nullOr types.str;
default = null;
description = "Path to the cert.pem file, which will be copied into Syncthing's configDir.";
};
key =
mkOption {
type = types.nullOr types.str;
default = null;
description = "Path to the key.pem file, which will be copied into Syncthing's configDir.";
};
overrideDevices =
mkOption {
type = types.bool;
default = true;
description = "Whether to delete the devices which are not configured via the devices option.";
};
overrideFolders =
mkOption {
type = types.bool;
default = !anyAutoAccept;
description = "Whether to delete the folders which are not configured via the folders option.";
};
settings =
mkOption {
type =
types.submodule {
freeformType = settingsFormat.type;
options = {
options =
mkOption {
default = {};
description = "The options element contains all other global configuration options";
type =
types.submodule {
freeformType = settingsFormat.type;
options = {
localAnnounceEnabled =
mkOption {
type = types.nullOr types.bool;
default = null;
description = "Whether to send announcements to the local LAN.";
};
globalAnnounceEnabled =
mkOption {
type = types.nullOr types.bool;
default = null;
description = "Whether to send announcements to the global discovery servers.";
};
relaysEnabled =
mkOption {
type = types.nullOr types.bool;
default = null;
description = "When true, relays will be connected to and potentially used for device to device connections.";
};
urAccepted =
mkOption {
type = types.nullOr types.int;
default = null;
description = "Whether the user has accepted to submit anonymous usage data.";
};
"jason" = {
id = "42II2VO-QYPJG26-ZS3MB2I-AOPVZ67-JJNSE76-U54CO5Y-634A5OG-ECU4YQA";
addresses = ["tcp://jason:22000"];
};
"chidi" = {
id = "N7W6SUT-QO6J4BE-T3Y65SM-OFGYGNV-TGYBJPX-JVN4Z72-AENZ247-KWXOQA6";
addresses = ["tcp://chidi:22000"];
};
};
folders = {
"nixos-config" = {
path = "${homeDir}/nixos-config";
devices = ["tahani" "jason" "chidi"];
devices =
mkOption {
default = {};
description = "Peers/devices which Syncthing should communicate with.";
type =
types.attrsOf (types.submodule ({name, ...}: {
freeformType = settingsFormat.type;
options = {
name =
mkOption {
type = types.str;
default = name;
description = "The name of the device.";
};
id =
mkOption {
type = types.str;
description = "The device ID.";
};
autoAcceptFolders =
mkOption {
type = types.bool;
default = false;
description = "Automatically create or share folders that this device advertises at the default path.";
};
};
}));
};
folders =
mkOption {
default = {};
description = "Folders which should be shared by Syncthing.";
type =
types.attrsOf (types.submodule ({name, ...}: {
freeformType = settingsFormat.type;
options = {
enable =
mkOption {
type = types.bool;
default = true;
description = "Whether to share this folder.";
};
path =
mkOption {
type = types.str;
default = name;
description = "The path to the folder which should be shared.";
};
id =
mkOption {
type = types.str;
default = name;
description = "The ID of the folder. Must be the same on all devices.";
};
label =
mkOption {
type = types.str;
default = name;
description = "The label of the folder.";
};
type =
mkOption {
type = types.enum ["sendreceive" "sendonly" "receiveonly" "receiveencrypted"];
default = "sendreceive";
description = "Controls how the folder is handled by Syncthing.";
};
devices =
mkOption {
type =
types.listOf (types.oneOf [
types.str
(types.submodule {
freeformType = settingsFormat.type;
options = {
name =
mkOption {
type = types.str;
description = "The name of a device defined in the devices option.";
};
encryptionPasswordFile =
mkOption {
type = types.nullOr types.path;
default = null;
description = "Path to encryption password file.";
};
};
})
]);
default = [];
description = "The devices this folder should be shared with.";
};
};
}));
};
};
};
default = {};
description = "Extra configuration options for Syncthing.";
};
guiAddress =
mkOption {
type = types.str;
default = "127.0.0.1:8384";
description = "The address to serve the web interface at.";
};
user =
mkOption {
type = types.str;
default = "syncthing";
description = "The user to run Syncthing as.";
};
group =
mkOption {
type = types.str;
default = "syncthing";
description = "The group to run Syncthing under.";
};
dataDir =
mkOption {
type = types.path;
default = "/var/lib/syncthing";
description = "The path where synchronised directories will exist.";
};
configDir =
mkOption {
type = types.path;
default = cfg.dataDir + "/.config/syncthing";
description = "The path where the settings and keys will exist.";
};
openDefaultPorts =
mkOption {
type = types.bool;
default = false;
description = "Whether to open the default ports in the firewall (not applicable on Darwin).";
};
package = mkPackageOption pkgs "syncthing" {};
};
};
options.globalAnnounceEnabled = false;
config =
mkIf cfg.enable {
assertions = [
{
assertion = !(cfg.overrideFolders && anyAutoAccept);
message = "services.syncthing.overrideFolders will delete auto-accepted folders from the configuration, creating path conflicts.";
}
];
environment.systemPackages = [cfg.package];
launchd.user.agents.syncthing = {
serviceConfig = {
ProgramArguments = [
"${cfg.package}/bin/syncthing"
"--no-browser"
"--gui-address=${
if isUnixGui
then "unix://"
else ""
}${cfg.guiAddress}"
"--config=${cfg.configDir}"
"--data=${cfg.configDir}"
];
EnvironmentVariables = {
STNORESTART = "yes";
STNOUPGRADE = "yes";
};
KeepAlive = true;
RunAtLoad = true;
ProcessType = "Background";
StandardOutPath = "${cfg.configDir}/syncthing.log";
StandardErrorPath = "${cfg.configDir}/syncthing.log";
};
};
launchd.user.agents.syncthing-init =
mkIf (cleanedConfig != {}) {
serviceConfig = {
ProgramArguments = ["${updateConfig}"];
RunAtLoad = true;
KeepAlive = false;
ProcessType = "Background";
StandardOutPath = "${cfg.configDir}/syncthing-init.log";
StandardErrorPath = "${cfg.configDir}/syncthing-init.log";
};
};
system.activationScripts.syncthing =
mkIf (cfg.cert != null || cfg.key != null) ''
echo "Setting up Syncthing certificates..."
mkdir -p ${cfg.configDir}
${optionalString (cfg.cert != null) ''
cp ${toString cfg.cert} ${cfg.configDir}/cert.pem
chmod 644 ${cfg.configDir}/cert.pem
''}
${optionalString (cfg.key != null) ''
cp ${toString cfg.key} ${cfg.configDir}/key.pem
chmod 600 ${cfg.configDir}/key.pem
''}
'';
};
}

View File

@@ -1,3 +1,3 @@
{inputs}: final: prev: {
zjstatus = inputs.zjstatus.packages.${prev.system}.default;
zjstatus = inputs.zjstatus.packages.${prev.stdenv.hostPlatform.system}.default;
}

60
profiles/darwin.nix Normal file
View File

@@ -0,0 +1,60 @@
{
constants,
pkgs,
user,
...
}: {
system = {
primaryUser = user;
stateVersion = constants.stateVersions.darwin;
defaults = {
NSGlobalDomain = {
# null equals "Light"
AppleInterfaceStyle = null;
AppleShowAllExtensions = true;
ApplePressAndHoldEnabled = false;
KeyRepeat = 2;
InitialKeyRepeat = 15;
"com.apple.mouse.tapBehavior" = 1;
"com.apple.sound.beep.volume" = 0.0;
"com.apple.sound.beep.feedback" = 0;
};
dock = {
autohide = true;
show-recents = false;
launchanim = true;
orientation = "bottom";
tilesize = 60;
};
finder = {
_FXShowPosixPathInTitle = false;
};
trackpad = {
Clicking = true;
TrackpadThreeFingerDrag = true;
};
};
};
nix = {
settings.trusted-users = ["@admin" "${user}"];
gc.interval = {
Weekday = 0;
Hour = 2;
Minute = 0;
};
};
users.users.${user} = {
name = "${user}";
home = "/Users/${user}";
isHidden = false;
shell = pkgs.fish;
};
home-manager.useGlobalPkgs = true;
}

View File

@@ -21,6 +21,7 @@
SAME_SITE = "strict";
};
api.ENABLE_SWAGGER = false;
server.LANDING_PAGE = "explore";
};
};

View File

@@ -7,6 +7,8 @@
email = "christoph@schmatzler.com";
};
git = {
sign-on-push = true;
subprocess = true;
write-change-id-header = true;
};
diff = {
@@ -19,7 +21,9 @@
diff-editor = ["nvim" "-c" "DiffEditor $left $right $output"];
};
aliases = {
n = ["new"];
tug = ["bookmark" "move" "--from" "closest_bookmark(@-)" "--to" "@-"];
stack = ["log" "-r" "ancestors((trunk()..@)::bookmarks() | @, 2)"];
retrunk = ["rebase" "-d" "trunk()"];
};
revset-aliases = {

View File

@@ -5,7 +5,7 @@
}: {
programs.opencode = {
enable = true;
package = inputs.nix-ai-tools.packages.${pkgs.system}.opencode;
package = inputs.llm-agents.packages.${pkgs.stdenv.hostPlatform.system}.opencode;
settings = {
theme = "catppuccin";
instructions = [
@@ -20,4 +20,7 @@
};
};
};
home.sessionVariables = {
OPENCODE_EXPERIMENTAL_EXA = "true";
};
}

View File

@@ -33,6 +33,7 @@ with pkgs;
sd
sops
sqlite
tea
tokei
tree
tree-sitter

53
profiles/syncthing.nix Normal file
View File

@@ -0,0 +1,53 @@
{
user,
pkgs,
...
}: let
isDarwin = pkgs.stdenv.isDarwin;
homeDir =
if isDarwin
then "/Users/${user}"
else "/home/${user}";
group =
if isDarwin
then "staff"
else "users";
in {
services.syncthing = {
enable = true;
openDefaultPorts = !isDarwin;
dataDir = "${homeDir}/.local/share/syncthing";
configDir = "${homeDir}/.config/syncthing";
user = "${user}";
group = group;
guiAddress = "0.0.0.0:8384";
overrideFolders = true;
overrideDevices = true;
settings = {
devices = {
"tahani" = {
id = "6B7OZZF-TEAMUGO-FBOELXP-Z4OY7EU-5ZHLB5T-V6Z3UDB-Q2DYR43-QBYW6QM";
addresses = ["tcp://tahani:22000"];
};
"jason" = {
id = "42II2VO-QYPJG26-ZS3MB2I-AOPVZ67-JJNSE76-U54CO5Y-634A5OG-ECU4YQA";
addresses = ["tcp://jason:22000"];
};
"chidi" = {
id = "N7W6SUT-QO6J4BE-T3Y65SM-OFGYGNV-TGYBJPX-JVN4Z72-AENZ247-KWXOQA6";
addresses = ["tcp://chidi:22000"];
};
};
folders = {
"nixos-config" = {
path = "${homeDir}/nixos-config";
devices = ["tahani" "jason" "chidi"];
};
};
options.globalAnnounceEnabled = false;
};
};
}