Files
Rpa_Skills/skills/rpa-run-tab/SKILL.md
T

142 lines
7.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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 <project>`. Don't ask about them.
## 3. Build
1. Copy `run_tab.html`, `run_tab.py`, `runner.py` and `fake_bot.py` into `<project>/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 <skill>/templates/palette.py <sky|teal|#hex> --write <project>/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_<time>.log`.
- Keep `[UI]` text to progress words and row numbers.
- **Never put** patient or customer names, amounts, account numbers, passwords or other PHI or secrets on screen, or in the failed reasons.
- **Bot output.** Leave the bot's existing prints. They go to the run log.
### 4a. Its own window
There is nothing more to do. Start it with `python run_tab/run_tab.py`.
### 4b. A tab in an existing PyQt page
Copy the four fenced parts of `run_tab.html` into the host page:
- `RUN-TAB:CSS`, `RUN-TAB:TOPBAR`, `RUN-TAB:MARKUP`, `RUN-TAB:JS`
- the `THEME` block, if the host has no tokens of its own
Then wire the host:
- **Page config:** add `const CFG = ...` to the host page; `page_html()` in `run_tab.py` shows its shape.
- **Messages:** route the host's Python→page messages through one `window.__pyMsg`, and merge the `handlePyMessage` branches.
- **Bridge:** give the host's bridge the `Bridge` slots from `run_tab.py`. They are `browse_file`, `process_dropped_path`, `read_sheet`, `download_sample_input`, `start_automation` and `set_dark`.
- **Window:** add the close guard from `RunTabWindow.closeEvent`.
- **Don't connect `js_message` in the page** as well as using `__pyMsg`. Doing both shows every message twice.
## 5. Verify with the fake bot
```
python run_tab/run_tab.py --selfcheck
```
It runs the fake bot through the real runner four times:
- complete → green
- partial → amber
- stuck → red, with box 2 marked stuck
- crash → red
Each line must print `ok`. It then saves the window as `logs/selfcheck_complete_light.png`, `logs/selfcheck_partial_dark.png` and `logs/selfcheck_stuck_light.png`. **Look at all three.** Check:
- the Tebra layout
- your colours, readable in both themes
- the checkpoint names
- no horizontal scroll
**Never press Trigger on the real bot yourself.** Tell the user to start the first real run.
## 6. Hand over (two lines)
Tell the user:
- how to start it (`python run_tab/run_tab.py`)
- where raw run logs go (`logs/`)
If the project ships as a PyInstaller exe:
- the entry point is `run_tab/run_tab.py`
- add `run_tab/run_tab.html` as data
- add the bot module as a hidden import, because the exe starts itself with `--run-bot`