├── .devcontainer
├── .bashrc
├── Dockerfile
├── README.md
├── devcontainer.json
├── docker-compose.yml
└── post-create.sh
├── .dockerignore
├── .github
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── PULL_REQUEST_TEMPLATE.md
├── SECURITY.md
└── workflows
│ ├── build.yml
│ ├── ci.yml
│ └── publish-cli.yml
├── .gitignore
├── .husky
└── pre-commit
├── .npmrc
├── LICENSE
├── NOTICE
├── README.md
├── apps
├── docs
│ ├── .gitignore
│ ├── README.md
│ ├── app
│ │ ├── (docs)
│ │ │ ├── [[...slug]]
│ │ │ │ ├── layout.tsx
│ │ │ │ └── page.tsx
│ │ │ └── layout.tsx
│ │ ├── api
│ │ │ └── search
│ │ │ │ └── route.ts
│ │ ├── global.css
│ │ ├── layout.config.tsx
│ │ └── layout.tsx
│ ├── components
│ │ ├── icons.tsx
│ │ ├── mdx-components.tsx
│ │ └── ui
│ │ │ ├── block-info-card.tsx
│ │ │ ├── block-types.tsx
│ │ │ ├── features.tsx
│ │ │ └── theme-image.tsx
│ ├── content
│ │ └── docs
│ │ │ ├── blocks
│ │ │ ├── agent.mdx
│ │ │ ├── api.mdx
│ │ │ ├── condition.mdx
│ │ │ ├── evaluator.mdx
│ │ │ ├── function.mdx
│ │ │ ├── index.mdx
│ │ │ ├── meta.json
│ │ │ └── router.mdx
│ │ │ ├── connections
│ │ │ ├── accessing-data.mdx
│ │ │ ├── basics.mdx
│ │ │ ├── best-practices.mdx
│ │ │ ├── data-structure.mdx
│ │ │ ├── index.mdx
│ │ │ ├── meta.json
│ │ │ └── tags.mdx
│ │ │ ├── execution
│ │ │ ├── advanced.mdx
│ │ │ ├── basics.mdx
│ │ │ ├── index.mdx
│ │ │ ├── loops.mdx
│ │ │ └── meta.json
│ │ │ ├── getting-started
│ │ │ └── index.mdx
│ │ │ ├── introduction
│ │ │ ├── index.mdx
│ │ │ └── meta.json
│ │ │ ├── meta.json
│ │ │ ├── tools
│ │ │ ├── airtable.mdx
│ │ │ ├── autoblocks.mdx
│ │ │ ├── browser_use.mdx
│ │ │ ├── clay.mdx
│ │ │ ├── confluence.mdx
│ │ │ ├── discord.mdx
│ │ │ ├── elevenlabs.mdx
│ │ │ ├── exa.mdx
│ │ │ ├── file.mdx
│ │ │ ├── firecrawl.mdx
│ │ │ ├── github.mdx
│ │ │ ├── gmail.mdx
│ │ │ ├── google_docs.mdx
│ │ │ ├── google_drive.mdx
│ │ │ ├── google_search.mdx
│ │ │ ├── google_sheets.mdx
│ │ │ ├── guesty.mdx
│ │ │ ├── image_generator.mdx
│ │ │ ├── index.mdx
│ │ │ ├── jina.mdx
│ │ │ ├── jira.mdx
│ │ │ ├── linear.mdx
│ │ │ ├── linkup.mdx
│ │ │ ├── mem0.mdx
│ │ │ ├── memory.mdx
│ │ │ ├── meta.json
│ │ │ ├── microsoft_excel.mdx
│ │ │ ├── microsoft_teams.mdx
│ │ │ ├── mistral_parse.mdx
│ │ │ ├── notion.mdx
│ │ │ ├── openai.mdx
│ │ │ ├── outlook.mdx
│ │ │ ├── perplexity.mdx
│ │ │ ├── pinecone.mdx
│ │ │ ├── reddit.mdx
│ │ │ ├── s3.mdx
│ │ │ ├── serper.mdx
│ │ │ ├── slack.mdx
│ │ │ ├── stagehand.mdx
│ │ │ ├── stagehand_agent.mdx
│ │ │ ├── supabase.mdx
│ │ │ ├── tavily.mdx
│ │ │ ├── telegram.mdx
│ │ │ ├── thinking.mdx
│ │ │ ├── translate.mdx
│ │ │ ├── twilio_sms.mdx
│ │ │ ├── typeform.mdx
│ │ │ ├── vision.mdx
│ │ │ ├── whatsapp.mdx
│ │ │ ├── x.mdx
│ │ │ └── youtube.mdx
│ │ │ └── variables
│ │ │ ├── index.mdx
│ │ │ └── meta.json
│ ├── lib
│ │ ├── source.ts
│ │ └── utils.ts
│ ├── next.config.ts
│ ├── package.json
│ ├── postcss.config.mjs
│ ├── public
│ │ ├── connections.mp4
│ │ ├── favicon
│ │ │ ├── android-chrome-192x192.png
│ │ │ ├── android-chrome-512x512.png
│ │ │ ├── apple-touch-icon.png
│ │ │ ├── favicon-16x16.png
│ │ │ ├── favicon-32x32.png
│ │ │ ├── favicon.ico
│ │ │ └── site.webmanifest
│ │ ├── loops.mp4
│ │ └── static
│ │ │ ├── dark
│ │ │ ├── agent-dark.png
│ │ │ ├── api-dark.png
│ │ │ ├── condition-dark.png
│ │ │ ├── evaluator-dark.png
│ │ │ ├── function-dark.png
│ │ │ ├── router-dark.png
│ │ │ ├── tooldropdown-dark.png
│ │ │ ├── variabledropdown-dark.png
│ │ │ └── variables-dark.png
│ │ │ └── light
│ │ │ ├── agent-light.png
│ │ │ ├── api-light.png
│ │ │ ├── condition-light.png
│ │ │ ├── evaluator-light.png
│ │ │ ├── function-light.png
│ │ │ ├── router-light.png
│ │ │ ├── tooldropdown-light.png
│ │ │ ├── variabledropdown-light.png
│ │ │ └── variables-light.png
│ ├── source.config.ts
│ └── tsconfig.json
└── sim
│ ├── .env.example
│ ├── .gitignore
│ ├── app
│ ├── (auth)
│ │ ├── components
│ │ │ ├── oauth-provider-checker.tsx
│ │ │ └── social-login-buttons.tsx
│ │ ├── layout.tsx
│ │ ├── login
│ │ │ ├── login-form.test.tsx
│ │ │ ├── login-form.tsx
│ │ │ └── page.tsx
│ │ ├── reset-password
│ │ │ ├── page.tsx
│ │ │ └── reset-password-form.tsx
│ │ ├── signup
│ │ │ ├── page.tsx
│ │ │ ├── signup-form.test.tsx
│ │ │ └── signup-form.tsx
│ │ └── verify
│ │ │ ├── page.tsx
│ │ │ ├── use-verification.ts
│ │ │ └── verify-content.tsx
│ ├── (landing)
│ │ ├── actions
│ │ │ └── github.ts
│ │ ├── components
│ │ │ ├── blog-card.tsx
│ │ │ ├── dot-pattern.tsx
│ │ │ ├── github-stars-client.tsx
│ │ │ ├── github-stars.tsx
│ │ │ ├── grid-pattern.tsx
│ │ │ ├── hero-block.tsx
│ │ │ ├── hero-edge.tsx
│ │ │ ├── hero-workflow.tsx
│ │ │ ├── hooks
│ │ │ │ └── use-is-mobile.tsx
│ │ │ ├── magicui
│ │ │ │ ├── marquee.tsx
│ │ │ │ └── orbiting-circles.tsx
│ │ │ ├── nav-client.tsx
│ │ │ ├── nav-wrapper.tsx
│ │ │ ├── sections
│ │ │ │ ├── blogs.tsx
│ │ │ │ ├── features.tsx
│ │ │ │ ├── footer.tsx
│ │ │ │ ├── hero.tsx
│ │ │ │ ├── integrations.tsx
│ │ │ │ └── testimonials.tsx
│ │ │ ├── use-window-size.ts
│ │ │ └── waitlist-form.tsx
│ │ ├── contributors
│ │ │ └── page.tsx
│ │ ├── landing.tsx
│ │ ├── privacy
│ │ │ └── page.tsx
│ │ ├── terms
│ │ │ └── page.tsx
│ │ └── utils
│ │ │ ├── github.ts
│ │ │ └── prefetch.ts
│ ├── api
│ │ ├── __test-utils__
│ │ │ ├── setup.ts
│ │ │ └── utils.ts
│ │ ├── auth
│ │ │ ├── [...all]
│ │ │ │ └── route.ts
│ │ │ ├── forget-password
│ │ │ │ ├── route.test.ts
│ │ │ │ └── route.ts
│ │ │ ├── oauth
│ │ │ │ ├── connections
│ │ │ │ │ ├── route.test.ts
│ │ │ │ │ └── route.ts
│ │ │ │ ├── credentials
│ │ │ │ │ ├── route.test.ts
│ │ │ │ │ └── route.ts
│ │ │ │ ├── disconnect
│ │ │ │ │ ├── route.test.ts
│ │ │ │ │ └── route.ts
│ │ │ │ ├── microsoft
│ │ │ │ │ ├── file
│ │ │ │ │ │ └── route.ts
│ │ │ │ │ └── files
│ │ │ │ │ │ └── route.ts
│ │ │ │ ├── token
│ │ │ │ │ ├── route.test.ts
│ │ │ │ │ └── route.ts
│ │ │ │ ├── utils.test.ts
│ │ │ │ └── utils.ts
│ │ │ ├── reset-password
│ │ │ │ └── route.ts
│ │ │ └── verify-waitlist-token
│ │ │ │ └── route.ts
│ │ ├── chat
│ │ │ ├── [subdomain]
│ │ │ │ ├── otp
│ │ │ │ │ └── route.ts
│ │ │ │ ├── route.test.ts
│ │ │ │ └── route.ts
│ │ │ ├── edit
│ │ │ │ └── [id]
│ │ │ │ │ └── route.ts
│ │ │ ├── route.test.ts
│ │ │ ├── route.ts
│ │ │ ├── subdomains
│ │ │ │ └── validate
│ │ │ │ │ ├── route.test.ts
│ │ │ │ │ └── route.ts
│ │ │ ├── utils.test.ts
│ │ │ └── utils.ts
│ │ ├── codegen
│ │ │ ├── route.test.ts
│ │ │ └── route.ts
│ │ ├── copilot
│ │ │ └── route.ts
│ │ ├── environment
│ │ │ └── route.ts
│ │ ├── files
│ │ │ ├── delete
│ │ │ │ ├── route.test.ts
│ │ │ │ └── route.ts
│ │ │ ├── parse
│ │ │ │ ├── route.test.ts
│ │ │ │ └── route.ts
│ │ │ ├── presigned
│ │ │ │ └── route.ts
│ │ │ ├── serve
│ │ │ │ └── [...path]
│ │ │ │ │ ├── route.test.ts
│ │ │ │ │ └── route.ts
│ │ │ ├── upload
│ │ │ │ ├── route.test.ts
│ │ │ │ └── route.ts
│ │ │ └── utils.ts
│ │ ├── function
│ │ │ └── execute
│ │ │ │ └── route.ts
│ │ ├── help
│ │ │ └── route.ts
│ │ ├── knowledge
│ │ │ ├── [id]
│ │ │ │ ├── documents
│ │ │ │ │ ├── [documentId]
│ │ │ │ │ │ ├── chunks
│ │ │ │ │ │ │ ├── [chunkId]
│ │ │ │ │ │ │ │ └── route.ts
│ │ │ │ │ │ │ └── route.ts
│ │ │ │ │ │ └── route.ts
│ │ │ │ │ └── route.ts
│ │ │ │ ├── process-documents
│ │ │ │ │ └── route.ts
│ │ │ │ └── route.ts
│ │ │ ├── route.ts
│ │ │ └── search
│ │ │ │ └── route.ts
│ │ ├── logs
│ │ │ ├── cleanup
│ │ │ │ └── route.ts
│ │ │ ├── route.test.ts
│ │ │ └── route.ts
│ │ ├── marketplace
│ │ │ ├── [id]
│ │ │ │ ├── info
│ │ │ │ │ └── route.ts
│ │ │ │ ├── unpublish
│ │ │ │ │ └── route.ts
│ │ │ │ └── view
│ │ │ │ │ └── route.ts
│ │ │ ├── publish
│ │ │ │ └── route.ts
│ │ │ └── workflows
│ │ │ │ └── route.ts
│ │ ├── memory
│ │ │ ├── [id]
│ │ │ │ └── route.ts
│ │ │ └── route.ts
│ │ ├── providers
│ │ │ └── route.ts
│ │ ├── proxy
│ │ │ ├── image
│ │ │ │ └── route.ts
│ │ │ ├── route.ts
│ │ │ └── tts
│ │ │ │ └── route.ts
│ │ ├── schedules
│ │ │ ├── [id]
│ │ │ │ ├── route.ts
│ │ │ │ └── status
│ │ │ │ │ ├── route.test.ts
│ │ │ │ │ └── route.ts
│ │ │ ├── execute
│ │ │ │ ├── route.test.ts
│ │ │ │ └── route.ts
│ │ │ ├── route.test.ts
│ │ │ └── route.ts
│ │ ├── telemetry
│ │ │ └── route.ts
│ │ ├── tools
│ │ │ ├── confluence
│ │ │ │ ├── page
│ │ │ │ │ └── route.ts
│ │ │ │ └── pages
│ │ │ │ │ └── route.ts
│ │ │ ├── custom
│ │ │ │ ├── route.test.ts
│ │ │ │ └── route.ts
│ │ │ ├── discord
│ │ │ │ ├── channels
│ │ │ │ │ └── route.ts
│ │ │ │ └── servers
│ │ │ │ │ └── route.ts
│ │ │ ├── drive
│ │ │ │ ├── file
│ │ │ │ │ └── route.ts
│ │ │ │ └── files
│ │ │ │ │ └── route.ts
│ │ │ ├── gmail
│ │ │ │ ├── label
│ │ │ │ │ └── route.ts
│ │ │ │ └── labels
│ │ │ │ │ └── route.ts
│ │ │ ├── jira
│ │ │ │ ├── issue
│ │ │ │ │ └── route.ts
│ │ │ │ ├── issues
│ │ │ │ │ └── route.ts
│ │ │ │ └── projects
│ │ │ │ │ └── route.ts
│ │ │ ├── linear
│ │ │ │ ├── projects
│ │ │ │ │ └── route.ts
│ │ │ │ └── teams
│ │ │ │ │ └── route.ts
│ │ │ ├── microsoft-teams
│ │ │ │ ├── channels
│ │ │ │ │ └── route.ts
│ │ │ │ ├── chats
│ │ │ │ │ └── route.ts
│ │ │ │ └── teams
│ │ │ │ │ └── route.ts
│ │ │ ├── outlook
│ │ │ │ └── folders
│ │ │ │ │ └── route.ts
│ │ │ ├── slack
│ │ │ │ └── channels
│ │ │ │ │ └── route.ts
│ │ │ └── stagehand
│ │ │ │ ├── agent
│ │ │ │ └── route.ts
│ │ │ │ ├── extract
│ │ │ │ └── route.ts
│ │ │ │ └── utils.ts
│ │ ├── user
│ │ │ ├── api-keys
│ │ │ │ ├── [id]
│ │ │ │ │ └── route.ts
│ │ │ │ └── route.ts
│ │ │ ├── settings
│ │ │ │ └── route.ts
│ │ │ ├── stats
│ │ │ │ └── route.ts
│ │ │ ├── subscription
│ │ │ │ ├── [id]
│ │ │ │ │ ├── seats
│ │ │ │ │ │ ├── route.test.ts
│ │ │ │ │ │ └── route.ts
│ │ │ │ │ └── transfer
│ │ │ │ │ │ ├── route.test.ts
│ │ │ │ │ │ └── route.ts
│ │ │ │ ├── enterprise
│ │ │ │ │ └── route.ts
│ │ │ │ └── route.ts
│ │ │ └── usage
│ │ │ │ └── route.ts
│ │ ├── waitlist
│ │ │ └── route.ts
│ │ ├── webhooks
│ │ │ ├── [id]
│ │ │ │ └── route.ts
│ │ │ ├── poll
│ │ │ │ └── gmail
│ │ │ │ │ └── route.ts
│ │ │ ├── route.ts
│ │ │ ├── test
│ │ │ │ └── route.ts
│ │ │ └── trigger
│ │ │ │ └── [path]
│ │ │ │ ├── route.test.ts
│ │ │ │ └── route.ts
│ │ ├── workflows
│ │ │ ├── [id]
│ │ │ │ ├── chat
│ │ │ │ │ └── status
│ │ │ │ │ │ └── route.ts
│ │ │ │ ├── deploy
│ │ │ │ │ ├── route.test.ts
│ │ │ │ │ └── route.ts
│ │ │ │ ├── deployed
│ │ │ │ │ └── route.ts
│ │ │ │ ├── execute
│ │ │ │ │ ├── route.test.ts
│ │ │ │ │ └── route.ts
│ │ │ │ ├── log
│ │ │ │ │ └── route.ts
│ │ │ │ ├── stats
│ │ │ │ │ └── route.ts
│ │ │ │ ├── status
│ │ │ │ │ └── route.ts
│ │ │ │ └── variables
│ │ │ │ │ └── route.ts
│ │ │ ├── middleware.ts
│ │ │ ├── public
│ │ │ │ └── [id]
│ │ │ │ │ └── route.ts
│ │ │ ├── sync
│ │ │ │ └── route.ts
│ │ │ └── utils.ts
│ │ └── workspaces
│ │ │ ├── [id]
│ │ │ └── route.ts
│ │ │ ├── invitations
│ │ │ ├── accept
│ │ │ │ └── route.ts
│ │ │ ├── details
│ │ │ │ └── route.ts
│ │ │ └── route.ts
│ │ │ ├── members
│ │ │ ├── [id]
│ │ │ │ └── route.ts
│ │ │ └── route.ts
│ │ │ └── route.ts
│ ├── chat
│ │ └── [subdomain]
│ │ │ ├── chat-client.tsx
│ │ │ ├── components
│ │ │ ├── auth
│ │ │ │ ├── email
│ │ │ │ │ └── email-auth.tsx
│ │ │ │ └── password
│ │ │ │ │ └── password-auth.tsx
│ │ │ ├── chat-client.tsx
│ │ │ ├── components
│ │ │ │ ├── header-links
│ │ │ │ │ └── header-links.tsx
│ │ │ │ └── markdown-renderer
│ │ │ │ │ └── markdown-renderer.tsx
│ │ │ ├── error-state
│ │ │ │ └── error-state.tsx
│ │ │ ├── header
│ │ │ │ └── header.tsx
│ │ │ ├── input
│ │ │ │ └── input.tsx
│ │ │ ├── loading-state
│ │ │ │ └── loading-state.tsx
│ │ │ ├── message-container
│ │ │ │ └── message-container.tsx
│ │ │ └── message
│ │ │ │ ├── components
│ │ │ │ └── markdown-renderer.tsx
│ │ │ │ └── message.tsx
│ │ │ ├── hooks
│ │ │ └── use-chat-streaming.ts
│ │ │ └── page.tsx
│ ├── favicon.ico
│ ├── global-error.tsx
│ ├── globals.css
│ ├── invite
│ │ ├── [id]
│ │ │ ├── invite.tsx
│ │ │ └── page.tsx
│ │ └── invite-error
│ │ │ ├── invite-error.tsx
│ │ │ └── page.tsx
│ ├── layout.tsx
│ ├── page.tsx
│ ├── telemetry-consent-dialog.tsx
│ ├── w
│ │ ├── [id]
│ │ │ ├── components
│ │ │ │ ├── code-prompt-bar
│ │ │ │ │ └── code-prompt-bar.tsx
│ │ │ │ ├── control-bar
│ │ │ │ │ ├── components
│ │ │ │ │ │ ├── deploy-modal
│ │ │ │ │ │ │ ├── components
│ │ │ │ │ │ │ │ ├── chat-deploy
│ │ │ │ │ │ │ │ │ └── chat-deploy.tsx
│ │ │ │ │ │ │ │ ├── deploy-form
│ │ │ │ │ │ │ │ │ └── deploy-form.tsx
│ │ │ │ │ │ │ │ └── deployment-info
│ │ │ │ │ │ │ │ │ ├── components
│ │ │ │ │ │ │ │ │ ├── api-endpoint
│ │ │ │ │ │ │ │ │ │ └── api-endpoint.tsx
│ │ │ │ │ │ │ │ │ ├── api-key
│ │ │ │ │ │ │ │ │ │ └── api-key.tsx
│ │ │ │ │ │ │ │ │ ├── deploy-status
│ │ │ │ │ │ │ │ │ │ └── deploy-status.tsx
│ │ │ │ │ │ │ │ │ └── example-command
│ │ │ │ │ │ │ │ │ │ └── example-command.tsx
│ │ │ │ │ │ │ │ │ └── deployment-info.tsx
│ │ │ │ │ │ │ └── deploy-modal.tsx
│ │ │ │ │ │ ├── deployment-controls
│ │ │ │ │ │ │ ├── components
│ │ │ │ │ │ │ │ ├── deployed-workflow-card.tsx
│ │ │ │ │ │ │ │ └── deployed-workflow-modal.tsx
│ │ │ │ │ │ │ └── deployment-controls.tsx
│ │ │ │ │ │ ├── history-dropdown-item
│ │ │ │ │ │ │ └── history-dropdown-item.tsx
│ │ │ │ │ │ ├── marketplace-modal
│ │ │ │ │ │ │ └── marketplace-modal.tsx
│ │ │ │ │ │ └── notification-dropdown-item
│ │ │ │ │ │ │ └── notification-dropdown-item.tsx
│ │ │ │ │ └── control-bar.tsx
│ │ │ │ ├── copilot
│ │ │ │ │ └── copilot.tsx
│ │ │ │ ├── error
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── loop-node
│ │ │ │ │ ├── components
│ │ │ │ │ │ ├── loop-badges.test.tsx
│ │ │ │ │ │ └── loop-badges.tsx
│ │ │ │ │ ├── loop-config.ts
│ │ │ │ │ ├── loop-node.test.tsx
│ │ │ │ │ └── loop-node.tsx
│ │ │ │ ├── notifications
│ │ │ │ │ └── notifications.tsx
│ │ │ │ ├── panel
│ │ │ │ │ ├── components
│ │ │ │ │ │ ├── chat
│ │ │ │ │ │ │ ├── chat.tsx
│ │ │ │ │ │ │ └── components
│ │ │ │ │ │ │ │ ├── chat-message
│ │ │ │ │ │ │ │ └── chat-message.tsx
│ │ │ │ │ │ │ │ ├── chat-modal
│ │ │ │ │ │ │ │ └── chat-modal.tsx
│ │ │ │ │ │ │ │ └── output-select
│ │ │ │ │ │ │ │ └── output-select.tsx
│ │ │ │ │ │ ├── console
│ │ │ │ │ │ │ ├── components
│ │ │ │ │ │ │ │ ├── audio-player
│ │ │ │ │ │ │ │ │ └── audio-player.tsx
│ │ │ │ │ │ │ │ ├── console-entry
│ │ │ │ │ │ │ │ │ └── console-entry.tsx
│ │ │ │ │ │ │ │ └── json-view
│ │ │ │ │ │ │ │ │ └── json-view.tsx
│ │ │ │ │ │ │ └── console.tsx
│ │ │ │ │ │ └── variables
│ │ │ │ │ │ │ └── variables.tsx
│ │ │ │ │ └── panel.tsx
│ │ │ │ ├── parallel-node
│ │ │ │ │ ├── components
│ │ │ │ │ │ └── parallel-badges.tsx
│ │ │ │ │ ├── parallel-config.ts
│ │ │ │ │ ├── parallel-node.test.tsx
│ │ │ │ │ └── parallel-node.tsx
│ │ │ │ ├── toolbar
│ │ │ │ │ ├── components
│ │ │ │ │ │ ├── toolbar-block
│ │ │ │ │ │ │ └── toolbar-block.tsx
│ │ │ │ │ │ ├── toolbar-loop-block
│ │ │ │ │ │ │ └── toolbar-loop-block.tsx
│ │ │ │ │ │ ├── toolbar-parallel-block
│ │ │ │ │ │ │ └── toolbar-parallel-block.tsx
│ │ │ │ │ │ └── toolbar-tabs
│ │ │ │ │ │ │ └── toolbar-tabs.tsx
│ │ │ │ │ └── toolbar.tsx
│ │ │ │ ├── workflow-block
│ │ │ │ │ ├── components
│ │ │ │ │ │ ├── action-bar
│ │ │ │ │ │ │ └── action-bar.tsx
│ │ │ │ │ │ ├── connection-blocks
│ │ │ │ │ │ │ └── connection-blocks.tsx
│ │ │ │ │ │ └── sub-block
│ │ │ │ │ │ │ ├── components
│ │ │ │ │ │ │ ├── channel-selector
│ │ │ │ │ │ │ │ ├── channel-selector-input.tsx
│ │ │ │ │ │ │ │ └── components
│ │ │ │ │ │ │ │ │ └── slack-channel-selector.tsx
│ │ │ │ │ │ │ ├── checkbox-list.tsx
│ │ │ │ │ │ │ ├── code.tsx
│ │ │ │ │ │ │ ├── condition-input.tsx
│ │ │ │ │ │ │ ├── credential-selector
│ │ │ │ │ │ │ │ ├── components
│ │ │ │ │ │ │ │ │ └── oauth-required-modal.tsx
│ │ │ │ │ │ │ │ └── credential-selector.tsx
│ │ │ │ │ │ │ ├── date-input.tsx
│ │ │ │ │ │ │ ├── dropdown.tsx
│ │ │ │ │ │ │ ├── eval-input.tsx
│ │ │ │ │ │ │ ├── file-selector
│ │ │ │ │ │ │ │ ├── components
│ │ │ │ │ │ │ │ │ ├── confluence-file-selector.tsx
│ │ │ │ │ │ │ │ │ ├── discord-channel-selector.tsx
│ │ │ │ │ │ │ │ │ ├── google-drive-picker.tsx
│ │ │ │ │ │ │ │ │ ├── jira-issue-selector.tsx
│ │ │ │ │ │ │ │ │ ├── microsoft-file-selector.tsx
│ │ │ │ │ │ │ │ │ └── teams-message-selector.tsx
│ │ │ │ │ │ │ │ └── file-selector-input.tsx
│ │ │ │ │ │ │ ├── file-upload.tsx
│ │ │ │ │ │ │ ├── folder-selector
│ │ │ │ │ │ │ │ ├── components
│ │ │ │ │ │ │ │ │ └── folder-selector-input.tsx
│ │ │ │ │ │ │ │ └── folder-selector.tsx
│ │ │ │ │ │ │ ├── long-input.tsx
│ │ │ │ │ │ │ ├── project-selector
│ │ │ │ │ │ │ │ ├── components
│ │ │ │ │ │ │ │ │ ├── discord-server-selector.tsx
│ │ │ │ │ │ │ │ │ ├── jira-project-selector.tsx
│ │ │ │ │ │ │ │ │ ├── linear-project-selector.tsx
│ │ │ │ │ │ │ │ │ └── linear-team-selector.tsx
│ │ │ │ │ │ │ │ └── project-selector-input.tsx
│ │ │ │ │ │ │ ├── schedule
│ │ │ │ │ │ │ │ ├── components
│ │ │ │ │ │ │ │ │ └── schedule-modal.tsx
│ │ │ │ │ │ │ │ └── schedule-config.tsx
│ │ │ │ │ │ │ ├── short-input.tsx
│ │ │ │ │ │ │ ├── slider-input.tsx
│ │ │ │ │ │ │ ├── starter
│ │ │ │ │ │ │ │ └── input-format.tsx
│ │ │ │ │ │ │ ├── switch.tsx
│ │ │ │ │ │ │ ├── table.tsx
│ │ │ │ │ │ │ ├── time-input.tsx
│ │ │ │ │ │ │ ├── tool-input
│ │ │ │ │ │ │ │ ├── components
│ │ │ │ │ │ │ │ │ ├── code-editor
│ │ │ │ │ │ │ │ │ │ └── code-editor.tsx
│ │ │ │ │ │ │ │ │ ├── custom-tool-modal
│ │ │ │ │ │ │ │ │ │ └── custom-tool-modal.tsx
│ │ │ │ │ │ │ │ │ └── tool-command
│ │ │ │ │ │ │ │ │ │ └── tool-command.tsx
│ │ │ │ │ │ │ │ └── tool-input.tsx
│ │ │ │ │ │ │ └── webhook
│ │ │ │ │ │ │ │ ├── components
│ │ │ │ │ │ │ │ ├── providers
│ │ │ │ │ │ │ │ │ ├── airtable.tsx
│ │ │ │ │ │ │ │ │ ├── discord.tsx
│ │ │ │ │ │ │ │ │ ├── generic.tsx
│ │ │ │ │ │ │ │ │ ├── github.tsx
│ │ │ │ │ │ │ │ │ ├── gmail.tsx
│ │ │ │ │ │ │ │ │ ├── slack.tsx
│ │ │ │ │ │ │ │ │ ├── stripe.tsx
│ │ │ │ │ │ │ │ │ ├── telegram.tsx
│ │ │ │ │ │ │ │ │ └── whatsapp.tsx
│ │ │ │ │ │ │ │ ├── ui
│ │ │ │ │ │ │ │ │ ├── config-field.tsx
│ │ │ │ │ │ │ │ │ ├── config-section.tsx
│ │ │ │ │ │ │ │ │ ├── confirmation.tsx
│ │ │ │ │ │ │ │ │ ├── copyable.tsx
│ │ │ │ │ │ │ │ │ ├── instructions-section.tsx
│ │ │ │ │ │ │ │ │ ├── test-result.tsx
│ │ │ │ │ │ │ │ │ ├── webhook-config-field.tsx
│ │ │ │ │ │ │ │ │ ├── webhook-footer.tsx
│ │ │ │ │ │ │ │ │ └── webhook-url.tsx
│ │ │ │ │ │ │ │ └── webhook-modal.tsx
│ │ │ │ │ │ │ │ └── webhook.tsx
│ │ │ │ │ │ │ ├── hooks
│ │ │ │ │ │ │ └── use-sub-block-value.ts
│ │ │ │ │ │ │ └── sub-block.tsx
│ │ │ │ │ └── workflow-block.tsx
│ │ │ │ └── workflow-edge
│ │ │ │ │ └── workflow-edge.tsx
│ │ │ ├── hooks
│ │ │ │ ├── use-block-connections.ts
│ │ │ │ ├── use-code-generation.ts
│ │ │ │ ├── use-deployment-change-detection.ts
│ │ │ │ └── use-workflow-execution.ts
│ │ │ ├── layout.tsx
│ │ │ ├── page.tsx
│ │ │ ├── utils.ts
│ │ │ └── workflow.tsx
│ │ ├── components
│ │ │ ├── providers
│ │ │ │ ├── providers.tsx
│ │ │ │ └── theme-provider.tsx
│ │ │ ├── sidebar
│ │ │ │ ├── components
│ │ │ │ │ ├── help-modal
│ │ │ │ │ │ ├── components
│ │ │ │ │ │ │ └── help-form
│ │ │ │ │ │ │ │ └── help-form.tsx
│ │ │ │ │ │ └── help-modal.tsx
│ │ │ │ │ ├── invite-modal
│ │ │ │ │ │ ├── invite-modal.tsx
│ │ │ │ │ │ └── invites-sent
│ │ │ │ │ │ │ └── invites-sent.tsx
│ │ │ │ │ ├── nav-section
│ │ │ │ │ │ └── nav-section.tsx
│ │ │ │ │ ├── settings-modal
│ │ │ │ │ │ ├── components
│ │ │ │ │ │ │ ├── account
│ │ │ │ │ │ │ │ └── account.tsx
│ │ │ │ │ │ │ ├── api-keys
│ │ │ │ │ │ │ │ └── api-keys.tsx
│ │ │ │ │ │ │ ├── credentials
│ │ │ │ │ │ │ │ └── credentials.tsx
│ │ │ │ │ │ │ ├── environment
│ │ │ │ │ │ │ │ └── environment.tsx
│ │ │ │ │ │ │ ├── general
│ │ │ │ │ │ │ │ └── general.tsx
│ │ │ │ │ │ │ ├── privacy
│ │ │ │ │ │ │ │ └── privacy.tsx
│ │ │ │ │ │ │ ├── settings-navigation
│ │ │ │ │ │ │ │ └── settings-navigation.tsx
│ │ │ │ │ │ │ ├── subscription
│ │ │ │ │ │ │ │ └── subscription.tsx
│ │ │ │ │ │ │ └── team-management
│ │ │ │ │ │ │ │ └── team-management.tsx
│ │ │ │ │ │ └── settings-modal.tsx
│ │ │ │ │ ├── sidebar-control
│ │ │ │ │ │ └── sidebar-control.tsx
│ │ │ │ │ ├── workflow-list
│ │ │ │ │ │ └── workflow-list.tsx
│ │ │ │ │ └── workspace-header
│ │ │ │ │ │ └── workspace-header.tsx
│ │ │ │ └── sidebar.tsx
│ │ │ └── workflow-preview
│ │ │ │ └── generic-workflow-preview.tsx
│ │ ├── error.tsx
│ │ ├── global-error.tsx
│ │ ├── hooks
│ │ │ ├── use-keyboard-shortcuts.ts
│ │ │ └── use-registry-loading.ts
│ │ ├── knowledge
│ │ │ ├── [id]
│ │ │ │ ├── [documentId]
│ │ │ │ │ ├── components
│ │ │ │ │ │ ├── document-loading.tsx
│ │ │ │ │ │ └── edit-chunk-modal.tsx
│ │ │ │ │ ├── document.tsx
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── base.tsx
│ │ │ │ ├── components
│ │ │ │ │ └── knowledge-base-loading.tsx
│ │ │ │ └── page.tsx
│ │ │ ├── components
│ │ │ │ ├── base-overview
│ │ │ │ │ └── base-overview.tsx
│ │ │ │ ├── create-modal
│ │ │ │ │ ├── components
│ │ │ │ │ │ └── create-form
│ │ │ │ │ │ │ └── create-form.tsx
│ │ │ │ │ └── create-modal.tsx
│ │ │ │ ├── empty-state-card
│ │ │ │ │ └── empty-state-card.tsx
│ │ │ │ ├── icons
│ │ │ │ │ └── document-icons.tsx
│ │ │ │ └── skeletons
│ │ │ │ │ ├── knowledge-base-card-skeleton.tsx
│ │ │ │ │ └── table-skeleton.tsx
│ │ │ ├── knowledge.tsx
│ │ │ ├── loading.tsx
│ │ │ └── page.tsx
│ │ ├── layout.tsx
│ │ ├── logs
│ │ │ ├── components
│ │ │ │ ├── control-bar
│ │ │ │ │ └── control-bar.tsx
│ │ │ │ ├── filters
│ │ │ │ │ ├── components
│ │ │ │ │ │ ├── filter-section.tsx
│ │ │ │ │ │ ├── level.tsx
│ │ │ │ │ │ ├── timeline.tsx
│ │ │ │ │ │ ├── trigger.tsx
│ │ │ │ │ │ └── workflow.tsx
│ │ │ │ │ └── filters.tsx
│ │ │ │ ├── sidebar
│ │ │ │ │ ├── components
│ │ │ │ │ │ └── markdown-renderer.tsx
│ │ │ │ │ └── sidebar.tsx
│ │ │ │ ├── tool-calls
│ │ │ │ │ └── tool-calls-display.tsx
│ │ │ │ └── trace-spans
│ │ │ │ │ └── trace-spans-display.tsx
│ │ │ ├── logs.tsx
│ │ │ ├── page.tsx
│ │ │ ├── stores
│ │ │ │ ├── store.ts
│ │ │ │ └── types.ts
│ │ │ └── utils
│ │ │ │ └── format-date.ts
│ │ └── marketplace
│ │ │ ├── components
│ │ │ ├── control-bar
│ │ │ │ └── control-bar.tsx
│ │ │ ├── error-message.tsx
│ │ │ ├── section.tsx
│ │ │ ├── toolbar
│ │ │ │ └── toolbar.tsx
│ │ │ ├── workflow-card-skeleton.tsx
│ │ │ └── workflow-card.tsx
│ │ │ ├── constants
│ │ │ └── categories.tsx
│ │ │ ├── marketplace.tsx
│ │ │ └── page.tsx
│ └── zoom-prevention.tsx
│ ├── blocks
│ ├── blocks
│ │ ├── agent.test.ts
│ │ ├── agent.ts
│ │ ├── airtable.ts
│ │ ├── api.ts
│ │ ├── autoblocks.ts
│ │ ├── browser_use.ts
│ │ ├── clay.ts
│ │ ├── condition.ts
│ │ ├── confluence.ts
│ │ ├── discord.ts
│ │ ├── elevenlabs.ts
│ │ ├── evaluator.ts
│ │ ├── exa.ts
│ │ ├── file.ts
│ │ ├── firecrawl.ts
│ │ ├── function.ts
│ │ ├── github.ts
│ │ ├── gmail.ts
│ │ ├── google.ts
│ │ ├── google_docs.ts
│ │ ├── google_drive.ts
│ │ ├── google_sheets.ts
│ │ ├── guesty.ts
│ │ ├── image_generator.ts
│ │ ├── jina.ts
│ │ ├── jira.ts
│ │ ├── knowledge.ts
│ │ ├── linear.ts
│ │ ├── linkup.ts
│ │ ├── mem0.ts
│ │ ├── memory.ts
│ │ ├── microsoft_excel.ts
│ │ ├── microsoft_teams.ts
│ │ ├── mistral_parse.ts
│ │ ├── notion.ts
│ │ ├── openai.ts
│ │ ├── outlook.ts
│ │ ├── perplexity.ts
│ │ ├── pinecone.ts
│ │ ├── reddit.ts
│ │ ├── router.ts
│ │ ├── s3.ts
│ │ ├── serper.ts
│ │ ├── slack.ts
│ │ ├── stagehand.ts
│ │ ├── stagehand_agent.ts
│ │ ├── starter.ts
│ │ ├── supabase.ts
│ │ ├── tavily.ts
│ │ ├── telegram.ts
│ │ ├── thinking.ts
│ │ ├── translate.ts
│ │ ├── twilio.ts
│ │ ├── typeform.ts
│ │ ├── vision.ts
│ │ ├── whatsapp.ts
│ │ ├── x.ts
│ │ └── youtube.ts
│ ├── index.ts
│ ├── registry.ts
│ ├── types.ts
│ └── utils.ts
│ ├── components.json
│ ├── components
│ ├── emails
│ │ ├── base-styles.ts
│ │ ├── footer.tsx
│ │ ├── invitation-email.tsx
│ │ ├── otp-verification-email.tsx
│ │ ├── render-email.ts
│ │ ├── reset-password-email.tsx
│ │ ├── waitlist-approval-email.tsx
│ │ ├── waitlist-confirmation-email.tsx
│ │ └── workspace-invitation.tsx
│ ├── icons.tsx
│ ├── icons
│ │ └── document-icons.tsx
│ └── ui
│ │ ├── alert-dialog.tsx
│ │ ├── alert.tsx
│ │ ├── avatar.tsx
│ │ ├── badge.tsx
│ │ ├── breadcrumb.tsx
│ │ ├── button.tsx
│ │ ├── calendar.tsx
│ │ ├── card.tsx
│ │ ├── checkbox.tsx
│ │ ├── code-block.tsx
│ │ ├── collapsible.tsx
│ │ ├── command.tsx
│ │ ├── copy-button.tsx
│ │ ├── dialog.tsx
│ │ ├── dropdown-menu.tsx
│ │ ├── env-var-dropdown.tsx
│ │ ├── form.tsx
│ │ ├── formatted-text.tsx
│ │ ├── input-otp-form.tsx
│ │ ├── input-otp.tsx
│ │ ├── input.tsx
│ │ ├── label.tsx
│ │ ├── loading-agent.tsx
│ │ ├── notice.tsx
│ │ ├── popover.tsx
│ │ ├── progress.tsx
│ │ ├── radio-group.tsx
│ │ ├── scroll-area.tsx
│ │ ├── select.tsx
│ │ ├── separator.tsx
│ │ ├── sheet.tsx
│ │ ├── skeleton.tsx
│ │ ├── slider.tsx
│ │ ├── switch.tsx
│ │ ├── table.tsx
│ │ ├── tabs.tsx
│ │ ├── tag-dropdown.test.tsx
│ │ ├── tag-dropdown.tsx
│ │ ├── textarea.tsx
│ │ ├── toggle.tsx
│ │ └── tooltip.tsx
│ ├── db
│ ├── index.ts
│ ├── migrations
│ │ ├── 0000_careless_black_knight.sql
│ │ ├── 0001_foamy_dakota_north.sql
│ │ ├── 0002_previous_xavin.sql
│ │ ├── 0003_smiling_hammerhead.sql
│ │ ├── 0004_nasty_mesmero.sql
│ │ ├── 0005_shocking_domino.sql
│ │ ├── 0006_plain_zzzax.sql
│ │ ├── 0007_mute_stepford_cuckoos.sql
│ │ ├── 0008_quick_paladin.sql
│ │ ├── 0009_cynical_bullseye.sql
│ │ ├── 0009_far_sharon_ventura.sql
│ │ ├── 0010_flashy_nebula.sql
│ │ ├── 0011_youthful_iron_lad.sql
│ │ ├── 0012_minor_dexter_bennett.sql
│ │ ├── 0013_dusty_aaron_stack.sql
│ │ ├── 0014_nice_dragon_lord.sql
│ │ ├── 0015_brief_martin_li.sql
│ │ ├── 0016_cultured_butterfly.sql
│ │ ├── 0017_curious_ink.sql
│ │ ├── 0018_sleepy_champions.sql
│ │ ├── 0019_even_lorna_dane.sql
│ │ ├── 0020_clear_skreet.sql
│ │ ├── 0021_shocking_korath.sql
│ │ ├── 0022_gray_galactus.sql
│ │ ├── 0023_nervous_tyger_tiger.sql
│ │ ├── 0024_next_whizzer.sql
│ │ ├── 0025_curved_jubilee.sql
│ │ ├── 0026_daily_killraven.sql
│ │ ├── 0027_careless_gamora.sql
│ │ ├── 0028_absent_triton.sql
│ │ ├── 0030_happy_joseph.sql
│ │ ├── 0031_lively_nico_minoru.sql
│ │ ├── 0032_rare_nico_minoru.sql
│ │ ├── 0033_solid_stellaris.sql
│ │ ├── 0034_brainy_revanche.sql
│ │ ├── 0035_slim_energizer.sql
│ │ ├── 0036_married_skreet.sql
│ │ ├── 0037_outgoing_madame_hydra.sql
│ │ ├── 0038_shocking_thor.sql
│ │ ├── 0039_tranquil_speed.sql
│ │ ├── 0040_silky_monster_badoon.sql
│ │ ├── meta
│ │ │ ├── 0000_snapshot.json
│ │ │ ├── 0001_snapshot.json
│ │ │ ├── 0002_snapshot.json
│ │ │ ├── 0003_snapshot.json
│ │ │ ├── 0004_snapshot.json
│ │ │ ├── 0005_snapshot.json
│ │ │ ├── 0006_snapshot.json
│ │ │ ├── 0007_snapshot.json
│ │ │ ├── 0008_snapshot.json
│ │ │ ├── 0009_snapshot.json
│ │ │ ├── 0010_snapshot.json
│ │ │ ├── 0011_snapshot.json
│ │ │ ├── 0012_snapshot.json
│ │ │ ├── 0013_snapshot.json
│ │ │ ├── 0014_snapshot.json
│ │ │ ├── 0015_snapshot.json
│ │ │ ├── 0016_snapshot.json
│ │ │ ├── 0017_snapshot.json
│ │ │ ├── 0018_snapshot.json
│ │ │ ├── 0019_snapshot.json
│ │ │ ├── 0020_snapshot.json
│ │ │ ├── 0021_snapshot.json
│ │ │ ├── 0022_snapshot.json
│ │ │ ├── 0023_snapshot.json
│ │ │ ├── 0024_snapshot.json
│ │ │ ├── 0025_snapshot.json
│ │ │ ├── 0026_snapshot.json
│ │ │ ├── 0027_snapshot.json
│ │ │ ├── 0028_snapshot.json
│ │ │ ├── 0030_snapshot.json
│ │ │ ├── 0031_snapshot.json
│ │ │ ├── 0032_snapshot.json
│ │ │ ├── 0033_snapshot.json
│ │ │ ├── 0034_snapshot.json
│ │ │ ├── 0035_snapshot.json
│ │ │ ├── 0036_snapshot.json
│ │ │ ├── 0037_snapshot.json
│ │ │ ├── 0038_snapshot.json
│ │ │ ├── 0039_snapshot.json
│ │ │ ├── 0040_snapshot.json
│ │ │ └── _journal.json
│ │ ├── relations.ts
│ │ └── schema.ts
│ └── schema.ts
│ ├── drizzle.config.ts
│ ├── executor
│ ├── __test-utils__
│ │ ├── executor-mocks.ts
│ │ ├── mock-dependencies.ts
│ │ └── test-executor.ts
│ ├── handlers
│ │ ├── agent
│ │ │ ├── agent-handler.test.ts
│ │ │ ├── agent-handler.ts
│ │ │ └── types.ts
│ │ ├── api
│ │ │ ├── api-handler.test.ts
│ │ │ └── api-handler.ts
│ │ ├── condition
│ │ │ ├── condition-handler.test.ts
│ │ │ └── condition-handler.ts
│ │ ├── evaluator
│ │ │ ├── evaluator-handler.test.ts
│ │ │ └── evaluator-handler.ts
│ │ ├── function
│ │ │ ├── function-handler.test.ts
│ │ │ └── function-handler.ts
│ │ ├── generic
│ │ │ ├── generic-handler.test.ts
│ │ │ └── generic-handler.ts
│ │ ├── index.ts
│ │ ├── loop
│ │ │ ├── loop-handler.test.ts
│ │ │ └── loop-handler.ts
│ │ ├── parallel
│ │ │ ├── parallel-handler.test.ts
│ │ │ └── parallel-handler.ts
│ │ └── router
│ │ │ ├── router-handler.test.ts
│ │ │ └── router-handler.ts
│ ├── index.test.ts
│ ├── index.ts
│ ├── loops.test.ts
│ ├── loops.ts
│ ├── parallels.test.ts
│ ├── parallels.ts
│ ├── path.test.ts
│ ├── path.ts
│ ├── resolver.test.ts
│ ├── resolver.ts
│ └── types.ts
│ ├── hooks
│ ├── use-debounce.ts
│ └── use-user-subscription.ts
│ ├── instrumentation-client.ts
│ ├── instrumentation-server.ts
│ ├── instrumentation.ts
│ ├── lib
│ ├── auth-client.ts
│ ├── auth.ts
│ ├── document-processor.ts
│ ├── env.ts
│ ├── environment.ts
│ ├── file-parsers
│ │ ├── csv-parser.ts
│ │ ├── docx-parser.ts
│ │ ├── index.test.ts
│ │ ├── index.ts
│ │ ├── pdf-parser.ts
│ │ ├── raw-pdf-parser.ts
│ │ └── types.ts
│ ├── freestyle.ts
│ ├── generate-chat-title.ts
│ ├── logs
│ │ ├── console-logger.ts
│ │ ├── execution-logger.ts
│ │ └── trace-spans.ts
│ ├── mailer.ts
│ ├── oauth.ts
│ ├── redis.ts
│ ├── schedules
│ │ ├── utils.test.ts
│ │ └── utils.ts
│ ├── subscription.ts
│ ├── subscription
│ │ ├── subscription.ts
│ │ ├── utils.test.ts
│ │ └── utils.ts
│ ├── telemetry.ts
│ ├── uploads
│ │ ├── s3-client.test.ts
│ │ ├── s3-client.ts
│ │ ├── setup.server.ts
│ │ └── setup.ts
│ ├── urls
│ │ └── utils.ts
│ ├── usage-monitor.ts
│ ├── utils.test.ts
│ ├── utils.ts
│ ├── variables
│ │ ├── variable-manager.test.ts
│ │ └── variable-manager.ts
│ ├── waitlist
│ │ ├── rate-limiter.ts
│ │ ├── service.ts
│ │ └── token.ts
│ ├── webhooks
│ │ ├── gmail-polling-service.ts
│ │ └── utils.ts
│ └── workflows
│ │ └── utils.ts
│ ├── middleware.ts
│ ├── next.config.ts
│ ├── package.json
│ ├── postcss.config.mjs
│ ├── providers
│ ├── anthropic
│ │ └── index.ts
│ ├── cerebras
│ │ ├── index.ts
│ │ └── types.ts
│ ├── deepseek
│ │ └── index.ts
│ ├── google
│ │ └── index.ts
│ ├── groq
│ │ └── index.ts
│ ├── index.ts
│ ├── model-capabilities.test.ts
│ ├── model-capabilities.ts
│ ├── ollama
│ │ ├── index.ts
│ │ └── types.ts
│ ├── openai
│ │ └── index.ts
│ ├── pricing.ts
│ ├── types.ts
│ ├── utils.test.ts
│ ├── utils.ts
│ └── xai
│ │ └── index.ts
│ ├── public
│ ├── favicon
│ │ ├── android-chrome-192x192.png
│ │ ├── android-chrome-512x512.png
│ │ ├── apple-touch-icon.png
│ │ ├── favicon-16x16.png
│ │ ├── favicon-32x32.png
│ │ ├── favicon.ico
│ │ └── site.webmanifest
│ ├── icon.svg
│ ├── logo-sim.svg
│ ├── sim.png
│ ├── sim.svg
│ ├── social
│ │ ├── facebook.png
│ │ ├── instagram.png
│ │ └── twitter.png
│ ├── static
│ │ ├── automate-blocks.svg
│ │ ├── demo.gif
│ │ ├── discord-icon.png
│ │ ├── github-icon.png
│ │ ├── preview.png
│ │ ├── sim.png
│ │ ├── sync-blocks.svg
│ │ └── x-icon.png
│ └── twitter
│ │ ├── daniel.jpg
│ │ ├── github-projects.jpg
│ │ ├── hasan.jpg
│ │ ├── lazukars.png
│ │ ├── nizzy.jpg
│ │ ├── samarth.jpg
│ │ ├── syamrajk.jpg
│ │ └── xyflow.jpg
│ ├── scripts
│ └── ollama_docker.sh
│ ├── serializer
│ ├── __test-utils__
│ │ └── test-workflows.ts
│ ├── index.test.ts
│ ├── index.ts
│ └── types.ts
│ ├── stores
│ ├── constants.ts
│ ├── copilot
│ │ ├── store.ts
│ │ ├── types.ts
│ │ └── utils.ts
│ ├── custom-tools
│ │ ├── store.ts
│ │ └── types.ts
│ ├── execution
│ │ ├── store.ts
│ │ └── types.ts
│ ├── index.ts
│ ├── notifications
│ │ ├── store.ts
│ │ └── types.ts
│ ├── ollama
│ │ ├── store.ts
│ │ └── types.ts
│ ├── panel
│ │ ├── chat
│ │ │ ├── store.ts
│ │ │ └── types.ts
│ │ ├── console
│ │ │ ├── store.ts
│ │ │ └── types.ts
│ │ ├── store.ts
│ │ ├── types.ts
│ │ └── variables
│ │ │ ├── store.ts
│ │ │ └── types.ts
│ ├── settings
│ │ ├── environment
│ │ │ ├── store.ts
│ │ │ └── types.ts
│ │ └── general
│ │ │ ├── store.ts
│ │ │ └── types.ts
│ ├── sidebar
│ │ └── store.ts
│ ├── sync-core.ts
│ ├── sync-registry.ts
│ ├── sync.ts
│ └── workflows
│ │ ├── index.ts
│ │ ├── middleware.ts
│ │ ├── persistence.ts
│ │ ├── registry
│ │ ├── store.ts
│ │ ├── types.ts
│ │ └── utils.ts
│ │ ├── subblock
│ │ ├── store.ts
│ │ ├── types.ts
│ │ └── utils.ts
│ │ ├── sync.ts
│ │ ├── utils.ts
│ │ └── workflow
│ │ ├── store.test.ts
│ │ ├── store.ts
│ │ ├── types.ts
│ │ ├── utils.test.ts
│ │ └── utils.ts
│ ├── tailwind.config.ts
│ ├── telemetry.config.ts
│ ├── tools
│ ├── __test-utils__
│ │ ├── mock-data.ts
│ │ └── test-tools.ts
│ ├── airtable
│ │ ├── create_records.ts
│ │ ├── get_record.ts
│ │ ├── index.test.ts
│ │ ├── index.ts
│ │ ├── list_records.ts
│ │ ├── types.ts
│ │ ├── update_multiple_records.ts
│ │ └── update_record.ts
│ ├── autoblocks
│ │ ├── index.ts
│ │ ├── prompt_manager.ts
│ │ └── types.ts
│ ├── browser_use
│ │ ├── index.ts
│ │ ├── run_task.ts
│ │ └── types.ts
│ ├── clay
│ │ ├── index.ts
│ │ ├── populate.ts
│ │ └── types.ts
│ ├── confluence
│ │ ├── index.ts
│ │ ├── retrieve.ts
│ │ ├── types.ts
│ │ ├── update.ts
│ │ └── utils.ts
│ ├── discord
│ │ ├── get_messages.ts
│ │ ├── get_server.ts
│ │ ├── get_user.ts
│ │ ├── index.ts
│ │ ├── send_message.ts
│ │ └── types.ts
│ ├── elevenlabs
│ │ ├── index.ts
│ │ ├── tts.ts
│ │ └── types.ts
│ ├── exa
│ │ ├── answer.ts
│ │ ├── find_similar_links.ts
│ │ ├── get_contents.ts
│ │ ├── index.ts
│ │ ├── search.ts
│ │ └── types.ts
│ ├── file
│ │ ├── index.ts
│ │ ├── parser.ts
│ │ └── types.ts
│ ├── firecrawl
│ │ ├── index.ts
│ │ ├── scrape.ts
│ │ └── types.ts
│ ├── function
│ │ ├── execute.test.ts
│ │ ├── execute.ts
│ │ ├── index.ts
│ │ └── types.ts
│ ├── github
│ │ ├── comment.ts
│ │ ├── index.ts
│ │ ├── latest_commit.ts
│ │ ├── pr.test.ts
│ │ ├── pr.ts
│ │ ├── repo_info.test.ts
│ │ ├── repo_info.ts
│ │ └── types.ts
│ ├── gmail
│ │ ├── index.ts
│ │ ├── read.test.ts
│ │ ├── read.ts
│ │ ├── search.ts
│ │ ├── send.ts
│ │ └── types.ts
│ ├── google
│ │ ├── index.ts
│ │ ├── search.ts
│ │ └── types.ts
│ ├── google_docs
│ │ ├── create.ts
│ │ ├── index.ts
│ │ ├── read.ts
│ │ ├── types.ts
│ │ └── write.ts
│ ├── google_drive
│ │ ├── create_folder.ts
│ │ ├── get_content.ts
│ │ ├── index.ts
│ │ ├── list.ts
│ │ ├── types.ts
│ │ ├── upload.ts
│ │ └── utils.ts
│ ├── google_sheets
│ │ ├── append.ts
│ │ ├── index.ts
│ │ ├── read.ts
│ │ ├── types.ts
│ │ ├── update.ts
│ │ └── write.ts
│ ├── guesty
│ │ ├── guest.ts
│ │ ├── index.ts
│ │ ├── reservation.ts
│ │ └── types.ts
│ ├── http
│ │ ├── index.ts
│ │ ├── request.test.ts
│ │ ├── request.ts
│ │ └── types.ts
│ ├── hubspot
│ │ └── contacts.ts
│ ├── index.test.ts
│ ├── index.ts
│ ├── jina
│ │ ├── index.ts
│ │ ├── read_url.ts
│ │ └── types.ts
│ ├── jira
│ │ ├── bulk_read.ts
│ │ ├── index.ts
│ │ ├── retrieve.ts
│ │ ├── types.ts
│ │ ├── update.ts
│ │ ├── utils.ts
│ │ └── write.ts
│ ├── knowledge
│ │ ├── index.ts
│ │ ├── search.ts
│ │ └── types.ts
│ ├── linear
│ │ ├── create_issue.ts
│ │ ├── index.ts
│ │ ├── read_issues.ts
│ │ └── types.ts
│ ├── linkup
│ │ ├── index.ts
│ │ ├── search.ts
│ │ └── types.ts
│ ├── mem0
│ │ ├── add_memories.ts
│ │ ├── get_memories.ts
│ │ ├── index.ts
│ │ ├── search_memories.ts
│ │ └── types.ts
│ ├── memory
│ │ ├── add.ts
│ │ ├── delete.ts
│ │ ├── get.ts
│ │ ├── get_all.ts
│ │ ├── index.ts
│ │ └── types.ts
│ ├── microsoft_excel
│ │ ├── index.ts
│ │ ├── read.ts
│ │ ├── table_add.ts
│ │ ├── types.ts
│ │ └── write.ts
│ ├── microsoft_teams
│ │ ├── attachment-utils.ts
│ │ ├── index.ts
│ │ ├── read_channel.ts
│ │ ├── read_chat.ts
│ │ ├── types.ts
│ │ ├── write_channel.ts
│ │ └── write_chat.ts
│ ├── mistral
│ │ ├── index.ts
│ │ ├── parser.ts
│ │ └── types.ts
│ ├── notion
│ │ ├── create_page.ts
│ │ ├── index.ts
│ │ ├── read.ts
│ │ ├── types.ts
│ │ ├── update_page.ts
│ │ └── write.ts
│ ├── openai
│ │ ├── embeddings.ts
│ │ ├── image.ts
│ │ ├── index.ts
│ │ └── types.ts
│ ├── outlook
│ │ ├── draft.ts
│ │ ├── index.ts
│ │ ├── read.ts
│ │ ├── send.ts
│ │ └── types.ts
│ ├── perplexity
│ │ ├── chat.ts
│ │ ├── index.ts
│ │ └── types.ts
│ ├── pinecone
│ │ ├── fetch.ts
│ │ ├── generate_embeddings.ts
│ │ ├── index.ts
│ │ ├── search_text.ts
│ │ ├── search_vector.ts
│ │ ├── types.ts
│ │ └── upsert_text.ts
│ ├── reddit
│ │ ├── get_comments.ts
│ │ ├── get_posts.ts
│ │ ├── hot_posts.ts
│ │ ├── index.ts
│ │ └── types.ts
│ ├── registry.ts
│ ├── s3
│ │ ├── get_object.ts
│ │ ├── index.ts
│ │ └── types.ts
│ ├── salesforce
│ │ └── opportunities.ts
│ ├── serper
│ │ ├── index.ts
│ │ ├── search.ts
│ │ └── types.ts
│ ├── slack
│ │ ├── index.ts
│ │ ├── message.ts
│ │ └── types.ts
│ ├── stagehand
│ │ ├── agent.ts
│ │ ├── extract.ts
│ │ ├── index.ts
│ │ └── types.ts
│ ├── supabase
│ │ ├── index.ts
│ │ ├── insert.ts
│ │ ├── query.ts
│ │ └── types.ts
│ ├── tavily
│ │ ├── extract.ts
│ │ ├── index.ts
│ │ ├── search.ts
│ │ └── types.ts
│ ├── telegram
│ │ ├── index.ts
│ │ ├── message.ts
│ │ └── types.ts
│ ├── thinking
│ │ ├── index.ts
│ │ ├── tool.ts
│ │ └── types.ts
│ ├── twilio
│ │ ├── index.ts
│ │ ├── send_sms.ts
│ │ └── types.ts
│ ├── typeform
│ │ ├── files.test.ts
│ │ ├── files.ts
│ │ ├── index.test.ts
│ │ ├── index.ts
│ │ ├── insights.test.ts
│ │ ├── insights.ts
│ │ ├── responses.test.ts
│ │ ├── responses.ts
│ │ └── types.ts
│ ├── types.ts
│ ├── utils.test.ts
│ ├── utils.ts
│ ├── vision
│ │ ├── index.ts
│ │ ├── tool.ts
│ │ └── types.ts
│ ├── whatsapp
│ │ ├── index.ts
│ │ ├── send_message.ts
│ │ └── types.ts
│ ├── x
│ │ ├── index.ts
│ │ ├── read.ts
│ │ ├── search.ts
│ │ ├── types.ts
│ │ ├── user.ts
│ │ └── write.ts
│ └── youtube
│ │ ├── index.ts
│ │ ├── search.ts
│ │ └── types.ts
│ ├── tsconfig.json
│ ├── vercel.json
│ ├── vitest.config.ts
│ └── vitest.setup.ts
├── biome.json
├── bun.lock
├── bunfig.toml
├── docker-compose.local.yml
├── docker-compose.ollama.yml
├── docker-compose.prod.yml
├── docker
├── app.Dockerfile
└── db.Dockerfile
├── package.json
├── packages
└── simstudio
│ ├── README.md
│ ├── package.json
│ ├── src
│ └── index.ts
│ └── tsconfig.json
├── scripts
├── README.md
├── generate-block-docs.ts
├── generate-docs.sh
├── package-lock.json
├── package.json
├── setup-doc-generator.sh
└── tsconfig.json
└── turbo.json
/.devcontainer/Dockerfile:
--------------------------------------------------------------------------------
1 | # Use the latest Bun canary image for development
2 | FROM oven/bun:canary
3 |
4 | # Avoid warnings by switching to noninteractive
5 | ENV DEBIAN_FRONTEND=noninteractive
6 |
7 | # Install necessary packages for development
8 | RUN apt-get update \
9 | && apt-get -y install --no-install-recommends \
10 | git curl wget jq sudo postgresql-client vim nano \
11 | bash-completion ca-certificates lsb-release gnupg \
12 | && apt-get clean -y \
13 | && rm -rf /var/lib/apt/lists/*
14 |
15 | # Create a non-root user
16 | ARG USERNAME=bun
17 | ARG USER_UID=1000
18 | ARG USER_GID=$USER_UID
19 |
20 | # Add sudo support
21 | RUN echo "$USERNAME ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/$USERNAME \
22 | && chmod 0440 /etc/sudoers.d/$USERNAME
23 |
24 | # Install global packages for development
25 | RUN bun install -g turbo drizzle-kit typescript @types/node
26 |
27 | # Install bun completions
28 | RUN bun completions > /etc/bash_completion.d/bun
29 |
30 | # Set up shell environment
31 | RUN echo "export PATH=$PATH:/home/$USERNAME/.bun/bin" >> /etc/profile
32 | RUN echo "source /etc/profile" >> /etc/bash.bashrc
33 |
34 | # Switch back to dialog for any ad-hoc use of apt-get
35 | ENV DEBIAN_FRONTEND=dialog
36 |
37 | WORKDIR /workspace
38 |
39 | # Expose the ports we're interested in
40 | EXPOSE 3000
41 | EXPOSE 3001
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 | LICENSE
2 | NOTICE
3 | .prettierrc
4 | .prettierignore
5 | README.md
6 | .gitignore
7 | .husky
8 | .github
9 | .devcontainer
10 | .env.example
11 | node_modules
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: '[BUG]'
5 | labels: bug
6 | assignees: ''
7 | ---
8 |
9 | **Describe the bug**
10 | A clear and concise description of what the bug is.
11 |
12 | **To Reproduce**
13 | Steps to reproduce the behavior:
14 |
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Additional context**
27 | Add any other context about the problem here.
28 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: '[REQUEST]'
5 | labels: feature
6 | assignees: ''
7 | ---
8 |
9 | **Is your feature request related to a problem? Please describe.**
10 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
11 |
12 | **Describe the solution you'd like**
13 | A clear and concise description of what you want to happen.
14 |
15 | **Describe alternatives you've considered**
16 | A clear and concise description of any alternative solutions or features you've considered.
17 |
18 | **Additional context**
19 | Add any other context or screenshots about the feature request here.
20 |
--------------------------------------------------------------------------------
/.github/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | ## Supported Versions
4 |
5 | | Version | Supported |
6 | | ------- | ------------------ |
7 | | 0.1.x | :white_check_mark: |
8 |
9 | ## Reporting a Vulnerability
10 |
11 | We take the security of Sim Studio seriously. If you believe you've found a security vulnerability, please follow these steps:
12 |
13 | 1. **Do not disclose the vulnerability publicly** or to any third parties.
14 |
15 | 2. **Email us directly** at security@simstudio.ai with details of the vulnerability.
16 |
17 | 3. **Include the following information** in your report:
18 |
19 | - Description of the vulnerability
20 | - Steps to reproduce
21 | - Potential impact
22 | - Any suggestions for mitigation
23 |
24 | 4. We will acknowledge receipt of your vulnerability report within 48 hours and provide an estimated timeline for a fix.
25 |
26 | 5. Once the vulnerability is fixed, we will notify you and publicly acknowledge your contribution (unless you prefer to remain anonymous).
27 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /apps/**/node_modules
6 | /packages/**/node_modules
7 | /scripts/node_modules
8 |
9 | # bun specific
10 | bun-debug.log*
11 |
12 | # testing
13 | /coverage
14 | /apps/**/coverage
15 |
16 | # next.js
17 | /.next/
18 | /apps/**/out/
19 | /apps/**/.next/
20 | /apps/**/build
21 |
22 | # production
23 | /build
24 | /dist
25 | **/dist/
26 | **/standalone/
27 | sim-standalone.tar.gz
28 |
29 | # misc
30 | .DS_Store
31 | *.pem
32 |
33 | # env files
34 | .env
35 | *.env
36 | .env.local
37 | .env.development
38 | .env.test
39 | .env.production
40 |
41 | # vercel
42 | .vercel
43 |
44 | # typescript
45 | *.tsbuildinfo
46 | next-env.d.ts
47 |
48 | # cursorrules
49 | .cursorrules
50 |
51 | # docs
52 | /apps/docs/.source
53 | /apps/docs/.contentlayer
54 | /apps/docs/.content-collections
55 |
56 | # database instantiation
57 | **/postgres_data/
58 |
59 | # collector configuration
60 | collector-config.yaml
61 | docker-compose.collector.yml
62 | start-collector.sh
63 |
64 | # Turborepo
65 | .turbo
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | bunx lint-staged
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | ignore-scripts=true
2 |
--------------------------------------------------------------------------------
/NOTICE:
--------------------------------------------------------------------------------
1 | Sim Studio
2 | Copyright 2025 Sim Studio
3 |
4 | This product includes software developed for the Sim Studio project.
--------------------------------------------------------------------------------
/apps/docs/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 |
6 | # bun specific
7 | .bun
8 | bun.lockb
9 | bun-debug.log*
10 |
11 | # testing
12 | /coverage
13 |
14 | # next.js
15 | /.next/
16 | /out/
17 | /build
18 |
19 | # misc
20 | .DS_Store
21 | *.pem
22 |
23 | # env files
24 | .env
25 | *.env
26 | .env.local
27 | .env.development
28 | .env.test
29 | .env.production
30 |
31 | # vercel
32 | .vercel
33 |
34 | # typescript
35 | *.tsbuildinfo
36 | next-env.d.ts
37 |
38 | # Fumadocs
39 | /.source/
--------------------------------------------------------------------------------
/apps/docs/README.md:
--------------------------------------------------------------------------------
1 | # docs
2 |
3 | This is a Next.js application generated with
4 | [Create Fumadocs](https://github.com/fuma-nama/fumadocs).
5 |
6 | Run development server:
7 |
8 | ```bash
9 | bun run dev
10 | ```
11 |
12 | Open http://localhost:3000 with your browser to see the result.
13 |
14 | ## Learn More
15 |
16 | To learn more about Next.js and Fumadocs, take a look at the following
17 | resources:
18 |
19 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js
20 | features and API.
21 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
22 | - [Fumadocs](https://fumadocs.vercel.app) - learn about Fumadocs
23 | - [Bun Documentation](https://bun.sh/docs) - learn about Bun features and API
24 |
--------------------------------------------------------------------------------
/apps/docs/app/(docs)/[[...slug]]/layout.tsx:
--------------------------------------------------------------------------------
1 | import type { ReactNode } from 'react'
2 |
3 | export default function SlugLayout({ children }: { children: ReactNode }) {
4 | return children
5 | }
6 |
--------------------------------------------------------------------------------
/apps/docs/app/(docs)/layout.tsx:
--------------------------------------------------------------------------------
1 | import type { ReactNode } from 'react'
2 | import { DocsLayout } from 'fumadocs-ui/layouts/docs'
3 | import { ExternalLink, GithubIcon } from 'lucide-react'
4 | import Link from 'next/link'
5 | import { source } from '@/lib/source'
6 |
7 | const GitHubLink = () => (
8 |
9 |
15 |
16 |
17 |
18 | )
19 |
20 | export default function Layout({ children }: { children: ReactNode }) {
21 | return (
22 | <>
23 | Sim Studio,
27 | }}
28 | links={[
29 | {
30 | text: 'Visit Sim Studio',
31 | url: 'https://simstudio.ai',
32 | icon: ,
33 | },
34 | ]}
35 | sidebar={{
36 | defaultOpenLevel: 1,
37 | collapsible: true,
38 | footer: null,
39 | }}
40 | >
41 | {children}
42 |
43 |
44 | >
45 | )
46 | }
47 |
--------------------------------------------------------------------------------
/apps/docs/app/api/search/route.ts:
--------------------------------------------------------------------------------
1 | import { createFromSource } from 'fumadocs-core/search/server'
2 | import { source } from '@/lib/source'
3 |
4 | export const { GET } = createFromSource(source)
5 |
--------------------------------------------------------------------------------
/apps/docs/app/global.css:
--------------------------------------------------------------------------------
1 | @import "tailwindcss";
2 | @import "fumadocs-ui/css/neutral.css";
3 | @import "fumadocs-ui/css/preset.css";
4 | :root {
5 | --color-fd-primary: #802fff; /* Purple from control-bar component */
6 | }
7 |
8 | /* Custom text highlighting styles */
9 | .text-highlight {
10 | color: var(--color-fd-primary);
11 | }
12 |
13 | /* Override marker color for highlighted lists */
14 | .highlight-markers li::marker {
15 | color: var(--color-fd-primary);
16 | }
17 |
18 | @source '../node_modules/fumadocs-ui/dist/**/*.js';
19 |
--------------------------------------------------------------------------------
/apps/docs/app/layout.config.tsx:
--------------------------------------------------------------------------------
1 | import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared'
2 |
3 | /**
4 | * Shared layout configurations
5 | *
6 | * you can customise layouts individually from:
7 | * Home Layout: app/(home)/layout.tsx
8 | * Docs Layout: app/docs/layout.tsx
9 | */
10 | export const baseOptions: BaseLayoutProps = {
11 | nav: {
12 | title: (
13 | <>
14 |
15 |
16 |
17 | My App
18 | >
19 | ),
20 | },
21 | }
22 |
--------------------------------------------------------------------------------
/apps/docs/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import type { ReactNode } from 'react'
2 | import { RootProvider } from 'fumadocs-ui/provider'
3 | import { Inter } from 'next/font/google'
4 | import './global.css'
5 | import { Analytics } from '@vercel/analytics/next'
6 |
7 | const inter = Inter({
8 | subsets: ['latin'],
9 | })
10 |
11 | export default function Layout({ children }: { children: ReactNode }) {
12 | return (
13 |
14 |
15 |
16 | {children}
17 |
18 |
19 |
20 |
21 | )
22 | }
23 |
24 | export const metadata = {
25 | title: 'Sim Studio',
26 | description:
27 | 'Build agents in seconds with a drag and drop workflow builder. Access comprehensive documentation to help you create efficient workflows and maximize your automation capabilities.',
28 | manifest: '/favicon/site.webmanifest',
29 | icons: {
30 | icon: [
31 | { url: '/favicon/favicon-16x16.png', sizes: '16x16', type: 'image/png' },
32 | { url: '/favicon/favicon-32x32.png', sizes: '32x32', type: 'image/png' },
33 | ],
34 | apple: '/favicon/apple-touch-icon.png',
35 | shortcut: '/favicon/favicon.ico',
36 | },
37 | appleWebApp: {
38 | capable: true,
39 | statusBarStyle: 'default',
40 | title: 'Sim Studio Docs',
41 | },
42 | }
43 |
--------------------------------------------------------------------------------
/apps/docs/components/mdx-components.tsx:
--------------------------------------------------------------------------------
1 | import defaultMdxComponents from 'fumadocs-ui/mdx'
2 | import { ThemeImage } from './ui/theme-image'
3 |
4 | // Extend the default MDX components with our custom components
5 | const mdxComponents = {
6 | ...defaultMdxComponents,
7 | ThemeImage,
8 | }
9 |
10 | export default mdxComponents
11 |
--------------------------------------------------------------------------------
/apps/docs/components/ui/block-info-card.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import type * as React from 'react'
4 |
5 | interface BlockInfoCardProps {
6 | type: string
7 | color: string
8 | icon?: boolean
9 | iconSvg?: string
10 | }
11 |
12 | export function BlockInfoCard({
13 | type,
14 | color,
15 | icon = false,
16 | iconSvg,
17 | }: BlockInfoCardProps): React.ReactNode {
18 | return (
19 |
20 |
21 |
25 | {iconSvg ? (
26 |
27 | ) : (
28 |
{type.substring(0, 2)}
29 | )}
30 |
31 |
32 | {icon && (
33 |
41 | )}
42 |
43 | )
44 | }
45 |
--------------------------------------------------------------------------------
/apps/docs/components/ui/theme-image.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { useEffect, useState } from 'react'
4 | import Image from 'next/image'
5 | import { useTheme } from 'next-themes'
6 |
7 | interface ThemeImageProps {
8 | lightSrc: string
9 | darkSrc: string
10 | alt: string
11 | width?: number
12 | height?: number
13 | className?: string
14 | }
15 |
16 | export function ThemeImage({
17 | lightSrc,
18 | darkSrc,
19 | alt,
20 | width = 600,
21 | height = 400,
22 | className = 'rounded-lg border border-border my-6',
23 | }: ThemeImageProps) {
24 | const { resolvedTheme } = useTheme()
25 | const [imageSrc, setImageSrc] = useState(lightSrc)
26 | const [mounted, setMounted] = useState(false)
27 |
28 | // Wait until component is mounted to avoid hydration mismatch
29 | useEffect(() => {
30 | setMounted(true)
31 | }, [])
32 |
33 | useEffect(() => {
34 | if (mounted) {
35 | setImageSrc(resolvedTheme === 'dark' ? darkSrc : lightSrc)
36 | }
37 | }, [resolvedTheme, lightSrc, darkSrc, mounted])
38 |
39 | if (!mounted) {
40 | return null
41 | }
42 |
43 | return (
44 |
45 |
46 |
47 | )
48 | }
49 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/blocks/meta.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Blocks",
3 | "pages": ["agent", "api", "condition", "function", "evaluator", "router"]
4 | }
5 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/connections/meta.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Connections",
3 | "pages": ["basics", "tags", "data-structure", "accessing-data", "best-practices"]
4 | }
5 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/execution/meta.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Execution",
3 | "pages": ["basics", "loops", "advanced"]
4 | }
5 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/introduction/meta.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Introduction",
3 | "pages": ["index"]
4 | }
5 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/meta.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Sim Studio Documentation",
3 | "pages": [
4 | "---Introduction---",
5 | "./introduction/index",
6 | "./getting-started/index",
7 | "---Create---",
8 | "blocks",
9 | "tools",
10 | "---Connections---",
11 | "connections",
12 | "---Execution---",
13 | "execution",
14 | "---Advanced---",
15 | "./variables/index"
16 | ],
17 | "defaultOpen": true
18 | }
19 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/tools/meta.json:
--------------------------------------------------------------------------------
1 | {
2 | "items": [
3 | "index",
4 | "airtable",
5 | "autoblocks",
6 | "browser_use",
7 | "clay",
8 | "confluence",
9 | "discord",
10 | "elevenlabs",
11 | "exa",
12 | "file",
13 | "firecrawl",
14 | "github",
15 | "gmail",
16 | "google_docs",
17 | "google_drive",
18 | "google_search",
19 | "google_sheets",
20 | "guesty",
21 | "image_generator",
22 | "jina",
23 | "jira",
24 | "linear",
25 | "linkup",
26 | "mem0",
27 | "memory",
28 | "microsoft_excel",
29 | "microsoft_teams",
30 | "mistral_parse",
31 | "notion",
32 | "openai",
33 | "outlook",
34 | "perplexity",
35 | "pinecone",
36 | "reddit",
37 | "s3",
38 | "serper",
39 | "slack",
40 | "stagehand",
41 | "stagehand_agent",
42 | "supabase",
43 | "tavily",
44 | "telegram",
45 | "thinking",
46 | "translate",
47 | "twilio_sms",
48 | "typeform",
49 | "vision",
50 | "whatsapp",
51 | "x",
52 | "youtube"
53 | ]
54 | }
55 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/variables/meta.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Variables",
3 | "pages": ["index"]
4 | }
5 |
--------------------------------------------------------------------------------
/apps/docs/lib/source.ts:
--------------------------------------------------------------------------------
1 | import { loader } from 'fumadocs-core/source'
2 | import { docs } from '@/.source'
3 |
4 | // `loader()` also assign a URL to your pages
5 | // See https://fumadocs.vercel.app/docs/headless/source-api for more info
6 | export const source = loader({
7 | baseUrl: '/',
8 | source: docs.toFumadocsSource(),
9 | })
10 |
--------------------------------------------------------------------------------
/apps/docs/lib/utils.ts:
--------------------------------------------------------------------------------
1 | import { type ClassValue, clsx } from 'clsx'
2 | import { twMerge } from 'tailwind-merge'
3 |
4 | /**
5 | * Combines multiple class names into a single string, merging Tailwind classes properly
6 | */
7 | export function cn(...inputs: ClassValue[]) {
8 | return twMerge(clsx(inputs))
9 | }
10 |
--------------------------------------------------------------------------------
/apps/docs/next.config.ts:
--------------------------------------------------------------------------------
1 | import { createMDX } from 'fumadocs-mdx/next'
2 |
3 | const withMDX = createMDX()
4 |
5 | /** @type {import('next').NextConfig} */
6 | const config = {
7 | reactStrictMode: true,
8 | async redirects() {
9 | return [
10 | {
11 | source: '/',
12 | destination: '/introduction',
13 | permanent: true,
14 | },
15 | ]
16 | },
17 | }
18 |
19 | export default withMDX(config)
20 |
--------------------------------------------------------------------------------
/apps/docs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "docs",
3 | "version": "0.0.0",
4 | "private": true,
5 | "license": "Apache-2.0",
6 | "scripts": {
7 | "dev": "next dev --port 3001",
8 | "build": "next build",
9 | "start": "next start",
10 | "postinstall": "fumadocs-mdx",
11 | "type-check": "tsc --noEmit"
12 | },
13 | "dependencies": {
14 | "@tabler/icons-react": "^3.31.0",
15 | "@vercel/analytics": "1.5.0",
16 | "@vercel/og": "^0.6.5",
17 | "clsx": "^2.1.1",
18 | "fumadocs-core": "^15.0.16",
19 | "fumadocs-mdx": "^11.5.6",
20 | "fumadocs-ui": "^15.0.16",
21 | "lucide-react": "^0.511.0",
22 | "next": "^15.2.3",
23 | "next-themes": "^0.4.6",
24 | "react": "19.1.0",
25 | "react-dom": "19.1.0",
26 | "tailwind-merge": "^3.0.2"
27 | },
28 | "devDependencies": {
29 | "@tailwindcss/postcss": "^4.0.12",
30 | "@types/mdx": "^2.0.13",
31 | "@types/node": "^22.14.1",
32 | "@types/react": "^19.1.2",
33 | "@types/react-dom": "^19.0.4",
34 | "dotenv-cli": "^8.0.0",
35 | "postcss": "^8.5.3",
36 | "tailwindcss": "^4.0.12",
37 | "typescript": "^5.8.2"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/apps/docs/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | export default {
2 | plugins: {
3 | '@tailwindcss/postcss': {},
4 | },
5 | }
6 |
--------------------------------------------------------------------------------
/apps/docs/public/connections.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/docs/public/connections.mp4
--------------------------------------------------------------------------------
/apps/docs/public/favicon/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/docs/public/favicon/android-chrome-192x192.png
--------------------------------------------------------------------------------
/apps/docs/public/favicon/android-chrome-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/docs/public/favicon/android-chrome-512x512.png
--------------------------------------------------------------------------------
/apps/docs/public/favicon/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/docs/public/favicon/apple-touch-icon.png
--------------------------------------------------------------------------------
/apps/docs/public/favicon/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/docs/public/favicon/favicon-16x16.png
--------------------------------------------------------------------------------
/apps/docs/public/favicon/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/docs/public/favicon/favicon-32x32.png
--------------------------------------------------------------------------------
/apps/docs/public/favicon/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/docs/public/favicon/favicon.ico
--------------------------------------------------------------------------------
/apps/docs/public/favicon/site.webmanifest:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Sim Studio",
3 | "short_name": "Sim Studio",
4 | "icons": [
5 | {
6 | "src": "/favicon/android-chrome-192x192.png",
7 | "sizes": "192x192",
8 | "type": "image/png"
9 | },
10 | {
11 | "src": "/favicon/android-chrome-512x512.png",
12 | "sizes": "512x512",
13 | "type": "image/png"
14 | }
15 | ],
16 | "theme_color": "#ffffff",
17 | "background_color": "#ffffff",
18 | "display": "standalone"
19 | }
20 |
--------------------------------------------------------------------------------
/apps/docs/public/loops.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/docs/public/loops.mp4
--------------------------------------------------------------------------------
/apps/docs/public/static/dark/agent-dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/docs/public/static/dark/agent-dark.png
--------------------------------------------------------------------------------
/apps/docs/public/static/dark/api-dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/docs/public/static/dark/api-dark.png
--------------------------------------------------------------------------------
/apps/docs/public/static/dark/condition-dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/docs/public/static/dark/condition-dark.png
--------------------------------------------------------------------------------
/apps/docs/public/static/dark/evaluator-dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/docs/public/static/dark/evaluator-dark.png
--------------------------------------------------------------------------------
/apps/docs/public/static/dark/function-dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/docs/public/static/dark/function-dark.png
--------------------------------------------------------------------------------
/apps/docs/public/static/dark/router-dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/docs/public/static/dark/router-dark.png
--------------------------------------------------------------------------------
/apps/docs/public/static/dark/tooldropdown-dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/docs/public/static/dark/tooldropdown-dark.png
--------------------------------------------------------------------------------
/apps/docs/public/static/dark/variabledropdown-dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/docs/public/static/dark/variabledropdown-dark.png
--------------------------------------------------------------------------------
/apps/docs/public/static/dark/variables-dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/docs/public/static/dark/variables-dark.png
--------------------------------------------------------------------------------
/apps/docs/public/static/light/agent-light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/docs/public/static/light/agent-light.png
--------------------------------------------------------------------------------
/apps/docs/public/static/light/api-light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/docs/public/static/light/api-light.png
--------------------------------------------------------------------------------
/apps/docs/public/static/light/condition-light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/docs/public/static/light/condition-light.png
--------------------------------------------------------------------------------
/apps/docs/public/static/light/evaluator-light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/docs/public/static/light/evaluator-light.png
--------------------------------------------------------------------------------
/apps/docs/public/static/light/function-light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/docs/public/static/light/function-light.png
--------------------------------------------------------------------------------
/apps/docs/public/static/light/router-light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/docs/public/static/light/router-light.png
--------------------------------------------------------------------------------
/apps/docs/public/static/light/tooldropdown-light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/docs/public/static/light/tooldropdown-light.png
--------------------------------------------------------------------------------
/apps/docs/public/static/light/variabledropdown-light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/docs/public/static/light/variabledropdown-light.png
--------------------------------------------------------------------------------
/apps/docs/public/static/light/variables-light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/docs/public/static/light/variables-light.png
--------------------------------------------------------------------------------
/apps/docs/source.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig, defineDocs } from 'fumadocs-mdx/config'
2 |
3 | export const docs = defineDocs({
4 | dir: 'content/docs',
5 | })
6 |
7 | export default defineConfig({
8 | mdxOptions: {
9 | // MDX options
10 | },
11 | })
12 |
--------------------------------------------------------------------------------
/apps/docs/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": ".",
4 | "target": "ESNext",
5 | "lib": ["dom", "dom.iterable", "esnext"],
6 | "allowJs": true,
7 | "skipLibCheck": true,
8 | "strict": true,
9 | "forceConsistentCasingInFileNames": true,
10 | "noEmit": true,
11 | "esModuleInterop": true,
12 | "module": "esnext",
13 | "moduleResolution": "bundler",
14 | "resolveJsonModule": true,
15 | "isolatedModules": true,
16 | "jsx": "preserve",
17 | "incremental": true,
18 | "paths": {
19 | "@/.source": ["./.source/index.ts"],
20 | "@/*": ["./*"]
21 | },
22 | "plugins": [
23 | {
24 | "name": "next"
25 | }
26 | ]
27 | },
28 | "include": [
29 | "next-env.d.ts",
30 | "**/*.ts",
31 | "**/*.tsx",
32 | ".next/types/**/*.ts",
33 | "content/docs/execution/index.mdx",
34 | "content/docs/connections/index.mdx"
35 | ],
36 | "exclude": ["node_modules"]
37 | }
38 |
--------------------------------------------------------------------------------
/apps/sim/.env.example:
--------------------------------------------------------------------------------
1 | # Database (Required)
2 | DATABASE_URL="postgresql://postgres:password@localhost:5432/postgres"
3 |
4 | # Authentication (Required)
5 | BETTER_AUTH_SECRET=your_secret_key # Use `openssl rand -hex 32` to generate, or visit https://www.better-auth.com/docs/installation
6 | BETTER_AUTH_URL=http://localhost:3000
7 |
8 | ## Security (Required)
9 | ENCRYPTION_KEY=your_encryption_key # Use `openssl rand -hex 32` to generate
10 |
11 | # Email Provider (Optional)
12 | # RESEND_API_KEY= # Uncomment and add your key from https://resend.com to send actual emails
13 | # If left commented out, emails will be logged to console instead
14 |
15 | # Freestyle API Key (Required for sandboxed code execution for functions/custom-tools)
16 | # FREESTYLE_API_KEY= # Uncomment and add your key from https://docs.freestyle.sh/Getting-Started/run
17 |
--------------------------------------------------------------------------------
/apps/sim/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /packages/**/node_modules
6 |
7 | # bun specific
8 | .bun
9 | bun.lockb
10 | bun-debug.log*
11 |
12 | # testing
13 | /coverage
14 |
15 | # next.js
16 | /.next/
17 | /out/
18 |
19 | # production
20 | /build
21 | /dist
22 | **/dist/
23 | **/standalone/
24 | sim-standalone.tar.gz
25 |
26 | # misc
27 | .DS_Store
28 | *.pem
29 |
30 | # env files
31 | .env
32 | *.env
33 | .env.local
34 | .env.development
35 | .env.test
36 | .env.production
37 |
38 | # vercel
39 | .vercel
40 |
41 | # typescript
42 | *.tsbuildinfo
43 | next-env.d.ts
44 |
45 | # cursorrules
46 | .cursorrules
47 |
48 | # Sentry Config File
49 | .env.sentry-build-plugin
50 |
51 | # Uploads
52 | /uploads
53 |
--------------------------------------------------------------------------------
/apps/sim/app/(auth)/components/oauth-provider-checker.tsx:
--------------------------------------------------------------------------------
1 | 'use server'
2 |
3 | import { env } from '@/lib/env'
4 | import { isProd } from '@/lib/environment'
5 |
6 | export async function getOAuthProviderStatus() {
7 | const githubAvailable = !!(
8 | env.GITHUB_CLIENT_ID &&
9 | env.GITHUB_CLIENT_SECRET &&
10 | env.GITHUB_CLIENT_ID !== 'placeholder' &&
11 | env.GITHUB_CLIENT_SECRET !== 'placeholder'
12 | )
13 |
14 | const googleAvailable = !!(
15 | env.GOOGLE_CLIENT_ID &&
16 | env.GOOGLE_CLIENT_SECRET &&
17 | env.GOOGLE_CLIENT_ID !== 'placeholder' &&
18 | env.GOOGLE_CLIENT_SECRET !== 'placeholder'
19 | )
20 |
21 | return { githubAvailable, googleAvailable, isProduction: isProd }
22 | }
23 |
--------------------------------------------------------------------------------
/apps/sim/app/(auth)/layout.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import Image from 'next/image'
4 | import Link from 'next/link'
5 | import { GridPattern } from '../(landing)/components/grid-pattern'
6 | import { NotificationList } from '../w/[id]/components/notifications/notifications'
7 |
8 | export default function AuthLayout({ children }: { children: React.ReactNode }) {
9 | return (
10 |
11 | {/* Background pattern */}
12 |
20 |
21 | {/* Header */}
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | {/* Content */}
31 |
34 |
35 | {/* Notifications */}
36 |
37 |
38 |
39 |
40 | )
41 | }
42 |
--------------------------------------------------------------------------------
/apps/sim/app/(auth)/login/page.tsx:
--------------------------------------------------------------------------------
1 | import { getOAuthProviderStatus } from '../components/oauth-provider-checker'
2 | import LoginForm from './login-form'
3 |
4 | // Force dynamic rendering to avoid prerender errors with search params
5 | export const dynamic = 'force-dynamic'
6 |
7 | export default async function LoginPage() {
8 | const { githubAvailable, googleAvailable, isProduction } = await getOAuthProviderStatus()
9 |
10 | return (
11 |
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/apps/sim/app/(auth)/signup/page.tsx:
--------------------------------------------------------------------------------
1 | import { getOAuthProviderStatus } from '../components/oauth-provider-checker'
2 | import SignupForm from './signup-form'
3 |
4 | // Force dynamic rendering to avoid prerender errors with search params
5 | export const dynamic = 'force-dynamic'
6 |
7 | export default async function SignupPage() {
8 | const { githubAvailable, googleAvailable, isProduction } = await getOAuthProviderStatus()
9 |
10 | return (
11 |
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/apps/sim/app/(auth)/verify/page.tsx:
--------------------------------------------------------------------------------
1 | import { env } from '@/lib/env'
2 | import { isProd } from '@/lib/environment'
3 | import { getBaseUrl } from '@/lib/urls/utils'
4 | import { VerifyContent } from './verify-content'
5 |
6 | // Force dynamic rendering to avoid prerender errors with search params
7 | export const dynamic = 'force-dynamic'
8 |
9 | export default function VerifyPage() {
10 | const baseUrl = getBaseUrl()
11 | const hasResendKey = Boolean(env.RESEND_API_KEY && env.RESEND_API_KEY !== 'placeholder')
12 |
13 | return
14 | }
15 |
--------------------------------------------------------------------------------
/apps/sim/app/(landing)/components/github-stars-client.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { motion } from 'framer-motion'
4 | import { GithubIcon } from '@/components/icons'
5 |
6 | interface GitHubStarsClientProps {
7 | stars: string
8 | }
9 |
10 | export default function GitHubStarsClient({ stars }: GitHubStarsClientProps) {
11 | return (
12 |
22 |
23 | {stars}
24 |
25 | )
26 | }
27 |
--------------------------------------------------------------------------------
/apps/sim/app/(landing)/components/hero-edge.tsx:
--------------------------------------------------------------------------------
1 | import { BaseEdge, type EdgeProps, getSmoothStepPath } from 'reactflow'
2 |
3 | export const HeroEdge = ({
4 | id,
5 | sourceX,
6 | sourceY,
7 | targetX,
8 | targetY,
9 | sourcePosition,
10 | targetPosition,
11 | style = {},
12 | markerEnd,
13 | }: EdgeProps) => {
14 | const isHorizontal = sourcePosition === 'right' || sourcePosition === 'left'
15 |
16 | const [edgePath] = getSmoothStepPath({
17 | sourceX,
18 | sourceY,
19 | sourcePosition,
20 | targetX,
21 | targetY,
22 | targetPosition,
23 | borderRadius: 8,
24 | offset: isHorizontal ? 30 : 20,
25 | })
26 |
27 | return (
28 |
39 | )
40 | }
41 |
--------------------------------------------------------------------------------
/apps/sim/app/(landing)/components/hooks/use-is-mobile.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from 'react'
2 |
3 | export default function useIsMobile() {
4 | const [isMobile, setIsMobile] = useState(false)
5 | const [mounted, setMounted] = useState(false)
6 |
7 | useEffect(() => {
8 | setMounted(true)
9 | const checkMobile = () => setIsMobile(window.innerWidth < 768)
10 | checkMobile()
11 |
12 | window.addEventListener('resize', checkMobile)
13 | return () => window.removeEventListener('resize', checkMobile)
14 | }, [])
15 |
16 | return { isMobile, mounted }
17 | }
18 |
--------------------------------------------------------------------------------
/apps/sim/app/(landing)/components/use-window-size.ts:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from 'react'
2 |
3 | interface WindowSize {
4 | width: number | undefined
5 | height: number | undefined
6 | }
7 |
8 | export function useWindowSize(): WindowSize {
9 | const [windowSize, setWindowSize] = useState({
10 | width: undefined,
11 | height: undefined,
12 | })
13 |
14 | useEffect(() => {
15 | // Handler to call on window resize
16 | function handleResize() {
17 | setWindowSize({
18 | width: window.innerWidth,
19 | height: window.innerHeight,
20 | })
21 | }
22 |
23 | // Add event listener
24 | window.addEventListener('resize', handleResize)
25 |
26 | // Call handler right away so state gets updated with initial window size
27 | handleResize()
28 |
29 | // Remove event listener on cleanup
30 | return () => window.removeEventListener('resize', handleResize)
31 | }, [])
32 |
33 | return windowSize
34 | }
35 |
--------------------------------------------------------------------------------
/apps/sim/app/(landing)/landing.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import NavWrapper from './components/nav-wrapper'
4 | import Footer from './components/sections/footer'
5 | import Hero from './components/sections/hero'
6 | import Integrations from './components/sections/integrations'
7 | import Testimonials from './components/sections/testimonials'
8 |
9 | export default function Landing() {
10 | const handleOpenTypeformLink = () => {
11 | window.open('https://form.typeform.com/to/jqCO12pF', '_blank')
12 | }
13 |
14 | return (
15 |
16 |
17 |
18 |
19 |
20 | {/* */}
21 |
22 | {/* */}
23 |
24 | {/* Footer */}
25 |
26 |
27 | )
28 | }
29 |
--------------------------------------------------------------------------------
/apps/sim/app/api/__test-utils__/setup.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * API Test Setup
3 | */
4 | import { afterEach, beforeEach, vi } from 'vitest'
5 |
6 | // Mock Next.js implementations
7 | vi.mock('next/headers', () => ({
8 | cookies: () => ({
9 | get: vi.fn().mockReturnValue({ value: 'test-session-token' }),
10 | }),
11 | headers: () => ({
12 | get: vi.fn().mockReturnValue('test-value'),
13 | }),
14 | }))
15 |
16 | // Mock auth utilities
17 | vi.mock('@/lib/auth/session', () => ({
18 | getSession: vi.fn().mockResolvedValue({
19 | user: {
20 | id: 'user-id',
21 | email: 'test@example.com',
22 | },
23 | sessionToken: 'test-session-token',
24 | }),
25 | }))
26 |
27 | // Configure Vitest environment
28 | beforeEach(() => {
29 | // Clear all mocks before each test
30 | vi.clearAllMocks()
31 | })
32 |
33 | afterEach(() => {
34 | // Ensure all mocks are restored after each test
35 | vi.restoreAllMocks()
36 | })
37 |
--------------------------------------------------------------------------------
/apps/sim/app/api/auth/[...all]/route.ts:
--------------------------------------------------------------------------------
1 | import { toNextJsHandler } from 'better-auth/next-js'
2 | import { auth } from '@/lib/auth'
3 |
4 | export const dynamic = 'force-dynamic'
5 |
6 | export const { GET, POST } = toNextJsHandler(auth.handler)
7 |
--------------------------------------------------------------------------------
/apps/sim/app/api/auth/forget-password/route.ts:
--------------------------------------------------------------------------------
1 | import { type NextRequest, NextResponse } from 'next/server'
2 | import { auth } from '@/lib/auth'
3 | import { createLogger } from '@/lib/logs/console-logger'
4 |
5 | export const dynamic = 'force-dynamic'
6 |
7 | const logger = createLogger('ForgetPasswordAPI')
8 |
9 | export async function POST(request: NextRequest) {
10 | try {
11 | const body = await request.json()
12 | const { email, redirectTo } = body
13 |
14 | if (!email) {
15 | return NextResponse.json({ message: 'Email is required' }, { status: 400 })
16 | }
17 |
18 | await auth.api.forgetPassword({
19 | body: {
20 | email,
21 | redirectTo,
22 | },
23 | method: 'POST',
24 | })
25 |
26 | return NextResponse.json({ success: true })
27 | } catch (error) {
28 | logger.error('Error requesting password reset:', { error })
29 |
30 | return NextResponse.json(
31 | {
32 | message:
33 | error instanceof Error
34 | ? error.message
35 | : 'Failed to send password reset email. Please try again later.',
36 | },
37 | { status: 500 }
38 | )
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/apps/sim/app/api/auth/reset-password/route.ts:
--------------------------------------------------------------------------------
1 | import { type NextRequest, NextResponse } from 'next/server'
2 | import { auth } from '@/lib/auth'
3 | import { createLogger } from '@/lib/logs/console-logger'
4 |
5 | export const dynamic = 'force-dynamic'
6 |
7 | const logger = createLogger('PasswordReset')
8 |
9 | export async function POST(request: NextRequest) {
10 | try {
11 | const body = await request.json()
12 | const { token, newPassword } = body
13 |
14 | if (!token || !newPassword) {
15 | return NextResponse.json({ message: 'Token and new password are required' }, { status: 400 })
16 | }
17 |
18 | await auth.api.resetPassword({
19 | body: {
20 | newPassword,
21 | token,
22 | },
23 | method: 'POST',
24 | })
25 |
26 | return NextResponse.json({ success: true })
27 | } catch (error) {
28 | logger.error('Error during password reset:', { error })
29 |
30 | return NextResponse.json(
31 | {
32 | message:
33 | error instanceof Error
34 | ? error.message
35 | : 'Failed to reset password. Please try again or request a new reset link.',
36 | },
37 | { status: 500 }
38 | )
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/apps/sim/app/api/user/subscription/route.ts:
--------------------------------------------------------------------------------
1 | import { NextResponse } from 'next/server'
2 | import { getSession } from '@/lib/auth'
3 | import { createLogger } from '@/lib/logs/console-logger'
4 | import { getHighestPrioritySubscription } from '@/lib/subscription/subscription'
5 | import { checkEnterprisePlan, checkTeamPlan } from '@/lib/subscription/utils'
6 |
7 | const logger = createLogger('UserSubscriptionAPI')
8 |
9 | export async function GET() {
10 | try {
11 | const session = await getSession()
12 |
13 | if (!session?.user?.id) {
14 | return NextResponse.json({ error: 'Authentication required' }, { status: 401 })
15 | }
16 |
17 | const activeSub = await getHighestPrioritySubscription(session.user.id)
18 |
19 | const isPaid =
20 | activeSub?.status === 'active' &&
21 | ['pro', 'team', 'enterprise'].includes(activeSub?.plan ?? '')
22 |
23 | const isPro = isPaid
24 |
25 | const isTeam = checkTeamPlan(activeSub)
26 |
27 | const isEnterprise = checkEnterprisePlan(activeSub)
28 |
29 | return NextResponse.json({
30 | isPaid,
31 | isPro,
32 | isTeam,
33 | isEnterprise,
34 | plan: activeSub?.plan || 'free',
35 | status: activeSub?.status || null,
36 | seats: activeSub?.seats || null,
37 | metadata: activeSub?.metadata || null,
38 | })
39 | } catch (error) {
40 | logger.error('Error fetching subscription:', error)
41 | return NextResponse.json({ error: 'Failed to fetch subscription data' }, { status: 500 })
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/apps/sim/app/api/user/usage/route.ts:
--------------------------------------------------------------------------------
1 | import { type NextRequest, NextResponse } from 'next/server'
2 | import { getSession } from '@/lib/auth'
3 | import { createLogger } from '@/lib/logs/console-logger'
4 | import { checkUsageStatus } from '@/lib/usage-monitor'
5 |
6 | const logger = createLogger('UserUsageAPI')
7 |
8 | export async function GET(request: NextRequest) {
9 | try {
10 | // Get the authenticated user
11 | const session = await getSession()
12 |
13 | if (!session?.user?.id) {
14 | logger.warn('Unauthorized usage data access attempt')
15 | return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
16 | }
17 |
18 | // Get usage data using our monitor utility
19 | const usageData = await checkUsageStatus(session.user.id)
20 |
21 | // Set appropriate caching headers
22 | const response = NextResponse.json(usageData)
23 |
24 | // Cache for 5 minutes, private (user-specific data), must revalidate
25 | response.headers.set('Cache-Control', 'private, max-age=300, must-revalidate')
26 | // Add date header for age calculation
27 | response.headers.set('Date', new Date().toUTCString())
28 |
29 | return response
30 | } catch (error) {
31 | logger.error('Error checking usage data:', error)
32 | return NextResponse.json({ error: 'Failed to check usage data' }, { status: 500 })
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/apps/sim/app/api/workflows/utils.ts:
--------------------------------------------------------------------------------
1 | import { NextResponse } from 'next/server'
2 |
3 | export function createErrorResponse(error: string, status: number, code?: string) {
4 | return NextResponse.json(
5 | {
6 | error,
7 | code: code || error.toUpperCase().replace(/\s+/g, '_'),
8 | },
9 | { status }
10 | )
11 | }
12 |
13 | export function createSuccessResponse(data: any) {
14 | return NextResponse.json(data)
15 | }
16 |
--------------------------------------------------------------------------------
/apps/sim/app/chat/[subdomain]/components/components/header-links/header-links.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { motion } from 'framer-motion'
4 | import { GithubIcon } from '@/components/icons'
5 |
6 | interface HeaderLinksProps {
7 | stars: string
8 | }
9 |
10 | export default function HeaderLinks({ stars }: HeaderLinksProps) {
11 | return (
12 |
13 |
23 |
24 | {stars}
25 |
26 |
27 | )
28 | }
29 |
--------------------------------------------------------------------------------
/apps/sim/app/chat/[subdomain]/components/loading-state/loading-state.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | export function ChatLoadingState() {
4 | return (
5 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/apps/sim/app/chat/[subdomain]/page.tsx:
--------------------------------------------------------------------------------
1 | import ChatClient from './chat-client'
2 |
3 | export default async function ChatPage({ params }: { params: Promise<{ subdomain: string }> }) {
4 | const { subdomain } = await params
5 | return
6 | }
7 |
--------------------------------------------------------------------------------
/apps/sim/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/sim/app/favicon.ico
--------------------------------------------------------------------------------
/apps/sim/app/global-error.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { useEffect } from 'react'
4 | import * as Sentry from '@sentry/nextjs'
5 | import NextError from 'next/error'
6 |
7 | export default function GlobalError({ error }: { error: Error & { digest?: string } }) {
8 | useEffect(() => {
9 | Sentry.captureException(error)
10 | }, [error])
11 |
12 | return (
13 |
14 |
15 | {/* `NextError` is the default Next.js error page component. Its type
16 | definition requires a `statusCode` prop. However, since the App Router
17 | does not expose status codes for errors, we simply pass 0 to render a
18 | generic error message. */}
19 |
20 |
21 |
22 | )
23 | }
24 |
--------------------------------------------------------------------------------
/apps/sim/app/invite/[id]/page.tsx:
--------------------------------------------------------------------------------
1 | import Invite from './invite'
2 |
3 | export default Invite
4 |
--------------------------------------------------------------------------------
/apps/sim/app/invite/invite-error/page.tsx:
--------------------------------------------------------------------------------
1 | import InviteError from './invite-error'
2 |
3 | // Generate this page on-demand instead of at build time
4 | export const dynamic = 'force-dynamic'
5 |
6 | export default function InviteErrorPage() {
7 | return
8 | }
9 |
--------------------------------------------------------------------------------
/apps/sim/app/page.tsx:
--------------------------------------------------------------------------------
1 | import Landing from './(landing)/landing'
2 |
3 | export default Landing
4 |
--------------------------------------------------------------------------------
/apps/sim/app/w/[id]/components/control-bar/components/deploy-modal/components/deployment-info/components/api-endpoint/api-endpoint.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { CopyButton } from '@/components/ui/copy-button'
4 | import { Label } from '@/components/ui/label'
5 |
6 | interface ApiEndpointProps {
7 | endpoint: string
8 | showLabel?: boolean
9 | }
10 |
11 | export function ApiEndpoint({ endpoint, showLabel = true }: ApiEndpointProps) {
12 | return (
13 |
14 | {showLabel && (
15 |
16 | API Endpoint
17 |
18 | )}
19 |
20 |
{endpoint}
21 |
22 |
23 |
24 | )
25 | }
26 |
--------------------------------------------------------------------------------
/apps/sim/app/w/[id]/components/loop-node/loop-config.ts:
--------------------------------------------------------------------------------
1 | import { RepeatIcon } from 'lucide-react'
2 |
3 | export const LoopTool = {
4 | id: 'loop',
5 | type: 'loop',
6 | name: 'Loop',
7 | description: 'Create a Loop',
8 | icon: RepeatIcon,
9 | bgColor: '#2FB3FF',
10 | data: {
11 | label: 'Loop',
12 | loopType: 'for',
13 | count: 5,
14 | collection: '',
15 | width: 500,
16 | height: 300,
17 | extent: 'parent',
18 | executionState: {
19 | currentIteration: 0,
20 | isExecuting: false,
21 | startTime: null,
22 | endTime: null,
23 | },
24 | },
25 | style: {
26 | width: 500,
27 | height: 300,
28 | },
29 | // Specify that this should be rendered as a ReactFlow group node
30 | isResizable: true,
31 | }
32 |
--------------------------------------------------------------------------------
/apps/sim/app/w/[id]/components/panel/components/console/console.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { useMemo } from 'react'
4 | import { ScrollArea } from '@/components/ui/scroll-area'
5 | import { useConsoleStore } from '@/stores/panel/console/store'
6 | import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
7 | import { ConsoleEntry } from './components/console-entry/console-entry'
8 |
9 | interface ConsoleProps {
10 | panelWidth: number
11 | }
12 |
13 | export function Console({ panelWidth }: ConsoleProps) {
14 | const entries = useConsoleStore((state) => state.entries)
15 | const { activeWorkflowId } = useWorkflowRegistry()
16 |
17 | const filteredEntries = useMemo(() => {
18 | return entries.filter((entry) => entry.workflowId === activeWorkflowId)
19 | }, [entries, activeWorkflowId])
20 |
21 | return (
22 |
23 |
24 | {filteredEntries.length === 0 ? (
25 |
26 | No console entries
27 |
28 | ) : (
29 | filteredEntries.map((entry) => (
30 |
31 | ))
32 | )}
33 |
34 |
35 | )
36 | }
37 |
--------------------------------------------------------------------------------
/apps/sim/app/w/[id]/components/parallel-node/parallel-config.ts:
--------------------------------------------------------------------------------
1 | import { SplitIcon } from 'lucide-react'
2 |
3 | export const ParallelTool = {
4 | id: 'parallel',
5 | type: 'parallel',
6 | name: 'Parallel',
7 | description: 'Parallel Execution',
8 | icon: SplitIcon,
9 | bgColor: '#8BC34A',
10 | data: {
11 | label: 'Parallel',
12 | parallelType: 'collection' as 'collection' | 'count',
13 | count: 5,
14 | collection: '',
15 | extent: 'parent',
16 | executionState: {
17 | currentExecution: 0,
18 | isExecuting: false,
19 | startTime: null,
20 | endTime: null,
21 | },
22 | },
23 | style: {
24 | width: 500,
25 | height: 300,
26 | },
27 | // Specify that this should be rendered as a ReactFlow group node
28 | isResizable: true,
29 | }
30 |
--------------------------------------------------------------------------------
/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/checkbox-list.tsx:
--------------------------------------------------------------------------------
1 | import { Checkbox } from '@/components/ui/checkbox'
2 | import { Label } from '@/components/ui/label'
3 | import { cn } from '@/lib/utils'
4 | import { useSubBlockValue } from '../hooks/use-sub-block-value'
5 |
6 | interface CheckboxListProps {
7 | blockId: string
8 | subBlockId: string
9 | title: string
10 | options: { label: string; id: string }[]
11 | layout?: 'full' | 'half'
12 | }
13 |
14 | export function CheckboxList({ blockId, subBlockId, title, options, layout }: CheckboxListProps) {
15 | return (
16 |
17 | {options.map((option) => {
18 | const [value, setValue] = useSubBlockValue(blockId, option.id)
19 | return (
20 |
21 | setValue(checked as boolean)}
25 | />
26 |
30 | {option.label}
31 |
32 |
33 | )
34 | })}
35 |
36 | )
37 | }
38 |
--------------------------------------------------------------------------------
/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/switch.tsx:
--------------------------------------------------------------------------------
1 | import { Label } from '@/components/ui/label'
2 | import { Switch as UISwitch } from '@/components/ui/switch'
3 | import { useSubBlockValue } from '../hooks/use-sub-block-value'
4 |
5 | interface SwitchProps {
6 | blockId: string
7 | subBlockId: string
8 | title: string
9 | }
10 |
11 | export function Switch({ blockId, subBlockId, title }: SwitchProps) {
12 | const [value, setValue] = useSubBlockValue(blockId, subBlockId)
13 |
14 | return (
15 |
16 |
17 | {title}
18 |
19 | setValue(checked)} />
20 |
21 | )
22 | }
23 |
--------------------------------------------------------------------------------
/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/ui/config-section.tsx:
--------------------------------------------------------------------------------
1 | import type React from 'react'
2 | import { cn } from '@/lib/utils'
3 |
4 | interface ConfigSectionProps {
5 | title?: string
6 | children: React.ReactNode
7 | className?: string
8 | }
9 |
10 | export function ConfigSection({ title, children, className }: ConfigSectionProps) {
11 | return (
12 |
15 | {children}
16 |
17 | )
18 | }
19 |
--------------------------------------------------------------------------------
/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/ui/instructions-section.tsx:
--------------------------------------------------------------------------------
1 | import type React from 'react'
2 | import { cn } from '@/lib/utils'
3 |
4 | interface InstructionsSectionProps {
5 | title?: string
6 | children: React.ReactNode
7 | tip?: string
8 | className?: string
9 | }
10 |
11 | export function InstructionsSection({
12 | title = 'Setup Instructions',
13 | children,
14 | tip,
15 | className,
16 | }: InstructionsSectionProps) {
17 | return (
18 |
19 |
{title}
20 |
21 | {children} {/* Instructions list goes here */}
22 |
23 |
24 | )
25 | }
26 |
--------------------------------------------------------------------------------
/apps/sim/app/w/[id]/layout.tsx:
--------------------------------------------------------------------------------
1 | import { ErrorBoundary } from './components/error'
2 |
3 | export default function WorkflowLayout({ children }: { children: React.ReactNode }) {
4 | return (
5 |
6 | {children}
7 |
8 | )
9 | }
10 |
--------------------------------------------------------------------------------
/apps/sim/app/w/[id]/page.tsx:
--------------------------------------------------------------------------------
1 | import WorkFlow from './workflow'
2 |
3 | export default WorkFlow
4 |
--------------------------------------------------------------------------------
/apps/sim/app/w/components/providers/providers.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { TooltipProvider } from '@/components/ui/tooltip'
4 | import { ThemeProvider } from './theme-provider'
5 |
6 | export default function Providers({ children }: { children: React.ReactNode }) {
7 | return (
8 |
9 |
10 | {children}
11 |
12 |
13 | )
14 | }
15 |
--------------------------------------------------------------------------------
/apps/sim/app/w/components/providers/theme-provider.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { useEffect } from 'react'
4 | import { useGeneralStore } from '@/stores/settings/general/store'
5 |
6 | export function ThemeProvider({ children }: { children: React.ReactNode }) {
7 | const theme = useGeneralStore((state) => state.theme)
8 |
9 | useEffect(() => {
10 | const root = window.document.documentElement
11 | root.classList.remove('light', 'dark')
12 |
13 | // If theme is system, check system preference
14 | if (theme === 'system') {
15 | const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches
16 | root.classList.add(prefersDark ? 'dark' : 'light')
17 | } else {
18 | root.classList.add(theme)
19 | }
20 | }, [theme])
21 |
22 | return children
23 | }
24 |
--------------------------------------------------------------------------------
/apps/sim/app/w/error.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { NextError } from './[id]/components/error'
4 |
5 | export default NextError
6 |
--------------------------------------------------------------------------------
/apps/sim/app/w/global-error.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { NextGlobalError } from './[id]/components/error'
4 |
5 | export default NextGlobalError
6 |
--------------------------------------------------------------------------------
/apps/sim/app/w/hooks/use-registry-loading.ts:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { useEffect } from 'react'
4 | import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
5 |
6 | /**
7 | * Custom hook to manage workflow registry loading state
8 | *
9 | * This hook initializes the loading state and automatically clears it
10 | * when workflows are loaded or after a timeout
11 | */
12 | export function useRegistryLoading() {
13 | const { workflows, setLoading } = useWorkflowRegistry()
14 |
15 | useEffect(() => {
16 | // Set loading state initially
17 | setLoading(true)
18 |
19 | // If workflows are already loaded, clear loading state
20 | if (Object.keys(workflows).length > 0) {
21 | setTimeout(() => setLoading(false), 300)
22 | return
23 | }
24 |
25 | // Create a timeout to clear loading state after max time
26 | const timeout = setTimeout(() => {
27 | setLoading(false)
28 | }, 3000) // 3 second maximum loading time
29 |
30 | // Listen for workflows to be loaded
31 | const checkInterval = setInterval(() => {
32 | const currentWorkflows = useWorkflowRegistry.getState().workflows
33 | if (Object.keys(currentWorkflows).length > 0) {
34 | setLoading(false)
35 | clearInterval(checkInterval)
36 | }
37 | }, 200)
38 |
39 | return () => {
40 | clearTimeout(timeout)
41 | clearInterval(checkInterval)
42 | }
43 | }, [setLoading, workflows])
44 | }
45 |
--------------------------------------------------------------------------------
/apps/sim/app/w/knowledge/[id]/[documentId]/page.tsx:
--------------------------------------------------------------------------------
1 | import { Document } from './document'
2 |
3 | interface DocumentPageProps {
4 | params: Promise<{
5 | id: string
6 | documentId: string
7 | }>
8 | searchParams: Promise<{
9 | kbName?: string
10 | docName?: string
11 | }>
12 | }
13 |
14 | export default async function DocumentChunksPage({ params, searchParams }: DocumentPageProps) {
15 | const { id, documentId } = await params
16 | const { kbName, docName } = await searchParams
17 |
18 | return (
19 |
25 | )
26 | }
27 |
--------------------------------------------------------------------------------
/apps/sim/app/w/knowledge/[id]/page.tsx:
--------------------------------------------------------------------------------
1 | import { KnowledgeBase } from './base'
2 |
3 | interface PageProps {
4 | params: Promise<{
5 | id: string
6 | }>
7 | searchParams: Promise<{
8 | kbName?: string
9 | }>
10 | }
11 |
12 | export default async function KnowledgeBasePage({ params, searchParams }: PageProps) {
13 | const { id } = await params
14 | const { kbName } = await searchParams
15 |
16 | return
17 | }
18 |
--------------------------------------------------------------------------------
/apps/sim/app/w/knowledge/components/empty-state-card/empty-state-card.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { LibraryBig } from 'lucide-react'
4 |
5 | interface EmptyStateCardProps {
6 | title: string
7 | description: string
8 | buttonText: string
9 | onClick: () => void
10 | icon?: React.ReactNode
11 | }
12 |
13 | export function EmptyStateCard({
14 | title,
15 | description,
16 | buttonText,
17 | onClick,
18 | icon,
19 | }: EmptyStateCardProps) {
20 | return (
21 |
25 |
26 | {icon || }
27 |
{title}
28 |
29 |
30 |
31 |
32 | Get started
33 |
34 |
35 |
{description}
36 |
37 |
38 | )
39 | }
40 |
--------------------------------------------------------------------------------
/apps/sim/app/w/knowledge/page.tsx:
--------------------------------------------------------------------------------
1 | import { Knowledge } from './knowledge'
2 |
3 | export default function KnowledgePage() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/apps/sim/app/w/layout.tsx:
--------------------------------------------------------------------------------
1 | import Providers from './components/providers/providers'
2 | import { Sidebar } from './components/sidebar/sidebar'
3 |
4 | export default function WorkspaceLayout({ children }: { children: React.ReactNode }) {
5 | return (
6 |
7 |
8 |
9 |
10 |
11 |
{children}
12 |
13 |
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/apps/sim/app/w/logs/components/filters/components/filter-section.tsx:
--------------------------------------------------------------------------------
1 | import { useState } from 'react'
2 | import { ChevronDown } from 'lucide-react'
3 | import { Button } from '@/components/ui/button'
4 | import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible'
5 |
6 | export default function FilterSection({
7 | title,
8 | defaultOpen = false,
9 | content,
10 | }: {
11 | title: string
12 | defaultOpen?: boolean
13 | content?: React.ReactNode
14 | }) {
15 | const [isOpen, setIsOpen] = useState(defaultOpen)
16 |
17 | return (
18 |
19 |
20 |
24 | {title}
25 |
30 |
31 |
32 |
33 | {content || (
34 |
35 | Filter options for {title} will go here
36 |
37 | )}
38 |
39 |
40 | )
41 | }
42 |
--------------------------------------------------------------------------------
/apps/sim/app/w/logs/page.tsx:
--------------------------------------------------------------------------------
1 | import Logs from './logs'
2 |
3 | export default Logs
4 |
--------------------------------------------------------------------------------
/apps/sim/app/w/logs/utils/format-date.ts:
--------------------------------------------------------------------------------
1 | import { format } from 'date-fns'
2 |
3 | /**
4 | * Helper function to format date in various formats
5 | */
6 | export const formatDate = (dateString: string) => {
7 | const date = new Date(dateString)
8 | return {
9 | full: date.toLocaleDateString('en-US', {
10 | month: 'short',
11 | day: 'numeric',
12 | year: 'numeric',
13 | hour: '2-digit',
14 | minute: '2-digit',
15 | second: '2-digit',
16 | hour12: false,
17 | }),
18 | time: date.toLocaleTimeString([], {
19 | hour: '2-digit',
20 | minute: '2-digit',
21 | second: '2-digit',
22 | hour12: false,
23 | }),
24 | formatted: format(date, 'HH:mm:ss'),
25 | relative: (() => {
26 | const now = new Date()
27 | const diffMs = now.getTime() - date.getTime()
28 | const diffMins = Math.floor(diffMs / 60000)
29 |
30 | if (diffMins < 1) return 'just now'
31 | if (diffMins < 60) return `${diffMins}m ago`
32 |
33 | const diffHours = Math.floor(diffMins / 60)
34 | if (diffHours < 24) return `${diffHours}h ago`
35 |
36 | const diffDays = Math.floor(diffHours / 24)
37 | if (diffDays === 1) return 'yesterday'
38 | if (diffDays < 7) return `${diffDays}d ago`
39 |
40 | return format(date, 'MMM d')
41 | })(),
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/apps/sim/app/w/marketplace/components/error-message.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { motion } from 'framer-motion'
4 | import { AlertCircle } from 'lucide-react'
5 |
6 | /**
7 | * ErrorMessageProps interface - defines the properties for the ErrorMessage component
8 | * @property {string | null} message - The error message to display, or null if no error
9 | */
10 | interface ErrorMessageProps {
11 | message: string | null
12 | }
13 |
14 | /**
15 | * ErrorMessage component - Displays an error message with animation
16 | * Only renders when a message is provided, otherwise returns null
17 | * Uses Framer Motion for smooth entrance animation
18 | */
19 | export function ErrorMessage({ message }: ErrorMessageProps) {
20 | // Don't render anything if there's no message
21 | if (!message) return null
22 |
23 | return (
24 |
30 |
31 |
32 | {message}
33 |
34 |
35 | )
36 | }
37 |
--------------------------------------------------------------------------------
/apps/sim/app/w/marketplace/components/section.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { forwardRef, type ReactNode } from 'react'
4 |
5 | /**
6 | * SectionProps interface - defines the properties for the Section component
7 | * @property {string} title - The heading text for the section
8 | * @property {string} id - The ID for the section (used for scroll targeting)
9 | * @property {ReactNode} children - The content to be rendered inside the section
10 | */
11 | interface SectionProps {
12 | title: string
13 | id: string
14 | children: ReactNode
15 | }
16 |
17 | /**
18 | * Section component - Renders a section with a title and content
19 | * Used to organize different categories of workflows in the marketplace
20 | * Implements forwardRef to allow parent components to access the DOM node for scrolling
21 | */
22 | export const Section = forwardRef(({ title, id, children }, ref) => {
23 | return (
24 |
25 |
{title}
26 | {children}
27 |
28 | )
29 | })
30 |
31 | Section.displayName = 'Section'
32 |
--------------------------------------------------------------------------------
/apps/sim/app/w/marketplace/page.tsx:
--------------------------------------------------------------------------------
1 | import Marketplace from './marketplace'
2 |
3 | export default Marketplace
4 |
--------------------------------------------------------------------------------
/apps/sim/app/zoom-prevention.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { useEffect } from 'react'
4 |
5 | export function ZoomPrevention() {
6 | useEffect(() => {
7 | const preventZoom = (e: KeyboardEvent | WheelEvent) => {
8 | // Prevent zoom on ctrl/cmd + wheel
9 | if (e instanceof WheelEvent && (e.ctrlKey || e.metaKey)) {
10 | e.preventDefault()
11 | }
12 |
13 | // Prevent zoom on ctrl/cmd + plus/minus/zero
14 | if (e instanceof KeyboardEvent && (e.ctrlKey || e.metaKey)) {
15 | if (e.key === '=' || e.key === '-' || e.key === '0') {
16 | e.preventDefault()
17 | }
18 | }
19 | }
20 |
21 | // Add event listeners
22 | document.addEventListener('wheel', preventZoom, { passive: false })
23 | document.addEventListener('keydown', preventZoom)
24 |
25 | // Cleanup
26 | return () => {
27 | document.removeEventListener('wheel', preventZoom)
28 | document.removeEventListener('keydown', preventZoom)
29 | }
30 | }, [])
31 |
32 | return null
33 | }
34 |
--------------------------------------------------------------------------------
/apps/sim/blocks/blocks/condition.ts:
--------------------------------------------------------------------------------
1 | import { ConditionalIcon } from '@/components/icons'
2 | import type { BlockConfig } from '../types'
3 |
4 | interface ConditionBlockOutput {
5 | success: boolean
6 | output: {
7 | content: string
8 | conditionResult: boolean
9 | selectedPath: {
10 | blockId: string
11 | blockType: string
12 | blockTitle: string
13 | }
14 | selectedConditionId: string
15 | }
16 | }
17 |
18 | export const ConditionBlock: BlockConfig = {
19 | type: 'condition',
20 | name: 'Condition',
21 | description: 'Add a condition',
22 | longDescription:
23 | 'Add a condition to the workflow to branch the execution path based on a boolean expression.',
24 | docsLink: 'https://docs.simstudio.ai/blocks/condition',
25 | bgColor: '#FF752F',
26 | icon: ConditionalIcon,
27 | category: 'blocks',
28 | subBlocks: [
29 | {
30 | id: 'conditions',
31 | type: 'condition-input',
32 | layout: 'full',
33 | },
34 | ],
35 | tools: {
36 | access: [],
37 | },
38 | inputs: {},
39 | outputs: {
40 | response: {
41 | type: {
42 | content: 'string',
43 | conditionResult: 'boolean',
44 | selectedPath: 'json',
45 | selectedConditionId: 'string',
46 | },
47 | },
48 | },
49 | }
50 |
--------------------------------------------------------------------------------
/apps/sim/blocks/blocks/function.ts:
--------------------------------------------------------------------------------
1 | import { CodeIcon } from '@/components/icons'
2 | import type { CodeExecutionOutput } from '@/tools/function/types'
3 | import type { BlockConfig } from '../types'
4 |
5 | export const FunctionBlock: BlockConfig = {
6 | type: 'function',
7 | name: 'Function',
8 | description: 'Run custom logic',
9 | longDescription:
10 | 'Execute custom JavaScript or TypeScript code within your workflow to transform data or implement complex logic. Create reusable functions to process inputs and generate outputs for other blocks.',
11 | docsLink: 'https://docs.simstudio.ai/blocks/function',
12 | category: 'blocks',
13 | bgColor: '#FF402F',
14 | icon: CodeIcon,
15 | subBlocks: [
16 | {
17 | id: 'code',
18 | type: 'code',
19 | layout: 'full',
20 | },
21 | ],
22 | tools: {
23 | access: ['function_execute'],
24 | },
25 | inputs: {
26 | code: { type: 'string', required: false },
27 | timeout: { type: 'number', required: false },
28 | },
29 | outputs: {
30 | response: {
31 | type: {
32 | result: 'any',
33 | stdout: 'string',
34 | },
35 | },
36 | },
37 | }
38 |
--------------------------------------------------------------------------------
/apps/sim/blocks/blocks/thinking.ts:
--------------------------------------------------------------------------------
1 | import { BrainIcon } from '@/components/icons'
2 | import type { ToolResponse } from '@/tools/types'
3 | import type { BlockConfig } from '../types'
4 |
5 | interface ThinkingToolResponse extends ToolResponse {
6 | output: {
7 | acknowledgedThought: string
8 | }
9 | }
10 |
11 | export const ThinkingBlock: BlockConfig = {
12 | type: 'thinking',
13 | name: 'Thinking',
14 | description: 'Forces model to outline its thought process.',
15 | longDescription:
16 | 'Adds a step where the model explicitly outlines its thought process before proceeding. This can improve reasoning quality by encouraging step-by-step analysis.',
17 | docsLink: 'https://docs.simstudio.ai/tools/thinking',
18 | category: 'tools',
19 | bgColor: '#181C1E',
20 | icon: BrainIcon,
21 | hideFromToolbar: true,
22 |
23 | subBlocks: [
24 | {
25 | id: 'thought',
26 | title: 'Thought Process / Instruction',
27 | type: 'long-input',
28 | layout: 'full',
29 | placeholder: 'Describe the step-by-step thinking process here...',
30 | hidden: true,
31 | },
32 | ],
33 |
34 | inputs: {
35 | thought: { type: 'string', required: true },
36 | },
37 |
38 | outputs: {
39 | response: {
40 | type: {
41 | acknowledgedThought: 'string',
42 | },
43 | },
44 | },
45 |
46 | tools: {
47 | access: ['thinking_tool'],
48 | },
49 | }
50 |
--------------------------------------------------------------------------------
/apps/sim/blocks/index.ts:
--------------------------------------------------------------------------------
1 | import {
2 | getAllBlocks,
3 | getAllBlockTypes,
4 | getBlock,
5 | getBlocksByCategory,
6 | isValidBlockType,
7 | registry,
8 | } from './registry'
9 |
10 | export { registry, getBlock, getBlocksByCategory, getAllBlockTypes, isValidBlockType, getAllBlocks }
11 |
12 | export type { BlockConfig } from './types'
13 |
--------------------------------------------------------------------------------
/apps/sim/components.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://ui.shadcn.com/schema.json",
3 | "style": "default",
4 | "rsc": true,
5 | "tsx": true,
6 | "tailwind": {
7 | "config": "tailwind.config.ts",
8 | "css": "app/globals.css",
9 | "baseColor": "neutral",
10 | "cssVariables": true,
11 | "prefix": ""
12 | },
13 | "aliases": {
14 | "components": "@/components",
15 | "utils": "@/lib/utils",
16 | "ui": "@/components/ui",
17 | "lib": "@/lib",
18 | "hooks": "@/hooks",
19 | "blocks": "@/blocks"
20 | },
21 | "iconLibrary": "lucide"
22 | }
23 |
--------------------------------------------------------------------------------
/apps/sim/components/ui/badge.tsx:
--------------------------------------------------------------------------------
1 | import type * as React from 'react'
2 | import { cva, type VariantProps } from 'class-variance-authority'
3 | import { cn } from '@/lib/utils'
4 |
5 | const badgeVariants = cva(
6 | 'inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2',
7 | {
8 | variants: {
9 | variant: {
10 | default: 'border-transparent bg-primary text-primary-foreground hover:bg-primary/80',
11 | secondary:
12 | 'border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80',
13 | destructive:
14 | 'border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80',
15 | outline: 'text-foreground',
16 | },
17 | },
18 | defaultVariants: {
19 | variant: 'default',
20 | },
21 | }
22 | )
23 |
24 | export interface BadgeProps
25 | extends React.HTMLAttributes,
26 | VariantProps {}
27 |
28 | function Badge({ className, variant, ...props }: BadgeProps) {
29 | return
30 | }
31 |
32 | export { Badge, badgeVariants }
33 |
--------------------------------------------------------------------------------
/apps/sim/components/ui/checkbox.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import * as React from 'react'
4 | import * as CheckboxPrimitive from '@radix-ui/react-checkbox'
5 | import { Check } from 'lucide-react'
6 | import { cn } from '@/lib/utils'
7 |
8 | const Checkbox = React.forwardRef<
9 | React.ElementRef,
10 | React.ComponentPropsWithoutRef
11 | >(({ className, ...props }, ref) => (
12 |
20 |
21 |
22 |
23 |
24 | ))
25 | Checkbox.displayName = CheckboxPrimitive.Root.displayName
26 |
27 | export { Checkbox }
28 |
--------------------------------------------------------------------------------
/apps/sim/components/ui/code-block.tsx:
--------------------------------------------------------------------------------
1 | import type React from 'react'
2 | import { CopyButton } from '@/components/ui/copy-button'
3 | import { cn } from '@/lib/utils'
4 |
5 | interface CodeBlockProps extends React.HTMLAttributes {
6 | code: string
7 | language?: string
8 | }
9 |
10 | export function CodeBlock({ code, language, className, ...props }: CodeBlockProps) {
11 | return (
12 |
13 |
14 | {code}
15 |
16 |
17 |
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/apps/sim/components/ui/collapsible.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import * as CollapsiblePrimitive from '@radix-ui/react-collapsible'
4 |
5 | const Collapsible = CollapsiblePrimitive.Root
6 |
7 | const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger
8 |
9 | const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent
10 |
11 | export { Collapsible, CollapsibleTrigger, CollapsibleContent }
12 |
--------------------------------------------------------------------------------
/apps/sim/components/ui/copy-button.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { useState } from 'react'
4 | import { Check, Copy } from 'lucide-react'
5 | import { Button } from '@/components/ui/button'
6 |
7 | interface CopyButtonProps {
8 | text: string
9 | className?: string
10 | showLabel?: boolean
11 | }
12 |
13 | export function CopyButton({ text, className = '', showLabel = true }: CopyButtonProps) {
14 | const [copied, setCopied] = useState(false)
15 |
16 | const copyToClipboard = () => {
17 | navigator.clipboard.writeText(text)
18 | setCopied(true)
19 | setTimeout(() => setCopied(false), 2000)
20 | }
21 |
22 | return (
23 |
24 | {showLabel && (
25 |
26 | {copied ? 'Copied!' : 'Click to copy'}
27 |
28 | )}
29 |
{
35 | e.stopPropagation() // Prevent click from affecting parent elements
36 | copyToClipboard()
37 | }}
38 | title='Copy to clipboard'
39 | >
40 | {copied ? (
41 |
42 | ) : (
43 |
44 | )}
45 |
46 |
47 | )
48 | }
49 |
--------------------------------------------------------------------------------
/apps/sim/components/ui/input.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react'
2 | import { cn } from '@/lib/utils'
3 |
4 | const Input = React.forwardRef>(
5 | ({ className, type, autoComplete = 'off', ...props }, ref) => {
6 | return (
7 |
20 | )
21 | }
22 | )
23 | Input.displayName = 'Input'
24 |
25 | export { Input }
26 |
--------------------------------------------------------------------------------
/apps/sim/components/ui/label.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import * as React from 'react'
4 | import * as LabelPrimitive from '@radix-ui/react-label'
5 | import { cva, type VariantProps } from 'class-variance-authority'
6 | import { cn } from '@/lib/utils'
7 |
8 | const labelVariants = cva(
9 | 'text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70'
10 | )
11 |
12 | const Label = React.forwardRef<
13 | React.ElementRef,
14 | React.ComponentPropsWithoutRef & VariantProps
15 | >(({ className, ...props }, ref) => (
16 |
17 | ))
18 | Label.displayName = LabelPrimitive.Root.displayName
19 |
20 | export { Label }
21 |
--------------------------------------------------------------------------------
/apps/sim/components/ui/popover.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import * as React from 'react'
4 | import * as PopoverPrimitive from '@radix-ui/react-popover'
5 | import { cn } from '@/lib/utils'
6 |
7 | const Popover = PopoverPrimitive.Root
8 |
9 | const PopoverTrigger = PopoverPrimitive.Trigger
10 |
11 | const PopoverContent = React.forwardRef<
12 | React.ElementRef,
13 | React.ComponentPropsWithoutRef
14 | >(({ className, align = 'center', sideOffset = 4, ...props }, ref) => (
15 |
16 |
26 |
27 | ))
28 | PopoverContent.displayName = PopoverPrimitive.Content.displayName
29 |
30 | export { Popover, PopoverTrigger, PopoverContent }
31 |
--------------------------------------------------------------------------------
/apps/sim/components/ui/progress.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import * as React from 'react'
4 | import * as ProgressPrimitive from '@radix-ui/react-progress'
5 | import { cn } from '@/lib/utils'
6 |
7 | const Progress = React.forwardRef<
8 | React.ElementRef,
9 | React.ComponentPropsWithoutRef
10 | >(({ className, value, ...props }, ref) => (
11 |
16 |
20 |
21 | ))
22 | Progress.displayName = ProgressPrimitive.Root.displayName
23 |
24 | export { Progress }
25 |
--------------------------------------------------------------------------------
/apps/sim/components/ui/separator.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import * as React from 'react'
4 | import * as SeparatorPrimitive from '@radix-ui/react-separator'
5 | import { cn } from '@/lib/utils'
6 |
7 | const Separator = React.forwardRef<
8 | React.ElementRef,
9 | React.ComponentPropsWithoutRef
10 | >(({ className, orientation = 'horizontal', decorative = true, ...props }, ref) => (
11 |
22 | ))
23 | Separator.displayName = SeparatorPrimitive.Root.displayName
24 |
25 | export { Separator }
26 |
--------------------------------------------------------------------------------
/apps/sim/components/ui/skeleton.tsx:
--------------------------------------------------------------------------------
1 | import { cn } from '@/lib/utils'
2 |
3 | function Skeleton({ className, ...props }: React.HTMLAttributes) {
4 | return
5 | }
6 |
7 | export { Skeleton }
8 |
--------------------------------------------------------------------------------
/apps/sim/components/ui/slider.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import * as React from 'react'
4 | import * as SliderPrimitive from '@radix-ui/react-slider'
5 | import { cn } from '@/lib/utils'
6 |
7 | const Slider = React.forwardRef<
8 | React.ElementRef,
9 | React.ComponentPropsWithoutRef
10 | >(({ className, ...props }, ref) => (
11 |
16 |
17 |
18 |
19 |
20 |
21 | ))
22 | Slider.displayName = SliderPrimitive.Root.displayName
23 |
24 | export { Slider }
25 |
--------------------------------------------------------------------------------
/apps/sim/components/ui/switch.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import * as React from 'react'
4 | import * as SwitchPrimitives from '@radix-ui/react-switch'
5 | import { cn } from '@/lib/utils'
6 |
7 | const Switch = React.forwardRef<
8 | React.ElementRef,
9 | React.ComponentPropsWithoutRef
10 | >(({ className, ...props }, ref) => (
11 |
19 |
24 |
25 | ))
26 | Switch.displayName = SwitchPrimitives.Root.displayName
27 |
28 | export { Switch }
29 |
--------------------------------------------------------------------------------
/apps/sim/components/ui/textarea.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react'
2 | import { cn } from '@/lib/utils'
3 |
4 | const Textarea = React.forwardRef>(
5 | ({ className, ...props }, ref) => {
6 | return (
7 |
15 | )
16 | }
17 | )
18 | Textarea.displayName = 'Textarea'
19 |
20 | export { Textarea }
21 |
--------------------------------------------------------------------------------
/apps/sim/db/index.ts:
--------------------------------------------------------------------------------
1 | import { drizzle } from 'drizzle-orm/postgres-js'
2 | import postgres from 'postgres'
3 | import { env } from '@/lib/env'
4 |
5 | // In production, use the Vercel-generated POSTGRES_URL
6 | // In development, use the direct DATABASE_URL
7 | const connectionString = env.POSTGRES_URL ?? env.DATABASE_URL
8 |
9 | // Disable prefetch as it is not supported for "Transaction" pool mode
10 | const client = postgres(connectionString, {
11 | prepare: false,
12 | idle_timeout: 30, // Keep connections alive for 30 seconds when idle
13 | connect_timeout: 30, // Timeout after 30 seconds when connecting
14 | })
15 |
16 | // Export the database client (never null)
17 | export const db = drizzle(client)
18 |
--------------------------------------------------------------------------------
/apps/sim/db/migrations/0001_foamy_dakota_north.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE "workflow" (
2 | "id" text PRIMARY KEY NOT NULL,
3 | "user_id" text NOT NULL,
4 | "name" text NOT NULL,
5 | "description" text,
6 | "state" text NOT NULL,
7 | "last_synced" timestamp NOT NULL,
8 | "created_at" timestamp NOT NULL,
9 | "updated_at" timestamp NOT NULL
10 | );
11 | --> statement-breakpoint
12 | ALTER TABLE "workflow" ADD CONSTRAINT "workflow_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
--------------------------------------------------------------------------------
/apps/sim/db/migrations/0002_previous_xavin.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE "waitlist" (
2 | "id" text PRIMARY KEY NOT NULL,
3 | "email" text NOT NULL,
4 | "status" text DEFAULT 'pending' NOT NULL,
5 | "created_at" timestamp DEFAULT now() NOT NULL,
6 | "updated_at" timestamp DEFAULT now() NOT NULL,
7 | CONSTRAINT "waitlist_email_unique" UNIQUE("email")
8 | );
9 |
--------------------------------------------------------------------------------
/apps/sim/db/migrations/0003_smiling_hammerhead.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE "logs" (
2 | "id" text PRIMARY KEY NOT NULL,
3 | "workflow_id" text NOT NULL,
4 | "execution_id" text,
5 | "level" text NOT NULL,
6 | "message" text NOT NULL,
7 | "created_at" timestamp DEFAULT now() NOT NULL
8 | );
9 | --> statement-breakpoint
10 | CREATE TABLE "user_environment" (
11 | "id" text PRIMARY KEY NOT NULL,
12 | "user_id" text NOT NULL,
13 | "variables" text NOT NULL,
14 | "updated_at" timestamp DEFAULT now() NOT NULL,
15 | CONSTRAINT "user_environment_user_id_unique" UNIQUE("user_id")
16 | );
17 | --> statement-breakpoint
18 | CREATE TABLE "user_settings" (
19 | "id" text PRIMARY KEY NOT NULL,
20 | "user_id" text NOT NULL,
21 | "is_auto_connect_enabled" boolean DEFAULT true NOT NULL,
22 | "updated_at" timestamp DEFAULT now() NOT NULL,
23 | CONSTRAINT "user_settings_user_id_unique" UNIQUE("user_id")
24 | );
25 | --> statement-breakpoint
26 | ALTER TABLE "logs" ADD CONSTRAINT "logs_workflow_id_workflow_id_fk" FOREIGN KEY ("workflow_id") REFERENCES "public"."workflow"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
27 | ALTER TABLE "user_environment" ADD CONSTRAINT "user_environment_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
28 | ALTER TABLE "user_settings" ADD CONSTRAINT "user_settings_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
--------------------------------------------------------------------------------
/apps/sim/db/migrations/0004_nasty_mesmero.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "user_settings" ADD COLUMN "is_debug_mode_enabled" boolean DEFAULT false NOT NULL;
--------------------------------------------------------------------------------
/apps/sim/db/migrations/0005_shocking_domino.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE "workflow_schedule" (
2 | "id" text PRIMARY KEY NOT NULL,
3 | "workflow_id" text NOT NULL,
4 | "cron_expression" text,
5 | "next_run_at" timestamp,
6 | "last_ran_at" timestamp,
7 | "trigger_type" text NOT NULL,
8 | "timezone" text DEFAULT 'UTC' NOT NULL,
9 | "created_at" timestamp DEFAULT now() NOT NULL,
10 | "updated_at" timestamp DEFAULT now() NOT NULL
11 | );
12 | --> statement-breakpoint
13 | ALTER TABLE "workflow_schedule" ADD CONSTRAINT "workflow_schedule_workflow_id_workflow_id_fk" FOREIGN KEY ("workflow_id") REFERENCES "public"."workflow"("id") ON DELETE cascade ON UPDATE no action;
--------------------------------------------------------------------------------
/apps/sim/db/migrations/0007_mute_stepford_cuckoos.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "workflow_schedule" ADD CONSTRAINT "workflow_schedule_workflow_id_unique" UNIQUE("workflow_id");
--------------------------------------------------------------------------------
/apps/sim/db/migrations/0008_quick_paladin.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "workflow_logs" ADD COLUMN "duration" text;
--------------------------------------------------------------------------------
/apps/sim/db/migrations/0009_cynical_bullseye.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "workflow" ADD COLUMN "is_deployed" boolean DEFAULT false NOT NULL;--> statement-breakpoint
2 | ALTER TABLE "workflow" ADD COLUMN "deployed_at" timestamp;--> statement-breakpoint
3 | ALTER TABLE "workflow" ADD COLUMN "api_key" text;
--------------------------------------------------------------------------------
/apps/sim/db/migrations/0009_far_sharon_ventura.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "workflow_schedule" DROP COLUMN "timezone";
--------------------------------------------------------------------------------
/apps/sim/db/migrations/0010_flashy_nebula.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "workflow_logs" ADD COLUMN "trigger" text NOT NULL;
--------------------------------------------------------------------------------
/apps/sim/db/migrations/0011_youthful_iron_lad.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "workflow_logs" ALTER COLUMN "trigger" DROP NOT NULL;
--------------------------------------------------------------------------------
/apps/sim/db/migrations/0012_minor_dexter_bennett.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "workflow" ADD COLUMN "color" text DEFAULT '#3972F6' NOT NULL;
--------------------------------------------------------------------------------
/apps/sim/db/migrations/0013_dusty_aaron_stack.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE "webhook" (
2 | "id" text PRIMARY KEY NOT NULL,
3 | "workflow_id" text NOT NULL,
4 | "path" text NOT NULL,
5 | "secret" text,
6 | "provider" text,
7 | "is_active" boolean DEFAULT true NOT NULL,
8 | "created_at" timestamp DEFAULT now() NOT NULL,
9 | "updated_at" timestamp DEFAULT now() NOT NULL
10 | );
11 | --> statement-breakpoint
12 | ALTER TABLE "webhook" ADD CONSTRAINT "webhook_workflow_id_workflow_id_fk" FOREIGN KEY ("workflow_id") REFERENCES "public"."workflow"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
13 | CREATE UNIQUE INDEX "path_idx" ON "webhook" USING btree ("path");
--------------------------------------------------------------------------------
/apps/sim/db/migrations/0014_nice_dragon_lord.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "webhook" ADD COLUMN "provider_config" json;--> statement-breakpoint
2 | ALTER TABLE "webhook" DROP COLUMN "secret";
--------------------------------------------------------------------------------
/apps/sim/db/migrations/0015_brief_martin_li.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "workflow_logs" ADD COLUMN "metadata" json;
--------------------------------------------------------------------------------
/apps/sim/db/migrations/0016_cultured_butterfly.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "workflow" ADD COLUMN "collaborators" json DEFAULT '[]' NOT NULL;
--------------------------------------------------------------------------------
/apps/sim/db/migrations/0017_curious_ink.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE "api_key" (
2 | "id" text PRIMARY KEY NOT NULL,
3 | "user_id" text NOT NULL,
4 | "name" text NOT NULL,
5 | "key" text NOT NULL,
6 | "last_used" timestamp,
7 | "created_at" timestamp DEFAULT now() NOT NULL,
8 | "updated_at" timestamp DEFAULT now() NOT NULL,
9 | "expires_at" timestamp,
10 | CONSTRAINT "api_key_key_unique" UNIQUE("key")
11 | );
12 | --> statement-breakpoint
13 | ALTER TABLE "api_key" ADD CONSTRAINT "api_key_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
--------------------------------------------------------------------------------
/apps/sim/db/migrations/0019_even_lorna_dane.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE "marketplace_execution" CASCADE;--> statement-breakpoint
2 | ALTER TABLE "marketplace" RENAME COLUMN "executions" TO "views";
--------------------------------------------------------------------------------
/apps/sim/db/migrations/0020_clear_skreet.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "workflow" ADD COLUMN "is_published" boolean DEFAULT false NOT NULL;
--------------------------------------------------------------------------------
/apps/sim/db/migrations/0021_shocking_korath.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE "user_stats" (
2 | "id" text PRIMARY KEY NOT NULL,
3 | "user_id" text NOT NULL,
4 | "total_manual_executions" integer DEFAULT 0 NOT NULL,
5 | "total_api_calls" integer DEFAULT 0 NOT NULL,
6 | "total_webhook_triggers" integer DEFAULT 0 NOT NULL,
7 | "total_scheduled_executions" integer DEFAULT 0 NOT NULL,
8 | "total_tokens_used" integer DEFAULT 0 NOT NULL,
9 | "total_cost" numeric DEFAULT '0' NOT NULL,
10 | "last_active" timestamp DEFAULT now() NOT NULL,
11 | CONSTRAINT "user_stats_user_id_unique" UNIQUE("user_id")
12 | );
13 | --> statement-breakpoint
14 | ALTER TABLE "workflow" ADD COLUMN "run_count" integer DEFAULT 0 NOT NULL;--> statement-breakpoint
15 | ALTER TABLE "workflow" ADD COLUMN "last_run_at" timestamp;--> statement-breakpoint
16 | ALTER TABLE "user_stats" ADD CONSTRAINT "user_stats_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
--------------------------------------------------------------------------------
/apps/sim/db/migrations/0022_gray_galactus.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "workflow" ADD COLUMN "variables" json DEFAULT '{}';
--------------------------------------------------------------------------------
/apps/sim/db/migrations/0023_nervous_tyger_tiger.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "workflow" DROP COLUMN "api_key";
--------------------------------------------------------------------------------
/apps/sim/db/migrations/0024_next_whizzer.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "workflow" ADD COLUMN "marketplace_data" json DEFAULT 'null'::json;
--------------------------------------------------------------------------------
/apps/sim/db/migrations/0025_curved_jubilee.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "workflow" ALTER COLUMN "marketplace_data" DROP DEFAULT;
--------------------------------------------------------------------------------
/apps/sim/db/migrations/0026_daily_killraven.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "workflow" ADD COLUMN "deployed_state" json;
--------------------------------------------------------------------------------
/apps/sim/db/migrations/0027_careless_gamora.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE "marketplace_star" CASCADE;--> statement-breakpoint
2 | ALTER TABLE "marketplace" DROP COLUMN "stars";
--------------------------------------------------------------------------------
/apps/sim/db/migrations/0028_absent_triton.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE "custom_tools" (
2 | "id" text PRIMARY KEY NOT NULL,
3 | "user_id" text NOT NULL,
4 | "title" text NOT NULL,
5 | "schema" json NOT NULL,
6 | "code" text NOT NULL,
7 | "created_at" timestamp DEFAULT now() NOT NULL,
8 | "updated_at" timestamp DEFAULT now() NOT NULL
9 | );
10 | --> statement-breakpoint
11 | ALTER TABLE "custom_tools" ADD CONSTRAINT "custom_tools_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
--------------------------------------------------------------------------------
/apps/sim/db/migrations/0030_happy_joseph.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE "chat" (
2 | "id" text PRIMARY KEY NOT NULL,
3 | "workflow_id" text NOT NULL,
4 | "user_id" text NOT NULL,
5 | "subdomain" text NOT NULL,
6 | "title" text NOT NULL,
7 | "description" text,
8 | "is_active" boolean DEFAULT true NOT NULL,
9 | "customizations" json DEFAULT '{}',
10 | "auth_type" text DEFAULT 'public' NOT NULL,
11 | "password" text,
12 | "allowed_emails" json DEFAULT '[]',
13 | "output_block_id" text,
14 | "output_path" text,
15 | "created_at" timestamp DEFAULT now() NOT NULL,
16 | "updated_at" timestamp DEFAULT now() NOT NULL
17 | );
18 | --> statement-breakpoint
19 | CREATE TABLE "subscription" (
20 | "id" text PRIMARY KEY NOT NULL,
21 | "plan" text NOT NULL,
22 | "reference_id" text NOT NULL,
23 | "stripe_customer_id" text,
24 | "stripe_subscription_id" text,
25 | "status" text,
26 | "period_start" timestamp,
27 | "period_end" timestamp,
28 | "cancel_at_period_end" boolean,
29 | "seats" integer
30 | );
31 | --> statement-breakpoint
32 | ALTER TABLE "user" ADD COLUMN "stripe_customer_id" text;--> statement-breakpoint
33 | ALTER TABLE "chat" ADD CONSTRAINT "chat_workflow_id_workflow_id_fk" FOREIGN KEY ("workflow_id") REFERENCES "public"."workflow"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
34 | ALTER TABLE "chat" ADD CONSTRAINT "chat_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
35 | CREATE UNIQUE INDEX "subdomain_idx" ON "chat" USING btree ("subdomain");
--------------------------------------------------------------------------------
/apps/sim/db/migrations/0032_rare_nico_minoru.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "chat" ADD COLUMN "output_configs" json DEFAULT '[]';--> statement-breakpoint
2 | ALTER TABLE "chat" DROP COLUMN "output_block_id";--> statement-breakpoint
3 | ALTER TABLE "chat" DROP COLUMN "output_path";
--------------------------------------------------------------------------------
/apps/sim/db/migrations/0033_solid_stellaris.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "settings" ALTER COLUMN "general" SET DEFAULT '{}';--> statement-breakpoint
2 | ALTER TABLE "settings" ADD COLUMN "theme" text DEFAULT 'system' NOT NULL;--> statement-breakpoint
3 | ALTER TABLE "settings" ADD COLUMN "debug_mode" boolean DEFAULT false NOT NULL;--> statement-breakpoint
4 | ALTER TABLE "settings" ADD COLUMN "auto_connect" boolean DEFAULT true NOT NULL;--> statement-breakpoint
5 | ALTER TABLE "settings" ADD COLUMN "auto_fill_env_vars" boolean DEFAULT true NOT NULL;--> statement-breakpoint
6 | ALTER TABLE "settings" ADD COLUMN "telemetry_enabled" boolean DEFAULT true NOT NULL;--> statement-breakpoint
7 | ALTER TABLE "settings" ADD COLUMN "telemetry_notified_user" boolean DEFAULT false NOT NULL;
--------------------------------------------------------------------------------
/apps/sim/db/migrations/0035_slim_energizer.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE "workspace_invitation" (
2 | "id" text PRIMARY KEY NOT NULL,
3 | "workspace_id" text NOT NULL,
4 | "email" text NOT NULL,
5 | "inviter_id" text NOT NULL,
6 | "role" text DEFAULT 'member' NOT NULL,
7 | "status" text DEFAULT 'pending' NOT NULL,
8 | "token" text NOT NULL,
9 | "expires_at" timestamp NOT NULL,
10 | "created_at" timestamp DEFAULT now() NOT NULL,
11 | "updated_at" timestamp DEFAULT now() NOT NULL,
12 | CONSTRAINT "workspace_invitation_token_unique" UNIQUE("token")
13 | );
14 | --> statement-breakpoint
15 | ALTER TABLE "workspace_invitation" ADD CONSTRAINT "workspace_invitation_workspace_id_workspace_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "public"."workspace"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
16 | ALTER TABLE "workspace_invitation" ADD CONSTRAINT "workspace_invitation_inviter_id_user_id_fk" FOREIGN KEY ("inviter_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
--------------------------------------------------------------------------------
/apps/sim/db/migrations/0036_married_skreet.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "organization" ALTER COLUMN "metadata" SET DATA TYPE json;--> statement-breakpoint
2 | ALTER TABLE "subscription" ADD COLUMN "metadata" json;--> statement-breakpoint
3 | ALTER TABLE "user_stats" ADD COLUMN "total_chat_executions" integer DEFAULT 0 NOT NULL;
--------------------------------------------------------------------------------
/apps/sim/db/migrations/0037_outgoing_madame_hydra.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "workflow_schedule" ADD COLUMN "failed_count" integer DEFAULT 0 NOT NULL;--> statement-breakpoint
2 | ALTER TABLE "workflow_schedule" ADD COLUMN "status" text DEFAULT 'active' NOT NULL;--> statement-breakpoint
3 | ALTER TABLE "workflow_schedule" ADD COLUMN "last_failed_at" timestamp;
--------------------------------------------------------------------------------
/apps/sim/db/migrations/0038_shocking_thor.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE "memory" (
2 | "id" text PRIMARY KEY NOT NULL,
3 | "workflow_id" text,
4 | "key" text NOT NULL,
5 | "type" text NOT NULL,
6 | "data" json NOT NULL,
7 | "created_at" timestamp DEFAULT now() NOT NULL,
8 | "updated_at" timestamp DEFAULT now() NOT NULL,
9 | "deleted_at" timestamp
10 | );
11 | --> statement-breakpoint
12 | ALTER TABLE "memory" ADD CONSTRAINT "memory_workflow_id_workflow_id_fk" FOREIGN KEY ("workflow_id") REFERENCES "public"."workflow"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
13 | CREATE INDEX "memory_key_idx" ON "memory" USING btree ("key");--> statement-breakpoint
14 | CREATE INDEX "memory_workflow_idx" ON "memory" USING btree ("workflow_id");--> statement-breakpoint
15 | CREATE UNIQUE INDEX "memory_workflow_key_idx" ON "memory" USING btree ("workflow_id","key");
--------------------------------------------------------------------------------
/apps/sim/db/migrations/0040_silky_monster_badoon.sql:
--------------------------------------------------------------------------------
1 | -- Add enabled field to embedding table
2 | ALTER TABLE "embedding" ADD COLUMN IF NOT EXISTS "enabled" boolean DEFAULT true NOT NULL;
3 |
4 | -- Composite index for knowledge base + enabled chunks (for search optimization)
5 | CREATE INDEX IF NOT EXISTS "emb_kb_enabled_idx" ON "embedding" USING btree ("knowledge_base_id", "enabled");
6 |
7 | -- Composite index for document + enabled chunks (for document chunk listings)
8 | CREATE INDEX IF NOT EXISTS "emb_doc_enabled_idx" ON "embedding" USING btree ("document_id", "enabled");
--------------------------------------------------------------------------------
/apps/sim/db/migrations/relations.ts:
--------------------------------------------------------------------------------
1 | import { relations } from 'drizzle-orm/relations'
2 | import { account, session, user } from './schema'
3 |
4 | export const accountRelations = relations(account, ({ one }) => ({
5 | user: one(user, {
6 | fields: [account.userId],
7 | references: [user.id],
8 | }),
9 | }))
10 |
11 | export const userRelations = relations(user, ({ many }) => ({
12 | accounts: many(account),
13 | sessions: many(session),
14 | }))
15 |
16 | export const sessionRelations = relations(session, ({ one }) => ({
17 | user: one(user, {
18 | fields: [session.userId],
19 | references: [user.id],
20 | }),
21 | }))
22 |
--------------------------------------------------------------------------------
/apps/sim/drizzle.config.ts:
--------------------------------------------------------------------------------
1 | import type { Config } from 'drizzle-kit'
2 | import { env } from './lib/env'
3 |
4 | export default {
5 | schema: './db/schema.ts',
6 | out: './db/migrations',
7 | dialect: 'postgresql',
8 | dbCredentials: {
9 | url: env.DATABASE_URL,
10 | },
11 | } satisfies Config
12 |
--------------------------------------------------------------------------------
/apps/sim/executor/handlers/agent/types.ts:
--------------------------------------------------------------------------------
1 | export interface AgentInputs {
2 | model?: string
3 | responseFormat?: string | object
4 | tools?: ToolInput[]
5 | systemPrompt?: string
6 | userPrompt?: string | object
7 | memories?: any
8 | temperature?: number
9 | maxTokens?: number
10 | apiKey?: string
11 | }
12 |
13 | export interface ToolInput {
14 | type?: string
15 | schema?: any
16 | title?: string
17 | code?: string
18 | params?: Record
19 | timeout?: number
20 | usageControl?: 'auto' | 'force' | 'none'
21 | operation?: string
22 | }
23 |
24 | export interface Message {
25 | role: 'system' | 'user' | 'assistant'
26 | content: string
27 | function_call?: any
28 | tool_calls?: any[]
29 | }
30 |
31 | export interface StreamingConfig {
32 | shouldUseStreaming: boolean
33 | isBlockSelectedForOutput: boolean
34 | hasOutgoingConnections: boolean
35 | }
36 |
--------------------------------------------------------------------------------
/apps/sim/executor/handlers/function/function-handler.ts:
--------------------------------------------------------------------------------
1 | import { createLogger } from '@/lib/logs/console-logger'
2 | import type { BlockOutput } from '@/blocks/types'
3 | import type { SerializedBlock } from '@/serializer/types'
4 | import { executeTool } from '@/tools'
5 | import type { BlockHandler, ExecutionContext } from '../../types'
6 |
7 | const logger = createLogger('FunctionBlockHandler')
8 |
9 | /**
10 | * Handler for Function blocks that execute custom code.
11 | */
12 | export class FunctionBlockHandler implements BlockHandler {
13 | canHandle(block: SerializedBlock): boolean {
14 | return block.metadata?.id === 'function'
15 | }
16 |
17 | async execute(
18 | block: SerializedBlock,
19 | inputs: Record,
20 | context: ExecutionContext
21 | ): Promise {
22 | const codeContent = Array.isArray(inputs.code)
23 | ? inputs.code.map((c: { content: string }) => c.content).join('\n')
24 | : inputs.code
25 |
26 | // Directly use the function_execute tool which calls the API route
27 | logger.info(`Executing function block via API route: ${block.id}`)
28 | const result = await executeTool('function_execute', {
29 | code: codeContent,
30 | timeout: inputs.timeout || 5000,
31 | envVars: context.environmentVariables || {},
32 | _context: { workflowId: context.workflowId },
33 | })
34 |
35 | if (!result.success) {
36 | throw new Error(result.error || 'Function execution failed')
37 | }
38 |
39 | return { response: result.output }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/apps/sim/executor/handlers/index.ts:
--------------------------------------------------------------------------------
1 | import { AgentBlockHandler } from './agent/agent-handler'
2 | import { ApiBlockHandler } from './api/api-handler'
3 | import { ConditionBlockHandler } from './condition/condition-handler'
4 | import { EvaluatorBlockHandler } from './evaluator/evaluator-handler'
5 | import { FunctionBlockHandler } from './function/function-handler'
6 | import { GenericBlockHandler } from './generic/generic-handler'
7 | import { LoopBlockHandler } from './loop/loop-handler'
8 | import { ParallelBlockHandler } from './parallel/parallel-handler'
9 | import { RouterBlockHandler } from './router/router-handler'
10 |
11 | export {
12 | AgentBlockHandler,
13 | ApiBlockHandler,
14 | ConditionBlockHandler,
15 | EvaluatorBlockHandler,
16 | FunctionBlockHandler,
17 | GenericBlockHandler,
18 | LoopBlockHandler,
19 | ParallelBlockHandler,
20 | RouterBlockHandler,
21 | }
22 |
--------------------------------------------------------------------------------
/apps/sim/hooks/use-debounce.ts:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from 'react'
2 |
3 | /**
4 | * A hook that debounces a value by a specified delay
5 | * @param value The value to debounce
6 | * @param delay The delay in milliseconds
7 | * @returns The debounced value
8 | */
9 | export function useDebounce(value: T, delay: number): T {
10 | const [debouncedValue, setDebouncedValue] = useState(value)
11 |
12 | useEffect(() => {
13 | // Set a timeout to update the debounced value after the delay
14 | const timer = setTimeout(() => {
15 | setDebouncedValue(value)
16 | }, delay)
17 |
18 | // Clean up the timeout if the value changes before the delay has passed
19 | return () => {
20 | clearTimeout(timer)
21 | }
22 | }, [value, delay])
23 |
24 | return debouncedValue
25 | }
26 |
--------------------------------------------------------------------------------
/apps/sim/instrumentation.ts:
--------------------------------------------------------------------------------
1 | export async function register() {
2 | if (process.env.NEXT_RUNTIME === 'nodejs') {
3 | await import('./instrumentation-server')
4 | }
5 |
6 | if (typeof window !== 'undefined') {
7 | await import('./instrumentation-client')
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/apps/sim/lib/environment.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Environment utility functions for consistent environment detection across the application
3 | */
4 | import { env } from './env'
5 |
6 | export const getNodeEnv = () => {
7 | try {
8 | return env.NODE_ENV
9 | } catch {
10 | return process.env.NODE_ENV
11 | }
12 | }
13 |
14 | /**
15 | * Is the application running in production mode
16 | */
17 | export const isProd = getNodeEnv() === 'production'
18 |
19 | /**
20 | * Is the application running in development mode
21 | */
22 | export const isDev = getNodeEnv() === 'development'
23 |
24 | /**
25 | * Is the application running in test mode
26 | */
27 | export const isTest = getNodeEnv() === 'test'
28 |
29 | /**
30 | * Is this the hosted version of the application
31 | */
32 | export const isHosted = env.NEXT_PUBLIC_APP_URL === 'https://www.simstudio.ai'
33 |
34 | /**
35 | * Get cost multiplier based on environment
36 | */
37 | export function getCostMultiplier(): number {
38 | return isProd ? Number.parseFloat(env.COST_MULTIPLIER!) || 1 : 1
39 | }
40 |
--------------------------------------------------------------------------------
/apps/sim/lib/file-parsers/types.ts:
--------------------------------------------------------------------------------
1 | export interface FileParseResult {
2 | content: string
3 | metadata?: Record
4 | }
5 |
6 | export interface FileParser {
7 | parseFile(filePath: string): Promise
8 | parseBuffer?(buffer: Buffer): Promise
9 | }
10 |
11 | export type SupportedFileType = 'pdf' | 'csv' | 'docx'
12 |
--------------------------------------------------------------------------------
/apps/sim/lib/generate-chat-title.ts:
--------------------------------------------------------------------------------
1 | import OpenAI from 'openai'
2 | import { env } from './env'
3 |
4 | /**
5 | * Generates a short title for a chat based on the first message
6 | * @param message First user message in the chat
7 | * @returns A short title or null if API key is not available
8 | */
9 | export async function generateChatTitle(message: string): Promise {
10 | const apiKey = env.OPENAI_API_KEY
11 |
12 | if (!apiKey) {
13 | return null
14 | }
15 |
16 | try {
17 | const openai = new OpenAI({ apiKey })
18 |
19 | const response = await openai.chat.completions.create({
20 | model: 'gpt-3.5-turbo',
21 | messages: [
22 | {
23 | role: 'system',
24 | content:
25 | 'Generate a very short title (3-5 words max) for a chat that starts with this message. The title should be concise and descriptive.',
26 | },
27 | {
28 | role: 'user',
29 | content: message,
30 | },
31 | ],
32 | max_tokens: 20,
33 | temperature: 0.7,
34 | })
35 |
36 | const title = response.choices[0]?.message?.content?.trim() || null
37 | return title
38 | } catch (error) {
39 | console.error('Error generating chat title:', error)
40 | return null
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/apps/sim/lib/uploads/setup.server.ts:
--------------------------------------------------------------------------------
1 | import { createLogger } from '@/lib/logs/console-logger'
2 | import { env } from '../env'
3 | import { ensureUploadsDirectory, USE_S3_STORAGE } from './setup'
4 |
5 | const logger = createLogger('UploadsSetup')
6 |
7 | // Immediately invoke on server startup
8 | if (typeof process !== 'undefined') {
9 | // Log storage mode
10 | logger.info(`Storage mode: ${USE_S3_STORAGE ? 'S3' : 'Local'}`)
11 |
12 | if (USE_S3_STORAGE) {
13 | // Verify AWS credentials
14 | if (!env.AWS_ACCESS_KEY_ID || !env.AWS_SECRET_ACCESS_KEY) {
15 | logger.warn('AWS credentials are not set in environment variables.')
16 | logger.warn('Set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY for S3 storage.')
17 | } else {
18 | logger.info('AWS credentials found in environment variables')
19 | }
20 | } else {
21 | // Only initialize local uploads directory in development mode
22 | ensureUploadsDirectory().then((success) => {
23 | if (success) {
24 | logger.info('Local uploads directory initialized')
25 | } else {
26 | logger.error('Failed to initialize local uploads directory')
27 | }
28 | })
29 | }
30 | }
31 |
32 | export default ensureUploadsDirectory
33 |
--------------------------------------------------------------------------------
/apps/sim/lib/uploads/setup.ts:
--------------------------------------------------------------------------------
1 | import { existsSync } from 'fs'
2 | import { mkdir } from 'fs/promises'
3 | import path, { join } from 'path'
4 | import { createLogger } from '@/lib/logs/console-logger'
5 | import { env } from '../env'
6 |
7 | const logger = createLogger('UploadsSetup')
8 |
9 | const PROJECT_ROOT = path.resolve(process.cwd())
10 |
11 | export const UPLOAD_DIR = join(PROJECT_ROOT, 'uploads')
12 |
13 | export const USE_S3_STORAGE = process.env.NODE_ENV === 'production'
14 |
15 | export const S3_CONFIG = {
16 | bucket: env.S3_BUCKET_NAME || '',
17 | region: env.AWS_REGION || '',
18 | }
19 |
20 | export async function ensureUploadsDirectory() {
21 | if (USE_S3_STORAGE) {
22 | logger.info('Using S3 storage, skipping local uploads directory creation')
23 | return true
24 | }
25 |
26 | try {
27 | if (!existsSync(UPLOAD_DIR)) {
28 | await mkdir(UPLOAD_DIR, { recursive: true })
29 | } else {
30 | logger.info(`Uploads directory already exists at ${UPLOAD_DIR}`)
31 | }
32 | return true
33 | } catch (error) {
34 | logger.error('Failed to create uploads directory:', error)
35 | return false
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/apps/sim/lib/urls/utils.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Returns the base URL of the application, respecting environment variables for deployment environments
3 | * @returns The base URL string (e.g., 'http://localhost:3000' or 'https://example.com')
4 | */
5 | export function getBaseUrl(): string {
6 | if (typeof window !== 'undefined') {
7 | return window.location.origin
8 | }
9 |
10 | const baseUrl = process.env.NEXT_PUBLIC_APP_URL
11 | if (baseUrl) {
12 | if (baseUrl.startsWith('http://') || baseUrl.startsWith('https://')) {
13 | return baseUrl
14 | }
15 |
16 | const isProd = process.env.NODE_ENV === 'production'
17 | const protocol = isProd ? 'https://' : 'http://'
18 | return `${protocol}${baseUrl}`
19 | }
20 |
21 | return 'http://localhost:3000'
22 | }
23 |
24 | /**
25 | * Returns just the domain and port part of the application URL
26 | * @returns The domain with port if applicable (e.g., 'localhost:3000' or 'simstudio.ai')
27 | */
28 | export function getBaseDomain(): string {
29 | try {
30 | const url = new URL(getBaseUrl())
31 | return url.host // host includes port if specified
32 | } catch (_e) {
33 | const fallbackUrl = process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000'
34 | try {
35 | return new URL(fallbackUrl).host
36 | } catch {
37 | const isProd = process.env.NODE_ENV === 'production'
38 | return isProd ? 'simstudio.ai' : 'localhost:3000'
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/apps/sim/lib/waitlist/token.ts:
--------------------------------------------------------------------------------
1 | import { jwtVerify, SignJWT } from 'jose'
2 | import { nanoid } from 'nanoid'
3 | import { env } from '../env'
4 |
5 | interface TokenPayload {
6 | email: string
7 | type: 'waitlist-approval' | 'password-reset'
8 | expiresIn: string
9 | }
10 |
11 | interface DecodedToken {
12 | email: string
13 | type: string
14 | jti: string
15 | iat: number
16 | exp: number
17 | }
18 |
19 | // Get JWT secret from environment variables
20 | const getJwtSecret = () => {
21 | const secret = env.JWT_SECRET
22 | if (!secret) {
23 | throw new Error('JWT_SECRET environment variable is not set')
24 | }
25 | return new TextEncoder().encode(secret)
26 | }
27 |
28 | /**
29 | * Create a JWT token
30 | */
31 | export async function createToken({ email, type, expiresIn }: TokenPayload): Promise {
32 | const jwt = await new SignJWT({ email, type })
33 | .setProtectedHeader({ alg: 'HS256' })
34 | .setIssuedAt()
35 | .setExpirationTime(expiresIn)
36 | .setJti(nanoid())
37 | .sign(getJwtSecret())
38 |
39 | return jwt
40 | }
41 |
42 | /**
43 | * Verify a JWT token
44 | */
45 | export async function verifyToken(token: string): Promise {
46 | try {
47 | const { payload } = await jwtVerify(token, getJwtSecret())
48 |
49 | return payload as unknown as DecodedToken
50 | } catch (error) {
51 | console.error('Error verifying token:', error)
52 | return null
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/apps/sim/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('postcss-load-config').Config} */
2 | const config = {
3 | plugins: {
4 | tailwindcss: {},
5 | },
6 | }
7 |
8 | export default config
9 |
--------------------------------------------------------------------------------
/apps/sim/providers/cerebras/types.ts:
--------------------------------------------------------------------------------
1 | interface CerebrasMessage {
2 | role: string
3 | content: string | null
4 | tool_calls?: Array<{
5 | id: string
6 | type: 'function'
7 | function: {
8 | name: string
9 | arguments: string
10 | }
11 | }>
12 | tool_call_id?: string
13 | }
14 |
15 | interface CerebrasChoice {
16 | message: CerebrasMessage
17 | index: number
18 | finish_reason: string
19 | }
20 |
21 | interface CerebrasUsage {
22 | prompt_tokens: number
23 | completion_tokens: number
24 | total_tokens: number
25 | }
26 |
27 | interface CerebrasResponse {
28 | id: string
29 | object: string
30 | created: number
31 | model: string
32 | choices: CerebrasChoice[]
33 | usage: CerebrasUsage
34 | }
35 |
--------------------------------------------------------------------------------
/apps/sim/providers/ollama/types.ts:
--------------------------------------------------------------------------------
1 | interface Model {
2 | name: string
3 | model: string
4 | modified_at: string
5 | size: number
6 | digest: string
7 | details: object
8 | }
9 |
10 | export interface ModelsObject {
11 | models: Model[]
12 | }
13 |
--------------------------------------------------------------------------------
/apps/sim/public/favicon/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/sim/public/favicon/android-chrome-192x192.png
--------------------------------------------------------------------------------
/apps/sim/public/favicon/android-chrome-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/sim/public/favicon/android-chrome-512x512.png
--------------------------------------------------------------------------------
/apps/sim/public/favicon/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/sim/public/favicon/apple-touch-icon.png
--------------------------------------------------------------------------------
/apps/sim/public/favicon/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/sim/public/favicon/favicon-16x16.png
--------------------------------------------------------------------------------
/apps/sim/public/favicon/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/sim/public/favicon/favicon-32x32.png
--------------------------------------------------------------------------------
/apps/sim/public/favicon/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/sim/public/favicon/favicon.ico
--------------------------------------------------------------------------------
/apps/sim/public/favicon/site.webmanifest:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Sim Studio",
3 | "short_name": "Sim Studio",
4 | "icons": [
5 | {
6 | "src": "/favicon/android-chrome-192x192.png",
7 | "sizes": "192x192",
8 | "type": "image/png"
9 | },
10 | {
11 | "src": "/favicon/android-chrome-512x512.png",
12 | "sizes": "512x512",
13 | "type": "image/png"
14 | }
15 | ],
16 | "theme_color": "#ffffff",
17 | "background_color": "#ffffff",
18 | "display": "standalone"
19 | }
20 |
--------------------------------------------------------------------------------
/apps/sim/public/icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/apps/sim/public/sim.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/sim/public/sim.png
--------------------------------------------------------------------------------
/apps/sim/public/sim.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/apps/sim/public/social/facebook.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/sim/public/social/facebook.png
--------------------------------------------------------------------------------
/apps/sim/public/social/instagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/sim/public/social/instagram.png
--------------------------------------------------------------------------------
/apps/sim/public/social/twitter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/sim/public/social/twitter.png
--------------------------------------------------------------------------------
/apps/sim/public/static/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/sim/public/static/demo.gif
--------------------------------------------------------------------------------
/apps/sim/public/static/discord-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/sim/public/static/discord-icon.png
--------------------------------------------------------------------------------
/apps/sim/public/static/github-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/sim/public/static/github-icon.png
--------------------------------------------------------------------------------
/apps/sim/public/static/preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/sim/public/static/preview.png
--------------------------------------------------------------------------------
/apps/sim/public/static/sim.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/sim/public/static/sim.png
--------------------------------------------------------------------------------
/apps/sim/public/static/x-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/sim/public/static/x-icon.png
--------------------------------------------------------------------------------
/apps/sim/public/twitter/daniel.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/sim/public/twitter/daniel.jpg
--------------------------------------------------------------------------------
/apps/sim/public/twitter/github-projects.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/sim/public/twitter/github-projects.jpg
--------------------------------------------------------------------------------
/apps/sim/public/twitter/hasan.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/sim/public/twitter/hasan.jpg
--------------------------------------------------------------------------------
/apps/sim/public/twitter/lazukars.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/sim/public/twitter/lazukars.png
--------------------------------------------------------------------------------
/apps/sim/public/twitter/nizzy.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/sim/public/twitter/nizzy.jpg
--------------------------------------------------------------------------------
/apps/sim/public/twitter/samarth.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/sim/public/twitter/samarth.jpg
--------------------------------------------------------------------------------
/apps/sim/public/twitter/syamrajk.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/sim/public/twitter/syamrajk.jpg
--------------------------------------------------------------------------------
/apps/sim/public/twitter/xyflow.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simstudioai/sim/dcf6e10b5bcdb426dd36fb8143281a4c2aa6596f/apps/sim/public/twitter/xyflow.jpg
--------------------------------------------------------------------------------
/apps/sim/scripts/ollama_docker.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | # Check that at least one argument is provided. If not, display the usage help.
5 | if [ "$#" -eq 0 ]; then
6 | echo "Usage: $(basename "$0") [args...]"
7 | echo "Example: $(basename "$0") ps # This will run 'ollama ps' inside the container"
8 | exit 1
9 | fi
10 |
11 | # Start a detached container from the ollama/ollama image,
12 | # mounting the host's ~/.ollama directory directly into the container.
13 | # Here we mount it to /root/.ollama, assuming that's where the image expects it.
14 | CONTAINER_ID=$(docker run -d -v ~/.ollama:/root/.ollama -p 11434:11434 ollama/ollama
15 | )
16 |
17 | # Define a cleanup function to stop the container regardless of how the script exits.
18 | cleanup() {
19 | docker stop "$CONTAINER_ID" >/dev/null
20 | }
21 | trap cleanup EXIT
22 |
23 | # Execute the command provided by the user within the running container.
24 | # The command runs as: "ollama "
25 | docker exec -it "$CONTAINER_ID" ollama "$@"
26 |
--------------------------------------------------------------------------------
/apps/sim/stores/constants.ts:
--------------------------------------------------------------------------------
1 | export const STORAGE_KEYS = {
2 | REGISTRY: 'workflow-registry',
3 | WORKFLOW: (id: string) => `workflow-${id}`,
4 | SUBBLOCK: (id: string) => `subblock-values-${id}`,
5 | }
6 |
7 | export const API_ENDPOINTS = {
8 | SYNC: '/api/workflows/sync',
9 | ENVIRONMENT: '/api/environment',
10 | SCHEDULE: '/api/schedules',
11 | SETTINGS: '/api/settings',
12 | WORKFLOWS: '/api/workflows',
13 | }
14 |
15 | export const SYNC_INTERVALS = {
16 | DEFAULT: 30000, // 30 seconds
17 | }
18 |
--------------------------------------------------------------------------------
/apps/sim/stores/copilot/types.ts:
--------------------------------------------------------------------------------
1 | export interface CopilotMessage {
2 | id: string
3 | role: 'user' | 'assistant' | 'system'
4 | content: string
5 | timestamp: number
6 | }
7 |
8 | export interface CopilotState {
9 | messages: CopilotMessage[]
10 | isProcessing: boolean
11 | error: string | null
12 | }
13 |
14 | export interface CopilotActions {
15 | sendMessage: (content: string) => Promise
16 | clearCopilot: () => void
17 | setError: (error: string | null) => void
18 | }
19 |
20 | export type CopilotStore = CopilotState & CopilotActions
21 |
--------------------------------------------------------------------------------
/apps/sim/stores/copilot/utils.ts:
--------------------------------------------------------------------------------
1 | // Helper function to get the next block number for a given type
2 | export const getNextBlockNumber = (blocks: Record, type: string) => {
3 | const typeBlocks = Object.values(blocks)
4 | .filter((block: any) => block.type.toLowerCase() === type.toLowerCase())
5 | .map((block: any) => {
6 | const match = block.name.match(new RegExp(`${type}\\s*(\\d+)`, 'i'))
7 | return match ? Number.parseInt(match[1]) : 0
8 | })
9 |
10 | const maxNumber = Math.max(0, ...typeBlocks)
11 | return maxNumber + 1
12 | }
13 |
14 | // Calculate block position based on existing blocks and current action index
15 | export const calculateBlockPosition = (
16 | existingBlocks: Record,
17 | index: number,
18 | startX = 100,
19 | startY = 100,
20 | xSpacing = 500,
21 | ySpacing = 150
22 | ) => {
23 | const blocksCount = Object.keys(existingBlocks).length
24 |
25 | // Calculate position based on existing blocks and current action index
26 | const row = Math.floor((blocksCount + index) / 5) // 5 blocks per row
27 | const col = (blocksCount + index) % 5
28 |
29 | return {
30 | x: startX + col * xSpacing,
31 | y: startY + row * ySpacing,
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/apps/sim/stores/custom-tools/types.ts:
--------------------------------------------------------------------------------
1 | export interface CustomToolSchema {
2 | type: string
3 | function: {
4 | name: string
5 | description?: string
6 | parameters: {
7 | type: string
8 | properties: Record
9 | required?: string[]
10 | }
11 | }
12 | }
13 |
14 | export interface CustomToolDefinition {
15 | id: string
16 | title: string
17 | schema: CustomToolSchema
18 | code: string
19 | createdAt: string
20 | updatedAt?: string
21 | }
22 |
23 | export interface CustomToolsStore {
24 | tools: Record
25 | isLoading: boolean
26 | error: string | null
27 |
28 | // CRUD operations
29 | addTool: (tool: Omit) => string
30 | updateTool: (
31 | id: string,
32 | updates: Partial>
33 | ) => boolean
34 | removeTool: (id: string) => void
35 | getTool: (id: string) => CustomToolDefinition | undefined
36 | getAllTools: () => CustomToolDefinition[]
37 |
38 | // Server sync operations
39 | loadCustomTools: () => Promise
40 | sync: () => Promise
41 | }
42 |
--------------------------------------------------------------------------------
/apps/sim/stores/execution/store.ts:
--------------------------------------------------------------------------------
1 | import { create } from 'zustand'
2 | import { type ExecutionActions, type ExecutionState, initialState } from './types'
3 |
4 | export const useExecutionStore = create()((set) => ({
5 | ...initialState,
6 |
7 | setActiveBlocks: (blockIds) => set({ activeBlockIds: new Set(blockIds) }),
8 | setIsExecuting: (isExecuting) => set({ isExecuting }),
9 | setIsDebugging: (isDebugging) => set({ isDebugging }),
10 | setPendingBlocks: (pendingBlocks) => set({ pendingBlocks }),
11 | setExecutor: (executor) => set({ executor }),
12 | setDebugContext: (debugContext) => set({ debugContext }),
13 | reset: () => set(initialState),
14 | }))
15 |
--------------------------------------------------------------------------------
/apps/sim/stores/execution/types.ts:
--------------------------------------------------------------------------------
1 | import type { Executor } from '@/executor'
2 | import type { ExecutionContext } from '@/executor/types'
3 |
4 | export interface ExecutionState {
5 | activeBlockIds: Set
6 | isExecuting: boolean
7 | isDebugging: boolean
8 | pendingBlocks: string[]
9 | executor: Executor | null
10 | debugContext: ExecutionContext | null
11 | }
12 |
13 | export interface ExecutionActions {
14 | setActiveBlocks: (blockIds: Set) => void
15 | setIsExecuting: (isExecuting: boolean) => void
16 | setIsDebugging: (isDebugging: boolean) => void
17 | setPendingBlocks: (blockIds: string[]) => void
18 | setExecutor: (executor: Executor | null) => void
19 | setDebugContext: (context: ExecutionContext | null) => void
20 | reset: () => void
21 | }
22 |
23 | export const initialState: ExecutionState = {
24 | activeBlockIds: new Set(),
25 | isExecuting: false,
26 | isDebugging: false,
27 | pendingBlocks: [],
28 | executor: null,
29 | debugContext: null,
30 | }
31 |
--------------------------------------------------------------------------------
/apps/sim/stores/notifications/types.ts:
--------------------------------------------------------------------------------
1 | export type NotificationType = 'error' | 'console' | 'api' | 'marketplace' | 'info'
2 |
3 | export interface Notification {
4 | id: string
5 | type: NotificationType
6 | message: string
7 | timestamp: number
8 | isVisible: boolean
9 | workflowId: string | null
10 | read: boolean
11 | isFading?: boolean
12 | options?: NotificationOptions
13 | }
14 |
15 | export interface NotificationSection {
16 | label: string
17 | content: string
18 | }
19 |
20 | export interface NotificationAction {
21 | label: string
22 | onClick: () => void
23 | }
24 |
25 | export interface NotificationOptions {
26 | copyableContent?: string
27 | isPersistent?: boolean
28 | sections?: NotificationSection[]
29 | needsRedeployment?: boolean
30 | actions?: NotificationAction[]
31 | }
32 |
33 | export interface NotificationStore {
34 | notifications: Notification[]
35 | addNotification: (
36 | type: NotificationType,
37 | message: string,
38 | workflowId: string | null,
39 | options?: NotificationOptions
40 | ) => string
41 | hideNotification: (id: string) => void
42 | showNotification: (id: string) => void
43 | setNotificationFading: (id: string) => void
44 | markAsRead: (id: string) => void
45 | markAllAsRead: (workflowId: string) => void
46 | removeNotification: (id: string) => void
47 | clearNotifications: () => void
48 | getWorkflowNotifications: (workflowId: string) => Notification[]
49 | getVisibleNotificationCount: (workflowId: string | null) => number
50 | }
51 |
--------------------------------------------------------------------------------
/apps/sim/stores/ollama/store.ts:
--------------------------------------------------------------------------------
1 | import { create } from 'zustand'
2 | import { createLogger } from '@/lib/logs/console-logger'
3 | import { updateOllamaProviderModels } from '@/providers/utils'
4 | import type { OllamaStore } from './types'
5 |
6 | const logger = createLogger('OllamaStore')
7 |
8 | export const useOllamaStore = create((set) => ({
9 | models: [],
10 | setModels: (models) => {
11 | logger.info('Updating Ollama models', { models })
12 | set({ models })
13 | // Update the providers when models change
14 | updateOllamaProviderModels(models)
15 | },
16 | }))
17 |
--------------------------------------------------------------------------------
/apps/sim/stores/ollama/types.ts:
--------------------------------------------------------------------------------
1 | export interface OllamaStore {
2 | models: string[]
3 | setModels: (models: string[]) => void
4 | }
5 |
--------------------------------------------------------------------------------
/apps/sim/stores/panel/chat/types.ts:
--------------------------------------------------------------------------------
1 | export interface ChatMessage {
2 | id: string
3 | content: string | any
4 | workflowId: string
5 | type: 'user' | 'workflow'
6 | timestamp: string
7 | blockId?: string
8 | isStreaming?: boolean
9 | }
10 |
11 | export interface OutputConfig {
12 | blockId: string
13 | path: string
14 | }
15 |
16 | export interface ChatStore {
17 | messages: ChatMessage[]
18 | selectedWorkflowOutputs: Record
19 | addMessage: (message: Omit) => void
20 | clearChat: (workflowId: string | null) => void
21 | getWorkflowMessages: (workflowId: string) => ChatMessage[]
22 | setSelectedWorkflowOutput: (workflowId: string, outputIds: string[]) => void
23 | getSelectedWorkflowOutput: (workflowId: string) => string[]
24 | appendMessageContent: (messageId: string, content: string) => void
25 | finalizeMessageStream: (messageId: string) => void
26 | }
27 |
--------------------------------------------------------------------------------
/apps/sim/stores/panel/console/types.ts:
--------------------------------------------------------------------------------
1 | export interface ConsoleEntry {
2 | id: string
3 | output: any
4 | error?: string
5 | warning?: string
6 | durationMs: number
7 | startedAt: string
8 | endedAt: string
9 | workflowId: string | null
10 | timestamp: string
11 | blockName?: string
12 | blockType?: string
13 | blockId?: string
14 | }
15 |
16 | export interface ConsoleStore {
17 | entries: ConsoleEntry[]
18 | isOpen: boolean
19 | addConsole: (entry: Omit) => ConsoleEntry
20 | clearConsole: (workflowId: string | null) => void
21 | getWorkflowEntries: (workflowId: string) => ConsoleEntry[]
22 | toggleConsole: () => void
23 | updateConsole: (
24 | entryId: string,
25 | updatedData: Partial>
26 | ) => void
27 | }
28 |
--------------------------------------------------------------------------------
/apps/sim/stores/panel/store.ts:
--------------------------------------------------------------------------------
1 | import { create } from 'zustand'
2 | import { devtools, persist } from 'zustand/middleware'
3 | import type { PanelStore, PanelTab } from './types'
4 |
5 | export const usePanelStore = create()(
6 | devtools(
7 | persist(
8 | (set) => ({
9 | isOpen: false,
10 | activeTab: 'console',
11 |
12 | togglePanel: () => {
13 | set((state) => ({ isOpen: !state.isOpen }))
14 | },
15 |
16 | setActiveTab: (tab: PanelTab) => {
17 | set({ activeTab: tab })
18 | },
19 | }),
20 | {
21 | name: 'panel-store',
22 | }
23 | )
24 | )
25 | )
26 |
--------------------------------------------------------------------------------
/apps/sim/stores/panel/types.ts:
--------------------------------------------------------------------------------
1 | export type PanelTab = 'console' | 'variables' | 'chat'
2 |
3 | export interface PanelStore {
4 | isOpen: boolean
5 | activeTab: PanelTab
6 | togglePanel: () => void
7 | setActiveTab: (tab: PanelTab) => void
8 | }
9 |
--------------------------------------------------------------------------------
/apps/sim/stores/settings/environment/types.ts:
--------------------------------------------------------------------------------
1 | export interface EnvironmentVariable {
2 | key: string
3 | value: string
4 | }
5 |
6 | export interface EnvironmentState {
7 | variables: Record
8 | isLoading: boolean
9 | error: string | null
10 | }
11 |
12 | export interface EnvironmentStore extends EnvironmentState {
13 | // Legacy method
14 | setVariables: (variables: Record) => void
15 |
16 | // New methods for direct DB interaction
17 | loadEnvironmentVariables: () => Promise
18 | saveEnvironmentVariables: (variables: Record) => Promise
19 |
20 | // Utility methods
21 | getVariable: (key: string) => string | undefined
22 | getAllVariables: () => Record
23 | }
24 |
--------------------------------------------------------------------------------
/apps/sim/stores/settings/general/types.ts:
--------------------------------------------------------------------------------
1 | export interface General {
2 | isAutoConnectEnabled: boolean
3 | isDebugModeEnabled: boolean
4 | isAutoFillEnvVarsEnabled: boolean
5 | theme: 'system' | 'light' | 'dark'
6 | telemetryEnabled: boolean
7 | telemetryNotifiedUser: boolean
8 | isLoading: boolean
9 | error: string | null
10 | }
11 |
12 | export interface GeneralActions {
13 | toggleAutoConnect: () => void
14 | toggleDebugMode: () => void
15 | toggleAutoFillEnvVars: () => void
16 | setTheme: (theme: 'system' | 'light' | 'dark') => void
17 | setTelemetryEnabled: (enabled: boolean) => void
18 | setTelemetryNotifiedUser: (notified: boolean) => void
19 | loadSettings: (force?: boolean) => Promise
20 | updateSetting: (key: K, value: UserSettings[K]) => Promise
21 | }
22 |
23 | export type GeneralStore = General & GeneralActions
24 |
25 | export type UserSettings = {
26 | theme: 'system' | 'light' | 'dark'
27 | debugMode: boolean
28 | autoConnect: boolean
29 | autoFillEnvVars: boolean
30 | telemetryEnabled: boolean
31 | telemetryNotifiedUser: boolean
32 | }
33 |
--------------------------------------------------------------------------------
/apps/sim/stores/workflows/subblock/types.ts:
--------------------------------------------------------------------------------
1 | export interface SubBlockState {
2 | workflowValues: Record>> // Store values per workflow ID
3 | toolParams: Record>
4 | clearedParams: Record>
5 | }
6 |
7 | export interface SubBlockStore extends SubBlockState {
8 | setValue: (blockId: string, subBlockId: string, value: any) => void
9 | getValue: (blockId: string, subBlockId: string) => any
10 | clear: () => void
11 | initializeFromWorkflow: (workflowId: string, blocks: Record) => void
12 | // Add debounced sync function
13 | syncWithDB: () => void
14 |
15 | // Tool params related functions
16 | setToolParam: (toolId: string, paramId: string, value: string) => void
17 | markParamAsCleared: (instanceId: string, paramId: string) => void
18 | unmarkParamAsCleared: (instanceId: string, paramId: string) => void
19 | isParamCleared: (instanceId: string, paramId: string) => boolean
20 | getToolParam: (toolId: string, paramId: string) => string | undefined
21 | getToolParams: (toolId: string) => Record
22 | isEnvVarReference: (value: string) => boolean
23 | resolveToolParamValue: (
24 | toolId: string,
25 | paramId: string,
26 | instanceId?: string
27 | ) => string | undefined
28 | clearToolParams: () => void
29 | }
30 |
--------------------------------------------------------------------------------
/apps/sim/tools/airtable/index.ts:
--------------------------------------------------------------------------------
1 | import { airtableCreateRecordsTool } from './create_records'
2 | import { airtableGetRecordTool } from './get_record'
3 | import { airtableListRecordsTool } from './list_records'
4 | import { airtableUpdateMultipleRecordsTool } from './update_multiple_records'
5 | import { airtableUpdateRecordTool } from './update_record'
6 |
7 | export {
8 | airtableCreateRecordsTool,
9 | airtableGetRecordTool,
10 | airtableListRecordsTool,
11 | airtableUpdateMultipleRecordsTool,
12 | airtableUpdateRecordTool,
13 | }
14 |
--------------------------------------------------------------------------------
/apps/sim/tools/autoblocks/index.ts:
--------------------------------------------------------------------------------
1 | import { promptManagerTool } from './prompt_manager'
2 |
3 | export const autoblocksPromptManagerTool = promptManagerTool
4 |
--------------------------------------------------------------------------------
/apps/sim/tools/autoblocks/types.ts:
--------------------------------------------------------------------------------
1 | import type { ToolResponse } from '../types'
2 |
3 | export interface PromptManagerParams {
4 | promptId: string
5 | version: string
6 | specificVersion?: string
7 | templateParams?: Record
8 | apiKey: string
9 | enableABTesting?: boolean
10 | abTestConfig?: {
11 | versions: Array<{
12 | version: string
13 | weight: number
14 | }>
15 | }
16 | environment: string
17 | }
18 |
19 | export interface PromptManagerResponse extends ToolResponse {
20 | output: {
21 | promptId: string
22 | version: string
23 | renderedPrompt: string
24 | templates: Record
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/apps/sim/tools/browser_use/index.ts:
--------------------------------------------------------------------------------
1 | import { runTaskTool } from './run_task'
2 |
3 | export const browserUseRunTaskTool = runTaskTool
4 |
--------------------------------------------------------------------------------
/apps/sim/tools/browser_use/types.ts:
--------------------------------------------------------------------------------
1 | import type { ToolResponse } from '../types'
2 |
3 | export interface BrowserUseRunTaskParams {
4 | task: string
5 | apiKey: string
6 | variables?: Record
7 | model?: string
8 | save_browser_data?: boolean
9 | }
10 |
11 | export interface BrowserUseTaskStep {
12 | id: string
13 | step: number
14 | evaluation_previous_goal: string
15 | next_goal: string
16 | url?: string
17 | extracted_data?: Record
18 | }
19 |
20 | export interface BrowserUseTaskOutput {
21 | id: string
22 | success: boolean
23 | output: any
24 | steps: BrowserUseTaskStep[]
25 | }
26 |
27 | export interface BrowserUseRunTaskResponse extends ToolResponse {
28 | output: BrowserUseTaskOutput
29 | }
30 |
--------------------------------------------------------------------------------
/apps/sim/tools/clay/index.ts:
--------------------------------------------------------------------------------
1 | import { clayPopulateTool } from './populate'
2 |
3 | export { clayPopulateTool }
4 |
--------------------------------------------------------------------------------
/apps/sim/tools/clay/types.ts:
--------------------------------------------------------------------------------
1 | import type { ToolResponse } from '../types'
2 |
3 | export interface ClayPopulateParams {
4 | webhookURL: string
5 | data: JSON
6 | authToken?: string
7 | }
8 |
9 | export interface ClayPopulateResponse extends ToolResponse {
10 | output: {
11 | data: any
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/apps/sim/tools/confluence/index.ts:
--------------------------------------------------------------------------------
1 | import { confluenceRetrieveTool } from './retrieve'
2 | import { confluenceUpdateTool } from './update'
3 |
4 | export { confluenceRetrieveTool }
5 | export { confluenceUpdateTool }
6 |
--------------------------------------------------------------------------------
/apps/sim/tools/confluence/types.ts:
--------------------------------------------------------------------------------
1 | import type { ToolResponse } from '../types'
2 |
3 | export interface ConfluenceRetrieveParams {
4 | accessToken: string
5 | pageId: string
6 | domain: string
7 | cloudId?: string
8 | }
9 |
10 | export interface ConfluenceRetrieveResponse extends ToolResponse {
11 | output: {
12 | ts: string
13 | pageId: string
14 | content: string
15 | title: string
16 | }
17 | }
18 |
19 | export interface ConfluencePage {
20 | id: string
21 | title: string
22 | spaceKey?: string
23 | url?: string
24 | lastModified?: string
25 | }
26 |
27 | export interface ConfluenceUpdateParams {
28 | accessToken: string
29 | domain: string
30 | pageId: string
31 | title?: string
32 | content?: string
33 | version?: number
34 | cloudId?: string
35 | }
36 |
37 | export interface ConfluenceUpdateResponse extends ToolResponse {
38 | output: {
39 | ts: string
40 | pageId: string
41 | title: string
42 | success: boolean
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/apps/sim/tools/confluence/utils.ts:
--------------------------------------------------------------------------------
1 | export async function getConfluenceCloudId(domain: string, accessToken: string): Promise {
2 | const response = await fetch('https://api.atlassian.com/oauth/token/accessible-resources', {
3 | method: 'GET',
4 | headers: {
5 | Authorization: `Bearer ${accessToken}`,
6 | Accept: 'application/json',
7 | },
8 | })
9 |
10 | const resources = await response.json()
11 |
12 | // If we have resources, find the matching one
13 | if (Array.isArray(resources) && resources.length > 0) {
14 | const normalizedInput = `https://${domain}`.toLowerCase()
15 | const matchedResource = resources.find((r) => r.url.toLowerCase() === normalizedInput)
16 |
17 | if (matchedResource) {
18 | return matchedResource.id
19 | }
20 | }
21 |
22 | // If we couldn't find a match, return the first resource's ID
23 | // This is a fallback in case the URL matching fails
24 | if (Array.isArray(resources) && resources.length > 0) {
25 | return resources[0].id
26 | }
27 |
28 | throw new Error('No Confluence resources found')
29 | }
30 |
--------------------------------------------------------------------------------
/apps/sim/tools/discord/index.ts:
--------------------------------------------------------------------------------
1 | import { discordGetMessagesTool } from './get_messages'
2 | import { discordGetServerTool } from './get_server'
3 | import { discordGetUserTool } from './get_user'
4 | import { discordSendMessageTool } from './send_message'
5 |
6 | export { discordSendMessageTool, discordGetMessagesTool, discordGetServerTool, discordGetUserTool }
7 |
--------------------------------------------------------------------------------
/apps/sim/tools/elevenlabs/index.ts:
--------------------------------------------------------------------------------
1 | import { elevenLabsTtsTool } from './tts'
2 |
3 | export { elevenLabsTtsTool }
4 |
--------------------------------------------------------------------------------
/apps/sim/tools/elevenlabs/types.ts:
--------------------------------------------------------------------------------
1 | import type { ToolResponse } from '../types'
2 |
3 | export interface ElevenLabsTtsParams {
4 | apiKey: string
5 | text: string
6 | voiceId: string
7 | modelId?: string
8 | }
9 |
10 | export interface ElevenLabsTtsResponse extends ToolResponse {
11 | output: {
12 | audioUrl: string
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/apps/sim/tools/exa/index.ts:
--------------------------------------------------------------------------------
1 | import { answerTool } from './answer'
2 | import { findSimilarLinksTool } from './find_similar_links'
3 | import { getContentsTool } from './get_contents'
4 | import { searchTool } from './search'
5 |
6 | export const exaAnswerTool = answerTool
7 | export const exaFindSimilarLinksTool = findSimilarLinksTool
8 | export const exaGetContentsTool = getContentsTool
9 | export const exaSearchTool = searchTool
10 |
--------------------------------------------------------------------------------
/apps/sim/tools/file/index.ts:
--------------------------------------------------------------------------------
1 | import { fileParserTool } from './parser'
2 |
3 | export const fileParseTool = fileParserTool
4 |
--------------------------------------------------------------------------------
/apps/sim/tools/file/types.ts:
--------------------------------------------------------------------------------
1 | import type { ToolResponse } from '../types'
2 |
3 | export interface FileParserInput {
4 | filePath: string | string[]
5 | fileType?: string
6 | }
7 |
8 | export interface FileParseResult {
9 | content: string
10 | fileType: string
11 | size: number
12 | name: string
13 | binary: boolean
14 | metadata?: Record
15 | }
16 |
17 | export interface FileParserOutputData {
18 | files: FileParseResult[]
19 | combinedContent: string
20 | [key: string]: any
21 | }
22 |
23 | export interface FileParserOutput extends ToolResponse {
24 | output: FileParserOutputData
25 | }
26 |
--------------------------------------------------------------------------------
/apps/sim/tools/firecrawl/index.ts:
--------------------------------------------------------------------------------
1 | import { scrapeTool } from './scrape'
2 |
3 | export { scrapeTool }
4 |
--------------------------------------------------------------------------------
/apps/sim/tools/firecrawl/types.ts:
--------------------------------------------------------------------------------
1 | import type { ToolResponse } from '../types'
2 |
3 | export interface ScrapeParams {
4 | apiKey: string
5 | url: string
6 | scrapeOptions?: {
7 | onlyMainContent?: boolean
8 | formats?: string[]
9 | }
10 | }
11 |
12 | export interface ScrapeResponse extends ToolResponse {
13 | output: {
14 | markdown: string
15 | html?: string
16 | metadata: {
17 | title: string
18 | description: string
19 | language: string
20 | keywords: string
21 | robots: string
22 | ogTitle: string
23 | ogDescription: string
24 | ogUrl: string
25 | ogImage: string
26 | ogLocaleAlternate: string[]
27 | ogSiteName: string
28 | sourceURL: string
29 | statusCode: number
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/apps/sim/tools/function/index.ts:
--------------------------------------------------------------------------------
1 | import { functionExecuteTool } from './execute'
2 |
3 | export { functionExecuteTool }
4 |
--------------------------------------------------------------------------------
/apps/sim/tools/function/types.ts:
--------------------------------------------------------------------------------
1 | import type { ToolResponse } from '../types'
2 |
3 | export interface CodeExecutionInput {
4 | code: Array<{ content: string; id: string }> | string
5 | timeout?: number
6 | memoryLimit?: number
7 | envVars?: Record
8 | _context?: {
9 | workflowId?: string
10 | }
11 | isCustomTool?: boolean
12 | }
13 |
14 | export interface CodeExecutionOutput extends ToolResponse {
15 | output: {
16 | result: any
17 | stdout: string
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/apps/sim/tools/github/index.ts:
--------------------------------------------------------------------------------
1 | import { commentTool } from './comment'
2 | import { latestCommitTool } from './latest_commit'
3 | import { prTool } from './pr'
4 | import { repoInfoTool } from './repo_info'
5 |
6 | export const githubCommentTool = commentTool
7 | export const githubLatestCommitTool = latestCommitTool
8 | export const githubPrTool = prTool
9 | export const githubRepoInfoTool = repoInfoTool
10 |
--------------------------------------------------------------------------------
/apps/sim/tools/gmail/index.ts:
--------------------------------------------------------------------------------
1 | import { gmailReadTool } from './read'
2 | import { gmailSearchTool } from './search'
3 | import { gmailSendTool } from './send'
4 |
5 | export { gmailSendTool, gmailReadTool, gmailSearchTool }
6 |
--------------------------------------------------------------------------------
/apps/sim/tools/google/index.ts:
--------------------------------------------------------------------------------
1 | import { searchTool } from './search'
2 |
3 | export { searchTool }
4 |
--------------------------------------------------------------------------------
/apps/sim/tools/google/types.ts:
--------------------------------------------------------------------------------
1 | import type { ToolResponse } from '../types'
2 |
3 | export interface GoogleSearchParams {
4 | query: string
5 | apiKey: string
6 | searchEngineId: string
7 | num?: number | string
8 | }
9 |
10 | export interface GoogleSearchResponse extends ToolResponse {
11 | output: {
12 | items: Array<{
13 | title: string
14 | link: string
15 | snippet: string
16 | displayLink?: string
17 | pagemap?: Record
18 | }>
19 | searchInformation: {
20 | totalResults: string
21 | searchTime: number
22 | formattedSearchTime: string
23 | formattedTotalResults: string
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/apps/sim/tools/google_docs/index.ts:
--------------------------------------------------------------------------------
1 | import { createTool } from './create'
2 | import { readTool } from './read'
3 | import { writeTool } from './write'
4 |
5 | export const googleDocsReadTool = readTool
6 | export const googleDocsWriteTool = writeTool
7 | export const googleDocsCreateTool = createTool
8 |
--------------------------------------------------------------------------------
/apps/sim/tools/google_docs/types.ts:
--------------------------------------------------------------------------------
1 | import type { ToolResponse } from '../types'
2 |
3 | export interface GoogleDocsMetadata {
4 | documentId: string
5 | title: string
6 | mimeType?: string
7 | createdTime?: string
8 | modifiedTime?: string
9 | url?: string
10 | }
11 |
12 | export interface GoogleDocsReadResponse extends ToolResponse {
13 | output: {
14 | content: string
15 | metadata: GoogleDocsMetadata
16 | }
17 | }
18 |
19 | export interface GoogleDocsWriteResponse extends ToolResponse {
20 | output: {
21 | updatedContent: boolean
22 | metadata: GoogleDocsMetadata
23 | }
24 | }
25 |
26 | export interface GoogleDocsCreateResponse extends ToolResponse {
27 | output: {
28 | metadata: GoogleDocsMetadata
29 | }
30 | }
31 |
32 | export interface GoogleDocsToolParams {
33 | accessToken: string
34 | documentId?: string
35 | manualDocumentId?: string
36 | title?: string
37 | content?: string
38 | folderId?: string
39 | folderSelector?: string
40 | }
41 |
--------------------------------------------------------------------------------
/apps/sim/tools/google_drive/index.ts:
--------------------------------------------------------------------------------
1 | import { createFolderTool } from './create_folder'
2 | import { getContentTool } from './get_content'
3 | import { listTool } from './list'
4 | import { uploadTool } from './upload'
5 |
6 | export const googleDriveCreateFolderTool = createFolderTool
7 | export const googleDriveGetContentTool = getContentTool
8 | export const googleDriveListTool = listTool
9 | export const googleDriveUploadTool = uploadTool
10 |
--------------------------------------------------------------------------------
/apps/sim/tools/google_drive/types.ts:
--------------------------------------------------------------------------------
1 | import type { ToolResponse } from '../types'
2 |
3 | export interface GoogleDriveFile {
4 | id: string
5 | name: string
6 | mimeType: string
7 | webViewLink?: string
8 | webContentLink?: string
9 | size?: string
10 | createdTime?: string
11 | modifiedTime?: string
12 | parents?: string[]
13 | }
14 |
15 | export interface GoogleDriveListResponse extends ToolResponse {
16 | output: {
17 | files: GoogleDriveFile[]
18 | nextPageToken?: string
19 | }
20 | }
21 |
22 | export interface GoogleDriveUploadResponse extends ToolResponse {
23 | output: {
24 | file: GoogleDriveFile
25 | }
26 | }
27 |
28 | export interface GoogleDriveGetContentResponse extends ToolResponse {
29 | output: {
30 | content: string
31 | metadata: GoogleDriveFile
32 | }
33 | }
34 |
35 | export interface GoogleDriveToolParams {
36 | accessToken: string
37 | folderId?: string
38 | folderSelector?: string
39 | fileId?: string
40 | fileName?: string
41 | content?: string
42 | mimeType?: string
43 | query?: string
44 | pageSize?: number
45 | pageToken?: string
46 | exportMimeType?: string
47 | }
48 |
--------------------------------------------------------------------------------
/apps/sim/tools/google_drive/utils.ts:
--------------------------------------------------------------------------------
1 | export const GOOGLE_WORKSPACE_MIME_TYPES = [
2 | 'application/vnd.google-apps.document', // Google Docs
3 | 'application/vnd.google-apps.spreadsheet', // Google Sheets
4 | 'application/vnd.google-apps.presentation', // Google Slides
5 | 'application/vnd.google-apps.drawing', // Google Drawings
6 | 'application/vnd.google-apps.form', // Google Forms
7 | 'application/vnd.google-apps.script', // Google Apps Scripts
8 | ]
9 |
10 | export const DEFAULT_EXPORT_FORMATS: Record = {
11 | 'application/vnd.google-apps.document': 'text/plain',
12 | 'application/vnd.google-apps.spreadsheet': 'text/csv',
13 | 'application/vnd.google-apps.presentation': 'text/plain',
14 | 'application/vnd.google-apps.drawing': 'image/png',
15 | 'application/vnd.google-apps.form': 'application/pdf',
16 | 'application/vnd.google-apps.script': 'application/json',
17 | }
18 |
19 | export const SOURCE_MIME_TYPES: Record = {
20 | 'application/vnd.google-apps.document': 'text/plain',
21 | 'application/vnd.google-apps.spreadsheet': 'text/csv',
22 | 'application/vnd.google-apps.presentation': 'application/vnd.ms-powerpoint',
23 | }
24 |
--------------------------------------------------------------------------------
/apps/sim/tools/google_sheets/index.ts:
--------------------------------------------------------------------------------
1 | import { appendTool } from './append'
2 | import { readTool } from './read'
3 | import { updateTool } from './update'
4 | import { writeTool } from './write'
5 |
6 | export const googleSheetsReadTool = readTool
7 | export const googleSheetsWriteTool = writeTool
8 | export const googleSheetsUpdateTool = updateTool
9 | export const googleSheetsAppendTool = appendTool
10 |
--------------------------------------------------------------------------------
/apps/sim/tools/guesty/index.ts:
--------------------------------------------------------------------------------
1 | import { guestyGuestTool } from './guest'
2 | import { guestyReservationTool } from './reservation'
3 |
4 | export { guestyGuestTool, guestyReservationTool }
5 |
--------------------------------------------------------------------------------
/apps/sim/tools/guesty/types.ts:
--------------------------------------------------------------------------------
1 | import type { ToolResponse } from '../types'
2 |
3 | export interface GuestyGuestParams {
4 | apiKey: string
5 | phoneNumber: string
6 | }
7 |
8 | export interface GuestyGuestResponse extends ToolResponse {
9 | output: {
10 | guests: Array<{
11 | id: string
12 | fullName: string
13 | email: string
14 | phone: string
15 | address: string
16 | city: string
17 | country: string
18 | }>
19 | }
20 | }
21 |
22 | export interface GuestyReservationParams {
23 | apiKey: string
24 | reservationId: string
25 | }
26 |
27 | export interface GuestyReservationResponse extends ToolResponse {
28 | output: {
29 | id: string
30 | guest: {
31 | fullName: string
32 | email: string
33 | phone: string
34 | }
35 | checkIn: string
36 | checkOut: string
37 | status: string
38 | listing: {
39 | id: string
40 | title: string
41 | }
42 | money: {
43 | totalPaid: number
44 | currency: string
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/apps/sim/tools/http/index.ts:
--------------------------------------------------------------------------------
1 | import { requestTool } from './request'
2 |
3 | export { requestTool }
4 |
--------------------------------------------------------------------------------
/apps/sim/tools/http/types.ts:
--------------------------------------------------------------------------------
1 | import type { HttpMethod, TableRow, ToolResponse } from '../types'
2 |
3 | export interface RequestParams {
4 | url: string
5 | method?: HttpMethod
6 | headers?: TableRow[]
7 | body?: any
8 | params?: TableRow[]
9 | pathParams?: Record
10 | formData?: Record
11 | timeout?: number
12 | validateStatus?: (status: number) => boolean
13 | }
14 |
15 | export interface RequestResponse extends ToolResponse {
16 | output: {
17 | data: any
18 | status: number
19 | headers: Record
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/apps/sim/tools/jina/index.ts:
--------------------------------------------------------------------------------
1 | import { readUrlTool } from './read_url'
2 |
3 | export { readUrlTool }
4 |
--------------------------------------------------------------------------------
/apps/sim/tools/jina/types.ts:
--------------------------------------------------------------------------------
1 | import type { ToolResponse } from '../types'
2 |
3 | export interface ReadUrlParams {
4 | url: string
5 | useReaderLMv2?: boolean
6 | gatherLinks?: boolean
7 | jsonResponse?: boolean
8 | apiKey?: string
9 | }
10 |
11 | export interface ReadUrlResponse extends ToolResponse {
12 | output: {
13 | content: string
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/apps/sim/tools/jira/index.ts:
--------------------------------------------------------------------------------
1 | import { jiraBulkRetrieveTool } from './bulk_read'
2 | import { jiraRetrieveTool } from './retrieve'
3 | import { jiraUpdateTool } from './update'
4 | import { jiraWriteTool } from './write'
5 |
6 | export { jiraRetrieveTool }
7 | export { jiraUpdateTool }
8 | export { jiraWriteTool }
9 | export { jiraBulkRetrieveTool }
10 |
--------------------------------------------------------------------------------
/apps/sim/tools/jira/utils.ts:
--------------------------------------------------------------------------------
1 | export async function getJiraCloudId(domain: string, accessToken: string): Promise {
2 | const response = await fetch('https://api.atlassian.com/oauth/token/accessible-resources', {
3 | method: 'GET',
4 | headers: {
5 | Authorization: `Bearer ${accessToken}`,
6 | Accept: 'application/json',
7 | },
8 | })
9 |
10 | const resources = await response.json()
11 |
12 | // If we have resources, find the matching one
13 | if (Array.isArray(resources) && resources.length > 0) {
14 | const normalizedInput = `https://${domain}`.toLowerCase()
15 | const matchedResource = resources.find((r) => r.url.toLowerCase() === normalizedInput)
16 |
17 | if (matchedResource) {
18 | return matchedResource.id
19 | }
20 | }
21 |
22 | // If we couldn't find a match, return the first resource's ID
23 | // This is a fallback in case the URL matching fails
24 | if (Array.isArray(resources) && resources.length > 0) {
25 | return resources[0].id
26 | }
27 |
28 | throw new Error('No Jira resources found')
29 | }
30 |
--------------------------------------------------------------------------------
/apps/sim/tools/knowledge/index.ts:
--------------------------------------------------------------------------------
1 | import { knowledgeSearchTool } from './search'
2 |
3 | export { knowledgeSearchTool }
4 |
--------------------------------------------------------------------------------
/apps/sim/tools/knowledge/types.ts:
--------------------------------------------------------------------------------
1 | export interface KnowledgeSearchResult {
2 | id: string
3 | content: string
4 | documentId: string
5 | chunkIndex: number
6 | metadata: Record
7 | similarity: number
8 | }
9 |
10 | export interface KnowledgeSearchResponse {
11 | success: boolean
12 | output: {
13 | results: KnowledgeSearchResult[]
14 | query: string
15 | knowledgeBaseId: string
16 | topK: number
17 | totalResults: number
18 | message: string
19 | }
20 | error?: string
21 | }
22 |
23 | export interface KnowledgeSearchParams {
24 | knowledgeBaseId: string
25 | query: string
26 | topK?: number
27 | }
28 |
--------------------------------------------------------------------------------
/apps/sim/tools/linear/index.ts:
--------------------------------------------------------------------------------
1 | import { linearCreateIssueTool } from './create_issue'
2 | import { linearReadIssuesTool } from './read_issues'
3 |
4 | export { linearReadIssuesTool, linearCreateIssueTool }
5 |
--------------------------------------------------------------------------------
/apps/sim/tools/linear/types.ts:
--------------------------------------------------------------------------------
1 | import type { ToolResponse } from '../types'
2 |
3 | export interface LinearIssue {
4 | id: string
5 | title: string
6 | description?: string
7 | state?: string
8 | teamId: string
9 | projectId: string
10 | }
11 |
12 | export interface LinearReadIssuesParams {
13 | teamId: string
14 | projectId: string
15 | accessToken?: string
16 | }
17 |
18 | export interface LinearCreateIssueParams {
19 | teamId: string
20 | projectId: string
21 | title: string
22 | description?: string
23 | accessToken?: string
24 | }
25 |
26 | export interface LinearReadIssuesResponse extends ToolResponse {
27 | output: {
28 | issues: LinearIssue[]
29 | }
30 | }
31 |
32 | export interface LinearCreateIssueResponse extends ToolResponse {
33 | output: {
34 | issue: LinearIssue
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/apps/sim/tools/linkup/index.ts:
--------------------------------------------------------------------------------
1 | import { searchTool } from './search'
2 |
3 | export const linkupSearchTool = searchTool
4 |
--------------------------------------------------------------------------------
/apps/sim/tools/linkup/types.ts:
--------------------------------------------------------------------------------
1 | import type { ToolResponse } from '../types'
2 |
3 | export interface LinkupSource {
4 | name: string
5 | url: string
6 | snippet: string
7 | }
8 |
9 | export interface LinkupSearchParams {
10 | q: string
11 | apiKey: string
12 | depth?: 'standard' | 'deep'
13 | outputType?: 'sourcedAnswer' | 'searchResults'
14 | }
15 |
16 | export interface LinkupSearchResponse {
17 | answer: string
18 | sources: LinkupSource[]
19 | }
20 |
21 | export interface LinkupSearchToolResponse extends ToolResponse {
22 | output: LinkupSearchResponse
23 | }
24 |
--------------------------------------------------------------------------------
/apps/sim/tools/mem0/index.ts:
--------------------------------------------------------------------------------
1 | import { mem0AddMemoriesTool } from './add_memories'
2 | import { mem0GetMemoriesTool } from './get_memories'
3 | import { mem0SearchMemoriesTool } from './search_memories'
4 |
5 | export { mem0AddMemoriesTool, mem0SearchMemoriesTool, mem0GetMemoriesTool }
6 |
--------------------------------------------------------------------------------
/apps/sim/tools/mem0/types.ts:
--------------------------------------------------------------------------------
1 | import type { ToolResponse } from '../types'
2 |
3 | export interface Mem0Response extends ToolResponse {
4 | output: {
5 | ids?: string[]
6 | memories?: any[]
7 | searchResults?: any[]
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/apps/sim/tools/memory/index.ts:
--------------------------------------------------------------------------------
1 | import { memoryAddTool } from './add'
2 | import { memoryDeleteTool } from './delete'
3 | import { memoryGetTool } from './get'
4 | import { memoryGetAllTool } from './get_all'
5 |
6 | export { memoryAddTool, memoryGetTool, memoryGetAllTool, memoryDeleteTool }
7 |
--------------------------------------------------------------------------------
/apps/sim/tools/memory/types.ts:
--------------------------------------------------------------------------------
1 | import type { ToolResponse } from '../types'
2 |
3 | export interface MemoryResponse extends ToolResponse {
4 | output: {
5 | memories?: any[]
6 | message?: string
7 | }
8 | }
9 |
10 | export interface AgentMemoryData {
11 | role: 'user' | 'assistant' | 'system'
12 | content: string
13 | }
14 |
15 | export interface MemoryRecord {
16 | id: string
17 | key: string
18 | type: 'agent'
19 | data: AgentMemoryData[]
20 | createdAt: string
21 | updatedAt: string
22 | workflowId?: string
23 | workspaceId?: string
24 | }
25 |
26 | export interface MemoryError {
27 | code: string
28 | message: string
29 | details?: Record
30 | }
31 |
--------------------------------------------------------------------------------
/apps/sim/tools/microsoft_excel/index.ts:
--------------------------------------------------------------------------------
1 | import { readTool } from './read'
2 | import { tableAddTool } from './table_add'
3 | import { writeTool } from './write'
4 |
5 | export const microsoftExcelReadTool = readTool
6 | export const microsoftExcelTableAddTool = tableAddTool
7 | export const microsoftExcelWriteTool = writeTool
8 |
--------------------------------------------------------------------------------
/apps/sim/tools/microsoft_teams/attachment-utils.ts:
--------------------------------------------------------------------------------
1 | import type { MicrosoftTeamsAttachment } from './types'
2 |
3 | /**
4 | * Transform raw attachment data from Microsoft Graph API
5 | */
6 | function transformAttachment(rawAttachment: any): MicrosoftTeamsAttachment {
7 | return {
8 | id: rawAttachment.id,
9 | contentType: rawAttachment.contentType,
10 | contentUrl: rawAttachment.contentUrl,
11 | content: rawAttachment.content,
12 | name: rawAttachment.name,
13 | thumbnailUrl: rawAttachment.thumbnailUrl,
14 | size: rawAttachment.size,
15 | sourceUrl: rawAttachment.sourceUrl,
16 | providerType: rawAttachment.providerType,
17 | item: rawAttachment.item,
18 | }
19 | }
20 |
21 | /**
22 | * Extract attachments from message data
23 | * Returns all attachments without any content processing
24 | */
25 | export function extractMessageAttachments(message: any): MicrosoftTeamsAttachment[] {
26 | const attachments = (message.attachments || []).map(transformAttachment)
27 |
28 | return attachments
29 | }
30 |
--------------------------------------------------------------------------------
/apps/sim/tools/microsoft_teams/index.ts:
--------------------------------------------------------------------------------
1 | import { readChannelTool } from './read_channel'
2 | import { readChatTool } from './read_chat'
3 | import { writeChannelTool } from './write_channel'
4 | import { writeChatTool } from './write_chat'
5 |
6 | export const microsoftTeamsReadChannelTool = readChannelTool
7 | export const microsoftTeamsWriteChannelTool = writeChannelTool
8 | export const microsoftTeamsReadChatTool = readChatTool
9 | export const microsoftTeamsWriteChatTool = writeChatTool
10 |
--------------------------------------------------------------------------------
/apps/sim/tools/microsoft_teams/types.ts:
--------------------------------------------------------------------------------
1 | import type { ToolResponse } from '../types'
2 |
3 | export interface MicrosoftTeamsAttachment {
4 | id: string
5 | contentType: string
6 | contentUrl?: string
7 | content?: string
8 | name?: string
9 | thumbnailUrl?: string
10 | size?: number
11 | sourceUrl?: string
12 | providerType?: string
13 | item?: any
14 | }
15 |
16 | export interface MicrosoftTeamsMetadata {
17 | messageId?: string
18 | channelId?: string
19 | teamId?: string
20 | chatId?: string
21 | content?: string
22 | createdTime?: string
23 | url?: string
24 | messageCount?: number
25 | messages?: Array<{
26 | id: string
27 | content: string
28 | sender: string
29 | timestamp: string
30 | messageType: string
31 | attachments?: MicrosoftTeamsAttachment[]
32 | }>
33 | // Global attachments summary
34 | totalAttachments?: number
35 | attachmentTypes?: string[]
36 | }
37 |
38 | export interface MicrosoftTeamsReadResponse extends ToolResponse {
39 | output: {
40 | content: string
41 | metadata: MicrosoftTeamsMetadata
42 | }
43 | }
44 |
45 | export interface MicrosoftTeamsWriteResponse extends ToolResponse {
46 | output: {
47 | updatedContent: boolean
48 | metadata: MicrosoftTeamsMetadata
49 | }
50 | }
51 |
52 | export interface MicrosoftTeamsToolParams {
53 | accessToken: string
54 | messageId?: string
55 | chatId?: string
56 | channelId?: string
57 | teamId?: string
58 | content?: string
59 | }
60 |
--------------------------------------------------------------------------------
/apps/sim/tools/mistral/index.ts:
--------------------------------------------------------------------------------
1 | import { mistralParserTool } from './parser'
2 |
3 | export { mistralParserTool }
4 |
--------------------------------------------------------------------------------
/apps/sim/tools/notion/index.ts:
--------------------------------------------------------------------------------
1 | import { notionCreatePageTool } from './create_page'
2 | import { notionReadTool } from './read'
3 | import { notionUpdatePageTool } from './update_page'
4 | import { notionWriteTool } from './write'
5 |
6 | export { notionReadTool, notionWriteTool, notionCreatePageTool, notionUpdatePageTool }
7 |
--------------------------------------------------------------------------------
/apps/sim/tools/notion/types.ts:
--------------------------------------------------------------------------------
1 | import type { ToolResponse } from '../types'
2 |
3 | export interface NotionReadParams {
4 | pageId: string
5 | accessToken: string
6 | }
7 |
8 | export interface NotionResponse extends ToolResponse {
9 | output: {
10 | content: string
11 | metadata?: {
12 | title?: string
13 | lastEditedTime?: string
14 | createdTime?: string
15 | url?: string
16 | }
17 | }
18 | }
19 |
20 | export interface NotionWriteParams {
21 | pageId: string
22 | content: string
23 | accessToken: string
24 | }
25 |
26 | export interface NotionCreatePageParams {
27 | parentType: 'page' | 'database'
28 | parentId: string
29 | title?: string
30 | properties?: Record
31 | content?: string
32 | accessToken: string
33 | }
34 |
35 | export interface NotionUpdatePageParams {
36 | pageId: string
37 | properties: Record
38 | accessToken: string
39 | }
40 |
--------------------------------------------------------------------------------
/apps/sim/tools/openai/index.ts:
--------------------------------------------------------------------------------
1 | import { embeddingsTool } from './embeddings'
2 | import { imageTool } from './image'
3 |
4 | export { embeddingsTool, imageTool }
5 |
--------------------------------------------------------------------------------
/apps/sim/tools/openai/types.ts:
--------------------------------------------------------------------------------
1 | import type { ToolResponse } from '../types'
2 |
3 | export interface BaseImageRequestBody {
4 | model: string
5 | prompt: string
6 | size: string
7 | n: number
8 | [key: string]: any // Allow for additional properties
9 | }
10 |
11 | export interface DalleResponse extends ToolResponse {
12 | output: {
13 | content: string // This will now be the image URL
14 | image: string // This will be the base64 image data
15 | metadata: {
16 | model: string // Only contains model name now
17 | }
18 | }
19 | }
20 |
21 | export interface OpenAIEmbeddingsParams {
22 | apiKey: string
23 | input: string | string[]
24 | model?: string
25 | encoding_format?: 'float' | 'base64'
26 | user?: string
27 | }
28 |
--------------------------------------------------------------------------------
/apps/sim/tools/outlook/index.ts:
--------------------------------------------------------------------------------
1 | import { outlookDraftTool } from './draft'
2 | import { outlookReadTool } from './read'
3 | import { outlookSendTool } from './send'
4 |
5 | export { outlookDraftTool, outlookReadTool, outlookSendTool }
6 |
--------------------------------------------------------------------------------
/apps/sim/tools/perplexity/index.ts:
--------------------------------------------------------------------------------
1 | import { chatTool } from './chat'
2 |
3 | export const perplexityChatTool = chatTool
4 |
--------------------------------------------------------------------------------
/apps/sim/tools/perplexity/types.ts:
--------------------------------------------------------------------------------
1 | import type { ToolResponse } from '../types'
2 |
3 | export interface PerplexityMessage {
4 | role: string
5 | content: string
6 | }
7 |
8 | export interface PerplexityChatParams {
9 | apiKey: string
10 | model: string
11 | messages?: PerplexityMessage[]
12 | max_tokens?: number
13 | temperature?: number
14 |
15 | prompt?: string
16 | system?: string
17 | }
18 |
19 | export interface PerplexityChatResponse extends ToolResponse {
20 | output: {
21 | content: string
22 | model: string
23 | usage: {
24 | prompt_tokens: number
25 | completion_tokens: number
26 | total_tokens: number
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/apps/sim/tools/pinecone/index.ts:
--------------------------------------------------------------------------------
1 | import { fetchTool } from './fetch'
2 | import { generateEmbeddingsTool } from './generate_embeddings'
3 | import { searchTextTool } from './search_text'
4 | import { searchVectorTool } from './search_vector'
5 | import { upsertTextTool } from './upsert_text'
6 |
7 | export const pineconeFetchTool = fetchTool
8 | export const pineconeGenerateEmbeddingsTool = generateEmbeddingsTool
9 | export const pineconeSearchTextTool = searchTextTool
10 | export const pineconeSearchVectorTool = searchVectorTool
11 | export const pineconeUpsertTextTool = upsertTextTool
12 |
--------------------------------------------------------------------------------
/apps/sim/tools/reddit/index.ts:
--------------------------------------------------------------------------------
1 | import { getCommentsTool } from './get_comments'
2 | import { getPostsTool } from './get_posts'
3 | import { hotPostsTool } from './hot_posts'
4 |
5 | export const redditHotPostsTool = hotPostsTool
6 | export const redditGetPostsTool = getPostsTool
7 | export const redditGetCommentsTool = getCommentsTool
8 |
--------------------------------------------------------------------------------
/apps/sim/tools/s3/index.ts:
--------------------------------------------------------------------------------
1 | import { s3GetObjectTool } from './get_object'
2 |
3 | export { s3GetObjectTool }
4 |
--------------------------------------------------------------------------------
/apps/sim/tools/s3/types.ts:
--------------------------------------------------------------------------------
1 | import type { ToolResponse } from '../types'
2 |
3 | export interface S3Response extends ToolResponse {
4 | output: {
5 | url: string
6 | metadata: {
7 | fileType: string
8 | size: number
9 | name: string
10 | lastModified: string
11 | error?: string
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/apps/sim/tools/serper/index.ts:
--------------------------------------------------------------------------------
1 | import { searchTool } from './search'
2 |
3 | export { searchTool }
4 |
--------------------------------------------------------------------------------
/apps/sim/tools/serper/types.ts:
--------------------------------------------------------------------------------
1 | import type { ToolResponse } from '../types'
2 |
3 | export interface SearchParams {
4 | query: string
5 | apiKey: string
6 | num?: number
7 | gl?: string // country code
8 | hl?: string // language code
9 | type?: 'search' | 'news' | 'places' | 'images'
10 | }
11 |
12 | export interface SearchResult {
13 | title: string
14 | link: string
15 | snippet: string
16 | position: number
17 | imageUrl?: string
18 | date?: string
19 | rating?: string
20 | reviews?: string
21 | address?: string
22 | }
23 |
24 | export interface SearchResponse extends ToolResponse {
25 | output: {
26 | searchResults: SearchResult[]
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/apps/sim/tools/slack/index.ts:
--------------------------------------------------------------------------------
1 | import { slackMessageTool } from './message'
2 |
3 | export { slackMessageTool }
4 |
--------------------------------------------------------------------------------
/apps/sim/tools/slack/types.ts:
--------------------------------------------------------------------------------
1 | import type { ToolResponse } from '../types'
2 |
3 | export interface SlackBaseParams {
4 | authMethod: 'oauth' | 'bot_token'
5 | accessToken: string
6 | botToken: string
7 | }
8 |
9 | export interface SlackMessageParams extends SlackBaseParams {
10 | channel: string
11 | text: string
12 | thread_ts?: string
13 | }
14 |
15 | export interface SlackMessageResponse extends ToolResponse {
16 | output: {
17 | ts: string
18 | channel: string
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/apps/sim/tools/stagehand/index.ts:
--------------------------------------------------------------------------------
1 | import { agentTool } from './agent'
2 | import { extractTool } from './extract'
3 |
4 | export const stagehandExtractTool = extractTool
5 | export const stagehandAgentTool = agentTool
6 |
--------------------------------------------------------------------------------
/apps/sim/tools/supabase/index.ts:
--------------------------------------------------------------------------------
1 | import { insertTool } from './insert'
2 | import { queryTool } from './query'
3 |
4 | export const supabaseQueryTool = queryTool
5 | export const supabaseInsertTool = insertTool
6 |
--------------------------------------------------------------------------------
/apps/sim/tools/supabase/types.ts:
--------------------------------------------------------------------------------
1 | import type { ToolResponse } from '../types'
2 |
3 | export interface SupabaseQueryParams {
4 | apiKey: string
5 | projectId: string
6 | table: string
7 | }
8 |
9 | export interface SupabaseInsertParams {
10 | apiKey: string
11 | projectId: string
12 | table: string
13 | data: any
14 | }
15 |
16 | export interface SupabaseQueryResponse extends ToolResponse {
17 | error?: string
18 | output: {
19 | message: string
20 | results: any
21 | }
22 | }
23 |
24 | export interface SupabaseInsertResponse extends ToolResponse {
25 | error?: string
26 | output: {
27 | message: string
28 | results: any
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/apps/sim/tools/tavily/index.ts:
--------------------------------------------------------------------------------
1 | import { extractTool } from './extract'
2 | import { searchTool } from './search'
3 |
4 | export const tavilyExtractTool = extractTool
5 | export const tavilySearchTool = searchTool
6 |
--------------------------------------------------------------------------------
/apps/sim/tools/telegram/index.ts:
--------------------------------------------------------------------------------
1 | import { telegramMessageTool } from './message'
2 |
3 | export { telegramMessageTool }
4 |
--------------------------------------------------------------------------------
/apps/sim/tools/telegram/types.ts:
--------------------------------------------------------------------------------
1 | import type { ToolResponse } from '../types'
2 |
3 | export interface TelegramMessageParams {
4 | botToken: string
5 | chatId: string
6 | text: string
7 | }
8 |
9 | export interface TelegramMessageResponse extends ToolResponse {
10 | output: {
11 | ok: boolean
12 | result: {
13 | message_id: number
14 | chat: {
15 | id: number
16 | type: string
17 | username: string
18 | }
19 | date: number
20 | text: string
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/apps/sim/tools/thinking/index.ts:
--------------------------------------------------------------------------------
1 | import { thinkingTool } from './tool'
2 |
3 | export { thinkingTool }
4 |
--------------------------------------------------------------------------------
/apps/sim/tools/thinking/tool.ts:
--------------------------------------------------------------------------------
1 | import type { ToolConfig } from '../types'
2 | import type { ThinkingToolParams, ThinkingToolResponse } from './types'
3 |
4 | export const thinkingTool: ToolConfig = {
5 | id: 'thinking_tool',
6 | name: 'Thinking Tool',
7 | description:
8 | 'Processes a provided thought/instruction, making it available for subsequent steps.',
9 | version: '1.0.0',
10 |
11 | // Define the input parameter
12 | params: {
13 | thought: {
14 | type: 'string',
15 | required: true,
16 | description:
17 | 'The thought process or instruction provided by the user in the Thinking Step block.',
18 | },
19 | },
20 |
21 | // Use directExecution as no external HTTP call is needed
22 | directExecution: async (params: ThinkingToolParams): Promise => {
23 | // Simply acknowledge the thought by returning it in the output
24 | return {
25 | success: true,
26 | output: {
27 | acknowledgedThought: params.thought,
28 | },
29 | }
30 | },
31 |
32 | // Request configuration is not needed due to directExecution, but the type requires it.
33 | // Provide minimal valid configuration.
34 | request: {
35 | url: '', // Not used
36 | method: 'POST', // Not used
37 | headers: () => ({}), // Not used
38 | },
39 | }
40 |
--------------------------------------------------------------------------------
/apps/sim/tools/thinking/types.ts:
--------------------------------------------------------------------------------
1 | import type { ToolResponse } from '../types'
2 |
3 | export interface ThinkingToolParams {
4 | thought: string
5 | }
6 |
7 | export interface ThinkingToolResponse extends ToolResponse {
8 | output: {
9 | acknowledgedThought: string
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/apps/sim/tools/twilio/index.ts:
--------------------------------------------------------------------------------
1 | import { sendSMSTool } from './send_sms'
2 |
3 | export { sendSMSTool }
4 |
--------------------------------------------------------------------------------
/apps/sim/tools/twilio/types.ts:
--------------------------------------------------------------------------------
1 | import type { ToolResponse } from '../types'
2 |
3 | export interface TwilioSendSMSParams {
4 | phoneNumbers: string
5 | message: string
6 | accountSid: string
7 | authToken: string
8 | fromNumber: string
9 | }
10 |
11 | export interface TwilioSMSBlockOutput extends ToolResponse {
12 | output: {
13 | success: boolean
14 | messageId?: string
15 | status?: string
16 | error?: string
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/apps/sim/tools/typeform/index.ts:
--------------------------------------------------------------------------------
1 | import { filesTool } from './files'
2 | import { insightsTool } from './insights'
3 | import { responsesTool } from './responses'
4 |
5 | export const typeformResponsesTool = responsesTool
6 | export const typeformFilesTool = filesTool
7 | export const typeformInsightsTool = insightsTool
8 |
--------------------------------------------------------------------------------
/apps/sim/tools/vision/index.ts:
--------------------------------------------------------------------------------
1 | import { visionTool } from './tool'
2 |
3 | export { visionTool }
4 |
--------------------------------------------------------------------------------
/apps/sim/tools/vision/types.ts:
--------------------------------------------------------------------------------
1 | import type { ToolResponse } from '../types'
2 |
3 | export interface VisionParams {
4 | apiKey: string
5 | imageUrl: string
6 | model?: string
7 | prompt?: string
8 | }
9 |
10 | export interface VisionResponse extends ToolResponse {
11 | output: {
12 | content: string
13 | model?: string
14 | tokens?: number
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/apps/sim/tools/whatsapp/index.ts:
--------------------------------------------------------------------------------
1 | import { sendMessageTool } from './send_message'
2 |
3 | export const whatsappSendMessageTool = sendMessageTool
4 |
--------------------------------------------------------------------------------
/apps/sim/tools/whatsapp/types.ts:
--------------------------------------------------------------------------------
1 | import type { ToolResponse } from '../types'
2 |
3 | export interface WhatsAppToolResponse extends ToolResponse {
4 | output: {
5 | success: boolean
6 | messageId?: string
7 | error?: string
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/apps/sim/tools/x/index.ts:
--------------------------------------------------------------------------------
1 | import { xReadTool } from './read'
2 | import { xSearchTool } from './search'
3 | import { xUserTool } from './user'
4 | import { xWriteTool } from './write'
5 |
6 | export { xReadTool }
7 | export { xWriteTool }
8 | export { xSearchTool }
9 | export { xUserTool }
10 |
--------------------------------------------------------------------------------
/apps/sim/tools/youtube/index.ts:
--------------------------------------------------------------------------------
1 | import { youtubeSearchTool } from './search'
2 |
3 | export { youtubeSearchTool }
4 |
--------------------------------------------------------------------------------
/apps/sim/tools/youtube/types.ts:
--------------------------------------------------------------------------------
1 | import type { ToolResponse } from '../types'
2 |
3 | export interface YouTubeSearchParams {
4 | apiKey: string
5 | query: string
6 | maxResults?: number
7 | pageToken?: string
8 | }
9 |
10 | export interface YouTubeSearchResponse extends ToolResponse {
11 | output: {
12 | items: Array<{
13 | videoId: string
14 | title: string
15 | description: string
16 | thumbnail: string
17 | }>
18 | totalResults: number
19 | nextPageToken?: string
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/apps/sim/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2020",
4 | "module": "esnext",
5 | "moduleResolution": "bundler",
6 | "lib": ["es2020", "dom", "dom.iterable"],
7 | "strict": true,
8 | "esModuleInterop": true,
9 | "skipLibCheck": true,
10 | "forceConsistentCasingInFileNames": true,
11 | "baseUrl": ".",
12 | "paths": {
13 | "@/*": ["./*"],
14 | "@/components/*": ["components/*"],
15 | "@/lib/*": ["./lib/*"],
16 | "@/stores": ["./stores"],
17 | "@/stores/*": ["./stores/*"],
18 | "@/hooks/*": ["./hooks/*"],
19 | "@/blocks": ["./blocks"],
20 | "@/blocks/*": ["./blocks/*"],
21 | "@/providers/*": ["./providers/*"],
22 | "@/providers": ["./providers"],
23 | "@/tools": ["./tools"],
24 | "@/tools/*": ["./tools/*"],
25 | "@/serializer": ["./serializer"],
26 | "@/serializer/*": ["./serializer/*"],
27 | "@/db": ["./db"],
28 | "@/db/*": ["./db/*"],
29 | "@/executor": ["./executor"],
30 | "@/executor/*": ["./executor/*"]
31 | },
32 | "allowJs": true,
33 | "noEmit": true,
34 | "incremental": true,
35 | "resolveJsonModule": true,
36 | "isolatedModules": true,
37 | "allowImportingTsExtensions": true,
38 | "jsx": "preserve",
39 | "plugins": [
40 | {
41 | "name": "next"
42 | }
43 | ]
44 | },
45 | "include": [
46 | "**/*.ts",
47 | "**/*.tsx",
48 | ".next/types/**/*.ts",
49 | "../next-env.d.ts",
50 | "telemetry.config.js"
51 | ],
52 | "exclude": ["node_modules"]
53 | }
54 |
--------------------------------------------------------------------------------
/apps/sim/vercel.json:
--------------------------------------------------------------------------------
1 | {
2 | "crons": [
3 | {
4 | "path": "/api/schedules/execute",
5 | "schedule": "*/1 * * * *"
6 | },
7 | {
8 | "path": "/api/webhooks/poll/gmail",
9 | "schedule": "*/1 * * * *"
10 | },
11 | {
12 | "path": "/api/logs/cleanup",
13 | "schedule": "0 0 * * *"
14 | }
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/bunfig.toml:
--------------------------------------------------------------------------------
1 | # Bun Configuration File
2 |
3 | [install]
4 | # Recommend using exact versions for better reproducibility
5 | exact = true
6 | # Auto-detect lockfile and registry changes
7 | registry = "https://registry.npmjs.org/"
8 | # Cache binaries for faster install
9 | cache = true
10 | # Strict mode for more reliable dependency resolution
11 | strict = false
12 | # Enables frozen lockfile by default to prevent accidental changes
13 | frozen = false
14 |
15 | # Configure workspaces for monorepo
16 | workspaces = ["apps/*", "packages/*"]
17 |
18 | [test]
19 | # Test configuration
20 | preload = "./apps/sim/test/setup.ts"
21 | extensions = [".test.ts", ".test.tsx"]
22 | timeout = 10000
23 |
24 | [run]
25 | # Environment setting for running scripts
26 | env = { NEXT_PUBLIC_APP_URL = "http://localhost:3000" }
27 |
28 | [build]
29 | # Build configuration
30 | minify = true
31 |
32 | [debug]
33 | # Configure debug mode
34 | inject-preload = true
--------------------------------------------------------------------------------
/docker-compose.ollama.yml:
--------------------------------------------------------------------------------
1 | services:
2 | local-llm-gpu:
3 | profiles:
4 | - local-gpu # This profile requires both 'local' and 'gpu'
5 | image: ollama/ollama:latest
6 | pull_policy: always
7 | volumes:
8 | - ${HOME}/.ollama:/root/.ollama
9 | ports:
10 | - '11434:11434'
11 | environment:
12 | - NVIDIA_DRIVER_CAPABILITIES=all
13 | - OLLAMA_LOAD_TIMEOUT=-1
14 | - OLLAMA_KEEP_ALIVE=-1
15 | - OLLAMA_DEBUG=1
16 | command: 'serve'
17 | deploy:
18 | resources:
19 | reservations:
20 | devices:
21 | - driver: nvidia
22 | count: all
23 | capabilities: [gpu]
24 | healthcheck:
25 | test: ['CMD', 'curl', '-f', 'http://localhost:11434/']
26 | interval: 10s
27 | timeout: 5s
28 | retries: 5
29 |
30 | local-llm-cpu:
31 | profiles:
32 | - local-cpu # This profile requires both 'local' and 'cpu'
33 | image: ollama/ollama:latest
34 | pull_policy: always
35 | volumes:
36 | - ${HOME}/.ollama:/root/.ollama
37 | ports:
38 | - '11434:11434'
39 | environment:
40 | - OLLAMA_LOAD_TIMEOUT=-1
41 | - OLLAMA_KEEP_ALIVE=-1
42 | - OLLAMA_DEBUG=1
43 | command: 'serve'
44 | healthcheck:
45 | test: ['CMD', 'curl', '-f', 'http://localhost:11434/']
46 | interval: 10s
47 | timeout: 5s
48 | retries: 5
49 |
--------------------------------------------------------------------------------
/docker/db.Dockerfile:
--------------------------------------------------------------------------------
1 | # ========================================
2 | # Dependencies Stage: Install Dependencies
3 | # ========================================
4 | FROM oven/bun:alpine AS deps
5 | WORKDIR /app
6 |
7 | # Copy only package files needed for migrations
8 | COPY package.json bun.lock turbo.json ./
9 | COPY apps/sim/package.json ./apps/sim/db/
10 |
11 | # Install minimal dependencies in one layer
12 | RUN bun install --omit dev --ignore-scripts && \
13 | bun install --omit dev --ignore-scripts drizzle-kit drizzle-orm postgres next-runtime-env zod @t3-oss/env-nextjs
14 |
15 | # ========================================
16 | # Runner Stage: Production Environment
17 | # ========================================
18 | FROM oven/bun:alpine AS runner
19 | WORKDIR /app
20 |
21 | # Copy only the necessary files from deps
22 | COPY --from=deps /app/node_modules ./node_modules
23 | COPY apps/sim/drizzle.config.ts ./apps/sim/drizzle.config.ts
24 | COPY apps/sim/db ./apps/sim/db
25 | COPY apps/sim/package.json ./apps/sim/package.json
26 | COPY apps/sim/lib/env.ts ./apps/sim/lib/env.ts
27 |
28 | WORKDIR /app/apps/sim
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "simstudio",
3 | "packageManager": "bun@1.2.12",
4 | "version": "0.0.0",
5 | "private": true,
6 | "license": "Apache-2.0",
7 | "workspaces": [
8 | "apps/*",
9 | "packages/*"
10 | ],
11 | "scripts": {
12 | "build": "turbo run build",
13 | "dev": "turbo run dev",
14 | "test": "turbo run test",
15 | "format": "bunx biome format --write .",
16 | "format:check": "bunx biome format .",
17 | "lint": "bunx biome check --write --unsafe .",
18 | "lint:check": "bunx biome check --unsafe .",
19 | "check": "bunx biome check --files-ignore-unknown=true",
20 | "prepare": "bun husky",
21 | "prebuild": "bun run lint:check",
22 | "type-check": "turbo run type-check"
23 | },
24 | "overrides": {
25 | "react": "19.1.0",
26 | "react-dom": "19.1.0",
27 | "tailwindcss": "3.4.1"
28 | },
29 | "dependencies": {
30 | "@linear/sdk": "40.0.0",
31 | "@t3-oss/env-nextjs": "0.13.4",
32 | "@vercel/analytics": "1.5.0",
33 | "remark-gfm": "4.0.1"
34 | },
35 | "devDependencies": {
36 | "@biomejs/biome": "2.0.0-beta.5",
37 | "@next/env": "^15.3.2",
38 | "@trivago/prettier-plugin-sort-imports": "^5.2.2",
39 | "dotenv-cli": "^8.0.0",
40 | "husky": "9.1.7",
41 | "lint-staged": "16.0.0",
42 | "prettier": "^3.5.3",
43 | "prettier-plugin-tailwindcss": "^0.6.11",
44 | "turbo": "2.5.3"
45 | },
46 | "lint-staged": {
47 | "*.{js,jsx,ts,tsx,json,css,scss,md}": [
48 | "biome check --files-ignore-unknown=true"
49 | ],
50 | "!.github/*.md": []
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/packages/simstudio/README.md:
--------------------------------------------------------------------------------
1 | # Sim Studio CLI
2 |
3 | Sim Studio CLI allows you to run [Sim Studio](https://simstudio.ai) using Docker with a single command.
4 |
5 | ## Installation
6 |
7 | To install the Sim Studio CLI globally, use:
8 |
9 | ```bash
10 | npm install -g simstudio
11 | ```
12 |
13 | ## Usage
14 |
15 | To start Sim Studio, simply run:
16 |
17 | ```bash
18 | simstudio
19 | ```
20 |
21 | ### Options
22 |
23 | - `-p, --port `: Specify the port to run Sim Studio on (default: 3000).
24 | - `--no-pull`: Skip pulling the latest Docker images.
25 |
26 | ## Requirements
27 |
28 | - Docker must be installed and running on your machine.
29 |
30 | ## Contributing
31 |
32 | Contributions are welcome! Please open an issue or submit a pull request.
33 |
34 | ## License
35 |
36 | This project is licensed under the Apache-2.0 License.
--------------------------------------------------------------------------------
/packages/simstudio/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "simstudio",
3 | "version": "0.1.18",
4 | "description": "Sim Studio CLI - Run Sim Studio with a single command",
5 | "main": "dist/index.js",
6 | "bin": {
7 | "simstudio": "dist/index.js"
8 | },
9 | "scripts": {
10 | "build": "bun run build:tsc",
11 | "build:tsc": "tsc",
12 | "prepublishOnly": "bun run build"
13 | },
14 | "files": [
15 | "dist"
16 | ],
17 | "keywords": [
18 | "simstudio",
19 | "ai",
20 | "workflow",
21 | "ui",
22 | "cli",
23 | "sim",
24 | "sim-studio",
25 | "agent",
26 | "agents",
27 | "automation",
28 | "docker"
29 | ],
30 | "author": "Sim Studio",
31 | "license": "Apache-2.0",
32 | "dependencies": {
33 | "chalk": "^4.1.2",
34 | "commander": "^11.1.0",
35 | "dotenv": "^16.3.1",
36 | "inquirer": "^8.2.6",
37 | "listr2": "^6.6.1"
38 | },
39 | "devDependencies": {
40 | "@types/inquirer": "^8.2.6",
41 | "@types/node": "^20.5.1",
42 | "typescript": "^5.1.6"
43 | },
44 | "engines": {
45 | "node": ">=16"
46 | },
47 | "turbo": {
48 | "tasks": {
49 | "build": {
50 | "outputs": [
51 | "dist/**"
52 | ]
53 | }
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/packages/simstudio/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2020",
4 | "module": "ESNext",
5 | "moduleResolution": "node",
6 | "outDir": "./dist",
7 | "rootDir": "./src",
8 | "strict": true,
9 | "esModuleInterop": true,
10 | "skipLibCheck": true,
11 | "declaration": true,
12 | "forceConsistentCasingInFileNames": true
13 | },
14 | "include": ["src/**/*"],
15 | "exclude": ["node_modules", "dist"]
16 | }
17 |
--------------------------------------------------------------------------------
/scripts/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sim-doc-generator",
3 | "version": "1.0.0",
4 | "description": "Documentation generator for Sim Studio blocks",
5 | "type": "module",
6 | "private": true,
7 | "devDependencies": {
8 | "@types/node": "^22.15.17",
9 | "@types/react": "^19.1.3",
10 | "glob": "^11.0.2",
11 | "ts-node": "^10.9.2",
12 | "tsx": "^4.19.4",
13 | "typescript": "^5.8.3"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/scripts/setup-doc-generator.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Get the scripts directory path
4 | SCRIPTS_DIR=$(dirname "$0")
5 | cd "$SCRIPTS_DIR"
6 | echo "Working in scripts directory: $(pwd)"
7 |
8 | echo "Setting up documentation generator..."
9 |
10 | # Create package.json for scripts directory
11 | cat > package.json << EOF
12 | {
13 | "name": "sim-doc-generator",
14 | "version": "1.0.0",
15 | "description": "Documentation generator for Sim Studio blocks",
16 | "type": "module",
17 | "private": true
18 | }
19 | EOF
20 |
21 | # Install dependencies local to scripts directory
22 | bun install --save-dev typescript @types/node @types/react ts-node tsx glob
23 |
24 | # Setup tsconfig.json
25 | cat > tsconfig.json << EOF
26 | {
27 | "compilerOptions": {
28 | "target": "ES2020",
29 | "module": "NodeNext",
30 | "moduleResolution": "NodeNext",
31 | "esModuleInterop": true,
32 | "allowSyntheticDefaultImports": true,
33 | "strict": true,
34 | "skipLibCheck": true,
35 | "forceConsistentCasingInFileNames": true,
36 | "resolveJsonModule": true,
37 | "noEmit": true,
38 | "allowImportingTsExtensions": true
39 | },
40 | "ts-node": {
41 | "esm": true,
42 | "experimentalSpecifierResolution": "node"
43 | },
44 | "include": ["./**/*.ts"]
45 | }
46 | EOF
47 |
48 | echo "Dependencies installed successfully!"
49 | echo "You can now run './scripts/generate-docs.sh' to generate the documentation."
--------------------------------------------------------------------------------
/scripts/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2020",
4 | "module": "NodeNext",
5 | "moduleResolution": "NodeNext",
6 | "esModuleInterop": true,
7 | "allowSyntheticDefaultImports": true,
8 | "strict": true,
9 | "skipLibCheck": true,
10 | "forceConsistentCasingInFileNames": true,
11 | "resolveJsonModule": true,
12 | "noEmit": true,
13 | "allowImportingTsExtensions": true
14 | },
15 | "ts-node": {
16 | "esm": true,
17 | "experimentalSpecifierResolution": "node"
18 | },
19 | "include": ["./**/*.ts"]
20 | }
21 |
--------------------------------------------------------------------------------
/turbo.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://turbo.build/schema.json",
3 | "envMode": "loose",
4 | "tasks": {
5 | "build": {
6 | "dependsOn": ["^build"],
7 | "inputs": ["$TURBO_DEFAULT$", ".env*"],
8 | "outputs": [".next/**", "!.next/cache/**", "packages/simstudio/dist/**"]
9 | },
10 | "dev": {
11 | "persistent": true,
12 | "cache": false
13 | },
14 | "start": {
15 | "cache": false
16 | },
17 | "test": {
18 | "dependsOn": ["^build"],
19 | "outputs": []
20 | },
21 | "format": {
22 | "outputs": []
23 | },
24 | "format:check": {
25 | "outputs": []
26 | },
27 | "lint": {
28 | "outputs": []
29 | },
30 | "type-check": {
31 | "outputs": []
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------