{"id":50391185,"url":"https://github.com/raulduk3/vigil","last_synced_at":"2026-05-30T18:01:49.434Z","repository":{"id":344493304,"uuid":"1122916270","full_name":"raulduk3/vigil","owner":"raulduk3","description":"An autonomous and inbox-agnostic email agent. Forward your email, Vigil handles the rest. BSL 1.1.","archived":false,"fork":false,"pushed_at":"2026-04-17T21:57:45.000Z","size":3761,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-17T23:37:12.692Z","etag":null,"topics":["agent","ai","bsl-license","bun","email","email-agent","email-monitoring","nextjs","self-hosted","typescript"],"latest_commit_sha":null,"homepage":"https://vigil.run","language":"TypeScript","has_issues":false,"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/raulduk3.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","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":"2025-12-25T20:11:25.000Z","updated_at":"2026-04-17T21:57:49.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/raulduk3/vigil","commit_stats":null,"previous_names":["raulduk3/vigil"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/raulduk3/vigil","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raulduk3%2Fvigil","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raulduk3%2Fvigil/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raulduk3%2Fvigil/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raulduk3%2Fvigil/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/raulduk3","download_url":"https://codeload.github.com/raulduk3/vigil/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raulduk3%2Fvigil/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33703065,"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-05-30T02:00:06.278Z","response_time":92,"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":["agent","ai","bsl-license","bun","email","email-agent","email-monitoring","nextjs","self-hosted","typescript"],"created_at":"2026-05-30T18:01:48.300Z","updated_at":"2026-05-30T18:01:49.410Z","avatar_url":"https://github.com/raulduk3.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Vigil\n\nOpen source, self-hosted AI email triage agent. Bring your own API key from OpenAI, Anthropic, or Google. Pick any model per watcher. You pay your provider directly, no markup.\n\nForward emails to Vigil. The agent reads each one, tracks conversation threads, builds persistent memory, and decides what to do. Most of the time it thinks and remembers quietly. When something genuinely requires your attention, it alerts you. No inbox access. No email bodies stored.\n\n## Quick Start\n\nGet running in under 5 minutes:\n\n```bash\n# Clone\ngit clone https://github.com/rickyalvarez/vigil.git\ncd vigil\n\n# Backend\ncd backend\nbun install\ncp .env.example .env\n# Fill in: JWT_SECRET, JWT_REFRESH_SECRET, ENCRYPTION_KEY, RESEND_API_KEY\n# Generate secrets: openssl rand -base64 32\nbun run dev\n\n# Frontend (new terminal)\ncd frontend\nnpm install\ncp .env.local.example .env.local\nnpm run dev\n\n# Open http://localhost:3000, create an account, add your API key, create a watcher\n```\n\nFor email ingestion, deploy the Cloudflare Worker (see [Self-hosting](#self-hosting)).\n\n## How It Works\n\n```\nYour email → forwarding rule → Cloudflare Worker → Backend Agent → Memory + Tools → You\n```\n\n1. Set a forwarding rule in Gmail/Outlook to your Vigil address\n2. Cloudflare Worker receives the email and forwards raw MIME to the backend\n3. The agent runs an 8-step invocation loop: load context → retrieve memories → get threads → parse email → build prompt → LLM call → execute tools → log\n4. The agent decides: remember something, update a thread, send an alert, fire a webhook, or do nothing\n5. Email body is discarded after processing. Only a SHA-256 hash is stored\n\n## Models\n\nVigil supports 9 models across three providers. Pick any model per watcher.\n\n| Model | Provider | Tier | ~Cost/Email | Max Tokens |\n|-------|----------|------|-------------|------------|\n| GPT-4.1 Nano | OpenAI | nano | $0.0001 | 1,024 |\n| GPT-4.1 Mini | OpenAI | mini | $0.0025 | 1,024 |\n| GPT-4o Mini | OpenAI | mini | $0.0006 | 1,024 |\n| GPT-4.1 | OpenAI | standard | $0.008 | 2,048 |\n| GPT-4o | OpenAI | standard | $0.010 | 2,048 |\n| Claude Haiku 4 | Anthropic | mini | $0.004 | 1,024 |\n| Claude Sonnet 4 | Anthropic | standard | $0.015 | 2,048 |\n| Gemini 2.5 Flash | Google | mini | $0.0006 | 1,024 |\n| Gemini 2.5 Pro | Google | standard | $0.010 | 2,048 |\n\nCosts are approximate per-email at direct API rates. Each watcher uses a single model for email triage. Mini/nano models use a classification pipeline with deterministic action mapping; standard models use the full agent prompt.\n\nSee [docs/MODELS.md](docs/MODELS.md) for the full breakdown.\n\n## BYOK (Bring Your Own Key)\n\nVigil is BYOK-first. You bring your own OpenAI, Anthropic, or Google API key. Every watcher can use a different model from any provider.\n\n- **Add keys** in the dashboard at `/account/keys` or via API (`POST /api/account/keys`)\n- **Pick a model** per watcher in the watcher settings\n- **Keys encrypted** at rest with AES-256-GCM. Never logged, never leave the server.\n- **Full cost transparency**: every token, model call, and dollar is logged and visible in the dashboard\n- **You pay your provider directly**. No middleman, no markup.\n\nSee [docs/BYOK.md](docs/BYOK.md) for details.\n\n## Architecture\n\n| Layer | Stack |\n|-------|-------|\n| **Email ingestion** | Cloudflare Email Routing → Worker → `/ingest/:token` |\n| **Backend** | Bun + Hono + SQLite |\n| **Agent engine** | Multi-model (OpenAI, Anthropic, Google), JSON mode, 8-step loop |\n| **Memory** | SQLite FTS5, BM25 ranking, time-decay scoring |\n| **Thread detection** | In-Reply-To header + subject normalization |\n| **Classification pipeline** | Mini/nano models classify, deterministic action mapping |\n| **Alerts** | Resend API |\n| **Frontend** | Next.js 16, three-panel dashboard |\n| **Extension** | Chrome sidepanel for setup and watcher management |\n\n### Agent Output Schema\n\nEvery agent invocation produces:\n\n```json\n{\n  \"email_analysis\": { \"summary\": \"...\", \"intent\": \"...\", \"urgency\": 1-5, \"entities\": [] },\n  \"memory_append\": \"...\",\n  \"thread_updates\": [{ \"thread_id\": \"...\", \"status\": \"...\", \"summary\": \"...\" }],\n  \"actions\": [{ \"tool\": \"send_alert\", \"params\": {} }]\n}\n```\n\n### Pipeline\n\nMini/nano tier models use a classification pipeline: the model classifies the email, then deterministic logic maps classifications to actions (alerts, thread updates, memory). Standard/pro tier models use the full agent prompt and decide actions directly.\n\nTicks (scheduled checks) always use the cheapest nano model. Email triage and chat use the watcher's configured model.\n\n## Self-hosting\n\n### Prerequisites\n\n- [Bun](https://bun.sh) ≥ 1.0\n- Node.js ≥ 18 (for frontend)\n- A domain with [Cloudflare Email Routing](https://developers.cloudflare.com/email-routing/)\n- At least one API key: OpenAI, Anthropic, or Google\n- [Resend](https://resend.com) API key (for outbound alert emails)\n\n### Backend\n\n```bash\ncd backend\nbun install\ncp .env.example .env\n# Required: JWT_SECRET, JWT_REFRESH_SECRET, ENCRYPTION_KEY, RESEND_API_KEY, RESEND_FROM_EMAIL\nbun run dev\n```\n\n### Frontend\n\n```bash\ncd frontend\nnpm install\ncp .env.local.example .env.local\n# Set NEXT_PUBLIC_API_URL=http://localhost:3001\nnpm run dev\n```\n\n### Cloudflare Worker\n\n```bash\ncd cloudflare-worker\n# Edit wrangler.toml: set BACKEND_URL to your backend endpoint\nnpx wrangler deploy\n```\n\nConfigure Cloudflare Email Routing to send to your worker. The worker forwards raw MIME to `BACKEND_URL/ingest/:token`. Each watcher has a unique ingest token generated on creation.\n\n### Docker\n\n```bash\ndocker compose up\n```\n\nSee [docker-compose.yml](docker-compose.yml) for the full configuration.\n\n### Environment Variables\n\nSee `backend/.env.example` for the full list. Key variables:\n\n| Variable | Required | Description |\n|----------|----------|-------------|\n| `JWT_SECRET` | Yes | Auth token signing |\n| `JWT_REFRESH_SECRET` | Yes | Refresh token signing |\n| `ENCRYPTION_KEY` | Yes | AES-256-GCM key for BYOK secrets |\n| `RESEND_API_KEY` | Yes | Outbound alert emails |\n| `RESEND_FROM_EMAIL` | Yes | From address for alerts |\n| `VIGIL_MODEL` | No | Default model (default: `gpt-4.1-mini`) |\n| `PORT` | No | Backend port (default: `4000`) |\n\n## Project Structure\n\n```\nvigil/\n├── backend/\n│   ├── src/agent/          # Engine, tools, memory, prompts\n│   │   ├── engine.ts       # 8-step invocation loop\n│   │   ├── tools.ts        # send_alert, update_thread, ignore_thread, webhook\n│   │   ├── memory.ts       # FTS5 search, BM25 ranking, time decay\n│   │   └── prompts.ts      # System + trigger prompt construction\n│   ├── src/api/            # Hono REST handlers\n│   ├── src/auth/           # JWT + OAuth (Google, GitHub)\n│   ├── src/db/             # SQLite client + schema\n│   └── src/ingestion/      # Email pipeline, body prep, MIME parsing\n├── frontend/               # Next.js 16 dashboard (App Router)\n├── chrome-extension/       # Sidepanel: setup, chat, watcher overview\n├── cloudflare-worker/      # MX-level email ingestion\n├── backend/promptfoo/      # LLM eval suite (promptfoo)\n└── docs/                   # Architecture and reference docs\n```\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, code style, and PR process.\n\n## License\n\n**Business Source License 1.1** — source available, self-hosting permitted, no competing hosted service.\n\nConverts to Apache 2.0 four years from each release date.\n\n## Author\n\n[Richard Álvarez](https://richardalvarez.info)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fraulduk3%2Fvigil","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fraulduk3%2Fvigil","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fraulduk3%2Fvigil/lists"}