Commit graph

393 commits

Author SHA1 Message Date
Viktor Vaczi
348596c515 perf(build): use all cores in host builds — wx lib, test apps, gal-webgl
env.sh exports a docker-safe JOBS=1 default, and every host build silently
inherited it (the docker kicad path dodges it by passing -j explicitly):

- build-wx-wasm.sh: the intended "${JOBS:-nproc}" fallback sat BELOW the
  env.sh source, so it was dead code — full wx builds ran make -j1 on the
  Mac and on CI. Compute the all-cores default before env.sh instead
  (explicit JOBS/PARALLEL_JOBS still wins); also -j the PCRE pre-build.
- build-wasm-test.sh: same default fix, plus fan the post-link
  hoist+asyncify loop out across JOBS with xargs -P. Per-app wasm-opt
  can't feed many cores (small modules), so serial stays ~4min even with
  BINARYEN_CORES=16; fanning across the 74 independent apps is what
  scales. Safe: apply-asyncify is in-place per wasm, injector tmp is
  per-js, HOIST_WASMOPT resolved once up front.
- build-gal-webgl-test.sh: make had no -j at all.

Measured on a 16-core M4 Max, clean test-app build: 15m36s (-j1) → 2m08s,
peak RAM 10.7 GB summed across all build processes (64 GB machine; CI
runners have 120 GB). Core counts are always derived from nproc at
runtime — nothing hardcoded, CI workers differ.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XeiSRRScdaox5jBueJNcyG
2026-07-02 10:54:14 +02:00
Viktor Vaczi
616bbbf67c test(screenshots): adopt Linux CI baselines (first re-baseline)
Promote the first green CI run built with the outputDir fix (b270507, run
28572705121) — the run that keeps test-results across the sequential suites.
Overwrites the Mac-rendered baselines with CI's Linux render (churn-free,
verbatim bytes):

- 335 updated  — Mac->Linux font/AA rendering (expected, not regressions)
- 14 added     — new specs (modal, notebook, pcbnew-move, 3d-viewer, dark-mode, ...)
- 7 unchanged  — blank/loading screens identical across platforms

Renders eyeballed (pcbnew / eeschema / wx controls) — all correct UI. From here
the baselines are the Linux source of truth; the next run compares Linux-vs-Linux.

12 stale baselines (renamed specs, e.g. wizard-01 -> wizard-01-loaded) are left in
place pending confirmation — prune separately.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 10:44:40 +02:00
Viktor Vaczi
f49d536f95 fix(build): wx 'zlib.h not found' CI flake — self-heal zlib port + deterministic cache touch
Two fixes for the intermittent wx-build failure on CI (zipstrm.cpp: fatal
error: 'zlib.h' file not found, surviving the serial retry):

- build-wx-wasm.sh: --with-zlib=sys resolves to the Emscripten zlib PORT,
  which only `embuilder build zlib` installs — and that ran only in the
  configure branch. A pre-configured build dir (CI cache) + fresh emsdk
  therefore died on any recompile of a zlib-using TU. Ensure the port
  before every make; --force because embuilder stamps the port on libz.a
  alone, so a half-populated cache would no-op.

- wasm-build.yml: the cache-restore `touch {} +` stamped files ns-apart in
  readdir order; GNU make 4.x compares ns mtimes, so objects touched before
  a generated header they depend on (wx/setup.h, pcre2.h via .deps/*.d)
  recompiled — a random subset per run, which is what made the failure
  flaky. Use one shared timestamp instead: equal mtimes = up to date.

Reproduced + validated locally (remove sysroot zlib.h + one .o → exact CI
failure; with fix, self-heals in 0.5s; Linux make ns/equal-mtime behavior
verified in a container).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XeiSRRScdaox5jBueJNcyG
2026-07-02 09:59:32 +02:00
Viktor Vaczi
b270507505 fix(tests): keep test-results across CI suites; loud pipeline alert
The screenshot report went silent on green CI runs. CI runs four sequential
`playwright test` invocations (wx, asyncify, kicad, perf) that all default their
outputDir to `test-results`; Playwright clears the whole outputDir at the start
of every run, so each suite wiped the previous suite's screenshots. By the time
`compare` ran, only perf-*.json remained -> all 354 baselines read as "removed"
-> the no-render guard stayed silent.

- Gate Playwright's outputDir off test-results/ in CI only
  (process.env.CI ? 'pw-artifacts/<suite>' : 'test-results') in the wx / asyncify
  / kicad configs, so the committed-baseline screenshots (page.screenshot to
  'test-results/...') accumulate in test-results/ across the suites for compare.
  Local single-suite behavior is unchanged.
- post-discord: replace the silent no-render guard with a loud, image-less
  pipeline alert ("No screenshots produced this run") when 0 render; genuine
  partial removals still post as the normal capped REMOVED list.
- gitignore pw-artifacts/; upload tests/pw-artifacts/** as a CI artifact.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 09:20:35 +02:00
Gergő Törcsvári
9b41d7321f feat(site): link the live demo + serve the gerber demo from the versioned CDN
Refer to demo.pcbjam.com from the landing: an accent "Live demo" link in the
header nav, an "Open the live editor" hero link, a note in the gerber section,
and a "Try the live demo now" line in the final CTA.

Rework the embedded gerber viewer (public/gerber-demo/boot.js) to source the
WASM from the deploy pipeline's versioned CDN instead of the hand-synced
assets.pcbjam.com bucket: resolve gerbview's content-addressed folder at runtime
from the release manifest (manifest-latest -> tag -> manifest-<tag> -> gerbview),
load all assets (glue + wasm + images.tar.gz) from cdn.pcbjam.com, and load the
cross-origin pthread worker via a same-origin blob importScripts shim (mirrors
web/standalone/src/wasm/boot.ts). Bump the config-seed KICAD_VERSION_DIR
9.99 -> 10.0 to match the deployed build. Drop the now-obsolete committed glue
mirror and the old assets.pcbjam.com sync/r2-deploy scripts.

Collapse the header nav to the hamburger below 1025px — the added demo link no
longer fits the 1024px-capped bar on a single row.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 07:40:30 +02:00
Viktor Vaczi
13551f4f22 feat(tests): screenshot regression + Discord review, perf-tracked
New tooling in tests/tools/screenshots/ (TypeScript via tsx):
- compare.ts: one pixelmatch engine (AA-excluded), connected-component
  "where to look" boxes, old|new+boxes|heatmap triptych, per-engine floors.
- promote.ts: churn-free updater — overwrite a baseline only when decoded
  pixels differ beyond the floor, copying CI bytes verbatim (no re-encode
  churn); pulls a CI run via `gh run download` or a local --from dir.
- post-discord.ts: always-on CI-on-main report (SHA + e2e status + the
  track-only runtime-perf table), then screenshot triptychs, batched +
  size-capped + flood-collapsed + 429-aware.
- perf-report.ts: perf table with Δ vs the previous main run (via gh).
- changelog.ts: no-build git-history baseline differ (Discord trigger B).
- noise.ts / gen-manifest.ts: calibration + manifest generation.

CI wiring:
- wasm-build.yml: post-test step runs the gate + report on the already-
  produced test-results (no extra build); report-only (continue-on-error),
  posts only on push to main, inert without DISCORD_WEBHOOK_URL.
- ci-ubicloud.yml: secrets: inherit (pass the webhook through).
- screenshot-changelog.yml: ~30s no-build changelog on baseline changes.

screenshot-manifest.json: canonical 354-name set + best-effort engine tags
(313 chromium-swiftshader / 41 firefox-llvmpipe).

Normalize scale:'device'->'css' across 18 spec files (no-op at CI DSF=1)
so committed baselines are uniformly css-scaled.

Design: CI's Linux render is the single source of truth; no pinned
container (accept rare env drift -> re-promote); dev commits via promote.
Replaces the byte-cmp compare-screenshots.sh + file-size-proxy
update-baseline-screenshots.sh (kept for now until the first re-baseline).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 18:17:20 +02:00
Viktor Vaczi
05127af431 docs(hoist): pass-simplification dossier; bump binaryen (FindAll/BranchUtils refactor)
Adds docs/features/hoist-cpp-catches-simplification/ (diagnosis + Layer 1 result) and bumps the binaryen submodule to 1d40cf5a8 (FindAll/BranchUtils refactor + describe-as-is comments of HoistCppCatches). Validated end-to-end: full pcbnew build through the refactored wasm-opt + Firefox pcbnew e2e 6/6.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 16:52:17 +02:00
Istvan Matejcsok
8ff05e137d fix(3d-viewer): resize deadlock — defer GL-window repaint (bump wxwidgets)
Bumps the wxwidgets submodule to the resize-deadlock fix: wx_window_resize no
longer forces a synchronous wxTheApp->Paint() for a window hosting a wxGLCanvas
(the 3D viewer). That synchronous, nested paint ran the multi-threaded CPU
raytracer from inside the resize call and deadlocked when it had to boot an
on-demand pthread Worker — the 236s mouse.move freeze that reddened CI. The GL
window now repaints via the normal event-loop pump, like a camera move, where the
Worker can boot; dialogs keep the synchronous repaint.

Verified locally against a fresh native-EH BUILD_3D_VIEWER=ON build: 3d-viewer.spec
4/4 green with all four tests in ONE shared serial worker (the frozen scenario);
resize 19.9s. CI green end-to-end.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 15:23:07 +02:00
Viktor Vaczi
3e5791774b test(perf): track-only runtime-perf E2E for eeschema + pcbnew
Measures the current build's cold load, open+render, and pan/zoom FPS
(1x/4x/6x CPU-throttle sweep) for both editors, writing
tests/test-results/perf-*.json. Track-only: asserts only that the app booted
and the document opened — no perf thresholds, so it never gates CI.

Runs on a new Chromium `perf` Playwright project (CDP throttling; pcbnew needs
V8 anyway) via `npm run test:perf`, and is wired into wasm-build.yml as a
continue-on-error step so the numbers are captured/uploaded without flaking the
gate. Reuses the existing fixtures, ready-signal, fs-inject, and board-ready
helpers; FPS counter is cancel-able so a throttle sweep on one page doesn't
accumulate rAF loops.

.gitignore: ignore /benchmark-builds/ (disposable prebuilt-WASM + standalone
harness bundle used to reproduce the native-vs-JS-EH comparison locally).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 14:43:54 +02:00
Viktor Vaczi
7eb65f5b6a docs(wasm-eh): add native-EH vs JS-EH runtime benchmark report
Benchmark of the WASM exception migration (native -fwasm-exceptions vs
legacy JS-EH) for eeschema + pcbnew, O1/O2, headed/headless: native-EH is
~22%/26% smaller gzip, ~30-35% faster load, and faster ops/FPS; ship the
post-link wasm-opt tail at -O1, not -O2. Full tables + methodology in the doc.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 14:43:54 +02:00
Gergő Törcsvári
b5ee3da92c
perf(cdn): publish demo WASM as brotli-q11 + no-transform
release.yml's publish-wasm job now uploads .wasm/.js with
`--compress br --quality 11` instead of gzip-6, and IMMUTABLE
content-addressed blobs carry `no-transform` so Cloudflare's edge
can't decompress + re-serve them at its on-the-fly br-4 (and the
original Content-Length passes through).

~15-20% smaller wasm on cdn.pcbjam.com. Forward-only: tool folders
already published stay gzip until their source changes (identity is
hashed over uncompressed bytes, so the compressor switch never
re-versions or re-uploads existing folders).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 12:21:54 +02:00
Gergő Törcsvári
e7640d0a97
build(wasm): standardize asyncify wasm-opt tail to -O1 everywhere
The Binaryen wasm-opt shrink after Asyncify was the only -O2 in the
pipeline: -O2 by default (local + tag release) but -O1 in main CI. The
C++/wx/deps compile is already -O1 everywhere (DEBUG_BUILD defaults to 1;
nothing passes --release in CI/release). Pin the tail to -O1 too:

- apply-asyncify.sh: BINARYEN_OPT_LEVEL default -O2 -> -O1
- release.yml: opt_level -O2 -> -O1 (demo now ships -O1)
- ci-ubicloud.yml / wasm-build.yml / docker/build.sh: refresh stale -O2 comments

Because both callers now build at -O1, the FINAL cache key converges, so a
tag release FINAL-cache-hits main's build and skips the asyncify-tail
rebuild entirely (previously the ~1-2h -O2 wasm-opt was rerun per release).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 12:18:57 +02:00
Gergő Törcsvári
89a433fda9
fix(trace): make ?trace= work by merging Module.ENV in the glue
The emscripten glue's `var ENV = {};` never merged Module.ENV, so boot.ts's
Module.ENV.KICAD_TRACE was a silent no-op — and since environ_get on a pthread
proxies to the main thread, the app/UI thread's getenv read the (empty) main
ENV. Net: KICAD_TRACE never arrived and every KI_TRACE was a no-op.

scripts/common/patch-env-shim.mjs post-processes each generated <app>.js to
merge Module.ENV into ENV (idempotent; runtime no-op when unset), wired into
docker/build.sh's per-app host post-process next to the dyncall-shim inject.
Replaces a fragile manual glue edit re-applied after every build. Verified:
symbol-editor eager load now emits KI_TRACE_SYM_CHOOSER fatLoad timing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 11:01:10 +02:00
Gergő Törcsvári
88aaba99c9
feat(libs): react load overlay + progress bar; mimalloc mallinfo stub; framed tests
- WasmTool/source.ts: LIB_LOADING_EVENT brackets the fat-load; full-cover
  overlay ('Loading <kind> libraries…') with a per-lib progress bar (done/total
  from listLibs), show-on-first / hide-after-last coalescing.
- mallinfo stub (wasm/shims/mallinfo_stub.c + build-kicad-target.sh): -sMALLOC=
  mimalloc doesn't export glibc mallinfo() that OpenCASCADE OSD_MemInfo (pcbnew
  3D) needs; zeroed no-op unblocks the pcbnew link.
- source/cdn-source tests: updated to the framed Uint8Array 'bodies' contract.
- bump kicad -> e8db3d3.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 09:56:32 +02:00
Gergő Törcsvári
4025b05218
feat(libs): parallel s-expr parse + mimalloc + copy-as-is transport — symbol chooser cold 274s→44s
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 07:58:30 +02:00
Gergő Törcsvári
ffd1cb1fc3
wip: symbol chooser load — no-clone enumerate + KI_TRACE instrumentation + ?trace= harness
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 20:08:57 +02:00
Viktor Vaczi
71807db734 feat(wasm,3d-viewer): run upstream multi-threaded CPU raytracer
Bumps the kicad submodule to the threading revert (the 3D-viewer raytracer's
WASM single-threaded #ifdef fallbacks + the bs_thread_pool inline shim are gone;
those four files are now byte-identical to upstream KiCad).

Links wasm/shims/nanosleep_yield.c into every app (mirrors the gl_ffp_stub
pattern): the now-upstream raw-thread raytracer joins via a main-thread
sleep_for busy-wait, and this shim makes that nanosleep Asyncify-yield to the JS
event loop instead of deadlocking on on-demand pthread-Worker creation. Its
EM_ASYNC_JS yield is already covered by env.__asyncjs__* in asyncify-imports.txt.
This is what lets upstream's multi-threaded code run on WASM under native-EH.

Also documents isolated-worktree + submodule-branch creation in the README.

Result: ~11x faster 3D raytrace (21.3s -> 1.9s, 16 threads), pixel-correct
render, full kicad e2e green (63 passed / 0 failed).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 18:17:56 +02:00
Istvan Matejcsok
3628a090dd feat: 🎸 wxWidgets dialog/frame header/drag/resize 2026-06-30 15:46:52 +02:00
Istvan Matejcsok
cf1fdf5c3d feat: 🎸 wxWidgets dialog/frame DOM header 2026-06-30 15:46:49 +02:00
Viktor Vaczi
917d03c22f fix(wasm-eh): native-EH link flags for the GAL WebGL test app
The native-EH migration left tests/gal-regression/wasm/Makefile on the old
Emscripten JS-exception model (-sNO_DISABLE_EXCEPTION_CATCHING, no
-fwasm-exceptions). The wxWidgets libs it links are now built with
-fwasm-exceptions, so wasm-ld couldn't resolve __cpp_exception / __c_longjmp and
the "Build GAL WebGL test app" CI step failed. This was masked until now because
the host post-process (finalize) bug killed every run before this step ran.

Compile and link with DEPS_EH_FLAGS (-fwasm-exceptions -sSUPPORT_LONGJMP=wasm
-sWASM_LEGACY_EXCEPTIONS=1), honoring the value build-gal-webgl-test.sh exports
via env.sh with a Makefile ?= fallback — matching the wxWidgets test-app build.
Drop the now-incompatible -sNO_DISABLE_EXCEPTION_CATCHING.

Verified locally: ./scripts/build-gal-webgl-test.sh links clean against the
native-EH wx libs and produces gal_webgl_test.{js,wasm}.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 13:25:00 +02:00
Viktor Vaczi
714b0a816b fix(wasm-eh): build wasm-emscripten-finalize from the Binaryen submodule (unbreak CI)
The native-EH migration pointed apply-finalize.sh at emsdk's bundled
wasm-emscripten-finalize (${EMSDK:-tools/emsdk}/upstream/bin), which exists on a
dev machine (tools/emsdk persists from a prior build) but never on the ephemeral
CI host — emsdk lives only inside the Docker image, and nothing on the host
post-process path provisions it. So the host post-process died at finalize for
every app once the binaryen-SHA cache re-key forced it to actually run. (Not the
missing-ninja theory — ninja was installed; the run never reached the wasm-opt
build, which is downstream of finalize.)

Finish the "Binaryen submodule everywhere" migration: build-wasm-opt.sh now also
builds wasm-emscripten-finalize, and apply-finalize.sh takes it from that build
(next to wasm-opt). The host post-process is now emsdk-free (dyncall=node,
finalize+asyncify=submodule v130) and finalize/wasm-opt share one Binaryen
version (previously finalize was emsdk's v121, wasm-opt the submodule's v130).
get-wasm-opt.sh stays for bench only; dropped it from the wasm cache key and
added build-wasm-opt.sh.

Also surface the from-source Binaryen build as a "Build Binaryen" stage in
build-monitor.sh (it had no marker), emitted at the pipelined pre-warm sites.

Validated: a clean from-scratch `docker/build.sh calculator --build-deps` (deps +
compile + finalize via the submodule binary + asyncify + -O2) succeeded
end-to-end; finalize resolved to build-wasm/tools/binaryen-hoist-build/bin.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 11:55:52 +02:00
Gergő Törcsvári
c7d7189c65
docs(git-workflow): add binaryen to git-feature SKILL.md instructions
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 10:21:16 +02:00
Gergő Törcsvári
6414036580
chore: add binaryen submodule to git-workflow
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 10:06:34 +02:00
Gergő Törcsvári
269449da46
fix(collab): dedupe yjs so @pcbjam/shared + standalone link ONE instance
Two pnpm workspaces (root globs pcbjam-shared; pcbjam/web has it too) each install yjs, so shared's collab code (kicad-y) and the app's yjs were two physical copies → a Y.Map rejects the other instance's Y types ('Unexpected content type'). resolve.dedupe:['yjs'] in vite + vitest forces a single copy. Not a test-only artifact: the same two copies bundle into the editor and would break collab on doc seed. Full standalone suite now 55/55 (was 47/55).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 09:54:50 +02:00
Gergő Törcsvári
fe0bec9909
feat(scopes): migrate GPL open backend + web e2e to scope grammar
backend-example (open ref backend): USER_HEADER, scope on the project DTO, raw routes under /api/scopes/:scope, no-op reportDrift + DOM lib (was red on main → now typecheck-green). GPL web specs (tools-open, symbol/footprint-write-remote, global-setup-web): /p/demo/:tool/* → /:scope/projects/demo/(file | -/:tool), direct API fetches scoped + x-pcbjam-owner → x-pcbjam-user. Reference backend keeps lib type 'user' (cosmetic vs closed 'org').

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 09:54:50 +02:00
Gergő Törcsvári
ff9b966109
docs(site): dev blog updates (w26 + webgl-porting post)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 09:54:50 +02:00
Gergő Törcsvári
344a36799a
chore: add dev:demo script (web) + refresh site lockfile
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 09:54:49 +02:00
Gergő Törcsvári
7bc5260bc7
fix(scopes): standalone project list label showed old /p/<slug> instead of scope/projects/<slug>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 09:54:49 +02:00
Gergő Törcsvári
234e5fe189
feat(scopes): phase 0003 — standalone scope routing, tool inference, scoped API client, Demo/Local/Cloud badges
Routes → /:scope/projects/:name/* (+ -/:tool) and /:scope/libs/:name; tool inferred from file ext / lib kind (?tool= override); currentScope()/userSlug() in config; SCOPE/USER headers + scoped paths through project + libs sources; @local/demo scopes on constructed projects; badge relabel (drop scary read-only).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 09:54:49 +02:00
Gergő Törcsvári
e28e5e8e57
chore: bump pcbjam-shared (scopes 0001 — shared scope grammar)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 09:54:49 +02:00
Viktor Vaczi
c1ef489cfa feat(wasm-eh): migrate the WASM build to native wasm exceptions (+ 3D viewer default-on)
Replace the legacy Emscripten JS-exceptions model with native wasm-EH (legacy
encoding) across the whole build, keeping Asyncify coroutines working via a
from-source Binaryen --hoist-cpp-catches pre-pass. Net result: native-EH is the
only build mode, the 3D viewer is on by default, and pcbnew shrinks substantially.

Highlights:
- Binaryen submodule everywhere + --hoist-cpp-catches integration in apply-asyncify;
  post-link Asyncify covers every app wasm (not just standalone test wasm).
- Build deps (incl. OpenCASCADE without OCC_CONVERT_SIGNALS) and all KiCad apps
  with -fwasm-exceptions; emscripten_sleep added to the post-link asyncify-imports.
- libcontext fiber entry wired under native exceptions; while-loop main loop +
  currData shim injected into all wx apps.
- Native-EH collab apply fixed: DEBUG-define the embind TU + match all out-of-CMake
  C++ TUs' ABI flags to the core, fixing the vtable-layout skew / mis-dispatch.
- 3D viewer enabled by default (real raytracer linked, not the stub).
- Retire the EH-spike scaffolding; flip the asyncify-races ablation pins to
  shim-redundancy pins (native-EH stays clean with the legacy shims ablated).
- Fix the asyncify-races quiescence check to not require Asyncify.currData==0:
  under the native-EH per-frame-yield top loop the main stack is asyncify-suspended
  every frame, so currData legitimately churns (a freed-but-not-yet-nulled buffer,
  not a leak). Refresh the pcbnew toolbar screenshot baseline for the new kicad.
- CI: drop the obsolete binaryen_version input/env (the build uses the binaryen
  submodule fork's wasm-opt, not a version download); key the wasm-output cache on
  the binaryen submodule SHA instead.

Bumps the wxwidgets + binaryen submodules to their squashed feature commits.

Validated green: all 7 apps native-EH (real 3D in pcbnew); KiCad e2e 63/63
Firefox + Chromium (3D viewer renders); wx 336; coroutine 34/34 both engines;
asyncify 7/7 both engines.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 09:40:26 +02:00
Istvan Matejcsok
b8c8dee355 fix(wasm): blank foreign-editor Preferences pages
Bump kicad to the KiFACE()-returns-nullptr fix so eeschema's Preferences
stops showing blank Footprint/PCB/3D/Gerber panels for editors not present
in a single-app build.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 12:56:25 +02:00
Istvan Matejcsok
13cac06778 fix(wasm): radio groups no longer merge into one
Bump wxwidgets to the %p->%zu radio-group name fix and add a standalone
wxWidgets harness plus an e2e regression that asserts three radio groups
in one window select independently. Build artifacts are gitignored; only
radiogroups_test.cpp is tracked.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 12:54:35 +02:00
Gergő Törcsvári
39cb04b127
feat(standalone): demo follow-ups — waitlist, analytics, move-to-local, file tree, load progress
- Waitlist signup form on the home page (between Projects and Tools),
  cross-posting to the landing site's /api/waitlist (CORS + OPTIONS added there,
  gated by WAITLIST_ALLOWED_ORIGINS).
- Version badge gains a pcbjam.com landing-page link (VITE_LANDING_URL).
- Optional Plausible analytics from VITE_PLAUSIBLE_DOMAIN (off by default);
  wired into build-demo + both deploy workflows via vars.PLAUSIBLE_DOMAIN.
- Opening a read-only gallery project auto-"moves to local": it forks into a
  writable browser-local project at the same slug, shadowing the gallery row.
- Project + local-folder views use the same iconed tool launcher (ToolGrid)
  and a navigable directory FileTree instead of a flat file list.
- Boot overlay shows real wasm download progress (Module.instantiateWasm +
  streaming byte counter) and a "taking too long" state after 60s.
- Home Libraries section lists the active libs source (the read-only R2/CDN
  set in the demo) with a name filter; useLibs now reads libsSourceConfig.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TPJYx4urFVhdMjEmYfMCMD
2026-06-27 07:59:09 +02:00
Gergő Törcsvári
6c6f889ef5
chore: bump kicad (lazy footprint load fixes pcbnew WASM boot hang)
Bumps kicad submodule fef0343 -> 9285d52:
- fix(wasm): lazy footprint library load — no-op enumerateLibrary + on-demand
  GetFootprints (mirror of the symbol lazy-load). Fixes the standalone PCB
  editor never opening: boot enumerated every global footprint library inline
  on the main thread (each a CDN fetch + parse) before first paint, freezing
  the tab. Footprints now load on demand (Add-Footprint chooser / footprint
  editor tree). eeschema was already lazy; footprint editor boots faster too.

Verified in the local demo: PCB editor and footprint editor both render; the
Add-Footprint chooser lists all ~222 libraries with footprint content fetched
on chooser-open, not at boot.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Eu9CbU7EybM8NEjDZD3hq7
2026-06-26 18:25:43 +02:00
Gergő Törcsvári
a77f7ae346
fix(standalone): bump KICAD_VERSION_DIR 9.99 -> 10.0 so seeded lib tables are read
After the kicad fork was rebased onto KiCad 10.0.4, GetMajorMinorVersion() (and
thus PATHS::GetUserSettingsPath()'s version subdir) became "10.0", but the
standalone still seeded the global sym-lib-table / config under
~/.config/kicad/kicad/9.99/. The WASM read .../10.0/ and found nothing, so
LIBRARY_MANAGER loaded 0 symbol-table rows and the Add Symbol / Add Power
choosers came up empty ("0 items loaded") with no library list requests.

Aligning KICAD_VERSION_DIR with the build's version makes the chooser load all
222 CDN libraries (19,779 symbols) again. Verified in the local demo against live
R2 (libs/kicad/10.0.3). The footprint editor / pcbnew read the same dir, so this
fixes their libraries too.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 13:50:55 +02:00
Gergő Törcsvári
e8d964d871
feat(demo): local dev-demo runner — R2 libs + example gallery, no backend/partykit
scripts/deploy/dev-demo.mjs (+ `pnpm dev:demo`) is the dev sibling of
build-demo.mjs: it runs the standalone via `vite dev` in the no-backend demo
configuration so a local WASM build can be exercised against the live R2 CDN.

  - libraries: live R2 CDN (VITE_LIBS_SOURCE=cdn, libs/kicad/<lib-tag>, default
    10.0.3) — IDB-cached, read-only; the lazy/fat lib-load path
  - projects: the read-only example gallery (deploy/demo/gallery.json → the same
    "Demo Board") built locally via publish-content.mjs and served same-origin at
    /content/<gallery-tag>/; --content-tag pins the live CDN gallery instead;
    --no-gallery falls back to local-folder + IDB only
  - no partykit (VITE_YJS_PROVIDER=broadcastchannel), no REST backend
    (offline.invalid → local-folder loader), browser-local IDB projects
  - WASM: local fresh build at /wasm (default) or --wasm r2

The generated gallery (public/content symlink, web/standalone/.demo-cdn) is
gitignored, mirroring the public/wasm dev symlink.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 08:16:43 +02:00
Gergő Törcsvári
d6ce380458
fix(wasm): add MODEL_SUBSTITUTION no-op stub for 3D-disabled pcbnew/footprint build
Provides wasm/stubs/model_substitution_stub.cpp — no-op IsWrlExtension /
STEP_CATALOG::Build / FindMatchFor — so pcbnew and footprint_editor link when the
3D viewer is off (KICAD_BUILD_3D_VIEWER_WASM=OFF). The KiCad 10 rebase made
dialog_migrate_3d_models.cpp reference these, which live in the unlinked 3D
library. The browser build has no 3D viewer, so model migration finds no
substitutions. Bumps kicad to the matching CMake wiring (fef0343).

Verified: pcbnew + footprint_editor compile and link clean (eeschema/symbol_editor
unaffected).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 08:14:47 +02:00
Gergő Törcsvári
30645dbae5
feat(libs): fat-list provider + getAllItems + parallel lib pre-sync; re-land onto KiCad 10 wasm-port
Replays the symbol-editor fast-lib-load work after the kicad fork was rebased
onto KiCad 10.0.4 and wasm-port was force-pushed. Carries the standalone libs
TS code (fat-list provider, getAllItems, parallel lib pre-sync) and bumps the
submodule pointers to the re-applied tips:

- kicad      -> c63009046 (lazy load on expand + chooser preview + fat-load enumerate)
- wxwidgets  -> 5d40228   (flush events + repaint after modal button click)
- pcbjam-shared -> c6a7e00 (bulk readAll for fat-load lib warm-up)

The 824e8cc build-kicad-target.sh sym-converter-contamination fix is omitted:
the KiCad 10 integration (ce344da) already pins KICAD_SYM_CONVERTER_WASM=OFF for
non-sym_convert targets. Verified: eeschema WASM kiface compiles + links; libs
unit tests 10/10.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 20:31:25 +02:00
Istvan Matejcsok
ce344da2dc upgrade: ⬆️ bump kicad 2026-06-25 09:57:42 +02:00
Istvan Matejcsok
a7cdafbb39 upgrade: ⬆️ bump kicad + wxwidgets 2026-06-25 09:33:04 +02:00
Istvan Matejcsok
40629fe9b5 test(eeschema): drop obsolete test.fail on crosshair cycle
The crosshair toolbar group-cycle (ACTION_TOOLBAR::onToolEvent) was
expected-to-fail because the kicad submodule was a pre-10.0 (9.99.0)
snapshot that lacked it. The KiCad 10.0.4 rebase on this branch restores
the behavior, so the test now passes and Playwright flagged it as
"Expected to fail, but passed". Remove the test.fail annotation as the
test's own comment instructed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 10:31:22 +02:00
Istvan Matejcsok
ddd2c4f5cc fix(test): match KiCad 10 FONT::Draw signature in gal-webgl stub
KiCad 10.0.4 added two trailing optional params (std::optional<VECTOR2I>
aMousePos, wxString* aActiveUrl) to the out-of-line FONT::Draw declaration
in font/font.h. The hand-written stub in the GAL WebGL test app still
declared the old 6-arg form, so it matched no declaration and failed the
CI "Build GAL WebGL test app" step. Update the stub signature to match.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 10:30:25 +02:00
Istvan Matejcsok
cdaa96250d fix(wasm): KiCad 10 kiplatform/libgit2 stubs, e2e fixtures, asyncify -g hook
- wasm/kiplatform: add EnableDarkMode, IO::TimestampDir, UI::AllowNetworkFileSystems,
  UI::CancelPendingScroll, SECRETS::DeleteSecret (new KiCad 10 functions).
- wasm/stubs/libgit2_stub.c: ~156 no-op stubs for KiCad 10's restructured git
  backend + git-backed local history + text_eval VCS.
- tests/kicad: bump the demo project dir 9.99 -> 10.0 (KiCad 10 stores projects
  under /home/kicad/documents/kicad/10.0/) — fixes load-pcb + 3d-viewer e2e.
- scripts/common/apply-asyncify.sh: ASYNCIFY_EXTRA_OPTS hook (e.g. -g for
  symbolizable wasm traces).
- kicad submodule -> ef00c2d3 (KiCad 10 link + runtime adaptations).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 10:30:25 +02:00
Istvan Matejcsok
3e3e97aec7 wasm-port-rebase: KiCad 10.0.4 rebase + WASM build adaptations
Root-side changes for the wasm-port-rebase work:
- kicad submodule bumped to wasm-port-rebase (43-commit rebase onto KiCad 10.0.4
  + the KiCad-10 WASM source adaptations)
- wasm/kiplatform/policy.cpp: GetPolicyEnumUInt -> std::optional (KiCad 10 API)
- wasm/stubs/api_plugin_stub.cpp: API_PLUGIN_MANAGER signature sync (KiCad 10 API)

Compiles 100% for pcbnew (3D viewer on, -O1); WASM link + e2e parity still pending.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 10:30:25 +02:00
Istvan Matejcsok
129f9496ce fix: 🐛 init window context unconditionally in setWindowRect 2026-06-23 16:15:03 +02:00
Istvan Matejcsok
a4dd0eaf3b fix: 🐛 wxWdigets popup position 2026-06-23 14:32:38 +02:00
Istvan Matejcsok
6493f8fe00 fix: 🐛 remove css duplication 2026-06-23 13:00:08 +02:00
Istvan Matejcsok
c35005589d refactor(cmake): batch F (gerbview/pl_editor #5 + navlib #6) + docs
Bumps kicad to 6f82742e68 (in-place CMake de-dup pass A-F complete) and updates
the fork-cleanup docs: CMake churn 1,702 -> 1,019, build-graph proven byte-identical
pre/post (zero behavior change), only Phase-B cmake/wasm relocation remaining.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 18:50:08 +02:00
Istvan Matejcsok
a3478fe3a5 refactor(cmake): de-churn batches A-E (fork-cleanup doc 02)
- KICAD_WASM_LAYER cache var replaces 25 ${CMAKE_SOURCE_DIR}/../wasm reach-outs
- pcbnew Python install: wrap-and-reindent -> early-return guard
- list(REMOVE_ITEM) for PCBNEW_IO_LIBRARIES (cache-FORCE), eeschema importers, GAL_SRCS
- add_shader redefined via wasm/cmake/WasmShaderOverride.cmake (upstream calls reused)
- additive BUILD_KIWAY_DLL property overrides; api kiapi type var
- pcb_calculator whole-file fork -> wasm block + guarded native body

Upstream-byte-identical where possible. WASM build + e2e (9/9, -O1) verified.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 18:50:08 +02:00