Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions scripts/board.py
Original file line number Diff line number Diff line change
Expand Up @@ -568,21 +568,34 @@ def _repo_url(snapshot: dict) -> str:


# The one-tap board family — the cross-board footer nav every board carries,
# each board skipping its own entry. Owner comes from the snapshot.
# each board skipping its own entry.
#
# Membership and order are NOT decided here: they live once, in the Brain's
# `config/policy.yaml` `board: boards:`, and `_theme.board_links` is the read.
# This file used to keep its own tuple, written before the Cortex had a board
# — so this footer was short a chip and out of the family's order, and nothing
# noticed. The tuple below survives only as the fallback for an older
# PyAutoBrain checkout whose theme predates the helper; it is deliberately the
# old list, because a fallback that guessed at the current one would drift the
# same way. Owner still comes from the snapshot.
BOARD_FAMILY = (("mind", "PyAutoMind"), ("brain", "PyAutoBrain"),
("heart", "PyAutoHeart"), ("hands", "PyAutoHands"),
("organism", "PyAutoScientist"))


def _boards_nav(snapshot: dict) -> str:
"""The cross-board footer — one chip per sibling, each in its own organ's
colour (the theme owns the chip palette; this board owns the URLs)."""
colour (the theme owns the chip palette AND the family's membership; this
board owns only its owner and which page it is)."""
owner = str(snapshot.get("owner") or "").lower()
if not owner:
return ""
links = {key: f"https://{owner}.github.io/{repo}/"
for key, repo in BOARD_FAMILY}
return theme().boards_footer(links, BOARD_KEY)
t_ = theme()
base = f"https://{owner}.github.io"
links = getattr(t_, "board_links", None)
links = (links(base, BOARD_KEY) if links else
{key: f"{base}/{repo}/" for key, repo in BOARD_FAMILY})
return t_.boards_footer(links, BOARD_KEY)


def _read_prompt(snapshot: dict, section: str) -> str:
Expand Down
52 changes: 52 additions & 0 deletions tests/test_board.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,58 @@ def test_live_repo_statuses_are_schema_valid():
assert seen <= {"stub", "drafted", "reviewed"}, f"schema-invalid statuses: {seen}"


# The canonical board family, in the order `PyAutoBrain/config/policy.yaml`
# declares it. This board is `memory`, so its own chip never appears.
FAMILY_WITHOUT_MEMORY = ["brain", "mind", "cortex", "heart", "hands", "organism"]


def _footer(tmp_path) -> str:
# The synthetic tree has no git remote, so `collect` finds no owner and
# the footer (rightly) renders empty. Name a fake one — this file carries
# no instance facts.
snap = board.collect(_tree(tmp_path))
snap["owner"] = "SomeOrg"
html = board.render(snap, "html")
return re.search(r'<ul class="boards">.*?</ul>', html, re.S).group(0)


def test_the_family_footer_carries_the_cortex_in_the_canonical_order(tmp_path):
"""The footer's membership is the Brain's config, not a tuple in here.

It used to be a tuple in here — written before the Cortex had a board —
so this page linked five siblings in an ad-hoc order and silently missed
the sixth. Reading `_theme.board_links` means adding a board to
`config/policy.yaml` lights it in every footer at once.
"""
footer = _footer(tmp_path)
assert re.findall(r'data-organ="(\w+)"', footer) == FAMILY_WITHOUT_MEMORY
assert "https://someorg.github.io/PyAutoCortex/" in footer


def test_the_footer_never_links_the_page_it_is_on(tmp_path):
footer = _footer(tmp_path)
assert f'data-organ="{board.BOARD_KEY}"' not in footer


def test_the_footer_falls_back_when_the_brain_checkout_predates_the_helper():
"""An older PyAutoBrain beside this repo has no `board_links`. The page
must still render its footer — from the legacy tuple — rather than lose
the whole board over a nav strip."""
class _Older:
def __init__(self, real):
self.boards_footer = real.boards_footer

real = board.theme()
saved = board._boards_nav.__globals__["theme"]
board._boards_nav.__globals__["theme"] = lambda: _Older(real)
try:
footer = board._boards_nav({"owner": "SomeOrg"})
finally:
board._boards_nav.__globals__["theme"] = saved
assert re.findall(r'data-organ="(\w+)"', footer) == [
k for k, _ in board.BOARD_FAMILY]


def test_html_wears_the_shared_family_theme(tmp_path):
# The look is the Brain's `board/_theme.py`, not a stylesheet copied in
# here: the page must carry this board's hero (mark, wordmark, tagline)
Expand Down
Loading