{"id":51861670,"url":"https://github.com/juninmd/evo-agent","last_synced_at":"2026-07-24T08:03:47.321Z","repository":{"id":359693871,"uuid":"1247140685","full_name":"juninmd/evo-agent","owner":"juninmd","description":null,"archived":false,"fork":false,"pushed_at":"2026-07-22T05:39:19.000Z","size":1375,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-23T10:18:11.051Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/juninmd.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-05-23T00:22:21.000Z","updated_at":"2026-07-22T05:39:26.000Z","dependencies_parsed_at":"2026-07-04T14:00:36.095Z","dependency_job_id":null,"html_url":"https://github.com/juninmd/evo-agent","commit_stats":null,"previous_names":["juninmd/evo-agent"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/juninmd/evo-agent","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/juninmd%2Fevo-agent","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/juninmd%2Fevo-agent/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/juninmd%2Fevo-agent/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/juninmd%2Fevo-agent/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/juninmd","download_url":"https://codeload.github.com/juninmd/evo-agent/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/juninmd%2Fevo-agent/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35832970,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-07-20T02:08:10.276Z","status":"online","status_checked_at":"2026-07-24T02:00:07.870Z","response_time":62,"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-07-24T08:03:46.520Z","updated_at":"2026-07-24T08:03:47.316Z","avatar_url":"https://github.com/juninmd.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# evo-agent\n\n[![TypeScript](https://img.shields.io/badge/TypeScript-5.7-blue)](https://www.typescriptlang.org/)\n[![Node](https://img.shields.io/badge/Node-24-green)](https://nodejs.org/)\n[![Biome](https://img.shields.io/badge/Lint-Biome-60a5fa)](https://biomejs.dev/)\n\nSelf-improving AI publishing agent. Crawls AI/developer sources, learns from trends, and generates pt-BR technical articles published to GitHub Pages.\n\n---\n\n## Architecture\n\n```mermaid\nflowchart TD\n    subgraph Crawler\n        RSS[RSS Feeds]\n        GN[Google News]\n        SX[SearXNG]\n        RC[Reddit Community Signals]\n    end\n\n    Crawler --\u003e|articles, signals| SQLite[(SQLite)]\n    SQLite --\u003e|context| Improver[Agent Improver]\n    Improver --\u003e|system prompt, keywords| SQLite\n    SQLite --\u003e|recent articles, snippets| Writer[Article Writer]\n    Writer --\u003e|markdown content| Publisher[GitHub Pages Publisher]\n    Publisher --\u003e|Jekyll assets, markdown| GH[gh-pages branch]\n    Publisher --\u003e|published URL| Notifier[Telegram Notifier]\n```\n\n## Features\n\n- **Multi-source crawling**: RSS/HTML sources, Google News keyword search, SearXNG for Reddit/X.com, Hacker News, TabNews, GitHub Trending, and Reddit community signal analysis\n- **Self-improvement loop**: System prompt and search keywords evolve from ingested content\n- **Reliable orchestration**: Overlapping cycles are skipped and every run is recorded in SQLite\n- **Editorial scoring**: Recency, engagement, source authority, diversity, and cross-source evidence shape selection\n- **Evidence provenance**: Every selected highlight preserves source URL, title, and supporting excerpt\n- **Guarded self-improvement**: Prompt candidates are scored, versioned, promoted only without regression, and rollback-capable\n- **Article generation**: richer daily articles and weekly/periodic reports in pt-BR via LLM, with expanded Reddit/community evidence when available\n- **Living ebook**: weekly/refinable AI-assisted development handbook published to GitHub Pages\n- **Atomic GitHub Pages publishing**: Article, layouts, and indexes land in one Git commit\n- **Telegram outbox**: Failed delivery retries with exponential backoff and dead-letter isolation\n- **Operational health**: Structured logs, persistent metrics, primary-source alerts, and a machine-readable health command\n- **Playwright stealth fallback**: Automatic browser-based fetch when RSS sources return 403/429\n\n## Quick Start\n\n```bash\ngit clone git@github.com:juninmd/evo-agent.git\ncd evo-agent\ncp .env.example .env\n# Edit .env with your credentials\nnpm install\nnpm run build\n```\n\n## Environment Variables\n\n| Variable | Required | Default | Description |\n|---|---|---|---|\n| `LITELLM_API_BASE` | No | `http://localhost:4000/v1` | LiteLLM base URL |\n| `LITELLM_API_KEY` | No | `no-key` | LiteLLM API key |\n| `LITELLM_MODEL` | No | `cloud/llama-70b` | Primary model name |\n| `LITELLM_FALLBACK_MODELS` | No | `cloud/maverick,cloud/llama-8b` | Comma-separated fallback models tried if the primary fails/times out/returns empty |\n| `LITELLM_MAX_OUTPUT_TOKENS` | No | `12000` | Max output tokens per request |\n| `LITELLM_TIMEOUT_MS` | No | `300000` | LiteLLM request timeout in milliseconds |\n| `TELEGRAM_BOT_TOKEN` | Yes | — | Telegram Bot API token |\n| `TELEGRAM_CHAT_ID` | Yes | — | Target Telegram chat/group ID |\n| `GITHUB_TOKEN` | Yes | — | GitHub PAT with repo write access |\n| `GITHUB_OWNER` | Yes | — | GitHub username or org |\n| `GITHUB_REPO` | Yes | — | Repository name for Pages |\n| `GITHUB_BRANCH` | No | `gh-pages` | Target branch for published content |\n| `CRAWL_INTERVAL_MINUTES` | No | `40` | Learn cycle frequency in daemon mode |\n| `ARTICLE_CRON` | No | `0 8 * * *` | Daily article cron expression |\n| `SEARXNG_URL` | No | `http://searxng.searxng.svc.cluster.local` | SearXNG instance URL |\n| `LOG_LEVEL` | No | `info` | Logging verbosity (`debug`, `info`, `warn`, `error`) |\n| `LOG_FORMAT` | No | `json` | Structured `json` logs or local `text` output |\n| `DB_PATH` | No | `data/knowledge.db` | SQLite database path |\n\n## Run Modes\n\nSet `RUN_MODE` env var to control execution:\n\n| Mode | Behavior |\n|---|---|\n| `DAEMON` (default) | Runs learn cycle immediately, then schedules crawling + daily article + weekly report via cron |\n| `CRAWL` | Single crawl + improve cycle, then exits |\n| `DAILY` | Generates and publishes one daily article, then exits |\n| `WEEKLY` | Generates and publishes one weekly article, then exits |\n| `BIWEEKLY` | Generates and publishes one biweekly report, then exits |\n| `MONTHLY` | Generates and publishes one monthly report, then exits |\n| `BIMONTHLY` | Generates and publishes one bimonthly report, then exits |\n| `SEMESTER` | Generates and publishes one semester report, then exits |\n| `EBOOK` | Refines and publishes the living AI-assisted development handbook, then exits |\n\n## Commands\n\n```bash\nnpm run build                  # TypeScript compilation\nnpm run lint                   # Biome static analysis\nnpm run lint:fix               # Auto-fix lint issues\nnpm run smoke:reddit-comments  # Test Reddit signal crawler with isolated DB\nnpm run benchmark:editorial    # Run deterministic editorial regression corpus\nnpm run test:coverage          # Enforce repository coverage floors\nnpm run health                 # Emit operational health JSON\nnpm run prompt:rollback        # Restore the previous promoted system prompt\nnpm run backfill:articles -- 2026-06-01 2026-06-11 # Publish historical editions without Telegram spam\nnpm run dev                    # Watch mode with tsx\nnpm start                      # Run compiled output\n```\n\n## Project Structure\n\n```\nsrc/\n  index.ts              # Entry point, cron scheduling, run modes\n  config.ts             # Env loading, validation, frozen config\n  crawler/\n    index.ts            # RSS, Google News, SearXNG, Reddit signal crawlers\n    reddit-smoke.ts     # Standalone Reddit community signal smoke test\n  knowledge/\n    store.ts            # SQLite persistence (articles, snippets, state, publish log)\n  agent/\n    improver.ts         # Self-improvement: updates prompt and keywords from recent sources\n    writer.ts           # LLM-powered article and weekly report generation\n    ebook.ts            # Living handbook refinement\n    editorial-renderer.ts # Deterministic article rendering and citations\n    prompt-policy.ts    # Prompt promotion and rollback policy\n  publisher/\n    github.ts           # Atomic GitHub API transaction and publication\n    site-renderer.ts    # Jekyll scaffold, layouts, CSS, and index rendering\n  notifier/\n    telegram.ts         # Telegram Bot API notifications\n    outbox.ts           # Retry and dead-letter policy\n  observability/\n    health.ts           # Operational health evaluation\n  utils/\n    ai.ts               # LiteLLM client wrapper for AI text generation\n    logger.ts           # Timestamped log levels via console\n```\n\n## Published Site\n\nArticles are available at `https://\u003cGITHUB_OWNER\u003e.github.io/\u003cGITHUB_REPO\u003e/` with:\n\n- Light and dark theme toggle (persisted in `localStorage`)\n- Article archive grouped by year and month\n- Weekly reports section\n- Markdown download button per article\n- Responsive typography (Source Serif 4 body, IBM Plex Mono code, IBM Plex Sans UI)\n\n## Deployment\n\nDocker image published at `ghcr.io/juninmd/evo-agent:latest`. Kubernetes manifests live in a separate `app-charts/evo-agent/` repository. Secrets are injected via environment — never commit `.env` or credentials to this repository.\n\n## Security\n\n- `.env` excluded from version control\n- Tokens never logged or exposed\n- Browser sandbox enabled (no `--disable-web-security`)\n- Signal handlers close SQLite database gracefully on shutdown\n- Article content wrapped with `{% raw %}` to prevent Jekyll Liquid injection\n\nOperational details and SLO-style checks are documented in\n[`docs/OPERATIONS.md`](docs/OPERATIONS.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjuninmd%2Fevo-agent","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjuninmd%2Fevo-agent","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjuninmd%2Fevo-agent/lists"}