personal memory agent
1# SPDX-License-Identifier: AGPL-3.0-only
2# Copyright (c) 2026 sol pbc
3
4from __future__ import annotations
5
6from pathlib import Path
7
8REPO_ROOT = Path(__file__).resolve().parents[1]
9APP_CSS_PATH = REPO_ROOT / "solstone" / "convey" / "static" / "app.css"
10
11
12def _class_specificity(selector: str) -> int:
13 return selector.count(".")
14
15
16def _rule_block(css: str, selector: str, start: int = 0) -> tuple[int, str]:
17 index = css.find(f"{selector} {{", start)
18 assert index != -1, f"{selector} rule was not found"
19 close = css.find("}", index)
20 assert close != -1, f"{selector} rule is not closed"
21 return index, css[index : close + 1]
22
23
24def _block_at(css: str, start: int) -> tuple[int, str]:
25 depth = 0
26 for index in range(start, len(css)):
27 char = css[index]
28 if char == "{":
29 depth += 1
30 elif char == "}":
31 depth -= 1
32 if depth == 0:
33 return start, css[start : index + 1]
34 raise AssertionError(f"block at {start} is not closed")
35
36
37def _media_blocks(css: str, query: str = "@media") -> list[tuple[int, str]]:
38 blocks: list[tuple[int, str]] = []
39 start = css.find(query)
40 while start != -1:
41 blocks.append(_block_at(css, start))
42 start = css.find(query, start + len(query))
43 return blocks
44
45
46def _unconditional_app_bar_geometry_rule(css: str) -> tuple[int, str]:
47 media_spans = [
48 (index, index + len(block)) for index, block in _media_blocks(css, "@media")
49 ]
50 start = css.find(".app-bar {")
51 while start != -1:
52 if not any(
53 span_start <= start < span_end for span_start, span_end in media_spans
54 ):
55 rule_index, rule = _rule_block(css, ".app-bar", start)
56 if "left:" in rule and "right:" in rule and "max-width:" in rule:
57 return rule_index, rule
58 start = css.find(".app-bar {", start + len(".app-bar {"))
59 raise AssertionError("unconditional .app-bar geometry rule was not found")
60
61
62def _mobile_app_bar_left_rules(css: str) -> list[tuple[int, str, str, int]]:
63 rules: list[tuple[int, str, str, int]] = []
64 for block_index, block in _media_blocks(css, "@media (max-width: 768px)"):
65 rule_index = block.find(".app-bar {")
66 if rule_index == -1:
67 continue
68 _, rule = _rule_block(block, ".app-bar", rule_index)
69 if "left:" in rule:
70 rules.append((block_index + rule_index, rule, block, rule_index))
71 return rules
72
73
74def test_desktop_app_bar_geometry_remains_unchanged():
75 css = APP_CSS_PATH.read_text(encoding="utf-8")
76 _, base_rule = _unconditional_app_bar_geometry_rule(css)
77
78 assert "left: var(--menu-bar-width-minimal);" in base_rule
79 assert "right: 0;" in base_rule
80 assert "max-width: 1200px;" in base_rule
81
82
83def test_exactly_one_mobile_app_bar_rule_declares_left_with_comment():
84 css = APP_CSS_PATH.read_text(encoding="utf-8")
85 rules = _mobile_app_bar_left_rules(css)
86
87 assert len(rules) == 1
88
89 _absolute_index, rule, block, rule_index = rules[0]
90 comment_index = block.rfind("/*", 0, rule_index)
91 comment_end = block.find("*/", comment_index)
92
93 assert comment_index != -1
94 assert comment_end != -1
95 assert comment_end < rule_index
96 assert comment_index < rule_index
97 assert "left: 8px;" in rule
98 assert "right: 8px;" in rule
99 assert "padding: 10px;" in rule
100 assert "gap: 10px;" in rule
101
102
103def test_later_mobile_app_bar_rule_wins_by_source_order_at_equal_specificity():
104 css = APP_CSS_PATH.read_text(encoding="utf-8")
105 base_selector = ".app-bar"
106 mobile_selector = ".app-bar"
107 base_index, _base_rule = _unconditional_app_bar_geometry_rule(css)
108 rules = _mobile_app_bar_left_rules(css)
109
110 assert len(rules) == 1
111
112 mobile_index, _mobile_rule, _block, _block_rule_index = rules[0]
113
114 assert _class_specificity(base_selector) == _class_specificity(mobile_selector)
115 assert base_index < mobile_index