Compare commits
No commits in common. "main" and "feat/rigging-integration" have entirely different histories.
main
...
feat/riggi
34 changed files with 55 additions and 549 deletions
|
|
@ -46,15 +46,6 @@ bosun.secrets.npmrc = { ... }; # Secret definitions
|
||||||
|
|
||||||
Profile definitions are in `modules/generic/profiles.nix`, implementations in `modules/nixos/profiles/`.
|
Profile definitions are in `modules/generic/profiles.nix`, implementations in `modules/nixos/profiles/`.
|
||||||
|
|
||||||
## Adding packages
|
|
||||||
|
|
||||||
Before writing a custom `packages/` derivation, always check if the package already exists in nixpkgs:
|
|
||||||
- Stable: https://search.nixos.org/packages?channel=25.11&query=<name>
|
|
||||||
- Unstable: https://search.nixos.org/packages?channel=unstable&query=<name>
|
|
||||||
- Master (bleeding edge): check open PRs at https://github.com/NixOS/nixpkgs/pulls
|
|
||||||
|
|
||||||
If it exists in `unstable` or `master` but not stable, pull it via `overlays/unstable.nix` using `channels.unstable` or `channels.master`. Only write a custom `packages/` derivation as a last resort.
|
|
||||||
|
|
||||||
## Architecture patterns
|
## Architecture patterns
|
||||||
|
|
||||||
- **import-tree** auto-discovers and imports `.nix` files in `modules/flake/`. Files prefixed with `_` are excluded from auto-import.
|
- **import-tree** auto-discovers and imports `.nix` files in `modules/flake/`. Files prefixed with `_` are excluded from auto-import.
|
||||||
|
|
|
||||||
6
flake.lock
generated
6
flake.lock
generated
|
|
@ -778,11 +778,11 @@
|
||||||
},
|
},
|
||||||
"master": {
|
"master": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1771495899,
|
"lastModified": 1767143992,
|
||||||
"narHash": "sha256-UlAN9PHsBx1Kk65gR/KvLfO74zQcOjNZ+d/0td5T8eM=",
|
"narHash": "sha256-c3jlq36uxltxGLuQ3KPYfxZkue/LLD0Ct3NdhBUsRyo=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "f4f54061a12ebbdd03d7c53eed54d1e135840624",
|
"rev": "5830d8dfe6ae79365987d78bda3dd4152c271d8b",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
{...}: {
|
|
||||||
# Attic binary cache client configuration
|
|
||||||
xdg.configFile."attic/config.toml".text = ''
|
|
||||||
[cache.toph]
|
|
||||||
endpoint = "https://cache.toph.so"
|
|
||||||
'';
|
|
||||||
}
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
{ pkgs, config, lib, ... }: {
|
|
||||||
home.packages = [ pkgs.awscli2 ];
|
|
||||||
|
|
||||||
# Derive AWS credentials from the existing nix-cache S3 secret — same
|
|
||||||
# credentials, different format. No duplication, no Nomad API access needed.
|
|
||||||
age.generators.aws-credentials = { decrypt, deps, ... }: ''
|
|
||||||
KEY=$(${decrypt} ${lib.escapeShellArg deps.nix-cache-s3-env.file} \
|
|
||||||
| grep AWS_ACCESS_KEY_ID | cut -d= -f2-)
|
|
||||||
SECRET=$(${decrypt} ${lib.escapeShellArg deps.nix-cache-s3-env.file} \
|
|
||||||
| grep AWS_SECRET_ACCESS_KEY | cut -d= -f2-)
|
|
||||||
printf '[t4]\naws_access_key_id = %s\naws_secret_access_key = %s\n' \
|
|
||||||
"$KEY" "$SECRET"
|
|
||||||
'';
|
|
||||||
|
|
||||||
bosun.secrets.aws-credentials = {
|
|
||||||
rekeyFile = "aws-credentials.age";
|
|
||||||
path = "${config.home.homeDirectory}/.aws/credentials";
|
|
||||||
mode = "0600";
|
|
||||||
generator = {
|
|
||||||
script = "aws-credentials";
|
|
||||||
dependencies = {
|
|
||||||
inherit (config.age.secrets) nix-cache-s3-env;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
home.file.".aws/config".text = ''
|
|
||||||
[profile t4]
|
|
||||||
endpoint_url = https://s3.toph.so
|
|
||||||
region = us-east-1
|
|
||||||
'';
|
|
||||||
}
|
|
||||||
|
|
@ -15,7 +15,6 @@
|
||||||
rfc # TUI-based RFC reader
|
rfc # TUI-based RFC reader
|
||||||
nix-init # Generate Nix packages from URLs
|
nix-init # Generate Nix packages from URLs
|
||||||
install-nothing
|
install-nothing
|
||||||
marimo
|
|
||||||
|
|
||||||
# Language Servers
|
# Language Servers
|
||||||
lua-language-server
|
lua-language-server
|
||||||
|
|
@ -24,9 +23,6 @@
|
||||||
nodePackages.typescript-language-server
|
nodePackages.typescript-language-server
|
||||||
nil # nix lsp
|
nil # nix lsp
|
||||||
|
|
||||||
# Node.js for MCP servers
|
|
||||||
nodejs_22
|
|
||||||
|
|
||||||
# trurl # Parsing and manipulating URLs via CLI
|
# trurl # Parsing and manipulating URLs via CLI
|
||||||
pandoc # Document converter
|
pandoc # Document converter
|
||||||
ripgrep # Grep file search
|
ripgrep # Grep file search
|
||||||
|
|
@ -42,7 +38,6 @@
|
||||||
gitui
|
gitui
|
||||||
tea
|
tea
|
||||||
harbor.agent-deck # Terminal session manager for AI coding agents
|
harbor.agent-deck # Terminal session manager for AI coding agents
|
||||||
happy-coder # Claude Code mobile client (happy.engineering)
|
|
||||||
harbor.oryx # TUI for sniffing network traffic using eBPF
|
harbor.oryx # TUI for sniffing network traffic using eBPF
|
||||||
|
|
||||||
# BMAD
|
# BMAD
|
||||||
|
|
@ -87,48 +82,33 @@
|
||||||
enable = true;
|
enable = true;
|
||||||
# package = inputs.unstable.${system}.claude-code;
|
# package = inputs.unstable.${system}.claude-code;
|
||||||
|
|
||||||
mcpServers = {
|
# mcpServers = {
|
||||||
# Official MCP servers (require Node.js)
|
# fetch = {
|
||||||
fetch = {
|
# args = ["-y" "@modelcontextprotocol/server-fetch"];
|
||||||
command = "npx";
|
# command = "npx";
|
||||||
args = ["-y" "@modelcontextprotocol/server-fetch"];
|
# type = "stdio";
|
||||||
type = "stdio";
|
# };
|
||||||
};
|
# playwright = {
|
||||||
playwright = {
|
# args = ["-y" "@modelcontextprotocol/server-playwright"];
|
||||||
command = "npx";
|
# command = "npx";
|
||||||
args = ["-y" "@modelcontextprotocol/server-playwright"];
|
# type = "stdio";
|
||||||
type = "stdio";
|
# };
|
||||||
};
|
# stackexchange = {
|
||||||
stackexchange = {
|
# args = ["-y" "mcp-server-stackexchange"];
|
||||||
command = "npx";
|
# command = "npx";
|
||||||
args = ["-y" "mcp-server-stackexchange"];
|
# type = "stdio";
|
||||||
type = "stdio";
|
# };
|
||||||
};
|
# arxiv = {
|
||||||
arxiv = {
|
# args = ["-y" "mcp-server-arxiv"];
|
||||||
command = "npx";
|
# command = "npx";
|
||||||
args = ["-y" "mcp-server-arxiv"];
|
# type = "stdio";
|
||||||
type = "stdio";
|
# };
|
||||||
};
|
# claudezilla = {
|
||||||
|
# command = "bun";
|
||||||
# Custom MCP servers
|
# args = ["/home/toph/code/vendor/claudezilla/mcp/server.js"];
|
||||||
claudezilla = {
|
# type = "stdio";
|
||||||
command = "bun";
|
# };
|
||||||
args = ["/home/toph/code/vendor/claudezilla/mcp/server.js"];
|
# };
|
||||||
type = "stdio";
|
|
||||||
};
|
|
||||||
|
|
||||||
# Charlie MCP servers (local)
|
|
||||||
charlie-memory = {
|
|
||||||
command = "bun";
|
|
||||||
args = ["/home/toph/agent/mcp/memory/index.js"];
|
|
||||||
type = "stdio";
|
|
||||||
};
|
|
||||||
charlie-comunica = {
|
|
||||||
command = "bun";
|
|
||||||
args = ["/home/toph/agent/mcp/comunica/index.js"];
|
|
||||||
type = "stdio";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@
|
||||||
./wakatime.nix
|
./wakatime.nix
|
||||||
./gpg
|
./gpg
|
||||||
./niri
|
./niri
|
||||||
./hyprland
|
|
||||||
./stylix.nix
|
./stylix.nix
|
||||||
./default-applications.nix
|
./default-applications.nix
|
||||||
./misc/launcher.nix
|
./misc/launcher.nix
|
||||||
|
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
{pkgs, ...}: {
|
|
||||||
imports = [
|
|
||||||
./settings.nix
|
|
||||||
./keybinds.nix
|
|
||||||
./window-rules.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
wayland.windowManager.hyprland.enable = true;
|
|
||||||
|
|
||||||
home.packages = with pkgs; [
|
|
||||||
wl-clipboard
|
|
||||||
cliphist
|
|
||||||
hyprpicker
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
||||||
{pkgs, ...}: {
|
|
||||||
wayland.windowManager.hyprland.settings = {
|
|
||||||
"$mod" = "SUPER";
|
|
||||||
|
|
||||||
bind = [
|
|
||||||
# Apps
|
|
||||||
"$mod, space, exec, fuzzel"
|
|
||||||
"$mod, c, exec, ${pkgs.harbor.spawn-term}/bin/spawn-term"
|
|
||||||
"$mod, e, exec, nautilus"
|
|
||||||
"$mod, d, exec, zeal"
|
|
||||||
"$mod, g, exec, ${pkgs.harbor.hg-picker}/bin/hg-picker"
|
|
||||||
"$mod, v, exec, cliphist list | fuzzel --dmenu | cliphist decode | wl-copy"
|
|
||||||
|
|
||||||
# Window management
|
|
||||||
"$mod, q, killactive"
|
|
||||||
"$mod, f, fullscreen, 1"
|
|
||||||
"$mod, t, togglefloating"
|
|
||||||
"$mod, p, pseudo"
|
|
||||||
"$mod SHIFT, j, togglesplit"
|
|
||||||
|
|
||||||
# Focus (vim-style, matching niri keybinds)
|
|
||||||
"$mod, h, movefocus, l"
|
|
||||||
"$mod, l, movefocus, r"
|
|
||||||
"$mod, k, movefocus, u"
|
|
||||||
"$mod, j, movefocus, d"
|
|
||||||
|
|
||||||
# Move windows
|
|
||||||
"$mod CTRL, h, movewindow, l"
|
|
||||||
"$mod CTRL, l, movewindow, r"
|
|
||||||
"$mod CTRL, k, movewindow, u"
|
|
||||||
"$mod CTRL, j, movewindow, d"
|
|
||||||
|
|
||||||
# Workspaces
|
|
||||||
"$mod, 1, workspace, 1"
|
|
||||||
"$mod, 2, workspace, 2"
|
|
||||||
"$mod, 3, workspace, 3"
|
|
||||||
"$mod, 4, workspace, 4"
|
|
||||||
"$mod, 5, workspace, 5"
|
|
||||||
"$mod, 6, workspace, 6"
|
|
||||||
"$mod, 7, workspace, 7"
|
|
||||||
"$mod, 8, workspace, 8"
|
|
||||||
|
|
||||||
# Move to workspace silently
|
|
||||||
"$mod CTRL, 1, movetoworkspacesilent, 1"
|
|
||||||
"$mod CTRL, 2, movetoworkspacesilent, 2"
|
|
||||||
"$mod CTRL, 3, movetoworkspacesilent, 3"
|
|
||||||
"$mod CTRL, 4, movetoworkspacesilent, 4"
|
|
||||||
"$mod CTRL, 5, movetoworkspacesilent, 5"
|
|
||||||
"$mod CTRL, 6, movetoworkspacesilent, 6"
|
|
||||||
"$mod CTRL, 7, movetoworkspacesilent, 7"
|
|
||||||
"$mod CTRL, 8, movetoworkspacesilent, 8"
|
|
||||||
];
|
|
||||||
|
|
||||||
bindm = [
|
|
||||||
# Mouse: move and resize windows
|
|
||||||
"$mod, mouse:272, movewindow"
|
|
||||||
"$mod, mouse:273, resizewindow"
|
|
||||||
];
|
|
||||||
|
|
||||||
bindl = [
|
|
||||||
# Scroll through workspaces
|
|
||||||
"$mod, mouse_down, workspace, e+1"
|
|
||||||
"$mod, mouse_up, workspace, e-1"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,95 +0,0 @@
|
||||||
{pkgs, ...}: {
|
|
||||||
wayland.windowManager.hyprland.settings = {
|
|
||||||
monitor = [
|
|
||||||
# Main ultrawide (left)
|
|
||||||
"HDMI-A-1,3840x1080,0x0,1"
|
|
||||||
# Vertical display (right)
|
|
||||||
"DP-3,1920x1080,3840x-430,1,transform,1"
|
|
||||||
# Fallback for any other monitor
|
|
||||||
",preferred,auto,1"
|
|
||||||
];
|
|
||||||
|
|
||||||
exec-once = [
|
|
||||||
# Clipboard history
|
|
||||||
"wl-paste --type text --watch cliphist store"
|
|
||||||
"wl-paste --type image --watch cliphist store"
|
|
||||||
# Automount USB drives
|
|
||||||
"udiskie"
|
|
||||||
];
|
|
||||||
|
|
||||||
env = [
|
|
||||||
"MOZ_ENABLE_WAYLAND,1"
|
|
||||||
"QT_WAYLAND_DISABLE_WINDOWDECORATION,1"
|
|
||||||
"ELECTRON_OZONE_PLATFORM_HINT,auto"
|
|
||||||
"NIXOS_OZONE_WL,1"
|
|
||||||
"XDG_SESSION_TYPE,wayland"
|
|
||||||
"XDG_CURRENT_DESKTOP,Hyprland"
|
|
||||||
];
|
|
||||||
|
|
||||||
input = {
|
|
||||||
kb_layout = "us";
|
|
||||||
kb_variant = "intl";
|
|
||||||
follow_mouse = 2;
|
|
||||||
sensitivity = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
general = {
|
|
||||||
gaps_in = 8;
|
|
||||||
gaps_out = 15;
|
|
||||||
border_size = 2;
|
|
||||||
layout = "dwindle";
|
|
||||||
};
|
|
||||||
|
|
||||||
decoration = {
|
|
||||||
rounding = 8;
|
|
||||||
blur = {
|
|
||||||
enabled = true;
|
|
||||||
size = 4;
|
|
||||||
passes = 2;
|
|
||||||
noise = 0.05;
|
|
||||||
};
|
|
||||||
shadow = {
|
|
||||||
enabled = true;
|
|
||||||
range = 4;
|
|
||||||
render_power = 3;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
animations = {
|
|
||||||
enabled = true;
|
|
||||||
bezier = "myBezier, 0.05, 0.9, 0.1, 1.05";
|
|
||||||
animation = [
|
|
||||||
"windows, 1, 7, myBezier"
|
|
||||||
"windowsOut, 1, 7, default, popin 80%"
|
|
||||||
"border, 1, 10, default"
|
|
||||||
"fade, 1, 7, default"
|
|
||||||
"workspaces, 1, 6, default"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
# Single tiled window on main monitor: give it breathing room
|
|
||||||
workspace = [
|
|
||||||
# Pin workspaces to monitors
|
|
||||||
"1, monitor:HDMI-A-1, default:true"
|
|
||||||
"2, monitor:HDMI-A-1"
|
|
||||||
"3, monitor:HDMI-A-1"
|
|
||||||
"4, monitor:HDMI-A-1"
|
|
||||||
"5, monitor:HDMI-A-1"
|
|
||||||
"6, monitor:DP-3, default:true"
|
|
||||||
"7, monitor:DP-3"
|
|
||||||
"8, monitor:DP-3"
|
|
||||||
# Single tiled window on main monitor: give it breathing room
|
|
||||||
"w[t1] m[HDMI-A-1], gapsout:15 840 15 840"
|
|
||||||
];
|
|
||||||
|
|
||||||
dwindle = {
|
|
||||||
pseudotile = true;
|
|
||||||
preserve_split = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
misc = {
|
|
||||||
disable_hyprland_logo = true;
|
|
||||||
disable_splash_rendering = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
{...}: {
|
|
||||||
wayland.windowManager.hyprland.settings = {
|
|
||||||
windowrulev2 = [
|
|
||||||
# Prevent garbage frame flash before first render
|
|
||||||
"immediate, class:.*"
|
|
||||||
|
|
||||||
# Privacy: block from screen capture
|
|
||||||
"noscreenshare, class:^(1password)$"
|
|
||||||
"noscreenshare, class:^(thunderbird)$"
|
|
||||||
"noscreenshare, title:^(ld\\.toph\\.so)$"
|
|
||||||
|
|
||||||
# Floating windows
|
|
||||||
"float, class:^(org\\.zealdocs\\.zeal)$"
|
|
||||||
"center 1, class:^(org\\.zealdocs\\.zeal)$"
|
|
||||||
"size 50% 80%, class:^(org\\.zealdocs\\.zeal)$"
|
|
||||||
"minsize 1400 500, class:^(org\\.zealdocs\\.zeal)$"
|
|
||||||
|
|
||||||
"float, class:^(speedcrunch)$"
|
|
||||||
"center 1, class:^(speedcrunch)$"
|
|
||||||
"size 30% 60%, class:^(speedcrunch)$"
|
|
||||||
|
|
||||||
"float, title:^(DevTools)$"
|
|
||||||
|
|
||||||
# Kitty: slight transparency
|
|
||||||
"opacity 0.97 0.97, class:^(kitty)$"
|
|
||||||
|
|
||||||
# JetBrains: suppress phantom windows (RE2 doesn't support lookaheads,
|
|
||||||
# so we can't exclude toolbox here — apply per-IDE if needed)
|
|
||||||
# "nofocus, class:^(jetbrains-idea|jetbrains-rider|jetbrains-clion)$, floating:1, title:^win\\d+$"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -2,9 +2,5 @@
|
||||||
programs.niri.settings.spawn-at-startup = [
|
programs.niri.settings.spawn-at-startup = [
|
||||||
# open fastfetch by default
|
# open fastfetch by default
|
||||||
{argv = ["kitty" "--title" "'fastfetch'" "sh" "-c" "'fastfetch; read'"];}
|
{argv = ["kitty" "--title" "'fastfetch'" "sh" "-c" "'fastfetch; read'"];}
|
||||||
|
|
||||||
# Clipboard history daemons
|
|
||||||
{argv = ["wl-paste" "--type" "text" "--watch" "cliphist" "store"];}
|
|
||||||
{argv = ["wl-paste" "--type" "image" "--watch" "cliphist" "store"];}
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,5 @@
|
||||||
|
|
||||||
home.packages = with pkgs; [
|
home.packages = with pkgs; [
|
||||||
fuzzel
|
fuzzel
|
||||||
wl-clipboard
|
|
||||||
cliphist
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@
|
||||||
"Mod+d".action = spawn "zeal"; # Documentation viewer
|
"Mod+d".action = spawn "zeal"; # Documentation viewer
|
||||||
"Mod+c".action = spawn "${pkgs.harbor.spawn-term}/bin/spawn-term";
|
"Mod+c".action = spawn "${pkgs.harbor.spawn-term}/bin/spawn-term";
|
||||||
"Mod+g".action = spawn "${pkgs.harbor.hg-picker}/bin/hg-picker";
|
"Mod+g".action = spawn "${pkgs.harbor.hg-picker}/bin/hg-picker";
|
||||||
"Mod+v".action = spawn "sh" "-c" "cliphist list | fuzzel --dmenu | cliphist decode | wl-copy";
|
|
||||||
|
|
||||||
"Mod+q".action = close-window;
|
"Mod+q".action = close-window;
|
||||||
"Mod+f".action = fullscreen-window;
|
"Mod+f".action = fullscreen-window;
|
||||||
|
|
|
||||||
|
|
@ -20,25 +20,6 @@
|
||||||
|
|
||||||
#quirks = ["avahi" "docker" "nix-ld"];
|
#quirks = ["avahi" "docker" "nix-ld"];
|
||||||
key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPjqieS4GkYAa1WRYZpxjgYsj7VGZ9U+rTFCkX8M0umD";
|
key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPjqieS4GkYAa1WRYZpxjgYsj7VGZ9U+rTFCkX8M0umD";
|
||||||
|
|
||||||
secrets = {
|
|
||||||
nix-cache-privkey = "nix-cache-privkey.age";
|
|
||||||
nix-cache-s3-env = "nix-cache-s3.env.age";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Sign builds and push to the S3 binary cache at s3.toph.so/nix-cache.
|
|
||||||
nix.settings = {
|
|
||||||
secret-key-files = [config.age.secrets.nix-cache-privkey.path];
|
|
||||||
post-build-hook = toString (pkgs.writeScript "nix-cache-upload" ''
|
|
||||||
#!/bin/sh
|
|
||||||
set -uf
|
|
||||||
. ${config.age.secrets.nix-cache-s3-env.path}
|
|
||||||
${config.nix.package}/bin/nix copy \
|
|
||||||
--to "s3://nix-cache?endpoint=https://s3.toph.so®ion=us-east-1" \
|
|
||||||
$OUT_PATHS \
|
|
||||||
>> /tmp/nix-cache-upload.log 2>&1 &
|
|
||||||
'');
|
|
||||||
};
|
};
|
||||||
|
|
||||||
networking = {
|
networking = {
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@
|
||||||
inherit lib;
|
inherit lib;
|
||||||
pkgs = prev;
|
pkgs = prev;
|
||||||
};
|
};
|
||||||
harbor = inputs.self.packages.${system} or {};
|
|
||||||
})
|
})
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,5 @@
|
||||||
just
|
just
|
||||||
nh
|
nh
|
||||||
age
|
age
|
||||||
attic-client
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,14 +30,7 @@
|
||||||
keep-outputs = true;
|
keep-outputs = true;
|
||||||
|
|
||||||
trusted-users = ["root" "@wheel"];
|
trusted-users = ["root" "@wheel"];
|
||||||
substituters = [
|
substituters = ["https://cache.nixos.org/"];
|
||||||
"https://cache.nixos.org/"
|
|
||||||
"https://cache.toph.so/toph"
|
|
||||||
];
|
|
||||||
trusted-public-keys = [
|
|
||||||
"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
|
|
||||||
"toph:E/oP7KyljH/yprI5LArxNPpSlQCdo29sMOkh3jm53Yg="
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,13 +20,11 @@ in {
|
||||||
'';
|
'';
|
||||||
|
|
||||||
functions = {
|
functions = {
|
||||||
nomad-auth = {
|
nomad-ui = {
|
||||||
description = "Fetches the Nomad management token from alvin. Pass --ui to also open the authenticated UI.";
|
description = "Fetches the Nomad management token from alvin and opens the authenticated UI";
|
||||||
body = ''
|
body = ''
|
||||||
set -gx NOMAD_TOKEN (ssh root@alvin cat /var/lib/nomad-acl/management.token)
|
set -gx NOMAD_TOKEN (ssh root@alvin cat /var/lib/nomad-acl/management.token)
|
||||||
if contains -- --ui $argv
|
nomad ui -authenticate
|
||||||
nomad ui -authenticate
|
|
||||||
end
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
agx = {
|
agx = {
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,6 @@ in {
|
||||||
package = pkgs.niri; # TODO: Use input niri pkgs/overlay!
|
package = pkgs.niri; # TODO: Use input niri pkgs/overlay!
|
||||||
};
|
};
|
||||||
|
|
||||||
programs.hyprland.enable = true;
|
|
||||||
|
|
||||||
services = {
|
services = {
|
||||||
xserver = {
|
xserver = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
@ -64,15 +62,11 @@ in {
|
||||||
xdg.portal = {
|
xdg.portal = {
|
||||||
enable = true;
|
enable = true;
|
||||||
# xdgOpenUsePortal = true;
|
# xdgOpenUsePortal = true;
|
||||||
config = {
|
config.common.default = "gtk";
|
||||||
common.default = "gtk";
|
|
||||||
hyprland.default = ["hyprland" "gtk"];
|
|
||||||
};
|
|
||||||
|
|
||||||
extraPortals = with pkgs; [
|
extraPortals = with pkgs; [
|
||||||
xdg-desktop-portal-gnome
|
xdg-desktop-portal-gnome
|
||||||
xdg-desktop-portal-gtk
|
xdg-desktop-portal-gtk
|
||||||
xdg-desktop-portal-hyprland
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -17,5 +17,5 @@
|
||||||
# open-webui
|
# open-webui
|
||||||
;
|
;
|
||||||
|
|
||||||
inherit (channels.master) install-nothing marimo happy-coder;
|
inherit (channels.master) install-nothing;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,116 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
# active-path <pid>
|
|
||||||
#
|
|
||||||
# Given a PID (e.g. from active-window), output the active working directory
|
|
||||||
# or project root for that process. Handles:
|
|
||||||
# - VSCode/Electron: parses --folder-uri from the process tree
|
|
||||||
# - Terminals (kitty, etc.): finds the deepest meaningful cwd in the tree
|
|
||||||
# - Fallback: own cwd
|
|
||||||
|
|
||||||
set -o errexit
|
|
||||||
set -o nounset
|
|
||||||
set -o pipefail
|
|
||||||
|
|
||||||
PID="${1:?Usage: active-path <pid>}"
|
|
||||||
|
|
||||||
PROJECT_MARKERS=(.git Cargo.toml package.json Gemfile pyproject.toml go.mod flake.nix)
|
|
||||||
|
|
||||||
# Walk up from a path looking for a project root marker.
|
|
||||||
# Returns the marker directory, or the original path if nothing is found.
|
|
||||||
find_project_root() {
|
|
||||||
local dir="$1"
|
|
||||||
local d="$dir"
|
|
||||||
while [[ "$d" != "/" && -n "$d" ]]; do
|
|
||||||
for marker in "${PROJECT_MARKERS[@]}"; do
|
|
||||||
[[ -e "$d/$marker" ]] && { printf '%s\n' "$d"; return 0; }
|
|
||||||
done
|
|
||||||
d="$(dirname "$d")"
|
|
||||||
done
|
|
||||||
printf '%s\n' "$dir"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Decode a percent-encoded URI path component (file:/// paths are rarely
|
|
||||||
# exotic, but spaces and non-ASCII chars do occur).
|
|
||||||
url_decode() {
|
|
||||||
printf '%b' "${1//%/\\x}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Read null-terminated argv of a pid and look for --folder-uri.
|
|
||||||
# Prints the decoded path and returns 0 if found, else returns 1.
|
|
||||||
folder_uri_from_cmdline() {
|
|
||||||
local pid="$1"
|
|
||||||
local prev=""
|
|
||||||
while IFS= read -r -d $'\0' arg; do
|
|
||||||
case "$arg" in
|
|
||||||
--folder-uri=file://*)
|
|
||||||
url_decode "${arg#--folder-uri=file://}"
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
file://*)
|
|
||||||
if [[ "$prev" == "--folder-uri" ]]; then
|
|
||||||
url_decode "${arg#file://}"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
prev="$arg"
|
|
||||||
done < "/proc/$pid/cmdline" 2>/dev/null
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Collect PIDs of all processes in the subtree rooted at $1.
|
|
||||||
all_pids() {
|
|
||||||
local pid="$1"
|
|
||||||
printf '%s\n' "$pid"
|
|
||||||
for child in $(pgrep -P "$pid" 2>/dev/null); do
|
|
||||||
all_pids "$child"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
# Given a list of PIDs, return the most specific (longest) cwd that lives
|
|
||||||
# under the user's home directory. Falls back to any non-root, non-proc cwd.
|
|
||||||
best_cwd_from_pids() {
|
|
||||||
local best=""
|
|
||||||
for pid in "$@"; do
|
|
||||||
local cwd
|
|
||||||
cwd=$(readlink -f "/proc/$pid/cwd" 2>/dev/null) || continue
|
|
||||||
[[ "$cwd" == "/" || "$cwd" == "/root" || "$cwd" == "${HOME}" ]] && continue
|
|
||||||
[[ "$cwd" =~ ^/(proc|sys|run|dev) ]] && continue
|
|
||||||
|
|
||||||
# Prefer paths under home; among those prefer longer (more specific) ones
|
|
||||||
if [[ "$cwd" == "${HOME}"/* ]]; then
|
|
||||||
if [[ -z "$best" || "${#cwd}" -gt "${#best}" ]]; then
|
|
||||||
best="$cwd"
|
|
||||||
fi
|
|
||||||
elif [[ -z "$best" ]]; then
|
|
||||||
best="$cwd"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
[[ -n "$best" ]] && printf '%s\n' "$best"
|
|
||||||
}
|
|
||||||
|
|
||||||
# --- Main ---
|
|
||||||
|
|
||||||
readarray -t TREE < <(all_pids "$PID")
|
|
||||||
|
|
||||||
# 1. VSCode / Electron: search entire process tree for --folder-uri
|
|
||||||
for pid in "${TREE[@]}"; do
|
|
||||||
if path=$(folder_uri_from_cmdline "$pid" 2>/dev/null); then
|
|
||||||
find_project_root "$path"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# 2. Terminal / generic: find the best cwd among all processes in the tree
|
|
||||||
# (prefers the shell or its running child over the terminal emulator itself,
|
|
||||||
# because terminal emulators typically sit at $HOME while the shell has moved)
|
|
||||||
if cwd=$(best_cwd_from_pids "${TREE[@]}"); then
|
|
||||||
find_project_root "$cwd"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 3. Absolute fallback: own cwd, even if it's /
|
|
||||||
own=$(readlink -f "/proc/$PID/cwd" 2>/dev/null || true)
|
|
||||||
[[ -n "$own" ]] && find_project_root "$own" && exit 0
|
|
||||||
|
|
||||||
exit 1
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
{pkgs, ...}:
|
|
||||||
pkgs.writeShellApplication {
|
|
||||||
name = "active-path";
|
|
||||||
runtimeInputs = [pkgs.procps];
|
|
||||||
text = builtins.readFile ./active-path;
|
|
||||||
}
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
{pkgs, ...}:
|
|
||||||
pkgs.writeShellApplication {
|
|
||||||
name = "active-window";
|
|
||||||
runtimeInputs = [pkgs.jq];
|
|
||||||
text = ''
|
|
||||||
if [[ -n "''${NIRI_SOCKET:-}" ]]; then
|
|
||||||
FOCUSED_ID=$(niri msg --json focused-window | jq '.id')
|
|
||||||
niri msg --json windows \
|
|
||||||
| jq --argjson id "$FOCUSED_ID" \
|
|
||||||
'[.[] | select(.id == $id)] | first
|
|
||||||
| {compositor: "niri", class: .app_id, pid: .pid}'
|
|
||||||
elif [[ -n "''${HYPRLAND_INSTANCE_SIGNATURE:-}" ]]; then
|
|
||||||
hyprctl activewindow -j \
|
|
||||||
| jq '{compositor: "hyprland", class: .class, pid: .pid}'
|
|
||||||
else
|
|
||||||
printf '{"compositor":"unknown","class":null,"pid":null}\n'
|
|
||||||
fi
|
|
||||||
'';
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
{ pkgs }:
|
|
||||||
|
|
||||||
pkgs.writeShellScriptBin "mcp-npx" ''
|
|
||||||
# Wrapper that provides npx with Node.js in PATH
|
|
||||||
exec ${pkgs.nodejs_22}/bin/npx "$@"
|
|
||||||
''
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
{pkgs, ...}:
|
{pkgs, ...}:
|
||||||
pkgs.writeShellApplication {
|
pkgs.writeShellApplication {
|
||||||
name = "quick-zeal";
|
name = "quick-zeal";
|
||||||
runtimeInputs = [pkgs.harbor.active-window pkgs.jq];
|
|
||||||
text = builtins.readFile ./quick-zeal;
|
text = builtins.readFile ./quick-zeal;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,13 @@ extract_major_version() {
|
||||||
}
|
}
|
||||||
|
|
||||||
# Detects the focused window and checks if it's Kitty
|
# Detects the focused window and checks if it's Kitty
|
||||||
WINDOW=$(active-window)
|
ACTIVE_WINDOW=$(hyprctl activewindow -j | jq -r '.class')
|
||||||
ACTIVE_WINDOW=$(printf '%s' "$WINDOW" | jq -r '.class // empty')
|
|
||||||
PID=$(printf '%s' "$WINDOW" | jq -r '.pid // empty')
|
|
||||||
|
|
||||||
# Check if the focused window is a Kitty terminal and if it's in a Git repository.
|
# Check if the focused window is a Kitty terminal and if it's in a Git repository.
|
||||||
# If so, determine the project type and open Zeal with the appropriate argument
|
# If so, determine the project type and open Zeal with the appropriate argument
|
||||||
zeal_argument=""
|
zeal_argument=""
|
||||||
if [[ $ACTIVE_WINDOW == "kitty" ]]; then
|
if [[ $ACTIVE_WINDOW == "kitty" ]]; then
|
||||||
|
PID=$(hyprctl activewindow -j | jq -r '.pid')
|
||||||
CHILD_PID=$(pgrep -P "$PID" | tail -1)
|
CHILD_PID=$(pgrep -P "$PID" | tail -1)
|
||||||
|
|
||||||
SHELL_CWD=$(readlink -f "/proc/${CHILD_PID}/cwd")
|
SHELL_CWD=$(readlink -f "/proc/${CHILD_PID}/cwd")
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,25 @@
|
||||||
{pkgs, ...}:
|
{pkgs, ...}:
|
||||||
pkgs.writeNushellApplication {
|
pkgs.writeNushellApplication {
|
||||||
name = "spawn-term";
|
name = "spawn-term";
|
||||||
runtimeInputs = [pkgs.harbor.active-window];
|
runtimeInputs = with pkgs; [kdotool];
|
||||||
|
|
||||||
text = ''
|
text = ''
|
||||||
let window = (active-window | from json)
|
let compositor = $env.XDG_CURRENT_DESKTOP? | default ""
|
||||||
let window_info = {
|
|
||||||
is_kitty: ($window.class? == "kitty"),
|
let window_info = if ($compositor | str contains "niri") {
|
||||||
pid: $window.pid?
|
let focused_window = (niri msg --json focused-window | from json | get id?)
|
||||||
|
if ($focused_window | is-empty) {
|
||||||
|
{ is_kitty: false, pid: null }
|
||||||
|
} else {
|
||||||
|
let info = (niri msg --json windows | from json | where id == $focused_window | first)
|
||||||
|
{ is_kitty: ($info.app_id? == "kitty"), pid: $info.pid? }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let focused_window = (kdotool getactivewindow)
|
||||||
|
{
|
||||||
|
is_kitty: ((kdotool getwindowclassname $focused_window) == "kitty"),
|
||||||
|
pid: (kdotool getwindowpid $focused_window | into int)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if $window_info.is_kitty {
|
if $window_info.is_kitty {
|
||||||
|
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
age-encryption.org/v1
|
|
||||||
-> X25519 j9CFK6quTBAviKfxt7nk/sdsTR/5swqEfqLgo7gjmTw
|
|
||||||
BSrgJCxZY1nIOtjkzAdx60POzJ98IF5ryF1SLXKMgZk
|
|
||||||
-> piv-p256 Kmn3OQ AwqKwTZh40d7YdbU3mMJFhKz75X/NKfXdBCzpKWf75uo
|
|
||||||
FIuAwxkVMN12HoV7SN7iq1fOhqakL4Lbz5Wp/PabTO4
|
|
||||||
-> F=1e<+J-grease pk rVDW+r/ Zme4
|
|
||||||
y52QMNBhnOd9wwF4NauKUGkRCt99O7L+cqGD6od03cDf79bfsCxc0jyY7wW+fe9R
|
|
||||||
TgFDwzdeRl4LQCL/3uH4bj+j
|
|
||||||
--- zuMUxvMUyLES8iVG6tbdW/oU0bAaTDlRJwN7x+k6kTw
|
|
||||||
Ê_Ï5ýZÄB£öÛù~Úi©Ç%<25>B¸3RÕ›ËrÜËôê˜<C3AA>W<| ASƒ•=œ×³Û*IÁ~޻ئ<C398>y$¦äY´`Óp|F¨Èz?nR ÄÂâÚ4h7y·Á#‘
/r…Vy«|Ò¢B+~òBfÁƒ;±å|áÇWu¤$Y“E=ËÇIÁU'… ¬
|
|
||||||
¯
|
|
||||||
Binary file not shown.
|
|
@ -1,11 +0,0 @@
|
||||||
age-encryption.org/v1
|
|
||||||
-> X25519 pxQqMT3kixRevDw5AOugW61Stxpa54NPwdaMDf5ywBc
|
|
||||||
emM75EuTf5bL1eueeWsmFfbEZDT5+27VzBOQgCfGzlw
|
|
||||||
-> piv-p256 Kmn3OQ A92Zkli15jy0zZZiW+VYVi5apkhwXi5gZdGsfz4Nzrai
|
|
||||||
wP2maNvDOmxxA6PMcj930SJLFnExpQHYOqWVXvh2g3o
|
|
||||||
-> ,*$Gmjb-grease `Ob>AA UG\`RJP S @-2
|
|
||||||
+HbUwSV+W2xrg8coxxpvSQ+VfPGWfqr0HjtDmX3wCmCO0jpjqKqRCDEAsTj5oTKL
|
|
||||||
MUOwTg
|
|
||||||
--- Ib2BGSJRp6WTD55zNN072D+RFxRegKZhjXa48sKg3+Q
|
|
||||||
ìLŸôÐô~\FþQ$€´¬šáûÌFõ²
|
|
||||||
i¯ E±EØ®ÔMi[x¿/z ÒþŠ¢·ÿÃ×s‡ÆüÆg®l8· 6tÒìi]ø’¨0Èo6—¿%’ÆúáÜÐc/ïÃ+%Ô¹Œ~ùšHˆpPŽ‘%[úuQ;шŒ_[p_§²}ªw†È
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
age-encryption.org/v1
|
|
||||||
-> ssh-ed25519 /u/eYA jAj/U8H5mR2k4JV8FEckBb8vmpGP9LLCFCFATVZd4yA
|
|
||||||
WyXJPAyZS2Dq93pK2GuVYNbBIxNyvEVJuVWrpZS89Zs
|
|
||||||
-> @W-grease _
|
|
||||||
Gd35VA
|
|
||||||
--- 6blY/MMnEQunu/tWdJv/oGaqf1i6Pv+xdrqLV0EZNes
|
|
||||||
«<EFBFBD>ˆëÇægŒúóþ/½çM0•2äPçÿ!°9XU–ÂxÖKï¦(ònÊ“ëçã×…/¯j„[`fÃ<66>.Nf¯f1ã ÃVíŒë€á!·rÆ}h`êûåÑeƒàsÀ/&8¾£þÅÛ¥«ûSÙ2ËÏ!o£úõ¾NjÞÕpäL?ïX]Ív<C38D>8C
|
|
||||||
Binary file not shown.
|
|
@ -1,8 +0,0 @@
|
||||||
age-encryption.org/v1
|
|
||||||
-> ssh-ed25519 Sih9FA DiICdXQXdFzjmLaO3TbZmurGr7rRlOyeyT4B6Q2hbgw
|
|
||||||
AMltu9LuCxoev0zm5Ihoa0aSYVvs7SAD04NIF4gyMxw
|
|
||||||
-> K0!Lf-grease AnUy
|
|
||||||
q4vQ1RJdAeh03A
|
|
||||||
--- g4sTWmo/FkvfmPBcfalOQE3FUapLvqYKLEfqDUvt2Yw
|
|
||||||
*ñUäA†±=¾w1üƒ·&º*d©UÙÎ<C399>s>a4¦s«˜hi<68>g<EFBFBD>€}K Š»}ÒïàÆ8dÄþp‰¸œˆÔVë†bB¼•†TxéÊ<C3A9>ÈŒ0sˆüdÃ÷Q¿UR+
|
|
||||||
nF?æÈÚ ýƒÏP'i¥Xœ²)¥UsÜq¶²EŒ~Êèi¥ûÀˆ=âµ|<7C>P.¥ùÁâ2
|
|
||||||
Loading…
Add table
Reference in a new issue