fix: apply the review items for #712 at merge

- session-ui.js _reloadCasesAfterRun: reload onto the toolbar's own case after every launch, not only one that names its case; comment updated
- test/tab-new-session.test.ts: a worktree tab's "+" Claude launch, the toolbar Run and a group's "New session" each keep the toolbar's case after a "+" moved lastUsedCase (fail without the fix); the reload setup is shared with the existing lastUsedCase test
- docs/architecture-invariants.md:349: the _reloadCasesAfterRun sentence covers every launch
- app.js _openTabLayoutMenu focusout: focus landing on the trigger is not a departure, so pressing the "+" again closes its picker in a real browser
- tab-rail-resize.js openTabRailActionMenu: close the group menu too, so the rail's ... pressed again does not leave the picker beside the row menu
- tab-rail-resize.js:329-331: the "New session here…" comment no longer says Enter on the "+" does nothing

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Codeman maintainer committed 2026-10-27 01:30:07 +01:00
1 parent 4f6481bf7c
commit 04aa44b69c
5 files changed
+73 -26

No files matched your search

+4 -2
View File
@@ -8615,10 +8615,12 @@ class CodemanApp {
// menu's own items are not a departure, and neither is focus going nowhere:
// Safari never focuses a clicked button, so a press on an item blurs the
// focused one with no relatedTarget, and closing then dropped its click
// (the tile count menu's rule, tile-grid.js).
// (the tile count menu's rule, tile-grid.js). Nor is focus landing on the
// trigger: a press on a focusable one (a tab's "+") focuses it before its
// click, and closing there let that click open the menu again.
menu.addEventListener('focusout', (focusEvent) => {
const to = focusEvent.relatedTarget;
if (!to || menu.contains(to)) return;
if (!to || menu.contains(to) || trigger?.contains?.(to)) return;
if (this._tabGroupMenu === menu) this.closeTabGroupMenu();
});
(menu.querySelector('button.selected') || menu.querySelector('button'))?.focus();
+9 -7
View File
@@ -2025,12 +2025,14 @@ Object.assign(CodemanApp.prototype, {
},
/**
* Re-reads the case list after a launch. The no-argument reload re-selects the
* server's `lastUsedCase`, which quick-start has just set to the launched case,
* so a launch in a case it names (a tab's "+") keeps the toolbar on its own.
* Re-reads the case list after a launch, keeping the toolbar on its own case.
* The no-argument reload would re-select the server's `lastUsedCase`, and a
* tab's "+" launching through quick-start sets that to the tab's case while the
* toolbar stays where it was, so every later launch (a worktree's, a plain Run,
* a group's "New session") would otherwise move the toolbar there.
*/
_reloadCasesAfterRun(options) {
this.loadQuickStartCases(options.caseName ? document.getElementById('quickStartCase').value : null);
_reloadCasesAfterRun() {
this.loadQuickStartCases(document.getElementById('quickStartCase').value || null);
},
async runClaude(options = {}) {
@@ -2142,7 +2144,7 @@ Object.assign(CodemanApp.prototype, {
this._appendSessionLaunchStatus(ownsLaunchTerminal, `All ${tabCount} remote session(s) ready`);
if (remoteIds[0]) {
await this.selectSession(remoteIds[0]);
this._reloadCasesAfterRun(options);
this._reloadCasesAfterRun();
}
this.terminal.focus();
return;
@@ -2221,7 +2223,7 @@ Object.assign(CodemanApp.prototype, {
// Auto-switch to the new session using selectSession (does proper refresh)
if (firstSessionId) {
await this.selectSession(firstSessionId);
this._reloadCasesAfterRun(options);
this._reloadCasesAfterRun();
}
this.terminal.focus();
+3 -2
View File
@@ -319,6 +319,7 @@ Object.assign(CodemanApp.prototype, {
event.preventDefault();
event.stopPropagation();
this.closeTabRailActionMenu();
this.closeTabGroupMenu?.();
const trigger = event.currentTarget;
const menu = document.createElement('div');
menu.className = 'tab-rail-action-menu';
@@ -327,8 +328,8 @@ Object.assign(CodemanApp.prototype, {
const settings = this.loadAppSettingsFromStorage();
const actions = [
{ label: 'Session options', run: () => this.openSessionOptions(sessionId) },
// The row's "+" (showTabNewButton on) as a menu item: its keyboard route, since
// Enter on the "+" itself does nothing, and its only route in the compact rail,
// The row's "+" (showTabNewButton on) as a menu item: a keyboard route beside
// Enter or Space on the "+" itself, and its only route in the compact rail,
// which hides it. Session rows only: tiles share this menu and carry no "+".
...(document.documentElement.classList.contains('tabs-show-new') && trigger.closest('.session-tab')
? [{ label: 'New session here…', run: () => this.openTabNewSessionMenu({ currentTarget: trigger }, sessionId) }]