58 Commits

Author SHA1 Message Date
Aymeric Rabot
8dfd1a9429 fix(mcp): add shared operations and secure scene APIs 2026-04-27 17:10:25 -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
Adrian Perez
8757de0c36 fix(mcp,editor): close PUT-route URL bypass + vision-tool SSRF (Phase 10 A2)
Pre-push audit agent A2 flagged two HIGH-severity security issues that
would have shipped in the PR had we not checked:

1. PUT /api/scenes/[id] URL-validation bypass. Phase 8 P4 fixed
   the POST /api/scenes route by replacing a loose z.unknown() graph
   schema with AnyNode superRefine. The fix never made it to the PUT
   handler - an attacker could resubmit the same javascript:/file:///
   payloads via PUT. Fixed by extracting the tight validator into
   apps/editor/lib/graph-schema.ts and sharing it across both routes.

2. SSRF in photo_to_scene / analyze_floorplan_image /
   analyze_room_photo. All three tools called raw fetch(image) on
   user-supplied URLs with no validation - a direct
   http://169.254.169.254/latest/meta-data/ exfil primitive on any
   cloud host. Added packages/mcp/src/lib/safe-fetch.ts that:
   - Blocks loopback (127.0.0.0/8, ::1)
   - Blocks link-local incl. cloud metadata (169.254.0.0/16)
   - Blocks private ranges (10/8, 172.16/12, 192.168/16, fc00::/7)
   - Blocks .local/.internal/.corp hostnames + localhost variants
   - Blocks v4-mapped IPv6 loopback (::ffff:127.0.0.1)
   - Manual redirects (max 3), revalidating the allowlist per hop
   - 20 MB response-size cap (streamed, enforced per-chunk)
   - 10s timeout
   - Optional PASCAL_ALLOWED_ASSET_ORIGINS env allowlist

Tests: 8 new SSRF guard tests, all vision tests still pass, full
suite 302/302.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 20:59:26 +02:00
Adrian Perez
0b84e7b7b1 fix(mcp,editor): close URL-validation bypasses surfaced by Phase 8 P4
Phase 8 parallel validation flagged two boundaries where malicious URLs
(javascript:, file:, external http:, data:text/html, ...) could be
persisted despite the AssetUrl allowlist added in Phase 7 A7:

1. `save_scene({ includeCurrentScene: false, graph })` — the graph arg
   was treated as opaque (`z.record(z.string(), z.unknown())`) and
   written to the store without re-running AnyNode.safeParse.

2. `POST /api/scenes { graph }` in the editor API — same issue; the
   Zod `graphSchema` accepted anything object-shaped.

Fixes:
- `save-scene.ts`: when `includeCurrentScene === false`, iterate every
  node and run `AnyNode.safeParse`; collect issues and throw
  `McpError(InvalidParams, 'graph_invalid', { errors })` on any
  failure.
- `app/api/scenes/route.ts`: replace `graphSchema` with a structured
  `z.object({ nodes, rootNodeIds, collections? })` + `superRefine`
  that runs `AnyNode.safeParse` on every node. Invalid → 400 with
  detailed issue paths.

Tests:
- Added `save_scene` regression test for the P4 attack
  (item.asset.src = 'javascript:alert(1)') — expected error.
- Fixed the existing `includeCurrentScene=false` test to use a
  schema-compliant site node id (the prior `id: 'root'` now fails
  the AnyNode parse, which is the desired strict behaviour).
- Full suite: 294 pass / 0 fail.

Also adds Phase 8 test-reports/phase8/** (10 agents, ~15 scripts +
markdown reports) documenting the validation run, plus minor biome
cleanups to the Phase 5/7 test artefacts (removed stale
`// biome-ignore` suppression comments that now resolve to the
already-off `noConsole` rule).

Phase 8 result summary (10 parallel agents, stdio MCP transport with
isolated data dirs):
- P1 templates: 18/18 PASS
- P2 variants: 6/7 mutations + determinism + save + combined + error
- P3 locking: 12/12 PASS (MCP + editor HTTP If-Match)
- P4 URL hardening: fixed 2 bypasses (see above)
- P5 photo-to-scene: 6/6 PASS
- P6 Casa del Sol via save_scene: 13/13 PASS
- P7 editor HTTP API: 18/18 PASS
- P8 concurrency: 4/5 PASS, flagged 2 real filesystem-store races
  (expectedVersion CAS gap + .index.json drift under parallel writes)
- P9 edge cases: 13/13 PASS (size cap, slug safety, bad inputs)
- P10 full sweep: 37/37 PASS (30 tools + 4 resources + 3 prompts)

Known follow-ups:
- FilesystemSceneStore needs a proper lockfile / atomic CAS to fix
  the P8 concurrency bugs (low priority: single-writer MCP is the
  typical case).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 20:26:26 +02:00
Adrian Perez
e8d0b13ff5 feat(mcp,editor): Option A+B storage + 10 agent deliverables (Phase 7)
Ships the combined filesystem/Supabase storage adapter + MCP scene
lifecycle tools + Next.js API routes + editor /scene/[id] route, so
an MCP save is directly openable at /scene/<id> without any
injection hack. End-to-end verified: 10/10 e2e steps pass.

Storage (A1/A2/A3):
- SceneStore interface + error classes + slug helpers
- FilesystemSceneStore at $PASCAL_DATA_DIR (defaults XDG/~/.pascal)
  with atomic writes, .index sidecar, optimistic locking
- SupabaseSceneStore with scenes + scene_revisions tables, RLS
  migration SQL, mock-backed unit tests
- createSceneStore(env) auto-selects based on SUPABASE_URL +
  SUPABASE_SERVICE_ROLE_KEY

MCP tools (A4, A8, A9, A10):
- save_scene / load_scene / list_scenes / delete_scene / rename_scene
- list_templates / create_from_template (3 seed templates:
  empty-studio, two-bedroom, garden-house)
- generate_variants (7 mutation kinds, seeded RNG, save=true|false)
- photo_to_scene (vision sampling → scene graph → save)

Editor (A5, A6):
- /api/scenes + /api/scenes/[id] with RFC 7232 If-Match locking
- /scene/[id] and /scenes route pages with save button, SceneLoader
- Removed the window.__pascalScene dev injection hack

Security + UX edges (A7, A8):
- AssetUrl Zod validator: asset:// blob: data:image/ /path https:
  (http://localhost for dev) + PASCAL_ALLOWED_ASSET_ORIGINS env
  allowlist. Hardens scan.url, guide.url, item.asset.src,
  material.texture.url, MaterialMaps.*Map
- Auto-frame camera on empty→non-empty scene transition
  (camera-controls:fit-scene emitter event)

Shared utilities:
- rehydrateSiteChildren() extracted to packages/mcp/src/lib/ and
  used by both create-from-template and generate-variants to work
  around the SiteNode.children-as-objects vs. ids inconsistency
  (CROSS_CUTTING §2)
- Storage + MCP subpath exports added to packages/mcp/package.json
  (CROSS_CUTTING §4)

Tests: 293 pass / 0 fail across 40 files (was 142 pre-Phase-7).
Biome: clean.

Phase-7 e2e script at packages/mcp/test-reports/phase7-e2e.ts:
MCP HTTP + editor Next.js both point at $PASCAL_DATA_DIR =
/tmp/pascal-e2e, save_scene from MCP, GET /api/scenes/<id> from
editor server, /scenes list page renders all saved scenes, scene
page renders SceneLoader, delete_scene works.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 19:29:28 +02:00
Adrian Perez
bdb47a6e5d feat(editor): expose useScene on window in dev for MCP-editor bridging
Adds window.__pascalScene = useScene in development builds so that a
running MCP process (which has its own Node-side in-memory store) can
inject a built scene into the browser editor for visual verification:

  fetch('/dev/casa-sol.json')
    .then(r => r.json())
    .then(s => window.__pascalScene.getState().setScene(s.nodes, s.rootNodeIds))

Also ships /public/dev/casa-sol.json as a reference scene — the
artefact exported from the MCP Casa del Sol test build.

Gated behind NODE_ENV !== 'production' so nothing leaks to prod.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 18:38:07 +02:00
Pascal
50eca057ca
feat: editor layout redesign v2 + 3D box select (#207)
Major layout redesign introducing v2 editor layout:

**New Features**
- V2 two-column layout (resizable sidebar + viewer panel with toolbar slots)
- 3D box select tool with marquee selection (561 lines pure Three.js geometry)
- View mode system (3D/2D/Split) replacing old floorplan toggle
- Floating level selector on viewer panel
- Viewer toolbar: level mode, wall mode, units, theme, camera, walkthrough, preview
- Horizontal tab bar for sidebar panels

**Layout Changes**
- Fixed 5-button control bar: Select, Box Select, Site Edit, Build, Delete
- Simplified view toggles (scans/guides only)
- Always-mounted viewers (display:none) to preserve WebGL context
- First-person walkthrough forces 3D view, restores on exit
- Site edit as permanent control (phase='site' is sole signal)

**Technical**
- layoutVersion prop: 'v1' (default) or 'v2'
- New exports: FloatingLevelSelector, SettingsPanel, SidebarTab, ViewMode, ViewerToolbarLeft/Right
- isCollapsed/setIsCollapsed added to sidebar store
- isFirstPersonMode restored for walkthrough support

19 files changed, +3230/-1898
Built and verified: bun run build passes (all tasks, 0 errors)
2026-04-02 11:24:19 -04:00
Anton
f06f2fa1b1
feat: 2D editing — floorplan panel, measurements, command palette (v0.3.0)
* sync: port 2D editing features from monorepo (v0.3.0)

## New Features

### Floorplan Panel (7.5K LOC)
- Full 2D editing interface with wall drawing, measurement, and unit display
- Interactive floorplan view with pan/zoom, grid snapping
- Wall thickness visualization, door/window placement
- Zone and slab polygon editing
- Guide image overlay support
- Metric/imperial unit toggle

### Command Palette Overhaul
- Complete rewrite with new command registry system
- Keyboard shortcuts UI with ShortcutToken component
- Editor-specific commands (floorplan, measurements, camera focus)
- Improved search and action organization

### Wall Measurements
- Real-time wall length labels in 3D view
- Metric/imperial conversion
- Wall measurement UI component

### Enhanced Tools
- Wall drafting utilities (grid snapping, validation)
- Node action menu for quick operations
- Improved polygon editing for zones/slabs/sites
- Roof segment panel for granular roof control

## Package Changes

### @pascal-app/core@0.3.0
- New wall-footprint.ts: 2D wall footprint calculation
- Wall mitering exports for floorplan view
- camera-controls:focus event
- Space detection undo pause/resume
- Mark sibling nodes dirty on deletion (miter recalc)

### @pascal-app/viewer@0.3.0
- ErrorBoundary component for robust item rendering
- Broken item fallback UI
- Wall renderer: mark dirty on mount
- Ground occluder: only lowest level punches through
- Unit state (metric/imperial) in viewer store

### @pascal-app/editor@0.1.0
- 48 file changes (16 new, 32 modified)
- New stores: useCommandRegistry, usePaletteViewRegistry
- Tree node drag-and-drop system
- Level selection utilities
- Enhanced scene graph operations

## Apps/Editor
- GeistPixelSquare font for pixel-perfect UI
- Blueprint icon asset
- Updated layout and globals for font support

## Security
- Zero AI imports or internal package refs
- All monorepo-specific code excluded
- Clean audit: no API keys or secrets

## Testing
- Security audit passed ✅
- All AI/internal code excluded ✅
- Version bumps applied ✅

79 files modified, 16 files added
~2600 insertions, ~1400 deletions

* fix: lint cleanup — suppress intentional dep warnings, fix missing dep, remove stale ignores

- Add biome-ignore for 3 intentional useEffect reset patterns (levelId, selectedGuide, selectedId)
- Fix actual missing dependency: currentBuildingId in handleSiteEditShortcutSelect callback
- Remove 3 stale biome-ignore comments in r3f.d.ts (rule not active)

Build and lint pass clean.

* fix: type errors — polygon area guards, selection cast, readonly keywords, door guard

- ceiling-panel, slab-panel, ceiling-tree-node, slab-tree-node, zone-tree-node:
  guard polygon[i]/polygon[j] array access before arithmetic (TS2532)
- scene.ts: introduce toViewerSelection() helper to cast persisted string IDs
  to branded template literal types expected by useViewer.setSelection (TS2345)
- door-panel: guard early return when node is undefined in setSegmentHeightRatio (TS18048)
- editor-commands: remove 'as const' from inline command object, keywords is mutable string[] (TS2322)

All type checks pass. Build and lint clean.

---------

Co-authored-by: Anton Pascal <anton-pascal@users.noreply.github.com>
2026-03-24 19:48:11 +00:00
wass08
f2501be2bf remove community 2026-03-13 09:07:46 +01:00
wass08
7359c1fcbf splitting editor and community 2026-03-11 12:16:26 +01:00
Aymeric Rabot
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 Rabot
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
wass08
849baa0a0e default value 2026-03-06 13:08:24 +01:00
wass08
88d0231a95 collection controls 2026-03-06 13:08:24 +01:00
wass08
54051b11fa item system controls 2026-03-06 13:08:21 +01:00
Aymeric Rabot
fb2c7c6c71
fix: harden viewer/editor renderer init and error handling (#133) 2026-03-05 15:42:58 -05:00
wass08
299cbdb0b3 fix build 2026-03-04 16:29:55 +01:00
wass08
23ed54cb6a thumbnail generation 2026-03-04 15:13:07 +01:00
wass08
ba2dfa8caa presets community 2026-03-04 13:38:51 +01:00
wass08
a86609aa5c community presets draft 2026-03-04 13:18:18 +01:00
wass08
5e0c64b760 remove position hack for zone + fade-in-out anims 2026-03-04 11:22:01 +01:00
Aymeric Rabot
bde8a005a7
feat(viewer): redesign viewer UI with dark toolbar and camera controls (#126)
Overhaul viewer overlay with a unified bottom toolbar, dark theme support,
theme toggle, camera orbit/top-view controls, and fix TypeScript array
access errors for level and wall mode cycling.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 01:28:37 -05:00
Aymeric Rabot
98c1d5247e
feat: filter empty projects from public gallery (#125)
* feat(community): filter empty projects from public gallery

Add is_empty column to projects table so the public gallery only shows
projects with actual content. Scene graph emptiness is computed on save
and on creation, and a backfill migration marks existing non-empty
projects. Also cleans up import ordering, fixes README migration path,
and removes stale feedback table migration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Use ESNext modules and bundler resolution

Update packages/db tsconfig to emit ESNext modules and use 'bundler' moduleResolution. This enables modern ESM output and bundler-style resolution for the db package (keeps outDir and rootDir unchanged).

* feat(editor): add dark mode theme and grid visibility toggle

Add theme state to viewer store with light/dark modes, dark-aware
lighting and background colors, grid show/hide toggle in settings,
and theme toggle buttons in the sidebar.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Add ground occluder, animated lighting & UI tweaks

Introduce a ground occluder and smoother animated lighting while adjusting editor UI and icons. Viewer: add GroundOccluder (uses polygon-clipping to union slab/zone polygons) and AnimatedBackground, integrate both into the Canvas; improve Lights to interpolate intensities/colors/ambient for smooth theme transitions. Editor: refactor sidebar header to support inline project title editing and move the theme toggle; replace some lucide icons with image assets and add a settings icon (apps/editor/public/icons/settings.png). Also add polygon-clipping to the viewer package dependencies.

* Update dark mode background color and clean up imports

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 23:49:48 -05:00
Aymeric Rabot
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 Rabot
5ecefbdc06
Feat/ux round 3 (#124)
* Tree: add isLast prop & draw connectors

Introduce an optional isLast prop across all site panel tree node components and TreeNode so children know when they're the last sibling. TreeNodeWrapper now renders vertical and horizontal connector lines (adjusted by depth and isLast) and keeps the toggle button clickable (z-index). Children are passed isLast when mapped, so the UI can stop the vertical line for final siblings. Also bump several deps in apps/editor package.json and update the lockfile accordingly.

* chore: clean up monorepo dependencies and update packages

Move app/library dependencies out of root package.json into their
respective workspaces. Root now only contains monorepo tooling
(turbo, biome, supabase CLI, typescript, portless, ultracite).

Updates:
- next 16.1.0 → 16.1.6
- drizzle-orm ^0.39.0 → ^0.45.1
- drizzle-kit ^0.30.0 → ^0.31.9
- drizzle-zod ^0.5.1 → ^0.8.3
- three-bvh-csg ^0.0.17 → ^0.0.18
- supabase 2.75.3 → 2.76.15
- typescript 5.9.2 → 5.9.3 (all workspaces)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Use semantic theme tokens and enable dark mode

Replace hardcoded zinc color classes with semantic design tokens (text-muted-foreground, text-foreground, border, bg-background, bg-border) across the action menu, camera controls, control modes, and view toggles for consistent theming. Update separators and borders to use bg-border/border-border. Add useEffect in the editor root to add/remove the 'dark' class on document.body and apply 'dark text-foreground' to the root container so the UI renders in dark mode; also import useEffect.

* Persistable sidebar width & resizer

Introduce a zustand store to persist sidebar width (key: `sidebar-preferences`) and track dragging state. Default width is 288px (18rem) and is clamped between 288 and 800px. Wire the store into SidebarProvider to drive the CSS variable for width and expose a data-dragging attribute. Add a SidebarResizer component that handles pointer events to resize the sidebar, toggles dragging state, updates cursor/user-select, and disables transitions while dragging. Small class and structure adjustments ensure the resizer is rendered and resizing behaves smoothly.

* Editor: floating action menu, selection/phase tweaks

Add a FloatingActionMenu (move/duplicate/delete) that attaches to selected 3D nodes and integrates with editor/viewer state; includes new cursor SVG and layout wrapper to use the custom cursor. Improve selection and phase behavior: auto-select first building+level on scene load (moved/centralized in project scene hook and editor init), add resolveBuildingId helper, and enhance SelectionManager to auto-switch between structure/furnish based on clicked nodes and to preserve building/level context when changing selection. Update sidebar tree node click handlers to switch phases for structural vs item nodes and stop hiding nodes by phase (keep tree items visible across phases). Add keyboard escape behavior to clear selections while keeping building/level context and reset selected reference. Misc: register unified event listeners for selection, position floating menu over objects using three.js Box3, and various small integration fixes.

* Add SceneLoader, loading states & editor fixes

Add a SceneLoader component and associated CSS loader styles and wire it into Editor, Viewer and page-level flows so a loading UI displays while project/scene data loads. Replace useLayoutEffect in editor page with a client-mounted useEffect guard to avoid hydration issues. Introduce isSceneLoading state and setter in the project store and set/clear it in useProjectScene; include sceneGraph when creating a new project and clear the scene beforehand.

Other changes: type-guard moving/duplicating logic in FloatingActionMenu and remove duplicated id on clones; refactor auto-selection logic for site/building/level and auto-select build/wall for empty levels in editor index and useProjectScene; optimize ZoneSystem to run per-frame (useFrame) and reduce unnecessary updates to visibility/label positions; add animated active background for layer toggle (motion) in site panel; add keyboard shortcuts to jump between levels (Ctrl/Cmd+ArrowUp/Down); simplify community-hub project-created handler to navigate straight to editor. These changes improve UX during load, enforce safer node operations, and optimize runtime rendering.

* Improve selection logic and refine UI components

Multiple editor and viewer updates:

- Selection: enhance selection-manager to support modifier (Meta/Ctrl) multi-select, compute next selection logic, track modifier keys, prevent grid deselect races, and add debug logs. Adapted selection handlers throughout scene/editor components to pass native events and modifier state.

- Sidebar / Site panel: refactor site panel to inline a LevelReferences UI (replacing the removed references dialog). Add upload flow for scan (.glb/.gltf) and guide images, handling file size/type checks, project asset upload/delete calls, and per-level reference lists. Add MultiSelectionBadge for showing/clearing multi-selection and animated expand/collapse for levels. Several tree-node components now use a shared handleTreeSelection helper and propagate click events properly.

- UI polish & icons: change dark theme color tokens for better contrast; increase button sizes and icon sizes across action menus; swap some lucide icons for image assets (rotate, topview, select, build, mesh, floorplan, level, etc.) and add new public icons.

- PascalRadio: replace popover with a framer-motion expandable panel, add outside-click handling, animated transitions, and minor UI tweaks.

- Other: minor viewer hook/selection-manager updates and tweaks to control modes and view toggles to support image icons and consistent sizing.

These changes improve multi-select reliability, user interactions in the sidebar, and overall visual polish with new icons and animations.

* Fix TypeScript build errors in selection-manager and scene-loader

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 22:09:40 -05:00
wass08
8345e42119 removed non logged in editor 2026-02-26 12:04:12 +09:00
Aymeric Rabot
48d5091bb3
UX polish: selection behavior, styling, and site panel improvements (#119)
* Remove .env.local guard; add portless dep

Remove the check that blocked a local .env.local in apps/editor's dev script and simplify the dev startup to source the root .env. Add portless@^0.4.2 to the project dependencies in package.json. Lockfile updated accordingly.

* Improve tool cursors, previews, and contextual tools

Revamp editor tool visuals and behaviour: replace mesh cursors with a new CursorSphere Group (adds ground marker, vertical indicator and optional tool icon tooltip), unify preview colors to #818cf8, add ground-level previews and ghost lines for ceiling and roof tools, and update slab/zone/wall visuals to match. Add automatic build-mode switching and contextual highlighting for structure tools via a new useContextualTools hook, and relax action-menu visibility checks so tool rows are shown even when not in build mode. Minor typing/import adjustments and small opacity/placement tweaks across multiple tool components.

* Keep tools active and refine action-menu styles

Stop auto-deactivating tools in RoofTool and ZoneTool by removing setTool(null) (and setMode('select') in roof). Add hasActiveTool checks and small layout padding to FurnishTools and StructureTools, and update button classes to improve visual emphasis: smoother transitions, stronger active rings/scale, and dimming/grayscale of non-active tools when another tool is active. These changes improve UX by keeping the selected tool active and giving clearer visual feedback in the action menu.

* Improve selection behavior and refresh UI styling

SelectionManager: add global enter/leave/double-click handlers to support cross-phase hovering and auto-switching into structure/furnish on double-click; normalize click handling (explicitly coalesce shiftKey). Remove per-strategy enter/leave listeners.

UI panels & controls: unify and modernize styles across many panels (ceiling, door, item, reference, roof, slab, wall, window) and action buttons — rounded-md, neutral borders, subtle shadows, translucent headers and consistent hover/focus states. Update view toggles icons and toggle styling.

NumberInput: integrate @number-flow/react NumberFlow for formatted value display, add visual drag progress indicator and refine input/label interactions and styling.

Sidebar: replace rename-popover with inline-rename-input and update tree nodes to use inline editing. Add slider-demo and tweak slider implementation. Update package.json accordingly.

* Use Barlow font across editor UI

Add the Google Barlow font and expose it as a CSS variable, update theme font variables in globals.css, and apply the new font across the editor UI. Imports: add Barlow in app/layout.tsx and include its variable on <html>, set body to use font-sans. Apply font-barlow or font-mono classes to headings, labels, numeric readouts and buttons across multiple panels and primitives to standardize typography. Also update button base variant to include font-barlow. Remove the PhaseSwitcher component and its import/usage from the action menu.

* Replace button wrapper with div in LevelItem

Replace the outer <button> around the LevelItem content with a <div> to avoid nesting interactive button elements (and the resulting invalid HTML/interaction issues). Preserves the original classes and onClick/onDoubleClick handlers so behavior remains the same and allows the PopoverTrigger/button children to function correctly.

* Refine site panel list styles and spacing

Update the SitePanel and TreeNode UI to use compact, border-bottom list rows instead of rounded, card-like items. Simplified active/hover states to use bg-accent variants and reduced shadow/ring styles for a cleaner look. Adjusted paddings (pl/px/py) and container layouts (many sections switched to flex-col) and increased tree node indent/paddingRight for consistent alignment. These changes unify spacing and visual hierarchy across levels, buildings, zones and tree nodes.

* Add auto-scroll to selected items and refine icon styles

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 18:05:02 -05:00
wass08
d9317bfba2 automated thumbnail + position enhancement 2026-02-25 12:43:14 +09:00
Wassim SAMAD
2182fe535d
Merge pull request #116 from pascalorg/fix/community-feedback-pass-3
Fix/community feedback pass 3
2026-02-24 16:17:44 +09:00
wass08
81ede241d5 save site + camera build position 2026-02-24 14:48:59 +09:00
Anton
5781e98270
feat: add YouTube social link to user profiles (#114)
* feat: add YouTube social link to user profiles

- Add youtube_url column to auth_users schema
- Add DB migration for the new column
- Update updateProfile action with YouTube URL validation
- Update getUserProfile and getPublicProfile to include youtubeUrl
- Add YouTube input field to settings page
- Display YouTube icon on public profile pages

* fix: use drizzle-kit generate for youtube_url migration

Replaces manually created migration with proper drizzle-kit generated
migration that includes meta snapshot and journal entry.

---------

Co-authored-by: Anton Pascal <anton-pascal@users.noreply.github.com>
2026-02-24 05:38:40 +00:00
wass08
0863f5e632 fix z-index viewer 2026-02-24 13:07:53 +09:00
wass08
0dea6a2205 fix zones in viewer too 2026-02-24 13:06:45 +09:00
Anton
2dcb80554c
feat: add terms, privacy pages, email notification preferences, and sign-in consent (#107)
- /terms — Terms of Service for editor + pascal.app platform
- /privacy — Privacy Policy (data collection, third parties, user rights)
- Email notification toggle in Settings (new column + migration)
- Sign-in consent text linking to terms/privacy
- Effective date: February 20, 2026

Co-authored-by: Anton Pascal <anton-pascal@users.noreply.github.com>
2026-02-20 04:02:08 +00:00
Aymeric Rabot
f4f9f8a220
feat: add project visibility settings for scans and floorplans (#106)
- Add show_scans_public and show_guides_public columns to projects table
- Add visibility toggles to editor sidebar settings panel (auto-save)
- Add visibility toggles to project settings dialog (auto-save)
- Propagate settings to community viewer (hide scans/guides for non-owners)
- Add updateProjectVisibility server action
- Fix username onboarding dialog stuck after DB reset (validate update affected rows)
- Add error handling to UsernameGate for stale sessions

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-19 16:59:23 -05:00
Anton
ff85765728
fix: resolve react-doctor errors (hooks order, reduced motion, key prop) (#105)
- Move useCallback hooks before early return in ReferencesDialog
  to fix conditional hook call violation (Rules of Hooks)
- Add useReducedMotion hook and apply to all motion animations
  for WCAG 2.3.3 accessibility compliance
- Replace useEffect state reset with key prop on ItemCatalog
  for proper React reconciliation on category change
- Add global prefers-reduced-motion CSS media query

Fixes 4 react-doctor errors, bringing score from 81 to ~85+.
2026-02-19 19:20:05 +00:00
Aymeric Rabot
9a0f83a1ec
feat: SEO improvements, OG image endpoint, favicon, and metadata (#104)
- Add dynamic OG image generation endpoint (/og) adapted from monorepo
- Replace favicon with monorepo version, remove unused icon.svg
- Add seo.ts config, robots.ts, sitemap.ts for better search indexing
- Add per-page metadata (editor, viewer, settings, profile, community)
- Remove stale package-lock.json that caused ENOWORKSPACES errors with Next.js
- Add OG fonts (Geist Regular, Plus Jakarta Sans SemiBold)

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-19 13:38:34 -05:00
Aymeric Rabot
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 Rabot
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
wass08
1cceb50ab6 fix thumbnail issues 2026-02-18 09:49:57 +09:00
Anton Pascal
ee30f17129 feat: rename properties to projects
- Rename all DB tables: properties → projects, properties_addresses → projects_addresses, properties_models → projects_models, property_likes → projects_likes
- Add projects_likes as proper Drizzle schema table (was SQL-only before)
- Rename ID prefixes: property_xxx → project_xxx
- Rename auth_sessions column: active_property_id → active_project_id
- Simplify project creation: address is now optional (no longer required to get started)
- Update all actions, stores, types, components, and routes
- Rename route: /editor/[propertyId] → /editor/[projectId]
- Add SQL migration for table/column/index/policy/function renames
- Update RPC functions: increment_project_views, get_project_like_count
- Update storage bucket reference: project-thumbnails
- All types/exports follow existing Drizzle patterns (pgTable, relations, zod schemas)
2026-02-17 20:40:52 +00:00
wass08
078b2500a3 handle thumbnails (manual) 2026-02-17 12:07:32 +09:00
wass08
144a2bd18f camera controls enhancement 2026-02-17 08:52:58 +09:00
wass08
66e8453db3 hub features 2026-02-16 13:43:19 +09:00
wass08
92f1c065f8 fix magic link issue 2026-02-11 17:09:08 +09:00
wass08
64205b1077 fix build 2026-02-11 16:46:12 +09:00
wass08
13bfa41489 fix build env 2026-02-11 16:40:24 +09:00
wass08
2e8b663001 community feature 2026-02-11 15:23:18 +09:00
wass08
30653b49c9 wall cutout 2026-02-03 14:28:06 +09:00