Files
wursor/HANDOFF.md
T
2026-04-26 09:09:55 +01:00

17 KiB
Raw Blame History

Originmain — Implementation Handoff

Living document. Updated after each layer is completed or substantially advanced. Reference: Originmain-Implementation-Guide-v1_0.md (v1.0, April 2026)


Layer Status Summary

Layer Name Status Notes
0 Infrastructure & DevOps Deferred Skipped for now per plan
1 Canvas UI Shell Complete ArtboardTree, CodebaseFileTree, CodeDiffPanel
2 Live Rendering Engine Complete postMessage protocol, fiber hook, MF config, LiveArtboard iframe
3 Visual Editing & Diff Engine Complete Diff engine (49 tests), SelectionOverlay, history store
4 Origin Graph & Data Store Complete 3 migrations, RLS, Zod types, query helpers
5 Design Language Runtime Complete New package, JSON Schema, Zod validator, token pipeline
6 AI Completion Layer Complete Gateway, 5 features, prompt caching, Claude Opus 4.7
7 Agent Bridge (MCP) Complete 5 tools, HMAC auth, rate limiter, Cursor + Claude Code adapters
8 Multi-Origin Ingestion Complete OriginIngester interface + 4 connectors
9 Multiplayer & Presence Foundation Room schema, adapter interface, cursor palette — no app integration yet
10 Platform & Extensions Foundation Plugin API, enterprise types (SSO/SCIM/audit), white-label theming

Layer 1 — Canvas UI Shell

Completed: 2026-04-25

What was built

Diff Engine integration (pre-Layer 1)

  • packages/diff-engine/src/schemas.ts — Zod schemas for ComponentSnapshot and ComponentDiff
  • packages/diff-engine/src/engine.ts — Core diff computation, Myers LCS, recursive child diffing
  • packages/diff-engine/src/myers.ts — Myers longest-common-subsequence algorithm
  • packages/diff-engine/src/patch.ts — Unified patch generation
  • packages/diff-engine/src/serialize.ts — Snapshot serialization to text
  • 49 tests, ~88% coverage, all passing

Canvas UI Shell components (NEW — additive only)

  • packages/app/src/components/navigator/ArtboardTree.tsx — Fluent 2 Tree/TreeItem/TreeItemLayout for workspace artboard hierarchy
  • packages/app/src/components/codebase/CodebaseFileTree.tsx@pierre/trees standalone codebase file browser (separate from ArtboardNavigator.tsx)
  • packages/app/src/components/diff/CodeDiffPanel.tsx@pierre/diffs PatchDiff renderer with unified diff patch string input

Critical invariants

  • ArtboardNavigator.tsx must never be reversed or have its @pierre/trees FileTree removed
  • ArtboardTree.tsx and CodebaseFileTree.tsx are separate components
  • All new components are additive

Layer 2 — Live Rendering Engine

Completed: 2026-04-25

Files created

  • packages/renderer/src/protocol.tsHostMessage/RendererMessage unions, isHostEnvelope(), isRendererEnvelope(), createHostEnvelope(), createRendererEnvelope(); source discriminants 'originmain-host' / 'originmain-renderer'
  • packages/renderer/src/fiber-hook.tsbuildFiberHookScript(artboardId) generates injectable script that patches __REACT_DEVTOOLS_GLOBAL_HOOK__.onCommitFiberRoot, walks Fiber tree, posts FIBER_TREE_UPDATE envelopes to window.parent
  • packages/renderer/src/module-federation.tscreateRendererHostConfig() and createRemoteConfig() MF host config helpers with shared React singleton
  • packages/renderer/src/index.ts — exports all of the above
  • packages/app/src/components/canvas/LiveArtboard.tsx — React iframe component; sandbox="allow-scripts allow-same-origin allow-forms"; injects fiber hook on READY; sends SET_DESIGN_TOKENS on token change

Layer 3 — Visual Editing & Diff Engine

Completed: 2026-04-25

Files created

  • packages/app/src/store/history.ts — Zustand store: stacks: Record<string, {past, future}>, pushEdit(), undo(), redo(), canUndo(), canRedo(), clearHistory(). Max 100 entries per artboard.
  • packages/app/src/components/canvas/SelectionOverlay.tsx — Transparent cursor: crosshair layer; hitTestFiber() depth-first Fiber tree search by mouse position + domRect; SelectionHandles corner drag-to-resize; commits PropChange[] via pushEdit()

Layer 4 — Origin Graph & Data Store

Completed: 2026-04-25

Files created

  • packages/origin-graph/migrations/001_initial_schema.sql — 5 enum types, 7 tables (workspaces, artboards, origins, intent_diffs, agent_sessions, design_language_files, team_members), FK indexes, set_updated_at() trigger
  • packages/origin-graph/migrations/002_artboard_ancestry.sql — Recursive CTE materialized view artboard_ancestry(artboard_id, ancestor_id, depth), unique index for CONCURRENTLY refresh, trigger on artboard insert/update
  • packages/origin-graph/migrations/003_rls_policies.sqlis_workspace_member(ws_id UUID) SECURITY DEFINER function, SELECT/INSERT/UPDATE/DELETE policies on all 7 tables
  • packages/origin-graph/src/types.ts — Zod schemas for all 7 tables + insert types
  • packages/origin-graph/src/queries.tsDbClient generic interface + 13 query helpers (no hard Supabase dependency)

Layer 5 — Design Language Runtime

Completed: 2026-04-25

New package: packages/design-language

  • src/schema.tsDesignLanguageFileBodySchema with tokens, components, screens, voice, accessibility subsections
  • src/validator.tsvalidateDesignLanguageFile() returns ValidationSuccess | ValidationFailure; checkComponentConstraints() for real-time per-edit validation
  • src/tokens.tsextractColorTokens(), tokensToCssVars(), dlfToCssVars(), dlfSummary()
  • tsconfig.base.json — path alias added: "@originmain/design-language": ["./packages/design-language/src/index.ts"]

Layer 6 — AI Completion Layer

Completed: 2026-04-25

New package: packages/ai-layer

  • src/client.tsgetClient(): Anthropic, MODEL = 'claude-opus-4-7'
  • src/gateway.tsAIGateway class: 60 RPM rate limiter, 3 retries on 429/529/5xx, cost tracking (computeCost()). Note: thinking: {type: 'adaptive'} pending SDK ≥0.58 upgrade
  • src/prompts/system.tsbuildSystemPrompt({role, dlfJson?}) returns TextBlockParam[]; DLF block has cache_control: {type: 'ephemeral'} as stable system prompt prefix
  • src/completion-zone.tsfillCompletionZone(): 3-retry JSON validation loop, temp 0.3
  • src/diff-summary.tsgenerateDiffSummary(): temp 0.3, 128 tokens max
  • src/artboard-query.tsqueryCrossArtboard(): temp 0.3
  • src/drift-report.tsgenerateDriftReport(): base64 image, temp 0.3
  • src/agent-qa.tsanswerAgentQuestion(): temp 0.7

SDK note

@anthropic-ai/sdk v0.56.0 is installed. Adaptive thinking (thinking: {type: 'adaptive'}) requires ≥0.58 — a TODO comment marks all 5 feature files for upgrade. All features remain fully functional at temperature level.


Layer 7 — Agent Bridge (MCP)

Completed: 2026-04-26

New package: packages/agent-bridge

  • src/protocol.ts — JSON-RPC 2.0 types: JsonRpcRequest, JsonRpcSuccess<T>, JsonRpcError, MCP_ERROR constants (UNAUTHORIZED: -32001, RATE_LIMITED: -32002), AuthRequest/AuthAck handshake, textResult()/jsonResult<T>() helpers
  • src/auth.tsissueWorkspaceToken(workspaceId, agentType) HMAC-SHA256 base64url token; verifyWorkspaceToken(token) with timing-safe comparison, 30-day TTL; uses Node crypto built-in
  • src/rate-limiter.ts — Sliding window: 100 requests/60-min/workspace; in-process Map of timestamp arrays (replace with Redis for multi-instance)
  • src/tools.tsToolContext interface (db + ai adapters), McpTool interface, 5 tools: get_pending_diffs (rate-guarded), get_artboard_context, ask_design_agent, update_diff_status, get_design_language; TOOLS array, TOOL_MAP, getToolList()
  • src/adapters/cursor.tsgenerateCursorConfig(): generates .cursorrules markdown + cursor_settings.json MCP server entry with Bearer auth
  • src/adapters/claude-code.tsgenerateClaudeCodeConfig(): generates CLAUDE.md section + .claude/settings.json MCP server declaration with SSE transport

Notes

  • Added @types/node devDep + "types": ["node"] in tsconfig for crypto/Buffer/process
  • AgentType: 'CURSOR' | 'CLAUDE_CODE' | 'GENERIC'

Layer 8 — Multi-Origin Ingestion

Completed: 2026-04-26

Package: packages/integrations

  • src/types.tsOriginIngester<TPayload> interface: parsePayload(raw): TPayload + ingest(payload): IngestionResult; IngestionResult carries origin: InsertOrigin, artboardTitle, optional renderUrl
  • src/connectors/linear.tslinearIngester: Zod-validates Linear Issue webhook payload; maps to LINEAR_ISSUE origin; prefers attachment URL for renderUrl
  • src/connectors/slack.tsslackIngester: Zod-validates Slack message_posted event; extracts first image attachment; maps to SLACK_MESSAGE origin
  • src/connectors/github.tsgithubIngester: Zod-validates GitHub pull_request webhook (opened/synchronize/reopened/closed); maps to GIT_COMMIT origin with PR metadata
  • src/connectors/intercom.tsintercomIngester: Zod-validates Intercom conversation.user.created webhook; extracts annotated screenshot attachment; maps to URL origin with user context

Design note

Each connector validates untrusted webhook JSON at the boundary with Zod (parsePayload throws ZodError on invalid input). The origin output maps directly to InsertOrigin from @originmain/origin-graph — no workspace_id on origins (that scoping lives on the artboards table via origin_id).


Package Inventory

Package Status Notes
packages/app Active Next.js 15 app; Layers 13 complete
packages/diff-engine Complete 49 tests, ~88% coverage
packages/ui Active Theme + FluentProvider
packages/renderer Complete Layer 2: postMessage protocol, fiber hook, MF config
packages/origin-graph Complete Layer 4: migrations, RLS, Zod types, query helpers
packages/design-language Complete Layer 5: DLF schema, validator, token pipeline
packages/ai-layer Complete Layer 6: gateway, 5 features, prompt library
packages/agent-bridge Complete Layer 7: MCP tools, auth, rate limiter, adapters
packages/integrations Complete Layer 8: OriginIngester + 4 connectors
packages/multiplayer Foundation Layer 9: room schema, MultiplayerAdapter, cursor palette
packages/platform Foundation Layer 10: Plugin API, SSO/SCIM/audit types, theming
packages/e2e Not started Playwright E2E; Phase 1 completion target

Key Technical Decisions

Decision Choice Rationale
Artboard tree Fluent 2 Tree/TreeItem ARIA, Fluent token integration, <100s of nodes
Codebase file tree @pierre/trees Virtualization for 5k+ files, git status, search
Diff renderer @pierre/diffs PatchDiff Shiki syntax highlight, split/unified modes
Canvas state Zustand Lightweight, supports undo/redo middleware
TS imports in Next.js extensionAlias .js → .ts ESM-compatible workspace packages
AI model Claude Opus 4.7 Max intelligence for design engineering tasks
Prompt caching DLF as stable system prompt prefix ~60% input token cost saving per session
MCP auth HMAC-SHA256 workspace token Stateless, 30-day TTL, timing-safe verify
Rate limit In-process sliding window Simple; swap for Redis in multi-instance deploy
Webhook validation Zod at connector boundary ZodError → HTTP 400 before any DB write
exactOptionalPropertyTypes Conditional spread ...(v !== undefined ? {k: v} : {}) Required by strict TS config throughout monorepo

Layer 9 — Multiplayer & Presence (Foundation)

Completed: 2026-04-26 (Phase 3 foundation only — no Liveblocks app integration per guide)

New package: packages/multiplayer

  • src/room-schema.ts — Liveblocks room schema types:
    • UserPresence — cursor {x,y}, activeArtboardId, selectedComponentIds, cursorColor; updated ≤50ms throttle
    • ArtboardStorageObject — CRDT-backed artboard state (viewport, locked, lastModifiedAt)
    • WorkspaceStorageartboards: Record<id, ArtboardStorageObject> + artboardOrder
    • LiveblocksRoomTypes — generic type params for createRoomContext<Presence, Storage, UserMeta, RoomEvent>
    • RoomEvent — broadcast events: ARTBOARD_LOCKED, DIFF_EXPORTED, COMPLETION_ZONE_ACCEPTED
    • workspaceRoomId(workspaceId) — room ID convention: "workspace:<uuid>"
  • src/adapter.tsMultiplayerAdapter interface matching Zustand store API surface (presence reads/writes, artboard storage, subscribe); createLocalAdapter() stub for Phase 1/2
  • src/cursor-colors.tscursorColorForUser(userId) deterministic 12-colour palette assignment

Phase 3 integration note

Actual createClient / createRoomContext calls go in packages/app/src/lib/liveblocks.ts (Phase 3). @liveblocks/client and @liveblocks/react are declared as optional peer deps — not installed yet.


Layer 10 — Platform & Extensions (Foundation)

Completed: 2026-04-26 (Phase 4 foundation — types and contracts only)

New package: packages/platform

  • src/plugin-api.ts — Plugin API:
    • PluginManifest — reverse-DNS id, version, entryUrl, bundleHash, permissions[]
    • PluginPermission — 7 scopes: artboards:read, artboards:write, diffs:read, diffs:export, completion-zones:register, ingesters:register, design-language:read
    • PluginReadAPI / PluginWriteAPI — async APIs exposed to sandboxed plugin via postMessage
    • PluginContextread, write (null unless artboards:write granted), notify()
    • CustomCompletionZoneDefinition — custom zone type with systemPromptAddendum + outputSchema
    • CustomIngesterDefinition — custom connector handleWebhook() interface
    • PluginRegistrylist / install / uninstall / setEnabled per workspace
  • src/enterprise.ts — Enterprise features:
    • SsoConfig — SAML 2.0: idpEntityId, idpSsoUrl, idpCertificate, enforced, emailDomains; providers: okta/azure/google-workspace/onelogin/custom
    • ScimUser / ScimGroup — SCIM 2.0 normalized objects with role mapped to TeamRole
    • AuditLogEntry — 30 audit actions across auth/workspace/artboard/diff/AI/plugin/DLF/agent-bridge
    • buildAuditEntry() — convenience constructor with auto-timestamp
  • src/theming.ts — White-label theming:
    • BrandTokensprimaryColor, secondaryColor, logoUrl, productName, faviconUrl
    • brandVariantsFromHex(hex) — derives 16-shade Fluent 2 BrandVariants from single hex colour via HSL interpolation (shade10=lightest → shade160=darkest)

Known Pending Items

  1. @anthropic-ai/sdk upgrade to ≥0.58 — unlocks thinking: {type: 'adaptive'} in all 5 AI feature files (marked with TODO comments)
  2. Redis-backed rate limiterpackages/agent-bridge/src/rate-limiter.ts is in-process only; needs Redis for multi-instance MCP server deployment
  3. Layer 0 — Infrastructure (Vercel, Supabase, Render, GitHub Actions) deferred per plan
  4. Layer 9 Phase 3 — Wire MultiplayerAdapter into app components; add createClient/createRoomContext in packages/app/src/lib/liveblocks.ts; install @liveblocks/client + @liveblocks/react
  5. Layer 10 Phase 4 — Plugin sandbox runtime (iframe + postMessage bridge); SCIM webhook endpoint; SSO provider registration UI; audit log Supabase table + extension
  6. packages/e2e — Playwright E2E tests not yet created

Last updated: 2026-04-26 after Layers 910 foundation completion