diff --git a/package.json b/package.json
index a636bdd5..da6236ad 100644
--- a/package.json
+++ b/package.json
@@ -13,7 +13,7 @@
"prepare-resources": "node scripts/download-python-embed.js",
"test": "npm run test:py && npm run test:node",
"test:py": "node scripts/run-pytests.mjs",
- "test:node": "node --test --experimental-strip-types --experimental-loader ./scripts/node-ts-extensionless-loader.mjs src/shared/types/assetLibrary.test.ts src/areas/generate/assetLibraryProjection.test.ts src/areas/generate/assetLibraryService.test.ts src/areas/generate/assetLibraryUi.test.ts src/areas/generate/orcaSlicerLink.test.ts src/shared/utils/agentStream.test.ts src/shared/utils/ollamaHealth.test.ts src/shared/utils/notification.test.ts electron/main/artifact-registry-service.test.ts electron/main/extension-path-guard.test.ts electron/main/storage-directory-guard.test.ts electron/main/storage-ownership.test.ts electron/main/startup-error.test.ts electron/main/api-port.test.ts electron/preload/artifact-registry-preload.test.ts && node --test electron/main/*.test.mjs src/**/*.test.mjs",
+ "test:node": "node --test --experimental-strip-types --experimental-loader ./scripts/node-ts-extensionless-loader.mjs src/shared/types/assetLibrary.test.ts src/areas/generate/assetLibraryProjection.test.ts src/areas/generate/assetLibraryService.test.ts src/areas/generate/assetLibraryUi.test.ts src/areas/generate/orcaSlicerLink.test.ts src/shared/utils/agentStream.test.ts src/shared/utils/ollamaHealth.test.ts src/shared/utils/notification.test.ts electron/main/artifact-registry-service.test.ts electron/main/extension-path-guard.test.ts electron/main/storage-directory-guard.test.ts electron/main/storage-ownership.test.ts electron/main/startup-error.test.ts electron/main/api-port.test.ts electron/preload/artifact-registry-preload.test.ts src/shared/stores/meshHistory.test.ts && node --test electron/main/*.test.mjs src/**/*.test.mjs",
"package": "cross-env CSC_IDENTITY_AUTO_DISCOVERY=false npm run build && npm run prepare-resources && electron-builder",
"package:mac": "cross-env CSC_IDENTITY_AUTO_DISCOVERY=false npm run build && npm run prepare-resources && electron-builder --mac --arm64",
"lint": "eslint ."
diff --git a/src/areas/generate/GeneratePage.tsx b/src/areas/generate/GeneratePage.tsx
index 76a13119..84639239 100644
--- a/src/areas/generate/GeneratePage.tsx
+++ b/src/areas/generate/GeneratePage.tsx
@@ -2,6 +2,7 @@ import { useState, useRef, useCallback, useEffect, useMemo } from 'react'
import type { ReactNode } from 'react'
import { useAppStore, DEFAULT_LIGHT_SETTINGS } from '@shared/stores/appStore'
import type { GenerationJob, LightSettings, PointLight } from '@shared/stores/appStore'
+import { redoDepth, undoDepth } from '@shared/stores/meshHistory'
import { useApi } from '@shared/hooks/useApi'
import { ColorPicker } from '@shared/components/ui'
import GenerationHUD from './components/GenerationHUD'
@@ -691,15 +692,15 @@ export default function GeneratePage(): JSX.Element {
const currentJob = useAppStore((s) => s.currentJob)
const apiUrl = useAppStore((s) => s.apiUrl)
const showError = useAppStore((s) => s.showError)
- const updateCurrentJob = useAppStore((s) => s.updateCurrentJob)
const setCurrentJob = useAppStore((s) => s.setCurrentJob)
const meshStats = useAppStore((s) => s.meshStats)
const meshSelected = useAppStore((s) => s.meshSelected)
const pushMeshUrl = useAppStore((s) => s.pushMeshUrl)
const undoMesh = useAppStore((s) => s.undoMesh)
const redoMesh = useAppStore((s) => s.redoMesh)
- const canUndo = useAppStore((s) => s.historyIndex > 0)
- const canRedo = useAppStore((s) => s.historyIndex < s.meshHistory.length - 1)
+ const applyMeshEdit = useAppStore((s) => s.applyMeshEdit)
+ const undoSteps = useAppStore((s) => undoDepth(s.meshHistory))
+ const redoSteps = useAppStore((s) => redoDepth(s.meshHistory))
const { optimizeMesh, smoothMesh, importMesh } = useApi()
const assetLibraryService = useMemo(() => getDefaultAssetLibraryService(), [])
@@ -894,8 +895,7 @@ export default function GeneratePage(): JSX.Element {
try {
const path = getOptimizePath(currentJob.outputUrl)
const { url } = await smoothMesh(path, iterations)
- updateCurrentJob({ outputUrl: url })
- pushMeshUrl(url)
+ applyMeshEdit(url)
setOpenPanel(null)
} catch (err) {
showError(err instanceof Error ? err.message : String(err))
@@ -910,8 +910,7 @@ export default function GeneratePage(): JSX.Element {
try {
const path = getOptimizePath(currentJob.outputUrl)
const { url } = await optimizeMesh(path, targetFaces)
- updateCurrentJob({ outputUrl: url })
- pushMeshUrl(url)
+ applyMeshEdit(url)
setOpenPanel(null)
} catch (err) {
showError(err instanceof Error ? err.message : String(err))
@@ -971,20 +970,25 @@ export default function GeneratePage(): JSX.Element {
{/* Undo / Redo */}