add oh-my-pi
This commit is contained in:
Generated
+82
-1
@@ -21,6 +21,29 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"bun2nix": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-parts": "flake-parts",
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"systems": "systems",
|
||||||
|
"treefmt-nix": "treefmt-nix"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1778446047,
|
||||||
|
"narHash": "sha256-oQvcadh2BCkrog+SGrG6YffKJrveYpjj3TdQJWaKhaM=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "bun2nix",
|
||||||
|
"rev": "f2bc12af1a6369648aac41041ceeaa0b866599c6",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "bun2nix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"cf": {
|
"cf": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1756852014,
|
"lastModified": 1756852014,
|
||||||
@@ -120,9 +143,30 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"flake-parts": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs-lib": [
|
||||||
|
"bun2nix",
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1777988971,
|
||||||
|
"narHash": "sha256-qIoWPDs+0/8JecyYgE3gpKQxW/4bLW/gp45vow9ioCQ=",
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"rev": "0678d8986be1661af6bb555f3489f2fdfc31f6ff",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"flake-utils": {
|
"flake-utils": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"systems": "systems"
|
"systems": "systems_2"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1731533236,
|
"lastModified": 1731533236,
|
||||||
@@ -435,6 +479,7 @@
|
|||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"acer-wmi-ext": "acer-wmi-ext",
|
"acer-wmi-ext": "acer-wmi-ext",
|
||||||
|
"bun2nix": "bun2nix",
|
||||||
"claude-code": "claude-code",
|
"claude-code": "claude-code",
|
||||||
"home-manager": "home-manager",
|
"home-manager": "home-manager",
|
||||||
"lanzaboote": "lanzaboote",
|
"lanzaboote": "lanzaboote",
|
||||||
@@ -484,6 +529,42 @@
|
|||||||
"repo": "default",
|
"repo": "default",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"systems_2": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"treefmt-nix": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"bun2nix",
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1775636079,
|
||||||
|
"narHash": "sha256-pc20NRoMdiar8oPQceQT47UUZMBTiMdUuWrYu2obUP0=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "treefmt-nix",
|
||||||
|
"rev": "790751ff7fd3801feeaf96d7dc416a8d581265ba",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "treefmt-nix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"root": "root",
|
"root": "root",
|
||||||
|
|||||||
@@ -43,6 +43,10 @@
|
|||||||
url = "github:sudosubin/nix-skills";
|
url = "github:sudosubin/nix-skills";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
bun2nix = {
|
||||||
|
url = "github:nix-community/bun2nix";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = { self, nixos-hardware, ... }@inputs:
|
outputs = { self, nixos-hardware, ... }@inputs:
|
||||||
|
|||||||
@@ -66,6 +66,7 @@
|
|||||||
nodejs_24
|
nodejs_24
|
||||||
codex
|
codex
|
||||||
claude-code
|
claude-code
|
||||||
|
oh-my-pi
|
||||||
winbox4
|
winbox4
|
||||||
amdgpu_top
|
amdgpu_top
|
||||||
dua
|
dua
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
ntfsplus,
|
ntfsplus,
|
||||||
nix-skills,
|
nix-skills,
|
||||||
nixpkgs-linuxeol,
|
nixpkgs-linuxeol,
|
||||||
|
bun2nix,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
hardwareConfig: hostConfig:
|
hardwareConfig: hostConfig:
|
||||||
@@ -31,7 +32,7 @@ nixpkgs.lib.nixosSystem {
|
|||||||
claude-code.overlays.default
|
claude-code.overlays.default
|
||||||
acer-wmi-ext.overlays.default
|
acer-wmi-ext.overlays.default
|
||||||
nix-skills.overlays.default
|
nix-skills.overlays.default
|
||||||
];
|
] ++ (import ../overlays/pkgs.nix { inherit bun2nix; });
|
||||||
nix.settings = {
|
nix.settings = {
|
||||||
substituters = [ "https://claude-code.cachix.org" ];
|
substituters = [ "https://claude-code.cachix.org" ];
|
||||||
trusted-public-keys = [ "claude-code.cachix.org-1:YeXf2aNu7UTX8Vwrze0za1WEDS+4DuI2kVeWEE4fsRk=" ];
|
trusted-public-keys = [ "claude-code.cachix.org-1:YeXf2aNu7UTX8Vwrze0za1WEDS+4DuI2kVeWEE4fsRk=" ];
|
||||||
|
|||||||
@@ -4,11 +4,6 @@
|
|||||||
# Allow unfree packages
|
# Allow unfree packages
|
||||||
nixpkgs.config.allowUnfree = true;
|
nixpkgs.config.allowUnfree = true;
|
||||||
|
|
||||||
# Overlay different packages on top of nixpkgs
|
|
||||||
nixpkgs.overlays = [
|
|
||||||
(import ../../overlays/pkgs.nix)
|
|
||||||
];
|
|
||||||
|
|
||||||
# Ventoy has some blobs making it insecure
|
# Ventoy has some blobs making it insecure
|
||||||
nixpkgs.config.permittedInsecurePackages = [
|
nixpkgs.config.permittedInsecurePackages = [
|
||||||
"ventoy-qt5-1.1.12"
|
"ventoy-qt5-1.1.12"
|
||||||
|
|||||||
+11
-6
@@ -1,9 +1,14 @@
|
|||||||
self: super:
|
{ bun2nix }:
|
||||||
{
|
|
||||||
opencode-claude-auth = super.callPackage ../pkgs/opencode-claude-auth {};
|
[
|
||||||
|
bun2nix.overlays.default
|
||||||
|
(final: prev: {
|
||||||
|
oh-my-pi = final.callPackage ../pkgs/oh-my-pi { inherit (final) bun2nix; };
|
||||||
|
opencode-claude-auth = prev.callPackage ../pkgs/opencode-claude-auth { };
|
||||||
# Build failure 08.05.2026
|
# Build failure 08.05.2026
|
||||||
# https://github.com/NixOS/nixpkgs/issues/513245#issuecomment-4320293674
|
# https://github.com/NixOS/nixpkgs/issues/513245#issuecomment-4320293674
|
||||||
openldap = super.openldap.overrideAttrs {
|
openldap = prev.openldap.overrideAttrs {
|
||||||
doCheck = !super.stdenv.hostPlatform.isi686;
|
doCheck = !prev.stdenv.hostPlatform.isi686;
|
||||||
};
|
};
|
||||||
}
|
})
|
||||||
|
]
|
||||||
|
|||||||
@@ -0,0 +1,221 @@
|
|||||||
|
{ bun2nix, fetchFromGitHub, fetchurl, fetchzip, runCommand, python3, pkgs, stdenv, ... }:
|
||||||
|
|
||||||
|
# NOTE: This derivation works around two open bun2nix bugs. Remove the
|
||||||
|
# workarounds and simplify once they are fixed upstream.
|
||||||
|
#
|
||||||
|
# Bug 1 — missing .npm manifest cache files
|
||||||
|
# https://github.com/nix-community/bun2nix/issues/77
|
||||||
|
#
|
||||||
|
# bun's install cache requires two kinds of entries per package:
|
||||||
|
# - the extracted package directory (e.g. handlebars@4.7.9@@@1/)
|
||||||
|
# - a hashed .npm manifest file (e.g. 02dd05ab1686ff3a.npm)
|
||||||
|
# bun2nix only provides the former. bun therefore fetches the manifest from
|
||||||
|
# the registry during the "Resolving" phase, which fails in the Nix sandbox.
|
||||||
|
#
|
||||||
|
# Workaround: pass --offline to bun install. This tells bun to skip manifest
|
||||||
|
# fetches and trust the lockfile for resolution instead.
|
||||||
|
#
|
||||||
|
# Bug 2 — catalog: specifiers still trigger network resolution with --offline
|
||||||
|
# https://github.com/nix-community/bun2nix/issues/77 (same thread)
|
||||||
|
#
|
||||||
|
# bun2nix's bunResolveCatalogRefs rewrites "catalog:" specifiers in
|
||||||
|
# package.json to the version *range* from the catalog table (e.g. "^1.3.14")
|
||||||
|
# rather than the exact pinned version from bun.lock's packages section.
|
||||||
|
# Even with --offline, bun reads the catalog table from bun.lock and tries to
|
||||||
|
# resolve those ranges, hitting the network.
|
||||||
|
#
|
||||||
|
# Workaround: the Python script below pre-processes the source before the
|
||||||
|
# build. It pins every dep in every workspace package.json to the exact
|
||||||
|
# version from bun.lock's packages section (so no ranges remain for bun to
|
||||||
|
# resolve), and strips the catalog/catalogs keys from bun.lock entirely.
|
||||||
|
#
|
||||||
|
# bun.lock is JSONC (trailing-comma JSON) so we parse it with Python's stdlib
|
||||||
|
# json after stripping trailing commas with a regex.
|
||||||
|
#
|
||||||
|
# Additionally, oh-my-pi's bun.lock was generated with bun >=1.3.14 which uses
|
||||||
|
# a different Wyhash seed for cache keys than nixpkgs's bun 1.3.13. Bumping bun
|
||||||
|
# globally breaks other packages (e.g. opencode), so instead we patch the
|
||||||
|
# generated wrapper script in postInstall to reference bun 1.3.14 directly.
|
||||||
|
# Hashes from https://github.com/NixOS/nixpkgs/pull/519796
|
||||||
|
|
||||||
|
let
|
||||||
|
version = "15.2.1";
|
||||||
|
|
||||||
|
# bun 1.3.14 — needed for correct cache key hashes; scoped to this package.
|
||||||
|
bun_1_3_14 = pkgs.bun.overrideAttrs (_: {
|
||||||
|
version = "1.3.14";
|
||||||
|
src =
|
||||||
|
let
|
||||||
|
sources = {
|
||||||
|
"aarch64-darwin" = fetchurl {
|
||||||
|
url = "https://github.com/oven-sh/bun/releases/download/bun-v1.3.14/bun-darwin-aarch64.zip";
|
||||||
|
hash = "sha256-2LliIYKK1vl6x6wKt+lYcjQa92MAHogD6CZ2UsJlJiA=";
|
||||||
|
};
|
||||||
|
"aarch64-linux" = fetchurl {
|
||||||
|
url = "https://github.com/oven-sh/bun/releases/download/bun-v1.3.14/bun-linux-aarch64.zip";
|
||||||
|
hash = "sha256-on/7Y6gxA3WDbg1vZorhf6jY0YuIw3yCHGUzGXOhmjs=";
|
||||||
|
};
|
||||||
|
"x86_64-darwin" = fetchurl {
|
||||||
|
url = "https://github.com/oven-sh/bun/releases/download/bun-v1.3.14/bun-darwin-x64-baseline.zip";
|
||||||
|
hash = "sha256-PjWtb1OXGpg0v55nhuKt9ytfGSHMmpxf3gc9KXKUQHY=";
|
||||||
|
};
|
||||||
|
"x86_64-linux" = fetchurl {
|
||||||
|
url = "https://github.com/oven-sh/bun/releases/download/bun-v1.3.14/bun-linux-x64.zip";
|
||||||
|
hash = "sha256-lR7iruhV8IWVruxiJSJqKY0/6oOj3NZGXAnLzN9+hI8=";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
sources.${stdenv.hostPlatform.system} or (throw "bun 1.3.14 not available for ${stdenv.hostPlatform.system}");
|
||||||
|
});
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "can1357";
|
||||||
|
repo = "oh-my-pi";
|
||||||
|
rev = "v${version}";
|
||||||
|
hash = "sha256-fztQJrhDG5ZbTlgqoHA96eCgwYm5WIna3mAPlCDWYLM=";
|
||||||
|
};
|
||||||
|
|
||||||
|
# The workspace source for @oh-my-pi/pi-natives has no pre-built .node
|
||||||
|
# binaries — those only exist in the npm tarball. Fetch it so we can copy
|
||||||
|
# the platform binaries into packages/natives/native/ before the build.
|
||||||
|
piNativesTarball = fetchzip {
|
||||||
|
url = "https://registry.npmjs.org/@oh-my-pi/pi-natives/-/pi-natives-${version}.tgz";
|
||||||
|
hash = "sha256-mEEnvTNxWFVSs1An61K83sSjUJ5bz4yrluwZvz1+6fg=";
|
||||||
|
stripRoot = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
srcWithBunNix = runCommand "oh-my-pi-src" {
|
||||||
|
nativeBuildInputs = [ bun2nix bun_1_3_14 python3 ];
|
||||||
|
} ''
|
||||||
|
cp -r ${src} $out
|
||||||
|
chmod -R u+w $out
|
||||||
|
|
||||||
|
# Copy pre-built .node binaries from the npm tarball into the workspace
|
||||||
|
# source so the runtime can load the native addon without building Rust.
|
||||||
|
cp ${piNativesTarball}/package/native/*.node $out/packages/natives/native/
|
||||||
|
|
||||||
|
bun2nix --lock-file $out/bun.lock --output-file $out/bun.nix
|
||||||
|
|
||||||
|
python3 - "$out" << 'EOF'
|
||||||
|
import sys, re, json, os
|
||||||
|
|
||||||
|
root = sys.argv[1]
|
||||||
|
lock_path = os.path.join(root, "bun.lock")
|
||||||
|
|
||||||
|
raw = open(lock_path).read()
|
||||||
|
lock = json.loads(re.sub(r',(\s*[}\]])', r'\1', raw))
|
||||||
|
|
||||||
|
packages = lock.get("packages", {})
|
||||||
|
catalog = lock.get("catalog", {})
|
||||||
|
catalogs = lock.get("catalogs", {})
|
||||||
|
|
||||||
|
# Build name -> exact resolved version from the packages section.
|
||||||
|
resolved = {}
|
||||||
|
for name, entry in packages.items():
|
||||||
|
if isinstance(entry, list) and entry and isinstance(entry[0], str):
|
||||||
|
spec = entry[0]
|
||||||
|
if spec.startswith(name + "@"):
|
||||||
|
resolved[name] = spec[len(name) + 1:]
|
||||||
|
|
||||||
|
def pin(name, spec):
|
||||||
|
"""Pin a dep specifier to its exact resolved version from bun.lock."""
|
||||||
|
if not isinstance(spec, str):
|
||||||
|
return spec
|
||||||
|
# catalog: specifiers — resolve via catalog table then pinned version.
|
||||||
|
if spec.startswith("catalog:"):
|
||||||
|
cname = spec[len("catalog:"):]
|
||||||
|
table = catalog if cname == "" else catalogs.get(cname, {})
|
||||||
|
rv = resolved.get(name)
|
||||||
|
cv = table.get(name)
|
||||||
|
if isinstance(rv, str) and rv.startswith("workspace:"):
|
||||||
|
return "workspace:*"
|
||||||
|
if isinstance(rv, str):
|
||||||
|
return rv
|
||||||
|
if isinstance(cv, str):
|
||||||
|
return cv
|
||||||
|
return spec
|
||||||
|
# Any npm version range — pin to exact resolved version.
|
||||||
|
if not spec.startswith(("workspace:", "file:", "link:", "git", "http", "/")):
|
||||||
|
rv = resolved.get(name)
|
||||||
|
if isinstance(rv, str) and rv.startswith("workspace:"):
|
||||||
|
return "workspace:*"
|
||||||
|
if isinstance(rv, str):
|
||||||
|
return rv
|
||||||
|
return spec
|
||||||
|
|
||||||
|
sections = ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"]
|
||||||
|
|
||||||
|
def rewrite(holder):
|
||||||
|
for sec in sections:
|
||||||
|
deps = holder.get(sec)
|
||||||
|
if isinstance(deps, dict):
|
||||||
|
for name in list(deps):
|
||||||
|
deps[name] = pin(name, deps[name])
|
||||||
|
|
||||||
|
# Rewrite bun.lock workspaces and drop the catalog tables.
|
||||||
|
for ws in lock.get("workspaces", {}).values():
|
||||||
|
rewrite(ws)
|
||||||
|
lock.pop("catalog", None)
|
||||||
|
lock.pop("catalogs", None)
|
||||||
|
open(lock_path, "w").write(json.dumps(lock, indent=2) + "\n")
|
||||||
|
|
||||||
|
# Rewrite each workspace package.json (root "" included).
|
||||||
|
for ws_dir in lock.get("workspaces", {}):
|
||||||
|
pkg_path = os.path.join(root, ws_dir, "package.json")
|
||||||
|
if not os.path.exists(pkg_path):
|
||||||
|
continue
|
||||||
|
pkg = json.loads(open(pkg_path).read())
|
||||||
|
rewrite(pkg)
|
||||||
|
open(pkg_path, "w").write(json.dumps(pkg, indent=2) + "\n")
|
||||||
|
EOF
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
|
||||||
|
(bun2nix.writeBunApplication {
|
||||||
|
pname = "omp";
|
||||||
|
inherit version;
|
||||||
|
|
||||||
|
src = srcWithBunNix;
|
||||||
|
|
||||||
|
# oh-my-pi requires bun >=1.3.14 at runtime. writeBunApplication prepends
|
||||||
|
# pkgs.bun (1.3.13) to PATH in the startup script, so we use an absolute
|
||||||
|
# path to bun 1.3.14 instead of relying on PATH resolution.
|
||||||
|
#
|
||||||
|
# writeBunApplication's installPhase does `cd $out/share/$pname` before
|
||||||
|
# exec, so $PWD is always the store path. OLDPWD is set by bash's cd to the
|
||||||
|
# user's original directory. We cd back so omp's process.cwd() is correct,
|
||||||
|
# and use an absolute path to the entry point so bun resolves modules from
|
||||||
|
# the store regardless of cwd.
|
||||||
|
# At this point the wrapper has already done `cd $out/share/omp`, so $PWD
|
||||||
|
# is the store package dir and OLDPWD is the user's original directory.
|
||||||
|
# Capture the store dir, cd back to the user's dir so omp's process.cwd()
|
||||||
|
# is correct, then exec bun with an absolute path so module resolution
|
||||||
|
# still works from the store.
|
||||||
|
startScript = ''
|
||||||
|
_omp_pkg="$PWD"
|
||||||
|
cd "''${OLDPWD:-$PWD}"
|
||||||
|
exec ${bun_1_3_14}/bin/bun run "$_omp_pkg/packages/coding-agent/src/cli.ts" "$@"
|
||||||
|
'';
|
||||||
|
|
||||||
|
dontUseBunBuild = true;
|
||||||
|
dontUseBunCheck = true;
|
||||||
|
|
||||||
|
# --offline: workaround for Bug 1 above (missing .npm manifest cache files).
|
||||||
|
bunInstallFlags = [ "--offline" "--linker=isolated" "--ignore-scripts" ];
|
||||||
|
|
||||||
|
# Generate the docs index embedded into the binary at build time.
|
||||||
|
# The prepack script reads docs/**/*.md and emits docs-index.generated.ts.
|
||||||
|
postBunNodeModulesInstallPhase = ''
|
||||||
|
${bun_1_3_14}/bin/bun run packages/coding-agent/scripts/generate-docs-index.ts
|
||||||
|
'';
|
||||||
|
|
||||||
|
bunDeps = bun2nix.fetchBunDeps {
|
||||||
|
bunNix = "${srcWithBunNix}/bun.nix";
|
||||||
|
};
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description = "AI coding agent for the terminal — batteries included";
|
||||||
|
homepage = "https://omp.sh";
|
||||||
|
mainProgram = "omp";
|
||||||
|
};
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user