<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>mindfork</title>
    <subtitle>A terminal AI chat written in Rust: local models via llama.cpp or OpenAI, Anthropic, Gemini and Grok in the cloud — with persistent memory, notes, RAG and tools. Windows and Linux.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://mindfork.io/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://mindfork.io"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-09-21T00:00:00+00:00</updated>
    <id>https://mindfork.io/atom.xml</id>
    <entry xml:lang="en">
        <title>mindfork 0.11.0 — from a bare Linux machine to a local model, in one line</title>
        <published>2026-09-21T00:00:00+00:00</published>
        <updated>2026-09-21T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://mindfork.io/blog/mindfork-0-11-0/"/>
        <id>https://mindfork.io/blog/mindfork-0-11-0/</id>
        
        <content type="html" xml:base="https://mindfork.io/blog/mindfork-0-11-0/">&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/vshylov/mindfork-rs/releases&quot;&gt;mindfork 0.11.0&lt;/a&gt; is out. It has
one subject: &lt;strong&gt;the distance between &quot;the app is unpacked&quot; and &quot;a local model
answers&quot;&lt;/strong&gt;, and what that distance costs on a machine you rent by the hour.&lt;/p&gt;
&lt;p&gt;On a desktop you cross it once: download llama.cpp, install the Python sandbox,
open the settings and type four paths and a number — the model, its vision
projector, the embedding model, the context. On a rented GPU box you cross it
&lt;em&gt;every time&lt;/em&gt;. On RunPod the container&#39;s own disk is cleared whenever the pod
stops, not only when it is terminated; what survives is one directory. So the
set-up is done per rental, in a browser terminal, while the meter runs.&lt;/p&gt;
&lt;h2 id=&quot;one-command&quot;&gt;One command&lt;/h2&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;mindfork&lt;/span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; setup --sandbox --llama cuda-12&lt;/span&gt;&lt;span style=&quot;color: #F5C2E7;&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;  --model /models/gemma-4-31b-it-q4_0.gguf&lt;/span&gt;&lt;span style=&quot;color: #F5C2E7;&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;  --mmproj /models/mmproj-gemma-4-31b-it-f16.gguf&lt;/span&gt;&lt;span style=&quot;color: #F5C2E7;&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;  --embed-model /models/bge-m3-Q8_0.gguf&lt;/span&gt;&lt;span style=&quot;color: #F5C2E7;&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;  --ctx&lt;/span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 32768&lt;/span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; --verify&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Every option is one step, and a step you do not name is not run — &lt;code&gt;mindfork setup --ctx 65536&lt;/code&gt; alone is a perfectly good use. What matters more than the list is how
it behaves:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Paths and keys are checked before anything is downloaded.&lt;/strong&gt; A model path that
names no file, a part of a multi-file GGUF that is not the first, a setting that
does not exist — each is an error &lt;em&gt;now&lt;/em&gt;, in the words the app would have used at
launch, not a status line ten minutes and a gigabyte later.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A step that fails does not stop the others.&lt;/strong&gt; If the sandbox download fails,
llama.cpp is still installed and the settings are still written; the command
ends with what failed and a non-zero exit code. Run the same line again and it
repeats only what is missing.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;It writes the settings&lt;/strong&gt; — once, at the end, and only if something changed.
That is the difference from the &lt;code&gt;MINDFORK_*&lt;/code&gt; environment variables, which
&lt;em&gt;override&lt;/em&gt; on every launch: what &lt;code&gt;setup&lt;/code&gt; sets is what the settings screen shows,
and what you change there afterwards sticks.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;--set&lt;/code&gt; reaches everything else&lt;/strong&gt;, by the field&#39;s path in &lt;code&gt;settings.json&lt;/code&gt;:
&lt;code&gt;--set engine.managed.sessions=4 --set engine.managed.no_mmap=true&lt;/code&gt;. A key that
does not exist is refused rather than silently dropped. API keys cannot be set
this way — a key on a command line ends up in the shell&#39;s history; name the
&lt;em&gt;variable&lt;/em&gt; that holds it instead.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And then &lt;strong&gt;&lt;code&gt;--verify&lt;/code&gt;&lt;/strong&gt; starts exactly what the app will start — the chat server
and the embedding server, &lt;em&gt;both at once&lt;/em&gt;, since whether the two fit the card
together is one of the questions — waits for each to load, and says what it found:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;== Starting what was configured&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  chat server: starting on port 8000…&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  embedding server: starting on port 8001…&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  chat server: ready in 41 s — context 32768, takes images, 4 slots&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  embedding server: ready in 6 s&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A context too large for the card, a projector that belongs to another model, a
port something else already listens on — each shows up here as &lt;code&gt;FAILED&lt;/code&gt; with the
reason, while the command line can still be edited.&lt;/p&gt;
&lt;h2 id=&quot;and-the-line-before-it&quot;&gt;And the line before it&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;mindfork setup&lt;/code&gt; cannot put mindfork on a machine that does not have it. An
install script does, and then hands over:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;curl&lt;/span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; -fsSL https://github.com/vshylov/mindfork-rs/releases/latest/download/install.sh&lt;/span&gt;&lt;span style=&quot;color: #F5C2E7;&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;  |&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; sh&lt;/span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; -s -- --dir /workspace/mindfork -- setup --sandbox --llama cuda-12&lt;/span&gt;&lt;span style=&quot;color: #F5C2E7;&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;      --model /workspace/models/chat.gguf --ctx&lt;/span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 32768&lt;/span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; --verify&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It unpacks the portable build into one directory, &lt;strong&gt;refuses the archive unless it
matches the release&#39;s checksums&lt;/strong&gt;, and then &lt;em&gt;runs the binary&lt;/em&gt; to see whether it
starts. On a bare image it does not — the app needs one system library that
minimal images do not carry — so the script installs that package with the
system&#39;s package manager, or stops and prints the exact command. Everything after
&lt;code&gt;--&lt;/code&gt; goes to &lt;code&gt;mindfork&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Run it again and it downloads nothing that is already there. On a pod that was
stopped and started, the same line takes seconds: what sits on the volume is
recognised, and only what the container lost is put back. Your data is never
touched.&lt;/p&gt;
&lt;p&gt;The script is an asset of the release, like the archive — listed in
&lt;code&gt;sha256sums.txt&lt;/code&gt;, covered by the same build attestation — so piping it adds no
party to trust that the binary had not already added. If you would rather read
before you run: download it, read it, &lt;code&gt;sh install.sh&lt;/code&gt;. It is one short POSIX
script. On a desktop the short form is all there is to it:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;curl&lt;/span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; -fsSL https://github.com/vshylov/mindfork-rs/releases/latest/download/install.sh&lt;/span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https://github.com/vshylov/mindfork-rs/blob/main/docs/install.md&quot;&gt;install guide&lt;/a&gt;
has the recipe for a rented box in full: which image to pick, why tmux is not
decoration there, what to do about API keys in a container, and what to take with
you before you terminate the pod.&lt;/p&gt;
&lt;h2 id=&quot;cuda-on-linux&quot;&gt;CUDA on Linux&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;mindfork llama setup&lt;/code&gt; downloads llama.cpp for your machine. Until the middle of
September llama.cpp published no CUDA build for Linux; now it does — and mindfork
&lt;strong&gt;refused to install it&lt;/strong&gt;. The build&#39;s CUDA runtime is a separate archive, and on
Linux it is named differently than on Windows; the command looked for the Windows
name, found nothing, listed the backend as &quot;no CUDA runtime published&quot; and
stopped. It looks for what the release actually publishes now.&lt;/p&gt;
&lt;p&gt;The same check turned up two more things. Recent llama.cpp builds print a log
line &lt;em&gt;ahead of&lt;/em&gt; their version, so the command showed that line as the version —
and the check that the binary you got is the build you asked for, finding no
number to compare, &lt;strong&gt;skipped itself without saying so&lt;/strong&gt;. The version is found by
what it says now, and a binary that names no build number is reported as such.
And with no &lt;code&gt;--build&lt;/code&gt;, the command takes the newest build that actually has the
backend you named, complete — a nightly is now and then published empty or
half-uploaded.&lt;/p&gt;
&lt;p&gt;One small addition rides along: &lt;strong&gt;a backend family&lt;/strong&gt;. llama.cpp renames its CUDA
builds whenever it moves to the next toolkit — &lt;code&gt;cuda-13.3&lt;/code&gt; became &lt;code&gt;cuda-13.4&lt;/code&gt;
inside two weeks — so a command you had saved stopped working. &lt;code&gt;--backend cuda-12&lt;/code&gt; installs the one &lt;code&gt;cuda-12.*&lt;/code&gt; build on offer.&lt;/p&gt;
&lt;p&gt;Nothing about the stored data changes in this release: no migration runs, and
0.10.2 and 0.11.0 open the same files.&lt;/p&gt;
&lt;p&gt;The full list is in the
&lt;a rel=&quot;external&quot; href=&quot;https://github.com/vshylov/mindfork-rs/blob/main/CHANGELOG.md&quot;&gt;changelog&lt;/a&gt;.
Downloads — Windows installer and archive, Linux archive, &lt;code&gt;.deb&lt;/code&gt;, &lt;code&gt;.rpm&lt;/code&gt; and
&lt;code&gt;.pkg.tar.zst&lt;/code&gt;, and now &lt;code&gt;install.sh&lt;/code&gt; — are on the
&lt;a rel=&quot;external&quot; href=&quot;https://github.com/vshylov/mindfork-rs/releases&quot;&gt;releases page&lt;/a&gt;, and
&lt;code&gt;cargo install mindfork&lt;/code&gt; builds the same version from
&lt;a rel=&quot;external&quot; href=&quot;https://crates.io/crates/mindfork&quot;&gt;crates.io&lt;/a&gt;.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>mindfork 0.10.2 — which copy of your data is the newest</title>
        <published>2026-09-20T00:00:00+00:00</published>
        <updated>2026-09-20T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://mindfork.io/blog/mindfork-0-10-2/"/>
        <id>https://mindfork.io/blog/mindfork-0-10-2/</id>
        
        <content type="html" xml:base="https://mindfork.io/blog/mindfork-0-10-2/">&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/vshylov/mindfork-rs/releases&quot;&gt;mindfork 0.10.2&lt;/a&gt; is out. It is
a small release with one subject: &lt;strong&gt;data that lives on more than one computer&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;mindfork keeps everything in a folder next to itself, with no account and no
sync. That is a promise, and it has a price: the day there is a desktop, a laptop
and a backup archive, &quot;which of these do I keep?&quot; is a question only you can
answer — and until now the way to answer it was to open each copy and look.&lt;/p&gt;
&lt;h2 id=&quot;which-copy-is-the-newest&quot;&gt;Which copy is the newest&lt;/h2&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mindfork stats                  # the data on this computer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mindfork stats copy.zip         # a backup archive, without restoring it&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It prints when the last message was written and when anything last changed, how
many profiles, chats and messages there are — and how many of them are deleted —
and the attached and stored files, images, projects, notes and the knowledge
base. Messages are counted the way the chat list counts them, and times are in
UTC, so the output of two computers can be read side by side, line by line.&lt;/p&gt;
&lt;p&gt;The command &lt;strong&gt;only reads&lt;/strong&gt;. Nothing is created, migrated or unpacked, so it is
safe to run while the app is open, and an archive stays a closed archive: an
encrypted one is read in memory and never written out decrypted. The password is
found the way &lt;code&gt;restore&lt;/code&gt; finds it — &lt;code&gt;--password&lt;/code&gt;, else the one saved in the
settings, else you are asked.&lt;/p&gt;
&lt;p&gt;The summary ends its first block with a &lt;strong&gt;fingerprint&lt;/strong&gt;. Two computers that print
the same one hold identical chats, notes, knowledge base and self-models, and
there is nothing more to check.&lt;/p&gt;
&lt;h2 id=&quot;what-each-copy-holds-that-the-other-lacks&quot;&gt;What each copy holds that the other lacks&lt;/h2&gt;
&lt;p&gt;The newest copy is not always the most complete one. A chat continued on the
laptop after the desktop&#39;s backup was taken exists only on the laptop — and the
desktop may still be the copy written last.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mindfork stats --json &amp;gt; laptop.json     # on the other computer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mindfork stats --compare laptop.json    # here&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The snapshot is a small file — ids, titles and checksums, &lt;strong&gt;no message text&lt;/strong&gt; —
so it can travel by whatever is at hand. &lt;code&gt;--compare&lt;/code&gt; takes a backup archive of
the other copy just as well. It prints a verdict first: the copies are identical;
this copy holds everything the other has, or the reverse; or &lt;em&gt;each copy holds
something the other lacks&lt;/em&gt;. Then the lists behind the verdict — chats only here,
only there, continued here or there, and &lt;strong&gt;diverged&lt;/strong&gt;: one chat continued on both
computers, each side holding messages the other does not.&lt;/p&gt;
&lt;p&gt;Chats are compared &lt;strong&gt;by the ids of their messages&lt;/strong&gt;, not by counts or dates. That
is the whole point: a chat continued on two machines has more messages on each
side than the other knows about, and a comparison by dates would report it as
merely &quot;newer there&quot; — and keeping that side would lose the other&#39;s half in
silence.&lt;/p&gt;
&lt;p&gt;mindfork does not merge copies. When each side holds something, keep both until
you have decided what to do with what is listed. The
&lt;a rel=&quot;external&quot; href=&quot;https://github.com/vshylov/mindfork-rs/blob/main/docs/install.md&quot;&gt;install guide&lt;/a&gt;
has the full description, next to &lt;code&gt;backup&lt;/code&gt; and &lt;code&gt;restore&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;one-frame-not-two&quot;&gt;One frame, not two&lt;/h2&gt;
&lt;p&gt;Picking a chat in the chat list used to show the conversation you were &lt;em&gt;leaving&lt;/em&gt;
for a fraction of a second before the one you asked for. The list now stays on
screen until the chat is ready, so the switch is a single step — and the same
goes for a new chat, a clone, a search hit and a run opened from the tasks
screen. A clone that is refused now says so in the list, instead of in the chat
behind it.&lt;/p&gt;
&lt;h2 id=&quot;also-in-this-release&quot;&gt;Also in this release&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;restore&lt;/code&gt; asks for the password on stderr&lt;/strong&gt;, so redirecting a command&#39;s
output no longer hides the question. And when the password that fails is the
one saved in the settings, the message says that and points at &lt;code&gt;--password&lt;/code&gt;,
instead of &quot;wrong backup password&quot; for a password you never typed.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nothing about the stored data changes in this release: no migration runs, and
0.10.1 and 0.10.2 open the same files.&lt;/p&gt;
&lt;p&gt;The full list is in the
&lt;a rel=&quot;external&quot; href=&quot;https://github.com/vshylov/mindfork-rs/blob/main/CHANGELOG.md&quot;&gt;changelog&lt;/a&gt;.
Downloads — Windows installer and archive, Linux archive, &lt;code&gt;.deb&lt;/code&gt;, &lt;code&gt;.rpm&lt;/code&gt; and
&lt;code&gt;.pkg.tar.zst&lt;/code&gt; — are on the
&lt;a rel=&quot;external&quot; href=&quot;https://github.com/vshylov/mindfork-rs/releases&quot;&gt;releases page&lt;/a&gt;, and
&lt;code&gt;cargo install mindfork&lt;/code&gt; builds the same version from
&lt;a rel=&quot;external&quot; href=&quot;https://crates.io/crates/mindfork&quot;&gt;crates.io&lt;/a&gt;.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>mindfork is public</title>
        <published>2026-09-19T00:00:00+00:00</published>
        <updated>2026-09-19T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://mindfork.io/blog/mindfork-is-public/"/>
        <id>https://mindfork.io/blog/mindfork-is-public/</id>
        
        <content type="html" xml:base="https://mindfork.io/blog/mindfork-is-public/">&lt;p&gt;The repository is open, and the first public release is on the
&lt;a rel=&quot;external&quot; href=&quot;https://github.com/vshylov/mindfork-rs/releases&quot;&gt;releases page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;mindfork is an AI chat that lives in your terminal. It runs local models through
llama.cpp, or talks to OpenAI, Anthropic, Gemini and Grok — all four configured
at once if you like, switching between them without losing anything. It is one
native binary for Windows and Linux, it keeps its data in a folder next to
itself, and it has no telemetry, no update check and no account.&lt;/p&gt;
&lt;h2 id=&quot;what-it-is-actually-for&quot;&gt;What it is actually for&lt;/h2&gt;
&lt;p&gt;Most clients are a window onto a model. This one is built on a different
premise: that a local Gemma or Qwen becomes &lt;strong&gt;more interesting to talk to&lt;/strong&gt; when
it is given room to remember and to act.&lt;/p&gt;
&lt;p&gt;So it keeps a &lt;strong&gt;self-model&lt;/strong&gt; — a summary, goals, traits and an observation
narrative that the assistant maintains about itself and about you, and that you
can read and wipe on one screen. It writes &lt;strong&gt;notes&lt;/strong&gt; and links them into a graph
where one note can supersede another. It builds a &lt;strong&gt;knowledge base&lt;/strong&gt; out of your
own files, retrieved semantically rather than by keyword. All of it per companion
profile, all of it on your disk.&lt;/p&gt;
&lt;p&gt;And it has &lt;strong&gt;tools&lt;/strong&gt;: web search and page fetching, a Python sandbox with no
access to your files, a file-access tool jailed to one directory you name, an
attached code project it can read and change under a diff you approve, video
understanding, and anything else you plug in over MCP. Every one of those is off
until you turn it on, and an optional confirmation shows exactly what a call is
about to do before it does it.&lt;/p&gt;
&lt;h2 id=&quot;what-a-first-run-looks-like&quot;&gt;What a first run looks like&lt;/h2&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mindfork demo&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sample conversations, a scripted engine, nothing written outside a temporary
folder. It takes a minute and answers the only question that matters early:
whether you want this shape of thing at all.&lt;/p&gt;
&lt;p&gt;After that, &lt;a href=&quot;/install/&quot;&gt;the install page&lt;/a&gt; has the downloads and
&lt;a rel=&quot;external&quot; href=&quot;https://github.com/vshylov/mindfork-rs/blob/main/docs/manual.md&quot;&gt;the manual&lt;/a&gt;
has the rest.&lt;/p&gt;
&lt;h2 id=&quot;how-it-was-built-and-why-the-repository-is-worth-a-look&quot;&gt;How it was built, and why the repository is worth a look&lt;/h2&gt;
&lt;p&gt;Two years of small reviewed tracks, each one a design document with its
alternatives written down, a branch, tests beside the code, and — for anything
touching a model — a run against a real one before it shipped. The suite is over
three thousand tests, and the engineering log says what was measured and what was
rejected, not just what was done.&lt;/p&gt;
&lt;p&gt;Much of the code was written by AI models under review, and the history says so:
every commit names the model that wrote it. That is not a disclaimer, it is the
same honesty the rest of the project tries for — the
&lt;a rel=&quot;external&quot; href=&quot;https://github.com/vshylov/mindfork-rs/tree/main/docs/journal&quot;&gt;journal&lt;/a&gt; is full
of measurements that overturned the plan they were meant to confirm.&lt;/p&gt;
&lt;p&gt;The code is &lt;a href=&quot;/license/&quot;&gt;MIT&lt;/a&gt;. The
&lt;a href=&quot;/disclaimer/&quot;&gt;disclaimer&lt;/a&gt; says what shipping no model means for what appears on
your screen, and the &lt;a href=&quot;/privacy/&quot;&gt;privacy policy&lt;/a&gt; says what leaves your machine —
which is nothing you did not configure.&lt;/p&gt;
&lt;p&gt;If you try it, &lt;a rel=&quot;external&quot; href=&quot;https://github.com/vshylov/mindfork-rs/issues&quot;&gt;issues&lt;/a&gt; are the
place to say what broke.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>mindfork 0.9.9 — files in, charts out, work in the background</title>
        <published>2026-09-13T00:00:00+00:00</published>
        <updated>2026-09-13T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://mindfork.io/blog/mindfork-0-9-9/"/>
        <id>https://mindfork.io/blog/mindfork-0-9-9/</id>
        
        <content type="html" xml:base="https://mindfork.io/blog/mindfork-0-9-9/">&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/vshylov/mindfork-rs/releases&quot;&gt;mindfork 0.9.9&lt;/a&gt; is out. It is
a release about &lt;em&gt;keeping the conversation moving&lt;/em&gt;: the assistant&#39;s code gets
your files and hands its own back with no copy-paste in between, a delegation
no longer holds the chat while it runs, and the engine is one command away
instead of a build away.&lt;/p&gt;
&lt;h2 id=&quot;your-files-reach-the-code-and-its-files-reach-you&quot;&gt;Your files reach the code, and its files reach you&lt;/h2&gt;
&lt;p&gt;Until now the sandboxed Python could compute, but only on what the assistant
typed into the script. Now a call &lt;strong&gt;names the chat&#39;s files it needs&lt;/strong&gt; — by the
number &lt;code&gt;/file list&lt;/code&gt; shows or by name — and each is copied into the sandbox
before the code runs: an attachment as its text, a stored file or a picture as
itself. The copies are the sandbox&#39;s own, so nothing here changes under the
code&#39;s hands, and only what it saves into &lt;code&gt;/w/out&lt;/code&gt; comes back. That folder is
the other half: a matplotlib chart, a CSV or a workbook saved there is kept
with the chat, listed by &lt;code&gt;/file list&lt;/code&gt;, packed by backups — up to ten files and
50 MB a call — and a PNG or JPEG is &lt;strong&gt;shown to the model&lt;/strong&gt;, so it can check the
chart it drew. Measured before shipping on Qwen 3.6 27B and Gemma 4 31B: a
plot colour only the image carries was named nearly every time with the
picture and never without — and blind, both models described a chart they had
not seen, which is why every image the assistant is &lt;em&gt;not&lt;/em&gt; shown is now said in
the result, in words a small model does not talk past.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/file attach&lt;/code&gt; stops refusing a binary: a workbook or a zip is kept with the
chat, readable by code alone, and a PDF, DOCX or web page keeps its original
beside the text the assistant reads — one entry in the list, removed together,
never your own file. &lt;code&gt;/file open &amp;lt;name|#N&amp;gt;&lt;/code&gt; hands a file to whatever your
system opens it with, and &lt;code&gt;/file folder&lt;/code&gt; opens the chat&#39;s folder. Only
document types open directly; a script, a shortcut or an HTML page the
assistant wrote opens &lt;em&gt;the folder it sits in&lt;/em&gt; instead, so nothing the
assistant produced can run by being opened — and on Windows a workbook or
document the code wrote carries the same mark as a download, so Office opens
it in Protected View.&lt;/p&gt;
&lt;p&gt;The same contract holds when Python runs on your own machine instead of in the
sandbox: the files named in the call are copied in, what the code saves comes
back, and a new per-process memory limit (Windows, off by default) turns a
runaway allocation into a &lt;code&gt;MemoryError&lt;/code&gt; instead of taking the machine&#39;s
memory. The sandbox itself gained sympy, networkx, lxml, pyyaml, regex,
feedparser, openpyxl, pypdf, tabulate, pillow and matplotlib —
&lt;code&gt;mindfork sandbox setup&lt;/code&gt; fetches only what is missing — and its packages are
now packed into an image the code cannot alter, so one call can no longer
leave a file that runs inside every later one. An existing sandbox needs that
command run once more; the tool names it when it refuses.&lt;/p&gt;
&lt;h2 id=&quot;work-that-goes-on-without-you&quot;&gt;Work that goes on without you&lt;/h2&gt;
&lt;p&gt;A delegation used to hold the conversation until it landed. Switch on
&lt;strong&gt;Background runs&lt;/strong&gt; in Settings → Tools and the assistant gains
&lt;code&gt;start_subagent&lt;/code&gt;: a delegation that returns at once — the assistant keeps
answering you, past the end of its own reply — and whose result arrives later
as a &lt;strong&gt;task notification&lt;/strong&gt; in the chat. When the chat is open and idle the
assistant reads it and reports by itself; otherwise the note waits for your
next message. The run is a row of the chat list while it is out, its transcript
opens as it streams, and a result that lands while you are looking elsewhere
marks its chat unread. A staged dialogue (below) can run the same way. A
background run never asks you to confirm a tool call — switch off the tools you
would not let run unattended.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;F7&lt;/code&gt;&lt;/strong&gt; (or &lt;code&gt;/tasks&lt;/code&gt;) is the screen for all of it: every subagent and dialogue
run across all your chats — the ones running, with the round and tool they are
in; the ones that landed, with how they ended — and the app&#39;s own quiet work
(reflection, consolidation, history compaction) as running, waiting or idle.
&lt;code&gt;Enter&lt;/code&gt; opens a run&#39;s transcript, &lt;code&gt;F6&lt;/code&gt; stops one — the app&#39;s own tasks
included — and &lt;code&gt;/tasks stop &amp;lt;kind&amp;gt;&lt;/code&gt; does the same from a terminal where &lt;code&gt;F6&lt;/code&gt;
never arrives. A reflection stopped before it wrote anything gives its window
back, so nothing is skipped and nothing is written twice.&lt;/p&gt;
&lt;p&gt;Things can also happen &lt;strong&gt;at once&lt;/strong&gt;. &lt;em&gt;Subagent: parallel runs&lt;/em&gt; lets the
delegations of one reply run together; &lt;em&gt;Parallel tool calls&lt;/em&gt; lets the reads
and page fetches of one reply run together — only tools that change nothing,
four at a time on a cloud engine by default, one after another on a local
engine until you raise it; and a new &lt;strong&gt;Parallel sessions&lt;/strong&gt; setting on every
engine mode says how many request streams the app may keep open. A managed
&lt;code&gt;llama-server&lt;/code&gt; is then launched with &lt;code&gt;-np N --kv-unified&lt;/code&gt;, its slots sharing
the one context pool, no extra memory. Parallel runs and sessions both default
to 1, so nothing changes until you turn them up. Measured on one RTX 4090: two
sessions gain little on a 31B model, four gain 2.9× on Qwen 3.6 27B. Every
stream reserves what it will occupy in the pool and waits for room rather than
overfilling it, so two subagents no longer die together with &quot;Context size has
been exceeded&quot; after a minute of visible progress.&lt;/p&gt;
&lt;p&gt;The app&#39;s own requests learnt to yield. A title, a reflection or a history
compaction that is streaming when your message arrives is cancelled and made
again after your reply, rather than holding your message until it ends —
measured, a message that waited 46 s on a CPU-only server now waits about
24 s, one that waited 5.6 s on a GPU under two. A CPU-only host runs a smaller
prompt batch for the same reason, and the app reads the server&#39;s own timing of
every prompt: once per server session it says in the feed how fast prompts are
processed and the one setting to change when that is slow.&lt;/p&gt;
&lt;h2 id=&quot;a-scene-of-two-characters&quot;&gt;A scene of two characters&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;run_dialogue&lt;/code&gt; stages a conversation between two personas the assistant
composes, and the assistant &lt;strong&gt;directs&lt;/strong&gt; it as it unfolds — a private stage
direction to one character, a retake, a line rewritten outright — and ends it
when the scene reaches its ending. The script is a child chat under the
conversation, each side under its character&#39;s name, the director&#39;s
interventions visible as notes; open it while it runs and each line streams in
on its speaker&#39;s side. One engine session, one request at a time, so no extra
VRAM on a local model; a run-time limit (30 minutes by default) bounds a scene
that will not end. Gemma 3&#39;s chat template, which refuses two same-role turns
in a row, is handled — for the director&#39;s memory of its verdicts, and for
&lt;code&gt;Ctrl+U&lt;/code&gt; impersonation, which used to answer with an engine error on every
chat you had opened yourself.&lt;/p&gt;
&lt;h2 id=&quot;the-engine-downloaded&quot;&gt;The engine, downloaded&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;mindfork llama backends&lt;/code&gt; lists the llama.cpp &lt;code&gt;llama-server&lt;/code&gt; builds published
for your OS and architecture — &lt;code&gt;cpu&lt;/code&gt;, &lt;code&gt;vulkan&lt;/code&gt;, &lt;code&gt;cuda-13.3&lt;/code&gt;, &lt;code&gt;rocm-10.0&lt;/code&gt;, … —
with their download sizes, and &lt;code&gt;mindfork llama setup --backend &amp;lt;id&amp;gt;&lt;/code&gt; fetches
one into &lt;code&gt;data/llama/&lt;/code&gt;. Every file is checked against the sha256 the release
publishes, an interrupted download resumes instead of starting over, and a
CUDA build brings the CUDA runtime with it — without it the backend does not
load and the server quietly runs on the CPU. Once unpacked, the binary is run
and reports its build number and the compute devices it found, so a GPU
backend with a missing driver says so instead of pretending. &lt;code&gt;--set-binary&lt;/code&gt;
writes the path into the settings; &lt;code&gt;mindfork llama installed&lt;/code&gt; and
&lt;code&gt;mindfork llama remove &amp;lt;id&amp;gt;&lt;/code&gt; manage what is on disk, and the remove refuses
while a setting still points at the build.&lt;/p&gt;
&lt;p&gt;Better still, the &lt;em&gt;llama-server binary&lt;/em&gt; field may now be left &lt;strong&gt;empty&lt;/strong&gt;: the
app takes the build installed last, or a &lt;code&gt;llama-server&lt;/code&gt; sitting next to the
application — so downloading one, or unpacking a llama.cpp archive beside
&lt;code&gt;mindfork&lt;/code&gt;, is enough to run in managed mode with nothing typed.&lt;/p&gt;
&lt;h2 id=&quot;pick-up-where-it-stopped&quot;&gt;Pick up where it stopped&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;/continue&lt;/code&gt; resumes an interrupted reply in place — one cut by &lt;code&gt;Esc&lt;/code&gt;, by a
dropped connection or by the length limit: the model picks up exactly at the
cut, the text grows inside the same message, and a turn interrupted between
tool calls resumes its tool loop. It works on the local and external engines,
on Gemini, and on Claude models up to the 4.5 generation; the providers that
cannot resume a partial reply (OpenAI, Grok, current Claude models) are told
apart, and the command says so instead of guessing. A reply that hit the
length limit finally gets a note at all.&lt;/p&gt;
&lt;p&gt;An external server&#39;s model is now &lt;strong&gt;named on screen&lt;/strong&gt; even when you did not
type it — the app asks the server what it is running — and the &quot;Model (opt.)&quot;
field, which had never actually been sent, now reaches the server:
&lt;code&gt;llama-server&lt;/code&gt; in router mode, LM Studio, LiteLLM and OpenRouter all pick the
model from it.&lt;/p&gt;
&lt;h2 id=&quot;off-until-you-say-so&quot;&gt;Off until you say so&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The web tools start off.&lt;/strong&gt; &lt;code&gt;web_search&lt;/code&gt;, &lt;code&gt;fetch_url&lt;/code&gt; and &lt;code&gt;youtube_watch&lt;/code&gt;
are disabled in a fresh installation: the search engines behind them are
picked by the app and the query is built from your conversation, so nothing
goes to them until you switch the tools on in Settings → Tools. An existing
installation keeps whatever its settings already say.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A search key is only used where you put it.&lt;/strong&gt; A &lt;code&gt;TAVILY_API_KEY&lt;/code&gt; sitting
in your environment for some other program is no longer picked up on its
own. Name the variable, or enter the key, in Settings → Tools.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The sandbox&#39;s largest download is verified too&lt;/strong&gt; — the Python
distribution &lt;code&gt;wasmer&lt;/code&gt; fetches on the app&#39;s behalf, until now the one file
not checked against a pinned checksum.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A privacy policy&lt;/strong&gt;, readable in the app: &lt;code&gt;F1&lt;/code&gt; → the tab that used to be
&quot;Disclaimer&quot; is now &lt;strong&gt;Legal&lt;/strong&gt; and carries both documents, in the interface
language. The Windows installer shows it and every archive ships it. It says
what stays on your machine, what leaves it and which setting has to be on
first, and what reaches the author — nothing.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The spellcheck dictionaries say where they come from&lt;/strong&gt;, with their
licences installed beside them; &lt;code&gt;en_GB&lt;/code&gt; moves to its author&#39;s current word
list, about 14 000 more stems; and an installed build gets a &lt;code&gt;dictionaries/&lt;/code&gt;
folder of your own in the data directory, with a note on how to add one.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;also-in-this-release&quot;&gt;Also in this release&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Files in an older encoding are read — and edited — as they are.&lt;/strong&gt; A
windows-1251, KOI8-R or cp866 text, or Notepad&#39;s &quot;Unicode&quot;, used to reach
the assistant with every letter replaced by the replacement character, and
an edit in an attached project rewrote the whole file that way. Files are
read in their own encoding now, an edit is written back in it — refused with
nothing written when the encoding cannot hold the new text — and a web page
in an older encoding is read as it declares itself, or recognised from its
text.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A fetched page is named after the page&lt;/strong&gt;, not its site — every chapter of
the Rust Book used to be attached as &quot;The Rust Programming Language&quot;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Spellcheck no longer stumbles over a stress mark&lt;/strong&gt;: a word carrying one is
judged whole, stressed text is left alone, and a real typo under the mark is
still underlined.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The assistant can name its language model.&lt;/strong&gt; &lt;code&gt;get_llm_name&lt;/code&gt; answers
&quot;which model are you?&quot; with the model actually generating the reply, and
&lt;code&gt;get_llm_history&lt;/code&gt; lists the profile&#39;s dated history of model changes —
filled from your existing chats on the first launch, as far back as they go.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The self-model screen (&lt;code&gt;F3&lt;/code&gt;) reads as two named halves&lt;/strong&gt; — &lt;em&gt;Assistant&lt;/em&gt;
and &lt;em&gt;User&lt;/em&gt;, or the names from the profile — with the newest observation
first; a setting flips the order.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Every key hint names only keys that work&lt;/strong&gt;, sits in the same place on
every screen and follows what you have selected, and &lt;code&gt;F1&lt;/code&gt; is among the hints
everywhere. The status bar no longer stacks its hints into a column while a
turn runs, and says &lt;em&gt;cancel&lt;/em&gt; for &lt;code&gt;Esc&lt;/code&gt; while a reply is generating.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;An API-key field says whose key it is&lt;/strong&gt; — &lt;em&gt;OpenAI API key&lt;/em&gt;, &lt;em&gt;Tavily API
key (env, opt.)&lt;/em&gt; — everywhere one is entered.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The chat list counts messages the way the conversation reads&lt;/strong&gt;: your
questions and the assistant&#39;s replies, not every tool call&#39;s result.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A long title no longer ends mid-word&lt;/strong&gt;: it is cut where it is drawn, to
the columns that screen has, always with &quot;…&quot; — and titles an older limit had
cut on disk are repaired.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A tool round on OpenAI no longer fails when the model reasons in stages&lt;/strong&gt;,
and a server error inside an open stream ends the reply as an error — with
the retry that was always meant to run — instead of passing for a finished
reply cut mid-word.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;In KDE Konsole the footer names the line-break chord the terminal can
actually deliver&lt;/strong&gt; (&lt;code&gt;Alt+Enter&lt;/code&gt;), instead of one it silently swallows.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;mindfork.exe&lt;/code&gt; calls itself &lt;code&gt;mindfork&lt;/code&gt;&lt;/strong&gt; in Task Manager and Explorer,
with the author and copyright it was missing; the installer carries the
real version instead of &lt;code&gt;0.0.0.0&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Python sandbox installs and runs again.&lt;/strong&gt; The Python package is pinned
to an exact version, after a build published in the Wasmer registry in late
August could not be compiled by the runtime the app pins. A sandbox
installed in that window needs &lt;code&gt;mindfork sandbox setup --force&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;One note on data: chats gain a list of stored files, and the data folder a
&lt;code&gt;files/&lt;/code&gt; directory beside &lt;code&gt;chats/&lt;/code&gt;; chat files move to schema 4 — a version
stamp for dialogue transcripts, then the repair of titles an older limit had
cut. Both migrations happen automatically on the first start, after a
pre-migration backup, and nothing is removed; an older build refuses to open
migrated data rather than misread it.&lt;/p&gt;
&lt;p&gt;The full list is in the
&lt;a rel=&quot;external&quot; href=&quot;https://github.com/vshylov/mindfork-rs/blob/main/CHANGELOG.md&quot;&gt;changelog&lt;/a&gt;.
Downloads — Windows installer and archive, Linux archive, &lt;code&gt;.deb&lt;/code&gt;, &lt;code&gt;.rpm&lt;/code&gt; and
&lt;code&gt;.pkg.tar.zst&lt;/code&gt; — are on the
&lt;a rel=&quot;external&quot; href=&quot;https://github.com/vshylov/mindfork-rs/releases&quot;&gt;releases page&lt;/a&gt;.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>mindfork 0.9.8 — give it real work</title>
        <published>2026-08-27T00:00:00+00:00</published>
        <updated>2026-08-27T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://mindfork.io/blog/mindfork-0-9-8/"/>
        <id>https://mindfork.io/blog/mindfork-0-9-8/</id>
        
        <content type="html" xml:base="https://mindfork.io/blog/mindfork-0-9-8/">&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/vshylov/mindfork-rs/releases&quot;&gt;mindfork 0.9.8&lt;/a&gt; is out. It is
a release about &lt;em&gt;work&lt;/em&gt;: handing the assistant something real to do — your code
project, a side-task big enough to delegate — and being able to watch every bit
of it happen.&lt;/p&gt;
&lt;h2 id=&quot;a-code-project-attached-to-a-chat&quot;&gt;A code project, attached to a chat&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;/project attach &amp;lt;directory&amp;gt;&lt;/code&gt; gives the open conversation a project. With one
attached, the assistant can see the project&#39;s structure, read its files with
line numbers and search them by regular expression — confined to that
directory, honouring &lt;code&gt;.gitignore&lt;/code&gt;. It can change files too: an edit replaces an
exact fragment, or writes a file whole, and every file&#39;s previous content is
saved before it is first touched.&lt;/p&gt;
&lt;p&gt;That last part is what makes the feature trustworthy. &lt;strong&gt;&lt;code&gt;F4&lt;/code&gt;&lt;/strong&gt; (or &lt;code&gt;/changes&lt;/code&gt;)
opens a screen listing every file the assistant touched, each shown as a diff
against the file as it was before — and &lt;code&gt;r&lt;/code&gt; puts one file back the way it was,
after asking. A file the assistant created is removed instead. If you would
rather approve each change before it happens, the existing &quot;confirm dangerous
calls&quot; switch covers project edits as well.&lt;/p&gt;
&lt;p&gt;It can also build, run and test — but only through command lines &lt;em&gt;you&lt;/em&gt; type:
&lt;code&gt;/project build-cmd cargo build&lt;/code&gt;, and the same for &lt;code&gt;run-cmd&lt;/code&gt; and &lt;code&gt;test-cmd&lt;/code&gt;.
The assistant runs them exactly as written and can never compose a command of
its own, add a flag, or chain a pipeline; a slot you have not filled gives it
no such tool at all. A command that outruns its time limit is stopped together
with everything it started, and whatever it printed still comes back.&lt;/p&gt;
&lt;p&gt;Attaching &lt;strong&gt;is&lt;/strong&gt; the permission: with no project attached, none of these tools
even exist, and nothing changes about what the assistant can reach. Reading and
editing the project deliberately do not spend the turn&#39;s tool-call budget — a
fix takes as many steps as it takes.&lt;/p&gt;
&lt;h2 id=&quot;subagents-grew-up&quot;&gt;Subagents grew up&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;call_subagent&lt;/code&gt; used to ask a persona one tool-less question. Now a delegation
is a &lt;strong&gt;nested turn with the assistant&#39;s own tools&lt;/strong&gt; — the same web, files,
Python, project and plugin tools it has in that chat (except creating
subagents of its own, reading the folded history and the self-model), over the
same attached files, under a persona the assistant composes. A dangerous call
inside the run asks you exactly as it would outside.&lt;/p&gt;
&lt;p&gt;The transcript became a conversation of its own. Every delegation shows as a
row nested under the chat that made it, opens like a chat — read-only — and is
searchable everywhere a chat is: the list&#39;s content search, the message-level
results, even the assistant&#39;s opt-in cross-chat tools. It gets a model-written
title when it lands, carries a &lt;code&gt;chat://&lt;/code&gt; address you can follow, and old
conversations join in: chats recorded before this release get a transcript
reconstructed from what each call already stored.&lt;/p&gt;
&lt;p&gt;And it is all visible &lt;strong&gt;while it runs&lt;/strong&gt;. The transcript appears in the list the
moment the assistant delegates, marked &lt;em&gt;running&lt;/em&gt;, its message count growing
round by round; open it and the subagent&#39;s reply streams word by word,
thoughts and tool calls included — and stepping between the transcript and the
parent chat no longer cancels the turn. The status bar shows a quiet chip with
the subagent&#39;s name, the round it is on and the tool it is using. In the same
spirit, every tool call&#39;s card now appears in the feed the moment the call
starts, marked &lt;em&gt;running…&lt;/em&gt;, and fills in when the result arrives — so a long
build or delegation is visible where it happens.&lt;/p&gt;
&lt;p&gt;The chat list keeps transcript rows folded under their chat by default, with a
muted &lt;code&gt;▸ n&lt;/code&gt; saying how many it holds — &lt;code&gt;Ctrl+O&lt;/code&gt; unfolds them, and the choice is
remembered per chat.&lt;/p&gt;
&lt;h2 id=&quot;web-search-with-a-key-this-time&quot;&gt;Web search, with a key this time&lt;/h2&gt;
&lt;p&gt;The free search engines throttle automated requests hard — measured, they
answer about twice in a row before blocking, and the block lasts far longer
than a conversation. A long chain of searches used to fall apart on that.&lt;/p&gt;
&lt;p&gt;Settings → Tools → Web search now takes an API key for &lt;strong&gt;Tavily&lt;/strong&gt; — the free
tier is 1000 searches a month, no card needed. With a key entered the assistant
searches through Tavily first; the free engines stay as the fallback, so
entering no key changes nothing. Blocks are also recognised for what they are
now: a provider that just refused is told to the assistant as &lt;em&gt;temporarily
unavailable&lt;/em&gt; rather than as &quot;the web has nothing on this&quot;, and it is tried last
for a few minutes instead of being retried first on every call — but never
dropped. Search results say which service answered.&lt;/p&gt;
&lt;h2 id=&quot;also-in-this-release&quot;&gt;Also in this release&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The command is &lt;code&gt;mindfork&lt;/code&gt; now.&lt;/strong&gt; The binary lost the &lt;code&gt;-rs&lt;/code&gt; suffix — that
stays the project&#39;s name. The Linux packages symlink &lt;code&gt;/usr/bin/mindfork&lt;/code&gt;, the
Windows installer installs &lt;code&gt;mindfork.exe&lt;/code&gt;; where your data lives is
unchanged.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The &lt;code&gt;auto&lt;/code&gt; theme really follows your terminal.&lt;/strong&gt; The app asks the terminal
for its background colour at start-up (Windows Terminal, VS Code&#39;s terminal,
JupyterLab&#39;s, plain SSH and tmux all answer; the legacy Windows console does
not, and is treated as the dark background it is), so code blocks and the
selection backdrop stop being dark on a light terminal.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;F1&lt;/code&gt; opens the help from any screen&lt;/strong&gt;, landing on that screen&#39;s own key
section, marked &lt;em&gt;you are here&lt;/em&gt; — and the settings, self-model, changes and
search screens&#39; keys are listed at all for the first time.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The licence and the disclaimer speak Russian&lt;/strong&gt; when the interface does — on
the &lt;code&gt;F1&lt;/code&gt; tabs and the Windows installer&#39;s legal pages. The translations are
unofficial and say so; the English originals govern.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A model split across several GGUF parts&lt;/strong&gt; loads by pointing the setting at
the first part — and the two ways of getting it wrong are caught before
launch instead of showing up as a server that quietly exits.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;More typed commands&lt;/strong&gt;: &lt;code&gt;/autotitle&lt;/code&gt; for a model-written title,
&lt;code&gt;/impersonation list|new|delete|use|system&lt;/code&gt; for the personas &lt;code&gt;Ctrl+U&lt;/code&gt; writes
as, &lt;code&gt;/profile system|greeting&lt;/code&gt; for the profile&#39;s texts — each usable where a
browser tab or an embedded terminal keeps the chord for itself.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Starting without the database says so.&lt;/strong&gt; A data folder copied without
&lt;code&gt;data.db&lt;/code&gt; used to open silently amnesiac; now the app says what is empty,
what survived and how to get the rest back — and &lt;code&gt;/reindex&lt;/code&gt; rebuilds an
attached file&#39;s missing search index from the text the chat already holds.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;One note on data: this release migrates two stored formats — chat files and
&lt;code&gt;settings.json&lt;/code&gt;, each schema 1 → 2. Both happen automatically on the first
start, after a pre-migration backup, and nothing is removed; an older build
refuses to open migrated data rather than misread it.&lt;/p&gt;
&lt;p&gt;The full list is in the
&lt;a rel=&quot;external&quot; href=&quot;https://github.com/vshylov/mindfork-rs/blob/main/CHANGELOG.md&quot;&gt;changelog&lt;/a&gt;.
Downloads — Windows installer (64-bit now) and archive, Linux archive, &lt;code&gt;.deb&lt;/code&gt;,
&lt;code&gt;.rpm&lt;/code&gt; and &lt;code&gt;.pkg.tar.zst&lt;/code&gt; — are on the
&lt;a rel=&quot;external&quot; href=&quot;https://github.com/vshylov/mindfork-rs/releases&quot;&gt;releases page&lt;/a&gt;.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>mindfork 0.9.7 — wherever your terminal is</title>
        <published>2026-08-17T00:00:00+00:00</published>
        <updated>2026-08-17T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://mindfork.io/blog/mindfork-0-9-7/"/>
        <id>https://mindfork.io/blog/mindfork-0-9-7/</id>
        
        <content type="html" xml:base="https://mindfork.io/blog/mindfork-0-9-7/">&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/vshylov/mindfork-rs/releases&quot;&gt;mindfork 0.9.7&lt;/a&gt; is out. It is
a release about &lt;em&gt;reach&lt;/em&gt;: running the app somewhere other than a terminal window
of your own, and giving conversations an address so they can point at each
other.&lt;/p&gt;
&lt;h2 id=&quot;the-terminal-is-not-always-yours&quot;&gt;The terminal is not always yours&lt;/h2&gt;
&lt;p&gt;A terminal embedded in something else takes key combinations for itself before
the app ever sees them. VS Code&#39;s integrated terminal claims &lt;code&gt;Ctrl+P&lt;/code&gt;, &lt;code&gt;Ctrl+E&lt;/code&gt;,
&lt;code&gt;Ctrl+F&lt;/code&gt;, &lt;code&gt;Ctrl+K&lt;/code&gt;, &lt;code&gt;F1&lt;/code&gt;, &lt;code&gt;F3&lt;/code&gt;, &lt;code&gt;F5&lt;/code&gt;, &lt;code&gt;F10&lt;/code&gt; and &lt;code&gt;Ctrl+Q&lt;/code&gt; by default; a terminal
in a browser tab claims &lt;code&gt;Ctrl+N&lt;/code&gt;, &lt;code&gt;Ctrl+T&lt;/code&gt; and &lt;code&gt;Ctrl+W&lt;/code&gt; — the last of which
closes the tab your session is running in. Measured against VS Code&#39;s defaults,
six features of the app were simply unreachable there.&lt;/p&gt;
&lt;p&gt;Nineteen new commands close that: &lt;code&gt;/settings&lt;/code&gt;, &lt;code&gt;/self&lt;/code&gt;, &lt;code&gt;/chats&lt;/code&gt;, &lt;code&gt;/help&lt;/code&gt;,
&lt;code&gt;/new&lt;/code&gt;, &lt;code&gt;/rename&lt;/code&gt;, &lt;code&gt;/clone&lt;/code&gt;, &lt;code&gt;/copy&lt;/code&gt;, &lt;code&gt;/regen&lt;/code&gt;, &lt;code&gt;/takeback&lt;/code&gt;, &lt;code&gt;/impersonate&lt;/code&gt;,
&lt;code&gt;/stop&lt;/code&gt;, &lt;code&gt;/find&lt;/code&gt;, &lt;code&gt;/search&lt;/code&gt;, &lt;code&gt;/links&lt;/code&gt;, &lt;code&gt;/thoughts&lt;/code&gt;, &lt;code&gt;/toolcalls&lt;/code&gt;, &lt;code&gt;/mouse&lt;/code&gt; and
&lt;code&gt;/emoji&lt;/code&gt;, plus &lt;code&gt;/profile list|new|delete&lt;/code&gt; and &lt;code&gt;/self clear&lt;/code&gt; for the two actions
that lived inside other screens. Each one reaches the same handler its key
does, confirmation prompts included — and, unlike a key, a command that cannot
run right now says why and names something that will. The keys are unchanged;
what the commands add is a second route.&lt;/p&gt;
&lt;h2 id=&quot;copying-works-over-ssh&quot;&gt;Copying works over SSH&lt;/h2&gt;
&lt;p&gt;The clipboard an application writes belongs to the machine it runs on. Over SSH
that is the &lt;em&gt;server&#39;s&lt;/em&gt; clipboard, which does you no good — and on a headless
server, where there is no clipboard at all, a copy simply failed.&lt;/p&gt;
&lt;p&gt;A copy is now also handed to the clipboard of the machine your &lt;strong&gt;terminal&lt;/strong&gt; runs
on, through the terminal itself (OSC 52), automatically when the session looks
remote. A new setting makes that &lt;code&gt;always&lt;/code&gt; or &lt;code&gt;off&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The protocol acknowledges nothing, so the app says the text was &lt;em&gt;sent&lt;/em&gt; rather
than promising it arrived — and not every terminal implements it: GNOME
Terminal, Terminal.app and JupyterLab&#39;s terminal do not. A conversation too
large for the sequence (about 75 KB) is reported as such instead of being
quietly cut in half.&lt;/p&gt;
&lt;h2 id=&quot;a-conversation-saved-to-a-file&quot;&gt;A conversation, saved to a file&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;/export&lt;/code&gt; writes the open chat next to wherever you started the app, named after
the chat and the date; &lt;code&gt;/export path/to/name.md&lt;/code&gt; puts it where you say. Markdown
is byte-for-byte what &lt;code&gt;F5&lt;/code&gt; copies, and &lt;strong&gt;json&lt;/strong&gt; is a document &lt;code&gt;mindfork-rs import&lt;/code&gt; reads back onto the same conversation. An existing file is never
overwritten.&lt;/p&gt;
&lt;p&gt;This is also the one way out of a browser terminal such as JupyterLab&#39;s, where
neither clipboard route can reach your machine at all.&lt;/p&gt;
&lt;h2 id=&quot;your-other-conversations&quot;&gt;Your other conversations&lt;/h2&gt;
&lt;p&gt;Two new tools, &lt;code&gt;chat_search&lt;/code&gt; and &lt;code&gt;chat_read&lt;/code&gt;, let the assistant find and read
what your &lt;em&gt;other&lt;/em&gt; conversations with the same companion said — for questions
like &quot;we worked this out in another chat&quot;. They are &lt;strong&gt;off by default&lt;/strong&gt; and not
even shown to the model until you turn them on per profile; the current chat,
hidden chats and other profiles stay out of reach.&lt;/p&gt;
&lt;p&gt;When the assistant mentions one of those conversations it now writes its address
as &lt;code&gt;chat://&amp;lt;id&amp;gt;&lt;/code&gt;, and the feed draws that as a link. &lt;code&gt;Ctrl+L&lt;/code&gt; lists the
conversations the open chat points at and opens the one you pick; with mouse
capture on you can click the link — the first thing in the feed that is
clickable at all. &lt;code&gt;Esc&lt;/code&gt; takes you back where you came from, and keeps meaning
that only while you are &lt;em&gt;reading&lt;/em&gt;: start working in the chat you arrived at and
&lt;code&gt;Esc&lt;/code&gt; goes back to meaning &quot;the chat list&quot;, so it can never teleport you out of
a conversation you have settled into.&lt;/p&gt;
&lt;p&gt;Only addresses that really lead somewhere are drawn as links, so following one
is never a dead end.&lt;/p&gt;
&lt;h2 id=&quot;also-in-this-release&quot;&gt;Also in this release&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;New chats name themselves.&lt;/strong&gt; After the first reply the model writes the
conversation a short title — no more lists full of &quot;New chat&quot;. On by default;
a setting moves it to right after your first message, the way cloud chat UIs
do it, or turns it off. A chat you renamed yourself is never touched.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;An external server&#39;s API key&lt;/strong&gt; can be entered in settings, stored encrypted
and bound to this machine, instead of having to come from an environment
variable — for a gateway such as LiteLLM or OpenRouter, or a &lt;code&gt;llama-server&lt;/code&gt;
started with &lt;code&gt;--api-key&lt;/code&gt;. Each &lt;code&gt;external&lt;/code&gt; tab keeps its own key, because those
are four independent servers.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The model&#39;s name in the feed&lt;/strong&gt;, optionally, next to each reply — taken from
the message itself, so a conversation reopened after switching providers still
says which model actually answered.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The &lt;code&gt;F1&lt;/code&gt; help window&lt;/strong&gt; grows with the terminal, aligns its descriptions in a
column and wraps the long ones instead of cutting them off mid-word.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The full list is in the
&lt;a rel=&quot;external&quot; href=&quot;https://github.com/vshylov/mindfork-rs/blob/main/CHANGELOG.md&quot;&gt;changelog&lt;/a&gt;.
Downloads — Windows installer and archive, Linux archive, &lt;code&gt;.deb&lt;/code&gt;, &lt;code&gt;.rpm&lt;/code&gt; and
&lt;code&gt;.pkg.tar.zst&lt;/code&gt; — are on the
&lt;a rel=&quot;external&quot; href=&quot;https://github.com/vshylov/mindfork-rs/releases&quot;&gt;releases page&lt;/a&gt;.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>mindfork 0.9.6 — the model can see</title>
        <published>2026-08-13T00:00:00+00:00</published>
        <updated>2026-08-13T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://mindfork.io/blog/mindfork-0-9-6/"/>
        <id>https://mindfork.io/blog/mindfork-0-9-6/</id>
        
        <content type="html" xml:base="https://mindfork.io/blog/mindfork-0-9-6/">&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/vshylov/mindfork-rs/releases&quot;&gt;mindfork 0.9.6&lt;/a&gt; is out. The
headline is images: you can now show the model a picture. The quieter half of
the release is about what the assistant is &lt;em&gt;not&lt;/em&gt; allowed to reach.&lt;/p&gt;
&lt;h2 id=&quot;show-it-a-picture&quot;&gt;Show it a picture&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;/image attach &amp;lt;path&amp;gt;&lt;/code&gt; puts an image on your next message. &lt;code&gt;/image paste&lt;/code&gt; takes
one straight off the clipboard, so a screenshot needs no file at all —
&lt;code&gt;Ctrl+V&lt;/code&gt; does it too, in terminals that let the key through (Windows Terminal
keeps that combination for its own paste, which is exactly why the command
exists). &lt;code&gt;/image attach https://…&lt;/code&gt; downloads the picture and stages it the same
way; the image itself is stored in the conversation, so it keeps working later
even if the link stops working.&lt;/p&gt;
&lt;p&gt;It works with a local vision-capable model — start &lt;code&gt;llama-server&lt;/code&gt; with a
projector — and with all four cloud providers. png, jpeg, webp, gif and bmp are
accepted and converted to what each provider takes, and a large image is shrunk
once, when you attach it, rather than costing you the upload on every later
turn. If the engine says it cannot see images, the attach is refused up front
and tells you what to change, instead of failing at send time.&lt;/p&gt;
&lt;p&gt;An image an &lt;strong&gt;MCP tool&lt;/strong&gt; returns reaches the model too, so a screenshot or a
chart a plugin produces can actually be looked at. That one comes with a switch
in settings — &quot;Let servers send images&quot;, on by default — because instructions
can be painted into pixels where you would not see them.&lt;/p&gt;
&lt;h2 id=&quot;the-web-tools-stop-at-your-front-door&quot;&gt;The web tools stop at your front door&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;fetch_url&lt;/code&gt; and the pages &lt;code&gt;web_search&lt;/code&gt; reads now refuse addresses that are not
on the public internet: your own machine, your LAN, and the address cloud
providers keep their credentials behind.&lt;/p&gt;
&lt;p&gt;This matters because of where the assistant&#39;s links come from. They are rarely
typed by you — they come off a page it just fetched, a search result, or a
document you attached. Any of those can ask it to open something on your side
of the router, and until this release nothing stopped it.&lt;/p&gt;
&lt;p&gt;If you &lt;em&gt;do&lt;/em&gt; want one reachable — a wiki or a dashboard on your network — there
is a new switch in settings → Tools: &lt;strong&gt;Allow local addresses&lt;/strong&gt;, off by default.
Attaching an image by address, which you type yourself, is unaffected, and so
is the address of your own engine.&lt;/p&gt;
&lt;h2 id=&quot;a-blip-no-longer-costs-the-turn&quot;&gt;A blip no longer costs the turn&lt;/h2&gt;
&lt;p&gt;When a cloud provider rate-limits or sheds load, the request is now retried —
three attempts with a short backoff, honouring the provider&#39;s own &lt;code&gt;Retry-After&lt;/code&gt;.
This matters most in a long turn: one blip on the eighth tool round used to
throw away the whole turn&#39;s work. Retries stop as soon as the answer starts
arriving, so nothing you have already read is re-generated and no tool runs
twice.&lt;/p&gt;
&lt;p&gt;Related, and overdue: a reply that gets cut off now says so. When the engine
failed &lt;em&gt;after&lt;/em&gt; the answer had started, the fragment used to sit on screen
looking like the whole reply.&lt;/p&gt;
&lt;h2 id=&quot;also-in-this-release&quot;&gt;Also in this release&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;mindfork demo&lt;/code&gt;&lt;/strong&gt; — the interactive demo mode announced when this site went
up ships in this release: the real TUI on seeded data with a scripted engine,
no model download, no API key, nothing written outside a temp folder.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Windows installer&lt;/strong&gt; now shows the MIT license and the disclaimer during
installation, rather than only dropping them next to the binary afterwards.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Esc&lt;/code&gt; interrupts a request that is still connecting, and a network failure
shows its reason instead of a bare URL.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The full list is in the
&lt;a rel=&quot;external&quot; href=&quot;https://github.com/vshylov/mindfork-rs/blob/main/CHANGELOG.md&quot;&gt;changelog&lt;/a&gt;.
Downloads — Windows installer and archive, Linux archive, &lt;code&gt;.deb&lt;/code&gt;, &lt;code&gt;.rpm&lt;/code&gt; and
&lt;code&gt;.pkg.tar.zst&lt;/code&gt; — are on the
&lt;a rel=&quot;external&quot; href=&quot;https://github.com/vshylov/mindfork-rs/releases&quot;&gt;releases page&lt;/a&gt;.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Hello from mindfork 0.9.5</title>
        <published>2026-08-10T00:00:00+00:00</published>
        <updated>2026-08-10T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://mindfork.io/blog/hello-mindfork/"/>
        <id>https://mindfork.io/blog/hello-mindfork/</id>
        
        <content type="html" xml:base="https://mindfork.io/blog/hello-mindfork/">&lt;p&gt;mindfork is a terminal AI chat written in Rust. It runs local models through
llama.cpp&#39;s &lt;code&gt;llama-server&lt;/code&gt;, speaks to OpenAI, Anthropic, Gemini and Grok in
the cloud, and keeps a memory of its own: a self-model, notes with a link
graph, and RAG over your documents. Windows and Linux, one native binary.&lt;/p&gt;
&lt;p&gt;This site is its new home. Short project news lands here in the blog — there
is an &lt;a href=&quot;/atom.xml&quot;&gt;Atom feed&lt;/a&gt; — and longer pieces live in
&lt;a href=&quot;/articles/&quot;&gt;Articles&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;where-the-project-stands&quot;&gt;Where the project stands&lt;/h2&gt;
&lt;p&gt;Version 0.9.5. The original M0–M9 plan is finished, and the last few months
added, among other things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;mindfork demo&lt;/code&gt;&lt;/strong&gt; — an interactive demo mode: the real TUI on seeded
data with a scripted engine. No model download, no API key, nothing
written outside a temp folder.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Grok (xAI)&lt;/strong&gt; as the fourth cloud provider.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;History compression&lt;/strong&gt; — a rolling summary keeps a long conversation
inside the model&#39;s context window (&lt;code&gt;/compact&lt;/code&gt;, plus an automatic
trigger), with read-back tools for the folded range.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Generated screenshots&lt;/strong&gt; — every screenshot on this site is rendered
from the current code by the test suite and guarded against rot in CI.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;what-s-next&quot;&gt;What&#39;s next&lt;/h2&gt;
&lt;p&gt;Cloud-error retry/backoff and image input sit at the top of the roadmap.
News will land here as it ships.&lt;/p&gt;
</content>
        
    </entry>
</feed>
