diff --git a/apps/docs/app/[lang]/page.tsx b/apps/docs/app/[lang]/page.tsx index 3adeee12aac..b68a2777dfa 100644 --- a/apps/docs/app/[lang]/page.tsx +++ b/apps/docs/app/[lang]/page.tsx @@ -1,10 +1,10 @@ import type { Metadata } from 'next'; import Link from 'next/link'; -import { ArrowRight, Check } from 'lucide-react'; +import { ArrowRight } from 'lucide-react'; import { Bricolage_Grotesque, IBM_Plex_Mono } from 'next/font/google'; import { HomeLayout } from 'fumadocs-ui/layouts/home'; -import { baseOptions, ESSAY_URL, gitConfig } from '@/lib/layout.shared'; -import { absoluteUrl, HERO_COVER } from '@/lib/site'; +import { baseOptions, gitConfig, PRODUCT_SITE_URL } from '@/lib/layout.shared'; +import { absoluteUrl, HERO_COVER, SITE_ORIGIN } from '@/lib/site'; import { APACHE_2_0_URL, GITHUB_REPO_URL, @@ -12,14 +12,8 @@ import { ORGANIZATION, ORGANIZATION_REF, SOFTWARE_ID, - YOUTUBE_CHANNEL_URL, type JsonLdNode, } from '@/lib/structured-data'; -import { YouTubeEmbed } from '@/components/youtube-embed'; -import { OntologyRunsFigure } from '@/components/figures'; - -/** The 90-second overview — the same video the README's hero cover links to. */ -const OVERVIEW_VIDEO_ID = 'CX_FlOoOtr0'; const display = Bricolage_Grotesque({ subsets: ['latin'], @@ -32,24 +26,29 @@ const mono = IBM_Plex_Mono({ variable: '--font-l-mono', }); -const HOME_TITLE = 'The ontology is the software'; -const HOME_DESCRIPTION = - 'One executable business ontology. AI writes it, the runtime runs it, agents operate it, you own it. The whole app — data model, UI, workflows, permissions — is typed metadata small enough for AI to hold whole.'; +/** + * This is the developer site. The product site (`PRODUCT_SITE_URL`) carries the + * hero, the editions, pricing and the one blog; this page carries one line of + * positioning, the start command, the docs entry points, the "Run it" strip and + * the GitHub link — nothing that sells. The slogan stays as the kicker above the + * positioning line: it is the project's one sentence, not a marketing hero. + */ +const KICKER = 'The ontology is the software.'; +const POSITIONING = + 'ObjectStack is the open protocol and SDK that ObjectOS is built on: one typed business ontology, and the database, API, Console and MCP tools derive from it.'; + +const HOME_TITLE = 'The open protocol and SDK ObjectOS is built on'; +const HOME_DESCRIPTION = POSITIONING; /** * The homepage's metadata. Its social card is the shared hero cover, - * `HERO_COVER` from `lib/site.ts` — the same image the video poster below uses. + * `HERO_COVER` from `lib/site.ts`. * * ⚠️ Deliberately NOT the docs card generator. `app/og/docs/[...slug]/route.tsx` * renders from a `source.getPage()` result, and the homepage has no MDX file * behind it — there is no slug to hand it. It reuses the hero cover instead, - * which is already shipped and already the video poster on this page, so the - * shared card costs no extra bytes and no extra route. - * - * The path used to be spelled as a literal here, again in the blog's card, and a - * third time as the `poster` further down this file — with a note asking whoever - * added a third consumer to hoist it. That happened; it lives in `lib/site.ts` - * now, and the reasons a re-encode has to be careful live with it. + * which is already shipped, so the shared card costs no extra bytes and no + * extra route. The reasons a re-encode has to be careful live in `lib/site.ts`. * * Left site-relative: `metadataBase` in `app/layout.tsx` absolutises it. */ @@ -97,8 +96,8 @@ export const metadata: Metadata = { * * Every field is drawn from something already on this page or in `lib/`: the * title and description are the same constants `metadata` uses, the image is - * `HERO_COVER`, the licence is the repo's own, and the two `sameAs` links are the - * GitHub organisation and the YouTube channel this page links to in its hero. + * `HERO_COVER`, the licence is the repo's own, and the `sameAs` links are the + * organisation's. */ function homeGraph(): JsonLdNode[] { return [ @@ -123,66 +122,67 @@ function homeGraph(): JsonLdNode[] { ]; } -/** Section 00's three sentences, verbatim from the maintainer's ruling. */ -const IDEA: string[] = [ - 'An enterprise is definition plus execution. When execution is nearly free, it is its definition.', - 'What the model lacks is not intelligence: a world, hands, and a fence.', - 'An ontology written clearly enough is software. Models change; the ontology stays.', +/** The start command, as `content/docs/getting-started` teaches it. */ +const START_COMMANDS: string[] = [ + 'npm create objectstack@latest my-app', + 'cd my-app', + 'npx os dev --ui', ]; -const VOCABULARY: { tag: string; title: string; copy: string }[] = [ - { tag: 'object', title: 'Objects & fields', copy: 'Typed schemas with relations, validation, formulas, and files.' }, - { tag: 'permission', title: 'Permissions', copy: 'RBAC plus row- and field-level security, enforced by the runtime.' }, - { tag: 'flow', title: 'Automation', copy: 'DAG flows, record triggers, scheduled jobs, and webhooks.' }, - { tag: 'approval', title: 'Approvals', copy: 'Multi-step approval chains with queues and a full audit trail.' }, - { tag: 'view', title: 'Views', copy: 'Lists, kanban boards, calendars, gantt, galleries — declared, not coded.' }, - { tag: 'dashboard', title: 'Dashboards & reports', copy: 'Charts, aggregations, and KPIs bound to live data.' }, - { tag: 'action', title: 'Actions', copy: 'Permission-checked buttons and server operations.' }, - { tag: 'api', title: 'APIs & SDK', copy: 'Generated REST and realtime endpoints with a typed client SDK.' }, - { tag: 'mcp', title: 'AI tools', copy: 'Every object and action doubles as a governed MCP tool.' }, - { tag: 'i18n', title: 'Translations', copy: 'Labels and UI text as metadata, per locale.' }, - { tag: 'seed', title: 'Seed data', copy: 'Fixtures and demo datasets that ship with the app.' }, - { tag: 'driver', title: 'Datasources', copy: 'Postgres, MySQL, SQLite, MongoDB, or in-memory.' }, +/** The docs entry points, in reading order. Every route exists under `content/docs`. */ +const DOCS_ENTRY_POINTS: { title: string; href: string; copy: string }[] = [ + { title: 'Getting started', href: '/docs/getting-started', copy: 'What ObjectStack is, your first project, the anatomy of an app.' }, + { title: 'Concepts', href: '/docs/concepts', copy: 'The business ontology, the runtime, and the principles behind both.' }, + { title: 'Spec', href: '/docs/protocol', copy: 'The protocol: how Data, UI and System layers describe an application.' }, + { title: 'CLI', href: '/docs/deployment/cli', copy: 'The os command — validate, dev, build, start, package.' }, + { title: 'Build with Claude Code', href: '/docs/getting-started/build-with-claude-code', copy: 'The main workflow: an agent writes the app, you verify it in the Console.' }, ]; -const GATES: { title: string; copy: string }[] = [ - { title: 'Typed', copy: 'Strict TypeScript + Zod — shape errors die in the editor, seconds after the agent writes them.' }, - { title: 'Validated', copy: 'os validate rejects metadata that would fail silently at runtime — before it ships.' }, - { title: 'Reviewed', copy: 'You approve a small readable diff in the Console — not a pile of generated glue.' }, - { title: 'Governed', copy: 'Permissions and audit are enforced by the runtime on every call. Even a wrong app stays inside the fence.' }, +/** + * The four sections the previous landing carried in full — the idea, the loop, + * the gates, the vocabulary — now one row of links into the docs pages that + * already carry that content. Nothing here is a second copy of a docs page. + */ +const DOCS_THEMES: { label: string; title: string; href: string }[] = [ + { label: 'The idea', title: 'Business ontology — the executable definition the runtime runs', href: '/docs/concepts/ontology' }, + { label: 'The loop', title: 'Describe · the agent writes metadata · os validate · you verify in the Console', href: '/docs/getting-started/build-with-claude-code' }, + { label: 'The gates', title: 'Why AI-written app development is safe — the guardrails between the agent and production', href: '/docs/getting-started/how-ai-development-works' }, + { label: 'The vocabulary', title: 'What can it build? — the capabilities, in business language', href: '/docs/capabilities' }, ]; -const STEPS: { num: string; title: string; cmd: string; copy: string }[] = [ +/** + * "Run it": ObjectOS is one product in three editions, and ObjectStack is the + * protocol and SDK every edition runs on. Community is this repository's own + * runtime image, so it links into these docs; the hosted and enterprise editions + * are the product site's to describe. + */ +const EDITIONS: { name: string; copy: string; href: string; cta: string; external: boolean }[] = [ { - num: '01', - title: 'Create a project', - cmd: 'npx create-objectstack my-app', - copy: 'A typed project skeleton — spec, seed data, and the Console already wired.', + name: 'ObjectOS Community', + copy: 'This repository’s runtime image, self-hosted and free: os start, or the container image.', + href: '/docs/deployment/self-hosting', + cta: 'Self-hosting guide', + external: false, }, { - num: '02', - title: 'Describe the requirement', - cmd: 'claude · os validate ✓', - copy: 'Tell Claude Code what the business needs. It writes compact typed metadata, and the validation gate rejects anything that would fail silently.', + name: 'ObjectOS Cloud', + copy: 'Hosted by ObjectOS — nothing to install, build and ask in the browser.', + href: PRODUCT_SITE_URL, + cta: 'objectos.ai', + external: true, }, { - num: '03', - title: 'Preview in the browser', - cmd: 'os dev', - copy: 'The Console renders it live — records, boards, dashboards. Requirement changed? Same loop: describe, validate, preview.', + name: 'ObjectOS Enterprise', + copy: 'Your infrastructure, your identity provider, with support from the team.', + href: PRODUCT_SITE_URL, + cta: 'objectos.ai', + external: true, }, ]; -function DiffLine({ children, plain }: { children: React.ReactNode; plain?: boolean }) { - return ( -
- - {plain ? ' ' : '+'} - - {children} -
- ); -} +/** The two hosts, read from the constants that own them — never spelled twice. */ +const THIS_SITE_HOST = new URL(SITE_ORIGIN).host; +const PRODUCT_SITE_HOST = new URL(PRODUCT_SITE_URL).host; export default function HomePage() { return ( @@ -205,42 +205,41 @@ export default function HomePage() { backgroundSize: '56px 56px', }} /> -
- {/* ── hero ─────────────────────────────────────────────── */} -
+ {/* ── positioning ──────────────────────────────────────── */} +

Open protocol & runtime · Apache-2.0

+

+ {KICKER} +

- The ontology{' '} - - is the software. - + {POSITIONING}

-

- One executable business ontology. AI writes it, the runtime runs it, agents operate - it, you own it. The whole app — data model, UI, workflows, permissions — is typed - metadata small enough for AI to hold whole: agents read it whole, reason it whole, - refactor it whole. -

-

- - Why the ontology is the software - - -

-
+ + {/* ── start command ────────────────────────────────── */} +
+
+ Start here +
+
+ {START_COMMANDS.map((cmd) => ( +
+ $ + {cmd} +
+ ))} +
+

+ then open http://localhost:3000/_console/ — the Console renders the app the metadata describes +

+
+ +
- - Documentation - GitHub - - YouTube - -
-
- Executable - | - AI-writable - | - Agent-operable - | - You own it
- {/* ── the 90-second overview — the page's first visual ──── */} -
-
- -
- ▶ ObjectStack in 90 Seconds - - More videos on YouTube - - -
-
-
- - {/* ── what that metadata is, in prose ──────────────────── */} -
-

- That metadata is your business ontology — an open, versioned definition of your - objects, relations, actions, permissions, flows, and agent and tool definitions that - you own. It is executable, not a knowledge-representation ontology: no inheritance, - no axioms, no reasoner. Strict TypeScript, Zod schemas, and a validation gate catch - the agent's mistakes at authoring time, and the runtime derives the database, - REST API, UI, and MCP server — permissions and audit enforced on every call. -

-
- - {/* ── 00 · the idea ────────────────────────────────────── */} -
+ {/* ── docs entry points ────────────────────────────────── */} +
- 00 · The idea + Docs
-

- An ontology written clearly enough runs directly -

- {/* The figure's caption takes its spacing and colour from the blog's prose - styles there; this page has no prose wrapper, so the wrapper sets them. */} -
- -
-
- {IDEA.map((line) => ( -
-
-

- {line} -

-
+
+ {DOCS_ENTRY_POINTS.map((d) => ( + +

+ {d.title} + +

+

{d.copy}

+ ))}
- - Read the essay - - -
- {/* ── 01 · the loop ────────────────────────────────────── */} -
-
- - 01 · The loop - -
-

- From requirement to running app -

-
- {STEPS.map((s) => ( -
-
- {s.num} -
-
-

{s.title}

-

+ {DOCS_THEMES.map((t) => ( + + - {s.cmd} -

-

{s.copy}

-
- ))} -
- - {/* the artifact card — requirement → metadata → gate → preview */} -
-
-
-

you → claude code

-

- “Build an expense approval app for a 50-person team.” -

-
-
-

expense.object.ts

- {`export const Expense = ObjectSchema.create({`} - {` name: 'expense_request',`} - {` fields: {`} - {` amount: Field.currency({ required: true }),`} - {` status: Field.select({ options: [...] }),`} - {` approver: Field.lookup('sys_user'),`} - {` },`} - {`});`} -
-
- - - os validate + {t.label} - - - types · permissions · flows - - - os dev - - Console preview - -
-
-
- one definition → tables · REST API · Console UI · MCP tools -
-
-
- - {/* ── 02 · four gates ──────────────────────────────────── */} -
-
- - 02 · The gates - -
-

- Four gates between the agent and production -

-
- {GATES.map((g, i) => ( -
-

- {String(i + 1).padStart(2, '0')} -

-

{g.title}

-

{g.copy}

-
+ {t.title} + ))}
- {/* ── 03 · the vocabulary ──────────────────────────────── */} -
+ {/* ── run it: the three editions ───────────────────────── */} +
- 03 · The vocabulary + Run it
-

- What can it actually build? -

-

- Point an agent at an empty repo and you get a one-off codebase — every screen - hand-invented, every mistake yours to find at runtime. ObjectStack gives the agent - a vocabulary instead: typed, validated primitives for everything enterprise - software needs. The agent composes the definition; the runtime already knows how to - run it. +

+ ObjectOS is the product built on this protocol, in three editions. Every edition runs the + same ObjectStack metadata.

-
- {VOCABULARY.map((v) => ( -
- - {v.tag} - -
- {v.title} - — {v.copy} -
+
+ {EDITIONS.map((e) => ( +
+

{e.name}

+

{e.copy}

+ {e.external ? ( + + {e.cta} + + + ) : ( + + {e.cta} + + + )}
))}
- - Browse the full vocabulary in the docs - -
- {/* ── closing ──────────────────────────────────────────── */} -
-
-

- The ontology is the software. Your objects, relations, actions, permissions, and - flows are your business ontology — views, dashboards, apps, and translations are - projections of it, and the definition layer of the AI era should be an open - protocol you own. -

-

- ObjectStack is build & ask with Claude Code. Rather build & ask online — - in the browser, nothing to install?{' '} - - Try ObjectOS - - -

+ {/* ── the two sites, by role ───────────────────────────── */} +
+
+ + {THIS_SITE_HOST} — Developer docs & protocol + + | + + {PRODUCT_SITE_HOST} — Product, editions & blog +
diff --git a/apps/docs/components/youtube-embed.tsx b/apps/docs/components/youtube-embed.tsx deleted file mode 100644 index f1974485de8..00000000000 --- a/apps/docs/components/youtube-embed.tsx +++ /dev/null @@ -1,65 +0,0 @@ -'use client'; - -import { useState } from 'react'; -import { Play } from 'lucide-react'; - -type YouTubeEmbedProps = { - /** The video id — the part after `youtu.be/`. */ - videoId: string; - /** Video title. Used for the iframe title and the play button's label. */ - title: string; - /** Cover shown until the viewer clicks play. Served from `public/`. */ - poster: string; -}; - -/** - * Click-to-play YouTube embed. - * - * A facade, not a bare `