docs: Scarf v2.5.1 patch — Core-Services, index, Home

Alan Wizemann
2026-04-27 15:22:45 +02:00
parent 60233169b5
commit 7b80f7fa19
3 changed files with 15 additions and 5 deletions
+9 -2
@@ -18,6 +18,13 @@ In v2.5 most service code moved out of the Mac target into the shared **ScarfCor
| [`ProjectDashboardService`](https://github.com/awizemann/scarf/blob/main/scarf/scarf/Core/Services/ProjectDashboardService.swift) | `Sendable struct` | ~71 | Loads/saves the project registry and per-project `.scarf/dashboard.json`. |
| [`UpdaterService`](https://github.com/awizemann/scarf/blob/main/scarf/scarf/Core/Services/UpdaterService.swift) | `@MainActor @Observable` | ~41 | Thin Sparkle wrapper exposing the auto-check toggle, last-check date, and a "check now" trigger. |
## v2.5.1 additions (in ScarfCore)
| Service | Isolation | Purpose |
|---|---|---|
| `HermesProfileResolver` | `Sendable enum` | Reads `~/.hermes/active_profile` and resolves the effective Hermes home path so every derived path (`stateDB`, `sessionsDir`, `configYAML`, `memoriesDir`, `cron/jobs.json`, `auth.json`, plugins, gateway state, logs) automatically follows the active Hermes v0.11+ profile. Validation regex mirrors `hermes_cli/profiles.py` exactly (`[a-z0-9][a-z0-9_-]{0,63}`); invalid or missing profiles fall back to `~/.hermes` with a logger warning. 5-second `OSAllocatedUnfairLock`-backed cache so frequent path-set construction doesn't hammer the filesystem. Backs `HermesPathSet.defaultLocalHome`. See [#50](https://github.com/awizemann/scarf/issues/50). |
| `SSHScriptRunner` | `Sendable enum` | Single shared entry point for running multi-line shell scripts on a `ServerContext`, **without** going through `ServerTransport.runProcess`'s argument quoting (which is correct for paths but mangles scripts containing `"$VAR"` references and nested quotes). Invokes `/usr/bin/ssh ... -- /bin/sh -s` directly with the script piped via stdin so it travels as opaque bytes. macOS-only via `#if os(macOS)` (`Foundation.Process` isn't on iOS); iOS uses Citadel transports for its own flows. Used by `ConnectionStatusViewModel` (15s heartbeat) AND `RemoteDiagnosticsViewModel` so both probes always agree on what the remote sees. See [#44](https://github.com/awizemann/scarf/issues/44). |
## v2.5 additions (in ScarfCore — shared across Mac + iOS)
| Service | Isolation | Purpose |
@@ -35,7 +42,7 @@ In v2.5 most service code moved out of the Mac target into the shared **ScarfCor
| Service | Purpose |
|---|---|
| `KeychainSSHKeyStore` | Per-server Ed25519 keypair persistence in the iOS Keychain (`com.scarf.ssh-key` service, `kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly`). v2 multi-server format: account `"server-key:<UUID>"`. Auto-migrates v1 (`"primary"` account) on first `listAll`. Wipe via single `SecItemDelete`. |
| `KeychainSSHKeyStore` | Per-server Ed25519 keypair persistence in the iOS Keychain (`com.scarf.ssh-key` service). Default accessibility `kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly` + `kSecAttrSynchronizable=false`; in v2.5.1 a `SSHKeyICloudPreference` opt-in (System → Security toggle) flips writes to `kSecAttrAccessibleAfterFirstUnlock` + `kSecAttrSynchronizable=true` so iCloud Keychain syncs the key across the user's Apple devices ([#52](https://github.com/awizemann/scarf/issues/52)). Read / list / delete queries unconditionally pass `kSecAttrSynchronizable=kSecAttrSynchronizableAny` so they match items regardless of sync state. v2 multi-server format: account `"server-key:<UUID>"`. Auto-migrates v1 (`"primary"` account) on first `listAll`. Public `migrateAllItems(toICloudSync:)` re-saves every stored bundle with target attributes — idempotent. |
| `CitadelSSHService` | Pure-Swift Ed25519 keypair generation + connection probes via Citadel. Used by Onboarding's "Generate Key" + "Test Connection" steps. |
| `CitadelServerTransport` | Citadel-backed implementation of `ServerTransport` — drives `executeCommandStream` for resilient stdout capture (preserves output on non-zero exit) and prepends `PATH=$HOME/.local/bin:/opt/homebrew/bin:/usr/local/bin:$PATH` so non-interactive sessions resolve `hermes` and its sub-tools without sourcing user shell rc files. |
@@ -56,4 +63,4 @@ See [ScarfCore Package](ScarfCore-Package) for the package architecture and how
See [Adding a Service](Adding-a-Service) for the recipe. Short version: take `ServerContext` in `init`, decide isolation (`actor` for stateful, `struct` for stateless), expose async public methods, route I/O through `context.transport`.
---
_Last updated: 2026-04-25 — Scarf v2.5.0 (ScarfCore extraction + 9 new services)_
_Last updated: 2026-04-27 — Scarf v2.5.1 (HermesProfileResolver + SSHScriptRunner; iCloud Keychain sync option on KeychainSSHKeyStore)_
+2 -2
@@ -2,7 +2,7 @@
A native macOS companion app for the [Hermes AI agent](https://github.com/hermes-ai/hermes-agent). Full visibility into what Hermes is doing, when, and what it creates — across one local install or many remote ones.
**Latest release:** [v2.5.0](https://github.com/awizemann/scarf/releases/tag/v2.5.0) — ScarfGo iOS companion + ScarfDesign overhaul + Hermes v0.11 chat parity.
**Latest release:** [v2.5.0](https://github.com/awizemann/scarf/releases/tag/v2.5.0) — ScarfGo iOS companion + ScarfDesign overhaul + Hermes v0.11 chat parity. Patched in [v2.5.1](https://github.com/awizemann/scarf/releases/tag/v2.5.1) (Mac chat performance, Hermes v0.11 profile awareness, iOS keyboard dismissal, opt-in iCloud Keychain sync, chat density preferences — see [release notes](https://github.com/awizemann/scarf/blob/main/releases/v2.5.1/RELEASE_NOTES.md)).
**Latest mobile:** [Join the public TestFlight](https://testflight.apple.com/join/qCrRpcTz). The link is live now but only accepts new beta testers once Apple's Beta Review approves the first build — see [ScarfGo](ScarfGo) for the full feature tour.
**Targets Hermes:** v0.11.0 (v2026.4.23) — `/steer`, new state.db columns, design-md/spotify skills, SKILL.md frontmatter chips. v0.10.0 still works for everything that didn't change.
**Available in:** English, Simplified Chinese (zh-Hans), German (de), French (fr), Spanish (es), Japanese (ja), Brazilian Portuguese (pt-BR). See [Localization](Localization). _ScarfGo is English-only in v1._
@@ -40,4 +40,4 @@ Scarf 2.0 is a multi-window app — one window per Hermes server, local or remot
Open-source (MIT), 160+ stars, actively maintained. See [Roadmap](Roadmap) for what's coming.
---
_Last updated: 2026-04-25 — Scarf v2.5.0 + ScarfGo public TestFlight_
_Last updated: 2026-04-27 — Scarf v2.5.1 patch (Mac + iOS bugfixes + chat density + iCloud Keychain sync)_
+4 -1
@@ -4,6 +4,7 @@ Every Scarf release in chronological order. The notes themselves live in `releas
| Version | Date | GitHub release | Notes file |
|---|---|---|---|
| **v2.5.1** | 2026-04-27 | [v2.5.1](https://github.com/awizemann/scarf/releases/tag/v2.5.1) | [`releases/v2.5.1/RELEASE_NOTES.md`](https://github.com/awizemann/scarf/blob/main/releases/v2.5.1/RELEASE_NOTES.md) |
| **v2.5.0** | 2026-04-25 | [v2.5.0](https://github.com/awizemann/scarf/releases/tag/v2.5.0) | [`releases/v2.5.0/RELEASE_NOTES.md`](https://github.com/awizemann/scarf/blob/main/releases/v2.5.0/RELEASE_NOTES.md) |
| **v2.3.0** | 2026-04-24 | [v2.3.0](https://github.com/awizemann/scarf/releases/tag/v2.3.0) | [`releases/v2.3.0/RELEASE_NOTES.md`](https://github.com/awizemann/scarf/blob/main/releases/v2.3.0/RELEASE_NOTES.md) |
| **v2.2.1** | 2026-04-23 | [v2.2.1](https://github.com/awizemann/scarf/releases/tag/v2.2.1) | [`releases/v2.2.1/RELEASE_NOTES.md`](https://github.com/awizemann/scarf/blob/main/releases/v2.2.1/RELEASE_NOTES.md) |
@@ -19,6 +20,8 @@ Every Scarf release in chronological order. The notes themselves live in `releas
## Highlights by major
**2.5.1** — Patch release bundling every reported issue against 2.5.0 plus TestFlight-driven iOS fixes. Mac chat O(n)-per-token rendering bog-down on long sessions ([#46](https://github.com/awizemann/scarf/issues/46)) — settled bubbles now short-circuit body re-eval via `Equatable`, trailing-group patch helper replaces full `buildMessageGroups()` per chunk. Hermes v0.11 profile awareness ([#50](https://github.com/awizemann/scarf/issues/50)) — new `HermesProfileResolver` reads `~/.hermes/active_profile`, every derived path follows automatically, SessionInfoBar gains a profile chip. Granular reasons + actionable hint popover on the "Connected — can't read Hermes state" pill ([#53](https://github.com/awizemann/scarf/issues/53)). Pill probe and Run Diagnostics no longer disagree ([#44](https://github.com/awizemann/scarf/issues/44)) — both now go through a shared `SSHScriptRunner` that bypasses `runProcess`'s argument quoting. New chat density preferences in Settings → Display ([#47](https://github.com/awizemann/scarf/issues/47) + [#48](https://github.com/awizemann/scarf/issues/48)) — Tool calls Full / Compact / Hidden, Reasoning Disclosure / Inline / Hidden, chat font size 85130%. iOS keyboard now dismissable via swipe + accessory toolbar ([#51](https://github.com/awizemann/scarf/issues/51)); first-run Cancel button hidden when there's nothing to cancel back to ([#55](https://github.com/awizemann/scarf/issues/55)); opt-in iCloud Keychain sync for SSH keys ([#52](https://github.com/awizemann/scarf/issues/52)) — pair iPhone + iPad without onboarding twice. Add Project on remote contexts now hides the local Browse button and shows a Verify-against-remote affordance ([#54](https://github.com/awizemann/scarf/issues/54)). Release pipeline gains a post-package codesign / spctl gate ([#49](https://github.com/awizemann/scarf/issues/49)). No data migrations.
**2.5****[ScarfGo](ScarfGo) iOS companion** ships in public TestFlight + full **Hermes v2026.4.23 (v0.11.0)** support: `/steer` non-interruptive guidance, per-turn stopwatch, numbered approval shortcuts, git branch chip in chat header, `messages.reasoning_content` + `sessions.api_call_count` columns surfaced. **Portable project-scoped slash commands** — author at `<project>/.scarf/slash-commands/<name>.md` and ship via `.scarftemplate` (schemaVersion 3); Mac authoring tab + iOS read-only browser. New skills: in-app **Spotify OAuth sheet** + **design-md npx prereq check**. SKILL.md frontmatter chips (`allowed_tools`, `related_skills`, `dependencies`). "What's New" pill on the Skills tab tracks per-server skill deltas. Mac global Sessions gets project filter + badges (parity with ScarfGo). Cross-platform `CronScheduleFormatter`, `GitBranchService`, `SkillSnapshotService`, `SkillPrereqService`, `ProjectSlashCommandService`, `SpotifyAuthFlow` consolidate into ScarfCore. See [Platform Differences](Platform-Differences) for the Mac↔iOS feature matrix.
**2.3** — [Projects sidebar grows up](https://github.com/awizemann/scarf/blob/main/releases/v2.3.0/RELEASE_NOTES.md): folders, rename, archive, search, ⌘1-9 keyboard jumps, per-project Sessions tab, and Scarf-managed `AGENTS.md` context block injected at chat-start so the agent always knows what project it's in. Catches up to Hermes v0.10.0's [Tool Gateway](Hermes-Version-Compatibility) — Nous Portal subscription routing, in-app sign-in, Health-tab visibility for tool routing.
@@ -44,4 +47,4 @@ When `scripts/release.sh <version>` completes a full (non-draft) release, this p
This is one of the [wiki update triggers](Wiki-Maintenance) that future Claude Code sessions will follow automatically.
---
_Last updated: 2026-04-25 — Scarf v2.5.0 + ScarfGo public TestFlight_
_Last updated: 2026-04-27 — Scarf v2.5.1 patch (Mac + iOS bugfixes + chat density + iCloud Keychain sync)_