mirror of
https://github.com/earendil-works/pi.git
synced 2026-10-22 06:19:16 +08:00
This adds codemode and MCP support to pi. Codemode (packages/codemode) runs model-written JavaScript in a QuickJS wasm VM inside a worker. From there the script calls pi's tools as async functions, uses a per-session store, and can read the model catalog and run classifiers. The codemode tool in coding-agent is compatible with Codex's exec tool, and codemode.mode works like Codex's tool modes (on or only). Large results are written to a JSON temp file. MCP (packages/mcp) is a standalone client for stdio and streamable HTTP servers, with OAuth. The core only gets general mechanisms; codemode, tool_search and MCP are built-in extensions that use them. Other extensions can replace these built-ins. Tools declare an exposure: direct, model-only, codemode, deferred or hidden. prepareLoadout() lets an orchestrating tool change which tool declarations the model sees. ctx.executeTool() runs nested calls through validation and the tool_call/tool_result hooks. Those calls emit events with parentToolCallId and are recorded as bounded nestedCalls on the parent result, which compaction and HTML export use. Tools can also return structuredContent with an outputSchema, and can report errors with isError instead of throwing. MCP servers come from mcp.json (global, or per project after the project is trusted) or from pi.registerMcpServer(). They are managed with /mcp and pi mcp list|login|logout, and their runtimes load on first use. Closes #10040
200 lines
6.2 KiB
Bash
Executable File
200 lines
6.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# Build pi binaries for all platforms locally.
|
|
# Mirrors .github/workflows/build-binaries.yml
|
|
#
|
|
# Usage:
|
|
# ./scripts/build-binaries.sh [--skip-install] [--skip-build] [--offline-model-data] [--platform <platform>] [--out <dir>]
|
|
#
|
|
# Options:
|
|
# --skip-install Skip npm ci
|
|
# --skip-build Skip the package build
|
|
# --offline-model-data Build with bundled model data instead of refreshing it
|
|
# --platform <name> Build only for specified platform (darwin-arm64, darwin-x64, linux-x64, linux-arm64, windows-x64, windows-arm64)
|
|
# --out <dir> Output directory (default: packages/coding-agent/binaries)
|
|
#
|
|
# 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
|
|
# pi-windows-arm64.zip
|
|
|
|
set -euo pipefail
|
|
|
|
cd "$(dirname "$0")/.."
|
|
|
|
SKIP_INSTALL=false
|
|
SKIP_BUILD=false
|
|
OFFLINE_MODEL_DATA=false
|
|
PLATFORM=""
|
|
OUTPUT_DIR=""
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case $1 in
|
|
--skip-install)
|
|
SKIP_INSTALL=true
|
|
shift
|
|
;;
|
|
--skip-build)
|
|
SKIP_BUILD=true
|
|
shift
|
|
;;
|
|
--offline-model-data)
|
|
OFFLINE_MODEL_DATA=true
|
|
shift
|
|
;;
|
|
--platform)
|
|
PLATFORM="$2"
|
|
shift 2
|
|
;;
|
|
--out)
|
|
OUTPUT_DIR="$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|windows-arm64)
|
|
;;
|
|
*)
|
|
echo "Invalid platform: $PLATFORM"
|
|
echo "Valid platforms: darwin-arm64, darwin-x64, linux-x64, linux-arm64, windows-x64, windows-arm64"
|
|
exit 1
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
if [[ -z "$OUTPUT_DIR" ]]; then
|
|
OUTPUT_DIR="packages/coding-agent/binaries"
|
|
fi
|
|
if [[ "$OUTPUT_DIR" != /* ]]; then
|
|
OUTPUT_DIR="$(pwd)/$OUTPUT_DIR"
|
|
fi
|
|
|
|
if [[ "$SKIP_INSTALL" == "false" ]]; then
|
|
echo "==> Installing dependencies..."
|
|
npm ci --ignore-scripts
|
|
else
|
|
echo "==> Skipping npm ci (--skip-install)"
|
|
fi
|
|
|
|
if [[ "$SKIP_BUILD" == "false" ]]; then
|
|
if [[ "$OFFLINE_MODEL_DATA" == "true" ]]; then
|
|
echo "==> Building all packages with bundled model data..."
|
|
npm run build:offline
|
|
else
|
|
echo "==> Building all packages..."
|
|
npm run build
|
|
fi
|
|
else
|
|
echo "==> Skipping package build (--skip-build)"
|
|
fi
|
|
|
|
echo "==> Building binaries..."
|
|
cd packages/coding-agent
|
|
|
|
# Clean previous builds
|
|
rm -rf "$OUTPUT_DIR"
|
|
mkdir -p "$OUTPUT_DIR"/{darwin-arm64,darwin-x64,linux-x64,linux-arm64,windows-x64,windows-arm64}
|
|
|
|
# Determine which platforms to build
|
|
if [[ -n "$PLATFORM" ]]; then
|
|
PLATFORMS=("$PLATFORM")
|
|
else
|
|
PLATFORMS=(darwin-arm64 darwin-x64 linux-x64 linux-arm64 windows-x64 windows-arm64)
|
|
fi
|
|
|
|
for platform in "${PLATFORMS[@]}"; do
|
|
echo "Building for $platform..."
|
|
bun_target="bun-$platform"
|
|
if [[ "$platform" == *-x64 ]]; then
|
|
bun_target="${bun_target}-baseline"
|
|
fi
|
|
|
|
# Bun compiled executables only embed worker scripts when they are passed as
|
|
# explicit build entrypoints. Bun places them at their path relative to the
|
|
# common directory of all entrypoints, so the main entry must stay in dist/
|
|
# for the worker URLs in src/config.ts to resolve.
|
|
#
|
|
# Disable cwd bunfig.toml autoload so project preload scripts cannot crash the
|
|
# standalone binary before pi starts (see #7684).
|
|
if [[ "$platform" == windows-* ]]; then
|
|
bun build --compile --no-compile-autoload-bunfig --target="$bun_target" ./dist/bun/cli.js ./src/utils/image-resize-worker.ts ./src/extensions/codemode/worker.ts --outfile "$OUTPUT_DIR/$platform/pi.exe"
|
|
else
|
|
bun build --compile --no-compile-autoload-bunfig --target="$bun_target" ./dist/bun/cli.js ./src/utils/image-resize-worker.ts ./src/extensions/codemode/worker.ts --outfile "$OUTPUT_DIR/$platform/pi"
|
|
fi
|
|
done
|
|
|
|
echo "==> Creating release archives..."
|
|
|
|
# Copy shared files to each platform directory
|
|
for platform in "${PLATFORMS[@]}"; do
|
|
cp package.json "$OUTPUT_DIR/$platform/"
|
|
cp README.md "$OUTPUT_DIR/$platform/"
|
|
cp CHANGELOG.md "$OUTPUT_DIR/$platform/"
|
|
cp ../../node_modules/@silvia-odwyer/photon-node/photon_rs_bg.wasm "$OUTPUT_DIR/$platform/"
|
|
mkdir -p "$OUTPUT_DIR/$platform/theme"
|
|
cp dist/modes/interactive/theme/*.json "$OUTPUT_DIR/$platform/theme/"
|
|
mkdir -p "$OUTPUT_DIR/$platform/assets"
|
|
cp dist/modes/interactive/assets/* "$OUTPUT_DIR/$platform/assets/"
|
|
cp -r dist/core/export-html "$OUTPUT_DIR/$platform/"
|
|
cp -r docs "$OUTPUT_DIR/$platform/"
|
|
cp -r examples "$OUTPUT_DIR/$platform/"
|
|
|
|
# Copy the selected architecture's native platform helpers next to the executable.
|
|
native_platform="${platform/windows-/win32-}"
|
|
native_path="native/${native_platform%-*}/prebuilds"
|
|
mkdir -p "$OUTPUT_DIR/$platform/$native_path"
|
|
cp -R "../tui/$native_path/$native_platform" "$OUTPUT_DIR/$platform/$native_path/"
|
|
done
|
|
|
|
# Create archives
|
|
cd "$OUTPUT_DIR"
|
|
|
|
for platform in "${PLATFORMS[@]}"; do
|
|
if [[ "$platform" == windows-* ]]; 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-* ]]; 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 $OUTPUT_DIR/"
|
|
ls -lh *.tar.gz *.zip 2>/dev/null || true
|
|
echo ""
|
|
echo "Extracted directories for testing:"
|
|
for platform in "${PLATFORMS[@]}"; do
|
|
if [[ "$platform" == windows-* ]]; then
|
|
echo " $OUTPUT_DIR/$platform/pi.exe"
|
|
else
|
|
echo " $OUTPUT_DIR/$platform/pi"
|
|
fi
|
|
done
|