npm package: @kilnwork/ghostflow-cli
Description: CLI for Ghostflow daemon management
Latest version: 0.1.1
Deprecated: Moved to ghostflow-cli

# @ghostflow/cli

> Command-line interface and interactive dashboard for Ghostflow — automatic git synchronization that runs in the background.

[![npm version](https://img.shields.io/npm/v/@ghostflow/cli)](https://www.npmjs.com/package/@ghostflow/cli)
[![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue)](https://www.typescriptlang.org/)
[![Effect-TS](https://img.shields.io/badge/Effect--TS-Powered-purple)](https://effect.website/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](../../LICENSE)

**Stop manually syncing. Start automatically flowing.**

Ghostflow eliminates the tedious `git pull`, `commit`, `push` workflow. Point it at a repository, and it syncs silently in the background. Perfect for Obsidian vaults, dotfiles, shared notes, or any repo you want always in sync.

---

## Table of Contents

- [Features](#features)
- [Quick Start](#quick-start)
- [Commands](#commands)
- [Interactive Dashboard](#interactive-dashboard)
- [Use Cases](#use-cases)
- [Configuration](#configuration)
- [Output Formats](#output-formats)
- [Troubleshooting](#troubleshooting)
- [Programmatic Usage](#programmatic-usage)
- [Development](#development)
- [Architecture](#architecture)
- [License](#license)

---

## Features

- **9 CLI commands** for complete daemon and flow management
- **Interactive TUI dashboard** with real-time sync status and keyboard navigation
- **First-run setup automation** — config directory, launchd plist, and prompts handled automatically
- **Smart conflict detection** — merge conflicts are quarantined, not force-pushed
- **Multiple output formats** — human-readable, compact one-liners, and JSON for scripting
- **Type-safe Effect-TS stack** — built with `@effect/cli`, `effect`, and Ink React

---

## Quick Start

Get syncing in 60 seconds:

```bash
# Install
npm install -g @ghostflow/cli

# Start the daemon (auto-setup on first run)
ghostflow start

# Add a repository to sync
ghostflow add ~/Documents/my-vault

# Done! Your repository now syncs automatically.
# Check status anytime:
ghostflow status
ghostflow list
```

**What happens on first run:**

1. CLI auto-detects or downloads the daemon binary
2. Creates config directory at `~/Library/Application Support/ghostflow/`
3. Generates launchd plist for automatic startup
4. Starts the daemon and verifies it's running

---

## Commands

### Daemon Control

| Command | Description |
|---------|-------------|
| `ghostflow start` | Start the daemon (runs first-time setup if needed) |
| `ghostflow stop` | Stop the daemon cleanly |
| `ghostflow restart` | Restart the daemon |
| `ghostflow status` | Show daemon health, uptime, and sync metrics |

**Examples:**

```bash
# Start with custom daemon binary path
ghostflow start --daemon-path /path/to/ghostflow-daemon

# Check daemon health
ghostflow status
# Output: ● healthy | uptime: 5h 23m | syncs: 42/45

# JSON output for scripts
ghostflow status --json
```

### Flow Management

| Command | Description |
|---------|-------------|
| `ghostflow add <path>` | Add a git repository to sync |
| `ghostflow remove <flowId>` | Remove a repository from syncing |
| `ghostflow list` | List all tracked repositories |

**Examples:**

```bash
# Add with custom name, remote, and branch
ghostflow add ~/projects/api --name "api" --remote "origin" --branch "develop"

# List flows in compact format
ghostflow list --compact

# Get just the paths (useful for scripts)
ghostflow list --paths
# Output:
# /Users/you/Documents/my-vault
# /Users/you/projects/api

# Remove without confirmation prompt
ghostflow remove abc123 --force
```

### Sync Operations

| Command | Description |
|---------|-------------|
| `ghostflow sync [flowId]` | Trigger immediate sync (all flows or specific one) |

**Examples:**

```bash
# Sync all flows immediately
ghostflow sync

# Sync a specific flow
ghostflow sync abc123
```

### Configuration

| Command | Description |
|---------|-------------|
| `ghostflow migrate` | Migrate from legacy REPO_PATH config to multi-flow format |

**Examples:**

```bash
# Preview migration without making changes
ghostflow migrate --dry-run

# Force migration even if already migrated
ghostflow migrate --force
```

---

## Interactive Dashboard

Run `ghostflow` without arguments to launch the TUI dashboard:

```bash
ghostflow
```

```
╭─ Ghostflow Dashboard ─────────────────────────────────────────────╮
│                                                                    │
│ ● healthy | uptime: 5h 23m | syncs: 42/45                         │
│                                                                    │
│ ● my-vault                                                         │
│   ~/Documents/my-vault                                             │
│   Last sync: 2m ago  ✓ Clean                                       │
│                                                                    │
│ ◐ api                                                              │
│   ~/projects/api                                                   │
│   Syncing...                                                       │
│                                                                    │
│ ✗ dotfiles                                                         │
│   ~/dotfiles                                                       │
│   Error: merge conflict                                            │
│                                                                    │
│ [a] add  [r] remove  [s] sync  [p] pause  [q] quit                │
╰────────────────────────────────────────────────────────────────────╯
```

**Keyboard Controls:**

| Key | Action |
|-----|--------|
| `↑` / `↓` | Navigate flow list |
| `a` | Add new repository (wizard) |
| `r` | Remove selected repository |
| `s` | Sync selected repository |
| `p` | Pause/resume selected repository |
| `q` | Quit dashboard |

**Flow Status Indicators:**

| Symbol | State |
|--------|-------|
| `●` | Clean — synced, no pending changes |
| `◐` | Syncing — sync in progress |
| `✗` | Error — last sync failed |
| `⏸` | Paused — manually paused or quarantined |

---

## Use Cases

### Knowledge Base Sync (Obsidian, Dendron)

Keep your notes automatically synced across devices:

```bash
ghostflow start
ghostflow add ~/Documents/my-vault
# Notes sync automatically when you save
```

### Dotfiles Across Machines

Your dotfiles, always up to date:

```bash
ghostflow add ~/dotfiles --name "dotfiles" --branch "main"
# Changes sync without manual commits
```

### Multi-Repo Development

Track multiple projects at once:

```bash
ghostflow add ~/projects/api --name "api"
ghostflow add ~/projects/web --name "web"
ghostflow add ~/projects/mobile --name "mobile"

# See all at a glance
ghostflow list
```

### CI/Monitoring Integration

Use JSON output for scripting:

```bash
# Check if daemon is healthy
if ghostflow status --compact | grep -q "healthy"; then
  echo "All good"
fi

# Get flow paths for backup scripts
ghostflow list --paths | xargs -I {} cp -r {} /backup/

# Parse JSON for custom metrics
ghostflow status --json | jq '.metrics.successfulSyncs'
```

---

## Configuration

### File Locations (macOS)

| File | Path |
|------|------|
| Config directory | `~/Library/Application Support/ghostflow/` |
| Config file | `~/Library/Application Support/ghostflow/config.json` |
| Launchd plist | `~/Library/LaunchAgents/com.ghostflow.daemon.plist` |
| Daemon logs | `~/Library/Logs/ghostflow/daemon.log` |

### Config File Structure

```json
{
  "version": 1,
  "flows": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "path": "/Users/you/Documents/my-vault",
      "name": "my-vault",
      "remote": "origin",
      "branch": "main",
      "enabled": true
    }
  ],
  "daemon": {
    "pullIntervalSeconds": 300,
    "debounceIntervalSeconds": 10
  }
}
```

### Environment Variables

| Variable | Description | Default |
|----------|-------------|---------|
| `GHOSTFLOW_SOCKET_PATH` | Unix socket for daemon IPC | `/tmp/ghostflow.sock` |
| `GHOSTFLOW_CONFIG_DIR` | Override config directory | Platform default |
| `GHOSTFLOW_LOG_LEVEL` | Logging verbosity | `info` |

---

## Output Formats

All list and status commands support multiple output formats:

### Human-Readable (Default)

```bash
ghostflow status
```

```
● Ghostflow Daemon: healthy
  Uptime: 5h 23m
  Successful syncs: 42
  Failed syncs: 3
  Flows: 3 active
```

### Compact (Single Line)

```bash
ghostflow status --compact
# ● healthy | uptime: 5h 23m | syncs: 42/45
```

### JSON (Structured)

```bash
ghostflow status --json
```

```json
{
  "status": "healthy",
  "uptimeSeconds": 19380,
  "metrics": {
    "successfulSyncs": 42,
    "failedSyncs": 3
  },
  "flowCount": 3
}
```

### Paths Only (for Scripts)

```bash
ghostflow list --paths
```

```
/Users/you/Documents/my-vault
/Users/you/projects/api
/Users/you/dotfiles
```

---

## Troubleshooting

### "Ghostflow daemon is not running"

The daemon isn't started or crashed.

```bash
# Start the daemon
ghostflow start

# Check status
ghostflow status

# View logs for errors
tail -f ~/Library/Logs/ghostflow/daemon.log
```

### "Daemon binary not found"

The platform-specific daemon package isn't installed.

```bash
# Install for Apple Silicon
npm install @ghostflow/daemon-darwin-arm64

# Install for Intel Mac
npm install @ghostflow/daemon-darwin-x64
```

### "Not a git repository"

You tried to add a directory that isn't a git repo.

```bash
# Initialize git first
cd ~/my-folder
git init
git remote add origin git@github.com:you/repo.git

# Then add to Ghostflow
ghostflow add ~/my-folder
```

### "Path is already being tracked"

The repository is already registered.

```bash
# View existing flows
ghostflow list

# Remove the old flow first
ghostflow remove <flow-id>

# Then add again
ghostflow add ~/my-repo
```

### "Merge conflict detected (quarantined)"

The daemon detected a conflict and paused the flow to prevent data loss.

```bash
# Navigate to the repo and resolve manually
cd ~/my-vault
git status
# Fix conflicts...
git add .
git commit -m "Resolve merge conflict"

# Resume syncing
ghostflow sync <flow-id>
```

### "Daemon failed to start"

Check the daemon logs for details:

```bash
tail -100 ~/Library/Logs/ghostflow/daemon.log
```

Common causes:
- Daemon binary missing or not executable
- Socket file locked by previous instance
- Config file malformed

---

## Programmatic Usage

The CLI exports commands and formatters for integration:

```typescript
import {
  statusCommand,
  addCommand,
  listCommand,
  formatStatus,
  formatFlows,
  resolveDaemonPath,
  validateDaemonPath
} from "@ghostflow/cli"

// Use formatters for custom output
const status = await client.status()
console.log(formatStatus(status))

// Resolve daemon binary location
const daemonPath = await resolveDaemonPath()
```

### Available Exports

**Commands** (for @effect/cli composition):
- `statusCommand`, `startCommand`, `stopCommand`, `restartCommand`
- `listCommand`, `addCommand`, `syncCommand`

**Formatters:**
- `formatStatus`, `formatStatusCompact`
- `formatFlows`, `formatFlowsCompact`, `formatFlowPaths`
- `formatDuration`, `formatRelativeTime`

**Utilities:**
- `resolveDaemonPath` — Auto-detect daemon binary
- `validateDaemonPath` — Validate user-provided paths

---

## Development

### Prerequisites

- Node.js 18+
- pnpm 8+

### Setup

```bash
# Clone the monorepo
git clone https://github.com/ghostflow/ghostflow.git
cd ghostflow

# Install dependencies
pnpm install

# Build all packages
pnpm build
```

### Available Scripts

| Script | Description |
|--------|-------------|
| `pnpm build` | Build TypeScript to dist/ |
| `pnpm test` | Run test suite |
| `pnpm test:watch` | Run tests in watch mode |
| `pnpm check` | Type-check without emitting |
| `pnpm lint` | Lint source files |
| `pnpm lint:fix` | Fix lint issues |

### Running Locally

```bash
# Run CLI directly
pnpm start

# Or via the bin script
./bin/ghostflow.js status
```

---

## Architecture

This package uses a modern Effect-TS stack:

| Layer | Technology | Purpose |
|-------|------------|---------|
| CLI Parsing | `@effect/cli` | Type-safe command definitions and help generation |
| Core Runtime | `effect` | Functional error handling, async composition, services |
| Terminal UI | `ink` (React 19) | Terminal-native React components |
| Navigation | `xstate` | Type-safe state machine for screen routing |
| Async State | `@tanstack/react-query` | Cache and sync TUI data |
| IPC Client | `@ghostflow/client` | Effect-based daemon communication |

### Project Structure

```
packages/cli/
├── src/
│   ├── main.ts              # Entry point (CLI vs TUI routing)
│   ├── commands/            # 9 CLI command handlers
│   ├── tui/                 # Ink React components and screens
│   │   ├── App.tsx          # Root component with providers
│   │   ├── screens/         # Dashboard, AddWizard, ConfirmDialog
│   │   ├── components/      # FlowList, StatusBadge, KeyHints
│   │   └── machines/        # XState navigation machine
│   ├── formatters/          # Output formatting utilities
│   ├── layers/              # Effect service composition
│   ├── resolver.ts          # Daemon binary resolution
│   └── setup.ts             # First-run setup automation
├── bin/
│   └── ghostflow.js         # Node.js entrypoint
└── tests/                   # Unit and integration tests
```

For detailed architecture documentation, see [ARCHITECTURE.md](./ARCHITECTURE.md).

---

## License

MIT — see [LICENSE](../../LICENSE) for details.

---

**[Report Issues](https://github.com/ghostflow/ghostflow/issues)** · **[View Changelog](../../CHANGELOG.md)** · **[Architecture Guide](./ARCHITECTURE.md)**