@zgeoff/atc 0.1.3 → 0.1.4

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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zgeoff/atc",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "Terminal control tower for Claude Code sessions",
5
5
  "homepage": "https://github.com/zgeoff/atc#readme",
6
6
  "bugs": "https://github.com/zgeoff/atc/issues",
package/src/index.ts CHANGED
@@ -4,7 +4,7 @@ import { loadConfig } from './config';
4
4
  import { collectDirs, findFuzzyScore, formatDir, pickMatches } from './dirs';
5
5
  import type { EventMsg } from './protocol';
6
6
  import { isRecord } from './report';
7
- import { countSessionStates, sortSessionViews } from './sessions';
7
+ import { countSessionStates, sortGroupedSessionViews, sortSessionViews } from './sessions';
8
8
  import type { SessionState } from './sessions';
9
9
  import { ansi, cols, drawHelp, drawHome, drawOverlay, drawPicker, drawStatusBar, rows } from './ui';
10
10
 
@@ -195,7 +195,7 @@ function applyHelpKey(buf: Buffer) {
195
195
  let overlayFilter: string | null = null;
196
196
 
197
197
  function pickOverlaySessions(): MirrorSession[] {
198
- const sorted = sortSessionViews(fleet);
198
+ const sorted = sortGroupedSessionViews(fleet);
199
199
 
200
200
  if (overlayFilter === null || overlayFilter === '') {
201
201
  return sorted;
@@ -229,7 +229,7 @@ function openOverlay() {
229
229
  confirmKill = false;
230
230
  overlayFilter = null;
231
231
 
232
- const focusedIndex = sortSessionViews(fleet).findIndex((s) => s.id === focusedID);
232
+ const focusedIndex = sortGroupedSessionViews(fleet).findIndex((s) => s.id === focusedID);
233
233
 
234
234
  overlaySelected = Math.max(0, focusedIndex);
235
235
 
package/src/sessions.ts CHANGED
@@ -613,3 +613,30 @@ export function sortSessionViews<
613
613
 
614
614
  return [...list].toSorted((a, b) => rank[a.state] - rank[b.state] || a.createdAt - b.createdAt);
615
615
  }
616
+
617
+ // Overlay display order: the urgency sort with each group's sessions pulled
618
+ // together at the position of its most urgent member, so the renderer's
619
+ // adjacency-based headers appear once per group and urgent groups still lead.
620
+ export function sortGroupedSessionViews<
621
+ T extends {
622
+ readonly state: SessionState;
623
+ readonly createdAt: number;
624
+ readonly group?: string;
625
+ readonly cwd: string;
626
+ },
627
+ >(list: readonly T[]): T[] {
628
+ const buckets = new Map<string, T[]>();
629
+
630
+ for (const s of sortSessionViews(list)) {
631
+ const key = s.group ?? s.cwd;
632
+ const bucket = buckets.get(key);
633
+
634
+ if (bucket === undefined) {
635
+ buckets.set(key, [s]);
636
+ } else {
637
+ bucket.push(s);
638
+ }
639
+ }
640
+
641
+ return [...buckets.values()].flat();
642
+ }