AI description trimmed to 754 chars (test: both stay <= 1024). Both SKILL.md files say templates/ (and <no-ai>) resolve against the skill's own folder, skills side by side; no-AI commands use <skill>/templates/. AI step 5 names the App.tsx/RunPanel.tsx markers and no longer remembers the model per user. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
9.8 KiB
name, description
| name | description |
|---|---|
| rpa-dashboard-no-ai | Builds a working dashboard page for an RPA bot that does not use AI. It always includes a sidebar and top bar with a dark toggle and status dot, KPI cards, a batch status donut, a run panel with steps and a live log, and a report table with search and Excel export. The page is wired to the bot through one data contract, or runs on sample data when there is no bot yet. Supports a desktop path (PyQt6 with an embedded page) and a web path. Use when the user asks for an "RPA dashboard", "automation dashboard", "bot dashboard", a dashboard "without AI", or a status/run/report page for a bot. For bots that use an LLM or OCR extraction, use rpa-dashboard-ai instead. |
RPA dashboard (no AI)
Everything this skill needs is bundled in templates/. Never read the original
source projects.
Paths: templates/... is in this skill's own folder (the one holding this SKILL.md),
not in the user's project. Below, <skill> is that folder's absolute path: run the
scripts as python <skill>/templates/<script>.py, from the user's project.
| File | What it is |
|---|---|
templates/dashboard.html |
The single-file page: theme tokens, shell, KPI, donut, run panel, report, sample data. Works in PyQt (QWebChannel) or on the web (polling). |
templates/bridge.py |
Minimal PyQt6 host: the window, the bridge slots, and the saved dark-mode choice. |
templates/bot_runner.py |
The bot wiring, without Qt. It runs the bot as a child process, tails its output, and turns lines into step and log events. |
templates/contract.md |
The data contract: events the bot sends, actions the page sends. |
templates/themes.md |
Theme presets (Tebra Sky, Superbill Ember) and the custom-colour steps. |
templates/palette.py |
Derives a custom palette from one brand hex and checks contrast. |
templates/sections.py, templates/sections.md |
Keeps the chosen optional sections in the page and deletes the rest; what each section needs from the host. |
templates/frontend.md |
Existing frontend: detect it, report it, then keep or restyle. Shared with rpa-dashboard-ai. |
templates/detect_frontend.py |
Finds an existing frontend and prints its location, stack and token blocks. |
templates/reference/ |
Raw Tebra extracts, for reference only. The optional sections are already in dashboard.html. |
Follow the steps in order. Ask one question at a time, and wait for the answer. If the user's request already answers a question, don't ask it again.
1. Scan the project
Before asking anything, look at the project:
- Frontend: run
python <skill>/templates/detect_frontend.py <project root>. It finds plain HTML, React/Vue/Angular/Svelte apps and PyQt web views, and prints each one's location, stack and colour tokens.templates/frontend.mdsays what it covers and what to do with its report. - Bot: the entry point (for example
main.py, a__main__module or a run script), what it prints (step markers, status and error lines), and how it starts.
2. Report the frontend, then ask keep or restyle
Follow templates/frontend.md sections 2 to 5. In short:
- No frontend: say "No existing frontend found." and go to step 3. Don't describe a frontend that isn't there.
- Frontend found: say "Frontend found at
<path>, stack<stack>, colours<main tokens>." Then ask: keep its look, or restyle it?- Keep: skip step 3. Build the page with the project's own tokens and fonts, and change no existing file.
- Restyle: go to step 3. In the existing files, change only the token blocks, never layout or logic, and show the user the diff.
3. Ask for colours
Skip this if the user chose to keep the existing look. Offer:
- Tebra Sky: blue glass cards on a sky gradient.
- Superbill Ember: flat surfaces with a red-orange brand gradient.
- Custom: the user gives one brand hex colour.
4. Ask desktop or web
Ask only if there is no frontend. If there is one, use its stack.
Don't ask if the project already uses PyQt (PyQt6 or PyQt5 in its requirements,
pyproject.toml or imports): choose desktop and say so.
- Desktop: a PyQt6 window with the page embedded. The page talks to Python through a bridge, so no web server is needed.
- Web: the same page, served by a backend that it polls.
5. Ask which optional sections to build
Always built: the shell (sidebar, top bar, dark toggle, status dot), KPI cards, the status donut, the run panel and the report table.
Ask which extras to add, as one multi-select question (choose any, or none):
- Checkpoint tracker: numbered boxes in the run panel that show each checkpoint as pending, in progress, done or stuck.
- Admin/roles screen: an Admin tab, for admins only, to give people admin or operator access.
- Login page: a sign-in screen in the dashboard's theme. It's UI only and hands off to the project's own auth.
Build only the chosen ones. In step 6, right after copying the page, run
python <skill>/templates/sections.py <copied dashboard.html> <chosen: checkpoints admin login>.
It deletes the unchosen sections completely (markup, script and style), so nothing
is left behind. Never cut the blocks by hand. Then follow templates/sections.md for
each kept section: what to fill, which events the bot sends, and which host actions
to answer.
6. Build
-
Copy
templates/dashboard.htmlinto the project:- Desktop: put it next to the host, for example
dashboard/dashboard.html. - Web: put it in the backend's static folder. With no backend yet, use
dashboard/dashboard.html. - Existing frontend: put it where
templates/frontend.mdsection 3 says.
Then run
python <skill>/templates/sections.py <copied dashboard.html> <chosen sections>(step 5). - Desktop: put it next to the host, for example
-
Fill every
{{...}}placeholder:Placeholder Value APP_NAME,APP_SUBTITLEThe project's name and a short tagline. LOGO_SRCThe logo's path, or empty if there is none. STEPS_JSONThe run steps as a JSON list, from the bot's real stages, for example ["Initializing","Login","Process items","Completed"].REPORT_COLUMNS_JSON[{"key":..., "label":...}]. It must include a column with keystatus, which shows the bucket pill.API_BASEWeb only, for example /api. Leave it empty for desktop. -
Apply the theme by replacing the
body{...}andbody.dark{...}token blocks with the preset fromtemplates/themes.md. For Ember, also add its font link. For a custom colour, runpython <skill>/templates/palette.py "<hex>", paste the tokens it prints, and show the user its contrast table. If the user chose keep, fill the blocks from the project's tokens instead (templates/frontend.mdsection 4). -
Desktop: also copy
templates/bridge.pyandtemplates/bot_runner.pynext to the page. Fill{{ORG}}and{{APP_NAME}}inbridge.py, and{{BOT_MODULE}}inbot_runner.py(with no bot yet, use the module the bot will have, for examplebot). -
Search the output for
{{. None may be left.
7. Wire the data
The contract is in templates/contract.md: one envelope, {event, data}, in
both directions.
- No bot yet: keep
SAMPLE_DATA = trueand theSAMPLE DATAblock. The page answers its own data actions, so it opens with sample batches and report rows, and Run plays a demo run. Tell the user which events their bot must send later. - Bot exists: set
SAMPLE_DATA = falseand delete theSAMPLE DATAblock. Then:- Desktop: all the wiring is in
bot_runner.py.- Get the bot's real output: run it once (for example
python -m bot), or read itsprintand logging calls. Never invent lines it doesn't print. - Set
BOT_CMDto start the bot as a child process, andBOT_CWDto the folder it runs from. - Set
STEPS_JSONin the page to the bot's real stages. FillSTEP_MARKERSwith(substring, step label, pct): one specific substring per stage (for example[step 3], never a bare word likelogin), each label exactly one of the page's STEPS, and pct rising to 100 on the bot's last line. The first match wins. - Fill
FRIENDLY_RULESwith(substring, plain-English message, type)for the lines an operator should see. Unmatched lines are hidden, except error lines (any line with a word fromERROR_WORDS), which are always shown as they are. Add the bot's own failure words toERROR_WORDSif it uses others. - Dry run without the window:
python dashboard/bot_runner.py. It prints each event the page would get. Check that the steps arrive in order and end at 100, and that the bot's error lines appear aserrorlog events.
- Get the bot's real output: run it once (for example
- Web: the backend serves
GET {API_BASE}/dashboard,GET {API_BASE}/run/status(returning{running, events[]}) andPOST {API_BASE}/<action-with-dashes>. - Apply the contract's derived rules: batch state from Pending plus date, and report buckets from status.
- Desktop: all the wiring is in
8. Verify
Open the page. On desktop run the host (python dashboard/bridge.py), click Run,
and check that the Run button stays disabled until the bot finishes, and that the
dark-mode choice is still set after you close and reopen the window. Otherwise
open the file or the served URL.
With sample data, opening the file in a browser is enough. Check:
- the light theme, the dark theme (use the toggle), and a window 820px wide or less;
- KPI cards, donut and legend, the run panel's steps and log, and the Report tab's rows and pills all show data;
- no
{{placeholders are left and the console shows no script errors.
If Python Playwright is installed, take headless screenshots of each check and look at them. Otherwise, ask the user to open the page. Finish by telling the user where the files are, which theme and sections were built, and whether the page is on sample data or wired to the bot.