This guide is the day-to-day entrypoint for contributors working on kwiver.
It focuses on how to build, test, and change the repository without fighting the current architecture.
For a higher-level system overview, read ../ARCHITECTURE.md. For JS/MoonBit ownership rules, read js-ffi-boundary.md.
The repository currently relies on a small toolchain:
moonfor building, checking, and testing MoonBit packagesnodefor regression scripts and browser smoke testsminiserveor another static file server for local browser preview
There is no package.json in this repository. The checked-in Node scripts use built-in Node modules only.
Build the release runtime artifact into the fixed browser autoload path:
moon build --release --target-dir browser_ui/_buildServe the browser UI directory:
miniserve ./browser_ui --port 8081Then open http://localhost:8081/.
The browser bridge expects the runtime artifact at:
browser_ui/_build/js/release/build/runtime/runtime.js
If you change the build location, the browser bridge will not find the runtime unless you also change the JS loader.
| Path | Owns |
|---|---|
engine/ |
Canonical diagram graph, import/export, UI adapter DTOs, selection-derived state |
geometry/ |
Pure curve/arrow math and render-plan generation |
runtime/ |
Browser-facing runtime/session API and JS export surface |
browser_ui/ |
DOM/UI shell, bridge code, smoke tests, static assets |
scripts/ |
Regression runners, parser corpus sync, upstream scanning helpers |
| Goal | Command |
|---|---|
| Type-check the repository | moon check |
| Run MoonBit tests | moon test -v |
| Build browser runtime artifact | moon build --release --target-dir browser_ui/_build |
| Run full regression | node scripts/local_regression.mjs |
| Run smoke-only regression | node scripts/local_regression.mjs --smoke-only |
| Resync parser corpus generated data | node scripts/sync_parser_corpus_manifest.mjs |
scripts/local_regression.mjs currently runs these steps in order:
- Sync parser corpus manifest data into
engine/tikz_parser_corpus_manifest_data.mbt. - Build the release runtime into
browser_ui/_build. - Run
moon test -vunless--smoke-onlyis used. - Run browser/runtime smoke tests from
browser_ui/tests/.
When in doubt, prefer the full regression script before merging.
engine/ is the canonical owner of diagram structure and dependency semantics.
If a feature changes committed graph state, import/export semantics, selection summaries, or undo/redo inputs, the change should land in MoonBit first and only be exposed to JS through the runtime boundary.
Browser code should prefer runtime/ session/command APIs over reaching into engine/ internals directly.
If you add a browser-visible feature, first ask whether it belongs as:
- a new runtime command
- a richer runtime response payload
- a new pure geometry export
Arrow path generation, clipping, and label positioning should stay deterministic and reusable. Do not move render math back into UI event handlers unless the state is purely transient and browser-local.
The browser UI is still in transition, but new work should reduce JS-side graph ownership rather than expand it. If a JS patch starts duplicating dependency logic or canonical selection reasoning, it is probably being added in the wrong layer.
- Update the relevant MoonBit implementation and
*_test.mbtcoverage. - Run
moon test -v. - If the browser-visible API or serialized payload changed, run
node scripts/local_regression.mjs.
- Keep the change in
geometry/unless it truly affects domain semantics. - Update geometry tests.
- Run at least
moon test -v; run full regression if the browser renderer depends on the output shape.
- Update
runtime/first, then the bridge/tests inbrowser_ui/. - Rebuild the release artifact:
moon build --release --target-dir browser_ui/_build- Run
node scripts/local_regression.mjs.
Source of truth lives in:
browser_ui/tests/parser_corpus_manifest.jsonbrowser_ui/tests/parser.texbrowser_ui/tests/parser_external.texbrowser_ui/tests/parser_external_invalid.tex
After editing any of them:
- Run
node scripts/sync_parser_corpus_manifest.mjs. - Review the generated diff in
engine/tikz_parser_corpus_manifest_data.mbt. - Run
node scripts/local_regression.mjs.
Use this minimal checklist:
- Run the narrowest relevant command while iterating, then run
node scripts/local_regression.mjsbefore merge when the browser/runtime boundary is involved. - Review generated-file diffs instead of blindly committing them.
- Update documentation if the workflow, protocol, or ownership boundary changed.