feat: import session sheet redesign and metadata-gen filter

Filter persisted metadata-generation sessions out of the import list so
existing on-disk entries stop polluting it for users.

Rename the surface to "Import session" everywhere, swap the bespoke
filter pills for SegmentedControl with provider icons, drop the trailing
provider label on rows (icon is enough), tighten padding, and align the
row icon with the segmented control's left edge.
This commit is contained in:
Mohamed Boudra
2026-05-09 19:00:01 +07:00
parent d1bda25a0b
commit c725352888
7 changed files with 204 additions and 176 deletions
@@ -179,6 +179,45 @@ test("listImportableProviderSessions filters, sorts, limits, and projects import
});
});
test("listImportableProviderSessions filters out metadata generation sessions", async () => {
const cwd = "/tmp/project";
const descriptors = [
makeDescriptor({
sessionId: "metadata-session",
nativeHandle: "metadata-handle",
cwd,
title: "Generate metadata for a coding agent based on the user prom...",
lastActivityAt: "2026-04-30T12:05:00.000Z",
firstPrompt:
"Generate metadata for a coding agent based on the user prompt.\nTitle: short descriptive label (<= 40 chars).",
}),
makeDescriptor({
sessionId: "real-session",
nativeHandle: "real-handle",
cwd,
title: "Real session",
lastActivityAt: "2026-04-30T12:00:00.000Z",
firstPrompt: "hey hey",
}),
];
const result = await listImportableProviderSessions({
request: makeRequest({ cwd, providers: ["codex"] }),
agentManager: {
listAgents: () => [],
listImportablePersistedAgents: async () => descriptors,
} satisfies Pick<AgentManager, "listAgents" | "listImportablePersistedAgents">,
agentStorage: {
list: async () => [],
} satisfies Pick<AgentStorage, "list">,
providerRegistry: { codex: { label: "Codex" } },
});
expect(result.entries).toHaveLength(1);
expect(result.entries[0].providerHandleId).toBe("real-handle");
expect(result.filteredAlreadyImportedCount).toBe(0);
});
test("listImportableProviderSessions rejects invalid since values", async () => {
await expect(
listImportableProviderSessions({
@@ -16,6 +16,9 @@ import type {
type ImportAgentRequestMessage = z.infer<typeof ImportAgentRequestMessageSchema>;
const METADATA_GENERATION_PROMPT_PREFIX =
"Generate metadata for a coding agent based on the user prompt.";
export interface NormalizedImportAgentRequest {
provider: string;
providerHandleId: string;
@@ -91,6 +94,9 @@ export async function listImportableProviderSessions(
if (sinceTimestamp !== null && descriptor.lastActivityAt.getTime() < sinceTimestamp) {
continue;
}
if (isMetadataGenerationDescriptor(descriptor)) {
continue;
}
const providerHandleId =
descriptor.persistence.nativeHandle ?? descriptor.persistence.sessionId;
if (importedHandles.has(toProviderSessionHandleKey(descriptor.provider, providerHandleId))) {
@@ -144,6 +150,14 @@ function toProviderSessionHandleKey(provider: string, providerHandleId: string):
return `${provider}\0${providerHandleId}`;
}
function isMetadataGenerationDescriptor(descriptor: PersistedAgentDescriptor): boolean {
for (const item of descriptor.timeline) {
if (item.type !== "user_message") continue;
return item.text.trimStart().startsWith(METADATA_GENERATION_PROMPT_PREFIX);
}
return false;
}
function collectProviderSessionHandleKeys(
target: Set<string>,
provider: AgentProvider | StoredAgentRecord["provider"] | string,