Merge integration/rpa-dashboard-skills into ticket 04

Keeps both sides: frontend detection and bot wiring from tickets 02/03, optional
sections from ticket 04. The a-empty-sections eval now uses the shared "fixture" key.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
VasanthandClaude Opus 5.5 committed 2026-10-16 15:04:34 +05:30
commit 3a11e55b58
29 files changed
+1964 -59

No files matched your search

+41 -16
View File
@@ -11,11 +11,14 @@ source projects.
| 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. It runs the bot as a child process and tails its output. |
| `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.
@@ -24,22 +27,24 @@ 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:** `*.html` files outside `node_modules`, `.venv` and build output; a
`web/`, `frontend/` or `static/` folder; `package.json` with react, vue, angular or
svelte; a PyQt `QWebEngineView`. For any you find, note the location, the stack and
the main colour tokens (CSS custom properties or the Tailwind theme).
- **Frontend:** run `python 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.md` says 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 none of its existing styles.
- Restyle: go to step 3. Change only the theme tokens, never layout or logic.
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
@@ -51,6 +56,8 @@ Skip this if the user chose to keep the existing look. Offer:
## 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.
@@ -81,6 +88,7 @@ to answer.
- 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.md` section 3 says.
2. Fill every `{{...}}` placeholder:
| Placeholder | Value |
@@ -94,10 +102,12 @@ to answer.
3. Apply the theme by replacing the `body{...}` and `body.dark{...}` token blocks
with the preset from `templates/themes.md`. For Ember, also add its font link.
For a custom colour, run `python templates/palette.py "<hex>"`, paste the
tokens it prints, and show the user its contrast table.
4. Desktop: also copy `templates/bridge.py` next to the page, and fill
`{{BOT_MODULE}}`, the `STEPS` list (the same steps as the page), `{{ORG}}` and
`{{APP_NAME}}`.
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.md`
section 4).
4. Desktop: also copy `templates/bridge.py` and `templates/bot_runner.py` next to
the page. Fill `{{ORG}}` and `{{APP_NAME}}` in `bridge.py`, and `{{BOT_MODULE}}` in
`bot_runner.py` (with no bot yet, use the module the bot will have, for example `bot`).
5. Search the output for `{{`. None may be left.
## 7. Wire the data
@@ -108,10 +118,22 @@ both directions.
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 = false` and delete the `SAMPLE DATA` block. Then:
- Desktop: in `bridge.py`, set `BOT_CMD` to start the bot as a child process.
Fill `STEP_MARKERS` and `FRIENDLY_RULES` from lines the bot really prints. Use
specific substrings (for example `[step 3]`, not a bare word); the first match
wins. Unmatched error lines must always reach the log.
- Desktop: all the wiring is in `bot_runner.py`.
1. Get the bot's real output: run it once (for example `python -m bot`), or read
its `print` and logging calls. Never invent lines it doesn't print.
2. Set `BOT_CMD` to start the bot as a child process, and `BOT_CWD` to the folder
it runs from.
3. Set `STEPS_JSON` in the page to the bot's real stages. Fill `STEP_MARKERS` with
`(substring, step label, pct)`: one specific substring per stage (for example
`[step 3]`, never a bare word like `login`), each label exactly one of the
page's STEPS, and pct rising to 100 on the bot's last line. The first match wins.
4. Fill `FRIENDLY_RULES` with `(substring, plain-English message, type)` for the
lines an operator should see. Unmatched lines are hidden, except error lines
(any line with a word from `ERROR_WORDS`), which are always shown as they are.
Add the bot's own failure words to `ERROR_WORDS` if it uses others.
5. 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 as `error` log events.
- Web: the backend serves `GET {API_BASE}/dashboard`, `GET {API_BASE}/run/status`
(returning `{running, events[]}`) and `POST {API_BASE}/<action-with-dashes>`.
- Apply the contract's derived rules: batch state from Pending plus date, and
@@ -119,7 +141,10 @@ both directions.
## 8. Verify
Open the page. On desktop run the host; otherwise open the file or the served URL.
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 tab's steps and log, and the Report tab's