mirror of
https://github.com/simstudioai/sim.git
synced 2026-01-09 23:17:59 -05:00
Compare commits
6 Commits
improvemen
...
v1.0.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
11d5b23d0a | ||
|
|
4687f5dd0f | ||
|
|
7f948a3a48 | ||
|
|
b538e5d884 | ||
|
|
1606f19d12 | ||
|
|
a9c755c5d4 |
@@ -3,6 +3,9 @@ FROM node:20-bullseye
|
||||
# Avoid warnings by switching to noninteractive
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# Set Node.js memory limit
|
||||
ENV NODE_OPTIONS="--max-old-space-size=4096"
|
||||
|
||||
# Install necessary packages for development
|
||||
RUN apt-get update \
|
||||
&& apt-get -y install --no-install-recommends \
|
||||
|
||||
58
.github/workflows/docker-publish.yml
vendored
Normal file
58
.github/workflows/docker-publish.yml
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
name: Docker Build and Publish
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
tags: [ 'v*' ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
IMAGE_NAME: simstudioai/sim
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Log in to the Container registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Extract metadata (tags, labels) for Docker
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
tags: |
|
||||
type=ref,event=branch
|
||||
type=ref,event=pr
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=sha,format=short
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
driver: docker
|
||||
buildkitd-flags: --debug
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
93
.github/workflows/publish-cli.yml
vendored
Normal file
93
.github/workflows/publish-cli.yml
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
name: Publish Sim Studio CLI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- 'packages/simstudio/**'
|
||||
- '.github/workflows/publish-cli.yml'
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
packages: write
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
cache: 'npm'
|
||||
cache-dependency-path: 'packages/simstudio/package-lock.json'
|
||||
|
||||
- name: Install dependencies
|
||||
working-directory: packages/simstudio
|
||||
run: npm ci
|
||||
|
||||
- name: Build package
|
||||
working-directory: packages/simstudio
|
||||
run: npm run build
|
||||
|
||||
- name: Get version
|
||||
working-directory: packages/simstudio
|
||||
id: get_version
|
||||
run: echo "version=$(node -p "require('./package.json').version")" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Check version update
|
||||
working-directory: packages/simstudio
|
||||
run: |
|
||||
if ! git diff ${{ github.event.before }} ${{ github.sha }} packages/simstudio/package.json | grep -q '"version":'; then
|
||||
echo "::error::Version not updated in package.json"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Run tests
|
||||
working-directory: packages/simstudio
|
||||
run: npm test
|
||||
|
||||
- name: Check for changes
|
||||
working-directory: packages/simstudio
|
||||
id: check_changes
|
||||
run: |
|
||||
if git diff --quiet ${{ github.event.before }} ${{ github.sha }} packages/simstudio/; then
|
||||
echo "changes=false" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "changes=true" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Publish to npm
|
||||
if: steps.check_changes.outputs.changes == 'true'
|
||||
working-directory: packages/simstudio
|
||||
run: |
|
||||
if ! npm publish; then
|
||||
echo "::error::Failed to publish package"
|
||||
exit 1
|
||||
fi
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
- name: Create Git tag
|
||||
if: steps.check_changes.outputs.changes == 'true'
|
||||
run: |
|
||||
git config --local user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git config --local user.name "github-actions[bot]"
|
||||
git tag -a "v${{ steps.get_version.outputs.version }}" -m "Release v${{ steps.get_version.outputs.version }}"
|
||||
git push origin "v${{ steps.get_version.outputs.version }}"
|
||||
|
||||
- name: Create GitHub Release
|
||||
if: steps.check_changes.outputs.changes == 'true'
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
name: "v${{ steps.get_version.outputs.version }}"
|
||||
tag_name: "v${{ steps.get_version.outputs.version }}"
|
||||
generate_release_notes: true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
16
Dockerfile
16
Dockerfile
@@ -3,19 +3,25 @@ FROM node:20-alpine
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
# Copy the entire sim directory
|
||||
COPY sim/ ./
|
||||
# Set Node.js memory limit
|
||||
ENV NODE_OPTIONS="--max-old-space-size=4096"
|
||||
|
||||
# Create the .env file if it doesn't exist
|
||||
RUN touch .env
|
||||
# Copy package files
|
||||
COPY sim/package*.json ./
|
||||
|
||||
# Install dependencies
|
||||
RUN npm install
|
||||
|
||||
# Copy the rest of the application
|
||||
COPY sim/ ./
|
||||
|
||||
# Generate database schema
|
||||
RUN npx drizzle-kit generate
|
||||
|
||||
# Build the application
|
||||
RUN npm run build
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
# Run migrations and start the app
|
||||
CMD npx drizzle-kit push && npm run dev
|
||||
CMD npx drizzle-kit push && npm run start
|
||||
199
README.md
199
README.md
@@ -14,99 +14,71 @@
|
||||
<strong>Sim Studio</strong> is a lightweight, user-friendly platform for building AI agent workflows.
|
||||
</p>
|
||||
|
||||
## Run
|
||||
## Getting Started
|
||||
|
||||
1. Run on our [cloud-hosted version](https://simstudio.ai)
|
||||
2. Self-host
|
||||
### Run on [Sim Studio Cloud](https://simstudio.ai)
|
||||
|
||||
## How to Self-Host
|
||||
The fastest way to get started is to use our [cloud-hosted version](https://simstudio.ai) - no setup required!
|
||||
|
||||
There are several ways to self-host Sim Studio:
|
||||
### Self-host Sim Studio
|
||||
|
||||
### Option 1: Docker Environment (Recommended)
|
||||
If you prefer to self-host, there are several options available:
|
||||
|
||||
### Option 1: Using CLI (Recommended)
|
||||
|
||||
The easiest way to self-host:
|
||||
|
||||
```bash
|
||||
# Clone your forked repository
|
||||
git clone https://github.com/YOUR_USERNAME/sim.git
|
||||
cd sim
|
||||
|
||||
# Create environment file and update with required environment variables (BETTER_AUTH_SECRET)
|
||||
cp sim/.env.example sim/.env
|
||||
|
||||
# Start Sim Studio using the provided script
|
||||
docker compose up -d --build
|
||||
|
||||
or
|
||||
|
||||
./start_simstudio_docker.sh
|
||||
npx simstudio
|
||||
# This will set up and run Sim Studio locally with minimal configuration
|
||||
```
|
||||
|
||||
After running these commands:
|
||||
|
||||
1. **Access the Application**:
|
||||
|
||||
- Open [http://localhost:3000/w/](http://localhost:3000/w/) in your browser
|
||||
- The `/w/` path is where the main workspace interface is located
|
||||
|
||||
2. **Useful Docker Commands**:
|
||||
|
||||
```bash
|
||||
# View application logs
|
||||
docker compose logs -f simstudio
|
||||
|
||||
# Access PostgreSQL database
|
||||
docker compose exec db psql -U postgres -d simstudio
|
||||
|
||||
# Stop the environment
|
||||
docker compose down
|
||||
|
||||
# Rebuild and restart (after code changes)
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
#### Working with Local Models
|
||||
|
||||
To use local models with Sim Studio, follow these steps:
|
||||
|
||||
1. **Pull Local Models**
|
||||
|
||||
```bash
|
||||
# Run the ollama_docker.sh script to pull the required models
|
||||
./sim/scripts/ollama_docker.sh pull <model_name>
|
||||
```
|
||||
|
||||
2. **Start Sim Studio with Local Models**
|
||||
|
||||
```bash
|
||||
#Start Sim Studio with local model support
|
||||
./start_simstudio_docker.sh --local
|
||||
|
||||
# or
|
||||
|
||||
# Start Sim Studio with local model support if you have nvidia GPU
|
||||
docker compose up --profile local-gpu -d --build
|
||||
|
||||
# or
|
||||
|
||||
# Start Sim Studio with local model support if you don't have nvidia GPU
|
||||
docker compose up --profile local-cpu -d --build
|
||||
```
|
||||
|
||||
The application will now be configured to use your local models. You can access it at [http://localhost:3000/w/](http://localhost:3000/w/).
|
||||
|
||||
#### Connecting to Existing Ollama Instance
|
||||
|
||||
If you already have an Ollama instance running on your host machine, you can connect to it using one of these methods:
|
||||
### Option 2: Using Docker Compose
|
||||
|
||||
```bash
|
||||
# Method 1: Use host networking (simplest approach)
|
||||
# Clone the repository
|
||||
git clone https://github.com/simstudioai/sim.git
|
||||
cd sim
|
||||
|
||||
# Create environment file (update BETTER_AUTH_SECRET and ENCRYPTION_KEY with secure random values)
|
||||
cp sim/.env.example sim/.env
|
||||
|
||||
# Start with Docker Compose
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
Once running, access the application at [http://localhost:3000/w/](http://localhost:3000/w/)
|
||||
|
||||
## Working with Local Models
|
||||
|
||||
Sim Studio supports integration with local LLM models:
|
||||
|
||||
```bash
|
||||
# Pull local models
|
||||
./sim/scripts/ollama_docker.sh pull <model_name>
|
||||
|
||||
# Start with local model support
|
||||
./start_simstudio_docker.sh --local
|
||||
|
||||
# For systems with NVIDIA GPU
|
||||
docker compose up --profile local-gpu -d --build
|
||||
|
||||
# For CPU-only systems
|
||||
docker compose up --profile local-cpu -d --build
|
||||
```
|
||||
|
||||
### Connecting to Existing Ollama Instance
|
||||
|
||||
If you already have Ollama running locally:
|
||||
|
||||
```bash
|
||||
# Using host networking (simplest)
|
||||
docker compose up --profile local-cpu -d --build --network=host
|
||||
```
|
||||
|
||||
Or modify your docker-compose.yml:
|
||||
Or add this to your docker-compose.yml:
|
||||
|
||||
```yaml
|
||||
# Method 2: Add host.docker.internal mapping
|
||||
services:
|
||||
simstudio:
|
||||
# ... existing configuration ...
|
||||
@@ -116,59 +88,46 @@ services:
|
||||
- OLLAMA_HOST=http://host.docker.internal:11434
|
||||
```
|
||||
|
||||
### Option 2: Dev Containers
|
||||
## Development Setup
|
||||
|
||||
1. Open VS Code or your favorite VS Code fork (Cursor, Windsurf, etc.)
|
||||
2. Install the [Remote - Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)
|
||||
3. Open the project in your editor
|
||||
4. Click "Reopen in Container" when prompted
|
||||
5. The environment will automatically be set up in the `sim` directory
|
||||
6. Run `npm run dev` in the terminal or use the `sim-start` alias
|
||||
### Prerequisites
|
||||
- Node.js 20+
|
||||
- Docker (recommended)
|
||||
- PostgreSQL (if not using Docker)
|
||||
|
||||
### Option 3: Manual Setup
|
||||
### Required Environment Variables
|
||||
|
||||
1. **Install Dependencies**
|
||||
For local development, create a `.env` file with these minimum variables:
|
||||
|
||||
```env
|
||||
DATABASE_URL=postgresql://postgres:postgres@db:5432/simstudio
|
||||
BETTER_AUTH_SECRET=<generate_a_secure_random_value>
|
||||
ENCRYPTION_KEY=<generate_a_secure_random_value>
|
||||
```
|
||||
|
||||
⚠️ **Note:** Without `RESEND_API_KEY`, verification codes will be logged to the console for local testing.
|
||||
|
||||
### Dev Container Option
|
||||
1. Open in VS Code with the Remote-Containers extension
|
||||
2. Click "Reopen in Container" when prompted
|
||||
3. Run `npm run dev` or use the `sim-start` alias
|
||||
|
||||
### Manual Setup
|
||||
```bash
|
||||
# Clone the repository
|
||||
git clone https://github.com/YOUR_USERNAME/sim.git
|
||||
cd sim/sim
|
||||
|
||||
# Install dependencies
|
||||
npm install
|
||||
```
|
||||
|
||||
2. **Set Up Environment**
|
||||
|
||||
```bash
|
||||
# Copy .env.example to .env
|
||||
cp .env.example .env
|
||||
|
||||
# Configure your .env file with the required environment variables:
|
||||
# - Database connection (PostgreSQL)
|
||||
# - Authentication settings (Better-Auth Secret)
|
||||
```
|
||||
|
||||
⚠️ **Important Notes:**
|
||||
- If `RESEND_API_KEY` is not set, verification codes for login/signup will be logged to the console.
|
||||
- You can use these logged codes for testing authentication locally.
|
||||
- For production environments, you should set up a proper email provider.
|
||||
|
||||
3. **Set Up Database**
|
||||
|
||||
```bash
|
||||
# Push the database schema
|
||||
npx drizzle-kit push
|
||||
```
|
||||
|
||||
4. **Start Development Server**
|
||||
|
||||
```bash
|
||||
# Start the development server
|
||||
npm run dev
|
||||
```
|
||||
|
||||
5. **Open [http://localhost:3000](http://localhost:3000) in your browser**
|
||||
## Troubleshooting
|
||||
|
||||
Common issues and solutions:
|
||||
|
||||
- **Authentication problems**: Check console logs for verification codes if `RESEND_API_KEY` is not set
|
||||
- **Database connection errors**: Verify PostgreSQL is running and credentials are correct
|
||||
- **Port conflicts**: Check if port 3000 is already in use by another application
|
||||
|
||||
## Tech Stack
|
||||
|
||||
@@ -188,6 +147,4 @@ We welcome contributions! Please see our [Contributing Guide](.github/CONTRIBUTI
|
||||
|
||||
This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.
|
||||
|
||||
##
|
||||
|
||||
<p align="center">Made with ❤️ by the Sim Studio Team</p>
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
simstudio:
|
||||
build:
|
||||
|
||||
129
packages/simstudio/PUBLISHING.md
Normal file
129
packages/simstudio/PUBLISHING.md
Normal file
@@ -0,0 +1,129 @@
|
||||
# Publishing Sim Studio CLI
|
||||
|
||||
This guide explains how to publish new versions of the Sim Studio CLI package to npm.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. An npm account with access to the `simstudio` package
|
||||
2. Node.js and npm installed
|
||||
3. Git repository access
|
||||
|
||||
## Publishing Steps
|
||||
|
||||
1. **Update Version**
|
||||
- Open `package.json`
|
||||
- Update the `version` field following [semantic versioning](https://semver.org/):
|
||||
- `MAJOR`: Breaking changes
|
||||
- `MINOR`: New features (backwards compatible)
|
||||
- `PATCH`: Bug fixes (backwards compatible)
|
||||
|
||||
2. **Build the Package**
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
This will compile TypeScript files to JavaScript in the `dist` directory.
|
||||
|
||||
3. **Test Locally**
|
||||
```bash
|
||||
# Test the CLI locally
|
||||
node dist/index.js start
|
||||
```
|
||||
Make sure everything works as expected before publishing.
|
||||
|
||||
4. **Login to npm** (if not already logged in)
|
||||
```bash
|
||||
npm login
|
||||
```
|
||||
|
||||
5. **Publish**
|
||||
```bash
|
||||
npm publish
|
||||
```
|
||||
|
||||
## Common Issues and Solutions
|
||||
|
||||
1. **Version Already Exists**
|
||||
- Make sure you've updated the version number in `package.json`
|
||||
- Each version must be unique
|
||||
|
||||
2. **Build Errors**
|
||||
- Check TypeScript compilation errors
|
||||
- Make sure all dependencies are installed
|
||||
- Run `npm install` if needed
|
||||
|
||||
3. **Permission Errors**
|
||||
- Ensure you're logged in to npm
|
||||
- Verify you have access to the package
|
||||
- Check if you're using the correct npm registry
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Version Control**
|
||||
- Commit all changes before publishing
|
||||
- Tag releases in Git after successful publish
|
||||
```bash
|
||||
git tag v0.1.12
|
||||
git push origin v0.1.12
|
||||
```
|
||||
|
||||
2. **Testing**
|
||||
- Always test the package locally before publishing
|
||||
- Test on different environments if possible
|
||||
|
||||
3. **Documentation**
|
||||
- Update README.md if there are new features
|
||||
- Document breaking changes
|
||||
- Update version history
|
||||
|
||||
4. **Changelog**
|
||||
- Keep a CHANGELOG.md file
|
||||
- Document all significant changes
|
||||
- Include migration guides for breaking changes
|
||||
|
||||
## Rollback Procedure
|
||||
|
||||
If you need to unpublish a version:
|
||||
|
||||
1. **Unpublish** (within 72 hours of publishing)
|
||||
```bash
|
||||
npm unpublish simstudio@0.1.12
|
||||
```
|
||||
|
||||
2. **Deprecate** (after 72 hours)
|
||||
```bash
|
||||
npm deprecate simstudio@0.1.12 "This version has issues, please use 0.1.13"
|
||||
```
|
||||
|
||||
## Automated Publishing
|
||||
|
||||
For automated publishing, you can use GitHub Actions. Add a workflow file in `.github/workflows/publish.yml`:
|
||||
|
||||
```yaml
|
||||
name: Publish Package
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [created]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
- run: npm ci
|
||||
- run: npm run build
|
||||
- run: npm publish
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
```
|
||||
|
||||
## Support
|
||||
|
||||
If you encounter any issues:
|
||||
1. Check the npm documentation
|
||||
2. Review the package's GitHub issues
|
||||
3. Contact the Sim Studio team
|
||||
2174
packages/simstudio/package-lock.json
generated
Normal file
2174
packages/simstudio/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
52
packages/simstudio/package.json
Normal file
52
packages/simstudio/package.json
Normal file
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"name": "simstudio",
|
||||
"version": "0.1.15",
|
||||
"description": "CLI tool for Sim Studio - easily start, build and test agent workflows",
|
||||
"main": "dist/index.js",
|
||||
"bin": {
|
||||
"simstudio": "./dist/index.js"
|
||||
},
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"start": "node ./dist/index.js",
|
||||
"dev": "tsc -w",
|
||||
"prepublishOnly": "npm run build"
|
||||
},
|
||||
"dependencies": {
|
||||
"chalk": "^4.1.2",
|
||||
"commander": "^11.1.0",
|
||||
"conf": "^10.2.0",
|
||||
"dotenv": "^16.4.7",
|
||||
"inquirer": "^8.2.6",
|
||||
"open": "^10.1.0",
|
||||
"tar": "^6.2.1",
|
||||
"update-notifier": "^5.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/inquirer": "^9.0.7",
|
||||
"@types/node": "^20",
|
||||
"@types/update-notifier": "^6.0.8",
|
||||
"typescript": "^5.7.3"
|
||||
},
|
||||
"keywords": [
|
||||
"sim",
|
||||
"sim-studio",
|
||||
"workflow",
|
||||
"automation",
|
||||
"cli",
|
||||
"agent",
|
||||
"ai",
|
||||
"workflow-automation"
|
||||
],
|
||||
"author": "Sim Studio Team",
|
||||
"license": "Apache-2.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/simstudioai/sim.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/simstudioai/sim/issues"
|
||||
},
|
||||
"homepage": "https://github.com/simstudioai/sim#readme"
|
||||
}
|
||||
274
packages/simstudio/src/index.ts
Normal file
274
packages/simstudio/src/index.ts
Normal file
@@ -0,0 +1,274 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import { Command } from 'commander'
|
||||
import inquirer from 'inquirer'
|
||||
import { execSync } from 'child_process'
|
||||
import { join } from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
import { existsSync, writeFileSync } from 'fs'
|
||||
import chalk from 'chalk'
|
||||
import updateNotifier from 'update-notifier'
|
||||
import open from 'open'
|
||||
import pkg from '../package.json' with { type: 'json' }
|
||||
|
||||
// Check for updates
|
||||
updateNotifier({ pkg }).notify()
|
||||
|
||||
interface StartAnswers {
|
||||
useDocker: boolean
|
||||
port?: string
|
||||
}
|
||||
|
||||
const program = new Command()
|
||||
const __dirname = fileURLToPath(new URL('.', import.meta.url))
|
||||
|
||||
// Helper function to run the start command
|
||||
async function startSimStudio() {
|
||||
console.log(chalk.magenta(`
|
||||
███████╗██╗███╗ ███╗ ███████╗████████╗██╗ ██╗██████╗ ██╗ ██████╗
|
||||
██╔════╝██║████╗ ████║ ██╔════╝╚══██╔══╝██║ ██║██╔══██╗██║██╔═══██╗
|
||||
███████╗██║██╔████╔██║ ███████╗ ██║ ██║ ██║██║ ██║██║██║ ██║
|
||||
╚════██║██║██║╚██╔╝██║ ╚════██║ ██║ ██║ ██║██║ ██║██║██║ ██║
|
||||
███████║██║██║ ╚═╝ ██║ ███████║ ██║ ╚██████╔╝██████╔╝██║╚██████╔╝
|
||||
╚══════╝╚═╝╚═╝ ╚═╝ ╚══════╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═════╝
|
||||
|
||||
`))
|
||||
console.log(chalk.gray('Lightweight, user-friendly platform for building AI agent workflows\n'))
|
||||
|
||||
const answers = await inquirer.prompt<StartAnswers>([
|
||||
{
|
||||
type: 'confirm',
|
||||
name: 'useDocker',
|
||||
message: 'Do you want to use Docker? (Recommended)',
|
||||
default: true
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
name: 'port',
|
||||
message: 'What port would you like to use?',
|
||||
default: '3000',
|
||||
validate: (input) => {
|
||||
const port = parseInt(input)
|
||||
if (isNaN(port)) {
|
||||
return 'Please enter a valid number'
|
||||
}
|
||||
if (port < 1 || port > 65535) {
|
||||
return 'Port must be between 1 and 65535'
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
])
|
||||
|
||||
if (answers.useDocker) {
|
||||
// Check if Docker is installed
|
||||
try {
|
||||
execSync('docker --version', { stdio: 'ignore' })
|
||||
} catch (error) {
|
||||
console.error(chalk.red('❌ Docker is not installed. Please install Docker first:'))
|
||||
console.log(chalk.yellow(' https://docs.docker.com/get-docker/'))
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
// Create .env file if it doesn't exist
|
||||
const envPath = join(process.cwd(), '.env')
|
||||
if (!existsSync(envPath)) {
|
||||
console.log(chalk.yellow('Creating .env file...'))
|
||||
const envContent = `
|
||||
DATABASE_URL=postgresql://postgres:postgres@db:5432/simstudio
|
||||
POSTGRES_URL=postgresql://postgres:postgres@db:5432/simstudio
|
||||
BETTER_AUTH_URL=http://localhost:${answers.port}
|
||||
NEXT_PUBLIC_APP_URL=http://localhost:${answers.port}
|
||||
BETTER_AUTH_SECRET=your_auth_secret_here
|
||||
ENCRYPTION_KEY=your_encryption_key_here
|
||||
FREESTYLE_API_KEY=placeholder
|
||||
GOOGLE_CLIENT_ID=placeholder
|
||||
GOOGLE_CLIENT_SECRET=placeholder
|
||||
GITHUB_CLIENT_ID=placeholder
|
||||
GITHUB_CLIENT_SECRET=placeholder
|
||||
RESEND_API_KEY=placeholder
|
||||
`.trim()
|
||||
writeFileSync(envPath, envContent)
|
||||
console.log(chalk.green('✓ .env file created'))
|
||||
}
|
||||
|
||||
// Create docker-compose.yml if it doesn't exist
|
||||
const composePath = join(process.cwd(), 'docker-compose.yml')
|
||||
if (!existsSync(composePath)) {
|
||||
console.log(chalk.yellow('Creating docker-compose.yml...'))
|
||||
const composeContent = `
|
||||
services:
|
||||
simstudio:
|
||||
image: ghcr.io/simstudioai/sim:latest
|
||||
ports:
|
||||
- "${answers.port}:3000"
|
||||
volumes:
|
||||
- ./.env:/app/.env
|
||||
environment:
|
||||
- NODE_ENV=development
|
||||
- DATABASE_URL=postgresql://postgres:postgres@db:5432/simstudio
|
||||
- POSTGRES_URL=postgresql://postgres:postgres@db:5432/simstudio
|
||||
- BETTER_AUTH_URL=http://localhost:${answers.port}
|
||||
- NEXT_PUBLIC_APP_URL=http://localhost:${answers.port}
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
|
||||
db:
|
||||
image: postgres:16
|
||||
restart: always
|
||||
environment:
|
||||
- POSTGRES_USER=postgres
|
||||
- POSTGRES_PASSWORD=postgres
|
||||
- POSTGRES_DB=simstudio
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U postgres"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
volumes:
|
||||
postgres_data:`
|
||||
writeFileSync(composePath, composeContent)
|
||||
console.log(chalk.green('✓ docker-compose.yml created'))
|
||||
}
|
||||
|
||||
// Check if Docker daemon is running
|
||||
try {
|
||||
console.log(chalk.blue('🔍 Checking Docker daemon...'))
|
||||
execSync('docker info', { stdio: 'ignore' })
|
||||
} catch (error) {
|
||||
console.error(chalk.red('❌ Docker daemon is not running. Please start Docker Desktop or the Docker service.'))
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
// Handle Docker network issues
|
||||
try {
|
||||
console.log(chalk.blue('🔍 Testing Docker networking...'))
|
||||
execSync('docker network ls', { stdio: 'ignore' })
|
||||
} catch (error) {
|
||||
console.error(chalk.red('❌ Docker networking issue detected. Please check your Docker installation.'))
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
// Add permission check for Docker socket
|
||||
if (process.platform === 'linux') {
|
||||
try {
|
||||
execSync('ls -l /var/run/docker.sock', { stdio: 'ignore' })
|
||||
} catch (error) {
|
||||
console.warn(chalk.yellow('⚠️ Could not check Docker socket permissions. You might need to run with sudo.'))
|
||||
}
|
||||
}
|
||||
|
||||
// Add timeout handling for image pull
|
||||
try {
|
||||
console.log(chalk.blue('🚚 Pulling latest Docker image...'))
|
||||
// Set a timeout and capture output
|
||||
const pullProcess = execSync('docker pull ghcr.io/simstudioai/sim:latest', {
|
||||
timeout: 180000, // 3 minutes
|
||||
stdio: 'pipe'
|
||||
})
|
||||
console.log(chalk.green('✓ Successfully pulled Docker image'))
|
||||
} catch (error: unknown) {
|
||||
if (error && typeof error === 'object' && 'code' in error && error.code === 'ETIMEDOUT') {
|
||||
console.error(chalk.red('❌ Image pull timed out. Check your internet connection.'))
|
||||
} else {
|
||||
const errorMessage = error instanceof Error ? error.message : String(error)
|
||||
console.error(chalk.red('❌ Failed to pull Docker image:'), errorMessage)
|
||||
console.log(chalk.yellow('Attempting to use cached image if available...'))
|
||||
}
|
||||
}
|
||||
|
||||
// Handle database connectivity issues
|
||||
setTimeout(() => {
|
||||
try {
|
||||
execSync('docker compose exec -T db pg_isready -U postgres', { stdio: 'ignore' })
|
||||
console.log(chalk.green('✓ Database is ready'))
|
||||
} catch (error) {
|
||||
console.error(chalk.red('❌ Could not connect to the database. Check the logs with:'))
|
||||
console.log(chalk.yellow(' docker compose logs db'))
|
||||
}
|
||||
}, 10000)
|
||||
|
||||
// Handle port conflicts
|
||||
try {
|
||||
console.log(chalk.blue(`🔍 Checking if port ${answers.port} is available...`))
|
||||
execSync(`lsof -i :${answers.port} || true`, { stdio: 'pipe' }).toString()
|
||||
// If we get output, the port is in use
|
||||
console.warn(chalk.yellow(`⚠️ Port ${answers.port} may already be in use. This could cause conflicts.`))
|
||||
} catch (error) {
|
||||
// Port is likely available, which is good
|
||||
}
|
||||
|
||||
// Add graceful shutdown handling
|
||||
process.on('SIGINT', () => {
|
||||
console.log(chalk.blue('\n👋 Shutting down Sim Studio...'))
|
||||
try {
|
||||
execSync('docker compose down', { stdio: 'inherit' })
|
||||
console.log(chalk.green('✓ Shutdown complete'))
|
||||
} catch (error) {
|
||||
console.error(chalk.red('❌ Error during shutdown:'), error)
|
||||
}
|
||||
process.exit(0)
|
||||
})
|
||||
|
||||
// Start Docker Compose
|
||||
try {
|
||||
console.log(chalk.blue('🚀 Starting Sim Studio with Docker Compose...'))
|
||||
execSync('docker compose up -d', { stdio: 'inherit' })
|
||||
|
||||
// Open browser after a short delay
|
||||
setTimeout(() => {
|
||||
console.log(chalk.green('✓ Opening Sim Studio in your browser...'))
|
||||
open(`http://localhost:${answers.port}`)
|
||||
}, 5000)
|
||||
} catch (error) {
|
||||
console.error(chalk.red('❌ Error starting Sim Studio:'), error)
|
||||
console.log(chalk.yellow('\nTroubleshooting tips:'))
|
||||
console.log(' 1. Make sure Docker is running')
|
||||
console.log(' 2. Check if port ' + answers.port + ' is available')
|
||||
console.log(' 3. Try running with a different port')
|
||||
console.log(' 4. Visit https://github.com/simstudioai/sim for more help')
|
||||
process.exit(1)
|
||||
}
|
||||
} else {
|
||||
// Local installation
|
||||
try {
|
||||
console.log(chalk.blue('📦 Installing dependencies...'))
|
||||
execSync('npm install', { stdio: 'inherit' })
|
||||
|
||||
console.log(chalk.blue('🚀 Starting Sim Studio...'))
|
||||
execSync('npm run dev', { stdio: 'inherit' })
|
||||
|
||||
// Open browser after a short delay
|
||||
setTimeout(() => {
|
||||
console.log(chalk.green('✓ Opening Sim Studio in your browser...'))
|
||||
open('http://localhost:3000')
|
||||
}, 5000)
|
||||
} catch (error) {
|
||||
console.error(chalk.red('❌ Error starting Sim Studio:'), error)
|
||||
console.log(chalk.yellow('\nTroubleshooting tips:'))
|
||||
console.log(' 1. Make sure Node.js 20+ is installed')
|
||||
console.log(' 2. Check if port 3000 is available')
|
||||
console.log(' 3. Try running with Docker instead')
|
||||
console.log(' 4. Visit https://github.com/simstudioai/sim for more help')
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
program
|
||||
.name('simstudio')
|
||||
.description('CLI tool for Sim Studio - easily start, build and test agent workflows')
|
||||
.version(pkg.version)
|
||||
.action(startSimStudio) // Run start when no command is specified
|
||||
|
||||
// Add explicit start command for backward compatibility
|
||||
program
|
||||
.command('start')
|
||||
.description('Start Sim Studio')
|
||||
.action(startSimStudio)
|
||||
|
||||
program.parse()
|
||||
15
packages/simstudio/tsconfig.json
Normal file
15
packages/simstudio/tsconfig.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "NodeNext",
|
||||
"esModuleInterop": true,
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"resolveJsonModule": true
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
@@ -22,10 +22,7 @@
|
||||
"cli:build": "npm run build -w packages/simstudio",
|
||||
"cli:dev": "npm run build -w packages/simstudio && cd packages/simstudio && node ./dist/index.js",
|
||||
"cli:publish": "cd packages/simstudio && npm publish",
|
||||
"cli:start": "cd packages/simstudio && node ./dist/index.js start",
|
||||
"build:standalone": "node scripts/build-standalone.js",
|
||||
"build:cli": "npm run cli:build && npm run build:standalone",
|
||||
"publish:cli": "npm run build:cli && npm run cli:publish"
|
||||
"cli:start": "cd packages/simstudio && node ./dist/index.js start"
|
||||
},
|
||||
"dependencies": {
|
||||
"@anthropic-ai/sdk": "^0.39.0",
|
||||
|
||||
Reference in New Issue
Block a user