Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
7882a15
feat(sidebar): nest forked sessions under their parent (#3224)
rodboev Jun 4, 2026
8b7b056
fix(#3224): keep nested forks first-class
rodboev Jun 8, 2026
0b24f93
fix(#3224): harden nested fork swipe behavior
rodboev Jun 8, 2026
2968dad
fix(sidebar): keep pinned and renameable nested forks (#3224)
rodboev Jun 8, 2026
6098227
fix(sidebar): sort fork groups by newest child activity (#3224)
rodboev Jun 8, 2026
72c615a
fix(sidebar): preserve nested fork menu and chain behavior (#3224)
rodboev Jun 8, 2026
bb8c502
fix(sidebar): attach fork chains in newest-first order (#3224)
rodboev Jun 8, 2026
9e66f6c
fix(sidebar): keep fork child groups independently collapsible (#3224)
rodboev Jun 8, 2026
09e2489
fix(sidebar): preserve nested fork session behavior (#3224)
rodboev Jun 8, 2026
292fcc8
Accept child-session streaming in sidebar coverage
rodboev Jun 11, 2026
dd9b2cc
Let subgrouping spinner tests follow shared streaming logic
rodboev Jun 11, 2026
8a6f2fd
Use the shared external-session gate for child opens
rodboev Jun 11, 2026
0c82940
test(sidebar): keep import-gate regression pin resilient to helper ex…
rodboev Jun 12, 2026
fa5bb9e
fix(sidebar): preserve parent sort order for nested forks (#3601)
rodboev Jun 12, 2026
1371e53
fix(sidebar): isolate parent streaming state from bubbled child, rest…
rodboev Jun 14, 2026
8e8b2ce
fix(sidebar): widen batch-select DOM closest to include fork child ro…
rodboev Jun 14, 2026
51b58b2
fix(sidebar): add attention and drag-hover CSS for nested fork rows (…
rodboev Jun 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
553 changes: 457 additions & 96 deletions static/sessions.js

Large diffs are not rendered by default.

34 changes: 33 additions & 1 deletion static/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -1022,7 +1022,19 @@
.session-item.attention-approval{box-shadow:inset 3px 0 0 var(--error);background:color-mix(in srgb,var(--error) 9%,transparent);}
.session-item.attention-clarify{box-shadow:inset 3px 0 0 var(--warning);background:color-mix(in srgb,var(--warning) 8%,transparent);}
@media (hover:hover){.session-item:hover{background:var(--hover-bg);color:var(--text);}}
.session-item.long-pressing{background:var(--hover-bg);color:var(--text);box-shadow:0 0 0 1px color-mix(in srgb,var(--accent) 38%,transparent);animation:session-long-press .4s cubic-bezier(.2,.8,.2,1) both;}
.session-item.loading{background:var(--hover-bg);color:var(--text);}
.session-item.long-pressing{
background:var(--hover-bg);
color:var(--text);
box-shadow:0 0 0 1px color-mix(in srgb,var(--accent) 38%,transparent);
animation:session-long-press .4s cubic-bezier(.2,.8,.2,1) both;
}
.session-child-session-fork.long-pressing{
background:var(--hover-bg);
color:var(--text);
box-shadow:0 0 0 1px color-mix(in srgb,var(--accent) 38%,transparent);
animation:session-long-press .4s cubic-bezier(.2,.8,.2,1) both;
}
.session-item.swiping-right{background:color-mix(in srgb,var(--warning) 16%,var(--surface));box-shadow:0 0 0 1px color-mix(in srgb,var(--warning) 48%,transparent);}
.session-item.swiping-left{background:color-mix(in srgb,var(--error) 14%,var(--surface));box-shadow:0 0 0 1px color-mix(in srgb,var(--error) 48%,transparent);}
.session-swipe-affordance{position:absolute;top:0;bottom:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:0;width:var(--session-swipe-reveal,0px);padding:0;box-sizing:border-box;opacity:0;overflow:hidden;transform:translate3d(calc(-1 * var(--session-swipe-offset,0px)),0,0);pointer-events:none;z-index:0;}
Expand Down Expand Up @@ -4507,6 +4519,26 @@ main.main > #mainPlugin{display:none;}
.session-child-sessions{display:flex;flex-direction:column;gap:3px;margin-top:6px;margin-left:12px;padding-left:8px;border-left:1px solid var(--border,rgba(255,255,255,.1));}
.session-child-session{appearance:none;border:0;background:transparent;color:var(--muted);font:inherit;font-size:11px;text-align:left;padding:3px 4px;border-radius:5px;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.session-child-session:hover,.session-child-session.active{background:rgba(255,255,255,.06);color:var(--text);}
.session-child-session-fork{position:relative;display:flex;align-items:center;gap:4px;padding:2px 4px 2px 0;overflow:visible;white-space:normal;touch-action:pan-y;-webkit-tap-highlight-color:transparent;user-select:none;-webkit-user-select:none;-webkit-touch-callout:none;transform:translate3d(var(--session-swipe-offset,0),0,0);transition:background .15s,color .15s,transform .5s cubic-bezier(.22,.61,.36,1),box-shadow .15s ease;}
.session-child-session-fork .session-child-session-main{appearance:none;border:0;background:transparent;color:inherit;font:inherit;font-size:11px;text-align:left;padding:3px 4px;border-radius:5px;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1 1 auto;min-width:0;}
.session-child-session-fork:hover .session-child-session-main,.session-child-session-fork.active .session-child-session-main,.session-child-session-fork .session-child-session-main.active{background:rgba(255,255,255,.06);color:var(--text);}
.session-child-session-fork.streaming .session-child-session-main{color:var(--accent);}
.session-child-session-fork .session-actions{position:static;transform:none;opacity:1;pointer-events:auto;flex:0 0 auto;}
.session-child-session-fork .session-child-session-state{position:static;transform:none;flex:0 0 auto;width:14px;height:14px;margin-right:2px;color:var(--accent);}
.session-child-session-fork .session-actions-trigger{width:22px;height:22px;}
.session-child-session-fork .session-swipe-affordance{top:1px;bottom:1px;}
.session-child-session-fork .session-child-session-main,.session-child-session-fork .session-actions{z-index:1;}
.session-child-session-fork.swiping-right{background:color-mix(in srgb,var(--warning) 16%,var(--surface));box-shadow:0 0 0 1px color-mix(in srgb,var(--warning) 48%,transparent);}
.session-child-session-fork.swiping-left{background:color-mix(in srgb,var(--error) 14%,var(--surface));box-shadow:0 0 0 1px color-mix(in srgb,var(--error) 48%,transparent);}
.session-child-session-fork.swiping-right .session-swipe-affordance-right,.session-child-session-fork.swiping-left .session-swipe-affordance-left{opacity:var(--session-swipe-progress,0);}
.session-child-session-fork.needs-attention{box-shadow:inset 3px 0 0 var(--warning);background:color-mix(in srgb,var(--warning) 8%,transparent);}
.session-child-session-fork.attention-approval{box-shadow:inset 3px 0 0 var(--error);background:color-mix(in srgb,var(--error) 9%,transparent);}
.session-child-session-fork.attention-clarify{box-shadow:inset 3px 0 0 var(--warning);background:color-mix(in srgb,var(--warning) 8%,transparent);}
.session-child-session-fork.dragging{transition:background .15s,color .15s,box-shadow .15s ease;will-change:transform;}
.session-child-session-fork.dragging:hover{background:transparent;color:var(--muted);}
.session-child-session-fork.swipe-committed,.session-child-session-fork.swipe-removing{transition:background .15s,color .15s,transform .5s cubic-bezier(.22,.61,.36,1),box-shadow .15s ease;will-change:transform;}
.session-child-session-fork.swipe-removing{overflow:hidden;}
.session-child-session-fork.swipe-committed .session-swipe-affordance{transition:opacity .18s ease,transform .18s ease;}
.session-tree-children{margin-left:16px;border-left:1px solid var(--border,rgba(255,255,255,.1));padding-left:4px;}
.session-tree-child.session-item{font-size:12px;opacity:.85;border-radius:6px;padding:6px 8px;}
.session-tree-child.session-item:hover{opacity:1;}
Expand Down
4 changes: 3 additions & 1 deletion tests/test_1764_context_menu_essentials.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,10 @@ def test_rename_dispatches_to_row_closure(self):
src = SESSIONS.read_text(encoding="utf-8")
# Row-attached closure invocation.
assert "row._startRename" in src
# Row lookup by data-sid.
# Row lookup by data-sid must include nested fork rows too.
assert "function _findSessionRenameRow(" in src
assert ".session-item[data-sid=" in src
assert ".session-child-session[data-sid=" in src

def test_row_exposes_start_rename(self):
"""The session row builder must attach `_startRename` to the row
Expand Down
Loading
Loading