{"id":45628201,"url":"https://github.com/automagik-dev/omni","last_synced_at":"2026-05-08T02:37:28.494Z","repository":{"id":336859606,"uuid":"1145547995","full_name":"automagik-dev/omni","owner":"automagik-dev","description":"Universal event-driven omnichannel platform for AI agents to communicate across any messaging platform","archived":false,"fork":false,"pushed_at":"2026-04-01T06:20:48.000Z","size":53924,"stargazers_count":14,"open_issues_count":7,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-03T05:36:39.882Z","etag":null,"topics":["ai-agents","bun","discord","event-driven","messaging","nats","omnichannel","typescript","whatsapp"],"latest_commit_sha":null,"homepage":"https://github.com/automagik-dev/omni","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/automagik-dev.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":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-01-29T23:09:28.000Z","updated_at":"2026-03-31T18:45:36.000Z","dependencies_parsed_at":null,"dependency_job_id":"9b5a1664-cf6c-4220-9166-e400a40dfdd4","html_url":"https://github.com/automagik-dev/omni","commit_stats":null,"previous_names":["automagik-dev/omni"],"tags_count":124,"template":false,"template_full_name":null,"purl":"pkg:github/automagik-dev/omni","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/automagik-dev%2Fomni","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/automagik-dev%2Fomni/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/automagik-dev%2Fomni/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/automagik-dev%2Fomni/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/automagik-dev","download_url":"https://codeload.github.com/automagik-dev/omni/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/automagik-dev%2Fomni/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31416332,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T20:09:54.854Z","status":"ssl_error","status_checked_at":"2026-04-04T20:09:44.350Z","response_time":60,"last_error":"SSL_read: 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","bun","discord","event-driven","messaging","nats","omnichannel","typescript","whatsapp"],"created_at":"2026-02-23T22:25:50.511Z","updated_at":"2026-04-04T22:01:40.798Z","avatar_url":"https://github.com/automagik-dev.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cpicture\u003e\n    \u003cimg src=\".github/assets/omni-header-2.png\" alt=\"Omni — One API, Every Channel\" width=\"800\" /\u003e\n  \u003c/picture\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/license-MIT-blue?style=flat-square\" alt=\"MIT License\" /\u003e\u003c/a\u003e\n  \u003cimg src=\"https://img.shields.io/badge/runtime-Bun-f9f1e1?style=flat-square\u0026logo=bun\" alt=\"Bun\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/version-2.0.0-8b5cf6?style=flat-square\" alt=\"v2.0.0\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/channels-3-25D366?style=flat-square\" alt=\"Channels\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/event%20bus-NATS%20JetStream-27AAE1?style=flat-square\" alt=\"NATS\" /\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\u003cstrong\u003eUniversal event-driven omnichannel messaging platform\u003c/strong\u003e\u003c/p\u003e\n\u003cp align=\"center\"\u003eOne API to send and receive messages across WhatsApp, Discord, Telegram, and more.\u003cbr/\u003eCLI-first. Event-driven. Built for AI agents.\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"#install\"\u003eInstall\u003c/a\u003e •\n  \u003ca href=\"#quick-start\"\u003eQuick Start\u003c/a\u003e •\n  \u003ca href=\"#ai-agents\"\u003eAI Agents\u003c/a\u003e •\n  \u003ca href=\"#cli-reference\"\u003eCLI\u003c/a\u003e •\n  \u003ca href=\"#rest-api\"\u003eAPI\u003c/a\u003e •\n  \u003ca href=\"#sdks\"\u003eSDKs\u003c/a\u003e •\n  \u003ca href=\"#development\"\u003eDevelopment\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\nThink of Omni as a deep-sea octopus. Each **channel** is a tentacle — WhatsApp, Discord, Telegram — reaching into a different messaging ecosystem. **Events** are nerve impulses flowing through NATS JetStream. The **core** is the brain — identity resolution, event routing, and a unified API that lets you treat all channels as one.\n\n## Why Omni?\n\n| | |\n|---|---|\n| 🔌 **One API, every channel** | Send a WhatsApp message, a Discord embed, and a Telegram photo with the same endpoint |\n| ⚡ **Event-driven** | Every action produces an event. Subscribe, replay, automate |\n| 🧬 **Identity graph** | Same person on WhatsApp and Discord? Omni knows |\n| 🤖 **AI-native** | Agent providers, automations, built to be controlled by LLMs |\n| 🔧 **Plugin architecture** | Build new channels with the Channel SDK |\n| 📦 **Multi-SDK** | Auto-generated TypeScript, Python, and Go SDKs |\n\n## Channels\n\n| Channel | Status | Highlights |\n|---------|--------|------------|\n| **WhatsApp** (Baileys) | ✅ Stable | QR/phone pairing, media, reactions, groups, contacts, presence |\n| **Discord** | ✅ Stable | Bots, embeds, polls, buttons, threads, slash commands |\n| **Telegram** | ✅ New | Bot API, inline keyboards, groups, channels, threads, polls |\n| WhatsApp Cloud API | 🔮 Planned | — |\n| Slack | 🔮 Planned | — |\n\n## Install\n\n### Quickest (npm)\n\n```bash\nbun add -g @automagik/omni\nomni install              # interactive wizard: sets up server + PM2\n```\n\n\u003e **Migrating from `@omni/cli`?** Run `bun remove -g @omni/cli` first.\n\n### Via install script (npm-first, git fallback)\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/automagik-dev/omni/main/install-client.sh | bash\n```\n\n### Full server from source\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/automagik-dev/omni/main/install.sh | bash\n```\n\nThree modes: **CLI only** · **Full server** · **CLI + connect to remote**\n\n\u003cdetails\u003e\n\u003csummary\u003eNon-interactive \u0026 manual install\u003c/summary\u003e\n\n```bash\n# CLI only (tries npm first, falls back to git clone)\ncurl -fsSL https://raw.githubusercontent.com/automagik-dev/omni/main/install.sh | bash -s -- --cli\n\n# CLI + connect to remote\ncurl -fsSL https://raw.githubusercontent.com/automagik-dev/omni/main/install.sh | bash -s -- --cli https://your-omni-server.com\n\n# Full server\ncurl -fsSL https://raw.githubusercontent.com/automagik-dev/omni/main/install.sh | bash -s -- --server\n```\n\n**Manual:**\n\n```bash\ngit clone https://github.com/automagik-dev/omni.git \u0026\u0026 cd omni\nmake setup    # Install deps, create .env, start services\n```\n\nAPI runs at `http://localhost:8882` · Swagger docs at `/api/v2/docs` · API key printed in startup banner.\n\n\u003c/details\u003e\n\n## Quick Start\n\n```bash\n# Authenticate\nomni auth login --api-key \u003cyour-key\u003e\n\n# WhatsApp — scan QR\nomni instances create --name \"my-whatsapp\" --channel whatsapp-baileys\nomni instances qr \u003cid\u003e --watch\n\n# Discord — connect bot\nomni instances create --name \"my-discord\" --channel discord\nomni instances connect \u003cid\u003e --token \"BOT_TOKEN\"\n\n# Telegram — connect bot\nomni instances create --name \"my-telegram\" --channel telegram\nomni instances connect \u003cid\u003e --token \"BOT_TOKEN\"\n\n# Send messages\nomni send --to \"+5511999999999\" --text \"Hello from the deep 🐙\"\n\n# Browse conversations\nomni chats list --unread --sort unread\n```\n\n## AI Agents\n\nConnect any LLM provider and your instances become intelligent agents — responding to messages, reacting to events, across every channel.\n\n```\nMessage received → NATS event → Agent Dispatcher → Provider (OpenAI/Agno/Webhook) → Humanized reply\n```\n\n```bash\n# Connect a provider\nomni providers create --name \"my-llm\" --schema openai --base-url \"https://api.openai.com/v1\" --api-key \"sk-...\"\n\n# Bind to instance — it's now an agent\nomni instances update \u003cid\u003e --agent-provider \u003cprovider-id\u003e\n```\n\n| Trigger | When | Use Case |\n|---------|------|----------|\n| **DM** | Direct message | Always reply |\n| **Mention** | @bot in group | Respond to mentions |\n| **Reply** | Reply to bot's message | Continue thread |\n| **Reaction** | Emoji on message | 👍 approve, 🔥 prioritize |\n\n**Built-in:** message debouncing · per-user rate limits · access control · smart response chunking · typing presence · cross-channel identity · self-chat detection\n\n\u003cdetails\u003e\n\u003csummary\u003eAutomations \u0026 event-driven workflows\u003c/summary\u003e\n\n```bash\n# Auto-reply\nomni automations create --name \"welcome\" \\\n  --trigger \"message.received\" \\\n  --action send_message --action-config '{\"text\":\"Got it! 🐙\"}'\n\n# Webhook on connection\nomni automations create --name \"notify\" \\\n  --trigger \"instance.connected\" \\\n  --action webhook --action-config '{\"url\":\"https://your-app.com/hook\"}'\n\n# Route VIPs to a special agent\nomni automations create --name \"vip\" \\\n  --trigger \"message.received\" \\\n  --condition '{\"field\":\"payload.from\",\"op\":\"in\",\"value\":[\"+551199...\"]}' \\\n  --action call_agent --agent-id \"vip-handler\" --provider-id \u003cid\u003e\n```\n\n\u003c/details\u003e\n\n## Architecture\n\n```\n┌─────────────┐  ┌─────────────┐  ┌─────────────┐\n│  WhatsApp   │  │   Discord   │  │  Telegram   │     Tentacles\n└──────┬──────┘  └──────┬──────┘  └──────┬──────┘\n       └────────────────┼────────────────┘\n              ┌─────────▼─────────┐\n              │   NATS JetStream  │                    Nerve System\n              └─────────┬─────────┘\n              ┌─────────▼─────────┐\n              │     Omni Core     │                    Brain\n              └─────────┬─────────┘\n         ┌──────────────┼──────────────┐\n   ┌─────▼─────┐ ┌─────▼─────┐ ┌─────▼─────┐\n   │  REST API  │ │    CLI    │ │ Dashboard  │        Interfaces\n   └───────────┘ └───────────┘ └───────────┘\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eProject structure\u003c/summary\u003e\n\n```\npackages/\n├── core/               # Events, identity, schemas\n├── db/                 # Drizzle ORM + PostgreSQL\n├── api/                # Hono + tRPC + OpenAPI\n├── channel-sdk/        # Plugin SDK\n├── channel-whatsapp/   # Baileys\n├── channel-discord/    # discord.js\n├── channel-telegram/   # grammy\n├── cli/                # `omni` command\n├── media-processing/   # Media sync\n├── sdk/                # TypeScript SDK\n├── sdk-go/             # Go SDK\n└── sdk-python/         # Python SDK\napps/\n└── ui/                 # React + Vite + Tailwind\n```\n\n\u003c/details\u003e\n\n## CLI Reference\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eCore commands\u003c/strong\u003e — send, chats, messages, instances, channels, persons\u003c/summary\u003e\n\n#### `send` — Send messages\n\n```bash\nomni send --to \"+5511999999999\" --text \"Hello!\"\nomni send --to \"+5511999999999\" --media ./photo.jpg --caption \"Check this out\"\nomni send --to \"+5511999999999\" --reaction \"👍\" --message \u003cmessageId\u003e\nomni send --to \"+5511999999999\" --sticker ./sticker.webp\nomni send --to \"+5511999999999\" --contact --name \"John\" --phone \"+1234567890\"\nomni send --to \"+5511999999999\" --location --lat -23.55 --lng -46.63 --address \"São Paulo\"\nomni send --to \"discord-channel-id\" --poll \"Favorite color?\" --options \"Red,Blue,Green\"\nomni send --to \"discord-channel-id\" --embed --title \"Alert\" --description \"Server rebooting\" --color \"#ff0000\"\nomni send --to \"+5511999999999\" --presence typing\n```\n\n#### `chats` — Manage conversations\n\n```bash\nomni chats list --unread --sort unread\nomni chats messages \u003cchatId\u003e --limit 20 --rich\nomni chats archive \u003cchatId\u003e\nomni chats participants \u003cchatId\u003e --add \"+5511999999999\"\n```\n\nSubcommands: `list` · `get` · `create` · `update` · `delete` · `archive` · `unarchive` · `messages` · `participants` · `read`\n\n#### `messages` — Search and manage\n\n```bash\nomni messages search \"meeting tomorrow\" --instance \u003cid\u003e --limit 10\nomni messages read --chat \u003cchatId\u003e --instance \u003cid\u003e\n```\n\n#### `instances` — Channel connections\n\n```bash\nomni instances list\nomni instances create --name \"work-whatsapp\" --channel whatsapp-baileys\nomni instances qr \u003cid\u003e --watch\nomni instances connect \u003cid\u003e --token \"BOT_TOKEN\"    # Discord / Telegram\nomni instances sync \u003cid\u003e --type all --depth 30\nomni instances contacts \u003cid\u003e --limit 50\nomni instances groups \u003cid\u003e\n```\n\nSubcommands: `list` · `get` · `create` · `delete` · `status` · `qr` · `pair` · `connect` · `disconnect` · `restart` · `logout` · `sync` · `syncs` · `update` · `contacts` · `groups` · `profile`\n\n#### `persons` — Contact directory\n\n```bash\nomni persons search \"John\"\nomni persons get \u003cid\u003e\nomni persons presence \u003cid\u003e\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eManagement\u003c/strong\u003e — keys, providers, automations, access, webhooks\u003c/summary\u003e\n\n#### `keys` — API key management\n\n```bash\nomni keys create --name \"agent-key\" --scopes \"messages:*,instances:read\"\nomni keys list --status active\nomni keys revoke \u003cid\u003e --reason \"Compromised\"\n```\n\n#### `providers` — AI/LLM providers\n\n```bash\nomni providers create --name \"openai\" --schema openai --api-key \"sk-...\"\nomni providers list\nomni providers test \u003cid\u003e\n```\n\nSchemas: `agnoos` · `a2a` · `openai` · `anthropic` · `webhook` · `custom`\n\n#### `automations` — Event-driven workflows\n\n```bash\nomni automations create --name \"Auto-reply\" --trigger \"message.received\" \\\n  --action send_message --action-config '{\"text\":\"Got it!\"}'\nomni automations list --enabled\nomni automations test \u003cid\u003e\n```\n\nActions: `webhook` · `send_message` · `emit_event` · `log` · `call_agent`\n\n#### `access` — Access control\n\n```bash\nomni access create --type deny --instance \u003cid\u003e --phone \"+1234567890\" --action block\nomni access list --instance \u003cid\u003e\nomni access check --instance \u003cid\u003e --user \"+1234567890\"\n```\n\nModes: `disabled` · `blocklist` · `allowlist`\n\n#### `webhooks` — External event sources\n\n```bash\nomni webhooks create --name \"github-events\"\nomni webhooks trigger --type \"custom.event\" --payload '{\"key\":\"value\"}'\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eSystem\u003c/strong\u003e — update, status, auth, config, events, batch, logs\u003c/summary\u003e\n\n```bash\nomni update -y                                 # Update CLI; restart only services that were already online\nomni update -y --no-restart                    # Update CLI only; skip restarts and API-port health check\nomni status                                    # Verify runtime health after update\nomni auth login --api-key \u003ckey\u003e                # Authenticate\nomni config set defaultInstance \u003cid\u003e           # CLI settings\nomni events list --type \"message.*\" --since 2h # Event history\nomni events replay --start --since 2024-01-01  # Replay events\nomni batch create --instance \u003cid\u003e --type targeted_chat_sync --chat \u003cchatId\u003e\nomni resync --instance \u003cid\u003e                    # History backfill\nomni logs list --level error --limit 50        # Server logs\nomni dead-letters list --limit 20              # Failed events\n```\n\n`omni update` can exit non-zero after install only when restart runs (services were already online): in that path it checks API health on the configured API port and fails on restart or health-check errors.\n\n`omni doctor` is not available yet and is tracked as a follow-up.\n\n\u003c/details\u003e\n\n## REST API\n\n| | |\n|---|---|\n| **Base URL** | `http://localhost:8882/api/v2` |\n| **Docs** | [`/api/v2/docs`](http://localhost:8882/api/v2/docs) (Swagger UI) |\n| **OpenAPI** | `/api/v2/openapi.json` |\n| **Auth** | `x-api-key` header |\n\n**20 endpoints:** `/auth` · `/instances` · `/messages` · `/chats` · `/events` · `/persons` · `/access` · `/settings` · `/providers` · `/automations` · `/webhooks` · `/keys` · `/logs` · `/batch-jobs` · `/dead-letters` · `/media` · `/metrics` · `/event-ops` · `/payloads`\n\n## SDKs\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n\n**TypeScript**\n```typescript\nimport { createOmniClient } from '@omni/sdk';\nconst omni = createOmniClient({\n  baseUrl: 'http://localhost:8882',\n  apiKey: 'your-api-key',\n});\nawait omni.messages.send({\n  instanceId: '...',\n  to: '+5511999999999',\n  text: 'Hello from SDK!',\n});\n```\n\n\u003c/td\u003e\n\u003ctd\u003e\n\n**Python**\n```python\nfrom omni import OmniClient\nclient = OmniClient(\n  base_url=\"http://localhost:8882\",\n  api_key=\"your-api-key\"\n)\ninstances = client.instances.list()\n```\n\n**Go**\n```go\nclient := omni.NewClient(\n  \"http://localhost:8882\",\n  \"your-api-key\",\n)\ninstances, _ := client.Instances.List(ctx)\n```\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\nRegenerate after API changes: `make sdk-generate`\n\n## Web Dashboard\n\n```bash\nmake dev-ui    # Dev → http://localhost:5173\nmake build-ui  # Prod → served by API on :8882\n```\n\n**Pages:** Dashboard · Instances · Chats · Chat View · Contacts · Persons · Providers · Automations · Access Rules · Batch Jobs · Dead Letters · Events · Logs · Settings\n\n\u003cdetails\u003e\n\u003csummary\u003e🔐 API Keys \u0026 Security\u003c/summary\u003e\n\nAPI key is generated on first boot (shown once in startup banner).\n\n```bash\n# Scoped keys\nomni keys create --name \"admin\" --scopes \"*\"\nomni keys create --name \"reader\" --scopes \"messages:read,chats:read\"\nomni keys create --name \"wa-only\" --scopes \"messages:*\" --instances \"uuid1,uuid2\"\n```\n\n**Scopes:** `namespace:action` pattern — `messages:*`, `instances:read`, `*` for full access\n\n**Namespaces:** `messages` · `chats` · `instances` · `persons` · `events` · `access` · `settings` · `providers` · `automations` · `webhooks` · `keys` · `logs` · `batch`\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e⚙️ Configuration \u0026 environment\u003c/summary\u003e\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `API_PORT` | `8882` | API server port |\n| `DATABASE_URL` | `postgresql://...localhost:8432/omni` | PostgreSQL |\n| `NATS_URL` | `nats://localhost:4222` | NATS connection |\n| `OMNI_API_KEY` | *(auto)* | Override primary key |\n\nSet `*_MANAGED=false` for external services. Full list in `.env.example`.\n\n| Service | PM2 Name | Port |\n|---------|----------|------|\n| PostgreSQL | `omni-pgserve` | 8432 |\n| NATS | `omni-nats` | 4222 |\n| API | `omni-api` | 8882 |\n\n\u003c/details\u003e\n\n## Development\n\n```bash\nmake dev           # Start all services + API\nmake check         # typecheck + lint + test\nmake dev-ui        # UI dev server\nmake db-push       # Push schema changes\nmake db-studio     # Drizzle Studio\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eAll make targets\u003c/summary\u003e\n\n```bash\nmake setup         # Full setup (deps + env + services)\nmake dev-api       # API only\nmake dev-services  # PostgreSQL + NATS via PM2\nmake typecheck     # TypeScript only\nmake lint          # Biome linter\nmake lint-fix      # Auto-fix\nmake test          # All tests\nmake test-api      # API tests\nmake test-file F=  # Specific test\nmake build         # Build all\nmake build-ui      # Build UI\nmake status        # Service status\nmake logs-api      # API logs\nmake restart-api   # Restart API\nmake db-reset      # Reset DB (DESTRUCTIVE)\nmake sdk-generate  # Regenerate SDKs\nmake cli ARGS=\"\"   # Run CLI from source\nmake cli-link      # Install CLI globally\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eBuilding a channel plugin\u003c/summary\u003e\n\n```typescript\nimport { BaseChannelPlugin } from '@omni/channel-sdk';\n\nexport class MyPlugin extends BaseChannelPlugin {\n  readonly id = 'my-channel';\n  readonly name = 'My Channel';\n  readonly version = '1.0.0';\n  readonly capabilities = { /* ... */ };\n\n  async connect(instanceId: string, config: InstanceConfig) { /* ... */ }\n  async disconnect(instanceId: string) { /* ... */ }\n  async sendMessage(instanceId: string, message: OutgoingMessage) { /* ... */ }\n}\n```\n\n\u003c/details\u003e\n\n## Tech Stack\n\n| | |\n|---|---|\n| Runtime | [Bun](https://bun.sh) |\n| HTTP | [Hono](https://hono.dev) |\n| API | [tRPC](https://trpc.io) + OpenAPI |\n| DB | PostgreSQL + [Drizzle](https://orm.drizzle.team) |\n| Events | [NATS JetStream](https://nats.io) |\n| Validation | [Zod](https://zod.dev) |\n| Frontend | React + [Vite](https://vitejs.dev) + Tailwind |\n| Monorepo | [Turborepo](https://turbo.build) |\n| Linter | [Biome](https://biomejs.dev) |\n\n---\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"LICENSE\"\u003eMIT\u003c/a\u003e — do whatever you want, just don't blame the octopus. 🐙\n  \u003cbr/\u003e\u003cbr/\u003e\n  \u003csub\u003eThis README is maintained by \u003ca href=\"docs/research/SQUAD.md\"\u003eScroll 📜\u003c/a\u003e, an autonomous sub-agent of Omni.\u003c/sub\u003e\n\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fautomagik-dev%2Fomni","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fautomagik-dev%2Fomni","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fautomagik-dev%2Fomni/lists"}