Architecture
Shelley is a single-file Go web app, using Vue and TypeScript for the UI. The data is stored in SQLite, whose schema and queries are managed by sqlc.
There are abstractions for talking to LLMs and maintaining a set of tools for a conversation.
The most important part of the data model is Conversation and Message. A conversation row is mutable, and has a one-to-many relationship with many message rows. The messages form an append-only log of immutable, ordered messages.
On every write commit, the Shelley server recomputes the “conversation list” query (every non-archived conversation with their last message and so on), and computes a diff with the previous output of this query, and sends said over a websocket to all listening clients. The clients need only to apply diffs, and because messages are immutable, they can cache them indefinitely. The server recompilation of this query is cheap enough because comparing even thousands of rows is quick. This is Shelley’s incremental view maintenance.
Testing
Browser tests use a system called LazyCue. A LazyCue test is merely a paragraph of text. At test time, a bespoke agentic creates a sequence of browser steps to run the test, and caches this in the repo. Subsequent test runs run the cached steps first. On failure, they try to “heal” the test. Surprisingly enough, this converges.
What to Look for in Reviews
Look at schema and API changes first.
Invariants We Care About
- Messages must be immutable.
- Old conversations should still render in the UI, even if their tools are long gone, within reason.
- When no conversations are active, Shelley should be cheap.
The “Demo Server”
Ask your agent to start the demo server with your new code to click around.