Initial public push: docs cosmos v4 + AI module + framework groundwork

This is the snapshot the production landing site (nibiru-framework.com) is
deployed from. Brings together the recent splash + docs migration to the v4
"Cosmos" design system, the new in-framework AI module, and the framework
groundwork that backs the framework-reference extraction.

What lands:
- docs/: Astro + Starlight site with the v4 dark cosmic palette, GalaxyHero
  canvas constellation, Mission Control chat (wired to /api/oracle →
  api.neuronetz.ai via providers.mjs Ollama), 5-panel MMVC stage
  (Model · AI · Module · Controller · View), translated EN/DE/JA/ES/FR
  content, PWA + sitemap + llms.txt + Umami analytics.
- docs/design-system/: canonical mockup bundle (source/index-v2.html for
  splash, source/docs-system.html + preview/ for docs, SPEC.md, tokens).
- docs/scripts/extraction/framework-reference-v2.md: deep framework
  reference (~1.6k lines, file:line citations, every public factory and
  idiom — basis for the LoRA training corpus.
- application/module/ai/: AI module with chat / embed / RAG / agent
  plugins, plus pdoQuery / httpGet / fileRead tools and Modelfile +
  smoke-test in training/.
- application/module/users/: user / ACL / form-factory traits used as the
  reference plugin pattern for the framework docs.
- application/settings/config/database/: schema + seed migrations
  including the AI module tables (200–203).
- Form factory + autogenerator changes the framework-reference-v2 covers.

Production secrets stay out: docs/.env, settings.production.ini and
ai.production.ini are all gitignored (.example files are in tree).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
stephan
2026-05-08 15:22:18 +02:00
parent a60ce90643
commit 48c839d927
662 changed files with 172811 additions and 1 deletions

View File

@@ -0,0 +1,61 @@
# Nibiru Atelier — Design System
The visual language of the Nibiru framework. A lotus on cream paper, lit by morning light.
## What's here
| File | Purpose |
|---|---|
| `tokens.json` | Source of truth, [W3C Design Tokens Community Group](https://design-tokens.github.io/community-group/format/) format. |
| `tokens.css` | CSS custom properties, namespaced `--nibiru-*`. |
| `tokens.scss` | SCSS variables and maps. |
| `tailwind.preset.js` | Tailwind preset extending colours, fonts, shadows. |
## Use
### CSS
```html
<link rel="stylesheet"
href="https://nibiru-framework.com/design-system/tokens.css">
<style>
body { background: var(--nibiru-paper); color: var(--nibiru-ink);
font-family: var(--nibiru-font-text); }
h1 { font-variation-settings: var(--nibiru-fv-display-hero);
letter-spacing: var(--nibiru-tracking-display); }
.cta { background: var(--nibiru-ink); color: var(--nibiru-paper);
padding: 0.7rem 1.2rem;
border-radius: var(--nibiru-radius-md); }
</style>
```
### Tailwind
```jsx
<button className="bg-nibiru-ink text-nibiru-paper px-5 py-2 rounded-md font-display tracking-body">
Read the docs
</button>
<h1 className="text-hero text-nibiru-ink tracking-display">
Create. Invent. <em className="text-nibiru-iris-deep">Impress.</em>
</h1>
```
## Full guide
→ <https://nibiru-framework.com/en/design/overview/>
## Versioning
`4.0.0`**Cosmos**. Dark-first AI-framework brand. Magenta-amber-blue nebula
palette on a deep-space body, Space Grotesk display + Inter Tight body +
JetBrains Mono. Light "paper" surfaces still available via `.alt` sections for
content-heavy reading.
`3.0.0`**Atelier × Cosmos**. Reconciles the editorial atelier (paper-and-ink)
with a modern AI-tool dialect: warmer butter page (`#fdf6df`), Geist type,
rounder surfaces (816 px), plus a dark cosmic sub-palette and a code surface
stack for hero / chat / code-card components.
`2.0.0` — Atelier release. Lotus-violet, sky-blue and warm-cream system drawn
from the actual brand mark. Bricolage Grotesque, editorial radii.

View File

@@ -0,0 +1,758 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Documentation page · Nibiru — design mockup</title>
<meta name="description" content="Design mockup for a typical Nibiru documentation page. Layout, type, components and surfaces — built on the v4 Cosmos design system.">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#0a0414">
<!-- Type: Inter Tight (body) + Space Grotesk (display) + JetBrains Mono -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter+Tight:wght@200..800&family=Space+Grotesk:wght@300..700&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
<!-- Canonical Nibiru tokens (also embedded inline below for portability) -->
<link rel="stylesheet" href="./tokens.css">
<style>
/* ============================================================================
* Documentation-page mockup — Nibiru v4 Cosmos
*
* Standalone HTML the designer can open in a browser and riff on. Mirrors
* the production stack (Astro + Starlight) at the visual layer: header on
* top, sidebar nav on the left, article in the middle, on-page TOC on
* the right. Pure CSS, no JS — open it with file:// and it just works.
*
* Hand off: the designer should treat this as the "before" baseline for
* doc pages. The startpage (separate file) sets the brand tone; this
* shows how that tone translates to a content-heavy reading layout.
* ========================================================================= */
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
font-family: 'Inter Tight', ui-sans-serif, system-ui, sans-serif;
background: var(--nibiru-space, #0a0414);
background-image:
radial-gradient(ellipse 70% 50% at 0% 0%, rgba(184, 107, 255, 0.10), transparent 60%),
radial-gradient(ellipse 60% 40% at 100% 0%, rgba(91, 141, 255, 0.07), transparent 60%);
background-attachment: fixed;
color: var(--nibiru-star, #f4eedb);
font-size: 16px;
line-height: 1.55;
font-feature-settings: "ss01", "cv11";
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
}
a { color: inherit; text-decoration: none; }
::selection { background: rgba(184, 107, 255, 0.4); color: var(--nibiru-star, #f4eedb); }
.mono, code, kbd, pre {
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;
}
.display { font-family: 'Space Grotesk', 'Inter Tight', ui-sans-serif, sans-serif; }
/* ============== HEADER ============== */
.doc-header {
position: sticky; top: 0; z-index: 60;
height: 64px;
display: flex; align-items: center;
padding: 0 24px;
background: rgba(6, 3, 15, 0.72);
border-bottom: 1px solid var(--nibiru-line, rgba(244, 238, 219, 0.12));
backdrop-filter: saturate(150%) blur(14px);
-webkit-backdrop-filter: saturate(150%) blur(14px);
}
.doc-header-row {
display: flex; align-items: center; justify-content: space-between;
width: 100%;
gap: 24px;
}
.brand {
display: flex; align-items: center; gap: 10px; flex: none;
font-family: 'Space Grotesk', sans-serif;
}
.brand-mark {
width: 28px; height: 28px;
border-radius: 50%;
background:
radial-gradient(circle at 35% 35%, #f4eedb 0%, #b86bff 40%, #5b8dff 80%, #1c0f3a 100%);
box-shadow: 0 0 12px rgba(184, 107, 255, 0.5);
}
.brand-name {
font-size: 18px; font-weight: 500; letter-spacing: -0.02em;
color: var(--nibiru-star, #f4eedb);
}
.brand-name em { font-style: normal; font-weight: 300; }
.nav-version {
font-family: 'JetBrains Mono', monospace;
font-size: 11px; letter-spacing: 0.04em;
color: var(--nibiru-muted, #6e6680);
padding: 3px 7px;
border: 1px solid var(--nibiru-line, rgba(244, 238, 219, 0.12));
border-radius: 999px;
margin-left: 6px;
display: inline-flex; align-items: center; gap: 6px;
}
.nav-version .dot {
width: 5px; height: 5px; border-radius: 50%;
background: #7ad6a3; box-shadow: 0 0 8px rgba(122, 214, 163, 0.7);
}
.doc-nav {
display: flex; gap: 24px; align-items: center;
flex: 1; justify-content: center;
}
.doc-nav a {
font-size: 14px;
color: rgba(244, 238, 219, 0.7);
transition: color 160ms ease;
}
.doc-nav a:hover, .doc-nav a[aria-current="page"] {
color: var(--nibiru-star, #f4eedb);
}
.search-inline {
display: flex; align-items: center; gap: 10px;
min-width: 220px;
height: 36px;
padding: 0 12px;
background: rgba(244, 238, 219, 0.04);
border: 1px solid var(--nibiru-line, rgba(244, 238, 219, 0.12));
border-radius: 999px;
color: rgba(244, 238, 219, 0.55);
font-size: 13px;
transition: border-color 160ms ease, background-color 160ms ease;
}
.search-inline:hover { border-color: var(--nibiru-line-strong, rgba(244, 238, 219, 0.28)); }
.search-inline svg { width: 14px; height: 14px; flex: none; }
.search-inline kbd {
margin-left: auto;
font-family: 'JetBrains Mono', monospace;
font-size: 11px;
color: var(--nibiru-muted, #6e6680);
padding: 2px 6px;
border: 1px solid var(--nibiru-line, rgba(244, 238, 219, 0.12));
border-radius: 4px;
background: rgba(244, 238, 219, 0.03);
}
.lang-switcher {
display: flex; gap: 4px;
font-family: 'JetBrains Mono', monospace;
font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase;
color: var(--nibiru-muted, #6e6680);
}
.lang-switcher a { padding: 4px 8px; border-radius: 6px; }
.lang-switcher a[aria-current="true"] {
color: var(--nibiru-star, #f4eedb);
background: rgba(184, 107, 255, 0.12);
}
/* ============== LAYOUT SHELL ============== */
.doc-shell {
display: grid;
grid-template-columns: 280px minmax(0, 1fr) 240px;
gap: 0;
max-width: 1400px;
margin: 0 auto;
min-height: calc(100vh - 64px);
}
@media (max-width: 1100px) {
.doc-shell { grid-template-columns: 240px 1fr; }
.doc-toc { display: none; }
}
@media (max-width: 768px) {
.doc-shell { grid-template-columns: 1fr; }
.doc-sidebar { display: none; }
}
/* ============== SIDEBAR ============== */
.doc-sidebar {
position: sticky; top: 64px;
height: calc(100vh - 64px);
overflow-y: auto;
padding: 28px 16px 28px 24px;
border-right: 1px solid var(--nibiru-line, rgba(244, 238, 219, 0.12));
background: rgba(10, 4, 20, 0.4);
backdrop-filter: blur(8px);
font-size: 14px;
scrollbar-width: thin;
scrollbar-color: rgba(184, 107, 255, 0.3) transparent;
}
.doc-sidebar h3 {
font-family: 'JetBrains Mono', monospace;
font-size: 11px; letter-spacing: 0.10em;
text-transform: uppercase;
color: var(--nibiru-muted, #6e6680);
margin: 22px 0 8px;
font-weight: 500;
}
.doc-sidebar h3:first-child { margin-top: 0; }
.doc-sidebar ul {
list-style: none; padding: 0; margin: 0;
display: flex; flex-direction: column; gap: 1px;
}
.doc-sidebar a {
display: block;
padding: 7px 12px;
color: rgba(244, 238, 219, 0.7);
border-left: 1.5px solid transparent;
border-radius: 0 8px 8px 0;
transition: color 160ms ease, border-color 160ms ease, background-color 160ms ease;
}
.doc-sidebar a:hover {
color: var(--nibiru-star, #f4eedb);
border-left-color: var(--nibiru-iris-soft, #d4b4ff);
background: rgba(184, 107, 255, 0.06);
}
.doc-sidebar a[aria-current="page"] {
color: var(--nibiru-star, #f4eedb);
font-weight: 500;
border-left-color: var(--nibiru-nebula-mag, #b86bff);
background: rgba(184, 107, 255, 0.10);
}
/* ============== ARTICLE ============== */
.doc-article {
min-width: 0;
padding: 56px 64px 120px;
max-width: 800px;
margin: 0 auto;
}
@media (max-width: 768px) {
.doc-article { padding: 32px 24px 80px; }
}
.breadcrumbs {
display: flex; align-items: center; gap: 8px;
font-family: 'JetBrains Mono', monospace;
font-size: 12px;
color: var(--nibiru-muted, #6e6680);
margin-bottom: 18px;
flex-wrap: wrap;
}
.breadcrumbs a:hover { color: var(--nibiru-star, #f4eedb); }
.breadcrumbs .sep { color: var(--nibiru-line-strong, rgba(244, 238, 219, 0.28)); }
.doc-article h1 {
font-family: 'Space Grotesk', sans-serif;
font-size: clamp(2rem, 1.5rem + 1.6vw, 2.75rem);
line-height: 1.05;
letter-spacing: -0.04em;
font-weight: 400;
margin: 0 0 18px;
color: var(--nibiru-star, #f4eedb);
}
.doc-article h1 em {
font-style: normal; font-weight: 500;
background: linear-gradient(110deg, #ffb574 0%, #b86bff 70%);
-webkit-background-clip: text; background-clip: text;
-webkit-text-fill-color: transparent;
color: transparent;
}
.doc-lede {
font-size: 1.18rem;
line-height: 1.55;
color: rgba(244, 238, 219, 0.72);
max-width: 56ch;
margin: 0 0 36px;
}
.doc-meta {
display: flex; gap: 28px; align-items: center;
font-family: 'JetBrains Mono', monospace;
font-size: 11px; letter-spacing: 0.06em;
text-transform: uppercase;
color: var(--nibiru-muted, #6e6680);
padding-bottom: 28px;
margin-bottom: 36px;
border-bottom: 1px solid var(--nibiru-line, rgba(244, 238, 219, 0.12));
flex-wrap: wrap;
}
.doc-meta strong { color: rgba(244, 238, 219, 0.85); font-weight: 500; }
.doc-meta .pulse {
width: 6px; height: 6px; border-radius: 50%;
background: #7ad6a3;
box-shadow: 0 0 8px rgba(122, 214, 163, 0.7);
}
.doc-article h2 {
font-family: 'Space Grotesk', sans-serif;
font-size: 1.6rem;
font-weight: 500;
letter-spacing: -0.025em;
line-height: 1.15;
margin: 56px 0 16px;
padding-top: 24px;
border-top: 1px solid var(--nibiru-line, rgba(244, 238, 219, 0.12));
color: var(--nibiru-star, #f4eedb);
}
.doc-article h3 {
font-family: 'Space Grotesk', sans-serif;
font-size: 1.18rem;
font-weight: 500;
letter-spacing: -0.02em;
margin: 36px 0 12px;
color: var(--nibiru-iris-soft, #d4b4ff);
}
.doc-article h4 {
font-family: 'JetBrains Mono', monospace;
font-size: 12px;
letter-spacing: 0.10em;
text-transform: uppercase;
color: var(--nibiru-muted, #6e6680);
margin: 28px 0 10px;
font-weight: 500;
}
.doc-article p {
color: rgba(244, 238, 219, 0.85);
margin: 0 0 18px;
line-height: 1.65;
}
.doc-article strong { color: var(--nibiru-star, #f4eedb); font-weight: 600; }
.doc-article a {
color: var(--nibiru-iris-soft, #d4b4ff);
border-bottom: 1px solid rgba(184, 107, 255, 0.4);
transition: color 200ms ease, border-color 200ms ease;
}
.doc-article a:hover {
color: var(--nibiru-star, #f4eedb);
border-bottom-color: var(--nibiru-nebula-mag, #b86bff);
}
.doc-article ul, .doc-article ol {
margin: 0 0 18px; padding-left: 24px;
}
.doc-article li { margin: 6px 0; color: rgba(244, 238, 219, 0.85); }
/* ============== INLINE CODE ============== */
.doc-article :not(pre) > code {
font-family: 'JetBrains Mono', monospace;
font-size: 0.86em;
background: rgba(184, 107, 255, 0.14);
color: var(--nibiru-iris-soft, #d4b4ff);
padding: 0.05em 0.4em;
border-radius: 6px;
border: 1px solid rgba(184, 107, 255, 0.20);
letter-spacing: 0.04em;
}
/* ============== CODE BLOCK ============== */
.code-block {
background: var(--nibiru-code-bg, #050208);
border: 1px solid var(--nibiru-line-strong, rgba(244, 238, 219, 0.28));
border-radius: 14px;
overflow: hidden;
margin: 22px 0;
box-shadow: 0 30px 60px -30px rgba(0, 0, 0, 0.7);
}
.code-block-head {
display: flex; justify-content: space-between; align-items: center;
padding: 10px 16px;
border-bottom: 1px solid rgba(244, 238, 219, 0.08);
font-family: 'JetBrains Mono', monospace;
font-size: 11px; letter-spacing: 0.10em; text-transform: uppercase;
color: var(--nibiru-muted, #6e6680);
}
.code-block-head .file { color: var(--nibiru-nebula-mag, #b86bff); }
.code-block-head .copy {
background: transparent;
border: 1px solid rgba(244, 238, 219, 0.12);
color: rgba(244, 238, 219, 0.7);
padding: 4px 10px;
border-radius: 6px;
font-family: 'JetBrains Mono', monospace;
font-size: 11px; letter-spacing: 0.10em;
cursor: pointer;
}
.code-block-head .copy:hover { border-color: var(--nibiru-iris-soft, #d4b4ff); color: var(--nibiru-star, #f4eedb); }
.code-block pre {
margin: 0; padding: 18px 20px;
font-family: 'JetBrains Mono', monospace;
font-size: 13px; line-height: 1.7;
color: var(--nibiru-star, #f4eedb);
overflow-x: auto;
}
.tk-c { color: #6e6680; font-style: italic; }
.tk-k { color: #c8a8ff; }
.tk-cls { color: #f0d4ff; }
.tk-fn { color: #b8d4ff; }
.tk-s { color: #ffd9a3; }
.tk-v { color: #ffb4d8; }
.tk-attr { color: #d4baff; }
.tk-n { color: #b8e0c2; }
/* ============== CALLOUT / ASIDE ============== */
.callout {
background: rgba(184, 107, 255, 0.06);
border: 1px solid rgba(244, 238, 219, 0.10);
border-left: 3px solid var(--nibiru-nebula-mag, #b86bff);
padding: 14px 16px 14px 18px;
border-radius: 0 10px 10px 0;
margin: 22px 0;
}
.callout--tip { border-left-color: var(--nibiru-nebula-amber, #ffb574); background: rgba(255, 181, 116, 0.06); }
.callout--danger { border-left-color: #ff8a9d; background: rgba(255, 138, 157, 0.06); }
.callout-title {
font-family: 'JetBrains Mono', monospace;
font-size: 11px; letter-spacing: 0.10em; text-transform: uppercase;
color: var(--nibiru-muted, #6e6680);
margin-bottom: 6px;
font-weight: 500;
}
.callout p { margin: 0; }
/* ============== TABLE ============== */
.doc-article table {
width: 100%;
border-collapse: collapse;
margin: 22px 0;
font-size: 14px;
}
.doc-article thead {
border-bottom: 2px solid var(--nibiru-line-strong, rgba(244, 238, 219, 0.28));
}
.doc-article th {
text-align: left;
padding: 10px 12px 10px 0;
font-family: 'JetBrains Mono', monospace;
font-weight: 500;
font-size: 11px;
letter-spacing: 0.10em;
text-transform: uppercase;
color: var(--nibiru-muted, #6e6680);
}
.doc-article td {
padding: 10px 12px 10px 0;
border-bottom: 1px solid var(--nibiru-line, rgba(244, 238, 219, 0.12));
color: rgba(244, 238, 219, 0.85);
vertical-align: top;
}
/* ============== ON-PAGE TOC (right rail) ============== */
.doc-toc {
position: sticky; top: 64px;
height: calc(100vh - 64px);
overflow-y: auto;
padding: 56px 24px 56px 16px;
border-left: 1px solid var(--nibiru-line, rgba(244, 238, 219, 0.12));
font-size: 13px;
}
.doc-toc h4 {
font-family: 'JetBrains Mono', monospace;
font-size: 11px; letter-spacing: 0.10em;
text-transform: uppercase;
color: var(--nibiru-muted, #6e6680);
margin: 0 0 12px;
font-weight: 500;
}
.doc-toc ul {
list-style: none; padding: 0; margin: 0;
display: flex; flex-direction: column; gap: 4px;
}
.doc-toc a {
color: rgba(244, 238, 219, 0.6);
display: block;
padding: 4px 0;
transition: color 160ms ease;
line-height: 1.4;
}
.doc-toc a:hover { color: var(--nibiru-star, #f4eedb); }
.doc-toc a.active {
color: var(--nibiru-star, #f4eedb);
border-left: 2px solid var(--nibiru-nebula-mag, #b86bff);
margin-left: -10px;
padding-left: 8px;
}
.doc-toc .l2 { padding-left: 12px; font-size: 12px; }
/* ============== PAGE FOOTER (prev / next) ============== */
.page-pagination {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
margin-top: 80px;
padding-top: 36px;
border-top: 1px solid var(--nibiru-line, rgba(244, 238, 219, 0.12));
}
@media (max-width: 600px) {
.page-pagination { grid-template-columns: 1fr; }
}
.page-pagination a {
background: var(--nibiru-night, #120825);
border: 1px solid var(--nibiru-line, rgba(244, 238, 219, 0.12));
border-radius: 14px;
padding: 16px 18px;
transition: border-color 200ms, transform 200ms;
}
.page-pagination a:hover {
border-color: var(--nibiru-nebula-mag, #b86bff);
transform: translateY(-1px);
}
.page-pagination .lbl {
font-family: 'JetBrains Mono', monospace;
font-size: 11px; letter-spacing: 0.10em;
text-transform: uppercase;
color: var(--nibiru-muted, #6e6680);
display: block;
margin-bottom: 4px;
}
.page-pagination .ttl {
font-size: 15px; font-weight: 500;
color: var(--nibiru-star, #f4eedb);
}
.page-pagination .next { text-align: right; }
/* ============== HELP STRIP ============== */
.help-strip {
margin-top: 48px;
padding: 18px 22px;
background: rgba(244, 238, 219, 0.03);
border: 1px solid var(--nibiru-line, rgba(244, 238, 219, 0.12));
border-radius: 12px;
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
flex-wrap: wrap;
font-size: 14px;
}
.help-strip-text { color: rgba(244, 238, 219, 0.75); }
.help-strip-actions { display: flex; gap: 8px; }
.help-strip-actions a {
padding: 7px 14px;
border: 1px solid var(--nibiru-line-strong, rgba(244, 238, 219, 0.28));
border-radius: 999px;
font-size: 13px;
color: rgba(244, 238, 219, 0.85);
transition: color 160ms, border-color 160ms;
border-bottom: 1px solid var(--nibiru-line-strong, rgba(244, 238, 219, 0.28));
}
.help-strip-actions a:hover {
color: var(--nibiru-star, #f4eedb);
border-color: var(--nibiru-iris-soft, #d4b4ff);
}
</style>
</head>
<body>
<!-- ====================== HEADER ====================== -->
<header class="doc-header">
<div class="doc-header-row">
<a class="brand" href="#">
<span class="brand-mark"></span>
<span class="brand-name">Nibiru<em> docs</em></span>
<span class="nav-version"><span class="dot"></span>v0.9.2</span>
</a>
<nav class="doc-nav" aria-label="Primary">
<a href="#" aria-current="page">Docs</a>
<a href="#">MMVC</a>
<a href="#">AI module</a>
<a href="#">CLI</a>
<a href="#">Showcase</a>
</nav>
<div class="doc-header-tools" style="display: flex; align-items: center; gap: 12px;">
<div class="search-inline" role="search">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="7"/><path d="m21 21-3-3"/></svg>
<span>Search the docs</span>
<kbd>⌘ K</kbd>
</div>
<div class="lang-switcher" aria-label="Language">
<a href="#" aria-current="true">EN</a>
<a href="#">DE</a>
<a href="#">JA</a>
<a href="#">ES</a>
<a href="#">FR</a>
</div>
</div>
</div>
</header>
<!-- ====================== SHELL ====================== -->
<div class="doc-shell">
<!-- ====== SIDEBAR ====== -->
<aside class="doc-sidebar" aria-label="Section navigation">
<h3>Get started</h3>
<ul>
<li><a href="#">What is Nibiru?</a></li>
<li><a href="#">Installation</a></li>
<li><a href="#">Quick start</a></li>
<li><a href="#" aria-current="page">Project structure</a></li>
<li><a href="#">Run it locally</a></li>
<li><a href="#">Deployment</a></li>
</ul>
<h3>The framework</h3>
<ul>
<li><a href="#">Architecture (MMVC)</a></li>
<li><a href="#">Bootstrap &amp; Dispatcher</a></li>
<li><a href="#">Routing</a></li>
<li><a href="#">Controllers</a></li>
<li><a href="#">Views &amp; Smarty</a></li>
<li><a href="#">Models</a></li>
<li><a href="#">Modules</a></li>
<li><a href="#">Forms</a></li>
<li><a href="#">Database &amp; Migrations</a></li>
<li><a href="#">Auth</a></li>
</ul>
<h3>AI in Nibiru</h3>
<ul>
<li><a href="#">The AI module</a></li>
<li><a href="#">Chat plugin</a></li>
<li><a href="#">Embed plugin</a></li>
<li><a href="#">RAG plugin</a></li>
<li><a href="#">Agent plugin</a></li>
<li><a href="#">Ask the Oracle</a></li>
</ul>
</aside>
<!-- ====== ARTICLE ====== -->
<main class="doc-article">
<nav class="breadcrumbs" aria-label="Breadcrumb">
<a href="#">Docs</a>
<span class="sep">/</span>
<a href="#">Get started</a>
<span class="sep">/</span>
<span>Project structure</span>
</nav>
<h1>Project <em>structure</em></h1>
<p class="doc-lede">Where Nibiru puts things, and why. The shape on disk maps to the four MMVC roles — read top-down and the framework will explain itself.</p>
<div class="doc-meta">
<span><span class="pulse"></span> <strong>Stable</strong> · v0.9.2</span>
<span>Updated <strong>2 days ago</strong></span>
<span>Reading time <strong>~ 6 min</strong></span>
<span>Edit on <strong>GitHub</strong></span>
</div>
<p>A fresh Nibiru install is just a Composer-managed PHP project with a single CLI binary, an <code>application/</code> tree for your code, and a <code>core/</code> tree for the framework itself. Everything else — Smarty's compiled templates, the public docroot, the migrations history — falls out of those four conventions.</p>
<h2 id="overview">Overview</h2>
<p>Open the repo and you'll see this:</p>
<div class="code-block">
<div class="code-block-head">
<span class="file">tree.txt</span>
<button class="copy" type="button">Copy</button>
</div>
<pre><span class="tk-c"># A Nibiru project, top level</span>
my-app/
├── application/ <span class="tk-c">// your code lives here</span>
│ ├── controller/
│ ├── module/
│ ├── view/
│ └── settings/
├── core/ <span class="tk-c">// the framework — don't edit</span>
├── public/ <span class="tk-c">// docroot — point your vhost here</span>
├── nibiru <span class="tk-c">// the CLI binary</span>
├── composer.json
└── index.php <span class="tk-c">// front controller</span></pre>
</div>
<h3 id="application">application/</h3>
<p>Your code. Each role in <strong>MMVC</strong> is its own subdirectory: <code>controller/</code>, <code>module/</code>, <code>view/</code>. The fourth — Models — live inside their own <code>module/&lt;name&gt;/models/</code> subtrees, because in MMVC every module owns the data shape it touches.</p>
<div class="callout callout--tip">
<div class="callout-title">Tip</div>
<p>Run <code>./nibiru -c products</code> and the CLI will scaffold the controller, the module, the navigation entry and a Smarty template into the right places automatically.</p>
</div>
<h3 id="core">core/</h3>
<p>The framework itself. <strong>Don't edit it.</strong> If you find yourself reaching in here, the answer is almost always to extend a class in <code>application/</code> instead. The single exception: <a href="#">contributing back</a>.</p>
<h3 id="public">public/</h3>
<p>Your vhost docroot. Static assets are served directly from this directory; everything else falls through to the front controller via <code>index.php</code>. The <code>.htaccess</code> in the project root takes care of rewrites for Apache; the included <a href="#"><code>vhost.conf</code></a> shows the equivalent for nginx.</p>
<h2 id="naming">Naming conventions</h2>
<p>Every controller is <code>&lt;name&gt;Controller.php</code>, every module sits at <code>application/module/&lt;name&gt;/</code>, every Smarty template lives at <code>application/view/templates/&lt;name&gt;.tpl</code>. The CLI enforces this — you don't have to remember it.</p>
<table>
<thead>
<tr>
<th>Path</th>
<th>Created by</th>
<th>Owns</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>application/controller/</code></td>
<td><code>./nibiru -c &lt;name&gt;</code></td>
<td>Routing, dispatch, lifecycle</td>
</tr>
<tr>
<td><code>application/module/</code></td>
<td><code>./nibiru -m &lt;name&gt;</code></td>
<td>Capabilities, plugins, models</td>
</tr>
<tr>
<td><code>application/view/templates/</code></td>
<td>scaffolded with controller</td>
<td>Smarty 3 templates</td>
</tr>
<tr>
<td><code>application/settings/migrations/</code></td>
<td><code>./nibiru -mi-add &lt;n&gt;</code></td>
<td>Timestamped SQL migrations</td>
</tr>
</tbody>
</table>
<div class="callout">
<div class="callout-title">Note</div>
<p>Smarty templates compile to <code>application/view/templates_c/</code> at first request. That directory is gitignored — clear it with <code>./nibiru -cache-clear</code> if a template ever sticks.</p>
</div>
<h2 id="next">Next</h2>
<p>You know where things go. Now wire one up — the <a href="#">Quick start</a> takes you from an empty project to a running controller in five commands.</p>
<!-- prev / next -->
<nav class="page-pagination" aria-label="Page navigation">
<a class="prev" href="#">
<span class="lbl">← Previous</span>
<span class="ttl">Quick start</span>
</a>
<a class="next" href="#">
<span class="lbl">Next →</span>
<span class="ttl">Run it locally</span>
</a>
</nav>
<!-- help strip -->
<aside class="help-strip">
<span class="help-strip-text">Was this page helpful?</span>
<div class="help-strip-actions">
<a href="#">Yes</a>
<a href="#">Suggest an edit</a>
</div>
</aside>
</main>
<!-- ====== ON-PAGE TOC ====== -->
<aside class="doc-toc" aria-label="On this page">
<h4>On this page</h4>
<ul>
<li><a href="#overview" class="active">Overview</a></li>
<li><a href="#application" class="l2">application/</a></li>
<li><a href="#core" class="l2">core/</a></li>
<li><a href="#public" class="l2">public/</a></li>
<li><a href="#naming">Naming conventions</a></li>
<li><a href="#next">Next</a></li>
</ul>
<h4 style="margin-top: 36px;">Notes</h4>
<p style="font-size: 12px; color: var(--nibiru-muted, #6e6680); line-height: 1.5;">
This is a design mockup, not a real docs page. The TOC scroll-spy, search modal,
and language-switcher are wired-up in the production Astro/Starlight build —
treat the visual elements here as the brief.
</p>
</aside>
</div>
</body>
</html>

View File

@@ -0,0 +1,108 @@
/**
* Nibiru Design System — v4.0.0 Tailwind Preset
*
* // tailwind.config.js
* module.exports = {
* presets: [require('@nibiru/design-system/tailwind.preset')],
* content: ['./src/**\/*.{html,js,ts,jsx,tsx,vue,astro}'],
* };
*/
module.exports = {
theme: {
extend: {
colors: {
nibiru: {
void: '#06030f',
space: '#0a0414',
night: '#120825',
plum: '#1c0f3a',
'nebula-mag': '#b86bff',
'nebula-blue': '#5b8dff',
'nebula-amber': '#ffb574',
iris: '#b86bff',
'iris-deep': '#8a3fd0',
'iris-soft': '#d4b4ff',
skyfall: '#5b8dff',
'skyfall-deep': '#3a6ad0',
'skyfall-soft': '#a8c0ff',
aurum: '#ffb574',
star: '#f4eedb',
paper: '#f4eedb',
'paper-2': '#ebe3c8',
mist: '#f8f3e2',
ink: '#0a0414',
'ink-2': '#2a2438',
'ink-deep': '#06030f',
'ink-faint': '#6e6680',
muted: '#6e6680',
success: '#7ad6a3',
rose: '#ff8a9d',
'code-bg': '#050208',
'code-text': '#f4eedb',
},
},
fontFamily: {
display: ['"Inter Tight"', 'ui-sans-serif', 'system-ui', 'sans-serif'],
sans: ['"Inter Tight"', 'ui-sans-serif', 'system-ui', 'sans-serif'],
mono: ['"JetBrains Mono"', 'ui-monospace', '"SF Mono"', 'Menlo', 'monospace'],
},
fontSize: {
hero: ['clamp(3.5rem, 7vw + 0.5rem, 7.75rem)', { lineHeight: '0.95', letterSpacing: '-0.04em' }],
section: ['clamp(2.5rem, 4vw + 0.5rem, 5rem)', { lineHeight: '1.02', letterSpacing: '-0.03em' }],
},
letterSpacing: {
display: '-0.04em',
heading: '-0.03em',
body: '-0.005em',
mono: '0.04em',
label: '0.10em',
eyebrow: '0.18em',
},
borderRadius: {
sm: '6px',
md: '10px',
lg: '14px',
xl: '18px',
'2xl':'22px',
pill: '999px',
},
boxShadow: {
'nibiru-sm': '0 1px 2px rgba(0, 0, 0, 0.20)',
'nibiru-md': '0 8px 24px -8px rgba(0, 0, 0, 0.40)',
'nibiru-lg': '0 30px 60px -30px rgba(0, 0, 0, 0.7)',
'nibiru-xl': '0 60px 120px -40px rgba(0, 0, 0, 0.7)',
'nibiru-cosmos': '0 60px 120px -40px rgba(0, 0, 0, 0.7), 0 0 0 1px rgba(184, 107, 255, 0.06) inset',
'nibiru-glow-mag': '0 0 24px rgba(184, 107, 255, 0.45)',
'nibiru-glow-amb': '0 0 24px rgba(255, 181, 116, 0.45)',
'nibiru-glow-blue':'0 0 24px rgba(91, 141, 255, 0.45)',
},
backgroundImage: {
'iris-to-sky': 'linear-gradient(135deg, #b86bff 0%, #5b8dff 100%)',
'headline': 'linear-gradient(110deg, #ffb574 0%, #b86bff 50%, #5b8dff 100%)',
'accent': 'linear-gradient(110deg, #ffb574, #b86bff 70%)',
'accent-light': 'linear-gradient(110deg, #b46500, #5b1f9e 70%)',
'nebula': 'radial-gradient(120% 90% at 50% 20%, #2a2156 0%, #1a1442 24%, #0e0a2a 52%, #06050f 82%), linear-gradient(180deg, #06050f 0%, #07060f 100%)',
'mmvc-stage': 'radial-gradient(ellipse at 50% 50%, #1c0f3a, #0a0414 60%)',
},
animation: {
'tele-pulse': 'nibiru-tele-pulse 2.4s ease-in-out infinite',
blink: 'nibiru-blink 1s steps(1) infinite',
breathe: 'nibiru-breathe 18s ease-in-out infinite',
},
keyframes: {
'nibiru-tele-pulse': {
'0%, 100%': { opacity: '0.5', transform: 'scale(0.85)' },
'50%': { opacity: '1', transform: 'scale(1.15)' },
},
'nibiru-blink': {
'50%': { opacity: '0' },
},
'nibiru-breathe': {
'0%, 100%': { transform: 'translateY(0) rotate(0deg)' },
'50%': { transform: 'translateY(-6px) rotate(0.6deg)' },
},
},
},
},
};

View File

@@ -0,0 +1,177 @@
/**
* Nibiru Design System — v4.0.0 "Cosmos"
*
* Canonical source of truth for the brand. Imported globally by the site
* (see astro.config.mjs `customCss`) and published verbatim at
* https://nibiru-framework.com/design-system/tokens.css
*
* v4 is dark-first: the page lives in space, headlines glow magenta-amber,
* the lotus mark is the star at the centre. Light "paper" surfaces are
* available via .alt sections for content-heavy reading.
*
* All tokens namespaced --nibiru-* so they coexist with other systems.
*/
:root {
/* === Cosmos surfaces (dark-first page) === */
--nibiru-void: #06030f; /* deepest, used for chat/code panes */
--nibiru-space: #0a0414; /* the page background */
--nibiru-night: #120825; /* card surface on dark */
--nibiru-plum: #1c0f3a; /* MMVC stage glow base */
/* === Nebula brand colours (the petals, retuned) === */
--nibiru-nebula-mag: #b86bff; /* primary brand — magenta */
--nibiru-nebula-blue: #5b8dff;
--nibiru-nebula-amber:#ffb574;
/* Legacy aliases — same role, mapped to new hexes */
--nibiru-iris: #b86bff;
--nibiru-iris-deep: #8a3fd0;
--nibiru-iris-soft: #d4b4ff;
--nibiru-skyfall: #5b8dff;
--nibiru-skyfall-deep:#3a6ad0;
--nibiru-skyfall-soft:#a8c0ff;
--nibiru-aurum: #ffb574; /* warm amber, brighter than v3 */
--nibiru-aurum-soft: #ffd0a3;
/* === Light "paper" surfaces (for .alt sections) === */
--nibiru-star: #f4eedb; /* the cream — also used as text on dark */
--nibiru-paper: #f4eedb;
--nibiru-paper-2: #ebe3c8;
--nibiru-bg: #f4eedb; /* legacy alias for content cards */
--nibiru-bg-2: #ebe3c8;
--nibiru-mist: #f8f3e2;
--nibiru-lavender: #ece6f3;
--nibiru-lavender-deep:#ddd3eb;
/* === Ink (text on light surfaces) === */
--nibiru-ink: #0a0414; /* deeper than v3, matches space */
--nibiru-ink-2: #2a2438;
--nibiru-ink-deep: #06030f;
--nibiru-ink-soft: #4a4258; /* legacy */
--nibiru-ink-faint: #6e6680;
--nibiru-muted: #6e6680;
/* === Hairlines === */
--nibiru-line: rgba(244, 238, 219, 0.12); /* on dark surfaces */
--nibiru-line-strong: rgba(244, 238, 219, 0.28); /* hover / focus */
--nibiru-line-light: rgba(20, 4, 30, 0.10); /* on light surfaces */
--nibiru-line-2: rgba(20, 4, 30, 0.18);
--nibiru-grid: rgba(244, 238, 219, 0.04); /* faint grid overlay */
/* === Status / accents === */
--nibiru-success: #7ad6a3;
--nibiru-rose: #ff8a9d;
--nibiru-moss: #94a96e;
/* === Code surface === */
--nibiru-code-bg: #050208;
--nibiru-code-line: rgba(244, 238, 219, 0.08);
--nibiru-code-text: #f4eedb;
--nibiru-code-mute: #6e6680;
/* === Twilight (legacy dark theme — kept for Starlight compatibility) === */
--nibiru-dark-bg: #0a0414;
--nibiru-dark-surface: #120825;
--nibiru-dark-surface-raised:#1c0f3a;
--nibiru-dark-ink: #f4eedb;
--nibiru-dark-ink-soft: #c5bfd1;
--nibiru-dark-ink-faint: #6e6680;
/* === Gradients === */
--nibiru-gradient-headline:
linear-gradient(110deg, #ffb574 0%, #b86bff 50%, #5b8dff 100%);
--nibiru-gradient-accent:
linear-gradient(110deg, #ffb574 0%, #b86bff 70%);
--nibiru-gradient-accent-light:
linear-gradient(110deg, #b46500 0%, #5b1f9e 70%);
--nibiru-gradient-iris-to-sky:
linear-gradient(135deg, #b86bff 0%, #5b8dff 100%);
--nibiru-gradient-nebula:
radial-gradient(120% 90% at 50% 20%, #2a2156 0%, #1a1442 24%, #0e0a2a 52%, #06050f 82%),
linear-gradient(180deg, #06050f 0%, #07060f 100%);
--nibiru-gradient-mmvc-stage:
radial-gradient(ellipse at 50% 50%, #1c0f3a, #0a0414 60%);
--nibiru-gradient-lotus-wash:
radial-gradient(ellipse 80% 50% at 0% 0%, rgba(184, 107, 255, 0.10), transparent 60%),
radial-gradient(ellipse 60% 40% at 100% 0%, rgba(91, 141, 255, 0.10), transparent 60%);
/* === Shadows === */
--nibiru-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.20);
--nibiru-shadow-md: 0 8px 24px -8px rgba(0, 0, 0, 0.40);
--nibiru-shadow-lg: 0 30px 60px -30px rgba(0, 0, 0, 0.7);
--nibiru-shadow-xl: 0 60px 120px -40px rgba(0, 0, 0, 0.7);
--nibiru-shadow-cosmos: 0 60px 120px -40px rgba(0, 0, 0, 0.7),
0 0 0 1px rgba(184, 107, 255, 0.06) inset;
--nibiru-shadow-glow-mag: 0 0 24px rgba(184, 107, 255, 0.45);
--nibiru-shadow-glow-amb: 0 0 24px rgba(255, 181, 116, 0.45);
--nibiru-shadow-glow-blue:0 0 24px rgba(91, 141, 255, 0.45);
/* === Typography === */
--nibiru-font-text: 'Inter Tight', ui-sans-serif, system-ui, -apple-system, sans-serif;
--nibiru-font-display: 'Inter Tight', ui-sans-serif, system-ui, sans-serif;
--nibiru-font-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;
/* Legacy alias — the v3 components reference --nibiru-font-text */
--nibiru-font-body: var(--nibiru-font-text);
/* Weights */
--nibiru-weight-light: 300;
--nibiru-weight-regular: 400;
--nibiru-weight-medium: 500;
--nibiru-weight-semibold: 600;
--nibiru-weight-bold: 700;
/* Letter-spacing */
--nibiru-tracking-display: -0.04em;
--nibiru-tracking-heading: -0.03em;
--nibiru-tracking-body: -0.005em;
--nibiru-tracking-mono: 0.04em;
--nibiru-tracking-label: 0.10em;
--nibiru-tracking-eyebrow: 0.18em;
/* Type scale */
--nibiru-text-xs: 0.69rem; /* 11px */
--nibiru-text-sm: 0.81rem; /* 13px */
--nibiru-text-md: 0.875rem; /* 14px */
--nibiru-text-base: 1rem; /* 16px — body */
--nibiru-text-lg: 1.125rem; /* 18px */
--nibiru-text-xl: 1.25rem; /* 20px */
--nibiru-text-2xl: 1.5rem;
--nibiru-text-3xl: 2rem;
--nibiru-text-section: clamp(2.5rem, 4vw + 0.5rem, 5rem); /* 40-80 */
--nibiru-text-hero: clamp(3.5rem, 7vw + 0.5rem, 7.75rem); /* 56-124 */
/* === Radii === */
--nibiru-radius-sm: 6px;
--nibiru-radius-md: 10px;
--nibiru-radius-lg: 14px;
--nibiru-radius-xl: 18px;
--nibiru-radius-2xl: 22px;
--nibiru-radius-pill: 999px;
/* === Spacing === */
--nibiru-space-0: 0;
--nibiru-space-1: 0.25rem;
--nibiru-space-2: 0.5rem;
--nibiru-space-3: 0.75rem;
--nibiru-space-4: 1rem;
--nibiru-space-5: 1.5rem;
--nibiru-space-6: 2rem;
--nibiru-space-8: 3rem;
--nibiru-space-10: 4rem;
--nibiru-space-12: 6rem;
--nibiru-space-section: 10rem;
--nibiru-container: 1280px;
--nibiru-content: 50rem;
/* === Motion === */
--nibiru-duration-fast: 160ms;
--nibiru-duration-normal: 240ms;
--nibiru-duration-slow: 500ms;
--nibiru-duration-pulse: 2.4s;
--nibiru-duration-blink: 1s;
--nibiru-duration-breathe: 18s;
--nibiru-ease-out: cubic-bezier(0.2, 0.7, 0.2, 1);
--nibiru-ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
}

View File

@@ -0,0 +1,153 @@
{
"$schema": "https://design-tokens.github.io/community-group/format/",
"name": "Nibiru Design System",
"version": "4.0.0",
"description": "Cosmos — dark-first AI-framework brand. Magenta-amber-blue nebula on a deep-space body, all-sans (Inter Tight body + display) + JetBrains Mono. Light paper surfaces available via .alt sections for content-heavy reading.",
"color": {
"void": { "$value": "#06030f", "$type": "color", "$description": "Deepest. Used for chat / code panes." },
"space": { "$value": "#0a0414", "$type": "color", "$description": "Page background. The site lives here." },
"night": { "$value": "#120825", "$type": "color", "$description": "Card / panel surface on dark." },
"plum": { "$value": "#1c0f3a", "$type": "color", "$description": "MMVC-stage glow base." },
"nebulaMag": { "$value": "#b86bff", "$type": "color", "$description": "Primary brand — electric magenta. Replaces v3 iris." },
"nebulaBlue": { "$value": "#5b8dff", "$type": "color", "$description": "Cool counterpoint. Replaces v3 skyfall." },
"nebulaAmber": { "$value": "#ffb574", "$type": "color", "$description": "Warm accent. Replaces v3 aurum." },
"iris": { "$value": "#b86bff", "$type": "color" },
"irisDeep": { "$value": "#8a3fd0", "$type": "color" },
"irisSoft": { "$value": "#d4b4ff", "$type": "color" },
"skyfall": { "$value": "#5b8dff", "$type": "color" },
"skyfallDeep": { "$value": "#3a6ad0", "$type": "color" },
"skyfallSoft": { "$value": "#a8c0ff", "$type": "color" },
"aurum": { "$value": "#ffb574", "$type": "color" },
"star": { "$value": "#f4eedb", "$type": "color", "$description": "Body text on dark surfaces. Also used as light paper." },
"paper": { "$value": "#f4eedb", "$type": "color", "$description": "Light surface for .alt sections." },
"paper2": { "$value": "#ebe3c8", "$type": "color" },
"mist": { "$value": "#f8f3e2", "$type": "color" },
"lavender": { "$value": "#ece6f3", "$type": "color" },
"lavenderDeep": { "$value": "#ddd3eb", "$type": "color" },
"ink": { "$value": "#0a0414", "$type": "color", "$description": "Text on light. Same as space — deliberate." },
"ink2": { "$value": "#2a2438", "$type": "color" },
"inkDeep": { "$value": "#06030f", "$type": "color" },
"inkFaint": { "$value": "#6e6680", "$type": "color" },
"muted": { "$value": "#6e6680", "$type": "color" },
"success": { "$value": "#7ad6a3", "$type": "color" },
"rose": { "$value": "#ff8a9d", "$type": "color" },
"moss": { "$value": "#94a96e", "$type": "color" }
},
"line": {
"default": { "$value": "rgba(244, 238, 219, 0.12)", "$type": "color", "$description": "Hairline on dark." },
"strong": { "$value": "rgba(244, 238, 219, 0.28)", "$type": "color", "$description": "Hover / focus on dark." },
"light": { "$value": "rgba(20, 4, 30, 0.10)", "$type": "color", "$description": "Hairline on light." },
"lightStrong": { "$value": "rgba(20, 4, 30, 0.18)", "$type": "color" },
"grid": { "$value": "rgba(244, 238, 219, 0.04)", "$type": "color", "$description": "Faint grid overlay." }
},
"code": {
"bg": { "$value": "#050208", "$type": "color" },
"line": { "$value": "rgba(244, 238, 219, 0.08)", "$type": "color" },
"text": { "$value": "#f4eedb", "$type": "color" },
"mute": { "$value": "#6e6680", "$type": "color" }
},
"gradient": {
"headline": { "$value": "linear-gradient(110deg, #ffb574 0%, #b86bff 50%, #5b8dff 100%)", "$type": "gradient", "$description": "Hero accent <em> — amber→magenta→blue." },
"accent": { "$value": "linear-gradient(110deg, #ffb574, #b86bff 70%)", "$type": "gradient", "$description": "Section title accent on dark." },
"accentLight": { "$value": "linear-gradient(110deg, #b46500, #5b1f9e 70%)", "$type": "gradient", "$description": "Section title accent on light (.alt)." },
"irisToSky": { "$value": "linear-gradient(135deg, #b86bff 0%, #5b8dff 100%)", "$type": "gradient" },
"nebula": { "$value": "radial-gradient(120% 90% at 50% 20%, #2a2156 0%, #1a1442 24%, #0e0a2a 52%, #06050f 82%), linear-gradient(180deg, #06050f 0%, #07060f 100%)", "$type": "gradient" },
"mmvcStage": { "$value": "radial-gradient(ellipse at 50% 50%, #1c0f3a, #0a0414 60%)", "$type": "gradient" },
"lotusWash": { "$value": "radial-gradient(ellipse 80% 50% at 0% 0%, rgba(184,107,255,0.10), transparent 60%), radial-gradient(ellipse 60% 40% at 100% 0%, rgba(91,141,255,0.10), transparent 60%)", "$type": "gradient" }
},
"shadow": {
"sm": { "$value": "0 1px 2px rgba(0, 0, 0, 0.20)", "$type": "shadow" },
"md": { "$value": "0 8px 24px -8px rgba(0, 0, 0, 0.40)", "$type": "shadow" },
"lg": { "$value": "0 30px 60px -30px rgba(0, 0, 0, 0.7)", "$type": "shadow" },
"xl": { "$value": "0 60px 120px -40px rgba(0, 0, 0, 0.7)", "$type": "shadow" },
"cosmos": { "$value": "0 60px 120px -40px rgba(0, 0, 0, 0.7), 0 0 0 1px rgba(184, 107, 255, 0.06) inset", "$type": "shadow" },
"glowMag": { "$value": "0 0 24px rgba(184, 107, 255, 0.45)", "$type": "shadow" },
"glowAmber":{ "$value": "0 0 24px rgba(255, 181, 116, 0.45)", "$type": "shadow" },
"glowBlue": { "$value": "0 0 24px rgba(91, 141, 255, 0.45)", "$type": "shadow" }
},
"font": {
"text": { "$value": "'Inter Tight', ui-sans-serif, system-ui, -apple-system, sans-serif", "$type": "fontFamily" },
"display": { "$value": "'Inter Tight', ui-sans-serif, system-ui, sans-serif", "$type": "fontFamily" },
"mono": { "$value": "'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace", "$type": "fontFamily" }
},
"weight": {
"light": { "$value": 300, "$type": "fontWeight" },
"regular": { "$value": 400, "$type": "fontWeight" },
"medium": { "$value": 500, "$type": "fontWeight" },
"semibold": { "$value": 600, "$type": "fontWeight" },
"bold": { "$value": 700, "$type": "fontWeight" }
},
"letterSpacing": {
"display": { "$value": "-0.04em", "$type": "dimension" },
"heading": { "$value": "-0.03em", "$type": "dimension" },
"body": { "$value": "-0.005em", "$type": "dimension" },
"mono": { "$value": "0.04em", "$type": "dimension" },
"label": { "$value": "0.10em", "$type": "dimension" },
"eyebrow": { "$value": "0.18em", "$type": "dimension" }
},
"fontSize": {
"xs": { "$value": "0.69rem", "$type": "dimension" },
"sm": { "$value": "0.81rem", "$type": "dimension" },
"md": { "$value": "0.875rem", "$type": "dimension" },
"base": { "$value": "1rem", "$type": "dimension" },
"lg": { "$value": "1.125rem", "$type": "dimension" },
"xl": { "$value": "1.25rem", "$type": "dimension" },
"2xl": { "$value": "1.5rem", "$type": "dimension" },
"3xl": { "$value": "2rem", "$type": "dimension" },
"section": { "$value": "clamp(2.5rem, 4vw + 0.5rem, 5rem)", "$type": "dimension" },
"hero": { "$value": "clamp(3.5rem, 7vw + 0.5rem, 7.75rem)", "$type": "dimension" }
},
"radius": {
"sm": { "$value": "6px", "$type": "dimension" },
"md": { "$value": "10px", "$type": "dimension" },
"lg": { "$value": "14px", "$type": "dimension" },
"xl": { "$value": "18px", "$type": "dimension" },
"2xl": { "$value": "22px", "$type": "dimension" },
"pill": { "$value": "999px", "$type": "dimension" }
},
"space": {
"0": { "$value": "0", "$type": "dimension" },
"1": { "$value": "0.25rem", "$type": "dimension" },
"2": { "$value": "0.5rem", "$type": "dimension" },
"3": { "$value": "0.75rem", "$type": "dimension" },
"4": { "$value": "1rem", "$type": "dimension" },
"5": { "$value": "1.5rem", "$type": "dimension" },
"6": { "$value": "2rem", "$type": "dimension" },
"8": { "$value": "3rem", "$type": "dimension" },
"10": { "$value": "4rem", "$type": "dimension" },
"12": { "$value": "6rem", "$type": "dimension" },
"section": { "$value": "10rem", "$type": "dimension" },
"container":{ "$value": "1280px", "$type": "dimension" },
"content": { "$value": "50rem", "$type": "dimension" }
},
"motion": {
"fast": { "$value": "160ms", "$type": "duration" },
"normal": { "$value": "240ms", "$type": "duration" },
"slow": { "$value": "500ms", "$type": "duration" },
"pulse": { "$value": "2.4s", "$type": "duration" },
"blink": { "$value": "1s", "$type": "duration" },
"breathe": { "$value": "18s", "$type": "duration" }
},
"ease": {
"out": { "$value": "cubic-bezier(0.2, 0.7, 0.2, 1)", "$type": "cubicBezier" },
"spring": { "$value": "cubic-bezier(0.34, 1.56, 0.64, 1)", "$type": "cubicBezier" }
}
}

View File

@@ -0,0 +1,120 @@
// Nibiru Design System — v4.0.0 "Cosmos" (SCSS)
// === Cosmos surfaces ===
$void: #06030f;
$space: #0a0414;
$night: #120825;
$plum: #1c0f3a;
// === Nebula brand ===
$nebula-mag: #b86bff;
$nebula-blue: #5b8dff;
$nebula-amber: #ffb574;
// Legacy aliases retuned to v4
$iris: #b86bff;
$iris-deep: #8a3fd0;
$iris-soft: #d4b4ff;
$skyfall: #5b8dff;
$skyfall-deep: #3a6ad0;
$skyfall-soft: #a8c0ff;
$aurum: #ffb574;
// === Light surfaces ===
$star: #f4eedb;
$paper: #f4eedb;
$paper-2: #ebe3c8;
$bg: #f4eedb;
$bg-2: #ebe3c8;
$mist: #f8f3e2;
$lavender: #ece6f3;
$lavender-deep:#ddd3eb;
// === Ink ===
$ink: #0a0414;
$ink-2: #2a2438;
$ink-deep: #06030f;
$ink-soft: #4a4258;
$ink-faint: #6e6680;
$muted: #6e6680;
// === Hairlines ===
$line: rgba(244, 238, 219, 0.12);
$line-strong: rgba(244, 238, 219, 0.28);
$line-light: rgba(20, 4, 30, 0.10);
$line-2: rgba(20, 4, 30, 0.18);
$grid: rgba(244, 238, 219, 0.04);
// === Status ===
$success: #7ad6a3;
$rose: #ff8a9d;
$moss: #94a96e;
// === Code surface ===
$code-bg: #050208;
$code-line: rgba(244, 238, 219, 0.08);
$code-text: #f4eedb;
$code-mute: #6e6680;
// === Twilight ===
$dark-bg: #0a0414;
$dark-surface: #120825;
$dark-surface-raised: #1c0f3a;
// === Typography ===
$font-text: ('Inter Tight', ui-sans-serif, system-ui, -apple-system, sans-serif);
$font-display: ('Inter Tight', ui-sans-serif, system-ui, sans-serif);
$font-mono: ('JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace);
$weight: (
light: 300, regular: 400, medium: 500, semibold: 600, bold: 700,
);
$tracking: (
display: -0.04em, heading: -0.03em, body: -0.005em,
mono: 0.04em, label: 0.10em, eyebrow: 0.18em,
);
$text: (
xs: 0.69rem,
sm: 0.81rem,
md: 0.875rem,
base: 1rem,
lg: 1.125rem,
xl: 1.25rem,
2xl: 1.5rem,
3xl: 2rem,
section: clamp(2.5rem, 4vw + 0.5rem, 5rem),
hero: clamp(3.5rem, 7vw + 0.5rem, 7.75rem),
);
// === Radii ===
$radius: (
sm: 6px, md: 10px, lg: 14px, xl: 18px, 2xl: 22px, pill: 999px,
);
// === Spacing ===
$space-scale: (
0: 0, 1: 0.25rem, 2: 0.5rem, 3: 0.75rem, 4: 1rem,
5: 1.5rem, 6: 2rem, 8: 3rem, 10: 4rem, 12: 6rem,
section: 10rem,
);
// === Motion ===
$duration: (
fast: 160ms, normal: 240ms, slow: 500ms,
pulse: 2.4s, blink: 1s, breathe: 18s,
);
$ease: (
out: cubic-bezier(0.2, 0.7, 0.2, 1),
spring: cubic-bezier(0.34, 1.56, 0.64, 1),
);
// === Shadows ===
$shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.20);
$shadow-md: 0 8px 24px -8px rgba(0, 0, 0, 0.40);
$shadow-lg: 0 30px 60px -30px rgba(0, 0, 0, 0.7);
$shadow-xl: 0 60px 120px -40px rgba(0, 0, 0, 0.7);
$shadow-cosmos: 0 60px 120px -40px rgba(0, 0, 0, 0.7),
0 0 0 1px rgba(184, 107, 255, 0.06) inset;
$shadow-glow-mag: 0 0 24px rgba(184, 107, 255, 0.45);
$shadow-glow-amb: 0 0 24px rgba(255, 181, 116, 0.45);
$shadow-glow-blue: 0 0 24px rgba(91, 141, 255, 0.45);

8
docs/public/favicon.svg Normal file
View File

@@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
<rect width="64" height="64" rx="8" fill="#f5f1e8"/>
<path d="M32 12 C 29 22, 29 36, 32 46 C 35 36, 35 22, 32 12 Z" fill="#5e548c"/>
<path d="M22 18 C 17 26, 19 38, 28 44 C 30 36, 28 24, 22 18 Z" fill="#7c70ab"/>
<path d="M42 18 C 47 26, 45 38, 36 44 C 34 36, 36 24, 42 18 Z" fill="#7c70ab"/>
<path d="M12 24 C 9 32, 14 42, 24 46 C 22 38, 18 28, 12 24 Z" fill="#7db7dc"/>
<path d="M52 24 C 55 32, 50 42, 40 46 C 42 38, 46 28, 52 24 Z" fill="#7db7dc"/>
</svg>

After

Width:  |  Height:  |  Size: 532 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

View File

@@ -0,0 +1,91 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 760" role="img" aria-label="Request lifecycle: Browser → index.php → framework.php → Dispatcher → Router/Modules/Autoloader → applicationController.php (navigationAction → action → pageAction) → Smarty render.">
<defs>
<linearGradient id="lc-box" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#faf7f0"/>
<stop offset="100%" stop-color="#ece6f3"/>
</linearGradient>
<linearGradient id="lc-box-strong" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#ece6f3"/>
<stop offset="100%" stop-color="#ddd3eb"/>
</linearGradient>
<marker id="lc-arrow" viewBox="0 0 12 12" refX="10" refY="6" markerWidth="9" markerHeight="9" orient="auto-start-reverse">
<path d="M0 0 L12 6 L0 12 Z" fill="#7c70ab"/>
</marker>
<filter id="lc-shadow" x="-10%" y="-10%" width="120%" height="120%">
<feDropShadow dx="0" dy="2" stdDeviation="3" flood-color="#5e548c" flood-opacity="0.18"/>
</filter>
</defs>
<g fill="none" stroke="#7c70ab" stroke-width="1.6" marker-end="url(#lc-arrow)">
<path d="M360 70 L360 100"/>
<path d="M360 160 L360 192"/>
<path d="M360 252 L360 284"/>
<path d="M360 344 L360 360 L150 360 L150 388"/>
<path d="M360 360 L360 388"/>
<path d="M360 360 L570 360 L570 388"/>
<path d="M360 448 L360 488"/>
<path d="M360 638 L360 670"/>
</g>
<g font-family="'JetBrains Mono', monospace" font-size="11" fill="#847b94">
<text x="370" y="86">HTTP</text>
<text x="370" y="178">require</text>
<text x="370" y="270">boots framework</text>
<text x="370" y="660">View::assign(…)</text>
</g>
<g font-family="'Bricolage Grotesque','Inter',sans-serif" font-weight="600" font-size="15" fill="#1f1b2e">
<g filter="url(#lc-shadow)">
<rect x="290" y="20" width="140" height="50" rx="4" fill="url(#lc-box)" stroke="#b6adcd"/>
<text x="360" y="51" text-anchor="middle">Browser</text>
</g>
<g filter="url(#lc-shadow)">
<rect x="290" y="110" width="140" height="50" rx="4" fill="url(#lc-box)" stroke="#b6adcd"/>
<text x="360" y="141" text-anchor="middle" font-family="'JetBrains Mono',monospace">index.php</text>
</g>
<g filter="url(#lc-shadow)">
<rect x="270" y="202" width="180" height="50" rx="4" fill="url(#lc-box)" stroke="#b6adcd"/>
<text x="360" y="233" text-anchor="middle" font-family="'JetBrains Mono',monospace">core/framework.php</text>
</g>
<g filter="url(#lc-shadow)">
<rect x="280" y="294" width="160" height="50" rx="4" fill="url(#lc-box-strong)" stroke="#7c70ab"/>
<text x="360" y="319" text-anchor="middle">Dispatcher</text>
<text x="360" y="335" text-anchor="middle" font-family="'JetBrains Mono',monospace" font-weight="400" font-size="11" fill="#5e548c">::run()</text>
</g>
<g filter="url(#lc-shadow)">
<rect x="90" y="388" width="120" height="60" rx="4" fill="url(#lc-box)" stroke="#b6adcd"/>
<text x="150" y="415" text-anchor="middle">Router</text>
<text x="150" y="432" text-anchor="middle" font-family="'JetBrains Mono',monospace" font-weight="400" font-size="11" fill="#5e548c">::route()</text>
</g>
<g filter="url(#lc-shadow)">
<rect x="300" y="388" width="120" height="60" rx="4" fill="url(#lc-box)" stroke="#b6adcd"/>
<text x="360" y="415" text-anchor="middle">Modules</text>
<text x="360" y="432" text-anchor="middle" font-family="'JetBrains Mono',monospace" font-weight="400" font-size="11" fill="#5e548c">Registry</text>
</g>
<g filter="url(#lc-shadow)">
<rect x="510" y="388" width="120" height="60" rx="4" fill="url(#lc-box)" stroke="#b6adcd"/>
<text x="570" y="415" text-anchor="middle">Autoloader</text>
<text x="570" y="432" text-anchor="middle" font-family="'JetBrains Mono',monospace" font-weight="400" font-size="11" fill="#5e548c">models + modules</text>
</g>
<g filter="url(#lc-shadow)">
<rect x="200" y="488" width="320" height="150" rx="4" fill="url(#lc-box-strong)" stroke="#7c70ab"/>
<text x="360" y="513" text-anchor="middle" font-family="'JetBrains Mono',monospace">applicationController.php</text>
<line x1="220" y1="525" x2="500" y2="525" stroke="#b6adcd" stroke-width="1"/>
<text x="360" y="550" text-anchor="middle" font-family="'JetBrains Mono',monospace" font-weight="400" font-size="13" fill="#4a4258">navigationAction()</text>
<text x="360" y="580" text-anchor="middle" font-family="'JetBrains Mono',monospace" font-weight="400" font-size="13" fill="#4a4258">&lt;_action&gt;Action()</text>
<text x="360" y="610" text-anchor="middle" font-family="'JetBrains Mono',monospace" font-weight="400" font-size="13" fill="#4a4258">pageAction()</text>
</g>
<g filter="url(#lc-shadow)">
<rect x="270" y="680" width="180" height="60" rx="4" fill="url(#lc-box)" stroke="#7db7dc"/>
<text x="360" y="708" text-anchor="middle">Smarty</text>
<text x="360" y="725" text-anchor="middle" font-family="'JetBrains Mono',monospace" font-weight="400" font-size="11" fill="#4a8fb7">templates/&lt;ctrl&gt;.tpl + shared/*</text>
</g>
</g>
<g font-family="'Bricolage Grotesque',sans-serif" font-size="12" fill="#4a4258">
<line x1="450" y1="227" x2="490" y2="227" stroke="#7c70ab" stroke-width="1.4" marker-end="url(#lc-arrow)" stroke-dasharray="3 3"/>
<text x="498" y="220">boots Config, Router, Engine,</text>
<text x="498" y="237">Smarty, all 28 form types,</text>
<text x="498" y="254">DB drivers, Auth.</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
docs/public/img/pwa-192.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

BIN
docs/public/img/pwa-512.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

File diff suppressed because it is too large Load Diff

6
docs/public/js/three.min.js vendored Normal file

File diff suppressed because one or more lines are too long

67
docs/public/llms.txt Normal file
View File

@@ -0,0 +1,67 @@
# Nibiru
> A modular MMVC PHP framework for rapid prototyping. Adds a second M ("Module") to the classic MVC pattern. Ships with multi-database support (MySQL, PDO, PostgreSQL, ODBC), a Smarty view layer, a fluent form factory, a numbered-SQL migration runner, a CLI scaffold tool, and a first-class AI module with chat, embeddings, RAG, and agents wired to local Ollama.
This site is the official documentation for the Nibiru framework. All content is freely available for reading, indexing, training, retrieval-augmented generation, and citation. License: BSD-4-Clause.
## Get started
- [What is Nibiru?](https://nibiru-framework.com/en/start/what-is-nibiru/): 90-second tour. Explains MMVC, the request lifecycle, and who the framework is for.
- [Installation](https://nibiru-framework.com/en/start/installation/): Clone, install dependencies, set permissions, run the first migration.
- [Quick Start](https://nibiru-framework.com/en/start/quick-start/): Build a minimal Products page in five minutes — controller, view, navigation entry.
- [Project Structure](https://nibiru-framework.com/en/start/structure/): Every directory in a Nibiru project explained.
- [Run It Locally](https://nibiru-framework.com/en/start/local-testing/): Three paths from clone to running site, including the Oracle on local Ollama.
- [Deployment](https://nibiru-framework.com/en/start/deployment/): Production with jwilder/nginx-proxy and self-hosted Ollama.
## The framework
- [Architecture (MMVC)](https://nibiru-framework.com/en/core/architecture/): How modules, controllers, views, models, and the registry orbit each other.
- [Bootstrap & Dispatcher](https://nibiru-framework.com/en/core/dispatcher/): Request lifecycle from index.php through the Dispatcher to the controller.
- [Routing](https://nibiru-framework.com/en/core/routing/): URL convention, SEO URL form, custom regex routes.
- [Controllers](https://nibiru-framework.com/en/core/controllers/): pageAction, navigationAction, custom actions, View::assign.
- [Views & Smarty](https://nibiru-framework.com/en/core/views/): Template resolution, partials, caching.
- [Models](https://nibiru-framework.com/en/core/models/): Schema-first auto-generated models from the database.
- [Modules](https://nibiru-framework.com/en/core/modules/): The second M in MMVC. Traits, plugins, interfaces, settings, observers.
- [Forms](https://nibiru-framework.com/en/core/forms/): The fluent form factory with 28 field types.
- [Database & Migrations](https://nibiru-framework.com/en/core/database/): Five drivers behind a unified Db adapter; numbered SQL migrations.
- [Auth](https://nibiru-framework.com/en/core/auth/): Session-based authentication and the Users module.
- [Config & Settings](https://nibiru-framework.com/en/core/config/): Environment-based INI files and the Registry.
- [Pagination](https://nibiru-framework.com/en/core/pagination/): URL-driven pagination with template helpers.
- [Registry](https://nibiru-framework.com/en/core/registry/): Auto-discovery and caching of module configs.
## CLI
- [The Nibiru CLI](https://nibiru-framework.com/en/cli/overview/): Every flag of the ./nibiru binary.
- [Modules & Controllers](https://nibiru-framework.com/en/cli/scaffolding/): Scaffold modules, controllers, plugins.
- [Migrations](https://nibiru-framework.com/en/cli/migrations/): Numbered SQL migrations, idempotency, reset commands.
- [CMS Pages](https://nibiru-framework.com/en/cli/cms/): Create and delete CMS pages from the command line.
## AI in Nibiru
- [The AI module](https://nibiru-framework.com/en/ai/module/overview/): Chat, embeddings, RAG, agents — first-class AI for Nibiru apps.
- [Chat plugin](https://nibiru-framework.com/en/ai/module/chat/): Single- or multi-turn chat completions.
- [Embed plugin](https://nibiru-framework.com/en/ai/module/embed/): Text-to-vector with cosine similarity helpers.
- [RAG plugin](https://nibiru-framework.com/en/ai/module/rag/): Ingest, retrieve, ground.
- [Agent plugin](https://nibiru-framework.com/en/ai/module/agent/): ReAct-style tool-using agents.
- [Training nibiru-coder](https://nibiru-framework.com/en/ai/module/training/): Register a Nibiru-flavoured model on Ollama.
- [Ask the Oracle](https://nibiru-framework.com/en/ai/oracle/): The in-site RAG chat UI.
- [Training corpus (LoRA)](https://nibiru-framework.com/en/ai/corpus/): Export the docs as JSONL for fine-tuning.
- [AI Roadmap](https://nibiru-framework.com/en/ai/roadmap/): Where the framework's AI integration is going.
## In production
- [Real-world projects](https://nibiru-framework.com/en/showcase/projects/): Apps running on Nibiru — TPMS, Maschinen Stockert, bowatech.lu.
- [Patterns from production](https://nibiru-framework.com/en/showcase/patterns/): Copy-paste-ready patterns extracted from shipping codebases.
## Design system
- [The Atelier design system](https://nibiru-framework.com/en/design/overview/): Visual language, exported as portable design tokens.
- [Palette](https://nibiru-framework.com/en/design/palette/): Every Nibiru colour with its role.
- [Typography](https://nibiru-framework.com/en/design/typography/): Bricolage Grotesque, used in earnest.
- [Components](https://nibiru-framework.com/en/design/components/): Buttons, cards, callouts, the Oracle launcher.
- [Motion](https://nibiru-framework.com/en/design/motion/): Slow, deliberate, never shouts.
## Optional
- [GitHub repository](https://github.com/alllinux/Nibiru): Source code, issue tracker, releases.
- [Sitemap](https://nibiru-framework.com/sitemap-index.xml): Full machine-readable URL list for all locales (en, de, ja, es, fr).

View File

@@ -0,0 +1,9 @@
{
"provider": null,
"model": null,
"dim": 0,
"builtAt": null,
"reason": "Ollama embeddings 404: {\"error\":\"model \\\"nomic-embed-text\\\" not found, try pulling it first\"}",
"chunks": [],
"embeddings": []
}

118
docs/public/robots.txt Normal file
View File

@@ -0,0 +1,118 @@
# =============================================================================
# robots.txt for nibiru-framework.com
#
# Policy: open. We want every search engine, every AI training crawler,
# every retrieval/RAG agent to be able to read these docs. The whole point
# of publishing this site is so that humans AND models can learn Nibiru.
#
# Wildcard rule below allows everything; AI-specific bots are listed
# explicitly so their operators can verify they are welcome here.
# =============================================================================
# ── Search engines ──────────────────────────────────────────────────────────
User-agent: Googlebot
Allow: /
User-agent: Bingbot
Allow: /
User-agent: DuckDuckBot
Allow: /
User-agent: Yandexbot
Allow: /
User-agent: Baiduspider
Allow: /
# ── AI training / search crawlers — explicitly welcomed ─────────────────────
# OpenAI
User-agent: GPTBot
Allow: /
User-agent: ChatGPT-User
Allow: /
User-agent: OAI-SearchBot
Allow: /
# Anthropic
User-agent: ClaudeBot
Allow: /
User-agent: Claude-Web
Allow: /
User-agent: anthropic-ai
Allow: /
# Google AI training
User-agent: Google-Extended
Allow: /
# Apple AI training
User-agent: Applebot-Extended
Allow: /
User-agent: Applebot
Allow: /
# Meta
User-agent: meta-externalagent
Allow: /
User-agent: FacebookBot
Allow: /
# Perplexity
User-agent: PerplexityBot
Allow: /
User-agent: Perplexity-User
Allow: /
# Other AI / LLM crawlers
User-agent: YouBot
Allow: /
User-agent: Bytespider
Allow: /
User-agent: Amazonbot
Allow: /
User-agent: Diffbot
Allow: /
User-agent: cohere-ai
Allow: /
User-agent: cohere-training-data-crawler
Allow: /
User-agent: Mistral-AI-User
Allow: /
User-agent: omgili
Allow: /
User-agent: omgilibot
Allow: /
# Common Crawl — the dataset most LLMs train on
User-agent: CCBot
Allow: /
# Internet Archive
User-agent: ia_archiver
Allow: /
# ── Default policy: allow everything ───────────────────────────────────────
User-agent: *
Allow: /
# Don't index or crawl the SSR API endpoint — it's not content.
Disallow: /api/
# ── Sitemaps ───────────────────────────────────────────────────────────────
Sitemap: https://nibiru-framework.com/sitemap-index.xml