feat(aionui): Add AionUi AI cowork desktop app (v2.1.4)
Some checks failed
CI / check (push) Has been cancelled
Some checks failed
CI / check (push) Has been cancelled
Build AionUi from source using bun for dependency fetching and electron-vite for TypeScript compilation. Native addons (better-sqlite3, sharp) are compiled against nixpkgs node-gyp. The package uses a fixed-output derivation for bun install, electron-vite for the build, and wraps the result with nixpkgs electron for a fully self-contained runtime. Also includes desktop entry and icon generation.
This commit is contained in:
@@ -12,6 +12,7 @@ A custom Nix overlay and flake providing additional packages not found in upstre
|
|||||||
|
|
||||||
| Package | Description | Category |
|
| Package | Description | Category |
|
||||||
|---------|-------------|----------|
|
|---------|-------------|----------|
|
||||||
|
| `aionui` | Free, open-source, Cowork app with AI Agents | AI Coding Agents |
|
||||||
| `container-use` | Containerized environments for coding agents | AI Coding Agents |
|
| `container-use` | Containerized environments for coding agents | AI Coding Agents |
|
||||||
| `desloppify` | Multi-language codebase health scanner and technical debt tracker for AI agents | AI Coding Agents |
|
| `desloppify` | Multi-language codebase health scanner and technical debt tracker for AI agents | AI Coding Agents |
|
||||||
| `freebuff` | The world's strongest free coding agent | AI Coding Agents |
|
| `freebuff` | The world's strongest free coding agent | AI Coding Agents |
|
||||||
@@ -106,6 +107,7 @@ nix-overlay/
|
|||||||
│ ├── default.nix # Binary-cache-friendly overlay
|
│ ├── default.nix # Binary-cache-friendly overlay
|
||||||
│ └── shared-nixpkgs.nix # Dependency-sharing overlay
|
│ └── shared-nixpkgs.nix # Dependency-sharing overlay
|
||||||
├── packages/ # Package definitions
|
├── packages/ # Package definitions
|
||||||
|
│ ├── aionui/ # AionUi - AI Cowork desktop app
|
||||||
│ ├── container-use/ # Containerized environments for coding agents
|
│ ├── container-use/ # Containerized environments for coding agents
|
||||||
│ ├── default/ # Meta-package listing all packages
|
│ ├── default/ # Meta-package listing all packages
|
||||||
│ ├── desloppify/ # Codebase health scanner for AI agents
|
│ ├── desloppify/ # Codebase health scanner for AI agents
|
||||||
|
|||||||
5
packages/aionui/default.nix
Normal file
5
packages/aionui/default.nix
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
pkgs.callPackage ./package.nix { }
|
||||||
226
packages/aionui/package.nix
Normal file
226
packages/aionui/package.nix
Normal file
@@ -0,0 +1,226 @@
|
|||||||
|
{
|
||||||
|
lib,
|
||||||
|
stdenv,
|
||||||
|
fetchFromGitHub,
|
||||||
|
bun,
|
||||||
|
nodejs,
|
||||||
|
node-gyp,
|
||||||
|
electron,
|
||||||
|
autoPatchelfHook,
|
||||||
|
makeWrapper,
|
||||||
|
copyDesktopItems,
|
||||||
|
imagemagick,
|
||||||
|
python3,
|
||||||
|
cacert,
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
version = "2.1.4";
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "iOfficeAI";
|
||||||
|
repo = "AionUi";
|
||||||
|
rev = "v${version}";
|
||||||
|
hash = "sha256-A7dKGEuo5n+M7D9fJR3TN95q1P7En/ulsTO+ev6SAUY=";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Fixed-output derivation: fetch all pure-JS dependencies via bun.
|
||||||
|
# We skip install scripts because they use #!/usr/bin/env shebangs
|
||||||
|
# that don't exist in the Nix sandbox. Native addons are built
|
||||||
|
# separately in the main derivation.
|
||||||
|
bunDeps = stdenv.mkDerivation {
|
||||||
|
name = "aionui-bun-deps-${version}";
|
||||||
|
inherit src;
|
||||||
|
nativeBuildInputs = [
|
||||||
|
bun
|
||||||
|
cacert
|
||||||
|
];
|
||||||
|
|
||||||
|
outputHashAlgo = "sha256";
|
||||||
|
outputHashMode = "recursive";
|
||||||
|
outputHash = "sha256-Fuj55vxDgpx5A4iwnU/5IZKPfaYMH3DeZ1yauuZHn8g=";
|
||||||
|
|
||||||
|
dontPatchShebangs = true;
|
||||||
|
dontFixup = true;
|
||||||
|
|
||||||
|
SSL_CERT_FILE = "${cacert}/etc/ssl/certs/ca-bundle.crt";
|
||||||
|
|
||||||
|
buildPhase = ''
|
||||||
|
export HOME=$TMPDIR
|
||||||
|
bun install --frozen-lockfile --ignore-scripts
|
||||||
|
'';
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out
|
||||||
|
cp -r node_modules $out/
|
||||||
|
cp -r packages $out/
|
||||||
|
# Workspace packages reference root configs with relative paths
|
||||||
|
cp tsconfig.json $out/
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
in
|
||||||
|
|
||||||
|
stdenv.mkDerivation rec {
|
||||||
|
pname = "aionui";
|
||||||
|
inherit version src;
|
||||||
|
|
||||||
|
nativeBuildInputs = [
|
||||||
|
bun
|
||||||
|
nodejs
|
||||||
|
node-gyp
|
||||||
|
autoPatchelfHook
|
||||||
|
makeWrapper
|
||||||
|
copyDesktopItems
|
||||||
|
imagemagick
|
||||||
|
python3
|
||||||
|
];
|
||||||
|
|
||||||
|
buildInputs = [
|
||||||
|
stdenv.cc.cc.lib
|
||||||
|
];
|
||||||
|
|
||||||
|
buildPhase = ''
|
||||||
|
runHook preBuild
|
||||||
|
|
||||||
|
export HOME=$TMPDIR
|
||||||
|
|
||||||
|
# Use the pre-fetched node_modules from the FOD (symlink farm)
|
||||||
|
ln -sf ${bunDeps}/node_modules .
|
||||||
|
|
||||||
|
# ── Build better-sqlite3 native addon ──────────────────────
|
||||||
|
# The FOD output is read-only; build in a temp dir.
|
||||||
|
echo "Building better-sqlite3 from source..."
|
||||||
|
BT3_SRC=$TMPDIR/bts3-src
|
||||||
|
BT3_OUT=$TMPDIR/bts3-out
|
||||||
|
mkdir -p "$BT3_SRC" "$BT3_OUT"
|
||||||
|
cp -rL node_modules/better-sqlite3/* "$BT3_SRC/"
|
||||||
|
chmod -R u+w "$BT3_SRC"
|
||||||
|
(
|
||||||
|
cd "$BT3_SRC"
|
||||||
|
export npm_config_nodedir=${nodejs}
|
||||||
|
node-gyp rebuild
|
||||||
|
mkdir -p "$BT3_OUT/build/Release"
|
||||||
|
cp build/Release/better_sqlite3.node "$BT3_OUT/build/Release/" 2>/dev/null || true
|
||||||
|
)
|
||||||
|
|
||||||
|
# ── Build sharp native addon ──────────────────────────────
|
||||||
|
echo "Building sharp from source..."
|
||||||
|
SHARP_SRC=$TMPDIR/sharp-src
|
||||||
|
SHARP_OUT=$TMPDIR/sharp-out
|
||||||
|
mkdir -p "$SHARP_SRC" "$SHARP_OUT"
|
||||||
|
cp -rL node_modules/sharp/* "$SHARP_SRC/" 2>/dev/null || true
|
||||||
|
if [ -f "$SHARP_SRC/package.json" ]; then
|
||||||
|
chmod -R u+w "$SHARP_SRC"
|
||||||
|
(
|
||||||
|
cd "$SHARP_SRC"
|
||||||
|
export npm_config_nodedir=${nodejs}
|
||||||
|
node-gyp rebuild 2>/dev/null || echo " sharp: build skipped (needs libvips)"
|
||||||
|
mkdir -p "$SHARP_OUT/build/Release"
|
||||||
|
cp build/Release/sharp.node "$SHARP_OUT/build/Release/" 2>/dev/null || true
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── electron-vite build ───────────────────────────────────
|
||||||
|
echo "Running electron-vite build..."
|
||||||
|
${nodejs}/bin/node node_modules/.bin/electron-vite build \
|
||||||
|
--config packages/desktop/electron.vite.config.ts
|
||||||
|
|
||||||
|
# ── Bundle MCP servers ────────────────────────────────────
|
||||||
|
echo "Building MCP servers..."
|
||||||
|
${nodejs}/bin/node scripts/build-mcp-servers.js
|
||||||
|
|
||||||
|
runHook postBuild
|
||||||
|
'';
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
runHook preInstall
|
||||||
|
|
||||||
|
mkdir -p $out/{bin,lib/aionui}
|
||||||
|
|
||||||
|
# ── Built output ──────────────────────────────────────────
|
||||||
|
cp -r out $out/lib/aionui/
|
||||||
|
cp -r public $out/lib/aionui/
|
||||||
|
cp package.json $out/lib/aionui/
|
||||||
|
|
||||||
|
# ── Runtime dependencies ──────────────────────────────────
|
||||||
|
# Copy node_modules (from the symlink) – the compiled output
|
||||||
|
# has externalized require() calls for every dependency.
|
||||||
|
cp -rL node_modules $out/lib/aionui/
|
||||||
|
|
||||||
|
# Remove prebuilt musl (Alpine) binaries from sharp — they
|
||||||
|
# are incompatible with glibc and we built from source anyway.
|
||||||
|
find $out/lib/aionui/node_modules -path "*/sharp-linuxmusl*" -type d -exec rm -rf {} + 2>/dev/null || true
|
||||||
|
find $out/lib/aionui/node_modules -path "*/sharp-libvips-linuxmusl*" -type d -exec rm -rf {} + 2>/dev/null || true
|
||||||
|
|
||||||
|
# ── Inject compiled native addons ─────────────────────────
|
||||||
|
# cp -rL from the FOD preserves read-only permissions.
|
||||||
|
# Make native addon dirs writable before overlaying binaries.
|
||||||
|
chmod -R u+w $out/lib/aionui/node_modules/better-sqlite3 2>/dev/null || true
|
||||||
|
chmod -R u+w $out/lib/aionui/node_modules/sharp 2>/dev/null || true
|
||||||
|
|
||||||
|
BT3_OUT=$TMPDIR/bts3-out
|
||||||
|
if [ -f "$BT3_OUT/build/Release/better_sqlite3.node" ]; then
|
||||||
|
mkdir -p $out/lib/aionui/node_modules/better-sqlite3/build/Release
|
||||||
|
cp "$BT3_OUT/build/Release/better_sqlite3.node" \
|
||||||
|
$out/lib/aionui/node_modules/better-sqlite3/build/Release/
|
||||||
|
fi
|
||||||
|
|
||||||
|
SHARP_OUT=$TMPDIR/sharp-out
|
||||||
|
if [ -f "$SHARP_OUT/build/Release/sharp.node" ]; then
|
||||||
|
mkdir -p $out/lib/aionui/node_modules/sharp/build/Release
|
||||||
|
cp "$SHARP_OUT/build/Release/sharp.node" \
|
||||||
|
$out/lib/aionui/node_modules/sharp/build/Release/
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── Desktop entry ─────────────────────────────────────────
|
||||||
|
mkdir -p $out/share/applications
|
||||||
|
cat > $out/share/applications/aionui.desktop << EOF
|
||||||
|
[Desktop Entry]
|
||||||
|
Name=AionUi
|
||||||
|
Comment=Free, open-source Cowork app with AI Agents
|
||||||
|
Exec=$out/bin/aionui
|
||||||
|
Icon=aionui
|
||||||
|
Terminal=false
|
||||||
|
Type=Application
|
||||||
|
Categories=Office;Utility;
|
||||||
|
EOF
|
||||||
|
|
||||||
|
mkdir -p $out/share/icons/hicolor/256x256/apps
|
||||||
|
if [ -f resources/app.png ]; then
|
||||||
|
convert resources/app.png -resize 256x256 \
|
||||||
|
$out/share/icons/hicolor/256x256/apps/aionui.png
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── Launcher ──────────────────────────────────────────────
|
||||||
|
makeWrapper ${electron}/bin/electron $out/bin/aionui \
|
||||||
|
--add-flags "$out/lib/aionui"
|
||||||
|
|
||||||
|
runHook postInstall
|
||||||
|
'';
|
||||||
|
|
||||||
|
dontStrip = true;
|
||||||
|
autoPatchelfIgnoreMissingDeps = true;
|
||||||
|
|
||||||
|
desktopItems = [ "aionui.desktop" ];
|
||||||
|
|
||||||
|
doCheck = false;
|
||||||
|
|
||||||
|
passthru = {
|
||||||
|
category = "AI Coding Agents";
|
||||||
|
updateScript = [
|
||||||
|
"nix-update"
|
||||||
|
"--flake"
|
||||||
|
".#aionui"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "Free, open-source, Cowork app with AI Agents";
|
||||||
|
homepage = "https://github.com/iOfficeAI/AionUi";
|
||||||
|
changelog = "https://github.com/iOfficeAI/AionUi/releases/tag/v${version}";
|
||||||
|
license = licenses.asl20;
|
||||||
|
sourceProvenance = with sourceTypes; [ fromSource ];
|
||||||
|
mainProgram = "aionui";
|
||||||
|
platforms = platforms.linux;
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user