feat(rpg): add day/night ambient lighting, multi-coder NPCs, thought bubbles, XP/level system, CI incident alarm, and interactive Kanban modal
This commit is contained in:
+756
-139
File diff suppressed because it is too large
Load Diff
@@ -25,6 +25,44 @@ class RealtimeRPGHandler(http.server.SimpleHTTPRequestHandler):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, directory=DIRECTORY, **kwargs)
|
||||
|
||||
def do_POST(self):
|
||||
parsed_url = urllib.parse.urlparse(self.path)
|
||||
if parsed_url.path == '/api/issue':
|
||||
content_length = int(self.headers.get('Content-Length', 0))
|
||||
post_data = self.rfile.read(content_length).decode('utf-8')
|
||||
try:
|
||||
payload = json.loads(post_data)
|
||||
project = payload.get('project', 'camper-knowledge-graph')
|
||||
title = payload.get('title', '').strip()
|
||||
body = payload.get('body', 'Erstellt über Agent RPG Terminal').strip()
|
||||
if not title:
|
||||
self.send_response(400)
|
||||
self.end_headers()
|
||||
self.wfile.write(json.dumps({"error": "Title is required"}).encode('utf-8'))
|
||||
return
|
||||
|
||||
req = urllib.request.Request(
|
||||
f"{GITEA_BASE_URL}/repos/openclaw/{project}/issues",
|
||||
data=json.dumps({"title": title, "body": body}).encode('utf-8'),
|
||||
headers={'Authorization': f'token {GITEA_TOKEN}', 'Content-Type': 'application/json'}
|
||||
)
|
||||
with urllib.request.urlopen(req, timeout=3) as resp:
|
||||
resp_data = json.loads(resp.read().decode())
|
||||
self.send_response(201)
|
||||
self.send_header('Content-Type', 'application/json')
|
||||
self.send_header('Access-Control-Allow-Origin', '*')
|
||||
self.end_headers()
|
||||
self.wfile.write(json.dumps({"success": True, "issue": resp_data}).encode('utf-8'))
|
||||
except Exception as e:
|
||||
self.send_response(500)
|
||||
self.send_header('Content-Type', 'application/json')
|
||||
self.send_header('Access-Control-Allow-Origin', '*')
|
||||
self.end_headers()
|
||||
self.wfile.write(json.dumps({"error": str(e)}).encode('utf-8'))
|
||||
else:
|
||||
self.send_response(404)
|
||||
self.end_headers()
|
||||
|
||||
def do_GET(self):
|
||||
parsed_url = urllib.parse.urlparse(self.path)
|
||||
if parsed_url.path == '/api/status':
|
||||
@@ -66,6 +104,11 @@ class RealtimeRPGHandler(http.server.SimpleHTTPRequestHandler):
|
||||
"ci_status": "PASSING",
|
||||
"connected": True
|
||||
},
|
||||
"metrics": {
|
||||
"active_agents": 0,
|
||||
"token_velocity": 0,
|
||||
"system_health": 100
|
||||
},
|
||||
"agents": {
|
||||
"coder1": {
|
||||
"name": f"Coder #{target_project[:4].upper()}",
|
||||
@@ -144,8 +187,9 @@ class RealtimeRPGHandler(http.server.SimpleHTTPRequestHandler):
|
||||
|
||||
# 2. Collect Gitea Live PRs & Issues for Whiteboard Kanban strictly for target_project
|
||||
try:
|
||||
# Check Gitea Actions API for actively running workflows
|
||||
# Check Gitea Actions API for actively running workflows and recent failure
|
||||
active_runs_count = 0
|
||||
latest_run_failed = False
|
||||
try:
|
||||
req_runs = urllib.request.Request(
|
||||
f"{GITEA_BASE_URL}/repos/openclaw/{target_project}/actions/runs?limit=10",
|
||||
@@ -153,14 +197,22 @@ class RealtimeRPGHandler(http.server.SimpleHTTPRequestHandler):
|
||||
)
|
||||
with urllib.request.urlopen(req_runs, timeout=2) as resp:
|
||||
runs_data = json.loads(resp.read().decode())
|
||||
for r in runs_data.get("workflow_runs", []):
|
||||
runs = runs_data.get("workflow_runs", [])
|
||||
for r in runs:
|
||||
if r.get("status") in ["running", "waiting", "queued"]:
|
||||
active_runs_count += 1
|
||||
if runs and runs[0].get("status") == "completed" and runs[0].get("conclusion") in ["failure", "cancelled"]:
|
||||
latest_run_failed = True
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
status["gitea"]["active_ci_jobs"] = active_runs_count
|
||||
status["gitea"]["ci_status"] = "BUILDING" if active_runs_count > 0 else "PASSING"
|
||||
if active_runs_count > 0:
|
||||
status["gitea"]["ci_status"] = "BUILDING"
|
||||
elif latest_run_failed:
|
||||
status["gitea"]["ci_status"] = "FAILURE"
|
||||
else:
|
||||
status["gitea"]["ci_status"] = "PASSING"
|
||||
|
||||
# Fetch Open Pull Requests
|
||||
req_prs = urllib.request.Request(
|
||||
@@ -389,6 +441,14 @@ class RealtimeRPGHandler(http.server.SimpleHTTPRequestHandler):
|
||||
status["agents"]["reviewer"]["lastAction"] = "Idle / Bereit"
|
||||
status["agents"]["reviewer"]["liveLog"] = ["PR Watcher aktiv"]
|
||||
|
||||
status["agents"]["coder_instances"] = coder_sessions
|
||||
|
||||
# Calculate live system metrics
|
||||
active_count = sum(1 for a in status["agents"].values() if isinstance(a, dict) and a.get("state") == "WORKING")
|
||||
status["metrics"]["active_agents"] = active_count
|
||||
status["metrics"]["token_velocity"] = (active_count * 185) + (total_active * 240)
|
||||
status["metrics"]["system_health"] = 90 if status["gitea"]["ci_status"] == "FAILURE" else 100
|
||||
|
||||
return status
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
Reference in New Issue
Block a user