diff --git a/examples/audiobook-curator/src/cli/library-audit.tsx b/examples/audiobook-curator/src/cli/library-audit.tsx index 11d0e2b81..5a4cd9ebf 100644 --- a/examples/audiobook-curator/src/cli/library-audit.tsx +++ b/examples/audiobook-curator/src/cli/library-audit.tsx @@ -4,6 +4,7 @@ import { Agent, agent } from '@agent-bundle/runtime'; import { z } from 'zod'; import { CuratorDocument } from '../components/curator-document.js'; +import { libraryAuditCliHeadline } from '../components/headlines.js'; import { LibraryAnalysis } from '../components/library-analysis.js'; import { DataList } from '../components/primitives.js'; import type { LibraryAuditReceipt } from '../library.js'; @@ -45,7 +46,7 @@ export default async function LibraryAudit({ input, signal }: CliRouteProps ## Library audit diff --git a/examples/audiobook-curator/src/components/headlines.ts b/examples/audiobook-curator/src/components/headlines.ts index c22140df4..84ecb466b 100644 --- a/examples/audiobook-curator/src/components/headlines.ts +++ b/examples/audiobook-curator/src/components/headlines.ts @@ -1,11 +1,17 @@ import type { AudibleSearchReceipt } from '../audible.ts'; import type { ConvertReceipt } from '../conversion.ts'; import type { IntegrityAuditReceipt } from '../integrity-audit.ts'; -import type { InventoryReceipt, SelectionReceipt } from '../library.ts'; +import type { InventoryReceipt, LibraryAuditReceipt, SelectionReceipt } from '../library.ts'; export const inventoryHeadline = (receipt: InventoryReceipt): string => `Inventoried ${receipt.summary.files} media files with ${receipt.summary.errors} retained errors.`; +export const libraryAuditHeadline = (receipt: LibraryAuditReceipt): string => + `Audited ${receipt.summary.files} library media files and found ${receipt.duplicateCandidates.length} duplicate candidate groups.`; + +export const libraryAuditCliHeadline = (receipt: LibraryAuditReceipt, sourceCount: number): string => + `Audited ${String(receipt.summary.files)} files (${String(receipt.summary.bytes)} bytes) across ${String(sourceCount)} sources.`; + export const selectionHeadline = (receipt: SelectionReceipt): string => { const reviewCount = receipt.selections.filter((selection) => selection.reviewRequired).length; return `Selected ${receipt.selections.length} source groups; ${reviewCount} require review.`; diff --git a/examples/audiobook-curator/src/components/library-shelf.tsx b/examples/audiobook-curator/src/components/library-shelf.tsx index d4b996df0..1cdf1d88c 100644 --- a/examples/audiobook-curator/src/components/library-shelf.tsx +++ b/examples/audiobook-curator/src/components/library-shelf.tsx @@ -63,8 +63,8 @@ export interface AuditShelfProps { readonly receipt: LibraryAuditReceipt; } -export const AuditShelf = ({ receipt }: AuditShelfProps) => { - const summaryFields: Field[] = [ +export const AuditSummary = ({ receipt }: AuditShelfProps) => { + const fields: Field[] = [ { label: 'Files', value: receipt.summary.files }, { label: 'Total bytes', value: receipt.summary.bytes }, { label: 'Missing album', value: receipt.summary.missingAlbum }, @@ -74,13 +74,23 @@ export const AuditShelf = ({ receipt }: AuditShelfProps) => { { label: 'Missing title', value: receipt.summary.missingTitle }, { label: 'Probe failures', value: receipt.summary.probeFailures }, ]; + return ; +}; + +export const AuditFileCards = ({ receipt }: AuditShelfProps) => ( + <> + {receipt.files.slice(0, maximumCards).map((file) => ( + + ))} + + +); + +export const AuditShelf = ({ receipt }: AuditShelfProps) => { return ( <> - - {receipt.files.slice(0, maximumCards).map((file) => ( - - ))} - + + {receipt.duplicateCandidates.slice(0, 10).map((group) => ( - - {receipt.files.slice(0, 20).map((file) => ( - - ))} - {receipt.files.length > 20 - ? {`_+${String(receipt.files.length - 20)} more files retained in the structured receipt._`} - : null} + + }>