Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 33 additions & 13 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@ on:
- ifc-converter
- all
bump:
description: "Version bump (use 'none' to publish current version as-is)"
description: "Version bump (beta publishes a prerelease on the beta dist-tag)"
required: true
type: choice
options:
- patch
- minor
- major
- beta
- none
dry-run:
description: "Dry run (no publish)"
Expand Down Expand Up @@ -63,6 +64,19 @@ jobs:

bump_version() {
local v=$1
if [ "$BUMP" = "beta" ]; then
if [[ "$v" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)-beta\.([0-9]+)$ ]]; then
echo "${BASH_REMATCH[1]}.${BASH_REMATCH[2]}.${BASH_REMATCH[3]}-beta.$((BASH_REMATCH[4]+1))"
return
fi
IFS='.' read -r MAJ _ _ <<< "${v%%-*}"
if [ "$MAJ" -lt 1 ]; then
echo "1.0.0-beta.1"
else
echo "$((MAJ+1)).0.0-beta.1"
fi
return
fi
IFS='.' read -r MAJ MIN PAT <<< "$v"
if [ "$BUMP" = "major" ]; then MAJ=$((MAJ+1)); MIN=0; PAT=0; fi
if [ "$BUMP" = "minor" ]; then MIN=$((MIN+1)); PAT=0; fi
Expand All @@ -71,6 +85,12 @@ jobs:
echo "$MAJ.$MIN.$PAT"
}

if [ "$BUMP" = "beta" ]; then
echo "NPM_TAG=beta" >> "$GITHUB_ENV"
else
echo "NPM_TAG=latest" >> "$GITHUB_ENV"
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Beta publish can tag latest

High Severity

NPM_TAG is set to beta only when bump is beta; every other bump, including none, publishes with --tag latest. After packages are on 1.0.0-beta.N, a none republish would mark that prerelease as latest. Non-beta bumps also parse 1.0.0-beta.1 into a broken patch segment and fail in arithmetic.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 658ce25. Configure here.


# Track new versions in shell-local vars.
# NOTE: $GITHUB_ENV writes don't surface within the same step, so the
# peerDeps sync below must use shell vars, not env indirection.
Expand Down Expand Up @@ -118,9 +138,9 @@ jobs:
bun run build
if [ "${{ inputs.dry-run }}" = "true" ]; then
echo "🏜️ Dry run — would publish @pascal-app/core@$CORE_VERSION"
npm publish --dry-run --access public
npm publish --dry-run --access public --tag "$NPM_TAG"
else
npm publish --access public
npm publish --access public --tag "$NPM_TAG"
echo "📦 Published @pascal-app/core@$CORE_VERSION"
fi

Expand All @@ -133,9 +153,9 @@ jobs:
bun run build
if [ "${{ inputs.dry-run }}" = "true" ]; then
echo "🏜️ Dry run — would publish @pascal-app/viewer@$VIEWER_VERSION"
npm publish --dry-run --access public
npm publish --dry-run --access public --tag "$NPM_TAG"
else
npm publish --access public
npm publish --access public --tag "$NPM_TAG"
echo "📦 Published @pascal-app/viewer@$VIEWER_VERSION"
fi

Expand All @@ -147,9 +167,9 @@ jobs:
run: |
if [ "${{ inputs.dry-run }}" = "true" ]; then
echo "🏜️ Dry run — would publish @pascal-app/editor@$EDITOR_VERSION"
npm publish --dry-run --access public
npm publish --dry-run --access public --tag "$NPM_TAG"
else
npm publish --access public
npm publish --access public --tag "$NPM_TAG"
echo "📦 Published @pascal-app/editor@$EDITOR_VERSION"
fi

Expand All @@ -162,9 +182,9 @@ jobs:
bun run build
if [ "${{ inputs.dry-run }}" = "true" ]; then
echo "🏜️ Dry run — would publish @pascal-app/nodes@$NODES_VERSION"
npm publish --dry-run --access public
npm publish --dry-run --access public --tag "$NPM_TAG"
else
npm publish --access public
npm publish --access public --tag "$NPM_TAG"
echo "📦 Published @pascal-app/nodes@$NODES_VERSION"
fi

Expand All @@ -177,9 +197,9 @@ jobs:
bun run build
if [ "${{ inputs.dry-run }}" = "true" ]; then
echo "🏜️ Dry run — would publish @pascal-app/mcp@$MCP_VERSION"
npm publish --dry-run --access public
npm publish --dry-run --access public --tag "$NPM_TAG"
else
npm publish --access public
npm publish --access public --tag "$NPM_TAG"
echo "📦 Published @pascal-app/mcp@$MCP_VERSION"
fi

Expand All @@ -194,9 +214,9 @@ jobs:
bun run build
if [ "${{ inputs.dry-run }}" = "true" ]; then
echo "🏜️ Dry run — would publish @pascal-app/ifc-converter@$IFC_CONVERTER_VERSION"
npm publish --dry-run --access public
npm publish --dry-run --access public --tag "$NPM_TAG"
else
npm publish --access public
npm publish --access public --tag "$NPM_TAG"
echo "📦 Published @pascal-app/ifc-converter@$IFC_CONVERTER_VERSION"
fi

Expand Down
36 changes: 36 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,41 @@
# Changelog

## 1.0.0-beta.1 (2026-07-30)

The first Pascal Editor 1.0 beta. Relative to
[v0.9.1](https://github.com/pascalorg/editor/releases/tag/v0.9.1), this release
focuses the editor around a stable extensible scene model and production-grade
architectural workflows.

### Highlights

- **Terrain sculpting** — raise, lower, flatten, and smooth a compact height field with a persistent brush, live grid feedback, subtle continuous sound, undo-safe strokes, terrain raycasting, and first-person collision.
- **Terrain-aware construction** — walls, slabs, stairs, fences, columns, items, and other floor-placed nodes resolve stacked support and update live while terrain is sculpted. Wall and slab foundations can fill down to terrain without changing authored height or thickness.
- **Vertical modeling** — stored storey heights, raised-support drafting, explicit elevation anchors and guides, slab/deck stacking, auto-room surface elevation, wall/ceiling clamps, and support-aware placement above or below slabs.
- **Plugin and node architecture** — public node definitions, the built-in nodes package, plugin management, host integration primitives, and first-party Nature and MEP workflows.
- **Floor-plan and export workflows** — faster navigation, contextual dimensions and modes, more reliable placement and selection, textured GLB plus STL/OBJ export, capture framing, and hardened bake/walkthrough paths.
- **Rendering and interaction quality** — grounded lighting, safer WebGPU/WebGL fallbacks, deterministic snapping, group manipulation, improved camera/compass synchronization, and resilient legacy-scene migration.

### Packages

All public packages are published as `1.0.0-beta.1` under the npm `beta`
dist-tag. Stable `latest` installations remain on the 0.x line during the beta.

### Contributors

Thank you to [@wass08](https://github.com/wass08),
[@sudhir9297](https://github.com/sudhir9297),
[@anton-pascal](https://github.com/anton-pascal),
[@konevenkatesh](https://github.com/konevenkatesh),
[@MateoSaettone](https://github.com/MateoSaettone),
[@ruok-dev](https://github.com/ruok-dev),
[@mvanhorn](https://github.com/mvanhorn), and
[@kuishou68](https://github.com/kuishou68) for their work across the editor,
viewer, node library, MCP integration, documentation, and stability fixes.

**Full changelog**:
https://github.com/pascalorg/editor/compare/v0.9.1...v1.0.0-beta.1

## 0.6.0 (2026-04-21)

### Features
Expand Down
20 changes: 18 additions & 2 deletions apps/editor/components/build-tab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
getFloorplanNodeExtension,
isFloorplanToolAvailableInMode,
MaterialPaintPanel,
TerrainSculptPanel,
triggerSFX,
useEditor,
useFloorplanMode,
Expand Down Expand Up @@ -46,7 +47,7 @@ type BuildType = {
kind?: string
paletteOrder?: number
/** Non-placement special mode. */
mode?: 'material-paint'
mode?: 'material-paint' | 'terrain-sculpt'
}

type MepItem = {
Expand Down Expand Up @@ -74,6 +75,7 @@ const BASE_BUILD_TYPES: BuildType[] = [
// Group tile — no tool of its own; opens the MEP sub-grid below (like Roof).
{ id: 'mep', label: 'MEP', iconSrc: '/icons/HVAC.webp' },
{ id: 'painting', label: 'Painting', iconSrc: '/icons/paint.webp', mode: 'material-paint' },
{ id: 'terrain', label: 'Terrain', iconSrc: '/icons/mesh.webp', mode: 'terrain-sculpt' },
]

function collectBuildTypes(floorplanMode: FloorplanMode): BuildType[] {
Expand Down Expand Up @@ -156,6 +158,14 @@ function activatePaintMode(): void {
ed.setMode('material-paint')
}

/**
* Enter terrain-sculpt mode — the Build tab's "Terrain" category. No `setPhase`:
* `setMode` moves to the site phase itself, since sculpting is a site-phase mode.
*/
function activateTerrainSculptMode(): void {
useEditor.getState().setMode('terrain-sculpt')
}

type RoofFeature = { kind: string; label: string; iconSrc: string }

const ROOF_FEATURE_FALLBACK_ICON = '/icons/roof.webp'
Expand Down Expand Up @@ -251,7 +261,7 @@ export function BuildTab() {
const isMepActive = mode === 'build' && !!activeTool && MEP_TOOL_KINDS.has(activeTool)

const isTypeActive = (type: BuildType) => {
if (type.mode === 'material-paint') return mode === 'material-paint'
if (type.mode) return mode === type.mode
if (type.id === 'mep') return isMepActive
if (type.id === 'roof')
return mode === 'build' && (activeTool === 'roof' || isRoofFeatureActive)
Expand All @@ -261,6 +271,8 @@ export function BuildTab() {
const handleTypeClick = useCallback((type: BuildType) => {
if (type.mode === 'material-paint') {
activatePaintMode()
} else if (type.mode === 'terrain-sculpt') {
activateTerrainSculptMode()
} else if (type.id === 'mep') {
// MEP is a group tile: arm its first tool so a usable tool is active
// (and we leave any prior paint mode), then reveal the MEP sub-grid.
Expand Down Expand Up @@ -332,6 +344,10 @@ export function BuildTab() {
<div className="min-h-0 flex-1 overflow-y-auto">
<MaterialPaintPanel />
</div>
) : mode === 'terrain-sculpt' ? (
<div className="min-h-0 flex-1 overflow-y-auto">
<TerrainSculptPanel />
</div>
) : mode === 'build' &&
(activeTool === 'roof' || isRoofFeatureActive) &&
roofFeatures.length > 0 ? (
Expand Down
Binary file added apps/editor/public/audios/sfx/terrain_flatten.mp3
Binary file not shown.
Binary file added apps/editor/public/audios/sfx/terrain_lower.mp3
Binary file not shown.
Binary file added apps/editor/public/audios/sfx/terrain_raise.mp3
Binary file not shown.
Binary file added apps/editor/public/audios/sfx/terrain_smooth.mp3
Binary file not shown.
Binary file added apps/editor/public/icons/terrain-flatten.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/editor/public/icons/terrain-lower.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/editor/public/icons/terrain-raise.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/editor/public/icons/terrain-smooth.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"clean:cache": "rm -rf apps/*/.next apps/*/.swc apps/*/.turbo packages/*/.turbo tooling/*/.turbo .turbo node_modules/.cache",
"restart": "bun kill && bun clean:cache && bun dev",
"release": "gh workflow run release.yml -f package=all -f bump=patch",
"release:beta": "gh workflow run release.yml -f package=all -f bump=beta",
"release:viewer": "gh workflow run release.yml -f package=viewer -f bump=patch",
"release:core": "gh workflow run release.yml -f package=core -f bump=patch",
"release:editor": "gh workflow run release.yml -f package=editor -f bump=patch",
Expand Down
Loading
Loading