🤖 codex: add linux builds (no-issue)

What:
- add linux outputs and source build for summarize; plugin flakes now follow current system
- expand update-tools to handle per-system assets and summarize source/pnpm hash
- include linux checks in garnix and docs updates

Why:
- enable linux users to consume supported tools and summarize via Nix

Tests:
- ubs --diff
- nix flake check
- nix flake check --all-systems
- nix build .#summarize
- ./result/bin/summarize --version
This commit is contained in:
Josh Palmer 2026-01-08 15:22:48 +01:00
parent 6e9ee0ddb9
commit 5234375e15
25 changed files with 505 additions and 162 deletions

View File

@ -4,7 +4,8 @@
Nix packaging for [Peter Steinberger's](https://github.com/steipete) tools, with per-tool clawdbot plugins. Part of the [nix-clawdbot](https://github.com/clawdbot/nix-clawdbot) ecosystem.
Darwin/aarch64 only (Apple Silicon Macs).
Darwin/aarch64 plus Linux (x86_64/aarch64) for tools that ship Linux builds.
On Linux, `summarize` is built from source (Node 22 + pnpm) since upstream only ships a macOS Bun binary.
## Why this exists
@ -58,6 +59,11 @@ inputs.nix-steipete-tools.url = "github:clawdbot/nix-steipete-tools";
inputs.nix-steipete-tools.packages.aarch64-darwin.camsnap
inputs.nix-steipete-tools.packages.aarch64-darwin.peekaboo
# etc.
# Linux examples:
inputs.nix-steipete-tools.packages.x86_64-linux.camsnap
inputs.nix-steipete-tools.packages.aarch64-linux.gogcli
inputs.nix-steipete-tools.packages.x86_64-linux.summarize
```
## Skills syncing
@ -86,7 +92,7 @@ Fetches latest release versions/URLs/hashes and updates the Nix expressions. Ora
|----------|----------|--------------|
| **sync-skills** | Every 30 min | Pulls latest skills from clawdbot main |
| **update-tools** | Every 10 min | Checks for new tool releases |
| **Garnix** | On push | Builds all packages via `checks.*` |
| **Garnix** | On push | Builds all packages via `checks.*` (darwin + linux) |
Automated PRs keep everything fresh without manual intervention.

View File

@ -12,10 +12,15 @@ import (
)
type Tool struct {
Name string
Repo string
AssetRegex *regexp.Regexp
NixFile string
Name string
Repo string
Assets []AssetSpec
NixFile string
}
type AssetSpec struct {
System string
Regex *regexp.Regexp
}
func updateTool(tool Tool) error {
@ -25,31 +30,107 @@ func updateTool(tool Tool) error {
return err
}
version := strings.TrimPrefix(rel.TagName, "v")
if err := internal.ReplaceOnce(tool.NixFile, regexp.MustCompile(`version = "[^"]+";`), fmt.Sprintf(`version = "%s";`, version)); err != nil {
return err
}
for _, asset := range tool.Assets {
var assetURL string
for _, a := range rel.Assets {
if asset.Regex.MatchString(a.Name) {
assetURL = a.BrowserDownloadURL
break
}
}
if assetURL == "" {
return fmt.Errorf("no asset matched for %s (%s)", tool.Name, asset.System)
}
hash, err := internal.PrefetchHash(assetURL)
if err != nil {
return err
}
if err := updateSourceBlock(tool.NixFile, asset.System, assetURL, hash); err != nil {
return err
}
}
return nil
}
func updateSourceBlock(path, system, url, hash string) error {
blockRe := regexp.MustCompile(fmt.Sprintf(`(?s)"%s" = \{.*?\};`, regexp.QuoteMeta(system)))
return internal.ReplaceOnceFunc(path, blockRe, func(s string) string {
out := regexp.MustCompile(`url = "[^"]+";`).ReplaceAllString(s, fmt.Sprintf(`url = "%s";`, url))
out = regexp.MustCompile(`hash = "sha256-[^"]+";`).ReplaceAllString(out, fmt.Sprintf(`hash = "%s";`, hash))
return out
})
}
func updateSummarize(repoRoot string) error {
log.Printf("[update-tools] summarize")
summarizeFile := filepath.Join(repoRoot, "nix", "pkgs", "summarize.nix")
orig, err := os.ReadFile(summarizeFile)
if err != nil {
return err
}
rel, err := internal.LatestRelease("steipete/summarize")
if err != nil {
return err
}
version := strings.TrimPrefix(rel.TagName, "v")
var assetURL string
for _, a := range rel.Assets {
if tool.AssetRegex.MatchString(a.Name) {
if matched, _ := regexp.MatchString(`summarize-macos-arm64-v[0-9.]+\.tar\.gz`, a.Name); matched {
assetURL = a.BrowserDownloadURL
break
}
}
if assetURL == "" {
return fmt.Errorf("no asset matched for %s", tool.Name)
return fmt.Errorf("no asset matched for summarize")
}
hash, err := internal.PrefetchHash(assetURL)
assetHash, err := internal.PrefetchHash(assetURL)
if err != nil {
return err
}
srcURL := fmt.Sprintf("https://github.com/steipete/summarize/archive/refs/tags/v%s.tar.gz", version)
srcHash, err := internal.PrefetchHash(srcURL)
if err != nil {
return err
}
if err := internal.ReplaceOnce(tool.NixFile, regexp.MustCompile(`version = "[^"]+";`), fmt.Sprintf(`version = "%s";`, version)); err != nil {
if err := internal.ReplaceOnce(summarizeFile, regexp.MustCompile(`version = "[^"]+";`), fmt.Sprintf(`version = "%s";`, version)); err != nil {
return err
}
if err := internal.ReplaceOnce(tool.NixFile, regexp.MustCompile(`url = "[^"]+";`), fmt.Sprintf(`url = "%s";`, assetURL)); err != nil {
if err := updateSourceBlock(summarizeFile, "aarch64-darwin", assetURL, assetHash); err != nil {
return err
}
if err := internal.ReplaceOnce(tool.NixFile, regexp.MustCompile(`hash = "sha256-[^"]+";`), fmt.Sprintf(`hash = "%s";`, hash)); err != nil {
srcRe := regexp.MustCompile(`(?s)src = fetchurl \{[^}]*hash = "sha256-[^"]+";`)
if err := internal.ReplaceOnceFunc(summarizeFile, srcRe, func(s string) string {
return regexp.MustCompile(`hash = "sha256-[^"]+";`).ReplaceAllString(s, fmt.Sprintf(`hash = "%s";`, srcHash))
}); err != nil {
return err
}
pnpmRe := regexp.MustCompile(`(?s)pnpmDeps.*hash = "sha256-[^"]+";`)
if err := internal.ReplaceOnceFunc(summarizeFile, pnpmRe, func(s string) string {
return regexp.MustCompile(`hash = "sha256-[^"]+";`).ReplaceAllString(s, `hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";`)
}); err != nil {
return err
}
log.Printf("[update-tools] summarize: deriving pnpm hash")
logText, buildErr := internal.NixBuildSummarize()
pnpmHash := internal.ExtractGotHash(logText)
if pnpmHash == "" {
_ = os.WriteFile(summarizeFile, orig, 0644)
log.Printf("[update-tools] summarize pnpm hash not found; restored original file (build err: %v)", buildErr)
return nil
}
if err := internal.ReplaceOnceFunc(summarizeFile, pnpmRe, func(s string) string {
return regexp.MustCompile(`hash = "sha256-[^"]+";`).ReplaceAllString(s, fmt.Sprintf(`hash = "%s";`, pnpmHash))
}); err != nil {
return err
}
return nil
}
@ -131,17 +212,82 @@ func main() {
}
tools := []Tool{
{"summarize", "steipete/summarize", regexp.MustCompile(`summarize-macos-arm64-v[0-9.]+\.tar\.gz`), filepath.Join(repoRoot, "nix", "pkgs", "summarize.nix")},
{"gogcli", "steipete/gogcli", regexp.MustCompile(`gogcli_[0-9.]+_darwin_arm64\.tar\.gz`), filepath.Join(repoRoot, "nix", "pkgs", "gogcli.nix")},
{"camsnap", "steipete/camsnap", regexp.MustCompile(`camsnap-macos-arm64\.tar\.gz`), filepath.Join(repoRoot, "nix", "pkgs", "camsnap.nix")},
{"sonoscli", "steipete/sonoscli", regexp.MustCompile(`sonoscli-macos-arm64\.tar\.gz`), filepath.Join(repoRoot, "nix", "pkgs", "sonoscli.nix")},
{"bird", "steipete/bird", regexp.MustCompile(`bird-macos-universal-v[0-9.]+\.tar\.gz`), filepath.Join(repoRoot, "nix", "pkgs", "bird.nix")},
{"peekaboo", "steipete/peekaboo", regexp.MustCompile(`peekaboo-macos-universal\.tar\.gz`), filepath.Join(repoRoot, "nix", "pkgs", "peekaboo.nix")},
{"poltergeist", "steipete/poltergeist", regexp.MustCompile(`poltergeist-macos-universal-v[0-9.]+\.tar\.gz`), filepath.Join(repoRoot, "nix", "pkgs", "poltergeist.nix")},
{"sag", "steipete/sag", regexp.MustCompile(`sag_[0-9.]+_darwin_universal\.tar\.gz`), filepath.Join(repoRoot, "nix", "pkgs", "sag.nix")},
{"imsg", "steipete/imsg", regexp.MustCompile(`imsg-macos\.zip`), filepath.Join(repoRoot, "nix", "pkgs", "imsg.nix")},
{
Name: "gogcli",
Repo: "steipete/gogcli",
Assets: []AssetSpec{
{System: "aarch64-darwin", Regex: regexp.MustCompile(`gogcli_[0-9.]+_darwin_arm64\.tar\.gz`)},
{System: "x86_64-linux", Regex: regexp.MustCompile(`gogcli_[0-9.]+_linux_amd64\.tar\.gz`)},
{System: "aarch64-linux", Regex: regexp.MustCompile(`gogcli_[0-9.]+_linux_arm64\.tar\.gz`)},
},
NixFile: filepath.Join(repoRoot, "nix", "pkgs", "gogcli.nix"),
},
{
Name: "camsnap",
Repo: "steipete/camsnap",
Assets: []AssetSpec{
{System: "aarch64-darwin", Regex: regexp.MustCompile(`camsnap-macos-arm64\.tar\.gz`)},
{System: "x86_64-linux", Regex: regexp.MustCompile(`camsnap_[0-9.]+_linux_amd64\.tar\.gz`)},
{System: "aarch64-linux", Regex: regexp.MustCompile(`camsnap_[0-9.]+_linux_arm64\.tar\.gz`)},
},
NixFile: filepath.Join(repoRoot, "nix", "pkgs", "camsnap.nix"),
},
{
Name: "sonoscli",
Repo: "steipete/sonoscli",
Assets: []AssetSpec{
{System: "aarch64-darwin", Regex: regexp.MustCompile(`sonoscli-macos-arm64\.tar\.gz`)},
{System: "x86_64-linux", Regex: regexp.MustCompile(`sonoscli_[0-9.]+_linux_amd64\.tar\.gz`)},
{System: "aarch64-linux", Regex: regexp.MustCompile(`sonoscli_[0-9.]+_linux_arm64\.tar\.gz`)},
},
NixFile: filepath.Join(repoRoot, "nix", "pkgs", "sonoscli.nix"),
},
{
Name: "bird",
Repo: "steipete/bird",
Assets: []AssetSpec{
{System: "aarch64-darwin", Regex: regexp.MustCompile(`bird-macos-universal-v[0-9.]+\.tar\.gz`)},
},
NixFile: filepath.Join(repoRoot, "nix", "pkgs", "bird.nix"),
},
{
Name: "peekaboo",
Repo: "steipete/peekaboo",
Assets: []AssetSpec{
{System: "aarch64-darwin", Regex: regexp.MustCompile(`peekaboo-macos-universal\.tar\.gz`)},
},
NixFile: filepath.Join(repoRoot, "nix", "pkgs", "peekaboo.nix"),
},
{
Name: "poltergeist",
Repo: "steipete/poltergeist",
Assets: []AssetSpec{
{System: "aarch64-darwin", Regex: regexp.MustCompile(`poltergeist-macos-universal-v[0-9.]+\.tar\.gz`)},
},
NixFile: filepath.Join(repoRoot, "nix", "pkgs", "poltergeist.nix"),
},
{
Name: "sag",
Repo: "steipete/sag",
Assets: []AssetSpec{
{System: "aarch64-darwin", Regex: regexp.MustCompile(`sag_[0-9.]+_darwin_universal\.tar\.gz`)},
{System: "x86_64-linux", Regex: regexp.MustCompile(`sag_[0-9.]+_linux_amd64\.tar\.gz`)},
},
NixFile: filepath.Join(repoRoot, "nix", "pkgs", "sag.nix"),
},
{
Name: "imsg",
Repo: "steipete/imsg",
Assets: []AssetSpec{
{System: "aarch64-darwin", Regex: regexp.MustCompile(`imsg-macos\.zip`)},
},
NixFile: filepath.Join(repoRoot, "nix", "pkgs", "imsg.nix"),
},
}
if err := updateSummarize(repoRoot); err != nil {
log.Fatalf("update summarize failed: %v", err)
}
for _, tool := range tools {
if err := updateTool(tool); err != nil {
log.Fatalf("update %s failed: %v", tool.Name, err)

View File

@ -7,40 +7,66 @@
outputs = { self, nixpkgs }:
let
systems = [ "aarch64-darwin" ];
forAllSystems = f: nixpkgs.lib.genAttrs systems (system: f system);
lib = nixpkgs.lib;
systems = [ "aarch64-darwin" "x86_64-linux" "aarch64-linux" ];
forAllSystems = f: lib.genAttrs systems (system: f system);
packageSystems = {
summarize = [ "aarch64-darwin" "x86_64-linux" "aarch64-linux" ];
gogcli = [ "aarch64-darwin" "x86_64-linux" "aarch64-linux" ];
camsnap = [ "aarch64-darwin" "x86_64-linux" "aarch64-linux" ];
sonoscli = [ "aarch64-darwin" "x86_64-linux" "aarch64-linux" ];
bird = [ "aarch64-darwin" ];
peekaboo = [ "aarch64-darwin" ];
poltergeist = [ "aarch64-darwin" ];
sag = [ "aarch64-darwin" "x86_64-linux" ];
imsg = [ "aarch64-darwin" ];
oracle = [ "aarch64-darwin" "x86_64-linux" "aarch64-linux" ];
};
in {
packages = forAllSystems (system:
let
pkgs = import nixpkgs { inherit system; };
in {
summarize = pkgs.callPackage ./nix/pkgs/summarize.nix {};
gogcli = pkgs.callPackage ./nix/pkgs/gogcli.nix {};
camsnap = pkgs.callPackage ./nix/pkgs/camsnap.nix {};
sonoscli = pkgs.callPackage ./nix/pkgs/sonoscli.nix {};
bird = pkgs.callPackage ./nix/pkgs/bird.nix {};
peekaboo = pkgs.callPackage ./nix/pkgs/peekaboo.nix {};
poltergeist = pkgs.callPackage ./nix/pkgs/poltergeist.nix {};
sag = pkgs.callPackage ./nix/pkgs/sag.nix {};
imsg = pkgs.callPackage ./nix/pkgs/imsg.nix {};
oracle = pkgs.callPackage ./nix/pkgs/oracle.nix {
pkgs = pkgs;
pnpm = if pkgs ? pnpm_10 then pkgs.pnpm_10 else pkgs.pnpm;
};
}
supports = name: lib.elem system packageSystems.${name};
in
(lib.optionalAttrs (supports "summarize") {
summarize = pkgs.callPackage ./nix/pkgs/summarize.nix {
pkgs = pkgs;
pnpm = if pkgs ? pnpm_10 then pkgs.pnpm_10 else pkgs.pnpm;
nodejs = if pkgs ? nodejs_22 then pkgs.nodejs_22 else pkgs.nodejs;
};
})
// (lib.optionalAttrs (supports "gogcli") {
gogcli = pkgs.callPackage ./nix/pkgs/gogcli.nix {};
})
// (lib.optionalAttrs (supports "camsnap") {
camsnap = pkgs.callPackage ./nix/pkgs/camsnap.nix {};
})
// (lib.optionalAttrs (supports "sonoscli") {
sonoscli = pkgs.callPackage ./nix/pkgs/sonoscli.nix {};
})
// (lib.optionalAttrs (supports "bird") {
bird = pkgs.callPackage ./nix/pkgs/bird.nix {};
})
// (lib.optionalAttrs (supports "peekaboo") {
peekaboo = pkgs.callPackage ./nix/pkgs/peekaboo.nix {};
})
// (lib.optionalAttrs (supports "poltergeist") {
poltergeist = pkgs.callPackage ./nix/pkgs/poltergeist.nix {};
})
// (lib.optionalAttrs (supports "sag") {
sag = pkgs.callPackage ./nix/pkgs/sag.nix {};
})
// (lib.optionalAttrs (supports "imsg") {
imsg = pkgs.callPackage ./nix/pkgs/imsg.nix {};
})
// (lib.optionalAttrs (supports "oracle") {
oracle = pkgs.callPackage ./nix/pkgs/oracle.nix {
pkgs = pkgs;
pnpm = if pkgs ? pnpm_10 then pkgs.pnpm_10 else pkgs.pnpm;
};
})
);
checks = forAllSystems (system: {
summarize = self.packages.${system}.summarize;
gogcli = self.packages.${system}.gogcli;
camsnap = self.packages.${system}.camsnap;
sonoscli = self.packages.${system}.sonoscli;
bird = self.packages.${system}.bird;
peekaboo = self.packages.${system}.peekaboo;
poltergeist = self.packages.${system}.poltergeist;
sag = self.packages.${system}.sag;
imsg = self.packages.${system}.imsg;
oracle = self.packages.${system}.oracle;
});
checks = forAllSystems (system: self.packages.${system});
};
}

View File

@ -1,3 +1,5 @@
builds:
include:
- "checks.aarch64-darwin.*"
- "checks.x86_64-linux.*"
- "checks.aarch64-linux.*"

View File

@ -39,6 +39,15 @@ func NixBuildOracle() (string, error) {
return out.String(), err
}
func NixBuildSummarize() (string, error) {
cmd := exec.Command("nix", "build", ".#summarize")
var out bytes.Buffer
cmd.Stdout = &out
cmd.Stderr = &out
err := cmd.Run()
return out.String(), err
}
func ExtractGotHash(log string) string {
for _, line := range strings.Split(log, "\n") {
if idx := strings.Index(line, "got: sha256-"); idx != -1 {

View File

@ -1,13 +1,18 @@
{ lib, stdenv, fetchurl }:
let
sources = {
"aarch64-darwin" = {
url = "https://github.com/steipete/bird/releases/download/v0.6.0/bird-macos-universal-v0.6.0.tar.gz";
hash = "sha256-HdvyNBkq96RUr7vNtDHvqbKv57w/SVLV3AWiaiMUOdo=";
};
};
in
stdenv.mkDerivation {
pname = "bird";
version = "0.6.0";
src = fetchurl {
url = "https://github.com/steipete/bird/releases/download/v0.6.0/bird-macos-universal-v0.6.0.tar.gz";
hash = "sha256-HdvyNBkq96RUr7vNtDHvqbKv57w/SVLV3AWiaiMUOdo=";
};
src = fetchurl sources.${stdenv.hostPlatform.system};
dontConfigure = true;
dontBuild = true;
@ -28,7 +33,7 @@ stdenv.mkDerivation {
description = "Fast X CLI for tweeting, replying, and reading";
homepage = "https://github.com/steipete/bird";
license = licenses.mit;
platforms = [ "aarch64-darwin" ];
platforms = builtins.attrNames sources;
mainProgram = "bird";
};
}

View File

@ -1,13 +1,26 @@
{ lib, stdenv, fetchurl, ffmpeg }:
let
sources = {
"aarch64-darwin" = {
url = "https://github.com/steipete/camsnap/releases/download/v0.2.0/camsnap-macos-arm64.tar.gz";
hash = "sha256-YSgnkN9HuSPbYC0ioR95blkUfcHEye6aQSW7lqKzgz4=";
};
"x86_64-linux" = {
url = "https://github.com/steipete/camsnap/releases/download/v0.2.0/camsnap_0.2.0_linux_amd64.tar.gz";
hash = "sha256-3UCuaKFaf9i3ohEBjzKkyiY7Aw4GlG5Bj+58gmdTMds=";
};
"aarch64-linux" = {
url = "https://github.com/steipete/camsnap/releases/download/v0.2.0/camsnap_0.2.0_linux_arm64.tar.gz";
hash = "sha256-hOcMkScldSUwj23to75jSyVr6gqojx6o0cJeN8j0ALA=";
};
};
in
stdenv.mkDerivation {
pname = "camsnap";
version = "0.2.0";
src = fetchurl {
url = "https://github.com/steipete/camsnap/releases/download/v0.2.0/camsnap-macos-arm64.tar.gz";
hash = "sha256-YSgnkN9HuSPbYC0ioR95blkUfcHEye6aQSW7lqKzgz4=";
};
src = fetchurl sources.${stdenv.hostPlatform.system};
dontConfigure = true;
dontBuild = true;
@ -36,7 +49,7 @@ stdenv.mkDerivation {
description = "One command to grab frames, clips, or motion alerts from RTSP/ONVIF cams";
homepage = "https://github.com/steipete/camsnap";
license = licenses.mit;
platforms = [ "aarch64-darwin" ];
platforms = builtins.attrNames sources;
mainProgram = "camsnap";
};
}

View File

@ -1,13 +1,26 @@
{ lib, stdenv, fetchurl }:
let
sources = {
"aarch64-darwin" = {
url = "https://github.com/steipete/gogcli/releases/download/v0.4.2/gogcli_0.4.2_darwin_arm64.tar.gz";
hash = "sha256-RC08Z/iBORPv/1Amt7nONFEj9j6OXkXN0RsDNuR8qBM=";
};
"x86_64-linux" = {
url = "https://github.com/steipete/gogcli/releases/download/v0.4.2/gogcli_0.4.2_linux_amd64.tar.gz";
hash = "sha256-dktV5uti+/av5gAg7hblkHtMf6I6gaEjXN+29NnpG28=";
};
"aarch64-linux" = {
url = "https://github.com/steipete/gogcli/releases/download/v0.4.2/gogcli_0.4.2_linux_arm64.tar.gz";
hash = "sha256-8Y4ax0Y/WLrHVPgR1B5ld79ulHtNrpWiASCI89Vdpic=";
};
};
in
stdenv.mkDerivation {
pname = "gogcli";
version = "0.4.2";
src = fetchurl {
url = "https://github.com/steipete/gogcli/releases/download/v0.4.2/gogcli_0.4.2_darwin_arm64.tar.gz";
hash = "sha256-RC08Z/iBORPv/1Amt7nONFEj9j6OXkXN0RsDNuR8qBM=";
};
src = fetchurl sources.${stdenv.hostPlatform.system};
dontConfigure = true;
dontBuild = true;
@ -28,7 +41,7 @@ stdenv.mkDerivation {
description = "Google CLI for Gmail, Calendar, Drive, and Contacts";
homepage = "https://github.com/steipete/gogcli";
license = licenses.mit;
platforms = [ "aarch64-darwin" ];
platforms = builtins.attrNames sources;
mainProgram = "gog";
};
}

View File

@ -1,13 +1,18 @@
{ lib, stdenv, fetchurl, unzip }:
let
sources = {
"aarch64-darwin" = {
url = "https://github.com/steipete/imsg/releases/download/v0.4.0/imsg-macos.zip";
hash = "sha256-0OXjM+6IGS1ZW/7Z7s5g417K0DABRZZtWtJ0WMM+QHs=";
};
};
in
stdenv.mkDerivation {
pname = "imsg";
version = "0.4.0";
src = fetchurl {
url = "https://github.com/steipete/imsg/releases/download/v0.4.0/imsg-macos.zip";
hash = "sha256-0OXjM+6IGS1ZW/7Z7s5g417K0DABRZZtWtJ0WMM+QHs=";
};
src = fetchurl sources.${stdenv.hostPlatform.system};
nativeBuildInputs = [ unzip ];
dontConfigure = true;
@ -32,7 +37,7 @@ stdenv.mkDerivation {
description = "Send and read iMessage / SMS from the terminal";
homepage = "https://github.com/steipete/imsg";
license = licenses.mit;
platforms = [ "aarch64-darwin" ];
platforms = builtins.attrNames sources;
mainProgram = "imsg";
};
}

View File

@ -122,7 +122,7 @@ PY
description = "Bundle prompts + files for second-model review";
homepage = "https://github.com/steipete/oracle";
license = licenses.mit;
platforms = [ "aarch64-darwin" ];
platforms = [ "aarch64-darwin" "x86_64-linux" "aarch64-linux" ];
mainProgram = "oracle";
};
})

View File

@ -1,13 +1,18 @@
{ lib, stdenv, fetchurl }:
let
sources = {
"aarch64-darwin" = {
url = "https://github.com/steipete/Peekaboo/releases/download/v3.0.0-beta3/peekaboo-macos-universal.tar.gz";
hash = "sha256-d+rfb9XFTqxktIRNXMiHiQttb0XUmvYbBcbinqLL0kU=";
};
};
in
stdenv.mkDerivation {
pname = "peekaboo";
version = "3.0.0-beta3";
src = fetchurl {
url = "https://github.com/steipete/Peekaboo/releases/download/v3.0.0-beta3/peekaboo-macos-universal.tar.gz";
hash = "sha256-d+rfb9XFTqxktIRNXMiHiQttb0XUmvYbBcbinqLL0kU=";
};
src = fetchurl sources.${stdenv.hostPlatform.system};
dontConfigure = true;
dontBuild = true;
@ -28,7 +33,7 @@ stdenv.mkDerivation {
description = "Lightning-fast macOS screenshots & AI vision analysis";
homepage = "https://github.com/steipete/peekaboo";
license = licenses.mit;
platforms = [ "aarch64-darwin" ];
platforms = builtins.attrNames sources;
mainProgram = "peekaboo";
};
}

View File

@ -1,13 +1,18 @@
{ lib, stdenv, fetchurl, watchman }:
let
sources = {
"aarch64-darwin" = {
url = "https://github.com/steipete/poltergeist/releases/download/v2.1.1/poltergeist-macos-universal-v2.1.1.tar.gz";
hash = "sha256-plQQjbB0QV7UY7U3ZdhfAZsAY/5m0G1E1WEgMm+elk8=";
};
};
in
stdenv.mkDerivation {
pname = "poltergeist";
version = "2.1.1";
src = fetchurl {
url = "https://github.com/steipete/poltergeist/releases/download/v2.1.1/poltergeist-macos-universal-v2.1.1.tar.gz";
hash = "sha256-plQQjbB0QV7UY7U3ZdhfAZsAY/5m0G1E1WEgMm+elk8=";
};
src = fetchurl sources.${stdenv.hostPlatform.system};
dontConfigure = true;
dontBuild = true;
@ -31,7 +36,7 @@ stdenv.mkDerivation {
description = "Universal file watcher with auto-rebuild for any language or build system";
homepage = "https://github.com/steipete/poltergeist";
license = licenses.mit;
platforms = [ "aarch64-darwin" ];
platforms = builtins.attrNames sources;
mainProgram = "poltergeist";
};
}

View File

@ -1,13 +1,22 @@
{ lib, stdenv, fetchurl }:
let
sources = {
"aarch64-darwin" = {
url = "https://github.com/steipete/sag/releases/download/v0.2.1/sag_0.2.1_darwin_universal.tar.gz";
hash = "sha256-ORwAi0fgn2S8p7HmrhEmIQ5gYatf3bzLgDtkUZVMy54=";
};
"x86_64-linux" = {
url = "https://github.com/steipete/sag/releases/download/v0.2.1/sag_0.2.1_linux_amd64.tar.gz";
hash = "sha256-Ti9i8IfPQZn9ZTcrgipbP+du8Rlgiu/vWpqMEYWeg4I=";
};
};
in
stdenv.mkDerivation {
pname = "sag";
version = "0.2.1";
src = fetchurl {
url = "https://github.com/steipete/sag/releases/download/v0.2.1/sag_0.2.1_darwin_universal.tar.gz";
hash = "sha256-ORwAi0fgn2S8p7HmrhEmIQ5gYatf3bzLgDtkUZVMy54=";
};
src = fetchurl sources.${stdenv.hostPlatform.system};
dontConfigure = true;
dontBuild = true;
@ -28,7 +37,7 @@ stdenv.mkDerivation {
description = "Command-line ElevenLabs TTS with mac-style flags";
homepage = "https://github.com/steipete/sag";
license = licenses.mit;
platforms = [ "aarch64-darwin" ];
platforms = builtins.attrNames sources;
mainProgram = "sag";
};
}

View File

@ -1,13 +1,26 @@
{ lib, stdenv, fetchurl }:
let
sources = {
"aarch64-darwin" = {
url = "https://github.com/steipete/sonoscli/releases/download/v0.1.0/sonoscli-macos-arm64.tar.gz";
hash = "sha256-t5VUWXPrxgYXopiQEuO7k91Gx70oefyhbOZmF/XDwaw=";
};
"x86_64-linux" = {
url = "https://github.com/steipete/sonoscli/releases/download/v0.1.0/sonoscli_0.1.0_linux_amd64.tar.gz";
hash = "sha256-8g/sTD4P8Ctbpv5N0nZ1SpP+UH6CUuUwNEo4VjW01ZM=";
};
"aarch64-linux" = {
url = "https://github.com/steipete/sonoscli/releases/download/v0.1.0/sonoscli_0.1.0_linux_arm64.tar.gz";
hash = "sha256-EtBtsNcvD5OvryUjCQ5oy3H7w4etgfXs7PkdsefWdE0=";
};
};
in
stdenv.mkDerivation {
pname = "sonoscli";
version = "0.1.0";
src = fetchurl {
url = "https://github.com/steipete/sonoscli/releases/download/v0.1.0/sonoscli-macos-arm64.tar.gz";
hash = "sha256-t5VUWXPrxgYXopiQEuO7k91Gx70oefyhbOZmF/XDwaw=";
};
src = fetchurl sources.${stdenv.hostPlatform.system};
dontConfigure = true;
dontBuild = true;
@ -34,7 +47,7 @@ stdenv.mkDerivation {
description = "Control Sonos speakers from the command-line";
homepage = "https://github.com/steipete/sonoscli";
license = licenses.mit;
platforms = [ "aarch64-darwin" ];
platforms = builtins.attrNames sources;
mainProgram = "sonos";
};
}

View File

@ -1,34 +1,120 @@
{ lib, stdenv, fetchurl }:
{ lib
, stdenv
, fetchurl
, nodejs
, pnpm
, python3
, python3Packages
, pkg-config
, makeWrapper
, pkgs
, zstd
}:
stdenv.mkDerivation {
let
pname = "summarize";
version = "0.9.0";
src = fetchurl {
url = "https://github.com/steipete/summarize/releases/download/v0.9.0/summarize-macos-arm64-v0.9.0.tar.gz";
hash = "sha256-B6/eUcbv4K9kgozo1fELFX+NNGa0C64dB6OSydwu6A8=";
binSources = {
"aarch64-darwin" = {
url = "https://github.com/steipete/summarize/releases/download/v0.9.0/summarize-macos-arm64-v0.9.0.tar.gz";
hash = "sha256-B6/eUcbv4K9kgozo1fELFX+NNGa0C64dB6OSydwu6A8=";
};
};
dontConfigure = true;
dontBuild = true;
src = fetchurl {
url = "https://github.com/steipete/summarize/archive/refs/tags/v${version}.tar.gz";
hash = "sha256-HQ/jboAN+g7Mz41ayDAt0thR5kuJjttgfJTXE7IRSzQ=";
};
unpackPhase = ''
tar -xzf "$src"
'';
pnpmFetchDepsPkg = pkgs.callPackage "${pkgs.path}/pkgs/build-support/node/fetch-pnpm-deps" {
inherit pnpm;
};
installPhase = ''
runHook preInstall
mkdir -p "$out/bin"
cp summarize "$out/bin/summarize"
chmod 0755 "$out/bin/summarize"
runHook postInstall
'';
pnpmDeps = (pnpmFetchDepsPkg.fetchPnpmDeps {
pname = pname;
version = version;
src = src;
hash = "sha256-3BRbu9xNYUpsUkC1DKXKl8iv5GO9rZqE2eqRVDh8DTA=";
fetcherVersion = 3;
});
meta = with lib; {
description = "Link clean text summary";
homepage = "https://github.com/steipete/summarize";
license = licenses.mit;
platforms = [ "aarch64-darwin" ];
platforms = [ "aarch64-darwin" "x86_64-linux" "aarch64-linux" ];
mainProgram = "summarize";
};
}
in
if stdenv.isLinux then
stdenv.mkDerivation {
inherit pname version src meta;
nativeBuildInputs = [
nodejs
pnpm
python3
python3Packages.setuptools
pkg-config
makeWrapper
zstd
];
env = {
PNPM_IGNORE_PACKAGE_MANAGER_CHECK = "1";
CI = "1";
HOME = "/tmp";
PNPM_HOME = "/tmp/pnpm-home";
PNPM_CONFIG_HOME = "/tmp/pnpm-config";
XDG_CACHE_HOME = "/tmp/pnpm-cache";
NPM_CONFIG_USERCONFIG = "/tmp/pnpm-config/.npmrc";
npm_config_nodedir = "${nodejs.dev}";
npm_config_build_from_source = "1";
PNPM_CONFIG_IGNORE_SCRIPTS = "1";
};
buildPhase = ''
runHook preBuild
mkdir -p "$HOME" "$PNPM_HOME" "$PNPM_CONFIG_HOME" "$XDG_CACHE_HOME"
export PNPM_STORE_PATH="$TMPDIR/pnpm-store"
mkdir -p "$PNPM_STORE_PATH"
tar --zstd -xf ${pnpmDeps}/pnpm-store.tar.zst -C "$PNPM_STORE_PATH"
pnpm install --offline --frozen-lockfile --store-dir "$PNPM_STORE_PATH" --ignore-scripts
pnpm build
pnpm prune --prod
runHook postBuild
'';
installPhase = ''
runHook preInstall
mkdir -p "$out/libexec" "$out/bin"
cp -r dist package.json node_modules "$out/libexec/"
chmod 0755 "$out/libexec/dist/cli.js"
makeWrapper "${nodejs}/bin/node" "$out/bin/summarize" \
--add-flags "$out/libexec/dist/cli.js"
runHook postInstall
'';
}
else
stdenv.mkDerivation {
pname = pname;
version = version;
src = fetchurl binSources.${stdenv.hostPlatform.system};
dontConfigure = true;
dontBuild = true;
unpackPhase = ''
tar -xzf "$src"
'';
installPhase = ''
runHook preInstall
mkdir -p "$out/bin"
cp summarize "$out/bin/summarize"
chmod 0755 "$out/bin/summarize"
runHook postInstall
'';
inherit meta;
}

View File

@ -8,13 +8,13 @@
outputs = { self, nixpkgs, root }:
let
system = "aarch64-darwin";
pkgs = import nixpkgs { inherit system; };
bird = root.packages.${system}.bird;
system = builtins.currentSystem;
packagesForSystem = root.packages.${system} or {};
bird = packagesForSystem.bird or null;
in {
packages.${system}.bird = bird;
packages.${system} = if bird == null then {} else { bird = bird; };
clawdbotPlugin = {
clawdbotPlugin = if bird == null then null else {
name = "bird";
skills = [ ./skills/bird ];
packages = [ bird ];

View File

@ -8,13 +8,13 @@
outputs = { self, nixpkgs, root }:
let
system = "aarch64-darwin";
pkgs = import nixpkgs { inherit system; };
camsnap = root.packages.${system}.camsnap;
system = builtins.currentSystem;
packagesForSystem = root.packages.${system} or {};
camsnap = packagesForSystem.camsnap or null;
in {
packages.${system}.camsnap = camsnap;
packages.${system} = if camsnap == null then {} else { camsnap = camsnap; };
clawdbotPlugin = {
clawdbotPlugin = if camsnap == null then null else {
name = "camsnap";
skills = [ ./skills/camsnap ];
packages = [ camsnap ];

View File

@ -8,13 +8,13 @@
outputs = { self, nixpkgs, root }:
let
system = "aarch64-darwin";
pkgs = import nixpkgs { inherit system; };
gogcli = root.packages.${system}.gogcli;
system = builtins.currentSystem;
packagesForSystem = root.packages.${system} or {};
gogcli = packagesForSystem.gogcli or null;
in {
packages.${system}.gogcli = gogcli;
packages.${system} = if gogcli == null then {} else { gogcli = gogcli; };
clawdbotPlugin = {
clawdbotPlugin = if gogcli == null then null else {
name = "gogcli";
skills = [ ./skills/gog ];
packages = [ gogcli ];

View File

@ -8,13 +8,13 @@
outputs = { self, nixpkgs, root }:
let
system = "aarch64-darwin";
pkgs = import nixpkgs { inherit system; };
imsg = root.packages.${system}.imsg;
system = builtins.currentSystem;
packagesForSystem = root.packages.${system} or {};
imsg = packagesForSystem.imsg or null;
in {
packages.${system}.imsg = imsg;
packages.${system} = if imsg == null then {} else { imsg = imsg; };
clawdbotPlugin = {
clawdbotPlugin = if imsg == null then null else {
name = "imsg";
skills = [ ./skills/imsg ];
packages = [ imsg ];

View File

@ -8,13 +8,13 @@
outputs = { self, nixpkgs, root }:
let
system = "aarch64-darwin";
pkgs = import nixpkgs { inherit system; };
oracle = root.packages.${system}.oracle;
system = builtins.currentSystem;
packagesForSystem = root.packages.${system} or {};
oracle = packagesForSystem.oracle or null;
in {
packages.${system}.oracle = oracle;
packages.${system} = if oracle == null then {} else { oracle = oracle; };
clawdbotPlugin = {
clawdbotPlugin = if oracle == null then null else {
name = "oracle";
skills = [ ./skills/oracle ];
packages = [ oracle ];

View File

@ -8,13 +8,13 @@
outputs = { self, nixpkgs, root }:
let
system = "aarch64-darwin";
pkgs = import nixpkgs { inherit system; };
peekaboo = root.packages.${system}.peekaboo;
system = builtins.currentSystem;
packagesForSystem = root.packages.${system} or {};
peekaboo = packagesForSystem.peekaboo or null;
in {
packages.${system}.peekaboo = peekaboo;
packages.${system} = if peekaboo == null then {} else { peekaboo = peekaboo; };
clawdbotPlugin = {
clawdbotPlugin = if peekaboo == null then null else {
name = "peekaboo";
skills = [ ./skills/peekaboo ];
packages = [ peekaboo ];

View File

@ -8,13 +8,13 @@
outputs = { self, nixpkgs, root }:
let
system = "aarch64-darwin";
pkgs = import nixpkgs { inherit system; };
poltergeist = root.packages.${system}.poltergeist;
system = builtins.currentSystem;
packagesForSystem = root.packages.${system} or {};
poltergeist = packagesForSystem.poltergeist or null;
in {
packages.${system}.poltergeist = poltergeist;
packages.${system} = if poltergeist == null then {} else { poltergeist = poltergeist; };
clawdbotPlugin = {
clawdbotPlugin = if poltergeist == null then null else {
name = "poltergeist";
skills = [ ./skills/poltergeist ];
packages = [ poltergeist ];

View File

@ -8,13 +8,13 @@
outputs = { self, nixpkgs, root }:
let
system = "aarch64-darwin";
pkgs = import nixpkgs { inherit system; };
sag = root.packages.${system}.sag;
system = builtins.currentSystem;
packagesForSystem = root.packages.${system} or {};
sag = packagesForSystem.sag or null;
in {
packages.${system}.sag = sag;
packages.${system} = if sag == null then {} else { sag = sag; };
clawdbotPlugin = {
clawdbotPlugin = if sag == null then null else {
name = "sag";
skills = [ ./skills/sag ];
packages = [ sag ];

View File

@ -8,13 +8,13 @@
outputs = { self, nixpkgs, root }:
let
system = "aarch64-darwin";
pkgs = import nixpkgs { inherit system; };
sonoscli = root.packages.${system}.sonoscli;
system = builtins.currentSystem;
packagesForSystem = root.packages.${system} or {};
sonoscli = packagesForSystem.sonoscli or null;
in {
packages.${system}.sonoscli = sonoscli;
packages.${system} = if sonoscli == null then {} else { sonoscli = sonoscli; };
clawdbotPlugin = {
clawdbotPlugin = if sonoscli == null then null else {
name = "sonoscli";
skills = [ ./skills/sonoscli ];
packages = [ sonoscli ];

View File

@ -8,13 +8,13 @@
outputs = { self, nixpkgs, root }:
let
system = "aarch64-darwin";
pkgs = import nixpkgs { inherit system; };
summarize = root.packages.${system}.summarize;
system = builtins.currentSystem;
packagesForSystem = root.packages.${system} or {};
summarize = packagesForSystem.summarize or null;
in {
packages.${system}.summarize = summarize;
packages.${system} = if summarize == null then {} else { summarize = summarize; };
clawdbotPlugin = {
clawdbotPlugin = if summarize == null then null else {
name = "summarize";
skills = [ ./skills/summarize ];
packages = [ summarize ];