Skip to content

Commit e4ddeb0

Browse files
v0.4.18: file upload tools, copilot upgrade, docs changes, model filtering
2 parents da091df + 063bd61 commit e4ddeb0

File tree

277 files changed

+20581
-3019
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

277 files changed

+20581
-3019
lines changed

.github/workflows/test-build.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ jobs:
2626
- name: Install dependencies
2727
run: bun install --frozen-lockfile
2828

29+
- name: Lint code
30+
run: bun run lint:check
31+
2932
- name: Run tests with coverage
3033
env:
3134
NODE_OPTIONS: '--no-warnings'

apps/docs/app/[lang]/[[...slug]]/page.tsx

Lines changed: 147 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { ChevronLeft, ChevronRight } from 'lucide-react'
55
import Link from 'next/link'
66
import { notFound } from 'next/navigation'
77
import { StructuredData } from '@/components/structured-data'
8+
import { CodeBlock } from '@/components/ui/code-block'
89
import { source } from '@/lib/source'
910

1011
export const dynamic = 'force-dynamic'
@@ -22,31 +23,143 @@ export default async function Page(props: { params: Promise<{ slug?: string[]; l
2223
pageTreeRecord[params.lang] ?? pageTreeRecord.en ?? Object.values(pageTreeRecord)[0]
2324
const neighbours = pageTree ? findNeighbour(pageTree, page.url) : null
2425

26+
const generateBreadcrumbs = () => {
27+
const breadcrumbs: Array<{ name: string; url: string }> = [
28+
{
29+
name: 'Home',
30+
url: baseUrl,
31+
},
32+
]
33+
34+
const urlParts = page.url.split('/').filter(Boolean)
35+
let currentPath = ''
36+
37+
urlParts.forEach((part, index) => {
38+
if (index === 0 && ['en', 'es', 'fr', 'de', 'ja', 'zh'].includes(part)) {
39+
currentPath = `/${part}`
40+
return
41+
}
42+
43+
currentPath += `/${part}`
44+
45+
const name = part
46+
.split('-')
47+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
48+
.join(' ')
49+
50+
if (index === urlParts.length - 1) {
51+
breadcrumbs.push({
52+
name: page.data.title,
53+
url: `${baseUrl}${page.url}`,
54+
})
55+
} else {
56+
breadcrumbs.push({
57+
name: name,
58+
url: `${baseUrl}${currentPath}`,
59+
})
60+
}
61+
})
62+
63+
return breadcrumbs
64+
}
65+
66+
const breadcrumbs = generateBreadcrumbs()
67+
2568
const CustomFooter = () => (
26-
<div className='mt-12 flex items-center justify-between border-border border-t py-8'>
27-
{neighbours?.previous ? (
69+
<div className='mt-12'>
70+
{/* Navigation links */}
71+
<div className='flex items-center justify-between py-8'>
72+
{neighbours?.previous ? (
73+
<Link
74+
href={neighbours.previous.url}
75+
className='group flex items-center gap-2 text-muted-foreground transition-colors hover:text-foreground'
76+
>
77+
<ChevronLeft className='group-hover:-translate-x-1 h-4 w-4 transition-transform' />
78+
<span className='font-medium'>{neighbours.previous.name}</span>
79+
</Link>
80+
) : (
81+
<div />
82+
)}
83+
84+
{neighbours?.next ? (
85+
<Link
86+
href={neighbours.next.url}
87+
className='group flex items-center gap-2 text-muted-foreground transition-colors hover:text-foreground'
88+
>
89+
<span className='font-medium'>{neighbours.next.name}</span>
90+
<ChevronRight className='h-4 w-4 transition-transform group-hover:translate-x-1' />
91+
</Link>
92+
) : (
93+
<div />
94+
)}
95+
</div>
96+
97+
{/* Divider line */}
98+
<div className='border-border border-t' />
99+
100+
{/* Social icons */}
101+
<div className='flex items-center gap-4 py-6'>
28102
<Link
29-
href={neighbours.previous.url}
30-
className='group flex items-center gap-2 text-muted-foreground transition-colors hover:text-foreground'
103+
href='https://x.com/simdotai'
104+
target='_blank'
105+
rel='noopener noreferrer'
106+
aria-label='X (Twitter)'
31107
>
32-
<ChevronLeft className='group-hover:-translate-x-1 h-4 w-4 transition-transform' />
33-
<span className='font-medium'>{neighbours.previous.name}</span>
108+
<div
109+
className='h-5 w-5 bg-gray-400 transition-colors hover:bg-gray-500 dark:bg-gray-500 dark:hover:bg-gray-400'
110+
style={{
111+
maskImage:
112+
"url('data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Cpath d=%22M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z%22/%3E%3C/svg%3E')",
113+
maskRepeat: 'no-repeat',
114+
maskPosition: 'center center',
115+
WebkitMaskImage:
116+
"url('data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Cpath d=%22M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z%22/%3E%3C/svg%3E')",
117+
WebkitMaskRepeat: 'no-repeat',
118+
WebkitMaskPosition: 'center center',
119+
}}
120+
/>
121+
</Link>
122+
<Link
123+
href='https://github.com/simstudioai/sim'
124+
target='_blank'
125+
rel='noopener noreferrer'
126+
aria-label='GitHub'
127+
>
128+
<div
129+
className='h-5 w-5 bg-gray-400 transition-colors hover:bg-gray-500 dark:bg-gray-500 dark:hover:bg-gray-400'
130+
style={{
131+
maskImage:
132+
"url('data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Cpath d=%22M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z%22/%3E%3C/svg%3E')",
133+
maskRepeat: 'no-repeat',
134+
maskPosition: 'center center',
135+
WebkitMaskImage:
136+
"url('data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Cpath d=%22M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z%22/%3E%3C/svg%3E')",
137+
WebkitMaskRepeat: 'no-repeat',
138+
WebkitMaskPosition: 'center center',
139+
}}
140+
/>
34141
</Link>
35-
) : (
36-
<div />
37-
)}
38-
39-
{neighbours?.next ? (
40142
<Link
41-
href={neighbours.next.url}
42-
className='group flex items-center gap-2 text-muted-foreground transition-colors hover:text-foreground'
143+
href='https://discord.gg/Hr4UWYEcTT'
144+
target='_blank'
145+
rel='noopener noreferrer'
146+
aria-label='Discord'
43147
>
44-
<span className='font-medium'>{neighbours.next.name}</span>
45-
<ChevronRight className='h-4 w-4 transition-transform group-hover:translate-x-1' />
148+
<div
149+
className='h-5 w-5 bg-gray-400 transition-colors hover:bg-gray-500 dark:bg-gray-500 dark:hover:bg-gray-400'
150+
style={{
151+
maskImage:
152+
"url('data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Cpath d=%22M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515a.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0a12.64 12.64 0 0 0-.617-1.25a.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057a19.9 19.9 0 0 0 5.993 3.03a.078.078 0 0 0 .084-.028a14.09 14.09 0 0 0 1.226-1.994a.076.076 0 0 0-.041-.106a13.107 13.107 0 0 1-1.872-.892a.077.077 0 0 1-.008-.128a10.2 10.2 0 0 0 .372-.292a.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127a12.299 12.299 0 0 1-1.873.892a.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028a19.839 19.839 0 0 0 6.002-3.03a.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419c0-1.333.956-2.419 2.157-2.419c1.21 0 2.176 1.096 2.157 2.42c0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419c0-1.333.955-2.419 2.157-2.419c1.21 0 2.176 1.096 2.157 2.42c0 1.333-.946 2.418-2.157 2.418z%22/%3E%3C/svg%3E')",
153+
maskRepeat: 'no-repeat',
154+
maskPosition: 'center center',
155+
WebkitMaskImage:
156+
"url('data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Cpath d=%22M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515a.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0a12.64 12.64 0 0 0-.617-1.25a.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057a19.9 19.9 0 0 0 5.993 3.03a.078.078 0 0 0 .084-.028a14.09 14.09 0 0 0 1.226-1.994a.076.076 0 0 0-.041-.106a13.107 13.107 0 0 1-1.872-.892a.077.077 0 0 1-.008-.128a10.2 10.2 0 0 0 .372-.292a.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127a12.299 12.299 0 0 1-1.873.892a.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028a19.839 19.839 0 0 0 6.002-3.03a.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419c0-1.333.956-2.419 2.157-2.419c1.21 0 2.176 1.096 2.157 2.42c0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419c0-1.333.955-2.419 2.157-2.419c1.21 0 2.176 1.096 2.157 2.42c0 1.333-.946 2.418-2.157 2.418z%22/%3E%3C/svg%3E')",
157+
WebkitMaskRepeat: 'no-repeat',
158+
WebkitMaskPosition: 'center center',
159+
}}
160+
/>
46161
</Link>
47-
) : (
48-
<div />
49-
)}
162+
</div>
50163
</div>
51164
)
52165

@@ -57,6 +170,7 @@ export default async function Page(props: { params: Promise<{ slug?: string[]; l
57170
description={page.data.description || ''}
58171
url={`${baseUrl}${page.url}`}
59172
lang={params.lang}
173+
breadcrumb={breadcrumbs}
60174
/>
61175
<DocsPage
62176
toc={page.data.toc}
@@ -82,7 +196,12 @@ export default async function Page(props: { params: Promise<{ slug?: string[]; l
82196
<DocsTitle>{page.data.title}</DocsTitle>
83197
<DocsDescription>{page.data.description}</DocsDescription>
84198
<DocsBody>
85-
<MDX components={defaultMdxComponents} />
199+
<MDX
200+
components={{
201+
...defaultMdxComponents,
202+
CodeBlock,
203+
}}
204+
/>
86205
</DocsBody>
87206
</DocsPage>
88207
</>
@@ -128,8 +247,10 @@ export async function generateMetadata(props: {
128247
url: fullUrl,
129248
siteName: 'Sim Documentation',
130249
type: 'article',
131-
locale: params.lang,
132-
alternateLocale: ['en', 'fr', 'zh'].filter((lang) => lang !== params.lang),
250+
locale: params.lang === 'en' ? 'en_US' : `${params.lang}_${params.lang.toUpperCase()}`,
251+
alternateLocale: ['en', 'es', 'fr', 'de', 'ja', 'zh']
252+
.filter((lang) => lang !== params.lang)
253+
.map((lang) => (lang === 'en' ? 'en_US' : `${lang}_${lang.toUpperCase()}`)),
133254
},
134255
twitter: {
135256
card: 'summary',
@@ -152,8 +273,12 @@ export async function generateMetadata(props: {
152273
alternates: {
153274
canonical: fullUrl,
154275
languages: {
155-
en: `${baseUrl}/en${page.url.replace(`/${params.lang}`, '')}`,
276+
'x-default': `${baseUrl}${page.url.replace(`/${params.lang}`, '')}`,
277+
en: `${baseUrl}${page.url.replace(`/${params.lang}`, '')}`,
278+
es: `${baseUrl}/es${page.url.replace(`/${params.lang}`, '')}`,
156279
fr: `${baseUrl}/fr${page.url.replace(`/${params.lang}`, '')}`,
280+
de: `${baseUrl}/de${page.url.replace(`/${params.lang}`, '')}`,
281+
ja: `${baseUrl}/ja${page.url.replace(`/${params.lang}`, '')}`,
157282
zh: `${baseUrl}/zh${page.url.replace(`/${params.lang}`, '')}`,
158283
},
159284
},

apps/docs/app/[lang]/layout.tsx

Lines changed: 79 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,27 @@ import type { ReactNode } from 'react'
22
import { defineI18nUI } from 'fumadocs-ui/i18n'
33
import { DocsLayout } from 'fumadocs-ui/layouts/docs'
44
import { RootProvider } from 'fumadocs-ui/provider/next'
5-
import { ExternalLink, GithubIcon } from 'lucide-react'
6-
import { Inter } from 'next/font/google'
5+
import { Geist_Mono, Inter } from 'next/font/google'
76
import Image from 'next/image'
8-
import Link from 'next/link'
9-
import { LanguageDropdown } from '@/components/ui/language-dropdown'
7+
import {
8+
SidebarFolder,
9+
SidebarItem,
10+
SidebarSeparator,
11+
} from '@/components/docs-layout/sidebar-components'
12+
import { Navbar } from '@/components/navbar/navbar'
1013
import { i18n } from '@/lib/i18n'
1114
import { source } from '@/lib/source'
1215
import '../global.css'
1316
import { Analytics } from '@vercel/analytics/next'
1417

1518
const inter = Inter({
1619
subsets: ['latin'],
20+
variable: '--font-geist-sans',
21+
})
22+
23+
const geistMono = Geist_Mono({
24+
subsets: ['latin'],
25+
variable: '--font-geist-mono',
1726
})
1827

1928
const { provider } = defineI18nUI(i18n, {
@@ -27,25 +36,18 @@ const { provider } = defineI18nUI(i18n, {
2736
fr: {
2837
displayName: 'Français',
2938
},
39+
de: {
40+
displayName: 'Deutsch',
41+
},
42+
ja: {
43+
displayName: '日本語',
44+
},
3045
zh: {
3146
displayName: '简体中文',
3247
},
3348
},
3449
})
3550

36-
const GitHubLink = () => (
37-
<div className='fixed right-4 bottom-4 z-50'>
38-
<Link
39-
href='https://github.com/simstudioai/sim'
40-
target='_blank'
41-
rel='noopener noreferrer'
42-
className='flex h-8 w-8 items-center justify-center rounded-full border border-border bg-background transition-colors hover:bg-muted'
43-
>
44-
<GithubIcon className='h-4 w-4' />
45-
</Link>
46-
</div>
47-
)
48-
4951
type LayoutProps = {
5052
children: ReactNode
5153
params: Promise<{ lang: string }>
@@ -54,43 +56,82 @@ type LayoutProps = {
5456
export default async function Layout({ children, params }: LayoutProps) {
5557
const { lang } = await params
5658

59+
const structuredData = {
60+
'@context': 'https://schema.org',
61+
'@type': 'WebSite',
62+
name: 'Sim Documentation',
63+
description:
64+
'Comprehensive documentation for Sim - the visual workflow builder for AI Agent Workflows.',
65+
url: 'https://docs.sim.ai',
66+
publisher: {
67+
'@type': 'Organization',
68+
name: 'Sim',
69+
url: 'https://sim.ai',
70+
logo: {
71+
'@type': 'ImageObject',
72+
url: 'https://docs.sim.ai/static/logo.png',
73+
},
74+
},
75+
inLanguage: lang,
76+
potentialAction: {
77+
'@type': 'SearchAction',
78+
target: {
79+
'@type': 'EntryPoint',
80+
urlTemplate: 'https://docs.sim.ai/api/search?q={search_term_string}',
81+
},
82+
'query-input': 'required name=search_term_string',
83+
},
84+
}
85+
5786
return (
58-
<html lang={lang} className={inter.className} suppressHydrationWarning>
59-
<body className='flex min-h-screen flex-col'>
87+
<html
88+
lang={lang}
89+
className={`${inter.variable} ${geistMono.variable}`}
90+
suppressHydrationWarning
91+
>
92+
<head>
93+
<script
94+
type='application/ld+json'
95+
dangerouslySetInnerHTML={{ __html: JSON.stringify(structuredData) }}
96+
/>
97+
</head>
98+
<body className='flex min-h-screen flex-col font-sans'>
6099
<RootProvider i18n={provider(lang)}>
100+
<Navbar />
61101
<DocsLayout
62102
tree={source.pageTree[lang]}
103+
themeSwitch={{
104+
enabled: false,
105+
}}
63106
nav={{
64107
title: (
65-
<div className='flex items-center gap-3'>
66-
<Image
67-
src='/static/logo.png'
68-
alt='Sim'
69-
width={60}
70-
height={24}
71-
className='h-6 w-auto'
72-
/>
73-
<LanguageDropdown />
74-
</div>
108+
<Image
109+
src='/static/logo.png'
110+
alt='Sim'
111+
width={72}
112+
height={28}
113+
className='h-7 w-auto'
114+
priority
115+
/>
75116
),
76117
}}
77-
links={[
78-
{
79-
text: 'Visit Sim',
80-
url: 'https://sim.ai',
81-
icon: <ExternalLink className='h-4 w-4' />,
82-
},
83-
]}
84118
sidebar={{
85119
defaultOpenLevel: 0,
86-
collapsible: true,
120+
collapsible: false,
87121
footer: null,
88122
banner: null,
123+
components: {
124+
Item: SidebarItem,
125+
Folder: SidebarFolder,
126+
Separator: SidebarSeparator,
127+
},
128+
}}
129+
containerProps={{
130+
className: '!pt-10',
89131
}}
90132
>
91133
{children}
92134
</DocsLayout>
93-
<GitHubLink />
94135
<Analytics />
95136
</RootProvider>
96137
</body>

0 commit comments

Comments
 (0)