Hearth — Personal Web Hub
The center of the house. Astro app on the dev machine — agent writes pages, installs libraries, hot-reloads instantly. One app for everything web: agent canvas, dashboards, tools. Agent-agnostic, framework-agnostic.
Concept
Text-based interfaces (terminal, chat) hit a wall when agents need rich output — maps, diagrams, diffs, charts, interactive views. Hearth is the personal web hub that fills the gap. One Astro app, many pages: agent canvas, dashboards, task views, budget charts — anything that needs a browser.
Agent-agnostic. Hearth is a web app on the dev machine. Any agent session can write to it:
- Terminal session → agent writes a page → opens
localhost:4321in browser - Telegram bridge → agent writes a page → sends web_app button → opens hearth via Telegram Mini App
- IDE extension → same — agent writes, browser shows
Same project, same dev server. The delivery channel (browser, Telegram Mini App, anything) is just how the URL reaches you.
Key insight: The agent IS the developer. No deploy step, no build pipeline. Agent writes .astro pages or React islands, hot-reloads instantly. Libraries are installed as needed and persist — the app grows organically.
Architecture
regret (dev machine) zx (always-on)
┌─────────────────────────┐ ┌──────────────────────┐
│ ~/code/hearth/ │ │ Technitium DNS │
│ ├─ Astro dev (:4321) │◄─────────│ hearth.zx → Caddy │
│ ├─ src/ │ │ │
│ │ ├─ pages/ │ │ Caddy │
│ │ ├─ components/ │ │ hearth.zx → HTTP │
│ │ └─ layouts/ │ │ regret.holm:4321 │
│ └─ package.json │ │ │
│ │ │ subdomain.com → HTTPS│ Clients
│ Claude Code │ │ regret.holm:4321 │ ├─ Browser (LAN/Tailnet)
│ └─ writes pages, │ │ │ ├─ Telegram Mini App (HTTPS)
│ installs libs, │ │ butler │ └─ IDE webview
│ edits freely │ │ └─ sends web_app │
└─────────────────────────┘ │ button URL │
└──────────────────────┘
No deploy step. Agent edits files → Astro hot-reloads → browser refreshes. Two access paths:
- Internal: hearth.zx → Caddy HTTP → regret.holm:4321 (LAN devices)
- Telegram Mini App: public subdomain → Caddy HTTPS (Let's Encrypt) → regret.holm:4321
How it works
- Agent needs rich output (map, chart, diff, etc.)
- Agent writes/edits a page in hearth (
src/pages/) or a component (src/components/) - Installs any needed library (
bun add leaflet,bun add d3, etc.) - Astro hot-reloads — live immediately
- Agent surfaces the URL:
- Terminal: prints localhost:4321 link or opens browser
- Telegram: sends web_app button via bridge → user taps to open
- User sees the rendered content
Pages and components accumulate over time. Hearth is a living project, not throwaway pages.
Use cases
| Consumer | Canvas renders |
|---|---|
| Trip planning | Leaflet map with pins, itinerary |
| skill-creator eval | Interactive pass/fail cards, diffs, scores |
| do/pom | Visual timer, task board |
| mooney | Budget charts, expense breakdown |
| Code review | Syntax-highlighted diffs with inline comments |
| Brainstorming | Mind map, node graph |
| Approval flow | Rich tool-call preview with approve/deny |
Any skill or agent that needs more than text can render to hearth.
Agent interface
Minimal — the agent just needs to know:
- Project path:
~/code/hearth/ - URLs:
http://hearth.zx/(internal), public HTTPS domain (Telegram)
The agent already knows how to write code, install packages, and edit files. No special tool needed beyond what it already has. In Telegram, the bridge telegram_api tool sends the web_app button. In terminal, a simple open command or printed URL suffices.
Stack
- Astro — file-based routing, zero JS by default, islands architecture
- React islands — agent writes interactive components (maps, charts) as React with
client:load - Framework-agnostic — same app can host React, Svelte, Vue islands. Agent writes React, human writes whatever fits
- TypeScript — types reduce agent errors
- TailwindCSS — inline styling, no separate CSS files
- Bun — package manager + runtime on dev machine
- Technitium DNS on zx — resolves hearth.zx for LAN devices (internal)
- Caddy on zx — HTTPS reverse proxy via public subdomain for Telegram Mini App, HTTP for hearth.zx internal
- Telegram Mini App — web_app button opens the public HTTPS URL in Telegram's webview
Batteries included — common libs pre-installed so agent never waits:
- Leaflet (maps), D3 (charts/graphs), highlight.js (code), Mermaid (diagrams)
One app, many pages. Hearth is the personal web hub. Canvas is one page, dashboard/tasks/budget are future pages. File-based routing: src/pages/canvas.astro, src/pages/dashboard.astro, etc. Simple .astro pages ship zero JS. Interactive views use React islands.
Agent-managed. Agent writes pages, fixes issues, installs libs as needed. Human can contribute in any framework. If it breaks, agent fixes it.
Bootstrap strategy: scaffold + skill
The token cost of generating code is ~1.5-2x markdown. The cost is mostly in the first render — discovering setup, imports, layout. Reduce this with two things:
1. Scaffold project — pre-installed libs, ready to go:
- Leaflet (maps), D3 (charts), highlight.js (code), Mermaid (diagrams)
- Base layout, Tailwind configured
- Astro + React integration ready
- Agent writes to
src/pages/(routes) andsrc/components/(React islands)
2. Canvas skill — gives the agent instant context:
- Project path (
~/code/hearth/) - What's installed and available
- Conventions (pages vs components, when to use islands)
- URLs (hearth.zx for internal, public domain for Telegram)
- Reusable components that already exist
~20 lines of skill context saves hundreds of tokens per render. Agent reads skill → writes a targeted edit → done. No rediscovery each session.
Component reuse: As views accumulate, the agent reuses them — "MapView already exists, update the pins" instead of writing from zero. The skill can list available components. Worth-keeping components get promoted naturally.
Design decisions
- State = code. No protocol, no state-passing mechanism. The agent writes the component — that IS the state. Tear down, rebuild as needed. Maximum flexibility, no premature abstractions.
- Ephemeral by default. Canvas is a scratchpad, not a persistence layer. Agent builds what it needs, tears it down when done. Components that prove worth keeping get promoted organically — we'll know when we see them.
- File-based routing. Astro handles it —
src/pages/canvas.astrois/canvas. No React Router needed. - Back-channel = file callback. Hearth has one fixed API route:
POST /api/callback { file, data }. Agent writes the callback file path into the page. User interacts → hearth writes data to that file. Agent reads it (poll or fs.watch). Schema is agent-decided per-page — no fixed protocol. Files must start with/tmp/hearth-*for safety. - Agent controls everything. Agent writes the page, decides the callback path, decides the schema, decides when to read. Hearth is infrastructure, not protocol.
- WS available later. If a page needs real-time bidirectional (live whiteboard, streaming), agent can add
/api/wsor write a per-page WS server. Not pre-built — added per-page as needed. - Security = Tailscale + HTTPS. hearth.zx internal via LAN. Public subdomain with Let's Encrypt cert for Telegram Mini App. No extra auth layer needed.
Principle: sandboxed but maximally flexible. Hearth is a blank page the agent owns. Don't build protocols — write code.
Deferred
- Security hardening (auth, public exposure)
- Offline/mobile-first (PWA capabilities)
- Canvas-to-chat: screenshot or summary of canvas state posted back to chat
- Multi-agent: different agents rendering to different views simultaneously
- Template library: pre-built components the agent can compose from
See also
- [[butler-bridge-mcp]] — bridge architecture, MCP tools
- [[claude-proxy-telegram]] — Phase 8 personal OS vision