- If
build/ios_device_run/CosimoSynthAUv3.xcodeprojdoes not exist yet in the current worktree, generate it with./scripts/generate_ios_auv3_xcode_project.sh build/ios_device_run. - The canonical shortcut for that step is
npm run ios:project. - To build the installable iPhone app, build the
CosimoSynth_Standalonescheme frombuild/ios_device_run/CosimoSynthAUv3.xcodeproj. - Install
build/ios_device_run/CosimoSynth_artefacts/Debug/Standalone/Cosimo Synth.appfrom the current worktree. - Do not install the
CosimoSynthtarget output,cosimo_ios_auv3_generated_plugin, or anything undergenerated/cmajor. Those are intermediate build products, not the wrapper app bundle.
- The only iPhone Vite dev server to use is
npm run ios:ui:dev. - The canonical iPhone frontend build command is
npm run ios:ui:build. ios_auv3/vite.config.mjsis the single iPhone Vite config. It must servepatch_gui/index.ios.html,patch_gui/index.ios-host.js, and the live React module atpatch_gui/index.ios.js.ui/ios/runtime-shell.htmlandui/ios/runtime-host.jsare the iPhone host source files.ui/build.mjs --iosgeneratespatch_gui/index.ios.htmlandpatch_gui/index.ios-host.jsfrom them.- The iPhone app bundle must only copy these
patch_guiruntime files: index.ios.htmlindex.ios-host.jsindex.ios.jsresource-client.jswavetable-worker.js- Do not copy the whole
patch_guidirectory into the iPhone app or AUv3 bundle.
- The generated Xcode project does not set
DEVELOPMENT_TEAM. A plainxcodebuilddevice build fails withSigning for "CosimoSynth_AUv3" requires a development team. - On this machine, the working override is personal team
JUFVT28775with automatic signing. The signing identity that Xcode actually used wasApple Development: andrewstern@cox.net (28VA33X8SY). - The exact device build command that succeeded from this worktree was:
xcodebuild -project build/ios_device_run/CosimoSynthAUv3.xcodeproj -scheme CosimoSynth_Standalone -configuration Debug -destination id=00008120-000139383644C01E DEVELOPMENT_TEAM=JUFVT28775 CODE_SIGN_STYLE=Automatic CODE_SIGN_IDENTITY='Apple Development' -allowProvisioningUpdates build- That command created development provisioning profiles for both bundle identifiers:
dev.cosimo.wavetable-synthdev.cosimo.wavetable-synth.wavetable-synthAUv3- The paired phone currently appears under two different Apple tool identifiers:
xcodebuilddestination id:00008120-000139383644C01Edevicectldevice id:00C7F433-8B6A-5CAC-856F-56D7385E12F9
- The install command that succeeded from this worktree was:
xcrun devicectl device install app --device 00C7F433-8B6A-5CAC-856F-56D7385E12F9 'build/ios_device_run/CosimoSynth_artefacts/Debug/Standalone/Cosimo Synth.app'- The standalone app bundle identifier is
dev.cosimo.wavetable-synth. - The launch command that succeeded was:
xcrun devicectl device process launch --device 00C7F433-8B6A-5CAC-856F-56D7385E12F9 dev.cosimo.wavetable-synth
- The iPhone app assets are copied by the
POST_BUILDstep forCosimoSynth_StandaloneandCosimoSynth_AUv3inios_auv3/CMakeLists.txt. - If someone builds the wrong target, the app bundle can be missing
assets/factory-bank-catalog.jsonandassets/factory_sources, which breaks the UI on launch.
- The app bundle should contain:
Cosimo Synth.app/assets/factory-bank-catalog.jsonCosimo Synth.app/assets/factory_sources/
WavetableSynth.cmajorpatchmust keepview.srcset topatch_gui/desktop/index.js.WavetableSynth.cmajorpatchandWavetableSynth.iOS.cmajorpatchare checked-in source files, not generated outputs. If the synth source list, worker path, or view entry changes, edit those manifest files directly.patch_gui/desktop/index.jsis a stable loader. It must default to the local compiled bundle./app.jsand must not be rewritten into a dev-server-only file byui/build.mjs.- The desktop native wrapper lives in
tools/desktop_native. - The canonical compiled desktop build command is
npm run desktop:native:build. - The canonical desktop HMR launcher command is
npm run desktop:native:dev. - If a task changes the desktop UI, the final delivery must include a running standalone dev app unless the user explicitly says not to launch it. Run
npm run desktop:native:devafter the changes, confirm it startshttp://127.0.0.1:5174, and confirm it launchesbuild/desktop_native/CosimoDesktopNative_artefacts/Release/Standalone/CosimoDesktopNative.app. - During desktop UI development, do not claim the standalone app is verified or ready for review unless
npm run desktop:native:devstarted a fresh Vite dev server for this repo, the wrapper was rebuilt against that dev server, and the standalone app was relaunched from that dev session. - During desktop UI development, do not deliver the compiled standalone build as if it were the active development app. If the app is not running against the dev server with HMR, say that explicitly.
- Both commands call
./scripts/build_desktop_native.sh, which writes tobuild/desktop_native. ./scripts/build_desktop_native.shdefaults to the compiled desktop UI.npm run desktop:native:devnow starts the desktop Vite server itself, rebuilds the wrapper indev-servermode, and launches the standalone app againsthttp://127.0.0.1:5174.- The desktop native wrapper chooses
dev-servermode by injectingwindow.__COSIMO_DESKTOP_UI_SOURCE_MODE__andwindow.__COSIMO_DESKTOP_DEV_SERVER_ORIGIN__fromtools/desktop_native/Source/cmaj_PatchLoaderPlugin.cppbefore the loader runs. - If
COSIMO_DESKTOP_UI_SOURCE_MODE=dev-server,./scripts/build_desktop_native.shmust fail unlesshttp://127.0.0.1:5174/patch_gui/desktop/index.jsis reachable. build_assets.pyonly regenerates the derived wavetable runtime catalogassets/factory-bank-catalog.jsonfromassets/factory-table-catalog.json. It must not rewrite either patch manifest.- React Grab for the standalone HMR path lives in
ui/desktop/patch-view-entry.tsx. In Vite dev mode it must importreact-graband@react-grab/mcp/client. The Codex MCP config should usenpx -y @react-grab/mcp --stdio; do not wire the deprecated@react-grab/codexpackage into this repo. - The standalone app only gets React Grab when it is running in
dev-servermode against Vite. The compiled desktop bundle must not load React Grab.
- In Ableton, Cmajor's
WKWebViewcan steal QWERTY Musical Typing input. The working pattern fromChorusLabFocusProbeis: deny WebView keyboard focus by default, allow it only during deliberate text entry, never callresignFirstResponderon theWKWebView, and forwardkeyDown:,keyUp:, andflagsChanged:to the next native responder when text entry is not active.