{"id":47736072,"url":"https://github.com/mschulkind-oss/swarf","last_synced_at":"2026-04-07T02:01:07.405Z","repository":{"id":348166610,"uuid":"1196769993","full_name":"mschulkind-oss/swarf","owner":"mschulkind-oss","description":null,"archived":false,"fork":false,"pushed_at":"2026-04-02T20:48:02.000Z","size":249,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-03T07:10:09.205Z","etag":null,"topics":["ai-agents","developer-tools","git","python","sync"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mschulkind-oss.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"docs/ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-03-31T02:52:05.000Z","updated_at":"2026-04-02T20:48:05.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/mschulkind-oss/swarf","commit_stats":null,"previous_names":["mschulkind-oss/swarf"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/mschulkind-oss/swarf","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mschulkind-oss%2Fswarf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mschulkind-oss%2Fswarf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mschulkind-oss%2Fswarf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mschulkind-oss%2Fswarf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mschulkind-oss","download_url":"https://codeload.github.com/mschulkind-oss/swarf/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mschulkind-oss%2Fswarf/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31381007,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-03T21:40:47.592Z","status":"ssl_error","status_checked_at":"2026-04-03T21:40:05.436Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-agents","developer-tools","git","python","sync"],"created_at":"2026-04-02T22:39:12.867Z","updated_at":"2026-04-03T23:01:00.965Z","avatar_url":"https://github.com/mschulkind-oss.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Swarf\n\n[![CI](https://github.com/mschulkind-oss/swarf/actions/workflows/ci.yml/badge.svg)](https://github.com/mschulkind-oss/swarf/actions/workflows/ci.yml)\n[![PyPI](https://img.shields.io/pypi/v/swarf)](https://pypi.org/project/swarf/)\n[![Go](https://img.shields.io/badge/go-%3E%3D1.26-blue)](https://go.dev/)\n[![License](https://img.shields.io/github/license/mschulkind-oss/swarf)](LICENSE)\n\nInvisible, auto-syncing personal storage for any git repo.\n\nYou build software and generate byproduct — research docs, design specs,\nagent skills, scratch notes. Swarf gives this material a durable home\nalongside any project, without touching the project itself.\n\n## The problem\n\nYou have files that should live near your code but don't belong in the repo:\n\n- Agent instructions and skills (`AGENTS.md`, `.copilot/skills/`)\n- Research notes, design docs, open questions\n- Security audits, experiment logs, scratch work\n\nToday these files are either **untracked and local-only** (one `rm -rf` from\ngone) or **committed to the repo** (polluting history, leaking on public\nrepos). Neither is good.\n\n## How it works\n\nSwarf creates a `swarf/` directory inside your project. Everything in it is\nautomatically excluded from git via `.git/info/exclude`. A background daemon\nwatches for changes, mirrors them to a central store, and syncs to your\nconfigured remote (a git repo or any rclone backend).\n\n```\nmy-project/\n├── src/\n├── swarf/                         ← private storage (invisible to git)\n│   ├── docs/                      ← research, design, anything\n│   ├── .links/                    ← files projected into the host tree\n│   │   └── AGENTS.md\n│   └── open-questions.md\n├── AGENTS.md → swarf/.links/AGENTS.md   ← symlink (also gitignored)\n└── .git/info/exclude              ← managed by swarf\n```\n\nThe central store at `~/.local/share/swarf/` mirrors all projects into a\nsingle git repo. The daemon commits changes locally, then pushes to your\nremote. For rclone backends, the entire store is synced — both working\nfiles and `.git/`. This means you can browse your files directly in Google\nDrive (or whatever backend), and you get full commit history too.\n\n## Install\n\n```bash\n# macOS / Linux (recommended)\nbrew tap mschulkind-oss/tap \u0026\u0026 brew install swarf\n\n# Via PyPI (persistent install to ~/.local/bin/)\npipx install swarf        # or: uv tool install swarf\n\n# Via Go\ngo install github.com/mschulkind-oss/swarf@latest\n\n# From source\ngit clone https://github.com/mschulkind-oss/swarf \u0026\u0026 cd swarf\njust deploy   # builds and copies to ~/.local/bin/\n```\n\n\u003e **Warning:** Don't use `pip install swarf` inside a virtualenv or `uvx swarf`.\n\u003e The daemon records the binary's absolute path and breaks when the venv\n\u003e disappears. `swarf doctor` detects this and warns you.\n\n## Quick start\n\n```bash\ncd ~/projects/my-app\nswarf init\n```\n\nOn first run, `init` walks you through setup:\n\n```\nNo global config found. Let's set one up.\n\n  Backend [git/rclone] (git): git\n  Remote URL (your private backup repo): git@github.com:you/my-swarf.git\n✓ Wrote ~/.config/swarf/config.toml\n✓ Created central store at ~/.local/share/swarf\n✓ Initialized swarf/ for my-app\n  Install systemd service for auto-sync? [Y/n] y\n✓ Installed systemd service — daemon is running\n✓ Daemon is running (PID 12345)\n\n✓ All checks passed.\n```\n\nNext time you run `swarf init` in another project — no prompts, instant setup.\n\n### Rclone backend (Google Drive, Dropbox, S3, etc.)\n\nSet up an rclone remote first:\n\n```bash\nbrew install rclone\nrclone config\n#   → n (new remote), name: gdrive, type: drive\n#   → scope: drive.file (option 2 — only files rclone creates)\n#   → auto config: y (opens browser for OAuth)\n```\n\nThen run `swarf init`, pick `rclone`, and select your remote from the\nnumbered menu. Swarf defaults to `swarf-store` as the directory path:\n\n```\n  Backend [git/rclone] (git): rclone\n\n  Pick an rclone remote:\n\n    1. gdrive:\n\n  Enter a number (1-1), or q to quit: 1\n\n  Directory path on gdrive: [swarf-store]:\n✓ Remote: gdrive:swarf-store\n```\n\nThe store is always a local git repo. Rclone syncs the whole store to\nthe remote — your files are browseable directly in Google Drive (or\nwherever), and you get full git history via the `.git/` directory.\n\n## Using swarf\n\n### Drop files in\n\n```bash\necho \"# Design Notes\" \u003e swarf/docs/design.md\n```\n\nThat's it. The daemon commits and syncs after a 5-second quiet period.\n\n### Sweep files into the host tree\n\nSome files need to appear at a specific path in the project (like `AGENTS.md`\nin the root). Use `sweep` to move them into swarf while leaving a symlink:\n\n```bash\nswarf sweep AGENTS.md\n# AGENTS.md → swarf/.links/AGENTS.md\n\nswarf sweep CLAUDE.md .copilot/skills/SKILL.md\n```\n\nBoth the original path and `swarf/` are automatically gitignored. Symlinks\nare relative, so they work across machines and inside containers.\n\nTo reverse a sweep:\n\n```bash\nswarf unlink AGENTS.md\n```\n\n### Auto-sweep\n\nConfigure files to be swept automatically whenever they appear:\n\n```toml\n# ~/.config/swarf/config.toml\n[auto_sweep]\npaths = [\"AGENTS.md\", \"CLAUDE.md\", \".copilot/skills/\"]\n```\n\nThe daemon watches for these files and sweeps them on creation.\n\n### Check status\n\n```bash\nswarf status\n```\n\nShows store state, pending files, remote verification, and daemon health:\n\n```\nStore\n  Path           ~/.local/share/swarf\n  Backend        git\n  Remote         git@github.com:you/my-swarf.git\n  Pending        all synced to remote\n  Last commit    2 minutes ago — auto: sync 3 files\n  Local save     2m ago\n  Remote push    2m ago\n  Remote sync    verified — local and remote match (a1b2c3d4)\n\nProjects\n╭──────────┬─────────────────────┬──────────╮\n│ PROJECT  │ PATH                │ STATUS   │\n├──────────┼─────────────────────┼──────────┤\n│ my-app   │ ~/projects/my-app   │ ✓ ok     │\n│ api      │ ~/work/api          │ ✓ ok     │\n╰──────────┴─────────────────────┴──────────╯\n\nDaemon: running (PID 12345)\n```\n\n### Doctor\n\n`swarf doctor` checks everything and fixes what it can:\n\n```bash\nswarf doctor\n```\n\nDoctor handles: missing config, missing store, broken symlinks, absolute\nsymlinks, missing gitignore entries, service installation, and remote\nreachability. Errors include the exact fix command or config file to edit.\n\n`init` and `doctor` share the same engine — the difference is that `init`\ncreates `swarf/` in a new directory, while `doctor` only checks and repairs.\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| `swarf init` | Set up swarf in the current project |\n| `swarf sweep \u003cfile\u003e...` | Move files into `swarf/.links/` and symlink back |\n| `swarf unlink \u003cfile\u003e...` | Reverse a sweep — restore symlinks to regular files |\n| `swarf doctor` | Check health and fix problems (config, store, service, links) |\n| `swarf status` | Show projects, sync state, remote verification, daemon health |\n| `swarf clone` | Clone the store from your configured remote (new machine setup) |\n| `swarf pull` | Pull latest changes from the remote into the store |\n| `swarf daemon start` | Start the background sync daemon (`--foreground` for debugging) |\n| `swarf daemon stop` | Stop the daemon |\n| `swarf daemon status` | Check if the daemon is running |\n| `swarf daemon install` | Install as system service (systemd on Linux, launchd on macOS) |\n| `swarf docs [topic]` | Browse built-in documentation |\n\n## Second machine setup\n\n```bash\nbrew install swarf\nswarf clone              # clones your store from the configured remote\ncd ~/projects/my-app\nswarf init               # re-links the project from the store\n```\n\n`clone` requires global config to exist (with the remote URL). After cloning,\nrun `swarf init` in each project directory to recreate the local `swarf/`\ndirectory and symlinks.\n\n## Containers and jails\n\nThe daemon runs on the **host**. Containers mount the project directory, so\n`swarf/` comes along. Agents read and write to `swarf/` directly — the host\ndaemon picks up changes and syncs.\n\nInside a container, `swarf doctor` detects the environment (no global config),\nskips system checks, and validates project-local state only. `sweep` and\n`unlink` work without the daemon. Symlinks are relative, so they resolve\ncorrectly regardless of mount path.\n\n## Guides\n\n- **[Configuration Guide](docs/CONFIGURATION.md)** — all config options,\n  file locations, environment variables, and examples\n- **[Roadmap](docs/ROADMAP.md)** — planned features and distribution channels\n- **Built-in docs:** `swarf docs` lists all topics (`quickstart`,\n  `architecture`, `config`, `sweep`, `daemon`, `backends`)\n\n## License\n\nApache 2.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmschulkind-oss%2Fswarf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmschulkind-oss%2Fswarf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmschulkind-oss%2Fswarf/lists"}