From de44814a00b9364e532dcf42e242c505bf9202b8 Mon Sep 17 00:00:00 2001 From: Ivan Malison Date: Sun, 10 May 2026 13:56:25 -0700 Subject: [PATCH] Update desktop and Codex configuration --- dotfiles/codex/.gitignore | 3 +- dotfiles/codex/config.toml | 7 +- dotfiles/config/hypr/hyprland/settings.lua | 6 +- .../config/taffybar/TaffybarConfig/Widgets.hs | 26 +-- dotfiles/config/taffybar/taffybar | 2 +- dotfiles/config/xmonad/xmonad-contrib | 2 +- .../home-manager/codex-generated-skills.nix | 159 ++++++++++++------ nixos/flake.lock | 76 ++++----- 8 files changed, 170 insertions(+), 111 deletions(-) diff --git a/dotfiles/codex/.gitignore b/dotfiles/codex/.gitignore index dcb67b74..2fe5f524 100644 --- a/dotfiles/codex/.gitignore +++ b/dotfiles/codex/.gitignore @@ -4,4 +4,5 @@ !config.toml !skills -# Generated/local Codex state, including config.local.toml, stays ignored. +# Legacy generated/local Codex state under this repo stays ignored. Active +# host-local Codex fragments now live under ~/.codex. diff --git a/dotfiles/codex/config.toml b/dotfiles/codex/config.toml index c528c571..23565ca8 100644 --- a/dotfiles/codex/config.toml +++ b/dotfiles/codex/config.toml @@ -4,10 +4,9 @@ service_tier = "fast" personality = "pragmatic" suppress_unstable_features_warning = true -# Portable Codex defaults. Machine-local additions are appended from -# dotfiles/codex/config.local.toml by Home Manager. Codex-owned local -# state, including project trust settings, is harvested there before -# this file is regenerated. +# Portable Codex defaults. Home Manager appends host-local fragments from +# ~/.codex/config.local.toml and ~/.codex/config.local-state.toml when it +# regenerates ~/.codex/config.toml. [mcp_servers.chrome-devtools] command = "npx" diff --git a/dotfiles/config/hypr/hyprland/settings.lua b/dotfiles/config/hypr/hyprland/settings.lua index 5024c276..5e44ef27 100644 --- a/dotfiles/config/hypr/hyprland/settings.lua +++ b/dotfiles/config/hypr/hyprland/settings.lua @@ -133,9 +133,9 @@ function M.setup(ctx) { leaf = "layersIn", enabled = true, speed = 5, bezier = "smoothOut", style = "fade" }, { leaf = "layersOut", enabled = true, speed = 5, bezier = "smoothOut", style = "fade" }, - { leaf = "workspaces", enabled = true, speed = 8, spring = "workspaceSpring", style = "slidefade 32%" }, - { leaf = "workspacesIn", enabled = true, speed = 8, spring = "workspaceSpring", style = "slidefade 32%" }, - { leaf = "workspacesOut", enabled = true, speed = 8, spring = "workspaceSpring", style = "slidefade 32%" }, + { leaf = "workspaces", enabled = true, speed = 10, spring = "workspaceSpring", style = "slide" }, + { leaf = "workspacesIn", enabled = true, speed = 10, spring = "workspaceSpring", style = "slide" }, + { leaf = "workspacesOut", enabled = true, speed = 10, spring = "workspaceSpring", style = "slide" }, { leaf = "specialWorkspace", enabled = true, speed = 8, spring = "workspaceSpring", style = "slidevert" }, { leaf = "specialWorkspaceIn", enabled = true, speed = 8, spring = "workspaceSpring", style = "slidevert" }, { leaf = "specialWorkspaceOut", enabled = true, speed = 8, spring = "workspaceSpring", style = "slidevert" }, diff --git a/dotfiles/config/taffybar/TaffybarConfig/Widgets.hs b/dotfiles/config/taffybar/TaffybarConfig/Widgets.hs index 4b363280..f30e4397 100644 --- a/dotfiles/config/taffybar/TaffybarConfig/Widgets.hs +++ b/dotfiles/config/taffybar/TaffybarConfig/Widgets.hs @@ -18,16 +18,6 @@ import Data.Text (Text) import qualified Data.Text as T import qualified GI.Gtk as Gtk import qualified StatusNotifier.Tray as SNITray -import TaffybarConfig.Host (laptopHosts) -import TaffybarConfig.WidgetUtil - ( decorateWithClassAndBox, - decorateWithClassAndBoxM, - setFixedLabelWidth, - setLabelAlignmentRecursively, - stackInPill, - usageLogoWidget, - ) -import TaffybarConfig.Workspaces (workspaceLabelSetter, workspaceShowPredicate, workspaceWindowIconGetter) import System.Environment (lookupEnv) import System.Environment.XDG.BaseDir (getUserConfigFile) import System.Taffybar.Context @@ -35,6 +25,7 @@ import System.Taffybar.Context TaffyIO, ) import System.Taffybar.Information.Memory (MemoryInfo (..), parseMeminfo) +import qualified System.Taffybar.Information.Workspaces.Hyprland as HyprlandWorkspaces import System.Taffybar.Util (postGUIASync) import System.Taffybar.Widget import qualified System.Taffybar.Widget.ASUS as ASUS @@ -69,6 +60,16 @@ import System.Taffybar.Widget.Util ) import qualified System.Taffybar.Widget.Wlsunset as Wlsunset import qualified System.Taffybar.Widget.Workspaces as Workspaces +import TaffybarConfig.Host (laptopHosts) +import TaffybarConfig.WidgetUtil + ( decorateWithClassAndBox, + decorateWithClassAndBoxM, + setFixedLabelWidth, + setLabelAlignmentRecursively, + stackInPill, + usageLogoWidget, + ) +import TaffybarConfig.Workspaces (workspaceLabelSetter, workspaceShowPredicate, workspaceWindowIconGetter) import Text.Printf (printf) import Text.Read (readMaybe) @@ -109,6 +110,11 @@ workspacesWidget = { Workspaces.widgetGap = 0, Workspaces.minIcons = 1, Workspaces.getWindowIconPixbuf = workspaceWindowIconGetter, + Workspaces.hyprlandWorkspaceProviderConfig = + HyprlandWorkspaces.defaultHyprlandWorkspaceProviderConfig + { HyprlandWorkspaces.specialWorkspaceWindowTarget = + HyprlandWorkspaces.specialWorkspaceWindowsToMinimized + }, Workspaces.labelSetter = workspaceLabelSetter, Workspaces.showWorkspaceFn = workspaceShowPredicate } diff --git a/dotfiles/config/taffybar/taffybar b/dotfiles/config/taffybar/taffybar index 8ab1f339..bb26f165 160000 --- a/dotfiles/config/taffybar/taffybar +++ b/dotfiles/config/taffybar/taffybar @@ -1 +1 @@ -Subproject commit 8ab1f3399f71e48fd52dd209fc58b1691d7e72da +Subproject commit bb26f165a7c4c38b9bbe378c9f1ba7b943e805af diff --git a/dotfiles/config/xmonad/xmonad-contrib b/dotfiles/config/xmonad/xmonad-contrib index 325453c0..1a8da468 160000 --- a/dotfiles/config/xmonad/xmonad-contrib +++ b/dotfiles/config/xmonad/xmonad-contrib @@ -1 +1 @@ -Subproject commit 325453c06c3d467ab53e689e8c2a2f33180d61c9 +Subproject commit 1a8da46855ca83e11cfb31cbbaed980ed7a8dfcc diff --git a/nix-shared/home-manager/codex-generated-skills.nix b/nix-shared/home-manager/codex-generated-skills.nix index e4365538..dcfe646f 100644 --- a/nix-shared/home-manager/codex-generated-skills.nix +++ b/nix-shared/home-manager/codex-generated-skills.nix @@ -22,6 +22,18 @@ in { description = "Codex dotfiles directory in the live worktree."; }; + localConfig = lib.mkOption { + type = lib.types.str; + default = "${cfg.codexHome}/config.local.toml"; + description = "Host-local Codex config fragment appended after the shared config."; + }; + + generatedStateConfig = lib.mkOption { + type = lib.types.str; + default = "${cfg.codexHome}/config.local-state.toml"; + description = "Codex-generated host-local state harvested from config.toml."; + }; + skillsDir = lib.mkOption { type = lib.types.str; default = "${cfg.codexHome}/skills"; @@ -46,16 +58,11 @@ in { force = true; source = oos "${cfg.worktreeCodexDir}/AGENTS.md"; }; - - ".codex/skills" = { - force = true; - source = oos "${cfg.worktreeCodexDir}/skills"; - }; }; home.activation.prepareCodexDirectory = lib.hm.dag.entryBefore ["checkLinkTargets"] '' codex_home=${lib.escapeShellArg cfg.codexHome} - worktree_codex=${lib.escapeShellArg cfg.worktreeCodexDir} + skills_dir=${lib.escapeShellArg cfg.skillsDir} if [ -L "$codex_home" ]; then rm -f "$codex_home" @@ -66,15 +73,46 @@ in { echo "Skipping Codex setup because $codex_home is not a directory" >&2 exit 1 fi + + if [ -L "$skills_dir" ]; then + tmp_skills="$(mktemp -d "''${TMPDIR:-/tmp}/codex-skills.XXXXXX")" + trap 'rm -rf "$tmp_skills"' EXIT + + for generated_dir in .system codex-primary-runtime; do + if [ -d "$skills_dir/$generated_dir" ]; then + cp -R "$skills_dir/$generated_dir" "$tmp_skills/$generated_dir" + fi + done + + rm -f "$skills_dir" + mkdir -p "$skills_dir" + + for generated_dir in "$tmp_skills"/*; do + if [ -e "$generated_dir" ]; then + mv "$generated_dir" "$skills_dir/" + fi + done + elif [ ! -e "$skills_dir" ]; then + mkdir -p "$skills_dir" + elif [ ! -d "$skills_dir" ]; then + echo "Skipping Codex skills setup because $skills_dir is not a directory" >&2 + exit 1 + fi ''; home.activation.generateCodexConfig = lib.hm.dag.entryAfter ["writeBoundary"] '' codex_home=${lib.escapeShellArg cfg.codexHome} base=${lib.escapeShellArg "${cfg.worktreeCodexDir}/config.toml"} - local_config=${lib.escapeShellArg "${cfg.worktreeCodexDir}/config.local.toml"} + local_config=${lib.escapeShellArg cfg.localConfig} + local_state_config=${lib.escapeShellArg cfg.generatedStateConfig} target="$codex_home/config.toml" begin_marker="# BEGIN AUTO-GENERATED CODEX MACHINE STATE" end_marker="# END AUTO-GENERATED CODEX MACHINE STATE" + rejected_project_prefixes=${lib.escapeShellArg ( + if pkgs.stdenv.isDarwin + then "/home/ /run/" + else "/Users/ /Volumes/" + )} if [ ! -r "$base" ]; then echo "Missing shared Codex config at $base" >&2 @@ -84,14 +122,13 @@ in { mkdir -p "$codex_home" if [ -r "$target" ]; then - mkdir -p "$(dirname "$local_config")" local_state="$(mktemp "$codex_home/config.local-state.XXXXXX")" - local_tmp="$(mktemp "$codex_home/config.local.toml.XXXXXX")" - trap 'rm -f "$tmp" "$local_state" "$local_tmp"' EXIT + trap 'rm -f "$tmp" "$local_state"' EXIT ${lib.getExe pkgs.gawk} \ -v begin_marker="$begin_marker" \ - -v end_marker="$end_marker" ' + -v end_marker="$end_marker" \ + -v rejected_prefixes="$rejected_project_prefixes" ' FNR == NR { if ($0 ~ /^\[[^]]+\]$/) { base_sections[$0] = 1 @@ -99,8 +136,27 @@ in { next } + function rejected_project(section, path, count, parts, i) { + if (section !~ /^\[projects\."/) { + return 0 + } + + path = section + sub(/^\[projects\."/ , "", path) + sub(/"\]$/, "", path) + count = split(rejected_prefixes, parts, /[[:space:]]+/) + + for (i = 1; i <= count; i++) { + if (parts[i] != "" && index(path, parts[i]) == 1) { + return 1 + } + } + + return 0 + } + function flush_block() { - if (keep && section != "" && !(section in base_sections)) { + if (keep && section != "" && !(section in base_sections) && !rejected_project(section)) { if (printed) { print "" } @@ -130,46 +186,12 @@ in { } ' "$base" "$target" > "$local_state" - if [ -s "$local_state" ] || { [ -r "$local_config" ] && grep -Fqx "$begin_marker" "$local_config"; }; then - if [ -r "$local_config" ]; then - ${lib.getExe pkgs.gawk} \ - -v begin_marker="$begin_marker" \ - -v end_marker="$end_marker" ' - $0 == begin_marker { - skip = 1 - next - } - - $0 == end_marker { - skip = 0 - next - } - - !skip { - print - } - ' "$local_config" > "$local_tmp" - else - : > "$local_tmp" - fi - - if [ -s "$local_tmp" ] && [ -s "$local_state" ]; then - printf '\n' >> "$local_tmp" - fi - - if [ -s "$local_state" ]; then - printf '%s\n' "$begin_marker" >> "$local_tmp" - cat "$local_state" >> "$local_tmp" - printf '%s\n' "$end_marker" >> "$local_tmp" - fi - - chmod 600 "$local_tmp" - mv -f "$local_tmp" "$local_config" + if [ -s "$local_state" ]; then + chmod 600 "$local_state" + mv -f "$local_state" "$local_state_config" else - rm -f "$local_tmp" + rm -f "$local_state" "$local_state_config" fi - - rm -f "$local_state" fi tmp="$(mktemp "$codex_home/config.toml.XXXXXX")" @@ -182,6 +204,12 @@ in { cat "$local_config" >> "$tmp" fi + if [ -r "$local_state_config" ]; then + printf '\n%s\n' "$begin_marker" >> "$tmp" + cat "$local_state_config" >> "$tmp" + printf '%s\n' "$end_marker" >> "$tmp" + fi + if [ -e "$target" ] && cmp -s "$tmp" "$target"; then rm -f "$tmp" else @@ -189,7 +217,36 @@ in { fi ''; - home.activation.setupCodexGeneratedSkills = lib.hm.dag.entryAfter ["writeBoundary"] '' + home.activation.linkCodexDotfileSkills = lib.hm.dag.entryAfter ["writeBoundary"] '' + skills_dir=${lib.escapeShellArg cfg.skillsDir} + worktree_skills=${lib.escapeShellArg "${cfg.worktreeCodexDir}/skills"} + + if [ ! -d "$worktree_skills" ]; then + echo "Skipping Codex dotfile skills setup because $worktree_skills is not a directory" >&2 + exit 1 + fi + + mkdir -p "$skills_dir" + + for skill in "$worktree_skills"/*; do + [ -d "$skill" ] || continue + [ -r "$skill/SKILL.md" ] || continue + + name="$(basename "$skill")" + case "$name" in + .system|codex-primary-runtime) continue ;; + esac + + target="$skills_dir/$name" + if [ -L "$target" ] || [ ! -e "$target" ]; then + ln -sfn "$skill" "$target" + elif [ ! -d "$target" ]; then + echo "Skipping Codex skill $name because $target exists and is not a directory" >&2 + fi + done + ''; + + home.activation.setupCodexGeneratedSkills = lib.hm.dag.entryAfter ["linkCodexDotfileSkills"] '' codex_home=${lib.escapeShellArg cfg.codexHome} skills_dir=${lib.escapeShellArg cfg.skillsDir} runtime_skills_root=${lib.escapeShellArg "${cfg.primaryRuntimeDir}/skills/skills"} diff --git a/nixos/flake.lock b/nixos/flake.lock index 58a9f77d..69922ea1 100644 --- a/nixos/flake.lock +++ b/nixos/flake.lock @@ -70,11 +70,11 @@ ] }, "locked": { - "lastModified": 1777604373, - "narHash": "sha256-cQ+Z/fx5o43bD3PFZaz9yeEOVbAH1jqzdOiEP0ytW4M=", + "lastModified": 1778354823, + "narHash": "sha256-fOHLkjzkL+Na9mA7hDiWji23ATf0LEKo4z2hGJ/BkBs=", "owner": "sadjow", "repo": "claude-code-nix", - "rev": "8bd0a84bcfbd7e76eaa1c3421fc59861eb8a8f24", + "rev": "45184286c7660075779f062d0740ef95307709b5", "type": "github" }, "original": { @@ -317,11 +317,11 @@ ] }, "locked": { - "lastModified": 1733312601, - "narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=", + "lastModified": 1775087534, + "narHash": "sha256-91qqW8lhL7TLwgQWijoGBbiD4t7/q75KTi8NxjVmSmA=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9", + "rev": "3107b77cd68437b9a76194f0f7f9c55f2329ca5b", "type": "github" }, "original": { @@ -466,18 +466,14 @@ "nixpkgs": [ "nix", "nixpkgs" - ], - "nixpkgs-stable": [ - "nix", - "nixpkgs" ] }, "locked": { - "lastModified": 1734279981, - "narHash": "sha256-NdaCraHPp8iYMWzdXAt5Nv6sA3MUzlCiGiR586TCwo0=", + "lastModified": 1776796298, + "narHash": "sha256-PcRvlWayisPSjd0UcRQbhG8Oqw78AcPE6x872cPRHN8=", "owner": "cachix", "repo": "git-hooks.nix", - "rev": "aa9f40c906904ebd83da78e7f328cd8aeaeae785", + "rev": "3cfd774b0a530725a077e17354fbdb87ea1c4aad", "type": "github" }, "original": { @@ -662,11 +658,11 @@ ] }, "locked": { - "lastModified": 1777679572, - "narHash": "sha256-egYNbRrkn+6SwTHinhdb6WUfzzdC3nXfCRqS321VylY=", + "lastModified": 1778365864, + "narHash": "sha256-ImoT/wqmgMImf2dAC+E0MverAdA4QXsedOeES9B7Ezw=", "owner": "nix-community", "repo": "home-manager", - "rev": "9cb587ade2aa1b4a7257f0238d41072690b0ca4f", + "rev": "2f419037039a152448c5f4ae9494154753d1b399", "type": "github" }, "original": { @@ -803,11 +799,11 @@ "xdph": "xdph" }, "locked": { - "lastModified": 1778199997, - "narHash": "sha256-L+jaxpUg7l8dThBsuXddzd5rv1QKMiKLENuwM/aG3aA=", + "lastModified": 1778360491, + "narHash": "sha256-juQ1sMUT/DfYDMWUs4W+PNLIPdzW61KaGM/8/FPTb6I=", "ref": "refs/heads/main", - "rev": "de9f8dc9831d921cd1ee30d5d14f45f0e345a8ca", - "revCount": 7275, + "rev": "ee58a513f77fa93d0b7e29ac9ad6e59554266711", + "revCount": 7291, "submodules": true, "type": "git", "url": "https://github.com/hyprwm/Hyprland" @@ -1034,11 +1030,11 @@ ] }, "locked": { - "lastModified": 1778179779, - "narHash": "sha256-Ri6rVf54CRD3aISHLhSY6H4tBScVjm9ebkv7rF2lcZM=", + "lastModified": 1778234770, + "narHash": "sha256-jAcsogZwWMfXT9MfXxZzkwliAqIuZUV0p71h6Ba9ReE=", "owner": "hyprwm", "repo": "hyprutils", - "rev": "3e170e5ad010602671f5f25b327e8bdb8fdd532c", + "rev": "a2dbd8a4cc51f7cbe4224732668392bb1aa79df2", "type": "github" }, "original": { @@ -1089,11 +1085,11 @@ ] }, "locked": { - "lastModified": 1778232426, - "narHash": "sha256-++SqOzXEkgmiOh7OHHeIvh+OZy1qk02WIdKesHjRW60=", + "lastModified": 1778234303, + "narHash": "sha256-4kgvtJbWtgKm7vduxqAph/RTgBtSpmnbxAFkkxvRjBU=", "owner": "colonelpanic8", "repo": "hyprwinview", - "rev": "d12710de81cbec367408fd8e3280c2895353f37d", + "rev": "7c0719ab9e28b149fb6c134301c3006d61bb1e3e", "type": "github" }, "original": { @@ -1230,11 +1226,11 @@ "nixpkgs-regression": "nixpkgs-regression" }, "locked": { - "lastModified": 1777670731, - "narHash": "sha256-d3XkEeFReCzdyQEdpCV2icSpe8YQqHJUJSZ1TVfK03g=", + "lastModified": 1778249748, + "narHash": "sha256-D+3kaW4NUUaiFTsEpmregtGZVniljBThg/O0JIjRL8k=", "owner": "NixOS", "repo": "nix", - "rev": "cfa3e804cbd6606a189fd446546b3d435317effe", + "rev": "616df97974fd29b79f83502f63854d6d471ee055", "type": "github" }, "original": { @@ -1251,11 +1247,11 @@ ] }, "locked": { - "lastModified": 1777692697, - "narHash": "sha256-54mvoxw8d0cxLMXttEaviI7s+n3IZuhzkEbP3egqIds=", + "lastModified": 1778308096, + "narHash": "sha256-o1TmxVuTHN5kM/Yp7qV/xk4vx/d+xwws7EW2GyStqiw=", "owner": "nixified-ai", "repo": "flake", - "rev": "fe03b9f6dd68fb54ada8a04733d2fd94c048d1c3", + "rev": "f4a3fa4c1719ca05ba25dd60759664e2a422e797", "type": "github" }, "original": { @@ -1288,11 +1284,11 @@ ] }, "locked": { - "lastModified": 1777394230, - "narHash": "sha256-So0O9VEARU3xTRIFkBtvfzpRDxx4W2WPZPgucxdKBm8=", + "lastModified": 1777732699, + "narHash": "sha256-2uX/XtOWZ/oy2rerRynVhqVA//ZXZ3Fo60PikLHEPQc=", "owner": "nix-community", "repo": "NixOS-WSL", - "rev": "d2e09229638f08f6d5c99060573f6fa4b1dde852", + "rev": "5482f113fd31ebac131d1ebeb2ae90bf0d5e41f5", "type": "github" }, "original": { @@ -1414,11 +1410,11 @@ }, "nixpkgs_4": { "locked": { - "lastModified": 1777268161, - "narHash": "sha256-bxrdOn8SCOv8tN4JbTF/TXq7kjo9ag4M+C8yzzIRYbE=", + "lastModified": 1777954456, + "narHash": "sha256-hGdgeU2Nk87RAuZyYjyDjFL6LK7dAZN5RE9+hrDTkDU=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "1c3fe55ad329cbcb28471bb30f05c9827f724c76", + "rev": "549bd84d6279f9852cae6225e372cc67fb91a4c1", "type": "github" }, "original": { @@ -1827,8 +1823,8 @@ ] }, "locked": { - "lastModified": 1778303132, - "narHash": "sha256-P8W/cn7iiWbvrrkyv4LPENnsVbKbASK6+bLKZbxeIoA=", + "lastModified": 1778446560, + "narHash": "sha256-5DLLhYoHZ16cvpxNmAcFq6ybv+YjP4hAB1XDnOaJBEQ=", "path": "/home/imalison/dotfiles/dotfiles/config/taffybar/taffybar", "type": "path" },