Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
23 changes: 23 additions & 0 deletions .claude/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"version": "0.0.1",
"configurations": [
{
"name": "Docs site (@objectos/docs)",
"runtimeExecutable": "pnpm",
"runtimeArgs": ["--filter", "@objectos/docs", "dev"],
"port": 3000,
"autoPort": true
},
{
"name": "ObjectStack server (@objectos/server)",
"runtimeExecutable": "pnpm",
"runtimeArgs": ["--filter", "@objectos/server", "dev"],
"port": 3001
},
{
"name": "Desktop app (@objectos/one, Tauri)",
"runtimeExecutable": "pnpm",
"runtimeArgs": ["--filter", "@objectos/one", "dev"]
}
]
}
6 changes: 5 additions & 1 deletion apps/docs/app/[lang]/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ import { i18n } from '@/lib/i18n';
// Language display names mapping
const LANGUAGE_NAMES: Record<string, string> = {
en: 'English',
cn: '中文',
'zh-Hans': '简体中文',
ja: '日本語',
de: 'Deutsch',
es: 'Español',
fr: 'Français',
};

export default async function LanguageLayout({
Expand Down
4 changes: 2 additions & 2 deletions apps/docs/app/[lang]/privacy/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const content = {
],
back: '← Back to home',
},
cn: {
'zh-Hans': {
title: '隐私政策',
updated: '最近更新:2026 年 5 月 27 日',
body: [
Expand Down Expand Up @@ -57,7 +57,7 @@ export default async function PrivacyPage({
params: Promise<{ lang: string }>;
}) {
const { lang } = await params;
const t = content[lang === 'cn' ? 'cn' : 'en'];
const t = content[lang as keyof typeof content] ?? content.en;

return (
<HomeLayout {...baseOptions(lang)} i18n>
Expand Down
4 changes: 2 additions & 2 deletions apps/docs/app/[lang]/terms/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const content = {
],
back: '← Back to home',
},
cn: {
'zh-Hans': {
title: '服务条款',
updated: '最近更新:2026 年 5 月 27 日',
body: [
Expand Down Expand Up @@ -65,7 +65,7 @@ export default async function TermsPage({
params: Promise<{ lang: string }>;
}) {
const { lang } = await params;
const t = content[lang === 'cn' ? 'cn' : 'en'];
const t = content[lang as keyof typeof content] ?? content.en;

return (
<HomeLayout {...baseOptions(lang)} i18n>
Expand Down
15 changes: 12 additions & 3 deletions apps/docs/lib/download-i18n.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* Download page translations + static install data.
*
* English is the source of truth — edit `en` first, then sync `cn`.
* English is the source of truth — edit `en` first, then sync `zhHans`.
*
* Only include install methods that have a real, published artifact:
* - Docker image: ghcr.io/objectstack-ai/objectos:latest (docker.yml)
Expand Down Expand Up @@ -198,7 +198,7 @@ export const en: DownloadTranslations = {
copy: { copy: 'Copy', copied: 'Copied' },
};

export const cn: DownloadTranslations = {
export const zhHans: DownloadTranslations = {
badge: `最新发布 · v${ONE_VERSION}`,
hero: {
title: '下载 ObjectOS',
Expand Down Expand Up @@ -313,8 +313,17 @@ export const cn: DownloadTranslations = {
copy: { copy: '复制', copied: '已复制' },
};

/**
* Registry of available download-page translations. Locales absent
* here (ja, de, es, fr until translated) resolve to English.
*/
const DOWNLOAD_TRANSLATIONS: Partial<Record<string, DownloadTranslations>> = {
en,
'zh-Hans': zhHans,
};

export function getDownloadTranslations(lang: string): DownloadTranslations {
return lang === 'cn' ? cn : en;
return DOWNLOAD_TRANSLATIONS[lang] ?? en;
}

/* ------------------------------------------------------------------ */
Expand Down
26 changes: 15 additions & 11 deletions apps/docs/lib/homepage-i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
* evaluating a customer-hosted runtime for ObjectStack applications —
* NOT framework developers.
*
* Supports: en (English), cn (Chinese / 中文)
* Supports: en (English), zh-Hans (简体中文). Additional locales
* (ja, de, es, fr) fall back to English until their objects are added.
*/

import { SPEC_VERSION, OBJECTOS_VERSION } from './version';
Expand Down Expand Up @@ -332,9 +333,9 @@ export const en: HomepageTranslations = {
};

/**
* Chinese Translations (中文翻译)
* Chinese (Simplified) Translations (简体中文翻译)
*/
export const cn: HomepageTranslations = {
export const zhHans: HomepageTranslations = {
badge: {
status: 'AI 原生业务平台',
version: SPEC_VERSION,
Expand Down Expand Up @@ -487,14 +488,17 @@ export const cn: HomepageTranslations = {
};

/**
* Get translations for a specific language
* Registry of available homepage translations. Locales absent here
* (ja, de, es, fr until translated) resolve to English via the getter.
*/
const HOMEPAGE_TRANSLATIONS: Partial<Record<string, HomepageTranslations>> = {
en,
'zh-Hans': zhHans,
};

/**
* Get translations for a specific language, falling back to English.
*/
export function getHomepageTranslations(lang: string): HomepageTranslations {
switch (lang) {
case 'cn':
return cn;
case 'en':
default:
return en;
}
return HOMEPAGE_TRANSLATIONS[lang] ?? en;
}
14 changes: 9 additions & 5 deletions apps/docs/lib/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,18 @@ import { defineI18n } from 'fumadocs-core/i18n';

/**
* i18n Configuration for ObjectStack Documentation
*
* Supported Languages:
* - en: English (Default)
* - cn: Chinese (中文)
*
* Supported Languages (BCP 47 tags):
* - en: English (Default)
* - zh-Hans: Chinese, Simplified (简体中文)
* - ja: Japanese (日本語)
* - de: German (Deutsch)
* - es: Spanish (Español)
* - fr: French (Français)
*/
export const i18n = defineI18n({
defaultLanguage: 'en',
languages: ['en', 'cn'],
languages: ['en', 'zh-Hans', 'ja', 'de', 'es', 'fr'],
// Hide locale prefix for default language (e.g., /docs instead of /en/docs)
hideLocale: 'default-locale',
});
6 changes: 5 additions & 1 deletion apps/docs/lib/layout.shared.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ export const gitConfig = {

const NAV_LABELS: Record<string, { docs: string; download: string; changelog: string }> = {
en: { docs: 'Docs', download: 'Download', changelog: 'Changelog' },
cn: { docs: '文档', download: '下载', changelog: '更新日志' },
'zh-Hans': { docs: '文档', download: '下载', changelog: '更新日志' },
ja: { docs: 'ドキュメント', download: 'ダウンロード', changelog: '変更履歴' },
de: { docs: 'Dokumentation', download: 'Download', changelog: 'Änderungen' },
es: { docs: 'Documentación', download: 'Descargar', changelog: 'Cambios' },
fr: { docs: 'Documentation', download: 'Télécharger', changelog: 'Journal' },
};

const RELEASES_URL = 'https://github.com/objectstack-ai/objectos/releases';
Expand Down
36 changes: 31 additions & 5 deletions apps/docs/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,21 @@ function setLocaleCookie(response: NextResponse, locale: string): void {
* Maps browser language codes to our supported language codes
*/
const LANGUAGE_MAPPING: Record<string, string> = {
'zh': 'cn', // Chinese -> cn
'zh-CN': 'cn', // Chinese (China) -> cn
'zh-TW': 'cn', // Chinese (Taiwan) -> cn
'zh-HK': 'cn', // Chinese (Hong Kong) -> cn
'zh': 'zh-Hans', // Chinese -> Simplified
'zh-CN': 'zh-Hans', // Chinese (China) -> Simplified
'zh-SG': 'zh-Hans', // Chinese (Singapore) -> Simplified
'zh-Hans': 'zh-Hans', // already Simplified
// Traditional variants fall back to Simplified until zh-Hant ships
'zh-TW': 'zh-Hans',
'zh-HK': 'zh-Hans',
};

/**
* Legacy locale redirects: old locale code -> current BCP 47 tag.
* Permanent (308) so search engines transfer ranking to the new path.
*/
const LEGACY_LOCALE_REDIRECTS: Record<string, string> = {
cn: 'zh-Hans',
};

/**
Expand Down Expand Up @@ -83,7 +94,8 @@ function getPreferredLanguage(request: NextRequest): string {
* - Detects the user's preferred language from browser settings or cookies
* - Redirects users to the appropriate localized version
* - For default language (en): keeps URL as "/" (with internal rewrite)
* - For other languages (cn): redirects to "/cn/"
* - For other languages (e.g. zh-Hans): redirects to "/zh-Hans/"
* - Redirects legacy locale paths (e.g. /cn/*) to their new tag
* - Stores language preference as a cookie
*/
export default function middleware(request: NextRequest) {
Expand All @@ -99,6 +111,20 @@ export default function middleware(request: NextRequest) {

const { pathname } = request.nextUrl;

// Legacy locale redirect (e.g. /cn/... -> /zh-Hans/...), permanent for SEO.
const legacySeg = pathname.split('/')[1];
if (legacySeg && LEGACY_LOCALE_REDIRECTS[legacySeg]) {
const target = LEGACY_LOCALE_REDIRECTS[legacySeg];
const url = new URL(request.url);
url.pathname = pathname.replace(
new RegExp(`^/${legacySeg}(/|$)`),
`/${target}$1`,
);
const response = NextResponse.redirect(url, 308);
setLocaleCookie(response, target);
return response;
}

// Check if the pathname already has a locale
const pathnameHasLocale = i18n.languages.some(
(locale) => pathname.startsWith(`/${locale}/`) || pathname === `/${locale}`
Expand Down
139 changes: 139 additions & 0 deletions content/docs/architecture.de.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
---
title: Architektur
description: Was tatsächlich auf Ihren Systemen läuft — für die Engineers, die abwägen, ob sie dies einführen sollen.
---

# Architektur

Eine praxisnahe Sicht darauf, was auf Ihren Maschinen läuft, wenn Sie
ObjectOS bereitstellen, welche Daten Ihr Netzwerk verlassen und welche nicht.

Das mentale Modell besteht aus zwei dünnen Schichten:

1. **Metadaten** — Pakete aus Objekten / Views / Actions / Flows /
Agents. Größtenteils vom [AI Builder](/docs/build/ai-builder)
gegen eine sandboxed Tool-API geschrieben; teils von Hand bearbeitet, stets
versionskontrolliert und auditiert.
2. **Eine einzige Node.js-Laufzeit**, die diese Metadaten in eine
funktionierende Anwendung interpretiert — REST-API, Console-UI, Berechtigungen, Jobs, AI-Tools — alles in einem Prozess, der mit Ihrer Datenbank kommuniziert.

Kein Codegenerierungsschritt, keine Deploy-Pipeline zwischen „Benutzer hat
beschrieben, was er möchte" und „es ist live". Die Laufzeit lädt die neuen
Metadaten nach einer HITL-Freigabe per Hot-Reload.

## Was Sie bereitstellen

Ein Node.js-Prozess pro ObjectOS-Instanz. Das ist alles.

```text
┌─────────────────────────────────────────────────────┐
│ ObjectOS process │
│ ┌───────────────────────────────────────────────┐ │
│ │ HTTP dispatcher (/ · /api · /_console …) │ │
│ ├───────────────────────────────────────────────┤ │
│ │ Per-project ObjectKernel (LRU cached) │ │
│ │ ├─ Auth (Better Auth) │ │
│ │ ├─ Security (RBAC + row-level + field) │ │
│ │ ├─ ObjectQL (data engine, generates SQL) │ │
│ │ ├─ REST API generator │ │
│ │ └─ Capabilities loaded per artifact │ │
│ │ (audit, storage, jobs, queue, AI …) │ │
│ └───────────────────────────────────────────────┘ │
└──────────┬──────────────────────────────────────────┘
Your business database
(Postgres / MySQL / SQLite / Turso / MongoDB)
```

Es hat die Komplexität einer einzigen statisch gelinkten Binärdatei. Kein
Sidecar, kein Kafka, keine separate Cache-Schicht erforderlich. Fügen Sie diese hinzu, wenn Sie
sie brauchen; zahlen Sie nicht am ersten Tag dafür.

## Wo Ihre Daten liegen

| Daten | Liegen in | Verlassen Ihr Netzwerk? |
|---|---|---|
| Geschäftsdatensätze | Ihrer Datenbank | **Nein** |
| Benutzerkonten, Sitzungen, OAuth-Tokens | Ihrer Datenbank | **Nein** |
| Audit-Log | Ihrer Datenbank | **Nein** |
| Einstellungen, API-Schlüssel, Secrets | Ihrer Datenbank / Secret-Manager | **Nein** |
| Hochgeladene Dateien | Ihrer Festplatte oder Ihrem S3/R2-Bucket | **Nein** |
| Die kompilierte App-Definition (`objectstack.json`) | Einer Datei auf der Festplatte oder abgerufen von Ihrer Control Plane | Optional |

ObjectOS telefoniert nicht nach Hause. Keine Telemetrie. Keine Lizenzprüfung. Wenn Sie den
Internetzugang vollständig kappen, läuft es unbegrenzt weiter. Siehe
[Air-gapped](/docs/deploy/air-gapped).

## Wie eine Anfrage bedient wird

```text
1. Ingress / TLS termination (your load balancer)
2. HTTP dispatcher (security headers, request id)
3. Hostname → project resolution (cached, TTL configurable)
4. Get or build per-project kernel from LRU
5. AuthPlugin — session cookie, bearer token, or API key
6. SecurityPlugin — RBAC + row-level + field-level checks
7. Route handler — generated REST, declarative action, or custom
8. Data driver — ObjectQL compiles to SQL / Mongo query
9. Response with X-Request-Id propagated
```

Die Schritte 4–8 werden typischerweise in < 5 ms ausgeführt, sobald der Kernel warm ist.

## Die drei Schichten (nur relevant, wenn Sie integrieren)

Die meisten Kunden stellen nur **ObjectOS** bereit. Die anderen beiden Schichten existieren, falls
Sie wissen möchten, woher das Artefakt stammt:

| Schicht | Was es ist | Wo es läuft |
|---|---|---|
| **Framework** (`@objectstack/*`) | Open-Source-Kernel, ObjectQL, Plugins, Treiber | npm — zur Build-Zeit eingebunden |
| **Control Plane** (optional) | Veröffentlicht kompilierte `objectstack.json`-Artefakte; Sie können die gehostete ObjectStack Cloud nutzen, eine eigene betreiben oder sie ganz weglassen | Ihre CI, unsere Cloud oder Ihr Laptop |
| **ObjectOS** | Die Laufzeit, die Sie betreiben | **Ihre Infrastruktur** |

Wenn Sie eine einzelne App ausliefern, benötigen Sie keine Control Plane —
kompilieren Sie `objectstack.config.ts → dist/objectstack.json` in Ihrer CI und
liefern Sie das JSON im Image aus. Wenn Sie einen internen App-Marketplace
mit vielen Tenants und Apps betreiben, ist die Control Plane der Ort, an dem der
Katalog liegt.

## Boot-Modi

| Modus | Wann | Wie |
|---|---|---|
| **Standalone** | Einzelne App, Entwicklung, Evaluierung, Air-gapped, die meisten Produktionsbereitstellungen | `pnpm dev` oder `dist/objectstack.json` von der Festplatte ausführen |
| **File-backed** | Produktion mit extern verwalteten Artefakten | `OS_ARTIFACT_PATH=/path/to/objectstack.json` setzen |
| **Cloud-connected** | Multi-Tenant- / Multi-App-Bereitstellungen, gespeist von einer Control Plane | `OS_CLOUD_URL` + `OS_CLOUD_API_KEY` setzen |

Der Modus wird automatisch anhand von Umgebungsvariablen erkannt.

## Performance-Eigenschaften

| Metrik | Wert |
|---|---|
| Kaltstart (Prozess hochgefahren, bereit für Traffic) | ~1 Sekunde |
| Kernel-Warmup (erste Anfrage an ein Projekt) | 50–300 ms je nach Capabilities |
| Latenz bei warmer Anfrage (CRUD via REST) | typischerweise < 10 ms + Datenbanklatenz |
| Speicherbedarf | ~150 MB Basis; ~10–30 MB pro aktivem Projekt-Kernel |
| Gleichzeitige Projekte pro Instanz | Begrenzt durch `OS_KERNEL_CACHE_SIZE` (Standard 32) |

## Warum diese Form

- **Ein Node-Prozess, keine Sidecars** → passt in ein `docker run`, passt in eine
systemd-Unit, passt in eine Lambda-ähnliche Umgebung.
- **Per-Projekt-Kernel, LRU-gecacht** → eine Instanz kann viele
kleine Apps bedienen, ohne bei jeder Anfrage die Warmup-Kosten zu tragen.
- **Generierte APIs auf Basis deklarierter Metadaten** → es gibt keinen Codegen-
Schritt in Ihrer CI, kein Client-SDK zum Veröffentlichen; die API entspricht Ihrem Datenmodell konstruktionsbedingt.
- **Alle Capabilities sind optionale Plugins** → die Image-Größe skaliert mit dem,
was Sie tatsächlich nutzen.

## Wie es weitergeht

- [Production Readiness](/docs/operate/production) — Checkliste, bevor
Sie es echtem Traffic aussetzen.
- [Runtime Configuration](/docs/configure/runtime) — Verdrahtung von Datenbanken,
Caches und Secrets.
- [Runtime Capabilities](/docs/reference/runtime-capabilities) —
welche optionalen Pakete existieren und was sie ermöglichen.
Loading
Loading