Commite0b17ab4Recorded21 Feb 2026Repositorysigil-web-demo
feat: Add live-coding support via nREPL and SSE reload
Message
Add the infrastructure for live-coding Sigil web applications. An AI agent or editor connects to a running app's nREPL, redefines handlers or views, and triggers a browser refresh — no page reload needed.
New modules:
- (sigil web dev): Dev broadcast channel, dev-reload!, dev-morph!, dev-error!, dev-sse-handler for SSE-based browser refresh
- (sigil nrepl client): Reusable nREPL client for connecting to running Sigil apps over TCP
- (sigil mcp dev-tools): MCP tools (dev-connect, dev-eval, dev-reload, dev-status, dev-disconnect) that proxy to nREPL
Changes:
- (sigil web ui): Add sse-reload event for page re-fetch + Idiomorph morph
- sigil-web-ui.js: Handle sigil:reload event with fetch + morph cycle
- Vinyl Vault demo: Wire up nREPL server (port 7888) and dev SSE endpoint
Changed
package.sgl | 1 +
src/sigil/web/demo.sgl | 17 +++++++++++++++--
src/sigil/web/demo/views.sgl | 3 ++-
3 files changed, 18 insertions(+), 3 deletions(-)Diff
package.sglmodified
@@ -16,6 +16,7 @@
16
(from-workspace name: "sigil-stdlib") 17
(from-workspace name: "sigil-http") 18
(from-workspace name: "sigil-web")+19
(from-workspace name: "sigil-nrepl") 20
(from-workspace name: "sigil-sqlite") 21
(from-workspace name: "sigil-sxml") 22
(from-workspace name: "sigil-css")))src/sigil/web/demo.sglmodified
@@ -15,6 +15,8 @@
15
(sigil http request) 16
(sigil web) 17
(sigil web ui)+18
(sigil web dev)+19
(sigil nrepl) 20
(sigil sqlite) 21
(sigil web demo db) 22
(sigil web demo views))@@ -222,7 +224,8 @@
224
(route method: POST pattern: "/records" handler: create-record-handler) 225
(route method: POST pattern: "/records/:id" handler: update-record-handler) 226
(route method: DELETE pattern: "/records/:id" handler: delete-record-handler)−225
(route method: GET pattern: "/js/sigil-web-ui.js" handler: (sigil-web-ui-handler))))+227
(route method: GET pattern: "/js/sigil-web-ui.js" handler: (sigil-web-ui-handler))+228
(route method: GET pattern: "/__dev/events" handler: (dev-sse-handler)))) 229
(with-db _ db) 230
(with-logging) 231
(with-content-type default: "text/html; charset=utf-8")@@ -230,10 +233,20 @@
233
234
;;; Start the demo server. 235
(define (start-demo)−233
(let ((db (sqlite-open "vinyl-vault.db")))+236
(let ((db (sqlite-open "vinyl-vault.db"))+237
(dev (make-dev-broadcast))) 238
(init-db db) 239
(display "Vinyl Vault running at http://localhost:8080\n")+240
(display "nREPL at port 7888\n") 241
(with-async+242
;; nREPL goroutine+243
(let ((nrepl (nrepl-start 7888)))+244
(when nrepl+245
(go (let loop ()+246
(nrepl-process-pending nrepl)+247
(sleep 0.05)+248
(loop)))))+249
;; HTTP server 250
(http-serve (make-app db) port: 8080)))) 251
252
))src/sigil/web/demo/views.sglmodified
@@ -393,7 +393,8 @@
393
(li (a (@ (href "/records/new")) "Add Record"))))) 394
(div (@ (id "sg-flash-container"))) 395
(main (@ (class "container"))−396
,body-content))))+396
,body-content)+397
(div (@ (data-sg-sse "/__dev/events") (style "display:none")))))) 398
399
;; ============================================================ 400
;; Pages