Something went wrong. Try again.
My version of https://github.com/vercel-labs/fx
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135const std = @import("std");const session_display_metadata = @import("session_display_metadata.zig");const session_store = @import("session_store.zig");const text_utils = @import("../shared/text_utils.zig");
pub const Scope = enum { current_workspace, all_workspaces,};
pub const LoadState = enum { loading, ready, failed,};
pub const ResumeFailure = enum { open_elsewhere, being_updated, unavailable,};
pub fn filteredCount(summaries: []const session_store.SessionSummary, query: []const u8) usize { var count: usize = 0; for (summaries) |summary| { if (matchesQuery(summary, query)) count += 1; } return count;}
pub fn summaryAt( summaries: []const session_store.SessionSummary, query: []const u8, display_index: usize,) ?*const session_store.SessionSummary { var current: usize = 0; for (summaries) |*summary| { if (!matchesQuery(summary.*, query)) continue; if (current == display_index) return summary; current += 1; } return null;}
pub fn displayTitle(summary: session_store.SessionSummary) []const u8 { return summary.title orelse session_display_metadata.fallback_title;}
pub fn workspacePath(summary: session_store.SessionSummary) []const u8 { return summary.workspace_root orelse summary.origin_workspace_root orelse "(unknown workspace)";}
pub fn relativeActivityAge(buf: []u8, updated_at_ms: i64, now_ms: i64) []const u8 { const delta_ms: i64 = @max(0, now_ms - updated_at_ms); if (delta_ms < std.time.ms_per_min) return "just now"; if (delta_ms < std.time.ms_per_hour) { return std.fmt.bufPrint(buf, "{d}m ago", .{@divFloor(delta_ms, std.time.ms_per_min)}) catch "recently"; } if (delta_ms < std.time.ms_per_day) { return std.fmt.bufPrint(buf, "{d}h ago", .{@divFloor(delta_ms, std.time.ms_per_hour)}) catch "recently"; } return std.fmt.bufPrint(buf, "{d}d ago", .{@divFloor(delta_ms, std.time.ms_per_day)}) catch "recently";}
// Same buckets as relativeActivityAge without the " ago" suffix, for tight// single-line layouts: "now", "5m", "2h", "1d".pub fn relativeActivityAgeCompact(buf: []u8, updated_at_ms: i64, now_ms: i64) []const u8 { const delta_ms: i64 = @max(0, now_ms - updated_at_ms); if (delta_ms < std.time.ms_per_min) return "now"; if (delta_ms < std.time.ms_per_hour) { return std.fmt.bufPrint(buf, "{d}m", .{@divFloor(delta_ms, std.time.ms_per_min)}) catch "recently"; } if (delta_ms < std.time.ms_per_day) { return std.fmt.bufPrint(buf, "{d}h", .{@divFloor(delta_ms, std.time.ms_per_hour)}) catch "recently"; } return std.fmt.bufPrint(buf, "{d}d", .{@divFloor(delta_ms, std.time.ms_per_day)}) catch "recently";}
fn matchesQuery(summary: session_store.SessionSummary, query: []const u8) bool { const query_text = std.mem.trim(u8, query, " \t\r\n"); if (query_text.len == 0) return true; if (text_utils.containsIgnoreCase(displayTitle(summary), query_text)) return true; if (text_utils.containsIgnoreCase(workspacePath(summary), query_text)) return true; if (summary.preview) |preview| { if (text_utils.containsIgnoreCase(preview, query_text)) return true; } return false;}
test "session catalog filters titles previews and workspace paths" { const summaries = [_]session_store.SessionSummary{ .{ .id = @constCast("one"), .workspace_root = @constCast("/worktrees/alpha"), .title = @constCast("Fix renderer"), .preview = @constCast("inspect footer state"), .created_at_ms = 1, .updated_at_ms = 2, .conversation_language = .literal("en"), .history_len = 4, }, .{ .id = @constCast("two"), .workspace_root = @constCast("/worktrees/beta"), .title = @constCast("Review sessions"), .created_at_ms = 1, .updated_at_ms = 3, .conversation_language = .literal("en"), .history_len = 2, }, };
try std.testing.expectEqual(@as(usize, 2), filteredCount(&summaries, "")); try std.testing.expectEqual(@as(usize, 1), filteredCount(&summaries, "RENDER")); try std.testing.expectEqualStrings("two", summaryAt(&summaries, "beta", 0).?.id); try std.testing.expectEqualStrings("one", summaryAt(&summaries, "footer", 0).?.id); try std.testing.expect(summaryAt(&summaries, "missing", 0) == null);}
test "session catalog activity age uses the last update" { var buf: [32]u8 = undefined; try std.testing.expectEqualStrings("just now", relativeActivityAge(&buf, 1_000, 1_000)); try std.testing.expectEqualStrings("3m ago", relativeActivityAge(&buf, 1_000, 1_000 + 3 * std.time.ms_per_min)); try std.testing.expectEqualStrings("2h ago", relativeActivityAge(&buf, 1_000, 1_000 + 2 * std.time.ms_per_hour)); try std.testing.expectEqualStrings("3d ago", relativeActivityAge(&buf, 1_000, 1_000 + 3 * std.time.ms_per_day));}
test "session catalog compact activity age drops the ago suffix" { var buf: [32]u8 = undefined; try std.testing.expectEqualStrings("now", relativeActivityAgeCompact(&buf, 1_000, 1_000)); try std.testing.expectEqualStrings("3m", relativeActivityAgeCompact(&buf, 1_000, 1_000 + 3 * std.time.ms_per_min)); try std.testing.expectEqualStrings("2h", relativeActivityAgeCompact(&buf, 1_000, 1_000 + 2 * std.time.ms_per_hour)); try std.testing.expectEqualStrings("3d", relativeActivityAgeCompact(&buf, 1_000, 1_000 + 3 * std.time.ms_per_day));}