From bc3bb1adc92b3c29e539c5173dc346450361186c Mon Sep 17 00:00:00 2001 From: anandgupta42 Date: Wed, 18 Mar 2026 08:05:32 -0700 Subject: [PATCH 1/3] feat: add `script/local.sh` to build and run compiled binary locally MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Running the compiled binary locally was painful — required manually setting `NODE_PATH` and finding the right platform binary in `dist/`. Adds: - `script/local.sh` — builds single-platform binary and runs it with correct `NODE_PATH` for `@altimateai/altimate-core` resolution - `build:local` and `local` package.json scripts for convenience Usage: ./script/local.sh # build + run ./script/local.sh --skip-build # run without rebuilding ./script/local.sh -- --help # pass flags to altimate-code Closes #260 --- packages/opencode/package.json | 2 ++ packages/opencode/script/local.sh | 56 +++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100755 packages/opencode/script/local.sh diff --git a/packages/opencode/package.json b/packages/opencode/package.json index d8b0312950..69c91626ba 100644 --- a/packages/opencode/package.json +++ b/packages/opencode/package.json @@ -9,6 +9,8 @@ "typecheck": "tsgo --noEmit", "test": "bun test --timeout 30000", "build": "bun run script/build.ts", + "build:local": "bun run script/build.ts --single --skip-install", + "local": "./script/local.sh", "dev": "bun run --conditions=browser ./src/index.ts", "db": "bun drizzle-kit" }, diff --git a/packages/opencode/script/local.sh b/packages/opencode/script/local.sh new file mode 100755 index 0000000000..73b764445b --- /dev/null +++ b/packages/opencode/script/local.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash +# Build and run altimate-code locally from a compiled binary. +# +# Usage: +# ./script/local.sh # build + run +# ./script/local.sh --skip-build # run without rebuilding +# ./script/local.sh -- --help # pass flags to altimate-code +# +# The script: +# 1. Builds a single-platform binary (current OS/arch) via `bun run script/build.ts --single --skip-install` +# 2. Sets NODE_PATH so the compiled Bun binary can find @altimateai/altimate-core +# 3. Launches the binary with any trailing arguments + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +PKG_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" + +# Parse script flags (everything before --) +SKIP_BUILD=false +ARGS=() +while [[ $# -gt 0 ]]; do + case "$1" in + --skip-build) SKIP_BUILD=true; shift ;; + --) shift; ARGS=("$@"); break ;; + *) ARGS+=("$1"); shift ;; + esac +done + +# --- Build --- +if [ "$SKIP_BUILD" = false ]; then + echo "Building for current platform..." + # Run in subshell to avoid changing the working directory + (cd "$PKG_DIR" && bun run script/build.ts --single --skip-install) +fi + +# --- Resolve binary --- +OS="$(uname -s | tr '[:upper:]' '[:lower:]')" +ARCH="$(uname -m)" +case "$ARCH" in + aarch64|arm64) ARCH="arm64" ;; + x86_64) ARCH="x64" ;; +esac + +BINARY="$PKG_DIR/dist/@altimateai/altimate-code-${OS}-${ARCH}/bin/altimate" +if [ ! -f "$BINARY" ]; then + echo "error: binary not found at $BINARY" >&2 + echo "Available builds:" >&2 + ls "$PKG_DIR/dist/@altimateai/" 2>/dev/null || echo " (none)" >&2 + exit 1 +fi + +# --- Run --- +export NODE_PATH="$PKG_DIR/node_modules${NODE_PATH:+:$NODE_PATH}" +# Use ${ARGS[@]+"${ARGS[@]}"} to avoid "unbound variable" on bash 3.2 (macOS default) +exec "$BINARY" ${ARGS[@]+"${ARGS[@]}"} From 11936ec01bb8214ab00e465f2a4d86b1a04db2ea Mon Sep 17 00:00:00 2001 From: anandgupta42 Date: Wed, 18 Mar 2026 08:10:29 -0700 Subject: [PATCH 2/3] docs: update CONTRIBUTING.md with `script/local.sh` instructions Replace outdated "Building a localcode" section (referenced old `opencode` naming and manual binary path) with the new `local.sh` workflow including `--skip-build` and package.json script shortcuts. --- CONTRIBUTING.md | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 96b3dea840..f7b2fcdf23 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -53,21 +53,38 @@ To run Altimate Code in the root of the opencode repo itself: bun dev . ``` -### Building a "localcode" +### Building and running a local binary -To compile a standalone executable: +The easiest way to build and run a compiled binary locally: ```bash -./packages/opencode/script/build.ts --single +cd packages/opencode + +# Build for current platform + run +./script/local.sh + +# Run without rebuilding (fast iteration) +./script/local.sh --skip-build + +# Pass flags to altimate-code +./script/local.sh -- --help ``` -Then run it with: +Or use the package.json scripts: ```bash -./packages/opencode/dist/opencode-/bin/opencode +bun run build:local # just build for current platform +bun run local # build + run ``` -Replace `` with your platform (e.g., `darwin-arm64`, `linux-x64`). +The script handles platform detection, `NODE_PATH` setup for native modules +like `@altimateai/altimate-core`, and binary resolution automatically. + +To compile all platform targets (CI/release): + +```bash +bun run build +``` - Core pieces: - `packages/opencode`: Altimate Code core business logic & server. From e3db446bd049a46a3c3a47773c457a9da6d4785b Mon Sep 17 00:00:00 2001 From: anandgupta42 Date: Wed, 18 Mar 2026 08:23:04 -0700 Subject: [PATCH 3/3] fix: detect Rosetta 2 in `local.sh` to resolve correct binary arch Under Rosetta 2, `uname -m` reports `x86_64` but `bun` builds a native `arm64` binary. Check `sysctl.proc_translated` on macOS to override arch when running under translation. --- packages/opencode/script/local.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/opencode/script/local.sh b/packages/opencode/script/local.sh index 73b764445b..13810633fa 100755 --- a/packages/opencode/script/local.sh +++ b/packages/opencode/script/local.sh @@ -37,6 +37,15 @@ fi # --- Resolve binary --- OS="$(uname -s | tr '[:upper:]' '[:lower:]')" ARCH="$(uname -m)" + +# Detect Rosetta 2: if the shell runs under Rosetta on Apple Silicon, +# uname -m reports x86_64 but bun builds a native arm64 binary. +if [ "$OS" = "darwin" ] && [ "$ARCH" = "x86_64" ]; then + if sysctl -n sysctl.proc_translated 2>/dev/null | grep -q 1; then + ARCH="arm64" + fi +fi + case "$ARCH" in aarch64|arm64) ARCH="arm64" ;; x86_64) ARCH="x64" ;;