mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-17 05:00:16 +00:00
fix(coding-agent): fix standalone binary WASM loading on Linux, fixes #784
- Import photon-node from ESM entry point (photon_rs_bg.js) instead of CJS entry, allowing Bun to embed WASM in compiled binaries - Add photon.d.ts for TypeScript support of ESM entry - Add scripts/build-binaries.sh for local binary builds - Simplify GitHub workflow to use the build script - Add binaries/ to gitignore
This commit is contained in:
parent
0c33e0dee5
commit
5aa0689828
7 changed files with 177 additions and 87 deletions
82
.github/workflows/build-binaries.yml
vendored
82
.github/workflows/build-binaries.yml
vendored
|
|
@ -36,86 +36,8 @@ jobs:
|
||||||
node-version: '22'
|
node-version: '22'
|
||||||
registry-url: 'https://registry.npmjs.org'
|
registry-url: 'https://registry.npmjs.org'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Build binaries
|
||||||
run: npm ci
|
run: ./scripts/build-binaries.sh
|
||||||
|
|
||||||
- name: Install cross-platform native bindings
|
|
||||||
run: |
|
|
||||||
# npm ci only installs optional deps for the current platform (linux-x64)
|
|
||||||
# We need all platform bindings for bun cross-compilation
|
|
||||||
# Use --force to bypass platform checks (os/cpu restrictions in package.json)
|
|
||||||
|
|
||||||
# Clipboard bindings for all target platforms
|
|
||||||
npm install --no-save --force \
|
|
||||||
@mariozechner/clipboard-darwin-arm64@0.3.0 \
|
|
||||||
@mariozechner/clipboard-darwin-x64@0.3.0 \
|
|
||||||
@mariozechner/clipboard-linux-x64-gnu@0.3.0 \
|
|
||||||
@mariozechner/clipboard-linux-arm64-gnu@0.3.0 \
|
|
||||||
@mariozechner/clipboard-win32-x64-msvc@0.3.0
|
|
||||||
|
|
||||||
# Sharp bindings for all target platforms
|
|
||||||
npm install --no-save --force \
|
|
||||||
@img/sharp-darwin-arm64@0.34.5 \
|
|
||||||
@img/sharp-darwin-x64@0.34.5 \
|
|
||||||
@img/sharp-linux-x64@0.34.5 \
|
|
||||||
@img/sharp-linux-arm64@0.34.5 \
|
|
||||||
@img/sharp-win32-x64@0.34.5 \
|
|
||||||
@img/sharp-libvips-darwin-arm64@1.2.4 \
|
|
||||||
@img/sharp-libvips-darwin-x64@1.2.4 \
|
|
||||||
@img/sharp-libvips-linux-x64@1.2.4 \
|
|
||||||
@img/sharp-libvips-linux-arm64@1.2.4
|
|
||||||
|
|
||||||
- name: Build all packages
|
|
||||||
run: npm run build
|
|
||||||
|
|
||||||
- name: Build binaries for all platforms
|
|
||||||
run: |
|
|
||||||
cd packages/coding-agent
|
|
||||||
|
|
||||||
# Create output directories for each platform
|
|
||||||
mkdir -p binaries/{darwin-arm64,darwin-x64,linux-x64,linux-arm64,windows-x64}
|
|
||||||
|
|
||||||
# Build for each platform - binary is always named 'pi' (or 'pi.exe' for Windows)
|
|
||||||
echo "Building for darwin-arm64..."
|
|
||||||
bun build --compile --target=bun-darwin-arm64 ./dist/cli.js --outfile binaries/darwin-arm64/pi
|
|
||||||
|
|
||||||
echo "Building for darwin-x64..."
|
|
||||||
bun build --compile --target=bun-darwin-x64 ./dist/cli.js --outfile binaries/darwin-x64/pi
|
|
||||||
|
|
||||||
echo "Building for linux-x64..."
|
|
||||||
bun build --compile --target=bun-linux-x64 ./dist/cli.js --outfile binaries/linux-x64/pi
|
|
||||||
|
|
||||||
echo "Building for linux-arm64..."
|
|
||||||
bun build --compile --target=bun-linux-arm64 ./dist/cli.js --outfile binaries/linux-arm64/pi
|
|
||||||
|
|
||||||
echo "Building for windows-x64..."
|
|
||||||
bun build --compile --target=bun-windows-x64 ./dist/cli.js --outfile binaries/windows-x64/pi.exe
|
|
||||||
|
|
||||||
- name: Create release archives
|
|
||||||
run: |
|
|
||||||
cd packages/coding-agent
|
|
||||||
|
|
||||||
# Copy shared files to each platform directory
|
|
||||||
for platform in darwin-arm64 darwin-x64 linux-x64 linux-arm64 windows-x64; do
|
|
||||||
cp package.json binaries/$platform/
|
|
||||||
cp README.md binaries/$platform/
|
|
||||||
cp CHANGELOG.md binaries/$platform/
|
|
||||||
mkdir -p binaries/$platform/theme
|
|
||||||
cp dist/modes/interactive/theme/*.json binaries/$platform/theme/
|
|
||||||
cp -r examples binaries/$platform/
|
|
||||||
done
|
|
||||||
|
|
||||||
# Create archives
|
|
||||||
cd binaries
|
|
||||||
|
|
||||||
# Unix platforms (tar.gz) - use wrapper directory for mise compatibility
|
|
||||||
# mise auto-detects single-directory archives and strips one component
|
|
||||||
for platform in darwin-arm64 darwin-x64 linux-x64 linux-arm64; do
|
|
||||||
mv $platform pi && tar -czf pi-$platform.tar.gz pi && mv pi $platform
|
|
||||||
done
|
|
||||||
|
|
||||||
# Windows (zip)
|
|
||||||
cd windows-x64 && zip -r ../pi-windows-x64.zip . && cd ..
|
|
||||||
|
|
||||||
- name: Extract changelog for this version
|
- name: Extract changelog for this version
|
||||||
id: changelog
|
id: changelog
|
||||||
|
|
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -31,3 +31,4 @@ syntax.jsonl
|
||||||
out.jsonl
|
out.jsonl
|
||||||
pi-*.html
|
pi-*.html
|
||||||
out.html
|
out.html
|
||||||
|
packages/coding-agent/binaries/
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
import photon from "@silvia-odwyer/photon-node";
|
// Use ESM entry point so Bun can embed the WASM in compiled binaries
|
||||||
|
// (the CJS entry uses fs.readFileSync which breaks in standalone binaries)
|
||||||
|
import { PhotonImage } from "@silvia-odwyer/photon-node/photon_rs_bg.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert image to PNG format for terminal display.
|
* Convert image to PNG format for terminal display.
|
||||||
|
|
@ -14,7 +16,7 @@ export async function convertToPng(
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const image = photon.PhotonImage.new_from_byteslice(new Uint8Array(Buffer.from(base64Data, "base64")));
|
const image = PhotonImage.new_from_byteslice(new Uint8Array(Buffer.from(base64Data, "base64")));
|
||||||
try {
|
try {
|
||||||
const pngBuffer = image.get_bytes();
|
const pngBuffer = image.get_bytes();
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
import type { ImageContent } from "@mariozechner/pi-ai";
|
import type { ImageContent } from "@mariozechner/pi-ai";
|
||||||
import photon from "@silvia-odwyer/photon-node";
|
// Use ESM entry point so Bun can embed the WASM in compiled binaries
|
||||||
|
// (the CJS entry uses fs.readFileSync which breaks in standalone binaries)
|
||||||
|
import { PhotonImage, resize, SamplingFilter } from "@silvia-odwyer/photon-node/photon_rs_bg.js";
|
||||||
|
|
||||||
export interface ImageResizeOptions {
|
export interface ImageResizeOptions {
|
||||||
maxWidth?: number; // Default: 2000
|
maxWidth?: number; // Default: 2000
|
||||||
|
|
@ -53,9 +55,9 @@ export async function resizeImage(img: ImageContent, options?: ImageResizeOption
|
||||||
const opts = { ...DEFAULT_OPTIONS, ...options };
|
const opts = { ...DEFAULT_OPTIONS, ...options };
|
||||||
const inputBuffer = Buffer.from(img.data, "base64");
|
const inputBuffer = Buffer.from(img.data, "base64");
|
||||||
|
|
||||||
let image: ReturnType<typeof photon.PhotonImage.new_from_byteslice> | undefined;
|
let image: ReturnType<typeof PhotonImage.new_from_byteslice> | undefined;
|
||||||
try {
|
try {
|
||||||
image = photon.PhotonImage.new_from_byteslice(new Uint8Array(inputBuffer));
|
image = PhotonImage.new_from_byteslice(new Uint8Array(inputBuffer));
|
||||||
|
|
||||||
const originalWidth = image.get_width();
|
const originalWidth = image.get_width();
|
||||||
const originalHeight = image.get_height();
|
const originalHeight = image.get_height();
|
||||||
|
|
@ -94,7 +96,7 @@ export async function resizeImage(img: ImageContent, options?: ImageResizeOption
|
||||||
height: number,
|
height: number,
|
||||||
jpegQuality: number,
|
jpegQuality: number,
|
||||||
): { buffer: Uint8Array; mimeType: string } {
|
): { buffer: Uint8Array; mimeType: string } {
|
||||||
const resized = photon.resize(image!, width, height, photon.SamplingFilter.Lanczos3);
|
const resized = resize(image!, width, height, SamplingFilter.Lanczos3);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const pngBuffer = resized.get_bytes();
|
const pngBuffer = resized.get_bytes();
|
||||||
|
|
|
||||||
5
packages/coding-agent/src/utils/photon.d.ts
vendored
Normal file
5
packages/coding-agent/src/utils/photon.d.ts
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
// Type declarations for the ESM entry point of @silvia-odwyer/photon-node
|
||||||
|
// The ESM entry exports the same API but uses WASM imports that bundlers can embed
|
||||||
|
declare module "@silvia-odwyer/photon-node/photon_rs_bg.js" {
|
||||||
|
export * from "@silvia-odwyer/photon-node";
|
||||||
|
}
|
||||||
|
|
@ -5,5 +5,5 @@
|
||||||
"rootDir": "./src"
|
"rootDir": "./src"
|
||||||
},
|
},
|
||||||
"include": ["src/**/*.ts"],
|
"include": ["src/**/*.ts"],
|
||||||
"exclude": ["node_modules", "dist", "**/*.d.ts", "src/**/*.d.ts"]
|
"exclude": ["node_modules", "dist"]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
158
scripts/build-binaries.sh
Executable file
158
scripts/build-binaries.sh
Executable file
|
|
@ -0,0 +1,158 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# Build pi binaries for all platforms locally.
|
||||||
|
# Mirrors .github/workflows/build-binaries.yml
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# ./scripts/build-binaries.sh [--skip-deps] [--platform <platform>]
|
||||||
|
#
|
||||||
|
# Options:
|
||||||
|
# --skip-deps Skip installing cross-platform dependencies
|
||||||
|
# --platform <name> Build only for specified platform (darwin-arm64, darwin-x64, linux-x64, linux-arm64, windows-x64)
|
||||||
|
#
|
||||||
|
# Output:
|
||||||
|
# packages/coding-agent/binaries/
|
||||||
|
# pi-darwin-arm64.tar.gz
|
||||||
|
# pi-darwin-x64.tar.gz
|
||||||
|
# pi-linux-x64.tar.gz
|
||||||
|
# pi-linux-arm64.tar.gz
|
||||||
|
# pi-windows-x64.zip
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
cd "$(dirname "$0")/.."
|
||||||
|
|
||||||
|
SKIP_DEPS=false
|
||||||
|
PLATFORM=""
|
||||||
|
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case $1 in
|
||||||
|
--skip-deps)
|
||||||
|
SKIP_DEPS=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--platform)
|
||||||
|
PLATFORM="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown option: $1"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Validate platform if specified
|
||||||
|
if [[ -n "$PLATFORM" ]]; then
|
||||||
|
case "$PLATFORM" in
|
||||||
|
darwin-arm64|darwin-x64|linux-x64|linux-arm64|windows-x64)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Invalid platform: $PLATFORM"
|
||||||
|
echo "Valid platforms: darwin-arm64, darwin-x64, linux-x64, linux-arm64, windows-x64"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "==> Installing dependencies..."
|
||||||
|
npm ci
|
||||||
|
|
||||||
|
if [[ "$SKIP_DEPS" == "false" ]]; then
|
||||||
|
echo "==> Installing cross-platform native bindings..."
|
||||||
|
# npm ci only installs optional deps for the current platform
|
||||||
|
# We need all platform bindings for bun cross-compilation
|
||||||
|
# Use --force to bypass platform checks (os/cpu restrictions in package.json)
|
||||||
|
# Install all in one command to avoid npm removing packages from previous installs
|
||||||
|
npm install --no-save --force \
|
||||||
|
@mariozechner/clipboard-darwin-arm64@0.3.0 \
|
||||||
|
@mariozechner/clipboard-darwin-x64@0.3.0 \
|
||||||
|
@mariozechner/clipboard-linux-x64-gnu@0.3.0 \
|
||||||
|
@mariozechner/clipboard-linux-arm64-gnu@0.3.0 \
|
||||||
|
@mariozechner/clipboard-win32-x64-msvc@0.3.0 \
|
||||||
|
@img/sharp-darwin-arm64@0.34.5 \
|
||||||
|
@img/sharp-darwin-x64@0.34.5 \
|
||||||
|
@img/sharp-linux-x64@0.34.5 \
|
||||||
|
@img/sharp-linux-arm64@0.34.5 \
|
||||||
|
@img/sharp-win32-x64@0.34.5 \
|
||||||
|
@img/sharp-libvips-darwin-arm64@1.2.4 \
|
||||||
|
@img/sharp-libvips-darwin-x64@1.2.4 \
|
||||||
|
@img/sharp-libvips-linux-x64@1.2.4 \
|
||||||
|
@img/sharp-libvips-linux-arm64@1.2.4
|
||||||
|
else
|
||||||
|
echo "==> Skipping cross-platform native bindings (--skip-deps)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "==> Building all packages..."
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
echo "==> Building binaries..."
|
||||||
|
cd packages/coding-agent
|
||||||
|
|
||||||
|
# Clean previous builds
|
||||||
|
rm -rf binaries
|
||||||
|
mkdir -p binaries/{darwin-arm64,darwin-x64,linux-x64,linux-arm64,windows-x64}
|
||||||
|
|
||||||
|
# Determine which platforms to build
|
||||||
|
if [[ -n "$PLATFORM" ]]; then
|
||||||
|
PLATFORMS=("$PLATFORM")
|
||||||
|
else
|
||||||
|
PLATFORMS=(darwin-arm64 darwin-x64 linux-x64 linux-arm64 windows-x64)
|
||||||
|
fi
|
||||||
|
|
||||||
|
for platform in "${PLATFORMS[@]}"; do
|
||||||
|
echo "Building for $platform..."
|
||||||
|
if [[ "$platform" == "windows-x64" ]]; then
|
||||||
|
bun build --compile --target=bun-$platform ./dist/cli.js --outfile binaries/$platform/pi.exe
|
||||||
|
else
|
||||||
|
bun build --compile --target=bun-$platform ./dist/cli.js --outfile binaries/$platform/pi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "==> Creating release archives..."
|
||||||
|
|
||||||
|
# Copy shared files to each platform directory
|
||||||
|
for platform in "${PLATFORMS[@]}"; do
|
||||||
|
cp package.json binaries/$platform/
|
||||||
|
cp README.md binaries/$platform/
|
||||||
|
cp CHANGELOG.md binaries/$platform/
|
||||||
|
mkdir -p binaries/$platform/theme
|
||||||
|
cp dist/modes/interactive/theme/*.json binaries/$platform/theme/
|
||||||
|
cp -r examples binaries/$platform/
|
||||||
|
done
|
||||||
|
|
||||||
|
# Create archives
|
||||||
|
cd binaries
|
||||||
|
|
||||||
|
for platform in "${PLATFORMS[@]}"; do
|
||||||
|
if [[ "$platform" == "windows-x64" ]]; then
|
||||||
|
# Windows (zip)
|
||||||
|
echo "Creating pi-$platform.zip..."
|
||||||
|
(cd $platform && zip -r ../pi-$platform.zip .)
|
||||||
|
else
|
||||||
|
# Unix platforms (tar.gz) - use wrapper directory for mise compatibility
|
||||||
|
echo "Creating pi-$platform.tar.gz..."
|
||||||
|
mv $platform pi && tar -czf pi-$platform.tar.gz pi && mv pi $platform
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Extract archives for easy local testing
|
||||||
|
echo "==> Extracting archives for testing..."
|
||||||
|
for platform in "${PLATFORMS[@]}"; do
|
||||||
|
rm -rf $platform
|
||||||
|
if [[ "$platform" == "windows-x64" ]]; then
|
||||||
|
mkdir -p $platform && (cd $platform && unzip -q ../pi-$platform.zip)
|
||||||
|
else
|
||||||
|
tar -xzf pi-$platform.tar.gz && mv pi $platform
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "==> Build complete!"
|
||||||
|
echo "Archives available in packages/coding-agent/binaries/"
|
||||||
|
ls -lh *.tar.gz *.zip 2>/dev/null || true
|
||||||
|
echo ""
|
||||||
|
echo "Extracted directories for testing:"
|
||||||
|
for platform in "${PLATFORMS[@]}"; do
|
||||||
|
echo " binaries/$platform/pi"
|
||||||
|
done
|
||||||
Loading…
Add table
Add a link
Reference in a new issue