Skip to content
Closed
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
5ef1dd8
feat(plugin-bootstrap): comprehensive optimization and robustness imp…
odilitime Feb 8, 2026
cef942e
fix(plugin-bootstrap): restore type safety and add parallel optimizat…
odilitime Feb 8, 2026
c57d767
docs(plugin-bootstrap): add WHY comments and update README
odilitime Feb 8, 2026
9edd424
fix(plugin-bootstrap): prevent cache memory leaks and log timeouts
odilitime Feb 8, 2026
ff8af7b
fix(cli): resolve CLI test failures and hanging tests
odilitime Feb 9, 2026
95135e0
refactor(core,plugin-bootstrap): extract entity processing to core an…
odilitime Feb 9, 2026
ea933a1
fix(core,plugin-bootstrap): improve type safety and remove code smells
odilitime Feb 9, 2026
02d65fc
fix(cli): resolve remaining CI test failures
odilitime Feb 9, 2026
c951512
fix(cli): ensure .gitignore exists after project creation
odilitime Feb 9, 2026
e538840
fix(cli): use synchronous fs ops for .gitignore creation in CI
odilitime Feb 9, 2026
f7f4a51
fix(cli): remove unused readdirSync import in copy-template
odilitime Feb 9, 2026
0d25515
fix(ci): resolve CLI, Cypress, and PGLite CI test failures
odilitime Feb 9, 2026
c0ac547
fix(ci): comprehensive CI diagnostics and fixes for all failing workf…
odilitime Feb 9, 2026
18cc024
docs(cli): document .gitignore/.npmignore pipeline to prevent regress…
odilitime Feb 9, 2026
d1cca19
fix(ci): file-based diagnostics for .gitignore, disable Vite HMR for …
odilitime Feb 9, 2026
60d4a2a
fix(ci): use elizaos create for CLI availability check on macOS
odilitime Feb 9, 2026
07d2803
fix: add full CLI subprocess diagnostics and ensure bin symlink in CI
odilitime Feb 9, 2026
36a650b
fix: update health check to test actual update import path on macOS
odilitime Feb 9, 2026
c73634a
fix: skip update tests on macOS CI due to bcrypt native module mismatch
odilitime Feb 9, 2026
7750573
fix(ci): add develop branch to CI workflow and fix core-package-tests…
odilitime Feb 9, 2026
f75496e
fix(ci): add build step to CI test job and fix formatting across pack…
odilitime Feb 9, 2026
c0f75f5
fix(plugin-sql): add PGLite WASM readiness check to reduce CI flakiness
odilitime Feb 9, 2026
734cbdc
fix: re-format client and cli files with lockfile prettier version
odilitime Feb 10, 2026
cac5666
fix: format cli plugin-env-filter.ts with root prettier
odilitime Feb 10, 2026
884c2af
fix: resolve eslint/prettier conflict in test-utils testDatabase.ts
odilitime Feb 10, 2026
b395c41
fix: resolve eslint/prettier conflicts and fix pre-existing lint errors
odilitime Feb 10, 2026
fafd26f
fix: resolve pre-existing eslint errors in client and api-client pack…
odilitime Feb 10, 2026
532d87a
fix: revert nullish checks to == null and fix plugin-sql build.ts lint
odilitime Feb 10, 2026
54dab91
fix(ci): add retry logic for Bun runtime crashes in test runners
odilitime Feb 10, 2026
0bacd4a
fix(client): make Cypress E2E tests resilient against slow React hydr…
odilitime Feb 10, 2026
fbfdb60
fix(client): move custom Cypress commands to e2e.ts support file
odilitime Feb 10, 2026
bafd429
fix(plugin-bootstrap): enforce hard cache size limits and fix any type
odilitime Feb 10, 2026
e1b6842
fix(plugin-bootstrap): remove unnecessary Record<string, any> cast
odilitime Feb 10, 2026
922b310
fix(cli): clear timeout timers in Promise.race scenario execution
odilitime Feb 10, 2026
d38da78
fix(cli): remove diagnostic JSON file from generated project directories
odilitime Feb 10, 2026
de9af58
fix(cli): make LLM judge evaluator use candidateModels instead of har…
odilitime Feb 10, 2026
dcb70ba
Document teardown requirement
odilitime Feb 10, 2026
54688f5
style(plugin-bootstrap): fix trailing whitespace in JSDoc comment
odilitime Feb 10, 2026
3267e5b
fix(client): stabilize Cypress component tests against Vite dev-serve…
odilitime Feb 10, 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
19 changes: 11 additions & 8 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ concurrency:

on:
push:
branches: [main]
branches: [main, develop]
pull_request:
branches: [main]
branches: [main, develop]
jobs:
# Test job
test:
# Skip duplicate runs: run on push to main, or on pull_request events only
if: github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref_name == 'main')
# Skip duplicate runs: run on push to main/develop, or on pull_request events only
if: github.event_name == 'pull_request' || (github.event_name == 'push' && contains(fromJson('["main", "develop"]'), github.ref_name))
runs-on: ubuntu-latest
timeout-minutes: 20
env:
Expand All @@ -33,6 +33,9 @@ jobs:
- name: Install dependencies
run: bun install

- name: Build packages
run: bun run build

- name: Create test env file
run: |
echo "TEST_DATABASE_CLIENT=pglite" > packages/core/.env.test
Expand All @@ -46,8 +49,8 @@ jobs:

# Lint and format job
lint-and-format:
# Skip duplicate runs: run on push to main, or on pull_request events only
if: github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref_name == 'main')
# Skip duplicate runs: run on push to main/develop, or on pull_request events only
if: github.event_name == 'pull_request' || (github.event_name == 'push' && contains(fromJson('["main", "develop"]'), github.ref_name))
runs-on: ubuntu-latest
timeout-minutes: 5
env:
Expand All @@ -72,8 +75,8 @@ jobs:

# Build job
build:
# Skip duplicate runs: run on push to main, or on pull_request events only
if: github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref_name == 'main')
# Skip duplicate runs: run on push to main/develop, or on pull_request events only
if: github.event_name == 'pull_request' || (github.event_name == 'push' && contains(fromJson('["main", "develop"]'), github.ref_name))
runs-on: ubuntu-latest
timeout-minutes: 8
env:
Expand Down
8 changes: 5 additions & 3 deletions .github/workflows/claude-security-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ concurrency:

jobs:
security:
# Skip for draft PRs, [skip-security] in title, or bot-triggered
# Skip for draft PRs or [skip-security] in title.
# NOTE: We intentionally do NOT exclude cursor[bot] or other bot actors.
# Development is done via Cursor, so bot-triggered pushes are normal
# workflow and still need security review.
if: |
github.event.pull_request.draft != true &&
!contains(github.event.pull_request.title, '[skip-security]') &&
github.actor != 'cursor[bot]'
!contains(github.event.pull_request.title, '[skip-security]')

runs-on: ubuntu-latest
permissions:
Expand Down
81 changes: 66 additions & 15 deletions .github/workflows/cli-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ jobs:
- name: Build all packages
run: bun run build

- name: Install cross-env globally (before linking, to avoid overwriting symlinks)
run: bun install -g cross-env

- name: Install BATS on macOS
if: matrix.os == 'macos-latest'
run: bun install -g bats

- name: Link packages globally
run: |
# Link core package first (everything depends on it)
Expand Down Expand Up @@ -101,18 +108,69 @@ jobs:
which elizaos || echo "elizaos not found in PATH"
elizaos --version || echo "Failed to run elizaos --version"

- name: Verify CLI build artifacts
- name: Ensure node_modules/.bin/elizaos symlink exists
shell: bash
run: |
# bun install can't create bin symlinks for workspace packages when
# dist/ doesn't exist yet. After building, we need to ensure the
# symlink exists so tests use the LOCAL binary rather than the global
# one from bun link (which may resolve __dirname differently).
if [ ! -f node_modules/.bin/elizaos ]; then
echo "Creating node_modules/.bin/elizaos symlink..."
mkdir -p node_modules/.bin
if [ "$RUNNER_OS" = "Windows" ]; then
# On Windows, create a cmd wrapper
echo '#!/usr/bin/env bun' > node_modules/.bin/elizaos
echo '"$(dirname "$0")/../../packages/cli/dist/index.js" "$@"' >> node_modules/.bin/elizaos
else
ln -sf ../../packages/cli/dist/index.js node_modules/.bin/elizaos
fi
chmod +x node_modules/.bin/elizaos 2>/dev/null || true
echo "✓ Created symlink"
else
echo "✓ Symlink already exists"
fi
ls -la node_modules/.bin/elizaos 2>/dev/null || true
readlink -f node_modules/.bin/elizaos 2>/dev/null || true

- name: Verify CLI build artifacts and templates
shell: bash
run: |
echo "Checking CLI build artifacts..."
echo "CLI dist contents:"
ls -la packages/cli/dist/ || echo "ERROR: No dist directory"
echo "=== CLI BUILD ARTIFACTS ==="
test -f packages/cli/dist/index.js && echo "✓ CLI index.js exists" || echo "ERROR: CLI index.js missing"
echo ""
echo "CLI templates in dist:"
ls -la packages/cli/dist/templates/ || echo "ERROR: No templates in dist"

echo "=== TEMPLATE SOURCE (packages/project-starter/) ==="
ls -la packages/project-starter/.gitignore 2>/dev/null && echo "✓ SOURCE .gitignore exists" || echo "✗ SOURCE .gitignore MISSING"
ls -la packages/project-starter/.npmignore 2>/dev/null && echo "✓ SOURCE .npmignore exists" || echo "✗ SOURCE .npmignore MISSING"
echo ""

echo "=== BUILD-COPIED TEMPLATE (packages/cli/templates/project-starter/) ==="
ls -la packages/cli/templates/project-starter/.gitignore 2>/dev/null && echo "✓ BUILD-COPY .gitignore exists" || echo "✗ BUILD-COPY .gitignore MISSING"
ls -la packages/cli/templates/project-starter/.npmignore 2>/dev/null && echo "✓ BUILD-COPY .npmignore exists" || echo "✗ BUILD-COPY .npmignore MISSING"
echo ""
echo "CLI executable:"
test -f packages/cli/dist/index.js && echo "✓ CLI index.js exists" || echo "ERROR: CLI index.js missing"

echo "=== DIST TEMPLATE (packages/cli/dist/templates/project-starter/) ==="
ls -la packages/cli/dist/templates/project-starter/.gitignore 2>/dev/null && echo "✓ DIST .gitignore exists" || echo "✗ DIST .gitignore MISSING"
ls -la packages/cli/dist/templates/project-starter/.npmignore 2>/dev/null && echo "✓ DIST .npmignore exists" || echo "✗ DIST .npmignore MISSING"
echo ""

echo "=== MONOREPO BIN SYMLINK ==="
ls -la node_modules/.bin/elizaos 2>/dev/null && echo "✓ node_modules/.bin/elizaos exists" || echo "⚠ node_modules/.bin/elizaos missing"
readlink -f node_modules/.bin/elizaos 2>/dev/null || true
echo ""

echo "=== GLOBAL BIN ==="
which elizaos 2>/dev/null && echo "✓ global elizaos: $(which elizaos)" || echo "⚠ no global elizaos"
readlink -f "$(which elizaos 2>/dev/null)" 2>/dev/null || true
echo ""

echo "=== BINARY VERIFICATION (grep for copy-template-diag marker) ==="
strings packages/cli/dist/index.js 2>/dev/null | grep -c "copy-template-diag" || echo "0 diag markers found in binary"
echo ""

echo "=== BINARY VERIFICATION (grep for COPY-TPL stderr marker) ==="
strings packages/cli/dist/index.js 2>/dev/null | grep -c "COPY-TPL" || echo "0 COPY-TPL markers found in binary"

- name: Clean eliza projects cache
shell: bash
Expand All @@ -124,13 +182,6 @@ jobs:
echo "OPENAI_API_KEY=$OPENAI_API_KEY" > .env
echo "LOG_LEVEL=info" >> .env

- name: Install cross-env globally
run: bun install -g cross-env

- name: Install BATS on macOS
if: matrix.os == 'macos-latest'
run: bun install -g bats

- name: Run CLI TypeScript tests
run: cross-env bun test tests/commands/
working-directory: packages/cli
Expand Down
47 changes: 40 additions & 7 deletions .github/workflows/core-package-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ concurrency:
on:
push:
branches:
- '*'
- main
- develop
paths:
- 'packages/**'
- '.github/workflows/core-package-tests.yaml'
pull_request:
branches:
- '*'
- main
- develop
paths:
- 'packages/**'
- '.github/workflows/core-package-tests.yaml'
Expand All @@ -29,8 +31,6 @@ env:
jobs:
# Validation job
validate:
# Skip duplicate runs: run on push to main/develop, or on pull_request events only
if: github.event_name == 'pull_request' || (github.event_name == 'push' && contains(fromJson('["main", "develop"]'), github.ref_name))
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
Expand Down Expand Up @@ -86,8 +86,6 @@ jobs:
# - Plugin/Project starters: no real tests, just templates
# - SQL plugin: excluded in main package.json
core-tests:
# Skip duplicate runs: run on push to main/develop, or on pull_request events only
if: github.event_name == 'pull_request' || (github.event_name == 'push' && contains(fromJson('["main", "develop"]'), github.ref_name))
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
Expand Down Expand Up @@ -145,6 +143,15 @@ jobs:

# Track if any tests fail
TESTS_FAILED=0
MAX_RETRIES=2 # Retry up to 2 times on Bun runtime crashes

# Check if exit code indicates a Bun runtime crash (segfault, SIGILL, etc.)
is_bun_crash() {
case $1 in
132|134|136|139|137) return 0 ;; # SIGILL, SIGABRT, SIGFPE, SIGSEGV, SIGKILL
*) return 1 ;;
esac
}

# Run tests in each package that has them (excluding CLI and client)
# These packages are tested together because they:
Expand All @@ -159,7 +166,33 @@ jobs:

cd "packages/$package"

if bun run test --timeout 60000; then
attempt=1
pkg_passed=false
while [ $attempt -le $((MAX_RETRIES + 1)) ]; do
set +e
bun run test --timeout 60000
exit_code=$?
set -e

if [ $exit_code -eq 0 ]; then
pkg_passed=true
break
elif is_bun_crash $exit_code; then
if [ $attempt -le $MAX_RETRIES ]; then
echo ""
echo "⚠️ Bun runtime crash (exit $exit_code) in $package — retrying ($((attempt + 1))/$((MAX_RETRIES + 1)))..."
sleep 3
((attempt++))
else
echo "⚠️ Bun crashed $((MAX_RETRIES + 1)) times in $package"
break
fi
else
break # Normal test failure, no retry
fi
done

if $pkg_passed; then
echo "✅ Tests passed for $package"
else
echo "❌ Tests failed for $package"
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/plugin-sql-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ on:
jobs:
pglite:
runs-on: ubuntu-latest
env:
# Use Node.js WASM runtime to avoid browser-style WASM init crashes in CI
PGLITE_WASM_MODE: node
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
Expand All @@ -26,6 +29,8 @@ jobs:
run: bun install && bun run build
- name: Tests
working-directory: ./packages/plugin-sql
env:
PGLITE_WASM_MODE: node
run: |
bun run test:unit
bun run test:integration
Expand Down Expand Up @@ -73,6 +78,8 @@ jobs:
# This tests upgrading from older Eliza versions (1.6.x) to current
e2e-upgrade:
runs-on: ubuntu-latest
env:
PGLITE_WASM_MODE: node
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
Expand All @@ -86,4 +93,6 @@ jobs:
run: bun install && bun run build
- name: E2E Upgrade Test
working-directory: ./packages/plugin-sql
env:
PGLITE_WASM_MODE: node
run: bun run test:e2e:upgrade
1 change: 0 additions & 1 deletion bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 12 additions & 5 deletions packages/api-client/src/lib/base-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,20 @@ export abstract class BaseApiClient {
// Handle error responses
if (!response.ok) {
// Try to extract error information from response
const errorData = jsonData as { error?: { code?: string; message?: string; details?: unknown } } | null;
const errorData = jsonData as {
error?: { code?: string; message?: string; details?: unknown };
} | null;
const error = errorData?.error || {
code: 'HTTP_ERROR',
message: `HTTP ${response.status}: ${response.statusText}`,
};
const details = typeof error.details === 'string' ? error.details : undefined;
throw new ApiError(error.code || 'HTTP_ERROR', error.message || 'Unknown error', details, response.status);
throw new ApiError(
error.code || 'HTTP_ERROR',
error.message || 'Unknown error',
details,
response.status
);
}

// Handle successful responses
Expand All @@ -149,9 +156,9 @@ export abstract class BaseApiClient {
'error' in apiResponse
? apiResponse.error
: {
code: 'UNKNOWN_ERROR',
message: 'An unknown error occurred',
};
code: 'UNKNOWN_ERROR',
message: 'An unknown error occurred',
};
throw new ApiError(error.code, error.message, error.details, response.status);
}
return apiResponse.data;
Expand Down
4 changes: 3 additions & 1 deletion packages/api-client/src/services/audio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,9 @@ export class AudioService extends BaseApiClient {
/**
* Convert audio input to appropriate FormData value
*/
private processAudioInput(audio: Blob | Buffer | ArrayBuffer | ArrayBufferView | string): Blob | string {
private processAudioInput(
audio: Blob | Buffer | ArrayBuffer | ArrayBufferView | string
): Blob | string {
if (audio instanceof Blob) {
return audio;
}
Expand Down
6 changes: 6 additions & 0 deletions packages/cli/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ dist
.turbo
cache
models

# Regenerated at build time by src/scripts/copy-templates.ts from the monorepo
# source packages (packages/project-starter, packages/plugin-starter, etc.).
# The copy script explicitly verifies .gitignore/.npmignore are present because
# fs-extra and Bun's fs.cp can silently drop them on some platforms.
# See the header comments in src/scripts/copy-templates.ts for full context.
templates/

# Generated version file (created at build time)
Expand Down
4 changes: 0 additions & 4 deletions packages/cli/src/commands/agent/actions/crud.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,6 @@ export async function getAgent(opts: OptionValues): Promise<void> {
const { id, createdAt, updatedAt, enabled, ...agentConfig } = agent;
console.log(JSON.stringify(agentConfig, null, 2));
}

return;
} catch (error) {
await checkServer(opts);
handleError(error);
Expand Down Expand Up @@ -96,7 +94,6 @@ export async function removeAgent(opts: OptionValues): Promise<void> {
await agentsService.deleteAgent(agentId);

console.log(`Successfully removed agent ${opts.name}`);
return;
} catch (error) {
await checkServer(opts);
handleError(error);
Expand Down Expand Up @@ -126,7 +123,6 @@ export async function clearAgentMemories(opts: OptionValues): Promise<void> {
const result = await memoryService.clearAgentMemories(agentId);

console.log(`Successfully cleared ${result?.deleted || 0} memories for agent ${opts.name}`);
return;
} catch (error) {
await checkServer(opts);
handleError(error);
Expand Down
2 changes: 0 additions & 2 deletions packages/cli/src/commands/agent/utils/display.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ export async function listAgents(opts: OptionValues): Promise<void> {
console.table(agentData);
}
}

return;
} catch (error) {
await checkServer(opts);
handleError(error);
Expand Down
Loading
Loading