3b9de49WASM REPL: interpreter in the browser with generative canvas
Compile the tree-walking interpreter to wasm32-freestanding via
zig build wasm. 96KB blimp.wasm module. JS loader class with
eval/getState/reset API. Browser REPL with inline prompt, multiline
do/end buffering, command history, state sidebar showing variables
and actor instance state.
Canvas visualization: actors as hexagons with generative fills
seeded from state hash. Four pattern types (dots, rings, stripes,
blobs). Message sends animate as dashed rays from REPL blob to
target actor. State changes flash the border white. Breathing
green blob for the global runtime.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
61421baTUI REPL: live LLVM IR panel, Tab toggles STATE/IR view
Source accumulates across submissions, IR updates on each eval
with syntax highlighting. libvaxis TEA architecture.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
f8fc2f9Pattern matching: destructure maps, lists, tuples in situation/case
situation/case branches now do structural pattern matching:
- Variable binding: n -> n * 2
- Map destructuring: %{name: n, age: a} -> n
- List head/tail: [h | t] -> h
- Tuple destructuring: {a, b} -> a + b
- Literal matching: :ok, 42, "hello", true, nil
- Nested patterns compose recursively
- Holes always match (wildcard)
Patterns produce bindings that are scoped to the branch body.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
f608d00List concatenation with + operator
[1, 2] + [3, 4, 5] => [1, 2, 3, 4, 5]
Works alongside string + for concat and integer + for addition.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
db61ab1Fix 3+ branch situation parsing: don't skip newlines after body stmt
The branch body loop was skipping newlines after each statement,
preventing the branch boundary detection from seeing the newline
that separates branches. Now the newline check at the loop top
handles boundary detection, and looksLikeBranch scans for -> on
the next line.
Fixes: situation with 3+ branches, recursive fib definition.
fib(25) = 75025 in 187ms (tree-walking interpreter).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
e15ff3cParser depth counter: use proper word boundaries for do/end detection
Word boundary check now uses isAlphanumeric instead of whitelist.
Fixes detection of 'do' after digits (e.g., 'situation n > 1 do').
Removed def/situation/case from parse error keyword reject list.
Improved branch body termination for new patterns at line start.
Known: 3+ branches in multiline situation still needs work.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
365348eLoops, spread operators, and self keyword
Three ways to iterate:
...list, fn -> map (returns new list)
..list, fn -> each (side effects, returns :ok)
for x in list do ... end -> verbose loop (returns list)
Self keyword resolves to current actor's ref inside handlers:
on :double do
self <- :set(val * 2)
end
for/in keywords added. .. and ... are lexed as distinct tokens.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
a987b2dterm_diff: config-driven orchestrator, REPL explorer, cleanup
Orchestrator config for max concurrent slots and stall detection.
REPL LiveView consuming blimp --introspect JSON. Agent runner
session continuation. Commentary prompt refactor. Navigation and
diff parser cleanups. Test fixes for async coordination.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
7d61d90Add blog post #3: Actors Are Alive
New post covering diff viewer, multiplexer, actor runtime, evaluator,
Elm-style errors, LLVM compilation, REPL, and tooling feedback loop.
Split-pane layout for all code sections in posts 2 and 3. Screenshots
of diff viewer, multiplexer, REPL, line selection dialog. Image
lightbox modal on click. Index updated.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
0320969Parser fixes, tree-sitter sync, benchmark suite
Fix parseStatementPublic to use parseTopLevel (handles def, situation,
case, for at top level). Remove def/situation/case/orelse from
parseError keyword reject list. Improve branch body termination to
detect new branch patterns at line start.
Tree-sitter grammar synced with all new constructs.
Benchmark suite: fib, actor spawn, ring in Blimp/Rust/Python/Elixir.
Known issue: multiline situation with 3+ branches inside def body
still fails in piped REPL. Needs deeper parser refactor for branch
boundary detection.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
f1b53f4Perceus reference counting for BlimpVal
Every BlimpVal gets an rc field initialized to 1. RC operations:
- blimp_rc_inc: increment on share (list push, variable copy)
- blimp_rc_dec: decrement on scope exit, recursive free at zero
(strings freed, list items dec'd, map keys/vals dec'd, closure env dec'd)
- blimp_rc_reuse: returns same pointer if rc==1 for in-place mutation
Codegen inserts rc_dec after list element pushes (list_push already
does rc_inc, so the local ref is balanced). Foundation for become
in-place reuse and actor death O(1) cleanup.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
be54559Async actor scheduler: run queue, round-robin dispatch, deadlock detection
blimp_send now enqueues messages and pumps a round-robin scheduler
instead of processing inline. FIFO run queue tracks runnable actors.
Self-send guard prevents deadlock when a handler sends to its own
actor. Deadlock detection aborts if scheduler makes no progress.
Actor status tracking (idle/runnable/running). Two new test programs:
cross_send.blimp and fairness.blimp.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
499085eClosures and higher-order functions
fn(x, y) do ... end creates closures that capture enclosing scope.
Closures are first-class values: store in variables, pass as arguments.
Named function calls check for closure bindings before builtins.
Higher-order builtins: map, filter, reduce, each. These take a list
and a closure, calling the closure for each element.
double = fn(x) do x * 2 end
map([1, 2, 3], double) # => [2, 4, 6]
filter([1,2,3,4], fn(x) do x > 2 end) # => [3, 4]
reduce([1,2,3], 0, fn(acc, x) do acc + x end) # => 6
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
5a091aeSupervision: bubble propagation, orelse catches, CascadeBubble restarts siblings
bubble keyword signals actor failure. orelse catches Bubble errors
and executes fallback. Handler bubbles() annotation declares strategy:
- SelfBubble: restart just the failing actor
- CascadeBubble: restart all siblings under the supervisor
Dot notation defines the supervision tree: Shop.Checkout and
Shop.Inventory are siblings under Shop. When Checkout bubbles with
CascadeBubble, both siblings get restarted to their default state.
Also: spawn now handles dot-notation names (spawn Shop.Checkout).
Parent/child relationships derived from type name prefixes.
Registry.restartActor and restartChildren reset state to template defaults.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
c9ba44cCanvas: adaptive grid layout, squares for values, same-state same-art
Grid layout tries all column counts and picks the largest cell size.
Scales hexagons down when space is tight. Staggered odd rows for
hex packing. Raw values (non-actor variables) render as squares.
Same type + same state produces identical generative fill.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
040ac00Codegen: lists, closures, for loops compile to native
Tagged value runtime (BlimpVal) with constructors, list operations,
and value extraction. Codegen emits blimp_val_int/blimp_val_list/
blimp_list_push for list literals, blimp_val_closure for fn expressions,
blimp_list_map for spread (...), and loop codegen with blimp_list_get/
blimp_val_to_int for unwrapping. New .tagged_val type tag for values
that live in the heap world. blimp_print_val for tagged output.
Full programs compile: actors + closures + lists + for loops + spread
all in native code. [21, 41, 61] from a program that spawns a Counter,
maps a list with a closure, and loops over the result.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
a081c6bmerge, values, type_of, print builtins
merge(%{a: 1}, %{b: 2}) => %{a: 1, b: 2} with overwrite on conflict.
values(%{x: 10}) => [10] extracts map values as list.
type_of(42) => :integer for runtime type introspection.
print(val) outputs to stdout and returns val (identity).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
f42e46bRebuild WASM with 3+ branch fix, fib now works in browser REPL
b000853Fix REPL depth counter for end), rebuild WASM, add playground
The REPL's do/end depth counter didn't recognize end) as closing
a block. Now allows ) and , after end keyword. Fixes inline
closures in function calls: map(list, fn(x) do x * 2 end)
Rebuild WASM with closures, spread operators, for/in, self.
Add playground.html with canvas + state panel + cheat sheet.
Rays draw on top of all shapes.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
9378be8++ operator for list and string concatenation
[1, 2] ++ [3, 4] => [1, 2, 3, 4]
"hello" ++ " world" => "hello world"
Separate from + (arithmetic/string). ++ is explicitly for
joining collections. Lexed as a two-character token.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
7c5804dEmbed WASM REPL in blog with canvas visualization
Inline REPL with canvas on the index page. "Try Blimp" button on all
three posts opens a modal REPL. Widget loads blimp.wasm (96KB),
blimp.js, and canvas.js from repl/ directory. Self-contained: one
script tag, no dependencies. Canvas shows generative hexagons for
actors, rays for message sends.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
a9b5ca0Sync tree-sitter grammar with Zig parser
Added: fn expressions, def statements, for/in loops, spread operators
(... and ..), self keyword, bubble statement, ++ concat operator,
spawn with actor_name. Updated conflicts and precedences. All new
constructs parse correctly. Known limitation: spawn with dot-notation
names (spawn Shop.Checkout) needs Zig parser, tree-sitter treats the
dot as dot_access.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
b28b738Fix multiline situation branches: allow bare identifiers in body
The handler body parser rejected bare identifiers (like _ -> n)
as "probably a typo". This broke situation branches that return
variables. Removed the check. Now all situation patterns work:
situation n > 1 do
true -> n * 2
_ -> n
end
Works inside fn, def, standalone, with any expression in branches.
This was the root cause of all the multiline parsing failures.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
b1258abrange, head, tail, sort builtins
range(1, 5) => [1, 2, 3, 4, 5] for integer sequences.
head/tail for list destructuring as functions.
sort for integer lists (insertion sort).
for i in range(1, 10) do i * i end now works naturally.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
e5b5078Rebuild WASM with def, string ops, supervision. Add supervision example.
WASM now includes: def keyword, concat/split/contains/to_string/
to_int/slice/upcase/downcase builtins, bubble/orelse supervision,
CascadeBubble/SelfBubble restart strategies. 119KB module.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
d760881Full actor system: LLVM codegen, C runtime, async mailboxes
Actors compile to native: state structs, handler functions, handler
tables, spawn, message send, become, reply, guards, multi-clause
dispatch. C runtime provides actor registry, ring buffer mailboxes,
round-robin scheduler. Parser fix for integer patterns. Four example
programs. --run and --dump-ir flags on blimp-compile.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1b827fbTagged value runtime: BlimpVal for heap-allocated data structures
Add BlimpVal tagged union to runtime.c alongside existing i64 path.
Supports: int, float, string, atom, bool, nil, list, map, actor_ref,
closure. Value constructors (blimp_val_int, blimp_val_list, etc.).
List operations: push, get, len, map, filter, reduce, each.
Tagged value printer (blimp_print_val).
This is the foundation for compiling closures, lists, maps, and
higher-order functions to native code. Existing i64-based actor
codegen is preserved and unaffected.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
b6384c8Codegen: stub new features, preserve existing compilation
Add compileExpr cases for self_ref, for_expr, spread_map,
spread_each. Currently return UnsupportedNode (interpreter-only
features). Existing actor compilation (counter, bank, traffic_light)
unaffected. Full codegen for closures and list iteration needs
runtime support for heap-allocated values beyond i64.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
b84e661Add blog post #4: You Can Try It Now
Covers closures, spread operators, pattern matching with Holes,
self keyword, async scheduler, tagged values with Perceus RC,
LLVM compilation of lists/closures/loops, WASM REPL in the browser,
and the generative canvas. Embedded REPL with Demo button at the
bottom. Split-pane layout for code sections. Index updated.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
45a5adadef keyword and string builtins
def name(params) do ... end creates named functions (sugar for
assigning a closure). String builtins: concat, split, contains,
to_string, to_int, slice, upcase, downcase. length() now works
on strings and maps too.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1262e6cCompile def to native LLVM functions with recursion
def name(params) do ... end compiles to a real LLVM function.
Forward-declared so recursive calls work. func_call finds it
via LLVMGetNamedFunction. situation branches compile to
conditional blocks.
fib(40) benchmark:
Blimp (compiled): 230ms
Rust: 190ms (1.2x faster)
Python: 8317ms (36x slower)
Blimp compiled is within 1.2x of Rust for pure recursion.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
7495ce3Runtime message log for canvas rays, demo mode, mobile fixes
Evaluator tracks message sends in a log so canvas rays fire for
sends inside closures (map over actors). WASM state JSON includes
messages array. Canvas: ResizeObserver for mobile, re-layout on
resize, per-frame size check. Playground: Demo button types out
a full session at human speed. Root landing page links to playground.
Blog post #4 draft started.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
9f138e0Add TUI REPL with libvaxis: TEA architecture, vim modes, syntax highlighting
New blimp-tui target built on libvaxis (v0.5.1):
- TEA (Elm Architecture): Model/Msg/update/view cycle
- Split panels: 75% REPL output + input, 25% state sidebar
- Vim modes: insert (default), normal (Escape), :q to quit
- Normal mode: j/k scroll, h/l cursor, w/b word, gg/G top/bottom, dd clear
- Syntax highlighting via existing Lexer token stream
- Multi-line input with do/end depth tracking
- Input history with up/down arrows
- Status bar with mode, counts, depth indicator
Separate target: zig build produces blimp, blimp-compile, and blimp-tui.
Existing targets unaffected. All tests pass.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
af218d8Add blog post: Actors Are Alive
Covers the full day's work: REPL, actor runtime with spawn/refs,
Elm-style errors, LLVM codegen, multiplexer overhaul, agent
decision trees, design docs.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
fab4072Add TUI REPL design doc: TEA architecture, vim navigation, libvaxis
Comprehensive design for the modern REPL TUI:
- TEA (Elm Architecture): Model/Msg/Update/View cycle
- Vim modes: insert (default), normal (Escape), command (:), search (/)
- Full vim keybindings: hjkl, w/b/e, 0/$, #, gg/G, dd, yy, p, u
- Syntax highlighting via existing Lexer token stream
- Tab completion from env/registry/builtins/keywords
- Scrollable split panels with mouse resize
- Multi-line TextBuffer with undo/redo
- Status bar with mode, actor count, cursor position
- Built on libvaxis (Zig 0.15 TUI framework)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
f37d5cbMerge term-diff/deep-look: multiplexer overhaul, deciduous integration
URL-parameterized agents, line selection, dark mode, interactive permissions,
agent decision trees via deciduous, LiveView REPL route.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
eb2f2b8Multiplexer overhaul: URL params, line selection, dark mode, permissions, deciduous
Major term_diff changes from this session:
Multiplexer:
- URL-parameterized agent state (/agents?panes=1,2&dark=1)
- Sidebar-driven pane management (click to toggle open/close)
- Per-pane chat input for continuing conversations
- Dark mode toggle with full theme support
- Interactive permission approval (Allow/Deny buttons)
- Runner defaults to --permission-mode default (not plan)
- PTY wrapper removed for clean stdin on permission responses
- LiveView navigation between Diffs/Agents/REPL tabs
Diff-to-Agent flow:
- Line selection in diff viewer (click + shift-click + drag)
- LineSelection pure module with tests
- Floating commentary prompt on selection
- Submit spawns agent and navigates to /agents?panes=<id>
- LineSelect JS hook for mouse events
Agent decision trees:
- deciduous_root column on runs table
- Deciduous wrapper module (create_root_node, build_agent_preamble)
- Orchestrator injects deciduous context on every dispatch
- Agents get root node ID and active agent info in system prompt
LiveView REPL:
- /repl route with dark terminal + state sidebar
- Spawns blimp binary as Erlang Port
Commentary:
- Added --permission-mode plan to AI.Claude for commentary calls
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
9bcddccAdd agent decision tree design doc: root nodes, overlap, recovery, merge
Covers how agents integrate with deciduous:
- Every agent gets a root goal node, ID stored on run record
- System prompt injection with deciduous context and active agent info
- Overlap detection via file lists and keyword matching
- Dead agent recovery: subtree persists, user can resume from last outcome
- Decision merge across agent subtrees
- Conflict detection and user resolution
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
9342f6aAdd spawn keyword to tree-sitter grammar
- spawn_expression: spawn Counter or spawn Counter(count: 10)
- Added to highlights.scm as keyword
- Corpus tests for basic spawn and spawn with state overrides
- 63/63 tree-sitter tests pass
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
75e1384Add actor runtime design doc: memory model, scheduler, registry
Covers the full runtime architecture:
- Per-actor arenas with Perceus RC (in-place reuse on refcount 1)
- Deep copy at message boundaries, actor refs are lightweight handles
- Preemptive scheduling via reduction counting (BEAM-style, 4000 default)
- FIFO run queue, full stack snapshot on yield, Zig async/suspend
- Global actor registry for message routing and supervision
- Supervision from dot-notation names (Shop.Checkout supervised by Shop)
- Five implementation phases from registry to supervision
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
8b92a5fAdd LLVM codegen: compile Blimp expressions to native executables
New blimp-compile target using LLVM 20 C API via Zig's @cImport:
- codegen.zig: AST -> LLVM IR (integers, floats, binary/unary ops, comparisons)
- compile_main.zig: CLI that parses, compiles, emits object, links with cc
- runtime.c: minimal C runtime (blimp_print_int, blimp_print_float)
- build.zig: separate blimp-compile target linking libLLVM, does not affect REPL
Tested: "1 + 2 * 3" compiles to native binary, outputs 7.
REPL continues to work without LLVM dependency.
All 214 Zig tests pass, no regressions.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
21f7ed2Add compilation pipeline design document: AST to LLVM IR via C API
Comprehensive design doc covering: Blimp IR (typed SSA), lowering passes
for all constructs (pipes, actors, become, message send, situation/case),
LLVM C API integration from Zig, runtime type representation, actor
runtime architecture (mailbox, scheduler, per-actor arenas), and five
build phases from expressions to WASM.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
b4ddbd7Fix last failing tree-sitter pipe test: hole in chained pipe args
61/61 tree-sitter corpus tests now pass.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
a1fff0dAdd REPL design document: architecture, evaluator, state sidebar, errors
Comprehensive design doc covering the dual-mode REPL (TUI + plain),
expression evaluator, actor runtime, Elm-style errors, multi-line input,
state sidebar, and LiveView integration. Living document.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
a52cabdAdd expression evaluator, actor runtime, and REPL
New modules:
- value.zig: runtime Value type (int, float, string, atom, bool, nil, list, tuple, map, hole, actor_instance)
- env.zig: lexically scoped variable environment with allBindings()
- eval.zig: tree-walking interpreter for all expression and actor nodes
- builtins.zig: 9 built-in functions (length, max, min, append, reverse, lookup, put, keys, now)
- errors.zig: Elm-style rich error reporting with source context and hints
Evaluator handles: literals, binary/unary ops, assignments, function calls,
pipes with _ substitution, lists, tuples, maps, dot access, orelse, situation/case
pattern matching, actor definitions, message send (<-), become, reply, guards.
REPL features:
- TUI mode with 75/25 split (REPL left, state sidebar right) when TTY
- Plain mode with parseable output when piped (for LiveView consumption)
- Multi-line input: tracks do/end depth, accumulates until balanced
- State sidebar shows all variables after each evaluation
- Elm-style errors: UNDEFINED VARIABLE, TYPE MISMATCH, DIVISION BY ZERO,
UNKNOWN FUNCTION, NOT AVAILABLE IN REPL, NO MATCHING HANDLER, etc.
Actor semantics: become updates state for next message (not current scope).
214 Zig tests pass.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
c375931Rewrite README: showcase all implemented language features
Updated to reflect current state: actors, typed state, pipes, message send,
guards, situations, holes, bubbles, orelse, dot-notation supervision.
Added implementation status section listing what actually parses.
Updated tooling section: diff follower, agent multiplexer, decision graph.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
b566fffAdd case keyword, type checker, and enforce explicit types
- case keyword: exhaustive pattern matching counterpart to situation
Separate case_expr AST node, parseCase mirrors parseSituation
- Type system (types.zig): Type tagged union with structural equality,
subtyping (Int->Float, nil->list/map/actor, hole as wildcard),
tuple {A, B} and map %{K => V} parsing, scoped TypeEnv
- Type checker (checker.zig): validates state defaults, become fields,
handler param types (required), return types vs reply, binary ops
- Handler params now typed: on :charge(payment: Payment) -> Receipt do
- parseTypeName extended for tuple {A, B} and map %{K => V} syntax
100 Zig tests pass, zero warnings.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
b7b8e8dAdd actor registry: cross-actor type checking, builtins, message send validation
Two-pass checking: pass 1 collects actor state fields and handler
signatures into ActorRegistry, pass 2 type-checks with full cross-actor
knowledge.
- Message sends validated: arg count, arg types, return type resolved
- Dot access resolves actor state field types from registry
- 10 built-in functions typed: length, max, min, remove, append,
lookup, insert, keys, now, validate
- Pipe expression inference threads through right-side calls
- 124 checker tests (24 new: registry, message send, dot access,
builtins, cross-actor integration)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
b517f52Document type system decisions D10-D12, add open questions Q7-Q8
D10: case keyword for exhaustive matching
D11: explicit types everywhere, no inference
D12: type checker first pass and known limitations
Q7: type aliases / struct definitions needed for nominal types
Q8: map key atom vs string semantics
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
0ad5a20Update all .blimp examples with explicit type annotations
Every handler param typed, every handler has a return type,
every state field has Type :: default. Tuple and map return types
used where structurally verifiable. All 12 examples pass the
type checker.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
463c4aaAdd /repl route: LiveView REPL explorer consuming blimp --introspect JSON
Smalltalk-style: the tool IS the environment. New route inside term_diff
renders Blimp source alongside a structured actor sidebar.
- Blimp module: shells out to blimp binary, parses introspection JSON
- ReplLive: file picker bar, source pane with line numbers and keyword
highlighting, actor sidebar with state fields/types/defaults, handler
signatures with params/return types/guards/bubbles, hole locations
with directives and [Fill] button, hole-fill prompt panel
- Zero warnings, clean compile
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ce1b0a2Merge multiplexer from blimp-termdiff worktree into main
Brings in the agent multiplexer system:
- Agent orchestrator, runner (Claude Code subprocess), workspace
- AgentLive: 2x2 split-pane grid with streaming output per pane
- AgentRunLive: per-run detail view
- AgentComponents: pane rendering, sidebar, prompt bar
- EventProcessor: maps raw runner output to structured blocks
- DiffLive: line selection for diff-to-agent flow
- JS hooks: agent auto-scroll, prompt submit
- Routes: /agents, /agents/:id
- Tests: line_selection, agent_live
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
d2e6c5eSync tree-sitter grammar: add actor_name for dot-notation, fix pipe hole tests
- Add actor_name rule supporting dotted names (Shop.Checkout, Shop.Checkout.Tax)
- Update all corpus tests for new actor_name node wrapping upper_identifier
- Add dot-notation actor name corpus tests
- Fix pipe tests to expect (hole) for _ in function call args
- 58/61 tree-sitter tests pass (3 pipe tests pending hole/identifier resolution)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
b46d1d6Add --introspect JSON API for REPL sidebar consumption
New introspect.zig module walks AST and outputs structured JSON:
- Every actor with state fields (name, type, default value)
- Every handler signature (params, return type, guard, bubbles)
- Every Hole with location, directive comment, and context
- Guard expressions rendered back to human-readable strings
Usage: blimp file.blimp --introspect
62 introspect tests, all 13 examples produce valid JSON.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
3b0e8c6Add zig-out/ to gitignore
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
efb3983Update tree-sitter grammar: case, typed params, return types, tuple/map types
- case_expression and case_branch rules
- handler_param rule with name: Type syntax
- return_type rule with -> Type syntax
- type_name now recursive: [T], {A, B}, %{K => V}
- Updated corpus tests for typed handler syntax
- 56/59 tests pass (3 pre-existing pipe hole/identifier issues)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
52d5535Merge pull request #14 from notactuallytreyanastasio/blimp-core/handler-syntax
Add when guards, bubbles(), dot-notation actors
8eff600Add when guards, bubbles() annotation, dot-notation actor names
on :msg(args) when guard bubbles(Strategy) do. Dot-notation
actor names: actor Shop.Checkout do. 38 tree-sitter tests.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
433a23fAdd message send <- and orelse for bubble recovery
actor <- :message(args) for sending. orelse catches bubbles.
Precedence: orelse lowest, then send, then binary ops.
27 Zig tests, 39 tree-sitter.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ce9b27bAdd situation keyword and _ as Hole
Hole is a first-class construct: identity at runtime, agent
directive via comments. situation is ambiguity-aware branching
where Holes are valid. 29 Zig tests, 38 tree-sitter.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
c26666fMerge pull request #12 from notactuallytreyanastasio/blimp-core/situation-holes
Add situation keyword and _ as Hole
dc4dca1Add pipe operator |> (#11)
* Add typed state and tree-sitter corpus tests
Typed state syntax: state name: Type :: default
New :: token in lexer, type_name parsing for Int/String/[Item].
Backwards compatible with untyped state.
Tree-sitter corpus: 34 tests across actors, expressions,
collections, statements, and complete programs.
Zig parser: 21 inline tests. All green.
* Add pipe operator |> with left-associative chaining
Pipe parsing at lowest binary precedence. _ placeholder
in pipe calls filled by pipe value. 26 Zig tests, 38 tree-sitter.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
9e4556efeat: add Tauri desktop wrapper for term_diff
Bundle Phoenix LiveView as a native macOS app using Tauri v2
and Burrito. Sidecar pattern: Tauri spawns the Burrito binary,
polls localhost:4123 until Phoenix is ready, then navigates
the webview to the LiveView.
- Add Burrito dep and release config (macos_silicon target)
- Configure prod for desktop: port 4123, localhost, auto-start
- Remove force_ssl (desktop runs HTTP)
- Scaffold Tauri v2 project at desktop/src-tauri/
- Rust lifecycle: spawn sidecar on Ready, kill on ExitRequested
- Loading spinner while Phoenix boots
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6d1db3anote that rev-parse is in fact just already plumbing
ea59594Fix amend mode: pre-populate message, show last commit diff
Three bugs fixed:
1. Textarea used value= attribute (ignored by browsers for textarea).
Changed to inner content: <textarea>{@commit.message}</textarea>
2. Amend mode now fetches and displays the diff of the commit being
amended in the right pane (full unified diff with hunks).
3. amend_diff cleared on cancel/escape/complete.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
e5bc1ecAdd 26 LiveView integration tests on real git repos
Every test creates a tmp_dir git repo with commits and working tree
changes, mounts DiffLive pointed at it, and exercises the full flow.
Coverage:
- Navigation: j/k movement, Enter/q focus, Tab toggle, log view
- Stage/unstage: s stages, u unstages, rapid s/u/s/u, s from diff_view,
u on unstaged-only is no-op
- Commit mode: cc with nothing staged (error), cc with staged (editor),
Escape exits, empty message (error), valid message (creates real commit)
- Amend mode: a pre-populates message, shows amend diff, Escape/cancel
exits, submit updates real commit message
- Click to select, follow mode toggle, unknown keys survive,
rapid multi-key sequences don't crash
Also fixes diff parser crash on optional hunk header captures
(nil/empty string from regex groups).
183 total tests, 0 failures.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
9116bb9Fix amend mode: pre-populate message, show last commit diff
Three bugs fixed:
1. Textarea used value= attribute (ignored by browsers for textarea).
Changed to inner content: <textarea>{@commit.message}</textarea>
2. Amend mode now fetches and displays the diff of the commit being
amended in the right pane (full unified diff with hunks).
3. amend_diff cleared on cancel/escape/complete.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2f52939Add 26 LiveView integration tests on real git repos
Every test creates a tmp_dir git repo with commits and working tree
changes, mounts DiffLive pointed at it, and exercises the full flow.
Coverage:
- Navigation: j/k movement, Enter/q focus, Tab toggle, log view
- Stage/unstage: s stages, u unstages, rapid s/u/s/u, s from diff_view,
u on unstaged-only is no-op
- Commit mode: cc with nothing staged (error), cc with staged (editor),
Escape exits, empty message (error), valid message (creates real commit)
- Amend mode: a pre-populates message, shows amend diff, Escape/cancel
exits, submit updates real commit message
- Click to select, follow mode toggle, unknown keys survive,
rapid multi-key sequences don't crash
Also fixes diff parser crash on optional hunk header captures
(nil/empty string from regex groups).
183 total tests, 0 failures.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
dc4c2d8note that rev-parse is in fact just already plumbing
e37cfa1Add tooling paragraph: diff viewer, semantic diffs, time travel, reflexivity
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
8ba4c79Add blog post: The Construction of Blimp
Second design journal entry walking through the grammar piece by piece.
Covers actors, typed state (Type :: default), Holes as first-class
agent directives, situation for ambiguity-aware branching, bubbles as
supervision actors, no shared memory, and supervisor-as-namespace with
both flat dot-notation and nested forms.
Also updates parser.md with decisions D4-D9 from this session.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
f305deeAdd note about diff viewer already existing, turtles all the way down
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
c0584edAdd blog post: The Construction of Blimp
Second design journal entry walking through the grammar piece by piece.
Covers actors, typed state (Type :: default), Holes as first-class
agent directives, situation for ambiguity-aware branching, bubbles as
supervision actors, no shared memory, and supervisor-as-namespace with
both flat dot-notation and nested forms.
Also updates parser.md with decisions D4-D9 from this session.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2024-07-31 · Chaifetz Arena, Saint Louis University
♥ Most Loved: 38 likes
2017-07-26 · Madison Square Garden
📊 93% Set 2 · 8/8 JCs from Set 2
Last: 2024-07-31 (601d ago) · avg every 184d
Best year: 2017 — 2/2 JC
🔥 JC Streak: 4 in a row
"Busted out after a 380 show absence, Phish goes 2 for 2 on delivering the goods ..."
TAP TO SEE AND PLAY JAMS
Mr. Completely
.533
TAP TO FLIP BACK
8 jams
★
2017-07-19
21:18
Petersen Events Center · Pittsburgh, PA
Busted out after a 380 show absence, Phish goes 2 for 2 on delivering the goods with this TAB standby. The jam quickly goes "Type II" and features bliss jamming aplenty as well as some new synth sounds from Page.
★
2017-07-26
13:52
Madison Square Garden · New York, NY
Surprising -> out of a great "Carini". A fiery minor key jam develops out of the verses, and Page takes control on the keys as Trey fires off echo-laden notes. They pivot nicely into a new key, where Mike really impresses and Fish pushes the tempo up a gear as Trey plays around with the "Mr. Completely" theme and leads the band into an anthemic finale. A high-spirited, energetic good time, with a > into an even more surprising "1999".
★
2021-08-04
18:55
Ascend Amphitheater · Nashville, TN
The opening to one of the year's strongest second frames, this "Mr. Completely" indulges in its usual jam before Fish switches up his flow and Trey moves into a new key. Page's electric piano cuts through the mire, and a warm groove emerges as a result. Fish starts throwing in the "Mr. Completely" drum fill almost as a challenge to himself, and Trey moves to stabbing echo-laden chords as the jam picks up speed "Bathtub Gin" style. Something funkier and stranger emerges, and Mike flips on his envelope filter as the jam builds to a ferocious climax, then dies away with some more "Mr. Completely" drum fills by Fish for fun. > into "BOAF".
★
2021-08-29
18:47
Gorge Amphitheatre · George, WA
Quickly maneuvers into major-key bliss, distinguished by some frenetic playing from Fishman, then moves into a brisker and snappier zone thanks to Trey switching to chords. The band briefly dips into contemplative minor key playing, before moving to something more upbeat, with Page's electric piano at the forefront. Trey's effects-smothered guitar playing and Page's synths combine wonderfully, with Mike going to the envelope filter and Fish as steady as ever. Very good -> into "Meat" to close. A fine companion piece to the 8/4/21 version.
★
2022-08-13
14:26
Alpine Valley Music Theatre · East Troy, WI
First locks into a super-cool and menacing, textural jam with a perfectly integrated "Crazy Train" tease from Trey, then slides into major for a heavenly spell before more familiar bliss brings it all home.
★
2023-04-23
18:03
Hollywood Bowl · Hollywood, CA
Another huge version of the once rare song in the catalog. Plucky playing from Trey around 9:30 changes the jam's trajectory. The searching, grimy jam sounds like the background to a noir detective show at times. The tempo gets kicked up towards the end, before eventually > "A Song I Heard the Ocean Sing".
★
2023-04-23
0:56
Hollywood Bowl · Hollywood, CA
-> from "A Song I Heard the Ocean Sing" to close out the "Mr C" > "ASIHTOS" -> "Mr C" sandwich.
★
2024-07-31
22:29
Chaifetz Arena, Saint Louis University · St. Louis, MO
After transitioning away from the song, Pageâs grand piano gives the improvisation shape and direction as Trey responds leading the band through uplifting and thematic play that modulates across both delicate and thornier spaces. Listen for Mike's "Meowdulator" pedal and Trey's "Hanon exercises" to make appearances before returning to the song proper to close.
Disappointed that War does not lead to actual combined-arms conflict.
jeff
04:01 AM
that would be hard to conjure
jeff
04:02 AM
I am so excited that this works and is a successful combination of windows and old apple lol
Uechi Nerd
04:02 AM
Probably for the best, actually. That shit is very very messy.
Uechi Nerd
04:02 AM
I am intrigued and happy it works!
Uechi Nerd
04:03 AM
I respect the wizardry.
Visitor7804
04:05 AM
this is delightful.
jeff
04:06 AM
hell yeah visitor 7804, this is livin' brother
guy4get
04:07 AM
i've never felt so alive
EarlofVincent
04:09 AM
Commencing experiment in 3....2....
jeff
04:14 AM
1
leah
04:16 AM
hi!
leah
04:16 AM
this is lovely
jeff
04:21 AM
hi! lol I was just like what if I combined Mac and windows and added a flower tree of life and called it my homepage and then smoked some weed and made it happen in an empty mall in Connecticut
B. Droptables
10:51 AM
Always cool to play with your toys.
Visitor1128
08:47 AM
yo!
Visitor1128
08:48 AM
i can barely work my phone. what am i doing here?
jeff
09:04 AM
the phone is not optimized yet but it "kind of works" I am sorry lol
jeff
09:04 AM
you have to pick a username, then it goes to the chat, then if you hit the bottom tabs it'll let you go to the app sections.
Bobdawg
04:43 AM
Hi everybody this is my blog I hope you enjoy it I did some more changes and anyone can write a post here now for me.
dinkleberg
01:45 AM
ALL HAIL TREE OF LIFE
jeff
08:55 PM
hi Hacker News
jeff
04:28 PM
hey there I am not really Jeff
Mal Function
05:34 PM
Hey! Please reveal... how exactly do I actually use losselot on my Mac? I've run the git clone commend in Terminal.app and seem successfully to have installed into a new <losselot> sub-folder in my home folder but now???