Skip to content

Commit 5f847d9

Browse files
Copilothotlong
andcommitted
Restore apps/site directory - keep for documentation site
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
1 parent ea21304 commit 5f847d9

Some content is hidden

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

52 files changed

+12127
-194
lines changed

.github/workflows/check-links.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ on:
66
- main
77
paths:
88
- '**/*.md'
9+
- 'apps/site/content/**/*.mdx'
910
pull_request:
1011
paths:
1112
- '**/*.md'
13+
- 'apps/site/content/**/*.mdx'
1214
schedule:
1315
# Run weekly on Sundays at 00:00 UTC
1416
- cron: '0 0 * * 0'
@@ -23,7 +25,7 @@ jobs:
2325
- name: Check links in Markdown files
2426
uses: lycheeverse/lychee-action@v2
2527
with:
26-
args: --verbose --no-progress '**/*.md'
28+
args: --verbose --no-progress '**/*.md' 'apps/site/content/**/*.mdx'
2729
fail: true
2830
env:
2931
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

CONTRIBUTING.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@ objectos/
1919
│ ├── kernel/ # @objectos/kernel - Core runtime engine
2020
│ ├── server/ # @objectos/server - NestJS HTTP server
2121
│ └── presets/ # @objectos/preset-* - Standard metadata
22+
├── apps/
23+
│ └── site/ # @objectos/site - Documentation site
2224
├── examples/ # Example applications
2325
└── docs/ # VitePress documentation
2426
```
2527

26-
**Note**: The UI package (`@objectos/ui`) and applications (`apps/web`, `apps/site`) have been moved to separate repositories and are developed independently.
28+
**Note**: The UI package (`@objectos/ui`) has been moved to a separate repository and is developed independently.
2729

2830
### Package Responsibilities
2931

apps/site/.gitignore

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# dependencies
2+
/node_modules
3+
/.pnp
4+
.pnp.js
5+
6+
# testing
7+
/coverage
8+
9+
# next.js
10+
/.next/
11+
/out/
12+
13+
# production
14+
/build
15+
16+
# misc
17+
.DS_Store
18+
*.pem
19+
20+
# debug
21+
npm-debug.log*
22+
yarn-debug.log*
23+
yarn-error.log*
24+
25+
# local env files
26+
.env*.local
27+
.env
28+
29+
# vercel
30+
.vercel
31+
32+
# typescript
33+
*.tsbuildinfo
34+
next-env.d.ts
35+
36+
# fumadocs
37+
.source

apps/site/app/blog/[slug]/page.tsx

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { blog } from '@/lib/source';
2+
import { notFound } from 'next/navigation';
3+
import { DocsBody } from 'fumadocs-ui/layouts/docs/page';
4+
import Link from 'next/link';
5+
import { ArrowLeft } from 'lucide-react';
6+
7+
export default async function BlogPostPage({
8+
params,
9+
}: {
10+
params: Promise<{ slug: string }>;
11+
}) {
12+
const { slug } = await params;
13+
const post = blog.find((post) => post.slug === slug);
14+
15+
if (!post) notFound();
16+
17+
// Handle MDX content retrieval safely
18+
const MDX = (post as any).body;
19+
20+
return (
21+
<main className="container max-w-3xl mx-auto py-12 px-4">
22+
<Link
23+
href="/blog"
24+
className="inline-flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground mb-8 transition-colors"
25+
>
26+
<ArrowLeft className="w-4 h-4" />
27+
Back to Blog
28+
</Link>
29+
30+
<article>
31+
<header className="mb-8 space-y-4">
32+
<h1 className="text-4xl font-bold tracking-tight">{(post as any).title}</h1>
33+
<div className="flex items-center gap-4 text-sm text-muted-foreground">
34+
{(post as any).date && (
35+
<time dateTime={new Date((post as any).date).toISOString()}>
36+
{new Date((post as any).date).toLocaleDateString('en-US', {
37+
year: 'numeric',
38+
month: 'long',
39+
day: 'numeric',
40+
})}
41+
</time>
42+
)}
43+
{(post as any).author && <span>• By {(post as any).author}</span>}
44+
</div>
45+
</header>
46+
47+
<DocsBody className="text-foreground">
48+
{MDX ? <MDX /> : <p>No content found</p>}
49+
</DocsBody>
50+
</article>
51+
</main>
52+
);
53+
}
54+
55+
export function generateStaticParams() {
56+
return blog.map((post) => ({
57+
slug: post.slug,
58+
}));
59+
}

apps/site/app/blog/layout.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { HomeLayout } from 'fumadocs-ui/layouts/home';
2+
import { baseOptions } from '../layout.config';
3+
import type { ReactNode } from 'react';
4+
5+
export default function BlogLayout({ children }: { children: ReactNode }) {
6+
return (
7+
<HomeLayout {...baseOptions}>
8+
{children}
9+
</HomeLayout>
10+
);
11+
}

apps/site/app/blog/page.tsx

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import Link from 'next/link';
2+
import { blog } from '@/lib/source';
3+
4+
export default function BlogIndex() {
5+
const posts = [...blog].sort((a, b) => {
6+
const dateA = (a as any).date;
7+
const dateB = (b as any).date;
8+
if (!dateA || !dateB) return 0;
9+
return new Date(dateB).getTime() - new Date(dateA).getTime();
10+
});
11+
12+
return (
13+
<main className="container max-w-4xl mx-auto py-12 px-4">
14+
<div className="flex flex-col gap-8">
15+
<div className="space-y-4">
16+
<h1 className="text-4xl font-bold tracking-tight">Blog</h1>
17+
<p className="text-muted-foreground text-lg">
18+
Latest updates and insights from the ObjectOS team.
19+
</p>
20+
</div>
21+
22+
<div className="grid gap-8">
23+
{posts.map((post) => (
24+
<Link
25+
key={post.url}
26+
href={post.url}
27+
className="flex flex-col gap-2 p-6 rounded-xl border border-border hover:bg-muted/50 transition-colors"
28+
>
29+
<h2 className="text-2xl font-bold">{(post as any).title}</h2>
30+
{(post as any).description && (
31+
<p className="text-muted-foreground">{(post as any).description}</p>
32+
)}
33+
<div className="flex items-center gap-4 text-sm text-muted-foreground mt-2">
34+
{(post as any).date && (
35+
timeElement((post as any).date)
36+
)}
37+
{(post as any).author && <span>By {(post as any).author}</span>}
38+
</div>
39+
</Link>
40+
))}
41+
</div>
42+
</div>
43+
</main>
44+
);
45+
}
46+
47+
function timeElement(date: string | Date) {
48+
const d = new Date(date);
49+
return (
50+
<time dateTime={d.toISOString()}>
51+
{d.toLocaleDateString('en-US', {
52+
year: 'numeric',
53+
month: 'long',
54+
day: 'numeric',
55+
})}
56+
</time>
57+
)
58+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { source } from '@/lib/source';
2+
import { DocsBody, DocsPage } from 'fumadocs-ui/layouts/docs/page';
3+
import { notFound } from 'next/navigation';
4+
import type { Metadata } from 'next';
5+
6+
export default async function Page(props: {
7+
params: Promise<{ slug?: string[] }>;
8+
}) {
9+
const params = await props.params;
10+
const page = source.getPage(params.slug);
11+
12+
if (!page) notFound();
13+
14+
const MDX = (page.data as any)._exports?.default || (page.data as any).exports?.default;
15+
const githubPath = params.slug
16+
? `apps/site/content/docs/${params.slug.join('/')}.mdx`
17+
: 'apps/site/content/docs/index.mdx';
18+
19+
return (
20+
<DocsPage
21+
toc={(page.data as any).toc ?? []}
22+
full={false}
23+
footer={{
24+
children: (
25+
<a
26+
href={`https://github.com/objectstack-ai/objectos/blob/main/${githubPath}`}
27+
target="_blank"
28+
rel="noreferrer noopener"
29+
className="inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground transition-colors"
30+
>
31+
<svg className="size-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
32+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" />
33+
</svg>
34+
Edit this page on GitHub
35+
</a>
36+
),
37+
}}
38+
>
39+
<DocsBody>
40+
<h1>{page.data.title}</h1>
41+
{MDX && <MDX />}
42+
</DocsBody>
43+
</DocsPage>
44+
);
45+
}
46+
47+
export function generateStaticParams() {
48+
return source.generateParams();
49+
}
50+
51+
export async function generateMetadata(props: {
52+
params: Promise<{ slug?: string[] }>;
53+
}): Promise<Metadata> {
54+
const params = await props.params;
55+
const page = source.getPage(params.slug);
56+
57+
if (!page) notFound();
58+
59+
return {
60+
title: page.data.title,
61+
description: page.data.description ?? '',
62+
};
63+
}

apps/site/app/docs/layout.tsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { docs } from '../../.source/server';
2+
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
3+
import type { ReactNode } from 'react';
4+
import { pageTree } from '@/lib/page-tree';
5+
import { baseOptions } from '../layout.config';
6+
7+
export default function Layout({ children }: { children: ReactNode }) {
8+
return (
9+
<DocsLayout
10+
tree={pageTree}
11+
{...baseOptions}
12+
sidebar={{
13+
collapsible: true,
14+
defaultOpenLevel: 0,
15+
}}
16+
>
17+
{children}
18+
</DocsLayout>
19+
);
20+
}
21+

apps/site/app/global.css

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
@import 'tailwindcss';
2+
@import 'fumadocs-ui/style.css';
3+
@import 'fumadocs-twoslash/twoslash.css';
4+
5+
@theme {
6+
/* Colors - using CSS custom properties */
7+
--color-background: hsl(var(--background));
8+
--color-foreground: hsl(var(--foreground));
9+
--color-card: hsl(var(--card));
10+
--color-card-foreground: hsl(var(--card-foreground));
11+
--color-popover: hsl(var(--popover));
12+
--color-popover-foreground: hsl(var(--popover-foreground));
13+
--color-primary: hsl(var(--primary));
14+
--color-primary-foreground: hsl(var(--primary-foreground));
15+
--color-secondary: hsl(var(--secondary));
16+
--color-secondary-foreground: hsl(var(--secondary-foreground));
17+
--color-muted: hsl(var(--muted));
18+
--color-muted-foreground: hsl(var(--muted-foreground));
19+
--color-accent: hsl(var(--accent));
20+
--color-accent-foreground: hsl(var(--accent-foreground));
21+
--color-destructive: hsl(var(--destructive));
22+
--color-destructive-foreground: hsl(var(--destructive-foreground));
23+
--color-border: hsl(var(--border));
24+
--color-input: hsl(var(--input));
25+
--color-ring: hsl(var(--ring));
26+
}
27+
28+
@layer base {
29+
:root {
30+
--background: 0 0% 100%;
31+
--foreground: 222.2 84% 4.9%;
32+
--card: 0 0% 100%;
33+
--card-foreground: 222.2 84% 4.9%;
34+
--popover: 0 0% 100%;
35+
--popover-foreground: 222.2 84% 4.9%;
36+
--primary: 222.2 47.4% 11.2%;
37+
--primary-foreground: 210 40% 98%;
38+
--secondary: 210 40% 96.1%;
39+
--secondary-foreground: 222.2 47.4% 11.2%;
40+
--muted: 210 40% 96.1%;
41+
--muted-foreground: 215.4 16.3% 46.9%;
42+
--accent: 210 40% 96.1%;
43+
--accent-foreground: 222.2 47.4% 11.2%;
44+
--destructive: 0 84.2% 60.2%;
45+
--destructive-foreground: 210 40% 98%;
46+
--border: 214.3 31.8% 91.4%;
47+
--input: 214.3 31.8% 91.4%;
48+
--ring: 222.2 84% 4.9%;
49+
}
50+
51+
.dark {
52+
--background: 222.2 84% 4.9%;
53+
--foreground: 210 40% 98%;
54+
--card: 222.2 84% 4.9%;
55+
--card-foreground: 210 40% 98%;
56+
--popover: 222.2 84% 4.9%;
57+
--popover-foreground: 210 40% 98%;
58+
--primary: 210 40% 98%;
59+
--primary-foreground: 222.2 47.4% 11.2%;
60+
--secondary: 217.2 32.6% 17.5%;
61+
--secondary-foreground: 210 40% 98%;
62+
--muted: 217.2 32.6% 17.5%;
63+
--muted-foreground: 215 20.2% 65.1%;
64+
--accent: 217.2 32.6% 17.5%;
65+
--accent-foreground: 210 40% 98%;
66+
--destructive: 0 62.8% 30.6%;
67+
--destructive-foreground: 210 40% 98%;
68+
--border: 217.2 32.6% 17.5%;
69+
--input: 217.2 32.6% 17.5%;
70+
--ring: 212.7 26.8% 83.9%;
71+
}
72+
}

0 commit comments

Comments
 (0)