agent-side is an AI-safe document and site generation layer.
It is designed for workflows where AI agents generate or edit documents, but humans still need to review the result comfortably and safely.
Agents write structured meaning.
Renderers generate human-readable output.
Humans review the rendered result in a browser.
AI agents should not directly edit fragile HTML, CSS, or loosely structured Markdown.
Instead, they should edit a structured document IR written in YAML.
flowchart TD
A[Agent / Human]
B[YAML DocIR]
C[Loader]
D[Validator]
E[Normalized AST]
F[Renderer]
G[Readable HTML]
A --> B --> C --> D --> E --> F --> G
The generated HTML is an output artifact. It is not the primary editing target.
Markdown is easy to write, but it becomes ambiguous as documents grow.
Common problems include:
- Tables become hard to maintain.
- Custom extensions differ between renderers.
- Notices, cards, tabs, accordions, and diagrams are not standardized.
- AI agents may break layout or semantics when editing raw HTML.
- Humans are forced to review long AI-generated Markdown directly.
- Visual structure is hard to understand in plain text.
agent-side introduces a structured document layer between AI output and rendered HTML.
Agents write meaning, not presentation.
For example, an agent should write this:
type: notice
tone: warning
title: Presentation Leakage
body: DocIR must not contain renderer-specific class names.The renderer decides how it should look.
For example, the current Bootstrap renderer may output an alert. A future Tailwind renderer could output a styled callout from the same DocIR.
The agent should not write Bootstrap classes, Tailwind utility classes, inline styles, or arbitrary HTML layout.
agent-side is:
- a structured document IR for AI-assisted workflows
- a renderer layer for human-readable review output
- a safer alternative to letting agents edit raw HTML
- a way to generate readable documents, reports, notes, and small static pages
- a foundation for future render targets
agent-side is currently under active implementation. The available renderers are Plain HTML, Bootstrap HTML, and Markdown. Some block types described below are design goals, not complete features yet.
agent-side is not:
- a full website builder
- a WYSIWYG editor
- a Markdown extension format
- a replacement for every static site generator
- a Bootstrap clone
- an HTML5 specification wrapper
- a free-form CSS layout system
The goal is not to support every possible visual expression.
The goal is to let AI agents safely produce structured documents that humans can comfortably review.
The main document format is YAML.
Example:
page:
title: agent-side sample
lang: en
lead: A complex DocIR sample for validating renderer behavior, nested structures, semantic blocks, and AI-safe document editing.
blocks:
- type: notice
tone: info
title: Editing Rule
body: Agents edit YAML DocIR, not raw HTML or CSS.
- type: section
title: Core Concept
blocks:
- type: paragraph
text: DocIR captures document meaning in YAML.
- type: mermaid
title: Generation Flow
diagram: |
flowchart LR
A[Agent or Human] --> B[DocIR YAML]
B --> C[Loader]
C --> D[Validator]
D --> E[Renderer]
E --> F[Readable HTML]
- type: cards
title: Main Components
layout: 3col
items:
- title: Loader
body: Reads YAML files, resolves include blocks, and prevents invalid paths or circular references.
badge: input
- title: Validator
body: Checks block types, required fields, forbidden presentation keys, and table row shape.
badge: safety
- title: Normalizer
body: Converts validated DocIR into a stable internal AST with defaults applied.
badge: structure
- title: Renderer
body: Converts the normalized AST into readable HTML using theme tokens and renderer rules.
badge: output
- title: Theme
body: Stores visual decisions outside DocIR so agents cannot freely modify presentation details.
badge: external
- title: Preview
body: Serves generated output locally and helps humans review changes in a browser.
badge: review
- type: decision
title: Primary Editing Target
decision: YAML DocIR is the source of truth.
rationale: Generated HTML is an artifact and should be easy to regenerate.Screenshots:
Project configuration should be stored in docir.toml.
Example:
[site]
title = "agent-side sample"
lang = "en"
entry = "docs/index.yml"
out_dir = "dist"
[renderer]
name = "plain"
theme = "default"
[renderer.mermaid]
mode = "cdn"
[include]
base_dir = "docs"
allow_parent = false
[validation]
strict = true
unknown_keys = "error"
[theme]
path = "themes/default.yml"agent-side/
docir.toml
docs/
index.yml
sections/
concept.yml
renderer.yml
themes/
default.yml
dist/
src/
tests/
Large documents can be split into multiple YAML files.
Use include blocks:
type: include
src: ./sections/concept.ymlInclude resolution is handled by the loader.
The renderer should receive a fully resolved normalized AST and should not care about file boundaries.
The loader should detect:
- missing include files
- circular includes
- parent directory traversal when disabled
- invalid YAML
- invalid included block types
The same DocIR is intended to be renderable into multiple targets.
Currently available:
- Plain HTML
- Bootstrap HTML
- Markdown
Planned or exploratory renderers:
- Tailwind HTML
- email HTML
- GitHub Pages
- WordPress blocks
Select the renderer with [renderer].name in docir.toml:
[renderer]
name = "plain"Supported values:
plainbootstrapmarkdown
Plain HTML is the baseline renderer and works well with the default single output mode.
Bootstrap HTML is the enhanced browser preview renderer.
Markdown exports DocIR back into readable Markdown.
Sample files:
Visual rendering rules should be stored outside DocIR.
Example:
name: default
blocks:
page:
container: lg
section:
spacing: normal
heading: h2
cards:
gap: normal
border: true
shadow: sm
radius: md
notice:
style: softTheme support is still being expanded.
Currently applied by the Bootstrap renderer:
tokens.accenttokens.surfacetokens.textblocks.page.containerblocks.section.spacing
Other theme fields in the example are accepted as forward-compatible design settings, but they are not all applied yet. The renderer maps implemented theme tokens to actual output-specific styles.
DocIR may contain limited semantic layout hints such as:
layout: 2col
width: wide
align: center
tone: warning
priority: highDocIR must not contain:
classstylemarginpaddingfont-sizecolor- renderer-specific class names
DocIR may contain Mermaid source.
Example:
type: mermaid
title: Generation Flow
diagram: |
flowchart TD
A[Agent] --> B[DocIR YAML]
B --> C[Validator]
C --> D[Renderer]
D --> E[Readable HTML]DocIR stores the diagram source.
The renderer decides how Mermaid is rendered.
Mermaid mode is configurable, but only cdn is implemented today.
Implemented:
cdn
Accepted by configuration but not implemented yet:
bundledpre_rendered
Those unimplemented modes fail explicitly instead of silently producing incomplete output.
Mermaid rendering failure should not break the entire document.
Recommended fallback behavior:
- show the Mermaid source in a visible block
- display a clear error message near the diagram
- keep the rest of the document usable
- optionally expose the original Mermaid source for debugging
Tables must use key-value rows.
Two-dimensional arrays are forbidden because they are position-dependent and easy for AI agents to break.
Do not use:
rows:
- [Bootstrap, easy, good]
- [Tailwind, flexible, complex]Use this instead:
type: table
title: Renderer Comparison
columns:
- key: renderer
label: Renderer
- key: merit
label: Merit
- key: concern
label: Concern
rows:
- renderer: Bootstrap
merit: Many components are available
concern: Appearance may feel Bootstrap-like
- renderer: Tailwind
merit: Flexible design
concern: Renderer needs more design rulesThe validator should reject array-based table rows.
The architecture should allow these semantic block types.
Currently implemented block types include:
sectionparagraphsummarypointslistnoticecardstablecomparekeyValuecodecommandoutputfileTreemermaiddecisiontodoissueriskassumptionconstraintopenQuestionchecklistquotereferenceinclude
Planned or not fully implemented yet:
pagetextstepsdefinitionglossarydifffigurelinkList
The first implementation does not need to support all of them completely, but the architecture should allow them to be added cleanly.
Generated HTML should be readable, stable, and structurally correct.
The renderer must not hard-code lang="en".
The HTML language should be configurable from project configuration or page metadata.
Preferred order:
page.langin DocIR[site].langindocir.toml- fallback value such as
en
Example:
<html lang="ja">The renderer must preserve a correct heading hierarchy.
Do not render every block title as h2.
The renderer should track nesting depth and choose headings accordingly.
Example:
<h1>Page Title</h1>
<section>
<h2>Top Level Section</h2>
<section>
<h3>Nested Block Title</h3>
</section>
</section>Visual size may be adjusted with CSS classes, but the semantic heading level should remain correct.
The renderer should avoid unstable or noisy HTML output.
Avoid:
<section class="doc-section ">Prefer:
<section class="doc-section">Class names should be joined safely and empty class tokens should be removed.
Use semantic HTML where practical.
Examples:
mainfor the document bodysectionfor document sectionsarticlefor standalone semantic blocks such as decisions or riskstable,thead,tbody,th, andtdfor tablesscope="col"for table headers
Notice-like blocks may use role="note" by default.
Use stronger roles such as role="alert" only when the content should interrupt assistive technology users.
The CLI currently provides:
agent-side init
agent-side validate
agent-side render
agent-side preview
preview renders the document and serves the generated output locally.
Automatic watching and live re-rendering are still planned.
Expected usage:
agent-side validate docs/index.yml
agent-side render docs/index.yml --out dist
agent-side previewRenderer selection is configured in docir.toml:
[renderer]
name = "plain" # plain | bootstrap | markdownRender output modes:
agent-side render docs/index.yml --out dist --mode single
agent-side render docs/index.yml --out dist --mode bundle
agent-side render docs/index.yml --out dist --mode sitesingle is the default. HTML renderers write dist/index.html; the Markdown renderer writes dist/index.md.
bundle and site currently write index.html plus assets/agent-side.css.
Use TypeScript for the first implementation.
Currently used libraries include:
typescripttsxzodyamlsmol-tomlcommanderpathehtml-escapersirvvitevitest
Planned or optional libraries under consideration:
consolafs-extrachokidaretamermaidhappy-domeslintprettier
Recommended order:
- Create project structure.
- Load
docir.toml. - Load YAML DocIR.
- Resolve include blocks.
- Define Zod schemas.
- Validate DocIR.
- Normalize into AST.
- Implement Bootstrap renderer.
- Output
dist/index.html. - Add snapshot tests.
- Add preview server.
- Add Mermaid rendering support.
- Add theme support.
- Expand block types.
The loader is responsible for:
- reading YAML files
- resolving includes
- preventing invalid paths
- detecting circular includes
- returning a complete unresolved or resolved document tree
The validator is responsible for:
- checking block types
- rejecting invalid fields
- rejecting unknown keys in strict mode
- rejecting array-based table rows
- checking required fields
- validating config and theme files
The normalizer is responsible for:
- converting valid DocIR into a stable internal AST
- applying defaults
- resolving shorthand forms if supported
- preparing data for renderer consumption
The renderer is responsible for:
- converting AST into HTML
- applying theme tokens
- escaping unsafe text
- rendering block types
- including required assets
- handling Mermaid rendering mode
- generating readable output
The preview system is responsible for:
- serving generated HTML locally
- making human review easy
Planned preview capabilities:
- watching YAML, theme, and config changes
- re-rendering on change
Renderer snapshot tests should cover at least:
- notice
- section
- mermaid
- decision
- table
- cards
- risk
- include-resolved documents
- nested heading structures
Snapshot tests should verify stable HTML output and prevent accidental renderer regressions.
agent-side is an AI-safe document rendering layer.
Agents write structured meaning. Renderers create human-readable output. Humans review the result in a browser.
The core value is not static site generation itself.
The core value is preventing AI agents from breaking documents while still allowing them to express rich information structures.
This project is licensed under the MIT License.
See LICENSE for details.
