Skip to main content
Glama
clausd

aedificium-template

by clausd
README.md
# aedificium — is a way to learn with Claude Code.

Aedificium is a web companion for Claude Code using channels for communication.

Use it to build notes, a lexicon of concept definitions and a collection of PDFs to talk about. Notes + Lexicon are maintained in a github repo. PDFs in Git LFS. 

Aedificium supports math notation - and a companion repo supports coding up demonstrations or tests of anything in the notes that can be expressed as math or code. 

The UI is a card-grid UI running on `http://localhost:8788` for notes, definitions (a lexicon), and PDFs, with a chat pane bridged to Claude Code via MCP. Math renders
first-class (KaTeX). Everything on disk is plain markdown, auto-committed to
git, and (optionally) auto-pushed to GitHub.

This is an **open-source template** without any notes or PDFS. Fork it, clone your fork next to a sibling `scriptorium/` code lab, and start writing.

## Fearure set

- **Card grid + reader** — notes on the left, chat with Claude on the right.
- **First-class math** — `$e^{i\pi}+1=0$` inline, `$$…$$` display, KaTeX
  server-side. Renders in the card grid *and* in the reader.
- **Lexicon** — one definition per file (`lexicon/eigenvalue.md`), rendered as
  a dictionary entry with headword + synonyms + domain label.
- **PDF library** — drop a PDF into `pdfs/`; a sidecar discussion card
  appears automatically. No embedded viewer — the browser's native one is
  better. Deep-link into pages with `#page=N`.
- **Chat is Claude Code** — you type in the browser, Claude answers, and your
  current card selection travels along as context (`refs=…`).
- **Wiki-links** — `[[slug]]` in any note becomes a click-to-open link in
  the reader, with `/note/<slug>` deep-links via the History API.
- **Git-native** — writes auto-commit (debounced ~3 s) and, if `origin` is
  set, auto-push. LFS pre-configured for PDFs so GitHub handles large
  binaries cleanly.

## Prerequisites

Developed and tested on **macOS (arm64)**. Linux should work with the
equivalent package installs.

- [**bun**](https://bun.sh) — the JavaScript runtime the server uses.
  `brew install oven-sh/bun/bun`.
- [**git-lfs**](https://git-lfs.com/) — for PDFs. `brew install git-lfs`.
- [**Claude Code**](https://www.anthropic.com/claude-code) — the CLI the
  chat pane talks to. This is what makes the notebook *interactive*.

## Setup

```bash
# Fork on GitHub first, then:
git clone git@github.com:clausd/aedificium.git
cd aedificium
bun install
git lfs install
```

## Launching

To make the channel work Claude Code needs to load the UI and for that to work you need to launch claude code from the terminal with the following permission setting
`--dangerously-load-development-channels server:aedificium` for the browser →
Claude direction of the channel to work. 

So from the root of the repo do

```bash
claude --dangerously-load-development-channels server:aedificium
```

Claude Code will spawn `bun server.ts` automatically (per `.mcp.json`). Then
open <http://localhost:8788>.


## Updating aedificium

If you need to pick up a change to the platform itself there's currently no other way than exiting Claude and restarting. 

## Repo folder structure

```
notes/                  YYYY-MM-DD-HHMM-slug.md — free-form notes
lexicon/                <slug>.md — one term per file, dictionary style
pdfs/                   PDFs + auto-generated sidecar .md discussion cards
assets/                 pasted / dropped images referenced from cards
files/                  misc non-PDF uploads
archive/                archived cards (preserves original subdir)
data/chat.jsonl         durable chat transcript (tracked + searchable)

```

Read [`CLAUDE.md`](CLAUDE.md) for further details

## Scriptorium

If you want a companion Python repo for models, notebooks, and figures, use
**scriptorium-template** as a sibling checkout:

```
your-workspace/
  aedificium/          # this repo
  scriptorium/         # from scriptorium-template
```

The scriptorium `aedificium.py` bridge lets notebook cells render aedificium
prose inline and save matplotlib figures directly into `aedificium/assets/`.
Set `AEDIFICIUM_DIR` (in scriptorium) or `AED_SCRIPTORIUM_DIR` (here) if the
two aren't siblings.

## GitHub setup

Push to GitHub as usual once you have LFS installed locally:

```bash
git remote set-url origin git@github.com:clausd/aedificium.git
git push -u origin main
```

Note changes are automatically committed and pushed if a remote is set up. Auto-push runs after each auto-commit (5 s debounce). Disable with
`AED_NO_PUSH=1`. GitHub LFS free tier is 1 GB storage / 1 GB bandwidth per
month per account — comfortably enough for a personal PDF library up to a
few hundred papers.

## Environment knobs

| Var | Default | Effect |
|---|---|---|
| `AED_PORT` | `8788` | HTTP + WebSocket port. |
| `AED_NO_GIT` | unset | Disable all auto-commit. |
| `AED_NO_PUSH` | unset | Auto-commit but never auto-push. |
| `AED_NO_CHAT_CHECKPOINT` | unset | Disable chat-log checkpointing. |
| `AED_PUSH_DEBOUNCE_MS` | `5000` | Coalesce commits into one push. |
| `AED_CHAT_IDLE_MS` | `300000` | Idle time before a chat checkpoint. |
| `AED_CHAT_MAX_MS` | `900000` | Max chat age before a forced checkpoint. |
| `AED_SCRIPTORIUM_DIR` | `../scriptorium` | Where `#code:` tags resolve. |
| `AED_EDITOR_URL` | `vscode://file/{path}` | Card "open in editor" URL scheme. |

## Troubleshooting

- **"I type in the chat pane and nothing happens."** Almost always the
  missing `--dangerously-load-development-channels server:aedificium` flag.
  Restart Claude Code with it.
- **"Claude says the `reply` tool is unavailable."** Bun got orphaned. Kill
  the process on port 8788, exit and re-enter Claude Code.
- **"`git push` refuses a PDF (`exceeds 100 MB`)."** LFS wasn't active when
  the PDF was added. Run `git lfs install`, then
  `git lfs migrate import --include="*.pdf" --everything`, then
  `git push --force-with-lease` (only safe when you're the sole clone).
- **"Auto-commit stopped."** Check bun's stderr. Most common cause is a
  merge conflict on `data/chat.jsonl` between machines — the conflict is
  usually the union of the two sides (chat.jsonl is append-only).

## License

MIT. Adapt freely — the point is that you own your notebook.

## Credits

Original concept, architecture, and implementation by
[Claus Dahl](https://github.com/clausd). 

Everybody in the AI universe had a version of this idea already btw. 
Here's [Karpathy's version](https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f)


The Aedificium was the name of the building housing the library in Umberto Eco's The Name of The Rose. The Scriptorium is where the monks worked on the books.