@zzusp/ccsm 1.0.0 → 1.0.1

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 (58) hide show
  1. package/README.md +7 -3
  2. package/bin/cli.mjs +52 -52
  3. package/dist/assets/DiskUsage-CKhggLs5.js +2 -0
  4. package/dist/assets/DiskUsage-CKhggLs5.js.map +1 -0
  5. package/dist/assets/{ImportPage-b8NORa8b.js → ImportPage-wge4VhZ-.js} +2 -2
  6. package/dist/assets/{ImportPage-b8NORa8b.js.map → ImportPage-wge4VhZ-.js.map} +1 -1
  7. package/dist/assets/{ProjectMemory-aSV8UzQ9.js → ProjectMemory-Q4XX40j_.js} +2 -2
  8. package/dist/assets/{ProjectMemory-aSV8UzQ9.js.map → ProjectMemory-Q4XX40j_.js.map} +1 -1
  9. package/dist/assets/{charts-A5eNHLjX.js → charts-jxJqXXUr.js} +2 -2
  10. package/dist/assets/{charts-A5eNHLjX.js.map → charts-jxJqXXUr.js.map} +1 -1
  11. package/dist/assets/index-7aMrnHJG.js +7 -0
  12. package/dist/assets/index-7aMrnHJG.js.map +1 -0
  13. package/dist/assets/index-BOeI_J4B.css +1 -0
  14. package/dist/assets/{query-C1K1uQRu.js → query-CS7JQ86v.js} +2 -2
  15. package/dist/assets/{query-C1K1uQRu.js.map → query-CS7JQ86v.js.map} +1 -1
  16. package/dist/assets/{react-W0jzChlo.js → react-CPkiFScu.js} +10 -10
  17. package/dist/assets/{react-W0jzChlo.js.map → react-CPkiFScu.js.map} +1 -1
  18. package/dist/assets/{router-DfbutHY3.js → router-DwaHAh1G.js} +2 -2
  19. package/dist/assets/{router-DfbutHY3.js.map → router-DwaHAh1G.js.map} +1 -1
  20. package/dist/assets/vendor-Cs8vYp-N.js +27 -0
  21. package/dist/assets/vendor-Cs8vYp-N.js.map +1 -0
  22. package/dist/favicon.svg +7 -7
  23. package/dist/index.html +6 -6
  24. package/package.json +83 -72
  25. package/server/index.ts +130 -126
  26. package/server/lib/active-sessions.test.ts +119 -0
  27. package/server/lib/bundle.test.ts +182 -0
  28. package/server/lib/claude-paths.test.ts +126 -0
  29. package/server/lib/claude-paths.ts +19 -12
  30. package/server/lib/cleanup-suggestions.ts +131 -0
  31. package/server/lib/constants.ts +1 -0
  32. package/server/lib/delete.test.ts +244 -0
  33. package/server/lib/delete.ts +5 -16
  34. package/server/lib/disk-usage.ts +6 -8
  35. package/server/lib/export-import-bundle.test.ts +337 -0
  36. package/server/lib/modified-files.test.ts +280 -0
  37. package/server/lib/modified-files.ts +228 -0
  38. package/server/lib/open-folder.ts +22 -15
  39. package/server/lib/parse-jsonl.ts +35 -3
  40. package/server/lib/safe-id.test.ts +41 -0
  41. package/server/lib/safe-remove.test.ts +73 -0
  42. package/server/lib/safe-remove.ts +25 -0
  43. package/server/lib/scan.ts +103 -0
  44. package/server/lib/update.ts +67 -0
  45. package/server/lib/version.test.ts +39 -0
  46. package/server/lib/version.ts +117 -0
  47. package/server/routes/disk-cleanup.ts +54 -0
  48. package/server/routes/sessions.ts +49 -0
  49. package/server/routes/version.ts +34 -0
  50. package/shared/constants.ts +5 -0
  51. package/shared/types.ts +152 -0
  52. package/dist/assets/DiskUsage-Bq4VaoUA.js +0 -2
  53. package/dist/assets/DiskUsage-Bq4VaoUA.js.map +0 -1
  54. package/dist/assets/index-DLATR3tZ.js +0 -5
  55. package/dist/assets/index-DLATR3tZ.js.map +0 -1
  56. package/dist/assets/index-DLDtbkux.css +0 -1
  57. package/dist/assets/vendor-CH80ylbS.js +0 -19
  58. package/dist/assets/vendor-CH80ylbS.js.map +0 -1
@@ -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-7aMrnHJG.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-Q4XX40j_.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ProjectMemory-aSV8UzQ9.js","sources":["../../web/src/routes/ProjectMemory.tsx"],"sourcesContent":["import { useQuery } from '@tanstack/react-query';\r\nimport { useEffect, useMemo, useRef, useState } from 'react';\r\nimport { useParams, useSearchParams } from 'react-router-dom';\r\nimport Breadcrumbs, { BreadcrumbFolderIcon } from '../components/Breadcrumbs.tsx';\r\nimport { Loading } from '../components/Loading.tsx';\r\nimport PageHeader, { MetaItem, Sep } from '../components/PageHeader.tsx';\r\nimport {\r\n api,\r\n type MemoryEntry,\r\n type MemoryResponse,\r\n type MemoryType,\r\n type ProjectSummary,\r\n} from '../lib/api.ts';\r\nimport { formatBytes, formatRelativeTime } from '../lib/format.ts';\r\nimport { useT } from '../lib/i18n.ts';\r\nimport { queryKeys } from '../lib/query-keys.ts';\r\n\r\ntype GroupKey = MemoryType | 'other';\r\n\r\ninterface ParsedLink {\r\n title: string;\r\n href: string;\r\n hook: string;\r\n}\r\ninterface IndexLine {\r\n raw: string;\r\n link: ParsedLink | null;\r\n}\r\n\r\ntype Row =\r\n | { kind: 'entry'; entry: MemoryEntry; hook: string }\r\n | { kind: 'missing'; title: string; hook: string }\r\n | { kind: 'heading'; text: string }\r\n | { kind: 'text'; text: string }\r\n | { kind: 'spacer' };\r\n\r\nconst LINK_RE = /^[\\s*-]*\\[(?<title>[^\\]]+)\\]\\((?<href>[^)]+)\\)\\s*[—–\\-:]?\\s*(?<hook>.*)$/;\r\n\r\nexport default function ProjectMemoryRoute() {\r\n const t = useT();\r\n const { projectId } = useParams<{ projectId: string }>();\r\n const id = projectId ?? '';\r\n const [searchParams, setSearchParams] = useSearchParams();\r\n\r\n const memoryQuery = useQuery({\r\n queryKey: queryKeys.projectMemory(id),\r\n queryFn: () => api<MemoryResponse>(`/api/projects/${encodeURIComponent(id)}/memory`),\r\n enabled: !!id,\r\n });\r\n\r\n const projectsQuery = useQuery({\r\n queryKey: queryKeys.projects(),\r\n queryFn: () => api<ProjectSummary[]>('/api/projects'),\r\n });\r\n const project = useMemo(\r\n () => projectsQuery.data?.find((p) => p.id === id),\r\n [projectsQuery.data, id],\r\n );\r\n\r\n const data = memoryQuery.data;\r\n const entries = useMemo(() => data?.entries ?? [], [data?.entries]);\r\n const indexLines = useMemo(() => parseIndex(data?.index ?? null), [data?.index]);\r\n\r\n const hookByFilename = useMemo(() => {\r\n const m = new Map<string, string>();\r\n for (const line of indexLines) {\r\n if (line.link) m.set(line.link.href, line.link.hook);\r\n }\r\n return m;\r\n }, [indexLines]);\r\n\r\n const { rows, orphans } = useMemo(\r\n () => buildRows(indexLines, entries),\r\n [indexLines, entries],\r\n );\r\n\r\n // URL-driven drawer state\r\n const drawerEntry = searchParams.get('entry');\r\n const drawerView = searchParams.get('view');\r\n const drawerOpen = drawerEntry !== null || drawerView === 'raw';\r\n\r\n function openEntry(filename: string) {\r\n const next = new URLSearchParams(searchParams);\r\n next.set('entry', filename);\r\n next.delete('view');\r\n setSearchParams(next);\r\n }\r\n function openRaw() {\r\n const next = new URLSearchParams(searchParams);\r\n next.set('view', 'raw');\r\n next.delete('entry');\r\n setSearchParams(next);\r\n }\r\n function closeDrawer() {\r\n const next = new URLSearchParams(searchParams);\r\n next.delete('entry');\r\n next.delete('view');\r\n setSearchParams(next);\r\n }\r\n\r\n const drawerTarget = useMemo(() => {\r\n if (drawerView === 'raw') return { kind: 'raw' as const };\r\n if (drawerEntry) {\r\n const entry = entries.find((e) => e.filename === drawerEntry) ?? null;\r\n return { kind: 'entry' as const, entry, filename: drawerEntry };\r\n }\r\n return null;\r\n }, [drawerEntry, drawerView, entries]);\r\n\r\n const [query, setQuery] = useState('');\r\n const trimmed = query.trim().toLowerCase();\r\n const searchActive = trimmed.length > 0;\r\n\r\n const filteredRows: Row[] = useMemo(() => {\r\n if (!searchActive) return rows;\r\n return rows.filter((r) => r.kind === 'entry' && matchEntry(r.entry, r.hook, trimmed));\r\n }, [rows, searchActive, trimmed]);\r\n\r\n const filteredOrphans = useMemo(\r\n () => (searchActive ? orphans.filter((e) => matchEntry(e, '', trimmed)) : orphans),\r\n [orphans, searchActive, trimmed],\r\n );\r\n\r\n const totalEntries = entries.length;\r\n const indexAvailable = !!data?.index;\r\n const hasContent = totalEntries > 0 || indexAvailable;\r\n\r\n const totalMatched =\r\n filteredRows.filter((r) => r.kind === 'entry').length + filteredOrphans.length;\r\n\r\n const cwd = project?.decodedCwd ?? id;\r\n const parts = cwd.split(/[\\\\/]+/).filter(Boolean);\r\n const tail = parts.at(-1) ?? cwd;\r\n const head = parts.slice(0, -1).join('/');\r\n\r\n const lastUpdate = useMemo(() => {\r\n let latest: number | null = null;\r\n for (const e of entries) {\r\n if (!e.mtime) continue;\r\n const t = Date.parse(e.mtime);\r\n if (Number.isFinite(t) && (latest === null || t > latest)) latest = t;\r\n }\r\n return latest ? new Date(latest).toISOString() : null;\r\n }, [entries]);\r\n\r\n const typeCount = useMemo(() => {\r\n const s = new Set<GroupKey>();\r\n for (const e of entries) s.add((e.type ?? 'other') as GroupKey);\r\n return s.size;\r\n }, [entries]);\r\n\r\n return (\r\n <section>\r\n <Breadcrumbs\r\n items={[\r\n { label: t('session.crumbProjects'), to: '/' },\r\n {\r\n label: tail,\r\n to: `/projects/${encodeURIComponent(id)}`,\r\n mono: true,\r\n icon: <BreadcrumbFolderIcon />,\r\n },\r\n { label: t('memory.title') },\r\n ]}\r\n />\r\n\r\n <div className=\"surface-card mt-6 p-6\">\r\n <PageHeader\r\n eyebrow={\r\n <span className=\"inline-flex items-center gap-2\">\r\n {head ? (\r\n <span className=\"font-mono normal-case tracking-normal\">{head}/</span>\r\n ) : (\r\n t('memory.action.open')\r\n )}\r\n </span>\r\n }\r\n title={t('memory.title')}\r\n meta={\r\n data ? (\r\n <>\r\n <MetaItem label={t('memory.meta.entries')} value={totalEntries} />\r\n {typeCount > 0 && (\r\n <>\r\n <Sep />\r\n <MetaItem label={t('memory.meta.types')} value={typeCount} />\r\n </>\r\n )}\r\n {lastUpdate && (\r\n <>\r\n <Sep />\r\n <MetaItem\r\n label={t('memory.meta.lastUpdate')}\r\n value={formatRelativeTime(lastUpdate)}\r\n />\r\n </>\r\n )}\r\n </>\r\n ) : null\r\n }\r\n />\r\n </div>\r\n\r\n {memoryQuery.isLoading && <Loading label={t('memory.loading')} className=\"mt-6\" />}\r\n {memoryQuery.error && (\r\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)]\">\r\n {t('common.failedMemory')}: {(memoryQuery.error as Error).message}\r\n </p>\r\n )}\r\n\r\n {data && !hasContent && <EmptyState />}\r\n\r\n {data && hasContent && (\r\n <IndexCard\r\n rows={filteredRows}\r\n orphans={filteredOrphans}\r\n totalMatched={totalMatched}\r\n totalEntries={totalEntries}\r\n query={query}\r\n onQuery={setQuery}\r\n searchActive={searchActive}\r\n indexAvailable={indexAvailable}\r\n onOpenEntry={openEntry}\r\n onOpenRaw={openRaw}\r\n />\r\n )}\r\n\r\n {drawerOpen && drawerTarget && (\r\n <Drawer\r\n target={drawerTarget}\r\n rawIndex={data?.index ?? ''}\r\n hookForEntry={\r\n drawerTarget.kind === 'entry' && drawerTarget.entry\r\n ? hookByFilename.get(drawerTarget.entry.filename) ?? null\r\n : null\r\n }\r\n onClose={closeDrawer}\r\n onJumpToCover={() => {\r\n closeDrawer();\r\n requestAnimationFrame(() => {\r\n const cover = document.getElementById('memo-index-card');\r\n cover?.scrollIntoView({ behavior: 'smooth', block: 'start' });\r\n });\r\n }}\r\n />\r\n )}\r\n </section>\r\n );\r\n}\r\n\r\nfunction IndexCard({\r\n rows,\r\n orphans,\r\n totalMatched,\r\n totalEntries,\r\n query,\r\n onQuery,\r\n searchActive,\r\n indexAvailable,\r\n onOpenEntry,\r\n onOpenRaw,\r\n}: {\r\n rows: Row[];\r\n orphans: MemoryEntry[];\r\n totalMatched: number;\r\n totalEntries: number;\r\n query: string;\r\n onQuery: (v: string) => void;\r\n searchActive: boolean;\r\n indexAvailable: boolean;\r\n onOpenEntry: (filename: string) => void;\r\n onOpenRaw: () => void;\r\n}) {\r\n const t = useT();\r\n const noResults = searchActive && totalMatched === 0;\r\n\r\n return (\r\n <div id=\"memo-index-card\" className=\"surface-card mt-6 px-7 py-6\">\r\n <div className=\"flex items-baseline justify-between gap-3\">\r\n <div>\r\n <div className=\"eyebrow\">{t('memory.cover.title')}</div>\r\n <h2 className=\"mt-0.5 font-display text-[18px] font-medium tracking-tight text-[var(--color-fg-primary)]\">\r\n {t('memory.cover.subtitle')}\r\n </h2>\r\n </div>\r\n {indexAvailable && (\r\n <button\r\n type=\"button\"\r\n onClick={onOpenRaw}\r\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)]\"\r\n >\r\n {t('memory.cover.viewRaw')} ↗\r\n </button>\r\n )}\r\n </div>\r\n\r\n <div className=\"mt-4 flex flex-wrap items-center gap-3\">\r\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)]\">\r\n <SearchIcon className=\"text-[var(--color-fg-muted)]\" />\r\n <input\r\n type=\"search\"\r\n value={query}\r\n onChange={(e) => onQuery(e.target.value)}\r\n placeholder={t('memory.search.placeholder')}\r\n className=\"w-full bg-transparent text-sm text-[var(--color-fg-primary)] placeholder:text-[var(--color-fg-faint)] focus:outline-none\"\r\n />\r\n </div>\r\n <span className=\"font-mono text-[10.5px] uppercase tracking-[0.18em] tabular-nums text-[var(--color-fg-faint)]\">\r\n {searchActive\r\n ? t('memory.list.count', { n: totalMatched, total: totalEntries })\r\n : `${totalEntries} ${t('memory.meta.entries').toLowerCase()}`}\r\n </span>\r\n </div>\r\n\r\n <div className=\"rule-dotted mt-5\" aria-hidden />\r\n\r\n {noResults ? (\r\n <p className=\"mt-6 text-sm text-[var(--color-fg-muted)]\">{t('memory.list.noResults')}</p>\r\n ) : (\r\n <ul className=\"mt-3\">\r\n {rows.map((row, i) => (\r\n <RowItem key={i} row={row} onOpenEntry={onOpenEntry} />\r\n ))}\r\n\r\n {orphans.length > 0 && (\r\n <>\r\n {!searchActive && rows.length > 0 && (\r\n <li aria-hidden className=\"h-3\" />\r\n )}\r\n <li className=\"pt-3 pb-2\">\r\n <div className=\"flex items-baseline gap-3\">\r\n <span className=\"font-mono text-[10.5px] uppercase tracking-[0.18em] text-[var(--color-fg-faint)]\">\r\n {t('memory.cover.orphan')}\r\n </span>\r\n <span className=\"font-mono text-[10.5px] tabular-nums text-[var(--color-fg-faint)]\">\r\n · {orphans.length}\r\n </span>\r\n <span aria-hidden className=\"ml-2 h-px flex-1 bg-[var(--color-hairline)]\" />\r\n </div>\r\n </li>\r\n {orphans.map((e) => (\r\n <RowItem\r\n key={e.filename}\r\n row={{ kind: 'entry', entry: e, hook: '' }}\r\n onOpenEntry={onOpenEntry}\r\n />\r\n ))}\r\n </>\r\n )}\r\n </ul>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nfunction RowItem({\r\n row,\r\n onOpenEntry,\r\n}: {\r\n row: Row;\r\n onOpenEntry: (filename: string) => void;\r\n}) {\r\n const t = useT();\r\n\r\n if (row.kind === 'spacer') {\r\n return <li aria-hidden className=\"h-2\" />;\r\n }\r\n if (row.kind === 'heading') {\r\n return (\r\n <li className=\"pt-4 pb-1\">\r\n <div className=\"font-mono text-[10.5px] uppercase tracking-[0.18em] text-[var(--color-fg-muted)]\">\r\n {row.text}\r\n </div>\r\n </li>\r\n );\r\n }\r\n if (row.kind === 'text') {\r\n return (\r\n <li className=\"px-1 py-0.5 text-[12.5px] text-[var(--color-fg-faint)] whitespace-pre-wrap break-words\">\r\n {row.text}\r\n </li>\r\n );\r\n }\r\n if (row.kind === 'missing') {\r\n return (\r\n <li\r\n title={t('memory.cover.missingTooltip')}\r\n className=\"flex items-baseline gap-3 px-2 py-1.5 text-[var(--color-fg-faint)]\"\r\n >\r\n <span className=\"text-[14px] font-medium line-through decoration-[var(--color-fg-faint)]/50\">\r\n {row.title}\r\n </span>\r\n {row.hook && <span className=\"truncate text-[12px]\">{row.hook}</span>}\r\n </li>\r\n );\r\n }\r\n\r\n const entry = row.entry;\r\n const typeKey: GroupKey = entry.type ?? 'other';\r\n const title = entry.name ?? entry.filename;\r\n const hookText = row.hook || entry.description || '';\r\n return (\r\n <li>\r\n <button\r\n type=\"button\"\r\n onClick={() => onOpenEntry(entry.filename)}\r\n className={`memo-row memo-type-${typeKey}`}\r\n >\r\n <span aria-hidden className=\"memo-row-dot\" />\r\n <div className=\"memo-row-content\">\r\n <div className=\"memo-row-headline\">\r\n <span className=\"memo-row-title\">{title}</span>\r\n {entry.mtime && (\r\n <span className=\"memo-row-meta-inline\">{formatRelativeTime(entry.mtime)}</span>\r\n )}\r\n <TypeChip k={typeKey} />\r\n </div>\r\n {hookText && <p className=\"memo-row-hook\">{hookText}</p>}\r\n </div>\r\n <span aria-hidden className=\"memo-row-chevron\">↗</span>\r\n </button>\r\n </li>\r\n );\r\n}\r\n\r\nfunction TypeChip({ k }: { k: GroupKey }) {\r\n const t = useT();\r\n const label =\r\n k === 'user'\r\n ? t('memory.type.user')\r\n : k === 'feedback'\r\n ? t('memory.type.feedback')\r\n : k === 'project'\r\n ? t('memory.type.project')\r\n : k === 'reference'\r\n ? t('memory.type.reference')\r\n : t('memory.type.other');\r\n return <span className=\"memo-chip\">{label}</span>;\r\n}\r\n\r\ntype DrawerTarget =\r\n | { kind: 'entry'; entry: MemoryEntry | null; filename: string }\r\n | { kind: 'raw' };\r\n\r\nfunction Drawer({\r\n target,\r\n rawIndex,\r\n hookForEntry,\r\n onClose,\r\n onJumpToCover,\r\n}: {\r\n target: DrawerTarget;\r\n rawIndex: string;\r\n hookForEntry: string | null;\r\n onClose: () => void;\r\n onJumpToCover: () => void;\r\n}) {\r\n const t = useT();\r\n const panelRef = useRef<HTMLDivElement | null>(null);\r\n\r\n useEffect(() => {\r\n const onKey = (e: KeyboardEvent) => {\r\n if (e.key === 'Escape') {\r\n e.preventDefault();\r\n onClose();\r\n }\r\n };\r\n window.addEventListener('keydown', onKey);\r\n const prevOverflow = document.body.style.overflow;\r\n document.body.style.overflow = 'hidden';\r\n requestAnimationFrame(() => panelRef.current?.focus());\r\n return () => {\r\n window.removeEventListener('keydown', onKey);\r\n document.body.style.overflow = prevOverflow;\r\n };\r\n }, [onClose]);\r\n\r\n const typeKey: GroupKey =\r\n target.kind === 'entry' ? (target.entry?.type ?? 'other') : 'reference';\r\n\r\n return (\r\n <>\r\n <div className=\"memo-drawer-backdrop\" onClick={onClose} aria-hidden />\r\n <div\r\n ref={panelRef}\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n tabIndex={-1}\r\n className={`memo-drawer-panel memo-type-${typeKey} focus:outline-none`}\r\n >\r\n <div className=\"flex items-start justify-between gap-3 border-b border-[var(--color-hairline)] px-7 pt-7 pb-5\">\r\n <div className=\"min-w-0 flex-1\">\r\n {target.kind === 'entry' ? (\r\n <>\r\n <TypeChip k={typeKey} />\r\n {target.entry ? (\r\n <>\r\n <h2 className=\"mt-3 font-display text-[24px] font-light leading-tight tracking-tight text-[var(--color-fg-primary)]\">\r\n {target.entry.name ?? target.entry.filename}\r\n </h2>\r\n <p className=\"mt-1.5 font-mono text-[11px] uppercase tracking-[0.16em] text-[var(--color-fg-faint)]\">\r\n {target.entry.filename} · {formatBytes(target.entry.bytes)}\r\n {target.entry.mtime ? ` · ${formatRelativeTime(target.entry.mtime)}` : ''}\r\n </p>\r\n </>\r\n ) : (\r\n <>\r\n <h2 className=\"mt-3 font-display text-[22px] font-light leading-tight text-[var(--color-fg-primary)]\">\r\n {t('memory.drawer.notFound.title')}\r\n </h2>\r\n <p className=\"mt-1.5 font-mono text-[11px] uppercase tracking-[0.16em] text-[var(--color-fg-faint)]\">\r\n {target.filename}\r\n </p>\r\n </>\r\n )}\r\n </>\r\n ) : (\r\n <>\r\n <span className=\"memo-chip memo-type-reference\">{t('memory.cover.title')}</span>\r\n <h2 className=\"mt-3 font-display text-[24px] font-light leading-tight tracking-tight text-[var(--color-fg-primary)]\">\r\n {t('memory.raw.title')}\r\n </h2>\r\n <p className=\"mt-1.5 font-mono text-[11px] uppercase tracking-[0.16em] text-[var(--color-fg-faint)]\">\r\n {t('memory.raw.subtitle')}\r\n </p>\r\n </>\r\n )}\r\n </div>\r\n <button\r\n type=\"button\"\r\n onClick={onClose}\r\n aria-label={t('memory.drawer.close')}\r\n className=\"rounded-md p-2 text-[var(--color-fg-muted)] hover:bg-[var(--color-sunken)] hover:text-[var(--color-fg-primary)]\"\r\n >\r\n <CloseIcon />\r\n </button>\r\n </div>\r\n\r\n <div className=\"flex-1 overflow-y-auto px-7 py-6\">\r\n {target.kind === 'entry' && target.entry ? (\r\n <EntryDrawerBody\r\n entry={target.entry}\r\n hookForEntry={hookForEntry}\r\n onJumpToCover={onJumpToCover}\r\n />\r\n ) : target.kind === 'entry' ? (\r\n <NotFoundDrawerBody filename={target.filename} onJumpToCover={onJumpToCover} />\r\n ) : (\r\n <RawDrawerBody source={rawIndex} />\r\n )}\r\n </div>\r\n </div>\r\n </>\r\n );\r\n}\r\n\r\nfunction EntryDrawerBody({\r\n entry,\r\n hookForEntry,\r\n onJumpToCover,\r\n}: {\r\n entry: MemoryEntry;\r\n hookForEntry: string | null;\r\n onJumpToCover: () => void;\r\n}) {\r\n const t = useT();\r\n const body = entry.body.trim();\r\n return (\r\n <div>\r\n {entry.description && (\r\n <p className=\"text-[14px] text-[var(--color-fg-secondary)]\">{entry.description}</p>\r\n )}\r\n <pre\r\n className={\r\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)] ' +\r\n (entry.description ? 'mt-5' : '')\r\n }\r\n >\r\n {body || '—'}\r\n </pre>\r\n {hookForEntry && (\r\n <div className=\"mt-7\">\r\n <div className=\"rule-dotted\" aria-hidden />\r\n <div className=\"mt-4 flex items-baseline justify-between gap-3\">\r\n <div className=\"eyebrow\">{t('memory.drawer.indexHook')}</div>\r\n <button\r\n type=\"button\"\r\n onClick={onJumpToCover}\r\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)]\"\r\n >\r\n {t('memory.cover.title')} ↑\r\n </button>\r\n </div>\r\n <p className=\"mt-1.5 text-[13px] text-[var(--color-fg-secondary)]\">{hookForEntry}</p>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nfunction NotFoundDrawerBody({\r\n filename,\r\n onJumpToCover,\r\n}: {\r\n filename: string;\r\n onJumpToCover: () => void;\r\n}) {\r\n const t = useT();\r\n return (\r\n <div>\r\n <p className=\"text-sm text-[var(--color-fg-secondary)]\">{t('memory.drawer.notFound.body')}</p>\r\n <p className=\"mt-3 font-mono text-[12px] text-[var(--color-fg-faint)]\">{filename}</p>\r\n <button\r\n type=\"button\"\r\n onClick={onJumpToCover}\r\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)]\"\r\n >\r\n {t('memory.cover.title')} ↑\r\n </button>\r\n </div>\r\n );\r\n}\r\n\r\nfunction RawDrawerBody({ source }: { source: string }) {\r\n const body = source.trim();\r\n return (\r\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)]\">\r\n {body || '—'}\r\n </pre>\r\n );\r\n}\r\n\r\nfunction EmptyState() {\r\n const t = useT();\r\n return (\r\n <div className=\"surface-card mt-6 px-8 py-14 text-center\">\r\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)]\">\r\n <BookmarkIcon />\r\n </div>\r\n <h2 className=\"mt-5 font-display text-[20px] font-light tracking-tight text-[var(--color-fg-primary)]\">\r\n {t('memory.empty.title')}\r\n </h2>\r\n <p className=\"mx-auto mt-3 max-w-xl text-[13px] leading-relaxed text-[var(--color-fg-secondary)]\">\r\n {t('memory.empty.body')}\r\n </p>\r\n </div>\r\n );\r\n}\r\n\r\nfunction SearchIcon({ className = '' }: { className?: string }) {\r\n return (\r\n <svg\r\n width=\"14\"\r\n height=\"14\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"1.7\"\r\n strokeLinecap=\"round\"\r\n className={className}\r\n aria-hidden\r\n >\r\n <circle cx=\"11\" cy=\"11\" r=\"6.2\" />\r\n <path d=\"M20 20l-4.3-4.3\" />\r\n </svg>\r\n );\r\n}\r\n\r\nfunction CloseIcon() {\r\n return (\r\n <svg\r\n width=\"16\"\r\n height=\"16\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"1.8\"\r\n strokeLinecap=\"round\"\r\n aria-hidden\r\n >\r\n <path d=\"M6 6l12 12M18 6L6 18\" />\r\n </svg>\r\n );\r\n}\r\n\r\nfunction BookmarkIcon() {\r\n return (\r\n <svg\r\n width=\"20\"\r\n height=\"20\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"1.6\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n aria-hidden\r\n >\r\n <path d=\"M6 4h12v17l-6-4-6 4z\" />\r\n </svg>\r\n );\r\n}\r\n\r\nfunction matchEntry(entry: MemoryEntry, hook: string, q: string): boolean {\r\n const fields = [\r\n entry.name ?? '',\r\n entry.filename,\r\n entry.description ?? '',\r\n entry.body,\r\n hook,\r\n ];\r\n return fields.some((f) => f.toLowerCase().includes(q));\r\n}\r\n\r\nfunction buildRows(\r\n indexLines: IndexLine[],\r\n entries: MemoryEntry[],\r\n): { rows: Row[]; orphans: MemoryEntry[] } {\r\n const filenameToEntry = new Map(entries.map((e) => [e.filename, e]));\r\n const seen = new Set<string>();\r\n const rows: Row[] = [];\r\n\r\n for (const line of indexLines) {\r\n if (line.link) {\r\n const entry = filenameToEntry.get(line.link.href);\r\n if (entry) {\r\n rows.push({ kind: 'entry', entry, hook: line.link.hook });\r\n seen.add(entry.filename);\r\n } else {\r\n rows.push({ kind: 'missing', title: line.link.title, hook: line.link.hook });\r\n }\r\n continue;\r\n }\r\n const txt = line.raw.trim();\r\n if (!txt) {\r\n rows.push({ kind: 'spacer' });\r\n continue;\r\n }\r\n const headingMatch = /^(#{1,6})\\s+(.+?)\\s*$/.exec(txt);\r\n if (headingMatch) {\r\n rows.push({ kind: 'heading', text: headingMatch[2]! });\r\n } else {\r\n rows.push({ kind: 'text', text: line.raw });\r\n }\r\n }\r\n\r\n const orphans = entries.filter((e) => !seen.has(e.filename));\r\n return { rows, orphans };\r\n}\r\n\r\nfunction parseIndex(raw: string | null): IndexLine[] {\r\n if (!raw) return [];\r\n const out: IndexLine[] = [];\r\n for (const rawLine of raw.split(/\\r?\\n/)) {\r\n const line = rawLine.trimEnd();\r\n if (line.trim() === '') {\r\n const last = out[out.length - 1];\r\n if (last && (last.link || last.raw.trim() !== '')) {\r\n out.push({ raw: '', link: null });\r\n }\r\n continue;\r\n }\r\n const m = LINK_RE.exec(line);\r\n const title = m?.groups?.title;\r\n const href = m?.groups?.href;\r\n if (m && title && href) {\r\n out.push({\r\n raw: line,\r\n link: { title: title.trim(), href: href.trim(), hook: (m.groups?.hook ?? '').trim() },\r\n });\r\n } else {\r\n out.push({ raw: line, link: null });\r\n }\r\n }\r\n while (out.length > 0) {\r\n const last = out[out.length - 1];\r\n if (last && !last.link && last.raw.trim() === '') out.pop();\r\n else break;\r\n }\r\n return out;\r\n}\r\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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"}
1
+ {"version":3,"file":"ProjectMemory-Q4XX40j_.js","sources":["../../web/src/routes/ProjectMemory.tsx"],"sourcesContent":["import { useQuery } from '@tanstack/react-query';\r\nimport { useEffect, useMemo, useRef, useState } from 'react';\r\nimport { useParams, useSearchParams } from 'react-router-dom';\r\nimport Breadcrumbs, { BreadcrumbFolderIcon } from '../components/Breadcrumbs.tsx';\r\nimport { Loading } from '../components/Loading.tsx';\r\nimport PageHeader, { MetaItem, Sep } from '../components/PageHeader.tsx';\r\nimport {\r\n api,\r\n type MemoryEntry,\r\n type MemoryResponse,\r\n type MemoryType,\r\n type ProjectSummary,\r\n} from '../lib/api.ts';\r\nimport { formatBytes, formatRelativeTime } from '../lib/format.ts';\r\nimport { useT } from '../lib/i18n.ts';\r\nimport { queryKeys } from '../lib/query-keys.ts';\r\n\r\ntype GroupKey = MemoryType | 'other';\r\n\r\ninterface ParsedLink {\r\n title: string;\r\n href: string;\r\n hook: string;\r\n}\r\ninterface IndexLine {\r\n raw: string;\r\n link: ParsedLink | null;\r\n}\r\n\r\ntype Row =\r\n | { kind: 'entry'; entry: MemoryEntry; hook: string }\r\n | { kind: 'missing'; title: string; hook: string }\r\n | { kind: 'heading'; text: string }\r\n | { kind: 'text'; text: string }\r\n | { kind: 'spacer' };\r\n\r\nconst LINK_RE = /^[\\s*-]*\\[(?<title>[^\\]]+)\\]\\((?<href>[^)]+)\\)\\s*[—–\\-:]?\\s*(?<hook>.*)$/;\r\n\r\nexport default function ProjectMemoryRoute() {\r\n const t = useT();\r\n const { projectId } = useParams<{ projectId: string }>();\r\n const id = projectId ?? '';\r\n const [searchParams, setSearchParams] = useSearchParams();\r\n\r\n const memoryQuery = useQuery({\r\n queryKey: queryKeys.projectMemory(id),\r\n queryFn: () => api<MemoryResponse>(`/api/projects/${encodeURIComponent(id)}/memory`),\r\n enabled: !!id,\r\n });\r\n\r\n const projectsQuery = useQuery({\r\n queryKey: queryKeys.projects(),\r\n queryFn: () => api<ProjectSummary[]>('/api/projects'),\r\n });\r\n const project = useMemo(\r\n () => projectsQuery.data?.find((p) => p.id === id),\r\n [projectsQuery.data, id],\r\n );\r\n\r\n const data = memoryQuery.data;\r\n const entries = useMemo(() => data?.entries ?? [], [data?.entries]);\r\n const indexLines = useMemo(() => parseIndex(data?.index ?? null), [data?.index]);\r\n\r\n const hookByFilename = useMemo(() => {\r\n const m = new Map<string, string>();\r\n for (const line of indexLines) {\r\n if (line.link) m.set(line.link.href, line.link.hook);\r\n }\r\n return m;\r\n }, [indexLines]);\r\n\r\n const { rows, orphans } = useMemo(\r\n () => buildRows(indexLines, entries),\r\n [indexLines, entries],\r\n );\r\n\r\n // URL-driven drawer state\r\n const drawerEntry = searchParams.get('entry');\r\n const drawerView = searchParams.get('view');\r\n const drawerOpen = drawerEntry !== null || drawerView === 'raw';\r\n\r\n function openEntry(filename: string) {\r\n const next = new URLSearchParams(searchParams);\r\n next.set('entry', filename);\r\n next.delete('view');\r\n setSearchParams(next);\r\n }\r\n function openRaw() {\r\n const next = new URLSearchParams(searchParams);\r\n next.set('view', 'raw');\r\n next.delete('entry');\r\n setSearchParams(next);\r\n }\r\n function closeDrawer() {\r\n const next = new URLSearchParams(searchParams);\r\n next.delete('entry');\r\n next.delete('view');\r\n setSearchParams(next);\r\n }\r\n\r\n const drawerTarget = useMemo(() => {\r\n if (drawerView === 'raw') return { kind: 'raw' as const };\r\n if (drawerEntry) {\r\n const entry = entries.find((e) => e.filename === drawerEntry) ?? null;\r\n return { kind: 'entry' as const, entry, filename: drawerEntry };\r\n }\r\n return null;\r\n }, [drawerEntry, drawerView, entries]);\r\n\r\n const [query, setQuery] = useState('');\r\n const trimmed = query.trim().toLowerCase();\r\n const searchActive = trimmed.length > 0;\r\n\r\n const filteredRows: Row[] = useMemo(() => {\r\n if (!searchActive) return rows;\r\n return rows.filter((r) => r.kind === 'entry' && matchEntry(r.entry, r.hook, trimmed));\r\n }, [rows, searchActive, trimmed]);\r\n\r\n const filteredOrphans = useMemo(\r\n () => (searchActive ? orphans.filter((e) => matchEntry(e, '', trimmed)) : orphans),\r\n [orphans, searchActive, trimmed],\r\n );\r\n\r\n const totalEntries = entries.length;\r\n const indexAvailable = !!data?.index;\r\n const hasContent = totalEntries > 0 || indexAvailable;\r\n\r\n const totalMatched =\r\n filteredRows.filter((r) => r.kind === 'entry').length + filteredOrphans.length;\r\n\r\n const cwd = project?.decodedCwd ?? id;\r\n const parts = cwd.split(/[\\\\/]+/).filter(Boolean);\r\n const tail = parts.at(-1) ?? cwd;\r\n const head = parts.slice(0, -1).join('/');\r\n\r\n const lastUpdate = useMemo(() => {\r\n let latest: number | null = null;\r\n for (const e of entries) {\r\n if (!e.mtime) continue;\r\n const t = Date.parse(e.mtime);\r\n if (Number.isFinite(t) && (latest === null || t > latest)) latest = t;\r\n }\r\n return latest ? new Date(latest).toISOString() : null;\r\n }, [entries]);\r\n\r\n const typeCount = useMemo(() => {\r\n const s = new Set<GroupKey>();\r\n for (const e of entries) s.add((e.type ?? 'other') as GroupKey);\r\n return s.size;\r\n }, [entries]);\r\n\r\n return (\r\n <section>\r\n <Breadcrumbs\r\n items={[\r\n { label: t('session.crumbProjects'), to: '/' },\r\n {\r\n label: tail,\r\n to: `/projects/${encodeURIComponent(id)}`,\r\n mono: true,\r\n icon: <BreadcrumbFolderIcon />,\r\n },\r\n { label: t('memory.title') },\r\n ]}\r\n />\r\n\r\n <div className=\"surface-card mt-6 p-6\">\r\n <PageHeader\r\n eyebrow={\r\n <span className=\"inline-flex items-center gap-2\">\r\n {head ? (\r\n <span className=\"font-mono normal-case tracking-normal\">{head}/</span>\r\n ) : (\r\n t('memory.action.open')\r\n )}\r\n </span>\r\n }\r\n title={t('memory.title')}\r\n meta={\r\n data ? (\r\n <>\r\n <MetaItem label={t('memory.meta.entries')} value={totalEntries} />\r\n {typeCount > 0 && (\r\n <>\r\n <Sep />\r\n <MetaItem label={t('memory.meta.types')} value={typeCount} />\r\n </>\r\n )}\r\n {lastUpdate && (\r\n <>\r\n <Sep />\r\n <MetaItem\r\n label={t('memory.meta.lastUpdate')}\r\n value={formatRelativeTime(lastUpdate)}\r\n />\r\n </>\r\n )}\r\n </>\r\n ) : null\r\n }\r\n />\r\n </div>\r\n\r\n {memoryQuery.isLoading && <Loading label={t('memory.loading')} className=\"mt-6\" />}\r\n {memoryQuery.error && (\r\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)]\">\r\n {t('common.failedMemory')}: {(memoryQuery.error as Error).message}\r\n </p>\r\n )}\r\n\r\n {data && !hasContent && <EmptyState />}\r\n\r\n {data && hasContent && (\r\n <IndexCard\r\n rows={filteredRows}\r\n orphans={filteredOrphans}\r\n totalMatched={totalMatched}\r\n totalEntries={totalEntries}\r\n query={query}\r\n onQuery={setQuery}\r\n searchActive={searchActive}\r\n indexAvailable={indexAvailable}\r\n onOpenEntry={openEntry}\r\n onOpenRaw={openRaw}\r\n />\r\n )}\r\n\r\n {drawerOpen && drawerTarget && (\r\n <Drawer\r\n target={drawerTarget}\r\n rawIndex={data?.index ?? ''}\r\n hookForEntry={\r\n drawerTarget.kind === 'entry' && drawerTarget.entry\r\n ? hookByFilename.get(drawerTarget.entry.filename) ?? null\r\n : null\r\n }\r\n onClose={closeDrawer}\r\n onJumpToCover={() => {\r\n closeDrawer();\r\n requestAnimationFrame(() => {\r\n const cover = document.getElementById('memo-index-card');\r\n cover?.scrollIntoView({ behavior: 'smooth', block: 'start' });\r\n });\r\n }}\r\n />\r\n )}\r\n </section>\r\n );\r\n}\r\n\r\nfunction IndexCard({\r\n rows,\r\n orphans,\r\n totalMatched,\r\n totalEntries,\r\n query,\r\n onQuery,\r\n searchActive,\r\n indexAvailable,\r\n onOpenEntry,\r\n onOpenRaw,\r\n}: {\r\n rows: Row[];\r\n orphans: MemoryEntry[];\r\n totalMatched: number;\r\n totalEntries: number;\r\n query: string;\r\n onQuery: (v: string) => void;\r\n searchActive: boolean;\r\n indexAvailable: boolean;\r\n onOpenEntry: (filename: string) => void;\r\n onOpenRaw: () => void;\r\n}) {\r\n const t = useT();\r\n const noResults = searchActive && totalMatched === 0;\r\n\r\n return (\r\n <div id=\"memo-index-card\" className=\"surface-card mt-6 px-7 py-6\">\r\n <div className=\"flex items-baseline justify-between gap-3\">\r\n <div>\r\n <div className=\"eyebrow\">{t('memory.cover.title')}</div>\r\n <h2 className=\"mt-0.5 font-display text-[18px] font-medium tracking-tight text-[var(--color-fg-primary)]\">\r\n {t('memory.cover.subtitle')}\r\n </h2>\r\n </div>\r\n {indexAvailable && (\r\n <button\r\n type=\"button\"\r\n onClick={onOpenRaw}\r\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)]\"\r\n >\r\n {t('memory.cover.viewRaw')} ↗\r\n </button>\r\n )}\r\n </div>\r\n\r\n <div className=\"mt-4 flex flex-wrap items-center gap-3\">\r\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)]\">\r\n <SearchIcon className=\"text-[var(--color-fg-muted)]\" />\r\n <input\r\n type=\"search\"\r\n value={query}\r\n onChange={(e) => onQuery(e.target.value)}\r\n placeholder={t('memory.search.placeholder')}\r\n className=\"w-full bg-transparent text-sm text-[var(--color-fg-primary)] placeholder:text-[var(--color-fg-faint)] focus:outline-none\"\r\n />\r\n </div>\r\n <span className=\"font-mono text-[10.5px] uppercase tracking-[0.18em] tabular-nums text-[var(--color-fg-faint)]\">\r\n {searchActive\r\n ? t('memory.list.count', { n: totalMatched, total: totalEntries })\r\n : `${totalEntries} ${t('memory.meta.entries').toLowerCase()}`}\r\n </span>\r\n </div>\r\n\r\n <div className=\"rule-dotted mt-5\" aria-hidden />\r\n\r\n {noResults ? (\r\n <p className=\"mt-6 text-sm text-[var(--color-fg-muted)]\">{t('memory.list.noResults')}</p>\r\n ) : (\r\n <ul className=\"mt-3\">\r\n {rows.map((row, i) => (\r\n <RowItem key={i} row={row} onOpenEntry={onOpenEntry} />\r\n ))}\r\n\r\n {orphans.length > 0 && (\r\n <>\r\n {!searchActive && rows.length > 0 && (\r\n <li aria-hidden className=\"h-3\" />\r\n )}\r\n <li className=\"pt-3 pb-2\">\r\n <div className=\"flex items-baseline gap-3\">\r\n <span className=\"font-mono text-[10.5px] uppercase tracking-[0.18em] text-[var(--color-fg-faint)]\">\r\n {t('memory.cover.orphan')}\r\n </span>\r\n <span className=\"font-mono text-[10.5px] tabular-nums text-[var(--color-fg-faint)]\">\r\n · {orphans.length}\r\n </span>\r\n <span aria-hidden className=\"ml-2 h-px flex-1 bg-[var(--color-hairline)]\" />\r\n </div>\r\n </li>\r\n {orphans.map((e) => (\r\n <RowItem\r\n key={e.filename}\r\n row={{ kind: 'entry', entry: e, hook: '' }}\r\n onOpenEntry={onOpenEntry}\r\n />\r\n ))}\r\n </>\r\n )}\r\n </ul>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nfunction RowItem({\r\n row,\r\n onOpenEntry,\r\n}: {\r\n row: Row;\r\n onOpenEntry: (filename: string) => void;\r\n}) {\r\n const t = useT();\r\n\r\n if (row.kind === 'spacer') {\r\n return <li aria-hidden className=\"h-2\" />;\r\n }\r\n if (row.kind === 'heading') {\r\n return (\r\n <li className=\"pt-4 pb-1\">\r\n <div className=\"font-mono text-[10.5px] uppercase tracking-[0.18em] text-[var(--color-fg-muted)]\">\r\n {row.text}\r\n </div>\r\n </li>\r\n );\r\n }\r\n if (row.kind === 'text') {\r\n return (\r\n <li className=\"px-1 py-0.5 text-[12.5px] text-[var(--color-fg-faint)] whitespace-pre-wrap break-words\">\r\n {row.text}\r\n </li>\r\n );\r\n }\r\n if (row.kind === 'missing') {\r\n return (\r\n <li\r\n title={t('memory.cover.missingTooltip')}\r\n className=\"flex items-baseline gap-3 px-2 py-1.5 text-[var(--color-fg-faint)]\"\r\n >\r\n <span className=\"text-[14px] font-medium line-through decoration-[var(--color-fg-faint)]/50\">\r\n {row.title}\r\n </span>\r\n {row.hook && <span className=\"truncate text-[12px]\">{row.hook}</span>}\r\n </li>\r\n );\r\n }\r\n\r\n const entry = row.entry;\r\n const typeKey: GroupKey = entry.type ?? 'other';\r\n const title = entry.name ?? entry.filename;\r\n const hookText = row.hook || entry.description || '';\r\n return (\r\n <li>\r\n <button\r\n type=\"button\"\r\n onClick={() => onOpenEntry(entry.filename)}\r\n className={`memo-row memo-type-${typeKey}`}\r\n >\r\n <span aria-hidden className=\"memo-row-dot\" />\r\n <div className=\"memo-row-content\">\r\n <div className=\"memo-row-headline\">\r\n <span className=\"memo-row-title\">{title}</span>\r\n {entry.mtime && (\r\n <span className=\"memo-row-meta-inline\">{formatRelativeTime(entry.mtime)}</span>\r\n )}\r\n <TypeChip k={typeKey} />\r\n </div>\r\n {hookText && <p className=\"memo-row-hook\">{hookText}</p>}\r\n </div>\r\n <span aria-hidden className=\"memo-row-chevron\">↗</span>\r\n </button>\r\n </li>\r\n );\r\n}\r\n\r\nfunction TypeChip({ k }: { k: GroupKey }) {\r\n const t = useT();\r\n const label =\r\n k === 'user'\r\n ? t('memory.type.user')\r\n : k === 'feedback'\r\n ? t('memory.type.feedback')\r\n : k === 'project'\r\n ? t('memory.type.project')\r\n : k === 'reference'\r\n ? t('memory.type.reference')\r\n : t('memory.type.other');\r\n return <span className=\"memo-chip\">{label}</span>;\r\n}\r\n\r\ntype DrawerTarget =\r\n | { kind: 'entry'; entry: MemoryEntry | null; filename: string }\r\n | { kind: 'raw' };\r\n\r\nfunction Drawer({\r\n target,\r\n rawIndex,\r\n hookForEntry,\r\n onClose,\r\n onJumpToCover,\r\n}: {\r\n target: DrawerTarget;\r\n rawIndex: string;\r\n hookForEntry: string | null;\r\n onClose: () => void;\r\n onJumpToCover: () => void;\r\n}) {\r\n const t = useT();\r\n const panelRef = useRef<HTMLDivElement | null>(null);\r\n\r\n useEffect(() => {\r\n const onKey = (e: KeyboardEvent) => {\r\n if (e.key === 'Escape') {\r\n e.preventDefault();\r\n onClose();\r\n }\r\n };\r\n window.addEventListener('keydown', onKey);\r\n const prevOverflow = document.body.style.overflow;\r\n document.body.style.overflow = 'hidden';\r\n requestAnimationFrame(() => panelRef.current?.focus());\r\n return () => {\r\n window.removeEventListener('keydown', onKey);\r\n document.body.style.overflow = prevOverflow;\r\n };\r\n }, [onClose]);\r\n\r\n const typeKey: GroupKey =\r\n target.kind === 'entry' ? (target.entry?.type ?? 'other') : 'reference';\r\n\r\n return (\r\n <>\r\n <div className=\"memo-drawer-backdrop\" onClick={onClose} aria-hidden />\r\n <div\r\n ref={panelRef}\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n tabIndex={-1}\r\n className={`memo-drawer-panel memo-type-${typeKey} focus:outline-none`}\r\n >\r\n <div className=\"flex items-start justify-between gap-3 border-b border-[var(--color-hairline)] px-7 pt-7 pb-5\">\r\n <div className=\"min-w-0 flex-1\">\r\n {target.kind === 'entry' ? (\r\n <>\r\n <TypeChip k={typeKey} />\r\n {target.entry ? (\r\n <>\r\n <h2 className=\"mt-3 font-display text-[24px] font-light leading-tight tracking-tight text-[var(--color-fg-primary)]\">\r\n {target.entry.name ?? target.entry.filename}\r\n </h2>\r\n <p className=\"mt-1.5 font-mono text-[11px] uppercase tracking-[0.16em] text-[var(--color-fg-faint)]\">\r\n {target.entry.filename} · {formatBytes(target.entry.bytes)}\r\n {target.entry.mtime ? ` · ${formatRelativeTime(target.entry.mtime)}` : ''}\r\n </p>\r\n </>\r\n ) : (\r\n <>\r\n <h2 className=\"mt-3 font-display text-[22px] font-light leading-tight text-[var(--color-fg-primary)]\">\r\n {t('memory.drawer.notFound.title')}\r\n </h2>\r\n <p className=\"mt-1.5 font-mono text-[11px] uppercase tracking-[0.16em] text-[var(--color-fg-faint)]\">\r\n {target.filename}\r\n </p>\r\n </>\r\n )}\r\n </>\r\n ) : (\r\n <>\r\n <span className=\"memo-chip memo-type-reference\">{t('memory.cover.title')}</span>\r\n <h2 className=\"mt-3 font-display text-[24px] font-light leading-tight tracking-tight text-[var(--color-fg-primary)]\">\r\n {t('memory.raw.title')}\r\n </h2>\r\n <p className=\"mt-1.5 font-mono text-[11px] uppercase tracking-[0.16em] text-[var(--color-fg-faint)]\">\r\n {t('memory.raw.subtitle')}\r\n </p>\r\n </>\r\n )}\r\n </div>\r\n <button\r\n type=\"button\"\r\n onClick={onClose}\r\n aria-label={t('memory.drawer.close')}\r\n className=\"rounded-md p-2 text-[var(--color-fg-muted)] hover:bg-[var(--color-sunken)] hover:text-[var(--color-fg-primary)]\"\r\n >\r\n <CloseIcon />\r\n </button>\r\n </div>\r\n\r\n <div className=\"flex-1 overflow-y-auto px-7 py-6\">\r\n {target.kind === 'entry' && target.entry ? (\r\n <EntryDrawerBody\r\n entry={target.entry}\r\n hookForEntry={hookForEntry}\r\n onJumpToCover={onJumpToCover}\r\n />\r\n ) : target.kind === 'entry' ? (\r\n <NotFoundDrawerBody filename={target.filename} onJumpToCover={onJumpToCover} />\r\n ) : (\r\n <RawDrawerBody source={rawIndex} />\r\n )}\r\n </div>\r\n </div>\r\n </>\r\n );\r\n}\r\n\r\nfunction EntryDrawerBody({\r\n entry,\r\n hookForEntry,\r\n onJumpToCover,\r\n}: {\r\n entry: MemoryEntry;\r\n hookForEntry: string | null;\r\n onJumpToCover: () => void;\r\n}) {\r\n const t = useT();\r\n const body = entry.body.trim();\r\n return (\r\n <div>\r\n {entry.description && (\r\n <p className=\"text-[14px] text-[var(--color-fg-secondary)]\">{entry.description}</p>\r\n )}\r\n <pre\r\n className={\r\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)] ' +\r\n (entry.description ? 'mt-5' : '')\r\n }\r\n >\r\n {body || '—'}\r\n </pre>\r\n {hookForEntry && (\r\n <div className=\"mt-7\">\r\n <div className=\"rule-dotted\" aria-hidden />\r\n <div className=\"mt-4 flex items-baseline justify-between gap-3\">\r\n <div className=\"eyebrow\">{t('memory.drawer.indexHook')}</div>\r\n <button\r\n type=\"button\"\r\n onClick={onJumpToCover}\r\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)]\"\r\n >\r\n {t('memory.cover.title')} ↑\r\n </button>\r\n </div>\r\n <p className=\"mt-1.5 text-[13px] text-[var(--color-fg-secondary)]\">{hookForEntry}</p>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nfunction NotFoundDrawerBody({\r\n filename,\r\n onJumpToCover,\r\n}: {\r\n filename: string;\r\n onJumpToCover: () => void;\r\n}) {\r\n const t = useT();\r\n return (\r\n <div>\r\n <p className=\"text-sm text-[var(--color-fg-secondary)]\">{t('memory.drawer.notFound.body')}</p>\r\n <p className=\"mt-3 font-mono text-[12px] text-[var(--color-fg-faint)]\">{filename}</p>\r\n <button\r\n type=\"button\"\r\n onClick={onJumpToCover}\r\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)]\"\r\n >\r\n {t('memory.cover.title')} ↑\r\n </button>\r\n </div>\r\n );\r\n}\r\n\r\nfunction RawDrawerBody({ source }: { source: string }) {\r\n const body = source.trim();\r\n return (\r\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)]\">\r\n {body || '—'}\r\n </pre>\r\n );\r\n}\r\n\r\nfunction EmptyState() {\r\n const t = useT();\r\n return (\r\n <div className=\"surface-card mt-6 px-8 py-14 text-center\">\r\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)]\">\r\n <BookmarkIcon />\r\n </div>\r\n <h2 className=\"mt-5 font-display text-[20px] font-light tracking-tight text-[var(--color-fg-primary)]\">\r\n {t('memory.empty.title')}\r\n </h2>\r\n <p className=\"mx-auto mt-3 max-w-xl text-[13px] leading-relaxed text-[var(--color-fg-secondary)]\">\r\n {t('memory.empty.body')}\r\n </p>\r\n </div>\r\n );\r\n}\r\n\r\nfunction SearchIcon({ className = '' }: { className?: string }) {\r\n return (\r\n <svg\r\n width=\"14\"\r\n height=\"14\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"1.7\"\r\n strokeLinecap=\"round\"\r\n className={className}\r\n aria-hidden\r\n >\r\n <circle cx=\"11\" cy=\"11\" r=\"6.2\" />\r\n <path d=\"M20 20l-4.3-4.3\" />\r\n </svg>\r\n );\r\n}\r\n\r\nfunction CloseIcon() {\r\n return (\r\n <svg\r\n width=\"16\"\r\n height=\"16\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"1.8\"\r\n strokeLinecap=\"round\"\r\n aria-hidden\r\n >\r\n <path d=\"M6 6l12 12M18 6L6 18\" />\r\n </svg>\r\n );\r\n}\r\n\r\nfunction BookmarkIcon() {\r\n return (\r\n <svg\r\n width=\"20\"\r\n height=\"20\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"1.6\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n aria-hidden\r\n >\r\n <path d=\"M6 4h12v17l-6-4-6 4z\" />\r\n </svg>\r\n );\r\n}\r\n\r\nfunction matchEntry(entry: MemoryEntry, hook: string, q: string): boolean {\r\n const fields = [\r\n entry.name ?? '',\r\n entry.filename,\r\n entry.description ?? '',\r\n entry.body,\r\n hook,\r\n ];\r\n return fields.some((f) => f.toLowerCase().includes(q));\r\n}\r\n\r\nfunction buildRows(\r\n indexLines: IndexLine[],\r\n entries: MemoryEntry[],\r\n): { rows: Row[]; orphans: MemoryEntry[] } {\r\n const filenameToEntry = new Map(entries.map((e) => [e.filename, e]));\r\n const seen = new Set<string>();\r\n const rows: Row[] = [];\r\n\r\n for (const line of indexLines) {\r\n if (line.link) {\r\n const entry = filenameToEntry.get(line.link.href);\r\n if (entry) {\r\n rows.push({ kind: 'entry', entry, hook: line.link.hook });\r\n seen.add(entry.filename);\r\n } else {\r\n rows.push({ kind: 'missing', title: line.link.title, hook: line.link.hook });\r\n }\r\n continue;\r\n }\r\n const txt = line.raw.trim();\r\n if (!txt) {\r\n rows.push({ kind: 'spacer' });\r\n continue;\r\n }\r\n const headingMatch = /^(#{1,6})\\s+(.+?)\\s*$/.exec(txt);\r\n if (headingMatch) {\r\n rows.push({ kind: 'heading', text: headingMatch[2]! });\r\n } else {\r\n rows.push({ kind: 'text', text: line.raw });\r\n }\r\n }\r\n\r\n const orphans = entries.filter((e) => !seen.has(e.filename));\r\n return { rows, orphans };\r\n}\r\n\r\nfunction parseIndex(raw: string | null): IndexLine[] {\r\n if (!raw) return [];\r\n const out: IndexLine[] = [];\r\n for (const rawLine of raw.split(/\\r?\\n/)) {\r\n const line = rawLine.trimEnd();\r\n if (line.trim() === '') {\r\n const last = out[out.length - 1];\r\n if (last && (last.link || last.raw.trim() !== '')) {\r\n out.push({ raw: '', link: null });\r\n }\r\n continue;\r\n }\r\n const m = LINK_RE.exec(line);\r\n const title = m?.groups?.title;\r\n const href = m?.groups?.href;\r\n if (m && title && href) {\r\n out.push({\r\n raw: line,\r\n link: { title: title.trim(), href: href.trim(), hook: (m.groups?.hook ?? '').trim() },\r\n });\r\n } else {\r\n out.push({ raw: line, link: null });\r\n }\r\n }\r\n while (out.length > 0) {\r\n const last = out[out.length - 1];\r\n if (last && !last.link && last.raw.trim() === '') out.pop();\r\n else break;\r\n }\r\n return out;\r\n}\r\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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"}