Compare commits

..

13 Commits

Author SHA1 Message Date
Morten Olsen
3c2be26cac improved git flow 2026-01-02 10:25:53 +01:00
Morten Olsen
760f8584cf improved git flow 2025-12-29 21:37:09 +01:00
Morten Olsen
7eb837a068 improved git flow 2025-12-29 21:32:07 +01:00
Morten Olsen
225b91b5d6 improved git flow 2025-12-29 21:27:28 +01:00
Morten Olsen
47a3e90c6c improved git flow 2025-12-29 21:24:37 +01:00
Morten Olsen
7cb12c4582 updated aliases 2025-12-29 21:14:44 +01:00
Morten Olsen
7f087bc39e updated 2025-12-27 00:05:22 +01:00
Morten Olsen
e384cc4829 updates 2025-12-25 00:56:49 +01:00
Morten Olsen
addbe8f963 add kube seal 2025-12-18 09:38:12 +01:00
Morten Olsen
0cbe2bb231 add visual studio code 2025-12-16 23:40:57 +01:00
Morten Olsen
e3c5020937 add argocd 2025-12-16 23:07:53 +01:00
Morten Olsen
2c59d739d7 added zen browser 2025-12-16 23:07:53 +01:00
Morten Olsen
e6167c2f86 improved system setup 2025-12-16 23:07:52 +01:00
17 changed files with 668 additions and 466 deletions

44
flake.lock generated
View File

@@ -7,11 +7,11 @@
]
},
"locked": {
"lastModified": 1765682243,
"narHash": "sha256-yeCxFV/905Wr91yKt5zrVvK6O2CVXWRMSrxqlAZnLp0=",
"lastModified": 1766682973,
"narHash": "sha256-GKO35onS711ThCxwWcfuvbIBKXwriahGqs+WZuJ3v9E=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "58bf3ecb2d0bba7bdf363fc8a6c4d49b4d509d03",
"rev": "91cdb0e2d574c64fae80d221f4bf09d5592e9ec2",
"type": "github"
},
"original": {
@@ -27,11 +27,11 @@
]
},
"locked": {
"lastModified": 1765684049,
"narHash": "sha256-svCS2r984qEowMT0y3kCrsD/m0J6zaF5I/UusS7QaH0=",
"lastModified": 1766784396,
"narHash": "sha256-rIlgatT0JtwxsEpzq+UrrIJCRfVAXgbYPzose1DmAcM=",
"owner": "LnL7",
"repo": "nix-darwin",
"rev": "9b628e171bfaea1a3d1edf31eee46251e0fe4a33",
"rev": "f0c8e1f6feb562b5db09cee9fb566a2f989e6b55",
"type": "github"
},
"original": {
@@ -42,11 +42,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1765644376,
"narHash": "sha256-yqHBL2wYGwjGL2GUF2w3tofWl8qO9tZEuI4wSqbCrtE=",
"lastModified": 1766747458,
"narHash": "sha256-m63jjuo/ygo8ztkCziYh5OOIbTSXUDkKbqw3Vuqu4a4=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "23735a82a828372c4ef92c660864e82fbe2f5fbe",
"rev": "c633f572eded8c4f3c75b8010129854ed404a6ce",
"type": "github"
},
"original": {
@@ -60,7 +60,31 @@
"inputs": {
"home-manager": "home-manager",
"nix-darwin": "nix-darwin",
"nixpkgs": "nixpkgs"
"nixpkgs": "nixpkgs",
"zen-browser": "zen-browser"
}
},
"zen-browser": {
"inputs": {
"home-manager": [
"home-manager"
],
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1766697593,
"narHash": "sha256-mGZBEN67mxeOsBhplBRLm6L+y++8jU46EEUYgemG1aQ=",
"owner": "0xc000022070",
"repo": "zen-browser-flake",
"rev": "98d8f48ba80a4b6e3b56addad850d57132301075",
"type": "github"
},
"original": {
"owner": "0xc000022070",
"repo": "zen-browser-flake",
"type": "github"
}
}
},

185
flake.nix
View File

@@ -16,90 +16,115 @@
url = "github:LnL7/nix-darwin";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = {
self,
nixpkgs,
home-manager,
nix-darwin,
...
} @ inputs: let
# Default username - can be overridden per-host if needed
username = "alice";
# Common special args passed to all modules
specialArgs = {inherit inputs username;};
in {
# Darwin (macOS) system configurations
darwinConfigurations = {
# Personal machine configuration
"personal" = nix-darwin.lib.darwinSystem {
system = "aarch64-darwin";
inherit specialArgs;
modules = [
# Host-specific darwin configuration
./hosts/personal
# Home Manager as a darwin module
home-manager.darwinModules.home-manager
{
home-manager = {
useGlobalPkgs = true;
useUserPackages = true;
extraSpecialArgs = specialArgs;
users.${username} = {...}: {
imports = [
./home
./home/personal.nix
];
};
};
}
];
};
# Work machine configuration
"work" = nix-darwin.lib.darwinSystem {
system = "aarch64-darwin";
inherit specialArgs;
modules = [
# Host-specific darwin configuration
./hosts/work
# Home Manager as a darwin module
home-manager.darwinModules.home-manager
{
home-manager = {
useGlobalPkgs = true;
useUserPackages = true;
extraSpecialArgs = specialArgs;
users.${username} = {...}: {
imports = [
./home
./home/work.nix
];
};
};
}
];
zen-browser = {
url = "github:0xc000022070/zen-browser-flake";
inputs = {
# IMPORTANT: we're using "libgbm" and is only available in unstable so ensure
# to have it up-to-date or simply don't specify the nixpkgs input
nixpkgs.follows = "nixpkgs";
home-manager.follows = "home-manager";
};
};
};
# Development shell for working on this repository
devShells = let
systems = ["aarch64-darwin" "x86_64-darwin"];
forAllSystems = nixpkgs.lib.genAttrs systems;
outputs =
{
self,
nixpkgs,
home-manager,
nix-darwin,
...
}@inputs:
let
# Default username - can be overridden per-host if needed
username = "alice";
# Common special args passed to all modules
specialArgs = { inherit inputs username; };
in
forAllSystems (system: let
pkgs = nixpkgs.legacyPackages.${system};
in {
default = pkgs.mkShell {
packages = with pkgs; [
nixfmt-rfc-style
nil # Nix LSP
{
# Darwin (macOS) system configurations
darwinConfigurations = {
# Personal machine configuration
"personal" = nix-darwin.lib.darwinSystem {
system = "aarch64-darwin";
inherit specialArgs;
modules = [
# Host-specific darwin configuration
./hosts/personal
# Home Manager as a darwin module
home-manager.darwinModules.home-manager
{
home-manager = {
useGlobalPkgs = true;
useUserPackages = true;
extraSpecialArgs = specialArgs;
users.${username} =
{ ... }:
{
imports = [
./home
./home/personal.nix
];
};
};
}
];
};
});
};
}
# Work machine configuration
"work" = nix-darwin.lib.darwinSystem {
system = "aarch64-darwin";
inherit specialArgs;
modules = [
# Host-specific darwin configuration
./hosts/work
# Home Manager as a darwin module
home-manager.darwinModules.home-manager
{
home-manager = {
useGlobalPkgs = true;
useUserPackages = true;
extraSpecialArgs = specialArgs;
users.${username} =
{ ... }:
{
imports = [
./home
./home/work.nix
];
};
};
}
];
};
};
# Development shell for working on this repository
devShells =
let
systems = [
"aarch64-darwin"
"x86_64-darwin"
];
forAllSystems = nixpkgs.lib.genAttrs systems;
in
forAllSystems (
system:
let
pkgs = nixpkgs.legacyPackages.${system};
in
{
default = pkgs.mkShell {
packages = with pkgs; [
nixfmt-rfc-style
nil # Nix LSP
];
};
}
);
};
}

View File

@@ -7,10 +7,14 @@
pkgs,
lib,
username,
inputs,
...
}: {
}:
{
# Import shared modules
imports = [
inputs.zen-browser.homeModules.beta
# Shell configuration (zsh, starship, atuin, direnv, zoxide, fzf, pyenv)
../modules/home/shell.nix
@@ -29,7 +33,7 @@
home = {
# Home Manager needs a bit of information about you and the paths it should manage
username = username;
inherit username;
homeDirectory = "/Users/${username}";
# This value determines the Home Manager release that your configuration is
@@ -80,4 +84,4 @@
aerospace.enable = true;
# jellyfin-tui is configured per-profile in personal.nix
};
}
}

View File

@@ -7,7 +7,8 @@
pkgs,
lib,
...
}: {
}:
{
# Import personal-specific modules
imports = [
../modules/home/git.nix
@@ -70,6 +71,10 @@
username = "morten";
passwordFile = "/Users/alice/Library/Application Support/jellyfin-tui/pass";
};
zen-browser = {
enable = true;
};
};
# Personal-only packages

View File

@@ -7,7 +7,8 @@
pkgs,
lib,
...
}: {
}:
{
# Import work-specific modules
imports = [
../modules/home/git.nix

View File

@@ -8,140 +8,14 @@
lib,
username,
...
}: {
}:
{
# Import darwin modules
imports = [
../../modules/darwin/system.nix
../../modules/darwin/homebrew.nix
];
# Nix configuration
nix = {
settings = {
# Enable flakes and new nix command
experimental-features = ["nix-command" "flakes"];
# Avoid unwanted garbage collection when using nix-direnv
keep-outputs = true;
keep-derivations = true;
};
};
# Allow unfree packages
nixpkgs.config.allowUnfree = true;
system = {
primaryUser = username;
keyboard = {
enableKeyMapping = true;
remapCapsLockToControl = true;
};
startup.chime = false;
defaults = {
spaces.spans-displays = false;
loginwindow = {
GuestEnabled = false;
DisableConsoleAccess = true;
};
dock = {
autohide = true;
autohide-delay = 0.0;
autohide-time-modifier = 0.0;
orientation = "bottom";
dashboard-in-overlay = true;
largesize = 85;
tilesize = 50;
magnification = true;
launchanim = false;
mru-spaces = false;
show-recents = false;
show-process-indicators = false;
static-only = true;
};
finder = {
AppleShowAllExtensions = true;
AppleShowAllFiles = true;
CreateDesktop = false;
FXDefaultSearchScope = "SCcf"; # current folder
QuitMenuItem = true;
};
NSGlobalDomain = {
NSAutomaticSpellingCorrectionEnabled = false;
NSAutomaticCapitalizationEnabled = false;
NSAutomaticPeriodSubstitutionEnabled = false;
NSAutomaticDashSubstitutionEnabled = false;
NSAutomaticQuoteSubstitutionEnabled = false;
NSAutomaticWindowAnimationsEnabled = false;
NSDocumentSaveNewDocumentsToCloud = false;
ApplePressAndHoldEnabled = false;
KeyRepeat = 2;
InitialKeyRepeat = 10;
# Enable subpixel font rendering on non-Apple LCDs
# Reference: https://github.com/kevinSuttle/macOS-Defaults/issues/17#issuecomment-266633501
AppleFontSmoothing = 2;
# Finder: show all filename extensions
AppleShowAllExtensions = true;
};
CustomUserPreferences = {
LaunchServices = {
# Whether to enable quarantine for downloaded applications
LSQuarantine = false;
};
trackpad = {
Clicking = true;
TrackpadRightClick = true;
};
"com.apple.systempreferences" = {
# Disable Resume system-wide
NSQuitAlwaysKeepsWindows = false;
};
"com.apple.desktopservices" = {
# Avoid creating .DS_Store files on network or USB volumes
DSDontWriteNetworkStores = true;
DSDontWriteUSBStores = true;
};
"com.apple.screensaver" = {
# Require password immediately after sleep or screen saver begins
askForPassword = 1;
askForPasswordDelay = 0;
};
"com.apple.AdLib" = {
# Don't fucking track me...
allowApplePersonalizedAdvertising = false;
};
"com.apple.BluetoothAudioAgent" = {
# Increase sound quality for Bluetooth headphones/headsets
"Apple Bitpool Min (editable)" = -40;
};
"com.apple.dashboard" = {
# Disable Dashboard
mcx-disabled = true;
};
alf = {
# Enables Firewall
globalstate = 1;
# Enable logging of requests
loggingenabled = 1;
# Drops incoming requests via ICMP such as ping requests
stealthenabled = 1;
};
};
};
};
users.users.${username} = {
name = username;
home = "/Users/${username}";
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFaIAP/ZJ7+7jeR44e1yIJjfQAB6MN351LDKJAXVF62P"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILAzuPy7D/54GxMq9Zhz0CUjaDnEQ6RkQ/yqVYl7U55k"
];
};
# System-level programs
programs = {
# Enable zsh as it's the default macOS shell

View File

@@ -8,140 +8,14 @@
lib,
username,
...
}: {
}:
{
# Import darwin modules
imports = [
../../modules/darwin/system.nix
../../modules/darwin/homebrew.nix
];
# Nix configuration
nix = {
settings = {
# Enable flakes and new nix command
experimental-features = ["nix-command" "flakes"];
# Avoid unwanted garbage collection when using nix-direnv
keep-outputs = true;
keep-derivations = true;
};
};
# Allow unfree packages
nixpkgs.config.allowUnfree = true;
system = {
primaryUser = username;
keyboard = {
enableKeyMapping = true;
remapCapsLockToControl = true;
};
startup.chime = false;
defaults = {
spaces.spans-displays = false;
loginwindow = {
GuestEnabled = false;
DisableConsoleAccess = true;
};
dock = {
autohide = true;
autohide-delay = 0.0;
autohide-time-modifier = 0.0;
orientation = "bottom";
dashboard-in-overlay = true;
largesize = 85;
tilesize = 50;
magnification = true;
launchanim = false;
mru-spaces = false;
show-recents = false;
show-process-indicators = false;
static-only = true;
};
finder = {
AppleShowAllExtensions = true;
AppleShowAllFiles = true;
CreateDesktop = false;
FXDefaultSearchScope = "SCcf"; # current folder
QuitMenuItem = true;
};
NSGlobalDomain = {
NSAutomaticSpellingCorrectionEnabled = false;
NSAutomaticCapitalizationEnabled = false;
NSAutomaticPeriodSubstitutionEnabled = false;
NSAutomaticDashSubstitutionEnabled = false;
NSAutomaticQuoteSubstitutionEnabled = false;
NSAutomaticWindowAnimationsEnabled = false;
NSDocumentSaveNewDocumentsToCloud = false;
ApplePressAndHoldEnabled = false;
KeyRepeat = 2;
InitialKeyRepeat = 10;
# Enable subpixel font rendering on non-Apple LCDs
# Reference: https://github.com/kevinSuttle/macOS-Defaults/issues/17#issuecomment-266633501
AppleFontSmoothing = 2;
# Finder: show all filename extensions
AppleShowAllExtensions = true;
};
CustomUserPreferences = {
LaunchServices = {
# Whether to enable quarantine for downloaded applications
LSQuarantine = false;
};
trackpad = {
Clicking = true;
TrackpadRightClick = true;
};
"com.apple.systempreferences" = {
# Disable Resume system-wide
NSQuitAlwaysKeepsWindows = false;
};
"com.apple.desktopservices" = {
# Avoid creating .DS_Store files on network or USB volumes
DSDontWriteNetworkStores = true;
DSDontWriteUSBStores = true;
};
"com.apple.screensaver" = {
# Require password immediately after sleep or screen saver begins
askForPassword = 1;
askForPasswordDelay = 0;
};
"com.apple.AdLib" = {
# Don't fucking track me...
allowApplePersonalizedAdvertising = false;
};
"com.apple.BluetoothAudioAgent" = {
# Increase sound quality for Bluetooth headphones/headsets
"Apple Bitpool Min (editable)" = -40;
};
"com.apple.dashboard" = {
# Disable Dashboard
mcx-disabled = true;
};
alf = {
# Enables Firewall
globalstate = 1;
# Enable logging of requests
loggingenabled = 1;
# Drops incoming requests via ICMP such as ping requests
stealthenabled = 1;
};
};
};
};
users.users.${username} = {
name = username;
home = "/Users/${username}";
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFaIAP/ZJ7+7jeR44e1yIJjfQAB6MN351LDKJAXVF62P"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILAzuPy7D/54GxMq9Zhz0CUjaDnEQ6RkQ/yqVYl7U55k"
];
};
# System-level programs
programs = {
# Enable zsh as it's the default macOS shell

2
mise.toml Normal file
View File

@@ -0,0 +1,2 @@
[tools]
rust = "latest"

View File

@@ -9,9 +9,11 @@
pkgs,
...
}:
with lib; let
with lib;
let
cfg = config.modules.homebrew;
in {
in
{
options.modules.homebrew = {
enable = mkEnableOption "Homebrew management via nix-darwin";
@@ -23,13 +25,16 @@ in {
# Password management
"1password"
"1password-cli"
"bitwarden"
# Terminal & Development
"ghostty"
"dbeaver-community"
"visual-studio-code"
# Window management
"aerospace"
"claude-code"
# Productivity
"raycast"
@@ -42,6 +47,8 @@ in {
# Networking & IoT
"localsend"
"home-assistant"
"cursor-cli"
];
description = "Homebrew casks to install on all machines";
};
@@ -123,7 +130,11 @@ in {
# Cleanup behavior
cleanup = mkOption {
type = types.enum ["none" "uninstall" "zap"];
type = types.enum [
"none"
"uninstall"
"zap"
];
default = "zap";
description = ''
Cleanup behavior for Homebrew packages:
@@ -146,7 +157,7 @@ in {
# Upgrade outdated packages
upgrade = true;
# Cleanup behavior for unmanaged packages
cleanup = cfg.cleanup;
inherit (cfg) cleanup;
};
# Global settings
@@ -158,26 +169,18 @@ in {
};
# Taps (third-party repositories)
taps = cfg.taps;
inherit (cfg) taps;
# Formulae (CLI tools from Homebrew)
brews = cfg.brews;
inherit (cfg) brews;
caskArgs.no_quarantine = true;
# Casks (GUI applications)
casks =
cfg.casks.shared
++ (
if cfg.casks.enablePersonal
then cfg.casks.personal
else []
)
++ (
if cfg.casks.enableWork
then cfg.casks.work
else []
);
++ (if cfg.casks.enablePersonal then cfg.casks.personal else [ ])
++ (if cfg.casks.enableWork then cfg.casks.work else [ ]);
};
};
}

143
modules/darwin/system.nix Normal file
View File

@@ -0,0 +1,143 @@
# It sets up system-level configuration and integrates with home-manager.
{
config,
pkgs,
lib,
username,
...
}:
{
# Nix configuration
nix = {
settings = {
# Enable flakes and new nix command
experimental-features = [
"nix-command"
"flakes"
];
# Avoid unwanted garbage collection when using nix-direnv
keep-outputs = true;
keep-derivations = true;
};
};
# Allow unfree packages
nixpkgs.config.allowUnfree = true;
system = {
primaryUser = username;
keyboard = {
enableKeyMapping = true;
remapCapsLockToControl = true;
};
startup.chime = false;
defaults = {
spaces.spans-displays = false;
loginwindow = {
GuestEnabled = false;
DisableConsoleAccess = true;
};
dock = {
autohide = true;
autohide-delay = 0.0;
autohide-time-modifier = 0.0;
orientation = "bottom";
dashboard-in-overlay = true;
largesize = 85;
tilesize = 50;
magnification = true;
launchanim = false;
mru-spaces = false;
show-recents = false;
show-process-indicators = false;
static-only = true;
};
finder = {
AppleShowAllExtensions = true;
AppleShowAllFiles = true;
CreateDesktop = false;
FXDefaultSearchScope = "SCcf"; # current folder
QuitMenuItem = true;
};
NSGlobalDomain = {
NSAutomaticSpellingCorrectionEnabled = false;
NSAutomaticCapitalizationEnabled = false;
NSAutomaticPeriodSubstitutionEnabled = false;
NSAutomaticDashSubstitutionEnabled = false;
NSAutomaticQuoteSubstitutionEnabled = false;
NSAutomaticWindowAnimationsEnabled = false;
NSDocumentSaveNewDocumentsToCloud = false;
ApplePressAndHoldEnabled = false;
KeyRepeat = 2;
InitialKeyRepeat = 10;
# Enable subpixel font rendering on non-Apple LCDs
# Reference: https://github.com/kevinSuttle/macOS-Defaults/issues/17#issuecomment-266633501
AppleFontSmoothing = 2;
# Finder: show all filename extensions
AppleShowAllExtensions = true;
};
CustomUserPreferences = {
LaunchServices = {
# Whether to enable quarantine for downloaded applications
LSQuarantine = false;
};
trackpad = {
Clicking = true;
TrackpadRightClick = true;
};
"com.apple.systempreferences" = {
# Disable Resume system-wide
NSQuitAlwaysKeepsWindows = false;
};
"com.apple.desktopservices" = {
# Avoid creating .DS_Store files on network or USB volumes
DSDontWriteNetworkStores = true;
DSDontWriteUSBStores = true;
};
"com.apple.screensaver" = {
# Require password immediately after sleep or screen saver begins
askForPassword = 1;
askForPasswordDelay = 0;
};
"com.apple.AdLib" = {
# Don't fucking track me...
allowApplePersonalizedAdvertising = false;
};
"com.apple.BluetoothAudioAgent" = {
# Increase sound quality for Bluetooth headphones/headsets
"Apple Bitpool Min (editable)" = -40;
};
"com.apple.dashboard" = {
# Disable Dashboard
mcx-disabled = true;
};
alf = {
# Enables Firewall
globalstate = 1;
# Enable logging of requests
loggingenabled = 1;
# Drops incoming requests via ICMP such as ping requests
stealthenabled = 1;
};
};
};
};
users.users.${username} = {
name = username;
home = "/Users/${username}";
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFaIAP/ZJ7+7jeR44e1yIJjfQAB6MN351LDKJAXVF62P"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILAzuPy7D/54GxMq9Zhz0CUjaDnEQ6RkQ/yqVYl7U55k"
];
};
# Used for backwards compatibility, read the changelog before changing.
# $ darwin-rebuild changelog
system.stateVersion = 5;
}

View File

@@ -7,9 +7,11 @@
pkgs,
lib,
...
}: let
}:
let
cfg = config.modules.apps;
in {
in
{
options.modules.apps = {
enable = lib.mkEnableOption "application configurations";
@@ -21,6 +23,14 @@ in {
};
};
zen-browser = {
enable = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Enable Zen Browser configuration (macOS only)";
};
};
jellyfin-tui = {
enable = lib.mkOption {
type = lib.types.bool;
@@ -55,6 +65,46 @@ in {
};
config = lib.mkIf cfg.enable {
programs.zen-browser = lib.mkIf cfg.zen-browser.enable {
enable = true;
policies =
let
mkExtensionSettings = builtins.mapAttrs (
_: pluginId: {
install_url = "https://addons.mozilla.org/firefox/downloads/latest/${pluginId}/latest.xpi";
installation_mode = "force_installed";
}
);
in
{
AutofillAddressEnabled = true;
AutofillCreditCardEnabled = false;
DisableAppUpdate = true;
DisableFeedbackCommands = true;
DisableFirefoxStudies = true;
DisablePocket = true;
DisableTelemetry = true;
DontCheckDefaultBrowser = true;
NoDefaultBookmarks = true;
OfferToSaveLogins = false;
EnableTrackingProtection = {
Value = true;
Locked = true;
Cryptomining = true;
Fingerprinting = true;
};
ExtensionSettings = mkExtensionSettings {
#"78272b6fa58f4a1abaac99321d503a20@proton.me" = "proton-pass";
"{446900e4-71c2-419f-a6a7-df9c091e268b}" = "bitwarden-password-manager";
"{d7742d87-e61d-4b78-b8a1-b469842139fa}" = "vimium-ff";
"readeck@readeck.com" = "readeck";
"@testpilot-containers" = "multi-account-containers";
"uBlock0@raymondhill.net" = "ublock-origin";
};
};
};
# Aerospace window manager configuration (macOS)
# Placed at ~/.aerospace.toml
home.file = lib.mkMerge [

View File

@@ -13,34 +13,42 @@
lib,
...
}:
with lib; let
with lib;
let
cfg = config.modules.gitFiles;
# Helper function to generate gitconfig content
mkGitConfig = {
email,
signingKey,
urlRewrites ? {},
}: ''
[user]
email = ${email}
name = Morten Olsen
signingkey = ${signingKey}
mkGitConfig =
{
email,
signingKey,
urlRewrites ? { },
}:
''
[user]
email = ${email}
name = Morten Olsen
signingkey = ${signingKey}
[commit]
gpgsign = true
[commit]
gpgsign = true
[gpg]
format = ssh
[gpg]
format = ssh
[gpg "ssh"]
program = "/Applications/1Password.app/Contents/MacOS/op-ssh-sign"
${optionalString (urlRewrites != {}) (concatStringsSep "\n" (mapAttrsToList (name: value: ''
[gpg "ssh"]
program = "/Applications/1Password.app/Contents/MacOS/op-ssh-sign"
${optionalString (urlRewrites != { }) (
concatStringsSep "\n" (
mapAttrsToList (name: value: ''
[url "${name}"]
insteadOf = ${value}'') urlRewrites))}
'';
in {
[url "${name}"]
insteadOf = ${value}'') urlRewrites
)
)}
'';
in
{
options.modules.gitFiles = {
enable = mkEnableOption "Project-specific git configuration files";
@@ -102,8 +110,8 @@ in {
# Used on personal machine for all projects under ~/Projects/
(mkIf cfg.personal.enable {
"Projects/.gitconfig".text = mkGitConfig {
email = cfg.personal.email;
signingKey = cfg.personal.signingKey;
inherit (cfg.personal) email;
inherit (cfg.personal) signingKey;
urlRewrites = {
"ssh://git@ssh-gitea.olsen.cloud:2205/" = "https://gitea.olsen.cloud/";
"git@github-private:" = "https://github.com/";
@@ -115,8 +123,8 @@ in {
# Used on work machine for personal projects under ~/Projects/private/
(mkIf cfg.private.enable {
"Projects/private/.gitconfig".text = mkGitConfig {
email = cfg.private.email;
signingKey = cfg.private.signingKey;
inherit (cfg.private) email;
inherit (cfg.private) signingKey;
urlRewrites = {
"ssh://git@ssh-gitea.olsen.cloud:2205/" = "https://gitea.olsen.cloud/";
"git@github-private:" = "https://github.com/";
@@ -128,8 +136,8 @@ in {
# Used on work machine for work projects under ~/Projects/zeronorth/
(mkIf cfg.zeronorth.enable {
"Projects/zeronorth/.gitconfig".text = mkGitConfig {
email = cfg.zeronorth.email;
signingKey = cfg.zeronorth.signingKey;
inherit (cfg.zeronorth) email;
inherit (cfg.zeronorth) signingKey;
urlRewrites = {
"git@github-zeronorth:" = "https://github.com/";
};

View File

@@ -11,9 +11,11 @@
lib,
...
}:
with lib; let
with lib;
let
cfg = config.modules.git;
in {
in
{
options.modules.git = {
enable = mkEnableOption "Git configuration";
@@ -36,21 +38,23 @@ in {
};
includes = mkOption {
type = types.listOf (types.submodule {
options = {
condition = mkOption {
type = types.str;
description = "The includeIf condition (e.g., gitdir:~/Projects/)";
example = "gitdir:~/Projects/";
type = types.listOf (
types.submodule {
options = {
condition = mkOption {
type = types.str;
description = "The includeIf condition (e.g., gitdir:~/Projects/)";
example = "gitdir:~/Projects/";
};
path = mkOption {
type = types.str;
description = "Path to the included gitconfig file";
example = "~/Projects/.gitconfig";
};
};
path = mkOption {
type = types.str;
description = "Path to the included gitconfig file";
example = "~/Projects/.gitconfig";
};
};
});
default = [];
}
);
default = [ ];
description = "List of conditional includes for project-specific git configurations";
};
};
@@ -80,18 +84,26 @@ in {
programs.git = {
enable = true;
# User configuration
userName = cfg.userName;
userEmail = cfg.userEmail;
# Signing configuration with 1Password
signing = {
key = cfg.signingKey;
signByDefault = true;
};
# Extra configuration
extraConfig = {
# Conditional includes for project-specific configurations
includes = map (inc: {
inherit (inc) condition;
inherit (inc) path;
}) cfg.includes;
# All git settings using the new unified settings option
settings = {
# User configuration
user = {
name = cfg.userName;
email = cfg.userEmail;
};
# Core settings (pager is set by programs.delta)
core = {
hooksPath = "/dev/null";
@@ -113,6 +125,57 @@ in {
autoSetupRemote = true;
};
# Rebase settings
rebase = {
autoStash = true;
updateRefs = true;
};
# Rerere (Reuse Recorded Resolution) - automatically reuse conflict resolutions
rerere = {
enabled = true;
};
# Color settings
color = {
ui = "auto";
branch = "auto";
diff = "auto";
status = "auto";
};
# Diff settings
diff = {
compactionHeuristic = true;
algorithm = "patience";
colorMoved = "default";
};
# Merge settings
merge = {
conflictStyle = "zdiff3";
};
# Fetch settings
fetch = {
prune = true;
showForcedUpdates = true;
};
# Advice settings (disable annoying messages)
advice = {
detachedHead = false;
statusHints = true;
addIgnoredFile = false;
};
# Blame settings
blame = {
colorLines = true;
markUnblamables = true;
markUnblamableLines = true;
};
# GPG/SSH signing settings
gpg = {
format = "ssh";
@@ -144,29 +207,117 @@ in {
"difftool \"nvimdiff\"" = {
cmd = "nvim -d \"$LOCAL\" \"$REMOTE\"";
};
};
# Aliases
aliases = {
graph = "log --graph --color --pretty=format:\"%C(yellow)%H%C(green)%d%C(reset)%n%x20%cd%n%x20%cn%C(blue)%x20(%ce)%x20%C(cyan)[gpg:%GK%x20%G?]%C(reset)%n%x20%s%n\"";
ll = "log --oneline";
st = "status -sb";
cm = "commit -m";
append = "commit --amend --no-edit";
sobmodules = "submodule update --init --recursive";
df = "difftool -t nvimdiff -y";
last = "log -1 --stat";
br = "branch --format='%(HEAD) %(color:yellow)%(refname:short)%(color:reset) - %(contents:subject) %(color:green)(%(committerdate:relative)) [%(authorname)]' --sort=-committerdate";
brr = "branch --remote --format='%(HEAD) %(color:yellow)%(refname:short)%(color:reset) - %(contents:subject) %(color:green)(%(committerdate:relative)) [%(authorname)]' --sort=-committerdate";
undo = "reset HEAD~1 --mixed";
unstage = "reset HEAD --";
};
# Aliases
alias = {
# Conditional includes for project-specific configurations
includes = map (inc: {
condition = inc.condition;
path = inc.path;
}) cfg.includes;
# Log and history aliases
# =====
# Pretty graph log with GPG info
history = "log --graph --color --pretty=format:\"%C(yellow)%H%C(green)%d%C(reset)%n%x20%cd%n%x20%cn%C(blue)%x20(%ce)%x20%C(cyan)[gpg:%GK%x20%G?]%C(reset)%n%x20%s%n\"";
graph = "log --graph --color --pretty=format:\"%C(yellow)%H%C(green)%d%C(reset)%n%x20%cd%n%x20%cn%C(blue)%x20(%ce)%x20%C(cyan)[gpg:%GK%x20%G?]%C(reset)%n%x20%s%n\"";
# One-line log
ll = "log --oneline";
# Last commit with stats
last = "log -1 --stat";
# Status and branch aliases
# =====
# Short branch status
st = "status -sb";
# Formatted local branches
local-branches = "branch --format='%(HEAD) %(color:yellow)%(refname:short)%(color:reset) - %(contents:subject) %(color:green)(%(committerdate:relative)) [%(authorname)]' --sort=-committerdate";
# Formatted remote branches
remote-branches = "branch --remote --format='%(HEAD) %(color:yellow)%(refname:short)%(color:reset) - %(contents:subject) %(color:green)(%(committerdate:relative)) [%(authorname)]' --sort=-committerdate";
# Create and switch to new branch
new-branch = "!f() { git checkout -b \"$1\"; }; f";
# Switch branch (interactive with fzf)
switch-branch = "!f() { branch=$(git branch --format='%(refname:short)' | fzf --height 40%); [ -n \"$branch\" ] && git checkout \"$branch\"; }; f";
# Delete branch (with confirmation)
delete-branch = "!f() { git branch -d \"$1\" 2>/dev/null || git branch -D \"$1\"; }; f";
# Commit aliases
# =====
# Commit with message
cm = "commit -m";
# Amend last commit without editing message
amend = "commit --amend --no-edit";
append = "commit --amend --no-edit";
# Stage all and amend to last commit
fix = "!git add . && git commit --amend --no-edit";
# Stage all, amend, and safely force push with lease and force-if-includes
fck = "!f() { git add . && git commit --amend --no-edit && git push --force-with-lease --force-if-includes; }; f";
# Stage all, commit with message, and push
save = "!f() { git add --all && git commit -m \"$*\" && git push; }; f";
# Fixup workflow aliases
# =====
# Interactive fixup: pick commit with fzf, stage all, create fixup
fix-commit = "!f() { commit=$(git log --oneline --color=always | fzf --ansi --height 40% | awk '{print $1}'); [ -n \"$commit\" ] && git add . && git commit --fixup=\"$commit\"; }; f";
apply-fixes = "!f() { upstream=$(git rev-parse --abbrev-ref --symbolic-full-name @{upstream} 2>/dev/null); if [ -n \"$upstream\" ]; then git rebase -i --autosquash \"$upstream\"; elif git show-ref --verify --quiet refs/remotes/origin/main; then git rebase -i --autosquash origin/main; elif git show-ref --verify --quiet refs/remotes/origin/master; then git rebase -i --autosquash origin/master; elif git show-ref --verify --quiet refs/heads/main; then git rebase -i --autosquash main; elif git show-ref --verify --quiet refs/heads/master; then git rebase -i --autosquash master; else first_commit=$(git rev-list --reverse HEAD | head -1); if [ -n \"$first_commit\" ]; then base=$(git rev-parse \"$first_commit^\" 2>/dev/null); if [ -n \"$base\" ] && [ \"$base\" != \"$first_commit\" ]; then git rebase -i --autosquash \"$base\"; else echo \"Could not determine base. Usage: git apply-fixes <base-branch>\"; fi; else echo \"No base branch found. Usage: git apply-fixes <base-branch>\"; fi; fi; }; f";
# Squash all commits unique to current branch (auto-detects default branch)
cleanup = "!f() { default=$(git remote show origin 2>/dev/null | sed -n '/HEAD branch/s/.*: //p' || echo \"main\"); if ! git show-ref --verify --quiet \"refs/remotes/origin/$default\"; then default=\"master\"; fi; if git show-ref --verify --quiet \"refs/remotes/origin/$default\"; then base=$(git merge-base HEAD \"origin/$default\"); git rebase -i \"$base\"; else echo \"Could not find default branch (main/master). Usage: git squash-all <base-branch>\"; fi; }; f";
squash-all = "!f() { default=$(git remote show origin 2>/dev/null | sed -n '/HEAD branch/s/.*: //p' || echo \"main\"); if ! git show-ref --verify --quiet \"refs/remotes/origin/$default\"; then default=\"master\"; fi; if git show-ref --verify --quiet \"refs/remotes/origin/$default\"; then base=$(git merge-base HEAD \"origin/$default\"); git rebase -i \"$base\"; else echo \"Could not find default branch (main/master). Usage: git squash-all <base-branch>\"; fi; }; f";
# Staging aliases
# =====
# Stage all files
stage-all = "add --all";
# Unstage all staged files
unstage = "reset HEAD --";
# Interactive staging with fzf
stage = "!f() { git status -s | fzf --multi --ansi --height 40% | awk '{print $2}' | xargs git add; }; f";
# Undo and reset aliases
# =====
# Interactive undo: pick state from reflog, show diff, confirm before hard reset
undo = "!f() { target=$(git reflog --color=always --date=relative --format=\"%C(yellow)%h%C(reset) %C(cyan)%gd%C(reset) %C(green)%gs%C(reset)\" | fzf --ansi --height 40% --header=\"Select a state to reset to\" | awk '{print $1}'); if [ -n \"$target\" ]; then echo \"\n=== Diff between HEAD and selected state ===\n\"; git diff --color=always HEAD \"$target\"; echo \"\n=== This will discard all changes above ===\n\"; read -p \"Reset to $target? (y/N): \" confirm; if [ \"$confirm\" = \"y\" ] || [ \"$confirm\" = \"Y\" ]; then git reset --hard \"$target\"; else echo \"Reset cancelled.\"; fi; fi; }; f";
# Remote operations aliases
# =====
# Fetch from all remotes
fetch-all = "fetch --all";
# Pull latest changes
pull-latest = "!f() { default=$(git remote show origin 2>/dev/null | sed -n '/HEAD branch/s/.*: //p' || echo \"main\"); if ! git show-ref --verify --quiet \"refs/remotes/origin/$default\"; then default=\"master\"; fi; git pull origin \"$default\"; }; f";
# Push and set upstream
push-new = "!f() { git push -u origin $(git rev-parse --abbrev-ref HEAD); }; f";
# Update from main/master (rebase)
update-from-main = "!f() { default=$(git remote show origin 2>/dev/null | sed -n '/HEAD branch/s/.*: //p' || echo \"main\"); if ! git show-ref --verify --quiet \"refs/remotes/origin/$default\"; then default=\"master\"; fi; git fetch origin && git rebase \"origin/$default\"; }; f";
# Stash aliases
# =====
# Save current changes to stash
stash-save = "stash push -m";
# Apply and remove stash (interactive with fzf)
stash-pop = "!f() { stash=$(git stash list --color=always | fzf --ansi --height 40% | awk -F: '{print $1}'); [ -n \"$stash\" ] && git stash pop \"$stash\"; }; f";
# List stashes
stash-list = "stash list";
# Workflow aliases
# =====
# Create new feature branch from main/master
new-feature = "!f() { default=$(git remote show origin 2>/dev/null | sed -n '/HEAD branch/s/.*: //p' || echo \"main\"); if ! git show-ref --verify --quiet \"refs/remotes/origin/$default\"; then default=\"master\"; fi; git fetch origin && git checkout -b \"$1\" \"origin/$default\"; }; f";
# Compare current branch with another branch
compare = "!f() { git diff \"$1\"..HEAD; }; f";
# Other aliases
# =====
# Initialize and update submodules
sobmodules = "submodule update --init --recursive";
# Diff tool using nvimdiff
df = "difftool -t nvimdiff -y";
};
};
};
};
}
}

View File

@@ -9,7 +9,8 @@
pkgs,
lib,
...
}: {
}:
{
home.packages = with pkgs; [
# ========================================================================
# Shell Tools
@@ -27,9 +28,10 @@
ripgrep # Modern grep (aliased as grep)
delta # Modern diff with syntax highlighting (aliased as diff)
dust # A more intuitive version of du written in rust
duf # A better df alternative
duf # A better df alternative
hyperfine # A command-line benchmarking tool.
choose # A human-friendly and fast alternative to cut and (sometimes) awk
coreutils
yazi # File manager
# ========================================================================
@@ -87,6 +89,11 @@
k9s # Kubernetes TUI
istioctl # Istio service mesh CLI
fluxcd # GitOps toolkit
popeye
argocd
kubeseal
kubebuilder
kind
# ========================================================================
# Infrastructure and Cloud Tools
@@ -108,6 +115,7 @@
age # Modern encryption tool
sops # Secrets management
rustscan # The Modern Port Scanner. Find ports quickly (3 seconds at its fastest). nmap alternative.
bitwarden-cli
# ========================================================================
# Miscellaneous Tools
@@ -123,12 +131,19 @@
mob
zsh-fast-syntax-highlighting
jellyfin-tui
mpv
# ========================================================================
# Nix Tools
# ========================================================================
nixfmt-rfc-style # Nix code formatter
nil # Nix language server
# ========================================================================
# AAI tools
# ========================================================================
gemini-cli
opencode
];
# ========================================================================
@@ -178,4 +193,30 @@
programs.lazygit = {
enable = true;
};
programs.k9s = {
enable = true;
plugins = {
"edit-secret" = {
shortCut = "Ctrl-X";
confirm = false;
description = "Edit Decoded Secret";
scopes = [ "secrets" ];
command = "sh";
background = false;
args = [
"-c"
''
tempfile=$(mktemp);
secret=$(kubectl get secrets --context $CONTEXT --namespace $NAMESPACE $NAME -o json);
printf '%s\n' $secret | jq '.data | map_values(@base64d)' > $tempfile;
vim $tempfile;
secret_data=$(cat $tempfile | jq -c '. | map_values(@base64)');
rm $tempfile;
printf '%s\n' $secret | jq -r --argjson secret_data "$secret_data" '.data = $secret_data' | kubectl apply -f -;
''
];
};
};
};
}

View File

@@ -13,7 +13,8 @@
pkgs,
lib,
...
}: {
}:
{
# ==========================================================================
# Zsh Configuration
# ==========================================================================
@@ -69,9 +70,6 @@
"--color=fg:#cdd6f4,header:#f38ba8,info:#cba6f7,pointer:#f5e0dc"
"--color=marker:#f5e0dc,fg+:#cdd6f4,prompt:#cba6f7,hl+:#f38ba8"
];
# NVM directory
NVM_DIR = "$HOME/.nvm";
};
# Shell aliases (migrated from 01-env.sh and 01-nvim.sh)
@@ -237,12 +235,6 @@
enableZshIntegration = true;
};
# ==========================================================================
# NVM - Node Version Manager
# ==========================================================================
# NVM is installed via Homebrew and sourced in the shell
# This allows managing multiple Node.js versions per project
# ==========================================================================
# Pyenv - Python version management
# ==========================================================================
@@ -288,7 +280,7 @@
enable = true;
# The config.nu can be anywhere you want if you like to edit your Nushell with Nu
# configFile.source = ./.../config.nu;
# for editing directly to config.nu
# for editing directly to config.nu
extraConfig = ''
let carapace_completer = {|spans|
carapace $spans.0 nushell ...$spans | from json
@@ -313,13 +305,13 @@
split row (char esep) |
append /usr/bin/env
)
'';
'';
shellAliases = {
vi = "hx";
vim = "hx";
nano = "hx";
};
};
};
programs.carapace = {
enable = true;
enableNushellIntegration = true;

View File

@@ -8,9 +8,11 @@
lib,
...
}:
with lib; let
with lib;
let
cfg = config.modules.ssh;
in {
in
{
options.modules.ssh = {
enable = mkEnableOption "SSH configuration";
@@ -65,7 +67,7 @@ in {
enableDefaultConfig = false;
# Include colima SSH config for container access
includes = ["~/.colima/ssh_config"];
includes = [ "~/.colima/ssh_config" ];
# 1Password SSH agent integration (macOS)
extraConfig = ''
@@ -119,7 +121,7 @@ in {
identityFile = cfg.githubZeronorthKeyPath;
identitiesOnly = true;
};
# Docker server
"docker.host" = {
hostname = "docker.olsen.cloud";
@@ -128,7 +130,7 @@ in {
identityFile = cfg.githubPrivateKeyPath;
identitiesOnly = true;
};
# NAS server
"nas.host" = {
hostname = "192.168.20.106";
@@ -137,7 +139,7 @@ in {
identityFile = cfg.githubPrivateKeyPath;
identitiesOnly = true;
};
# Private MacBook
"macbook.host" = {
hostname = "192.168.3.9";
@@ -146,7 +148,7 @@ in {
identityFile = cfg.githubPrivateKeyPath;
identitiesOnly = true;
};
# ZN MacBook
"zn.host" = {
hostname = "192.168.3.3";

View File

@@ -7,7 +7,8 @@
pkgs,
lib,
...
}: {
}:
{
programs.tmux = {
enable = true;
@@ -116,6 +117,8 @@
# Utils - lazygit popup
bind -r g display-popup -d '#{pane_current_path}' -w80% -h80% -E lazygit
bind -r o display-popup -d '#{pane_current_path}' -w80% -h80% -E yazi
bind -r p display-popup -d '#{pane_current_path}' -w80% -h80% -E $SHELL
'';
};
}
}