No-AI desktop path: PyQt bot wired to the page

- templates/bot_runner.py (new, no Qt): runs the bot as a child process
  (unbuffered, UTF-8), tails its output, keeps raw lines in bot_raw.log,
  and turns lines into step/log/status events. Step markers and friendly
  rules use specific substrings, first match wins; unmatched error lines
  are always shown, other unmatched lines hidden. Dry run:
  python dashboard/bot_runner.py prints the events the page would get.
- bridge.py: delegates to bot_runner, one run at a time, restores the
  saved dark mode on every page load (fixes sample-data mode in PyQt),
  adds load_latest_report / download_report slots the page calls.
- SKILL.md: skip the stack question for a PyQt project; desktop wiring
  steps from the bot's real output; verify steps for the host.
- tests: assert-based self-check for the line logic and run loop; Seam 1
  run replay (status dot, Run button, steps, log) and wired-page mode;
  fixture b-pyqt-bot and its Seam 2 eval (all 14 checks pass).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
VasanthandClaude Opus 5.5 committed 2026-10-16 14:28:51 +05:30
1 parent 3eb3fdf00e
commit 162edd41df
17 files changed
+753 -47

No files matched your search

+29
View File
@@ -0,0 +1,29 @@
"""Work-item follow-up bot. Start it with: python -m bot"""
import time
ITEMS = ["WI-1001", "WI-1002", "WI-1003"]
def say(line):
print(line)
time.sleep(0.2)
def main():
say("[step 1] Initializing")
say("Loading settings from config.ini")
say("Completed loading 3 work items")
say("[step 2] Logging in to the portal")
say("Login page loaded")
say("[login] ok")
say("[step 3] Processing work items")
for i, item in enumerate(ITEMS, 1):
say(f"[item] {item} updated ({i}/{len(ITEMS)})")
say("WARNING: portal slow to respond, waited 5s")
say("ERROR: could not attach the note to WI-1003")
say("[step 4] Writing the summary")
say(f"[all done] {len(ITEMS)} items processed")
if __name__ == "__main__":
main()