From 8e71906f18dc4ba1f8167fd33d041c866486d4e6 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 20 Jan 2026 05:17:25 +0000
Subject: [PATCH 03/10] Changes before error encountered
Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com>
---
apps/docs/app/source.ts | 7 +-
apps/docs/source.config.ts | 14 ++++
content/blog/welcome.mdx | 38 +++++++++
content/blog/zod-first-design.mdx | 128 ++++++++++++++++++++++++++++++
4 files changed, 186 insertions(+), 1 deletion(-)
create mode 100644 content/blog/welcome.mdx
create mode 100644 content/blog/zod-first-design.mdx
diff --git a/apps/docs/app/source.ts b/apps/docs/app/source.ts
index 82838edb5..ed823c2c8 100644
--- a/apps/docs/app/source.ts
+++ b/apps/docs/app/source.ts
@@ -1,4 +1,4 @@
-import { docs } from 'fumadocs-mdx:collections/server';
+import { docs, blog as blogCollection } from 'fumadocs-mdx:collections/server';
import { loader } from 'fumadocs-core/source';
import { i18n } from '@/lib/i18n';
@@ -7,3 +7,8 @@ export const source = loader({
i18n,
source: (docs as any).toFumadocsSource(),
});
+
+export const blog = loader({
+ baseUrl: '/blog',
+ source: (blogCollection as any).toFumadocsSource(),
+});
diff --git a/apps/docs/source.config.ts b/apps/docs/source.config.ts
index a4cae9999..95750ad40 100644
--- a/apps/docs/source.config.ts
+++ b/apps/docs/source.config.ts
@@ -1,7 +1,21 @@
import { defineDocs, defineConfig } from 'fumadocs-mdx/config';
+import { z } from 'zod';
export const docs = defineDocs({
dir: '../../content/docs',
}) as any;
+export const blog = defineDocs({
+ dir: '../../content/blog',
+ docs: {
+ schema: (ctx) => {
+ return ctx.schema.extend({
+ author: z.string().optional(),
+ date: z.string().date().or(z.date()).optional(),
+ tags: z.array(z.string()).optional(),
+ });
+ },
+ },
+}) as any;
+
export default defineConfig();
diff --git a/content/blog/welcome.mdx b/content/blog/welcome.mdx
new file mode 100644
index 000000000..25bcaffe6
--- /dev/null
+++ b/content/blog/welcome.mdx
@@ -0,0 +1,38 @@
+---
+title: Welcome to ObjectStack Blog
+description: Introducing the ObjectStack Protocol blog - your source for updates, insights, and best practices.
+author: ObjectStack Team
+date: 2024-01-15
+tags: [announcement, introduction]
+---
+
+# Welcome to ObjectStack Blog
+
+We're excited to launch the official ObjectStack Protocol blog! This is your go-to resource for:
+
+## What You'll Find Here
+
+- **Protocol Updates**: Stay informed about the latest changes and improvements to the ObjectStack Protocol
+- **Technical Deep Dives**: Detailed explorations of protocol components and implementation strategies
+- **Best Practices**: Learn how to effectively use ObjectStack in your projects
+- **Community Highlights**: Showcasing amazing projects built with ObjectStack
+- **AI Integration**: Tips for using ObjectStack with LLMs and AI-powered development
+
+## Why ObjectStack?
+
+The ObjectStack Protocol is designed to be the **universal language** for metadata-driven applications. Whether you're building:
+
+- Internal developer platforms (IDP)
+- Low-code/no-code solutions
+- AI-powered applications
+- Multi-tenant SaaS platforms
+
+ObjectStack provides a **Zod-first**, **database-agnostic**, and **AI-native** foundation for your project.
+
+## Stay Connected
+
+Follow our blog for regular updates, tutorials, and insights from the ObjectStack community. We're just getting started!
+
+---
+
+*Have questions or feedback? Join our [GitHub Discussions](https://github.com/objectstack-ai/spec/discussions) or open an [issue](https://github.com/objectstack-ai/spec/issues).*
diff --git a/content/blog/zod-first-design.mdx b/content/blog/zod-first-design.mdx
new file mode 100644
index 000000000..28f4d21ca
--- /dev/null
+++ b/content/blog/zod-first-design.mdx
@@ -0,0 +1,128 @@
+---
+title: Understanding Zod-First Protocol Design
+description: Learn why ObjectStack chose Zod as the foundation for protocol definitions and how it benefits your development workflow.
+author: ObjectStack Team
+date: 2024-01-18
+tags: [zod, typescript, protocol, technical]
+---
+
+# Understanding Zod-First Protocol Design
+
+One of the core principles of ObjectStack is **Zod-First** design. But what does that mean, and why is it important?
+
+## What is Zod?
+
+[Zod](https://zod.dev/) is a TypeScript-first schema declaration and validation library. It allows you to:
+
+- Define schemas with full TypeScript type inference
+- Validate data at runtime
+- Generate JSON Schema for documentation
+- Create parsers and transformers
+
+## Why Zod-First?
+
+ObjectStack Protocol uses Zod as the single source of truth for all definitions. This approach provides several key benefits:
+
+### 1. Runtime Validation
+
+```typescript
+import { ObjectProtocol } from '@objectstack/spec';
+
+export const User = ObjectProtocol.define({
+ name: 'user',
+ fields: {
+ email: Field.text({ required: true }),
+ age: Field.number({ min: 0, max: 150 }),
+ }
+});
+
+// Runtime validation happens automatically
+```
+
+### 2. Static Type Inference
+
+Because everything is defined in Zod, TypeScript can infer types directly from your schemas:
+
+```typescript
+type UserType = z.infer
;
+// No need to maintain separate type definitions!
+```
+
+### 3. JSON Schema Generation
+
+Zod schemas can be automatically converted to JSON Schema, making them:
+- **Documentable**: Auto-generate API documentation
+- **Interoperable**: Work with any language/tool that supports JSON Schema
+- **AI-Friendly**: LLMs can understand and work with JSON Schema
+
+### 4. Single Source of Truth
+
+With Zod-First design, you define your protocol once and get:
+- Runtime validation ✅
+- TypeScript types ✅
+- JSON Schema ✅
+- IDE autocomplete ✅
+- Error messages ✅
+
+## Real-World Example
+
+Here's how a complete Object definition looks:
+
+```typescript
+import { z } from 'zod';
+import { ObjectProtocol, Field } from '@objectstack/spec';
+
+export const ProjectTaskSchema = ObjectProtocol.define({
+ name: 'project_task',
+ label: 'Project Task',
+ fields: {
+ title: Field.text({
+ required: true,
+ maxLength: 255
+ }),
+ status: Field.select({
+ options: ['todo', 'in_progress', 'done'],
+ default: 'todo'
+ }),
+ assignee: Field.lookup({
+ reference: 'user',
+ multiple: false
+ }),
+ due_date: Field.date({ required: false }),
+ priority: Field.number({
+ min: 1,
+ max: 5,
+ default: 3
+ }),
+ },
+ enable: {
+ trackHistory: true,
+ apiEnabled: true,
+ }
+});
+
+// TypeScript type is automatically inferred
+type ProjectTask = z.infer;
+```
+
+## Benefits for AI Development
+
+Zod-First design makes ObjectStack incredibly **AI-friendly**:
+
+1. **Deterministic Schema**: LLMs can reliably generate valid ObjectStack definitions
+2. **JSON Schema Output**: AI agents can understand the structure through standardized JSON Schema
+3. **Validation Feedback**: Runtime validation provides clear error messages for AI to learn from
+
+## Conclusion
+
+Zod-First protocol design is not just a technical choice—it's a philosophy that prioritizes:
+- **Developer Experience**: Write once, use everywhere
+- **Type Safety**: Catch errors at compile time and runtime
+- **Interoperability**: Work with any tool that understands JSON Schema
+- **AI Integration**: Enable seamless AI-powered development
+
+Ready to dive deeper? Check out our [Schema Definition Guide](/docs/specifications/data/schema-definition) for more details.
+
+---
+
+*Questions? Join the discussion on [GitHub](https://github.com/objectstack-ai/spec/discussions).*
From dee0344adddad3bc08cadb9d8fdc9af65452c908 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 20 Jan 2026 05:43:13 +0000
Subject: [PATCH 04/10] Add blog section with fumadocs integration
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
---
.../docs/app/[lang]/blog/[[...slug]]/page.tsx | 186 ++++++++++++++++++
apps/docs/app/layout.config.tsx | 5 +
apps/docs/source.config.ts | 16 +-
3 files changed, 197 insertions(+), 10 deletions(-)
create mode 100644 apps/docs/app/[lang]/blog/[[...slug]]/page.tsx
diff --git a/apps/docs/app/[lang]/blog/[[...slug]]/page.tsx b/apps/docs/app/[lang]/blog/[[...slug]]/page.tsx
new file mode 100644
index 000000000..206518aa3
--- /dev/null
+++ b/apps/docs/app/[lang]/blog/[[...slug]]/page.tsx
@@ -0,0 +1,186 @@
+import { notFound } from 'next/navigation';
+import { blog } from '@/app/source';
+import defaultMdxComponents from 'fumadocs-ui/mdx';
+import { HomeLayout } from 'fumadocs-ui/layouts/home';
+import { baseOptions } from '@/app/layout.config';
+import Link from 'next/link';
+import { ArrowLeft } from 'lucide-react';
+
+export default async function BlogPage({
+ params,
+}: {
+ params: Promise<{ lang: string; slug?: string[] }>;
+}) {
+ const { slug } = await params;
+
+ // If no slug, show blog index
+ if (!slug || slug.length === 0) {
+ const posts = blog.getPages();
+
+ return (
+
+
+
+
Blog
+
+ Insights, updates, and best practices from the ObjectStack team.
+
+
+
+
+ {posts.map((post) => (
+
+
+
+ {post.data.title}
+
+ {post.data.description && (
+
+ {post.data.description}
+
+ )}
+
+
+
+ {post.data.date && (
+
+ )}
+ {post.data.author && (
+ By {post.data.author}
+ )}
+
+
+ {post.data.tags && post.data.tags.length > 0 && (
+
+ {post.data.tags.map((tag: string) => (
+
+ {tag}
+
+ ))}
+
+ )}
+
+ ))}
+
+
+ {posts.length === 0 && (
+
+
No blog posts yet. Check back soon!
+
+ )}
+
+
+ );
+ }
+
+ // Show individual blog post
+ const page = blog.getPage(slug);
+
+ if (!page) {
+ notFound();
+ }
+
+ const MDX = page.data.body;
+
+ return (
+
+
+
+
+ Back to Blog
+
+
+
+
+ {page.data.title}
+
+ {page.data.description && (
+
+ {page.data.description}
+
+ )}
+
+
+ {page.data.date && (
+
+ )}
+ {page.data.author && (
+ By {page.data.author}
+ )}
+
+
+ {page.data.tags && page.data.tags.length > 0 && (
+
+ {page.data.tags.map((tag: string) => (
+
+ {tag}
+
+ ))}
+
+ )}
+
+
+
+
+
+
+ );
+}
+
+export async function generateStaticParams() {
+ return blog.getPages().map((page) => ({
+ slug: page.slugs,
+ }));
+}
+
+export async function generateMetadata({
+ params,
+}: {
+ params: Promise<{ slug?: string[] }>;
+}) {
+ const { slug } = await params;
+
+ // If no slug, return default metadata for blog index
+ if (!slug || slug.length === 0) {
+ return {
+ title: 'Blog',
+ description: 'Insights, updates, and best practices from the ObjectStack team.',
+ };
+ }
+
+ const page = blog.getPage(slug);
+
+ if (!page) {
+ notFound();
+ }
+
+ return {
+ title: page.data.title,
+ description: page.data.description,
+ };
+}
diff --git a/apps/docs/app/layout.config.tsx b/apps/docs/app/layout.config.tsx
index 424eaa4d0..231f6ca15 100644
--- a/apps/docs/app/layout.config.tsx
+++ b/apps/docs/app/layout.config.tsx
@@ -22,6 +22,11 @@ export const baseOptions: BaseLayoutProps = {
url: '/docs/',
active: 'nested-url',
},
+ {
+ text: 'Blog',
+ url: '/blog',
+ active: 'nested-url',
+ },
// {
// text: 'Concepts',
// url: '/docs/concepts/manifesto',
diff --git a/apps/docs/source.config.ts b/apps/docs/source.config.ts
index 95750ad40..892181cc7 100644
--- a/apps/docs/source.config.ts
+++ b/apps/docs/source.config.ts
@@ -1,4 +1,4 @@
-import { defineDocs, defineConfig } from 'fumadocs-mdx/config';
+import { defineDocs, defineConfig, frontmatterSchema } from 'fumadocs-mdx/config';
import { z } from 'zod';
export const docs = defineDocs({
@@ -7,15 +7,11 @@ export const docs = defineDocs({
export const blog = defineDocs({
dir: '../../content/blog',
- docs: {
- schema: (ctx) => {
- return ctx.schema.extend({
- author: z.string().optional(),
- date: z.string().date().or(z.date()).optional(),
- tags: z.array(z.string()).optional(),
- });
- },
- },
+ schema: frontmatterSchema.extend({
+ author: z.string().optional(),
+ date: z.string().or(z.date()).optional(),
+ tags: z.array(z.string()).optional(),
+ }),
}) as any;
export default defineConfig();
From e1063f6a4e22ad3f14627210c0b49f74b6b40f25 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 20 Jan 2026 05:45:39 +0000
Subject: [PATCH 05/10] Fix blog schema validation for date field
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
---
apps/docs/source.config.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/docs/source.config.ts b/apps/docs/source.config.ts
index 892181cc7..2e705c2b1 100644
--- a/apps/docs/source.config.ts
+++ b/apps/docs/source.config.ts
@@ -9,7 +9,7 @@ export const blog = defineDocs({
dir: '../../content/blog',
schema: frontmatterSchema.extend({
author: z.string().optional(),
- date: z.string().or(z.date()).optional(),
+ date: z.string().date().optional(),
tags: z.array(z.string()).optional(),
}),
}) as any;
From 929b5b30bdd5e4ee970ace8a77767e6c6827a3da Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 20 Jan 2026 05:47:47 +0000
Subject: [PATCH 06/10] Apply consistent font color improvements to blog pages
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
---
apps/docs/app/[lang]/blog/[[...slug]]/page.tsx | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/apps/docs/app/[lang]/blog/[[...slug]]/page.tsx b/apps/docs/app/[lang]/blog/[[...slug]]/page.tsx
index 206518aa3..bcea85046 100644
--- a/apps/docs/app/[lang]/blog/[[...slug]]/page.tsx
+++ b/apps/docs/app/[lang]/blog/[[...slug]]/page.tsx
@@ -22,7 +22,7 @@ export default async function BlogPage({
Blog
-
+
Insights, updates, and best practices from the ObjectStack team.
@@ -39,13 +39,13 @@ export default async function BlogPage({
{post.data.title}
{post.data.description && (
-
+
{post.data.description}
)}