Browser editor

The generation panel can load and save target settings and preview SQL without writing. Template directories remain CLI-only; see Custom generation.

bluep serve <dir> [--port 7878] [--host 127.0.0.1] serves a single-page editor from the binary itself: a small HTTP/1.1 server on the standard library's TCP listener, plain HTML, CSS and JavaScript, no framework, no bundler and no network access. It prints serving <dir> at http://<host>:<port>/ and runs until interrupted.

Reviews

The review panel presents repository-local review state and anchored discussion threads alongside the model editor. It uses GET/POST /api/reviews, GET /api/reviews/<id>, POST /api/reviews/<id>/comments, POST /api/reviews/<id>/threads/<thread>/comments, POST /api/reviews/<id>/threads/<thread>/resolve, and POST /api/reviews/<id>/state. Review text is inserted as text, not HTML. Selecting a model element filters threads by its dotted object anchor spelling, such as attribute:customer.email or table:pg.public.customer.

Layout of the page

  • Toolbar: model name, Reload (re-read the files from disk), Lint (open the findings drawer), New entity, New relationship, New area, and a status area that shows saved <files> after a write or the error message of a rejected edit.
  • Sidebar: a filter box and the lists of areas, entities and relationships.
  • Library panel: resolved aliases, versions and dependencies, plus a safe reload action. Library-backed objects show their source and are read-only.
  • Main panel: the selected area (description, membership, diagram), entity (description, attributes, keys, relationships in and out, physical tables, sync to target) or relationship (parent, child, key, column pairs, cardinalities, actions).
  • Lint drawer: one row per finding; clicking a row selects the object.

Editing model

Every change is sent to the JSON API, applied to the in-memory model, validated with the same rules as bluep check, and written to the text files in canonical form (bluep fmt afterwards reports no changes). A

Mappings are available under the Mappings panel. The Lineage panel accepts a local table or column selector and follows upstream or downstream declared inputs; objects from a library or sibling model remain read-only. change that would make the model invalid is rejected with HTTP 400 and the first issue message, for example attribute 'customer.email': domain 'x' does not exist, and nothing is written. Deleting or renaming an entity or attribute cascades to relationships, areas, key definitions and column mappings.

Dragging a box on a diagram writes the position into the area block as entity <name> at <x> <y>; entities without a stored position are placed by the automatic layout.

API

All bodies and responses are JSON unless noted. Names in paths are percent-encoded.

Method Path Purpose
GET / the editor page
GET /assets/app.js, /assets/app.css static assets
GET /api/model the whole model in the JSON interchange format
GET /api/libraries resolved library aliases, versions and dependencies
POST /api/libraries/reload reload libraries when local model files are unchanged
GET /api/summary names and counts for the sidebar
GET /api/types logical types, domains and enums for the type editor
GET, POST /api/entities list / create (201; 409 when the name exists)
GET, PUT, DELETE /api/entities/<n> read / replace / delete (cascades)
POST /api/entities/<n>/rename {"to": "<name>"} (cascades)
POST /api/entities/<n>/attributes add an attribute, optionally "after": "<attr>"
PUT, DELETE /api/entities/<n>/attributes/<a> replace / delete an attribute
POST /api/entities/<n>/attributes/<a>/rename {"to": "<name>"}
POST /api/entities/<n>/sync {"target": "<t>"} or {}: create or extend the entity's tables
GET, POST /api/relationships list / create
GET, PUT, DELETE /api/relationships/<n> read / replace / delete
GET, POST /api/areas list / create
GET, PUT, DELETE /api/areas/<n> read / replace / delete
GET, PUT /api/areas/<n>/layout {"<entity>": {"x": .., "y": ..}}
GET /api/areas/<n>/diagram.svg SVG diagram of the area (image/svg+xml)
GET /api/diagram.svg SVG diagram of all entities
GET /api/lint {"findings": [..], "errors": n, "warnings": n}
POST /api/reload re-read the model directory
GET /api/files [{"path": "model.bluep", "bytes": n}]

Write responses are {"ok": true, "files": [<changed relative paths>]}. Errors are {"error": "<message>"} with status 400 (invalid input or model), 404 (unknown object or route), 409 (duplicate name) or 413 (body larger than 16 MiB).

The entity editor provides typed property and classification controls. It adds one classification column to the attribute table for each declared classification, and uses the property declarations to choose the appropriate property value control.

The entity form has a Stereotype select (none, fact, dimension or bridge), saved as the entity's stereotype. The area form has a Notation select (model default, crows_foot or idef1x); saving an area re-renders its diagram in the chosen notation.

Bulk grid

The Bulk grid loads entities, attributes, columns, relationships, or properties through /api/grid/<kind>. Keys remain read-only. Filtered and sorted views are presentation-only; CSV planning always uses the complete snapshot. See Bulk editing for the keyboard editing, validation, and review workflow.

Hierarchies

The association panel uses /api/associations for sorted CRUD and /api/infer-relationships for read-only suggestions. Association edges carry data-kind="many-to-many"; evidence is shown separately and must be accepted explicitly before it is written.

The hierarchy panel edits categories, discriminators, subtype values and target transformations. Its category nodes use the same complete/incomplete and exclusive/inclusive values as the text model.

Limits

The server is meant for one person on one machine: it binds to 127.0.0.1 by default, has no authentication, serves one request per connection and holds the model behind a single lock.