@brimveyn/aimux 1.14.9 → 1.14.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -57,6 +57,7 @@ import {
|
|
|
57
57
|
} from '../state/layout-tree'
|
|
58
58
|
import { filterAssistants, filterSessions, filterSnippets } from '../state/selectors'
|
|
59
59
|
import { saveSessionCatalog } from '../state/session-catalog'
|
|
60
|
+
import { pruneSnapshotOfWorktree } from '../state/session-persistence'
|
|
60
61
|
import {
|
|
61
62
|
filterTabsForActiveWorktree,
|
|
62
63
|
getActiveWorktree,
|
|
@@ -1524,6 +1525,7 @@ function removeWorktreeRecordFromSession(
|
|
|
1524
1525
|
activeWorktreeId: nextActive?.id,
|
|
1525
1526
|
projectPath: nextActive?.path ?? entry.projectPath,
|
|
1526
1527
|
updatedAt: new Date().toISOString(),
|
|
1528
|
+
workspaceSnapshot: pruneSnapshotOfWorktree(entry.workspaceSnapshot, worktreeId),
|
|
1527
1529
|
worktrees: remaining,
|
|
1528
1530
|
}))
|
|
1529
1531
|
saveSessionCatalog(sessions)
|
|
@@ -394,7 +394,12 @@ export function reduceTabState(state: AppState, action: AppAction): AppState | n
|
|
|
394
394
|
if (state.tabs.length === 0) {
|
|
395
395
|
return state
|
|
396
396
|
}
|
|
397
|
-
const
|
|
397
|
+
const session = getCurrentSession(state)
|
|
398
|
+
const visibleTabs = filterTabsForActiveWorktree(state.tabs, session)
|
|
399
|
+
if (visibleTabs.length === 0) {
|
|
400
|
+
return state
|
|
401
|
+
}
|
|
402
|
+
const orderedTabs = orderTabsByWorktree(visibleTabs, session)
|
|
398
403
|
const currentIndex = orderedTabs.findIndex((tab) => tab.id === state.activeTabId)
|
|
399
404
|
const safeIndex = currentIndex === -1 ? 0 : currentIndex
|
|
400
405
|
const nextIndex = (safeIndex + action.delta + orderedTabs.length) % orderedTabs.length
|
|
@@ -126,6 +126,58 @@ export function restoreLayoutTrees(
|
|
|
126
126
|
return { layoutTrees, tabGroupMap }
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
+
// When a worktree is removed, its tabs are killed live via disposeWorktreeTabs
|
|
130
|
+
// — but the session's persisted workspaceSnapshot still references them by
|
|
131
|
+
// worktreeId. Without this pruning, a subsequent load-session (session switch
|
|
132
|
+
// or restart) resurrects the dead tabs and they reappear in h-l navigation.
|
|
133
|
+
export function pruneSnapshotOfWorktree(
|
|
134
|
+
snapshot: WorkspaceSnapshotV1 | undefined,
|
|
135
|
+
worktreeId: string
|
|
136
|
+
): WorkspaceSnapshotV1 | undefined {
|
|
137
|
+
if (!snapshot) return snapshot
|
|
138
|
+
const keptTabs = snapshot.tabs.filter((tab) => tab.worktreeId !== worktreeId)
|
|
139
|
+
if (keptTabs.length === snapshot.tabs.length) return snapshot
|
|
140
|
+
const validTabIds = new Set(keptTabs.map((tab) => tab.id))
|
|
141
|
+
|
|
142
|
+
let nextLayoutTrees: typeof snapshot.layoutTrees
|
|
143
|
+
let nextTabGroupMap: typeof snapshot.tabGroupMap
|
|
144
|
+
if (snapshot.layoutTrees) {
|
|
145
|
+
const trees: Record<string, LayoutNode> = {}
|
|
146
|
+
const groupMap: Record<string, string> = {}
|
|
147
|
+
for (const [groupId, tree] of Object.entries(snapshot.layoutTrees)) {
|
|
148
|
+
const pruned = pruneLayoutTree(tree, validTabIds)
|
|
149
|
+
if (pruned && pruned.type === 'split') {
|
|
150
|
+
trees[groupId] = pruned
|
|
151
|
+
for (const leafId of allLeafIds(pruned)) {
|
|
152
|
+
groupMap[leafId] = groupId
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
nextLayoutTrees = Object.keys(trees).length > 0 ? trees : undefined
|
|
157
|
+
nextTabGroupMap = Object.keys(groupMap).length > 0 ? groupMap : undefined
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
let nextLayoutTree = snapshot.layoutTree
|
|
161
|
+
if (nextLayoutTree) {
|
|
162
|
+
const pruned = pruneLayoutTree(nextLayoutTree, validTabIds)
|
|
163
|
+
nextLayoutTree = pruned && pruned.type === 'split' ? pruned : undefined
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const nextActiveTabId =
|
|
167
|
+
snapshot.activeTabId != null && validTabIds.has(snapshot.activeTabId)
|
|
168
|
+
? snapshot.activeTabId
|
|
169
|
+
: (keptTabs[0]?.id ?? null)
|
|
170
|
+
|
|
171
|
+
return {
|
|
172
|
+
...snapshot,
|
|
173
|
+
activeTabId: nextActiveTabId,
|
|
174
|
+
layoutTree: nextLayoutTree,
|
|
175
|
+
layoutTrees: nextLayoutTrees,
|
|
176
|
+
tabGroupMap: nextTabGroupMap,
|
|
177
|
+
tabs: keptTabs,
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
129
181
|
export function normalizeGroupedTabOrder(
|
|
130
182
|
tabs: TabSession[],
|
|
131
183
|
layoutTrees: Record<string, LayoutNode>,
|