v1.10: booterm container — xterm.js + tmux + node-pty

This commit is contained in:
2026-05-18 14:06:46 +00:00
parent d85b17081e
commit 7486e7d3e0
25 changed files with 1515 additions and 29 deletions

View File

@@ -19,6 +19,14 @@ function chatPane(chatId: string): WorkspacePane {
return { id: generateId(), kind: 'chat', chatId, chatIds: [chatId], activeChatIdx: 0 };
}
// v1.10 booterm: terminal panes carry no chats. Their `id` is used as the
// tmux window key on booterm — see apps/booterm/src/pty/manager.ts. They
// persist in localStorage along with chat panes so a refresh resumes the
// same tmux window via the idempotent start endpoint.
function terminalPane(): WorkspacePane {
return { id: generateId(), kind: 'terminal', chatIds: [], activeChatIdx: -1 };
}
// v1.9: settings pane factory. No chats, no state beyond identity — the
// SettingsPane component renders Session/Project sections from the
// surrounding session/project.
@@ -234,10 +242,6 @@ export function useWorkspacePanes(sessionId: string): UseWorkspacePanesResult {
}, []);
const addSplitPane = useCallback((kind: 'chat' | 'terminal' | 'agent') => {
if (kind === 'terminal') {
toast('Terminal panes coming in BooTerm');
return;
}
if (kind === 'agent') {
toast('Agent panes coming in BooCoder');
return;
@@ -248,7 +252,8 @@ export function useWorkspacePanes(sessionId: string): UseWorkspacePanesResult {
toast.error(`Maximum ${MAX_PANES} panes`);
return prev;
}
const next = [...prev, emptyPane()];
const newPane = kind === 'terminal' ? terminalPane() : emptyPane();
const next = [...prev, newPane];
setActivePaneIdx(next.length - 1);
return next;
});