{"id":47352960,"url":"https://github.com/thomasindrias/mahoraga","last_synced_at":"2026-04-01T18:39:10.305Z","repository":{"id":345118352,"uuid":"1184580518","full_name":"thomasindrias/mahoraga","owner":"thomasindrias","description":"Self-evolving frontend intelligence — ingests analytics, detects UI issues, dispatches AI agents to fix them","archived":false,"fork":false,"pushed_at":"2026-03-18T00:21:30.000Z","size":275,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-18T07:58:43.890Z","etag":null,"topics":["ai","ai-agents","amplitude","analytics","automation","claude","code-quality","developer-tools","frontend","monorepo","posthog","pull-requests","sentry","typescript","ux"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thomasindrias.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":".github/SECURITY.md","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-03-17T18:16:26.000Z","updated_at":"2026-03-18T00:21:33.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/thomasindrias/mahoraga","commit_stats":null,"previous_names":["thomasindrias/mahoraga"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/thomasindrias/mahoraga","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomasindrias%2Fmahoraga","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomasindrias%2Fmahoraga/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomasindrias%2Fmahoraga/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomasindrias%2Fmahoraga/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thomasindrias","download_url":"https://codeload.github.com/thomasindrias/mahoraga/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomasindrias%2Fmahoraga/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30706183,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-19T05:29:31.190Z","status":"ssl_error","status_checked_at":"2026-03-19T05:28:25.821Z","response_time":57,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: 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","ai-agents","amplitude","analytics","automation","claude","code-quality","developer-tools","frontend","monorepo","posthog","pull-requests","sentry","typescript","ux"],"created_at":"2026-03-18T01:12:58.505Z","updated_at":"2026-04-01T18:39:10.300Z","avatar_url":"https://github.com/thomasindrias.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"docs/assets/logo-dark.svg\"\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"docs/assets/logo-light.svg\"\u003e\n  \u003cimg alt=\"Mahoraga\" src=\"docs/assets/logo-light.svg\" width=\"120\" height=\"120\"\u003e\n\u003c/picture\u003e\n\n# Mahoraga\n\n**Self-evolving frontend intelligence.**\n\nIngests user behavior data from your existing analytics stack, detects UI issues through automated analysis, and dispatches AI agents to fix them — creating pull requests automatically.\n\n[![npm](https://img.shields.io/npm/v/mahoraga-cli.svg)](https://www.npmjs.com/package/mahoraga-cli)\n[![License: MIT](https://img.shields.io/badge/License-MIT-D4A336.svg)](LICENSE)\n[![Node](https://img.shields.io/badge/Node-%3E%3D20-333.svg)](https://nodejs.org)\n[![TypeScript](https://img.shields.io/badge/TypeScript-strict-333.svg)](https://www.typescriptlang.org)\n\n\u003c/div\u003e\n\n---\n\nMahoraga is **not** a tracker. It is the brain that sits on top of your existing analytics data and turns behavioral signals into code improvements. Named after the [Jujutsu Kaisen character](https://jujutsu-kaisen.fandom.com/wiki/Mahoraga) that adapts after every encounter.\n\n## How It Works\n\n```\nSources (Amplitude, PostHog, Sentry)\n    | pull via API adapters\nNormalize (common event schema, Zod-validated)\n    | persist to SQLite\nAnalyze (pluggable detection rules)\n    | produce Issue reports\nMap (AST-based selector-to-source-file resolution)\n    | resolve CSS selectors to source locations\nDispatch (OpenCode CLI agent)\n    | create PR with plan + fix\nHuman Review -\u003e Merge\n```\n\n## Features\n\n- **Source adapters** — Pull behavioral data from Amplitude and PostHog, with Sentry planned\n- **Detection rules** — Pluggable analysis engine (rage clicks, error spikes, dead clicks, form abandonment, slow navigation, layout shifts, error loops)\n- **Configurable thresholds** — Tune every detection rule's sensitivity via `analysis.thresholds` in config\n- **URL normalization** — Group dynamic URLs (`/products/123`, `/products/456`) into route patterns (`/products/:id`)\n- **False-positive suppression** — Permanently dismiss noisy issues with `mahoraga dismiss`, with audit trail\n- **Code mapper** — AST-based resolution from CSS selectors to exact source file locations\n- **Agent dispatcher** — Generates fixes, writes tests, validates via build/test/diff, and opens draft PRs\n- **Adaptation loop** — If a generated test fails, the agent retries with error context (up to 3 attempts)\n- **Cost budget enforcement** — Tracks actual dispatch costs and stops when per-run cost or dispatch limits are reached\n- **Blast radius control** — Allowed/denied paths, confidence thresholds, cost budgets, diff size limits\n- **Agent isolation** — Operates in fresh git worktrees; `main` is never directly modified\n\n## Quick Start\n\n### Prerequisites\n\n- Node.js \u003e= 20\n- An [Amplitude](https://amplitude.com) or [PostHog](https://posthog.com) account\n- [OpenCode CLI](https://opencode.ai) (for agent dispatch)\n- [GitHub CLI](https://cli.github.com) (`gh`) for PR creation\n\n### Install\n\n```bash\n# npm\nnpm install mahoraga-cli\n\n# pnpm\npnpm add mahoraga-cli\n\n# Or try it without installing\nnpx mahoraga-cli --help\n```\n\n\u003e To use schemas and types directly in your code, also install `mahoraga-core`.\n\n### Configure\n\nCreate `mahoraga.config.ts` in your project root:\n\n```typescript\nimport { defineConfig } from \"mahoraga-core\";\n\nexport default defineConfig({\n  sources: [\n    // Amplitude\n    {\n      adapter: \"amplitude\",\n      apiKey: process.env.MAHORAGA_AMPLITUDE_API_KEY!,\n      secretKey: process.env.MAHORAGA_AMPLITUDE_SECRET_KEY!,\n    },\n    // Or PostHog\n    {\n      adapter: \"posthog\",\n      apiKey: process.env.MAHORAGA_POSTHOG_API_KEY!,\n      projectId: process.env.MAHORAGA_POSTHOG_PROJECT_ID!,\n      // host: \"https://eu.posthog.com\",  // optional, for self-hosted or EU cloud\n    },\n  ],\n  analysis: {\n    rules: [\"rage-clicks\", \"error-spikes\", \"dead-clicks\", \"form-abandonment\", \"slow-navigation\", \"layout-shifts\", \"error-loops\"],\n    // Group dynamic URLs into route patterns\n    routePatterns: [\"/products/:id\", \"/users/:userId/posts/:postId\"],\n    // Tune detection sensitivity per rule\n    thresholds: {\n      \"rage-clicks\": { clickCount: 3, windowMs: 1000 },\n      \"slow-navigation\": { thresholdMs: 5000 },\n    },\n  },\n  agent: {\n    provider: \"opencode\",\n    allowedPaths: [\"src/**\"],\n    deniedPaths: [\"src/generated/**\"],\n  },\n});\n```\n\nOr generate one interactively:\n\n```bash\nnpx mahoraga-cli init\n```\n\nStore credentials in `.mahoraga.env` (automatically gitignored):\n\n```env\nMAHORAGA_AMPLITUDE_API_KEY=your-api-key\nMAHORAGA_AMPLITUDE_SECRET_KEY=your-secret-key\n# Or for PostHog:\nMAHORAGA_POSTHOG_API_KEY=your-personal-api-key\nMAHORAGA_POSTHOG_PROJECT_ID=your-project-id\n```\n\n### Run\n\n```bash\n# Preview detected issues without dispatching agents\nnpx mahoraga-cli analyze --dry-run\n\n# Run full pipeline: pull → analyze → dispatch → PR\nnpx mahoraga-cli analyze\n\n# Suppress a false-positive issue\nnpx mahoraga-cli dismiss \u003cfingerprint\u003e --reason \"expected behavior\"\n\n# List or undo suppressions\nnpx mahoraga-cli dismiss --list\nnpx mahoraga-cli dismiss --undo \u003cfingerprint\u003e\n\n# Query stored events or detected issues\nnpx mahoraga-cli inspect events\nnpx mahoraga-cli inspect issues\n\n# Check agent dispatch status\nnpx mahoraga-cli status\n\n# Rebuild code-to-event index\nnpx mahoraga-cli map\n\n# Clean up old data\nnpx mahoraga-cli gc\n\n# Scaffold a custom detection rule\nnpx mahoraga-cli create-rule\n```\n\n## Custom Rules\n\nCreate your own detection rules with the scaffold command:\n\n```bash\nnpx mahoraga-cli create-rule\n```\n\nThis generates a rule class and test file with boilerplate. Follow the prompts to name your rule, select event types, and get started.\n\n## Packages\n\n| Package | npm | Description |\n|---------|-----|-------------|\n| [`mahoraga-core`](packages/core) | [![npm](https://img.shields.io/npm/v/mahoraga-core.svg?label=)](https://www.npmjs.com/package/mahoraga-core) | Zod schemas, SQLite storage, types, utilities |\n| [`mahoraga-sources`](packages/sources) | [![npm](https://img.shields.io/npm/v/mahoraga-sources.svg?label=)](https://www.npmjs.com/package/mahoraga-sources) | Pluggable source adapters (Amplitude, PostHog) |\n| [`mahoraga-analyzer`](packages/analyzer) | [![npm](https://img.shields.io/npm/v/mahoraga-analyzer.svg?label=)](https://www.npmjs.com/package/mahoraga-analyzer) | Detection rules engine |\n| [`mahoraga-mapper`](packages/mapper) | [![npm](https://img.shields.io/npm/v/mahoraga-mapper.svg?label=)](https://www.npmjs.com/package/mahoraga-mapper) | AST-based selector-to-source mapping |\n| [`mahoraga-agent`](packages/agent) | [![npm](https://img.shields.io/npm/v/mahoraga-agent.svg?label=)](https://www.npmjs.com/package/mahoraga-agent) | Agent dispatcher with adaptation loop |\n| [`mahoraga-cli`](packages/cli) | [![npm](https://img.shields.io/npm/v/mahoraga-cli.svg?label=)](https://www.npmjs.com/package/mahoraga-cli) | CLI entry point |\n\n### Dependency Graph\n\n```\ncli (composition root)\n ├── agent ─── core, mapper\n ├── analyzer ── core\n ├── sources ─── core\n ├── mapper ──── core\n └── core\n```\n\n## Configuration Reference\n\nAll options with their defaults:\n\n```typescript\ndefineConfig({\n  // Required: at least one source\n  sources: [\n    { adapter: \"amplitude\", apiKey: \"...\", secretKey: \"...\" },\n    { adapter: \"posthog\", apiKey: \"...\", projectId: \"...\", host: \"...\" },\n  ],\n\n  // Analysis (all optional)\n  analysis: {\n    windowDays: 3,                    // Days of data to analyze\n    rules: [\"rage-clicks\", \"error-spikes\"],  // Default; add more as needed:\n    // \"dead-clicks\", \"form-abandonment\", \"slow-navigation\", \"layout-shifts\", \"error-loops\"\n    customRules: [],                  // Custom DetectionRule implementations\n    routePatterns: [],                // URL normalization: [\"/products/:id\"]\n    thresholds: {                     // Per-rule threshold overrides\n      \"rage-clicks\": { clickCount: 3, windowMs: 1000 },\n      \"error-spikes\": { spikeMultiplier: 2, minAbsoluteCount: 5 },\n      \"dead-clicks\": { minClickCount: 5, minSessions: 2, waitMs: 2000 },\n      \"form-abandonment\": { minAbandonRate: 0.4, minSessions: 3 },\n      \"slow-navigation\": { thresholdMs: 3000, minOccurrences: 3, minSessions: 2 },\n      \"layout-shifts\": { minPoorEvents: 3, minSessions: 2 },\n      \"error-loops\": { minOccurrences: 3, minSessions: 2 },\n    },\n  },\n\n  // Agent (all optional)\n  agent: {\n    provider: \"opencode\",             // \"opencode\" only\n    workflow: \"plan-then-implement\",   // Only supported workflow\n    agentMdPath: \"path/to/AGENTS.md\", // Optional: agent-specific instructions\n    createPR: true,                   // Whether to create PRs (default: true)\n    baseBranch: \"main\",\n    draftPR: true,                    // Create PRs as drafts\n    maxRetries: 3,                    // Adaptation loop retries\n    timeoutMs: 300000,                // Max dispatch time in ms (5 min)\n    maxCostPerIssue: 2,               // USD budget per issue\n    maxCostPerRun: 20,                // USD budget per run\n    maxDispatchesPerRun: 5,\n    confidenceThreshold: 0.7,         // Below this → issue instead of PR\n    allowedPaths: [],                 // Glob patterns the agent can modify\n    deniedPaths: [],                  // Glob patterns the agent must not modify\n    postChecks: {\n      build: true,\n      test: true,\n      maxDiffLines: 500,\n    },\n  },\n\n  // Storage (all optional)\n  storage: {\n    dbPath: \".mahoraga/mahoraga.db\",\n    retentionDays: 30,\n  },\n\n  // Logging (all optional)\n  logging: {\n    level: \"info\",                    // \"debug\" | \"info\" | \"warn\" | \"error\"\n    format: \"pretty\",                 // \"pretty\" | \"json\"\n  },\n});\n```\n\n## AI Agent Support\n\nMahoraga includes a Claude Code plugin with 4 skills that help AI coding agents understand and extend the system:\n\n| Skill | Description |\n|-------|-------------|\n| `mahoraga-setup` | Initialize, configure, and run Mahoraga |\n| `mahoraga-custom-rules` | Write custom detection rules for the analysis engine |\n| `mahoraga-source-adapters` | Build adapters for new analytics platforms |\n| `mahoraga-agent-config` | Configure agent dispatch, governance, and cost controls |\n\nThe plugin auto-discovers from `.claude-plugin/` when cloning the repo. Skills work with Claude Code and any agent that supports the superpowers skills format.\n\n## Troubleshooting\n\n### GITHUB_TOKEN Hijacks AI Provider\n\nOpenCode auto-detects `GITHUB_TOKEN` and defaults to GitHub Models, which returns 403 errors. Mahoraga strips `GITHUB_TOKEN` from the agent's environment automatically, but if you see provider errors in CI, ensure your `.opencode.json` explicitly sets the provider.\n\n### Permission Config for CI\n\nOpenCode requires explicit permission grants for non-interactive mode. Your `.opencode.json` must include:\n\n```json\n{\n  \"permission\": { \"*\": \"allow\" }\n}\n```\n\nWithout this, OpenCode blocks on tool approval prompts with no TTY.\n\n### PAT_TOKEN for PR Creation\n\nGitHub organization policies often restrict `GITHUB_TOKEN` from creating pull requests. Create a fine-grained Personal Access Token with:\n- **Contents:** Read and write\n- **Pull requests:** Read and write\n\nStore it as `PAT_TOKEN` in repository secrets. The generated workflow uses `PAT_TOKEN || GITHUB_TOKEN` as fallback.\n\n### Agent Reports Success but No Files Changed\n\nIf the AI agent claims success but creates no diff, Mahoraga's adaptation loop detects this and retries. If all retries fail, check:\n- The prompt is specific enough for the agent to locate the right files\n- `.opencode.json` provider config points to a capable model\n- The worktree has the expected source files\n\n### Stale Remote Branches\n\nFailed agent runs may leave remote branches (e.g. `mahoraga/fix-error-spikes-...`). Prune them periodically:\n\n```bash\ngit branch -r | grep 'origin/mahoraga/' | sed 's|origin/||' | xargs -I{} git push origin --delete {}\n```\n\n## Contributing\n\n```bash\ngit clone https://github.com/thomasindrias/mahoraga.git\ncd mahoraga\npnpm install\npnpm turbo build\n```\n\n```bash\npnpm turbo build              # Build all packages\npnpm turbo test               # Run all tests\npnpm turbo test:coverage      # Run tests with 80% coverage thresholds\npnpm turbo test:integration   # Run all tests including integration tests\npnpm turbo lint               # Lint all packages\npnpm turbo typecheck          # Type-check all packages\n\n# Work on a specific package\npnpm --filter mahoraga-core test\npnpm --filter mahoraga-analyzer build\n```\n\n## License\n\n[MIT](LICENSE) - Thomas Indrias\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthomasindrias%2Fmahoraga","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthomasindrias%2Fmahoraga","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthomasindrias%2Fmahoraga/lists"}