Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
5d92703
build: pin bun and add canonical lockfile
sethkarten Sep 1, 2026
1eb597f
build: make bun the primary development runtime
sethkarten Sep 1, 2026
ae5ed1e
fix: support Bun runtime process semantics
sethkarten Sep 1, 2026
7ae2493
test: run suites with Bun isolation
sethkarten Sep 1, 2026
624c83d
build: ship Bun binaries with verified sidecars
sethkarten Sep 1, 2026
d0e3c63
ci: run checks and releases with pinned Bun
sethkarten Sep 1, 2026
6edda2e
chore: finish Bun tooling migration
sethkarten Sep 1, 2026
4a65980
docs: make Bun the default workflow
sethkarten Sep 1, 2026
9791df5
docs: add Bun migration changelog fragments
sethkarten Sep 1, 2026
076cd4f
chore(ai): refresh generated model catalog
sethkarten Sep 1, 2026
b4613f0
fix(coding-agent): stabilize Python skill diagnostics
sethkarten Sep 1, 2026
b80a52b
fix: harden binary release and installer paths
sethkarten Sep 1, 2026
a688401
fix: drain daemon sockets before shutdown
sethkarten Sep 1, 2026
19a52a0
chore(ai): refresh generated model catalog
sethkarten Sep 1, 2026
424cb85
fix: normalize release paths and require HTTPS
sethkarten Sep 1, 2026
2399dfb
fix: keep npm release postinstall Node-compatible
sethkarten Sep 1, 2026
f670360
fix: trim release base URLs before packing
sethkarten Sep 1, 2026
06e57bc
feat!: make compiled Bun binaries the only install path
sethkarten Sep 1, 2026
7deaf89
fix: reject ambiguous release URLs
sethkarten Sep 1, 2026
c465c92
fix: verify activated binary install paths
sethkarten Sep 1, 2026
e53576d
fix: serialize binary installer activation
sethkarten Sep 1, 2026
1ced0af
fix: avoid same-version self-rollback
sethkarten Sep 1, 2026
4f366f9
fix: persist binary install paths
sethkarten Sep 1, 2026
faf7280
fix: canonicalize binary install roots
sethkarten Sep 1, 2026
69ccb0e
fix: harden installer lock ownership
sethkarten Sep 1, 2026
0bcc0c2
chore(ai): refresh generated model catalog
sethkarten Sep 2, 2026
3acc3ab
ci: make model catalog builds deterministic
sethkarten Sep 2, 2026
3272cec
fix: retain installer lock coordination root
sethkarten Sep 2, 2026
df849ab
feat: upgrade primary runtime to Bun 1.4.0
sethkarten Sep 2, 2026
cad37bc
perf: accelerate compiled Bun startup
sethkarten Sep 2, 2026
4d41a62
feat: add native Windows support
sethkarten Sep 2, 2026
2af76a9
ci: exercise the real Windows Python kernel
sethkarten Sep 2, 2026
9cfb56c
fix: validate Windows terminal and kernel cleanup
sethkarten Sep 2, 2026
3145d17
ci: focus Windows kernel validation
sethkarten Sep 2, 2026
02632fb
fix: support Windows kernel interrupts
sethkarten Sep 2, 2026
438dd80
ci: validate Windows Arm64 executable
sethkarten Sep 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .bun-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1.4.0
2 changes: 1 addition & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Dependency update PRs wait out the same 7-day cooldown that .npmrc's
# Dependency update PRs wait out the same 7-day cooldown that bunfig.toml's
# min-release-age enforces locally. Security-advisory PRs are exempt
# from cooldown by design, so CVE fixes still arrive promptly.
version: 2
Expand Down
176 changes: 147 additions & 29 deletions .github/workflows/build-binaries.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ on:
concurrency:
group: release-prime-agent
cancel-in-progress: false
queue: max

permissions:
contents: read
Expand All @@ -40,6 +39,14 @@ jobs:
fetch-tags: true
persist-credentials: false

- name: Setup Bun 1.4.0
uses: oven-sh/setup-bun@4bc047ad259df6fc24a6c9b0f9a0cb08cf17fbe5 # v2.0.1
with:
bun-version: 1.4.0

- name: Verify Bun 1.4.0
run: bun run check:bun-version

- name: Resolve release context
id: context
env:
Expand Down Expand Up @@ -72,15 +79,15 @@ jobs:
build_ref="$REF_NAME"
publish_production=true
else
production_version=$(node -p "require('./package.json').version")
production_version=$(bun -e "console.log(require('./package.json').version)")
build_ref="$GITHUB_SHA_VALUE"
beta_version="${production_version}-beta.${RUN_NUMBER}.${RUN_ATTEMPT}.${GITHUB_SHA_VALUE::7}"
publish_beta=true

previous_version=
if [ -n "$BEFORE_SHA" ] && ! printf '%s\n' "$BEFORE_SHA" | grep -Eq '^0+$' && git cat-file -e "${BEFORE_SHA}:package.json"; then
git show "${BEFORE_SHA}:package.json" > /tmp/previous-package.json
previous_version=$(node -p "require('/tmp/previous-package.json').version")
previous_version=$(bun -e "console.log(require('/tmp/previous-package.json').version)")
fi

if [ -z "$previous_version" ] || [ "$production_version" != "$previous_version" ]; then
Expand Down Expand Up @@ -133,28 +140,49 @@ jobs:
ref: ${{ env.BUILD_REF }}
persist-credentials: false

- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
- name: Setup Bun 1.4.0
uses: oven-sh/setup-bun@4bc047ad259df6fc24a6c9b0f9a0cb08cf17fbe5 # v2.0.1
with:
node-version: '22'
registry-url: 'https://registry.npmjs.org'
bun-version: 1.4.0

- name: Verify Bun 1.4.0
run: bun run check:bun-version

- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev

- name: Install dependencies
run: npm ci
- name: Install dependencies for all release platforms
run: bun install --frozen-lockfile --os=* --cpu=*

- name: Build
run: npm run build
run: bun run build

- name: Check
run: npm run check
run: bun run check

- name: Compile binaries for all platforms
working-directory: packages/coding-agent
run: |
mkdir -p binaries
for platform in darwin-arm64 darwin-x64 linux-arm64 linux-x64 windows-x64 windows-arm64; do
echo "Compiling for $platform..."
mkdir -p "binaries/$platform"
bun build --compile --minify --keep-names --bytecode --format=esm --external koffi --target="bun-$platform" ./dist/bun/cli.js --outfile "binaries/$platform/pi"
done

- name: Copy binary sidecar assets
working-directory: packages/coding-agent
run: bun run copy-binary-assets

- name: Pack production release
if: env.PUBLISH_PRODUCTION == 'true'
env:
PRIME_AGENT_DOWNLOAD_BASE_URL: ${{ vars.R2_PUBLIC_BASE_URL }}
run: |
test -n "$PRIME_AGENT_DOWNLOAD_BASE_URL"
npm run release:pack -- \
bun run release:pack -- \
--channel stable \
--version "$PRODUCTION_VERSION" \
--base-url "$PRIME_AGENT_DOWNLOAD_BASE_URL" \
Expand All @@ -166,12 +194,65 @@ jobs:
PRIME_AGENT_DOWNLOAD_BASE_URL: ${{ vars.R2_PUBLIC_BASE_URL }}
run: |
test -n "$PRIME_AGENT_DOWNLOAD_BASE_URL"
npm run release:pack -- \
bun run release:pack -- \
--channel beta \
--version "$BETA_VERSION" \
--base-url "$PRIME_AGENT_DOWNLOAD_BASE_URL" \
--out-dir packages/coding-agent/release/beta

- name: Smoke test host-platform archive
if: env.PUBLISH_PRODUCTION == 'true' || env.PUBLISH_BETA == 'true'
run: |
# Determine which archive to test (prefer production, fall back to beta)
ARTIFACTS_DIR=""
if [ "$PUBLISH_PRODUCTION" = "true" ]; then
ARTIFACTS_DIR="packages/coding-agent/release/production/artifacts"
else
ARTIFACTS_DIR="packages/coding-agent/release/beta/artifacts"
fi

# Detect host platform
OS=$(uname -s)
ARCH=$(uname -m)
case "$OS" in
Linux)
case "$ARCH" in
x86_64) PLATFORM="linux-x64" ;;
aarch64|arm64) PLATFORM="linux-arm64" ;;
*) echo "Unknown host arch: $ARCH"; exit 1 ;;
esac
;;
Darwin)
case "$ARCH" in
x86_64) PLATFORM="darwin-x64" ;;
arm64) PLATFORM="darwin-arm64" ;;
*) echo "Unknown host arch: $ARCH"; exit 1 ;;
esac
;;
*)
echo "Unknown host OS: $OS"; exit 1 ;;
esac

# Extract host-platform archive and run --version
ARCHIVE=$(ls "$ARTIFACTS_DIR"/*-"${PLATFORM}.tar.gz" 2>/dev/null | head -1)
if [ -z "$ARCHIVE" ]; then
echo "No archive for host platform ${PLATFORM} in ${ARTIFACTS_DIR}"
exit 1
fi

SMOKE_DIR=$(mktemp -d)
tar -xzf "$ARCHIVE" -C "$SMOKE_DIR"
chmod +x "$SMOKE_DIR/prime-agent"
if "$SMOKE_DIR/prime-agent" --version >/dev/null 2>&1; then
echo "Smoke test passed: $("$SMOKE_DIR/prime-agent" --version 2>&1)"
else
echo "Smoke test FAILED."
"$SMOKE_DIR/prime-agent" --version 2>&1 || true
rm -rf "$SMOKE_DIR"
exit 1
fi
rm -rf "$SMOKE_DIR"

- name: Upload production artifacts
if: env.PUBLISH_PRODUCTION == 'true'
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
Expand Down Expand Up @@ -212,6 +293,14 @@ jobs:
ref: ${{ env.BUILD_REF }}
persist-credentials: false

- name: Setup Bun 1.4.0
uses: oven-sh/setup-bun@4bc047ad259df6fc24a6c9b0f9a0cb08cf17fbe5 # v2.0.1
with:
bun-version: 1.4.0

- name: Verify Bun 1.4.0
run: bun run check:bun-version

- name: Download production artifacts
if: env.PUBLISH_PRODUCTION == 'true'
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
Expand All @@ -232,17 +321,20 @@ jobs:
export INSTALL_BASE_URL
test -n "$INSTALL_BASE_URL"

node - <<'NODE'
bun -e '
const fs = require("node:fs");
const baseUrl = process.env.INSTALL_BASE_URL;
if (!baseUrl) throw new Error("INSTALL_BASE_URL is required");
const installer = fs.readFileSync("install.sh", "utf8");
const renderInstaller = (channel) => installer
const renderInstaller = (source, channel) => source
.replaceAll("__PRIME_AGENT_DOWNLOAD_BASE_URL__", baseUrl)
.replaceAll("__PRIME_AGENT_DEFAULT_RELEASE_CHANNEL__", channel);
fs.writeFileSync("/tmp/prime-agent-install.sh", renderInstaller("stable"));
fs.writeFileSync("/tmp/prime-agent-install-beta.sh", renderInstaller("beta"));
NODE
const shellInstaller = fs.readFileSync("install.sh", "utf8");
const powershellInstaller = fs.readFileSync("install.ps1", "utf8");
fs.writeFileSync("/tmp/prime-agent-install.sh", renderInstaller(shellInstaller, "stable"));
fs.writeFileSync("/tmp/prime-agent-install-beta.sh", renderInstaller(shellInstaller, "beta"));
fs.writeFileSync("/tmp/prime-agent-install.ps1", renderInstaller(powershellInstaller, "stable"));
fs.writeFileSync("/tmp/prime-agent-install-beta.ps1", renderInstaller(powershellInstaller, "beta"));
'

- name: Extract production release notes
if: env.PUBLISH_PRODUCTION == 'true'
Expand All @@ -257,22 +349,24 @@ jobs:
run: |
PRODUCTION_DIR=release-artifacts/production
RELEASE_PREFIX="releases/v${PRODUCTION_VERSION}"
TARBALL="$PRODUCTION_DIR/prime-agent-${PRODUCTION_VERSION}.tgz"

test -f "$TARBALL"
test -f "$PRODUCTION_DIR/SHA256SUMS"
test -f "$PRODUCTION_DIR/stable"
test -f "$PRODUCTION_DIR/latest.json"
test -n "$R2_BUCKET"
test -n "$R2_ENDPOINT_URL"

for artifact in "$PRODUCTION_DIR"/*.tgz; do
for artifact in "$PRODUCTION_DIR"/*.tar.gz "$PRODUCTION_DIR"/*.zip; do
test -f "$artifact" || continue
content_type="application/gzip"
case "$artifact" in
*.zip) content_type="application/zip" ;;
esac
aws s3 cp "$artifact" "s3://${R2_BUCKET}/${RELEASE_PREFIX}/$(basename "$artifact")" \
--endpoint-url "$R2_ENDPOINT_URL" \
--content-type application/gzip \
--content-type "$content_type" \
--cache-control 'public, max-age=31536000, immutable'
done

aws s3 cp "$PRODUCTION_DIR/SHA256SUMS" "s3://${R2_BUCKET}/${RELEASE_PREFIX}/SHA256SUMS" \
--endpoint-url "$R2_ENDPOINT_URL" \
--content-type text/plain \
Expand All @@ -298,6 +392,16 @@ jobs:
--content-type text/x-shellscript \
--cache-control no-cache

aws s3 cp /tmp/prime-agent-install.ps1 "s3://${R2_BUCKET}/install.ps1" \
--endpoint-url "$R2_ENDPOINT_URL" \
--content-type text/x-powershell \
--cache-control no-cache

aws s3 cp /tmp/prime-agent-install-beta.ps1 "s3://${R2_BUCKET}/install-beta.ps1" \
--endpoint-url "$R2_ENDPOINT_URL" \
--content-type text/x-powershell \
--cache-control no-cache

- name: Create production GitHub release
if: env.PUBLISH_PRODUCTION == 'true'
env:
Expand Down Expand Up @@ -325,22 +429,24 @@ jobs:
run: |
BETA_DIR=release-artifacts/beta
RELEASE_PREFIX="releases/v${BETA_VERSION}"
TARBALL="$BETA_DIR/prime-agent-${BETA_VERSION}.tgz"

test -f "$TARBALL"
test -f "$BETA_DIR/SHA256SUMS"
test -f "$BETA_DIR/beta"
test -f "$BETA_DIR/beta.json"
test -n "$R2_BUCKET"
test -n "$R2_ENDPOINT_URL"

for artifact in "$BETA_DIR"/*.tgz; do
for artifact in "$BETA_DIR"/*.tar.gz "$BETA_DIR"/*.zip; do
test -f "$artifact" || continue
content_type="application/gzip"
case "$artifact" in
*.zip) content_type="application/zip" ;;
esac
aws s3 cp "$artifact" "s3://${R2_BUCKET}/${RELEASE_PREFIX}/$(basename "$artifact")" \
--endpoint-url "$R2_ENDPOINT_URL" \
--content-type application/gzip \
--content-type "$content_type" \
--cache-control 'public, max-age=31536000, immutable'
done

aws s3 cp "$BETA_DIR/SHA256SUMS" "s3://${R2_BUCKET}/${RELEASE_PREFIX}/SHA256SUMS" \
--endpoint-url "$R2_ENDPOINT_URL" \
--content-type text/plain \
Expand All @@ -359,6 +465,7 @@ jobs:
fi

BETA_DIR=release-artifacts/beta

aws s3 cp "$BETA_DIR/beta.json" "s3://${R2_BUCKET}/beta.json" \
--endpoint-url "$R2_ENDPOINT_URL" \
--content-type application/json \
Expand All @@ -379,6 +486,16 @@ jobs:
--content-type text/x-shellscript \
--cache-control no-cache

aws s3 cp /tmp/prime-agent-install.ps1 "s3://${R2_BUCKET}/install.ps1" \
--endpoint-url "$R2_ENDPOINT_URL" \
--content-type text/x-powershell \
--cache-control no-cache

aws s3 cp /tmp/prime-agent-install-beta.ps1 "s3://${R2_BUCKET}/install-beta.ps1" \
--endpoint-url "$R2_ENDPOINT_URL" \
--content-type text/x-powershell \
--cache-control no-cache

printf 'Automated beta build from `%s` (`%s`).\n' "$DEFAULT_BRANCH" "$BUILD_REF" > /tmp/beta-release-notes.md

if gh api "repos/${GITHUB_REPOSITORY}/git/ref/tags/beta" >/dev/null 2>&1; then
Expand Down Expand Up @@ -410,3 +527,4 @@ jobs:

gh release upload beta "$BETA_DIR"/* --clobber
echo "Beta installer: ${R2_PUBLIC_BASE_URL%/}/install-beta.sh"
echo "Windows beta installer: ${R2_PUBLIC_BASE_URL%/}/install-beta.ps1"
Loading
Loading