Files
micronomicon/CLAUDE.md
2026-04-01 10:13:14 +02:00

12 KiB

µFrame (Micronomicon)

A self-hosted web IDE and CLI for building rich terminal UIs using a declarative DSL. Compiles .uf source files into both plain ASCII art and styled Micron .mu pages for NomadNet — a decentralized communication platform running on the Reticulum mesh network.

What It Does

Write this:

page "Node Status" 60
  box double "Relay Alpha-7"
    align center
    text "Reticulum Network Node"
  gauge "CPU" 62 100 28 warn=75 crit=90
  status "East Relay" online
  table "Routes"
    columns "Dest" 20 | "Hops" 6 | "Status" 10
    row "relay-east" | "2" | "@color{0f0}{alive}"

Get this (ASCII):

╔═ Relay Alpha-7 ════════════════════════════════════════════╗
║               Reticulum Network Node                       ║
╚════════════════════════════════════════════════════════════╝
CPU  ████████████████████░░░░░░░░  62%
● East Relay
┌────────────────────┬──────┬──────────┐
│Dest                │Hops  │Status    │
├────────────────────┼──────┼──────────┤
│relay-east          │2     │● alive   │
└────────────────────┴──────┴──────────┘

And the same content as Micron .mu with color tags, bold, links, and interactive form fields — ready to serve on NomadNet.

Quick Start

Web IDE

# Backend
cd backend
source .venv/bin/activate
PAGES_DIR=~/.nomadnetwork/storage/pages \
SOURCES_DIR=~/.micron-editor/sources \
uvicorn main:app --reload --port 8080

# Frontend (separate terminal)
cd frontend
npm run dev

Open http://localhost:5173 → click New Page → click Examples → pick a template.

CLI

cd backend
source .venv/bin/activate

# Render to terminal
python -m uframe render page.uf

# Render Micron only
python -m uframe render page.uf --micron

# Compile to .mu file
python -m uframe compile page.uf --out page.mu

# Validate without output
python -m uframe check page.uf

# Compile and deploy to NomadNet
python -m uframe deploy page.uf

Tech Stack

Layer Technology
Backend Python 3.13 + FastAPI + uvicorn
µFrame Pure Python (zero deps): parser → IR → CharGrid → emitters
Frontend React 19 + Vite + TypeScript
UI shadcn/ui + Tailwind CSS v4
Editor CodeMirror 6 (custom µFrame syntax mode)
Graph React Flow (@xyflow/react) + dagre
State Zustand
Container Docker + Compose

Project Structure

micronomicon/
├── backend/
│   ├── main.py              # FastAPI app + static file serving
│   ├── converter.py          # POST /api/compile endpoint
│   ├── pages.py              # CRUD /api/pages (.uf sources + .mu publish)
│   ├── graph.py              # GET /api/graph (link parser)
│   ├── docker_utils.py       # POST /api/restart (NomadNet container)
│   └── uframe/               # µFrame engine (16 modules, ~3800 LOC)
│       ├── __init__.py        #   compile(source, width) → CompileResult
│       ├── parser.py          #   .uf DSL → IR tree (indentation-based)
│       ├── ir.py              #   30+ IR node dataclasses
│       ├── grid.py            #   CharGrid — 2D char + style buffer
│       ├── chars.py           #   Unicode tables (box-drawing, braille)
│       ├── measure.py         #   Bottom-up size computation
│       ├── layout.py          #   Top-down position assignment
│       ├── paint.py           #   IR nodes → CharGrid rendering
│       ├── borders.py         #   Junction merging post-pass
│       ├── emit_ascii.py      #   CharGrid → plain text
│       ├── emit_micron.py     #   CharGrid → Micron with style tags
│       ├── codegen.py         #   Dynamic page → executable Python script
│       ├── cli.py             #   CLI: render / compile / check / deploy
│       ├── errors.py          #   ParseError, LayoutError, CompileWarning
│       └── tests/             #   42 tests (compile, dynamic, components)
├── frontend/src/
│   ├── routes/                # DashboardView, EditorView, GraphView
│   ├── components/editor/
│   │   ├── EditorPane.tsx     #   CodeMirror 6 host
│   │   ├── PreviewPane.tsx    #   ASCII / Micron / Raw / Script tabs
│   │   ├── ToolBar.tsx        #   Save, Publish, Examples, Backlinks
│   │   ├── uframeHighlight.ts #   µFrame syntax highlighting
│   │   ├── uframeCommands.ts  #   "/" slash command palette
│   │   ├── micronRenderer.ts  #   Micron → HTML preview renderer
│   │   └── examples.ts        #   9 built-in example templates
│   ├── hooks/
│   │   ├── useCompile.ts      #   Debounced POST /api/compile
│   │   └── useUnsavedGuard.ts #   Prevent accidental navigation
│   └── stores/
│       ├── editorStore.ts     #   Zustand: source, compiled output, preview mode
│       └── pagesStore.ts      #   Zustand: page list, delete, unpublish
└── docs/
    ├── framework-design-v3.md #   Full DSL spec + rendering model
    └── dynamic-templates.md   #   Dynamic page addendum

API Endpoints

Method Path Description
GET /api/health Health check
POST /api/compile Compile .uf{ascii, micron, script, is_dynamic}
GET /api/pages List all pages with metadata
GET /api/pages/{name} Read page source
POST /api/pages/{name} Save page — { source, publish }
DELETE /api/pages/{name} Delete source and/or .mu file
GET /api/graph Page link graph (nodes + edges)
POST /api/restart Restart NomadNet Docker container

Storage

~/.micron-editor/sources/       ← .uf source files (drafts + published)
~/.nomadnetwork/storage/pages/  ← Compiled .mu files served by NomadNet
  • Save Draft: writes .uf to sources dir only
  • Publish (static): compiles .uf.mu, writes to pages dir (chmod 644)
  • Publish (dynamic): compiles .uf → executable Python script, writes to pages dir (chmod 755)

NomadNet auto-detects the execute bit: static pages are served as-is, dynamic pages are executed and their stdout is served.

µFrame DSL Reference

Layout

page "Title" [width]                         # root (default width 64)
  box [light|heavy|double|rounded] "Title"   # bordered panel
  row [gap]                                  # horizontal layout
    col [width]                              # column in a row
  spacer [lines]                             # vertical whitespace
  pad [t] [r] [b] [l]                       # inner margin

Content

heading [1|2|3] "Text"                       # styled heading
text "Content with @bold{inline} @color{hex}{modifiers}"
label "Key" "Value"                          # aligned key-value pair
list [bullet|dash]
  item "Entry"
link "Display text" "/dest.mu"               # clickable in Micron
divider [light|heavy|double|dash|dot]        # horizontal rule
# comment                                   # ignored in output

Data Visualization

gauge "Label" value max width [warn=N crit=N]  # ████░░░░ bar with thresholds
sparkline "Label" "1,3,5,8,7,5" width          # ⣀⣤⣶⣿⣷⣤ braille chart
status "Label" [online|offline|degraded]        # ●○◐ colored indicators
table "Title"
  columns "Name" 20 | "Hops" 6 | "Status" 10
  row "relay" | "2" | "@color{0f0}{● alive}"

Forms

form "name"
  field "name" [width] "placeholder"          # text input
  password "name" [width] "placeholder"       # masked input
  radio "group" "Opt A" | "Opt B" | "Opt C"  # radio buttons
  checkbox "name" "Label"                     # checkbox
  button "Label" "/action/path"               # submit link

Dynamic Features

cache 0                                       # never cache (re-execute)
source cpu : shell "cat /proc/loadavg"        # live data at render time
source config : json "/path/config.json"      # JSON file read
source ts : python "datetime.now().isoformat()" # Python expression
let name = "Relay Alpha"                      # variable assignment

if $cpu > 90
  text "ALERT: CPU critical"
elif $cpu > 75
  text "Warning: elevated"

for peer in $peers
  status "$peer.name" $peer.state

on_submit "search"
  source results : shell "search.py '$query'"
  text "$results"

state "counter" "/tmp/counter.json"           # persistent JSON store

Components

# Define a reusable component
component stat(label, value, max)
  gauge "$label" $value $max 20

# Use it
stat "CPU" 62 100
stat "MEM" 84 100

# Import standard library
use std/dashboard
banner "My Node" "Mesh Network"
resources 62 84

Standard Libraries

Library Components
std/dashboard banner(title, subtitle), resources(cpu, mem), peer_status(name, state)
std/status-bar status_bar(label, value, max), status_item(name, state)
std/nav nav_link(label, dest), nav_divider()

Rendering Pipeline

.uf source
    │
    ▼
  Parse ──→ IR Tree (30+ node types)
    │
    ▼
  Measure (bottom-up: compute sizes)
    │
    ▼
  Layout (top-down: assign positions)
    │
    ▼
  Paint (depth-first: write chars into CharGrid)
    │
    ▼
  Merge Borders (fix junction characters)
    │
    ├──→ ASCII emitter → plain text
    ├──→ Micron emitter → styled .mu (with colors, links, form tags)
    └──→ Codegen (if dynamic) → executable Python script

Web IDE Features

  • Split-pane editor: µFrame DSL source (left) / live preview (right)
  • Syntax highlighting: keywords, strings, variables, comments in distinct colors
  • / command palette: type / to insert layout, content, data viz, form, and style primitives
  • 4 preview tabs: ASCII | Micron (rendered) | Raw (Micron source) | Script (dynamic pages only)
  • ⚡ dynamic badge: auto-detected when source contains source, if, for, etc.
  • Examples dropdown: 9 built-in templates (Hello World → Full Node Page → Dynamic Dashboard)
  • Pages dashboard: table view with Published/Draft/Orphan status badges
  • Page graph: React Flow visualization of inter-page links
  • Keyboard shortcuts: Ctrl+S save draft, Ctrl+P publish
  • Unsaved changes guard: warns before navigating away
  • Backlink indicator: shows which pages link to the current page

Running Tests

cd backend
source .venv/bin/activate
python -m pytest uframe/tests/ -v

42 tests covering:

  • Static compilation (boxes, headings, text, gauges, tables, links, lists, spacers, dividers)
  • Form elements (field, radio, checkbox, button)
  • Dynamic pages (source, if/for, let, state, on_submit, codegen)
  • Components (inline definitions, standard library, parameter substitution)

Conventions

  • µFrame engine is pure Python stdlib — zero external dependencies
  • Backend is FastAPI; no ORM, flat file storage
  • Frontend uses shadcn/ui components in frontend/src/components/ui/
  • Feature components grouped by domain: dashboard/, editor/, shared/
  • State management via Zustand stores
  • All .uf sources stored in SOURCES_DIR, compiled .mu in PAGES_DIR

References