| Filename | Latest commit message | Latest commit date |
|---|---|---|
Add kicadCollabSnapshotItems / kicadCollabApplyItems / window.kicadCollab.onItems
to pl_editor, eeschema, pcbnew — per-item native-blob payloads
({added/changed:[{sexpr,parent}], removed:[uuid]}) alongside the untouched scalar
wire (legacy collab specs stay green).
- pl_editor: itemBlob per item; apply = SetPageLayout(append) + replace-by-uuid
(pointer-snapshot safe); bare payloads get the kicad_wks envelope. Snapshot +
apply + emit verified headless.
- eeschema: clipboard Format per item (symbols carry their lib_symbols); apply
mirrors the native paste — LoadContent into a throwaway sheet → detach →
replace-by-uuid → symbol lib relink (blob's lib_symbols first, live screen's
second) → SCH_COMMIT, in the CallAfter+COROUTINE context. Snapshot + apply
verified headless (a "lost" lone junction turned out to be correct connection
cleanup — test uses text).
- pcbnew: blobForItem per ROOT item with child→footprint lifting in flushDiff;
apply = makeFromBlob + commit replace-by-uuid on the fiber; bare non-footprint
payloads get wrapInBoardEnvelope (live board layer table). Snapshot + footprint
replace/add WITH children (the 0004 containment gap, closed) + removal verified
headless. Track/via/zone/text blob-apply hits the documented asyncify-fragile
envelope parse (reconfirmed empirically — a verbatim SaveSelection segment
envelope dies silently in the commit) and stays on the legacy scalar apply;
tracked in ysync 0008 status.
- eeschema/pcbnew scheduleFlush now runs flushDiff inside a COROUTINE: the
per-item Format in the v2 emit needs the fiber stack (0007 lesson). Their emit
remains unverifiable headless (both legacy two-tab tests are test.skip:
"open=false → SCH_COMMIT no-ops" / "harness can't PAINT") — verify in the real
app at Stage D; pl_editor's emit IS verified.
- tests/kicad/items-bridge.spec.ts: per-tool suite (snapshot uuids → local-edit
emit (where drivable) → apply changed/added/removed via save-readback → no
apply echo). 3/3 pass; roundtrip + collab suites unaffected.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
||
| .. | ||
| backend | ||
| pcbjam-shared@9cfea4184b | ||
| standalone | ||
| .env.example | ||
| .gitignore | ||
| package.json | ||
| pnpm-lock.yaml | ||
| pnpm-workspace.yaml | ||
| README.md | ||
| tsconfig.base.json | ||
| turbo.json | ||
PCBJam Web — standalone editor (GPL)
A self-contained, GPL web app that opens KiCad projects in the WASM tools
(pcbnew / eeschema / pl_editor / …) — from a local folder, or from any backend
that implements the MIT @pcbjam/shared contract. It opens a
tool by URL:
/p/<project>/<tool>/<file-path> e.g. /p/demo/pcbnew/nyak.kicad_pcb
This workspace contains only the generic editor and a thin reference backend. All project-specific concerns (accounts, project management, uploads, auth) live in the separate closed application, which reuses this editor by hosting it standalone and redirecting to it (it must not link the GPL editor).
Layout
web/
├── standalone/ # @pcbjam/standalone — the GPL editor (Vite + React)
├── backend/ # @pcbjam/backend-example — thin reference @pcbjam/shared impl
└── pcbjam-shared/ # @pcbjam/shared — the FE↔BE contract (git submodule, MIT)
- Editor: Vite + React + TypeScript. Boots a tool directly in the document (no iframe), syncs the project tree into MEMFS, drives File→Open, and runs same-tab collaboration over BroadcastChannel.
- Example backend: Fastify + ts-rest serving a single project off the local
filesystem (
PROJECT_DIR). No DB, no auth, no uploads — the minimum the editor needs, and a worked example of the contract.
Quick start
cd web
pnpm install
git submodule update --init web/pcbjam-shared # if not already populated
cp standalone/.env.example standalone/.env
cp backend/.env.example backend/.env # PROJECT_DIR=../../tests/fixtures/demo
pnpm dev # turbo: backend :3060 + editor :3048
Open http://localhost:3048 — either open a local folder (no backend needed)
or open the backend's project. The editor can point at any conforming backend
via VITE_API_BASE_URL.
WASM artifacts
The runtime artifacts (<tool>.js/.wasm, wx.js, images.tar.gz, <tool>.html)
are build outputs, not committed. They are synced into tests/apps/kicad/ by
tests/scripts/setup-kicad-wasm.sh (from repo-root output/).
They must be served same-origin as the app. Under the document's COEP /
cross-origin-isolation (set by the Vite dev server), KiCad WASM refuses to load
its glue/wasm from a different origin. pnpm dev runs scripts/link-wasm.mjs,
which symlinks standalone/public/wasm → tests/apps/kicad; Vite serves them
at /wasm. VITE_WASM_ASSET_BASE_URL defaults to /wasm.
- Point the symlink elsewhere with
WASM_SRC_DIR=/path pnpm --filter @pcbjam/standalone link-wasm. - If a tool won't load, the target dir is probably empty — run
tests/scripts/setup-kicad-wasm.shto populatetests/apps/kicad/. - prod: point
VITE_WASM_ASSET_BASE_URLat a URL whose origin also satisfies the same-origin / COEP constraints.
Scripts
| Command | What |
|---|---|
pnpm dev |
editor + example backend (turbo) |
pnpm build |
build all packages |
pnpm typecheck |
typecheck all packages |
Contract (@pcbjam/shared, MIT)
The editor reads from a backend over the shared contract:
GET /api/projects, GET /api/projects/:project,
GET /api/projects/:project/files, and the streamed
GET /api/projects/:project/files/* (raw bytes). Management/write operations and
ownership are not part of this contract — they belong to the closed app.