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
18 changes: 18 additions & 0 deletions .github/codeql/codeql-config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: "CodeQL config"

paths-ignore:
# Demo applications
- apps/streaming-demo
# Test files
- "**/test"
- "**/tests"
- "**/__tests__"
- "**/*.test.ts"
- "**/*.test.tsx"
- "**/*.spec.ts"
- "**/*.spec.tsx"
# Enclave VM adapters - intentionally execute user code in sandboxed VM
# Security is provided by: VM sandbox isolation, AST-guard code validation,
# and double VM architecture. The "code injection" alerts are expected behavior.
- libs/enclave-vm/src/adapters/vm-adapter.ts
- libs/enclave-vm/src/adapters/worker-pool/worker-pool-adapter.ts
3 changes: 2 additions & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ fi

# Check formatting for files changed from main
# Pipe directly to preserve null-terminated input (don't use intermediate variable)
# Filter to only existing files (excludes deleted files)
echo "Checking formatting for files changed from main..."
git diff --name-only -z --diff-filter=ACMR main... | grep -zE '\.(js|jsx|ts|tsx|json|css|scss|md|html|yml|yaml)$' | xargs -0 -r npx prettier --check
git diff --name-only -z --diff-filter=ACMR main... | grep -zE '\.(js|jsx|ts|tsx|json|css|scss|md|html|yml|yaml)$' | xargs -0 -I {} sh -c '[ -f "$1" ] && printf "%s\0" "$1"' _ {} | xargs -0 -r npx prettier --check
PRETTIER_EXIT=$?

if [ $PRETTIER_EXIT -ne 0 ]; then
Expand Down
4 changes: 4 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
/.nx/cache
/.nx/workspace-data

# Lock files (use yarn.lock only)
package-lock.json
pnpm-lock.yaml

node_modules
dist
build
Expand Down
664 changes: 664 additions & 0 deletions README-ARCHITECTURE.md

Large diffs are not rendered by default.

101 changes: 94 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
[![npm vectoriadb](https://img.shields.io/npm/v/vectoriadb.svg?label=vectoriadb&color=e8a045)](https://www.npmjs.com/package/vectoriadb)
[![npm enclave-vm](https://img.shields.io/npm/v/enclave-vm.svg?label=enclave-vm&color=e8a045)](https://www.npmjs.com/package/enclave-vm)
<br>
[![npm @enclavejs/broker](https://img.shields.io/npm/v/@enclavejs/broker.svg?label=@enclavejs/broker&color=e8a045)](https://www.npmjs.com/package/@enclavejs/broker)
[![npm @enclavejs/client](https://img.shields.io/npm/v/@enclavejs/client.svg?label=@enclavejs/client&color=e8a045)](https://www.npmjs.com/package/@enclavejs/client)
[![npm @enclavejs/react](https://img.shields.io/npm/v/@enclavejs/react.svg?label=@enclavejs/react&color=e8a045)](https://www.npmjs.com/package/@enclavejs/react)
<br>
[![Node](https://img.shields.io/badge/node-%3E%3D22-339933)](https://nodejs.org)
[![License](https://img.shields.io/badge/license-Apache--2.0-blue)](./LICENSE)

Expand All @@ -25,20 +29,45 @@

---

## Why Enclave?

- **Extensive security testing** - See [security audit](./libs/enclave-vm/SECURITY-AUDIT.md) for details
- **Defense in depth** - 6 security layers for LLM-generated code
- **Streaming runtime** - Real-time event streaming with tool call support
- **Zero-config** - Works out of the box with sensible defaults
- **TypeScript-first** - Full type safety and excellent DX

## Install

### Core Packages

```bash
npm install enclave-vm # Secure JS execution
npm install ast-guard # AST validation
npm install enclave-vm # Secure JS sandbox
npm install ast-guard # AST security validation
npm install vectoriadb # Vector search
```

## Why Enclave?
### Streaming Runtime

- **Extensive security testing** - See [security audit](./libs/enclave-vm/SECURITY-AUDIT.md) for details
- **Defense in depth** - 6 security layers for LLM-generated code
- **Zero-config** - Works out of the box with sensible defaults
- **TypeScript-first** - Full type safety and excellent DX
```bash
npm install @enclavejs/broker # Tool broker & session management
npm install @enclavejs/client # Browser/Node client SDK
npm install @enclavejs/react # React hooks & components
```

## Packages

| Package | Description |
| ------------------------------------------------ | --------------------------------------------------- |
| [`enclave-vm`](./libs/enclave-vm) | Secure JavaScript sandbox with 6 security layers |
| [`@enclavejs/broker`](./libs/enclavejs-broker) | Tool registry, secrets management, session API |
| [`@enclavejs/client`](./libs/enclavejs-client) | Browser & Node.js client for streaming sessions |
| [`@enclavejs/react`](./libs/enclavejs-react) | React hooks: `useEnclaveSession`, `EnclaveProvider` |
| [`@enclavejs/runtime`](./libs/enclavejs-runtime) | Deployable runtime worker (Lambda, Vercel, etc.) |
| [`@enclavejs/types`](./libs/enclavejs-types) | TypeScript types & Zod schemas |
| [`@enclavejs/stream`](./libs/enclavejs-stream) | NDJSON streaming, encryption, reconnection |
| [`ast-guard`](./libs/ast-guard) | AST-based security validator |
| [`vectoriadb`](./libs/vectoriadb) | Lightweight in-memory vector database |

## Quick Start

Expand All @@ -65,6 +94,64 @@ if (result.success) {
enclave.dispose();
```

## React Integration

```tsx
import { EnclaveProvider, useEnclaveSession } from '@enclavejs/react';

function App() {
return (
<EnclaveProvider brokerUrl="https://your-server.com">
<CodeRunner />
</EnclaveProvider>
);
}

function CodeRunner() {
const { execute, state, result, stdout } = useEnclaveSession();

const runCode = () =>
execute(`
const data = await callTool('fetchData', { id: 123 });
return data;
`);

return (
<div>
<button onClick={runCode} disabled={state === 'running'}>
{state === 'running' ? 'Running...' : 'Run Code'}
</button>
{stdout && <pre>{stdout}</pre>}
{result && <pre>{JSON.stringify(result, null, 2)}</pre>}
</div>
);
}
```

## Architecture

See [README-ARCHITECTURE.md](./README-ARCHITECTURE.md) for detailed architecture documentation covering:

- Deployment scenarios (embedded vs extracted runtime)
- Streaming protocol (NDJSON)
- Tool broker pattern
- Reference sidecar & auto-ref
- Security & encryption

## Demo

Run the streaming demo locally:

```bash
npx nx demo streaming-demo
```

This starts 3 servers demonstrating the secure architecture:

- **Client** (port 4100) - Web UI
- **Broker** (port 4101) - Tool execution & session management
- **Runtime** (port 4102) - Sandboxed code execution

**[Read the full documentation →](https://agentfront.dev/docs/guides/enclave)**

---
Expand Down
23 changes: 23 additions & 0 deletions apps/streaming-demo/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module.exports = {
displayName: 'streaming-demo',
preset: '../../jest.preset.js',
testEnvironment: 'node',
transform: {
'^.+\\.[tj]s$': [
'ts-jest',
{
tsconfig: '<rootDir>/tsconfig.spec.json',
isolatedModules: true,
diagnostics: {
ignoreCodes: [151002],
},
},
],
},
moduleFileExtensions: ['ts', 'js', 'html'],
coverageDirectory: '../../coverage/apps/streaming-demo',
collectCoverageFrom: ['src/**/*.ts', '!src/**/*.spec.ts', '!src/**/*.test.ts', '!src/**/index.ts'],
coverageReporters: ['text', 'text-summary', 'lcov', 'html', 'json'],
testTimeout: 30000, // Longer timeout for WebSocket tests
transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)', '<rootDir>/../../libs/.*/dist/'],
};
28 changes: 28 additions & 0 deletions apps/streaming-demo/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "streaming-demo",
"version": "0.0.1",
"private": true,
"description": "3-server demo showcasing EnclaveJS streaming architecture",
"main": "dist/broker-server.js",
"scripts": {
"build": "tsc -p tsconfig.app.json",
"broker": "ts-node src/broker-server.ts",
"client": "ts-node src/client-server.ts",
"runtime": "ts-node src/runtime-server.ts"
},
"dependencies": {
"@enclavejs/broker": "0.1.0",
"@enclavejs/client": "0.1.0",
"@enclavejs/types": "0.1.0",
"enclave-vm": "2.7.0",
"express": "^4.21.0",
"zod": "^3.24.0"
},
"devDependencies": {
"@types/express": "^4.17.21",
"@types/node": "^22.0.0",
"ts-node": "^10.9.2",
"typescript": "^5.6.3"
},
"type": "commonjs"
}
55 changes: 55 additions & 0 deletions apps/streaming-demo/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{
"name": "streaming-demo",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "apps/streaming-demo/src",
"projectType": "application",
"targets": {
"build": {
"executor": "@nx/js:tsc",
"outputs": ["{options.outputPath}"],
"options": {
"outputPath": "dist/apps/streaming-demo",
"main": "apps/streaming-demo/src/broker-server.ts",
"tsConfig": "apps/streaming-demo/tsconfig.app.json",
"assets": ["apps/streaming-demo/src/public"]
}
},
"serve:runtime": {
"executor": "nx:run-commands",
"options": {
"command": "npx tsx apps/streaming-demo/src/runtime-server.ts"
}
},
"serve:broker": {
"executor": "nx:run-commands",
"options": {
"command": "npx tsx apps/streaming-demo/src/broker-server.ts"
}
},
"serve:client": {
"executor": "nx:run-commands",
"options": {
"command": "npx tsx apps/streaming-demo/src/client-server.ts"
}
},
"demo": {
"executor": "nx:run-commands",
"options": {
"commands": [
"npx tsx apps/streaming-demo/src/runtime-server.ts",
"sleep 1 && npx tsx apps/streaming-demo/src/broker-server.ts",
"sleep 2 && npx tsx apps/streaming-demo/src/client-server.ts"
],
"parallel": true
}
},
"test": {
"executor": "nx:run-commands",
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
"options": {
"command": "NODE_OPTIONS='--experimental-vm-modules' npx jest --config apps/streaming-demo/jest.config.ts --passWithNoTests --runInBand"
}
}
},
"tags": []
}
Loading