{"id":51181361,"url":"https://github.com/plyght/anchor","last_synced_at":"2026-06-27T07:02:58.534Z","repository":{"id":354543234,"uuid":"1126944546","full_name":"plyght/anchor","owner":"plyght","description":"anchor is a volunteer coordinator for emergency mesh networks.","archived":false,"fork":false,"pushed_at":"2026-01-04T23:51:39.000Z","size":13004,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-04-29T02:40:58.617Z","etag":null,"topics":["ai","coordinator","hackathon","mesh","mesh-networks","ml"],"latest_commit_sha":null,"homepage":"https://anchor-flame.vercel.app","language":"TypeScript","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/plyght.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-01-02T21:37:08.000Z","updated_at":"2026-01-25T20:47:19.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/plyght/anchor","commit_stats":null,"previous_names":["plyght/anchor"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/plyght/anchor","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/plyght%2Fanchor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/plyght%2Fanchor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/plyght%2Fanchor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/plyght%2Fanchor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/plyght","download_url":"https://codeload.github.com/plyght/anchor/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/plyght%2Fanchor/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34844346,"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-27T02:00:06.362Z","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":["ai","coordinator","hackathon","mesh","mesh-networks","ml"],"created_at":"2026-06-27T07:02:57.040Z","updated_at":"2026-06-27T07:02:58.526Z","avatar_url":"https://github.com/plyght.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Anchor\n\nEmergency volunteer coordination system using Bluetooth mesh networks for infrastructure-independent task dispatch during crisis events.\n\n## Overview\n\nAnchor coordinates emergency response volunteers through a token-gated task system that operates over Bluetooth LE mesh networks when traditional infrastructure fails. The system generates tasks from incident triggers, matches them to available volunteers based on skills and location, and dispatches assignments via BitChat mesh with unique acceptance codes for verification.\n\n## Features\n\n- **Infrastructure-Independent**: Operates over Bluetooth LE mesh when internet/cellular networks are unavailable\n- **Token-Gated Tasks**: 4-character acceptance codes prevent unauthorized task claiming\n- **Intelligent Matching**: Skills-based task assignment with availability and location awareness\n- **AI-Powered Coordination**: Optional AI features for task generation, volunteer matching, and message routing\n- **Real-Time Coordination**: Live dashboard updates via Convex reactive queries\n- **Audit Trail**: Complete system history for compliance and post-incident analysis\n- **Escalation System**: Automatic task reassignment when volunteers don't respond\n- **Bridge Architecture**: HTTP polling bridge connects web app to mesh network\n\n## AI Integration\n\nAnchor includes optional AI-powered features using OpenAI for intelligent coordination:\n\n- **🤖 Dynamic Task Generation**: AI creates contextually relevant tasks based on incident details (vs hardcoded templates)\n- **🎯 Smart Volunteer Matching**: AI assists with difficult-to-match tasks when rule-based matching fails\n- **📨 Emergency Message Routing**: Automatically analyze and route incoming mesh messages to appropriate volunteers\n\n**Quick Start:**\n\n```typescript\n// Enable AI for task generation\nconst tasks = await generateForIncident({ incident_id, use_ai: true });\n\n// Use AI for difficult matches\nconst result = await matchIncidentWithAI({ incident_id, use_ai_fallback: true });\n\n// Process emergency message with AI\nconst analysis = await processEmergencyMessage({ \n  message: \"Medical emergency at Main St\", \n  incident_id,\n  auto_assign: true \n});\n```\n\n**Setup:** Set OpenAI API key in Convex environment:\n\n```bash\nbunx convex env set OPENAI_API_KEY \"sk-...\"\n```\n\n📖 **Full Documentation**: [docs/AI_INTEGRATION.md](docs/AI_INTEGRATION.md)\n\n## Installation\n\n### Prerequisites\n- Bun 1.0+\n- Convex account (sign up at https://convex.dev)\n- BitChat iOS/Android app for volunteers\n- Rust 1.85+ (for bridge component at ~/bitchat-terminal)\n\n### Convex Setup\n\n```bash\n# From the project root, run Convex dev\nbunx convex dev\n\n# This will:\n# 1. Login/create account (if first time)\n# 2. Create/select a project\n# 3. Generate types in convex/_generated/\n# 4. Create .env.local with CONVEX_URL\n```\n\nAfter running `convex dev`, copy the `CONVEX_URL` from `.env.local` to `frontend/.env` as `VITE_CONVEX_URL`:\n```bash\n# Copy CONVEX_URL from .env.local to frontend/.env\necho \"VITE_CONVEX_URL=$(grep CONVEX_URL .env.local | cut -d '=' -f2)\" \u003e\u003e frontend/.env\n```\n\n### Backend Setup\n\n```bash\ncd backend\ncp .env.example .env\n# Edit .env with Convex deploy key if needed\nbun install\nbun run src/index.ts\n```\n\nBackend runs on http://localhost:8000\n\n### Frontend Setup\n\n```bash\ncd frontend\ncp .env.example .env\n# Edit .env with your Convex URL (from convex dev output)\nbun install\nbun dev\n```\n\nFrontend runs on http://localhost:5173\n\n### Bridge Setup (BitChat Integration)\n\n```bash\ncd ~/bitchat-terminal\n\n# Create .env\ncat \u003e .env \u003c\u003cEOF\nCONVEX_URL=$(grep CONVEX_URL ~/anchor/.env.local | cut -d '=' -f2)\nBRIDGE_MODE=true\nPOLL_INTERVAL_SECS=5\nEOF\n\n# Build\ncargo build --release\n\n# Run (requires sudo for Bluetooth)\nsudo -E ./target/release/bitchat --bridge\n```\n\nSee [Bridge Integration Guide](docs/CONVEX_BRIDGE_INTEGRATION.md) for full details.\n\n## Usage\n\n### Creating an Incident\n\nUse the admin dashboard at http://localhost:5173/admin or call Convex mutations directly:\n\n```typescript\nimport { useMutation } from 'convex/react';\nimport { api } from './convex/_generated/api';\n\nconst createIncident = useMutation(api.incidents.create);\nconst incidentId = await createIncident({\n  title: \"River Flood - Section B\",\n  incident_type: \"flood\",\n  severity: \"high\",\n  trigger_data: { water_level: 15.2, threshold: 12.0 }\n});\n```\n\n### Generating Tasks\n\n```typescript\nconst generateTasks = useMutation(api.tasks.generateForIncident);\nconst taskIds = await generateTasks({ incident_id: incidentId });\n```\n\n### Matching Volunteers to Tasks\n\n```typescript\nconst matchIncident = useMutation(api.matching.matchIncident);\nconst result = await matchIncident({ incident_id: incidentId });\n```\n\n### Dispatching to Mesh\n\n1. Tasks are created with `status='pending'`\n2. Admin clicks \"Dispatch\" in UI → updates to `status='dispatched'`\n3. Bridge polls Convex, finds dispatched tasks\n4. Bridge broadcasts to BitChat mesh network\n\n### Volunteer Response Flow\n\nTasks dispatched to mesh show: `TASK#3: Check levee B5 | Code: X7Y2`\n\nVolunteer responses:\n```\nX7Y2 A     # Accept task\nX7Y2 D     # Decline task\nX7Y2 DONE  # Mark complete\n```\n\nBridge validates code and updates Convex automatically.\n\n## Authentication\n\nAnchor uses [Convex Auth](https://labs.convex.dev/auth) for authentication, which stores user credentials directly in Convex (no separate database required).\n\n### Auth Features:\n- Password-based authentication\n- Email/password signup and login\n- Session management handled by Convex\n- No external auth service needed\n\n### JWT Setup (Required)\n\nConvex Auth requires `JWT_PRIVATE_KEY` and `JWKS` environment variables to be set in your Convex deployment.\n\n**Generate the keys:**\n\n```bash\n# Install jose if needed\nbun add -d jose\n\n# Generate keys\nbun run generateKeys.mjs\n```\n\nThis will output two environment variables. Set them in Convex:\n\n**Option 1: Using Convex CLI**\n```bash\nbunx convex env set JWT_PRIVATE_KEY \"your-private-key-value\"\nbunx convex env set JWKS '{\"keys\":[...]}'\n```\n\n**Option 2: Using Convex Dashboard**\n1. Go to [Convex Dashboard](https://dashboard.convex.dev)\n2. Select your project\n3. Navigate to **Settings** → **Environment Variables**\n4. Add `JWT_PRIVATE_KEY` and `JWKS` with the generated values\n\n**Important**: Set these for both development and production environments if deploying to production.\n\n### Adding OAuth Providers:\n\nTo add OAuth (GitHub, Google, etc.), update `convex/auth.ts`:\n\n```typescript\nimport { GitHub, Google } from \"@convex-dev/auth/providers\";\n\nexport const { auth, signIn, signOut, store } = convexAuth({\n  providers: [Password, GitHub, Google],\n});\n```\n\nSee [Convex Auth docs](https://labs.convex.dev/auth) for full configuration options.\n\n## Configuration\n\n### Frontend Environment\n\n```env\nVITE_CONVEX_URL=https://your-project.convex.cloud\nVITE_API_URL=http://localhost:8000\n```\n\n### Backend Environment\n\n```env\nPORT=8000\nCONVEX_URL=https://your-project.convex.cloud\nCONVEX_DEPLOY_KEY=your-convex-deploy-key\n```\n\n### Bridge Environment (bitchat-terminal)\n\n```env\nCONVEX_URL=https://your-project.convex.cloud\nBRIDGE_MODE=true\nPOLL_INTERVAL_SECS=5\n```\n\n## Architecture\n\n### System Layers\n\n```\nWeb App (React + Bun)\n    ↓\nConvex (Reactive Database + Functions)\n    ↓ (HTTP Polling)\nBridge Process (Rust - bitchat-terminal)\n    ↓ (Bluetooth LE)\nBitChat Mesh Network (iOS/Android)\n```\n\n### Database Schema\n\nConvex schema defined in `convex/schema.ts`:\n\n- **volunteers**: User profiles with BitChat usernames, skills, availability schedules\n- **incidents**: Emergency events with severity, type, trigger data\n- **tasks**: Work items with acceptance codes, status, required skills\n- **task_assignments**: Assignment history and responses for audit trail\n- **audit_log**: Complete system audit trail\n- **mesh_messages**: Bluetooth mesh message log for debugging\n\n### Key Components\n\n- `convex/volunteers.ts`: Volunteer CRUD operations\n- `convex/incidents.ts`: Incident management\n- `convex/tasks.ts`: Task management and generation\n- `convex/matching.ts`: Skills-based volunteer matching algorithm\n- `convex/escalation.ts`: Timeout-based task reassignment (scheduled)\n- `convex/audit.ts`: System audit trail generation\n- `convex/crons.ts`: Scheduled escalation checks\n- `convex/task_assignments.ts`: Volunteer response tracking\n- `convex/mesh_messages.ts`: Mesh network message logging\n- `frontend/src/pages/`: Dashboard, incident, and volunteer management UIs\n\n### Bridge Integration\n\nThe bridge process connects web infrastructure to mesh network:\n\n1. Bridge polls Convex every N seconds for tasks with `status='dispatched'`\n2. Bridge formats and broadcasts tasks to BitChat mesh network\n3. Bridge receives volunteer response codes from mesh\n4. Bridge validates codes and updates Convex with task status\n5. Web app reflects changes in real-time via Convex reactive queries\n\n**Bridge Location:** `~/bitchat-terminal` (separate repository)  \n**Integration Docs:** [docs/CONVEX_BRIDGE_INTEGRATION.md](docs/CONVEX_BRIDGE_INTEGRATION.md)\n\n## Development\n\n### Convex Development\n\n```bash\n# Start Convex dev server (generates types automatically)\nconvex dev\n\n# Deploy to production\nconvex deploy\n```\n\n### Backend Development\n\n```bash\ncd backend\nbun run src/index.ts\n```\n\n### Frontend Development\n\n```bash\ncd frontend\nbun dev\n```\n\n### Bridge Development\n\n```bash\ncd ~/bitchat-terminal\ncargo build --release\nsudo -E ./target/release/bitchat --bridge -d\n```\n\n### Testing\n\n```bash\n# Backend\ncd backend\nbun test\n\n# Frontend\ncd frontend\nbun test\n\n# Bridge integration\ncd ~/anchor\nbun test test/bridge-integration.test.ts\n```\n\n## Tech Stack\n\n- Runtime: Bun (JavaScript/TypeScript)\n- Backend: Hono (Web framework) + Convex\n- Auth: Convex Auth (password-based authentication)\n- Database: Convex (reactive database)\n- Frontend: React + Vite + Convex React hooks\n- Styling: TailwindCSS\n- Mesh Network: BitChat (Bluetooth LE)\n- Bridge: Rust (bitchat-terminal at ~/bitchat-terminal)\n\nDependencies: convex, @convex-dev/auth, hono, react-router-dom, zustand.\n\n## Convex Functions\n\n### Queries (Read-only)\n- `api.volunteers.list` - List all volunteers\n- `api.volunteers.get` - Get volunteer by ID\n- `api.volunteers.getByStatus` - Filter by status\n- `api.incidents.list` - List all incidents\n- `api.incidents.get` - Get incident by ID\n- `api.incidents.getByStatus` - Filter by status\n- `api.tasks.list` - List tasks (filterable by status/incident)\n- `api.tasks.get` - Get task by ID\n- `api.matching.matchTasksToVolunteers` - Calculate matches\n- `api.task_assignments.listByTask` - Get responses for task\n- `api.mesh_messages.listByTask` - Get mesh logs for task\n\n### Mutations (Write)\n- `api.volunteers.create` - Create volunteer\n- `api.volunteers.update` - Update volunteer\n- `api.incidents.create` - Create incident\n- `api.tasks.create` - Create task\n- `api.tasks.update` - Update task (including status → 'dispatched')\n- `api.tasks.generateForIncident` - Generate default tasks\n- `api.matching.assignTaskToVolunteer` - Assign task\n- `api.matching.matchIncident` - Match and assign all tasks\n- `api.audit.logAuditEvent` - Log audit event\n- `api.task_assignments.create` - Record volunteer response\n- `api.mesh_messages.create` - Log mesh message\n\n### Scheduled Functions\n- `internal.escalation.checkAndEscalateTasks` - Runs every minute via cron\n\n## Security\n\n- Convex functions use validators for all inputs\n- Internal functions are not exposed to public API\n- Acceptance codes prevent unauthorized task claiming\n- Authentication handled by Convex Auth with secure session management\n- Password hashing and secure storage built into Convex Auth\n- Bridge uses Convex public HTTP API (add authentication if needed)\n\n## Migration from Supabase\n\nThis project has been migrated from Supabase to Convex. Key changes:\n\n1. **Database**: PostgreSQL → Convex reactive database\n2. **Real-time**: Supabase subscriptions → Convex reactive queries\n3. **Backend API**: REST endpoints → Convex queries/mutations\n4. **Scheduled Jobs**: PostgreSQL triggers → Convex cron jobs\n5. **Type Safety**: Manual types → Auto-generated Convex types\n6. **Bridge Integration**: PostgreSQL LISTEN/NOTIFY → HTTP polling\n\n## Deployment\n\n### Backend Deployment (Koyeb)\n\n1. **Create Koyeb Account**: Sign up at [koyeb.com](https://koyeb.com)\n\n2. **Deploy from GitHub**:\n   - Connect your GitHub repository to Koyeb\n   - Select the `backend` directory as the build context\n   - Set build command: `bun install`\n   - Set run command: `bun start`\n   - Set port: `8000` (or use Koyeb's auto-detected port)\n\n3. **Configure Environment Variables** in Koyeb dashboard:\n   ```\n   PORT=8000\n   CONVEX_URL=https://your-project.convex.cloud\n   CONVEX_DEPLOY_KEY=prod:your-project|your-deploy-key\n   ```\n\n4. **Get Convex Deploy Key**:\n   - Go to Convex dashboard → Settings → Deploy Keys\n   - Create a new production deploy key\n   - Copy and add to Koyeb environment variables\n\n### Frontend Deployment (Vercel)\n\n1. **Create Vercel Account**: Sign up at [vercel.com](https://vercel.com)\n\n2. **Deploy from GitHub**:\n   - Import your GitHub repository\n   - Vercel will auto-detect Vite configuration\n   - Root directory: `frontend`\n   - Build command: `bun run build` (auto-detected)\n   - Output directory: `dist` (auto-detected)\n\n3. **Configure Environment Variables** in Vercel dashboard:\n   ```\n   VITE_CONVEX_URL=https://your-project.convex.cloud\n   VITE_API_URL=https://your-backend.koyeb.app\n   ```\n\n4. **Deploy**: Vercel will automatically deploy on every push to main branch\n\n### Convex Production Deployment\n\nBefore deploying frontend/backend, deploy your Convex functions:\n\n```bash\n# From project root\nbunx convex deploy --prod\n\n# This will:\n# 1. Deploy all functions to production\n# 2. Output your production CONVEX_URL\n# 3. Generate production deploy keys\n```\n\nUse the production `CONVEX_URL` in both frontend and backend environment variables.\n\n### Bridge Deployment\n\nSee [Bridge Integration Guide](docs/CONVEX_BRIDGE_INTEGRATION.md#production-deployment) for systemd service setup.\n\n### Post-Deployment Checklist\n\n- [ ] Convex functions deployed to production\n- [ ] Backend deployed to Koyeb with correct environment variables\n- [ ] Frontend deployed to Vercel with correct environment variables\n- [ ] Bridge running on dedicated device (Raspberry Pi, Linux server)\n- [ ] Health check endpoint responds: `https://your-backend.koyeb.app/health`\n- [ ] Frontend loads and connects to Convex\n- [ ] Auth flow works end-to-end\n- [ ] Test incident creation and task generation\n- [ ] Test task dispatch to mesh network\n- [ ] Test volunteer response from mesh\n\n### Monitoring\n\n- **Backend Health**: `GET https://your-backend.koyeb.app/health`\n- **Convex Dashboard**: Monitor function calls, logs, and database queries\n- **Vercel Dashboard**: Monitor deployments and analytics\n- **Koyeb Dashboard**: Monitor backend logs and performance\n- **Bridge Logs**: `sudo journalctl -u bitchat-bridge -f`\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplyght%2Fanchor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fplyght%2Fanchor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplyght%2Fanchor/lists"}