- dashboard.html: each section sits in OPTIONAL:<name> BEGIN/END blocks in the style, markup and script, with sample answers so a page with no bot shows it working. Core change: setUser records the role on <body>, so CSS hides admin-only parts from operators. - templates/sections.py keeps the chosen sections and deletes the rest, markers included; it stops on a broken marker. - templates/sections.md: what each section needs from the host (events, actions, desktop slot snippets, the role re-check, the login hand-off). - SKILL.md step 5 asks one multi-select question and runs sections.py. - Page check: checkpoint states, admin visibility by role and assign/remove, login theme and hand-off to auth or the stub. Cases skip on a generated page without the section; the template must carry all three. The harness signs in when the page has a login screen. - tests/test_sections.py: no sections leave no trace, and that page still passes the page check. - Eval runner: a-empty-sections variant (all three) and per-section checks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
36 lines
1.5 KiB
Python
36 lines
1.5 KiB
Python
"""Keep the optional sections the user chose in dashboard.html, and delete the rest.
|
|
|
|
Usage: python sections.py <dashboard.html> [checkpoints] [admin] [login]
|
|
|
|
Each section sits between marker lines, in HTML, CSS and script:
|
|
<!-- OPTIONAL:admin BEGIN --> /* OPTIONAL:admin BEGIN */ // OPTIONAL:admin BEGIN
|
|
... ... ...
|
|
<!-- OPTIONAL:admin END --> /* OPTIONAL:admin END */ // OPTIONAL:admin END
|
|
Chosen sections lose only their marker lines. Unchosen ones lose everything.
|
|
The file is rewritten in place. Name no sections to remove all of them.
|
|
"""
|
|
import re
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
SECTIONS = ("checkpoints", "admin", "login")
|
|
BLOCK = re.compile(r"^[ \t]*(?:<!--|/\*|//) OPTIONAL:(\w+) BEGIN.*\n((?:.*\n)*?)[ \t]*(?:<!--|/\*|//) OPTIONAL:\1 END.*\n", re.M)
|
|
|
|
|
|
def keep(html, chosen):
|
|
unknown = set(chosen) - set(SECTIONS)
|
|
if unknown:
|
|
sys.exit(f"unknown section(s) {', '.join(sorted(unknown))}; choose from {', '.join(SECTIONS)}")
|
|
html = BLOCK.sub(lambda m: m[2] if m[1] in chosen else "", html)
|
|
if "OPTIONAL:" in html:
|
|
sys.exit("an OPTIONAL marker has no matching BEGIN/END line; fix the template")
|
|
return html
|
|
|
|
|
|
if __name__ == "__main__":
|
|
if len(sys.argv) < 2:
|
|
sys.exit(__doc__)
|
|
page = Path(sys.argv[1])
|
|
page.write_text(keep(page.read_text(encoding="utf-8"), sys.argv[2:]), encoding="utf-8")
|
|
print(f"{page}: kept {', '.join(sys.argv[2:]) or 'no optional sections'}")
|