mirror of
https://github.com/simstudioai/sim.git
synced 2026-04-28 03:00:29 -04:00
chore(repo): rebase fixes and quality improvements for realtime split
Addresses merge-time issues and gaps from the realtime app split: - Retarget stale vi.mock paths to @sim/workflow-persistence/subblocks - Restore README branding, fix AGENTS.md script reference - Restore TSDoc on workflow-persistence subblocks helpers - Use toError() from @sim/utils/errors in save.ts - Add vitest config + local mocks so @sim/audit tests run standalone - Move socket.io-client to devDependencies in apps/realtime - Add missing package COPY steps to docker/app.Dockerfile - Add check:boundaries/check:realtime-prune scripts and wire into CI Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
4
.github/workflows/test-build.yml
vendored
4
.github/workflows/test-build.yml
vendored
@@ -104,10 +104,10 @@ jobs:
|
||||
run: bun run lint:check
|
||||
|
||||
- name: Enforce monorepo boundaries
|
||||
run: bun run scripts/check-monorepo-boundaries.ts
|
||||
run: bun run check:boundaries
|
||||
|
||||
- name: Verify realtime prune graph
|
||||
run: bun run scripts/check-realtime-prune-graph.ts
|
||||
run: bun run check:realtime-prune
|
||||
|
||||
- name: Run tests with coverage
|
||||
env:
|
||||
|
||||
@@ -53,7 +53,7 @@ packages/
|
||||
### Package boundaries
|
||||
- `apps/* → packages/*` only. Packages never import from `apps/*`.
|
||||
- Each package has explicit subpath `exports` maps; no barrels that accidentally pull in heavy halves.
|
||||
- `apps/realtime` intentionally avoids Next.js, React, the block/tool registry, provider SDKs, and the executor. CI enforces this via `scripts/check-monorepo-boundaries.ts` and `scripts/check-realtime-image-size.ts`.
|
||||
- `apps/realtime` intentionally avoids Next.js, React, the block/tool registry, provider SDKs, and the executor. CI enforces this via `scripts/check-monorepo-boundaries.ts` and `scripts/check-realtime-prune-graph.ts`.
|
||||
- Auth is shared across services via the Better Auth "Shared Database Session" pattern: both apps read the same `BETTER_AUTH_SECRET` and point at the same DB via `@sim/db`.
|
||||
|
||||
### Naming Conventions
|
||||
|
||||
94
README.md
94
README.md
@@ -1,55 +1,69 @@
|
||||
<p align="center">
|
||||
<a href="https://sim.ai" target="_blank" rel="noopener noreferrer">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="apps/sim/public/logo/wordmark.svg">
|
||||
<source media="(prefers-color-scheme: light)" srcset="apps/sim/public/logo/wordmark-dark.svg">
|
||||
<img src="apps/sim/public/logo/wordmark-dark.svg" alt="Sim Logo" width="380"/>
|
||||
</picture>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center">The open-source platform to build AI agents and run your agentic workforce. Connect 1,000+ integrations and LLMs to orchestrate agentic workflows.</p>
|
||||
|
||||
The open-source platform to build AI agents and run your agentic workforce. Connect 1,000+ integrations and LLMs to orchestrate agentic workflows.
|
||||
|
||||
|
||||
|
||||
<p align="center">
|
||||
<a href="https://sim.ai" target="_blank" rel="noopener noreferrer"><img src="https://img.shields.io/badge/sim.ai-33c482" alt="Sim.ai"></a>
|
||||
<a href="https://discord.gg/Hr4UWYEcTT" target="_blank" rel="noopener noreferrer"><img src="https://img.shields.io/badge/Discord-Join%20Server-5865F2?logo=discord&logoColor=white" alt="Discord"></a>
|
||||
<a href="https://x.com/simdotai" target="_blank" rel="noopener noreferrer"><img src="https://img.shields.io/twitter/follow/simdotai?style=social" alt="Twitter"></a>
|
||||
<a href="https://docs.sim.ai" target="_blank" rel="noopener noreferrer"><img src="https://img.shields.io/badge/Docs-33c482.svg" alt="Documentation"></a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://deepwiki.com/simstudioai/sim" target="_blank" rel="noopener noreferrer"><img src="https://deepwiki.com/badge.svg" alt="Ask DeepWiki"></a> <a href="https://cursor.com/link/prompt?text=Help%20me%20set%20up%20Sim%20locally.%20Follow%20these%20steps%3A%0A%0A1.%20First%2C%20verify%20Docker%20is%20installed%20and%20running%3A%0A%20%20%20docker%20--version%0A%20%20%20docker%20info%0A%0A2.%20Clone%20the%20repository%3A%0A%20%20%20git%20clone%20https%3A%2F%2Fgithub.com%2Fsimstudioai%2Fsim.git%0A%20%20%20cd%20sim%0A%0A3.%20Start%20the%20services%20with%20Docker%20Compose%3A%0A%20%20%20docker%20compose%20-f%20docker-compose.prod.yml%20up%20-d%0A%0A4.%20Wait%20for%20all%20containers%20to%20be%20healthy%20(this%20may%20take%201-2%20minutes)%3A%0A%20%20%20docker%20compose%20-f%20docker-compose.prod.yml%20ps%0A%0A5.%20Verify%20the%20app%20is%20accessible%20at%20http%3A%2F%2Flocalhost%3A3000%0A%0AIf%20there%20are%20any%20errors%2C%20help%20me%20troubleshoot%20them.%20Common%20issues%3A%0A-%20Port%203000%2C%203002%2C%20or%205432%20already%20in%20use%0A-%20Docker%20not%20running%0A-%20Insufficient%20memory%20(needs%2012GB%2B%20RAM)%0A%0AFor%20local%20AI%20models%20with%20Ollama%2C%20use%20this%20instead%20of%20step%203%3A%0A%20%20%20docker%20compose%20-f%20docker-compose.ollama.yml%20--profile%20setup%20up%20-d"><img src="https://img.shields.io/badge/Set%20Up%20with-Cursor-000000?logo=cursor&logoColor=white" alt="Set Up with Cursor"></a>
|
||||
</p>
|
||||
|
||||
### Build Workflows with Ease
|
||||
|
||||
Design agent workflows visually on a canvas—connect agents, tools, and blocks, then run them instantly.
|
||||
|
||||
|
||||
<p align="center">
|
||||
<img src="apps/sim/public/static/workflow.gif" alt="Workflow Builder Demo" width="800"/>
|
||||
</p>
|
||||
|
||||
### Supercharge with Copilot
|
||||
|
||||
Leverage Copilot to generate nodes, fix errors, and iterate on flows directly from natural language.
|
||||
|
||||
|
||||
<p align="center">
|
||||
<img src="apps/sim/public/static/copilot.gif" alt="Copilot Demo" width="800"/>
|
||||
</p>
|
||||
|
||||
### Integrate Vector Databases
|
||||
|
||||
Upload documents to a vector store and let agents answer questions grounded in your specific content.
|
||||
|
||||
|
||||
<p align="center">
|
||||
<img src="apps/sim/public/static/knowledge.gif" alt="Knowledge Uploads and Retrieval Demo" width="800"/>
|
||||
</p>
|
||||
|
||||
## Quickstart
|
||||
|
||||
### Cloud-hosted: [sim.ai](https://sim.ai)
|
||||
|
||||
|
||||
<a href="https://sim.ai" target="_blank" rel="noopener noreferrer"><img src="https://img.shields.io/badge/sim.ai-33c482?logo=data:image/svg%2bxml;base64,PHN2ZyB3aWR0aD0iNjE2IiBoZWlnaHQ9IjYxNiIgdmlld0JveD0iMCAwIDYxNiA2MTYiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF8xMTU5XzMxMykiPgo8cGF0aCBkPSJNNjE2IDBIMFY2MTZINjE2VjBaIiBmaWxsPSIjMzNjNDgyIi8+CjxwYXRoIGQ9Ik04MyAzNjUuNTY3SDExM0MxMTMgMzczLjgwNSAxMTYgMzgwLjM3MyAxMjIgMzg1LjI3MkMxMjggMzg5Ljk0OCAxMzYuMTExIDM5Mi4yODUgMTQ2LjMzMyAzOTIuMjg1QzE1Ny40NDQgMzkyLjI4NSAxNjYgMzkwLjE3MSAxNzIgMzg1LjkzOUMxNzcuOTk5IDM4MS40ODcgMTgxIDM3NS41ODYgMTgxIDM2OC4yMzlDMTgxIDM2Mi44OTUgMTc5LjMzMyAzNTguNDQyIDE3NiAzNTQuODhDMTcyLjg4OSAzNTEuMzE4IDE2Ny4xMTEgMzQ4LjQyMiAxNTguNjY3IDM0Ni4xOTZMMTMwIDMzOS41MTdDMTE1LjU1NSAzMzUuOTU1IDEwNC43NzggMzMwLjQ5OSA5Ny42NjY1IDMyMy4xNTFDOTAuNzc3NSAzMTUuODA0IDg3LjMzMzQgMzA2LjExOSA4Ny4zMzM0IDI5NC4wOTZDODcuMzMzNCAyODQuMDc2IDg5Ljg4OSAyNzUuMzkyIDk0Ljk5OTYgMjY4LjA0NUMxMDAuMzMzIDI2MC42OTcgMTA3LjU1NSAyNTUuMDIgMTE2LjY2NiAyNTEuMDEyQzEyNiAyNDcuMDA0IDEzNi42NjcgMjQ1IDE0OC42NjYgMjQ1QzE2MC42NjcgMjQ1IDE3MSAyNDcuMTE2IDE3OS42NjcgMjUxLjM0NkMxODguNTU1IDI1NS41NzYgMTk1LjQ0NCAyNjEuNDc3IDIwMC4zMzMgMjY5LjA0N0MyMDUuNDQ0IDI3Ni42MTcgMjA4LjExMSAyODUuNjM0IDIwOC4zMzMgMjk2LjA5OUgxNzguMzMzQzE3OC4xMTEgMjg3LjYzOCAxNzUuMzMzIDI4MS4wNyAxNjkuOTk5IDI3Ni4zOTRDMTY0LjY2NiAyNzEuNzE5IDE1Ny4yMjIgMjY5LjM4MSAxNDcuNjY3IDI2OS4zODFDMTM3Ljg4OSAyNjkuMzgxIDEzMC4zMzMgMjcxLjQ5NiAxMjUgMjc1LjcyNkMxMTkuNjY2IDI3OS45NTcgMTE3IDI4NS43NDYgMTE3IDI5My4wOTNDMTE3IDMwNC4wMDMgMTI1IDMxMS40NjIgMTQxIDMxNS40N0wxNjkuNjY3IDMyMi40ODNDMTgzLjQ0NSAzMjUuNiAxOTMuNzc4IDMzMC43MjIgMjAwLjY2NyAzMzcuODQ3QzIwNy41NTUgMzQ0Ljc0OSAyMTEgMzU0LjIxMiAyMTEgMzY2LjIzNUMyMTEgMzc2LjQ3NyAyMDguMjIyIDM4NS40OTQgMjAyLjY2NiAzOTMuMjg3QzE5Ny4xMTEgNDAwLjg1NyAxODkuNDQ0IDQwNi43NTggMTc5LjY2NyA0MTAuOTg5QzE3MC4xMTEgNDE0Ljk5NiAxNTguNzc4IDQxNyAxNDUuNjY3IDQxN0MxMjYuNTU1IDQxNyAxMTEuMzMzIDQxMi4zMjUgOTkuOTk5NyA0MDIuOTczQzg4LjY2NjggMzkzLjYyMSA4MyAzODEuMTUzIDgzIDM2NS41NjdaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNMjMyLjI5MSA0MTNWMjUwLjA4MkMyNDQuNjg0IDI1NC42MTQgMjUwLjE0OCAyNTQuNjE0IDI2My4zNzEgMjUwLjA4MlY0MTNIMjMyLjI5MVpNMjQ3LjUgMjM5LjMxM0MyNDEuOTkgMjM5LjMxMyAyMzcuMTQgMjM3LjMxMyAyMzIuOTUyIDIzMy4zMTZDMjI4Ljk4NCAyMjkuMDk1IDIyNyAyMjQuMjA5IDIyNyAyMTguNjU2QzIyNyAyMTIuODgyIDIyOC45ODQgMjA3Ljk5NSAyMzIuOTUyIDIwMy45OTdDMjM3LjE0IDE5OS45OTkgMjQxLjk5IDE5OCAyNDcuNSAxOThDMjUzLjIzMSAxOTggMjU4LjA4IDE5OS45OTkgMjYyLjA0OSAyMDMuOTk3QzI2Ni4wMTYgMjA3Ljk5NSAyNjggMjEyLjg4MiAyNjggMjE4LjY1NkMyNjggMjI0LjIwOSAyNjYuMDE2IDIyOS4wOTUgMjYyLjA0OSAyMzMuMzE2QzI1OC4wOCAyMzcuMzEzIDI1My4yMzEgMjM5LjMxMyAyNDcuNSAyMzkuMzEzWiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTMxOS4zMzMgNDEzSDI4OFYyNDkuNjc2SDMxNlYyNzcuMjMzQzMxOS4zMzMgMjY4LjEwNCAzMjUuNzc4IDI2MC4zNjQgMzM0LjY2NyAyNTQuMzUyQzM0My43NzggMjQ4LjExNyAzNTQuNzc4IDI0NSAzNjcuNjY3IDI0NUMzODIuMTExIDI0NSAzOTQuMTEyIDI0OC44OTcgNDAzLjY2NyAyNTYuNjlDNDEzLjIyMiAyNjQuNDg0IDQxOS40NDQgMjc0LjgzNyA0MjIuMzM0IDI4Ny43NTJINDE2LjY2N0M0MTguODg5IDI3NC44MzcgNDI1IDI2NC40ODQgNDM1IDI1Ni42OUM0NDUgMjQ4Ljg5NyA0NTcuMzM0IDI0NSA0NzIgMjQ1QzQ5MC42NjYgMjQ1IDUwNS4zMzQgMjUwLjQ1NSA1MTYgMjYxLjM2NkM1MjYuNjY3IDI3Mi4yNzYgNTMyIDI4Ny4xOTUgNTMyIDMwNi4xMjFWNDEzSDUwMS4zMzNWMzEzLjgwNEM1MDEuMzMzIDMwMC44ODkgNDk4IDI5MC45ODEgNDkxLjMzMyAyODQuMDc4QzQ4NC44ODkgMjc2Ljk1MiA0NzYuMTExIDI3My4zOSA0NjUgMjczLjM5QzQ1Ny4yMjIgMjczLjM5IDQ1MC4zMzMgMjc1LjE3MSA0NDQuMzM0IDI3OC43MzRDNDM4LjU1NiAyODIuMDc0IDQzNCAyODYuOTcyIDQzMC42NjcgMjkzLjQzQzQyNy4zMzMgMjk5Ljg4NyA0MjUuNjY3IDMwNy40NTcgNDI1LjY2NyAzMTYuMTQxVjQxM0gzOTQuNjY3VjMxMy40NjlDMzk0LjY2NyAzMDAuNTU1IDM5MS40NDUgMjkwLjc1OCAzODUgMjg0LjA3OEMzNzguNTU2IDI3Ny4xNzUgMzY5Ljc3OCAyNzMuNzI0IDM1OC42NjcgMjczLjcyNEMzNTAuODg5IDI3My43MjQgMzQ0IDI3NS41MDUgMzM4IDI3OS4wNjhDMzMyLjIyMiAyODIuNDA4IDMyNy42NjcgMjg3LjMwNyAzMjQuMzMzIDI5My43NjNDMzIxIDI5OS45OTggMzE5LjMzMyAzMDcuNDU3IDMxOS4zMzMgMzE2LjE0MVY0MTNaIiBmaWxsPSJ3aGl0ZSIvPgo8L2c+CjxkZWZzPgo8Y2xpcFBhdGggaWQ9ImNsaXAwXzExNTlfMzEzIj4KPHJlY3Qgd2lkdGg9IjYxNiIgaGVpZ2h0PSI2MTYiIGZpbGw9IndoaXRlIi8+CjwvY2xpcFBhdGg+CjwvZGVmcz4KPC9zdmc+&logoColor=white" alt="Sim.ai"></a>
|
||||
|
||||
### Self-hosted: NPM Package
|
||||
|
||||
```bash
|
||||
npx simstudio
|
||||
```
|
||||
|
||||
→ [http://localhost:3000](http://localhost:3000)
|
||||
→ http://localhost:3000
|
||||
|
||||
#### Note
|
||||
|
||||
Docker must be installed and running on your machine.
|
||||
|
||||
#### Options
|
||||
|
||||
|
||||
| Flag | Description |
|
||||
| ------------------- | ----------------------------------- |
|
||||
| Flag | Description |
|
||||
|------|-------------|
|
||||
| `-p, --port <port>` | Port to run Sim on (default `3000`) |
|
||||
| `--no-pull` | Skip pulling latest Docker images |
|
||||
|
||||
| `--no-pull` | Skip pulling latest Docker images |
|
||||
|
||||
### Self-hosted: Docker Compose
|
||||
|
||||
@@ -75,7 +89,7 @@ bun install
|
||||
bun run prepare # Set up pre-commit hooks
|
||||
```
|
||||
|
||||
1. Set up PostgreSQL with pgvector:
|
||||
2. Set up PostgreSQL with pgvector:
|
||||
|
||||
```bash
|
||||
docker run --name simstudio-db -e POSTGRES_PASSWORD=your_password -e POSTGRES_DB=simstudio -p 5432:5432 -d pgvector/pgvector:pg17
|
||||
@@ -83,61 +97,43 @@ docker run --name simstudio-db -e POSTGRES_PASSWORD=your_password -e POSTGRES_DB
|
||||
|
||||
Or install manually via the [pgvector guide](https://github.com/pgvector/pgvector#installation).
|
||||
|
||||
1. Configure environment:
|
||||
3. Configure environment:
|
||||
|
||||
```bash
|
||||
# Main app env (large, app-specific: OAuth secrets, LLM keys, etc.)
|
||||
cp apps/sim/.env.example apps/sim/.env
|
||||
# Create your secrets
|
||||
perl -i -pe "s/your_encryption_key/$(openssl rand -hex 32)/" apps/sim/.env
|
||||
perl -i -pe "s/your_internal_api_secret/$(openssl rand -hex 32)/" apps/sim/.env
|
||||
perl -i -pe "s/your_api_encryption_key/$(openssl rand -hex 32)/" apps/sim/.env
|
||||
|
||||
# Realtime server env (small: just the ~6 shared values)
|
||||
cp apps/realtime/.env.example apps/realtime/.env
|
||||
# Copy DATABASE_URL, BETTER_AUTH_URL, BETTER_AUTH_SECRET, INTERNAL_API_SECRET,
|
||||
# and NEXT_PUBLIC_APP_URL from apps/sim/.env into apps/realtime/.env so both
|
||||
# services use the same auth secret and DB.
|
||||
|
||||
# DB migration env
|
||||
# DB configs for migration
|
||||
cp packages/db/.env.example packages/db/.env
|
||||
|
||||
# Edit each .env to set DATABASE_URL="postgresql://postgres:your_password@localhost:5432/simstudio"
|
||||
# Edit both .env files to set DATABASE_URL="postgresql://postgres:your_password@localhost:5432/simstudio"
|
||||
```
|
||||
|
||||
We use per-app `.env` files (the Turborepo-canonical pattern) rather than a
|
||||
single root `.env`. This mirrors production — each service has its own env
|
||||
block in Docker Compose / k8s — and keeps sim's app secrets (OAuth, LLM keys,
|
||||
Stripe, etc.) out of the realtime server's process scope. The shared values
|
||||
(DATABASE_URL, BETTER_AUTH_SECRET, INTERNAL_API_SECRET, etc.) are duplicated
|
||||
across `apps/sim/.env` and `apps/realtime/.env`; that's the trade-off.
|
||||
|
||||
Production uses env vars passed through Docker Compose / Kubernetes directly
|
||||
and does not read any `.env` files.
|
||||
|
||||
1. Run migrations:
|
||||
4. Run migrations:
|
||||
|
||||
```bash
|
||||
cd packages/db && bun run db:migrate
|
||||
```
|
||||
|
||||
1. Start development servers:
|
||||
5. Start development servers:
|
||||
|
||||
```bash
|
||||
bun run dev:full # Starts Next.js app and realtime socket server
|
||||
```
|
||||
|
||||
Or run separately: `bun run dev` (Next.js) and `bun run dev:sockets` (realtime). All scripts run from the repo root.
|
||||
Or run separately: `bun run dev` (Next.js) and `cd apps/sim && bun run dev:sockets` (realtime).
|
||||
|
||||
## Copilot API Keys
|
||||
|
||||
Copilot is a Sim-managed service. To use Copilot on a self-hosted instance:
|
||||
|
||||
- Go to [https://sim.ai](https://sim.ai) → Settings → Copilot and generate a Copilot API key
|
||||
- Set `COPILOT_API_KEY` in `apps/sim/.env` to that value
|
||||
- Go to https://sim.ai → Settings → Copilot and generate a Copilot API key
|
||||
- Set `COPILOT_API_KEY` environment variable in your self-hosted apps/sim/.env file to that value
|
||||
|
||||
## Environment Variables
|
||||
|
||||
See the [environment variables reference](https://docs.sim.ai/self-hosting/environment-variables) for the full list, or [`apps/sim/.env.example`](apps/sim/.env.example) (main app) and [`apps/realtime/.env.example`](apps/realtime/.env.example) (realtime server) for defaults.
|
||||
See the [environment variables reference](https://docs.sim.ai/self-hosting/environment-variables) for the full list, or [`apps/sim/.env.example`](apps/sim/.env.example) for defaults.
|
||||
|
||||
## Tech Stack
|
||||
|
||||
@@ -164,4 +160,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.
|
||||
|
||||
Made with ❤️ by the Sim Team
|
||||
<p align="center">Made with ❤️ by the Sim Team</p>
|
||||
|
||||
@@ -35,13 +35,13 @@
|
||||
"postgres": "^3.4.5",
|
||||
"redis": "5.10.0",
|
||||
"socket.io": "^4.8.1",
|
||||
"socket.io-client": "4.8.1",
|
||||
"zod": "^3.24.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sim/testing": "workspace:*",
|
||||
"@sim/tsconfig": "workspace:*",
|
||||
"@types/node": "24.2.1",
|
||||
"socket.io-client": "4.8.1",
|
||||
"typescript": "^5.7.3",
|
||||
"vitest": "^3.0.8"
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ vi.mock('@/serializer', () => ({
|
||||
Serializer: vi.fn(),
|
||||
}))
|
||||
|
||||
vi.mock('@/lib/workflows/subblocks', () => ({
|
||||
vi.mock('@sim/workflow-persistence/subblocks', () => ({
|
||||
mergeSubblockStateWithValues: mockMergeSubblockStateWithValues,
|
||||
mergeSubBlockValues: mockMergeSubBlockValues,
|
||||
}))
|
||||
|
||||
@@ -59,7 +59,7 @@ vi.mock('@/lib/logs/execution/trace-spans/trace-spans', () => ({
|
||||
|
||||
vi.mock('@/lib/workflows/persistence/utils', () => workflowsPersistenceUtilsMock)
|
||||
|
||||
vi.mock('@/lib/workflows/subblocks', () => ({
|
||||
vi.mock('@sim/workflow-persistence/subblocks', () => ({
|
||||
mergeSubblockStateWithValues: mergeSubblockStateWithValuesMock,
|
||||
}))
|
||||
|
||||
|
||||
6
bun.lock
6
bun.lock
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"lockfileVersion": 1,
|
||||
"configVersion": 0,
|
||||
"workspaces": {
|
||||
"": {
|
||||
"name": "simstudio",
|
||||
@@ -68,13 +69,13 @@
|
||||
"postgres": "^3.4.5",
|
||||
"redis": "5.10.0",
|
||||
"socket.io": "^4.8.1",
|
||||
"socket.io-client": "4.8.1",
|
||||
"zod": "^3.24.2",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sim/testing": "workspace:*",
|
||||
"@sim/tsconfig": "workspace:*",
|
||||
"@types/node": "24.2.1",
|
||||
"socket.io-client": "4.8.1",
|
||||
"typescript": "^5.7.3",
|
||||
"vitest": "^3.0.8",
|
||||
},
|
||||
@@ -301,8 +302,10 @@
|
||||
"drizzle-orm": "^0.45.2",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sim/testing": "workspace:*",
|
||||
"@sim/tsconfig": "workspace:*",
|
||||
"typescript": "^5.7.3",
|
||||
"vitest": "^3.0.8",
|
||||
},
|
||||
},
|
||||
"packages/auth": {
|
||||
@@ -442,6 +445,7 @@
|
||||
"dependencies": {
|
||||
"@sim/db": "workspace:*",
|
||||
"@sim/logger": "workspace:*",
|
||||
"@sim/utils": "workspace:*",
|
||||
"@sim/workflow-types": "workspace:*",
|
||||
"drizzle-orm": "^0.45.2",
|
||||
"reactflow": "^11.11.4",
|
||||
|
||||
@@ -18,13 +18,30 @@ FROM base AS deps
|
||||
WORKDIR /app
|
||||
|
||||
COPY package.json bun.lock turbo.json ./
|
||||
RUN mkdir -p apps packages/db packages/testing packages/logger packages/tsconfig packages/utils
|
||||
RUN mkdir -p apps \
|
||||
packages/audit \
|
||||
packages/db \
|
||||
packages/logger \
|
||||
packages/realtime-protocol \
|
||||
packages/security \
|
||||
packages/testing \
|
||||
packages/tsconfig \
|
||||
packages/utils \
|
||||
packages/workflow-authz \
|
||||
packages/workflow-persistence \
|
||||
packages/workflow-types
|
||||
COPY apps/sim/package.json ./apps/sim/package.json
|
||||
COPY packages/audit/package.json ./packages/audit/package.json
|
||||
COPY packages/db/package.json ./packages/db/package.json
|
||||
COPY packages/testing/package.json ./packages/testing/package.json
|
||||
COPY packages/logger/package.json ./packages/logger/package.json
|
||||
COPY packages/realtime-protocol/package.json ./packages/realtime-protocol/package.json
|
||||
COPY packages/security/package.json ./packages/security/package.json
|
||||
COPY packages/testing/package.json ./packages/testing/package.json
|
||||
COPY packages/tsconfig/package.json ./packages/tsconfig/package.json
|
||||
COPY packages/utils/package.json ./packages/utils/package.json
|
||||
COPY packages/workflow-authz/package.json ./packages/workflow-authz/package.json
|
||||
COPY packages/workflow-persistence/package.json ./packages/workflow-persistence/package.json
|
||||
COPY packages/workflow-types/package.json ./packages/workflow-types/package.json
|
||||
|
||||
# Install dependencies, then rebuild isolated-vm for Node.js
|
||||
# Use --linker=hoisted for flat node_modules layout (required for Docker multi-stage builds)
|
||||
@@ -49,10 +66,17 @@ COPY --from=deps /app/node_modules ./node_modules
|
||||
# Copy package configuration files (needed for build)
|
||||
COPY package.json bun.lock turbo.json ./
|
||||
COPY apps/sim/package.json ./apps/sim/package.json
|
||||
COPY packages/audit/package.json ./packages/audit/package.json
|
||||
COPY packages/db/package.json ./packages/db/package.json
|
||||
COPY packages/testing/package.json ./packages/testing/package.json
|
||||
COPY packages/logger/package.json ./packages/logger/package.json
|
||||
COPY packages/realtime-protocol/package.json ./packages/realtime-protocol/package.json
|
||||
COPY packages/security/package.json ./packages/security/package.json
|
||||
COPY packages/testing/package.json ./packages/testing/package.json
|
||||
COPY packages/tsconfig/package.json ./packages/tsconfig/package.json
|
||||
COPY packages/utils/package.json ./packages/utils/package.json
|
||||
COPY packages/workflow-authz/package.json ./packages/workflow-authz/package.json
|
||||
COPY packages/workflow-persistence/package.json ./packages/workflow-persistence/package.json
|
||||
COPY packages/workflow-types/package.json ./packages/workflow-types/package.json
|
||||
|
||||
# Copy workspace configuration files (needed for turbo)
|
||||
COPY apps/sim/next.config.ts ./apps/sim/next.config.ts
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
"lint:helm": "helm lint ./helm/sim --strict --values ./helm/sim/test/values-lint.yaml",
|
||||
"lint:all": "turbo run lint && bun run lint:helm",
|
||||
"check": "turbo run format:check",
|
||||
"check:boundaries": "bun run scripts/check-monorepo-boundaries.ts",
|
||||
"check:realtime-prune": "bun run scripts/check-realtime-prune-graph.ts",
|
||||
"mship-contracts:generate": "bun run scripts/sync-mothership-stream-contract.ts",
|
||||
"mship-contracts:check": "bun run scripts/sync-mothership-stream-contract.ts --check",
|
||||
"mship-tools:generate": "bun run scripts/sync-tool-catalog.ts",
|
||||
|
||||
@@ -20,7 +20,9 @@
|
||||
"lint": "biome check --write --unsafe .",
|
||||
"lint:check": "biome check .",
|
||||
"format": "biome format --write .",
|
||||
"format:check": "biome format ."
|
||||
"format:check": "biome format .",
|
||||
"test": "vitest run",
|
||||
"test:watch": "vitest"
|
||||
},
|
||||
"dependencies": {
|
||||
"@sim/db": "workspace:*",
|
||||
@@ -29,7 +31,9 @@
|
||||
"drizzle-orm": "^0.45.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sim/testing": "workspace:*",
|
||||
"@sim/tsconfig": "workspace:*",
|
||||
"typescript": "^5.7.3"
|
||||
"typescript": "^5.7.3",
|
||||
"vitest": "^3.0.8"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,21 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
vi.mock('@sim/db', () => ({
|
||||
...dbChainMock,
|
||||
auditLog: { id: 'id', workspaceId: 'workspace_id' },
|
||||
user: { id: 'id', name: 'name', email: 'email' },
|
||||
}))
|
||||
vi.mock('drizzle-orm', () => ({
|
||||
eq: vi.fn(),
|
||||
and: vi.fn(),
|
||||
or: vi.fn(),
|
||||
sql: vi.fn(),
|
||||
}))
|
||||
vi.mock('@sim/logger', () => ({
|
||||
createLogger: () => ({
|
||||
info: vi.fn(),
|
||||
warn: vi.fn(),
|
||||
error: vi.fn(),
|
||||
debug: vi.fn(),
|
||||
}),
|
||||
}))
|
||||
vi.mock('@sim/utils/id', () => ({
|
||||
generateId: () => 'test-uuid-123',
|
||||
|
||||
9
packages/audit/vitest.config.ts
Normal file
9
packages/audit/vitest.config.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { defineConfig } from 'vitest/config'
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
globals: false,
|
||||
environment: 'node',
|
||||
include: ['src/**/*.test.ts'],
|
||||
},
|
||||
})
|
||||
@@ -41,6 +41,7 @@
|
||||
"dependencies": {
|
||||
"@sim/db": "workspace:*",
|
||||
"@sim/logger": "workspace:*",
|
||||
"@sim/utils": "workspace:*",
|
||||
"@sim/workflow-types": "workspace:*",
|
||||
"drizzle-orm": "^0.45.2",
|
||||
"reactflow": "^11.11.4"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { db, workflowBlocks, workflowEdges, workflowSubflows } from '@sim/db'
|
||||
import { createLogger } from '@sim/logger'
|
||||
import { toError } from '@sim/utils/errors'
|
||||
import type { BlockState, WorkflowState } from '@sim/workflow-types/workflow'
|
||||
import { SUBFLOW_TYPES } from '@sim/workflow-types/workflow'
|
||||
import type { InferInsertModel } from 'drizzle-orm'
|
||||
@@ -101,7 +102,7 @@ export async function saveWorkflowToNormalizedTables(
|
||||
logger.error(`Error saving workflow ${workflowId} to normalized tables:`, error)
|
||||
return {
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : 'Unknown error',
|
||||
error: toError(error).message,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,13 @@ import type { BlockState, SubBlockState } from '@sim/workflow-types/workflow'
|
||||
|
||||
export const DEFAULT_SUBBLOCK_TYPE = 'short-input'
|
||||
|
||||
/**
|
||||
* Merges subblock values into the provided subblock structures.
|
||||
* Falls back to a default subblock shape when a value has no structure.
|
||||
* @param subBlocks - Existing subblock definitions from the workflow
|
||||
* @param values - Stored subblock values keyed by subblock id
|
||||
* @returns Merged subblock structures with updated values
|
||||
*/
|
||||
export function mergeSubBlockValues(
|
||||
subBlocks: Record<string, unknown> | undefined,
|
||||
values: Record<string, unknown> | undefined
|
||||
@@ -29,6 +36,14 @@ export function mergeSubBlockValues(
|
||||
return merged
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges workflow block states with explicit subblock values while maintaining block structure.
|
||||
* Values that are null or undefined do not override existing subblock values.
|
||||
* @param blocks - Block configurations from workflow state
|
||||
* @param subBlockValues - Subblock values keyed by blockId -> subBlockId -> value
|
||||
* @param blockId - Optional specific block ID to merge (merges all if not provided)
|
||||
* @returns Merged block states with updated subblocks
|
||||
*/
|
||||
export function mergeSubblockStateWithValues(
|
||||
blocks: Record<string, BlockState>,
|
||||
subBlockValues: Record<string, Record<string, unknown>> = {},
|
||||
|
||||
Reference in New Issue
Block a user