Skip to content

ryannono/Ghostflow

Repository files navigation

Ghostflow - Set it once. Sync forever.

npm version License macOS 12+ TypeScript

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.


Why Ghostflow?

Your digital life, perfectly synchronized

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.

Life with Ghostflow

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.

Built for

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.


How It Works

Ghostflow runs as a background daemon on your Mac. When you save a file in a watched repository:

  1. Detect — Ghostflow notices the change instantly via macOS file system events
  2. Commit — Changes are automatically committed with a timestamp
  3. 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.


Get Started

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 start

That's it. Your repository is now syncing automatically in the background.

Run ghostflow status to verify everything is working.


Installation

Prerequisites

  • macOS 12+ (Monterey or later)
  • Node.js 18+
  • Git 2.0+

Install via npm

npm install -g @ghostflow/cli

This installs the CLI and automatically downloads the correct daemon binary for your architecture (Apple Silicon or Intel).

Verify installation

ghostflow --version
ghostflow status

Usage Examples

Sync an Obsidian Vault

ghostflow add ~/Documents/Obsidian/MyVault -n obsidian -r origin -b main
ghostflow start

Your notes are now backed up automatically. Edit on your laptop, and the changes appear on your desktop.

Sync Dotfiles

ghostflow add ~/.dotfiles -n dotfiles -r origin -b main

Sync Multiple Repositories

ghostflow add ~/Projects/notes -n work-notes
ghostflow add ~/Projects/wiki -n team-wiki
ghostflow list

Each repository syncs independently—a slow network on one never blocks another.

Force a Manual Sync

ghostflow sync obsidian      # Sync specific flow
ghostflow sync               # Sync all flows

Pause and Resume

ghostflow pause obsidian     # Stop syncing temporarily
ghostflow resume obsidian    # Resume syncing

Interactive TUI

Launch 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/k to move, s to sync, p to pause)
  • Auto-starts the daemon if not running

CLI Reference

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

Options

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 output

Configuration

Configuration 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
  }
}

Configuration Options

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.


Architecture

┌─────────────────────────────────────────────────────────────┐
│                     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

SDK & Integration

Effect-TS Client

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)))

Promise API

import { createPromiseClient } from "@ghostflow/client/promise"

const client = await createPromiseClient()

const status = await client.status()
const flows = await client.listFlows()
await client.sync("obsidian")

React Query Hooks

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>
  )
}

Troubleshooting

Daemon not running

ghostflow status        # Check status
ghostflow start         # Start daemon
tail -f ~/Library/Logs/ghostflow/daemon.log  # View logs

Flow in error state

ghostflow list          # Check flow status
ghostflow sync <name>   # Force sync to retry
ghostflow resume <name> # Resume if quarantined

Socket permission issues

ls -la /tmp/ghostflow.sock   # Check socket exists
ghostflow restart            # Restart daemon

Common error codes

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

Comparison

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

Packages

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

Development

Prerequisites

  • Node.js 18+
  • pnpm 8+
  • Swift 5.9+ (Xcode 15+)

Setup

git clone https://github.com/ryannono/ghostflow.git
cd ghostflow
pnpm install
pnpm build

Build daemon

cd packages/daemon
swift build -c release

Run tests

pnpm test                    # All packages
pnpm --filter @ghostflow/client test
pnpm --filter @ghostflow/cli test

Project structure

packages/
├── daemon/           # Swift macOS daemon
├── client/           # TypeScript SDK (Effect-TS)
├── cli/              # CLI + Ink TUI
├── ui-core/          # React Query hooks
└── daemon-darwin-*   # Prebuilt binaries

License

MIT — see LICENSE for details.


Report an issue · Contribute