Commit Graph
299 Commits
Author SHA1 Message Date
Wassim SAMADandClaude Opus 4.7 386df62b43 Add MovementService (axis-lock + grid-snap) to core (Phase 1, 4/6)
Pure constraint math built on the registry's `MovableConfig`:

- `resolveMovable(node)` — reads `def.capabilities.movable`, runs the
  optional `override(ctx)` callback (returning null falls back to the
  base config). Returns null when the kind isn't movable.
- `applyAxisLock(current, target, axes)` — projects 3D motion onto
  the allowed axes; locked components fall back to current.
- `moveToward(node, current, target, options?)` — top-level helper
  combining axis lock + (optional) grid snap. Returns null when the
  node is not movable.
- `movePlanToward(node, currentY, current, target, options?)` —
  X/Z-plane convenience for floor/plan-view placement.
- `isMovable(node)` — predicate for tools/UI gating.

Tests cover override callback, null-override fallback, axis lock
permutations, grid-snap on/off, and the 2D plan convenience.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 12:29:00 -04:00
Wassim SAMADandClaude Opus 4.7 bc0c73d449 Add SnapServices (grid + angle) to core (Phase 1, 3/6)
Pure math, no React, no scene access. Three primitives plus a facade:

- `snapScalar(value, step)` / `snapPointToGrid(point, step)` /
  `snapVec3ToGrid(point, step)` — regular grid snapping. Default
  step 0.25m matches the editor's wall tool.
- `snapPointToAngle(from, cursor, angleStep, gridStep?)` — locks a
  cursor to the nearest angle multiple from a fixed point, preserves
  distance, optionally re-grids the projected point. Default angle
  step π/12 (15°).
- `snapAngleToList(angle, list, tolerance)` — snaps a free angle to
  the nearest entry in a fixed list (e.g. 0/45/90/135) within a
  tolerance; returns the original angle otherwise. Handles wrap.
- `snapServices` facade — `grid.*` + `angle.*` namespaces. Stable
  contract that `DragAction.snap` callbacks receive. Phase 3 ports
  the existing `snapWallDraftPoint` family from
  `editor/.../wall-drafting.ts` under a `wall.*` namespace.

17 unit tests cover the math + the facade pass-through. No existing
callers re-wired yet — Phase 2 column/shelf tools are the first
consumers.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 12:27:25 -04:00
Wassim SAMADandClaude Opus 4.7 cf93c32183 Add HostingService with cycle/depth/kind validation (Phase 1, 2/6)
First service in `core/src/services/`: pure, no React or R3F, takes
SceneApi + node data, returns results.

Exports:
- `canAttach(childId, hostId, scene)` — validates host attachment.
  Rejects self-host, cycles (host's ancestor chain contains child),
  chains past MAX_HOST_DEPTH (6), and host kinds outside the child
  def's `capabilities.hostable.parents` allowlist. Returns a typed
  AttachError discriminated union so callers can render specific
  messages.
- `getSurface(host)` / `getTopSurfaceHeight(host)` — reads
  `def.capabilities.surfaces` from the registry; resolves
  function-valued heights with the node.
- `clampYToHostTop(host, y)` — convenience for placement code.
- `pickHost({ point, candidates, placedKind, hitTest? })` — given
  spatially pre-filtered candidates, returns the first hostable.
  The runtime is responsible for spatial filtering; this function
  stays pure.

MAX_HOST_DEPTH = 6: the explore earlier found today's editor has no
cap on item-on-item nesting. Cap is bounded by hostable depth, not
total tree depth (sites/buildings/levels don't count).

17 tests cover all rejection paths + happy paths + function-valued
surface heights.

Re-exported from `@pascal-app/core` via a new `services/` barrel.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 12:20:28 -04:00
Wassim SAMADandClaude Opus 4.7 90702e74e2 Add relations cascade resolver (Phase 1, 1/6)
Pure traversal that walks a node's declared `relations` and returns the
full set of IDs that should be marked dirty alongside it. Two
implementations:

- `cascadeDirty(id, ctx)` — follows `hosts` (matching children) and
  `affectsSpatial` (via injected spatialQuery). Phase 3 will add
  `linkedBy: 'endpoint-match'`.
- `collectDescendants(id, ctx)` — pure subtree traversal for
  `cascadeDelete: 'descendants'` and subtree deletion tools.

Both bounded by maxDepth (default 16) and visited-set so cycles in
bad data can't loop forever.

Context-based design: spatialQuery and childQuery are injected, so the
resolver itself stays pure — the DragAction runtime can plug in
spatialGridManager-backed queries; tests pass stubs.

Today, registry has no kinds → cascadeDirty(id) always returns just
{id}. No behavior change. Phase 3 wall is the first real consumer.

11 unit tests cover empty/no-relations baseline, hosts cascade, depth
limit, spatial query, missing spatialQuery branch, cycle protection,
childQuery override, descendant collection.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 12:16:56 -04:00
Wassim SAMADandClaude Opus 4.7 3de098fe4f Add Presentation + IconRef to NodeDefinition v1 surface
Adds optional `presentation` field for tool palette metadata: sentence-
case label, optional description, icon (iconify reference, inline SVG,
or lazy React component), palette section override, sort order, and a
`hidden` flag for container kinds that exist but should not appear in
the palette.

Consumer arrives in Phase 4 (auto-derived palette buttons) — defining
the type now means Phase 2's `column` and `shelf` definitions ship with
the field already populated, no later round-trip.

Iconify is the encouraged form for built-ins and AI-authored nodes:
matches the @iconify-react setup the editor app already uses, and AI
emits a name string from a curated list (no asset upload step needed).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 12:09:10 -04:00
Wassim SAMADandClaude Opus 4.7 c683c04c39 Add test script to @pascal-app/core so turbo picks up its unit tests
Without a "test" script the package was invisible to `turbo test` —
private-editor's CI runs `bun run test` (= `turbo test`), which only
walks workspace packages that declare a test runner. Mirrors mcp and
nodes which already do this.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 11:41:46 -04:00
Wassim SAMADandClaude Opus 4.7 4c3feea052 Proxy-back sceneRegistry.byType for registry/plugin kinds (shim 1/4)
byType was a hardcoded object keyed by the built-in node kinds. With
the registry, kinds can come from @pascal-app/nodes (or future
plugins) — so byType now wraps a Map via a Proxy that auto-creates an
empty Set the first time any kind is touched.

Built-in kinds are still pre-seeded at module init so the fast path
(no Proxy trap) is preserved. clear() iterates the backing Map.

useRegistry's `type` parameter widens from `keyof typeof byType` to
`KnownNodeKind | (string & {})` — preserves autocomplete for
built-ins while accepting plugin-supplied kinds.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 11:30:55 -04:00
Wassim SAMADandClaude Opus 4.7 a41321e193 Lock bun.lock for @pascal-app/nodes workspace + sort registry barrel
Companion changes for the new nodes package: bun.lock entry from
`bun install`, and a Biome-auto-sort of the registry barrel.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 11:25:27 -04:00
Wassim SAMADandClaude Opus 4.7 fb91713374 Add node registry primitives (PR 0.1 of node-registry plan)
Introduces the @pascal-app/core/registry surface that future node-bundle
packages (and external plugins) will use to register node kinds with the
host. No runtime behavior changes — registry is empty until subsequent
PRs populate it.

- types.ts: NodeDefinition, Capabilities, Relations, DragAction, Plugin,
  ParametricDescriptor, Affordance, SceneApi, NodeRegistry. Capability
  configs accept an override escape hatch; additive-only after v1.
- registry.ts: nodeRegistry singleton, registerNode, async loadPlugin.
  Validates kind, schemaVersion, apiVersion; rejects duplicate kinds.
- scene-api.ts: createSceneApi factory wrapping the scene store with
  copy-on-write snapshot semantics for pauseHistory/restore/resumeHistory.
- index.ts: barrel re-exporting the public surface.
- core/index.ts + package.json: export * from registry and add the
  ./registry subpath so consumers can import either way.

Tests (27 cases, all bun:test): registry registration / validation /
plugin loading; SceneApi read/write/dirty/history; lazy snapshot capture
with update/upsert/delete reversal via restore and restoreAll.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 11:18:29 -04:00
Wassim SAMADandClaude Opus 4.7 c5ee1c64d0 Mark elevator-opening-system as client
The file imports useEffect/useRef from React, which Next.js RSC builds
flag as client-only. Other core systems (e.g. elevator-runtime-system)
use useFrame from @react-three/fiber and slip through, but this one
needs the directive explicitly.

Fixes Turbopack build failure in private-editor community app:
"You're importing a module that depends on useEffect into a React
Server Component module."

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 16:49:17 -04:00
sudhir ce69433a1a Refine elevator sync and viewer rebuild handling 2026-05-13 22:28:19 +05:30
sudhir 9838d2cd4f Refactor elevator runtime into core 2026-05-13 01:56:06 +05:30
sudhir b782ce9cf2 Merge branch 'main' into feat/elevator-system
# Conflicts:
#	packages/editor/src/components/tools/item/move-tool.tsx
#	packages/editor/src/components/tools/tool-manager.tsx
#	packages/editor/src/components/ui/panels/panel-manager.tsx
#	packages/editor/src/store/use-editor.tsx
#	packages/viewer/src/components/renderers/site/site-renderer.tsx
#	packages/viewer/src/components/viewer/ground-occluder.tsx
#	packages/viewer/src/components/viewer/index.tsx
#	packages/viewer/src/components/viewer/post-processing.tsx
2026-05-13 01:38:55 +05:30
sudhir 70c85d7760 Refine wall move previews and expose auto-slab planning 2026-05-12 12:15:45 +05:30
sudhir 564bfa229e Merge remote-tracking branch 'origin/main' into fix/fri-8-may
# Conflicts:
#	packages/editor/src/components/tools/fence/move-fence-endpoint-tool.tsx
#	packages/editor/src/components/tools/select/box-select-tool.tsx
#	packages/editor/src/components/tools/wall/move-wall-tool.tsx
#	packages/editor/src/components/ui/panels/column-panel.tsx
#	packages/editor/src/components/ui/panels/door-panel.tsx
#	packages/editor/src/components/ui/panels/window-panel.tsx
#	packages/viewer/src/components/renderers/column/column-renderer.tsx
#	packages/viewer/src/components/viewer/index.tsx
#	packages/viewer/src/systems/slab/slab-system.tsx
2026-05-12 00:27:06 +05:30
sudhir be41511474 Fix wall move junction ownership 2026-05-11 23:46:57 +05:30
sudhir 92a9846193 Refactor elevator systems across core, viewer, and editor 2026-05-10 12:38:44 +05:30
sudhir 909f96ef09 Improve elevator floorplan resize and drag controls 2026-05-10 12:20:53 +05:30
github-actions[bot] 60dbfcd3fe release: @pascal-app/core@0.8.0 @pascal-app/viewer@0.8.0 @pascal-app/editor@0.8.0 @pascal-app/mcp@0.2.0 2026-05-10 00:41:38 +00:00
sudhir 263228cbf0 Add cab door-open control and align elevator buttons 2026-05-10 02:28:00 +05:30
Wawa e618175bba Reset core/viewer/editor/mcp packages and apps/editor from private-editor
Wholesale swap of packages/{core,viewer,editor,mcp} and apps/editor with the
versions from the private editor repo, which is the production source of truth.

Setup changes:
- packages/{core,viewer,editor} versions held at 0.7.0 baseline (matching
  the most recent published release) so a bump=minor publishes 0.8.0
- packages/mcp held at 0.1.1 (never published; first publish will go through
  the new release.yml flow)
- peerDependencies and devDependencies for inter-package @pascal-app/*
  references pinned to ^0.7.0 instead of '*' / 'workspace:*' so they are
  valid for npm consumers
- Root package.json: TypeScript bumped to 6.0.2, added overrides for
  @types/react, @types/react-dom, @types/three to prevent JSX namespace
  fragmentation across the workspace
- release.yml extended to also publish editor and mcp; 'both' option renamed
  to 'all'; added a sync step that updates inter-package peerDeps/devDeps to
  match the new versions on every bump (so viewer/editor/mcp tarballs always
  reference the version of core they were built against)
- Root scripts gained release:editor and release:mcp shortcuts

Verification:
- bun install --frozen-lockfile is consistent
- packages/{core,viewer,mcp} build cleanly, dist/index.d.ts emitted
- packages/editor check-types reports 21 pre-existing errors, identical to
  what private-editor currently reports

Open PRs against editor-v2 will need rebasing/conflict resolution.
2026-05-09 20:52:26 +00:00
open-pascal 146f0a846f release: v0.7.0 2026-05-09 14:37:55 +00:00
sudhir 2480be91b1 Optimize elevator editing performance with live previews 2026-05-09 19:09:48 +05:30
Pascal 723ae14e9b release: v0.6.1 2026-05-09 02:25:15 +00:00
sudhir 0514363136 Add column hit testing and align column defaults 2026-05-08 14:31:58 +05:30
sudhir 53393b7def Add procedural support column variants 2026-05-08 12:54:59 +05:30
Wassim SAMADandGitHub e348ccdb08 Merge pull request #296 from sudhir9297/wed-6-may-bug-fix
fix: Improve item surface placement, floorplan resizing, and placement preview stability
2026-05-07 13:09:20 -04:00
sudhir 8f6a8fbe8b Add first-person window interaction 2026-05-07 13:50:30 +05:30
sudhir 133d81e563 Refine window corner shape support 2026-05-07 13:34:16 +05:30
sudhir eef19804d1 Merge branch 'main' into feat/door-improvement
# Conflicts:
#	packages/core/src/events/bus.ts
#	packages/viewer/src/systems/door/door-system.tsx
2026-05-07 10:40:51 +05:30
sudhir cef3f24dad Move door animations into viewer system 2026-05-07 10:11:25 +05:30
sudhir 7e86e4628c Fix item surface placement and remove item height annotations 2026-05-06 15:13:37 +05:30
Wassim SAMADandGitHub 5f57e9bb09 Merge pull request #292 from sudhir9297/feat/mon-4-feat-fix
feat: column node with door/window nodes improvement
2026-05-05 16:39:21 -04:00
sudhir f5f80d0f3f Centralize door animation state and operation mapping 2026-05-05 17:23:48 +05:30
sudhir 1490d280d4 Refine editor layer boundaries and selection handling 2026-05-05 13:26:39 +05:30
Pascal 1002a0a980 feat(editor): precise item dimensions — static bounding boxes, placement-math, remove item-mesh-metadata system
- Replace runtime mesh-based bounding-box computation with static dimension-based polygons for item footprints
- Add snapUpToGridStep() and getGridAlignedDimensions() to placement-math for grid-cell-aligned placement wireframes
- Add expandBoundsToGrid() to use-placement-coordinator for consistent wireframe snapping
- Add currentCursorRotationY to PlacementContext; preserve world orientation across item-surface transitions
- Fix item detach from surface: use worldToBuildingLocal() instead of event.localPosition to avoid coordinate-space jump
- Subscribe to useLiveTransforms in FloorplanPanel during placement so R/T keyboard rotation refreshes the 2D overlay immediately
- Fix FloorplanItemImage rotation (+180° to account for top-down camera capture orientation)
- Simplify spatial-grid-manager: single dimension-based getItemLocalBounds(), removes runtime mesh-metadata path
- Remove item-mesh-metadata system (compute-item-mesh-metadata, item-mesh-metadata-system, sync-request)
2026-05-04 19:35:41 +00:00
sudhir 762c9fc763 Refactor guide events and column placement handling 2026-05-04 23:06:23 +05:30
sudhir db765f1eb3 Enable pillar duplication in floating action menu 2026-05-04 22:54:52 +05:30
sudhir 848529acb0 Add column presets and procedural shaft controls 2026-05-04 16:38:52 +05:30
sudhir 23eec44714 Move render systems out of core 2026-05-01 15:07:47 +05:30
sudhir b3f7957076 Refactor editor selection and viewer integration 2026-05-01 13:54:23 +05:30
sudhir 09bfb0b484 Add frameless door openings and first-person collider support 2026-05-01 11:35:26 +05:30
sudhir 915393d649 Add swing angle support for door rotation 2026-05-01 10:18:36 +05:30
sudhir 3df3d12f46 Refactor guide UI state and slab rendering 2026-05-01 00:33:57 +05:30
sudhir f375861439 Merge branch 'main' of github.com:sudhir9297/editor into feat/improvement-and-fixes 2026-04-30 22:59:10 +05:30
sudhir 8631622e60 Refactor editor workflow and update UI state handling 2026-04-30 13:37:52 +05:30
sudhir 411ae2e905 Refine 2D door swing rendering 2026-04-29 17:51:58 +05:30
sudhir e761084635 Normalize root scene nodes and fix level duplication 2026-04-29 12:53:40 +05:30
Sudhir YadavandGitHub 9ff657419c Merge branch 'main' into feat/upgrade-and-bug-fix 2026-04-29 10:49:11 +05:30
sudhir e688792c34 Refactor first-person and spawn selection handling 2026-04-29 10:35:34 +05:30