-
v1.4.0 — live tool tokens, a real terminal pane, and one-command tailnet access
StableSome checks failedci / gate (push) Has been cancelledreleased this
2026-09-20 04:52:36 -04:00 | 0 commits to main since this releaseevilcode 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+Lsplit 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+Lsplit- 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, andmultieditpreviews 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
.mdwrites 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
/tailscaleinside evilcode to start the web companion on loopback, configuretailscale 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 | shExisting installations can update in place:
evilcode updateSource builds require Go 1.26 or newer. This release publishes the Linux/amd64 binary
evilcode-linux-amd64.Verification
go build ./...go vet ./...go mod verifygo test ./... -count=1go test -race ./internal/agent ./internal/provider ./internal/tools ./internal/daemon ./internal/tuigo test -tags probe ./probe -count=1
SHA-256 for
evilcode-linux-amd64:1e569761f72689e6aace283d0faa3f7f37055195a68916c457c529aec076eb4bDownloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
-
v1.3.0 — the web companion, a ported compaction engine, and a steadier transcript
StableSome checks failedci / gate (push) Has been cancelledreleased this
2026-09-17 00:10:23 -04:00 | 24 commits to main since this releaseevilcode 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-addrflags 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-Noff 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_changedrefresh 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 = truerestores the old behavior; the/poketoggle 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 | shExisting installations can update in place:
evilcode updateSource 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:1cd9ae5049b5a75f5b8ed3e4aeba77203e41f7b02c4f11d6424b6486cd91a9abDownloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- A second frontend in the daemon. The
-
v1.2.0 — the Live panel Stable
released this
2026-08-26 19:15:37 -04:00 | 135 commits to main since this releaseevilcode 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
livetag 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
qis 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/showcapability 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 | shExisting installations can update in place:
evilcode updateSource 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:485dbf746bbc435d6220e45053cbc9b2692388e25c61b2d49e3919de184b748fDownloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- 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
-
released this
2026-08-26 04:15:38 -04:00 | 157 commits to main since this releaseevilcode 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%or96%. The percent is now computed from item statuses:●●○○ 1/4 done · 25%, and an all-closed group reads100%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.
The cloud-usage widget with a valid cookie
- A bare
__Secure-sessiontoken is base64 and often ends in=padding; it
was mistaken for a fullCookie: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
commanddid 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, andResult.Diffis
capped at 1 MiB separately from model-visible output.
Install or update
Fresh install:
curl -fsSL https://evileko.dev/evilcode | shExisting installations can update in place:
evilcode updateSource builds require Go 1.26 or newer. This release publishes the Linux/amd64
binaryevilcode-linux-amd64.Verification
go test ./...go vet ./...- Probe suite (
go test -tags probe ./probe/...) green, goldens refreshed
SHA-256 for
evilcode-linux-amd64:01396e81572c8f2f8ed23c6ed05f54307fabde6b48060c93ec8d05de5a7c88f8Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- The docked Todos widget and the todo card's group headers previously
-
released this
2026-08-26 00:59:25 -04:00 | 174 commits to main since this releaseevilcode 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 whenOLLAMA_API_KEYis set, and through the local Ollama daemon (deepseek-v4-flash:0731@ollama-local) when it is not. The previous default wasglm-5.2:cloud. deepseek-v4-flash:0731is a thinking model, so the default routes pin reasoning effort tohighfor 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_modelset. An existingconfig.tomlthat states its owndefault_modelis 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 meaninglessCtrl+O · Ctrl+Non narrow terminals. Now:- The key-summary hint keeps the verb at every width, down to
Ctrl+O set defaulton the narrowest. - A contextual
Ctrl+O set as defaulthint 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.
- The key-summary hint keeps the verb at every width, down to
- No new key binding was added, so filtering the picker by typing (including
dto reachdeepseekmodels) is unchanged.
The idle tip rotation covers the niche features
- The idle
Tipsrotation is the only passive discovery surface — a user who never opens/helpand 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
/helpwould otherwise reveal:/btw(a side question that costs no main context),/rewind(collapse back to a checkpoint).
- Niche keybindings that had no other passive surface:
- 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 updatestops 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 updatenow 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_modelactually works through the daemon- Two bugs made the remembered-model preference useless when running through the daemon (the default
evilcode/ecpath):- 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
servestart and never re-reads it, so picker model switches were ignored on the next launch. Session builds now refreshlast_modelfrom the config file, so a long-lived daemon honors the model you actually last used.
- The daemon resolved a new session's model but never wrote the result back to
- Guarded by
TestBuildHonorsTheFilesLastModelandTestBuildKeepsLastModelForInMemoryConfig; in-memory test configs stay hermetic.
Install or update
Fresh install:
curl -fsSL https://evileko.dev/evilcode | shExisting installations can update in place:
evilcode updateSource 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:d5384978c0bc8205ff0ec2a70cb6c89be7a53d1f4a62ce5d9708b192936b3090Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- The default model is now
-
released this
2026-08-25 23:57:07 -04:00 | 178 commits to main since this releaseevilcode 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-listcommand drops the cache and re-opens the picker,
re-running discovery (GET /api/tagsplus the per-model/api/showenrichment
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. /modelis unchanged: a warm cache is shown as-is, which is the behavior
/refresh-model-listexists 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 athinkingcapability, 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 andevilcode updatepath are
unchanged.
Install or update
Fresh install:
curl -fsSL https://evileko.dev/evilcode | shExisting installations can update in place:
evilcode updateSource builds require Go 1.26 or newer. This release publishes the Linux/amd64
binaryevilcode-linux-amd64.Verification
go test ./...go vet ./...
SHA-256 for
evilcode-linux-amd64:8b7719aaaa451034d02e631f090d07ef61f9f628091f7e64e1aafe524f2be497Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- The model picker catalog was fetched live from each provider once, then cached
-
released this
2026-08-21 17:30:15 -04:00 | 181 commits to main since this releaseevilcode 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
bashorfishcode 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, andbashtool
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, orxselhelper 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 | shExisting installations can update in place:
evilcode updateThis release publishes the Linux/amd64 binary
evilcode-linux-amd64.Verification
go test ./...go test -race ./...go vet ./...
SHA-256 for
evilcode-linux-amd64:065beb30e0299e750d7d6e0772ccb7f9f1e5c4c55885574061a79fa85086ba97Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- Click a
-
released this
2026-08-20 07:56:48 -04:00 | 196 commits to main since this releaseevilcode 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 servehosts sessions on a socket;evilcode attach [session]connects a TUI to one;evilcode run --remote "…"submits into a running daemon. The standaloneevilcode/evilcode run -localpath still works without a daemon.- The protocol display version is shared by both frontends from a single
buildinfopackage.
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 | shExisting installations can update in place:
evilcode updateSource 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:04c645dd8d73686353594baef198dd0adf21dfd1c4583f36acc9905c5ca8b476Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
-
released this
2026-08-20 05:37:39 -04:00 | 204 commits to main since this releaseevilcode 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 | shExisting installations can update in place:
evilcode updateSource 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:c6f69bbda66751754af1857c6b6258f6d711b9c10fd396f9be3873aa1eea5279See the full v1.0.0…v1.0.1 comparison.
GPL-3.0. Linux only. Built with the Charm stack.
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
-
released this
2026-08-20 01:13:58 -04:00 | 216 commits to main since this releaseevilcode 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/evilcodeplus anecsymlink. No Go toolchain, no clone, no build:curl -fsSL https://evileko.dev/evilcode | shThe script prints each step (retrieve version, download, install) and a few tips. If
~/.local/binis not on yourPATHit warns and prints theexport 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) ExitSelf-update at any time:
evilcode updateupdatefetches 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/ecRequirements
Linux only. At runtime:
rgfor thegreptool,tmuxfor the probe rig. Optional extras used if present —goplsfor thelsptool,mmdcfor mermaid diagrams,img2sixelfor 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 sessionevilcode runwrites 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.
readattaches supported images to vision models, truncates oversized individual lines while preserving paging, and suggests nearby names for a missing path.multieditapplies ordered edits with one atomic write; common argument spellings such asfile_pathare silently repaired and shown in the tool row. - Sessions are the source of truth. Every message is written as it lands;
/compactand/rewindrewrite 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_workerstarts a headless worker on a self-contained task with aresult_schemaits answer is validated against;send_message/broadcast/peerscoordinate 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 theskilltool 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 updateresolves the latest release fromhttps://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 fromgit credential fill.
GPL-3.0. Linux only. Built with the Charm stack.
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- Agent-friendly filesystem tools.