@zzusp/ccsm 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +236 -232
  3. package/dist/assets/DiskUsage-BY6XwffG.js +2 -0
  4. package/dist/assets/DiskUsage-BY6XwffG.js.map +1 -0
  5. package/dist/assets/{ImportPage-b8NORa8b.js → ImportPage-Cwq5bx7G.js} +2 -2
  6. package/dist/assets/ImportPage-Cwq5bx7G.js.map +1 -0
  7. package/dist/assets/MarkdownContent-BFu7Nkk_.js +2 -0
  8. package/dist/assets/MarkdownContent-BFu7Nkk_.js.map +1 -0
  9. package/dist/assets/{ProjectMemory-aSV8UzQ9.js → ProjectMemory-CcE3KbUK.js} +2 -2
  10. package/dist/assets/ProjectMemory-CcE3KbUK.js.map +1 -0
  11. package/dist/assets/{charts-A5eNHLjX.js → charts-jxJqXXUr.js} +2 -2
  12. package/dist/assets/{charts-A5eNHLjX.js.map → charts-jxJqXXUr.js.map} +1 -1
  13. package/dist/assets/index-CrWxV6sb.css +1 -0
  14. package/dist/assets/index-DTbWl1jb.js +11 -0
  15. package/dist/assets/index-DTbWl1jb.js.map +1 -0
  16. package/dist/assets/markdown-Bag5rX3T.js +30 -0
  17. package/dist/assets/markdown-Bag5rX3T.js.map +1 -0
  18. package/dist/assets/{query-C1K1uQRu.js → query-CS7JQ86v.js} +2 -2
  19. package/dist/assets/{query-C1K1uQRu.js.map → query-CS7JQ86v.js.map} +1 -1
  20. package/dist/assets/{react-W0jzChlo.js → react-CPkiFScu.js} +10 -10
  21. package/dist/assets/{react-W0jzChlo.js.map → react-CPkiFScu.js.map} +1 -1
  22. package/dist/assets/{router-DfbutHY3.js → router-DwaHAh1G.js} +2 -2
  23. package/dist/assets/{router-DfbutHY3.js.map → router-DwaHAh1G.js.map} +1 -1
  24. package/dist/assets/vendor-Cs8vYp-N.js +27 -0
  25. package/dist/assets/vendor-Cs8vYp-N.js.map +1 -0
  26. package/dist/favicon.svg +7 -7
  27. package/dist/index.html +30 -30
  28. package/package.json +24 -11
  29. package/server/index.ts +4 -0
  30. package/server/lib/active-sessions.test.ts +119 -0
  31. package/server/lib/active-sessions.ts +95 -95
  32. package/server/lib/bundle.test.ts +182 -0
  33. package/server/lib/bundle.ts +86 -86
  34. package/server/lib/claude-paths.test.ts +126 -0
  35. package/server/lib/claude-paths.ts +43 -36
  36. package/server/lib/cleanup-suggestions.ts +131 -0
  37. package/server/lib/constants.ts +8 -7
  38. package/server/lib/delete-project.ts +100 -100
  39. package/server/lib/delete.test.ts +244 -0
  40. package/server/lib/delete.ts +192 -203
  41. package/server/lib/disk-usage.ts +81 -83
  42. package/server/lib/encode-cwd.ts +24 -24
  43. package/server/lib/export-bundle.ts +236 -236
  44. package/server/lib/export-import-bundle.test.ts +337 -0
  45. package/server/lib/fs-size.ts +38 -38
  46. package/server/lib/import-bundle.ts +488 -488
  47. package/server/lib/load-memory.ts +120 -120
  48. package/server/lib/load-session.ts +209 -209
  49. package/server/lib/modified-files.test.ts +280 -0
  50. package/server/lib/modified-files.ts +228 -0
  51. package/server/lib/open-folder.ts +47 -40
  52. package/server/lib/parse-jsonl.ts +160 -107
  53. package/server/lib/port.ts +23 -23
  54. package/server/lib/safe-id.test.ts +41 -0
  55. package/server/lib/safe-id.ts +6 -6
  56. package/server/lib/safe-remove.test.ts +73 -0
  57. package/server/lib/safe-remove.ts +25 -0
  58. package/server/lib/scan.ts +289 -183
  59. package/server/lib/search-all.ts +130 -130
  60. package/server/lib/search-session.ts +203 -203
  61. package/server/lib/system-tags.ts +20 -20
  62. package/server/lib/update.ts +67 -0
  63. package/server/lib/version.test.ts +39 -0
  64. package/server/lib/version.ts +117 -0
  65. package/server/routes/disk-cleanup.ts +54 -0
  66. package/server/routes/disk.ts +9 -9
  67. package/server/routes/import.ts +87 -87
  68. package/server/routes/projects.ts +104 -104
  69. package/server/routes/search.ts +79 -79
  70. package/server/routes/sessions.ts +130 -81
  71. package/server/routes/version.ts +34 -0
  72. package/server/types.ts +1 -1
  73. package/shared/constants.ts +7 -2
  74. package/shared/types.ts +513 -359
  75. package/dist/assets/DiskUsage-Bq4VaoUA.js +0 -2
  76. package/dist/assets/DiskUsage-Bq4VaoUA.js.map +0 -1
  77. package/dist/assets/ImportPage-b8NORa8b.js.map +0 -1
  78. package/dist/assets/ProjectMemory-aSV8UzQ9.js.map +0 -1
  79. package/dist/assets/index-DLATR3tZ.js +0 -5
  80. package/dist/assets/index-DLATR3tZ.js.map +0 -1
  81. package/dist/assets/index-DLDtbkux.css +0 -1
  82. package/dist/assets/vendor-CH80ylbS.js +0 -19
  83. package/dist/assets/vendor-CH80ylbS.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DiskUsage-BY6XwffG.js","sources":["../../web/src/components/CleanupSuggestions.tsx","../../web/src/components/StatCard.tsx","../../web/src/routes/DiskUsage.tsx"],"sourcesContent":["import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\nimport { motion } from 'motion/react';\nimport { useEffect, useRef, useState } from 'react';\nimport { Link } from 'react-router-dom';\nimport {\n api,\n type DiskCleanupOrphan,\n type DiskCleanupSuggestions,\n type DiskOrphanDeleteResult,\n type DiskOrphanKind,\n} from '../lib/api.ts';\nimport { formatBytes, formatRelativeTime } from '../lib/format.ts';\nimport { useT } from '../lib/i18n.ts';\nimport { queryKeys } from '../lib/query-keys.ts';\nimport { Loading } from './Loading.tsx';\n\n/**\n * \"清理建议\" 区块:从 /api/disk-cleanup/suggestions 拉取最大的会话 + 两类孤儿目录,\n * 用户逐条确认后通过 DELETE /api/disk-cleanup/orphan/:kind/:sid 单条清理。\n * 不做批量、不做自动清理。\n */\nexport default function CleanupSuggestions() {\n const t = useT();\n const { data, isLoading, error } = useQuery({\n queryKey: queryKeys.diskCleanupSuggestions(),\n queryFn: () => api<DiskCleanupSuggestions>('/api/disk-cleanup/suggestions'),\n });\n\n return (\n <section className=\"surface-card mt-12 p-6\">\n <header className=\"flex flex-wrap items-baseline justify-between gap-x-4 gap-y-1\">\n <h2 className=\"font-display text-xl font-light tracking-tight text-[var(--color-fg-primary)]\">\n {t('cleanup.title')}\n </h2>\n <p className=\"min-w-0 flex-1 font-display text-[13px] italic leading-snug text-[var(--color-fg-muted)]\">\n {t('cleanup.tagline')}\n </p>\n </header>\n <div className=\"rule-dotted mt-3\" aria-hidden />\n\n {isLoading && <Loading label={t('common.computing')} className=\"mt-6\" />}\n {error && (\n <p className=\"mt-6 rounded-md border border-[var(--color-danger)]/40 bg-[var(--color-danger-soft)] px-4 py-3 text-sm text-[var(--color-danger)]\">\n {t('cleanup.failed', { msg: (error as Error).message })}\n </p>\n )}\n\n {data && (\n <div className=\"mt-6 space-y-8\">\n <LargeSessionsTable data={data.largeSessions} />\n <OrphanTable\n kind=\"file-history\"\n title={t('cleanup.section.orphanFileHistory')}\n hint={t('cleanup.section.orphanFileHistory.hint')}\n rows={data.orphanFileHistory}\n />\n <OrphanTable\n kind=\"session-env\"\n title={t('cleanup.section.orphanSessionEnv')}\n hint={t('cleanup.section.orphanSessionEnv.hint')}\n rows={data.orphanSessionEnv}\n />\n </div>\n )}\n </section>\n );\n}\n\nfunction SectionHeader({ title, hint }: { title: string; hint: string }) {\n return (\n <div\n className=\"flex flex-wrap items-baseline justify-between gap-x-3 gap-y-1 rounded-[var(--radius-input)] bg-[var(--color-sunken)] px-3 py-2\"\n >\n <h3 className=\"font-display text-[15px] font-light tracking-tight text-[var(--color-fg-primary)]\">\n {title}\n </h3>\n <span className=\"font-mono text-[10.5px] uppercase tracking-[0.16em] text-[var(--color-fg-muted)]\">\n {hint}\n </span>\n </div>\n );\n}\n\nfunction LargeSessionsTable({\n data,\n}: {\n data: DiskCleanupSuggestions['largeSessions'];\n}) {\n const t = useT();\n return (\n <div>\n <SectionHeader\n title={t('cleanup.section.largeSessions')}\n hint={t('cleanup.section.largeSessions.hint', { n: data.length || 10 })}\n />\n {data.length === 0 ? (\n <p className=\"mt-3 font-mono text-xs uppercase tracking-[0.18em] text-[var(--color-fg-muted)]\">\n {t('cleanup.empty.largeSessions')}\n </p>\n ) : (\n <div className=\"mt-3 -mx-6 overflow-x-auto px-6\">\n <table className=\"w-full table-fixed text-sm\">\n <colgroup>\n <col />\n <col className=\"w-[20rem]\" />\n <col className=\"w-24\" />\n <col className=\"w-24\" />\n <col className=\"w-20\" />\n </colgroup>\n <thead>\n <tr className=\"text-left\">\n <th className=\"px-2 py-2 eyebrow\">{t('cleanup.col.session')}</th>\n <th className=\"px-2 py-2 eyebrow\">{t('cleanup.col.project')}</th>\n <th className=\"px-2 py-2 eyebrow text-right\">{t('cleanup.col.last')}</th>\n <th className=\"px-2 py-2 eyebrow text-right\">{t('cleanup.col.size')}</th>\n <th className=\"px-2 py-2 eyebrow text-right\">{t('cleanup.col.actions')}</th>\n </tr>\n </thead>\n <tbody className=\"border-t border-[var(--color-hairline)]\">\n {data.map((row) => {\n const display = row.customTitle ?? row.title;\n return (\n <tr\n key={`${row.projectId}/${row.sessionId}`}\n className=\"ribbon-row border-b border-[var(--color-hairline)] hover:bg-[var(--color-sunken)]\"\n >\n <td className=\"px-2 py-2.5 align-top\">\n <div\n className=\"truncate font-medium text-[var(--color-fg-primary)]\"\n title={display}\n >\n {display}\n </div>\n <div\n className=\"mt-0.5 truncate font-mono text-[10.5px] text-[var(--color-fg-faint)]\"\n title={row.sessionId}\n >\n {row.sessionId}\n </div>\n </td>\n <td\n className=\"px-2 py-2.5 align-top font-mono text-[12px] text-[var(--color-fg-muted)]\"\n >\n <Link\n to={`/projects/${encodeURIComponent(row.projectId)}`}\n className=\"block truncate hover:text-[var(--color-fg-primary)]\"\n title={row.projectPath}\n >\n {shortCwd(row.projectPath)}\n </Link>\n </td>\n <td className=\"px-2 py-2.5 text-right align-top font-mono text-[12px] text-[var(--color-fg-secondary)]\">\n {formatRelativeTime(row.lastActivity)}\n </td>\n <td className=\"px-2 py-2.5 text-right align-top font-mono tabular-nums text-[var(--color-fg-primary)]\">\n {formatBytes(row.sizeBytes)}\n </td>\n <td className=\"px-2 py-2.5 text-right align-top\">\n <Link\n to={`/projects/${encodeURIComponent(row.projectId)}/sessions/${row.sessionId}`}\n className=\"inline-block rounded-[var(--radius-control)] border border-[var(--color-hairline-strong)] px-2.5 py-1 text-[11.5px] font-medium text-[var(--color-fg-secondary)] hover:bg-[var(--color-sunken)] hover:text-[var(--color-fg-primary)]\"\n >\n {t('cleanup.action.view')}\n </Link>\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n )}\n </div>\n );\n}\n\nfunction OrphanTable({\n kind,\n title,\n hint,\n rows,\n}: {\n kind: DiskOrphanKind;\n title: string;\n hint: string;\n rows: DiskCleanupOrphan[];\n}) {\n const t = useT();\n const [confirming, setConfirming] = useState<DiskCleanupOrphan | null>(null);\n return (\n <div>\n <SectionHeader title={title} hint={hint} />\n {rows.length === 0 ? (\n <p className=\"mt-3 font-mono text-xs uppercase tracking-[0.18em] text-[var(--color-fg-muted)]\">\n {t('cleanup.empty.orphan')}\n </p>\n ) : (\n <div className=\"mt-3 -mx-6 overflow-x-auto px-6\">\n <table className=\"w-full table-fixed text-sm\">\n <colgroup>\n <col />\n <col className=\"w-24\" />\n <col className=\"w-24\" />\n </colgroup>\n <thead>\n <tr className=\"text-left\">\n <th className=\"px-2 py-2 eyebrow\">{t('cleanup.col.sid')}</th>\n <th className=\"px-2 py-2 eyebrow text-right\">{t('cleanup.col.size')}</th>\n <th className=\"px-2 py-2 eyebrow text-right\">{t('cleanup.col.actions')}</th>\n </tr>\n </thead>\n <tbody className=\"border-t border-[var(--color-hairline)]\">\n {rows.map((row) => (\n <tr\n key={row.sessionId}\n className=\"ribbon-row border-b border-[var(--color-hairline)] hover:bg-[var(--color-sunken)]\"\n >\n <td\n className=\"px-2 py-2.5 align-top font-mono text-[12px] text-[var(--color-fg-secondary)]\"\n title={row.sessionId}\n >\n <span className=\"block truncate\">{row.sessionId}</span>\n </td>\n <td className=\"px-2 py-2.5 text-right align-top font-mono tabular-nums text-[var(--color-fg-primary)]\">\n {formatBytes(row.sizeBytes)}\n </td>\n <td className=\"px-2 py-2.5 text-right align-top\">\n <button\n type=\"button\"\n onClick={() => setConfirming(row)}\n className=\"inline-block rounded-[var(--radius-control)] border border-[var(--color-danger)]/40 px-2.5 py-1 text-[11.5px] font-medium text-[var(--color-danger)] hover:bg-[var(--color-danger-soft)]\"\n >\n {t('cleanup.action.delete')}\n </button>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n {confirming && (\n <OrphanConfirmDialog\n kind={kind}\n orphan={confirming}\n onClose={() => setConfirming(null)}\n />\n )}\n </div>\n );\n}\n\nfunction OrphanConfirmDialog({\n kind,\n orphan,\n onClose,\n}: {\n kind: DiskOrphanKind;\n orphan: DiskCleanupOrphan;\n onClose: () => void;\n}) {\n const t = useT();\n const queryClient = useQueryClient();\n const mutation = useMutation({\n mutationFn: () =>\n api<DiskOrphanDeleteResult>(\n `/api/disk-cleanup/orphan/${kind}/${encodeURIComponent(orphan.sessionId)}`,\n { method: 'DELETE' },\n ),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: queryKeys.diskCleanupSuggestions() });\n queryClient.invalidateQueries({ queryKey: queryKeys.diskUsage() });\n onClose();\n },\n });\n\n const isPendingRef = useRef(mutation.isPending);\n isPendingRef.current = mutation.isPending;\n useEffect(() => {\n function onKey(e: KeyboardEvent) {\n if (e.key === 'Escape' && !isPendingRef.current) onClose();\n }\n window.addEventListener('keydown', onKey);\n return () => window.removeEventListener('keydown', onKey);\n }, [onClose]);\n\n return (\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.18 }}\n className=\"fixed inset-0 z-[60] flex items-start justify-center bg-[oklch(0.16_0.006_85_/_0.55)] backdrop-blur-[2px] px-4 py-12\"\n onClick={() => !mutation.isPending && onClose()}\n >\n <motion.div\n initial={{ y: 8, opacity: 0 }}\n animate={{ y: 0, opacity: 1 }}\n transition={{ duration: 0.24, ease: [0.16, 1, 0.3, 1] }}\n className=\"w-full max-w-md overflow-hidden rounded-[var(--radius-panel)] border border-[var(--color-hairline)] bg-[var(--color-surface)] shadow-[var(--shadow-pop)]\"\n onClick={(e) => e.stopPropagation()}\n >\n <header className=\"border-b border-[var(--color-hairline)] px-6 py-5\">\n <p className=\"eyebrow text-[var(--color-danger)]\">{t('delete.eyebrow.confirm')}</p>\n <h2 className=\"mt-1 font-display text-xl font-light tracking-tight text-[var(--color-fg-primary)]\">\n {t('cleanup.confirm.title')}\n </h2>\n <p className=\"mt-2 text-sm text-[var(--color-fg-muted)]\">\n {t('cleanup.confirm.body', {\n kind,\n sid: orphan.sessionId,\n size: formatBytes(orphan.sizeBytes),\n })}\n </p>\n </header>\n {mutation.error && (\n <p className=\"mx-6 mt-3 rounded-md border border-[var(--color-danger)]/40 bg-[var(--color-danger-soft)] px-3 py-2 text-sm text-[var(--color-danger)]\">\n {(mutation.error as Error).message}\n </p>\n )}\n <footer className=\"flex justify-end gap-2 border-t border-[var(--color-hairline)] px-6 py-4\">\n <button\n type=\"button\"\n onClick={onClose}\n disabled={mutation.isPending}\n className=\"rounded-[var(--radius-control)] border border-[var(--color-hairline-strong)] px-4 py-1.5 text-sm text-[var(--color-fg-secondary)] hover:bg-[var(--color-sunken)] disabled:opacity-50\"\n >\n {t('cleanup.confirm.cancel')}\n </button>\n <button\n type=\"button\"\n onClick={() => mutation.mutate()}\n disabled={mutation.isPending}\n className=\"rounded-[var(--radius-control)] bg-[var(--color-danger)] px-4 py-1.5 text-sm font-medium text-white shadow-[var(--shadow-rise)] hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {mutation.isPending ? t('cleanup.action.deleting') : t('cleanup.confirm.confirm')}\n </button>\n </footer>\n </motion.div>\n </motion.div>\n );\n}\n\nfunction shortCwd(cwd: string): string {\n const parts = cwd.split(/[\\\\/]+/).filter(Boolean);\n if (parts.length <= 2) return cwd;\n return '…/' + parts.slice(-2).join('/');\n}\n","import type { ReactNode } from 'react';\n\ninterface Props {\n label: string;\n value: ReactNode;\n unit?: ReactNode;\n trail?: ReactNode;\n accent?: boolean;\n}\n\nexport default function StatCard({ label, value, unit, trail, accent }: Props) {\n return (\n <div\n className={\n 'surface-card is-interactive group relative overflow-hidden p-5 ' +\n (accent ? 'border-[var(--color-accent)]/40 hover:border-[var(--color-accent)]/60' : '')\n }\n >\n {accent && (\n <span\n aria-hidden\n className=\"pointer-events-none absolute -right-12 -top-12 h-32 w-32 rounded-full bg-[var(--color-accent-soft)] opacity-70 blur-2xl\"\n />\n )}\n <div className=\"eyebrow\">{label}</div>\n <div className=\"mt-3 flex items-baseline gap-1.5\">\n <span className=\"font-mono text-4xl font-light leading-none tracking-[-0.02em] tabular-nums text-[var(--color-fg-primary)]\">\n {value}\n </span>\n {unit && (\n <span className=\"font-mono text-[11px] uppercase tracking-[0.16em] text-[var(--color-fg-muted)]\">\n {unit}\n </span>\n )}\n </div>\n {trail && (\n <div className=\"mt-3 font-mono text-[11px] text-[var(--color-fg-muted)]\">{trail}</div>\n )}\n </div>\n );\n}\n","import { useQuery } from '@tanstack/react-query';\nimport { motion } from 'motion/react';\nimport { useEffect, useMemo, useState } from 'react';\nimport { Link } from 'react-router-dom';\nimport {\n Area,\n AreaChart,\n Cell,\n Pie,\n PieChart,\n ResponsiveContainer,\n Tooltip,\n XAxis,\n YAxis,\n} from 'recharts';\nimport CleanupSuggestions from '../components/CleanupSuggestions.tsx';\nimport { Loading } from '../components/Loading.tsx';\nimport { MetaItem, Sep } from '../components/PageHeader.tsx';\nimport StatCard from '../components/StatCard.tsx';\nimport { api, type DiskUsage } from '../lib/api.ts';\nimport { formatBytes, formatRelativeTime } from '../lib/format.ts';\nimport { useT } from '../lib/i18n.ts';\nimport { fadeUpItem, staggerParent } from '../lib/motion.ts';\nimport { queryKeys } from '../lib/query-keys.ts';\n\nconst PALETTE_VARS = [\n '--color-accent',\n '--color-moss',\n '--color-iris',\n '--color-fg-secondary',\n '--color-accent-ink',\n '--color-fg-muted',\n];\n\nconst CHART_VARS = [\n '--color-accent',\n '--color-fg-muted',\n '--color-hairline',\n '--color-surface',\n '--color-fg-primary',\n] as const;\n\n// Resolve a list of CSS variables on <html> and re-resolve whenever the\n// theme class flips. Recharts needs concrete colors; CSS vars don't traverse SVG cleanly.\nfunction useThemeColors<T extends readonly string[]>(vars: T): Record<T[number], string> {\n const [snapshot, setSnapshot] = useState(() => readVars(vars));\n useEffect(() => {\n const observer = new MutationObserver(() => setSnapshot(readVars(vars)));\n observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] });\n return () => observer.disconnect();\n }, [vars]);\n return snapshot;\n}\n\nfunction readVars<T extends readonly string[]>(vars: T): Record<T[number], string> {\n const cs = getComputedStyle(document.documentElement);\n const out = {} as Record<T[number], string>;\n for (const v of vars) (out as Record<string, string>)[v] = cs.getPropertyValue(v).trim() || '#888';\n return out;\n}\n\nexport default function DiskUsageRoute() {\n const t = useT();\n const { data, isLoading, error } = useQuery({\n queryKey: queryKeys.diskUsage(),\n queryFn: () => api<DiskUsage>('/api/disk-usage'),\n });\n\n const colors = useThemeColors(CHART_VARS);\n const accent = colors['--color-accent'];\n const muted = colors['--color-fg-muted'];\n const hairline = colors['--color-hairline'];\n const surface = colors['--color-surface'];\n const fgPrimary = colors['--color-fg-primary'];\n\n const palette = useThemeColors(PALETTE_VARS);\n const resolvedPalette = useMemo(() => PALETTE_VARS.map((v) => palette[v]), [palette]);\n\n const pieData = useMemo(() => {\n if (!data) return [];\n return data.byProject.map((p) => ({\n name: shortCwd(p.decodedCwd),\n value: p.totalBytes,\n sessions: p.sessionCount,\n }));\n }, [data]);\n\n const monthData = useMemo(() => {\n if (!data) return [];\n return data.byMonth.map((m) => ({ month: m.month, MB: +(m.totalBytes / 1_048_576).toFixed(2) }));\n }, [data]);\n\n return (\n <section>\n <div className=\"surface-card p-6\">\n <Masthead\n title={t('disk.title')}\n tagline={t('disk.tagline')}\n stats={\n data\n ? {\n totalBytes: data.totalBytes,\n projectCount: data.byProject.length,\n totalSessions: data.totalSessions,\n }\n : null\n }\n />\n </div>\n\n {isLoading && <Loading label={t('common.computing')} className=\"mt-10\" />}\n {error && (\n <p className=\"mt-10 rounded-md border border-[var(--color-danger)]/40 bg-[var(--color-danger-soft)] px-4 py-3 text-sm text-[var(--color-danger)]\">\n {t('common.failed')}: {(error as Error).message}\n </p>\n )}\n\n {data && (\n <>\n <motion.div\n initial=\"hidden\"\n animate=\"show\"\n variants={staggerParent}\n className=\"mt-8 grid gap-3 sm:grid-cols-3\"\n >\n <motion.div variants={fadeUpItem}>\n <StatCard\n accent\n label={t('disk.stat.total')}\n value={formatBytes(data.totalBytes).split(' ')[0]}\n unit={formatBytes(data.totalBytes).split(' ')[1]}\n trail={t('disk.stat.acrossProjects', { n: data.byProject.length })}\n />\n </motion.div>\n <motion.div variants={fadeUpItem}>\n <StatCard\n label={t('disk.stat.sessions')}\n value={data.totalSessions.toLocaleString()}\n trail={\n data.topSessions[0]\n ? t('disk.stat.largest', { size: formatBytes(data.topSessions[0].totalBytes) })\n : undefined\n }\n />\n </motion.div>\n <motion.div variants={fadeUpItem}>\n <StatCard\n label={t('disk.stat.months')}\n value={data.byMonth.length}\n trail={\n data.byMonth[0]\n ? `${data.byMonth[0].month} → ${data.byMonth.at(-1)?.month ?? data.byMonth[0].month}`\n : undefined\n }\n />\n </motion.div>\n </motion.div>\n\n <div className=\"mt-12 grid gap-8 lg:grid-cols-5\">\n <Card\n title={t('disk.composition.title')}\n subtitle={t('disk.composition.subtitle')}\n className=\"lg:col-span-3\"\n >\n {pieData.length === 0 ? (\n <Empty />\n ) : (\n <div className=\"grid gap-6 md:grid-cols-[minmax(0,1fr)_minmax(0,1.1fr)] md:items-center\">\n <div className=\"relative mx-auto aspect-square w-full max-w-[260px]\">\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <PieChart margin={{ top: 0, right: 0, bottom: 0, left: 0 }}>\n <Pie\n data={pieData}\n dataKey=\"value\"\n nameKey=\"name\"\n cx=\"50%\"\n cy=\"50%\"\n innerRadius=\"58%\"\n outerRadius=\"92%\"\n paddingAngle={1.5}\n stroke={surface}\n strokeWidth={2}\n isAnimationActive={false}\n >\n {pieData.map((_, i) => (\n <Cell key={i} fill={resolvedPalette[i % resolvedPalette.length]} />\n ))}\n </Pie>\n <Tooltip\n contentStyle={tooltipStyle(surface, hairline, fgPrimary)}\n formatter={(value: number) => formatBytes(value)}\n />\n </PieChart>\n </ResponsiveContainer>\n <div className=\"pointer-events-none absolute inset-0 flex flex-col items-center justify-center text-center\">\n <span className=\"eyebrow\">{t('disk.composition.total')}</span>\n <span className=\"mt-1 font-mono text-2xl font-light tabular-nums text-[var(--color-fg-primary)]\">\n {formatBytes(data.totalBytes)}\n </span>\n </div>\n </div>\n <ol className=\"space-y-1.5 text-sm\">\n {pieData.slice(0, 8).map((p, i) => {\n const pct = ((p.value / data.totalBytes) * 100).toFixed(1);\n return (\n <li key={i} className=\"grid grid-cols-[14px_1fr_auto] items-baseline gap-2\">\n <span\n aria-hidden\n className=\"block h-2.5 w-2.5 self-center rounded-sm\"\n style={{ background: resolvedPalette[i % resolvedPalette.length] }}\n />\n <span className=\"truncate font-mono text-xs text-[var(--color-fg-secondary)]\" title={p.name}>\n {p.name}\n </span>\n <span className=\"font-mono tabular-nums text-xs text-[var(--color-fg-primary)]\">\n {pct}% <span className=\"text-[var(--color-fg-faint)]\">· {formatBytes(p.value)}</span>\n </span>\n </li>\n );\n })}\n </ol>\n </div>\n )}\n </Card>\n\n <Card\n title={t('disk.cadence.title')}\n subtitle={t('disk.cadence.subtitle')}\n className=\"lg:col-span-2\"\n >\n {monthData.length === 0 ? (\n <Empty />\n ) : (\n <div className=\"h-72\">\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <AreaChart data={monthData} margin={{ top: 10, right: 8, bottom: 0, left: -10 }}>\n <defs>\n <linearGradient id=\"cadenceFill\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stopColor={accent} stopOpacity={0.55} />\n <stop offset=\"100%\" stopColor={accent} stopOpacity={0} />\n </linearGradient>\n </defs>\n <XAxis\n dataKey=\"month\"\n tick={{ fontSize: 11, fill: muted, fontFamily: 'var(--font-mono)' }}\n tickLine={false}\n axisLine={{ stroke: hairline }}\n />\n <YAxis\n tick={{ fontSize: 11, fill: muted, fontFamily: 'var(--font-mono)' }}\n tickLine={false}\n axisLine={false}\n width={36}\n />\n <Tooltip\n contentStyle={tooltipStyle(surface, hairline, fgPrimary)}\n formatter={(value: number) => `${value.toFixed(2)} MB`}\n cursor={{ stroke: hairline, strokeDasharray: '2 3' }}\n />\n <Area\n type=\"monotone\"\n dataKey=\"MB\"\n stroke={accent}\n strokeWidth={1.6}\n fill=\"url(#cadenceFill)\"\n />\n </AreaChart>\n </ResponsiveContainer>\n </div>\n )}\n </Card>\n </div>\n\n <div className=\"surface-card mt-12 p-6\">\n <div className=\"flex items-baseline justify-between\">\n <h2 className=\"font-display text-xl font-light tracking-tight text-[var(--color-fg-primary)]\">\n {t('disk.heaviest.title')}\n </h2>\n {data.topSessions.length > 0 && (\n <span className=\"font-mono text-[11px] uppercase tracking-[0.16em] text-[var(--color-fg-muted)]\">\n {t('disk.heaviest.top', { n: data.topSessions.length })}\n </span>\n )}\n </div>\n <div className=\"rule-dotted mt-3\" aria-hidden />\n {data.topSessions.length === 0 ? (\n <Empty className=\"mt-6\" />\n ) : (\n <div className=\"mt-4 -mx-6 overflow-x-auto px-6\">\n <table className=\"w-full table-fixed text-sm\">\n <colgroup>\n <col className=\"w-10\" />\n <col />\n <col className=\"w-[22rem]\" />\n <col className=\"w-24\" />\n <col className=\"w-24\" />\n </colgroup>\n <thead>\n <tr className=\"text-left\">\n <th className=\"px-2 py-3 eyebrow\">{t('disk.col.num')}</th>\n <th className=\"px-2 py-3 eyebrow\">{t('disk.col.title')}</th>\n <th className=\"px-2 py-3 eyebrow\">{t('disk.col.project')}</th>\n <th className=\"px-2 py-3 eyebrow text-right\">{t('disk.col.last')}</th>\n <th className=\"px-2 py-3 eyebrow text-right\">{t('disk.col.size')}</th>\n </tr>\n </thead>\n <tbody className=\"border-t border-[var(--color-hairline)]\">\n {data.topSessions.map((s, i) => {\n const displayTitle = s.customTitle ?? s.title;\n return (\n <tr\n key={`${s.projectId}/${s.sessionId}`}\n className=\"ribbon-row border-b border-[var(--color-hairline)] hover:bg-[var(--color-sunken)]\"\n >\n <td className=\"px-2 py-3 align-top font-mono text-[11px] text-[var(--color-fg-faint)]\">\n {String(i + 1).padStart(2, '0')}\n </td>\n <td className=\"px-2 py-3 align-top\">\n <Link\n to={`/projects/${encodeURIComponent(s.projectId)}/sessions/${s.sessionId}`}\n className=\"block truncate font-medium text-[var(--color-fg-primary)] hover:text-[var(--color-accent-ink)] dark:hover:text-[var(--color-accent)]\"\n title={displayTitle}\n >\n {displayTitle}\n </Link>\n </td>\n <td className=\"px-2 py-3 align-top font-mono text-[12px] text-[var(--color-fg-muted)]\">\n <Link\n to={`/projects/${encodeURIComponent(s.projectId)}`}\n className=\"block truncate hover:text-[var(--color-fg-primary)]\"\n title={s.projectId}\n >\n {projectCwdLabel(data, s.projectId)}\n </Link>\n </td>\n <td className=\"px-2 py-3 text-right align-top font-mono text-[12.5px] text-[var(--color-fg-secondary)]\">\n {formatRelativeTime(s.lastAt)}\n </td>\n <td className=\"px-2 py-3 text-right align-top font-mono tabular-nums text-[var(--color-fg-primary)]\">\n {formatBytes(s.totalBytes)}\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n )}\n </div>\n\n <CleanupSuggestions />\n </>\n )}\n </section>\n );\n}\n\nfunction Masthead({\n title,\n tagline,\n stats,\n}: {\n title: string;\n tagline: string;\n stats: {\n totalBytes: number;\n projectCount: number;\n totalSessions: number;\n } | null;\n}) {\n const t = useT();\n return (\n <header className=\"relative\">\n <div className=\"flex flex-wrap items-baseline gap-x-4 gap-y-1\">\n <h1 className=\"font-display text-[clamp(1.75rem,3.5vw,2.25rem)] font-light leading-[1.1] tracking-[-0.02em] text-[var(--color-fg-primary)]\">\n {title}\n <span className=\"text-[var(--color-accent)]\">.</span>\n </h1>\n <p className=\"min-w-0 flex-1 font-display text-[13px] italic leading-snug text-[var(--color-fg-muted)]\">\n {tagline}\n </p>\n </div>\n {stats && (\n <div className=\"mt-3 flex flex-wrap items-baseline gap-x-3 gap-y-1 text-xs\">\n <MetaItem label={t('disk.meta.total')} value={formatBytes(stats.totalBytes)} />\n <Sep />\n <MetaItem label={t('disk.meta.projects')} value={stats.projectCount} />\n <Sep />\n <MetaItem label={t('disk.meta.sessions')} value={stats.totalSessions.toLocaleString()} />\n </div>\n )}\n </header>\n );\n}\n\nfunction tooltipStyle(surface: string, hairline: string, fg: string): React.CSSProperties {\n return {\n background: surface,\n border: `1px solid ${hairline}`,\n borderRadius: 8,\n fontFamily: 'var(--font-mono)',\n fontSize: 11,\n color: fg,\n boxShadow: 'var(--shadow-pop)',\n };\n}\n\nfunction projectCwdLabel(data: DiskUsage, projectId: string): string {\n const p = data.byProject.find((row) => row.projectId === projectId);\n return p ? shortCwd(p.decodedCwd) : projectId;\n}\n\nfunction shortCwd(cwd: string): string {\n const parts = cwd.split(/[\\\\/]+/).filter(Boolean);\n if (parts.length <= 2) return cwd;\n return '…/' + parts.slice(-2).join('/');\n}\n\nfunction Card({\n title,\n subtitle,\n children,\n className = '',\n}: {\n title: string;\n subtitle?: string;\n children: React.ReactNode;\n className?: string;\n}) {\n return (\n <section className={`surface-card p-5 ${className}`}>\n <header className=\"mb-4 flex items-baseline justify-between gap-3\">\n <h3 className=\"font-display text-lg font-light tracking-tight text-[var(--color-fg-primary)]\">\n {title}\n </h3>\n {subtitle && (\n <span className=\"font-mono text-[10px] uppercase tracking-[0.18em] text-[var(--color-fg-muted)]\">\n {subtitle}\n </span>\n )}\n </header>\n {children}\n </section>\n );\n}\n\nfunction Empty({ className = '' }: { className?: string }) {\n const t = useT();\n return (\n <p className={`font-mono text-xs uppercase tracking-[0.18em] text-[var(--color-fg-muted)] ${className}`}>\n {t('common.noData')}\n </p>\n );\n}\n"],"names":["CleanupSuggestions","t","useT","data","isLoading","error","useQuery","queryKeys","api","jsxs","jsx","Loading","LargeSessionsTable","OrphanTable","SectionHeader","title","hint","row","display","Link","shortCwd","formatRelativeTime","formatBytes","kind","rows","confirming","setConfirming","useState","OrphanConfirmDialog","orphan","onClose","queryClient","useQueryClient","mutation","useMutation","isPendingRef","useRef","useEffect","onKey","e","motion","cwd","parts","StatCard","label","value","unit","trail","accent","PALETTE_VARS","CHART_VARS","useThemeColors","vars","snapshot","setSnapshot","readVars","observer","cs","out","v","DiskUsageRoute","colors","muted","hairline","surface","fgPrimary","palette","resolvedPalette","useMemo","pieData","p","monthData","m","Masthead","Fragment","staggerParent","fadeUpItem","_a","Card","Empty","ResponsiveContainer","PieChart","Pie","_","i","Cell","Tooltip","tooltipStyle","pct","AreaChart","XAxis","YAxis","Area","s","displayTitle","projectCwdLabel","tagline","stats","MetaItem","Sep","fg","projectId","subtitle","children","className"],"mappings":"+XAqBA,SAAwBA,IAAqB,CAC3C,MAAMC,EAAIC,EAAA,EACJ,CAAE,KAAAC,EAAM,UAAAC,EAAW,MAAAC,CAAA,EAAUC,EAAS,CAC1C,SAAUC,EAAU,uBAAA,EACpB,QAAS,IAAMC,EAA4B,+BAA+B,CAAA,CAC3E,EAED,OACEC,EAAAA,KAAC,UAAA,CAAQ,UAAU,yBACjB,SAAA,CAAAA,EAAAA,KAAC,SAAA,CAAO,UAAU,gEAChB,SAAA,CAAAC,MAAC,KAAA,CAAG,UAAU,gFACX,SAAAT,EAAE,eAAe,EACpB,QACC,IAAA,CAAE,UAAU,2FACV,SAAAA,EAAE,iBAAiB,CAAA,CACtB,CAAA,EACF,EACAS,EAAAA,IAAC,MAAA,CAAI,UAAU,mBAAmB,cAAW,GAAC,EAE7CN,SAAcO,EAAA,CAAQ,MAAOV,EAAE,kBAAkB,EAAG,UAAU,OAAO,EACrEI,GACCK,EAAAA,IAAC,IAAA,CAAE,UAAU,oIACV,SAAAT,EAAE,iBAAkB,CAAE,IAAMI,EAAgB,OAAA,CAAS,CAAA,CACxD,EAGDF,GACCM,EAAAA,KAAC,MAAA,CAAI,UAAU,iBACb,SAAA,CAAAC,EAAAA,IAACE,GAAA,CAAmB,KAAMT,EAAK,aAAA,CAAe,EAC9CO,EAAAA,IAACG,EAAA,CACC,KAAK,eACL,MAAOZ,EAAE,mCAAmC,EAC5C,KAAMA,EAAE,wCAAwC,EAChD,KAAME,EAAK,iBAAA,CAAA,EAEbO,EAAAA,IAACG,EAAA,CACC,KAAK,cACL,MAAOZ,EAAE,kCAAkC,EAC3C,KAAMA,EAAE,uCAAuC,EAC/C,KAAME,EAAK,gBAAA,CAAA,CACb,CAAA,CACF,CAAA,EAEJ,CAEJ,CAEA,SAASW,EAAc,CAAE,MAAAC,EAAO,KAAAC,GAAyC,CACvE,OACEP,EAAAA,KAAC,MAAA,CACC,UAAU,iIAEV,SAAA,CAAAC,EAAAA,IAAC,KAAA,CAAG,UAAU,oFACX,SAAAK,EACH,EACAL,EAAAA,IAAC,OAAA,CAAK,UAAU,mFACb,SAAAM,CAAA,CACH,CAAA,CAAA,CAAA,CAGN,CAEA,SAASJ,GAAmB,CAC1B,KAAAT,CACF,EAEG,CACD,MAAM,EAAID,EAAA,EACV,cACG,MAAA,CACC,SAAA,CAAAQ,EAAAA,IAACI,EAAA,CACC,MAAO,EAAE,+BAA+B,EACxC,KAAM,EAAE,qCAAsC,CAAE,EAAGX,EAAK,QAAU,GAAI,CAAA,CAAA,EAEvEA,EAAK,SAAW,QACd,IAAA,CAAE,UAAU,kFACV,SAAA,EAAE,6BAA6B,CAAA,CAClC,QAEC,MAAA,CAAI,UAAU,kCACb,SAAAM,EAAAA,KAAC,QAAA,CAAM,UAAU,6BACf,SAAA,CAAAA,OAAC,WAAA,CACC,SAAA,CAAAC,EAAAA,IAAC,MAAA,EAAI,EACLA,EAAAA,IAAC,MAAA,CAAI,UAAU,WAAA,CAAY,EAC3BA,EAAAA,IAAC,MAAA,CAAI,UAAU,MAAA,CAAO,EACtBA,EAAAA,IAAC,MAAA,CAAI,UAAU,MAAA,CAAO,EACtBA,EAAAA,IAAC,MAAA,CAAI,UAAU,MAAA,CAAO,CAAA,EACxB,EACAA,MAAC,QAAA,CACC,SAAAD,EAAAA,KAAC,KAAA,CAAG,UAAU,YACZ,SAAA,CAAAC,MAAC,KAAA,CAAG,UAAU,oBAAqB,SAAA,EAAE,qBAAqB,EAAE,QAC3D,KAAA,CAAG,UAAU,oBAAqB,SAAA,EAAE,qBAAqB,EAAE,QAC3D,KAAA,CAAG,UAAU,+BAAgC,SAAA,EAAE,kBAAkB,EAAE,QACnE,KAAA,CAAG,UAAU,+BAAgC,SAAA,EAAE,kBAAkB,EAAE,QACnE,KAAA,CAAG,UAAU,+BAAgC,SAAA,EAAE,qBAAqB,CAAA,CAAE,CAAA,CAAA,CACzE,CAAA,CACF,QACC,QAAA,CAAM,UAAU,0CACd,SAAAP,EAAK,IAAKc,GAAQ,CACjB,MAAMC,EAAUD,EAAI,aAAeA,EAAI,MACvC,OACER,EAAAA,KAAC,KAAA,CAEC,UAAU,oFAEV,SAAA,CAAAA,EAAAA,KAAC,KAAA,CAAG,UAAU,wBACZ,SAAA,CAAAC,EAAAA,IAAC,MAAA,CACC,UAAU,sDACV,MAAOQ,EAEN,SAAAA,CAAA,CAAA,EAEHR,EAAAA,IAAC,MAAA,CACC,UAAU,uEACV,MAAOO,EAAI,UAEV,SAAAA,EAAI,SAAA,CAAA,CACP,EACF,EACAP,EAAAA,IAAC,KAAA,CACC,UAAU,2EAEV,SAAAA,EAAAA,IAACS,EAAA,CACC,GAAI,aAAa,mBAAmBF,EAAI,SAAS,CAAC,GAClD,UAAU,sDACV,MAAOA,EAAI,YAEV,SAAAG,GAASH,EAAI,WAAW,CAAA,CAAA,CAC3B,CAAA,QAED,KAAA,CAAG,UAAU,0FACX,SAAAI,EAAmBJ,EAAI,YAAY,EACtC,QACC,KAAA,CAAG,UAAU,yFACX,SAAAK,EAAYL,EAAI,SAAS,EAC5B,EACAP,EAAAA,IAAC,KAAA,CAAG,UAAU,mCACZ,SAAAA,EAAAA,IAACS,EAAA,CACC,GAAI,aAAa,mBAAmBF,EAAI,SAAS,CAAC,aAAaA,EAAI,SAAS,GAC5E,UAAU,uOAET,WAAE,qBAAqB,CAAA,CAAA,CAC1B,CACF,CAAA,CAAA,EAzCK,GAAGA,EAAI,SAAS,IAAIA,EAAI,SAAS,EAAA,CA4C5C,CAAC,CAAA,CACH,CAAA,CAAA,CACF,CAAA,CACF,CAAA,EAEJ,CAEJ,CAEA,SAASJ,EAAY,CACnB,KAAAU,EACA,MAAAR,EACA,KAAAC,EACA,KAAAQ,CACF,EAKG,CACD,MAAMvB,EAAIC,EAAA,EACJ,CAACuB,EAAYC,CAAa,EAAIC,EAAAA,SAAmC,IAAI,EAC3E,cACG,MAAA,CACC,SAAA,CAAAjB,EAAAA,IAACI,EAAA,CAAc,MAAAC,EAAc,KAAAC,CAAA,CAAY,EACxCQ,EAAK,SAAW,QACd,IAAA,CAAE,UAAU,kFACV,SAAAvB,EAAE,sBAAsB,CAAA,CAC3B,QAEC,MAAA,CAAI,UAAU,kCACb,SAAAQ,EAAAA,KAAC,QAAA,CAAM,UAAU,6BACf,SAAA,CAAAA,OAAC,WAAA,CACC,SAAA,CAAAC,EAAAA,IAAC,MAAA,EAAI,EACLA,EAAAA,IAAC,MAAA,CAAI,UAAU,MAAA,CAAO,EACtBA,EAAAA,IAAC,MAAA,CAAI,UAAU,MAAA,CAAO,CAAA,EACxB,EACAA,MAAC,QAAA,CACC,SAAAD,EAAAA,KAAC,KAAA,CAAG,UAAU,YACZ,SAAA,CAAAC,MAAC,KAAA,CAAG,UAAU,oBAAqB,SAAAT,EAAE,iBAAiB,EAAE,QACvD,KAAA,CAAG,UAAU,+BAAgC,SAAAA,EAAE,kBAAkB,EAAE,QACnE,KAAA,CAAG,UAAU,+BAAgC,SAAAA,EAAE,qBAAqB,CAAA,CAAE,CAAA,CAAA,CACzE,CAAA,CACF,QACC,QAAA,CAAM,UAAU,0CACd,SAAAuB,EAAK,IAAKP,GACTR,EAAAA,KAAC,KAAA,CAEC,UAAU,oFAEV,SAAA,CAAAC,EAAAA,IAAC,KAAA,CACC,UAAU,+EACV,MAAOO,EAAI,UAEX,SAAAP,EAAAA,IAAC,OAAA,CAAK,UAAU,iBAAkB,WAAI,SAAA,CAAU,CAAA,CAAA,QAEjD,KAAA,CAAG,UAAU,yFACX,SAAAY,EAAYL,EAAI,SAAS,EAC5B,EACAP,EAAAA,IAAC,KAAA,CAAG,UAAU,mCACZ,SAAAA,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,QAAS,IAAMgB,EAAcT,CAAG,EAChC,UAAU,2LAET,WAAE,uBAAuB,CAAA,CAAA,CAC5B,CACF,CAAA,CAAA,EApBKA,EAAI,SAAA,CAsBZ,CAAA,CACH,CAAA,CAAA,CACF,CAAA,CACF,EAEDQ,GACCf,EAAAA,IAACkB,GAAA,CACC,KAAAL,EACA,OAAQE,EACR,QAAS,IAAMC,EAAc,IAAI,CAAA,CAAA,CACnC,EAEJ,CAEJ,CAEA,SAASE,GAAoB,CAC3B,KAAAL,EACA,OAAAM,EACA,QAAAC,CACF,EAIG,CACD,MAAM7B,EAAIC,EAAA,EACJ6B,EAAcC,EAAA,EACdC,EAAWC,EAAY,CAC3B,WAAY,IACV1B,EACE,4BAA4Be,CAAI,IAAI,mBAAmBM,EAAO,SAAS,CAAC,GACxE,CAAE,OAAQ,QAAA,CAAS,EAEvB,UAAW,IAAM,CACfE,EAAY,kBAAkB,CAAE,SAAUxB,EAAU,uBAAA,EAA0B,EAC9EwB,EAAY,kBAAkB,CAAE,SAAUxB,EAAU,UAAA,EAAa,EACjEuB,EAAA,CACF,CAAA,CACD,EAEKK,EAAeC,EAAAA,OAAOH,EAAS,SAAS,EAC9C,OAAAE,EAAa,QAAUF,EAAS,UAChCI,EAAAA,UAAU,IAAM,CACd,SAASC,EAAMC,EAAkB,CAC3BA,EAAE,MAAQ,UAAY,CAACJ,EAAa,SAASL,EAAA,CACnD,CACA,cAAO,iBAAiB,UAAWQ,CAAK,EACjC,IAAM,OAAO,oBAAoB,UAAWA,CAAK,CAC1D,EAAG,CAACR,CAAO,CAAC,EAGVpB,EAAAA,IAAC8B,EAAO,IAAP,CACC,QAAS,CAAE,QAAS,CAAA,EACpB,QAAS,CAAE,QAAS,CAAA,EACpB,KAAM,CAAE,QAAS,CAAA,EACjB,WAAY,CAAE,SAAU,GAAA,EACxB,UAAU,uHACV,QAAS,IAAM,CAACP,EAAS,WAAaH,EAAA,EAEtC,SAAArB,EAAAA,KAAC+B,EAAO,IAAP,CACC,QAAS,CAAE,EAAG,EAAG,QAAS,CAAA,EAC1B,QAAS,CAAE,EAAG,EAAG,QAAS,CAAA,EAC1B,WAAY,CAAE,SAAU,IAAM,KAAM,CAAC,IAAM,EAAG,GAAK,CAAC,CAAA,EACpD,UAAU,2JACV,QAAUD,GAAMA,EAAE,gBAAA,EAElB,SAAA,CAAA9B,EAAAA,KAAC,SAAA,CAAO,UAAU,oDAChB,SAAA,CAAAC,MAAC,IAAA,CAAE,UAAU,qCAAsC,SAAAT,EAAE,wBAAwB,EAAE,QAC9E,KAAA,CAAG,UAAU,qFACX,SAAAA,EAAE,uBAAuB,EAC5B,EACAS,EAAAA,IAAC,IAAA,CAAE,UAAU,4CACV,WAAE,uBAAwB,CACzB,KAAAa,EACA,IAAKM,EAAO,UACZ,KAAMP,EAAYO,EAAO,SAAS,CAAA,CACnC,CAAA,CACH,CAAA,EACF,EACCI,EAAS,OACRvB,MAAC,IAAA,CAAE,UAAU,yIACT,SAAAuB,EAAS,MAAgB,OAAA,CAC7B,EAEFxB,EAAAA,KAAC,SAAA,CAAO,UAAU,2EAChB,SAAA,CAAAC,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,QAASoB,EACT,SAAUG,EAAS,UACnB,UAAU,uLAET,WAAE,wBAAwB,CAAA,CAAA,EAE7BvB,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,QAAS,IAAMuB,EAAS,OAAA,EACxB,SAAUA,EAAS,UACnB,UAAU,mMAET,WAAS,UAAYhC,EAAE,yBAAyB,EAAIA,EAAE,yBAAyB,CAAA,CAAA,CAClF,CAAA,CACF,CAAA,CAAA,CAAA,CACF,CAAA,CAGN,CAEA,SAASmB,GAASqB,EAAqB,CACrC,MAAMC,EAAQD,EAAI,MAAM,QAAQ,EAAE,OAAO,OAAO,EAChD,OAAIC,EAAM,QAAU,EAAUD,EACvB,KAAOC,EAAM,MAAM,EAAE,EAAE,KAAK,GAAG,CACxC,CCjVA,SAAwBC,EAAS,CAAE,MAAAC,EAAO,MAAAC,EAAO,KAAAC,EAAM,MAAAC,EAAO,OAAAC,GAAiB,CAC7E,OACEvC,EAAAA,KAAC,MAAA,CACC,UACE,mEACCuC,EAAS,wEAA0E,IAGrF,SAAA,CAAAA,GACCtC,EAAAA,IAAC,OAAA,CACC,cAAW,GACX,UAAU,yHAAA,CAAA,EAGdA,EAAAA,IAAC,MAAA,CAAI,UAAU,UAAW,SAAAkC,EAAM,EAChCnC,EAAAA,KAAC,MAAA,CAAI,UAAU,mCACb,SAAA,CAAAC,EAAAA,IAAC,OAAA,CAAK,UAAU,4GACb,SAAAmC,EACH,EACCC,GACCpC,EAAAA,IAAC,OAAA,CAAK,UAAU,iFACb,SAAAoC,CAAA,CACH,CAAA,EAEJ,EACCC,GACCrC,EAAAA,IAAC,MAAA,CAAI,UAAU,0DAA2D,SAAAqC,CAAA,CAAM,CAAA,CAAA,CAAA,CAIxF,CCfA,MAAME,EAAe,CACnB,iBACA,eACA,eACA,uBACA,qBACA,kBACF,EAEMC,GAAa,CACjB,iBACA,mBACA,mBACA,kBACA,oBACF,EAIA,SAASC,EAA4CC,EAAoC,CACvF,KAAM,CAACC,EAAUC,CAAW,EAAI3B,EAAAA,SAAS,IAAM4B,EAASH,CAAI,CAAC,EAC7Df,OAAAA,EAAAA,UAAU,IAAM,CACd,MAAMmB,EAAW,IAAI,iBAAiB,IAAMF,EAAYC,EAASH,CAAI,CAAC,CAAC,EACvE,OAAAI,EAAS,QAAQ,SAAS,gBAAiB,CAAE,WAAY,GAAM,gBAAiB,CAAC,OAAO,EAAG,EACpF,IAAMA,EAAS,WAAA,CACxB,EAAG,CAACJ,CAAI,CAAC,EACFC,CACT,CAEA,SAASE,EAAsCH,EAAoC,CACjF,MAAMK,EAAK,iBAAiB,SAAS,eAAe,EAC9CC,EAAM,CAAA,EACZ,UAAWC,KAAKP,EAAOM,EAA+BC,CAAC,EAAIF,EAAG,iBAAiBE,CAAC,EAAE,KAAA,GAAU,OAC5F,OAAOD,CACT,CAEA,SAAwBE,IAAiB,OACvC,MAAM3D,EAAIC,EAAA,EACJ,CAAE,KAAAC,EAAM,UAAAC,EAAW,MAAAC,CAAA,EAAUC,EAAS,CAC1C,SAAUC,EAAU,UAAA,EACpB,QAAS,IAAMC,EAAe,iBAAiB,CAAA,CAChD,EAEKqD,EAASV,EAAeD,EAAU,EAClCF,EAASa,EAAO,gBAAgB,EAChCC,EAAQD,EAAO,kBAAkB,EACjCE,EAAWF,EAAO,kBAAkB,EACpCG,EAAUH,EAAO,iBAAiB,EAClCI,EAAYJ,EAAO,oBAAoB,EAEvCK,EAAUf,EAAeF,CAAY,EACrCkB,EAAkBC,EAAAA,QAAQ,IAAMnB,EAAa,IAAKU,GAAMO,EAAQP,CAAC,CAAC,EAAG,CAACO,CAAO,CAAC,EAE9EG,EAAUD,EAAAA,QAAQ,IACjBjE,EACEA,EAAK,UAAU,IAAKmE,IAAO,CAChC,KAAMlD,EAASkD,EAAE,UAAU,EAC3B,MAAOA,EAAE,WACT,SAAUA,EAAE,YAAA,EACZ,EALgB,CAAA,EAMjB,CAACnE,CAAI,CAAC,EAEHoE,EAAYH,EAAAA,QAAQ,IACnBjE,EACEA,EAAK,QAAQ,IAAKqE,IAAO,CAAE,MAAOA,EAAE,MAAO,GAAI,EAAEA,EAAE,WAAa,SAAW,QAAQ,CAAC,GAAI,EAD7E,CAAA,EAEjB,CAACrE,CAAI,CAAC,EAET,cACG,UAAA,CACC,SAAA,CAAAO,EAAAA,IAAC,MAAA,CAAI,UAAU,mBACb,SAAAA,EAAAA,IAAC+D,GAAA,CACC,MAAOxE,EAAE,YAAY,EACrB,QAASA,EAAE,cAAc,EACzB,MACEE,EACI,CACE,WAAYA,EAAK,WACjB,aAAcA,EAAK,UAAU,OAC7B,cAAeA,EAAK,aAAA,EAEtB,IAAA,CAAA,EAGV,EAECC,SAAcO,EAAA,CAAQ,MAAOV,EAAE,kBAAkB,EAAG,UAAU,QAAQ,EACtEI,GACCI,EAAAA,KAAC,IAAA,CAAE,UAAU,qIACV,SAAA,CAAAR,EAAE,eAAe,EAAE,KAAII,EAAgB,OAAA,EAC1C,EAGDF,GACCM,EAAAA,KAAAiE,WAAA,CACE,SAAA,CAAAjE,EAAAA,KAAC+B,EAAO,IAAP,CACC,QAAQ,SACR,QAAQ,OACR,SAAUmC,EACV,UAAU,iCAEV,SAAA,CAAAjE,EAAAA,IAAC8B,EAAO,IAAP,CAAW,SAAUoC,EACpB,SAAAlE,EAAAA,IAACiC,EAAA,CACC,OAAM,GACN,MAAO1C,EAAE,iBAAiB,EAC1B,MAAOqB,EAAYnB,EAAK,UAAU,EAAE,MAAM,GAAG,EAAE,CAAC,EAChD,KAAMmB,EAAYnB,EAAK,UAAU,EAAE,MAAM,GAAG,EAAE,CAAC,EAC/C,MAAOF,EAAE,2BAA4B,CAAE,EAAGE,EAAK,UAAU,OAAQ,CAAA,CAAA,EAErE,EACAO,EAAAA,IAAC8B,EAAO,IAAP,CAAW,SAAUoC,EACpB,SAAAlE,EAAAA,IAACiC,EAAA,CACC,MAAO1C,EAAE,oBAAoB,EAC7B,MAAOE,EAAK,cAAc,eAAA,EAC1B,MACEA,EAAK,YAAY,CAAC,EACdF,EAAE,oBAAqB,CAAE,KAAMqB,EAAYnB,EAAK,YAAY,CAAC,EAAE,UAAU,CAAA,CAAG,EAC5E,MAAA,CAAA,EAGV,EACAO,EAAAA,IAAC8B,EAAO,IAAP,CAAW,SAAUoC,EACpB,SAAAlE,EAAAA,IAACiC,EAAA,CACC,MAAO1C,EAAE,kBAAkB,EAC3B,MAAOE,EAAK,QAAQ,OACpB,MACEA,EAAK,QAAQ,CAAC,EACV,GAAGA,EAAK,QAAQ,CAAC,EAAE,KAAK,QAAM0E,EAAA1E,EAAK,QAAQ,GAAG,EAAE,IAAlB,YAAA0E,EAAqB,QAAS1E,EAAK,QAAQ,CAAC,EAAE,KAAK,GACjF,MAAA,CAAA,CAER,CACF,CAAA,CAAA,CAAA,EAGFM,EAAAA,KAAC,MAAA,CAAI,UAAU,kCACb,SAAA,CAAAC,EAAAA,IAACoE,EAAA,CACC,MAAO7E,EAAE,wBAAwB,EACjC,SAAUA,EAAE,2BAA2B,EACvC,UAAU,gBAET,SAAAoE,EAAQ,SAAW,EAClB3D,EAAAA,IAACqE,IAAM,EAEPtE,EAAAA,KAAC,MAAA,CAAI,UAAU,0EACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,sDACb,SAAA,CAAAC,MAACsE,GAAoB,MAAM,OAAO,OAAO,OACvC,gBAACC,EAAA,CAAS,OAAQ,CAAE,IAAK,EAAG,MAAO,EAAG,OAAQ,EAAG,KAAM,GACrD,SAAA,CAAAvE,EAAAA,IAACwE,EAAA,CACC,KAAMb,EACN,QAAQ,QACR,QAAQ,OACR,GAAG,MACH,GAAG,MACH,YAAY,MACZ,YAAY,MACZ,aAAc,IACd,OAAQL,EACR,YAAa,EACb,kBAAmB,GAElB,SAAAK,EAAQ,IAAI,CAACc,EAAGC,IACf1E,EAAAA,IAAC2E,EAAA,CAAa,KAAMlB,EAAgBiB,EAAIjB,EAAgB,MAAM,CAAA,EAAnDiB,CAAsD,CAClE,CAAA,CAAA,EAEH1E,EAAAA,IAAC4E,EAAA,CACC,aAAcC,EAAavB,EAASD,EAAUE,CAAS,EACvD,UAAYpB,GAAkBvB,EAAYuB,CAAK,CAAA,CAAA,CACjD,CAAA,CACF,CAAA,CACF,EACApC,EAAAA,KAAC,MAAA,CAAI,UAAU,6FACb,SAAA,CAAAC,MAAC,OAAA,CAAK,UAAU,UAAW,SAAAT,EAAE,wBAAwB,EAAE,QACtD,OAAA,CAAK,UAAU,iFACb,SAAAqB,EAAYnB,EAAK,UAAU,CAAA,CAC9B,CAAA,CAAA,CACF,CAAA,EACF,EACAO,EAAAA,IAAC,KAAA,CAAG,UAAU,sBACX,SAAA2D,EAAQ,MAAM,EAAG,CAAC,EAAE,IAAI,CAACC,EAAGc,IAAM,CACjC,MAAMI,GAAQlB,EAAE,MAAQnE,EAAK,WAAc,KAAK,QAAQ,CAAC,EACzD,OACEM,EAAAA,KAAC,KAAA,CAAW,UAAU,sDACpB,SAAA,CAAAC,EAAAA,IAAC,OAAA,CACC,cAAW,GACX,UAAU,2CACV,MAAO,CAAE,WAAYyD,EAAgBiB,EAAIjB,EAAgB,MAAM,CAAA,CAAE,CAAA,EAEnEzD,EAAAA,IAAC,QAAK,UAAU,8DAA8D,MAAO4D,EAAE,KACpF,WAAE,IAAA,CACL,EACA7D,EAAAA,KAAC,OAAA,CAAK,UAAU,gEACb,SAAA,CAAA+E,EAAI,KAAE/E,EAAAA,KAAC,OAAA,CAAK,UAAU,+BAA+B,SAAA,CAAA,KAAGa,EAAYgD,EAAE,KAAK,CAAA,CAAA,CAAE,CAAA,CAAA,CAChF,CAAA,CAAA,EAXOc,CAYT,CAEJ,CAAC,CAAA,CACH,CAAA,CAAA,CACF,CAAA,CAAA,EAIJ1E,EAAAA,IAACoE,EAAA,CACC,MAAO7E,EAAE,oBAAoB,EAC7B,SAAUA,EAAE,uBAAuB,EACnC,UAAU,gBAET,SAAAsE,EAAU,SAAW,EACpB7D,EAAAA,IAACqE,EAAA,CAAA,CAAM,EAEPrE,EAAAA,IAAC,MAAA,CAAI,UAAU,OACb,SAAAA,EAAAA,IAACsE,EAAA,CAAoB,MAAM,OAAO,OAAO,OACvC,SAAAvE,OAACgF,EAAA,CAAU,KAAMlB,EAAW,OAAQ,CAAE,IAAK,GAAI,MAAO,EAAG,OAAQ,EAAG,KAAM,KACxE,SAAA,CAAA7D,EAAAA,IAAC,OAAA,CACC,SAAAD,EAAAA,KAAC,iBAAA,CAAe,GAAG,cAAc,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IACvD,SAAA,CAAAC,MAAC,QAAK,OAAO,KAAK,UAAWsC,EAAQ,YAAa,IAAM,QACvD,OAAA,CAAK,OAAO,OAAO,UAAWA,EAAQ,YAAa,CAAA,CAAG,CAAA,CAAA,CACzD,CAAA,CACF,EACAtC,EAAAA,IAACgF,EAAA,CACC,QAAQ,QACR,KAAM,CAAE,SAAU,GAAI,KAAM5B,EAAO,WAAY,kBAAA,EAC/C,SAAU,GACV,SAAU,CAAE,OAAQC,CAAA,CAAS,CAAA,EAE/BrD,EAAAA,IAACiF,EAAA,CACC,KAAM,CAAE,SAAU,GAAI,KAAM7B,EAAO,WAAY,kBAAA,EAC/C,SAAU,GACV,SAAU,GACV,MAAO,EAAA,CAAA,EAETpD,EAAAA,IAAC4E,EAAA,CACC,aAAcC,EAAavB,EAASD,EAAUE,CAAS,EACvD,UAAYpB,GAAkB,GAAGA,EAAM,QAAQ,CAAC,CAAC,MACjD,OAAQ,CAAE,OAAQkB,EAAU,gBAAiB,KAAA,CAAM,CAAA,EAErDrD,EAAAA,IAACkF,EAAA,CACC,KAAK,WACL,QAAQ,KACR,OAAQ5C,EACR,YAAa,IACb,KAAK,mBAAA,CAAA,CACP,CAAA,CACF,EACF,CAAA,CACF,CAAA,CAAA,CAEJ,EACF,EAEAvC,EAAAA,KAAC,MAAA,CAAI,UAAU,yBACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,sCACb,SAAA,CAAAC,MAAC,KAAA,CAAG,UAAU,gFACX,SAAAT,EAAE,qBAAqB,EAC1B,EACCE,EAAK,YAAY,OAAS,GACzBO,EAAAA,IAAC,QAAK,UAAU,iFACb,SAAAT,EAAE,oBAAqB,CAAE,EAAGE,EAAK,YAAY,MAAA,CAAQ,CAAA,CACxD,CAAA,EAEJ,EACAO,EAAAA,IAAC,MAAA,CAAI,UAAU,mBAAmB,cAAW,GAAC,EAC7CP,EAAK,YAAY,SAAW,EAC3BO,EAAAA,IAACqE,GAAM,UAAU,MAAA,CAAO,EAExBrE,EAAAA,IAAC,OAAI,UAAU,kCACb,SAAAD,EAAAA,KAAC,QAAA,CAAM,UAAU,6BACf,SAAA,CAAAA,OAAC,WAAA,CACC,SAAA,CAAAC,EAAAA,IAAC,MAAA,CAAI,UAAU,MAAA,CAAO,QACrB,MAAA,EAAI,EACLA,EAAAA,IAAC,MAAA,CAAI,UAAU,WAAA,CAAY,EAC3BA,EAAAA,IAAC,MAAA,CAAI,UAAU,MAAA,CAAO,EACtBA,EAAAA,IAAC,MAAA,CAAI,UAAU,MAAA,CAAO,CAAA,EACxB,EACAA,MAAC,QAAA,CACC,SAAAD,EAAAA,KAAC,KAAA,CAAG,UAAU,YACZ,SAAA,CAAAC,MAAC,KAAA,CAAG,UAAU,oBAAqB,SAAAT,EAAE,cAAc,EAAE,QACpD,KAAA,CAAG,UAAU,oBAAqB,SAAAA,EAAE,gBAAgB,EAAE,QACtD,KAAA,CAAG,UAAU,oBAAqB,SAAAA,EAAE,kBAAkB,EAAE,QACxD,KAAA,CAAG,UAAU,+BAAgC,SAAAA,EAAE,eAAe,EAAE,QAChE,KAAA,CAAG,UAAU,+BAAgC,SAAAA,EAAE,eAAe,CAAA,CAAE,CAAA,CAAA,CACnE,CAAA,CACF,EACAS,EAAAA,IAAC,SAAM,UAAU,0CACd,WAAK,YAAY,IAAI,CAACmF,EAAGT,IAAM,CAC9B,MAAMU,EAAeD,EAAE,aAAeA,EAAE,MACxC,OACApF,EAAAA,KAAC,KAAA,CAEC,UAAU,oFAEV,SAAA,CAAAC,EAAAA,IAAC,KAAA,CAAG,UAAU,yEACX,SAAA,OAAO0E,EAAI,CAAC,EAAE,SAAS,EAAG,GAAG,CAAA,CAChC,EACA1E,EAAAA,IAAC,KAAA,CAAG,UAAU,sBACZ,SAAAA,EAAAA,IAACS,EAAA,CACC,GAAI,aAAa,mBAAmB0E,EAAE,SAAS,CAAC,aAAaA,EAAE,SAAS,GACxE,UAAU,uIACV,MAAOC,EAEN,SAAAA,CAAA,CAAA,EAEL,EACApF,EAAAA,IAAC,KAAA,CAAG,UAAU,yEACZ,SAAAA,EAAAA,IAACS,EAAA,CACC,GAAI,aAAa,mBAAmB0E,EAAE,SAAS,CAAC,GAChD,UAAU,sDACV,MAAOA,EAAE,UAER,SAAAE,GAAgB5F,EAAM0F,EAAE,SAAS,CAAA,CAAA,EAEtC,QACC,KAAA,CAAG,UAAU,0FACX,SAAAxE,EAAmBwE,EAAE,MAAM,EAC9B,QACC,KAAA,CAAG,UAAU,uFACX,SAAAvE,EAAYuE,EAAE,UAAU,CAAA,CAC3B,CAAA,CAAA,EA7BK,GAAGA,EAAE,SAAS,IAAIA,EAAE,SAAS,EAAA,CAgCtC,CAAC,CAAA,CACH,CAAA,CAAA,CACF,CAAA,CACF,CAAA,EAEJ,QAEC7F,GAAA,CAAA,CAAmB,CAAA,CAAA,CACtB,CAAA,EAEJ,CAEJ,CAEA,SAASyE,GAAS,CAChB,MAAA1D,EACA,QAAAiF,EACA,MAAAC,CACF,EAQG,CACD,MAAMhG,EAAIC,EAAA,EACV,OACEO,EAAAA,KAAC,SAAA,CAAO,UAAU,WAChB,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,gDACb,SAAA,CAAAA,EAAAA,KAAC,KAAA,CAAG,UAAU,8HACX,SAAA,CAAAM,EACDL,EAAAA,IAAC,OAAA,CAAK,UAAU,6BAA6B,SAAA,GAAA,CAAC,CAAA,EAChD,EACAA,EAAAA,IAAC,IAAA,CAAE,UAAU,2FACV,SAAAsF,CAAA,CACH,CAAA,EACF,EACCC,GACCxF,EAAAA,KAAC,MAAA,CAAI,UAAU,6DACb,SAAA,CAAAC,EAAAA,IAACwF,EAAA,CAAS,MAAOjG,EAAE,iBAAiB,EAAG,MAAOqB,EAAY2E,EAAM,UAAU,CAAA,CAAG,QAC5EE,EAAA,EAAI,EACLzF,MAACwF,GAAS,MAAOjG,EAAE,oBAAoB,EAAG,MAAOgG,EAAM,aAAc,QACpEE,EAAA,EAAI,EACLzF,EAAAA,IAACwF,EAAA,CAAS,MAAOjG,EAAE,oBAAoB,EAAG,MAAOgG,EAAM,cAAc,gBAAe,CAAG,CAAA,CAAA,CACzF,CAAA,EAEJ,CAEJ,CAEA,SAASV,EAAavB,EAAiBD,EAAkBqC,EAAiC,CACxF,MAAO,CACL,WAAYpC,EACZ,OAAQ,aAAaD,CAAQ,GAC7B,aAAc,EACd,WAAY,mBACZ,SAAU,GACV,MAAOqC,EACP,UAAW,mBAAA,CAEf,CAEA,SAASL,GAAgB5F,EAAiBkG,EAA2B,CACnE,MAAM/B,EAAInE,EAAK,UAAU,KAAMc,GAAQA,EAAI,YAAcoF,CAAS,EAClE,OAAO/B,EAAIlD,EAASkD,EAAE,UAAU,EAAI+B,CACtC,CAEA,SAASjF,EAASqB,EAAqB,CACrC,MAAMC,EAAQD,EAAI,MAAM,QAAQ,EAAE,OAAO,OAAO,EAChD,OAAIC,EAAM,QAAU,EAAUD,EACvB,KAAOC,EAAM,MAAM,EAAE,EAAE,KAAK,GAAG,CACxC,CAEA,SAASoC,EAAK,CACZ,MAAA/D,EACA,SAAAuF,EACA,SAAAC,EACA,UAAAC,EAAY,EACd,EAKG,CACD,OACE/F,EAAAA,KAAC,UAAA,CAAQ,UAAW,oBAAoB+F,CAAS,GAC/C,SAAA,CAAA/F,EAAAA,KAAC,SAAA,CAAO,UAAU,iDAChB,SAAA,CAAAC,EAAAA,IAAC,KAAA,CAAG,UAAU,gFACX,SAAAK,EACH,EACCuF,GACC5F,EAAAA,IAAC,OAAA,CAAK,UAAU,iFACb,SAAA4F,CAAA,CACH,CAAA,EAEJ,EACCC,CAAA,EACH,CAEJ,CAEA,SAASxB,EAAM,CAAE,UAAAyB,EAAY,IAA8B,CACzD,MAAM,EAAItG,EAAA,EACV,OACEQ,MAAC,KAAE,UAAW,8EAA8E8F,CAAS,GAClG,SAAA,EAAE,eAAe,CAAA,CACpB,CAEJ"}
@@ -1,2 +1,2 @@
1
- import{r as x,j as e}from"./react-W0jzChlo.js";import{u as P,a as h}from"./query-C1K1uQRu.js";import{u as C,P as I,c as b,q as u}from"./index-DLATR3tZ.js";import{L as S}from"./router-DfbutHY3.js";import"./vendor-CH80ylbS.js";const E=["skip","overwrite-if-newer","keep-both"],K={skip:"import.policy.skip","overwrite-if-newer":"import.policy.overwrite-if-newer","keep-both":"import.policy.keep-both"},L={create:"import.action.create",overwrite:"import.action.overwrite","keep-both":"import.action.keep-both",skip:"import.action.skip"},y={"existing-project":"import.suggestion.existing-project","original-path":"import.suggestion.original-path","same-basename":"import.suggestion.same-basename"},T={create:"import.memory.create",skip:"import.memory.skip",conflict:"import.memory.conflict"};function q(o){switch(o){case"create":return"border-[var(--color-moss)]/40 bg-[var(--color-moss-soft)] text-[var(--color-fg-primary)]";case"overwrite":return"border-[var(--color-danger)]/40 bg-[var(--color-danger-soft)] text-[var(--color-danger)]";case"keep-both":return"border-[var(--color-accent)]/40 bg-[var(--color-accent-soft)] text-[var(--color-accent-ink)] dark:text-[var(--color-accent)]";default:return"border-[var(--color-hairline-strong)] bg-[var(--color-sunken)] text-[var(--color-fg-muted)]"}}function A(){const o=C(),d=P(),[l,j]=x.useState(""),[i,v]=x.useState(""),[s,w]=x.useState("skip"),[t,g]=x.useState(null),n=h({mutationFn:r=>b("/api/import/preview",{method:"POST",body:JSON.stringify({bundleDir:l.trim(),targetCwd:r.targetCwd,collisionPolicy:r.collisionPolicy})}),onSuccess:r=>{g(r),v(r.remap.targetCwd)}}),a=h({mutationFn:()=>b("/api/import",{method:"POST",body:JSON.stringify({bundleDir:l.trim(),targetCwd:i.trim(),collisionPolicy:s})}),onSuccess:r=>{d.invalidateQueries({queryKey:u.projects()}),d.invalidateQueries({queryKey:u.projectSessions(r.targetProjectId)}),d.invalidateQueries({queryKey:u.projectMemory(r.targetProjectId)}),d.invalidateQueries({queryKey:u.diskUsage()})}});function f(){l.trim()!==""&&(g(null),a.reset(),n.mutate({targetCwd:void 0,collisionPolicy:s}))}function m(r,k){a.reset(),n.mutate({targetCwd:r.trim()||void 0,collisionPolicy:k})}function N(r){w(r),t&&m(i,r)}const c=a.data,p=n.isPending;return e.jsxs("section",{children:[e.jsxs("div",{className:"surface-card p-6",children:[e.jsx(I,{eyebrow:o("nav.import"),title:o("import.title")}),e.jsx("p",{className:"mt-2 max-w-2xl text-sm text-[var(--color-fg-muted)]",children:o("import.tagline")}),e.jsxs("div",{className:"mt-5 flex flex-col gap-2 sm:flex-row",children:[e.jsx("input",{type:"text",value:l,onChange:r=>j(r.target.value),onKeyDown:r=>r.key==="Enter"&&f(),placeholder:o("import.bundlePlaceholder"),spellCheck:!1,"aria-label":o("import.bundleLabel"),className:"min-w-0 flex-1 rounded-[var(--radius-input)] border border-[var(--color-hairline-strong)] bg-[var(--color-canvas)] px-3 py-2 font-mono text-sm text-[var(--color-fg-primary)] outline-none focus:border-[var(--color-accent)]"}),e.jsx("button",{type:"button",onClick:f,disabled:l.trim()===""||p,className:"rounded-[var(--radius-control)] bg-[var(--color-fg-primary)] px-4 py-2 text-sm font-medium text-[var(--color-canvas)] shadow-[var(--shadow-rise)] hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50",children:o(p?"import.btn.loading":t?"import.btn.recheck":"import.btn.load")})]}),n.error&&e.jsx("p",{className:"mt-3 rounded-md border border-[var(--color-danger)]/40 bg-[var(--color-danger-soft)] px-3 py-2 text-sm text-[var(--color-danger)]",children:n.error.message}),!t&&!n.error&&e.jsx("p",{className:"mt-4 text-sm text-[var(--color-fg-muted)]",children:o("import.empty")})]}),t&&e.jsxs("div",{className:"surface-card mt-6 space-y-6 p-6",children:[e.jsx("p",{className:"break-all font-mono text-xs text-[var(--color-fg-muted)]",children:o("import.source",{platform:t.source.platform,cwd:t.source.cwd})}),e.jsxs("div",{children:[e.jsx("span",{className:"eyebrow",children:o("import.targetLabel")}),e.jsxs("div",{className:"mt-1.5 flex flex-col gap-2 sm:flex-row",children:[e.jsx("input",{type:"text",value:i,onChange:r=>v(r.target.value),onKeyDown:r=>r.key==="Enter"&&m(i,s),spellCheck:!1,"aria-label":o("import.targetLabel"),className:"min-w-0 flex-1 rounded-[var(--radius-input)] border border-[var(--color-hairline-strong)] bg-[var(--color-canvas)] px-3 py-2 font-mono text-sm text-[var(--color-fg-primary)] outline-none focus:border-[var(--color-accent)]"}),e.jsx("button",{type:"button",onClick:()=>m(i,s),disabled:p,className:"rounded-[var(--radius-control)] border border-[var(--color-hairline-strong)] px-4 py-2 text-sm text-[var(--color-fg-secondary)] hover:bg-[var(--color-sunken)] disabled:opacity-50",children:o("import.btn.recheck")})]}),e.jsx("p",{className:"mt-1.5 text-xs text-[var(--color-fg-muted)]",children:o("import.targetHint")}),e.jsx("p",{className:"mt-1 font-mono text-[11px] text-[var(--color-fg-faint)]",children:o("import.targetId",{id:t.remap.targetProjectId})}),t.suggestions.length>0&&e.jsxs("div",{className:"mt-2 flex flex-wrap items-center gap-1.5",children:[e.jsx("span",{className:"eyebrow mr-1",children:o("import.suggestions")}),t.suggestions.map(r=>e.jsxs("button",{type:"button",onClick:()=>{v(r.cwd),m(r.cwd,s)},className:"inline-flex items-center gap-1.5 rounded-[var(--radius-control)] border border-[var(--color-hairline-strong)] bg-[var(--color-surface)] px-2.5 py-1 font-mono text-[11px] text-[var(--color-fg-secondary)] hover:border-[var(--color-accent)] hover:text-[var(--color-accent-ink)] dark:hover:text-[var(--color-accent)]",title:o(y[r.reason]),children:[e.jsx("span",{className:"max-w-[20rem] truncate",children:r.cwd}),e.jsxs("span",{className:"text-[var(--color-fg-faint)]",children:["· ",o(y[r.reason])]})]},r.projectId))]})]}),e.jsxs("div",{children:[e.jsx("span",{className:"eyebrow",children:o("import.policyLabel")}),e.jsx("div",{className:"mt-1.5 inline-flex flex-wrap gap-1 rounded-[var(--radius-input)] border border-[var(--color-hairline)] bg-[var(--color-sunken)] p-1",children:E.map(r=>e.jsx("button",{type:"button",onClick:()=>N(r),"aria-pressed":s===r,className:"rounded-[var(--radius-control)] px-3 py-1.5 text-xs font-medium transition "+(s===r?"bg-[var(--color-surface)] text-[var(--color-fg-primary)] shadow-[var(--shadow-rise)]":"text-[var(--color-fg-muted)] hover:text-[var(--color-fg-primary)]"),children:o(K[r])},r))})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-baseline justify-between",children:[e.jsx("span",{className:"eyebrow",children:o("import.sessions.heading")}),e.jsx("span",{className:"font-mono text-[11px] text-[var(--color-fg-faint)]",children:o("import.history",{n:t.historyLinesToAdd})})]}),t.sessions.length===0?e.jsx("p",{className:"mt-2 text-sm text-[var(--color-fg-muted)]",children:o("import.sessions.empty")}):e.jsx("ul",{className:"mt-2 space-y-1.5",children:t.sessions.map(r=>e.jsxs("li",{className:"flex items-center gap-3 rounded-md border border-[var(--color-hairline)] bg-[var(--color-canvas)] px-3 py-2",children:[e.jsx("span",{className:"shrink-0 rounded-[var(--radius-control)] border px-2 py-0.5 text-[10px] font-medium uppercase tracking-[0.12em] "+q(r.action),children:o(L[r.action])}),e.jsxs("span",{className:"min-w-0 flex-1",children:[e.jsx("span",{className:"block truncate text-sm text-[var(--color-fg-primary)]",children:r.title}),e.jsx("span",{className:"block truncate font-mono text-[10.5px] text-[var(--color-fg-faint)]",children:r.newSessionId??r.sessionId})]}),r.reason&&e.jsx("span",{className:"shrink-0 text-[11px] text-[var(--color-fg-muted)]",children:r.reason})]},r.sessionId))})]}),t.memory.length>0&&e.jsxs("div",{children:[e.jsx("span",{className:"eyebrow",children:o("import.memory.heading")}),e.jsx("ul",{className:"mt-2 flex flex-wrap gap-1.5",children:t.memory.map(r=>e.jsxs("li",{className:"inline-flex items-center gap-1.5 rounded-[var(--radius-control)] border border-[var(--color-hairline)] bg-[var(--color-canvas)] px-2.5 py-1 font-mono text-[11px] text-[var(--color-fg-secondary)]",children:[e.jsx("span",{className:"text-[var(--color-fg-primary)]",children:r.filename}),e.jsxs("span",{className:"text-[var(--color-fg-faint)]",children:["·"," ",r.action==="conflict"?o("import.memory.conflict",{name:r.writtenAs??""}):o(T[r.action])]})]},r.filename))})]}),a.error&&e.jsx("p",{className:"rounded-md border border-[var(--color-danger)]/40 bg-[var(--color-danger-soft)] px-3 py-2 text-sm text-[var(--color-danger)]",children:a.error.message}),c?e.jsxs("div",{className:"space-y-3 rounded-[var(--radius-card)] border border-[var(--color-moss)]/40 bg-[var(--color-moss-soft)] px-4 py-3",children:[e.jsx("p",{className:"font-display text-lg font-light text-[var(--color-fg-primary)]",children:o("import.result.title")}),e.jsx("p",{className:"text-sm text-[var(--color-fg-secondary)]",children:o("import.result.summary",{n:c.imported.length,skipped:c.skipped.length,memory:c.memoryWritten.length,lines:c.historyLinesAdded})}),e.jsx(S,{to:`/projects/${encodeURIComponent(c.targetProjectId)}`,className:"inline-flex w-fit items-center gap-2 rounded-[var(--radius-control)] bg-[var(--color-fg-primary)] px-4 py-1.5 text-sm font-medium text-[var(--color-canvas)] hover:opacity-90",children:o("import.result.viewProject")})]}):e.jsx("div",{className:"flex justify-end border-t border-[var(--color-hairline)] pt-4",children:e.jsx("button",{type:"button",onClick:()=>a.mutate(),disabled:i.trim()===""||p||a.isPending,className:"rounded-[var(--radius-control)] bg-[var(--color-fg-primary)] px-5 py-2 text-sm font-medium text-[var(--color-canvas)] shadow-[var(--shadow-rise)] hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50",children:a.isPending?o("import.btn.committing"):o("import.btn.commit")})})]})]})}export{A as default};
2
- //# sourceMappingURL=ImportPage-b8NORa8b.js.map
1
+ import{r as x,j as e}from"./react-CPkiFScu.js";import{b as P,a as b}from"./query-CS7JQ86v.js";import{u as C,P as I,b as h,q as u}from"./index-DTbWl1jb.js";import{L as S}from"./router-DwaHAh1G.js";import"./vendor-Cs8vYp-N.js";const E=["skip","overwrite-if-newer","keep-both"],K={skip:"import.policy.skip","overwrite-if-newer":"import.policy.overwrite-if-newer","keep-both":"import.policy.keep-both"},L={create:"import.action.create",overwrite:"import.action.overwrite","keep-both":"import.action.keep-both",skip:"import.action.skip"},y={"existing-project":"import.suggestion.existing-project","original-path":"import.suggestion.original-path","same-basename":"import.suggestion.same-basename"},T={create:"import.memory.create",skip:"import.memory.skip",conflict:"import.memory.conflict"};function q(o){switch(o){case"create":return"border-[var(--color-moss)]/40 bg-[var(--color-moss-soft)] text-[var(--color-fg-primary)]";case"overwrite":return"border-[var(--color-danger)]/40 bg-[var(--color-danger-soft)] text-[var(--color-danger)]";case"keep-both":return"border-[var(--color-accent)]/40 bg-[var(--color-accent-soft)] text-[var(--color-accent-ink)] dark:text-[var(--color-accent)]";default:return"border-[var(--color-hairline-strong)] bg-[var(--color-sunken)] text-[var(--color-fg-muted)]"}}function A(){const o=C(),d=P(),[l,j]=x.useState(""),[i,v]=x.useState(""),[s,w]=x.useState("skip"),[t,g]=x.useState(null),n=b({mutationFn:r=>h("/api/import/preview",{method:"POST",body:JSON.stringify({bundleDir:l.trim(),targetCwd:r.targetCwd,collisionPolicy:r.collisionPolicy})}),onSuccess:r=>{g(r),v(r.remap.targetCwd)}}),a=b({mutationFn:()=>h("/api/import",{method:"POST",body:JSON.stringify({bundleDir:l.trim(),targetCwd:i.trim(),collisionPolicy:s})}),onSuccess:r=>{d.invalidateQueries({queryKey:u.projects()}),d.invalidateQueries({queryKey:u.projectSessions(r.targetProjectId)}),d.invalidateQueries({queryKey:u.projectMemory(r.targetProjectId)}),d.invalidateQueries({queryKey:u.diskUsage()})}});function f(){l.trim()!==""&&(g(null),a.reset(),n.mutate({targetCwd:void 0,collisionPolicy:s}))}function m(r,k){a.reset(),n.mutate({targetCwd:r.trim()||void 0,collisionPolicy:k})}function N(r){w(r),t&&m(i,r)}const c=a.data,p=n.isPending;return e.jsxs("section",{children:[e.jsxs("div",{className:"surface-card p-6",children:[e.jsx(I,{eyebrow:o("nav.import"),title:o("import.title")}),e.jsx("p",{className:"mt-2 max-w-2xl text-sm text-[var(--color-fg-muted)]",children:o("import.tagline")}),e.jsxs("div",{className:"mt-5 flex flex-col gap-2 sm:flex-row",children:[e.jsx("input",{type:"text",value:l,onChange:r=>j(r.target.value),onKeyDown:r=>r.key==="Enter"&&f(),placeholder:o("import.bundlePlaceholder"),spellCheck:!1,"aria-label":o("import.bundleLabel"),className:"min-w-0 flex-1 rounded-[var(--radius-input)] border border-[var(--color-hairline-strong)] bg-[var(--color-canvas)] px-3 py-2 font-mono text-sm text-[var(--color-fg-primary)] outline-none focus:border-[var(--color-accent)]"}),e.jsx("button",{type:"button",onClick:f,disabled:l.trim()===""||p,className:"rounded-[var(--radius-control)] bg-[var(--color-fg-primary)] px-4 py-2 text-sm font-medium text-[var(--color-canvas)] shadow-[var(--shadow-rise)] hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50",children:o(p?"import.btn.loading":t?"import.btn.recheck":"import.btn.load")})]}),n.error&&e.jsx("p",{className:"mt-3 rounded-md border border-[var(--color-danger)]/40 bg-[var(--color-danger-soft)] px-3 py-2 text-sm text-[var(--color-danger)]",children:n.error.message}),!t&&!n.error&&e.jsx("p",{className:"mt-4 text-sm text-[var(--color-fg-muted)]",children:o("import.empty")})]}),t&&e.jsxs("div",{className:"surface-card mt-6 space-y-6 p-6",children:[e.jsx("p",{className:"break-all font-mono text-xs text-[var(--color-fg-muted)]",children:o("import.source",{platform:t.source.platform,cwd:t.source.cwd})}),e.jsxs("div",{children:[e.jsx("span",{className:"eyebrow",children:o("import.targetLabel")}),e.jsxs("div",{className:"mt-1.5 flex flex-col gap-2 sm:flex-row",children:[e.jsx("input",{type:"text",value:i,onChange:r=>v(r.target.value),onKeyDown:r=>r.key==="Enter"&&m(i,s),spellCheck:!1,"aria-label":o("import.targetLabel"),className:"min-w-0 flex-1 rounded-[var(--radius-input)] border border-[var(--color-hairline-strong)] bg-[var(--color-canvas)] px-3 py-2 font-mono text-sm text-[var(--color-fg-primary)] outline-none focus:border-[var(--color-accent)]"}),e.jsx("button",{type:"button",onClick:()=>m(i,s),disabled:p,className:"rounded-[var(--radius-control)] border border-[var(--color-hairline-strong)] px-4 py-2 text-sm text-[var(--color-fg-secondary)] hover:bg-[var(--color-sunken)] disabled:opacity-50",children:o("import.btn.recheck")})]}),e.jsx("p",{className:"mt-1.5 text-xs text-[var(--color-fg-muted)]",children:o("import.targetHint")}),e.jsx("p",{className:"mt-1 font-mono text-[11px] text-[var(--color-fg-faint)]",children:o("import.targetId",{id:t.remap.targetProjectId})}),t.suggestions.length>0&&e.jsxs("div",{className:"mt-2 flex flex-wrap items-center gap-1.5",children:[e.jsx("span",{className:"eyebrow mr-1",children:o("import.suggestions")}),t.suggestions.map(r=>e.jsxs("button",{type:"button",onClick:()=>{v(r.cwd),m(r.cwd,s)},className:"inline-flex items-center gap-1.5 rounded-[var(--radius-control)] border border-[var(--color-hairline-strong)] bg-[var(--color-surface)] px-2.5 py-1 font-mono text-[11px] text-[var(--color-fg-secondary)] hover:border-[var(--color-accent)] hover:text-[var(--color-accent-ink)] dark:hover:text-[var(--color-accent)]",title:o(y[r.reason]),children:[e.jsx("span",{className:"max-w-[20rem] truncate",children:r.cwd}),e.jsxs("span",{className:"text-[var(--color-fg-faint)]",children:["· ",o(y[r.reason])]})]},r.projectId))]})]}),e.jsxs("div",{children:[e.jsx("span",{className:"eyebrow",children:o("import.policyLabel")}),e.jsx("div",{className:"mt-1.5 inline-flex flex-wrap gap-1 rounded-[var(--radius-input)] border border-[var(--color-hairline)] bg-[var(--color-sunken)] p-1",children:E.map(r=>e.jsx("button",{type:"button",onClick:()=>N(r),"aria-pressed":s===r,className:"rounded-[var(--radius-control)] px-3 py-1.5 text-xs font-medium transition "+(s===r?"bg-[var(--color-surface)] text-[var(--color-fg-primary)] shadow-[var(--shadow-rise)]":"text-[var(--color-fg-muted)] hover:text-[var(--color-fg-primary)]"),children:o(K[r])},r))})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-baseline justify-between",children:[e.jsx("span",{className:"eyebrow",children:o("import.sessions.heading")}),e.jsx("span",{className:"font-mono text-[11px] text-[var(--color-fg-faint)]",children:o("import.history",{n:t.historyLinesToAdd})})]}),t.sessions.length===0?e.jsx("p",{className:"mt-2 text-sm text-[var(--color-fg-muted)]",children:o("import.sessions.empty")}):e.jsx("ul",{className:"mt-2 space-y-1.5",children:t.sessions.map(r=>e.jsxs("li",{className:"flex items-center gap-3 rounded-md border border-[var(--color-hairline)] bg-[var(--color-canvas)] px-3 py-2",children:[e.jsx("span",{className:"shrink-0 rounded-[var(--radius-control)] border px-2 py-0.5 text-[10px] font-medium uppercase tracking-[0.12em] "+q(r.action),children:o(L[r.action])}),e.jsxs("span",{className:"min-w-0 flex-1",children:[e.jsx("span",{className:"block truncate text-sm text-[var(--color-fg-primary)]",children:r.title}),e.jsx("span",{className:"block truncate font-mono text-[10.5px] text-[var(--color-fg-faint)]",children:r.newSessionId??r.sessionId})]}),r.reason&&e.jsx("span",{className:"shrink-0 text-[11px] text-[var(--color-fg-muted)]",children:r.reason})]},r.sessionId))})]}),t.memory.length>0&&e.jsxs("div",{children:[e.jsx("span",{className:"eyebrow",children:o("import.memory.heading")}),e.jsx("ul",{className:"mt-2 flex flex-wrap gap-1.5",children:t.memory.map(r=>e.jsxs("li",{className:"inline-flex items-center gap-1.5 rounded-[var(--radius-control)] border border-[var(--color-hairline)] bg-[var(--color-canvas)] px-2.5 py-1 font-mono text-[11px] text-[var(--color-fg-secondary)]",children:[e.jsx("span",{className:"text-[var(--color-fg-primary)]",children:r.filename}),e.jsxs("span",{className:"text-[var(--color-fg-faint)]",children:["·"," ",r.action==="conflict"?o("import.memory.conflict",{name:r.writtenAs??""}):o(T[r.action])]})]},r.filename))})]}),a.error&&e.jsx("p",{className:"rounded-md border border-[var(--color-danger)]/40 bg-[var(--color-danger-soft)] px-3 py-2 text-sm text-[var(--color-danger)]",children:a.error.message}),c?e.jsxs("div",{className:"space-y-3 rounded-[var(--radius-card)] border border-[var(--color-moss)]/40 bg-[var(--color-moss-soft)] px-4 py-3",children:[e.jsx("p",{className:"font-display text-lg font-light text-[var(--color-fg-primary)]",children:o("import.result.title")}),e.jsx("p",{className:"text-sm text-[var(--color-fg-secondary)]",children:o("import.result.summary",{n:c.imported.length,skipped:c.skipped.length,memory:c.memoryWritten.length,lines:c.historyLinesAdded})}),e.jsx(S,{to:`/projects/${encodeURIComponent(c.targetProjectId)}`,className:"inline-flex w-fit items-center gap-2 rounded-[var(--radius-control)] bg-[var(--color-fg-primary)] px-4 py-1.5 text-sm font-medium text-[var(--color-canvas)] hover:opacity-90",children:o("import.result.viewProject")})]}):e.jsx("div",{className:"flex justify-end border-t border-[var(--color-hairline)] pt-4",children:e.jsx("button",{type:"button",onClick:()=>a.mutate(),disabled:i.trim()===""||p||a.isPending,className:"rounded-[var(--radius-control)] bg-[var(--color-fg-primary)] px-5 py-2 text-sm font-medium text-[var(--color-canvas)] shadow-[var(--shadow-rise)] hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50",children:a.isPending?o("import.btn.committing"):o("import.btn.commit")})})]})]})}export{A as default};
2
+ //# sourceMappingURL=ImportPage-Cwq5bx7G.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ImportPage-Cwq5bx7G.js","sources":["../../web/src/routes/ImportPage.tsx"],"sourcesContent":["import { useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useState } from 'react';\nimport { Link } from 'react-router-dom';\nimport PageHeader from '../components/PageHeader.tsx';\nimport {\n api,\n type ImportCollisionPolicy,\n type ImportPreviewResult,\n type ImportResult,\n type ImportSessionAction,\n} from '../lib/api.ts';\nimport { useT } from '../lib/i18n.ts';\nimport { queryKeys } from '../lib/query-keys.ts';\n\nconst POLICIES: ImportCollisionPolicy[] = ['skip', 'overwrite-if-newer', 'keep-both'];\n\nconst POLICY_KEY = {\n skip: 'import.policy.skip',\n 'overwrite-if-newer': 'import.policy.overwrite-if-newer',\n 'keep-both': 'import.policy.keep-both',\n} as const;\n\nconst ACTION_KEY = {\n create: 'import.action.create',\n overwrite: 'import.action.overwrite',\n 'keep-both': 'import.action.keep-both',\n skip: 'import.action.skip',\n} as const;\n\nconst SUGGEST_KEY = {\n 'existing-project': 'import.suggestion.existing-project',\n 'original-path': 'import.suggestion.original-path',\n 'same-basename': 'import.suggestion.same-basename',\n} as const;\n\nconst MEM_KEY = {\n create: 'import.memory.create',\n skip: 'import.memory.skip',\n conflict: 'import.memory.conflict',\n} as const;\n\nfunction actionTone(action: ImportSessionAction): string {\n switch (action) {\n case 'create':\n return 'border-[var(--color-moss)]/40 bg-[var(--color-moss-soft)] text-[var(--color-fg-primary)]';\n case 'overwrite':\n return 'border-[var(--color-danger)]/40 bg-[var(--color-danger-soft)] text-[var(--color-danger)]';\n case 'keep-both':\n return 'border-[var(--color-accent)]/40 bg-[var(--color-accent-soft)] text-[var(--color-accent-ink)] dark:text-[var(--color-accent)]';\n default:\n return 'border-[var(--color-hairline-strong)] bg-[var(--color-sunken)] text-[var(--color-fg-muted)]';\n }\n}\n\nexport default function ImportPage() {\n const t = useT();\n const queryClient = useQueryClient();\n\n const [bundleDir, setBundleDir] = useState('');\n const [targetCwd, setTargetCwd] = useState('');\n const [policy, setPolicy] = useState<ImportCollisionPolicy>('skip');\n const [preview, setPreview] = useState<ImportPreviewResult | null>(null);\n\n const previewMutation = useMutation({\n mutationFn: (vars: { targetCwd?: string; collisionPolicy: ImportCollisionPolicy }) =>\n api<ImportPreviewResult>('/api/import/preview', {\n method: 'POST',\n body: JSON.stringify({\n bundleDir: bundleDir.trim(),\n targetCwd: vars.targetCwd,\n collisionPolicy: vars.collisionPolicy,\n }),\n }),\n onSuccess: (data) => {\n setPreview(data);\n setTargetCwd(data.remap.targetCwd);\n },\n });\n\n const commitMutation = useMutation({\n mutationFn: () =>\n api<ImportResult>('/api/import', {\n method: 'POST',\n body: JSON.stringify({\n bundleDir: bundleDir.trim(),\n targetCwd: targetCwd.trim(),\n collisionPolicy: policy,\n }),\n }),\n onSuccess: (data) => {\n queryClient.invalidateQueries({ queryKey: queryKeys.projects() });\n queryClient.invalidateQueries({ queryKey: queryKeys.projectSessions(data.targetProjectId) });\n queryClient.invalidateQueries({ queryKey: queryKeys.projectMemory(data.targetProjectId) });\n queryClient.invalidateQueries({ queryKey: queryKeys.diskUsage() });\n },\n });\n\n function loadBundle() {\n if (bundleDir.trim() === '') return;\n setPreview(null);\n commitMutation.reset();\n previewMutation.mutate({ targetCwd: undefined, collisionPolicy: policy });\n }\n\n function recheck(nextTarget: string, nextPolicy: ImportCollisionPolicy) {\n commitMutation.reset();\n previewMutation.mutate({\n targetCwd: nextTarget.trim() || undefined,\n collisionPolicy: nextPolicy,\n });\n }\n\n function changePolicy(p: ImportCollisionPolicy) {\n setPolicy(p);\n if (preview) recheck(targetCwd, p);\n }\n\n const result = commitMutation.data;\n const busy = previewMutation.isPending;\n\n return (\n <section>\n <div className=\"surface-card p-6\">\n <PageHeader eyebrow={t('nav.import')} title={t('import.title')} />\n <p className=\"mt-2 max-w-2xl text-sm text-[var(--color-fg-muted)]\">\n {t('import.tagline')}\n </p>\n\n <div className=\"mt-5 flex flex-col gap-2 sm:flex-row\">\n <input\n type=\"text\"\n value={bundleDir}\n onChange={(e) => setBundleDir(e.target.value)}\n onKeyDown={(e) => e.key === 'Enter' && loadBundle()}\n placeholder={t('import.bundlePlaceholder')}\n spellCheck={false}\n aria-label={t('import.bundleLabel')}\n className=\"min-w-0 flex-1 rounded-[var(--radius-input)] border border-[var(--color-hairline-strong)] bg-[var(--color-canvas)] px-3 py-2 font-mono text-sm text-[var(--color-fg-primary)] outline-none focus:border-[var(--color-accent)]\"\n />\n <button\n type=\"button\"\n onClick={loadBundle}\n disabled={bundleDir.trim() === '' || busy}\n className=\"rounded-[var(--radius-control)] bg-[var(--color-fg-primary)] px-4 py-2 text-sm font-medium text-[var(--color-canvas)] shadow-[var(--shadow-rise)] hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {busy ? t('import.btn.loading') : preview ? t('import.btn.recheck') : t('import.btn.load')}\n </button>\n </div>\n\n {previewMutation.error && (\n <p className=\"mt-3 rounded-md border border-[var(--color-danger)]/40 bg-[var(--color-danger-soft)] px-3 py-2 text-sm text-[var(--color-danger)]\">\n {(previewMutation.error as Error).message}\n </p>\n )}\n\n {!preview && !previewMutation.error && (\n <p className=\"mt-4 text-sm text-[var(--color-fg-muted)]\">{t('import.empty')}</p>\n )}\n </div>\n\n {preview && (\n <div className=\"surface-card mt-6 space-y-6 p-6\">\n <p className=\"break-all font-mono text-xs text-[var(--color-fg-muted)]\">\n {t('import.source', { platform: preview.source.platform, cwd: preview.source.cwd })}\n </p>\n\n {/* target */}\n <div>\n <span className=\"eyebrow\">{t('import.targetLabel')}</span>\n <div className=\"mt-1.5 flex flex-col gap-2 sm:flex-row\">\n <input\n type=\"text\"\n value={targetCwd}\n onChange={(e) => setTargetCwd(e.target.value)}\n onKeyDown={(e) => e.key === 'Enter' && recheck(targetCwd, policy)}\n spellCheck={false}\n aria-label={t('import.targetLabel')}\n className=\"min-w-0 flex-1 rounded-[var(--radius-input)] border border-[var(--color-hairline-strong)] bg-[var(--color-canvas)] px-3 py-2 font-mono text-sm text-[var(--color-fg-primary)] outline-none focus:border-[var(--color-accent)]\"\n />\n <button\n type=\"button\"\n onClick={() => recheck(targetCwd, policy)}\n disabled={busy}\n className=\"rounded-[var(--radius-control)] border border-[var(--color-hairline-strong)] px-4 py-2 text-sm text-[var(--color-fg-secondary)] hover:bg-[var(--color-sunken)] disabled:opacity-50\"\n >\n {t('import.btn.recheck')}\n </button>\n </div>\n <p className=\"mt-1.5 text-xs text-[var(--color-fg-muted)]\">{t('import.targetHint')}</p>\n <p className=\"mt-1 font-mono text-[11px] text-[var(--color-fg-faint)]\">\n {t('import.targetId', { id: preview.remap.targetProjectId })}\n </p>\n\n {preview.suggestions.length > 0 && (\n <div className=\"mt-2 flex flex-wrap items-center gap-1.5\">\n <span className=\"eyebrow mr-1\">{t('import.suggestions')}</span>\n {preview.suggestions.map((s) => (\n <button\n key={s.projectId}\n type=\"button\"\n onClick={() => {\n setTargetCwd(s.cwd);\n recheck(s.cwd, policy);\n }}\n className=\"inline-flex items-center gap-1.5 rounded-[var(--radius-control)] border border-[var(--color-hairline-strong)] bg-[var(--color-surface)] px-2.5 py-1 font-mono text-[11px] text-[var(--color-fg-secondary)] hover:border-[var(--color-accent)] hover:text-[var(--color-accent-ink)] dark:hover:text-[var(--color-accent)]\"\n title={t(SUGGEST_KEY[s.reason])}\n >\n <span className=\"max-w-[20rem] truncate\">{s.cwd}</span>\n <span className=\"text-[var(--color-fg-faint)]\">· {t(SUGGEST_KEY[s.reason])}</span>\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* policy */}\n <div>\n <span className=\"eyebrow\">{t('import.policyLabel')}</span>\n <div className=\"mt-1.5 inline-flex flex-wrap gap-1 rounded-[var(--radius-input)] border border-[var(--color-hairline)] bg-[var(--color-sunken)] p-1\">\n {POLICIES.map((p) => (\n <button\n key={p}\n type=\"button\"\n onClick={() => changePolicy(p)}\n aria-pressed={policy === p}\n className={\n 'rounded-[var(--radius-control)] px-3 py-1.5 text-xs font-medium transition ' +\n (policy === p\n ? 'bg-[var(--color-surface)] text-[var(--color-fg-primary)] shadow-[var(--shadow-rise)]'\n : 'text-[var(--color-fg-muted)] hover:text-[var(--color-fg-primary)]')\n }\n >\n {t(POLICY_KEY[p])}\n </button>\n ))}\n </div>\n </div>\n\n {/* sessions */}\n <div>\n <div className=\"flex items-baseline justify-between\">\n <span className=\"eyebrow\">{t('import.sessions.heading')}</span>\n <span className=\"font-mono text-[11px] text-[var(--color-fg-faint)]\">\n {t('import.history', { n: preview.historyLinesToAdd })}\n </span>\n </div>\n {preview.sessions.length === 0 ? (\n <p className=\"mt-2 text-sm text-[var(--color-fg-muted)]\">\n {t('import.sessions.empty')}\n </p>\n ) : (\n <ul className=\"mt-2 space-y-1.5\">\n {preview.sessions.map((s) => (\n <li\n key={s.sessionId}\n className=\"flex items-center gap-3 rounded-md border border-[var(--color-hairline)] bg-[var(--color-canvas)] px-3 py-2\"\n >\n <span\n className={\n 'shrink-0 rounded-[var(--radius-control)] border px-2 py-0.5 text-[10px] font-medium uppercase tracking-[0.12em] ' +\n actionTone(s.action)\n }\n >\n {t(ACTION_KEY[s.action])}\n </span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate text-sm text-[var(--color-fg-primary)]\">\n {s.title}\n </span>\n <span className=\"block truncate font-mono text-[10.5px] text-[var(--color-fg-faint)]\">\n {s.newSessionId ?? s.sessionId}\n </span>\n </span>\n {s.reason && (\n <span className=\"shrink-0 text-[11px] text-[var(--color-fg-muted)]\">\n {s.reason}\n </span>\n )}\n </li>\n ))}\n </ul>\n )}\n </div>\n\n {/* memory */}\n {preview.memory.length > 0 && (\n <div>\n <span className=\"eyebrow\">{t('import.memory.heading')}</span>\n <ul className=\"mt-2 flex flex-wrap gap-1.5\">\n {preview.memory.map((m) => (\n <li\n key={m.filename}\n className=\"inline-flex items-center gap-1.5 rounded-[var(--radius-control)] border border-[var(--color-hairline)] bg-[var(--color-canvas)] px-2.5 py-1 font-mono text-[11px] text-[var(--color-fg-secondary)]\"\n >\n <span className=\"text-[var(--color-fg-primary)]\">{m.filename}</span>\n <span className=\"text-[var(--color-fg-faint)]\">\n ·{' '}\n {m.action === 'conflict'\n ? t('import.memory.conflict', { name: m.writtenAs ?? '' })\n : t(MEM_KEY[m.action])}\n </span>\n </li>\n ))}\n </ul>\n </div>\n )}\n\n {commitMutation.error && (\n <p className=\"rounded-md border border-[var(--color-danger)]/40 bg-[var(--color-danger-soft)] px-3 py-2 text-sm text-[var(--color-danger)]\">\n {(commitMutation.error as Error).message}\n </p>\n )}\n\n {result ? (\n <div className=\"space-y-3 rounded-[var(--radius-card)] border border-[var(--color-moss)]/40 bg-[var(--color-moss-soft)] px-4 py-3\">\n <p className=\"font-display text-lg font-light text-[var(--color-fg-primary)]\">\n {t('import.result.title')}\n </p>\n <p className=\"text-sm text-[var(--color-fg-secondary)]\">\n {t('import.result.summary', {\n n: result.imported.length,\n skipped: result.skipped.length,\n memory: result.memoryWritten.length,\n lines: result.historyLinesAdded,\n })}\n </p>\n <Link\n to={`/projects/${encodeURIComponent(result.targetProjectId)}`}\n className=\"inline-flex w-fit items-center gap-2 rounded-[var(--radius-control)] bg-[var(--color-fg-primary)] px-4 py-1.5 text-sm font-medium text-[var(--color-canvas)] hover:opacity-90\"\n >\n {t('import.result.viewProject')}\n </Link>\n </div>\n ) : (\n <div className=\"flex justify-end border-t border-[var(--color-hairline)] pt-4\">\n <button\n type=\"button\"\n onClick={() => commitMutation.mutate()}\n disabled={targetCwd.trim() === '' || busy || commitMutation.isPending}\n className=\"rounded-[var(--radius-control)] bg-[var(--color-fg-primary)] px-5 py-2 text-sm font-medium text-[var(--color-canvas)] shadow-[var(--shadow-rise)] hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {commitMutation.isPending ? t('import.btn.committing') : t('import.btn.commit')}\n </button>\n </div>\n )}\n </div>\n )}\n </section>\n );\n}\n"],"names":["POLICIES","POLICY_KEY","ACTION_KEY","SUGGEST_KEY","MEM_KEY","actionTone","action","ImportPage","t","useT","queryClient","useQueryClient","bundleDir","setBundleDir","useState","targetCwd","setTargetCwd","policy","setPolicy","preview","setPreview","previewMutation","useMutation","vars","api","data","commitMutation","queryKeys","loadBundle","recheck","nextTarget","nextPolicy","changePolicy","p","result","busy","jsxs","jsx","PageHeader","e","s","m","Link"],"mappings":"iOAcA,MAAMA,EAAoC,CAAC,OAAQ,qBAAsB,WAAW,EAE9EC,EAAa,CACjB,KAAM,qBACN,qBAAsB,mCACtB,YAAa,yBACf,EAEMC,EAAa,CACjB,OAAQ,uBACR,UAAW,0BACX,YAAa,0BACb,KAAM,oBACR,EAEMC,EAAc,CAClB,mBAAoB,qCACpB,gBAAiB,kCACjB,gBAAiB,iCACnB,EAEMC,EAAU,CACd,OAAQ,uBACR,KAAM,qBACN,SAAU,wBACZ,EAEA,SAASC,EAAWC,EAAqC,CACvD,OAAQA,EAAA,CACN,IAAK,SACH,MAAO,2FACT,IAAK,YACH,MAAO,2FACT,IAAK,YACH,MAAO,+HACT,QACE,MAAO,6FAAA,CAEb,CAEA,SAAwBC,GAAa,CACnC,MAAMC,EAAIC,EAAA,EACJC,EAAcC,EAAA,EAEd,CAACC,EAAWC,CAAY,EAAIC,EAAAA,SAAS,EAAE,EACvC,CAACC,EAAWC,CAAY,EAAIF,EAAAA,SAAS,EAAE,EACvC,CAACG,EAAQC,CAAS,EAAIJ,EAAAA,SAAgC,MAAM,EAC5D,CAACK,EAASC,CAAU,EAAIN,EAAAA,SAAqC,IAAI,EAEjEO,EAAkBC,EAAY,CAClC,WAAaC,GACXC,EAAyB,sBAAuB,CAC9C,OAAQ,OACR,KAAM,KAAK,UAAU,CACnB,UAAWZ,EAAU,KAAA,EACrB,UAAWW,EAAK,UAChB,gBAAiBA,EAAK,eAAA,CACvB,CAAA,CACF,EACH,UAAYE,GAAS,CACnBL,EAAWK,CAAI,EACfT,EAAaS,EAAK,MAAM,SAAS,CACnC,CAAA,CACD,EAEKC,EAAiBJ,EAAY,CACjC,WAAY,IACVE,EAAkB,cAAe,CAC/B,OAAQ,OACR,KAAM,KAAK,UAAU,CACnB,UAAWZ,EAAU,KAAA,EACrB,UAAWG,EAAU,KAAA,EACrB,gBAAiBE,CAAA,CAClB,CAAA,CACF,EACH,UAAYQ,GAAS,CACnBf,EAAY,kBAAkB,CAAE,SAAUiB,EAAU,SAAA,EAAY,EAChEjB,EAAY,kBAAkB,CAAE,SAAUiB,EAAU,gBAAgBF,EAAK,eAAe,EAAG,EAC3Ff,EAAY,kBAAkB,CAAE,SAAUiB,EAAU,cAAcF,EAAK,eAAe,EAAG,EACzFf,EAAY,kBAAkB,CAAE,SAAUiB,EAAU,UAAA,EAAa,CACnE,CAAA,CACD,EAED,SAASC,GAAa,CAChBhB,EAAU,KAAA,IAAW,KACzBQ,EAAW,IAAI,EACfM,EAAe,MAAA,EACfL,EAAgB,OAAO,CAAE,UAAW,OAAW,gBAAiBJ,EAAQ,EAC1E,CAEA,SAASY,EAAQC,EAAoBC,EAAmC,CACtEL,EAAe,MAAA,EACfL,EAAgB,OAAO,CACrB,UAAWS,EAAW,KAAA,GAAU,OAChC,gBAAiBC,CAAA,CAClB,CACH,CAEA,SAASC,EAAaC,EAA0B,CAC9Cf,EAAUe,CAAC,EACPd,GAASU,EAAQd,EAAWkB,CAAC,CACnC,CAEA,MAAMC,EAASR,EAAe,KACxBS,EAAOd,EAAgB,UAE7B,cACG,UAAA,CACC,SAAA,CAAAe,EAAAA,KAAC,MAAA,CAAI,UAAU,mBACb,SAAA,CAAAC,MAACC,EAAA,CAAW,QAAS9B,EAAE,YAAY,EAAG,MAAOA,EAAE,cAAc,EAAG,QAC/D,IAAA,CAAE,UAAU,sDACV,SAAAA,EAAE,gBAAgB,EACrB,EAEA4B,EAAAA,KAAC,MAAA,CAAI,UAAU,uCACb,SAAA,CAAAC,EAAAA,IAAC,QAAA,CACC,KAAK,OACL,MAAOzB,EACP,SAAW2B,GAAM1B,EAAa0B,EAAE,OAAO,KAAK,EAC5C,UAAYA,GAAMA,EAAE,MAAQ,SAAWX,EAAA,EACvC,YAAapB,EAAE,0BAA0B,EACzC,WAAY,GACZ,aAAYA,EAAE,oBAAoB,EAClC,UAAU,+NAAA,CAAA,EAEZ6B,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,QAAST,EACT,SAAUhB,EAAU,KAAA,IAAW,IAAMuB,EACrC,UAAU,qNAET,SAAO3B,EAAP2B,EAAS,qBAAwBhB,EAAY,qBAA0B,iBAA1C,CAA2D,CAAA,CAC3F,EACF,EAECE,EAAgB,OACfgB,MAAC,IAAA,CAAE,UAAU,oIACT,SAAAhB,EAAgB,MAAgB,OAAA,CACpC,EAGD,CAACF,GAAW,CAACE,EAAgB,OAC5BgB,EAAAA,IAAC,IAAA,CAAE,UAAU,4CAA6C,SAAA7B,EAAE,cAAc,CAAA,CAAE,CAAA,EAEhF,EAECW,GACCiB,EAAAA,KAAC,MAAA,CAAI,UAAU,kCACb,SAAA,CAAAC,EAAAA,IAAC,IAAA,CAAE,UAAU,2DACV,SAAA7B,EAAE,gBAAiB,CAAE,SAAUW,EAAQ,OAAO,SAAU,IAAKA,EAAQ,OAAO,GAAA,CAAK,EACpF,SAGC,MAAA,CACC,SAAA,CAAAkB,MAAC,OAAA,CAAK,UAAU,UAAW,SAAA7B,EAAE,oBAAoB,EAAE,EACnD4B,EAAAA,KAAC,MAAA,CAAI,UAAU,yCACb,SAAA,CAAAC,EAAAA,IAAC,QAAA,CACC,KAAK,OACL,MAAOtB,EACP,SAAWwB,GAAMvB,EAAauB,EAAE,OAAO,KAAK,EAC5C,UAAYA,GAAMA,EAAE,MAAQ,SAAWV,EAAQd,EAAWE,CAAM,EAChE,WAAY,GACZ,aAAYT,EAAE,oBAAoB,EAClC,UAAU,+NAAA,CAAA,EAEZ6B,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,QAAS,IAAMR,EAAQd,EAAWE,CAAM,EACxC,SAAUkB,EACV,UAAU,qLAET,WAAE,oBAAoB,CAAA,CAAA,CACzB,EACF,QACC,IAAA,CAAE,UAAU,8CAA+C,SAAA3B,EAAE,mBAAmB,EAAE,EACnF6B,EAAAA,IAAC,IAAA,CAAE,UAAU,0DACV,SAAA7B,EAAE,kBAAmB,CAAE,GAAIW,EAAQ,MAAM,eAAA,CAAiB,CAAA,CAC7D,EAECA,EAAQ,YAAY,OAAS,GAC5BiB,EAAAA,KAAC,MAAA,CAAI,UAAU,2CACb,SAAA,CAAAC,MAAC,OAAA,CAAK,UAAU,eAAgB,SAAA7B,EAAE,oBAAoB,EAAE,EACvDW,EAAQ,YAAY,IAAKqB,GACxBJ,EAAAA,KAAC,SAAA,CAEC,KAAK,SACL,QAAS,IAAM,CACbpB,EAAawB,EAAE,GAAG,EAClBX,EAAQW,EAAE,IAAKvB,CAAM,CACvB,EACA,UAAU,2TACV,MAAOT,EAAEL,EAAYqC,EAAE,MAAM,CAAC,EAE9B,SAAA,CAAAH,EAAAA,IAAC,OAAA,CAAK,UAAU,yBAA0B,SAAAG,EAAE,IAAI,EAChDJ,EAAAA,KAAC,OAAA,CAAK,UAAU,+BAA+B,SAAA,CAAA,KAAG5B,EAAEL,EAAYqC,EAAE,MAAM,CAAC,CAAA,CAAA,CAAE,CAAA,CAAA,EAVtEA,EAAE,SAAA,CAYV,CAAA,CAAA,CACH,CAAA,EAEJ,SAGC,MAAA,CACC,SAAA,CAAAH,MAAC,OAAA,CAAK,UAAU,UAAW,SAAA7B,EAAE,oBAAoB,EAAE,QAClD,MAAA,CAAI,UAAU,sIACZ,SAAAR,EAAS,IAAKiC,GACbI,EAAAA,IAAC,SAAA,CAEC,KAAK,SACL,QAAS,IAAML,EAAaC,CAAC,EAC7B,eAAchB,IAAWgB,EACzB,UACE,+EACChB,IAAWgB,EACR,uFACA,qEAGL,SAAAzB,EAAEP,EAAWgC,CAAC,CAAC,CAAA,EAXXA,CAAA,CAaR,CAAA,CACH,CAAA,EACF,SAGC,MAAA,CACC,SAAA,CAAAG,EAAAA,KAAC,MAAA,CAAI,UAAU,sCACb,SAAA,CAAAC,MAAC,OAAA,CAAK,UAAU,UAAW,SAAA7B,EAAE,yBAAyB,EAAE,EACxD6B,EAAAA,IAAC,OAAA,CAAK,UAAU,qDACb,SAAA7B,EAAE,iBAAkB,CAAE,EAAGW,EAAQ,iBAAA,CAAmB,CAAA,CACvD,CAAA,EACF,EACCA,EAAQ,SAAS,SAAW,QAC1B,IAAA,CAAE,UAAU,4CACV,SAAAX,EAAE,uBAAuB,EAC5B,EAEA6B,MAAC,MAAG,UAAU,mBACX,WAAQ,SAAS,IAAKG,GACrBJ,EAAAA,KAAC,KAAA,CAEC,UAAU,8GAEV,SAAA,CAAAC,EAAAA,IAAC,OAAA,CACC,UACE,mHACAhC,EAAWmC,EAAE,MAAM,EAGpB,SAAAhC,EAAEN,EAAWsC,EAAE,MAAM,CAAC,CAAA,CAAA,EAEzBJ,EAAAA,KAAC,OAAA,CAAK,UAAU,iBACd,SAAA,CAAAC,EAAAA,IAAC,OAAA,CAAK,UAAU,wDACb,SAAAG,EAAE,MACL,QACC,OAAA,CAAK,UAAU,sEACb,SAAAA,EAAE,cAAgBA,EAAE,SAAA,CACvB,CAAA,EACF,EACCA,EAAE,QACDH,EAAAA,IAAC,QAAK,UAAU,oDACb,WAAE,MAAA,CACL,CAAA,CAAA,EAtBGG,EAAE,SAAA,CAyBV,CAAA,CACH,CAAA,EAEJ,EAGCrB,EAAQ,OAAO,OAAS,UACtB,MAAA,CACC,SAAA,CAAAkB,MAAC,OAAA,CAAK,UAAU,UAAW,SAAA7B,EAAE,uBAAuB,EAAE,EACtD6B,EAAAA,IAAC,MAAG,UAAU,8BACX,WAAQ,OAAO,IAAKI,GACnBL,EAAAA,KAAC,KAAA,CAEC,UAAU,qMAEV,SAAA,CAAAC,EAAAA,IAAC,OAAA,CAAK,UAAU,iCAAkC,SAAAI,EAAE,SAAS,EAC7DL,EAAAA,KAAC,OAAA,CAAK,UAAU,+BAA+B,SAAA,CAAA,IAC3C,IACDK,EAAE,SAAW,WACVjC,EAAE,yBAA0B,CAAE,KAAMiC,EAAE,WAAa,EAAA,CAAI,EACvDjC,EAAEJ,EAAQqC,EAAE,MAAM,CAAC,CAAA,CAAA,CACzB,CAAA,CAAA,EATKA,EAAE,QAAA,CAWV,CAAA,CACH,CAAA,EACF,EAGDf,EAAe,OACdW,MAAC,IAAA,CAAE,UAAU,+HACT,SAAAX,EAAe,MAAgB,OAAA,CACnC,EAGDQ,EACCE,EAAAA,KAAC,MAAA,CAAI,UAAU,oHACb,SAAA,CAAAC,MAAC,IAAA,CAAE,UAAU,iEACV,SAAA7B,EAAE,qBAAqB,EAC1B,EACA6B,EAAAA,IAAC,IAAA,CAAE,UAAU,2CACV,WAAE,wBAAyB,CAC1B,EAAGH,EAAO,SAAS,OACnB,QAASA,EAAO,QAAQ,OACxB,OAAQA,EAAO,cAAc,OAC7B,MAAOA,EAAO,iBAAA,CACf,EACH,EACAG,EAAAA,IAACK,EAAA,CACC,GAAI,aAAa,mBAAmBR,EAAO,eAAe,CAAC,GAC3D,UAAU,gLAET,WAAE,2BAA2B,CAAA,CAAA,CAChC,CAAA,CACF,EAEAG,EAAAA,IAAC,MAAA,CAAI,UAAU,gEACb,SAAAA,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,QAAS,IAAMX,EAAe,OAAA,EAC9B,SAAUX,EAAU,KAAA,IAAW,IAAMoB,GAAQT,EAAe,UAC5D,UAAU,qNAET,WAAe,UAAYlB,EAAE,uBAAuB,EAAIA,EAAE,mBAAmB,CAAA,CAAA,CAChF,CACF,CAAA,CAAA,CAEJ,CAAA,EAEJ,CAEJ"}
@@ -0,0 +1,2 @@
1
+ import{r as n,j as r}from"./react-CPkiFScu.js";import{C as c}from"./index-DTbWl1jb.js";import{M as d,r as i}from"./markdown-Bag5rX3T.js";import"./query-CS7JQ86v.js";import"./router-DwaHAh1G.js";import"./vendor-Cs8vYp-N.js";function s(o){let e="";for(const t of o.children)t.type==="text"?e+=t.value:t.type==="element"&&(e+=s(t));return e}function x(o){const e=Array.isArray(o)?o[0]:o;if(!n.isValidElement(e))return null;const t=e.props.className??"",a=/language-([\w+-]+)/.exec(t);return a?a[1]:null}const m={p:({node:o,...e})=>r.jsx("p",{className:"whitespace-pre-wrap break-words",...e}),h1:({node:o,...e})=>r.jsx("h1",{className:"font-display text-[17.5px] font-semibold tracking-[-0.01em] text-[var(--color-fg-primary)]",...e}),h2:({node:o,...e})=>r.jsx("h2",{className:"font-display text-[16.5px] font-semibold tracking-[-0.01em] text-[var(--color-fg-primary)]",...e}),h3:({node:o,...e})=>r.jsx("h3",{className:"font-display text-[15.5px] font-semibold text-[var(--color-fg-primary)]",...e}),h4:({node:o,...e})=>r.jsx("h4",{className:"font-display text-[14.5px] font-semibold text-[var(--color-fg-primary)]",...e}),h5:({node:o,...e})=>r.jsx("h5",{className:"font-display text-[13.5px] font-semibold text-[var(--color-fg-primary)]",...e}),h6:({node:o,...e})=>r.jsx("h6",{className:"eyebrow",...e}),a:({node:o,...e})=>r.jsx("a",{target:"_blank",rel:"noreferrer",className:"break-words text-[var(--color-accent-ink)] underline decoration-[var(--color-accent)]/50 underline-offset-2 transition hover:decoration-[var(--color-accent)] dark:text-[var(--color-accent)]",...e}),strong:({node:o,...e})=>r.jsx("strong",{className:"font-semibold text-[var(--color-fg-primary)]",...e}),del:({node:o,...e})=>r.jsx("del",{className:"text-[var(--color-fg-muted)] line-through decoration-[var(--color-hairline-strong)]",...e}),ul:({node:o,...e})=>r.jsx("ul",{className:"list-disc space-y-1 pl-5 marker:text-[var(--color-fg-faint)]",...e}),ol:({node:o,...e})=>r.jsx("ol",{className:"list-decimal space-y-1 pl-5 marker:font-mono marker:text-[12px] marker:text-[var(--color-fg-muted)]",...e}),li:({node:o,className:e,...t})=>r.jsx("li",{className:"break-words"+(e!=null&&e.includes("task-list-item")?" -ml-5 list-none":""),...t}),input:({node:o,...e})=>e.type==="checkbox"?r.jsx("span",{"aria-hidden":!0,className:"mr-1.5 inline-flex h-[13px] w-[13px] -translate-y-px items-center justify-center rounded-[3px] border align-middle font-mono text-[9px] leading-none "+(e.checked?"border-[var(--color-moss)] bg-[var(--color-moss-soft)] text-[var(--color-moss)]":"border-[var(--color-hairline-strong)] text-transparent"),children:"✓"}):null,blockquote:({node:o,...e})=>r.jsx("blockquote",{className:"space-y-1.5 border-l-2 border-[var(--color-accent)] pl-3 italic text-[var(--color-fg-secondary)]",...e}),hr:({node:o,...e})=>r.jsx("hr",{className:"rule-dotted my-1 border-0",...e}),code:({node:o,...e})=>r.jsx("code",{className:"rounded-[5px] border border-[var(--color-hairline)] bg-[var(--color-sunken)] px-[5px] py-[1.5px] font-mono text-[12.5px] text-[var(--color-accent-ink)] dark:text-[var(--color-accent)]",...e}),pre:({node:o,children:e,...t})=>{const a=x(e),l=o?s(o):"";return r.jsxs("div",{className:"group/code relative overflow-hidden rounded-[var(--radius-control)] border border-[var(--color-hairline)] bg-[var(--color-sunken)]",children:[r.jsxs("div",{className:"absolute right-1.5 top-1.5 z-[1] flex items-center gap-1.5",children:[a&&r.jsx("span",{className:"rounded-sm bg-[var(--color-surface)]/85 px-1.5 py-0.5 font-mono text-[9.5px] uppercase tracking-[0.14em] text-[var(--color-fg-faint)]",children:a}),r.jsx("span",{className:"opacity-0 transition group-hover/code:opacity-100",children:r.jsx(c,{text:l})})]}),r.jsx("pre",{className:"overflow-x-auto px-3.5 py-3 font-mono text-[12px] leading-[1.6] text-[var(--color-fg-primary)] [&_code]:rounded-none [&_code]:border-0 [&_code]:bg-transparent [&_code]:p-0 [&_code]:text-[12px] [&_code]:text-inherit",...t,children:e})]})},table:({node:o,...e})=>r.jsx("div",{className:"overflow-x-auto",children:r.jsx("table",{className:"w-max min-w-[50%] border-collapse text-[13.5px]",...e})}),th:({node:o,...e})=>r.jsx("th",{className:"border-b border-[var(--color-hairline-strong)] px-2.5 py-1.5 text-left text-[12.5px] font-semibold text-[var(--color-fg-secondary)]",...e}),td:({node:o,...e})=>r.jsx("td",{className:"border-b border-[var(--color-hairline)] px-2.5 py-1.5 align-top",...e}),img:({node:o,...e})=>r.jsx("img",{loading:"lazy",className:"my-1 max-w-full rounded-[var(--radius-control)] border border-[var(--color-hairline)]",...e})},p=[i];function f({text:o}){return r.jsx("div",{className:"space-y-2.5 break-words text-[14.5px] leading-relaxed",children:r.jsx(d,{remarkPlugins:p,components:m,children:o})})}const j=n.memo(f);export{j as default};
2
+ //# sourceMappingURL=MarkdownContent-BFu7Nkk_.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MarkdownContent-BFu7Nkk_.js","sources":["../../web/src/components/MarkdownContent.tsx"],"sourcesContent":["import type { Element } from 'hast';\nimport { isValidElement, memo, type ReactNode } from 'react';\nimport ReactMarkdown, { type Components } from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport type { PluggableList } from 'unified';\nimport { CopyButton } from './ToolBlock.tsx';\n\n// Claude 回复(assistant text block)的 markdown 排版。仅在【非搜索态】渲染:\n// 搜索时上层退回 plain HighlightedText(见 MessageBubble 的 markdown 开关),\n// 所以本组件不需要处理搜索高亮——「读用富渲染,搜用原文高亮」。\n// 仅 assistant 走这里:用户输入是终端原文,渲染成 markdown 会误伤 `*args`、路径等字面量。\n// 安全性:不挂 rehype-raw,react-markdown 默认不渲染原始 HTML(显示为字面文本),\n// URL 走默认 defaultUrlTransform 白名单。\n//\n// 本组件经 MessageBubble lazy() 引入,连同 remark/micromark 系列被 vite 拆进\n// `markdown` chunk(见 vite.config.ts),不进首屏。\n\n/** 收集 hast 节点下全部文本,供代码块复制按钮取原文。 */\nfunction hastText(node: Element): string {\n let out = '';\n for (const child of node.children) {\n if (child.type === 'text') out += child.value;\n else if (child.type === 'element') out += hastText(child);\n }\n return out;\n}\n\n/** 从 <pre> 的子 <code> 上取 ```lang 标注(className: language-x)。 */\nfunction codeLang(children: ReactNode): string | null {\n const el = Array.isArray(children) ? children[0] : children;\n if (!isValidElement(el)) return null;\n const cls = (el.props as { className?: string }).className ?? '';\n const m = /language-([\\w+-]+)/.exec(cls);\n return m ? m[1]! : null;\n}\n\n// 元素 → 设计 token 的映射。标题在气泡语境内整体缩阶;代码用 mono + sunken;\n// 引用沿用 tagline 的 accent 左边框 + 斜体;hr 复用 rule-dotted。\nconst COMPONENTS: Components = {\n p: ({ node: _n, ...props }) => (\n <p className=\"whitespace-pre-wrap break-words\" {...props} />\n ),\n h1: ({ node: _n, ...props }) => (\n <h1 className=\"font-display text-[17.5px] font-semibold tracking-[-0.01em] text-[var(--color-fg-primary)]\" {...props} />\n ),\n h2: ({ node: _n, ...props }) => (\n <h2 className=\"font-display text-[16.5px] font-semibold tracking-[-0.01em] text-[var(--color-fg-primary)]\" {...props} />\n ),\n h3: ({ node: _n, ...props }) => (\n <h3 className=\"font-display text-[15.5px] font-semibold text-[var(--color-fg-primary)]\" {...props} />\n ),\n h4: ({ node: _n, ...props }) => (\n <h4 className=\"font-display text-[14.5px] font-semibold text-[var(--color-fg-primary)]\" {...props} />\n ),\n h5: ({ node: _n, ...props }) => (\n <h5 className=\"font-display text-[13.5px] font-semibold text-[var(--color-fg-primary)]\" {...props} />\n ),\n h6: ({ node: _n, ...props }) => <h6 className=\"eyebrow\" {...props} />,\n a: ({ node: _n, ...props }) => (\n <a\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"break-words text-[var(--color-accent-ink)] underline decoration-[var(--color-accent)]/50 underline-offset-2 transition hover:decoration-[var(--color-accent)] dark:text-[var(--color-accent)]\"\n {...props}\n />\n ),\n strong: ({ node: _n, ...props }) => (\n <strong className=\"font-semibold text-[var(--color-fg-primary)]\" {...props} />\n ),\n del: ({ node: _n, ...props }) => (\n <del className=\"text-[var(--color-fg-muted)] line-through decoration-[var(--color-hairline-strong)]\" {...props} />\n ),\n ul: ({ node: _n, ...props }) => (\n <ul className=\"list-disc space-y-1 pl-5 marker:text-[var(--color-fg-faint)]\" {...props} />\n ),\n ol: ({ node: _n, ...props }) => (\n <ol className=\"list-decimal space-y-1 pl-5 marker:font-mono marker:text-[12px] marker:text-[var(--color-fg-muted)]\" {...props} />\n ),\n li: ({ node: _n, className, ...props }) => (\n <li\n className={\n 'break-words' +\n (className?.includes('task-list-item') ? ' -ml-5 list-none' : '')\n }\n {...props}\n />\n ),\n // GFM 任务清单的 checkbox:换成与 TodoWrite 同语言的方框打钩。\n input: ({ node: _n, ...props }) =>\n props.type === 'checkbox' ? (\n <span\n aria-hidden\n className={\n 'mr-1.5 inline-flex h-[13px] w-[13px] -translate-y-px items-center justify-center rounded-[3px] border align-middle font-mono text-[9px] leading-none ' +\n (props.checked\n ? 'border-[var(--color-moss)] bg-[var(--color-moss-soft)] text-[var(--color-moss)]'\n : 'border-[var(--color-hairline-strong)] text-transparent')\n }\n >\n ✓\n </span>\n ) : null,\n blockquote: ({ node: _n, ...props }) => (\n <blockquote\n className=\"space-y-1.5 border-l-2 border-[var(--color-accent)] pl-3 italic text-[var(--color-fg-secondary)]\"\n {...props}\n />\n ),\n hr: ({ node: _n, ...props }) => <hr className=\"rule-dotted my-1 border-0\" {...props} />,\n code: ({ node: _n, ...props }) => (\n <code\n className=\"rounded-[5px] border border-[var(--color-hairline)] bg-[var(--color-sunken)] px-[5px] py-[1.5px] font-mono text-[12.5px] text-[var(--color-accent-ink)] dark:text-[var(--color-accent)]\"\n {...props}\n />\n ),\n pre: ({ node, children, ...props }) => {\n const lang = codeLang(children);\n const raw = node ? hastText(node) : '';\n return (\n <div className=\"group/code relative overflow-hidden rounded-[var(--radius-control)] border border-[var(--color-hairline)] bg-[var(--color-sunken)]\">\n <div className=\"absolute right-1.5 top-1.5 z-[1] flex items-center gap-1.5\">\n {lang && (\n <span className=\"rounded-sm bg-[var(--color-surface)]/85 px-1.5 py-0.5 font-mono text-[9.5px] uppercase tracking-[0.14em] text-[var(--color-fg-faint)]\">\n {lang}\n </span>\n )}\n <span className=\"opacity-0 transition group-hover/code:opacity-100\">\n <CopyButton text={raw} />\n </span>\n </div>\n {/* 行内 code 的 chip 样式在代码块内用后代选择器整体中和。 */}\n <pre\n className=\"overflow-x-auto px-3.5 py-3 font-mono text-[12px] leading-[1.6] text-[var(--color-fg-primary)] [&_code]:rounded-none [&_code]:border-0 [&_code]:bg-transparent [&_code]:p-0 [&_code]:text-[12px] [&_code]:text-inherit\"\n {...props}\n >\n {children}\n </pre>\n </div>\n );\n },\n table: ({ node: _n, ...props }) => (\n <div className=\"overflow-x-auto\">\n <table className=\"w-max min-w-[50%] border-collapse text-[13.5px]\" {...props} />\n </div>\n ),\n th: ({ node: _n, ...props }) => (\n <th\n className=\"border-b border-[var(--color-hairline-strong)] px-2.5 py-1.5 text-left text-[12.5px] font-semibold text-[var(--color-fg-secondary)]\"\n {...props}\n />\n ),\n td: ({ node: _n, ...props }) => (\n <td className=\"border-b border-[var(--color-hairline)] px-2.5 py-1.5 align-top\" {...props} />\n ),\n img: ({ node: _n, ...props }) => (\n <img\n loading=\"lazy\"\n className=\"my-1 max-w-full rounded-[var(--radius-control)] border border-[var(--color-hairline)]\"\n {...props}\n />\n ),\n};\n\nconst REMARK_PLUGINS: PluggableList = [remarkGfm];\n\nfunction MarkdownContent({ text }: { text: string }) {\n return (\n <div className=\"space-y-2.5 break-words text-[14.5px] leading-relaxed\">\n <ReactMarkdown remarkPlugins={REMARK_PLUGINS} components={COMPONENTS}>\n {text}\n </ReactMarkdown>\n </div>\n );\n}\n\n// 时间线一次窗口化渲染 50 条消息,memo 避免轮询引发的全量重解析。\nexport default memo(MarkdownContent);\n"],"names":["hastText","node","out","child","codeLang","children","el","isValidElement","cls","m","COMPONENTS","_n","props","jsx","className","lang","raw","jsxs","CopyButton","REMARK_PLUGINS","remarkGfm","MarkdownContent","text","ReactMarkdown","MarkdownContent_default","memo"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{r as u,j as e}from"./react-W0jzChlo.js";import{b as T}from"./query-C1K1uQRu.js";import{u as y,B as Y,d as Z,P as ee,M as R,S as U,b as C,L as te,a as re,c as O,q as Q}from"./index-DLATR3tZ.js";import{b as ne,c as oe}from"./router-DfbutHY3.js";import"./vendor-CH80ylbS.js";const se=/^[\s*-]*\[(?<title>[^\]]+)\]\((?<href>[^)]+)\)\s*[—–\-:]?\s*(?<hook>.*)$/;function we(){const t=y(),{projectId:r}=ne(),i=r??"",[s,l]=oe(),c=T({queryKey:Q.projectMemory(i),queryFn:()=>O(`/api/projects/${encodeURIComponent(i)}/memory`),enabled:!!i}),a=T({queryKey:Q.projects(),queryFn:()=>O("/api/projects")}),d=u.useMemo(()=>{var n;return(n=a.data)==null?void 0:n.find(p=>p.id===i)},[a.data,i]),o=c.data,m=u.useMemo(()=>(o==null?void 0:o.entries)??[],[o==null?void 0:o.entries]),x=u.useMemo(()=>fe((o==null?void 0:o.index)??null),[o==null?void 0:o.index]),f=u.useMemo(()=>{const n=new Map;for(const p of x)p.link&&n.set(p.link.href,p.link.hook);return n},[x]),{rows:h,orphans:j}=u.useMemo(()=>he(x,m),[x,m]),v=s.get("entry"),b=s.get("view"),H=v!==null||b==="raw";function V(n){const p=new URLSearchParams(s);p.set("entry",n),p.delete("view"),l(p)}function _(){const n=new URLSearchParams(s);n.set("view","raw"),n.delete("entry"),l(n)}function F(){const n=new URLSearchParams(s);n.delete("entry"),n.delete("view"),l(n)}const g=u.useMemo(()=>b==="raw"?{kind:"raw"}:v?{kind:"entry",entry:m.find(p=>p.filename===v)??null,filename:v}:null,[v,b,m]),[L,G]=u.useState(""),k=L.trim().toLowerCase(),w=k.length>0,I=u.useMemo(()=>w?h.filter(n=>n.kind==="entry"&&z(n.entry,n.hook,k)):h,[h,w,k]),E=u.useMemo(()=>w?j.filter(n=>z(n,"",k)):j,[j,w,k]),N=m.length,B=!!(o!=null&&o.index),S=N>0||B,J=I.filter(n=>n.kind==="entry").length+E.length,P=(d==null?void 0:d.decodedCwd)??i,q=P.split(/[\\/]+/).filter(Boolean),X=q.at(-1)??P,$=q.slice(0,-1).join("/"),D=u.useMemo(()=>{let n=null;for(const p of m){if(!p.mtime)continue;const M=Date.parse(p.mtime);Number.isFinite(M)&&(n===null||M>n)&&(n=M)}return n?new Date(n).toISOString():null},[m]),K=u.useMemo(()=>{const n=new Set;for(const p of m)n.add(p.type??"other");return n.size},[m]);return e.jsxs("section",{children:[e.jsx(Y,{items:[{label:t("session.crumbProjects"),to:"/"},{label:X,to:`/projects/${encodeURIComponent(i)}`,mono:!0,icon:e.jsx(Z,{})},{label:t("memory.title")}]}),e.jsx("div",{className:"surface-card mt-6 p-6",children:e.jsx(ee,{eyebrow:e.jsx("span",{className:"inline-flex items-center gap-2",children:$?e.jsxs("span",{className:"font-mono normal-case tracking-normal",children:[$,"/"]}):t("memory.action.open")}),title:t("memory.title"),meta:o?e.jsxs(e.Fragment,{children:[e.jsx(R,{label:t("memory.meta.entries"),value:N}),K>0&&e.jsxs(e.Fragment,{children:[e.jsx(U,{}),e.jsx(R,{label:t("memory.meta.types"),value:K})]}),D&&e.jsxs(e.Fragment,{children:[e.jsx(U,{}),e.jsx(R,{label:t("memory.meta.lastUpdate"),value:C(D)})]})]}):null})}),c.isLoading&&e.jsx(te,{label:t("memory.loading"),className:"mt-6"}),c.error&&e.jsxs("p",{className:"mt-6 rounded-md border border-[var(--color-danger)]/40 bg-[var(--color-danger-soft)] px-4 py-3 text-sm text-[var(--color-danger)]",children:[t("common.failedMemory"),": ",c.error.message]}),o&&!S&&e.jsx(de,{}),o&&S&&e.jsx(ae,{rows:I,orphans:E,totalMatched:J,totalEntries:N,query:L,onQuery:G,searchActive:w,indexAvailable:B,onOpenEntry:V,onOpenRaw:_}),H&&g&&e.jsx(ie,{target:g,rawIndex:(o==null?void 0:o.index)??"",hookForEntry:g.kind==="entry"&&g.entry?f.get(g.entry.filename)??null:null,onClose:F,onJumpToCover:()=>{F(),requestAnimationFrame(()=>{const n=document.getElementById("memo-index-card");n==null||n.scrollIntoView({behavior:"smooth",block:"start"})})}})]})}function ae({rows:t,orphans:r,totalMatched:i,totalEntries:s,query:l,onQuery:c,searchActive:a,indexAvailable:d,onOpenEntry:o,onOpenRaw:m}){const x=y(),f=a&&i===0;return e.jsxs("div",{id:"memo-index-card",className:"surface-card mt-6 px-7 py-6",children:[e.jsxs("div",{className:"flex items-baseline justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"eyebrow",children:x("memory.cover.title")}),e.jsx("h2",{className:"mt-0.5 font-display text-[18px] font-medium tracking-tight text-[var(--color-fg-primary)]",children:x("memory.cover.subtitle")})]}),d&&e.jsxs("button",{type:"button",onClick:m,className:"font-mono text-[11px] uppercase tracking-[0.16em] text-[var(--color-fg-muted)] hover:text-[var(--color-accent-ink)] dark:hover:text-[var(--color-accent)]",children:[x("memory.cover.viewRaw")," ↗"]})]}),e.jsxs("div",{className:"mt-4 flex flex-wrap items-center gap-3",children:[e.jsxs("div",{className:"flex flex-1 min-w-[14rem] items-center gap-2 border-b border-[var(--color-hairline)] py-1.5 transition focus-within:border-[var(--color-accent)]",children:[e.jsx(xe,{className:"text-[var(--color-fg-muted)]"}),e.jsx("input",{type:"search",value:l,onChange:h=>c(h.target.value),placeholder:x("memory.search.placeholder"),className:"w-full bg-transparent text-sm text-[var(--color-fg-primary)] placeholder:text-[var(--color-fg-faint)] focus:outline-none"})]}),e.jsx("span",{className:"font-mono text-[10.5px] uppercase tracking-[0.18em] tabular-nums text-[var(--color-fg-faint)]",children:a?x("memory.list.count",{n:i,total:s}):`${s} ${x("memory.meta.entries").toLowerCase()}`})]}),e.jsx("div",{className:"rule-dotted mt-5","aria-hidden":!0}),f?e.jsx("p",{className:"mt-6 text-sm text-[var(--color-fg-muted)]",children:x("memory.list.noResults")}):e.jsxs("ul",{className:"mt-3",children:[t.map((h,j)=>e.jsx(W,{row:h,onOpenEntry:o},j)),r.length>0&&e.jsxs(e.Fragment,{children:[!a&&t.length>0&&e.jsx("li",{"aria-hidden":!0,className:"h-3"}),e.jsx("li",{className:"pt-3 pb-2",children:e.jsxs("div",{className:"flex items-baseline gap-3",children:[e.jsx("span",{className:"font-mono text-[10.5px] uppercase tracking-[0.18em] text-[var(--color-fg-faint)]",children:x("memory.cover.orphan")}),e.jsxs("span",{className:"font-mono text-[10.5px] tabular-nums text-[var(--color-fg-faint)]",children:["· ",r.length]}),e.jsx("span",{"aria-hidden":!0,className:"ml-2 h-px flex-1 bg-[var(--color-hairline)]"})]})}),r.map(h=>e.jsx(W,{row:{kind:"entry",entry:h,hook:""},onOpenEntry:o},h.filename))]})]})]})}function W({row:t,onOpenEntry:r}){const i=y();if(t.kind==="spacer")return e.jsx("li",{"aria-hidden":!0,className:"h-2"});if(t.kind==="heading")return e.jsx("li",{className:"pt-4 pb-1",children:e.jsx("div",{className:"font-mono text-[10.5px] uppercase tracking-[0.18em] text-[var(--color-fg-muted)]",children:t.text})});if(t.kind==="text")return e.jsx("li",{className:"px-1 py-0.5 text-[12.5px] text-[var(--color-fg-faint)] whitespace-pre-wrap break-words",children:t.text});if(t.kind==="missing")return e.jsxs("li",{title:i("memory.cover.missingTooltip"),className:"flex items-baseline gap-3 px-2 py-1.5 text-[var(--color-fg-faint)]",children:[e.jsx("span",{className:"text-[14px] font-medium line-through decoration-[var(--color-fg-faint)]/50",children:t.title}),t.hook&&e.jsx("span",{className:"truncate text-[12px]",children:t.hook})]});const s=t.entry,l=s.type??"other",c=s.name??s.filename,a=t.hook||s.description||"";return e.jsx("li",{children:e.jsxs("button",{type:"button",onClick:()=>r(s.filename),className:`memo-row memo-type-${l}`,children:[e.jsx("span",{"aria-hidden":!0,className:"memo-row-dot"}),e.jsxs("div",{className:"memo-row-content",children:[e.jsxs("div",{className:"memo-row-headline",children:[e.jsx("span",{className:"memo-row-title",children:c}),s.mtime&&e.jsx("span",{className:"memo-row-meta-inline",children:C(s.mtime)}),e.jsx(A,{k:l})]}),a&&e.jsx("p",{className:"memo-row-hook",children:a})]}),e.jsx("span",{"aria-hidden":!0,className:"memo-row-chevron",children:"↗"})]})})}function A({k:t}){const r=y(),i=r(t==="user"?"memory.type.user":t==="feedback"?"memory.type.feedback":t==="project"?"memory.type.project":t==="reference"?"memory.type.reference":"memory.type.other");return e.jsx("span",{className:"memo-chip",children:i})}function ie({target:t,rawIndex:r,hookForEntry:i,onClose:s,onJumpToCover:l}){var o;const c=y(),a=u.useRef(null);u.useEffect(()=>{const m=f=>{f.key==="Escape"&&(f.preventDefault(),s())};window.addEventListener("keydown",m);const x=document.body.style.overflow;return document.body.style.overflow="hidden",requestAnimationFrame(()=>{var f;return(f=a.current)==null?void 0:f.focus()}),()=>{window.removeEventListener("keydown",m),document.body.style.overflow=x}},[s]);const d=t.kind==="entry"?((o=t.entry)==null?void 0:o.type)??"other":"reference";return e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"memo-drawer-backdrop",onClick:s,"aria-hidden":!0}),e.jsxs("div",{ref:a,role:"dialog","aria-modal":"true",tabIndex:-1,className:`memo-drawer-panel memo-type-${d} focus:outline-none`,children:[e.jsxs("div",{className:"flex items-start justify-between gap-3 border-b border-[var(--color-hairline)] px-7 pt-7 pb-5",children:[e.jsx("div",{className:"min-w-0 flex-1",children:t.kind==="entry"?e.jsxs(e.Fragment,{children:[e.jsx(A,{k:d}),t.entry?e.jsxs(e.Fragment,{children:[e.jsx("h2",{className:"mt-3 font-display text-[24px] font-light leading-tight tracking-tight text-[var(--color-fg-primary)]",children:t.entry.name??t.entry.filename}),e.jsxs("p",{className:"mt-1.5 font-mono text-[11px] uppercase tracking-[0.16em] text-[var(--color-fg-faint)]",children:[t.entry.filename," · ",re(t.entry.bytes),t.entry.mtime?` · ${C(t.entry.mtime)}`:""]})]}):e.jsxs(e.Fragment,{children:[e.jsx("h2",{className:"mt-3 font-display text-[22px] font-light leading-tight text-[var(--color-fg-primary)]",children:c("memory.drawer.notFound.title")}),e.jsx("p",{className:"mt-1.5 font-mono text-[11px] uppercase tracking-[0.16em] text-[var(--color-fg-faint)]",children:t.filename})]})]}):e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"memo-chip memo-type-reference",children:c("memory.cover.title")}),e.jsx("h2",{className:"mt-3 font-display text-[24px] font-light leading-tight tracking-tight text-[var(--color-fg-primary)]",children:c("memory.raw.title")}),e.jsx("p",{className:"mt-1.5 font-mono text-[11px] uppercase tracking-[0.16em] text-[var(--color-fg-faint)]",children:c("memory.raw.subtitle")})]})}),e.jsx("button",{type:"button",onClick:s,"aria-label":c("memory.drawer.close"),className:"rounded-md p-2 text-[var(--color-fg-muted)] hover:bg-[var(--color-sunken)] hover:text-[var(--color-fg-primary)]",children:e.jsx(pe,{})})]}),e.jsx("div",{className:"flex-1 overflow-y-auto px-7 py-6",children:t.kind==="entry"&&t.entry?e.jsx(le,{entry:t.entry,hookForEntry:i,onJumpToCover:l}):t.kind==="entry"?e.jsx(ce,{filename:t.filename,onJumpToCover:l}):e.jsx(me,{source:r})})]})]})}function le({entry:t,hookForEntry:r,onJumpToCover:i}){const s=y(),l=t.body.trim();return e.jsxs("div",{children:[t.description&&e.jsx("p",{className:"text-[14px] text-[var(--color-fg-secondary)]",children:t.description}),e.jsx("pre",{className:"whitespace-pre-wrap break-words rounded-[var(--radius-input)] border border-[var(--color-hairline)] bg-[var(--color-sunken)] px-4 py-3 font-mono text-[12.5px] leading-[1.65] text-[var(--color-fg-primary)] "+(t.description?"mt-5":""),children:l||"—"}),r&&e.jsxs("div",{className:"mt-7",children:[e.jsx("div",{className:"rule-dotted","aria-hidden":!0}),e.jsxs("div",{className:"mt-4 flex items-baseline justify-between gap-3",children:[e.jsx("div",{className:"eyebrow",children:s("memory.drawer.indexHook")}),e.jsxs("button",{type:"button",onClick:i,className:"font-mono text-[10.5px] uppercase tracking-[0.16em] text-[var(--color-fg-muted)] hover:text-[var(--color-accent-ink)] dark:hover:text-[var(--color-accent)]",children:[s("memory.cover.title")," ↑"]})]}),e.jsx("p",{className:"mt-1.5 text-[13px] text-[var(--color-fg-secondary)]",children:r})]})]})}function ce({filename:t,onJumpToCover:r}){const i=y();return e.jsxs("div",{children:[e.jsx("p",{className:"text-sm text-[var(--color-fg-secondary)]",children:i("memory.drawer.notFound.body")}),e.jsx("p",{className:"mt-3 font-mono text-[12px] text-[var(--color-fg-faint)]",children:t}),e.jsxs("button",{type:"button",onClick:r,className:"mt-5 inline-flex items-center gap-1.5 rounded-[var(--radius-control)] border border-[var(--color-hairline)] px-3 py-1.5 text-[11px] font-medium uppercase tracking-[0.14em] text-[var(--color-fg-secondary)] hover:border-[var(--color-hairline-strong)] hover:text-[var(--color-fg-primary)]",children:[i("memory.cover.title")," ↑"]})]})}function me({source:t}){const r=t.trim();return e.jsx("pre",{className:"whitespace-pre-wrap break-words rounded-[var(--radius-input)] border border-[var(--color-hairline)] bg-[var(--color-sunken)] px-4 py-3 font-mono text-[12.5px] leading-[1.65] text-[var(--color-fg-primary)]",children:r||"—"})}function de(){const t=y();return e.jsxs("div",{className:"surface-card mt-6 px-8 py-14 text-center",children:[e.jsx("div",{className:"mx-auto flex h-12 w-12 items-center justify-center rounded-full border border-[var(--color-hairline)] bg-[var(--color-sunken)] text-[var(--color-fg-muted)]",children:e.jsx(ue,{})}),e.jsx("h2",{className:"mt-5 font-display text-[20px] font-light tracking-tight text-[var(--color-fg-primary)]",children:t("memory.empty.title")}),e.jsx("p",{className:"mx-auto mt-3 max-w-xl text-[13px] leading-relaxed text-[var(--color-fg-secondary)]",children:t("memory.empty.body")})]})}function xe({className:t=""}){return e.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.7",strokeLinecap:"round",className:t,"aria-hidden":!0,children:[e.jsx("circle",{cx:"11",cy:"11",r:"6.2"}),e.jsx("path",{d:"M20 20l-4.3-4.3"})]})}function pe(){return e.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.8",strokeLinecap:"round","aria-hidden":!0,children:e.jsx("path",{d:"M6 6l12 12M18 6L6 18"})})}function ue(){return e.jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.6",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":!0,children:e.jsx("path",{d:"M6 4h12v17l-6-4-6 4z"})})}function z(t,r,i){return[t.name??"",t.filename,t.description??"",t.body,r].some(l=>l.toLowerCase().includes(i))}function he(t,r){const i=new Map(r.map(a=>[a.filename,a])),s=new Set,l=[];for(const a of t){if(a.link){const m=i.get(a.link.href);m?(l.push({kind:"entry",entry:m,hook:a.link.hook}),s.add(m.filename)):l.push({kind:"missing",title:a.link.title,hook:a.link.hook});continue}const d=a.raw.trim();if(!d){l.push({kind:"spacer"});continue}const o=/^(#{1,6})\s+(.+?)\s*$/.exec(d);o?l.push({kind:"heading",text:o[2]}):l.push({kind:"text",text:a.raw})}const c=r.filter(a=>!s.has(a.filename));return{rows:l,orphans:c}}function fe(t){var i,s,l;if(!t)return[];const r=[];for(const c of t.split(/\r?\n/)){const a=c.trimEnd();if(a.trim()===""){const x=r[r.length-1];x&&(x.link||x.raw.trim()!=="")&&r.push({raw:"",link:null});continue}const d=se.exec(a),o=(i=d==null?void 0:d.groups)==null?void 0:i.title,m=(s=d==null?void 0:d.groups)==null?void 0:s.href;d&&o&&m?r.push({raw:a,link:{title:o.trim(),href:m.trim(),hook:(((l=d.groups)==null?void 0:l.hook)??"").trim()}}):r.push({raw:a,link:null})}for(;r.length>0;){const c=r[r.length-1];if(c&&!c.link&&c.raw.trim()==="")r.pop();else break}return r}export{we as default};
2
- //# sourceMappingURL=ProjectMemory-aSV8UzQ9.js.map
1
+ import{r as u,j as e}from"./react-CPkiFScu.js";import{u as T}from"./query-CS7JQ86v.js";import{u as y,B as Y,d as Z,P as ee,M as R,S as U,f as C,L as te,a as re,b as O,q as Q}from"./index-DTbWl1jb.js";import{b as ne,c as oe}from"./router-DwaHAh1G.js";import"./vendor-Cs8vYp-N.js";const se=/^[\s*-]*\[(?<title>[^\]]+)\]\((?<href>[^)]+)\)\s*[—–\-:]?\s*(?<hook>.*)$/;function we(){const t=y(),{projectId:r}=ne(),i=r??"",[s,l]=oe(),c=T({queryKey:Q.projectMemory(i),queryFn:()=>O(`/api/projects/${encodeURIComponent(i)}/memory`),enabled:!!i}),a=T({queryKey:Q.projects(),queryFn:()=>O("/api/projects")}),d=u.useMemo(()=>{var n;return(n=a.data)==null?void 0:n.find(p=>p.id===i)},[a.data,i]),o=c.data,m=u.useMemo(()=>(o==null?void 0:o.entries)??[],[o==null?void 0:o.entries]),x=u.useMemo(()=>fe((o==null?void 0:o.index)??null),[o==null?void 0:o.index]),f=u.useMemo(()=>{const n=new Map;for(const p of x)p.link&&n.set(p.link.href,p.link.hook);return n},[x]),{rows:h,orphans:j}=u.useMemo(()=>he(x,m),[x,m]),v=s.get("entry"),b=s.get("view"),H=v!==null||b==="raw";function V(n){const p=new URLSearchParams(s);p.set("entry",n),p.delete("view"),l(p)}function _(){const n=new URLSearchParams(s);n.set("view","raw"),n.delete("entry"),l(n)}function F(){const n=new URLSearchParams(s);n.delete("entry"),n.delete("view"),l(n)}const g=u.useMemo(()=>b==="raw"?{kind:"raw"}:v?{kind:"entry",entry:m.find(p=>p.filename===v)??null,filename:v}:null,[v,b,m]),[L,G]=u.useState(""),k=L.trim().toLowerCase(),w=k.length>0,I=u.useMemo(()=>w?h.filter(n=>n.kind==="entry"&&z(n.entry,n.hook,k)):h,[h,w,k]),E=u.useMemo(()=>w?j.filter(n=>z(n,"",k)):j,[j,w,k]),N=m.length,B=!!(o!=null&&o.index),S=N>0||B,J=I.filter(n=>n.kind==="entry").length+E.length,P=(d==null?void 0:d.decodedCwd)??i,q=P.split(/[\\/]+/).filter(Boolean),X=q.at(-1)??P,$=q.slice(0,-1).join("/"),D=u.useMemo(()=>{let n=null;for(const p of m){if(!p.mtime)continue;const M=Date.parse(p.mtime);Number.isFinite(M)&&(n===null||M>n)&&(n=M)}return n?new Date(n).toISOString():null},[m]),K=u.useMemo(()=>{const n=new Set;for(const p of m)n.add(p.type??"other");return n.size},[m]);return e.jsxs("section",{children:[e.jsx(Y,{items:[{label:t("session.crumbProjects"),to:"/"},{label:X,to:`/projects/${encodeURIComponent(i)}`,mono:!0,icon:e.jsx(Z,{})},{label:t("memory.title")}]}),e.jsx("div",{className:"surface-card mt-6 p-6",children:e.jsx(ee,{eyebrow:e.jsx("span",{className:"inline-flex items-center gap-2",children:$?e.jsxs("span",{className:"font-mono normal-case tracking-normal",children:[$,"/"]}):t("memory.action.open")}),title:t("memory.title"),meta:o?e.jsxs(e.Fragment,{children:[e.jsx(R,{label:t("memory.meta.entries"),value:N}),K>0&&e.jsxs(e.Fragment,{children:[e.jsx(U,{}),e.jsx(R,{label:t("memory.meta.types"),value:K})]}),D&&e.jsxs(e.Fragment,{children:[e.jsx(U,{}),e.jsx(R,{label:t("memory.meta.lastUpdate"),value:C(D)})]})]}):null})}),c.isLoading&&e.jsx(te,{label:t("memory.loading"),className:"mt-6"}),c.error&&e.jsxs("p",{className:"mt-6 rounded-md border border-[var(--color-danger)]/40 bg-[var(--color-danger-soft)] px-4 py-3 text-sm text-[var(--color-danger)]",children:[t("common.failedMemory"),": ",c.error.message]}),o&&!S&&e.jsx(de,{}),o&&S&&e.jsx(ae,{rows:I,orphans:E,totalMatched:J,totalEntries:N,query:L,onQuery:G,searchActive:w,indexAvailable:B,onOpenEntry:V,onOpenRaw:_}),H&&g&&e.jsx(ie,{target:g,rawIndex:(o==null?void 0:o.index)??"",hookForEntry:g.kind==="entry"&&g.entry?f.get(g.entry.filename)??null:null,onClose:F,onJumpToCover:()=>{F(),requestAnimationFrame(()=>{const n=document.getElementById("memo-index-card");n==null||n.scrollIntoView({behavior:"smooth",block:"start"})})}})]})}function ae({rows:t,orphans:r,totalMatched:i,totalEntries:s,query:l,onQuery:c,searchActive:a,indexAvailable:d,onOpenEntry:o,onOpenRaw:m}){const x=y(),f=a&&i===0;return e.jsxs("div",{id:"memo-index-card",className:"surface-card mt-6 px-7 py-6",children:[e.jsxs("div",{className:"flex items-baseline justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"eyebrow",children:x("memory.cover.title")}),e.jsx("h2",{className:"mt-0.5 font-display text-[18px] font-medium tracking-tight text-[var(--color-fg-primary)]",children:x("memory.cover.subtitle")})]}),d&&e.jsxs("button",{type:"button",onClick:m,className:"font-mono text-[11px] uppercase tracking-[0.16em] text-[var(--color-fg-muted)] hover:text-[var(--color-accent-ink)] dark:hover:text-[var(--color-accent)]",children:[x("memory.cover.viewRaw")," ↗"]})]}),e.jsxs("div",{className:"mt-4 flex flex-wrap items-center gap-3",children:[e.jsxs("div",{className:"flex flex-1 min-w-[14rem] items-center gap-2 border-b border-[var(--color-hairline)] py-1.5 transition focus-within:border-[var(--color-accent)]",children:[e.jsx(xe,{className:"text-[var(--color-fg-muted)]"}),e.jsx("input",{type:"search",value:l,onChange:h=>c(h.target.value),placeholder:x("memory.search.placeholder"),className:"w-full bg-transparent text-sm text-[var(--color-fg-primary)] placeholder:text-[var(--color-fg-faint)] focus:outline-none"})]}),e.jsx("span",{className:"font-mono text-[10.5px] uppercase tracking-[0.18em] tabular-nums text-[var(--color-fg-faint)]",children:a?x("memory.list.count",{n:i,total:s}):`${s} ${x("memory.meta.entries").toLowerCase()}`})]}),e.jsx("div",{className:"rule-dotted mt-5","aria-hidden":!0}),f?e.jsx("p",{className:"mt-6 text-sm text-[var(--color-fg-muted)]",children:x("memory.list.noResults")}):e.jsxs("ul",{className:"mt-3",children:[t.map((h,j)=>e.jsx(W,{row:h,onOpenEntry:o},j)),r.length>0&&e.jsxs(e.Fragment,{children:[!a&&t.length>0&&e.jsx("li",{"aria-hidden":!0,className:"h-3"}),e.jsx("li",{className:"pt-3 pb-2",children:e.jsxs("div",{className:"flex items-baseline gap-3",children:[e.jsx("span",{className:"font-mono text-[10.5px] uppercase tracking-[0.18em] text-[var(--color-fg-faint)]",children:x("memory.cover.orphan")}),e.jsxs("span",{className:"font-mono text-[10.5px] tabular-nums text-[var(--color-fg-faint)]",children:["· ",r.length]}),e.jsx("span",{"aria-hidden":!0,className:"ml-2 h-px flex-1 bg-[var(--color-hairline)]"})]})}),r.map(h=>e.jsx(W,{row:{kind:"entry",entry:h,hook:""},onOpenEntry:o},h.filename))]})]})]})}function W({row:t,onOpenEntry:r}){const i=y();if(t.kind==="spacer")return e.jsx("li",{"aria-hidden":!0,className:"h-2"});if(t.kind==="heading")return e.jsx("li",{className:"pt-4 pb-1",children:e.jsx("div",{className:"font-mono text-[10.5px] uppercase tracking-[0.18em] text-[var(--color-fg-muted)]",children:t.text})});if(t.kind==="text")return e.jsx("li",{className:"px-1 py-0.5 text-[12.5px] text-[var(--color-fg-faint)] whitespace-pre-wrap break-words",children:t.text});if(t.kind==="missing")return e.jsxs("li",{title:i("memory.cover.missingTooltip"),className:"flex items-baseline gap-3 px-2 py-1.5 text-[var(--color-fg-faint)]",children:[e.jsx("span",{className:"text-[14px] font-medium line-through decoration-[var(--color-fg-faint)]/50",children:t.title}),t.hook&&e.jsx("span",{className:"truncate text-[12px]",children:t.hook})]});const s=t.entry,l=s.type??"other",c=s.name??s.filename,a=t.hook||s.description||"";return e.jsx("li",{children:e.jsxs("button",{type:"button",onClick:()=>r(s.filename),className:`memo-row memo-type-${l}`,children:[e.jsx("span",{"aria-hidden":!0,className:"memo-row-dot"}),e.jsxs("div",{className:"memo-row-content",children:[e.jsxs("div",{className:"memo-row-headline",children:[e.jsx("span",{className:"memo-row-title",children:c}),s.mtime&&e.jsx("span",{className:"memo-row-meta-inline",children:C(s.mtime)}),e.jsx(A,{k:l})]}),a&&e.jsx("p",{className:"memo-row-hook",children:a})]}),e.jsx("span",{"aria-hidden":!0,className:"memo-row-chevron",children:"↗"})]})})}function A({k:t}){const r=y(),i=r(t==="user"?"memory.type.user":t==="feedback"?"memory.type.feedback":t==="project"?"memory.type.project":t==="reference"?"memory.type.reference":"memory.type.other");return e.jsx("span",{className:"memo-chip",children:i})}function ie({target:t,rawIndex:r,hookForEntry:i,onClose:s,onJumpToCover:l}){var o;const c=y(),a=u.useRef(null);u.useEffect(()=>{const m=f=>{f.key==="Escape"&&(f.preventDefault(),s())};window.addEventListener("keydown",m);const x=document.body.style.overflow;return document.body.style.overflow="hidden",requestAnimationFrame(()=>{var f;return(f=a.current)==null?void 0:f.focus()}),()=>{window.removeEventListener("keydown",m),document.body.style.overflow=x}},[s]);const d=t.kind==="entry"?((o=t.entry)==null?void 0:o.type)??"other":"reference";return e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"memo-drawer-backdrop",onClick:s,"aria-hidden":!0}),e.jsxs("div",{ref:a,role:"dialog","aria-modal":"true",tabIndex:-1,className:`memo-drawer-panel memo-type-${d} focus:outline-none`,children:[e.jsxs("div",{className:"flex items-start justify-between gap-3 border-b border-[var(--color-hairline)] px-7 pt-7 pb-5",children:[e.jsx("div",{className:"min-w-0 flex-1",children:t.kind==="entry"?e.jsxs(e.Fragment,{children:[e.jsx(A,{k:d}),t.entry?e.jsxs(e.Fragment,{children:[e.jsx("h2",{className:"mt-3 font-display text-[24px] font-light leading-tight tracking-tight text-[var(--color-fg-primary)]",children:t.entry.name??t.entry.filename}),e.jsxs("p",{className:"mt-1.5 font-mono text-[11px] uppercase tracking-[0.16em] text-[var(--color-fg-faint)]",children:[t.entry.filename," · ",re(t.entry.bytes),t.entry.mtime?` · ${C(t.entry.mtime)}`:""]})]}):e.jsxs(e.Fragment,{children:[e.jsx("h2",{className:"mt-3 font-display text-[22px] font-light leading-tight text-[var(--color-fg-primary)]",children:c("memory.drawer.notFound.title")}),e.jsx("p",{className:"mt-1.5 font-mono text-[11px] uppercase tracking-[0.16em] text-[var(--color-fg-faint)]",children:t.filename})]})]}):e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"memo-chip memo-type-reference",children:c("memory.cover.title")}),e.jsx("h2",{className:"mt-3 font-display text-[24px] font-light leading-tight tracking-tight text-[var(--color-fg-primary)]",children:c("memory.raw.title")}),e.jsx("p",{className:"mt-1.5 font-mono text-[11px] uppercase tracking-[0.16em] text-[var(--color-fg-faint)]",children:c("memory.raw.subtitle")})]})}),e.jsx("button",{type:"button",onClick:s,"aria-label":c("memory.drawer.close"),className:"rounded-md p-2 text-[var(--color-fg-muted)] hover:bg-[var(--color-sunken)] hover:text-[var(--color-fg-primary)]",children:e.jsx(pe,{})})]}),e.jsx("div",{className:"flex-1 overflow-y-auto px-7 py-6",children:t.kind==="entry"&&t.entry?e.jsx(le,{entry:t.entry,hookForEntry:i,onJumpToCover:l}):t.kind==="entry"?e.jsx(ce,{filename:t.filename,onJumpToCover:l}):e.jsx(me,{source:r})})]})]})}function le({entry:t,hookForEntry:r,onJumpToCover:i}){const s=y(),l=t.body.trim();return e.jsxs("div",{children:[t.description&&e.jsx("p",{className:"text-[14px] text-[var(--color-fg-secondary)]",children:t.description}),e.jsx("pre",{className:"whitespace-pre-wrap break-words rounded-[var(--radius-input)] border border-[var(--color-hairline)] bg-[var(--color-sunken)] px-4 py-3 font-mono text-[12.5px] leading-[1.65] text-[var(--color-fg-primary)] "+(t.description?"mt-5":""),children:l||"—"}),r&&e.jsxs("div",{className:"mt-7",children:[e.jsx("div",{className:"rule-dotted","aria-hidden":!0}),e.jsxs("div",{className:"mt-4 flex items-baseline justify-between gap-3",children:[e.jsx("div",{className:"eyebrow",children:s("memory.drawer.indexHook")}),e.jsxs("button",{type:"button",onClick:i,className:"font-mono text-[10.5px] uppercase tracking-[0.16em] text-[var(--color-fg-muted)] hover:text-[var(--color-accent-ink)] dark:hover:text-[var(--color-accent)]",children:[s("memory.cover.title")," ↑"]})]}),e.jsx("p",{className:"mt-1.5 text-[13px] text-[var(--color-fg-secondary)]",children:r})]})]})}function ce({filename:t,onJumpToCover:r}){const i=y();return e.jsxs("div",{children:[e.jsx("p",{className:"text-sm text-[var(--color-fg-secondary)]",children:i("memory.drawer.notFound.body")}),e.jsx("p",{className:"mt-3 font-mono text-[12px] text-[var(--color-fg-faint)]",children:t}),e.jsxs("button",{type:"button",onClick:r,className:"mt-5 inline-flex items-center gap-1.5 rounded-[var(--radius-control)] border border-[var(--color-hairline)] px-3 py-1.5 text-[11px] font-medium uppercase tracking-[0.14em] text-[var(--color-fg-secondary)] hover:border-[var(--color-hairline-strong)] hover:text-[var(--color-fg-primary)]",children:[i("memory.cover.title")," ↑"]})]})}function me({source:t}){const r=t.trim();return e.jsx("pre",{className:"whitespace-pre-wrap break-words rounded-[var(--radius-input)] border border-[var(--color-hairline)] bg-[var(--color-sunken)] px-4 py-3 font-mono text-[12.5px] leading-[1.65] text-[var(--color-fg-primary)]",children:r||"—"})}function de(){const t=y();return e.jsxs("div",{className:"surface-card mt-6 px-8 py-14 text-center",children:[e.jsx("div",{className:"mx-auto flex h-12 w-12 items-center justify-center rounded-full border border-[var(--color-hairline)] bg-[var(--color-sunken)] text-[var(--color-fg-muted)]",children:e.jsx(ue,{})}),e.jsx("h2",{className:"mt-5 font-display text-[20px] font-light tracking-tight text-[var(--color-fg-primary)]",children:t("memory.empty.title")}),e.jsx("p",{className:"mx-auto mt-3 max-w-xl text-[13px] leading-relaxed text-[var(--color-fg-secondary)]",children:t("memory.empty.body")})]})}function xe({className:t=""}){return e.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.7",strokeLinecap:"round",className:t,"aria-hidden":!0,children:[e.jsx("circle",{cx:"11",cy:"11",r:"6.2"}),e.jsx("path",{d:"M20 20l-4.3-4.3"})]})}function pe(){return e.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.8",strokeLinecap:"round","aria-hidden":!0,children:e.jsx("path",{d:"M6 6l12 12M18 6L6 18"})})}function ue(){return e.jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.6",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":!0,children:e.jsx("path",{d:"M6 4h12v17l-6-4-6 4z"})})}function z(t,r,i){return[t.name??"",t.filename,t.description??"",t.body,r].some(l=>l.toLowerCase().includes(i))}function he(t,r){const i=new Map(r.map(a=>[a.filename,a])),s=new Set,l=[];for(const a of t){if(a.link){const m=i.get(a.link.href);m?(l.push({kind:"entry",entry:m,hook:a.link.hook}),s.add(m.filename)):l.push({kind:"missing",title:a.link.title,hook:a.link.hook});continue}const d=a.raw.trim();if(!d){l.push({kind:"spacer"});continue}const o=/^(#{1,6})\s+(.+?)\s*$/.exec(d);o?l.push({kind:"heading",text:o[2]}):l.push({kind:"text",text:a.raw})}const c=r.filter(a=>!s.has(a.filename));return{rows:l,orphans:c}}function fe(t){var i,s,l;if(!t)return[];const r=[];for(const c of t.split(/\r?\n/)){const a=c.trimEnd();if(a.trim()===""){const x=r[r.length-1];x&&(x.link||x.raw.trim()!=="")&&r.push({raw:"",link:null});continue}const d=se.exec(a),o=(i=d==null?void 0:d.groups)==null?void 0:i.title,m=(s=d==null?void 0:d.groups)==null?void 0:s.href;d&&o&&m?r.push({raw:a,link:{title:o.trim(),href:m.trim(),hook:(((l=d.groups)==null?void 0:l.hook)??"").trim()}}):r.push({raw:a,link:null})}for(;r.length>0;){const c=r[r.length-1];if(c&&!c.link&&c.raw.trim()==="")r.pop();else break}return r}export{we as default};
2
+ //# sourceMappingURL=ProjectMemory-CcE3KbUK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProjectMemory-CcE3KbUK.js","sources":["../../web/src/routes/ProjectMemory.tsx"],"sourcesContent":["import { useQuery } from '@tanstack/react-query';\nimport { useEffect, useMemo, useRef, useState } from 'react';\nimport { useParams, useSearchParams } from 'react-router-dom';\nimport Breadcrumbs, { BreadcrumbFolderIcon } from '../components/Breadcrumbs.tsx';\nimport { Loading } from '../components/Loading.tsx';\nimport PageHeader, { MetaItem, Sep } from '../components/PageHeader.tsx';\nimport {\n api,\n type MemoryEntry,\n type MemoryResponse,\n type MemoryType,\n type ProjectSummary,\n} from '../lib/api.ts';\nimport { formatBytes, formatRelativeTime } from '../lib/format.ts';\nimport { useT } from '../lib/i18n.ts';\nimport { queryKeys } from '../lib/query-keys.ts';\n\ntype GroupKey = MemoryType | 'other';\n\ninterface ParsedLink {\n title: string;\n href: string;\n hook: string;\n}\ninterface IndexLine {\n raw: string;\n link: ParsedLink | null;\n}\n\ntype Row =\n | { kind: 'entry'; entry: MemoryEntry; hook: string }\n | { kind: 'missing'; title: string; hook: string }\n | { kind: 'heading'; text: string }\n | { kind: 'text'; text: string }\n | { kind: 'spacer' };\n\nconst LINK_RE = /^[\\s*-]*\\[(?<title>[^\\]]+)\\]\\((?<href>[^)]+)\\)\\s*[—–\\-:]?\\s*(?<hook>.*)$/;\n\nexport default function ProjectMemoryRoute() {\n const t = useT();\n const { projectId } = useParams<{ projectId: string }>();\n const id = projectId ?? '';\n const [searchParams, setSearchParams] = useSearchParams();\n\n const memoryQuery = useQuery({\n queryKey: queryKeys.projectMemory(id),\n queryFn: () => api<MemoryResponse>(`/api/projects/${encodeURIComponent(id)}/memory`),\n enabled: !!id,\n });\n\n const projectsQuery = useQuery({\n queryKey: queryKeys.projects(),\n queryFn: () => api<ProjectSummary[]>('/api/projects'),\n });\n const project = useMemo(\n () => projectsQuery.data?.find((p) => p.id === id),\n [projectsQuery.data, id],\n );\n\n const data = memoryQuery.data;\n const entries = useMemo(() => data?.entries ?? [], [data?.entries]);\n const indexLines = useMemo(() => parseIndex(data?.index ?? null), [data?.index]);\n\n const hookByFilename = useMemo(() => {\n const m = new Map<string, string>();\n for (const line of indexLines) {\n if (line.link) m.set(line.link.href, line.link.hook);\n }\n return m;\n }, [indexLines]);\n\n const { rows, orphans } = useMemo(\n () => buildRows(indexLines, entries),\n [indexLines, entries],\n );\n\n // URL-driven drawer state\n const drawerEntry = searchParams.get('entry');\n const drawerView = searchParams.get('view');\n const drawerOpen = drawerEntry !== null || drawerView === 'raw';\n\n function openEntry(filename: string) {\n const next = new URLSearchParams(searchParams);\n next.set('entry', filename);\n next.delete('view');\n setSearchParams(next);\n }\n function openRaw() {\n const next = new URLSearchParams(searchParams);\n next.set('view', 'raw');\n next.delete('entry');\n setSearchParams(next);\n }\n function closeDrawer() {\n const next = new URLSearchParams(searchParams);\n next.delete('entry');\n next.delete('view');\n setSearchParams(next);\n }\n\n const drawerTarget = useMemo(() => {\n if (drawerView === 'raw') return { kind: 'raw' as const };\n if (drawerEntry) {\n const entry = entries.find((e) => e.filename === drawerEntry) ?? null;\n return { kind: 'entry' as const, entry, filename: drawerEntry };\n }\n return null;\n }, [drawerEntry, drawerView, entries]);\n\n const [query, setQuery] = useState('');\n const trimmed = query.trim().toLowerCase();\n const searchActive = trimmed.length > 0;\n\n const filteredRows: Row[] = useMemo(() => {\n if (!searchActive) return rows;\n return rows.filter((r) => r.kind === 'entry' && matchEntry(r.entry, r.hook, trimmed));\n }, [rows, searchActive, trimmed]);\n\n const filteredOrphans = useMemo(\n () => (searchActive ? orphans.filter((e) => matchEntry(e, '', trimmed)) : orphans),\n [orphans, searchActive, trimmed],\n );\n\n const totalEntries = entries.length;\n const indexAvailable = !!data?.index;\n const hasContent = totalEntries > 0 || indexAvailable;\n\n const totalMatched =\n filteredRows.filter((r) => r.kind === 'entry').length + filteredOrphans.length;\n\n const cwd = project?.decodedCwd ?? id;\n const parts = cwd.split(/[\\\\/]+/).filter(Boolean);\n const tail = parts.at(-1) ?? cwd;\n const head = parts.slice(0, -1).join('/');\n\n const lastUpdate = useMemo(() => {\n let latest: number | null = null;\n for (const e of entries) {\n if (!e.mtime) continue;\n const t = Date.parse(e.mtime);\n if (Number.isFinite(t) && (latest === null || t > latest)) latest = t;\n }\n return latest ? new Date(latest).toISOString() : null;\n }, [entries]);\n\n const typeCount = useMemo(() => {\n const s = new Set<GroupKey>();\n for (const e of entries) s.add((e.type ?? 'other') as GroupKey);\n return s.size;\n }, [entries]);\n\n return (\n <section>\n <Breadcrumbs\n items={[\n { label: t('session.crumbProjects'), to: '/' },\n {\n label: tail,\n to: `/projects/${encodeURIComponent(id)}`,\n mono: true,\n icon: <BreadcrumbFolderIcon />,\n },\n { label: t('memory.title') },\n ]}\n />\n\n <div className=\"surface-card mt-6 p-6\">\n <PageHeader\n eyebrow={\n <span className=\"inline-flex items-center gap-2\">\n {head ? (\n <span className=\"font-mono normal-case tracking-normal\">{head}/</span>\n ) : (\n t('memory.action.open')\n )}\n </span>\n }\n title={t('memory.title')}\n meta={\n data ? (\n <>\n <MetaItem label={t('memory.meta.entries')} value={totalEntries} />\n {typeCount > 0 && (\n <>\n <Sep />\n <MetaItem label={t('memory.meta.types')} value={typeCount} />\n </>\n )}\n {lastUpdate && (\n <>\n <Sep />\n <MetaItem\n label={t('memory.meta.lastUpdate')}\n value={formatRelativeTime(lastUpdate)}\n />\n </>\n )}\n </>\n ) : null\n }\n />\n </div>\n\n {memoryQuery.isLoading && <Loading label={t('memory.loading')} className=\"mt-6\" />}\n {memoryQuery.error && (\n <p className=\"mt-6 rounded-md border border-[var(--color-danger)]/40 bg-[var(--color-danger-soft)] px-4 py-3 text-sm text-[var(--color-danger)]\">\n {t('common.failedMemory')}: {(memoryQuery.error as Error).message}\n </p>\n )}\n\n {data && !hasContent && <EmptyState />}\n\n {data && hasContent && (\n <IndexCard\n rows={filteredRows}\n orphans={filteredOrphans}\n totalMatched={totalMatched}\n totalEntries={totalEntries}\n query={query}\n onQuery={setQuery}\n searchActive={searchActive}\n indexAvailable={indexAvailable}\n onOpenEntry={openEntry}\n onOpenRaw={openRaw}\n />\n )}\n\n {drawerOpen && drawerTarget && (\n <Drawer\n target={drawerTarget}\n rawIndex={data?.index ?? ''}\n hookForEntry={\n drawerTarget.kind === 'entry' && drawerTarget.entry\n ? hookByFilename.get(drawerTarget.entry.filename) ?? null\n : null\n }\n onClose={closeDrawer}\n onJumpToCover={() => {\n closeDrawer();\n requestAnimationFrame(() => {\n const cover = document.getElementById('memo-index-card');\n cover?.scrollIntoView({ behavior: 'smooth', block: 'start' });\n });\n }}\n />\n )}\n </section>\n );\n}\n\nfunction IndexCard({\n rows,\n orphans,\n totalMatched,\n totalEntries,\n query,\n onQuery,\n searchActive,\n indexAvailable,\n onOpenEntry,\n onOpenRaw,\n}: {\n rows: Row[];\n orphans: MemoryEntry[];\n totalMatched: number;\n totalEntries: number;\n query: string;\n onQuery: (v: string) => void;\n searchActive: boolean;\n indexAvailable: boolean;\n onOpenEntry: (filename: string) => void;\n onOpenRaw: () => void;\n}) {\n const t = useT();\n const noResults = searchActive && totalMatched === 0;\n\n return (\n <div id=\"memo-index-card\" className=\"surface-card mt-6 px-7 py-6\">\n <div className=\"flex items-baseline justify-between gap-3\">\n <div>\n <div className=\"eyebrow\">{t('memory.cover.title')}</div>\n <h2 className=\"mt-0.5 font-display text-[18px] font-medium tracking-tight text-[var(--color-fg-primary)]\">\n {t('memory.cover.subtitle')}\n </h2>\n </div>\n {indexAvailable && (\n <button\n type=\"button\"\n onClick={onOpenRaw}\n className=\"font-mono text-[11px] uppercase tracking-[0.16em] text-[var(--color-fg-muted)] hover:text-[var(--color-accent-ink)] dark:hover:text-[var(--color-accent)]\"\n >\n {t('memory.cover.viewRaw')} ↗\n </button>\n )}\n </div>\n\n <div className=\"mt-4 flex flex-wrap items-center gap-3\">\n <div className=\"flex flex-1 min-w-[14rem] items-center gap-2 border-b border-[var(--color-hairline)] py-1.5 transition focus-within:border-[var(--color-accent)]\">\n <SearchIcon className=\"text-[var(--color-fg-muted)]\" />\n <input\n type=\"search\"\n value={query}\n onChange={(e) => onQuery(e.target.value)}\n placeholder={t('memory.search.placeholder')}\n className=\"w-full bg-transparent text-sm text-[var(--color-fg-primary)] placeholder:text-[var(--color-fg-faint)] focus:outline-none\"\n />\n </div>\n <span className=\"font-mono text-[10.5px] uppercase tracking-[0.18em] tabular-nums text-[var(--color-fg-faint)]\">\n {searchActive\n ? t('memory.list.count', { n: totalMatched, total: totalEntries })\n : `${totalEntries} ${t('memory.meta.entries').toLowerCase()}`}\n </span>\n </div>\n\n <div className=\"rule-dotted mt-5\" aria-hidden />\n\n {noResults ? (\n <p className=\"mt-6 text-sm text-[var(--color-fg-muted)]\">{t('memory.list.noResults')}</p>\n ) : (\n <ul className=\"mt-3\">\n {rows.map((row, i) => (\n <RowItem key={i} row={row} onOpenEntry={onOpenEntry} />\n ))}\n\n {orphans.length > 0 && (\n <>\n {!searchActive && rows.length > 0 && (\n <li aria-hidden className=\"h-3\" />\n )}\n <li className=\"pt-3 pb-2\">\n <div className=\"flex items-baseline gap-3\">\n <span className=\"font-mono text-[10.5px] uppercase tracking-[0.18em] text-[var(--color-fg-faint)]\">\n {t('memory.cover.orphan')}\n </span>\n <span className=\"font-mono text-[10.5px] tabular-nums text-[var(--color-fg-faint)]\">\n · {orphans.length}\n </span>\n <span aria-hidden className=\"ml-2 h-px flex-1 bg-[var(--color-hairline)]\" />\n </div>\n </li>\n {orphans.map((e) => (\n <RowItem\n key={e.filename}\n row={{ kind: 'entry', entry: e, hook: '' }}\n onOpenEntry={onOpenEntry}\n />\n ))}\n </>\n )}\n </ul>\n )}\n </div>\n );\n}\n\nfunction RowItem({\n row,\n onOpenEntry,\n}: {\n row: Row;\n onOpenEntry: (filename: string) => void;\n}) {\n const t = useT();\n\n if (row.kind === 'spacer') {\n return <li aria-hidden className=\"h-2\" />;\n }\n if (row.kind === 'heading') {\n return (\n <li className=\"pt-4 pb-1\">\n <div className=\"font-mono text-[10.5px] uppercase tracking-[0.18em] text-[var(--color-fg-muted)]\">\n {row.text}\n </div>\n </li>\n );\n }\n if (row.kind === 'text') {\n return (\n <li className=\"px-1 py-0.5 text-[12.5px] text-[var(--color-fg-faint)] whitespace-pre-wrap break-words\">\n {row.text}\n </li>\n );\n }\n if (row.kind === 'missing') {\n return (\n <li\n title={t('memory.cover.missingTooltip')}\n className=\"flex items-baseline gap-3 px-2 py-1.5 text-[var(--color-fg-faint)]\"\n >\n <span className=\"text-[14px] font-medium line-through decoration-[var(--color-fg-faint)]/50\">\n {row.title}\n </span>\n {row.hook && <span className=\"truncate text-[12px]\">{row.hook}</span>}\n </li>\n );\n }\n\n const entry = row.entry;\n const typeKey: GroupKey = entry.type ?? 'other';\n const title = entry.name ?? entry.filename;\n const hookText = row.hook || entry.description || '';\n return (\n <li>\n <button\n type=\"button\"\n onClick={() => onOpenEntry(entry.filename)}\n className={`memo-row memo-type-${typeKey}`}\n >\n <span aria-hidden className=\"memo-row-dot\" />\n <div className=\"memo-row-content\">\n <div className=\"memo-row-headline\">\n <span className=\"memo-row-title\">{title}</span>\n {entry.mtime && (\n <span className=\"memo-row-meta-inline\">{formatRelativeTime(entry.mtime)}</span>\n )}\n <TypeChip k={typeKey} />\n </div>\n {hookText && <p className=\"memo-row-hook\">{hookText}</p>}\n </div>\n <span aria-hidden className=\"memo-row-chevron\">↗</span>\n </button>\n </li>\n );\n}\n\nfunction TypeChip({ k }: { k: GroupKey }) {\n const t = useT();\n const label =\n k === 'user'\n ? t('memory.type.user')\n : k === 'feedback'\n ? t('memory.type.feedback')\n : k === 'project'\n ? t('memory.type.project')\n : k === 'reference'\n ? t('memory.type.reference')\n : t('memory.type.other');\n return <span className=\"memo-chip\">{label}</span>;\n}\n\ntype DrawerTarget =\n | { kind: 'entry'; entry: MemoryEntry | null; filename: string }\n | { kind: 'raw' };\n\nfunction Drawer({\n target,\n rawIndex,\n hookForEntry,\n onClose,\n onJumpToCover,\n}: {\n target: DrawerTarget;\n rawIndex: string;\n hookForEntry: string | null;\n onClose: () => void;\n onJumpToCover: () => void;\n}) {\n const t = useT();\n const panelRef = useRef<HTMLDivElement | null>(null);\n\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n e.preventDefault();\n onClose();\n }\n };\n window.addEventListener('keydown', onKey);\n const prevOverflow = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n requestAnimationFrame(() => panelRef.current?.focus());\n return () => {\n window.removeEventListener('keydown', onKey);\n document.body.style.overflow = prevOverflow;\n };\n }, [onClose]);\n\n const typeKey: GroupKey =\n target.kind === 'entry' ? (target.entry?.type ?? 'other') : 'reference';\n\n return (\n <>\n <div className=\"memo-drawer-backdrop\" onClick={onClose} aria-hidden />\n <div\n ref={panelRef}\n role=\"dialog\"\n aria-modal=\"true\"\n tabIndex={-1}\n className={`memo-drawer-panel memo-type-${typeKey} focus:outline-none`}\n >\n <div className=\"flex items-start justify-between gap-3 border-b border-[var(--color-hairline)] px-7 pt-7 pb-5\">\n <div className=\"min-w-0 flex-1\">\n {target.kind === 'entry' ? (\n <>\n <TypeChip k={typeKey} />\n {target.entry ? (\n <>\n <h2 className=\"mt-3 font-display text-[24px] font-light leading-tight tracking-tight text-[var(--color-fg-primary)]\">\n {target.entry.name ?? target.entry.filename}\n </h2>\n <p className=\"mt-1.5 font-mono text-[11px] uppercase tracking-[0.16em] text-[var(--color-fg-faint)]\">\n {target.entry.filename} · {formatBytes(target.entry.bytes)}\n {target.entry.mtime ? ` · ${formatRelativeTime(target.entry.mtime)}` : ''}\n </p>\n </>\n ) : (\n <>\n <h2 className=\"mt-3 font-display text-[22px] font-light leading-tight text-[var(--color-fg-primary)]\">\n {t('memory.drawer.notFound.title')}\n </h2>\n <p className=\"mt-1.5 font-mono text-[11px] uppercase tracking-[0.16em] text-[var(--color-fg-faint)]\">\n {target.filename}\n </p>\n </>\n )}\n </>\n ) : (\n <>\n <span className=\"memo-chip memo-type-reference\">{t('memory.cover.title')}</span>\n <h2 className=\"mt-3 font-display text-[24px] font-light leading-tight tracking-tight text-[var(--color-fg-primary)]\">\n {t('memory.raw.title')}\n </h2>\n <p className=\"mt-1.5 font-mono text-[11px] uppercase tracking-[0.16em] text-[var(--color-fg-faint)]\">\n {t('memory.raw.subtitle')}\n </p>\n </>\n )}\n </div>\n <button\n type=\"button\"\n onClick={onClose}\n aria-label={t('memory.drawer.close')}\n className=\"rounded-md p-2 text-[var(--color-fg-muted)] hover:bg-[var(--color-sunken)] hover:text-[var(--color-fg-primary)]\"\n >\n <CloseIcon />\n </button>\n </div>\n\n <div className=\"flex-1 overflow-y-auto px-7 py-6\">\n {target.kind === 'entry' && target.entry ? (\n <EntryDrawerBody\n entry={target.entry}\n hookForEntry={hookForEntry}\n onJumpToCover={onJumpToCover}\n />\n ) : target.kind === 'entry' ? (\n <NotFoundDrawerBody filename={target.filename} onJumpToCover={onJumpToCover} />\n ) : (\n <RawDrawerBody source={rawIndex} />\n )}\n </div>\n </div>\n </>\n );\n}\n\nfunction EntryDrawerBody({\n entry,\n hookForEntry,\n onJumpToCover,\n}: {\n entry: MemoryEntry;\n hookForEntry: string | null;\n onJumpToCover: () => void;\n}) {\n const t = useT();\n const body = entry.body.trim();\n return (\n <div>\n {entry.description && (\n <p className=\"text-[14px] text-[var(--color-fg-secondary)]\">{entry.description}</p>\n )}\n <pre\n className={\n 'whitespace-pre-wrap break-words rounded-[var(--radius-input)] border border-[var(--color-hairline)] bg-[var(--color-sunken)] px-4 py-3 font-mono text-[12.5px] leading-[1.65] text-[var(--color-fg-primary)] ' +\n (entry.description ? 'mt-5' : '')\n }\n >\n {body || '—'}\n </pre>\n {hookForEntry && (\n <div className=\"mt-7\">\n <div className=\"rule-dotted\" aria-hidden />\n <div className=\"mt-4 flex items-baseline justify-between gap-3\">\n <div className=\"eyebrow\">{t('memory.drawer.indexHook')}</div>\n <button\n type=\"button\"\n onClick={onJumpToCover}\n className=\"font-mono text-[10.5px] uppercase tracking-[0.16em] text-[var(--color-fg-muted)] hover:text-[var(--color-accent-ink)] dark:hover:text-[var(--color-accent)]\"\n >\n {t('memory.cover.title')} ↑\n </button>\n </div>\n <p className=\"mt-1.5 text-[13px] text-[var(--color-fg-secondary)]\">{hookForEntry}</p>\n </div>\n )}\n </div>\n );\n}\n\nfunction NotFoundDrawerBody({\n filename,\n onJumpToCover,\n}: {\n filename: string;\n onJumpToCover: () => void;\n}) {\n const t = useT();\n return (\n <div>\n <p className=\"text-sm text-[var(--color-fg-secondary)]\">{t('memory.drawer.notFound.body')}</p>\n <p className=\"mt-3 font-mono text-[12px] text-[var(--color-fg-faint)]\">{filename}</p>\n <button\n type=\"button\"\n onClick={onJumpToCover}\n className=\"mt-5 inline-flex items-center gap-1.5 rounded-[var(--radius-control)] border border-[var(--color-hairline)] px-3 py-1.5 text-[11px] font-medium uppercase tracking-[0.14em] text-[var(--color-fg-secondary)] hover:border-[var(--color-hairline-strong)] hover:text-[var(--color-fg-primary)]\"\n >\n {t('memory.cover.title')} ↑\n </button>\n </div>\n );\n}\n\nfunction RawDrawerBody({ source }: { source: string }) {\n const body = source.trim();\n return (\n <pre className=\"whitespace-pre-wrap break-words rounded-[var(--radius-input)] border border-[var(--color-hairline)] bg-[var(--color-sunken)] px-4 py-3 font-mono text-[12.5px] leading-[1.65] text-[var(--color-fg-primary)]\">\n {body || '—'}\n </pre>\n );\n}\n\nfunction EmptyState() {\n const t = useT();\n return (\n <div className=\"surface-card mt-6 px-8 py-14 text-center\">\n <div className=\"mx-auto flex h-12 w-12 items-center justify-center rounded-full border border-[var(--color-hairline)] bg-[var(--color-sunken)] text-[var(--color-fg-muted)]\">\n <BookmarkIcon />\n </div>\n <h2 className=\"mt-5 font-display text-[20px] font-light tracking-tight text-[var(--color-fg-primary)]\">\n {t('memory.empty.title')}\n </h2>\n <p className=\"mx-auto mt-3 max-w-xl text-[13px] leading-relaxed text-[var(--color-fg-secondary)]\">\n {t('memory.empty.body')}\n </p>\n </div>\n );\n}\n\nfunction SearchIcon({ className = '' }: { className?: string }) {\n return (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.7\"\n strokeLinecap=\"round\"\n className={className}\n aria-hidden\n >\n <circle cx=\"11\" cy=\"11\" r=\"6.2\" />\n <path d=\"M20 20l-4.3-4.3\" />\n </svg>\n );\n}\n\nfunction CloseIcon() {\n return (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.8\"\n strokeLinecap=\"round\"\n aria-hidden\n >\n <path d=\"M6 6l12 12M18 6L6 18\" />\n </svg>\n );\n}\n\nfunction BookmarkIcon() {\n return (\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.6\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden\n >\n <path d=\"M6 4h12v17l-6-4-6 4z\" />\n </svg>\n );\n}\n\nfunction matchEntry(entry: MemoryEntry, hook: string, q: string): boolean {\n const fields = [\n entry.name ?? '',\n entry.filename,\n entry.description ?? '',\n entry.body,\n hook,\n ];\n return fields.some((f) => f.toLowerCase().includes(q));\n}\n\nfunction buildRows(\n indexLines: IndexLine[],\n entries: MemoryEntry[],\n): { rows: Row[]; orphans: MemoryEntry[] } {\n const filenameToEntry = new Map(entries.map((e) => [e.filename, e]));\n const seen = new Set<string>();\n const rows: Row[] = [];\n\n for (const line of indexLines) {\n if (line.link) {\n const entry = filenameToEntry.get(line.link.href);\n if (entry) {\n rows.push({ kind: 'entry', entry, hook: line.link.hook });\n seen.add(entry.filename);\n } else {\n rows.push({ kind: 'missing', title: line.link.title, hook: line.link.hook });\n }\n continue;\n }\n const txt = line.raw.trim();\n if (!txt) {\n rows.push({ kind: 'spacer' });\n continue;\n }\n const headingMatch = /^(#{1,6})\\s+(.+?)\\s*$/.exec(txt);\n if (headingMatch) {\n rows.push({ kind: 'heading', text: headingMatch[2]! });\n } else {\n rows.push({ kind: 'text', text: line.raw });\n }\n }\n\n const orphans = entries.filter((e) => !seen.has(e.filename));\n return { rows, orphans };\n}\n\nfunction parseIndex(raw: string | null): IndexLine[] {\n if (!raw) return [];\n const out: IndexLine[] = [];\n for (const rawLine of raw.split(/\\r?\\n/)) {\n const line = rawLine.trimEnd();\n if (line.trim() === '') {\n const last = out[out.length - 1];\n if (last && (last.link || last.raw.trim() !== '')) {\n out.push({ raw: '', link: null });\n }\n continue;\n }\n const m = LINK_RE.exec(line);\n const title = m?.groups?.title;\n const href = m?.groups?.href;\n if (m && title && href) {\n out.push({\n raw: line,\n link: { title: title.trim(), href: href.trim(), hook: (m.groups?.hook ?? '').trim() },\n });\n } else {\n out.push({ raw: line, link: null });\n }\n }\n while (out.length > 0) {\n const last = out[out.length - 1];\n if (last && !last.link && last.raw.trim() === '') out.pop();\n else break;\n }\n return out;\n}\n"],"names":["LINK_RE","ProjectMemoryRoute","useT","projectId","useParams","id","searchParams","setSearchParams","useSearchParams","memoryQuery","useQuery","queryKeys","api","projectsQuery","project","useMemo","_a","data","entries","indexLines","parseIndex","hookByFilename","m","line","rows","orphans","buildRows","drawerEntry","drawerView","drawerOpen","openEntry","filename","next","openRaw","closeDrawer","drawerTarget","e","query","setQuery","useState","trimmed","searchActive","filteredRows","r","matchEntry","filteredOrphans","totalEntries","indexAvailable","hasContent","totalMatched","cwd","parts","tail","head","lastUpdate","latest","t","typeCount","s","jsx","Breadcrumbs","BreadcrumbFolderIcon","PageHeader","jsxs","Fragment","MetaItem","Sep","formatRelativeTime","Loading","EmptyState","IndexCard","Drawer","cover","onQuery","onOpenEntry","onOpenRaw","noResults","SearchIcon","row","i","RowItem","entry","typeKey","title","hookText","TypeChip","k","label","target","rawIndex","hookForEntry","onClose","onJumpToCover","panelRef","useRef","useEffect","onKey","prevOverflow","formatBytes","CloseIcon","EntryDrawerBody","NotFoundDrawerBody","RawDrawerBody","body","source","BookmarkIcon","className","hook","q","f","filenameToEntry","seen","txt","headingMatch","raw","out","rawLine","last","href","_b","_c"],"mappings":"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"}