feat: initialize AIUI monorepo with project rules and core types

Foundation for the next-generation AI content surface UI:
- 16 Cursor rules files covering philosophy, Vue conventions, design system,
  content surfaces, plugin system, AI integration, renderers, security,
  Bitcoin-only policy, dev/prod modes, accessibility, performance, animation,
  mobile UX, and git workflow
- pnpm workspaces + Turborepo monorepo (@aiui/core, @aiui/app)
- Vue 3 + Vite + TypeScript + Tailwind CSS 4
- Core type system: plugins, renderers, messages, content blocks
- Plugin registry with renderer registration
- 50 mock film fixtures with search/filter utilities
- App shell with chat page layout
- Environment config templates

Made-with: Cursor
This commit is contained in:
Dorian
2026-03-02 14:15:39 +00:00
commit c28e6dd811
44 changed files with 5384 additions and 0 deletions
+51
View File
@@ -0,0 +1,51 @@
import { ref, readonly } from 'vue'
import type { AIUIPlugin, PluginType } from '../types/plugin'
import type { RendererDefinition } from '../types/renderer'
const plugins = ref<Map<string, AIUIPlugin>>(new Map())
const renderers = ref<Map<string, RendererDefinition>>(new Map())
export function registerPlugin(plugin: AIUIPlugin): void {
if (plugins.value.has(plugin.id)) {
console.warn(`Plugin "${plugin.id}" is already registered. Skipping.`)
return
}
plugins.value.set(plugin.id, plugin)
}
export function unregisterPlugin(pluginId: string): void {
plugins.value.delete(pluginId)
}
export function getPlugin<T extends AIUIPlugin>(pluginId: string): T | undefined {
return plugins.value.get(pluginId) as T | undefined
}
export function getPluginsByType<T extends AIUIPlugin>(type: PluginType): T[] {
return Array.from(plugins.value.values()).filter(
(p) => p.type === type
) as T[]
}
export function registerRenderer(renderer: RendererDefinition): void {
if (renderers.value.has(renderer.id)) {
console.warn(`Renderer "${renderer.id}" is already registered. Skipping.`)
return
}
renderers.value.set(renderer.id, renderer)
}
export function getRendererForContentType(
contentType: string
): RendererDefinition | undefined {
return Array.from(renderers.value.values()).find(
(r) => r.contentType === contentType
)
}
export function getAllRenderers(): RendererDefinition[] {
return Array.from(renderers.value.values())
}
export const pluginRegistry = readonly(plugins)
export const rendererRegistry = readonly(renderers)