NeuralDeskApp ships under four names, two runtimes, and a lockfile check that stops the build
Versatile Almost Local, Eventually Reasonable Assistant 🔫
At a glance
- What is it?
- A desktop AI agent written in TypeScript that talks to any OpenAI-compatible endpoint, keeping memory in ~/.valera/memory.md and sessions in SQLite. The interesting parts are the identity drift between the repository, the README, the package name and the release tags, and the build scripts that assume both Tauri and Electron.
- Who is it for?
- Adopt NeuralDeskApp if you want a desktop agent you can point at a local OpenAI-compatible server, read the TypeScript that draws the tools, and keep transcripts on your own disk. Do not adopt it expecting a Windows binary today, since the README marks that build as coming soon and sends you to .github/workflows instead.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 141 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 3, 2026, and from our analysis. They are not legal advice.
Editorial analysis
One repository, four names
Start by naming things, because the naming does not agree. The repository is NeuralDeskApp. The README heading says KVDesk, and the rest of that document, every example configuration and every build target filename, says ValeDesk. The npm package is called valera. The three GitHub releases are tagged v0.0.8, v0.0.7 and v0.0.5 but titled LocalDesk v0.0.8 and so on. The self description changes too: the repository metadata calls it Versatile Almost Local, Eventually Reasonable Assistant, while the package description expands the same phrase to Very Almost Local and adds OpenAI SDK compatible AI agent.
The on-disk state carries the fourth identity. Preferences land in ~/.valera/memory.md and per-iteration request and response JSON lands in ~/.valera/logs/sessions/, neither of which matches the ValeDesk strings or the valera package name on its face.
Practical consequence: grep for the wrong token and you will miss both the code and the data. The project also spreads a fourth surface beyond its own tree, a Skills Marketplace hosted on GitHub Pages under a ValeDesk-Skills path, so installed skills are not versioned next to the agent that loads them.
The last push landed on 2026-05-15 and the newest release is v0.0.8 from 2026-01-26, so the tag line and the commit line disagree on recency by several months.
Both Tauri and Electron are wired into the same tree
The README advertises React with Tauri, and the manual build steps are a Tauri build.
# 1. Build sidecar binary
npm run build:sidecar
# 2. Build Tauri app
cd src-tauri && cargo build --releaseThe package manifest points somewhere else. The main field resolves to dist-electron/agent/main.js, the start script runs electron . --no-sandbox, build:app runs npx electron-rebuild after the TypeScript and Vite build, and a headless variant wraps the same entry point in xvfb-run -a electron . --no-sandbox. The top-level file list contains electron-builder.json next to src-tauri/, alongside a separate transpile:sidecar script.
So both shells exist in one repository: a Rust src-tauri tree that produces ValeDesk-0.0.8.dmg through make bundle, and an Electron main process that package.json considers canonical. The Vite dev server is pinned to a fixed address with --host 127.0.0.1 --port 5173 --strictPort, which means a second copy of the dev server on the same machine fails rather than silently moving ports, and dev:tauri, dev:react and dev:electron:delayed exist as separate entry points into the three halves.
Nothing in the README explains when you would want one over the other.
The OpenAI SDK is the only integration surface
There is no vendor list to maintain. The agent is written against the OpenAI SDK and accepts any compatible endpoint, which is what puts vLLM, Ollama and LM Studio in reach without a separate integration each. Local servers are expected to be running first.
# Run Ollama locally (free, 100% private)
ollama serve
# Configure ValeDesk: http://localhost:11434/v1
# Or use vLLM for faster inference
vllm serve Qwen/Qwen2.5-14B-Instruct --port 8000
# Configure ValeDesk: http://localhost:8000/v1Configuration happens in the Settings dialog and takes four fields: an API Key, which accepts the literal string dummy-key for local models that ignore authentication, a Base URL that must include the /v1 path segment, a Model Name, and a Temperature between 0.0 and 2.0 defaulting to 0.3. Save Settings commits the change.
{
"apiKey": "dummy-key",
"baseUrl": "http://localhost:8000/v1",
"model": "qwen3-30b-a3b-instruct-2507"
}The /v1 requirement is the one field with a stated format rule, and it is the field people get wrong when copying an Ollama URL. Web search is separate from the model endpoint and goes through Tavily or Z.AI, and the offline claim in the README is scoped accordingly: it works without internet except for those tools.
make dev refuses to continue without package-lock.json
The Makefile treats the dependency state as something to verify, not assume. Its ensure-node-deps target first tests for the lockfile and aborts with a message stating that package-lock.json is required for npm ci when it is absent. Only if node_modules is missing does it run npm ci, and it follows that with a rebuild of the better-sqlite3 native module for the current Node.js.
Rust gets a floor of 1.74.0, held in the MIN_RUST_VERSION variable and compared component by component: major, then minor, then patch. A missing rustc stops the build with a pointer to the rustup installer. Tool checks branch on the OS environment variable, dispatching to ensure_deps.sh on Unix and to a PowerShell script with execution policy bypassed on Windows, and the Rust check follows the same split.
Development itself is three commands after the clone.
git clone https://github.com/vakovalskii/ValeDesk.git
cd ValeDesk
# Install dependencies
npm install
# Run in development mode
make devNote that the clone URL in the README points at a ValeDesk path while the repository you are reading is NeuralDeskApp. The prerequisites above that step are Rust 1.74 or newer, Node.js 20 or newer, and Python 3, the last one only because of the execute_python tool.
Loop detection counts five identical tool calls
Two runtime guards are worth knowing about because they change how a stuck agent behaves. Loop detection fires on five or more sequential calls to the same tool, which is the shape a broken agent gets into when a tool keeps returning something the model cannot use and it retries the same name indefinitely. Request timeouts sit at five minutes with an automatic retry, so a hung endpoint produces one long pause rather than an instant failure.
Streaming is interruptible at any point, and the UI updates are driven by requestAnimationFrame rather than by a re-render per token, which is what keeps a long answer at 60fps. Token tracking displays input and output counts alongside the API duration for each call, so you can see cost per turn rather than guessing.
Two more defaults shape the surface. Tool execution runs under a permission system with ask and default modes, so you choose whether a call is confirmed every time. Message editing resends with history truncation, meaning an edit rewrites the stored branch rather than appending a correction. Sessions persist across restart on SQLite, can be pinned, and can be searched through chat history. Scheduling is separate from all of this: reminders and recurring tasks execute on their own.
Tool names are verb_noun, and one of them is a shell
Every tool follows a snake_case verb_noun pattern, which makes the list scannable and makes a custom addition predictable. The file group is run_command for shell execution in PowerShell or bash, read_file, write_file, edit_file for search and replace, search_files for glob patterns such as *.pdf or src/**/*.ts, search_text for grep-style content search, and read_document for PDF and DOCX text extraction with a 10MB ceiling.
Code execution splits by runtime and by trust level. JavaScript runs in a Node.js vm sandbox under execute_js, while Python runs as a system subprocess, which is a materially weaker boundary. The README marks Python 3 as a prerequisite only for that second path, and the sandboxing claim in the feature list is about directory restrictions on file operations plus the JavaScript sandbox, not about the subprocess runner. If you enable Python execution on a machine with credentials, that is the line to think about.
Document extraction is bundled rather than delegated to a system tool, so PDF and DOCX text works out of the box. Telegram parsing is a separate capability rather than a tool: it renders t.me channels with reactions and view counts and auto-scrolls to load older posts.
Two directories in the tree hint at how this gets tested: e2e/ and tests/, alongside playwright.config.ts, vitest.config.ts and eslint.config.js. The test entry point is a single command.
Voice input is a server you start yourself
Speech to text is not built in. You run a local transcription server first, and the setup script picks the runtime for you.
chmod +x scripts/setup_voice_server.sh
./scripts/setup_voice_server.shThe script uses Docker by default and falls back to uvx or a venv when Docker is unavailable. Five variables tune it: PORT, MODEL, DEVICE, COMPUTE_TYPE and DOCKER_TAG. Three more size the container.
DOCKER_MEMORY=6g DOCKER_CPUS=6 DOCKER_SHM_SIZE=2g ./scripts/setup_voice_server.shThose resource variables exist because transcription models are memory hungry, and the shared memory setting in particular has a documented need beyond plain memory limits. In the app, Settings then Voice takes a Voice Base URL such as http://localhost:8000/v1, a Model, and optionally an API Key and a Language. The status has to read Connected before the mic button in the prompt input does anything.
The rest of the app is Python-free apart from execute_python, which makes voice the one feature where you are assembling a stack rather than flipping a setting. Combine it with the five minute request timeout and you have two separate long waits in one interaction.
Windows is marked coming soon and CI is the fallback
The feature list claims Windows, macOS and Linux support with proper shell commands, and the Makefile carries a full PowerShell branch for every check that matters, from ensure_deps.ps1 through ensure_node_deps.ps1 to ensure_rust.ps1 with a MinRustVersion argument. The documented DMG build is macOS only.
# Build DMG (macOS)
make bundle
# Output: ValeDesk-0.0.8.dmgAgainst that, the Windows section of the README is a single sentence saying the build requires cross-compilation setup and pointing you at .github/workflows for CI builds. That is the whole answer for Windows: check the workflows. The manual path exists for macOS and ends in a hdiutil create call producing a UDZO disk image from the release bundle.
That split also puts the version numbers in perspective. package.json carries 0.0.8 and the release train is v0.0.5, v0.0.7, v0.0.8, all published in January 2026, with the last push on 2026-05-15. The licence field is SEE LICENSE IN LICENSE rather than an identifier, so there is no machine-readable licence string in the manifest and no COPYING-style file named in the top-level listing beyond LICENSE itself.
For a project you intend to modify, that combination is workable. For a project you intend to depend on at a pinned version, the release cadence and the licensing metadata are both thinner than the feature list suggests.
Editorial conclusion
Adopt NeuralDeskApp if you want a desktop agent you can point at a local OpenAI-compatible server, read the TypeScript that draws the tools, and keep transcripts on your own disk. Do not adopt it expecting a Windows binary today, since the README marks that build as coming soon and sends you to .github/workflows instead. Before you trust it with a machine, verify three things: that make dev finds Rust 1.74 or newer and a package-lock.json, that the Base URL you paste actually ends in /v1, and that the runtime you assumed matches the one in package.json, because dist-electron/agent/main.js points at Electron while the build instructions in the README say Tauri.
Frequently asked questions
What is NeuralDeskApp and what does ValeDesk refer to?
They are the same project under different names. The repository is NeuralDeskApp, the README heading reads KVDesk, the body of that document and every build output use ValeDesk, the npm package is valera, and the GitHub releases are titled LocalDesk. Local state is written to ~/.valera, so search for both spellings when you look through a checkout.
How do I point NeuralDeskApp at a local model instead of OpenAI?
Start a local server first, then set the Base URL in Settings to its /v1 endpoint, for example http://localhost:11434/v1 after ollama serve or http://localhost:8000/v1 after a vLLM launch. Enter dummy-key as the API Key for local models that do not check authentication, and give the Model Name you started the server with.
Does NeuralDeskApp run on Windows today?
The README marks the Windows build as coming soon because it requires cross-compilation setup, and it points you at the .github/workflows directory for CI builds instead. The Makefile already carries PowerShell branches for the dependency and Rust checks, but the documented application bundle is a macOS DMG built with make bundle.
What stops a NeuralDeskApp agent from looping on the same tool forever?
Loop detection triggers when five or more sequential calls go to the same tool. Separately, LLM requests have a five minute timeout with an automatic retry, and streaming can be interrupted at any point during a response.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/vakovalskii-neuraldeskapp)