-
Notifications
You must be signed in to change notification settings - Fork 0
tech overview
Canon document. Updated by the Synthesis agent at the close of each initiative.
Patchwork is a TypeScript monorepo that provides an in-browser JSX/TypeScript compiler, a virtual file system with sync, widget mounting with service bridging, a visual DOM inspector, a markdown editor with code extraction, and a service aggregation server — all composable as libraries and integrated via a VS Code extension and standalone chat app.
| Category | Selection | Notes |
|---|---|---|
| Language/Runtime | TypeScript 5.x, Node.js | All packages and apps are TypeScript |
| Monorepo | pnpm workspaces + Turborepo |
pnpm-workspace.yaml defines apps/** and packages/**
|
| Build (Libraries) | tsup (esbuild-based) | All packages use tsup.config.ts for bundling |
| Build (Apps) | Vite | Chat app uses Vite + React |
| Compiler Engine | esbuild-wasm | In-browser compilation of JSX/TSX → ESM |
| Frontend | React 18 + TipTap + Radix UI | UI components follow ShadCN/ui patterns |
| Styling | Tailwind CSS + CSS Variables | ShadCN theme system with HSL custom properties |
| AI Integration | Vercel AI SDK (@ai-sdk/react, ai) |
Chat app uses useChat hook for LLM interaction |
| Service Protocol | MCP + UTCP | Stitchery aggregates tools from MCP servers and UTCP clients |
| VS Code | VS Code Extension API | TreeDataProvider, FileSystemProvider, WebviewViewProvider |
| Testing | Not configured | No test framework currently set up |
| Deployment | Local development | VS Code extension + local Stitchery server |
| Key Libraries | esbuild-wasm, @tiptap/, @radix-ui/, shiki, zod | Compilation, editing, UI, syntax highlighting, validation |
patchwork/
├── apps/
│ └── chat/ # Standalone chat SPA (Vite + React)
│ └── src/
│ ├── pages/ChatPage.tsx # Main chat interface
│ └── components/ui/ # ShadCN UI components
├── packages/
│ ├── compiler/ # Core: JSX → ESM compiler + VFS + mounting
│ │ └── src/
│ │ ├── compiler.ts # Compilation orchestrator
│ │ ├── vfs/ # Virtual file system (backends, sync, core)
│ │ ├── mount/ # Widget mounting (embedded, iframe, bridge)
│ │ ├── images/ # Image/dependency loading from CDN
│ │ ├── transforms/ # esbuild plugins (CDN rewriting, VFS resolution)
│ │ ├── schemas.ts # Zod schemas (ImageConfig, Manifest, MountOptions)
│ │ └── types.ts # Core type definitions
│ ├── editor/ # Markdown editor + code extraction + edit sessions
│ │ └── src/
│ │ ├── components/ # MarkdownEditor, CodePreview, EditModal, etc.
│ │ └── lib/ # code-extractor, diff, VFS utilities
│ ├── bobbin/ # Visual DOM inspector + style editor
│ │ └── src/
│ │ ├── Bobbin.tsx # Main component
│ │ ├── core/ # Hooks: useBobbin, useElementSelection, useChangeTracker
│ │ ├── components/ # EditPanel, Inspector, Overlay, Pill, ThemeToggle
│ │ └── tokens/ # Design tokens (colors, spacing, typography, etc.)
│ ├── patchwork/ # Service proxy layer
│ │ └── src/
│ │ ├── services/ # ServiceBackend interface, createProxy, callProcedure
│ │ └── types.ts # Service types
│ ├── stitchery/ # Backend server aggregating MCP/UTCP tools
│ │ └── src/
│ │ ├── server/ # Express-like server, routes, service registry
│ │ ├── cli.ts # CLI entry point
│ │ └── prompts.ts # System prompts for AI endpoints
│ ├── utcp/ # UTCP protocol bridge → ServiceBackend
│ │ └── src/index.ts
│ ├── images/
│ │ └── shadcn/ # ShadCN/ui runtime image (Tailwind CDN, theme setup)
│ │ └── src/
│ │ ├── index.ts # Exports: setup, cleanup, cn, cva, clsx, twMerge
│ │ └── setup.ts # Tailwind CDN injection, CSS variables, MutationObserver
│ └── vscode/ # VS Code extension
│ └── src/
│ ├── extension.ts # Activation, command registration
│ └── providers/ # TreeProvider, FileSystemProvider, PreviewPanelProvider
├── .cicadas/ # Cicadas lifecycle artifacts
├── turbo.json # Turborepo pipeline configuration
├── pnpm-workspace.yaml # Workspace definition
└── tsconfig.json # Root TypeScript configuration
Patchwork follows a layered library architecture where each package is independently publishable and composable. The core compilation pipeline flows from source code through esbuild transforms to mounted widgets, with a parallel service proxy layer connecting widgets to external tool backends.
The system has two integration surfaces: (1) the VS Code extension which embeds all packages into an IDE workflow with project management, preview panels, and AI-driven editing; and (2) the chat app which provides a standalone conversational interface for AI-powered widget generation.
| Component | Responsibility | Key Files |
|---|---|---|
| Compiler | JSX/TSX → ESM compilation via esbuild-wasm, image loading, transform pipeline | packages/compiler/src/compiler.ts |
| VFS | Virtual file system with Memory/IndexedDB/HTTP backends and bidirectional sync | packages/compiler/src/vfs/ |
| Mount | Widget embedding (direct DOM or iframe) with cross-context service bridge | packages/compiler/src/mount/ |
| Bobbin | Visual DOM inspector with element selection, spacing overlays, and style editing | packages/bobbin/src/ |
| Editor | Markdown editing, code block extraction, diff preview, and edit sessions | packages/editor/src/ |
| Patchwork Services | Service proxy: callProcedure(namespace, procedure, args) routing |
packages/patchwork/src/services/ |
| Stitchery | Backend server aggregating MCP/UTCP tools into a unified service registry | packages/stitchery/src/server/ |
| UTCP Bridge | Adapter from Patchwork ServiceBackend interface to UTCP protocol | packages/utcp/src/index.ts |
| ShadCN Image | Runtime widget dependency: Tailwind CDN, CSS variable theming, utility classes | packages/images/shadcn/src/ |
| VS Code Extension | IDE integration: file system, tree view, preview panel, embedded Stitchery | packages/vscode/src/ |
Widget Compilation & Mounting:
Source (JSX/TSX) → [VFS] → [Image Loader] → [esbuild + Transforms] → ESM Bundle
→ [Mount (embedded | iframe)] → Live Widget in DOM
↕ [Bridge (postMessage RPC)]
→ [Patchwork Proxy] → [Stitchery Server] → [MCP/UTCP Tool Backends]
Edit Flow (Editor package):
Markdown Content → [code-extractor] → Code Blocks + File Tree
→ User Edits → [useEditSession] → Compilation Request
→ [Compiler] → Diff Generation → [SaveConfirmDialog] → Updated Markdown
VS Code Integration:
Project Folder → [PatchworkFileSystemProvider] → [PatchworkTreeProvider] → Tree View
→ Select File → [PreviewPanelProvider] → Webview with Compiler + Bobbin
→ AI Edit Request → [Copilot Proxy] → [EmbeddedStitchery] → [EditService] → File Update
- esbuild-wasm for in-browser compilation: Chosen for speed and ability to run entirely client-side without a build server. Constrains supported syntax to what esbuild handles.
- VFS abstraction over real filesystem: Enables the same compilation pipeline to work in browser (IndexedDB/Memory), VS Code (FileSystemProvider), and remote (HTTP backend) contexts.
-
ServiceBackend as the universal proxy interface: All external service calls flow through
callProcedure(namespace, procedure, args), enabling uniform routing regardless of whether the backend is MCP, UTCP, or direct. - iframe isolation for widget mounting: Widgets can be sandboxed in iframes with configurable permissions, using postMessage RPC for service calls back to the parent context.
- ShadCN/ui as default component system: Standardized on Radix primitives + Tailwind rather than building a custom design system. Widgets use the same component patterns as the platform itself.
{
platform: "browser" | "cli",
esbuild: { target, format, jsx, ... },
framework: {
globals: Record<string, string>, // e.g., { "React": "window.React" }
preload: string[], // CDN URLs to preload
deps: Record<string, string>, // Version overrides for CDN imports
},
aliases: Record<string, string>,
dependencies: Record<string, string>,
}{
name: string,
version: string,
image: string, // Image specifier (e.g., "@aprovan/patchwork-image-shadcn")
platform: "browser" | "cli",
inputs: Array<{
name: string,
type: string,
default?: any,
required?: boolean,
}>,
services: string[], // Required service namespaces
}{
path: string,
type: "create" | "update" | "delete",
mtime: number,
}{
type: "SERVICE_CALL" | "SERVICE_RESULT",
id: string,
namespace?: string,
procedure?: string,
args?: any,
result?: any,
error?: string,
}POST /api/chat # LLM chat completion with tool use
POST /api/edit # AI-driven code editing
GET /api/proxy/* # Service proxy: /api/proxy/{namespace}/{procedure}
POST /api/proxy/* # Service proxy with body args
compile(options: CompileOptions): Promise<CompiledWidget>
mount(widget: CompiledWidget, options: MountOptions): Promise<MountedWidget>readFile(path: string): Promise<string>
writeFile(path: string, content: string): Promise<void>
mkdir(path: string): Promise<void>
readdir(path: string): Promise<string[]>
stat(path: string): Promise<FileStat>
sync(): Promise<SyncResult>callProcedure(namespace: string, procedure: string, args: any): Promise<any>
createProxy(namespace: string): ProxyObject
setServiceBackend(backend: ServiceBackend): void| Service / API | Purpose | Auth method |
|---|---|---|
| esm.sh CDN | ESM module hosting for CDN imports | None |
| Tailwind Play CDN | Runtime Tailwind CSS compilation | None |
| MCP Servers | External tool providers (configurable) | Per-server config |
| UTCP Servers | External tool providers (configurable) | Per-server config |
| Copilot Proxy | AI edit requests in VS Code | Local proxy URL |
| Construct | Convention | Example |
|---|---|---|
| Files (components) | PascalCase .tsx
|
EditModal.tsx, CodePreview.tsx
|
| Files (utilities) | camelCase .ts
|
changeSerializer.ts, utils.ts
|
| Files (config) | kebab-case |
tsup.config.ts, vite.config.ts
|
| React components | PascalCase |
SelectionOverlay, MarkdownEditor
|
| Hooks | camelCase with use prefix |
useBobbin(), useEditSession()
|
| Types/Interfaces | PascalCase |
CompiledWidget, ServiceBackend
|
| Functions | camelCase |
callProcedure(), createProxy()
|
- Error handling: Error boundaries in React components for widget preview; try/catch at compilation boundaries; errors surfaced to user inline
-
Package boundaries: Each package exports through a single
index.tsbarrel; no cross-package internal imports -
Build system: All packages use
tsupwith identical config pattern; apps usevite -
Service abstraction: All external calls go through the
ServiceBackendinterface — never call external APIs directly from widgets -
VFS abstraction: File operations always go through VFS — never use
fsdirectly in browser-targeted code
-
modules/compiler.md— Core compilation pipeline, VFS, mounting, transforms -
modules/bobbin.md— Visual DOM inspector and style editor -
modules/editor.md— Markdown editor, code extraction, edit sessions -
modules/patchwork.md— Service proxy layer -
modules/stitchery.md— Backend server and service registry -
modules/vscode.md— VS Code extension integration -
modules/chat.md— Standalone chat application
- Test infrastructure — No test framework is configured; testing strategy needs to be established
-
CI/CD pipeline — Only a
publish.ymlGitHub Action exists; no CI for tests or linting -
Package versioning — Packages are published under
@aprovan/scope; versioning strategy unclear - HTTP VFS authentication — No auth on the HTTP backend; required before production remote sync