{"id":50803748,"url":"https://github.com/mayckol/fftracking","last_synced_at":"2026-06-26T17:00:36.320Z","repository":{"id":362166788,"uuid":"1257528996","full_name":"mayckol/fftracking","owner":"mayckol","description":"Local file-history \u0026 breaking-point tracker (JetBrains Local History style) — snapshot, diff, and revert by block/file/folder, plus local git compare \u0026 merge-conflict resolver. macOS/Linux.","archived":false,"fork":false,"pushed_at":"2026-06-22T12:10:51.000Z","size":10283,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-22T14:09:52.958Z","etag":null,"topics":["desktop-app","developer-tools","diff","file-watcher","git","linux","local-history","macos","monaco-editor","react","rust","snapshot","tauri","typescript","version-control"],"latest_commit_sha":null,"homepage":"https://github.com/mayckol/fftracking/releases/latest","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mayckol.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"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-06-02T19:08:12.000Z","updated_at":"2026-06-22T12:10:53.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/mayckol/fftracking","commit_stats":null,"previous_names":["mayckol/fftracking"],"tags_count":23,"template":false,"template_full_name":null,"purl":"pkg:github/mayckol/fftracking","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mayckol%2Ffftracking","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mayckol%2Ffftracking/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mayckol%2Ffftracking/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mayckol%2Ffftracking/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mayckol","download_url":"https://codeload.github.com/mayckol/fftracking/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mayckol%2Ffftracking/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34825611,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-26T02:00:06.560Z","response_time":106,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["desktop-app","developer-tools","diff","file-watcher","git","linux","local-history","macos","monaco-editor","react","rust","snapshot","tauri","typescript","version-control"],"created_at":"2026-06-12T23:01:35.784Z","updated_at":"2026-06-26T17:00:36.315Z","avatar_url":"https://github.com/mayckol.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cpicture\u003e\n    \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"assets/logo-dark.png\" /\u003e\n    \u003cimg src=\"assets/logo-light.png\" alt=\"fftracking\" width=\"340\" /\u003e\n  \u003c/picture\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  Local file-history \u0026amp; breaking-point tracker — IDE-style history view, independent of git.\u003cbr/\u003e\n  \u003cb\u003emacOS · Linux\u003c/b\u003e\n\u003c/p\u003e\n\n---\n\nfftracking watches your folders recursively and captures **breaking points**\n(snapshots) as you work — on every save and on a timer. Browse the timeline,\ndiff any point side-by-side, and revert by block, file, or folder. It also has a\nlocal **git compare** tab with per-block revert and a merge-conflict resolver.\n\nDrive it from the desktop app, the **`fft` command line**, or the built-in\n**MCP server** so AI agents can checkpoint and revert your work.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/screenshots/history.png\" alt=\"fftracking history view\" width=\"100%\" /\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\u003cem\u003eTimeline of breaking points · nested changed-files tree · side-by-side diff with per-block ⟲ revert.\u003c/em\u003e\u003c/p\u003e\n\n## Features\n\n- **Automatic breaking points** — captured on file save (debounced) and on an\n  interval; rapid saves coalesce into one point per configurable gap (default 20s).\n- **Content-addressed store** — blake3-deduplicated blobs; one changed file in a\n  10k-file tree stores a single new blob.\n- **Diff with inline revert** — Monaco side-by-side or inline, change-navigation\n  arrows, and an always-visible **⟲ revert icon** on every changed block.\n- **Revert anything** — per block (gutter ⟲), per file, or per folder; right-click\n  the changed-files tree to revert; in-diff editing with Cmd+Z / Cmd+Shift+Z.\n- **Git-aware comparison** — inside a repo, breaking points diff against the\n  **current branch (HEAD)** with one-click **Reset to branch**; outside git, against\n  the **previous point**. Every point shows added / modified / deleted badges.\n- **CLI + MCP** — the headless **`fft`** binary (and an `fft mcp` stdio server)\n  drive the same store as the app, so scripts and AI agents can track, snapshot,\n  diff, and revert.\n- **Labels** — name any breaking point (e.g. \"before refactor\").\n- **Editor auto-detect** — opens a folder in VSCode or Zed and fftracking starts\n  tracking the focused workspace automatically (no extensions).\n- **Local git** — **stage \u0026 commit** (pick files, write a message, commit), diff\n  branches / commits / working tree, per-block apply, and a 3-way merge-conflict\n  resolver (accept ours / theirs / both).\n- **Smart retention** — today stays dense, past days coalesce, anything past the\n  window is pruned, and the store is capped (default 1 GB).\n- **Lightweight** — runs in the tray, shows live CPU / memory in the title bar.\n- **Redis plugin** (opt-in, disabled by default) — browse keys, view/edit values,\n  set TTLs, and run raw commands. See [Redis plugin](#redis-plugin) for the OS\n  keychain permission it needs.\n\n## Screenshots\n\n### Local git — diff branches, commits, or the working tree\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/screenshots/git-compare.png\" alt=\"git compare view\" width=\"100%\" /\u003e\n\u003c/p\u003e\n\nCompare any two refs (here `develop → main`). Each changed block gets a **⟲**\nicon that applies that side's version into your working tree — works branch↔branch\nor against the working tree.\n\n### Resolve merge conflicts\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/screenshots/conflict-resolver.png\" alt=\"merge conflict resolver\" width=\"100%\" /\u003e\n\u003c/p\u003e\n\nA 3-way resolver per conflict region — **Accept ours / theirs / keep both** — with\nan editable result. **Mark resolved \u0026 stage** writes the file and stages it.\n\n## Install\n\n### Quick install (macOS / Linux)\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/mayckol/fftracking/main/scripts/install.sh | sh\n```\n\nInstalls the latest release — `fftracking.app` to `/Applications` on macOS\n(Apple Silicon), or the AppImage to `~/.local/bin/fftracking` on Linux (x86_64) —\nplus the headless **`fft`** CLI (+ MCP server) at `~/.local/bin/fft`.\nPin a version with `FFTRACKING_VERSION=v0.3.1`.\n\n### Homebrew (macOS)\n\n```bash\nbrew install --cask mayckol/tap/fftracking\n```\n\n### From a release\n\nDownload the artifact for your OS from the\n[Releases](https://github.com/mayckol/fftracking/releases) page:\n\n- **macOS** — `fftracking_\u003cversion\u003e_aarch64.dmg` (Apple Silicon). Open the DMG and\n  drag **fftracking** to Applications. First launch: right-click → **Open** (the\n  build is unsigned).\n- **Linux** — `.AppImage` (`chmod +x` then run) or `.deb`\n  (`sudo dpkg -i fftracking_\u003cversion\u003e_amd64.deb`).\n\n### Uninstall\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/mayckol/fftracking/main/scripts/install.sh | sh -s -- --uninstall\n```\n\nRemoves `fftracking.app` / the AppImage, the **`fft`** and **`fftrack`** CLIs, and\nthe Linux desktop entry + icon. Your tracked history (the app data dir) is kept.\nHomebrew installs uninstall with `brew uninstall --cask fftracking`.\n\n### From source\n\n**Requirements**\n\n- [Rust](https://rustup.rs) (stable) and Cargo\n- [Node.js](https://nodejs.org) 18+ and npm\n- **macOS**: Xcode Command Line Tools (`xcode-select --install`)\n- **Linux**: WebKitGTK + build deps, e.g. on Debian/Ubuntu:\n\n  ```bash\n  sudo apt update \u0026\u0026 sudo apt install -y \\\n    libwebkit2gtk-4.1-dev build-essential curl wget file \\\n    libxdo-dev libssl-dev libayatana-appindicator3-dev librsvg2-dev\n  ```\n\n**Build \u0026 install**\n\n```bash\ngit clone git@github.com:mayckol/fftracking.git\ncd fftracking\nnpm install\nnpm run tauri build\n```\n\nBundles land in `target/release/bundle/`:\n- macOS: `bundle/macos/fftracking.app` (copy to `/Applications`) and `bundle/dmg/`\n- Linux: `bundle/appimage/` and `bundle/deb/`\n\n## Develop\n\n```bash\nnpm install\nnpm run tauri dev     # hot-reload app (Vite + Rust)\ncargo test -p ffcore  # engine tests\n```\n\n### Logs\n\nThe app mirrors its webview console output and uncaught errors to **stdout** (the\n`npm run tauri dev` terminal) and to a log file you can follow live. On startup it\nprints the exact path:\n\n```\n📂 ff logs: \u003capp-log-dir\u003e/ff.log  (tail -f to follow)\n```\n\nDefault locations:\n\n- Linux: `~/.local/share/com.fftracking.app/logs/ff.log`\n- macOS: `~/Library/Logs/com.fftracking.app/ff.log`\n\n```bash\ntail -f ~/.local/share/com.fftracking.app/logs/ff.log\n```\n\nFor verbose **keyboard-shortcut** diagnostics — every keypress, the resolved\ncombo, and why it did or didn't fire — enable the debug channel from the in-app\ndevtools console, then reload:\n\n```js\nffShortcutsDebug(true)   // snapshot of key detection; disable with ffShortcutsDebug(false)\n```\n\n## Usage\n\n1. **+ Folder** (or just open a project in VSCode / Zed — it's picked up automatically).\n2. Edit files; breaking points appear in the timeline. **⦿ Snapshot now** forces one.\n3. Click a point → a file → see the diff. Toggle **vs before / vs now** and\n   **split / inline**. Use **↑ ↓** to jump between changes.\n4. Revert with the gutter **⟲**, the **Revert file / folder** buttons, or\n   right-click in the changed-files tree. Label a point with **🏷**, delete with **×**.\n5. **Git** tab — **Commit** mode to stage files (`+` / `−`), write a message, and\n   commit; **Compare** mode to diff two refs (or the working tree), apply blocks,\n   and resolve merge conflicts.\n6. **Settings** — interval, min gap, retention, disk cap, ignore globs, respect\n   `.gitignore` (off by default — like local history), launch on login.\n\n## Redis plugin\n\nA lightweight Redis client built into the app — browse keys, view and edit\nvalues, set TTLs, and run raw commands, in the spirit of JetBrains' Redis tool.\n\n**It is disabled by default.** Open the **Plugins** tab, find **Redis Cache**,\nclick **Add** to install it, and a **Redis** icon appears in the bottom status\nbar. Removing or disabling the plugin hides the view again.\n\n1. **+** in the Connections rail → fill host / port / db (and username / password\n   for ACL or `requirepass` servers) → **Save \u0026 Connect**.\n2. **Scan** with a pattern (`*`, `user:*`, …) to list keys; click one to inspect.\n3. Edit string values in place and **Save value**; set or clear a key's TTL;\n   delete a key. Collection types (list / set / hash / zset) are shown read-only —\n   edit them from the **console** at the bottom (`HSET user:1 name Ada`, etc.).\n\n### OS keychain permission\n\nConnection passwords are **never written to disk in plaintext**. When you tick\n*Remember password*, the password is stored in your operating system's keychain,\nwhich the OS must allow:\n\n| OS | Backend | What to expect |\n|----|---------|----------------|\n| **macOS** | Keychain | The system prompts the first time to allow access. |\n| **Windows** | Credential Manager | Works automatically, no prompt. |\n| **Linux** | Secret Service (D-Bus) | Needs a running secret service — **GNOME Keyring** or **KWallet** — in your desktop session. Headless / minimal setups without one have no keychain. |\n\nIf no keychain is available (commonly a barebones Linux session), fftracking does\n**not** persist the password — it asks for it each time you connect. You can also\nleave *Remember password* unticked to always be prompted.\n\n## Command line \u0026 AI agents (`fft`)\n\n`fft` is a headless front-end to the same store as the desktop app — anything it\ndoes shows up live in the GUI, and vice versa. The quick-install script and the\nHomebrew cask place it at `~/.local/bin/fft`.\n\n```bash\nfft track    --path ~/proj                 # start tracking (+ first point)\nfft snapshot --path ~/proj --label \"wip\"   # capture a breaking point now\nfft points   --path ~/proj                 # list points with +A ~M -D counts\nfft changes  --path ~/proj                 # what changed at the latest point\nfft diff     --path ~/proj --file src/a.ts # unified diff vs branch / prev point\nfft revert   --path ~/proj --point 42 --file src/a.ts\nfft reset    --path ~/proj --file src/a.ts # restore from the current git branch\nfft \u003ccmd\u003e --json                           # machine-readable output\nfft --help                                 # full reference\n```\n\nComparison follows the same rule as the app: the **current git branch (HEAD)** in\na repo, otherwise the **previous breaking point**.\n\n### MCP (Model Context Protocol)\n\n`fft mcp` is a stdio MCP server exposing `track`, `snapshot`, `points`, `changes`,\n`diff`, `revert`, `reset`, `label`, and `untrack` as tools, so an AI agent can\ncheckpoint and revert your work. Register it (e.g. with Claude):\n\n```bash\nclaude mcp add fftracking -- fft mcp\n```\n\n```json\n{ \"mcpServers\": { \"fftracking\": { \"command\": \"fft\", \"args\": [\"mcp\"] } } }\n```\n\n## Data\n\nState lives in the OS app-data dir (`db.sqlite` + `objects/\u003cblake3\u003e` blobs):\n\n- macOS: `~/Library/Application Support/com.fftracking.app/`\n- Linux: `~/.local/share/com.fftracking.app/`\n\nBy default fftracking tracks **everything** (so files like `.env` get history) and\nskips heavy dirs (`.git`, `node_modules`, `target`, `dist`, …) plus files \u003e 5 MB.\n\n## Architecture\n\n- **`crates/ffcore`** — Rust engine: watcher (`notify`), content-addressed store\n  (blake3 + SQLite), retention/prune, local git (`git2`), editor detection. Fully\n  unit-tested, no UI deps.\n- **`src-tauri`** — Tauri v2 shell: IPC commands, tray, autostart, detect daemon.\n- **`src`** — React + Monaco diff UI.\n- **`crates/ffcli`** — the `fft` CLI + stdio MCP server (ffcore only, no UI deps);\n  shares the desktop app's data store.\n\n## License\n\n[Coffeeware](LICENSE) — do whatever you want with it; if we meet and you think\nit's worth it, ☕ buy me a coffee. — [mayckol.dev](https://mayckol.dev)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmayckol%2Ffftracking","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmayckol%2Ffftracking","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmayckol%2Ffftracking/lists"}