Compare commits
1 Commits
burn/1453-
...
fix/issue-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
169b2c119b |
@@ -29,7 +29,7 @@ from typing import Any, Callable, Optional
|
||||
|
||||
import websockets
|
||||
|
||||
from bannerlord_trace import BannerlordTraceLogger
|
||||
from nexus.bannerlord_trace import BannerlordTraceLogger
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# CONFIGURATION
|
||||
|
||||
@@ -49,6 +49,62 @@ def strip_ansi(text: str) -> str:
|
||||
return ANSI_RE.sub("", text or "")
|
||||
|
||||
|
||||
def clean_lines(text: str) -> list[str]:
|
||||
"""Clean ANSI codes and split text into non-empty lines."""
|
||||
text = strip_ansi(text).replace("\r", "")
|
||||
return [line.strip() for line in text.split("\n") if line.strip()]
|
||||
|
||||
|
||||
def parse_room_output(text: str) -> dict | None:
|
||||
"""Parse Evennia room output into structured data."""
|
||||
lines = clean_lines(text)
|
||||
if len(lines) < 2:
|
||||
return None
|
||||
title = lines[0]
|
||||
desc = lines[1]
|
||||
exits = []
|
||||
objects = []
|
||||
for line in lines[2:]:
|
||||
if line.startswith("Exits:"):
|
||||
raw = line.split(":", 1)[1].strip().replace(" and ", ", ")
|
||||
exits = [{"key": t.strip(), "destination_id": t.strip().title(), "destination_key": t.strip().title()} for t in raw.split(",") if t.strip()]
|
||||
elif line.startswith("You see:"):
|
||||
raw = line.split(":", 1)[1].strip().replace(" and ", ", ")
|
||||
parts = [t.strip() for t in raw.split(",") if t.strip()]
|
||||
objects = [{"id": p.removeprefix("a ").removeprefix("an "), "key": p.removeprefix("a ").removeprefix("an "), "short_desc": p} for p in parts]
|
||||
return {"title": title, "desc": desc, "exits": exits, "objects": objects}
|
||||
|
||||
|
||||
def normalize_event(raw: dict, hermes_session_id: str) -> list[dict]:
|
||||
"""Normalize raw Evennia event into Nexus event format."""
|
||||
from nexus.evennia_event_adapter import (
|
||||
actor_located, command_issued, command_result,
|
||||
room_snapshot, session_bound,
|
||||
)
|
||||
|
||||
out = []
|
||||
event = raw.get("event")
|
||||
actor = raw.get("actor", "Timmy")
|
||||
timestamp = raw.get("timestamp")
|
||||
if event == "connect":
|
||||
out.append(session_bound(hermes_session_id, evennia_account=actor, evennia_character=actor, timestamp=timestamp))
|
||||
parsed = parse_room_output(raw.get("output", ""))
|
||||
if parsed:
|
||||
out.append(actor_located(actor, parsed["title"], parsed["title"], timestamp=timestamp))
|
||||
out.append(room_snapshot(parsed["title"], parsed["title"], parsed["desc"], exits=parsed["exits"], objects=parsed["objects"], timestamp=timestamp))
|
||||
elif event == "command":
|
||||
cmd = raw.get("command", "")
|
||||
output = raw.get("output", "")
|
||||
out.append(command_issued(hermes_session_id, actor, cmd, timestamp=timestamp))
|
||||
success = not output.startswith("Command '") and not output.startswith("Could not find")
|
||||
out.append(command_result(hermes_session_id, actor, cmd, strip_ansi(output), success=success, timestamp=timestamp))
|
||||
parsed = parse_room_output(output)
|
||||
if parsed:
|
||||
out.append(actor_located(actor, parsed["title"], parsed["title"], timestamp=timestamp))
|
||||
out.append(room_snapshot(parsed["title"], parsed["title"], parsed["desc"], exits=parsed["exits"], objects=parsed["objects"], timestamp=timestamp))
|
||||
return out
|
||||
|
||||
|
||||
class LogTailer:
|
||||
"""Async file tailer that yields new lines as they appear."""
|
||||
|
||||
@@ -183,56 +239,6 @@ async def live_bridge(log_dir: str, ws_url: str, reconnect_delay: float = 5.0):
|
||||
|
||||
async def playback(log_path: Path, ws_url: str):
|
||||
"""Legacy mode: replay a telemetry JSONL file."""
|
||||
from nexus.evennia_event_adapter import (
|
||||
actor_located, command_issued, command_result,
|
||||
room_snapshot, session_bound,
|
||||
)
|
||||
|
||||
def clean_lines(text: str) -> list[str]:
|
||||
text = strip_ansi(text).replace("\r", "")
|
||||
return [line.strip() for line in text.split("\n") if line.strip()]
|
||||
|
||||
def parse_room_output(text: str):
|
||||
lines = clean_lines(text)
|
||||
if len(lines) < 2:
|
||||
return None
|
||||
title = lines[0]
|
||||
desc = lines[1]
|
||||
exits = []
|
||||
objects = []
|
||||
for line in lines[2:]:
|
||||
if line.startswith("Exits:"):
|
||||
raw = line.split(":", 1)[1].strip().replace(" and ", ", ")
|
||||
exits = [{"key": t.strip(), "destination_id": t.strip().title(), "destination_key": t.strip().title()} for t in raw.split(",") if t.strip()]
|
||||
elif line.startswith("You see:"):
|
||||
raw = line.split(":", 1)[1].strip().replace(" and ", ", ")
|
||||
parts = [t.strip() for t in raw.split(",") if t.strip()]
|
||||
objects = [{"id": p.removeprefix("a ").removeprefix("an "), "key": p.removeprefix("a ").removeprefix("an "), "short_desc": p} for p in parts]
|
||||
return {"title": title, "desc": desc, "exits": exits, "objects": objects}
|
||||
|
||||
def normalize_event(raw: dict, hermes_session_id: str) -> list[dict]:
|
||||
out = []
|
||||
event = raw.get("event")
|
||||
actor = raw.get("actor", "Timmy")
|
||||
timestamp = raw.get("timestamp")
|
||||
if event == "connect":
|
||||
out.append(session_bound(hermes_session_id, evennia_account=actor, evennia_character=actor, timestamp=timestamp))
|
||||
parsed = parse_room_output(raw.get("output", ""))
|
||||
if parsed:
|
||||
out.append(actor_located(actor, parsed["title"], parsed["title"], timestamp=timestamp))
|
||||
out.append(room_snapshot(parsed["title"], parsed["title"], parsed["desc"], exits=parsed["exits"], objects=parsed["objects"], timestamp=timestamp))
|
||||
elif event == "command":
|
||||
cmd = raw.get("command", "")
|
||||
output = raw.get("output", "")
|
||||
out.append(command_issued(hermes_session_id, actor, cmd, timestamp=timestamp))
|
||||
success = not output.startswith("Command '") and not output.startswith("Could not find")
|
||||
out.append(command_result(hermes_session_id, actor, cmd, strip_ansi(output), success=success, timestamp=timestamp))
|
||||
parsed = parse_room_output(output)
|
||||
if parsed:
|
||||
out.append(actor_located(actor, parsed["title"], parsed["title"], timestamp=timestamp))
|
||||
out.append(room_snapshot(parsed["title"], parsed["title"], parsed["desc"], exits=parsed["exits"], objects=parsed["objects"], timestamp=timestamp))
|
||||
return out
|
||||
|
||||
hermes_session_id = log_path.stem
|
||||
async with websockets.connect(ws_url) as ws:
|
||||
for line in log_path.read_text(encoding="utf-8").splitlines():
|
||||
|
||||
@@ -35,7 +35,7 @@ for arg in "$@"; do
|
||||
done
|
||||
|
||||
API="$GITEA_URL/api/v1"
|
||||
AUTH="Authorization: token $GITEA_TOKEN"
|
||||
AUTH="token $GITEA_TOKEN"
|
||||
|
||||
log() { echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] $*"; }
|
||||
|
||||
@@ -148,51 +148,6 @@ if [ "$DUPLICATES_FOUND" -eq 0 ]; then
|
||||
log "No duplicate PRs found"
|
||||
fi
|
||||
|
||||
# ─── Additional cleanup: Stale branches from closed/merged PRs ───
|
||||
log "Checking for stale branches from closed/merged PRs..."
|
||||
|
||||
ALL_PRS=$(curl -s -H "$AUTH" "$API/repos/$REPO/pulls?state=closed&limit=100")
|
||||
STALE_BRANCHES_DELETED=0
|
||||
|
||||
if [ -n "$ALL_PRS" ] && [ "$ALL_PRS" != "null" ]; then
|
||||
echo "$ALL_PRS" | jq -r '.[] | select(.merged == false) | "\(.number)\t(.head.ref)\t\(.state)"' | while IFS=$'\t' read -r pr_num pr_branch pr_state; do
|
||||
[ -z "$pr_branch" ] && continue
|
||||
# Skip if branch doesn't exist
|
||||
branch_check=$(curl -s -o /dev/null -w "%{http_code}" -H "$AUTH" "$API/repos/$REPO/branches/$pr_branch")
|
||||
if [ "$branch_check" != "200" ]; then
|
||||
continue
|
||||
fi
|
||||
log "Stale branch from closed PR #$pr_num: $pr_branch"
|
||||
if [ "$DRY_RUN" = "true" ]; then
|
||||
log "DRY RUN: Would delete branch $pr_branch"
|
||||
else
|
||||
curl -s -X DELETE -H "$AUTH" "$API/repos/$REPO/branches/$pr_branch" > /dev/null
|
||||
log "Deleted branch $pr_branch"
|
||||
STALE_BRANCHES_DELETED=$((STALE_BRANCHES_DELETED + 1))
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# ─── Additional cleanup: Stale branches from merged PRs ───
|
||||
log "Checking for stale branches from merged PRs..."
|
||||
|
||||
if [ -n "$ALL_PRS" ] && [ "$ALL_PRS" != "null" ]; then
|
||||
echo "$ALL_PRS" | jq -r '.[] | select(.merged == true) | "\(.number)\t\(.head.ref)"' | while IFS=$'\t' read -r pr_num pr_branch; do
|
||||
[ -z "$pr_branch" ] && continue
|
||||
branch_check=$(curl -s -o /dev/null -w "%{http_code}" -H "$AUTH" "$API/repos/$REPO/branches/$pr_branch")
|
||||
if [ "$branch_check" != "200" ]; then
|
||||
continue
|
||||
fi
|
||||
log "Stale branch from merged PR #$pr_num: $pr_branch"
|
||||
if [ "$DRY_RUN" = "true" ]; then
|
||||
log "DRY RUN: Would delete branch $pr_branch"
|
||||
else
|
||||
curl -s -X DELETE -H "$AUTH" "$API/repos/$REPO/branches/$pr_branch" > /dev/null
|
||||
log "Deleted branch $pr_branch"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# ─── Additional cleanup: Stale PRs ────────────────────────
|
||||
# Check for PRs older than 30 days with no activity
|
||||
log "Checking for stale PRs (older than 30 days)..."
|
||||
|
||||
Reference in New Issue
Block a user