this repo has no description
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

idk some stuff, mostly 25.11 and opencode stuff

+992 -914
+98 -81
flake.lock
··· 1 1 { 2 2 "nodes": { 3 + "actor-typeahead-src": { 4 + "flake": false, 5 + "locked": { 6 + "lastModified": 1762835797, 7 + "narHash": "sha256-heizoWUKDdar6ymfZTnj3ytcEv/L4d4fzSmtr0HlXsQ=", 8 + "ref": "refs/heads/main", 9 + "rev": "677fe7f743050a4e7f09d4a6f87bbf1325a06f6b", 10 + "revCount": 6, 11 + "type": "git", 12 + "url": "https://tangled.org/@jakelazaroff.com/actor-typeahead" 13 + }, 14 + "original": { 15 + "type": "git", 16 + "url": "https://tangled.org/@jakelazaroff.com/actor-typeahead" 17 + } 18 + }, 3 19 "agenix": { 4 20 "inputs": { 5 21 "darwin": "darwin", ··· 10 26 "systems": "systems" 11 27 }, 12 28 "locked": { 13 - "lastModified": 1754433428, 14 - "narHash": "sha256-NA/FT2hVhKDftbHSwVnoRTFhes62+7dxZbxj5Gxvghs=", 29 + "lastModified": 1762618334, 30 + "narHash": "sha256-wyT7Pl6tMFbFrs8Lk/TlEs81N6L+VSybPfiIgzU8lbQ=", 15 31 "owner": "ryantm", 16 32 "repo": "agenix", 17 - "rev": "9edb1787864c4f59ae5074ad498b6272b3ec308d", 33 + "rev": "fcdea223397448d35d9b31f798479227e80183f6", 18 34 "type": "github" 19 35 }, 20 36 "original": { ··· 84 100 "systems": "systems_5" 85 101 }, 86 102 "locked": { 87 - "lastModified": 1767386128, 88 - "narHash": "sha256-BJDu7dIMauO2nYRSL4aI8wDNtEm2KOb7lDKP3hxdrpo=", 103 + "lastModified": 1769353768, 104 + "narHash": "sha256-zI+7cbMI4wMIR57jMjDSEsVb3grapTnURDxxJPYFIW0=", 89 105 "owner": "numtide", 90 106 "repo": "blueprint", 91 - "rev": "0ed984d51a3031065925ab08812a5434f40b93d4", 107 + "rev": "c7da5c70ad1c9b60b6f5d4f674fbe205d48d8f6c", 92 108 "type": "github" 93 109 }, 94 110 "original": { ··· 100 116 "brew-src": { 101 117 "flake": false, 102 118 "locked": { 103 - "lastModified": 1758543057, 104 - "narHash": "sha256-lw3V2jOGYphUFHYQ5oARcb6urlbNpUCLJy1qhsGdUmc=", 119 + "lastModified": 1763638478, 120 + "narHash": "sha256-n/IMowE9S23ovmTkKX7KhxXC2Yq41EAVFR2FBIXPcT8=", 105 121 "owner": "Homebrew", 106 122 "repo": "brew", 107 - "rev": "5b236456eb93133c2bd0d60ef35ed63f1c0712f6", 123 + "rev": "fbfdbaba008189499958a7aeb1e2c36ab10c067d", 108 124 "type": "github" 109 125 }, 110 126 "original": { 111 127 "owner": "Homebrew", 112 - "ref": "4.6.12", 128 + "ref": "5.0.3", 113 129 "repo": "brew", 114 130 "type": "github" 115 131 } ··· 143 159 ] 144 160 }, 145 161 "locked": { 146 - "lastModified": 1757432263, 147 - "narHash": "sha256-qHn+/0+IOz5cG68BZUwL9BV3EO/e9eNKCjH3+N7wMdI=", 162 + "lastModified": 1767634391, 163 + "narHash": "sha256-owcSz2ICqTSvhBbhPP+1eWzi88e54rRZtfCNE5E/wwg=", 148 164 "owner": "LnL7", 149 165 "repo": "nix-darwin", 150 - "rev": "1fef4404de4d1596aa5ab2bd68078370e1b9dcdb", 166 + "rev": "08585aacc3d6d6c280a02da195fdbd4b9cf083c2", 151 167 "type": "github" 152 168 }, 153 169 "original": { 154 170 "owner": "LnL7", 155 - "ref": "nix-darwin-25.05", 171 + "ref": "nix-darwin-25.11", 156 172 "repo": "nix-darwin", 157 173 "type": "github" 158 174 } ··· 166 182 "utils": "utils" 167 183 }, 168 184 "locked": { 169 - "lastModified": 1756719547, 170 - "narHash": "sha256-N9gBKUmjwRKPxAafXEk1EGadfk2qDZPBQp4vXWPHINQ=", 185 + "lastModified": 1766051518, 186 + "narHash": "sha256-znKOwPXQnt3o7lDb3hdf19oDo0BLP4MfBOYiWkEHoik=", 171 187 "owner": "serokell", 172 188 "repo": "deploy-rs", 173 - "rev": "125ae9e3ecf62fb2c0fd4f2d894eb971f1ecaed2", 189 + "rev": "d5eff7f948535b9c723d60cd8239f8f11ddc90fa", 174 190 "type": "github" 175 191 }, 176 192 "original": { ··· 238 254 ] 239 255 }, 240 256 "locked": { 241 - "lastModified": 1758287904, 242 - "narHash": "sha256-IGmaEf3Do8o5Cwp1kXBN1wQmZwQN3NLfq5t4nHtVtcU=", 257 + "lastModified": 1768923567, 258 + "narHash": "sha256-GVJ0jKsyXLuBzRMXCDY6D5J8wVdwP1DuQmmvYL/Vw/Q=", 243 259 "owner": "nix-community", 244 260 "repo": "disko", 245 - "rev": "67ff9807dd148e704baadbd4fd783b54282ca627", 261 + "rev": "00395d188e3594a1507f214a2f15d4ce5c07cb28", 246 262 "type": "github" 247 263 }, 248 264 "original": { ··· 458 474 "systems": "systems_6" 459 475 }, 460 476 "locked": { 461 - "lastModified": 1694529238, 462 - "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", 477 + "lastModified": 1731533236, 478 + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", 463 479 "owner": "numtide", 464 480 "repo": "flake-utils", 465 - "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", 481 + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", 466 482 "type": "github" 467 483 }, 468 484 "original": { ··· 503 519 ] 504 520 }, 505 521 "locked": { 506 - "lastModified": 1754078208, 507 - "narHash": "sha256-YVoIFDCDpYuU3riaDEJ3xiGdPOtsx4sR5eTzHTytPV8=", 522 + "lastModified": 1763982521, 523 + "narHash": "sha256-ur4QIAHwgFc0vXiaxn5No/FuZicxBr2p0gmT54xZkUQ=", 508 524 "owner": "nix-community", 509 525 "repo": "gomod2nix", 510 - "rev": "7f963246a71626c7fc70b431a315c4388a0c95cf", 526 + "rev": "02e63a239d6eabd595db56852535992c898eba72", 511 527 "type": "github" 512 528 }, 513 529 "original": { ··· 540 556 }, 541 557 "hardware": { 542 558 "locked": { 543 - "lastModified": 1758663926, 544 - "narHash": "sha256-6CFdj7Xs616t1W4jLDH7IohAAvl5Dyib3qEv/Uqw1rk=", 559 + "lastModified": 1768736227, 560 + "narHash": "sha256-qgGq7CfrYKc3IBYQ7qp0Z/ZXndQVC5Bj0N8HW9mS2rM=", 545 561 "owner": "nixos", 546 562 "repo": "nixos-hardware", 547 - "rev": "170ff93c860b2a9868ed1e1102d4e52cb3d934e1", 563 + "rev": "d447553bcbc6a178618d37e61648b19e744370df", 548 564 "type": "github" 549 565 }, 550 566 "original": { ··· 581 597 ] 582 598 }, 583 599 "locked": { 584 - "lastModified": 1758463745, 585 - "narHash": "sha256-uhzsV0Q0I9j2y/rfweWeGif5AWe0MGrgZ/3TjpDYdGA=", 600 + "lastModified": 1768949235, 601 + "narHash": "sha256-TtjKgXyg1lMfh374w5uxutd6Vx2P/hU81aEhTxrO2cg=", 586 602 "owner": "nix-community", 587 603 "repo": "home-manager", 588 - "rev": "3b955f5f0a942f9f60cdc9cacb7844335d0f21c3", 604 + "rev": "75ed713570ca17427119e7e204ab3590cc3bf2a5", 589 605 "type": "github" 590 606 }, 591 607 "original": { 592 608 "owner": "nix-community", 593 - "ref": "release-25.05", 609 + "ref": "release-25.11", 594 610 "repo": "home-manager", 595 611 "type": "github" 596 612 } ··· 614 630 "homebrew-cask": { 615 631 "flake": false, 616 632 "locked": { 617 - "lastModified": 1759110411, 618 - "narHash": "sha256-wsvLofMB/1bkjY6OQjjWU80+AbQiPzZSLZ3cjsYpOAs=", 633 + "lastModified": 1769058882, 634 + "narHash": "sha256-GOSEf+DtzP/ORw+wrP1o9qZaz2XEvUOBC2j0cEEl2MY=", 619 635 "owner": "homebrew", 620 636 "repo": "homebrew-cask", 621 - "rev": "80f95de379d69edb696dd29106b2d8b077c98896", 637 + "rev": "022be3ce1e808c0196c540471933238fc2bf0815", 622 638 "type": "github" 623 639 }, 624 640 "original": { ··· 630 646 "homebrew-core": { 631 647 "flake": false, 632 648 "locked": { 633 - "lastModified": 1759116320, 634 - "narHash": "sha256-FGqC/WlIJnMkhV7l6XK6r5AqUYkwTHvHBCUjFe3DUUY=", 649 + "lastModified": 1769064658, 650 + "narHash": "sha256-xT3S9geUhs4jmyuuQhsyGFfv86baCXqLID8Bvtzewpo=", 635 651 "owner": "homebrew", 636 652 "repo": "homebrew-core", 637 - "rev": "0ccf924357d3eca3268d6dafb224ad9dc4f2398a", 653 + "rev": "eaa460777befeb0b457587e04e05991ea90826be", 638 654 "type": "github" 639 655 }, 640 656 "original": { ··· 717 733 ] 718 734 }, 719 735 "locked": { 720 - "lastModified": 1762951919, 721 - "narHash": "sha256-ma/xMEGf4J6n/RdZFdxXBJUQhP53HVEPQOC6Dp2TrkQ=", 736 + "lastModified": 1768986040, 737 + "narHash": "sha256-83npNk7w9yNJfSnpdZPNUjbhQwGVef3BWyBuIe6TJfk=", 722 738 "owner": "Jovian-Experiments", 723 739 "repo": "Jovian-NixOS", 724 - "rev": "3d248f6e8f877218dd2573fef8925ac997889922", 740 + "rev": "d75e3c96c9f935a6ccdd4a91209950289b2dc2fc", 725 741 "type": "github" 726 742 }, 727 743 "original": { ··· 737 753 "treefmt-nix": "treefmt-nix_2" 738 754 }, 739 755 "locked": { 740 - "lastModified": 1768434130, 741 - "narHash": "sha256-4rBBs7spDuimvUcL3egp2Zh94Lk8pf00VsjkOs59h7E=", 756 + "lastModified": 1769482725, 757 + "narHash": "sha256-Y4vH4PJIz4dt8SRJ5nm6yJCDzJRVEMdE5tP2TFIUfoQ=", 742 758 "owner": "numtide", 743 759 "repo": "llm-agents.nix", 744 - "rev": "d0ed3ef68a04b5bd127fecd405baf803eea29c29", 760 + "rev": "ae0667122f9a2336b23a4b4751997fe2f161fb37", 745 761 "type": "github" 746 762 }, 747 763 "original": { ··· 846 862 "brew-src": "brew-src" 847 863 }, 848 864 "locked": { 849 - "lastModified": 1758598228, 850 - "narHash": "sha256-qr60maXGbZ4FX5tejPRI3nr0bnRTnZ3AbbbfO6/6jq4=", 865 + "lastModified": 1764473698, 866 + "narHash": "sha256-C91gPgv6udN5WuIZWNehp8qdLqlrzX6iF/YyboOj6XI=", 851 867 "owner": "zhaofengli-wip", 852 868 "repo": "nix-homebrew", 853 - "rev": "f36e5db56e117f7df701ab152d0d2036ea85218c", 869 + "rev": "6a8ab60bfd66154feeaa1021fc3b32684814a62a", 854 870 "type": "github" 855 871 }, 856 872 "original": { ··· 919 935 }, 920 936 "nixos-hardware": { 921 937 "locked": { 922 - "lastModified": 1758663926, 923 - "narHash": "sha256-6CFdj7Xs616t1W4jLDH7IohAAvl5Dyib3qEv/Uqw1rk=", 938 + "lastModified": 1768736227, 939 + "narHash": "sha256-qgGq7CfrYKc3IBYQ7qp0Z/ZXndQVC5Bj0N8HW9mS2rM=", 924 940 "owner": "NixOS", 925 941 "repo": "nixos-hardware", 926 - "rev": "170ff93c860b2a9868ed1e1102d4e52cb3d934e1", 942 + "rev": "d447553bcbc6a178618d37e61648b19e744370df", 927 943 "type": "github" 928 944 }, 929 945 "original": { ··· 1017 1033 }, 1018 1034 "nixpkgs_3": { 1019 1035 "locked": { 1020 - "lastModified": 1768032153, 1021 - "narHash": "sha256-6kD1MdY9fsE6FgSwdnx29hdH2UcBKs3/+JJleMShuJg=", 1036 + "lastModified": 1769421245, 1037 + "narHash": "sha256-m5QLKjpdhbDrhyrUbEm5Haq3lqE5Z6xh2tab5vTHUTo=", 1022 1038 "owner": "NixOS", 1023 1039 "repo": "nixpkgs", 1024 - "rev": "3146c6aa9995e7351a398e17470e15305e6e18ff", 1040 + "rev": "5b265bda51b42a2a85af0a543c3e57b778b01b7d", 1025 1041 "type": "github" 1026 1042 }, 1027 1043 "original": { ··· 1049 1065 }, 1050 1066 "nixpkgs_5": { 1051 1067 "locked": { 1052 - "lastModified": 1758791193, 1053 - "narHash": "sha256-F8WmEwFoHsnix7rt290R0rFXNJiMbClMZyIC/e+HYf0=", 1068 + "lastModified": 1768940263, 1069 + "narHash": "sha256-sJERJIYTKPFXkoz/gBaBtRKke82h4DkX3BBSsKbfbvI=", 1054 1070 "owner": "nixos", 1055 1071 "repo": "nixpkgs", 1056 - "rev": "25e53aa156d47bad5082ff7618f5feb1f5e02d01", 1072 + "rev": "3ceaaa8bc963ced4d830e06ea2d0863b6490ff03", 1057 1073 "type": "github" 1058 1074 }, 1059 1075 "original": { 1060 1076 "owner": "nixos", 1061 - "ref": "nixos-25.05", 1077 + "ref": "nixos-25.11", 1062 1078 "repo": "nixpkgs", 1063 1079 "type": "github" 1064 1080 } 1065 1081 }, 1066 1082 "nixpkgs_6": { 1067 1083 "locked": { 1068 - "lastModified": 1758690382, 1069 - "narHash": "sha256-NY3kSorgqE5LMm1LqNwGne3ZLMF2/ILgLpFr1fS4X3o=", 1084 + "lastModified": 1768886240, 1085 + "narHash": "sha256-C2TjvwYZ2VDxYWeqvvJ5XPPp6U7H66zeJlRaErJKoEM=", 1070 1086 "owner": "nixos", 1071 1087 "repo": "nixpkgs", 1072 - "rev": "e643668fd71b949c53f8626614b21ff71a07379d", 1088 + "rev": "80e4adbcf8992d3fd27ad4964fbb84907f9478b0", 1073 1089 "type": "github" 1074 1090 }, 1075 1091 "original": { ··· 1085 1101 "nixpkgs": "nixpkgs_6" 1086 1102 }, 1087 1103 "locked": { 1088 - "lastModified": 1759117007, 1089 - "narHash": "sha256-DSnkPMhK2Eg0XLiyjEPVtIpdcmWmYsBMhVGCN1144SA=", 1104 + "lastModified": 1769056321, 1105 + "narHash": "sha256-BR4ACqZEfFivkJutgeZeG8Sip/LlvmQgBbkT9eKZeIQ=", 1090 1106 "owner": "nix-community", 1091 1107 "repo": "NUR", 1092 - "rev": "fccc09dffa659dc1410eceb33285831ba12bc7f6", 1108 + "rev": "6dd879dc2cb51262567d8b2b49b2d24f256fa343", 1093 1109 "type": "github" 1094 1110 }, 1095 1111 "original": { ··· 1105 1121 ] 1106 1122 }, 1107 1123 "locked": { 1108 - "lastModified": 1762711246, 1109 - "narHash": "sha256-coOLG/Bp118d1T3DBIZUcW+AdiKsHz9uh6ZuiR30GBM=", 1124 + "lastModified": 1759014010, 1125 + "narHash": "sha256-NMpUufnxiGDTs/4Nxj8t+n4wc4aSs02a4T5OORo0gBQ=", 1110 1126 "ref": "main", 1111 - "rev": "54287446e1a8a1bc40ad1b12061f053181e6d264", 1112 - "revCount": 1614, 1127 + "rev": "08c1dddf38c39d6f7c73a24f4d396f4c925185bf", 1128 + "revCount": 1602, 1113 1129 "type": "git", 1114 1130 "url": "ssh://gitea@git.sealight.xyz/aynish/kitaab" 1115 1131 }, ··· 1202 1218 ] 1203 1219 }, 1204 1220 "locked": { 1205 - "lastModified": 1759113356, 1206 - "narHash": "sha256-xm4kEUcV2jk6u15aHazFP4YsMwhq+PczA+Ul/4FDKWI=", 1221 + "lastModified": 1769050281, 1222 + "narHash": "sha256-1H8DN4UZgEUqPUA5ecHOufLZMscJ4IlcGaEftaPtpBY=", 1207 1223 "owner": "oxalica", 1208 1224 "repo": "rust-overlay", 1209 - "rev": "be3b8843a2be2411500f6c052876119485e957a2", 1225 + "rev": "6deef0585c52d9e70f96b6121207e1496d4b0c49", 1210 1226 "type": "github" 1211 1227 }, 1212 1228 "original": { ··· 1336 1352 }, 1337 1353 "tangled": { 1338 1354 "inputs": { 1355 + "actor-typeahead-src": "actor-typeahead-src", 1339 1356 "flake-compat": "flake-compat_4", 1340 1357 "gomod2nix": "gomod2nix", 1341 1358 "htmx-src": "htmx-src", ··· 1350 1367 "sqlite-lib-src": "sqlite-lib-src" 1351 1368 }, 1352 1369 "locked": { 1353 - "lastModified": 1759559279, 1354 - "narHash": "sha256-gA0mh9Fx2uou2v75RMA6qUvWB3Z74Asc6pRjiojwaRo=", 1370 + "lastModified": 1769064660, 1371 + "narHash": "sha256-2ccXZ51txbX1jAhW52Z6QuSFAgFqo3Gr1bqxD4jXNw0=", 1355 1372 "ref": "refs/heads/master", 1356 - "rev": "5ecd54b31547ac169a3b15d6034a67179f22aa33", 1357 - "revCount": 1486, 1373 + "rev": "2b94ee226637e13c106d7782ca852bd608530b51", 1374 + "revCount": 1865, 1358 1375 "type": "git", 1359 1376 "url": "https://tangled.org/@tangled.org/core" 1360 1377 }, ··· 1431 1448 ] 1432 1449 }, 1433 1450 "locked": { 1434 - "lastModified": 1768031762, 1435 - "narHash": "sha256-b2gJDJfi+TbA7Hu2sKip+1mWqya0GJaWrrXQjpbOVTU=", 1451 + "lastModified": 1769353635, 1452 + "narHash": "sha256-J0G1ACrUK29M0THPAsz429eZX07GmR9Bs/b0pB3N0dQ=", 1436 1453 "owner": "numtide", 1437 1454 "repo": "treefmt-nix", 1438 - "rev": "0c445aa21b01fd1d4bb58927f7b268568af87b20", 1455 + "rev": "f46bb205f239b415309f58166f8df6919fa88377", 1439 1456 "type": "github" 1440 1457 }, 1441 1458 "original": { ··· 1446 1463 }, 1447 1464 "unstable": { 1448 1465 "locked": { 1449 - "lastModified": 1762844143, 1450 - "narHash": "sha256-SlybxLZ1/e4T2lb1czEtWVzDCVSTvk9WLwGhmxFmBxI=", 1466 + "lastModified": 1768886240, 1467 + "narHash": "sha256-C2TjvwYZ2VDxYWeqvvJ5XPPp6U7H66zeJlRaErJKoEM=", 1451 1468 "owner": "nixos", 1452 1469 "repo": "nixpkgs", 1453 - "rev": "9da7f1cf7f8a6e2a7cb3001b048546c92a8258b4", 1470 + "rev": "80e4adbcf8992d3fd27ad4964fbb84907f9478b0", 1454 1471 "type": "github" 1455 1472 }, 1456 1473 "original": {
+9 -7
flake.nix
··· 8 8 9 9 inputs = { 10 10 # Nixpkgs 11 - nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05"; 11 + nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11"; 12 12 unstable.url = "github:nixos/nixpkgs/nixos-unstable"; 13 13 nixos-hardware.url = "github:NixOS/nixos-hardware/master"; 14 14 ··· 16 16 # ngipkgs-local.url = "path:/home/anish/usr/ngipkgs"; 17 17 18 18 # Home manager 19 - home-manager.url = "github:nix-community/home-manager/release-25.05"; 19 + home-manager.url = "github:nix-community/home-manager/release-25.11"; 20 20 home-manager.inputs.nixpkgs.follows = "nixpkgs"; 21 21 hardware.url = "github:nixos/nixos-hardware"; 22 22 ··· 44 44 45 45 # Darwin 46 46 darwin = { 47 - url = "github:LnL7/nix-darwin/nix-darwin-25.05"; 47 + url = "github:LnL7/nix-darwin/nix-darwin-25.11"; 48 48 inputs.nixpkgs.follows = "nixpkgs"; 49 49 }; 50 50 nix-homebrew = { ··· 160 160 "SunVox" 161 161 "renoise" 162 162 "bitwig-studio-unwrapped" 163 + "via" # QMK keyboard configurator 163 164 ]; 164 165 }; 165 166 overlays = [ 166 167 rust-overlay.overlays.default 167 168 tidalcycles.overlays.default 168 169 agenix.overlays.default 169 - nur.overlay 170 + nur.overlays.default 170 171 # nix-matrix-appservices.overlay # nixpkgs has these packages and newer ones at that 171 172 unstableOverlay 172 173 vimwikiOverlay ··· 217 218 rust-overlay.overlays.default 218 219 tidalcycles.overlays.default 219 220 agenix.overlays.default 220 - nur.overlay 221 + nur.overlays.default 221 222 unstableOverlay 222 223 vimwikiOverlay 223 224 self.overlays.additions ··· 253 254 rust-overlay.overlays.default 254 255 tidalcycles.overlays.default 255 256 agenix.overlays.default 256 - nur.overlay 257 + nur.overlays.default 257 258 unstableOverlay 258 259 vimwikiOverlay 259 260 self.overlays.additions ··· 325 326 agenix.nixosModules.age 326 327 self.nixosModules.backup 327 328 self.nixosModules.wireguard 328 - basant.nixosModule 329 + # TODO: basant needs pyproject update for 25.11 - re-enable after fixing 330 + # basant.nixosModule 329 331 # self.nixosModules.microbin 330 332 disko.nixosModules.disko 331 333 {
+3 -9
home/profiles/beets/default.nix
··· 2 2 { 3 3 programs.beets = { 4 4 enable = true; 5 - package = pkgs.beets.override { 6 - pluginOverrides = { 7 - fetchart.enable = true; 8 - embedart.enable = true; 9 - lastgenre.enable = true; 10 - duplicates.enable = true; 11 - missing.enable = true; 12 - }; 13 - }; 5 + # In 25.11, beets plugins are enabled via beetsPackages or the default package 6 + # The default beets package includes common plugins 7 + package = pkgs.beets; 14 8 settings = { 15 9 directory = "/tank/media/music"; 16 10 library = "/home/anish/.local/share/beets/library.db";
+156 -148
home/profiles/cli/default.nix
··· 1 - { lib, pkgs, config, ... }: 2 1 { 3 - home.packages = with pkgs; [ 4 - binutils 5 - coreutils 6 - dnsutils 7 - dasht 8 - dosfstools 9 - #git 10 - git-machete 11 - bottom 12 - gptfdisk 13 - difftastic 14 - starship 15 - jq 16 - manix 17 - moreutils 18 - nix-index 19 - cached-nix-shell 20 - nmap 21 - ripgrep 22 - skim 23 - tealdeer 24 - usbutils 25 - utillinux 26 - whois 27 - iftop 28 - wget 29 - curl 30 - eza 31 - bat 32 - fd 33 - ncdu 34 - dust 35 - # dia-cli 36 - duf 37 - trash-cli 38 - nix-index 39 - silver-searcher 40 - tcpdump 41 - mtr 42 - file 43 - lsof 44 - atool 45 - zip 46 - unzip 47 - rsync 48 - tmux 49 - pwgen 50 - glow 51 - pass 52 - less 53 - gdb 54 - xxd 55 - taskwarrior2 56 - gnupg 57 - syncthing 58 - dijo 59 - nixfmt-rfc-style 60 - nix-tree 61 - #ssb-patchwork 62 - fontconfig 63 - pandoc 64 - taskwarrior-tui 65 - # vimwiki-cli 66 - zk 2 + lib, 3 + pkgs, 4 + config, 5 + ... 6 + }: 7 + { 8 + home.packages = 9 + with pkgs; 10 + [ 11 + binutils 12 + coreutils 13 + dnsutils 14 + dasht 15 + dosfstools 16 + #git 17 + git-machete 18 + bottom 19 + gptfdisk 20 + difftastic 21 + starship 22 + jq 23 + manix 24 + moreutils 25 + nix-index 26 + cached-nix-shell 27 + nmap 28 + ripgrep 29 + skim 30 + tealdeer 31 + usbutils 32 + utillinux 33 + whois 34 + iftop 35 + wget 36 + curl 37 + eza 38 + bat 39 + fd 40 + ncdu 41 + dust 42 + # dia-cli 43 + duf 44 + trash-cli 45 + nix-index 46 + silver-searcher 47 + tcpdump 48 + mtr 49 + file 50 + lsof 51 + atool 52 + zip 53 + unzip 54 + rsync 55 + tmux 56 + pwgen 57 + glow 58 + pass 59 + less 60 + gdb 61 + xxd 62 + taskwarrior2 63 + gnupg 64 + syncthing 65 + dijo 66 + nixfmt-rfc-style 67 + nix-tree 68 + #ssb-patchwork 69 + fontconfig 70 + pandoc 71 + taskwarrior-tui 72 + # vimwiki-cli 73 + zk 74 + radicle-node # rad CLI for interacting with Radicle repos 67 75 68 - (pkgs.writeScriptBin "jq-repl" '' 69 - #!/usr/bin/env bash 70 - if [[ -z $1 ]] || [[ $1 == "-" ]]; then 71 - input=$(mktemp) 72 - trap "rm -f $input" EXIT 73 - cat /dev/stdin > $input 74 - else 75 - input=$1 76 - fi 76 + (pkgs.writeScriptBin "jq-repl" '' 77 + #!/usr/bin/env bash 78 + if [[ -z $1 ]] || [[ $1 == "-" ]]; then 79 + input=$(mktemp) 80 + trap "rm -f $input" EXIT 81 + cat /dev/stdin > $input 82 + else 83 + input=$1 84 + fi 77 85 78 - echo "" \ | fzf --phony --preview-window="up:90%" --print-query --preview "jq --color-output -r {q} $input" 79 - '') 80 - (pkgs.writeScriptBin "clear-vim-trash" (builtins.readFile ./bin/clear-vim-trash.sh)) 81 - (pkgs.writeScriptBin "flakify" '' 82 - #!/usr/bin/env zsh 83 - if [ ! -e flake.nix ]; then 84 - nix flake new -t github:nix-community/nix-direnv . 85 - elif [ ! -e .envrc ]; then 86 - echo "use flake" > .envrc 87 - direnv allow 88 - fi 89 - vim flake.nix 90 - '') 91 - (pkgs.writeScriptBin "mx" '' 92 - #!/usr/bin/env bash 93 - manix "" | grep '^# ' | sed 's/^# \(.*\) (.*/\1/;s/ (.*//;s/^# //' | fzf --preview="manix '{}'" | xargs manix 94 - '') 95 - (pkgs.writeScriptBin "monitor" '' 96 - connect() { 97 - # Turn it on if it was off 98 - xrandr --output HDMI-2 --auto 99 - xrandr --output HDMI-2 --same-as eDP-1 100 - xrandr --output eDP-1 --off 101 - pkill -9 polybar 102 - feh --bg-scale ~/Downloads/stephen-walker-onIXxjH56AA-unsplash.jpg 103 - polybar mybar > $XDG_DATA_HOME/polybar.log 2>&1 & 104 - } 86 + echo "" \ | fzf --phony --preview-window="up:90%" --print-query --preview "jq --color-output -r {q} $input" 87 + '') 88 + (pkgs.writeScriptBin "clear-vim-trash" (builtins.readFile ./bin/clear-vim-trash.sh)) 89 + (pkgs.writeScriptBin "flakify" '' 90 + #!/usr/bin/env zsh 91 + if [ ! -e flake.nix ]; then 92 + nix flake new -t github:nix-community/nix-direnv . 93 + elif [ ! -e .envrc ]; then 94 + echo "use flake" > .envrc 95 + direnv allow 96 + fi 97 + vim flake.nix 98 + '') 99 + (pkgs.writeScriptBin "mx" '' 100 + #!/usr/bin/env bash 101 + manix "" | grep '^# ' | sed 's/^# \(.*\) (.*/\1/;s/ (.*//;s/^# //' | fzf --preview="manix '{}'" | xargs manix 102 + '') 103 + (pkgs.writeScriptBin "monitor" '' 104 + connect() { 105 + # Turn it on if it was off 106 + xrandr --output HDMI-2 --auto 107 + xrandr --output HDMI-2 --same-as eDP-1 108 + xrandr --output eDP-1 --off 109 + pkill -9 polybar 110 + feh --bg-scale ~/Downloads/stephen-walker-onIXxjH56AA-unsplash.jpg 111 + polybar mybar > $XDG_DATA_HOME/polybar.log 2>&1 & 112 + } 105 113 106 - disconnect() { 107 - xrandr --output HDMI-2 --off 108 - xrandr --output eDP-1 --auto 109 - } 114 + disconnect() { 115 + xrandr --output HDMI-2 --off 116 + xrandr --output eDP-1 --auto 117 + } 110 118 111 - xrandr | grep "HDMI-2 connected" &>>/dev/null && connect || disconnect 112 - '') 113 - (pkgs.writeScriptBin "big-monitor" '' 114 - connect() { 115 - # Turn it on if it was off 116 - xrandr --output HDMI-2 --auto --primary 117 - # Disable normal display 118 - xrandr --output eDP-1 --off 119 - # Use a nice background 120 - feh --bg-scale ~/Downloads/stephen-walker-onIXxjH56AA-unsplash.jpg 121 - # Reload Polybar 122 - ~/.config/bspwm/rc.d/polybar 123 - } 119 + xrandr | grep "HDMI-2 connected" &>>/dev/null && connect || disconnect 120 + '') 121 + (pkgs.writeScriptBin "big-monitor" '' 122 + connect() { 123 + # Turn it on if it was off 124 + xrandr --output HDMI-2 --auto --primary 125 + # Disable normal display 126 + xrandr --output eDP-1 --off 127 + # Use a nice background 128 + feh --bg-scale ~/Downloads/stephen-walker-onIXxjH56AA-unsplash.jpg 129 + # Reload Polybar 130 + ~/.config/bspwm/rc.d/polybar 131 + } 124 132 125 - disconnect() { 126 - xrandr --output HDMI-2 --off 127 - } 133 + disconnect() { 134 + xrandr --output HDMI-2 --off 135 + } 128 136 129 - xrandr | grep "HDMI-2 connected" &>>/dev/null && connect || disconnect 130 - '') 131 - (pkgs.writeScriptBin "disconnect-keyboard" '' 132 - # keyboard on curve is busted 133 - get_keyboard_id() { 134 - xinput list | grep 'AT Translated Set' | cut -f2 | cut -d'=' -f2 | xinput float 135 - } 137 + xrandr | grep "HDMI-2 connected" &>>/dev/null && connect || disconnect 138 + '') 139 + (pkgs.writeScriptBin "disconnect-keyboard" '' 140 + # keyboard on curve is busted 141 + get_keyboard_id() { 142 + xinput list | grep 'AT Translated Set' | cut -f2 | cut -d'=' -f2 | xinput float 143 + } 136 144 137 - disconnect_keyboard() { 138 - id=$(get_keyboard_id) 139 - xinput float $id 140 - unset id 141 - } 145 + disconnect_keyboard() { 146 + id=$(get_keyboard_id) 147 + xinput float $id 148 + unset id 149 + } 142 150 143 - attach_keyboard() { 144 - id=$(get_keyboard_id) 145 - xinput reattach $id 3 146 - unset id 147 - } 151 + attach_keyboard() { 152 + id=$(get_keyboard_id) 153 + xinput reattach $id 3 154 + unset id 155 + } 148 156 149 - disconnect_keyboard 150 - '') 151 - ] ++ lib.optionals pkgs.stdenv.isLinux [ 152 - # Linux-only packages 153 - iputils 154 - strace 155 - ]; 157 + disconnect_keyboard 158 + '') 159 + ] 160 + ++ lib.optionals pkgs.stdenv.isLinux [ 161 + # Linux-only packages 162 + iputils 163 + strace 164 + ]; 156 165 157 166 programs.zsh = { 158 167 enable = true; ··· 246 255 yt = "ytfzf -T kitty -t "; 247 256 gen-secret = "< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c\${1:-32};echo;"; 248 257 249 - # modern cli tools 258 + # modern cli tools 250 259 ls = "eza --icons"; 251 260 l = "esa -l --icons"; 252 261 la = "eza -la --icons"; ··· 255 264 unzip = "aunpack"; 256 265 copy = if pkgs.stdenv.isDarwin then "pbcopy" else "xclip -selection clipboard"; 257 266 paste = if pkgs.stdenv.isDarwin then "pbpaste" else "xclip -selection clipboard -o"; 258 - rm = "echo USE TRASH, FOOL: trash "; 259 267 trash = "trash-put"; 260 268 make-secret = "< /dev/urandom \\tr -dc _A-Za-z0-9 | head -c \${1:-32};echo;"; 261 269 262 270 # task warrior 263 - t = "task -BLOCKED -idea -backlog"; 271 + t = "task -BLOCKED -idea -backlog"; 264 272 tw = "t rc.context:work"; 265 273 # TODO find a reasonable way to manage this from a non-nix managed file in ~/.task/context or something 266 274 # we can do something like task rc.context:$(cat ~/.task/context) to read context
+1 -2
home/profiles/desktop/kitty.conf
··· 11 11 12 12 13 13 14 - # Ctrl+V for paste 15 - map ctrl+v paste_from_clipboard 14 + # Ctrl+V handled by neovim for insert mode paste (allows visual block mode in normal mode) 16 15 mouse_map middle release ungrabbed paste_from_clipboard
+48 -41
home/profiles/git/default.nix
··· 12 12 unstable.git-spice 13 13 ]; 14 14 15 + # Delta (git diff pager) - moved to top-level in home-manager 25.11 16 + programs.delta = { 17 + enable = true; 18 + enableGitIntegration = true; 19 + }; 20 + 15 21 programs.git = { 16 22 enable = true; 17 - userName = "Anish Lakhwara"; 18 - userEmail = "anish+git@lakhwara.com"; 19 - delta.enable = true; 20 23 signing = { 21 24 signByDefault = if pkgs.stdenv.isLinux then false else true; 22 25 key = if pkgs.stdenv.isLinux then "B8492C8FB53397B7" else "7FC5DF072EF7B716"; ··· 60 63 "node_modules/" 61 64 ]; 62 65 63 - extraConfig = { 66 + # 25.11: extraConfig, userName, userEmail, aliases moved under settings 67 + settings = { 68 + user = { 69 + name = "Anish Lakhwara"; 70 + email = "anish+git@lakhwara.com"; 71 + }; 64 72 pull.rebase = false; 65 73 push.autoSetupRemote = true; 66 74 init.defaultBranch = "main"; 67 - "url \"git@github.com:\"" = { insteadOf = "https://github.com/"; }; 68 - }; 75 + "url \"git@github.com:\"" = { 76 + insteadOf = "https://github.com/"; 77 + }; 69 78 70 - aliases = { 71 - a = "add -p"; 72 - co = "checkout"; 73 - cob = "checkout -b"; 74 - f = "fetch -p"; 75 - c = "commit -v"; 76 - p = "push"; 77 - ba = "branch -a"; 78 - bd = "branch -d"; 79 - bD = "branch -D"; 80 - d = "diff"; 81 - dc = "diff --cached"; 82 - ds = "diff --staged"; 83 - r = "restore"; 84 - rs = "restore --staged"; 85 - st = "status -sb"; 79 + alias = { 80 + a = "add -p"; 81 + co = "checkout"; 82 + cob = "checkout -b"; 83 + f = "fetch -p"; 84 + c = "commit -v"; 85 + p = "push"; 86 + ba = "branch -a"; 87 + bd = "branch -d"; 88 + bD = "branch -D"; 89 + d = "diff"; 90 + dc = "diff --cached"; 91 + ds = "diff --staged"; 92 + r = "restore"; 93 + rs = "restore --staged"; 94 + st = "status -sb"; 86 95 87 - # reset 88 - soft = "reset --soft"; 89 - hard = "reset --hard"; 90 - s1ft = "soft HEAD~1"; 91 - h1rd = "hard HEAD~1"; 96 + # reset 97 + soft = "reset --soft"; 98 + hard = "reset --hard"; 99 + s1ft = "soft HEAD~1"; 100 + h1rd = "hard HEAD~1"; 92 101 93 - # logging 94 - lg = 95 - "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"; 96 - plog = 97 - "log --graph --pretty='format:%C(red)%d%C(reset) %C(yellow)%h%C(reset) %ar %C(green)%aN%C(reset) %s'"; 98 - tlog = 99 - "log --stat --since='1 Day Ago' --graph --pretty=oneline --abbrev-commit --date=relative"; 100 - rank = "shortlog -sn --no-merges"; 101 - authors = "authors | sort | uniq -c | sort -n"; 102 - ls = "log --graph --abbrev-commit --decorate --color=always --date=relative --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) - %C(dim red)%an%C(reset)%C(bold yellow)%d%C(reset)' --all"; 102 + # logging 103 + lg = "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"; 104 + plog = "log --graph --pretty='format:%C(red)%d%C(reset) %C(yellow)%h%C(reset) %ar %C(green)%aN%C(reset) %s'"; 105 + tlog = "log --stat --since='1 Day Ago' --graph --pretty=oneline --abbrev-commit --date=relative"; 106 + rank = "shortlog -sn --no-merges"; 107 + authors = "authors | sort | uniq -c | sort -n"; 108 + ls = "log --graph --abbrev-commit --decorate --color=always --date=relative --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) - %C(dim red)%an%C(reset)%C(bold yellow)%d%C(reset)' --all"; 103 109 104 - # delete merged branches 105 - bdm = "!git branch --merged | grep -v '*' | xargs -n 1 git branch -d"; 106 - undo = "!git reset HEAD~1 --mixed"; 107 - blm = "blame -w -C -C -C"; 110 + # delete merged branches 111 + bdm = "!git branch --merged | grep -v '*' | xargs -n 1 git branch -d"; 112 + undo = "!git reset HEAD~1 --mixed"; 113 + blm = "blame -w -C -C -C"; 114 + }; 108 115 }; 109 116 }; 110 117 }
+143 -113
home/profiles/nvim/default.nix
··· 1 - { pkgs, lib, config, ... }: 1 + { 2 + pkgs, 3 + lib, 4 + config, 5 + ... 6 + }: 2 7 let 3 8 customPlugins = { 4 9 vim-zettel = pkgs.vimUtils.buildVimPlugin { ··· 116 121 }; 117 122 }; 118 123 119 - my-python-packages = python-packages: with python-packages; [ 120 - tasklib 121 - pynvim 122 - six 123 - # other python packages you want 124 - ]; 124 + my-python-packages = 125 + python-packages: with python-packages; [ 126 + tasklib 127 + pynvim 128 + six 129 + # other python packages you want 130 + ]; 125 131 python-with-my-packages = pkgs.python3.withPackages my-python-packages; 126 132 in 127 133 { ··· 146 152 ''; 147 153 148 154 # Private mode plugin for concealing buffer content (out of store symlink for live editing) 149 - home.file.".config/nvim/lua/private-mode.lua".source = config.lib.file.mkOutOfStoreSymlink "${toString ./.}/private-mode.lua"; 155 + home.file.".config/nvim/lua/private-mode.lua".source = 156 + config.lib.file.mkOutOfStoreSymlink "${toString ./.}/private-mode.lua"; 150 157 151 158 #environment.systemPackages = with customPlugins; [ tidal ]; 152 159 programs.neovim = { ··· 483 490 484 491 485 492 vim.api.nvim_set_keymap('n', '<leader>vt', ':call v:lua.toggle_diagnostics()<CR>', {noremap = true, silent = true}) 486 - 493 + 487 494 -- nicer diff view 488 495 vim.opt.diffopt = {'internal', 'filler', 'closeoff', 'algorithm:patience', 'indent-heuristic'} 489 - 496 + 490 497 -- autopairs 491 498 require('nvim-autopairs').setup{} 492 499 ··· 577 584 Function = "ƒ " 578 585 } 579 586 } 580 - 587 + 581 588 -- Setup neo-tree 582 589 require("neo-tree").setup {} 583 - 590 + 584 591 -- Setup outline 585 592 require("outline").setup {} 586 - 593 + 587 594 -- Setup trouble 588 595 require("trouble").setup {} 589 - 596 + 590 597 -- Setup noice for floating command palette and notifications 591 598 require("noice").setup({ 592 599 cmdline = { ··· 636 643 }, 637 644 }, 638 645 }) 639 - 646 + 640 647 -- Setup barbar (tabline with icons) 641 648 require'barbar'.setup { 642 649 icons = { ··· 646 653 }, 647 654 } 648 655 local navic = require("nvim-navic") 649 - 656 + 650 657 -- Setup conform.nvim for formatting 651 658 require("conform").setup({ 652 659 formatters_by_ft = { ··· 880 887 881 888 require("which-key").setup{} 882 889 require('leap').set_default_keymaps() 883 - 890 + 884 891 -- supercollider 885 892 local scnvim = require 'scnvim' 886 893 local map = scnvim.map ··· 1025 1032 disable_on_zoom = true, 1026 1033 mux = 'auto', -- auto-detect tmux 1027 1034 } 1028 - 1035 + 1029 1036 -- Set up Navigator.nvim keybindings 1030 1037 vim.keymap.set({'n', 't'}, '<M-h>', '<CMD>NavigatorLeft<CR>') 1031 1038 vim.keymap.set({'n', 't'}, '<M-j>', '<CMD>NavigatorDown<CR>') 1032 1039 vim.keymap.set({'n', 't'}, '<M-k>', '<CMD>NavigatorUp<CR>') 1033 1040 vim.keymap.set({'n', 't'}, '<M-l>', '<CMD>NavigatorRight<CR>') 1034 1041 1035 - -- Paste from system clipboard in insert mode (handles tmux/kitty better) 1036 - -- vim.keymap.set('i', '<C-v>', '<C-r><C-p>+', {noremap = true, silent = true}) 1042 + -- Paste from system clipboard in insert mode (Ctrl+V in normal mode remains visual block) 1043 + vim.keymap.set('i', '<C-v>', '<C-r><C-p>+', {noremap = true, silent = true}) 1037 1044 1038 1045 -- Pane resizing with Alt+Shift+hjkl (to match tmux) 1039 1046 vim.keymap.set('n', '<M-S-h>', '<Cmd>vertical resize -2<CR>', {silent = true}) ··· 1130 1137 zk 1131 1138 ]; 1132 1139 1133 - plugins = with pkgs.vimPlugins // customPlugins; [ 1134 - # ui 1135 - lualine-nvim 1136 - fzf-vim 1137 - neo-tree-nvim 1138 - outline-nvim 1139 - noice-nvim 1140 - nui-nvim 1141 - trouble-nvim 1142 - neovim-ayu 1143 - rainbow_parentheses-vim 1144 - vim-surround 1145 - vim-devicons 1146 - nvim-web-devicons 1147 - undotree 1148 - telescope-nvim 1149 - plenary-nvim 1150 - nvim-navic 1151 - (nvim-treesitter.withPlugins (p: [ p.nix p.clojure p.python p.fennel p.lua p.html p.css p.regex p.supercollider p.beancount p.markdown p.glsl p.yaml p.toml p.dockerfile p.json ])) 1152 - nvim-treesitter-context 1153 - my-fterm 1154 - barbar-nvim 1155 - auto-session 1156 - my-marks 1157 - which-key-nvim 1158 - nvim-peekup 1159 - zen-mode-nvim 1160 - twilight-nvim 1161 - my-lspsaga 1162 - vim-dasht 1140 + plugins = 1141 + with pkgs.vimPlugins // customPlugins; 1142 + [ 1143 + # ui 1144 + lualine-nvim 1145 + fzf-vim 1146 + neo-tree-nvim 1147 + outline-nvim 1148 + noice-nvim 1149 + nui-nvim 1150 + trouble-nvim 1151 + neovim-ayu 1152 + rainbow_parentheses-vim 1153 + vim-surround 1154 + vim-devicons 1155 + nvim-web-devicons 1156 + undotree 1157 + telescope-nvim 1158 + plenary-nvim 1159 + nvim-navic 1160 + (nvim-treesitter.withPlugins (p: [ 1161 + p.nix 1162 + p.clojure 1163 + p.python 1164 + p.fennel 1165 + p.lua 1166 + p.html 1167 + p.css 1168 + p.regex 1169 + p.supercollider 1170 + p.beancount 1171 + p.markdown 1172 + p.glsl 1173 + p.yaml 1174 + p.toml 1175 + p.dockerfile 1176 + p.json 1177 + ])) 1178 + nvim-treesitter-context 1179 + my-fterm 1180 + barbar-nvim 1181 + auto-session 1182 + my-marks 1183 + which-key-nvim 1184 + nvim-peekup 1185 + zen-mode-nvim 1186 + twilight-nvim 1187 + my-lspsaga 1188 + vim-dasht 1163 1189 1164 - # language 1165 - vim-nix 1166 - vim-elixir 1167 - emmet-vim 1168 - csv-vim 1169 - direnv-vim 1170 - zig-vim 1171 - conjure 1190 + # language 1191 + vim-nix 1192 + vim-elixir 1193 + emmet-vim 1194 + csv-vim 1195 + direnv-vim 1196 + zig-vim 1197 + conjure 1172 1198 1173 - # kitaab stuff 1174 - vimwiki 1175 - taskwiki 1176 - vim-zettel 1177 - hologram-nvim 1178 - zk-nvim 1199 + # kitaab stuff 1200 + vimwiki 1201 + taskwiki 1202 + vim-zettel 1203 + hologram-nvim 1204 + zk-nvim 1179 1205 1180 - # lsp stuff 1181 - # nvim-lint 1182 - nvim-lspconfig 1183 - nvim-cmp 1184 - cmp-nvim-lsp 1185 - cmp-treesitter 1186 - nvim-lsp-ts-utils 1187 - cmp-conjure 1188 - cmp-buffer 1189 - cmp-path 1190 - cmp-spell 1191 - nvim-autopairs 1192 - cmp_luasnip 1193 - luasnip 1194 - conform-nvim 1195 - friendly-snippets 1196 - lspkind-nvim 1206 + # lsp stuff 1207 + # nvim-lint 1208 + nvim-lspconfig 1209 + nvim-cmp 1210 + cmp-nvim-lsp 1211 + cmp-treesitter 1212 + nvim-lsp-ts-utils 1213 + cmp-conjure 1214 + cmp-buffer 1215 + cmp-path 1216 + cmp-spell 1217 + nvim-autopairs 1218 + cmp_luasnip 1219 + luasnip 1220 + conform-nvim 1221 + friendly-snippets 1222 + lspkind-nvim 1197 1223 1198 - # git stuff 1199 - vim-fugitive 1200 - gitsigns-nvim 1201 - fzf-checkout-vim 1202 - diffview-nvim 1224 + # git stuff 1225 + vim-fugitive 1226 + gitsigns-nvim 1227 + fzf-checkout-vim 1228 + diffview-nvim 1203 1229 1204 - # Clojure stuff 1205 - # conjure 1206 - vim-sexp 1207 - vim-sexp-mappings-for-regular-people 1208 - fennel-vim 1230 + # Clojure stuff 1231 + # conjure 1232 + vim-sexp 1233 + vim-sexp-mappings-for-regular-people 1234 + fennel-vim 1209 1235 1210 - # experimental 1211 - nvim-luapad 1212 - gh-addressed 1213 - scnvim 1214 - leap-nvim 1215 - Navigator-nvim 1216 - vim-beancount 1217 - # vimtex 1218 - # custom 1219 - yuck-vim 1220 - nvim-parinfer 1221 - 1222 - # opencode integration 1223 - opencode-nvim 1224 - # vim-processing 1225 - ] ++ lib.optionals pkgs.stdenv.isLinux [ 1226 - # Linux-only plugins 1227 - vim-tidal # requires SuperCollider which is Linux-only 1228 - ]; 1236 + # experimental 1237 + nvim-luapad 1238 + gh-addressed 1239 + scnvim 1240 + leap-nvim 1241 + Navigator-nvim 1242 + vim-beancount 1243 + # vimtex 1244 + # custom 1245 + yuck-vim 1246 + nvim-parinfer 1247 + 1248 + # opencode integration 1249 + opencode-nvim 1250 + # vim-processing 1251 + ] 1252 + ++ lib.optionals pkgs.stdenv.isLinux [ 1253 + # Linux-only plugins 1254 + vim-tidal # requires SuperCollider which is Linux-only 1255 + ]; 1229 1256 withPython3 = true; 1230 - extraPython3Packages = pkgs: with pkgs; [ tasklib six packaging ]; 1257 + extraPython3Packages = 1258 + pkgs: with pkgs; [ 1259 + tasklib 1260 + six 1261 + packaging 1262 + ]; 1231 1263 vimAlias = true; 1232 1264 }; 1233 1265 } 1234 - 1235 -
+2 -1
home/profiles/opencode/agent/adversary.md home/profiles/opencode/agents/adversary.md
··· 1 1 --- 2 2 description: Adversarial code reviewer that critically examines code for flaws, bugs, and design issues. Invoke with @adversary to get a devil's advocate perspective on your code. 3 - mode: subagent 3 + mode: all 4 + color: "#E0115F" 4 5 temperature: 0.2 5 6 tools: 6 7 "*": false
-73
home/profiles/opencode/agent/archivist.md
··· 1 - --- 2 - description: Search through past OpenCode sessions to find relevant context, previous solutions, and historical decisions. Use this when you need to recall how something was done before or find related past work. 3 - mode: subagent 4 - model: anthropic/claude-haiku-4-5 5 - temperature: 0.1 6 - tools: 7 - "*": false 8 - search-history: true 9 - skill: true 10 - permission: 11 - skill: 12 - "session-search": allow 13 - "*": deny 14 - --- 15 - 16 - You are the Archivist, a specialized agent that searches through OpenCode session history to find relevant past conversations, code changes, and decisions. 17 - 18 - You are running inside an AI coding system as a subagent. The main agent invokes you when it needs to find relevant context from previous sessions. 19 - 20 - ## Your Purpose 21 - 22 - When invoked, you will: 23 - 1. Search through the local OpenCode session history 24 - 2. Find sessions and messages relevant to the query 25 - 3. Synthesize findings into a clear, actionable answer 26 - 27 - ## How to Search 28 - 29 - First, load the `session-search` skill to understand the search strategies and storage structure. 30 - 31 - Then use the `search-history` tool to find relevant sessions. You can: 32 - - Search by keywords, code patterns, file names, or concepts 33 - - Filter by project directory if the query is project-specific 34 - - List recent sessions to get an overview 35 - 36 - ## Search Strategies 37 - 38 - 1. **Start broad**: Use general keywords related to the query 39 - 2. **Refine**: If too many results, add more specific terms or filter by directory 40 - 3. **Cross-reference**: Search for related terms (e.g., if searching for "auth", also try "login", "authentication") 41 - 4. **Check context**: Look at session titles and directories to understand the context 42 - 43 - ## Response Format 44 - 45 - Your response should directly answer the question posed, using information from past sessions: 46 - 47 - 1. **Direct answer**: What was found that addresses the question 48 - 2. **Relevant sessions**: List session IDs where this was discussed (so user can resume if needed) 49 - 3. **Key details**: Important snippets or decisions from the history 50 - 51 - Example response: 52 - ``` 53 - Based on past sessions, authentication was implemented using JWT tokens with a 24-hour expiry. 54 - 55 - **Relevant sessions:** 56 - - ses_abc123 - "Implementing user auth" (2024-01-15) 57 - - ses_def456 - "Auth token refresh" (2024-01-20) 58 - 59 - **Key details:** 60 - - Tokens are stored in httpOnly cookies 61 - - Refresh endpoint at /api/auth/refresh 62 - - Used jose library for JWT handling 63 - ``` 64 - 65 - ## Guidelines 66 - 67 - - Be concise and direct - the main agent needs actionable information 68 - - Include session IDs so the user can explore further if needed 69 - - If nothing relevant is found, say so clearly 70 - - Focus on answering the specific question, not providing exhaustive history 71 - - Never fabricate information - only report what's actually in the history 72 - 73 - IMPORTANT: Your final message is returned to the main agent. Make it comprehensive but focused on answering the original question.
home/profiles/opencode/agent/librarian.md home/profiles/opencode/agents/librarian.md
+41
home/profiles/opencode/agents/box.md
··· 1 + # Box Server Environment 2 + 3 + You are running on `box`, a NAS server. The user is interacting remotely via mobile phone and cannot run local debugging tools, browser devtools, or inspect terminals directly. 4 + 5 + ## Remote Development Constraints 6 + 7 + - User has no access to browser devtools or local terminal inspection 8 + - Be verbose with output - include full error messages and logs 9 + - Provide curl commands for testing endpoints 10 + - Explain what's happening at each step since user can't easily inspect 11 + 12 + ## Running Dev Servers 13 + 14 + When starting development servers or long-running processes: 15 + 16 + 1. **Use the `tmux` skill** - load it with `/skill tmux` for detailed instructions on spawning and managing background processes 17 + 18 + 2. **Port Selection**: Use ports in the range **7000-9000** (firewall is configured for this range) 19 + 20 + 3. **Bind Address**: Always bind to `0.0.0.0`, not `localhost`, so the server is accessible from other devices 21 + 22 + Example commands: 23 + - Vite: `npm run dev -- --host 0.0.0.0 --port 7500` 24 + - Next.js: `npm run dev -- -H 0.0.0.0 -p 7500` 25 + - Generic: `HOST=0.0.0.0 PORT=7500 npm start` 26 + 27 + 4. **Session Naming**: Name tmux sessions/windows after the project (e.g., `tmux new-window -n "helm-dev" -d`) 28 + 29 + ## Network Access 30 + 31 + The user can access dev servers at: 32 + - **Wireguard**: `http://10.0.69.4:<port>` (from any device on the VPN) 33 + - **LAN**: `http://mossnet.lan:<port>` (from local network) 34 + 35 + ## Debugging 36 + 37 + Since the user cannot inspect the browser or terminal directly: 38 + - Always capture and report server logs using `tmux capture-pane` 39 + - Include full stack traces in responses 40 + - Suggest curl commands to test API endpoints 41 + - When something fails, proactively check logs before asking the user
+106
home/profiles/opencode/agents/learn.md
··· 1 + --- 2 + description: Socratic teaching mode that guides learning through questions rather than direct answers. Use when learning new codebases, concepts, or technologies. 3 + mode: primary 4 + color: "#22C55E" 5 + temperature: 0.3 6 + tools: 7 + "*": false 8 + read: true 9 + glob: true 10 + grep: true 11 + webfetch: true 12 + task: true 13 + skill: true 14 + --- 15 + 16 + You are a Socratic programming tutor. Your purpose is to guide the user's understanding through thoughtful questions and exploration, not to provide direct answers or write code for them. 17 + 18 + You are running inside an AI coding system as a primary agent mode. Users switch to you when they want to learn rather than just get things done. 19 + 20 + ## Core Principles 21 + 22 + 1. **Guide, don't answer**: Ask "How would you approach this?" instead of solving 23 + 2. **Socratic questioning**: Use "What do you notice?", "What happens if...?", "What evidence supports that?" 24 + 3. **Emphasize fundamentals**: Highlight underlying principles, not just syntax or implementation details 25 + 4. **Scaffold learning**: Provide progressively specific hints when the user is stuck, not solutions 26 + 27 + ## Teaching Strategies 28 + 29 + ### Starting a Topic 30 + - Ask what the user already knows or expects 31 + - Identify their mental model before exploring code 32 + - Frame the exploration as a joint investigation 33 + 34 + ### During Exploration 35 + - Point to relevant code/docs but ask the user to interpret what they see 36 + - Use "What do you notice about...?" questions 37 + - Ask the user to predict behavior before revealing it 38 + - Connect new concepts to things they already understand 39 + 40 + ### When They're Stuck 41 + - Offer a small hint, not the answer 42 + - Break the problem into smaller questions 43 + - Ask what specific part is confusing 44 + - Suggest a simpler related example to reason through first 45 + 46 + ### Building Understanding 47 + - Ask the user to explain their understanding back to you 48 + - Have them trace through code mentally or on paper 49 + - Encourage them to form hypotheses and test them 50 + - Celebrate correct reasoning; gently redirect misconceptions 51 + 52 + ## Response Patterns 53 + 54 + **Good**: "What do you think this function is responsible for, based on its name and parameters?" 55 + 56 + **Good**: "You mentioned JWT tokens. Where would you expect to find token validation logic? Let's check your hypothesis." 57 + 58 + **Good**: "That's a solid observation about the middleware. What implications does that have for how errors are handled?" 59 + 60 + **Avoid**: "Here's how authentication works: [explanation]" 61 + 62 + **Avoid**: "The answer is X because Y." 63 + 64 + **Avoid**: Writing or suggesting code solutions directly. 65 + 66 + ## When Asked to "Just Tell Me" 67 + 68 + Acknowledge their frustration, but gently redirect: 69 + 70 + > I understand you want a quick answer, but working through this will help it stick. Let me give you a more specific hint: [focused question or smaller piece of the puzzle] 71 + 72 + If they insist after multiple attempts, you may provide a partial explanation while still prompting them to fill in gaps. 73 + 74 + ## Tools Usage 75 + 76 + You have read-only access to explore code and fetch documentation: 77 + 78 + - **read/glob/grep**: Explore the local codebase to find relevant examples 79 + - **webfetch**: Fetch documentation, tutorials, or reference material 80 + - **task**: Delegate research to specialized agents (librarian, explore) when needed 81 + - **skill**: Load skills for specialized knowledge 82 + 83 + Use these to gather context and point the user toward relevant material - but always frame findings as prompts for their analysis, not answers. 84 + 85 + ## Providing Structure (When Asked) 86 + 87 + You may create: 88 + - **Learning paths**: Ordered list of concepts to study 89 + - **Study guides**: Key questions to answer about a topic 90 + - **Practice exercises**: Problems for the user to solve (without solutions) 91 + - **Concept maps**: How ideas relate to each other 92 + 93 + ## Communication 94 + 95 + Use Markdown for formatting. When including code blocks, always specify the language. 96 + 97 + Be warm and encouraging, but not patronizing. You're a patient mentor who believes the user can figure things out with the right guidance. 98 + 99 + Keep responses focused. A few good questions are better than a wall of text. 100 + 101 + ## Constraints 102 + 103 + - You cannot edit files or run commands that modify state 104 + - You must not provide direct code solutions 105 + - If the user needs code written, suggest they switch to build mode 106 + - Your role is to develop understanding, not to complete tasks for them
home/profiles/opencode/command/cleanup.md home/profiles/opencode/commands/cleanup.md
+13 -11
home/profiles/opencode/default.nix
··· 2 2 pkgs, 3 3 lib, 4 4 inputs, 5 + osConfig ? { }, 5 6 ... 6 7 }: 7 8 9 + let 10 + # Check if we're running on box (for box-specific config) 11 + isBox = (osConfig.networking.hostName or "") == "box"; 12 + in 8 13 let 9 14 # Paths to agenix-decrypted secrets (same on Darwin and NixOS) 10 15 githubToken = "/run/agenix/github-token"; ··· 29 34 autoupdate = false; 30 35 permission = { 31 36 external_directory = "allow"; 32 - # Restrict session-search skill to archivist only 33 - skill = { 34 - "session-search" = "deny"; 35 - }; 36 37 }; 37 38 provider = { 38 39 anthropic = { ··· 60 61 #plugin = ["@plannotator/opencode@latest"]; 61 62 }; 62 63 63 - "opencode/themes/ayu-mirage.json".source = ./themes/ayu-mirage.json; 64 - "opencode/agent/librarian.md".source = ./agent/librarian.md; 65 - "opencode/agent/adversary.md".source = ./agent/adversary.md; 66 - "opencode/agent/archivist.md".source = ./agent/archivist.md; 67 - "opencode/command/cleanup.md".source = ./command/cleanup.md; 68 - "opencode/tool/search-history.ts".source = ./tool/search-history.ts; 69 - "opencode/skill/session-search/SKILL.md".source = ./skill/session-search/SKILL.md; 64 + "opencode/themes".source = ./themes; 65 + "opencode/agents".source = ./agents; 66 + "opencode/commands".source = ./commands; 67 + "opencode/skills".source = ./skills; 68 + }; 69 + 70 + home.file = lib.mkIf isBox { 71 + "usr/.opencode/agents.md".source = ./agents/box.md; 70 72 }; 71 73 }
-104
home/profiles/opencode/skill/session-search/SKILL.md
··· 1 - --- 2 - name: session-search 3 - description: Advanced strategies for searching OpenCode session history. Restricted to the archivist agent. 4 - --- 5 - 6 - # Session Search Skill 7 - 8 - This skill provides advanced strategies for searching through OpenCode's session history storage. 9 - 10 - ## Storage Structure 11 - 12 - OpenCode stores data in `~/.local/share/opencode/storage/`: 13 - 14 - ``` 15 - storage/ 16 - ├── session/ # Session metadata by project 17 - │ └── {projectHash}/ 18 - │ └── ses_*.json # Session info (title, directory, timestamps) 19 - ├── message/ # Messages organized by session 20 - │ └── ses_*/ 21 - │ └── msg_*.json # Message metadata (role, agent, model) 22 - ├── part/ # Actual message content 23 - │ └── msg_*/ 24 - │ └── prt_*.json # Content parts (text, tool calls) 25 - └── project/ # Project metadata 26 - └── {hash}.json # Worktree path, timestamps 27 - ``` 28 - 29 - ## Search Tool Usage 30 - 31 - The `search-history` tool accepts: 32 - - `query`: Text pattern to search for (searches message content) 33 - - `directory`: Optional filter by project path (partial match) 34 - - `limit`: Max results (default 30) 35 - 36 - ### Examples 37 - 38 - ```typescript 39 - // Find all sessions mentioning "authentication" 40 - search-history({ query: "authentication" }) 41 - 42 - // Find sessions in a specific project 43 - search-history({ query: "database", directory: "myproject" }) 44 - 45 - // List recent sessions (empty query) 46 - search-history({ query: "", limit: 20 }) 47 - ``` 48 - 49 - ## Search Strategies 50 - 51 - ### 1. Keyword Expansion 52 - Don't just search for the exact term. Try synonyms and related concepts: 53 - - "auth" → also try "login", "authentication", "jwt", "token" 54 - - "database" → also try "postgres", "sqlite", "db", "migration" 55 - - "api" → also try "endpoint", "route", "handler" 56 - 57 - ### 2. Code Pattern Search 58 - Search for code-specific patterns: 59 - - Function names: `handleAuth`, `validateToken` 60 - - File paths: `src/auth`, `lib/database` 61 - - Import statements: `import.*prisma` 62 - - Error messages: specific error text 63 - 64 - ### 3. Tool Usage Search 65 - Find when specific tools were used: 66 - - Edit operations: search for file paths that were edited 67 - - Bash commands: search for command names 68 - - Specific operations: "git push", "npm install" 69 - 70 - ### 4. Directory Filtering 71 - Use the `directory` parameter to scope searches: 72 - - Filter by project name: `directory: "myapp"` 73 - - Filter by path segment: `directory: "usr/projects"` 74 - 75 - ### 5. Iterative Refinement 76 - 1. Start with broad search 77 - 2. If too many results, add specificity 78 - 3. If no results, broaden or try alternative terms 79 - 4. Cross-reference multiple searches 80 - 81 - ## Understanding Results 82 - 83 - ### Session Info 84 - - `id`: Unique session identifier (can be used to reference) 85 - - `title`: Auto-generated session title 86 - - `directory`: Project worktree path 87 - - `updated`: Last activity timestamp 88 - 89 - ### Content Matches 90 - - `sessionID`: Which session contains this match 91 - - `snippet`: Context around the match (±100 chars) 92 - - `role`: user/assistant/tool 93 - 94 - ## Tips 95 - 96 - 1. **Recent vs Relevant**: The tool returns recent sessions first. Older but more relevant sessions may be further in results. 97 - 98 - 2. **Title Search**: Session titles are auto-generated from the conversation and can be good search targets. 99 - 100 - 3. **Multiple Searches**: Don't hesitate to run multiple searches with different terms to build a complete picture. 101 - 102 - 4. **Context Matters**: The snippet provides limited context. Session titles and directories help understand the broader context. 103 - 104 - 5. **No Results**: If no results found, the pattern may be too specific. Try shorter or more general terms.
+97
home/profiles/opencode/skills/tmux/SKILL.md
··· 1 + --- 2 + name: tmux 3 + description: Instructions for using tmux to spawn multiple processes, inspect them, and capture their output. Useful for running servers or long-running tasks in the background. 4 + allowed-tools: 5 + - Bash 6 + --- 7 + 8 + # Tmux Skill 9 + 10 + This skill empowers you to manage multiple concurrent processes (like servers, watchers, or long builds) using `tmux` directly from the `Bash` tool. 11 + 12 + Since you are likely already running inside a tmux session, you can spawn new windows or panes to handle these tasks without blocking your main communication channel. 13 + 14 + ## 1. Verify Environment & Check Status 15 + 16 + First, verify you are running inside tmux: 17 + 18 + ```bash 19 + echo $TMUX 20 + ``` 21 + 22 + If this returns empty, you are not running inside tmux and these commands will not work as expected. 23 + 24 + Once verified, check your current windows: 25 + 26 + ```bash 27 + tmux list-windows 28 + ``` 29 + 30 + ## 2. Spawn a Background Process 31 + 32 + To run a command (e.g., a dev server) in a way that persists and can be inspected: 33 + 34 + 1. **Create a new detached window** with a specific name. This keeps it isolated and easy to reference. 35 + 36 + ```bash 37 + tmux new-window -n "server-log" -d 38 + ``` 39 + 40 + _(Replace "server-log" with a relevant name for your task)_ 41 + 42 + 2. **Send the command** to that window. 43 + ```bash 44 + tmux send-keys -t "server-log" "npm start" C-m 45 + ``` 46 + _(`C-m` simulates the Enter key)_ 47 + 48 + ## 3. Inspect Output (Read Logs) 49 + 50 + You can read the output of that pane at any time without switching your context. 51 + 52 + **Get the current visible screen:** 53 + 54 + ```bash 55 + tmux capture-pane -p -t "server-log" 56 + ``` 57 + 58 + **Get the entire history (scrollback):** 59 + 60 + ```bash 61 + tmux capture-pane -p -S - -t "server-log" 62 + ``` 63 + 64 + _Use this if the output might have scrolled off the screen._ 65 + 66 + ## 4. Interact with the Process 67 + 68 + If you need to stop or restart the process: 69 + 70 + **Send Ctrl+C (Interrupt):** 71 + 72 + ```bash 73 + tmux send-keys -t "server-log" C-c 74 + ``` 75 + 76 + **Kill the window (Clean up):** 77 + 78 + ```bash 79 + tmux kill-window -t "server-log" 80 + ``` 81 + 82 + ## 5. Advanced: Chaining Commands 83 + 84 + You can chain multiple tmux commands in a single invocation using `';'` (note the quotes to avoid interpretation by the shell). This is faster and cleaner than running multiple `tmux` commands. 85 + 86 + Example: Create window and start process in one go: 87 + 88 + ```bash 89 + tmux new-window -n "server-log" -d ';' send-keys -t "server-log" "npm start" C-m 90 + ``` 91 + 92 + ## Summary of Pattern 93 + 94 + 1. `tmux new-window -n "ID" -d` 95 + 2. `tmux send-keys -t "ID" "CMD" C-m` 96 + 3. `tmux capture-pane -p -t "ID"` 97 +
-275
home/profiles/opencode/tool/search-history.ts
··· 1 - import { tool } from "@opencode-ai/plugin" 2 - import { $ } from "bun" 3 - import { readdir, readFile } from "fs/promises" 4 - import { join } from "path" 5 - import { homedir } from "os" 6 - 7 - const STORAGE_PATH = join(homedir(), ".local/share/opencode/storage") 8 - 9 - interface SessionInfo { 10 - id: string 11 - title: string 12 - directory: string 13 - projectID: string 14 - created: number 15 - updated: number 16 - } 17 - 18 - interface MessageMatch { 19 - sessionID: string 20 - messageID: string 21 - snippet: string 22 - role: string 23 - timestamp?: number 24 - } 25 - 26 - interface SearchResult { 27 - sessions: SessionInfo[] 28 - matches: MessageMatch[] 29 - totalMatches: number 30 - } 31 - 32 - async function getSessionInfo(sessionID: string): Promise<SessionInfo | null> { 33 - try { 34 - // Sessions are stored in directories named by project hash 35 - const sessionDirs = await readdir(join(STORAGE_PATH, "session")) 36 - for (const dir of sessionDirs) { 37 - const sessionPath = join(STORAGE_PATH, "session", dir) 38 - const files = await readdir(sessionPath).catch(() => []) 39 - for (const file of files) { 40 - if (file.startsWith(sessionID) || file.includes(sessionID)) { 41 - const content = await readFile(join(sessionPath, file), "utf-8") 42 - const data = JSON.parse(content) 43 - return { 44 - id: data.id, 45 - title: data.title || "Untitled", 46 - directory: data.directory || "", 47 - projectID: data.projectID || "", 48 - created: data.time?.created || 0, 49 - updated: data.time?.updated || 0, 50 - } 51 - } 52 - } 53 - } 54 - } catch { 55 - // Fall back to searching message directories 56 - } 57 - return null 58 - } 59 - 60 - async function searchWithRipgrep( 61 - pattern: string, 62 - directory?: string, 63 - limit: number = 50 64 - ): Promise<SearchResult> { 65 - const matches: MessageMatch[] = [] 66 - const sessionIDs = new Set<string>() 67 - 68 - // Search through part storage (contains actual message content) 69 - const partPath = join(STORAGE_PATH, "part") 70 - 71 - try { 72 - // Use ripgrep to search JSON files, extracting context around matches 73 - const rgResult = await $`rg -i -l ${pattern} ${partPath} --type json 2>/dev/null || true`.text() 74 - const matchingFiles = rgResult.trim().split("\n").filter(Boolean) 75 - 76 - for (const file of matchingFiles.slice(0, limit * 2)) { 77 - try { 78 - const content = await readFile(file, "utf-8") 79 - const data = JSON.parse(content) 80 - 81 - // Filter by directory if specified 82 - if (directory) { 83 - const sessionInfo = await getSessionInfo(data.sessionID) 84 - if (sessionInfo && !sessionInfo.directory.includes(directory)) { 85 - continue 86 - } 87 - } 88 - 89 - // Extract snippet around the match 90 - const text = data.text || data.content || JSON.stringify(data) 91 - const lowerText = text.toLowerCase() 92 - const lowerPattern = pattern.toLowerCase() 93 - const matchIndex = lowerText.indexOf(lowerPattern) 94 - 95 - if (matchIndex !== -1) { 96 - const start = Math.max(0, matchIndex - 100) 97 - const end = Math.min(text.length, matchIndex + pattern.length + 100) 98 - const snippet = (start > 0 ? "..." : "") + 99 - text.slice(start, end) + 100 - (end < text.length ? "..." : "") 101 - 102 - matches.push({ 103 - sessionID: data.sessionID, 104 - messageID: data.messageID, 105 - snippet: snippet.replace(/\n/g, " ").trim(), 106 - role: data.role || "unknown", 107 - timestamp: data.time?.created, 108 - }) 109 - 110 - sessionIDs.add(data.sessionID) 111 - 112 - if (matches.length >= limit) break 113 - } 114 - } catch { 115 - // Skip files that can't be parsed 116 - } 117 - } 118 - } catch (e) { 119 - // ripgrep not found or error 120 - } 121 - 122 - // Also search message metadata for titles 123 - const messagePath = join(STORAGE_PATH, "message") 124 - try { 125 - const rgResult = await $`rg -i -l ${pattern} ${messagePath} --type json 2>/dev/null || true`.text() 126 - const matchingFiles = rgResult.trim().split("\n").filter(Boolean) 127 - 128 - for (const file of matchingFiles.slice(0, 20)) { 129 - try { 130 - const content = await readFile(file, "utf-8") 131 - const data = JSON.parse(content) 132 - if (data.sessionID) { 133 - sessionIDs.add(data.sessionID) 134 - } 135 - } catch { 136 - // Skip 137 - } 138 - } 139 - } catch { 140 - // Ignore errors 141 - } 142 - 143 - // Get session info for all matched sessions 144 - const sessions: SessionInfo[] = [] 145 - for (const sessionID of sessionIDs) { 146 - const info = await getSessionInfo(sessionID) 147 - if (info) { 148 - // Apply directory filter for sessions too 149 - if (!directory || info.directory.includes(directory)) { 150 - sessions.push(info) 151 - } 152 - } 153 - } 154 - 155 - // Sort sessions by most recent 156 - sessions.sort((a, b) => b.updated - a.updated) 157 - 158 - return { 159 - sessions: sessions.slice(0, 20), 160 - matches: matches.slice(0, limit), 161 - totalMatches: matches.length, 162 - } 163 - } 164 - 165 - async function listRecentSessions( 166 - directory?: string, 167 - limit: number = 20 168 - ): Promise<SessionInfo[]> { 169 - const sessions: SessionInfo[] = [] 170 - 171 - try { 172 - const sessionDirs = await readdir(join(STORAGE_PATH, "session")) 173 - 174 - for (const dir of sessionDirs) { 175 - const sessionPath = join(STORAGE_PATH, "session", dir) 176 - const files = await readdir(sessionPath).catch(() => []) 177 - 178 - for (const file of files) { 179 - if (!file.endsWith(".json")) continue 180 - try { 181 - const content = await readFile(join(sessionPath, file), "utf-8") 182 - const data = JSON.parse(content) 183 - 184 - if (directory && !data.directory?.includes(directory)) { 185 - continue 186 - } 187 - 188 - sessions.push({ 189 - id: data.id, 190 - title: data.title || "Untitled", 191 - directory: data.directory || "", 192 - projectID: data.projectID || "", 193 - created: data.time?.created || 0, 194 - updated: data.time?.updated || 0, 195 - }) 196 - } catch { 197 - // Skip invalid files 198 - } 199 - } 200 - } 201 - } catch { 202 - // Storage doesn't exist 203 - } 204 - 205 - sessions.sort((a, b) => b.updated - a.updated) 206 - return sessions.slice(0, limit) 207 - } 208 - 209 - export default tool({ 210 - description: 211 - "Search through OpenCode session history to find past conversations, code changes, and decisions. Use this to find relevant context from previous sessions.", 212 - args: { 213 - query: tool.schema 214 - .string() 215 - .describe( 216 - "Search pattern to find in session history. Searches message content, titles, and tool outputs." 217 - ), 218 - directory: tool.schema 219 - .string() 220 - .optional() 221 - .describe( 222 - "Optional: Filter results to sessions from a specific project directory path (partial match)" 223 - ), 224 - limit: tool.schema 225 - .number() 226 - .optional() 227 - .describe("Maximum number of matches to return (default: 30)"), 228 - }, 229 - async execute(args) { 230 - const limit = args.limit || 30 231 - 232 - if (!args.query || args.query.trim() === "") { 233 - // List recent sessions if no query 234 - const sessions = await listRecentSessions(args.directory, limit) 235 - return JSON.stringify( 236 - { 237 - type: "recent_sessions", 238 - sessions, 239 - message: `Found ${sessions.length} recent sessions${args.directory ? ` in ${args.directory}` : ""}`, 240 - }, 241 - null, 242 - 2 243 - ) 244 - } 245 - 246 - const results = await searchWithRipgrep(args.query, args.directory, limit) 247 - 248 - // Format output for the agent 249 - let output = `## Search Results for "${args.query}"\n\n` 250 - 251 - if (results.sessions.length > 0) { 252 - output += `### Relevant Sessions (${results.sessions.length})\n\n` 253 - for (const session of results.sessions) { 254 - const date = new Date(session.updated).toLocaleDateString() 255 - output += `- **${session.title}** (${session.id})\n` 256 - output += ` - Directory: \`${session.directory}\`\n` 257 - output += ` - Last updated: ${date}\n\n` 258 - } 259 - } 260 - 261 - if (results.matches.length > 0) { 262 - output += `### Content Matches (${results.totalMatches})\n\n` 263 - for (const match of results.matches.slice(0, 15)) { 264 - output += `**Session:** ${match.sessionID}\n` 265 - output += `> ${match.snippet}\n\n` 266 - } 267 - } 268 - 269 - if (results.sessions.length === 0 && results.matches.length === 0) { 270 - output += `No matches found for "${args.query}"${args.directory ? ` in ${args.directory}` : ""}\n` 271 - } 272 - 273 - return output 274 - }, 275 - })
+3 -1
hosts/box/default.nix
··· 10 10 ../profiles/monitoring 11 11 ../profiles/nfs 12 12 ../profiles/gonic 13 - ../profiles/headphones 13 + # ../profiles/headphones 14 14 ../profiles/radicale 15 15 # ../profiles/seafile # waiting for https://github.com/NixOS/nixpkgs/pull/249523 to be merged 16 16 ../profiles/syncthing ··· 20 20 ../profiles/finance 21 21 ../profiles/sync/website 22 22 ../profiles/sync/music 23 + ../profiles/sync/tv 23 24 # ../profiles/grasp # private repo - disabled 24 25 # ../profiles/archivebox # requires insecure django - fix in flake.nix permittedInsecurePackages 25 26 ../profiles/woodpecker-agent ··· 31 32 ../profiles/transmission 32 33 ../profiles/raven 33 34 ../profiles/radicle-node 35 + ../profiles/opencode-server 34 36 # ../profiles/postgres_upgrade_script # one-time use 35 37 ]; 36 38
+1
hosts/curve/default.nix
··· 12 12 ../profiles/mimetypes 13 13 ../profiles/syncthing 14 14 ../profiles/mossnet-hosts 15 + ../profiles/opencode-server 15 16 # ../profiles/fly-wg 16 17 # ../profiles/kuberenetes 17 18 # ../profiles/mount-mossnet
+6 -5
hosts/helix/default.nix
··· 11 11 ../profiles/core 12 12 ../profiles/server 13 13 # ../profiles/metrics 14 - # ../profiles/gitea # Replaced by radicle 15 - ../profiles/radicle-seed 14 + ../profiles/gitea 15 + # ../profiles/radicle-seed 16 16 # ../profiles/woodpecker-server 17 17 ../profiles/rss-bridge 18 18 # ../profiles/mount-mossnet 19 - ../profiles/freshrss 20 - ../profiles/microbin 21 - ../profiles/site 19 + # ../profiles/freshrss 20 + # ../profiles/microbin 21 + # TODO: re-enable after basant pyproject fix for 25.11 22 + # ../profiles/site 22 23 23 24 # ../profiles/postgres_upgrade_script 24 25 ];
+1
hosts/profiles/immich/default.nix
··· 5 5 package = pkgs.unstable.immich; 6 6 database = { 7 7 enable = true; 8 + enableVectorChord = true; # 25.11: Use VectorChord instead of pgvecto-rs 8 9 }; 9 10 host = "0.0.0.0"; 10 11 port = 8567;
+38 -2
hosts/profiles/jacket/default.nix
··· 1 - { config, lib, pkgs, ... }: 1 + { 2 + config, 3 + lib, 4 + pkgs, 5 + ... 6 + }: 2 7 { 3 8 services.jackett = { 4 9 enable = true; ··· 17 22 ''; 18 23 }; 19 24 }; 25 + 20 26 services.lidarr = { 21 27 enable = true; 22 - user = "headphones"; 23 28 group = "audio"; 24 29 }; 25 30 services.nginx.virtualHosts."lidarr.mossnet.lan" = { ··· 32 37 ''; 33 38 }; 34 39 }; 40 + 41 + services.sonarr = { 42 + enable = true; 43 + group = "video"; 44 + }; 45 + services.nginx.virtualHosts."sonarr.mossnet.lan" = { 46 + enableACME = false; 47 + forceSSL = false; 48 + 49 + locations."/" = { 50 + extraConfig = '' 51 + proxy_pass http://127.0.0.1:8989/; 52 + ''; 53 + }; 54 + }; 55 + 56 + services.jellyseerr = { 57 + enable = true; 58 + # group = "video"; 59 + }; 60 + services.nginx.virtualHosts."seerr.mossnet.lan" = { 61 + enableACME = false; 62 + forceSSL = false; 63 + 64 + locations."/" = { 65 + extraConfig = '' 66 + proxy_pass http://127.0.0.1:5055/; 67 + ''; 68 + }; 69 + }; 70 + 35 71 }
+4 -4
hosts/profiles/jellyfin/default.nix
··· 6 6 }: 7 7 { 8 8 # Enable Hardware Acceleration for transcoding 9 - # Note: vaapiIntel override with enableHybridCodec should be in flake.nix overlay if needed 9 + # Note: intel-vaapi-driver override with enableHybridCodec should be in flake.nix overlay if needed 10 10 hardware.graphics = { 11 11 enable = true; 12 12 extraPackages = with pkgs; [ 13 13 intel-media-driver 14 - vaapiIntel 15 - vaapiVdpau 14 + intel-vaapi-driver # renamed from vaapiIntel in 25.11 15 + libva-vdpau-driver # renamed from vaapiVdpau in 25.11 16 16 libvdpau-va-gl 17 17 intel-compute-runtime # OpenCL filter support (hardware tonemapping and subtitle burn-in) 18 18 ]; ··· 37 37 enableACME = false; 38 38 locations."/".proxyPass = "http://localhost:8096/"; 39 39 }; 40 - }; 40 + }; 41 41 }; 42 42 }
+2 -2
hosts/profiles/matrix/compress-state-service.nix
··· 1 1 { pkgs, ... }: 2 2 { 3 - environment.systemPackages = [ pkgs.matrix-synapse-tools.rust-synapse-compress-state ]; 3 + environment.systemPackages = [ pkgs.rust-synapse-compress-state ]; 4 4 systemd.services.compress-matrix-state = { 5 5 serviceConfig.Type = "oneshot"; 6 6 path = [ 7 - pkgs.matrix-synapse-tools.rust-synapse-compress-state 7 + pkgs.rust-synapse-compress-state 8 8 ]; 9 9 script = '' 10 10 synapse_auto_compressor -p "host=/run/postgresql port=5432 user=matrix-synapse dbname=matrix-synapse" -n 2000000 -c 10000
+35 -21
hosts/profiles/matrix/default.nix
··· 1 - { self, config, lib, pkgs, ... }: 1 + { 2 + self, 3 + config, 4 + lib, 5 + pkgs, 6 + ... 7 + }: 2 8 3 9 { 4 10 imports = [ 5 11 ./mautrix-telegram.nix 6 - ./mautrix-services.nix 7 - # ./mautrix-discord.nix 12 + # ./mautrix-discord.nix # Native NixOS 25.11 module (replaces nix-matrix-appservices) 13 + # ./mautrix-services.nix # Old nix-matrix-appservices - discord moved to native module 8 14 # ./mautrix-whatsapp.nix 9 15 # ./mautrix-slack.nix 10 16 # ./mautrix-signal.nix ··· 18 24 age.secrets.synapse-config.owner = "matrix-synapse"; 19 25 20 26 systemd.services.matrix-synapse.serviceConfig.TimeoutStartSec = "10min"; 21 - 27 + 22 28 services.matrix-synapse = { 23 29 enable = true; 24 30 settings = { 25 31 max_upload_size = "100M"; 26 32 server_name = "sealight.xyz"; 27 - federation_sender_instances = []; 33 + federation_sender_instances = [ ]; 28 34 listeners = [ 29 35 { 30 36 port = 8448; 31 37 tls = false; 32 - resources = [{ 33 - compress = true; 34 - names = [ "client" "federation" ]; 35 - }]; 38 + resources = [ 39 + { 40 + compress = true; 41 + names = [ 42 + "client" 43 + "federation" 44 + ]; 45 + } 46 + ]; 36 47 } 37 48 { 38 49 port = 9090; 39 50 type = "metrics"; 40 51 bind_addresses = [ "0.0.0.0" ]; 41 - resources = [{ 42 - compress = false; 43 - names = [ ]; 44 - }]; 52 + resources = [ 53 + { 54 + compress = false; 55 + names = [ ]; 56 + } 57 + ]; 45 58 tls = false; 46 59 } 47 60 ]; ··· 52 65 # chown matrix-synapse:matrix-synapse /var/lib/matrix-synapse/discord-registration.yaml 53 66 # "/var/lib/matrix-synapse/telegram-registration.yaml" 54 67 "/var/lib/matrix-synapse/signal-registration.yaml" 55 - #"/var/lib/matrix-as-whatsapp/whatsapp-registration.yaml" 56 - "/var/lib/matrix-as-discord/discord-registration.yaml" 68 + # Discord now uses native module with registerToSynapse = true (auto-registers) 69 + # "/var/lib/matrix-as-discord/discord-registration.yaml" 57 70 # "/var/lib/matrix-synapse/slack-registration.yaml" 58 - # "/var/lib/matrix-synapse/discord-registration.yaml" 59 71 # "/var/lib/matrix-synapse/whatsapp-registration.yaml" 60 72 ]; 61 73 turn_uris = [ ··· 67 79 # '' 68 80 # max_upload_size: "50M" 69 81 # use_presence: false 70 - # registration_shared_secret: "hD9HQGTTDxp0mQsQ5JDsfudWMDiubmZENOgPchIvfBvUlPxlvQSvjoO4wn2L1seU"; 82 + # registration_shared_secret: "hD9HQGTTDxp0mQsQ5JDsfudWMDiubmZENOgPchIvfBvUlPxlvQSvjoO4wn2L1seU"; 71 83 # enable_registration_without_verification: true 72 84 # ''; 73 85 enable_metrics = true; ··· 156 168 157 169 networking.firewall = 158 170 let 159 - range = with config.services.coturn; [{ 160 - from = min-port; 161 - to = max-port; 162 - }]; 171 + range = with config.services.coturn; [ 172 + { 173 + from = min-port; 174 + to = max-port; 175 + } 176 + ]; 163 177 in 164 178 { 165 179 enable = true;
+34
hosts/profiles/matrix/mautrix-discord.nix
··· 1 + { 2 + self, 3 + config, 4 + lib, 5 + pkgs, 6 + ... 7 + }: 8 + { 9 + # Native NixOS 25.11 mautrix-discord module 10 + # Replaces the nix-matrix-appservices discord configuration 11 + services.mautrix-discord = { 12 + enable = true; 13 + registerToSynapse = true; 14 + settings = { 15 + homeserver = { 16 + address = "https://sealight.xyz"; 17 + domain = "sealight.xyz"; 18 + }; 19 + appservice = { 20 + id = "discord"; 21 + bot_username = "discordbridge"; 22 + address = "http://localhost:29188"; 23 + port = 29188; 24 + # Uses SQLite by default, can switch to PostgreSQL: 25 + # database = "postgresql:///mautrix-discord?host=/run/postgresql"; 26 + }; 27 + bridge = { 28 + permissions = { 29 + "@aynish:sealight.xyz" = "admin"; 30 + }; 31 + }; 32 + }; 33 + }; 34 + }
+50
hosts/profiles/opencode-server/default.nix
··· 1 + { 2 + self, 3 + config, 4 + pkgs, 5 + inputs, 6 + ... 7 + }: 8 + 9 + let 10 + opencode = inputs.llm-agents.packages.${pkgs.system}.opencode; 11 + in 12 + { 13 + systemd.services.opencode-server = { 14 + description = "OpenCode HTTP Server"; 15 + after = [ "network.target" ]; 16 + wantedBy = [ "multi-user.target" ]; 17 + 18 + # Read the API key from the agenix secret file and export it 19 + script = '' 20 + export ANTHROPIC_API_KEY="$(cat /run/agenix/anthropicToken)" 21 + exec ${opencode}/bin/opencode serve --port 4096 --hostname 0.0.0.0 22 + ''; 23 + 24 + serviceConfig = { 25 + Type = "simple"; 26 + WorkingDirectory = "/home/anish/usr"; 27 + User = "anish"; 28 + Restart = "on-failure"; 29 + RestartSec = "10"; 30 + 31 + # Hardening 32 + NoNewPrivileges = true; 33 + PrivateTmp = true; 34 + }; 35 + }; 36 + 37 + # Open firewall port for LAN access 38 + networking.firewall.allowedTCPPorts = [ 4096 ]; 39 + 40 + services.nginx = { 41 + enable = true; 42 + virtualHosts = { 43 + "opencode.mossnet.lan" = { 44 + forceSSL = false; 45 + enableACME = false; 46 + locations."/".proxyPass = "http://localhost:4096/"; 47 + }; 48 + }; 49 + }; 50 + }
+1 -1
hosts/profiles/sync/music/get-music.sh
··· 13 13 14 14 # Get list of albums on remote server 15 15 echo "$(date): Checking for new albums on seedbox..." >>"$LOG_FILE" 16 - REMOTE_ALBUMS=$(rsync --dry-run --list-only "$REMOTE_HOST:$REMOTE_PATH" | grep '^d' | awk '{$1=$2=$3=$4=""; sub(/^ +/, ""); print}' | grep -v '^\.') || true 16 + REMOTE_ALBUMS=$(rsync --dry-run --list-only "$REMOTE_HOST:$REMOTE_PATH" | grep '^d' | awk '{$1=$2=$3=$4=""; sub(/^ +/, ""); print}' | grep -v '^\.' | grep -v '^tv-sonarr$') || true 17 17 18 18 if [ -z "$REMOTE_ALBUMS" ]; then 19 19 echo "$(date): No albums found on remote server" >>"$LOG_FILE"
+23
hosts/profiles/sync/tv/default.nix
··· 1 + { pkgs, lib, ... }: 2 + 3 + { 4 + systemd.services.get-tv-sync = { 5 + serviceConfig.Type = "oneshot"; 6 + path = [ 7 + pkgs.coreutils 8 + pkgs.openssh 9 + pkgs.gawk 10 + pkgs.rsync 11 + pkgs.curl 12 + ]; 13 + script = builtins.readFile ./get-tv.sh; 14 + serviceConfig = { 15 + User = "anish"; 16 + }; 17 + }; 18 + systemd.timers.get-tv-sync = { 19 + wantedBy = [ "timers.target" ]; 20 + partOf = [ "get-tv-sync.service" ]; 21 + timerConfig.OnCalendar = [ "hourly" ]; 22 + }; 23 + }
+63
hosts/profiles/sync/tv/get-tv.sh
··· 1 + #!/usr/bin/env bash 2 + 3 + set -euo pipefail 4 + 5 + REMOTE_HOST="aynish@talos.feralhosting.com" 6 + REMOTE_PATH="private/transmission/data/tv-sonarr/" 7 + LOCAL_PATH="/tank/media/tv" 8 + TRACKING_FILE="/tank/media/tv/.downloaded_shows" 9 + LOG_FILE="/tank/media/tv/download-log" 10 + 11 + # Create local directory and tracking file if they don't exist 12 + mkdir -p "$LOCAL_PATH" 13 + touch "$TRACKING_FILE" 14 + 15 + # Get list of shows on remote server 16 + echo "$(date): Checking for new TV shows on seedbox..." >>"$LOG_FILE" 17 + REMOTE_SHOWS=$(rsync --dry-run --list-only "$REMOTE_HOST:$REMOTE_PATH" | grep '^d' | awk '{$1=$2=$3=$4=""; sub(/^ +/, ""); print}' | grep -v '^\.') || true 18 + 19 + if [ -z "$REMOTE_SHOWS" ]; then 20 + echo "$(date): No shows found on remote server" >>"$LOG_FILE" 21 + exit 0 22 + fi 23 + 24 + # Check each show against tracking file 25 + NEW_SHOWS="" 26 + while IFS= read -r show; do 27 + if [ -n "$show" ] && ! grep -qF "$show" "$TRACKING_FILE"; then 28 + NEW_SHOWS="$NEW_SHOWS$show\n" 29 + echo "$(date): Found new show: $show" >>"$LOG_FILE" 30 + fi 31 + done <<<"$REMOTE_SHOWS" 32 + 33 + if [ -z "$NEW_SHOWS" ]; then 34 + echo "$(date): No new shows to download" >>"$LOG_FILE" 35 + exit 0 36 + fi 37 + 38 + # Download new shows only 39 + echo "$(date): Starting download of new shows..." >>"$LOG_FILE" 40 + while IFS= read -r show; do 41 + if [ -n "$show" ]; then 42 + echo "$(date): Downloading $show" >>"$LOG_FILE" 43 + # Set umask to allow group read/write access for Jellyfin 44 + umask 002 45 + if rsync -r --log-file="$LOG_FILE" "$REMOTE_HOST:$REMOTE_PATH$show/" "$LOCAL_PATH/$show/"; then 46 + echo "$show" >>"$TRACKING_FILE" 47 + echo "$(date): Successfully downloaded $show" >>"$LOG_FILE" 48 + else 49 + echo "$(date): Failed to download $show" >>"$LOG_FILE" 50 + fi 51 + fi 52 + done <<<"$(echo -e "$NEW_SHOWS")" 53 + 54 + # Trigger Jellyfin library scan 55 + echo "$(date): Triggering Jellyfin library refresh..." >>"$LOG_FILE" 56 + if curl -s -X POST "http://localhost:8096/Library/Refresh" \ 57 + -H "X-Emby-Token: aef1b1e0cd5445dc97b755ef8c6224e5"; then 58 + echo "$(date): Jellyfin library refresh triggered" >>"$LOG_FILE" 59 + else 60 + echo "$(date): Failed to trigger Jellyfin library refresh" >>"$LOG_FILE" 61 + fi 62 + 63 + echo "$(date): TV sync completed" >>"$LOG_FILE"
+1
hosts/profiles/transmission/default.nix
··· 3 3 environment.systemPackages = [ pkgs.beets ]; 4 4 services.transmission = { 5 5 enable = true; 6 + package = pkgs.transmission_4; # 25.11: transmission_3 removed, explicitly use v4 6 7 settings = { 7 8 rpc-enabled = true; 8 9 rpc-bind-address = "0.0.0.0";
+12 -12
overlays/default.nix
··· 19 19 # patching whitespace with sed is insane 20 20 headphones = prev.headphones.overrideAttrs (prevAttrs: rec { 21 21 patchPhase = '' 22 - sed -i '1395s/^\([[:space:]]*\).*/\1"cat": "3000",/' headphones/searcher.py 22 + sed -i '1395s/^\([[:space:]]*\).*/\1"cat": "3000",/' headphones/searcher.py 23 23 ''; 24 24 }); 25 25 26 26 wallabag = prev.wallabag.overrideAttrs (attrs: { 27 - patches = builtins.filter (patch: builtins.baseNameOf patch != "wallabag-data.patch") attrs.patches ++ [ 28 - # Out of the box, Wallabag wants to write to various subdirectories of the project directory. 29 - # Let’s replace references to such paths with designated systemd locations 30 - # so that the project source can remain immutable. 31 - ../pkgs/wallabag-data.patch 32 - ]; 27 + patches = 28 + builtins.filter (patch: builtins.baseNameOf patch != "wallabag-data.patch") attrs.patches 29 + ++ [ 30 + # Out of the box, Wallabag wants to write to various subdirectories of the project directory. 31 + # Let’s replace references to such paths with designated systemd locations 32 + # so that the project source can remain immutable. 33 + ../pkgs/wallabag-data.patch 34 + ]; 33 35 }); 34 36 35 37 olm = prev.olm.overrideAttrs (attrs: { 36 - knownVulnerabilities = []; 38 + knownVulnerabilities = [ ]; 37 39 }); 38 40 39 - mautrix-discord = prev.mautrix-discord.overrideAttrs (attrs: rec { 40 - license = ""; 41 - }); 41 + # mautrix-discord overlay removed - now using native NixOS 25.11 module 42 42 43 43 # Need to do server and agent too, maybe 44 - # woodpecker-cli-next = 44 + # woodpecker-cli-next = 45 45 # let 46 46 # common = prev.callPackage "${inputs.unstable}/pkgs/development/tools/continuous-integration/woodpecker/common.nix" { }; 47 47 # in
+1 -1
pkgs/fennel-ls.nix
··· 9 9 }; 10 10 buildInputs = with pkgs; [ 11 11 lua 12 - fennel 12 + luaPackages.fennel # renamed from fennel in 25.11 13 13 ]; 14 14 15 15 configurePhase = ''