Merge PR #68 [aidan] bug: ui/ux fixes (back/forward disabled-state, browser-card dashboard scoping + resize, selection-overlay clipping, dashboard-duplicate carries chats)

AppShell conflict resolved: kept the lucide/redesign + folded in the back/forward disabled-state logic.
This commit is contained in:
ciregenz
2026-06-11 02:59:30 -07:00
12 changed files with 311 additions and 63 deletions
@@ -59,6 +59,8 @@ export interface BrowserCardPosition {
zOrder: number;
/** Agent session that spawned this browser; auto-removed when its owner reaches terminal state. */
spawned_by?: string | null;
/** Dashboard this card belongs to; cards render and persist only on their owning dashboard. */
dashboard_id?: string;
}
export type NoteColor = 'yellow' | 'pink' | 'blue' | 'green' | 'purple' | 'gray';
@@ -975,10 +977,14 @@ const dashboardLayoutSlice = createSlice({
// browsers spawn). The caller says which; never inferred from state.
const isReconnectRefetch = action.meta.arg.isReconnect === true;
state.initialized = true;
const ownerDashboardId = action.meta.arg.dashboardId;
if (!isReconnectRefetch) {
state.cards = action.payload.cards;
state.viewCards = action.payload.viewCards;
state.browserCards = action.payload.browserCards;
for (const card of Object.values(state.browserCards)) {
card.dashboard_id = ownerDashboardId;
}
state.notes = action.payload.notes || {};
// Cards boot parked (no guest process, title placeholder); the suspend
// hook wakes viewport-sized and agent-driven ones on its first pass.
@@ -992,6 +998,9 @@ const dashboardLayoutSlice = createSlice({
addMissingCards(state.cards, action.payload.cards, occupied);
addMissingCards(state.viewCards, action.payload.viewCards, occupied);
addMissingCards(state.browserCards, action.payload.browserCards, occupied);
for (const card of Object.values(state.browserCards)) {
if (!card.dashboard_id) card.dashboard_id = ownerDashboardId;
}
addMissingCards(state.notes, action.payload.notes || {}, occupied);
}
state.persistedExpandedSessionIds = action.payload.expandedSessionIds;
+8 -1
View File
@@ -736,7 +736,14 @@ class WebSocketManager {
case 'dashboard:browser_card_added':
if (data.browser_card) {
store.dispatch(addBrowserCardFromBackend(data.browser_card));
// Tag with origin dashboard so the card renders only on the dashboard
// that spawned it , without this, a browser spawned by an agent on
// dashboard A leaks into whatever dashboard the user is currently
// viewing (the global browserCards dict + unfiltered render).
store.dispatch(addBrowserCardFromBackend({
...data.browser_card,
dashboard_id: data.dashboard_id,
}));
const parentId = data.parent_session_id;
if (parentId) {
const layoutState = store.getState().dashboardLayout;