Releases: vshylov/mindfork-rs
Release list
mindfork-rs v0.11.0
From a bare Linux machine to a local model that answers, in one line. A new
command installs the Python sandbox and llama.cpp and writes the model, its
projector, the embedding model and the context into the settings — checked
before anything is downloaded, and started once to prove it loads; an install
script puts the app itself on the machine first. Written for a rented GPU box
that is new at every stop, and just as good on a desktop. And llama setup can
install CUDA builds on Linux, which it had been refusing.
Added
mindfork setup— a working local engine from one command. For a machine
that is new every time (a rented GPU box, a container), and any other:
mindfork setup --sandbox --llama cuda-12 --model … --mmproj … --embed-model … --ctx 32768 --verifyinstalls the Python sandbox and llama.cpp, writes the
model, projector, embedding model and context into the settings and switches
the engine to managed mode — no settings screen in between. Paths and keys are
checked before anything is downloaded; a step that fails does not stop the
others, and running the same line again repeats only what is missing.
--set engine.managed.sessions=4reaches any other setting, and--verify
starts the servers once and reports how long they took to load, the context,
whether the model takes images — or why it did not start.- An install script for Linux, and a recipe for a rented GPU box.
curl -fsSL …/releases/latest/download/install.sh | shunpacks the portable build, checks
it against the release's checksums, installs the one system library a bare
image lacks, and can hand the rest of the line tomindfork setup. It is safe
to run again: on RunPod, where a stopped pod loses everything outside
/workspace, the same line puts back what is missing in seconds
(docs/install.md §1, §3.4). mindfork llama setup --backend cuda-12— a backend family. llama.cpp
renames its CUDA builds whenever it moves to the next toolkit (cuda-13.3
becamecuda-13.4inside two weeks), so a command you had saved stopped
working. A family installs the one build of it on offer; one that fits two
backends (cuda,sycl) is refused and both are named.
Fixed
mindfork llama setuprefused every CUDA build on Linux. llama.cpp has
published CUDA builds for Linux since mid-September 2026, but the command
looked for their runtime archive under the name the Windows one has, found
nothing, listed the backend as "no CUDA runtime published" and would not
install it.- The installed llama.cpp's version read as a log line. Recent builds print
a log line ahead of their version, sollama setupshowed that line instead —
and the check that the binary you got is the build you asked for stopped
checking, without saying so. The version is found by what it says now, and a
binary that names no build number is reported as such. llama setupcould pick a half-uploaded build. With no--build, it
takes the newest build that actually has the backend you named, complete,
instead of the newest with anything in it.
mindfork-rs v0.10.2
For data that lives on more than one computer. A new command says which copy
is the newest and what each one holds that the other lacks — without restoring or
changing anything — and opening a chat no longer flashes the one you were leaving.
Added
mindfork stats— which copy of your data is the newest. With the data on
several computers, one command now prints when the last message was written,
how many chats and messages there are (and how many are deleted), the attached
files, images, projects, notes and the knowledge base — for the data on this
computer, or for a backup archive without restoring it
(mindfork stats copy.zip, with--passwordfor an encrypted one). It only
reads: nothing is created or unpacked, so it is safe while the app is open, and
an encrypted archive is never written out decrypted. The summary ends with a
fingerprint: two computers that print the same one hold identical data.mindfork stats --compare— what each copy holds that the other lacks. The
newest copy is not always the most complete one. Take a snapshot on the other
computer (mindfork stats --json > laptop.json, a small file with no message
text in it) or use a backup archive of it, and--compareprints a verdict —
identical, this copy has everything, the other has everything, or each holds
something — and the lists behind it: chats only here, only there, continued
here or there, and diverged (one chat continued on both computers). Chats
are compared by the ids of their messages, not by counts or dates, so a chat
continued on two machines is never reported as merely "newer there".
Changed
restoreasks for the password on stderr, so redirecting a command'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--password, instead of
"wrong backup password" for a password you never typed.
Fixed
- Opening a chat no longer flashes the previous one. Picking a chat in the
chat list showed the conversation you were leaving 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.
mindfork-rs v0.10.1
The first release that also goes to a package registry. Nothing on screen
changed; what did is where the program can be installed from, and one line in
your shell profile if you read its logs.
Added
cargo install mindfork. The package is published to
crates.io asmindfork— the repository
keeps its-rs, which says "written in Rust". It builds from source and
installs the binary alone, so the spellcheck dictionaries are not part of it
and the portable data directory lands next to the installed executable;
docs/install.md §1 says what that means and how to change
it. The prebuilt archives, the Linux packages and the Windows installer carry
the dictionaries and every licence text, and remain the recommended way in.
Changed
- The log filter is
mindfork, notmindfork_rs.MINDFORK_LOGtakes
crate names, and the crate was renamed for the registry — so a filter written
asMINDFORK_LOG=mindfork_rs=debugno longer names anything in this program,
and the lines it used to turn on stay off. Write
MINDFORK_LOG=mindfork=debug. - The crypto stack that encrypts stored API keys moved up a generation
(sha20.10 → 0.11 withhkdf/hmacto match, on Linux). The derived key is
byte-for-byte the one the old crates produced — pinned by a test against a
vector measured on them — so keys stored by an earlier version keep opening.
mindfork-rs v0.10.0
The first public release. Everything before this shipped to a handful of
people who knew where to look; this is the one a stranger downloads. Most of the
work behind it is invisible on screen and only shows up when something would
otherwise have gone wrong: a Windows binary that starts on a clean machine, file
tools that cannot reach outside the folder you give them, a sandbox with no route
to your own network, the licence of every dependency travelling with every
download, and a release that is checked against this changelog before it is
built. What you will notice: you now pick a model from the provider's own list
instead of typing its name, a thinking model's answer is no longer cut off in the
middle, and there is a manual.
Added
-
A manual. docs/manual.md is the document the project did
not have: how the app is actually used — the screens and how to move between
them, what it remembers and where each memory lives, files and images and an
attached code project, the tools and what each switch opens, the settings worth
knowing early, the full list of keys and commands, and what to do when
something goes wrong. docs/README.md is the index over it and
everything else. -
Pick the model from a list, instead of typing its name.
Enteron a model
field in settings — the assistant's, impersonation's or the embedder's — asks
the provider what it serves and shows the list, with a filter line to type into
andCtrl+Rto ask again; the first row of the list is still "type a name by
hand". Where a provider says what a model is for, the list is narrowed to it
(Gemini, xAI and Anthropic do; the embedder's list then holds embedding models
only); where it says nothing, everything it lists is offered — ordered so that
the ones whose names look like image, audio or embedding models sit at the
bottom rather than the top, newest first within each group, with the models the
provider is retiring marked. Nothing is ever hidden: whatever the provider
lists can be chosen. Nothing is requested until you open the list,
and if there is no list to show — no key yet, no answer, an address that serves
no catalogue — the field works exactly as before and says why. The hint on those
fields has stopped naming example models: it points at the list instead, which
cannot go out of date. -
The Windows installer can put
mindforkonPATH. A box on the "Additional
tasks" page, off by default: with it,mindfork llama setupand the other
commands the app suggests work from any terminal instead of only from the install
folder. It is added once however many times you upgrade, and removed when you
uninstall. -
Every download now carries the licences of what it is built from. The archives, the
Linux packages and the Windows installer includeTHIRD-PARTY-NOTICES.md— the licence
text of every Rust package the binary is built from, generated for that exact release —
and the licences of the vendored syntax grammars underlicenses/syntaxes/. Thedeb,
rpmand Arch packages also carry the privacy policy, which until now only the archives
and the installer had. -
A gateway's own catalogue now configures the app. Point
externalmode at a
service that publishes one (OpenRouter and the like) and two things stop being
your job: long chats are compacted automatically, measured against the window
the catalogue gives for the model you named — before, that number had to be
typed in or nothing was ever folded — and the sampling settings show only the
parameters that endpoint actually takes, instead of the full local-model set of
which it silently drops half. The same narrowing reaches the assistant's own
set_samplingand the per-message record of what was applied. A typed context
window still wins, and nothing changes against a local server, which publishes
no catalogue. -
A fresh install says how to connect a model. An empty chat with no model
configured lists the ways to start — a cloud provider in the settings (Ctrl+Por
/settings), a local llama.cpp build throughmindfork llama setup, or
mindfork demoto look around — and sending a message there points at the settings
instead of answering "LLM server is not configured".
Fixed
-
A managed server would not start with "No mmap" ticked. llama.cpp replaced
--no-mmapwith--load-modeand then removed the old flag entirely, so any
current build — including the onemindfork llama setupinstalls — refused to
launch witherror: invalid argument: --no-mmap. The app now asks the binary
which spelling it takes and sends that one, so the box works both on a current
llama.cpp and on an older one you already have. The setting's row is labelled
"No mmap" rather than by a flag name that depends on the build. -
A thinking model's answer is no longer cut off in the middle. The reply limit
counts the model's own reasoning on every provider that charges for it that way,
and the shipped limit of 2048 tokens was set before any of them did: measured on
Gemini 2.5 Pro, a school arithmetic question spent 1697 tokens thinking, left 347
for the answer, and the reply ended mid-explanation. The default is now 16384 —
a limit you typed yourself is kept as it is. -
A local model server is no longer started without a model. With a llama.cpp
build installed and no GGUF chosen, the app started the server anyway; it came up
in a mode that answers "ready" while refusing every message, and could have
downloaded a model from the internet on its own. It now says the model is not
configured, and points at the setting — the same guidance an empty chat shows. -
The app no longer keeps running after the part that answers has stopped. If
that part failed, the interface stayed up, accepted messages and answered none of
them, for as long as you kept trying. It now closes with one line saying so and
where the log is; what was written before the failure is saved. -
A startup error no longer disappears with its own window. Double-clicked from
Explorer, mindfork gets a console that Windows closes the instant the program
exits — so "another copy is already running", a broken settings file or a data
folder that cannot be opened flashed by unread. In that window the program now
waits for Enter. Started from a terminal, nothing changes. -
On a clean Windows the app now starts. The binary needed
VCRUNTIME140.dll, part of
the Visual C++ redistributable — a library Windows does not include and the installer
did not bring — so on a machine that had never installed a C++ application it failed
with a missing-DLL dialog before showing anything. The runtime is now built into the
binary, which costs it 365 KB. -
Starting mindfork without a terminal no longer hangs. With its output redirected
to a file or a pipe, or with no console, the app filled that output with screen codes
and waited for keys forever. It now says it needs a terminal and exits with code 2,
creating nothing;mindfork demothe same. -
A failed chat search no longer writes what you searched for into the log, which
the privacy policy says never holds message text. -
A chart from
python_execis no longer described to the model as shown when it was
not. On a model that cannot see images — a local server without its projector, or a
text-only model behind a gateway — the chart's line in the result said it was shown
while a note below said it was not. The line now says it was not shown and why; on a
model that sees, it reads as before. -
A chat with images keeps working after a switch to a model that cannot see them.
An image stays in the chat's history and was sent again on every turn, so once the
model changed to one without vision — a local server started without its projector,
or a text-only model behind a gateway — every message in that chat failed with
"image input is not supported" or "No endpoints found that support image input". The
images now go as a note telling the model it cannot see them, so it says so instead
of guessing, and the chat mentions once that they were not sent. They are still in
the chat and reach the model again after switching back to one that sees. -
A text-only model behind a gateway no longer breaks a chat with an image. In
externalmode against a service that publishes a catalogue (OpenRouter and the
like), an image sent to a model that cannot see one was refused with "No endpoints
found that support image input" — and, since the image stays in the chat's history,
so was every later message in that chat. That includes a chart frompython_exec,
with nothing attached by hand. The app now reads from the catalogue whether the model
takes images:/image attachrefuses up front and says to pick a vision model, and a
tool's picture is kept back with a note telling the model it has not seen it. For a
model that does take images, attaching one no longer warns that the engine cannot say. -
A reply the provider's content filter stopped now says so. OpenAI, Anthropic,
Gemini, OpenRouter and other OpenAI-compatible servers each report when their
moderation cut a reply short, and the app showed the fragment as a finished answer
— or, with OpenAI, as a reply that hit the length limit, suggesting/continue,
which only meets the same filter again. The fragment is kept with a note saying
why it ends there; impersonation says the same under the draft, and a subagent
tells the assistant that delegated to it. Gemini's English "did not produce a
response" line no longer lands inside the reply itself. -
The thinking switch works through a gateway. In
externalmode against a
service that publishes a c...
mindfork-rs v0.9.9
Added
-
A memory limit for the local Python interpreter — in Settings, the Python group in local mode now has a per-process memory limit (Windows only). A script that tries to take more gets a
MemoryErrorinstead of the machine's memory, and so does any process it starts. Off by default, and separate from the sandbox's limit, since the sandbox needs about a gigabyte just to start. -
The local-interpreter mode exchanges files too. Running Python on your own machine
instead of in the sandbox used to mean the assistant's code could neither read this
chat's files nor save anything for you. It now works exactly as the sandbox does: the
call names the files it needs, each is copied in before the code runs, and what the code
saves comes back into the chat's files and into/file list. Nothing else changes about
the mode — it is still your machine, with your permissions and your network. -
Opening a chat's file in the system:
/file open <name|#N>opens one of the files
/file listshows — an attachment, a file the assistant saved, an image of the
conversation — in whatever application the system uses for it, and/file folderopens
the chat's files folder. Only document types (images, pdf, csv, txt, md, json, xlsx,
docx) open directly; anything else — a script, a shortcut, an HTML page the assistant
wrote — opens the folder it sits in instead, so nothing the assistant produced can run
by being opened. The path is always printed, so a file the system will not open is a
copy-paste away. -
Files into the Python sandbox. The assistant's code can now read this
chat's files: it names them in the call, by the number/file listshows or by
name, and each is copied into the sandbox before the code runs. Attachments go
in as their text, stored files and pictures as themselves. The copies are the
sandbox's own — changing one changes nothing here, and only what the code saves
to/w/outcomes back — so a chart or a table one call made is readable by the
next./file attachnow also keeps the file itself: a workbook, a zip or
any other binary is no longer refused (it is kept with the chat, and only code
can read it), and a PDF, DOCX or web page keeps its original beside the text
the assistant reads; the two are one entry in/file list, and removing it
removes both — never your own file./file listalso shows the chat's
pictures, with the same numbers the assistant uses. When Confirm dangerous
tool calls is on, the confirmation now states which files would go into the
sandbox, their sizes and whether it has network access. -
Files out of the Python sandbox. What the code saves directly into
/w/out— a matplotlib chart, a CSV, a workbook — is kept with the chat, in
data/files/<chat-id>/, and the call's card shows the folder and every file. A
PNG or JPEG is also shown to the model, so it can check the chart it drew;
Show charts to the model under Settings → Tools → Python turns that off. Up to
10 files and 50 MB a call; a file of a name already saved gets a numbered copy
rather than overwriting the first./file listshows stored files after the
attachments,/file removedeletes them, and backups include them. -
More packages in the Python sandbox.
mindfork sandbox setupnow also
installs sympy (symbolic maths), networkx (graphs), lxml, pyyaml, regex,
feedparser, openpyxl and pypdf (reading Excel and PDF files), tabulate
(Markdown tables from pandas), pillow and matplotlib — about 28 MB more to
download. An existing sandbox gets them by runningmindfork sandbox setup
again, which fetches only what is missing. matplotlib is installed and draws
correctly. -
mindfork llama remove <id>deletes a downloaded engine build from
data/llama/— by the namemindfork llama installedprints, or by a
bare backend name while only one build of it is installed. If the
settings point at that build the command refuses and says which fields
do, so it cannot quietly leave them aiming at nothing;--forcedeletes
anyway. It then reports how much was freed and what an empty
llama-server binary field resolves to now. There is deliberately no
--alland no automatic prune. -
The engine binary is found, not just typed. The llama-server binary
field may now be left empty: the app takes the buildmindfork llama setupinstalled last, or allama-serversitting next to the
application — so downloading one, or unpacking a llama.cpp archive beside
mindfork, is enough to run in managed mode with nothing to type. A bare
name likellama-serveris looked for beside the application and then in
PATH; a path you actually typed is used exactly as written. The same
applies to the impersonation server and the embedder, which run the same
binary. -
The engine, downloaded.
mindfork llama backendslists the
llama.cppllama-serverbuilds published for your OS and architecture —
cpu,vulkan,cuda-13.3,rocm-10.0, … — with their download sizes,
andmindfork llama setup --backend <id>fetches one into
data/llama/<backend>-<tag>/. 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).
When it is unpacked the command runs the binary and reports the build
number and the compute devices it found, so a GPU backend with a missing
driver says so instead of pretending.--build <tag>pins a build,
mindfork llama installedshows what is on disk, and several builds can
live side by side. The list of backends is read out of the release, so
one that upstream adds or renames appears without an app update.
--set-binaryputs the path into the settings for you once the install
succeeds — the assistant's engine always, the impersonation engine and
the embedding server only if they had no path of their own; the engine
mode is never switched behind your back. -
A note when the server processes prompts slowly. A local
llama-serverlooks at its queue only between batches of prompt tokens,
so a background request stopped or displaced during its prompt holds its
slot for a whole batch — tens of seconds on a CPU. The app now reads the
server's own timing of every prompt — the history compression's
request, the background reflection and consolidation runs, a page
summary a tool asked for, the automatic title and, on the shared
engine, impersonation (whose prompt is the whole conversation, processed
afresh) included,
the prompts a server that kept its cache still processes whole — and, once per server session, says in the feed how
fast prompts are processed, how long such a hold would be, and the one
change to make: the Batch (-b) setting for a managed
server,-b 256 -ub 256on the launch line for an external one. Nothing
is said on a GPU host, on the clouds, or where the batch is already
small. -
A limit on how long quitting waits for background work. Tools →
Quit: wait for background work (s): empty — wait until every task has
landed (each has its own run time limit); a number — at most that many
seconds;0— leave at once. -
/tasks stop <kind>. The typed route to stopping one of the app's own
background tasks —reflection,notes,selforcompact— for a
terminal whereF6on the tasks screen never arrives. Bare/tasks stop
stops the only task running; with several running it lists them, with none
it says so;/tasks stop allstops every one running./taskson its own
still opens the screen. -
A batch setting for the managed server. Performance → Batch (-b):
how many prompt tokensllama-serverprocesses per pass. Empty means
auto — 256 when GPU layers is 0, the server's default otherwise; a
number is passed as is. Changing it restarts the server. -
Stop the app's own background task. On the tasks screen (
F7)F6
now also stops one of the app's own tasks — a reflection, a consolidation,
a history compaction — when its row says running or waiting, not only
a background run. The task lands as cancelled: nothing it already wrote is
undone, it is not counted as a failure, and the next scheduled one runs as
usual; a/compactyou asked for answers with a short notice. -
A tasks screen.
F7(or/tasks) shows everything the app is doing
in the background on one screen: every sub-agent and dialogue run across
all your chats — the ones running, with the round and tool they are in and
how long they have been out, then the ones that landed, with how they
ended — and the app's own quiet work (reflection, consolidation, history
compaction) as running or idle.Enteropens a run's transcript,Pits
chat,F6stops a running background run, andEscfrom a chat opened
there brings you back to the list. -
Dialogues in the background. The same switch that offers background
sub-agents now also offersstart_dialogue: the assistant stages a
directed scene between two personas, gets itschat://address at once,
and keeps talking to you while the scene plays out — its closing result
arrives later as a task notification, exactly as a background sub-agent's
does. The transcript is a row of the chat list while it runs and streams
line by line if you open it,F6there stops it (as does
/subagents stop [n]), and the cap counts scenes and sub-agents together.
The director reads the conversation as it was when you asked for the
scene. The setting is now called "Background runs (subagent/dialogue)". -
Sub-agents in the background. Switch on "Subagent: background runs"
in Settings → Tools and the assistant gainsstart_subagent: a
delegation that returns at once — the assistant keeps answ...
mindfork-rs v0.9.8
Added
-
The build date on the "About" tab.
F1→ "About" now shows, right under
the version, the day the copy you are running was built (2026-08-27, UTC) —
so a bug report can name a build the version number alone cannot tell apart.
The row appears in released builds; a build you made yourself from source in
development mode does not show it, because the date there could be older than
the code and a wrong date is worse than none. -
Web search can use a provider with an API key. 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 — which is
why a long chain of searches used to fall apart. Settings → Tools → Web search
now takes an API key for Tavily — 1000 searches a month, no card needed.
Enter one and the assistant searches through Tavily first; the free engines
stay as the fallback, so nothing changes if you enter no key at all. You can
also point the app at an environment variable instead (TAVILY_API_KEY), or
turn the key off for search entirely. Search results now say which service
answered. -
Sub-agent transcripts fold under their chat. The chat list now keeps a
chat's transcript rows collapsed by default, with a muted▸ nbeside the
count saying how many it holds;Ctrl+Oin the list unfolds/refolds the
selected chat's (on a transcript row — its parent's), and/subagentstyped
in the chat does the same for the open conversation (bare — a toggle;
expand/collapseset it outright). The choice is remembered per chat, and
a search still surfaces a matching transcript under its collapsed chat. -
The sub-agent has the assistant's tools.
call_subagentno longer asks
one tool-less question: the sub-agent runs as a nested turn with the same
tools the assistant has in this chat (except creating sub-agents, reading
the folded history and the self-model), over the same attached files and
project, under the persona the assistant composes — with an optionalname
for it. A dangerous call inside the run asks you exactly as outside. Its
whole transcript is kept on the call inside this chat (the list, a read-only
view and search follow in the next stages), and the assistant gets the
sub-agent's final reply plus the transcript'schat://address. -
Sub-agent transcripts in the chat list. Each delegation shows as a row
nested under the chat that made it (└), in call order, with a mark when the
run did not complete. It opens like a chat — the sub-agent's persona on top as
a system message, the instruction headed by your assistant's name, the replies
by the sub-agent's — but read-only: sending and anything that would change a
conversation refuse and point you to the parent chat; renaming (F2,
/rename,Ctrl+Rfor a model-written title), copying, exporting, searching
and speaking work.DelandCtrl+Drefuse on a transcript — it goes away
with the exchange that made it (Ctrl+E/Ctrl+Rin the parent) or with the
parent. Thechat://address a sub-agent's result carries is now a link. -
Sub-agent transcripts are searchable. The chat list's content search
(Ctrl+F) finds text said inside a delegation and shows the transcript's
row under its chat;Enteron that row opens the transcript on its first
match. The message-level results (Ctrl+G) group a transcript's hits
under its chat's header with a└, andEnteropens the transcript on the
message. With the optionalchat_search/chat_readtools on, the
assistant can search and read sub-agent transcripts of this profile's
conversations too — including this chat's own — each labelled as the
transcript of its conversation and reachable by itschat://address. -
You can see a sub-agent working. While the assistant waits on a
delegation the status bar shows a quiet chip — the sub-agent's name, the
round it is on and the tool it is using — instead of a bare "generating"
for minutes. -
Coming back to a chat mid-reply shows the reply so far. Step into a
running sub-agent's transcript and back, and the chat shows everything the
assistant has written in the current round — text, thoughts, the tool calls
it opened — and keeps streaming into it, instead of catching up only when
the reply lands. -
A sub-agent's transcript streams while you watch. Open a running
delegation and the sub-agent's reply arrives word by word, its thoughts and
tool calls included, with its own token counter — and opening it mid-reply
shows what it has written so far rather than starting from the next round. -
A tool call shows up the moment it starts. The card for a tool call
appears in the reply as soon as the assistant makes the call, marked
running… where the result will go, and fills in when the result arrives —
so a long call (a sub-agent run, a project build, a Python script) is
visible where it happens rather than only as a status-bar chip. -
A sub-agent's transcript is there while it runs. The moment the
assistant delegates, the transcript appears in the chat list under the chat,
marked running, its message count growing round by round. Open it to read
what the sub-agent has done so far — it grows as you watch — and go back to
the chat: moving between the two no longer cancels the turn (any other chat
switch still does). Renaming it while it runs keeps your title. -
Sub-agent transcripts name themselves. With automatic titling on
(either setting), a finished delegation gets a model-written title the
moment it lands, like a new chat does; a title you gave it by hand is
kept. The demo (mindfork demo) now includes one such transcript. -
The licence and the disclaimer in Russian — with the interface language
set to Russian, theF1→ "Licence"/"Disclaimer" tabs and the Windows
installer's two legal pages show a Russian text instead of an English one.
The translations are unofficial and say so in their first paragraph: the
English originals are the texts that have legal force. Both travel with the
product, next to the originals, in the archives, the Linux packages and the
installed folder. -
See what the assistant changed in your project, and undo it —
F4(or
/changes) opens a screen listing every file it touched, with the changes
shown as a diff against the file as it was before it was first touched.
rputs one file back the way it was, after asking; a file the assistant
created is removed instead. Files it could not diff — binary, very large, or
deleted since — say so rather than showing nothing. -
The assistant can build, run and test the attached project — through
command lines you type:/project build-cmd cargo build, and the same for
run-cmdandtest-cmd(/project clear build|run|testremoves one, and
/project statusshows all three). It runs them exactly as written and can
never change one, add a flag to it or compose a command of its own; 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
by then still comes back. Pipelines and redirects are not run — the refusal
says so when you set the line, and points at wrapping the steps in a script.
New settings under Tools → Workspace: the command time limit, how much output
reaches the model, and how many rounds one answer may spend inside the project. -
The assistant can change the attached project — it edits a file by
replacing an exact fragment, or writes a file whole. Every file's previous
content is saved before it is first touched, so a coming release can show the
changes and put them back; a change that cannot be saved that way is refused
rather than made. Turn on "confirm dangerous tool calls" in settings to approve
each change before it happens. Reading and editing the project no longer spend
the tool-call limit — a fix takes as many steps as it takes. -
A code project can be attached to a chat —
/project attach <directory>,
/project detach,/project status. With a project attached the assistant
can see its structure, read its files (with line numbers) and search them by
regular expression, all confined to that directory and honouring
.gitignore. Attaching is the whole permission: with no project attached
nothing changes about what the assistant can reach, and the tools are not
even offered to it. Editing, build/run/test commands and a changes screen
come in the following stages. -
The app says so when it starts without its database.
data.dbholds the
notes, the self-model, the knowledge base and the search index over files
attached to chats — and copying a data folder to another machine without it
used to be silent: the conversations were all there and the assistant
remembered nothing about them, with no explanation. Now a launch that finds
chats but nodata.dbwrites a warning to the log and opens with one note in
the feed saying what is empty, what survived (the conversations and the text
of their attachments) and how to get the rest back — put the file next to
chats/, or restore a backup. A first launch, having no chats either, stays
quiet as before. -
/autotitle— the model-written title as a typed command. The action
lived only behindCtrl+Rin the chat list, and in a browser tab that key
reloads the page. The command titles the open conversation; failures land as
a note in the chat when the list is not there to show them. -
The impersonation profiles are operable by commands.
/impersonation list · new [name] · delete <name> · use <name|default> · system [text|clear]— the user personasCtrl+Uwrites as, until now editable
only in settings behindCtrl+N/Ctrl+D, which a browser tab keeps for
itself. Deleting...
mindfork-rs v0.9.7
Added
-
The model's name can be shown in the feed. A new "Model name in the feed"
toggle in Settings → Interface prints the model that wrote each reply next to
the✦ ASSISTANTheader, in the same muted grey as the "thoughts" block. The
name comes from the message itself, so a conversation reopened after switching
providers still says which model actually answered — and a reply saved before
the app recorded that shows nothing. Off by default. -
New chats name themselves. After the first reply the model writes the
conversation a short title — no more lists full of "New chat". On by default;
a setting (Interface → Behavior) 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, andCtrl+Rin the chat list still asks for a fresh title
whenever you want one. -
An external server's API key can be entered in settings. Connecting to a
server that requires authorization — a gateway such as LiteLLM or OpenRouter, or
allama-serverstarted with--api-key— no longer means setting an
environment variable first: theexternalmode now has the same "API key"
field the cloud modes have, stored encrypted and bound to this computer, never
shown back. It is optional (a local server needs none, and then nothing is
sent), the "API key (env)" field stays as the fallback for CI and scripts, and
eachexternaltab — Assistant, Impersonation, Embeddings, Speech — keeps its
own key, because those are four independent servers. -
/exportsaves a conversation to a file./exportwrites it next to
wherever you started the app, naming the file after the chat and the date;
/export path/to/name.mdputs it where you say. Two formats: md — exactly
whatF5copies — and json, whichmindfork-rs importcan read back onto
the same chat (it carries no tool calls, and the app says so when you use it).
An existing file is never overwritten. This is also the way out of a browser
terminal such as JupyterLab's, where the clipboard cannot reach your machine
at all. -
Copying works over SSH. The clipboard the app writes belongs to the
machine it runs on, so over SSH a copy went to the server — and on a headless
server, where there is no clipboard at all, it simply failed. A copy is now
also handed to the clipboard of the machine your terminal runs on (OSC 52),
automatically when the session looks remote; the new "Clipboard over the
terminal" setting under "Interface" makes thatalwaysoroff. Terminals do
not confirm receiving it, so the app says the text was sent rather than
promising it arrived, and a conversation too large for the sequence (~75 KB)
is reported instead of being quietly cut in half. Not every terminal supports
it — GNOME Terminal, Terminal.app and JupyterLab's terminal do not. -
Every action now has a typed command, not just a key. In a terminal
embedded in something else — VS Code's integrated terminal, a JupyterLab
terminal in a browser tab — the host takes many key combinations for itself
before the app ever sees them, and some of the app's features were simply
unreachable there. Nineteen new commands cover the rest of the interface the
way/exitalready covered quitting:/settings,/self,/chats,
/help,/new [profile],/rename [title],/clone,/copy,/regen
(/retry),/takeback,/impersonate [text],/stop,/find [text],
/search <text>,/links,/thoughts,/toolcalls,/mouseand/emoji.
Each does exactly what its key does, confirmation prompts included — and,
unlike a key, a command that cannot run right now says why and tells you what
will work./searchalso goes straight to the message search that used to
take three keys to reach. The keys are unchanged.The two actions that lived inside other screens followed:
/profile list,
/profile new [name]and/profile delete <name>(the settings
screen'sCtrl+N/Ctrl+D), and/self clear(Ctrl+Ktwice in the
self-model screen). Both destructive ones always ask first — a command names
its target by word, and a shortened name could match a profile you did not
have in mind — and creating or deleting a profile now leaves a note saying
what happened, whichever route you took. -
Links to conversations. When the assistant mentions another of your
conversations it now writes its address aschat://<id>, and the feed draws
that as a link.Ctrl+Llists the conversations the open chat links to
and opens the one you pick — and with mouse capture on (Ctrl+W) you can
simply click a link, the first thing in the feed that is clickable at all.
Esctakes you back to the conversation you came from, the way it already
does after opening a search hit — the status bar says where it currently goes.
The way back lasts as long as you are reading: start working in the chat you
arrived at (send, regenerate, take back an exchange,/compact, attach a
file) andEscgoes back to meaning "the chat list", so it can never
teleport you out of a conversation you have settled into. The same now applies
after opening a search hit. Only addresses that really lead somewhere — a
conversation of the current companion — are drawn as links, so a link is
never a dead end; the rest stays ordinary text. (Requires the cross-chat
tools below to be enabled — they are what hands the assistant the addresses.) -
The assistant can search your other chats — if you let it. Two new
tools,chat_searchandchat_read, let the model find and read what other
conversations of the same profile said (message text only), for questions
like "we discussed this in another chat". Both are off by default and
not even shown to the model until you enable them per profile in settings →
Tools; the current conversation, hidden chats and other profiles stay out
of reach. -
/exitand/quitleave the app. Until now the only ways out wereCtrl+Q
andF10, and some terminals keep both keys for themselves — VS Code's
integrated terminal bindsCtrl+Qto the editor andF10to the debugger, which
left no advertised way out at all. A typed command reaches the app whatever the
host binds. Either spelling works, both quit mid-answer just like the keys, and
the commands are listed inF1→ "Commands".
Changed
- The
F1help window looks after its own layout. The window now grows with
the terminal (between its old 76×34 and a readable cap of 96×44) instead of
always taking the small fixed size; in the "Hotkeys" and "Commands" tabs every
description starts in the same column, wrapped lines hang under that column,
and related entries sit in small groups with a breathing line between them.
The "Components" tab lays its tables out like a table of contents — name on
the left, version and license aligned to the right edge, a faint dotted
leader between — instead of leaving the right half of the window empty.
Fixed
- The
F1help no longer cuts its descriptions off. In the "Hotkeys" and
"Commands" tabs a line too long for the window simply lost its tail mid-word —
/image pasteended at "works in every termin". Long descriptions now wrap onto
the next line, indented under the text they continue.
mindfork-rs v0.9.6
Added
-
The Windows installer now shows the license and the disclaimer. The wizard
opens with the MIT license (accept it to continue) and then the disclaimer —
what the models may say and do, what the tools may do on your machine, and what
leaves it for a cloud provider. It is the same text as the app'sF1→
"Disclaimer" tab and theDISCLAIMER.mdinstalled next to the program; both
texts stay in English in the Russian wizard. -
The assistant can no longer be talked into fetching your local network.
fetch_urland the pagesweb_searchreads now refuse addresses that are not
on the public internet — your own machine, your LAN, and the address cloud
providers keep their credentials behind. It matters because the links the
assistant follows usually come from a page it just read, and such a page can
ask it to open something on your side of the router. If you do want one
reachable — a wiki or a dashboard on your network — there is a new switch in
settings → Tools: Allow local addresses, off by default. Attaching an image
by address (/image attach <url>), which you type yourself, is unaffected, and
so is the engine address in settings. -
You can show the model a picture.
/image attach <path>puts an image on
your next message,/image pastetakes one straight off the clipboard (so a
screenshot needs no file at all —Ctrl+Vdoes it too, in terminals that let
the key through; Windows Terminal keeps it for its own paste, which is why the
command exists),/image listshows what is waiting, and
/image remove <name|#N>takes one back off. It works with a local
vision-capable model (startllama-serverwith a projector — the new
"Vision projector (--mmproj)" setting, orMINDFORK_MMPROJ) and with all
four cloud providers — OpenAI, Claude, Gemini and Grok. png, jpeg, webp, gif
and bmp are accepted and converted to what the providers take; a large image is
shrunk once, when you attach it, so it does not cost you upload and tokens on
every later turn. The status bar shows what is staged and roughly what it will
cost. If the engine says it cannot see images, the attach is refused up front
and tells you what to change instead of failing later. -
An image can be attached by its web address.
/image attach https://…
downloads the picture and stages it for your next message, the same as a file —
useful when the image is in a browser rather than on disk. The image itself is
stored in the conversation, so it keeps working later even if the link stops
working, and it reaches every provider, including the ones that accept no
remote addresses. An address that serves a page rather than a picture says so,
and names what to attach instead. -
A tool's screenshot now reaches the model. When an MCP server's tool
returns an image, it is shown to the model instead of the old
"[image content omitted]" note — so a screenshot or a chart a plugin produces
can actually be looked at. The tool block in the feed says how many images came
back. At most four per result (the rest are counted out loud, not dropped
quietly), and each is shrunk to the same limits your own attachments get. New
switch in settings → "Plugins": Let servers send images, on by default —
turn it off if you would rather no third-party picture reached the model, since
instructions can be painted into pixels where you would not see them. -
A blip on a cloud provider no longer costs you the turn. When a provider
rate-limits or sheds load (429,5xx, Claude's "overloaded"), the request
is retried automatically — three attempts, waiting about a second and then
two, honouring the provider's ownRetry-Afterwhen it sends one. The status
bar says which attempt is running and how long the wait is, andEsccuts it
short. This matters most in a long turn: one blip on the eighth tool round
used to throw away the whole turn's work. Retries stop as soon as the answer
starts arriving, so nothing you have already read is ever re-generated and no
tool runs twice; a provider asking for more than 30 seconds is reported
instead of hidden behind a spinner. Applies to the cloud providers and to
"external" servers (a proxy or gateway); a locally managedllama-serveris
still recovered by the existing health monitor. -
Demo mode — try the app without a model.
mindfork demoboots the real
TUI on sample data with a scripted engine: a showcase conversation (a table,
a flowchart drawn in the terminal, a tool call), a filled chat list, a
living self-model onF3, and streamed canned replies that say plainly what
they are. No server, no API key; nothing outside a temporary folder is
touched, and the folder is removed on exit. The feed header honestly labels
the enginedemo (mock engine); a real engine connects any time in settings
(Ctrl+P).
Fixed
- A reply that gets cut off now says so. When the engine failed after the
answer had started arriving — an overloaded cloud provider, a dropped
connection — generation simply stopped: the half-written reply stayed on
screen with nothing indicating it was a fragment, and on Claude such a
truncation was indistinguishable from a finished answer. Every provider's
mid-answer failure is now reported in the feed, with what the provider said
and a pointer toCtrl+R; what did arrive is still kept. Escinterrupts a request that is still connecting. The engine clients
had no connect timeout and ignored cancellation until the first bytes of the
reply arrived, so a wrong port or a silently dropping firewall left the chat
generating forever with no way back.- A network failure now shows the reason. "Connection refused" and friends
were replaced by the bare request URL before reaching the screen.
mindfork-rs v0.9.5
Added
-
Grok (xAI) as a model provider. Alongside a local model, OpenAI, Gemini and
Claude, you can now point mindfork at xAI's Grok models: settings (Ctrl+P) →
"Model/server" → "Mode" →grok, then a model name (grok-4.5,grok-4.3,
grok-4.20…) and an API key from console.x.ai. The key
is entered in settings and stored encrypted for this computer, exactly like the
other providers', and one key serves chat, impersonation and embeddings.
Reasoning ("thoughts") and tool calling work as with the other clouds; the
sampling section shows only the parameters xAI actually honours (temperature,
top-p, seed, token limit and the reasoning depth) instead of ones it would
reject or ignore. Note that xAI, like Anthropic, offers no embedding models —
under agrokengine the knowledge base needs an embedder from somewhere else
(a local server, OpenAI or Gemini) in the same section's "Embeddings" tab. -
A disclaimer about what the models can say and do — a new
DISCLAIMER.md,
readable in the app on theF1→ "Disclaimer" tab and shipped in the archives,
packages and installer next to the license. The app carries no model of its own:
every word on screen is written by a model you chose and downloaded, it may be
wrong or harmful, and nothing here filters or moderates it. The notice spells out
what that means for warranty and liability, for the tools a model can run on your
machine, and for what leaves it when you use a cloud provider. The MIT license
itself is unchanged — the disclaimer supplements it and takes nothing away.
The Russian label of theF1hotkeys tab was shortened to make room for the
new tab. -
History compression (
/compact). A long conversation eventually stops fitting
the model's context window — the engine then refuses the request outright. The
older part of a chat can now be folded into a rolling summary that is sent in
place of those messages. Nothing is deleted: the feed, search and export still
show the whole conversation; only what the request carries changes, and the feed
marks the boundary with a divider you can unfold (together with the "thoughts"
blocks,Ctrl+T) to read the summary. On by default where it can act, and fully
switchable off in settings → "Memory" → "Context" — off, the whole history is sent
exactly as before. It also happens by itself: once a conversation reaches a
share of the model's context window (75% by default, adjustable there), the older
part is folded in the background while you keep typing. The window is worked out
on its own — from a managed server's own setting, or by asking a llama.cpp server
— and you can state it yourself for a model that cannot be asked. And if the
window fills up anyway, the error now says what to do about it instead of showing
the server's raw reply. Finally, a summary is no longer the end of the story:
what it had to leave out is still reachable, because the assistant can read the
folded part back page by page and search it by words — so asking about a detail
from the beginning of a long conversation gets an answer from the actual messages
rather than a guess. The search needs no embedding server, and the page size is in
the same settings group. Writing a message as the user (Ctrl+U) sends the
same folded conversation, so it no longer runs into the ceiling the rest of the
chat is already protected from. -
The Windows installer can set up the Python sandbox for you. A new
Install the Python sandbox and enable Python execution checkbox on the
"Additional tasks" page (off by default) installs it during the installation and
switches thepython_exectool on, instead of leaving you to run
mindfork-rs sandbox setupand find the setting yourself. It downloads about
300 MB and takes a few minutes, with the progress visible in a console window;
if it fails, the installation still succeeds and the tool stays off — it is
never enabled without a working sandbox. The Linux packages don't offer this —
they install as root, while the sandbox belongs to your user account, so run the
command yourself after installing. -
mindfork-rs sandbox setup --enable-pythondoes the same from the command
line: install the sandbox, then turn Python execution on — but only if the
install succeeded. Without the flag the setting is left untouched. -
Tool calls in the feed fold away, like "thoughts".
Ctrl+Ocollapses and
expands them; collapsed, a call keeps its header — the tool's name and a short
argument — so you still see what ran, while the arguments and the result move
out of the way. Collapsed is the new default, so a turn full of tool work
reads as the reply it produced. The collapsed/expanded choice for both kinds of
block (Ctrl+T— "thoughts",Ctrl+O— tool calls) is now remembered for
each chat separately and survives a restart: one conversation can be read with
everything open while another stays compact. Expanded, the call is laid out
properly: the tool's name on the header line, every argument listed under it
one per line, a gap, then the result. The header line has always been a
summary — it cuts a long value at a hundred characters and cannot show a list
or a nested value at all — so a request could not be read in full anywhere. -
MCP servers are configured in the settings window. A new "Plugins"
section holds the master switch, the server list and its editor:Ctrl+Nadds
a server, the fields below set its command line and environment,Ctrl+D
deletes it — no more hand-editingsettings.json(which still works and is the
same data). A server added here starts switched off, so nothing is launched
while you are still typing its command, and an identifier that would make the
server invisible is refused as you enter it. -
An MCP server's token can be entered in the app. List the variables the
server needs by name (GITHUB_TOKEN, SLACK_TOKEN) and a row appears for each:
pressEnterand type the value into a masked field,Deldeletes it. The
value is encrypted with a key belonging to this computer and never appears in the settings file — the
same storage the cloud API keys and the backup password use, so copying the
configuration elsewhere is still safe (on another computer you enter the value
again). Scripted setups are unaffected: the server inherits the application's
own environment, so a variable you already set in the system reaches it
without being listed at all. Previously a hosted server (GitHub, Slack, …)
meant setting a system variable and restarting the application. -
A configuration from another MCP client can be imported. "Import from a
file" in the "Plugins" section takes the path of amcpServersJSON —
Claude Desktop'sclaude_desktop_config.jsonand the clients that share its
shape. Imported servers arrive switched off so nothing starts unreviewed,
their tokens are stored encrypted for this computer rather than written to the
settings file, a server whose name is already taken is skipped (so importing
twice changes nothing), and entries this application cannot run — the ones
that connect over the network rather than as a program — are reported instead
of quietly disappearing. -
One MCP server config now works on every platform. The launch command is
resolved the way a shell resolves it, so"command": "npx"no longer has to be
written ascmd /c npx …on Windows — configs can be copied between machines
and between operating systems as they are. Existingcmd /c …configs keep
working. -
A stuck MCP server can be reconnected from settings.
Enteron a server's
row confirms a changed tool catalog as before — and, when there is nothing to
confirm, restarts the server. Previously a server that had crashed too often
could only be brought back by restarting the application. -
The assistant can watch a YouTube video — the new
youtube_watchtool
tells what is said and shown in it, with timestamps, andfocusnarrows
that to your question. It needs a Gemini API key, but not a Gemini chat:
the tool calls Gemini itself, so this works with a local model or with Claude
just the same (Gemini is currently the only provider that accepts video at
all). Long videos are refused with a suggestion to ask for a segment —
watching is billed per second of footage — and the ceiling, the model and the
frame-sampling detail live in settings → "Tools" → "Video". Without a key the
tool still returns the title, channel, length and the author's description,
and says plainly that it could not watch. Only public videos. -
A YouTube link is no longer a dead end for
fetch_url. It used to answer
"failed to extract readable text" (a watch page carries none); now it returns
the same free metadata and points atyoutube_watch. -
youtube_watchcan bring back the words, not just a description. Pass
transcript: trueand the assistant also gets a transcript of the speech with
timestamps. If it is short, it comes straight back in the answer; if it is
large, it is attached to the chat (it shows up in/file list, and the
assistant reads it page by page or searches it by meaning) instead of filling
the conversation. The transcript costs exactly as much as watching — it is the
same request — so it is not requested by default. Timestamps are always counted
from the start of the video, even when you asked for a segment. -
Backups can be password-protected. Give a password with
mindfork backup --password …, or set it once in settings → "Data" → "Backup
password" and every copy is encrypted with it — including the ones the app
makes by itself before a restore or a data-format update. The archive uses
standard AES-256, so 7-Zip or WinZip still open it with the password if yo...
mindfork-rs v0.9.4
Added
-
beautifulsoup4 in the Python sandbox —
mindfork-rs sandbox setupnow also
installs BeautifulSoup (withsoupsievefor CSS selectors), so sandboxed code
can parse HTML — a natural companion to the already-availablerequests. An
existing sandbox picks it up by re-running the same command; everything already
installed is skipped. -
Custom names for the user and the assistant — two new fields in the
settings "Profiles" section ("Persona" group). When set, the name replaces the
role headers in the chat feed (in caps:GAIAinstead ofYOU) and the labels
when copying the conversation withF5(Gaia:instead ofUser:). Both are
empty by default, which keeps the usual labels in the interface language; the
names apply to the profile's existing chats immediately, so they can be changed
at any time. -
Impersonation profiles — the user personas the model writes a message as
(Ctrl+U) are now a list of their own, each with its own name and system
message, instead of a single text field buried on the assistant profile. The
"Impersonation" subsection of the settings "Profiles" section now edits exactly
that list (Ctrl+N— create,Ctrl+D— delete), and an assistant profile picks
which persona its chats use via the new "Impersonation profile" field. Several
assistant profiles can share one persona; not choosing one keeps the previous
behaviour (a shared default text).
Changed
- The project site
mindfork.iois now carried by the package metadata as
well: the Windows installer shows it as the publisher link in "Apps &
features" (support and updates there now point at GitHub issues and releases
respectively), and the Linux packages use it forHomepage:/URL:. Every
GitHub Release page also gains a footer linking the site and the install guide
as of that release. The site itself is not up yet — the repository stays the
live destination for issues and downloads.
Fixed
- A newly created profile is now selectable right away.
Ctrl+Nin the
settings "Profiles" section created the profile, but the settings screen never
learned about it — it couldn't be selected or edited until the app was
restarted. The new profile is now delivered to the screen and selected
automatically; deleting a profile likewise refreshes the list immediately. - Ctrl shortcuts now work under any keyboard layout on Windows — previously
only the standard Russian one was handled (via a built-in table), so under a
Greek, Hebrew, Georgian, Bulgarian, Armenian, … layoutCtrl+Q,Ctrl+Pand
the rest simply did nothing. The physical key is now resolved through the
layout itself, which also covers the Russian letters sitting on punctuation
keys (which the table never had) and non-standard variants such as Russian
Typewriter. On Linux, Cyrillic works as before, plus whatever the terminal
itself handles (the GNOME Terminal family copes with every layout on its own).
Data
- Role names (
Profile.character_names) used to be seeded with placeholder values
that nothing ever displayed. Now that they are shown, those seeds are cleared once
at startup, so the feed and theF5export keep using the interface language's
labels; a name you chose yourself is left alone. New profiles start with the fields
empty. No schema-version bump. - The legacy impersonation system message stored on an assistant profile
(Profile.impersonation_system_message) is migrated once at startup into a named
impersonation profile ("«profile name» (impersonation)") and linked back. The
migration is idempotent and the old field is left on disk untouched, so nothing is
lost and a downgrade still finds its data. No schema-version bump (the new fields
are additive).