Files
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

27 lines
942 B
TypeScript

/**
* Split a flat list into consecutive runs. A new run starts whenever
* `sameRun(previousItem, currentItem)` returns false. Total function: every
* input element lands in exactly one run, runs preserve order, and an empty
* input yields an empty result. No element is ever dropped or duplicated.
*
* This is the segmentation primitive behind neighbour-dependent projections
* (e.g. coalescing thinking into the message it precedes). Keeping it generic
* and pure means the grouping decision lives entirely in the `sameRun`
* predicate, which is trivially table-testable on its own.
*/
export function chunkBy<T>(
items: readonly T[],
sameRun: (previous: T, current: T) => boolean
): T[][] {
const runs: T[][] = [];
for (const item of items) {
const current = runs.at(-1);
if (current && sameRun(current.at(-1)!, item)) {
current.push(item);
continue;
}
runs.push([item]);
}
return runs;
}