New
+wasm32-wasip1 unit and the std module are compiled with WebAssembly exception handling in its standardized form (exnref), against the exception-enabled libc++ the sysroot ships under lib/<triple>/eh/, and -lunwind and -lsetjmp are linked automatically, so throw and catch, libc++'s own throws, setjmp and longjmp all work. The Flatpak's WASI sysroot is built with those libraries. A page from EnableWasiBrowserRuntime probes for the feature and names what an older browser lacks instead of failing with a CompileError.cfg.scripts; crafter-build run <name> [args...] runs it with everything after the name handed over untouched, a bare run lists the scripts, and the callback's return value is the exit status. ScriptContext gives it the project, the project directory, the arguments and Run(command), which runs a shell command with the terminal attached. Crafter::ShellQuote is exported. Only the scripts of the project crafter-build was pointed at can be run, never a dependency's.AGENTS.consumer.md beside its project.cpp; crafter-build and crafter-build test keep its dependencies' notes in a marked section of a consumer's AGENTS.md, when the consumer has one, and never create the file. cfg.dependencyNotes picks the dependencies: Transitive (the default), Direct or None, which also removes the section.EnableWasiBrowserRuntime, exit and _Exit end the program without running any of its code on the way out, no destructor and no catch (...), with the status in window.crafter_wasi.exitCode. A program that hands the thread to the browser for good and goes on serving calls imports crafter_runtime.park instead, which never returns and leaves main's locals valid for the calls that follow.x86_64-w64-mingw32-gcc on PATH, through CRAFTER_MINGW_DIR naming another prefix, and inside the Flatpak through the host's /usr when it has mingw-w64. Its std module comes from the toolchain's own libstdc++.modules.json, and a toolchain that is not there is a build error saying where it looked, not std::terminate.Fixes
+#pragma crafter dependency tools, with the same args, got the tool's copy back: host tooling with -march=native and -fPIC, whose BMI clang then refused. Host tooling and everything it loads are now kept apart in the project cache.crafter-build format clean formats the rules matching "clean"; it used to delete bin/ and build/ and exit 0.-- ends crafter-build's options, as the help has advertised: every later word is an operand of the verb. It used to be forwarded as a project arg and change the variant hash, and the words after it were still read as options.ProjectDependency() works from a static initialiser of a project file; it used to find nothing there and terminate the process.Breaking
+-fno-exceptions, -flto in compileFlags or linkFlags, and shared libraries, each with a message that says why; there is no switch back to building without exceptions. The result runs on engines with exnref: Chrome 137, Firefox 131, Safari 18.4 and wasmtime 47 or newer (the bundled one qualifies; an older wasmtime needs -W exceptions=y). An exception that escapes main ends the program as an uncaught WebAssembly exception without calling std::terminate, so catch it in main to report it. The flags are part of the variant hash, so the first wasm build after updating starts in a fresh directory.GitProject or LocalProject without .args now receives the args its loading project.cpp was given, so --target=, --march=, --debug and the project's own flags reach every sibling down the chain; releases up to 2.2.0 forwarded nothing. Set .args = {} to keep the old behaviour, and give every sibling the same list: a project that two paths load with different lists now stops the build. The default is read when the spec is made, so make it inside CrafterBuildProject; a spec made at namespace scope forwards nothing. A #pragma crafter dependency still gets none of the project's args.A Shader entry can carry defines, spelled like the compiler's -D (NAME is defined to 1, NAME=VALUE to VALUE), and a variant that names its output, so one source compiles into several outputs: ui.comp.glsl with variant sets becomes ui.comp.sets.spv. A configuration in which two entries share an output name is refused with both named, as are a malformed define and a variant with a path separator.