Files
ft/CodexOutput/upserver/playmode_monitor.py

63 lines
2.1 KiB
Python

# PlayMode console monitor: polls UnitySkills console_get_logs every few seconds
# and appends newly (re)appearing entries to a timestamped capture file.
# Used for 2026-09-21 manual acceptance runs (user operates, AI records evidence).
import sys, time, hashlib
sys.path.insert(0, r'C:\Users\LB\.agents\skills\shared-unity-skills\scripts')
import unity_skills
OUT = r'C:\projects\ft\CodexOutput\upserver\playmode-console-2026-09-21.log'
PORT = 8091
POLL_SECONDS = 4
HEARTBEAT_SECONDS = 60
def sig(entry):
raw = str(entry.get('type')) + '|' + entry.get('message', '')
return hashlib.md5(raw.encode('utf-8', errors='ignore')).hexdigest()
def fmt(entry):
ts = time.strftime('%H:%M:%S')
typ = entry.get('type', '?')
msg = entry.get('message', '').replace('\r', ' ').replace('\n', ' | ')[:400]
return f"{ts} [{typ}] {msg}"
def main():
prev = set()
last_beat = 0.0
c = unity_skills.connect(port=PORT)
with open(OUT, 'a', encoding='utf-8') as f:
f.write(f"\n==== monitor start {time.strftime('%Y-%m-%d %H:%M:%S')} port={PORT} ====\n")
while True:
try:
logs = c.call('console_get_logs', count=100)
entries = logs.get('logs', [])
cur = set()
for e in entries:
s = sig(e)
cur.add(s)
if s not in prev:
f.write(fmt(e) + '\n')
prev = cur
except Exception as ex:
# domain reload / server restart window: retry and reconnect
f.write(f"{time.strftime('%H:%M:%S')} [monitor] connection gap: {type(ex).__name__}; reconnecting\n")
try:
c = unity_skills.connect(port=PORT)
except Exception:
pass
time.sleep(3)
continue
now = time.time()
if now - last_beat > HEARTBEAT_SECONDS:
f.write(f"{time.strftime('%H:%M:%S')} [monitor] alive, window={len(entries)}\n")
last_beat = now
f.flush()
time.sleep(POLL_SECONDS)
if __name__ == '__main__':
main()