From a57b32e8cb9096993a942e49ce6070572b76818b Mon Sep 17 00:00:00 2001 From: Vasanth Date: Fri, 16 Oct 2026 16:30:59 +0530 Subject: [PATCH] Add rpa-run-tab skill A Tebra-style Run tab for desktop PyQt6 bots, built in about 5 minutes: Trigger button, Excel input card, progress with timer, live log, checkpoint boxes with time limits, and green/amber/red endings. It is checked with a fake bot (run_tab.py --selfcheck). The design decisions are in rpa-run-tab/docs/adr. Co-Authored-By: Claude Opus 5.5 --- .gitignore | 3 + README.md | 7 + rpa-run-tab/SKILL.md | 141 +++++ ...0001-one-checkpoint-list-drives-run-tab.md | 11 + .../0002-bot-talks-through-tagged-log-file.md | 11 + .../0003-stuck-kills-no-restart-no-stop.md | 7 + rpa-run-tab/templates/fake_bot.py | 31 + rpa-run-tab/templates/palette.py | 99 +++ rpa-run-tab/templates/rt.py | 36 ++ rpa-run-tab/templates/run_tab.html | 592 ++++++++++++++++++ rpa-run-tab/templates/run_tab.py | 345 ++++++++++ rpa-run-tab/templates/runner.py | 152 +++++ 12 files changed, 1435 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 rpa-run-tab/SKILL.md create mode 100644 rpa-run-tab/docs/adr/0001-one-checkpoint-list-drives-run-tab.md create mode 100644 rpa-run-tab/docs/adr/0002-bot-talks-through-tagged-log-file.md create mode 100644 rpa-run-tab/docs/adr/0003-stuck-kills-no-restart-no-stop.md create mode 100644 rpa-run-tab/templates/fake_bot.py create mode 100644 rpa-run-tab/templates/palette.py create mode 100644 rpa-run-tab/templates/rt.py create mode 100644 rpa-run-tab/templates/run_tab.html create mode 100644 rpa-run-tab/templates/run_tab.py create mode 100644 rpa-run-tab/templates/runner.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..422d68d --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +rpa-run-tab/logs/ +__pycache__/ +*.pyc diff --git a/README.md b/README.md new file mode 100644 index 0000000..4b7b5dd --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# RPA Skills + +Claude skills for RPA projects. Each folder is one skill: copy it into `~/.claude/skills/` to install it. + +| Skill | What it does | +|---|---| +| [`rpa-run-tab`](rpa-run-tab/SKILL.md) | Adds a Tebra-style Run tab (Trigger button, Excel input, progress, live log, checkpoints) to a desktop PyQt6 bot in about 5 minutes. | diff --git a/rpa-run-tab/SKILL.md b/rpa-run-tab/SKILL.md new file mode 100644 index 0000000..5220f0b --- /dev/null +++ b/rpa-run-tab/SKILL.md @@ -0,0 +1,141 @@ +--- +name: rpa-run-tab +description: Adds a Tebra-style Run tab to a desktop RPA bot in about 5 minutes. The Run tab is a PyQt6 window (or a tab in an existing PyQt web page) with a Trigger button, an Excel input card (drop zone, sheet tabs, preview with masked passwords, sample download), a progress bar with a timer, a step list, a friendly live log, checkpoint boxes with time limits, and green/amber/red endings. It also wires the real bot to the page. Use when the user asks for a "Run tab", "run screen", "trigger screen", "start/run page for my bot", or "the Tebra run tab" for an RPA or automation project. For a whole dashboard (KPIs, report table), use rpa-dashboard-no-ai. +--- + +# RPA Run tab + +Build the Run tab, wire the real bot to it and check it with the fake bot. The whole job should take about 5 minutes. +The look is fixed. It is Tebra Auto Post's Run tab, and only the colours change. +Everything needed is in `templates/`. Never read the original Tebra projects. + +| File | What it is | +|---|---| +| `templates/run_tab.html` | The page. Its config comes from `run_tab.py`, and its theme is between `THEME:START` and `THEME:END`. Each part is fenced with `RUN-TAB:CSS`, `TOPBAR`, `MARKUP` and `JS` markers. | +| `templates/run_tab.py` | The PyQt6 window and bridge. It is also the bot's process (`--run-bot`, which loads no Qt). It holds the **CONFIG** block you fill in and `--selfcheck`. | +| `templates/runner.py` | Qt-free. It starts the bot, reads its log file every 0.2 s, turns lines into events, kills stuck runs and decides the ending. | +| `templates/rt.py` | The protocol helpers the bot calls: `checkpoint`, `checkpoint_done`, `ui`, `result`, `summary`. | +| `templates/fake_bot.py` | Prints the protocol for the endings complete, partial, stuck and crash. Used only by the self-check. | +| `templates/palette.py` | Theme: `sky`, `teal` or a brand hex. Use `--write` to put it into the page. It checks contrast. | + +The rules come from the ADRs in `docs/adr/`. Keep to them: +- One checkpoint list drives the steps, the boxes and the progress %. +- The bot talks only through tagged lines in a log file. +- A stuck checkpoint kills the run, and the run fails. +- There is no auto-restart and no Stop or Pause button. +- There is no database, no resume and no roles. + +## 1. Scan (about 1 minute, ask nothing yet) + +**Never run the bot.** Real bots act on live systems. + +1. **Bot entry point.** + - Look for a `main(...)` function, an `if __name__ == "__main__"` script, or a `run_*` function. + - Note its loop over input rows or items. Those become the summary's `total` and `failed`. + - Note its big stages, such as sign in, open a page, process rows, export. Those become the checkpoints. +2. **Input.** + - Does the bot read an Excel file (`openpyxl`, `pandas.read_excel`, `xlrd`)? + - If yes, note the sheet names and column names it reads, for `SAMPLE_SHEETS`. + - No Excel file means `HAS_INPUT = False`. +3. **Host.** Search for `QWebEngineView`, `setHtml` or a `.html` page loaded by PyQt, or an `rpa-dashboard-no-ai` `dashboard.html`. If you find one, the Run tab becomes a tab in it (step 4b). Otherwise it gets its own window (step 4a). +4. **Processes.** Note any extra programs the bot starts and that must die with it, such as `chromedriver.exe` or a desktop app. These go in `KILL_ALSO`. + +## 2. Ask once (one message, at most 3 questions) + +Send the scan result and these questions in one message, then wait: +1. **Colour:** + - 1) Tebra Sky (blue) + - 2) TVL Teal (green) + - 3) Custom: send one brand hex +2. **Checkpoints:** propose 3–8, each with a name of 2–3 plain words and a time limit, for example `Sign in, max 5 min`. Use `no limit` for long loops over rows. The user confirms or edits the list. +3. **Input:** "Excel input, or no input file?" Skip this question when the scan already answered it. + +Default the title and subtitle from the project name, for example `Run automation` and `Upload the input Excel and start `. Don't ask about them. + +## 3. Build + +1. Copy `run_tab.html`, `run_tab.py`, `runner.py` and `fake_bot.py` into `/run_tab/`. +2. Copy `rt.py` there and next to the bot's entry file. +3. Fill the **CONFIG** block at the top of `run_tab/run_tab.py`: + - `TITLE`, `SUBTITLE` + - `BOT`: `"bot.py"` relative to the project root, or `"package.module:function"` + - `HAS_INPUT`, `INPUT_HINT` + - `CHECKPOINTS` + - `SAMPLE_SHEETS` + - `KILL_ALSO` + - `APP_ID`: the project name, no spaces +4. Apply the theme: `python /templates/palette.py --write /run_tab/run_tab.html`. + - It must print PASS for every row. + - If a row fails, tell the user and suggest a darker hex. +5. Make sure `openpyxl`, `PyQt6` and `PyQt6-WebEngine` are in the project's requirements. + +## 4. Wire the bot + +Keep the bot's logic as it is. Only add these lines: + +```python +import rt + +def main(excel_path): # BOT = "bot:main"; the Run tab passes the Excel path + rt.checkpoint(1); rt.ui("Signing in"); ...; rt.ui("Signed in", "ok"); rt.checkpoint_done(1) + failed = [] + rt.checkpoint(2) + for i, row in enumerate(rows, start=2): + try: process(row) + except Exception as e: failed.append((f"Row {i}", str(e))); rt.ui(f"Row {i} failed", "warn") + rt.checkpoint_done(2) + return rt.result(total=len(rows), failed=failed) +``` + +- **Checkpoint numbers** are 1-based positions in `CHECKPOINTS`. A loop may go back to an earlier checkpoint for the next item; the later boxes reset and the bar never moves back. +- **Returning a summary.** A plain script with no entry function prints `rt.summary(total, failed)` as its last line instead. If no summary arrives, the run counts as **failed**. +- **What the operator sees.** Only `[UI]` lines and error lines reach the screen. Everything else goes only to `logs/run_