feat(sessions): group conversation list by project directory (closes #67) (#96)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Den
2026-07-17 02:22:57 -07:00
committed by GitHub
parent 3b6dab8c27
commit 90093f4bac
3 changed files with 187 additions and 11 deletions

View File

@@ -0,0 +1,43 @@
import { test } from "node:test"
import assert from "node:assert/strict"
import { groupByDirectory } from "./session-grouping.ts"
test("groupByDirectory: buckets items by directory, preserving item order within a bucket", () => {
const items = [
{ id: "1", directory: "/a" },
{ id: "2", directory: "/b" },
{ id: "3", directory: "/a" },
]
const groups = groupByDirectory(items)
assert.equal(groups.length, 2)
assert.equal(groups[0].directory, "/a")
assert.deepEqual(groups[0].items.map((i) => i.id), ["1", "3"])
assert.equal(groups[1].directory, "/b")
assert.deepEqual(groups[1].items.map((i) => i.id), ["2"])
})
test("groupByDirectory: orders groups by first-seen directory, not alphabetically", () => {
const items = [
{ id: "1", directory: "/z" },
{ id: "2", directory: "/a" },
]
const groups = groupByDirectory(items)
assert.deepEqual(
groups.map((g) => g.directory),
["/z", "/a"],
)
})
test("groupByDirectory: empty input returns no groups", () => {
assert.deepEqual(groupByDirectory([]), [])
})
test("groupByDirectory: single directory yields a single group with all items", () => {
const items = [
{ id: "1", directory: "/a" },
{ id: "2", directory: "/a" },
]
const groups = groupByDirectory(items)
assert.equal(groups.length, 1)
assert.equal(groups[0].items.length, 2)
})

View File

@@ -0,0 +1,31 @@
// Pure helpers for grouping the session list by project directory.
// No React Native imports — unit-testable with node --test.
/** A contiguous-by-directory bucket of items, in first-seen order. */
export interface DirectoryGroup<T> {
directory: string
items: T[]
}
/**
* Groups items by their `directory` field, preserving both the original
* item order within a group and the order in which each directory was
* first encountered. Does not sort — callers decide presentation order.
*/
export function groupByDirectory<T extends { directory: string }>(items: T[]): DirectoryGroup<T>[] {
const order: string[] = []
const buckets = new Map<string, T[]>()
for (const item of items) {
const dir = item.directory
let bucket = buckets.get(dir)
if (!bucket) {
bucket = []
buckets.set(dir, bucket)
order.push(dir)
}
bucket.push(item)
}
return order.map((directory) => ({ directory, items: buckets.get(directory) as T[] }))
}