Skip to content

RevoGrid Project – AI Agent Instructions

Scope

These instructions apply to the entire repository.

This repo is a pnpm monorepo combining:

  • RevoGrid core source in revogrid/ (git submodule)
  • RevoGrid Pro plugin source in packages/pro/plugins/
  • RevoGrid Enterprise plugin source in packages/enterprise/plugins/ (Pivot)
  • Portal and documentation source in packages/portal/src/
  • Framework example components in packages/portal/src/components/
  • Framework wrappers in packages/angular/ and packages/react/

Source Of Truth

When answering questions or making suggestions about RevoGrid, plugins, types, rendering, or grid behavior:

  1. Look at revogrid/ first. The core grid implementation is the primary source of truth.
  2. Look at core types next, especially:
    • revogrid/src/types/interfaces.ts
    • revogrid/src/types/dimension.ts
    • revogrid/src/types/selection.ts
    • revogrid/src/types/plugin.types.ts
  3. For Pro behavior and extension patterns, inspect packages/pro/plugins/.
  4. For Enterprise behavior (Pivot), inspect packages/enterprise/plugins/.
  5. For framework-specific usage and demos, inspect packages/portal/src/components/.
  6. Prefer implementation over docs. If there is any ambiguity, verify in source code.

Repo-Specific Guidance

  • Pro plugin implementation lives in packages/pro/plugins/.
  • Enterprise plugin implementation (Pivot) lives in packages/enterprise/plugins/.
  • packages/pro/plugins/index.ts is the central export hub for Pro plugins and related utilities.
  • packages/enterprise/plugins/index.ts exports Enterprise plugins (PivotPlugin, PivotConfig).
  • Enterprise imports shared modules from Pro via sub-path exports (@revolist/revogrid-pro/core, @revolist/revogrid-pro/events, @revolist/revogrid-pro/aggregations).
  • packages/portal/src/components/ contains examples and wrappers used by the docs portal. Treat these as usage references, not the canonical implementation.
  • Documentation content under packages/portal/src/content/docs/ is useful for wording and examples, but should not override behavior observed in revogrid/, packages/pro/plugins/, or packages/enterprise/plugins/.

MCP Usage

  • If the RevoGrid MCP service is available, use it early to retrieve the best matching docs, examples, migration notes, Pro/Core feature resolution, and typed plugin context.
  • Prefer MCP especially for:
    • finding the closest framework example
    • checking whether a capability is Core or Pro
    • locating the right plugin or editor API before writing code
    • retrieving migration guidance for advanced features
  • If Pro access is configured, the hosted endpoint is https://mcp.rv-grid.com/pro.
  • MCP is a retrieval aid, not the final authority. Validate any implementation detail that affects behavior against local source code in revogrid/, core types, and packages/pro/plugins/ and packages/enterprise/plugins/.
  • If MCP results and local implementation disagree, trust the local implementation in this repository and note the discrepancy.

Monorepo Structure

This project uses pnpm workspaces. Key conventions:

  • Workspace config: pnpm-workspace.yaml at root
  • All packages live under packages/
  • Cross-package dependencies use workspace:* protocol
  • Build order is topological: pro → enterprise → portal
  • Root package.json contains workspace-level scripts (pnpm build, pnpm dev, etc.)
  • Never use npm — always use pnpm

Change Strategy

When making changes:

  1. Determine whether the behavior belongs to core grid logic, a Pro plugin, or only a docs/example layer.
  2. Fix the underlying implementation in the correct source folder rather than patching only examples or docs.
  3. Keep public types aligned with the implementation when behavior or contracts change.
  4. Check existing plugin patterns in packages/pro/plugins/ before introducing a new plugin API or structure.
  5. For Pivot/Enterprise changes, work in packages/enterprise/plugins/.
  6. Never edit revogrid/ folder repo.

Testing Expectations

Use the existing RevoGrid end-to-end suite when changes affect:

  • rendering
  • keyboard interaction
  • mouse interaction
  • editing
  • filtering
  • sorting
  • grouping
  • pinning
  • virtualization
  • export
  • lifecycle behavior in the browser

Relevant test locations and commands:

  • E2E tests: revogrid/e2e/
  • Unit tests: revogrid/test/
  • Core unit test command: npm run test from revogrid/
  • Core E2E command: npm run test:e2e from revogrid/
  • Pro lint: pnpm lint:pro from root
  • Full lint: pnpm lint from root

If a behavior change touches browser interaction or visual grid state, prefer adding or updating an E2E test in revogrid/e2e/.

Practical Review Order

For most tasks, inspect files in this order:

  1. RevoGrid MCP results, if available and relevant
  2. revogrid/src/...
  3. revogrid/src/types/...
  4. packages/pro/plugins/...
  5. packages/enterprise/plugins/...
  6. packages/portal/src/components/...
  7. packages/portal/src/content/docs/...

Adding a New Demo Example

When asked to add a demo, follow this checklist exactly. The pivot-field-panel demo is the canonical reference — read those files if you need a concrete example.

Files to create

All demo source files go in packages/portal/src/components/<feature>/. Create one file per framework:

FileFrameworkRunner
MyDemo.tsVanilla JS/TSts-sandbox
MyDemo.tsxReactsingle-spa
MyDemo.vueVue 3single-spa
MyDemoAngular.tsAngularsingle-spa

Vanilla TS — export a named load(parentSelector, rows?) function. Create and configure the revo-grid element, append it to parentSelector, set grid.source last (after appending), and return a cleanup arrow that calls grid.remove().

React — default-export a functional component. Accept { rows?: any[] }. Wrap plugins, columnTypes, and additionalData in useMemo. Never compute these inline.

Vue 3 — use <script setup>. Keep rows as a ref, make additionalData a computed. Pass plugins as a plain array constant.

Angular — standalone @Component with ViewEncapsulation.None. Import RevoGrid from @revolist/angular-datagrid. Bind all grid properties with [] syntax. Always set encapsulation: ViewEncapsulation.None.

Files to update — do all three, never skip one

1. packages/demos/src/catalog/demo-catalog.ts

Add an object to the exported array:

ts
{
  id: 'my-demo',           // kebab-case, globally unique
  title: '...',
  description: '...',
  group: 'Enterprise',     // or 'Pro' / 'Core'
  tags: ['...'],
  image: '/images/demos/pivot.png',
  defaultFramework: 'ts',
  variants: [
    createVariant('ts', 'JavaScript', 'ts', 'ts-sandbox', false, [
      ['packages/portal/src/components/<feature>/MyDemo.ts', 'src/index.ts', 'ts', false],
    ]),
    createVariant('react', 'React', 'react', 'single-spa', true, [
      ['packages/portal/src/components/<feature>/MyDemo.tsx', 'src/App.tsx', 'tsx', true],
    ]),
    createVariant('vue', 'Vue 3', 'vue', 'single-spa', true, [
      ['packages/portal/src/components/<feature>/MyDemo.vue', 'src/App.vue', 'vue', true],
    ]),
    createVariant('angular', 'Angular', 'angular', 'single-spa', true, [
      ['packages/portal/src/components/<feature>/MyDemoAngular.ts', 'src/app/demo.component.ts', 'ts', true],
    ]),
  ],
  links: [{ title: '...', url: `${PRO_DOCS}/guides/<feature>/`, description: '...' }],
},

If a framework variant genuinely does not exist yet, use null for Vue/React map entries and omit from the Angular map — but prefer creating all four.

2. packages/demos/src/preview/react/lifecycles.tsx

tsx
// near other imports of the same feature group
import MyDemo from '@components/<feature>/MyDemo.tsx';

// in reactDemoMap
'my-demo': ({ runtimeContext }) => <MyDemo rows={runtimeContext?.pivotRows ?? []} />,

3. packages/demos/src/preview/vue/lifecycles.ts

ts
import MyDemo from '@components/<feature>/MyDemo.vue';

// in vueDemoMap
'my-demo': MyDemo,

4. packages/demos/src/preview/angular/lifecycles.ts

ts
// in the angular string map
'my-demo': 'my-demo',

5. packages/angular/src/preview-app/preview-app.component.ts — Angular has its own internal registry, all three places must be updated:

ts
// 1. Add import
import { MyDemoGridComponent } from '@components/<feature>/MyDemoAngular';

// 2. Add to PreviewDemo union type
| 'my-demo'

// 3. Add to @Component imports array
MyDemoGridComponent,

// 4. Add to template ngSwitch
<my-demo-grid *ngSwitchCase="'my-demo'"></my-demo-grid>

The selector in the template (my-demo-grid) must match the selector field in the @Component decorator of MyDemoAngular.ts.

Checklist

  • [ ] MyDemo.ts — exports load(), sets source last, returns cleanup
  • [ ] MyDemo.tsx — default export, useMemo for plugins + additionalData
  • [ ] MyDemo.vue<script setup>, computed additionalData
  • [ ] MyDemoAngular.ts — standalone, ViewEncapsulation.None
  • [ ] Entry added to demo-catalog.ts with all 4 variants
  • [ ] Import + map entry in react/lifecycles.tsx
  • [ ] Import + map entry in vue/lifecycles.ts
  • [ ] Entry in angular/lifecycles.ts
  • [ ] Import + union type + imports array + template case in packages/angular/src/preview-app/preview-app.component.ts

Agent Output Quality Bar

  • Do not infer grid behavior from docs when the implementation is available.
  • Do not treat demo code as the definitive contract.
  • When uncertain, cite the exact implementation file that establishes the behavior.
  • Keep fixes minimal and aligned with the existing RevoGrid architecture and plugin patterns.