Quick Start · CLI Reference · SDK · Troubleshooting
You open your laptop and your Obsidian vault is three days behind. Your Alfred workflows don't exist on your work machine. Your dotfiles are different on every computer you touch. You spend the first 15 minutes of every session wondering: "Wait, which version is this?"
This is death by a thousand paper cuts.
Ghostflow watches your repositories and syncs every change automatically—across every machine, in the background, without you lifting a finger. Your configurations, your notes, your workflows: always current, everywhere.
Set it once. Never think about it again.
You've built systems. Your Obsidian vault holds years of accumulated knowledge. Your dotfiles are the product of hundreds of hours of tweaking. Your Alfred workflows save you minutes every day. These aren't just files—they're extensions of how you think and work.
But they're trapped. Scattered across machines that don't talk to each other.
| The friction you live with today | |
|---|---|
| Obsidian users | "My vault on my laptop is different from my desktop. Again." |
| Dotfile managers | "I spent two hours setting up my new machine. Again." |
| Alfred power users | "My workflows don't exist on my work computer." |
| Knowledge workers | "Did I push? Did I pull? Is this the latest version?" |
Ghostflow eliminates this friction permanently.
| Ghostflow gives you | |
|---|---|
| Ubiquitous access | Your configurations exist everywhere you work, always current |
| Zero mental overhead | No commits to remember, no pushes to forget, no pull rituals |
| Instant consistency | Edit on one machine, it appears on all others automatically |
| Conflict protection | Detects conflicts automatically—no surprise merge disasters |
| Infinite scale | One repository or fifty—same effortless experience |
You stop managing synchronization. You just work.
Obsidian & PKM users — Your second brain should be everywhere your first brain goes. Whether you have 100 notes or 10,000, edit on your laptop during your commute and it's waiting on your desktop when you get home.
Dotfile obsessives — You've spent years perfecting your shell. Your .zshrc is a work of art. Now it lives on every machine you touch—always identical, always current.
Alfred & Raycast power users — Your workflows, snippets, and scripts represent hundreds of hours of automation. Right now they're hostage to whichever machine you built them on. Ghostflow sets them free. New machine setup becomes: clone, done.
Developers with personal tooling — IDE settings, code snippets, custom scripts. The stuff that makes you you as a developer. Stop recreating it. Start syncing it.
Not designed for production codebases with code review workflows or team repos requiring pull requests. Ghostflow is for your personal infrastructure—the systems that make you effective.
Ghostflow runs as a background daemon on your Mac. When you save a file in a watched repository:
- Detect — Ghostflow notices the change instantly via macOS file system events
- Commit — Changes are automatically committed with a timestamp
- Sync — The commit is pushed to your remote (and pulls any remote changes)
You never see this happening. You just work, and your work stays safe.
Why "Ghost"? Because the best tools are the ones you forget are running.
Three commands to peace of mind:
# Install
npm install -g @ghostflow/cli
# Add a repository
ghostflow add ~/Vaults/MyVault --name notes --remote origin --branch main
# Start syncing
ghostflow startThat's it. Your repository is now syncing automatically in the background.
Run ghostflow status to verify everything is working.
- macOS 12+ (Monterey or later)
- Node.js 18+
- Git 2.0+
npm install -g @ghostflow/cliThis installs the CLI and automatically downloads the correct daemon binary for your architecture (Apple Silicon or Intel).
ghostflow --version
ghostflow statusghostflow add ~/Documents/Obsidian/MyVault -n obsidian -r origin -b main
ghostflow startYour notes are now backed up automatically. Edit on your laptop, and the changes appear on your desktop.
ghostflow add ~/.dotfiles -n dotfiles -r origin -b mainghostflow add ~/Projects/notes -n work-notes
ghostflow add ~/Projects/wiki -n team-wiki
ghostflow listEach repository syncs independently—a slow network on one never blocks another.
ghostflow sync obsidian # Sync specific flow
ghostflow sync # Sync all flowsghostflow pause obsidian # Stop syncing temporarily
ghostflow resume obsidian # Resume syncingLaunch without arguments to open the interactive terminal UI:
ghostflow┌─────────────────────────────────────────────────────────────────┐
│ Ghostflow ● Connected │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 3 flows · All synced │
│ │
│ ▸ obsidian ✓ 2m ago ●●●●●●●●●●●● │
│ ~/Documents/Obsidian/Vault │
│ [S] Sync [P] Pause [R] Remove │
│ │
│ dotfiles ✓ 5m ago ●●●●●●●●●●●● │
│ ~/.dotfiles │
│ │
│ work-notes ‖ PAUSED ○○○○○○○○○○○○ │
│ ~/Projects/notes │
│ │
├─────────────────────────────────────────────────────────────────┤
│ [↑↓] Navigate [A] Add [Q] Quit │
└─────────────────────────────────────────────────────────────────┘
The TUI provides:
- Real-time flow status with color-coded badges (✓ synced, ↻ syncing, ✗ error, ‖ paused)
- Health bars showing sync history (● success, ○ inactive)
- Inline actions on selected flow
- Keyboard navigation (
j/kto move,sto sync,pto pause) - Auto-starts the daemon if not running
| Command | Description |
|---|---|
ghostflow |
Launch interactive TUI |
ghostflow start |
Start the daemon |
ghostflow stop |
Stop the daemon |
ghostflow restart |
Restart the daemon |
ghostflow add <path> |
Add a repository to sync |
ghostflow remove <name> |
Remove a repository |
ghostflow list |
List all configured repositories |
ghostflow status |
Show daemon health and statistics |
ghostflow sync [name] |
Force immediate sync |
ghostflow pause [name] |
Pause syncing for a repository |
ghostflow resume [name] |
Resume syncing |
ghostflow add <path> [options]
-n, --name <name> Display name for the flow
-r, --remote <remote> Git remote (default: origin)
-b, --branch <branch> Git branch (default: main)
ghostflow list [options]
--compact Compact output
--json JSON output
--paths Show paths only
ghostflow status [options]
--compact Compact output
--json JSON outputConfiguration lives at ~/.ghostflow/config.json:
{
"version": 1,
"flows": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"path": "/Users/you/Vaults/PersonalVault",
"name": "obsidian",
"remote": "origin",
"branch": "main",
"enabled": true
}
],
"daemon": {
"pullIntervalSeconds": 300,
"debounceIntervalSeconds": 2
}
}| Option | Default | Description |
|---|---|---|
pullIntervalSeconds |
300 | How often to pull from remote (10–3600) |
debounceIntervalSeconds |
2 | Wait time after file changes before syncing (0.1–60) |
After editing manually, run ghostflow restart to apply changes.
┌─────────────────────────────────────────────────────────────┐
│ Ghostflow Daemon │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ FlowActor │ │ FlowActor │ │ FlowActor │ │
│ │ (obsidian) │ │ (dotfiles) │ │ (wiki) │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ └──────────────────┼──────────────────┘ │
│ │ │
│ ┌──────────┴──────────┐ │
│ │ PathDemultiplexer │ │
│ │ (radix trie) │ │
│ └──────────┬──────────┘ │
│ │ │
│ ┌───────┴───────┐ │
│ │ FSEvents │ │
│ │ Watcher │ │
│ └───────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
Unix Domain Socket
│
┌─────────────────────────────────────────────────────────────┐
│ CLI / TUI / SDK │
└─────────────────────────────────────────────────────────────┘
Under the hood:
- Actor Model: Each repository runs as an independent Swift actor—slow operations on one never block others
- FSEvents: Native macOS file system events with intelligent debouncing
- Smart Filtering: Automatically ignores
.git, temp files, and editor swap files - Conflict Detection: Pauses syncing and alerts you when merge conflicts occur
import { Effect, Layer } from "effect"
import { GhostflowClient, GhostflowClientLayer, UnixSocketTransportLayer } from "@ghostflow/client"
const ClientLayer = GhostflowClientLayer.pipe(Layer.provide(UnixSocketTransportLayer))
const program = Effect.gen(function*() {
const client = yield* GhostflowClient
const status = yield* client.status()
console.log(`Daemon: ${status.status}`)
const { flows } = yield* client.listFlows()
for (const flow of flows) {
console.log(`${flow.name}: ${flow.state}`)
}
})
Effect.runPromise(program.pipe(Effect.provide(ClientLayer)))import { createPromiseClient } from "@ghostflow/client/promise"
const client = await createPromiseClient()
const status = await client.status()
const flows = await client.listFlows()
await client.sync("obsidian")import {
useFlows,
useSyncFlow,
useEventSubscription,
GhostflowClientProvider,
queryClient
} from "@ghostflow/ui-core"
function Dashboard() {
const { data: flows, isLoading } = useFlows()
const { mutate: sync } = useSyncFlow()
useEventSubscription() // Subscribe to real-time updates
if (isLoading) return <div>Loading...</div>
return (
<ul>
{flows?.map(flow => (
<li key={flow.id}>
{flow.name}: {flow.state}
<button onClick={() => sync(flow.id)}>Sync</button>
</li>
))}
</ul>
)
}ghostflow status # Check status
ghostflow start # Start daemon
tail -f ~/Library/Logs/ghostflow/daemon.log # View logsghostflow list # Check flow status
ghostflow sync <name> # Force sync to retry
ghostflow resume <name> # Resume if quarantinedls -la /tmp/ghostflow.sock # Check socket exists
ghostflow restart # Restart daemon| Code | Meaning |
|---|---|
| E1001 | Socket connection failed |
| E1002 | Request timeout |
| E2001 | Daemon not running |
| E2002 | Flow quarantined (merge conflict) |
| E3001 | Git authentication failed |
| E3002 | Merge conflict detected |
| Feature | Ghostflow | git-sync | Obsidian Git | Manual scripts |
|---|---|---|---|---|
| Background daemon | Yes | No | No | No |
| Multi-repo support | Yes | Limited | No | Manual |
| Conflict detection | Yes | No | Limited | Manual |
| Real-time events | Yes | No | No | No |
| Type-safe SDK | Yes | No | No | No |
| macOS native | Yes | No | No | No |
| Package | Description | Version |
|---|---|---|
@ghostflow/cli |
CLI and interactive TUI | 0.1.5 |
@ghostflow/client |
Effect-TS SDK | 0.1.3 |
@ghostflow/ui-core |
React Query hooks | 0.1.3 |
@ghostflow/daemon-darwin-arm64 |
Daemon binary (Apple Silicon) | 0.1.2 |
@ghostflow/daemon-darwin-x64 |
Daemon binary (Intel) | 0.1.2 |
- Node.js 18+
- pnpm 8+
- Swift 5.9+ (Xcode 15+)
git clone https://github.com/ryannono/ghostflow.git
cd ghostflow
pnpm install
pnpm buildcd packages/daemon
swift build -c releasepnpm test # All packages
pnpm --filter @ghostflow/client test
pnpm --filter @ghostflow/cli testpackages/
├── daemon/ # Swift macOS daemon
├── client/ # TypeScript SDK (Effect-TS)
├── cli/ # CLI + Ink TUI
├── ui-core/ # React Query hooks
└── daemon-darwin-* # Prebuilt binaries
MIT — see LICENSE for details.