{"id":16536106,"url":"https://github.com/jasperan/github-utils","last_synced_at":"2026-05-09T16:03:59.499Z","repository":{"id":40600136,"uuid":"161610594","full_name":"jasperan/github-utils","owner":"jasperan","description":"Utilities to increase Github commit, release, branch,... counts according to Github ToS","archived":false,"fork":false,"pushed_at":"2023-03-24T00:00:09.000Z","size":1369234,"stargazers_count":3,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-07T11:15:36.566Z","etag":null,"topics":["automation","bot","commits","github","issue-management","issues"],"latest_commit_sha":null,"homepage":"","language":"Python","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/jasperan.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}},"created_at":"2018-12-13T08:53:24.000Z","updated_at":"2024-08-27T13:45:52.000Z","dependencies_parsed_at":"2024-11-14T09:43:20.034Z","dependency_job_id":"4e80037d-fa76-4de3-a954-8922d42b6748","html_url":"https://github.com/jasperan/github-utils","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jasperan/github-utils","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jasperan%2Fgithub-utils","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jasperan%2Fgithub-utils/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jasperan%2Fgithub-utils/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jasperan%2Fgithub-utils/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jasperan","download_url":"https://codeload.github.com/jasperan/github-utils/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jasperan%2Fgithub-utils/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280583894,"owners_count":26355258,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-23T02:00:06.710Z","response_time":142,"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":["automation","bot","commits","github","issue-management","issues"],"created_at":"2024-10-11T18:29:44.171Z","updated_at":"2026-05-09T16:03:59.492Z","avatar_url":"https://github.com/jasperan.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# github-utils\n\nA toolkit for painting text and patterns on your GitHub contribution graph, simulating realistic developer activity, and tracking contribution analytics.\n\n## Installation\n\n\u003c!-- one-command-install --\u003e\n\u003e **One-command install**: clone, configure, and run in a single step:\n\u003e\n\u003e ```bash\n\u003e curl -fsSL https://raw.githubusercontent.com/jasperan/github-utils/master/install.sh | bash\n\u003e ```\n\u003e\n\u003e \u003cdetails\u003e\u003csummary\u003eAdvanced options\u003c/summary\u003e\n\u003e\n\u003e Override install location:\n\u003e ```bash\n\u003e PROJECT_DIR=/opt/myapp curl -fsSL https://raw.githubusercontent.com/jasperan/github-utils/master/install.sh | bash\n\u003e ```\n\u003e\n\u003e Or install manually:\n\u003e ```bash\n\u003e git clone https://github.com/jasperan/github-utils.git\n\u003e cd github-utils\n\u003e # See below for setup instructions\n\u003e ```\n\u003e \u003c/details\u003e\n\n\n```bash\n# From source (development)\ngit clone https://github.com/jasperan/github-utils.git\ncd github-utils\npip install -e \".[dev]\"\n\n# From PyPI\npip install github-utils\n```\n\nRequires Python 3.10+.\n\n## Quick Start\n\n```bash\n# Paint \"HELLO\" on your contribution graph (dry run)\ngithub-utils paint \"HELLO\" --dry-run\n\n# Simulate 90 days of realistic activity\ngithub-utils simulate --days 90 --profile default --dry-run\n\n# Check available subcommands\ngithub-utils --help\n```\n\n## Commands Reference\n\n### paint\n\nRender text, built-in patterns, or custom YAML pattern files onto the contribution graph.\n\n```bash\n# Paint text with default intensity (4)\ngithub-utils paint \"HI\"\n\n# Paint text with lower intensity\ngithub-utils paint \"CODE\" --intensity 2\n\n# Paint a built-in pattern\ngithub-utils paint --pattern heart\n\n# Paint from a custom YAML file\ngithub-utils paint --file my-pattern.yaml\n\n# Preview only (no commits)\ngithub-utils paint \"TEST\" --preview\n\n# Dry run (show commit plan without executing)\ngithub-utils paint \"ABC\" --dry-run\n```\n\nOptions:\n\n| Option | Short | Description |\n|--------|-------|-------------|\n| `--pattern` | `-p` | Named built-in pattern (heart, wave, checkerboard) |\n| `--file` | `-f` | Path to a YAML pattern file |\n| `--intensity` | `-i` | Intensity level 1-4 for text mode (default: 4) |\n| `--preview` | | Show terminal grid preview only |\n| `--dry-run` | | Show commit plan without executing |\n\nText is rendered using a built-in 5x7 pixel font supporting A-Z, 0-9, and common punctuation (space, dash, period, exclamation mark). Each character occupies 5 columns with a 1-column gap. The contribution graph has 52 columns, so approximately 8 characters fit.\n\n### simulate\n\nGenerate realistic GitHub activity patterns using configurable developer profiles.\n\n```bash\n# Simulate 90 days with the default profile\ngithub-utils simulate --days 90\n\n# Use a specific profile\ngithub-utils simulate --days 180 --profile night-owl\n\n# Reproducible output with a seed\ngithub-utils simulate --days 30 --profile 9-to-5 --seed 42 --dry-run\n```\n\nOptions:\n\n| Option | Short | Description |\n|--------|-------|-------------|\n| `--days` | `-d` | Number of days to simulate (default: 90) |\n| `--profile` | `-p` | Activity profile name (default: default) |\n| `--seed` | `-s` | Random seed for reproducibility |\n| `--dry-run` | | Show plan without executing |\n\n### stats\n\nContribution analytics with snapshot and comparison capabilities.\n\n```bash\n# Take a snapshot of current contribution stats\ngithub-utils stats snapshot\n\n# Compare two snapshots\ngithub-utils stats compare --before snap-before.json --after snap-after.json\n```\n\nSubcommands:\n\n- `snapshot` -- Capture a point-in-time snapshot of your contribution statistics (requires GitHub API token).\n- `compare` -- Load two snapshot JSON files and display deltas for total contributions, current streak, longest streak, and active days.\n\n### legacy\n\nBackward-compatible bridge for the original `utils.py` CLI interface.\n\n```bash\n# Create commits (legacy mode)\ngithub-utils legacy commit 50000 --dry-run\n\n# Branch operations (legacy mode)\ngithub-utils legacy branch inf --dry-run\n```\n\n## Pattern Library\n\nThree built-in patterns ship with the project. Custom patterns can be created as YAML files.\n\n| Pattern | Description |\n|---------|-------------|\n| `heart` | Heart shape centered on the grid |\n| `wave` | Sine wave pattern across the full width |\n| `checkerboard` | Alternating filled and empty cells |\n\nCustom pattern YAML format:\n\n```yaml\nname: my-pattern\ngrid:\n- [0, 0, 4, 4, 0, 0, ...]  # row 0 (Sunday)\n- [0, 4, 4, 4, 4, 0, ...]  # row 1 (Monday)\n# ... 7 rows total, 52 columns each\n# Values 0-4 represent intensity levels\n```\n\n## Activity Profiles\n\nThe simulate command uses a state machine with three modes (normal, burst, quiet) to produce organic-looking contribution patterns. Five named profiles are available:\n\n| Profile | Description |\n|---------|-------------|\n| `default` | Balanced weekday activity with lighter weekends. Moderate burst/quiet cycles. |\n| `night-owl` | Slightly higher weekday intensity, shorter bursts, fewer quiet days. |\n| `weekend-warrior` | Low weekday activity, high weekend commits. Frequent short bursts. |\n| `9-to-5` | Strong weekday focus, near-zero weekends. Lower burst probability, longer quiet periods. |\n| `open-source-maintainer` | Consistent daily activity including weekends. Long burst phases, rare quiet days. |\n\nEach profile configures: weekly pattern multipliers (Mon-Sun), commits per active day range, burst/quiet probabilities and durations, and burst multiplier.\n\n## Realism Engines\n\nWhen realism is enabled (default for `simulate`, optional for `paint`), two engines enhance the output:\n\n- **Temporal Engine** -- Generates timestamps weighted toward business hours (peaks at 10-12 and 14-17) with per-commit jitter, so commits are spread naturally across each day rather than clustering at a single time.\n- **Content Engine** -- Produces conventional-commit-style messages (e.g., `feat: add auth support`) from a bank of 2400+ unique combinations. File changes span multiple extensions (.py, .js, .ts, .md, .yaml, .json) with 1-4 files per commit.\n\n## Configuration\n\nConfiguration is loaded from a YAML file with environment variable overrides.\n\n### Config file\n\nDefault location: `~/.github-utils.yaml`\n\n```yaml\ntoken: ghp_xxxxxxxxxxxx    # GitHub personal access token\nbranch: github-utils-canvas # Branch name for painted commits\npush_every: 500             # Push interval (commits between pushes)\ntimezone: UTC               # Timezone for timestamp generation\nusername: your-username     # GitHub username\n```\n\nLegacy format (`personal_access_token` key) is also accepted.\n\n### Environment variables\n\n| Variable | Config key | Description |\n|----------|-----------|-------------|\n| `GITHUB_UTILS_TOKEN` | `token` | GitHub API token |\n| `GITHUB_UTILS_BRANCH` | `branch` | Target branch name |\n| `GITHUB_UTILS_PUSH_EVERY` | `push_every` | Push interval |\n| `GITHUB_UTILS_TIMEZONE` | `timezone` | Timezone |\n| `GITHUB_UTILS_USERNAME` | `username` | GitHub username |\n| `GITHUB_TOKEN` | `token` (fallback) | Fallback token source |\n\n### GitHub CLI token\n\nIf no token is configured, the API client can pull a token from the GitHub CLI:\n\n```bash\ngh auth login\n# github-utils will use `gh auth token` automatically\n```\n\n## Development\n\n### Setup\n\n```bash\nconda create -n github-utils python=3.12\nconda activate github-utils\npip install -e \".[dev]\"\n```\n\n### Running tests\n\n```bash\n# Full suite with coverage\npytest --cov=github_utils -v\n\n# Single test file\npytest tests/test_integration.py -v\n\n# Only unit tests (fast)\npytest tests/ -v --ignore=tests/test_integration.py\n```\n\n### Project structure\n\n```\nsrc/github_utils/\n  cli.py               # Typer app entry point\n  config.py             # YAML + env var configuration\n  executor.py           # Wires paint/simulation plans to git operations\n  commands/\n    paint.py            # paint subcommand\n    simulate.py         # simulate subcommand\n    stats.py            # stats subcommand\n    legacy.py           # legacy bridge\n  painter/\n    font.py             # 5x7 pixel font (A-Z, 0-9, punctuation)\n    grid.py             # 7x52 ContributionGrid model\n    engine.py           # Grid -\u003e PaintPlan orchestrator\n    patterns.py         # Built-in and custom YAML pattern loader\n    preview.py          # Terminal grid preview renderer\n  realism/\n    profile.py          # Developer activity profiles and state machine\n    temporal.py         # Timestamp generation with hour weighting\n    content.py          # Commit message and file change generation\n  analytics/\n    snapshot.py         # Snapshot persistence and comparison\n  api/\n    client.py           # GitHub GraphQL API client\n  git/\n    operations.py       # GitEngine for backdated commits and push\npatterns/               # Built-in YAML patterns (heart, wave, checkerboard)\ntests/                  # Unit and integration tests\n```\n\n## License\n\nSee [LICENSE](LICENSE) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjasperan%2Fgithub-utils","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjasperan%2Fgithub-utils","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjasperan%2Fgithub-utils/lists"}