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>
3b0e8c6Add zig-out/ to gitignore
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
c26666fMerge pull request #12 from notactuallytreyanastasio/blimp-core/situation-holes
Add situation keyword and _ as Hole
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>
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
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>
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>
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>
9cd97aaWIP: Blimp grammar, lexer, parser, and tree-sitter grammar
Zig parser (chunks/lang/src/):
- token.zig: 50+ token types with keyword lookup
- lexer.zig: single-pass lexer, line/col tracking, 9 test blocks
- ast.zig: tagged union AST with 16 node types
- parser.zig: recursive descent with Pratt precedence, 8 test blocks
- main.zig: CLI reads .blimp files, prints S-expression AST
Tree-sitter grammar (chunks/lang/tree-sitter-blimp/):
- grammar.js: actors, state, on/become/reply, expressions
- highlights.scm: syntax highlighting queries
7 example .blimp programs all parse successfully.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
5669d74Add note about diff viewer already existing, turtles all the way down
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
9c373bcFix 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>
0b8029cnote that rev-parse is in fact just already plumbing
3e992e9Fix nav pipeline clobbering refreshed state after stage/unstage
handle_nav_change was using the pre-stage nav, overwriting the
freshly synced nav from refresh_now. Now re-reads socket.assigns.nav
after handle_stage_actions so downstream steps see the real state.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
4c7302dAdd FileState state machine for git staging lifecycle
Every file is in exactly one state (untracked, staged_new,
unstaged_modified, staged_modified, partial_modified, etc).
Each state returns the correct git command for stage/unstage
via stage_command/1 and unstage_command/1.
DiffLive now derives FileState from the file entry and delegates
to Runner.exec_file_command/2 instead of ad-hoc conditionals.
All Runner errors are logged and surfaced via put_flash.
24 new FileState tests. 142 total, 0 failures.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
84b75f5Extract CommitState pure state machine from Navigation
Moves commit workflow (idle->editing->submitting->complete/error) into
its own module with explicit phases. Navigation no longer tracks
commit_mode/amend_mode. Errors shown inline instead of flash messages.
Nothing-staged and no-previous-commit cases blocked at entry.
108 tests, 0 failures, 0 warnings.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
9abc7cfFix Commentary.Server supervision and eliminate Process.sleep in tests
Replace async_nolink with start_child + explicit message passing.
Task sends {:review_complete, result} back to GenServer on completion.
Tests use assert_receive instead of Process.sleep for determinism.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
f399bd4Modernize HEEx syntax and refactor submit_commit
Replace <%= if/for with :if/:for attributes across all templates.
Replace <%= expr %> with {expr} curly brace syntax throughout.
Break nested if-inside-case in submit_commit into separate functions:
execute_commit, run_git_commit, handle_commit_result.
Fix alias ordering (alphabetical within groups).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
61f9a8dSplit Commentary.Types into one type per file
Annotation, ReviewResult, FileCommentary each get their own module
file under commentary/. Updated all alias references.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
16392f7Add --json-schema support for forced structured JSON output
Claude.build_args now accepts :json_schema option, passing
--json-schema flag to claude -p for validated structured output.
Prompt module defines the review schema (summary + annotations array
with file, start_line, end_line, comment, severity enum).
Server's default_caller passes the schema automatically.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
efcdeedFix stale state after stage/unstage: synchronous refresh
After a git stage/unstage command, immediately re-fetch repo state
instead of relying on async send(self(), :refresh). This prevents
the next keypress from seeing stale file states where a just-staged
file still appears as unstaged.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
67f5c13Fix unstage on newly added files
git restore --staged fails on :added files (no prior version to
restore to). Now checks staged_status: :added files use
git rm --cached, :modified files use git restore --staged.
DiffLive passes the file's staged_status from RepoState.
Three new Runner tests covering the exact bug scenario.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
d8440d2Migrate Runner from System.cmd to Erlang Port
All git commands now execute via Port.open with :spawn_executable.
Supports expected_exits option for commands like diff --no-index
that return exit code 1 on success. Adds 10s timeout.
Includes first Runner test suite (8 integration tests with tmp_dir).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
13d528bConvert CommitState to embedded Ecto schema
Uses Ecto.Enum for phase and mode fields instead of plain @type.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
8335c10Watch .git/index and refs for stage/commit/branch changes
Watcher was ignoring ALL .git/ paths. Now watches specific git
internal files: index (stage/unstage), refs/ (commits/branches),
HEAD (checkout), MERGE_HEAD/REBASE_HEAD (merge/rebase).
External git operations (staging from another terminal, git hooks)
now trigger UI refresh automatically.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
69f47c7Update build-test skill for Elixir project quality cycle
Replaces cargo build/test with mix compile/test/credo pipeline.
Adds TDD reminder, frontmatter metadata, and mix.exs auto-discovery.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
5a7898aFix Runner stripping leading whitespace from git status output
String.trim() was removing the leading space from porcelain status
lines like " M file.ex", causing Status.parse to fail on files with
only unstaged changes. Changed to String.trim_trailing() to preserve
the significant leading column characters.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2af65dbAdd plumbing_status/1 using diff-index, diff-files, ls-files
New Runner.plumbing_status/1 returns [FileState.t()] directly
from three plumbing commands instead of parsing porcelain output.
Runs alongside the existing status/1 for now.
9 integration tests covering all file states: untracked, staged_new,
unstaged_modified, staged_modified, partial_modified, staged_deleted,
unstaged_deleted, and mixed multi-file scenarios.
157 total tests, 0 failures.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
31d07c1Fix cursor drift after stage/unstage with path-based tracking
Navigation.sync_to_files/2 resolves file_index from selected_file
path instead of blindly trusting the index. After refresh, the
cursor stays on the same file even when the list reorders.
Removes ad-hoc selected_file resolution from keydown handler.
The refresh handler now syncs nav to the new file list properly.
6 new tests for sync_to_files covering: path resolution, file
removal, empty list, nil selected_file, list shrink clamping.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
4a19037Add Elixir/HEEx style rules to CLAUDE.md
Codifies preferences from PR #1 review: HEEx curly brace syntax,
:if/:for attributes, no nested if/case, no Process.sleep in tests,
one type per file, embedded Ecto schemas, supervision patterns.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
98faa5aFix s/u keybindings: work from both file_list and diff_view
stage_selected and unstage_selected were restricted to :file_list
focus only. Now they fire from :diff_view too (anywhere a file is
selected). Guards on nil selected_file prevent empty commands.
Log_view/log_detail still no-op (no file context there).
6 new Navigation tests for s/u across focus states.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
d152c17Remove LLMChain/CodeReviewer code entirely
Deleting the Ollama-based code reviewer and langchain dependency.
Will revisit AI review via claude -p CLI approach later.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
cbc418dAdd 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>
a2add80Fix nav pipeline clobbering refreshed state after stage/unstage
handle_nav_change was using the pre-stage nav, overwriting the
freshly synced nav from refresh_now. Now re-reads socket.assigns.nav
after handle_stage_actions so downstream steps see the real state.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
046d9d6Watch .git/index and refs for stage/commit/branch changes
Watcher was ignoring ALL .git/ paths. Now watches specific git
internal files: index (stage/unstage), refs/ (commits/branches),
HEAD (checkout), MERGE_HEAD/REBASE_HEAD (merge/rebase).
External git operations (staging from another terminal, git hooks)
now trigger UI refresh automatically.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
4d68766Fix stale state after stage/unstage: synchronous refresh
After a git stage/unstage command, immediately re-fetch repo state
instead of relying on async send(self(), :refresh). This prevents
the next keypress from seeing stale file states where a just-staged
file still appears as unstaged.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
9f8b342Add plumbing_status/1 using diff-index, diff-files, ls-files
New Runner.plumbing_status/1 returns [FileState.t()] directly
from three plumbing commands instead of parsing porcelain output.
Runs alongside the existing status/1 for now.
9 integration tests covering all file states: untracked, staged_new,
unstaged_modified, staged_modified, partial_modified, staged_deleted,
unstaged_deleted, and mixed multi-file scenarios.
157 total tests, 0 failures.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
dc37df7Fix s/u keybindings: work from both file_list and diff_view
stage_selected and unstage_selected were restricted to :file_list
focus only. Now they fire from :diff_view too (anywhere a file is
selected). Guards on nil selected_file prevent empty commands.
Log_view/log_detail still no-op (no file context there).
6 new Navigation tests for s/u across focus states.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
c6da445Add FileState state machine for git staging lifecycle
Every file is in exactly one state (untracked, staged_new,
unstaged_modified, staged_modified, partial_modified, etc).
Each state returns the correct git command for stage/unstage
via stage_command/1 and unstage_command/1.
DiffLive now derives FileState from the file entry and delegates
to Runner.exec_file_command/2 instead of ad-hoc conditionals.
All Runner errors are logged and surfaced via put_flash.
24 new FileState tests. 142 total, 0 failures.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
8ed2fd4feat: replace tungstenite with hand-rolled WebSocket over raw TCP
tungstenite corrupts internal state when read/write are interleaved
from different threads, even with Mutex protection. Replace it with
a minimal WebSocket implementation (~150 lines) that:
- Does HTTP upgrade handshake byte-by-byte (avoids BufReader read-ahead)
- Uses TcpStream::try_clone() to split into independent read/write halves
- Reader thread owns the read half, writer Mutex holds the write half
- No shared internal framing state — reads and writes are independent
- SHA-1 for the accept key via sha1_smol (only external dep)
Also removes the sleep() debug logging.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
9a9b350fix: set read timeout on WS connections for Rust backend
Both server-accepted and client connections now have a 50ms read
timeout. This prevents the recv loop from holding the socket Mutex
indefinitely, allowing send operations to interleave. Without this,
the Rust server couldn't send frames because recv blocked the lock.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
3a512b1fix: use dedicated threads for Rust ws operations
Temper's Rust runtime uses a single-threaded task runner. Blocking
ws operations (accept, send, recv) would block the runner and
prevent other async blocks (like readLine) from processing.
Spawn dedicated threads for ws_accept, ws_send, and ws_recv instead
of going through crate::run_async. This lets the WS operations
block independently while other async work continues.
Also adds error logging to ws_recv for debugging.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
561c49afeat: add Python backend for std/ws and std/io terminal size
Wire WebSocket support (wsListen, wsAccept, wsConnect, wsSend, wsRecv,
wsClose) and terminal size detection (terminalColumns, terminalRows)
for the Python backend.
Uses hand-rolled WebSocket over raw TCP (same approach as Rust) with
socket.dup() for read/write split and a dedicated reader thread per
connection. No external dependencies — just stdlib socket, hashlib,
base64, struct, threading.
Terminal size uses shutil.get_terminal_size().
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
936910dfix: guard wsSend against closed WebSocket connections
Check readyState before calling send(), and wrap in try/catch to
prevent synchronous throws from crashing the server when a client
disconnects mid-broadcast.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
73b848dfix: Rust ws support - rename functions, fix visibility and stream types
- Rename support functions to std_ws_* to avoid colliding with
Temper-generated panic stubs (same pattern as std_sleep/std_read_line)
- Change visibility from pub(crate) to pub for cross-crate access
- Accept &dyn WsServerTrait/WsConnectionTrait instead of &WsServer to
work with the Rust backend's interface deref codegen
- Use WsStream enum to handle both WebSocket<TcpStream> (server-accepted)
and WebSocket<MaybeTlsStream<TcpStream>> (client-connected)
- Use temper_core::cast() for downcasting instead of manual as_any chain
- Add .into() for tungstenite 0.26 Message::Text(Utf8Bytes) change
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 (600d 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???