|
1 | | -# CLAUDE.md |
2 | | - |
3 | | -This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
4 | | - |
5 | | -## Project overview |
6 | | - |
7 | | -Browser-only RDF graph editor (no backend/server): a React + React Flow canvas on top of an |
8 | | -in-browser Python RDF engine. All RDF parsing, SHACL validation, and graph mutation happens in |
9 | | -Python (rdflib/pyshacl), running client-side via PyScript/Pyodide — the two toolchains are |
10 | | -connected through a JS↔Python bridge, not parallel/unconnected. |
11 | | - |
12 | | -Hosted at https://ld4p.github.io/graph-editor/, deployed via `.github/workflows/deploy-pages.yml`. |
13 | | - |
14 | | -## Architecture |
15 | | - |
16 | | -- `public/py/rdf_service.py` — the RDF engine. Holds the single in-memory `rdflib.Graph`, |
17 | | - undo/redo history, and all mutation functions (add/delete/rename node, add/delete edge, |
18 | | - add/update/delete property, SHACL validation, namespace management). Every mutating function |
19 | | - snapshots history first, then returns `_project(graph)`: a plain-dict `{nodes, edges}` |
20 | | - projection of the graph for the UI. When run under PyScript, functions are registered on |
21 | | - `sync.*` so JS can call them directly. |
22 | | -- `src/lib/pyBridge.ts` — lazily boots the Pyodide worker (via PyScript's `PyWorker`, loaded |
23 | | - from `public/py/pyscript.toml`) and exposes typed async wrappers around each `sync.*` function. |
24 | | -- `src/model/rdfGraphModel.ts` — TS types mirroring the Python projection shapes |
25 | | - (`RdfProjection`, `RdfNode`, `RdfEdge`, SHACL/namespace result types). |
26 | | -- `src/state/graphStore.ts` (zustand) — holds the current projection, node positions, selection, |
27 | | - and undo/redo status; `setProjection` also fires autosave to `localStorage`. |
28 | | -- `src/lib/layout.ts` — lays out the projection as React Flow nodes/edges, with either the |
29 | | - force-directed layout (default) or dagre, chosen by `layoutMode` in the store. Manually-dragged |
30 | | - positions from the store are always kept. |
31 | | -- `src/lib/forceLayout.ts` — Springy-style force simulation used by the default layout. CBD groups |
32 | | - stay clustered, an overlap pass keeps cards and group boxes apart, dragged nodes stay pinned, and |
33 | | - each run warm-starts from the previous `settled` positions (kept in `GraphCanvas`) so edits |
34 | | - don't reshuffle the graph. |
35 | | -- `src/components/` — `GraphCanvas.tsx` (React Flow canvas), `ResourceNode.tsx` / |
36 | | - `ResourcePredicateEdge.tsx` (custom node/edge renderers with inline editing), `Inspector.tsx`, |
37 | | - `NamespacePanel.tsx`, `ValidationPanel.tsx`, `Toolbar.tsx`, `Dialog.tsx`, `AutosaveBanner.tsx`. |
38 | | - |
39 | | -Python and TypeScript are edited in lockstep: a new mutation exposed from `rdf_service.py` needs |
40 | | -a matching `sync.*` registration, a `pyBridge.ts` wrapper, and (if the projection shape changes) a |
41 | | -`rdfGraphModel.ts` update. |
42 | | - |
43 | | -## Setup |
44 | | - |
45 | | -- **Python**: managed with [uv](https://docs.astral.sh/uv/), Python >=3.10 (pinned in |
46 | | - `.python-version`). Deps (`rdflib`, `pyshacl`, `pytest` dev dep) are declared in `pyproject.toml`. |
47 | | -- **Node**: Vite + React 19 + TypeScript + `@xyflow/react` (React Flow) + `@dagrejs/dagre` + |
48 | | - zustand. Deps in `package.json`. |
49 | | - |
50 | | -## Common commands |
51 | | - |
52 | | -```bash |
53 | | -# Frontend dev server |
54 | | -npm run dev |
55 | | - |
56 | | -# Type-check + production build |
57 | | -npm run build |
58 | | - |
59 | | -# Python tests (exercise rdf_service.py directly, no browser/Pyodide needed) |
60 | | -uv run pytest |
61 | | - |
62 | | -# TypeScript tests (Vitest; *.test.ts files next to the code they test) |
63 | | -npm test |
64 | | -``` |
65 | | - |
66 | | -`tests/test_rdf_service.py` imports `rdf_service` directly (pytest's `pythonpath` is set to |
67 | | -`public/py` in `pyproject.toml`) and is the fast way to verify RDF-logic changes without spinning |
68 | | -up the browser/Pyodide runtime. `npm test` runs the Vitest suite, which currently covers the |
69 | | -layout code in `src/lib/` (`forceLayout.test.ts`, `layout.test.ts`). |
| 1 | +@AGENTS.md |
0 commit comments