dendritic migration
dendritic migration
This commit is contained in:
10
.sisyphus/boulder.json
Normal file
10
.sisyphus/boulder.json
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"active_plan": "/home/cschmatzler/nixos-config/.sisyphus/plans/dendritic-migration.md",
|
||||||
|
"started_at": "2026-03-05T10:57:53.044Z",
|
||||||
|
"session_ids": [
|
||||||
|
"ses_34287fe8effeSATHvHUmGqZ5Fp"
|
||||||
|
],
|
||||||
|
"plan_name": "dendritic-migration",
|
||||||
|
"agent": "atlas",
|
||||||
|
"worktree_path": "/home/cschmatzler/nixos-config"
|
||||||
|
}
|
||||||
2
.sisyphus/notepads/dendritic-migration/decisions.md
Normal file
2
.sisyphus/notepads/dendritic-migration/decisions.md
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
- Do not include user aspects (e.g. `den.aspects.cschmatzler`) in host aspect `includes`. Den HM integration already applies the user aspect for each `den.hosts.<system>.<host>.users.<user>` via `den.ctx.user`; duplicating it via host `includes` leads to duplicated HM option merges (notably `types.lines` options like `programs.nushell.extraConfig`).
|
||||||
3
.sisyphus/notepads/dendritic-migration/issues.md
Normal file
3
.sisyphus/notepads/dendritic-migration/issues.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
|
||||||
|
- Nushell `programs.nushell.extraConfig` duplication traced to Den applying the user aspect twice: it is included via host aspect `includes` (e.g. `den.aspects.tahani.includes = [ ... den.aspects.cschmatzler ... ]`) AND Den's HM integration already includes the user aspect via `den.ctx.user` (see Den `hm-integration.nix`). Result: user-aspect-provided HM config (like `den.aspects.shell.homeManager`) merges twice, so `extraConfig` contains two identical copies.
|
||||||
|
- `dev-tools` nushell functions (e.g. `ggpull`) missing in `michael` is expected: `modules/michael.nix` does not include `den.aspects.dev-tools`.
|
||||||
128
.sisyphus/notepads/dendritic-migration/learnings.md
Normal file
128
.sisyphus/notepads/dendritic-migration/learnings.md
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
- For den migration, move legacy non-flake-parts modules into `modules/_legacy/` before enabling `inputs.import-tree ./modules`; import-tree ignores underscore-prefixed paths.
|
||||||
|
- `flake-parts` must include `inputs.nixpkgs-lib.follows = "nixpkgs"` in this repository to match den bootstrap expectations.
|
||||||
|
- The den bootstrap works with `modules/dendritic.nix` importing `(inputs.flake-file.flakeModules.dendritic or { })` and `(inputs.den.flakeModules.dendritic or { })`, plus initial `flake-file.inputs` declarations.
|
||||||
|
- Den host wiring uses `den.hosts.<system>.<hostname>.users.<username> = {}` declarations in `modules/hosts.nix` for each host-user pair.
|
||||||
|
- `den.default.includes` accepts batteries directly via `den.provides.*`; this bootstrap uses `den.provides.define-user` and `den.provides.inputs'`.
|
||||||
|
- In this flake-parts setup, declaring `options.flake.darwinConfigurations` as `lib.types.lazyAttrsOf lib.types.raw` allows multiple Darwin hosts to merge correctly.
|
||||||
|
|
||||||
|
## Task 3: Utility functions under _lib/ - COMPLETED
|
||||||
|
|
||||||
|
**What was done:**
|
||||||
|
- Created `modules/_lib/` directory
|
||||||
|
- Copied 5 pure function files (not NixOS modules):
|
||||||
|
- `lib/constants.nix` → `modules/_lib/constants.nix` (14 lines)
|
||||||
|
- `lib/build-rust-package.nix` → `modules/_lib/build-rust-package.nix` (20 lines)
|
||||||
|
- `profiles/wallpaper.nix` → `modules/_lib/wallpaper.nix` (11 lines)
|
||||||
|
- `profiles/open-project.nix` → `modules/_lib/open-project.nix` (10 lines)
|
||||||
|
- `profiles/packages.nix` → `modules/_lib/packages.nix` (67 lines)
|
||||||
|
|
||||||
|
**Key insight:**
|
||||||
|
- import-tree ignores paths with `/_` prefix, so `modules/_lib/` is safe for pure functions
|
||||||
|
- These files are NOT NixOS/home-manager modules - they're utility functions that would crash import-tree if placed directly under `modules/`
|
||||||
|
- Files were COPIED (not moved) because old locations are still referenced by existing host configs until Task 26
|
||||||
|
|
||||||
|
**Verification:**
|
||||||
|
- All 5 files copied with identical content (byte-for-byte match)
|
||||||
|
- `alejandra --check modules/_lib/` passed (formatting compliant)
|
||||||
|
- `nix flake show` exits 0 (import-tree correctly ignores `_lib/`)
|
||||||
|
|
||||||
|
**Dependencies:**
|
||||||
|
- Unblocks Task 4 (overlays need `build-rust-package.nix` from `_lib/`)
|
||||||
|
|
||||||
|
## Task 2: Hosts and defaults bootstrap notes
|
||||||
|
|
||||||
|
- Den host wiring uses `den.hosts.<system>.<hostname>.users.<username> = {}` declarations in `modules/hosts.nix` for each host-user pair.
|
||||||
|
- `den.default.includes` accepts batteries directly via `den.provides.*`; this bootstrap uses `den.provides.define-user` and `den.provides.inputs'`.
|
||||||
|
- In this flake-parts setup, declaring `options.flake.darwinConfigurations` as `lib.types.lazyAttrsOf lib.types.raw` allows multiple Darwin hosts to merge correctly.
|
||||||
|
|
||||||
|
## Task 5: Core aspect module - COMPLETED
|
||||||
|
|
||||||
|
**What was done:**
|
||||||
|
- Created `modules/core.nix` as a flake-parts module defining `den.aspects.core`
|
||||||
|
- Ported all nix settings from `profiles/core.nix` into the `os` class (applies to both nixos and darwin)
|
||||||
|
- Updated `modules/defaults.nix` to include `den.aspects.core` in `den.default.includes`
|
||||||
|
|
||||||
|
**Key decisions:**
|
||||||
|
- Used `os` class for shared settings (fish, nushell, nixpkgs.config.allowUnfree, nix package, substituters, trusted-public-keys, gc.automatic, gc.options, experimental-features)
|
||||||
|
- Deliberately EXCLUDED `trusted-users` from core.nix (platform-specific: darwin uses "@admin", NixOS uses specific user — handled by darwin.nix and nixos-system.nix)
|
||||||
|
- Deliberately EXCLUDED gc interval/dates (platform-specific: darwin uses `interval`, NixOS uses `dates` — handled by darwin.nix and nixos-system.nix)
|
||||||
|
|
||||||
|
**Verification:**
|
||||||
|
- `modules/core.nix` created with 35 lines (exact port of profiles/core.nix settings)
|
||||||
|
- `modules/defaults.nix` updated to include `den.aspects.core` in includes list
|
||||||
|
- `alejandra .` formatted both files successfully
|
||||||
|
- `nix flake show` exits 0 (flake evaluates cleanly)
|
||||||
|
|
||||||
|
**Dependencies:**
|
||||||
|
- Unblocks Task 6 (darwin.nix and nixos-system.nix can now reference den.aspects.core)
|
||||||
|
|
||||||
|
## Task 6a: NixOS system aspect - COMPLETED
|
||||||
|
|
||||||
|
**What was done:**
|
||||||
|
- Created `modules/nixos-system.nix` as a flake-parts module defining `den.aspects.nixos-system`
|
||||||
|
- Ported NixOS-specific config from `profiles/nixos.nix` into the `nixos` class
|
||||||
|
|
||||||
|
**Key decisions:**
|
||||||
|
- Used `nixos` class (not `os`) since all settings are NixOS-specific (sudo, boot, systemd-boot, users)
|
||||||
|
- `nixos` class uses NixOS module function form `{pkgs, ...}: { ... }` to access `pkgs` for `linuxPackages_latest` and `nushell`
|
||||||
|
- `inputs` accessed from outer flake-parts module args for `home-manager.nixosModules.home-manager` import
|
||||||
|
- Hardcoded "cschmatzler" instead of variable interpolation (user is always the same)
|
||||||
|
- Hardcoded SSH keys inline instead of referencing constants (simplifies dependency)
|
||||||
|
- Deliberately EXCLUDED: system.stateVersion (in defaults.nix), sops.age.sshKeyPaths (in secrets.nix), home-manager.sharedModules/_module.args (den handles via inputs' battery)
|
||||||
|
|
||||||
|
**Pattern:**
|
||||||
|
- Outer function: `{inputs, ...}:` — flake-parts module args
|
||||||
|
- Inner class: `nixos = {pkgs, ...}: { ... }` — NixOS module function
|
||||||
|
- `imports = [inputs.home-manager.nixosModules.home-manager]` inside the nixos class
|
||||||
|
|
||||||
|
**Verification:**
|
||||||
|
- `alejandra --check .` passes (already compliant on write)
|
||||||
|
- `nix flake show` exits 0 (both michael and tahani evaluate cleanly)
|
||||||
|
|
||||||
|
## Task 6b: Darwin system aspect - COMPLETED
|
||||||
|
|
||||||
|
**What was done:**
|
||||||
|
- Created `modules/darwin.nix` as a flake-parts module defining `den.aspects.darwin-system`
|
||||||
|
- Created `modules/_darwin/dock.nix` — the dock module (NixOS-style with options/config)
|
||||||
|
- Ported profiles/darwin.nix, profiles/dock.nix, profiles/homebrew.nix, and nix-homebrew config
|
||||||
|
|
||||||
|
**Files created:**
|
||||||
|
- `modules/darwin.nix` — flake-parts module with `den.aspects.darwin-system.darwin` class
|
||||||
|
- `modules/_darwin/dock.nix` — dock options+activation script module (underscore prefix avoids import-tree)
|
||||||
|
|
||||||
|
**Key decisions:**
|
||||||
|
- `darwin` class uses NixOS module function form `{pkgs, ...}: { ... }` to access `pkgs.nushell`
|
||||||
|
- `inputs` accessed from outer flake-parts module args via closure (for nix-homebrew, home-manager, homebrew taps)
|
||||||
|
- Dock module placed in `modules/_darwin/dock.nix` and imported via `imports = [./_darwin/dock.nix]` inside the darwin class
|
||||||
|
- All `user` variable references replaced with hardcoded "cschmatzler"
|
||||||
|
- Excluded: home-manager.extraSpecialArgs (den handles via batteries), system.stateVersion (in defaults.nix)
|
||||||
|
- nix-homebrew config wired with taps from flake inputs (homebrew-core, homebrew-cask)
|
||||||
|
|
||||||
|
**Pattern for complex sub-modules:**
|
||||||
|
- Use `modules/_<platform>/` prefix (underscore avoids import-tree auto-import)
|
||||||
|
- Import from aspect class via `imports = [./_darwin/dock.nix]`
|
||||||
|
- The inner NixOS module function captures `inputs` from outer flake-parts scope via Nix closure
|
||||||
|
|
||||||
|
**Verification:**
|
||||||
|
- `alejandra .` — already compliant on write (no changes needed)
|
||||||
|
- `nix flake show` exits 0 (flake evaluates cleanly with new aspect)
|
||||||
|
|
||||||
|
## Task 23: Michael aspect with absorbed gitea module - COMPLETED
|
||||||
|
|
||||||
|
- Created `modules/_hosts/michael/` and copied `hosts/michael/disk-config.nix` plus `hosts/michael/hardware-configuration.nix` byte-for-byte into underscore-prefixed paths so import-tree ignores them.
|
||||||
|
- Added `modules/michael.nix` defining `den.aspects.michael` with includes `den.aspects.nixos-system`, `den.aspects.core`, and `den.aspects.cschmatzler`.
|
||||||
|
- Inlined the full gitea/redis/litestream/caddy/restic/systemd config directly in the michael aspect and removed dependency on `options.my.gitea`.
|
||||||
|
- Preserved intentional `lib.mkForce` overrides for litestream and restic service users/groups.
|
||||||
|
- Replaced legacy `cfg.*` references with concrete values and SOPS paths: litestream bucket `michael-gitea-litestream`, restic bucket `michael-gitea-repositories`, endpoint `s3.eu-central-003.backblazeb2.com`, and `config.sops.secrets.michael-gitea-*.path`.
|
||||||
|
|
||||||
|
## Task 25: Tahani aspect with host sub-files - COMPLETED
|
||||||
|
|
||||||
|
- Created `modules/_hosts/tahani/` and copied `hosts/tahani/{adguardhome,cache,networking,paperless}.nix` byte-for-byte into underscore-prefixed paths so import-tree ignores host-only sub-files.
|
||||||
|
- Added `modules/tahani.nix` defining `den.aspects.tahani` with includes `den.aspects.nixos-system`, `den.aspects.core`, and `den.aspects.cschmatzler` (network aspects intentionally deferred).
|
||||||
|
- Ported tahani-specific NixOS settings into the aspect (`networking.hostName`, docker enablement, docker group membership for `cschmatzler`, and 16 GiB swapfile declaration).
|
||||||
|
- Ported tahani-specific Home Manager settings into the aspect (`programs.git.settings.user.email`, zellij Nushell integration override enabled for tahani).
|
||||||
|
- Inbox-triage systemd unit now uses `pkgs.himalaya` from overlay in `PATH` (`${pkgs.himalaya}/bin`) with `inputs'.llm-agents.packages.opencode` for `ExecStart`; no `config.home-manager.users...` lookup.
|
||||||
|
- Verification: `alejandra .`, `alejandra --check .`, and `nix flake show` all pass; `lsp_diagnostics` is clean on all newly created tahani files.
|
||||||
|
|
||||||
|
- Home Manager `programs.nushell` module writes `config.nu` as a merge of: `environmentVariables` (via `load-env`), flattened `settings`, optional `configFile.text`, then `extraConfig`, then generated `shellAliases` (see HM `modules/programs/nushell.nix`). So any duplication in `config.nu` that is isolated to `extraConfig` almost always means the option value was merged multiple times (module included multiple times), not that HM writes it twice.
|
||||||
|
- In Den, HM user contexts include both the host aspect chain and the user aspect (`den.ctx.user`). If you also include the user aspect from the host aspect `includes`, user HM config is applied twice.
|
||||||
1794
.sisyphus/plans/dendritic-migration.md
Normal file
1794
.sisyphus/plans/dendritic-migration.md
Normal file
File diff suppressed because it is too large
Load Diff
93
AGENTS.md
93
AGENTS.md
@@ -12,12 +12,12 @@ nix flake check # Validate flake
|
|||||||
|
|
||||||
### Remote Deployment (NixOS only)
|
### Remote Deployment (NixOS only)
|
||||||
```bash
|
```bash
|
||||||
colmena build # Build all NixOS hosts
|
nix run .#deploy # Deploy to all NixOS hosts
|
||||||
colmena apply --on <host> # Deploy to specific NixOS host (michael, tahani)
|
nix run .#deploy -- .#michael # Deploy to specific NixOS host
|
||||||
colmena apply # Deploy to all NixOS hosts
|
nix run .#deploy -- .#tahani # Deploy to specific NixOS host
|
||||||
```
|
```
|
||||||
|
|
||||||
When you're on tahani and asked to apply, that means running `colmena apply`.
|
When you're on tahani and asked to apply, that means running `nix run .#deploy`.
|
||||||
|
|
||||||
### Formatting
|
### Formatting
|
||||||
```bash
|
```bash
|
||||||
@@ -32,14 +32,35 @@ alejandra . # Format all Nix files
|
|||||||
- **Command**: Run `alejandra .` before committing
|
- **Command**: Run `alejandra .` before committing
|
||||||
|
|
||||||
### File Structure
|
### File Structure
|
||||||
- **Hosts**: `hosts/<hostname>/` - Per-machine configurations
|
- **Modules**: `modules/` - All configuration (flake-parts modules, auto-imported by import-tree)
|
||||||
- Darwin: `chidi`, `jason`
|
- `_lib/` - Utility functions (underscore = ignored by import-tree)
|
||||||
- NixOS: `michael`, `tahani`
|
- `_darwin/` - Darwin-specific sub-modules
|
||||||
- **Profiles**: `profiles/` - Reusable program/service configurations (imported by hosts)
|
- `_neovim/` - Neovim plugin configs
|
||||||
- **Modules**: `modules/` - Custom NixOS/darwin modules
|
- `_opencode/` - OpenCode agent/command/skill configs
|
||||||
- **Lib**: `lib/` - Shared constants and utilities
|
- `_hosts/` - Host-specific sub-files (disk-config, hardware, etc.)
|
||||||
|
- **Apps**: `apps/` - Per-system app scripts (Nushell)
|
||||||
- **Secrets**: `secrets/` - SOPS-encrypted secrets (`.sops.yaml` for config)
|
- **Secrets**: `secrets/` - SOPS-encrypted secrets (`.sops.yaml` for config)
|
||||||
|
|
||||||
|
### Architecture
|
||||||
|
|
||||||
|
**Framework**: den (vic/den) — every .nix file in `modules/` is a flake-parts module
|
||||||
|
|
||||||
|
**Pattern**: Feature/aspect-centric, not host-centric
|
||||||
|
|
||||||
|
**Aspects**: `den.aspects.<name>.<class>` where class is:
|
||||||
|
- `nixos` - NixOS-only configuration
|
||||||
|
- `darwin` - macOS-only configuration
|
||||||
|
- `homeManager` - Home Manager configuration
|
||||||
|
- `os` - Applies to both NixOS and darwin
|
||||||
|
|
||||||
|
**Hosts**: `den.hosts.<system>.<name>` defined in `modules/hosts.nix`
|
||||||
|
|
||||||
|
**Defaults**: `den.default.*` defined in `modules/defaults.nix`
|
||||||
|
|
||||||
|
**Imports**: Auto-imported by import-tree; underscore-prefixed dirs (`_lib/`, `_darwin/`, etc.) are excluded from auto-import
|
||||||
|
|
||||||
|
**Deployment**: deploy-rs for NixOS hosts (michael, tahani); darwin hosts (chidi, jason) are local-only
|
||||||
|
|
||||||
### Nix Language Conventions
|
### Nix Language Conventions
|
||||||
|
|
||||||
**Function Arguments**:
|
**Function Arguments**:
|
||||||
@@ -48,20 +69,11 @@ alejandra . # Format all Nix files
|
|||||||
```
|
```
|
||||||
Destructure arguments on separate lines. Use `...` to capture remaining args.
|
Destructure arguments on separate lines. Use `...` to capture remaining args.
|
||||||
|
|
||||||
**Imports**:
|
|
||||||
```nix
|
|
||||||
../../profiles/foo.nix
|
|
||||||
```
|
|
||||||
Use relative paths from file location, not absolute paths.
|
|
||||||
|
|
||||||
**Attribute Sets**:
|
**Attribute Sets**:
|
||||||
```nix
|
```nix
|
||||||
options.my.gitea = {
|
den.aspects.myfeature.os = {
|
||||||
enable = lib.mkEnableOption "Gitea git hosting service";
|
enable = true;
|
||||||
bucket = lib.mkOption {
|
config = "value";
|
||||||
type = lib.types.str;
|
|
||||||
description = "S3 bucket name";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
One attribute per line with trailing semicolons.
|
One attribute per line with trailing semicolons.
|
||||||
@@ -77,7 +89,7 @@ with pkgs;
|
|||||||
```
|
```
|
||||||
Use `with pkgs;` for package lists, one item per line.
|
Use `with pkgs;` for package lists, one item per line.
|
||||||
|
|
||||||
**Modules**:
|
**Aspect Definition**:
|
||||||
```nix
|
```nix
|
||||||
{
|
{
|
||||||
config,
|
config,
|
||||||
@@ -86,9 +98,9 @@ Use `with pkgs;` for package lists, one item per line.
|
|||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
with lib; let
|
with lib; let
|
||||||
cfg = config.my.feature;
|
cfg = config.den.aspects.myfeature;
|
||||||
in {
|
in {
|
||||||
options.my.feature = {
|
options.den.aspects.myfeature = {
|
||||||
enable = mkEnableOption "Feature description";
|
enable = mkEnableOption "Feature description";
|
||||||
};
|
};
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
@@ -113,22 +125,27 @@ in {
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Naming Conventions
|
### Naming Conventions
|
||||||
- **Option names**: `my.<feature>.<option>` for custom modules
|
- **Aspect names**: `den.aspects.<name>.<class>` for feature configuration
|
||||||
- **Hostnames**: Lowercase, descriptive (e.g., `michael`, `tahani`)
|
- **Hostnames**: Lowercase, descriptive (e.g., `michael`, `tahani`, `chidi`, `jason`)
|
||||||
- **Profile files**: Descriptive, lowercase with hyphens (e.g., `homebrew.nix`)
|
- **Module files**: Descriptive, lowercase with hyphens (e.g., `neovim-config.nix`)
|
||||||
|
|
||||||
### Secrets Management
|
### Secrets Management
|
||||||
- Use SOPS for secrets (see `.sops.yaml`)
|
- Use SOPS for secrets (see `.sops.yaml`)
|
||||||
- Never commit unencrypted secrets
|
- Never commit unencrypted secrets
|
||||||
- Secrets files in `hosts/<host>/secrets.nix` import SOPS-generated files
|
- Secret definitions in `modules/secrets.nix`
|
||||||
|
|
||||||
### Imports Pattern
|
### Aspect Composition
|
||||||
Host configs import:
|
Use `den.aspects.<name>.includes` to compose aspects:
|
||||||
1. System modules (`modulesPath + "/..."`)
|
```nix
|
||||||
2. Host-specific files (`./disk-config.nix`, `./hardware-configuration.nix`)
|
den.aspects.myfeature.includes = [
|
||||||
3. SOPS secrets (`./secrets.nix`)
|
"other-aspect"
|
||||||
4. Custom modules (`../../modules/*.nix`)
|
"another-aspect"
|
||||||
5. Base profiles (`../../profiles/*.nix`)
|
];
|
||||||
6. Input modules (`inputs.<module>.xxxModules.module`)
|
```
|
||||||
|
|
||||||
Home-manager users import profiles in a similar manner.
|
### Key Conventions
|
||||||
|
- No `specialArgs` — den batteries handle input passing
|
||||||
|
- No hostname string comparisons in shared aspects
|
||||||
|
- Host-specific config goes in `den.aspects.<hostname>.*`
|
||||||
|
- Shared config uses `os` class (applies to both NixOS and darwin)
|
||||||
|
- Non-module files go in `_`-prefixed subdirs
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env nu
|
||||||
|
|
||||||
set -euo pipefail
|
use ../common.nu *
|
||||||
source "$(dirname "$0")/../common.sh"
|
|
||||||
|
|
||||||
HOSTNAME="${1:-$(scutil --get LocalHostName 2>/dev/null || hostname -s)}"
|
def main [hostname?: string, ...rest: string] {
|
||||||
|
let host = if ($hostname | is-empty) {
|
||||||
print_info "Applying configuration for $HOSTNAME"
|
try { scutil --get LocalHostName | str trim } catch { hostname -s | str trim }
|
||||||
|
} else { $hostname }
|
||||||
nix run nix-darwin -- switch --flake ".#$HOSTNAME" "${@:2}"
|
|
||||||
|
print_info $"Applying configuration for ($host)"
|
||||||
print_success "Configuration applied successfully"
|
|
||||||
|
nix run nix-darwin -- switch --flake $".#($host)" ...$rest
|
||||||
|
|
||||||
|
print_success "Configuration applied successfully"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,16 +1,19 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env nu
|
||||||
|
|
||||||
set -euo pipefail
|
use ../common.nu *
|
||||||
source "$(dirname "$0")/../common.sh"
|
|
||||||
|
|
||||||
HOSTNAME="${1:-$(scutil --get LocalHostName 2>/dev/null || hostname -s)}"
|
def main [hostname?: string, ...rest: string] {
|
||||||
|
let host = if ($hostname | is-empty) {
|
||||||
print_info "Building configuration for $HOSTNAME"
|
try { scutil --get LocalHostName | str trim } catch { hostname -s | str trim }
|
||||||
|
} else { $hostname }
|
||||||
nix build ".#darwinConfigurations.$HOSTNAME.system" --show-trace "${@:2}"
|
|
||||||
|
print_info $"Building configuration for ($host)"
|
||||||
if [[ -L ./result ]]; then
|
|
||||||
unlink ./result
|
nix build $".#darwinConfigurations.($host).system" --show-trace ...$rest
|
||||||
fi
|
|
||||||
|
if ("./result" | path exists) {
|
||||||
print_success "Build completed successfully"
|
rm ./result
|
||||||
|
}
|
||||||
|
|
||||||
|
print_success "Build completed successfully"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,27 +1,30 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env nu
|
||||||
|
|
||||||
set -euo pipefail
|
use ../common.nu *
|
||||||
source "$(dirname "$0")/../common.sh"
|
|
||||||
|
|
||||||
HOSTNAME="${1:-$(scutil --get LocalHostName 2>/dev/null || hostname -s)}"
|
def main [hostname?: string, ...rest: string] {
|
||||||
|
let host = if ($hostname | is-empty) {
|
||||||
print_info "Building and switching configuration for $HOSTNAME"
|
try { scutil --get LocalHostName | str trim } catch { hostname -s | str trim }
|
||||||
|
} else { $hostname }
|
||||||
# Build
|
|
||||||
print_info "Building configuration..."
|
print_info $"Building and switching configuration for ($host)"
|
||||||
if ! nix build ".#darwinConfigurations.$HOSTNAME.system" --show-trace "${@:2}"; then
|
|
||||||
print_error "Build failed"
|
# Build
|
||||||
exit 1
|
print_info "Building configuration..."
|
||||||
fi
|
if (nix build $".#darwinConfigurations.($host).system" --show-trace ...$rest | complete).exit_code != 0 {
|
||||||
|
print_error "Build failed"
|
||||||
print_success "Build completed"
|
exit 1
|
||||||
|
}
|
||||||
# Switch
|
|
||||||
print_info "Switching to new configuration..."
|
print_success "Build completed"
|
||||||
sudo ./result/sw/bin/darwin-rebuild switch --flake ".#$HOSTNAME" "${@:2}"
|
|
||||||
|
# Switch
|
||||||
if [[ -L ./result ]]; then
|
print_info "Switching to new configuration..."
|
||||||
unlink ./result
|
sudo ./result/sw/bin/darwin-rebuild switch --flake $".#($host)" ...$rest
|
||||||
fi
|
|
||||||
|
if ("./result" | path exists) {
|
||||||
print_success "Build and switch completed successfully"
|
rm ./result
|
||||||
|
}
|
||||||
|
|
||||||
|
print_success "Build and switch completed successfully"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env nu
|
||||||
|
|
||||||
set -euo pipefail
|
use ../common.nu *
|
||||||
source "$(dirname "$0")/../common.sh"
|
|
||||||
|
|
||||||
print_info "Available generations:"
|
def main [] {
|
||||||
darwin-rebuild --list-generations
|
print_info "Available generations:"
|
||||||
|
darwin-rebuild --list-generations
|
||||||
echo -n "Enter generation number to rollback to: "
|
|
||||||
read -r GEN_NUM
|
let gen_num = input "Enter generation number to rollback to: "
|
||||||
|
|
||||||
if [[ -z "$GEN_NUM" ]]; then
|
if ($gen_num | is-empty) {
|
||||||
print_error "No generation number provided"
|
print_error "No generation number provided"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
}
|
||||||
|
|
||||||
print_warning "Rolling back to generation $GEN_NUM..."
|
print_warning $"Rolling back to generation ($gen_num)..."
|
||||||
darwin-rebuild switch --switch-generation "$GEN_NUM"
|
darwin-rebuild switch --switch-generation $gen_num
|
||||||
|
|
||||||
print_success "Rollback to generation $GEN_NUM complete"
|
print_success $"Rollback to generation ($gen_num) complete"
|
||||||
|
}
|
||||||
|
|||||||
17
apps/common.nu
Normal file
17
apps/common.nu
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#!/usr/bin/env nu
|
||||||
|
|
||||||
|
export def print_info [msg: string] {
|
||||||
|
print $"(ansi blue)[INFO](ansi reset) ($msg)"
|
||||||
|
}
|
||||||
|
|
||||||
|
export def print_success [msg: string] {
|
||||||
|
print $"(ansi green)[OK](ansi reset) ($msg)"
|
||||||
|
}
|
||||||
|
|
||||||
|
export def print_error [msg: string] {
|
||||||
|
print $"(ansi red)[ERROR](ansi reset) ($msg)"
|
||||||
|
}
|
||||||
|
|
||||||
|
export def print_warning [msg: string] {
|
||||||
|
print $"(ansi yellow)[WARN](ansi reset) ($msg)"
|
||||||
|
}
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
#!/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"
|
|
||||||
}
|
|
||||||
@@ -1,16 +1,21 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env nu
|
||||||
|
|
||||||
set -euo pipefail
|
use ../common.nu *
|
||||||
source "$(dirname "$0")/../common.sh"
|
|
||||||
|
|
||||||
HOSTNAME="${1:-$(hostname)}"
|
def main [hostname?: string, ...rest: string] {
|
||||||
|
let host = if ($hostname | is-empty) {
|
||||||
print_info "Applying configuration for $HOSTNAME"
|
hostname | str trim
|
||||||
|
} else { $hostname }
|
||||||
if [[ "$EUID" -ne 0 ]]; then
|
|
||||||
sudo nixos-rebuild switch --flake ".#$HOSTNAME" "${@:2}"
|
print_info $"Applying configuration for ($host)"
|
||||||
else
|
|
||||||
nixos-rebuild switch --flake ".#$HOSTNAME" "${@:2}"
|
let euid = (id -u | str trim | into int)
|
||||||
fi
|
|
||||||
|
if $euid != 0 {
|
||||||
print_success "Configuration applied successfully"
|
sudo nixos-rebuild switch --flake $".#($host)" ...$rest
|
||||||
|
} else {
|
||||||
|
nixos-rebuild switch --flake $".#($host)" ...$rest
|
||||||
|
}
|
||||||
|
|
||||||
|
print_success "Configuration applied successfully"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,16 +1,19 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env nu
|
||||||
|
|
||||||
set -euo pipefail
|
use ../common.nu *
|
||||||
source "$(dirname "$0")/../common.sh"
|
|
||||||
|
|
||||||
HOSTNAME="${1:-$(hostname)}"
|
def main [hostname?: string, ...rest: string] {
|
||||||
|
let host = if ($hostname | is-empty) {
|
||||||
print_info "Building configuration for $HOSTNAME"
|
hostname | str trim
|
||||||
|
} else { $hostname }
|
||||||
nix build ".#nixosConfigurations.$HOSTNAME.config.system.build.toplevel" --show-trace "${@:2}"
|
|
||||||
|
print_info $"Building configuration for ($host)"
|
||||||
if [[ -L ./result ]]; then
|
|
||||||
unlink ./result
|
nix build $".#nixosConfigurations.($host).config.system.build.toplevel" --show-trace ...$rest
|
||||||
fi
|
|
||||||
|
if ("./result" | path exists) {
|
||||||
print_success "Build completed successfully"
|
rm ./result
|
||||||
|
}
|
||||||
|
|
||||||
|
print_success "Build completed successfully"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,26 +1,32 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env nu
|
||||||
|
|
||||||
set -euo pipefail
|
use ../common.nu *
|
||||||
source "$(dirname "$0")/../common.sh"
|
|
||||||
|
|
||||||
HOSTNAME="${1:-$(hostname)}"
|
def main [hostname?: string, ...rest: string] {
|
||||||
|
let host = if ($hostname | is-empty) {
|
||||||
print_info "Building and switching configuration for $HOSTNAME"
|
hostname | str trim
|
||||||
|
} else { $hostname }
|
||||||
# Build
|
|
||||||
print_info "Building configuration..."
|
print_info $"Building and switching configuration for ($host)"
|
||||||
if ! nix build ".#nixosConfigurations.$HOSTNAME.config.system.build.toplevel" --no-link "${@:2}"; then
|
|
||||||
print_error "Build failed"
|
# Build
|
||||||
exit 1
|
print_info "Building configuration..."
|
||||||
fi
|
if (nix build $".#nixosConfigurations.($host).config.system.build.toplevel" --no-link ...$rest | complete).exit_code != 0 {
|
||||||
|
print_error "Build failed"
|
||||||
print_success "Build completed"
|
exit 1
|
||||||
|
}
|
||||||
print_info "Switching to new configuration..."
|
|
||||||
if [[ "$EUID" -ne 0 ]]; then
|
print_success "Build completed"
|
||||||
sudo nixos-rebuild switch --flake ".#$HOSTNAME" "${@:2}"
|
|
||||||
else
|
# Switch
|
||||||
nixos-rebuild switch --flake ".#$HOSTNAME" "${@:2}"
|
print_info "Switching to new configuration..."
|
||||||
fi
|
let euid = (id -u | str trim | into int)
|
||||||
|
|
||||||
print_success "Build and switch completed successfully"
|
if $euid != 0 {
|
||||||
|
sudo nixos-rebuild switch --flake $".#($host)" ...$rest
|
||||||
|
} else {
|
||||||
|
nixos-rebuild switch --flake $".#($host)" ...$rest
|
||||||
|
}
|
||||||
|
|
||||||
|
print_success "Build and switch completed successfully"
|
||||||
|
}
|
||||||
|
|||||||
60
apps/x86_64-linux/rollback
Normal file → Executable file
60
apps/x86_64-linux/rollback
Normal file → Executable file
@@ -1,30 +1,34 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env nu
|
||||||
|
|
||||||
set -euo pipefail
|
use ../common.nu *
|
||||||
source "$(dirname "$0")/../common.sh"
|
|
||||||
|
|
||||||
print_info "Available generations:"
|
def main [] {
|
||||||
if [[ "$EUID" -ne 0 ]]; then
|
print_info "Available generations:"
|
||||||
sudo nix-env --profile /nix/var/nix/profiles/system --list-generations
|
|
||||||
else
|
let euid = (id -u | str trim | into int)
|
||||||
nix-env --profile /nix/var/nix/profiles/system --list-generations
|
|
||||||
fi
|
if $euid != 0 {
|
||||||
|
sudo nix-env --profile /nix/var/nix/profiles/system --list-generations
|
||||||
echo -n "Enter generation number to rollback to: "
|
} else {
|
||||||
read -r GEN_NUM
|
nix-env --profile /nix/var/nix/profiles/system --list-generations
|
||||||
|
}
|
||||||
if [[ -z "$GEN_NUM" ]]; then
|
|
||||||
print_error "No generation number provided"
|
let gen_num = input "Enter generation number to rollback to: "
|
||||||
exit 1
|
|
||||||
fi
|
if ($gen_num | is-empty) {
|
||||||
|
print_error "No generation number provided"
|
||||||
print_warning "Rolling back to generation $GEN_NUM..."
|
exit 1
|
||||||
if [[ "$EUID" -ne 0 ]]; then
|
}
|
||||||
sudo nix-env --profile /nix/var/nix/profiles/system --switch-generation "$GEN_NUM" && \
|
|
||||||
sudo /nix/var/nix/profiles/system/bin/switch-to-configuration switch
|
print_warning $"Rolling back to generation ($gen_num)..."
|
||||||
else
|
|
||||||
nix-env --profile /nix/var/nix/profiles/system --switch-generation "$GEN_NUM" && \
|
if $euid != 0 {
|
||||||
/nix/var/nix/profiles/system/bin/switch-to-configuration switch
|
sudo nix-env --profile /nix/var/nix/profiles/system --switch-generation $gen_num
|
||||||
fi
|
sudo /nix/var/nix/profiles/system/bin/switch-to-configuration switch
|
||||||
|
} else {
|
||||||
print_success "Rollback to generation $GEN_NUM complete"
|
nix-env --profile /nix/var/nix/profiles/system --switch-generation $gen_num
|
||||||
|
/nix/var/nix/profiles/system/bin/switch-to-configuration switch
|
||||||
|
}
|
||||||
|
|
||||||
|
print_success $"Rollback to generation ($gen_num) complete"
|
||||||
|
}
|
||||||
|
|||||||
299
flake.lock
generated
299
flake.lock
generated
@@ -6,7 +6,7 @@
|
|||||||
"llm-agents",
|
"llm-agents",
|
||||||
"nixpkgs"
|
"nixpkgs"
|
||||||
],
|
],
|
||||||
"systems": "systems_2"
|
"systems": "systems_3"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1771437256,
|
"lastModified": 1771437256,
|
||||||
@@ -42,12 +42,12 @@
|
|||||||
"bun2nix": {
|
"bun2nix": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-parts": "flake-parts_2",
|
"flake-parts": "flake-parts_2",
|
||||||
"import-tree": "import-tree",
|
"import-tree": "import-tree_2",
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
"llm-agents",
|
"llm-agents",
|
||||||
"nixpkgs"
|
"nixpkgs"
|
||||||
],
|
],
|
||||||
"systems": "systems_3",
|
"systems": "systems_4",
|
||||||
"treefmt-nix": "treefmt-nix"
|
"treefmt-nix": "treefmt-nix"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
@@ -64,30 +64,6 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"colmena": {
|
|
||||||
"inputs": {
|
|
||||||
"flake-compat": "flake-compat",
|
|
||||||
"flake-utils": "flake-utils",
|
|
||||||
"nix-github-actions": "nix-github-actions",
|
|
||||||
"nixpkgs": [
|
|
||||||
"nixpkgs"
|
|
||||||
],
|
|
||||||
"stable": "stable"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1762034856,
|
|
||||||
"narHash": "sha256-QVey3iP3UEoiFVXgypyjTvCrsIlA4ecx6Acaz5C8/PQ=",
|
|
||||||
"owner": "zhaofengli",
|
|
||||||
"repo": "colmena",
|
|
||||||
"rev": "349b035a5027f23d88eeb3bc41085d7ee29f18ed",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "zhaofengli",
|
|
||||||
"repo": "colmena",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"crane": {
|
"crane": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1765739568,
|
"lastModified": 1765739568,
|
||||||
@@ -124,6 +100,41 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"den": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1772696629,
|
||||||
|
"narHash": "sha256-wJvv0ZAcjpHBo/MnDSEZ+Dti+daJvlxznDUgKUvkT3c=",
|
||||||
|
"owner": "vic",
|
||||||
|
"repo": "den",
|
||||||
|
"rev": "94b8721bcff4940e1cce97c509d72545efa4a8e4",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "vic",
|
||||||
|
"repo": "den",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deploy-rs": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-compat": "flake-compat",
|
||||||
|
"nixpkgs": "nixpkgs",
|
||||||
|
"utils": "utils"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1770019181,
|
||||||
|
"narHash": "sha256-hwsYgDnby50JNVpTRYlF3UR/Rrpt01OrxVuryF40CFY=",
|
||||||
|
"owner": "serokell",
|
||||||
|
"repo": "deploy-rs",
|
||||||
|
"rev": "77c906c0ba56aabdbc72041bf9111b565cdd6171",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "serokell",
|
||||||
|
"repo": "deploy-rs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"disko": {
|
"disko": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
@@ -212,14 +223,29 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"flake-aspects": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1772679072,
|
||||||
|
"narHash": "sha256-qrbfroFGetX5DS/n6gP6BifqGCO084b5ad8C5kwaLAk=",
|
||||||
|
"owner": "vic",
|
||||||
|
"repo": "flake-aspects",
|
||||||
|
"rev": "82a472654139897fab1bcb2d96ae337fb7928800",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "vic",
|
||||||
|
"repo": "flake-aspects",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"flake-compat": {
|
"flake-compat": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1650374568,
|
"lastModified": 1733328505,
|
||||||
"narHash": "sha256-Z+s0J8/r907g149rllvwhb4pKi8Wam5ij0st8PwAh+E=",
|
"narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=",
|
||||||
"owner": "edolstra",
|
"owner": "edolstra",
|
||||||
"repo": "flake-compat",
|
"repo": "flake-compat",
|
||||||
"rev": "b4a34015c698c7793d592d66adbab377907a2be8",
|
"rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -228,9 +254,26 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"flake-file": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1772677111,
|
||||||
|
"narHash": "sha256-tFVzJ+A39OrBPK1lYlM5giUu6yl9pwjUGf6VR3b8Yho=",
|
||||||
|
"owner": "vic",
|
||||||
|
"repo": "flake-file",
|
||||||
|
"rev": "f18f9bad86481621b9c378842987b172e91ca82c",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "vic",
|
||||||
|
"repo": "flake-file",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"flake-parts": {
|
"flake-parts": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs-lib": "nixpkgs-lib"
|
"nixpkgs-lib": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772408722,
|
"lastModified": 1772408722,
|
||||||
@@ -248,7 +291,7 @@
|
|||||||
},
|
},
|
||||||
"flake-parts_2": {
|
"flake-parts_2": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs-lib": "nixpkgs-lib_2"
|
"nixpkgs-lib": "nixpkgs-lib"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1769996383,
|
"lastModified": 1769996383,
|
||||||
@@ -286,23 +329,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flake-utils": {
|
"flake-utils": {
|
||||||
"locked": {
|
|
||||||
"lastModified": 1659877975,
|
|
||||||
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"flake-utils_2": {
|
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"systems": "systems"
|
"systems": "systems_2"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1731533236,
|
"lastModified": 1731533236,
|
||||||
@@ -318,9 +346,9 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flake-utils_3": {
|
"flake-utils_2": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"systems": "systems_6"
|
"systems": "systems_7"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1731533236,
|
"lastModified": 1731533236,
|
||||||
@@ -339,7 +367,7 @@
|
|||||||
"himalaya": {
|
"himalaya": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"fenix": "fenix",
|
"fenix": "fenix",
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs_2",
|
||||||
"pimalaya": "pimalaya"
|
"pimalaya": "pimalaya"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
@@ -409,6 +437,21 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"import-tree": {
|
"import-tree": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1772344373,
|
||||||
|
"narHash": "sha256-OQQ1MhB9t1J71b2wxRRTdH/Qd8UGG0p+dGspfCf5U1c=",
|
||||||
|
"owner": "vic",
|
||||||
|
"repo": "import-tree",
|
||||||
|
"rev": "10fda59eee7d7970ec443b925f32a1bc7526648c",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "vic",
|
||||||
|
"repo": "import-tree",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"import-tree_2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1763762820,
|
"lastModified": 1763762820,
|
||||||
"narHash": "sha256-ZvYKbFib3AEwiNMLsejb/CWs/OL/srFQ8AogkebEPF0=",
|
"narHash": "sha256-ZvYKbFib3AEwiNMLsejb/CWs/OL/srFQ8AogkebEPF0=",
|
||||||
@@ -441,8 +484,8 @@
|
|||||||
},
|
},
|
||||||
"jj-starship": {
|
"jj-starship": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-utils": "flake-utils_2",
|
"flake-utils": "flake-utils",
|
||||||
"nixpkgs": "nixpkgs_2"
|
"nixpkgs": "nixpkgs_3"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1769370163,
|
"lastModified": 1769370163,
|
||||||
@@ -462,7 +505,7 @@
|
|||||||
"inputs": {
|
"inputs": {
|
||||||
"blueprint": "blueprint",
|
"blueprint": "blueprint",
|
||||||
"bun2nix": "bun2nix",
|
"bun2nix": "bun2nix",
|
||||||
"nixpkgs": "nixpkgs_3",
|
"nixpkgs": "nixpkgs_4",
|
||||||
"treefmt-nix": "treefmt-nix_2"
|
"treefmt-nix": "treefmt-nix_2"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
@@ -524,27 +567,6 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nix-github-actions": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": [
|
|
||||||
"colmena",
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1729742964,
|
|
||||||
"narHash": "sha256-B4mzTcQ0FZHdpeWcpDYPERtyjJd/NIuaQ9+BV1h+MpA=",
|
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "nix-github-actions",
|
|
||||||
"rev": "e04df33f62cdcf93d73e9a04142464753a16db67",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "nix-github-actions",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nix-homebrew": {
|
"nix-homebrew": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"brew-src": "brew-src"
|
"brew-src": "brew-src"
|
||||||
@@ -565,36 +587,21 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1736437047,
|
"lastModified": 1743014863,
|
||||||
"narHash": "sha256-JJBziecfU+56SUNxeJlDIgixJN5WYuADd+/TVd5sQos=",
|
"narHash": "sha256-jAIUqsiN2r3hCuHji80U7NNEafpIMBXiwKlSrjWMlpg=",
|
||||||
"owner": "nixos",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "f17b95775191ea44bc426831235d87affb10faba",
|
"rev": "bd3bac8bfb542dbde7ffffb6987a1a1f9d41699f",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "nixos",
|
"owner": "NixOS",
|
||||||
"ref": "staging-next",
|
"ref": "nixpkgs-unstable",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs-lib": {
|
"nixpkgs-lib": {
|
||||||
"locked": {
|
|
||||||
"lastModified": 1772328832,
|
|
||||||
"narHash": "sha256-e+/T/pmEkLP6BHhYjx6GmwP5ivonQQn0bJdH9YrRB+Q=",
|
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "nixpkgs.lib",
|
|
||||||
"rev": "c185c7a5e5dd8f9add5b2f8ebeff00888b070742",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "nixpkgs.lib",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs-lib_2": {
|
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1769909678,
|
"lastModified": 1769909678,
|
||||||
"narHash": "sha256-cBEymOf4/o3FD5AZnzC3J9hLbiZ+QDT/KDuyHXVJOpM=",
|
"narHash": "sha256-cBEymOf4/o3FD5AZnzC3J9hLbiZ+QDT/KDuyHXVJOpM=",
|
||||||
@@ -610,6 +617,22 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs_2": {
|
"nixpkgs_2": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1736437047,
|
||||||
|
"narHash": "sha256-JJBziecfU+56SUNxeJlDIgixJN5WYuADd+/TVd5sQos=",
|
||||||
|
"owner": "nixos",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "f17b95775191ea44bc426831235d87affb10faba",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nixos",
|
||||||
|
"ref": "staging-next",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_3": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1766840161,
|
"lastModified": 1766840161,
|
||||||
"narHash": "sha256-Ss/LHpJJsng8vz1Pe33RSGIWUOcqM1fjrehjUkdrWio=",
|
"narHash": "sha256-Ss/LHpJJsng8vz1Pe33RSGIWUOcqM1fjrehjUkdrWio=",
|
||||||
@@ -625,7 +648,7 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs_3": {
|
"nixpkgs_4": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772643971,
|
"lastModified": 1772643971,
|
||||||
"narHash": "sha256-+bllfMsclzbAAPMZTm3K9G/a5lG+s6l18/AyyYLPSIE=",
|
"narHash": "sha256-+bllfMsclzbAAPMZTm3K9G/a5lG+s6l18/AyyYLPSIE=",
|
||||||
@@ -641,7 +664,7 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs_4": {
|
"nixpkgs_5": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772701849,
|
"lastModified": 1772701849,
|
||||||
"narHash": "sha256-CO0mU0p/Fe5ekivxJmKO0WMA6kMOI/DbI+qEKhOxYCo=",
|
"narHash": "sha256-CO0mU0p/Fe5ekivxJmKO0WMA6kMOI/DbI+qEKhOxYCo=",
|
||||||
@@ -657,7 +680,7 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs_5": {
|
"nixpkgs_6": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1770380644,
|
"lastModified": 1770380644,
|
||||||
"narHash": "sha256-P7dWMHRUWG5m4G+06jDyThXO7kwSk46C1kgjEWcybkE=",
|
"narHash": "sha256-P7dWMHRUWG5m4G+06jDyThXO7kwSk46C1kgjEWcybkE=",
|
||||||
@@ -673,7 +696,7 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs_6": {
|
"nixpkgs_7": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1771923393,
|
"lastModified": 1771923393,
|
||||||
"narHash": "sha256-Fy0+UXELv9hOE8WjYhJt8fMDLYTU2Dqn3cX4BwoGBos=",
|
"narHash": "sha256-Fy0+UXELv9hOE8WjYhJt8fMDLYTU2Dqn3cX4BwoGBos=",
|
||||||
@@ -689,7 +712,7 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs_7": {
|
"nixpkgs_8": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1765934234,
|
"lastModified": 1765934234,
|
||||||
"narHash": "sha256-pJjWUzNnjbIAMIc5gRFUuKCDQ9S1cuh3b2hKgA7Mc4A=",
|
"narHash": "sha256-pJjWUzNnjbIAMIc5gRFUuKCDQ9S1cuh3b2hKgA7Mc4A=",
|
||||||
@@ -708,8 +731,8 @@
|
|||||||
"nixvim": {
|
"nixvim": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-parts": "flake-parts_3",
|
"flake-parts": "flake-parts_3",
|
||||||
"nixpkgs": "nixpkgs_5",
|
"nixpkgs": "nixpkgs_6",
|
||||||
"systems": "systems_4"
|
"systems": "systems_5"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772402258,
|
"lastModified": 1772402258,
|
||||||
@@ -743,20 +766,27 @@
|
|||||||
},
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"colmena": "colmena",
|
|
||||||
"darwin": "darwin",
|
"darwin": "darwin",
|
||||||
|
"den": "den",
|
||||||
|
"deploy-rs": "deploy-rs",
|
||||||
"disko": "disko",
|
"disko": "disko",
|
||||||
|
"flake-aspects": "flake-aspects",
|
||||||
|
"flake-file": "flake-file",
|
||||||
"flake-parts": "flake-parts",
|
"flake-parts": "flake-parts",
|
||||||
"himalaya": "himalaya",
|
"himalaya": "himalaya",
|
||||||
"home-manager": "home-manager",
|
"home-manager": "home-manager",
|
||||||
"homebrew-cask": "homebrew-cask",
|
"homebrew-cask": "homebrew-cask",
|
||||||
"homebrew-core": "homebrew-core",
|
"homebrew-core": "homebrew-core",
|
||||||
|
"import-tree": "import-tree",
|
||||||
"jj-ryu": "jj-ryu",
|
"jj-ryu": "jj-ryu",
|
||||||
"jj-starship": "jj-starship",
|
"jj-starship": "jj-starship",
|
||||||
"llm-agents": "llm-agents",
|
"llm-agents": "llm-agents",
|
||||||
"naersk": "naersk",
|
"naersk": "naersk",
|
||||||
"nix-homebrew": "nix-homebrew",
|
"nix-homebrew": "nix-homebrew",
|
||||||
"nixpkgs": "nixpkgs_4",
|
"nixpkgs": "nixpkgs_5",
|
||||||
|
"nixpkgs-lib": [
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
"nixvim": "nixvim",
|
"nixvim": "nixvim",
|
||||||
"sops-nix": "sops-nix",
|
"sops-nix": "sops-nix",
|
||||||
"tuicr": "tuicr",
|
"tuicr": "tuicr",
|
||||||
@@ -855,22 +885,6 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"stable": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1750133334,
|
|
||||||
"narHash": "sha256-urV51uWH7fVnhIvsZIELIYalMYsyr2FCalvlRTzqWRw=",
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "36ab78dab7da2e4e27911007033713bab534187b",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "NixOS",
|
|
||||||
"ref": "nixos-25.05",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"systems": {
|
"systems": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1681028828,
|
"lastModified": 1681028828,
|
||||||
@@ -961,6 +975,21 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"systems_7": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"treefmt-nix": {
|
"treefmt-nix": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
@@ -1007,8 +1036,8 @@
|
|||||||
"tuicr": {
|
"tuicr": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"naersk": "naersk_2",
|
"naersk": "naersk_2",
|
||||||
"nixpkgs": "nixpkgs_6",
|
"nixpkgs": "nixpkgs_7",
|
||||||
"utils": "utils"
|
"utils": "utils_2"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772695807,
|
"lastModified": 1772695807,
|
||||||
@@ -1026,7 +1055,25 @@
|
|||||||
},
|
},
|
||||||
"utils": {
|
"utils": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"systems": "systems_5"
|
"systems": "systems"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1731533236,
|
||||||
|
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"utils_2": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems_6"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1731533236,
|
"lastModified": 1731533236,
|
||||||
@@ -1045,8 +1092,8 @@
|
|||||||
"zjstatus": {
|
"zjstatus": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"crane": "crane",
|
"crane": "crane",
|
||||||
"flake-utils": "flake-utils_3",
|
"flake-utils": "flake-utils_2",
|
||||||
"nixpkgs": "nixpkgs_7",
|
"nixpkgs": "nixpkgs_8",
|
||||||
"rust-overlay": "rust-overlay"
|
"rust-overlay": "rust-overlay"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
|
|||||||
184
flake.nix
184
flake.nix
@@ -1,168 +1,58 @@
|
|||||||
|
# DO-NOT-EDIT. This file was auto-generated using github:vic/flake-file.
|
||||||
|
# Use `nix run .#write-flake` to regenerate it.
|
||||||
{
|
{
|
||||||
description = "Configuration for my macOS laptops and NixOS server";
|
outputs = inputs: inputs.flake-parts.lib.mkFlake {inherit inputs;} (inputs.import-tree ./modules);
|
||||||
|
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:nixos/nixpkgs/master";
|
|
||||||
flake-parts.url = "github:hercules-ci/flake-parts";
|
|
||||||
sops-nix = {
|
|
||||||
url = "github:Mic92/sops-nix";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
};
|
|
||||||
home-manager = {
|
|
||||||
url = "github:nix-community/home-manager";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
};
|
|
||||||
darwin = {
|
darwin = {
|
||||||
url = "github:LnL7/nix-darwin/master";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
url = "github:LnL7/nix-darwin/master";
|
||||||
};
|
};
|
||||||
nix-homebrew.url = "github:zhaofengli-wip/nix-homebrew";
|
den.url = "github:vic/den";
|
||||||
homebrew-core = {
|
deploy-rs.url = "github:serokell/deploy-rs";
|
||||||
url = "github:homebrew/homebrew-core";
|
disko = {
|
||||||
flake = false;
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
url = "github:nix-community/disko";
|
||||||
|
};
|
||||||
|
flake-aspects.url = "github:vic/flake-aspects";
|
||||||
|
flake-file.url = "github:vic/flake-file";
|
||||||
|
flake-parts = {
|
||||||
|
inputs.nixpkgs-lib.follows = "nixpkgs";
|
||||||
|
url = "github:hercules-ci/flake-parts";
|
||||||
|
};
|
||||||
|
himalaya.url = "github:pimalaya/himalaya";
|
||||||
|
home-manager = {
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
url = "github:nix-community/home-manager";
|
||||||
};
|
};
|
||||||
homebrew-cask = {
|
homebrew-cask = {
|
||||||
|
flake = false;
|
||||||
url = "github:homebrew/homebrew-cask";
|
url = "github:homebrew/homebrew-cask";
|
||||||
|
};
|
||||||
|
homebrew-core = {
|
||||||
flake = false;
|
flake = false;
|
||||||
|
url = "github:homebrew/homebrew-core";
|
||||||
};
|
};
|
||||||
nixvim.url = "github:nix-community/nixvim";
|
import-tree.url = "github:vic/import-tree";
|
||||||
zjstatus.url = "github:dj95/zjstatus";
|
|
||||||
llm-agents.url = "github:numtide/llm-agents.nix";
|
|
||||||
disko = {
|
|
||||||
url = "github:nix-community/disko";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
};
|
|
||||||
colmena = {
|
|
||||||
url = "github:zhaofengli/colmena";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
};
|
|
||||||
jj-ryu = {
|
jj-ryu = {
|
||||||
url = "github:dmmulroy/jj-ryu";
|
|
||||||
flake = false;
|
flake = false;
|
||||||
|
url = "github:dmmulroy/jj-ryu";
|
||||||
};
|
};
|
||||||
jj-starship.url = "github:dmmulroy/jj-starship";
|
jj-starship.url = "github:dmmulroy/jj-starship";
|
||||||
himalaya.url = "github:pimalaya/himalaya";
|
llm-agents.url = "github:numtide/llm-agents.nix";
|
||||||
naersk = {
|
naersk = {
|
||||||
url = "github:nix-community/naersk/master";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
url = "github:nix-community/naersk/master";
|
||||||
|
};
|
||||||
|
nix-homebrew.url = "github:zhaofengli-wip/nix-homebrew";
|
||||||
|
nixpkgs.url = "github:nixos/nixpkgs/master";
|
||||||
|
nixpkgs-lib.follows = "nixpkgs";
|
||||||
|
nixvim.url = "github:nix-community/nixvim";
|
||||||
|
sops-nix = {
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
url = "github:Mic92/sops-nix";
|
||||||
};
|
};
|
||||||
tuicr.url = "github:agavra/tuicr";
|
tuicr.url = "github:agavra/tuicr";
|
||||||
|
zjstatus.url = "github:dj95/zjstatus";
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = inputs @ {flake-parts, ...}:
|
|
||||||
flake-parts.lib.mkFlake {inherit inputs;} (
|
|
||||||
let
|
|
||||||
inherit (inputs.nixpkgs) lib;
|
|
||||||
constants = import ./lib/constants.nix;
|
|
||||||
inherit (constants) user;
|
|
||||||
|
|
||||||
darwinHosts = ["chidi" "jason"];
|
|
||||||
nixosHosts = ["michael" "tahani"];
|
|
||||||
|
|
||||||
overlays = import ./overlays {inherit inputs;};
|
|
||||||
nixpkgsConfig = hostPlatform: {
|
|
||||||
nixpkgs = {inherit hostPlatform overlays;};
|
|
||||||
};
|
|
||||||
in {
|
|
||||||
systems = [
|
|
||||||
"x86_64-linux"
|
|
||||||
"aarch64-darwin"
|
|
||||||
];
|
|
||||||
|
|
||||||
flake.darwinConfigurations =
|
|
||||||
lib.genAttrs darwinHosts (
|
|
||||||
hostname:
|
|
||||||
inputs.darwin.lib.darwinSystem {
|
|
||||||
specialArgs = {inherit inputs user hostname constants;};
|
|
||||||
modules = [
|
|
||||||
inputs.home-manager.darwinModules.home-manager
|
|
||||||
inputs.nix-homebrew.darwinModules.nix-homebrew
|
|
||||||
(nixpkgsConfig "aarch64-darwin")
|
|
||||||
{
|
|
||||||
nix-homebrew = {
|
|
||||||
inherit user;
|
|
||||||
enable = true;
|
|
||||||
mutableTaps = true;
|
|
||||||
taps = {
|
|
||||||
"homebrew/homebrew-core" = inputs.homebrew-core;
|
|
||||||
"homebrew/homebrew-cask" = inputs.homebrew-cask;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
./hosts/${hostname}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
flake.nixosConfigurations =
|
|
||||||
lib.genAttrs nixosHosts (
|
|
||||||
hostname:
|
|
||||||
lib.nixosSystem {
|
|
||||||
specialArgs = {inherit inputs user hostname constants;};
|
|
||||||
modules = [
|
|
||||||
inputs.home-manager.nixosModules.home-manager
|
|
||||||
(nixpkgsConfig "x86_64-linux")
|
|
||||||
./hosts/${hostname}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
flake.colmena =
|
|
||||||
{
|
|
||||||
meta = {
|
|
||||||
nixpkgs = inputs.nixpkgs.legacyPackages.x86_64-linux;
|
|
||||||
specialArgs = {inherit inputs user constants;};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// lib.genAttrs nixosHosts (
|
|
||||||
hostname: {
|
|
||||||
deployment = {
|
|
||||||
targetHost = hostname;
|
|
||||||
targetUser = user;
|
|
||||||
};
|
|
||||||
imports = [
|
|
||||||
inputs.home-manager.nixosModules.home-manager
|
|
||||||
(nixpkgsConfig "x86_64-linux")
|
|
||||||
{_module.args.hostname = hostname;}
|
|
||||||
./hosts/${hostname}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
flake.nixosModules = {
|
|
||||||
pgbackrest = ./modules/pgbackrest.nix;
|
|
||||||
};
|
|
||||||
|
|
||||||
flake.overlays = {
|
|
||||||
default = lib.composeManyExtensions overlays;
|
|
||||||
list = overlays;
|
|
||||||
};
|
|
||||||
|
|
||||||
flake.lib = {inherit constants;};
|
|
||||||
|
|
||||||
perSystem = {
|
|
||||||
pkgs,
|
|
||||||
system,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
mkApp = name: {
|
|
||||||
type = "app";
|
|
||||||
program = "${(pkgs.writeShellScriptBin name ''
|
|
||||||
PATH=${pkgs.git}/bin:$PATH
|
|
||||||
echo "Running ${name} for ${system}"
|
|
||||||
exec ${inputs.self}/apps/${system}/${name} "$@"
|
|
||||||
'')}/bin/${name}";
|
|
||||||
};
|
|
||||||
|
|
||||||
appNames = [
|
|
||||||
"apply"
|
|
||||||
"build"
|
|
||||||
"build-switch"
|
|
||||||
"rollback"
|
|
||||||
];
|
|
||||||
in {
|
|
||||||
apps = pkgs.lib.genAttrs appNames mkApp;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,57 +0,0 @@
|
|||||||
{
|
|
||||||
pkgs,
|
|
||||||
inputs,
|
|
||||||
user,
|
|
||||||
hostname,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
imports = [
|
|
||||||
./secrets.nix
|
|
||||||
../../profiles/core.nix
|
|
||||||
../../profiles/darwin.nix
|
|
||||||
../../profiles/dock.nix
|
|
||||||
../../profiles/homebrew.nix
|
|
||||||
../../profiles/tailscale.nix
|
|
||||||
inputs.sops-nix.darwinModules.sops
|
|
||||||
];
|
|
||||||
|
|
||||||
networking.hostName = hostname;
|
|
||||||
networking.computerName = hostname;
|
|
||||||
|
|
||||||
home-manager.users.${user} = {
|
|
||||||
imports = [
|
|
||||||
../../profiles/atuin.nix
|
|
||||||
../../profiles/aerospace.nix
|
|
||||||
../../profiles/bash.nix
|
|
||||||
../../profiles/bat.nix
|
|
||||||
../../profiles/direnv.nix
|
|
||||||
../../profiles/nushell.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/claude-code.nix
|
|
||||||
../../profiles/ripgrep.nix
|
|
||||||
../../profiles/ssh.nix
|
|
||||||
../../profiles/starship.nix
|
|
||||||
../../profiles/yazi.nix
|
|
||||||
../../profiles/zellij.nix
|
|
||||||
../../profiles/zk.nix
|
|
||||||
../../profiles/zoxide.nix
|
|
||||||
../../profiles/zsh.nix
|
|
||||||
inputs.nixvim.homeModules.nixvim
|
|
||||||
];
|
|
||||||
fonts.fontconfig.enable = true;
|
|
||||||
programs.git.settings.user.email = "christoph@tuist.dev";
|
|
||||||
};
|
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [
|
|
||||||
slack
|
|
||||||
];
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
{user, ...}: {
|
|
||||||
sops.age.keyFile = "/Users/${user}/.config/sops/age/keys.txt";
|
|
||||||
sops.age.sshKeyPaths = [];
|
|
||||||
sops.gnupg.sshKeyPaths = [];
|
|
||||||
}
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
{
|
|
||||||
inputs,
|
|
||||||
user,
|
|
||||||
hostname,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
imports = [
|
|
||||||
./secrets.nix
|
|
||||||
../../profiles/core.nix
|
|
||||||
../../profiles/darwin.nix
|
|
||||||
../../profiles/dock.nix
|
|
||||||
../../profiles/homebrew.nix
|
|
||||||
../../profiles/tailscale.nix
|
|
||||||
inputs.sops-nix.darwinModules.sops
|
|
||||||
];
|
|
||||||
|
|
||||||
networking.hostName = hostname;
|
|
||||||
networking.computerName = hostname;
|
|
||||||
|
|
||||||
home-manager.users.${user} = {
|
|
||||||
imports = [
|
|
||||||
../../profiles/atuin.nix
|
|
||||||
../../profiles/aerospace.nix
|
|
||||||
../../profiles/bash.nix
|
|
||||||
../../profiles/bat.nix
|
|
||||||
../../profiles/direnv.nix
|
|
||||||
../../profiles/nushell.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/claude-code.nix
|
|
||||||
../../profiles/ripgrep.nix
|
|
||||||
../../profiles/ssh.nix
|
|
||||||
../../profiles/starship.nix
|
|
||||||
../../profiles/yazi.nix
|
|
||||||
../../profiles/zellij.nix
|
|
||||||
../../profiles/zk.nix
|
|
||||||
../../profiles/zoxide.nix
|
|
||||||
../../profiles/zsh.nix
|
|
||||||
inputs.nixvim.homeModules.nixvim
|
|
||||||
];
|
|
||||||
fonts.fontconfig.enable = true;
|
|
||||||
programs.git.settings.user.email = "christoph@schmatzler.com";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
{user, ...}: {
|
|
||||||
sops.age.keyFile = "/Users/${user}/.config/sops/age/keys.txt";
|
|
||||||
sops.age.sshKeyPaths = [];
|
|
||||||
sops.gnupg.sshKeyPaths = [];
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
{
|
|
||||||
config,
|
|
||||||
inputs,
|
|
||||||
user,
|
|
||||||
hostname,
|
|
||||||
modulesPath,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
imports = [
|
|
||||||
(modulesPath + "/installer/scan/not-detected.nix")
|
|
||||||
(modulesPath + "/profiles/qemu-guest.nix")
|
|
||||||
./disk-config.nix
|
|
||||||
./hardware-configuration.nix
|
|
||||||
./secrets.nix
|
|
||||||
../../modules/gitea.nix
|
|
||||||
../../profiles/core.nix
|
|
||||||
../../profiles/fail2ban.nix
|
|
||||||
../../profiles/nixos.nix
|
|
||||||
../../profiles/openssh.nix
|
|
||||||
../../profiles/tailscale.nix
|
|
||||||
inputs.disko.nixosModules.disko
|
|
||||||
inputs.sops-nix.nixosModules.sops
|
|
||||||
];
|
|
||||||
|
|
||||||
my.gitea = {
|
|
||||||
enable = true;
|
|
||||||
litestream = {
|
|
||||||
bucket = "michael-gitea-litestream";
|
|
||||||
secretFile = config.sops.secrets.michael-gitea-litestream.path;
|
|
||||||
};
|
|
||||||
restic = {
|
|
||||||
bucket = "michael-gitea-repositories";
|
|
||||||
passwordFile = config.sops.secrets.michael-gitea-restic-password.path;
|
|
||||||
environmentFile = config.sops.secrets.michael-gitea-restic-env.path;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
networking.hostName = hostname;
|
|
||||||
|
|
||||||
home-manager.users.${user} = {
|
|
||||||
imports = [
|
|
||||||
../../profiles/nushell.nix
|
|
||||||
../../profiles/home.nix
|
|
||||||
../../profiles/ssh.nix
|
|
||||||
inputs.nixvim.homeModules.nixvim
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
{...}: {
|
|
||||||
sops.secrets = {
|
|
||||||
michael-gitea-litestream = {
|
|
||||||
sopsFile = ../../secrets/michael-gitea-litestream;
|
|
||||||
format = "binary";
|
|
||||||
owner = "gitea";
|
|
||||||
group = "gitea";
|
|
||||||
};
|
|
||||||
michael-gitea-restic-password = {
|
|
||||||
sopsFile = ../../secrets/michael-gitea-restic-password;
|
|
||||||
format = "binary";
|
|
||||||
owner = "gitea";
|
|
||||||
group = "gitea";
|
|
||||||
};
|
|
||||||
michael-gitea-restic-env = {
|
|
||||||
sopsFile = ../../secrets/michael-gitea-restic-env;
|
|
||||||
format = "binary";
|
|
||||||
owner = "gitea";
|
|
||||||
group = "gitea";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
{
|
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
inputs,
|
|
||||||
user,
|
|
||||||
hostname,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
himalaya = config.home-manager.users.${user}.programs.himalaya.package;
|
|
||||||
opencode = inputs.llm-agents.packages.${pkgs.stdenv.hostPlatform.system}.opencode;
|
|
||||||
in {
|
|
||||||
imports = [
|
|
||||||
./adguardhome.nix
|
|
||||||
./cache.nix
|
|
||||||
./networking.nix
|
|
||||||
./paperless.nix
|
|
||||||
./secrets.nix
|
|
||||||
../../profiles/core.nix
|
|
||||||
../../profiles/nixos.nix
|
|
||||||
../../profiles/openssh.nix
|
|
||||||
../../profiles/tailscale.nix
|
|
||||||
inputs.sops-nix.nixosModules.sops
|
|
||||||
];
|
|
||||||
|
|
||||||
networking.hostName = hostname;
|
|
||||||
|
|
||||||
home-manager.users.${user} = {
|
|
||||||
imports = [
|
|
||||||
../../profiles/atuin.nix
|
|
||||||
../../profiles/bash.nix
|
|
||||||
../../profiles/bat.nix
|
|
||||||
../../profiles/direnv.nix
|
|
||||||
../../profiles/nushell.nix
|
|
||||||
../../profiles/fzf.nix
|
|
||||||
../../profiles/git.nix
|
|
||||||
../../profiles/himalaya.nix
|
|
||||||
../../profiles/mbsync.nix
|
|
||||||
../../profiles/home.nix
|
|
||||||
../../profiles/jjui.nix
|
|
||||||
../../profiles/jujutsu.nix
|
|
||||||
../../profiles/lazygit.nix
|
|
||||||
../../profiles/mise.nix
|
|
||||||
../../profiles/neovim
|
|
||||||
../../profiles/opencode.nix
|
|
||||||
../../profiles/claude-code.nix
|
|
||||||
../../profiles/ripgrep.nix
|
|
||||||
../../profiles/ssh.nix
|
|
||||||
../../profiles/starship.nix
|
|
||||||
../../profiles/yazi.nix
|
|
||||||
../../profiles/zellij.nix
|
|
||||||
../../profiles/zk.nix
|
|
||||||
../../profiles/zoxide.nix
|
|
||||||
../../profiles/zsh.nix
|
|
||||||
inputs.nixvim.homeModules.nixvim
|
|
||||||
];
|
|
||||||
|
|
||||||
programs.git.settings.user.email = "christoph@schmatzler.com";
|
|
||||||
|
|
||||||
systemd.user.services.opencode-inbox-triage = {
|
|
||||||
Unit = {
|
|
||||||
Description = "OpenCode inbox triage";
|
|
||||||
};
|
|
||||||
Service = {
|
|
||||||
Type = "oneshot";
|
|
||||||
ExecStart = "${opencode}/bin/opencode run --command inbox-triage";
|
|
||||||
Environment = "PATH=${himalaya}/bin:${opencode}/bin:${pkgs.coreutils}/bin";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.user.timers.opencode-inbox-triage = {
|
|
||||||
Unit = {
|
|
||||||
Description = "Run OpenCode inbox triage every 10 minutes";
|
|
||||||
};
|
|
||||||
Timer = {
|
|
||||||
OnCalendar = "*:0/10";
|
|
||||||
Persistent = true;
|
|
||||||
};
|
|
||||||
Install = {
|
|
||||||
WantedBy = ["timers.target"];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
virtualisation.docker.enable = true;
|
|
||||||
|
|
||||||
users.users.${user}.extraGroups = ["docker"];
|
|
||||||
|
|
||||||
swapDevices = [
|
|
||||||
{
|
|
||||||
device = "/swapfile";
|
|
||||||
size = 16 * 1024;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{user, ...}: {
|
|
||||||
sops.secrets = {
|
|
||||||
tahani-paperless-password = {
|
|
||||||
sopsFile = ../../secrets/tahani-paperless-password;
|
|
||||||
format = "binary";
|
|
||||||
};
|
|
||||||
tahani-email-password = {
|
|
||||||
sopsFile = ../../secrets/tahani-email-password;
|
|
||||||
format = "binary";
|
|
||||||
owner = user;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -2,7 +2,6 @@
|
|||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
user,
|
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
with lib; let
|
with lib; let
|
||||||
@@ -46,7 +45,7 @@ in {
|
|||||||
{path = "/System/Applications/Music.app/";}
|
{path = "/System/Applications/Music.app/";}
|
||||||
{path = "/System/Applications/System Settings.app/";}
|
{path = "/System/Applications/System Settings.app/";}
|
||||||
{
|
{
|
||||||
path = "${config.users.users.${user}.home}/Downloads";
|
path = "${config.users.users.cschmatzler.home}/Downloads";
|
||||||
section = "others";
|
section = "others";
|
||||||
options = "--sort name --view grid --display stack";
|
options = "--sort name --view grid --display stack";
|
||||||
}
|
}
|
||||||
@@ -57,7 +56,7 @@ in {
|
|||||||
mkOption {
|
mkOption {
|
||||||
description = "Username to apply the dock settings to";
|
description = "Username to apply the dock settings to";
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = user;
|
default = "cschmatzler";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -11,7 +11,6 @@ with pkgs;
|
|||||||
alejandra
|
alejandra
|
||||||
ast-grep
|
ast-grep
|
||||||
bun
|
bun
|
||||||
colmena
|
|
||||||
delta
|
delta
|
||||||
devenv
|
devenv
|
||||||
dig
|
dig
|
||||||
0
modules/_opencode/tool/.gitkeep
Normal file
0
modules/_opencode/tool/.gitkeep
Normal file
130
modules/ai-tools.nix
Normal file
130
modules/ai-tools.nix
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
{inputs, ...}: {
|
||||||
|
den.aspects.ai-tools.homeManager = {
|
||||||
|
pkgs,
|
||||||
|
inputs',
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
programs.opencode = {
|
||||||
|
enable = true;
|
||||||
|
package = inputs'.llm-agents.packages.opencode;
|
||||||
|
settings = {
|
||||||
|
model = "anthropic/claude-opus-4-6";
|
||||||
|
small_model = "anthropic/claude-haiku-4-5";
|
||||||
|
theme = "catppuccin";
|
||||||
|
plugin = ["oh-my-opencode@latest" "opencode-anthropic-auth@latest"];
|
||||||
|
permission = {
|
||||||
|
read = {
|
||||||
|
"*" = "allow";
|
||||||
|
"*.env" = "deny";
|
||||||
|
"*.env.*" = "deny";
|
||||||
|
"*.envrc" = "deny";
|
||||||
|
"secrets/*" = "deny";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
agent = {
|
||||||
|
plan = {
|
||||||
|
model = "anthropic/claude-opus-4-6";
|
||||||
|
};
|
||||||
|
explore = {
|
||||||
|
model = "anthropic/claude-haiku-4-5";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
instructions = [
|
||||||
|
"CLAUDE.md"
|
||||||
|
"AGENT.md"
|
||||||
|
# "AGENTS.md"
|
||||||
|
"AGENTS.local.md"
|
||||||
|
];
|
||||||
|
formatter = {
|
||||||
|
mix = {
|
||||||
|
disabled = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
mcp = {
|
||||||
|
opensrc = {
|
||||||
|
enabled = true;
|
||||||
|
type = "local";
|
||||||
|
command = ["bunx" "opensrc-mcp"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
home.packages = [
|
||||||
|
inputs'.llm-agents.packages.claude-code
|
||||||
|
];
|
||||||
|
|
||||||
|
xdg.configFile = {
|
||||||
|
"opencode/agent" = {
|
||||||
|
source = ./_opencode/agent;
|
||||||
|
recursive = true;
|
||||||
|
};
|
||||||
|
"opencode/command" = {
|
||||||
|
source = ./_opencode/command;
|
||||||
|
recursive = true;
|
||||||
|
};
|
||||||
|
"opencode/skill" = {
|
||||||
|
source = ./_opencode/skill;
|
||||||
|
recursive = true;
|
||||||
|
};
|
||||||
|
"opencode/tool" = {
|
||||||
|
source = ./_opencode/tool;
|
||||||
|
recursive = true;
|
||||||
|
};
|
||||||
|
"opencode/plugin" = {
|
||||||
|
source = ./_opencode/plugin;
|
||||||
|
recursive = true;
|
||||||
|
};
|
||||||
|
"opencode/AGENTS.md".source = ./_opencode/AGENTS.md;
|
||||||
|
"opencode/oh-my-opencode.json".text =
|
||||||
|
builtins.toJSON {
|
||||||
|
"$schema" = "https://raw.githubusercontent.com/code-yeongyu/oh-my-opencode/master/assets/oh-my-opencode.schema.json";
|
||||||
|
disabled_skills = ["playwright" "dev-browser"];
|
||||||
|
git_master = {
|
||||||
|
commit_footer = false;
|
||||||
|
include_co_authored_by = false;
|
||||||
|
};
|
||||||
|
runtime_fallback = true;
|
||||||
|
agents = {
|
||||||
|
explore = {
|
||||||
|
model = "opencode-go/minimax-m2.5";
|
||||||
|
fallback_models = ["anthropic/claude-haiku-4-5"];
|
||||||
|
};
|
||||||
|
librarian = {
|
||||||
|
model = "opencode-go/minimax-m2.5";
|
||||||
|
fallback_models = ["opencode-go/glm-5"];
|
||||||
|
};
|
||||||
|
sisyphus = {
|
||||||
|
fallback_models = ["opencode-go/kimi-k2.5" "opencode-go/glm-5"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
categories = {
|
||||||
|
"visual-engineering" = {
|
||||||
|
fallback_models = ["opencode-go/glm-5" "opencode-go/kimi-k2.5"];
|
||||||
|
};
|
||||||
|
ultrabrain = {
|
||||||
|
fallback_models = ["opencode-go/kimi-k2.5" "opencode-go/glm-5"];
|
||||||
|
};
|
||||||
|
deep = {
|
||||||
|
fallback_models = ["opencode-go/kimi-k2.5" "opencode-go/glm-5"];
|
||||||
|
};
|
||||||
|
artistry = {
|
||||||
|
fallback_models = ["opencode-go/kimi-k2.5" "opencode-go/glm-5"];
|
||||||
|
};
|
||||||
|
quick = {
|
||||||
|
fallback_models = ["opencode-go/minimax-m2.5"];
|
||||||
|
};
|
||||||
|
"unspecified-low" = {
|
||||||
|
fallback_models = ["opencode-go/minimax-m2.5" "opencode-go/kimi-k2.5"];
|
||||||
|
};
|
||||||
|
"unspecified-high" = {
|
||||||
|
fallback_models = ["opencode-go/kimi-k2.5" "opencode-go/glm-5"];
|
||||||
|
};
|
||||||
|
writing = {
|
||||||
|
fallback_models = ["opencode-go/kimi-k2.5" "opencode-go/minimax-m2.5"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
26
modules/apps.nix
Normal file
26
modules/apps.nix
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{inputs, ...}: {
|
||||||
|
perSystem = {
|
||||||
|
pkgs,
|
||||||
|
system,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
mkApp = name: {
|
||||||
|
type = "app";
|
||||||
|
program = "${(pkgs.writeShellScriptBin name ''
|
||||||
|
PATH=${pkgs.git}/bin:$PATH
|
||||||
|
echo "Running ${name} for ${system}"
|
||||||
|
exec ${inputs.self}/apps/${system}/${name} "$@"
|
||||||
|
'')}/bin/${name}";
|
||||||
|
};
|
||||||
|
appNames = ["apply" "build" "build-switch" "rollback"];
|
||||||
|
in {
|
||||||
|
apps =
|
||||||
|
pkgs.lib.genAttrs appNames mkApp
|
||||||
|
// {
|
||||||
|
deploy = {
|
||||||
|
type = "app";
|
||||||
|
program = "${inputs.deploy-rs.packages.${system}.deploy-rs}/bin/deploy";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
17
modules/atuin.nix
Normal file
17
modules/atuin.nix
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{...}: {
|
||||||
|
den.aspects.atuin.homeManager = {...}: {
|
||||||
|
programs.atuin = {
|
||||||
|
enable = true;
|
||||||
|
enableNushellIntegration = true;
|
||||||
|
flags = [
|
||||||
|
"--disable-up-arrow"
|
||||||
|
];
|
||||||
|
settings = {
|
||||||
|
style = "compact";
|
||||||
|
inline_height = 0;
|
||||||
|
show_help = false;
|
||||||
|
show_tabs = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
29
modules/chidi.nix
Normal file
29
modules/chidi.nix
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
{den, ...}: {
|
||||||
|
den.aspects.chidi.includes = [
|
||||||
|
den.aspects.darwin-system
|
||||||
|
den.aspects.core
|
||||||
|
den.aspects.tailscale
|
||||||
|
den.aspects.desktop
|
||||||
|
den.aspects.terminal
|
||||||
|
den.aspects.atuin
|
||||||
|
den.aspects.dev-tools
|
||||||
|
den.aspects.neovim
|
||||||
|
den.aspects.ai-tools
|
||||||
|
den.aspects.zellij
|
||||||
|
den.aspects.zk
|
||||||
|
];
|
||||||
|
|
||||||
|
den.aspects.chidi.darwin = {pkgs, ...}: {
|
||||||
|
networking.hostName = "chidi";
|
||||||
|
networking.computerName = "chidi";
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
slack
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
den.aspects.chidi.homeManager = {...}: {
|
||||||
|
fonts.fontconfig.enable = true;
|
||||||
|
programs.git.settings.user.email = "christoph@tuist.dev";
|
||||||
|
};
|
||||||
|
}
|
||||||
33
modules/core.nix
Normal file
33
modules/core.nix
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
{...}: {
|
||||||
|
den.aspects.core.os = {pkgs, ...}: {
|
||||||
|
programs.fish.enable = true;
|
||||||
|
environment.shells = [pkgs.nushell];
|
||||||
|
|
||||||
|
nixpkgs = {
|
||||||
|
config = {
|
||||||
|
allowUnfree = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
nix = {
|
||||||
|
package = pkgs.nix;
|
||||||
|
settings = {
|
||||||
|
substituters = [
|
||||||
|
"https://nix-community.cachix.org"
|
||||||
|
"https://cache.nixos.org"
|
||||||
|
];
|
||||||
|
trusted-public-keys = [
|
||||||
|
"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
|
||||||
|
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
|
||||||
|
];
|
||||||
|
};
|
||||||
|
gc = {
|
||||||
|
automatic = true;
|
||||||
|
options = "--delete-older-than 30d";
|
||||||
|
};
|
||||||
|
extraOptions = ''
|
||||||
|
experimental-features = nix-command flakes
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,17 +1,14 @@
|
|||||||
{
|
{inputs, ...}: {
|
||||||
pkgs,
|
den.aspects.darwin-system.darwin = {pkgs, ...}: {
|
||||||
inputs,
|
imports = [
|
||||||
user,
|
inputs.nix-homebrew.darwinModules.nix-homebrew
|
||||||
constants,
|
inputs.home-manager.darwinModules.home-manager
|
||||||
...
|
./_darwin/dock.nix
|
||||||
}: {
|
];
|
||||||
home-manager.extraSpecialArgs = {inherit user constants inputs;};
|
|
||||||
|
|
||||||
system = {
|
system.primaryUser = "cschmatzler";
|
||||||
primaryUser = user;
|
|
||||||
stateVersion = constants.stateVersions.darwin;
|
|
||||||
|
|
||||||
defaults = {
|
system.defaults = {
|
||||||
NSGlobalDomain = {
|
NSGlobalDomain = {
|
||||||
AppleInterfaceStyle = null;
|
AppleInterfaceStyle = null;
|
||||||
AppleShowAllExtensions = true;
|
AppleShowAllExtensions = true;
|
||||||
@@ -103,23 +100,42 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
nix = {
|
nix = {
|
||||||
settings.trusted-users = ["@admin" "${user}"];
|
settings.trusted-users = ["@admin" "cschmatzler"];
|
||||||
gc.interval = {
|
gc.interval = {
|
||||||
Weekday = 0;
|
Weekday = 0;
|
||||||
Hour = 2;
|
Hour = 2;
|
||||||
Minute = 0;
|
Minute = 0;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
users.users.cschmatzler = {
|
||||||
|
name = "cschmatzler";
|
||||||
|
home = "/Users/cschmatzler";
|
||||||
|
isHidden = false;
|
||||||
|
shell = pkgs.nushell;
|
||||||
|
};
|
||||||
|
|
||||||
|
home-manager.useGlobalPkgs = true;
|
||||||
|
|
||||||
|
nix-homebrew = {
|
||||||
|
enable = true;
|
||||||
|
user = "cschmatzler";
|
||||||
|
mutableTaps = true;
|
||||||
|
taps = {
|
||||||
|
"homebrew/homebrew-core" = inputs.homebrew-core;
|
||||||
|
"homebrew/homebrew-cask" = inputs.homebrew-cask;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
homebrew = {
|
||||||
|
enable = true;
|
||||||
|
casks = [
|
||||||
|
"ghostty@tip"
|
||||||
|
"helium-browser"
|
||||||
|
"tidal"
|
||||||
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
users.users.${user} = {
|
|
||||||
name = user;
|
|
||||||
home = "/Users/${user}";
|
|
||||||
isHidden = false;
|
|
||||||
shell = pkgs.nushell;
|
|
||||||
};
|
|
||||||
|
|
||||||
home-manager.useGlobalPkgs = true;
|
|
||||||
}
|
}
|
||||||
31
modules/defaults.nix
Normal file
31
modules/defaults.nix
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
den,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
options.flake = {
|
||||||
|
darwinConfigurations =
|
||||||
|
lib.mkOption {
|
||||||
|
type = lib.types.lazyAttrsOf lib.types.raw;
|
||||||
|
default = {};
|
||||||
|
};
|
||||||
|
deploy =
|
||||||
|
lib.mkOption {
|
||||||
|
type = lib.types.lazyAttrsOf lib.types.raw;
|
||||||
|
default = {};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
den.default.nixos.system.stateVersion = "25.11";
|
||||||
|
den.default.darwin.system.stateVersion = 6;
|
||||||
|
den.default.homeManager.home.stateVersion = "25.11";
|
||||||
|
|
||||||
|
den.default.includes = [
|
||||||
|
den.provides.define-user
|
||||||
|
den.provides.inputs'
|
||||||
|
];
|
||||||
|
|
||||||
|
den.base.user.classes = lib.mkDefault ["homeManager"];
|
||||||
|
};
|
||||||
|
}
|
||||||
61
modules/dendritic.nix
Normal file
61
modules/dendritic.nix
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
{inputs, ...}: {
|
||||||
|
imports = [
|
||||||
|
inputs.den.flakeModule
|
||||||
|
(inputs.flake-file.flakeModules.dendritic or {})
|
||||||
|
];
|
||||||
|
|
||||||
|
# Declare all framework and module inputs via flake-file
|
||||||
|
flake-file.inputs = {
|
||||||
|
den.url = "github:vic/den";
|
||||||
|
flake-file.url = "github:vic/flake-file";
|
||||||
|
import-tree.url = "github:vic/import-tree";
|
||||||
|
flake-aspects.url = "github:vic/flake-aspects";
|
||||||
|
nixpkgs.url = "github:nixos/nixpkgs/master";
|
||||||
|
flake-parts = {
|
||||||
|
url = "github:hercules-ci/flake-parts";
|
||||||
|
inputs.nixpkgs-lib.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
home-manager = {
|
||||||
|
url = "github:nix-community/home-manager";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
darwin = {
|
||||||
|
url = "github:LnL7/nix-darwin/master";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
deploy-rs.url = "github:serokell/deploy-rs";
|
||||||
|
disko = {
|
||||||
|
url = "github:nix-community/disko";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
nix-homebrew.url = "github:zhaofengli-wip/nix-homebrew";
|
||||||
|
homebrew-core = {
|
||||||
|
url = "github:homebrew/homebrew-core";
|
||||||
|
flake = false;
|
||||||
|
};
|
||||||
|
homebrew-cask = {
|
||||||
|
url = "github:homebrew/homebrew-cask";
|
||||||
|
flake = false;
|
||||||
|
};
|
||||||
|
nixvim.url = "github:nix-community/nixvim";
|
||||||
|
llm-agents.url = "github:numtide/llm-agents.nix";
|
||||||
|
# Overlay inputs
|
||||||
|
himalaya.url = "github:pimalaya/himalaya";
|
||||||
|
jj-ryu = {
|
||||||
|
url = "github:dmmulroy/jj-ryu";
|
||||||
|
flake = false;
|
||||||
|
};
|
||||||
|
jj-starship.url = "github:dmmulroy/jj-starship";
|
||||||
|
zjstatus.url = "github:dj95/zjstatus";
|
||||||
|
tuicr.url = "github:agavra/tuicr";
|
||||||
|
naersk = {
|
||||||
|
url = "github:nix-community/naersk/master";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
# Secrets inputs
|
||||||
|
sops-nix = {
|
||||||
|
url = "github:Mic92/sops-nix";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
26
modules/deploy.nix
Normal file
26
modules/deploy.nix
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
inputs,
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
flake.deploy.nodes = {
|
||||||
|
michael = {
|
||||||
|
hostname = "michael";
|
||||||
|
sshUser = "cschmatzler";
|
||||||
|
profiles.system = {
|
||||||
|
user = "root";
|
||||||
|
path = inputs.deploy-rs.lib.x86_64-linux.activate.nixos config.flake.nixosConfigurations.michael;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
tahani = {
|
||||||
|
hostname = "tahani";
|
||||||
|
sshUser = "cschmatzler";
|
||||||
|
profiles.system = {
|
||||||
|
user = "root";
|
||||||
|
path = inputs.deploy-rs.lib.x86_64-linux.activate.nixos config.flake.nixosConfigurations.tahani;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
flake.checks.x86_64-linux = inputs.deploy-rs.lib.x86_64-linux.deployChecks config.flake.deploy;
|
||||||
|
}
|
||||||
144
modules/desktop.nix
Normal file
144
modules/desktop.nix
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
{...}: {
|
||||||
|
den.aspects.desktop.homeManager = {...}: {
|
||||||
|
programs.aerospace = {
|
||||||
|
enable = true;
|
||||||
|
launchd.enable = true;
|
||||||
|
settings = {
|
||||||
|
start-at-login = true;
|
||||||
|
accordion-padding = 30;
|
||||||
|
default-root-container-layout = "tiles";
|
||||||
|
default-root-container-orientation = "auto";
|
||||||
|
on-focused-monitor-changed = [
|
||||||
|
"move-mouse monitor-lazy-center"
|
||||||
|
];
|
||||||
|
|
||||||
|
workspace-to-monitor-force-assignment = {
|
||||||
|
"1" = "main";
|
||||||
|
"2" = "main";
|
||||||
|
"3" = "main";
|
||||||
|
"4" = "main";
|
||||||
|
"5" = "main";
|
||||||
|
"6" = "main";
|
||||||
|
"7" = "main";
|
||||||
|
"8" = "main";
|
||||||
|
"9" = "secondary";
|
||||||
|
};
|
||||||
|
|
||||||
|
gaps = {
|
||||||
|
inner = {
|
||||||
|
horizontal = 8;
|
||||||
|
vertical = 8;
|
||||||
|
};
|
||||||
|
outer = {
|
||||||
|
left = 8;
|
||||||
|
right = 8;
|
||||||
|
top = 8;
|
||||||
|
bottom = 8;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
on-window-detected = [
|
||||||
|
{
|
||||||
|
"if" = {
|
||||||
|
"app-id" = "com.apple.systempreferences";
|
||||||
|
};
|
||||||
|
run = "layout floating";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
"if" = {
|
||||||
|
"app-id" = "com.mitchellh.ghostty";
|
||||||
|
};
|
||||||
|
run = ["layout tiling" "move-node-to-workspace 3"];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
"if" = {
|
||||||
|
"app-id" = "net.imput.helium";
|
||||||
|
};
|
||||||
|
run = "move-node-to-workspace 2";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
"if" = {
|
||||||
|
"app-id" = "com.tinyspeck.slackmacgap";
|
||||||
|
};
|
||||||
|
run = "move-node-to-workspace 5";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
"if" = {
|
||||||
|
"app-id" = "net.whatsapp.WhatsApp";
|
||||||
|
};
|
||||||
|
run = "move-node-to-workspace 5";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
"if" = {
|
||||||
|
"app-id" = "com.tidal.desktop";
|
||||||
|
};
|
||||||
|
run = "move-node-to-workspace 6";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
mode = {
|
||||||
|
main.binding = {
|
||||||
|
"alt-enter" = "exec-and-forget open -a Ghostty";
|
||||||
|
"alt-h" = "focus left";
|
||||||
|
"alt-j" = "focus down";
|
||||||
|
"alt-k" = "focus up";
|
||||||
|
"alt-l" = "focus right";
|
||||||
|
"alt-shift-h" = "move left";
|
||||||
|
"alt-shift-j" = "move down";
|
||||||
|
"alt-shift-k" = "move up";
|
||||||
|
"alt-shift-l" = "move right";
|
||||||
|
"alt-ctrl-h" = "focus-monitor --wrap-around left";
|
||||||
|
"alt-ctrl-j" = "focus-monitor --wrap-around down";
|
||||||
|
"alt-ctrl-k" = "focus-monitor --wrap-around up";
|
||||||
|
"alt-ctrl-l" = "focus-monitor --wrap-around right";
|
||||||
|
"alt-ctrl-shift-h" = "move-node-to-monitor --focus-follows-window --wrap-around left";
|
||||||
|
"alt-ctrl-shift-j" = "move-node-to-monitor --focus-follows-window --wrap-around down";
|
||||||
|
"alt-ctrl-shift-k" = "move-node-to-monitor --focus-follows-window --wrap-around up";
|
||||||
|
"alt-ctrl-shift-l" = "move-node-to-monitor --focus-follows-window --wrap-around right";
|
||||||
|
"alt-space" = "layout tiles accordion";
|
||||||
|
"alt-shift-space" = "layout floating tiling";
|
||||||
|
"alt-slash" = "layout horizontal vertical";
|
||||||
|
"alt-f" = "fullscreen";
|
||||||
|
"alt-tab" = "workspace-back-and-forth";
|
||||||
|
"alt-shift-tab" = "move-workspace-to-monitor --wrap-around next";
|
||||||
|
"alt-r" = "mode resize";
|
||||||
|
"alt-shift-semicolon" = "mode service";
|
||||||
|
"alt-1" = "workspace 1";
|
||||||
|
"alt-2" = "workspace 2";
|
||||||
|
"alt-3" = "workspace 3";
|
||||||
|
"alt-4" = "workspace 4";
|
||||||
|
"alt-5" = "workspace 5";
|
||||||
|
"alt-6" = "workspace 6";
|
||||||
|
"alt-7" = "workspace 7";
|
||||||
|
"alt-8" = "workspace 8";
|
||||||
|
"alt-9" = "workspace 9";
|
||||||
|
"alt-shift-1" = "move-node-to-workspace --focus-follows-window 1";
|
||||||
|
"alt-shift-2" = "move-node-to-workspace --focus-follows-window 2";
|
||||||
|
"alt-shift-3" = "move-node-to-workspace --focus-follows-window 3";
|
||||||
|
"alt-shift-4" = "move-node-to-workspace --focus-follows-window 4";
|
||||||
|
"alt-shift-5" = "move-node-to-workspace --focus-follows-window 5";
|
||||||
|
"alt-shift-6" = "move-node-to-workspace --focus-follows-window 6";
|
||||||
|
"alt-shift-7" = "move-node-to-workspace --focus-follows-window 7";
|
||||||
|
"alt-shift-8" = "move-node-to-workspace --focus-follows-window 8";
|
||||||
|
"alt-shift-9" = "move-node-to-workspace --focus-follows-window 9";
|
||||||
|
};
|
||||||
|
resize.binding = {
|
||||||
|
"h" = "resize width -50";
|
||||||
|
"j" = "resize height +50";
|
||||||
|
"k" = "resize height -50";
|
||||||
|
"l" = "resize width +50";
|
||||||
|
"enter" = "mode main";
|
||||||
|
"esc" = "mode main";
|
||||||
|
};
|
||||||
|
service.binding = {
|
||||||
|
"esc" = "mode main";
|
||||||
|
"r" = ["reload-config" "mode main"];
|
||||||
|
"b" = ["balance-sizes" "mode main"];
|
||||||
|
"f" = ["layout floating tiling" "mode main"];
|
||||||
|
"backspace" = ["close-all-windows-but-current" "mode main"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
371
modules/dev-tools.nix
Normal file
371
modules/dev-tools.nix
Normal file
@@ -0,0 +1,371 @@
|
|||||||
|
{...}: {
|
||||||
|
den.aspects.dev-tools.homeManager = {...}: let
|
||||||
|
name = "Christoph Schmatzler";
|
||||||
|
in {
|
||||||
|
# Git configuration
|
||||||
|
programs.git = {
|
||||||
|
enable = true;
|
||||||
|
ignores = ["*.swp"];
|
||||||
|
settings = {
|
||||||
|
user.name = name;
|
||||||
|
init.defaultBranch = "main";
|
||||||
|
core = {
|
||||||
|
editor = "vim";
|
||||||
|
autocrlf = "input";
|
||||||
|
pager = "delta";
|
||||||
|
};
|
||||||
|
credential = {
|
||||||
|
helper = "!gh auth git-credential";
|
||||||
|
"https://github.com".useHttpPath = true;
|
||||||
|
"https://gist.github.com".useHttpPath = true;
|
||||||
|
};
|
||||||
|
pull.rebase = true;
|
||||||
|
rebase.autoStash = true;
|
||||||
|
interactive.diffFilter = "delta --color-only";
|
||||||
|
delta = {
|
||||||
|
navigate = true;
|
||||||
|
line-numbers = true;
|
||||||
|
syntax-theme = "GitHub";
|
||||||
|
side-by-side = true;
|
||||||
|
pager = "less -FRX";
|
||||||
|
};
|
||||||
|
pager = {
|
||||||
|
diff = "delta";
|
||||||
|
log = "delta";
|
||||||
|
show = "delta";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
lfs = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Git shell aliases
|
||||||
|
home.shellAliases = {
|
||||||
|
g = "git";
|
||||||
|
ga = "git add";
|
||||||
|
gaa = "git add --all";
|
||||||
|
gapa = "git add --patch";
|
||||||
|
gau = "git add --update";
|
||||||
|
gav = "git add --verbose";
|
||||||
|
gap = "git apply";
|
||||||
|
gapt = "git apply --3way";
|
||||||
|
gb = "git branch";
|
||||||
|
gba = "git branch --all";
|
||||||
|
gbd = "git branch --delete";
|
||||||
|
gbD = "git branch --delete --force";
|
||||||
|
gbl = "git blame -w";
|
||||||
|
gbnm = "git branch --no-merged";
|
||||||
|
gbr = "git branch --remote";
|
||||||
|
gbs = "git bisect";
|
||||||
|
gbsb = "git bisect bad";
|
||||||
|
gbsg = "git bisect good";
|
||||||
|
gbsn = "git bisect new";
|
||||||
|
gbso = "git bisect old";
|
||||||
|
gbsr = "git bisect reset";
|
||||||
|
gbss = "git bisect start";
|
||||||
|
gc = "git commit --verbose";
|
||||||
|
gca = "git commit --verbose --all";
|
||||||
|
gcam = "git commit --all --message";
|
||||||
|
gcas = "git commit --all --signoff";
|
||||||
|
gcasm = "git commit --all --signoff --message";
|
||||||
|
gcb = "git checkout -b";
|
||||||
|
gcB = "git checkout -B";
|
||||||
|
gcf = "git config --list";
|
||||||
|
gclean = "git clean --interactive -d";
|
||||||
|
gcl = "git clone --recurse-submodules";
|
||||||
|
gclf = "git clone --recursive --shallow-submodules --filter=blob:none --also-filter-submodules";
|
||||||
|
gcm = "git checkout main";
|
||||||
|
gcmsg = "git commit --message";
|
||||||
|
gcn = "git commit --verbose --no-edit";
|
||||||
|
gco = "git checkout";
|
||||||
|
gcor = "git checkout --recurse-submodules";
|
||||||
|
gcount = "git shortlog --summary --numbered";
|
||||||
|
gcp = "git cherry-pick";
|
||||||
|
gcpa = "git cherry-pick --abort";
|
||||||
|
gcpc = "git cherry-pick --continue";
|
||||||
|
gcs = "git commit --gpg-sign";
|
||||||
|
gcss = "git commit --gpg-sign --signoff";
|
||||||
|
gcssm = "git commit --gpg-sign --signoff --message";
|
||||||
|
gcsm = "git commit --signoff --message";
|
||||||
|
gd = "git diff";
|
||||||
|
gdca = "git diff --cached";
|
||||||
|
gdcw = "git diff --cached --word-diff";
|
||||||
|
gds = "git diff --staged";
|
||||||
|
gdw = "git diff --word-diff";
|
||||||
|
gdt = "git diff-tree --no-commit-id --name-only -r";
|
||||||
|
gdup = "git diff @{upstream}";
|
||||||
|
gf = "git fetch";
|
||||||
|
gfa = "git fetch --all --tags --prune";
|
||||||
|
gfo = "git fetch origin";
|
||||||
|
gg = "git gui citool";
|
||||||
|
gga = "git gui citool --amend";
|
||||||
|
ghh = "git help";
|
||||||
|
gignore = "git update-index --assume-unchanged";
|
||||||
|
gl = "git pull";
|
||||||
|
glg = "git log --stat";
|
||||||
|
glgp = "git log --stat --patch";
|
||||||
|
glgg = "git log --graph";
|
||||||
|
glgga = "git log --graph --decorate --all";
|
||||||
|
glgm = "git log --graph --max-count=10";
|
||||||
|
glo = "git log --oneline --decorate";
|
||||||
|
glog = "git log --oneline --decorate --graph";
|
||||||
|
gloga = "git log --oneline --decorate --graph --all";
|
||||||
|
glol = "git log --graph --pretty=\"%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ar) %C(bold blue)<%an>%Creset\"";
|
||||||
|
glola = "git log --graph --pretty=\"%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ar) %C(bold blue)<%an>%Creset\" --all";
|
||||||
|
glols = "git log --graph --pretty=\"%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ar) %C(bold blue)<%an>%Creset\" --stat";
|
||||||
|
glod = "git log --graph --pretty=\"%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ad) %C(bold blue)<%an>%Creset\"";
|
||||||
|
glods = "git log --graph --pretty=\"%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ad) %C(bold blue)<%an>%Creset\" --date=short";
|
||||||
|
glum = "git pull upstream main";
|
||||||
|
gm = "git merge";
|
||||||
|
gma = "git merge --abort";
|
||||||
|
gmc = "git merge --continue";
|
||||||
|
gms = "git merge --squash";
|
||||||
|
gmff = "git merge --ff-only";
|
||||||
|
gmtl = "git mergetool --no-prompt";
|
||||||
|
gmtlvim = "git mergetool --no-prompt --tool=vimdiff";
|
||||||
|
gmum = "git merge upstream/main";
|
||||||
|
gmom = "git merge origin/main";
|
||||||
|
gp = "git push";
|
||||||
|
gpd = "git push --dry-run";
|
||||||
|
gpf = "git push --force-with-lease";
|
||||||
|
gpod = "git push origin --delete";
|
||||||
|
gpr = "git pull --rebase";
|
||||||
|
gpra = "git pull --rebase --autostash";
|
||||||
|
gprav = "git pull --rebase --autostash -v";
|
||||||
|
gprom = "git pull --rebase origin main";
|
||||||
|
gpromi = "git pull --rebase=interactive origin main";
|
||||||
|
gprv = "git pull --rebase -v";
|
||||||
|
gprum = "git pull --rebase upstream main";
|
||||||
|
gprumi = "git pull --rebase=interactive upstream main";
|
||||||
|
gpv = "git push --verbose";
|
||||||
|
gpu = "git push upstream";
|
||||||
|
gr = "git remote";
|
||||||
|
gra = "git remote add";
|
||||||
|
grb = "git rebase";
|
||||||
|
grba = "git rebase --abort";
|
||||||
|
grbc = "git rebase --continue";
|
||||||
|
grbd = "git rebase develop";
|
||||||
|
grbi = "git rebase --interactive";
|
||||||
|
grbm = "git rebase main";
|
||||||
|
grbo = "git rebase --onto";
|
||||||
|
grbom = "git rebase origin/main";
|
||||||
|
grbs = "git rebase --skip";
|
||||||
|
grbum = "git rebase upstream/main";
|
||||||
|
grev = "git revert";
|
||||||
|
greva = "git revert --abort";
|
||||||
|
grevc = "git revert --continue";
|
||||||
|
grf = "git reflog";
|
||||||
|
grh = "git reset";
|
||||||
|
grhh = "git reset --hard";
|
||||||
|
grhk = "git reset --keep";
|
||||||
|
grhs = "git reset --soft";
|
||||||
|
grm = "git rm";
|
||||||
|
grmc = "git rm --cached";
|
||||||
|
grmv = "git remote rename";
|
||||||
|
grrm = "git remote remove";
|
||||||
|
grs = "git restore";
|
||||||
|
grset = "git remote set-url";
|
||||||
|
grss = "git restore --source";
|
||||||
|
grst = "git restore --staged";
|
||||||
|
gru = "git reset --";
|
||||||
|
grup = "git remote update";
|
||||||
|
grv = "git remote --verbose";
|
||||||
|
gsb = "git status --short --branch";
|
||||||
|
gsh = "git show";
|
||||||
|
gsi = "git submodule init";
|
||||||
|
gsps = "git show --pretty=short --show-signature";
|
||||||
|
gss = "git status --short";
|
||||||
|
gst = "git status";
|
||||||
|
gsta = "git stash push";
|
||||||
|
gstaa = "git stash apply";
|
||||||
|
gstall = "git stash --all";
|
||||||
|
gstc = "git stash clear";
|
||||||
|
gstd = "git stash drop";
|
||||||
|
gstl = "git stash list";
|
||||||
|
gstp = "git stash pop";
|
||||||
|
gsts = "git stash show --patch";
|
||||||
|
gstu = "git stash push --include-untracked";
|
||||||
|
gsu = "git submodule update";
|
||||||
|
gsw = "git switch";
|
||||||
|
gswc = "git switch --create";
|
||||||
|
gswd = "git switch develop";
|
||||||
|
gswm = "git switch main";
|
||||||
|
gta = "git tag --annotate";
|
||||||
|
gts = "git tag --sign";
|
||||||
|
gunignore = "git update-index --no-assume-unchanged";
|
||||||
|
gwch = "git whatchanged -p --abbrev-commit --pretty=medium";
|
||||||
|
gwt = "git worktree";
|
||||||
|
gwta = "git worktree add";
|
||||||
|
gwtls = "git worktree list";
|
||||||
|
gwtmv = "git worktree move";
|
||||||
|
gwtrm = "git worktree remove";
|
||||||
|
lg = "lazygit";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Complex git aliases that require pipes/subshells — nushell `alias` can't
|
||||||
|
# handle these, so they're defined as custom commands instead.
|
||||||
|
programs.nushell.extraConfig = ''
|
||||||
|
def ggpull [] { git pull origin (git branch --show-current | str trim) }
|
||||||
|
def ggpush [] { git push origin (git branch --show-current | str trim) }
|
||||||
|
def ggsup [] { git branch $"--set-upstream-to=origin/(git branch --show-current | str trim)" }
|
||||||
|
def gluc [] { git pull upstream (git branch --show-current | str trim) }
|
||||||
|
def gpsup [] { git push --set-upstream origin (git branch --show-current | str trim) }
|
||||||
|
def gpsupf [] { git push --set-upstream origin (git branch --show-current | str trim) --force-with-lease }
|
||||||
|
def groh [] { git reset $"origin/(git branch --show-current | str trim)" --hard }
|
||||||
|
def --env grt [] {
|
||||||
|
let toplevel = (do { git rev-parse --show-toplevel } | complete | get stdout | str trim)
|
||||||
|
if ($toplevel | is-not-empty) { cd $toplevel } else { cd . }
|
||||||
|
}
|
||||||
|
def gfg [...pattern: string] { git ls-files | lines | where {|f| $f =~ ($pattern | str join ".*") } }
|
||||||
|
def gignored [] { git ls-files -v | lines | where {|l| ($l | str substring 0..1) =~ "[a-z]" } }
|
||||||
|
def gpoat [] { git push origin --all; git push origin --tags }
|
||||||
|
def gtv [] { git tag | lines | sort }
|
||||||
|
def gwipe [] { git reset --hard; git clean --force -df }
|
||||||
|
def gunwip [] {
|
||||||
|
let msg = (git rev-list --max-count=1 --format="%s" HEAD | lines | get 1)
|
||||||
|
if ($msg | str contains "--wip--") { git reset HEAD~1 }
|
||||||
|
}
|
||||||
|
def gwip [] {
|
||||||
|
git add -A
|
||||||
|
let deleted = (git ls-files --deleted | lines)
|
||||||
|
if ($deleted | is-not-empty) { git rm ...$deleted }
|
||||||
|
git commit --no-verify --no-gpg-sign --message "--wip-- [skip ci]"
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
|
||||||
|
# Jujutsu configuration
|
||||||
|
programs.jujutsu = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
user = {
|
||||||
|
name = name;
|
||||||
|
email = "christoph@schmatzler.com";
|
||||||
|
};
|
||||||
|
git = {
|
||||||
|
sign-on-push = true;
|
||||||
|
subprocess = true;
|
||||||
|
write-change-id-header = true;
|
||||||
|
private-commits = "description(glob:'wip:*') | description(glob:'WIP:*') | description(exact:'')";
|
||||||
|
};
|
||||||
|
fsmonitor = {
|
||||||
|
backend = "watchman";
|
||||||
|
};
|
||||||
|
ui = {
|
||||||
|
default-command = "status";
|
||||||
|
diff-formatter = ":git";
|
||||||
|
pager = ["delta" "--pager" "less -FRX"];
|
||||||
|
diff-editor = ["nvim" "-c" "DiffEditor $left $right $output"];
|
||||||
|
movement = {
|
||||||
|
edit = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
aliases = {
|
||||||
|
n = ["new"];
|
||||||
|
tug = ["bookmark" "move" "--from" "closest_bookmark(@-)" "--to" "@-"];
|
||||||
|
stack = ["log" "-r" "stack()"];
|
||||||
|
retrunk = ["rebase" "-d" "trunk()"];
|
||||||
|
bm = ["bookmark"];
|
||||||
|
gf = ["git" "fetch"];
|
||||||
|
gp = ["git" "push"];
|
||||||
|
};
|
||||||
|
revset-aliases = {
|
||||||
|
"closest_bookmark(to)" = "heads(::to & bookmarks())";
|
||||||
|
"closest_pushable(to)" = "heads(::to & mutable() & ~description(exact:\"\") & (~empty() | merges()))";
|
||||||
|
"mine()" = "author(\"christoph@schmatzler.com\")";
|
||||||
|
"wip()" = "mine() ~ immutable()";
|
||||||
|
"open()" = "mine() ~ ::trunk()";
|
||||||
|
"current()" = "@:: & mutable()";
|
||||||
|
"stack()" = "reachable(@, mutable())";
|
||||||
|
};
|
||||||
|
templates = {
|
||||||
|
draft_commit_description = ''
|
||||||
|
concat(
|
||||||
|
coalesce(description, default_commit_description, "\n"),
|
||||||
|
surround(
|
||||||
|
"\nJJ: This commit contains the following changes:\n", "",
|
||||||
|
indent("JJ: ", diff.stat(72)),
|
||||||
|
),
|
||||||
|
"\nJJ: ignore-rest\n",
|
||||||
|
diff.git(),
|
||||||
|
)
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Lazygit configuration
|
||||||
|
programs.lazygit = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
git = {
|
||||||
|
commit.signOff = true;
|
||||||
|
pagers = [
|
||||||
|
{
|
||||||
|
delta = {
|
||||||
|
colorArg = "always";
|
||||||
|
pager = "DELTA_FEATURES=decorations delta --light --paging=never --line-numbers --hyperlinks --hyperlinks-file-link-format=\"lazygit-edit://{path}:{line}\"";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
gui = {
|
||||||
|
authorColors = {
|
||||||
|
"*" = "#7287fd";
|
||||||
|
};
|
||||||
|
theme = {
|
||||||
|
activeBorderColor = [
|
||||||
|
"#8839ef"
|
||||||
|
"bold"
|
||||||
|
];
|
||||||
|
inactiveBorderColor = [
|
||||||
|
"#6c6f85"
|
||||||
|
];
|
||||||
|
optionsTextColor = [
|
||||||
|
"#1e66f5"
|
||||||
|
];
|
||||||
|
selectedLineBgColor = [
|
||||||
|
"#ccd0da"
|
||||||
|
];
|
||||||
|
cherryPickedCommitBgColor = [
|
||||||
|
"#bcc0cc"
|
||||||
|
];
|
||||||
|
cherryPickedCommitFgColor = [
|
||||||
|
"#8839ef"
|
||||||
|
];
|
||||||
|
defaultFgColor = [
|
||||||
|
"#4c4f69"
|
||||||
|
];
|
||||||
|
searchingActiveBorderColor = [
|
||||||
|
"#df8e1d"
|
||||||
|
];
|
||||||
|
unstagedChangesColor = [
|
||||||
|
"#d20f39"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# JJUI configuration
|
||||||
|
programs.jjui = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Direnv configuration
|
||||||
|
programs.direnv = {
|
||||||
|
enable = true;
|
||||||
|
nix-direnv.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Mise configuration
|
||||||
|
programs.mise = {
|
||||||
|
enable = true;
|
||||||
|
enableNushellIntegration = true;
|
||||||
|
globalConfig.settings = {
|
||||||
|
auto_install = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
54
modules/email.nix
Normal file
54
modules/email.nix
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
{...}: {
|
||||||
|
den.aspects.email.homeManager = {pkgs, ...}: {
|
||||||
|
programs.himalaya = {
|
||||||
|
enable = true;
|
||||||
|
package =
|
||||||
|
pkgs.writeShellApplication {
|
||||||
|
name = "himalaya";
|
||||||
|
runtimeInputs = [pkgs.bash pkgs.coreutils pkgs.himalaya];
|
||||||
|
text = ''
|
||||||
|
exec env RUST_LOG="warn,imap_codec::response=error" ${pkgs.himalaya}/bin/himalaya "$@"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.mbsync.enable = true;
|
||||||
|
services.mbsync = {
|
||||||
|
enable = true;
|
||||||
|
frequency = "*:0/5";
|
||||||
|
};
|
||||||
|
|
||||||
|
accounts.email = {
|
||||||
|
accounts."christoph@schmatzler.com" = {
|
||||||
|
primary = true;
|
||||||
|
maildir.path = "christoph@schmatzler.com";
|
||||||
|
address = "christoph@schmatzler.com";
|
||||||
|
userName = "christoph.schmatzler@icloud.com";
|
||||||
|
realName = "Christoph Schmatzler";
|
||||||
|
passwordCommand = ["cat" "/run/secrets/tahani-email-password"];
|
||||||
|
folders = {
|
||||||
|
inbox = "INBOX";
|
||||||
|
drafts = "Drafts";
|
||||||
|
sent = "Sent Messages";
|
||||||
|
trash = "Deleted Messages";
|
||||||
|
};
|
||||||
|
smtp = {
|
||||||
|
host = "smtp.mail.me.com";
|
||||||
|
port = 587;
|
||||||
|
tls.useStartTls = true;
|
||||||
|
};
|
||||||
|
himalaya.enable = true;
|
||||||
|
mbsync = {
|
||||||
|
enable = true;
|
||||||
|
create = "both";
|
||||||
|
expunge = "both";
|
||||||
|
};
|
||||||
|
imap = {
|
||||||
|
host = "imap.mail.me.com";
|
||||||
|
port = 993;
|
||||||
|
tls.enable = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,198 +0,0 @@
|
|||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
with lib; let
|
|
||||||
cfg = config.my.gitea;
|
|
||||||
in {
|
|
||||||
options.my.gitea = {
|
|
||||||
enable = mkEnableOption "Gitea git hosting service";
|
|
||||||
|
|
||||||
litestream = {
|
|
||||||
bucket =
|
|
||||||
mkOption {
|
|
||||||
type = types.str;
|
|
||||||
description = "S3 bucket name for Litestream database replication";
|
|
||||||
};
|
|
||||||
|
|
||||||
secretFile =
|
|
||||||
mkOption {
|
|
||||||
type = types.path;
|
|
||||||
description = "Path to the environment file containing S3 credentials for Litestream";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
restic = {
|
|
||||||
bucket =
|
|
||||||
mkOption {
|
|
||||||
type = types.str;
|
|
||||||
description = "S3 bucket name for Restic repository backups";
|
|
||||||
};
|
|
||||||
|
|
||||||
passwordFile =
|
|
||||||
mkOption {
|
|
||||||
type = types.path;
|
|
||||||
description = "Path to the file containing the Restic repository password";
|
|
||||||
};
|
|
||||||
|
|
||||||
environmentFile =
|
|
||||||
mkOption {
|
|
||||||
type = types.path;
|
|
||||||
description = "Path to the environment file containing S3 credentials for Restic";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
s3 = {
|
|
||||||
endpoint =
|
|
||||||
mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "s3.eu-central-003.backblazeb2.com";
|
|
||||||
description = "S3 endpoint URL";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config =
|
|
||||||
mkIf cfg.enable {
|
|
||||||
networking.firewall.allowedTCPPorts = [80 443];
|
|
||||||
|
|
||||||
services.redis.servers.gitea = {
|
|
||||||
enable = true;
|
|
||||||
port = 6380;
|
|
||||||
bind = "127.0.0.1";
|
|
||||||
settings = {
|
|
||||||
maxmemory = "64mb";
|
|
||||||
maxmemory-policy = "allkeys-lru";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.gitea = {
|
|
||||||
enable = true;
|
|
||||||
database = {
|
|
||||||
type = "sqlite3";
|
|
||||||
path = "/var/lib/gitea/data/gitea.db";
|
|
||||||
};
|
|
||||||
settings = {
|
|
||||||
server = {
|
|
||||||
ROOT_URL = "https://git.schmatzler.com/";
|
|
||||||
DOMAIN = "git.schmatzler.com";
|
|
||||||
HTTP_ADDR = "127.0.0.1";
|
|
||||||
HTTP_PORT = 3000;
|
|
||||||
LANDING_PAGE = "explore";
|
|
||||||
};
|
|
||||||
service.DISABLE_REGISTRATION = true;
|
|
||||||
security.INSTALL_LOCK = true;
|
|
||||||
cache = {
|
|
||||||
ADAPTER = "redis";
|
|
||||||
HOST = "redis://127.0.0.1:6380/0?pool_size=100&idle_timeout=180s";
|
|
||||||
ITEM_TTL = "16h";
|
|
||||||
};
|
|
||||||
"cache.last_commit" = {
|
|
||||||
ITEM_TTL = "8760h";
|
|
||||||
COMMITS_COUNT = 100;
|
|
||||||
};
|
|
||||||
session = {
|
|
||||||
PROVIDER = "redis";
|
|
||||||
PROVIDER_CONFIG = "redis://127.0.0.1:6380/1?pool_size=100&idle_timeout=180s";
|
|
||||||
COOKIE_SECURE = true;
|
|
||||||
SAME_SITE = "strict";
|
|
||||||
};
|
|
||||||
api.ENABLE_SWAGGER = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.litestream = {
|
|
||||||
enable = true;
|
|
||||||
environmentFile = cfg.litestream.secretFile;
|
|
||||||
settings = {
|
|
||||||
dbs = [
|
|
||||||
{
|
|
||||||
path = "/var/lib/gitea/data/gitea.db";
|
|
||||||
replicas = [
|
|
||||||
{
|
|
||||||
type = "s3";
|
|
||||||
bucket = cfg.litestream.bucket;
|
|
||||||
path = "gitea";
|
|
||||||
endpoint = cfg.s3.endpoint;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.litestream = {
|
|
||||||
serviceConfig = {
|
|
||||||
User = mkForce "gitea";
|
|
||||||
Group = mkForce "gitea";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.caddy = {
|
|
||||||
enable = true;
|
|
||||||
virtualHosts."git.schmatzler.com".extraConfig = ''
|
|
||||||
header {
|
|
||||||
Strict-Transport-Security "max-age=31536000; includeSubDomains"
|
|
||||||
X-Content-Type-Options "nosniff"
|
|
||||||
X-Frame-Options "DENY"
|
|
||||||
Referrer-Policy "strict-origin-when-cross-origin"
|
|
||||||
}
|
|
||||||
reverse_proxy localhost:3000
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
services.restic.backups.gitea = {
|
|
||||||
repository = "s3:${cfg.s3.endpoint}/${cfg.restic.bucket}";
|
|
||||||
paths = ["/var/lib/gitea"];
|
|
||||||
exclude = [
|
|
||||||
"/var/lib/gitea/log"
|
|
||||||
"/var/lib/gitea/data/gitea.db"
|
|
||||||
"/var/lib/gitea/data/gitea.db-shm"
|
|
||||||
"/var/lib/gitea/data/gitea.db-wal"
|
|
||||||
];
|
|
||||||
passwordFile = cfg.restic.passwordFile;
|
|
||||||
environmentFile = cfg.restic.environmentFile;
|
|
||||||
pruneOpts = [
|
|
||||||
"--keep-daily 7"
|
|
||||||
"--keep-weekly 4"
|
|
||||||
"--keep-monthly 6"
|
|
||||||
];
|
|
||||||
timerConfig = {
|
|
||||||
OnCalendar = "daily";
|
|
||||||
Persistent = true;
|
|
||||||
RandomizedDelaySec = "1h";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.restic-backups-gitea = {
|
|
||||||
wants = ["restic-init-gitea.service"];
|
|
||||||
after = ["restic-init-gitea.service"];
|
|
||||||
serviceConfig = {
|
|
||||||
User = mkForce "gitea";
|
|
||||||
Group = mkForce "gitea";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.restic-init-gitea = {
|
|
||||||
description = "Initialize Restic repository for Gitea backups";
|
|
||||||
wantedBy = ["multi-user.target"];
|
|
||||||
after = ["network-online.target"];
|
|
||||||
wants = ["network-online.target"];
|
|
||||||
path = [pkgs.restic];
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "oneshot";
|
|
||||||
User = "gitea";
|
|
||||||
Group = "gitea";
|
|
||||||
RemainAfterExit = true;
|
|
||||||
EnvironmentFile = cfg.restic.environmentFile;
|
|
||||||
};
|
|
||||||
script = ''
|
|
||||||
export RESTIC_PASSWORD=$(cat ${cfg.restic.passwordFile})
|
|
||||||
restic -r s3:${cfg.s3.endpoint}/${cfg.restic.bucket} snapshots &>/dev/null || \
|
|
||||||
restic -r s3:${cfg.s3.endpoint}/${cfg.restic.bucket} init
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
6
modules/hosts.nix
Normal file
6
modules/hosts.nix
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{...}: {
|
||||||
|
den.hosts.aarch64-darwin.chidi.users.cschmatzler = {};
|
||||||
|
den.hosts.aarch64-darwin.jason.users.cschmatzler = {};
|
||||||
|
den.hosts.x86_64-linux.michael.users.cschmatzler = {};
|
||||||
|
den.hosts.x86_64-linux.tahani.users.cschmatzler = {};
|
||||||
|
}
|
||||||
25
modules/jason.nix
Normal file
25
modules/jason.nix
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
{den, ...}: {
|
||||||
|
den.aspects.jason.includes = [
|
||||||
|
den.aspects.darwin-system
|
||||||
|
den.aspects.core
|
||||||
|
den.aspects.tailscale
|
||||||
|
den.aspects.desktop
|
||||||
|
den.aspects.terminal
|
||||||
|
den.aspects.atuin
|
||||||
|
den.aspects.dev-tools
|
||||||
|
den.aspects.neovim
|
||||||
|
den.aspects.ai-tools
|
||||||
|
den.aspects.zellij
|
||||||
|
den.aspects.zk
|
||||||
|
];
|
||||||
|
|
||||||
|
den.aspects.jason.darwin = {...}: {
|
||||||
|
networking.hostName = "jason";
|
||||||
|
networking.computerName = "jason";
|
||||||
|
};
|
||||||
|
|
||||||
|
den.aspects.jason.homeManager = {...}: {
|
||||||
|
fonts.fontconfig.enable = true;
|
||||||
|
programs.git.settings.user.email = "christoph@schmatzler.com";
|
||||||
|
};
|
||||||
|
}
|
||||||
191
modules/michael.nix
Normal file
191
modules/michael.nix
Normal file
@@ -0,0 +1,191 @@
|
|||||||
|
{
|
||||||
|
inputs,
|
||||||
|
den,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
den.aspects.michael.includes = [
|
||||||
|
den.aspects.nixos-system
|
||||||
|
den.aspects.core
|
||||||
|
den.aspects.openssh
|
||||||
|
den.aspects.fail2ban
|
||||||
|
den.aspects.tailscale
|
||||||
|
];
|
||||||
|
|
||||||
|
den.aspects.michael.nixos = {
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
modulesPath,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
imports = [
|
||||||
|
(modulesPath + "/installer/scan/not-detected.nix")
|
||||||
|
(modulesPath + "/profiles/qemu-guest.nix")
|
||||||
|
./_hosts/michael/disk-config.nix
|
||||||
|
./_hosts/michael/hardware-configuration.nix
|
||||||
|
inputs.disko.nixosModules.default
|
||||||
|
];
|
||||||
|
|
||||||
|
networking.hostName = "michael";
|
||||||
|
|
||||||
|
sops.secrets = {
|
||||||
|
michael-gitea-litestream = {
|
||||||
|
sopsFile = ../secrets/michael-gitea-litestream;
|
||||||
|
format = "binary";
|
||||||
|
owner = "gitea";
|
||||||
|
group = "gitea";
|
||||||
|
};
|
||||||
|
michael-gitea-restic-password = {
|
||||||
|
sopsFile = ../secrets/michael-gitea-restic-password;
|
||||||
|
format = "binary";
|
||||||
|
owner = "gitea";
|
||||||
|
group = "gitea";
|
||||||
|
};
|
||||||
|
michael-gitea-restic-env = {
|
||||||
|
sopsFile = ../secrets/michael-gitea-restic-env;
|
||||||
|
format = "binary";
|
||||||
|
owner = "gitea";
|
||||||
|
group = "gitea";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.firewall.allowedTCPPorts = [80 443];
|
||||||
|
|
||||||
|
services.redis.servers.gitea = {
|
||||||
|
enable = true;
|
||||||
|
port = 6380;
|
||||||
|
bind = "127.0.0.1";
|
||||||
|
settings = {
|
||||||
|
maxmemory = "64mb";
|
||||||
|
maxmemory-policy = "allkeys-lru";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.gitea = {
|
||||||
|
enable = true;
|
||||||
|
database = {
|
||||||
|
type = "sqlite3";
|
||||||
|
path = "/var/lib/gitea/data/gitea.db";
|
||||||
|
};
|
||||||
|
settings = {
|
||||||
|
server = {
|
||||||
|
ROOT_URL = "https://git.schmatzler.com/";
|
||||||
|
DOMAIN = "git.schmatzler.com";
|
||||||
|
HTTP_ADDR = "127.0.0.1";
|
||||||
|
HTTP_PORT = 3000;
|
||||||
|
LANDING_PAGE = "explore";
|
||||||
|
};
|
||||||
|
service.DISABLE_REGISTRATION = true;
|
||||||
|
security.INSTALL_LOCK = true;
|
||||||
|
cache = {
|
||||||
|
ADAPTER = "redis";
|
||||||
|
HOST = "redis://127.0.0.1:6380/0?pool_size=100&idle_timeout=180s";
|
||||||
|
ITEM_TTL = "16h";
|
||||||
|
};
|
||||||
|
"cache.last_commit" = {
|
||||||
|
ITEM_TTL = "8760h";
|
||||||
|
COMMITS_COUNT = 100;
|
||||||
|
};
|
||||||
|
session = {
|
||||||
|
PROVIDER = "redis";
|
||||||
|
PROVIDER_CONFIG = "redis://127.0.0.1:6380/1?pool_size=100&idle_timeout=180s";
|
||||||
|
COOKIE_SECURE = true;
|
||||||
|
SAME_SITE = "strict";
|
||||||
|
};
|
||||||
|
api.ENABLE_SWAGGER = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.litestream = {
|
||||||
|
enable = true;
|
||||||
|
environmentFile = config.sops.secrets.michael-gitea-litestream.path;
|
||||||
|
settings = {
|
||||||
|
dbs = [
|
||||||
|
{
|
||||||
|
path = "/var/lib/gitea/data/gitea.db";
|
||||||
|
replicas = [
|
||||||
|
{
|
||||||
|
type = "s3";
|
||||||
|
bucket = "michael-gitea-litestream";
|
||||||
|
path = "gitea";
|
||||||
|
endpoint = "s3.eu-central-003.backblazeb2.com";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.litestream = {
|
||||||
|
serviceConfig = {
|
||||||
|
User = lib.mkForce "gitea";
|
||||||
|
Group = lib.mkForce "gitea";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.caddy = {
|
||||||
|
enable = true;
|
||||||
|
virtualHosts."git.schmatzler.com".extraConfig = ''
|
||||||
|
header {
|
||||||
|
Strict-Transport-Security "max-age=31536000; includeSubDomains"
|
||||||
|
X-Content-Type-Options "nosniff"
|
||||||
|
X-Frame-Options "DENY"
|
||||||
|
Referrer-Policy "strict-origin-when-cross-origin"
|
||||||
|
}
|
||||||
|
reverse_proxy localhost:3000
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
services.restic.backups.gitea = {
|
||||||
|
repository = "s3:s3.eu-central-003.backblazeb2.com/michael-gitea-repositories";
|
||||||
|
paths = ["/var/lib/gitea"];
|
||||||
|
exclude = [
|
||||||
|
"/var/lib/gitea/log"
|
||||||
|
"/var/lib/gitea/data/gitea.db"
|
||||||
|
"/var/lib/gitea/data/gitea.db-shm"
|
||||||
|
"/var/lib/gitea/data/gitea.db-wal"
|
||||||
|
];
|
||||||
|
passwordFile = config.sops.secrets.michael-gitea-restic-password.path;
|
||||||
|
environmentFile = config.sops.secrets.michael-gitea-restic-env.path;
|
||||||
|
pruneOpts = [
|
||||||
|
"--keep-daily 7"
|
||||||
|
"--keep-weekly 4"
|
||||||
|
"--keep-monthly 6"
|
||||||
|
];
|
||||||
|
timerConfig = {
|
||||||
|
OnCalendar = "daily";
|
||||||
|
Persistent = true;
|
||||||
|
RandomizedDelaySec = "1h";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.restic-backups-gitea = {
|
||||||
|
wants = ["restic-init-gitea.service"];
|
||||||
|
after = ["restic-init-gitea.service"];
|
||||||
|
serviceConfig = {
|
||||||
|
User = lib.mkForce "gitea";
|
||||||
|
Group = lib.mkForce "gitea";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.restic-init-gitea = {
|
||||||
|
description = "Initialize Restic repository for Gitea backups";
|
||||||
|
wantedBy = ["multi-user.target"];
|
||||||
|
after = ["network-online.target"];
|
||||||
|
wants = ["network-online.target"];
|
||||||
|
path = [pkgs.restic];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
User = "gitea";
|
||||||
|
Group = "gitea";
|
||||||
|
RemainAfterExit = true;
|
||||||
|
EnvironmentFile = config.sops.secrets.michael-gitea-restic-env.path;
|
||||||
|
};
|
||||||
|
script = ''
|
||||||
|
export RESTIC_PASSWORD=$(cat ${config.sops.secrets.michael-gitea-restic-password.path})
|
||||||
|
restic -r s3:s3.eu-central-003.backblazeb2.com/michael-gitea-repositories snapshots &>/dev/null || \
|
||||||
|
restic -r s3:s3.eu-central-003.backblazeb2.com/michael-gitea-repositories init
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
8
modules/neovim.nix
Normal file
8
modules/neovim.nix
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{inputs, ...}: {
|
||||||
|
den.aspects.neovim.homeManager = {pkgs, ...}: {
|
||||||
|
imports = [
|
||||||
|
inputs.nixvim.homeModules.nixvim
|
||||||
|
./_neovim/default.nix
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
67
modules/network.nix
Normal file
67
modules/network.nix
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
{...}: {
|
||||||
|
den.aspects.openssh.nixos = {
|
||||||
|
services.openssh = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
PermitRootLogin = "no";
|
||||||
|
PasswordAuthentication = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
den.aspects.fail2ban.nixos = {
|
||||||
|
services.fail2ban = {
|
||||||
|
enable = true;
|
||||||
|
maxretry = 5;
|
||||||
|
bantime = "10m";
|
||||||
|
bantime-increment = {
|
||||||
|
enable = true;
|
||||||
|
multipliers = "1 2 4 8 16 32 64";
|
||||||
|
maxtime = "168h";
|
||||||
|
overalljails = true;
|
||||||
|
};
|
||||||
|
jails = {
|
||||||
|
sshd = {
|
||||||
|
settings = {
|
||||||
|
enabled = true;
|
||||||
|
port = "ssh";
|
||||||
|
filter = "sshd";
|
||||||
|
maxretry = 3;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
gitea = {
|
||||||
|
settings = {
|
||||||
|
enabled = true;
|
||||||
|
filter = "gitea";
|
||||||
|
logpath = "/var/lib/gitea/log/gitea.log";
|
||||||
|
maxretry = 10;
|
||||||
|
findtime = 3600;
|
||||||
|
bantime = 900;
|
||||||
|
action = "iptables-allports";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.etc."fail2ban/filter.d/gitea.local".text = ''
|
||||||
|
[Definition]
|
||||||
|
failregex = .*(Failed authentication attempt|invalid credentials|Attempted access of unknown user).* from <HOST>
|
||||||
|
ignoreregex =
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
den.aspects.tailscale.nixos = {
|
||||||
|
services.tailscale = {
|
||||||
|
enable = true;
|
||||||
|
openFirewall = true;
|
||||||
|
permitCertUid = "caddy";
|
||||||
|
useRoutingFeatures = "server";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
den.aspects.tailscale.darwin = {
|
||||||
|
services.tailscale = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
87
modules/nixos-system.nix
Normal file
87
modules/nixos-system.nix
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
{inputs, ...}: {
|
||||||
|
den.aspects.nixos-system.nixos = {pkgs, ...}: {
|
||||||
|
imports = [inputs.home-manager.nixosModules.home-manager];
|
||||||
|
|
||||||
|
security.sudo.enable = true;
|
||||||
|
security.sudo.extraRules = [
|
||||||
|
{
|
||||||
|
users = ["cschmatzler"];
|
||||||
|
commands = [
|
||||||
|
{
|
||||||
|
command = "/run/current-system/sw/bin/nix-env";
|
||||||
|
options = ["NOPASSWD"];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
command = "/nix/store/*/bin/switch-to-configuration";
|
||||||
|
options = ["NOPASSWD"];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
command = "/nix/store/*/bin/activate";
|
||||||
|
options = ["NOPASSWD"];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
command = "/nix/store/*/bin/activate-rs";
|
||||||
|
options = ["NOPASSWD"];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
command = "/nix/store/*/bin/wait-activate";
|
||||||
|
options = ["NOPASSWD"];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
time.timeZone = "UTC";
|
||||||
|
|
||||||
|
nix = {
|
||||||
|
settings.trusted-users = ["cschmatzler"];
|
||||||
|
gc.dates = "weekly";
|
||||||
|
nixPath = ["nixos-config=/home/cschmatzler/.local/share/src/nixos-config:/etc/nixos"];
|
||||||
|
};
|
||||||
|
|
||||||
|
boot = {
|
||||||
|
loader = {
|
||||||
|
systemd-boot = {
|
||||||
|
enable = true;
|
||||||
|
configurationLimit = 42;
|
||||||
|
};
|
||||||
|
efi.canTouchEfiVariables = true;
|
||||||
|
};
|
||||||
|
initrd.availableKernelModules = [
|
||||||
|
"xhci_pci"
|
||||||
|
"ahci"
|
||||||
|
"nvme"
|
||||||
|
"usbhid"
|
||||||
|
"usb_storage"
|
||||||
|
"sd_mod"
|
||||||
|
];
|
||||||
|
kernelPackages = pkgs.linuxPackages_latest;
|
||||||
|
};
|
||||||
|
|
||||||
|
users.users = {
|
||||||
|
cschmatzler = {
|
||||||
|
isNormalUser = true;
|
||||||
|
home = "/home/cschmatzler";
|
||||||
|
extraGroups = [
|
||||||
|
"wheel"
|
||||||
|
"sudo"
|
||||||
|
"network"
|
||||||
|
"systemd-journal"
|
||||||
|
];
|
||||||
|
shell = pkgs.nushell;
|
||||||
|
openssh.authorizedKeys.keys = [
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHfRZQ+7ejD3YHbyMTrV0gN1Gc0DxtGgl5CVZSupo5ws"
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL/I+/2QT47raegzMIyhwMEPKarJP/+Ox9ewA4ZFJwk/"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
root = {
|
||||||
|
openssh.authorizedKeys.keys = [
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHfRZQ+7ejD3YHbyMTrV0gN1Gc0DxtGgl5CVZSupo5ws"
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL/I+/2QT47raegzMIyhwMEPKarJP/+Ox9ewA4ZFJwk/"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
home-manager.useGlobalPkgs = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
29
modules/overlays.nix
Normal file
29
modules/overlays.nix
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
{inputs, ...}: let
|
||||||
|
overlays = [
|
||||||
|
# himalaya
|
||||||
|
(final: prev: {
|
||||||
|
himalaya = inputs.himalaya.packages.${prev.stdenv.hostPlatform.system}.default;
|
||||||
|
})
|
||||||
|
# jj-ryu (uses build-rust-package helper)
|
||||||
|
(final: prev: {
|
||||||
|
jj-ryu =
|
||||||
|
import ./_lib/build-rust-package.nix {
|
||||||
|
inherit inputs prev;
|
||||||
|
input = inputs.jj-ryu;
|
||||||
|
};
|
||||||
|
})
|
||||||
|
# jj-starship (passes through upstream overlay)
|
||||||
|
inputs.jj-starship.overlays.default
|
||||||
|
# zjstatus
|
||||||
|
(final: prev: {
|
||||||
|
zjstatus = inputs.zjstatus.packages.${prev.stdenv.hostPlatform.system}.default;
|
||||||
|
})
|
||||||
|
# tuicr
|
||||||
|
(final: prev: {
|
||||||
|
tuicr = inputs.tuicr.defaultPackage.${prev.stdenv.hostPlatform.system};
|
||||||
|
})
|
||||||
|
];
|
||||||
|
in {
|
||||||
|
den.default.nixos.nixpkgs.overlays = overlays;
|
||||||
|
den.default.darwin.nixpkgs.overlays = overlays;
|
||||||
|
}
|
||||||
@@ -1,257 +0,0 @@
|
|||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
with lib; let
|
|
||||||
cfg = config.my.pgbackrest;
|
|
||||||
in {
|
|
||||||
options.my.pgbackrest = {
|
|
||||||
enable = mkEnableOption "pgBackRest PostgreSQL backup";
|
|
||||||
|
|
||||||
stanza =
|
|
||||||
mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "main";
|
|
||||||
description = "Name of the pgBackRest stanza";
|
|
||||||
};
|
|
||||||
|
|
||||||
secretFile =
|
|
||||||
mkOption {
|
|
||||||
type = types.path;
|
|
||||||
description = "Path to the environment file containing S3 credentials and cipher passphrase";
|
|
||||||
};
|
|
||||||
|
|
||||||
s3 =
|
|
||||||
mkOption {
|
|
||||||
type =
|
|
||||||
types.submodule {
|
|
||||||
options = {
|
|
||||||
endpoint =
|
|
||||||
mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "s3.eu-central-003.backblazeb2.com";
|
|
||||||
description = "S3 endpoint URL";
|
|
||||||
};
|
|
||||||
bucket =
|
|
||||||
mkOption {
|
|
||||||
type = types.str;
|
|
||||||
description = "S3 bucket name";
|
|
||||||
};
|
|
||||||
region =
|
|
||||||
mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "eu-central-003";
|
|
||||||
description = "S3 region";
|
|
||||||
};
|
|
||||||
path =
|
|
||||||
mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "/backups";
|
|
||||||
description = "Path within the S3 bucket";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
default = {};
|
|
||||||
description = "S3 storage configuration";
|
|
||||||
};
|
|
||||||
|
|
||||||
retention =
|
|
||||||
mkOption {
|
|
||||||
type =
|
|
||||||
types.submodule {
|
|
||||||
options = {
|
|
||||||
full =
|
|
||||||
mkOption {
|
|
||||||
type = types.int;
|
|
||||||
default = 7;
|
|
||||||
description = "Number of full backups to retain";
|
|
||||||
};
|
|
||||||
diff =
|
|
||||||
mkOption {
|
|
||||||
type = types.int;
|
|
||||||
default = 7;
|
|
||||||
description = "Number of differential backups to retain";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
default = {};
|
|
||||||
description = "Backup retention configuration";
|
|
||||||
};
|
|
||||||
|
|
||||||
compression =
|
|
||||||
mkOption {
|
|
||||||
type =
|
|
||||||
types.submodule {
|
|
||||||
options = {
|
|
||||||
type =
|
|
||||||
mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "zst";
|
|
||||||
description = "Compression algorithm (none, gz, lz4, zst)";
|
|
||||||
};
|
|
||||||
level =
|
|
||||||
mkOption {
|
|
||||||
type = types.int;
|
|
||||||
default = 3;
|
|
||||||
description = "Compression level";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
default = {};
|
|
||||||
description = "Compression configuration";
|
|
||||||
};
|
|
||||||
|
|
||||||
processMax =
|
|
||||||
mkOption {
|
|
||||||
type = types.int;
|
|
||||||
default = 2;
|
|
||||||
description = "Maximum number of processes for parallel operations";
|
|
||||||
};
|
|
||||||
|
|
||||||
schedule =
|
|
||||||
mkOption {
|
|
||||||
type =
|
|
||||||
types.submodule {
|
|
||||||
options = {
|
|
||||||
full =
|
|
||||||
mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "daily";
|
|
||||||
description = "OnCalendar expression for full backups";
|
|
||||||
};
|
|
||||||
diff =
|
|
||||||
mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "hourly";
|
|
||||||
description = "OnCalendar expression for differential backups";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
default = {};
|
|
||||||
description = "Backup schedule configuration";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config =
|
|
||||||
mkIf cfg.enable (let
|
|
||||||
archivePushScript =
|
|
||||||
pkgs.writeShellScript "pgbackrest-archive-push" ''
|
|
||||||
set -a
|
|
||||||
source ${cfg.secretFile}
|
|
||||||
set +a
|
|
||||||
exec ${pkgs.pgbackrest}/bin/pgbackrest --stanza=${cfg.stanza} archive-push "$1"
|
|
||||||
'';
|
|
||||||
in {
|
|
||||||
environment.systemPackages = [
|
|
||||||
pkgs.pgbackrest
|
|
||||||
(pkgs.writeShellScriptBin "pgbackrest-wrapper" ''
|
|
||||||
set -a
|
|
||||||
source ${cfg.secretFile}
|
|
||||||
set +a
|
|
||||||
exec ${pkgs.pgbackrest}/bin/pgbackrest "$@"
|
|
||||||
'')
|
|
||||||
];
|
|
||||||
|
|
||||||
services.postgresql.settings = {
|
|
||||||
archive_mode = "on";
|
|
||||||
archive_command = "${archivePushScript} %p";
|
|
||||||
};
|
|
||||||
|
|
||||||
environment.etc."pgbackrest/pgbackrest.conf".text = ''
|
|
||||||
[global]
|
|
||||||
repo1-type=s3
|
|
||||||
repo1-s3-endpoint=${cfg.s3.endpoint}
|
|
||||||
repo1-s3-bucket=${cfg.s3.bucket}
|
|
||||||
repo1-s3-region=${cfg.s3.region}
|
|
||||||
repo1-path=${cfg.s3.path}
|
|
||||||
repo1-retention-full=${toString cfg.retention.full}
|
|
||||||
repo1-retention-diff=${toString cfg.retention.diff}
|
|
||||||
repo1-cipher-type=aes-256-cbc
|
|
||||||
compress-type=${cfg.compression.type}
|
|
||||||
compress-level=${toString cfg.compression.level}
|
|
||||||
process-max=${toString cfg.processMax}
|
|
||||||
log-level-console=info
|
|
||||||
log-level-file=detail
|
|
||||||
log-path=/var/log/pgbackrest
|
|
||||||
spool-path=/var/spool/pgbackrest
|
|
||||||
|
|
||||||
[${cfg.stanza}]
|
|
||||||
pg1-path=/var/lib/postgresql/${config.services.postgresql.package.psqlSchema}
|
|
||||||
pg1-user=postgres
|
|
||||||
'';
|
|
||||||
|
|
||||||
systemd.services.pgbackrest-stanza-create = {
|
|
||||||
description = "pgBackRest Stanza Create";
|
|
||||||
after = ["postgresql.service"];
|
|
||||||
requires = ["postgresql.service"];
|
|
||||||
path = [pkgs.pgbackrest];
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "oneshot";
|
|
||||||
User = "postgres";
|
|
||||||
EnvironmentFile = cfg.secretFile;
|
|
||||||
RemainAfterExit = true;
|
|
||||||
};
|
|
||||||
script = ''
|
|
||||||
pgbackrest --stanza=${cfg.stanza} stanza-create || true
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.pgbackrest-backup = {
|
|
||||||
description = "pgBackRest Full Backup";
|
|
||||||
after = ["postgresql.service" "pgbackrest-stanza-create.service"];
|
|
||||||
requires = ["postgresql.service"];
|
|
||||||
wants = ["pgbackrest-stanza-create.service"];
|
|
||||||
path = [pkgs.pgbackrest];
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "oneshot";
|
|
||||||
User = "postgres";
|
|
||||||
EnvironmentFile = cfg.secretFile;
|
|
||||||
};
|
|
||||||
script = ''
|
|
||||||
pgbackrest --stanza=${cfg.stanza} backup --type=full
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.timers.pgbackrest-backup = {
|
|
||||||
wantedBy = ["timers.target"];
|
|
||||||
timerConfig = {
|
|
||||||
OnCalendar = cfg.schedule.full;
|
|
||||||
Persistent = true;
|
|
||||||
RandomizedDelaySec = "1h";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.pgbackrest-backup-diff = {
|
|
||||||
description = "pgBackRest Differential Backup";
|
|
||||||
after = ["postgresql.service" "pgbackrest-stanza-create.service"];
|
|
||||||
requires = ["postgresql.service"];
|
|
||||||
wants = ["pgbackrest-stanza-create.service"];
|
|
||||||
path = [pkgs.pgbackrest];
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "oneshot";
|
|
||||||
User = "postgres";
|
|
||||||
EnvironmentFile = cfg.secretFile;
|
|
||||||
};
|
|
||||||
script = ''
|
|
||||||
pgbackrest --stanza=${cfg.stanza} backup --type=diff
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.timers.pgbackrest-backup-diff = {
|
|
||||||
wantedBy = ["timers.target"];
|
|
||||||
timerConfig = {
|
|
||||||
OnCalendar = cfg.schedule.diff;
|
|
||||||
Persistent = true;
|
|
||||||
RandomizedDelaySec = "5m";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.tmpfiles.rules = [
|
|
||||||
"d /var/lib/pgbackrest 0750 postgres postgres -"
|
|
||||||
"d /var/log/pgbackrest 0750 postgres postgres -"
|
|
||||||
"d /var/spool/pgbackrest 0750 postgres postgres -"
|
|
||||||
];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
15
modules/secrets.nix
Normal file
15
modules/secrets.nix
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{inputs, ...}: {
|
||||||
|
# Import sops-nix modules into den.default per-class
|
||||||
|
den.default.nixos.imports = [inputs.sops-nix.nixosModules.sops];
|
||||||
|
den.default.darwin.imports = [inputs.sops-nix.darwinModules.sops];
|
||||||
|
|
||||||
|
# Configure NixOS SOPS defaults
|
||||||
|
den.default.nixos.sops.age.sshKeyPaths = ["/etc/ssh/ssh_host_ed25519_key"];
|
||||||
|
|
||||||
|
# Configure Darwin SOPS defaults
|
||||||
|
den.default.darwin = {
|
||||||
|
sops.age.keyFile = "/Users/cschmatzler/.config/sops/age/keys.txt";
|
||||||
|
sops.age.sshKeyPaths = [];
|
||||||
|
sops.gnupg.sshKeyPaths = [];
|
||||||
|
};
|
||||||
|
}
|
||||||
285
modules/shell.nix
Normal file
285
modules/shell.nix
Normal file
@@ -0,0 +1,285 @@
|
|||||||
|
{...}: {
|
||||||
|
den.aspects.shell.homeManager = {
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
programs.nushell = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
show_banner = false;
|
||||||
|
completions = {
|
||||||
|
algorithm = "fuzzy";
|
||||||
|
case_sensitive = false;
|
||||||
|
};
|
||||||
|
history = {
|
||||||
|
file_format = "sqlite";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
environmentVariables = {
|
||||||
|
COLORTERM = "truecolor";
|
||||||
|
COLORFGBG = "15;0";
|
||||||
|
TERM_BACKGROUND = "light";
|
||||||
|
EDITOR = "nvim";
|
||||||
|
};
|
||||||
|
|
||||||
|
extraEnv =
|
||||||
|
''
|
||||||
|
$env.LS_COLORS = (${pkgs.vivid}/bin/vivid generate catppuccin-latte)
|
||||||
|
''
|
||||||
|
+ lib.optionalString pkgs.stdenv.isDarwin ''
|
||||||
|
# Nushell on Darwin doesn't source /etc/zprofile or path_helper,
|
||||||
|
# so nix-managed paths must be added explicitly.
|
||||||
|
$env.PATH = ($env.PATH | split row (char esep) | prepend "/run/current-system/sw/bin" | prepend $"($env.HOME)/.nix-profile/bin")
|
||||||
|
'';
|
||||||
|
|
||||||
|
extraConfig = ''
|
||||||
|
# --- Catppuccin Latte Theme ---
|
||||||
|
let theme = {
|
||||||
|
rosewater: "#dc8a78"
|
||||||
|
flamingo: "#dd7878"
|
||||||
|
pink: "#ea76cb"
|
||||||
|
mauve: "#8839ef"
|
||||||
|
red: "#d20f39"
|
||||||
|
maroon: "#e64553"
|
||||||
|
peach: "#fe640b"
|
||||||
|
yellow: "#df8e1d"
|
||||||
|
green: "#40a02b"
|
||||||
|
teal: "#179299"
|
||||||
|
sky: "#04a5e5"
|
||||||
|
sapphire: "#209fb5"
|
||||||
|
blue: "#1e66f5"
|
||||||
|
lavender: "#7287fd"
|
||||||
|
text: "#4c4f69"
|
||||||
|
subtext1: "#5c5f77"
|
||||||
|
subtext0: "#6c6f85"
|
||||||
|
overlay2: "#7c7f93"
|
||||||
|
overlay1: "#8c8fa1"
|
||||||
|
overlay0: "#9ca0b0"
|
||||||
|
surface2: "#acb0be"
|
||||||
|
surface1: "#bcc0cc"
|
||||||
|
surface0: "#ccd0da"
|
||||||
|
base: "#eff1f5"
|
||||||
|
mantle: "#e6e9ef"
|
||||||
|
crust: "#dce0e8"
|
||||||
|
}
|
||||||
|
|
||||||
|
let scheme = {
|
||||||
|
recognized_command: $theme.blue
|
||||||
|
unrecognized_command: $theme.text
|
||||||
|
constant: $theme.peach
|
||||||
|
punctuation: $theme.overlay2
|
||||||
|
operator: $theme.sky
|
||||||
|
string: $theme.green
|
||||||
|
virtual_text: $theme.surface2
|
||||||
|
variable: { fg: $theme.flamingo attr: i }
|
||||||
|
filepath: $theme.yellow
|
||||||
|
}
|
||||||
|
|
||||||
|
$env.config.color_config = {
|
||||||
|
separator: { fg: $theme.surface2 attr: b }
|
||||||
|
leading_trailing_space_bg: { fg: $theme.lavender attr: u }
|
||||||
|
header: { fg: $theme.text attr: b }
|
||||||
|
row_index: $scheme.virtual_text
|
||||||
|
record: $theme.text
|
||||||
|
list: $theme.text
|
||||||
|
hints: $scheme.virtual_text
|
||||||
|
search_result: { fg: $theme.base bg: $theme.yellow }
|
||||||
|
shape_closure: $theme.teal
|
||||||
|
closure: $theme.teal
|
||||||
|
shape_flag: { fg: $theme.maroon attr: i }
|
||||||
|
shape_matching_brackets: { attr: u }
|
||||||
|
shape_garbage: $theme.red
|
||||||
|
shape_keyword: $theme.mauve
|
||||||
|
shape_match_pattern: $theme.green
|
||||||
|
shape_signature: $theme.teal
|
||||||
|
shape_table: $scheme.punctuation
|
||||||
|
cell-path: $scheme.punctuation
|
||||||
|
shape_list: $scheme.punctuation
|
||||||
|
shape_record: $scheme.punctuation
|
||||||
|
shape_vardecl: $scheme.variable
|
||||||
|
shape_variable: $scheme.variable
|
||||||
|
empty: { attr: n }
|
||||||
|
filesize: {||
|
||||||
|
if $in < 1kb {
|
||||||
|
$theme.teal
|
||||||
|
} else if $in < 10kb {
|
||||||
|
$theme.green
|
||||||
|
} else if $in < 100kb {
|
||||||
|
$theme.yellow
|
||||||
|
} else if $in < 10mb {
|
||||||
|
$theme.peach
|
||||||
|
} else if $in < 100mb {
|
||||||
|
$theme.maroon
|
||||||
|
} else if $in < 1gb {
|
||||||
|
$theme.red
|
||||||
|
} else {
|
||||||
|
$theme.mauve
|
||||||
|
}
|
||||||
|
}
|
||||||
|
duration: {||
|
||||||
|
if $in < 1day {
|
||||||
|
$theme.teal
|
||||||
|
} else if $in < 1wk {
|
||||||
|
$theme.green
|
||||||
|
} else if $in < 4wk {
|
||||||
|
$theme.yellow
|
||||||
|
} else if $in < 12wk {
|
||||||
|
$theme.peach
|
||||||
|
} else if $in < 24wk {
|
||||||
|
$theme.maroon
|
||||||
|
} else if $in < 52wk {
|
||||||
|
$theme.red
|
||||||
|
} else {
|
||||||
|
$theme.mauve
|
||||||
|
}
|
||||||
|
}
|
||||||
|
datetime: {|| (date now) - $in |
|
||||||
|
if $in < 1day {
|
||||||
|
$theme.teal
|
||||||
|
} else if $in < 1wk {
|
||||||
|
$theme.green
|
||||||
|
} else if $in < 4wk {
|
||||||
|
$theme.yellow
|
||||||
|
} else if $in < 12wk {
|
||||||
|
$theme.peach
|
||||||
|
} else if $in < 24wk {
|
||||||
|
$theme.maroon
|
||||||
|
} else if $in < 52wk {
|
||||||
|
$theme.red
|
||||||
|
} else {
|
||||||
|
$theme.mauve
|
||||||
|
}
|
||||||
|
}
|
||||||
|
shape_external: $scheme.unrecognized_command
|
||||||
|
shape_internalcall: $scheme.recognized_command
|
||||||
|
shape_external_resolved: $scheme.recognized_command
|
||||||
|
shape_block: $scheme.recognized_command
|
||||||
|
block: $scheme.recognized_command
|
||||||
|
shape_custom: $theme.pink
|
||||||
|
custom: $theme.pink
|
||||||
|
background: $theme.base
|
||||||
|
foreground: $theme.text
|
||||||
|
cursor: { bg: $theme.rosewater fg: $theme.base }
|
||||||
|
shape_range: $scheme.operator
|
||||||
|
range: $scheme.operator
|
||||||
|
shape_pipe: $scheme.operator
|
||||||
|
shape_operator: $scheme.operator
|
||||||
|
shape_redirection: $scheme.operator
|
||||||
|
glob: $scheme.filepath
|
||||||
|
shape_directory: $scheme.filepath
|
||||||
|
shape_filepath: $scheme.filepath
|
||||||
|
shape_glob_interpolation: $scheme.filepath
|
||||||
|
shape_globpattern: $scheme.filepath
|
||||||
|
shape_int: $scheme.constant
|
||||||
|
int: $scheme.constant
|
||||||
|
bool: $scheme.constant
|
||||||
|
float: $scheme.constant
|
||||||
|
nothing: $scheme.constant
|
||||||
|
binary: $scheme.constant
|
||||||
|
shape_nothing: $scheme.constant
|
||||||
|
shape_bool: $scheme.constant
|
||||||
|
shape_float: $scheme.constant
|
||||||
|
shape_binary: $scheme.constant
|
||||||
|
shape_datetime: $scheme.constant
|
||||||
|
shape_literal: $scheme.constant
|
||||||
|
string: $scheme.string
|
||||||
|
shape_string: $scheme.string
|
||||||
|
shape_string_interpolation: $theme.flamingo
|
||||||
|
shape_raw_string: $scheme.string
|
||||||
|
shape_externalarg: $scheme.string
|
||||||
|
}
|
||||||
|
$env.config.highlight_resolved_externals = true
|
||||||
|
$env.config.explore = {
|
||||||
|
status_bar_background: { fg: $theme.text, bg: $theme.mantle },
|
||||||
|
command_bar_text: { fg: $theme.text },
|
||||||
|
highlight: { fg: $theme.base, bg: $theme.yellow },
|
||||||
|
status: {
|
||||||
|
error: $theme.red,
|
||||||
|
warn: $theme.yellow,
|
||||||
|
info: $theme.blue,
|
||||||
|
},
|
||||||
|
selected_cell: { bg: $theme.blue fg: $theme.base },
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Custom Commands ---
|
||||||
|
def --env open_project [] {
|
||||||
|
let base = ($env.HOME | path join "Projects")
|
||||||
|
let choice = (
|
||||||
|
${pkgs.fd}/bin/fd -t d -d 1 -a . ($base | path join "Personal") ($base | path join "Work")
|
||||||
|
| lines
|
||||||
|
| each {|p| $p | str replace $"($base)/" "" }
|
||||||
|
| str join "\n"
|
||||||
|
| ${pkgs.fzf}/bin/fzf --prompt "project > "
|
||||||
|
)
|
||||||
|
if ($choice | str trim | is-not-empty) {
|
||||||
|
cd ($base | path join ($choice | str trim))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Keybinding: Ctrl+O for open_project ---
|
||||||
|
$env.config.keybindings = ($env.config.keybindings | append [
|
||||||
|
{
|
||||||
|
name: open_project
|
||||||
|
modifier: control
|
||||||
|
keycode: char_o
|
||||||
|
mode: [emacs vi_insert vi_normal]
|
||||||
|
event: {
|
||||||
|
send: executehostcommand
|
||||||
|
cmd: "open_project"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
])
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.zsh = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.starship = {
|
||||||
|
enable = true;
|
||||||
|
enableNushellIntegration = true;
|
||||||
|
settings = {
|
||||||
|
format = "$directory\${custom.scm}$hostname$line_break$character";
|
||||||
|
buf = {
|
||||||
|
disabled = true;
|
||||||
|
};
|
||||||
|
character = {
|
||||||
|
error_symbol = "[](bold red)";
|
||||||
|
success_symbol = "[](bold green)";
|
||||||
|
};
|
||||||
|
directory = {
|
||||||
|
truncate_to_repo = false;
|
||||||
|
};
|
||||||
|
git_branch = {
|
||||||
|
disabled = true;
|
||||||
|
symbol = " ";
|
||||||
|
truncation_length = 18;
|
||||||
|
};
|
||||||
|
git_status = {
|
||||||
|
disabled = true;
|
||||||
|
};
|
||||||
|
git_commit = {
|
||||||
|
disabled = true;
|
||||||
|
};
|
||||||
|
git_state = {
|
||||||
|
disabled = true;
|
||||||
|
};
|
||||||
|
custom.scm = {
|
||||||
|
when = "jj-starship detect";
|
||||||
|
shell = ["jj-starship" "--strip-bookmark-prefix" "cschmatzler/" "--truncate-name" "20" "--bookmarks-display-limit" "1"];
|
||||||
|
format = "$output ";
|
||||||
|
};
|
||||||
|
lua = {
|
||||||
|
symbol = " ";
|
||||||
|
};
|
||||||
|
package = {
|
||||||
|
disabled = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
27
modules/ssh-client.nix
Normal file
27
modules/ssh-client.nix
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
{...}: {
|
||||||
|
den.aspects.ssh-client.homeManager = {
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
programs.ssh = {
|
||||||
|
enable = true;
|
||||||
|
enableDefaultConfig = false;
|
||||||
|
includes = [
|
||||||
|
(lib.mkIf pkgs.stdenv.hostPlatform.isLinux "/home/${config.home.username}/.ssh/config_external")
|
||||||
|
(lib.mkIf pkgs.stdenv.hostPlatform.isDarwin "/Users/${config.home.username}/.ssh/config_external")
|
||||||
|
];
|
||||||
|
matchBlocks = {
|
||||||
|
"*" = {};
|
||||||
|
"github.com" = {
|
||||||
|
identitiesOnly = true;
|
||||||
|
identityFile = [
|
||||||
|
(lib.mkIf pkgs.stdenv.hostPlatform.isLinux "/home/${config.home.username}/.ssh/id_ed25519")
|
||||||
|
(lib.mkIf pkgs.stdenv.hostPlatform.isDarwin "/Users/${config.home.username}/.ssh/id_ed25519")
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
89
modules/tahani.nix
Normal file
89
modules/tahani.nix
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
{den, ...}: {
|
||||||
|
den.aspects.tahani.includes = [
|
||||||
|
den.aspects.nixos-system
|
||||||
|
den.aspects.core
|
||||||
|
den.aspects.openssh
|
||||||
|
den.aspects.tailscale
|
||||||
|
den.aspects.terminal
|
||||||
|
den.aspects.email
|
||||||
|
den.aspects.atuin
|
||||||
|
den.aspects.dev-tools
|
||||||
|
den.aspects.neovim
|
||||||
|
den.aspects.ai-tools
|
||||||
|
den.aspects.zellij
|
||||||
|
den.aspects.zk
|
||||||
|
];
|
||||||
|
|
||||||
|
den.aspects.tahani.nixos = {...}: {
|
||||||
|
imports = [
|
||||||
|
./_hosts/tahani/adguardhome.nix
|
||||||
|
./_hosts/tahani/cache.nix
|
||||||
|
./_hosts/tahani/networking.nix
|
||||||
|
./_hosts/tahani/paperless.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
networking.hostName = "tahani";
|
||||||
|
|
||||||
|
sops.secrets = {
|
||||||
|
tahani-paperless-password = {
|
||||||
|
sopsFile = ../secrets/tahani-paperless-password;
|
||||||
|
format = "binary";
|
||||||
|
};
|
||||||
|
tahani-email-password = {
|
||||||
|
sopsFile = ../secrets/tahani-email-password;
|
||||||
|
format = "binary";
|
||||||
|
owner = "cschmatzler";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
virtualisation.docker.enable = true;
|
||||||
|
users.users.cschmatzler.extraGroups = ["docker"];
|
||||||
|
swapDevices = [
|
||||||
|
{
|
||||||
|
device = "/swapfile";
|
||||||
|
size = 16 * 1024;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
den.aspects.tahani.homeManager = {
|
||||||
|
pkgs,
|
||||||
|
inputs',
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
opencode = inputs'.llm-agents.packages.opencode;
|
||||||
|
in {
|
||||||
|
programs.git.settings.user.email = "christoph@schmatzler.com";
|
||||||
|
|
||||||
|
# Auto-start zellij in nushell on tahani (headless server)
|
||||||
|
programs.nushell.extraConfig = ''
|
||||||
|
if 'ZELLIJ' not-in ($env | columns) {
|
||||||
|
zellij
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
|
||||||
|
# Inbox-triage systemd service
|
||||||
|
systemd.user.services.opencode-inbox-triage = {
|
||||||
|
Unit = {
|
||||||
|
Description = "OpenCode inbox triage";
|
||||||
|
};
|
||||||
|
Service = {
|
||||||
|
Type = "oneshot";
|
||||||
|
ExecStart = "${opencode}/bin/opencode run --command inbox-triage";
|
||||||
|
Environment = "PATH=${pkgs.himalaya}/bin:${opencode}/bin:${pkgs.coreutils}/bin";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.user.timers.opencode-inbox-triage = {
|
||||||
|
Unit = {
|
||||||
|
Description = "Run OpenCode inbox triage every 10 minutes";
|
||||||
|
};
|
||||||
|
Timer = {
|
||||||
|
OnCalendar = "*:0/10";
|
||||||
|
Persistent = true;
|
||||||
|
};
|
||||||
|
Install = {
|
||||||
|
WantedBy = ["timers.target"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
129
modules/terminal.nix
Normal file
129
modules/terminal.nix
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
{...}: {
|
||||||
|
den.aspects.terminal.homeManager = {pkgs, ...}: {
|
||||||
|
xdg.configFile."ghostty/config".text = ''
|
||||||
|
command = ${pkgs.nushell}/bin/nu
|
||||||
|
theme = Catppuccin Latte
|
||||||
|
window-padding-x = 12
|
||||||
|
window-padding-y = 3
|
||||||
|
window-padding-balance = true
|
||||||
|
font-family = TX-02
|
||||||
|
font-size = 16.5
|
||||||
|
cursor-style = block
|
||||||
|
mouse-hide-while-typing = true
|
||||||
|
mouse-scroll-multiplier = 1.25
|
||||||
|
shell-integration = none
|
||||||
|
shell-integration-features = no-cursor
|
||||||
|
clipboard-read = allow
|
||||||
|
clipboard-write = allow
|
||||||
|
'';
|
||||||
|
|
||||||
|
programs.bat = {
|
||||||
|
enable = true;
|
||||||
|
config = {
|
||||||
|
theme = "Catppuccin Latte";
|
||||||
|
pager = "ov";
|
||||||
|
};
|
||||||
|
themes = {
|
||||||
|
"Catppuccin Latte" = {
|
||||||
|
src =
|
||||||
|
pkgs.fetchFromGitHub {
|
||||||
|
owner = "catppuccin";
|
||||||
|
repo = "bat";
|
||||||
|
rev = "6810349b28055dce54076712fc05fc68da4b8ec0";
|
||||||
|
sha256 = "lJapSgRVENTrbmpVyn+UQabC9fpV1G1e+CdlJ090uvg=";
|
||||||
|
};
|
||||||
|
file = "themes/Catppuccin Latte.tmTheme";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.fzf = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
home.sessionVariables = {
|
||||||
|
FZF_DEFAULT_OPTS = ''
|
||||||
|
--bind=alt-k:up,alt-j:down
|
||||||
|
--expect=tab,enter
|
||||||
|
--layout=reverse
|
||||||
|
--delimiter='\t'
|
||||||
|
--with-nth=1
|
||||||
|
--preview-window='border-rounded' --prompt=' ' --marker=' ' --pointer=' '
|
||||||
|
--separator='─' --scrollbar='┃' --layout='reverse'
|
||||||
|
|
||||||
|
--color=bg+:#CCD0DA,bg:#EFF1F5,spinner:#DC8A78,hl:#D20F39
|
||||||
|
--color=fg:#4C4F69,header:#D20F39,info:#8839EF,pointer:#DC8A78
|
||||||
|
--color=marker:#7287FD,fg+:#4C4F69,prompt:#8839EF,hl+:#D20F39
|
||||||
|
--color=selected-bg:#BCC0CC
|
||||||
|
--color=border:#9CA0B0,label:#4C4F69
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.ripgrep = {
|
||||||
|
enable = true;
|
||||||
|
arguments = [
|
||||||
|
"--max-columns=150"
|
||||||
|
"--max-columns-preview"
|
||||||
|
"--hidden"
|
||||||
|
"--smart-case"
|
||||||
|
"--colors=column:none"
|
||||||
|
"--colors=column:fg:4"
|
||||||
|
"--colors=column:style:underline"
|
||||||
|
"--colors=line:none"
|
||||||
|
"--colors=line:fg:4"
|
||||||
|
"--colors=match:none"
|
||||||
|
"--colors=match:bg:0"
|
||||||
|
"--colors=match:fg:6"
|
||||||
|
"--colors=path:none"
|
||||||
|
"--colors=path:fg:14"
|
||||||
|
"--colors=path:style:bold"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.zoxide = {
|
||||||
|
enable = true;
|
||||||
|
enableNushellIntegration = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.yazi = {
|
||||||
|
enable = true;
|
||||||
|
enableNushellIntegration = true;
|
||||||
|
shellWrapperName = "y";
|
||||||
|
settings = {
|
||||||
|
manager = {
|
||||||
|
show_hidden = true;
|
||||||
|
sort_by = "natural";
|
||||||
|
sort_dir_first = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
theme = {
|
||||||
|
tabs = {
|
||||||
|
sep_inner = {
|
||||||
|
open = "";
|
||||||
|
close = "";
|
||||||
|
};
|
||||||
|
sep_outer = {
|
||||||
|
open = "";
|
||||||
|
close = "";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
indicator = {
|
||||||
|
padding = {
|
||||||
|
open = "";
|
||||||
|
close = "";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
status = {
|
||||||
|
sep_left = {
|
||||||
|
open = "";
|
||||||
|
close = "";
|
||||||
|
};
|
||||||
|
sep_right = {
|
||||||
|
open = "";
|
||||||
|
close = "";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user