Skip to content

Zackriya-Solutions/syncfu

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

66 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

syncfu icon

syncfu

The notification layer your AI agents are missing.

Release License Build Platform Rust

Install · Quick Start · API · Use Cases · Integrations · syncfu.dev


syncfu is a standalone overlay notification system that sits between your background processes — AI agents, autonomous loops, skills, CI pipelines, cron jobs, anything — and you. It renders always-on-top native notifications that bypass the OS notification center, so nothing gets buried.

One command. One notification on your screen. That's it.

syncfu send "All 47 tests passing."

Need a decision from the user? Add --wait and the CLI blocks until they click.

syncfu send "Ship to production?" -t "Deploy?" \
  -a "yes:Yes" -a "no:No:danger" --wait
# stdout: "yes" or "no", exit 0. Dismissed = exit 1. Timeout = exit 2.

Need more? Add flags.

syncfu send -t "Loop complete" -p high -i circle-check \
  --action "open:Open PR:primary" --action "skip:Skip:secondary" \
  "All 47 tests passing."

Highlights

Feature Description
🔔 Always-on-top overlay NSPanel on macOS — non-activating, click-through, joins all Spaces
--wait flag CLI blocks until the user clicks an action button (SSE-backed)
🎨 27 style properties Full visual control per notification — colors, fonts, borders, radii
🖥️ Multi-monitor Notifications follow your mouse cursor across displays
🔗 Webhook callbacks Action buttons POST to your callbackUrl for closed-loop automation
📊 Live progress bars Update in-flight notifications with progress, body changes, new actions
🏝️ notch notifications Notch-covering capsule that morphs pill ↔ card — ambient, hover-reveal, hides from screen capture
🧪 443 tests 227 frontend + 169 Rust server + 47 CLI
Zero config No config files — everything is API-driven per notification


Screenshots

syncfu notifications on a MacBook: the capsule covers the notch and spring-morphs from an ambient pill into a full card. On non-notch Macs, Windows, and Linux it renders as a floating capsule.

The island covering a MacBook notch: the card's wedge top is flush at the screen edge over the cutout, content below it
On a notched Mac, syncfu covers the notch — the black shape absorbs the cutout and content sits below it (shown on a bright wallpaper so the shape is visible).

Collapsed ambient pill
Idle — a compact ambient pill
Expanded island card
Expands to a full card on arrival or click
Collapsed pill with a mini progress ring
Collapsed — live mini-ring
Expanded card with a progress bar
Expanded — progress bar
Expanded card with a progress ring
--progress-style ring
Decision card with primary and danger action buttons
Decision — primary / danger actions
Critical alert card
Critical — never auto-dismisses, close via hover x
Island card with custom colors and font
27 style overrides + Google Fonts
Island card with a longer rich body
Rich body content
Tall island card that grew to fit its content
Grows to fit — content never spills
Float island anchored left
left
Float island anchored center
center
Float island anchored right
right
Float island anchored bottom-center
bottom-center (expands upward)
Island in dark appearance
Dark appearance
Island in light appearance
Light appearance
Compact pill with a spotlight item and an x2 badge
Spotlight + x2 badge
Compact pill with a 9+ badge
Badge caps at 9+
Expanded ranked list of notifications with per-row actions and Clear all
Expanded ranked list — per-row actions, Clear all

Built with Tauri v2 + Rust (axum) + React (Zustand). Ships on macOS, Windows, and Linux.


Table of Contents


Why this exists

If you run AI agents, autonomous coding loops, or long-running background tasks — you already know the problem. The work finishes, but you don't notice. The agent wrote 14 files, ran the tests, opened a PR... and you're on Twitter. Or the build broke 20 minutes ago and you've been waiting on nothing.

OS notifications are unreliable for this. They get swallowed by Focus Mode, grouped into oblivion, or silently dropped. You need a notification layer that respects your attention — one that puts information on your screen when it matters, with action buttons so you can respond without context-switching.

syncfu is that layer.


How it works

syncfu runs as a system tray app with two faces:

  1. Overlay — an invisible, always-on-top layer across your screen. When a notification arrives via HTTP, it slides in from the top-right with action buttons, progress bars, and custom styling. Clicks pass through to your apps underneath. Only the notification cards are interactive. Follows your mouse cursor across monitors.

  2. System tray — syncfu lives in your menu bar / system tray. Open the main window to see active notifications, or quit from the tray menu.

Your App ──HTTP POST──▸ syncfu server ──▸ Overlay Notification
CLI      ──HTTP POST──▸ syncfu server ──▸ Overlay Notification
CLI (--wait) ─────────▸ SSE stream ◂──── wait for action/dismiss
Protocol Port Purpose
HTTP REST 9868 Send, update, dismiss, wait (SSE)

Install

One-liner (recommended)

macOS / Linux:

curl -fsSL https://raw.githubusercontent.com/Zackriya-Solutions/syncfu/main/install.sh | sh

Windows (PowerShell):

irm https://raw.githubusercontent.com/Zackriya-Solutions/syncfu/main/install.ps1 | iex

Specific version:

curl -fsSL https://raw.githubusercontent.com/Zackriya-Solutions/syncfu/main/install.sh | sh -s -- --version=X.Y.Z

SHA-256 checksum verification is enforced by default. Use --skip-checksum to bypass.

From source (CLI only)

git clone https://github.com/Zackriya-Solutions/syncfu.git
cd syncfu
cargo install --path cli

Desktop app (from source)

git clone https://github.com/Zackriya-Solutions/syncfu.git
cd syncfu
pnpm install
pnpm tauri build

Prerequisites: Rust, Node.js 18+, pnpm, and Tauri v2 prerequisites.

See CHEATSHEET.md for a quick-reference of all CLI commands and flags.

Uninstall

macOS / Linux:

curl -fsSL https://raw.githubusercontent.com/Zackriya-Solutions/syncfu/main/uninstall.sh | sh

Windows (PowerShell):

irm https://raw.githubusercontent.com/Zackriya-Solutions/syncfu/main/uninstall.ps1 | iex

Quick start

# Send your first notification — just a message
syncfu send "Hello from syncfu!"

# With a title and priority
syncfu send -t "Build Complete" -p high "All 142 tests passing"

# With action buttons
syncfu send -t "PR #42" \
  --action "approve:Approve:primary" \
  --action "skip:Skip:secondary" \
  "Review requested"

# Block until the user responds (--wait)
ACTION=$(syncfu send -t "Approve?" \
  -a "yes:Yes" -a "no:No:danger" --wait "Merge PR #42?")
echo "User chose: $ACTION"  # "yes", "no", "dismissed", or "timeout"

# Or use curl directly
curl -X POST localhost:9868/notify \
  -H "Content-Type: application/json" \
  -d '{"sender":"test","title":"It works","body":"Your first notification"}'

# List active notifications
syncfu list | jq '.[].title'

# Check server health
syncfu health

Always running

syncfu is designed to stay alive in the background — your agents depend on it.

  • Starts at login (configurable) — silently, tray + overlay only
  • Closing the window hides it to the tray — doesn't quit
  • Ctrl+Q / Cmd+Q asks: "Quit syncfu? Agents won't be able to notify you."
  • Tray → Quit also confirms before exiting
  • You'll never accidentally kill it

Claude Code integration

syncfu ships with ready-to-use Claude Code files in the claude/ directory:

File What it does How to use
claude/command.md /syncfu slash command — type /syncfu tests passed and Claude sends the notification for you Copy to ~/.claude/commands/syncfu.md
claude/skill.md Full API reference — Claude reads this to know all flags, endpoints, and patterns Copy to ~/.claude/skills/syncfu.md

Quick setup:

# Install the slash command and skill
cp claude/command.md ~/.claude/commands/syncfu.md
cp claude/skill.md ~/.claude/skills/syncfu.md

Then in Claude Code:

/syncfu build passed, all 142 tests green
/syncfu critical: database connection pool exhausted
/syncfu ask me whether to deploy

Claude interprets your intent, picks the right priority/icon/actions, and runs the CLI command. With ask me phrasing, it uses --wait to block until you respond via the overlay notification.

See claude/command.md for the full pattern reference.


Use cases

AI agents & autonomous loops

Claude Code skills and hooks

Your /remind skill fires a cron, but the alert is just a terminal bell you'll never hear. Wire it to syncfu and get an overlay notification with action buttons — snooze, mark done, or open the file.

# Inside any Claude Code skill or hook
syncfu send -t "$TITLE" -s remind --sound default \
  --action "done:Done:primary" --action "snooze:Snooze 15m:secondary" \
  "$BODY"

Autonomous coding loops

Running /loop or a multi-agent workflow that takes 30 minutes? Get notified when each phase completes, when tests fail, or when the loop needs human input.

syncfu send -t "Phase 3/5 complete" -s loop-operator \
  --progress 0.6 --progress-label "3 of 5" \
  "Integration tests: 42 passed, 0 failed. Starting E2E phase..."

Agent decision gates

An agent needs human approval before a destructive action. Use --wait to block the agent until the user responds via the overlay notification.

syncfu send -t "Confirm" -s agent -p high \
  -a "yes:Proceed" -a "no:Cancel:danger" \
  --wait --wait-timeout 120 \
  "Delete 47 stale branches?" && git branch -d $(git branch --merged)

More ideas

  • Agent handoff alerts — notify the human between agent stages for review
  • Stalled loop detection — watchdog pings syncfu if no progress in N minutes
  • Multi-agent dashboards — each agent reports with its own sender ID, stacked as a live progress board
CI/CD & DevOps
syncfu send -t "Build passed" -s github-actions -i circle-check \
  --action "open_pr:Open PR:primary" --sound success --group ci-builds \
  "main built in 3m 42s — 142 tests passed, coverage 87% (+2.1%)"
  • Deploy progress — track multi-stage deployments with live progress bars
  • Infrastructure alerts — disk full, memory pressure, certificate expiring
  • Database migrations"Migrating users table — 2.4M of 8.1M rows (30%)"
Development workflow
# Notify on test pass or fail
cargo test && syncfu send -t "Tests passed" -p low -i circle-check "All green" \
  || syncfu send -t "Tests failed" -p critical -i circle-x "Check terminal"
  • Long compilation finished — Rust full rebuild, C++ linking, Go generate
  • PR review requested — webhook listener with "Review" and "Skip" buttons
  • Merge conflict alerts — detect before you waste time on a broken base
  • Lint / type-check results — background eslint or tsc --noEmit
Personal productivity & ADHD support
syncfu send -t "Stand-up in 5 minutes" -p high --sound default --timeout 300 \
  "Prepare: yesterday's PR review, today's auth refactor"
  • Reminders that actually reach you — overlay ON YOUR SCREEN, not a badge on an app you don't check
  • Time-boxed focus sessions — pomodoro with live progress bar
  • Context switching prompts"You've been on this bug for 45 minutes..."
  • Medication reminders — critical-priority, no auto-dismiss, --wait confirms you took it
syncfu send -t "Medication" -p critical -i pill --timeout never \
  -a "taken:Taken" -a "skip:Skip:danger" \
  --wait "Time to take your medication"
Server & infrastructure monitoring
  • Health check dashboard — poll services every 60s, stacked notification group
  • SSL certificate expiry — with a "Renew" action button
  • Disk space warnings"/dev/sda1 is 92% full — 14GB remaining"
  • Container restart loops — critical priority alerts
  • Cron job completion — nightly backup, database vacuum, log rotation
Data & ML pipelines
syncfu send -t "Epoch 45/100" -s training --progress 0.45 --group training-run-7 \
  "Loss: 0.0234 (↓12%) — Val accuracy: 94.2% — ETA: 2h 15m"
  • Data pipeline stages — extract → transform → load, with failure alerts
  • Model evaluation"Model v2.3: accuracy 94.2% (+1.8%)" with Deploy/Reject buttons
  • Dataset processing — progress bar that updates every 1000 records
Team, home automation & more
  • Slack/Discord highlights — forward @mentions as overlay notifications
  • Email triage — urgent emails surface as notifications with "Open" and "Snooze" actions
  • Smart home events — Home Assistant, Node-RED, IoT webhooks
  • Price alerts — stock/crypto threshold notifications
  • Billing warnings"AWS spend: $847 (85% of $1000 budget)"
  • Render complete — video, 3D scene, image batch notifications

System tray

syncfu lives in your system tray (menu bar on macOS). From the tray you can:

  • Open the main window to see active notifications
  • Clear all notifications
  • Quit syncfu (with confirmation)

Closing the main window hides it — syncfu keeps running in the tray. The overlay stays active.


API reference

HTTP endpoints

Method Path Description
POST /notify Send a notification
POST /notify/{id}/update Update an existing notification (progress, body)
POST /notify/{id}/action Trigger an action (fires webhook, dismisses)
POST /notify/{id}/dismiss Dismiss a specific notification
GET /notify/{id}/wait SSE stream — blocks until action/dismiss
POST /dismiss-all Dismiss all active notifications
GET /health Server status + active notification count
GET /active List all active notifications (JSON)

Notification payload

{
  "sender": "my-app",
  "title": "Build Complete",
  "body": "**main** built in 3m 42s\n- 142 tests passed",
  "icon": "circle-check",
  "priority": "normal",
  "timeout": { "seconds": 15 },
  "actions": [
    { "id": "open", "label": "Open PR", "style": "primary" },
    { "id": "dismiss", "label": "Dismiss", "style": "secondary" }
  ],
  "progress": { "value": 0.75, "label": "3 of 4", "style": "bar" },
  "group": "ci-builds",
  "theme": "github-dark",
  "sound": "success",
  "callback_url": "http://localhost:8080/callback"
}
Full field reference
Field Type Required Description
sender string yes Identifier for the sending process
title string yes Notification title
body string yes Body text (plain text)
presentation string no island (default when omitted) or card - routes to the notch notification or the top-right card.
icon string no Lucide icon name (e.g. phone, git-pull-request, bell)
font string no Google Font name (e.g. Space Grotesk, JetBrains Mono)
priority string no low, normal (default), high, critical
timeout object no {"seconds": N} or "never" or "default" (auto by priority)
actions array no Up to 3 action buttons
progress object no Progress bar (bar or ring style)
group string no Group key (tracked, grouping UI planned)
theme string no light or dark (auto-follows system by default)
sound string no Sound name (accepted, playback planned)
callback_url string no URL to POST when an action is clicked
style object no Per-notification style overrides (see below)
Style overrides (27 properties)

Override any visual property per notification:

{
  "style": {
    "accentColor": "#22c55e",
    "cardBg": "rgba(10, 40, 20, 0.96)",
    "iconColor": "#4ade80",
    "iconBg": "rgba(34, 197, 94, 0.15)",
    "titleColor": "#bbf7d0",
    "bodyColor": "#86efac",
    "senderColor": "#67e8f9",
    "btnBg": "#7c3aed",
    "btnColor": "#ffffff",
    "btn2Color": "#c084fc",
    "dangerBg": "#dc2626",
    "progressColor": "#22c55e",
    "countdownColor": "#ef4444"
  }
}

Full list: accentColor, cardBg, cardBorderRadius, iconColor, iconBg, iconBorderColor, titleColor, titleFontSize, bodyColor, bodyFontSize, senderColor, timeColor, btnBg, btnColor, btnBorderColor, btn2Bg, btn2Color, btn2BorderColor, dangerBg, dangerColor, dangerBorderColor, progressColor, progressTrackColor, countdownColor, closeBg, closeColor, closeBorderColor.

Per-action button styling

Each action button can override its own colors:

{
  "actions": [
    {
      "id": "deploy",
      "label": "Deploy",
      "style": "primary",
      "icon": "rocket",
      "bg": "#22c55e",
      "color": "#ffffff",
      "borderColor": "#16a34a"
    }
  ]
}

Integrations

Claude Code hooks

Get notified on every agent completion:

{
  "hooks": {
    "Stop": [{
      "command": "syncfu send -t 'Agent done' \"$(git diff --stat HEAD~1 2>/dev/null || echo 'No changes')\""
    }]
  }
}

GitHub Actions

- name: Notify syncfu
  if: always()
  run: |
    syncfu send -t "${{ github.workflow }} — ${{ job.status }}" \
      -s github-actions \
      -p ${{ job.status == 'success' && 'normal' || 'critical' }} \
      "${{ github.repository }}@${{ github.ref_name }}"
  env:
    SYNCFU_SERVER: http://your-machine:9868

Shell aliases

# Add to .zshrc / .bashrc
alias notify='syncfu send -t'
alias notify-done='syncfu send -t "Done"'
alias notify-fail='syncfu send -t "Failed" -p critical --sound error'

# Usage
long-running-command; notify-done "Finished long-running-command"

Node.js / Python / Any language

// Node.js
await fetch('http://localhost:9868/notify', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ sender: 'my-app', title: 'Done', body: 'Task complete' })
});
# Python
import requests
requests.post('http://localhost:9868/notify', json={
    'sender': 'my-app', 'title': 'Done', 'body': 'Task complete'
})

Architecture

                           ┌──────────────────────────────────┐
                           │          syncfu (Tauri v2)        │
                           │                                   │
 HTTP POST :9868 ─────────▸│  axum server ──▸ Notification     │
                           │       │          Manager          │──emit──▸ React Overlay
 CLI (fire & forget) ─────▸│       │          (Arc shared)     │         (follows cursor monitor)
                           │       │              │            │
 CLI (--wait) ─────────────▸│  SSE stream ◂── Waiter Registry │
                           │       │         (broadcast ch)    │
                           │       │              │            │
                           │       │         ┌────┴────┐       │
                           │       │         │ Tray    │       │
                           │       │         │ Webhook │       │
                           │       │         └─────────┘       │
                           └──────────────────────────────────┘
Component Stack
Backend Rust — axum HTTP server, SSE streams, tokio broadcast channels
Frontend React — Zustand store, CSS animations, Lucide icons, Google Fonts
Overlay NSPanel (macOS) — non-activating, follows mouse cursor across monitors
CLI Rust — fire-and-forget by default, --wait opens SSE stream
System tray Tauri tray API — pause, clear, quit with confirmation

Customization

syncfu doesn't use config files — everything is controlled per-notification via the API.

Per-notification styling — override any of 27 CSS properties:

syncfu send -t "Custom" --style-json '{"accentColor":"#22c55e","cardBg":"rgba(10,40,20,0.96)"}' "Styled notification"

Google Fonts — load any Google Font on demand:

syncfu send -t "Fancy" --font "Space Grotesk" "With a custom font"

Light/dark theme — auto-follows system by default, or set per-notification with "theme": "dark".


Notch notifications

The notch notification is syncfu's second presentation and, as of 0.4.0, the defaultsyncfu send routes here unless you pass --presentation card. It is a pure-black capsule anchored top-center that spring-morphs between a compact pill and an expanded card. On a MacBook it covers the physical notch (its concave wedge top sits flush at the screen edge, over the cutout, so it reads as one shape); on non-notch Macs, Windows, and Linux it renders as a floating capsule.

It suits glanceable, ambient status for long agent tasks (timers, progress, approvals), and it can be hidden from screen recording and screen sharing so private notifications do not leak on a live capture (see the support matrix for the exact per-OS guarantee). For the full reference (every setting, the payload field, troubleshooting), see docs/island.md.

Interaction model

In notch mode the notification moves through four states, where the count is the number of active notch notifications:

   count 0            count >= 1, idle          hover the notch/wings        click the pill
  +--------+         +-------------------+       +--------------------+      +-----------------+
  | hidden |  --->   |   ambient wings   | --->  | revealed pill      | ---> | expanded card   |
  | window |         | slim black stubs  |       | slides down under  |      | full content,   |
  | hidden | <---    | beside the cutout |<----  | the cutout with the|<---- | actions, x, bar |
  +--------+  count  | + accent dot or   | leave | collapsed content  | click| (click surface  |
              back 0 | mini progress ring|  +grace                     | card |  to collapse)   |
                     +-------------------+       +--------------------+      +-----------------+
  1. Hidden (count 0): the island window is hidden entirely.
  2. Ambient wings (collapsed, idle): the under-notch pill is concealed and two slim black extensions peek out beside the physical cutout, flush at the screen top. The right wing carries a priority-accent dot, or a mini progress ring when the notification carries progress. The wings are the ambient signal - there is no glyph or label.
  3. Revealed pill (hover): hovering the physical notch or its wings drops a notch-shaped pill down out of the cutout with the collapsed content. The pill covers the notch (its concave top sits flush at the screen edge, over the cutout) so it reads as one shape, never a second notch. Leaving conceals it back to the wings after a short grace.
  4. Expanded card (click / arrival): the full card. Click the revealed pill to expand; click the card surface (anywhere that is not a button) to collapse.

A fresh notification arrives EXPANDED, holds ~2.6s, then auto-collapses to the pill. A decision (a notification carrying actions, i.e. a pending --wait) and any critical notification stay expanded and never auto-collapse. The window is a click-through envelope: clicks pass to the apps underneath except over the drawn pill or card. Float / non-notch mode skips the ambient-wings and hover-reveal steps - the pill is always visible and expands on click.

Live progress

Update one notification in place as a task advances - the island never stacks a new one per step. While collapsed the right ambient wing carries a mini progress ring; expanded, it shows a bar or a ring.

Decisions and critical alerts

A decision (action buttons, i.e. a pending --wait) and any critical notification arrive expanded and stay that way until you resolve them.

Dismissal

  • Expanded card x: hover the expanded card to reveal a close x. This is also the only way to dismiss a critical no-action notification (it never auto-dismisses and has no action buttons).
  • Per-row x (multi-notification list): each row has a hover-visible x that dismisses just that row.
  • "Clear all" (multi-notification list header): empties the island in one click. Note: it calls dismiss-all, which also clears any top-right card notifications and resolves every waiter as dismissed. It is a deliberate global clear.

All three resolve the same waiter path a dismissed card uses (CLI --wait exit 1).

Sending a notification

Every notification uses the notch notification by default; route one to the top-right card with --presentation card:

syncfu send --presentation island -t "Deploying" "Rolling out v2.3"

Everything the card supports works on the island: actions, priority timeouts, progress, grouping, and all 27 style overrides. Geometry and position are not part of the payload (they are app settings, see below); the payload only carries the style overrides.

syncfu send --presentation island -t "Approve?" \
  -a "yes:Approve:primary" -a "no:Reject:danger" \
  --wait --wait-timeout 120 "Merge PR #42?"
# stdout: the chosen action id; exit 0 = action, 1 = dismissed, 2 = timeout

Over HTTP, add the same field to the payload:

curl -X POST localhost:9868/notify \
  -H "Content-Type: application/json" \
  -d '{"sender":"deploy","title":"Deploying","body":"Rolling out v2.3","presentation":"island"}'

An omitted presentation field defaults to the notch notification (island). A present value must be card or island.

--wait exit codes

A --wait decision on the island arrives expanded and stays expanded until you answer; its auto-dismiss is paused while it waits. If you never answer, the CLI's --wait-timeout (default 300s) elapses and the command exits 2 (timeout). This differs from the top-right card, where an unanswered non-critical decision auto-dismisses when its priority timeout elapses and the command exits 1 (dismissed).

Notch vs float

  • Notch mode (default): the capsule covers the top-center notch. Its concave-shouldered top sits flush at the screen edge, over the physical cutout, so the black shape absorbs the hardware notch and reads as one shape (never a second notch below it). The compact pill matches the cutout width, and content is inset below the cutout so nothing renders behind it. The pill stays pure black even in light appearance so it blends with the physical notch. position is ignored in notch mode.
  • Float mode: a fully-rounded floating capsule you can place left, center, right, or bottom-center (bottom-center is float-only and expands upward). Non-notch Macs, Windows, and Linux always float; float layout is unchanged by the notch adaptation.

Float placement (mode: float) anchors the capsule to any edge; bottom-center expands upward.

The appearance setting is dark, light, or auto (follows the OS). In notch mode the compact pill stays pure black regardless, so it always blends with the physical cutout.

Multiple notifications

When more than one island notification is active, the compact pill shows the highest-priority spotlight item plus an xN count badge (capped at 9+). Expanding reveals a priority-ranked, deduped list (critical first) capped at 6 rows before it scrolls. Auto-dismiss is paused while the list is open. Notifications with a pending --wait are exempt from de-duplication so each keeps its own exit code.

Single instance

Only one syncfu app runs at a time. A second launch is terminated immediately and the first instance's main window comes to the front (shown, focused, unminimized). This prevents a duplicate from squatting beside the first with a dead HTTP bind on :9868.

Settings

The island's geometry and appearance are app-wide settings, not per-notification. Senders never control them. Configure the 13 settings from the app's Island panel; they persist across restarts (stored as island.settings.json in the app config dir). Out-of-range numeric values are clamped, not rejected.

Setting Range Default Notes
compactWidth 150-600 218 compact pill width (px)
expandedWidth 320-560 380 expanded card width (px)
height 24-60 34 capsule height (px)
surfaceOpacity 0-100% 94 surface fill alpha (stored as 0.0-1.0)
topRadius 0-24 6 top-corner radius (px)
bottomRadius 0-40 14 bottom-corner radius (px)
cornerScaling on / off on scale radii between compact and expanded
accent preset or hex #4a9eff accent color
mode notch / float notch notch hugs the notch; float detaches
position left / center / right / bottom-center center float mode only
appearance dark / light / auto dark notch compact pill stays black even in light
reducedMotion on / off off uses the calmer 1000/100 springs
hideFromScreenCapture on / off on exclude from screen capture (see matrix)

Screen-capture support matrix

hideFromScreenCapture maps to the OS content-protection flag. What the OS actually delivers:

Platform Behavior Notes
macOS 14 (Sonoma) and earlier Hidden Guaranteed: the OS honors the exclusion.
macOS 15 (Sequoia) and later Best effort The flag is applied but ScreenCaptureKit can still capture the window, and there is no public API to force exclusion. The app reports this status honestly and never claims a guarantee.
Windows 10 build 19041 and newer Hidden Guaranteed (WDA_EXCLUDEFROMCAPTURE).
Windows older than build 19041 Not supported No reliable exclusion mechanism.
Linux Not supported No reliable capture-exclusion API.

The island never claims to be invisible where the OS cannot deliver it. On macOS 15+ and unsupported platforms the setting is surfaced with its true status.


Roadmap

Shipped

  • Core overlay window + system tray
  • NSPanel on macOS (non-activating, joins all Spaces)
  • Liquid Glass design + slide-in/out animations
  • HTTP REST server (port 9868)
  • Light/dark theme (auto + per-notification override)
  • Lucide icons + Google Fonts (programmable per notification)
  • Auto-dismiss with countdown bar (pauses on hover)
  • Critical pulsing glow (Siri-style)
  • Webhook callbacks (action buttons POST to callbackUrl)
  • 27 per-notification style properties + per-action button styling
  • CLI (syncfu send/dismiss/list/health) + --wait flag (SSE)
  • Multi-monitor support (follows mouse cursor)
  • Click-through overlay (only cards interactive)
  • One-command install (curl | sh + PowerShell)
  • Notch notifications (covers the notch, morphs pill ↔ card, default presentation)
  • 443 tests (227 frontend + 169 Rust server + 47 CLI)

Planned

  • Markdown body rendering
  • Sound playback
  • Notification grouping UI
  • Persistent history (SQLite)
  • Linux Wayland support
  • Configuration file
  • Encrypted transport (mTLS / API keys)
  • Remote notifications (tunnel / cloud relay)

Contributing

syncfu is open source under the MIT license. Contributions welcome.

git clone https://github.com/Zackriya-Solutions/syncfu.git
cd syncfu
pnpm install
pnpm tauri dev

Prerequisites: Rust 1.75+, Node.js 18+, pnpm, Tauri v2 prerequisites


License

MIT © Zackriya Solutions


syncfu.dev — because your agents shouldn't have to wait for you to check the terminal.

About

Rust based notification layer for AI agents. Command line based tool that can trigger notifications from your terminal. Because your agents shouldn't have to wait for you to check the terminal.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages