fix: new session poll-until-ready before auto-opening

This commit is contained in:
Brian Krabach
2026-03-30 03:30:16 -07:00
parent 424a4f5377
commit ffa8167c8f
3 changed files with 64 additions and 9 deletions
+30 -6
View File
@@ -1402,8 +1402,10 @@ function showFabSessionInput() {
/**
* Create a new tmux session via POST /api/sessions.
* Shows a toast with the created session name, calls pollSessions() to refresh,
* and if ss.auto_open_created !== false, calls openSession(data.name) after 500ms.
* Shows a toast, then polls _currentSessions until the session name appears
* (or times out after 30s) before calling openSession — this handles commands
* that take time to create the tmux session (e.g. cloning repos, setup scripts).
* If auto_open_created is false in server settings, skips the auto-open.
* @param {string} name - The session name to create.
* @returns {Promise<void>}
*/
@@ -1411,12 +1413,34 @@ async function createNewSession(name) {
try {
const res = await api('POST', '/api/sessions', { name });
const data = await res.json();
showToast('Created: ' + (data.name || name));
await pollSessions();
const sessionName = data.name || name;
showToast('Creating session \'' + sessionName + '\'…');
const ss = _serverSettings || {};
if (ss.auto_open_created !== false) {
setTimeout(() => openSession(data.name || name), 500);
if (ss.auto_open_created === false) {
// Auto-open disabled — just do one refresh
await pollSessions();
return;
}
// Poll until the session appears in _currentSessions (max 30s, every 2s)
var attempts = 0;
var maxAttempts = 15;
var pollForSession = setInterval(async function() {
attempts++;
await pollSessions();
var found = _currentSessions && _currentSessions.find(function(s) {
return s.name === sessionName;
});
if (found) {
clearInterval(pollForSession);
showToast('Session \'' + sessionName + '\' ready');
openSession(sessionName);
} else if (attempts >= maxAttempts) {
clearInterval(pollForSession);
showToast('Session \'' + sessionName + '\' is taking longer than expected');
}
}, 2000);
} catch (err) {
showToast(err.message || 'Failed to create session');
}
+24
View File
@@ -2382,4 +2382,28 @@ test('app.js source uses 500ms debounce for template input and references new_se
assert.ok(source.includes('new_session_template'), 'must reference new_session_template setting key');
});
test('createNewSession polls for session before auto-opening (not immediate setTimeout openSession)', () => {
// The old behavior was: setTimeout(() => openSession(...), 500) immediately after POST.
// The new behavior must use a polling interval to wait for the session to appear in
// _currentSessions before calling openSession — so the immediate pattern must be gone.
const source = fs.readFileSync(
new URL('../app.js', import.meta.url), 'utf8'
);
// Extract the createNewSession function body
const start = source.indexOf('async function createNewSession(');
assert.ok(start !== -1, 'createNewSession function must exist');
// Find the end of the function (next function declaration at same indent level)
const snippet = source.slice(start, start + 2000);
// Must NOT contain the old immediate-open pattern inside createNewSession
assert.ok(
!snippet.includes("setTimeout(() => openSession"),
'createNewSession must not use immediate setTimeout(() => openSession) — should poll instead'
);
// Must contain a polling mechanism (setInterval)
assert.ok(
snippet.includes('setInterval'),
'createNewSession must use setInterval to poll for session readiness'
);
});