Task titles come from one table whose final fallback returns the raw command
string, so a dispatched command with no matching row does not error — it just
renders as "libreportal instance remove bookstack_work" beside properly named
neighbours. That silence is why this kept being fixed and kept coming back.
The guard reads BOTH files as source — the command templates from
task-commands.js and the pattern table from tasks-format.js — so it fails on a
command added without a name rather than leaving it to be noticed in the UI.
Two checks, both from source rather than guessed from rendered text:
1. Nothing falls through: a title equal to its command, or still starting with
"libreportal ", means the raw fallback was reached.
2. Every `libreportal app <verb>` verb has an actionMap entry. Without one the
generic branch composes "<Verb> Application", which is how "Up Application"
and "Down Application" shipped.
The second check reads the actionMap keys instead of pattern-matching the title,
which a first attempt did and which was wrong: "Reload Application" is both a
correct hand-written label and what the generic branch emits, so the rendered
text cannot distinguish them and the heuristic failed a title that was fine.
Verified by breaking it deliberately in both directions — adding a command with
no pattern, and deleting an actionMap verb. Each is caught, named, and pointed at
the file to edit; both files were restored byte-identical afterwards.
Lives in scripts/dev, which .gitattributes marks export-ignore, so it never ships
in a release tarball. Needs a node and borrows the running container's when the
host has none, the same constraint lp-shot works around for chromium.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
58 lines
2.7 KiB
Markdown
58 lines
2.7 KiB
Markdown
# LibrePortal — agent notes
|
|
|
|
## Verify WebUI changes visually before marking them done
|
|
After changing anything user-visible in the WebUI (`containers/libreportal/frontend/`),
|
|
confirm it actually renders correctly — syntax checks and type-correctness don't
|
|
catch layout or visual regressions.
|
|
|
|
The maintainer's dev environment provides a headless screenshot helper, `lp-shot`,
|
|
that captures a WebUI route (or a single element, via a trailing CSS selector) to a
|
|
PNG for review:
|
|
|
|
```
|
|
lp-shot /admin/system # full route -> /tmp/webui-shot.png
|
|
lp-shot /admin/system /tmp/x.png 12 ".sys-strip" # just one element, crisp
|
|
```
|
|
|
|
Use it (and read the PNG) to self-check UI work instead of assuming it looks right or
|
|
asking the user to look. Skip it for purely backend/non-visual edits. If `lp-shot`
|
|
isn't present, fall back to asking the user for a screenshot.
|
|
|
|
Every route except `/` is behind the WebUI login, and `lp-shot` handles that
|
|
itself — it signs a one-hour session from the `jwtSecret` the backend stores in
|
|
`frontend/.auth.json`, the same token `/api/auth/login` would issue. No password
|
|
is involved (the stored one is a bcrypt hash). So no setup: just run it. Override
|
|
with `LP_SHOT_TOKEN`, or `LP_SHOT_USER`+`LP_SHOT_PASS`, when shooting a remote
|
|
instance. `lp-shot --help` lists the rest (`LP_SHOT_URL`, `LP_SHOT_VIEWPORT`,
|
|
`LP_SHOT_SCALE`, …).
|
|
|
|
If a shot comes back as the boot splash, the page wasn't ready — `lp-shot` waits
|
|
for `#libreportal-loading-screen` to leave the DOM, so a splash in the PNG means
|
|
boot genuinely stalled. Read the `page error:` lines it prints to stderr.
|
|
|
|
Testing against the live WebUI means updating the running install, not just the
|
|
repo: `/libreportal-containers/libreportal/frontend/` is bind-mounted into the
|
|
container, so copying changed files there (owned `dockerinstall:dockerinstall`)
|
|
takes effect on the next browser load — no rebuild or restart. Diff before you
|
|
copy; the live tree can hold changes the repo doesn't.
|
|
|
|
## Check task names after adding a dispatched command
|
|
|
|
Task titles all come from one table in `components/tasks/js/tasks-format.js`,
|
|
whose final fallback returns the raw command string. A command added to
|
|
`core/tasks/js/task-commands.js` without a matching row does not error — it just
|
|
renders as `libreportal instance remove bookstack_work` next to properly named
|
|
neighbours like `Bookstack - Create Backup`. That silence is why bad titles kept
|
|
coming back.
|
|
|
|
`lp-task-names` reads both files and fails if any dispatched command has no
|
|
proper name:
|
|
|
|
```
|
|
scripts/dev/lp-task-names # table of every command and its title
|
|
scripts/dev/lp-task-names --quiet # failures only
|
|
```
|
|
|
|
Run it after touching either file. It needs a node and borrows the running
|
|
container's if the host has none.
|