AkurAI Build
Menu

Public repository / 4f0fa16197a4c339c643dd14c402e84faadc29d9

AkurAI-Framework / ISA.md

Latest change 51aec02c44fe7eb9438a160c80c03b0b12141f7a - feat: akurai-router core + dev SSE live-reload (frontend-platform increment) by Ólafur Búi Ólafsson

---
project: AkurAI-Framework
task: Frontend platform increment — file router core + SSE dev live-reload
effort: E3
phase: complete
progress: 16/16
mode: build
started: 2026-06-26
updated: 2026-06-26
---

# ISA — Frontend platform: router core + dev live-reload

> First two items from the "10 features we lack vs Next/Vue/Svelte" analysis:
> **(1) file/convention routing with dynamic segments** — the spine everything
> hangs off — and **(5) SSE-powered dev live-reload** — the quick win whose
> substrate (SSE) already ships. The broader map stays in `AGENTS.md`; this ISA
> governs the active increment.

## Problem

AkurAI serves pages by a flat `path → template` map with an SPA fallback: there
is no `/posts/:id`, no wildcard, no params, no layout composition — so it can't
express a real application's URL surface. And iterating on the frontend means
restarting the server by hand; there is no live-reload, even though SSE (the
natural transport for it) already ships.

## Vision

A developer edits a template or stylesheet and the browser updates on its own,
within a heartbeat, with zero config. And routes are declared by pattern with
named params that flow into both the server-side render and the client — the
foundation that loaders, layouts, and lazy routes will later build on. Both land
without a bundler and without a single runtime dependency.

## Out of Scope

This increment is the **router core matcher** and the **dev live-reload loop** —
not the full routing integration (wiring patterns into `cmd_serve`, layouts,
loaders) and not production hot-module replacement. Live-reload is a **dev-only**
convenience; it must never touch the production `serve` path. CSS hot-swap
(reload without full navigation) is a later refinement; a correct full reload is
enough now. No client reactivity runtime here (that is feature #2, separate).

## Constraints

- Pure `std`, zero runtime dependencies (workspace crates only).
- No build step; the injected client script is inline native JS.
- Live-reload is gated to `akurai dev`; `akurai serve` is byte-for-byte unchanged.
- Router core is transport-agnostic: pattern + path → params, no HTTP coupling.
- Small scoped files (<1000 lines), one responsibility each, indexed in AGENTS.md.
- TDD: failing test first; matcher and watcher both covered.

## Goal

Ship a pure-std `akurai-router` crate that matches static/`:param`/`*wildcard`
patterns to a path with correct specificity ordering, and a dev-only SSE
live-reload that pushes a `reload` event to the browser whenever a watched file
changes — verified by a real browser actually reloading.

## Criteria

- [x] ISC-1: `crates/router` builds in the workspace, pure std, zero deps.
- [x] ISC-2: A fully-static pattern matches its exact path and nothing else.
- [x] ISC-3: `:name` captures one path segment into params under `name`.
- [x] ISC-4: `*name` (trailing) captures the remaining path into `name`.
- [x] ISC-5: A non-matching path returns `None`.
- [x] ISC-6: When several patterns match, specificity wins: static > param > wildcard.
- [x] ISC-7: A pattern with a different segment count than the path does not match.
- [x] ISC-8: Params preserve order and support multiple captures in one pattern.
- [x] ISC-9: `crates/cli/src/dev_reload.rs` exists with a broadcast version + file watcher.
- [x] ISC-10: `akurai dev` registers `GET /_dev/reload` returning `text/event-stream`.
- [x] ISC-11: In dev, HTML responses inject the live-reload client `<script>` before `</body>`.
- [x] ISC-12: A change to a watched file bumps the version and emits a `reload` SSE event.
- [x] ISC-13: Anti: `akurai serve` (production) returns 404 for `/_dev/reload` and injects no script.
- [x] ISC-14: Anti: the watcher runs on its own thread and never blocks the accept loop.
- [x] ISC-15: A real browser (CDP) connected in dev reloads when a watched file is touched.
- [x] ISC-16: `cargo clippy --all-targets -- -D warnings` and `cargo fmt --check` are clean.

## Features

| name | satisfies | depends_on | parallelizable |
|------|-----------|------------|----------------|
| `akurai-router` crate (pattern parse + match + specificity) | ISC-1..8 | — | yes |
| dev live-reload module (broadcast + watcher + SSE) | ISC-9,10,12,14 | http/sse | yes |
| dev-mode wiring (Config.dev, route, script injection) | ISC-11,13 | live-reload | no |
| verification (unit tests + CDP real-reload) | ISC-2..8,12,15,16 | all | no |

## Test Strategy

| isc | type | check | threshold | tool |
|-----|------|-------|-----------|------|
| ISC-2..8 | unit | router matcher truth tables | all pass | `cargo test -p akurai-router` |
| ISC-10 | integration | curl `/_dev/reload` head | `text/event-stream` | curl in dev |
| ISC-11/13 | integration | grep injected script in dev vs serve | present/absent | curl + grep |
| ISC-12 | integration | touch file → SSE `reload` event observed | event arrives | bun SSE client |
| ISC-15 | live probe | CDP: edit file, assert page reloaded | reload observed | headless chrome + CDP |
| ISC-16 | gate | clippy -D + fmt | clean | cargo |