Metadata-Version: 2.4
Name: github-sync-agent
Version: 0.3.0
Summary: Sync all your local projects to GitHub automatically
Author-email: GitHub Sync Agent Maintainers <yuvalavni@users.noreply.github.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/yuvalavni/Agents
Project-URL: Repository, https://github.com/yuvalavni/Agents
Project-URL: Issues, https://github.com/yuvalavni/Agents/issues
Keywords: github,git,sync,backup,automation,cli,api
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: POSIX :: Linux
Classifier: Environment :: Console
Classifier: Topic :: Software Development :: Version Control :: Git
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: pyyaml>=6.0
Requires-Dist: click>=8.0
Provides-Extra: api
Requires-Dist: fastapi>=0.100; extra == "api"
Requires-Dist: uvicorn>=0.23; extra == "api"
Provides-Extra: mcp
Requires-Dist: mcp>=1.0; extra == "mcp"
Provides-Extra: llm
Requires-Dist: httpx>=0.27; extra == "llm"

# GitHub Sync Agent

Automatically syncs every local project directory to its own GitHub repository.

For each project it will:
1. `git init` if not already a repo
2. Create the GitHub repo if it doesn't exist yet
3. Ensure the remote uses SSH
4. Stage + commit any uncommitted changes
5. Push to `origin`

Runs daily via a systemd user timer, and on-demand via CLI.

---

## Installation

```bash
pip install github-sync-agent                  # CLI + tools (base)
pip install 'github-sync-agent[api]'           # + web chat UI & HTTP API
pip install 'github-sync-agent[mcp]'           # + MCP server (Cursor / Claude Desktop)
pip install 'github-sync-agent[llm]'           # + ask command (requires Ollama)
pip install 'github-sync-agent[api,mcp,llm]'  # everything
```

**Prerequisites (all platforms):**
- Python 3.10+
- `git` — [git-scm.com](https://git-scm.com)
- `gh` (GitHub CLI) — [cli.github.com](https://cli.github.com)

**For `ask` command and web chat:**
- [Ollama](https://ollama.com) running locally (`ollama serve`)
- A downloaded model: `ollama pull gemma3:4b`

## First-time setup

```bash
github-sync init
```

The wizard will:
- Check `git` and `gh` are installed
- Authenticate with GitHub (`gh auth login`)
- Ask which folder to scan for projects
- Set up your SSH key automatically
- **Verify SSH works** (auto-fixes port 443 and ssh-agent if needed)
- Write a config file to `~/.config/github-sync/config.yaml`

Setup will **not** complete until `ssh -T git@github.com` succeeds.

---

## Usage

### Service management

```bash
# Check all prerequisites and service status
github-sync doctor

# Start everything (Ollama + HTTP API / web chat)
github-sync start

# Stop everything
github-sync stop

# If Ollama was installed as a system service and start/stop fails:
sudo systemctl start ollama
sudo systemctl stop ollama

# Fine-grained control
github-sync start --no-ollama   # start API only (Ollama already running)
github-sync stop --no-ollama    # stop API only, leave Ollama running
```

### Sync

```bash
# Sync all projects
github-sync sync

# Sync a single project
github-sync sync --project my-project

# Preview without making changes
github-sync sync --dry-run

# Show status of all projects
github-sync status
```

---

## Shared tools layer

`github_sync/tools.py` defines the core operations used by the API, MCP server, `ask` command, and web chat:

| Tool | Description |
|------|-------------|
| `list_projects` | List discoverable project directories |
| `get_status` | Git/remote/changes/GitHub status for all projects |
| `sync_all` | Sync every project (`dry_run` optional) |
| `sync_project` | Sync one project by name (`dry_run` optional) |

Inspect and test from CLI:

```bash
github-sync tool list
github-sync tool run list_projects
github-sync tool run get_status
github-sync tool run sync_project --arg project=Agents --arg dry_run=true
```

Each tool returns JSON: `{"ok": true/false, "message": "...", "data": {...}}`.

---

## MCP Server (Cursor / Claude Desktop)

Exposes the 4 tools above to any MCP host via stdio.

### Install

```bash
pip install 'github-sync-agent[mcp]'
```

### Register in Cursor

Add to `~/.cursor/mcp.json` (create if it doesn't exist):

```json
{
  "mcpServers": {
    "github-sync": {
      "command": "/path/to/.venv/bin/github-sync-mcp",
      "args": [],
      "env": {}
    }
  }
}
```

If you installed with pipx, the command is just `github-sync-mcp`.  
With a venv, find the path with:
```bash
which github-sync-mcp
# or: github-sync doctor
```

Then **reload Cursor** (`Ctrl+Shift+P` → *Reload Window*). The 4 tools will appear and the AI can call them directly.

### Run manually

```bash
github-sync-mcp
```

---

## Ask command (natural language via Ollama)

Install and start Ollama first (see [Local LLM](#local-llm-ollama--gemma) below), then:

```bash
pip install 'github-sync-agent[llm]'
```

```bash
github-sync ask what is the status of my projects
github-sync ask are there any uncommitted changes
github-sync ask sync the Agents project
github-sync ask sync everything dry run
```

The agent calls the appropriate tool (`get_status`, `sync_project`, etc.), gets real data, and answers in plain English. No cloud — runs entirely on your machine.

Override model or URL:
```bash
github-sync ask --model llama3.2 --ollama-url http://localhost:11434 "sync all"
```

---

## Web chat UI

```bash
pip install 'github-sync-agent[api,llm]'

# Start everything in one command
github-sync start
# → Open http://127.0.0.1:8741

# Or manually:
sudo systemctl start ollama   # start Ollama (system service)
github-sync serve             # start the web server
```

Features:
- Live project status strip (synced / unsynced / GitHub ✓)
- Chat interface — type naturally, press Enter
- Tool calls shown inline as collapsible cards
- Streaming responses from the local LLM
- Works entirely offline (no cloud)

---

## HTTP API

Install API dependencies:

```bash
pip install 'github-sync-agent[api]'
```

Start the server:

```bash
github-sync serve
# → http://127.0.0.1:8741
```

### Endpoints

| Method | Path | Description |
|--------|------|-------------|
| `GET` | `/health` | Health check (no auth) |
| `GET` | `/tools` | List available tools and JSON schemas |
| `GET` | `/status` | Sync status for all projects |
| `POST` | `/sync` | Sync all projects |
| `POST` | `/sync/{project}` | Sync one project |

Optional body for POST: `{"dry_run": false}`

### Examples

```bash
curl http://127.0.0.1:8741/health
curl http://127.0.0.1:8741/tools
curl http://127.0.0.1:8741/status
curl -X POST http://127.0.0.1:8741/sync
curl -X POST http://127.0.0.1:8741/sync/Agents
```

### API authentication (optional)

Add to `config.yaml`:

```yaml
api_key: "your-secret-key"
```

Then pass the key on every request (except `/health`):

```bash
curl -H "Authorization: Bearer your-secret-key" http://127.0.0.1:8741/status
```

### Run as a systemd service

```bash
cp systemd/github-sync-api.service ~/.config/systemd/user/
systemctl --user enable --now github-sync-api.service
```

---

## Configuration (`~/.config/github-sync/config.yaml`)

Generated by `github-sync init`. You can edit it at any time.

| Key | Default | Description |
|-----|---------|-------------|
| `github_user` | _(detected from gh auth)_ | Your GitHub username |
| `projects_root` | `~/projects` | Scans all subdirectories here |
| `schedule_time` | `02:00` | Daily run time |
| `default_visibility` | `private` | `private` or `public` for new repos |
| `auto_commit_message` | `chore: auto-sync` | Commit message for auto-commits |
| `exclude` | `[]` | Directory names to skip |
| `log_file` | `~/.local/share/github-sync/github-sync.log` | Log file path |
| `log_level` | `INFO` | `DEBUG` / `INFO` / `WARNING` / `ERROR` |
| `api_host` | `127.0.0.1` | API bind address |
| `api_port` | `8741` | API port |
| `api_key` | _(empty)_ | Optional Bearer token for API auth |
| `ollama_url` | `http://localhost:11434` | Ollama base URL for `ask` and web chat |
| `llm_model` | `gemma3:4b` | Ollama model name |
| `llm_timeout` | `120` | Seconds to wait for LLM response |

### Excluding a project

```yaml
exclude:
  - SomeProjectToSkip
```

---

## Local LLM (Ollama + Gemma)

The agent can use a local LLM via [Ollama](https://ollama.com). Gemma runs **inside** Ollama — you start/stop **Ollama**, not Gemma separately.

### Install (WSL / Linux, once)

```bash
sudo apt-get install -y zstd
curl -fsSL https://ollama.com/install.sh | sh
ollama pull gemma3:4b
```

### Start / stop Ollama

```bash
# Check if running
curl -s http://localhost:11434 && echo "Ollama is running"

# Start (systemd — typical after install)
sudo systemctl start ollama
sudo systemctl enable ollama    # optional: start on boot

# Stop
sudo systemctl stop ollama

# Start manually (foreground — Ctrl+C to stop)
ollama serve
```

On WSL with user systemd:

```bash
systemctl status ollama
systemctl start ollama
systemctl stop ollama
```

### Use the model

```bash
# Interactive chat
ollama run gemma3:4b

# One-shot prompt
ollama run gemma3:4b "Hello"

# List downloaded models
ollama list
```

### Quick reference

| Action | Command |
|--------|---------|
| Is it running? | `curl http://localhost:11434` |
| Start (service) | `sudo systemctl start ollama` |
| Stop (service) | `sudo systemctl stop ollama` |
| Start (manual) | `ollama serve` |
| Stop (manual) | `Ctrl+C` |
| Chat with Gemma | `ollama run gemma3:4b` |

Ollama listens on `http://localhost:11434` — used by `github-sync ask` and the web chat UI.

---

## License

MIT
