The test's name says "report_no_remote" but its push assertion still
expected the pre-fix behavior ("error"). After 6d97335d made has_remote
URL-aware, git_push on a vault with no URL-bearing remote short-circuits
with "no_remote" — matching the test name and the pull assertion above.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sibling to the has_remote fix on this branch (6d97335d). Plain `git remote`
lists remote names defined in any config layer, so a [remote "origin"]
section inherited from ~/.gitconfig (e.g. with `prune = true`) made
list_remotes return ["origin"] for fresh local vaults. That broke
git_add_remote (returned "already_configured") and silently neutered
disconnect_all_remotes.
Reuse remote::remote_line_has_url to parse `git remote -v` output and
keep only remotes with a non-empty URL column. Dedupe by name across
the (fetch)/(push) line pair.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`has_remote()` ran bare `git remote`, which lists every remote name from
any config layer — so a `[remote "origin"]` section inherited from the
user's `~/.gitconfig` (e.g. with only `prune = true`) made every vault
look remote-backed. `git_pull` then ran `git pull --no-rebase`, hit
"no tracking information", and the status bar surfaced "Sync failed".
Parse `git remote -v` and require at least one line with a non-empty URL
column. Mirror the guard on `git_push` so direct callers return
`no_remote` instead of issuing a doomed push. Handle `no_remote`
explicitly in `useAutoSync.performPull` / `pullAndPush` / `handlePushResult`
so the frontend short-circuits the push step and keeps a neutral status.
Fixes: https://github.com/refactoringhq/tolaria/issues/734
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Fixes#695
`where claude` on Windows returns both the npm-generated POSIX shell
wrapper (extensionless) and the Windows batch shim (`claude.cmd`)
side-by-side. The existing `path_from_successful_output` helpers in
`claude_cli.rs` and `codex_cli.rs` picked the first existing line,
which gave the POSIX wrapper - Windows tried to load it as a PE32,
`CreateProcessW` returned ERROR_BAD_EXE_FORMAT (193), and the AI chat
panel surfaced "%1 is not a valid Win32 application."
Mirror the fix that landed for Gemini in `gemini_discovery.rs`: when
`cfg!(windows)`, filter candidates through the existing shared utility
`cli_agent_runtime::has_windows_cli_extension` so .bat/.cmd/.com/.exe
win over extensionless POSIX scripts. Non-Windows behavior is unchanged.
Added a regression test in each file matching the
`windows_path_lookup_prefers_cmd_shim_over_extensionless_npm_script`
pattern from gemini_discovery.rs.
Fixes#705
GUI launches of the AppImage on Linux do not inherit the shell PATH, so
`find_on_path` and `find_in_user_shell` cannot reach Homebrew-on-Linux's
Node install. Add the canonical Linuxbrew paths to `fallback_node_paths`
and to `node_binary_candidates_for_home`; `.is_file()` filtering keeps
machines without Linuxbrew unaffected.
Tolaria's MCP server is pure ESM with only standard `node:fs|path|http|child_process`
imports and pure-JS dependencies, so Bun can execute it identically to Node.
Until now `find_node()` was the single entry point for spawning the WebSocket
bridge and writing external AI tool config — users with Bun but no Node would
hit "node not found in PATH or common install locations" and lose access to MCP
tools entirely.
Introduce `find_mcp_runtime()` which returns the first verifying runtime,
preferring Node 18+ when present and falling back to Bun 1+. The generic
PATH and login-shell lookup helpers (`find_on_path`, `find_in_user_shell`,
`lookup_command`, `lookup_paths`) are now parameterised by command name so
both runtimes share the same machinery. Bun candidates cover `~/.bun/bin/bun`,
mise/asdf/proto shims, Homebrew, and `%USERPROFILE%\.bun\bin\bun.exe` on
Windows. The Codex CLI and Windows .cmd-shim resolution paths keep using the
strict `find_node()` since they specifically need Node.
`spawn_ws_bridge_with_paths`, `mcp_config_snippet`, and `register_mcp` now
resolve through `find_mcp_runtime` so the runtime that gets registered into
`~/.claude.json`, `~/.gemini/settings.json`, `~/.cursor/mcp.json`, etc.
matches the one actually present on the machine.
Locale copy updated from "nodeRequirement" to "runtimeRequirement" across
all 15 catalogs to reflect "Node.js 18+ or Bun 1+".
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Port the useful dynamic-vault MCP direction from Domenico Lupinetti's proposal into the current mounted-workspace model.
Durable external MCP registration is now vault-neutral, Node MCP resolves active mounted vaults from explicit env or Tolaria vaults.json, and vault context includes root AGENTS.md instructions per active vault.
Based-on: https://github.com/refactoringhq/tolaria/pull/603
Co-authored-by: Domenico Lupinetti <domenico@translated.net>