Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
0acd860
fix(blog): use unoptimized tag for image assets (#2374)
waleedlatif1 Dec 15, 2025
6009a73
fix(vllm): remove requirement for api key for vllm (#2380)
waleedlatif1 Dec 15, 2025
e43afc8
fix(subscription): incomplete team subscription race condition (#2381)
icecrasher321 Dec 15, 2025
9762bbc
fix(wand): validate session before allowing access to wand generation…
waleedlatif1 Dec 15, 2025
8d38c2f
fix(wand): should not be able to use wand ui without write/admin perm…
icecrasher321 Dec 15, 2025
17b2e58
improvement(rce): updated rce to use isolate pkg for RCE (#2385)
waleedlatif1 Dec 15, 2025
3a5363a
feat(i18n): update translations (#2386)
waleedlatif1 Dec 15, 2025
a45bb1b
fix(rce): add 'isolate' to list of trusted deps, fixed custom tools e…
waleedlatif1 Dec 15, 2025
bdcc42e
fix(permissions): add client-side hints to prevent read-only users fr…
waleedlatif1 Dec 16, 2025
300aaa5
feat(slack): ability to have DM channels as destination for slack too…
icecrasher321 Dec 16, 2025
b72e111
fix(vm): use node child process for RCE (#2389)
waleedlatif1 Dec 16, 2025
57e6a0b
fixed jira output (#2392)
aadamgough Dec 16, 2025
a5b7148
fix(node): use node subprocess explicitly (#2391)
waleedlatif1 Dec 16, 2025
12d42e2
fix(docs): regen docs (#2393)
waleedlatif1 Dec 16, 2025
ab30d37
feat(i18n): update translations (#2395)
waleedlatif1 Dec 16, 2025
f0dc8e8
fix(build): downgrade nextjs from canary to 16.0.9 (#2394)
waleedlatif1 Dec 16, 2025
0e6a131
improvement: workflow loading, sidebar scrolling (#2322)
emir-karabeg Dec 16, 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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ When running with Docker, use `host.docker.internal` if vLLM is on your host mac

**Requirements:**
- [Bun](https://bun.sh/) runtime
- [Node.js](https://nodejs.org/) v20+ (required for sandboxed code execution)
- PostgreSQL 12+ with [pgvector extension](https://github.com/pgvector/pgvector) (required for AI embeddings)

**Note:** Sim uses vector embeddings for AI features like knowledge bases and semantic search, which requires the `pgvector` PostgreSQL extension.
Expand Down
65 changes: 40 additions & 25 deletions apps/docs/app/[lang]/[[...slug]]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type React from 'react'
import { findNeighbour } from 'fumadocs-core/page-tree'
import defaultMdxComponents from 'fumadocs-ui/mdx'
import { DocsBody, DocsDescription, DocsPage, DocsTitle } from 'fumadocs-ui/page'
Expand All @@ -10,14 +11,15 @@ import { LLMCopyButton } from '@/components/page-actions'
import { StructuredData } from '@/components/structured-data'
import { CodeBlock } from '@/components/ui/code-block'
import { Heading } from '@/components/ui/heading'
import { source } from '@/lib/source'
import { type PageData, source } from '@/lib/source'

export default async function Page(props: { params: Promise<{ slug?: string[]; lang: string }> }) {
const params = await props.params
const page = source.getPage(params.slug, params.lang)
if (!page) notFound()

const MDX = page.data.body
const data = page.data as PageData
const MDX = data.body
const baseUrl = 'https://docs.sim.ai'

const pageTreeRecord = source.pageTree as Record<string, any>
Expand Down Expand Up @@ -51,7 +53,7 @@ export default async function Page(props: { params: Promise<{ slug?: string[]; l

if (index === urlParts.length - 1) {
breadcrumbs.push({
name: page.data.title,
name: data.title,
url: `${baseUrl}${page.url}`,
})
} else {
Expand Down Expand Up @@ -168,15 +170,15 @@ export default async function Page(props: { params: Promise<{ slug?: string[]; l
return (
<>
<StructuredData
title={page.data.title}
description={page.data.description || ''}
title={data.title}
description={data.description || ''}
url={`${baseUrl}${page.url}`}
lang={params.lang}
breadcrumb={breadcrumbs}
/>
<DocsPage
toc={page.data.toc}
full={page.data.full}
toc={data.toc}
full={data.full}
breadcrumb={{
enabled: false,
}}
Expand Down Expand Up @@ -207,20 +209,32 @@ export default async function Page(props: { params: Promise<{ slug?: string[]; l
</div>
<PageNavigationArrows previous={neighbours?.previous} next={neighbours?.next} />
</div>
<DocsTitle>{page.data.title}</DocsTitle>
<DocsDescription>{page.data.description}</DocsDescription>
<DocsTitle>{data.title}</DocsTitle>
<DocsDescription>{data.description}</DocsDescription>
</div>
<DocsBody>
<MDX
components={{
...defaultMdxComponents,
CodeBlock,
h1: (props) => <Heading as='h1' {...props} />,
h2: (props) => <Heading as='h2' {...props} />,
h3: (props) => <Heading as='h3' {...props} />,
h4: (props) => <Heading as='h4' {...props} />,
h5: (props) => <Heading as='h5' {...props} />,
h6: (props) => <Heading as='h6' {...props} />,
h1: (props: React.HTMLAttributes<HTMLHeadingElement>) => (
<Heading as='h1' {...props} />
),
h2: (props: React.HTMLAttributes<HTMLHeadingElement>) => (
<Heading as='h2' {...props} />
),
h3: (props: React.HTMLAttributes<HTMLHeadingElement>) => (
<Heading as='h3' {...props} />
),
h4: (props: React.HTMLAttributes<HTMLHeadingElement>) => (
<Heading as='h4' {...props} />
),
h5: (props: React.HTMLAttributes<HTMLHeadingElement>) => (
<Heading as='h5' {...props} />
),
h6: (props: React.HTMLAttributes<HTMLHeadingElement>) => (
<Heading as='h6' {...props} />
),
}}
/>
</DocsBody>
Expand All @@ -240,16 +254,17 @@ export async function generateMetadata(props: {
const page = source.getPage(params.slug, params.lang)
if (!page) notFound()

const data = page.data as PageData
const baseUrl = 'https://docs.sim.ai'
const fullUrl = `${baseUrl}${page.url}`

const description = page.data.description || ''
const ogImageUrl = `${baseUrl}/api/og?title=${encodeURIComponent(page.data.title)}&category=DOCUMENTATION${description ? `&description=${encodeURIComponent(description)}` : ''}`
const description = data.description || ''
const ogImageUrl = `${baseUrl}/api/og?title=${encodeURIComponent(data.title)}&category=DOCUMENTATION${description ? `&description=${encodeURIComponent(description)}` : ''}`

return {
title: page.data.title,
title: data.title,
description:
page.data.description || 'Sim visual workflow builder for AI applications documentation',
data.description || 'Sim visual workflow builder for AI applications documentation',
keywords: [
'AI workflow builder',
'visual workflow editor',
Expand All @@ -258,16 +273,16 @@ export async function generateMetadata(props: {
'AI agents',
'no-code AI',
'drag and drop workflows',
page.data.title?.toLowerCase().split(' '),
data.title?.toLowerCase().split(' '),
]
.flat()
.filter(Boolean),
authors: [{ name: 'Sim Team' }],
category: 'Developer Tools',
openGraph: {
title: page.data.title,
title: data.title,
description:
page.data.description || 'Sim visual workflow builder for AI applications documentation',
data.description || 'Sim visual workflow builder for AI applications documentation',
url: fullUrl,
siteName: 'Sim Documentation',
type: 'article',
Expand All @@ -280,15 +295,15 @@ export async function generateMetadata(props: {
url: ogImageUrl,
width: 1200,
height: 630,
alt: page.data.title,
alt: data.title,
},
],
},
twitter: {
card: 'summary_large_image',
title: page.data.title,
title: data.title,
description:
page.data.description || 'Sim visual workflow builder for AI applications documentation',
data.description || 'Sim visual workflow builder for AI applications documentation',
images: [ogImageUrl],
creator: '@simdotai',
site: '@simdotai',
Expand Down
38 changes: 25 additions & 13 deletions apps/docs/app/api/og/route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ export async function GET(request: NextRequest) {
const description = searchParams.get('description') || ''

const baseUrl = new URL(request.url).origin
const backgroundImageUrl = `${baseUrl}/static/og-background.png`

const allText = `${title}${category}${description}docs.sim.ai`
const fontData = await loadGoogleFont('Geist', '400;500;600', allText)
Expand All @@ -55,36 +54,49 @@ export async function GET(request: NextRequest) {
width: '100%',
display: 'flex',
flexDirection: 'column',
background: 'linear-gradient(315deg, #1e1e3f 0%, #1a1a2e 40%, #0f0f0f 100%)',
background: '#0c0c0c',
position: 'relative',
fontFamily: 'Geist',
}}
>
{/* Background texture */}
<img
src={backgroundImageUrl}
alt=''
{/* Base gradient layer - very subtle purple tint across the entire image */}
<div
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
background:
'radial-gradient(ellipse 150% 100% at 50% 100%, rgba(88, 28, 135, 0.15) 0%, rgba(88, 28, 135, 0.08) 25%, rgba(88, 28, 135, 0.03) 50%, transparent 80%)',
display: 'flex',
}}
/>

{/* Secondary glow - adds depth without harsh edges */}
<div
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
objectFit: 'cover',
opacity: 0.04,
background:
'radial-gradient(ellipse 100% 80% at 80% 90%, rgba(112, 31, 252, 0.12) 0%, rgba(112, 31, 252, 0.04) 40%, transparent 70%)',
display: 'flex',
}}
/>

{/* Subtle purple glow from bottom right */}
{/* Top darkening - creates natural vignette */}
<div
style={{
position: 'absolute',
bottom: 0,
right: 0,
width: '50%',
top: 0,
left: 0,
width: '100%',
height: '100%',
background:
'radial-gradient(ellipse at bottom right, rgba(112, 31, 252, 0.1) 0%, transparent 50%)',
'linear-gradient(180deg, rgba(0, 0, 0, 0.3) 0%, transparent 40%, transparent 100%)',
display: 'flex',
}}
/>
Expand Down
Loading
Loading