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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions .agent/workflows/implement-design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
description: Implement a new CMS module from a design screenshot and add it to a page.
---

# Workflow: Implement Design

This workflow guides the Root Agent to create a new CMS module from a visual design and integrate it into a page.

## 1. Analyze Design

- [ ] Examine the provided screenshot.
- [ ] Identify the component name (e.g., `TemplateFeatureCards`).
- [ ] Determine necessary fields (title, body, image, list items, etc.).
- [ ] Identify reusable UI components (Buttons, Text, etc.).

## 2. Create Module Files

- [ ] Create directory: `docs/blocks/<Name>/` or `docs/templates/<Name>/`.
- [ ] Create `<Name>.schema.ts`: Define fields using `@blinkk/root-cms`.
- [ ] Create `<Name>.module.scss`: Implement styles using CSS modules.
- [ ] Create `<Name>.tsx`: Implement React component using `useTranslations`, `RichText`, and `node`.

## 3. Verify Schema

- [ ] Run `npm run build:core` (or wait for watcher) to generate types in `root-cms.d.ts`.
- [ ] Ensure the new block is available in the project schema.

## 4. Add to Page (Optional)

If the user requested adding it to a page:

- [ ] **Get Schema**: `collections_get_schema(collectionId='<Collection>')`.
- [ ] **Fetch Page**: `docs_get(collectionId='<Collection>', slug='<Slug>')`.
- [ ] **Construct Data**: Create a JSON object for the new block.
- Remember `_type: '<Name>'`.
- Remember richtext format: `{"blocks": [...]}`.
- [ ] **Update Page**: Append the new block to the `modules` array (or target field).
- [ ] **Save**: `docs_save(collectionId='<Collection>', slug='<Slug>', data=...)`.

## 5. Final Review

- [ ] Check if the module renders correctly in the CMS preview (if possible) or ask user to verify.
69 changes: 69 additions & 0 deletions .cursorrules
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Root Agent Configuration

You are the **Root Agent**, an expert AI engineer specializing in the Root.js framework and Root CMS. Your goal is to autonomously implement features, designs, and content updates based on high-level user requests and visual inputs (screenshots).

## Capabilities

1. **Code Generation**: You can create new CMS modules (blocks/templates) by analyzing screenshots or descriptions. You follow strict project conventions.
2. **Content Management**: You use the `root-cms` MCP server to interact with the CMS, allowing you to query schemas, list documents, and update content.
3. **Visual Implementation**: You can translate visual designs (screenshots) into pixel-perfect React components using SCSS modules and Root.js primitives.

## Project Conventions

### Modules (Blocks & Templates)

- **Location**:
- Reusable blocks: `docs/blocks/<Name>/`
- Page templates: `docs/templates/<Name>/`
- **Files**:
- `<Name>.schema.ts`: Defines the CMS schema using `@blinkk/root-cms`.
- `<Name>.tsx`: The React component.
- `<Name>.module.scss`: Styles using CSS modules and `@layer component`.
- **Schema**:
- Use `schema.define({ name: '<Name>', fields: [...] })`.
- Common fields: `id`, `options`, `eyebrow`, `title`, `body`, `image`.
- **ALWAYS** use `schema.richtext` for body copy.
- **Component**:
- Import `useTranslations` from `@blinkk/root`.
- Import `RichText` from `@blinkk/root-cms/richtext` for richtext fields.
- Import `node` from `@/components/RootNode/RootNode.js` for CMS editing overlays.
- Use `Text` component from `@/components/Text/Text.js` for typography.
- Export a named function component matching the directory name.
- **NEVER** use `export default`. Always use named exports (e.g., `export function Name()`).
- Props type should **ALWAYS** use the types generated by `regenerate_types` (in `root-cms.d.ts`), e.g. `<Name>Doc` or `<Name>Fields`. **NEVER** inline props.

## Workflow: Implement Design

When asked to "Build this module" or "Implement this design":

1. **Analyze**: Look at the provided screenshot/description. Identify the structure, fields needed, and layout.
2. **Scaffold**: Use `node packages/root/bin/root.js codegen block <Name> --out docs/blocks` or `node packages/root/bin/root.js codegen template <Name> --out docs/templates` to generate the files.
3. **Implement**:
- Write the schema first.
- Write the SCSS (use `tokens` for colors/spacing if available).
- Write the React component, wiring up props to the CMS fields.
4. **Register**: Ensure the new module is discoverable. (Note: `root dev` automatically updates `root-cms.d.ts`. If not running, run `npm run types`).
5. **Integrate**: If asked to add it to a page:
- Use `collections_get_schema` to check the page schema.
- Use `docs_get` to fetch the current page content.
- Construct the new block data (following the schema).
- If the design includes images, use placeholder data URI SVG images for the image fields.
- Append the block to the appropriate `modules` array in the page content.
- Use `docs_save` to update the page.

## MCP Tools Usage

- **Check Schema**: Always call `collections_get_schema` before creating content to ensure you match the expected structure.
- **Richtext**: When creating richtext content, ALWAYS use the EditorJS format: `{"blocks": [{"type": "paragraph", "data": {"text": "..."}}]}`.
- **OneOf Fields**: When adding to a `oneof` array (like `modules`), ALWAYS include `_type: '<ModuleName>'`.

## Example Command

> "Build this module from the screenshot, name it 'FeatureCards', and add it to the 'Pages/index' page."

1. Run `node packages/root/bin/root.js codegen block FeatureCards --out docs/blocks`.
- This creates `docs/blocks/FeatureCards/FeatureCards.schema.ts`, `.tsx`, `.module.scss`.
2. Call `collections_get_schema(collectionId='Pages')`.
3. Call `docs_get(collectionId='Pages', slug='index')`.
4. Add `{ _type: 'FeatureCards', ...fields }` to `modules`.
5. Call `docs_save(collectionId='Pages', slug='index', data=updatedData)`.
44 changes: 44 additions & 0 deletions .github/agents/root-agent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Root Agent

The **Root Agent** is an AI-powered workflow designed to automate the end-to-end process of building Root CMS modules from visual designs and managing content.

## Setup

1. **Configuration**: Ensure the `.cursorrules` file is present in the root of your project. This file instructs the AI assistant on project conventions and capabilities.
2. **MCP Server**: Ensure the `root-cms` MCP server is running and connected to your editor.
- Command: `root-cms mcp` (usually handled by your editor's MCP client).

## Usage

You can interact with the Root Agent directly in your editor's chat interface (e.g., Cursor Chat).

### Scenario: Build from Screenshot

1. **Upload Screenshot**: Drag and drop a design screenshot into the chat.
2. **Prompt**: Give a high-level command.
> "Build this module, name it `TemplateFeatureCards`, and add it to the `Pages/index` page."

### What the Agent Does

1. **Analysis**: It analyzes the screenshot to understand the layout and fields.
2. **Coding**: It creates the necessary files in `docs/blocks/` or `docs/templates/`:
- `Schema`: Defines the data structure.
- `Component`: React code with `useTranslations` and `RichText`.
- `Styles`: SCSS with CSS modules.
3. **Integration**: It uses the MCP tools to:
- Fetch the schema for `Pages`.
- Fetch the content of `Pages/index`.
- Append the new `TemplateFeatureCards` block to the page's `modules` list.
- Save the updated page.

## Workflows

We have defined specific workflows in `.agent/workflows/` to guide the agent:

- **`implement-design.md`**: The standard flow for converting a design to a CMS module.

## Tips

- **Be Specific**: If you have specific naming preferences or existing components to reuse, mention them.
- **Richtext**: The agent knows to use EditorJS format for richtext fields.
- **Review**: Always review the generated code and the CMS content update.
9 changes: 9 additions & 0 deletions .vscode/mcp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"servers": {
"root-cms": {
"command": "pnpm",
"args": ["exec", "root-cms", "mcp"],
"cwd": "./docs/"
}
}
}
46 changes: 46 additions & 0 deletions ROOT_AGENT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Root Agent

The **Root Agent** is an AI-powered workflow designed to automate the end-to-end process of building Root CMS modules from visual designs and managing content.

## Setup

1. **Configuration**: Ensure the `.cursorrules` file is present in the root of your project. This file instructs the AI assistant on project conventions and capabilities.
2. **MCP Server**: Ensure the `root-cms` MCP server is running and connected to your editor.
- Command: `root-cms mcp` (usually handled by your editor's MCP client).

## Usage

You can interact with the Root Agent directly in your editor's chat interface (e.g., Cursor Chat).

### Scenario: Build from Screenshot

1. **Upload Screenshot**: Drag and drop a design screenshot into the chat.
2. **Prompt**: Give a high-level command.
> "Build this module, name it `TemplateFeatureCards`, and add it to the `Pages/index` page."

### What the Agent Does

1. **Analysis**: It analyzes the screenshot to understand the layout and fields.
2. **Coding**: It creates the necessary files in `docs/blocks/` or `docs/templates/`:
- `Schema`: Defines the data structure.
- `Component`: React code with `useTranslations` and `RichText`.
- `Styles`: SCSS with CSS modules.
- **Note**: It uses `node packages/root/bin/root.js codegen block <Name> --out docs/blocks` to scaffold these files.
- **Note**: `root dev` automatically updates `root-cms.d.ts`. If not running, run `npm run types`.
3. **Integration**: It uses the MCP tools to:
- Fetch the schema for `Pages`.
- Fetch the content of `Pages/index`.
- Append the new `TemplateFeatureCards` block to the page's `modules` list.
- Save the updated page.

## Workflows

We have defined specific workflows in `.agent/workflows/` to guide the agent:

- **`implement-design.md`**: The standard flow for converting a design to a CMS module.

## Tips

- **Be Specific**: If you have specific naming preferences or existing components to reuse, mention them.
- **Richtext**: The agent knows to use EditorJS format for richtext fields.
- **Review**: Always review the generated code and the CMS content update.
11 changes: 11 additions & 0 deletions codegen/block/[name].module.scss.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
@use 'tokens';

@layer component {
.root {
padding: 40px 0;
}

.title {
margin-bottom: 20px;
}
}
15 changes: 15 additions & 0 deletions codegen/block/[name].schema.ts.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import {schema} from '@blinkk/root-cms';

export default schema.define({
name: '[[name]]',
fields: [
schema.string({
id: 'title',
label: 'Title',
}),
schema.richtext({
id: 'body',
label: 'Body',
}),
],
});
24 changes: 24 additions & 0 deletions codegen/block/[name].tsx.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import {useTranslations} from '@blinkk/root';
import {RichText} from '@blinkk/root-cms/richtext';
import {node} from '@/components/RootNode/RootNode.js';
import {Text} from '@/components/Text/Text.js';
import {[[name]]Fields} from '@/root-cms.js';
import styles from './[[name]].module.scss';

export function [[name]](props: [[name]]Fields) {
const t = useTranslations();
return (
<div className={styles.root}>
{props.title && (
<Text as="h2" className={styles.title}>
{node('title', t(props.title))}
</Text>
)}
{props.body && (
<div className={styles.body}>
{node('body', <RichText data={props.body} />)}
</div>
)}
</div>
);
}
11 changes: 11 additions & 0 deletions codegen/template/[name].module.scss.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
@use 'tokens';

@layer component {
.root {
padding: 40px 0;
}

.title {
margin-bottom: 20px;
}
}
15 changes: 15 additions & 0 deletions codegen/template/[name].schema.ts.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import {schema} from '@blinkk/root-cms';

export default schema.define({
name: '[[name]]',
fields: [
schema.string({
id: 'title',
label: 'Title',
}),
schema.richtext({
id: 'body',
label: 'Body',
}),
],
});
24 changes: 24 additions & 0 deletions codegen/template/[name].tsx.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import {useTranslations} from '@blinkk/root';
import {RichText} from '@blinkk/root-cms/richtext';
import {node} from '@/components/RootNode/RootNode.js';
import {Text} from '@/components/Text/Text.js';
import {[[name]]Fields} from '@/root-cms.js';
import styles from './[[name]].module.scss';

export function [[name]](props: [[name]]Fields) {
const t = useTranslations();
return (
<div className={styles.root}>
{props.title && (
<Text as="h2" className={styles.title}>
{node('title', t(props.title))}
</Text>
)}
{props.body && (
<div className={styles.body}>
{node('body', <RichText data={props.body} />)}
</div>
)}
</div>
);
}
2 changes: 1 addition & 1 deletion packages/create-root/src/root-version.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
// This file is autogenerated by update-root-version.mjs.
export const ROOT_VERSION = '2.4.1';
export const ROOT_VERSION = '2.4.3';
Loading