From 480c556d3213b2bde043cfedeea9576e63263e63 Mon Sep 17 00:00:00 2001 From: atagen Date: Wed, 20 May 2026 16:01:46 +1000 Subject: [PATCH] homebrew pinning --- common/binfmts.nix | 2 +- common/editor.nix | 1 + common/nix/gc.nix | 2 +- common/nix/managers.nix | 8 +- common/nix/nixpkgs.nix | 1 + common/nix/plugins.nix | 20 - common/nix/settings.nix | 8 +- common/nix/substituters.nix | 1 + common/nix/tools.nix | 8 +- common/security.nix | 1 - common/systemd.nix | 2 +- common/terminal.nix | 5 + flake.lock | 1286 --------------------------- flake.nix | 100 --- graphical/binds.nix | 1 + graphical/boot.nix | 3 +- graphical/browser.nix | 1 + graphical/desktop/wry.nix | 10 +- graphical/documents.nix | 1 + graphical/fm.nix | 1 + graphical/gfx-env.nix | 2 +- graphical/hw.nix | 2 +- graphical/kernel.nix | 9 +- graphical/llm/clod.nix | 960 ++++++++++++++++++++ graphical/llm/codex.nix | 7 + graphical/llm/launcher.nu | 126 --- graphical/llm/lift-claude-bun.py | 92 -- graphical/llm/llm.nix | 152 ---- graphical/llm/patch-claude-src.py | 231 ----- graphical/llm/statusline-command.nu | 137 --- graphical/login.nix | 12 + graphical/media.nix | 1 + graphical/quick-services.nix | 1 + graphical/sync.nix | 2 +- graphical/terminal.nix | 18 +- hosts/adrift/boot.nix | 2 +- hosts/adrift/kernel.nix | 4 - hosts/quiver/boot.nix | 1 + hosts/quiver/kernel.nix | 14 - hosts/quiver/ssh.nix | 2 +- hosts/quiver/wm.nix | 3 + lib/create.nix | 2 +- lib/inputs.nix | 109 ++- pins/pins.lock.json | 179 ++++ pins/pins.toml | 90 ++ 45 files changed, 1401 insertions(+), 2219 deletions(-) delete mode 100644 common/nix/plugins.nix delete mode 100644 flake.lock delete mode 100644 flake.nix create mode 100644 graphical/llm/clod.nix create mode 100644 graphical/llm/codex.nix delete mode 100644 graphical/llm/launcher.nu delete mode 100644 graphical/llm/lift-claude-bun.py delete mode 100644 graphical/llm/llm.nix delete mode 100644 graphical/llm/patch-claude-src.py delete mode 100644 graphical/llm/statusline-command.nu create mode 100644 graphical/login.nix delete mode 100644 hosts/adrift/kernel.nix delete mode 100644 hosts/quiver/kernel.nix create mode 100644 hosts/quiver/wm.nix create mode 100644 pins/pins.lock.json create mode 100644 pins/pins.toml diff --git a/common/binfmts.nix b/common/binfmts.nix index 640b65e..116225e 100644 --- a/common/binfmts.nix +++ b/common/binfmts.nix @@ -1 +1 @@ -{ inputs, ... }: scope "imports" <| [ inputs.qstn.nixosModules.default ] +{ inputs, scope, ... }: scope "imports" <| [ inputs.qstn.nixosModules.default ] diff --git a/common/editor.nix b/common/editor.nix index 8e2a95c..5f497e7 100644 --- a/common/editor.nix +++ b/common/editor.nix @@ -2,6 +2,7 @@ pkgs, lib, config, + scope, ... }: let diff --git a/common/nix/gc.nix b/common/nix/gc.nix index 41f90e2..135f7d9 100644 --- a/common/nix/gc.nix +++ b/common/nix/gc.nix @@ -8,7 +8,7 @@ inputs.angrr.nixosModules.angrr ]; nix = { - package = pkgs.nixVersions.nix_2_31; + package = pkgs.nixVersions.git; optimise = { automatic = true; dates = "weekly"; diff --git a/common/nix/managers.nix b/common/nix/managers.nix index 2f692a0..ceaecd8 100644 --- a/common/nix/managers.nix +++ b/common/nix/managers.nix @@ -1,4 +1,9 @@ -{ inputs, mainUser, ... }: +{ + inputs, + mainUser, + getFlakePkg, + ... +}: { imports = [ inputs.meat.nixosModules.meat @@ -6,6 +11,7 @@ programs.meat = { enable = true; flake = "/home/${mainUser}/.nix"; + monitor = getFlakePkg inputs.rom; }; # services.smooooth = { diff --git a/common/nix/nixpkgs.nix b/common/nix/nixpkgs.nix index 6fecf22..4506b9a 100644 --- a/common/nix/nixpkgs.nix +++ b/common/nix/nixpkgs.nix @@ -1,6 +1,7 @@ { inputs, lib, + scope, ... }: scope "nixpkgs" { diff --git a/common/nix/plugins.nix b/common/nix/plugins.nix deleted file mode 100644 index ddf05cc..0000000 --- a/common/nix/plugins.nix +++ /dev/null @@ -1,20 +0,0 @@ -{ - inputs, - getFlakePkg, - config, - ... -}: -{ - imports = [ - inputs.nix-shorturl-plugin.nixosModules.default - inputs.nix-scope-plugin.nixosModules.default - ]; - nix.shorturls = { - enable = true; - schemes = { - atagen = "git+https://git.lobotomise.me/atagen/{path}"; - amaan = "github:amaanq/{path}"; - kosslan = "git+ssh://git@git.kosslan.dev/{path}"; - }; - }; -} diff --git a/common/nix/settings.nix b/common/nix/settings.nix index 1786090..4cdf353 100644 --- a/common/nix/settings.nix +++ b/common/nix/settings.nix @@ -1,10 +1,4 @@ -{ - pkgs, - inputs, - getFlakePkg', - ... -}: -{ +_: { nix = { settings = { experimental-features = [ diff --git a/common/nix/substituters.nix b/common/nix/substituters.nix index f0d5d58..65b96bb 100644 --- a/common/nix/substituters.nix +++ b/common/nix/substituters.nix @@ -1,4 +1,5 @@ { + scope, ... }: scope "nix.settings" { diff --git a/common/nix/tools.nix b/common/nix/tools.nix index 776148a..8604bff 100644 --- a/common/nix/tools.nix +++ b/common/nix/tools.nix @@ -1,14 +1,12 @@ { pkgs, inputs, - getFlakePkg, ... }: { - environment.systemPackages = [ - pkgs.nixfmt - (getFlakePkg inputs.yoke) - (getFlakePkg inputs.nil) + environment.systemPackages = with pkgs; [ + nixfmt + nil ]; imports = [ inputs.nix-index-database.nixosModules.nix-index diff --git a/common/security.nix b/common/security.nix index 0b19f74..e8a81af 100644 --- a/common/security.nix +++ b/common/security.nix @@ -7,7 +7,6 @@ { imports = [ inputs.run0-shim.nixosModules.default - inputs.yoke.nixosModules.default ]; environment.shellAliases = { #make run0 use aliases diff --git a/common/systemd.nix b/common/systemd.nix index 67a768a..eeb770e 100644 --- a/common/systemd.nix +++ b/common/systemd.nix @@ -1,4 +1,4 @@ -{ ... }: +{ scope, ... }: scope "systemd" { services."user@".serviceConfig.Delegate = "memory pids cpu cpuset"; user.extraConfig = "LogLevel=debug"; diff --git a/common/terminal.nix b/common/terminal.nix index 0511fae..4272aa7 100644 --- a/common/terminal.nix +++ b/common/terminal.nix @@ -245,6 +245,11 @@ let git push --force } + def activate [p: path] { + sudo nix-env --set -p /nix/var/nix/profiles/system $p + sudo $"$(p)/bin/switch-to-configuration" switch + } + # direnv $env.config = ($env.config? | default {}) $env.config.hooks = ($env.config.hooks? | default {}) diff --git a/flake.lock b/flake.lock deleted file mode 100644 index c06e08a..0000000 --- a/flake.lock +++ /dev/null @@ -1,1286 +0,0 @@ -{ - "nodes": { - "__flake-compat": { - "flake": false, - "locked": { - "lastModified": 1751685974, - "narHash": "sha256-NKw96t+BgHIYzHUjkTK95FqYRVKB8DHpVhefWSz/kTw=", - "ref": "refs/heads/main", - "rev": "549f2762aebeff29a2e5ece7a7dc0f955281a1d1", - "revCount": 92, - "type": "git", - "url": "https://git.lix.systems/lix-project/flake-compat.git" - }, - "original": { - "type": "git", - "url": "https://git.lix.systems/lix-project/flake-compat.git" - } - }, - "angrr": { - "inputs": { - "flake-compat": "flake-compat", - "flake-parts": "flake-parts", - "nix-darwin": "nix-darwin", - "nixpkgs": "nixpkgs", - "treefmt-nix": "treefmt-nix" - }, - "locked": { - "lastModified": 1776730547, - "narHash": "sha256-X0ZdetAsg4TaoKm6wGyzaZ/X2TlQFWQLHAUaMWDr+7A=", - "owner": "linyinfeng", - "repo": "angrr", - "rev": "bb5cdadcce3e4406fbf79e7f3bcfea59794075cf", - "type": "github" - }, - "original": { - "owner": "linyinfeng", - "repo": "angrr", - "type": "github" - } - }, - "arbys": { - "locked": { - "lastModified": 1756449827, - "narHash": "sha256-Z/O9W0A0SG/cZiiviNPfmciqvI6a3giCLFt/ElwtLCs=", - "ref": "refs/heads/meats", - "rev": "cc1e2613fbbb0ed98bb4ce0d52c6e99bb8f98055", - "revCount": 9, - "type": "git", - "url": "https://git.lobotomise.me/atagen/arbys" - }, - "original": { - "type": "git", - "url": "https://git.lobotomise.me/atagen/arbys" - } - }, - "bunker": { - "inputs": { - "nixpkgs": "nixpkgs_2" - }, - "locked": { - "lastModified": 1777267575, - "narHash": "sha256-58VFXbVR76Lk96qIXU4zkyQgBUVm25kShazR5uSfQgQ=", - "owner": "amaanq", - "repo": "bunker-patches", - "rev": "27bf12d2e5e17d8932d9c043a605d8733a167b6c", - "type": "github" - }, - "original": { - "owner": "amaanq", - "repo": "bunker-patches", - "type": "github" - } - }, - "crane": { - "locked": { - "lastModified": 1775839657, - "narHash": "sha256-SPm9ck7jh3Un9nwPuMGbRU04UroFmOHjLP56T10MOeM=", - "owner": "ipetkov", - "repo": "crane", - "rev": "7cf72d978629469c4bd4206b95c402514c1f6000", - "type": "github" - }, - "original": { - "owner": "ipetkov", - "repo": "crane", - "type": "github" - } - }, - "crane_2": { - "locked": { - "lastModified": 1776635034, - "narHash": "sha256-OEOJrT3ZfwbChzODfIH4GzlNTtOFuZFWPtW7jIeR8xU=", - "owner": "ipetkov", - "repo": "crane", - "rev": "dc7496d8ea6e526b1254b55d09b966e94673750f", - "type": "github" - }, - "original": { - "owner": "ipetkov", - "repo": "crane", - "type": "github" - } - }, - "fenix": { - "inputs": { - "nixpkgs": [ - "niri-tag", - "naersk", - "nixpkgs" - ], - "rust-analyzer-src": "rust-analyzer-src" - }, - "locked": { - "lastModified": 1752475459, - "narHash": "sha256-z6QEu4ZFuHiqdOPbYss4/Q8B0BFhacR8ts6jO/F/aOU=", - "owner": "nix-community", - "repo": "fenix", - "rev": "bf0d6f70f4c9a9cf8845f992105652173f4b617f", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "fenix", - "type": "github" - } - }, - "flake-compat": { - "flake": false, - "locked": { - "lastModified": 1767039857, - "narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab", - "type": "github" - }, - "original": { - "owner": "edolstra", - "repo": "flake-compat", - "type": "github" - } - }, - "flake-compat_2": { - "flake": false, - "locked": { - "lastModified": 1767039857, - "narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=", - "owner": "NixOS", - "repo": "flake-compat", - "rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab", - "type": "github" - }, - "original": { - "owner": "NixOS", - "repo": "flake-compat", - "type": "github" - } - }, - "flake-parts": { - "inputs": { - "nixpkgs-lib": [ - "angrr", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1775087534, - "narHash": "sha256-91qqW8lhL7TLwgQWijoGBbiD4t7/q75KTi8NxjVmSmA=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "3107b77cd68437b9a76194f0f7f9c55f2329ca5b", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "flake-parts", - "type": "github" - } - }, - "flake-parts_2": { - "inputs": { - "nixpkgs-lib": [ - "nix-rice", - "nixpkgs-lib" - ] - }, - "locked": { - "lastModified": 1768135262, - "narHash": "sha256-PVvu7OqHBGWN16zSi6tEmPwwHQ4rLPU9Plvs8/1TUBY=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "80daad04eddbbf5a4d883996a73f3f542fa437ac", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "flake-parts", - "type": "github" - } - }, - "git-hooks-nix": { - "inputs": { - "flake-compat": "flake-compat_2", - "gitignore": "gitignore", - "nixpkgs": [ - "nix-rice", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1767281941, - "narHash": "sha256-6MkqajPICgugsuZ92OMoQcgSHnD6sJHwk8AxvMcIgTE=", - "owner": "cachix", - "repo": "git-hooks.nix", - "rev": "f0927703b7b1c8d97511c4116eb9b4ec6645a0fa", - "type": "github" - }, - "original": { - "owner": "cachix", - "repo": "git-hooks.nix", - "type": "github" - } - }, - "gitignore": { - "inputs": { - "nixpkgs": [ - "nix-rice", - "git-hooks-nix", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1709087332, - "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", - "owner": "hercules-ci", - "repo": "gitignore.nix", - "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "gitignore.nix", - "type": "github" - } - }, - "helium": { - "inputs": { - "nixpkgs": "nixpkgs_3" - }, - "locked": { - "lastModified": 1776646564, - "narHash": "sha256-/v9Hy6wnIu4RIEOkzL6Wy1WpBDkst9GMn+hXJLC2C7U=", - "owner": "amaanq", - "repo": "helium-flake", - "rev": "a7c9452dbc7977c35409aeff4eb71c8730e1e466", - "type": "github" - }, - "original": { - "owner": "amaanq", - "repo": "helium-flake", - "type": "github" - } - }, - "hudcore": { - "inputs": { - "nix-systems": "nix-systems", - "nixpkgs": "nixpkgs_4" - }, - "locked": { - "lastModified": 1774692528, - "narHash": "sha256-AI72zuAQBSYETn/dhN8qN8Hdts8PWnSDLEgAxMSZ+CU=", - "ref": "refs/heads/main", - "rev": "6555d555797bf1960bd89e76a53e0240b6a93df9", - "revCount": 1, - "type": "git", - "url": "https://git.lobotomise.me/atagen/hudcore-plymouth" - }, - "original": { - "type": "git", - "url": "https://git.lobotomise.me/atagen/hudcore-plymouth" - } - }, - "inshellah": { - "inputs": { - "nixpkgs": [ - "bunker", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1774774137, - "narHash": "sha256-5HeZobkuaeqFmGKr1sh7mcpBi7qs4z5bpdPYyyRgmU0=", - "ref": "refs/heads/main", - "rev": "9dd1261a4602a20cc9c6e8a450493e909c20f585", - "revCount": 10, - "type": "git", - "url": "https://git.lobotomise.me/atagen/inshellah" - }, - "original": { - "type": "git", - "url": "https://git.lobotomise.me/atagen/inshellah" - } - }, - "kitty-themes-src": { - "flake": false, - "locked": { - "lastModified": 1768000027, - "narHash": "sha256-jefF6MzFbKDz6Grsdh5fyi/hrZI72mNkp5iUvelIhDs=", - "owner": "kovidgoyal", - "repo": "kitty-themes", - "rev": "0da136b4d31ab1c0dc49306bbf2ba8b819dafed8", - "type": "github" - }, - "original": { - "owner": "kovidgoyal", - "repo": "kitty-themes", - "type": "github" - } - }, - "meat": { - "inputs": { - "nix-systems": "nix-systems_2", - "nixpkgs": [ - "bunker", - "nixpkgs" - ], - "unf": "unf" - }, - "locked": { - "lastModified": 1774349585, - "narHash": "sha256-bLWGWLCE1yn1/rMl/EvnJpjji3Rm+/uYvfqOk1Crbdg=", - "ref": "refs/heads/master", - "rev": "945892f51d84d2c77d8b831e4ce8afa33117419f", - "revCount": 43, - "type": "git", - "url": "https://git.lobotomise.me/atagen/meat" - }, - "original": { - "type": "git", - "url": "https://git.lobotomise.me/atagen/meat" - } - }, - "naersk": { - "inputs": { - "fenix": "fenix", - "nixpkgs": "nixpkgs_8" - }, - "locked": { - "lastModified": 1768908532, - "narHash": "sha256-HIdLXEFaUVE8FiaCPJbCfBMsnF+mVtDub8Jwj2BD+mk=", - "owner": "nix-community", - "repo": "naersk", - "rev": "8d97452673640eb7fabe428e8b6a425bc355008b", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "naersk", - "type": "github" - } - }, - "ndg": { - "inputs": { - "nixpkgs": "nixpkgs_5" - }, - "locked": { - "lastModified": 1773478949, - "narHash": "sha256-8rMpSs2OWGaDlDFO5FS6Pf9WutHBXxM2omPr6hfKydI=", - "owner": "feel-co", - "repo": "ndg", - "rev": "c3bc1541668e6f6632a7005c7e4963c0a5dedc7b", - "type": "github" - }, - "original": { - "owner": "feel-co", - "repo": "ndg", - "type": "github" - } - }, - "nil": { - "inputs": { - "nixpkgs": [ - "bunker", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1772014815, - "narHash": "sha256-er96DK9KxsSU2RE3jCvZNquvby8YzMBEygPuznZvnn8=", - "owner": "atagen", - "repo": "nil", - "rev": "f5dc3f3239f64904d901a537bd88bafe5735aa0a", - "type": "github" - }, - "original": { - "owner": "atagen", - "repo": "nil", - "type": "github" - } - }, - "niri": { - "inputs": { - "niri-stable": "niri-stable", - "niri-unstable": "niri-unstable", - "nixpkgs": "nixpkgs_7", - "nixpkgs-stable": "nixpkgs-stable", - "xwayland-satellite-stable": "xwayland-satellite-stable", - "xwayland-satellite-unstable": "xwayland-satellite-unstable" - }, - "locked": { - "lastModified": 1776879043, - "narHash": "sha256-M9RjuowtoqQbFRdQAm2P6GjFwgHjRcnWYcB7ChSjDms=", - "owner": "sodiboo", - "repo": "niri-flake", - "rev": "535ebbe038039215a5d1c6c0c67f833409a5be96", - "type": "github" - }, - "original": { - "owner": "sodiboo", - "repo": "niri-flake", - "type": "github" - } - }, - "niri-s76": { - "locked": { - "lastModified": 1771162707, - "narHash": "sha256-UicMzXYy2XE5jr2J7IO6pZTXUNPndPrGHSIIN6+fB1E=", - "ref": "refs/heads/main", - "rev": "e3afb85f23c0e59b2a818094ee7b391ca2f3504d", - "revCount": 2, - "type": "git", - "url": "https://git.lobotomise.me/atagen/niri-s76-bridge" - }, - "original": { - "type": "git", - "url": "https://git.lobotomise.me/atagen/niri-s76-bridge" - } - }, - "niri-stable": { - "flake": false, - "locked": { - "lastModified": 1756556321, - "narHash": "sha256-RLD89dfjN0RVO86C/Mot0T7aduCygPGaYbog566F0Qo=", - "owner": "YaLTeR", - "repo": "niri", - "rev": "01be0e65f4eb91a9cd624ac0b76aaeab765c7294", - "type": "github" - }, - "original": { - "owner": "YaLTeR", - "ref": "v25.08", - "repo": "niri", - "type": "github" - } - }, - "niri-tag": { - "inputs": { - "naersk": "naersk", - "niri": "niri_2", - "nixpkgs": [ - "bunker", - "nixpkgs" - ], - "systems": "systems" - }, - "locked": { - "lastModified": 1772457471, - "narHash": "sha256-y5KsYbzC3MLKr+2M1792jxs3//uV8x9kG+G0LA7cycg=", - "ref": "refs/heads/main", - "rev": "785619920b8ae1dd147da795cc7e703c3367c34a", - "revCount": 44, - "type": "git", - "url": "https://git.lobotomise.me/atagen/niri-tag" - }, - "original": { - "type": "git", - "url": "https://git.lobotomise.me/atagen/niri-tag" - } - }, - "niri-unstable": { - "flake": false, - "locked": { - "lastModified": 1776853441, - "narHash": "sha256-mSxfoEs7DiDhMCBzprI/1K7UXzMISuGq0b7T06LVJXE=", - "owner": "YaLTeR", - "repo": "niri", - "rev": "74d2b18603366b98ec9045ecf4a632422f472365", - "type": "github" - }, - "original": { - "owner": "YaLTeR", - "repo": "niri", - "type": "github" - } - }, - "niri_2": { - "flake": false, - "locked": { - "lastModified": 1768678265, - "narHash": "sha256-Ub8eed4DsfIDWyg30xEe+8bSxL/z5Af/gCjmvJ0V/Hs=", - "owner": "YaLTeR", - "repo": "niri", - "rev": "d7184a04b904e07113f4623610775ae78d32394c", - "type": "github" - }, - "original": { - "owner": "YaLTeR", - "repo": "niri", - "type": "github" - } - }, - "nix-darwin": { - "inputs": { - "nixpkgs": [ - "angrr", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1775037210, - "narHash": "sha256-KM2WYj6EA7M/FVZVCl3rqWY+TFV5QzSyyGE2gQxeODU=", - "owner": "nix-darwin", - "repo": "nix-darwin", - "rev": "06648f4902343228ce2de79f291dd5a58ee12146", - "type": "github" - }, - "original": { - "owner": "nix-darwin", - "repo": "nix-darwin", - "type": "github" - } - }, - "nix-github-actions": { - "inputs": { - "nixpkgs": [ - "run0-shim", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1737420293, - "narHash": "sha256-F1G5ifvqTpJq7fdkT34e/Jy9VCyzd5XfJ9TO8fHhJWE=", - "owner": "nix-community", - "repo": "nix-github-actions", - "rev": "f4158fa080ef4503c8f4c820967d946c2af31ec9", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "nix-github-actions", - "type": "github" - } - }, - "nix-index-database": { - "inputs": { - "nixpkgs": "nixpkgs_9" - }, - "locked": { - "lastModified": 1776829403, - "narHash": "sha256-oHVcvP2Ahhj1KUsEzp+2BQF55/r5VSa3QxdPdwE1p00=", - "owner": "Mic92", - "repo": "nix-index-database", - "rev": "c43246d4e9e506178b69baed075d797ec2d873e2", - "type": "github" - }, - "original": { - "owner": "Mic92", - "repo": "nix-index-database", - "type": "github" - } - }, - "nix-rice": { - "inputs": { - "flake-parts": "flake-parts_2", - "git-hooks-nix": "git-hooks-nix", - "kitty-themes-src": "kitty-themes-src", - "nixpkgs": "nixpkgs_10", - "nixpkgs-lib": "nixpkgs-lib", - "systems": "systems_2" - }, - "locked": { - "lastModified": 1768817933, - "narHash": "sha256-nt/xmuXaJB/vWlRJ4wpdlYQCIgCzFR6QJwlRyhfNn5o=", - "owner": "bertof", - "repo": "nix-rice", - "rev": "98b16b0f649bb41db9a1c3b32191bccb9a1ec271", - "type": "github" - }, - "original": { - "owner": "bertof", - "repo": "nix-rice", - "type": "github" - } - }, - "nix-scope-plugin": { - "inputs": { - "nixpkgs": [ - "bunker", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1776947301, - "narHash": "sha256-9jl+jsqh16I4hgjqV2YTuIQivjNBY9yW6Z2vhh9H1tk=", - "ref": "refs/heads/main", - "rev": "70b537244df3f83523e82629b3c8cc1b0dea9c55", - "revCount": 4, - "type": "git", - "url": "https://git.lobotomise.me/atagen/nix-scope-plugin" - }, - "original": { - "type": "git", - "url": "https://git.lobotomise.me/atagen/nix-scope-plugin" - } - }, - "nix-shorturl-plugin": { - "inputs": { - "nixpkgs": [ - "bunker", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1776947322, - "narHash": "sha256-99Lh4XMng3ZbUFw2ISrS8ax/Q7E1fD8KGX4AA6odk48=", - "ref": "refs/heads/main", - "rev": "7fbcc8744d68f74a7439957fbc1d7eb8668c024d", - "revCount": 4, - "type": "git", - "url": "https://git.lobotomise.me/atagen/nix-shorturl-plugin" - }, - "original": { - "type": "git", - "url": "https://git.lobotomise.me/atagen/nix-shorturl-plugin" - } - }, - "nix-systems": { - "locked": { - "lastModified": 1689347949, - "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=", - "owner": "nix-systems", - "repo": "default-linux", - "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default-linux", - "type": "github" - } - }, - "nix-systems_2": { - "locked": { - "lastModified": 1689347949, - "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=", - "owner": "nix-systems", - "repo": "default-linux", - "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default-linux", - "type": "github" - } - }, - "nixos-core": { - "inputs": { - "nixpkgs": [ - "bunker", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1776982365, - "narHash": "sha256-3KuTDkbIZsv/luigCj4dHi+3a5dQRmDV8j1zYyE0A1Q=", - "owner": "feel-co", - "repo": "nixos-core", - "rev": "c8297e1d2acadc1e690b7875f408a60c04c6d01a", - "type": "github" - }, - "original": { - "owner": "feel-co", - "repo": "nixos-core", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1776548001, - "narHash": "sha256-ZSK0NL4a1BwVbbTBoSnWgbJy9HeZFXLYQizjb2DPF24=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "b12141ef619e0a9c1c84dc8c684040326f27cdcc", - "type": "github" - }, - "original": { - "owner": "nixos", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs-lib": { - "locked": { - "lastModified": 1768699094, - "narHash": "sha256-uapeGJTPPbmqjdo5zlrWFEIys1XIOQ66sKP3A5UNEOk=", - "owner": "nix-community", - "repo": "nixpkgs.lib", - "rev": "78975aaec5a67ea502e15836919b89d7df96ac27", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "nixpkgs.lib", - "type": "github" - } - }, - "nixpkgs-stable": { - "locked": { - "lastModified": 1776734388, - "narHash": "sha256-vl3dkhlE5gzsItuHoEMVe+DlonsK+0836LIRDnm6MXQ=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "10e7ad5bbcb421fe07e3a4ad53a634b0cd57ffac", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-25.11", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs-stable_2": { - "locked": { - "lastModified": 1776734388, - "narHash": "sha256-vl3dkhlE5gzsItuHoEMVe+DlonsK+0836LIRDnm6MXQ=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "10e7ad5bbcb421fe07e3a4ad53a634b0cd57ffac", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-25.11", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_10": { - "locked": { - "lastModified": 1768810879, - "narHash": "sha256-6RrqzfHu3e4vvRaDRY0muyl/BkFzCEPfwXmYY8iRjSw=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "0ef1c5b62bec8b182affa76ff079d80a2ba026ba", - "type": "github" - }, - "original": { - "owner": "nixos", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_11": { - "locked": { - "lastModified": 1775710090, - "narHash": "sha256-ar3rofg+awPB8QXDaFJhJ2jJhu+KqN/PRCXeyuXR76E=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "4c1018dae018162ec878d42fec712642d214fdfa", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_12": { - "locked": { - "lastModified": 1766651565, - "narHash": "sha256-QEhk0eXgyIqTpJ/ehZKg9IKS7EtlWxF3N7DXy42zPfU=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "3e2499d5539c16d0d173ba53552a4ff8547f4539", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_13": { - "locked": { - "lastModified": 1775350496, - "narHash": "sha256-uuw97G2Qm6C7rdrkq4zBzwLo0oA35flYijyMy65w/8c=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "9341c707a0f78d80c73e1b403d98d728eda607ac", - "type": "github" - }, - "original": { - "owner": "NixOS", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_2": { - "locked": { - "lastModified": 1776877367, - "narHash": "sha256-wMN1gM00sUQ2KC9CNr/XEOGdfOrl67PabIRv9AYayTo=", - "rev": "0726a0ecb6d4e08f6adced58726b95db924cef57", - "type": "tarball", - "url": "https://releases.nixos.org/nixos/unstable/nixos-26.05pre985613.0726a0ecb6d4/nixexprs.tar.xz" - }, - "original": { - "type": "tarball", - "url": "https://channels.nixos.org/nixos-unstable/nixexprs.tar.xz" - } - }, - "nixpkgs_3": { - "locked": { - "lastModified": 1770562336, - "narHash": "sha256-ub1gpAONMFsT/GU2hV6ZWJjur8rJ6kKxdm9IlCT0j84=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "d6c71932130818840fc8fe9509cf50be8c64634f", - "type": "github" - }, - "original": { - "owner": "nixos", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_4": { - "locked": { - "lastModified": 1746397377, - "narHash": "sha256-5oLdRa3vWSRbuqPIFFmQBGGUqaYZBxX+GGtN9f/n4lU=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "ed30f8aba41605e3ab46421e3dcb4510ec560ff8", - "type": "github" - }, - "original": { - "owner": "nixos", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_5": { - "locked": { - "lastModified": 1773282481, - "narHash": "sha256-oFe06TmOy8UUT1f7xMHqDpSYq2Fy1mkIsXZUvdnyfeY=", - "rev": "fe416aaedd397cacb33a610b33d60ff2b431b127", - "type": "tarball", - "url": "https://releases.nixos.org/nixos/unstable/nixos-26.05pre962285.fe416aaedd39/nixexprs.tar.xz?lastModified=1773282481&rev=fe416aaedd397cacb33a610b33d60ff2b431b127" - }, - "original": { - "type": "tarball", - "url": "https://channels.nixos.org/nixos-unstable/nixexprs.tar.xz" - } - }, - "nixpkgs_6": { - "locked": { - "lastModified": 1774078191, - "narHash": "sha256-nyxxxW1/2ouu9dU0I02ul5pHrmUrE1JVFhfFlmYe3Lw=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "09061f748ee21f68a089cd5d91ec1859cd93d0be", - "type": "github" - }, - "original": { - "owner": "nixos", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_7": { - "locked": { - "lastModified": 1776548001, - "narHash": "sha256-ZSK0NL4a1BwVbbTBoSnWgbJy9HeZFXLYQizjb2DPF24=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "b12141ef619e0a9c1c84dc8c684040326f27cdcc", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_8": { - "locked": { - "lastModified": 1752077645, - "narHash": "sha256-HM791ZQtXV93xtCY+ZxG1REzhQenSQO020cu6rHtAPk=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "be9e214982e20b8310878ac2baa063a961c1bdf6", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_9": { - "locked": { - "lastModified": 1776169885, - "narHash": "sha256-l/iNYDZ4bGOAFQY2q8y5OAfBBtrDAaPuRQqWaFHVRXM=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "4bd9165a9165d7b5e33ae57f3eecbcb28fb231c9", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "qstn": { - "inputs": { - "nixpkgs": [ - "bunker", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1767007132, - "narHash": "sha256-0tMAB3gHKG32A4z/hM7aWNU2t+jh1zT4dpoamcHucog=", - "ref": "refs/heads/main", - "rev": "e6570c79145f3190ff93cb2036ae963a8643445f", - "revCount": 2, - "type": "git", - "url": "https://git.lobotomise.me/atagen/qstn" - }, - "original": { - "type": "git", - "url": "https://git.lobotomise.me/atagen/qstn" - } - }, - "qtengine": { - "inputs": { - "nixpkgs": [ - "bunker", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1772766331, - "narHash": "sha256-aJ5ZdIX10nmhzMLjP6QMuFJHvljJD+xcojuKZjPkr70=", - "owner": "kossLAN", - "repo": "qtengine", - "rev": "abf8c1d3068dd10739b0671fa62f96c5347f276f", - "type": "github" - }, - "original": { - "owner": "kossLAN", - "repo": "qtengine", - "type": "github" - } - }, - "root": { - "inputs": { - "__flake-compat": "__flake-compat", - "angrr": "angrr", - "arbys": "arbys", - "bunker": "bunker", - "helium": "helium", - "hudcore": "hudcore", - "inshellah": "inshellah", - "meat": "meat", - "nil": "nil", - "niri": "niri", - "niri-s76": "niri-s76", - "niri-tag": "niri-tag", - "nix-index-database": "nix-index-database", - "nix-rice": "nix-rice", - "nix-scope-plugin": "nix-scope-plugin", - "nix-shorturl-plugin": "nix-shorturl-plugin", - "nixos-core": "nixos-core", - "nixpkgs": [ - "bunker", - "nixpkgs" - ], - "nixpkgs-stable": "nixpkgs-stable_2", - "qstn": "qstn", - "qtengine": "qtengine", - "run0-shim": "run0-shim", - "stash": "stash", - "tuigreet": "tuigreet", - "wry": "wry", - "yoke": "yoke" - } - }, - "run0-shim": { - "inputs": { - "nix-github-actions": "nix-github-actions", - "nixpkgs": [ - "bunker", - "nixpkgs" - ], - "treefmt-nix": "treefmt-nix_2" - }, - "locked": { - "lastModified": 1774702115, - "narHash": "sha256-iZ0HSQwjr9nYpVn10ZI4zQTdqvSggfxhXZ1c4oSZnuc=", - "owner": "lordgrimmauld", - "repo": "run0-sudo-shim", - "rev": "c9e06e2f220ab2fcf2228d4315c0a7fc2dc6e438", - "type": "github" - }, - "original": { - "owner": "lordgrimmauld", - "repo": "run0-sudo-shim", - "type": "github" - } - }, - "rust-analyzer-src": { - "flake": false, - "locked": { - "lastModified": 1752428706, - "narHash": "sha256-EJcdxw3aXfP8Ex1Nm3s0awyH9egQvB2Gu+QEnJn2Sfg=", - "owner": "rust-lang", - "repo": "rust-analyzer", - "rev": "591e3b7624be97e4443ea7b5542c191311aa141d", - "type": "github" - }, - "original": { - "owner": "rust-lang", - "ref": "nightly", - "repo": "rust-analyzer", - "type": "github" - } - }, - "rust-overlay": { - "inputs": { - "nixpkgs": [ - "tuigreet", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1776654897, - "narHash": "sha256-Vqi4AiJVCcBGn/RmBtRCgyH5rCxqm/w0xV9diJWF1Ic=", - "owner": "oxalica", - "repo": "rust-overlay", - "rev": "25d75be8139815a53560745fa060909777495105", - "type": "github" - }, - "original": { - "owner": "oxalica", - "repo": "rust-overlay", - "type": "github" - } - }, - "stash": { - "inputs": { - "crane": "crane", - "nixpkgs": "nixpkgs_11" - }, - "locked": { - "lastModified": 1776783630, - "narHash": "sha256-FxNTnfZTH96ptne2wH5N4DzctdTHy75cPepZaVNQwck=", - "owner": "notashelf", - "repo": "stash", - "rev": "4d3c99368fdb9373f0d7423de1a9642ae0c11745", - "type": "github" - }, - "original": { - "owner": "notashelf", - "repo": "stash", - "type": "github" - } - }, - "systems": { - "locked": { - "lastModified": 1689347949, - "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=", - "owner": "nix-systems", - "repo": "default-linux", - "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default-linux", - "type": "github" - } - }, - "systems_2": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - }, - "systems_3": { - "locked": { - "lastModified": 1689347949, - "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=", - "owner": "nix-systems", - "repo": "default-linux", - "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default-linux", - "type": "github" - } - }, - "treefmt-nix": { - "inputs": { - "nixpkgs": [ - "angrr", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1775636079, - "narHash": "sha256-pc20NRoMdiar8oPQceQT47UUZMBTiMdUuWrYu2obUP0=", - "owner": "numtide", - "repo": "treefmt-nix", - "rev": "790751ff7fd3801feeaf96d7dc416a8d581265ba", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "treefmt-nix", - "type": "github" - } - }, - "treefmt-nix_2": { - "inputs": { - "nixpkgs": [ - "run0-shim", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1773297127, - "narHash": "sha256-6E/yhXP7Oy/NbXtf1ktzmU8SdVqJQ09HC/48ebEGBpk=", - "owner": "numtide", - "repo": "treefmt-nix", - "rev": "71b125cd05fbfd78cab3e070b73544abe24c5016", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "treefmt-nix", - "type": "github" - } - }, - "tuigreet": { - "inputs": { - "crane": "crane_2", - "nixpkgs": "nixpkgs_12", - "rust-overlay": "rust-overlay" - }, - "locked": { - "lastModified": 1777107181, - "narHash": "sha256-zC0gTr/Rlz0lPH+LiH/UAeZgzLqr2Az270CB0xERGbI=", - "path": "/home/bolt/code/etc/tuigreet", - "type": "path" - }, - "original": { - "path": "/home/bolt/code/etc/tuigreet", - "type": "path" - } - }, - "unf": { - "inputs": { - "ndg": "ndg", - "nixpkgs": "nixpkgs_6" - }, - "locked": { - "lastModified": 1760178630, - "narHash": "sha256-oxRMTQtzIO1yFRhY++Ss8+ea1cTH40bD/+FAE+m5NFk=", - "ref": "refs/heads/main", - "rev": "8a6aa536039f1b207888b1369c5cabf0b131e07b", - "revCount": 5, - "type": "git", - "url": "https://git.atagen.co/atagen/unf" - }, - "original": { - "type": "git", - "url": "https://git.atagen.co/atagen/unf" - } - }, - "wry": { - "inputs": { - "nixpkgs": "nixpkgs_13" - }, - "locked": { - "lastModified": 1776171180, - "narHash": "sha256-hmf6U/73HgOgigs26zcpfVCQEZTDNWBi7whDNcYpBXo=", - "path": "/home/bolt/code/wry", - "type": "path" - }, - "original": { - "path": "/home/bolt/code/wry", - "type": "path" - } - }, - "xwayland-satellite-stable": { - "flake": false, - "locked": { - "lastModified": 1755491097, - "narHash": "sha256-m+9tUfsmBeF2Gn4HWa6vSITZ4Gz1eA1F5Kh62B0N4oE=", - "owner": "Supreeeme", - "repo": "xwayland-satellite", - "rev": "388d291e82ffbc73be18169d39470f340707edaa", - "type": "github" - }, - "original": { - "owner": "Supreeeme", - "ref": "v0.7", - "repo": "xwayland-satellite", - "type": "github" - } - }, - "xwayland-satellite-unstable": { - "flake": false, - "locked": { - "lastModified": 1773622265, - "narHash": "sha256-wToKwH7IgWdGLMSIWksEDs4eumR6UbbsuPQ42r0oTXQ=", - "owner": "Supreeeme", - "repo": "xwayland-satellite", - "rev": "a879e5e0896a326adc79c474bf457b8b99011027", - "type": "github" - }, - "original": { - "owner": "Supreeeme", - "repo": "xwayland-satellite", - "type": "github" - } - }, - "yoke": { - "inputs": { - "nixpkgs": [ - "bunker", - "nixpkgs" - ], - "systems": "systems_3" - }, - "locked": { - "lastModified": 1772106982, - "narHash": "sha256-XyHN0Wl9dxknzsAR8c/Ce3BjtqbNhv11xIRG0KeEvm4=", - "ref": "refs/heads/main", - "rev": "bf06ab5fe821bfa033c290f49949b8adffbef56e", - "revCount": 12, - "type": "git", - "url": "https://git.lobotomise.me/atagen/yoke" - }, - "original": { - "type": "git", - "url": "https://git.lobotomise.me/atagen/yoke" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/flake.nix b/flake.nix deleted file mode 100644 index f17ca9c..0000000 --- a/flake.nix +++ /dev/null @@ -1,100 +0,0 @@ -{ - description = "nixos config"; - - outputs = _: { }; - - inputs = { - # nixpkgs.url = "github:NixOS/nixpkgs"; - nixpkgs.follows = "bunker/nixpkgs"; - nixpkgs-stable.url = "github:NixOS/nixpkgs/nixos-25.11"; - - nix-index-database.url = "github:Mic92/nix-index-database"; - - nix-rice.url = "github:bertof/nix-rice"; - - meat = { - url = "atagen:meat"; - inputs.nixpkgs.follows = "bunker/nixpkgs"; - }; - - hudcore.url = "atagen:hudcore-plymouth"; - niri.url = "github:sodiboo/niri-flake"; - - niri-tag = { - url = "atagen:niri-tag"; - inputs.nixpkgs.follows = "bunker/nixpkgs"; - }; - - angrr.url = "github:linyinfeng/angrr"; - - arbys.url = "atagen:arbys"; - - qstn = { - url = "atagen:qstn"; - inputs.nixpkgs.follows = "bunker/nixpkgs"; - }; - - __flake-compat = { - url = "git+https://git.lix.systems/lix-project/flake-compat.git"; - flake = false; - }; - - yoke = { - url = "atagen:yoke"; - inputs.nixpkgs.follows = "bunker/nixpkgs"; - }; - - run0-shim = { - url = "github:lordgrimmauld/run0-sudo-shim"; - inputs.nixpkgs.follows = "bunker/nixpkgs"; - }; - - bunker.url = "amaan:bunker-patches"; - - niri-s76.url = "atagen:niri-s76-bridge"; - - helium.url = "amaan:helium-flake"; - - nil = { - url = "github:atagen/nil"; - inputs.nixpkgs.follows = "bunker/nixpkgs"; - }; - - nix-scope-plugin = { - url = "atagen:nix-scope-plugin"; - inputs.nixpkgs.follows = "bunker/nixpkgs"; - }; - - nix-shorturl-plugin = { - url = "atagen:nix-shorturl-plugin"; - inputs.nixpkgs.follows = "bunker/nixpkgs"; - }; - - stash.url = "github:notashelf/stash"; - wry = { - # url = "kosslan:wry/jay"; - url = "path:/home/bolt/code/wry"; - # inputs.nixpkgs.follows = "bunker/nixpkgs"; - }; - - # tuigreet.url = "github:notashelf/tuigreet"; - tuigreet.url = "path:/home/bolt/code/etc/tuigreet"; - - inshellah = { - url = "atagen:inshellah"; - inputs.nixpkgs.follows = "bunker/nixpkgs"; - }; - - qtengine = { - url = "github:kossLAN/qtengine"; - inputs.nixpkgs.follows = "bunker/nixpkgs"; - }; - - nixos-core = { - url = "github:feel-co/nixos-core"; - inputs.nixpkgs.follows = "bunker/nixpkgs"; - }; - - }; - -} diff --git a/graphical/binds.nix b/graphical/binds.nix index 4ad2f31..999ca46 100644 --- a/graphical/binds.nix +++ b/graphical/binds.nix @@ -1,6 +1,7 @@ { lib, config, + scope, ... }: let diff --git a/graphical/boot.nix b/graphical/boot.nix index 446cd6f..8afa616 100644 --- a/graphical/boot.nix +++ b/graphical/boot.nix @@ -2,6 +2,7 @@ config, machineName, mainUser, + scope, ... }: scope "boot" { @@ -18,7 +19,7 @@ scope "boot" { { wallpapers = [ config.rice.bg.src ]; interface = { - brandingColor = 1; + brandingColor = pal.normal.red; branding = "hello ${mainUser}. welcome to ${machineName}"; }; graphicalTerminal = diff --git a/graphical/browser.nix b/graphical/browser.nix index 809c439..86ed207 100644 --- a/graphical/browser.nix +++ b/graphical/browser.nix @@ -3,6 +3,7 @@ pkgs, inputs, getFlakePkg, + scope, ... }: let diff --git a/graphical/desktop/wry.nix b/graphical/desktop/wry.nix index d5831d2..daae455 100644 --- a/graphical/desktop/wry.nix +++ b/graphical/desktop/wry.nix @@ -3,6 +3,7 @@ pkgs, lib, getFlakePkg, + config, ... }: let @@ -16,18 +17,15 @@ let in { options.programs.wry = { + enable = lib.mkEnableOption "wry compositor"; package = lib.mkOption { type = lib.types.package; default = wry; }; }; - config = { - environment.systemPackages = [ wry ]; - services.greetd = { - enable = true; - settings.default_session.command = "${lib.getExe (getFlakePkg inputs.tuigreet)} --sessions /etc/greetd/wayland-sessions --remember-session --animation doom"; - }; + config = lib.mkIf (config.programs.wry.enable) { + environment.systemPackages = [ wry ]; environment.etc."greetd/wayland-sessions/wry.desktop".text = '' [Desktop Entry] diff --git a/graphical/documents.nix b/graphical/documents.nix index c07fe1a..857b1e2 100644 --- a/graphical/documents.nix +++ b/graphical/documents.nix @@ -2,6 +2,7 @@ pkgs, config, mkWrappers, + scope, ... }: let diff --git a/graphical/fm.nix b/graphical/fm.nix index 0500103..661f0c4 100644 --- a/graphical/fm.nix +++ b/graphical/fm.nix @@ -1,5 +1,6 @@ { pkgs, + scope, ... }: with pkgs; diff --git a/graphical/gfx-env.nix b/graphical/gfx-env.nix index a70e6cf..bd278eb 100644 --- a/graphical/gfx-env.nix +++ b/graphical/gfx-env.nix @@ -1,4 +1,4 @@ -{ ... }: +{ scope, ... }: scope "environment.sessionVariables" { NIXOS_OZONE_WL = "1"; GBM_BACKEND = "nvidia-drm"; diff --git a/graphical/hw.nix b/graphical/hw.nix index bff93ca..76b5b0f 100644 --- a/graphical/hw.nix +++ b/graphical/hw.nix @@ -1,4 +1,4 @@ -{ ... }: +{ scope, ... }: scope "hardware" { enableRedistributableFirmware = true; enableAllFirmware = true; diff --git a/graphical/kernel.nix b/graphical/kernel.nix index 22be143..f088b03 100644 --- a/graphical/kernel.nix +++ b/graphical/kernel.nix @@ -1,9 +1,8 @@ -{ ... }: +{ pkgs, ... }: { services.system76-scheduler.enable = true; - services.scx = { - enable = true; - scheduler = "scx_lavd"; - }; + boot.kernelPackages = pkgs.linuxPackages_xanmod_latest; + boot.kernelParams = [ "preempt=lazy" ]; + } diff --git a/graphical/llm/clod.nix b/graphical/llm/clod.nix new file mode 100644 index 0000000..8c9a468 --- /dev/null +++ b/graphical/llm/clod.nix @@ -0,0 +1,960 @@ +{ + lib, + mainUser, + pkgs, + ... +}: +let + inherit (lib) optionals; + inherit (lib.lists) singleton; + inherit (lib.meta) getExe getExe'; + inherit (lib.strings) toJSON; + + # Statusline: model, ctx %, in/out tokens, cache %, cost, timing, churn, + # cwd, usage quotas. Reads the harness JSON blob on stdin. + statusLine = pkgs.writeScriptBin "claude-code-statusline" /* nu */ '' + #!${getExe pkgs.nushell} + + def format-duration [ms: int] { + let total_s = $ms // 1000 + let h = $total_s // 3600 + let m = ($total_s mod 3600) // 60 + let s = $total_s mod 60 + if $h > 0 { + $"($h)h($m | fill -a r -w 2 -c '0')m($s | fill -a r -w 2 -c '0')s" + } else if $m > 0 { + $"($m)m($s | fill -a r -w 2 -c '0')s" + } else { + $"($s)s" + } + } + + def color-for-pct [pct: number] { + let pct_int = $pct | math floor | into int + if $pct_int >= 80 { + "\e[31m" + } else if $pct_int >= 50 { + "\e[33m" + } else { + "\e[32m" + } + } + + def format-rate-limits [input: record] { + let session_pct = try { $input | get rate_limits.five_hour.used_percentage } catch { null } + let week_pct = try { $input | get rate_limits.seven_day.used_percentage } catch { null } + + let session_part = if $session_pct != null { + let c = color-for-pct $session_pct + let v = $session_pct | math round --precision 0 | into int + $"session: ($c)($v)%\e[0m" + } else { "" } + let week_part = if $week_pct != null { + let c = color-for-pct $week_pct + let v = $week_pct | math round --precision 0 | into int + $"week: ($c)($v)%\e[0m" + } else { "" } + + [$session_part $week_part] | where {|x| $x | is-not-empty} | str join " " + } + + # --- Main --- + let input = (^cat | from json) + + let usage_info = format-rate-limits $input + + let model_name = ($input | get model?.display_name? | default ($input | get model?.id? | default "unknown")) + let used_pct = ($input | get context_window?.used_percentage? | default null) + let total_cost = ($input | get cost?.total_cost_usd? | default 0) + let total_input = ($input | get context_window?.s_in? | default ($input | get context_window?.total_input_tokens? | default 0)) + let total_output = ($input | get context_window?.s_out? | default ($input | get context_window?.total_output_tokens? | default 0)) + let duration_ms = ($input | get cost?.total_duration_ms? | default 0) + let api_duration_ms = ($input | get cost?.total_api_duration_ms? | default 0) + let lines_added = ($input | get cost?.total_lines_added? | default 0) + let lines_removed = ($input | get cost?.total_lines_removed? | default 0) + let exceeds_200k = ($input | get exceeds_200k_tokens? | default false) + + let cache_read = ($input | get context_window?.cache_read_tokens? | default 0) + let cache_create = ($input | get context_window?.cache_creation_tokens? | default 0) + + let total_tokens = $total_input + $total_output + + def format-tokens [n: int] { + if $n >= 1_000_000 { + $"($n / 1_000_000.0 | math round --precision 1)M" + } else if $n >= 1_000 { + $"($n / 1_000.0 | math round --precision 1)k" + } else { + $"($n)" + } + } + + let in_display = (format-tokens ($total_input | into int)) + let out_display = (format-tokens ($total_output | into int)) + let tok_display = $"($in_display)/($out_display)" + + let cache_total = $cache_read + $cache_create + let cache_display = if $cache_total > 0 { + let cache_pct = ($cache_read * 100 / $cache_total | math round --precision 0 | into int) + let cache_color = if $cache_pct >= 70 { + "\e[32m" + } else if $cache_pct >= 40 { + "\e[33m" + } else { + "\e[31m" + } + $" cache:($cache_color)($cache_pct)%\e[0m" + } else { "" } + + let context_display = if $used_pct != null { + let color = color-for-pct $used_pct + let pct_str = $used_pct | math round --precision 1 + $"($color)($pct_str)%\e[0m" + } else { "--" } + + let cost_cents = ($total_cost * 100 | math round | into int) + let cost_dollars = $cost_cents // 100 + let cost_frac = ($cost_cents mod 100 | math abs | into string | fill -a r -w 2 -c '0') + let cost_display = $"$($cost_dollars).($cost_frac)" + let elapsed_display = (format-duration ($duration_ms | into int)) + let wait_display = (format-duration ($api_duration_ms | into int)) + let churn_display = $"\e[32m+($lines_added)\e[0m/\e[31m-($lines_removed)\e[0m" + let marker_200k = if $exceeds_200k { " | \e[31m!200k\e[0m" } else { "" } + def format-cwd [dir: string] { + if ($dir | is-empty) { return "" } + let root_parts = ($root | split row "/") + let base = if ($root_parts | length) <= 5 { + $root_display + } else { + let tail = ($root_parts | last 5 | str join "/") + $"…/($tail)" + } + let subpath = if ($dir | str starts-with $root) { + $dir | str replace $root "" | str trim -l -c '/' + } else { "" } + if ($subpath | is-not-empty) { + $"\e[36m($base)\e[0m → \e[34m($subpath)\e[0m" + } else { + $"\e[36m($base)\e[0m" + } + } + + let cwd_raw = ($input | get workspace?.current_dir? | default "") + let cwd_display = if ($cwd_raw | is-not-empty) { + let formatted = (format-cwd $cwd_raw) + $" | ($formatted)" + } else { "" } + let quota_section = if ($usage_info | is-not-empty) { + " | (usage) " + $usage_info + } else { "" } + + print -n $"($model_name) | Ctx: ($context_display) | ($tok_display)($cache_display) | ($cost_display) | t:($elapsed_display) w:($wait_display) | ($churn_display)($marker_200k)($quota_section)($cwd_display)" + ''; + + # Extract cli.js from the bun --compile --bytecode executable. Since 2.1.113 + # the npm package ships a bun SEA ELF instead of plain cli.js, but the source + # is still embedded as text alongside the V8 parse cache. + lift = pkgs.writeScriptBin "lift-claude-bun" /* py */ '' + #!${getExe pkgs.python3} + from __future__ import annotations + + import sys + from pathlib import Path + + # Skip over .rodata / .text — those contain `// @bun` string literals (error + # messages, help text) that would confuse the scanner. The first real module + # sat at ~0xd333ec8 in 2.1.113; staying well below that survives future growth. + SCAN_FROM: int = 0x6000000 + + HEADERS: list[bytes] = [ + b"// @bun @bytecode @bun-cjs\n(function(exports, require, module, __filename, __dirname) {", + b"// @bun @bun-cjs\n(function(exports, require, module, __filename, __dirname) {", + ] + + CJS_OPEN: bytes = b"(function(exports, require, module, __filename, __dirname) {" + CJS_END: bytes = b"})\n\x00" + + + def find_main_module(data: bytes) -> tuple[int, int]: + # In 2.1.117 bun emits cli.js twice: once as a @bytecode blob with the V8 + # parse cache interleaved between the source and its `})\n\x00` terminator, + # and again as a clean source-only copy that terminates normally. Collect + # every header past SCAN_FROM and pick the first one whose terminator lies + # before the next header — that's the source-only copy. + headers: list[tuple[int, int]] = [] + for header in HEADERS: + p: int = SCAN_FROM + while True: + p = data.find(header, p) + if p < 0: + break + headers.append((p, len(header))) + p += 1 + + if not headers: + sys.exit("lift: no bun CJS module header found past 0x6000000") + + headers.sort() + boundaries: list[int] = [p for p, _ in headers] + [len(data)] + + for idx, (start, _) in enumerate(headers): + next_header: int = boundaries[idx + 1] + end: int = data.find(CJS_END, start, next_header) + if end >= 0: + return start, end + 3 # include })\n, exclude trailing NUL + + sys.exit("lift: could not find module terminator (})\\n\\x00)") + + + def unwrap(mod: bytes) -> bytes: + nl = mod.find(b"\n") + if nl < 0: + sys.exit("lift: module has no header newline") + body = mod[nl + 1 :] + if not body.startswith(CJS_OPEN): + sys.exit("lift: module does not open with expected CJS wrapper") + body = body[len(CJS_OPEN) :] + if body.endswith(b"})\n"): + body = body[:-3] + elif body.endswith(b"})"): + body = body[:-2] + else: + sys.exit("lift: module does not end with `})` wrapper close") + return body + + + def main() -> None: + if len(sys.argv) != 3: + sys.exit("usage: lift-claude-bun ") + + binary = Path(sys.argv[1]) + output = Path(sys.argv[2]) + + data = binary.read_bytes() + start, end = find_main_module(data) + body = unwrap(data[start:end]) + + if b"Anthropic" not in body[:4096]: + sys.exit("lift: extracted body is missing Anthropic banner — layout changed?") + + output.write_bytes(body) + sys.stderr.write( + f"lifted {len(body):,} bytes from {binary.name} " + f"(module @ {start:#x}..{end:#x}) -> {output}\n" + ) + + + if __name__ == "__main__": + main() + ''; + + # Patch the lifted cli.cjs: AGENTS.md loader, macOS config path, hard-disabled + # slash commands, telemetry-gate bypass, Av() force-true, 1h prompt cache TTL, + # deno bridge spawn via env(1), feature gate flips, background agent timeout + # bump, claude-api skill disable, Deno-native OAuth usage fetch. + patch = pkgs.writeScriptBin "patch-claude-code-src" /* py */ '' + #!${getExe pkgs.python3} + from __future__ import annotations + + import re + import sys + from collections.abc import Callable + from pathlib import Path + from typing import Union + + type Replacement = Union[bytes, Callable[[re.Match[bytes]], bytes]] + + W: bytes = rb"[\w$]+" + # Qualified name: matches `FN` and also `NS.FN` (e.g. `Lf.join`, `Oc7.spawn`). + # Since 2.1.113 bun's bundler emits more member-style calls for path/spawn helpers. + Q: bytes = rb"[\w$]+(?:\.[\w$]+)*" + data: bytes = Path(sys.argv[1]).read_bytes() + + SEARCH_WINDOW: int = 500 + + + def log(msg: str) -> None: + sys.stderr.write(msg + "\n") + + + def patch(label: str, pattern: bytes, replacement: Replacement) -> None: + global data + data, n = re.subn(pattern, replacement, data) + log(f"{label} ({n})") + + + def replace(label: str, old: bytes, new: bytes) -> None: + global data + n: int = data.count(old) + if n == 0: + log(f"{label}: NOT FOUND") + return + data = data.replace(old, new) + log(f"{label} ({n})") + + + def flip_gates(gates: list[tuple[bytes, str]]) -> None: + """Flip all gate defaults from false to true in a single regex pass.""" + global data + gate_keys: list[bytes] = [g for g, _ in gates] + labels: dict[bytes, str] = dict(gates) + alternation: bytes = b"|".join(re.escape(g) for g in gate_keys) + pat: bytes = W + rb'\("(' + alternation + rb')",!1\)' + flipped: set[bytes] = set() + + def replacer(m: re.Match[bytes]) -> bytes: + flipped.add(m.group(1)) + return m[0].replace(b",!1)", b",!0)") + + data, n = re.subn(pat, replacer, data) + log(f"feature gates: {n} flipped across {len(flipped)} gates") + for key in gate_keys: + status = "ok" if key in flipped else "MISSED" + log(f" {labels[key]} [{status}]") + + + # --- AGENTS.md support --- + # The CLAUDE.md loader only reads CLAUDE.md. Patch it to also load AGENTS.md + # from the same directories. Pattern: let VAR=ME(DIR,"CLAUDE.md");ARR.push(...await XE(VAR,"Project",ARG,BOOL)) + + agents_pat: bytes = ( + rb"let (" + W + rb")=(" + Q + rb")\((" + W + rb'),"CLAUDE\.md"\);' + rb"(" + W + rb")\.push\(\.\.\.await (" + W + rb")\(\1,\"Project\",(" + W + rb"),(" + W + rb")\)\)" + ) + + + def agents_repl(m: re.Match[bytes]) -> bytes: + var, join_fn, dir_, arr, load_fn, arg, flag = [m.group(i) for i in range(1, 8)] + return ( + b'for(let _f of["CLAUDE.md","AGENTS.md"]){let ' + + var + b"=" + join_fn + b"(" + dir_ + b",_f);" + + arr + b".push(...await " + load_fn + b"(" + var + b',"Project",' + arg + b"," + flag + b"))}" + ) + + + patch("agents.md loader", agents_pat, agents_repl) + + # --- macOS config path --- + + replace( + "macOS config path", + b'case"macos":return"/Library/Application Support/ClaudeCode"', + b'case"macos":return"/etc/claude-code"', + ) + + # --- Enable hard-disabled slash commands --- + + slash_commands: list[tuple[bytes, str]] = [ + (b'name:"btw",description:"Ask a quick side question', "/btw"), + (b'name:"bridge-kick",description:"Inject bridge failure states', "/bridge-kick"), + (b'name:"files",description:"List all files currently in context"', "/files"), + ] + + for anchor, label in slash_commands: + pos: int = data.find(anchor) + if pos < 0: + log(f"slash command {label}: NOT FOUND") + continue + window: bytes = data[pos : pos + SEARCH_WINDOW] + patched: bytes = window.replace(b"isEnabled:()=>!1", b"isEnabled:()=>!0", 1) + if patched == window: + log(f"slash command {label}: isEnabled not found in window") + continue + data = data[:pos] + patched + data[pos + SEARCH_WINDOW :] + log(f"slash command {label}: enabled") + + # --- Bypass telemetry gate in feature flag checker --- + # The chain is: h8(featureGate) bails to default if !Qo(); Qo()=Ew6(); + # Ew6()=!Cq6(); Cq6() returns true when on bedrock/vertex/foundry OR when + # user-facing telemetry is disabled (s_1()/equivalent). Drop the trailing + # telemetry-disabled check so feature gates still resolve with + # DISABLE_TELEMETRY=1 while preserving the bedrock/vertex/foundry detection. + # Anchor on the stable env-var literal CLAUDE_CODE_USE_BEDROCK; the obfuscated + # function name (Cq6) and the trailing wrapper name (s_1) both rotate. + + patch( + "telemetry gate (drop telemetry-disabled check)", + ( + rb"function (" + W + rb")\(\)\{return (" + W + rb")\(process\.env\.CLAUDE_CODE_USE_BEDROCK\)" + rb"\|\|\2\(process\.env\.CLAUDE_CODE_USE_VERTEX\)" + rb"\|\|\2\(process\.env\.CLAUDE_CODE_USE_FOUNDRY\)" + rb"\|\|" + W + rb"\(\)\}" + ), + lambda m: re.sub(rb"\|\|" + W + rb"\(\)\}$", b"||!1}", m[0]), + ) + + # --- Force Av() async-gate to always resolve true --- + # Av(flag) is the ASYNC feature-gate resolver. It short-circuits to its default + # in two places when telemetry is off: an inline `if(!va())return!1;` AND the + # same check inside Irq() which it delegates to. Since Av() hardcodes !1 as the + # default passed to Irq, dropping only the inline guard leaves Irq returning + # false anyway. + # + # Every Av() call-site in 2.1.113 targets a gate we intentionally want enabled: + # - tengu_ccr_bridge → Qr8() → initReplBridge() auto-connect + # - tengu_ccr_bridge_multi_session → multi-session remote control + # - tengu_ccr_bundle_seed_enabled → CCR bundle seed + # - tengu_harbor → plugin marketplace + # None of these are things we want off. Replace the whole body to return !0. + # Safe because Av() never writes telemetry — it only reads cached flag state. + + patch( + "Av() force-true for telemetry-off builds", + # Negative lookahead keeps the body match from extending past the end of Av + # into the next function definition (a previous version matched `async + # function Bb8(...)` and spanned through Av's tail, obliterating both). + # The inner resolver name (Irq → aeq → ...) rotates across versions, so + # capture it rather than pinning to a literal. + rb"async function (" + W + rb")\(H\)\{(?:(?!async function ).){60,400}?return " + W + rb"\(H,!1,!0\)\}", + lambda m: b"async function " + m[1] + b"(H){return !0}", + ) + + # --- Restore 1h prompt cache TTL when telemetry is off --- + # https://github.com/anthropics/claude-code/issues/45381 + # The GrowthBook allowlist for "ttl":"1h" cache_control falls back to the + # default object when telemetry is off. Anthropic now ships + # {allowlist:["repl_main_thread*","sdk","auto_mode"]} as the default (up + # from the broken {} in earlier versions), so the TUI and SDK already get + # 1h TTL — but batch agents and less-common query sources still miss. + # Widen the default to ["*"] so everything matches. + + patch( + "1h prompt cache TTL fallback", + rb'(' + W + rb')\("tengu_prompt_cache_1h_config",\{allowlist:\[[^\]]+\]\}\)\.allowlist\?\?\[\]', + lambda m: m[1] + b'("tengu_prompt_cache_1h_config",{allowlist:["*"]}).allowlist??[]', + ) + + # --- Disable tengu_keybindings_dom (new chord dispatcher) --- + # 2.1.118 introduced a DOM-style chord/focus keybinding system behind this + # gate. The gate defaults !0 (on). The new system wraps the TUI in a + # programmatic focus manager (gt()-guarded useLayoutEffect subscribes to + # activeElement and re-focuses a tabIndex ref). During /rewind the message + # selector unmounts and remounts in a sequence where the focus target goes + # null long enough that keystrokes stop routing — stdin ends up paused, + # fd 0 drops out of epoll, and Ctrl-C (a raw 0x03 byte in raw mode) has no + # reader. Wedges the TUI hard; only `kill` from another terminal recovers. + # The old 117-era dispatcher is still present as the `: old_path` branch + # of every gt()?new:old site; flipping the default reverts to it. + + patch( + "disable new keybindings dispatcher (causes /rewind hang in 2.1.118)", + rb'(' + W + rb')\("tengu_keybindings_dom",!0\)', + lambda m: m[1] + b'("tengu_keybindings_dom",!1)', + ) + + # --- Fix Deno-compile bridge spawn --- + # Deno-compiled binaries eat --flags as V8 args, so we route spawns through + # env(1) to pass them as normal CLI flags instead. + + patch( + "deno bridge spawn fix", + rb"let (" + W + rb")=(" + Q + rb")\((" + W + rb")\.execPath,(" + W + rb"),", + lambda m: ( + b"let " + + m[1] + + b"=" + + m[2] + + b'("env",["--",' + + m[3] + + b".execPath,..." + + m[4] + + b"]," + ), + ) + + # --- Flip feature gates --- + # DISABLE_TELEMETRY=1 prevents GrowthBook feature flag resolution, so all gates + # fall back to their hardcoded defaults (false). Flip them to true. + + Gate = tuple[bytes, str] + + core_gates: list[Gate] = [ + (b"tengu_ccr_bridge", "remote control"), + (b"tengu_bridge_system_init", "bridge SDK init on connect"), + (b"tengu_bridge_client_presence_enabled", "bridge presence heartbeats"), + (b"tengu_bridge_requires_action_details", "bridge rich tool-use payloads"), + (b"tengu_remote_backend", "remote backend"), + (b"tengu_immediate_model_command", "instant /model switching"), + (b"tengu_fgts", "fine-grained tool streaming"), + (b"tengu_auto_background_agents", "background agent timeout"), + (b"tengu_plan_mode_interview_phase", "plan mode interview"), + (b"tengu_surreal_dali", "scheduled agents/cron"), + ] + + memory_gates: list[Gate] = [ + # (b"tengu_session_memory", "session memory"), # auto-memory; pollutes unrelated convos + (b"tengu_pebble_leaf_prune", "message pruning"), + (b"tengu_herring_clock", "team memory directory"), + (b"tengu_passport_quail", "typed combined memory prompts"), + (b"tengu_paper_halyard", "memory dedup in nested dirs"), + ] + + ux_gates: list[Gate] = [ + (b"tengu_coral_fern", "grep hints in prompt"), + (b"tengu_kairos_brief", "brief output mode"), + (b"tengu_destructive_command_warning", "destructive command warnings"), + (b"tengu_amber_prism", "permission denial context"), + (b"tengu_hawthorn_steeple", "context windowing"), + (b"tengu_loud_sugary_rock", "Opus 4.7 terse output guidance"), + (b"tengu_verified_vs_assumed", "verified-vs-assumed reporting"), + (b"tengu_birch_compass", "/usage 'What's contributing' breakdown block"), + # tengu_pewter_brook (fullscreen TUI default) disabled — Ink fullscreen + # rendering drops memoized Text children in nested Box columns (/usage + # loses its "What's contributing..." bold header, big vertical gaps). + # Re-enable by setting `tui: "fullscreen"` in settings.json if desired. + ] + + tool_gates: list[Gate] = [ + (b"tengu_chrome_auto_enable", "auto-enable chrome devtools"), + (b"tengu_plum_vx3", "web search reranking"), + # (b"tengu_moth_copse", "relevant memory recall"), # auto-recall; pollutes unrelated convos + (b"tengu_cork_m4q", "batch command processing"), + (b"tengu_harbor", "plugin marketplace"), + (b"tengu_harbor_permissions", "plugin permissions"), + (b"tengu_relay_chain_v1", "parallel command chaining guidance"), + (b"tengu_edit_minimalanchor_jrn", "Edit tool minimal-anchor instructions"), + (b"tengu_slate_reef", "Read tool clearer offset/limit docs"), + (b"tengu_otk_slot_v1", "output-token escalation for complex tasks"), + (b"tengu_onyx_basin_m1k", "subagent tool-result truncation"), + (b"tengu_sub_nomdrep_q7k", "block subagent report .md writes"), + (b"tengu_amber_sentinel", "Monitor tool for streaming bg scripts"), + (b"tengu_miraculo_the_bard", "skip penguin-mode startup prefetch"), + (b"tengu_noreread_q7m_velvet", "sharper 'wasted read' feedback"), + ] + + flip_gates(core_gates + memory_gates + ux_gates + tool_gates) + + # --- Bump background agent timeout from 120s to 240s --- + + patch( + "background agent timeout", + rb'"tengu_auto_background_agents",![01]\)\)return 120000', + lambda m: m[0].replace(b"120000", b"240000"), + ) + + # --- Disable the claude-api bundled skill --- + # Registered via vA({name:"claude-api",description:v4_,...}) at bundle-load + # time. The description (v4_) is a ~200-token SDK/Bedrock usage matrix with + # TRIGGER/SKIP rules that gets injected into every system prompt. We don't + # write Anthropic SDK code in this environment, so cut it. Renamed from + # `claude-developer-platform` in an earlier release — match on current name. + + patch( + "disable claude-api skill", + rb'(' + W + rb')\(\{name:"claude-api",description:', + lambda m: m[1] + b'({name:"claude-api",isEnabled:()=>!1,description:', + ) + + # --- Replace usage fetch with self-contained OAuth implementation --- + # FO()/eO() falls back to x-api-key when dA()/nA() returns false (telemetry off), + # but /api/oauth/usage requires Bearer + oauth beta header. Replace the entire + # function with a Deno-native implementation that reads credentials directly. + + usage_fn_pat: bytes = ( + rb"async function (" + W + rb")\(\)\{" + rb"(?:if\(!" + W + rb"\(\)\|\|!" + W + rb"\(\)\)return\{\};)?" + rb"let " + W + rb"=" + W + rb"\(\);if\(" + W + rb"&&" + W + rb"\(" + W + rb"\." + W + rb"\)\)return null;" + rb"let " + W + rb"=" + W + rb"\(\);if\(" + W + rb"\.error\)throw Error\(\x60Auth error: \x24\{" + W + rb"\.error\}\x60\);" + rb"let " + W + rb"=\{[^}]+\}," + W + rb"=\x60\x24\{(" + W + rb")\(\)\.(" + W + rb")\}/api/oauth/usage\x60;" + rb"return\(await (" + W + rb")\.get\(" + W + rb",\{headers:" + W + rb",timeout:5000\}\)\)\.data\}" + ) + + usage_fn_match: re.Match[bytes] | None = re.search(usage_fn_pat, data) + if usage_fn_match: + fn_name: bytes = usage_fn_match.group(1) + config_fn: bytes = usage_fn_match.group(2) + base_url_key: bytes = usage_fn_match.group(3) + http_client: bytes = usage_fn_match.group(4) + replacement: bytes = ( + b"async function " + fn_name + b"(){" + b"const _cd=(process.env.CLAUDE_CONFIG_DIR||" + b'(Deno.env.get("HOME")+"/.config/claude"));' + b"let _tk;" + b'try{const _cr=JSON.parse(new TextDecoder().decode(' + b'Deno.readFileSync(_cd+"/.credentials.json")));' + b"_tk=_cr?.claudeAiOauth?.accessToken}catch{return{}}" + b"if(!_tk)return{};" + b'const _cp="/tmp/.claude-usage-"+_tk.slice(-8)+".json";' + b"try{const _s=Deno.statSync(_cp);" + b"if(Date.now()-_s.mtime.getTime()<60000)" + b'return JSON.parse(new TextDecoder().decode(Deno.readFileSync(_cp)))}catch{}' + b"const _h={" + b'"Content-Type":"application/json",' + b'"Authorization":"Bearer "+_tk,' + b'"anthropic-beta":"oauth-2025-04-20"};' + b"const _u=`''${" + config_fn + b"()." + base_url_key + b"}/api/oauth/usage`;" + b"const _r=(await " + http_client + b".get(_u,{headers:_h,timeout:5000})).data;" + b'try{Deno.writeTextFileSync(_cp,JSON.stringify(_r))}catch{}' + b"return _r}" + ) + data = data.replace(usage_fn_match[0], replacement) + log("usage fetch: replaced") + else: + log("usage fetch: pattern NOT FOUND") + + # --- grep/find/rg shim: delegate to absolute Nix store paths --- + # claude-code ships a shell shim (o45/i45 → a38) that redefines + # `grep`/`find`/`rg` as bash functions which re-exec the claude binary + # with argv[0]=ugrep/bfs/rg. In Bun "ant-native" builds this dispatches + # to bundled native tools. The Deno repack drops those, so invocations + # fail with `error: unknown option '-G'`. Rewrite a38's emitted bash to + # call the real tools directly via their Nix store paths (resolved at + # build time), so the shim works regardless of PATH and whether the + # cached binary is launched through the wrapper or standalone. + + a38_pat: bytes = ( + rb"function (" + W + rb")\(H,_,q=\[\]\)\{" + rb"let (" + W + rb")=q\.length>0\?\x60\$\{q\.join\(\" \"\)\} \"\$@\"\x60:'\"\$@\"';" + rb"return\[[\s\S]*?\]\.join\(\x60\n\x60\)\}" + ) + + + def a38_repl(m: re.Match[bytes]) -> bytes: + fn_name: bytes = m.group(1) + loc: bytes = m.group(2) + return ( + b"function " + fn_name + b"(H,_,q=[]){" + b"let " + loc + b'=q.length>0?\x60''${q.join(" ")} "$@"\x60:\'"$@"\';' + b'let P=({ugrep:"${getExe' pkgs.ugrep "ugrep"}",' + b'bfs:"${getExe pkgs.bfs}",' + b'rg:"${getExe pkgs.ripgrep}"})[_]||_;' + b"return\x60function ''${H} { " + b'if ! [ -x ''${P} ]; then command ''${H} "$@"; return; fi; ' + b"''${P} ''${" + loc + b"}; }\x60}" + ) + + + patch("grep/find/rg shim: use absolute store paths", a38_pat, a38_repl) + + # --- Bun runtime polyfill --- + # Since 2.1.128 the bundle calls Bun.* APIs unguarded (Bun.stringWidth, + # Bun.semver, Bun.hash, Bun.spawn, Bun.YAML, Bun.Transpiler, Bun.listen, + # Bun.which, Bun.wrapAnsi, Bun.stripANSI, Bun.embeddedFiles, Bun.gc, + # Bun.generateHeapSnapshot, Bun.JSONL, Bun.Terminal, Bun.version). Under + # Deno these throw `ReferenceError: Bun is not defined` at first use + # (Bun.stringWidth fires in a column-width helper called during banner + # render). Define globalThis.Bun upfront with Node-backed equivalents so + # bare `Bun.X` lookups resolve. + # + # Bun.Terminal and Bun.JSONL are intentionally left absent: the bundle + # already has fallback paths gated on `typeof Bun.Terminal<"u"` and + # `Bun.JSONL?.parseChunk`, so leaving them undefined preserves the + # built-in "running under Node?" degradation rather than half-emulating. + + bun_shim: bytes = rb"""(()=>{if(typeof globalThis.Bun!=="undefined")return; + const sw=require("string-width"),sa=require("strip-ansi"),wa=require("wrap-ansi"); + const sv=require("semver"),ya=require("yaml"); + const cp=require("child_process"),fs=require("fs"),path=require("path"); + const crypto=require("crypto"),net=require("net"); + function bunHash(input){const buf=Buffer.isBuffer(input)?input:Buffer.from(typeof input==="string"?input:String(input));return crypto.createHash("sha1").update(buf).digest().readBigUInt64LE(0);} + function bunSpawn(cmd,opts){opts=opts||{};const[bin,...args]=cmd;const stdio=["pipe","pipe",opts.stderr==="ignore"?"ignore":"pipe"];const child=cp.spawn(bin,args,{cwd:opts.cwd,env:opts.env||process.env,stdio,argv0:opts.argv0});const exited=new Promise(r=>child.on("exit",c=>r(c==null?1:c)));return{pid:child.pid,stdin:child.stdin,stdout:child.stdout,stderr:child.stderr,exitCode:null,killed:false,kill(s){try{child.kill(s)}catch{}this.killed=true},async wait(){return await exited},exited};} + function bunListen(opts){const h=opts.socket||{};const server=net.createServer(s=>{s.data=undefined;if(h.open)try{h.open(s)}catch{}s.on("data",d=>h.data&&h.data(s,d));s.on("close",()=>h.close&&h.close(s));s.on("error",e=>h.error&&h.error(s,e));});server.listen(opts.port||0,opts.hostname||"127.0.0.1");return server;} + class BunTranspiler{constructor(o){this.opts=o}transformSync(s){return s}} + globalThis.Bun={version:"1.3.13",embeddedFiles:[],stringWidth:(s,o)=>sw(String(s||""),o),stripANSI:s=>sa(String(s||"")),wrapAnsi:(s,w,o)=>wa(String(s||""),w,o),semver:{satisfies:(a,b)=>sv.satisfies(a,b),order:(a,b)=>sv.compare(a,b)},hash:bunHash,which(cmd){const dirs=(process.env.PATH||"").split(path.delimiter);for(const d of dirs){const f=path.join(d,cmd);try{fs.accessSync(f,fs.constants.X_OK);return f;}catch{}}return null;},spawn:bunSpawn,listen:bunListen,YAML:{parse:s=>ya.parse(s),stringify:(o,r,i)=>ya.stringify(o,r,i)},Transpiler:BunTranspiler,generateHeapSnapshot:()=>new ArrayBuffer(0),gc:()=>{}}; + })(); + """ + + data = bun_shim + data + log("Bun runtime polyfill: prepended") + + Path(sys.argv[1]).write_bytes(data) + ''; + + settings = { + "$schema" = "https://json.schemastore.org/claude-code-settings.json"; + + env = { + CLAUDE_BASH_NO_LOGIN = "1"; + CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING = "1"; + CLAUDE_CODE_DISABLE_FEEDBACK_SURVEY = "1"; + CLAUDE_CODE_DISABLE_TERMINAL_TITLE = "1"; + CLAUDE_CODE_EAGER_FLUSH = "1"; + CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS = "1"; + CLAUDE_CODE_FORCE_GLOBAL_CACHE = "1"; + CLAUDE_CODE_HIDE_ACCOUNT_INFO = "1"; + CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY = "20"; + CLAUDE_CODE_PLAN_V2_AGENT_COUNT = "5"; + CLAUDE_CODE_PLAN_V2_EXPLORE_AGENT_COUNT = "5"; + DISABLE_AUTO_COMPACT = "1"; + DISABLE_AUTOUPDATER = "1"; + DISABLE_COST_WARNINGS = "1"; + DISABLE_ERROR_REPORTING = "1"; + DISABLE_INSTALLATION_CHECKS = "1"; + DISABLE_TELEMETRY = "1"; + ENABLE_MCP_LARGE_OUTPUT_FILES = "1"; + ENABLE_TOOL_SEARCH = "auto:5"; + MAX_THINKING_TOKENS = "31999"; + MCP_CONNECTION_NONBLOCKING = "1"; + RTK_TELEMETRY_DISABLED = "1"; + USE_BUILTIN_RIPGREP = "0"; + UV_THREADPOOL_SIZE = "16"; + }; + + attribution.commit = ""; + attribution.pr = ""; + + permissions.allow = [ + "Read" + ]; + permissions.defaultMode = "bypassPermissions"; + + extraKnownMarketplaces.openai-codex.source = { + source = "github"; + repo = "openai/codex-plugin-cc"; + }; + + enabledPlugins = { + "clangd-lsp@claude-plugins-official" = true; + "code-review@claude-plugins-official" = true; + "code-simplifier@claude-plugins-official" = true; + "codex@openai-codex" = true; + "kotlin-lsp@claude-plugins-official" = true; + "ralph-loop@claude-plugins-official" = true; + "rust-analyzer-lsp@claude-plugins-official" = true; + }; + + statusLine = { + type = "command"; + command = getExe statusLine; + }; + + skipWebFetchPreflight = true; + + spinnerVerbs.mode = "replace"; + spinnerVerbs.verbs = [ + "Redeeming" + "Clodding" + "Tokenmaxxing" + "Slopping" + "Clanking" + "Churning" + "Forgetting" + "Splurging" + "Ignoring GPL" + "Increasing ram prices" + ]; + + cleanupPeriodDays = 90; + alwaysThinkingEnabled = true; + remoteControlAtStartup = true; + showClearContextOnPlanAccept = true; + skipDangerousModePermissionPrompt = true; + }; + + settingsJson = pkgs.writeText "claude-settings.json" (toJSON settings); + + mkSlopLauncher = + { + name, + versionUrl, + versionParser, + fetch, + runtimeDeps ? [ ], + preExec ? "", + cacheSubdir ? name, + }: + pkgs.writeScriptBin name /* nu */ '' + #!${getExe pkgs.nushell} --no-config-file + + def detect-version [--cache: directory, --rebuild]: nothing -> string { + let version_file = $cache | path join "latest-version" + let rebuild = ($rebuild | default false) + let stale = try { (date now) - (ls $version_file | get 0.modified) > 6hr } catch { true } + + if not ($rebuild or $stale) { + return (try { + open $version_file + } catch { + print --stderr $"(ansi yellow_bold)warn:(ansi reset) failed to read latest fetched version" + "" + }) + } + + let version = try { + http get --max-time 5sec ${versionUrl} | ${versionParser} + } catch { + print --stderr $"(ansi yellow_bold)warn:(ansi reset) can't fetch latest version" + return "" + } + + try { + $version_file | path parse | get parent | mkdir $in + $version | save --force $version_file + } catch { + print --stderr $"(ansi yellow_bold)warn:(ansi reset) failed to save latest fetched version" + } + + $version + } + + # Find newest cached binary path. Returns "" if none. Includes + # symlinks because some tools (opencode) cache binaries via + # `ln -s` to a nix-build gcroot, where the mode field reads + # `lrwxrwxrwx` and the exec-bit check would reject it. A broken + # symlink would still fail at exec time. + def latest-cached [--cache: directory]: nothing -> string { + try { + ls --long ($cache | path join "${name}-*") + | where { + ($in.type == "file" and ($in.mode | str substring 2..<3) == "x") + or ($in.type == "symlink") + } + | sort-by modified + | last + | get name + } catch { "" } + } + + def fetch-binary [version: string, binary_path: string, cache: string] { + ${fetch} + } + + def --wrapped main [--rebuild, ...args] { + let rebuild = ($rebuild | default false) + let cache = $env + | get --optional "XDG_CACHE_HOME" + | default ($env.HOME | path join ".cache") + | path join "${cacheSubdir}" + mkdir $cache + + let version = detect-version --cache $cache --rebuild=$rebuild + + # Resolve to a binary path. Both branches converge on the same + # PATH/preExec/exec sequence below so offline-fallback isn't a + # special codepath that skips environment setup (config syncing, + # hook installation, etc). + let binary_path = if ($version | is-empty) { + print --stderr $"(ansi yellow_bold)warn:(ansi reset) version probe failed, trying latest cached binary" + latest-cached --cache $cache + } else { + let p = $cache | path join $"${name}-($version)" + if not ($p | path exists) or $rebuild { + fetch-binary $version $p $cache + } + $p + } + + if ($binary_path | is-empty) { + print --stderr $"(ansi red_bold)error:(ansi reset) no binary available (network down + nothing cached)" + exit 67 + } + + $env.PATH = ($env.PATH | prepend ("${lib.makeBinPath runtimeDeps}" | split row ":")) + ${preExec} + exec $binary_path ...$args + } + ''; + + mkClod = + suffix: + mkSlopLauncher { + name = "claude-${suffix}"; + cacheSubdir = "claude-code"; + versionUrl = "https://registry.npmjs.org/@anthropic-ai/claude-code/latest"; + versionParser = "get version"; + runtimeDeps = [ + pkgs.procps + pkgs.ripgrep + pkgs.bubblewrap + pkgs.socat + ]; + preExec = /* nu */ '' + let config_dir = $env.HOME | path join ".claude-${suffix}" + mkdir $config_dir + + # Sync declarative settings into the writable config dir. Slop refuses + # to read a read-only settings.json in place, so we have to copy. + cp --force ${settingsJson} ($config_dir | path join "settings.json") + + r#'${toJSON settings.env}'# | from json | load-env + $env.CLAUDE_CONFIG_DIR = $config_dir + ''; + fetch = /* nu */ '' + let arch = match ($nu.os-info.arch | str downcase) { + "x86_64" | "x64" | "amd64" => "x64" + "aarch64" | "arm64" => "arm64" + $arch => { error make { msg: $"unsupported arch: ($arch)" } } + } + + let platform = match ($nu.os-info.name | str downcase) { + "linux" => $"linux-($arch)" + "macos" | "darwin" => $"darwin-($arch)" + $os => { error make { msg: $"unsupported os: ($os)" } } + } + + let pkg = $"@anthropic-ai/claude-code-($platform)" + let tarball_url = $"https://registry.npmjs.org/($pkg)/-/claude-code-($platform)-($version).tgz" + + let tgz_dir = $cache | path join "tgz" + mkdir $tgz_dir + let tgz = $tgz_dir | path join $"claude-code-($platform)-($version).tgz" + + # Download to .tmp + atomic rename so an interrupted run doesn't + # leave a partial tarball cached forever (sticky-bad). + if not ($tgz | path exists) { + let tmp = $"($tgz).tmp" + print --stderr $"(ansi cyan)fetch:(ansi reset) ($tarball_url)" + http get --raw $tarball_url | save --force --raw $tmp + mv $tmp $tgz + } + + let workdir = $cache | path join $"build-($version)" + rm -rf $workdir + mkdir $workdir + + ^${getExe pkgs.gnutar} -xzf $tgz -C $workdir + let native_bin = $workdir | path join "package" "claude" + if not ($native_bin | path exists) { + error make { msg: $"lift: ($native_bin) missing after tar extract" } + } + + let cli = $workdir | path join "cli.cjs" + ^${getExe lift} $native_bin $cli + ^${getExe patch} $cli + + # Bun keeps a handful of http/ws/schema libs as runtime-external. Deno has + # no equivalent — drop a package.json next to cli.cjs, resolve deps into + # a local node_modules/, and bundle the tree into the executable via + # --include. + r#'${ + toJSON { + name = "claude-code-lifted"; + type = "commonjs"; + dependencies = { + ws = "^8"; + undici = "^6"; + node-fetch = "^3"; + ajv = "^8"; + ajv-formats = "^3"; + yaml = "^2"; + # Bun shim deps (see "Bun runtime polyfill" in patch-claude-code-src). + # Pinned to CJS-compatible majors: ESM-only releases (string-width@5+, + # strip-ansi@7+, wrap-ansi@8+) break require() inside cli.cjs. + string-width = "^4"; + strip-ansi = "^6"; + wrap-ansi = "^7"; + semver = "^7"; + }; + } + }'# | save --force ($workdir | path join "package.json") + + cd $workdir + $env.DENO_DIR = ($workdir | path join ".deno") + ^${getExe pkgs.deno} install --node-modules-dir=auto + ^${getExe pkgs.deno} compile --allow-all --no-check --node-modules-dir=auto --include=node_modules --output $binary_path "cli.cjs" + + # nushell refuses to delete a directory you're currently inside + cd $cache + rm -rf $workdir + ''; + }; +in +{ + environment.systemPackages = [ + (mkClod "amaan") + (mkClod "lillis") + (mkClod "amaan-work") + ]; + + programs.nix-ld.enable = true; + # environment.variables.CLAUDE_CONFIG_DIR = "$XDG_CONFIG_HOME/claude"; +} diff --git a/graphical/llm/codex.nix b/graphical/llm/codex.nix new file mode 100644 index 0000000..c01acce --- /dev/null +++ b/graphical/llm/codex.nix @@ -0,0 +1,7 @@ +{ pkgs, ... }: +{ + environment.systemPackages = [ + pkgs.codex + pkgs.opencode + ]; +} diff --git a/graphical/llm/launcher.nu b/graphical/llm/launcher.nu deleted file mode 100644 index 6202b67..0000000 --- a/graphical/llm/launcher.nu +++ /dev/null @@ -1,126 +0,0 @@ -def detect-platform []: nothing -> string { - let os = $nu.os-info.name | str downcase - let arch = $nu.os-info.arch | str downcase - - let norm_arch = match $arch { - "x86_64" | "x64" | "amd64" => "x64" - "aarch64" | "arm64" => "arm64" - _ => { error make { msg: $"unsupported arch: ($arch)" } } - } - - match $os { - "linux" => { - let musl_ld = $"/lib/ld-musl-($arch).so.1" - let suffix = if ($musl_ld | path exists) { "-musl" } else { "" } - $"linux-($norm_arch)($suffix)" - } - "macos" | "darwin" => $"darwin-($norm_arch)" - "windows" => { error make { msg: "windows unsupported by this launcher" } } - _ => { error make { msg: $"unsupported os: ($os)" } } - } -} - -def build-binary [version: string, binary_path: string, cache: string] { - let platform = detect-platform - let pkg = $"@anthropic-ai/claude-code-($platform)" - let tarball_url = $"https://registry.npmjs.org/($pkg)/-/claude-code-($platform)-($version).tgz" - - let tgz_dir = $cache | path join "tgz" - mkdir $tgz_dir - let tgz = $tgz_dir | path join $"claude-code-($platform)-($version).tgz" - - if not ($tgz | path exists) { - print --stderr $"(ansi cyan)fetch:(ansi reset) ($tarball_url)" - http get --raw $tarball_url | save --force --raw $tgz - } - - let workdir = $cache | path join $"build-($version)" - rm -rf $workdir - mkdir $workdir - - run-external $env._TAR "-xzf" $tgz "-C" $workdir - let native_bin = $workdir | path join "package" "claude" - if not ($native_bin | path exists) { - error make { msg: $"lift: ($native_bin) missing after tar extract" } - } - - let cli = $workdir | path join "cli.cjs" - run-external $env._LIFT_SCRIPT $native_bin $cli - run-external $env._PATCH_SCRIPT $cli - - # Bun's bundler keeps a handful of http/ws/schema libs as runtime-external. - # Deno has no equivalent provision — drop a package.json next to cli.cjs, - # resolve deps into a local node_modules/, and bundle that tree into the - # executable via --include. - cp --force $env._EXTERNAL_PACKAGE_JSON ($workdir | path join "package.json") - - cd $workdir - $env.DENO_DIR = ($workdir | path join ".deno") - run-external $env._DENO "install" "--node-modules-dir=auto" - run-external $env._DENO "compile" "--allow-all" "--no-check" "--node-modules-dir=auto" "--include=node_modules" "--output" $binary_path "cli.cjs" - - # nushell refuses to delete a directory you're currently inside - cd $cache - rm -rf $workdir -} - -def main --wrapped [...args] { - let cache = $env - | get --optional "XDG_CACHE_HOME" - | default ($env.HOME | path join ".cache") - | path join "claude-code" - mkdir $cache - - let config_dir = $env | get --optional "CLAUDE_CONFIG_DIR" | default ( - $env - | get --optional "XDG_CONFIG_HOME" - | default ($env.HOME | path join ".config") - | path join "claude" - ) - mkdir $config_dir - - # Sync declarative settings into writable config dir - cp --force $env._SETTINGS_JSON ($config_dir | path join "settings.json") - - let version = do { - let version_file = $cache | path join "latest-version" - let stale = try { (date now) - (ls $version_file | get 0.modified) > 6hr } catch { true } - - if not $stale { return (try { open $version_file } catch { "" }) } - - let version = try { - http get --max-time 5sec https://registry.npmjs.org/@anthropic-ai/claude-code/latest - | get version - } catch { - print --stderr $"(ansi yellow_bold)warn:(ansi reset) version cache stale, can't re-fetch" - return "" - } - - try { - $version | save --force $version_file - } - $version - } - - let binary_path = if ($version | is-empty) { - print --stderr $"(ansi yellow_bold)warn:(ansi reset) falling back to latest binary" - - try { - glob ($cache | path join "claude-*") | sort | last - } catch { - print --stderr $"(ansi red_bold)error:(ansi reset) no binary found" - exit 67 - } - } else { - $cache | path join $"claude-($version)" - } - - if not ($binary_path | path exists) { - build-binary $version $binary_path $cache - } - - $env.PATH = ($env.PATH | prepend ($env._RUNTIME_DEPS | split row ":")) - $env._ENV_JSON | load-env - - exec $binary_path ...$args -} diff --git a/graphical/llm/lift-claude-bun.py b/graphical/llm/lift-claude-bun.py deleted file mode 100644 index 3152595..0000000 --- a/graphical/llm/lift-claude-bun.py +++ /dev/null @@ -1,92 +0,0 @@ -from __future__ import annotations - -# Extract the cli.js bundle from a bun --compile --bytecode executable. -# -# Starting with @anthropic-ai/claude-code 2.1.113 the npm package stopped -# shipping cli.js and instead publishes platform-specific tarballs that contain -# a bun-compiled ELF (~226 MB). The JavaScript is still fully embedded in the -# binary as plaintext — the @bytecode marker just means a V8 parse-cache lives -# alongside it, not instead of it. -# -# Layout of each CJS module inside the bun SEA payload: -# // @bun[ @bytecode] @bun-cjs\n -# (function(exports, require, module, __filename, __dirname) {})\n -# \x00/$bunfs/root/\x00... -# -# Claude Code ships three real modules in the tail region (past 0x6000000): -# the main cli (~12 MB), then two tiny native-loader stubs for the optional -# image-processor.node and audio-capture.node. Only the first is interesting. - -import sys -from pathlib import Path - -# Skip over .rodata / .text — those contain `// @bun` string literals (error -# messages, help text) that would confuse the scanner. The first real module -# sat at ~0xd333ec8 in 2.1.113; staying well below that survives future growth. -SCAN_FROM: int = 0x6000000 - -HEADERS: list[bytes] = [ - b"// @bun @bytecode @bun-cjs\n(function(exports, require, module, __filename, __dirname) {", - b"// @bun @bun-cjs\n(function(exports, require, module, __filename, __dirname) {", -] - -CJS_OPEN: bytes = b"(function(exports, require, module, __filename, __dirname) {" -CJS_END: bytes = b"})\n\x00" - - -def find_main_module(data: bytes) -> tuple[int, int]: - for header in HEADERS: - start = data.find(header, SCAN_FROM) - if start >= 0: - break - else: - sys.exit("lift: no bun CJS module header found past 0x6000000") - - end = data.find(CJS_END, start) - if end < 0: - sys.exit("lift: could not find module terminator (})\\n\\x00)") - return start, end + 3 # include })\n, exclude trailing NUL - - -def unwrap(mod: bytes) -> bytes: - nl = mod.find(b"\n") - if nl < 0: - sys.exit("lift: module has no header newline") - body = mod[nl + 1 :] - if not body.startswith(CJS_OPEN): - sys.exit("lift: module does not open with expected CJS wrapper") - body = body[len(CJS_OPEN) :] - # tail is either `})\n` or `})` - if body.endswith(b"})\n"): - body = body[:-3] - elif body.endswith(b"})"): - body = body[:-2] - else: - sys.exit("lift: module does not end with `})` wrapper close") - return body - - -def main() -> None: - if len(sys.argv) != 3: - sys.exit("usage: lift-claude-bun ") - - binary = Path(sys.argv[1]) - output = Path(sys.argv[2]) - - data = binary.read_bytes() - start, end = find_main_module(data) - body = unwrap(data[start:end]) - - # Sanity: the real claude-code cli.js always contains this legal banner. - if b"Anthropic" not in body[:4096]: - sys.exit("lift: extracted body is missing Anthropic banner — layout changed?") - - output.write_bytes(body) - sys.stderr.write( - f"lifted {len(body):,} bytes from {binary.name} " - f"(module @ {start:#x}..{end:#x}) -> {output}\n" - ) - - -if __name__ == "__main__": - main() diff --git a/graphical/llm/llm.nix b/graphical/llm/llm.nix deleted file mode 100644 index 8aa3e0d..0000000 --- a/graphical/llm/llm.nix +++ /dev/null @@ -1,152 +0,0 @@ -{ - - lib, - pkgs, - ... -}: -let - inherit (lib) optionals; - settings = { - "$schema" = "https://json.schemastore.org/claude-code-settings.json"; - - env = { - CLAUDE_BASH_NO_LOGIN = "1"; - CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING = "1"; - CLAUDE_CODE_DISABLE_FEEDBACK_SURVEY = "1"; - CLAUDE_CODE_DISABLE_TERMINAL_TITLE = "1"; - CLAUDE_CODE_EAGER_FLUSH = "1"; - CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS = "1"; - CLAUDE_CODE_FORCE_GLOBAL_CACHE = "1"; - CLAUDE_CODE_HIDE_ACCOUNT_INFO = "1"; - CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY = "20"; - CLAUDE_CODE_PLAN_V2_AGENT_COUNT = "5"; - CLAUDE_CODE_PLAN_V2_EXPLORE_AGENT_COUNT = "5"; - DISABLE_AUTO_COMPACT = "1"; - DISABLE_AUTOUPDATER = "1"; - DISABLE_COST_WARNINGS = "1"; - DISABLE_ERROR_REPORTING = "1"; - DISABLE_INSTALLATION_CHECKS = "1"; - DISABLE_TELEMETRY = "1"; - ENABLE_MCP_LARGE_OUTPUT_FILES = "1"; - ENABLE_TOOL_SEARCH = "auto:5"; - MAX_THINKING_TOKENS = "31999"; - MCP_CONNECTION_NONBLOCKING = "1"; - UV_THREADPOOL_SIZE = "16"; - }; - - attribution = { - commit = ""; - pr = ""; - }; - - permissions = { - allow = [ - "Read" - ]; - defaultMode = "bypassPermissions"; - }; - - statusLine = { - type = "command"; - command = "/etc/claude/statusline-command.nu"; - }; - - enabledPlugins = { - "clangd-lsp@claude-plugins-official" = true; - "rust-analyzer-lsp@claude-plugins-official" = true; - "context7@claude-plugins-official" = true; - "code-review@claude-plugins-official" = true; - "linear@claude-plugins-official" = true; - }; - - skipWebFetchPreflight = true; - - spinnerVerbs = { - mode = "replace"; - verbs = [ - "Redeeming" - "Clodding" - "Tokenmaxxing" - "Slopping" - "Clanking" - "Churning" - "Forgetting" - "Splurging" - "Ignoring GPL" - "Increasing ram prices" - ]; - }; - - cleanupPeriodDays = 90; - alwaysThinkingEnabled = true; - remoteControlAtStartup = true; - showClearContextOnPlanAccept = true; - skipDangerousModePermissionPrompt = true; - }; - - settingsJson = pkgs.writeText "claude-settings.json" (builtins.toJSON settings); - - runtimeDeps = lib.makeBinPath ([ - pkgs.bash - pkgs.procps - pkgs.ripgrep - pkgs.bubblewrap - pkgs.socat - ]); - - patchScript = pkgs.writeScript "patch-claude-src" '' - #!${pkgs.python3}/bin/python3 - ${builtins.readFile ./patch-claude-src.py} - ''; - - liftScript = pkgs.writeScript "lift-claude-bun" '' - #!${pkgs.python3}/bin/python3 - ${builtins.readFile ./lift-claude-bun.py} - ''; - - externalPackageJson = pkgs.writeText "claude-code-external-package.json" ( - builtins.toJSON { - name = "claude-code-lifted"; - type = "commonjs"; - dependencies = { - ws = "^8"; - undici = "^6"; - node-fetch = "^3"; - ajv = "^8"; - ajv-formats = "^3"; - yaml = "^2"; - }; - } - ); - - mkClod = - suffix: - let - finalSuffix = "-${suffix}"; - in - pkgs.writeScriptBin "claude${finalSuffix}" '' - #!${pkgs.nushell}/bin/nu --no-config-file - - $env._SETTINGS_JSON = "${settingsJson}" - $env._DENO = "${pkgs.deno}/bin/deno" - $env._PATCH_SCRIPT = "${patchScript}" - $env._LIFT_SCRIPT = "${liftScript}" - $env._EXTERNAL_PACKAGE_JSON = "${externalPackageJson}" - $env._TAR = "${pkgs.gnutar}/bin/tar" - $env._RUNTIME_DEPS = "${runtimeDeps}" - $env._ENV_JSON = ${lib.strings.toJSON settings.env} - $env.CLAUDE_CONFIG_DIR = ("~/.claude${finalSuffix}" | path expand) - - ${builtins.readFile ./launcher.nu} - ''; -in -{ - environment.systemPackages = [ - (mkClod "lillis") - (mkClod "amaan") - ]; - - environment.etc."claude/statusline-command.nu".source = ./statusline-command.nu; - - programs.nix-ld.enable = true; -} diff --git a/graphical/llm/patch-claude-src.py b/graphical/llm/patch-claude-src.py deleted file mode 100644 index 7036654..0000000 --- a/graphical/llm/patch-claude-src.py +++ /dev/null @@ -1,231 +0,0 @@ -from __future__ import annotations - -import re -import sys -from collections.abc import Callable -from pathlib import Path -from typing import Union - -type Replacement = Union[bytes, Callable[[re.Match[bytes]], bytes]] - -W: bytes = rb"[\w$]+" -# Qualified name: matches `FN` and also `NS.FN` (e.g. `Lf.join`, `Oc7.spawn`). -# Since 2.1.113 bun's bundler emits more member-style calls for path/spawn helpers. -Q: bytes = rb"[\w$]+(?:\.[\w$]+)*" -data: bytes = Path(sys.argv[1]).read_bytes() - -SEARCH_WINDOW: int = 500 - - -def log(msg: str) -> None: - sys.stderr.write(msg + "\n") - - -def patch(label: str, pattern: bytes, replacement: Replacement) -> None: - global data - data, n = re.subn(pattern, replacement, data) - log(f"{label} ({n})") - - -def replace(label: str, old: bytes, new: bytes) -> None: - global data - n: int = data.count(old) - if n == 0: - log(f"{label}: NOT FOUND") - return - data = data.replace(old, new) - log(f"{label} ({n})") - - -def flip_gates(gates: list[tuple[bytes, str]]) -> None: - """Flip all gate defaults from false to true in a single regex pass.""" - global data - gate_keys: list[bytes] = [g for g, _ in gates] - labels: dict[bytes, str] = dict(gates) - alternation: bytes = b"|".join(re.escape(g) for g in gate_keys) - pat: bytes = W + rb'\("(' + alternation + rb')",!1\)' - flipped: set[bytes] = set() - - def replacer(m: re.Match[bytes]) -> bytes: - flipped.add(m.group(1)) - return m[0].replace(b",!1)", b",!0)") - - data, n = re.subn(pat, replacer, data) - log(f"feature gates: {n} flipped across {len(flipped)} gates") - for key in gate_keys: - status = "ok" if key in flipped else "MISSED" - log(f" {labels[key]} [{status}]") - - -# --- AGENTS.md support --- -# The CLAUDE.md loader only reads CLAUDE.md. Patch it to also load AGENTS.md -# from the same directories. Pattern: let VAR=ME(DIR,"CLAUDE.md");ARR.push(...await XE(VAR,"Project",ARG,BOOL)) - -agents_pat: bytes = ( - rb"let (" + W + rb")=(" + Q + rb")\((" + W + rb'),"CLAUDE\.md"\);' - rb"(" + W + rb")\.push\(\.\.\.await (" + W + rb")\(\1,\"Project\",(" + W + rb"),(" + W + rb")\)\)" -) - - -def agents_repl(m: re.Match[bytes]) -> bytes: - var, join_fn, dir_, arr, load_fn, arg, flag = [m.group(i) for i in range(1, 8)] - return ( - b'for(let _f of["CLAUDE.md","AGENTS.md"]){let ' - + var + b"=" + join_fn + b"(" + dir_ + b",_f);" - + arr + b".push(...await " + load_fn + b"(" + var + b',"Project",' + arg + b"," + flag + b"))}" - ) - - -patch("agents.md loader", agents_pat, agents_repl) - -# --- macOS config path --- - -replace( - "macOS config path", - b'case"macos":return"/Library/Application Support/ClaudeCode"', - b'case"macos":return"/etc/claude-code"', -) - -# --- Enable hard-disabled slash commands --- - -slash_commands: list[tuple[bytes, str]] = [ - (b'name:"btw",description:"Ask a quick side question', "/btw"), - (b'name:"bridge-kick",description:"Inject bridge failure states', "/bridge-kick"), - (b'name:"files",description:"List all files currently in context"', "/files"), -] - -for anchor, label in slash_commands: - pos: int = data.find(anchor) - if pos < 0: - log(f"slash command {label}: NOT FOUND") - continue - window: bytes = data[pos : pos + SEARCH_WINDOW] - patched: bytes = window.replace(b"isEnabled:()=>!1", b"isEnabled:()=>!0", 1) - if patched == window: - log(f"slash command {label}: isEnabled not found in window") - continue - data = data[:pos] + patched + data[pos + SEARCH_WINDOW :] - log(f"slash command {label}: enabled") - -# --- Bypass telemetry gate in feature flag checker --- -# The chain is: h8(featureGate) bails to default if !Qo(); Qo()=Ew6(); -# Ew6()=!Cq6(); Cq6() returns true when on bedrock/vertex/foundry OR when -# user-facing telemetry is disabled (s_1()/equivalent). Drop the trailing -# telemetry-disabled check so feature gates still resolve with -# DISABLE_TELEMETRY=1 while preserving the bedrock/vertex/foundry detection. -# Anchor on the stable env-var literal CLAUDE_CODE_USE_BEDROCK; the obfuscated -# function name (Cq6) and the trailing wrapper name (s_1) both rotate. - -patch( - "telemetry gate (drop telemetry-disabled check)", - ( - rb"function (" + W + rb")\(\)\{return (" + W + rb")\(process\.env\.CLAUDE_CODE_USE_BEDROCK\)" - rb"\|\|\2\(process\.env\.CLAUDE_CODE_USE_VERTEX\)" - rb"\|\|\2\(process\.env\.CLAUDE_CODE_USE_FOUNDRY\)" - rb"\|\|" + W + rb"\(\)\}" - ), - lambda m: re.sub(rb"\|\|" + W + rb"\(\)\}$", b"||!1}", m[0]), -) - -# --- Restore 1h prompt cache TTL when telemetry is off --- -# https://github.com/anthropics/claude-code/issues/45381 -# The GrowthBook allowlist for "ttl":"1h" cache_control falls back to the -# default object when telemetry is off. Anthropic now ships -# {allowlist:["repl_main_thread*","sdk","auto_mode"]} as the default (up -# from the broken {} in earlier versions), so the TUI and SDK already get -# 1h TTL — but batch agents and less-common query sources still miss. -# Widen the default to ["*"] so everything matches. - -patch( - "1h prompt cache TTL fallback", - rb'(' + W + rb')\("tengu_prompt_cache_1h_config",\{allowlist:\[[^\]]+\]\}\)\.allowlist\?\?\[\]', - lambda m: m[1] + b'("tengu_prompt_cache_1h_config",{allowlist:["*"]}).allowlist??[]', -) - -# --- Fix Deno-compile bridge spawn --- -# Deno-compiled binaries eat --flags as V8 args, so we route spawns through -# env(1) to pass them as normal CLI flags instead. - -patch( - "deno bridge spawn fix", - rb"let (" + W + rb")=(" + Q + rb")\((" + W + rb")\.execPath,(" + W + rb"),", - lambda m: ( - b"let " - + m[1] - + b"=" - + m[2] - + b'("env",["--",' - + m[3] - + b".execPath,..." - + m[4] - + b"]," - ), -) - -# --- Flip feature gates --- -# DISABLE_TELEMETRY=1 prevents GrowthBook feature flag resolution, so all gates -# fall back to their hardcoded defaults (false). Flip them to true. - -Gate = tuple[bytes, str] - -core_gates: list[Gate] = [ - (b"tengu_ccr_bridge", "remote control"), - (b"tengu_bridge_system_init", "bridge SDK init on connect"), - (b"tengu_bridge_client_presence_enabled", "bridge presence heartbeats"), - (b"tengu_bridge_requires_action_details", "bridge rich tool-use payloads"), - (b"tengu_remote_backend", "remote backend"), - (b"tengu_immediate_model_command", "instant /model switching"), - (b"tengu_fgts", "fine-grained tool streaming"), - (b"tengu_auto_background_agents", "background agent timeout"), - (b"tengu_plan_mode_interview_phase", "plan mode interview"), - (b"tengu_surreal_dali", "scheduled agents/cron"), -] - -memory_gates: list[Gate] = [ - # (b"tengu_session_memory", "session memory"), # auto-memory; pollutes unrelated convos - (b"tengu_pebble_leaf_prune", "message pruning"), - (b"tengu_herring_clock", "team memory directory"), - (b"tengu_passport_quail", "typed combined memory prompts"), - (b"tengu_paper_halyard", "memory dedup in nested dirs"), -] - -ux_gates: list[Gate] = [ - (b"tengu_coral_fern", "grep hints in prompt"), - (b"tengu_kairos_brief", "brief output mode"), - (b"tengu_destructive_command_warning", "destructive command warnings"), - (b"tengu_amber_prism", "permission denial context"), - (b"tengu_hawthorn_steeple", "context windowing"), - (b"tengu_loud_sugary_rock", "Opus 4.7 terse output guidance"), - (b"tengu_verified_vs_assumed", "verified-vs-assumed reporting"), - (b"tengu_pewter_brook", "fullscreen TUI default"), -] - -tool_gates: list[Gate] = [ - (b"tengu_chrome_auto_enable", "auto-enable chrome devtools"), - (b"tengu_plum_vx3", "web search reranking"), - # (b"tengu_moth_copse", "relevant memory recall"), # auto-recall; pollutes unrelated convos - (b"tengu_cork_m4q", "batch command processing"), - (b"tengu_harbor", "plugin marketplace"), - (b"tengu_harbor_permissions", "plugin permissions"), - (b"tengu_relay_chain_v1", "parallel command chaining guidance"), - (b"tengu_edit_minimalanchor_jrn", "Edit tool minimal-anchor instructions"), - (b"tengu_slate_reef", "Read tool clearer offset/limit docs"), - (b"tengu_otk_slot_v1", "output-token escalation for complex tasks"), - (b"tengu_onyx_basin_m1k", "subagent tool-result truncation"), - (b"tengu_sub_nomdrep_q7k", "block subagent report .md writes"), - (b"tengu_amber_sentinel", "Monitor tool for streaming bg scripts"), - (b"tengu_miraculo_the_bard", "skip penguin-mode startup prefetch"), - (b"tengu_noreread_q7m_velvet", "sharper 'wasted read' feedback"), -] - -flip_gates(core_gates + memory_gates + ux_gates + tool_gates) - -# --- Bump background agent timeout from 120s to 240s --- - -patch( - "background agent timeout", - rb'"tengu_auto_background_agents",![01]\)\)return 120000', - lambda m: m[0].replace(b"120000", b"240000"), -) - -Path(sys.argv[1]).write_bytes(data) diff --git a/graphical/llm/statusline-command.nu b/graphical/llm/statusline-command.nu deleted file mode 100644 index 47b702f..0000000 --- a/graphical/llm/statusline-command.nu +++ /dev/null @@ -1,137 +0,0 @@ -#!/usr/bin/env -S nu --no-config-file - -def format-duration [ms: int] { - let total_s = $ms // 1000 - let h = $total_s // 3600 - let m = ($total_s mod 3600) // 60 - let s = $total_s mod 60 - if $h > 0 { - $"($h)h($m | fill -a r -w 2 -c '0')m($s | fill -a r -w 2 -c '0')s" - } else if $m > 0 { - $"($m)m($s | fill -a r -w 2 -c '0')s" - } else { - $"($s)s" - } -} - -def color-for-pct [pct: number] { - let pct_int = $pct | math floor | into int - if $pct_int >= 80 { - "\e[31m" - } else if $pct_int >= 50 { - "\e[33m" - } else { - "\e[32m" - } -} - -def format-rate-limits [input: record] { - let session_pct = try { $input | get rate_limits.five_hour.used_percentage } catch { null } - let week_pct = try { $input | get rate_limits.seven_day.used_percentage } catch { null } - - let session_part = if $session_pct != null { - let c = color-for-pct $session_pct - let v = $session_pct | math round --precision 0 | into int - $"session: ($c)($v)%\e[0m" - } else { "" } - let week_part = if $week_pct != null { - let c = color-for-pct $week_pct - let v = $week_pct | math round --precision 0 | into int - $"week: ($c)($v)%\e[0m" - } else { "" } - - [$session_part $week_part] | where {|x| $x | is-not-empty} | str join " " -} - - -# --- Main --- -let input = (^cat | from json) - -let usage_info = format-rate-limits $input - -let model_name = ($input | get model?.display_name? | default ($input | get model?.id? | default "unknown")) -let used_pct = ($input | get context_window?.used_percentage? | default null) -let total_cost = ($input | get cost?.total_cost_usd? | default 0) -let total_input = ($input | get context_window?.s_in? | default ($input | get context_window?.total_input_tokens? | default 0)) -let total_output = ($input | get context_window?.s_out? | default ($input | get context_window?.total_output_tokens? | default 0)) -let duration_ms = ($input | get cost?.total_duration_ms? | default 0) -let api_duration_ms = ($input | get cost?.total_api_duration_ms? | default 0) -let lines_added = ($input | get cost?.total_lines_added? | default 0) -let lines_removed = ($input | get cost?.total_lines_removed? | default 0) -let exceeds_200k = ($input | get exceeds_200k_tokens? | default false) - -let cache_read = ($input | get context_window?.cache_read_tokens? | default 0) -let cache_create = ($input | get context_window?.cache_creation_tokens? | default 0) - -let total_tokens = $total_input + $total_output - -def format-tokens [n: int] { - if $n >= 1_000_000 { - $"($n / 1_000_000.0 | math round --precision 1)M" - } else if $n >= 1_000 { - $"($n / 1_000.0 | math round --precision 1)k" - } else { - $"($n)" - } -} - -let in_display = (format-tokens ($total_input | into int)) -let out_display = (format-tokens ($total_output | into int)) -let tok_display = $"($in_display)/($out_display)" - -let cache_total = $cache_read + $cache_create -let cache_display = if $cache_total > 0 { - let cache_pct = ($cache_read * 100 / $cache_total | math round --precision 0 | into int) - let cache_color = if $cache_pct >= 70 { - "\e[32m" - } else if $cache_pct >= 40 { - "\e[33m" - } else { - "\e[31m" - } - $" cache:($cache_color)($cache_pct)%\e[0m" -} else { "" } - -let context_display = if $used_pct != null { - let color = color-for-pct $used_pct - let pct_str = $used_pct | math round --precision 1 - $"($color)($pct_str)%\e[0m" -} else { "--" } - -let cost_cents = ($total_cost * 100 | math round | into int) -let cost_dollars = $cost_cents // 100 -let cost_frac = ($cost_cents mod 100 | math abs | into string | fill -a r -w 2 -c '0') -let cost_display = $"$($cost_dollars).($cost_frac)" -let elapsed_display = (format-duration ($duration_ms | into int)) -let wait_display = (format-duration ($api_duration_ms | into int)) -let churn_display = $"\e[32m+($lines_added)\e[0m/\e[31m-($lines_removed)\e[0m" -let marker_200k = if $exceeds_200k { " | \e[31m!200k\e[0m" } else { "" } -def format-cwd [dir: string] { - if ($dir | is-empty) { return "" } - let home = ($env.HOME? | default "") - let display = if ($home | is-not-empty) and ($dir | str starts-with $home) { - let rel = ($dir | str replace $home "" | str trim -l -c '/') - $"~/($rel)" - } else { - $dir - } - let parts = ($display | split row "/") - let shortened = if ($parts | length) <= 5 { - $display - } else { - let tail = ($parts | last 5 | str join "/") - $"…/($tail)" - } - $shortened -} - -let cwd_raw = ($input | get workspace?.current_dir? | default "") -let cwd_display = if ($cwd_raw | is-not-empty) { - let formatted = (format-cwd $cwd_raw) - $" | ($formatted)" -} else { "" } -let quota_section = if ($usage_info | is-not-empty) { - " | (usage) " + $usage_info -} else { "" } - -print -n $"($model_name) | Ctx: ($context_display) | ($tok_display)($cache_display) | ($cost_display) | t:($elapsed_display) w:($wait_display) | ($churn_display)($marker_200k)($quota_section)($cwd_display)" diff --git a/graphical/login.nix b/graphical/login.nix new file mode 100644 index 0000000..ac942b2 --- /dev/null +++ b/graphical/login.nix @@ -0,0 +1,12 @@ +{ + lib, + inputs, + getFlakePkg, + ... +}: +{ + services.greetd = { + enable = true; + settings.default_session.command = "${lib.getExe (getFlakePkg inputs.tuigreet)} --sessions /etc/greetd/wayland-sessions --remember-session --background doom"; + }; +} diff --git a/graphical/media.nix b/graphical/media.nix index 334a9b0..155323f 100644 --- a/graphical/media.nix +++ b/graphical/media.nix @@ -2,6 +2,7 @@ config, pkgs, mkWrappers, + scope, ... }: let diff --git a/graphical/quick-services.nix b/graphical/quick-services.nix index a916997..c92335f 100644 --- a/graphical/quick-services.nix +++ b/graphical/quick-services.nix @@ -2,6 +2,7 @@ config, lib, mainUser, + scope, ... }: let diff --git a/graphical/sync.nix b/graphical/sync.nix index 403e6be..a1e2ece 100644 --- a/graphical/sync.nix +++ b/graphical/sync.nix @@ -1 +1 @@ -{ ... }: scope "services.syncthing.enable" <| true +{ scope, ... }: scope "services.syncthing.enable" <| true diff --git a/graphical/terminal.nix b/graphical/terminal.nix index 52fd06e..e58be63 100644 --- a/graphical/terminal.nix +++ b/graphical/terminal.nix @@ -1,8 +1,9 @@ { pkgs, - lib, config, mkWrappers, + inputs, + scope, ... }: let @@ -60,16 +61,19 @@ let tab-width=180 tab-padding=10 margin=8 + + [key-bindings] + tab-overview=Control+Alt+Tab ''; - footPatched = pkgs.foot.overrideAttrs (old: { - patches = (old.patches or [ ]) ++ [ ./foot-tabs.patch ]; - }); + toesPkg = pkgs.foot.overrideAttrs { + src = inputs.toes; + }; - foot = wrap { + toes = wrap { name = "foot"; - pkg = footPatched; + pkg = toesPkg; args = [ "--config=${footConfig}" ]; }; in -scope "apps.terminal" foot +scope "apps.terminal" toes diff --git a/hosts/adrift/boot.nix b/hosts/adrift/boot.nix index b6a8412..2e3210d 100644 --- a/hosts/adrift/boot.nix +++ b/hosts/adrift/boot.nix @@ -1,4 +1,4 @@ -{ ... }: +{ scope, ... }: scope "boot" { kernelParams = [ "mitigations=off" diff --git a/hosts/adrift/kernel.nix b/hosts/adrift/kernel.nix deleted file mode 100644 index 856c5ff..0000000 --- a/hosts/adrift/kernel.nix +++ /dev/null @@ -1,4 +0,0 @@ -{ pkgs, ... }: -{ - boot.kernelPackages = pkgs.linuxKernel.packages.linux_xanmod; -} diff --git a/hosts/quiver/boot.nix b/hosts/quiver/boot.nix index 580d76c..69ad280 100644 --- a/hosts/quiver/boot.nix +++ b/hosts/quiver/boot.nix @@ -1,4 +1,5 @@ { + scope, ... }: scope "boot" { diff --git a/hosts/quiver/kernel.nix b/hosts/quiver/kernel.nix deleted file mode 100644 index f9ea386..0000000 --- a/hosts/quiver/kernel.nix +++ /dev/null @@ -1,14 +0,0 @@ -{ inputs, ... }: -{ - imports = [ - inputs.bunker.nixosModules.default - ]; - - bunker.kernel = { - enable = true; - version = "7.0"; - # cpuArch = "MZEN3"; - # hardened = false; - # lto = "none"; - }; -} diff --git a/hosts/quiver/ssh.nix b/hosts/quiver/ssh.nix index 57f508b..1e88bb1 100644 --- a/hosts/quiver/ssh.nix +++ b/hosts/quiver/ssh.nix @@ -1,6 +1,6 @@ _: { services.openssh = { - enable = true; + enable = false; listenAddresses = [ { addr = "100.64.0.3"; diff --git a/hosts/quiver/wm.nix b/hosts/quiver/wm.nix new file mode 100644 index 0000000..fb7e92a --- /dev/null +++ b/hosts/quiver/wm.nix @@ -0,0 +1,3 @@ +_: { + programs.wry.enable = true; +} diff --git a/lib/create.nix b/lib/create.nix index 47cad32..411de82 100644 --- a/lib/create.nix +++ b/lib/create.nix @@ -16,7 +16,7 @@ in inherit (inputs.nixpkgs.legacyPackages.${info.system}) callPackage; directory = ../pkgs; }; - # scope = import ./scope.nix { inherit lib; }; + scope = import ./scope.nix { inherit lib; }; mainUser = info.username; machineName = name; getPkgs = builtins.attrValues; diff --git a/lib/inputs.nix b/lib/inputs.nix index 5f5acc3..4ea982b 100644 --- a/lib/inputs.nix +++ b/lib/inputs.nix @@ -1,17 +1,96 @@ let - lock = builtins.fromJSON (builtins.readFile ../flake.lock); - # we use lix's flake-compat fork here to "lazify" the flake inputs - node = lock.nodes.root.inputs.__flake-compat; - inherit (lock.nodes.${node}.locked) narHash rev url; - flake-compat = builtins.fetchTarball { - url = "${url}/archive/${rev}.tar.gz"; - sha256 = narHash; - }; - flake = import flake-compat { - src = ../.; - # these options prevent eager store copies - copySourceTreeToStore = false; - useBuiltinsFetchTree = true; - }; + pins = builtins.fromTOML (builtins.readFile ../pins/pins.toml); + lock = builtins.fromJSON (builtins.readFile ../pins/pins.lock.json); + + fetchPin = name: builtins.fetchTree lock.${name}; + + resolveSpec = + upLock: spec: + if builtins.isList spec then walkPath upLock upLock.root spec else spec; + + walkPath = + upLock: nodeName: path: + if path == [ ] then + nodeName + else + walkPath upLock (resolveSpec upLock upLock.nodes.${nodeName}.inputs.${builtins.head path}) ( + builtins.tail path + ); + + evalTransitive = + upLock: nodeName: sourceInfo: + let + raw = import (sourceInfo.outPath + "/flake.nix"); + node = upLock.nodes.${nodeName}; + callerInputs = builtins.mapAttrs ( + n: _decl: + let + ref = + (node.inputs or { }).${n} + or (throw "lib/inputs.nix: transitive '${n}' missing in flake.lock node '${nodeName}'"); + childName = resolveSpec upLock ref; + childNode = upLock.nodes.${childName}; + childSrc = builtins.fetchTree childNode.locked; + in + if childNode.flake or true then evalTransitive upLock childName childSrc else childSrc + ) (raw.inputs or { }); + outputs = raw.outputs (callerInputs // { self = result; }); + result = outputs // sourceInfo // { + outPath = sourceInfo.outPath; + inputs = callerInputs; + inherit outputs; + inherit sourceInfo; + _type = "flake"; + }; + in + result; + + evalTopFlake = + sourceInfo: pin: + let + raw = import (sourceInfo.outPath + "/flake.nix"); + upLockPath = sourceInfo.outPath + "/flake.lock"; + upLock = + if builtins.pathExists upLockPath then builtins.fromJSON (builtins.readFile upLockPath) else null; + + overrides = builtins.mapAttrs (_: target: self.${target}) (pin.follows or { }); + + callerInputs = builtins.mapAttrs ( + n: _decl: + if overrides ? ${n} then + overrides.${n} + else if upLock != null then + let + ref = + (upLock.nodes.${upLock.root}.inputs or { }).${n} + or (throw "lib/inputs.nix: input '${n}' declared but not in flake.lock at ${toString sourceInfo.outPath}"); + childName = resolveSpec upLock ref; + childNode = upLock.nodes.${childName}; + childSrc = builtins.fetchTree childNode.locked; + in + if childNode.flake or true then evalTransitive upLock childName childSrc else childSrc + else + throw "lib/inputs.nix: no flake.lock at ${toString sourceInfo.outPath}; cannot resolve '${n}'" + ) (raw.inputs or { }); + + outputs = raw.outputs (callerInputs // { self = result; }); + result = outputs // sourceInfo // { + outPath = sourceInfo.outPath; + inputs = callerInputs; + inherit outputs; + inherit sourceInfo; + _type = "flake"; + }; + in + result; + + loadPin = + name: pin: + let + sourceInfo = fetchPin name; + in + if pin.flake or true then evalTopFlake sourceInfo pin else sourceInfo.outPath; + + self = builtins.mapAttrs loadPin pins.inputs; in -flake.inputs +self diff --git a/pins/pins.lock.json b/pins/pins.lock.json new file mode 100644 index 0000000..50b360e --- /dev/null +++ b/pins/pins.lock.json @@ -0,0 +1,179 @@ +{ + "angrr": { + "type": "github", + "owner": "linyinfeng", + "repo": "angrr", + "rev": "a26f5a1d188a40077b81349e623f44466c18f75b", + "narHash": "sha256-GixsqdtE/dZr/YHzPz7c7+LOx2UnR/MoYOQ8lpz7vNc=", + "lastModified": 1778862956 + }, + "arbys": { + "type": "git", + "url": "https://git.lobotomise.me/atagen/arbys", + "ref": "refs/heads/meats", + "rev": "cc1e2613fbbb0ed98bb4ce0d52c6e99bb8f98055", + "narHash": "sha256-Z/O9W0A0SG/cZiiviNPfmciqvI6a3giCLFt/ElwtLCs=", + "lastModified": 1756449827 + }, + "helium": { + "type": "github", + "owner": "amaanq", + "repo": "helium-flake", + "rev": "bab62ae9dbd96ed176078251a4b208743fc5ca6a", + "narHash": "sha256-DnIdzBUFd/Y7LCOQetLiP+71hoDeD/R3wG0GiTefAkg=", + "lastModified": 1778797907 + }, + "hudcore": { + "type": "git", + "url": "https://git.lobotomise.me/atagen/hudcore-plymouth", + "ref": "refs/heads/main", + "rev": "6555d555797bf1960bd89e76a53e0240b6a93df9", + "narHash": "sha256-AI72zuAQBSYETn/dhN8qN8Hdts8PWnSDLEgAxMSZ+CU=", + "lastModified": 1774692528 + }, + "inshellah": { + "type": "git", + "url": "https://git.lobotomise.me/atagen/inshellah", + "ref": "refs/heads/main", + "rev": "a87b5eb3bd3384970d079cf519b55d1dd84750c8", + "narHash": "sha256-x1lrJVHWwd6FNC1nYe0SkQUbd60i7MBoD1kHHxrx3oU=", + "lastModified": 1779197734 + }, + "meat": { + "lastModified": 1779254800, + "ref": "refs/heads/master", + "rev": "e44c71c128a59e7a0fa7d8a4df2b9622b1c63b69", + "revCount": 3, + "type": "git", + "url": "https://git.lobotomise.me/atagen/meat", + "narHash": "sha256-xtx6/GpboyRsK3EVT4hT9RyvE+VHukLkkM0DSu8tqdI=" + }, + "niri": { + "type": "github", + "owner": "sodiboo", + "repo": "niri-flake", + "rev": "daefca3370581223fedc24d0101c4915a3689f9e", + "narHash": "sha256-SPCWvqeVySTNUgX/shARpRl5fi/NnkObUgDGR/Aco4c=", + "lastModified": 1778942403 + }, + "niri-s76": { + "type": "git", + "url": "https://git.lobotomise.me/atagen/niri-s76-bridge", + "ref": "refs/heads/main", + "rev": "e3afb85f23c0e59b2a818094ee7b391ca2f3504d", + "narHash": "sha256-UicMzXYy2XE5jr2J7IO6pZTXUNPndPrGHSIIN6+fB1E=", + "lastModified": 1771162707 + }, + "niri-tag": { + "type": "git", + "url": "https://git.lobotomise.me/atagen/niri-tag", + "ref": "refs/heads/main", + "rev": "785619920b8ae1dd147da795cc7e703c3367c34a", + "narHash": "sha256-y5KsYbzC3MLKr+2M1792jxs3//uV8x9kG+G0LA7cycg=", + "lastModified": 1772457471 + }, + "nix-index-database": { + "type": "github", + "owner": "Mic92", + "repo": "nix-index-database", + "rev": "f680e0d3c1dbefe298c423691662e238496890f2", + "narHash": "sha256-V5GquqJvAqwFTcpN6hxKSQAtwuJFRUEHmyNKbeaTQDg=", + "lastModified": 1778999127 + }, + "nix-rice": { + "type": "github", + "owner": "bertof", + "repo": "nix-rice", + "rev": "98b16b0f649bb41db9a1c3b32191bccb9a1ec271", + "narHash": "sha256-nt/xmuXaJB/vWlRJ4wpdlYQCIgCzFR6QJwlRyhfNn5o=", + "lastModified": 1768817933 + }, + "nixos-core": { + "type": "github", + "owner": "feel-co", + "repo": "nixos-core", + "rev": "5512197f02333c24a9260dd9254c8d0dd8990981", + "narHash": "sha256-fTHhZmepyzXXwisSb/ULB/gGu8wqDF0FqKD/v6nMBYM=", + "lastModified": 1778833218 + }, + "nixpkgs": { + "type": "github", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "d233902339c02a9c334e7e593de68855ad26c4cb", + "narHash": "sha256-30sZNZoA1cqF5JNO9fVX+wgiQYjB7HJqqJ4ztCDeBZE=", + "lastModified": 1778869304 + }, + "nixpkgs-stable": { + "type": "github", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "d7a713c0b7e47c908258e71cba7a2d77cc8d71d5", + "narHash": "sha256-6xWoytx8jFW4PF1GjRm/i/53trbpKGfz6zjzQGBr4cI=", + "lastModified": 1778737229 + }, + "qstn": { + "type": "git", + "url": "https://git.lobotomise.me/atagen/qstn", + "ref": "refs/heads/main", + "rev": "e6570c79145f3190ff93cb2036ae963a8643445f", + "narHash": "sha256-0tMAB3gHKG32A4z/hM7aWNU2t+jh1zT4dpoamcHucog=", + "lastModified": 1767007132 + }, + "qtengine": { + "type": "github", + "owner": "kossLAN", + "repo": "qtengine", + "rev": "073987f0120ac77a92fb9f0c0877aa7f1f04d3bf", + "narHash": "sha256-D7mzavE5WfLyvEXV0pvO3/gxC+SSmfjw4Lxy7I5qvnI=", + "lastModified": 1778644540 + }, + "rom": { + "type": "github", + "owner": "feel-co", + "repo": "rom", + "rev": "c558ce03f4763f861d8a1de25e69b111e63c197e", + "narHash": "sha256-Ttjh24GzioYSkW7HOx9BVPRhCR20unQ5FVwa37jpr3o=", + "lastModified": 1778049674 + }, + "run0-shim": { + "type": "github", + "owner": "lordgrimmauld", + "repo": "run0-sudo-shim", + "rev": "c9e06e2f220ab2fcf2228d4315c0a7fc2dc6e438", + "narHash": "sha256-iZ0HSQwjr9nYpVn10ZI4zQTdqvSggfxhXZ1c4oSZnuc=", + "lastModified": 1774702115 + }, + "stash": { + "type": "github", + "owner": "notashelf", + "repo": "stash", + "rev": "c1ca18e332d5e2915e4d7ea25b8779e6a4f979df", + "narHash": "sha256-Fgvd+4EC59N9UmmFvhYcILxe9nms1el25goZpyXX+Lg=", + "lastModified": 1778772168 + }, + "toes": { + "type": "git", + "url": "ssh://forgejo@git.wry.land/entailz/toes", + "ref": "refs/heads/master", + "rev": "05ee680778cfb0a05d72c73d1684834d021c9a5f", + "narHash": "sha256-7LIluI0PWtWy+AoYTU1cuHoU9OEKgCh53GtwXkjZA1o=", + "lastModified": 1779130477 + }, + "tuigreet": { + "type": "github", + "owner": "notashelf", + "repo": "tuigreet", + "rev": "ba17edead8fcefc21d7dbf6e24f2c718bbc463d6", + "narHash": "sha256-LzKasoA1Ezcs6nnTzR8L/9mP9veLjU3dONi/hYoc3aA=", + "lastModified": 1779071066 + }, + "wry": { + "type": "git", + "url": "ssh://forgejo@git.wry.land/wry/wry", + "ref": "refs/heads/master", + "rev": "a29937ebe8ba6a88c6c952a27e9f22651cfbd970", + "narHash": "sha256-cwplIeQHM8OlIYMaju9qHixP8kZiViQJdnxSy7rxMhk=", + "lastModified": 1778970905 + } +} \ No newline at end of file diff --git a/pins/pins.toml b/pins/pins.toml new file mode 100644 index 0000000..cbec21d --- /dev/null +++ b/pins/pins.toml @@ -0,0 +1,90 @@ +# Shorturl schemes — read by `meat fresh` only. The Nix evaluator never +# resolves a shorturl; only the resolved URL appears in pins.lock.json. +[shorturls] +atagen = "git+https://git.lobotomise.me/atagen/{path}" +amaan = "github:amaanq/{path}" +kosslan = "git+ssh://git@git.kosslan.dev/{path}" +wry = "git+ssh://forgejo@git.wry.land/{path}" + +# ---- inputs -------------------------------------------------------------- +# Each [inputs.] block declares a top-level pin. Fields: +# url (required) shorturl ok; meat expands before resolving +# flake (optional) default true; false = expose source path +# follows (optional) { childInputName = "topLevelPinName" } override map +# dir (optional) subdirectory containing flake.nix +# submodules (optional) fetch git submodules + +[inputs.nixpkgs] +url = "github:NixOS/nixpkgs/nixos-unstable" + +[inputs.nixpkgs-stable] +url = "github:NixOS/nixpkgs/nixos-25.11" + +[inputs.nix-index-database] +url = "github:Mic92/nix-index-database" + +[inputs.nix-rice] +url = "github:bertof/nix-rice" + +[inputs.meat] +url = "atagen:meat" +follows = { nixpkgs = "nixpkgs" } + +[inputs.hudcore] +url = "atagen:hudcore-plymouth" + +[inputs.niri] +url = "github:sodiboo/niri-flake" + +[inputs.niri-tag] +url = "atagen:niri-tag" +follows = { nixpkgs = "nixpkgs" } + +[inputs.angrr] +url = "github:linyinfeng/angrr" + +[inputs.arbys] +url = "atagen:arbys" + +[inputs.qstn] +url = "atagen:qstn" +follows = { nixpkgs = "nixpkgs" } + +[inputs.run0-shim] +url = "github:lordgrimmauld/run0-sudo-shim" +follows = { nixpkgs = "nixpkgs" } + +[inputs.niri-s76] +url = "atagen:niri-s76-bridge" + +[inputs.helium] +url = "amaan:helium-flake" + +[inputs.stash] +url = "github:notashelf/stash" + +[inputs.wry] +url = "wry:wry/wry" +follows = { nixpkgs = "nixpkgs" } + +[inputs.toes] +url = "wry:entailz/toes" +flake = false + +[inputs.tuigreet] +url = "github:notashelf/tuigreet" + +[inputs.rom] +url = "github:feel-co/rom" + +[inputs.inshellah] +url = "atagen:inshellah" +follows = { nixpkgs = "nixpkgs" } + +[inputs.qtengine] +url = "github:kossLAN/qtengine" +follows = { nixpkgs = "nixpkgs" } + +[inputs.nixos-core] +url = "github:feel-co/nixos-core" +follows = { nixpkgs = "nixpkgs" }