mirror of
https://github.com/awizemann/scarf.git
synced 2026-05-10 18:44:45 +00:00
424711c3d9
Reported on iOS: dashboard shows "Connection issue / Citadel.SSH
Client.CommandFailed error 1", memory files (USER.md, SOUL.md) load
fine but Sessions / Activity / Tool Calls all show 0. The snapshot
operation that pulls ~/.hermes/state.db over SFTP via `sqlite3
.backup` was failing on the remote, but the iOS user got zero
actionable context.
Two latent bugs in CitadelServerTransport.asyncSnapshotSQLite —
both fixed in v2.5.0 for asyncRunProcess but missed on this path:
1. `executeCommand` throws CommandFailed on non-zero exit AND
discards the captured stderr buffer. So when sqlite3 is missing
(slim Docker images, statically-linked installs) or state.db
doesn't exist, the user only saw "error 1" and a generic
connection-issue banner with no remediation.
2. No `PATH=...` prefix. asyncRunProcess inline-prepends
`PATH="$HOME/.local/bin:/opt/homebrew/bin:/usr/local/bin:$PATH"`
so bare command resolution works on Citadel's stripped-PATH
exec channel; the snapshot path didn't, so any sqlite3 install
outside /usr/bin failed at exit 127 ("command not found").
Mirror the asyncRunProcess hardening on the snapshot path:
- Prepend the same PATH prefix so sqlite3 resolves on hosts where
it lives at /usr/local/bin or /opt/homebrew/bin.
- Drive `executeCommandStream` instead of `executeCommand`.
Capture stdout + stderr regardless of exit code.
- On non-zero exit, throw an NSError carrying the real stderr (or
stdout if stderr is empty — sqlite3 sometimes errors via stdout
depending on the remote shell). HermesDataService.humanize
already keys off "sqlite3: command not found" /
"permission denied" / "no such file" substrings, so once the
real message reaches it the dashboard banner becomes actionable
("sqlite3 is not installed on <host>. Install with apt install
sqlite3..." instead of the generic CommandFailed error).
- When the stream itself fails to start (network/auth-level), throw
with a "Failed to start snapshot stream" message so the connect-
level error path is distinguishable from the remote-exec failure.
iOS-only — Mac path was already correct.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>