Issue #79 — Browse Hub clearly listed "honcho" but searching for "honcho" with the source picker on "All Sources" returned nothing. Root cause is on the Hermes side: `hermes skills search <query>` without a `--source` flag routes through the centralized `hermes-index` source and skips the external API sources (skills-sh, github, clawhub, lobehub, well-known, claude-marketplace). Browse aggregates those sources too, so any skill that lives only in the API tier shows up in browse but disappears in search. Same picker, same query, contradictory results. Rather than chase Hermes's index gaps, redefine "All Sources" search in Scarf to mean filter-what-you-see — the canonical type-to-filter UX users already expect on a list. Source-specific searches keep the CLI shell-out for full upstream search semantics on that registry. Implementation: - New `lastBrowseResults` cache populated on every successful `browseHub()`. Setter is `internal` so the test suite can seed without invoking the live CLI; out-of-module callers can still only read. - `searchHub()` now branches on `hubSource`. The "all" branch filters the cache via `localizedCaseInsensitiveContains` against name, description, and identifier, runs synchronously on the calling actor (UI invocations are already on MainActor) so the user sees the narrowed list without a render-tick gap. - If the cache is empty (search-before-browse), `browseHubThenFilter` performs one CLI fetch, populates the cache, then applies the filter — failure surfaces a "Search failed" banner instead of a silent empty state. - Source-specific search still shells out to `hermes skills search <query> --source <s> --limit 40`. Adds five regression tests covering name match, description match, case-insensitive folding, no-match message state, and the empty-query fallthrough to browse. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Scarf
A native macOS companion app for the Hermes AI agent.
Full visibility into what Hermes is doing, when, and what it creates.
Available in English, 简体中文, Deutsch, Français, Español, 日本語, and Português (Brasil).
What's New in 2.7
The biggest release since 2.6 — six weeks of work focused on remote-context performance, a new project authoring flow, dashboard widgets, OAuth resilience, and a top-to-bottom performance instrumentation harness that drove the bulk of the rest. 36 commits, no schema bump, no Hermes capability bump.
Remote chats and Activity in seconds, not 30s timeouts
Resuming a chat or opening Activity on a slow remote (a 420ms-RTT droplet, an underprovisioned VPS, a tunnel through 4G) used to fetch the full message column set in one shot, which routinely tripped the 30s SSH timeout on chats with multi-page tool result blobs. v2.7 introduces a skeleton-then-hydrate pattern that bounds the wire payload by what the user actually needs to see RIGHT NOW, then fills in the heavy stuff in the background.
- Chat skeleton — user + assistant rows only (skips
role='tool'),tool_calls/reasoninghard-NULLed at SQL level. Wire payload bounded by conversational text. The chat appears in seconds. Background hydration pages tool calls in 5-id batches; tool-result CONTENT is opt-in (Settings → Display → "Load tool results in past chats", default off) with per-card lazy-fetch in the inspector pane. - Activity skeleton — metadata-only fetch (~3 KB for 50 rows). Placeholder rows render immediately; real per-call entries swap in as paged hydration completes.
- Single-id whale recovery — when a 5-id batch trips the 30s timeout (one row carries an oversized
tool_callsblob), an L1 single-id retry isolates the offender so the rest of the batch still hydrates.
SSH cancellation that actually cancels
Task.detached doesn't inherit cancellation from the awaiting parent. Pre-fix, navigating away from a chat left the underlying ssh subprocess running for the full 30s, pinning a remote sqlite query and a ControlMaster session — the "third chat hangs" / "dashboard spins after rapid switching" symptom. v2.7 wires withTaskCancellationHandler through SSHScriptRunner.run and RemoteSQLiteBackend.query; cancellation now reaches the Process within ~100ms.
New Project from Scratch wizard + Keychain-backed cron secrets
A third project entry point alongside Browse Catalog and Add Existing Project. Scaffolds a Scarf-standard skeleton, registers it, and hands off to a chat session that auto-activates the bundled scarf-template-author skill. The skill drives the rest conversationally — widgets, optional config schema, optional cron — and writes the final files itself.
Cron + Keychain. Cron prompts that referenced secret-typed config fields used to get the literal keychain://... URI back, producing 401s. v2.7 mirrors resolved Keychain values into ~/.hermes/.env under $SCARF_<UPPER_SLUG>_<UPPER_FIELD> env vars. Hermes already reloads .env per cron tick — credential rotation is automatic.
Project dashboards — file-reading widgets, sparklines, typed status
Five new widget types and project-wide auto-refresh. Backwards-compatible — every existing dashboard.json renders byte-identically.
markdown_file/log_tail/cron_status/image/status_grid— file-reading widgets that auto-refresh when the underlying file changes. By convention, place files inside<project>/.scarf/.statwidget gains inline sparklines via optionalsparkline: [Number]. SVG-only render; dozens per dashboard cost nothing.- Typed status badges with lenient decode (
ok/up→ success,down/error→ danger). Unknown strings render as plain text rather than crashing. - Structured widget error card replaces the legacy "Unknown: <type>" placeholder.
OAuth resilience + Credential Pools
- Daily OAuth keepalive cron prevents Anthropic OAuth refresh tokens from expiring after weeks of inactivity.
- Remote re-auth unblocked — OAuth flow drives a remote
hermes auth addcorrectly with stdin forwarded. - OAuth remove button + auto-refresh of Credential Pools on
auth.jsonchange. resolve_provider_clienterrors (auxiliary task references an unauthenticated provider) classified into a clear hint with a one-click jump to Settings → Aux Models.- Model/provider mismatch banner detects when
model.defaultcarries a<provider>/...prefix that disagrees withmodel.provider, with one-click fix in either direction.
ScarfMon — performance instrumentation harness
The diagnostic surface that drove the bulk of the v2.7 perf work. Off by default; signpost-only mode (Instruments-friendly) is free; Full mode keeps a 4096-entry in-memory ring buffer you can copy as JSON for paste-into-issue diagnosis. Wiki: Performance-Monitoring.
See the full v2.7.0 release notes for the complete list (36 commits, including: in-flight coalescing for loadRecentSessions, snapshot pipeline rewrite from sqlite3 .backup to direct SSH-streamed queries #74, per-message TTS, window-position persistence, sidebar reorder, and many other fixes).
Previous releases: see the Release Notes Index on the wiki for v2.6, v2.5, v2.3, v2.2, v2.0, v1.6, and earlier.
ScarfGo — the iPhone companion
Same Hermes server you've been running on your Mac — reachable from your phone over SSH. Multi-server, project-scoped chat, session resume, memory editor, cron list, skills tree, settings (read), all native iOS. Pure-Swift SSH (Citadel under the hood — no ssh binary needed on iOS). Per-project chat writes the same Scarf-managed AGENTS.md block the Mac app does, so the agent boots with the same project context regardless of which client opened the session.
Join the public TestFlight — the link is live now but only accepts new beta testers once Apple's Beta Review approves the first build. If you hit a "not accepting testers" splash, bookmark it and try again in 24–48h.
Tap any thumbnail to view full size. Servers list · Chat · Project dashboard (Site Status Checker template) · Skills browser · System tab.
See the ScarfGo wiki page for the full feature tour, ScarfGo Onboarding for the SSH-key setup walkthrough, and Platform Differences for what is and isn't shared between Mac and iOS.
Connect ScarfGo to your Hermes server
ScarfGo speaks SSH directly — no companion service, no developer-controlled server in between. Onboarding takes about a minute:
- Install via TestFlight. Open the public TestFlight link on your phone, accept the invite, install ScarfGo from TestFlight (just like any other beta).
- Tap Add Server. Enter the host (IP or DNS), SSH user, port (default 22), and an optional nickname. Same details you'd type into
ssh user@host. - Generate Key. ScarfGo creates a fresh Ed25519 keypair on the device. The private half lives in the iOS Keychain (
kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly) and is excluded from iCloud sync — it never leaves the phone. - Add the public key to your Hermes host. Tap Copy public key, then on the host run:
This is its own line per device — the convention any second SSH client uses. Mac (Scarf) keeps using your existing ssh-agent /
cat >> ~/.ssh/authorized_keys <<'EOF' <paste the line ScarfGo showed you> EOF chmod 600 ~/.ssh/authorized_keys~/.ssh/configand is unaffected. - Tap Test connection. ScarfGo opens an SSH session, probes for the
hermesbinary, and saves the server on success. If it can't findhermes, see the troubleshooting section — it's almost always aPATHquirk on non-interactive SSH.
Done. Open the Dashboard tab and tap any session to resume it; tap the + in Chat to start a new project-scoped session.
Multi-server, one window per server
Scarf 2.0 is a multi-window app. Each window is bound to exactly one Hermes server — your local ~/.hermes/ is synthesized automatically, and you can add remotes via File → Open Server… → Add Server (host, user, port, optional identity file). Open a second window for a different server and the two run side-by-side with independent state.
Remote Hermes is reached over system SSH — the same ~/.ssh/config, ssh-agent, ProxyJump, and ControlMaster pooling your terminal uses. File I/O flows through scp/sftp; SQLite is served from atomic sqlite3 .backup snapshots cached under ~/Library/Caches/scarf/snapshots/<server-id>/; chat (ACP) tunnels as ssh -T host -- hermes acp with JSON-RPC over stdio end-to-end. Everything in the feature list below works against remote identically to local.
Remote setup requirements
The remote host must have:
- SSH access — key-based auth via your local ssh-agent. Scarf never prompts for passphrases; run
ssh-addonce in Terminal before connecting. sqlite3on the remote$PATH— needed for the atomic DB snapshots. Install on the remote withapt install sqlite3(Ubuntu/Debian),yum install sqlite(RHEL/Fedora), orapk add sqlite(Alpine).pgrepon the remote$PATH— used by the Dashboard "is Hermes running" check. Standard on every distro; installprocpsif missing.~/.hermes/readable by the SSH user. When Hermes runs as a separate user (systemd service, Docker container), the SSH user needs read access toconfig.yamlandstate.db. Either (a) SSH as the Hermes user, (b)chmodHermes's home to be group-readable and add your SSH user to that group, or (c) set the Hermes data directory field when adding the server to point at the right location (e.g./var/lib/hermes/.hermes).
Troubleshooting remote connections
If the connection pill is green but the Dashboard shows "Stopped", "unknown", or empty values, the SSH user can't read the Hermes state files. Open Manage Servers → 🩺 Run Diagnostics (or click the yellow "Can't read Hermes state" pill in the toolbar). The diagnostics sheet runs fourteen checks in one SSH session — connectivity, sqlite3 presence, read access to config.yaml and state.db, the effective non-login $PATH — and tells you exactly which one fails and why, with remediation hints for each. Use the Copy Full Report button to paste the full output into a bug report.
For the common "Hermes isn't at the default path" case (systemd services, Docker), Test Connection in the Add Server sheet now probes /var/lib/hermes/.hermes, /opt/hermes/.hermes, /home/hermes/.hermes, and /root/.hermes when it can't find state.db at ~/.hermes/, and offers a one-click fill if it finds any of them.
Features
Scarf mirrors Hermes's surface area through a sidebar-based UI. Sections below map 1:1 to the app's sidebar.
Monitor
- Dashboard — System health, token usage, cost tracking, recent sessions with live refresh
- Insights — Usage analytics with token breakdown (including reasoning tokens), cost tracking, model/platform stats, top tools bar chart, activity heatmaps, notable sessions, and time period filtering (7/30/90 days or all time)
- Sessions Browser — Full conversation history with message rendering, model reasoning/thinking display, tool call inspection, full-text search, rename, delete, and JSONL export. Subagent sessions are filtered from the main list and accessible via parent session drill-down
- Activity Feed — Recent tool execution log with filtering by kind and session, detail inspector with pretty-printed arguments and tool output display
Interact
- Live Chat — Two modes: Rich Chat streams responses in real-time via the Agent Client Protocol (ACP) with iMessage-style bubbles, markdown rendering, tool call visualization, thinking/reasoning display, permission request dialogs, and a one-click
/compressfocus sheet (when Hermes advertises the command); Terminal runshermes chatwith full ANSI color and Rich formatting via SwiftTerm. Both modes support session persistence, resume/continue previous sessions, auto-reconnection with session recovery, and voice mode controls - Memory Viewer/Editor — View and edit Hermes's MEMORY.md and USER.md with live file-watcher refresh, external memory provider awareness (Honcho, Supermemory, etc.), and profile-scoped memory support with profile picker
- Skills Browser — Browse installed skills by category with file content viewer and required config warnings. New in 1.6: Browse the Skills Hub, search by registry (official, skills.sh, well-known, GitHub, ClawHub, LobeHub), install, check for updates, and uninstall — all from the app
Configure (new in 1.6)
- Platforms — Native GUI setup for all 13 messaging platforms (Telegram, Discord, Slack, WhatsApp, Signal, Email, Matrix, Mattermost, Feishu, iMessage, Home Assistant, Webhook, CLI). Per-platform forms write credentials to
~/.hermes/.envand behavior toggles to~/.hermes/config.yaml. WhatsApp and Signal pairing use an inline SwiftTerm terminal for QR scan and signal-cli daemon management - Personalities — List defined personalities, pick the active one, and edit
SOUL.mdinline with markdown preview - Quick Commands — Editor for custom
/command_nameshell shortcuts with dangerous-pattern detection (rm -rf,mkfs, etc.) - Credential Pools — Per-provider credential rotation with a fixed OAuth flow (URL extraction + browser open + code paste) and proper
--type api-keyhandling. API keys never stored in UI state — only last-4 preview. Strategy picker (fill_first / round_robin / least_used / random) - Plugins — Install via Git URL or
owner/repo, update, remove, enable/disable. Reads~/.hermes/plugins/directly for reliable state - Webhooks — Create, list, test-fire, and remove webhook subscriptions. Detects the "platform not enabled" state and links to gateway setup
- Profiles — Switch between multiple isolated Hermes instances. Create, rename, delete, export (zip), import. Safe-switch warning reminds users to restart Scarf after activating a different profile
Manage
- Tools — Enable/disable toolsets per platform with a connectivity-aware platform menu (green/orange/grey/red dots for connected/configured/offline/error). Fixed in 1.6: all 13 platforms now appear (was previously stuck on CLI)
- MCP Servers — Manage Model Context Protocol servers Hermes connects to. Add via curated presets (GitHub, Linear, Notion, Sentry, Stripe, and more) or fully custom (stdio command + args, or HTTP URL with optional bearer auth). Per-server detail view with enable/disable toggle, environment variable + header editor, tool-include/exclude filters, resources/prompts toggles, request and connect timeouts, OAuth token detection + clearing, and one-click "Test Connection" that runs
hermes mcp testand surfaces the discovered tool list. Gateway-restart banner appears after config changes that require a reload - Gateway Control — Start/stop/restart the messaging gateway, view platform connection status, manage user pairing (approve/revoke)
- Cron Manager — View scheduled jobs with pre-run scripts, delivery failure tracking, timeout info, and
[SILENT]job indicators. New in 1.6: full write support — create, edit, pause, resume, run-now, and delete jobs from the app - Health — Component-level status and diagnostics. New in 1.6: inline "Run Dump" and "Share Debug Report" buttons (the latter with an upload-confirmation dialog before sending to Nous support)
- Log Viewer — Real-time log tailing for agent.log, errors.log, and gateway.log with level filtering, component filter (Gateway / Agent / Tools / CLI / Cron), clickable session-ID pills that filter to a single session, and text search
- Settings — Restructured in 1.6 into a 10-tab layout: General, Display, Agent, Terminal, Browser, Voice, Memory, Aux Models, Security, Advanced. Exposes ~60 previously hidden config fields including all 8 auxiliary model tasks, container limits, full TTS/STT provider settings, human-delay simulation, compression thresholds, logging rotation, checkpoints, website blocklist, Tirith sandbox, and delegation. One-click Backup & Restore via
hermes backup/hermes import. Model picker replaces the old free-text model field, backed by the models.dev cache (111 providers, all major models) with a "Custom…" escape hatch
Project Dashboards
Custom, agent-generated dashboards for any project. Define stat boxes, charts, tables, progress bars, checklists, rich text, and embedded web views in a simple JSON file — Scarf renders them with live refresh. Let your Hermes agent build and maintain project-specific visualizations automatically. See Project Dashboards below for the full schema.
System
- Hermes Process Control — Start, stop, and restart the Hermes agent directly from Scarf
- Menu Bar — Status icon showing Hermes running state with quick actions
Requirements
- macOS 14.6+ (Sonoma) for Scarf
- iOS 18.0+ for ScarfGo (the iPhone companion, public TestFlight from v2.5)
- Xcode 16.0+ to build from source
- Hermes agent v0.6.0+ installed at
~/.hermes/on each target host (v0.12.0+ recommended for full v2.6 feature support — autonomous Curator, multimodal image input, 5 new providers, Microsoft Teams + Yuanbao gateways, Kanban, Skills v0.12 surface, cron--workdir, prompt-cache TTL, Piper TTS, Vercel terminal) - For remote servers: SSH access (key-based),
sqlite3on the remote (for atomic DB snapshots), and thehermesCLI resolvable from the remote user'sPATHor at a path you specify per server. ScarfGo requires the same on every Hermes host it connects to.
Compatibility
Scarf reads Hermes's SQLite database and parses CLI output from hermes status, hermes doctor, hermes tools, hermes sessions, hermes gateway, and hermes pairing. Automatic schema detection provides backward compatibility with older databases while supporting new features in newer Hermes versions.
| Hermes Version | Status |
|---|---|
| v0.6.0 (2026-03-30) | Verified |
| v0.7.0 (2026-04-03) | Verified |
| v0.8.0 (2026-04-08) | Verified |
| v0.9.0 (2026-04-13) | Verified |
| v0.10.0 (2026-04-16) | Verified (Tool Gateway introduced) |
| v0.11.0 (2026-04-23) | Verified |
| v0.12.0 (2026-04-30) | Verified — current target (recommended for full v2.6 feature support) |
Scarf 2.6 targets Hermes v0.12.0 for the autonomous Curator, multimodal ACP image content blocks, the 5 new inference providers, Microsoft Teams + Yuanbao gateways, the read-only Kanban view, the Skills v0.12 surface (URL install / reload / disable badges / curator pin), cron --workdir, auxiliary.curator, prompt_caching.cache_ttl, the redaction toggle, the runtime metadata footer, Piper TTS, and the Vercel terminal backend. Every v0.12 surface is capability-gated — Scarf detects the host's Hermes version once per server connection (hermes --version → semver + YYYY.M.D parse) and hides v0.12-only UI on older hosts. v0.11.0 hosts keep the full v2.5 surface (/steer, messages.reasoning_content, sessions.api_call_count, design-md/spotify skills, SKILL.md frontmatter chips, hermes memory reset). Earlier Hermes versions remain supported for monitoring, sessions, file-based features, and ACP chat; new behavior degrades gracefully on older agents.
If a Hermes update changes the database schema or CLI output format, Scarf may need to be updated. Check the Health view for compatibility warnings.
Install
Pre-built Binary (no Xcode required)
Download the latest build from Releases:
Scarf-vX.X.X-Universal.zip— Apple Silicon + Intel (recommended)Scarf-vX.X.X-ARM64.zip— Apple Silicon only (smaller download)
- Unzip and drag Scarf.app to Applications
- Launch normally — builds are Developer ID signed and notarized, so Gatekeeper accepts them on first launch
Scarf checks for updates automatically on launch via Sparkle and daily thereafter. You can disable automatic checks or trigger a manual check from Settings → General → Updates or the menu bar icon.
"Scarf.app is damaged" on first launch
If Gatekeeper rejects the app on first launch (occasionally happens on macOS 14+ for zip-distributed apps depending on extraction tool + quarantine state), the bundle itself is fine — every release is verified to pass codesign --verify --strict --deep and spctl --assess --type execute before it ships. The fix is to only remove the quarantine attribute, never strip all xattrs or re-sign:
# Recommended — non-destructive
xattr -d com.apple.quarantine /Applications/Scarf.app
# Or extract with ditto instead of double-clicking the zip:
ditto -xk ~/Downloads/Scarf-vX.X.X-Universal.zip ~/Downloads/
Do not run xattr -rc /Applications/Scarf.app — it strips codesign-related extended attributes and can break the bundle's seal. Do not run codesign --force --deep --sign - /Applications/Scarf.app — --deep ad-hoc re-signing is incompatible with Sparkle.framework's nested XPC services and Updater.app sub-bundle, and will corrupt the framework signature even if the outer app appears intact afterward. If a clean re-download + xattr -d com.apple.quarantine doesn't resolve the issue, please open an issue with codesign --verify --verbose=4 --strict /Applications/Scarf.app output captured before any mitigation attempts.
Build from Source
git clone https://github.com/awizemann/scarf.git
cd scarf/scarf
open scarf.xcodeproj
Or from the command line:
xcodebuild -project scarf/scarf.xcodeproj -scheme scarf -configuration Release -arch arm64 -arch x86_64 ONLY_ACTIVE_ARCH=NO build
Architecture
Scarf follows the MVVM-Feature pattern with zero external dependencies beyond SwiftTerm:
scarf/
Core/
Models/ Plain data structs (HermesSession, HermesMessage, HermesConfig, etc.)
Services/ Data access (SQLite reader, file I/O, log tailing, file watcher)
Features/ Self-contained feature modules
Dashboard/ System overview and stats
Insights/ Usage analytics and activity patterns
Sessions/ Conversation browser with rename, delete, export
Activity/ Tool execution feed with inspector
Projects/ Agent-generated project dashboards with widget rendering
Chat/ Rich ACP chat and embedded terminal with voice controls
Memory/ Memory viewer and editor
Skills/ Skill browser by category
Tools/ Toolset management per platform
MCPServers/ MCP server registry, presets, OAuth, tool filters, test runner
Gateway/ Messaging gateway control and pairing
Cron/ Scheduled job viewer
Logs/ Real-time log viewer
Settings/ Structured config editor
Navigation/ AppCoordinator + SidebarView
Data Sources
Scarf reads Hermes data directly from ~/.hermes/:
| Source | Format | Access |
|---|---|---|
state.db |
SQLite (WAL mode) | Read-only |
config.yaml |
YAML | Read-only |
memories/*.md |
Markdown | Read/Write |
cron/jobs.json |
JSON | Read-only |
logs/*.log |
Text | Read-only |
gateway_state.json |
JSON | Read-only |
skills/ |
Directory tree | Read-only |
hermes acp |
ACP subprocess (JSON-RPC stdio) | Real-time chat |
hermes chat |
Terminal subprocess | Interactive |
hermes tools |
CLI commands | Enable/Disable |
hermes sessions |
CLI commands | Rename/Delete/Export |
hermes gateway |
CLI commands | Start/Stop/Restart |
hermes pairing |
CLI commands | Approve/Revoke |
hermes mcp |
CLI commands | Add/Remove/Test MCP servers |
mcp-tokens/*.json |
JSON (per-server OAuth) | Detect/Delete |
.scarf/dashboard.json |
JSON (per-project) | Read-only |
scarf/projects.json |
JSON (registry) | Read/Write |
The app opens state.db in read-only mode to avoid WAL contention with Hermes. Management actions (tool toggles, session rename/delete/export) go through the Hermes CLI.
Dependencies
| Package | Purpose |
|---|---|
| SwiftTerm | Terminal emulator for the Chat feature |
| Sparkle | Auto-updates from the GitHub-hosted appcast |
Everything else uses system frameworks: SQLite3 C API, Foundation JSON, AttributedString markdown, SwiftUI Charts, GCD file watching.
How It Works
Scarf watches ~/.hermes/ for file changes and queries the SQLite database for sessions, messages, and analytics. Views refresh automatically when Hermes writes new data.
The Chat tab has two modes. Rich Chat communicates with Hermes via the Agent Client Protocol (ACP) — a JSON-RPC connection over stdio — streaming responses in real-time with automatic reconnection and session recovery on connection loss. Terminal mode spawns hermes chat in a pseudo-terminal for the full interactive CLI experience with proper ANSI rendering. Sessions persist across navigation in both modes — switch tabs and come back without losing your conversation.
Management actions (renaming sessions, toggling tools, editing memory) call the Hermes CLI or write directly to the appropriate files, keeping Scarf and Hermes in sync.
The app sandbox is disabled because Scarf needs direct access to ~/.hermes/ and the ability to spawn the Hermes binary.
Project Dashboards
Project Dashboards turn Scarf into a customizable monitoring hub for all your projects. You define a simple JSON file in your project folder describing what to display — stat boxes, charts, tables, progress bars, checklists, rich text, and embedded web views — and Scarf renders it as a live-updating dashboard. Your Hermes agent can generate and maintain these dashboards automatically.
What You Can Build
- Development dashboards — test coverage, build status, open issues, sprint progress
- Data project trackers — pipeline metrics, data quality scores, processing throughput
- Deployment monitors — deploy history tables, uptime stats, error rate charts
- Research dashboards — experiment results, key findings, paper status checklists
- Agent activity views — cron job results, content generation stats, task completion rates
- Embedded web apps — local dev servers, HTML reports, Grafana dashboards, any web-based tool your agent generates
- Any project status — if your agent can measure it, Scarf can display it
Quick Start
1. Create the dashboard file
Create .scarf/dashboard.json in any project folder:
{
"version": 1,
"title": "My Project",
"description": "Project status at a glance",
"sections": [
{
"title": "Overview",
"columns": 3,
"widgets": [
{
"type": "stat",
"title": "Test Coverage",
"value": "87%",
"icon": "checkmark.shield",
"color": "green",
"subtitle": "+2.1% this week"
},
{
"type": "progress",
"title": "Sprint Progress",
"value": 0.73,
"label": "73% complete",
"color": "blue"
},
{
"type": "list",
"title": "Tasks",
"items": [
{ "text": "Write unit tests", "status": "done" },
{ "text": "Update API docs", "status": "active" },
{ "text": "Deploy to prod", "status": "pending" }
]
}
]
}
]
}
2. Register your project
In Scarf, go to Projects in the sidebar and click the + button to add your project folder. Or have your agent add it directly to the registry at ~/.hermes/scarf/projects.json:
{
"projects": [
{ "name": "my-project", "path": "/Users/you/Developer/my-project" }
]
}
3. View in Scarf
Select your project in the Projects sidebar — the dashboard renders immediately. Scarf watches the file for changes and refreshes automatically whenever the JSON is updated.
Widget Types
| Type | Description | Key Fields |
|---|---|---|
stat |
Key metric with large value display | value, icon, color, subtitle |
progress |
Progress bar with label | value (0.0–1.0), label, color |
text |
Rich text block | content, format ("markdown" or "plain") |
table |
Data table with headers | columns, rows |
chart |
Line, bar, or pie chart | chartType, series (each with name, color, data) |
list |
Checklist with status indicators | items (each with text, status: done/active/pending) |
webview |
Embedded web browser | url, height (default 400) |
The webview widget embeds a live web browser directly in your dashboard — perfect for displaying local dev servers, HTML reports, or any web-based tool your agent generates.
When a dashboard includes a webview widget, Scarf adds a tabbed interface: Dashboard shows your normal widgets, Site shows the web content full-canvas with clean margins — using the entire available space in the app. This gives you the best of both worlds: compact metrics at a glance, and a full embedded browser when you need it.
{
"type": "webview",
"title": "Project Report",
"url": "http://localhost:8000/dashboard",
"height": 500
}
url: Any URL — typically a local server (http://localhost:...) or file pathheight: Height in points when displayed as an inline widget card (default: 400). The Site tab always uses full available space regardless of this setting.
Colors: red, orange, yellow, green, blue, purple, pink, teal, indigo, mint, brown, gray
Icons: Any SF Symbol name (e.g., checkmark.shield, cpu, doc.text, chart.bar)
Agent-Generated Dashboards
The real power is letting your Hermes agent build and update dashboards automatically. Add instructions like this to your agent's context:
Analyze this project and create a
.scarf/dashboard.jsondashboard with relevant metrics and status. Use stat widgets for key numbers, charts for trends, tables for structured data, lists for task tracking, and a webview widget if the project has a local web server or HTML reports. Register the project in~/.hermes/scarf/projects.jsonif not already registered.
Your agent can update the dashboard as part of cron jobs, after builds, or whenever project state changes. Since Scarf watches the file, updates appear in real-time.
Dashboard Schema Reference
{
"version": 1,
"title": "Required — dashboard title",
"description": "Optional — subtitle text",
"updatedAt": "Optional — ISO 8601 timestamp",
"sections": [
{
"title": "Section Name",
"columns": 3,
"widgets": [{ "type": "...", "title": "..." }]
}
]
}
Each section defines a grid with 1–4 columns. Widgets flow left-to-right, wrapping to new rows. See DASHBOARD_SCHEMA.md for the full schema reference with examples of every widget type.
Releases
Scarf ships through GitHub releases — the App Store is not supported because Scarf spawns the user-installed hermes binary and reads ~/.hermes/ directly, both of which App Sandbox forbids.
Each release goes through a single local script: scripts/release.sh. The script archives a universal binary, signs it with the Developer ID Application cert, submits to notarytool, staples the ticket, produces the distribution zip, signs an appcast entry with Sparkle's EdDSA key, pushes an updated appcast.xml to the gh-pages branch, creates the GitHub release, and tags main.
The Sparkle appcast is served from awizemann.github.io/scarf/appcast.xml.
Signing prerequisites (one-time):
Developer ID Applicationcertificate in the login Keychainscarf-notarykeychain profile registered viaxcrun notarytool store-credentials- Sparkle EdDSA private key in Keychain item
https://sparkle-project.org(back this up — without it, shipped apps can never receive updates)
Template Catalog
Community-contributed Scarf project templates live under templates/ in this repo and are browsable at awizemann.github.io/scarf/templates/ with live dashboard previews and one-click scarf://install?url=… links.
- Install from the web — click "Install with Scarf" on any template's detail page; the app takes over from there.
- Install from a local file — Scarf → Projects → Templates → Install from File…, or double-click any
.scarftemplatein Finder. - Author a template — see
templates/CONTRIBUTING.mdfor the full walkthrough. Fork, drop a template undertemplates/<your-github-handle>/<your-name>/, open a PR; CI validates the bundle automatically.
The catalog's site is a static HTML + vanilla JS build generated by tools/build-catalog.py and driven by scripts/catalog.sh (check / build / preview / publish). Appcast and main landing page are independent — updating the catalog never disturbs Sparkle.
Contributing
Contributions are welcome. Please open an issue to discuss what you'd like to change before submitting a PR.
- Fork the repo
- Create your feature branch (
git checkout -b feature/my-feature) - Commit your changes (
git commit -m 'Add my feature') - Push to the branch (
git push origin feature/my-feature) - Open a Pull Request
For template submissions, see templates/CONTRIBUTING.md — same flow, with a catalog-specific checklist + automated CI validation.
Support
If you find Scarf useful, consider buying me a coffee.




