Skip to content

Commit 1fd49a9

Browse files
committed
release: prepare v0.6.2
1 parent 4d50227 commit 1fd49a9

7 files changed

Lines changed: 47 additions & 14 deletions

File tree

CHANGELOG.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

77
## [Unreleased]
88

9+
## [0.6.2] - 2026-07-04
10+
11+
### Fixed
12+
- Kept long Codex replies pinned to the final metadata row after markdown layout
13+
settles, while still respecting manual scroll-away during active replies.
14+
- Cleared stale screen-reader reply status when starting an empty session.
15+
- Made narrow-window new sessions use the standard chat width, with the sidebar
16+
moving off-canvas earlier so the composer and starter prompts do not collapse
17+
into a thin column.
18+
919
## [0.6.1] - 2026-07-04
1020

1121
### Changed
@@ -266,7 +276,8 @@ First public release.
266276
bundle (Zenodo, doi:10.5281/zenodo.20836918), not this repository.
267277
- FastAPI service, CLI (`switchboard`), and a minimal local web UI.
268278

269-
[Unreleased]: https://github.com/aivinay/switchboard/compare/v0.6.1...HEAD
279+
[Unreleased]: https://github.com/aivinay/switchboard/compare/v0.6.2...HEAD
280+
[0.6.2]: https://github.com/aivinay/switchboard/compare/v0.6.1...v0.6.2
270281
[0.6.1]: https://github.com/aivinay/switchboard/compare/v0.6.0...v0.6.1
271282
[0.6.0]: https://github.com/aivinay/switchboard/compare/v0.5.2...v0.6.0
272283
[0.5.2]: https://github.com/aivinay/switchboard/compare/v0.5.1...v0.5.2

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,11 @@ learned component — is down.
105105
pip install switchboard-local
106106
```
107107

108-
The current release is **0.6.1**. For source installs, run `make install` from
108+
The current release is **0.6.2**. For source installs, run `make install` from
109109
this checkout or install from the git tag:
110110

111111
```bash
112-
pip install "git+https://github.com/aivinay/switchboard@v0.6.1"
112+
pip install "git+https://github.com/aivinay/switchboard@v0.6.2"
113113
```
114114

115115
```bash

RELEASE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ git ls-files | grep -iE 'switchboard.*\.db|^reports/|publication_plan|research_p
3333
## 3. Tag and release
3434

3535
```bash
36-
VERSION=0.6.1
36+
VERSION=0.6.2
3737
git tag -a "v$VERSION" -m "Switchboard $VERSION"
3838
git push origin main "v$VERSION"
3939
```

docs/demo.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ switchboard metrics summary
7171

7272
Current release verification:
7373

74-
- `make check`: ruff, mypy, and the full pytest suite passed for v0.6.1
74+
- `make check`: ruff, mypy, and the full pytest suite passed for v0.6.2
7575
- Mock evals: 64/64 passed
7676
- Fast real smoke evals: 11/11 passed
7777
- Full real smoke evals: 13/13 passed locally in the recorded 90 second run

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "switchboard-local"
3-
version = "0.6.1"
3+
version = "0.6.2"
44
description = "Privacy-aware, local-first router across CLI coding agents (Codex, Claude Code) and local LLMs (Ollama)."
55
readme = "README.md"
66
requires-python = ">=3.11"

switchboard/app/static/app.js

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -484,20 +484,37 @@ function setSrStatus(message) {
484484
}
485485
}
486486

487+
function isNearMessageBottom(threshold = 80) {
488+
return messages.scrollHeight - messages.scrollTop - messages.clientHeight < threshold;
489+
}
490+
487491
function scrollToBottom(force = false) {
488-
const distanceFromBottom =
489-
messages.scrollHeight - messages.scrollTop - messages.clientHeight;
490-
if (!force && distanceFromBottom >= 80) {
492+
if (!force && !isNearMessageBottom()) {
491493
return;
492494
}
493495
messages.scrollTop = messages.scrollHeight;
494496
}
495497

496498
function keepLatestTurnVisible(force = false) {
497499
const schedule = window.requestAnimationFrame || ((callback) => setTimeout(callback, 0));
498-
schedule(() => scrollToBottom(force));
500+
const shouldForce = force || Boolean(activeResponseState?.keepLatestTurnPinned);
501+
schedule(() => {
502+
scrollToBottom(shouldForce);
503+
if (shouldForce) {
504+
schedule(() => scrollToBottom(true));
505+
}
506+
});
499507
}
500508

509+
messages.addEventListener("scroll", () => {
510+
if (!activeResponseState?.keepLatestTurnPinned) {
511+
return;
512+
}
513+
if (!isNearMessageBottom(160)) {
514+
activeResponseState.keepLatestTurnPinned = false;
515+
}
516+
});
517+
501518
function clearWelcome() {
502519
const welcome = messages.querySelector(".welcome-panel");
503520
if (welcome) {
@@ -929,6 +946,7 @@ function schedulePendingAnswerRefresh(forSessionId, attempt = 0) {
929946

930947
async function loadHistory() {
931948
if (!sessionId) {
949+
setSrStatus("");
932950
showWelcomeIfEmpty();
933951
return;
934952
}
@@ -1035,6 +1053,7 @@ function startNewChat() {
10351053
applyPrivateChatState(false, { restoreModel: wasPrivate });
10361054
window.localStorage.removeItem(sessionStorageKey);
10371055
messages.textContent = "";
1056+
setSrStatus("");
10381057
showWelcomeIfEmpty();
10391058
input.focus();
10401059
}
@@ -2895,6 +2914,7 @@ async function sendMessage() {
28952914
statusEl: null,
28962915
currentStatus: initialStatus,
28972916
stopped: false,
2917+
keepLatestTurnPinned: true,
28982918
};
28992919
const controller = new AbortController();
29002920
activeResponseController = controller;
@@ -2973,13 +2993,14 @@ async function sendMessage() {
29732993
}
29742994
finalizeActivityFeed(state);
29752995
if (!state.failed) {
2996+
const shouldKeepLatestTurnVisible = isNearMessageBottom();
29762997
if (state.bodyEl) {
29772998
revealAssistantBody(pending, state);
29782999
state.bodyEl.classList.remove("streaming-cursor");
29793000
await renderFinalMarkdown(state.bodyEl, state.raw);
29803001
}
29813002
pending.appendChild(makeMetaRow(pending, state.displayModel, state.routing));
2982-
scrollToBottom();
3003+
keepLatestTurnVisible(shouldKeepLatestTurnVisible);
29833004
setSrStatus(
29843005
state.displayModel ? `Reply ready from ${state.displayModel}` : "Reply ready"
29853006
);

switchboard/app/static/styles.css

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,7 @@ body.sidebar-collapsed .sidebar-footer {
358358
height: 100dvh;
359359
display: grid;
360360
grid-template-rows: auto auto minmax(0, 1fr) auto;
361+
width: 100%;
361362
max-width: 900px;
362363
margin: 0 auto;
363364
padding: 18px 18px 12px;
@@ -1304,8 +1305,8 @@ button {
13041305
}
13051306

13061307
.welcome-panel {
1307-
align-self: center;
1308-
width: min(680px, 100%);
1308+
align-self: stretch;
1309+
width: 100%;
13091310
display: grid;
13101311
gap: 8px;
13111312
margin: auto 0;
@@ -1565,7 +1566,7 @@ textarea {
15651566
font-size: 15px;
15661567
}
15671568

1568-
@media (max-width: 640px) {
1569+
@media (max-width: 900px) {
15691570
.app-shell {
15701571
grid-template-columns: 1fr;
15711572
}

0 commit comments

Comments
 (0)