{"id":50909595,"url":"https://github.com/developer180527/web-save","last_synced_at":"2026-06-16T09:01:13.052Z","repository":{"id":364327198,"uuid":"1266495193","full_name":"developer180527/web-save","owner":"developer180527","description":null,"archived":false,"fork":false,"pushed_at":"2026-06-12T15:42:22.000Z","size":449,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-12T16:27:29.988Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/developer180527.png","metadata":{"files":{"readme":"README.md","changelog":null,"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":null,"dco":null,"cla":null}},"created_at":"2026-06-11T17:08:55.000Z","updated_at":"2026-06-12T15:42:26.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/developer180527/web-save","commit_stats":null,"previous_names":["developer180527/web-save"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/developer180527/web-save","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/developer180527%2Fweb-save","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/developer180527%2Fweb-save/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/developer180527%2Fweb-save/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/developer180527%2Fweb-save/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/developer180527","download_url":"https://codeload.github.com/developer180527/web-save/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/developer180527%2Fweb-save/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34398408,"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-16T02:00:06.860Z","response_time":126,"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":[],"created_at":"2026-06-16T09:01:12.132Z","updated_at":"2026-06-16T09:01:13.013Z","avatar_url":"https://github.com/developer180527.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# WebSave\n\nLocal-first web bookmark and reference manager. A lightweight, fast alternative\nto browser bookmarks and services like Raindrop.io: capture pages, enrich them\nwith tags and notes, search everything instantly, and let a background monitor\ntell you when links rot.\n\n## Architecture\n\n```\nweb-save/\n├── core/           websave-core — portable Rust library (no UI dependencies)\n│                   vault storage (SQLite + FTS5), CRUD, tagging, search,\n│                   link monitoring. Reusable from any host: this app, a CLI,\n│                   mobile, or as a plugin in another Tauri app (e.g. Noter).\n├── ffi/            websave-ffi — UniFFI bindings over the core for native\n│                   hosts (Swift today; Kotlin/iOS-ready).\n├── macos-menubar/  Native SwiftUI menubar app (MenuBarExtra popover with\n│                   search, starred \u0026 recent) linking websave-core directly.\n│                   Build \u0026 launch: npm run menubar\n├── src-tauri/      Tauri shell — thin #[tauri::command] wrappers around the\n│                   vault, a background link-monitor thread, and a localhost\n│                   capture server (127.0.0.1:38917) for the extension.\n├── extension/      Chrome extension (MV3) — right-click capture. Pure capture\n│                   client: gathers url/title/description/favicon and POSTs to\n│                   the capture server; queues offline saves in the browser.\n└── src/            React + TypeScript frontend (list, search, filters,\n                    tag/notes editor, settings).\n```\n\nQuick access per platform: on macOS the SwiftUI menubar app owns the tray —\nthe engine creates no tray icon there. On Windows/Linux the engine shows a\ntray icon with a webview popover (left click) and a native menu (right\nclick). The menubar app reads/writes the same WAL-mode SQLite vault as the\nengine and nudges it over localhost (`/reload` after writes, `/show` to\nraise the main window) so both UIs stay in sync.\n\n### The vault\n\nAll data lives in a portable directory (`~/Library/Application\nSupport/com.venugopal.web-save/vault` on macOS):\n\n- `websave.db` — SQLite database (WAL mode) with an FTS5 full-text index over\n  titles, URLs, descriptions, notes and tags. Schema changes are applied via\n  `PRAGMA user_version` migrations.\n- `assets/` — reserved for local assets such as thumbnails.\n\nBack it up, sync it, or move it between machines — it is self-contained.\n\n### Link monitoring\n\nEach save carries a status: `unchecked`, `active`, `changed` (content hash\ndiffers from the last check), `redirected` (now resolves somewhere\nmeaningfully different; http→https and `www.` changes don't count), or `dead`\n(DNS/transport failure, 404/410, server errors). A background thread re-checks\nstale links in small batches every 30 minutes; the UI can also check a single\nlink or re-check everything on demand.\n\n### Capture flow\n\nThe extension never touches the database. It POSTs a `NewSave` JSON payload\nto `http://127.0.0.1:38917/save`; the app validates, stores, and notifies the\nUI. The endpoint binds to loopback only, sends no CORS headers, and requires\nan `x-websave-client` header (which forces a failing preflight for normal web\npages), so random websites can't write into your vault. If the app isn't\nrunning, the extension queues saves in `chrome.storage.local` and retries\nevery minute.\n\n## Development\n\n```sh\nnpm install\nnpm run tauri dev      # run the desktop app\nnpm run menubar        # (macOS) build + launch the native menubar app\ncargo test --workspace # core test suite\n```\n\n`npm run tauri build` bundles only the engine (desktop app); the menubar\ncompanion is a separate macOS-only artifact produced by `npm run menubar`\n(`macos-menubar/dist/WebSave Menubar.app`) and is never included in\nmac/Windows/Linux release bundles. The engine can launch it on demand\n(Settings → Menubar app), looking it up via LaunchServices, /Applications,\nnext to the engine binary, or the in-repo dev build.\n\n### Installing the extension\n\n1. Open `chrome://extensions` and enable **Developer mode**.\n2. Click **Load unpacked** and pick this repo's `extension/` folder.\n3. With the desktop app running, right-click any page → *Save page to\n   WebSave* (or click the toolbar button). Links and selections have their\n   own context-menu entries.\n\n## Roadmap\n\n- [x] Phase 1 — portable core (`websave-core`), Tauri commands, desktop UI\n- [x] Phase 2 — Chrome extension (right-click capture → desktop app)\n- [x] Phase 3 — tray quick access: native SwiftUI menubar app on macOS\n      (UniFFI → websave-core); webview popover + native menu on Windows/Linux\n- [x] Thumbnails (og:image + extension screenshots), bookmark import,\n      archive snapshots (searchable readable-text copies of saved pages)\n- [ ] Later — export, keyboard layer, read/unread, Noter plugin packaging\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeveloper180527%2Fweb-save","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdeveloper180527%2Fweb-save","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeveloper180527%2Fweb-save/lists"}