mirror of
https://github.com/harivansh-afk/nix.git
synced 2026-04-15 08:03:44 +00:00
commit
d97aee6808
28 changed files with 844 additions and 553 deletions
26
README.md
26
README.md
|
|
@ -49,14 +49,20 @@ just fmt
|
|||
## layout
|
||||
|
||||
```
|
||||
hosts/darwin/ - macOS host entrypoint
|
||||
hosts/netty/ - NixOS VPS entrypoint (disko + hardware)
|
||||
modules/ - shared system modules + devshells
|
||||
modules/hosts/ - flake-parts host output definitions
|
||||
modules/nixpkgs.nix - shared flake context (hosts, args, pkgs helpers)
|
||||
home/ - Home Manager modules
|
||||
lib/hosts.nix - host metadata used by the flake
|
||||
lib/ - shared package sets and theme system
|
||||
config/ - repo-owned config files (nvim, tmux, etc.)
|
||||
scripts/ - secret management and utility scripts
|
||||
hosts/darwin/ - macOS host entrypoint
|
||||
hosts/netty/ - NixOS VPS entrypoint (disko + hardware + services)
|
||||
modules/ - shared system modules + devshells
|
||||
modules/hosts/ - flake-parts host output definitions
|
||||
modules/nixpkgs.nix - shared flake context (hosts, specialArgs, pkgs)
|
||||
home/default.nix - unified home entry (conditional on hostConfig)
|
||||
home/common.nix - modules shared across all hosts
|
||||
home/xdg.nix - XDG compliance (env vars, config files)
|
||||
home/security.nix - SSH/GPG permission enforcement
|
||||
home/ - per-tool home-manager modules
|
||||
lib/hosts.nix - host metadata + feature flags
|
||||
lib/theme.nix - centralized color system (gruvbox)
|
||||
lib/package-sets.nix - shared + host-gated package lists
|
||||
config/ - repo-owned config files (nvim, tmux, etc.)
|
||||
scripts/ - secret management and utility scripts
|
||||
nix-maxxing.txt - architecture and operations guide
|
||||
```
|
||||
|
|
|
|||
|
|
@ -1,30 +0,0 @@
|
|||
{
|
||||
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"
|
||||
'';
|
||||
}
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
@ -1,183 +0,0 @@
|
|||
# vim:ft=zsh ts=2 sw=2 sts=2
|
||||
#
|
||||
# agnoster's Theme - https://gist.github.com/3712874
|
||||
# A Powerline-inspired theme for ZSH
|
||||
|
||||
### Segment drawing
|
||||
CURRENT_BG='NONE'
|
||||
|
||||
case ${SOLARIZED_THEME:-dark} in
|
||||
light)
|
||||
CURRENT_FG=${CURRENT_FG:-'white'}
|
||||
CURRENT_DEFAULT_FG=${CURRENT_DEFAULT_FG:-'white'}
|
||||
;;
|
||||
*)
|
||||
CURRENT_FG=${CURRENT_FG:-'black'}
|
||||
CURRENT_DEFAULT_FG=${CURRENT_DEFAULT_FG:-'default'}
|
||||
;;
|
||||
esac
|
||||
|
||||
### Theme Configuration Initialization
|
||||
: ${AGNOSTER_DIR_FG:=${CURRENT_FG}}
|
||||
: ${AGNOSTER_DIR_BG:=blue}
|
||||
|
||||
: ${AGNOSTER_CONTEXT_FG:=${CURRENT_DEFAULT_FG}}
|
||||
: ${AGNOSTER_CONTEXT_BG:=black}
|
||||
|
||||
: ${AGNOSTER_GIT_CLEAN_FG:=${CURRENT_FG}}
|
||||
: ${AGNOSTER_GIT_CLEAN_BG:=green}
|
||||
: ${AGNOSTER_GIT_DIRTY_FG:=black}
|
||||
: ${AGNOSTER_GIT_DIRTY_BG:=yellow}
|
||||
|
||||
: ${AGNOSTER_BZR_CLEAN_FG:=${CURRENT_FG}}
|
||||
: ${AGNOSTER_BZR_CLEAN_BG:=green}
|
||||
: ${AGNOSTER_BZR_DIRTY_FG:=black}
|
||||
: ${AGNOSTER_BZR_DIRTY_BG:=yellow}
|
||||
|
||||
: ${AGNOSTER_HG_NEWFILE_FG:=white}
|
||||
: ${AGNOSTER_HG_NEWFILE_BG:=red}
|
||||
: ${AGNOSTER_HG_CHANGED_FG:=black}
|
||||
: ${AGNOSTER_HG_CHANGED_BG:=yellow}
|
||||
: ${AGNOSTER_HG_CLEAN_FG:=${CURRENT_FG}}
|
||||
: ${AGNOSTER_HG_CLEAN_BG:=green}
|
||||
|
||||
: ${AGNOSTER_VENV_FG:=black}
|
||||
: ${AGNOSTER_VENV_BG:=blue}
|
||||
|
||||
: ${AGNOSTER_AWS_PROD_FG:=yellow}
|
||||
: ${AGNOSTER_AWS_PROD_BG:=red}
|
||||
: ${AGNOSTER_AWS_FG:=black}
|
||||
: ${AGNOSTER_AWS_BG:=green}
|
||||
|
||||
: ${AGNOSTER_STATUS_RETVAL_FG:=red}
|
||||
: ${AGNOSTER_STATUS_ROOT_FG:=yellow}
|
||||
: ${AGNOSTER_STATUS_JOB_FG:=cyan}
|
||||
: ${AGNOSTER_STATUS_FG:=${CURRENT_DEFAULT_FG}}
|
||||
: ${AGNOSTER_STATUS_BG:=black}
|
||||
|
||||
: ${AGNOSTER_STATUS_RETVAL_NUMERIC:=false}
|
||||
: ${AGNOSTER_GIT_INLINE:=false}
|
||||
: ${AGNOSTER_GIT_BRANCH_STATUS:=true}
|
||||
|
||||
() {
|
||||
local LC_ALL="" LC_CTYPE="en_US.UTF-8"
|
||||
SEGMENT_SEPARATOR=$'\ue0b0'
|
||||
}
|
||||
|
||||
prompt_segment() {
|
||||
local bg fg
|
||||
[[ -n $1 ]] && bg="%K{$1}" || bg="%k"
|
||||
[[ -n $2 ]] && fg="%F{$2}" || fg="%f"
|
||||
if [[ $CURRENT_BG != 'NONE' && $1 != $CURRENT_BG ]]; then
|
||||
echo -n " %{$bg%F{$CURRENT_BG}%}$SEGMENT_SEPARATOR%{$fg%} "
|
||||
else
|
||||
echo -n "%{$bg%}%{$fg%} "
|
||||
fi
|
||||
CURRENT_BG=$1
|
||||
[[ -n $3 ]] && echo -n $3
|
||||
}
|
||||
|
||||
prompt_end() {
|
||||
if [[ -n $CURRENT_BG ]]; then
|
||||
echo -n " %{%k%F{$CURRENT_BG}%}$SEGMENT_SEPARATOR"
|
||||
else
|
||||
echo -n "%{%k%}"
|
||||
fi
|
||||
echo -n "%{%f%}"
|
||||
CURRENT_BG=''
|
||||
}
|
||||
|
||||
git_toplevel() {
|
||||
local repo_root=$(git rev-parse --show-toplevel)
|
||||
if [[ $repo_root = '' ]]; then
|
||||
repo_root=$(git rev-parse --git-dir)
|
||||
[[ $repo_root = '.' ]] && repo_root=$PWD
|
||||
fi
|
||||
echo -n $repo_root
|
||||
}
|
||||
|
||||
### Prompt components
|
||||
|
||||
prompt_context() {
|
||||
if [[ -n "$SSH_CLIENT" ]]; then
|
||||
prompt_segment "$AGNOSTER_CONTEXT_BG" "$AGNOSTER_CONTEXT_FG" "%(!.%{%F{$AGNOSTER_STATUS_ROOT_FG}%}.)%n@%m"
|
||||
fi
|
||||
}
|
||||
|
||||
prompt_git_relative() {
|
||||
local repo_root=$(git_toplevel)
|
||||
local path_in_repo=$(pwd | sed "s/^$(echo "$repo_root" | sed 's:/:\\/:g;s/\$/\\$/g')//;s:^/::;s:/$::;")
|
||||
[[ $path_in_repo != '' ]] && prompt_segment "$AGNOSTER_DIR_BG" "$AGNOSTER_DIR_FG" "$path_in_repo"
|
||||
}
|
||||
|
||||
prompt_git() {
|
||||
(( $+commands[git] )) || return
|
||||
[[ "$(command git config --get oh-my-zsh.hide-status 2>/dev/null)" = 1 ]] && return
|
||||
|
||||
local PL_BRANCH_CHAR
|
||||
() { local LC_ALL="" LC_CTYPE="en_US.UTF-8"; PL_BRANCH_CHAR=$'\ue0a0' }
|
||||
|
||||
if [[ "$(command git rev-parse --is-inside-work-tree 2>/dev/null)" = "true" ]]; then
|
||||
local dirty ref
|
||||
dirty=$(parse_git_dirty)
|
||||
ref=$(command git symbolic-ref HEAD 2>/dev/null) || \
|
||||
ref="➦ $(command git rev-parse --short HEAD 2>/dev/null)"
|
||||
|
||||
if [[ -n $dirty ]]; then
|
||||
prompt_segment "$AGNOSTER_GIT_DIRTY_BG" "$AGNOSTER_GIT_DIRTY_FG"
|
||||
else
|
||||
prompt_segment "$AGNOSTER_GIT_CLEAN_BG" "$AGNOSTER_GIT_CLEAN_FG"
|
||||
fi
|
||||
|
||||
echo -n "${${ref:gs/%/%%}/refs\/heads\//$PL_BRANCH_CHAR }"
|
||||
fi
|
||||
}
|
||||
|
||||
prompt_dir() {
|
||||
if [[ $AGNOSTER_GIT_INLINE == 'true' ]] && $(git rev-parse --is-inside-work-tree >/dev/null 2>&1); then
|
||||
prompt_segment "$AGNOSTER_DIR_BG" "$AGNOSTER_DIR_FG" "$(git_toplevel | sed "s:^$HOME:~:")"
|
||||
else
|
||||
prompt_segment "$AGNOSTER_DIR_BG" "$AGNOSTER_DIR_FG" '%~'
|
||||
fi
|
||||
}
|
||||
|
||||
prompt_virtualenv() {
|
||||
return
|
||||
}
|
||||
|
||||
prompt_status() {
|
||||
local -a symbols
|
||||
[[ $AGNOSTER_STATUS_RETVAL_NUMERIC == 'true' && $RETVAL -ne 0 ]] && symbols+="%{%F{$AGNOSTER_STATUS_RETVAL_FG}%}$RETVAL"
|
||||
[[ $AGNOSTER_STATUS_RETVAL_NUMERIC != 'true' && $RETVAL -ne 0 ]] && symbols+="%{%F{$AGNOSTER_STATUS_RETVAL_FG}%}✘"
|
||||
[[ $UID -eq 0 ]] && symbols+="%{%F{$AGNOSTER_STATUS_ROOT_FG}%}⚡"
|
||||
[[ $(jobs -l | wc -l) -gt 0 ]] && symbols+="%{%F{$AGNOSTER_STATUS_JOB_FG}%}⚙"
|
||||
[[ -n "$symbols" ]] && prompt_segment "$AGNOSTER_STATUS_BG" "$AGNOSTER_STATUS_FG" "$symbols"
|
||||
}
|
||||
|
||||
prompt_aws() {
|
||||
[[ -z "$AWS_PROFILE" || "$SHOW_AWS_PROMPT" = false ]] && return
|
||||
case "$AWS_PROFILE" in
|
||||
*-prod|*production*) prompt_segment "$AGNOSTER_AWS_PROD_BG" "$AGNOSTER_AWS_PROD_FG" "AWS: ${AWS_PROFILE:gs/%/%%}" ;;
|
||||
*) prompt_segment "$AGNOSTER_AWS_BG" "$AGNOSTER_AWS_FG" "AWS: ${AWS_PROFILE:gs/%/%%}" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
prompt_terraform() {
|
||||
local terraform_info=$(tf_prompt_info)
|
||||
[[ -z "$terraform_info" ]] && return
|
||||
prompt_segment magenta yellow "TF: $terraform_info"
|
||||
}
|
||||
|
||||
build_prompt() {
|
||||
RETVAL=$?
|
||||
prompt_status
|
||||
prompt_virtualenv
|
||||
prompt_aws
|
||||
prompt_terraform
|
||||
prompt_context
|
||||
prompt_dir
|
||||
prompt_git
|
||||
prompt_end
|
||||
}
|
||||
|
||||
PROMPT='%{%f%b%k%}$(build_prompt) '
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
# Secrets
|
||||
|
||||
## Current Model
|
||||
|
||||
This repo does not store secret values in Nix.
|
||||
|
||||
Instead:
|
||||
|
||||
- Bitwarden vault items are the current source of truth for imported machine
|
||||
secrets
|
||||
- Nix/Home Manager owns the integration points
|
||||
- generated runtime files live outside the repo under `~/.config/secrets`
|
||||
|
||||
That boundary matters because the Nix store is not the right place for real
|
||||
secret values.
|
||||
|
||||
## What Is Already Wired
|
||||
|
||||
- [home/zsh.nix](/Users/rathi/Documents/GitHub/nix/home/zsh.nix) sources
|
||||
`~/.config/secrets/shell.zsh` when present
|
||||
- [scripts/render-bw-shell-secrets.sh](/Users/rathi/Documents/GitHub/nix/scripts/render-bw-shell-secrets.sh)
|
||||
renders that file from Bitwarden vault items
|
||||
- [scripts/restore-bw-files.sh](/Users/rathi/Documents/GitHub/nix/scripts/restore-bw-files.sh)
|
||||
restores file-based credentials and SSH material from Bitwarden vault items
|
||||
- [justfile](/Users/rathi/Documents/GitHub/nix/justfile) exposes this as
|
||||
`just secrets-sync` and `just secrets-restore-files`
|
||||
|
||||
## Daily Shell Flow
|
||||
|
||||
```bash
|
||||
export BW_SESSION="$(bw unlock --raw)"
|
||||
just secrets-sync
|
||||
exec zsh -l
|
||||
```
|
||||
|
||||
That flow currently materializes:
|
||||
|
||||
- `OPENAI_API_KEY`
|
||||
- `GREPTILE_API_KEY`
|
||||
- `CONTEXT7_API_KEY`
|
||||
- `MISTRAL_API_KEY`
|
||||
|
||||
## Machine Secret Coverage
|
||||
|
||||
The Bitwarden vault now holds:
|
||||
|
||||
- API keys and CLI tokens
|
||||
- AWS default credentials
|
||||
- GCloud ADC
|
||||
- Stripe CLI config
|
||||
- Codex auth
|
||||
- Vercel auth
|
||||
- SSH configs
|
||||
- SSH private keys
|
||||
|
||||
The vault is currently the backup/recovery source of truth for those values.
|
||||
|
||||
## Sandbox Strategy
|
||||
|
||||
For a fresh sandbox or new machine, the clean bootstrap is:
|
||||
|
||||
1. `darwin-rebuild switch` or Home Manager activation
|
||||
2. authenticate `bw`
|
||||
3. `just secrets-sync`
|
||||
4. `just secrets-restore-files`
|
||||
|
||||
That gives you a usable dev shell quickly without committing any secret values
|
||||
into the repo.
|
||||
|
||||
## Future Upgrade
|
||||
|
||||
If you want fully non-interactive sandbox secret injection, the next step is to
|
||||
move the env-style secrets from normal Bitwarden vault items into Bitwarden
|
||||
Secrets Manager (`bws`) and keep file-based credentials and SSH material in the
|
||||
normal vault.
|
||||
|
||||
That would give you:
|
||||
|
||||
- `bws` for machine/app secrets
|
||||
- `bw` for human-managed vault items, SSH material, and recovery data
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
description = "Rathi's macOS nix-darwin + NixOS + Home Manager config";
|
||||
description = "Hari's nix config";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||
|
|
@ -25,11 +25,6 @@
|
|||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
agentcomputer-cli = {
|
||||
url = "path:/Users/rathi/Documents/GitHub/companion/agentcomputer/apps/cli";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
openspec = {
|
||||
url = "github:Fission-AI/OpenSpec";
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
{ ... }:
|
||||
{ theme, ... }:
|
||||
{
|
||||
programs.bat = {
|
||||
enable = true;
|
||||
|
||||
config = {
|
||||
theme = "gruvbox-dark";
|
||||
theme = theme.batTheme theme.defaultMode;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,17 +7,16 @@ 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";
|
||||
home.file.".claude/CLAUDE.md".source = ../config/claude/CLAUDE.md;
|
||||
home.file.".claude/commands" = {
|
||||
|
||||
xdg.configFile."claude/CLAUDE.md".source = ../config/claude/CLAUDE.md;
|
||||
xdg.configFile."claude/commands" = {
|
||||
source = ../config/claude/commands;
|
||||
recursive = true;
|
||||
};
|
||||
home.file.".claude/settings.json".source = ../config/claude/settings.json;
|
||||
home.file.".claude/settings.local.json".source = ../config/claude/settings.local.json;
|
||||
home.file.".claude/statusline.sh" = {
|
||||
xdg.configFile."claude/settings.json".source = ../config/claude/settings.json;
|
||||
xdg.configFile."claude/settings.local.json".source = ../config/claude/settings.local.json;
|
||||
xdg.configFile."claude/statusline.sh" = {
|
||||
source = ../config/claude/statusline.sh;
|
||||
executable = true;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
{ ... }:
|
||||
{ config, ... }:
|
||||
{
|
||||
_module.args.theme = import ../lib/theme.nix { inherit config; };
|
||||
|
||||
imports = [
|
||||
./bat.nix
|
||||
./eza.nix
|
||||
./claude.nix
|
||||
./xdg.nix
|
||||
./security.nix
|
||||
./codex.nix
|
||||
./fzf.nix
|
||||
./gcloud.nix
|
||||
|
|
@ -15,6 +19,7 @@
|
|||
./mise.nix
|
||||
./migration.nix
|
||||
./nvim.nix
|
||||
./prompt.nix
|
||||
./skills.nix
|
||||
./scripts.nix
|
||||
./ssh.nix
|
||||
|
|
@ -25,4 +30,9 @@
|
|||
home.stateVersion = "24.11";
|
||||
programs.home-manager.enable = true;
|
||||
xdg.enable = true;
|
||||
|
||||
programs.zoxide = {
|
||||
enable = true;
|
||||
enableZshIntegration = true;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,18 @@
|
|||
{ ... }:
|
||||
{
|
||||
lib,
|
||||
hostConfig,
|
||||
...
|
||||
}:
|
||||
{
|
||||
imports = [
|
||||
./common.nix
|
||||
]
|
||||
++ lib.optionals hostConfig.isDarwin [
|
||||
./colima.nix
|
||||
./rectangle.nix
|
||||
./karabiner.nix
|
||||
]
|
||||
++ lib.optionals hostConfig.isLinux [
|
||||
./netty-worktree.nix
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,4 @@
|
|||
{ config, ... }:
|
||||
let
|
||||
theme = import ../lib/theme.nix { inherit config; };
|
||||
in
|
||||
{ theme, ... }:
|
||||
{
|
||||
home.sessionVariables = {
|
||||
FZF_DEFAULT_OPTS_FILE = theme.paths.fzfCurrentFile;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
hostConfig,
|
||||
theme,
|
||||
...
|
||||
}:
|
||||
let
|
||||
theme = import ../lib/theme.nix { inherit config; };
|
||||
ghosttyConfig = ''
|
||||
theme = "cozybox-current"
|
||||
font-family = Berkeley Mono
|
||||
|
|
@ -40,7 +40,7 @@ let
|
|||
keybind = vim/i=deactivate_key_table
|
||||
keybind = vim/catch_all=ignore
|
||||
mouse-hide-while-typing = true
|
||||
${lib.optionalString pkgs.stdenv.isDarwin ''
|
||||
${lib.optionalString hostConfig.isDarwin ''
|
||||
macos-titlebar-style = hidden
|
||||
macos-option-as-alt = true
|
||||
''}
|
||||
|
|
@ -57,7 +57,7 @@ in
|
|||
{
|
||||
programs.ghostty = {
|
||||
enable = true;
|
||||
package = if pkgs.stdenv.isDarwin then pkgs.ghostty-bin else pkgs.ghostty;
|
||||
package = if hostConfig.isDarwin then pkgs.ghostty-bin else pkgs.ghostty;
|
||||
installBatSyntax = true;
|
||||
};
|
||||
|
||||
|
|
@ -69,7 +69,7 @@ in
|
|||
xdg.configFile."ghostty/themes/cozybox-dark".text = theme.renderGhostty "dark";
|
||||
xdg.configFile."ghostty/themes/cozybox-light".text = theme.renderGhostty "light";
|
||||
|
||||
home.file = lib.mkIf pkgs.stdenv.isDarwin {
|
||||
home.file = lib.mkIf hostConfig.isDarwin {
|
||||
"Library/Application Support/com.mitchellh.ghostty/config.ghostty" = {
|
||||
text = ghosttyConfig;
|
||||
force = true;
|
||||
|
|
|
|||
31
home/git.nix
31
home/git.nix
|
|
@ -1,10 +1,37 @@
|
|||
{ ... }:
|
||||
{ theme, ... }:
|
||||
{
|
||||
programs.git = {
|
||||
enable = true;
|
||||
lfs.enable = true;
|
||||
signing.format = "openpgp";
|
||||
|
||||
ignores = [
|
||||
"*.swp"
|
||||
"*.swo"
|
||||
"*~"
|
||||
".DS_Store"
|
||||
"Thumbs.db"
|
||||
".env"
|
||||
".env.local"
|
||||
".env.*.local"
|
||||
".vscode/"
|
||||
".idea/"
|
||||
".claude/"
|
||||
"CLAUDE.md"
|
||||
"node_modules/"
|
||||
"__pycache__/"
|
||||
"*.pyc"
|
||||
"venv/"
|
||||
".venv/"
|
||||
"build/"
|
||||
"dist/"
|
||||
"out/"
|
||||
"target/"
|
||||
"result"
|
||||
"result-*"
|
||||
".direnv/"
|
||||
];
|
||||
|
||||
settings = {
|
||||
user = {
|
||||
name = "Harivansh Rathi";
|
||||
|
|
@ -40,7 +67,7 @@
|
|||
};
|
||||
|
||||
delta = {
|
||||
"syntax-theme" = "gruvbox-dark";
|
||||
"syntax-theme" = theme.deltaTheme theme.defaultMode;
|
||||
"hunk-header-style" = "omit";
|
||||
"minus-style" = ''syntax "#3c1f1e"'';
|
||||
"minus-emph-style" = ''syntax "#72261d"'';
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
lib,
|
||||
pkgs,
|
||||
hostConfig,
|
||||
...
|
||||
}:
|
||||
{
|
||||
xdg.configFile."lazygit/config.yml".source = ../config/lazygit/config.yml;
|
||||
|
||||
home.file = lib.mkIf pkgs.stdenv.isDarwin {
|
||||
home.file = lib.mkIf hostConfig.isDarwin {
|
||||
"Library/Application Support/lazygit/config.yml".source = ../config/lazygit/config.yml;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
86
home/prompt.nix
Normal file
86
home/prompt.nix
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
{
|
||||
lib,
|
||||
pkgs,
|
||||
theme,
|
||||
...
|
||||
}:
|
||||
{
|
||||
home.packages = [ pkgs.pure-prompt ];
|
||||
|
||||
programs.zsh.initContent = lib.mkMerge [
|
||||
(lib.mkOrder 800 ''
|
||||
fpath+=("${pkgs.pure-prompt}/share/zsh/site-functions")
|
||||
autoload -Uz promptinit && promptinit
|
||||
|
||||
export PURE_PROMPT_SYMBOL=$'\xe2\x9d\xaf'
|
||||
export PURE_PROMPT_VICMD_SYMBOL=$'\xe2\x9d\xae'
|
||||
export PURE_GIT_DIRTY=""
|
||||
export PURE_GIT_UP_ARROW="^"
|
||||
export PURE_GIT_DOWN_ARROW="v"
|
||||
export PURE_GIT_STASH_SYMBOL="="
|
||||
export PURE_CMD_MAX_EXEC_TIME=5
|
||||
export PURE_GIT_PULL=0
|
||||
export PURE_GIT_UNTRACKED_DIRTY=1
|
||||
zstyle ':prompt:pure:git:stash' show yes
|
||||
|
||||
${theme.renderPurePrompt "dark"}
|
||||
|
||||
typeset -g prompt_newline=' '
|
||||
prompt pure
|
||||
|
||||
prompt_pure_preprompt_render() {
|
||||
setopt localoptions noshwordsplit
|
||||
unset prompt_pure_async_render_requested
|
||||
|
||||
typeset -g prompt_pure_git_branch_color=$prompt_pure_colors[git:branch]
|
||||
[[ -n ''${prompt_pure_git_last_dirty_check_timestamp+x} ]] && prompt_pure_git_branch_color=$prompt_pure_colors[git:branch:cached]
|
||||
|
||||
# Branch, arrows, and prompt symbol turn yellow when dirty
|
||||
if [[ -n $prompt_pure_git_dirty ]]; then
|
||||
prompt_pure_git_branch_color=$prompt_pure_colors[git:dirty]
|
||||
prompt_pure_colors[git:arrow]=$prompt_pure_colors[git:dirty]
|
||||
prompt_pure_colors[prompt:success]=$prompt_pure_colors[git:dirty]
|
||||
else
|
||||
prompt_pure_colors[git:arrow]=$_codex_pure_default_arrow
|
||||
prompt_pure_colors[prompt:success]=$_codex_pure_default_success
|
||||
fi
|
||||
|
||||
psvar[12]=; ((''${(M)#jobstates:#suspended:*} != 0)) && psvar[12]=''${PURE_SUSPENDED_JOBS_SYMBOL:-✦}
|
||||
psvar[13]=; [[ -n $prompt_pure_state[username] ]] && psvar[13]=1
|
||||
psvar[14]=''${prompt_pure_vcs_info[branch]}
|
||||
psvar[15]=
|
||||
psvar[16]=''${prompt_pure_vcs_info[action]}
|
||||
psvar[17]=''${prompt_pure_git_arrows}
|
||||
psvar[18]=; [[ -n $prompt_pure_git_stash ]] && psvar[18]=1
|
||||
psvar[19]=''${prompt_pure_cmd_exec_time}
|
||||
|
||||
local expanded_prompt
|
||||
expanded_prompt="''${(S%%)PROMPT}"
|
||||
|
||||
if [[ $1 != precmd && $prompt_pure_last_prompt != $expanded_prompt ]]; then
|
||||
prompt_pure_reset_prompt
|
||||
fi
|
||||
|
||||
typeset -g prompt_pure_last_prompt=$expanded_prompt
|
||||
}
|
||||
|
||||
typeset -g _codex_pure_default_arrow=$prompt_pure_colors[git:arrow]
|
||||
typeset -g _codex_pure_default_success=$prompt_pure_colors[prompt:success]
|
||||
|
||||
_codex_apply_prompt_theme() {
|
||||
local mode="$(_codex_read_theme_mode)"
|
||||
[[ "$mode" == "''${_CODEX_LAST_PROMPT_THEME:-}" ]] && return
|
||||
|
||||
if [[ "$mode" == light ]]; then
|
||||
${theme.renderPurePrompt "light"}
|
||||
else
|
||||
${theme.renderPurePrompt "dark"}
|
||||
fi
|
||||
|
||||
typeset -g _codex_pure_default_arrow=$prompt_pure_colors[git:arrow]
|
||||
typeset -g _codex_pure_default_success=$prompt_pure_colors[prompt:success]
|
||||
typeset -g _CODEX_LAST_PROMPT_THEME="$mode"
|
||||
}
|
||||
'')
|
||||
];
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
hostConfig,
|
||||
...
|
||||
}:
|
||||
let
|
||||
|
|
@ -10,7 +11,7 @@ in
|
|||
{
|
||||
home.packages =
|
||||
builtins.attrValues customScripts.commonPackages
|
||||
++ lib.optionals pkgs.stdenv.isDarwin (builtins.attrValues customScripts.darwinPackages);
|
||||
++ lib.optionals hostConfig.isDarwin (builtins.attrValues customScripts.darwinPackages);
|
||||
|
||||
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}"
|
||||
|
|
|
|||
26
home/security.nix
Normal file
26
home/security.nix
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
{
|
||||
home.activation.secretPermissions = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
|
||||
if [ -d "${config.home.homeDirectory}/.ssh" ]; then
|
||||
$DRY_RUN_CMD chmod 700 "${config.home.homeDirectory}/.ssh"
|
||||
for f in "${config.home.homeDirectory}/.ssh/"*; do
|
||||
[ -f "$f" ] || continue
|
||||
[ -L "$f" ] && continue
|
||||
case "$f" in
|
||||
*.pub|*/known_hosts|*/known_hosts.old)
|
||||
$DRY_RUN_CMD chmod 644 "$f" ;;
|
||||
*)
|
||||
$DRY_RUN_CMD chmod 600 "$f" ;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
if [ -d "${config.home.homeDirectory}/.gnupg" ]; then
|
||||
$DRY_RUN_CMD find "${config.home.homeDirectory}/.gnupg" -type d -exec chmod 700 {} +
|
||||
$DRY_RUN_CMD find "${config.home.homeDirectory}/.gnupg" -type f -exec chmod 600 {} +
|
||||
fi
|
||||
'';
|
||||
}
|
||||
|
|
@ -1,12 +1,9 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
theme,
|
||||
...
|
||||
}:
|
||||
let
|
||||
theme = import ../lib/theme.nix { inherit config; };
|
||||
in
|
||||
{
|
||||
programs.tmux = {
|
||||
enable = true;
|
||||
|
|
|
|||
93
home/xdg.nix
Normal file
93
home/xdg.nix
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
hostConfig,
|
||||
...
|
||||
}:
|
||||
let
|
||||
f = hostConfig.features;
|
||||
in
|
||||
{
|
||||
home.sessionVariables = lib.mkMerge [
|
||||
{
|
||||
LESSHISTFILE = "-";
|
||||
WGETRC = "${config.xdg.configHome}/wgetrc";
|
||||
}
|
||||
(lib.mkIf (f.rust or false) {
|
||||
CARGO_HOME = "${config.xdg.dataHome}/cargo";
|
||||
RUSTUP_HOME = "${config.xdg.dataHome}/rustup";
|
||||
})
|
||||
(lib.mkIf (f.go or false) {
|
||||
GOPATH = "${config.xdg.dataHome}/go";
|
||||
GOMODCACHE = "${config.xdg.cacheHome}/go/mod";
|
||||
})
|
||||
(lib.mkIf (f.node or false) {
|
||||
NPM_CONFIG_USERCONFIG = "${config.xdg.configHome}/npm/npmrc";
|
||||
NODE_REPL_HISTORY = "${config.xdg.stateHome}/node_repl_history";
|
||||
PNPM_HOME = "${config.xdg.dataHome}/pnpm";
|
||||
PNPM_NO_UPDATE_NOTIFIER = "true";
|
||||
})
|
||||
(lib.mkIf (f.python or false) {
|
||||
PYTHONSTARTUP = "${config.xdg.configHome}/python/pythonrc";
|
||||
PYTHON_HISTORY = "${config.xdg.stateHome}/python_history";
|
||||
PYTHONPYCACHEPREFIX = "${config.xdg.cacheHome}/python";
|
||||
PYTHONUSERBASE = "${config.xdg.dataHome}/python";
|
||||
})
|
||||
(lib.mkIf (f.docker or false) {
|
||||
DOCKER_CONFIG = "${config.xdg.configHome}/docker";
|
||||
})
|
||||
(lib.mkIf (f.aws or false) {
|
||||
AWS_SHARED_CREDENTIALS_FILE = "${config.xdg.configHome}/aws/credentials";
|
||||
AWS_CONFIG_FILE = "${config.xdg.configHome}/aws/config";
|
||||
})
|
||||
(lib.mkIf (f.claude or false) {
|
||||
CLAUDE_CONFIG_DIR = "${config.xdg.configHome}/claude";
|
||||
})
|
||||
{
|
||||
PSQL_HISTORY = "${config.xdg.stateHome}/psql_history";
|
||||
SQLITE_HISTORY = "${config.xdg.stateHome}/sqlite_history";
|
||||
}
|
||||
];
|
||||
|
||||
home.sessionPath = lib.mkMerge [
|
||||
[ "${config.home.homeDirectory}/.local/bin" ]
|
||||
(lib.mkIf (f.rust or false) [ "${config.xdg.dataHome}/cargo/bin" ])
|
||||
(lib.mkIf (f.go or false) [ "${config.xdg.dataHome}/go/bin" ])
|
||||
(lib.mkIf (f.node or false) [ "${config.xdg.dataHome}/pnpm" ])
|
||||
];
|
||||
|
||||
xdg.configFile."npm/npmrc" = lib.mkIf (f.node or false) {
|
||||
text = ''
|
||||
prefix=''${XDG_DATA_HOME}/npm
|
||||
cache=''${XDG_CACHE_HOME}/npm
|
||||
init-module=''${XDG_CONFIG_HOME}/npm/config/npm-init.js
|
||||
'';
|
||||
};
|
||||
|
||||
xdg.configFile."python/pythonrc" = lib.mkIf (f.python or false) {
|
||||
text = ''
|
||||
import atexit
|
||||
import os
|
||||
import readline
|
||||
|
||||
history = os.path.join(os.environ.get('XDG_STATE_HOME', os.path.expanduser('~/.local/state')), 'python_history')
|
||||
|
||||
try:
|
||||
readline.read_history_file(history)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
def write_history():
|
||||
try:
|
||||
readline.write_history_file(history)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
atexit.register(write_history)
|
||||
'';
|
||||
};
|
||||
|
||||
xdg.configFile."wgetrc".text = ''
|
||||
hsts_file = ${config.xdg.stateHome}/wget-hsts
|
||||
'';
|
||||
}
|
||||
176
home/zsh.nix
176
home/zsh.nix
|
|
@ -2,17 +2,11 @@
|
|||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
hostConfig,
|
||||
theme,
|
||||
...
|
||||
}:
|
||||
{
|
||||
home.file.".oh-my-zsh/custom/themes/agnoster.zsh-theme".source = ../config/agnoster.zsh-theme;
|
||||
|
||||
home.activation.ensureOhMyZshCache = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
|
||||
mkdir -p "${config.xdg.cacheHome}/oh-my-zsh"
|
||||
'';
|
||||
|
||||
home.packages = [ pkgs.oh-my-zsh ];
|
||||
|
||||
programs.zsh = {
|
||||
enable = true;
|
||||
dotDir = config.home.homeDirectory;
|
||||
|
|
@ -22,6 +16,17 @@
|
|||
autosuggestion.enable = true;
|
||||
syntaxHighlighting.enable = true;
|
||||
|
||||
history = {
|
||||
size = 50000;
|
||||
save = 50000;
|
||||
ignoreDups = true;
|
||||
ignoreAllDups = true;
|
||||
ignoreSpace = true;
|
||||
extended = true;
|
||||
append = true;
|
||||
path = "${config.xdg.stateHome}/zsh_history";
|
||||
};
|
||||
|
||||
shellAliases = {
|
||||
co = "codex --dangerously-bypass-approvals-and-sandbox";
|
||||
ca = "cursor-agent";
|
||||
|
|
@ -38,7 +43,7 @@
|
|||
lg = "lazygit";
|
||||
nim = "nvim .";
|
||||
}
|
||||
// lib.optionalAttrs pkgs.stdenv.isDarwin {
|
||||
// lib.optionalAttrs hostConfig.isDarwin {
|
||||
tailscale = "/Applications/Tailscale.app/Contents/MacOS/Tailscale";
|
||||
};
|
||||
|
||||
|
|
@ -48,9 +53,7 @@
|
|||
fi
|
||||
export NODE_NO_WARNINGS=1
|
||||
''
|
||||
+ lib.optionalString pkgs.stdenv.isDarwin ''
|
||||
# Ghostty shell integration expects a resource directory; the Nix app
|
||||
# bundle lives in the store instead of /Applications.
|
||||
+ lib.optionalString hostConfig.isDarwin ''
|
||||
export GHOSTTY_RESOURCES_DIR="${pkgs.ghostty-bin}/Applications/Ghostty.app/Contents/Resources/ghostty"
|
||||
''
|
||||
+ ''
|
||||
|
|
@ -59,18 +62,9 @@
|
|||
|
||||
initContent = lib.mkMerge [
|
||||
(lib.mkOrder 550 ''
|
||||
# OpenSpec shell completions configuration
|
||||
fpath=("$HOME/.oh-my-zsh/custom/completions" $fpath)
|
||||
'')
|
||||
|
||||
(lib.mkOrder 800 ''
|
||||
export ZSH="${pkgs.oh-my-zsh}/share/oh-my-zsh"
|
||||
export ZSH_CUSTOM="$HOME/.oh-my-zsh/custom"
|
||||
export ZSH_CACHE_DIR="${config.xdg.cacheHome}/oh-my-zsh"
|
||||
ZSH_THEME="agnoster"
|
||||
plugins=(git)
|
||||
ZSH_DISABLE_COMPFIX=true
|
||||
source "$ZSH/oh-my-zsh.sh"
|
||||
autoload -U compinit && compinit -d "${config.xdg.stateHome}/zcompdump" -u
|
||||
zmodload zsh/complist
|
||||
zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-za-z}'
|
||||
'')
|
||||
|
||||
(lib.mkOrder 1000 ''
|
||||
|
|
@ -80,29 +74,21 @@
|
|||
source ~/.secrets
|
||||
fi
|
||||
|
||||
eval "$(zoxide init zsh)"
|
||||
|
||||
[ -s "$HOME/.bun/_bun" ] && source "$HOME/.bun/_bun"
|
||||
|
||||
export BUN_INSTALL="$HOME/.bun"
|
||||
export PNPM_HOME="${
|
||||
if pkgs.stdenv.isDarwin then "$HOME/Library/pnpm" else "${config.xdg.dataHome}/pnpm"
|
||||
}"
|
||||
bindkey -v
|
||||
typeset -U path PATH
|
||||
path=(
|
||||
"$HOME/.amp/bin"
|
||||
"$PNPM_HOME"
|
||||
"$BUN_INSTALL/bin"
|
||||
"$HOME/.antigravity/antigravity/bin"
|
||||
"$HOME/.opencode/bin"
|
||||
"${pkgs.postgresql_17}/bin"
|
||||
"$HOME/.local/bin"
|
||||
"$HOME/.nix-profile/bin"
|
||||
"/etc/profiles/per-user/${config.home.username}/bin"
|
||||
"/run/current-system/sw/bin"
|
||||
"/nix/var/nix/profiles/default/bin"
|
||||
${lib.optionalString pkgs.stdenv.isDarwin ''
|
||||
${lib.optionalString hostConfig.isDarwin ''
|
||||
"/opt/homebrew/bin"
|
||||
"/opt/homebrew/sbin"
|
||||
''}
|
||||
|
|
@ -119,78 +105,19 @@
|
|||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
printf 'dark'
|
||||
}
|
||||
|
||||
_codex_apply_highlight_styles() {
|
||||
local mode="$(_codex_read_theme_mode)"
|
||||
if [[ "$mode" == "''${_CODEX_LAST_HIGHLIGHT_THEME:-}" ]]; then
|
||||
return
|
||||
fi
|
||||
[[ "$mode" == "''${_CODEX_LAST_HIGHLIGHT_THEME:-}" ]] && return
|
||||
|
||||
typeset -gA ZSH_HIGHLIGHT_STYLES
|
||||
|
||||
if [[ "$mode" == light ]]; then
|
||||
ZSH_HIGHLIGHT_STYLES[arg0]='fg=#427b58'
|
||||
ZSH_HIGHLIGHT_STYLES[autodirectory]='fg=#427b58,underline'
|
||||
ZSH_HIGHLIGHT_STYLES[back-dollar-quoted-argument]='fg=#076678'
|
||||
ZSH_HIGHLIGHT_STYLES[back-double-quoted-argument]='fg=#076678'
|
||||
ZSH_HIGHLIGHT_STYLES[back-quoted-argument-delimiter]='fg=#8f3f71'
|
||||
ZSH_HIGHLIGHT_STYLES[bracket-error]='fg=#ea6962,bold'
|
||||
ZSH_HIGHLIGHT_STYLES[bracket-level-1]='fg=#076678,bold'
|
||||
ZSH_HIGHLIGHT_STYLES[bracket-level-2]='fg=#427b58,bold'
|
||||
ZSH_HIGHLIGHT_STYLES[bracket-level-3]='fg=#8f3f71,bold'
|
||||
ZSH_HIGHLIGHT_STYLES[bracket-level-4]='fg=#b57614,bold'
|
||||
ZSH_HIGHLIGHT_STYLES[bracket-level-5]='fg=#076678,bold'
|
||||
ZSH_HIGHLIGHT_STYLES[comment]='fg=#928374'
|
||||
ZSH_HIGHLIGHT_STYLES[command-substitution-delimiter]='fg=#8f3f71'
|
||||
ZSH_HIGHLIGHT_STYLES[dollar-double-quoted-argument]='fg=#076678'
|
||||
ZSH_HIGHLIGHT_STYLES[dollar-quoted-argument]='fg=#b57614'
|
||||
ZSH_HIGHLIGHT_STYLES[double-quoted-argument]='fg=#b57614'
|
||||
ZSH_HIGHLIGHT_STYLES[global-alias]='fg=#076678'
|
||||
ZSH_HIGHLIGHT_STYLES[globbing]='fg=#076678'
|
||||
ZSH_HIGHLIGHT_STYLES[history-expansion]='fg=#076678'
|
||||
ZSH_HIGHLIGHT_STYLES[path]='fg=#3c3836,underline'
|
||||
ZSH_HIGHLIGHT_STYLES[precommand]='fg=#427b58,underline'
|
||||
ZSH_HIGHLIGHT_STYLES[process-substitution-delimiter]='fg=#8f3f71'
|
||||
ZSH_HIGHLIGHT_STYLES[rc-quote]='fg=#076678'
|
||||
ZSH_HIGHLIGHT_STYLES[redirection]='fg=#b57614'
|
||||
ZSH_HIGHLIGHT_STYLES[reserved-word]='fg=#b57614'
|
||||
ZSH_HIGHLIGHT_STYLES[single-quoted-argument]='fg=#b57614'
|
||||
ZSH_HIGHLIGHT_STYLES[suffix-alias]='fg=#427b58,underline'
|
||||
ZSH_HIGHLIGHT_STYLES[unknown-token]='fg=#ea6962,bold'
|
||||
${theme.renderZshHighlights "light"}
|
||||
else
|
||||
ZSH_HIGHLIGHT_STYLES[arg0]='fg=#8ec97c'
|
||||
ZSH_HIGHLIGHT_STYLES[autodirectory]='fg=#8ec97c,underline'
|
||||
ZSH_HIGHLIGHT_STYLES[back-dollar-quoted-argument]='fg=#8ec07c'
|
||||
ZSH_HIGHLIGHT_STYLES[back-double-quoted-argument]='fg=#8ec07c'
|
||||
ZSH_HIGHLIGHT_STYLES[back-quoted-argument-delimiter]='fg=#d3869b'
|
||||
ZSH_HIGHLIGHT_STYLES[bracket-error]='fg=#ea6962,bold'
|
||||
ZSH_HIGHLIGHT_STYLES[bracket-level-1]='fg=#5b84de,bold'
|
||||
ZSH_HIGHLIGHT_STYLES[bracket-level-2]='fg=#8ec97c,bold'
|
||||
ZSH_HIGHLIGHT_STYLES[bracket-level-3]='fg=#d3869b,bold'
|
||||
ZSH_HIGHLIGHT_STYLES[bracket-level-4]='fg=#d8a657,bold'
|
||||
ZSH_HIGHLIGHT_STYLES[bracket-level-5]='fg=#8ec07c,bold'
|
||||
ZSH_HIGHLIGHT_STYLES[comment]='fg=#7c6f64'
|
||||
ZSH_HIGHLIGHT_STYLES[command-substitution-delimiter]='fg=#d3869b'
|
||||
ZSH_HIGHLIGHT_STYLES[dollar-double-quoted-argument]='fg=#8ec07c'
|
||||
ZSH_HIGHLIGHT_STYLES[dollar-quoted-argument]='fg=#d8a657'
|
||||
ZSH_HIGHLIGHT_STYLES[double-quoted-argument]='fg=#d8a657'
|
||||
ZSH_HIGHLIGHT_STYLES[global-alias]='fg=#8ec07c'
|
||||
ZSH_HIGHLIGHT_STYLES[globbing]='fg=#5b84de'
|
||||
ZSH_HIGHLIGHT_STYLES[history-expansion]='fg=#5b84de'
|
||||
ZSH_HIGHLIGHT_STYLES[path]='fg=#d4be98,underline'
|
||||
ZSH_HIGHLIGHT_STYLES[precommand]='fg=#8ec97c,underline'
|
||||
ZSH_HIGHLIGHT_STYLES[process-substitution-delimiter]='fg=#d3869b'
|
||||
ZSH_HIGHLIGHT_STYLES[rc-quote]='fg=#8ec07c'
|
||||
ZSH_HIGHLIGHT_STYLES[redirection]='fg=#d8a657'
|
||||
ZSH_HIGHLIGHT_STYLES[reserved-word]='fg=#d8a657'
|
||||
ZSH_HIGHLIGHT_STYLES[single-quoted-argument]='fg=#d8a657'
|
||||
ZSH_HIGHLIGHT_STYLES[suffix-alias]='fg=#8ec97c,underline'
|
||||
ZSH_HIGHLIGHT_STYLES[unknown-token]='fg=#ea6962,bold'
|
||||
${theme.renderZshHighlights "dark"}
|
||||
fi
|
||||
|
||||
typeset -g _CODEX_LAST_HIGHLIGHT_THEME="$mode"
|
||||
}
|
||||
|
||||
|
|
@ -199,7 +126,6 @@
|
|||
git() {
|
||||
command git "$@"
|
||||
local exit_code=$?
|
||||
|
||||
case "$1" in
|
||||
add|stage|reset|checkout)
|
||||
if command -v critic >/dev/null 2>&1; then
|
||||
|
|
@ -207,64 +133,32 @@
|
|||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
return $exit_code
|
||||
}
|
||||
|
||||
function _codex_set_cursor {
|
||||
if [[ "$1" == block ]]; then
|
||||
printf '\e[2 q'
|
||||
else
|
||||
printf '\e[6 q'
|
||||
fi
|
||||
}
|
||||
|
||||
function zle-keymap-select {
|
||||
if [[ "$KEYMAP" == vicmd ]]; then
|
||||
_codex_set_cursor block
|
||||
else
|
||||
_codex_set_cursor beam
|
||||
fi
|
||||
}
|
||||
zle -N zle-keymap-select
|
||||
|
||||
function zle-line-init {
|
||||
_codex_set_cursor beam
|
||||
}
|
||||
zle -N zle-line-init
|
||||
|
||||
function zle-line-finish {
|
||||
_codex_set_cursor beam
|
||||
}
|
||||
zle -N zle-line-finish
|
||||
autoload -Uz add-zle-hook-widget
|
||||
_codex_cursor() { printf '\e[%s q' "''${1:-6}"; }
|
||||
_codex_cursor_select() { [[ "$KEYMAP" == vicmd ]] && _codex_cursor 2 || _codex_cursor 6; }
|
||||
_codex_cursor_beam() { _codex_cursor 6; }
|
||||
add-zle-hook-widget zle-keymap-select _codex_cursor_select
|
||||
add-zle-hook-widget zle-line-init _codex_cursor_beam
|
||||
add-zle-hook-widget zle-line-finish _codex_cursor_beam
|
||||
|
||||
precmd() {
|
||||
_codex_apply_prompt_theme
|
||||
_codex_apply_highlight_styles
|
||||
_codex_set_cursor beam
|
||||
}
|
||||
|
||||
preexec() {
|
||||
_codex_set_cursor beam
|
||||
_codex_cursor_beam
|
||||
}
|
||||
preexec() { _codex_cursor_beam; }
|
||||
|
||||
_codex_apply_prompt_theme
|
||||
_codex_apply_highlight_styles
|
||||
|
||||
${lib.optionalString pkgs.stdenv.isDarwin ''
|
||||
if command -v wt >/dev/null 2>&1; then
|
||||
eval "$(command wt config shell init zsh)"
|
||||
|
||||
# `wt` changes directories by sourcing directives into the current shell,
|
||||
# so wrappers around it must stay shell functions instead of scripts.
|
||||
wtc() {
|
||||
wt switch --create --base @ "$@"
|
||||
}
|
||||
fi
|
||||
''}
|
||||
'')
|
||||
|
||||
(lib.mkAfter ''
|
||||
bindkey '^k' forward-car
|
||||
bindkey '^j' backward-car
|
||||
bindkey '^k' forward-char
|
||||
bindkey '^j' backward-char
|
||||
'')
|
||||
];
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
inputs,
|
||||
lib,
|
||||
modulesPath,
|
||||
pkgs,
|
||||
username,
|
||||
self,
|
||||
|
|
@ -14,6 +15,8 @@ in
|
|||
./hardware-configuration.nix
|
||||
./disk-config.nix
|
||||
../../modules/base.nix
|
||||
(modulesPath + "/profiles/minimal.nix")
|
||||
(modulesPath + "/profiles/headless.nix")
|
||||
];
|
||||
|
||||
boot.loader.grub = {
|
||||
|
|
@ -21,12 +24,31 @@ in
|
|||
efiSupport = true;
|
||||
efiInstallAsRemovable = true;
|
||||
device = "nodev";
|
||||
configurationLimit = 5;
|
||||
configurationLimit = 3;
|
||||
};
|
||||
|
||||
documentation.enable = false;
|
||||
fonts.fontconfig.enable = false;
|
||||
|
||||
networking = {
|
||||
hostName = "netty";
|
||||
useDHCP = true;
|
||||
useDHCP = false;
|
||||
interfaces.ens3 = {
|
||||
ipv4.addresses = [
|
||||
{
|
||||
address = "152.53.195.59";
|
||||
prefixLength = 22;
|
||||
}
|
||||
];
|
||||
};
|
||||
defaultGateway = {
|
||||
address = "152.53.192.1";
|
||||
interface = "ens3";
|
||||
};
|
||||
nameservers = [
|
||||
"1.1.1.1"
|
||||
"8.8.8.8"
|
||||
];
|
||||
firewall.allowedTCPPorts = [
|
||||
22
|
||||
80
|
||||
|
|
@ -44,9 +66,13 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
users.users.root.openssh.authorizedKeys.keys = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM6tzq33IQcurWoQ7vhXOTLjv8YkdTGb7NoNsul3Sbfu rathi@mac"
|
||||
];
|
||||
# Emergency console access - generate hashed password and save to Bitwarden later
|
||||
users.users.root = {
|
||||
initialPassword = "temppass123";
|
||||
openssh.authorizedKeys.keys = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM6tzq33IQcurWoQ7vhXOTLjv8YkdTGb7NoNsul3Sbfu rathi@mac"
|
||||
];
|
||||
};
|
||||
|
||||
users.users.${username} = {
|
||||
isNormalUser = true;
|
||||
|
|
@ -64,15 +90,182 @@ in
|
|||
username
|
||||
];
|
||||
|
||||
nix.gc.options = lib.mkForce "--delete-older-than 3d";
|
||||
|
||||
nix.extraOptions = ''
|
||||
min-free = ${toString (100 * 1024 * 1024)}
|
||||
max-free = ${toString (1024 * 1024 * 1024)}
|
||||
'';
|
||||
|
||||
services.journald.extraConfig = "MaxRetainedFileSec=1week";
|
||||
|
||||
environment.systemPackages = packageSets.extras ++ [
|
||||
pkgs.bubblewrap
|
||||
pkgs.pnpm
|
||||
pkgs.nodejs
|
||||
];
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"L /usr/bin/bwrap - - - - ${pkgs.bubblewrap}/bin/bwrap"
|
||||
];
|
||||
|
||||
# --- ACME / Let's Encrypt ---
|
||||
security.acme = {
|
||||
acceptTerms = true;
|
||||
defaults.email = "rathiharivansh@gmail.com";
|
||||
};
|
||||
|
||||
# --- Nginx reverse proxy ---
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
recommendedProxySettings = true;
|
||||
recommendedTlsSettings = true;
|
||||
clientMaxBodySize = "512m";
|
||||
|
||||
virtualHosts."sandbox.example.dev" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
locations."/".proxyPass = "http://127.0.0.1:2470";
|
||||
};
|
||||
|
||||
virtualHosts."git.example.dev" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
locations."/".proxyPass = "http://127.0.0.1:3000";
|
||||
};
|
||||
};
|
||||
|
||||
# --- Forgejo ---
|
||||
users.users.git = {
|
||||
isSystemUser = true;
|
||||
home = "/var/lib/forgejo";
|
||||
group = "git";
|
||||
shell = "${pkgs.bash}/bin/bash";
|
||||
};
|
||||
users.groups.git = { };
|
||||
|
||||
services.forgejo = {
|
||||
enable = true;
|
||||
user = "git";
|
||||
group = "git";
|
||||
settings = {
|
||||
server = {
|
||||
DOMAIN = "git.example.dev";
|
||||
ROOT_URL = "https://git.example.dev/";
|
||||
HTTP_PORT = 3000;
|
||||
SSH_DOMAIN = "git.example.dev";
|
||||
};
|
||||
service.DISABLE_REGISTRATION = true;
|
||||
session.COOKIE_SECURE = true;
|
||||
mirror = {
|
||||
DEFAULT_INTERVAL = "1h";
|
||||
MIN_INTERVAL = "10m";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# --- Forgejo mirror sync (hourly) ---
|
||||
systemd.services.forgejo-mirror-sync = {
|
||||
description = "Sync GitHub mirrors to Forgejo";
|
||||
after = [ "forgejo.service" ];
|
||||
requires = [ "forgejo.service" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
EnvironmentFile = "/etc/forgejo-mirror.env";
|
||||
};
|
||||
path = [
|
||||
pkgs.curl
|
||||
pkgs.jq
|
||||
pkgs.coreutils
|
||||
];
|
||||
script = ''
|
||||
set -euo pipefail
|
||||
|
||||
# Fetch all GitHub repos
|
||||
page=1
|
||||
repos=""
|
||||
while true; do
|
||||
batch=$(curl -sf -H "Authorization: token $GITHUB_TOKEN" \
|
||||
"https://api.github.com/user/repos?per_page=100&page=$page&affiliation=owner")
|
||||
count=$(echo "$batch" | jq length)
|
||||
[ "$count" -eq 0 ] && break
|
||||
repos="$repos$batch"
|
||||
page=$((page + 1))
|
||||
done
|
||||
|
||||
echo "$repos" | jq -r '.[].clone_url' | while read -r clone_url; do
|
||||
repo_name=$(basename "$clone_url" .git)
|
||||
|
||||
# Check if mirror already exists in Forgejo
|
||||
status=$(curl -sf -o /dev/null -w '%{http_code}' \
|
||||
-H "Authorization: token $FORGEJO_TOKEN" \
|
||||
"$FORGEJO_URL/api/v1/repos/$FORGEJO_OWNER/$repo_name")
|
||||
|
||||
if [ "$status" = "404" ]; then
|
||||
# Create mirror
|
||||
curl -sf -X POST \
|
||||
-H "Authorization: token $FORGEJO_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
"$FORGEJO_URL/api/v1/repos/migrate" \
|
||||
-d "{
|
||||
\"clone_addr\": \"$clone_url\",
|
||||
\"auth_token\": \"$GITHUB_TOKEN\",
|
||||
\"uid\": $(curl -sf -H "Authorization: token $FORGEJO_TOKEN" "$FORGEJO_URL/api/v1/user" | jq .id),
|
||||
\"repo_name\": \"$repo_name\",
|
||||
\"mirror\": true,
|
||||
\"service\": \"github\"
|
||||
}"
|
||||
echo "Created mirror: $repo_name"
|
||||
else
|
||||
# Trigger sync on existing mirror
|
||||
curl -sf -X POST \
|
||||
-H "Authorization: token $FORGEJO_TOKEN" \
|
||||
"$FORGEJO_URL/api/v1/repos/$FORGEJO_OWNER/$repo_name/mirror-sync" || true
|
||||
echo "Synced mirror: $repo_name"
|
||||
fi
|
||||
done
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.timers.forgejo-mirror-sync = {
|
||||
wantedBy = [ "timers.target" ];
|
||||
timerConfig = {
|
||||
OnCalendar = "hourly";
|
||||
Persistent = true;
|
||||
RandomizedDelaySec = "5m";
|
||||
};
|
||||
};
|
||||
|
||||
# --- Sandbox Agent (declarative systemd services) ---
|
||||
systemd.services.sandbox-agent = {
|
||||
description = "Sandbox Agent";
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
User = username;
|
||||
Group = "users";
|
||||
EnvironmentFile = "/home/${username}/.config/sandbox-agent/agent.env";
|
||||
ExecStart = "/home/${username}/.local/bin/sandbox-agent";
|
||||
Restart = "on-failure";
|
||||
RestartSec = 5;
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.sandbox-cors-proxy = {
|
||||
description = "Sandbox CORS Proxy";
|
||||
after = [ "sandbox-agent.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
User = username;
|
||||
Group = "users";
|
||||
ExecStart = "${pkgs.nodejs}/bin/node /home/${username}/.config/sandbox-agent/cors-proxy.js";
|
||||
Restart = "on-failure";
|
||||
RestartSec = 5;
|
||||
};
|
||||
};
|
||||
|
||||
system.configurationRevision = self.rev or self.dirtyRev or null;
|
||||
system.stateVersion = "24.11";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,5 @@
|
|||
|
||||
virtualisation.hypervGuest.enable = false;
|
||||
|
||||
networking.useDHCP = lib.mkDefault true;
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,20 @@
|
|||
kind = "darwin";
|
||||
system = "aarch64-darwin";
|
||||
hostname = "hari-macbook-pro";
|
||||
homeModule = ../home;
|
||||
homeDirectory = "/Users/${username}";
|
||||
isDarwin = true;
|
||||
isLinux = false;
|
||||
isNixOS = false;
|
||||
features = {
|
||||
rust = true;
|
||||
go = true;
|
||||
node = true;
|
||||
python = true;
|
||||
aws = true;
|
||||
claude = true;
|
||||
docker = true;
|
||||
tex = true;
|
||||
};
|
||||
};
|
||||
|
||||
netty = {
|
||||
|
|
@ -14,8 +26,19 @@
|
|||
kind = "nixos";
|
||||
system = "x86_64-linux";
|
||||
hostname = "netty";
|
||||
homeModule = ../home/netty.nix;
|
||||
standaloneHomeModule = ../hosts/netty;
|
||||
homeDirectory = "/home/${username}";
|
||||
isDarwin = false;
|
||||
isLinux = true;
|
||||
isNixOS = true;
|
||||
features = {
|
||||
rust = true;
|
||||
go = true;
|
||||
node = true;
|
||||
python = true;
|
||||
aws = true;
|
||||
claude = true;
|
||||
docker = false;
|
||||
tex = false;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,56 +6,8 @@
|
|||
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;
|
||||
|
||||
graphite = pkgs.stdenvNoCC.mkDerivation rec {
|
||||
pname = "graphite";
|
||||
version = "1.7.20";
|
||||
|
||||
src = pkgs.fetchurl {
|
||||
url = "https://github.com/withgraphite/homebrew-tap/releases/download/v${version}/gt-macos-arm64";
|
||||
hash = "sha256-ho9VQw1ic3jhG3yxNwUL0W1WvNFku9zw6DQnGehs7+8=";
|
||||
};
|
||||
|
||||
dontUnpack = true;
|
||||
|
||||
installPhase = ''
|
||||
install -Dm755 "$src" "$out/bin/gt"
|
||||
'';
|
||||
|
||||
meta = {
|
||||
description = "Manage stacked Git changes and submit them for review";
|
||||
homepage = "https://graphite.dev/";
|
||||
license = lib.licenses.agpl3Only;
|
||||
mainProgram = "gt";
|
||||
platforms = lib.platforms.darwin;
|
||||
};
|
||||
};
|
||||
|
||||
worktrunk = pkgs.rustPlatform.buildRustPackage rec {
|
||||
pname = "worktrunk";
|
||||
version = "0.23.1";
|
||||
|
||||
src = pkgs.fetchurl {
|
||||
url = "https://github.com/max-sixty/worktrunk/archive/refs/tags/v${version}.tar.gz";
|
||||
hash = "sha256-cdQDUz7to3JkriWE9i5iJ2RftJFZivw7CTwGxDZPAqw=";
|
||||
};
|
||||
|
||||
cargoHash = "sha256-DHjwNqMiVkWqL3CuOCITvyqkdKe+GOZ2nlMSstDIcTg=";
|
||||
doCheck = false;
|
||||
|
||||
meta = {
|
||||
description = "CLI for Git worktree management";
|
||||
homepage = "https://worktrunk.dev";
|
||||
license = with lib.licenses; [
|
||||
asl20
|
||||
mit
|
||||
];
|
||||
mainProgram = "wt";
|
||||
platforms = lib.platforms.darwin;
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
core = with pkgs; [
|
||||
|
|
@ -104,18 +56,13 @@ in
|
|||
redis
|
||||
tailscale
|
||||
terraform
|
||||
texliveFull
|
||||
yt-dlp
|
||||
])
|
||||
++ lib.optionals pkgs.stdenv.isDarwin [
|
||||
agentcomputerPackage
|
||||
pkgs.texliveFull
|
||||
]
|
||||
++ [
|
||||
openspecPackage
|
||||
]
|
||||
++ lib.optionals pkgs.stdenv.isDarwin [
|
||||
graphite
|
||||
worktrunk
|
||||
];
|
||||
|
||||
fonts = with pkgs; [
|
||||
|
|
|
|||
114
lib/theme.nix
114
lib/theme.nix
|
|
@ -140,14 +140,128 @@ let
|
|||
--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}
|
||||
'';
|
||||
renderPurePrompt =
|
||||
mode:
|
||||
let
|
||||
theme = themes.${mode};
|
||||
c =
|
||||
if mode == "light" then
|
||||
{
|
||||
path = "#4261a5";
|
||||
branch = "#427b58";
|
||||
dirty = sharedPalette.yellow;
|
||||
arrow = sharedPalette.purpleNeutral;
|
||||
stash = sharedPalette.aquaNeutral;
|
||||
success = "#427b58";
|
||||
error = "#c5524a";
|
||||
execTime = sharedPalette.gray;
|
||||
host = sharedPalette.gray;
|
||||
user = sharedPalette.gray;
|
||||
}
|
||||
else
|
||||
{
|
||||
path = sharedPalette.blue;
|
||||
branch = sharedPalette.green;
|
||||
dirty = sharedPalette.yellowBright;
|
||||
arrow = sharedPalette.purple;
|
||||
stash = sharedPalette.aqua;
|
||||
success = sharedPalette.green;
|
||||
error = sharedPalette.red;
|
||||
execTime = sharedPalette.gray;
|
||||
host = sharedPalette.gray;
|
||||
user = sharedPalette.gray;
|
||||
};
|
||||
in
|
||||
''
|
||||
zstyle ':prompt:pure:path' color '${c.path}'
|
||||
zstyle ':prompt:pure:git:branch' color '${c.branch}'
|
||||
zstyle ':prompt:pure:git:dirty' color '${c.dirty}'
|
||||
zstyle ':prompt:pure:git:arrow' color '${c.arrow}'
|
||||
zstyle ':prompt:pure:git:stash' color '${c.stash}'
|
||||
zstyle ':prompt:pure:git:action' color '${c.dirty}'
|
||||
zstyle ':prompt:pure:prompt:success' color '${c.success}'
|
||||
zstyle ':prompt:pure:prompt:error' color '${c.error}'
|
||||
zstyle ':prompt:pure:execution_time' color '${c.execTime}'
|
||||
zstyle ':prompt:pure:host' color '${c.host}'
|
||||
zstyle ':prompt:pure:user' color '${c.user}'
|
||||
zstyle ':prompt:pure:user:root' color '${c.error}'
|
||||
'';
|
||||
|
||||
batTheme = mode: if mode == "light" then "gruvbox-light" else "gruvbox-dark";
|
||||
|
||||
deltaTheme = mode: if mode == "light" then "gruvbox-light" else "gruvbox-dark";
|
||||
|
||||
renderZshHighlights =
|
||||
mode:
|
||||
let
|
||||
# Light mode uses gruvbox-light specific colors
|
||||
light = {
|
||||
arg0 = "#427b58";
|
||||
aqua = "#076678";
|
||||
purple = "#8f3f71";
|
||||
yellow = "#b57614";
|
||||
text = "#3c3836";
|
||||
comment = "#928374";
|
||||
error = "#ea6962";
|
||||
};
|
||||
# Dark mode uses our theme palette
|
||||
dark = {
|
||||
arg0 = sharedPalette.green;
|
||||
aqua = sharedPalette.aqua;
|
||||
purple = sharedPalette.purple;
|
||||
yellow = "#d8a657";
|
||||
text = "#d4be98";
|
||||
comment = "#7c6f64";
|
||||
error = sharedPalette.red;
|
||||
blue = sharedPalette.blue;
|
||||
};
|
||||
c = if mode == "light" then light else dark;
|
||||
blueOrAqua = if mode == "light" then c.aqua else c.blue;
|
||||
in
|
||||
''
|
||||
ZSH_HIGHLIGHT_STYLES[arg0]='fg=${c.arg0}'
|
||||
ZSH_HIGHLIGHT_STYLES[autodirectory]='fg=${c.arg0},underline'
|
||||
ZSH_HIGHLIGHT_STYLES[back-dollar-quoted-argument]='fg=${if mode == "light" then c.aqua else c.aqua}'
|
||||
ZSH_HIGHLIGHT_STYLES[back-double-quoted-argument]='fg=${if mode == "light" then c.aqua else c.aqua}'
|
||||
ZSH_HIGHLIGHT_STYLES[back-quoted-argument-delimiter]='fg=${c.purple}'
|
||||
ZSH_HIGHLIGHT_STYLES[bracket-error]='fg=${c.error},bold'
|
||||
ZSH_HIGHLIGHT_STYLES[bracket-level-1]='fg=${blueOrAqua},bold'
|
||||
ZSH_HIGHLIGHT_STYLES[bracket-level-2]='fg=${c.arg0},bold'
|
||||
ZSH_HIGHLIGHT_STYLES[bracket-level-3]='fg=${c.purple},bold'
|
||||
ZSH_HIGHLIGHT_STYLES[bracket-level-4]='fg=${c.yellow},bold'
|
||||
ZSH_HIGHLIGHT_STYLES[bracket-level-5]='fg=${if mode == "light" then c.aqua else c.aqua},bold'
|
||||
ZSH_HIGHLIGHT_STYLES[comment]='fg=${c.comment}'
|
||||
ZSH_HIGHLIGHT_STYLES[command-substitution-delimiter]='fg=${c.purple}'
|
||||
ZSH_HIGHLIGHT_STYLES[dollar-double-quoted-argument]='fg=${
|
||||
if mode == "light" then c.aqua else c.aqua
|
||||
}'
|
||||
ZSH_HIGHLIGHT_STYLES[dollar-quoted-argument]='fg=${c.yellow}'
|
||||
ZSH_HIGHLIGHT_STYLES[double-quoted-argument]='fg=${c.yellow}'
|
||||
ZSH_HIGHLIGHT_STYLES[global-alias]='fg=${if mode == "light" then c.aqua else c.aqua}'
|
||||
ZSH_HIGHLIGHT_STYLES[globbing]='fg=${blueOrAqua}'
|
||||
ZSH_HIGHLIGHT_STYLES[history-expansion]='fg=${blueOrAqua}'
|
||||
ZSH_HIGHLIGHT_STYLES[path]='fg=${c.text},underline'
|
||||
ZSH_HIGHLIGHT_STYLES[precommand]='fg=${c.arg0},underline'
|
||||
ZSH_HIGHLIGHT_STYLES[process-substitution-delimiter]='fg=${c.purple}'
|
||||
ZSH_HIGHLIGHT_STYLES[rc-quote]='fg=${if mode == "light" then c.aqua else c.aqua}'
|
||||
ZSH_HIGHLIGHT_STYLES[redirection]='fg=${c.yellow}'
|
||||
ZSH_HIGHLIGHT_STYLES[reserved-word]='fg=${c.yellow}'
|
||||
ZSH_HIGHLIGHT_STYLES[single-quoted-argument]='fg=${c.yellow}'
|
||||
ZSH_HIGHLIGHT_STYLES[suffix-alias]='fg=${c.arg0},underline'
|
||||
ZSH_HIGHLIGHT_STYLES[unknown-token]='fg=${c.error},bold'
|
||||
'';
|
||||
in
|
||||
{
|
||||
inherit
|
||||
batTheme
|
||||
defaultMode
|
||||
deltaTheme
|
||||
paths
|
||||
renderFzf
|
||||
renderGhostty
|
||||
renderPurePrompt
|
||||
renderTmux
|
||||
renderZshHighlights
|
||||
themes
|
||||
;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,11 +22,13 @@ in
|
|||
username
|
||||
];
|
||||
use-xdg-base-directories = true;
|
||||
max-jobs = "auto";
|
||||
cores = 0;
|
||||
};
|
||||
|
||||
nix.gc = {
|
||||
automatic = true;
|
||||
options = "--delete-older-than 14d";
|
||||
options = lib.mkDefault "--delete-older-than 14d";
|
||||
}
|
||||
// (
|
||||
if pkgs.stdenv.isDarwin then
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
{
|
||||
hosts,
|
||||
inputs,
|
||||
mkPkgs,
|
||||
mkSpecialArgs,
|
||||
mkHomeManagerModule,
|
||||
...
|
||||
|
|
@ -21,13 +20,5 @@ in
|
|||
(mkHomeManagerModule host)
|
||||
];
|
||||
};
|
||||
|
||||
homeConfigurations.${host.name} = inputs.home-manager.lib.homeManagerConfiguration {
|
||||
pkgs = mkPkgs host.system;
|
||||
extraSpecialArgs = mkSpecialArgs host;
|
||||
modules = [
|
||||
host.standaloneHomeModule
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ let
|
|||
mkSpecialArgs = host: {
|
||||
inherit inputs self username;
|
||||
hostname = host.hostname;
|
||||
hostConfig = host;
|
||||
};
|
||||
|
||||
mkHomeManagerModule = host: {
|
||||
|
|
@ -25,7 +26,7 @@ let
|
|||
home-manager.useUserPackages = true;
|
||||
home-manager.extraSpecialArgs = mkSpecialArgs host;
|
||||
home-manager.backupCommand = "bash ${../scripts/home-manager-backup.sh}";
|
||||
home-manager.users.${username} = import host.homeModule;
|
||||
home-manager.users.${username} = import ../home;
|
||||
};
|
||||
in
|
||||
{
|
||||
|
|
|
|||
173
nix-maxxing.txt
Normal file
173
nix-maxxing.txt
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
Nix Config - Architecture and Operations Guide
|
||||
================================================
|
||||
|
||||
1. STATIC IP
|
||||
----------------------------
|
||||
DHCP on a VPS is dangerous. If the DHCP lease expires or the server
|
||||
reboots while the DHCP server is unreachable, the machine loses its IP
|
||||
and becomes inaccessible via SSH.
|
||||
|
||||
Static config in hosts/netty/configuration.nix:
|
||||
- IP: 152.53.195.59/22
|
||||
- Gateway: 152.53.192.1
|
||||
- Interface: ens3
|
||||
- DNS: 1.1.1.1, 8.8.8.8
|
||||
|
||||
Always verify the interface name with `ip link show` before changing
|
||||
network config. Keep VNC console access available as a fallback.
|
||||
|
||||
|
||||
2. HOST ABSTRACTION (hostConfig)
|
||||
---------------------------------
|
||||
lib/hosts.nix defines each machine with:
|
||||
- isDarwin / isLinux / isNixOS booleans
|
||||
- features map (rust, go, node, python, aws, claude, docker, tex)
|
||||
|
||||
modules/nixpkgs.nix passes hostConfig via specialArgs so all home-manager
|
||||
modules can use it. This replaces scattered `pkgs.stdenv.isDarwin` checks.
|
||||
|
||||
To add a new host:
|
||||
1. Add entry to lib/hosts.nix with all fields
|
||||
2. Create hosts/<name>/configuration.nix (NixOS) or add darwin case
|
||||
3. Add host output in modules/hosts/<name>.nix
|
||||
4. home/default.nix auto-selects modules based on hostConfig flags
|
||||
|
||||
home/default.nix is the unified entry point - no separate per-host home
|
||||
modules needed.
|
||||
|
||||
|
||||
3. XDG COMPLIANCE
|
||||
------------------
|
||||
home/xdg.nix sets environment variables so tools respect XDG dirs:
|
||||
|
||||
CARGO_HOME -> $XDG_DATA_HOME/cargo
|
||||
RUSTUP_HOME -> $XDG_DATA_HOME/rustup
|
||||
GOPATH -> $XDG_DATA_HOME/go
|
||||
GOMODCACHE -> $XDG_CACHE_HOME/go/mod
|
||||
NPM_CONFIG_USERCONFIG -> $XDG_CONFIG_HOME/npm/npmrc
|
||||
NODE_REPL_HISTORY -> $XDG_STATE_HOME/node_repl_history
|
||||
PYTHON_HISTORY -> $XDG_STATE_HOME/python_history
|
||||
AWS_CONFIG_FILE -> $XDG_CONFIG_HOME/aws/config
|
||||
DOCKER_CONFIG -> $XDG_CONFIG_HOME/docker
|
||||
CLAUDE_CONFIG_DIR -> $XDG_CONFIG_HOME/claude
|
||||
PSQL_HISTORY -> $XDG_STATE_HOME/psql_history
|
||||
SQLITE_HISTORY -> $XDG_STATE_HOME/sqlite_history
|
||||
LESSHISTFILE -> "-" (disabled)
|
||||
|
||||
All gated by hostConfig.features so tools only get configured when
|
||||
the feature flag is set for that host.
|
||||
|
||||
|
||||
4. SECURITY MODULE
|
||||
-------------------
|
||||
home/security.nix runs activation scripts on every `home-manager switch`:
|
||||
- ~/.ssh/ dir: 700, private keys: 600, pub/known_hosts/config: 644
|
||||
- ~/.gnupg/ dirs: 700, files: 600
|
||||
|
||||
No manual chmod needed after restoring keys from Bitwarden.
|
||||
|
||||
|
||||
5. THEME SYSTEM
|
||||
----------------
|
||||
lib/theme.nix is the single source of truth for colors.
|
||||
|
||||
Shared palette (gruvbox-inspired) used across:
|
||||
- Ghostty terminal (renderGhostty)
|
||||
- Tmux status bar (renderTmux)
|
||||
- fzf color scheme (renderFzf)
|
||||
- Zsh syntax highlighting (renderZshHighlights)
|
||||
- Bat (batTheme)
|
||||
- Git delta (deltaTheme)
|
||||
|
||||
Runtime toggle: `theme toggle` writes "light" or "dark" to
|
||||
$XDG_STATE_HOME/theme/current, then updates Ghostty, tmux, fzf,
|
||||
and Neovim (via RPC) live. Bat and delta are static at build time.
|
||||
|
||||
|
||||
6. SHELL SETUP
|
||||
---------------
|
||||
Pure prompt with gruvbox-colored git integration. Async git status
|
||||
(no blocking on large repos). Colors defined in lib/theme.nix via
|
||||
renderPurePrompt - adapts to light/dark mode at runtime.
|
||||
Vim mode via defaultKeymap = "viins" with cursor shape switching
|
||||
(beam for insert, block for normal).
|
||||
|
||||
History: 50k entries, dedup, ignoreSpace, extended format, stored at
|
||||
$XDG_STATE_HOME/zsh_history.
|
||||
|
||||
zoxide: declarative via programs.zoxide (no manual eval).
|
||||
|
||||
PATH: managed via home.sessionPath in xdg.nix + initContent block
|
||||
in zsh.nix for entries that need conditional logic.
|
||||
|
||||
|
||||
7. SERVER SERVICES (netty)
|
||||
---------------------------
|
||||
All in hosts/netty/configuration.nix:
|
||||
|
||||
Nginx reverse proxy with ACME SSL:
|
||||
- sandbox.example.dev -> 127.0.0.1:2470 (sandbox agent)
|
||||
- git.example.dev -> 127.0.0.1:3000 (forgejo)
|
||||
|
||||
Forgejo:
|
||||
- Self-hosted git, registration disabled
|
||||
- Runs as git user on port 3000
|
||||
- GitHub mirror sync via hourly systemd timer
|
||||
- Requires /etc/forgejo-mirror.env with GITHUB_TOKEN, FORGEJO_TOKEN,
|
||||
FORGEJO_URL, FORGEJO_OWNER
|
||||
|
||||
Sandbox Agent:
|
||||
- System-level systemd services (not user units)
|
||||
- sandbox-agent on :2470, env from ~/.config/sandbox-agent/agent.env
|
||||
- sandbox-cors-proxy on :2468 (Node.js)
|
||||
- No cloudflared - nginx handles SSL termination
|
||||
|
||||
Garbage collection: 3-day retention (vs 14-day on darwin).
|
||||
Disk guards: min-free 100MB, max-free 1GB.
|
||||
Journald: 1-week retention.
|
||||
|
||||
|
||||
8. DEPLOY COMMANDS
|
||||
-------------------
|
||||
Darwin (local):
|
||||
just switch
|
||||
|
||||
Netty (from mac):
|
||||
just switch-netty
|
||||
|
||||
First-time netty install:
|
||||
nix run github:nix-community/nixos-anywhere -- \
|
||||
--flake .#netty --target-host netty --build-on-remote
|
||||
|
||||
|
||||
9. ROLLBACK
|
||||
-------------
|
||||
Each phase is a separate git commit.
|
||||
|
||||
NixOS rollback:
|
||||
ssh netty "nixos-rebuild switch --rollback"
|
||||
|
||||
Or boot previous generation from GRUB (3 kept).
|
||||
|
||||
Darwin rollback:
|
||||
git revert <commit> && just switch
|
||||
|
||||
Home Manager rollback:
|
||||
home-manager generations # list
|
||||
home-manager switch --flake .#<host> # after git revert
|
||||
|
||||
|
||||
10. FEATURE FLAGS REFERENCE
|
||||
-----------------------------
|
||||
| Feature | darwin | netty |
|
||||
|---------|--------|-------|
|
||||
| rust | yes | yes |
|
||||
| go | yes | yes |
|
||||
| node | yes | yes |
|
||||
| python | yes | yes |
|
||||
| aws | yes | yes |
|
||||
| claude | yes | yes |
|
||||
| docker | yes | no |
|
||||
| tex | yes | no |
|
||||
|
||||
Set in lib/hosts.nix, consumed by home/xdg.nix and lib/package-sets.nix.
|
||||
Loading…
Add table
Add a link
Reference in a new issue