eeschema's half of the Yjs collaborative bridge, reusing the generic reconciler /
BroadcastChannel transport unchanged. Zero kicad-fork change: native SCH_ITEM uuid +
native SCHEMATIC_LISTENER. All in the wasm layer (wasm/bindings/eeschema_embind.cpp).
Working (verified in the web app):
- kicadCollabSnapshot(): enumerate sch.Hierarchy() -> LastScreen()->Items() as
{id,type,x,y}; registers the listener on first call
- emit: SCHEMATIC_LISTENER subclass -> per-item delta via window.kicadCollab.onDelta;
fires on real SCH_COMMIT::Push (a real wire move broadcasts added/removed/changed)
Apply is a documented follow-up (gated off so a peer tab can't crash): SCH_ITEM::Move
traps with 'indirect call signature mismatch' when invoked outside a KiCad tool
coroutine (Asyncify+fiber+exception-trampoline). Modify/Clone/GetPosition all work;
only the virtual Move write traps. Fix direction: route apply through TOOL_MANAGER.
Also: build-kicad-target.sh now force-relinks when only <app>_embind.cpp changed (the
embind .o isn't a make dep, so new bindings silently vanished), and adds the
expected/rtree/fmt thirdparty includes the eeschema bindings need.
Tests: eeschema-collab.spec.ts covers snapshot (green); apply/two-tab skipped with the
blocker noted. WasmTool gates collab to pl_editor only until eeschema apply works.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bump kicad submodule to the per-item uuid identity change, plus the wasm/test
infra to verify it:
- wasm/bindings/pl_editor_embind.cpp: test-only kicadSaveDrawingSheet(path) hook
that serializes the singleton DS_DATA_MODEL to MEMFS (also a building block for
the bridge's later materialize-to-file path)
- tests/kicad/pl_editor-uuid.spec.ts: open->save->read-back e2e proving (uuid …)
backfill (4 distinct uuids) and load->save round-trip preservation
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add the two newly WASM-ported editors to the web app the same way as the
existing tools:
- pl_editor (drawing-sheet, .kicad_wks): PL_EDITOR_FRAME overrides
OpenProjectFiles, so it gets the generic kicadOpenFile embind hook
(wasm/bindings/pl_editor_embind.cpp) for deterministic open. Mapped
.kicad_wks -> pl_editor in EXTENSION_TOOL.
- symbol_editor (symbol library): SYMBOL_EDIT_FRAME does NOT override
OpenProjectFiles, so it's treated as file-less (boot standalone, opens
libraries via its own UI). Added to FILELESS_TOOLS.
Both boot through single_top.cpp's STARTWIZARD, so both seed config to skip the
first-run wizard (TOOL_NEEDS_CONFIG_SEED) and get a /usr/bin/<binary> argv0.
contract: add to TOOLS, plus a TOOL_LABELS map for friendly names. The project
UI now renders file-less launch links generically from FILELESS_TOOLS and
per-file "Open in <label>" links from EXTENSION_TOOL (auto file-type detection),
so adding a tool needs no UI edits.
Verified in-browser: pl_editor opens a .kicad_wks (renders the sheet),
symbol_editor boots wizard-free; both with 0 console errors.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Brings up KiCad's pagelayout_editor (drawing-sheet editor) in the
browser, to roughly the same "boots, canvas visible, partially usable
in-session" level as the existing pcbnew/eeschema/calculator ports.
Build:
- docker/build.sh: add pl_editor to the unified app dispatch (case,
subdir map, all-loop).
- scripts/kicad/build-kicad-target.sh: add pl_editor to the case;
upstream target name pl_editor under source subdir pagelayout_editor.
- scripts/kicad/build-pl_editor.sh: 7-line thin wrapper matching the
pcbnew/eeschema/calculator pattern.
- tests/scripts/setup-kicad-wasm.sh: copy_app pl_editor.
App glue:
- wasm/stubs/nl_pl_editor_plugin_stub.cpp: no-op SpaceMouse plugin so
pl_editor_frame.cpp's NL_PL_EDITOR_PLUGIN symbols resolve. Mirrors
nl_pcbnew_plugin_stub.cpp.
- tests/apps/kicad/pl_editor.html: browser shell. preRun creates
/home/kicad and FS.chdir there so file dialogs land somewhere
friendly instead of MEMFS root (/dev/, /proc/, etc.).
E2E coverage:
- tests/kicad/pl_editor.spec.ts: 5 tests — smoke (canvas, no abort),
wizard, File menu has Open/Save As, file-dialog folder-navigation
regression, canvas + toolbar metrics.
- tests/e2e/filedialog-folder-nav.spec.ts: wxWidgets-level twin of
the regression test (exercises the underlying widget directly via
the standalone filedialog_test app).
Submodule bumps:
- kicad → feature/pl-editor (WASM gating in pagelayout_editor's
CMakeLists + navlib stub).
- wxwidgets → feature/pl-editor (wxGenericFileDialog::OnOk navigates
into selected directories; wasm/mouse.cpp emits wxEVT_LEFT_DCLICK
via timestamp-based double-click detection — the latter benefits
every wxWidgets-WASM app).
See features/pl-editor/ for the design doc + per-repo diff patches.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Set KICAD_BUILD_3D_VIEWER_WASM=OFF in build script
- Add comprehensive 3D canvas stubs (~500 lines) including:
- EDA_3D_CANVAS with wxWidgets event table
- BOARD_ADAPTER, EDA_3D_VIEWER_SETTINGS
- PANEL_PREVIEW_3D_MODEL with all event handlers
- DIALOG_SELECT_3DMODEL
- TRACK_BALL camera
- BBOX_2D, BBOX_3D, BVH_CONTAINER_2D
- OGL_ATT_LIST::GetAttributesList
- Add 3D scenegraph stubs for VRML export
- Update KiCad submodule with WASM guards
- Update WebGL GAL implementation plan to COMPLETE status
All 4 phases of the WebGL GAL implementation are now complete:
- Phase 1: Native test harness (28 scenarios)
- Phase 2: WebGL GAL implementation (~27,800 lines)
- Phase 3: Complete API coverage
- Phase 4: KiCad integration with 3D viewer stubs
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The idftools/vrml_layer.cpp uses this GLU tessellation constant
which was missing from our WASM GLU stub header.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Changes:
- Add glu_wasm_impl.cpp: GLU tesselator using KiCad's earcut triangulation
- Add GL/glu.h: GLU header for WASM builds
- Add 3D viewer stubs for KICAD_BUILD_3D_VIEWER_WASM=ON
- Remove obsolete gl_canvas_stub.cpp (OpenGL now uses real impl)
- Remove obsolete glu_stub.c (replaced by glu_wasm_impl.cpp)
- Update build-pcbnew.sh comment about GLU implementation
The OpenGL GAL now works in WASM using WebGL with LEGACY_GL_EMULATION.
3D viewer is stubbed out but builds successfully.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Build improvements:
- Change -O0 to -O1 to fix "local count too large" asyncify error
- Add wasm-emscripten-finalize to host (Docker OOMs on large WASM)
- Use -gseparate-dwarf for smaller main binary with debug info
- Build native protoc for code generation
- Add more functions to asyncify removelist
Runtime fixes:
- Add inject-dyncall-shims.sh to fix "dynCall_* is not defined" in Emscripten 4.x
- Update wxwidgets with browserInfo.name fix
New stubs and bindings:
- Add Embind bindings for JavaScript interop
- Add stubs for scripting, API plugin, PCB frame, navlib
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Build the 3D viewer code for WASM instead of stubbing it out.
This is simpler to maintain than complex header stubs.
Changes:
- Enable KICAD_BUILD_3D_VIEWER_WASM=ON in build script
- Remove -gsource-map to avoid OOM in wasm-emscripten-finalize
- Add OpenGL stubs for fixed-function pipeline (WebGL ES 2.0 only)
- Add GLU stub for gluErrorString
- Add NNG stub for IPC API (sockets don't work in WASM)
- Add PCBnew scripting stub
- Expand curl and libgit2 stubs
The 3D viewer code compiles but won't render at runtime since
OpenGL GAL is disabled and Cairo GAL is used instead.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>