100 Commits
Author SHA1 Message Date
Aymeric RabotandGitHub 28ab27f5ec Merge pull request #539 from pascalorg/feat/realtime-collaboration-sfx
Harden remote scene commit convergence
2026-07-24 00:33:14 +02:00
Aymeric RabotandGitHub 34b601bb79 Merge pull request #523 from pascalorg/feat/realtime-collaboration-sfx
Improve realtime collaboration feedback and previews
2026-07-21 01:44:49 +02:00
Aymeric RabotandGitHub 5c7f58f295 Merge pull request #515 from pascalorg/fix/preload-tool-inspector
Preload the selected tool inspector
2026-07-19 17:40:32 +02:00
Aymeric RabotandGitHub c0a5db935e Merge pull request #514 from pascalorg/feat/host-integration-primitives
Expose generic host integration primitives
2026-07-19 17:19:11 +02:00
Aymeric RabotandGitHub 7d6879c416 Merge pull request #487 from pascalorg/fix/compass-follow-hidden-align-north
fix(editor): compass needle follows align-north in 3D-only view
2026-07-10 10:22:26 +02:00
Aymeric RabotandGitHub 5831b7b234 Merge pull request #479 from pascalorg/feat/smart-unit-suffix
editor: smart unit suffix — dim on focus, yield to explicit units
2026-07-09 16:20:44 +02:00
Aymeric RabotandGitHub 2d4e7be709 Merge pull request #478 from pascalorg/fix/compass-sync
editor: compass sync + fast align-to-north
2026-07-09 16:20:40 +02:00
Aymeric RabotandGitHub a477c4ade3 Merge pull request #477 from pascalorg/fix/unit-labels-lingo-0.2
fix(editor): area readouts + generated names follow the unit toggle; bump lingo to 0.2.0
2026-07-08 22:51:49 +02:00
Aymeric RabotandClaude Opus 4.8 8476a991f4 chore(deps): bump @pascal-app/lingo to 0.2.0
0.2.0 is API-compatible with our usage (parseQuantity, quantity, Kind);
it adds i18n/locale entrypoints and does not change the symbols we import.
Verified: @pascal-app/editor and @pascal-app/mcp typecheck, and all 31
measurement tests pass, including the AMBIGUOUS_NUMBER escalate guard.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 22:34:31 +02:00
Aymeric RabotandClaude Opus 4.8 682c023be1 fix(editor): area readouts and generated names follow the unit toggle
The metric/imperial preference was already honored by every length input,
but two area surfaces were still hardcoded to m²:

- the "Load build" import dialog's Floor area stat
- the auto-generated default names for zones, slabs, and ceilings
  (e.g. "Zone (12.3m²)"), which are live display fallbacks

Both now convert value + label to the active unit. Adds shared
squareMetersToAreaUnit / getAreaUnitLabel / formatAreaLabel helpers to
lib/measurements (with tests) and routes the site-panel Area readout
through them, replacing an inline 10.7639 magic constant.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 22:34:30 +02:00
Aymeric RabotandGitHub 2cfce3f6b5 Merge pull request #472 from pascalorg/feat/lingo-natural-inputs
feat: natural-language measurement inputs (UI + MCP tools) via @pascal-app/lingo
2026-07-08 17:08:43 +02:00
Aymeric RabotandClaude Opus 4.8 5ffde5f66a fix(editor): site-panel property-line coords + area/perimeter follow the unit toggle
The property-line vertex X/Z inputs and the Area/Perimeter readout were
hardcoded to meters. Convert them to feet / ft² when the viewer preference is
imperial, matching every other length input.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 17:00:47 +02:00
Aymeric RabotandClaude Opus 4.8 69813a6e62 feat(editor): honor the metric/imperial toggle in every length input
SliderControl (which drives the auto-inspector's ~144 fields and most custom
panels) previously ignored the viewer unit preference and always rendered raw
meters with a static "m" label, while MetricControl converted to feet — so
toggling imperial changed some length inputs and not others. Extract the
conversion into a shared `useLinearDisplay(unit, precision)` hook and route
BOTH controls through it, so every `unit="m"` length field displays and edits
in feet when imperial and meters when metric — consistently.

Values are always stored in meters; only display, the text field, and drag/
wheel/arrow deltas move to the display unit. For metric and non-length units
(°, %, in, …) the conversions are the identity, so those paths are unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 17:00:47 +02:00
Aymeric RabotandClaude Opus 4.8 af1fe6a34c chore(deps): add @pascal-app/lingo to the lockfile; note duplicated helper
Records @pascal-app/lingo@^0.1.0 in bun.lock (added to @pascal-app/editor and
@pascal-app/mcp), so `bun install --frozen-lockfile` in CI resolves it. Also
documents that measurement.ts is intentionally duplicated with the AI-chat copy
across the submodule boundary and must be kept in sync.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 13:32:36 +02:00
Aymeric RabotandClaude Opus 4.8 3273aac551 fix(mcp): restore >0 validation and reject ambiguous numbers in measurement()
Adversarial-review follow-ups to the lingo measurement() field:
- Add a `positive` option (strict > 0) and use it for the non-zero dimension
  params. Swapping z.number().positive() → measurement(..,{min:0}) had started
  admitting 0 (the core node schemas have no positivity backstop), so a zero-size
  wall/opening/roof could be created. Inclusive-0 fields (overhang, sill height,
  knee-wall height, opening offset, roof pitch) keep min:0.
- Escalate AMBIGUOUS_NUMBER to error so "1,234" fails instead of silently reading
  as 1234 — a 1000x hazard for European decimals. Matches lingo's own /ai fields.
- roofLevelElevation reverted to z.number() (it's a level ordinal, not meters);
  radians fields now advertise radian-appropriate examples.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 13:09:59 +02:00
Aymeric RabotandClaude Opus 4.8 f66dcd438b feat(mcp): natural-language measurements for tool inputs via @pascal-app/lingo
Measurement/angle parameters on the scene tools now accept a bare number OR a
natural-language string ("6 in", "180cm", "45°", "1.57rad"), canonicalized to
the unit the handler already expects (meters for length, radians/degrees for
angles) with min/max bounds and model-readable errors. Makes LLM tool calls
safer — "6 in" no longer has to be pre-converted to 0.1524, and a bad value is
rejected with a message the model can self-correct from.

A shared `measurement(kind, unit)` zod field wraps lingo's parseQuantity as a
`number | string` union+transform; numbers pass through unchanged (backward
compatible), so no handler changes were needed. Covers create_wall, cut_opening,
place_item, create_level, create_story_shell, create_roof,
create_stair_between_levels, create_room, add_door, add_window, photo_to_scene.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 12:51:08 +02:00
Aymeric RabotandClaude Opus 4.8 a5963560b1 feat(editor): natural-language measurement inputs via @pascal-app/lingo
Type any unit into SliderControl / MetricControl fields — "6ft", "180cm",
"1m80", "5'11\"", "72in", "45°", "1.57rad" — and it canonicalizes to the
unit the field already stores (meters / degrees / radians / inches),
independent of the metric/imperial display toggle. A live "= 1.83 m" hint
previews the parsed value while typing.

Only the typed-text commit path changes: drag-scrub, wheel, and arrow-key
editing are untouched, and any unit the adapter doesn't recognise (%, unitless,
rad/s) falls back to Number.parseFloat, so nothing regresses. The shared
lib/measurement-parser.ts maps each field's `unit` prop to a lingo kind +
canonical unit, covering the auto-inspector and every custom panel at once.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 12:04:14 +02:00
Aymeric RabotandGitHub 460b924577 Merge pull request #442 from pascalorg/chore/typescript-7-native
chore(ts7): adopt the TypeScript 7 native compiler (tsgo)
2026-06-25 14:28:08 -04:00
Aymeric RabotandClaude Opus 4.8 1b4c656901 chore(ts7): adopt the TypeScript 7 native compiler (tsgo)
Make the editor packages compatible with, and benefit from, the native Go
compiler (TypeScript 7 / tsgo) while keeping the npm publish path on stable tsc.

- Add @typescript/native-preview (pinned 7.0.0-dev.20260624.1). tsgo coexists
  with typescript@6, which Next typegen and the IDE plugin still need until the
  TS 7.1 programmatic API ships.
- Fix two react-three-fiber JSX augmentations the native checker rejects but
  tsc tolerated:
  - viewer: map only LineBasicNodeMaterial (the one webgpu node material used as
    a JSX tag) instead of the whole three/webgpu namespace (TS2320/TS2590).
  - plane-box-select-tool: drop the redundant `IntrinsicElements extends
    ThreeElements` block — it duplicated R3F's global augmentation and, by
    referencing @react-three/fiber's ThreeElements directly, hit a bun peer-dep
    variant-directory duplicate under tsgo (TS2320). r3f.d.ts already covers
    those JSX intrinsics. Types-only — no runtime change.
- check-types -> tsgo --noEmit (editor, @repo/ui, editor app, ifc-converter app)
- emit-package dev watch -> tsgo --build --watch
- build/publish stay tsc --build (prepublishOnly + release.yml unchanged;
  emitted .d.ts is byte-identical to tsc output)
- bump next 16.2.6 -> 16.2.9

tsc remains the source of truth and fallback. Published artifacts unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 13:37:58 -04:00
Aymeric RabotandGitHub 2d053c4317 Merge pull request #408 from pascalorg/feat/opening-proximity-guides
Move handle + proximity / sill / equal-spacing guides for wall openings
2026-06-15 13:01:32 -04:00
Aymeric RabotandGitHub 2d2dba5dba Merge pull request #395 from pascalorg/feat/editor-ux-rendering-placement
editor: roof wall openings — doors/windows/items on roof-segment wall faces
2026-06-10 14:39:37 -04:00
Aymeric RabotandClaude Fable 5 ee7bb39605 style: biome format/import-order for refactored tool files
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 14:36:19 -04:00
Aymeric RabotandClaude Fable 5 aa3b0ef758 refactor: release-review cleanup for roof wall openings
Dual review pass (Claude multi-angle + Codex release-quality). One
correctness fix and the agreed do-now cleanups:

- fix: clone-scene-graph remaps roofSegmentId like wallId in both
  clone paths — duplicated scenes/levels kept pointing roof-hosted
  children at the original segments.
- extract the settled, stateless roof target/cursor math shared by the
  four door/window tools into shared/roof-wall-opening-placement.ts
  (resolveRoofWallOpeningTarget + getRoofWallOpeningCursorPose +
  worldToSelectedBuildingLocal); tools keep the stateful lifecycle
  (drafts, undo/temporal, commit field lists). −199 net lines.
- rename host-generic state: currentWallId→currentHostId,
  markWallDirty→markHostDirty (they hold segment ids too); capability
  cascadesViaHostSegment→dirtyHandledByOwnSystem (behavior-facing,
  before the public API hardens).
- drop getRoofAccessoryKinds from core's public API — its only caller
  was the standalone Build tab, which now enumerates the registry
  inline with its app-specific filter.
- window move-tool uses the shared stripPlacementMetadataFlags; stale
  "segment-local" comment fixed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 14:33:13 -04:00
Aymeric Rabot b8dfa90762 Merge remote-tracking branch 'origin/main' into feat/editor-ux-rendering-placement 2026-06-10 14:21:35 -04:00
Aymeric Rabot 07d01b18e7 feat(editor): action menu tracks live geometry changes
Floating action menu re-derives its anchor when the selected node's
geometry rebuilds (position/index attribute versions as the key) and
accounts for roof height via getActiveRoofHeight + effective nodes.
2026-06-10 14:21:24 -04:00
Aymeric RabotandClaude Fable 5 7879b83df3 feat: face-frame hosting for roof wall children + items on roof walls
Wall-mounted items join doors/windows on roof-segment wall faces, and
the storage model moves to FACE-LOCAL coordinates so hosted children
track segment edits live.

- Children store roofFace + position [u, v, z-from-mid-plane] with
  rotation 0 in-frame — the exact wall-child conventions (the wall
  volume's mid-plane lands on the nominal footprint). A shared
  <RoofFaceHostFrame> derives segment pose + face frame from the
  live-override-merged segment: children follow resize handle drags in
  real time and never jump on commit. No re-anchor cascade needed —
  position is authoritative, the frame is derived. migrateNodes
  converts branch-era segment-local data.
- Items: roofWallStrategy + roof:* handlers in the placement
  coordinator (surface 'roof-wall'), Shift free-place normalized with
  walls, ItemSystem wall-side push extended to segment hosts, correct
  2D plan glyphs via face→segment→roof pose composition. The roof
  hit resolver + overlap guard moved to @pascal-app/editor (the
  coordinator lives there; nodes already depends on editor).
- Cuts: subtractAccessoryCuts extracted and applied in BOTH the
  merged-shell and per-segment CSG paths (full edit mode / painted
  segments used to lose every hole), built from the CURRENT host
  geometry and live-effective children so holes follow segment and
  opening drags.
- Handle rig: the grandparent portal now maps the node's world pose
  into the portal frame instead of composing parent+node registry
  poses — correct for any nesting (the face-frame group broke the
  old assumption), identical for walls.
- Host-field hygiene: useDraftNode.commit/adopt and the window panel
  duplicate forward roofSegmentId/roofFace/wallId; every roof↔wall
  re-anchor clears and every revert restores them.

Codex-reviewed (design consultation, adversarial rounds on the
replaced cascade and on this refactor); frame conventions locked by
unit tests. Record: private-editor plans/editor-roof-wall-openings.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 14:21:14 -04:00
Aymeric Rabot 5fd9be05df Fix spawn floorplan move handle 2026-06-10 14:11:50 -04:00
Aymeric Rabot 3a1ba56246 Polish editor interaction behavior 2026-06-10 11:28:12 -04:00
Aymeric RabotandClaude Fable 5 bdfee058bd feat: doors and windows on roof-segment wall faces
Openings now host on the walls a roof segment generates — the base
walls under the roof and the coplanar gable/shed/gambrel end faces, so
a window can sit in a gable pediment.

- core: roof-segment-walls.ts models the four vertical faces as 2D
  frames (u along face, v height) with convex profile polygons that
  mirror the wall volume getRoofSegmentBrushes builds; rect-in-profile
  clamping and anchored resize limits via half-plane algebra.
- schemas: optional roofSegmentId on door/window; position is the
  segment-local wall mid-plane center, rotation[1] the face yaw.
- cut: reuses capabilities.roofAccessory.buildCut; new cutScope: 'wall'
  subtracts from the wall brush only. cascadesViaHostSegment keeps the
  roof-merge loop from consuming door/window dirty marks (their own
  systems cascade via parentId).
- tools: roof:* handlers in door/window tool + move-tool (the Build-tab
  preset path), with roofSegmentId cleared/restored across every
  roof<->wall re-anchor and revert; shared hit resolver normalizes
  normals through world space (merged mesh vs painted segment frames).
- fix: RoofSystem no longer rebuilds per-segment CSG in accessory-reveal
  mode — the uncut rebuild used to draw over the merged shell's fresh
  opening until deselect.
- fix: the walkthrough collider world now prunes by renderer-effective
  visibility; stale uncut segment CSG inside the hidden segments-wrapper
  blocked the player at openings the merged shell had cut through.

Known gap: painted segments render per-segment CSG without accessory
cuts (pre-existing, also affects skylight/dormer). Twice Codex-reviewed;
details in private-editor plans/editor-roof-wall-openings.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 00:39:13 -04:00
Aymeric RabotandClaude Fable 5 1487328ec7 fix: never drop walkthrough player below the site ground plane
The site ground collider was sized to the scene footprint with a 30 m
minimum — exactly the default site polygon, so one step past the site
boundary left nothing under the character controller and the player
fell into the void. The ground collider now extends 2 km (still a
single BVH box) so the ground plane acts unbounded, and a respawn net
in the first-person frame loop recovers the controller if it ever ends
up below every collider (e.g. scenes with no site node), preferring the
live spawn node over the mount-time start position.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 00:14:38 -04:00
Aymeric RabotandClaude Fable 5 478f0910f7 feat(editor): roof features in standalone Build tab + thumbnail flag fix
- registry: getRoofAccessoryKinds() enumerates kinds declaring the
  roofAccessory capability, in deterministic builtin-list order (mirrors
  getSelectableKinds); exported from the registry barrel.
- apps/editor build-tab: a "Features" group under the Roof tile, discovered
  from the registry (no DB) and activating each kind's roof-attach tool —
  parity with the community editor's roof features.
- site-boundary-editor: hide the flag handle group around thumbnail captures
  (they render on SCENE_LAYER so the thumbnail camera can't layer-filter them),
  matching handle-arrow.tsx — keeps flags out of preset/snapshot thumbnails.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-09 19:55:53 -04:00
Aymeric Rabot eb00f9f477 fix: harden editor scene loading 2026-06-09 19:54:42 -04:00
Aymeric Rabot e81dc63b28 feat: sync surface polygon editing 2026-06-09 19:54:35 -04:00
Aymeric RabotandGitHub c93778c170 Merge pull request #389 from pascalorg/chore/deps-2026-06
chore(deps): June 2026 refresh — next 16.2.7 (security), TS 6.0.3
2026-06-09 19:02:49 -04:00
Aymeric Rabot 92078741cd feat: add ceiling wall snap feedback 2026-06-09 17:50:01 -04:00
Aymeric Rabot f3c1407cae fix: sync ceiling handles during polygon edits 2026-06-09 15:58:43 -04:00
Aymeric Rabot 265acdb2be fix: improve ceiling handle feedback and WebGPU placeholders 2026-06-09 14:49:42 -04:00
Aymeric Rabot 8ce26154d9 fix: respect scene depth for site and ceiling handles 2026-06-09 13:17:04 -04:00
Aymeric RabotandGitHub 5d29363704 feat: add persistent site boundary handles
Add persistent site boundary handles
2026-06-08 17:50:23 -04:00
Aymeric Rabot b33059ef81 feat: add persistent site boundary handles 2026-06-08 17:42:20 -04:00
Aymeric RabotandGitHub 7796837081 Merge pull request #384 from pascalorg/codex/remove-action-bar-dead-controls
Remove unused action bar controls
2026-06-08 09:15:23 -04:00
Aymeric Rabot d2137ddf94 Remove unused action bar controls 2026-06-08 09:12:35 -04:00
Aymeric RabotandGitHub 14acf50491 Merge pull request #383 from pascalorg/fix/relative-move-grab-offset
Fix relative move and fresh placement commits
2026-06-08 02:16:49 -04:00
Aymeric Rabot 73cd6e8614 fix(editor): strip placement metadata on commit 2026-06-08 02:12:01 -04:00
Aymeric Rabot bd9e97e224 Stabilize split view navigation sync 2026-06-08 01:56:45 -04:00
Aymeric Rabot 4445c60532 Fix active floorplan rotation feedback 2026-06-08 01:14:12 -04:00
Aymeric Rabot f7789a5c7a Fix split view rotation sync direction 2026-06-08 01:10:04 -04:00
Aymeric Rabot 8dc602caa9 Improve editor manipulation flows 2026-06-08 01:07:53 -04:00
Aymeric RabotandClaude Opus 4.8 ab271df9b6 fix(editor): keep walkthrough on ground, pass through ceilings
Two gaps in the first-person walkthrough collider world:

- The visible default ground is the site node's mesh, but `site` is a
  `site`-category node and excluded from the generic collider sweep. The
  per-level fallback floor only fires for a level without a slab, so a
  spawn on the bare ground (no slab) had no floor and fell through. Add a
  dedicated site-ground collider derived from node data (not the rendered
  mesh, so it's immune to geometry-mount timing) covering the scene
  footprint at the site's ground plane.

- Ceilings are `structure`-category and were swept in as colliders, so the
  player was held up as if standing on a floor slab. Exclude nodes whose
  registry `surfaceRole` is 'ceiling' so the player passes through them
  (they're a transparent mount surface for lights/fans), while walls,
  slabs and stairs keep colliding.

Adds tests for both behaviors.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 01:05:30 -04:00
Aymeric Rabot 6b8dc33b62 fix: restore walkthrough collisions and spawn controls 2026-06-07 23:58:49 -04:00
Aymeric Rabot be0f491bbd Fix relative move drag offsets 2026-06-07 18:18:46 -04:00
Aymeric RabotandGitHub 9b9bb0902d Merge pull request #380 from pascalorg/bug-fixes-and-improvements
Fix stair openings and editor placement polish
2026-06-07 01:18:07 -04:00
Aymeric Rabot 03f57b1f4f Fix stair opening previews and slab cutouts 2026-06-07 00:46:51 -04:00
Aymeric Rabot 21b79c0d62 Snap roof segment resize handles to grid 2026-06-07 00:44:58 -04:00
Aymeric Rabot fe0a1056f2 Separate screen and plane box selection 2026-06-07 00:43:34 -04:00
Aymeric Rabot 2b3d3d06b5 Respect unit preference in alignment guides 2026-06-07 00:27:08 -04:00
Aymeric Rabot f84910848b Improve roof node editing 2026-06-07 00:24:15 -04:00
Aymeric Rabot b7d6038348 Add 3D box selection 2026-06-07 00:24:02 -04:00
Aymeric Rabot 3750679d48 Add wall placement axis angle guides 2026-06-07 00:05:36 -04:00
Aymeric Rabot 16e09d778d Fix auto ceiling height sync 2026-06-06 23:34:33 -04:00
Aymeric RabotandGitHub f093cbdf3c Merge pull request #264 from AdrianPerez3/feat/mcp-server 2026-04-27 14:22:45 -07:00
Aymeric Rabot 0711cad660 Merge remote-tracking branch 'origin/main' into feat/mcp-server 2026-04-27 17:22:14 -04:00
Aymeric Rabot 8dfd1a9429 fix(mcp): add shared operations and secure scene APIs 2026-04-27 17:10:25 -04:00
Aymeric Rabot 058ee747c9 fix(mcp): distinguish roof support levels from stories 2026-04-27 16:45:27 -04:00
Aymeric Rabot 3d5c87a651 feat(mcp): add guided construction workflows 2026-04-27 14:31:04 -04:00
Aymeric Rabot b3d1f663f6 fix(mcp): use local sqlite scene storage 2026-04-24 13:32:04 -07:00
Aymeric RabotandClaude Opus 4.6 e2cde339ae fix: add @types/node to viewer devDependencies for process.env typing
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 15:29:12 -07:00
Aymeric RabotandClaude Opus 4.6 6bbb1db334 chore: update lockfile
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 15:14:26 -07:00
Aymeric RabotandClaude Opus 4.6 10449c5cc5 fix: replace npm version with jq to avoid peer dep conflicts in CI
npm version triggers npm install which fails on peer dependency
resolution in workspace monorepos. Use jq for version bumping instead.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 23:20:37 -04:00
Aymeric Rabot bc59752edb Bump devDependencies and update lockfile
Bump devDependencies in package.json: @biomejs/biome ^2.4.4→^2.4.6, turbo ^2.8.12→^2.8.15, ultracite ^7.2.4→^7.2.5. Regenerate bun.lock to reflect these updates and related transitive changes (e.g. @clack, glob, path-scurry/minipass, minimatch).
2026-03-10 15:02:55 -04:00
Aymeric RabotandGitHub ae801428b1 Merge pull request #137 from pascalorg/feat/editor-preview
Add editor preview mode
2026-03-06 23:44:30 -05:00
Aymeric RabotandClaude Opus 4.6 d3e17cac04 Add editor preview mode for in-place viewer experience
Adds a Preview button next to Radio Pascal that switches the editor
into a viewer-like experience without leaving the page. The preview
mode swaps in the viewer's selection manager (hierarchical drill-down),
zone system, camera controls (left-click pan, auto-navigate), and
interactive item system while hiding editor-only UI (tools, panels,
sidebar, grid). Back arrow in the viewer overlay returns to the editor.

Also widens the default sidebar from 288px to 432px for better
project title visibility.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-06 23:43:10 -05:00
Aymeric RabotandClaude Opus 4.6 de6bfd8c00 Add react-scan and react-grab dev tools (development only)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-06 18:52:01 -05:00
Aymeric Rabot 0edbc65e8d Update polygon-editor.tsx 2026-03-03 16:22:08 -05:00
Aymeric RabotandClaude Opus 4.6 48979ec014 fix raycaster layers, polygon drag, slider undo, and grid events
- Enable EDITOR_LAYER on R3F raycaster for proper hit detection
- Fix polygon editor drag using refs and direct position passing
- Handle pointercancel events and fix pointerId access in polygon editor
- Fix slider undo by reverting to start value before resuming temporal state
- Allow grid:move during camera drag so polygon editor works while panning
- Bump better-auth to ^1.5.2 and turbo to ^2.8.12
- Remove explicit return type on createAuth for better inference

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 14:41:19 -05:00
Aymeric Rabot 2ddf10f3f0 Play SFX when placing doors and windows
Add audio feedback for item placement by importing sfxEmitter and emitting 'sfx:item-place' in DoorTool and WindowTool. This change triggers a placement sound when a door or window node is created, improving UX by confirming successful placement.
2026-02-28 01:39:35 -05:00
Aymeric Rabot 7dde5dc578 Update ground-occluder.tsx 2026-02-28 01:34:41 -05:00
Aymeric Rabot 5077011c26 Initialize WebGPU renderer before post-processing
Make the gl prop synchronous and move/await renderer initialization inside the post-processing component. index.tsx: remove async gl factory and the await renderer.init() so renderer is created synchronously. post-processing.tsx: add isInitialized state, an async initRenderer that calls renderer.init(), and guard post-processing setup until init completes (with mounted cleanup and updated effect deps). This ensures the WebGPU renderer is fully initialized before building the render pipeline and avoids using an async gl factory.
2026-02-27 14:28:31 -05:00
Aymeric RabotandClaude Opus 4.6 64de2a8e63 feat(editor): direct-to-Supabase uploads with progress for large scans
Upload files directly to Supabase Storage via signed URLs, bypassing
the Next.js 100MB body size limit. Supports scans up to 200MB with
real-time progress tracking that persists across sidebar panel switches.

- Add Zustand upload store for persistent upload state
- Add createAssetUploadUrl/confirmAssetUpload server actions
- Add XHR-based upload orchestrator with progress events
- Scene node creation works even if sidebar panel unmounts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 14:19:06 -05:00
Aymeric RabotandClaude Opus 4.6 77f41ba8b7 fix(db): add missing drizzle metadata for storage buckets migration
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 13:15:21 -05:00
Aymeric Rabot 18307761b5 Revert "chore(editor): remove instrumentation.ts bucket creation logic"
This reverts commit da3168ccb8.
2026-02-27 12:58:18 -05:00
Aymeric Rabot da3168ccb8 chore(editor): remove instrumentation.ts bucket creation logic
Made-with: Cursor
2026-02-27 12:43:09 -05:00
Aymeric Rabot efa97444f6 fix(db): create missing storage buckets in migration
Made-with: Cursor
2026-02-27 12:39:59 -05:00
Aymeric RabotandClaude Opus 4.6 31c09bacdd Fix scan/guide visibility with per-project preferences
- Store showScans/showGuides preferences per project so toggling
  persists when switching between projects
- Apply showGuides/showScans directly on guide and scan renderer groups
- Set projectId in both editor and viewer pages on mount

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 01:38:10 -05:00
Aymeric RabotandClaude Opus 4.6 d0e0fe7e1e UX polish round 4: action button component, keyboard shortcuts dialog, and build fixes
- Add reusable ActionButton component with tooltip and shortcut display
- Add keyboard shortcuts dialog in settings panel
- Fix ButtonProps import error (derive type from Button component)
- Fix AnyNodeId type mismatch in tree-node-actions visibility toggle
- Various UI refinements across action menu, sidebar, and editor

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 01:19:13 -05:00
Aymeric Rabot 659c01052e Update .gitignore 2026-02-19 15:43:44 -05:00
Aymeric RabotandClaude Opus 4.6 867681e1da feat: add env.mjs for centralized env validation (t3-env)
Validates all required env vars at runtime with zod schemas.
Skips validation during build via SKIP_ENV_VALIDATION flag.
Replaces scattered process.env access with typed env imports.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-19 01:47:36 -05:00
Aymeric RabotandClaude Opus 4.6 4c0d0885a3 fix: declare env vars in turbo.json so Vercel build receives them
Turbo was stripping env vars during build on Vercel. Added all required
vars to turbo.json build task. Also hardened Supabase and BetterAuth
init with fallback placeholders for build-time safety.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-19 01:45:09 -05:00
Aymeric RabotandClaude Opus 4.6 48397917a9 feat: auto-create avatars storage bucket on server startup
Uses Next.js instrumentation.ts to ensure the Supabase "avatars"
bucket exists on first boot — no manual setup needed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-19 01:41:48 -05:00
Aymeric RabotandClaude Opus 4.6 23a71c376f feat: avatar upload, connected accounts, round navbar avatar, Vercel analytics
- Avatar upload to Supabase Storage with pencil overlay in settings
- Show username initials as avatar fallback (instead of name initials)
- Round avatar in navbar (rounded-full with natural shadow)
- Connected Accounts section in settings showing Google status
- Connect Google directly from settings without signing out
- Add Vercel Analytics, Speed Insights, and Toolbar
- Update page title to "Pascal Editor"

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-19 01:40:17 -05:00
Aymeric RabotandClaude Opus 4.6 b53cb984eb chore: add missing feedback migration to match remote
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-19 01:32:02 -05:00
Aymeric RabotandClaude Opus 4.6 6f7613818b feat: account linking for magic link + Google, last login method hint
- Move account linking config out of Google conditional so it's always active
- Trust both 'google' and 'email' providers for automatic account linking
- Add lastLoginMethod plugin to track how users last signed in
- Show "Last signed in with Google/email link" hint in sign-in dialog

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-19 01:29:30 -05:00
Aymeric RabotandClaude Opus 4.6 a0ac904dfc fix: lazy-init Supabase and Drizzle clients for build compatibility
Defer database client creation until first use via Proxy so Next.js
builds succeed without POSTGRES_URL and SUPABASE_URL env vars present.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-19 01:21:41 -05:00
Aymeric Rabot d6e6954877 Update .gitignore 2026-02-19 01:19:52 -05:00
Aymeric RabotandClaude Opus 4.6 62dde6ef5a feat: add Google OAuth, user profiles, community hub improvements
- Add Google OAuth sign-in alongside magic link authentication
- Username onboarding: require username selection after first sign-in
- Public profile pages at /u/[username] with social links (GitHub, X)
- Settings page for managing username and social links
- Viewer header: unified floating card with project name, @username, breadcrumb
- Guest CTA on viewer page prompting sign-in
- Show owner avatar + username on community project cards
- Redesigned project cards (larger preview, avatar + stats row below)
- Consistent navbar across hub and profile pages with GitHub link
- Footer with links to GitHub repo and npm packages
- Borderless design with natural shadows throughout
- Apple corner smoothing (squircle) progressive enhancement
- cursor:pointer globally on buttons and links
- DB migrations: username, github_url, x_url columns on auth_users
- Root-level db:generate/migrate/push/studio scripts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-19 01:04:37 -05:00
Aymeric Rabot 40c1c9f651 Update .gitignore 2026-02-18 15:44:45 -05:00
Aymeric Rabot e2ecbf48da Create drizzle.config.ts 2026-02-18 01:51:17 -05:00
Aymeric RabotandGitHub 8f70e8b53e Merge pull request #99 from pascalorg/feat/refactor-supabase-setup
Refactor Supabase setup and fix local dev ports
2026-02-18 01:49:05 -05:00
Aymeric RabotandClaude Opus 4.6 aa27e0dd7a refactor: move supabase config to repo root, fix port and env setup
- Move supabase/ from packages/db/ to repo root for simpler CLI usage
- Use custom ports (553xx) to avoid conflicts with other local Supabase instances
- Add --env-mode=loose to turbo dev so root .env vars reach Next.js
- Remove hardcoded --port 3000 from next dev (reads PORT env var instead)
- Add .env.example with Supabase env var placeholders
- Add supabase local state dirs to .gitignore

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-18 01:48:53 -05:00
Aymeric RabotandClaude Opus 4.6 7a871be792 Add slab polygon editing with drag, add, and delete vertices
Reuse the shared PolygonEditor for slab boundary editing with levelY
and surfaceHeight support. Handles render as 3D cylinders that adapt
to slab thickness. Prevent deselection after drag by suppressing
grid:click propagation, and reset preview state on undo/redo.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 14:49:53 -05:00