Phase E.2b — create a tab inside a workspace. Validates the
parent exists; otherwise emits Event::Error (non-fatal). On
success: assigns a UUID, appends to the workspace’s tab_ids,
inserts into state.tabs, emits Event::TabCreated. If the
workspace had no active tab, the new tab also becomes active
and an Event::ActiveTabChanged is emitted alongside.
Phase E.2b — delete a tab from a workspace. Idempotent: deleting
a missing tab is a silent no-op. If the deleted tab was the
active tab, the workspace’s active tab becomes the next tab in
tab_ids (or the previous one if the deleted was last; or None
if the workspace is now empty), and an Event::ActiveTabChanged
is emitted alongside Event::TabDeleted.
Phase E.5.5 — move a tab from src_workspace_id to
dst_workspace_id, inserting at dst_index (clamped to dst’s
length). Updates the tab’s workspace_id, removes it from src’s
tab_ids, inserts into dst’s tab_ids. If the tab was src’s
active_tab_id, src’s active reverts to its first remaining
tab (or None when empty).
Phase E.2c.3b — reorder a tab within its workspace’s
tab_ids. new_index is clamped to tab_ids.len(). No-op
if the tab is already at that position. Errors (non-fatal) if
the workspace doesn’t exist or the tab isn’t in its tab list.
Phase E.5.3 — replace a workspace’s tab_ids with the given
list. Validates the workspace exists and the new list is a
permutation of the current set (same elements, possibly
different order). No-op if identical.
Phase E.2b — set a workspace’s active tab. No-op if already
active. Errors (non-fatal) if the workspace doesn’t exist or the
tab isn’t in that workspace’s tab list.