ci + lint

This commit is contained in:
Harivansh Rathi 2026-03-30 00:28:59 -04:00
parent d088a98954
commit 66d9b25682
39 changed files with 395 additions and 225 deletions

63
.github/workflows/quality.yml vendored Normal file
View file

@ -0,0 +1,63 @@
name: quality
on:
pull_request:
branches: [main]
push:
branches: [main]
permissions:
contents: read
jobs:
changes:
runs-on: ubuntu-latest
outputs:
quality: ${{ steps.filter.outputs.quality }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: filter
with:
filters: |
quality:
- "**/*.nix"
- "flake.lock"
- "flake.nix"
- "ci/**"
- "config/**"
- "scripts/**"
- ".github/workflows/**"
flake-check:
name: Flake Check
runs-on: ubuntu-latest
needs: changes
if: ${{ needs.changes.outputs.quality == 'true' }}
steps:
- uses: actions/checkout@v4
- uses: DeterminateSystems/nix-installer-action@main
- uses: DeterminateSystems/magic-nix-cache-action@main
- name: Prepare local flake input shims
run: |
set -euo pipefail
# The repo currently depends on a local path flake input for agentcomputer-cli.
sudo mkdir -p /Users/rathi/Documents/GitHub/companion/agentcomputer/apps
sudo ln -sfn "$GITHUB_WORKSPACE/ci/agentcomputer-cli-stub" /Users/rathi/Documents/GitHub/companion/agentcomputer/apps/cli
- run: nix flake check
nix-format:
name: Nix Format Check
runs-on: ubuntu-latest
needs: changes
if: ${{ needs.changes.outputs.quality == 'true' }}
steps:
- uses: actions/checkout@v4
- uses: DeterminateSystems/nix-installer-action@main
- uses: DeterminateSystems/magic-nix-cache-action@main
- name: Prepare local flake input shims
run: |
set -euo pipefail
sudo mkdir -p /Users/rathi/Documents/GitHub/companion/agentcomputer/apps
sudo ln -sfn "$GITHUB_WORKSPACE/ci/agentcomputer-cli-stub" /Users/rathi/Documents/GitHub/companion/agentcomputer/apps/cli
- run: nix fmt -- --ci

View file

@ -0,0 +1,30 @@
{
description = "CI stub for the local agentcomputer-cli flake input";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
outputs =
{ nixpkgs, ... }:
let
systems = [
"aarch64-darwin"
"x86_64-darwin"
"aarch64-linux"
"x86_64-linux"
];
forAllSystems = nixpkgs.lib.genAttrs systems;
in
{
packages = forAllSystems (
system:
let
pkgs = import nixpkgs { inherit system; };
in
{
default = pkgs.writeShellScriptBin "aicomputer" ''
echo "agentcomputer-cli CI stub"
'';
}
);
};
}

View file

@ -1,4 +1,5 @@
{...}: {
{ ... }:
{
programs.bat = {
enable = true;

View file

@ -2,10 +2,11 @@
inputs,
pkgs,
...
}: let
claudePackage =
inputs.claudeCode.packages.${pkgs.stdenv.hostPlatform.system}.default;
in {
}:
let
claudePackage = inputs.claudeCode.packages.${pkgs.stdenv.hostPlatform.system}.default;
in
{
# Keep the managed Claude binary on the same path the live machine was using
# so the Nix package cleanly replaces the prior manual install.
home.file.".local/bin/claude".source = "${claudePackage}/bin/claude";

View file

@ -1,4 +1,5 @@
{...}: {
{ ... }:
{
home.file.".codex/AGENTS.md".source = ../config/codex/AGENTS.md;
home.file.".codex/config.toml".source = ../config/codex/config.toml;
}

View file

@ -2,9 +2,11 @@
config,
pkgs,
...
}: let
}:
let
defaultProfile = "default";
in {
in
{
home.packages = with pkgs; [
docker-buildx
docker-client

View file

@ -1,4 +1,5 @@
{...}: {
{ ... }:
{
imports = [
./bat.nix
./eza.nix

View file

@ -1,4 +1,5 @@
{...}: {
{ ... }:
{
imports = [
./common.nix
./colima.nix

View file

@ -1,4 +1,5 @@
{...}: {
{ ... }:
{
programs.eza = {
enable = true;
enableZshIntegration = true;

View file

@ -1,6 +1,8 @@
{config, ...}: let
theme = import ../lib/theme.nix {inherit config;};
in {
{ config, ... }:
let
theme = import ../lib/theme.nix { inherit config; };
in
{
home.sessionVariables = {
FZF_DEFAULT_OPTS_FILE = theme.paths.fzfCurrentFile;
};

View file

@ -1,7 +1,8 @@
{lib, ...}: {
{ lib, ... }:
{
xdg.configFile."gcloud/active_config".text = "default\n";
xdg.configFile."gcloud/configurations/config_default".text = lib.generators.toINI {} {
xdg.configFile."gcloud/configurations/config_default".text = lib.generators.toINI { } {
core = {
account = "rathiharivansh@gmail.com";
project = "hari-gc";

View file

@ -1,4 +1,5 @@
{...}: {
{ ... }:
{
programs.gh = {
enable = true;
gitCredentialHelper.enable = true;

View file

@ -3,8 +3,9 @@
lib,
pkgs,
...
}: let
theme = import ../lib/theme.nix {inherit config;};
}:
let
theme = import ../lib/theme.nix { inherit config; };
ghosttyConfig = ''
theme = "cozybox-current"
font-family = Berkeley Mono
@ -52,13 +53,11 @@
focus-follows-mouse = true
link-url = true
'';
in {
in
{
programs.ghostty = {
enable = true;
package =
if pkgs.stdenv.isDarwin
then pkgs.ghostty-bin
else pkgs.ghostty;
package = if pkgs.stdenv.isDarwin then pkgs.ghostty-bin else pkgs.ghostty;
installBatSyntax = true;
};

View file

@ -1,4 +1,5 @@
{...}: {
{ ... }:
{
programs.git = {
enable = true;
lfs.enable = true;

View file

@ -1,4 +1,5 @@
{...}: {
{ ... }:
{
programs.k9s = {
enable = true;

View file

@ -2,11 +2,12 @@
config,
lib,
...
}: {
}:
{
# Karabiner-Elements destroys file-level symlinks (unlink + rewrite), but
# directory-level symlinks survive. Point ~/.config/karabiner at the repo
# directory so changes are tracked in git and Karabiner can write freely.
home.activation.karabinerConfig = lib.hm.dag.entryAfter ["writeBoundary"] ''
home.activation.karabinerConfig = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
karabiner_link="${config.home.homeDirectory}/.config/karabiner"
karabiner_src="/Users/rathi/Documents/GitHub/nix/config/karabiner"

View file

@ -2,11 +2,11 @@
lib,
pkgs,
...
}: {
}:
{
xdg.configFile."lazygit/config.yml".source = ../config/lazygit/config.yml;
home.file = lib.mkIf pkgs.stdenv.isDarwin {
"Library/Application Support/lazygit/config.yml".source =
../config/lazygit/config.yml;
"Library/Application Support/lazygit/config.yml".source = ../config/lazygit/config.yml;
};
}

View file

@ -1,8 +1,9 @@
{lib, ...}: {
{ lib, ... }:
{
# Transitional cleanup for files previously owned by ~/dots. Keeping this
# separate from steady-state modules makes it obvious what can be deleted
# once every managed path has been fully handed over to Home Manager.
home.activation.removeLegacyZshLinks = lib.hm.dag.entryBefore ["checkLinkTargets"] ''
home.activation.removeLegacyZshLinks = lib.hm.dag.entryBefore [ "checkLinkTargets" ] ''
for path in "$HOME/.zshenv" "$HOME/.zshrc"; do
if [ -L "$path" ]; then
target="$(readlink "$path")"
@ -15,7 +16,7 @@
done
'';
home.activation.removeLegacyTmuxLink = lib.hm.dag.entryBefore ["checkLinkTargets"] ''
home.activation.removeLegacyTmuxLink = lib.hm.dag.entryBefore [ "checkLinkTargets" ] ''
path="$HOME/.config/tmux/tmux.conf"
if [ -L "$path" ]; then
target="$(readlink "$path")"

View file

@ -1,4 +1,5 @@
{...}: {
{ ... }:
{
programs.mise = {
enable = true;
globalConfig = {

View file

@ -1,4 +1,5 @@
{...}: {
{ ... }:
{
imports = [
./common.nix
];

View file

@ -3,22 +3,23 @@
lib,
pkgs,
...
}: let
}:
let
nvimConfig = lib.cleanSourceWith {
src = ../config/nvim;
filter = path: type:
builtins.baseNameOf path != ".git"
&& builtins.baseNameOf path != "lazy-lock.json";
filter =
path: type: builtins.baseNameOf path != ".git" && builtins.baseNameOf path != "lazy-lock.json";
};
lazyLockSeed = ../config/nvim/lazy-lock.json;
lazyLockPath = "${config.xdg.stateHome}/nvim/lazy-lock.json";
python = pkgs.writeShellScriptBin "python" ''
exec ${pkgs.python3}/bin/python3 "$@"
'';
in {
in
{
# Keep rust-analyzer in the user profile so it shadows rustup's proxy in
# /run/current-system/sw/bin when Neovim resolves LSP executables.
home.packages = [pkgs.rust-analyzer];
home.packages = [ pkgs.rust-analyzer ];
programs.neovim = {
enable = true;
@ -59,7 +60,7 @@ in {
recursive = true;
};
home.activation.seedNvimLazyLock = lib.hm.dag.entryAfter ["writeBoundary"] ''
home.activation.seedNvimLazyLock = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
state_dir="${config.xdg.stateHome}/nvim"
lockfile="${lazyLockPath}"

View file

@ -1,5 +1,6 @@
{lib, ...}: {
home.activation.importRectanglePreferences = lib.hm.dag.entryAfter ["writeBoundary"] ''
{ lib, ... }:
{
home.activation.importRectanglePreferences = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
/usr/bin/defaults import com.knollsoft.Rectangle ${../config/rectangle/Rectangle.plist}
'';
}

View file

@ -3,12 +3,14 @@
lib,
pkgs,
...
}: let
customScripts = import ../scripts {inherit config lib pkgs;};
in {
}:
let
customScripts = import ../scripts { inherit config lib pkgs; };
in
{
home.packages = builtins.attrValues customScripts.packages;
home.activation.initializeThemeState = lib.hm.dag.entryAfter ["writeBoundary"] ''
home.activation.initializeThemeState = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
mkdir -p "${customScripts.theme.paths.stateDir}" "${customScripts.theme.paths.fzfDir}" "${customScripts.theme.paths.ghosttyDir}" "${customScripts.theme.paths.tmuxDir}"
if [[ -f "${customScripts.theme.paths.stateFile}" ]]; then

View file

@ -3,7 +3,8 @@
lib,
pkgs,
...
}: let
}:
let
globalSkills = [
{
name = "rams";
@ -42,8 +43,9 @@
needs_sync=1
fi
'') globalSkills;
in {
home.activation.ensureGlobalSkills = lib.hm.dag.entryAfter ["writeBoundary"] ''
in
{
home.activation.ensureGlobalSkills = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
state_dir="${config.xdg.stateHome}/skills"
stamp_file="$state_dir/global-skills-manifest.sha256"
desired_hash=${lib.escapeShellArg manifestHash}
@ -58,14 +60,16 @@ in {
${missingChecks}
if [ "$needs_sync" -eq 1 ]; then
export PATH="${lib.makeBinPath [
export PATH="${
lib.makeBinPath [
pkgs.nodejs_22
pkgs.git
pkgs.coreutils
pkgs.findutils
pkgs.gnugrep
pkgs.gnused
]}:$PATH"
]
}:$PATH"
${installCommands}

View file

@ -1,4 +1,5 @@
{...}: {
{ ... }:
{
programs.ssh = {
enable = true;
enableDefaultConfig = false;

View file

@ -3,9 +3,11 @@
lib,
pkgs,
...
}: let
theme = import ../lib/theme.nix {inherit config;};
in {
}:
let
theme = import ../lib/theme.nix { inherit config; };
in
{
programs.tmux = {
enable = true;
plugins = with pkgs.tmuxPlugins; [

View file

@ -3,15 +3,15 @@
lib,
pkgs,
...
}: {
home.file.".oh-my-zsh/custom/themes/agnoster.zsh-theme".source =
../config/agnoster.zsh-theme;
}:
{
home.file.".oh-my-zsh/custom/themes/agnoster.zsh-theme".source = ../config/agnoster.zsh-theme;
home.activation.ensureOhMyZshCache = lib.hm.dag.entryAfter ["writeBoundary"] ''
home.activation.ensureOhMyZshCache = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
mkdir -p "${config.xdg.cacheHome}/oh-my-zsh"
'';
home.packages = [pkgs.oh-my-zsh];
home.packages = [ pkgs.oh-my-zsh ];
programs.zsh = {
enable = true;
@ -22,8 +22,7 @@
autosuggestion.enable = true;
syntaxHighlighting.enable = true;
shellAliases =
{
shellAliases = {
co = "codex --dangerously-bypass-approvals-and-sandbox";
ca = "cursor-agent";
cc = "claude";
@ -43,8 +42,7 @@
tailscale = "/Applications/Tailscale.app/Contents/MacOS/Tailscale";
};
envExtra =
''
envExtra = ''
if [[ -f "$HOME/.cargo/env" ]]; then
. "$HOME/.cargo/env"
fi
@ -88,9 +86,7 @@
export BUN_INSTALL="$HOME/.bun"
export PNPM_HOME="${
if pkgs.stdenv.isDarwin
then "$HOME/Library/pnpm"
else "${config.xdg.dataHome}/pnpm"
if pkgs.stdenv.isDarwin then "$HOME/Library/pnpm" else "${config.xdg.dataHome}/pnpm"
}"
bindkey -v
typeset -U path PATH

View file

@ -4,7 +4,8 @@
username,
hostname,
...
}: {
}:
{
imports = [
../../modules/base.nix
../../modules/macos.nix

View file

@ -5,9 +5,11 @@
username,
self,
...
}: let
packageSets = import ../../lib/package-sets.nix {inherit inputs lib pkgs;};
in {
}:
let
packageSets = import ../../lib/package-sets.nix { inherit inputs lib pkgs; };
in
{
imports = [
./hardware-configuration.nix
./disk-config.nix
@ -25,7 +27,11 @@ in {
networking = {
hostName = "netty";
useDHCP = true;
firewall.allowedTCPPorts = [22 80 443];
firewall.allowedTCPPorts = [
22
80
443
];
};
services.qemuGuest.enable = true;
@ -44,7 +50,7 @@ in {
users.users.${username} = {
isNormalUser = true;
extraGroups = ["wheel"];
extraGroups = [ "wheel" ];
shell = pkgs.zsh;
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM6tzq33IQcurWoQ7vhXOTLjv8YkdTGb7NoNsul3Sbfu rathi@mac"

View file

@ -4,9 +4,11 @@
pkgs,
username,
...
}: let
packageSets = import ../../lib/package-sets.nix {inherit inputs lib pkgs;};
in {
}:
let
packageSets = import ../../lib/package-sets.nix { inherit inputs lib pkgs; };
in
{
imports = [
../../home/netty.nix
];

View file

@ -4,7 +4,8 @@
lib,
modulesPath,
...
}: {
}:
{
imports = [
(modulesPath + "/profiles/qemu-guest.nix")
];
@ -15,9 +16,9 @@
"ahci"
"sd_mod"
];
boot.initrd.kernelModules = [];
boot.kernelModules = [];
boot.extraModulePackages = [];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
virtualisation.hypervGuest.enable = false;

View file

@ -2,15 +2,12 @@
inputs,
lib,
pkgs,
}: let
gwsPackage =
inputs.googleworkspace-cli.packages.${pkgs.stdenv.hostPlatform.system}.default;
claudePackage =
inputs.claudeCode.packages.${pkgs.stdenv.hostPlatform.system}.default;
agentcomputerPackage =
inputs.agentcomputer-cli.packages.${pkgs.stdenv.hostPlatform.system}.default;
openspecPackage =
inputs.openspec.packages.${pkgs.stdenv.hostPlatform.system}.default;
}:
let
gwsPackage = inputs.googleworkspace-cli.packages.${pkgs.stdenv.hostPlatform.system}.default;
claudePackage = inputs.claudeCode.packages.${pkgs.stdenv.hostPlatform.system}.default;
agentcomputerPackage = inputs.agentcomputer-cli.packages.${pkgs.stdenv.hostPlatform.system}.default;
openspecPackage = inputs.openspec.packages.${pkgs.stdenv.hostPlatform.system}.default;
memex = pkgs.stdenvNoCC.mkDerivation rec {
pname = "memex";
@ -76,12 +73,16 @@
meta = {
description = "CLI for Git worktree management";
homepage = "https://worktrunk.dev";
license = with lib.licenses; [asl20 mit];
license = with lib.licenses; [
asl20
mit
];
mainProgram = "wt";
platforms = lib.platforms.darwin;
};
};
in {
in
{
core = with pkgs; [
bitwarden-cli
curl

View file

@ -1,4 +1,5 @@
{config, ...}: let
{ config, ... }:
let
defaultMode = "dark";
sharedPalette = {
red = "#ea6962";
@ -93,14 +94,17 @@
};
};
renderGhostty = mode: let
renderGhostty =
mode:
let
theme = themes.${mode};
paletteLines =
builtins.concatStringsSep "\n"
(builtins.genList
(index: "palette = ${toString index}=${builtins.elemAt theme.palette index}")
(builtins.length theme.palette));
in ''
paletteLines = builtins.concatStringsSep "\n" (
builtins.genList (index: "palette = ${toString index}=${builtins.elemAt theme.palette index}") (
builtins.length theme.palette
)
);
in
''
background = ${theme.background}
foreground = ${theme.foreground}
cursor-color = ${theme.cursorColor}
@ -110,9 +114,12 @@
${paletteLines}
'';
renderTmux = mode: let
renderTmux =
mode:
let
theme = themes.${mode};
in ''
in
''
set-option -g @cozybox-mode '${mode}'
set-option -g @cozybox-accent '${theme.purple}'
set-option -g status-style bg=${theme.background},fg=${theme.text}
@ -123,13 +130,24 @@
set-option -g pane-active-border-style fg=${theme.border}
'';
renderFzf = mode: let
renderFzf =
mode:
let
theme = themes.${mode};
in ''
in
''
--color=fg:${theme.text},bg:${theme.background},hl:${theme.blue}
--color=fg+:${theme.text},bg+:${theme.surface},hl+:${theme.blue}
--color=info:${theme.green},prompt:${theme.blue},pointer:${theme.text},marker:${theme.green},spinner:${theme.text}
'';
in {
inherit defaultMode paths renderFzf renderGhostty renderTmux themes;
in
{
inherit
defaultMode
paths
renderFzf
renderGhostty
renderTmux
themes
;
}

View file

@ -4,9 +4,11 @@
pkgs,
username,
...
}: let
packageSets = import ../lib/package-sets.nix {inherit inputs lib pkgs;};
in {
}:
let
packageSets = import ../lib/package-sets.nix { inherit inputs lib pkgs; };
in
{
nix.enable = true;
nix.settings = {
@ -22,8 +24,7 @@ in {
use-xdg-base-directories = true;
};
nix.gc =
{
nix.gc = {
automatic = true;
options = "--delete-older-than 14d";
}
@ -45,7 +46,7 @@ in {
nixpkgs.config.allowUnfree = true;
programs.zsh.enable = true;
environment.shells = [pkgs.zsh];
environment.shells = [ pkgs.zsh ];
environment.systemPackages = packageSets.core;

View file

@ -1,4 +1,5 @@
{...}: {
{ ... }:
{
homebrew = {
enable = true;

View file

@ -1,4 +1,5 @@
{...}: {
{ ... }:
{
security.pam.services.sudo_local.touchIdAuth = true;
# Karabiner-Elements is managed via Homebrew cask because nix-darwin's

View file

@ -20,9 +20,7 @@ let
hostname = host.hostname;
};
mkHomeManagerModule =
host:
{
mkHomeManagerModule = host: {
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.extraSpecialArgs = mkSpecialArgs host;

View file

@ -3,9 +3,11 @@
lib,
pkgs,
...
}: let
packageSets = import ../lib/package-sets.nix {inherit inputs lib pkgs;};
in {
}:
let
packageSets = import ../lib/package-sets.nix { inherit inputs lib pkgs; };
in
{
environment.systemPackages = packageSets.extras;
fonts.packages = packageSets.fonts;
}

View file

@ -2,52 +2,67 @@
config,
lib,
pkgs,
}: let
theme = import ../lib/theme.nix {inherit config;};
}:
let
theme = import ../lib/theme.nix { inherit config; };
tmuxConfigs = {
dark = pkgs.writeText "tmux-theme-dark.conf" (theme.renderTmux "dark");
light = pkgs.writeText "tmux-theme-light.conf" (theme.renderTmux "light");
};
mkScript = {
mkScript =
{
file,
name,
runtimeInputs ? [],
replacements ? {},
runtimeInputs ? [ ],
replacements ? { },
}:
pkgs.writeShellApplication {
inherit name runtimeInputs;
text =
lib.replaceStrings
(builtins.attrNames replacements)
(builtins.attrValues replacements)
(builtins.readFile file);
text = lib.replaceStrings (builtins.attrNames replacements) (builtins.attrValues replacements) (
builtins.readFile file
);
};
packages = {
ga = mkScript {
name = "ga";
file = ./ga.sh;
runtimeInputs = with pkgs; [git];
runtimeInputs = with pkgs; [ git ];
};
ghpr = mkScript {
name = "ghpr";
file = ./ghpr.sh;
runtimeInputs = with pkgs; [gh git gnugrep gnused coreutils];
runtimeInputs = with pkgs; [
gh
git
gnugrep
gnused
coreutils
];
};
gpr = mkScript {
name = "gpr";
file = ./gpr.sh;
runtimeInputs = with pkgs; [gh fzf gnugrep coreutils];
runtimeInputs = with pkgs; [
gh
fzf
gnugrep
coreutils
];
};
iosrun = mkScript {
name = "iosrun";
file = ./iosrun.sh;
runtimeInputs = with pkgs; [findutils gnugrep coreutils];
runtimeInputs = with pkgs; [
findutils
gnugrep
coreutils
];
};
mdview = mkScript {
@ -58,13 +73,18 @@
ni = mkScript {
name = "ni";
file = ./ni.sh;
runtimeInputs = with pkgs; [nix];
runtimeInputs = with pkgs; [ nix ];
};
theme = mkScript {
name = "theme";
file = ./theme.sh;
runtimeInputs = with pkgs; [coreutils findutils neovim tmux];
runtimeInputs = with pkgs; [
coreutils
findutils
neovim
tmux
];
replacements = {
"@DEFAULT_MODE@" = theme.defaultMode;
"@STATE_DIR@" = theme.paths.stateDir;
@ -90,6 +110,7 @@
file = ./wtc.sh;
};
};
in {
in
{
inherit packages theme tmuxConfigs;
}