Lighting plot generator. Vector-only SVG drafting surface, structured document model, IndexedDB autosave, project file save/load.
This started as the Phase 0 spike that validates the chassis ported from PixelForge.
Notion is the canonical phase source for this project. README status was reconciled against SFT | PlotForge on 2026-06-21.
- Hardcoded venue (36' × 22') seeded with 1ST ELEC, 2ND ELEC, FOH TRUSS positions
- 10 fixtures pre-placed (5 S4s, 3 Fresnels, 2 moving spots)
- SVG canvas: pan (drag empty area), zoom (wheel), drag fixtures along their position
- 1" snap on drag, automatic stage-right-to-left unit renumbering
- Inspector: per field validation, keyboard recovery, channel, DMX, circuit, dimmer, color, status, layered notes, and delete
- IndexedDB autosave with crash-recovery banner
.plotfile save/load via File System Access API + download fallback- Topbar save status for unsaved, saving, saved, and failed save states
- Document-snapshot undo/redo (80-entry history)
- DMX conflict detection across universes (footprint-aware) + duplicate channel detection
- Status bar reflects fixture count, position count, DMX OK / N conflicts
- Venue editor for stage width, stage depth, and proscenium width
- Position editor: add, select, rename, change kind, move by Y, resize length, edit trim, and delete positions
- Fixture library with curated GDTF seed profiles and OFL JSON import
- Patch table with CSV export
- Print to PDF export with title block and ANSI D paper preset
- Project metadata editor for show title, drawing title, venue, designer, company, show date, revision, and scale
- Named revision log with active revision selection for title block issue tracking
- Conflict panel that lists channel and DMX issues with reveal selection
- Debounced fixture inspector edits with imperial position parsing, per field commit isolation, invalid field recovery, and multi-select primary editing
- Focus beam tool for placing fixture focus points on the plot and print sheet
- Per-fixture status with inspector control, plot markers, patch table display, CSV export, and
.plotmigration - Layered fixture notes for color, gobo, focus, and crew handoff, with legacy note migration
- Multi-select fixture editing with align left, align center, align right, and distribute controls
- Gel palette rollup with per-gel fixture counts, fixture labels, and CSV export
- Circuit and dimmer schema with inspector edits, patch table display, CSV export, and circuit check summary
- Comment pins with canvas placement, sidepanel editing, print output, and
.plotmigration - Interop manifest export with fixture paperwork, GDTF provenance, focus points, circuit data, and comment pins
- OSC bridge route map with saved relay settings, JSON export, selected fixture send, and a dependency-free local WebSocket-to-UDP relay
- Multi-show registry with IndexedDB snapshots, load/delete actions,
.plotshare/export, and PWA manifest plus service worker shell caching - AI plot starter with brief parsing, local starter plan generation, prompt copy, and one click plan apply
- Command palette (Cmd/Ctrl+K): find any fixture by channel, unit, DMX pair, gel, instrument, position, or status and jump the canvas to it
- Marquee select (Shift+drag) plus named Systems: save any selection as a reusable set with one-click reselect
- Rig Check mode: guided channel-check walk that fires each unit's OSC select route through the relay and records status per unit, fully offline-safe
- Revision rig diff: every new revision snapshots the rig; compare live doc against any revision with ghost markers on the plot and a copyable change list
- Focus charts and magic sheet: printable per-position focus paperwork plus gel-grouped magic sheet generated from existing document data
Lightwright roundtrip, auth, sharing, and production quality of life tools.
MVR import parser locking is parked until Vectorworks Spotlight 2024 / 2025 / 2026 .mvr sample files are available.
Vendor-specific OSC console macro packs remain future work.
Provider backed AI generation remains future work until a model and pricing decision exists.
cd plot-forge
npm install # pulls React 19, Vite 8, vitest 4
npm run dev # http://localhost:5173
npm run build
npm testRequires Node 22+.
Latest verification on 2026-08-09, on a fresh checkout of main at b34855f with Node v22.22.1:
npm run lint: 0 errors, 0 warnings.npm test -- --run: 31 files passed, 160 tests passed.npm run build: Vite production build completed.- Production: GitHub deployment
5820228196(commit5b326c5, five-feature drop) then5820291141(commitb34855f, changelog reconcile); Vercel deploymentdpl_FjsX4xhXxJjqi1K7gVJbsFzUjS7Tis READY andhttps://plotforge-beta.vercel.appreturns HTTP 200.
Earlier local verification on 2026-06-22 with Node v22.22.1:
PATH=/opt/homebrew/opt/node@22/bin:$PATH ./node_modules/.bin/eslint src/components/Inspector.jsx src/components/SaveStatus.jsx src/hooks/useShowDoc.js src/hooks/useAutosaveRecovery.js src/PlotForge.jsx src/debugEvents.js src/__tests__/inspector.test.jsx src/__tests__/useShowDoc.test.jsx: 0 errors, 0 warnings.PATH=/opt/homebrew/opt/node@22/bin:$PATH ./node_modules/.bin/vitest run src/__tests__/inspector.test.jsx src/__tests__/useShowDoc.test.jsx --pool=forks --maxWorkers=1 --no-file-parallelism --reporter=verbose: 2 files passed, 30 tests passed.PATH=/opt/homebrew/opt/node@22/bin:$PATH npm run lint: 0 errors, 0 warnings.PATH=/opt/homebrew/opt/node@22/bin:$PATH npm run build: Vite production build completed.PATH=/opt/homebrew/opt/node@22/bin:$PATH ./node_modules/.bin/vitest run --pool=forks --maxWorkers=1 --no-file-parallelism: 25 files passed, 115 tests passed.
Earlier local verification on 2026-06-11 with Node v22.22.1 and npm 10.9.4:
- Cleared the locked partial install directory
_trash-nm. npm installcompleted with 346 packages audited and 0 vulnerabilities.node scripts/smoke-domain.mjs: 15 / 15 passing.node scripts/syntax-check.mjs: 21 / 21 JS and JSX files parsed cleanly.npm run lint: 0 errors and 0 warnings.npm test: 2 files passed, 13 tests passed.npm run build: Vite production build completed.- Browser check at
http://127.0.0.1:5173/: app renders the seeded plot with 10 fixtures, 3 positions, and DMX OK. Console has only the React DevTools info message. - P0-1 browser check: Add created a fourth position, edit changed it to
BALC PIPE/FOH/-4'-0"/24'-0", delete returned the app to 3 positions, mobile width had no horizontal overflow, and console errors stayed at 0. - Browser screenshot saved at
docs/plotforge-dev-verified-2026-06-11.png. - P0-1 editor screenshot saved at
docs/plotforge-p0-1-editor-2026-06-11.png.
src/
domain/
show.js show / venue / position / fixture types + pure mutations
patch.js DMX + channel conflict detection
oscBridge.js OSC route map, manifest, and packet encoding
plotStarter.js local AI starter planning and apply helpers
fixtureNotes.js color / gobo / focus / crew note normalization
fixtureStatus.js per-fixture status options + normalization
focus.js focus point snapping + beam rows
profiles.js curated GDTF seed profiles + OFL import normalization
units.js mm-as-integer conversions + imperial parser
ids.js collision-resistant id generator
hooks/
useHistory.js document-snapshot undo/redo
useAutosaveRecovery.js debounced IndexedDB autosave + recovery probe
usePanZoom.js SVG viewBox-based pan + zoom
components/
ProjectMetadata.jsx editable project metadata + title block source
RevisionsPanel.jsx named revision log
ConflictPanel.jsx conflict list + reveal action
PlotCanvas.jsx SVG drafting surface
FixtureSymbol.jsx fixture glyphs
Inspector.jsx fixture metadata editor with debounced commits
SaveStatus.jsx topbar save state chip
PlotStarterPanel.jsx AI plot starter sidepanel
DraftRecoveryBanner.jsx
ErrorBoundary.jsx
autosave.js IndexedDB store (ported from PixelForge)
debugEvents.js dev-only local debug ring buffer
showRegistry.js multi-show IndexedDB snapshot registry
serialization.js .plot JSON schema + File System Access API + migrations
PlotForge.jsx app root
PlotForge.css tokens + layout
InspectorUx.css inspector and save status UX refinements
main.jsx entry
scripts/
smoke-domain.mjs no-deps smoke harness for the domain layer
syntax-check.mjs walks src/ and parses every JS/JSX with @babel/parser
- Internal canonical unit: millimeters as integers. No float drift, no unit confusion at the data layer.
- Display scale (
1/4" = 1', metric, etc.) is a presentation concern only. - Origin (0, 0) is at center-line / plaster-line. +x is stage-right (audience-left), +y is upstage.
- Position lines are horizontal (constant y). Fixtures slide along x.
- SVG
viewBoxIS world coordinates (mm). CSS sizing handles the viewport.
The chassis: build pipeline (Vite, ESLint, Vitest), autosave.js IndexedDB store (renamed DB), the structural shape of useHistory (rewritten for whole-doc snapshots — pixel-shaped layer-patch logic was dropped), the dark UI palette pattern, the ErrorBoundary component pattern, the project-file save/load pattern with File System Access API + download fallback.
Everything raster (brushes, floodFill, imageEffects, imageImport, canvasOps, render, text, marquee, clipboard, shapes) was dropped — wrong architecture for vector drafting.
Current canonical status, reconciled from Notion on 2026-06-22:
- P0-1 venue and position editor: shipped.
- P0-2 fixture library and add-fixture flow: shipped on 2026-06-18. Curated GDTF profiles and OFL JSON import are implemented.
- P0-3 patch table plus CSV export: shipped on 2026-06-21. The sidepanel patch table lists fixture, profile, channel, DMX range, footprint, and conflict state, with CSV export.
- P0-4 print to PDF with title block: export path shipped on 2026-06-21. Physical ANSI D fidelity sign-off is parked until plotter access is available.
- P1-1 project metadata plus editable title block: shipped on 2026-06-21. The sidepanel edits show title, drawing title, venue, designer, draftsperson, company, show date, revision, and scale; print output uses the same metadata.
- P1-2 named revisions: shipped on 2026-06-21. The sidepanel saves named revision records with notes, can activate a prior revision, and drives the title block revision field from the active record.
- P1-3 conflict panel with reveal: shipped on 2026-06-21. The sidepanel lists channel and DMX conflicts with affected fixtures and a Reveal action that selects the first fixture in the conflict.
- P1-4 inspector debouncing plus imperial parsing: shipped on 2026-06-21. The inspector stages channel, DMX, color, note, and position edits locally, commits after a short pause or blur, parses feet and inch position text, and shows inline errors for invalid measurements.
- P1-5 focus beam tool: shipped on 2026-06-21. The canvas Focus tool places snapped focus points for the selected fixture, renders focus beams on the live plot, includes focus beams in print output, and can clear the selected fixture focus.
- P1 tier deploy: shipped on 2026-06-21. Production alias
https://plotforge-beta.vercel.apppoints at the P1 focus beam build. - P2-1 fixture status: shipped in the repo on 2026-06-21. Fixtures store normalized status, legacy
.plotdocs migrate to planned, the inspector edits status, canvas symbols show a status marker, and patch table plus CSV output include status. - P2-2 layered notes: shipped in the repo on 2026-06-21. Fixtures store color, gobo, focus, and crew note layers, older
notevalues migrate into the crew note, the inspector edits each layer, and patch table plus CSV output include layered note data. - P2-3 multi-select plus align and distribute: shipped in the repo on 2026-06-21. Modifier-click selection tracks multiple fixtures, the primary fixture still drives the inspector and focus tools, and the selection panel aligns or distributes selected fixtures along the X axis.
- P2-4 gel palette plus order rollup: shipped in the repo on 2026-06-21. Fixture color strings are parsed into normalized gel codes, the sidepanel lists per-gel counts and fixture labels, and CSV export produces the gel order.
- P2-5 circuit and dimmer schema: shipped in the repo on 2026-06-21. Fixtures store normalized circuit and dimmer fields, legacy
.plotdocs migrate with empty defaults, the inspector edits both fields, the patch table and CSV include both fields, and the circuit check panel flags unassigned, partial, and shared assignments. - P2-6 comment pins: shipped in the repo on 2026-06-21. Plot clicks in Comment mode create pinned notes, the canvas renders selectable numbered pins, the sidepanel edits and deletes pin text, print output includes pin callouts, and legacy
.plotdocs migrate with empty pin stores. - P2 tier deploy: shipped on 2026-06-21. Production alias
https://plotforge-beta.vercel.appserves the P2 comment pin build. - P3-1 MVR and GDTF interop: partially shipped in the repo on 2026-06-21. The P3 Interop manifest exports fixture paperwork, GDTF Share provenance, focus points, circuit and dimmer data, layered notes, and comment pins as JSON. MVR import parser locking is parked until Vectorworks Spotlight 2024 / 2025 / 2026
.mvrsample files are available. - P3-2 OSC console bridge: shipped in the repo on 2026-06-22. The sidepanel stores relay settings in the
.plotdocument, exports a JSON OSC bridge manifest, creates select / patch / status / focus routes from fixture data, sends the selected fixture route over WebSocket, and includesnpm run osc:relayas a local UDP OSC relay. - P3-3 multi-show registry plus share plus PWA: shipped in the repo on 2026-06-22. The sidepanel saves named show snapshots into IndexedDB, loads or deletes saved shows, shares the current
.plotthrough Web Share with download fallback, and adds a web app manifest plus service worker shell cache. - P3-4 AI plot starter: shipped in the repo on 2026-06-22. The sidepanel accepts a production brief, generates a local starter plan with positions, fixture groups, colors, channels, DMX starts, and focus notes, applies that plan into the document without clearing existing work, and copies a structured prompt for future provider backed AI refinement.
- P3 tier deploy: shipped on 2026-06-22. Production alias
https://plotforge-beta.vercel.appserves the P3 AI plot starter build. - Inspector UX and validation artifact: shipped in the repo on 2026-06-22. The inspector now keeps valid sibling field commits moving when one field is invalid, reverts invalid fields on blur or Escape, flushes valid drafts before unmount, supports arrow key numeric stepping, shows multi-select primary editing, exposes a topbar save status chip, and writes local debug events only in development.
docs/UX_UI_AUDIT.md defines the UX/UI audit protocol for the editor: seven weighted lenses with pass gates, a ten-scenario task battery drawn from real production workflow, a domain-weighted severity model, the test fixtures to build, and a scorecard with release gates.
docs/UX_UI_AUDIT_RESULTS_2026-08-07.md records the first execution of that protocol against aae4ac0, followed by a remediation pass. The original run scored 1.9 / 5 with two S1 findings and zero S0. All findings are now patched and re-verified with the same harness: axe violations across nine panels in both themes went 298 to 0, the canvas is operable by keyboard, fixture positions are clamped to their pipe, Inspector edits no longer drop keystrokes, and pan p95 at 800 fixtures went 22 to 44 fps. One finding (PF-UX-012) was retracted as a false positive. Lenses needing a domain reviewer, screen readers, a plotter, other browsers, or macOS remain unrun and are listed as such.
Documented remaining plan:
- P0: complete except ANSI D fidelity sign-off parked on plotter access.
- P1: complete and deployed.
- P2: complete and deployed.
- P3: complete and deployed except MVR import parser locking parked on sample file access.