• v1.4.0 19091973a4

    v1.4.0 — live tool tokens, a real terminal pane, and one-command tailnet access
    Some checks failed
    ci / gate (push) Has been cancelled
    Stable

    evileko released this 2026-09-20 04:52:36 -04:00 | 0 commits to main since this release

    evilcode v1.4.0 — live tool tokens, a real terminal pane, and one-command tailnet access

    This release makes tool use visible while it happens. Tool calls now type into the transcript as their arguments arrive, and the Ctrl+L split follows the active call: bash output behaves like a live terminal, file mutations assemble against the file on disk, Markdown renders while it is being written, and every other tool gets a bounded preview instead of a blank panel.

    It also adds /tailscale, which brings up the web companion on the current tailnet from inside the TUI, plus a broad daemon and agent reliability pass covering fan-out, replay, wakeups, prompt durability, and concurrent model/context updates.

    What changed

    Live tool calls from provider to TUI

    • Arguments stream end to end. OpenAI, Codex, Ollama, and non-streaming providers now expose one stable call identity and the same start/delta semantics; malformed or partial JSON remains safe to preview while it is arriving.
    • The transcript types along. Tool rows appear when a call starts and update in place as arguments arrive, then reconcile with the authoritative completed call.
    • Replay is self-healing. Daemon attach and ring replay preserve live deltas without changing the final headless response shape, and a full payload repairs a missed or interrupted delta stream.

    A genuinely live Ctrl+L split

    • Bash is a terminal pane. The command appears as it is assembled, stdout and stderr append while the process runs, ANSI control sequences are stripped for safe rendering, and retained output is bounded.
    • Writes and edits assemble visibly. write, edit, and multiedit previews are applied to the current on-disk file as their JSON arrives. Diffs use the same syntax-aware highlight-then-tint treatment as the inline transcript.
    • Markdown renders while streaming. Whole-document .md writes render uncached during assembly and settle into the normal cached preview at completion.
    • Every tool has a fallback. Unknown tools show a dimmed, bounded raw-argument preview rather than leaving the split stale or empty. The newest active call owns the panel, and completed calls reconcile it cleanly.

    /tailscale

    • Run /tailscale inside evilcode to start the web companion on loopback, configure tailscale serve --bg, and display the tailnet URL and QR code.
    • Existing Serve routes are respected, failures are surfaced in the transcript, and the command includes a safe cleanup path.

    Agent and daemon reliability

    • Worker fan-out now reserves capacity correctly, wakes reliably, and persists session-log delivery without races.
    • Attach snapshot plus replay has one publication boundary, avoiding gaps and duplicates during concurrent activity.
    • Prompt rebuilds and context-window/model transitions are synchronized without holding locks across provider work; retry delays saturate safely.
    • Web ask cards lock for the full answer lifecycle and disable their controls once answered.

    Install or update

    Fresh install:

    curl -fsSL https://evileko.dev/evilcode | sh
    

    Existing installations can update in place:

    evilcode update
    

    Source builds require Go 1.26 or newer. This release publishes the Linux/amd64 binary evilcode-linux-amd64.

    Verification

    • go build ./...
    • go vet ./...
    • go mod verify
    • go test ./... -count=1
    • go test -race ./internal/agent ./internal/provider ./internal/tools ./internal/daemon ./internal/tui
    • go test -tags probe ./probe -count=1

    SHA-256 for evilcode-linux-amd64:

    1e569761f72689e6aace283d0faa3f7f37055195a68916c457c529aec076eb4b
    
    Downloads
  • v1.3.0 0d1fb97f98

    v1.3.0 — the web companion, a ported compaction engine, and a steadier transcript
    Some checks failed
    ci / gate (push) Has been cancelled
    Stable

    evileko released this 2026-09-17 00:10:23 -04:00 | 24 commits to main since this release

    evilcode v1.3.0 — the web companion, a ported compaction engine, and a steadier transcript

    The headline of this release is the web companion: the daemon now serves a real second frontend, so the roster and the full chat — streaming, interrupts, answers, model and effort switching, commands, spawning — drive the same session from a browser or a phone. Alongside it: the compaction engine ported from omp with overflow recovery and full-document handoff, a four-phase orchestrator swarm with live worker previews, every MCP corner found in review hardened, and a transcript that holds still while you read instead of sliding away.

    What changed

    The web companion (P1–P7)

    • A second frontend in the daemon. The [webui] config table, an embedded app shell with manifest, icons, and security headers, token auth with a handoff cookie and Origin+Host discipline, and -web / -web-addr flags with a startup line and a once-only tokenized URL.
    • A live mirror. An SSE event stream replays the attach sequence against a durable deep-history reader with pagination, so a browser session looks like a TUI window: a live snapshot or stored read-only history per session.
    • The full command surface. Input, interrupt, ask answers, model and effort switching, slash commands, session create and spawn, and the models list — the browser can drive everything the TUI can.
    • Design system. Palette-driven CSS token generation keeps the web theme in step with the TUI's themes, and the transcript engine mirrors streaming, tool rows, and history.
    • Mobile and PWA. Install hint, keyboard shim, touch audit, reconnect resilience, and a wake lock.
    • Network hardening. Tailscale forwarded hosts, proxied same-origin writes, and a trusted-network auth opt-out for homelab use.

    Compaction, ported from omp

    • The engine. A candidate chain with trigger thresholds, per-turn pruning that reclaims superseded reads, and the shake strategy for deterministic reclaim; overflow and incomplete recovery are handled inside agent.Run.
    • Handoff. A full-document continuation strategy for turns that outgrow the window.
    • Storage meta and display. Short summaries and before-tokens land in storage, and the TUI can visualize and inspect what compaction did.
    • Budget discipline. Compaction checks every round, and manual compaction no longer consumes the auto budget. A dedicated embedding model can power semantic memory and compaction relevance, decoupled from the chat choice.

    The orchestrator swarm and grunts

    • Four phases. Parallel spawn scheduling with wait:false, per-call model routing with an audit trail, layered guidance across four layers, and ops knobs — cancel and partial results, a depth flag, and cost rollup — plus live-cap fixes for real reservation counting.
    • Grunts. Workers are named grunt-N off an on-disk high-water mark, preview live in boxes on the start screen and transcript with click-to-expand, and can attach in observe mode.

    MCP hardening

    Nine review gaps closed: per-server call timeouts, every result content type plus structured content, pagination cursors, tools/list_changed refresh reaching the agent, streamable HTTP for hosted servers, an environment allowlist for server subprocesses, dead-server reconnect with surfaced status, prompts and resources adapted into the tool set, and schema diagnostics with a real version and duplicate refusal.

    A steadier transcript

    • Scrolling up holds the window. Reading old context while the agent streams no longer slides away: the window stays put until you scroll back to the bottom, background completions no longer yank it, and their failure notices actually reach the frame.
    • Status lines expire. Transient notices clear after 8 seconds — configurable with display.notice_ttl — instead of going stale; the detach confirm and masked-input prompts stay pinned, and a failed background task becomes a transcript block instead of a flash.
    • Other agents share the streaming line (streaming… · 1 agent · bat) instead of spending their own row.
    • The overscroll reveal got substance. Pulling past the bottom shows the context window with its meter, the cache hit rate (or an honest n/a), the model with its effort and thinking mode, and the location — and it reserves its rows, so it shows even when the window is full.
    • Auto-poke is opt-in. features.auto_poke = true restores the old behavior; the /poke toggle and the orchestrator's save/restore are unchanged.
    • Responses thinking streams. OpenAI Responses models now request a reasoning summary, so thinking deltas reach the TUI instead of opaque encrypted items.

    Daemon and session reliability

    • A daemon holds its socket claim for life; a session is created on the first prompt and an idle daemon stops on quit; stale-socket recovery keeps the lifetime lock through the race.
    • Reasoning-only responses retry instead of ending the turn, restore the normal agentic loop, and stream a thought's last word with the thought.
    • The R2 hardening pass: daemon frames can no longer exceed the client's 8 MiB limit, the replay ring subtracts replaced events, a refused dispatch restores the prompt, workspace confinement fails closed with a descriptor walk, model-run shell commands get an environment allowlist, role fallback chains fire at runtime, the updater verifies checksum manifests, credentials are validated before they are committed, model switching builds its candidate off the lock, and strict decoding repairs the argument shapes real models send. A CI workflow runs the review's minimum gate.

    Install or update

    Fresh install:

    curl -fsSL https://evileko.dev/evilcode | sh
    

    Existing installations can update in place:

    evilcode update
    

    Source builds require Go 1.26 or newer. This release publishes the Linux/amd64 binary evilcode-linux-amd64.

    Verification

    • go build ./...
    • go test ./internal/...
    • go vet ./...

    SHA-256 for evilcode-linux-amd64:

    1cd9ae5049b5a75f5b8ed3e4aeba77203e41f7b02c4f11d6424b6486cd91a9ab
    
    Downloads
  • v1.2.0 b0fcfb8cb2

    evileko released this 2026-08-26 19:15:37 -04:00 | 135 commits to main since this release

    evilcode v1.2.0 — the Live panel

    The headline of this release is the Live panel: the side split is now a real second viewport that shows whole files, scrolls under the mouse, and can follow the agent as it works. The release also restores full context on resumed sessions, makes reasoning effort work for models the name heuristic doesn't recognize, and switches the default theme.

    What changed

    The Live panel (split view upgrade)

    • Whole files, not truncated diffs. Clicking a write/edit block opens the entire file in the side pane with the change marked in the gutter — added lines numbered with +, deleted lines inserted where they were removed — centered on the first hunk. Unreadable or binary files fall back to the diff alone.
    • Ctrl+L live view. The split follows the agent: every read/write/edit tool result opens the touched file in the pane — whole file with the diff marked for edits, highlighted source for reads — scrolled to the change, updating as each edit streams in. A green live tag sits bottom-left while active. Clicking a file or closing the split turns live view off; scrolling the pane away pauses the follow and scrolling back to the top resumes it. Ctrl+L is a true toggle: off → on opens the pane, on → off closes it.
    • Wheel scrolls the side under the mouse. The wheel drives the pane when the pointer is over it and the transcript when it is not, with the panel scrolling independently instead of truncating. Wheel direction is natural (up = toward the top of the file).
    • ctrl+q closes the split. Plain q is an ordinary letter again and types even while the split is open; ctrl+q closes the split (quick view first, then the panel and live view) regardless of composer state. The pane footer and the help overlay show the bindings.
    • Numbered read views. Read quick views (and live view's read tracking) show line numbers like the diff views, so a read and an edit of the same file line up.
    • No more per-frame lag. The pane body is cached across frames (keyed by content identity, path, diff, mode, width, and palette), so a warm frame costs ~1.2ms instead of ~50ms per wheel notch on a 1000-line file. A guard test pins that the wheel frame cost does not grow with session length.
    • Footer stays put. The panel footer stays on the last visible row when the chat overflows, and the pane only auto-updates in live view.

    Resumed sessions keep their context

    Resuming a session (or viewing it from another window) dropped half of every tool row: bash rows said "bash" with no command or output, and edits had no diff. Tool blocks are now rebuilt from both halves of the conversation — the tool call and its result — so resumed sessions re-render the command, output, target, path, token estimate, and the diff a write/edit produced, including the +/- counts and the whole-file quick view on click. The session picker and start-page previews show real tool rows too.

    Reasoning effort works for unrecognized models

    Setting a reasoning effort on a model the name heuristic doesn't match (e.g. deepseek-v4-flash:0731, kimi-k2.6, minimax-m3) was rejected with "reasoning effort not supported" even though the model advertises thinking. The daemon now enriches via the model's /api/show capability when the heuristic misses, so the offered levels match what the client picker shows. The heuristic still serves matched families without a network call; an unreachable endpoint behaves as before.

    Default theme: catppuccin-frappe (mauve)

    The default theme is now catppuccin-frappe with mauve accents instead of dracula. Syntax highlighting uses chroma's frappe style so code matches the chrome, and the no-op fast path is frappe. Existing configs that state their own theme are untouched.

    Install or update

    Fresh install:

    curl -fsSL https://evileko.dev/evilcode | sh
    

    Existing installations can update in place:

    evilcode update
    

    Source builds require Go 1.26 or newer. This release publishes the Linux/amd64 binary evilcode-linux-amd64.

    Verification

    • go build ./...
    • go test ./internal/...
    • go vet ./...

    SHA-256 for evilcode-linux-amd64:

    485dbf746bbc435d6220e45053cbc9b2692388e25c61b2d49e3919de184b748f
    
    Downloads
  • v1.1.4 04b17c1508

    evileko released this 2026-08-26 04:15:38 -04:00 | 157 commits to main since this release

    evilcode v1.1.4 — accurate percents, queued prompts, and hardening

    This patch release fixes the display bugs found in day-to-day use and
    completes the codex-review memory-safety item D2.

    Highlights

    Progress figures are now exact

    • The docked Todos widget and the todo card's group headers previously
      showed the model's confidence score as the percent — 4/4 done could read
      94% or 96%. The percent is now computed from item statuses: ●●○○ 1/4 done · 25%, and an all-closed group reads 100% no matter what the
      honest scores say.
    • The context meter rounds to the nearest percent and prefers the
      provider-reported window, so it no longer systematically under-reads.
    • The KV-cache hit rate uses the same rounding.

    Queued prompts wait where they belong

    • Sending a prompt while a turn is running used to draw it in the transcript
      immediately, even though the daemon only delivers it when the turn ends.
      Queued prompts now wait in a strip above the composer and enter the
      transcript when their turn actually starts. Rejected queued inputs (queue
      full) drop off the strip instead of lingering.

    Multi-line composer navigation

    • Up/Down arrows now move the caret between lines of a multi-line prompt
      (column-preserving, clamped to shorter lines). Previously they did nothing
      once the composer had text.

    Cloud Usage widget is Ollama-only

    • The widget now fetches and renders only while an Ollama provider (local or
      cloud) is active — it scrapes the Ollama settings page, which says nothing
      about a Codex, OpenAI-compatible, or mock session.
    • A bare __Secure-session token is base64 and often ends in = padding; it
      was mistaken for a full Cookie: header line, so the request carried no
      usable cookie and the widget said "session expired" even though the session
      was live. Bare tokens are now wrapped correctly (a ; or a cookie-name
      prefix still passes a full header through).

    Argument repairs teach the model

    • Tool arguments repaired by the alias layer (command→cmd, …) were only
      flagged in the UI row, which the model never sees — so a model that emits
      command did it on every call and every row carried the note. The repair is
      now also surfaced in the tool result the model reads, so it adopts the
      canonical names and the repairs stop.

    Session hardening (D2 completed)

    • The daemon's replay ring is byte-bounded (16 MiB budget; the oldest events
      are evicted) in addition to its 4096-event count cap, and Result.Diff is
      capped at 1 MiB separately from model-visible output.

    Install or update

    Fresh install:

    curl -fsSL https://evileko.dev/evilcode | sh
    

    Existing installations can update in place:

    evilcode update
    

    Source builds require Go 1.26 or newer. This release publishes the Linux/amd64
    binary evilcode-linux-amd64.

    Verification

    • go test ./...
    • go vet ./...
    • Probe suite (go test -tags probe ./probe/...) green, goldens refreshed

    SHA-256 for evilcode-linux-amd64:

    01396e81572c8f2f8ed23c6ed05f54307fabde6b48060c93ec8d05de5a7c88f8
    
    Downloads
  • v1.1.3 71e343d6b7

    evileko released this 2026-08-26 00:59:25 -04:00 | 174 commits to main since this release

    evilcode v1.1.3 — deepseek default, picker hints, more idle tips

    A small feature release. The agent loop, tool surface, and session model are unchanged; what changed is the out-of-the-box model, how discoverable the model picker's default-setter is, how many niche features the idle tip rotation surfaces, and two fixes to how the daemon path remembers and swaps the model.

    What changed

    New default model: deepseek-v4-flash:0731 (high)

    • The default model is now deepseek-v4-flash:0731@ollama-cloud (reasoning effort high), routed through Ollama Cloud when OLLAMA_API_KEY is set, and through the local Ollama daemon (deepseek-v4-flash:0731@ollama-local) when it is not. The previous default was glm-5.2:cloud.
    • deepseek-v4-flash:0731 is a thinking model, so the default routes pin reasoning effort to high for both the cloud and local routes. A user's saved per-model preference still overrides this at runtime.
    • This only affects fresh configs with no default_model set. An existing config.toml that states its own default_model is untouched.

    The model picker now tells you how to set the default

    • The picker's default-setter (Ctrl+O) was undiscoverable — it lived only in the one-line key summary above the box, which truncated to a meaningless Ctrl+O · Ctrl+N on narrow terminals. Now:
      • The key-summary hint keeps the verb at every width, down to Ctrl+O set default on the narrowest.
      • A contextual Ctrl+O set as default hint appears right at the model the cursor is on, for any selectable model that is not already the default. It is combined with the reasoning-level line when present (e.g. reasoning: high · Ctrl+O set as default), and never shown for an unavailable model.
    • No new key binding was added, so filtering the picker by typing (including d to reach deepseek models) is unchanged.

    The idle tip rotation covers the niche features

    • The idle Tips rotation is the only passive discovery surface — a user who never opens /help and never presses an undiscovered chord still sees it rotate in the status line and the right-side dock. It went from 5 entries to 16, now covering:
      • Niche keybindings that had no other passive surface: Alt+B (send a running tool to the background), Alt+R (cycle reasoning effort), Ctrl+Up (retrieve staged messages), Alt+G (cycle diff mode), Ctrl+P (toggle auto-poke).
      • The right-side dock widgets and side panel: Alt+I (info widgets), Alt+X (todo card), Alt+M (side panel).
      • Niche slash commands only /help would otherwise reveal: /btw (a side question that costs no main context), /rewind (collapse back to a checkpoint).
    • A guard test (TestTipsFitAndRotate) locks in that every tip fits a single status-line row and the rotation visits every entry, so a tip added to the list actually reaches the user.

    evilcode update stops a running daemon

    • A running daemon holds the old binary in memory, so swapping the file on disk did not change the version it served until a manual restart. evilcode update now requests a graceful daemon shutdown (right after the download verifies, so a failed download never disturbs it) before installing the new binary. No daemon running is a silent no-op; an unreachable one is a warning, not a failure.

    Fix: last_model actually works through the daemon

    • Two bugs made the remembered-model preference useless when running through the daemon (the default evilcode/ec path):
      • The daemon resolved a new session's model but never wrote the result back to last_model, so the file sat at whatever value it booted with. The attach client now persists the resolved session model, mirroring the standalone TUI path.
      • The daemon loads its config once at serve start and never re-reads it, so picker model switches were ignored on the next launch. Session builds now refresh last_model from the config file, so a long-lived daemon honors the model you actually last used.
    • Guarded by TestBuildHonorsTheFilesLastModel and TestBuildKeepsLastModelForInMemoryConfig; in-memory test configs stay hermetic.

    Install or update

    Fresh install:

    curl -fsSL https://evileko.dev/evilcode | sh
    

    Existing installations can update in place:

    evilcode update
    

    Source builds require Go 1.26 or newer. This release publishes the Linux/amd64 binary evilcode-linux-amd64.

    Verification

    • go build ./...
    • go test ./internal/...
    • go vet ./...

    SHA-256 for evilcode-linux-amd64:

    d5384978c0bc8205ff0ec2a70cb6c89be7a53d1f4a62ce5d9708b192936b3090
    
    Downloads
  • v1.1.2 c41ae122a1

    evileko released this 2026-08-25 23:57:07 -04:00 | 178 commits to main since this release

    evilcode v1.1.2 — refresh the model catalog without restarting

    This patch release keeps v1.1.1's behavior intact and fixes one gap in model
    discovery, plus a small source-layout cleanup.

    Highlights

    /refresh-model-list

    • The model picker catalog was fetched live from each provider once, then cached
      for the whole session. Reopening the picker re-displayed the same list with no
      network call, so models released by Ollama Cloud (or any provider) after the
      first open never surfaced without restarting evilcode.
    • The new /refresh-model-list command drops the cache and re-opens the picker,
      re-running discovery (GET /api/tags plus the per-model /api/show enrichment
      on Ollama, the catalog endpoint on other providers) against every configured
      provider. The picker opens immediately with a "loading…" placeholder and
      fills in when the providers answer.
    • /model is unchanged: a warm cache is shown as-is, which is the behavior
      /refresh-model-list exists to override.
    • README now documents the once-per-session cache and the command; the work log
      records the root cause and the discovery boundary (reasoning effort levels
      are not endpoint data — Ollama exposes a thinking capability, and evilcode
      maps it to a fixed vocabulary).

    Source layout

    • The entrypoint moved from the repository root (main.go) to the standard
      cmd/evilcode/ layout (cmd/evilcode/main.go, cmd/evilcode/update.go).
      Affects source builds; the installed binary and evilcode update path are
      unchanged.

    Install or update

    Fresh install:

    curl -fsSL https://evileko.dev/evilcode | sh
    

    Existing installations can update in place:

    evilcode update
    

    Source builds require Go 1.26 or newer. This release publishes the Linux/amd64
    binary evilcode-linux-amd64.

    Verification

    • go test ./...
    • go vet ./...

    SHA-256 for evilcode-linux-amd64:

    8b7719aaaa451034d02e631f090d07ef61f9f628091f7e64e1aafe524f2be497
    
    Downloads
  • v1.1.1 3f4b850336

    evileko released this 2026-08-21 17:30:15 -04:00 | 181 commits to main since this release

    evilcode v1.1.1 — clickable shell commands, smoother start page, safer sessions

    This patch release keeps v1.1.0's persistent daemon/client model and tightens the
    places that matter during everyday terminal work: copying commands, typing into the
    start page, and recovering sessions across daemon restarts.

    Highlights

    Click-to-copy shell commands

    • Click a bash or fish code block to copy its pasteable command to the clipboard.
    • Inline comments are removed only when they are shell comments (quoted hashes and
      escaped hashes stay intact); comment-only lines, trailing whitespace, and trailing
      blank lines are left out of the copied text.
    • Actionable text — including read, write, edit, multiedit, and bash tool
      rows, reasoning traces, and shell commands — gets a jagged underline while hovered.
      The hover state remains visible while the pointer is still, and shell fences only
      underline the exact command prefix that will be copied.
    • Clipboard writes use the native wl-copy, xclip, or xsel helper asynchronously
      with a timeout, so an unavailable clipboard cannot freeze the TUI.

    A calmer, faster start page

    • Typing a new prompt no longer makes the green resume highlight flash back in or
      compete with the composer. Roster polling pauses while the composer has text, and
      the start-page preview is cached without making wrapped input lag.
    • The old greeting is replaced by a centered four-line figlet -f small evilcode
      wordmark in mauve, crossed by a faster, smoother animated white wave.
    • The wordmark, preview, and session row stay aligned across terminal widths, with
      updated probe goldens for the new layout.

    Sessions shut down cleanly

    • A detached session with no open window and no active turn is kept hydrated for ten
      minutes. After that, evilcode writes a clean exit, consolidates memory, unloads the
      live runtime, and leaves the durable transcript ready for a later resume.
    • Daemon shutdown now distinguishes an idle or between-turn session from a session
      that was actively making a turn: only the latter remains crash-detectable on resume.
    • Session teardown and in-flight builds are bounded so a stuck local filesystem cannot
      wedge daemon shutdown.

    Reliability and polish

    • Partial streamed answers survive provider errors and interrupts instead of vanishing
      from the durable conversation.
    • A timeout owned by one tool is no longer mistaken for a user interruption of the
      whole turn.
    • Daemon session builds use isolated configuration snapshots, Codex tool calls with
      missing IDs are handled safely, and deterministic replays no longer risk deleting an
      existing conversation log.
    • The composer now keeps a visible caret, and the TUI avoids rebuilding settled
      transcript/start-page work on every keystroke.

    Documentation

    The README was rewritten to be more direct about what evilcode is, how its daemon and
    sessions work, what is optional, and how to contribute. It also calls out the project's
    AI-assisted origin and its intentionally opinionated, still-evolving shape.

    Install or update

    Fresh install:

    curl -fsSL https://evileko.dev/evilcode | sh
    

    Existing installations can update in place:

    evilcode update
    

    This release publishes the Linux/amd64 binary evilcode-linux-amd64.

    Verification

    • go test ./...
    • go test -race ./...
    • go vet ./...

    SHA-256 for evilcode-linux-amd64:

    065beb30e0299e750d7d6e0772ccb7f9f1e5c4c55885574061a79fa85086ba97
    
    Downloads
  • v1.1.0 5af6964885

    evileko released this 2026-08-20 07:56:48 -04:00 | 196 commits to main since this release

    evilcode v1.1.0 — persistent daemon, detached TUI, in-TUI start page

    This is the first feature release on the 1.x line. The agent loop, tool surface, and session model are unchanged; what changed is how a session is hosted and how you reach it. The daemon now owns long-running sessions and the TUI is a thin client that attaches, detaches, and re-attaches to them.

    What changed

    A persistent daemon, separate from the TUI

    • The daemon owns the session and any running turn; the TUI is a client that attaches to it. Quitting or detaching a client leaves the agent running — you re-attach later and the turn is still going.
    • Remote attach state is synced to late-joining clients, and hidden prompts are tracked across the client/server protocol, so a client that attaches mid-turn sees the same state as one that was there from the start.
    • evilcode serve hosts sessions on a socket; evilcode attach [session] connects a TUI to one; evilcode run --remote "…" submits into a running daemon. The standalone evilcode / evilcode run -local path still works without a daemon.
    • The protocol display version is shared by both frontends from a single buildinfo package.

    In-TUI start page

    • The resume window is replaced by an in-TUI start page. It lists recent and running sessions with a live preview of the selected session's most recent turns, a real message count, and stable ordering; selection follows the session you launch.
    • The empty greeting packs at the top so the composer hugs it and the rows below stay blank — which is where the slash palette floats when it opens.

    Ctrl+C detaches without stopping the agent

    • Two Ctrl+C presses detach this window from the server: the client quits and the session (and any running turn) keeps going on the daemon. A single press only arms the second; Esc or typing clears it. Esc remains the way to stop a runaway agent.

    TUI and operational polish

    • Opening the slash palette never moves the transcript — the overlay splices in below the composer rather than being forced above it and covering the status line (plan.md §5.2 invariant, guarded by TestPaletteReservesNoLayoutHeight).
    • Probe coverage and terminal goldens were refreshed for the v1.1.0 server/client header, the new start page, and the daemon/TUI separation, so visual regressions stay easy to catch.

    Install or update

    Fresh install:

    curl -fsSL https://evileko.dev/evilcode | sh
    

    Existing installations can update in place:

    evilcode update
    

    Source builds require Go 1.26 or newer. This release publishes the Linux/amd64 binary evilcode-linux-amd64.

    Verification

    • go test ./...
    • go test -race ./...
    • go test -tags probe ./probe/...
    • go vet ./...

    SHA-256 for evilcode-linux-amd64:

    04c645dd8d73686353594baef198dd0adf21dfd1c4583f36acc9905c5ca8b476
    
    Downloads
  • v1.0.1 60e1ffa32c

    evileko released this 2026-08-20 05:37:39 -04:00 | 204 commits to main since this release

    evilcode v1.0.1 — hardening and reliability

    This is a focused patch release for the stable 1.0 line. It keeps the core evilcode workflow intact while making persistence, self-updates, and safety boundaries more dependable.

    What changed

    Safer updates and installation

    • Release metadata and binary downloads are bounded, require the canonical HTTPS Forgejo host, and validate redirects before following them.
    • Update downloads are checked before installation, including ELF validation, and are synced, permissioned, and atomically swapped into place so an interrupted update cannot leave a half-written executable.
    • The installer is safer around paths, symlinks, temporary files, and reset/remove operations, with clearer Linux and architecture messages.

    More durable sessions and state

    • Compaction now replays the canonical session state correctly, including safe UTF-8 handling when content must be shortened.
    • Session appends and clean-exit markers are serialized and written atomically, reducing the chance of corrupted or misleading resume state.
    • Configuration, memory, and todo results are defensively copied so callers cannot accidentally mutate persisted state through shared slices or maps.
    • Todo state loading now enforces size, score, dependency, rollback, and cycle-safety checks.

    Safer provider and tool boundaries

    • Provider responses, prompt input, stdin, and background-task waits have explicit limits and cancellation behavior.
    • URL, date, integer, and JSON parsing is stricter at tool boundaries, including rejection of trailing JSON values.
    • Confined and atomic filesystem writes use safer temporary names and preserve clear distinctions between existing and newly created files.
    • Skill discovery, search requests, LSP operations, and image rendering handle invalid or oversized inputs more safely.

    TUI and operational polish

    • Interrupts, model/provider overrides, reasoning preferences, session titles, productivity images, and reconnect-related notices behave more predictably.
    • Probe coverage and terminal goldens were refreshed alongside the fixes, so visual regressions are easier to catch.
    • Completion metadata now tracks the current command surface, including session and daemon-related options.

    Install or update

    Fresh install:

    curl -fsSL https://evileko.dev/evilcode | sh
    

    Existing installations can update in place:

    evilcode update
    

    Source builds require Go 1.26 or newer. This release publishes the Linux/amd64 binary evilcode-linux-amd64.

    Verification

    • go test ./...
    • go test -race ./...
    • go test -tags probe ./probe/...
    • go vet ./...

    SHA-256 for evilcode-linux-amd64:

    c6f69bbda66751754af1857c6b6258f6d711b9c10fd396f9be3873aa1eea5279
    

    See the full v1.0.0…v1.0.1 comparison.

    GPL-3.0. Linux only. Built with the Charm stack.

    Downloads
  • v1.0.0 c1e69a5a65

    evileko released this 2026-08-20 01:13:58 -04:00 | 216 commits to main since this release

    evilcode v1.0.0 — first stable release

    A terminal coding agent. An agentic tool-calling loop, a TUI built on the Charm stack, and first-class support for Ollama Cloud alongside anything that speaks the OpenAI API. Single user, no telemetry, no account — sessions are JSONL files on your own disk.

    This is the first stable release. The binary below is built for linux/amd64.

    Install

    One line — downloads this release's binary and installs it to ~/.local/bin/evilcode plus an ec symlink. No Go toolchain, no clone, no build:

    curl -fsSL https://evileko.dev/evilcode | sh
    

    The script prints each step (retrieve version, download, install) and a few tips. If ~/.local/bin is not on your PATH it warns and prints the export PATH=… line to add to your shell rc.

    If evilcode is already installed, the script asks what to do instead of silently reinstalling:

    1) Check for updates   — runs 'evilcode update'
    2) Reinstall latest    — fresh download + atomic install
    3) Remove evilcode     — deletes the binary + ec symlink (optional config/data removal)
    4) Reset config        — backs up ~/.config/evilcode and removes it so defaults apply
    5) Exit
    

    Self-update at any time:

    evilcode update
    

    update fetches the latest release binary (evilcode-<os>-<arch>) and atomically swaps it over the running executable. It never touches the installed binary before the download completes.

    Build from source

    Requires Go 1.26 or newer.

    git clone https://git.evileko.dev/evileko/evilcode
    cd evilcode
    go build -o evilcode ./
    ln -sf "$PWD/evilcode" ~/.local/bin/evilcode
    ln -sf "$PWD/evilcode" ~/.local/bin/ec
    

    Requirements

    Linux only. At runtime: rg for the grep tool, tmux for the probe rig. Optional extras used if present — gopls for the lsp tool, mmdc for mermaid diagrams, img2sixel for images on terminals without the kitty graphics protocol.

    Usage

    evilcode                      # interactive TUI
    evilcode run "fix the parser" # headless, one shot
    evilcode serve                # daemon hosting sessions
    evilcode attach [session]     # attach a TUI to the daemon
    evilcode run --remote "..."   # submit into a running daemon
    evilcode resume --from claude <id-or-path> # import and continue a foreign session
    

    evilcode run writes the model's text to stdout and everything else to stderr, so it composes with other tools. It exits 130 on interrupt.

    Highlights

    • Agent-friendly filesystem tools. read attaches supported images to vision models, truncates oversized individual lines while preserving paging, and suggests nearby names for a missing path. multiedit applies ordered edits with one atomic write; common argument spellings such as file_path are silently repaired and shown in the tool row.
    • Sessions are the source of truth. Every message is written as it lands; /compact and /rewind rewrite the log atomically — a backup is written and synced before the primary is replaced, and the live session follows the rewrite. Compaction summarizes older turns but keeps the ten most recent turns verbatim, so a task in progress survives both the live rewrite and resume.
    • Predictive compaction. Watches recent context growth and recent assistant-turn embeddings: a detected topic shift can compact at a natural boundary, while growth still projects ahead of the fixed 85% limit. Embedding is best-effort and asynchronous, so an unavailable or slow provider leaves the predictive path in charge rather than delaying a turn.
    • Destructive-command gate. A runtime command-risk evaluator holds or refuses destructive shell commands (git push --force, git clean -fd, …) rather than relying on prompt-level advice; a held command can be released with a substantive justification.
    • Foreign session import. evilcode resume --from claude|codex|opencode <id-or-path> converts a foreign transcript into a native JSONL session and enters the ordinary resume path.
    • Swarm coordination. spawn_worker starts a headless worker on a self-contained task with a result_schema its answer is validated against; send_message / broadcast / peers coordinate agents that share a working directory, with conflict notices for files mid-edit.
    • Scoped memory and skills. Long-term memory with remember / recall / reflect, and on-demand skills loaded through the skill tool so the system prompt stays cacheable as the skill set grows.
    • Read-only advisor. A second, small model watches the turn and raises at most one concrete concern per turn — silence is the easy answer, so it only speaks when the main agent is about to miss a real problem.

    Self-update

    evilcode update resolves the latest release from https://git.evileko.dev/api/v1/repos/evileko/evilcode/releases/latest, downloads the binary built for this OS/arch, and swaps it in over the running executable. A public repo answers without credentials; a private mirror or gated download falls back to a Basic header drawn from git credential fill.


    GPL-3.0. Linux only. Built with the Charm stack.

    Downloads