Compare commits
214 Commits
a3c9102409
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 85eb20c4cb | |||
| 276378b57c | |||
| 03b968513b | |||
| e545d38314 | |||
| 564ccd2559 | |||
| f32f51970b | |||
| 0e50839ce0 | |||
| ed995a1edd | |||
| 2424b87b46 | |||
| 37ef245374 | |||
| ac40abe696 | |||
| a611d7fb99 | |||
| 89c430b940 | |||
| 1dd7d8a2d8 | |||
| 69697c822c | |||
| 8def00f368 | |||
| c907354a4f | |||
| 80ff1f8b03 | |||
| 9b5069693a | |||
| 2cad84ff26 | |||
| bbfcc366c2 | |||
| 8b09aa9705 | |||
| 0eaa830050 | |||
| 8577807650 | |||
| a186c136f0 | |||
| e6b5ff0fb8 | |||
| 6a8bda9031 | |||
| 073cc1aa38 | |||
| cea666f3d8 | |||
| 813fd347d5 | |||
| 66ff22f9e6 | |||
| 86afae7d6c | |||
| 5e46938488 | |||
| 8f3951522c | |||
| 6e5af04278 | |||
| 01cf320c2e | |||
| b69cc789b1 | |||
| 642598bbab | |||
| 31b87c7177 | |||
| aae96c7b5a | |||
| 980bd7c993 | |||
| dd77ed07e5 | |||
| 724abba247 | |||
| 9239e8dc6d | |||
| 11c816b2c2 | |||
| 901059d0cd | |||
| 4c69dddcd3 | |||
| 447d7f1dd7 | |||
| a8b07b0c30 | |||
| 94baea90d6 | |||
| 1bb97448a4 | |||
| 3ede8cd2c2 | |||
| c9e986121b | |||
| 067312dddf | |||
| a5e387a81d | |||
| 1005313bd0 | |||
| 2d3e15231a | |||
| a6cc5dcc4a | |||
| 958c332bf1 | |||
| 49fa4d623e | |||
| 4eefa6b337 | |||
| bef2afed66 | |||
| 5ad97d97a7 | |||
| 51b0bd4b1d | |||
| 19c770c163 | |||
| 9bd22bc5de | |||
| 85f2d5c19f | |||
| d3ceac88fc | |||
| 799207efaa | |||
| 260da9cbfc | |||
| 34ecdaf528 | |||
| d1964e8212 | |||
| 03228cfdf1 | |||
| 4defd577d3 | |||
| 4adc8329a1 | |||
| c859f5e41e | |||
| 7d93a9e09e | |||
| 0a79986914 | |||
| 9598d68a84 | |||
| 4f507d6bd1 | |||
| 04d7eda8c4 | |||
| 32fda4a7e9 | |||
| 6c816ae5ab | |||
| 7810be3cc1 | |||
| d2f1555309 | |||
| 80f24ce11f | |||
| 3b345614f7 | |||
| 4fa8026ce5 | |||
| f989e96fb8 | |||
| 0f39be78da | |||
| 1edbafd18a | |||
| e28dbf2236 | |||
| 944ee0e6e7 | |||
| ce490cacdc | |||
| 2452683a0c | |||
| 7be22a5210 | |||
| 3e8f143752 | |||
| 2b44191e73 | |||
| a25be94c48 | |||
| e829a9ff39 | |||
| 0c70cb0707 | |||
| b4a1f09841 | |||
| 227caee599 | |||
| 7045dee36e | |||
| d6d5b33d4c | |||
| 4b8e1215a5 | |||
| b21a150452 | |||
| b24065bf5c | |||
| 5d9f25747d | |||
| b882adc7ea | |||
| e88b11d8bb | |||
| 09d9501427 | |||
| 8f893a7216 | |||
| 12a24b83f4 | |||
| 0d9213e461 | |||
| 8c84c70152 | |||
| a92d0cfe8b | |||
| d19a0ffb81 | |||
| e4a20ddeb9 | |||
| e4d859a6ae | |||
| 627e5cc5cd | |||
| e5416214ad | |||
| ec0c33109e | |||
| bf35e81d0b | |||
| ecffadc9c4 | |||
| 110f9fa8ee | |||
| 263fe067e5 | |||
| ec04ea123d | |||
| 46cd921ef8 | |||
| f40284b3be | |||
| b45d3c65ac | |||
| 10ebe9e1af | |||
| 6b93e33607 | |||
| 5839f63ad5 | |||
| dbfcacb6e7 | |||
| c620d32c51 | |||
| aa80055d58 | |||
| 6e1547ae48 | |||
| f2b2302f61 | |||
| f357586217 | |||
| 4c29259470 | |||
| 7b72236b4c | |||
| 60120d46bf | |||
| b64a7416c9 | |||
| 3138f6ce11 | |||
| 6569d7d4d8 | |||
| eae286c5ab | |||
| e12d425df5 | |||
| 671036416b | |||
| a778a124bf | |||
| f896135f36 | |||
| 0b882455f8 | |||
| 31a6f7d5d4 | |||
| c63372082c | |||
| 82b7c96edf | |||
| c53d54865f | |||
| c4ed4758fd | |||
| e836072b51 | |||
| 5f26b3fac8 | |||
| a64db4cbe2 | |||
| 5a5e5e9b67 | |||
| 0d23f2b0f4 | |||
| f6ecc783ff | |||
| 564e6e37fd | |||
| 393c38f82f | |||
| a4f17a97c7 | |||
| bfc9af382f | |||
| 0aa8606153 | |||
| 0a955151d0 | |||
| c2a898888f | |||
| f101b5f2fc | |||
| 1d961dbb8c | |||
| ff6b0aff22 | |||
| dd59c33256 | |||
| 2e45bc69f2 | |||
| 37125d8d01 | |||
| e315aa6221 | |||
| 7d8df70308 | |||
| efb313d16a | |||
| d5197777b4 | |||
| 497b98cb70 | |||
| b662770683 | |||
| c2edf7fe47 | |||
| c4314ab4d6 | |||
| 86b0e5bd6c | |||
| 01a7f77ab8 | |||
| 4c533fc570 | |||
| 849f65e455 | |||
| 6c9a0adf23 | |||
| eb145c067f | |||
| 2213db9800 | |||
| c3345aaebb | |||
| 2a98e4f8db | |||
| c8316d578a | |||
| d65aac71ec | |||
| f55137f7ca | |||
| e463c42740 | |||
| 05544d0597 | |||
| ea3653c824 | |||
| 9ad45386b1 | |||
| 3ec12e649d | |||
| 4b26de32bb | |||
| ed157d8f67 | |||
| 18e289d8e1 | |||
| 4e0245848e | |||
| 9cce8cf9af | |||
| c19b7686d7 | |||
| 58cc4dd82a | |||
| 90e3b752b0 | |||
| 98adb4061b | |||
| 4536fb90f4 | |||
| 09d0050014 | |||
| fd24b0d613 | |||
| 0985ef935f |
@@ -1,13 +1,15 @@
|
|||||||
keys:
|
keys:
|
||||||
|
- &user_cschmatzler age1xate984yhl9qk9d4q99pyxmzz48sq56nfhu8weyzkgum4ed5tc5shjmrs7
|
||||||
- &host_tahani age1njjegjjdqzfnrr54f536yl4lduqgna3wuv7ef6vtl9jw5cju0grsgy62tm
|
- &host_tahani age1njjegjjdqzfnrr54f536yl4lduqgna3wuv7ef6vtl9jw5cju0grsgy62tm
|
||||||
- &host_michael age187jl7e4k9n4guygkmpuqzeh0wenefwrfkpvuyhvwjrjwxqpzassqq3x67j
|
- &host_michael age187jl7e4k9n4guygkmpuqzeh0wenefwrfkpvuyhvwjrjwxqpzassqq3x67j
|
||||||
- &host_jason age1ez6j3r5wdp0tjy7n5qzv5vfakdc2nh2zeu388zu7a80l0thv052syxq5e2
|
- &host_janet age1f9h725ewwwwwkelnrvdvrurg6fcsn3zxrxdt0v6v8ys0nzngcsvqu77nc8
|
||||||
- &host_chidi age1tlymdmaukhwupzrhszspp26lgd8s64rw4vu9lwc7gsgrjm78095s9fe9l3
|
- &host_chidi age1tlymdmaukhwupzrhszspp26lgd8s64rw4vu9lwc7gsgrjm78095s9fe9l3
|
||||||
creation_rules:
|
creation_rules:
|
||||||
- path_regex: secrets/[^/]+$
|
- path_regex: secrets/[^/]+$
|
||||||
key_groups:
|
key_groups:
|
||||||
- age:
|
- age:
|
||||||
|
- *user_cschmatzler
|
||||||
- *host_tahani
|
- *host_tahani
|
||||||
- *host_michael
|
- *host_michael
|
||||||
- *host_jason
|
- *host_janet
|
||||||
- *host_chidi
|
- *host_chidi
|
||||||
|
|||||||
102
AGENTS.md
102
AGENTS.md
@@ -5,19 +5,19 @@
|
|||||||
### Local Development
|
### Local Development
|
||||||
```bash
|
```bash
|
||||||
nix run .#build # Build current host config
|
nix run .#build # Build current host config
|
||||||
nix run .#build -- <hostname> # Build specific host (chidi, jason, michael, tahani)
|
nix run .#build -- <hostname> # Build specific host (chidi, janet, michael, tahani)
|
||||||
nix run .#apply # Build and apply locally (darwin-rebuild/nixos-rebuild switch)
|
nix run .#apply # Build and apply locally (darwin-rebuild/nixos-rebuild switch)
|
||||||
nix flake check # Validate flake
|
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,36 +32,51 @@ 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`
|
- `hosts/` - Per-host composition modules
|
||||||
- NixOS: `michael`, `tahani`
|
- `profiles/` - Shared host and user profile bundles
|
||||||
- **Profiles**: `profiles/` - Reusable program/service configurations (imported by hosts)
|
- `_lib/` - Utility functions (underscore = ignored by import-tree)
|
||||||
- **Modules**: `modules/` - Custom NixOS/darwin modules
|
- `_darwin/` - Darwin-specific sub-modules
|
||||||
- **Lib**: `lib/` - Shared constants and utilities
|
- `_neovim/` - Neovim plugin configs
|
||||||
|
- `hosts/_parts/` - Host-specific leaf files (disk-config, hardware, service fragments, 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>` declared in `modules/inventory.nix`
|
||||||
|
|
||||||
|
**Profiles**: shared bundles live under `modules/profiles/{host,user}` and are exposed as `den.aspects.host-*` and `den.aspects.user-*`
|
||||||
|
|
||||||
|
**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, janet) are local-only
|
||||||
|
|
||||||
### Nix Language Conventions
|
### Nix Language Conventions
|
||||||
|
|
||||||
**Function Arguments**:
|
**Function Arguments**:
|
||||||
```nix
|
```nix
|
||||||
{inputs, pkgs, lib, ...}:
|
{inputs, pkgs, lib, ...}:
|
||||||
```
|
```
|
||||||
Destructure arguments on separate lines. Use `...` to capture remaining args.
|
Use `...` to capture remaining args. Let Alejandra control the exact layout.
|
||||||
|
|
||||||
**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 +92,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 +101,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 {
|
||||||
@@ -96,7 +111,6 @@ in {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
- Destructure args on separate lines
|
|
||||||
- Use `with lib;` for brevity with NixOS lib functions
|
- Use `with lib;` for brevity with NixOS lib functions
|
||||||
- Define `cfg` for config options
|
- Define `cfg` for config options
|
||||||
- Use `mkIf`, `mkForce`, `mkDefault` appropriately
|
- Use `mkIf`, `mkForce`, `mkDefault` appropriately
|
||||||
@@ -113,22 +127,28 @@ 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`, `janet`)
|
||||||
- **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 live in per-host modules (`modules/hosts/michael.nix`, `modules/hosts/tahani.nix`, etc.)
|
||||||
|
- Shared SOPS defaults (module imports, key paths) 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
|
||||||
|
|||||||
64
README.md
Normal file
64
README.md
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
# NixOS Config
|
||||||
|
|
||||||
|
Personal Nix flake for four machines:
|
||||||
|
|
||||||
|
- `michael` - x86_64 Linux server
|
||||||
|
- `tahani` - x86_64 Linux home server / workstation
|
||||||
|
- `chidi` - aarch64 Darwin work laptop
|
||||||
|
- `janet` - aarch64 Darwin personal laptop
|
||||||
|
|
||||||
|
## Repository Map
|
||||||
|
|
||||||
|
- `modules/` - flake-parts modules, auto-imported via `import-tree`
|
||||||
|
- `modules/hosts/` - per-host composition modules
|
||||||
|
- `modules/hosts/_parts/` - host-private leaf modules like hardware, disks, and literal networking
|
||||||
|
- `modules/profiles/` - shared host and user profile bundles
|
||||||
|
- `modules/_lib/` - local helper functions
|
||||||
|
- `modules/_notability/`, `modules/_paperless/` - feature-owned scripts and templates
|
||||||
|
- `apps/` - Nushell apps exposed through the flake
|
||||||
|
- `secrets/` - SOPS-encrypted secrets
|
||||||
|
- `flake.nix` - generated flake entrypoint
|
||||||
|
- `modules/dendritic.nix` - source of truth for flake inputs and `flake.nix` generation
|
||||||
|
|
||||||
|
## How It Is Structured
|
||||||
|
|
||||||
|
This repo uses `den` and organizes configuration around aspects instead of putting everything directly in host files.
|
||||||
|
|
||||||
|
- shared behavior lives in `den.aspects.<name>.<class>` modules under `modules/*.nix`
|
||||||
|
- the machine inventory lives in `modules/inventory.nix`
|
||||||
|
- shared bundles live in `modules/profiles/{host,user}/`
|
||||||
|
- host composition happens in `modules/hosts/<host>.nix`
|
||||||
|
- host-private imports live in `modules/hosts/_parts/<host>/` and stay limited to true machine leaf files
|
||||||
|
- feature-owned services live in top-level modules like `modules/gitea.nix`, `modules/notability.nix`, and `modules/paperless.nix`
|
||||||
|
- user-level config mostly lives in Home Manager aspects
|
||||||
|
|
||||||
|
Common examples:
|
||||||
|
|
||||||
|
- `modules/core.nix` - shared Nix and shell foundation
|
||||||
|
- `modules/dev-tools.nix` - VCS, language, and developer tooling
|
||||||
|
- `modules/network.nix` - SSH, fail2ban, and tailscale aspects
|
||||||
|
- `modules/gitea.nix` - Gitea, Litestream, and backup stack for `michael`
|
||||||
|
- `modules/notability.nix` - Notability ingest services and user tooling for `tahani`
|
||||||
|
- `modules/profiles/user/workstation.nix` - shared developer workstation user bundle
|
||||||
|
- `modules/hosts/michael.nix` - server composition for `michael`
|
||||||
|
- `modules/hosts/tahani.nix` - server/workstation composition for `tahani`
|
||||||
|
|
||||||
|
## Common Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nix run .#build
|
||||||
|
nix run .#build -- michael
|
||||||
|
nix run .#apply
|
||||||
|
nix run .#deploy -- .#tahani
|
||||||
|
nix flake check
|
||||||
|
alejandra .
|
||||||
|
```
|
||||||
|
|
||||||
|
## Updating The Flake
|
||||||
|
|
||||||
|
`flake.nix` is generated. Update inputs in `modules/dendritic.nix`, then regenerate:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nix run .#write-flake
|
||||||
|
alejandra .
|
||||||
|
```
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
set -euo pipefail
|
|
||||||
source "$(dirname "$0")/../common.sh"
|
|
||||||
|
|
||||||
HOSTNAME="${1:-$(scutil --get LocalHostName 2>/dev/null || hostname -s)}"
|
|
||||||
|
|
||||||
print_info "Applying configuration for $HOSTNAME"
|
|
||||||
|
|
||||||
nix run nix-darwin -- switch --flake ".#$HOSTNAME" "${@:2}"
|
|
||||||
|
|
||||||
print_success "Configuration applied successfully"
|
|
||||||
@@ -1,16 +1,7 @@
|
|||||||
#!/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] {
|
||||||
|
build-config "darwin" $hostname ...$rest
|
||||||
print_info "Building configuration for $HOSTNAME"
|
}
|
||||||
|
|
||||||
nix build ".#darwinConfigurations.$HOSTNAME.system" --show-trace "${@:2}"
|
|
||||||
|
|
||||||
if [[ -L ./result ]]; then
|
|
||||||
unlink ./result
|
|
||||||
fi
|
|
||||||
|
|
||||||
print_success "Build completed successfully"
|
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
set -euo pipefail
|
|
||||||
source "$(dirname "$0")/../common.sh"
|
|
||||||
|
|
||||||
HOSTNAME="${1:-$(scutil --get LocalHostName 2>/dev/null || hostname -s)}"
|
|
||||||
|
|
||||||
print_info "Building and switching configuration for $HOSTNAME"
|
|
||||||
|
|
||||||
# Build
|
|
||||||
print_info "Building configuration..."
|
|
||||||
if ! nix build ".#darwinConfigurations.$HOSTNAME.system" --show-trace "${@:2}"; then
|
|
||||||
print_error "Build failed"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
print_success "Build completed"
|
|
||||||
|
|
||||||
# Switch
|
|
||||||
print_info "Switching to new configuration..."
|
|
||||||
sudo ./result/sw/bin/darwin-rebuild switch --flake ".#$HOSTNAME" "${@:2}"
|
|
||||||
|
|
||||||
if [[ -L ./result ]]; then
|
|
||||||
unlink ./result
|
|
||||||
fi
|
|
||||||
|
|
||||||
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"
|
|
||||||
|
|
||||||
|
def main [] {
|
||||||
print_info "Available generations:"
|
print_info "Available generations:"
|
||||||
darwin-rebuild --list-generations
|
darwin-rebuild --list-generations
|
||||||
|
|
||||||
echo -n "Enter generation number to rollback to: "
|
let gen_num = input "Enter generation number to rollback to: "
|
||||||
read -r GEN_NUM
|
|
||||||
|
|
||||||
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"
|
||||||
|
}
|
||||||
|
|||||||
22
apps/apply
Executable file
22
apps/apply
Executable file
@@ -0,0 +1,22 @@
|
|||||||
|
#!/usr/bin/env nu
|
||||||
|
|
||||||
|
use ./common.nu *
|
||||||
|
|
||||||
|
def main [hostname?: string, ...rest: string] {
|
||||||
|
let host = resolve-host $hostname
|
||||||
|
|
||||||
|
print_info $"Applying configuration for ($host)"
|
||||||
|
|
||||||
|
if $nu.os-info.name == "macos" {
|
||||||
|
sudo darwin-rebuild switch --flake $".#($host)" ...$rest
|
||||||
|
} else {
|
||||||
|
let euid = (id -u | str trim | into int)
|
||||||
|
if $euid != 0 {
|
||||||
|
sudo nixos-rebuild switch --flake $".#($host)" ...$rest
|
||||||
|
} else {
|
||||||
|
nixos-rebuild switch --flake $".#($host)" ...$rest
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print_success "Configuration applied successfully"
|
||||||
|
}
|
||||||
72
apps/common.nu
Normal file
72
apps/common.nu
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
#!/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)"
|
||||||
|
}
|
||||||
|
|
||||||
|
export def get-hostname [] {
|
||||||
|
if $nu.os-info.name == "macos" {
|
||||||
|
try { ^scutil --get LocalHostName | str trim } catch { ^hostname -s | str trim }
|
||||||
|
} else {
|
||||||
|
^hostname | str trim
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export def resolve-host [hostname?: string] {
|
||||||
|
if ($hostname | is-empty) {
|
||||||
|
get-hostname
|
||||||
|
} else {
|
||||||
|
$hostname
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export def cleanup-result-link [] {
|
||||||
|
if ("./result" | path exists) {
|
||||||
|
rm ./result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export def build-config [kind: string, hostname?: string, ...rest: string] {
|
||||||
|
let host = resolve-host $hostname
|
||||||
|
|
||||||
|
print_info $"Building configuration for ($host)"
|
||||||
|
|
||||||
|
if $kind == "darwin" {
|
||||||
|
nix build $".#darwinConfigurations.($host).system" --show-trace ...$rest
|
||||||
|
} else {
|
||||||
|
nix build $".#nixosConfigurations.($host).config.system.build.toplevel" --show-trace ...$rest
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup-result-link
|
||||||
|
print_success "Build completed successfully"
|
||||||
|
}
|
||||||
|
|
||||||
|
export def update-flake [inputs: list<string>] {
|
||||||
|
if ($inputs | is-empty) {
|
||||||
|
print_info "Updating all flake inputs"
|
||||||
|
nix flake update
|
||||||
|
} else {
|
||||||
|
print_info $"Updating flake inputs: ($inputs | str join ', ')"
|
||||||
|
nix flake update ...$inputs
|
||||||
|
}
|
||||||
|
|
||||||
|
print_info "Regenerating flake.nix"
|
||||||
|
nix run .#write-flake
|
||||||
|
|
||||||
|
print_info "Formatting"
|
||||||
|
alejandra .
|
||||||
|
|
||||||
|
print_success "Flake updated"
|
||||||
|
}
|
||||||
@@ -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"
|
|
||||||
}
|
|
||||||
7
apps/update
Executable file
7
apps/update
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
#!/usr/bin/env nu
|
||||||
|
|
||||||
|
use ./common.nu *
|
||||||
|
|
||||||
|
def main [...inputs: string] {
|
||||||
|
update-flake $inputs
|
||||||
|
}
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
set -euo pipefail
|
|
||||||
source "$(dirname "$0")/../common.sh"
|
|
||||||
|
|
||||||
HOSTNAME="${1:-$(hostname)}"
|
|
||||||
|
|
||||||
print_info "Applying configuration for $HOSTNAME"
|
|
||||||
|
|
||||||
if [[ "$EUID" -ne 0 ]]; then
|
|
||||||
sudo nixos-rebuild switch --flake ".#$HOSTNAME" "${@:2}"
|
|
||||||
else
|
|
||||||
nixos-rebuild switch --flake ".#$HOSTNAME" "${@:2}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
print_success "Configuration applied successfully"
|
|
||||||
@@ -1,16 +1,7 @@
|
|||||||
#!/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] {
|
||||||
|
build-config "nixos" $hostname ...$rest
|
||||||
print_info "Building configuration for $HOSTNAME"
|
}
|
||||||
|
|
||||||
nix build ".#nixosConfigurations.$HOSTNAME.config.system.build.toplevel" --show-trace "${@:2}"
|
|
||||||
|
|
||||||
if [[ -L ./result ]]; then
|
|
||||||
unlink ./result
|
|
||||||
fi
|
|
||||||
|
|
||||||
print_success "Build completed successfully"
|
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
set -euo pipefail
|
|
||||||
source "$(dirname "$0")/../common.sh"
|
|
||||||
|
|
||||||
HOSTNAME="${1:-$(hostname)}"
|
|
||||||
|
|
||||||
print_info "Building and switching configuration for $HOSTNAME"
|
|
||||||
|
|
||||||
# Build
|
|
||||||
print_info "Building configuration..."
|
|
||||||
if ! nix build ".#nixosConfigurations.$HOSTNAME.config.system.build.toplevel" --no-link "${@:2}"; then
|
|
||||||
print_error "Build failed"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
print_success "Build completed"
|
|
||||||
|
|
||||||
print_info "Switching to new configuration..."
|
|
||||||
if [[ "$EUID" -ne 0 ]]; then
|
|
||||||
sudo nixos-rebuild switch --flake ".#$HOSTNAME" "${@:2}"
|
|
||||||
else
|
|
||||||
nixos-rebuild switch --flake ".#$HOSTNAME" "${@:2}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
print_success "Build and switch completed successfully"
|
|
||||||
38
apps/x86_64-linux/rollback
Normal file → Executable file
38
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"
|
|
||||||
|
|
||||||
|
def main [] {
|
||||||
print_info "Available generations:"
|
print_info "Available generations:"
|
||||||
if [[ "$EUID" -ne 0 ]]; then
|
|
||||||
|
let euid = (id -u | str trim | into int)
|
||||||
|
|
||||||
|
if $euid != 0 {
|
||||||
sudo nix-env --profile /nix/var/nix/profiles/system --list-generations
|
sudo nix-env --profile /nix/var/nix/profiles/system --list-generations
|
||||||
else
|
} else {
|
||||||
nix-env --profile /nix/var/nix/profiles/system --list-generations
|
nix-env --profile /nix/var/nix/profiles/system --list-generations
|
||||||
fi
|
}
|
||||||
|
|
||||||
echo -n "Enter generation number to rollback to: "
|
let gen_num = input "Enter generation number to rollback to: "
|
||||||
read -r GEN_NUM
|
|
||||||
|
|
||||||
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)..."
|
||||||
if [[ "$EUID" -ne 0 ]]; then
|
|
||||||
sudo nix-env --profile /nix/var/nix/profiles/system --switch-generation "$GEN_NUM" && \
|
if $euid != 0 {
|
||||||
|
sudo nix-env --profile /nix/var/nix/profiles/system --switch-generation $gen_num
|
||||||
sudo /nix/var/nix/profiles/system/bin/switch-to-configuration switch
|
sudo /nix/var/nix/profiles/system/bin/switch-to-configuration switch
|
||||||
else
|
} else {
|
||||||
nix-env --profile /nix/var/nix/profiles/system --switch-generation "$GEN_NUM" && \
|
nix-env --profile /nix/var/nix/profiles/system --switch-generation $gen_num
|
||||||
/nix/var/nix/profiles/system/bin/switch-to-configuration switch
|
/nix/var/nix/profiles/system/bin/switch-to-configuration switch
|
||||||
fi
|
}
|
||||||
|
|
||||||
print_success "Rollback to generation $GEN_NUM complete"
|
print_success $"Rollback to generation ($gen_num) complete"
|
||||||
|
}
|
||||||
|
|||||||
626
flake.lock
generated
626
flake.lock
generated
@@ -6,7 +6,10 @@
|
|||||||
"llm-agents",
|
"llm-agents",
|
||||||
"nixpkgs"
|
"nixpkgs"
|
||||||
],
|
],
|
||||||
"systems": "systems_2"
|
"systems": [
|
||||||
|
"llm-agents",
|
||||||
|
"systems"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1771437256,
|
"lastModified": 1771437256,
|
||||||
@@ -25,41 +28,67 @@
|
|||||||
"brew-src": {
|
"brew-src": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1769363988,
|
"lastModified": 1774235677,
|
||||||
"narHash": "sha256-BiGPeulrDVetXP+tjxhMcGLUROZAtZIhU5m4MqawCfM=",
|
"narHash": "sha256-0ryNYmzDAeRlrzPTAgmzGH/Cgc8iv/LBN6jWGUANvIk=",
|
||||||
"owner": "Homebrew",
|
"owner": "Homebrew",
|
||||||
"repo": "brew",
|
"repo": "brew",
|
||||||
"rev": "d01011cac6d72032c75fd2cd9489909e95d9faf2",
|
"rev": "894a3d23ac0c8aaf561b9874b528b9cb2e839201",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "Homebrew",
|
"owner": "Homebrew",
|
||||||
"ref": "5.0.12",
|
"ref": "5.1.1",
|
||||||
"repo": "brew",
|
"repo": "brew",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"colmena": {
|
"bun2nix": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-compat": "flake-compat",
|
"flake-parts": [
|
||||||
"flake-utils": "flake-utils",
|
"llm-agents",
|
||||||
"nix-github-actions": "nix-github-actions",
|
"flake-parts"
|
||||||
|
],
|
||||||
|
"import-tree": "import-tree_2",
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
|
"llm-agents",
|
||||||
"nixpkgs"
|
"nixpkgs"
|
||||||
],
|
],
|
||||||
"stable": "stable"
|
"systems": [
|
||||||
|
"llm-agents",
|
||||||
|
"systems"
|
||||||
|
],
|
||||||
|
"treefmt-nix": [
|
||||||
|
"llm-agents",
|
||||||
|
"treefmt-nix"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1762034856,
|
"lastModified": 1770895533,
|
||||||
"narHash": "sha256-QVey3iP3UEoiFVXgypyjTvCrsIlA4ecx6Acaz5C8/PQ=",
|
"narHash": "sha256-v3QaK9ugy9bN9RXDnjw0i2OifKmz2NnKM82agtqm/UY=",
|
||||||
"owner": "zhaofengli",
|
"owner": "nix-community",
|
||||||
"repo": "colmena",
|
"repo": "bun2nix",
|
||||||
"rev": "349b035a5027f23d88eeb3bc41085d7ee29f18ed",
|
"rev": "c843f477b15f51151f8c6bcc886954699440a6e1",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "zhaofengli",
|
"owner": "nix-community",
|
||||||
"repo": "colmena",
|
"repo": "bun2nix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"code-review-nvim": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1765543014,
|
||||||
|
"narHash": "sha256-WpbQswkUpB4Nblos8+5UE5I/PHUQOi+RQ+hj4CCdL4o=",
|
||||||
|
"owner": "choplin",
|
||||||
|
"repo": "code-review.nvim",
|
||||||
|
"rev": "ed91462e20bd08c3be71efb11a4a7d00459f0b47",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "choplin",
|
||||||
|
"repo": "code-review.nvim",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -85,11 +114,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772379624,
|
"lastModified": 1775037210,
|
||||||
"narHash": "sha256-NG9LLTWlz4YiaTAiRGChbrzbVxBfX+Auq4Ab/SWmk4A=",
|
"narHash": "sha256-KM2WYj6EA7M/FVZVCl3rqWY+TFV5QzSyyGE2gQxeODU=",
|
||||||
"owner": "LnL7",
|
"owner": "LnL7",
|
||||||
"repo": "nix-darwin",
|
"repo": "nix-darwin",
|
||||||
"rev": "52d061516108769656a8bd9c6e811c677ec5b462",
|
"rev": "06648f4902343228ce2de79f291dd5a58ee12146",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -99,6 +128,41 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"den": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1775702491,
|
||||||
|
"narHash": "sha256-5BCNtE/zCLSheltliy4hTdwsq0Boj/W1XRIX8n89nqA=",
|
||||||
|
"owner": "vic",
|
||||||
|
"repo": "den",
|
||||||
|
"rev": "d267c458e384b57317d06d45f7c65f7fb03fae4b",
|
||||||
|
"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": [
|
||||||
@@ -106,11 +170,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772420042,
|
"lastModified": 1773889306,
|
||||||
"narHash": "sha256-naZz40TUFMa0E0CutvwWsSPhgD5JldyTUDEgP9ADpfU=",
|
"narHash": "sha256-PAqwnsBSI9SVC2QugvQ3xeYCB0otOwCacB1ueQj2tgw=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "disko",
|
"repo": "disko",
|
||||||
"rev": "5af7af10f14706e4095bd6bc0d9373eb097283c6",
|
"rev": "5ad85c82cc52264f4beddc934ba57f3789f28347",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -122,11 +186,32 @@
|
|||||||
"fenix": {
|
"fenix": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
"himalaya",
|
|
||||||
"nixpkgs"
|
"nixpkgs"
|
||||||
],
|
],
|
||||||
"rust-analyzer-src": "rust-analyzer-src"
|
"rust-analyzer-src": "rust-analyzer-src"
|
||||||
},
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1775721346,
|
||||||
|
"narHash": "sha256-ogqjruvVBYEj8sWM3viOucSo1Pna9c147EKQOfA+p3I=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "fenix",
|
||||||
|
"rev": "99fde43dfee2a672e4e37ef211e0844337e5b725",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "fenix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fenix_2": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"himalaya",
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"rust-analyzer-src": "rust-analyzer-src_2"
|
||||||
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1767250179,
|
"lastModified": 1767250179,
|
||||||
"narHash": "sha256-PnQdWvPZqHp+7yaHWDFX3NYSKaOy0fjkwpR+rIQC7AY=",
|
"narHash": "sha256-PnQdWvPZqHp+7yaHWDFX3NYSKaOy0fjkwpR+rIQC7AY=",
|
||||||
@@ -142,14 +227,51 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"fenix_3": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"naersk",
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"rust-analyzer-src": "rust-analyzer-src_3"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1752475459,
|
||||||
|
"narHash": "sha256-z6QEu4ZFuHiqdOPbYss4/Q8B0BFhacR8ts6jO/F/aOU=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "fenix",
|
||||||
|
"rev": "bf0d6f70f4c9a9cf8845f992105652173f4b617f",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "fenix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-aspects": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1773552804,
|
||||||
|
"narHash": "sha256-a0kjpCZGnD5lt7yW6C3hzPhSf5KjnTyvX6XZ2NuhGs4=",
|
||||||
|
"owner": "vic",
|
||||||
|
"repo": "flake-aspects",
|
||||||
|
"rev": "56fa8d4d4772d58eb7f9d66c28c1cd2762b60423",
|
||||||
|
"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": {
|
||||||
@@ -158,16 +280,33 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"flake-file": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1774886516,
|
||||||
|
"narHash": "sha256-w2LoQVM6DXrSdGUZBZqa1nYkMzHoB0t82DrptzZKhTs=",
|
||||||
|
"owner": "vic",
|
||||||
|
"repo": "flake-file",
|
||||||
|
"rev": "3daadf37de2bb85b0ff34e2a7ab0d71e077c2b9e",
|
||||||
|
"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": 1775087534,
|
||||||
"narHash": "sha256-rHuJtdcOjK7rAHpHphUb1iCvgkU3GpfvicLMwwnfMT0=",
|
"narHash": "sha256-91qqW8lhL7TLwgQWijoGBbiD4t7/q75KTi8NxjVmSmA=",
|
||||||
"owner": "hercules-ci",
|
"owner": "hercules-ci",
|
||||||
"repo": "flake-parts",
|
"repo": "flake-parts",
|
||||||
"rev": "f20dc5d9b8027381c474144ecabc9034d6a839a3",
|
"rev": "3107b77cd68437b9a76194f0f7f9c55f2329ca5b",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -177,6 +316,48 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flake-parts_2": {
|
"flake-parts_2": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs-lib": [
|
||||||
|
"llm-agents",
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1775087534,
|
||||||
|
"narHash": "sha256-91qqW8lhL7TLwgQWijoGBbiD4t7/q75KTi8NxjVmSmA=",
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"rev": "3107b77cd68437b9a76194f0f7f9c55f2329ca5b",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-parts_3": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs-lib": [
|
||||||
|
"neovim-nightly-overlay",
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1775087534,
|
||||||
|
"narHash": "sha256-91qqW8lhL7TLwgQWijoGBbiD4t7/q75KTi8NxjVmSmA=",
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"rev": "3107b77cd68437b9a76194f0f7f9c55f2329ca5b",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-parts_4": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs-lib": [
|
"nixpkgs-lib": [
|
||||||
"nixvim",
|
"nixvim",
|
||||||
@@ -198,23 +379,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,
|
||||||
@@ -230,9 +396,9 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flake-utils_3": {
|
"flake-utils_2": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"systems": "systems_4"
|
"systems": "systems_5"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1731533236,
|
"lastModified": 1731533236,
|
||||||
@@ -250,8 +416,8 @@
|
|||||||
},
|
},
|
||||||
"himalaya": {
|
"himalaya": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"fenix": "fenix",
|
"fenix": "fenix_2",
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs_2",
|
||||||
"pimalaya": "pimalaya"
|
"pimalaya": "pimalaya"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
@@ -275,11 +441,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772569491,
|
"lastModified": 1775683737,
|
||||||
"narHash": "sha256-bdr6ueeXO1Xg91sFkuvaysYF0mVdwHBpdyhTjBEWv+s=",
|
"narHash": "sha256-oBYyowo6yfgb95Z78s3uTnAd9KkpJpwzjJbfnpLaM2Y=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"rev": "924e61f5c2aeab38504028078d7091077744ab17",
|
"rev": "7ba4ee4228ed36123c7cb75d50524b43514ef992",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -291,11 +457,11 @@
|
|||||||
"homebrew-cask": {
|
"homebrew-cask": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772604536,
|
"lastModified": 1775700724,
|
||||||
"narHash": "sha256-vrxMf1pJ+Ha8IOKqpGmTgxHbm8n2RnWLPf+7eQ07JQw=",
|
"narHash": "sha256-qQm9uIF+tI7gamLMa7DSXSQQzLQalEtOa7PHPxNkbr8=",
|
||||||
"owner": "homebrew",
|
"owner": "homebrew",
|
||||||
"repo": "homebrew-cask",
|
"repo": "homebrew-cask",
|
||||||
"rev": "516018702882dab40819690742e91186c0454793",
|
"rev": "c622bff3b88557e3c870104db0426b93e0767a8f",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -307,11 +473,11 @@
|
|||||||
"homebrew-core": {
|
"homebrew-core": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772616642,
|
"lastModified": 1775721921,
|
||||||
"narHash": "sha256-4M1w/6k94xSKxJif11K+cxGNaGy5rxyBq9J63uRZ5lY=",
|
"narHash": "sha256-s6K2QbKa4OJlblFp3zMSh0/2PM2zpWpAd4ZnREirj/I=",
|
||||||
"owner": "homebrew",
|
"owner": "homebrew",
|
||||||
"repo": "homebrew-core",
|
"repo": "homebrew-core",
|
||||||
"rev": "5ca972b7adf504a678b5d15774708c28cad4bbb2",
|
"rev": "70028a68b515145bbeccb2961240275ab6eb9e82",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -320,6 +486,68 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"import-tree": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1773693634,
|
||||||
|
"narHash": "sha256-BtZ2dtkBdSUnFPPFc+n0kcMbgaTxzFNPv2iaO326Ffg=",
|
||||||
|
"owner": "vic",
|
||||||
|
"repo": "import-tree",
|
||||||
|
"rev": "c41e7d58045f9057880b0d85e1152d6a4430dbf1",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "vic",
|
||||||
|
"repo": "import-tree",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"import-tree_2": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1763762820,
|
||||||
|
"narHash": "sha256-ZvYKbFib3AEwiNMLsejb/CWs/OL/srFQ8AogkebEPF0=",
|
||||||
|
"owner": "vic",
|
||||||
|
"repo": "import-tree",
|
||||||
|
"rev": "3c23749d8013ec6daa1d7255057590e9ca726646",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "vic",
|
||||||
|
"repo": "import-tree",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"jj-diffconflicts": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1774204449,
|
||||||
|
"narHash": "sha256-CDLOo07tGOg/7Sowb1d39k9Nq/RW50axGj8L1D3Be70=",
|
||||||
|
"owner": "rafikdraoui",
|
||||||
|
"repo": "jj-diffconflicts",
|
||||||
|
"rev": "58163ae8fe7646179dfd7741206dd9a2b4cdadc0",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "rafikdraoui",
|
||||||
|
"repo": "jj-diffconflicts",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"jj-nvim": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1775551442,
|
||||||
|
"narHash": "sha256-hoU+DenrgxNwvLNmDtIsJ5yB5fhRjDRPOOL8WW9bpZM=",
|
||||||
|
"owner": "NicolasGB",
|
||||||
|
"repo": "jj.nvim",
|
||||||
|
"rev": "2dbe2c73c599a29e86e4123b42e430828b1f01d9",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NicolasGB",
|
||||||
|
"repo": "jj.nvim",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"jj-ryu": {
|
"jj-ryu": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
@@ -338,8 +566,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,
|
||||||
@@ -358,15 +586,18 @@
|
|||||||
"llm-agents": {
|
"llm-agents": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"blueprint": "blueprint",
|
"blueprint": "blueprint",
|
||||||
"nixpkgs": "nixpkgs_3",
|
"bun2nix": "bun2nix",
|
||||||
|
"flake-parts": "flake-parts_2",
|
||||||
|
"nixpkgs": "nixpkgs_4",
|
||||||
|
"systems": "systems_3",
|
||||||
"treefmt-nix": "treefmt-nix"
|
"treefmt-nix": "treefmt-nix"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772605697,
|
"lastModified": 1775705124,
|
||||||
"narHash": "sha256-VOvCw5I28nIcy3mFs88M/Unzj4uKiUrIJK6S69kHOCU=",
|
"narHash": "sha256-OUtgrn0k7DYnAP9skY2rOJSWJyn4w5tnUcF3lSJdfME=",
|
||||||
"owner": "numtide",
|
"owner": "numtide",
|
||||||
"repo": "llm-agents.nix",
|
"repo": "llm-agents.nix",
|
||||||
"rev": "705bb4900230a4e7bdd42bd8f34cb3a4558e593b",
|
"rev": "ca76524952b00135dba57da62ce2dd123a1ba4be",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -375,24 +606,63 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nix-github-actions": {
|
"naersk": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
|
"fenix": "fenix_3",
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
"colmena",
|
|
||||||
"nixpkgs"
|
"nixpkgs"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1729742964,
|
"lastModified": 1769799857,
|
||||||
"narHash": "sha256-B4mzTcQ0FZHdpeWcpDYPERtyjJd/NIuaQ9+BV1h+MpA=",
|
"narHash": "sha256-88IFXZ7Sa1vxbz5pty0Io5qEaMQMMUPMonLa3Ls/ss4=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "nix-github-actions",
|
"repo": "naersk",
|
||||||
"rev": "e04df33f62cdcf93d73e9a04142464753a16db67",
|
"rev": "9d4ed44d8b8cecdceb1d6fd76e74123d90ae6339",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "nix-github-actions",
|
"ref": "master",
|
||||||
|
"repo": "naersk",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"neovim-nightly-overlay": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-parts": "flake-parts_3",
|
||||||
|
"neovim-src": "neovim-src",
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1775693082,
|
||||||
|
"narHash": "sha256-nnhkpfWsRutQh//KmVoIV7e9Gk90tBezjcoRr775BfU=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "neovim-nightly-overlay",
|
||||||
|
"rev": "21b2795e6aeb4a0110bdc7bd81bad59c022c9986",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "neovim-nightly-overlay",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"neovim-src": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1775689880,
|
||||||
|
"narHash": "sha256-savZYhFAaBm3BQUdTrPOv7i5K18JFANJvyHv0uuvaWM=",
|
||||||
|
"owner": "neovim",
|
||||||
|
"repo": "neovim",
|
||||||
|
"rev": "eefb50e352a689ec1a0a55d6827abea79960cd3d",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "neovim",
|
||||||
|
"repo": "neovim",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -401,11 +671,11 @@
|
|||||||
"brew-src": "brew-src"
|
"brew-src": "brew-src"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1769437432,
|
"lastModified": 1774720267,
|
||||||
"narHash": "sha256-8d7KnCpT2LweRvSzZYEGd9IM3eFX+A78opcnDM0+ndk=",
|
"narHash": "sha256-YYftFe8jyfpQI649yfr0E+dqEXE2jznZNcYvy/lKV1U=",
|
||||||
"owner": "zhaofengli-wip",
|
"owner": "zhaofengli-wip",
|
||||||
"repo": "nix-homebrew",
|
"repo": "nix-homebrew",
|
||||||
"rev": "a5409abd0d5013d79775d3419bcac10eacb9d8c5",
|
"rev": "a7760a3a83f7609f742861afb5732210fdc437ed",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -415,6 +685,22 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1743014863,
|
||||||
|
"narHash": "sha256-jAIUqsiN2r3hCuHji80U7NNEafpIMBXiwKlSrjWMlpg=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "bd3bac8bfb542dbde7ffffb6987a1a1f9d41699f",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixpkgs-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1736437047,
|
"lastModified": 1736437047,
|
||||||
"narHash": "sha256-JJBziecfU+56SUNxeJlDIgixJN5WYuADd+/TVd5sQos=",
|
"narHash": "sha256-JJBziecfU+56SUNxeJlDIgixJN5WYuADd+/TVd5sQos=",
|
||||||
@@ -430,22 +716,7 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs-lib": {
|
"nixpkgs_3": {
|
||||||
"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_2": {
|
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1766840161,
|
"lastModified": 1766840161,
|
||||||
"narHash": "sha256-Ss/LHpJJsng8vz1Pe33RSGIWUOcqM1fjrehjUkdrWio=",
|
"narHash": "sha256-Ss/LHpJJsng8vz1Pe33RSGIWUOcqM1fjrehjUkdrWio=",
|
||||||
@@ -461,13 +732,13 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs_3": {
|
"nixpkgs_4": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772554988,
|
"lastModified": 1775639890,
|
||||||
"narHash": "sha256-8Kb+MSE6QYVX1S96aZOluOMVfvSEOs70vgX980qVUaY=",
|
"narHash": "sha256-9O9gNidrdzcb7vgKGtff7QiLtr0IsVaCi0pAXm8anhQ=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "87f6b6e02cb3f87a1be4f939326c94c8af9d55d8",
|
"rev": "456e8a9468b9d46bd8c9524425026c00745bc4d2",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -477,13 +748,13 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs_4": {
|
"nixpkgs_5": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772616530,
|
"lastModified": 1775722436,
|
||||||
"narHash": "sha256-uBNYd+ER7FYm8r6ijiiHsagcQOGwP4Gp8kPVARQ/Qos=",
|
"narHash": "sha256-Z7QmfL80jmUPoSQkMlCc+1MGfkugf7bG47H3UTsyi7Q=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "1e3ada21dc0d2493ddf46e1ea0c812c54ec7f1ec",
|
"rev": "e73a61d035ee91f95bb0a6b95ce0b9d2866bd332",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -493,7 +764,7 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs_5": {
|
"nixpkgs_6": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1770380644,
|
"lastModified": 1770380644,
|
||||||
"narHash": "sha256-P7dWMHRUWG5m4G+06jDyThXO7kwSk46C1kgjEWcybkE=",
|
"narHash": "sha256-P7dWMHRUWG5m4G+06jDyThXO7kwSk46C1kgjEWcybkE=",
|
||||||
@@ -509,7 +780,7 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs_6": {
|
"nixpkgs_7": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1765934234,
|
"lastModified": 1765934234,
|
||||||
"narHash": "sha256-pJjWUzNnjbIAMIc5gRFUuKCDQ9S1cuh3b2hKgA7Mc4A=",
|
"narHash": "sha256-pJjWUzNnjbIAMIc5gRFUuKCDQ9S1cuh3b2hKgA7Mc4A=",
|
||||||
@@ -527,16 +798,16 @@
|
|||||||
},
|
},
|
||||||
"nixvim": {
|
"nixvim": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-parts": "flake-parts_2",
|
"flake-parts": "flake-parts_4",
|
||||||
"nixpkgs": "nixpkgs_5",
|
"nixpkgs": "nixpkgs_6",
|
||||||
"systems": "systems_3"
|
"systems": "systems_4"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772402258,
|
"lastModified": 1775307257,
|
||||||
"narHash": "sha256-3DmCFOdmbkFML1/G9gj8Wb+rCCZFPOQtNoMCpqOF8SA=",
|
"narHash": "sha256-y9hEecHH4ennFwIcw1n480YCGh73DkEmizmQnyXuvgg=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "nixvim",
|
"repo": "nixvim",
|
||||||
"rev": "21ae25e13b01d3b4cdc750b5f9e7bad68b150c10",
|
"rev": "2e008bb941f72379d5b935d5bfe70ed8b7c793ff",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -545,22 +816,6 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"overseer": {
|
|
||||||
"flake": false,
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1770303305,
|
|
||||||
"narHash": "sha256-NM1haQAk1mWdmewgIv6tzApaIQxWKrIrri0+uXHY3Zc=",
|
|
||||||
"owner": "dmmulroy",
|
|
||||||
"repo": "overseer",
|
|
||||||
"rev": "5880d97939744ff72eb552c671da2fae1789041e",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "dmmulroy",
|
|
||||||
"repo": "overseer",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pimalaya": {
|
"pimalaya": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
@@ -579,26 +834,55 @@
|
|||||||
},
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"colmena": "colmena",
|
"code-review-nvim": "code-review-nvim",
|
||||||
"darwin": "darwin",
|
"darwin": "darwin",
|
||||||
|
"den": "den",
|
||||||
|
"deploy-rs": "deploy-rs",
|
||||||
"disko": "disko",
|
"disko": "disko",
|
||||||
|
"fenix": "fenix",
|
||||||
|
"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-diffconflicts": "jj-diffconflicts",
|
||||||
|
"jj-nvim": "jj-nvim",
|
||||||
"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",
|
||||||
|
"neovim-nightly-overlay": "neovim-nightly-overlay",
|
||||||
"nix-homebrew": "nix-homebrew",
|
"nix-homebrew": "nix-homebrew",
|
||||||
"nixpkgs": "nixpkgs_4",
|
"nixpkgs": "nixpkgs_5",
|
||||||
|
"nixpkgs-lib": [
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
"nixvim": "nixvim",
|
"nixvim": "nixvim",
|
||||||
"overseer": "overseer",
|
|
||||||
"sops-nix": "sops-nix",
|
"sops-nix": "sops-nix",
|
||||||
"zjstatus": "zjstatus"
|
"zjstatus": "zjstatus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"rust-analyzer-src": {
|
"rust-analyzer-src": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1775663707,
|
||||||
|
"narHash": "sha256-3cSvpBETRa8aDSrUCX1jGc6FSse3OWB7cXACIZW8BYI=",
|
||||||
|
"owner": "rust-lang",
|
||||||
|
"repo": "rust-analyzer",
|
||||||
|
"rev": "8c5af725817905e462052d91a8d229b85ffa83a5",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "rust-lang",
|
||||||
|
"ref": "nightly",
|
||||||
|
"repo": "rust-analyzer",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rust-analyzer-src_2": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1767191410,
|
"lastModified": 1767191410,
|
||||||
@@ -615,6 +899,23 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"rust-analyzer-src_3": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1752428706,
|
||||||
|
"narHash": "sha256-EJcdxw3aXfP8Ex1Nm3s0awyH9egQvB2Gu+QEnJn2Sfg=",
|
||||||
|
"owner": "rust-lang",
|
||||||
|
"repo": "rust-analyzer",
|
||||||
|
"rev": "591e3b7624be97e4443ea7b5542c191311aa141d",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "rust-lang",
|
||||||
|
"ref": "nightly",
|
||||||
|
"repo": "rust-analyzer",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"rust-overlay": {
|
"rust-overlay": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
@@ -643,11 +944,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772495394,
|
"lastModified": 1775682595,
|
||||||
"narHash": "sha256-hmIvE/slLKEFKNEJz27IZ8BKlAaZDcjIHmkZ7GCEjfw=",
|
"narHash": "sha256-0E9PohY/VuESLq0LR4doaH7hTag513sDDW5n5qmHd1Q=",
|
||||||
"owner": "Mic92",
|
"owner": "Mic92",
|
||||||
"repo": "sops-nix",
|
"repo": "sops-nix",
|
||||||
"rev": "1d9b98a29a45abe9c4d3174bd36de9f28755e3ff",
|
"rev": "d2e8438d5886e92bc5e7c40c035ab6cae0c41f76",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -656,22 +957,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,
|
||||||
@@ -732,6 +1017,21 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"systems_5": {
|
||||||
|
"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": [
|
||||||
@@ -740,11 +1040,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1770228511,
|
"lastModified": 1775636079,
|
||||||
"narHash": "sha256-wQ6NJSuFqAEmIg2VMnLdCnUc0b7vslUohqqGGD+Fyxk=",
|
"narHash": "sha256-pc20NRoMdiar8oPQceQT47UUZMBTiMdUuWrYu2obUP0=",
|
||||||
"owner": "numtide",
|
"owner": "numtide",
|
||||||
"repo": "treefmt-nix",
|
"repo": "treefmt-nix",
|
||||||
"rev": "337a4fe074be1042a35086f15481d763b8ddc0e7",
|
"rev": "790751ff7fd3801feeaf96d7dc416a8d581265ba",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -753,19 +1053,37 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"utils": {
|
||||||
|
"inputs": {
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
},
|
||||||
"zjstatus": {
|
"zjstatus": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"crane": "crane",
|
"crane": "crane",
|
||||||
"flake-utils": "flake-utils_3",
|
"flake-utils": "flake-utils_2",
|
||||||
"nixpkgs": "nixpkgs_6",
|
"nixpkgs": "nixpkgs_7",
|
||||||
"rust-overlay": "rust-overlay"
|
"rust-overlay": "rust-overlay"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1771148613,
|
"lastModified": 1773119656,
|
||||||
"narHash": "sha256-nLzdw8jskekSRrunxBDCA0NCHr/2aJjcXqZ1Fcqm5eY=",
|
"narHash": "sha256-AE6SthrvDyUU70myW7wAq4mzQbtmK5Spng7Y/OdCdhI=",
|
||||||
"owner": "dj95",
|
"owner": "dj95",
|
||||||
"repo": "zjstatus",
|
"repo": "zjstatus",
|
||||||
"rev": "7a039f56da80681408454d6e175fde3f54b9e592",
|
"rev": "e80d508ffbff6ab6b39a481ae9986109d3c313ac",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
194
flake.nix
194
flake.nix
@@ -1,167 +1,77 @@
|
|||||||
|
# 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";
|
code-review-nvim = {
|
||||||
flake-parts.url = "github:hercules-ci/flake-parts";
|
url = "github:choplin/code-review.nvim";
|
||||||
sops-nix = {
|
flake = false;
|
||||||
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";
|
url = "github:LnL7/nix-darwin/master";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
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;
|
url = "github:nix-community/disko";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
fenix = {
|
||||||
|
url = "github:nix-community/fenix";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
flake-aspects.url = "github:vic/flake-aspects";
|
||||||
|
flake-file.url = "github:vic/flake-file";
|
||||||
|
flake-parts = {
|
||||||
|
url = "github:hercules-ci/flake-parts";
|
||||||
|
inputs.nixpkgs-lib.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
himalaya.url = "github:pimalaya/himalaya";
|
||||||
|
home-manager = {
|
||||||
|
url = "github:nix-community/home-manager";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
homebrew-cask = {
|
homebrew-cask = {
|
||||||
url = "github:homebrew/homebrew-cask";
|
url = "github:homebrew/homebrew-cask";
|
||||||
flake = false;
|
flake = false;
|
||||||
};
|
};
|
||||||
nixvim.url = "github:nix-community/nixvim";
|
homebrew-core = {
|
||||||
zjstatus.url = "github:dj95/zjstatus";
|
url = "github:homebrew/homebrew-core";
|
||||||
llm-agents.url = "github:numtide/llm-agents.nix";
|
flake = false;
|
||||||
disko = {
|
|
||||||
url = "github:nix-community/disko";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
};
|
};
|
||||||
colmena = {
|
import-tree.url = "github:vic/import-tree";
|
||||||
url = "github:zhaofengli/colmena";
|
jj-diffconflicts = {
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
url = "github:rafikdraoui/jj-diffconflicts";
|
||||||
|
flake = false;
|
||||||
|
};
|
||||||
|
jj-nvim = {
|
||||||
|
url = "github:NicolasGB/jj.nvim";
|
||||||
|
flake = false;
|
||||||
};
|
};
|
||||||
jj-ryu = {
|
jj-ryu = {
|
||||||
url = "github:dmmulroy/jj-ryu";
|
url = "github:dmmulroy/jj-ryu";
|
||||||
flake = false;
|
flake = false;
|
||||||
};
|
};
|
||||||
jj-starship.url = "github:dmmulroy/jj-starship";
|
jj-starship.url = "github:dmmulroy/jj-starship";
|
||||||
overseer = {
|
llm-agents.url = "github:numtide/llm-agents.nix";
|
||||||
url = "github:dmmulroy/overseer";
|
naersk = {
|
||||||
flake = false;
|
url = "github:nix-community/naersk/master";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
himalaya.url = "github:pimalaya/himalaya";
|
neovim-nightly-overlay = {
|
||||||
|
url = "github:nix-community/neovim-nightly-overlay";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
nix-homebrew.url = "github:zhaofengli-wip/nix-homebrew";
|
||||||
outputs = inputs @ {flake-parts, ...}:
|
nixpkgs.url = "github:nixos/nixpkgs/master";
|
||||||
flake-parts.lib.mkFlake {inherit inputs;} (
|
nixpkgs-lib.follows = "nixpkgs";
|
||||||
let
|
nixvim.url = "github:nix-community/nixvim";
|
||||||
inherit (inputs.nixpkgs) lib;
|
sops-nix = {
|
||||||
constants = import ./lib/constants.nix;
|
url = "github:Mic92/sops-nix";
|
||||||
inherit (constants) user;
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
|
||||||
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;
|
|
||||||
};
|
};
|
||||||
|
zjstatus.url = "github:dj95/zjstatus";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
./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,60 +0,0 @@
|
|||||||
{
|
|
||||||
services.adguardhome = {
|
|
||||||
enable = true;
|
|
||||||
host = "0.0.0.0";
|
|
||||||
port = 10000;
|
|
||||||
settings = {
|
|
||||||
dhcp = {
|
|
||||||
enabled = false;
|
|
||||||
};
|
|
||||||
dns = {
|
|
||||||
upstream_dns = [
|
|
||||||
"1.1.1.1"
|
|
||||||
"1.0.0.1"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
filtering = {
|
|
||||||
protection_enabled = true;
|
|
||||||
filtering_enabled = true;
|
|
||||||
safe_search = {
|
|
||||||
enabled = false;
|
|
||||||
};
|
|
||||||
safebrowsing_enabled = true;
|
|
||||||
blocked_response_ttl = 10;
|
|
||||||
filters_update_interval = 24;
|
|
||||||
blocked_services = {
|
|
||||||
ids = [
|
|
||||||
"reddit"
|
|
||||||
"twitter"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
filters = [
|
|
||||||
{
|
|
||||||
enabled = true;
|
|
||||||
url = "https://cdn.jsdelivr.net/gh/hagezi/dns-blocklists@latest/adblock/pro.txt";
|
|
||||||
name = "HaGeZi Multi PRO";
|
|
||||||
id = 1;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
enabled = true;
|
|
||||||
url = "https://cdn.jsdelivr.net/gh/hagezi/dns-blocklists@latest/adblock/tif.txt";
|
|
||||||
name = "HaGeZi Threat Intelligence Feeds";
|
|
||||||
id = 2;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
enabled = true;
|
|
||||||
url = "https://cdn.jsdelivr.net/gh/hagezi/dns-blocklists@latest/adblock/gambling.txt";
|
|
||||||
name = "HaGeZi Gambling";
|
|
||||||
id = 3;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
enabled = true;
|
|
||||||
url = "https://cdn.jsdelivr.net/gh/hagezi/dns-blocklists@latest/adblock/nsfw.txt";
|
|
||||||
name = "HaGeZi NSFW";
|
|
||||||
id = 4;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
{...}: {
|
|
||||||
services.caddy.virtualHosts."cache.manticore-hippocampus.ts.net" = {
|
|
||||||
extraConfig = ''
|
|
||||||
tls {
|
|
||||||
get_certificate tailscale
|
|
||||||
}
|
|
||||||
reverse_proxy localhost:32843
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,95 +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/overseer.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,73 +0,0 @@
|
|||||||
{config, ...}: {
|
|
||||||
services.caddy = {
|
|
||||||
enable = true;
|
|
||||||
globalConfig = ''
|
|
||||||
admin off
|
|
||||||
'';
|
|
||||||
virtualHosts."docs.manticore-hippocampus.ts.net" = {
|
|
||||||
extraConfig = ''
|
|
||||||
tls {
|
|
||||||
get_certificate tailscale
|
|
||||||
}
|
|
||||||
reverse_proxy localhost:${toString config.services.paperless.port}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
virtualHosts."docs-ai.manticore-hippocampus.ts.net" = {
|
|
||||||
extraConfig = ''
|
|
||||||
tls {
|
|
||||||
get_certificate tailscale
|
|
||||||
}
|
|
||||||
reverse_proxy localhost:3000
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
virtualisation.oci-containers = {
|
|
||||||
backend = "docker";
|
|
||||||
containers.paperless-ai = {
|
|
||||||
image = "clusterzx/paperless-ai:latest";
|
|
||||||
autoStart = true;
|
|
||||||
volumes = [
|
|
||||||
"paperless-ai-data:/app/data"
|
|
||||||
];
|
|
||||||
environment = {
|
|
||||||
PUID = "1000";
|
|
||||||
PGID = "1000";
|
|
||||||
PAPERLESS_AI_PORT = "3000";
|
|
||||||
# Initial setup wizard will configure the rest
|
|
||||||
PAPERLESS_AI_INITIAL_SETUP = "yes";
|
|
||||||
# Paperless-ngx API URL accessible from container (using host network)
|
|
||||||
PAPERLESS_API_URL = "http://127.0.0.1:${toString config.services.paperless.port}/api";
|
|
||||||
};
|
|
||||||
extraOptions = [
|
|
||||||
"--network=host"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.redis.servers.paperless = {
|
|
||||||
enable = true;
|
|
||||||
port = 6379;
|
|
||||||
bind = "127.0.0.1";
|
|
||||||
settings = {
|
|
||||||
maxmemory = "256mb";
|
|
||||||
maxmemory-policy = "allkeys-lru";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.paperless = {
|
|
||||||
enable = true;
|
|
||||||
address = "0.0.0.0";
|
|
||||||
passwordFile = config.sops.secrets.tahani-paperless-password.path;
|
|
||||||
settings = {
|
|
||||||
PAPERLESS_DBENGINE = "sqlite";
|
|
||||||
PAPERLESS_REDIS = "redis://127.0.0.1:6379";
|
|
||||||
PAPERLESS_CONSUMER_IGNORE_PATTERN = [
|
|
||||||
".DS_STORE/*"
|
|
||||||
"desktop.ini"
|
|
||||||
];
|
|
||||||
PAPERLESS_OCR_LANGUAGE = "deu+eng";
|
|
||||||
PAPERLESS_CSRF_TRUSTED_ORIGINS = "https://docs.manticore-hippocampus.ts.net";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -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;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
input,
|
|
||||||
prev,
|
|
||||||
}: let
|
|
||||||
manifest = (prev.lib.importTOML "${input}/Cargo.toml").package;
|
|
||||||
in
|
|
||||||
prev.rustPlatform.buildRustPackage {
|
|
||||||
pname = manifest.name;
|
|
||||||
version = manifest.version;
|
|
||||||
|
|
||||||
cargoLock.lockFile = "${input}/Cargo.lock";
|
|
||||||
|
|
||||||
src = input;
|
|
||||||
|
|
||||||
nativeBuildInputs = [prev.pkg-config];
|
|
||||||
buildInputs = [prev.openssl];
|
|
||||||
OPENSSL_NO_VENDOR = 1;
|
|
||||||
|
|
||||||
doCheck = false;
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
user = "cschmatzler";
|
|
||||||
|
|
||||||
sshKeys = [
|
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHfRZQ+7ejD3YHbyMTrV0gN1Gc0DxtGgl5CVZSupo5ws"
|
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL/I+/2QT47raegzMIyhwMEPKarJP/+Ox9ewA4ZFJwk/"
|
|
||||||
];
|
|
||||||
|
|
||||||
stateVersions = {
|
|
||||||
darwin = 6;
|
|
||||||
nixos = "25.11";
|
|
||||||
homeManager = "25.11";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -2,12 +2,13 @@
|
|||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
user,
|
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
with lib; let
|
with lib; let
|
||||||
cfg = config.local.dock;
|
cfg = config.local.dock;
|
||||||
inherit (pkgs) stdenv dockutil;
|
inherit (pkgs) dockutil stdenv;
|
||||||
|
local = import ../_lib/local.nix;
|
||||||
|
userHome = "/Users/${local.user.name}";
|
||||||
in {
|
in {
|
||||||
options = {
|
options = {
|
||||||
local.dock = {
|
local.dock = {
|
||||||
@@ -38,7 +39,7 @@ in {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
default = [
|
default = [
|
||||||
{path = "/Applications/Helium.app/";}
|
{path = "/Applications/Safari.app/";}
|
||||||
{path = "/Applications/Ghostty.app/";}
|
{path = "/Applications/Ghostty.app/";}
|
||||||
{path = "/System/Applications/Calendar.app/";}
|
{path = "/System/Applications/Calendar.app/";}
|
||||||
{path = "/System/Applications/Mail.app/";}
|
{path = "/System/Applications/Mail.app/";}
|
||||||
@@ -46,7 +47,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 = "${userHome}/Downloads";
|
||||||
section = "others";
|
section = "others";
|
||||||
options = "--sort name --view grid --display stack";
|
options = "--sort name --view grid --display stack";
|
||||||
}
|
}
|
||||||
@@ -57,7 +58,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 = local.user.name;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
67
modules/_dev-tools/tuist-pr.nu
Normal file
67
modules/_dev-tools/tuist-pr.nu
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
#!/usr/bin/env nu
|
||||||
|
|
||||||
|
const repo = "tuist/tuist"
|
||||||
|
|
||||||
|
def fail [msg: string] {
|
||||||
|
error make {msg: $msg}
|
||||||
|
}
|
||||||
|
|
||||||
|
def clean [s: string] {
|
||||||
|
$s | str replace --all "\t" " " | str replace --all "\n" " "
|
||||||
|
}
|
||||||
|
|
||||||
|
def pick-pr [] {
|
||||||
|
let prs = (
|
||||||
|
gh pr list --repo $repo --state open --limit 200 --json number,title,headRefName,author
|
||||||
|
| from json
|
||||||
|
)
|
||||||
|
|
||||||
|
if ($prs | is-empty) {
|
||||||
|
fail $"No open PRs found for ($repo)"
|
||||||
|
}
|
||||||
|
|
||||||
|
let choice = (
|
||||||
|
$prs
|
||||||
|
| each {|pr|
|
||||||
|
let title = (clean $pr.title)
|
||||||
|
let branch = (clean $pr.headRefName)
|
||||||
|
let author = $pr.author.login
|
||||||
|
$"($pr.number)\t($title)\t($author)\t($branch)"
|
||||||
|
}
|
||||||
|
| str join (char newline)
|
||||||
|
| fzf --prompt "tuist pr > " --delimiter "\t" --with-nth "1,2,3,4" --preview "gh pr view --repo tuist/tuist {1}" --preview-window "right:70%"
|
||||||
|
)
|
||||||
|
|
||||||
|
if ($choice | str trim | is-empty) {
|
||||||
|
exit 130
|
||||||
|
}
|
||||||
|
|
||||||
|
$choice | split row "\t" | first | into int
|
||||||
|
}
|
||||||
|
|
||||||
|
def main [pr_number?: int] {
|
||||||
|
let number = if ($pr_number | is-empty) { pick-pr } else { $pr_number }
|
||||||
|
let pr = (
|
||||||
|
gh pr view --repo $repo $number --json number,title,url
|
||||||
|
| from json
|
||||||
|
)
|
||||||
|
|
||||||
|
let base = ([$env.HOME "Projects" "Work"] | path join)
|
||||||
|
let dest = ([$base $"tuist-pr-($pr.number)"] | path join)
|
||||||
|
|
||||||
|
if ($dest | path exists) {
|
||||||
|
fail $"Destination already exists: ($dest)"
|
||||||
|
}
|
||||||
|
|
||||||
|
^mkdir -p $base
|
||||||
|
|
||||||
|
print $"Cloning ($repo) PR #($pr.number): ($pr.title)"
|
||||||
|
jj git clone $"https://github.com/($repo).git" $dest
|
||||||
|
|
||||||
|
do {
|
||||||
|
cd $dest
|
||||||
|
gh pr checkout $pr.number
|
||||||
|
}
|
||||||
|
|
||||||
|
print $"Ready: ($dest)"
|
||||||
|
}
|
||||||
19
modules/_lib/caddy.nix
Normal file
19
modules/_lib/caddy.nix
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
let
|
||||||
|
local = import ./local.nix;
|
||||||
|
in {
|
||||||
|
inherit (local) tailscaleHost;
|
||||||
|
|
||||||
|
mkTailscaleVHost = {
|
||||||
|
name,
|
||||||
|
configText,
|
||||||
|
}: {
|
||||||
|
"${local.tailscaleHost name}" = {
|
||||||
|
extraConfig = ''
|
||||||
|
tls {
|
||||||
|
get_certificate tailscale
|
||||||
|
}
|
||||||
|
${configText}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
37
modules/_lib/hosts.nix
Normal file
37
modules/_lib/hosts.nix
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
{
|
||||||
|
den,
|
||||||
|
lib,
|
||||||
|
}: let
|
||||||
|
merge = lib.recursiveUpdate;
|
||||||
|
in {
|
||||||
|
mkUserHost = {
|
||||||
|
system,
|
||||||
|
host,
|
||||||
|
user,
|
||||||
|
userAspect ? "${host}-${user}",
|
||||||
|
includes ? [],
|
||||||
|
homeManager ? null,
|
||||||
|
}:
|
||||||
|
merge
|
||||||
|
(lib.setAttrByPath ["den" "hosts" system host "users" user "aspect"] userAspect)
|
||||||
|
(lib.setAttrByPath ["den" "aspects" userAspect] ({inherit includes;}
|
||||||
|
// lib.optionalAttrs (homeManager != null) {
|
||||||
|
inherit homeManager;
|
||||||
|
}));
|
||||||
|
|
||||||
|
mkPerHostAspect = {
|
||||||
|
host,
|
||||||
|
includes ? [],
|
||||||
|
darwin ? null,
|
||||||
|
nixos ? null,
|
||||||
|
}:
|
||||||
|
lib.setAttrByPath ["den" "aspects" host "includes"] [
|
||||||
|
(den.lib.perHost ({inherit includes;}
|
||||||
|
// lib.optionalAttrs (darwin != null) {
|
||||||
|
inherit darwin;
|
||||||
|
}
|
||||||
|
// lib.optionalAttrs (nixos != null) {
|
||||||
|
inherit nixos;
|
||||||
|
}))
|
||||||
|
];
|
||||||
|
}
|
||||||
33
modules/_lib/local.nix
Normal file
33
modules/_lib/local.nix
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
rec {
|
||||||
|
user = {
|
||||||
|
name = "cschmatzler";
|
||||||
|
fullName = "Christoph Schmatzler";
|
||||||
|
emails = {
|
||||||
|
personal = "christoph@schmatzler.com";
|
||||||
|
work = "christoph@tuist.dev";
|
||||||
|
icloud = "christoph.schmatzler@icloud.com";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
secretPath = name: "/run/secrets/${name}";
|
||||||
|
|
||||||
|
mkHome = system:
|
||||||
|
if builtins.match ".*-darwin" system != null
|
||||||
|
then "/Users/${user.name}"
|
||||||
|
else "/home/${user.name}";
|
||||||
|
|
||||||
|
mkHost = system: {
|
||||||
|
inherit system;
|
||||||
|
home = mkHome system;
|
||||||
|
};
|
||||||
|
|
||||||
|
hosts = {
|
||||||
|
chidi = mkHost "aarch64-darwin";
|
||||||
|
janet = mkHost "aarch64-darwin";
|
||||||
|
michael = mkHost "x86_64-linux";
|
||||||
|
tahani = mkHost "x86_64-linux";
|
||||||
|
};
|
||||||
|
|
||||||
|
tailscaleDomain = "manticore-hippocampus.ts.net";
|
||||||
|
tailscaleHost = name: "${name}.${tailscaleDomain}";
|
||||||
|
}
|
||||||
44
modules/_lib/secrets.nix
Normal file
44
modules/_lib/secrets.nix
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
{lib}: let
|
||||||
|
local = import ./local.nix;
|
||||||
|
in rec {
|
||||||
|
mkBinarySecret = {
|
||||||
|
name,
|
||||||
|
sopsFile,
|
||||||
|
owner ? null,
|
||||||
|
group ? null,
|
||||||
|
path ? local.secretPath name,
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
inherit path sopsFile;
|
||||||
|
format = "binary";
|
||||||
|
}
|
||||||
|
// lib.optionalAttrs (owner != null) {
|
||||||
|
inherit owner;
|
||||||
|
}
|
||||||
|
// lib.optionalAttrs (group != null) {
|
||||||
|
inherit group;
|
||||||
|
};
|
||||||
|
|
||||||
|
mkUserBinarySecret = {
|
||||||
|
name,
|
||||||
|
sopsFile,
|
||||||
|
owner ? local.user.name,
|
||||||
|
path ? local.secretPath name,
|
||||||
|
}:
|
||||||
|
mkBinarySecret {
|
||||||
|
inherit name owner path sopsFile;
|
||||||
|
};
|
||||||
|
|
||||||
|
mkServiceBinarySecret = {
|
||||||
|
name,
|
||||||
|
sopsFile,
|
||||||
|
serviceUser,
|
||||||
|
serviceGroup ? serviceUser,
|
||||||
|
path ? local.secretPath name,
|
||||||
|
}:
|
||||||
|
mkBinarySecret {
|
||||||
|
inherit name path sopsFile;
|
||||||
|
group = serviceGroup;
|
||||||
|
owner = serviceUser;
|
||||||
|
};
|
||||||
|
}
|
||||||
46
modules/_lib/theme.nix
Normal file
46
modules/_lib/theme.nix
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
{
|
||||||
|
rosePineDawn = {
|
||||||
|
slug = "rose-pine-dawn";
|
||||||
|
displayName = "Rosé Pine Dawn";
|
||||||
|
ghosttyName = "Rose Pine Dawn";
|
||||||
|
|
||||||
|
hex = {
|
||||||
|
love = "#b4637a";
|
||||||
|
gold = "#ea9d34";
|
||||||
|
rose = "#d7827e";
|
||||||
|
pine = "#286983";
|
||||||
|
foam = "#56949f";
|
||||||
|
iris = "#907aa9";
|
||||||
|
leaf = "#6d8f89";
|
||||||
|
text = "#575279";
|
||||||
|
subtle = "#797593";
|
||||||
|
muted = "#9893a5";
|
||||||
|
highlightHigh = "#cecacd";
|
||||||
|
highlightMed = "#dfdad9";
|
||||||
|
highlightLow = "#f4ede8";
|
||||||
|
overlay = "#f2e9e1";
|
||||||
|
surface = "#fffaf3";
|
||||||
|
base = "#faf4ed";
|
||||||
|
};
|
||||||
|
|
||||||
|
rgb = {
|
||||||
|
love = "180 99 122";
|
||||||
|
gold = "234 157 52";
|
||||||
|
rose = "215 130 126";
|
||||||
|
pine = "40 105 131";
|
||||||
|
foam = "86 148 159";
|
||||||
|
iris = "144 122 169";
|
||||||
|
leaf = "109 143 137";
|
||||||
|
text = "87 82 121";
|
||||||
|
subtle = "121 117 147";
|
||||||
|
muted = "152 147 165";
|
||||||
|
highlightHigh = "206 202 205";
|
||||||
|
highlightMed = "223 218 217";
|
||||||
|
highlightLow = "244 237 232";
|
||||||
|
overlay = "242 233 225";
|
||||||
|
surface = "255 250 243";
|
||||||
|
base = "250 244 237";
|
||||||
|
black = "0 0 0";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
52
modules/_neovim/autocmd.nix
Normal file
52
modules/_neovim/autocmd.nix
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
{
|
||||||
|
programs.nixvim = {
|
||||||
|
autoGroups = {
|
||||||
|
Christoph = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
autoCmd = [
|
||||||
|
{
|
||||||
|
event = ["VimEnter" "ColorScheme"];
|
||||||
|
group = "Christoph";
|
||||||
|
pattern = "*";
|
||||||
|
callback.__raw = ''
|
||||||
|
function()
|
||||||
|
local p = require("rose-pine.palette")
|
||||||
|
vim.api.nvim_set_hl(0, "NormalFloat", { bg = p.base })
|
||||||
|
vim.api.nvim_set_hl(0, "FloatTitle", { fg = p.foam, bg = p.base, bold = true })
|
||||||
|
vim.api.nvim_set_hl(0, "Pmenu", { fg = p.subtle, bg = p.base })
|
||||||
|
vim.api.nvim_set_hl(0, "PmenuExtra", { fg = p.muted, bg = p.base })
|
||||||
|
vim.api.nvim_set_hl(0, "PmenuKind", { fg = p.foam, bg = p.base })
|
||||||
|
vim.api.nvim_set_hl(0, "PmenuSbar", { bg = p.base })
|
||||||
|
vim.api.nvim_set_hl(0, "MiniPickPrompt", { bg = p.base, bold = true })
|
||||||
|
vim.api.nvim_set_hl(0, "MiniPickBorderText", { bg = p.base })
|
||||||
|
end
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
{
|
||||||
|
event = "BufWritePre";
|
||||||
|
group = "Christoph";
|
||||||
|
pattern = "*";
|
||||||
|
command = "%s/\\s\\+$//e";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
event = "BufReadPost";
|
||||||
|
group = "Christoph";
|
||||||
|
pattern = "*";
|
||||||
|
command = "normal zR";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
event = "FileReadPost";
|
||||||
|
group = "Christoph";
|
||||||
|
pattern = "*";
|
||||||
|
command = "normal zR";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
event = "FileType";
|
||||||
|
group = "Christoph";
|
||||||
|
pattern = "elixir,eelixir,heex";
|
||||||
|
command = "setlocal expandtab tabstop=2 shiftwidth=2 softtabstop=2";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,17 +1,22 @@
|
|||||||
{
|
{inputs', ...}: {
|
||||||
imports = [
|
imports = [
|
||||||
./autocmd.nix
|
./autocmd.nix
|
||||||
./mappings.nix
|
./mappings.nix
|
||||||
./options.nix
|
./options.nix
|
||||||
./plugins/blink-cmp.nix
|
./plugins/blink-cmp.nix
|
||||||
|
./plugins/code-review.nix
|
||||||
./plugins/conform.nix
|
./plugins/conform.nix
|
||||||
|
./plugins/diffview.nix
|
||||||
./plugins/grug-far.nix
|
./plugins/grug-far.nix
|
||||||
|
./plugins/hardtime.nix
|
||||||
./plugins/harpoon.nix
|
./plugins/harpoon.nix
|
||||||
./plugins/hunk.nix
|
./plugins/hunk.nix
|
||||||
./plugins/jj-diffconflicts.nix
|
./plugins/jj-diffconflicts.nix
|
||||||
|
./plugins/jj-nvim.nix
|
||||||
./plugins/lsp.nix
|
./plugins/lsp.nix
|
||||||
./plugins/mini.nix
|
./plugins/mini.nix
|
||||||
./plugins/oil.nix
|
./plugins/oil.nix
|
||||||
|
./plugins/render-markdown.nix
|
||||||
./plugins/toggleterm.nix
|
./plugins/toggleterm.nix
|
||||||
./plugins/treesitter.nix
|
./plugins/treesitter.nix
|
||||||
./plugins/zk.nix
|
./plugins/zk.nix
|
||||||
@@ -20,16 +25,18 @@
|
|||||||
programs.nixvim = {
|
programs.nixvim = {
|
||||||
enable = true;
|
enable = true;
|
||||||
defaultEditor = true;
|
defaultEditor = true;
|
||||||
|
package = inputs'.neovim-nightly-overlay.packages.default;
|
||||||
luaLoader.enable = true;
|
luaLoader.enable = true;
|
||||||
colorschemes.catppuccin = {
|
colorschemes.rose-pine = {
|
||||||
enable = true;
|
enable = true;
|
||||||
settings = {
|
settings = {
|
||||||
flavour = "latte";
|
variant = "dawn";
|
||||||
|
extend_background_behind_borders = false;
|
||||||
|
styles = {
|
||||||
|
italic = false;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
extraConfigLua = ''
|
|
||||||
vim.ui.select = MiniPick.ui_select
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
home.shellAliases = {
|
home.shellAliases = {
|
||||||
@@ -117,16 +117,58 @@
|
|||||||
action = ":Pick visit_paths<CR>";
|
action = ":Pick visit_paths<CR>";
|
||||||
options.desc = "Visit paths (cwd)";
|
options.desc = "Visit paths (cwd)";
|
||||||
}
|
}
|
||||||
# g - git
|
# v - vcs
|
||||||
{
|
{
|
||||||
mode = "n";
|
mode = "n";
|
||||||
key = "<leader>gc";
|
key = "<leader>va";
|
||||||
|
action = ":J annotate<CR>";
|
||||||
|
options.desc = "Annotate (blame)";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<leader>vc";
|
||||||
action = ":JJDiffConflicts<CR>";
|
action = ":JJDiffConflicts<CR>";
|
||||||
options.desc = "Resolve conflicts";
|
options.desc = "Resolve conflicts";
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
mode = "n";
|
mode = "n";
|
||||||
key = "<leader>gg";
|
key = "<leader>vd";
|
||||||
|
action.__raw = ''
|
||||||
|
function()
|
||||||
|
require('jj.cmd').diff()
|
||||||
|
end
|
||||||
|
'';
|
||||||
|
options.desc = "Diff (current file)";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<leader>vD";
|
||||||
|
action.__raw = ''
|
||||||
|
function()
|
||||||
|
require('jj.diff').show_revision({})
|
||||||
|
end
|
||||||
|
'';
|
||||||
|
options.desc = "Diff (all changes)";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<leader>ve";
|
||||||
|
action.__raw = ''
|
||||||
|
function()
|
||||||
|
require('jj.cmd').describe()
|
||||||
|
end
|
||||||
|
'';
|
||||||
|
options.desc = "Describe (edit message)";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<leader>vf";
|
||||||
|
action = ":J fetch<CR>";
|
||||||
|
options.desc = "Fetch";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<leader>vv";
|
||||||
action.__raw = ''
|
action.__raw = ''
|
||||||
function()
|
function()
|
||||||
require('toggleterm.terminal').Terminal:new({ cmd = 'jjui', direction = 'float' }):toggle()
|
require('toggleterm.terminal').Terminal:new({ cmd = 'jjui', direction = 'float' }):toggle()
|
||||||
@@ -134,6 +176,123 @@
|
|||||||
'';
|
'';
|
||||||
options.desc = "jjui";
|
options.desc = "jjui";
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<leader>vh";
|
||||||
|
action.__raw = ''
|
||||||
|
function()
|
||||||
|
require('jj.diff').show_revision({ rev = '@-' })
|
||||||
|
end
|
||||||
|
'';
|
||||||
|
options.desc = "Diff parent revision";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<leader>vl";
|
||||||
|
action.__raw = ''
|
||||||
|
function()
|
||||||
|
require('jj.cmd').log()
|
||||||
|
end
|
||||||
|
'';
|
||||||
|
options.desc = "Log";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<leader>vn";
|
||||||
|
action.__raw = ''
|
||||||
|
function()
|
||||||
|
require('jj.cmd').new()
|
||||||
|
end
|
||||||
|
'';
|
||||||
|
options.desc = "New change";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<leader>vp";
|
||||||
|
action = ":J git push<CR>";
|
||||||
|
options.desc = "Push";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<leader>vq";
|
||||||
|
action = ":DiffviewClose<CR>";
|
||||||
|
options.desc = "Close diffview";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<leader>vR";
|
||||||
|
action.__raw = ''
|
||||||
|
function()
|
||||||
|
require('jj.diff').diff_revisions({ left = 'trunk()', right = '@' })
|
||||||
|
end
|
||||||
|
'';
|
||||||
|
options.desc = "Review bookmark (trunk..@)";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<leader>vs";
|
||||||
|
action.__raw = ''
|
||||||
|
function()
|
||||||
|
require('jj.cmd').status()
|
||||||
|
end
|
||||||
|
'';
|
||||||
|
options.desc = "Status";
|
||||||
|
}
|
||||||
|
# r - review
|
||||||
|
{
|
||||||
|
mode = ["n" "v"];
|
||||||
|
key = "<leader>rc";
|
||||||
|
action = ":CodeReviewComment<CR>";
|
||||||
|
options.desc = "Add comment";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<leader>rd";
|
||||||
|
action = ":CodeReviewDeleteComment<CR>";
|
||||||
|
options.desc = "Delete comment";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<leader>rl";
|
||||||
|
action = ":CodeReviewList<CR>";
|
||||||
|
options.desc = "List comments";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<leader>ro";
|
||||||
|
action = ":CodeReviewResolve<CR>";
|
||||||
|
options.desc = "Resolve thread";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<leader>rp";
|
||||||
|
action = ":CodeReviewPreview<CR>";
|
||||||
|
options.desc = "Preview review";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<leader>rr";
|
||||||
|
action = ":CodeReviewReply<CR>";
|
||||||
|
options.desc = "Reply to comment";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<leader>rs";
|
||||||
|
action = ":CodeReviewShowComment<CR>";
|
||||||
|
options.desc = "Show comment";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<leader>rx";
|
||||||
|
action = ":CodeReviewClear<CR>";
|
||||||
|
options.desc = "Clear all comments";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<leader>ry";
|
||||||
|
action = ":CodeReviewCopy<CR>";
|
||||||
|
options.desc = "Copy review to clipboard";
|
||||||
|
}
|
||||||
# l - lsp/formatter
|
# l - lsp/formatter
|
||||||
{
|
{
|
||||||
mode = "n";
|
mode = "n";
|
||||||
@@ -162,13 +321,13 @@
|
|||||||
{
|
{
|
||||||
mode = "n";
|
mode = "n";
|
||||||
key = "<leader>lj";
|
key = "<leader>lj";
|
||||||
action = ":lua vim.diagnostic.goto_next()<CR>";
|
action = ":lua vim.diagnostic.jump({ count = 1 })<CR>";
|
||||||
options.desc = "Next diagnostic";
|
options.desc = "Next diagnostic";
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
mode = "n";
|
mode = "n";
|
||||||
key = "<leader>lk";
|
key = "<leader>lk";
|
||||||
action = ":lua vim.diagnostic.goto_prev()<CR>";
|
action = ":lua vim.diagnostic.jump({ count = -1 })<CR>";
|
||||||
options.desc = "Prev diagnostic";
|
options.desc = "Prev diagnostic";
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
@@ -189,6 +348,111 @@
|
|||||||
action = ":lua vim.lsp.buf.definition()<CR>";
|
action = ":lua vim.lsp.buf.definition()<CR>";
|
||||||
options.desc = "Source definition";
|
options.desc = "Source definition";
|
||||||
}
|
}
|
||||||
|
# t - tab
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<leader>tc";
|
||||||
|
action = ":tabclose<CR>";
|
||||||
|
options.desc = "Close tab";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<leader>tn";
|
||||||
|
action = ":tabnew<CR>";
|
||||||
|
options.desc = "New tab";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<leader>to";
|
||||||
|
action = ":tabonly<CR>";
|
||||||
|
options.desc = "Close other tabs";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<leader>th";
|
||||||
|
action = ":tabprevious<CR>";
|
||||||
|
options.desc = "Previous tab";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<leader>tl";
|
||||||
|
action = ":tabnext<CR>";
|
||||||
|
options.desc = "Next tab";
|
||||||
|
}
|
||||||
|
# w - window
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<leader>wh";
|
||||||
|
action = "<C-w>h";
|
||||||
|
options.desc = "Go left";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<leader>wj";
|
||||||
|
action = "<C-w>j";
|
||||||
|
options.desc = "Go down";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<leader>wk";
|
||||||
|
action = "<C-w>k";
|
||||||
|
options.desc = "Go up";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<leader>wl";
|
||||||
|
action = "<C-w>l";
|
||||||
|
options.desc = "Go right";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<leader>ws";
|
||||||
|
action = ":split<CR>";
|
||||||
|
options.desc = "Split horizontal";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<leader>wv";
|
||||||
|
action = ":vsplit<CR>";
|
||||||
|
options.desc = "Split vertical";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<leader>wc";
|
||||||
|
action = ":close<CR>";
|
||||||
|
options.desc = "Close window";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<leader>wq";
|
||||||
|
action = ":q<CR>";
|
||||||
|
options.desc = "Quit window";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<leader>wo";
|
||||||
|
action = ":only<CR>";
|
||||||
|
options.desc = "Close other windows";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<leader>w=";
|
||||||
|
action = "<C-w>=";
|
||||||
|
options.desc = "Equalize windows";
|
||||||
|
}
|
||||||
|
# scrolling
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<C-d>";
|
||||||
|
action = "<C-d>zz";
|
||||||
|
options.desc = "Scroll down and center";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
key = "<C-u>";
|
||||||
|
action = "<C-u>zz";
|
||||||
|
options.desc = "Scroll up and center";
|
||||||
|
}
|
||||||
# other
|
# other
|
||||||
{
|
{
|
||||||
mode = "n";
|
mode = "n";
|
||||||
@@ -4,14 +4,17 @@
|
|||||||
clipboard = "osc52";
|
clipboard = "osc52";
|
||||||
};
|
};
|
||||||
opts = {
|
opts = {
|
||||||
|
winborder = "single";
|
||||||
expandtab = false;
|
expandtab = false;
|
||||||
tabstop = 2;
|
tabstop = 2;
|
||||||
ignorecase = true;
|
ignorecase = true;
|
||||||
list = false;
|
list = false;
|
||||||
mouse = "";
|
mouse = "";
|
||||||
relativenumber = true;
|
relativenumber = true;
|
||||||
|
scrolloff = 8;
|
||||||
shiftwidth = 2;
|
shiftwidth = 2;
|
||||||
smartcase = true;
|
smartcase = true;
|
||||||
|
undofile = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
39
modules/_neovim/plugins/code-review.nix
Normal file
39
modules/_neovim/plugins/code-review.nix
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
nvim-plugin-sources,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
code-review-nvim =
|
||||||
|
pkgs.vimUtils.buildVimPlugin {
|
||||||
|
pname = "code-review-nvim";
|
||||||
|
version = "unstable";
|
||||||
|
src = nvim-plugin-sources.code-review-nvim;
|
||||||
|
doCheck = false;
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
programs.nixvim = {
|
||||||
|
extraPlugins = [
|
||||||
|
code-review-nvim
|
||||||
|
];
|
||||||
|
extraConfigLua = ''
|
||||||
|
require('code-review').setup({
|
||||||
|
keymaps = false,
|
||||||
|
comment = {
|
||||||
|
storage = {
|
||||||
|
backend = "file",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ui = {
|
||||||
|
input_window = {
|
||||||
|
border = "single",
|
||||||
|
},
|
||||||
|
preview = {
|
||||||
|
float = {
|
||||||
|
border = "single",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -5,9 +5,8 @@
|
|||||||
format_on_save = {};
|
format_on_save = {};
|
||||||
formatters_by_ft = {
|
formatters_by_ft = {
|
||||||
nix = ["alejandra"];
|
nix = ["alejandra"];
|
||||||
javascript = ["prettier"];
|
javascript = ["oxfmt"];
|
||||||
typescript = ["prettier"];
|
typescript = ["oxfmt"];
|
||||||
vue = ["prettier"];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
26
modules/_neovim/plugins/diffview.nix
Normal file
26
modules/_neovim/plugins/diffview.nix
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{pkgs, ...}: {
|
||||||
|
programs.nixvim = {
|
||||||
|
extraPlugins = with pkgs.vimPlugins; [
|
||||||
|
diffview-nvim
|
||||||
|
];
|
||||||
|
extraConfigLua = ''
|
||||||
|
require('diffview').setup({
|
||||||
|
enhanced_diff_hl = true,
|
||||||
|
view = {
|
||||||
|
default = { layout = "diff2_horizontal" },
|
||||||
|
merge_tool = { layout = "diff3_mixed", disable_diagnostics = true },
|
||||||
|
file_history = { layout = "diff2_horizontal" },
|
||||||
|
},
|
||||||
|
default_args = {
|
||||||
|
DiffviewOpen = { "--imply-local" },
|
||||||
|
},
|
||||||
|
hooks = {
|
||||||
|
diff_buf_read = function(bufnr)
|
||||||
|
vim.opt_local.wrap = false
|
||||||
|
vim.opt_local.list = false
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
7
modules/_neovim/plugins/hardtime.nix
Normal file
7
modules/_neovim/plugins/hardtime.nix
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
programs.nixvim.plugins = {
|
||||||
|
hardtime = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
12
modules/_neovim/plugins/jj-diffconflicts.nix
Normal file
12
modules/_neovim/plugins/jj-diffconflicts.nix
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
nvim-plugin-sources,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
programs.nixvim.extraPlugins = [
|
||||||
|
(pkgs.vimUtils.buildVimPlugin {
|
||||||
|
name = "jj-diffconflicts";
|
||||||
|
src = nvim-plugin-sources.jj-diffconflicts;
|
||||||
|
})
|
||||||
|
];
|
||||||
|
}
|
||||||
39
modules/_neovim/plugins/jj-nvim.nix
Normal file
39
modules/_neovim/plugins/jj-nvim.nix
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
nvim-plugin-sources,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
jj-nvim =
|
||||||
|
pkgs.vimUtils.buildVimPlugin {
|
||||||
|
pname = "jj-nvim";
|
||||||
|
version = "unstable";
|
||||||
|
src = nvim-plugin-sources.jj-nvim;
|
||||||
|
doCheck = false;
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
programs.nixvim = {
|
||||||
|
extraPlugins = [
|
||||||
|
jj-nvim
|
||||||
|
];
|
||||||
|
extraConfigLua = ''
|
||||||
|
require('jj').setup({
|
||||||
|
diff = {
|
||||||
|
backend = "diffview",
|
||||||
|
},
|
||||||
|
cmd = {
|
||||||
|
describe = {
|
||||||
|
editor = { type = "buffer" },
|
||||||
|
},
|
||||||
|
log = {
|
||||||
|
close_on_edit = false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ui = {
|
||||||
|
log = {
|
||||||
|
keymaps = true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
175
modules/_neovim/plugins/mini.nix
Normal file
175
modules/_neovim/plugins/mini.nix
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
{
|
||||||
|
programs.nixvim = {
|
||||||
|
plugins.mini = {
|
||||||
|
enable = true;
|
||||||
|
modules = {
|
||||||
|
ai = {
|
||||||
|
custom_textobjects = {
|
||||||
|
B.__raw = "require('mini.extra').gen_ai_spec.buffer()";
|
||||||
|
F.__raw = "require('mini.ai').gen_spec.treesitter({ a = '@function.outer', i = '@function.inner' })";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
align = {};
|
||||||
|
basics = {
|
||||||
|
options = {
|
||||||
|
basic = true;
|
||||||
|
extra_ui = true;
|
||||||
|
};
|
||||||
|
mappings = {
|
||||||
|
basic = false;
|
||||||
|
};
|
||||||
|
autocommands = {
|
||||||
|
basic = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
bracketed = {};
|
||||||
|
clue = {
|
||||||
|
clues.__raw = ''
|
||||||
|
{
|
||||||
|
{ mode = 'n', keys = '<Leader>e', desc = '+Explore/+Edit' },
|
||||||
|
{ mode = 'n', keys = '<Leader>f', desc = '+Find' },
|
||||||
|
{ mode = 'n', keys = '<Leader>v', desc = '+VCS' },
|
||||||
|
{ mode = 'n', keys = '<Leader>l', desc = '+LSP' },
|
||||||
|
{ mode = 'x', keys = '<Leader>l', desc = '+LSP' },
|
||||||
|
{ mode = 'n', keys = '<Leader>r', desc = '+Review' },
|
||||||
|
{ mode = 'v', keys = '<Leader>r', desc = '+Review' },
|
||||||
|
{ mode = 'n', keys = '<Leader>t', desc = '+Tab' },
|
||||||
|
{ mode = 'n', keys = '<Leader>w', desc = '+Window' },
|
||||||
|
require("mini.clue").gen_clues.builtin_completion(),
|
||||||
|
require("mini.clue").gen_clues.g(),
|
||||||
|
require("mini.clue").gen_clues.marks(),
|
||||||
|
require("mini.clue").gen_clues.registers(),
|
||||||
|
require("mini.clue").gen_clues.windows({ submode_resize = true }),
|
||||||
|
require("mini.clue").gen_clues.z(),
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
triggers = [
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
keys = "<Leader>";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "x";
|
||||||
|
keys = "<Leader>";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
keys = "[";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
keys = "]";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "x";
|
||||||
|
keys = "[";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "x";
|
||||||
|
keys = "]";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "i";
|
||||||
|
keys = "<C-x>";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
keys = "g";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "x";
|
||||||
|
keys = "g";
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
keys = "\"";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "x";
|
||||||
|
keys = "\"";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "i";
|
||||||
|
keys = "<C-r>";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "c";
|
||||||
|
keys = "<C-r>";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
keys = "<C-w>";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
keys = "z";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "x";
|
||||||
|
keys = "z";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
keys = "'";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "n";
|
||||||
|
keys = "`";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "x";
|
||||||
|
keys = "'";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mode = "x";
|
||||||
|
keys = "`";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
cmdline = {};
|
||||||
|
comment = {};
|
||||||
|
diff = {};
|
||||||
|
extra = {};
|
||||||
|
git = {};
|
||||||
|
hipatterns = {
|
||||||
|
highlighters = {
|
||||||
|
fixme.__raw = "{ pattern = '%f[%w]()FIXME()%f[%W]', group = 'MiniHipatternsFixme' }";
|
||||||
|
hack.__raw = "{ pattern = '%f[%w]()HACK()%f[%W]', group = 'MiniHipatternsHack' }";
|
||||||
|
todo.__raw = "{ pattern = '%f[%w]()TODO()%f[%W]', group = 'MiniHipatternsTodo' }";
|
||||||
|
note.__raw = "{ pattern = '%f[%w]()NOTE()%f[%W]', group = 'MiniHipatternsNote' }";
|
||||||
|
hex_color.__raw = "require('mini.hipatterns').gen_highlighter.hex_color()";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
icons = {};
|
||||||
|
indentscope = {
|
||||||
|
settings = {
|
||||||
|
symbol = "|";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
jump = {};
|
||||||
|
jump2d = {
|
||||||
|
settings = {
|
||||||
|
spotter.__raw = "require('mini.jump2d').gen_spotter.pattern('[^%s%p]+')";
|
||||||
|
labels = "asdfghjkl";
|
||||||
|
view = {
|
||||||
|
dim = true;
|
||||||
|
n_steps_ahead = 2;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
move = {};
|
||||||
|
notify = {};
|
||||||
|
pairs = {};
|
||||||
|
pick = {};
|
||||||
|
splitjoin = {};
|
||||||
|
starter = {};
|
||||||
|
statusline = {};
|
||||||
|
surround = {};
|
||||||
|
trailspace = {};
|
||||||
|
visits = {};
|
||||||
|
};
|
||||||
|
mockDevIcons = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
9
modules/_neovim/plugins/render-markdown.nix
Normal file
9
modules/_neovim/plugins/render-markdown.nix
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
programs.nixvim.plugins.render-markdown = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
anti_conceal = {enabled = false;};
|
||||||
|
file_types = ["markdown"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
22
modules/_neovim/plugins/treesitter.nix
Normal file
22
modules/_neovim/plugins/treesitter.nix
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{pkgs, ...}: {
|
||||||
|
programs.nixvim = {
|
||||||
|
plugins.treesitter = {
|
||||||
|
enable = true;
|
||||||
|
nixGrammars = true;
|
||||||
|
grammarPackages = with pkgs.vimPlugins.nvim-treesitter-parsers; [
|
||||||
|
css
|
||||||
|
elixir
|
||||||
|
javascript
|
||||||
|
lua
|
||||||
|
markdown
|
||||||
|
markdown_inline
|
||||||
|
nix
|
||||||
|
typescript
|
||||||
|
];
|
||||||
|
settings = {
|
||||||
|
highlight.enable = true;
|
||||||
|
indent.enable = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
28
modules/_opencode/AGENTS.md
Normal file
28
modules/_opencode/AGENTS.md
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# AGENTS.md
|
||||||
|
|
||||||
|
## Version Control
|
||||||
|
|
||||||
|
- Use `jj` for version control, not `git`.
|
||||||
|
- `jj tug` is an alias for `jj bookmark move --from closest_bookmark(@-) --to @-`.
|
||||||
|
- Never attempt historically destructive Git commands.
|
||||||
|
- Make small, frequent commits.
|
||||||
|
- "Commit" means `jj commit`, not `jj desc`; `desc` stays on the same working copy.
|
||||||
|
|
||||||
|
## Scripting
|
||||||
|
|
||||||
|
- Use Nushell (`nu`) for scripting.
|
||||||
|
- Do not use Python, Perl, Lua, awk, or any other scripting language. You are programatically blocked from doing so.
|
||||||
|
|
||||||
|
## Workflow
|
||||||
|
|
||||||
|
- Always complete the requested work.
|
||||||
|
- If there is any ambiguity about what to do next, do NOT make a decision yourself. Stop your work and ask.
|
||||||
|
- Do not end with “If you want me to…” or “I can…”; take the next necessary step and finish the job without waiting for additional confirmation.
|
||||||
|
- Do not future-proof things. Stick to the original plan.
|
||||||
|
- Do not add fallbacks or backward compatibility unless explicitly required by the user. By default, replace the previous implementation with the new one entirely.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
- Do not ignore failing tests or checks, even if they appear unrelated to your changes.
|
||||||
|
- After completing and validating your work, the final step is to run the project's full validation and test commands and ensure they all pass.
|
||||||
|
|
||||||
@@ -10,6 +10,7 @@ Hard requirements:
|
|||||||
- Do not use pattern-matching commands or searches (`grep`, `rg`, `awk`, `sed`, `himalaya envelope list` query filters, etc.).
|
- Do not use pattern-matching commands or searches (`grep`, `rg`, `awk`, `sed`, `himalaya envelope list` query filters, etc.).
|
||||||
- Always inspect current folders first, then triage.
|
- Always inspect current folders first, then triage.
|
||||||
- Treat this as a single deterministic run over a snapshot of message IDs discovered during this run.
|
- Treat this as a single deterministic run over a snapshot of message IDs discovered during this run.
|
||||||
|
- Ingest valuable document attachments into Paperless (see Document Ingestion section below).
|
||||||
|
|
||||||
Workflow:
|
Workflow:
|
||||||
1. Run `himalaya folder list` first and use those folders as the primary taxonomy.
|
1. Run `himalaya folder list` first and use those folders as the primary taxonomy.
|
||||||
@@ -35,8 +36,9 @@ Workflow:
|
|||||||
5. For each single envelope ID, do all checks before any move/delete:
|
5. For each single envelope ID, do all checks before any move/delete:
|
||||||
- Check envelope flags from the JSON listing (seen/answered/flagged) before reading.
|
- Check envelope flags from the JSON listing (seen/answered/flagged) before reading.
|
||||||
- Read the message: `himalaya message read -f "<source>" <id>`.
|
- Read the message: `himalaya message read -f "<source>" <id>`.
|
||||||
- If needed for classification, inspect attachments: `himalaya attachment download -f "<source>" <id> --dir /tmp/himalaya-triage`.
|
- If needed for classification or ingestion, download attachments: `himalaya attachment download -f "<source>" <id> --dir /tmp/himalaya-triage`.
|
||||||
- If attachments are downloaded, inspect them and `rm` the downloaded files from `/tmp/himalaya-triage` after use.
|
- If the message qualifies for document ingestion (see Document Ingestion below), copy eligible attachments to the Paperless consume directory before cleanup.
|
||||||
|
- Always `rm` downloaded files from `/tmp/himalaya-triage` after processing (whether ingested or not).
|
||||||
- Move: `himalaya message move -f "<source>" "<destination>" <id>`.
|
- Move: `himalaya message move -f "<source>" "<destination>" <id>`.
|
||||||
- Delete: `himalaya message delete -f "<source>" <id>`.
|
- Delete: `himalaya message delete -f "<source>" <id>`.
|
||||||
6. Classification precedence (higher rule wins on conflict):
|
6. Classification precedence (higher rule wins on conflict):
|
||||||
@@ -58,6 +60,30 @@ Workflow:
|
|||||||
- Naming constraints: concise topic name, avoid duplicates, and avoid broad catch-all names.
|
- Naming constraints: concise topic name, avoid duplicates, and avoid broad catch-all names.
|
||||||
- Command: `himalaya folder add "<new-folder>"`.
|
- Command: `himalaya folder add "<new-folder>"`.
|
||||||
|
|
||||||
|
Document Ingestion (Paperless):
|
||||||
|
- **Purpose**: Automatically archive valuable document attachments into Paperless via its consumption directory.
|
||||||
|
- **Ingestion path**: `/var/lib/paperless/consume/inbox-triage/`
|
||||||
|
- **When to ingest**: Only for messages whose attachments have long-term archival value. Eligible categories:
|
||||||
|
- Invoices, receipts, and billing statements (messages going to `Orders and Invoices` or `Payments`)
|
||||||
|
- Contracts, agreements, and legal documents
|
||||||
|
- Tax documents, account statements, and financial summaries
|
||||||
|
- Insurance documents and policy papers
|
||||||
|
- Official correspondence with document attachments (government, institutions)
|
||||||
|
- **When NOT to ingest**:
|
||||||
|
- Marketing emails, newsletters, promotional material
|
||||||
|
- Shipping/tracking notifications without invoice attachments
|
||||||
|
- OTP codes, login alerts, password resets, ephemeral notifications
|
||||||
|
- Subscription renewal reminders without actual invoices
|
||||||
|
- Duplicate documents already seen in this run
|
||||||
|
- Inline images, email signatures, logos, and non-document attachments
|
||||||
|
- **Eligible file types**: PDF, PNG, JPG/JPEG, TIFF, WEBP (documents and scans only). Skip archive files (ZIP, etc.), calendar invites (ICS), and other non-document formats.
|
||||||
|
- **Procedure**:
|
||||||
|
1. After downloading attachments to `/tmp/himalaya-triage`, check if any are eligible documents.
|
||||||
|
2. Copy eligible files: `cp /tmp/himalaya-triage/<filename> /var/lib/paperless/consume/inbox-triage/`
|
||||||
|
3. If multiple messages could produce filename collisions, prefix the filename with the message ID: `<id>-<filename>`.
|
||||||
|
4. Log each ingested file in the action log at the end of the run.
|
||||||
|
- **Conservative rule**: When in doubt whether an attachment is worth archiving, skip it. Paperless storage is cheap, but noise degrades searchability. Prefer false negatives over false positives for marketing material, but prefer false positives over false negatives for anything that looks like a financial or legal document.
|
||||||
|
|
||||||
Execution rules:
|
Execution rules:
|
||||||
- Never perform bulk operations. One message ID per `read`, `move`, `delete`, and attachment command.
|
- Never perform bulk operations. One message ID per `read`, `move`, `delete`, and attachment command.
|
||||||
- Always use page size 20 for envelope listing (`-s 20`).
|
- Always use page size 20 for envelope listing (`-s 20`).
|
||||||
@@ -74,6 +100,7 @@ Execution rules:
|
|||||||
- counts by action (untouched/moved-to-folder/deleted),
|
- counts by action (untouched/moved-to-folder/deleted),
|
||||||
- per-destination-folder counts,
|
- per-destination-folder counts,
|
||||||
- created folders,
|
- created folders,
|
||||||
|
- documents ingested to Paperless (count and filenames),
|
||||||
- short rationale for non-obvious classifications.
|
- short rationale for non-obvious classifications.
|
||||||
|
|
||||||
<user-request>
|
<user-request>
|
||||||
150
modules/_opencode/command/supermemory-init.md
Normal file
150
modules/_opencode/command/supermemory-init.md
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
---
|
||||||
|
description: Initialize Supermemory with comprehensive codebase knowledge
|
||||||
|
---
|
||||||
|
|
||||||
|
# Initializing Supermemory
|
||||||
|
|
||||||
|
You are initializing persistent memory for this codebase. This is not just data collection - you're building context that will make you significantly more effective across all future sessions.
|
||||||
|
|
||||||
|
## Understanding Context
|
||||||
|
|
||||||
|
You are a **stateful** coding agent. Users expect to work with you over extended periods - potentially the entire lifecycle of a project. Your memory is how you get better over time and maintain continuity.
|
||||||
|
|
||||||
|
## What to Remember
|
||||||
|
|
||||||
|
### 1. Procedures (Rules & Workflows)
|
||||||
|
Explicit rules that should always be followed:
|
||||||
|
- "Never commit directly to main - always use feature branches"
|
||||||
|
- "Always run lint before tests"
|
||||||
|
- "Use conventional commits format"
|
||||||
|
|
||||||
|
### 2. Preferences (Style & Conventions)
|
||||||
|
Project and user coding style:
|
||||||
|
- "Prefer functional components over class components"
|
||||||
|
- "Use early returns instead of nested conditionals"
|
||||||
|
- "Always add JSDoc to exported functions"
|
||||||
|
|
||||||
|
### 3. Architecture & Context
|
||||||
|
How the codebase works and why:
|
||||||
|
- "Auth system was refactored in v2.0 - old patterns deprecated"
|
||||||
|
- "The monorepo used to have 3 modules before consolidation"
|
||||||
|
- "This pagination bug was fixed before - similar to PR #234"
|
||||||
|
|
||||||
|
## Memory Scopes
|
||||||
|
|
||||||
|
**Project-scoped** (\`scope: "project"\`):
|
||||||
|
- Build/test/lint commands
|
||||||
|
- Architecture and key directories
|
||||||
|
- Team conventions specific to this codebase
|
||||||
|
- Technology stack and framework choices
|
||||||
|
- Known issues and their solutions
|
||||||
|
|
||||||
|
**User-scoped** (\`scope: "user"\`):
|
||||||
|
- Personal coding preferences across all projects
|
||||||
|
- Communication style preferences
|
||||||
|
- General workflow habits
|
||||||
|
|
||||||
|
## Research Approach
|
||||||
|
|
||||||
|
This is a **deep research** initialization. Take your time and be thorough (~50+ tool calls). The goal is to genuinely understand the project, not just collect surface-level facts.
|
||||||
|
|
||||||
|
**What to uncover:**
|
||||||
|
- Tech stack and dependencies (explicit and implicit)
|
||||||
|
- Project structure and architecture
|
||||||
|
- Build/test/deploy commands and workflows
|
||||||
|
- Contributors & team dynamics (who works on what?)
|
||||||
|
- Commit conventions and branching strategy
|
||||||
|
- Code evolution (major refactors, architecture changes)
|
||||||
|
- Pain points (areas with lots of bug fixes)
|
||||||
|
- Implicit conventions not documented anywhere
|
||||||
|
|
||||||
|
## Research Techniques
|
||||||
|
|
||||||
|
### File-based
|
||||||
|
- README.md, CONTRIBUTING.md, AGENTS.md, CLAUDE.md
|
||||||
|
- Package manifests (package.json, Cargo.toml, pyproject.toml, go.mod)
|
||||||
|
- Config files (.eslintrc, tsconfig.json, .prettierrc)
|
||||||
|
- CI/CD configs (.github/workflows/)
|
||||||
|
|
||||||
|
### Git-based
|
||||||
|
- \`git log --oneline -20\` - Recent history
|
||||||
|
- \`git branch -a\` - Branching strategy
|
||||||
|
- \`git log --format="%s" -50\` - Commit conventions
|
||||||
|
- \`git shortlog -sn --all | head -10\` - Main contributors
|
||||||
|
|
||||||
|
### Explore Agent
|
||||||
|
Fire parallel explore queries for broad understanding:
|
||||||
|
\`\`\`
|
||||||
|
Task(explore, "What is the tech stack and key dependencies?")
|
||||||
|
Task(explore, "What is the project structure? Key directories?")
|
||||||
|
Task(explore, "How do you build, test, and run this project?")
|
||||||
|
Task(explore, "What are the main architectural patterns?")
|
||||||
|
Task(explore, "What conventions or patterns are used?")
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
## How to Do Thorough Research
|
||||||
|
|
||||||
|
**Don't just collect data - analyze and cross-reference.**
|
||||||
|
|
||||||
|
Bad (shallow):
|
||||||
|
- Run commands, copy output
|
||||||
|
- List facts without understanding
|
||||||
|
|
||||||
|
Good (thorough):
|
||||||
|
- Cross-reference findings (if inconsistent, dig deeper)
|
||||||
|
- Resolve ambiguities (don't leave questions unanswered)
|
||||||
|
- Read actual file content, not just names
|
||||||
|
- Look for patterns (what do commits tell you about workflow?)
|
||||||
|
- Think like a new team member - what would you want to know?
|
||||||
|
|
||||||
|
## Saving Memories
|
||||||
|
|
||||||
|
Use the \`supermemory\` tool for each distinct insight:
|
||||||
|
|
||||||
|
\`\`\`
|
||||||
|
supermemory(mode: "add", content: "...", type: "...", scope: "project")
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
**Types:**
|
||||||
|
- \`project-config\` - tech stack, commands, tooling
|
||||||
|
- \`architecture\` - codebase structure, key components, data flow
|
||||||
|
- \`learned-pattern\` - conventions specific to this codebase
|
||||||
|
- \`error-solution\` - known issues and their fixes
|
||||||
|
- \`preference\` - coding style preferences (use with user scope)
|
||||||
|
|
||||||
|
**Guidelines:**
|
||||||
|
- Save each distinct insight as a separate memory
|
||||||
|
- Be concise but include enough context to be useful
|
||||||
|
- Include the "why" not just the "what" when relevant
|
||||||
|
- Update memories incrementally as you research (don't wait until the end)
|
||||||
|
|
||||||
|
**Good memories:**
|
||||||
|
- "Uses Bun runtime and package manager. Commands: bun install, bun run dev, bun test"
|
||||||
|
- "API routes in src/routes/, handlers in src/handlers/. Hono framework."
|
||||||
|
- "Auth uses Redis sessions, not JWT. Implementation in src/lib/auth.ts"
|
||||||
|
- "Never use \`any\` type - strict TypeScript. Use \`unknown\` and narrow."
|
||||||
|
- "Database migrations must be backward compatible - we do rolling deploys"
|
||||||
|
|
||||||
|
## Upfront Questions
|
||||||
|
|
||||||
|
Before diving in, ask:
|
||||||
|
1. "Any specific rules I should always follow?"
|
||||||
|
2. "Preferences for how I communicate? (terse/detailed)"
|
||||||
|
|
||||||
|
## Reflection Phase
|
||||||
|
|
||||||
|
Before finishing, reflect:
|
||||||
|
1. **Completeness**: Did you cover commands, architecture, conventions, gotchas?
|
||||||
|
2. **Quality**: Are memories concise and searchable?
|
||||||
|
3. **Scope**: Did you correctly separate project vs user knowledge?
|
||||||
|
|
||||||
|
Then ask: "I've initialized memory with X insights. Want me to continue refining, or is this good?"
|
||||||
|
|
||||||
|
## Your Task
|
||||||
|
|
||||||
|
1. Ask upfront questions (research depth, rules, preferences)
|
||||||
|
2. Check existing memories: \`supermemory(mode: "list", scope: "project")\`
|
||||||
|
3. Research based on chosen depth
|
||||||
|
4. Save memories incrementally as you discover insights
|
||||||
|
5. Reflect and verify completeness
|
||||||
|
6. Summarize what was learned and ask if user wants refinement
|
||||||
49
modules/_opencode/plugin/block-git.ts
Normal file
49
modules/_opencode/plugin/block-git.ts
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import type { Plugin } from "@opencode-ai/plugin";
|
||||||
|
|
||||||
|
const COMMAND_PREFIXES = new Set([
|
||||||
|
"env",
|
||||||
|
"command",
|
||||||
|
"builtin",
|
||||||
|
"time",
|
||||||
|
"sudo",
|
||||||
|
"nohup",
|
||||||
|
"nice",
|
||||||
|
]);
|
||||||
|
|
||||||
|
function findCommandWord(words: string[]): string | undefined {
|
||||||
|
for (const word of words) {
|
||||||
|
if (COMMAND_PREFIXES.has(word)) continue;
|
||||||
|
if (/^[A-Za-z_][A-Za-z0-9_]*=/.test(word)) continue;
|
||||||
|
return word;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
function segmentHasGit(words: string[]): boolean {
|
||||||
|
const cmd = findCommandWord(words);
|
||||||
|
return cmd === "git";
|
||||||
|
}
|
||||||
|
|
||||||
|
function containsBlockedGit(command: string): boolean {
|
||||||
|
const segments = command.split(/\s*(?:&&|\|\||[;&|]|\$\(|`)\s*/);
|
||||||
|
for (const segment of segments) {
|
||||||
|
const words = segment.trim().split(/\s+/).filter(Boolean);
|
||||||
|
if (segmentHasGit(words)) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const BlockGitPlugin: Plugin = async () => {
|
||||||
|
return {
|
||||||
|
"tool.execute.before": async (input, output) => {
|
||||||
|
if (input.tool === "bash") {
|
||||||
|
const command = output.args.command as string;
|
||||||
|
if (containsBlockedGit(command)) {
|
||||||
|
throw new Error(
|
||||||
|
"This project uses jj, only use `jj` commands, not `git`.",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
19
modules/_opencode/plugin/block-scripting.ts
Normal file
19
modules/_opencode/plugin/block-scripting.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import type { Plugin } from "@opencode-ai/plugin";
|
||||||
|
|
||||||
|
const SCRIPTING_PATTERN =
|
||||||
|
/(?:^|[;&|]\s*|&&\s*|\|\|\s*|\$\(\s*|`\s*)(?:python[23]?|perl|ruby|php|lua|node\s+-e|bash\s+-c|sh\s+-c)\s/;
|
||||||
|
|
||||||
|
export const BlockScriptingPlugin: Plugin = async () => {
|
||||||
|
return {
|
||||||
|
"tool.execute.before": async (input, output) => {
|
||||||
|
if (input.tool === "bash") {
|
||||||
|
const command = output.args.command as string;
|
||||||
|
if (SCRIPTING_PATTERN.test(command)) {
|
||||||
|
throw new Error(
|
||||||
|
"Do not use python, perl, ruby, php, lua, or inline bash/sh for scripting. Use `nu -c` instead.",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
1434
modules/_opencode/plugin/review.ts
Normal file
1434
modules/_opencode/plugin/review.ts
Normal file
File diff suppressed because it is too large
Load Diff
6
modules/_overlays/ast-grep.nix
Normal file
6
modules/_overlays/ast-grep.nix
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{inputs, ...}: final: prev: {
|
||||||
|
ast-grep =
|
||||||
|
prev.ast-grep.overrideAttrs (old: {
|
||||||
|
doCheck = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
44
modules/_overlays/cog-cli.nix
Normal file
44
modules/_overlays/cog-cli.nix
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
{inputs, ...}: final: prev: let
|
||||||
|
version = "0.24.1";
|
||||||
|
srcs = {
|
||||||
|
x86_64-linux =
|
||||||
|
prev.fetchurl {
|
||||||
|
url = "https://github.com/trycog/cog-cli/releases/download/v${version}/cog-linux-x86_64.tar.gz";
|
||||||
|
hash = "sha256-/ioEuM58F3ppO0wlc5nw7ZNHunoweOXL/Gda65r0Ig4=";
|
||||||
|
};
|
||||||
|
aarch64-darwin =
|
||||||
|
prev.fetchurl {
|
||||||
|
url = "https://github.com/trycog/cog-cli/releases/download/v${version}/cog-darwin-arm64.tar.gz";
|
||||||
|
hash = "sha256-o/A2hVU3Jzmlzx5RbGLFCpfGAghcLGTD8Bm+bVR5OkQ=";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
cog-cli =
|
||||||
|
prev.stdenvNoCC.mkDerivation {
|
||||||
|
pname = "cog-cli";
|
||||||
|
inherit version;
|
||||||
|
src =
|
||||||
|
srcs.${prev.stdenv.hostPlatform.system}
|
||||||
|
or (throw "Unsupported system for cog-cli: ${prev.stdenv.hostPlatform.system}");
|
||||||
|
|
||||||
|
dontUnpack = true;
|
||||||
|
dontConfigure = true;
|
||||||
|
dontBuild = true;
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
runHook preInstall
|
||||||
|
tar -xzf "$src"
|
||||||
|
install -Dm755 cog "$out/bin/cog"
|
||||||
|
runHook postInstall
|
||||||
|
'';
|
||||||
|
|
||||||
|
meta = with prev.lib; {
|
||||||
|
description = "Memory, code intelligence, and debugging for AI agents";
|
||||||
|
homepage = "https://github.com/trycog/cog-cli";
|
||||||
|
license = licenses.mit;
|
||||||
|
mainProgram = "cog";
|
||||||
|
platforms = builtins.attrNames srcs;
|
||||||
|
sourceProvenance = [sourceTypes.binaryNativeCode];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
{inputs}: final: prev: {
|
{inputs, ...}: final: prev: {
|
||||||
himalaya = inputs.himalaya.packages.${prev.stdenv.hostPlatform.system}.default;
|
himalaya = inputs.himalaya.packages.${prev.stdenv.hostPlatform.system}.default;
|
||||||
}
|
}
|
||||||
15
modules/_overlays/jj-ryu.nix
Normal file
15
modules/_overlays/jj-ryu.nix
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{inputs, ...}: final: prev: let
|
||||||
|
naersk-lib = prev.callPackage inputs.naersk {};
|
||||||
|
manifest = (prev.lib.importTOML "${inputs.jj-ryu}/Cargo.toml").package;
|
||||||
|
in {
|
||||||
|
jj-ryu =
|
||||||
|
naersk-lib.buildPackage {
|
||||||
|
pname = manifest.name;
|
||||||
|
version = manifest.version;
|
||||||
|
src = inputs.jj-ryu;
|
||||||
|
nativeBuildInputs = [prev.pkg-config];
|
||||||
|
buildInputs = [prev.openssl];
|
||||||
|
OPENSSL_NO_VENDOR = 1;
|
||||||
|
doCheck = false;
|
||||||
|
};
|
||||||
|
}
|
||||||
1
modules/_overlays/jj-starship.nix
Normal file
1
modules/_overlays/jj-starship.nix
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{inputs, ...}: inputs.jj-starship.overlays.default
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
{inputs}: final: prev: {
|
{inputs, ...}: final: prev: {
|
||||||
zjstatus = inputs.zjstatus.packages.${prev.stdenv.hostPlatform.system}.default;
|
zjstatus = inputs.zjstatus.packages.${prev.stdenv.hostPlatform.system}.default;
|
||||||
}
|
}
|
||||||
26
modules/_paperless/tag_prompt.tmpl
Normal file
26
modules/_paperless/tag_prompt.tmpl
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
I will provide you with the content and title of a document. Your task is to select appropriate tags for the document from the available list.
|
||||||
|
Only select tags from the provided list.
|
||||||
|
|
||||||
|
Rules:
|
||||||
|
1. Focus on WHAT the document IS (document type) and what TOPIC it relates to — not on incidental details mentioned in the content.
|
||||||
|
- GOOD tags for a server hosting invoice: "Invoice", "Hosting"
|
||||||
|
- BAD tags for a server hosting invoice: "IBAN", "VAT", "Bank account" — these are just details that appear on any invoice.
|
||||||
|
2. Pick 1-4 tags maximum. Fewer is better. Every tag must add distinct, meaningful categorisation value.
|
||||||
|
3. All tags must be in English.
|
||||||
|
4. Never tag based on formatting details, payment methods, reference numbers, or boilerplate text.
|
||||||
|
|
||||||
|
The content is likely in {{.Language}}, but tags must always be in English.
|
||||||
|
|
||||||
|
<available_tags>
|
||||||
|
{{.AvailableTags | join ", "}}
|
||||||
|
</available_tags>
|
||||||
|
|
||||||
|
<title>
|
||||||
|
{{.Title}}
|
||||||
|
</title>
|
||||||
|
|
||||||
|
<content>
|
||||||
|
{{.Content}}
|
||||||
|
</content>
|
||||||
|
|
||||||
|
Respond only with the selected tags as a comma-separated list, without any additional information.
|
||||||
26
modules/_paperless/title_prompt.tmpl
Normal file
26
modules/_paperless/title_prompt.tmpl
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
I will provide you with the content of a document that has been partially read by OCR (so it may contain errors).
|
||||||
|
Your task is to generate a clear, consistent document title for use in paperless-ngx.
|
||||||
|
|
||||||
|
Title format: "YYYY-MM-DD - Sender - Description"
|
||||||
|
- YYYY-MM-DD: The document date (issue date, statement date, etc.). Use the most specific date available. If no date is found, omit the date prefix.
|
||||||
|
- Sender: The company, organisation, or person who sent/issued the document. Use their common short name (e.g. "Hetzner" not "Hetzner Online GmbH").
|
||||||
|
- Description: A brief description of what the document is (e.g. "Server hosting invoice", "Payslip January", "Employment contract", "Tax assessment 2024"). Keep it concise but specific enough to distinguish from similar documents.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
- "2025-03-01 - Hetzner - Server hosting invoice"
|
||||||
|
- "2024-12-15 - Techniker Krankenkasse - Health insurance statement"
|
||||||
|
- "2024-06-30 - Acme Corp - Payslip June"
|
||||||
|
- "2024-01-10 - Finanzamt Berlin - Tax assessment 2023"
|
||||||
|
|
||||||
|
Rules:
|
||||||
|
1. Always write the title in English, regardless of the document language.
|
||||||
|
2. Keep the description part under 6 words.
|
||||||
|
3. If the original title contains useful information, use it to inform your suggestion.
|
||||||
|
4. Respond only with the title, without any additional information.
|
||||||
|
|
||||||
|
The content is likely in {{.Language}}.
|
||||||
|
|
||||||
|
<original_title>{{.Title}}</original_title>
|
||||||
|
<content>
|
||||||
|
{{.Content}}
|
||||||
|
</content>
|
||||||
181
modules/_terminal/rose-pine-dawn-glow.json
Normal file
181
modules/_terminal/rose-pine-dawn-glow.json
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
{
|
||||||
|
"document": {
|
||||||
|
"block_prefix": "\n",
|
||||||
|
"block_suffix": "\n",
|
||||||
|
"color": "#575279",
|
||||||
|
"margin": 2
|
||||||
|
},
|
||||||
|
"block_quote": {
|
||||||
|
"color": "#797593",
|
||||||
|
"italic": true,
|
||||||
|
"indent": 1,
|
||||||
|
"indent_token": "│ "
|
||||||
|
},
|
||||||
|
"list": {
|
||||||
|
"color": "#575279",
|
||||||
|
"level_indent": 2
|
||||||
|
},
|
||||||
|
"heading": {
|
||||||
|
"block_suffix": "\n",
|
||||||
|
"color": "#907aa9",
|
||||||
|
"bold": true
|
||||||
|
},
|
||||||
|
"h1": {
|
||||||
|
"prefix": "# ",
|
||||||
|
"bold": true
|
||||||
|
},
|
||||||
|
"h2": {
|
||||||
|
"prefix": "## "
|
||||||
|
},
|
||||||
|
"h3": {
|
||||||
|
"prefix": "### "
|
||||||
|
},
|
||||||
|
"h4": {
|
||||||
|
"prefix": "#### "
|
||||||
|
},
|
||||||
|
"h5": {
|
||||||
|
"prefix": "##### "
|
||||||
|
},
|
||||||
|
"h6": {
|
||||||
|
"prefix": "###### "
|
||||||
|
},
|
||||||
|
"strikethrough": {
|
||||||
|
"crossed_out": true
|
||||||
|
},
|
||||||
|
"emph": {
|
||||||
|
"italic": true,
|
||||||
|
"color": "#d7827e"
|
||||||
|
},
|
||||||
|
"strong": {
|
||||||
|
"bold": true,
|
||||||
|
"color": "#286983"
|
||||||
|
},
|
||||||
|
"hr": {
|
||||||
|
"color": "#dfdad9",
|
||||||
|
"format": "\n--------\n"
|
||||||
|
},
|
||||||
|
"item": {
|
||||||
|
"block_prefix": "• "
|
||||||
|
},
|
||||||
|
"enumeration": {
|
||||||
|
"block_prefix": ". ",
|
||||||
|
"color": "#286983"
|
||||||
|
},
|
||||||
|
"task": {
|
||||||
|
"ticked": "[✓] ",
|
||||||
|
"unticked": "[ ] "
|
||||||
|
},
|
||||||
|
"link": {
|
||||||
|
"color": "#286983",
|
||||||
|
"underline": true
|
||||||
|
},
|
||||||
|
"link_text": {
|
||||||
|
"color": "#56949f"
|
||||||
|
},
|
||||||
|
"image": {
|
||||||
|
"color": "#286983",
|
||||||
|
"underline": true
|
||||||
|
},
|
||||||
|
"image_text": {
|
||||||
|
"color": "#56949f",
|
||||||
|
"format": "Image: {{.text}} →"
|
||||||
|
},
|
||||||
|
"code": {
|
||||||
|
"color": "#ea9d34",
|
||||||
|
"background_color": "#f2e9e1",
|
||||||
|
"prefix": " ",
|
||||||
|
"suffix": " "
|
||||||
|
},
|
||||||
|
"code_block": {
|
||||||
|
"color": "#ea9d34",
|
||||||
|
"margin": 2,
|
||||||
|
"chroma": {
|
||||||
|
"text": {
|
||||||
|
"color": "#575279"
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"color": "#faf4ed",
|
||||||
|
"background_color": "#b4637a"
|
||||||
|
},
|
||||||
|
"comment": {
|
||||||
|
"color": "#9893a5"
|
||||||
|
},
|
||||||
|
"comment_preproc": {
|
||||||
|
"color": "#56949f"
|
||||||
|
},
|
||||||
|
"keyword": {
|
||||||
|
"color": "#b4637a"
|
||||||
|
},
|
||||||
|
"keyword_reserved": {
|
||||||
|
"color": "#b4637a"
|
||||||
|
},
|
||||||
|
"keyword_namespace": {
|
||||||
|
"color": "#b4637a"
|
||||||
|
},
|
||||||
|
"keyword_type": {
|
||||||
|
"color": "#907aa9"
|
||||||
|
},
|
||||||
|
"operator": {
|
||||||
|
"color": "#56949f"
|
||||||
|
},
|
||||||
|
"punctuation": {
|
||||||
|
"color": "#797593"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"color": "#286983"
|
||||||
|
},
|
||||||
|
"name_constant": {
|
||||||
|
"color": "#907aa9"
|
||||||
|
},
|
||||||
|
"name_builtin": {
|
||||||
|
"color": "#d7827e"
|
||||||
|
},
|
||||||
|
"name_tag": {
|
||||||
|
"color": "#b4637a"
|
||||||
|
},
|
||||||
|
"name_attribute": {
|
||||||
|
"color": "#d7827e"
|
||||||
|
},
|
||||||
|
"name_class": {
|
||||||
|
"color": "#907aa9"
|
||||||
|
},
|
||||||
|
"name_decorator": {
|
||||||
|
"color": "#56949f"
|
||||||
|
},
|
||||||
|
"name_function": {
|
||||||
|
"color": "#286983"
|
||||||
|
},
|
||||||
|
"literal_number": {
|
||||||
|
"color": "#ea9d34"
|
||||||
|
},
|
||||||
|
"literal_string": {
|
||||||
|
"color": "#ea9d34"
|
||||||
|
},
|
||||||
|
"literal_string_escape": {
|
||||||
|
"color": "#d7827e"
|
||||||
|
},
|
||||||
|
"generic_deleted": {
|
||||||
|
"color": "#b4637a"
|
||||||
|
},
|
||||||
|
"generic_emph": {
|
||||||
|
"italic": true
|
||||||
|
},
|
||||||
|
"generic_inserted": {
|
||||||
|
"color": "#286983"
|
||||||
|
},
|
||||||
|
"generic_strong": {
|
||||||
|
"bold": true
|
||||||
|
},
|
||||||
|
"generic_subheading": {
|
||||||
|
"color": "#907aa9"
|
||||||
|
},
|
||||||
|
"background": {
|
||||||
|
"background_color": "#f2e9e1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"table": {},
|
||||||
|
"definition_description": {
|
||||||
|
"block_prefix": "\n🠶 "
|
||||||
|
}
|
||||||
|
}
|
||||||
62
modules/adguardhome.nix
Normal file
62
modules/adguardhome.nix
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
{...}: let
|
||||||
|
caddyLib = import ./_lib/caddy.nix;
|
||||||
|
in {
|
||||||
|
den.aspects.adguardhome.nixos = {config, ...}: {
|
||||||
|
services.adguardhome = {
|
||||||
|
enable = true;
|
||||||
|
host = "127.0.0.1";
|
||||||
|
port = 10000;
|
||||||
|
settings = {
|
||||||
|
dhcp.enabled = false;
|
||||||
|
dns.upstream_dns = [
|
||||||
|
"1.1.1.1"
|
||||||
|
"1.0.0.1"
|
||||||
|
];
|
||||||
|
filtering = {
|
||||||
|
protection_enabled = true;
|
||||||
|
filtering_enabled = true;
|
||||||
|
safe_search.enabled = false;
|
||||||
|
safebrowsing_enabled = true;
|
||||||
|
blocked_response_ttl = 10;
|
||||||
|
filters_update_interval = 24;
|
||||||
|
blocked_services.ids = [
|
||||||
|
"reddit"
|
||||||
|
"twitter"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
filters = [
|
||||||
|
{
|
||||||
|
enabled = true;
|
||||||
|
url = "https://cdn.jsdelivr.net/gh/hagezi/dns-blocklists@latest/adblock/pro.txt";
|
||||||
|
name = "HaGeZi Multi PRO";
|
||||||
|
id = 1;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
enabled = true;
|
||||||
|
url = "https://cdn.jsdelivr.net/gh/hagezi/dns-blocklists@latest/adblock/tif.txt";
|
||||||
|
name = "HaGeZi Threat Intelligence Feeds";
|
||||||
|
id = 2;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
enabled = true;
|
||||||
|
url = "https://cdn.jsdelivr.net/gh/hagezi/dns-blocklists@latest/adblock/gambling.txt";
|
||||||
|
name = "HaGeZi Gambling";
|
||||||
|
id = 3;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
enabled = true;
|
||||||
|
url = "https://cdn.jsdelivr.net/gh/hagezi/dns-blocklists@latest/adblock/nsfw.txt";
|
||||||
|
name = "HaGeZi NSFW";
|
||||||
|
id = 4;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.caddy.virtualHosts =
|
||||||
|
caddyLib.mkTailscaleVHost {
|
||||||
|
name = "adguard";
|
||||||
|
configText = "reverse_proxy localhost:${toString config.services.adguardhome.port}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
180
modules/ai-tools.nix
Normal file
180
modules/ai-tools.nix
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
{inputs, ...}: let
|
||||||
|
local = import ./_lib/local.nix;
|
||||||
|
inherit (local) secretPath;
|
||||||
|
opencodeSecretPath = secretPath "opencode-api-key";
|
||||||
|
in {
|
||||||
|
den.aspects.ai-tools.homeManager = {
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
inputs',
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
home.packages = [
|
||||||
|
inputs'.llm-agents.packages.claude-code
|
||||||
|
pkgs.cog-cli
|
||||||
|
];
|
||||||
|
|
||||||
|
programs.nushell.extraEnv =
|
||||||
|
lib.mkAfter ''
|
||||||
|
if ("${opencodeSecretPath}" | path exists) {
|
||||||
|
$env.OPENCODE_API_KEY = (open --raw "${opencodeSecretPath}" | str trim)
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
|
||||||
|
programs.opencode = {
|
||||||
|
enable = true;
|
||||||
|
package = inputs'.llm-agents.packages.opencode;
|
||||||
|
tui = {
|
||||||
|
theme = "rosepine";
|
||||||
|
plugin = ["./plugin/review.ts"];
|
||||||
|
};
|
||||||
|
settings = {
|
||||||
|
model = "openai/gpt-5.4";
|
||||||
|
small_model = "openai/gpt-5.1-codex-mini";
|
||||||
|
plugin = [
|
||||||
|
"opencode-claude-auth"
|
||||||
|
"opencode-supermemory"
|
||||||
|
];
|
||||||
|
permission = {
|
||||||
|
external_directory = {
|
||||||
|
"*" = "allow";
|
||||||
|
"**/.gnupg/**" = "deny";
|
||||||
|
"**/.ssh/**" = "deny";
|
||||||
|
"~/.config/gh/hosts.yml" = "deny";
|
||||||
|
"~/.config/sops/age/keys.txt" = "deny";
|
||||||
|
"~/.local/share/opencode/mcp-auth.json" = "deny";
|
||||||
|
"/etc/ssh/ssh_host_*" = "deny";
|
||||||
|
"/run/secrets/*" = "deny";
|
||||||
|
};
|
||||||
|
bash = {
|
||||||
|
"*" = "allow";
|
||||||
|
env = "deny";
|
||||||
|
"env *" = "deny";
|
||||||
|
printenv = "deny";
|
||||||
|
"printenv *" = "deny";
|
||||||
|
"export *" = "deny";
|
||||||
|
"gh auth *" = "deny";
|
||||||
|
ssh = "ask";
|
||||||
|
"ssh *" = "ask";
|
||||||
|
mosh = "ask";
|
||||||
|
"mosh *" = "ask";
|
||||||
|
"cat *.env" = "deny";
|
||||||
|
"cat *.env.*" = "deny";
|
||||||
|
"cat **/.env" = "deny";
|
||||||
|
"cat **/.env.*" = "deny";
|
||||||
|
"cat *.envrc" = "deny";
|
||||||
|
"cat **/.envrc" = "deny";
|
||||||
|
"cat .dev.vars" = "deny";
|
||||||
|
"cat **/.dev.vars" = "deny";
|
||||||
|
"cat *.pem" = "deny";
|
||||||
|
"cat *.key" = "deny";
|
||||||
|
"cat **/.gnupg/**" = "deny";
|
||||||
|
"cat **/.ssh/**" = "deny";
|
||||||
|
"cat ~/.config/gh/hosts.yml" = "deny";
|
||||||
|
"cat ~/.config/sops/age/keys.txt" = "deny";
|
||||||
|
"cat ~/.local/share/opencode/mcp-auth.json" = "deny";
|
||||||
|
"cat /etc/ssh/ssh_host_*" = "deny";
|
||||||
|
"cat /run/secrets/*" = "deny";
|
||||||
|
};
|
||||||
|
edit = {
|
||||||
|
"*" = "allow";
|
||||||
|
"**/.gnupg/**" = "deny";
|
||||||
|
"**/.ssh/**" = "deny";
|
||||||
|
"**/secrets/**" = "deny";
|
||||||
|
"secrets/*" = "deny";
|
||||||
|
"~/.config/gh/hosts.yml" = "deny";
|
||||||
|
"~/.config/sops/age/keys.txt" = "deny";
|
||||||
|
"~/.local/share/opencode/mcp-auth.json" = "deny";
|
||||||
|
"/etc/ssh/ssh_host_*" = "deny";
|
||||||
|
"/run/secrets/*" = "deny";
|
||||||
|
};
|
||||||
|
glob = "allow";
|
||||||
|
grep = "allow";
|
||||||
|
list = "allow";
|
||||||
|
lsp = "allow";
|
||||||
|
question = "allow";
|
||||||
|
read = {
|
||||||
|
"*" = "allow";
|
||||||
|
"*.env" = "deny";
|
||||||
|
"*.env.*" = "deny";
|
||||||
|
"*.envrc" = "deny";
|
||||||
|
"**/.env" = "deny";
|
||||||
|
"**/.env.*" = "deny";
|
||||||
|
"**/.envrc" = "deny";
|
||||||
|
".dev.vars" = "deny";
|
||||||
|
"**/.dev.vars" = "deny";
|
||||||
|
"**/.gnupg/**" = "deny";
|
||||||
|
"**/.ssh/**" = "deny";
|
||||||
|
"*.key" = "deny";
|
||||||
|
"*.pem" = "deny";
|
||||||
|
"**/secrets/**" = "deny";
|
||||||
|
"secrets/*" = "deny";
|
||||||
|
"~/.config/gh/hosts.yml" = "deny";
|
||||||
|
"~/.config/sops/age/keys.txt" = "deny";
|
||||||
|
"~/.local/share/opencode/mcp-auth.json" = "deny";
|
||||||
|
"/etc/ssh/ssh_host_*" = "deny";
|
||||||
|
"/run/secrets/*" = "deny";
|
||||||
|
};
|
||||||
|
skill = "allow";
|
||||||
|
task = "allow";
|
||||||
|
webfetch = "allow";
|
||||||
|
websearch = "allow";
|
||||||
|
codesearch = "allow";
|
||||||
|
};
|
||||||
|
agent = {
|
||||||
|
explore = {
|
||||||
|
model = "openai/gpt-5.1-codex-mini";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
instructions = [
|
||||||
|
"CLAUDE.md"
|
||||||
|
"AGENT.md"
|
||||||
|
# "AGENTS.md"
|
||||||
|
"AGENTS.local.md"
|
||||||
|
];
|
||||||
|
formatter = {
|
||||||
|
mix = {
|
||||||
|
disabled = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
mcp = {
|
||||||
|
opensrc = {
|
||||||
|
enabled = true;
|
||||||
|
type = "local";
|
||||||
|
command = ["node" "/home/cschmatzler/.bun/bin/opensrc-mcp"];
|
||||||
|
};
|
||||||
|
context7 = {
|
||||||
|
enabled = true;
|
||||||
|
type = "remote";
|
||||||
|
url = "https://mcp.context7.com/mcp";
|
||||||
|
};
|
||||||
|
grep_app = {
|
||||||
|
enabled = true;
|
||||||
|
type = "remote";
|
||||||
|
url = "https://mcp.grep.app";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
xdg.configFile = {
|
||||||
|
# "opencode/agent" = {
|
||||||
|
# source = ./_opencode/agent;
|
||||||
|
# recursive = true;
|
||||||
|
# };
|
||||||
|
"opencode/command" = {
|
||||||
|
source = ./_opencode/command;
|
||||||
|
recursive = true;
|
||||||
|
};
|
||||||
|
"opencode/skill" = {
|
||||||
|
source = ./_opencode/skill;
|
||||||
|
recursive = true;
|
||||||
|
};
|
||||||
|
"opencode/plugin" = {
|
||||||
|
source = ./_opencode/plugin;
|
||||||
|
recursive = true;
|
||||||
|
};
|
||||||
|
"opencode/AGENTS.md".source = ./_opencode/AGENTS.md;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
43
modules/apps.nix
Normal file
43
modules/apps.nix
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
{inputs, ...}: {
|
||||||
|
perSystem = {
|
||||||
|
pkgs,
|
||||||
|
system,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
descriptions = {
|
||||||
|
apply = "Build and apply configuration";
|
||||||
|
build = "Build configuration";
|
||||||
|
rollback = "Rollback to previous generation";
|
||||||
|
update = "Update flake inputs and regenerate flake.nix";
|
||||||
|
};
|
||||||
|
mkPlatformApp = name: {
|
||||||
|
type = "app";
|
||||||
|
program = "${(pkgs.writeShellScriptBin name ''
|
||||||
|
PATH=${pkgs.git}/bin:$PATH
|
||||||
|
exec ${inputs.self}/apps/${system}/${name} "$@"
|
||||||
|
'')}/bin/${name}";
|
||||||
|
meta.description = descriptions.${name};
|
||||||
|
};
|
||||||
|
mkSharedApp = name: {
|
||||||
|
type = "app";
|
||||||
|
program = "${(pkgs.writeShellScriptBin name ''
|
||||||
|
PATH=${pkgs.git}/bin:$PATH
|
||||||
|
exec ${inputs.self}/apps/${name} "$@"
|
||||||
|
'')}/bin/${name}";
|
||||||
|
meta.description = descriptions.${name};
|
||||||
|
};
|
||||||
|
platformAppNames = ["build" "rollback"];
|
||||||
|
sharedAppNames = ["apply" "update"];
|
||||||
|
in {
|
||||||
|
apps =
|
||||||
|
pkgs.lib.genAttrs platformAppNames mkPlatformApp
|
||||||
|
// pkgs.lib.genAttrs sharedAppNames mkSharedApp
|
||||||
|
// {
|
||||||
|
deploy = {
|
||||||
|
type = "app";
|
||||||
|
program = "${inputs.deploy-rs.packages.${system}.deploy-rs}/bin/deploy";
|
||||||
|
meta.description = "Deploy to NixOS hosts via deploy-rs";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
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;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
11
modules/cache.nix
Normal file
11
modules/cache.nix
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{...}: let
|
||||||
|
caddyLib = import ./_lib/caddy.nix;
|
||||||
|
in {
|
||||||
|
den.aspects.cache.nixos = {
|
||||||
|
services.caddy.virtualHosts =
|
||||||
|
caddyLib.mkTailscaleVHost {
|
||||||
|
name = "cache";
|
||||||
|
configText = "reverse_proxy localhost:32843";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
44
modules/core.nix
Normal file
44
modules/core.nix
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
{...}: {
|
||||||
|
den.aspects.core.os = {
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
# System utilities
|
||||||
|
environment.systemPackages =
|
||||||
|
lib.optionals pkgs.stdenv.isLinux [
|
||||||
|
pkgs.lm_sensors
|
||||||
|
];
|
||||||
|
|
||||||
|
programs.fish.enable = true;
|
||||||
|
environment.shells = [pkgs.nushell];
|
||||||
|
|
||||||
|
nixpkgs = {
|
||||||
|
config = {
|
||||||
|
allowUnfree = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
nix = {
|
||||||
|
package = pkgs.nix;
|
||||||
|
settings = {
|
||||||
|
cores = 4;
|
||||||
|
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,23 @@
|
|||||||
{
|
{inputs, ...}: let
|
||||||
pkgs,
|
local = import ./_lib/local.nix;
|
||||||
inputs,
|
userHome = "/Users/${local.user.name}";
|
||||||
user,
|
in {
|
||||||
constants,
|
den.aspects.darwin-system.darwin = {pkgs, ...}: {
|
||||||
...
|
imports = [
|
||||||
}: {
|
inputs.nix-homebrew.darwinModules.nix-homebrew
|
||||||
home-manager.extraSpecialArgs = {inherit user constants inputs;};
|
inputs.home-manager.darwinModules.home-manager
|
||||||
|
./_darwin/dock.nix
|
||||||
|
];
|
||||||
|
|
||||||
system = {
|
system.primaryUser = local.user.name;
|
||||||
primaryUser = user;
|
|
||||||
stateVersion = constants.stateVersions.darwin;
|
|
||||||
|
|
||||||
defaults = {
|
# Darwin system utilities
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
dockutil
|
||||||
|
mas
|
||||||
|
];
|
||||||
|
|
||||||
|
system.defaults = {
|
||||||
NSGlobalDomain = {
|
NSGlobalDomain = {
|
||||||
AppleInterfaceStyle = null;
|
AppleInterfaceStyle = null;
|
||||||
AppleShowAllExtensions = true;
|
AppleShowAllExtensions = true;
|
||||||
@@ -38,7 +44,7 @@
|
|||||||
autohide = true;
|
autohide = true;
|
||||||
show-recents = false;
|
show-recents = false;
|
||||||
launchanim = true;
|
launchanim = true;
|
||||||
orientation = "bottom";
|
orientation = "left";
|
||||||
tilesize = 60;
|
tilesize = 60;
|
||||||
minimize-to-application = true;
|
minimize-to-application = true;
|
||||||
mru-spaces = false;
|
mru-spaces = false;
|
||||||
@@ -99,14 +105,16 @@
|
|||||||
allowApplePersonalizedAdvertising = false;
|
allowApplePersonalizedAdvertising = false;
|
||||||
};
|
};
|
||||||
"com.apple.Spotlight" = {
|
"com.apple.Spotlight" = {
|
||||||
MenuItemHidden = true;
|
"NSStatusItem Visible Item-0" = false;
|
||||||
};
|
};
|
||||||
|
"com.apple.TextInputMenu" = {
|
||||||
|
visible = false;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
nix = {
|
nix = {
|
||||||
settings.trusted-users = ["@admin" "${user}"];
|
settings.trusted-users = [local.user.name];
|
||||||
gc.interval = {
|
gc.interval = {
|
||||||
Weekday = 0;
|
Weekday = 0;
|
||||||
Hour = 2;
|
Hour = 2;
|
||||||
@@ -114,12 +122,44 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
users.users.${user} = {
|
users.users.${local.user.name} = {
|
||||||
name = user;
|
name = local.user.name;
|
||||||
home = "/Users/${user}";
|
home = userHome;
|
||||||
isHidden = false;
|
isHidden = false;
|
||||||
shell = pkgs.nushell;
|
shell = pkgs.nushell;
|
||||||
};
|
};
|
||||||
|
|
||||||
home-manager.useGlobalPkgs = true;
|
nix-homebrew = {
|
||||||
|
enable = true;
|
||||||
|
user = local.user.name;
|
||||||
|
mutableTaps = true;
|
||||||
|
taps = {
|
||||||
|
"homebrew/homebrew-core" = inputs.homebrew-core;
|
||||||
|
"homebrew/homebrew-cask" = inputs.homebrew-cask;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
homebrew = {
|
||||||
|
enable = true;
|
||||||
|
onActivation = {
|
||||||
|
autoUpdate = true;
|
||||||
|
cleanup = "uninstall";
|
||||||
|
upgrade = true;
|
||||||
|
};
|
||||||
|
taps = [
|
||||||
|
"homebrew/cask"
|
||||||
|
];
|
||||||
|
casks = [
|
||||||
|
"1password"
|
||||||
|
"alcove"
|
||||||
|
"aqua-voice"
|
||||||
|
"chatgpt"
|
||||||
|
"ghostty@tip"
|
||||||
|
"raycast"
|
||||||
|
"spotify"
|
||||||
|
"tailscale"
|
||||||
|
"whatsapp"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
70
modules/defaults.nix
Normal file
70
modules/defaults.nix
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
{
|
||||||
|
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 = {};
|
||||||
|
};
|
||||||
|
flakeModules =
|
||||||
|
lib.mkOption {
|
||||||
|
type = lib.types.lazyAttrsOf lib.types.raw;
|
||||||
|
default = {};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
flake.flakeModules = {
|
||||||
|
# Shared system foundations
|
||||||
|
core = ./core.nix;
|
||||||
|
darwin = ./darwin.nix;
|
||||||
|
network = ./network.nix;
|
||||||
|
nixos-system = ./nixos-system.nix;
|
||||||
|
overlays = ./overlays.nix;
|
||||||
|
secrets = ./secrets.nix;
|
||||||
|
|
||||||
|
# Shared host features
|
||||||
|
adguardhome = ./adguardhome.nix;
|
||||||
|
cache = ./cache.nix;
|
||||||
|
gitea = ./gitea.nix;
|
||||||
|
opencode = ./opencode.nix;
|
||||||
|
paperless = ./paperless.nix;
|
||||||
|
|
||||||
|
# User environment
|
||||||
|
ai-tools = ./ai-tools.nix;
|
||||||
|
atuin = ./atuin.nix;
|
||||||
|
desktop = ./desktop.nix;
|
||||||
|
dev-tools = ./dev-tools.nix;
|
||||||
|
email = ./email.nix;
|
||||||
|
neovim = ./neovim.nix;
|
||||||
|
shell = ./shell.nix;
|
||||||
|
ssh-client = ./ssh-client.nix;
|
||||||
|
terminal = ./terminal.nix;
|
||||||
|
zellij = ./zellij.nix;
|
||||||
|
zk = ./zk.nix;
|
||||||
|
};
|
||||||
|
den.default.nixos.system.stateVersion = "25.11";
|
||||||
|
den.default.darwin.system.stateVersion = 6;
|
||||||
|
den.default.homeManager = {
|
||||||
|
home.stateVersion = "25.11";
|
||||||
|
programs.home-manager.enable = true;
|
||||||
|
};
|
||||||
|
den.default.nixos.home-manager.useGlobalPkgs = true;
|
||||||
|
den.default.darwin.home-manager.useGlobalPkgs = true;
|
||||||
|
|
||||||
|
den.default.includes = [
|
||||||
|
den.provides.define-user
|
||||||
|
den.provides.inputs'
|
||||||
|
];
|
||||||
|
|
||||||
|
den.schema.user.classes = lib.mkDefault ["homeManager"];
|
||||||
|
};
|
||||||
|
}
|
||||||
92
modules/dendritic.nix
Normal file
92
modules/dendritic.nix
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
{inputs, ...}: {
|
||||||
|
imports = [
|
||||||
|
(inputs.den.flakeModules.dendritic or {})
|
||||||
|
(inputs.flake-file.flakeModules.dendritic or {})
|
||||||
|
];
|
||||||
|
|
||||||
|
# Use alejandra with tabs for flake.nix formatting (matches alejandra.toml)
|
||||||
|
flake-file.formatter = pkgs:
|
||||||
|
pkgs.writeShellApplication {
|
||||||
|
name = "alejandra-tabs";
|
||||||
|
runtimeInputs = [pkgs.alejandra];
|
||||||
|
text = ''
|
||||||
|
echo 'indentation = "Tabs"' > alejandra.toml
|
||||||
|
alejandra "$@"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# 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";
|
||||||
|
neovim-nightly-overlay = {
|
||||||
|
url = "github:nix-community/neovim-nightly-overlay";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
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";
|
||||||
|
fenix = {
|
||||||
|
url = "github:nix-community/fenix";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
naersk = {
|
||||||
|
url = "github:nix-community/naersk/master";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
# Neovim plugin inputs
|
||||||
|
code-review-nvim = {
|
||||||
|
url = "github:choplin/code-review.nvim";
|
||||||
|
flake = false;
|
||||||
|
};
|
||||||
|
jj-nvim = {
|
||||||
|
url = "github:NicolasGB/jj.nvim";
|
||||||
|
flake = false;
|
||||||
|
};
|
||||||
|
jj-diffconflicts = {
|
||||||
|
url = "github:rafikdraoui/jj-diffconflicts";
|
||||||
|
flake = false;
|
||||||
|
};
|
||||||
|
# Secrets inputs
|
||||||
|
sops-nix = {
|
||||||
|
url = "github:Mic92/sops-nix";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
38
modules/deploy.nix
Normal file
38
modules/deploy.nix
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
{
|
||||||
|
inputs,
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
local = import ./_lib/local.nix;
|
||||||
|
acceptNewHostKeys = [
|
||||||
|
"-o"
|
||||||
|
"StrictHostKeyChecking=accept-new"
|
||||||
|
];
|
||||||
|
mkSystemNode = {
|
||||||
|
hostname,
|
||||||
|
host,
|
||||||
|
}: {
|
||||||
|
inherit hostname;
|
||||||
|
sshUser = local.user.name;
|
||||||
|
sshOpts = acceptNewHostKeys;
|
||||||
|
profiles.system = {
|
||||||
|
user = "root";
|
||||||
|
path = inputs.deploy-rs.lib.x86_64-linux.activate.nixos config.flake.nixosConfigurations.${host};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
flake.deploy.nodes = {
|
||||||
|
michael =
|
||||||
|
mkSystemNode {
|
||||||
|
hostname = "git.schmatzler.com";
|
||||||
|
host = "michael";
|
||||||
|
};
|
||||||
|
tahani =
|
||||||
|
mkSystemNode {
|
||||||
|
hostname = "127.0.0.1";
|
||||||
|
host = "tahani";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
flake.checks.x86_64-linux = inputs.deploy-rs.lib.x86_64-linux.deployChecks config.flake.deploy;
|
||||||
|
}
|
||||||
148
modules/desktop.nix
Normal file
148
modules/desktop.nix
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
{...}: {
|
||||||
|
den.aspects.desktop.homeManager = {
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
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" = "com.apple.Safari";
|
||||||
|
};
|
||||||
|
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"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
246
modules/dev-tools.nix
Normal file
246
modules/dev-tools.nix
Normal file
@@ -0,0 +1,246 @@
|
|||||||
|
{...}: let
|
||||||
|
local = import ./_lib/local.nix;
|
||||||
|
palette = (import ./_lib/theme.nix).rosePineDawn.hex;
|
||||||
|
in {
|
||||||
|
den.aspects.dev-tools.homeManager = {
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
name = local.user.fullName;
|
||||||
|
in {
|
||||||
|
home.packages = with pkgs;
|
||||||
|
[
|
||||||
|
alejandra
|
||||||
|
ast-grep
|
||||||
|
bun
|
||||||
|
delta
|
||||||
|
deadnix
|
||||||
|
devenv
|
||||||
|
docker
|
||||||
|
docker-compose
|
||||||
|
lazydocker
|
||||||
|
gh
|
||||||
|
gnumake
|
||||||
|
hyperfine
|
||||||
|
jj-ryu
|
||||||
|
jj-starship
|
||||||
|
nil
|
||||||
|
nodejs_24
|
||||||
|
nurl
|
||||||
|
pnpm
|
||||||
|
postgresql_17
|
||||||
|
serie
|
||||||
|
sqlite
|
||||||
|
statix
|
||||||
|
tea
|
||||||
|
tokei
|
||||||
|
tree-sitter
|
||||||
|
(pkgs.writeShellApplication {
|
||||||
|
name = "tuist-pr";
|
||||||
|
runtimeInputs = with pkgs; [coreutils fzf gh git nushell];
|
||||||
|
text = ''
|
||||||
|
exec nu ${./_dev-tools/tuist-pr.nu} "$@"
|
||||||
|
'';
|
||||||
|
})
|
||||||
|
]
|
||||||
|
++ lib.optionals stdenv.isDarwin [
|
||||||
|
xcodes
|
||||||
|
]
|
||||||
|
++ lib.optionals stdenv.isLinux [
|
||||||
|
gcc15
|
||||||
|
];
|
||||||
|
|
||||||
|
# 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;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Jujutsu configuration
|
||||||
|
programs.jujutsu = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
user = {
|
||||||
|
name = name;
|
||||||
|
email = local.user.emails.personal;
|
||||||
|
};
|
||||||
|
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(\"${local.user.emails.personal}\")";
|
||||||
|
"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(),
|
||||||
|
)
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# JJUI configuration
|
||||||
|
programs.jjui = {
|
||||||
|
enable = true;
|
||||||
|
settings.ui.colors = {
|
||||||
|
text = {fg = palette.text;};
|
||||||
|
dimmed = {fg = palette.muted;};
|
||||||
|
selected = {
|
||||||
|
bg = palette.overlay;
|
||||||
|
fg = palette.text;
|
||||||
|
bold = true;
|
||||||
|
};
|
||||||
|
border = {fg = palette.muted;};
|
||||||
|
title = {
|
||||||
|
fg = palette.iris;
|
||||||
|
bold = true;
|
||||||
|
};
|
||||||
|
shortcut = {
|
||||||
|
fg = palette.pine;
|
||||||
|
bold = true;
|
||||||
|
};
|
||||||
|
matched = {
|
||||||
|
fg = palette.gold;
|
||||||
|
bold = true;
|
||||||
|
};
|
||||||
|
"revisions selected" = {
|
||||||
|
bg = palette.overlay;
|
||||||
|
fg = palette.text;
|
||||||
|
bold = true;
|
||||||
|
};
|
||||||
|
"status" = {bg = palette.overlay;};
|
||||||
|
"status title" = {
|
||||||
|
bg = palette.iris;
|
||||||
|
fg = palette.base;
|
||||||
|
bold = true;
|
||||||
|
};
|
||||||
|
"status shortcut" = {fg = palette.pine;};
|
||||||
|
"status dimmed" = {fg = palette.muted;};
|
||||||
|
"menu" = {bg = palette.base;};
|
||||||
|
"menu selected" = {
|
||||||
|
bg = palette.overlay;
|
||||||
|
fg = palette.text;
|
||||||
|
bold = true;
|
||||||
|
};
|
||||||
|
"menu border" = {fg = palette.muted;};
|
||||||
|
"menu title" = {
|
||||||
|
fg = palette.iris;
|
||||||
|
bold = true;
|
||||||
|
};
|
||||||
|
"menu shortcut" = {fg = palette.pine;};
|
||||||
|
"menu matched" = {
|
||||||
|
fg = palette.gold;
|
||||||
|
bold = true;
|
||||||
|
};
|
||||||
|
"preview border" = {fg = palette.muted;};
|
||||||
|
"help" = {bg = palette.base;};
|
||||||
|
"help border" = {fg = palette.muted;};
|
||||||
|
"help title" = {
|
||||||
|
fg = palette.iris;
|
||||||
|
bold = true;
|
||||||
|
};
|
||||||
|
"confirmation" = {bg = palette.base;};
|
||||||
|
"confirmation border" = {fg = palette.muted;};
|
||||||
|
"confirmation selected" = {
|
||||||
|
bg = palette.overlay;
|
||||||
|
fg = palette.text;
|
||||||
|
bold = true;
|
||||||
|
};
|
||||||
|
"confirmation dimmed" = {fg = palette.muted;};
|
||||||
|
source_marker = {
|
||||||
|
fg = palette.foam;
|
||||||
|
bold = true;
|
||||||
|
};
|
||||||
|
target_marker = {
|
||||||
|
fg = palette.rose;
|
||||||
|
bold = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Direnv configuration
|
||||||
|
programs.direnv = {
|
||||||
|
enable = true;
|
||||||
|
nix-direnv.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Mise configuration
|
||||||
|
programs.mise = {
|
||||||
|
enable = true;
|
||||||
|
enableNushellIntegration = true;
|
||||||
|
globalConfig.settings = {
|
||||||
|
auto_install = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
62
modules/email.nix
Normal file
62
modules/email.nix
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
{...}: let
|
||||||
|
local = import ./_lib/local.nix;
|
||||||
|
in {
|
||||||
|
den.aspects.email.homeManager = {pkgs, ...}: {
|
||||||
|
programs.aerc = {
|
||||||
|
enable = true;
|
||||||
|
extraConfig.general.unsafe-accounts-conf = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
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.${local.user.emails.personal} = {
|
||||||
|
primary = true;
|
||||||
|
maildir.path = local.user.emails.personal;
|
||||||
|
address = local.user.emails.personal;
|
||||||
|
userName = local.user.emails.icloud;
|
||||||
|
realName = local.user.fullName;
|
||||||
|
passwordCommand = ["${pkgs.coreutils}/bin/cat" (local.secretPath "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;
|
||||||
|
};
|
||||||
|
aerc.enable = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,61 +1,33 @@
|
|||||||
{
|
{lib, ...}: let
|
||||||
|
secretLib = import ./_lib/secrets.nix {inherit lib;};
|
||||||
|
in {
|
||||||
|
den.aspects.gitea.nixos = {
|
||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
...
|
...
|
||||||
}:
|
}: {
|
||||||
with lib; let
|
sops.secrets = {
|
||||||
cfg = config.my.gitea;
|
michael-gitea-litestream =
|
||||||
in {
|
secretLib.mkServiceBinarySecret {
|
||||||
options.my.gitea = {
|
name = "michael-gitea-litestream";
|
||||||
enable = mkEnableOption "Gitea git hosting service";
|
serviceUser = "gitea";
|
||||||
|
sopsFile = ../secrets/michael-gitea-litestream;
|
||||||
litestream = {
|
|
||||||
bucket =
|
|
||||||
mkOption {
|
|
||||||
type = types.str;
|
|
||||||
description = "S3 bucket name for Litestream database replication";
|
|
||||||
};
|
};
|
||||||
|
michael-gitea-restic-password =
|
||||||
secretFile =
|
secretLib.mkServiceBinarySecret {
|
||||||
mkOption {
|
name = "michael-gitea-restic-password";
|
||||||
type = types.path;
|
serviceUser = "gitea";
|
||||||
description = "Path to the environment file containing S3 credentials for Litestream";
|
sopsFile = ../secrets/michael-gitea-restic-password;
|
||||||
|
};
|
||||||
|
michael-gitea-restic-env =
|
||||||
|
secretLib.mkServiceBinarySecret {
|
||||||
|
name = "michael-gitea-restic-env";
|
||||||
|
serviceUser = "gitea";
|
||||||
|
sopsFile = ../secrets/michael-gitea-restic-env;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
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];
|
networking.firewall.allowedTCPPorts = [80 443];
|
||||||
|
|
||||||
services.redis.servers.gitea = {
|
services.redis.servers.gitea = {
|
||||||
@@ -105,29 +77,25 @@ in {
|
|||||||
|
|
||||||
services.litestream = {
|
services.litestream = {
|
||||||
enable = true;
|
enable = true;
|
||||||
environmentFile = cfg.litestream.secretFile;
|
environmentFile = config.sops.secrets.michael-gitea-litestream.path;
|
||||||
settings = {
|
settings.dbs = [
|
||||||
dbs = [
|
|
||||||
{
|
{
|
||||||
path = "/var/lib/gitea/data/gitea.db";
|
path = "/var/lib/gitea/data/gitea.db";
|
||||||
replicas = [
|
replicas = [
|
||||||
{
|
{
|
||||||
type = "s3";
|
type = "s3";
|
||||||
bucket = cfg.litestream.bucket;
|
bucket = "michael-gitea-litestream";
|
||||||
path = "gitea";
|
path = "gitea";
|
||||||
endpoint = cfg.s3.endpoint;
|
endpoint = "s3.eu-central-003.backblazeb2.com";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.litestream = {
|
systemd.services.litestream.serviceConfig = {
|
||||||
serviceConfig = {
|
User = lib.mkForce "gitea";
|
||||||
User = mkForce "gitea";
|
Group = lib.mkForce "gitea";
|
||||||
Group = mkForce "gitea";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
services.caddy = {
|
services.caddy = {
|
||||||
@@ -144,7 +112,7 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
services.restic.backups.gitea = {
|
services.restic.backups.gitea = {
|
||||||
repository = "s3:${cfg.s3.endpoint}/${cfg.restic.bucket}";
|
repository = "s3:s3.eu-central-003.backblazeb2.com/michael-gitea-repositories";
|
||||||
paths = ["/var/lib/gitea"];
|
paths = ["/var/lib/gitea"];
|
||||||
exclude = [
|
exclude = [
|
||||||
"/var/lib/gitea/log"
|
"/var/lib/gitea/log"
|
||||||
@@ -152,8 +120,8 @@ in {
|
|||||||
"/var/lib/gitea/data/gitea.db-shm"
|
"/var/lib/gitea/data/gitea.db-shm"
|
||||||
"/var/lib/gitea/data/gitea.db-wal"
|
"/var/lib/gitea/data/gitea.db-wal"
|
||||||
];
|
];
|
||||||
passwordFile = cfg.restic.passwordFile;
|
passwordFile = config.sops.secrets.michael-gitea-restic-password.path;
|
||||||
environmentFile = cfg.restic.environmentFile;
|
environmentFile = config.sops.secrets.michael-gitea-restic-env.path;
|
||||||
pruneOpts = [
|
pruneOpts = [
|
||||||
"--keep-daily 7"
|
"--keep-daily 7"
|
||||||
"--keep-weekly 4"
|
"--keep-weekly 4"
|
||||||
@@ -170,8 +138,8 @@ in {
|
|||||||
wants = ["restic-init-gitea.service"];
|
wants = ["restic-init-gitea.service"];
|
||||||
after = ["restic-init-gitea.service"];
|
after = ["restic-init-gitea.service"];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
User = mkForce "gitea";
|
User = lib.mkForce "gitea";
|
||||||
Group = mkForce "gitea";
|
Group = lib.mkForce "gitea";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -186,12 +154,12 @@ in {
|
|||||||
User = "gitea";
|
User = "gitea";
|
||||||
Group = "gitea";
|
Group = "gitea";
|
||||||
RemainAfterExit = true;
|
RemainAfterExit = true;
|
||||||
EnvironmentFile = cfg.restic.environmentFile;
|
EnvironmentFile = config.sops.secrets.michael-gitea-restic-env.path;
|
||||||
};
|
};
|
||||||
script = ''
|
script = ''
|
||||||
export RESTIC_PASSWORD=$(cat ${cfg.restic.passwordFile})
|
export RESTIC_PASSWORD=$(cat ${config.sops.secrets.michael-gitea-restic-password.path})
|
||||||
restic -r s3:${cfg.s3.endpoint}/${cfg.restic.bucket} snapshots &>/dev/null || \
|
restic -r s3:s3.eu-central-003.backblazeb2.com/michael-gitea-repositories snapshots &>/dev/null || \
|
||||||
restic -r s3:${cfg.s3.endpoint}/${cfg.restic.bucket} init
|
restic -r s3:s3.eu-central-003.backblazeb2.com/michael-gitea-repositories init
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
nameservers = ["1.1.1.1"];
|
nameservers = ["1.1.1.1"];
|
||||||
firewall = {
|
firewall = {
|
||||||
enable = true;
|
enable = true;
|
||||||
trustedInterfaces = ["eno1" "tailscale0"];
|
trustedInterfaces = ["eno1" "tailscale0" "docker0"];
|
||||||
allowedUDPPorts = [
|
allowedUDPPorts = [
|
||||||
53
|
53
|
||||||
config.services.tailscale.port
|
config.services.tailscale.port
|
||||||
35
modules/hosts/chidi.nix
Normal file
35
modules/hosts/chidi.nix
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
den,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
hostLib = import ../_lib/hosts.nix {inherit den lib;};
|
||||||
|
local = import ../_lib/local.nix;
|
||||||
|
host = "chidi";
|
||||||
|
hostMeta = local.hosts.chidi;
|
||||||
|
in
|
||||||
|
lib.recursiveUpdate
|
||||||
|
(hostLib.mkUserHost {
|
||||||
|
system = hostMeta.system;
|
||||||
|
inherit host;
|
||||||
|
user = local.user.name;
|
||||||
|
includes = [den.aspects.user-darwin-laptop];
|
||||||
|
homeManager = {...}: {
|
||||||
|
programs.git.settings.user.email = local.user.emails.work;
|
||||||
|
};
|
||||||
|
})
|
||||||
|
(hostLib.mkPerHostAspect {
|
||||||
|
inherit host;
|
||||||
|
includes = [
|
||||||
|
den.aspects.host-darwin-base
|
||||||
|
den.aspects.opencode-api-key
|
||||||
|
];
|
||||||
|
darwin = {...}: {
|
||||||
|
networking.hostName = host;
|
||||||
|
networking.computerName = host;
|
||||||
|
|
||||||
|
homebrew.casks = [
|
||||||
|
"slack"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
})
|
||||||
31
modules/hosts/janet.nix
Normal file
31
modules/hosts/janet.nix
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
den,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
hostLib = import ../_lib/hosts.nix {inherit den lib;};
|
||||||
|
local = import ../_lib/local.nix;
|
||||||
|
host = "janet";
|
||||||
|
hostMeta = local.hosts.janet;
|
||||||
|
in
|
||||||
|
lib.recursiveUpdate
|
||||||
|
(hostLib.mkUserHost {
|
||||||
|
system = hostMeta.system;
|
||||||
|
inherit host;
|
||||||
|
user = local.user.name;
|
||||||
|
includes = [
|
||||||
|
den.aspects.user-darwin-laptop
|
||||||
|
den.aspects.user-personal
|
||||||
|
];
|
||||||
|
})
|
||||||
|
(hostLib.mkPerHostAspect {
|
||||||
|
inherit host;
|
||||||
|
includes = [
|
||||||
|
den.aspects.host-darwin-base
|
||||||
|
den.aspects.opencode-api-key
|
||||||
|
];
|
||||||
|
darwin = {...}: {
|
||||||
|
networking.hostName = host;
|
||||||
|
networking.computerName = host;
|
||||||
|
};
|
||||||
|
})
|
||||||
35
modules/hosts/michael.nix
Normal file
35
modules/hosts/michael.nix
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
den,
|
||||||
|
inputs,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
hostLib = import ../_lib/hosts.nix {inherit den lib;};
|
||||||
|
local = import ../_lib/local.nix;
|
||||||
|
host = "michael";
|
||||||
|
hostMeta = local.hosts.michael;
|
||||||
|
in
|
||||||
|
lib.recursiveUpdate
|
||||||
|
(hostLib.mkUserHost {
|
||||||
|
system = hostMeta.system;
|
||||||
|
inherit host;
|
||||||
|
user = local.user.name;
|
||||||
|
includes = [den.aspects.user-minimal];
|
||||||
|
})
|
||||||
|
(hostLib.mkPerHostAspect {
|
||||||
|
inherit host;
|
||||||
|
includes = [
|
||||||
|
den.aspects.host-public-server
|
||||||
|
den.aspects.gitea
|
||||||
|
];
|
||||||
|
nixos = {modulesPath, ...}: {
|
||||||
|
imports = [
|
||||||
|
(modulesPath + "/installer/scan/not-detected.nix")
|
||||||
|
./_parts/michael/disk-config.nix
|
||||||
|
./_parts/michael/hardware-configuration.nix
|
||||||
|
inputs.disko.nixosModules.default
|
||||||
|
];
|
||||||
|
|
||||||
|
networking.hostName = host;
|
||||||
|
};
|
||||||
|
})
|
||||||
109
modules/hosts/tahani.nix
Normal file
109
modules/hosts/tahani.nix
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
{
|
||||||
|
den,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
hostLib = import ../_lib/hosts.nix {inherit den lib;};
|
||||||
|
local = import ../_lib/local.nix;
|
||||||
|
secretLib = import ../_lib/secrets.nix {inherit lib;};
|
||||||
|
host = "tahani";
|
||||||
|
hostMeta = local.hosts.tahani;
|
||||||
|
in
|
||||||
|
lib.recursiveUpdate
|
||||||
|
(hostLib.mkUserHost {
|
||||||
|
system = hostMeta.system;
|
||||||
|
inherit host;
|
||||||
|
user = local.user.name;
|
||||||
|
includes = [
|
||||||
|
den.aspects.user-workstation
|
||||||
|
den.aspects.user-personal
|
||||||
|
den.aspects.email
|
||||||
|
];
|
||||||
|
homeManager = {
|
||||||
|
config,
|
||||||
|
inputs',
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
opencode = inputs'.llm-agents.packages.opencode;
|
||||||
|
in {
|
||||||
|
programs.opencode.settings.permission.external_directory = {
|
||||||
|
"/tmp/himalaya-triage/*" = "allow";
|
||||||
|
"/var/lib/paperless/consume/inbox-triage/*" = "allow";
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.nushell.extraConfig = ''
|
||||||
|
if $nu.is-interactive and ('SSH_CONNECTION' in ($env | columns)) and ('ZELLIJ' not-in ($env | columns)) {
|
||||||
|
try {
|
||||||
|
zellij attach -c main
|
||||||
|
exit
|
||||||
|
} catch {
|
||||||
|
print "zellij auto-start failed; staying in shell"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
|
||||||
|
systemd.user.services.opencode-inbox-triage = {
|
||||||
|
Unit = {
|
||||||
|
Description = "OpenCode inbox triage";
|
||||||
|
};
|
||||||
|
Service = {
|
||||||
|
Type = "oneshot";
|
||||||
|
ExecStart = "${opencode}/bin/opencode run --command inbox-triage --model opencode-go/glm-5";
|
||||||
|
Environment = "PATH=${config.home.profileDirectory}/bin:/run/current-system/sw/bin";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.user.timers.opencode-inbox-triage = {
|
||||||
|
Unit = {
|
||||||
|
Description = "Run OpenCode inbox triage every 12 hours";
|
||||||
|
};
|
||||||
|
Timer = {
|
||||||
|
OnCalendar = "*-*-* 0/12:00:00";
|
||||||
|
Persistent = true;
|
||||||
|
};
|
||||||
|
Install = {
|
||||||
|
WantedBy = ["timers.target"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
})
|
||||||
|
(hostLib.mkPerHostAspect {
|
||||||
|
inherit host;
|
||||||
|
includes = [
|
||||||
|
den.aspects.host-nixos-base
|
||||||
|
den.aspects.opencode-api-key
|
||||||
|
den.aspects.adguardhome
|
||||||
|
den.aspects.cache
|
||||||
|
den.aspects.paperless
|
||||||
|
];
|
||||||
|
nixos = {...}: {
|
||||||
|
imports = [
|
||||||
|
./_parts/tahani/networking.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
networking.hostName = host;
|
||||||
|
|
||||||
|
sops.secrets.tahani-email-password =
|
||||||
|
secretLib.mkUserBinarySecret {
|
||||||
|
name = "tahani-email-password";
|
||||||
|
sopsFile = ../../secrets/tahani-email-password;
|
||||||
|
};
|
||||||
|
|
||||||
|
virtualisation.docker.enable = true;
|
||||||
|
users.users.${local.user.name}.extraGroups = [
|
||||||
|
"docker"
|
||||||
|
"paperless"
|
||||||
|
];
|
||||||
|
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"d /var/lib/paperless/consume 2775 paperless paperless -"
|
||||||
|
"d /var/lib/paperless/consume/inbox-triage 2775 paperless paperless -"
|
||||||
|
];
|
||||||
|
swapDevices = [
|
||||||
|
{
|
||||||
|
device = "/swapfile";
|
||||||
|
size = 16 * 1024;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
})
|
||||||
10
modules/inventory.nix
Normal file
10
modules/inventory.nix
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{lib, ...}: let
|
||||||
|
local = import ./_lib/local.nix;
|
||||||
|
in
|
||||||
|
lib.foldl' lib.recursiveUpdate {} (
|
||||||
|
lib.mapAttrsToList (
|
||||||
|
host: hostMeta:
|
||||||
|
lib.setAttrByPath ["den" "hosts" hostMeta.system host "users" local.user.name] {}
|
||||||
|
)
|
||||||
|
local.hosts
|
||||||
|
)
|
||||||
14
modules/neovim.nix
Normal file
14
modules/neovim.nix
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{inputs, ...}: {
|
||||||
|
den.aspects.neovim.homeManager = {pkgs, ...}: {
|
||||||
|
imports = [
|
||||||
|
inputs.nixvim.homeModules.nixvim
|
||||||
|
./_neovim/default.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
_module.args.nvim-plugin-sources = {
|
||||||
|
code-review-nvim = inputs.code-review-nvim;
|
||||||
|
jj-nvim = inputs.jj-nvim;
|
||||||
|
jj-diffconflicts = inputs.jj-diffconflicts;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
76
modules/network.nix
Normal file
76
modules/network.nix
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
{...}: {
|
||||||
|
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;
|
||||||
|
extraSetFlags = ["--ssh"];
|
||||||
|
openFirewall = true;
|
||||||
|
permitCertUid = "caddy";
|
||||||
|
useRoutingFeatures = "server";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
den.aspects.mosh.nixos = {
|
||||||
|
programs.mosh = {
|
||||||
|
enable = true;
|
||||||
|
openFirewall = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.firewall.interfaces.tailscale0.allowedUDPPortRanges = [
|
||||||
|
{
|
||||||
|
from = 60000;
|
||||||
|
to = 61000;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
den.aspects.tailscale.darwin = {
|
||||||
|
services.tailscale.enable = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user