The shared mesh-constants.ts module imported by both the main process
and renderer may cause Vite bundling issues. Inline the constants in
main.ts and MeshSettings.tsx instead.
Signed-off-by: jh-block <jhugo@block.xyz>
The top-level promisify(execFile) call caused a renderer crash on
startup. Replace with a simple promise-wrapping helper function that
avoids module-scope side effects.
Signed-off-by: jh-block <jhugo@block.xyz>
The promisify(execFile) statement was placed between import
declarations, breaking ESM module evaluation order and causing React
hooks to be null at app startup.
Signed-off-by: jh-block <jhugo@block.xyz>
Store the 5-minute startup timeout in a ref and clear it on each new
startMesh call, preventing a stale timer from interrupting a valid
retry with a false failure message.
Signed-off-by: jh-block <jhugo@block.xyz>
Only show the Download mesh-llm button on arm64 Macs, matching the
backend guard. Intel Macs now see only the install guide link. Expose
process.arch via the electron preload bridge to support the check.
Signed-off-by: jh-block <jhugo@block.xyz>
Replace execFileSync calls (curl, tar, codesign, xattr) with
promisified execFile so Electron's main event loop stays responsive
during mesh-llm download and installation.
Signed-off-by: jh-block <jhugo@block.xyz>
- check-mesh: verify HTTP 200 status and that response data is an array
with string IDs before marking mesh as running, preventing false
positives from other services on port 9337 or JSON error responses
- SettingsView: block section=mesh deep-link when tunnelDisabled, and
reset activeTab to models if mesh tab becomes unavailable, matching
the existing local-inference availability pattern
Signed-off-by: jh-block <jhugo@block.xyz>
- Store meshProviderId in localStorage so reopening Settings finds the
previously created provider instead of creating duplicates
- Gate auto-download on process.arch === 'arm64' in addition to darwin
check, since the bundled binaries are Apple Silicon only
Signed-off-by: jh-block <jhugo@block.xyz>
- Track mesh provider ID in state so subsequent activations look up the
correct ID returned by createCustomProvider (e.g. custom_inference_mesh)
instead of always querying for 'mesh', which caused duplicate providers
- Replace shell-interpolated execSync calls in download-mesh with
execFileSync argument arrays for curl, tar, codesign, and xattr to
avoid path-dependent failures (e.g. apostrophes in home directory)
- Download to temp tarball then extract, with cleanup in finally block
Signed-off-by: jh-block <jhugo@block.xyz>
The node version bump was unintentionally included in a mesh settings
commit. Restore bin/ symlinks to match main.
Signed-off-by: jh-block <jhugo@block.xyz>
- stopMesh: check result.stopped before updating UI state
- stop-mesh IPC: return { stopped: false } when binary is not found
- start-mesh IPC: close log file descriptor after spawn to prevent fd leak
- start-mesh IPC: wait 500ms for early spawn errors (permissions, ENOENT)
- check-mesh: prioritize API probe over install check so running mesh
from an undiscovered path is detected correctly
- stop-mesh IPC: use execFileSync instead of execSync to avoid shell
metacharacter injection risk
- Remove redundant ensureMeshProvider IPC that wrote mesh.json directly;
use REST API create-or-update pattern exclusively for atomic file
writes and registry refresh
- Remove ensureMeshProvider from preload.ts and main.ts IPC handlers
- Replace dynamic imports of Node builtins (os, path, fs, child_process,
http) with top-level imports, eliminating per-call overhead and .default
access patterns
- Extract shared port/model constants to mesh-constants.ts, imported by
both main.ts and MeshSettings.tsx to eliminate duplication
Signed-off-by: jh-block <jhugo@block.xyz>
Writing mesh.json directly ensures the ID is 'mesh', but the running
goosed server doesn't know about it until its registry is refreshed.
After writing the file, call updateCustomProvider via the API which
triggers refresh_custom_providers() server-side. Then setConfigProvider
can find the 'mesh' provider.
Signed-off-by: Michael Neale <michael.neale@gmail.com>
1. Write mesh.json directly to custom_providers/ via IPC instead of
using the create API (which generates an unpredictable ID from the
display name). Ensures the provider is always 'mesh' so
setConfigProvider works on fresh installs.
2. Add 5-minute timeout on 'starting' state so the UI doesn't get
stuck if mesh-llm crashes on startup. Shows log path in error.
3. Add privacy warning to auto-discover: public meshes are run by
volunteers, prompts are sent to their hardware.
Signed-off-by: Michael Neale <michael.neale@gmail.com>
Reuse the existing GOOSE_TUNNEL=no flag (already set by bundle.py
for corporate builds) to hide the Mesh tab. When tunnel is disabled,
mesh is hidden too — same intent: no external network features.
Removes the GOOSE_MESH_ENABLED variable added in the previous commit.
Signed-off-by: Michael Neale <michael.neale@gmail.com>
Mesh tab is shown by default (open-source). Set env var
GOOSE_MESH_ENABLED=false to hide the tab entirely — for use
in bundled/enterprise builds via goose-releases.
Signed-off-by: Michael Neale <michael.neale@gmail.com>
Remove pl-6 indent — the checkbox applies to both auto and join
modes equally, not as a sub-option of a specific radio button.
Signed-off-by: Michael Neale <michael.neale@gmail.com>
- Mark as 'Experimental' in the description
- Link to docs.anarchai.org as 'Learn more' and inline doc link
- Not-installed panel: show Download button on macOS, Install guide
link on all platforms, no platform-shaming messaging
- Consistent tone: this is a new thing, use with care
Signed-off-by: Michael Neale <michael.neale@gmail.com>
The release bundle is aarch64 macOS (Apple Silicon) only. On other
platforms, show a note instead of the download button and suggest
manual install. Also guard the IPC handler server-side.
Signed-off-by: Michael Neale <michael.neale@gmail.com>
After activating a mesh model, call refreshCurrentModelAndProvider()
so the existing chat window picks up the new provider/model
immediately — same pattern as LocalInferenceSettings.
Signed-off-by: Michael Neale <michael.neale@gmail.com>
Status was set to 'checking' which triggered the useEffect (depends
on status), which recreated the interval, which called checkStatus
again — infinite loop.
Fix: separate 'checking' into a boolean flag that doesn't affect
the polling interval. The status enum only holds stable states
(stopped/running/starting/etc). The checking spinner shows inline
on the current status indicator instead of replacing it.
Signed-off-by: Michael Neale <michael.neale@gmail.com>
When mesh-llm isn't found on PATH or ~/.local/bin or ~/.mesh-llm,
the Mesh settings tab shows a 'Download mesh-llm' button (~19 MB).
Downloads the release bundle from GitHub, extracts to ~/.mesh-llm/,
and codesigns + clears quarantine on macOS. Once downloaded, the
setup panel (start/join/auto) unlocks.
Binary lookup order: PATH > ~/.mesh-llm/ > ~/.local/bin/
Shared findMeshBinary() used by all three IPC handlers.
Signed-off-by: Michael Neale <michael.neale@gmail.com>
Settings > Mesh tab for integrating with mesh-llm:
- Start a new private mesh (pick a model from catalog)
- Join with invite token (optionally contribute GPU)
- Auto-discover public meshes
- View live models and select one as Goose's provider
- Copy invite token to share with others
- Open web console (localhost:3131)
- Stop mesh from UI
Architecture: no new Rust provider needed. mesh-llm exposes an
OpenAI-compatible API on localhost:9337. The UI creates/updates a
custom provider ('mesh') pointing at that endpoint via the existing
declarative provider system.
Electron spawns mesh-llm detached (it's a daemon — survives Goose
quit, serves peers, keeps models loaded). Same pattern as Ollama:
check if running, don't own the process lifecycle.
IPC handlers: check-mesh (probes API + console for status/token/peers),
start-mesh (spawns detached with mode-specific args), stop-mesh
(runs 'mesh-llm stop').
Signed-off-by: Michael Neale <michael.neale@gmail.com>
The ui/acp/.npmrc file with registry= prevents npm from inheriting
the auth token from the parent ui/.npmrc during publishing.
This is the same fix that was applied to ui/text/.npmrc in a36ca9a.
Fixes the ENEEDAUTH error in the publish-npm workflow.
Signed-off-by: Alex Hancock <alexhancock@block.xyz>