* fix(cli): harden TUI diagnostics, keyring migration, and home paths Problem: - Interactive TUI freezes left zero-byte cli-tui logs and unrecoverable terminals on Windows ConPTY and stuck D-Bus startups (#7435, #7507). - Global hooks/doctor/capdiag could miss the real Reasonix home on Windows AppData and REASONIX_HOME isolation (#7411, #7331). - Legacy keyring migration blocked startup when Secret Service hung. - #7600's automatic HOME rewrite risked breaking isolation contracts. Root cause: - Diagnostics started after heavy work and never flushed milestones/heartbeats. - Hooks resolved global settings via derived ~/.reasonix rather than the exact Reasonix home used by the rest of the product. - Keyring probes ran unbounded per key with file import ordered after D-Bus. - Subprocess HOME rewriting conflates service HOME with Reasonix isolation. Fix: - Start TUI diagnostics before config/controller work; record milestones and flush immediately; 1s heartbeat with 10s stall → goroutine dump + Program.Kill. - Unify hook/capdiag/doctor on exact ReasonixHomeDir; public paths show <reasonix-home>. - Legacy credential migration: files first, then shared 1s keyring budget with empty-success markers; timeout leaves no marker for retry. - Doctor warns when process HOME ≠ account home without REASONIX_HOME; do not auto-rewrite subprocess HOME (#7600 not adopted). Verification: - go test ./internal/cli ./internal/config ./internal/hook ./internal/capdiag ./internal/doctor -count=1 Co-authored-by: Zhiyao Wen <[email protected]> Co-authored-by: zhaotian1 <[email protected]> * fix(cli): isolate keyring probes and tighten migration markers Problem: - In-process keyring timeouts could leave hung D-Bus goroutines and collapse found/absent/error/timeout into a single false, risking wrong migration-done markers (#7507 audit). - Keyring markers also skipped legacy credential *file* import. - doctor HOME warning leaked absolute account paths into shareable reports. - lint failed on an unused diagnostics mutex; CodeQL flagged SHA-256 of env names as secret-like storage. Root cause: - Timeout wrappers cannot cancel platform keyring calls in-process. - skip() treated keyring markers as global migration completion. - redactHome only knows the process HOME, not the OS account home. Fix: - Run legacy keyring batch probes in an isolated helper child with a shared 1s deadline; parent Kill+Wait on timeout (no parent goroutine leak). - Four-state outcomes: found / absent / error / timeout; write markers only on confirmed absent. - File import always runs first; markers only filter keyring probes. - Marker paths use sanitized env names under legacy-keyring-checked/. - doctor reports HOME mismatch without embedding either path. - Watchdog WaitGroup drains before closing the diagnostic log file. Verification: - go test ./internal/config ./internal/doctor ./internal/cli ./internal/hook ./internal/capdiag -count=1 - go vet ./internal/cli ./internal/config ./internal/doctor * fix(cli): keyring four-state to metal and secret-free helper Problem: - Platform keyring probes still returned (string, bool), so D-Bus/unlock failures were treated as absent and could write migration markers. - The isolated helper printed keyring secrets on stdout, making any process that can launch reasonix a credential oracle. - Watchdog Close waited only 2s, so a stuck Stack/Sync/Kill could write a closed diagnostic file. - Marker names folded distinct keys onto "_" collisions. Root cause: - Four-state status stopped at the batch layer; the Secret Service path collapsed every error to false. - Helper was designed as a value RPC instead of an in-child store step. - Close used a timed wait instead of joining the watchdog fully. Fix: - legacyKeyringProbe returns found/absent/error at the platform layer (ErrNotFound/empty search → absent; transport/unlock/session errors → error). - Helper stores found secrets via StoreCredentialLines and emits only key+status metadata on stdout (no value field). - Parent never receives secret Values from the helper path; markers only on confirmed absent. - Watchdog WaitGroup is joined fully before closing the log file. - Marker basenames use base64.RawURLEncoding of the env name. Verification: - go test ./internal/config ./internal/cli ./internal/doctor -count=1 - New tests: error does not write marker; helper JSON has no secrets; RawURL marker collision-free; four-state in-process outcomes * fix(cli): drop keyring helper oracle; atomic store-if-absent Problem: - The REASONIX_LEGACY_KEYRING_HELPER entrypoint let any process that can launch reasonix dump keyring secrets into a caller-controlled REASONIX_HOME/.env (disk oracle after stdout was scrubbed). - Legacy import could overwrite a concurrent settings write or tombstone because presence was checked outside the credential lock. Root cause: - Migration used an external helper to bound D-Bus hangs, which reopened a secret export surface via StoreCredentialLines + controllable home. - store used unconditional StoreCredentialLines after a TOCTOU check. Fix: - Remove the helper entrypoint entirely (main + env dispatch). - Linux/BSD Secret Service probes use godbus CallWithContext under a shared 1s batch deadline so stuck D-Bus calls cancel in-process. - Found secrets are written only via storeCredentialIfAbsentAndNotCleared (same advisory lock re-checks missing/not-cleared before write). - Channel-forced tests cover user-value and tombstone races without sleep. Verification: - go test ./internal/config ./internal/cli ./internal/doctor -count=1 - REASONIX_LEGACY_KEYRING_HELPER=1 reasonix --version is a normal version print (no helper path, no oracle home writes) * fix(cli): private ctx-bound D-Bus keyring and real probe races Problem: - dbus.SessionBus left process-global godbus workers that failed goleak under Ubuntu/race/coverage. - GetProperty and session Close used non-context call paths, so a stuck bus could still hang CLI past the 1s migration budget. - Race tests called store-if-absent directly and never forced the production probe→store window. Root cause: - Shared SessionBus + GetProperty(Background) escaped the batch ctx. - Channel tests interleaving happened outside lookupLegacyKeyringBatch. Fix: - Open a private ConnectSessionBus per probe, race Dial/Auth/Hello against the shared ctx, and always Close the connection. - Resolve Collections and Close sessions only via CallWithContext(ctx). - Drive store-if-absent races through a blocking probe stub inside lookupLegacyKeyringBatch (user write and tombstone cases). - go mod tidy promotes godbus to a direct dependency. Verification: - go test ./internal/config -count=1 - go test -race ./internal/config -count=1 - go test ./internal/control -count=1 * fix(cli): bind keyring bus connect to batch context Problem: - ConnectSessionBus had no dbus.WithContext, so a stuck Auth/Hello after Dial could keep the connect goroutine and late reaper parked forever even though the caller returned at 1s. Root cause: - Connection lifecycle was only raced externally; godbus never received the migration ctx to Close the transport on deadline. Fix: - SessionBusPrivateNoAutoStartup(dbus.WithContext(ctx)) then Auth+Hello, so cancel closes the transport and unblocks Auth/Hello I/O. - Avoid dbus-launch (NoAutoStartup): missing session address fails closed instead of hanging in CombinedOutput. - Outer select still bounds the caller; late *Conn is always closed. - Document residual: pure Dial hang before newConn remains a godbus limit. Verification: - go test ./internal/config -count=1 - go test -race ./internal/config -count=1 - go test ./internal/control -count=1 - GOOS=linux go test ./internal/config -c * ci: allow Windows smoke runner variance Problem: The Windows smoke step regularly takes 7-9 minutes and the current run exceeded its 10-minute job budget even though vet and build succeeded. Root cause: The job-level timeout leaves too little headroom for hosted Windows runner variance. Fix: Raise only the pull-request Windows smoke job budget to 15 minutes while retaining the per-package 3-minute Go test timeout. Verification: YAML parse; git diff --check; go test ./internal/cli ./internal/config -count=1. --------- Co-authored-by: Zhiyao Wen <[email protected]> Co-authored-by: zhaotian1 <[email protected]>
English · 简体中文 · Guide · ACP · Extensions · Spec · Website · Discord
A DeepSeek-native AI coding agent for your terminal.
A config- and plugin-driven harness — a single static Go binary, tuned around DeepSeek's prefix cache so token costs stay low across long sessions.
Important
Community · 加入社区 — bilingual Discord for setup help (
#help/#求助), workflow showcases, and feature ideas. → https://discord.gg/XF78rEME2D
Features
- Config-driven. Providers, the agent, enabled tools, and plugins are all
declared in
reasonix.toml. No hardcoded models. - Multi-model & composable. DeepSeek ships as a preset; any OpenAI-compatible endpoint is a config entry, not new code. Optionally run two models together (executor + planner) in separate, cache-stable sessions.
- Plugin-driven. MCP servers contribute tools, prompts, and resources; Extension Protocol v1 sidecars can also intercept runtime events, contribute Providers and structured UI, and ship versioned plugin packages.
- Cache-aware context maintenance. Startup injects a small stable environment summary, stale tool output is snipped/pruned before summary compaction, and the built-in tool schema contract is documented for regression review.
- Zero-friction distribution.
CGO_ENABLED=0single binary; cross-compile to six targets with one command. The only dependency is a TOML parser.
Install
Choose the path that matches how you want to use Reasonix. The CLI/TUI, desktop app, and VS Code extension all use the same local Reasonix engine.
Path A: CLI / TUI
Install the native binary through npm on any supported platform, or use Homebrew on macOS:
npm i -g reasonix # any OS; pulls the prebuilt native binary
brew install esengine/reasonix/reasonix # macOS
Prebuilt archives (darwin|linux|windows × amd64|arm64) and SHA256SUMS are on
every GitHub release.
Path B: Desktop app
Use the official download page for the latest desktop build.
| Platform | Package | Architecture |
|---|---|---|
| macOS | Universal .dmg or .zip |
Apple Silicon / Intel |
| Windows | Installer .exe or portable .zip |
x64 / ARM64 |
| Linux | .deb or .tar.gz |
x64 |
Windows installers are code-signed through SignPath.io with a free certificate provided by the SignPath Foundation.
Path C: VS Code extension
Complete Path A first. The extension does not bundle the CLI; it starts your
local reasonix acp backend and adds native chat, editor context, tool-call
approvals, model selection, and workspace sessions.
- VS Code: install from Visual Studio Marketplace
- VSCodium / Eclipse Theia: install from Open VSX Registry
- Extension ID:
SivanLiu.reasonix-agent· source and usage guide
Path D: Build from source
git clone https://github.com/esengine/DeepSeek-Reasonix.git
cd DeepSeek-Reasonix
make build # -> bin/reasonix(.exe)
make cross # -> dist/ (darwin|linux|windows × amd64|arm64)
Quick start
CLI / TUI
These commands are for the CLI/TUI installed through Path A:
reasonix setup # configure a provider and model
reasonix # start an interactive session
reasonix run "implement the TODOs in main.go"
In an interactive session, run /init when you want Reasonix to create project
instructions.
Desktop app
Download the installer for your platform from the official download page, install and launch Reasonix, then configure a provider and model in the app. The CLI commands above are not required for the desktop app.
For advanced CLI usage and configuration, see the CLI reference, Guide, and configuration paths.
Documentation
- Getting started: Guide · CLI reference · Configuration paths · ACP editor integration
- Features & troubleshooting: Subagent profiles · Context Engine v2 · Capability diagnostics · Recovery and updates · Bot guide · Checkpoints & rewind
- Engineering & migration: Spec · Task contracts & pause policy · Tool contract · Migrating from 0.x
- Extension development: Extensions · Plugin packages and Manifest v1 · Extension Protocol · Go SDK and starter
Star History
Acknowledgments
A small list of folks whose work has shaped Reasonix the most — the current top 20 contributors by commit count. The full contributor graph is on GitHub.
| Contributor | Contributor | Contributor | Contributor |
|---|---|---|---|
| SivanCola | esengine | ttmouse | lifu963 |
| reasonix (anonymous) | HUQIANTAO | GTC2080 | light-front-theory |
| merge-order-check (anonymous) | Li-Charles-One | eghrhegpe | wufengfan (anonymous) |
| CVEngineer66 | dependabot[bot] | lanshi17 | SuMuxi66 |
| CnsMaple | cyq1017 | JesonChou | XTLine |
Also a separate thank-you to Bernardxu123 for designing the project logo, and to AIGC Link for promoting the project on XiaoHongShu.
MIT — see LICENSE
Built by the community at esengine/DeepSeek-Reasonix
Support this project
If Reasonix has been useful and you'd like to say thanks, you can. It stays a coffee, not a contract — donations don't buy feature priority or change how issues get triaged.
- International — PayPal: paypal.me/yuhuahui
- 国内 — 微信支付(扫码)
