Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
59 changes: 59 additions & 0 deletions .github/actions/build-sea/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: Build SEA
description: Build and verify a Node.js single executable application

inputs:
executable:
description: Executable filename written to the release directory
required: true

runs:
using: composite
steps:
- name: Use Node.js
uses: actions/setup-node@v6
with:
cache: npm
node-version: 25.9.0

- name: Install dependencies
shell: bash
run: npm ci --prefer-offline

- name: Build SEA bundle
shell: bash
run: npm run build -- --config vite.sea.config.mts

- name: Create release directory
shell: bash
run: mkdir -p release

- name: Build executable
if: runner.os != 'Windows'
shell: bash
run: node --build-sea sea-config.json

- name: Build executable on Windows
if: runner.os == 'Windows'
shell: pwsh
run: |
$config = Get-Content sea-config.json | ConvertFrom-Json
$config.output = "release/${{ inputs.executable }}"
$config | ConvertTo-Json | Set-Content sea-config.windows.json
node --build-sea sea-config.windows.json

- name: Sign executable on macOS
if: runner.os == 'macOS'
shell: bash
run: codesign --sign - --force "release/${{ inputs.executable }}"

- name: Verify executable
shell: bash
run: |
actual=$(release/${{ inputs.executable }} --version)
expected=$(node -p "require('./package.json').version")
actual_version=${actual%% *}
actual_version=${actual_version#code-ollama/}

printf '%s\n' "$actual"
test "$actual_version" = "$expected"
release/${{ inputs.executable }} --help
15 changes: 13 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ name: build
on: [push, pull_request]

permissions:
contents: write
contents: read

jobs:
build:
build-package:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
Expand All @@ -22,3 +22,14 @@ jobs:

- name: Build package
run: npm run build

build-sea:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v7

- name: Build SEA
uses: ./.github/actions/build-sea
with:
executable: code-ollama
59 changes: 59 additions & 0 deletions .github/workflows/release-please.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ jobs:
runs-on: ubuntu-latest
outputs:
release_created: ${{ steps.release.outputs.release_created }}
tag_name: ${{ steps.release.outputs.tag_name }}
permissions:
contents: write
pull-requests: write
Expand Down Expand Up @@ -43,3 +44,61 @@ jobs:

- name: Publish
run: npm publish --provenance --access public

build:
runs-on: ${{ matrix.os }}
needs: release
if: ${{ needs.release.outputs.release_created }}
permissions:
contents: write
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
target: linux-x64
executable: code-ollama
- os: ubuntu-24.04-arm
target: linux-arm64
executable: code-ollama
- os: macos-15-intel
target: darwin-x64
executable: code-ollama
- os: macos-latest
target: darwin-arm64
executable: code-ollama
- os: windows-latest
target: windows-x64
executable: code-ollama.exe

steps:
- name: Checkout repository
uses: actions/checkout@v7

- name: Build SEA
uses: ./.github/actions/build-sea
with:
executable: ${{ matrix.executable }}

- name: Archive and upload executable
if: runner.os != 'Windows'
run: |
archive="release/code-ollama-${TAG_NAME}-${TARGET}.tar.gz"
tar -czf "$archive" -C release "${{ matrix.executable }}"
gh release upload "$TAG_NAME" "$archive" --clobber
env:
GH_TOKEN: ${{ github.token }}
TAG_NAME: ${{ needs.release.outputs.tag_name }}
TARGET: ${{ matrix.target }}

- name: Archive and upload executable on Windows
if: runner.os == 'Windows'
shell: pwsh
run: |
$archive = "release/code-ollama-$env:TAG_NAME-$env:TARGET.zip"
Compress-Archive -Path "release/${{ matrix.executable }}" -DestinationPath $archive
gh release upload $env:TAG_NAME $archive --clobber
env:
GH_TOKEN: ${{ github.token }}
TAG_NAME: ${{ needs.release.outputs.tag_name }}
TARGET: ${{ matrix.target }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ jspm_packages
# Build files
dist/
docs/
release/

# Vim swap files
*.swp
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ Install the [CLI](https://www.npmjs.com/package/code-ollama) globally:
npm install --global code-ollama
```

## Download

Standalone executables for Linux, macOS, and Windows are also available from [GitHub Releases](https://github.com/ai-action/code-ollama/releases). Extract the archive for your operating system and architecture, then run `code-ollama` (or `code-ollama.exe` on Windows).

> [!WARNING]
> OAuth authentication for MCP servers is not supported in standalone executables. Install the npm package when OAuth-backed MCP servers are required.

## Usage

### TUI
Expand Down
6 changes: 6 additions & 0 deletions sea-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"main": "dist/sea/cli.js",
"mainFormat": "module",
"output": "release/code-ollama",
"disableExperimentalSEAWarning": true
}
20 changes: 11 additions & 9 deletions vite.config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,19 @@ import { resolve } from 'node:path';

import { defineConfig } from 'vitest/config';

export const alias = {
'@': resolve(__dirname, 'src'),
'@modelcontextprotocol/sdk/client/auth':
'@modelcontextprotocol/sdk/client/auth.js',
'@modelcontextprotocol/sdk/client/stdio':
'@modelcontextprotocol/sdk/client/stdio.js',
'@modelcontextprotocol/sdk/client/streamableHttp':
'@modelcontextprotocol/sdk/client/streamableHttp.js',
};

export default defineConfig({
resolve: {
alias: {
'@': resolve(__dirname, 'src'),
'@modelcontextprotocol/sdk/client/auth':
'@modelcontextprotocol/sdk/client/auth.js',
'@modelcontextprotocol/sdk/client/stdio':
'@modelcontextprotocol/sdk/client/stdio.js',
'@modelcontextprotocol/sdk/client/streamableHttp':
'@modelcontextprotocol/sdk/client/streamableHttp.js',
},
alias,
},

build: {
Expand Down
28 changes: 28 additions & 0 deletions vite.sea.config.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { defineConfig } from 'vite';

import { alias } from './vite.config.mts';

export default defineConfig({
resolve: {
alias,
},

ssr: {
noExternal: true,
},

build: {
emptyOutDir: true,
outDir: 'dist/sea',
ssr: 'src/cli.ts',
target: 'node25',
rolldownOptions: {
external: ['@napi-rs/keyring'],
output: {
codeSplitting: false,
entryFileNames: 'cli.js',
format: 'esm',
},
},
},
});