Compare commits
10 Commits
5bbdcde00e
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 78003c0e33 | |||
| 01c34b7e4c | |||
| 68d00058f0 | |||
| 9c34c0401b | |||
| 505fe09ed3 | |||
| 1909389c33 | |||
| 9abd075121 | |||
| 95380ec3b1 | |||
| 91a2f0fb62 | |||
| c25fb2e10e |
@@ -16,6 +16,13 @@
|
||||
<string>/Users/hansheinemann/Projects/hans-tools/tools/gh-monitor/state/stdout.log</string>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>/Users/hansheinemann/Projects/hans-tools/tools/gh-monitor/state/stderr.log</string>
|
||||
<key>EnvironmentVariables</key>
|
||||
<dict>
|
||||
<key>PATH</key>
|
||||
<string>/usr/local/bin:/usr/bin:/bin:/Users/hansheinemann/.nvm/versions/node/v22.22.1/bin</string>
|
||||
<key>HOME</key>
|
||||
<string>/Users/hansheinemann</string>
|
||||
</dict>
|
||||
<key>RunAtLoad</key>
|
||||
<false/>
|
||||
</dict>
|
||||
|
||||
@@ -6,3 +6,4 @@ repos:
|
||||
- review_comment
|
||||
- issue_comment
|
||||
- pr_closed
|
||||
ignore_actor: hansheinemann # skip my own comments to prevent feedback loops
|
||||
|
||||
@@ -153,6 +153,31 @@ def format_notification(repo_slug: str, pr: dict, event: dict) -> str:
|
||||
return f'[gh-monitor] PR #{number} "{title}" — {actor} {action}:\n"{body_preview}"\n{url}'
|
||||
|
||||
|
||||
def dispatch_to_main(repo_slug: str, pr: dict, event: dict) -> None:
|
||||
"""
|
||||
Send a system event to the main session with full context so Hans handles
|
||||
the PR comment directly — no isolated agent needed.
|
||||
"""
|
||||
number = pr["number"]
|
||||
title = pr["title"]
|
||||
actor = event["actor"]
|
||||
action = event["action"]
|
||||
body = (event["body"] or "")[:500]
|
||||
url = event["url"]
|
||||
|
||||
text = (
|
||||
f"[gh-monitor] New PR activity on {repo_slug}#{number} \"{title}\":\n"
|
||||
f"{actor} {action}:\n"
|
||||
f'"{body}"\n'
|
||||
f"{url}\n\n"
|
||||
f"Read the full comment, address it if needed (code change + GitHub reply), "
|
||||
f"and notify Andrew on Signal when done."
|
||||
)
|
||||
|
||||
notify(text)
|
||||
log.info("Notified main session for PR #%d %s by %s", number, action, actor)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# STEP 8 — error tracking
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -208,6 +233,8 @@ def poll_repo(repo_cfg: dict, state: dict) -> dict:
|
||||
|
||||
all_new_events: list[tuple[dict, dict]] = [] # (pr, event)
|
||||
|
||||
my_login = repo_cfg.get("ignore_actor", "hansheinemann")
|
||||
|
||||
for pr in open_prs:
|
||||
pr_number = pr["number"]
|
||||
fetchers = []
|
||||
@@ -223,6 +250,11 @@ def poll_repo(repo_cfg: dict, state: dict) -> dict:
|
||||
events = fetcher(owner, repo, pr_number)
|
||||
new = new_events_since(events, cursor, seen_ids)
|
||||
for event in new:
|
||||
if event.get("actor") == my_login:
|
||||
log.debug("Skipping own event from %s", my_login)
|
||||
if event.get("id"):
|
||||
seen_ids.add(event["id"])
|
||||
continue
|
||||
all_new_events.append((pr, event))
|
||||
except GHAPIError as e:
|
||||
log.error("[%s] PR #%d fetch error: %s", repo_slug, pr_number, e)
|
||||
@@ -259,9 +291,8 @@ def poll_repo(repo_cfg: dict, state: dict) -> dict:
|
||||
all_new_events.sort(key=lambda x: x[1]["created_at"])
|
||||
|
||||
for pr, event in all_new_events:
|
||||
text = format_notification(repo_slug, pr, event)
|
||||
notify(text)
|
||||
log.info("[%s] Notified: PR #%d %s by %s", repo_slug, pr["number"], event["action"], event["actor"])
|
||||
log.info("[%s] New event: PR #%d %s by %s", repo_slug, pr["number"], event["action"], event["actor"])
|
||||
dispatch_to_main(repo_slug, pr, event)
|
||||
if event.get("id"):
|
||||
seen_ids.add(event["id"])
|
||||
|
||||
|
||||
Reference in New Issue
Block a user