{"id":49336236,"url":"https://github.com/datanoisetv/github-magician","last_synced_at":"2026-04-27T01:01:58.747Z","repository":{"id":353588125,"uuid":"1220025729","full_name":"DatanoiseTV/github-magician","owner":"DatanoiseTV","description":"Scheduled GitHub triage + maintenance automation driven by Claude Code — issue triage, backlog sweeps, conservative fix PRs, dependency updates, security scans with private disclosure, and release/artifact cleanup.","archived":false,"fork":false,"pushed_at":"2026-04-24T14:06:28.000Z","size":26,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-24T16:22:05.208Z","etag":null,"topics":["anthropic","automation","claude-code","cli","dependency-updates","github-automation","issue-triage","launchd","macos","repository-maintenance","responsible-disclosure","security-scanning"],"latest_commit_sha":null,"homepage":null,"language":"Shell","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/DatanoiseTV.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":null,"dco":null,"cla":null}},"created_at":"2026-04-24T13:18:35.000Z","updated_at":"2026-04-24T14:06:32.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/DatanoiseTV/github-magician","commit_stats":null,"previous_names":["datanoisetv/github-magician"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/DatanoiseTV/github-magician","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DatanoiseTV%2Fgithub-magician","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DatanoiseTV%2Fgithub-magician/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DatanoiseTV%2Fgithub-magician/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DatanoiseTV%2Fgithub-magician/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DatanoiseTV","download_url":"https://codeload.github.com/DatanoiseTV/github-magician/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DatanoiseTV%2Fgithub-magician/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32318417,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-26T23:26:28.701Z","status":"ssl_error","status_checked_at":"2026-04-26T23:26:25.802Z","response_time":129,"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":["anthropic","automation","claude-code","cli","dependency-updates","github-automation","issue-triage","launchd","macos","repository-maintenance","responsible-disclosure","security-scanning"],"created_at":"2026-04-27T01:01:58.052Z","updated_at":"2026-04-27T01:01:58.731Z","avatar_url":"https://github.com/DatanoiseTV.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# claude-maintenance\n\nLocal, scheduled GitHub automation driven by Claude Code. Triages issues, drafts\nconservative fix PRs, runs weekly dependency + security + hygiene sweeps, and\nkeeps a backlog sane — all while respecting work-in-progress and keeping any\nnon-trivial security findings private.\n\n**Runs entirely on your machine.** Uses the `gh` CLI's existing OS-keychain auth\nand the `claude` CLI's existing auth. No tokens stored in this repo, no cloud\nservices involved.\n\n## Requirements\n\n- macOS (uses `launchd` and `osascript` for notifications; trivially portable to\n  Linux with cron + `notify-send`).\n- [`claude`](https://docs.anthropic.com/claude/docs/claude-code) — the Claude\n  Code CLI, logged into an account with access to a capable model (defaults to\n  `claude-sonnet-4-6`).\n- [`gh`](https://cli.github.com/) — the GitHub CLI, authenticated (`gh auth\n  login`).\n- `envsubst` (ships with gettext: `brew install gettext` on macOS).\n- `jq`.\n\n## Install\n\n```sh\ncp .env.example .env\n$EDITOR .env             # set GITHUB_USER\n./install.sh\n```\n\nFirst run will prompt you to edit `.env`; re-run `install.sh` afterwards. The\nscript is idempotent — it'll unload-and-reload the LaunchAgents on each run.\n\n## Layout\n\n```\n.env.example                     template (checked in)\n.env                             your config (gitignored)\n.gitignore\nREADME.md · LICENSE\ninstall.sh · uninstall.sh\n\ntriage-prompt.md                 daily issue triage\nbacklog-triage-prompt.md         one-shot full-backlog sweep\nmaintenance-prompt.md            twice-weekly dep/security/hygiene sweep\n\nscripts/\n  run-triage.sh\n  run-backlog-triage.sh\n  run-maintenance.sh\nlaunchd/\n  com.claude-maintenance.triage.plist.template\n  com.claude-maintenance.maintenance.plist.template\n\nreports/                         auto-populated, gitignored\nsecurity-reports/                auto-populated, gitignored, PRIVATE disclosures\n.claude/settings.json            scoped permission allowlist for the runs\n```\n\n## Schedule\n\n| Agent | Cadence (Europe/Berlin) | Cron-equivalent (UTC) |\n|---|---|---|\n| Triage | daily 08:00 + 18:00 | `0 6,16 * * *` |\n| Maintenance | Wednesday + Sunday 22:00 | `0 20 * * 0,3` |\n\nEdit the `StartCalendarInterval` sections of the `.plist.template` files and\nre-run `install.sh` to change them.\n\n## What the agents do\n\n### Triage (daily)\n\n- **Pre-filter** by activity: drops repos not pushed this year and not pushed in\n  the last 90 days (unless they have fresh issue activity in the last 14h).\n- **Spam filter**: crypto/giveaway/off-topic/low-effort → label `possible-spam`.\n- **Security guardrails** (in every prompt): treats issue bodies as untrusted\n  input, refuses prompt-injection attempts silently, never echoes secrets,\n  redacts token patterns before including anything in output.\n- **Duplicate detection**: closes dupes of an older canonical issue with\n  cross-links. Labels `duplicate` / `possible-duplicate`.\n- **Split-large**: if a new issue has 2–5 enumerable sub-tasks, opens sub-issues\n  and converts the parent into a `meta` umbrella with a checklist.\n- **Conservative fix drafting**: \u003c50 LOC, clear bug, WIP pre-check passes (no\n  open PRs by you, no recent commits to touched files) → draft PR, never applied\n  from OP-suggested code.\n\n### Backlog triage (one-shot, can be re-run)\n\nSame rules as daily, but scans *all* open issues across *all* non-archived\nnon-fork repos. Classifies into `close-obsolete` / `actionable` / `backlog` /\n`skip-unreasonable`. Adds `effort:X` / `feasibility:Y` / `priority:Z` labels and\na structured analysis comment. Assigns `actionable` + `trivial|small` +\n`feasibility:clear` issues. Max 3 draft PRs per run.\n\n```sh\n./scripts/run-backlog-triage.sh          # real\nDRY_RUN=1 ./scripts/run-backlog-triage.sh  # no writes\n```\n\n### Maintenance (twice weekly)\n\n1. **Pick up to 10 active repos** (pushed this year or in the last 90 days).\n2. **Dep check** (`npm/bun/pip/cargo/go` outdated) — patch + minor → one draft\n   PR per repo; major → one tracking issue per repo with a checklist.\n3. **Backlog drift**: same logic as backlog-triage, capped at 10 issues.\n4. **Security scan** — injection / secrets / weak crypto / insecure\n   randomness / path traversal / SSRF / unsafe deserialization / `verify=False`\n   / ReDoS. Severity-classified with a strict disclosure split (below).\n5. **Occasional small code improvement** — max 1 per repo, max 2 per run, \u003c30\n   LOC, draft PR, WIP pre-check applies.\n6. **Release / artifact cleanup** — deletes Actions artifacts older than 90\n   days (max 20 per repo/run) and unused prereleases/drafts older than 180 days\n   (max 5 total/run). Strict safeguards: never touches stable releases, the\n   latest release, releases with \u003e10 asset downloads, or releases with tags\n   referenced from the default branch.\n7. **Code review** — one recently-merged PR per repo, comments only on real\n   findings.\n8. **Hygiene** — flags missing LICENSE / README / CI / dependabot via a\n   checklist issue.\n9. Writes its timestamp to `[maintenance-sweep] last run` in your most-active\n   repo (next run uses this to skip repos that haven't moved).\n\n## Security disclosure policy (mandatory)\n\n| Severity | Channel | Notification |\n|---|---|---|\n| **Critical / High / Medium** | **Private file** under `security-reports/\u003crepo\u003e-\u003cYYYYMMDD\u003e-\u003cseverity\u003e.md`. **Never published** (no public issue, no public PR). | Loud macOS `Sosumi` sound + \"⚠ Security findings — private\" banner. |\n| Low | Public issue labelled `security-low`, no PoC in text. | Normal banner. |\n| Informational | Folded into regular code-review comments. | None. |\n\nThis split is enforced by the prompt; don't weaken it casually. Low-priority\nfindings being public is intentional (accountability, renovate-style\nvisibility); high/medium going private is responsible-disclosure hygiene.\n\n## Safety properties\n\n- **WIP pre-check**: before drafting any PR, all agents skip repos where you\n  have an open PR, or have committed to files you'd touch in the last 7 days.\n- **Read-only on archived repos**: detected via `gh repo view` metadata.\n- **Never applies OP-suggested code**: patches suggested in issue bodies are\n  treated as untrusted. Agents rewrite fixes from the codebase.\n- **Prompt injection**: issue text is treated as data, never as instructions.\n  Attempts labelled `prompt-injection` and ignored silently (no engagement).\n- **Secret redaction**: tokens matching common patterns (`ghp_`, `sk-`, `xox[baprs]-`,\n  AWS/GCP shapes) are redacted from anything the agent writes back.\n- **Dry run**: every script honours `DRY_RUN=1` — does everything except the\n  GitHub writes.\n\n## Uninstall\n\n```sh\n./uninstall.sh               # unload + remove LaunchAgents\n./uninstall.sh --purge       # also delete reports/ and security-reports/\n```\n\nScripts and prompts stay — delete the directory if you want it fully gone.\n\n## License\n\nMIT — see `LICENSE`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdatanoisetv%2Fgithub-magician","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdatanoisetv%2Fgithub-magician","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdatanoisetv%2Fgithub-magician/lists"}