feat(header): optional per-server subtitle so several instances can be told apart - #96
Open
maxlamagna wants to merge 1 commit into
Open
feat(header): optional per-server subtitle so several instances can be told apart#96maxlamagna wants to merge 1 commit into
maxlamagna wants to merge 1 commit into
Conversation
…e told apart Running one agentchattr install across several projects, as the per-project isolation section describes, leaves you with identical tabs and identical headers. There is no way to tell which server a tab belongs to. This fills in the #room-subtitle span that already exists in the header but has never had anything put into it. A new "This server" field in Settings sets it, it renders beside the title, and it is appended to the browser tab title as "agentchattr - name". Empty by default, which is today's appearance exactly, so nothing changes for anyone who ignores it. The value is normalised on the way in: internal whitespace is collapsed so a pasted newline cannot break the header across two lines, and it is capped at 40 characters so a long name cannot crowd out the rest of the header. Normalisation also runs on the settings-file read path, because data/settings.json is hand-editable and would otherwise bypass every check the live update path applies. It is rendered with textContent, not innerHTML. This commit also changes an existing rule of yours, and it is easy to drop if you would rather it stayed as it is. The .subtitle rule is 12px, normal weight, in --text-dim, which is #6a6a80 against a dark header. Because nothing ever populated the span, that styling had never actually been rendered, and it is hard to read once there is text in it. This raises it to weight 500 and --text. It stays clearly secondary to the title, which is 16px at weight 600. static/index.html:22 is the only element carrying the class, so nothing else in the UI moves. Tests: 12 new in tests/test_room_name.py, covering normalisation, the cap, the settings-file read path, and the default-empty behaviour. One declared gap: the single line wiring the subtitle into the websocket update_settings handler is not covered. Testing it needs either a live websocket or extracting that inline settings block, and neither belongs in this change. The normalisation it delegates to is covered directly.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The per-project isolation section in the README explains how to run one install as several isolated instances. Once you do, every one of them has the same header and the same tab title, and there is no way to tell which server a tab belongs to.
What this adds
static/index.htmlalready has<span class="subtitle" id="room-subtitle">in the header, and a.subtitlerule instatic/style.css, but nothing has ever put anything into that span. This fills it in.A new This server field in Settings sets the value. It renders beside the title, and it is appended to the browser tab title as
agentchattr - name. Empty by default, which is exactly today's appearance, so nothing changes for anyone who ignores it.Handling of the value
It is rendered with
textContent, neverinnerHTML.Internal whitespace is collapsed, so a pasted newline cannot break the header across two lines, and it is capped at 40 characters so a long name cannot crowd out the rest of the header.
That normalisation also runs on the settings-file read path, not just the live update path.
data/settings.jsonis hand-editable, so a value written straight into the file would otherwise bypass every check.One change to an existing rule of yours, easy to decline
The
.subtitlerule is yours and pre-existing: 12px, normal weight,var(--text-dim), which is#6a6a80against a dark header. Because nothing ever populated the span, that styling has never actually been rendered, and it is hard to read once there is text in it.This raises it to weight 500 and
var(--text). It stays clearly secondary to the title, which is 16px at weight 600.static/index.html:22is the only element carrying the class, so nothing else in the UI moves.If you would rather keep your own styling, drop that one hunk in
static/style.cssand the rest of the PR is unaffected.Tests
12 new in
tests/test_room_name.py, covering normalisation, the 40-character cap, the settings-file read path, and the default-empty behaviour.Full suite on this branch: 93 tests, 0 failures, 1 skipped.
One declared gap: the single line wiring the subtitle into the websocket
update_settingshandler is not covered. Testing it needs either a live websocket or extracting that inline settings block, and neither felt like it belonged in this change. The normalisation that line delegates to is covered directly.README
One paragraph added to the Per-project isolation section, since the setting is currently undocumented.
One thing to know if you merge this second
A companion PR fixes one-shot scheduling. Both PRs bump
style.css?v=andchat.js?v=instatic/index.html, and both bump them to the same values. They merge cleanly, but the second merge then leaves the stamps unchanged from the first, so a browser that loaded after the first merge would keep those assets. Please bump both stamps once more when you take the second of the two.