{"version":3,"file":"memory-compare-output.d.ts","sourceRoot":"","sources":["../../src/core/memory-compare-output.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AASzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAE1E,MAAM,WAAW,0BAA0B;IAC1C,mBAAmB,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC;IAC5C,uBAAuB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,kBAAkB,CAAC;CAC/D;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAgBzD;AAED,wBAAgB,yBAAyB,CACxC,SAAS,EAAE,SAAS,qBAAqB,EAAE,EAC3C,OAAO,EAAE,IAAI,CAAC,0BAA0B,EAAE,qBAAqB,CAAC,GAC9D,MAAM,EAAE,CAsCV;AAED,wBAAgB,sBAAsB,CACrC,SAAS,EAAE,SAAS,qBAAqB,EAAE,EAC3C,OAAO,EAAE,0BAA0B,EACnC,SAAS,CAAC,EAAE;IACX,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB,GACC,MAAM,EAAE,CA6FV","sourcesContent":["import type { MemoryHistorySnapshot } from \"./memory.js\";\nimport { computeMemorySnapshotDiff } from \"./memory-diff.js\";\nimport {\n\tformatAdjacentDiffHeader,\n\tformatExplicitDiffHeader,\n\tformatSnapshotSelectorHistoryGuidance,\n\tformatSnapshotSelectorResolutionFailure,\n\tformatSnapshotShortId,\n} from \"./snapshot-selector-formatter.js\";\nimport type { SnapshotResolution } from \"./snapshot-selector-resolver.js\";\n\nexport interface MemoryCompareOutputContext {\n\tgetRelativeAgeLabel: (date: Date) => string;\n\tresolveSnapshotSelector: (input: string) => SnapshotResolution;\n}\n\nexport function formatRelativeAgeLabel(date: Date): string {\n\tconst now = Date.now();\n\tconst diffMs = now - date.getTime();\n\tconst diffSecs = Math.floor(diffMs / 1000);\n\tconst diffMins = Math.floor(diffSecs / 60);\n\tconst diffHours = Math.floor(diffMins / 60);\n\tconst diffDays = Math.floor(diffHours / 24);\n\n\tif (diffSecs < 60) return \"just now\";\n\tif (diffMins < 60) return `${diffMins}m ago`;\n\tif (diffHours < 24) return `${diffHours}h ago`;\n\tif (diffDays < 30) return `${diffDays}d ago`;\n\tconst diffMonths = Math.floor(diffDays / 30);\n\tif (diffMonths < 12) return `${diffMonths}mo ago`;\n\tconst diffYears = Math.floor(diffMonths / 12);\n\treturn `${diffYears}y ago`;\n}\n\nexport function formatMemoryHistoryOutput(\n\tsnapshots: readonly MemoryHistorySnapshot[],\n\tcontext: Pick<MemoryCompareOutputContext, \"getRelativeAgeLabel\">,\n): string[] {\n\tif (snapshots.length === 0) {\n\t\treturn [\"No memory snapshots found in current branch.\"];\n\t}\n\n\tconst lines: string[] = [];\n\tlines.push(`Branch history · ${snapshots.length} snapshot${snapshots.length === 1 ? \"\" : \"s\"} · oldest first`);\n\tlines.push(\"Each snapshot is a complete memory state at that point (not individual changes).\");\n\tlines.push(\"\");\n\tlines.push(...formatSnapshotSelectorHistoryGuidance());\n\tlines.push(\"\");\n\n\tfor (let i = snapshots.length - 1; i >= 0; i--) {\n\t\tconst snapshot = snapshots[i]!;\n\t\tconst date = new Date(snapshot.recordedAt);\n\t\tconst ageLabel = context.getRelativeAgeLabel(date);\n\t\tconst currentMarker = snapshot.isCurrent ? \" [current]\" : \"\";\n\t\tconst itemCount = snapshot.items.length;\n\t\tconst itemLabel = itemCount === 1 ? \"item\" : \"items\";\n\t\tconst shortId = formatSnapshotShortId(snapshot.entryId);\n\n\t\tlines.push(`${ageLabel}${currentMarker} · ${itemCount} ${itemLabel} · ${date.toLocaleString()} · ${shortId}`);\n\n\t\tif (snapshot.items.length > 0) {\n\t\t\tfor (const item of snapshot.items.slice(0, 5)) {\n\t\t\t\tconst valuePreview = item.value.length > 30 ? `${item.value.slice(0, 30)}…` : item.value;\n\t\t\t\tlines.push(`  ${item.key}: ${valuePreview}`);\n\t\t\t}\n\t\t\tif (snapshot.items.length > 5) {\n\t\t\t\tlines.push(`  … and ${snapshot.items.length - 5} more`);\n\t\t\t}\n\t\t} else {\n\t\t\tlines.push(\"  (empty)\");\n\t\t}\n\t\tlines.push(\"\");\n\t}\n\n\treturn lines;\n}\n\nexport function formatMemoryDiffOutput(\n\tsnapshots: readonly MemoryHistorySnapshot[],\n\tcontext: MemoryCompareOutputContext,\n\tselectors?: {\n\t\tbaseline?: string;\n\t\ttarget?: string;\n\t},\n): string[] {\n\tif (snapshots.length === 0) {\n\t\treturn [\"No memory snapshots found. Nothing to diff against.\"];\n\t}\n\n\tconst explicitBaselineId = selectors?.baseline;\n\tconst explicitTargetId = selectors?.target;\n\tlet baselineSnapshot: MemoryHistorySnapshot | undefined;\n\tlet targetSnapshot: MemoryHistorySnapshot | undefined;\n\tlet isExplicitIds = false;\n\n\tif (explicitBaselineId && explicitTargetId) {\n\t\tisExplicitIds = true;\n\t\tconst baselineResult = context.resolveSnapshotSelector(explicitBaselineId);\n\t\tconst targetResult = context.resolveSnapshotSelector(explicitTargetId);\n\n\t\tif (baselineResult.error !== undefined || targetResult.error !== undefined) {\n\t\t\treturn formatSnapshotSelectorResolutionFailure([\n\t\t\t\t{ label: \"Baseline\", resolution: baselineResult },\n\t\t\t\t{ label: \"Target\", resolution: targetResult },\n\t\t\t]);\n\t\t}\n\n\t\tbaselineSnapshot = baselineResult.snapshot;\n\t\ttargetSnapshot = targetResult.snapshot;\n\t} else {\n\t\ttargetSnapshot = snapshots[snapshots.length - 1];\n\t\tbaselineSnapshot = snapshots.length >= 2 ? snapshots[snapshots.length - 2] : undefined;\n\n\t\tif (!baselineSnapshot) {\n\t\t\treturn [\n\t\t\t\t`Initial snapshot — ${targetSnapshot!.items.length} item(s)`,\n\t\t\t\t\"\",\n\t\t\t\t`Recorded: ${new Date(targetSnapshot!.recordedAt).toLocaleString()}`,\n\t\t\t\t\"(snapshot comparison · not an event log)\",\n\t\t\t];\n\t\t}\n\t}\n\n\tconst diff = computeMemorySnapshotDiff(baselineSnapshot!, targetSnapshot!);\n\tconst lines = isExplicitIds\n\t\t? formatExplicitDiffHeader({\n\t\t\t\tbaselineSnapshot: baselineSnapshot!,\n\t\t\t\ttargetSnapshot: targetSnapshot!,\n\t\t\t\tgetRelativeAgeLabel: context.getRelativeAgeLabel,\n\t\t\t})\n\t\t: formatAdjacentDiffHeader({\n\t\t\t\tbaselineSnapshot: baselineSnapshot!,\n\t\t\t\ttargetSnapshot: targetSnapshot!,\n\t\t\t\tgetRelativeAgeLabel: context.getRelativeAgeLabel,\n\t\t\t});\n\n\tif (baselineSnapshot!.entryId === targetSnapshot!.entryId) {\n\t\tlines.push(\"Baseline and target are the same snapshot — no changes to show.\");\n\t\treturn lines;\n\t}\n\n\tif (diff.added.length > 0) {\n\t\tlines.push(`+ Added (${diff.added.length})`);\n\t\tfor (const item of diff.added) {\n\t\t\tconst preview = item.value.length > 50 ? `${item.value.slice(0, 50)}…` : item.value;\n\t\t\tlines.push(`  + ${item.key}: ${preview}`);\n\t\t}\n\t\tlines.push(\"\");\n\t}\n\n\tif (diff.removed.length > 0) {\n\t\tlines.push(`- Removed (${diff.removed.length})`);\n\t\tfor (const item of diff.removed) {\n\t\t\tconst preview = item.value.length > 50 ? `${item.value.slice(0, 50)}…` : item.value;\n\t\t\tlines.push(`  - ${item.key}: ${preview}`);\n\t\t}\n\t\tlines.push(\"\");\n\t}\n\n\tif (diff.changed.length > 0) {\n\t\tlines.push(`~ Changed (${diff.changed.length})`);\n\t\tfor (const item of diff.changed) {\n\t\t\tconst prevPreview =\n\t\t\t\titem.previousValue.length > 40 ? `${item.previousValue.slice(0, 40)}…` : item.previousValue;\n\t\t\tconst currPreview = item.currentValue.length > 40 ? `${item.currentValue.slice(0, 40)}…` : item.currentValue;\n\t\t\tlines.push(`  ~ ${item.key}:`);\n\t\t\tlines.push(`    ${prevPreview}`);\n\t\t\tlines.push(`    ${currPreview}`);\n\t\t}\n\t\tlines.push(\"\");\n\t}\n\n\tif (diff.added.length === 0 && diff.removed.length === 0 && diff.changed.length === 0) {\n\t\tlines.push(\"No changes between snapshots.\");\n\t}\n\n\treturn lines;\n}\n"]}