{"section":"cli","slug":"scaffolding-generators","featureTitle":"Scaffolding Generators","summary":"Scaffold modules, pages, payloads, services, and contracts through commands that already understand Semitexa structure and AI-friendly output modes.","entryLine":"The generator surface matters because it teaches the framework shape by producing the right files, not by asking the developer to remember ceremony.","highlights":["make:module","make:page","make:payload","make:service","make:contract","--llm-hints"],"learnMoreLabel":"See the generator workflow →","deepDiveLabel":"Why this scaffolding is different →","documentBodyHtml":"<article class=\"sx-docs-fragment\" data-doc-id=\"cli/scaffolding-generators\" data-doc-locale=\"en\">\n<h1>Scaffolding Generators</h1>\n<p>The generator surface matters because it teaches the framework shape by producing the right files, not by asking the developer to remember ceremony.</p>\n<h2>How it works</h2>\n<p><code>make:module</code>, <code>make:page</code>, <code>make:payload</code>, <code>make:service</code>, <code>make:contract</code>, <code>make:handler</code>, <code>make:resource</code>, <code>make:command</code>, and <code>make:event-listener</code> each encode Semitexa's expected file layout and attribute conventions directly into the generated stubs. Dry-run and <code>--llm-hints</code> modes let humans and agents inspect the plan before files are written. JSON output makes generator results consumable by automated workflows.</p>\n<h2>Payload access modifiers</h2>\n<p>Both <code>make:payload</code> and <code>make:page</code> accept <code>--access=public|protected|service</code>. The flag picks exactly one of the three current access attributes:</p>\n<table>\n<thead>\n<tr>\n<th><code>--access</code> value</th>\n<th>Generated attribute</th>\n<th>When to use</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>public</code> (explicit)</td>\n<td><code>#[AsPublicPayload]</code></td>\n<td>Anonymous endpoints — login, marketing pages, health checks.</td>\n</tr>\n<tr>\n<td><code>protected</code> (default)</td>\n<td><code>#[AsProtectedPayload]</code></td>\n<td>User-authenticated endpoints — the safe default.</td>\n</tr>\n<tr>\n<td><code>service</code></td>\n<td><code>#[AsServicePayload]</code></td>\n<td>Machine-to-machine endpoints — webhook receivers, partner integrations, internal service callers.</td>\n</tr>\n</tbody>\n</table>\n<p>The default is <code>protected</code> so an omitted flag still produces a closed-by-default endpoint. An invalid value (<code>--access=open</code>, <code>--access=foo</code>) fails the generator with a clear <code>Unknown payload access type</code> error before any file is written. The three access attributes are mutually exclusive in generated output — <code>GeneratorForbiddenPatternRegressionTest::payload_plan_builder_emits_exactly_one_access_attribute</code> pins the contract.</p>\n<h2>Why this matters</h2>\n<p>The point is not fewer keystrokes. The point is fewer incorrect architectural starts. Good scaffolding shortens onboarding because the produced files demonstrate the intended structure directly and reduce wrong patterns before they become habits. The framework's regression suite scans every template and every plan builder output for retired payload attributes (see the <a href=\"../migration/post-hardening.md\">post-hardening migration guide</a> for the full list), so a future template tweak that silently reintroduces a stale shape fails CI before it lands.</p>\n</article>","sectionLabel":"CLI","navSections":[{"key":"get-started","label":"Start Here","sidebarLabel":"Get Started","summary":"The shortest path from fresh scaffold to a trustworthy local Semitexa runtime: install, boot, understand the module map, bind a real host, and reach the first tenant boundary.","icon":"GO","eyebrow":"Onboarding","starter":true,"prerequisites":[],"featureCount":7,"href":"/demo/get-started","features":[{"section":"get-started","slug":"module-structure","label":"Start Here","title":"Module Structure","summary":"The minimal Semitexa module is a typed HTTP spine of payload, handler, resource, and template.","opensInNewTab":false,"href":"/demo/get-started/module-structure"},{"section":"get-started","slug":"installation","label":"Start Here","title":"Installation","summary":"Create the project, review the baseline env contract, and bring up the Semitexa runtime the supported way.","opensInNewTab":false,"href":"/demo/get-started/installation"},{"section":"get-started","slug":"local-domain","label":"Start Here","title":"Local Domain","summary":"Register .test domains through the built-in local-domain helper instead of relying on ad hoc host setup.","opensInNewTab":false,"href":"/demo/get-started/local-domain"},{"section":"get-started","slug":"base-tenant","label":"Start Here","title":"Base Tenant","summary":"Establish one default tenant context early so tenant-aware behavior is visible before the rest of the application grows.","opensInNewTab":false,"href":"/demo/get-started/base-tenant"},{"section":"get-started","slug":"locale-setup","label":"Start Here","title":"Locale Setup","summary":"Configure the minimal Locale contract so translations and locale-aware rendering become explicit early.","opensInNewTab":false,"href":"/demo/get-started/locale-setup"},{"section":"get-started","slug":"ai-console","label":"Start Here","title":"AI Console","summary":"Use the Semitexa AI console as a command translation surface over real operator commands.","opensInNewTab":false,"href":"/demo/get-started/ai-console"},{"section":"get-started","slug":"beyond-controllers","label":"Start Here","title":"Beyond Controllers","summary":"Understand why Semitexa keeps transport, use case, and rendering as separate explicit responsibilities.","opensInNewTab":false,"href":"/demo/get-started/beyond-controllers"}],"groups":[{"key":"structure","label":"Module Structure","featureCount":1,"features":[{"section":"get-started","slug":"module-structure","label":"Start Here","title":"Module Structure","summary":"The minimal Semitexa module is a typed HTTP spine of payload, handler, resource, and template.","opensInNewTab":false,"href":"/demo/get-started/module-structure"}]},{"key":"onboarding","label":"Onboarding","featureCount":6,"features":[{"section":"get-started","slug":"installation","label":"Start Here","title":"Installation","summary":"Create the project, review the baseline env contract, and bring up the Semitexa runtime the supported way.","opensInNewTab":false,"href":"/demo/get-started/installation"},{"section":"get-started","slug":"local-domain","label":"Start Here","title":"Local Domain","summary":"Register .test domains through the built-in local-domain helper instead of relying on ad hoc host setup.","opensInNewTab":false,"href":"/demo/get-started/local-domain"},{"section":"get-started","slug":"base-tenant","label":"Start Here","title":"Base Tenant","summary":"Establish one default tenant context early so tenant-aware behavior is visible before the rest of the application grows.","opensInNewTab":false,"href":"/demo/get-started/base-tenant"},{"section":"get-started","slug":"locale-setup","label":"Start Here","title":"Locale Setup","summary":"Configure the minimal Locale contract so translations and locale-aware rendering become explicit early.","opensInNewTab":false,"href":"/demo/get-started/locale-setup"},{"section":"get-started","slug":"ai-console","label":"Start Here","title":"AI Console","summary":"Use the Semitexa AI console as a command translation surface over real operator commands.","opensInNewTab":false,"href":"/demo/get-started/ai-console"},{"section":"get-started","slug":"beyond-controllers","label":"Start Here","title":"Beyond Controllers","summary":"Understand why Semitexa keeps transport, use case, and rendering as separate explicit responsibilities.","opensInNewTab":false,"href":"/demo/get-started/beyond-controllers"}]}]},{"key":"routing","label":"Routing & Handlers","summary":"Attribute-driven routes, typed handlers, and content negotiation in one coherent request pipeline.","icon":"RT","eyebrow":"HTTP Layer","starter":true,"prerequisites":[],"featureCount":7,"href":"/demo/routing","features":[{"section":"routing","slug":"basic","label":"Routing & Handlers","title":"Basic Route","summary":"Define a route with one access attribute on the payload — no XML, no YAML, no config files.","opensInNewTab":false,"href":"/demo/routing/basic"},{"section":"routing","slug":"parameterized","label":"Routing & Handlers","title":"Parameterized Route","summary":"Path parameters with regex constraints and typed injection.","opensInNewTab":false,"href":"/demo/routing/parameterized/headphones"},{"section":"routing","slug":"env-route-override","label":"Routing & Handlers","title":"Env Route Override","summary":"Keep the payload as the route source of truth while allowing operations to remap the public URL through .env.","opensInNewTab":false,"href":"/demo/routing/env-route-override"},{"section":"routing","slug":"payload-shield","label":"Routing & Handlers","title":"Payload As A Shield","summary":"Hydration happens before the handler, and each setter owns the normalization and guard logic for its own field.","opensInNewTab":false,"href":"/demo/routing/payload-shield"},{"section":"routing","slug":"payload-parts","label":"Routing & Handlers","title":"Payload Parts","summary":"One module owns the route, another module can extend the same payload contract without forking or reopening the base class.","opensInNewTab":false,"href":"/demo/routing/payload-parts"},{"section":"routing","slug":"content-negotiation","label":"Routing & Handlers","title":"Content Negotiation","summary":"One endpoint, multiple response formats — automatically.","opensInNewTab":false,"href":"/demo/routing/content-negotiation"},{"section":"routing","slug":"public-endpoint","label":"Routing & Handlers","title":"Public Payload","summary":"Anonymous endpoints opt in explicitly with the public access attribute. Every other payload requires authentication.","opensInNewTab":false,"href":"/demo/routing/public-endpoint"}],"groups":[{"key":"foundations","label":"Foundations","featureCount":3,"features":[{"section":"routing","slug":"basic","label":"Routing & Handlers","title":"Basic Route","summary":"Define a route with one access attribute on the payload — no XML, no YAML, no config files.","opensInNewTab":false,"href":"/demo/routing/basic"},{"section":"routing","slug":"parameterized","label":"Routing & Handlers","title":"Parameterized Route","summary":"Path parameters with regex constraints and typed injection.","opensInNewTab":false,"href":"/demo/routing/parameterized/headphones"},{"section":"routing","slug":"env-route-override","label":"Routing & Handlers","title":"Env Route Override","summary":"Keep the payload as the route source of truth while allowing operations to remap the public URL through .env.","opensInNewTab":false,"href":"/demo/routing/env-route-override"}]},{"key":"request-model","label":"Request Model","featureCount":2,"features":[{"section":"routing","slug":"payload-shield","label":"Routing & Handlers","title":"Payload As A Shield","summary":"Hydration happens before the handler, and each setter owns the normalization and guard logic for its own field.","opensInNewTab":false,"href":"/demo/routing/payload-shield"},{"section":"routing","slug":"payload-parts","label":"Routing & Handlers","title":"Payload Parts","summary":"One module owns the route, another module can extend the same payload contract without forking or reopening the base class.","opensInNewTab":false,"href":"/demo/routing/payload-parts"}]},{"key":"delivery","label":"Delivery","featureCount":2,"features":[{"section":"routing","slug":"content-negotiation","label":"Routing & Handlers","title":"Content Negotiation","summary":"One endpoint, multiple response formats — automatically.","opensInNewTab":false,"href":"/demo/routing/content-negotiation"},{"section":"routing","slug":"public-endpoint","label":"Routing & Handlers","title":"Public Payload","summary":"Anonymous endpoints opt in explicitly with the public access attribute. Every other payload requires authentication.","opensInNewTab":false,"href":"/demo/routing/public-endpoint"}]}]},{"key":"di","label":"Dependency Injection","summary":"Single-path DI with explicit lifecycles, deterministic contracts, and stable boot behavior for long-running workers.","icon":"DI","eyebrow":"Container","starter":true,"prerequisites":[],"featureCount":5,"href":"/demo/di","features":[{"section":"di","slug":"overview","label":"Dependency Injection","title":"DI Canon","summary":"One canonical DI path for container-managed classes: explicit properties, explicit lifecycles, deterministic boot.","opensInNewTab":false,"href":"/demo/di/overview"},{"section":"di","slug":"readonly","label":"Dependency Injection","title":"Readonly Injection","summary":"One explicit DI path, one shared worker instance — fast at runtime and stable under reload.","opensInNewTab":false,"href":"/demo/di/readonly"},{"section":"di","slug":"mutable","label":"Dependency Injection","title":"Mutable Injection","summary":"Execution-scoped services get a fresh clone every run — safe state without contaminating the worker.","opensInNewTab":false,"href":"/demo/di/mutable"},{"section":"di","slug":"factory","label":"Dependency Injection","title":"Factory Injection","summary":"On-demand creation stays explicit — lazy instances without falling back to service locator habits.","opensInNewTab":false,"href":"/demo/di/factory"},{"section":"di","slug":"contracts","label":"Dependency Injection","title":"Service Contracts","summary":"Depend on contracts, but keep ownership explicit — deterministic substitution instead of runtime magic.","opensInNewTab":false,"href":"/demo/di/contracts"}],"groups":[{"key":"container-basics","label":"Container Basics","featureCount":5,"features":[{"section":"di","slug":"overview","label":"Dependency Injection","title":"DI Canon","summary":"One canonical DI path for container-managed classes: explicit properties, explicit lifecycles, deterministic boot.","opensInNewTab":false,"href":"/demo/di/overview"},{"section":"di","slug":"readonly","label":"Dependency Injection","title":"Readonly Injection","summary":"One explicit DI path, one shared worker instance — fast at runtime and stable under reload.","opensInNewTab":false,"href":"/demo/di/readonly"},{"section":"di","slug":"mutable","label":"Dependency Injection","title":"Mutable Injection","summary":"Execution-scoped services get a fresh clone every run — safe state without contaminating the worker.","opensInNewTab":false,"href":"/demo/di/mutable"},{"section":"di","slug":"factory","label":"Dependency Injection","title":"Factory Injection","summary":"On-demand creation stays explicit — lazy instances without falling back to service locator habits.","opensInNewTab":false,"href":"/demo/di/factory"},{"section":"di","slug":"contracts","label":"Dependency Injection","title":"Service Contracts","summary":"Depend on contracts, but keep ownership explicit — deterministic substitution instead of runtime magic.","opensInNewTab":false,"href":"/demo/di/contracts"}]}]},{"key":"data","label":"Persistence","summary":"Attribute-mapped resources, repositories, filtering, pagination, and relations with real demo data.","icon":"DB","eyebrow":"Persistence","starter":true,"prerequisites":[],"featureCount":9,"href":"/demo/data","features":[{"section":"data","slug":"domain-models","label":"Persistence","title":"Domain-Level Models","summary":"Semitexa separates persistence resources from business models. Resources map tables; domain models carry behavior and invariants.","opensInNewTab":false,"href":"/demo/data/domain-models"},{"section":"data","slug":"repository-workflow","label":"Persistence","title":"Repository Workflow","summary":"The canonical Semitexa path: handlers depend on repository contracts, repositories return domain models, and persistence resources stay behind the boundary.","opensInNewTab":false,"href":"/demo/data/repository-workflow"},{"section":"data","slug":"schema-sync","label":"Persistence","title":"Schema Sync, Not Migration Churn","summary":"Semitexa creates SQL only when the real schema changed, blocks destructive drops by default, and logs the exact DDL plan as SQL and JSON.","opensInNewTab":false,"href":"/demo/data/schema-sync"},{"section":"data","slug":"query","label":"Persistence","title":"Query Builder","summary":"Compose type-safe queries with a fluent API — no raw SQL, no magic strings.","opensInNewTab":false,"href":"/demo/data/query"},{"section":"data","slug":"filtering","label":"Persistence","title":"Filtering","summary":"Mark a property #[Filterable] and the ORM handles the rest — no manual WHERE clauses.","opensInNewTab":false,"href":"/demo/data/filtering"},{"section":"data","slug":"pagination","label":"Persistence","title":"Pagination","summary":"Offset and cursor pagination out of the box — switch modes with a single query parameter.","opensInNewTab":false,"href":"/demo/data/pagination"},{"section":"data","slug":"relations","label":"Persistence","title":"Relations","summary":"Declare parent and child links on the resource itself, then read typed relations from the handler.","opensInNewTab":false,"href":"/demo/data/relations"},{"section":"data","slug":"table-extension","label":"Persistence","title":"Shared Table Extension","summary":"Two modules can extend one table independently, and the ORM merges the schema without forcing either side to edit the other.","opensInNewTab":false,"href":"/demo/data/table-extension"},{"section":"data","slug":"n-plus-one","label":"Persistence","title":"N+1 Without Magic","summary":"Semitexa avoids N+1 by using resource slices for the exact columns and relations each screen needs, instead of hiding database traffic behind implicit relation loading.","opensInNewTab":false,"href":"/demo/data/n-plus-one"}],"groups":[{"key":"modeling","label":"Modeling & Workflow","featureCount":3,"features":[{"section":"data","slug":"domain-models","label":"Persistence","title":"Domain-Level Models","summary":"Semitexa separates persistence resources from business models. Resources map tables; domain models carry behavior and invariants.","opensInNewTab":false,"href":"/demo/data/domain-models"},{"section":"data","slug":"repository-workflow","label":"Persistence","title":"Repository Workflow","summary":"The canonical Semitexa path: handlers depend on repository contracts, repositories return domain models, and persistence resources stay behind the boundary.","opensInNewTab":false,"href":"/demo/data/repository-workflow"},{"section":"data","slug":"schema-sync","label":"Persistence","title":"Schema Sync, Not Migration Churn","summary":"Semitexa creates SQL only when the real schema changed, blocks destructive drops by default, and logs the exact DDL plan as SQL and JSON.","opensInNewTab":false,"href":"/demo/data/schema-sync"}]},{"key":"querying","label":"Querying","featureCount":6,"features":[{"section":"data","slug":"query","label":"Persistence","title":"Query Builder","summary":"Compose type-safe queries with a fluent API — no raw SQL, no magic strings.","opensInNewTab":false,"href":"/demo/data/query"},{"section":"data","slug":"filtering","label":"Persistence","title":"Filtering","summary":"Mark a property #[Filterable] and the ORM handles the rest — no manual WHERE clauses.","opensInNewTab":false,"href":"/demo/data/filtering"},{"section":"data","slug":"pagination","label":"Persistence","title":"Pagination","summary":"Offset and cursor pagination out of the box — switch modes with a single query parameter.","opensInNewTab":false,"href":"/demo/data/pagination"},{"section":"data","slug":"relations","label":"Persistence","title":"Relations","summary":"Declare parent and child links on the resource itself, then read typed relations from the handler.","opensInNewTab":false,"href":"/demo/data/relations"},{"section":"data","slug":"table-extension","label":"Persistence","title":"Shared Table Extension","summary":"Two modules can extend one table independently, and the ORM merges the schema without forcing either side to edit the other.","opensInNewTab":false,"href":"/demo/data/table-extension"},{"section":"data","slug":"n-plus-one","label":"Persistence","title":"N+1 Without Magic","summary":"Semitexa avoids N+1 by using resource slices for the exact columns and relations each screen needs, instead of hiding database traffic behind implicit relation loading.","opensInNewTab":false,"href":"/demo/data/n-plus-one"}]}]},{"key":"auth","label":"Security","summary":"Typed session payloads, machine credentials, RBAC, and route protection without string-key auth chaos.","icon":"AU","eyebrow":"Security","starter":false,"prerequisites":[],"featureCount":7,"href":"/demo/auth","features":[{"section":"auth","slug":"session","label":"Security","title":"Session Auth","summary":"Google signs the user in, then the session stores the selected demo role and re-hydrates it on every request.","opensInNewTab":false,"href":"/demo/auth/session"},{"section":"auth","slug":"session-payloads","label":"Security","title":"Session Payloads","summary":"Semitexa forbids string-key session chaos: session state lives in typed Session Payloads or it does not exist.","opensInNewTab":false,"href":"/demo/auth/session-payloads"},{"section":"auth","slug":"google","label":"Security","title":"Google Authorization","summary":"Authorization is required for demo SSE blocks that keep a long-lived backend connection open.","opensInNewTab":false,"href":"/demo/auth/google"},{"section":"auth","slug":"machine","label":"Security","title":"Machine Auth","summary":"Service-to-service authentication via Bearer tokens — scoped, revocable, and audited.","opensInNewTab":false,"href":"/demo/auth/machine"},{"section":"auth","slug":"protected","label":"Security","title":"Protected Route","summary":"Add one access attribute and one optional permission attribute and the framework enforces access — 401 for unauthenticated requests, 403 for unauthorized ones.","opensInNewTab":false,"href":"/demo/auth/protected"},{"section":"auth","slug":"requires-permission","label":"Security","title":"Requires Permission","summary":"Declare one permission slug on the payload and let the framework enforce it before your handler runs.","opensInNewTab":false,"href":"/demo/auth/requires-permission"},{"section":"auth","slug":"rbac","label":"Security","title":"RBAC","summary":"Hybrid RBAC with coarse-grained capabilities, exact permission slugs, and module-owned permission catalogs.","opensInNewTab":false,"href":"/demo/auth/rbac"}],"groups":[{"key":"identity","label":"Identity","featureCount":4,"features":[{"section":"auth","slug":"session","label":"Security","title":"Session Auth","summary":"Google signs the user in, then the session stores the selected demo role and re-hydrates it on every request.","opensInNewTab":false,"href":"/demo/auth/session"},{"section":"auth","slug":"session-payloads","label":"Security","title":"Session Payloads","summary":"Semitexa forbids string-key session chaos: session state lives in typed Session Payloads or it does not exist.","opensInNewTab":false,"href":"/demo/auth/session-payloads"},{"section":"auth","slug":"google","label":"Security","title":"Google Authorization","summary":"Authorization is required for demo SSE blocks that keep a long-lived backend connection open.","opensInNewTab":false,"href":"/demo/auth/google"},{"section":"auth","slug":"machine","label":"Security","title":"Machine Auth","summary":"Service-to-service authentication via Bearer tokens — scoped, revocable, and audited.","opensInNewTab":false,"href":"/demo/auth/machine"}]},{"key":"access-control","label":"Access Control","featureCount":3,"features":[{"section":"auth","slug":"protected","label":"Security","title":"Protected Route","summary":"Add one access attribute and one optional permission attribute and the framework enforces access — 401 for unauthenticated requests, 403 for unauthorized ones.","opensInNewTab":false,"href":"/demo/auth/protected"},{"section":"auth","slug":"requires-permission","label":"Security","title":"Requires Permission","summary":"Declare one permission slug on the payload and let the framework enforce it before your handler runs.","opensInNewTab":false,"href":"/demo/auth/requires-permission"},{"section":"auth","slug":"rbac","label":"Security","title":"RBAC","summary":"Hybrid RBAC with coarse-grained capabilities, exact permission slugs, and module-owned permission catalogs.","opensInNewTab":false,"href":"/demo/auth/rbac"}]}]},{"key":"events","label":"Async","summary":"Synchronous and deferred event flows, queues, and SSE-style interactions.","icon":"EV","eyebrow":"Async","starter":false,"prerequisites":[],"featureCount":5,"href":"/demo/events","features":[{"section":"events","slug":"arena","label":"Async","title":"Execution Arena","summary":"Launch the same backend intent in sync, Swoole async, and queued modes, then watch the proof arrive over SSE.","opensInNewTab":false,"href":"/demo/events/arena"},{"section":"events","slug":"sync","label":"Async","title":"Sync Events","summary":"Dispatch an event and all sync listeners run before the response is sent.","opensInNewTab":false,"href":"/demo/events/sync"},{"section":"events","slug":"deferred","label":"Async","title":"Deferred Handler","summary":"Heavy work runs after the response is sent — the user gets instant feedback.","opensInNewTab":false,"href":"/demo/events/deferred"},{"section":"events","slug":"queued","label":"Async","title":"Queued Handler","summary":"Events survive restarts and scale across workers — backed by a durable message queue.","opensInNewTab":false,"href":"/demo/events/queued"},{"section":"events","slug":"sse","label":"Async","title":"SSE Stream","summary":"Real-time server push without WebSockets — connect once and receive real backend events over plain HTTP.","opensInNewTab":false,"href":"/demo/events/sse"}],"groups":[{"key":"event-flow","label":"Event Flow","featureCount":5,"features":[{"section":"events","slug":"arena","label":"Async","title":"Execution Arena","summary":"Launch the same backend intent in sync, Swoole async, and queued modes, then watch the proof arrive over SSE.","opensInNewTab":false,"href":"/demo/events/arena"},{"section":"events","slug":"sync","label":"Async","title":"Sync Events","summary":"Dispatch an event and all sync listeners run before the response is sent.","opensInNewTab":false,"href":"/demo/events/sync"},{"section":"events","slug":"deferred","label":"Async","title":"Deferred Handler","summary":"Heavy work runs after the response is sent — the user gets instant feedback.","opensInNewTab":false,"href":"/demo/events/deferred"},{"section":"events","slug":"queued","label":"Async","title":"Queued Handler","summary":"Events survive restarts and scale across workers — backed by a durable message queue.","opensInNewTab":false,"href":"/demo/events/queued"},{"section":"events","slug":"sse","label":"Async","title":"SSE Stream","summary":"Real-time server push without WebSockets — connect once and receive real backend events over plain HTTP.","opensInNewTab":false,"href":"/demo/events/sse"}]}]},{"key":"rendering","label":"UI Rendering & SSR","summary":"One rendering story from handler to HTML: page data, page regions, and live updates stay in the same server-driven model instead of splitting into frontend and backend template logic.","icon":"UI","eyebrow":"Frontend","starter":false,"prerequisites":[],"featureCount":15,"href":"/demo/rendering","features":[{"section":"rendering","slug":"philosophy","label":"UI Rendering & SSR","title":"SSR Philosophy","summary":"Semitexa SSR is one continuous rendering architecture: page, slots, deferred regions, live refresh, and interactive components stay inside one server-owned story.","opensInNewTab":false,"href":"/demo/rendering/philosophy"},{"section":"rendering","slug":"resource-dtos","label":"UI Rendering & SSR","title":"Resource DTOs","summary":"A Resource DTO is the one typed source of presentation data: handlers shape it once, templates consume it everywhere, and no view has to dissect random arrays.","opensInNewTab":false,"href":"/demo/rendering/resource-dtos"},{"section":"rendering","slug":"slots","label":"UI Rendering & SSR","title":"Slot Resources","summary":"Each page region is its own resource pipeline with the same template system as the main page — no scattered partial glue, no mystery wiring.","opensInNewTab":false,"href":"/demo/rendering/slots"},{"section":"rendering","slug":"components","label":"UI Rendering & SSR","title":"Components","summary":"Reusable, attribute-registered UI components — discovered automatically from the classmap.","opensInNewTab":false,"href":"/demo/rendering/components"},{"section":"rendering","slug":"seo","label":"UI Rendering & SSR","title":"SEO","summary":"Set title, description, and Open Graph tags from your handler — no template hacks needed.","opensInNewTab":false,"href":"/demo/rendering/seo"},{"section":"rendering","slug":"assets","label":"UI Rendering & SSR","title":"Asset Pipeline","summary":"Declare assets with glob patterns in assets.json — served, versioned, and injected automatically.","opensInNewTab":false,"href":"/demo/rendering/assets"},{"section":"rendering","slug":"component-scripts","label":"UI Rendering & SSR","title":"Component Script Assets","summary":"A Semitexa SSR component can own its optional enhancement asset, so behavior travels with the component instead of leaking into page-level glue.","opensInNewTab":false,"href":"/demo/rendering/component-scripts"},{"section":"rendering","slug":"deferred-scripts","label":"UI Rendering & SSR","title":"Script Injection","summary":"Deferred blocks carry their own JS — injected once when the block arrives, never duplicated.","opensInNewTab":false,"href":"/demo/rendering/deferred-scripts"},{"section":"rendering","slug":"deferred","label":"UI Rendering & SSR","title":"Deferred Blocks","summary":"SSR renders the shell first, then expensive regions stream in as real HTML over SSE — no SPA handoff and no client-side page rebuild.","opensInNewTab":true,"href":"/demo/rendering/deferred"},{"section":"rendering","slug":"deferred-encapsulation","label":"UI Rendering & SSR","title":"Block Isolation","summary":"Two identical blocks on the same page run independently — scoped DOM, scoped JS, no conflicts.","opensInNewTab":false,"href":"/demo/rendering/deferred-encapsulation"},{"section":"rendering","slug":"deferred-live","label":"UI Rendering & SSR","title":"Live Widgets","summary":"A live slot can refresh itself on a timer while the page stays SSR-first — no SPA runtime and no handwritten polling layer.","opensInNewTab":false,"href":"/demo/rendering/deferred-live"},{"section":"rendering","slug":"reactive-report","label":"UI Rendering & SSR","title":"Reactive Report","summary":"Background work updates an SSR-first slot in place, so the UI feels live without falling back to SPA state orchestration.","opensInNewTab":false,"href":"/demo/rendering/reactive-report"},{"section":"rendering","slug":"reactive-import","label":"UI Rendering & SSR","title":"Reactive Import","summary":"Background batches keep moving, and the page reflects server progress as live HTML instead of a client-managed progress app.","opensInNewTab":false,"href":"/demo/rendering/reactive-import"},{"section":"rendering","slug":"reactive-analytics","label":"UI Rendering & SSR","title":"Reactive Analytics","summary":"Independent analytics jobs can light up one dashboard progressively, while the page stays server-rendered from the first byte.","opensInNewTab":false,"href":"/demo/rendering/reactive-analytics"},{"section":"rendering","slug":"reactive-ai","label":"UI Rendering & SSR","title":"Reactive AI Task","summary":"Submit a task and watch the AI pipeline stages reveal one by one as the cron job processes it.","opensInNewTab":false,"href":"/demo/rendering/reactive-ai"}],"groups":[{"key":"rendering-model","label":"SSR Foundation","featureCount":8,"features":[{"section":"rendering","slug":"philosophy","label":"UI Rendering & SSR","title":"SSR Philosophy","summary":"Semitexa SSR is one continuous rendering architecture: page, slots, deferred regions, live refresh, and interactive components stay inside one server-owned story.","opensInNewTab":false,"href":"/demo/rendering/philosophy"},{"section":"rendering","slug":"resource-dtos","label":"UI Rendering & SSR","title":"Resource DTOs","summary":"A Resource DTO is the one typed source of presentation data: handlers shape it once, templates consume it everywhere, and no view has to dissect random arrays.","opensInNewTab":false,"href":"/demo/rendering/resource-dtos"},{"section":"rendering","slug":"slots","label":"UI Rendering & SSR","title":"Slot Resources","summary":"Each page region is its own resource pipeline with the same template system as the main page — no scattered partial glue, no mystery wiring.","opensInNewTab":false,"href":"/demo/rendering/slots"},{"section":"rendering","slug":"components","label":"UI Rendering & SSR","title":"Components","summary":"Reusable, attribute-registered UI components — discovered automatically from the classmap.","opensInNewTab":false,"href":"/demo/rendering/components"},{"section":"rendering","slug":"seo","label":"UI Rendering & SSR","title":"SEO","summary":"Set title, description, and Open Graph tags from your handler — no template hacks needed.","opensInNewTab":false,"href":"/demo/rendering/seo"},{"section":"rendering","slug":"assets","label":"UI Rendering & SSR","title":"Asset Pipeline","summary":"Declare assets with glob patterns in assets.json — served, versioned, and injected automatically.","opensInNewTab":false,"href":"/demo/rendering/assets"},{"section":"rendering","slug":"component-scripts","label":"UI Rendering & SSR","title":"Component Script Assets","summary":"A Semitexa SSR component can own its optional enhancement asset, so behavior travels with the component instead of leaking into page-level glue.","opensInNewTab":false,"href":"/demo/rendering/component-scripts"},{"section":"rendering","slug":"deferred-scripts","label":"UI Rendering & SSR","title":"Script Injection","summary":"Deferred blocks carry their own JS — injected once when the block arrives, never duplicated.","opensInNewTab":false,"href":"/demo/rendering/deferred-scripts"}]},{"key":"deferred","label":"Deferred Delivery","featureCount":2,"features":[{"section":"rendering","slug":"deferred","label":"UI Rendering & SSR","title":"Deferred Blocks","summary":"SSR renders the shell first, then expensive regions stream in as real HTML over SSE — no SPA handoff and no client-side page rebuild.","opensInNewTab":true,"href":"/demo/rendering/deferred"},{"section":"rendering","slug":"deferred-encapsulation","label":"UI Rendering & SSR","title":"Block Isolation","summary":"Two identical blocks on the same page run independently — scoped DOM, scoped JS, no conflicts.","opensInNewTab":false,"href":"/demo/rendering/deferred-encapsulation"}]},{"key":"live","label":"Reactive UI","featureCount":5,"features":[{"section":"rendering","slug":"deferred-live","label":"UI Rendering & SSR","title":"Live Widgets","summary":"A live slot can refresh itself on a timer while the page stays SSR-first — no SPA runtime and no handwritten polling layer.","opensInNewTab":false,"href":"/demo/rendering/deferred-live"},{"section":"rendering","slug":"reactive-report","label":"UI Rendering & SSR","title":"Reactive Report","summary":"Background work updates an SSR-first slot in place, so the UI feels live without falling back to SPA state orchestration.","opensInNewTab":false,"href":"/demo/rendering/reactive-report"},{"section":"rendering","slug":"reactive-import","label":"UI Rendering & SSR","title":"Reactive Import","summary":"Background batches keep moving, and the page reflects server progress as live HTML instead of a client-managed progress app.","opensInNewTab":false,"href":"/demo/rendering/reactive-import"},{"section":"rendering","slug":"reactive-analytics","label":"UI Rendering & SSR","title":"Reactive Analytics","summary":"Independent analytics jobs can light up one dashboard progressively, while the page stays server-rendered from the first byte.","opensInNewTab":false,"href":"/demo/rendering/reactive-analytics"},{"section":"rendering","slug":"reactive-ai","label":"UI Rendering & SSR","title":"Reactive AI Task","summary":"Submit a task and watch the AI pipeline stages reveal one by one as the cron job processes it.","opensInNewTab":false,"href":"/demo/rendering/reactive-ai"}]}]},{"key":"platform","label":"Tenancy","summary":"Multi-tenant resolution, tenant-aware configuration, and strict isolation of data and background work.","icon":"TN","eyebrow":"Multi-Tenant","starter":false,"prerequisites":["data","rendering"],"featureCount":5,"href":"/demo/platform","features":[{"section":"platform","slug":"tenancy-resolution","label":"Tenancy","title":"Tenant Context Resolution","summary":"See how Semitexa resolves the active tenant from subdomain, header, path, or query input before the rest of the platform runs.","opensInNewTab":false,"href":"/demo/platform/tenancy-resolution"},{"section":"platform","slug":"tenancy-config","label":"Tenancy","title":"Per-Tenant Configuration","summary":"Three demo tenants with distinct branding -- switch tenant, everything changes without if/else.","opensInNewTab":false,"href":"/demo/platform/tenancy-config"},{"section":"platform","slug":"tenancy-layers","label":"Tenancy","title":"Multi-Layer Tenancy","summary":"Organization, Locale, Theme, Environment -- four independent layers compose into one TenantContext.","opensInNewTab":false,"href":"/demo/platform/tenancy-layers"},{"section":"platform","slug":"tenancy-isolation","label":"Tenancy","title":"Data Isolation","summary":"Product listing scoped by tenant -- switch tenant, list changes. Zero manual WHERE clauses.","opensInNewTab":false,"href":"/demo/platform/tenancy-isolation"},{"section":"platform","slug":"tenancy-queue","label":"Tenancy","title":"Queue Tenant Propagation","summary":"Tenant context travels with queued jobs -- _tenant key injected automatically, restored by worker.","opensInNewTab":false,"href":"/demo/platform/tenancy-queue"}],"groups":[{"key":"resolution","label":"Tenant Resolution","featureCount":1,"features":[{"section":"platform","slug":"tenancy-resolution","label":"Tenancy","title":"Tenant Context Resolution","summary":"See how Semitexa resolves the active tenant from subdomain, header, path, or query input before the rest of the platform runs.","opensInNewTab":false,"href":"/demo/platform/tenancy-resolution"}]},{"key":"configuration","label":"Tenant Configuration","featureCount":2,"features":[{"section":"platform","slug":"tenancy-config","label":"Tenancy","title":"Per-Tenant Configuration","summary":"Three demo tenants with distinct branding -- switch tenant, everything changes without if/else.","opensInNewTab":false,"href":"/demo/platform/tenancy-config"},{"section":"platform","slug":"tenancy-layers","label":"Tenancy","title":"Multi-Layer Tenancy","summary":"Organization, Locale, Theme, Environment -- four independent layers compose into one TenantContext.","opensInNewTab":false,"href":"/demo/platform/tenancy-layers"}]},{"key":"isolation","label":"Isolation & Work","featureCount":2,"features":[{"section":"platform","slug":"tenancy-isolation","label":"Tenancy","title":"Data Isolation","summary":"Product listing scoped by tenant -- switch tenant, list changes. Zero manual WHERE clauses.","opensInNewTab":false,"href":"/demo/platform/tenancy-isolation"},{"section":"platform","slug":"tenancy-queue","label":"Tenancy","title":"Queue Tenant Propagation","summary":"Tenant context travels with queued jobs -- _tenant key injected automatically, restored by worker.","opensInNewTab":false,"href":"/demo/platform/tenancy-queue"}]}]},{"key":"api","label":"API","summary":"External API endpoints, machine auth, versioning, and consumer-facing schema behavior.","icon":"API","eyebrow":"Machine","starter":false,"prerequisites":["routing","auth"],"featureCount":7,"href":"/demo/api","features":[{"section":"api","slug":"rest-api","label":"API","title":"REST API","summary":"Classic Semitexa REST endpoints with typed payloads, versioning, and consumer-friendly response shaping.","opensInNewTab":false,"href":"/demo/api/rest-api"},{"section":"api","slug":"structured-errors","label":"API","title":"Structured Errors","summary":"Throw domain exceptions and let semitexa-api map them into stable machine-readable error envelopes.","opensInNewTab":false,"href":"/demo/api/structured-errors"},{"section":"api","slug":"active-version","label":"API","title":"Active Version","summary":"The current collection endpoint with a clean X-Api-Version header and no deprecation noise.","opensInNewTab":false,"href":"/demo/api/active-version"},{"section":"api","slug":"sunset-version","label":"API","title":"Sunset Version","summary":"A deprecated product endpoint that emits both Deprecation and Sunset headers.","opensInNewTab":false,"href":"/demo/api/sunset-version"},{"section":"api","slug":"schema-discovery","label":"API","title":"Schema Discovery","summary":"A mini Swagger-style explorer for the live product API contract, schema endpoint, and response shapes.","opensInNewTab":false,"href":"/demo/api/schema-discovery"},{"section":"api","slug":"graphql","label":"API","title":"GraphQL API","summary":"GraphQL-first Semitexa contracts built with typed payloads and typed output DTOs instead of resolver sprawl.","opensInNewTab":false,"href":"/demo/api/graphql"},{"section":"api","slug":"rest-graphql","label":"API","title":"REST + GraphQL","summary":"One Semitexa use case can serve both REST and GraphQL without duplicating handler logic into separate resolver classes.","opensInNewTab":false,"href":"/demo/api/rest-graphql"}],"groups":[{"key":"public-api","label":"REST Surface","featureCount":4,"features":[{"section":"api","slug":"rest-api","label":"API","title":"REST API","summary":"Classic Semitexa REST endpoints with typed payloads, versioning, and consumer-friendly response shaping.","opensInNewTab":false,"href":"/demo/api/rest-api"},{"section":"api","slug":"structured-errors","label":"API","title":"Structured Errors","summary":"Throw domain exceptions and let semitexa-api map them into stable machine-readable error envelopes.","opensInNewTab":false,"href":"/demo/api/structured-errors"},{"section":"api","slug":"active-version","label":"API","title":"Active Version","summary":"The current collection endpoint with a clean X-Api-Version header and no deprecation noise.","opensInNewTab":false,"href":"/demo/api/active-version"},{"section":"api","slug":"sunset-version","label":"API","title":"Sunset Version","summary":"A deprecated product endpoint that emits both Deprecation and Sunset headers.","opensInNewTab":false,"href":"/demo/api/sunset-version"}]},{"key":"schema","label":"Schema Discovery","featureCount":3,"features":[{"section":"api","slug":"schema-discovery","label":"API","title":"Schema Discovery","summary":"A mini Swagger-style explorer for the live product API contract, schema endpoint, and response shapes.","opensInNewTab":false,"href":"/demo/api/schema-discovery"},{"section":"api","slug":"graphql","label":"API","title":"GraphQL API","summary":"GraphQL-first Semitexa contracts built with typed payloads and typed output DTOs instead of resolver sprawl.","opensInNewTab":false,"href":"/demo/api/graphql"},{"section":"api","slug":"rest-graphql","label":"API","title":"REST + GraphQL","summary":"One Semitexa use case can serve both REST and GraphQL without duplicating handler logic into separate resolver classes.","opensInNewTab":false,"href":"/demo/api/rest-graphql"}]}]},{"key":"cli","label":"CLI","summary":"Operational, introspection, and AI-oriented command surfaces that explain and drive the framework from the terminal.","icon":"CLI","eyebrow":"Operations","starter":false,"prerequisites":["routing"],"featureCount":6,"href":"/demo/cli","features":[{"section":"cli","slug":"describe-commands","label":"CLI","title":"Project Graph Introspection","summary":"Routes, modules, contracts, and handlers can be introspected directly from the CLI instead of reverse-engineering the framework graph by hand.","opensInNewTab":false,"href":"/demo/cli/describe-commands"},{"section":"cli","slug":"runtime-maintenance","label":"CLI","title":"Runtime Maintenance","summary":"Reload workers, clear stale cache, sync registries, lint architecture rules, and probe handler wiring without reaching for ad-hoc shell scripts.","opensInNewTab":false,"href":"/demo/cli/runtime-maintenance"},{"section":"cli","slug":"scaffolding-generators","label":"CLI","title":"Scaffolding Generators","summary":"Scaffold modules, pages, payloads, services, and contracts through commands that already understand Semitexa structure and AI-friendly output modes.","opensInNewTab":false,"href":"/demo/cli/scaffolding-generators"},{"section":"cli","slug":"workers-scheduling","label":"CLI","title":"Workers & Scheduling","summary":"Run queues, scheduler pools, mail delivery, webhooks, and tenant-scoped commands from a coherent operator surface instead of bespoke daemons.","opensInNewTab":false,"href":"/demo/cli/workers-scheduling"},{"section":"cli","slug":"ai-tooling","label":"CLI","title":"AI Tooling Surface","summary":"Semitexa exposes AI-facing commands as explicit CLI contracts: capabilities, skills, log access, and a local assistant entrypoint.","opensInNewTab":false,"href":"/demo/cli/ai-tooling"},{"section":"cli","slug":"orm-console","label":"CLI","title":"ORM Console Toolkit","summary":"The ORM ships with a practical CLI surface: status, diff, sync, and seed commands with dry-run safety and SQL plan export.","opensInNewTab":false,"href":"/demo/cli/orm-console"}],"groups":[{"key":"inspection","label":"Describe & Inspect","featureCount":2,"features":[{"section":"cli","slug":"describe-commands","label":"CLI","title":"Project Graph Introspection","summary":"Routes, modules, contracts, and handlers can be introspected directly from the CLI instead of reverse-engineering the framework graph by hand.","opensInNewTab":false,"href":"/demo/cli/describe-commands"},{"section":"cli","slug":"runtime-maintenance","label":"CLI","title":"Runtime Maintenance","summary":"Reload workers, clear stale cache, sync registries, lint architecture rules, and probe handler wiring without reaching for ad-hoc shell scripts.","opensInNewTab":false,"href":"/demo/cli/runtime-maintenance"}]},{"key":"automation","label":"Automation","featureCount":4,"features":[{"section":"cli","slug":"scaffolding-generators","label":"CLI","title":"Scaffolding Generators","summary":"Scaffold modules, pages, payloads, services, and contracts through commands that already understand Semitexa structure and AI-friendly output modes.","opensInNewTab":false,"href":"/demo/cli/scaffolding-generators"},{"section":"cli","slug":"workers-scheduling","label":"CLI","title":"Workers & Scheduling","summary":"Run queues, scheduler pools, mail delivery, webhooks, and tenant-scoped commands from a coherent operator surface instead of bespoke daemons.","opensInNewTab":false,"href":"/demo/cli/workers-scheduling"},{"section":"cli","slug":"ai-tooling","label":"CLI","title":"AI Tooling Surface","summary":"Semitexa exposes AI-facing commands as explicit CLI contracts: capabilities, skills, log access, and a local assistant entrypoint.","opensInNewTab":false,"href":"/demo/cli/ai-tooling"},{"section":"cli","slug":"orm-console","label":"CLI","title":"ORM Console Toolkit","summary":"The ORM ships with a practical CLI surface: status, diff, sync, and seed commands with dry-run safety and SQL plan export.","opensInNewTab":false,"href":"/demo/cli/orm-console"}]}]},{"key":"llm","label":"LLM Module","sidebarLabel":"LLM","summary":"The dedicated `semitexa/llm` module: AI assistant entrypoint, skill discovery, planner, executor, provider backends, and skill authoring rules.","icon":"AI","eyebrow":"semitexa/llm","starter":false,"prerequisites":["cli"],"featureCount":4,"href":"/demo/llm","features":[{"section":"llm","slug":"overview","label":"LLM Module","title":"LLM Module Overview","summary":"What `semitexa/llm` adds to the framework and how your project can expose its own CLI skills to the assistant.","opensInNewTab":false,"href":"/demo/llm/overview"},{"section":"llm","slug":"providers","label":"LLM Module","title":"Providers & Backends","summary":"Provider contracts, backend resolution, local vs remote Ollama, and the environment knobs that shape LLM runtime behavior.","opensInNewTab":false,"href":"/demo/llm/providers"},{"section":"llm","slug":"skills","label":"LLM Module","title":"Adding Skills","summary":"How a console command becomes AI-executable through `#[AsAiSkill]`, metadata policy, and registry discovery.","opensInNewTab":false,"href":"/demo/llm/skills"},{"section":"llm","slug":"execution-flow","label":"LLM Module","title":"Execution Flow","summary":"How a user request becomes a planner decision, a reviewed skill proposal, and finally a real console execution.","opensInNewTab":false,"href":"/demo/llm/execution-flow"}],"groups":[{"key":"assistant-basics","label":"Assistant Surface","featureCount":2,"features":[{"section":"llm","slug":"overview","label":"LLM Module","title":"LLM Module Overview","summary":"What `semitexa/llm` adds to the framework and how your project can expose its own CLI skills to the assistant.","opensInNewTab":false,"href":"/demo/llm/overview"},{"section":"llm","slug":"providers","label":"LLM Module","title":"Providers & Backends","summary":"Provider contracts, backend resolution, local vs remote Ollama, and the environment knobs that shape LLM runtime behavior.","opensInNewTab":false,"href":"/demo/llm/providers"}]},{"key":"skill-system","label":"Skill System","featureCount":2,"features":[{"section":"llm","slug":"skills","label":"LLM Module","title":"Adding Skills","summary":"How a console command becomes AI-executable through `#[AsAiSkill]`, metadata policy, and registry discovery.","opensInNewTab":false,"href":"/demo/llm/skills"},{"section":"llm","slug":"execution-flow","label":"LLM Module","title":"Execution Flow","summary":"How a user request becomes a planner decision, a reviewed skill proposal, and finally a real console execution.","opensInNewTab":false,"href":"/demo/llm/execution-flow"}]}]},{"key":"project-graph","label":"Project Graph","summary":"The `semitexa-project-graph` package: stored structural graph, intelligence layer, impact analysis, and task-scoped context for serious repository work.","icon":"PG","eyebrow":"AI Accelerator","starter":true,"prerequisites":["cli"],"featureCount":3,"href":"/demo/project-graph","features":[{"section":"project-graph","slug":"overview","label":"Project Graph","title":"Project Graph Overview","summary":"Understand what `semitexa-project-graph` adds: a stored structural map, an intelligence layer, and task-scoped context for large-codebase work.","opensInNewTab":false,"href":"/demo/project-graph/overview"},{"section":"project-graph","slug":"inspection","label":"Project Graph","title":"Inspecting the Graph","summary":"Use Project Graph queries and intelligence views to inspect modules, dependencies, flows, events, and hotspots without reconstructing the repository manually.","opensInNewTab":false,"href":"/demo/project-graph/inspection"},{"section":"project-graph","slug":"impact","label":"Project Graph","title":"Impact, Context, and Watch Mode","summary":"Use impact analysis, context packing, and watch mode to scope risky changes and keep graph-backed answers current during long work sessions.","opensInNewTab":false,"href":"/demo/project-graph/impact"}],"groups":[{"key":"launch","label":"Start Here","featureCount":1,"features":[{"section":"project-graph","slug":"overview","label":"Project Graph","title":"Project Graph Overview","summary":"Understand what `semitexa-project-graph` adds: a stored structural map, an intelligence layer, and task-scoped context for large-codebase work.","opensInNewTab":false,"href":"/demo/project-graph/overview"}]},{"key":"exploration","label":"Explore & Inspect","featureCount":1,"features":[{"section":"project-graph","slug":"inspection","label":"Project Graph","title":"Inspecting the Graph","summary":"Use Project Graph queries and intelligence views to inspect modules, dependencies, flows, events, and hotspots without reconstructing the repository manually.","opensInNewTab":false,"href":"/demo/project-graph/inspection"}]},{"key":"change-safety","label":"Impact & Context","featureCount":1,"features":[{"section":"project-graph","slug":"impact","label":"Project Graph","title":"Impact, Context, and Watch Mode","summary":"Use impact analysis, context packing, and watch mode to scope risky changes and keep graph-backed answers current during long work sessions.","opensInNewTab":false,"href":"/demo/project-graph/impact"}]}]},{"key":"testing","label":"Testing","summary":"Contract-level verification patterns for payloads and other framework boundaries.","icon":"QA","eyebrow":"Verification","starter":false,"prerequisites":["routing"],"featureCount":1,"href":"/demo/testing","features":[{"section":"testing","slug":"payload-contracts","label":"Testing","title":"Payload Contract Testing","summary":"Run one project-level contract suite through the canonical test runner and let strategy profiles verify payload boundaries without hand-writing repetitive negative cases.","opensInNewTab":false,"href":"/demo/testing/payload-contracts"}],"groups":[{"key":"contracts","label":"Contracts","featureCount":1,"features":[{"section":"testing","slug":"payload-contracts","label":"Testing","title":"Payload Contract Testing","summary":"Run one project-level contract suite through the canonical test runner and let strategy profiles verify payload boundaries without hand-writing repetitive negative cases.","opensInNewTab":false,"href":"/demo/testing/payload-contracts"}]}]}],"featureTree":[{"key":"start-here","label":"Start Here","eyebrow":"Guided path","summary":"The smallest reliable sequence that makes Semitexa feel like a system instead of a brochure.","type":"feature-links","href":"/#start-here","features":[{"section":"get-started","slug":"installation","label":"Start Here","title":"Installation","summary":"Create the project, review the baseline env contract, and bring up the Semitexa runtime the supported way.","opensInNewTab":false,"href":"/demo/get-started/installation"},{"section":"get-started","slug":"local-domain","label":"Start Here","title":"Local Domain","summary":"Register .test domains through the built-in local-domain helper instead of relying on ad hoc host setup.","opensInNewTab":false,"href":"/demo/get-started/local-domain"},{"section":"get-started","slug":"module-structure","label":"Start Here","title":"Module Structure","summary":"The minimal Semitexa module is a typed HTTP spine of payload, handler, resource, and template.","opensInNewTab":false,"href":"/demo/get-started/module-structure"},{"section":"get-started","slug":"base-tenant","label":"Start Here","title":"Base Tenant","summary":"Establish one default tenant context early so tenant-aware behavior is visible before the rest of the application grows.","opensInNewTab":false,"href":"/demo/get-started/base-tenant"},{"section":"get-started","slug":"locale-setup","label":"Start Here","title":"Locale Setup","summary":"Configure the minimal Locale contract so translations and locale-aware rendering become explicit early.","opensInNewTab":false,"href":"/demo/get-started/locale-setup"},{"section":"get-started","slug":"ai-console","label":"Start Here","title":"AI Console","summary":"Use the Semitexa AI console as a command translation surface over real operator commands.","opensInNewTab":false,"href":"/demo/get-started/ai-console"},{"section":"project-graph","slug":"overview","label":"Project Graph","title":"Project Graph Overview","summary":"Understand what `semitexa-project-graph` adds: a stored structural map, an intelligence layer, and task-scoped context for large-codebase work.","opensInNewTab":false,"href":"/demo/project-graph/overview"},{"section":"routing","slug":"basic","label":"Routing & Handlers","title":"Basic Route","summary":"Define a route with one access attribute on the payload — no XML, no YAML, no config files.","opensInNewTab":false,"href":"/demo/routing/basic"},{"section":"di","slug":"overview","label":"Dependency Injection","title":"DI Canon","summary":"One canonical DI path for container-managed classes: explicit properties, explicit lifecycles, deterministic boot.","opensInNewTab":false,"href":"/demo/di/overview"}],"featureCount":9},{"key":"full-catalog","label":"Full Catalog","eyebrow":"Route-first map","summary":"The exhaustive live map, still route-first, still real, and still one click away from every feature route.","type":"section-groups","href":"/#full-catalog","sectionKeys":["get-started","routing","di","data","auth","events","rendering","platform","api","cli","project-graph","llm","testing"],"featureCount":81,"sections":[{"key":"get-started","label":"Start Here","sidebarLabel":"Get Started","summary":"The shortest path from fresh scaffold to a trustworthy local Semitexa runtime: install, boot, understand the module map, bind a real host, and reach the first tenant boundary.","icon":"GO","eyebrow":"Onboarding","starter":true,"prerequisites":[],"featureCount":7,"href":"/demo/get-started","features":[{"section":"get-started","slug":"module-structure","label":"Start Here","title":"Module Structure","summary":"The minimal Semitexa module is a typed HTTP spine of payload, handler, resource, and template.","opensInNewTab":false,"href":"/demo/get-started/module-structure"},{"section":"get-started","slug":"installation","label":"Start Here","title":"Installation","summary":"Create the project, review the baseline env contract, and bring up the Semitexa runtime the supported way.","opensInNewTab":false,"href":"/demo/get-started/installation"},{"section":"get-started","slug":"local-domain","label":"Start Here","title":"Local Domain","summary":"Register .test domains through the built-in local-domain helper instead of relying on ad hoc host setup.","opensInNewTab":false,"href":"/demo/get-started/local-domain"},{"section":"get-started","slug":"base-tenant","label":"Start Here","title":"Base Tenant","summary":"Establish one default tenant context early so tenant-aware behavior is visible before the rest of the application grows.","opensInNewTab":false,"href":"/demo/get-started/base-tenant"},{"section":"get-started","slug":"locale-setup","label":"Start Here","title":"Locale Setup","summary":"Configure the minimal Locale contract so translations and locale-aware rendering become explicit early.","opensInNewTab":false,"href":"/demo/get-started/locale-setup"},{"section":"get-started","slug":"ai-console","label":"Start Here","title":"AI Console","summary":"Use the Semitexa AI console as a command translation surface over real operator commands.","opensInNewTab":false,"href":"/demo/get-started/ai-console"},{"section":"get-started","slug":"beyond-controllers","label":"Start Here","title":"Beyond Controllers","summary":"Understand why Semitexa keeps transport, use case, and rendering as separate explicit responsibilities.","opensInNewTab":false,"href":"/demo/get-started/beyond-controllers"}],"groups":[{"key":"structure","label":"Module Structure","featureCount":1,"features":[{"section":"get-started","slug":"module-structure","label":"Start Here","title":"Module Structure","summary":"The minimal Semitexa module is a typed HTTP spine of payload, handler, resource, and template.","opensInNewTab":false,"href":"/demo/get-started/module-structure"}]},{"key":"onboarding","label":"Onboarding","featureCount":6,"features":[{"section":"get-started","slug":"installation","label":"Start Here","title":"Installation","summary":"Create the project, review the baseline env contract, and bring up the Semitexa runtime the supported way.","opensInNewTab":false,"href":"/demo/get-started/installation"},{"section":"get-started","slug":"local-domain","label":"Start Here","title":"Local Domain","summary":"Register .test domains through the built-in local-domain helper instead of relying on ad hoc host setup.","opensInNewTab":false,"href":"/demo/get-started/local-domain"},{"section":"get-started","slug":"base-tenant","label":"Start Here","title":"Base Tenant","summary":"Establish one default tenant context early so tenant-aware behavior is visible before the rest of the application grows.","opensInNewTab":false,"href":"/demo/get-started/base-tenant"},{"section":"get-started","slug":"locale-setup","label":"Start Here","title":"Locale Setup","summary":"Configure the minimal Locale contract so translations and locale-aware rendering become explicit early.","opensInNewTab":false,"href":"/demo/get-started/locale-setup"},{"section":"get-started","slug":"ai-console","label":"Start Here","title":"AI Console","summary":"Use the Semitexa AI console as a command translation surface over real operator commands.","opensInNewTab":false,"href":"/demo/get-started/ai-console"},{"section":"get-started","slug":"beyond-controllers","label":"Start Here","title":"Beyond Controllers","summary":"Understand why Semitexa keeps transport, use case, and rendering as separate explicit responsibilities.","opensInNewTab":false,"href":"/demo/get-started/beyond-controllers"}]}]},{"key":"routing","label":"Routing & Handlers","summary":"Attribute-driven routes, typed handlers, and content negotiation in one coherent request pipeline.","icon":"RT","eyebrow":"HTTP Layer","starter":true,"prerequisites":[],"featureCount":7,"href":"/demo/routing","features":[{"section":"routing","slug":"basic","label":"Routing & Handlers","title":"Basic Route","summary":"Define a route with one access attribute on the payload — no XML, no YAML, no config files.","opensInNewTab":false,"href":"/demo/routing/basic"},{"section":"routing","slug":"parameterized","label":"Routing & Handlers","title":"Parameterized Route","summary":"Path parameters with regex constraints and typed injection.","opensInNewTab":false,"href":"/demo/routing/parameterized/headphones"},{"section":"routing","slug":"env-route-override","label":"Routing & Handlers","title":"Env Route Override","summary":"Keep the payload as the route source of truth while allowing operations to remap the public URL through .env.","opensInNewTab":false,"href":"/demo/routing/env-route-override"},{"section":"routing","slug":"payload-shield","label":"Routing & Handlers","title":"Payload As A Shield","summary":"Hydration happens before the handler, and each setter owns the normalization and guard logic for its own field.","opensInNewTab":false,"href":"/demo/routing/payload-shield"},{"section":"routing","slug":"payload-parts","label":"Routing & Handlers","title":"Payload Parts","summary":"One module owns the route, another module can extend the same payload contract without forking or reopening the base class.","opensInNewTab":false,"href":"/demo/routing/payload-parts"},{"section":"routing","slug":"content-negotiation","label":"Routing & Handlers","title":"Content Negotiation","summary":"One endpoint, multiple response formats — automatically.","opensInNewTab":false,"href":"/demo/routing/content-negotiation"},{"section":"routing","slug":"public-endpoint","label":"Routing & Handlers","title":"Public Payload","summary":"Anonymous endpoints opt in explicitly with the public access attribute. Every other payload requires authentication.","opensInNewTab":false,"href":"/demo/routing/public-endpoint"}],"groups":[{"key":"foundations","label":"Foundations","featureCount":3,"features":[{"section":"routing","slug":"basic","label":"Routing & Handlers","title":"Basic Route","summary":"Define a route with one access attribute on the payload — no XML, no YAML, no config files.","opensInNewTab":false,"href":"/demo/routing/basic"},{"section":"routing","slug":"parameterized","label":"Routing & Handlers","title":"Parameterized Route","summary":"Path parameters with regex constraints and typed injection.","opensInNewTab":false,"href":"/demo/routing/parameterized/headphones"},{"section":"routing","slug":"env-route-override","label":"Routing & Handlers","title":"Env Route Override","summary":"Keep the payload as the route source of truth while allowing operations to remap the public URL through .env.","opensInNewTab":false,"href":"/demo/routing/env-route-override"}]},{"key":"request-model","label":"Request Model","featureCount":2,"features":[{"section":"routing","slug":"payload-shield","label":"Routing & Handlers","title":"Payload As A Shield","summary":"Hydration happens before the handler, and each setter owns the normalization and guard logic for its own field.","opensInNewTab":false,"href":"/demo/routing/payload-shield"},{"section":"routing","slug":"payload-parts","label":"Routing & Handlers","title":"Payload Parts","summary":"One module owns the route, another module can extend the same payload contract without forking or reopening the base class.","opensInNewTab":false,"href":"/demo/routing/payload-parts"}]},{"key":"delivery","label":"Delivery","featureCount":2,"features":[{"section":"routing","slug":"content-negotiation","label":"Routing & Handlers","title":"Content Negotiation","summary":"One endpoint, multiple response formats — automatically.","opensInNewTab":false,"href":"/demo/routing/content-negotiation"},{"section":"routing","slug":"public-endpoint","label":"Routing & Handlers","title":"Public Payload","summary":"Anonymous endpoints opt in explicitly with the public access attribute. Every other payload requires authentication.","opensInNewTab":false,"href":"/demo/routing/public-endpoint"}]}]},{"key":"di","label":"Dependency Injection","summary":"Single-path DI with explicit lifecycles, deterministic contracts, and stable boot behavior for long-running workers.","icon":"DI","eyebrow":"Container","starter":true,"prerequisites":[],"featureCount":5,"href":"/demo/di","features":[{"section":"di","slug":"overview","label":"Dependency Injection","title":"DI Canon","summary":"One canonical DI path for container-managed classes: explicit properties, explicit lifecycles, deterministic boot.","opensInNewTab":false,"href":"/demo/di/overview"},{"section":"di","slug":"readonly","label":"Dependency Injection","title":"Readonly Injection","summary":"One explicit DI path, one shared worker instance — fast at runtime and stable under reload.","opensInNewTab":false,"href":"/demo/di/readonly"},{"section":"di","slug":"mutable","label":"Dependency Injection","title":"Mutable Injection","summary":"Execution-scoped services get a fresh clone every run — safe state without contaminating the worker.","opensInNewTab":false,"href":"/demo/di/mutable"},{"section":"di","slug":"factory","label":"Dependency Injection","title":"Factory Injection","summary":"On-demand creation stays explicit — lazy instances without falling back to service locator habits.","opensInNewTab":false,"href":"/demo/di/factory"},{"section":"di","slug":"contracts","label":"Dependency Injection","title":"Service Contracts","summary":"Depend on contracts, but keep ownership explicit — deterministic substitution instead of runtime magic.","opensInNewTab":false,"href":"/demo/di/contracts"}],"groups":[{"key":"container-basics","label":"Container Basics","featureCount":5,"features":[{"section":"di","slug":"overview","label":"Dependency Injection","title":"DI Canon","summary":"One canonical DI path for container-managed classes: explicit properties, explicit lifecycles, deterministic boot.","opensInNewTab":false,"href":"/demo/di/overview"},{"section":"di","slug":"readonly","label":"Dependency Injection","title":"Readonly Injection","summary":"One explicit DI path, one shared worker instance — fast at runtime and stable under reload.","opensInNewTab":false,"href":"/demo/di/readonly"},{"section":"di","slug":"mutable","label":"Dependency Injection","title":"Mutable Injection","summary":"Execution-scoped services get a fresh clone every run — safe state without contaminating the worker.","opensInNewTab":false,"href":"/demo/di/mutable"},{"section":"di","slug":"factory","label":"Dependency Injection","title":"Factory Injection","summary":"On-demand creation stays explicit — lazy instances without falling back to service locator habits.","opensInNewTab":false,"href":"/demo/di/factory"},{"section":"di","slug":"contracts","label":"Dependency Injection","title":"Service Contracts","summary":"Depend on contracts, but keep ownership explicit — deterministic substitution instead of runtime magic.","opensInNewTab":false,"href":"/demo/di/contracts"}]}]},{"key":"data","label":"Persistence","summary":"Attribute-mapped resources, repositories, filtering, pagination, and relations with real demo data.","icon":"DB","eyebrow":"Persistence","starter":true,"prerequisites":[],"featureCount":9,"href":"/demo/data","features":[{"section":"data","slug":"domain-models","label":"Persistence","title":"Domain-Level Models","summary":"Semitexa separates persistence resources from business models. Resources map tables; domain models carry behavior and invariants.","opensInNewTab":false,"href":"/demo/data/domain-models"},{"section":"data","slug":"repository-workflow","label":"Persistence","title":"Repository Workflow","summary":"The canonical Semitexa path: handlers depend on repository contracts, repositories return domain models, and persistence resources stay behind the boundary.","opensInNewTab":false,"href":"/demo/data/repository-workflow"},{"section":"data","slug":"schema-sync","label":"Persistence","title":"Schema Sync, Not Migration Churn","summary":"Semitexa creates SQL only when the real schema changed, blocks destructive drops by default, and logs the exact DDL plan as SQL and JSON.","opensInNewTab":false,"href":"/demo/data/schema-sync"},{"section":"data","slug":"query","label":"Persistence","title":"Query Builder","summary":"Compose type-safe queries with a fluent API — no raw SQL, no magic strings.","opensInNewTab":false,"href":"/demo/data/query"},{"section":"data","slug":"filtering","label":"Persistence","title":"Filtering","summary":"Mark a property #[Filterable] and the ORM handles the rest — no manual WHERE clauses.","opensInNewTab":false,"href":"/demo/data/filtering"},{"section":"data","slug":"pagination","label":"Persistence","title":"Pagination","summary":"Offset and cursor pagination out of the box — switch modes with a single query parameter.","opensInNewTab":false,"href":"/demo/data/pagination"},{"section":"data","slug":"relations","label":"Persistence","title":"Relations","summary":"Declare parent and child links on the resource itself, then read typed relations from the handler.","opensInNewTab":false,"href":"/demo/data/relations"},{"section":"data","slug":"table-extension","label":"Persistence","title":"Shared Table Extension","summary":"Two modules can extend one table independently, and the ORM merges the schema without forcing either side to edit the other.","opensInNewTab":false,"href":"/demo/data/table-extension"},{"section":"data","slug":"n-plus-one","label":"Persistence","title":"N+1 Without Magic","summary":"Semitexa avoids N+1 by using resource slices for the exact columns and relations each screen needs, instead of hiding database traffic behind implicit relation loading.","opensInNewTab":false,"href":"/demo/data/n-plus-one"}],"groups":[{"key":"modeling","label":"Modeling & Workflow","featureCount":3,"features":[{"section":"data","slug":"domain-models","label":"Persistence","title":"Domain-Level Models","summary":"Semitexa separates persistence resources from business models. Resources map tables; domain models carry behavior and invariants.","opensInNewTab":false,"href":"/demo/data/domain-models"},{"section":"data","slug":"repository-workflow","label":"Persistence","title":"Repository Workflow","summary":"The canonical Semitexa path: handlers depend on repository contracts, repositories return domain models, and persistence resources stay behind the boundary.","opensInNewTab":false,"href":"/demo/data/repository-workflow"},{"section":"data","slug":"schema-sync","label":"Persistence","title":"Schema Sync, Not Migration Churn","summary":"Semitexa creates SQL only when the real schema changed, blocks destructive drops by default, and logs the exact DDL plan as SQL and JSON.","opensInNewTab":false,"href":"/demo/data/schema-sync"}]},{"key":"querying","label":"Querying","featureCount":6,"features":[{"section":"data","slug":"query","label":"Persistence","title":"Query Builder","summary":"Compose type-safe queries with a fluent API — no raw SQL, no magic strings.","opensInNewTab":false,"href":"/demo/data/query"},{"section":"data","slug":"filtering","label":"Persistence","title":"Filtering","summary":"Mark a property #[Filterable] and the ORM handles the rest — no manual WHERE clauses.","opensInNewTab":false,"href":"/demo/data/filtering"},{"section":"data","slug":"pagination","label":"Persistence","title":"Pagination","summary":"Offset and cursor pagination out of the box — switch modes with a single query parameter.","opensInNewTab":false,"href":"/demo/data/pagination"},{"section":"data","slug":"relations","label":"Persistence","title":"Relations","summary":"Declare parent and child links on the resource itself, then read typed relations from the handler.","opensInNewTab":false,"href":"/demo/data/relations"},{"section":"data","slug":"table-extension","label":"Persistence","title":"Shared Table Extension","summary":"Two modules can extend one table independently, and the ORM merges the schema without forcing either side to edit the other.","opensInNewTab":false,"href":"/demo/data/table-extension"},{"section":"data","slug":"n-plus-one","label":"Persistence","title":"N+1 Without Magic","summary":"Semitexa avoids N+1 by using resource slices for the exact columns and relations each screen needs, instead of hiding database traffic behind implicit relation loading.","opensInNewTab":false,"href":"/demo/data/n-plus-one"}]}]},{"key":"auth","label":"Security","summary":"Typed session payloads, machine credentials, RBAC, and route protection without string-key auth chaos.","icon":"AU","eyebrow":"Security","starter":false,"prerequisites":[],"featureCount":7,"href":"/demo/auth","features":[{"section":"auth","slug":"session","label":"Security","title":"Session Auth","summary":"Google signs the user in, then the session stores the selected demo role and re-hydrates it on every request.","opensInNewTab":false,"href":"/demo/auth/session"},{"section":"auth","slug":"session-payloads","label":"Security","title":"Session Payloads","summary":"Semitexa forbids string-key session chaos: session state lives in typed Session Payloads or it does not exist.","opensInNewTab":false,"href":"/demo/auth/session-payloads"},{"section":"auth","slug":"google","label":"Security","title":"Google Authorization","summary":"Authorization is required for demo SSE blocks that keep a long-lived backend connection open.","opensInNewTab":false,"href":"/demo/auth/google"},{"section":"auth","slug":"machine","label":"Security","title":"Machine Auth","summary":"Service-to-service authentication via Bearer tokens — scoped, revocable, and audited.","opensInNewTab":false,"href":"/demo/auth/machine"},{"section":"auth","slug":"protected","label":"Security","title":"Protected Route","summary":"Add one access attribute and one optional permission attribute and the framework enforces access — 401 for unauthenticated requests, 403 for unauthorized ones.","opensInNewTab":false,"href":"/demo/auth/protected"},{"section":"auth","slug":"requires-permission","label":"Security","title":"Requires Permission","summary":"Declare one permission slug on the payload and let the framework enforce it before your handler runs.","opensInNewTab":false,"href":"/demo/auth/requires-permission"},{"section":"auth","slug":"rbac","label":"Security","title":"RBAC","summary":"Hybrid RBAC with coarse-grained capabilities, exact permission slugs, and module-owned permission catalogs.","opensInNewTab":false,"href":"/demo/auth/rbac"}],"groups":[{"key":"identity","label":"Identity","featureCount":4,"features":[{"section":"auth","slug":"session","label":"Security","title":"Session Auth","summary":"Google signs the user in, then the session stores the selected demo role and re-hydrates it on every request.","opensInNewTab":false,"href":"/demo/auth/session"},{"section":"auth","slug":"session-payloads","label":"Security","title":"Session Payloads","summary":"Semitexa forbids string-key session chaos: session state lives in typed Session Payloads or it does not exist.","opensInNewTab":false,"href":"/demo/auth/session-payloads"},{"section":"auth","slug":"google","label":"Security","title":"Google Authorization","summary":"Authorization is required for demo SSE blocks that keep a long-lived backend connection open.","opensInNewTab":false,"href":"/demo/auth/google"},{"section":"auth","slug":"machine","label":"Security","title":"Machine Auth","summary":"Service-to-service authentication via Bearer tokens — scoped, revocable, and audited.","opensInNewTab":false,"href":"/demo/auth/machine"}]},{"key":"access-control","label":"Access Control","featureCount":3,"features":[{"section":"auth","slug":"protected","label":"Security","title":"Protected Route","summary":"Add one access attribute and one optional permission attribute and the framework enforces access — 401 for unauthenticated requests, 403 for unauthorized ones.","opensInNewTab":false,"href":"/demo/auth/protected"},{"section":"auth","slug":"requires-permission","label":"Security","title":"Requires Permission","summary":"Declare one permission slug on the payload and let the framework enforce it before your handler runs.","opensInNewTab":false,"href":"/demo/auth/requires-permission"},{"section":"auth","slug":"rbac","label":"Security","title":"RBAC","summary":"Hybrid RBAC with coarse-grained capabilities, exact permission slugs, and module-owned permission catalogs.","opensInNewTab":false,"href":"/demo/auth/rbac"}]}]},{"key":"events","label":"Async","summary":"Synchronous and deferred event flows, queues, and SSE-style interactions.","icon":"EV","eyebrow":"Async","starter":false,"prerequisites":[],"featureCount":5,"href":"/demo/events","features":[{"section":"events","slug":"arena","label":"Async","title":"Execution Arena","summary":"Launch the same backend intent in sync, Swoole async, and queued modes, then watch the proof arrive over SSE.","opensInNewTab":false,"href":"/demo/events/arena"},{"section":"events","slug":"sync","label":"Async","title":"Sync Events","summary":"Dispatch an event and all sync listeners run before the response is sent.","opensInNewTab":false,"href":"/demo/events/sync"},{"section":"events","slug":"deferred","label":"Async","title":"Deferred Handler","summary":"Heavy work runs after the response is sent — the user gets instant feedback.","opensInNewTab":false,"href":"/demo/events/deferred"},{"section":"events","slug":"queued","label":"Async","title":"Queued Handler","summary":"Events survive restarts and scale across workers — backed by a durable message queue.","opensInNewTab":false,"href":"/demo/events/queued"},{"section":"events","slug":"sse","label":"Async","title":"SSE Stream","summary":"Real-time server push without WebSockets — connect once and receive real backend events over plain HTTP.","opensInNewTab":false,"href":"/demo/events/sse"}],"groups":[{"key":"event-flow","label":"Event Flow","featureCount":5,"features":[{"section":"events","slug":"arena","label":"Async","title":"Execution Arena","summary":"Launch the same backend intent in sync, Swoole async, and queued modes, then watch the proof arrive over SSE.","opensInNewTab":false,"href":"/demo/events/arena"},{"section":"events","slug":"sync","label":"Async","title":"Sync Events","summary":"Dispatch an event and all sync listeners run before the response is sent.","opensInNewTab":false,"href":"/demo/events/sync"},{"section":"events","slug":"deferred","label":"Async","title":"Deferred Handler","summary":"Heavy work runs after the response is sent — the user gets instant feedback.","opensInNewTab":false,"href":"/demo/events/deferred"},{"section":"events","slug":"queued","label":"Async","title":"Queued Handler","summary":"Events survive restarts and scale across workers — backed by a durable message queue.","opensInNewTab":false,"href":"/demo/events/queued"},{"section":"events","slug":"sse","label":"Async","title":"SSE Stream","summary":"Real-time server push without WebSockets — connect once and receive real backend events over plain HTTP.","opensInNewTab":false,"href":"/demo/events/sse"}]}]},{"key":"rendering","label":"UI Rendering & SSR","summary":"One rendering story from handler to HTML: page data, page regions, and live updates stay in the same server-driven model instead of splitting into frontend and backend template logic.","icon":"UI","eyebrow":"Frontend","starter":false,"prerequisites":[],"featureCount":15,"href":"/demo/rendering","features":[{"section":"rendering","slug":"philosophy","label":"UI Rendering & SSR","title":"SSR Philosophy","summary":"Semitexa SSR is one continuous rendering architecture: page, slots, deferred regions, live refresh, and interactive components stay inside one server-owned story.","opensInNewTab":false,"href":"/demo/rendering/philosophy"},{"section":"rendering","slug":"resource-dtos","label":"UI Rendering & SSR","title":"Resource DTOs","summary":"A Resource DTO is the one typed source of presentation data: handlers shape it once, templates consume it everywhere, and no view has to dissect random arrays.","opensInNewTab":false,"href":"/demo/rendering/resource-dtos"},{"section":"rendering","slug":"slots","label":"UI Rendering & SSR","title":"Slot Resources","summary":"Each page region is its own resource pipeline with the same template system as the main page — no scattered partial glue, no mystery wiring.","opensInNewTab":false,"href":"/demo/rendering/slots"},{"section":"rendering","slug":"components","label":"UI Rendering & SSR","title":"Components","summary":"Reusable, attribute-registered UI components — discovered automatically from the classmap.","opensInNewTab":false,"href":"/demo/rendering/components"},{"section":"rendering","slug":"seo","label":"UI Rendering & SSR","title":"SEO","summary":"Set title, description, and Open Graph tags from your handler — no template hacks needed.","opensInNewTab":false,"href":"/demo/rendering/seo"},{"section":"rendering","slug":"assets","label":"UI Rendering & SSR","title":"Asset Pipeline","summary":"Declare assets with glob patterns in assets.json — served, versioned, and injected automatically.","opensInNewTab":false,"href":"/demo/rendering/assets"},{"section":"rendering","slug":"component-scripts","label":"UI Rendering & SSR","title":"Component Script Assets","summary":"A Semitexa SSR component can own its optional enhancement asset, so behavior travels with the component instead of leaking into page-level glue.","opensInNewTab":false,"href":"/demo/rendering/component-scripts"},{"section":"rendering","slug":"deferred-scripts","label":"UI Rendering & SSR","title":"Script Injection","summary":"Deferred blocks carry their own JS — injected once when the block arrives, never duplicated.","opensInNewTab":false,"href":"/demo/rendering/deferred-scripts"},{"section":"rendering","slug":"deferred","label":"UI Rendering & SSR","title":"Deferred Blocks","summary":"SSR renders the shell first, then expensive regions stream in as real HTML over SSE — no SPA handoff and no client-side page rebuild.","opensInNewTab":true,"href":"/demo/rendering/deferred"},{"section":"rendering","slug":"deferred-encapsulation","label":"UI Rendering & SSR","title":"Block Isolation","summary":"Two identical blocks on the same page run independently — scoped DOM, scoped JS, no conflicts.","opensInNewTab":false,"href":"/demo/rendering/deferred-encapsulation"},{"section":"rendering","slug":"deferred-live","label":"UI Rendering & SSR","title":"Live Widgets","summary":"A live slot can refresh itself on a timer while the page stays SSR-first — no SPA runtime and no handwritten polling layer.","opensInNewTab":false,"href":"/demo/rendering/deferred-live"},{"section":"rendering","slug":"reactive-report","label":"UI Rendering & SSR","title":"Reactive Report","summary":"Background work updates an SSR-first slot in place, so the UI feels live without falling back to SPA state orchestration.","opensInNewTab":false,"href":"/demo/rendering/reactive-report"},{"section":"rendering","slug":"reactive-import","label":"UI Rendering & SSR","title":"Reactive Import","summary":"Background batches keep moving, and the page reflects server progress as live HTML instead of a client-managed progress app.","opensInNewTab":false,"href":"/demo/rendering/reactive-import"},{"section":"rendering","slug":"reactive-analytics","label":"UI Rendering & SSR","title":"Reactive Analytics","summary":"Independent analytics jobs can light up one dashboard progressively, while the page stays server-rendered from the first byte.","opensInNewTab":false,"href":"/demo/rendering/reactive-analytics"},{"section":"rendering","slug":"reactive-ai","label":"UI Rendering & SSR","title":"Reactive AI Task","summary":"Submit a task and watch the AI pipeline stages reveal one by one as the cron job processes it.","opensInNewTab":false,"href":"/demo/rendering/reactive-ai"}],"groups":[{"key":"rendering-model","label":"SSR Foundation","featureCount":8,"features":[{"section":"rendering","slug":"philosophy","label":"UI Rendering & SSR","title":"SSR Philosophy","summary":"Semitexa SSR is one continuous rendering architecture: page, slots, deferred regions, live refresh, and interactive components stay inside one server-owned story.","opensInNewTab":false,"href":"/demo/rendering/philosophy"},{"section":"rendering","slug":"resource-dtos","label":"UI Rendering & SSR","title":"Resource DTOs","summary":"A Resource DTO is the one typed source of presentation data: handlers shape it once, templates consume it everywhere, and no view has to dissect random arrays.","opensInNewTab":false,"href":"/demo/rendering/resource-dtos"},{"section":"rendering","slug":"slots","label":"UI Rendering & SSR","title":"Slot Resources","summary":"Each page region is its own resource pipeline with the same template system as the main page — no scattered partial glue, no mystery wiring.","opensInNewTab":false,"href":"/demo/rendering/slots"},{"section":"rendering","slug":"components","label":"UI Rendering & SSR","title":"Components","summary":"Reusable, attribute-registered UI components — discovered automatically from the classmap.","opensInNewTab":false,"href":"/demo/rendering/components"},{"section":"rendering","slug":"seo","label":"UI Rendering & SSR","title":"SEO","summary":"Set title, description, and Open Graph tags from your handler — no template hacks needed.","opensInNewTab":false,"href":"/demo/rendering/seo"},{"section":"rendering","slug":"assets","label":"UI Rendering & SSR","title":"Asset Pipeline","summary":"Declare assets with glob patterns in assets.json — served, versioned, and injected automatically.","opensInNewTab":false,"href":"/demo/rendering/assets"},{"section":"rendering","slug":"component-scripts","label":"UI Rendering & SSR","title":"Component Script Assets","summary":"A Semitexa SSR component can own its optional enhancement asset, so behavior travels with the component instead of leaking into page-level glue.","opensInNewTab":false,"href":"/demo/rendering/component-scripts"},{"section":"rendering","slug":"deferred-scripts","label":"UI Rendering & SSR","title":"Script Injection","summary":"Deferred blocks carry their own JS — injected once when the block arrives, never duplicated.","opensInNewTab":false,"href":"/demo/rendering/deferred-scripts"}]},{"key":"deferred","label":"Deferred Delivery","featureCount":2,"features":[{"section":"rendering","slug":"deferred","label":"UI Rendering & SSR","title":"Deferred Blocks","summary":"SSR renders the shell first, then expensive regions stream in as real HTML over SSE — no SPA handoff and no client-side page rebuild.","opensInNewTab":true,"href":"/demo/rendering/deferred"},{"section":"rendering","slug":"deferred-encapsulation","label":"UI Rendering & SSR","title":"Block Isolation","summary":"Two identical blocks on the same page run independently — scoped DOM, scoped JS, no conflicts.","opensInNewTab":false,"href":"/demo/rendering/deferred-encapsulation"}]},{"key":"live","label":"Reactive UI","featureCount":5,"features":[{"section":"rendering","slug":"deferred-live","label":"UI Rendering & SSR","title":"Live Widgets","summary":"A live slot can refresh itself on a timer while the page stays SSR-first — no SPA runtime and no handwritten polling layer.","opensInNewTab":false,"href":"/demo/rendering/deferred-live"},{"section":"rendering","slug":"reactive-report","label":"UI Rendering & SSR","title":"Reactive Report","summary":"Background work updates an SSR-first slot in place, so the UI feels live without falling back to SPA state orchestration.","opensInNewTab":false,"href":"/demo/rendering/reactive-report"},{"section":"rendering","slug":"reactive-import","label":"UI Rendering & SSR","title":"Reactive Import","summary":"Background batches keep moving, and the page reflects server progress as live HTML instead of a client-managed progress app.","opensInNewTab":false,"href":"/demo/rendering/reactive-import"},{"section":"rendering","slug":"reactive-analytics","label":"UI Rendering & SSR","title":"Reactive Analytics","summary":"Independent analytics jobs can light up one dashboard progressively, while the page stays server-rendered from the first byte.","opensInNewTab":false,"href":"/demo/rendering/reactive-analytics"},{"section":"rendering","slug":"reactive-ai","label":"UI Rendering & SSR","title":"Reactive AI Task","summary":"Submit a task and watch the AI pipeline stages reveal one by one as the cron job processes it.","opensInNewTab":false,"href":"/demo/rendering/reactive-ai"}]}]},{"key":"platform","label":"Tenancy","summary":"Multi-tenant resolution, tenant-aware configuration, and strict isolation of data and background work.","icon":"TN","eyebrow":"Multi-Tenant","starter":false,"prerequisites":["data","rendering"],"featureCount":5,"href":"/demo/platform","features":[{"section":"platform","slug":"tenancy-resolution","label":"Tenancy","title":"Tenant Context Resolution","summary":"See how Semitexa resolves the active tenant from subdomain, header, path, or query input before the rest of the platform runs.","opensInNewTab":false,"href":"/demo/platform/tenancy-resolution"},{"section":"platform","slug":"tenancy-config","label":"Tenancy","title":"Per-Tenant Configuration","summary":"Three demo tenants with distinct branding -- switch tenant, everything changes without if/else.","opensInNewTab":false,"href":"/demo/platform/tenancy-config"},{"section":"platform","slug":"tenancy-layers","label":"Tenancy","title":"Multi-Layer Tenancy","summary":"Organization, Locale, Theme, Environment -- four independent layers compose into one TenantContext.","opensInNewTab":false,"href":"/demo/platform/tenancy-layers"},{"section":"platform","slug":"tenancy-isolation","label":"Tenancy","title":"Data Isolation","summary":"Product listing scoped by tenant -- switch tenant, list changes. Zero manual WHERE clauses.","opensInNewTab":false,"href":"/demo/platform/tenancy-isolation"},{"section":"platform","slug":"tenancy-queue","label":"Tenancy","title":"Queue Tenant Propagation","summary":"Tenant context travels with queued jobs -- _tenant key injected automatically, restored by worker.","opensInNewTab":false,"href":"/demo/platform/tenancy-queue"}],"groups":[{"key":"resolution","label":"Tenant Resolution","featureCount":1,"features":[{"section":"platform","slug":"tenancy-resolution","label":"Tenancy","title":"Tenant Context Resolution","summary":"See how Semitexa resolves the active tenant from subdomain, header, path, or query input before the rest of the platform runs.","opensInNewTab":false,"href":"/demo/platform/tenancy-resolution"}]},{"key":"configuration","label":"Tenant Configuration","featureCount":2,"features":[{"section":"platform","slug":"tenancy-config","label":"Tenancy","title":"Per-Tenant Configuration","summary":"Three demo tenants with distinct branding -- switch tenant, everything changes without if/else.","opensInNewTab":false,"href":"/demo/platform/tenancy-config"},{"section":"platform","slug":"tenancy-layers","label":"Tenancy","title":"Multi-Layer Tenancy","summary":"Organization, Locale, Theme, Environment -- four independent layers compose into one TenantContext.","opensInNewTab":false,"href":"/demo/platform/tenancy-layers"}]},{"key":"isolation","label":"Isolation & Work","featureCount":2,"features":[{"section":"platform","slug":"tenancy-isolation","label":"Tenancy","title":"Data Isolation","summary":"Product listing scoped by tenant -- switch tenant, list changes. Zero manual WHERE clauses.","opensInNewTab":false,"href":"/demo/platform/tenancy-isolation"},{"section":"platform","slug":"tenancy-queue","label":"Tenancy","title":"Queue Tenant Propagation","summary":"Tenant context travels with queued jobs -- _tenant key injected automatically, restored by worker.","opensInNewTab":false,"href":"/demo/platform/tenancy-queue"}]}]},{"key":"api","label":"API","summary":"External API endpoints, machine auth, versioning, and consumer-facing schema behavior.","icon":"API","eyebrow":"Machine","starter":false,"prerequisites":["routing","auth"],"featureCount":7,"href":"/demo/api","features":[{"section":"api","slug":"rest-api","label":"API","title":"REST API","summary":"Classic Semitexa REST endpoints with typed payloads, versioning, and consumer-friendly response shaping.","opensInNewTab":false,"href":"/demo/api/rest-api"},{"section":"api","slug":"structured-errors","label":"API","title":"Structured Errors","summary":"Throw domain exceptions and let semitexa-api map them into stable machine-readable error envelopes.","opensInNewTab":false,"href":"/demo/api/structured-errors"},{"section":"api","slug":"active-version","label":"API","title":"Active Version","summary":"The current collection endpoint with a clean X-Api-Version header and no deprecation noise.","opensInNewTab":false,"href":"/demo/api/active-version"},{"section":"api","slug":"sunset-version","label":"API","title":"Sunset Version","summary":"A deprecated product endpoint that emits both Deprecation and Sunset headers.","opensInNewTab":false,"href":"/demo/api/sunset-version"},{"section":"api","slug":"schema-discovery","label":"API","title":"Schema Discovery","summary":"A mini Swagger-style explorer for the live product API contract, schema endpoint, and response shapes.","opensInNewTab":false,"href":"/demo/api/schema-discovery"},{"section":"api","slug":"graphql","label":"API","title":"GraphQL API","summary":"GraphQL-first Semitexa contracts built with typed payloads and typed output DTOs instead of resolver sprawl.","opensInNewTab":false,"href":"/demo/api/graphql"},{"section":"api","slug":"rest-graphql","label":"API","title":"REST + GraphQL","summary":"One Semitexa use case can serve both REST and GraphQL without duplicating handler logic into separate resolver classes.","opensInNewTab":false,"href":"/demo/api/rest-graphql"}],"groups":[{"key":"public-api","label":"REST Surface","featureCount":4,"features":[{"section":"api","slug":"rest-api","label":"API","title":"REST API","summary":"Classic Semitexa REST endpoints with typed payloads, versioning, and consumer-friendly response shaping.","opensInNewTab":false,"href":"/demo/api/rest-api"},{"section":"api","slug":"structured-errors","label":"API","title":"Structured Errors","summary":"Throw domain exceptions and let semitexa-api map them into stable machine-readable error envelopes.","opensInNewTab":false,"href":"/demo/api/structured-errors"},{"section":"api","slug":"active-version","label":"API","title":"Active Version","summary":"The current collection endpoint with a clean X-Api-Version header and no deprecation noise.","opensInNewTab":false,"href":"/demo/api/active-version"},{"section":"api","slug":"sunset-version","label":"API","title":"Sunset Version","summary":"A deprecated product endpoint that emits both Deprecation and Sunset headers.","opensInNewTab":false,"href":"/demo/api/sunset-version"}]},{"key":"schema","label":"Schema Discovery","featureCount":3,"features":[{"section":"api","slug":"schema-discovery","label":"API","title":"Schema Discovery","summary":"A mini Swagger-style explorer for the live product API contract, schema endpoint, and response shapes.","opensInNewTab":false,"href":"/demo/api/schema-discovery"},{"section":"api","slug":"graphql","label":"API","title":"GraphQL API","summary":"GraphQL-first Semitexa contracts built with typed payloads and typed output DTOs instead of resolver sprawl.","opensInNewTab":false,"href":"/demo/api/graphql"},{"section":"api","slug":"rest-graphql","label":"API","title":"REST + GraphQL","summary":"One Semitexa use case can serve both REST and GraphQL without duplicating handler logic into separate resolver classes.","opensInNewTab":false,"href":"/demo/api/rest-graphql"}]}]},{"key":"cli","label":"CLI","summary":"Operational, introspection, and AI-oriented command surfaces that explain and drive the framework from the terminal.","icon":"CLI","eyebrow":"Operations","starter":false,"prerequisites":["routing"],"featureCount":6,"href":"/demo/cli","features":[{"section":"cli","slug":"describe-commands","label":"CLI","title":"Project Graph Introspection","summary":"Routes, modules, contracts, and handlers can be introspected directly from the CLI instead of reverse-engineering the framework graph by hand.","opensInNewTab":false,"href":"/demo/cli/describe-commands"},{"section":"cli","slug":"runtime-maintenance","label":"CLI","title":"Runtime Maintenance","summary":"Reload workers, clear stale cache, sync registries, lint architecture rules, and probe handler wiring without reaching for ad-hoc shell scripts.","opensInNewTab":false,"href":"/demo/cli/runtime-maintenance"},{"section":"cli","slug":"scaffolding-generators","label":"CLI","title":"Scaffolding Generators","summary":"Scaffold modules, pages, payloads, services, and contracts through commands that already understand Semitexa structure and AI-friendly output modes.","opensInNewTab":false,"href":"/demo/cli/scaffolding-generators"},{"section":"cli","slug":"workers-scheduling","label":"CLI","title":"Workers & Scheduling","summary":"Run queues, scheduler pools, mail delivery, webhooks, and tenant-scoped commands from a coherent operator surface instead of bespoke daemons.","opensInNewTab":false,"href":"/demo/cli/workers-scheduling"},{"section":"cli","slug":"ai-tooling","label":"CLI","title":"AI Tooling Surface","summary":"Semitexa exposes AI-facing commands as explicit CLI contracts: capabilities, skills, log access, and a local assistant entrypoint.","opensInNewTab":false,"href":"/demo/cli/ai-tooling"},{"section":"cli","slug":"orm-console","label":"CLI","title":"ORM Console Toolkit","summary":"The ORM ships with a practical CLI surface: status, diff, sync, and seed commands with dry-run safety and SQL plan export.","opensInNewTab":false,"href":"/demo/cli/orm-console"}],"groups":[{"key":"inspection","label":"Describe & Inspect","featureCount":2,"features":[{"section":"cli","slug":"describe-commands","label":"CLI","title":"Project Graph Introspection","summary":"Routes, modules, contracts, and handlers can be introspected directly from the CLI instead of reverse-engineering the framework graph by hand.","opensInNewTab":false,"href":"/demo/cli/describe-commands"},{"section":"cli","slug":"runtime-maintenance","label":"CLI","title":"Runtime Maintenance","summary":"Reload workers, clear stale cache, sync registries, lint architecture rules, and probe handler wiring without reaching for ad-hoc shell scripts.","opensInNewTab":false,"href":"/demo/cli/runtime-maintenance"}]},{"key":"automation","label":"Automation","featureCount":4,"features":[{"section":"cli","slug":"scaffolding-generators","label":"CLI","title":"Scaffolding Generators","summary":"Scaffold modules, pages, payloads, services, and contracts through commands that already understand Semitexa structure and AI-friendly output modes.","opensInNewTab":false,"href":"/demo/cli/scaffolding-generators"},{"section":"cli","slug":"workers-scheduling","label":"CLI","title":"Workers & Scheduling","summary":"Run queues, scheduler pools, mail delivery, webhooks, and tenant-scoped commands from a coherent operator surface instead of bespoke daemons.","opensInNewTab":false,"href":"/demo/cli/workers-scheduling"},{"section":"cli","slug":"ai-tooling","label":"CLI","title":"AI Tooling Surface","summary":"Semitexa exposes AI-facing commands as explicit CLI contracts: capabilities, skills, log access, and a local assistant entrypoint.","opensInNewTab":false,"href":"/demo/cli/ai-tooling"},{"section":"cli","slug":"orm-console","label":"CLI","title":"ORM Console Toolkit","summary":"The ORM ships with a practical CLI surface: status, diff, sync, and seed commands with dry-run safety and SQL plan export.","opensInNewTab":false,"href":"/demo/cli/orm-console"}]}]},{"key":"project-graph","label":"Project Graph","summary":"The `semitexa-project-graph` package: stored structural graph, intelligence layer, impact analysis, and task-scoped context for serious repository work.","icon":"PG","eyebrow":"AI Accelerator","starter":true,"prerequisites":["cli"],"featureCount":3,"href":"/demo/project-graph","features":[{"section":"project-graph","slug":"overview","label":"Project Graph","title":"Project Graph Overview","summary":"Understand what `semitexa-project-graph` adds: a stored structural map, an intelligence layer, and task-scoped context for large-codebase work.","opensInNewTab":false,"href":"/demo/project-graph/overview"},{"section":"project-graph","slug":"inspection","label":"Project Graph","title":"Inspecting the Graph","summary":"Use Project Graph queries and intelligence views to inspect modules, dependencies, flows, events, and hotspots without reconstructing the repository manually.","opensInNewTab":false,"href":"/demo/project-graph/inspection"},{"section":"project-graph","slug":"impact","label":"Project Graph","title":"Impact, Context, and Watch Mode","summary":"Use impact analysis, context packing, and watch mode to scope risky changes and keep graph-backed answers current during long work sessions.","opensInNewTab":false,"href":"/demo/project-graph/impact"}],"groups":[{"key":"launch","label":"Start Here","featureCount":1,"features":[{"section":"project-graph","slug":"overview","label":"Project Graph","title":"Project Graph Overview","summary":"Understand what `semitexa-project-graph` adds: a stored structural map, an intelligence layer, and task-scoped context for large-codebase work.","opensInNewTab":false,"href":"/demo/project-graph/overview"}]},{"key":"exploration","label":"Explore & Inspect","featureCount":1,"features":[{"section":"project-graph","slug":"inspection","label":"Project Graph","title":"Inspecting the Graph","summary":"Use Project Graph queries and intelligence views to inspect modules, dependencies, flows, events, and hotspots without reconstructing the repository manually.","opensInNewTab":false,"href":"/demo/project-graph/inspection"}]},{"key":"change-safety","label":"Impact & Context","featureCount":1,"features":[{"section":"project-graph","slug":"impact","label":"Project Graph","title":"Impact, Context, and Watch Mode","summary":"Use impact analysis, context packing, and watch mode to scope risky changes and keep graph-backed answers current during long work sessions.","opensInNewTab":false,"href":"/demo/project-graph/impact"}]}]},{"key":"llm","label":"LLM Module","sidebarLabel":"LLM","summary":"The dedicated `semitexa/llm` module: AI assistant entrypoint, skill discovery, planner, executor, provider backends, and skill authoring rules.","icon":"AI","eyebrow":"semitexa/llm","starter":false,"prerequisites":["cli"],"featureCount":4,"href":"/demo/llm","features":[{"section":"llm","slug":"overview","label":"LLM Module","title":"LLM Module Overview","summary":"What `semitexa/llm` adds to the framework and how your project can expose its own CLI skills to the assistant.","opensInNewTab":false,"href":"/demo/llm/overview"},{"section":"llm","slug":"providers","label":"LLM Module","title":"Providers & Backends","summary":"Provider contracts, backend resolution, local vs remote Ollama, and the environment knobs that shape LLM runtime behavior.","opensInNewTab":false,"href":"/demo/llm/providers"},{"section":"llm","slug":"skills","label":"LLM Module","title":"Adding Skills","summary":"How a console command becomes AI-executable through `#[AsAiSkill]`, metadata policy, and registry discovery.","opensInNewTab":false,"href":"/demo/llm/skills"},{"section":"llm","slug":"execution-flow","label":"LLM Module","title":"Execution Flow","summary":"How a user request becomes a planner decision, a reviewed skill proposal, and finally a real console execution.","opensInNewTab":false,"href":"/demo/llm/execution-flow"}],"groups":[{"key":"assistant-basics","label":"Assistant Surface","featureCount":2,"features":[{"section":"llm","slug":"overview","label":"LLM Module","title":"LLM Module Overview","summary":"What `semitexa/llm` adds to the framework and how your project can expose its own CLI skills to the assistant.","opensInNewTab":false,"href":"/demo/llm/overview"},{"section":"llm","slug":"providers","label":"LLM Module","title":"Providers & Backends","summary":"Provider contracts, backend resolution, local vs remote Ollama, and the environment knobs that shape LLM runtime behavior.","opensInNewTab":false,"href":"/demo/llm/providers"}]},{"key":"skill-system","label":"Skill System","featureCount":2,"features":[{"section":"llm","slug":"skills","label":"LLM Module","title":"Adding Skills","summary":"How a console command becomes AI-executable through `#[AsAiSkill]`, metadata policy, and registry discovery.","opensInNewTab":false,"href":"/demo/llm/skills"},{"section":"llm","slug":"execution-flow","label":"LLM Module","title":"Execution Flow","summary":"How a user request becomes a planner decision, a reviewed skill proposal, and finally a real console execution.","opensInNewTab":false,"href":"/demo/llm/execution-flow"}]}]},{"key":"testing","label":"Testing","summary":"Contract-level verification patterns for payloads and other framework boundaries.","icon":"QA","eyebrow":"Verification","starter":false,"prerequisites":["routing"],"featureCount":1,"href":"/demo/testing","features":[{"section":"testing","slug":"payload-contracts","label":"Testing","title":"Payload Contract Testing","summary":"Run one project-level contract suite through the canonical test runner and let strategy profiles verify payload boundaries without hand-writing repetitive negative cases.","opensInNewTab":false,"href":"/demo/testing/payload-contracts"}],"groups":[{"key":"contracts","label":"Contracts","featureCount":1,"features":[{"section":"testing","slug":"payload-contracts","label":"Testing","title":"Payload Contract Testing","summary":"Run one project-level contract suite through the canonical test runner and let strategy profiles verify payload boundaries without hand-writing repetitive negative cases.","opensInNewTab":false,"href":"/demo/testing/payload-contracts"}]}]}]}],"currentSection":"cli","currentSlug":"scaffolding-generators","infoWhat":"Semitexa generators scaffold framework-native files and can also emit machine-readable planning hints for AI-assisted implementation.","infoHow":"Commands like make:module, make:page, make:payload, make:service, and make:contract use builders and template resolvers to produce correctly placed files, with dry-run, JSON, and llm-hints modes where appropriate.","infoWhy":"Good scaffolding is not just about speed. It teaches the expected architecture by generating the right boundaries and naming conventions from the start.","infoKeywords":[{"term":"make:page","definition":"Scaffolds a complete page boundary: payload, handler, resource, and template."},{"term":"--llm-hints","definition":"Outputs a machine-readable envelope describing what files were created and what should be implemented next."},{"term":"dry-run","definition":"Lets the user inspect the generation plan before any files are written."}],"navMode":"catalog","activeLayerKey":"full-catalog","authUi":{"isAuthenticated":false,"label":"Google user","shortLabel":"Google","email":null,"startUrl":"/demo/auth/google/start?return_to=%2Fdemo","authPageUrl":"/demo/auth/google?return_to=%2Fdemo","accountUrl":"/demo/auth/google?return_to=%2Fdemo","logoutUrl":"/demo/auth/google/logout?return_to=%2Fdemo","actionLabel":"Sign in with Google","signInTitle":"Sign in with Google to unlock advanced demos","signedInLabel":"Authorized as"},"explanation":{"what":"Semitexa generators scaffold framework-native files and can also emit machine-readable planning hints for AI-assisted implementation.","how":"Commands like make:module, make:page, make:payload, make:service, and make:contract use builders and template resolvers to produce correctly placed files, with dry-run, JSON, and llm-hints modes where appropriate.","why":"Good scaffolding is not just about speed. It teaches the expected architecture by generating the right boundaries and naming conventions from the start.","keywords":[{"term":"make:page","definition":"Scaffolds a complete page boundary: payload, handler, resource, and template."},{"term":"--llm-hints","definition":"Outputs a machine-readable envelope describing what files were created and what should be implemented next."},{"term":"dry-run","definition":"Lets the user inspect the generation plan before any files are written."}]},"sourceCode":{"make:module Command":"","make:page Command":"","make:payload Command":"","make:service Command":"","make:contract Command":""},"resultPreviewTemplate":"@project-layouts-semitexa-demo/components/previews/cli-command-workbench.html.twig","resultPreviewData":{"eyebrow":"Code Generation","title":"Scaffolding that already knows Semitexa conventions","summary":"These commands do not just dump stubs. They encode module structure, naming, response boundaries, and even AI-oriented follow-up hints, so the generated result starts aligned with the framework.","pillars":[{"title":"Structure-aware.","summary":"make:module and make:page know the expected module, payload, handler, resource, and template layout without asking the developer to assemble it manually."},{"title":"Machine-readable when needed.","summary":"Dry-run, JSON, and --llm-hints modes let both humans and agents inspect the plan before committing files."},{"title":"Teaches the shape.","summary":"Good scaffolding shortens onboarding because the produced files demonstrate the intended Semitexa architecture directly."}],"commands":[{"name":"bin/semitexa make:module --name=Catalog","purpose":"Create a new module with standard directories already in place.","value":"Removes the need to remember directory conventions or Composer changes."},{"name":"bin/semitexa make:page --module=Catalog --name=Pricing --path=/pricing --method=GET","purpose":"Scaffold a full SSR page boundary in one step.","value":"Creates the payload, handler, resource, and template as a coherent unit."},{"name":"bin/semitexa make:payload --module=Catalog --name=CreateProduct --path=/products --method=POST --response=CreateProduct","purpose":"Generate only the transport boundary when you need a narrower step.","value":"Useful when the payload contract should be reviewed before the rest of the implementation."},{"name":"bin/semitexa make:contract --module=Catalog --name=PriceFeed --implementation=ApiPriceFeed --llm-hints","purpose":"Scaffold a DI contract plus implementation and emit follow-up hints.","value":"Great fit for AI-assisted workflows because the command can describe what to fill next."}],"snippets":[{"label":"Preview a new page without writing files","code":"bin/semitexa make:page --module=Catalog --name=Pricing --path=/pricing --method=GET --dry-run"},{"label":"Generate a payload with agent-friendly hints","code":"bin/semitexa make:payload --module=Catalog --name=CreateProduct --path=/products --method=POST --response=CreateProduct --llm-hints"},{"label":"Scaffold a contract and verify it after generation","code":"bin/semitexa make:contract --module=Catalog --name=PriceFeed --implementation=ApiPriceFeed\nbin/semitexa contracts:list --json"}]},"l2ContentTemplate":"@project-layouts-semitexa-demo/components/previews/checklist-panel.html.twig","l2ContentData":{"eyebrow":"Generator Rule","title":"When scaffolding actually adds value","summary":"The point is not fewer keystrokes. The point is fewer incorrect architectural starts.","rules":["Use generators to establish the canonical file and attribute shape before implementation details creep in.","Prefer dry-run, JSON, or llm-hints when you want reviewers or agents to inspect the plan before files are written.","Treat generated files as architectural starting points, not as final code that excuses design thinking.","A scaffold is successful when it reduces wrong framework patterns, not only when it saves typing."]},"__page_document_html_iri":"/demo/cli/scaffolding-generators","__page_document_json_iri":"/demo/cli/scaffolding-generators?_format=json","__page_alternates":[{"type":"application/json","href":"/demo/cli/scaffolding-generators?_format=json"}]}