Skip to content

Releases: DevMando/MandoCode

v0.12.0 — Long sessions that don't freeze

16 Jun 05:59
1449cc7

Choose a tag to compare

v0.12.0 — Long sessions that don't freeze

This release is all about reliability on long, real-world tasks. While building actual projects with MandoCode, I found several ways a long session could freeze, scramble its own output, or spin in circles instead of finishing — and I fixed every one. The hardest freezes were tracked down by inspecting the stuck app directly, so these address the real causes, not just the symptoms.

Fixed:

  • No more freezing when you approve a change. Deep in a multi-step task — right as MandoCode started creating files and asking you to approve them — it could lock up with nothing on screen, leaving you no choice but to quit and lose your progress. The approval prompts could end up waiting forever for a keypress that never reached them; I rebuilt them so they always respond.

  • No more locking up while running a command. Some commands could make MandoCode hang on a single step and never come back. It was getting stuck while formatting the command for display — certain commands (long ones, or ones containing file paths) could send it into a loop that never finished. That can't happen now, and a safety cutoff stops anything that ever runs unusually long.

  • No more garbled or duplicated text. On longer replies, a second, scrambled copy of the text could end up drawn over the first. I changed how responses are written to the screen so they show once, cleanly, every time.

  • No more wasting a session on repeated searches. While researching, MandoCode could run the same web search over and over without realizing it already had the answer — burning time and tokens for nothing. It now recognizes a repeated search and moves on with what it already found.

  • No more stalling when previewing your work. Asked to "test it in the browser," MandoCode used to try to start a local web server it couldn't keep running, and would just sit there waiting. Now it simply gives you the exact command and link to open it yourself.

Every fix is covered by automated tests — the suite grew to 449 checks to keep these from coming back.

v0.11.0 — Agentic-loop trust + reliable web search

12 Jun 01:02
e7a948a

Choose a tag to compare

Agentic-loop hardening and prompt trust: every fix in this release closes a way a long session
could hang, thrash, silently lose its mind, or roll past the user's "stop" — each found by
dogfooding and verified live. Every interactive menu now speaks one visual language, arrow keys
are deterministic, and plan cancellation is enforced by the app instead of requested of the
model. Under the hood, the largest file in the codebase was decomposed and warnings are now
build errors — so this release also makes the next one safer to build. Web search also stops
depending on DuckDuckGo's goodwill: an optional free Tavily key makes it reliable.

Fixed

  • Models no longer recite their knowledge cutoff instead of using the web search they have — observed live on minimax-m3: asked for current weather, the model claimed "I don't have any tool to fetch live weather feeds" (false — search_web was registered), recommended the user try Google and weather.com, and asked permission to search instead of searching; the same setup on minimax-m2.7 searched fine. Two causes. First, the prompt's web guidance was a passive "use search_web when you need current information" buried at guideline #9 — no match for a trained cutoff-disclaimer reflex, and once a model disclaims live access once, self-consistency keeps it disclaiming for the rest of the conversation (the bad session opened with a from-memory-answerable question, which set the no-search precedent). Second, the static prompt advertised search even when EnableWebSearch was off. SystemPrompts.MandoCodeAssistant is now BuildMandoCodeAssistant(webSearchEnabled): enabled, an assertive LIVE WEB ACCESS section instructs search-FIRST for anything recent (no asking permission), forbids claiming a lack of internet access, and forbids punting the user to Google; disabled, the prompt stops advertising tools that aren't registered and points at /config set websearch true instead. AIService rebuilds the prompt on every settings path, and RefreshSettingsAsync swaps the in-history system message in place so toggling websearch mid-conversation actually reaches the model instead of waiting for the next /clear.

  • "Cancel the plan" now actually stops the work — immediately — cancelling at a diff approval previously only set a flag that the plan runner checked after the whole step finished. A step that wrote three files kept right on presenting file #2 and file #3 for approval after the user had already cancelled at file #1, because Semantic Kernel's auto-invoke loop was still executing the response's remaining tool calls — and the "stop all further work" message returned to the model is a polite request that models demonstrably ignore (the same lesson as the plan-prompt cancel fix below). New plan-cancellation circuit in FunctionInvocationFilter, first in priority above the budget and dedup circuits: once a scope is flagged cancelled, every subsequent tool call — writes, reads, commands — is refused mechanically, before any approval UI is reached. Cancellation went from a stop sign the model could roll through to a stop gate. Covered by regression tests reproducing the exact observed 3-file scenario, including that a fresh turn isn't poisoned by a previously cancelled scope.

  • Arrow keys at the plan-approval menu no longer get eaten ("press twice" lag) — two console readers were racing: Spectre's blocking SelectionPrompt and RazorConsole's framework keyboard pump (KeyboardEventManager polls Console.KeyAvailable every 50ms and reads unconditionally — no focus check, no pause API, and its IConsoleInput seam is internal so it can't be substituted). An arrow pressed while Spectre was mid-repaint sat in the buffer just long enough for the pump to steal it and drop it (no focused VDOM element exists mid-turn). The plan-approval prompt is now a VDOM component (ApprovalSelect) fed by the pump itself — one reader, no race, by construction. The remaining Spectre menus (step-failure prompt, the four DiffApprovalHandler approvals) carry the same latent race at lower traffic and migrate next using the same component.

  • Changing settings mid-task can no longer freeze the stall watchdog permanently/config set rebuilds the kernel; the rebuild detached event handlers from the old FunctionInvocationFilter even when a tool call was still in flight on it, so that call's completion never reached the pending-function tracker. The count stayed pinned > 0 and the stall watchdog — which only resumes at count 0 — stayed paused for the rest of the session (the same failure surface as the pending-count leak below, through a different door). BuildKernel now deliberately leaves the old filter's handlers attached: in-flight calls complete and decrement correctly, nothing fires twice (new calls route through the new kernel), and the old filter becomes collectible once its calls finish.

  • Step-failure "How would you like to proceed?" prompt no longer fires as a fake-async methodHandleProgressEventAsync was declared async with a fully synchronous body (CS1998); now an honest synchronous HandleProgressEvent. Surfaced by the new warnings-as-errors policy below.

  • Assorted hardening from a full-codebase reviewValidateModelAsync disposes its HTTP response; RequestTimeoutMinutes is clamped by ValidateAndClamp like every other numeric setting (a hand-edited "requestTimeoutMinutes": 999 previously loaded unclamped); FileSystemPlugin's grep/search loops only swallow file-access exceptions (IOException/UnauthorizedAccessException/NotSupportedException) instead of everything; MusicPlayerService teardown disposes each NAudio object in its own guarded step so one failing Dispose can't skip the rest.

  • Concurrent approval prompts can no longer deadlock the session — new ApprovalPromptGate (a SemaphoreSlim(1,1) async mutex) serializes every interactive approval surface: diff, delete, command, MCP, and plan approval. The kernel runs with AllowConcurrentInvocation = true, so a model response containing two approval-gated tool calls opened two blocking Spectre prompts at once — both looping on Console.ReadKey, stealing each other's keys. The visible prompt completed; the invisible one blocked its function forever, the turn never ended, and the input prompt never returned. This was the primary cause of the "agent suddenly stops and won't display the prompt" hang on long agentic loops. The plan-approval prompt holds the gate only around the prompt itself, never around execution — plan steps' own approvals take the same gate, so holding it across ExecutePlanAsync would deadlock the first step.

  • Pending-function-count leak permanently paused the stall watchdogFunctionInvocationFilter.OnFunctionInvocationAsync incremented the count and fired OnFunctionStarted ~250 lines before the try/finally that decremented it, with seven hand-rolled cleanup copies on the early-return paths. An exception anywhere in that window (UI event handler, approval callback) skipped the decrement; the filter is long-lived, so PendingFunctionCount stayed pinned > 0 for the rest of the session and the stall watchdog — which only resumes at count 0 — never resumed again. Any later genuine model stall then hung silently until the 15-minute request ceiling. Restructured: one try/finally owns the lifecycle (InvokeCoreAsync split), all seven manual copies deleted. The MCP approval gate also moved inside the lifecycle so the watchdog pauses while the user deliberates at an MCP prompt, like every other approval.

  • Approval awaits now observe cancellation — all five approval awaits (MCP, edit, write, delete, command) are wrapped in WaitAsync(context.CancellationToken). A wedged prompt previously blocked an await that observed no token, which defeated Esc, the stall watchdog, AND the request ceiling simultaneously — the turn could never unwind.

  • "Cancel request" at the plan-approval prompt actually cancels — it previously returned a "stop here" string to the model as a tool result, a polite request that a frontier cloud model was observed simply ignoring (it executed the cancelled plan's steps itself via direct tool calls). Now it cancels _requestCts — the same mechanical path as Esc — so the turn unwinds regardless of what the model thinks of the instruction.

  • One plan per turn, enforced mechanically — observed runaway: a model completed a 5-step plan, immediately started building an uninvited duplicate of the project, then proposed a third round of work. PlanHandoff's recursion guard only covers a plan that's still running. New InvocationScope.PlanAlreadyProcessed circuit: once a real plan (≥1 step) is handled — executed, rejected, or cancelled — any further propose_plan in the same turn is short-circuited with a stop directive. Malformed/empty proposals don't consume the slot, so a legitimate retry with corrected steps still works. The plan-completion summary returned to the model now also ends with an explicit wrap-up directive ("respond with a brief summary; do NOT create more files or propose another plan").

  • Plugin-level edit_file failures now count toward the N=3 edit-failure circuit — the circuit previously only counted preview-level failures. The preview validates old_text against a snapshot captured at interception; when an earlier edit in the same concurrent batch landed in between, the plugin's re-validation failed AFTER the preview passed — and those failures bypassed the circuit entirely. Observed live: 9+ consecutive "Could not find the specified text" misses on one path with no trip. UpdateScopeForCompletedCall now records error-result edit_file calls into the same counter.

  • Per-scope bookkeeping keys are normalized across path aliases — the model was observed addressing one file as both Games/index.html and src/MandoCode/bin/Debug/net8.0/Games/index.html (the plugin's `StripRedundantRoo...

Read more

v0.10.0 — File-read and cloud-signin reliability

28 Apr 02:25
7d0bcad

Choose a tag to compare

Three reliability fixes for the file-system plugin and the cloud sign-in flow, plus one cosmetic UI tweak.

Fixed

  • Nested same-name folder readsread_file_contents, write_file, and edit_file no longer mangle paths when
    a project's folder layout repeats the project root's last segment (e.g. the MyApp/MyApp/MyApp.csproj pattern from
    dotnet new). GetFullPath now resolves the literal path first and only falls back to StripRedundantRootPrefix
    when nothing exists at the un-stripped target. Previously the heuristic always stripped a matching trailing segment,
    so legitimate nested files appeared as "File not found" with the suggested "elsewhere" path identical to the requested
    one.
  • ollama signin not launching after fresh installRunOllamaSigninAsync, TryStartOllamaProcess, and
    AutoPullAsync now resolve ollama via the new ResolveOllamaExecutable() helper, which falls back to canonical
    install paths (%LOCALAPPDATA%\Programs\Ollama\ollama.exe, /opt/homebrew/bin/ollama, /usr/local/bin/ollama, etc.)
    when bare ollama isn't on the running process's PATH. Fixes the silent "browser never opens" failure when MandoCode
    is launched in the same shell that just installed Ollama (installer PATH updates only apply to new processes).
  • First-run wizard imperative output getting repaintedInitializeConnectionAsync now wraps
    RunOnboardingFlowAsync in _setupActive = true / false, suppressing HomeView for the entire wizard run instead
    of just the 401 auto-recovery path. Closes the latent VDOM redraw race that could clobber ollama signin URLs, error
    messages, or progress lines during first-run setup.

Added

  • Auto-open browser on ollama signinRunOllamaSigninAsync now captures stdout/stderr, scans for the first
    https:// URL Ollama prints, and calls OpenInBrowser directly so the sign-in page opens reliably regardless of
    Ollama's own browser-launch behavior. The URL is also re-emitted via AnsiConsole.MarkupLine as a clickable link with
    a "If your browser didn't open, copy the URL above" follow-up — survives any subsequent VDOM redraw and gives users a
    copy/paste fallback.

UI

  • Green selection highlight in setup wizardOnboardingFlow.Select now applies HighlightStyle(new Style(foreground: Color.Green)) to every SelectionPrompt, replacing Spectre's default blue. Affects the model
    picker, "What would you like to do?", "Sign me in now" branch, "Pick a starter model to install", and every other
    arrow-key choice in the wizard.

Install / update: dotnet tool update -g MandoCode

Full changelog: v0.9.9...v0.10.0

v0.9.9

26 Apr 06:16
698014b

Choose a tag to compare

🎯 v0.9.9 — Onboarding overhaul

First-run is now a guided wizard instead of a static "install Ollama, run serve, pull a model, then come back"
panel. The path from dotnet tool install -g MandoCode to first chat is auto-detected, auto-recovered, or
auto-installed at every step where it's possible. New users hit zero dead-ends; existing users get faster /config, a
new /model quick-switch, and a --doctor preflight.

Highlights

  • 🪄 Guided first-run wizard — auto-fires on first run and via /setup. Walks you through Ollama install → daemon
    start → cloud sign-in → model pick → context size, all from inside the terminal.
  • 📦 Auto-install Ollama — runs winget install Ollama.Ollama (Windows), brew install ollama (macOS), or curl install.sh (Linux) for you. Inherited stdio so you see the installer's progress and can answer prompts. Falls back to
    opening ollama.com/download if anything fails.
  • 🔐 Auto-launch ollama signin — wizard spawns the CLI command, browser opens, the local token is written
    automatically. Fixes the "I signed in on the website but chat still 401s" trap.
  • 🚀 Auto-launch ollama serve — when the daemon's down, the wizard offers to start it with a live-progress
    spinner.
  • 🛟 401 auto-recovery on chat — if a chat hits 401 mid-session, the cloud sign-in walkthrough fires immediately.
    No need to type /setup.
  • 🩹 Trailing-slash healhttp://localhost:11434/ is silently corrected.
  • 🎯 Wrong-port auto-fallback — when ollama serve succeeds but your configured URL doesn't reach the daemon, the
    wizard auto-probes http://localhost:11434 and switches if reachable. No retype required.
  • 🪟 PATH-refresh detection on Windows — checks canonical install paths
    (%LOCALAPPDATA%\Programs\Ollama\ollama.exe etc.) when where ollama fails, so post-install detection works without
    relaunching mandocode.
  • 🧠 Hardware-aware local model pickerqwen3.5:0.8b (CPU-only) → 2b4b9b (8+ GB VRAM) with size and
    hardware expectations spelled out. Auto-pulls your selection.
  • ☁️ Cloud upsell after local pull — informational tip pointing to minimax-m2.7:cloud as the more capable
    alternative (free with ollama signin).

New commands

Command Description
/setup Guided wizard — reconnect to Ollama, install/sign in, or pick a different model
/model Quick switch — pick a different model + context size
mandocode --doctor Preflight check from the CLI: .NET runtime, Ollama status, models pulled, sign-in state.
Exits 0 if green, 1 if anything's off.

UI improvements

  • k-notation max-tokens picker (32k, 128k, 200k) with current value highlighted at the top via ← current
    marker
  • Tiered context-size guide with educational intros on temperature and max-tokens (what tokens are, relationship
    to model context window, per-tier usage examples)
  • VDOM-aware text input for URL entry in /setup and /config — RazorConsole's TextInput instead of Spectre's
    TextPrompt, fixing dropped keystrokes alongside the live render loop. Pre-filled with current URL ("press Enter to
    keep current")
  • Combined cloud/local model picker with (cloud) / (local) badges. Replaces the old two-step "Cloud or Local?
    → list" flow.
  • Inline color tags (<red>, <green>, <yellow>, <cyan>) in the markdown renderer for chat error responses.
    401 errors now show Error: in red and the recommended action in green; backticked ollama signin keeps its purple
    inline-code styling.

Changed

  • Default cloud model: minimax-m2.5:cloudminimax-m2.7:cloud (config defaults, README, /learn, system
    prompt, error messages)
  • Default MaxTokens: 4k → 32k for new installs (existing configs preserved)
  • MaxMaxTokens: 256k → 200k after testing showed many cloud models hit a practical limit closer to 200k once
    system prompts and tool definitions are accounted for. Existing configs with 256k saved get clamped on next load.
  • /help table reorganized with /setup and /model next to /config and disambiguated descriptions
  • 16+ failure messages across the app now consistently surface /setup and /retry as recovery paths

Fixed

  • Status-aware /api/tags fetch with auto-retry — transient daemon hiccups no longer misroute users with pulled
    models into the "no models yet" flow
  • Post-pick cloud auth check via /api/generate — pulled cloud models that show in /api/tags after sign-out no
    longer cause the wizard to falsely report "Setup complete" before chat fails with 401
  • Picked-model validation via /api/show before the wizard declares success — surfaces models listed in /api/tags
    but not actually loadable
  • Misleading "Couldn't start Ollama" error when Process.Start succeeded but the URL didn't reach the daemon (port
    mismatch); now distinguishes "process didn't launch" from "process launched but URL unreachable"
  • <Markup> Razor component bracket markup — failure-state lines that used [yellow]…[/] now render in actual color
    via Foreground props
  • LearnContent.Display() double-render on every StateHasChanged

Breaking changes

  • Configs with MaxTokens > 200k (i.e. 256k saved) get clamped to 200k on next load. The picker shows 32k highlighted
    next time /config or /model opens — re-pick if you want.
  • Configs without an explicit maxTokens key now default to 32k instead of 4k. Configs with "maxTokens": 4096 are
    unaffected.

Install

dotnet tool install -g MandoCode      # new install
dotnet tool update  -g MandoCode      # upgrade from 0.9.8
mandocode                              # launch — wizard auto-fires on first run
mandocode --doctor                     # troubleshoot if anything's off

v0.9.8

25 Apr 08:49
c5665f4

Choose a tag to compare

Highlights

  • 🧩 Skills support — auto-invoked by the LLM, with a force-skill command (#43)
  • 🔌 MCP client support — interactive setup wizard (#44)
  • 📋 Paste handling + batch-deny on tool denial (#45)
  • 🖥️ Markdown rendering rebuilt on RazorConsole's translator pipeline (#47)
  • ⏱️ Streamed execute_command output with idle-based timeout (#48)

Install / Update

```
dotnet tool update -g MandoCode
```

What's Changed

  • v0.9.7 — Task planner redesign… (#42)
  • Skills support (#43)
  • MCP client support (#44)
  • Paste handling + batch-deny (#45)
  • README logo update (#46)
  • Markdown rendering on RazorConsole (#47)
  • Streamed execute_command output (#48)
  • CHANGELOG for v0.9.8 (#49)

Full Changelog: v0.9.6...v0.9.8

v0.9.6

06 Apr 19:32

Choose a tag to compare

Changelog

All notable changes to MandoCode will be documented in this file.

[0.9.6] - 2026-04-06

Added

  • Unit test project with 65 tests covering InputStateMachine and DiffService
    • Text input, cursor movement, backspace/delete, submit
    • Command autocomplete filtering, dropdown navigation, accept/dismiss
    • Command history navigation with saved input restoration
    • Paste handling with newline-to-space conversion
    • Static helper tests (IsCommand, GetCommandName) using parameterized [Theory] tests
    • Diff computation for new files, modifications, deletions, identical content
    • Line ending normalization (Windows \r\n, old Mac \r)
    • Large file fallback with sampled diffs
    • Context collapse with configurable context lines
  • Empty response recovery — when the model returns blank (context overflow), MandoCode now shows a helpful message instead of freezing with a blank screen
  • Rendering timeout guard — markdown rendering runs with a 30-second timeout and a "Rendering..." spinner after 1 second, preventing permanent freezes on large responses. Falls back to raw text if rendering exceeds the limit.

Fixed

  • Timeout retry deadlock — when a request timed out (5-minute limit), RetryPolicy was treating the timeout as a transient error and retrying the entire request including all file reads. With 2 retries, this could silently hang for up to 15 minutes. Now the cancellation token is properly passed to RetryPolicy so timeouts fail fast.
  • Silent exception suppression — replaced 6 bare catch { } blocks with catch (Exception ex) logging to Debug.WriteLine across TerminalThemeService, App.razor, FileSystemPlugin, FunctionInvocationFilter, and ShellCommandHandler
  • Shell command injection surfaceShellCommandHandler and FileSystemPlugin now use ProcessStartInfo.ArgumentList for proper argument escaping instead of manual string concatenation with cmd.Replace("\"", "\\\"")
  • Inconsistent config validationProgram.cs accepted any maxTokens > 0 while ValidateAndClamp() enforced [256, 131072]. All validation now uses centralized constants and helpers on MandoCodeConfig

Changed

  • Config validation constants (MinTemperature, MaxTemperature, MinMaxTokens, MaxMaxTokens) and helpers (IsValidTemperature, IsValidMaxTokens) are now defined once on MandoCodeConfig and referenced by Program.cs, ConfigurationWizard.cs, and ValidateAndClamp()

MandoCode v0.9.5 – Unified Input, Smarter Onboarding, Slicker UX

01 Apr 08:10

Choose a tag to compare

Highlights

  • Unified input state machine – Both the VDOM prompt and the imperative console loop now share the same InputStateMachine, so autocomplete,
    history, and paste behave identically everywhere.
  • Seamless autocomplete – / and @ dropdowns no longer glitch; selecting a file or command instantly snaps back to the VDOM prompt with your
    text intact.
  • Robust paste handling – Windows’ “large paste” confirmation no longer injects stray Enter keystrokes; pasted text is normalized and
    inserted safely.

VDOM & input pipeline

  • Async PromptInput bridge – PromptInput now awaits the autocomplete hand-off, drains buffered keystrokes, and feeds them back into the
    shared state machine, eliminating the “typing on an empty console” flash.
  • @ browsing polish – Accepting directories/files keeps the dropdown state and immediately repopulates the VDOM prompt, so you can chain
    references without retyping.

Smarter onboarding

  • Connection lifecycle – Clear “🔄 Connecting…” → “✅ MandoCode is ready!” flow with /retry at any time.
  • Offline guidance – A yellow panel explains exactly how to start Ollama (install, ollama serve, pull a model) and keeps /config + /learn
    accessible.
  • /retry command – Rechecks the endpoint, re-validates the model, and updates the UI without restarting the CLI.

UX & personality

  • Modern banner – Clean gradient “MANDOCODE” figlet replaces the wolf animation for a sharper first impression.
  • Help tweaks – /exit is the only exit command; /retry and an @file tip are surfaced in the help table.
  • Spinner upgrades – Loading messages pull from a new hip-hop / 90s tech / Matrix / CS 1.6 list, and every Spectre spinner style auto-loads
    so animations never break.

Token & output polish

  • Session totals still print above the prompt for quick reference.
  • Per-response summaries remain right-aligned ([~in, out: tok/s]) without cluttering the scrollback.

Docs

  • Added VDOMArchitecture.md, RazorConsoleComponents.md, AutocompleteSkill.md, and TaskPlanner.md explaining the new state machine + VDOM
    bridge and how the CLI renders messages.
dotnet tool update -g MandoCode 

Update with and enjoy the smoother experience!
Thanks to everyone who tried v0.9.2 , it had quite a bit of major breaking bugs, I hope this version serves you better.

THANK YOU!

v0.9.2

04 Mar 21:27
635313a

Choose a tag to compare

What's New

  • Arrow key navigation — move cursor left/right within your input with arrow keys, Home/End to jump to start/end, Delete key
    support
  • Fixed paste detection — fast typing no longer falsely triggers paste mode
  • Fixed cursor after paste — pasting long text no longer freezes input or breaks Enter submission
  • Pasted text shown inline — no more [pasted N characters] summary, actual text is displayed

Install / Update

dotnet tool update -g MandoCode