{"id":50682291,"url":"https://github.com/Makisuo/maple","last_synced_at":"2026-06-25T18:01:00.841Z","repository":{"id":338670476,"uuid":"1158615018","full_name":"Makisuo/maple","owner":"Makisuo","description":"OpenTelemetry observability platform","archived":false,"fork":false,"pushed_at":"2026-06-23T10:04:52.000Z","size":43249,"stargazers_count":1494,"open_issues_count":10,"forks_count":94,"subscribers_count":4,"default_branch":"main","last_synced_at":"2026-06-23T12:39:54.691Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://maple.dev","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/Makisuo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"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":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-02-15T16:58:28.000Z","updated_at":"2026-06-23T12:31:03.000Z","dependencies_parsed_at":null,"dependency_job_id":"5ba792dc-33b6-4ef9-b8cd-458c238a1501","html_url":"https://github.com/Makisuo/maple","commit_stats":null,"previous_names":["makisuo/maple"],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/Makisuo/maple","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Makisuo%2Fmaple","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Makisuo%2Fmaple/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Makisuo%2Fmaple/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Makisuo%2Fmaple/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Makisuo","download_url":"https://codeload.github.com/Makisuo/maple/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Makisuo%2Fmaple/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34786231,"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-25T02:00:05.521Z","response_time":101,"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-08T20:00:23.317Z","updated_at":"2026-06-25T18:01:00.831Z","avatar_url":"https://github.com/Makisuo.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\".github/assets/maple-hero.png\" alt=\"Maple — open-source observability for traces, logs, and metrics, built on OpenTelemetry\" width=\"100%\" /\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eOpen-source observability for traces, logs \u0026amp; metrics — built on OpenTelemetry + ClickHouse.\u003c/strong\u003e\n\u003c/p\u003e\n\n# Maple Monorepo\n\nMaple is now organized as a monorepo with a SPA frontend and an Effect-based backend API.\n\n## Workspace Layout\n\n- `apps/web`: TanStack Router SPA (Vite)\n- `apps/api`: Effect HTTP API (Tinybird proxy + MCP server code)\n- `apps/ingest`: OTLP ingest gateway (key auth + org enrichment + collector forwarding)\n- `apps/landing`: Astro landing site\n- `apps/alerting`: Alert evaluation worker\n- `apps/chat-flue`: Flue + Workers AI chat backend (agent + triage workflow)\n- `apps/cli`: CLI utilities\n- `apps/mobile`: Expo mobile app\n- `packages/domain`: Shared Effect HTTP contracts and domain types\n- `packages/query-engine`: Shared query and observability logic\n- `packages/ui`: Shared UI primitives and components\n\n## Prerequisites\n\n- Bun `\u003e=1.3`\n\n## Install\n\n```bash\nbun install\n```\n\n## Try Maple Locally\n\nRun Maple as a single local binary with OTLP ingest, embedded ClickHouse, and\nthe dashboard:\n\n```bash\nbrew install Makisuo/tap/maple\nmaple start\n```\n\nSee [docs/local-mode.md](docs/local-mode.md) for Homebrew, manual installer,\nupdate, and uninstall details.\n\n## Develop\n\nRun every available `dev` task in the monorepo:\n\n```bash\nbun run dev\n```\n\nRun individual apps from the repo root with workspace filters:\n\n```bash\nbun --filter=@maple/web dev\nbun --filter=@maple/api dev\nbun --filter=@maple/ingest dev\nbun --filter=@maple/landing dev\n```\n\nThere is also a dedicated root helper for alerting:\n\n```bash\nbun run dev:alerting\n```\n\nTurbo dev runs in TUI mode so interactive servers stay attached.\n\n## Validate\n\n```bash\nbun run typecheck\nbun run build\nbun run test\n```\n\n## Docker (Local)\n\nRun the local multi-service stack (API + web + ingest + otel collector):\n\n```bash\ndocker compose -f docker-compose.yml up --build\n```\n\nServices:\n\n- API: `http://localhost:3472`\n- Web: `http://localhost:3471`\n- Ingest: `http://localhost:3474`\n- OTEL collector: `4317` (gRPC), `4318` (HTTP), `13133` (health/extensions)\n\n## Cloudflare Deploy (Alchemy)\n\nDeployments are per-app Alchemy runs pinned to Cloudflare Workers + D1:\n\n- `apps/api/alchemy.run.ts` — D1 database `MAPLE_DB` + api Worker with all env bindings\n- `apps/landing/alchemy.run.ts` — Astro build + Worker serving static assets\n- `apps/web/alchemy.run.ts` — TanStack Start app via the `Vite()` resource\n\nStage grammar is `prd` / `stg` / `pr-\u003cnumber\u003e`, resolved via `@maple/infra/cloudflare` (`parseMapleStage`, `resolveMapleDomains`, `resolveWorkerName`, `resolveD1Name`).\n\nRun locally:\n\n```bash\nbun run alchemy:deploy:prd\nbun run alchemy:deploy:stg\nPR_NUMBER=123 bun run alchemy:deploy:pr\n```\n\nTear down:\n\n```bash\nbun run alchemy:destroy:prd\nbun run alchemy:destroy:stg\nPR_NUMBER=123 bun run alchemy:destroy:pr\n```\n\nCI workflows:\n\n- STG (default on push to `main`): `.github/workflows/deploy-stg.yml`\n- PRD (manual only via `workflow_dispatch`): `.github/workflows/deploy-prd.yml`\n- PR preview lifecycle: `.github/workflows/deploy-pr-preview.yml` (`pull_request` opened/synchronize/reopened/closed)\n\nSecrets source model (CI):\n\n- GitHub Secrets (only one): `DOPPLER_TOKEN`\n- Doppler configs (`prd`, `stg`, `pr`) must define:\n    - `ALCHEMY_PASSWORD`\n    - `ALCHEMY_STATE_TOKEN`\n    - `CLOUDFLARE_API_TOKEN`\n    - `CLOUDFLARE_DEFAULT_ACCOUNT_ID`\n    - `TINYBIRD_HOST`\n    - `TINYBIRD_TOKEN`\n    - `RESEND_API_KEY`\n    - `RESEND_FROM_EMAIL`\n    - `MAPLE_INGEST_KEY_ENCRYPTION_KEY`\n    - `MAPLE_INGEST_KEY_LOOKUP_HMAC_KEY`\n    - `MAPLE_AUTH_MODE`\n    - `MAPLE_ROOT_PASSWORD` (required in `self_hosted` mode)\n    - `CLERK_SECRET_KEY`\n    - `CLERK_PUBLISHABLE_KEY`\n    - `CLERK_JWT_KEY`\n\nFree/Starter note: when using a personal Doppler token, the workflow must also specify Doppler selectors (`doppler-project`, `doppler-config`). This repo uses `maple` with stage configs `prd`, `stg`, and `pr`.\n\nRuntime API URL behavior:\n\n- Deploy-time web builds resolve `VITE_API_BASE_URL` from the Cloudflare api worker domain (`api.maple.dev` in `prd`, `api-staging.maple.dev` in `stg`, worker.dev URL for `pr-*`).\n- Local `bun --filter=@maple/web dev` can still use root `.env` `VITE_API_BASE_URL` for local API routing.\n\n## Environment\n\n- Canonical env example: `.env.example`\n- API-only env example: `apps/api/.env.example`\n- Real `.env` values are local-only and should stay untracked.\n\nThe web app expects `VITE_API_BASE_URL` to point to the API (defaults to `http://localhost:3472`).\n\nFor ingest + key auth, set these at minimum in your root `.env` when running the ingest gateway:\n\n- `MAPLE_INGEST_KEY_LOOKUP_HMAC_KEY`\n- `MAPLE_INGEST_KEY_ENCRYPTION_KEY` (required for D1-backed ingest deployments)\n- `INGEST_PORT`\n- `INGEST_FORWARD_OTLP_ENDPOINT`\n- `INGEST_FORWARD_TIMEOUT_MS`\n- `INGEST_MAX_REQUEST_BODY_BYTES`\n- `INGEST_REQUIRE_TLS`\n\n## Persistence (SQLite / Turso)\n\nMaple now persists dashboards in SQLite via libSQL:\n\n- Default local mode: no Turso CLI needed. If `MAPLE_DB_URL` is unset, Maple uses `apps/api/.data/maple.db`.\n- Turso cloud mode: set `MAPLE_DB_URL` to your Turso/libSQL URL and `MAPLE_DB_AUTH_TOKEN` to your token.\n- Self-hosting: persist the `apps/api/.data` directory as a volume so dashboard state survives container/restart cycles.\n\nMigration commands:\n\n```bash\nbun --filter=@maple/api db:migrate\nbun --filter=@maple/db db:generate\nbun --filter=@maple/db db:push\nbun --filter=@maple/db db:studio\n```\n\nWhen running the API (`bun --filter=@maple/api dev` or `bun --filter=@maple/api start`), migrations are applied automatically before boot.\n\n## Ingest Keys\n\n- Maple now manages per-org ingest keys in the database (`public` + `private`).\n- Keys are available in Settings and can be rerolled independently.\n- Reroll revokes the previous key immediately.\n- Private ingest keys are encrypted at rest with `MAPLE_INGEST_KEY_ENCRYPTION_KEY` (base64-encoded 32-byte key).\n- Ingest key lookup/auth uses non-reversible HMAC hashes via `MAPLE_INGEST_KEY_LOOKUP_HMAC_KEY`.\n\n## Auth Modes\n\nMaple supports exactly two auth modes via `MAPLE_AUTH_MODE`:\n\n1. `clerk`\n    - Create a Clerk application with Organizations enabled.\n    - Set `MAPLE_AUTH_MODE=clerk`\n    - Set `CLERK_SECRET_KEY`\n    - Optionally set `CLERK_JWT_KEY` for networkless verification\n    - Set `CLERK_PUBLISHABLE_KEY` for the web app\n    - Optionally override `VITE_CLERK_SIGN_IN_URL` and `VITE_CLERK_SIGN_UP_URL`\n2. `self_hosted`\n    - Set `MAPLE_AUTH_MODE=self_hosted`\n    - Set `MAPLE_ROOT_PASSWORD` (required)\n    - Set `MAPLE_DEFAULT_ORG_ID` (defaults to `default`)\n    - Users must sign in at `/sign-in` with the root password before accessing the dashboard/API.\n\nStart apps:\n\n```bash\nbun --filter=@maple/api dev\nbun --filter=@maple/web dev\n```\n\nValidate behavior:\n\n- Clerk mode:\n    - Signed-out users are redirected to `/sign-in`\n    - Signed-in users without an active org are redirected to `/org-required`\n    - Signed-in users with an active org can query the API with bearer auth\n- Self-hosted mode:\n    - Signed-out users are redirected to `/sign-in`\n    - `MAPLE_ROOT_PASSWORD` login issues a bearer session token\n    - Protected API routes reject requests without a valid bearer session token\n\nBreaking change:\n\n- Self-hosted multi-tenant JWT/API-key auth paths were removed.\n- `MAPLE_ROOT_PASSWORD` is now required when `MAPLE_AUTH_MODE=self_hosted`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FMakisuo%2Fmaple","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FMakisuo%2Fmaple","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FMakisuo%2Fmaple/lists"}