Added RAG implementation, setup wizard and other fixes - #65
Open
lsoft wants to merge 23 commits into
Open
Conversation
…efects. MCP proxy: - ProcessMcpServerProxyAsync no longer appends a second wrapper for a server which is already running, so the tools of every reconfigured server stopped being offered to the model twice, three times and so on. The wrapper of a server which failed to start is dropped as well - GetTools enumerates the wrappers, so removing its tools from the container alone was not enough. - The JSON-RPC channel is re-attached to the streams of the restarted proxy. ProcessMonitor did restart the process, but the channel stayed bound to the streams of the dead one, so every MCP call after the first crash was lost. A freshly started proxy hosts no MCP servers, so the configuration is pushed into it again. Started/ProxyInterface now tell whether the channel is alive. - A failed start no longer ends the monitoring for the rest of the session: it is retried with a pause, and given up only after several failures in a row. - Proxy.zip: "already unpacked" is decided by a marker file written after the last entry. The folder used to be created before the first entry, so an interrupted unpacking left a truncated folder which was never repaired. Options: - DeserializeAsync returned null when a place was asked for explicitly and nothing was there, contrary to its own contract; callers dereference it. - SerializeAsync into a solution-related file with no solution opened reports what has happened instead of throwing ArgumentNullException from FileInfo. - Installing the MSDN MCP server overwrites the entry instead of Add-ing it: the name could be taken already, and CanExecute only looks at the endpoint. Concurrency: - ChatContainer handed out the live list of chats and read it without the lock, while chats are added from the UI thread and their statuses change on the threads which stream the answers. Events are no longer raised under the lock. - LLMReader could hand a cancelled (and then disposed) token source to a read started right after a stop, and the finishing read could null the _task of a newer one. - FileCacheEntry updated its value and its signature around an await without any synchronization, and dereferenced a null the converter is allowed to return. UI: - The buttons inserted into the Git Changes pane and into the "Find in Files" dialog are restored after Visual Studio rebuilds them. The scan stopped after the first insertion, so reopening the dialog left it without our controls. - Windows are no longer subscribed to Closed on every Loaded. - The FreeAIrPackage summary stood after the attributes: CS1587, and it never made it into the documentation. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Documents that the solution requires full MSBuild from the Visual Studio installation, since the projects are legacy-format VSIX/.NET Framework 4.8 and the VSSDK targets are unavailable to the .NET SDK. Also records two non-obvious traps found while building: - "dotnet build" not only fails, it rewrites obj/project.assets.json with .NET SDK semantics and breaks the next MSBuild build with a spurious "doesn't list win as a RuntimeIdentifier" error. Recovery is to re-run the MSBuild restore. - vswhere.exe returns an empty list here, so toolchain discovery through it silently finds nothing and the MSBuild path must be given explicitly. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The search used to hand every text file of the scope to the model, one context window at a time. With `Use RAG` checked it now asks the embedding index which files are worth reading and gives the model those only. Index: - Extracted `Rag\FreeAIr.Rag.csproj` (netstandard2.0) out of the VSIX: the index format, the vector codec, the outline tree and the ranking know nothing about the IDE, and the VSIX assembly cannot be loaded by a test runner. That is what makes any of this testable at all. - New on-disk format. Vectors are quantized and written one per line, and an outline which is nothing but the name of the member it describes is not embedded at all - eighteen times less disk space on the sample solution. The order does not depend on the machine which built the file, so two people rebuilding the index in two branches get a merge instead of a conflict. - One file less: the tree of the outlines is derived from the outlines instead of being stored. The format is not backward compatible; an index built by 4.2.11 or earlier has to be rebuilt. - The index remembers which model built it, by storing the vectors of a few fixed sentences. A search with another model is refused instead of returning noise - the vector length alone did not catch it, since unrelated models often share it. The name the server reports for itself is recorded too, which is the only name that changes when a local server is given another model. - `RagMinScore` is gone. Every build now measures what a query with no answer scores on this model and this solution, and `Sensitivity` says how far above that measured noise a file has to stand - one value which keeps its meaning when the embedding model changes. `RagTopOutlineCount` and `RagMaxFileCount` moved into a `Rag` node of their own. - `EmbeddingIndexContainer` is shared by the search and the GetAllSolutionFiles MCP tool, which used to read the whole index on every call. Calibration: - `Extensions / FreeAIr / Open RAG search calibration window...` asks the index the questions the user would ask the search, shows what the threshold lets through and what it cuts, and saves the questions into the settings and the numbers into the index - without rebuilding the vectors, so a threshold is fixed in a minute instead of in an hour of embedding. - Queries whose answer is known are kept in the settings as well: the threshold is never allowed to climb up to them, and a query which fails to find its own file is reported at the end of the build, because that means the model does not understand this codebase. Search: - Every step is cancellable, including the reading of the index. - The shortlist is shown before the first answer arrives: that is the only moment where the user can tell the search is looking in the wrong place. - The results window names the agents behind the answers - the one which was asked, and, for a RAG search, the one which vectorized the query. The second one is normally chosen from the index rather than by the user. - The `Confidence` column reads `High (85)` instead of `85`. The number is a guess of the model, not a measurement. Fixes: - An agent without a token was invisible to everything which looks an agent up by name. An embedding server run locally wants no token, so the agent which had built the index was never found and a cloud chat agent was silently used to vectorize the query - which answers a request for embeddings with 400. - An embedding server which refuses a request is now quoted. `HTTP 400` alone says nothing about which model or which parameter it did not like, and the server had already explained it in an answer that was being discarded. - The results window failed to open at all: its progress bar was bound two way onto a read only property, which throws while the window is being built. - The natural language search gave up in silence in six places. An empty file mask now means every file, as it does in `Find in Files`, instead of killing the search with an exception nobody sees; the other five say why they stop. Every step also writes itself into a `FreeAIr natural language search` pane of the Output window. - `Edit actions`: clicking an action did nothing. `SelectedAction` was writing into the backing field of the property while the rest of the window kept reading a separate field, which therefore stayed null - the editing panel was hidden and every command disabled. Tests and docs: - `Rag.Tests` (net8.0, xunit) covers the index format, the vector codec, the outline tree, the ranking and the calibration. `run-tests.bat` builds with MSBuild first, because letting the .NET SDK restore breaks the VSIX build. `run-integration-tests.bat` runs the tests which need a real server. - The calibration and NLO windows describe themselves in a block at the top. - README, ARCHITECTURE and the release notes follow. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Finding where a text occurs used to mean handing whole files to the model one by one. `VisualStudio.SearchFileContent` answers that question directly: the matching lines, each with its file and line number. Nothing is installed and no process is started - the matching is `Rag\Grep\GrepSearch.cs`. Shipping a `grep.exe` inside the VSIX would have bought speed nobody asked for, at the price of a third party binary, its licence and the antivirus reports about it. - Literal by default and a .NET regular expression on request, both through the same code path - the literal one is escaped. `case_sensitive` and `whole_word` are the other two switches, and `invert_match` reports the lines which do not match, the way `grep -v` does. - `search_scope` chooses between the files of the projects (the default) and every file in the solution folder. The walk skips `bin`, `obj`, `.git`, `node_modules` and the like either way, so a search does not answer with build output. - `file_mask` is `*.cs;*.xaml`, and a mask which starts with `!` subtracts: `*.cs;!*.Designer.cs` is what keeps generated code from eating the budget. - The answer is capped - 100 matching lines by default, 500 at most - and says whether the cap was reached. A truncated list which does not admit to being one is read by the model as the whole truth. - Running inside devenv is what a `grep.exe` could not have done: a document which is open and not saved yet is searched as the user sees it rather than as it is on the disk. Those buffers are collected on the main thread and the scan itself runs off it, so a solution of thousands of files does not freeze the IDE. - The pattern is written by a model, so the regular expression is given a five second timeout: the file which makes it misbehave is reported and the rest of the search survives. The matching, the masks and the decoding of a file into lines live in `FreeAIr.Rag`, which a test runner can load, and are covered by `Rag.Tests\GrepFacts.cs`. The tool itself is the Visual Studio half of it. CLAUDE.md gets a warning as well: a new file in the legacy-format `FreeAIr.csproj` has to be added to it by hand. This tool was missing from the built assembly for exactly that reason, with the build still reporting no errors at all. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
4.2.12 was never released: the version was raised to it and then to 4.3.0 a couple of hours later, so the RAG search - the `Use RAG` checkbox, the new index format, the calibration window - ships in 4.3.0 together with the grep MCP tool. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
4.2.12 is a released version and keeps its section, but it shipped the fix for issue #61 only: the RAG search - the `Use RAG` checkbox, the new index format, the Sensitivity setting and the calibration window - is part of 4.3.0, and so are the MCP proxy, options and concurrency fixes which had no release note at all. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The C# scanner fed the embedding index only the bare text runs of a <summary>, so everything inside <see cref>, <c>, <list> and <paramref> was dropped on the way in: "Reads the <see cref="EmbeddingIndex"/> from disk" reached the index as "Reads the from disk". Bullet lists vanished whole. It also never visited enums, delegates, events or indexers, so a comment on any of them was indexed nowhere. CleanCommentText now walks the nested markup and keeps the identifiers out of cref and name attributes, and the tree builder emits nodes for every declaration a summary can be written on. Node ids of existing members are unchanged; enums and the rest are new nodes, so the index has to be rebuilt to pick them up. Overloads still collapse onto one Target of Type.Method and therefore one id, so only one of their summaries survives. Left alone here: fixing it changes the ids of every overloaded member and the Type.Member convention OutlineTreeAssembler splits on. With that fixed, commented the core - Chat, BLogic and the support actions - aiming at what the index actually stores rather than at formal doc comments. Nodes carrying a real outline went from 918 to 1030 of 4299; Chat 43%, BLogic 49%. CLAUDE.md gains a section on what the scanner reads and how to write for it, since none of this is guessable from the code. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
lsoft
force-pushed
the
fix/mcp-proxy-restart-and-concurrency
branch
from
August 3, 2026 10:53
bafbdbc to
eee7396
Compare
Continues the pass started in the previous commit: the parts of the core the scanner still saw as bare identifiers, and which were therefore absent from the embedding index entirely. Covered here: - Chat and ChatContainer - the ownership and the lifetime rules, why the context is injected right before the last prompt, why archiving is what brings the token cost of a long dialogue back down. - TextDescriptor - the two ways an answer is written back, and why the selected variant goes through the text buffer rather than the file. - TypeReferenceWalker - what each override harvests a type from, and why types from referenced assemblies are dropped. - SupportContext - what every prompt anchor stands for and which scope supplies it. - FreeAIrOptions, AgentJson, AgentCollectionJson, McpServersJson - where the settings live, how a token is resolved out of an environment variable, and what the shipped system prompts are for. Nodes carrying a real outline: 1030 -> 1181 of 4299. Chat 43% -> 69%, Options2 27% -> 70%. The overload collision is still there: two methods sharing Type.Method share one node id, so only one summary reaches the index. WithContextItemAsync says so in its own summary; fixing it would change the id of every overloaded member. Release builds with 0 errors, Rag tests 112 passed / 6 skipped. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Covered here: - CallAwaiter - the callback-to-awaitable adapter behind recording and similar one-shot async operations, and why the finalizer fires as a last-resort guard. - RecorderTranscriberPostProcessor - the record/transcribe/post-process loop, its status events, and how a misconfigured post-process action falls back to the raw transcription. - UnsortedJson - the settings that never got a dedicated node: output length, answer culture, GitHub token resolution, whole line completion. - RagJson - summaries on the properties and the calibration probe types that the Description attributes alone do not reach the outline index. Nodes carrying a real outline: 1181 -> 1214 of 4299. Release builds with 0 errors, Rag tests 112 passed / 6 skipped. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`FreeAIr.Rag` was never really "the RAG project" - its csproj comment always said what it is: the half of search that does not need Visual Studio and can therefore be exercised by an ordinary test runner. The natural language search (index, vector codec, outline tree, ranking) and the Grep text matcher behind the SearchFileContent MCP tool live there for that one reason, testability, not because Grep has anything to do with retrieval augmented generation. The old name just happened to describe the bigger half and mislead about the rest. Renamed via `git mv`, tracked as renames: - Rag/ -> Search/, Rag.Tests/ -> Search.Tests/ - FreeAIr.Rag.csproj -> FreeAIr.Search.csproj (AssemblyName, RootNamespace, InternalsVisibleTo), same for the Tests project - every test file's `namespace FreeAIr.Rag.Tests` -> `FreeAIr.Search.Tests` - FreeAIr.sln project entries, FreeAIr.csproj's ProjectReference, run-tests.bat - CLAUDE.md, ARCHITECTURE.md, and the two doc comments in FreeAIr\Embedding that named the assembly in prose Domain types genuinely about the RAG feature keep their names as they should - RagShortlist, RagCalibration, RagJson, RagCalibrationViewModel - only the project/assembly identity moved. Release builds with 0 errors; Rag.Tests -> FreeAIr.Search.Tests still 112 passed / 6 skipped under the new name. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Four of the built-in Visual Studio tools take no arguments and declared an
empty `{}` schema. LM Studio validates `function.parameters` and answers the
whole completion request with 400, so one such tool took every other tool and
the conversation with it. Tool schemas are now normalized on their way to the
model rather than at the four declarations only: the schemas of third party MCP
servers reach us unseen and may say the very same thing.
The natural language search and the outline generation hit the same status from
the other end, by asking for the `json_object` response format which LM Studio
does not implement. They ask for the json in the prompt, as they already did,
and the answer passes the cleanup which strips fences and reasoning blocks
before it is parsed.
Tool calls are also reassembled from the whole stream instead of its first
chunk. The arguments arrive as deltas across the following chunks, and reading
only the first one ran the tool with no arguments and sent a half-read call
back to the server, which replied 500.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Adds <summary> XML doc comments across the MCP proxy protocol (Dto/*, the Proxy process's Server/* and BLogic/Api.cs) and the VSIX-side MCP tool implementations (ServerProxy/*), so this code is findable through the natural-language search instead of being invisible to it. MCP coverage in the outline index goes from 2% to 31%.
…ch coverage. Adds XML doc summaries to the ANTLR listener, the block/part model, the table/xml/image/url renderers and the parser entry points (CachedMarkdownParser/DirectMarkdownParser), following the same NLO-outline convention used for MCP. No logic changes.
…age. Covers the cross-process CodeLens flow (Shared DTOs/contracts, the out-of-process data point in CodeLens/, the Visual Studio-side listener and connection handler in FreeAIr/CodeLens/, and the details-pane view model) plus the WpfHelpers MVVM/command/collection utilities.
…elpers surface for NLO/RAG search coverage. Raises overall NLO/RAG comment coverage from 36% to 95% (FreeAIr core 33%->95%, MCP 31%->98%, MarkdownParser 50%->96%, CodeLens 56%->91%, WpfHelpers 77%->96%). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…when it is not configured. A new install of FreeAIr starts with the author's own debug configuration - placeholder tokens, personal endpoints - and no guided way to replace it. The wizard walks through agents, MCP servers, actions and the remaining settings, explaining each step, and writes nothing until the last page. It is offered by an info bar the first time FreeAIr runs and stays available from Extensions > FreeAIr > Open setup wizard... The logic that needs neither Visual Studio nor WPF - step navigation, the agent-field and action-binding validators, the endpoint and MCP server catalogs - lives in the new netstandard2.0 SetupWizard project so an ordinary test runner can reach it (SetupWizard.Tests, 45 tests), the same split as FreeAIr.Search. It carries no resources, so its validators report enum codes which the view model renders into the localized sentences; the window itself is fully localized like the rest of the product. Notable behaviour: - On a first run the shipped sample agents are wiped and the user is guided through creating one of their own field by field, with an endpoint reachability check and a choice between a literal token and an environment variable holding it. A later run gets the ordinary multi-agent list editor. - The actions page explains what an action is, warns in red about any action naming an agent which does not exist, and can restore the shipped prompt library bound to the first agent. - Whole line completion is switched on and off on that same page, because it is what makes its action live or dormant: while it is off the action is neither bound by the defaults button nor reported as a problem. - The Microsoft Learn documentation MCP server is one checkbox on the MCP servers page. Its name and endpoint move into KnownMcpServerCatalog, which the control center's install command now reads too, so the two cannot drift apart. - The GitHub MCP server is opt-in; nothing asks for a GitHub token until the box is ticked. - Nothing in the wizard may throw into WPF's dispatcher - an unhandled exception in a modal dialog inside devenv ends Visual Studio rather than the dialog - so every command body, the window loading, the info bar and the package hook each catch, log and report. Separately, whole line completion no longer opens an error dialog on every pause in typing when its action names no existing agent. That is how the shipped agent_name_must_be_set placeholder used to interrupt a brand new install, the setup wizard included. The complaint goes to the activity log, and is shown as a dialog only when a suggestion was asked for explicitly with the shortcut. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Скан индекса и так считает скор каждой записи, поэтому фоновый уровень конкретного запроса достаётся бесплатно: медиана и нижний квартиль всего ранжира дают порог median + k*sigma, где k читается из той же Sensitivity. Это работает на индексе, который никогда не калибровали, и снимает то, чего единственное число калибровки не видит: общий короткий запрос близок ко всему корпусу, узкий - ни к чему. Файл обязан пройти оба порога. Разброс берётся по нижней половине распределения - верхняя это и есть ответы, и порог рос бы каждый раз, когда поиск срабатывает. На индексе меньше 256 записей порога отсюда нет вовсе: квартили десятка чисел не квартили. Разбор калибровки и ещё четыре способа сделать её автоматической - в devdocs/RAG_AUTO_CALIBRATION.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Five things which grew out of one another: the MCP proxy was fixed first, then the natural language
search was taught to use an embedding index, the search machinery which came out of that turned out
to be the right home for a grep tool as well, and a setup wizard was added so a new install has a
guided way to replace the configuration this repository ships with.
Version bumped to 4.3.0. The index files of
TestSubjectare regenerated in the new format.RAG for the natural language search, and a window to calibrate it
The search used to hand every text file of the scope to the model, one context window at a time.
With
Use RAGchecked it asks the embedding index which files are worth reading and gives the modelthose only.
Search\FreeAIr.Search.csproj(netstandard2.0) is extracted out of the VSIX: the index format, thevector codec, the outline tree and the ranking know nothing about the IDE, and the VSIX assembly
cannot be loaded by a test runner. That is what makes any of this testable at all —
Search.Tests\is new too.nothing but the name of the member it describes, and an order which does not depend on the machine
which wrote the file. Eighteen times less disk space on the sample solution, and a merge instead of
a conflict when two branches rebuild the index. Not backward compatible — an index built by
4.2.11 or earlier has to be rebuilt.
search with another model is refused instead of returning noise. The vector length alone did not
catch this, since unrelated models often share it.
RagMinScoreis gone. Every build measures what a query with no answer scores on this model andthis solution, and
Sensitivitysays how far above that measured noise a file has to stand — onenumber which keeps its meaning when the embedding model changes.
Extensions / FreeAIr / Open RAG search calibration window...asks the index the questions theuser would ask the search, shows what the threshold lets through and what it cuts, and saves the
result without rebuilding the vectors: a threshold is fixed in a minute instead of in an hour of
embedding.
writes what it is doing into a
FreeAIr natural language searchpane of the Output window insteadof giving up in silence in six different places.
A grep tool for the built-in Visual Studio MCP server
Finding where a text occurs used to mean handing whole files to the model one by one.
VisualStudio.SearchFileContentanswers that question directly: the matching lines, each with itsfile and line number.
Nothing is installed and no process is started — the matching is
Search\Grep\. Shipping agrep.exeinside the VSIX would have bought speed nobody asked for, at the price of a third partybinary, its licence and the antivirus reports about it.
patternis_regular_expressionis setcase_sensitive,whole_wordinvert_matchgrep -vdoessearch_scopesubfolder,file_mask*.cs;*.xaml; a mask which starts with!subtracts, so*.cs;!*.Designer.cskeeps generated code from eating the budgetcontext_line_count,max_result_countread by the model as the whole truth.
grep.execould not have done: a document which is open and notsaved yet is searched as the user sees it. Those buffers are collected on the main thread and the
scan itself runs off it, so a solution of thousands of files does not freeze the IDE.
detected by extension and by content, and the regular expression — written by a model — is given a
five second timeout, so one pathological file is reported instead of hanging the IDE.
MCP proxy lifecycle, options and concurrency
to the model twice, three times and so on.
MCP call after the first crash lost, and the configuration is pushed into the fresh process again.
A failed start is retried instead of ending the monitoring for the session.
Proxy.zipdecides "already unpacked" by a marker written after the last entry, so an interruptedunpacking is repaired instead of being trusted.
threw when no solution was open, and an MCP server installation which added a duplicate entry.
ChatContainerhanded out its live list of chats and read it without the lock,LLMReadercould hand a cancelled token source to a read started right after a stop, andFileCacheEntryupdated its value across an await unsynchronized.Find in Filesdialog are restoredafter Visual Studio rebuilds them, and windows are no longer subscribed to
Closedon everyLoaded.A first-run setup wizard
A new install starts with the configuration this repository ships with — placeholder tokens, the
author's own endpoints — and the only way to replace it was to reverse-engineer the settings file or
to find the control center's per-entity editors one at a time. The wizard walks through agents, MCP
servers, actions and the remaining settings, says what each step is for, and writes nothing until
Finish. An info bar offers it the first time FreeAIr runs (alongside the release notes, once), andit stays available from
Extensions / FreeAIr / Open setup wizard....SetupWizard\FreeAIr.SetupWizard.csproj(netstandard2.0) holds what needs neither Visual Studionor WPF: step navigation and skipping, the agent-field and action-binding validators, the known
endpoint and known MCP server catalogs.
SetupWizard.Tests\covers it with 45 tests. Same split,and the same reason, as
FreeAIr.Search.them into localized sentences. The window itself is fully localized — 79 new keys in the
en,ruandzh-Hansresx — and takes its colours from the Visual Studio theme rather than fromliterals, so its text is readable under a dark theme too.
of their own field by field, each field with its own explanation, plus a
test connectioncheck ofthe endpoint (the same
GetModelsAsynccall the model picker makes) and a choice between pasting atoken and naming an environment variable which holds it. A later run gets the ordinary multi-agent
list editor instead.
action naming an agent which does not exist — which is what renaming or deleting an agent silently
produces. A
Use default valuesbutton restores the shipped prompt library bound to the firstagent.
run whole line completion as you typeswitch sits on that same page, because it is what makesthe whole line completion action live or dormant: while it is off that action is neither bound by
the defaults button nor reported as a problem, and ticking it does both.
HTTP endpoint, so nothing is downloaded and no token is needed. Its name and endpoint moved into
KnownMcpServerCatalog, which the control center's install command reads too, so the two cannotdrift apart and a server installed by one is recognized by the other.
devenvends Visual Studio rather than the dialog — so every command body, the window loading, theinfo bar and the package hook each catch, log to the activity log, and report.
McpServerConfigureWindow/ActionConfigureWindowagainst a clone, so a cancelled sub-dialogleaves the wizard untouched.
DirectOrEnvStringHelpermoved into the new project instead of beingcopied into it, and the shipped defaults stayed the single source they already were.
Separately, whole line completion no longer opens an error dialog on every pause in typing when its
action names no existing agent. That is how the shipped
agent_name_must_be_setplaceholder used tointerrupt a brand new install, the wizard included. The complaint goes to the activity log now, and
is shown as a dialog only when a suggestion was asked for explicitly with
Alt+A.Documentation
ARCHITECTURE.mddescribes the projects, the flow of a chat and the MCP, search and setup wizardsubsystems;
CLAUDE.mdholds what an automated agent needs to build this repository — full MSBuildrather than the .NET SDK, why
dotnet buildbreaks the next build, how to run the tests, and thefact that a new file in the legacy-format
FreeAIr.csprojhas to be added to it by hand or it issilently not compiled.
Checks
FreeAIr.slnbuilds with 0 errors in Release (the ~800 warnings are pre-existing), andrun-tests.batis green: 112 passing inFreeAIr.Search.Testswith 6 integration tests skippedwithout an embedding server, and 45 passing in
FreeAIr.SetupWizard.Tests.🤖 Generated with Claude Code