diff --git a/.gitignore b/.gitignore index 8efce08a7..f6c428691 100644 --- a/.gitignore +++ b/.gitignore @@ -52,6 +52,7 @@ website/static/api/ # Generated from docs/ by website/scripts/generate-llms-full.sh, which runs as the # prebuild step of every site build. Committing it only lets it drift. website/static/llms-full.txt +website/static/docs/ ### Maven ### # Machine-local heap tuning for the reactor. Maven reads it automatically, so a diff --git a/README.md b/README.md index 9df5cd0ef..20402755a 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ [![Kotlin 2.0+](https://img.shields.io/badge/Kotlin-2.0%2B-purple)](https://kotlinlang.org/) [![Java 21](https://img.shields.io/badge/Java-21-blue)](https://openjdk.org/projects/jdk/21/) -**Storm is the type-safe, SQL-first ORM for Kotlin 2.0+ and Java 21.** Immutable data-class entities, one-line queries checked at compile time, and none of the machinery you fight in traditional ORMs: no proxies, no N+1, no persistence context. +**Storm is the type-safe, SQL-first ORM for Kotlin 2.0+ and Java 21, built for agentic coding and performance.** Immutable data-class entities, one-line queries checked at compile time, and none of the machinery you fight in traditional ORMs: no proxies, no N+1, no persistence context. ```kotlin // An entity is a data class. This is the whole mapping. @@ -27,7 +27,7 @@ interface UserRepository : EntityRepository { } ``` -The `city` graph loads in a single query, and `User_` is generated at compile time so a typo is a compile error. What you write is what runs. +The `city` graph loads in a single query, and `User_` is generated at compile time so a typo is a compile error. What you write is what runs, which is also what makes Storm work so well with coding agents: the data class is the whole model, so the agent has the exact details it needs. Set your agent up with `npx @storm-orm/cli init` ([Agentic Coding](#agentic-coding)). ## Why Storm @@ -179,16 +179,20 @@ Both paths add the metamodel processor, which generates the `User_` and `City_` With the BOM imported, add Storm modules without specifying versions. -## AI-Assisted Development +## Agentic Coding -Storm's stateless, immutable model is a natural fit for AI coding tools: what you see in the source is exactly what runs, with no proxies, lazy loading, or hidden persistence-context rules to trip up generated code. An optional workflow gives AI tools full schema awareness through a local MCP server, guides them with Storm-specific skills, and closes the loop by verifying generated entities and queries with real tests rather than trusting model reasoning. +A coding agent is only as right as what it can read. In Storm the data class is the table, its keys and its relations, every database call is a visible line of code, and the domain model already gives one-line, type-safe queries across relations. There are no proxies, no lazy loading and no persistence context, so the code the agent reads is exactly what runs. + +One command sets your agent up: ```bash -npm install -g @storm-orm/cli -storm init +npx @storm-orm/cli init # in your project: rules, skills and schema access +npx @storm-orm/cli demo # in an empty directory: your agent builds a demo app on Storm ``` -See [AI-Assisted Development](docs/ai.md) for the full workflow. +It installs Storm's rules and skills for Claude Code, Cursor, GitHub Copilot, Windsurf and Codex. An existing `CLAUDE.md` or rules file keeps its content; Storm adds its own marked block. Optionally it sets up an MCP server that runs on your machine and is read-only: the agent sees your schema, never your credentials, and sees data only if you allow it. The agent then checks its own work with `validateSchema()` and `SqlCapture`. + +See [Agentic Coding](docs/ai.md) for the full workflow. ## Examples diff --git a/docs/ai-reference.md b/docs/ai-reference.md index fbd85ade3..1948a8ac5 100644 --- a/docs/ai-reference.md +++ b/docs/ai-reference.md @@ -1,6 +1,6 @@ # AI Tools Reference -This page lists the configuration locations, skills, and database skills that Storm installs for each AI coding tool. For the main guide, see [AI-Assisted Development](ai.md). +This page lists the configuration locations, skills, and database skills that Storm installs for each AI coding tool. For the main guide, see [Agentic Coding](ai.md). --- diff --git a/docs/ai.md b/docs/ai.md index 7e3e5b483..213f64705 100644 --- a/docs/ai.md +++ b/docs/ai.md @@ -1,29 +1,41 @@ -# AI-Assisted Development +# Agentic Coding import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -Storm is an AI-first ORM. Entities are plain Kotlin data classes or Java records. Queries are explicit SQL. Built-in verification lets AI validate its own work before anything touches production. +Storm is built for agentic coding. A coding agent is only as right as what it can read, and in Storm every detail lives in the model: your data classes define the tables, keys and relations, and the queries follow from them. Underneath is a thin layer over JDBC, so nothing sits between the model and the database. -:::info AI-first, not AI-only -Storm keeps you in control. `ORMTemplate.validateSchema()` validates that entities match the database. `SqlCapture` validates that queries match the intent. `@StormTest` runs both checks in an isolated in-memory database before anything reaches production. The AI generates code, then Storm verifies it. That is what AI-first means here. +- **What you see is what runs.** No proxies, no lazy loading, no persistence context, no flush. An entity is a value, and every database call is a visible line of code. +- **All in one place.** One data class is the table, its keys and its relations. There is no second table definition beside it and no session state deciding at runtime what a field holds. The agent reads one file and has the full picture. +- **Queries come from the domain.** The entities already give one-line, type-safe queries across relations, with the whole entity graph loaded in one statement. There is less for the agent to write, and fewer joins and mappings to get wrong. + +Good for your agent, good for you: the same properties that make Storm code easy to generate correctly make it easy to review. On top of that, Storm gives the agent its conventions (rules and skills), your schema (a local, read-only MCP server), and a way to check its own work (`validateSchema()` and `SqlCapture`). + +:::info You stay in control +`ORMTemplate.validateSchema()` validates that entities match the database. `SqlCapture` validates that queries match the intent. `@StormTest` runs both checks in an isolated in-memory database before anything reaches production. The agent generates code, then Storm verifies it. ::: --- ## Quick Setup -Install the Storm CLI and run it in your project: +Run the Storm CLI from the root of your project. Nothing to install first: ```bash -npm install -g @storm-orm/cli -storm init +npx @storm-orm/cli init ``` -Or without installing globally: +Starting from an empty directory instead? `demo` creates a Kotlin project and installs a skill that guides your agent to build a small web application on Storm, using the public IMDB dataset: ```bash -npx @storm-orm/cli init +npx @storm-orm/cli demo +``` + +If you will use the CLI again, for `storm update` (refresh rules and skills), `storm db` (manage database connections) or `storm mcp` (manage a project's MCP servers), install it globally: + +```bash +npm install -g @storm-orm/cli +storm init ``` The interactive setup walks you through three steps: @@ -36,13 +48,13 @@ Choose which AI coding tools you use. Storm configures each one with rules, skil For each selected tool, Storm installs two types of AI context: -**Rules** are a project-level configuration file that is always loaded by the AI tool. They contain Storm's key patterns, naming conventions, and critical constraints (immutable QueryBuilder, no collection fields on entities, `Ref` for circular references, etc.). The rules ensure the AI follows Storm's conventions in every interaction, without you having to repeat them. +**Rules** are a project-level configuration file that is always loaded by the AI tool. When the file already exists (an existing `CLAUDE.md`, for example), its content is kept: Storm adds its rules as a marked block, and later runs replace only that block. They contain Storm's key patterns, naming conventions, and critical constraints (immutable QueryBuilder, no collection fields on entities, `Ref` for circular references, etc.). The rules ensure the AI follows Storm's conventions in every interaction, without you having to repeat them. **Skills** are per-topic guides that the AI loads on demand when working on a specific task. Each skill contains focused instructions, code examples, and common pitfalls for one area of Storm (entities, queries, repositories, migrations, JSON, serialization, and more). Skills are fetched from orm.st during setup and can be updated automatically on each run without requiring a CLI update. See [AI Tools Reference](ai-reference.md#skills) for the full list. ### 3. Database connection (optional) -If you have a local development database running, Storm can set up a schema-aware MCP server. This gives your AI tool access to your actual database structure (table definitions, column types, foreign keys) without exposing credentials or data. +If you have a local development database running, Storm can set up a schema-aware MCP server. This gives your AI tool access to your actual database structure (table definitions, column types, foreign keys) without exposing credentials or data. The server runs on your machine and is read-only: it cannot write, modify or delete anything. The MCP server runs locally on your machine, exposes only schema metadata by default, and stores credentials in `~/.storm/` (outside your project, outside the LLM's reach). It supports PostgreSQL, MySQL, MariaDB, Oracle, SQL Server, SQLite, and H2. You can connect multiple databases to a single project, even across different database types. @@ -95,11 +107,11 @@ Most AI coding tools support adding context through URLs or pasted text. Point y --- -## Why Storm Works Well With AI +## Why Storm Works Well With Agents -AI works better when framework behavior is explicit and visible in source code. +Agents work better when framework behavior is explicit and visible in source code. -Traditional ORMs rely on mechanisms that are powerful but implicit: proxy objects that intercept field access, lazy loading that triggers queries at unpredictable moments, persistence contexts that track entity state across transaction boundaries, and cascading rules that propagate changes through the object graph. These features serve real purposes, but they make AI-assisted development harder. The AI has to account for behavior that does not appear in the code. Code that compiles and looks correct can still break at runtime because of invisible framework state. +Traditional ORMs rely on mechanisms that are powerful but implicit: proxy objects that intercept field access, lazy loading that triggers queries at unpredictable moments, persistence contexts that track entity state across transaction boundaries, and cascading rules that propagate changes through the object graph. These features serve real purposes, but they make agentic coding harder. The AI has to account for behavior that does not appear in the code. Code that compiles and looks correct can still break at runtime because of invisible framework state. Storm eliminates all of that. Entities are plain Kotlin data classes or Java records. There are no proxies, no managed state, no persistence context, and no transparent lazy loading: deferred loading is explicit, through `Ref`. Queries are explicit, and what you see in the source code is exactly what happens at runtime. This makes Storm's behavior predictable for AI tools: the code is the complete picture. @@ -112,7 +124,7 @@ The design choices that matter most: - **Compile-time metamodel.** Type errors caught at build time, not at runtime. The AI gets immediate feedback. - **Secure schema access.** The MCP server gives AI tools structural database knowledge without exposing credentials. Data access is opt-in, read-only by construction, and enforced at the database driver level. -Beyond the data model, Storm provides dedicated tooling for AI-assisted workflows: +Beyond the data model, Storm provides dedicated tooling for agentic workflows: - **Skills** guide AI tools through specific tasks (entity creation, queries, repositories, migrations) with framework-aware conventions and rules. - **A locally running MCP server** gives AI tools access to your live database schema: table definitions, column types, constraints, and foreign keys. Optionally, the AI can also query individual records (read-only) when sample data would improve type decisions. The AI can inspect your actual database structure to generate entities that match, or validate entities it just created. @@ -305,9 +317,9 @@ You can also ask the AI to keep the test as a permanent regression test. The cho --- -## The Gold Standard: Verify, Then Trust +## Verify, Then Trust -This is what makes Storm the gold standard for AI-assisted database development. The AI does not just generate code and hope for the best. It generates code, then validates it through Storm's own verification, before anything is committed. +The AI does not just generate code and hope for the best. It generates code, then validates it through Storm's own verification, before anything is committed. | Task | AI generates | Storm verifies | |------|-------------|-------------------| diff --git a/docs/getting-started.md b/docs/getting-started.md index eb79b71d5..e1e463cb1 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -1,7 +1,7 @@ --- title: Set Up Your Project sidebar_label: Set Up Your Project -description: "Wire Storm into a project you intend to keep: prerequisites, the four setup routes, and how to verify the result." +description: "Wire Storm into a project you intend to keep: prerequisites, the four setup routes (fastest with a coding agent), and how to verify the result." --- import Tabs from '@theme/Tabs'; @@ -9,7 +9,7 @@ import TabItem from '@theme/TabItem'; # Set Up Your Project -This page is about getting Storm into a real project: what it needs from your toolchain, which of the four setup routes fits your situation, and how to prove the wiring works before you write application code. +This page is about getting Storm into a real project: what it needs from your toolchain, which of the four setup routes fits your situation, and how to prove the wiring works before you write application code. If you work with a coding agent, the fastest route is to let it do the wiring: one command gives it everything it needs. :::tip Just want to see it work? The **[Quickstart](/quickstart)** takes about five minutes, needs no database server, and ends with a working query and the SQL it generated. It is the fastest way to judge Storm, and it is the recommended first stop. Come back here when you are setting up a project you intend to keep. @@ -31,10 +31,35 @@ The JDK 21 pin is a property of the platform, not of Storm: the Java API is buil ## Choose a Setup Route -All four routes end at the same place: a project with the Storm dependencies, the metamodel processor, and the Kotlin compiler plugin wired up. +All four routes end at the same place: a project with the Storm dependencies, the metamodel processor, and the Kotlin compiler plugin wired up. With a coding agent, the agent does this for you; the other three routes are the same setup by hand. - + + +### Setup with a coding agent (fastest) + +If you work with a coding agent (Claude Code, Cursor, GitHub Copilot, Windsurf, or Codex), let it do the wiring. Run one command from the root of your project: + +```bash +npx @storm-orm/cli init +``` + +It installs Storm's rules and skills for your agent, so the agent knows the conventions, the build setup for Gradle and Maven, and the common pitfalls. An existing `CLAUDE.md` or rules file keeps its content: Storm adds its own marked block. Optionally, it connects a schema-aware MCP server to your development database. That server runs on your machine and is read-only: the agent sees your schema, never your credentials, and sees data only if you allow it. + +Then ask the agent for what you need, for example: + +- *"Add Storm to this project with the Gradle plugin and the PostgreSQL dialect."* +- *"Generate Storm entities for the `customer` and `order` tables, and validate them against the schema."* +- *"Write a repository method that finds a customer's open orders, and show me the SQL it runs."* + +Storm entities carry every detail in the model, so the agent has what it needs to act, and it can check its own work: `validateSchema()` confirms the entities match the database, and `SqlCapture` shows the SQL a query really runs. + +Starting from an empty directory instead? `npx @storm-orm/cli demo` creates a Kotlin project and has your agent build a small web application on Storm. + +See [Agentic Coding](ai.md) for the full workflow and [Database Connections & MCP](database-and-mcp.md) for the schema-aware server. + + + ### Gradle plugin (recommended for Kotlin) @@ -85,21 +110,6 @@ Each starter template is a GitHub template repository holding one vertical slice What each one contains is on the [starter templates page](/templates/). The [example projects](/examples/) are a different thing: complete applications on the public IMDB dataset, written to be read and run rather than started from. - - - -### AI-assisted setup - -If you work with an AI coding tool (Claude Code, Cursor, GitHub Copilot, Windsurf, or Codex), one command installs Storm's rules and skills for it and can connect it to your development database: - -```bash -npx @storm-orm/cli init -``` - -The tool can then add the dependencies, generate entities from your existing tables, and write repository methods. It has Storm's documentation and, with the MCP server configured, your real schema. - -See [AI-Assisted Development](ai.md) for the full setup and [Database and MCP](database-and-mcp.md) for the schema-aware server. - diff --git a/docs/index.md b/docs/index.md index 89749c009..e496e87d4 100644 --- a/docs/index.md +++ b/docs/index.md @@ -8,7 +8,7 @@ import TabItem from '@theme/TabItem'; # Storm -**Storm** is an ORM for Kotlin 2.0+ and Java 21, built on a SQL template engine. Entities are plain immutable data classes and records, queries are checked at compile time, and every database call is explicit: no proxies, no persistence context, no accidental N+1 queries. +**Storm** is an ORM for Kotlin 2.0+ and Java 21, built for agentic coding and performance on a SQL template engine. Entities are plain immutable data classes and records, queries are checked at compile time, and every database call is explicit: no proxies, no persistence context, no accidental N+1 queries. ## Start Here @@ -16,6 +16,7 @@ import TabItem from '@theme/TabItem'; |----------------|-------| | See Storm work end to end, in five minutes | **[Quickstart](/quickstart)** | | Add Storm to a project you already have | [Set Up Your Project](getting-started.md) | +| Work with a coding agent (Claude Code, Cursor, Copilot, Windsurf, Codex) | [Agentic Coding](ai.md): `npx @storm-orm/cli init` | | Understand the model before writing code | [Entities](entities.md), then [Queries](queries.md) | | Decide whether to adopt it | [Evaluating for Production](#evaluating-for-production) | @@ -169,7 +170,7 @@ To talk the evaluation through with the engineers behind Storm, write to [hello@ Storm is focused on being a great ORM and SQL template engine. It intentionally does not include: -- **Schema migration or DDL generation.** Storm does not automatically create, alter, or drop tables at runtime. With Storm's [AI integration](ai.md), your coding assistant can read your database schema and generate Flyway or Liquibase migration scripts on demand. For schema versioning, use [Flyway](https://flywaydb.org/) or [Liquibase](https://www.liquibase.com/). +- **Schema migration or DDL generation.** Storm does not automatically create, alter, or drop tables at runtime. With Storm's [agentic coding support](ai.md), your coding agent can read your database schema and generate Flyway or Liquibase migration scripts on demand. For schema versioning, use [Flyway](https://flywaydb.org/) or [Liquibase](https://www.liquibase.com/). - **Second-level cache.** Storm's entity cache is transaction-scoped and cleared on commit. For cross-transaction caching, use Spring's `@Cacheable` or a dedicated cache layer like Caffeine or Redis. - **Lazy loading proxies.** Entities are plain records with no proxies. Related entities are loaded eagerly in a single query via JOINs. For deferred loading, use [Refs](refs.md) to explicitly control when related data is fetched. @@ -186,17 +187,17 @@ See [Database Dialects](dialects.md) for installation and configuration details. - Kotlin 2.0+ (JDK 21 or later), or Java on JDK 21 exactly (the Java API uses preview class files, which are version-locked) - Maven 3.9+ or Gradle 8+ -## AI-Assisted Development +## Agentic Coding -Storm's stateless, immutable entities mean what you see in the source code is exactly what exists at runtime: no hidden proxies, no lazy loading surprises, no persistence context rules that trip up generated code. When you ask an AI tool to write a query, define an entity, or build a repository, the output is straightforward data classes and explicit SQL. +Storm is built for agentic coding. What you see in the source code is exactly what runs: no hidden proxies, no lazy loading surprises, no persistence context rules that trip up generated code. One data class is the table, its keys and its relations, and the domain model already gives one-line, type-safe queries, so your agent has the exact details it needs and less to write. -One command configures your tool (Claude Code, Cursor, Copilot, Windsurf, or Codex) with Storm's rules, skills, and slash commands, and can connect it to your development database for schema-aware generation: +One command configures your tool (Claude Code, Cursor, Copilot, Windsurf, or Codex) with Storm's rules, skills, and slash commands, and can connect it to your development database through a local, read-only MCP server for schema-aware generation: ```bash npx @storm-orm/cli init ``` -See [AI-Assisted Development](ai.md) for the full setup, and [Database and MCP](database-and-mcp.md) for the schema-aware server. +See [Agentic Coding](ai.md) for the full setup, and [Database and MCP](database-and-mcp.md) for the schema-aware server. ## Glossary diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts index 6b8b27889..4208e7870 100644 --- a/website/docusaurus.config.ts +++ b/website/docusaurus.config.ts @@ -25,7 +25,7 @@ const CONTACT_EMAIL = 'hello@orm.st'; const config: Config = { title: 'Storm Framework', - tagline: 'A modern, high-performance ORM for Kotlin 2.0+ and Java 21+', + tagline: 'A modern ORM for Kotlin 2.0+ and Java 21+, built for agentic coding and performance', favicon: 'img/storm-dark.png', // Load the marketing type pair (Inter + JetBrains Mono) on the docs pages too, @@ -244,6 +244,11 @@ const config: Config = { position: 'left', label: 'Documentation', }, + { + to: '/docs/ai', + label: 'AI', + position: 'left', + }, { to: '/tutorials/', label: 'Tutorials', @@ -283,6 +288,7 @@ const config: Config = { title: 'Learn', items: [ {label: 'Quickstart', to: '/quickstart'}, + {label: 'Agentic coding', to: '/docs/ai'}, {label: 'Installation', to: '/docs/installation'}, {label: 'Entities', to: '/docs/entities'}, {label: 'Queries', to: '/docs/queries'}, diff --git a/website/plugins/static-version-replace.js b/website/plugins/static-version-replace.js index a28dff6c7..e9c9b5c37 100644 --- a/website/plugins/static-version-replace.js +++ b/website/plugins/static-version-replace.js @@ -1,7 +1,8 @@ /** * Docusaurus plugin that replaces @@STORM_VERSION@@ in static files after they * are copied to the build output: the per-tool skill files (static/skills/*.md) - * and the AI-facing docs indexes (static/llms.txt and static/llms-full.txt). + * the AI-facing docs indexes (static/llms.txt and static/llms-full.txt) and the + * per-page Markdown copies of the docs (static/docs/**.md). * These files are copied verbatim and never pass through the remark version * plugin, so this postBuild pass is what keeps their install snippets on the * current version. @@ -34,6 +35,14 @@ module.exports = function staticVersionReplace(context, options) { // AI-facing docs indexes copied from static/. replaceInFile(path.join(outDir, 'llms.txt')); replaceInFile(path.join(outDir, 'llms-full.txt')); + + // Per-page Markdown copies of the docs, generated into static/docs/. + for (const dir of [path.join(outDir, 'docs'), path.join(outDir, 'docs', 'next')]) { + if (!fs.existsSync(dir)) continue; + for (const name of fs.readdirSync(dir)) { + if (name.endsWith('.md')) replaceInFile(path.join(dir, name)); + } + } }, }; }; diff --git a/website/scripts/generate-llms-full.sh b/website/scripts/generate-llms-full.sh index 91c4d79ae..3a5c497b8 100755 --- a/website/scripts/generate-llms-full.sh +++ b/website/scripts/generate-llms-full.sh @@ -1,6 +1,8 @@ #!/usr/bin/env bash # -# Generates llms-full.txt from all documentation files in sidebar order. +# Generates llms-full.txt from all documentation files in sidebar order, and a +# plain Markdown copy of every docs page beside its HTML route, so an agent can +# fetch /docs/.md instead of scraping the rendered page. # Strips Docusaurus-specific syntax (imports, JSX components, frontmatter, admonitions). # # Usage: bash website/scripts/generate-llms-full.sh @@ -23,6 +25,10 @@ DOCS=( first-entity.md first-query.md glossary.md + # Agentic Coding + ai.md + ai-reference.md + database-and-mcp.md # Core Concepts entities.md projections.md @@ -71,9 +77,6 @@ DOCS=( faq.md migration-from-jpa.md jpa-cascades-vs-write-sets.md - ai.md - ai-reference.md - database-and-mcp.md # API Reference api-kotlin.md api-java.md @@ -135,20 +138,23 @@ strip_docusaurus() { cat > "$OUTPUT" <<'HEADER' # Storm Framework - Complete Documentation -> Storm is an AI-first ORM framework for Kotlin 2.0+ and Java 21+, the gold -> standard for AI-assisted database development. +> Storm is an ORM for Kotlin 2.0+ and Java 21+, built for agentic coding and +> performance. > -> It uses immutable data classes and records instead of proxied entities, -> providing type-safe queries, predictable performance, and zero hidden magic. -> Storm works perfectly standalone, but its design and tooling make it uniquely -> suited for AI-assisted development: immutable entities produce stable code, -> the CLI installs per-tool skills, and a locally running MCP server exposes -> only schema metadata (table definitions, column types, constraints) while -> shielding your database credentials and data from the LLM. Built-in -> verification (validateSchema(), SqlCapture) lets the AI validate its own work -> before anything is committed. +> Every detail lives in the model. Entities are plain Kotlin data classes or Java +> records: one class is the table, its keys and its relations, and the queries +> follow from it. Underneath is a thin layer over JDBC. There is no persistence +> context, no transparent lazy loading, no proxy generation, and no entity state +> management, so the code is exactly what runs. The domain model gives one-line, +> type-safe queries across relations, returning the whole entity graph in one +> statement. The CLI installs rules and skills for coding +> agents, plus a local MCP server that exposes only schema metadata while +> keeping database credentials away from the LLM. Built-in verification +> (validateSchema(), SqlCapture) lets the agent check its own work before +> anything is committed. > -> Get started: `npx @storm-orm/cli` +> Get started: `npx @storm-orm/cli init` (existing project) or +> `npx @storm-orm/cli demo` (empty directory) > Website: https://orm.st > GitHub: https://github.com/storm-orm/storm-framework > License: Apache 2.0 @@ -173,3 +179,22 @@ for doc in "${DOCS[@]}"; do done echo "Generated $OUTPUT" + +# Per-page Markdown. /docs/ serves the latest released snapshot and +# /docs/next/ the docs in this repository, so each gets its Markdown copy +# from the same source: /docs/.md and /docs/next/.md. The output is +# generated on every build and not committed. +write_markdown_pages() { + local src="$1" out="$2" + mkdir -p "$out" + for filepath in "$src"/*.md; do + strip_docusaurus < "$filepath" > "$out/$(basename "$filepath")" + done +} +MARKDOWN_OUT="$WEBSITE_DIR/static/docs" +LATEST_VERSION="$(node -p "require('$WEBSITE_DIR/versions.json')[0]")" +rm -rf "$MARKDOWN_OUT" +write_markdown_pages "$WEBSITE_DIR/versioned_docs/version-$LATEST_VERSION" "$MARKDOWN_OUT" +write_markdown_pages "$DOCS_DIR" "$MARKDOWN_OUT/next" + +echo "Generated Markdown pages in $MARKDOWN_OUT" diff --git a/website/sidebars.ts b/website/sidebars.ts index 9a1373c44..71eabfb0a 100644 --- a/website/sidebars.ts +++ b/website/sidebars.ts @@ -25,6 +25,15 @@ const sidebars: SidebarsConfig = { 'glossary', ], }, + { + type: 'category', + label: 'Agentic Coding', + items: [ + 'ai', + 'ai-reference', + 'database-and-mcp', + ], + }, { type: 'category', label: 'Core Concepts', @@ -107,9 +116,6 @@ const sidebars: SidebarsConfig = { 'faq', 'migration-from-jpa', 'jpa-cascades-vs-write-sets', - 'ai', - 'ai-reference', - 'database-and-mcp', ], }, { diff --git a/website/src/components/tutorial/tutorialTheme.js b/website/src/components/tutorial/tutorialTheme.js index 69bd89c87..9efaca5b0 100644 --- a/website/src/components/tutorial/tutorialTheme.js +++ b/website/src/components/tutorial/tutorialTheme.js @@ -305,6 +305,7 @@ export const navHtml = (active) => `