From 785561367e4a437761275eaf69b3470070e3bf1b Mon Sep 17 00:00:00 2001 From: John Ogle Date: Wed, 8 Apr 2026 11:33:40 -0700 Subject: [PATCH] Add opencode package and install via base role - Add packages/opencode with pre-built binaries from GitHub releases (v1.4.0) - Support all 4 platforms (aarch64-darwin, x86_64-darwin, x86_64-linux, aarch64-linux) - Add update-opencode flake app for automated version bumps - Install opencode via home.roles.base so it's available on all machines - Reformat flake.nix and packages with nixfmt --- flake.nix | 616 ++++++++++++++++++---------------- home/roles/base/default.nix | 8 +- packages/default.nix | 15 +- packages/opencode/default.nix | 82 +++++ packages/opencode/update.sh | 148 ++++++++ 5 files changed, 575 insertions(+), 294 deletions(-) create mode 100644 packages/opencode/default.nix create mode 100755 packages/opencode/update.sh diff --git a/flake.nix b/flake.nix index 550c7cb..52dad29 100644 --- a/flake.nix +++ b/flake.nix @@ -58,7 +58,7 @@ perles = { url = "github:zjrosen/perles"; - flake = false; # No flake.nix upstream yet + flake = false; # No flake.nix upstream yet }; nix-doom-emacs-unstraightened = { @@ -68,308 +68,352 @@ }; }; - outputs = { self, nixpkgs, nixpkgs-unstable, ... } @ inputs: let - # Shared overlay function to reduce duplication across module sets - # Parameters: - # unstableOverlays: Additional overlays to apply when importing nixpkgs-unstable - mkBaseOverlay = { unstableOverlays ? [] }: (final: prev: { - unstable = import nixpkgs-unstable { - system = prev.stdenv.hostPlatform.system; - config.allowUnfree = true; - overlays = unstableOverlays; - }; - # Separate nixpkgs for qt5webengine-heavy packages to avoid rebuild churn - qt-pinned = import inputs.nixpkgs-qt { - system = prev.stdenv.hostPlatform.system; - config = { - allowUnfree = true; - permittedInsecurePackages = [ "qtwebengine-5.15.19" ]; - }; - }; - custom = prev.callPackage ./packages {}; - # Compatibility: bitwarden renamed to bitwarden-desktop in unstable - bitwarden-desktop = prev.bitwarden-desktop or prev.bitwarden; - }); - - # Shared home-manager configuration factory - # Parameters: - # sharedModules: Additional modules to include in home-manager.sharedModules - mkHomeManagerConfig = { sharedModules ? [] }: { - home-manager.useGlobalPkgs = true; - home-manager.useUserPackages = true; - home-manager.sharedModules = sharedModules ++ [ - inputs.nix-doom-emacs-unstraightened.homeModule - ]; - home-manager.extraSpecialArgs = { - globalInputs = inputs; - }; - }; - - - # Shared unstable overlays for custom package builds - customUnstableOverlays = [ - # Override claude-code in unstable to use our custom GCS-based build - # (needed for corporate networks that block npm registry) - (ufinal: uprev: { - claude-code = uprev.callPackage ./packages/claude-code {}; - }) - # Pin dolt to v1.82.4 (gastown requires >= 1.82.4) - (ufinal: uprev: { - dolt = uprev.dolt.overrideAttrs (old: rec { - version = "1.82.4"; - src = uprev.fetchFromGitHub { - owner = "dolthub"; - repo = "dolt"; - tag = "v${version}"; - hash = "sha256-mavL3y+Kv25hzFlDFXk7W/jeKVKlCBjlc67GkL3Jcwk="; - }; - vendorHash = "sha256-K1KzsqptZxO5OraWKIXeqKuVSzb6E/Mjy3c5PQ7Rs9k="; - }); - }) - ]; - - nixosModules = [ - ./roles - inputs.home-manager.nixosModules.home-manager - { - nixpkgs.overlays = [ (mkBaseOverlay { unstableOverlays = customUnstableOverlays; }) ]; - } - (mkHomeManagerConfig { - sharedModules = [ inputs.plasma-manager.homeModules.plasma-manager ]; - }) - ]; - - # Modules for unstable-based systems (like nix-deck) - nixosModulesUnstable = [ - ./roles - inputs.home-manager-unstable.nixosModules.home-manager - inputs.jovian.nixosModules.jovian - { - nixpkgs.overlays = [ (mkBaseOverlay { unstableOverlays = customUnstableOverlays; }) ]; - } - (mkHomeManagerConfig { - sharedModules = [ inputs.plasma-manager-unstable.homeModules.plasma-manager ]; - }) - ]; - - darwinModules = [ - ./roles/darwin.nix - inputs.home-manager.darwinModules.home-manager - { - nixpkgs.overlays = [ (mkBaseOverlay { unstableOverlays = customUnstableOverlays; }) ]; - } - (mkHomeManagerConfig { sharedModules = []; }) - ]; - - in { - nixosConfigurations.nix-book = nixpkgs.lib.nixosSystem rec { - system = "x86_64-linux"; - modules = nixosModules ++ [ - ./machines/nix-book/configuration.nix + outputs = + { + self, + nixpkgs, + nixpkgs-unstable, + ... + }@inputs: + let + # Shared overlay function to reduce duplication across module sets + # Parameters: + # unstableOverlays: Additional overlays to apply when importing nixpkgs-unstable + mkBaseOverlay = { - home-manager.users.johno = { - imports = [ ./home/home-laptop-compact.nix ]; - # Machine-specific overrides - home.roles.i3_sway.extraSwayConfig = { - output.eDP-1.scale = "1.75"; + unstableOverlays ? [ ], + }: + (final: prev: { + unstable = import nixpkgs-unstable { + system = prev.stdenv.hostPlatform.system; + config.allowUnfree = true; + overlays = unstableOverlays; + }; + # Separate nixpkgs for qt5webengine-heavy packages to avoid rebuild churn + qt-pinned = import inputs.nixpkgs-qt { + system = prev.stdenv.hostPlatform.system; + config = { + allowUnfree = true; + permittedInsecurePackages = [ "qtwebengine-5.15.19" ]; }; }; - home-manager.extraSpecialArgs = { inherit system; }; - } - ]; - }; + custom = prev.callPackage ./packages { }; + # Compatibility: bitwarden renamed to bitwarden-desktop in unstable + bitwarden-desktop = prev.bitwarden-desktop or prev.bitwarden; + }); - nixosConfigurations.boxy = nixpkgs.lib.nixosSystem rec { - system = "x86_64-linux"; - modules = nixosModules ++ [ - ./machines/boxy/configuration.nix + # Shared home-manager configuration factory + # Parameters: + # sharedModules: Additional modules to include in home-manager.sharedModules + mkHomeManagerConfig = { - home-manager.users.johno = import ./home/home-media-center.nix; - # kodi user: AVR volume control + minimal Plasma config for Bigscreen session - home-manager.users.kodi = import ./home/home-kodi.nix; - home-manager.extraSpecialArgs = { inherit system; }; - } - ]; - }; + sharedModules ? [ ], + }: + { + home-manager.useGlobalPkgs = true; + home-manager.useUserPackages = true; + home-manager.sharedModules = sharedModules ++ [ + inputs.nix-doom-emacs-unstraightened.homeModule + ]; + home-manager.extraSpecialArgs = { + globalInputs = inputs; + }; + }; - nixosConfigurations.zix790prors = nixpkgs.lib.nixosSystem rec { - system = "x86_64-linux"; - modules = nixosModules ++ [ - ./machines/zix790prors/configuration.nix + # Shared unstable overlays for custom package builds + customUnstableOverlays = [ + # Override claude-code in unstable to use our custom GCS-based build + # (needed for corporate networks that block npm registry) + (ufinal: uprev: { + claude-code = uprev.callPackage ./packages/claude-code { }; + }) + # Pin dolt to v1.82.4 (gastown requires >= 1.82.4) + (ufinal: uprev: { + dolt = uprev.dolt.overrideAttrs (old: rec { + version = "1.82.4"; + src = uprev.fetchFromGitHub { + owner = "dolthub"; + repo = "dolt"; + tag = "v${version}"; + hash = "sha256-mavL3y+Kv25hzFlDFXk7W/jeKVKlCBjlc67GkL3Jcwk="; + }; + vendorHash = "sha256-K1KzsqptZxO5OraWKIXeqKuVSzb6E/Mjy3c5PQ7Rs9k="; + }); + }) + ]; + + nixosModules = [ + ./roles + inputs.home-manager.nixosModules.home-manager { - home-manager.users.johno = { - imports = [ ./home/home-desktop.nix ]; - home.roles.i3_sway.extraSwayConfig = { - output = { - "DP-1" = { - mode = "3440x1440@164.900Hz"; + nixpkgs.overlays = [ (mkBaseOverlay { unstableOverlays = customUnstableOverlays; }) ]; + } + (mkHomeManagerConfig { + sharedModules = [ inputs.plasma-manager.homeModules.plasma-manager ]; + }) + ]; + + # Modules for unstable-based systems (like nix-deck) + nixosModulesUnstable = [ + ./roles + inputs.home-manager-unstable.nixosModules.home-manager + inputs.jovian.nixosModules.jovian + { + nixpkgs.overlays = [ (mkBaseOverlay { unstableOverlays = customUnstableOverlays; }) ]; + } + (mkHomeManagerConfig { + sharedModules = [ inputs.plasma-manager-unstable.homeModules.plasma-manager ]; + }) + ]; + + darwinModules = [ + ./roles/darwin.nix + inputs.home-manager.darwinModules.home-manager + { + nixpkgs.overlays = [ (mkBaseOverlay { unstableOverlays = customUnstableOverlays; }) ]; + } + (mkHomeManagerConfig { sharedModules = [ ]; }) + ]; + + in + { + nixosConfigurations.nix-book = nixpkgs.lib.nixosSystem rec { + system = "x86_64-linux"; + modules = nixosModules ++ [ + ./machines/nix-book/configuration.nix + { + home-manager.users.johno = { + imports = [ ./home/home-laptop-compact.nix ]; + # Machine-specific overrides + home.roles.i3_sway.extraSwayConfig = { + output.eDP-1.scale = "1.75"; + }; + }; + home-manager.extraSpecialArgs = { inherit system; }; + } + ]; + }; + + nixosConfigurations.boxy = nixpkgs.lib.nixosSystem rec { + system = "x86_64-linux"; + modules = nixosModules ++ [ + ./machines/boxy/configuration.nix + { + home-manager.users.johno = import ./home/home-media-center.nix; + # kodi user: AVR volume control + minimal Plasma config for Bigscreen session + home-manager.users.kodi = import ./home/home-kodi.nix; + home-manager.extraSpecialArgs = { inherit system; }; + } + ]; + }; + + nixosConfigurations.zix790prors = nixpkgs.lib.nixosSystem rec { + system = "x86_64-linux"; + modules = nixosModules ++ [ + ./machines/zix790prors/configuration.nix + { + home-manager.users.johno = { + imports = [ ./home/home-desktop.nix ]; + home.roles.i3_sway.extraSwayConfig = { + output = { + "DP-1" = { + mode = "3440x1440@164.900Hz"; + }; }; }; }; + home-manager.extraSpecialArgs = { inherit system; }; + } + ]; + }; + + # Live USB ISO configuration + nixosConfigurations.live-usb = nixpkgs.lib.nixosSystem rec { + system = "x86_64-linux"; + modules = nixosModules ++ [ + ./machines/live-usb/configuration.nix + { + home-manager.users.nixos = import ./home/home-live-usb.nix; + home-manager.extraSpecialArgs = { inherit system; }; + } + ]; + }; + + # Steam Deck configuration (using unstable for better Jovian compatibility) + nixosConfigurations.nix-deck = nixpkgs-unstable.lib.nixosSystem rec { + system = "x86_64-linux"; + modules = nixosModulesUnstable ++ [ + ./machines/nix-deck/configuration.nix + { + home-manager.users.johno = import ./home/home-desktop.nix; + home-manager.extraSpecialArgs = { inherit system; }; + } + ]; + }; + + # ZFS/NFS server configuration + nixosConfigurations.john-endesktop = nixpkgs.lib.nixosSystem rec { + system = "x86_64-linux"; + modules = nixosModules ++ [ + ./machines/john-endesktop/configuration.nix + inputs.home-manager.nixosModules.home-manager + { + home-manager.users.johno = import ./home/home-server.nix; + home-manager.extraSpecialArgs = { inherit system; }; + } + ]; + }; + + # Darwin/macOS configurations + darwinConfigurations."BLKFV4YF49KT7" = inputs.nix-darwin.lib.darwinSystem rec { + system = "aarch64-darwin"; + modules = darwinModules ++ [ + ./machines/johno-macbookpro/configuration.nix + { + home-manager.users.johno = import ./home/home-darwin-work.nix; + home-manager.extraSpecialArgs = { inherit system; }; + } + ]; + }; + + # Packages for CI caching (custom packages, flake inputs, and qt-pinned) + packages = nixpkgs.lib.genAttrs [ "x86_64-linux" "aarch64-linux" ] ( + system: + let + pkgs = import nixpkgs { + inherit system; + config.allowUnfree = true; + overlays = [ (mkBaseOverlay { }) ]; }; - home-manager.extraSpecialArgs = { inherit system; }; - } - ]; - }; - - # Live USB ISO configuration - nixosConfigurations.live-usb = nixpkgs.lib.nixosSystem rec { - system = "x86_64-linux"; - modules = nixosModules ++ [ - ./machines/live-usb/configuration.nix - { - home-manager.users.nixos = import ./home/home-live-usb.nix; - home-manager.extraSpecialArgs = { inherit system; }; - } - ]; - }; - - # Steam Deck configuration (using unstable for better Jovian compatibility) - nixosConfigurations.nix-deck = nixpkgs-unstable.lib.nixosSystem rec { - system = "x86_64-linux"; - modules = nixosModulesUnstable ++ [ - ./machines/nix-deck/configuration.nix - { - home-manager.users.johno = import ./home/home-desktop.nix; - home-manager.extraSpecialArgs = { inherit system; }; - } - ]; - }; - - # ZFS/NFS server configuration - nixosConfigurations.john-endesktop = nixpkgs.lib.nixosSystem rec { - system = "x86_64-linux"; - modules = nixosModules ++ [ - ./machines/john-endesktop/configuration.nix - inputs.home-manager.nixosModules.home-manager - { - home-manager.users.johno = import ./home/home-server.nix; - home-manager.extraSpecialArgs = { inherit system; }; - } - ]; - }; - - # Darwin/macOS configurations - darwinConfigurations."BLKFV4YF49KT7" = inputs.nix-darwin.lib.darwinSystem rec { - system = "aarch64-darwin"; - modules = darwinModules ++ [ - ./machines/johno-macbookpro/configuration.nix - { - home-manager.users.johno = import ./home/home-darwin-work.nix; - home-manager.extraSpecialArgs = { inherit system; }; - } - ]; - }; - - # Packages for CI caching (custom packages, flake inputs, and qt-pinned) - packages = nixpkgs.lib.genAttrs [ "x86_64-linux" "aarch64-linux" ] (system: - let - pkgs = import nixpkgs { - inherit system; - config.allowUnfree = true; - overlays = [ (mkBaseOverlay {}) ]; - }; - pkgsQt = import inputs.nixpkgs-qt { - inherit system; - config = { - allowUnfree = true; - permittedInsecurePackages = [ "qtwebengine-5.15.19" ]; + pkgsQt = import inputs.nixpkgs-qt { + inherit system; + config = { + allowUnfree = true; + permittedInsecurePackages = [ "qtwebengine-5.15.19" ]; + }; }; - }; - # Version strings for flake input packages - beadsRev = builtins.substring 0 8 (inputs.beads.rev or "unknown"); - gastownRev = builtins.substring 0 8 (inputs.gastown.rev or "unknown"); - in { - "custom-claude-code" = pkgs.custom.claude-code; - "custom-app-launcher-server" = pkgs.custom.app-launcher-server; - "custom-mcrcon-rbw" = pkgs.custom.mcrcon-rbw; - "custom-tea-rbw" = pkgs.custom.tea-rbw; - "custom-rclone-torbox-setup" = pkgs.custom.rclone-torbox-setup; - "custom-nextcloud-talk-desktop" = pkgs.custom.nextcloud-talk-desktop; - "qt-pinned-jellyfin-media-player" = pkgsQt.jellyfin-media-player; - "qt-pinned-stremio" = pkgsQt.stremio; - # Flake input packages (beads, gastown) - these get version from input rev - "custom-beads" = pkgs.callPackage ./packages/beads { - inherit (pkgs.unstable) buildGoModule; - src = inputs.beads; - version = "0.52.0-${beadsRev}"; - }; - "custom-gastown" = pkgs.callPackage ./packages/gastown { - src = inputs.gastown; - version = "unstable-${gastownRev}"; - }; - "custom-perles" = pkgs.callPackage ./packages/perles { - inherit (pkgs.unstable) buildGoModule; - src = inputs.perles; - version = "unstable-${builtins.substring 0 8 (inputs.perles.rev or "unknown")}"; - }; - } // (if system == "x86_64-linux" then { - # nix-deck kernel from Jovian-NixOS (Steam Deck) - expensive to build - "nix-deck-kernel" = self.nixosConfigurations.nix-deck.config.boot.kernelPackages.kernel; - } else {}) - ); + # Version strings for flake input packages + beadsRev = builtins.substring 0 8 (inputs.beads.rev or "unknown"); + gastownRev = builtins.substring 0 8 (inputs.gastown.rev or "unknown"); + in + { + "custom-claude-code" = pkgs.custom.claude-code; + "custom-app-launcher-server" = pkgs.custom.app-launcher-server; + "custom-mcrcon-rbw" = pkgs.custom.mcrcon-rbw; + "custom-tea-rbw" = pkgs.custom.tea-rbw; + "custom-rclone-torbox-setup" = pkgs.custom.rclone-torbox-setup; + "custom-nextcloud-talk-desktop" = pkgs.custom.nextcloud-talk-desktop; + "custom-opencode" = pkgs.custom.opencode; + "qt-pinned-jellyfin-media-player" = pkgsQt.jellyfin-media-player; + "qt-pinned-stremio" = pkgsQt.stremio; + # Flake input packages (beads, gastown) - these get version from input rev + "custom-beads" = pkgs.callPackage ./packages/beads { + inherit (pkgs.unstable) buildGoModule; + src = inputs.beads; + version = "0.52.0-${beadsRev}"; + }; + "custom-gastown" = pkgs.callPackage ./packages/gastown { + src = inputs.gastown; + version = "unstable-${gastownRev}"; + }; + "custom-perles" = pkgs.callPackage ./packages/perles { + inherit (pkgs.unstable) buildGoModule; + src = inputs.perles; + version = "unstable-${builtins.substring 0 8 (inputs.perles.rev or "unknown")}"; + }; + } + // ( + if system == "x86_64-linux" then + { + # nix-deck kernel from Jovian-NixOS (Steam Deck) - expensive to build + "nix-deck-kernel" = self.nixosConfigurations.nix-deck.config.boot.kernelPackages.kernel; + } + else + { } + ) + ); - # Flake apps - apps = nixpkgs.lib.genAttrs [ "x86_64-linux" "aarch64-linux" "aarch64-darwin" ] (system: - let - pkgs = import nixpkgs { inherit system; }; - commonDeps = [ pkgs.curl pkgs.jq pkgs.nix pkgs.git pkgs.gnused pkgs.gnugrep pkgs.coreutils pkgs.gawk ]; + # Flake apps + apps = nixpkgs.lib.genAttrs [ "x86_64-linux" "aarch64-linux" "aarch64-darwin" ] ( + system: + let + pkgs = import nixpkgs { inherit system; }; + commonDeps = [ + pkgs.curl + pkgs.jq + pkgs.nix + pkgs.git + pkgs.gnused + pkgs.gnugrep + pkgs.coreutils + pkgs.gawk + ]; - update-doomemacs = pkgs.writeShellScriptBin "update-doomemacs" '' - export PATH="${pkgs.lib.makeBinPath commonDeps}:$PATH" - ${builtins.readFile ./scripts/update-doomemacs.sh} - ''; + update-doomemacs = pkgs.writeShellScriptBin "update-doomemacs" '' + export PATH="${pkgs.lib.makeBinPath commonDeps}:$PATH" + ${builtins.readFile ./scripts/update-doomemacs.sh} + ''; - update-claude-code = pkgs.writeShellScriptBin "update-claude-code" '' - export PATH="${pkgs.lib.makeBinPath commonDeps}:$PATH" - ${builtins.readFile ./packages/claude-code/update.sh} - ''; + update-claude-code = pkgs.writeShellScriptBin "update-claude-code" '' + export PATH="${pkgs.lib.makeBinPath commonDeps}:$PATH" + ${builtins.readFile ./packages/claude-code/update.sh} + ''; - rotate-wallpaper = pkgs.writeShellScriptBin "rotate-wallpaper" '' - export PATH="${pkgs.lib.makeBinPath commonDeps}:$PATH" - ${builtins.readFile ./scripts/rotate-wallpaper.sh} - ''; + update-opencode = pkgs.writeShellScriptBin "update-opencode" '' + export PATH="${pkgs.lib.makeBinPath commonDeps}:$PATH" + ${builtins.readFile ./packages/opencode/update.sh} + ''; - upgrade = pkgs.writeShellScriptBin "upgrade" '' - export PATH="${pkgs.lib.makeBinPath commonDeps}:$PATH" - ${builtins.readFile ./scripts/upgrade.sh} - ''; + rotate-wallpaper = pkgs.writeShellScriptBin "rotate-wallpaper" '' + export PATH="${pkgs.lib.makeBinPath commonDeps}:$PATH" + ${builtins.readFile ./scripts/rotate-wallpaper.sh} + ''; - bootstrap = pkgs.writeShellScriptBin "bootstrap" '' - export PATH="${pkgs.lib.makeBinPath commonDeps}:$PATH" - ${builtins.readFile ./scripts/bootstrap.sh} - ''; + upgrade = pkgs.writeShellScriptBin "upgrade" '' + export PATH="${pkgs.lib.makeBinPath commonDeps}:$PATH" + ${builtins.readFile ./scripts/upgrade.sh} + ''; - build-liveusb = pkgs.writeShellScriptBin "build-liveusb" '' - export PATH="${pkgs.lib.makeBinPath commonDeps}:$PATH" - ${builtins.readFile ./scripts/build-liveusb.sh} - ''; - in { - update-doomemacs = { - type = "app"; - program = "${update-doomemacs}/bin/update-doomemacs"; - }; - update-claude-code = { - type = "app"; - program = "${update-claude-code}/bin/update-claude-code"; - }; - rotate-wallpaper = { - type = "app"; - program = "${rotate-wallpaper}/bin/rotate-wallpaper"; - }; - upgrade = { - type = "app"; - program = "${upgrade}/bin/upgrade"; - }; - bootstrap = { - type = "app"; - program = "${bootstrap}/bin/bootstrap"; - }; - build-liveusb = { - type = "app"; - program = "${build-liveusb}/bin/build-liveusb"; - }; - } - ); - }; + bootstrap = pkgs.writeShellScriptBin "bootstrap" '' + export PATH="${pkgs.lib.makeBinPath commonDeps}:$PATH" + ${builtins.readFile ./scripts/bootstrap.sh} + ''; + + build-liveusb = pkgs.writeShellScriptBin "build-liveusb" '' + export PATH="${pkgs.lib.makeBinPath commonDeps}:$PATH" + ${builtins.readFile ./scripts/build-liveusb.sh} + ''; + in + { + update-doomemacs = { + type = "app"; + program = "${update-doomemacs}/bin/update-doomemacs"; + }; + update-claude-code = { + type = "app"; + program = "${update-claude-code}/bin/update-claude-code"; + }; + update-opencode = { + type = "app"; + program = "${update-opencode}/bin/update-opencode"; + }; + rotate-wallpaper = { + type = "app"; + program = "${rotate-wallpaper}/bin/rotate-wallpaper"; + }; + upgrade = { + type = "app"; + program = "${upgrade}/bin/upgrade"; + }; + bootstrap = { + type = "app"; + program = "${bootstrap}/bin/bootstrap"; + }; + build-liveusb = { + type = "app"; + program = "${build-liveusb}/bin/build-liveusb"; + }; + } + ); + }; } diff --git a/home/roles/base/default.nix b/home/roles/base/default.nix index 614949e..55ce5f8 100644 --- a/home/roles/base/default.nix +++ b/home/roles/base/default.nix @@ -1,4 +1,9 @@ -{ config, lib, pkgs, ... }: +{ + config, + lib, + pkgs, + ... +}: with lib; @@ -24,6 +29,7 @@ in tmux tree watch + custom.opencode ]; # Automatic garbage collection for user profile (home-manager generations). diff --git a/packages/default.nix b/packages/default.nix index 8741ddc..560379a 100644 --- a/packages/default.nix +++ b/packages/default.nix @@ -1,10 +1,11 @@ { pkgs, ... }: { - tea-rbw = pkgs.callPackage ./tea-rbw {}; - app-launcher-server = pkgs.callPackage ./app-launcher-server {}; - claude-code = pkgs.callPackage ./claude-code {}; - mcrcon-rbw = pkgs.callPackage ./mcrcon-rbw {}; - rclone-torbox-setup = pkgs.callPackage ./rclone-torbox-setup {}; - pi-coding-agent = pkgs.callPackage ./pi-coding-agent {}; - nextcloud-talk-desktop = pkgs.callPackage ./nextcloud-talk-desktop {}; + tea-rbw = pkgs.callPackage ./tea-rbw { }; + app-launcher-server = pkgs.callPackage ./app-launcher-server { }; + claude-code = pkgs.callPackage ./claude-code { }; + mcrcon-rbw = pkgs.callPackage ./mcrcon-rbw { }; + rclone-torbox-setup = pkgs.callPackage ./rclone-torbox-setup { }; + pi-coding-agent = pkgs.callPackage ./pi-coding-agent { }; + nextcloud-talk-desktop = pkgs.callPackage ./nextcloud-talk-desktop { }; + opencode = pkgs.callPackage ./opencode { }; } diff --git a/packages/opencode/default.nix b/packages/opencode/default.nix new file mode 100644 index 0000000..e224f9a --- /dev/null +++ b/packages/opencode/default.nix @@ -0,0 +1,82 @@ +{ + lib, + stdenv, + fetchzip, + patchelf, + glibc, +}: + +let + version = "1.4.0"; + + srcs = { + aarch64-darwin = { + url = "https://github.com/anomalyco/opencode/releases/download/v${version}/opencode-darwin-arm64.zip"; + sha256 = "0m97j2vln8yhhvnsjl92phx6dac24y7hgh75csmbkbhawkz9xm4l"; + }; + x86_64-darwin = { + url = "https://github.com/anomalyco/opencode/releases/download/v${version}/opencode-darwin-x64.zip"; + sha256 = "17n04j06pdc2raxjm91y6p87gwpnra0liabpbjwdmyd1iqgqv0q8"; + }; + x86_64-linux = { + url = "https://github.com/anomalyco/opencode/releases/download/v${version}/opencode-linux-x64.tar.gz"; + sha256 = "16117lwfj2lb8wjbq5cyf77vhi52ada5ys3212hjqw3qw3wrcc0r"; + }; + aarch64-linux = { + url = "https://github.com/anomalyco/opencode/releases/download/v${version}/opencode-linux-arm64.tar.gz"; + sha256 = "06lvm1qiji74xdd3psqn6lwxak65gqsbmkib1pjb4n65f9246jwm"; + }; + }; + + src = + srcs.${stdenv.hostPlatform.system} or (throw "Unsupported system: ${stdenv.hostPlatform.system}"); + +in +stdenv.mkDerivation { + pname = "opencode"; + inherit version; + + src = fetchzip { + inherit (src) url sha256; + }; + + # Bun standalone binaries have JS code appended after the ELF sections + # stripping/patching would remove or corrupt this appended data + dontStrip = true; + dontPatchELF = true; + + nativeBuildInputs = lib.optionals stdenv.isLinux [ patchelf ]; + + installPhase = '' + runHook preInstall + + install -Dm755 $src/opencode $out/bin/opencode + + runHook postInstall + ''; + + # Manually patch the interpreter for bun standalone binaries on Linux + postFixup = lib.optionalString stdenv.isLinux '' + interpreter="${glibc}/lib/${ + if stdenv.hostPlatform.system == "aarch64-linux" then + "ld-linux-aarch64.so.1" + else + "ld-linux-x86-64.so.2" + }" + patchelf --set-interpreter "$interpreter" $out/bin/opencode + ''; + + meta = with lib; { + description = "Terminal-based AI coding assistant"; + homepage = "https://opencode.ai"; + license = licenses.mit; + maintainers = [ ]; + platforms = [ + "aarch64-darwin" + "x86_64-darwin" + "x86_64-linux" + "aarch64-linux" + ]; + mainProgram = "opencode"; + }; +} diff --git a/packages/opencode/update.sh b/packages/opencode/update.sh new file mode 100755 index 0000000..e5e9030 --- /dev/null +++ b/packages/opencode/update.sh @@ -0,0 +1,148 @@ +#!/usr/bin/env bash +set -euo pipefail + +DRY_RUN=false + +while [[ $# -gt 0 ]]; do + case $1 in + --dry-run|-n) + DRY_RUN=true + shift + ;; + --help|-h) + echo "Usage: $0 [OPTIONS]" + echo "" + echo "Options:" + echo " --dry-run, -n Show what would be updated without making changes" + echo " --help, -h Show this help message" + exit 0 + ;; + *) + echo "Unknown option: $1" + echo "Use --help for usage information" + exit 1 + ;; + esac +done + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' + +REPO_ROOT="${REPO_ROOT:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}" +NIX_FILE="$REPO_ROOT/packages/opencode/default.nix" + +echo "Fetching latest opencode version from GitHub API..." + +RELEASE_INFO=$(curl -fsSL https://api.github.com/repos/anomalyco/opencode/releases/latest) +NEW_VERSION=$(echo "$RELEASE_INFO" | jq -r '.tag_name' | sed 's/^v//') + +if [ -z "$NEW_VERSION" ] || [ "$NEW_VERSION" = "null" ]; then + echo -e "${RED}Error: Failed to fetch version from GitHub API${NC}" + exit 1 +fi + +CURRENT_VERSION=$(grep -m1 'version = ' "$NIX_FILE" | sed -E 's/.*version = "([^"]+)".*/\1/') + +if [ "$CURRENT_VERSION" = "$NEW_VERSION" ]; then + echo -e "${GREEN}Already up to date: $CURRENT_VERSION${NC}" + exit 0 +fi + +echo -e "${YELLOW}Updating from $CURRENT_VERSION to $NEW_VERSION${NC}" + +# Compute SHA256 hashes for each platform +# fetchzip hashes the unpacked directory, so we need to extract and hash +compute_unpacked_hash() { + local url="$1" + local ext="$2" + local tmpdir=$(mktemp -d) + local archive="/tmp/opencode-archive.$ext" + + curl -fsSL "$url" -o "$archive" + + if [ "$ext" = "zip" ]; then + (cd "$tmpdir" && unzip -q "$archive") + else + (cd "$tmpdir" && tar xzf "$archive") + fi + + local sri_hash=$(nix hash path "$tmpdir") + local nix32_hash=$(nix hash convert --hash-algo sha256 --to nix32 "$sri_hash") + + rm -rf "$tmpdir" "$archive" + echo "$nix32_hash" +} + +echo "Computing SHA256 hashes (this may take a moment)..." + +SHA_DARWIN_ARM=$(compute_unpacked_hash "https://github.com/anomalyco/opencode/releases/download/v${NEW_VERSION}/opencode-darwin-arm64.zip" "zip") +echo " aarch64-darwin: $SHA_DARWIN_ARM" + +SHA_DARWIN_X64=$(compute_unpacked_hash "https://github.com/anomalyco/opencode/releases/download/v${NEW_VERSION}/opencode-darwin-x64.zip" "zip") +echo " x86_64-darwin: $SHA_DARWIN_X64" + +SHA_LINUX_X64=$(compute_unpacked_hash "https://github.com/anomalyco/opencode/releases/download/v${NEW_VERSION}/opencode-linux-x64.tar.gz" "tar.gz") +echo " x86_64-linux: $SHA_LINUX_X64" + +SHA_LINUX_ARM64=$(compute_unpacked_hash "https://github.com/anomalyco/opencode/releases/download/v${NEW_VERSION}/opencode-linux-arm64.tar.gz" "tar.gz") +echo " aarch64-linux: $SHA_LINUX_ARM64" + +if [ "$DRY_RUN" = true ]; then + echo -e "${YELLOW}DRY RUN - No changes will be made${NC}" + echo "" + echo "Would update:" + echo " Version: $CURRENT_VERSION -> $NEW_VERSION" + echo " aarch64-darwin SHA: $SHA_DARWIN_ARM" + echo " x86_64-darwin SHA: $SHA_DARWIN_X64" + echo " x86_64-linux SHA: $SHA_LINUX_X64" + echo " aarch64-linux SHA: $SHA_LINUX_ARM64" + exit 0 +fi + +# Update version +sed -i.tmp "s/version = \".*\";/version = \"$NEW_VERSION\";/" "$NIX_FILE" + +# Update SHA256 hashes using awk +awk -v sha_arm="$SHA_DARWIN_ARM" -v sha_x64="$SHA_DARWIN_X64" -v sha_linux_x64="$SHA_LINUX_X64" -v sha_linux_arm="$SHA_LINUX_ARM64" ' +/aarch64-darwin = {/ { in_arm = 1 } +/x86_64-darwin = {/ { in_x64 = 1; in_arm = 0 } +/x86_64-linux = {/ { in_linux_x64 = 1; in_x64 = 0 } +/aarch64-linux = {/ { in_linux_arm = 1; in_linux_x64 = 0 } +/};/ { + in_arm = 0 + in_x64 = 0 + in_linux_x64 = 0 + in_linux_arm = 0 +} +/sha256 = / { + if (in_arm) { + sub(/sha256 = ".*";/, "sha256 = \"" sha_arm "\";") + } else if (in_x64) { + sub(/sha256 = ".*";/, "sha256 = \"" sha_x64 "\";") + } else if (in_linux_x64) { + sub(/sha256 = ".*";/, "sha256 = \"" sha_linux_x64 "\";") + } else if (in_linux_arm) { + sub(/sha256 = ".*";/, "sha256 = \"" sha_linux_arm "\";") + } +} +{ print } +' "$NIX_FILE" > "$NIX_FILE.new" + +mv "$NIX_FILE.new" "$NIX_FILE" +rm -f "$NIX_FILE.tmp" + +echo -e "${GREEN}Successfully updated to version $NEW_VERSION${NC}" +echo "" +echo "Updated SHA256 hashes:" +echo " aarch64-darwin: $SHA_DARWIN_ARM" +echo " x86_64-darwin: $SHA_DARWIN_X64" +echo " x86_64-linux: $SHA_LINUX_X64" +echo " aarch64-linux: $SHA_LINUX_ARM64" +echo "" +echo "Next steps:" +echo " 1. Review changes: git diff $NIX_FILE" +echo " 2. Test build: nix build .#custom-opencode" +echo " 3. Verify version: ./result/bin/opencode --version" +echo " 4. Commit: git add $NIX_FILE && git commit -m 'opencode: Update to version $NEW_VERSION'"