diff --git a/.claude/settings.local.json b/.claude/settings.local.json deleted file mode 100644 index 2c42fb2..0000000 --- a/.claude/settings.local.json +++ /dev/null @@ -1,169 +0,0 @@ -{ - "permissions": { - "allow": [ - "Bash(pnpm --version)", - "Bash(pnpm install *)", - "Bash(pnpm run *)", - "Bash(pnpm approve-builds *)", - "WebFetch(domain:github.com)", - "WebFetch(domain:www.figma.com)", - "mcp__Claude_in_Chrome__tabs_context_mcp", - "Bash(curl -s \"https://github.com/features/codespaces\")", - "Bash(curl -s \"https://www.figma.com/draw/\")", - "Bash(curl -s \"https://www.figma.com/make/\")", - "Bash(curl -s \"https://github.githubassets.com/assets/primer-primitives-0f570a01cbe448fb.css\")", - "Bash(pnpm --filter @originmain/app run build)", - "Bash(pnpm --filter @originmain/app install)", - "Bash(pnpm add *)", - "Bash(xargs ls *)", - "Bash(grep -E \"\\\\.\\(ts|tsx\\)$\")", - "WebSearch", - "WebFetch(domain:trees.software)", - "Bash(pnpm exec *)", - "WebFetch(domain:diffs.com)", - "WebFetch(domain:diff.com)", - "Bash(npm show *)", - "Bash(python3 -c \"import sys,json; d=json.load\\(sys.stdin\\); print\\(json.dumps\\({k:d.get\\(k\\) for k in ['description','main','types','exports','peerDependencies','keywords']}, indent=2\\)\\)\")", - "Bash(pnpm --filter @originmain/diff-engine test)", - "Bash(npx tsc *)", - "Bash(npm test *)", - "Skill(claude-api)", - "Skill(claude-api:*)", - "Bash(python3 -c \"import sys,json; d=json.load\\(sys.stdin\\); print\\(json.dumps\\({**d.get\\('dependencies',{}\\), **d.get\\('devDependencies',{}\\)}, indent=2\\)\\)\")", - "Bash(python3 -c \"import sys,json; d=json.load\\(sys.stdin\\); print\\(json.dumps\\(d.get\\('exports', d.get\\('main', ''\\)\\), indent=2\\)\\)\")", - "Bash(python3 -c \"import sys,json; d=json.load\\(sys.stdin\\); print\\(d['version']\\)\")", - "Bash(node_modules/.bin/tsc --noEmit)", - "Bash(echo \"exit: $?\")", - "Bash(echo \"agent-bridge: $?\")", - "Bash(echo \"integrations: $?\")", - "Bash(echo \"agent-bridge exit: $?\")", - "Bash(echo \"integrations exit: $?\")", - "Bash(echo \"platform exit: $?\")", - "Bash(node -e \"const c = require\\('./node_modules/.pnpm/@clerk+nextjs@7.2.7_next@15.3.1_react-dom@19.2.5_react@19.2.5__react@19.2.5__react@19.2.5_react-dom@19.2.5_react@19.2.5__react@19.2.5/node_modules/@clerk/nextjs/dist/cjs/index.js'\\); console.log\\(Object.keys\\(c\\).filter\\(k => /show|signed/i.test\\(k\\)\\)\\)\")", - "Bash(echo \"port 3000 status: $?\")", - "Bash(curl -s http://localhost:3002)", - "Bash(xargs ps *)", - "Bash(curl -s http://localhost:3000 -L)", - "Bash(pnpm typecheck *)", - "Bash(pnpm build *)", - "Bash(tee /tmp/build-out.txt)", - "Bash(echo \"EXIT:$?\")", - "Bash(npx next *)", - "Bash(echo \"EXIT_CODE:$?\")", - "Bash(node_modules/.bin/next build *)", - "Bash(./node_modules/.bin/next build *)", - "Bash(../../node_modules/.bin/next build *)", - "Bash(/Users/USER/Desktop/originmain/node_modules/.bin/next build *)", - "Bash(echo \"BUILD_EXIT:$?\")", - "Bash(node /Users/USER/Desktop/originmain/node_modules/.pnpm/next@15.5.15_@playwright+test@1.59.1_react-dom@19.2.5_react@19.2.5__react@19.2.5/node_modules/next/dist/bin/next build)", - "Bash(pkill -f \"next build\")", - "Bash(pnpm --filter @originmain/app build)", - "Bash(curl -s \"https://raw.githubusercontent.com/simple-icons/simple-icons/develop/icons/linear.svg\")", - "Bash(curl -s \"https://raw.githubusercontent.com/simple-icons/simple-icons/develop/icons/slack.svg\")", - "Bash(curl -s \"https://raw.githubusercontent.com/simple-icons/simple-icons/develop/icons/cursor.svg\")", - "Bash(curl -s \"https://raw.githubusercontent.com/simple-icons/simple-icons/develop/icons/visualstudiocode.svg\")", - "Bash(curl -s \"https://raw.githubusercontent.com/simple-icons/simple-icons/develop/icons/anthropic.svg\")", - "Bash(curl -s \"https://raw.githubusercontent.com/simple-icons/simple-icons/develop/icons/typescript.svg\")", - "Bash(curl -s \"https://raw.githubusercontent.com/simple-icons/simple-icons/develop/icons/nextdotjs.svg\")", - "Bash(curl -s \"https://raw.githubusercontent.com/simple-icons/simple-icons/develop/icons/react.svg\")", - "Bash(curl -s \"https://raw.githubusercontent.com/simple-icons/simple-icons/develop/icons/slack.svg\" -o /dev/null -w \"%{http_code}\")", - "Bash(curl -s \"https://raw.githubusercontent.com/simple-icons/simple-icons/develop/icons/visualstudiocode.svg\" -o /dev/null -w \"%{http_code}\")", - "Bash(curl -s \"https://raw.githubusercontent.com/simple-icons/simple-icons/develop/_data/simple-icons.json\")", - "Bash(python3 -c ' *)", - "Bash(curl -s \"https://raw.githubusercontent.com/simple-icons/simple-icons/develop/simple-icons.json\")", - "Bash(curl -s \"https://api.github.com/repos/simple-icons/simple-icons/contents/icons\")", - "Bash(curl -sI \"https://cdn.simpleicons.org/slack\")", - "Bash(curl -sI \"https://cdn.simpleicons.org/visualstudiocode\")", - "Bash(curl -s \"https://raw.githubusercontent.com/simple-icons/simple-icons/master/icons/slack.svg\")", - "Bash(curl -s \"https://raw.githubusercontent.com/simple-icons/simple-icons/master/icons/visualstudiocode.svg\")", - "Bash(python3 -c \"import json,sys; d=json.load\\(sys.stdin\\); print\\(d.get\\('tag_name',''\\)\\)\")", - "Bash(curl -s \"https://raw.githubusercontent.com/simple-icons/simple-icons/16.18.0/icons/slack.svg\")", - "Bash(curl -s \"https://raw.githubusercontent.com/simple-icons/simple-icons/16.18.0/icons/visualstudiocode.svg\")", - "Bash(curl -s \"https://raw.githubusercontent.com/simple-icons/simple-icons/16.18.0/_data/simple-icons.json\")", - "Bash(curl -s \"https://registry.npmjs.org/simple-icons/latest\")", - "Bash(python3 -c \"import json,sys; d=json.load\\(sys.stdin\\); print\\(d.get\\('version',''\\)\\)\")", - "Bash(curl -s \"https://unpkg.com/simple-icons/icons/slack.svg\")", - "Bash(curl -s \"https://unpkg.com/simple-icons/icons/visualstudiocode.svg\")", - "Bash(curl -sL \"https://unpkg.com/simple-icons/icons/slack.svg\")", - "Bash(curl -sL \"https://unpkg.com/simple-icons/icons/visualstudiocode.svg\")", - "Bash(curl -sL \"https://unpkg.com/simple-icons/simple-icons.json\")", - "Bash(curl -sL \"https://unpkg.com/simple-icons@16.18.0/\")", - "Bash(curl -sL \"https://unpkg.com/simple-icons@16.18.0/?meta\")", - "Bash(curl -sL \"https://unpkg.com/simple-icons@13.22.0/icons/slack.svg\")", - "Bash(curl -sL \"https://unpkg.com/simple-icons@13.22.0/icons/visualstudiocode.svg\")", - "Bash(curl -sL \"https://unpkg.com/simple-icons@14.0.0/icons/slack.svg\")", - "Bash(curl -sL \"https://unpkg.com/simple-icons@14.0.0/icons/visualstudiocode.svg\")", - "Bash(curl -sL \"https://unpkg.com/simple-icons@14.0.0/?meta\")", - "Bash(curl -sL \"https://unpkg.com/simple-icons@9.0.0/icons/visualstudiocode.svg\")", - "Bash(curl -sL \"https://unpkg.com/simple-icons@9.0.0/simple-icons.json\")", - "Bash(curl -sL \"https://raw.githubusercontent.com/simple-icons/simple-icons/14.0.0/_data/simple-icons.json\" -o /tmp/si14.json)", - "Read(//tmp/**)", - "Bash(curl -sL \"https://raw.githubusercontent.com/simple-icons/simple-icons/9.0.0/_data/simple-icons.json\" -o /tmp/si9.json)", - "Bash(curl -sL \"https://raw.githubusercontent.com/simple-icons/simple-icons/develop/_data/simple-icons.json\" -o /tmp/si_dev.json)", - "Bash(curl -sL \"https://raw.githubusercontent.com/simple-icons/simple-icons/develop/icons/cursor.svg\")", - "Bash(curl -s \"https://api.github.com/repos/simple-icons/simple-icons/git/trees/develop?recursive=0\")", - "Bash(curl -sL \"https://raw.githubusercontent.com/simple-icons/simple-icons/develop/data/simple-icons.json\" -o /tmp/si_develop.json)", - "Bash(pnpm --filter @originmain/agent-bridge exec tsc --noEmit)", - "Bash(pnpm --filter @originmain/integrations exec tsc --noEmit)", - "Bash(pnpm --filter @originmain/multiplayer exec tsc --noEmit)", - "Bash(pnpm --filter @originmain/platform exec tsc --noEmit)", - "Bash(pnpm --filter @originmain/ai-layer exec tsc --noEmit)", - "Bash(pnpm --filter @originmain/design-language exec tsc --noEmit)", - "Bash(pnpm --filter @originmain/origin-graph exec tsc --noEmit)", - "Bash(pnpm --filter originmain-app exec tsc --noEmit)", - "WebFetch(domain:raw.githubusercontent.com)", - "WebFetch(domain:cdn.simpleicons.org)", - "WebFetch(domain:brandfetch.com)", - "WebFetch(domain:simpleicons.org)", - "WebFetch(domain:www.svgrepo.com)", - "WebFetch(domain:worldvectorlogo.com)", - "Bash(pnpm --filter @originmain/app exec tsc --noEmit)", - "Bash(mkdir -p /Users/USER/Desktop/originmain/packages/app/src/app/sign-in/\\\\[\\\\[...sign-in\\\\]\\\\])", - "Bash(mkdir -p /Users/USER/Desktop/originmain/packages/app/src/app/sign-up/\\\\[\\\\[...sign-up\\\\]\\\\])", - "Bash(python3)", - "Bash(mkdir -p \"/Users/USER/Desktop/originmain/packages/app/src/app/workspace/[wid]\")", - "Bash(mkdir -p \"/Users/USER/Desktop/originmain/packages/app/src/app/workspace/[wid]/project/new\")", - "Bash(mkdir -p \"/Users/USER/Desktop/originmain/packages/app/src/app/workspace/[wid]/project/[pid]\")", - "Bash(git -C /Users/USER/Desktop/originmain log --oneline --follow -- packages/origin-graph/migrations/002_artboard_ancestry.sql packages/origin-graph/migrations/003_rls_policies.sql packages/origin-graph/migrations/004_add_notes_to_diffs.sql)", - "Bash(git -C /Users/USER/Desktop/originmain diff --stat HEAD)", - "Bash(git -C /Users/USER/Desktop/originmain status --short)", - "Bash(mkdir -p /Users/USER/Desktop/originmain/packages/app/src/app/api/workspace/\\\\[id\\\\]/tokens)", - "Bash(mkdir -p /Users/USER/Desktop/originmain/packages/app/src/app/api/workspace/\\\\[id\\\\]/projects/\\\\[pid\\\\])", - "Bash(mkdir -p /Users/USER/Desktop/originmain/packages/app/src/app/api/workspace/\\\\[id\\\\]/invite)", - "Bash(grep anthropic *)", - "Bash(npx --yes npm-check-updates --packageFile /Users/USER/Desktop/originmain/packages/ai-layer/package.json --filter \"@anthropic-ai/sdk\")", - "Bash(pnpm --filter @originmain/app tsc --noEmit)", - "Bash(pnpm --filter @originmain/ai-layer add @anthropic-ai/sdk@latest)", - "Bash(pnpm --filter @originmain/origin-graph test)", - "Bash(grep -E \"\\\\.d\\\\.ts$\")", - "Bash(pnpm -w ls @anthropic-ai/sdk)", - "Bash(grep -v \"\\\\.map$\")", - "Bash(perl -pi -e 's/background: '\\\\''#FAFAFA'\\\\''/background: '\\\\''var\\(--page-bg\\)'\\\\''/g' /Users/USER/Desktop/originmain/packages/app/src/app/onboarding/page.tsx /Users/USER/Desktop/originmain/packages/app/src/app/error.tsx)", - "Bash(node -e ' *)", - "Bash(python3 -c \"import sys,json; [print\\(m['id']\\) for m in json.load\\(sys.stdin\\).get\\('data',[]\\)]\")", - "Bash(python3 -c \"import sys,json; d=json.load\\(sys.stdin\\); print\\(json.dumps\\({k:d[k] for k in d if k!='content'}, indent=2\\)\\); print\\('TEXT:', next\\(\\(b['text'] for b in d.get\\('content',[]\\) if b['type']=='text'\\),''\\)[:200]\\)\")", - "Bash(python3 -c \"import sys,json; d=json.load\\(sys.stdin\\); text=next\\(\\(b['text'] for b in d.get\\('content',[]\\) if b['type']=='text'\\),''\\); print\\('STATUS:', d.get\\('type','ok'\\)\\); print\\('TEXT:', text[:300]\\)\")", - "Bash(python3 -c \"import sys,json; d=json.load\\(sys.stdin\\); print\\('main:', d.get\\('main'\\)\\); print\\('exports:', json.dumps\\(d.get\\('exports',{}\\), indent=2\\)\\); print\\('scripts:', json.dumps\\(d.get\\('scripts',{}\\), indent=2\\)\\)\")", - "Bash(curl -s http://localhost:3000/api/ai/query -X POST -H 'Content-Type: application/json' -d '{\"workspace_id\":\"test\",\"question\":\"test\"}')", - "Bash(curl -sv http://localhost:3000/api/ai/query -X POST -H 'Content-Type: application/json' -d '{\"workspace_id\":\"test\",\"question\":\"test\"}')", - "Bash(curl -s -w '\\\\nHTTP_STATUS:%{http_code}' http://localhost:3000/api/ai/query -X POST -H 'Content-Type: application/json' -d '{\"workspace_id\":\"test\",\"question\":\"test\"}')", - "Bash(python3 -c \"import sys,json; d=json.load\\(sys.stdin\\); print\\(json.dumps\\(d.get\\('dependencies',{}\\), indent=2\\)\\)\")", - "Bash(python3 -c \"import sys,json; d=json.load\\(sys.stdin\\); print\\('version:', d.get\\('version'\\)\\)\")", - "Bash(python3 -c \"import sys,json; d=json.load\\(sys.stdin\\); print\\('type:', d.get\\('type'\\)\\); print\\('error:', d.get\\('error',{}\\).get\\('message','none'\\)[:200]\\)\")", - "Bash(python3 -c \"import sys,json; d=json.load\\(sys.stdin\\); text=next\\(\\(b['text'] for b in d.get\\('content',[]\\) if b['type']=='text'\\),''\\); print\\('STATUS:', d.get\\('type','?'\\)\\); print\\('ERROR:', d.get\\('error',{}\\).get\\('message','none'\\)[:300]\\); print\\('TEXT:', text[:300]\\)\")", - "Bash(perl -pi -e 's/color: '\\\\''rgba\\\\\\(255,255,255,0\\\\.22\\\\\\)'\\\\''/color: T.dim/g;' -e 's/color: '\\\\''rgba\\\\\\(255,255,255,0\\\\.18\\\\\\)'\\\\''/color: T.dim/g;' -e 's/color: '\\\\''rgba\\\\\\(255,255,255,0\\\\.28\\\\\\)'\\\\''/color: T.key/g;' -e 's/color: '\\\\''rgba\\\\\\(255,255,255,0\\\\.32\\\\\\)'\\\\''/color: T.key/g;' -e 's/color: '\\\\''rgba\\\\\\(255,255,255,0\\\\.45\\\\\\)'\\\\''/color: T.fgMuted/g;' -e 's/color: '\\\\''rgba\\\\\\(255,255,255,0\\\\.5\\\\\\)'\\\\''/color: T.fgMuted/g;' -e 's/color: '\\\\''rgba\\\\\\(255,255,255,0\\\\.62\\\\\\)'\\\\''/color: T.fgMuted/g;' -e 's/color: '\\\\''rgba\\\\\\(255,255,255,0\\\\.85\\\\\\)'\\\\''/color: T.fg/g;' -e 's/color: '\\\\''rgba\\\\\\(255,255,255,0\\\\.88\\\\\\)'\\\\''/color: T.fg/g;' /Users/USER/Desktop/originmain/packages/app/src/components/inspector/Inspector.tsx)", - "Bash(pnpm --filter @originmain/renderer exec tsc --noEmit)", - "Bash(pnpm --filter \"@originmain/origin-graph\" exec tsc --noEmit)", - "Bash(pnpm --filter \"@originmain/ai-layer\" exec tsc --noEmit)", - "Bash(pnpm --filter \"@originmain/diff-engine\" exec tsc --noEmit)", - "Bash(pnpm --filter \"@originmain/renderer\" exec tsc --noEmit)", - "Bash(pnpm --filter \"@originmain/app\" exec tsc --noEmit)", - "Bash(pnpm --filter \"@originmain/origin-graph\" run test)", - "Bash(pnpm update *)", - "Bash(pnpm --filter \"@originmain/diff-engine\" run test)", - "Bash(pnpm --filter @originmain/app typecheck)", - "Bash(pnpm --filter @originmain/ai-layer typecheck)", - "Bash(pnpm --filter @originmain/design-language typecheck)" - ] - } -} diff --git a/.env.example b/.env.example deleted file mode 100644 index 8049e98..0000000 --- a/.env.example +++ /dev/null @@ -1,31 +0,0 @@ -# Supabase — get from https://supabase.com/dashboard/project//settings/api -NEXT_PUBLIC_SUPABASE_URL= -NEXT_PUBLIC_SUPABASE_ANON_KEY= -SUPABASE_SERVICE_ROLE_KEY= - -# Anthropic — https://console.anthropic.com/settings/keys -# Never expose this in the browser bundle — server-side only -ANTHROPIC_API_KEY= - -# Clerk — https://dashboard.clerk.com -# NOTE: the publishable key MUST use the NEXT_PUBLIC_ prefix so Clerk initialises -# on the client side. The secret key is server-only and must NOT have the prefix. -NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY= -CLERK_SECRET_KEY= - -# Agent Bridge — used to sign/verify workspace tokens for IDE integrations (Cursor, Claude Code). -# Generate with: openssl rand -hex 32 -AGENT_BRIDGE_SECRET= - -# Liveblocks (Phase 3) — https://liveblocks.io/dashboard -LIVEBLOCKS_SECRET_KEY= - -# Webhook secrets — set these in each integration's dashboard -LINEAR_WEBHOOK_SECRET= -SLACK_BOT_TOKEN= -SLACK_SIGNING_SECRET= -GITHUB_WEBHOOK_SECRET= -INTERCOM_WEBHOOK_SECRET= - -# App base URL -NEXT_PUBLIC_APP_URL=http://localhost:3000 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index 476644e..0000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,55 +0,0 @@ -name: CI - -on: - pull_request: - branches: [main] - -concurrency: - group: ci-${{ github.ref }} - cancel-in-progress: true - -jobs: - ci: - name: Lint · Type · Test · Build - runs-on: ubuntu-latest - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup pnpm - uses: pnpm/action-setup@v4 - with: - version: 10 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: '22' - cache: 'pnpm' - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Type check - run: pnpm run typecheck - - - name: Lint - run: pnpm run lint - - - name: Test - run: pnpm run test - - - name: Build - run: pnpm run build - env: - NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.NEXT_PUBLIC_SUPABASE_URL }} - NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.NEXT_PUBLIC_SUPABASE_ANON_KEY }} - CLERK_PUBLISHABLE_KEY: ${{ secrets.CLERK_PUBLISHABLE_KEY }} - CLERK_SECRET_KEY: ${{ secrets.CLERK_SECRET_KEY }} - - - name: Migration dry-run - run: pnpm run migration:dry-run - env: - SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }} - SUPABASE_DB_PASSWORD: ${{ secrets.SUPABASE_DB_PASSWORD }} diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml deleted file mode 100644 index bc9c591..0000000 --- a/.github/workflows/preview.yml +++ /dev/null @@ -1,57 +0,0 @@ -name: Preview Deployment - -on: - pull_request: - branches: [main] - -concurrency: - group: preview-${{ github.ref }} - cancel-in-progress: true - -jobs: - deploy-preview: - name: Deploy Vercel Preview - runs-on: ubuntu-latest - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup pnpm - uses: pnpm/action-setup@v4 - with: - version: 10 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: '22' - cache: 'pnpm' - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Deploy to Vercel - id: vercel-deploy - uses: amondnet/vercel-action@v25 - with: - vercel-token: ${{ secrets.VERCEL_TOKEN }} - vercel-org-id: ${{ secrets.VERCEL_ORG_ID }} - vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }} - working-directory: packages/app - - - name: Post preview URL as PR comment - uses: actions/github-script@v7 - env: - PREVIEW_URL: ${{ steps.vercel-deploy.outputs.preview-url }} - COMMIT_SHA: ${{ github.sha }} - with: - script: | - const previewUrl = process.env.PREVIEW_URL; - const sha = process.env.COMMIT_SHA; - github.rest.issues.createComment({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - body: `## Preview Deployment\n\n✅ **Preview URL:** ${previewUrl}\n\nDeployed from commit \`${sha}\`` - }); diff --git a/.gitignore b/.gitignore index d6275a0..8d36b60 100644 --- a/.gitignore +++ b/.gitignore @@ -1,34 +1,11 @@ -# Dependencies -node_modules/ -.pnpm-store/ - -# Environment -.env -.env.local -.env.*.local - -# Build outputs -.next/ -dist/ -out/ -build/ - -# Test & coverage -coverage/ -.vitest/ - -# Supabase -supabase/.branches -supabase/.temp - -# Vercel -.vercel/ - -# OS .DS_Store -Thumbs.db - -# Editor -.vscode/settings.json +.env +.env.* +!.env.example +node_modules/ +.wp-env/ +vendor/ +dist/ +*.log .idea/ -*.swp +.vscode/ diff --git a/.npmrc b/.npmrc deleted file mode 100644 index 01a9404..0000000 --- a/.npmrc +++ /dev/null @@ -1,3 +0,0 @@ - -# Allow esbuild to run its install script (downloads the native binary) -build-scripts-allowed=esbuild diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 6d887b3..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,58 +0,0 @@ -# Changelog - -All notable changes to Originmain are documented here. -Format: [version] — date — summary - ---- - -## [Unreleased] - -### Added -- **Figma-style Design panel** — Inspector Design tab rebuilt from scratch with semantic Figma-parity layout: - - **Dimensions block** — W/H stepper inputs always at top, arrow-key ±1 (Shift ±10) while preserving CSS unit - - **Fill** — colour-picker swatch (opens native ``) + hex text input + alpha %; hidden when background is transparent - - **Text Color** — same colour-swatch treatment for `color` property - - **Typography** — font family full-width text input, compact row of Size / Weight / Line-H, letter-spacing + text-align toggle group (L/C/R/J icon buttons) - - **Layout** — Display select, flex-direction toggle (→↓←↑), Gap, Align/Justify selects, 4-corner padding grid (↑→↓←) - - **Appearance** — Radius + Opacity side-by-side, border colour/width (shown only when border exists), box-shadow text input - - All inputs fire `patchStyleEdit` on every change — live preview in the iframe with zero latency -- **Live resize handles** — SelectionOverlay handles call `patchStyleEdit` on every `mousemove` during drag, giving real-time iframe feedback -- **8 resize handles** — 4 corners (nwse/nesw cursors) + 4 edge midpoints (ns/ew cursors), matching Figma's control points -- **Delete component** — "✕ delete" button in the selection label bar + Delete/Backspace keyboard shortcut; sends `REMOVE_ELEMENT` to iframe (sets `display: none`, non-destructive) -- **Auto multi-screen layout** — When a live artboard connects, `ROUTES_DISCOVERED` message auto-creates new artboards for every undiscovered route in a horizontal row (80 px gaps). Designers see all app screens on the canvas without manual setup. -- **Route discovery in hook** — `discoverRoutes()` scans `` DOM links + fiber tree for Link/NavLink/RouterLink components; fires on READY and on `popstate` -- **Live style patching** — `PATCH_ELEMENT_STYLE` protocol message applies an inline-style override to a fiber node's DOM element in real time. Non-destructive — source files are unchanged; changes are exportable as diffs. -- **Element style inspection** — `REQUEST_ELEMENT_STYLES` / `ELEMENT_STYLES` protocol round-trip: hook reads `window.getComputedStyle()` for ~30 CSS properties and posts them back to the host. -- **Route-aware artboards** — Each artboard has an optional `route` field (e.g. `/dashboard`). The iframe src becomes `baseUrl + route`. Route is editable inline in the Props tab. -- **On-canvas onboarding** — The empty canvas shows a 3-step guide (Press A → run CLI → paste proxy URL) including the exact CLI command. - -### Changed -- Inspector default tab changed from **Props** to **Design** — mirrors Figma's inspect-first workflow. -- Tab order: **Design → Props → Diff → Graph**. -- `selectComponent` store action clears `selectedComponentStyles` on every selection change. -- `selectArtboard` store action clears both component selection and styles. - -### Fixed -- HTTP 204 with body in `/api/design-language` route — now returns 200. -- `tools/list` MCP endpoint now includes `inputSchema` per spec. -- `ProjectSettingsForm` role check used wrong constant (`'DEVELOPER'` → `'ENGINEER'`). -- Removed dead `INJECT_FIBER_HOOK` message type from renderer protocol. -- Zustand v5 compatibility: replaced `subscribe(selector, listener)` (removed in v5) with `useEffect` + selector hook. - ---- - -## [0.0.3] — 2026-04-28 -- CLI proxy published to npm as `@originmain/cli` -- README added covering quick start, CLI flags, programmatic API - -## [0.0.2] — 2026-04-27 -- Live rendering foundation: fiber hook injection, X-Frame-Options stripping, WebSocket passthrough -- Canvas artboard system: create, drag, rename, delete -- Inspector: Props / Diff / Graph tabs -- Live artboard iframe with bidirectional postMessage protocol -- Click-to-select components in live render with blue highlight ring -- Design token injection via CSS custom properties -- Drift report generation via AI layer -- Diff export with AI-generated summaries -- MCP agent bridge with JSON-RPC 2.0 workspace token auth -- Origin Graph query tab in inspector diff --git a/HANDOFF.md b/HANDOFF.md deleted file mode 100644 index 784788d..0000000 --- a/HANDOFF.md +++ /dev/null @@ -1,471 +0,0 @@ -# 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 | ✅ Revised | CLI proxy + Live SDK; see RENDERING-ARCHITECTURE.md | -| 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 ✅ (Revised 2026-04-29) - -**Original:** 2026-04-25 — postMessage protocol, fiber hook, MF config, LiveArtboard iframe -**Revised:** 2026-04-29 — Replaced non-functional cross-origin injection with two working modes - -> See **`RENDERING-ARCHITECTURE.md`** for the full design document. - -### Why the original approach was non-functional -The original `LiveArtboard.tsx` tried `iframe.contentDocument.createElement('script')` to inject the fiber hook. This fails for cross-origin iframes (the browser blocks DOM access), and the READY handshake had a circular dependency. See `RENDERING-ARCHITECTURE.md` §2 for details. - -### Two rendering modes (both use the same postMessage protocol) - -#### Mode A — CLI Proxy (`@originmain/cli`) -For active local development. User runs `npx @originmain/cli dev --target http://localhost:3000` and enters the proxy URL (`http://localhost:4170`) into the artboard. - -The proxy: -1. Strips `X-Frame-Options` / CSP headers from responses -2. Injects the fiber hook `` content | ✅ Yes | -| Hook installed too late | `__REACT_DEVTOOLS_GLOBAL_HOOK__` must exist **before** React's module body evaluates. Injected scripts run after HTML parses — after React is already loaded | ✅ Yes | - -**The only reliable fix**: the fiber hook must be installed by the app itself, not by an external injector. That means it ships as an npm package the developer imports **before React** in their app entry point. - ---- - -## 2. Target Architecture - -``` -┌─────────────────────────────────────────────────────────────────────────────┐ -│ ORIGINMAIN CLOUD (originmain.com) │ -│ │ -│ ┌─────────────────────────────┐ ┌──────────────────────────────────┐ │ -│ │ Canvas (Next.js app) │◄───►│ WebSocket Bridge │ │ -│ │ • Artboards / iframes │ │ /api/sdk/[projectId] │ │ -│ │ • Inspector / Editor │ │ • auth via SDK token │ │ -│ │ • File diff viewer │ │ • routes messages to user │ │ -│ └─────────────────────────────┘ └──────────────────────────────────┘ │ -│ ▲ │ -└────────────────────────────────────────────────────────│───────────────────┘ - │ WSS - │ (wss://originmain.com/api/sdk/[projectId]) -┌────────────────────────────────────────────────────────│───────────────────┐ -│ USER MACHINE (localhost / staging) │ │ -│ ▼ │ -│ ┌──────────────────────────┐ ┌────────────────────────────────────┐ │ -│ │ Next.js dev server │◄───►│ @originmain/dev (SDK) │ │ -│ │ (next dev / Vercel) │ │ • client runtime in browser │ │ -│ │ │ │ • server runtime in Node │ │ -│ │ │ │ • direct React fiber access │ │ -│ │ Components.tsx ◄────────┼─────┤ • file-write capability │ │ -│ │ │ │ • opens WSS to cloud canvas │ │ -│ └──────────────────────────┘ └────────────────────────────────────┘ │ -│ │ -│ next.config.js — wrapped with @originmain/next plugin │ -└─────────────────────────────────────────────────────────────────────────────┘ -``` - -**Key invariant**: the fiber hook lives *inside* the user's app bundle. -No proxy, no injection, no external script — the user's `import '@originmain/live'` -is what instruments React. - ---- - -## 3. System Components - -### 3.1 `@originmain/live` (client runtime) — `packages/live-sdk` - -The browser-side SDK. A side-effect import that: - -- Installs `__REACT_DEVTOOLS_GLOBAL_HOOK__` **before React evaluates** (module-load time) -- Resolves the artboard ID from three sources in priority order: - 1. URL fragment: `location.hash` contains `#__om_artboard=` ← primary, cross-origin safe - 2. `window.name`: starts with `om:` (same-origin iframes only) - 3. postMessage handshake: sends `{ __om_init_request: true }` to parent, awaits reply -- Runs the full postMessage protocol (see §4) once the artboard ID is known -- Is a **complete no-op** outside an Originmain artboard iframe (zero runtime cost in production) - -### 3.2 `@originmain/next` (build plugin) — `packages/next` - -A `withOriginmain(nextConfig)` wrapper for `next.config.ts` that: - -- Prepends `@originmain/live` to every client-side webpack entry point -- Ensures the fiber hook import runs **before any other module** in the bundle -- Skips the server-side bundle (fiber hook is browser-only) -- Is idempotent (safe to wrap twice) -- Delegates to any existing `webpack` customisation in the user's config - -### 3.3 `@originmain/dev` (full SDK) — `packages/dev` ❌ NOT BUILT YET - -The full SDK intended for local development. Will combine: - -- Everything in `@originmain/live` (client runtime, fiber hook) -- A **server runtime** that runs inside the Next.js dev server process -- A **WebSocket client** that connects outbound to the cloud canvas bridge -- **File-write capability**: receives design panel edits from the canvas and applies them to source files (`.tsx`, `.ts`, CSS modules) - -### 3.4 WebSocket Bridge — `packages/app/src/app/api/sdk/[projectId]/` ❌ NOT BUILT YET - -A Next.js API route on the cloud canvas that: - -- Accepts an inbound WSS connection from `@originmain/dev` -- Authenticates via a project-scoped SDK token (issued in project settings) -- Routes messages bidirectionally: - - SDK → Canvas: `FIBER_TREE_UPDATE`, `ELEMENT_STYLES`, `ROUTES_DISCOVERED`, etc. - - Canvas → SDK: `PATCH_ELEMENT_STYLE`, `REQUEST_ELEMENT_STYLES`, `CAPTURE_SNAPSHOT`, etc. -- Maintains one WebSocket connection per active project session - -### 3.5 Canvas (Next.js app) — `packages/app` - -Originmain's cloud editor. Current transport: **postMessage via iframe**. -Future transport: **WebSocket via bridge** (for `@originmain/dev` local dev). - -Key components: -- `LiveArtboard.tsx` — manages the `