Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
ae79372
feat(google-groups): added google groups (#2229)
aadamgough Dec 7, 2025
683b447
fix(google-drive): added support for shared drive (#2232)
aadamgough Dec 7, 2025
6e02a73
feat(i18n): update translations (#2233)
waleedlatif1 Dec 7, 2025
22c9384
improvement(code): removed dedicated code-optimized virtualized viewe…
waleedlatif1 Dec 7, 2025
e9d5304
fix(inactivity-notif): add cron to helm (#2235)
icecrasher321 Dec 7, 2025
92c03b8
improvement(salesforce): fixed refresh and added endpoints (#2177)
aadamgough Dec 7, 2025
9f884c1
feat(credits): prepurchase credits (#2174)
icecrasher321 Dec 7, 2025
05022e3
fix(copilot-autolayout): more subflow cases and deal with resizing (#…
icecrasher321 Dec 8, 2025
5b9f3d3
feat(docs): added additional self-hosting documentation (#2237)
waleedlatif1 Dec 8, 2025
b49b8ee
feat(i18n): update translations (#2238)
waleedlatif1 Dec 8, 2025
434d129
fix(autolayout): reduce horizontal spacing in autolayout (#2240)
icecrasher321 Dec 8, 2025
d09fd6c
fix(import): fixed trigger save on export/import flow (#2239)
waleedlatif1 Dec 8, 2025
e2b077f
fix(conditional): don't error in condition blocks when no conditions …
waleedlatif1 Dec 8, 2025
d200f66
feat(i18n): update translations (#2244)
waleedlatif1 Dec 8, 2025
01b2f80
feat(cursor): add cursor block and tools (#2245)
icecrasher321 Dec 8, 2025
598c3bc
feat(i18n): update translations (#2246)
waleedlatif1 Dec 8, 2025
feb5918
fix(docs): fix salesforce docs & update styling (#2248)
waleedlatif1 Dec 8, 2025
4fb039f
feat(i18n): update translations (#2249)
waleedlatif1 Dec 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,36 @@ Wait for the model to download, then visit [http://localhost:3000](http://localh
docker compose -f docker-compose.ollama.yml exec ollama ollama pull llama3.1:8b
```

#### Using an External Ollama Instance

If you already have Ollama running on your host machine (outside Docker), you need to configure the `OLLAMA_URL` to use `host.docker.internal` instead of `localhost`:

```bash
# Docker Desktop (macOS/Windows)
OLLAMA_URL=http://host.docker.internal:11434 docker compose -f docker-compose.prod.yml up -d

# Linux (add extra_hosts or use host IP)
docker compose -f docker-compose.prod.yml up -d # Then set OLLAMA_URL to your host's IP
```

**Why?** When running inside Docker, `localhost` refers to the container itself, not your host machine. `host.docker.internal` is a special DNS name that resolves to the host.

For Linux users, you can either:
- Use your host machine's actual IP address (e.g., `http://192.168.1.100:11434`)
- Add `extra_hosts: ["host.docker.internal:host-gateway"]` to the simstudio service in your compose file

#### Using vLLM

Sim also supports [vLLM](https://docs.vllm.ai/) for self-hosted models with OpenAI-compatible API:

```bash
# Set these environment variables
VLLM_BASE_URL=http://your-vllm-server:8000
VLLM_API_KEY=your_optional_api_key # Only if your vLLM instance requires auth
```

When running with Docker, use `host.docker.internal` if vLLM is on your host machine (same as Ollama above).

### Self-hosted: Dev Containers

1. Open VS Code with the [Remote - Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)
Expand Down Expand Up @@ -190,6 +220,46 @@ Copilot is a Sim-managed service. To use Copilot on a self-hosted instance:
- Go to https://sim.ai → Settings → Copilot and generate a Copilot API key
- Set `COPILOT_API_KEY` environment variable in your self-hosted apps/sim/.env file to that value

## Environment Variables

Key environment variables for self-hosted deployments (see `apps/sim/.env.example` for full list):

| Variable | Required | Description |
|----------|----------|-------------|
| `DATABASE_URL` | Yes | PostgreSQL connection string with pgvector |
| `BETTER_AUTH_SECRET` | Yes | Auth secret (`openssl rand -hex 32`) |
| `BETTER_AUTH_URL` | Yes | Your app URL (e.g., `http://localhost:3000`) |
| `NEXT_PUBLIC_APP_URL` | Yes | Public app URL (same as above) |
| `ENCRYPTION_KEY` | Yes | Encryption key (`openssl rand -hex 32`) |
| `OLLAMA_URL` | No | Ollama server URL (default: `http://localhost:11434`) |
| `VLLM_BASE_URL` | No | vLLM server URL for self-hosted models |
| `COPILOT_API_KEY` | No | API key from sim.ai for Copilot features |

## Troubleshooting

### Ollama models not showing in dropdown (Docker)

If you're running Ollama on your host machine and Sim in Docker, change `OLLAMA_URL` from `localhost` to `host.docker.internal`:

```bash
OLLAMA_URL=http://host.docker.internal:11434 docker compose -f docker-compose.prod.yml up -d
```

See [Using an External Ollama Instance](#using-an-external-ollama-instance) for details.

### Database connection issues

Ensure PostgreSQL has the pgvector extension installed. When using Docker, wait for the database to be healthy before running migrations.

### Port conflicts

If ports 3000, 3002, or 5432 are in use, configure alternatives:

```bash
# Custom ports
NEXT_PUBLIC_APP_URL=http://localhost:3100 POSTGRES_PORT=5433 docker compose up -d
```

## Tech Stack

- **Framework**: [Next.js](https://nextjs.org/) (App Router)
Expand Down
6 changes: 5 additions & 1 deletion apps/docs/app/[lang]/[[...slug]]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,11 @@ export default async function Page(props: { params: Promise<{ slug?: string[]; l
tableOfContent={{
style: 'clerk',
enabled: true,
header: <div className='mb-2 font-medium text-sm'>On this page</div>,
header: (
<div key='toc-header' className='mb-2 font-medium text-sm'>
On this page
</div>
),
footer: <TOCFooter />,
single: false,
}}
Expand Down
5 changes: 1 addition & 4 deletions apps/docs/app/[lang]/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,6 @@ export default async function Layout({ children, params }: LayoutProps) {
<Navbar />
<DocsLayout
tree={source.pageTree[lang]}
themeSwitch={{
enabled: false,
}}
nav={{
title: (
<Image
Expand All @@ -128,7 +125,7 @@ export default async function Layout({ children, params }: LayoutProps) {
},
}}
containerProps={{
className: '!pt-10',
className: '!pt-0',
}}
>
{children}
Expand Down
159 changes: 88 additions & 71 deletions apps/docs/app/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -96,54 +96,58 @@ aside#nd-sidebar {
border-right: none !important;
}

/* Responsive sidebar positioning */
/* Mobile: Fumadocs handles drawer */
@media (min-width: 768px) and (max-width: 1024px) {
aside[data-sidebar],
aside#nd-sidebar {
left: var(--sidebar-offset) !important;
}
/* Fumadocs v16: Add sidebar placeholder styling for grid area */
[data-sidebar-placeholder] {
background: transparent !important;
}

/* Desktop layout alignment */
@media (min-width: 1025px) {
[data-sidebar-container] {
margin-left: var(--sidebar-offset) !important;
/* Fumadocs v16: Hide sidebar panel (floating collapse button) */
[data-sidebar-panel] {
display: none !important;
}

/* Mobile only: Reduce gap between navbar and content */
@media (max-width: 1023px) {
#nd-docs-layout {
margin-top: -25px;
}
aside[data-sidebar],
aside#nd-sidebar {
left: var(--sidebar-offset) !important;
}

/* Desktop only: Apply custom navbar offset, sidebar width and margin offsets */
/* On mobile, let fumadocs handle the layout natively */
@media (min-width: 1024px) {
:root {
--fd-banner-height: 64px !important;
}
/* TOC positioning - target all possible selectors */
[data-toc],
aside[data-toc],
div[data-toc],
.fd-toc,
#nd-toc,
nav[data-toc],
aside:has([role="complementary"]) {
right: var(--toc-offset) !important;

#nd-docs-layout {
--fd-docs-height: calc(100dvh - 64px) !important;
--fd-sidebar-width: 300px !important;
margin-left: var(--sidebar-offset) !important;
margin-right: var(--toc-offset) !important;
}

/* Alternative TOC container targeting */
[data-docs-page] > aside:last-child,
main ~ aside {
right: var(--toc-offset) !important;
/* Hide fumadocs nav on desktop - we use custom navbar there */
#nd-docs-layout > header {
display: none !important;
}
}

/* Sidebar spacing - compact like turborepo */
[data-sidebar-viewport] {
padding: 0.5rem 20px 12px;
/* Fumadocs v16: [data-sidebar-viewport] doesn't exist, target #nd-sidebar > div instead */
[data-sidebar-viewport],
#nd-sidebar > div {
padding: 0.5rem 12px 12px;
background: transparent !important;
background-color: transparent !important;
}

/* Override sidebar item styling to match Raindrop */
/* Target Link and button elements in sidebar - override Fumadocs itemVariants */
/* Exclude the small chevron-only toggle buttons */
#nd-sidebar a,
#nd-sidebar button:not([aria-label*="ollapse"]):not([aria-label*="xpand"]) {
/* Using html prefix for higher specificity over Tailwind v4 utilities */
html #nd-sidebar a,
html #nd-sidebar button:not([aria-label*="ollapse"]):not([aria-label*="xpand"]) {
font-size: 0.9375rem !important; /* 15px to match Raindrop */
line-height: 1.4 !important;
padding: 0.5rem 0.75rem !important; /* More compact like Raindrop */
Expand All @@ -154,14 +158,14 @@ aside#nd-sidebar {
}

/* Dark mode sidebar text */
.dark #nd-sidebar a,
.dark #nd-sidebar button:not([aria-label*="ollapse"]):not([aria-label*="xpand"]) {
html.dark #nd-sidebar a,
html.dark #nd-sidebar button:not([aria-label*="ollapse"]):not([aria-label*="xpand"]) {
color: rgba(255, 255, 255, 0.6) !important;
}

/* Light mode sidebar text */
:root:not(.dark) #nd-sidebar a,
:root:not(.dark) #nd-sidebar button:not([aria-label*="ollapse"]):not([aria-label*="xpand"]) {
html:not(.dark) #nd-sidebar a,
html:not(.dark) #nd-sidebar button:not([aria-label*="ollapse"]):not([aria-label*="xpand"]) {
color: rgba(0, 0, 0, 0.6) !important;
}

Expand Down Expand Up @@ -194,7 +198,10 @@ aside#nd-sidebar {
}

/* Section headers should be slightly larger */
[data-sidebar-viewport] [data-separator] {
/* Fumadocs v16: Also target #nd-sidebar for compatibility */
[data-sidebar-viewport] [data-separator],
#nd-sidebar [data-separator],
#nd-sidebar p {
font-size: 0.75rem !important;
font-weight: 600 !important;
text-transform: uppercase !important;
Expand All @@ -218,61 +225,61 @@ aside#nd-sidebar {
}

/* Dark mode active state */
.dark #nd-sidebar a[data-active="true"],
.dark #nd-sidebar button[data-active="true"],
.dark #nd-sidebar a.bg-fd-primary\/10,
.dark #nd-sidebar a.text-fd-primary,
.dark #nd-sidebar a[class*="bg-fd-primary"],
.dark #nd-sidebar a[class*="text-fd-primary"],
.dark #nd-sidebar a.bg-purple-50\/80,
.dark #nd-sidebar a.text-purple-600,
.dark #nd-sidebar a[class*="bg-purple"],
.dark #nd-sidebar a[class*="text-purple"] {
html.dark #nd-sidebar a[data-active="true"],
html.dark #nd-sidebar button[data-active="true"],
html.dark #nd-sidebar a.bg-fd-primary\/10,
html.dark #nd-sidebar a.text-fd-primary,
html.dark #nd-sidebar a[class*="bg-fd-primary"],
html.dark #nd-sidebar a[class*="text-fd-primary"],
html.dark #nd-sidebar a.bg-purple-50\/80,
html.dark #nd-sidebar a.text-purple-600,
html.dark #nd-sidebar a[class*="bg-purple"],
html.dark #nd-sidebar a[class*="text-purple"] {
background-color: rgba(255, 255, 255, 0.15) !important;
color: rgba(255, 255, 255, 1) !important;
}

/* Light mode active state */
:root:not(.dark) #nd-sidebar a[data-active="true"],
:root:not(.dark) #nd-sidebar button[data-active="true"],
:root:not(.dark) #nd-sidebar a.bg-fd-primary\/10,
:root:not(.dark) #nd-sidebar a.text-fd-primary,
:root:not(.dark) #nd-sidebar a[class*="bg-fd-primary"],
:root:not(.dark) #nd-sidebar a[class*="text-fd-primary"],
:root:not(.dark) #nd-sidebar a.bg-purple-50\/80,
:root:not(.dark) #nd-sidebar a.text-purple-600,
:root:not(.dark) #nd-sidebar a[class*="bg-purple"],
:root:not(.dark) #nd-sidebar a[class*="text-purple"] {
html:not(.dark) #nd-sidebar a[data-active="true"],
html:not(.dark) #nd-sidebar button[data-active="true"],
html:not(.dark) #nd-sidebar a.bg-fd-primary\/10,
html:not(.dark) #nd-sidebar a.text-fd-primary,
html:not(.dark) #nd-sidebar a[class*="bg-fd-primary"],
html:not(.dark) #nd-sidebar a[class*="text-fd-primary"],
html:not(.dark) #nd-sidebar a.bg-purple-50\/80,
html:not(.dark) #nd-sidebar a.text-purple-600,
html:not(.dark) #nd-sidebar a[class*="bg-purple"],
html:not(.dark) #nd-sidebar a[class*="text-purple"] {
background-color: rgba(0, 0, 0, 0.07) !important;
color: rgba(0, 0, 0, 0.9) !important;
}

/* Dark mode hover state */
.dark #nd-sidebar a:hover:not([data-active="true"]),
.dark #nd-sidebar button:hover:not([data-active="true"]) {
html.dark #nd-sidebar a:hover:not([data-active="true"]),
html.dark #nd-sidebar button:hover:not([data-active="true"]) {
background-color: rgba(255, 255, 255, 0.08) !important;
}

/* Light mode hover state */
:root:not(.dark) #nd-sidebar a:hover:not([data-active="true"]),
:root:not(.dark) #nd-sidebar button:hover:not([data-active="true"]) {
html:not(.dark) #nd-sidebar a:hover:not([data-active="true"]),
html:not(.dark) #nd-sidebar button:hover:not([data-active="true"]) {
background-color: rgba(0, 0, 0, 0.03) !important;
}

/* Dark mode - ensure active/selected items don't change on hover */
.dark #nd-sidebar a.bg-purple-50\/80:hover,
.dark #nd-sidebar a[class*="bg-purple"]:hover,
.dark #nd-sidebar a[data-active="true"]:hover,
.dark #nd-sidebar button[data-active="true"]:hover {
html.dark #nd-sidebar a.bg-purple-50\/80:hover,
html.dark #nd-sidebar a[class*="bg-purple"]:hover,
html.dark #nd-sidebar a[data-active="true"]:hover,
html.dark #nd-sidebar button[data-active="true"]:hover {
background-color: rgba(255, 255, 255, 0.15) !important;
color: rgba(255, 255, 255, 1) !important;
}

/* Light mode - ensure active/selected items don't change on hover */
:root:not(.dark) #nd-sidebar a.bg-purple-50\/80:hover,
:root:not(.dark) #nd-sidebar a[class*="bg-purple"]:hover,
:root:not(.dark) #nd-sidebar a[data-active="true"]:hover,
:root:not(.dark) #nd-sidebar button[data-active="true"]:hover {
html:not(.dark) #nd-sidebar a.bg-purple-50\/80:hover,
html:not(.dark) #nd-sidebar a[class*="bg-purple"]:hover,
html:not(.dark) #nd-sidebar a[data-active="true"]:hover,
html:not(.dark) #nd-sidebar button[data-active="true"]:hover {
background-color: rgba(0, 0, 0, 0.07) !important;
color: rgba(0, 0, 0, 0.9) !important;
}
Expand Down Expand Up @@ -351,7 +358,16 @@ aside[data-sidebar] > *:not([data-sidebar-viewport]) {
[data-sidebar] [data-title],
#nd-sidebar > a:first-child,
#nd-sidebar > div:first-child > a:first-child,
#nd-sidebar img[alt="Sim"] {
#nd-sidebar img[alt="Sim"],
/* Hide theme toggle at bottom of sidebar on desktop */
#nd-sidebar
> footer,
#nd-sidebar footer,
aside#nd-sidebar > *:last-child:not(div),
#nd-sidebar > button:last-child,
#nd-sidebar button[aria-label*="theme" i],
#nd-sidebar button[aria-label*="Theme"],
#nd-sidebar > div:last-child > button {
display: none !important;
visibility: hidden !important;
height: 0 !important;
Expand Down Expand Up @@ -498,13 +514,14 @@ main article,
============================================ */

/* Main content area - center and constrain like turborepo/raindrop */
/* Note: --sidebar-offset and --toc-offset are now applied at #nd-docs-layout level */
main[data-main] {
max-width: var(--spacing-fd-container, 1400px);
margin-left: auto;
margin-right: auto;
padding-top: 1rem;
padding-left: calc(var(--sidebar-offset) + var(--content-gap));
padding-right: calc(var(--toc-offset) + var(--content-gap));
padding-left: var(--content-gap);
padding-right: var(--content-gap);
order: 1 !important;
}

Expand Down
Loading
Loading