Phase 5 Stage E: full kind migration into packages/nodes

Wholesale move of every remaining kind into its own subdirectory under
`packages/nodes/src/`, finishing the registry-driven migration. Each
kind now ships its definition, schema (re-exported from core), and any
of `geometry` / `renderer` / `system` / `floorplan` / `tool` /
`move-tool` / `panel` / `floorplan-move` / `floorplan-affordances` /
`parametrics` / `preview` it needs — no per-kind code remains under
`packages/editor/src/components/tools/` or
`packages/viewer/src/components/renderers/`.

Deleted (replaced by registry-driven equivalents):
- `tools/{ceiling,column,door,fence,item,slab,spawn,wall,window}/...`
  (boundary editors, hole editors, placement tools, move tools,
  endpoint movers, curve tools, helpers, math libs)
- `ui/helpers/{ceiling,slab,wall}-helper.tsx`
- `ui/panels/{column,door,elevator,item,roof,roof-segment,spawn,
  stair,stair-segment,wall,window}-panel.tsx`
- `viewer/src/components/renderers/{building,ceiling,column,door,
  elevator,fence,guide,item,level,roof,roof-segment,scan,site,slab,
  spawn,stair,stair-segment,wall,window,zone}-renderer.tsx`
- `viewer/src/components/viewer/legacy-system.tsx`

Added under `packages/nodes/src/`:
- `building/`, `column/`, `elevator/`, `guide/`, `level/`, `roof/`,
  `roof-segment/`, `scan/`, `shared/`, `site/`, `stair/`,
  `stair-segment/` packages with definition + schema + renderer / system
  / floorplan / panel as appropriate.
- New `floorplan-move.ts` for every kind that supports 2D moves
  (ceiling, door, item, shelf, slab, window) — single registry-driven
  dispatch path via `def.floorplanMoveTarget`.
- New `floorplan-affordances.ts` for kinds with polygon / endpoint
  drags (ceiling, fence, slab, wall) — using the shared
  `polygon-vertex-affordance` factories.
- New per-kind `panel.tsx` for kinds with custom inspector content
  (door, item, shelf, spawn, wall, window).
- New per-kind `tool.tsx` for placement (door, item, shelf, window).
- New per-kind `move-tool.tsx` for kinds with custom 3D move flows
  (door, item, slab, window).

Coordinator + manager updates in `packages/editor/`:
- `tool-manager.tsx` resolves tools from the registry only — no
  hardcoded type→component map.
- `panel-manager.tsx` resolves inspector panels the same way.
- `placement-{coordinator,strategies,types}.ts` extended with
  shelf-surface placement.
- `selection-manager.tsx` adds the registry-selectable fallback.
- `floorplan-panel.tsx`, `floorplan-background-placement.ts`,
  `floorplan-render-context.tsx` updated for the registry layer's new
  contract (props, affordance dispatch, render context).

Viewer updates:
- `viewer/index.tsx` drops legacy renderer mounts.
- `node-renderer.tsx` resolves by registry only.
- `scene-bvh.tsx`, `use-node-events.ts`, `level-system.tsx`,
  `wall-cutout.tsx`, `zone-system.tsx`, `materials.ts` adjusted for
  the registry-only world.

Sidebar tree nodes for ceiling / fence / slab / shelf / tree-node
updated to read from the registered nodes instead of the deleted
legacy renderer trees.

Wiki: new `plugin-authoring.md` page, README index updated.

Tests in `packages/nodes/src/index.test.ts` validate every registered
kind has the required shape.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Wassim SAMAD
2026-05-19 15:14:12 -04:00
co-authored by Claude Opus 4.7
parent 11015ea1ed
commit d747d2f0ea
204 changed files with 6888 additions and 7877 deletions
+41 -4
View File
@@ -1,13 +1,25 @@
import type { AnyNodeDefinition, Plugin } from '@pascal-app/core'
import { buildingDefinition } from './building'
import { ceilingDefinition } from './ceiling'
import { columnDefinition } from './column'
import { doorDefinition } from './door'
import { elevatorDefinition } from './elevator'
import { fenceDefinition } from './fence'
import { guideDefinition } from './guide'
import { itemDefinition } from './item'
import { levelDefinition } from './level'
import { roofDefinition } from './roof'
import { roofSegmentDefinition } from './roof-segment'
import { scanDefinition } from './scan'
import { shelfDefinition } from './shelf'
import { siteDefinition } from './site'
import { slabDefinition } from './slab'
import { spawnDefinition } from './spawn'
import { stairDefinition } from './stair'
import { stairSegmentDefinition } from './stair-segment'
import { wallDefinition } from './wall'
import { windowDefinition } from './window'
import { zoneDefinition } from './zone'
/**
* Built-in plugin bundling every node kind shipped with the Pascal editor.
@@ -22,15 +34,14 @@ import { windowDefinition } from './window'
*
* All kinds are registered unconditionally. Parity is verified by
* comparing against deployed production rather than an in-app env-var
* flag toggle. Legacy paths still exist in `viewer/` and `editor/` for
* kinds undergoing migration; they short-circuit via the Phase 0
* `<LegacySystem>` wrapper + `NodeRenderer`'s registry-first dispatch.
* Phase 6 deletes the legacy paths.
* flag toggle. As of Phase 6 the legacy mount points in `viewer/` are
* gone — every kind dispatches through the registry.
*/
export const builtinPlugin: Plugin = {
id: 'pascal:core',
apiVersion: 1,
nodes: [
// Stage E-complete (full registry path)
shelfDefinition as unknown as AnyNodeDefinition,
spawnDefinition as unknown as AnyNodeDefinition,
wallDefinition as unknown as AnyNodeDefinition,
@@ -40,15 +51,41 @@ export const builtinPlugin: Plugin = {
doorDefinition as unknown as AnyNodeDefinition,
windowDefinition as unknown as AnyNodeDefinition,
itemDefinition as unknown as AnyNodeDefinition,
// Stage A — wrap-exports the legacy renderer + system. Legacy
// panels / move tools / floorplan branches still serve these.
columnDefinition as unknown as AnyNodeDefinition,
elevatorDefinition as unknown as AnyNodeDefinition,
roofDefinition as unknown as AnyNodeDefinition,
roofSegmentDefinition as unknown as AnyNodeDefinition,
stairDefinition as unknown as AnyNodeDefinition,
stairSegmentDefinition as unknown as AnyNodeDefinition,
zoneDefinition as unknown as AnyNodeDefinition,
siteDefinition as unknown as AnyNodeDefinition,
buildingDefinition as unknown as AnyNodeDefinition,
levelDefinition as unknown as AnyNodeDefinition,
guideDefinition as unknown as AnyNodeDefinition,
scanDefinition as unknown as AnyNodeDefinition,
],
}
export { buildingDefinition } from './building'
export { ceilingDefinition } from './ceiling'
export { columnDefinition } from './column'
export { doorDefinition } from './door'
export { elevatorDefinition } from './elevator'
export { fenceDefinition } from './fence'
export { guideDefinition } from './guide'
export { itemDefinition } from './item'
export { levelDefinition } from './level'
export { roofDefinition } from './roof'
export { roofSegmentDefinition } from './roof-segment'
export { scanDefinition } from './scan'
export { shelfDefinition } from './shelf'
export { siteDefinition } from './site'
export { slabDefinition } from './slab'
export { spawnDefinition } from './spawn'
export { stairDefinition } from './stair'
export { stairSegmentDefinition } from './stair-segment'
export { wallDefinition } from './wall'
export { windowDefinition } from './window'
export { zoneDefinition } from './zone'