@illodev/workfile
Advanced tools
| import{n as e}from"./rolldown-runtime-CbXtAM7H.js";import{i as t,t as n}from"./react-Buq45Vzz.js";import{_t as r,mt as i,pt as a,rt as o}from"./ui-primitives-wYj92QGw.js";import{a as s,f as c,i as l,m as u,o as d,p as f,r as p,s as m,t as h,u as g}from"./empty-BHqXimMR.js";import{A as _,G as v,Q as y,U as b,X as x,Y as S,Z as C,j as w,n as T,q as E,r as D,t as O}from"./index-DEiK6_Ib.js";var k=e(t(),1),A=n(),j=[];function M(e,t){let[n,r]=(0,k.useState)(t);(0,k.useEffect)(()=>{r(t)},[e.length,t]);let i=(0,k.useCallback)(()=>r(n=>Math.min(n+t,e.length)),[e.length,t]);return[n>=e.length?e:e.slice(0,n),n<e.length,i]}function N({onVisible:e,remaining:t}){let n=(0,k.useRef)(null);return(0,k.useEffect)(()=>{let t=n.current;if(!t)return;let r=new IntersectionObserver(t=>{t.some(e=>e.isIntersecting)&&e()},{rootMargin:`600px 0px`});return r.observe(t),()=>r.disconnect()},[e,t]),(0,A.jsxs)(`span`,{ref:n,className:`px-0.5 py-1 font-mono text-[11px] text-muted-foreground`,children:[`+`,t,` more`]})}function P({task:e,epicId:t,onOpen:n,onDragStart:r,onCarry:i,carrying:a}){let o=e.claimed_at?Date.parse(e.claimed_at.includes(`T`)?e.claimed_at:`${e.claimed_at}T00:00:00`):NaN,s=Number.isNaN(o)?null:Math.max(0,Math.floor((Date.now()-o)/864e5)),l=[t&&t!==e.id?`epic ${t}`:``,e.effort?`effort ${e.effort}`:``,e.claimed_by?`claimed by ${e.claimed_by}${s==null?``:` · ${s}d`}`:``].filter(Boolean);return(0,A.jsxs)(`article`,{className:u(`flex cursor-pointer flex-col gap-1.5 rounded-lg border bg-background px-3 py-2.5 shadow-xs outline-none transition-[color,border-color,box-shadow] hover:border-ring focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50`,a&&`border-ring ring-2 ring-ring`),tabIndex:0,draggable:!!r,"aria-grabbed":i?!!a:void 0,title:l.length?l.join(` · `):void 0,onClick:()=>n(e.id),onKeyDown:t=>{t.key===`Enter`?(t.preventDefault(),n(e.id)):t.key===` `&&i?(t.preventDefault(),i()):t.key===` `&&(t.preventDefault(),n(e.id))},onDragStart:r,children:[(0,A.jsxs)(`span`,{className:`flex items-center`,children:[(0,A.jsx)(`span`,{className:`font-mono text-[11px] text-foreground/70`,children:e.id}),(0,A.jsx)(`span`,{className:`flex-1`}),(0,A.jsx)(`span`,{className:`font-mono text-[10px] font-medium`,style:{color:m(e.priority)},children:e.priority})]}),(0,A.jsx)(`span`,{className:`text-[12.5px] leading-snug font-medium`,role:`heading`,"aria-level":3,children:e.title}),(0,A.jsxs)(`span`,{className:`flex items-center gap-1.5 font-mono text-[10px] text-muted-foreground`,children:[(0,A.jsx)(`span`,{children:e.area}),(0,A.jsx)(`span`,{children:`·`}),(0,A.jsx)(`span`,{children:e.type}),e.claimed_by?(0,A.jsxs)(`span`,{className:`ml-auto inline-flex min-w-0 items-center gap-[5px]`,style:{color:c(`doing`)},children:[(0,A.jsx)(`span`,{className:`size-[5px] flex-none rounded-full bg-current`,"aria-hidden":`true`}),(0,A.jsx)(`span`,{className:`max-w-[90px] truncate`,children:e.claimed_by})]}):null]}),Array.isArray(e.scope)&&e.scope.length?(0,A.jsxs)(`span`,{className:`mt-0.5 truncate border-t border-dashed pt-1.5 font-mono text-[10.5px] text-muted-foreground`,children:[`scope `,e.scope.join(` · `)]}):null]})}function F({status:e,cards:t,epicIds:n,collapsed:r,onToggleCollapsed:m,onOpen:g,onMove:v,onCarry:b,carryingId:x,isDropTarget:S,onDragEnterColumn:C,onDragLeaveColumn:T}){let[E,D,O]=M(t,25),k=c(e),j={onDragOver:t=>{t.preventDefault(),t.dataTransfer.dropEffect=`move`,C?.(e)},onDragLeave:t=>{t.currentTarget.contains(t.relatedTarget)||T?.(e)},onDrop:t=>{t.preventDefault(),T?.(e);let n=t.dataTransfer.getData(`text/plain`);n&&v(n,e).catch(()=>void 0)}};return r?(0,A.jsxs)(w,{role:`region`,"aria-label":`${e}, ${t.length} cards, collapsed`,className:u(`relative w-11 flex-none gap-0 overflow-hidden rounded-lg py-0 shadow-xs`,S&&`border-primary`),...j,children:[(0,A.jsx)(_,{edge:`top`,color:k}),(0,A.jsxs)(`button`,{type:`button`,"aria-expanded":!1,"aria-label":`Expand the ${e} column`,title:`${e} · ${t.length}`,className:u(`flex h-full w-full cursor-pointer flex-col items-center gap-2.5 px-1 pt-4 pb-3 transition-colors hover:bg-accent/50`,S&&`bg-accent/50`),onClick:m,children:[(0,A.jsx)(i,{"aria-hidden":`true`,className:`size-3.5 shrink-0 text-muted-foreground`}),(0,A.jsx)(`span`,{className:`min-h-0 flex-1 truncate font-mono text-[11px] uppercase tracking-[0.06em] [writing-mode:vertical-rl]`,style:{color:k},children:e}),(0,A.jsx)(y,{variant:`secondary`,className:`h-5 shrink-0 rounded-md px-[7px] font-mono text-[11px] font-normal`,children:t.length})]})]}):(0,A.jsxs)(w,{role:`region`,"aria-label":`${e}, ${t.length} cards`,className:u(`relative w-[268px] flex-none gap-0 overflow-hidden rounded-lg py-0 shadow-xs`,S&&`border-primary`),...j,children:[(0,A.jsx)(_,{edge:`top`,color:k}),(0,A.jsxs)(`header`,{className:`flex flex-none items-center gap-2 px-3 pb-2.5 pt-4`,children:[(0,A.jsx)(`span`,{className:`flex-1 font-mono text-[11px] uppercase tracking-[0.06em]`,style:{color:k},children:e}),(0,A.jsx)(y,{variant:`secondary`,className:`h-5 rounded-md px-[7px] font-mono text-[11px] font-normal`,children:t.length}),m?(0,A.jsx)(f,{type:`button`,variant:`ghost`,size:`icon-xs`,"aria-expanded":!0,"aria-label":`Collapse the ${e} column`,title:`Collapse column`,className:`-mr-1 text-muted-foreground`,onClick:m,children:(0,A.jsx)(a,{"aria-hidden":`true`})}):null]}),(0,A.jsxs)(`div`,{className:u(`scroll-fade flex flex-1 flex-col gap-2 overflow-y-auto p-2.5`,S&&`bg-accent/50`),children:[t.length===0?(0,A.jsx)(h,{className:`flex-1 gap-2 rounded-lg border border-dashed p-4`,children:(0,A.jsxs)(l,{className:`gap-1`,children:[(0,A.jsx)(s,{variant:`icon`,className:`mb-0 size-8 [&_svg:not([class*='size-'])]:size-4`,children:(0,A.jsx)(o,{"aria-hidden":`true`})}),(0,A.jsx)(d,{className:`text-[12.5px] font-medium`,children:`No cards`}),(0,A.jsx)(p,{className:`text-[11.5px]`,children:`Nothing in this state.`})]})}):E.map(e=>(0,A.jsx)(P,{task:e,epicId:n.get(e.id),onOpen:g,onCarry:b?()=>b(e):void 0,carrying:x===e.id,onDragStart:t=>{t.dataTransfer.effectAllowed=`move`,t.dataTransfer.setData(`text/plain`,e.id)}},e.id)),D&&(0,A.jsx)(N,{onVisible:O,remaining:t.length-E.length})]})]})}function I({tasks:e,epicIds:t,showClosed:n,onOpen:r,onMove:i}){let[a,o]=(0,k.useState)(null),[s,c]=(0,k.useState)(null),[l,u]=(0,k.useState)(``),[d,f]=(0,k.useState)(()=>{try{let e=localStorage.getItem(`workfile-flow-collapsed`);return new Set(e?JSON.parse(e):[])}catch{return new Set}}),p=(0,k.useCallback)(e=>{f(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),localStorage.setItem(`workfile-flow-collapsed`,JSON.stringify([...n])),n})},[]),m=(0,k.useMemo)(()=>[`backlog`,`next`,`doing`,`review`,`blocked`,`deferred`,...n?[`done`,`discarded`]:[]],[n]),h=(0,k.useMemo)(()=>{let t=new Map;for(let n of e){let e=t.get(n.status);e?e.push(n):t.set(n.status,[n])}return t},[e]),g=e=>{o({id:e.id,status:e.status}),u(`${e.id} picked up from ${e.status}. Use the arrow keys to choose a column, space to drop, escape to cancel.`)},_=e=>{if(!a)return;let t=m.indexOf(a.status),n=m[Math.min(m.length-1,Math.max(0,t+e))];!n||n===a.status||(o({...a,status:n}),u(`${a.id} over ${n}.`))},v=async()=>{if(!a)return;let t=a;o(null);let n=e.find(e=>e.id===t.id);n&&n.status!==t.status?(await i(t.id,t.status),u(`${t.id} moved to ${t.status}.`)):u(`${t.id} put back.`)};return(0,A.jsxs)(`div`,{className:`flex min-h-0 flex-1 gap-3 overflow-x-auto p-3.5`,onDragEnd:()=>c(null),onKeyDown:e=>{a&&(e.key===`Escape`?(e.preventDefault(),o(null),u(`Move cancelled.`)):e.key===`ArrowRight`?(e.preventDefault(),_(1)):e.key===`ArrowLeft`?(e.preventDefault(),_(-1)):(e.key===` `||e.key===`Enter`)&&(e.preventDefault(),v()))},children:[(0,A.jsx)(`p`,{className:`sr-only`,role:`status`,"aria-live":`polite`,children:l}),m.map(e=>(0,A.jsx)(F,{status:e,cards:h.get(e)??j,epicIds:t,collapsed:d.has(e),onToggleCollapsed:()=>p(e),onOpen:r,onMove:i,onCarry:g,carryingId:a?.id??null,isDropTarget:a?.status===e||s===e,onDragEnterColumn:c,onDragLeaveColumn:e=>c(t=>t===e?null:t)},e))]})}function L({tasks:e,allTasks:t,epicIds:n,onOpen:r}){let i=(0,k.useMemo)(()=>new Map(t.map(e=>[e.id,e])),[t]),a=(0,k.useMemo)(()=>{let t=new Map;for(let r of e){let e=n.get(r.id)||(r.type===`epic`?r.id:`__none`);t.has(e)||t.set(e,[]),r.id!==e&&t.get(e)?.push(r)}return[...t].sort(([e],[t])=>e===`__none`?1:t===`__none`?-1:e.localeCompare(t,void 0,{numeric:!0}))},[n,e]);return a.length?(0,A.jsx)(`div`,{className:`flex-1 overflow-y-auto p-3.5`,children:(0,A.jsx)(`div`,{className:`flex flex-col gap-2.5`,children:a.map(([e,t])=>{let n=i.get(e),a=t.length,o=t.filter(e=>e.status===`done`||e.status===`discarded`).length,s=t.filter(e=>e.status===`doing`).length,l=a-o-s,d=e=>a?`${e/a*100}%`:`0%`,f=[{label:`${o} done`,color:c(`done`)},{label:`${s} doing`,color:c(`doing`)},{label:`${l} open`,color:null}],p=(0,A.jsxs)(A.Fragment,{children:[(0,A.jsxs)(`span`,{className:`flex min-w-0 items-center gap-2.5`,children:[(0,A.jsx)(`span`,{className:`font-mono text-[11.5px] text-foreground/70`,children:e===`__none`?`—`:e}),(0,A.jsx)(`span`,{className:`min-w-0 flex-1 text-sm font-semibold tracking-[-0.01em] text-pretty`,children:n?.title||`Without epic`}),n?(0,A.jsx)(`span`,{className:`font-mono text-[11px]`,style:{color:c(n.status)},children:n.status}):null,(0,A.jsxs)(`span`,{className:`font-mono text-[11.5px] text-muted-foreground`,children:[o,`/`,a]})]}),(0,A.jsx)(`span`,{className:`flex h-2 w-full overflow-hidden rounded-full bg-muted`,"aria-hidden":`true`,children:a>0?(0,A.jsxs)(A.Fragment,{children:[(0,A.jsx)(`span`,{className:`h-full`,style:{width:d(o),background:c(`done`)}}),(0,A.jsx)(`span`,{className:`h-full`,style:{width:d(s),background:c(`doing`)}})]}):null}),(0,A.jsxs)(`span`,{className:`flex flex-wrap items-center gap-3.5 font-mono text-[10.5px] text-muted-foreground`,children:[f.map(e=>(0,A.jsxs)(`span`,{className:`inline-flex items-center gap-[5px]`,children:[(0,A.jsx)(`span`,{className:u(`size-1.5 rounded-[2px]`,!e.color&&`bg-muted-foreground`),style:e.color?{background:e.color}:void 0,"aria-hidden":`true`}),e.label]},e.label)),(0,A.jsx)(`span`,{className:`ml-auto`,children:n?.area??``})]})]});return n?(0,A.jsx)(`button`,{type:`button`,className:`flex w-full cursor-pointer flex-col gap-2.5 rounded-xl border bg-card px-4 py-3.5 text-left text-card-foreground shadow-xs outline-none transition-[color,border-color,box-shadow] hover:border-ring focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50`,onClick:()=>r(e),children:p},e):(0,A.jsx)(w,{className:`gap-2.5 rounded-xl px-4 py-3.5 shadow-xs`,children:p},e)})})}):(0,A.jsx)(h,{className:`flex-1 p-6`,children:(0,A.jsxs)(l,{children:[(0,A.jsx)(d,{className:`text-sm`,children:`No epics`}),(0,A.jsx)(p,{className:`text-[11.5px]`,children:`No cards match the current filters.`})]})})}var R=300,z=30;function B({task:e,span:t,mode:n,epicId:r,pct:i,labelWidth:a,onOpen:o}){let s=c(e.status);return(0,A.jsxs)(`button`,{type:`button`,onClick:()=>o(e.id),title:`${D(e,n,t)} · ${e.status}${r&&r!==e.id?` · epic ${r}`:``}`,className:`flex w-full cursor-pointer items-center border-b bg-transparent p-0 text-left transition-colors hover:bg-muted`,children:[(0,A.jsxs)(`span`,{className:`flex min-w-0 items-center gap-2 border-r px-3.5`,style:{width:a,flex:`0 0 ${a}px`,height:`var(--row-h)`},children:[(0,A.jsx)(`span`,{className:`flex-none whitespace-nowrap font-mono text-[11px] text-foreground/70`,children:e.id}),(0,A.jsx)(`span`,{className:`min-w-0 truncate text-[12.5px]`,children:e.title})]}),(0,A.jsx)(`span`,{className:`relative block flex-1`,style:{height:`var(--row-h)`},children:t.point?(0,A.jsx)(`span`,{style:{position:`absolute`,top:`50%`,width:9,height:9,transform:`translate(-50%, -50%) rotate(45deg)`,borderRadius:2,background:s,display:`block`,left:`${i(t.from)}%`}}):(0,A.jsx)(`span`,{style:{position:`absolute`,top:`50%`,transform:`translateY(-50%)`,height:12,minWidth:6,borderRadius:3,background:s,display:`block`,left:`${i(t.from)}%`,width:`${Math.max(i(t.to)-i(t.from),.8)}%`}})})]})}function V({tasks:e,epicIds:t,axes:n={},mode:i,counts:a,onModeChange:o,onOpen:s}){let c=b()?168:R,u=c+460,[m,_]=(0,k.useState)(()=>{try{return localStorage.getItem(`workfile-timeline-group`)||`none`}catch{return`none`}}),y=(0,k.useCallback)(e=>{_(e);try{localStorage.setItem(`workfile-timeline-group`,e)}catch{}},[]),w=(0,k.useMemo)(()=>[`none`,`epic`,`area`,...Object.keys(n)],[n]),D=w.includes(m)?m:`none`,j=(0,k.useCallback)(e=>{if(D===`epic`)return t.get(e.id)||``;if(D===`area`)return e.area||``;let n=e[D];return typeof n==`string`?n:``},[t,D]),M=(0,k.useMemo)(()=>{let t=new Map;for(let n of e){let e=T(n,i);e&&t.set(n.id,e)}return t},[i,e]),N=(0,k.useMemo)(()=>{let t=(e,t)=>M.get(e.id).from-M.get(t.id).from||e.id.localeCompare(t.id),n=e.filter(e=>M.has(e.id)).sort(t);return D===`none`?n:[...n].sort((e,n)=>{let r=j(e),i=j(n);return!r==!i?r.localeCompare(i)||t(e,n):r?-1:1})},[j,D,M,e]),P=(0,k.useMemo)(()=>{if(D===`none`)return N.map(e=>({task:e,label:null}));let e=[],t=null;for(let n of N){let r=j(n);r!==t&&(t=r,e.push({task:null,label:r||`no ${D}`})),e.push({task:n,label:null})}return e},[j,D,N]),F=(0,k.useMemo)(()=>new Map(P.flatMap((e,t)=>e.task?[[e.task.id,t]]:[])),[P]),I=(0,k.useMemo)(()=>{let e=[];for(let t of N)for(let n of t.depends||[])F.has(n)&&e.push({from:n,to:t.id});return e},[F,N]),L=(0,k.useMemo)(()=>O(N.map(e=>M.get(e.id)),Date.now()),[N,M]),V=a[i===`plan`?`actual`:`plan`];return!N.length||!L?(0,A.jsx)(h,{className:`flex-1 p-6`,children:(0,A.jsxs)(l,{children:[(0,A.jsx)(d,{className:`text-sm`,children:i===`plan`?`Nothing scheduled`:`Nothing recorded`}),(0,A.jsx)(p,{className:`text-[11.5px]`,children:i===`plan`?`Add a start or due date to a card.`:`Cards record a trail as they are claimed and moved.`}),V>0?(0,A.jsx)(p,{className:`text-[11.5px]`,children:(0,A.jsx)(f,{variant:`outline`,size:`sm`,className:`mt-2 text-[12.5px] font-medium`,onClick:()=>o(i===`plan`?`actual`:`plan`),children:i===`plan`?`show what actually happened · ${V} cards`:`show the schedule · ${V} cards`})}):null]})}):(0,A.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col`,children:[(0,A.jsxs)(`div`,{className:`no-scrollbar flex flex-none items-center gap-2.5 overflow-x-auto border-b bg-card px-3.5 py-2`,children:[(0,A.jsxs)(`span`,{className:`shrink-0 font-mono text-[11px] whitespace-nowrap text-muted-foreground`,children:[N.length,` `,i===`actual`?`recorded`:`scheduled`,` ·`,` `,I.length,` dependenc`,I.length===1?`y`:`ies`]}),(0,A.jsxs)(v,{children:[(0,A.jsx)(C,{asChild:!0,children:(0,A.jsxs)(f,{variant:`outline`,size:`sm`,"aria-label":`dates`,className:`ml-auto shrink-0 text-[12.5px] font-medium`,children:[`dates`,(0,A.jsx)(`span`,{className:`font-normal text-muted-foreground`,children:i}),(0,A.jsx)(r,{className:`size-[13px] text-muted-foreground`})]})}),(0,A.jsx)(E,{align:`end`,children:(0,A.jsxs)(S,{value:i,onValueChange:e=>o(e),children:[(0,A.jsx)(x,{value:`plan`,children:`plan`}),(0,A.jsx)(x,{value:`actual`,children:`actual`})]})})]}),(0,A.jsxs)(v,{children:[(0,A.jsx)(C,{asChild:!0,children:(0,A.jsxs)(f,{variant:`outline`,size:`sm`,"aria-label":`group`,className:`shrink-0 text-[12.5px] font-medium`,children:[`group`,(0,A.jsx)(`span`,{className:`font-normal text-muted-foreground`,children:D}),(0,A.jsx)(r,{className:`size-[13px] text-muted-foreground`})]})}),(0,A.jsx)(E,{align:`end`,children:(0,A.jsx)(S,{value:D,onValueChange:y,children:w.map(e=>(0,A.jsx)(x,{value:e,children:e},e))})})]})]}),(0,A.jsx)(`div`,{className:`min-h-0 flex-1 overflow-auto`,children:(0,A.jsxs)(`div`,{className:`relative min-h-full`,style:{minWidth:u},children:[(0,A.jsxs)(`div`,{"aria-hidden":`true`,className:`sticky top-0 z-[2] flex items-stretch border-b bg-card`,style:{height:z},children:[(0,A.jsx)(`span`,{className:`flex items-center border-r px-3.5 text-[10px] uppercase tracking-[0.08em] text-muted-foreground`,style:{width:c,flex:`0 0 ${c}px`},children:`card`}),(0,A.jsx)(`span`,{className:`relative flex-1`,children:L.ticks.map((e,t)=>(0,A.jsx)(`span`,{className:`text-[10px] uppercase tracking-[0.08em] text-muted-foreground`,style:{position:`absolute`,top:`50%`,transform:`translateY(-50%)`,left:`${e.left}%`,width:`${(L.ticks[t+1]?.left??100)-e.left}%`,overflow:`hidden`,paddingLeft:8,whiteSpace:`nowrap`},children:e.label},e.key))})]}),(0,A.jsxs)(`div`,{"aria-hidden":`true`,className:`pointer-events-none absolute`,style:{top:z,bottom:0,left:c,right:0},children:[L.ticks.map(e=>(0,A.jsx)(`span`,{className:`absolute inset-y-0 w-px bg-border`,style:{left:`${e.left}%`}},e.key)),L.today!=null&&(0,A.jsx)(`span`,{className:`absolute inset-y-0 w-px`,style:{background:g(`error`),opacity:.55,left:`${L.today}%`}})]}),(0,A.jsxs)(`div`,{className:`relative`,children:[I.length>0&&(0,A.jsx)(`svg`,{"aria-hidden":`true`,preserveAspectRatio:`none`,viewBox:`0 0 100 ${P.length}`,className:`pointer-events-none absolute top-0 h-full`,style:{left:c,width:`calc(100% - ${c}px)`},children:I.map(e=>{let t=M.get(e.from),n=M.get(e.to);if(!t||!n)return null;let r=L.pct(t.to),i=L.pct(n.from),a=F.get(e.from)+.5,o=F.get(e.to)+.5;return(0,A.jsx)(`path`,{d:`M ${r} ${a} C ${(r+i)/2} ${a}, ${(r+i)/2} ${o}, ${i} ${o}`,vectorEffect:`non-scaling-stroke`,style:i<r?{fill:`none`,stroke:g(`error`),strokeWidth:1.5,strokeDasharray:`3 2`}:{fill:`none`,stroke:`var(--muted-foreground)`,strokeWidth:1.5,opacity:.4}},`${e.from}-${e.to}`)})}),P.map((e,n)=>e.task?(0,A.jsx)(B,{task:e.task,span:M.get(e.task.id),mode:i,epicId:t.get(e.task.id),pct:L.pct,labelWidth:c,onOpen:s},e.task.id):(0,A.jsx)(`div`,{className:`border-b bg-muted/40`,children:(0,A.jsx)(`span`,{className:`flex items-center px-3.5 text-[10px] uppercase tracking-[0.08em] text-muted-foreground`,style:{height:`var(--row-h)`},children:e.label})},`group-${n}-${e.label}`))]})]})})]})}export{L as EpicsView,I as FlowBoard,V as TimelineView}; |
| import{n as e}from"./rolldown-runtime-CbXtAM7H.js";import{i as t,t as n}from"./react-Buq45Vzz.js";import{F as r,V as i,gt as ee,q as te,st as a,z as o}from"./ui-primitives-wYj92QGw.js";import{i as ne,l as s,m as c,o as re,p as l,r as ie,t as ae}from"./empty-BHqXimMR.js";import{n as u,t as d}from"./native-select-NN1SzVJL.js";import{$ as f,C as p,E as m,H as h,I as g,O as oe,Q as _,S as se,T as ce,U as le,_ as ue,b as v,c as de,d as fe,et as y,f as pe,g as me,h as he,k as ge,l as _e,p as ve,v as b,x as ye,y as x}from"./index-DEiK6_Ib.js";import{t as be}from"./layout-QiuZ_k5v.js";var S=e(t(),1),C=n(),w=`doc-h`,xe=[`current`,`draft`,`superseded`,`archived`],T=`text-[10px] font-medium tracking-[0.07em] uppercase text-muted-foreground`;function Se({document:e,selected:t,onSelect:n}){return(0,C.jsx)(m,{asChild:!0,size:`sm`,className:c(`w-full cursor-pointer flex-col items-start gap-0.5 px-2 py-1.5 text-left hover:bg-accent`,t&&`bg-accent`),children:(0,C.jsxs)(`button`,{type:`button`,"aria-current":t?`true`:void 0,onClick:n,children:[(0,C.jsxs)(`span`,{className:`flex w-full items-center gap-1.5`,children:[(0,C.jsx)(`span`,{className:`flex-1 truncate text-xs font-medium`,children:e.title}),(0,C.jsx)(`span`,{className:c(`font-mono text-[10px]`,!e.managed&&`text-muted-foreground`),style:e.managed?{color:s(e.status)}:void 0,children:e.managed?e.status:`indexed`})]}),(0,C.jsx)(`span`,{className:`w-full truncate font-mono text-[10px] text-muted-foreground`,children:e.path})]})})}function Ce({entries:e,activeId:t,onJump:n}){let r=Math.min(...e.map(e=>e.level));return(0,C.jsxs)(`aside`,{"aria-label":`Document outline`,className:`hidden w-[228px] shrink-0 overflow-y-auto border-l px-3 py-6.5 xl:block`,children:[(0,C.jsx)(`span`,{className:c(T,`px-2`),children:`on this page`}),(0,C.jsx)(`nav`,{className:`mt-2 flex flex-col gap-px`,children:e.map(e=>{let i=e.id===t;return(0,C.jsx)(`button`,{type:`button`,"aria-current":i?`true`:void 0,className:c(`cursor-pointer rounded-md px-2 py-1 text-left text-xs leading-snug transition-colors hover:bg-accent`,i?`bg-accent font-medium text-foreground`:`text-muted-foreground`),style:{paddingLeft:`${8+Math.min(e.level-r,3)*12}px`},onClick:()=>n(e.id),children:e.text},e.id)})})]})}function E({label:e,value:t}){return(0,C.jsxs)(b,{className:`w-auto min-w-[120px] gap-0.5 rounded-lg border bg-card px-3 py-2 shadow-xs`,children:[(0,C.jsx)(`span`,{className:T,children:e}),(0,C.jsx)(`span`,{className:`text-[13px] font-medium`,children:t})]})}function D({label:e,links:t,onOpen:n}){return t.length?(0,C.jsxs)(`section`,{className:`flex flex-col gap-1.5`,children:[(0,C.jsx)(`span`,{className:T,children:e}),t.map((e,t)=>{let r=!e.exists&&!e.title;return(0,C.jsx)(m,{asChild:!0,variant:`outline`,size:`sm`,className:c(`w-full cursor-pointer gap-2 px-2.5 py-2 text-left hover:bg-accent`,r&&`cursor-default opacity-55 hover:bg-transparent`),children:(0,C.jsxs)(`button`,{type:`button`,disabled:r,onClick:()=>n(e.id),children:[(0,C.jsx)(`span`,{className:`min-w-[78px] shrink-0 font-mono text-[11px] font-medium`,children:e.id}),(0,C.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-xs text-muted-foreground`,children:e.title||(e.exists===!1?`Missing record`:e.id)}),e.relation?(0,C.jsx)(_,{variant:`secondary`,className:`font-mono text-[10px]`,children:e.relation}):null]})},`${e.id}-${t}`)})]}):null}var O=(0,C.jsx)(`span`,{"aria-hidden":`true`,className:`text-muted-foreground`,children:`·`});function k({selectedId:e,onSelect:t,onOpenCard:n}){let[m,_]=(0,S.useState)([]),[k,A]=(0,S.useState)(``),[j,M]=(0,S.useState)(!0),[N,P]=(0,S.useState)(``),[F,I]=(0,S.useState)(!1),[L,we]=(0,S.useState)(!1),[R,z]=(0,S.useState)(null),[B,V]=(0,S.useState)(!1),[H,U]=(0,S.useState)(``),[W,Te]=(0,S.useState)(null),[Ee,G]=(0,S.useState)(0);ge(e=>{oe(e,`/docs/`,`docs/`)&&G(e=>e+1)}),(0,S.useEffect)(()=>{let e=!1;M(!0);let t=window.setTimeout(()=>{g.docs(k.trim()).then(t=>{e||(_(t.records),P(``))}).catch(t=>{e||P(t instanceof Error?t.message:String(t))}).finally(()=>{e||M(!1)})},k?180:0);return()=>{e=!0,window.clearTimeout(t)}},[k,Ee]),(0,S.useEffect)(()=>{if(!R||W)return;let e=!1;return g.tasks().then(t=>{e||Te(t.schema.docs)}).catch(()=>{}),()=>{e=!0}},[R,W]);let K=(0,S.useMemo)(()=>F?m.filter(e=>e.managed):m,[m,F]),q=(0,S.useMemo)(()=>{let e=K.filter(e=>e.managed),t=K.filter(e=>!e.managed);return[{key:`managed`,label:`.project/docs · managed`,docs:e},{key:`indexed`,label:`indexed · read only`,docs:t}].filter(e=>e.docs.length>0)},[K]),De=le(),J=K.find(t=>t.id===e)||(De?void 0:K[0]),Y=(0,S.useRef)(null),[Oe,X]=(0,S.useState)(``),Z=(0,S.useMemo)(()=>J&&!L?se(J.body,w):[],[J,L]),Q=Z.length>1;(0,S.useEffect)(()=>{X(``);let e=Y.current;if(!e||!Q)return;let t=new Map,n=new IntersectionObserver(e=>{for(let n of e)t.set(n.target.id,n.isIntersecting);let n=Z.find(e=>t.get(e.id));n&&X(n.id)},{root:e,rootMargin:`0px 0px -66% 0px`,threshold:0});for(let e of Z){let t=document.getElementById(e.id);t&&n.observe(t)}return()=>n.disconnect()},[Z,Q]);let ke=e=>{document.getElementById(e)?.scrollIntoView({block:`start`,behavior:`smooth`}),X(e)},$=e=>{let r=m.find(t=>t.id===e);r?t(r.id):n(e)},Ae=(0,S.useMemo)(()=>{let e=new Set(W?.kinds??[]);for(let t of m)t.managed&&e.add(t.documentKind);return R&&e.add(R.kind),[...e].sort()},[W,m,R]),je=(0,S.useMemo)(()=>{let e=new Set(W?.statuses??xe);for(let t of m)t.managed&&e.add(t.status);return R&&e.add(R.status),[...e].sort()},[W,m,R]);function Me(e){U(``),z({id:e.id,title:e.title,kind:e.documentKind,status:e.status,owners:(e.owners??[]).join(`, `),reviewed:e.reviewed??``})}async function Ne(){if(!R)return;let e=m.find(e=>e.id===R.id);if(!e){U(`This document no longer exists in the workspace.`);return}let t=R.owners.split(`,`).map(e=>e.trim()).filter(Boolean),n={},r=R.title.trim();if(r&&r!==e.title&&(n.title=r),R.kind!==e.documentKind&&(n.kind=R.kind),R.status!==e.status&&(n.status=R.status),t.join(` | ||
| `)!==(e.owners??[]).join(` | ||
| `)&&(n.owners=t),(R.reviewed||``)!==(e.reviewed??``)&&(n.reviewed=R.reviewed||null),!Object.keys(n).length){z(null);return}V(!0),U(``);try{let t=await g.patchDocument(e.id,n,e.revision);_(n=>n.map(n=>n.id===e.id?t.record:n)),z(null)}catch(e){let t=e;t.code?.endsWith(`WRITE_CONFLICT`)?(G(e=>e+1),U(`The document changed on disk; the list was refreshed. Save again to apply your changes to the latest revision.`)):U(t.message||String(e))}finally{V(!1)}}return(0,C.jsxs)(`div`,{className:`flex min-h-0 flex-1`,children:[(0,C.jsxs)(`aside`,{"aria-label":`Documents`,className:c(`min-h-0 w-full shrink-0 flex-col border-r px-2 py-3 lg:flex lg:w-[290px]`,J?`hidden`:`flex`),children:[(0,C.jsxs)(`div`,{className:`flex flex-col gap-2 pb-2.5`,children:[(0,C.jsxs)(he,{className:`h-8`,children:[(0,C.jsx)(me,{children:(0,C.jsx)(i,{"aria-hidden":`true`})}),(0,C.jsx)(ue,{className:`h-8`,type:`search`,value:k,"aria-label":`Search documentation`,placeholder:`Search documentation…`,onChange:e=>A(e.target.value)})]}),(0,C.jsx)(`div`,{className:`flex gap-1.5`,children:(0,C.jsxs)(l,{type:`button`,variant:`outline`,size:`sm`,"aria-pressed":F,className:c(`h-7 gap-1.5 px-2.5 text-xs`,F&&`border-ring bg-accent`),onClick:()=>I(!F),children:[`managed`,(0,C.jsx)(`span`,{className:`font-normal text-muted-foreground`,children:F?`only`:`all`})]})})]}),(0,C.jsx)(`div`,{"aria-busy":j||void 0,className:`min-h-0 flex-1 overflow-y-auto`,children:j?(0,C.jsxs)(`span`,{className:`flex items-center gap-2 px-2 py-1.5 font-mono text-[10.5px] text-muted-foreground`,children:[(0,C.jsx)(ce,{className:`size-3`}),`Loading documents…`]}):N?(0,C.jsx)(f,{variant:`destructive`,className:`mt-1.5`,children:(0,C.jsx)(y,{children:N})}):q.length?q.map(e=>(0,C.jsxs)(`div`,{className:`flex flex-col gap-px pb-3.5`,children:[(0,C.jsxs)(`span`,{className:`flex items-center gap-2 px-2 py-1.5 font-mono text-[10.5px] text-muted-foreground`,children:[(0,C.jsx)(`span`,{className:`text-foreground/80`,children:e.label}),(0,C.jsx)(`span`,{children:e.docs.length})]}),e.docs.map(e=>(0,C.jsx)(Se,{document:e,selected:J?.id===e.id,onSelect:()=>t(e.id)},e.id))]},e.key)):(0,C.jsx)(ae,{className:`gap-2 p-4 md:p-4`,children:(0,C.jsxs)(ne,{children:[(0,C.jsx)(re,{className:`text-sm`,children:`No documents found.`}),(0,C.jsx)(ie,{className:`text-xs`,children:F?`Try another search, or include indexed files.`:`Try another search.`})]})})})]}),(0,C.jsx)(`section`,{ref:Y,className:c(`min-w-0 flex-1 overflow-y-auto px-6 py-6.5 sm:px-8.5`,J?`block`:`hidden lg:block`),children:(0,C.jsx)(`div`,{className:be,children:J?(0,C.jsxs)(C.Fragment,{children:[(0,C.jsxs)(l,{type:`button`,variant:`ghost`,size:`sm`,className:`-ml-2 mb-2 lg:hidden`,onClick:()=>t(``),children:[(0,C.jsx)(ee,{"aria-hidden":`true`}),`All documents`]}),(0,C.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2 font-mono text-[11px] text-muted-foreground`,children:[(0,C.jsx)(`span`,{children:J.id}),O,(0,C.jsx)(`span`,{children:J.documentKind}),O,(0,C.jsx)(`span`,{style:{color:s(J.status)},children:J.status}),O,(0,C.jsx)(`span`,{children:J.managed?`managed`:`indexed`}),(0,C.jsx)(`span`,{className:`flex-1`}),J.managed?(0,C.jsxs)(C.Fragment,{children:[(0,C.jsxs)(l,{type:`button`,variant:`outline`,size:`sm`,onClick:()=>we(e=>!e),children:[L?(0,C.jsx)(a,{"aria-hidden":`true`}):(0,C.jsx)(te,{"aria-hidden":`true`}),L?`Preview`:`Edit`]}),(0,C.jsxs)(l,{type:`button`,variant:`outline`,size:`sm`,onClick:()=>Me(J),children:[(0,C.jsx)(o,{"aria-hidden":`true`}),`Metadata`]})]}):null]}),(0,C.jsx)(`h2`,{className:`mt-3 mb-1.5 text-2xl font-semibold tracking-tight`,children:J.title}),(0,C.jsx)(`span`,{className:`font-mono text-[11px] text-muted-foreground [overflow-wrap:anywhere]`,children:J.path}),(0,C.jsxs)(`div`,{className:`mt-4.5 flex flex-wrap gap-2`,children:[(0,C.jsx)(E,{label:`kind`,value:J.documentKind}),(0,C.jsx)(E,{label:`status`,value:J.status}),(0,C.jsx)(E,{label:`reviewed`,value:J.reviewed||`—`}),(0,C.jsx)(E,{label:`owners`,value:J.owners?.join(`, `)||`—`}),(0,C.jsx)(E,{label:`backlinks`,value:String(J.incomingTotal??J.incoming.length)}),J.updated?(0,C.jsx)(E,{label:`updated`,value:J.updated}):null]}),J.freshness.length>0?(0,C.jsxs)(f,{role:`status`,className:`mt-4.5 max-w-2xl`,children:[(0,C.jsx)(r,{"aria-hidden":`true`,className:`text-sev-warning`}),(0,C.jsx)(y,{children:J.freshness.map(e=>(0,C.jsx)(`span`,{children:e.message},`${e.code}-${e.message}`))})]}):null,(0,C.jsx)(`div`,{className:`mt-6.5`,children:L&&J.managed?(0,C.jsx)(p,{value:J.body,revision:J.revision,onSave:async(e,t)=>{let n=await g.patchDocument(J.id,{body:e},t);_(e=>e.map(e=>e.id===J.id?n.record:e))}},J.id):J.body.trim()?(0,C.jsx)(ye,{source:J.body,headingPrefix:w,onOpen:$}):(0,C.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:J.managed?`This document is empty. Use Edit to write its first version.`:`This file has no body to render.`})}),J.outgoing.length||J.incoming.length||J.scope?.length?(0,C.jsxs)(`div`,{className:`mt-7 flex max-w-[70ch] flex-col gap-4.5`,children:[(0,C.jsx)(D,{label:`links to`,links:J.outgoing,onOpen:$}),(0,C.jsx)(D,{label:(J.incomingTotal??J.incoming.length)>J.incoming.length?`backlinks (${J.incoming.length} of ${J.incomingTotal})`:`backlinks`,links:J.incoming,onOpen:$}),J.scope?.length?(0,C.jsxs)(`section`,{className:`flex flex-col gap-1.5`,children:[(0,C.jsx)(`span`,{className:T,children:`scope`}),J.scope.map(e=>(0,C.jsx)(`span`,{className:`font-mono text-[10.5px] text-muted-foreground [overflow-wrap:anywhere]`,children:e},e))]}):null]}):null]}):(0,C.jsx)(`div`,{className:`flex h-full items-center justify-center text-xs text-muted-foreground`,children:j?`Loading documents…`:`Select a document from the list to read it.`})})}),Q?(0,C.jsx)(Ce,{entries:Z,activeId:Oe,onJump:ke}):null,(0,C.jsx)(de,{open:R!==null,onOpenChange:e=>{!e&&!B&&z(null)},children:(0,C.jsxs)(_e,{"aria-describedby":void 0,children:[(0,C.jsx)(pe,{children:(0,C.jsx)(ve,{children:`Edit metadata${R?` — ${R.id}`:``}`})}),R?(0,C.jsxs)(x,{className:`gap-4`,children:[(0,C.jsxs)(b,{children:[(0,C.jsx)(v,{htmlFor:`docs-meta-title`,children:`title`}),(0,C.jsx)(h,{id:`docs-meta-title`,value:R.title,onChange:e=>z({...R,title:e.target.value})})]}),(0,C.jsxs)(`div`,{className:`grid grid-cols-2 gap-2.5`,children:[(0,C.jsxs)(b,{className:`[&_[data-slot=native-select-wrapper]]:w-full`,children:[(0,C.jsx)(v,{htmlFor:`docs-meta-kind`,children:`kind`}),(0,C.jsx)(d,{id:`docs-meta-kind`,value:R.kind,onChange:e=>z({...R,kind:e.target.value}),children:Ae.map(e=>(0,C.jsx)(u,{value:e,children:e},e))})]}),(0,C.jsxs)(b,{className:`[&_[data-slot=native-select-wrapper]]:w-full`,children:[(0,C.jsx)(v,{htmlFor:`docs-meta-status`,children:`status`}),(0,C.jsx)(d,{id:`docs-meta-status`,value:R.status,onChange:e=>z({...R,status:e.target.value}),children:je.map(e=>(0,C.jsx)(u,{value:e,children:e},e))})]})]}),(0,C.jsxs)(`div`,{className:`grid grid-cols-2 gap-2.5`,children:[(0,C.jsxs)(b,{children:[(0,C.jsx)(v,{htmlFor:`docs-meta-owners`,children:`owners`}),(0,C.jsx)(h,{id:`docs-meta-owners`,value:R.owners,placeholder:`comma-separated`,onChange:e=>z({...R,owners:e.target.value})})]}),(0,C.jsxs)(b,{children:[(0,C.jsx)(v,{htmlFor:`docs-meta-reviewed`,children:`reviewed`}),(0,C.jsx)(h,{id:`docs-meta-reviewed`,type:`date`,value:R.reviewed,onChange:e=>z({...R,reviewed:e.target.value})})]})]}),H?(0,C.jsx)(f,{variant:`destructive`,children:(0,C.jsx)(y,{children:H})}):null]}):null,(0,C.jsxs)(fe,{children:[(0,C.jsx)(l,{type:`button`,variant:`outline`,disabled:B,onClick:()=>z(null),children:`Cancel`}),(0,C.jsx)(l,{type:`button`,disabled:B,onClick:()=>void Ne(),children:B?`Saving…`:`Save`})]})]})})]})}export{k as DocsView}; |
| import{n as e}from"./rolldown-runtime-CbXtAM7H.js";import{i as t,t as n}from"./react-Buq45Vzz.js";import{Ct as r,St as i,b as a,ft as o,vt as s,y as c,z as ee}from"./ui-primitives-wYj92QGw.js";import{f as l,i as te,m as u,o as ne,p as d,r as re,s as f,t as ie}from"./empty-BHqXimMR.js";import{n as p,t as m}from"./native-select-NN1SzVJL.js";import{B as ae,D as oe,L as se,R as ce,V as le,a as h,i as ue,o as g,s as de,z as fe}from"./index-DEiK6_Ib.js";import{t as _}from"./progress-CKc41PRw.js";var v=e(t(),1),y=n();function b({className:e,...t}){return(0,y.jsx)(c,{"data-slot":`checkbox`,className:u(`peer size-4 shrink-0 rounded-[4px] border border-input shadow-xs transition-shadow outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:bg-input/30 dark:aria-invalid:ring-destructive/40 dark:data-[state=checked]:bg-primary`,e),...t,children:(0,y.jsx)(a,{"data-slot":`checkbox-indicator`,className:`grid place-content-center text-current transition-none`,children:(0,y.jsx)(s,{className:`size-3.5`})})})}function pe({className:e,...t}){return(0,y.jsx)(`div`,{"data-slot":`table-container`,className:`relative w-full overflow-x-auto`,children:(0,y.jsx)(`table`,{"data-slot":`table`,className:u(`w-full caption-bottom text-sm`,e),...t})})}function me({className:e,...t}){return(0,y.jsx)(`thead`,{"data-slot":`table-header`,className:u(`[&_tr]:border-b`,e),...t})}function he({className:e,...t}){return(0,y.jsx)(`tbody`,{"data-slot":`table-body`,className:u(`[&_tr:last-child]:border-0`,e),...t})}function x({className:e,...t}){return(0,y.jsx)(`tr`,{"data-slot":`table-row`,className:u(`border-b transition-colors hover:bg-muted/50 has-aria-expanded:bg-muted/50 data-[state=selected]:bg-muted`,e),...t})}function S({className:e,...t}){return(0,y.jsx)(`th`,{"data-slot":`table-head`,className:u(`h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]`,e),...t})}function C({className:e,...t}){return(0,y.jsx)(`td`,{"data-slot":`table-cell`,className:u(`p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]`,e),...t})}var w=[[`id`,`id`],[`title`,`title · claim`],[`status`,`status`],[`priority`,`prio`],[`type`,`type`],[`area`,`area`],[`epic`,`links`],[`updated`,`updated`]],T=new Map(h.map((e,t)=>[e,t])),E=new Map(g.map((e,t)=>[e,t])),D=w.length+1;function O(e,t){let n=new Map;for(let r of e){let e=r[t];typeof e==`string`&&n.set(e,(n.get(e)||0)+1)}return n}function k({title:e,values:t,counts:n,selected:r,color:i,onSelect:a}){let o=t.filter(e=>n.has(e));if(!o.length)return null;let s=Math.max(...o.map(e=>n.get(e)||0));return(0,y.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,y.jsx)(`span`,{className:`px-1.5 font-mono text-[10px] tracking-widest uppercase text-muted-foreground`,children:e}),o.map(e=>{let t=n.get(e)||0,o=r===e;return(0,y.jsxs)(`button`,{type:`button`,"aria-pressed":o,onClick:()=>a(o?``:e),className:u(`flex w-full cursor-pointer flex-col gap-1 rounded-md px-1.5 py-1 text-left transition-colors hover:bg-accent/50`,o&&`bg-accent`),children:[(0,y.jsxs)(`span`,{className:`flex w-full items-center gap-1.5`,children:[(0,y.jsx)(`span`,{className:u(`min-w-0 flex-1 truncate text-xs`,o?`font-medium text-foreground`:`text-muted-foreground`),children:e}),(0,y.jsx)(`span`,{className:`font-mono text-[11px] text-muted-foreground`,children:t})]}),(0,y.jsx)(_,{value:s?Math.round(t/s*100):0,className:u(`h-[5px] bg-muted [&>div]:bg-current`,!i&&`text-primary`),style:i?{color:i(e)}:void 0})]},e)})]})}function A({label:e,value:t,options:n,color:r,withDot:i,onChange:a}){return(0,y.jsxs)(`span`,{className:`inline-flex items-center gap-1.5`,style:{color:r},children:[i?(0,y.jsx)(`span`,{className:`size-1.5 shrink-0 rounded-full bg-current`,"aria-hidden":`true`}):null,(0,y.jsx)(m,{"aria-label":e,value:t,onChange:e=>a(e.target.value),className:`h-[22px] cursor-pointer border-transparent bg-transparent px-1 py-0 pr-8 font-mono text-[11px] text-inherit shadow-none dark:bg-transparent dark:hover:bg-transparent`,children:n.map(e=>(0,y.jsx)(p,{value:e,children:e},e))})]})}var ge=(0,v.memo)(function({task:e,epicId:t,checked:n,isOpen:r,onToggle:i,onOpen:a,onPatch:o}){let s=(e.depends?.length??0)+ +!!e.parent;return(0,y.jsxs)(x,{className:`h-[var(--row-h)] cursor-pointer`,"data-state":r?`selected`:void 0,tabIndex:0,onClick:()=>a(e.id),onKeyDown:t=>{t.key===`Enter`&&a(e.id)},children:[(0,y.jsx)(C,{className:u(`w-7 border-l-2 border-l-transparent`,r&&`border-l-primary`),onClick:e=>e.stopPropagation(),children:(0,y.jsx)(b,{"aria-label":`Select ${e.id}`,checked:n,onCheckedChange:()=>i(e.id)})}),(0,y.jsx)(C,{className:`font-mono text-xs text-muted-foreground`,children:e.id}),(0,y.jsx)(C,{className:`max-w-[520px]`,children:(0,y.jsxs)(`span`,{className:`flex min-w-0 items-baseline gap-2`,children:[(0,y.jsx)(`span`,{className:`min-w-0 truncate font-medium`,children:e.title}),e.claimed_by?(0,y.jsxs)(`span`,{className:`font-mono text-[10px] whitespace-nowrap text-muted-foreground/60`,children:[`· `,e.claimed_by]}):null]})}),(0,y.jsx)(C,{onClick:e=>e.stopPropagation(),children:(0,y.jsx)(A,{label:`Status for ${e.id}`,value:e.status,options:g,color:l(e.status),withDot:!0,onChange:t=>void o(e.id,{status:t}).catch(()=>void 0)})}),(0,y.jsx)(C,{onClick:e=>e.stopPropagation(),children:(0,y.jsx)(A,{label:`Priority for ${e.id}`,value:e.priority,options:h,color:f(e.priority),onChange:t=>void o(e.id,{priority:t}).catch(()=>void 0)})}),(0,y.jsx)(C,{className:`font-mono text-[11px] text-muted-foreground`,children:e.type}),(0,y.jsx)(C,{className:`font-mono text-[11px] text-muted-foreground`,children:e.area}),(0,y.jsxs)(C,{className:`font-mono text-[11px] text-muted-foreground/60`,children:[t?(0,y.jsx)(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),a(t)},className:u(`cursor-pointer text-primary hover:underline`,s>0&&`mr-1.5`),children:t}):null,s>0?`${s} ↔`:t?null:`—`]}),(0,y.jsx)(C,{className:`font-mono text-[11px] text-muted-foreground/60`,children:e.updated||`—`})]})});function j({tasks:e,allTasks:t,areas:n,filters:a,setFilters:s,epicIds:c,onOpen:u,onPatch:_,onBulkPatch:C}){let[A,j]=(0,v.useState)(()=>new Set),[_e,ve]=(0,v.useState)(null),[M,ye]=(0,v.useState)(`id`),[N,P]=(0,v.useState)(`desc`),[F,I]=(0,v.useState)(``),[L,R]=(0,v.useState)(``),[z,B]=(0,v.useState)(``),V=(0,v.useRef)(null),[H,be]=(0,v.useState)({start:0,end:40}),[U,xe]=(0,v.useState)(40),W=(0,v.useDeferredValue)(a),G=(0,v.useMemo)(()=>{let e=e=>ue(t,{...W,...e});return{status:O(e({status:``}),`status`),type:O(e({type:``,showIdeas:!0}),`type`),priority:O(e({priority:``}),`priority`),area:O(e({area:``}),`area`)}},[t,W]),K=(0,v.useMemo)(()=>{let t=[...e];return t.sort((e,t)=>{let n=0;return n=M===`priority`?(T.get(e.priority)||0)-(T.get(t.priority)||0):M===`status`?(E.get(e.status)||0)-(E.get(t.status)||0):M===`epic`?(c.get(e.id)||``).localeCompare(c.get(t.id)||``):String(e[M]||``).localeCompare(String(t[M]||``),void 0,{numeric:!0}),N===`asc`?n:-n}),t},[c,N,M,e]),q=(0,v.useRef)(0),Se=K.length>0,J=(0,v.useCallback)(()=>{let e=V.current;if(!e)return;let t=parseFloat(getComputedStyle(document.documentElement).getPropertyValue(`--row-h`))||40;xe(t);let n=Math.max(0,Math.floor(e.scrollTop/t)-10),r=Math.ceil(e.clientHeight/t);be({start:n,end:Math.min(q.current,n+r+20)})},[]);(0,v.useEffect)(()=>{let e=V.current;if(!e)return;e.addEventListener(`scroll`,J,{passive:!0}),window.addEventListener(`resize`,J);let t=new MutationObserver(J);return t.observe(document.documentElement,{attributes:!0,attributeFilter:[`data-density`]}),()=>{e.removeEventListener(`scroll`,J),window.removeEventListener(`resize`,J),t.disconnect()}},[J,Se]),(0,v.useEffect)(()=>{q.current=K.length,J()},[J,K.length]);let Ce=[a.search,a.status,a.area,a.type,a.priority,a.milestone,a.showIdeas,a.showClosed,M,N].join(`|`);(0,v.useEffect)(()=>{V.current&&(V.current.scrollTop=0),J()},[Ce,J]);let we=(0,v.useCallback)(e=>{j(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},[]),Te=(0,v.useCallback)(e=>{ve(e),u(e)},[u]),Y=(0,v.useMemo)(()=>K.map(e=>e.id),[K]),X=Y.length>0&&Y.every(e=>A.has(e)),Ee=Y.some(e=>A.has(e)),De=K.slice(H.start,H.end),Z=!!(F||L||z);function Oe(e){M===e?P(e=>e===`asc`?`desc`:`asc`):(ye(e),P(e===`id`?`desc`:`asc`))}async function ke(){let e={};if(F&&(e.status=F),L&&(e.priority=L),z&&(e.area=z),!(!Z||A.size===0))try{await C([...A],e),j(new Set),I(``),R(``),B(``)}catch{}}let Q=(0,y.jsxs)(y.Fragment,{children:[(0,y.jsx)(k,{title:`status`,values:g,counts:G.status,selected:a.status,color:l,onSelect:e=>s(t=>({...t,status:e}))}),(0,y.jsx)(k,{title:`priority`,values:h,counts:G.priority,selected:a.priority,color:f,onSelect:e=>s(t=>({...t,priority:e}))}),(0,y.jsx)(k,{title:`area`,values:n,counts:G.area,selected:a.area,onSelect:e=>s(t=>({...t,area:e}))}),(0,y.jsx)(k,{title:`type`,values:de,counts:G.type,selected:a.type,onSelect:e=>s(t=>({...t,type:e}))})]}),$=[a.status,a.priority,a.area,a.type].filter(Boolean).length;return(0,y.jsxs)(`div`,{className:`flex min-h-0 flex-1`,children:[(0,y.jsx)(`aside`,{"aria-label":`Backlog facets`,className:`hidden w-[204px] flex-none flex-col gap-5 overflow-y-auto border-r px-3.5 py-4 lg:flex`,children:Q}),(0,y.jsxs)(`div`,{className:`flex min-h-0 min-w-0 flex-1 flex-col`,children:[(0,y.jsxs)(`div`,{className:`flex flex-none items-center gap-2 px-3.5 pt-2.5 lg:hidden`,children:[(0,y.jsxs)(se,{children:[(0,y.jsx)(le,{asChild:!0,children:(0,y.jsxs)(d,{variant:`outline`,size:`sm`,className:`h-7 gap-1.5 px-2.5 text-xs`,children:[(0,y.jsx)(ee,{className:`size-3.5`}),`Facets`,$?(0,y.jsx)(`span`,{className:`font-mono text-[10px] text-muted-foreground`,children:$}):null]})}),(0,y.jsxs)(ce,{side:`left`,className:`w-[280px] gap-0 sm:max-w-[280px]`,children:[(0,y.jsx)(fe,{className:`pb-2`,children:(0,y.jsx)(ae,{className:`font-mono text-[11px] tracking-wide uppercase`,children:`Facets`})}),(0,y.jsx)(`div`,{className:`flex flex-col gap-5 overflow-y-auto px-4 pb-4`,children:Q})]})]}),(0,y.jsxs)(`span`,{className:`font-mono text-[10.5px] text-muted-foreground/70`,children:[K.length.toLocaleString(),` row`,K.length===1?``:`s`,` · scroll sideways for every column`]})]}),A.size>0&&(0,y.jsxs)(`div`,{role:`region`,"aria-label":`Bulk actions`,className:`mx-3.5 mt-2.5 mb-2.5 flex flex-none flex-wrap items-center gap-2 rounded-md border bg-muted/50 px-3 py-2`,children:[(0,y.jsxs)(`span`,{className:`font-mono text-[11px]`,children:[A.size,` selected`]}),(0,y.jsxs)(m,{"aria-label":`Set status`,value:F,onChange:e=>I(e.target.value),className:`h-7 px-2 py-0 pr-8 text-xs`,children:[(0,y.jsx)(p,{value:``,children:`status…`}),g.map(e=>(0,y.jsx)(p,{value:e,children:e},e))]}),(0,y.jsxs)(m,{"aria-label":`Set priority`,value:L,onChange:e=>R(e.target.value),className:`h-7 px-2 py-0 pr-8 text-xs`,children:[(0,y.jsx)(p,{value:``,children:`priority…`}),h.map(e=>(0,y.jsx)(p,{value:e,children:e},e))]}),(0,y.jsxs)(m,{"aria-label":`Set area`,value:z,onChange:e=>B(e.target.value),className:`h-7 px-2 py-0 pr-8 text-xs`,children:[(0,y.jsx)(p,{value:``,children:`area…`}),n.map(e=>(0,y.jsx)(p,{value:e,children:e},e))]}),(0,y.jsxs)(oe,{children:[(0,y.jsx)(d,{size:`sm`,className:`h-7`,disabled:!Z,onClick:()=>void ke(),children:`Apply`}),(0,y.jsx)(d,{size:`sm`,variant:`outline`,className:`h-7`,onClick:()=>j(new Set),children:`Clear`})]})]}),K.length===0?(0,y.jsx)(ie,{children:(0,y.jsxs)(te,{children:[(0,y.jsx)(ne,{children:`No cards match`}),(0,y.jsx)(re,{children:`Adjust filters or clear the search`})]})}):(0,y.jsx)(`div`,{ref:V,className:`min-w-0 flex-1 overflow-auto [&>[data-slot=table-container]]:overflow-visible`,children:(0,y.jsxs)(pe,{className:`text-[13px]`,children:[(0,y.jsx)(me,{children:(0,y.jsxs)(x,{className:`hover:bg-transparent`,children:[(0,y.jsx)(S,{className:`sticky top-0 z-10 w-7 bg-background`,children:(0,y.jsx)(b,{"aria-label":`Select all matching cards`,checked:X?!0:Ee?`indeterminate`:!1,onCheckedChange:()=>j(e=>{let t=new Set(e);return X?Y.forEach(e=>t.delete(e)):Y.forEach(e=>t.add(e)),t})})}),w.map(([e,t])=>(0,y.jsx)(S,{"aria-sort":M===e?N===`asc`?`ascending`:`descending`:`none`,className:`sticky top-0 z-10 bg-background`,children:(0,y.jsxs)(d,{variant:`ghost`,size:`sm`,onClick:()=>Oe(e),className:`-ml-2 h-7 gap-1 px-2 text-xs text-muted-foreground`,children:[t,M===e?N===`asc`?(0,y.jsx)(i,{className:`size-3`}):(0,y.jsx)(r,{className:`size-3`}):(0,y.jsx)(o,{className:`size-3 opacity-50`})]})},e))]})}),(0,y.jsxs)(he,{children:[H.start>0&&(0,y.jsx)(`tr`,{"aria-hidden":`true`,children:(0,y.jsx)(`td`,{colSpan:D,style:{height:H.start*U}})}),De.map(e=>(0,y.jsx)(ge,{task:e,epicId:c.get(e.id)||``,checked:A.has(e.id),isOpen:_e===e.id,onToggle:we,onOpen:Te,onPatch:_},e.id)),H.end<K.length&&(0,y.jsx)(`tr`,{"aria-hidden":`true`,children:(0,y.jsx)(`td`,{colSpan:D,style:{height:(K.length-H.end)*U}})})]})]})})]})]})}export{j as Explorer}; |
| import{n as e}from"./rolldown-runtime-CbXtAM7H.js";import{i as t,t as n}from"./react-Buq45Vzz.js";import{dt as r}from"./ui-primitives-wYj92QGw.js";import{a as i,f as a,i as o,o as s,p as c,r as l,t as u,u as d}from"./empty-BHqXimMR.js";import{$ as f,A as p,I as m,Q as h,T as g,et as _,j as v,k as y}from"./index-DEiK6_Ib.js";var b=e(t(),1),x=n(),S=[{level:`error`,label:`errors`,hint:`must be fixed for a consistent workspace`,zeroHint:`the doctor does not block the release`},{level:`warning`,label:`warnings`,hint:`worth a look, nothing is broken yet`,zeroHint:`nothing worth flagging`},{level:`info`,label:`infos`,hint:`informational, no action required`,zeroHint:`no notices from the doctor`}];function C(e){return e.replace(/[-_.]+/g,` `)}var w={error:0,warning:1,info:2};function T({onOpen:e}){let[t,n]=(0,b.useState)(null),[T,E]=(0,b.useState)(``),[D,O]=(0,b.useState)(``),[k,A]=(0,b.useState)(0);y(()=>A(e=>e+1)),(0,b.useEffect)(()=>{let e=!0;return m.health().then(t=>{e&&n(t)}).catch(t=>{e&&E(t instanceof Error?t.message:String(t))}),()=>{e=!1}},[k]);let j=(0,b.useMemo)(()=>{if(!t)return[];let e=D?t.issues.filter(e=>e.severity===D):t.issues,n=new Map;for(let t of e){let e=n.get(t.code);e?e.push(t):n.set(t.code,[t])}return[...n.entries()].sort(([e,[t]],[n,[r]])=>{let i=w[t.severity]-w[r.severity];return i===0?e.localeCompare(n):i})},[t,D]);if(T)return(0,x.jsx)(`div`,{className:`p-3.5`,children:(0,x.jsx)(f,{variant:`destructive`,children:(0,x.jsx)(_,{children:T})})});if(!t)return(0,x.jsxs)(`div`,{className:`flex items-center gap-2 p-3.5`,"aria-busy":`true`,children:[(0,x.jsx)(g,{className:`size-3 text-muted-foreground`}),(0,x.jsx)(`span`,{className:`font-mono text-[11px] text-muted-foreground`,children:`running workfile doctor…`})]});let M=[[`cards`,t.modules?.cards??t.cards],[`docs`,t.modules?.docs],[`memory`,t.modules?.memory],[`changelog`,t.modules?.changelog]].filter(([,e])=>e!=null).map(([e,t])=>`${t.toLocaleString()} ${e}`).join(`, `),N=new Intl.DateTimeFormat(void 0,{dateStyle:`medium`,timeStyle:`short`}).format(new Date(t.generatedAt));return(0,x.jsxs)(`div`,{className:`flex-1 overflow-y-auto p-3.5`,children:[(0,x.jsx)(`div`,{className:`mb-2.5 flex gap-1.5`,children:S.map(({level:e,label:n})=>(0,x.jsxs)(c,{type:`button`,variant:`outline`,size:`sm`,"aria-pressed":D===e,className:`aria-pressed:border-ring aria-pressed:bg-accent`,onClick:()=>O(t=>t===e?``:e),children:[n,(0,x.jsx)(h,{variant:`secondary`,className:`px-1.5 font-mono text-[10.5px]`,children:t.counts[e]})]},e))}),(0,x.jsx)(`div`,{className:`flex flex-wrap gap-2.5`,children:S.map(({level:e,label:n,hint:r,zeroHint:i})=>{let o=t.counts[e],s=e===`error`&&o===0?a(`done`):d(e);return(0,x.jsxs)(v,{className:`relative min-w-[13rem] flex-1 gap-1 py-3 pl-5 pr-3.5`,children:[(0,x.jsx)(p,{edge:`left`,color:s}),(0,x.jsxs)(`span`,{className:`flex items-baseline gap-2`,children:[(0,x.jsx)(`span`,{className:`text-[26px] font-semibold tracking-tight`,style:{color:s},children:o}),(0,x.jsx)(`span`,{className:`font-mono text-[11px] text-muted-foreground`,children:n})]}),(0,x.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:o===0?i:r})]},e)})}),(0,x.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-2.5 gap-y-1 px-0.5 pt-4 pb-2`,children:[(0,x.jsxs)(`span`,{className:`font-mono text-[11px] text-muted-foreground`,children:[`grouped by code · `,M,` · checked `,N]}),(0,x.jsx)(`span`,{className:`ml-auto font-mono text-[10.5px] text-muted-foreground/70`,children:`workfile doctor --json`})]}),j.length===0?(0,x.jsx)(u,{className:`gap-2 p-10`,children:(0,x.jsxs)(o,{children:[(0,x.jsx)(i,{children:(0,x.jsx)(r,{"aria-hidden":`true`,size:20,style:{color:a(`done`)}})}),(0,x.jsx)(s,{className:`text-sm`,children:`All clear`}),(0,x.jsxs)(l,{className:`text-[12.5px]`,children:[`No `,D||`integrity`,` issues found.`]})]})}):(0,x.jsx)(`div`,{className:`flex flex-col gap-2`,children:j.map(([t,n])=>(0,x.jsxs)(v,{className:`gap-0 overflow-hidden py-0`,children:[(0,x.jsxs)(`div`,{className:`flex items-center gap-2 border-b px-3 py-1.5`,children:[(0,x.jsx)(`span`,{"aria-hidden":`true`,className:`size-[7px] rounded-full bg-current`,style:{color:d(n[0].severity)}}),(0,x.jsx)(`span`,{className:`font-mono text-[11.5px]`,children:t}),(0,x.jsx)(`span`,{className:`flex-1 text-[12.5px] text-muted-foreground`,children:C(t)}),(0,x.jsx)(`span`,{className:`font-mono text-[11px] text-muted-foreground/70`,children:n.length})]}),n.map((t,n)=>(0,x.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-2.5 gap-y-1 border-b px-3 py-[7px] last:border-0`,children:[t.id?(0,x.jsx)(c,{type:`button`,variant:`link`,className:`h-auto w-[82px] flex-[0_0_82px] justify-start p-0 font-mono text-[11px] font-normal`,onClick:()=>e(t.id),children:t.id}):(0,x.jsx)(`span`,{className:`w-[82px] flex-[0_0_82px] font-mono text-[11px] text-muted-foreground/70`,children:`—`}),(0,x.jsx)(`span`,{className:`min-w-[12rem] flex-1 text-[12.5px] text-muted-foreground`,children:t.message}),t.file?(0,x.jsx)(`span`,{className:`max-w-full truncate font-mono text-[10.5px] text-muted-foreground/70 sm:max-w-80`,title:t.file,children:t.file}):null]},`${t.id||t.file}-${n}`))]},t))})]})}export{T as HealthView}; |
| import{n as e}from"./rolldown-runtime-CbXtAM7H.js";import{i as t,t as n}from"./react-Buq45Vzz.js";import{K as r,N as i,_t as a,gt as o}from"./ui-primitives-wYj92QGw.js";import{f as s,l as c,m as l,p as u,r as d,t as f,u as p}from"./empty-BHqXimMR.js";import{n as m,t as h}from"./native-select-NN1SzVJL.js";import{$ as g,D as _,E as v,F as ee,G as y,H as b,I as x,K as S,M as C,N as w,O as te,P as ne,Q as T,Z as E,b as D,c as O,d as k,et as A,f as j,j as re,k as ie,l as M,p as N,q as P,u as F,v as I,w as ae,x as oe}from"./index-DEiK6_Ib.js";import{t as se}from"./layout-QiuZ_k5v.js";var L=e(t(),1),R=n(),z=`text-[10px] font-medium tracking-widest uppercase text-muted-foreground`;function B(e){switch(e){case`added`:return s(`done`);case`changed`:return s(`doing`);case`fixed`:return s(`review`);case`removed`:return s(`blocked`);case`security`:return p(`error`);default:return s(`backlog`)}}function ce(e,t){let n=null;for(let t of e){let e=/^v?(\d+)\.(\d+)\.(\d+)/.exec(t.version);if(!e)continue;let r=[Number(e[1]),Number(e[2]),Number(e[3])];(n?r[0]-n[0]||r[1]-n[1]||r[2]-n[2]:1)>0&&(n=r)}return n?t.some(e=>[`added`,`removed`,`deprecated`].includes(e.type))?`${n[0]}.${n[1]+1}.0`:`${n[0]}.${n[1]}.${n[2]+1}`:`0.1.0`}function V(e){return e instanceof Error?e.message:String(e)}function H({label:e,value:t,options:n,onChange:r}){return(0,R.jsxs)(y,{children:[(0,R.jsx)(E,{asChild:!0,children:(0,R.jsxs)(u,{type:`button`,variant:`outline`,size:`sm`,"aria-label":e,className:l(`h-7 gap-1 px-2 text-xs`,t&&`border-ring bg-accent`),children:[e,(0,R.jsx)(`span`,{className:l(`font-normal`,!t&&`text-muted-foreground`),children:t||`all`}),(0,R.jsx)(a,{"aria-hidden":`true`,className:`size-3 text-muted-foreground`})]})}),(0,R.jsxs)(P,{align:`start`,children:[(0,R.jsx)(S,{checked:!t,onSelect:()=>r(``),children:`all`}),n.map(e=>(0,R.jsx)(S,{checked:t===e,onSelect:()=>r(e),children:e},e))]})]})}function U({record:e,selected:t,onSelect:n}){let r=e.kind===`release`?`release`:e.type,i=e.kind===`release`?`var(--primary)`:B(e.type),a=e.kind===`release`?`${e.fragments.length} fragment${e.fragments.length===1?``:`s`} · ${e.date}`:e.area;return(0,R.jsx)(v,{asChild:!0,variant:`outline`,size:`sm`,children:(0,R.jsxs)(`button`,{type:`button`,"aria-current":t?`true`:void 0,onClick:n,className:l(`flex-col flex-nowrap items-stretch gap-1 px-2.5 py-2 text-left shadow-xs`,t?`border-ring bg-accent`:`bg-card hover:border-ring`),children:[(0,R.jsxs)(`span`,{className:`flex items-baseline gap-2`,children:[(0,R.jsx)(`span`,{className:`font-mono text-[11px] text-muted-foreground`,children:e.id}),(0,R.jsx)(`span`,{className:`font-mono text-[10px]`,style:{color:i},children:r}),(0,R.jsx)(`span`,{className:`flex-1`}),(0,R.jsx)(`span`,{className:`max-w-[170px] truncate font-mono text-[10px] text-muted-foreground/70`,children:a})]}),(0,R.jsx)(`span`,{className:`text-sm leading-snug font-normal`,children:e.title})]})})}function W({label:e,records:t,selectedId:n,onSelect:r}){return t.length?(0,R.jsxs)(`div`,{role:`group`,"aria-label":e,className:`flex flex-col gap-1.5 pt-4`,children:[(0,R.jsxs)(`span`,{className:z,children:[e,` · `,t.length]}),t.map(e=>(0,R.jsx)(U,{record:e,selected:e.id===n,onSelect:()=>r(e.id)},e.id))]}):null}function G({id:e,title:t,relation:n,disabled:r,onOpen:i}){return(0,R.jsx)(v,{asChild:!0,variant:`outline`,size:`sm`,children:(0,R.jsxs)(`button`,{type:`button`,disabled:r,onClick:i,className:`flex-nowrap gap-2 bg-card px-2.5 py-1.5 text-left shadow-xs hover:border-ring disabled:pointer-events-none disabled:opacity-55`,children:[(0,R.jsx)(`span`,{className:`shrink-0 font-mono text-[11px] text-muted-foreground`,children:e}),(0,R.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-[12.5px]`,children:t}),n?(0,R.jsx)(T,{variant:`outline`,className:`shrink-0 font-mono text-[10px] font-normal text-muted-foreground`,children:n}):null]})})}function K({label:e,links:t,onOpen:n}){return t.length?(0,R.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,R.jsx)(`span`,{className:z,children:e}),t.map(t=>(0,R.jsx)(G,{id:t.id,title:t.title,relation:t.relation,disabled:t.disabled,onOpen:()=>n(t.id)},`${e}-${t.id}`))]}):null}function le(e){return e.map(e=>({id:e.id,title:e.title||`Missing record`,relation:e.relation,disabled:!e.exists&&!e.title}))}function ue({schema:e,areas:t,onClose:n,onCreated:r}){let[i,a]=(0,L.useState)({title:``,type:e.defaults.type,area:t[0]||`general`,visibility:e.defaults.visibility,body:``}),[o,s]=(0,L.useState)(!1),[c,l]=(0,L.useState)(``),d=(e,t)=>a(n=>({...n,[e]:t})),f=async()=>{s(!0);try{r((await x.createChange(i)).record)}catch(e){l(V(e))}finally{s(!1)}};return(0,R.jsx)(O,{open:!0,onOpenChange:e=>{e||n()},children:(0,R.jsxs)(M,{onOpenAutoFocus:e=>e.preventDefault(),children:[(0,R.jsxs)(j,{children:[(0,R.jsx)(N,{children:`New change fragment`}),(0,R.jsx)(F,{children:`Record one user- or operator-meaningful change.`})]}),(0,R.jsxs)(I,{children:[(0,R.jsx)(D,{htmlFor:`new-fragment-title`,children:`Title`}),(0,R.jsx)(b,{id:`new-fragment-title`,autoFocus:!0,required:!0,maxLength:120,value:i.title,onChange:e=>d(`title`,e.target.value)})]}),(0,R.jsxs)(`div`,{className:`grid grid-cols-3 gap-2.5`,children:[(0,R.jsxs)(I,{children:[(0,R.jsx)(D,{htmlFor:`new-fragment-type`,children:`Type`}),(0,R.jsx)(h,{id:`new-fragment-type`,value:i.type,onChange:e=>d(`type`,e.target.value),children:e.types.map(e=>(0,R.jsx)(m,{value:e,children:e},e))})]}),(0,R.jsxs)(I,{children:[(0,R.jsx)(D,{htmlFor:`new-fragment-area`,children:`Area`}),(0,R.jsx)(h,{id:`new-fragment-area`,value:i.area,onChange:e=>d(`area`,e.target.value),children:t.map(e=>(0,R.jsx)(m,{value:e,children:e},e))})]}),(0,R.jsxs)(I,{children:[(0,R.jsx)(D,{htmlFor:`new-fragment-visibility`,children:`Visibility`}),(0,R.jsx)(h,{id:`new-fragment-visibility`,value:i.visibility,onChange:e=>d(`visibility`,e.target.value),children:e.visibilities.map(e=>(0,R.jsx)(m,{value:e,children:e},e))})]})]}),(0,R.jsxs)(I,{children:[(0,R.jsx)(D,{htmlFor:`new-fragment-details`,children:`Details`}),(0,R.jsx)(ae,{id:`new-fragment-details`,rows:5,value:i.body,onChange:e=>d(`body`,e.target.value)})]}),c?(0,R.jsx)(g,{variant:`destructive`,"aria-live":`polite`,children:(0,R.jsx)(A,{children:c})}):null,(0,R.jsxs)(k,{children:[(0,R.jsx)(u,{type:`button`,variant:`outline`,onClick:n,children:`Cancel`}),(0,R.jsx)(u,{type:`button`,disabled:o||!i.title.trim(),onClick:()=>void f(),children:o?`Saving…`:`Create fragment`})]})]})})}function de({preview:e,suggestedVersion:t,onClose:n,onReleased:r}){let[i,a]=(0,L.useState)(t),[o,s]=(0,L.useState)(``),[c,l]=(0,L.useState)(!1),[d,f]=(0,L.useState)(``),p=async()=>{l(!0);try{await x.createRelease({version:i,title:o||void 0,fragmentIds:e.fragments.map(e=>e.id)}),r()}catch(e){f(V(e))}finally{l(!1)}};return(0,R.jsx)(O,{open:!0,onOpenChange:e=>{e||n()},children:(0,R.jsxs)(M,{className:`flex max-h-[85vh] flex-col sm:max-w-[640px]`,children:[(0,R.jsxs)(j,{children:[(0,R.jsx)(N,{children:`Release preparation`}),(0,R.jsxs)(F,{children:[e.fragments.length,` unreleased fragment`,e.fragments.length===1?``:`s`,` selected.`]})]}),(0,R.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col gap-4 overflow-y-auto`,children:[(0,R.jsxs)(`div`,{className:`grid grid-cols-[150px_1fr] gap-2.5`,children:[(0,R.jsxs)(I,{children:[(0,R.jsx)(D,{htmlFor:`release-version`,children:`Version`}),(0,R.jsx)(b,{id:`release-version`,className:`font-mono`,placeholder:`2.4.0`,value:i,onChange:e=>a(e.target.value)})]}),(0,R.jsxs)(I,{children:[(0,R.jsx)(D,{htmlFor:`release-title`,children:`Release title`}),(0,R.jsx)(b,{id:`release-title`,placeholder:`Optional curated title`,value:o,onChange:e=>s(e.target.value)})]})]}),e.groups.map(e=>(0,R.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,R.jsxs)(`span`,{className:z,style:{color:B(e.type)},children:[e.type,` · `,e.fragments.length]}),e.fragments.map(e=>(0,R.jsxs)(`span`,{className:`flex items-baseline gap-2 text-[12.5px]`,children:[(0,R.jsx)(`span`,{className:`shrink-0 font-mono text-[11px] text-muted-foreground`,children:e.id}),(0,R.jsx)(`span`,{className:`min-w-0 truncate`,children:e.title}),(0,R.jsx)(`span`,{className:`flex-1`}),(0,R.jsx)(`span`,{className:`font-mono text-[10px] text-muted-foreground/70`,children:e.area})]},e.id))]},e.type)),(0,R.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,R.jsx)(`span`,{className:z,children:`release notes preview`}),(0,R.jsx)(`div`,{className:`max-h-[220px] overflow-y-auto rounded-md border bg-background px-3 py-1`,children:(0,R.jsx)(oe,{source:e.markdown||`No release notes to render.`})})]}),d?(0,R.jsx)(g,{variant:`destructive`,"aria-live":`polite`,children:(0,R.jsx)(A,{children:d})}):null]}),(0,R.jsxs)(k,{children:[(0,R.jsx)(u,{type:`button`,variant:`outline`,onClick:n,children:`Cancel`}),(0,R.jsx)(u,{type:`button`,disabled:c||!i.trim()||!e.fragments.length,onClick:()=>void p(),children:c?`Releasing…`:`Create release`})]})]})})}function fe({record:e,schema:t,areas:n,onSaved:r}){let[i,a]=(0,L.useState)({title:e.title,type:e.type,area:e.area,visibility:e.visibility}),[o,s]=(0,L.useState)(!1),[c,l]=(0,L.useState)(``),d=(e,t)=>a(n=>({...n,[e]:t})),f={};for(let t of[`title`,`type`,`area`,`visibility`])i[t]!==e[t]&&(f[t]=i[t]);let g=Object.keys(f).length>0,_=n.includes(e.area)?n:[e.area,...n],v=async()=>{s(!0);try{let t=await x.patchChange(e.id,f,e.revision);l(``),r(t.record)}catch(e){l(V(e))}finally{s(!1)}};return(0,R.jsxs)(re,{className:`gap-2.5 rounded-lg py-3 shadow-xs`,children:[(0,R.jsx)(ne,{className:`px-3`,children:(0,R.jsx)(ee,{className:z,children:`edit fragment`})}),(0,R.jsxs)(C,{className:`flex flex-col gap-2.5 px-3`,children:[(0,R.jsxs)(I,{children:[(0,R.jsx)(D,{htmlFor:`edit-fragment-title`,children:`Title`}),(0,R.jsx)(b,{id:`edit-fragment-title`,maxLength:120,value:i.title,onChange:e=>d(`title`,e.target.value)})]}),(0,R.jsxs)(`div`,{className:`grid grid-cols-3 gap-2.5`,children:[(0,R.jsxs)(I,{children:[(0,R.jsx)(D,{htmlFor:`edit-fragment-type`,children:`Type`}),(0,R.jsx)(h,{id:`edit-fragment-type`,value:i.type,onChange:e=>d(`type`,e.target.value),children:t.types.map(e=>(0,R.jsx)(m,{value:e,children:e},e))})]}),(0,R.jsxs)(I,{children:[(0,R.jsx)(D,{htmlFor:`edit-fragment-area`,children:`Area`}),(0,R.jsx)(h,{id:`edit-fragment-area`,value:i.area,onChange:e=>d(`area`,e.target.value),children:_.map(e=>(0,R.jsx)(m,{value:e,children:e},e))})]}),(0,R.jsxs)(I,{children:[(0,R.jsx)(D,{htmlFor:`edit-fragment-visibility`,children:`Visibility`}),(0,R.jsx)(h,{id:`edit-fragment-visibility`,value:i.visibility,onChange:e=>d(`visibility`,e.target.value),children:t.visibilities.map(e=>(0,R.jsx)(m,{value:e,children:e},e))})]})]})]}),(0,R.jsxs)(w,{className:`gap-2.5 px-3`,children:[c?(0,R.jsx)(`span`,{className:`flex-1 text-xs`,style:{color:p(`error`)},"aria-live":`polite`,children:c}):(0,R.jsx)(`span`,{className:`flex-1`}),(0,R.jsx)(u,{type:`button`,variant:`outline`,size:`sm`,disabled:o||!g||!i.title.trim(),onClick:()=>void v(),children:o?`Saving…`:`Save changes`})]})]})}function pe({selectedId:e,onSelect:t,onOpenRecord:n,schema:a,areas:s}){let[m,h]=(0,L.useState)([]),[v,ee]=(0,L.useState)(``),[y,S]=(0,L.useState)(``),[C,w]=(0,L.useState)(``),[ne,E]=(0,L.useState)(!0),[D,O]=(0,L.useState)(``),[k,j]=(0,L.useState)(``),[M,N]=(0,L.useState)(!1),[P,F]=(0,L.useState)(null),[I,ae]=(0,L.useState)(`public`),[z,U]=(0,L.useState)({content:``,error:``,loading:!0}),[G,pe]=(0,L.useState)(0),me=()=>pe(e=>e+1);ie(e=>{te(e,`/changelog/`)&&me()}),(0,L.useEffect)(()=>{let e=!1,t=async()=>{E(!0);try{let t=await x.changelog(v.trim(),{state:y||void 0,visibility:C||void 0});if(e)return;h(t.records),O(``)}catch(t){e||O(V(t))}finally{e||E(!1)}},n=window.setTimeout(()=>void t(),v?180:0);return()=>{e=!0,window.clearTimeout(n)}},[v,y,C,G]),(0,L.useEffect)(()=>{let e=!1;return U(e=>({...e,loading:!0})),x.renderedChangelog(I).then(t=>{e||U({content:t.content,error:``,loading:!1})}).catch(t=>{e||U({content:``,error:V(t),loading:!1})}),()=>{e=!0}},[I,G]);let q=(0,L.useMemo)(()=>[...m].sort((e,t)=>{if(e.kind!==t.kind)return e.kind===`change`?-1:1;if(e.kind===`release`&&t.kind===`release`){let n=t.date.localeCompare(e.date);return n===0?t.id.localeCompare(e.id):n}return String(t.updated||``).localeCompare(String(e.updated||``))}),[m]),J=(0,L.useMemo)(()=>new Map(m.map(e=>[e.id,e])),[m]),Y=(0,L.useMemo)(()=>q.filter(e=>e.kind===`change`&&!e.released),[q]),he=(0,L.useMemo)(()=>q.filter(e=>e.kind===`change`&&e.released),[q]),X=(0,L.useMemo)(()=>q.filter(e=>e.kind===`release`),[q]),Z=(0,L.useMemo)(()=>ce(X,Y),[X,Y]),Q=e?J.get(e):void 0,$=e=>{if(J.has(e)){t(e);return}if(/^(CHG|REL)-/.test(e)){S(``),w(``),t(e);return}n(e)},ge=()=>{j(``),x.releasePreview().then(F).catch(e=>j(V(e)))},_e=Q?.issues.some(e=>e.severity===`error`)?`destructive`:`default`,ve=(0,R.jsxs)(u,{type:`button`,variant:`outline`,size:`sm`,onClick:()=>N(!0),children:[(0,R.jsx)(r,{"aria-hidden":`true`}),`New fragment`]});return(0,R.jsxs)(`div`,{className:`flex min-h-0 flex-1`,children:[(0,R.jsxs)(`div`,{className:l(`w-full shrink-0 flex-col border-r lg:flex lg:w-[400px]`,Q?`hidden`:`flex`),children:[(0,R.jsxs)(`div`,{className:`flex flex-col gap-2.5 p-3.5 pb-0`,children:[(0,R.jsxs)(re,{className:`flex-row items-center gap-2.5 border-primary bg-primary/10 p-3`,children:[(0,R.jsxs)(`span`,{className:`flex min-w-0 flex-1 flex-col gap-0.5`,children:[(0,R.jsxs)(`span`,{className:`text-[13px] font-semibold`,children:[Y.length,` unpublished fragment`,Y.length===1?``:`s`]}),(0,R.jsxs)(`span`,{className:`font-mono text-[10.5px] text-muted-foreground`,children:[`next: `,Z,` ·`,` `,a.releaseStrategy]})]}),(0,R.jsx)(u,{type:`button`,size:`sm`,className:`whitespace-nowrap`,onClick:ge,children:`Prepare release`})]}),k?(0,R.jsx)(g,{variant:`destructive`,"aria-live":`polite`,children:(0,R.jsx)(A,{children:k})}):null,(0,R.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,R.jsx)(b,{type:`search`,"aria-label":`Search history`,placeholder:`Search fragments and releases…`,value:v,onChange:e=>ee(e.target.value),className:`h-7 flex-1 px-2.5 text-xs md:text-xs`}),(0,R.jsx)(H,{label:`state`,value:y,options:[`unreleased`,`released`],onChange:S}),(0,R.jsx)(H,{label:`visibility`,value:C,options:a.visibilities,onChange:w})]})]}),(0,R.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto px-3.5 pb-6 [mask-image:linear-gradient(to_bottom,black_calc(100%-24px),transparent)]`,children:ne?(0,R.jsx)(`div`,{"aria-busy":`true`,className:`flex flex-col gap-2 pt-4`,children:Array.from({length:6},(e,t)=>(0,R.jsx)(`div`,{className:`h-[52px] animate-pulse rounded-md bg-muted`},t))}):D?(0,R.jsx)(g,{variant:`destructive`,className:`mt-4`,"aria-live":`polite`,children:(0,R.jsx)(A,{children:D})}):q.length?(0,R.jsxs)(R.Fragment,{children:[(0,R.jsx)(W,{label:`unpublished`,records:Y,selectedId:e,onSelect:t}),(0,R.jsx)(W,{label:`releases`,records:X,selectedId:e,onSelect:t}),(0,R.jsx)(W,{label:`published fragments`,records:he,selectedId:e,onSelect:t})]}):(0,R.jsx)(f,{className:`mt-4 gap-1 p-4 md:p-4`,children:(0,R.jsx)(d,{className:`text-xs`,children:`No history records match the filters.`})})})]}),(0,R.jsx)(`div`,{className:l(`min-w-0 flex-1 overflow-y-auto px-6 py-5 sm:px-8.5`,Q?`block`:`hidden lg:block`),children:(0,R.jsx)(`div`,{className:se,children:Q?(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(u,{type:`button`,variant:`ghost`,size:`sm`,className:`-ml-2 mb-2 lg:hidden`,onClick:()=>t(``),children:[(0,R.jsx)(o,{"aria-hidden":`true`}),`All history`]}),(0,R.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-2 gap-y-1 font-mono text-[11px]`,children:[(0,R.jsx)(`span`,{className:`whitespace-nowrap text-primary`,children:Q.id}),(0,R.jsx)(`span`,{className:`text-muted-foreground/60`,children:`·`}),(0,R.jsx)(`span`,{className:`text-muted-foreground/70`,children:Q.kind}),(0,R.jsx)(`span`,{className:`text-muted-foreground/60`,children:`·`}),Q.kind===`change`?(0,R.jsxs)(R.Fragment,{children:[(0,R.jsx)(`span`,{style:{color:B(Q.type)},children:Q.type}),(0,R.jsx)(`span`,{className:`text-muted-foreground/60`,children:`·`}),(0,R.jsx)(`span`,{className:`text-muted-foreground`,children:Q.area}),(0,R.jsx)(`span`,{className:`text-muted-foreground/60`,children:`·`}),(0,R.jsx)(`span`,{className:`text-muted-foreground`,children:Q.visibility}),(0,R.jsx)(`span`,{className:`text-muted-foreground/60`,children:`·`}),(0,R.jsx)(`span`,{style:{color:c(Q.released?`released`:`unreleased`)},children:Q.released?`released`:`unreleased`}),Q.updated?(0,R.jsxs)(R.Fragment,{children:[(0,R.jsx)(`span`,{className:`text-muted-foreground/60`,children:`·`}),(0,R.jsx)(`span`,{className:`text-muted-foreground/70`,children:Q.updated})]}):null]}):(0,R.jsxs)(R.Fragment,{children:[(0,R.jsx)(`span`,{className:`text-primary`,children:Q.version}),(0,R.jsx)(`span`,{className:`text-muted-foreground/60`,children:`·`}),(0,R.jsx)(`span`,{className:`text-muted-foreground`,children:Q.date}),Q.commit?(0,R.jsxs)(R.Fragment,{children:[(0,R.jsx)(`span`,{className:`text-muted-foreground/60`,children:`·`}),(0,R.jsx)(`span`,{className:`text-muted-foreground/70`,children:Q.commit})]}):null,(0,R.jsx)(`span`,{className:`text-muted-foreground/60`,children:`·`}),(0,R.jsxs)(`span`,{className:`text-muted-foreground/70`,children:[Q.fragments.length,` fragment`,Q.fragments.length===1?``:`s`]})]}),(0,R.jsxs)(`span`,{className:`ml-auto flex shrink-0 items-center gap-1`,children:[ve,(0,R.jsx)(u,{type:`button`,variant:`ghost`,size:`icon-sm`,"aria-label":`Close record`,title:`Back to the derived changelog`,onClick:()=>t(``),children:(0,R.jsx)(i,{"aria-hidden":`true`})})]})]}),(0,R.jsx)(`h2`,{className:`mt-2.5 mb-1 text-[26px] leading-tight font-semibold tracking-tight [text-wrap:pretty]`,children:Q.title}),(0,R.jsx)(`div`,{className:`font-mono text-[10.5px] break-all text-muted-foreground/70`,children:Q.path}),Q.issues.length>0?(0,R.jsx)(g,{variant:_e,className:`mt-3.5`,children:(0,R.jsx)(A,{className:`w-full gap-1`,children:Q.issues.map(e=>(0,R.jsxs)(`span`,{className:`flex items-baseline gap-2`,children:[(0,R.jsx)(`span`,{className:`shrink-0 font-mono text-[10.5px]`,style:{color:p(e.severity)},children:e.severity}),(0,R.jsx)(`span`,{children:e.message})]},`${e.code}-${e.message}`))})}):null,(0,R.jsx)(`div`,{className:`mt-4.5`,children:(0,R.jsx)(oe,{source:Q.body||`No additional notes.`,onOpen:$})}),(0,R.jsxs)(`div`,{className:`mt-5.5 flex flex-col gap-3.5`,children:[Q.kind===`change`?(0,R.jsx)(K,{label:`shipped in`,links:(Q.releaseIds||[]).map(e=>({id:e,title:J.get(e)?.title||`Open release`,relation:`release`})),onOpen:$}):(0,R.jsx)(K,{label:`fragments · ${Q.fragments.length}`,links:Q.fragments.map(e=>{let t=J.get(e);return{id:e,title:t?.title||`Open fragment`,relation:t?.kind===`change`?t.type:void 0}}),onOpen:$}),(0,R.jsx)(K,{label:`links to`,links:le(Q.outgoing),onOpen:$}),(0,R.jsx)(K,{label:`backlinks`,links:le(Q.incoming),onOpen:$})]}),Q.kind===`change`?(0,R.jsx)(`div`,{className:`mt-5.5`,children:(0,R.jsx)(fe,{record:Q,schema:a,areas:s,onSaved:e=>h(t=>t.map(t=>t.id===e.id?e:t))},`${Q.id}:${Q.revision}`)}):null]}):(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-2.5 gap-y-2 border-b pb-3`,children:[(0,R.jsx)(`span`,{className:`text-[13px] font-semibold`,children:`Derived changelog`}),(0,R.jsxs)(`span`,{className:`font-mono text-[11px] text-muted-foreground`,children:[`visibility `,I,` · CHANGELOG.md`]}),(0,R.jsxs)(`span`,{className:`ml-auto flex flex-wrap items-center gap-2.5`,children:[(0,R.jsx)(_,{children:a.visibilities.map(e=>(0,R.jsx)(u,{type:`button`,size:`sm`,variant:I===e?`default`:`outline`,"aria-pressed":I===e,className:`h-7 px-2.5 text-xs`,onClick:()=>ae(e),children:e},e))}),(0,R.jsx)(T,{variant:`outline`,className:`rounded-md font-mono text-[10.5px] font-normal whitespace-nowrap text-muted-foreground`,children:`render --write`}),ve]})]}),z.error?(0,R.jsx)(g,{variant:`destructive`,className:`mt-4`,"aria-live":`polite`,children:(0,R.jsx)(A,{children:z.error})}):(0,R.jsx)(`pre`,{className:`mt-4 font-mono text-xs leading-[1.75] whitespace-pre-wrap text-muted-foreground`,"aria-busy":z.loading||void 0,children:z.loading&&!z.content?`Rendering…`:z.content||`Nothing to render yet — create the first change fragment.`})]})})}),M?(0,R.jsx)(ue,{schema:a,areas:s,onClose:()=>N(!1),onCreated:e=>{N(!1),h(t=>[e,...t]),t(e.id)}}):null,P?(0,R.jsx)(de,{preview:P,suggestedVersion:Z,onClose:()=>F(null),onReleased:()=>{F(null),me()}}):null]})}export{pe as HistoryView}; |
Sorry, the diff of this file is too big to display
| import{n as e}from"./rolldown-runtime-CbXtAM7H.js";import{i as t,t as n}from"./react-Buq45Vzz.js";import{G as r,K as i,V as a,_t as o,it as s,q as c,vt as l}from"./ui-primitives-wYj92QGw.js";import{l as u,m as d,p as f,r as p,t as m,u as h}from"./empty-BHqXimMR.js";import{n as g,t as _}from"./native-select-NN1SzVJL.js";import{$ as v,E as y,G as b,H as x,I as S,J as C,M as ee,O as te,P as ne,Q as w,T,Z as E,_ as re,b as D,c as O,d as k,et as A,f as j,g as M,h as N,j as P,k as F,l as I,m as ie,p as L,q as R,v as z,w as B,x as V}from"./index-DEiK6_Ib.js";var H=e(t(),1),U=n(),W=[`low`,`medium`,`high`],G=[`critical`,`high`,`medium`,`low`],ae=`[mask-image:linear-gradient(to_bottom,black_calc(100%_-_24px),transparent)]`;function oe(e){return e&&e[0].toUpperCase()+e.slice(1)}function K(e,t){return`${e} ${t}${e===1?``:`s`}`}function q(e){return{category:e===`learnings`||e===`decisions`,confidence:e===`learnings`,severity:e===`incidents`,expires:e===`context`,review_after:e===`context`}}function se(e){let t=[];switch(e.collection){case`learnings`:t.push(e.confidence,e.category,e.occurrences==null?null:`${e.occurrences}×`);break;case`decisions`:e.superseded_by?.length?t.push(`superseded by ${e.superseded_by.join(`, `)}`):e.supersedes?.length?t.push(`supersedes ${e.supersedes.join(`, `)}`):t.push(e.category);break;case`incidents`:t.push(e.severity,e.corrective_actions?.length?K(e.corrective_actions.length,`corrective action`):null);break;case`conventions`:t.push(e.owners?.length?e.owners.join(`, `):`no owner`);break;case`context`:t.push(e.expires?`expires ${e.expires}`:null,e.review_after?`review after ${e.review_after}`:null);break;default:t.push(e.category,e.severity)}return t.filter(Boolean).join(` · `)}function J({label:e,value:t,options:n,allLabel:r=`all`,onChange:i}){return(0,U.jsxs)(b,{children:[(0,U.jsx)(E,{asChild:!0,children:(0,U.jsxs)(f,{type:`button`,variant:`outline`,size:`sm`,"aria-label":e,className:d(`h-7 gap-1 rounded-full px-2.5 text-xs`,t&&`border-ring bg-accent`),children:[e,(0,U.jsx)(`span`,{className:`font-normal text-muted-foreground`,children:t||r}),(0,U.jsx)(o,{"aria-hidden":`true`,className:`size-3 text-muted-foreground`})]})}),(0,U.jsxs)(R,{align:`start`,sideOffset:4,children:[(0,U.jsxs)(C,{onSelect:()=>i(``),children:[r,t?null:(0,U.jsx)(l,{"aria-hidden":`true`,className:`ml-auto`})]}),n.map(e=>(0,U.jsxs)(C,{onSelect:()=>i(e.value),children:[e.color?(0,U.jsx)(`span`,{className:`size-2 shrink-0 rounded-full`,style:{backgroundColor:e.color},"aria-hidden":`true`}):null,e.label??e.value,t===e.value?(0,U.jsx)(l,{"aria-hidden":`true`,className:`ml-auto`}):null]},e.value))]})]})}function Y({id:e,label:t,children:n}){return(0,U.jsxs)(z,{className:`gap-1.5 [&_[data-slot=native-select-wrapper]]:w-full`,children:[(0,U.jsx)(D,{htmlFor:e,children:t}),n]})}function ce({record:e,selected:t,onSelect:n}){let r=se(e),i=e.lifecycleIssues?.length||0;return(0,U.jsx)(y,{asChild:!0,variant:`outline`,size:`sm`,className:`w-full flex-none flex-col items-stretch gap-1 rounded-lg bg-background px-2.5 py-2 text-left shadow-xs hover:border-ring aria-[current=true]:border-ring aria-[current=true]:bg-accent`,children:(0,U.jsxs)(`button`,{type:`button`,"aria-current":t?`true`:void 0,onClick:n,children:[(0,U.jsxs)(`span`,{className:`flex items-center justify-between gap-2`,children:[(0,U.jsx)(`span`,{className:`font-mono text-[11px] text-muted-foreground`,children:e.id}),(0,U.jsxs)(w,{variant:`outline`,className:`h-[18px] gap-1 rounded-md px-1.5 font-mono text-[10px] font-medium`,children:[(0,U.jsx)(`span`,{className:`size-[5px] shrink-0 rounded-full`,style:{backgroundColor:u(e.status)},"aria-hidden":`true`}),e.status]})]}),(0,U.jsx)(`span`,{className:`text-[13px] font-medium leading-snug`,children:e.title}),r||i?(0,U.jsxs)(`span`,{className:`font-mono text-[10.5px] text-muted-foreground`,children:[r,r&&i?` · `:null,i?(0,U.jsx)(`span`,{style:{color:h(`warning`)},children:K(i,`lifecycle warning`)}):null]}):null]})})}function X({issues:e,kind:t}){return e.length?(0,U.jsx)(U.Fragment,{children:e.map(e=>(0,U.jsx)(v,{variant:e.severity===`error`?`destructive`:`default`,className:`px-3 py-2`,children:(0,U.jsxs)(A,{className:`flex flex-wrap items-baseline gap-x-2 gap-y-0.5`,children:[(0,U.jsx)(`span`,{className:`font-mono text-[10.5px]`,style:{color:h(e.severity)},children:t===`lifecycle`?`lifecycle`:e.severity}),(0,U.jsx)(`span`,{children:e.message})]})},`${t}-${e.code}-${e.message}`))}):null}function Z({label:e,links:t,onOpen:n}){return t.length?(0,U.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,U.jsx)(`span`,{className:`text-[10px] font-medium uppercase tracking-wide text-muted-foreground`,children:e}),t.map(t=>{let r=!t.exists&&!t.title;return(0,U.jsx)(y,{asChild:!0,variant:`outline`,size:`sm`,className:`gap-2 rounded-lg px-2.5 py-2 text-left hover:border-ring disabled:pointer-events-none disabled:opacity-50`,children:(0,U.jsxs)(`button`,{type:`button`,disabled:r,onClick:()=>n(t.id),children:[(0,U.jsx)(`span`,{className:`w-[78px] shrink-0 truncate font-mono text-[11px] font-medium`,children:t.id}),(0,U.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-xs text-muted-foreground`,children:t.title||`Missing record`}),t.relation||t.kind?(0,U.jsx)(w,{variant:`secondary`,className:`h-[18px] rounded-md px-1.5 font-mono text-[10px] font-medium`,children:t.relation||t.kind}):null]})},`${e}-${t.id}`)})]}):null}function Q({message:e}){return e?(0,U.jsx)(v,{variant:`destructive`,className:`px-3 py-2`,children:(0,U.jsx)(A,{children:e})}):null}function le({schema:e,initialCollection:t,onClose:n,onCreated:r}){let i=e.collections.find(e=>e.id===t)||e.collections[0],[a,o]=(0,H.useState)({collection:i?.id||`learnings`,status:i?.statuses[0]||`active`,title:``,category:``,confidence:``,severity:``,expires:``,body:``}),[s,c]=(0,H.useState)(!1),[l,u]=(0,H.useState)(``),d=e.collections.find(e=>e.id===a.collection),p=q(a.collection),m=(e,t)=>o(n=>({...n,[e]:t})),h=t=>{let n=e.collections.find(e=>e.id===t);o(e=>({...e,collection:t,status:n?.statuses[0]||`active`}))},v=async()=>{c(!0);try{r((await S.createMemory({collection:a.collection,title:a.title,status:a.status,body:a.body,category:a.category||void 0,confidence:a.confidence||void 0,severity:a.severity||void 0,expires:a.expires||void 0})).record)}catch(e){u(e instanceof Error?e.message:String(e))}finally{c(!1)}};return(0,U.jsx)(O,{open:!0,onOpenChange:e=>{e||n()},children:(0,U.jsxs)(I,{className:`sm:max-w-[520px]`,"aria-describedby":void 0,children:[(0,U.jsx)(j,{children:(0,U.jsxs)(L,{children:[`New `,d?.singular||`record`]})}),(0,U.jsxs)(`div`,{className:`-m-1 flex max-h-[65vh] flex-col gap-3 overflow-y-auto p-1`,children:[(0,U.jsxs)(`div`,{className:`grid grid-cols-2 gap-2.5`,children:[(0,U.jsx)(Y,{id:`memory-create-collection`,label:`Collection`,children:(0,U.jsx)(_,{id:`memory-create-collection`,value:a.collection,onChange:e=>h(e.target.value),children:e.collections.map(e=>(0,U.jsx)(g,{value:e.id,children:e.id},e.id))})}),(0,U.jsx)(Y,{id:`memory-create-status`,label:`Status`,children:(0,U.jsx)(_,{id:`memory-create-status`,value:a.status,onChange:e=>m(`status`,e.target.value),children:(d?.statuses||[]).map(e=>(0,U.jsx)(g,{value:e,children:e},e))})})]}),(0,U.jsx)(Y,{id:`memory-create-title`,label:`Title`,children:(0,U.jsx)(x,{id:`memory-create-title`,autoFocus:!0,required:!0,maxLength:120,value:a.title,onChange:e=>m(`title`,e.target.value)})}),p.category||p.confidence||p.severity||p.expires?(0,U.jsxs)(`div`,{className:`grid grid-cols-2 gap-2.5`,children:[p.category?(0,U.jsx)(Y,{id:`memory-create-category`,label:`Category`,children:(0,U.jsx)(x,{id:`memory-create-category`,value:a.category,onChange:e=>m(`category`,e.target.value)})}):null,p.confidence?(0,U.jsx)(Y,{id:`memory-create-confidence`,label:`Confidence`,children:(0,U.jsxs)(_,{id:`memory-create-confidence`,value:a.confidence,onChange:e=>m(`confidence`,e.target.value),children:[(0,U.jsx)(g,{value:``,children:`not set`}),W.map(e=>(0,U.jsx)(g,{value:e,children:e},e))]})}):null,p.severity?(0,U.jsx)(Y,{id:`memory-create-severity`,label:`Severity`,children:(0,U.jsxs)(_,{id:`memory-create-severity`,value:a.severity,onChange:e=>m(`severity`,e.target.value),children:[(0,U.jsx)(g,{value:``,children:`not set`}),G.map(e=>(0,U.jsx)(g,{value:e,children:e},e))]})}):null,p.expires?(0,U.jsx)(Y,{id:`memory-create-expires`,label:`Expires`,children:(0,U.jsx)(x,{id:`memory-create-expires`,type:`date`,value:a.expires,onChange:e=>m(`expires`,e.target.value)})}):null]}):null,(0,U.jsx)(Y,{id:`memory-create-body`,label:`Details`,children:(0,U.jsx)(B,{id:`memory-create-body`,rows:8,value:a.body,onChange:e=>m(`body`,e.target.value)})}),(0,U.jsx)(Q,{message:l})]}),(0,U.jsxs)(k,{children:[(0,U.jsx)(f,{type:`button`,variant:`outline`,onClick:n,children:`Cancel`}),(0,U.jsx)(f,{type:`button`,disabled:s||!a.title.trim(),onClick:()=>void v(),children:s?(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(T,{"aria-hidden":`true`}),`Saving…`]}):`Create record`})]})]})})}function ue({record:e,statuses:t,onClose:n,onUpdated:r}){let i=q(e.collection),[a,o]=(0,H.useState)({title:e.title,status:e.status,category:e.category||``,confidence:e.confidence||``,severity:e.severity||``,expires:e.expires||``,review_after:e.review_after||``,body:e.body}),[s,c]=(0,H.useState)(!1),[l,u]=(0,H.useState)(``),d=(e,t)=>o(n=>({...n,[e]:t})),p=async()=>{let t={};a.title.trim()&&a.title!==e.title&&(t.title=a.title),a.status!==e.status&&(t.status=a.status),a.body!==e.body&&(t.body=a.body);for(let n of[`category`,`confidence`,`severity`,`expires`,`review_after`])a[n]!==(e[n]||``)&&(t[n]=a[n]||null);if(!Object.keys(t).length){n();return}c(!0);try{r((await S.patchMemory(e.id,t,e.revision)).record),n()}catch(e){u(e instanceof Error?e.message:String(e))}finally{c(!1)}};return(0,U.jsx)(O,{open:!0,onOpenChange:e=>{e||n()},children:(0,U.jsxs)(I,{className:`sm:max-w-[520px]`,"aria-describedby":void 0,children:[(0,U.jsx)(j,{children:(0,U.jsxs)(L,{children:[`Edit `,e.id]})}),(0,U.jsxs)(`div`,{className:`-m-1 flex max-h-[65vh] flex-col gap-3 overflow-y-auto p-1`,children:[(0,U.jsx)(Y,{id:`memory-edit-title`,label:`Title`,children:(0,U.jsx)(x,{id:`memory-edit-title`,autoFocus:!0,required:!0,maxLength:120,value:a.title,onChange:e=>d(`title`,e.target.value)})}),(0,U.jsxs)(`div`,{className:`grid grid-cols-2 gap-2.5`,children:[(0,U.jsx)(Y,{id:`memory-edit-status`,label:`Status`,children:(0,U.jsx)(_,{id:`memory-edit-status`,value:a.status,onChange:e=>d(`status`,e.target.value),children:(t.includes(a.status)?t:[a.status,...t]).map(e=>(0,U.jsx)(g,{value:e,children:e},e))})}),i.category?(0,U.jsx)(Y,{id:`memory-edit-category`,label:`Category`,children:(0,U.jsx)(x,{id:`memory-edit-category`,value:a.category,onChange:e=>d(`category`,e.target.value)})}):null,i.confidence?(0,U.jsx)(Y,{id:`memory-edit-confidence`,label:`Confidence`,children:(0,U.jsxs)(_,{id:`memory-edit-confidence`,value:a.confidence,onChange:e=>d(`confidence`,e.target.value),children:[(0,U.jsx)(g,{value:``,children:`not set`}),W.map(e=>(0,U.jsx)(g,{value:e,children:e},e))]})}):null,i.severity?(0,U.jsx)(Y,{id:`memory-edit-severity`,label:`Severity`,children:(0,U.jsxs)(_,{id:`memory-edit-severity`,value:a.severity,onChange:e=>d(`severity`,e.target.value),children:[(0,U.jsx)(g,{value:``,children:`not set`}),G.map(e=>(0,U.jsx)(g,{value:e,children:e},e))]})}):null,i.expires?(0,U.jsx)(Y,{id:`memory-edit-expires`,label:`Expires`,children:(0,U.jsx)(x,{id:`memory-edit-expires`,type:`date`,value:a.expires,onChange:e=>d(`expires`,e.target.value)})}):null,i.review_after?(0,U.jsx)(Y,{id:`memory-edit-review-after`,label:`Review after`,children:(0,U.jsx)(x,{id:`memory-edit-review-after`,type:`date`,value:a.review_after,onChange:e=>d(`review_after`,e.target.value)})}):null]}),(0,U.jsx)(Y,{id:`memory-edit-body`,label:`Details`,children:(0,U.jsx)(B,{id:`memory-edit-body`,rows:10,value:a.body,onChange:e=>d(`body`,e.target.value)})}),(0,U.jsx)(Q,{message:l})]}),(0,U.jsxs)(k,{children:[(0,U.jsx)(f,{type:`button`,variant:`outline`,onClick:n,children:`Cancel`}),(0,U.jsx)(f,{type:`button`,disabled:s||!a.title.trim(),onClick:()=>void p(),children:s?(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(T,{"aria-hidden":`true`}),`Saving…`]}):`Save changes`})]})]})})}function de({record:e,mode:t,onClose:n,onUpdated:r}){let[i,a]=(0,H.useState)(``),[o,s]=(0,H.useState)(!1),[c,l]=(0,H.useState)(``),u=async()=>{s(!0);try{r((t===`graduate`?await S.graduateMemory(e.id,i.split(`,`).map(e=>e.trim()).filter(Boolean),e.revision):await S.supersedeMemory(e.id,i.trim(),e.revision)).record),n()}catch(e){l(e instanceof Error?e.message:String(e))}finally{s(!1)}};return(0,U.jsx)(O,{open:!0,onOpenChange:e=>{e||n()},children:(0,U.jsxs)(I,{className:`sm:max-w-[420px]`,"aria-describedby":void 0,children:[(0,U.jsx)(j,{children:(0,U.jsxs)(L,{children:[t===`graduate`?`Graduate`:`Supersede`,` `,e.id]})}),(0,U.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,U.jsx)(Y,{id:`memory-lifecycle-target`,label:t===`graduate`?`Target IDs`:`Replacement ID`,children:(0,U.jsx)(x,{id:`memory-lifecycle-target`,autoFocus:!0,placeholder:t===`graduate`?`CONV-0001, DOC-0004`:`ADR-0009`,value:i,onChange:e=>a(e.target.value)})}),(0,U.jsx)(Q,{message:c})]}),(0,U.jsxs)(k,{children:[(0,U.jsx)(f,{type:`button`,variant:`outline`,onClick:n,children:`Cancel`}),(0,U.jsx)(f,{type:`button`,disabled:o||!i.trim(),onClick:()=>void u(),children:o?(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(T,{"aria-hidden":`true`}),`Saving…`]}):`Apply`})]})]})})}function fe({record:e,statuses:t,onOpenRelation:n,onOpenRecord:i,onUpdated:a,onDialogOpenChange:o}){let[l,d]=(0,H.useState)(!1),[p,m]=(0,H.useState)(``),g=l||!!p;(0,H.useEffect)(()=>{o?.(g)},[g,o]);let _=e.collection===`learnings`&&e.status!==`graduated`,v=[`learnings`,`decisions`,`conventions`].includes(e.collection),y=[[`status`,e.status,u(e.status)]];return e.category&&y.push([`category`,e.category]),e.confidence&&y.push([`confidence`,e.confidence]),e.severity&&y.push([`severity`,e.severity,h(e.severity)]),e.occurrences!=null&&y.push([`occurrences`,String(e.occurrences)]),e.expires&&y.push([`expires`,e.expires]),e.review_after&&y.push([`review after`,e.review_after]),e.started_at&&y.push([`started`,e.started_at]),e.resolved_at&&y.push([`resolved`,e.resolved_at]),e.graduated_to?.length&&y.push([`graduated to`,e.graduated_to.join(`, `)]),e.superseded_by?.length&&y.push([`superseded by`,e.superseded_by.join(`, `)]),e.owners?.length&&y.push([`owners`,e.owners.join(`, `)]),y.push([`updated`,e.updated||`—`]),(0,U.jsxs)(`aside`,{"aria-label":`Memory record`,className:`flex min-h-0 flex-col overflow-hidden border-l bg-background`,children:[(0,U.jsxs)(`div`,{className:`flex h-11 shrink-0 items-center gap-2 border-b px-3.5`,children:[(0,U.jsx)(`span`,{className:`font-mono text-[11px] text-muted-foreground`,children:e.id}),(0,U.jsx)(`span`,{className:`font-mono text-[11px] text-muted-foreground/60`,children:`·`}),(0,U.jsx)(`span`,{className:`font-mono text-[11px] text-muted-foreground`,children:e.collection}),(0,U.jsx)(`span`,{className:`font-mono text-[11px] text-muted-foreground/60`,children:`·`}),(0,U.jsx)(`span`,{className:`font-mono text-[11px]`,style:{color:u(e.status)},children:e.status})]}),(0,U.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col gap-3.5 overflow-y-auto p-4`,children:[(0,U.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,U.jsx)(`h2`,{className:`m-0 text-[17px] font-semibold leading-[1.3] tracking-[-0.01em] [text-wrap:pretty]`,children:e.title}),e.path?(0,U.jsx)(`span`,{className:`break-all font-mono text-[10.5px] text-muted-foreground`,children:e.path}):null]}),(0,U.jsx)(`div`,{className:`grid grid-cols-2 gap-x-3 gap-y-2`,children:y.map(([e,t,n])=>(0,U.jsxs)(`span`,{className:`flex flex-col gap-0.5`,children:[(0,U.jsx)(`span`,{className:`text-[10px] font-medium uppercase tracking-wide text-muted-foreground`,children:e}),(0,U.jsx)(`span`,{className:`text-sm`,style:n?{color:n}:void 0,children:t})]},e))}),(0,U.jsx)(X,{issues:e.issues,kind:`validation`}),(0,U.jsx)(X,{issues:e.lifecycleIssues||[],kind:`lifecycle`}),(0,U.jsx)(V,{className:`[--typeset-size:0.875rem]`,source:e.body||`No details recorded.`,onOpen:i}),(0,U.jsx)(Z,{label:`Links to`,links:e.outgoing,onOpen:n}),(0,U.jsx)(Z,{label:`Backlinks`,links:e.incoming,onOpen:n}),(0,U.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,U.jsxs)(f,{type:`button`,variant:`outline`,size:`sm`,onClick:()=>d(!0),children:[(0,U.jsx)(c,{"aria-hidden":`true`}),`Edit`]}),_?(0,U.jsxs)(f,{type:`button`,variant:`outline`,size:`sm`,onClick:()=>m(`graduate`),children:[(0,U.jsx)(s,{"aria-hidden":`true`}),`Graduate`]}):null,v?(0,U.jsxs)(f,{type:`button`,variant:`outline`,size:`sm`,onClick:()=>m(`supersede`),children:[(0,U.jsx)(r,{"aria-hidden":`true`}),`Supersede`]}):null]})]}),l?(0,U.jsx)(ue,{record:e,statuses:t,onClose:()=>d(!1),onUpdated:a}):null,p?(0,U.jsx)(de,{record:e,mode:p,onClose:()=>m(``),onUpdated:a}):null]})}function $(e,t){return e.find(e=>e.id===t)?.statuses||[]}function pe({selectedId:e,onSelect:t,onOpenRecord:n,schema:r}){let[o,s]=(0,H.useState)([]),[c,l]=(0,H.useState)(``),[h,g]=(0,H.useState)(``),[_,y]=(0,H.useState)(``),[b,x]=(0,H.useState)(!0),[C,E]=(0,H.useState)(``),[D,O]=(0,H.useState)(null),[k,j]=(0,H.useState)(()=>localStorage.getItem(`workfile-memory-drawer`)===`expanded`);(0,H.useEffect)(()=>{localStorage.setItem(`workfile-memory-drawer`,k?`expanded`:`normal`)},[k]);let I=(0,H.useRef)(!1),L=(0,H.useRef)(0),R=(0,H.useCallback)(e=>{L.current=performance.now(),t(e)},[t]),[z,B]=(0,H.useState)(0);F(e=>{te(e,`/memory/`)&&B(e=>e+1)}),(0,H.useEffect)(()=>{let e=async()=>{x(!0);try{let e=await S.memory(c.trim(),{collection:h||void 0,status:_||void 0});s(e.records),E(``)}catch(e){E(e instanceof Error?e.message:String(e))}finally{x(!1)}},t=window.setTimeout(()=>void e(),c?180:0);return()=>window.clearTimeout(t)},[c,h,_,z]);let V=(0,H.useMemo)(()=>[...o].sort((e,t)=>String(t.updated||``).localeCompare(String(e.updated||``))||e.title.localeCompare(t.title)),[o]),W=(0,H.useMemo)(()=>{let e=r.collections.filter(e=>!h||e.id===h).map(e=>({schema:e,records:V.filter(t=>t.collection===e.id)})),t=new Set(r.collections.map(e=>e.id)),n=V.filter(e=>!t.has(e.collection));return n.length&&e.push({schema:{id:`other`,singular:`record`,idPrefix:`?`,statuses:[]},records:n}),e},[r.collections,V,h]),G=V.find(t=>t.id===e),q=h?$(r.collections,h):[...new Set(r.collections.flatMap(e=>e.statuses))];return(0,U.jsxs)(U.Fragment,{children:[(0,U.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2 px-3.5 pt-3.5`,children:[(0,U.jsxs)(N,{className:`w-full min-w-[180px] sm:w-[260px]`,children:[(0,U.jsx)(M,{children:(0,U.jsx)(a,{"aria-hidden":`true`})}),(0,U.jsx)(re,{type:`search`,"aria-label":`Search workfile memory`,placeholder:`Search decisions, incidents, learnings…`,value:c,onChange:e=>l(e.target.value)})]}),(0,U.jsx)(J,{label:`collection`,value:h,options:r.collections.map(e=>({value:e.id})),onChange:e=>{g(e),y(``)}}),(0,U.jsx)(J,{label:`status`,value:_,options:q.map(e=>({value:e,color:u(e)})),onChange:y}),(0,U.jsx)(`span`,{className:`ml-auto flex shrink-0 items-center gap-1.5 whitespace-nowrap font-mono text-[11px] text-muted-foreground`,children:b?(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(T,{"aria-hidden":`true`,className:`size-3`}),`loading…`]}):K(o.length,`record`)})]}),C?(0,U.jsx)(v,{variant:`destructive`,className:`mx-3.5 mt-3 w-auto px-3 py-2`,children:(0,U.jsxs)(A,{children:[`Memory could not be loaded: `,C]})}):null,(0,U.jsx)(`div`,{className:`flex min-h-0 flex-1 gap-3 overflow-hidden p-3.5`,children:(0,U.jsx)(`div`,{className:`flex min-h-0 flex-1 gap-3 overflow-x-auto`,children:W.map(t=>(0,U.jsxs)(P,{className:`w-[272px] flex-none gap-0 overflow-hidden rounded-xl py-0 [--card-spacing:--spacing(2)]`,children:[(0,U.jsxs)(ne,{className:`flex flex-row items-center gap-2 border-b px-3 py-2`,children:[(0,U.jsx)(`span`,{className:`font-mono text-[11px] font-medium text-primary`,children:t.schema.idPrefix}),(0,U.jsx)(`span`,{className:`flex-1 text-[12.5px] font-semibold`,children:oe(t.schema.singular)}),(0,U.jsx)(w,{variant:`secondary`,className:`h-5 px-1.5 font-mono text-[11px] font-normal`,children:t.records.length}),t.schema.id===`other`?null:(0,U.jsx)(f,{type:`button`,variant:`ghost`,size:`icon-xs`,"aria-label":`New ${t.schema.singular}`,onClick:()=>O(t.schema.id),children:(0,U.jsx)(i,{"aria-hidden":`true`})})]}),(0,U.jsxs)(ee,{className:d(`flex min-h-0 flex-1 flex-col gap-2 overflow-y-auto p-2.5`,ae),children:[t.records.map(t=>(0,U.jsx)(ce,{record:t,selected:t.id===e,onSelect:()=>R(t.id)},t.id)),!t.records.length&&!b?(0,U.jsx)(m,{className:`gap-1 border border-dashed p-4 md:p-6`,children:(0,U.jsx)(p,{className:`font-mono text-xs`,children:`no records`})}):null]})]},t.schema.id))})}),(0,U.jsx)(ie,{open:!!G,expanded:k,label:`record`,description:`Details and lifecycle for the selected memory record.`,onOpenChange:e=>{e||t(``)},onExpandedChange:j,holdOpen:()=>I.current||performance.now()-L.current<200,children:G?(0,U.jsx)(fe,{record:G,statuses:$(r.collections,G.collection),onOpenRelation:e=>{o.some(t=>t.id===e)?R(e):n(e)},onOpenRecord:n,onUpdated:e=>s(t=>t.map(t=>t.id===e.id?e:t)),onDialogOpenChange:e=>{I.current=e}},G.id):null}),D===null?null:(0,U.jsx)(le,{schema:r,initialCollection:D,onClose:()=>O(null),onCreated:e=>{O(null),s(t=>[e,...t]),t(e.id)}})]})}export{pe as MemoryView}; |
| import{n as e}from"./rolldown-runtime-CbXtAM7H.js";import{i as t,t as n}from"./react-Buq45Vzz.js";import{W as r,Y as i,yt as a}from"./ui-primitives-wYj92QGw.js";import{a as o,f as s,i as c,m as l,n as u,o as d,p as f,r as p,s as m,t as h}from"./empty-BHqXimMR.js";import{W as g,a as _,x as v}from"./index-DEiK6_Ib.js";import{t as y}from"./layout-QiuZ_k5v.js";import{t as b}from"./progress-CKc41PRw.js";var x=e(t(),1),S=n(),C=[{key:`N`,label:`Move to next`,status:`next`},{key:`D`,label:`Defer`,status:`deferred`},{key:`X`,label:`Discard`,status:`discarded`}];function w({tasks:e,repoRoot:t,repoUrl:n,onPatch:w,onOpen:T}){let[E,D]=(0,x.useState)(()=>new Set),[O,k]=(0,x.useState)(0),A=(0,x.useMemo)(()=>e.filter(e=>!E.has(e.id)),[E,e]),j=A[O]||A[0],M=e.length;(0,x.useEffect)(()=>{O>=A.length&&k(Math.max(0,A.length-1))},[O,A.length]);let N=(0,x.useCallback)(async(e,t=!0)=>{if(j){try{await w(j.id,e)}catch{return}t&&(D(e=>new Set(e).add(j.id)),k(e=>Math.min(e,Math.max(0,A.length-2))))}},[w,A.length,j]);(0,x.useEffect)(()=>{let e=e=>{if(e.ctrlKey||e.metaKey||e.altKey)return;let t=e.target;if([`INPUT`,`SELECT`,`TEXTAREA`].includes(t.tagName)||t.isContentEditable)return;let n=e.key.toUpperCase();if(n===`J`||e.key===`ArrowDown`)e.preventDefault(),k(e=>Math.min(A.length-1,e+1));else if(n===`K`||e.key===`ArrowUp`)e.preventDefault(),k(e=>Math.max(0,e-1));else if(/^[1-4]$/.test(n))e.preventDefault(),N({priority:_[Number(n)-1]},!1);else{let t=C.find(e=>e.key===n);t&&(e.preventDefault(),N({status:t.status}))}};return document.addEventListener(`keydown`,e),()=>document.removeEventListener(`keydown`,e)},[N,A.length]);let P=e=>n?`${n.replace(/\/+$/,``)}/blob/main/${e}`:`vscode://file${t}/${e}`;return j?(0,S.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col overflow-y-auto`,children:[(0,S.jsxs)(`div`,{className:`flex items-center gap-2.5 border-b bg-card px-3.5 py-2.5`,children:[(0,S.jsx)(b,{value:M?E.size/M*100:0,className:`max-w-[340px] flex-1`}),(0,S.jsxs)(`span`,{className:`font-mono text-[11px] text-muted-foreground`,children:[E.size,` of `,M,` processed`]}),(0,S.jsx)(`span`,{className:`flex-1`}),(0,S.jsxs)(f,{type:`button`,variant:`outline`,size:`sm`,disabled:O===0,onClick:()=>k(e=>Math.max(0,e-1)),children:[(0,S.jsx)(g,{children:`K`}),`Previous`]}),(0,S.jsxs)(`span`,{className:`font-mono text-[11px] text-muted-foreground tabular-nums`,children:[O+1,` / `,A.length]}),(0,S.jsxs)(f,{type:`button`,variant:`outline`,size:`sm`,disabled:O>=A.length-1,onClick:()=>k(e=>Math.min(A.length-1,e+1)),children:[(0,S.jsx)(g,{children:`J`}),`Next`]}),(0,S.jsxs)(f,{type:`button`,variant:`outline`,size:`sm`,onClick:()=>T(j.id),children:[(0,S.jsx)(i,{"aria-hidden":`true`}),`Open full card`]})]}),(0,S.jsxs)(`div`,{className:l(y,`px-6 py-7 sm:px-8`),children:[(0,S.jsxs)(`div`,{className:`flex items-center gap-2 font-mono text-[11px] text-muted-foreground`,children:[(0,S.jsx)(`span`,{children:j.id}),(0,S.jsx)(`span`,{className:`text-muted-foreground/60`,children:`·`}),(0,S.jsx)(`span`,{style:{color:s(j.status)},children:j.status}),(0,S.jsx)(`span`,{className:`text-muted-foreground/60`,children:`·`}),(0,S.jsx)(`span`,{children:j.area}),(0,S.jsx)(`span`,{className:`text-muted-foreground/60`,children:`·`}),(0,S.jsx)(`span`,{children:j.type})]}),(0,S.jsx)(`h2`,{className:`mt-3 mb-1 text-[26px] leading-[1.2] font-semibold tracking-tight [text-wrap:pretty]`,children:j.title}),j.file?(0,S.jsx)(`a`,{className:`font-mono text-[11px] text-muted-foreground/70 underline underline-offset-[3px]`,href:P(j.file),target:n?`_blank`:void 0,rel:n?`noreferrer`:void 0,children:j.file}):null,j.source?(0,S.jsxs)(`span`,{className:`mt-[3px] block font-mono text-[11px] text-muted-foreground/70`,children:[`source`,` `,(0,S.jsx)(`a`,{className:`font-mono underline underline-offset-[3px]`,href:P(j.source),target:n?`_blank`:void 0,rel:n?`noreferrer`:void 0,children:j.source})]}):null,(0,S.jsx)(`div`,{className:`mt-[22px]`,children:(0,S.jsx)(v,{source:j.body,onOpen:T})}),(0,S.jsxs)(`div`,{className:`mt-[30px] flex flex-wrap gap-2 border-t pt-[18px]`,children:[_.map((e,t)=>(0,S.jsxs)(f,{type:`button`,variant:`outline`,"aria-pressed":j.priority===e,style:j.priority===e?{borderColor:m(e)}:void 0,onClick:()=>void N({priority:e},!1),children:[(0,S.jsx)(g,{children:t+1}),(0,S.jsx)(`span`,{style:{color:m(e)},children:e})]},e)),C.map(e=>(0,S.jsxs)(f,{type:`button`,variant:`outline`,onClick:()=>void N({status:e.status}),children:[(0,S.jsx)(g,{children:e.key}),(0,S.jsx)(`span`,{style:{color:s(e.status)},children:e.label})]},e.key))]}),(0,S.jsx)(`span`,{className:`mt-3.5 block text-xs text-muted-foreground`,children:`Every action writes the card's frontmatter to disk immediately. Shortcuts work while focus is outside a form.`})]})]}):(0,S.jsxs)(h,{className:`gap-3 p-10`,children:[(0,S.jsxs)(c,{children:[(0,S.jsx)(o,{children:(0,S.jsx)(a,{"aria-hidden":`true`,size:20,style:{color:s(`done`)}})}),(0,S.jsx)(d,{className:`text-sm`,children:`Queue clear`}),(0,S.jsxs)(p,{className:`text-[12.5px]`,children:[`You processed `,E.size.toLocaleString(),` cards.`]})]}),(0,S.jsx)(u,{children:(0,S.jsxs)(f,{type:`button`,variant:`outline`,size:`sm`,onClick:()=>{D(new Set),k(0)},children:[(0,S.jsx)(r,{"aria-hidden":`true`}),`Start again`]})})]})}export{w as TriageView}; |
+501
-187
@@ -5,2 +5,3 @@ import { NEXT_DEFAULT_LIMIT, NEXT_MAXIMUM_LIMIT, appendCardNote, archiveCard, claimCard, createCard, patchCard, patchCardBody, rankNextCards, releaseCard, reopenCard, transitionCard } from "../cards/index.js"; | ||
| import { resolveActor } from "../../core/actor.js"; | ||
| import { CARD_EFFORTS, CARD_PRIORITIES, CARD_STATUSES, CARD_TYPES } from "../../config/defaults.js"; | ||
| import { dateBoundary } from "../../core/inputs.js"; | ||
@@ -15,8 +16,50 @@ import { runDoctor } from "../health/doctor.js"; | ||
| const OBJECT = { type: "object", additionalProperties: false }; | ||
| const STRING_ARRAY = { type: "array", items: { type: "string" } }; | ||
| /** | ||
| * Property builders. | ||
| * | ||
| * Every property carries a `description` because the alternative is the model | ||
| * inferring one from the property name, and names like `scope`, `source` and | ||
| * `related` do not survive that inference — `scope` is filesystem paths on a | ||
| * card and subject-matter tags on a document. Describing them is not | ||
| * decoration; it is the difference between a call that lands and a retry. | ||
| */ | ||
| function text(description, extra = {}) { | ||
| return { type: "string", description, ...extra }; | ||
| } | ||
| /** A required identifier: never empty, never padded. */ | ||
| function identifier(description) { | ||
| return { type: "string", minLength: 1, description }; | ||
| } | ||
| function strings(description, extra = {}) { | ||
| return { type: "array", items: { type: "string" }, description, ...extra }; | ||
| } | ||
| function flag(description, extra = {}) { | ||
| return { type: "boolean", description, ...extra }; | ||
| } | ||
| function count(description, extra = {}) { | ||
| return { type: "integer", description, ...extra }; | ||
| } | ||
| /** | ||
| * A closed vocabulary. | ||
| * | ||
| * Only for the frozen protocol constants. Areas, document kinds, changelog | ||
| * types and the rest are declared per project — `validateStringList` accepts | ||
| * any string for them — so an enum here would refuse values a project has | ||
| * legitimately configured. Those say where to look instead. | ||
| */ | ||
| function choice(values, description, extra = {}) { | ||
| return { type: "string", enum: [...values], description, ...extra }; | ||
| } | ||
| const WORKSPACE_VOCABULARY = "Project-declared, so the accepted values vary; project_workspace reports them."; | ||
| /** Project-declared classification axes: `{ context: "treasury" }`. */ | ||
| const AXES_OBJECT = { | ||
| type: "object", | ||
| additionalProperties: { type: "string" } | ||
| additionalProperties: { type: "string" }, | ||
| description: "Declared classification axes as { axis: value }, e.g. { context: \"treasury\" }. " + | ||
| WORKSPACE_VOCABULARY | ||
| }; | ||
| const EXPECTED_REVISION = text("Revision string from an earlier read of this record. The write is refused if it no longer matches, so a concurrent edit is reported rather than overwritten. Omit to skip the check."); | ||
| const ACTOR = text("Who to attribute this to. Defaults to the MCP client's own name; pass one only to act on another actor's behalf."); | ||
| const BODY = text("Markdown body, written below the frontmatter."); | ||
| const LIMIT_DEFAULT = 50; | ||
| function schema(properties, required = []) { | ||
@@ -29,2 +72,83 @@ return { | ||
| } | ||
| /** | ||
| * A declared reply shape. | ||
| * | ||
| * Never a closed object: `toolResult` appends `truncated` when a payload | ||
| * exceeds `mcp.maxToolResultBytes`, and a closed schema would make its own | ||
| * degradation path invalid. | ||
| */ | ||
| function output(properties, required = []) { | ||
| return { | ||
| type: "object", | ||
| additionalProperties: true, | ||
| properties, | ||
| ...(required.length ? { required } : {}) | ||
| }; | ||
| } | ||
| const RECORD_SUMMARY = { | ||
| type: "object", | ||
| additionalProperties: true, | ||
| description: "A record in list projection: identity and frontmatter without the Markdown body.", | ||
| properties: { | ||
| id: text("Stable record ID: T-0042, DOC-0003, CHG-0101, ADR-0009."), | ||
| kind: text("Record family: card, doc, change, release or memory."), | ||
| recordType: text("Type within the family — a card's type, a document's kind, a memory record's collection."), | ||
| title: text("Human-readable title."), | ||
| path: text("Repository-relative path to the Markdown file."), | ||
| status: text("Lifecycle status, in the vocabulary of this record's family."), | ||
| created: text("Creation date, YYYY-MM-DD."), | ||
| updated: text("Date of the last write, YYYY-MM-DD."), | ||
| incomingTotal: count("How many other records link to this one."), | ||
| bodyBytes: count("Size in bytes of the body this projection left out.") | ||
| } | ||
| }; | ||
| const RECORD_FULL = { | ||
| type: "object", | ||
| additionalProperties: true, | ||
| description: "A canonical record with its body, revision and reference graph.", | ||
| properties: { | ||
| id: text("Stable record ID."), | ||
| kind: text("Record family: card, doc, change, release or memory."), | ||
| recordType: text("Type within the family."), | ||
| title: text("Human-readable title."), | ||
| status: text("Lifecycle status."), | ||
| path: text("Repository-relative path to the Markdown file."), | ||
| file: text("File name within the collection directory."), | ||
| revision: text("Content hash to pass back as expectedRevision on the next write."), | ||
| body: text("Markdown body below the frontmatter."), | ||
| created: text("Creation date, YYYY-MM-DD."), | ||
| updated: text("Date of the last write, YYYY-MM-DD."), | ||
| archived: flag("Whether the record lives in the archive directory."), | ||
| tags: strings("Free-form tags."), | ||
| outgoing: { | ||
| type: "array", | ||
| items: { type: "object", additionalProperties: true }, | ||
| description: "References this record makes to others." | ||
| }, | ||
| incoming: { | ||
| type: "array", | ||
| items: { type: "object", additionalProperties: true }, | ||
| description: "Backlinks: references other records make to this one." | ||
| }, | ||
| incomingTotal: count("Total backlinks, which may exceed the returned page."), | ||
| issues: { | ||
| type: "array", | ||
| items: { type: "object", additionalProperties: true }, | ||
| description: "Validation findings doctor would report for this record." | ||
| } | ||
| } | ||
| }; | ||
| function listing(what) { | ||
| return output({ | ||
| records: { | ||
| type: "array", | ||
| items: RECORD_SUMMARY, | ||
| description: `${what} matching the filters, in list projection.` | ||
| }, | ||
| total: count("Matches before offset and limit were applied."), | ||
| offset: count("Offset this page started at."), | ||
| limit: count("Maximum this page could contain.") | ||
| }, ["records", "total"]); | ||
| } | ||
| const RECORD_RESULT = output({ record: RECORD_FULL }, ["record"]); | ||
| function annotations({ readOnly = false, destructive = false, idempotent = false } = {}) { | ||
@@ -191,4 +315,19 @@ return { | ||
| title: "Read project workspace", | ||
| description: "Return the effective Workfile workspace, schema, enabled modules and mutation mode.", | ||
| description: "Return the effective Workfile workspace, schema, enabled modules and mutation mode. Read this first when a vocabulary is project-declared: it reports the areas, axes, document kinds, changelog types and memory collections this project accepts.", | ||
| inputSchema: schema({}), | ||
| outputSchema: output({ | ||
| name: text("Project name from project.config.mjs."), | ||
| root: text("Absolute path to the workspace root."), | ||
| version: { | ||
| type: "object", | ||
| additionalProperties: true, | ||
| description: "Schema version the workspace was created with." | ||
| }, | ||
| schema: { | ||
| type: "object", | ||
| additionalProperties: true, | ||
| description: "Effective vocabularies and paths per module: cards (statuses, types, priorities, efforts, areas, axes), docs, memory, changelog, agents, ci, mcp and search." | ||
| }, | ||
| readOnly: flag("Whether this server refuses mutations, from --read-only or mcp.allowMutations.") | ||
| }, ["name", "root", "readOnly"]), | ||
| annotations: annotations({ readOnly: true, idempotent: true }), | ||
@@ -211,12 +350,28 @@ readOnly: true, | ||
| inputSchema: schema({ | ||
| query: { type: "string", minLength: 1 }, | ||
| kinds: STRING_ARRAY, | ||
| limit: { type: "integer", minimum: 1, maximum: 100 }, | ||
| mode: { type: "string", enum: ["lexical", "hybrid"] }, | ||
| view: { | ||
| type: "string", | ||
| enum: ["summary", "full"], | ||
| description: "summary (default) omits record bodies and returns an excerpt; full returns everything." | ||
| } | ||
| query: identifier("Free text. Matched against titles, bodies and tags; never empty."), | ||
| kinds: strings("Restrict to these record families: card, doc, change, release, memory. Omit to search all of them."), | ||
| limit: count("Maximum records to return.", { | ||
| minimum: 1, | ||
| maximum: 100, | ||
| default: 20 | ||
| }), | ||
| mode: choice(["lexical", "hybrid"], "hybrid adds the injected semantic provider when the host configured one and falls back to lexical when it did not. lexical is deterministic.", { default: "hybrid" }), | ||
| view: choice(["summary", "full"], "summary omits record bodies and returns an excerpt; full returns everything, which costs far more tokens at the same limit.", { default: "summary" }) | ||
| }, ["query"]), | ||
| outputSchema: output({ | ||
| records: { | ||
| type: "array", | ||
| items: { | ||
| ...RECORD_SUMMARY, | ||
| description: "A match, carrying searchScore and — in summary view — excerpt." | ||
| }, | ||
| description: "Matches, best-scoring first." | ||
| }, | ||
| total: count("Matches found before limit was applied."), | ||
| offset: count("Offset this page started at."), | ||
| limit: count("Maximum this page could contain."), | ||
| view: text("Which projection was applied: summary or full."), | ||
| mode: text("Which ranking ran: lexical or hybrid."), | ||
| provider: text("Semantic provider that contributed, or null when ranking was purely lexical.") | ||
| }, ["records", "total"]), | ||
| annotations: annotations({ readOnly: true, idempotent: true }), | ||
@@ -247,4 +402,7 @@ readOnly: true, | ||
| title: "Read a project record", | ||
| description: "Read one canonical project record by stable ID, including body, revision, outgoing references, backlinks and health signals.", | ||
| inputSchema: schema({ id: { type: "string", minLength: 1 } }, ["id"]), | ||
| description: "Read one canonical project record by stable ID, including body, revision, outgoing references, backlinks and health signals. The revision it returns is what a later write passes as expectedRevision.", | ||
| inputSchema: schema({ | ||
| id: identifier("Stable record ID of any family: T-0042, DOC-0003, CHG-0101, REL-0007, ADR-0009.") | ||
| }, ["id"]), | ||
| outputSchema: RECORD_RESULT, | ||
| annotations: annotations({ readOnly: true, idempotent: true }), | ||
@@ -265,6 +423,26 @@ readOnly: true, | ||
| title: "Run workfile doctor", | ||
| description: "Validate Work, Docs, History, Memory, agent instructions, CI templates and cross-record references.", | ||
| description: "Validate Work, Docs, History, Memory, agent instructions, CI templates and cross-record references. Run before declaring work finished.", | ||
| inputSchema: schema({ | ||
| checkPaths: { type: "boolean", description: "Check referenced filesystem paths." } | ||
| checkPaths: flag("Also verify that paths referenced by records exist on disk. Set false to skip the filesystem walk on a large repository.", { default: true }) | ||
| }), | ||
| outputSchema: output({ | ||
| ok: flag("True when no error-severity issue was found."), | ||
| generatedAt: text("When this run completed, as an RFC 3339 timestamp."), | ||
| cards: count("Cards inspected."), | ||
| modules: { | ||
| type: "object", | ||
| additionalProperties: true, | ||
| description: "Record counts per module and collection." | ||
| }, | ||
| counts: { | ||
| type: "object", | ||
| additionalProperties: true, | ||
| description: "Issue counts by severity: error, warning, info." | ||
| }, | ||
| issues: { | ||
| type: "array", | ||
| items: { type: "object", additionalProperties: true }, | ||
| description: "Findings, each with a severity, a code and the record it concerns." | ||
| } | ||
| }, ["ok", "issues"]), | ||
| annotations: annotations({ readOnly: true, idempotent: true }), | ||
@@ -282,7 +460,23 @@ readOnly: true, | ||
| title: "Build bounded agent context", | ||
| description: "Build a compact context bundle around a card from direct relations, active conventions, open incidents and active project context.", | ||
| description: "Build a compact context bundle around a card from direct relations, active conventions, open incidents and active project context. Prefer this over reading records one by one before working on a card.", | ||
| inputSchema: schema({ | ||
| cardId: { type: "string", minLength: 1 }, | ||
| limit: { type: "integer", minimum: 1, maximum: 50 } | ||
| cardId: identifier("Card the bundle is centred on, e.g. T-0042."), | ||
| limit: count("Maximum related records to include.", { | ||
| minimum: 1, | ||
| maximum: 50, | ||
| default: 20 | ||
| }) | ||
| }, ["cardId"]), | ||
| outputSchema: output({ | ||
| focus: text("ID of the card the bundle was built around."), | ||
| generatedAt: text("When the bundle was assembled, RFC 3339."), | ||
| truncated: flag("True when relevant records were dropped to respect limit."), | ||
| totalAvailable: count("Related records before limit was applied."), | ||
| records: { | ||
| type: "array", | ||
| items: RECORD_FULL, | ||
| description: "The selected records, with bodies." | ||
| }, | ||
| markdown: text("The same bundle rendered as Markdown, ready to paste into a prompt.") | ||
| }, ["focus", "records"]), | ||
| annotations: annotations({ readOnly: true, idempotent: true }), | ||
@@ -306,18 +500,24 @@ readOnly: true, | ||
| inputSchema: schema({ | ||
| status: STRING_ARRAY, | ||
| area: STRING_ARRAY, | ||
| type: STRING_ARRAY, | ||
| priority: STRING_ARRAY, | ||
| parent: { type: "string" }, | ||
| claimedBy: { type: "string" }, | ||
| unclaimed: { type: "boolean" }, | ||
| tags: STRING_ARRAY, | ||
| updatedSince: { | ||
| type: "string", | ||
| description: "Only records updated on or after this date. YYYY-MM-DD; an RFC 3339 timestamp is read as its date.", | ||
| pattern: "^\\d{4}-\\d{2}-\\d{2}" | ||
| }, | ||
| limit: { type: "integer", minimum: 1, maximum: 200 }, | ||
| offset: { type: "integer", minimum: 0 } | ||
| status: strings(`Keep only these statuses; any match passes. One of: ${CARD_STATUSES.join(", ")}.`, { items: { type: "string", enum: [...CARD_STATUSES] } }), | ||
| area: strings(`Keep only these areas. ${WORKSPACE_VOCABULARY}`), | ||
| type: strings(`Keep only these card types. One of: ${CARD_TYPES.join(", ")}.`, { | ||
| items: { type: "string", enum: [...CARD_TYPES] } | ||
| }), | ||
| priority: strings(`Keep only these priorities. One of: ${CARD_PRIORITIES.join(", ")}.`, { items: { type: "string", enum: [...CARD_PRIORITIES] } }), | ||
| parent: text("Keep only direct children of this card ID."), | ||
| claimedBy: text("Keep only cards claimed by this actor."), | ||
| unclaimed: flag("Keep only cards nobody has claimed."), | ||
| tags: strings("Keep cards carrying any of these tags."), | ||
| updatedSince: text("Only records updated on or after this date. YYYY-MM-DD; an RFC 3339 timestamp is read as its date.", { pattern: "^\\d{4}-\\d{2}-\\d{2}" }), | ||
| limit: count("Maximum cards to return.", { | ||
| minimum: 1, | ||
| maximum: 200, | ||
| default: LIMIT_DEFAULT | ||
| }), | ||
| offset: count("Skip this many matches before the page starts.", { | ||
| minimum: 0, | ||
| default: 0 | ||
| }) | ||
| }), | ||
| outputSchema: listing("Cards"), | ||
| annotations: annotations({ readOnly: true, idempotent: true }), | ||
@@ -334,8 +534,16 @@ readOnly: true, | ||
| inputSchema: schema({ | ||
| kind: STRING_ARRAY, | ||
| status: STRING_ARRAY, | ||
| managed: { type: "boolean" }, | ||
| limit: { type: "integer", minimum: 1, maximum: 200 }, | ||
| offset: { type: "integer", minimum: 0 } | ||
| kind: strings(`Keep only these document kinds. ${WORKSPACE_VOCABULARY}`), | ||
| status: strings(`Keep only these document statuses. ${WORKSPACE_VOCABULARY}`), | ||
| managed: flag("true keeps only documents Workfile owns under the managed docs root; false keeps only repository files it merely indexes."), | ||
| limit: count("Maximum documents to return.", { | ||
| minimum: 1, | ||
| maximum: 200, | ||
| default: LIMIT_DEFAULT | ||
| }), | ||
| offset: count("Skip this many matches before the page starts.", { | ||
| minimum: 0, | ||
| default: 0 | ||
| }) | ||
| }), | ||
| outputSchema: listing("Documents"), | ||
| annotations: annotations({ readOnly: true, idempotent: true }), | ||
@@ -352,9 +560,17 @@ readOnly: true, | ||
| inputSchema: schema({ | ||
| type: STRING_ARRAY, | ||
| area: STRING_ARRAY, | ||
| visibility: STRING_ARRAY, | ||
| released: { type: "boolean" }, | ||
| limit: { type: "integer", minimum: 1, maximum: 200 }, | ||
| offset: { type: "integer", minimum: 0 } | ||
| type: strings(`Keep only these change types. ${WORKSPACE_VOCABULARY}`), | ||
| area: strings(`Keep only these areas. ${WORKSPACE_VOCABULARY}`), | ||
| visibility: strings(`Keep only these visibilities, typically public or internal. ${WORKSPACE_VOCABULARY}`), | ||
| released: flag("true keeps only fragments already consumed by a release; false keeps only unreleased ones."), | ||
| limit: count("Maximum records to return.", { | ||
| minimum: 1, | ||
| maximum: 200, | ||
| default: LIMIT_DEFAULT | ||
| }), | ||
| offset: count("Skip this many matches before the page starts.", { | ||
| minimum: 0, | ||
| default: 0 | ||
| }) | ||
| }), | ||
| outputSchema: listing("Change fragments and releases"), | ||
| annotations: annotations({ readOnly: true, idempotent: true }), | ||
@@ -371,7 +587,20 @@ readOnly: true, | ||
| inputSchema: schema({ | ||
| collection: STRING_ARRAY, | ||
| status: STRING_ARRAY, | ||
| limit: { type: "integer", minimum: 1, maximum: 200 }, | ||
| offset: { type: "integer", minimum: 0 } | ||
| collection: strings("Keep only these collections: learnings, decisions, incidents, conventions, context.", { | ||
| items: { | ||
| type: "string", | ||
| enum: ["learnings", "decisions", "incidents", "conventions", "context"] | ||
| } | ||
| }), | ||
| status: strings(`Keep only these lifecycle statuses. Each collection has its own vocabulary — a decision is proposed or accepted, an incident is open or resolved. ${WORKSPACE_VOCABULARY}`), | ||
| limit: count("Maximum records to return.", { | ||
| minimum: 1, | ||
| maximum: 200, | ||
| default: LIMIT_DEFAULT | ||
| }), | ||
| offset: count("Skip this many matches before the page starts.", { | ||
| minimum: 0, | ||
| default: 0 | ||
| }) | ||
| }), | ||
| outputSchema: listing("Memory records"), | ||
| annotations: annotations({ readOnly: true, idempotent: true }), | ||
@@ -388,6 +617,21 @@ readOnly: true, | ||
| inputSchema: schema({ | ||
| actor: { type: "string" }, | ||
| area: STRING_ARRAY, | ||
| limit: { type: "integer", minimum: 1, maximum: 20 } | ||
| actor: ACTOR, | ||
| area: strings(`Rank only cards in these areas. ${WORKSPACE_VOCABULARY}`), | ||
| limit: count("Maximum candidates to rank.", { | ||
| minimum: 1, | ||
| maximum: NEXT_MAXIMUM_LIMIT, | ||
| default: NEXT_DEFAULT_LIMIT | ||
| }) | ||
| }), | ||
| outputSchema: output({ | ||
| records: { | ||
| type: "array", | ||
| items: { | ||
| ...RECORD_SUMMARY, | ||
| description: "A ranked candidate, carrying `reason` — why the ranking surfaced it." | ||
| }, | ||
| description: "Candidates, most actionable first." | ||
| }, | ||
| total: count("Actionable cards found before limit was applied.") | ||
| }, ["records", "total"]), | ||
| annotations: annotations({ readOnly: true, idempotent: true }), | ||
@@ -402,19 +646,24 @@ readOnly: true, | ||
| title: "Create a work card", | ||
| description: "Create one canonical Work card with a concurrency-safe stable ID.", | ||
| description: "Create one canonical Work card with a concurrency-safe stable ID. Search first: this mints a new record rather than finding an existing one.", | ||
| inputSchema: schema({ | ||
| title: { type: "string", minLength: 1, maxLength: 80 }, | ||
| status: { type: "string" }, | ||
| type: { type: "string" }, | ||
| priority: { type: "string" }, | ||
| area: { type: "string" }, | ||
| parent: { type: "string" }, | ||
| depends: STRING_ARRAY, | ||
| source: { type: "string" }, | ||
| tags: STRING_ARRAY, | ||
| scope: STRING_ARRAY, | ||
| related: STRING_ARRAY, | ||
| effort: { type: "string" }, | ||
| start: { type: "string" }, | ||
| due: { type: "string" }, | ||
| body: { type: "string" }, | ||
| title: text("What the card is about, in one line.", { | ||
| minLength: 1, | ||
| maxLength: 80 | ||
| }), | ||
| status: choice(CARD_STATUSES, "Starting lifecycle status.", { | ||
| default: "backlog" | ||
| }), | ||
| type: choice(CARD_TYPES, "What kind of work this is."), | ||
| priority: choice(CARD_PRIORITIES, "How urgent the work is."), | ||
| area: text(`Part of the system this touches. ${WORKSPACE_VOCABULARY}`), | ||
| parent: text("ID of the parent card. The hierarchy is bounded by cards.maxHierarchyDepth."), | ||
| depends: strings("IDs of cards that must close first. Blocks this card from being ranked as actionable."), | ||
| source: text("Where the work came from: an issue URL, a person, a meeting."), | ||
| tags: strings("Free-form tags for filtering."), | ||
| scope: strings("Repository paths this work will change. Declared here, enforced when the card is claimed."), | ||
| related: strings("IDs of records worth reading alongside this one."), | ||
| effort: choice(CARD_EFFORTS, "Rough size: S, M or L."), | ||
| start: text("Planned start date, YYYY-MM-DD."), | ||
| due: text("Target completion date, YYYY-MM-DD."), | ||
| body: BODY, | ||
| // A container rather than a property per axis: this schema is | ||
@@ -426,2 +675,3 @@ // static and axes are declared per project, so the axis name | ||
| }, ["title"]), | ||
| outputSchema: RECORD_RESULT, | ||
| annotations: annotations(), | ||
@@ -446,11 +696,15 @@ readOnly: false, | ||
| title: "Claim a work card", | ||
| description: "Claim a card for an actor, move it to doing and optionally declare the filesystem scope that will be changed.", | ||
| description: "Claim a card for an actor, move it to doing and optionally declare the filesystem scope that will be changed. Claim before editing anything the card covers; another actor's claim is refused unless forced.", | ||
| inputSchema: schema({ | ||
| id: { type: "string", minLength: 1 }, | ||
| actor: { type: "string", minLength: 1 }, | ||
| scope: STRING_ARRAY, | ||
| force: { type: "boolean" }, | ||
| reason: { type: "string" }, | ||
| expectedRevision: { type: "string" } | ||
| id: identifier("Card to claim, e.g. T-0042."), | ||
| actor: text("Who is claiming. Defaults to the MCP client's own name; a hand-typed value will not match the identity the edit guard sees.", { minLength: 1 }), | ||
| scope: strings("Repository paths this claim covers. Overlapping scopes are what stop two agents editing the same files."), | ||
| force: flag("Take a claim another actor already holds. Requires reason.", { default: false }), | ||
| reason: text("Why the existing claim is being taken over. Recorded on the card."), | ||
| expectedRevision: EXPECTED_REVISION | ||
| }, ["id", "actor"]), | ||
| outputSchema: output({ | ||
| record: RECORD_FULL, | ||
| warnings: strings("Non-fatal findings, such as a stale claim that was taken over.") | ||
| }, ["record"]), | ||
| annotations: annotations(), | ||
@@ -478,9 +732,12 @@ readOnly: false, | ||
| inputSchema: schema({ | ||
| id: { type: "string", minLength: 1 }, | ||
| actor: { type: "string" }, | ||
| status: { type: "string" }, | ||
| force: { type: "boolean" }, | ||
| reason: { type: "string" }, | ||
| expectedRevision: { type: "string" } | ||
| id: identifier("Card whose claim is being released."), | ||
| actor: ACTOR, | ||
| status: choice(CARD_STATUSES.filter((value) => value !== "doing"), "Status to leave the card in. Omit to keep the current one — a card just moved to done is not demoted by releasing it — except doing, which becomes next because active work without a claimant is a contradiction. doing is refused as an explicit target.", {}), | ||
| force: flag("Release a claim held by another actor. Requires reason.", { | ||
| default: false | ||
| }), | ||
| reason: text("Why another actor's claim is being released. Recorded on the card."), | ||
| expectedRevision: EXPECTED_REVISION | ||
| }, ["id"]), | ||
| outputSchema: RECORD_RESULT, | ||
| annotations: annotations({ idempotent: true }), | ||
@@ -504,6 +761,7 @@ async execute(args, context) { | ||
| inputSchema: schema({ | ||
| id: { type: "string", minLength: 1 }, | ||
| body: { type: "string" }, | ||
| expectedRevision: { type: "string" } | ||
| id: identifier("Card whose body is being replaced."), | ||
| body: text("The complete new Markdown body. This overwrites, so read the card first unless you intend to discard what is there."), | ||
| expectedRevision: EXPECTED_REVISION | ||
| }, ["id", "body"]), | ||
| outputSchema: RECORD_RESULT, | ||
| annotations: annotations({}), | ||
@@ -524,7 +782,8 @@ async execute(args, context) { | ||
| inputSchema: schema({ | ||
| id: { type: "string", minLength: 1 }, | ||
| text: { type: "string", minLength: 1 }, | ||
| section: { type: "string" }, | ||
| actor: { type: "string" } | ||
| id: identifier("Card to append to."), | ||
| text: identifier("The line to append. One observation, not a paragraph."), | ||
| section: text("Heading to append under. Created if it does not exist yet.", { default: "Notes" }), | ||
| actor: ACTOR | ||
| }, ["id", "text"]), | ||
| outputSchema: RECORD_RESULT, | ||
| annotations: annotations({}), | ||
@@ -544,10 +803,11 @@ async execute(args, context) { | ||
| title: "Transition a work card", | ||
| description: "Move a card to another protocol status while enforcing claim and verification semantics.", | ||
| description: "Move a card to another protocol status. Moving to doing claims the card for the actor; review means the implementation is finished but unverified, and done requires evidence it ran, not a commit.", | ||
| inputSchema: schema({ | ||
| id: { type: "string", minLength: 1 }, | ||
| status: { type: "string", minLength: 1 }, | ||
| actor: { type: "string" }, | ||
| scope: STRING_ARRAY, | ||
| expectedRevision: { type: "string" } | ||
| id: identifier("Card to transition."), | ||
| status: choice(CARD_STATUSES, "Target status. backlog: identified, uncommitted. next: prioritized. doing: actively worked, and claimed by the actor. review: implemented, awaiting verification. blocked: externally blocked, record why. deferred: postponed on purpose, record why. done: verified where it actually runs. discarded: will not be done, record why."), | ||
| actor: ACTOR, | ||
| scope: strings("Repository paths to claim when moving to doing. Ignored by the other statuses."), | ||
| expectedRevision: EXPECTED_REVISION | ||
| }, ["id", "status"]), | ||
| outputSchema: RECORD_RESULT, | ||
| annotations: annotations(), | ||
@@ -572,6 +832,11 @@ readOnly: false, | ||
| inputSchema: schema({ | ||
| id: { type: "string", minLength: 1 }, | ||
| changes: { type: "object", additionalProperties: true }, | ||
| expectedRevision: { type: "string" } | ||
| id: identifier("Card to patch."), | ||
| changes: { | ||
| type: "object", | ||
| additionalProperties: true, | ||
| description: "Frontmatter fields to overwrite, e.g. { priority: \"high\", tags: [\"mcp\"] }. Only the keys present are touched. Use project_card_transition for status and project_card_write for the body; declared axes go under an axes key." | ||
| }, | ||
| expectedRevision: EXPECTED_REVISION | ||
| }, ["id", "changes"]), | ||
| outputSchema: RECORD_RESULT, | ||
| annotations: annotations({ idempotent: true }), | ||
@@ -593,7 +858,8 @@ readOnly: false, | ||
| title: "Archive a closed work card", | ||
| description: "Move a closed card to the canonical archive directory.", | ||
| description: "Move a closed card to the canonical archive directory. Only done and discarded cards can be archived; the ID and the file survive, so project_card_reopen undoes this.", | ||
| inputSchema: schema({ | ||
| id: { type: "string", minLength: 1 }, | ||
| expectedRevision: { type: "string" } | ||
| id: identifier("Card to archive. Must already be done or discarded."), | ||
| expectedRevision: EXPECTED_REVISION | ||
| }, ["id"]), | ||
| outputSchema: RECORD_RESULT, | ||
| annotations: annotations({ destructive: true }), | ||
@@ -613,9 +879,12 @@ readOnly: false, | ||
| title: "Reopen an archived work card", | ||
| description: "Move an archived card back into the live backlog.", | ||
| description: "Move an archived card back out of the archive directory and into a live status. The ID never changes, so every existing reference to it keeps resolving.", | ||
| inputSchema: schema({ | ||
| id: { type: "string", minLength: 1 }, | ||
| status: { type: "string" }, | ||
| actor: { type: "string" }, | ||
| expectedRevision: { type: "string" } | ||
| id: identifier("Archived card to bring back."), | ||
| status: choice(CARD_STATUSES, "Status to reopen into.", { | ||
| default: "backlog" | ||
| }), | ||
| actor: ACTOR, | ||
| expectedRevision: EXPECTED_REVISION | ||
| }, ["id"]), | ||
| outputSchema: RECORD_RESULT, | ||
| annotations: annotations(), | ||
@@ -639,15 +908,16 @@ readOnly: false, | ||
| inputSchema: schema({ | ||
| title: { type: "string", minLength: 1 }, | ||
| kind: { type: "string" }, | ||
| status: { type: "string" }, | ||
| folder: { type: "string" }, | ||
| owners: STRING_ARRAY, | ||
| related: STRING_ARRAY, | ||
| supersedes: STRING_ARRAY, | ||
| scope: STRING_ARRAY, | ||
| tags: STRING_ARRAY, | ||
| source: { type: "string" }, | ||
| review_after: { type: "string" }, | ||
| body: { type: "string" } | ||
| title: identifier("What the document is about, in one line."), | ||
| kind: text(`What sort of document this is — architecture, runbook, reference and so on. ${WORKSPACE_VOCABULARY}`), | ||
| status: text(`Lifecycle status, typically draft or current. ${WORKSPACE_VOCABULARY}`), | ||
| folder: text("Folder below the managed docs root. Omit to let docs.layout decide; an empty string writes to the root."), | ||
| owners: strings("Who is answerable for keeping this accurate."), | ||
| related: strings("IDs of records worth reading alongside this one."), | ||
| supersedes: strings("IDs of documents this replaces. They are marked superseded."), | ||
| scope: strings("Subject matter this document covers — topics, not file paths."), | ||
| tags: strings("Free-form tags for filtering."), | ||
| source: text("Where the content came from: a URL, a person, a meeting."), | ||
| review_after: text("Date after which this goes stale, YYYY-MM-DD. Defaults to docs.reviewIntervalDays from now."), | ||
| body: BODY | ||
| }, ["title"]), | ||
| outputSchema: RECORD_RESULT, | ||
| annotations: annotations(), | ||
@@ -675,6 +945,7 @@ readOnly: false, | ||
| inputSchema: schema({ | ||
| id: { type: "string", minLength: 1 }, | ||
| folder: { type: "string" }, | ||
| expectedRevision: { type: "string" } | ||
| id: identifier("Managed document to move, e.g. DOC-0003."), | ||
| folder: text("Destination folder relative to the managed docs root. An empty string moves it to the root."), | ||
| expectedRevision: EXPECTED_REVISION | ||
| }, ["id", "folder"]), | ||
| outputSchema: RECORD_RESULT, | ||
| annotations: annotations({ idempotent: true }), | ||
@@ -695,8 +966,13 @@ readOnly: false, | ||
| title: "Patch managed documentation", | ||
| description: "Patch a managed document using optimistic concurrency. Indexed repository docs are intentionally read-only through this tool.", | ||
| description: "Patch a managed document using optimistic concurrency. Indexed repository docs are intentionally read-only through this tool — edit those files directly.", | ||
| inputSchema: schema({ | ||
| id: { type: "string", minLength: 1 }, | ||
| changes: { type: "object", additionalProperties: true }, | ||
| expectedRevision: { type: "string" } | ||
| id: identifier("Managed document to patch, e.g. DOC-0003."), | ||
| changes: { | ||
| type: "object", | ||
| additionalProperties: true, | ||
| description: "Frontmatter fields to overwrite, plus body to replace the Markdown. Only the keys present are touched. Use project_doc_move to change the folder." | ||
| }, | ||
| expectedRevision: EXPECTED_REVISION | ||
| }, ["id", "changes"]), | ||
| outputSchema: RECORD_RESULT, | ||
| annotations: annotations({ idempotent: true }), | ||
@@ -714,15 +990,16 @@ readOnly: false, | ||
| title: "Add a changelog fragment", | ||
| description: "Create an atomic unreleased changelog fragment and relate it to cards, decisions or other records.", | ||
| description: "Create an atomic unreleased changelog fragment and relate it to cards, decisions or other records. One fragment per user-visible change, written when the change lands rather than when the release is cut.", | ||
| inputSchema: schema({ | ||
| title: { type: "string", minLength: 1 }, | ||
| type: { type: "string" }, | ||
| area: { type: "string" }, | ||
| visibility: { type: "string" }, | ||
| cards: STRING_ARRAY, | ||
| issues: STRING_ARRAY, | ||
| decisions: STRING_ARRAY, | ||
| related: STRING_ARRAY, | ||
| tags: STRING_ARRAY, | ||
| body: { type: "string" } | ||
| title: identifier("The change, stated from the reader's side rather than the implementer's."), | ||
| type: text(`What kind of change this is — added, changed, fixed and so on. ${WORKSPACE_VOCABULARY}`), | ||
| area: text(`Part of the system that changed. ${WORKSPACE_VOCABULARY}`), | ||
| visibility: text(`Who the entry is rendered for, typically public or internal. ${WORKSPACE_VOCABULARY}`), | ||
| cards: strings("IDs of the cards this change came from."), | ||
| issues: strings("External issue or ticket references."), | ||
| decisions: strings("IDs of decision records this change implements."), | ||
| related: strings("IDs of other records worth reading alongside."), | ||
| tags: strings("Free-form tags for filtering."), | ||
| body: BODY | ||
| }, ["title"]), | ||
| outputSchema: RECORD_RESULT, | ||
| annotations: annotations(), | ||
@@ -748,8 +1025,13 @@ readOnly: false, | ||
| title: "Patch a changelog fragment", | ||
| description: "Patch an unreleased changelog fragment using optimistic concurrency.", | ||
| description: "Patch an unreleased changelog fragment using optimistic concurrency. Only works before a release consumes the fragment; afterwards the text belongs to that release.", | ||
| inputSchema: schema({ | ||
| id: { type: "string", minLength: 1 }, | ||
| changes: { type: "object", additionalProperties: true }, | ||
| expectedRevision: { type: "string" } | ||
| id: identifier("Unreleased fragment to patch, e.g. CHG-0101."), | ||
| changes: { | ||
| type: "object", | ||
| additionalProperties: true, | ||
| description: "Frontmatter fields to overwrite — title, type, area, visibility, tags and the relation lists — plus body to replace the Markdown. Only the keys present are touched." | ||
| }, | ||
| expectedRevision: EXPECTED_REVISION | ||
| }, ["id", "changes"]), | ||
| outputSchema: RECORD_RESULT, | ||
| annotations: annotations({ idempotent: true }), | ||
@@ -767,7 +1049,20 @@ readOnly: false, | ||
| title: "Preview a release", | ||
| description: "Render selected unreleased fragments without mutating the repository.", | ||
| description: "Render selected unreleased fragments without mutating the repository. Use to read a release before project_changelog_release makes it permanent.", | ||
| inputSchema: schema({ | ||
| fragmentIds: STRING_ARRAY, | ||
| visibility: { type: "string" } | ||
| fragmentIds: strings("Fragments to include, e.g. CHG-0101. Omit to preview every unreleased fragment."), | ||
| visibility: text(`Render only entries at this visibility, typically public or internal. Omit to include all of them. ${WORKSPACE_VOCABULARY}`) | ||
| }), | ||
| outputSchema: output({ | ||
| fragments: { | ||
| type: "array", | ||
| items: RECORD_SUMMARY, | ||
| description: "Fragments this preview covered." | ||
| }, | ||
| groups: { | ||
| type: "array", | ||
| items: { type: "object", additionalProperties: true }, | ||
| description: "Entries bucketed by change type, in render order." | ||
| }, | ||
| markdown: text("The release notes as they would be written.") | ||
| }, ["markdown"]), | ||
| annotations: annotations({ readOnly: true, idempotent: true }), | ||
@@ -785,13 +1080,24 @@ readOnly: true, | ||
| title: "Create a release", | ||
| description: "Consume selected unreleased fragments and create a canonical release record. This moves fragment files into the release directory.", | ||
| description: "Consume selected unreleased fragments and create a canonical release record. This moves fragment files into the release directory, so preview first: the fragments stop being separately editable.", | ||
| inputSchema: schema({ | ||
| version: { type: "string", minLength: 1 }, | ||
| title: { type: "string" }, | ||
| date: { type: "string" }, | ||
| fragmentIds: STRING_ARRAY, | ||
| visibility: { type: "string" }, | ||
| commit: { type: "string" }, | ||
| tags: STRING_ARRAY, | ||
| body: { type: "string" } | ||
| version: identifier("Version being cut, e.g. 0.5.4. Validated against changelog.releaseStrategy."), | ||
| title: text("Release title. Defaults to the version itself."), | ||
| date: text("Release date, YYYY-MM-DD. Defaults to today."), | ||
| fragmentIds: strings("Fragments to consume, e.g. CHG-0101. Omit to consume every unreleased fragment."), | ||
| visibility: text(`Visibility of the release record itself, typically public or internal. ${WORKSPACE_VOCABULARY}`), | ||
| commit: text("Commit SHA this release was cut from."), | ||
| tags: strings("Free-form tags for filtering."), | ||
| body: text("Markdown prelude written above the generated entries.") | ||
| }, ["version"]), | ||
| outputSchema: output({ | ||
| record: { | ||
| ...RECORD_FULL, | ||
| description: "The release record that was created." | ||
| }, | ||
| consumedFragments: { | ||
| type: "array", | ||
| items: RECORD_SUMMARY, | ||
| description: "Fragments that moved into the release directory and no longer exist as unreleased records." | ||
| } | ||
| }, ["record", "consumedFragments"]), | ||
| annotations: annotations({ destructive: true }), | ||
@@ -817,28 +1123,26 @@ readOnly: false, | ||
| title: "Add workfile memory", | ||
| description: "Create a typed learning, decision, incident, convention or temporary context record.", | ||
| description: "Create a typed learning, decision, incident, convention or temporary context record. For knowledge that should change future behaviour — not for narrating what happened this session.", | ||
| inputSchema: schema({ | ||
| collection: { | ||
| type: "string", | ||
| enum: ["learnings", "decisions", "incidents", "conventions", "context"] | ||
| }, | ||
| title: { type: "string", minLength: 1 }, | ||
| status: { type: "string" }, | ||
| category: { type: "string" }, | ||
| confidence: { type: "string" }, | ||
| occurrences: { type: "integer", minimum: 0 }, | ||
| severity: { type: "string" }, | ||
| started_at: { type: "string" }, | ||
| resolved_at: { type: "string" }, | ||
| expires: { type: "string" }, | ||
| review_after: { type: "string" }, | ||
| deciders: STRING_ARRAY, | ||
| related: STRING_ARRAY, | ||
| supersedes: STRING_ARRAY, | ||
| graduated_to: STRING_ARRAY, | ||
| corrective_actions: STRING_ARRAY, | ||
| scope: STRING_ARRAY, | ||
| owners: STRING_ARRAY, | ||
| tags: STRING_ARRAY, | ||
| body: { type: "string" } | ||
| collection: choice(["learnings", "decisions", "incidents", "conventions", "context"], "Which kind of memory this is. learnings: something discovered that changes how the next attempt goes. decisions: a choice made, with its rationale (ADR). incidents: something that broke, and what it cost. conventions: a rule the project now follows. context: temporary situational state, which expires."), | ||
| title: identifier("The knowledge itself, stated as a claim rather than a topic."), | ||
| status: text(`Lifecycle status. Each collection has its own vocabulary — a decision is proposed or accepted, an incident is open or resolved. ${WORKSPACE_VOCABULARY}`), | ||
| category: text("Optional sub-classification within the collection."), | ||
| confidence: text("How well established this is — for learnings, whether it has been seen once or many times."), | ||
| occurrences: count("How many times this has been observed.", { minimum: 0 }), | ||
| severity: text("For incidents: how bad it was."), | ||
| started_at: text("For incidents: when it began, YYYY-MM-DD."), | ||
| resolved_at: text("For incidents: when it was resolved, YYYY-MM-DD."), | ||
| expires: text("For context: the date after which this stops being true, YYYY-MM-DD."), | ||
| review_after: text("Date after which this should be re-read, YYYY-MM-DD."), | ||
| deciders: strings("For decisions: who made the call."), | ||
| related: strings("IDs of records worth reading alongside this one."), | ||
| supersedes: strings("IDs of memory records this replaces. Prefer project_memory_supersede, which updates both sides."), | ||
| graduated_to: strings("IDs of the durable records a learning has been promoted into."), | ||
| corrective_actions: strings("For incidents: IDs of the cards that stop it recurring."), | ||
| scope: strings("Subject matter this applies to — topics, not file paths."), | ||
| owners: strings("Who is answerable for keeping this accurate."), | ||
| tags: strings("Free-form tags for filtering."), | ||
| body: BODY | ||
| }, ["collection", "title"]), | ||
| outputSchema: RECORD_RESULT, | ||
| annotations: annotations(), | ||
@@ -868,8 +1172,13 @@ readOnly: false, | ||
| title: "Patch workfile memory", | ||
| description: "Patch a durable memory record using optimistic concurrency.", | ||
| description: "Patch a durable memory record using optimistic concurrency. To retire one in favour of another use project_memory_supersede, which updates both sides.", | ||
| inputSchema: schema({ | ||
| id: { type: "string", minLength: 1 }, | ||
| changes: { type: "object", additionalProperties: true }, | ||
| expectedRevision: { type: "string" } | ||
| id: identifier("Memory record to patch: LRN-, ADR-, INC-, CONV- or CTX-."), | ||
| changes: { | ||
| type: "object", | ||
| additionalProperties: true, | ||
| description: "Frontmatter fields to overwrite — status, tags, related, owners and the collection-specific fields — plus body to replace the Markdown. Only the keys present are touched." | ||
| }, | ||
| expectedRevision: EXPECTED_REVISION | ||
| }, ["id", "changes"]), | ||
| outputSchema: RECORD_RESULT, | ||
| annotations: annotations({ idempotent: true }), | ||
@@ -887,8 +1196,9 @@ readOnly: false, | ||
| title: "Graduate a learning", | ||
| description: "Mark a learning as graduated and link it to the convention, decision or documentation that now carries the durable rule.", | ||
| description: "Mark a learning as graduated and link it to the convention, decision or documentation that now carries the durable rule. Create the target record first — graduating points at something that must already exist.", | ||
| inputSchema: schema({ | ||
| id: { type: "string", minLength: 1 }, | ||
| targets: STRING_ARRAY, | ||
| expectedRevision: { type: "string" } | ||
| id: identifier("Learning to graduate, e.g. LRN-0015."), | ||
| targets: strings("IDs of the records that now carry the rule: a convention, a decision or a document."), | ||
| expectedRevision: EXPECTED_REVISION | ||
| }, ["id", "targets"]), | ||
| outputSchema: RECORD_RESULT, | ||
| annotations: annotations(), | ||
@@ -906,8 +1216,12 @@ readOnly: false, | ||
| title: "Supersede workfile memory", | ||
| description: "Supersede one memory record with another and update both sides atomically.", | ||
| description: "Supersede one memory record with another and update both sides atomically. Create the replacement first; neither record is deleted, so the superseded one stays readable and its ID keeps resolving.", | ||
| inputSchema: schema({ | ||
| id: { type: "string", minLength: 1 }, | ||
| replacementId: { type: "string", minLength: 1 }, | ||
| expectedRevision: { type: "string" } | ||
| id: identifier("Memory record being retired."), | ||
| replacementId: identifier("Memory record that replaces it. Must already exist."), | ||
| expectedRevision: EXPECTED_REVISION | ||
| }, ["id", "replacementId"]), | ||
| outputSchema: output({ | ||
| record: { ...RECORD_FULL, description: "The superseded record." }, | ||
| replacement: { ...RECORD_FULL, description: "The record that replaces it." } | ||
| }, ["record", "replacement"]), | ||
| annotations: annotations(), | ||
@@ -914,0 +1228,0 @@ readOnly: false, |
@@ -13,3 +13,3 @@ <!doctype html> | ||
| /> | ||
| <script type="module" crossorigin src="/static/index-F1UmdPYw.js"></script> | ||
| <script type="module" crossorigin src="/static/index-DEiK6_Ib.js"></script> | ||
| <link rel="modulepreload" crossorigin href="/static/rolldown-runtime-CbXtAM7H.js"> | ||
@@ -16,0 +16,0 @@ <link rel="modulepreload" crossorigin href="/static/react-Buq45Vzz.js"> |
+24
-0
@@ -163,2 +163,26 @@ # MCP server | ||
| ### What each tool declares | ||
| Every tool declares its full contract, so a caller never has to infer one: | ||
| - **Every input property carries a `description`.** Names do not survive | ||
| inference — `scope` is filesystem paths on a card and subject matter on a | ||
| document, and `source` is provenance on both while meaning different things. | ||
| - **Closed vocabularies declare `enum`.** Card `status`, `type`, `priority` and | ||
| `effort` come from frozen protocol constants, so they are enumerated in the | ||
| schema itself. Areas, document kinds, changelog types and memory statuses are | ||
| declared per project and accept any string, so they are *not* enumerated — | ||
| their descriptions point at `project_workspace`, which reports what this | ||
| project actually accepts. | ||
| - **Defaults are declared where the implementation has one**, rather than left | ||
| for the caller to discover by omitting the field. | ||
| - **Every tool declares an `outputSchema`** matching the `structuredContent` it | ||
| returns. None of them is a closed object: a payload over `maxToolResultBytes` | ||
| gains a `truncated` marker, and a schema that forbade it would invalidate the | ||
| server's own degradation path. | ||
| `project_card_release` is the one place where an enum is narrower than the | ||
| protocol's: a released card cannot stay `doing`, so that value is refused as an | ||
| explicit target and omitted from the schema. | ||
| ## Resources and prompts | ||
@@ -165,0 +189,0 @@ |
+1
-1
| { | ||
| "name": "@illodev/workfile", | ||
| "version": "0.5.3", | ||
| "version": "0.5.4", | ||
| "type": "module", | ||
@@ -5,0 +5,0 @@ "mcpName": "io.github.illodev/workfile", |
| import{n as e}from"./rolldown-runtime-CbXtAM7H.js";import{i as t,t as n}from"./react-Buq45Vzz.js";import{_t as r,mt as i,pt as a,rt as o}from"./ui-primitives-wYj92QGw.js";import{a as s,f as c,i as l,m as u,o as d,p as f,r as p,s as m,t as h,u as g}from"./empty-BHqXimMR.js";import{A as _,G as v,Q as y,U as b,X as x,Y as S,Z as C,j as w,n as T,q as E,r as D,t as O}from"./index-F1UmdPYw.js";var k=e(t(),1),A=n(),j=[];function M(e,t){let[n,r]=(0,k.useState)(t);(0,k.useEffect)(()=>{r(t)},[e.length,t]);let i=(0,k.useCallback)(()=>r(n=>Math.min(n+t,e.length)),[e.length,t]);return[n>=e.length?e:e.slice(0,n),n<e.length,i]}function N({onVisible:e,remaining:t}){let n=(0,k.useRef)(null);return(0,k.useEffect)(()=>{let t=n.current;if(!t)return;let r=new IntersectionObserver(t=>{t.some(e=>e.isIntersecting)&&e()},{rootMargin:`600px 0px`});return r.observe(t),()=>r.disconnect()},[e,t]),(0,A.jsxs)(`span`,{ref:n,className:`px-0.5 py-1 font-mono text-[11px] text-muted-foreground`,children:[`+`,t,` more`]})}function P({task:e,epicId:t,onOpen:n,onDragStart:r,onCarry:i,carrying:a}){let o=e.claimed_at?Date.parse(e.claimed_at.includes(`T`)?e.claimed_at:`${e.claimed_at}T00:00:00`):NaN,s=Number.isNaN(o)?null:Math.max(0,Math.floor((Date.now()-o)/864e5)),l=[t&&t!==e.id?`epic ${t}`:``,e.effort?`effort ${e.effort}`:``,e.claimed_by?`claimed by ${e.claimed_by}${s==null?``:` · ${s}d`}`:``].filter(Boolean);return(0,A.jsxs)(`article`,{className:u(`flex cursor-pointer flex-col gap-1.5 rounded-lg border bg-background px-3 py-2.5 shadow-xs outline-none transition-[color,border-color,box-shadow] hover:border-ring focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50`,a&&`border-ring ring-2 ring-ring`),tabIndex:0,draggable:!!r,"aria-grabbed":i?!!a:void 0,title:l.length?l.join(` · `):void 0,onClick:()=>n(e.id),onKeyDown:t=>{t.key===`Enter`?(t.preventDefault(),n(e.id)):t.key===` `&&i?(t.preventDefault(),i()):t.key===` `&&(t.preventDefault(),n(e.id))},onDragStart:r,children:[(0,A.jsxs)(`span`,{className:`flex items-center`,children:[(0,A.jsx)(`span`,{className:`font-mono text-[11px] text-foreground/70`,children:e.id}),(0,A.jsx)(`span`,{className:`flex-1`}),(0,A.jsx)(`span`,{className:`font-mono text-[10px] font-medium`,style:{color:m(e.priority)},children:e.priority})]}),(0,A.jsx)(`span`,{className:`text-[12.5px] leading-snug font-medium`,role:`heading`,"aria-level":3,children:e.title}),(0,A.jsxs)(`span`,{className:`flex items-center gap-1.5 font-mono text-[10px] text-muted-foreground`,children:[(0,A.jsx)(`span`,{children:e.area}),(0,A.jsx)(`span`,{children:`·`}),(0,A.jsx)(`span`,{children:e.type}),e.claimed_by?(0,A.jsxs)(`span`,{className:`ml-auto inline-flex min-w-0 items-center gap-[5px]`,style:{color:c(`doing`)},children:[(0,A.jsx)(`span`,{className:`size-[5px] flex-none rounded-full bg-current`,"aria-hidden":`true`}),(0,A.jsx)(`span`,{className:`max-w-[90px] truncate`,children:e.claimed_by})]}):null]}),Array.isArray(e.scope)&&e.scope.length?(0,A.jsxs)(`span`,{className:`mt-0.5 truncate border-t border-dashed pt-1.5 font-mono text-[10.5px] text-muted-foreground`,children:[`scope `,e.scope.join(` · `)]}):null]})}function F({status:e,cards:t,epicIds:n,collapsed:r,onToggleCollapsed:m,onOpen:g,onMove:v,onCarry:b,carryingId:x,isDropTarget:S,onDragEnterColumn:C,onDragLeaveColumn:T}){let[E,D,O]=M(t,25),k=c(e),j={onDragOver:t=>{t.preventDefault(),t.dataTransfer.dropEffect=`move`,C?.(e)},onDragLeave:t=>{t.currentTarget.contains(t.relatedTarget)||T?.(e)},onDrop:t=>{t.preventDefault(),T?.(e);let n=t.dataTransfer.getData(`text/plain`);n&&v(n,e).catch(()=>void 0)}};return r?(0,A.jsxs)(w,{role:`region`,"aria-label":`${e}, ${t.length} cards, collapsed`,className:u(`relative w-11 flex-none gap-0 overflow-hidden rounded-lg py-0 shadow-xs`,S&&`border-primary`),...j,children:[(0,A.jsx)(_,{edge:`top`,color:k}),(0,A.jsxs)(`button`,{type:`button`,"aria-expanded":!1,"aria-label":`Expand the ${e} column`,title:`${e} · ${t.length}`,className:u(`flex h-full w-full cursor-pointer flex-col items-center gap-2.5 px-1 pt-4 pb-3 transition-colors hover:bg-accent/50`,S&&`bg-accent/50`),onClick:m,children:[(0,A.jsx)(i,{"aria-hidden":`true`,className:`size-3.5 shrink-0 text-muted-foreground`}),(0,A.jsx)(`span`,{className:`min-h-0 flex-1 truncate font-mono text-[11px] uppercase tracking-[0.06em] [writing-mode:vertical-rl]`,style:{color:k},children:e}),(0,A.jsx)(y,{variant:`secondary`,className:`h-5 shrink-0 rounded-md px-[7px] font-mono text-[11px] font-normal`,children:t.length})]})]}):(0,A.jsxs)(w,{role:`region`,"aria-label":`${e}, ${t.length} cards`,className:u(`relative w-[268px] flex-none gap-0 overflow-hidden rounded-lg py-0 shadow-xs`,S&&`border-primary`),...j,children:[(0,A.jsx)(_,{edge:`top`,color:k}),(0,A.jsxs)(`header`,{className:`flex flex-none items-center gap-2 px-3 pb-2.5 pt-4`,children:[(0,A.jsx)(`span`,{className:`flex-1 font-mono text-[11px] uppercase tracking-[0.06em]`,style:{color:k},children:e}),(0,A.jsx)(y,{variant:`secondary`,className:`h-5 rounded-md px-[7px] font-mono text-[11px] font-normal`,children:t.length}),m?(0,A.jsx)(f,{type:`button`,variant:`ghost`,size:`icon-xs`,"aria-expanded":!0,"aria-label":`Collapse the ${e} column`,title:`Collapse column`,className:`-mr-1 text-muted-foreground`,onClick:m,children:(0,A.jsx)(a,{"aria-hidden":`true`})}):null]}),(0,A.jsxs)(`div`,{className:u(`scroll-fade flex flex-1 flex-col gap-2 overflow-y-auto p-2.5`,S&&`bg-accent/50`),children:[t.length===0?(0,A.jsx)(h,{className:`flex-1 gap-2 rounded-lg border border-dashed p-4`,children:(0,A.jsxs)(l,{className:`gap-1`,children:[(0,A.jsx)(s,{variant:`icon`,className:`mb-0 size-8 [&_svg:not([class*='size-'])]:size-4`,children:(0,A.jsx)(o,{"aria-hidden":`true`})}),(0,A.jsx)(d,{className:`text-[12.5px] font-medium`,children:`No cards`}),(0,A.jsx)(p,{className:`text-[11.5px]`,children:`Nothing in this state.`})]})}):E.map(e=>(0,A.jsx)(P,{task:e,epicId:n.get(e.id),onOpen:g,onCarry:b?()=>b(e):void 0,carrying:x===e.id,onDragStart:t=>{t.dataTransfer.effectAllowed=`move`,t.dataTransfer.setData(`text/plain`,e.id)}},e.id)),D&&(0,A.jsx)(N,{onVisible:O,remaining:t.length-E.length})]})]})}function I({tasks:e,epicIds:t,showClosed:n,onOpen:r,onMove:i}){let[a,o]=(0,k.useState)(null),[s,c]=(0,k.useState)(null),[l,u]=(0,k.useState)(``),[d,f]=(0,k.useState)(()=>{try{let e=localStorage.getItem(`workfile-flow-collapsed`);return new Set(e?JSON.parse(e):[])}catch{return new Set}}),p=(0,k.useCallback)(e=>{f(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),localStorage.setItem(`workfile-flow-collapsed`,JSON.stringify([...n])),n})},[]),m=(0,k.useMemo)(()=>[`backlog`,`next`,`doing`,`review`,`blocked`,`deferred`,...n?[`done`,`discarded`]:[]],[n]),h=(0,k.useMemo)(()=>{let t=new Map;for(let n of e){let e=t.get(n.status);e?e.push(n):t.set(n.status,[n])}return t},[e]),g=e=>{o({id:e.id,status:e.status}),u(`${e.id} picked up from ${e.status}. Use the arrow keys to choose a column, space to drop, escape to cancel.`)},_=e=>{if(!a)return;let t=m.indexOf(a.status),n=m[Math.min(m.length-1,Math.max(0,t+e))];!n||n===a.status||(o({...a,status:n}),u(`${a.id} over ${n}.`))},v=async()=>{if(!a)return;let t=a;o(null);let n=e.find(e=>e.id===t.id);n&&n.status!==t.status?(await i(t.id,t.status),u(`${t.id} moved to ${t.status}.`)):u(`${t.id} put back.`)};return(0,A.jsxs)(`div`,{className:`flex min-h-0 flex-1 gap-3 overflow-x-auto p-3.5`,onDragEnd:()=>c(null),onKeyDown:e=>{a&&(e.key===`Escape`?(e.preventDefault(),o(null),u(`Move cancelled.`)):e.key===`ArrowRight`?(e.preventDefault(),_(1)):e.key===`ArrowLeft`?(e.preventDefault(),_(-1)):(e.key===` `||e.key===`Enter`)&&(e.preventDefault(),v()))},children:[(0,A.jsx)(`p`,{className:`sr-only`,role:`status`,"aria-live":`polite`,children:l}),m.map(e=>(0,A.jsx)(F,{status:e,cards:h.get(e)??j,epicIds:t,collapsed:d.has(e),onToggleCollapsed:()=>p(e),onOpen:r,onMove:i,onCarry:g,carryingId:a?.id??null,isDropTarget:a?.status===e||s===e,onDragEnterColumn:c,onDragLeaveColumn:e=>c(t=>t===e?null:t)},e))]})}function L({tasks:e,allTasks:t,epicIds:n,onOpen:r}){let i=(0,k.useMemo)(()=>new Map(t.map(e=>[e.id,e])),[t]),a=(0,k.useMemo)(()=>{let t=new Map;for(let r of e){let e=n.get(r.id)||(r.type===`epic`?r.id:`__none`);t.has(e)||t.set(e,[]),r.id!==e&&t.get(e)?.push(r)}return[...t].sort(([e],[t])=>e===`__none`?1:t===`__none`?-1:e.localeCompare(t,void 0,{numeric:!0}))},[n,e]);return a.length?(0,A.jsx)(`div`,{className:`flex-1 overflow-y-auto p-3.5`,children:(0,A.jsx)(`div`,{className:`flex flex-col gap-2.5`,children:a.map(([e,t])=>{let n=i.get(e),a=t.length,o=t.filter(e=>e.status===`done`||e.status===`discarded`).length,s=t.filter(e=>e.status===`doing`).length,l=a-o-s,d=e=>a?`${e/a*100}%`:`0%`,f=[{label:`${o} done`,color:c(`done`)},{label:`${s} doing`,color:c(`doing`)},{label:`${l} open`,color:null}],p=(0,A.jsxs)(A.Fragment,{children:[(0,A.jsxs)(`span`,{className:`flex min-w-0 items-center gap-2.5`,children:[(0,A.jsx)(`span`,{className:`font-mono text-[11.5px] text-foreground/70`,children:e===`__none`?`—`:e}),(0,A.jsx)(`span`,{className:`min-w-0 flex-1 text-sm font-semibold tracking-[-0.01em] text-pretty`,children:n?.title||`Without epic`}),n?(0,A.jsx)(`span`,{className:`font-mono text-[11px]`,style:{color:c(n.status)},children:n.status}):null,(0,A.jsxs)(`span`,{className:`font-mono text-[11.5px] text-muted-foreground`,children:[o,`/`,a]})]}),(0,A.jsx)(`span`,{className:`flex h-2 w-full overflow-hidden rounded-full bg-muted`,"aria-hidden":`true`,children:a>0?(0,A.jsxs)(A.Fragment,{children:[(0,A.jsx)(`span`,{className:`h-full`,style:{width:d(o),background:c(`done`)}}),(0,A.jsx)(`span`,{className:`h-full`,style:{width:d(s),background:c(`doing`)}})]}):null}),(0,A.jsxs)(`span`,{className:`flex flex-wrap items-center gap-3.5 font-mono text-[10.5px] text-muted-foreground`,children:[f.map(e=>(0,A.jsxs)(`span`,{className:`inline-flex items-center gap-[5px]`,children:[(0,A.jsx)(`span`,{className:u(`size-1.5 rounded-[2px]`,!e.color&&`bg-muted-foreground`),style:e.color?{background:e.color}:void 0,"aria-hidden":`true`}),e.label]},e.label)),(0,A.jsx)(`span`,{className:`ml-auto`,children:n?.area??``})]})]});return n?(0,A.jsx)(`button`,{type:`button`,className:`flex w-full cursor-pointer flex-col gap-2.5 rounded-xl border bg-card px-4 py-3.5 text-left text-card-foreground shadow-xs outline-none transition-[color,border-color,box-shadow] hover:border-ring focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50`,onClick:()=>r(e),children:p},e):(0,A.jsx)(w,{className:`gap-2.5 rounded-xl px-4 py-3.5 shadow-xs`,children:p},e)})})}):(0,A.jsx)(h,{className:`flex-1 p-6`,children:(0,A.jsxs)(l,{children:[(0,A.jsx)(d,{className:`text-sm`,children:`No epics`}),(0,A.jsx)(p,{className:`text-[11.5px]`,children:`No cards match the current filters.`})]})})}var R=300,z=30;function B({task:e,span:t,mode:n,epicId:r,pct:i,labelWidth:a,onOpen:o}){let s=c(e.status);return(0,A.jsxs)(`button`,{type:`button`,onClick:()=>o(e.id),title:`${D(e,n,t)} · ${e.status}${r&&r!==e.id?` · epic ${r}`:``}`,className:`flex w-full cursor-pointer items-center border-b bg-transparent p-0 text-left transition-colors hover:bg-muted`,children:[(0,A.jsxs)(`span`,{className:`flex min-w-0 items-center gap-2 border-r px-3.5`,style:{width:a,flex:`0 0 ${a}px`,height:`var(--row-h)`},children:[(0,A.jsx)(`span`,{className:`flex-none whitespace-nowrap font-mono text-[11px] text-foreground/70`,children:e.id}),(0,A.jsx)(`span`,{className:`min-w-0 truncate text-[12.5px]`,children:e.title})]}),(0,A.jsx)(`span`,{className:`relative block flex-1`,style:{height:`var(--row-h)`},children:t.point?(0,A.jsx)(`span`,{style:{position:`absolute`,top:`50%`,width:9,height:9,transform:`translate(-50%, -50%) rotate(45deg)`,borderRadius:2,background:s,display:`block`,left:`${i(t.from)}%`}}):(0,A.jsx)(`span`,{style:{position:`absolute`,top:`50%`,transform:`translateY(-50%)`,height:12,minWidth:6,borderRadius:3,background:s,display:`block`,left:`${i(t.from)}%`,width:`${Math.max(i(t.to)-i(t.from),.8)}%`}})})]})}function V({tasks:e,epicIds:t,axes:n={},mode:i,counts:a,onModeChange:o,onOpen:s}){let c=b()?168:R,u=c+460,[m,_]=(0,k.useState)(()=>{try{return localStorage.getItem(`workfile-timeline-group`)||`none`}catch{return`none`}}),y=(0,k.useCallback)(e=>{_(e);try{localStorage.setItem(`workfile-timeline-group`,e)}catch{}},[]),w=(0,k.useMemo)(()=>[`none`,`epic`,`area`,...Object.keys(n)],[n]),D=w.includes(m)?m:`none`,j=(0,k.useCallback)(e=>{if(D===`epic`)return t.get(e.id)||``;if(D===`area`)return e.area||``;let n=e[D];return typeof n==`string`?n:``},[t,D]),M=(0,k.useMemo)(()=>{let t=new Map;for(let n of e){let e=T(n,i);e&&t.set(n.id,e)}return t},[i,e]),N=(0,k.useMemo)(()=>{let t=(e,t)=>M.get(e.id).from-M.get(t.id).from||e.id.localeCompare(t.id),n=e.filter(e=>M.has(e.id)).sort(t);return D===`none`?n:[...n].sort((e,n)=>{let r=j(e),i=j(n);return!r==!i?r.localeCompare(i)||t(e,n):r?-1:1})},[j,D,M,e]),P=(0,k.useMemo)(()=>{if(D===`none`)return N.map(e=>({task:e,label:null}));let e=[],t=null;for(let n of N){let r=j(n);r!==t&&(t=r,e.push({task:null,label:r||`no ${D}`})),e.push({task:n,label:null})}return e},[j,D,N]),F=(0,k.useMemo)(()=>new Map(P.flatMap((e,t)=>e.task?[[e.task.id,t]]:[])),[P]),I=(0,k.useMemo)(()=>{let e=[];for(let t of N)for(let n of t.depends||[])F.has(n)&&e.push({from:n,to:t.id});return e},[F,N]),L=(0,k.useMemo)(()=>O(N.map(e=>M.get(e.id)),Date.now()),[N,M]),V=a[i===`plan`?`actual`:`plan`];return!N.length||!L?(0,A.jsx)(h,{className:`flex-1 p-6`,children:(0,A.jsxs)(l,{children:[(0,A.jsx)(d,{className:`text-sm`,children:i===`plan`?`Nothing scheduled`:`Nothing recorded`}),(0,A.jsx)(p,{className:`text-[11.5px]`,children:i===`plan`?`Add a start or due date to a card.`:`Cards record a trail as they are claimed and moved.`}),V>0?(0,A.jsx)(p,{className:`text-[11.5px]`,children:(0,A.jsx)(f,{variant:`outline`,size:`sm`,className:`mt-2 text-[12.5px] font-medium`,onClick:()=>o(i===`plan`?`actual`:`plan`),children:i===`plan`?`show what actually happened · ${V} cards`:`show the schedule · ${V} cards`})}):null]})}):(0,A.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col`,children:[(0,A.jsxs)(`div`,{className:`no-scrollbar flex flex-none items-center gap-2.5 overflow-x-auto border-b bg-card px-3.5 py-2`,children:[(0,A.jsxs)(`span`,{className:`shrink-0 font-mono text-[11px] whitespace-nowrap text-muted-foreground`,children:[N.length,` `,i===`actual`?`recorded`:`scheduled`,` ·`,` `,I.length,` dependenc`,I.length===1?`y`:`ies`]}),(0,A.jsxs)(v,{children:[(0,A.jsx)(C,{asChild:!0,children:(0,A.jsxs)(f,{variant:`outline`,size:`sm`,"aria-label":`dates`,className:`ml-auto shrink-0 text-[12.5px] font-medium`,children:[`dates`,(0,A.jsx)(`span`,{className:`font-normal text-muted-foreground`,children:i}),(0,A.jsx)(r,{className:`size-[13px] text-muted-foreground`})]})}),(0,A.jsx)(E,{align:`end`,children:(0,A.jsxs)(S,{value:i,onValueChange:e=>o(e),children:[(0,A.jsx)(x,{value:`plan`,children:`plan`}),(0,A.jsx)(x,{value:`actual`,children:`actual`})]})})]}),(0,A.jsxs)(v,{children:[(0,A.jsx)(C,{asChild:!0,children:(0,A.jsxs)(f,{variant:`outline`,size:`sm`,"aria-label":`group`,className:`shrink-0 text-[12.5px] font-medium`,children:[`group`,(0,A.jsx)(`span`,{className:`font-normal text-muted-foreground`,children:D}),(0,A.jsx)(r,{className:`size-[13px] text-muted-foreground`})]})}),(0,A.jsx)(E,{align:`end`,children:(0,A.jsx)(S,{value:D,onValueChange:y,children:w.map(e=>(0,A.jsx)(x,{value:e,children:e},e))})})]})]}),(0,A.jsx)(`div`,{className:`min-h-0 flex-1 overflow-auto`,children:(0,A.jsxs)(`div`,{className:`relative min-h-full`,style:{minWidth:u},children:[(0,A.jsxs)(`div`,{"aria-hidden":`true`,className:`sticky top-0 z-[2] flex items-stretch border-b bg-card`,style:{height:z},children:[(0,A.jsx)(`span`,{className:`flex items-center border-r px-3.5 text-[10px] uppercase tracking-[0.08em] text-muted-foreground`,style:{width:c,flex:`0 0 ${c}px`},children:`card`}),(0,A.jsx)(`span`,{className:`relative flex-1`,children:L.ticks.map((e,t)=>(0,A.jsx)(`span`,{className:`text-[10px] uppercase tracking-[0.08em] text-muted-foreground`,style:{position:`absolute`,top:`50%`,transform:`translateY(-50%)`,left:`${e.left}%`,width:`${(L.ticks[t+1]?.left??100)-e.left}%`,overflow:`hidden`,paddingLeft:8,whiteSpace:`nowrap`},children:e.label},e.key))})]}),(0,A.jsxs)(`div`,{"aria-hidden":`true`,className:`pointer-events-none absolute`,style:{top:z,bottom:0,left:c,right:0},children:[L.ticks.map(e=>(0,A.jsx)(`span`,{className:`absolute inset-y-0 w-px bg-border`,style:{left:`${e.left}%`}},e.key)),L.today!=null&&(0,A.jsx)(`span`,{className:`absolute inset-y-0 w-px`,style:{background:g(`error`),opacity:.55,left:`${L.today}%`}})]}),(0,A.jsxs)(`div`,{className:`relative`,children:[I.length>0&&(0,A.jsx)(`svg`,{"aria-hidden":`true`,preserveAspectRatio:`none`,viewBox:`0 0 100 ${P.length}`,className:`pointer-events-none absolute top-0 h-full`,style:{left:c,width:`calc(100% - ${c}px)`},children:I.map(e=>{let t=M.get(e.from),n=M.get(e.to);if(!t||!n)return null;let r=L.pct(t.to),i=L.pct(n.from),a=F.get(e.from)+.5,o=F.get(e.to)+.5;return(0,A.jsx)(`path`,{d:`M ${r} ${a} C ${(r+i)/2} ${a}, ${(r+i)/2} ${o}, ${i} ${o}`,vectorEffect:`non-scaling-stroke`,style:i<r?{fill:`none`,stroke:g(`error`),strokeWidth:1.5,strokeDasharray:`3 2`}:{fill:`none`,stroke:`var(--muted-foreground)`,strokeWidth:1.5,opacity:.4}},`${e.from}-${e.to}`)})}),P.map((e,n)=>e.task?(0,A.jsx)(B,{task:e.task,span:M.get(e.task.id),mode:i,epicId:t.get(e.task.id),pct:L.pct,labelWidth:c,onOpen:s},e.task.id):(0,A.jsx)(`div`,{className:`border-b bg-muted/40`,children:(0,A.jsx)(`span`,{className:`flex items-center px-3.5 text-[10px] uppercase tracking-[0.08em] text-muted-foreground`,style:{height:`var(--row-h)`},children:e.label})},`group-${n}-${e.label}`))]})]})})]})}export{L as EpicsView,I as FlowBoard,V as TimelineView}; |
| import{n as e}from"./rolldown-runtime-CbXtAM7H.js";import{i as t,t as n}from"./react-Buq45Vzz.js";import{F as r,V as i,gt as ee,q as te,st as a,z as o}from"./ui-primitives-wYj92QGw.js";import{i as ne,l as s,m as c,o as re,p as l,r as ie,t as ae}from"./empty-BHqXimMR.js";import{n as u,t as d}from"./native-select-NN1SzVJL.js";import{$ as f,C as p,E as m,H as h,I as g,O as oe,Q as _,S as se,T as ce,U as le,_ as ue,b as v,c as de,d as fe,et as y,f as pe,g as me,h as he,k as ge,l as _e,p as ve,v as b,x as ye,y as x}from"./index-F1UmdPYw.js";import{t as be}from"./layout-QiuZ_k5v.js";var S=e(t(),1),C=n(),w=`doc-h`,xe=[`current`,`draft`,`superseded`,`archived`],T=`text-[10px] font-medium tracking-[0.07em] uppercase text-muted-foreground`;function Se({document:e,selected:t,onSelect:n}){return(0,C.jsx)(m,{asChild:!0,size:`sm`,className:c(`w-full cursor-pointer flex-col items-start gap-0.5 px-2 py-1.5 text-left hover:bg-accent`,t&&`bg-accent`),children:(0,C.jsxs)(`button`,{type:`button`,"aria-current":t?`true`:void 0,onClick:n,children:[(0,C.jsxs)(`span`,{className:`flex w-full items-center gap-1.5`,children:[(0,C.jsx)(`span`,{className:`flex-1 truncate text-xs font-medium`,children:e.title}),(0,C.jsx)(`span`,{className:c(`font-mono text-[10px]`,!e.managed&&`text-muted-foreground`),style:e.managed?{color:s(e.status)}:void 0,children:e.managed?e.status:`indexed`})]}),(0,C.jsx)(`span`,{className:`w-full truncate font-mono text-[10px] text-muted-foreground`,children:e.path})]})})}function Ce({entries:e,activeId:t,onJump:n}){let r=Math.min(...e.map(e=>e.level));return(0,C.jsxs)(`aside`,{"aria-label":`Document outline`,className:`hidden w-[228px] shrink-0 overflow-y-auto border-l px-3 py-6.5 xl:block`,children:[(0,C.jsx)(`span`,{className:c(T,`px-2`),children:`on this page`}),(0,C.jsx)(`nav`,{className:`mt-2 flex flex-col gap-px`,children:e.map(e=>{let i=e.id===t;return(0,C.jsx)(`button`,{type:`button`,"aria-current":i?`true`:void 0,className:c(`cursor-pointer rounded-md px-2 py-1 text-left text-xs leading-snug transition-colors hover:bg-accent`,i?`bg-accent font-medium text-foreground`:`text-muted-foreground`),style:{paddingLeft:`${8+Math.min(e.level-r,3)*12}px`},onClick:()=>n(e.id),children:e.text},e.id)})})]})}function E({label:e,value:t}){return(0,C.jsxs)(b,{className:`w-auto min-w-[120px] gap-0.5 rounded-lg border bg-card px-3 py-2 shadow-xs`,children:[(0,C.jsx)(`span`,{className:T,children:e}),(0,C.jsx)(`span`,{className:`text-[13px] font-medium`,children:t})]})}function D({label:e,links:t,onOpen:n}){return t.length?(0,C.jsxs)(`section`,{className:`flex flex-col gap-1.5`,children:[(0,C.jsx)(`span`,{className:T,children:e}),t.map((e,t)=>{let r=!e.exists&&!e.title;return(0,C.jsx)(m,{asChild:!0,variant:`outline`,size:`sm`,className:c(`w-full cursor-pointer gap-2 px-2.5 py-2 text-left hover:bg-accent`,r&&`cursor-default opacity-55 hover:bg-transparent`),children:(0,C.jsxs)(`button`,{type:`button`,disabled:r,onClick:()=>n(e.id),children:[(0,C.jsx)(`span`,{className:`min-w-[78px] shrink-0 font-mono text-[11px] font-medium`,children:e.id}),(0,C.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-xs text-muted-foreground`,children:e.title||(e.exists===!1?`Missing record`:e.id)}),e.relation?(0,C.jsx)(_,{variant:`secondary`,className:`font-mono text-[10px]`,children:e.relation}):null]})},`${e.id}-${t}`)})]}):null}var O=(0,C.jsx)(`span`,{"aria-hidden":`true`,className:`text-muted-foreground`,children:`·`});function k({selectedId:e,onSelect:t,onOpenCard:n}){let[m,_]=(0,S.useState)([]),[k,A]=(0,S.useState)(``),[j,M]=(0,S.useState)(!0),[N,P]=(0,S.useState)(``),[F,I]=(0,S.useState)(!1),[L,we]=(0,S.useState)(!1),[R,z]=(0,S.useState)(null),[B,V]=(0,S.useState)(!1),[H,U]=(0,S.useState)(``),[W,Te]=(0,S.useState)(null),[Ee,G]=(0,S.useState)(0);ge(e=>{oe(e,`/docs/`,`docs/`)&&G(e=>e+1)}),(0,S.useEffect)(()=>{let e=!1;M(!0);let t=window.setTimeout(()=>{g.docs(k.trim()).then(t=>{e||(_(t.records),P(``))}).catch(t=>{e||P(t instanceof Error?t.message:String(t))}).finally(()=>{e||M(!1)})},k?180:0);return()=>{e=!0,window.clearTimeout(t)}},[k,Ee]),(0,S.useEffect)(()=>{if(!R||W)return;let e=!1;return g.tasks().then(t=>{e||Te(t.schema.docs)}).catch(()=>{}),()=>{e=!0}},[R,W]);let K=(0,S.useMemo)(()=>F?m.filter(e=>e.managed):m,[m,F]),q=(0,S.useMemo)(()=>{let e=K.filter(e=>e.managed),t=K.filter(e=>!e.managed);return[{key:`managed`,label:`.project/docs · managed`,docs:e},{key:`indexed`,label:`indexed · read only`,docs:t}].filter(e=>e.docs.length>0)},[K]),De=le(),J=K.find(t=>t.id===e)||(De?void 0:K[0]),Y=(0,S.useRef)(null),[Oe,X]=(0,S.useState)(``),Z=(0,S.useMemo)(()=>J&&!L?se(J.body,w):[],[J,L]),Q=Z.length>1;(0,S.useEffect)(()=>{X(``);let e=Y.current;if(!e||!Q)return;let t=new Map,n=new IntersectionObserver(e=>{for(let n of e)t.set(n.target.id,n.isIntersecting);let n=Z.find(e=>t.get(e.id));n&&X(n.id)},{root:e,rootMargin:`0px 0px -66% 0px`,threshold:0});for(let e of Z){let t=document.getElementById(e.id);t&&n.observe(t)}return()=>n.disconnect()},[Z,Q]);let ke=e=>{document.getElementById(e)?.scrollIntoView({block:`start`,behavior:`smooth`}),X(e)},$=e=>{let r=m.find(t=>t.id===e);r?t(r.id):n(e)},Ae=(0,S.useMemo)(()=>{let e=new Set(W?.kinds??[]);for(let t of m)t.managed&&e.add(t.documentKind);return R&&e.add(R.kind),[...e].sort()},[W,m,R]),je=(0,S.useMemo)(()=>{let e=new Set(W?.statuses??xe);for(let t of m)t.managed&&e.add(t.status);return R&&e.add(R.status),[...e].sort()},[W,m,R]);function Me(e){U(``),z({id:e.id,title:e.title,kind:e.documentKind,status:e.status,owners:(e.owners??[]).join(`, `),reviewed:e.reviewed??``})}async function Ne(){if(!R)return;let e=m.find(e=>e.id===R.id);if(!e){U(`This document no longer exists in the workspace.`);return}let t=R.owners.split(`,`).map(e=>e.trim()).filter(Boolean),n={},r=R.title.trim();if(r&&r!==e.title&&(n.title=r),R.kind!==e.documentKind&&(n.kind=R.kind),R.status!==e.status&&(n.status=R.status),t.join(` | ||
| `)!==(e.owners??[]).join(` | ||
| `)&&(n.owners=t),(R.reviewed||``)!==(e.reviewed??``)&&(n.reviewed=R.reviewed||null),!Object.keys(n).length){z(null);return}V(!0),U(``);try{let t=await g.patchDocument(e.id,n,e.revision);_(n=>n.map(n=>n.id===e.id?t.record:n)),z(null)}catch(e){let t=e;t.code?.endsWith(`WRITE_CONFLICT`)?(G(e=>e+1),U(`The document changed on disk; the list was refreshed. Save again to apply your changes to the latest revision.`)):U(t.message||String(e))}finally{V(!1)}}return(0,C.jsxs)(`div`,{className:`flex min-h-0 flex-1`,children:[(0,C.jsxs)(`aside`,{"aria-label":`Documents`,className:c(`min-h-0 w-full shrink-0 flex-col border-r px-2 py-3 lg:flex lg:w-[290px]`,J?`hidden`:`flex`),children:[(0,C.jsxs)(`div`,{className:`flex flex-col gap-2 pb-2.5`,children:[(0,C.jsxs)(he,{className:`h-8`,children:[(0,C.jsx)(me,{children:(0,C.jsx)(i,{"aria-hidden":`true`})}),(0,C.jsx)(ue,{className:`h-8`,type:`search`,value:k,"aria-label":`Search documentation`,placeholder:`Search documentation…`,onChange:e=>A(e.target.value)})]}),(0,C.jsx)(`div`,{className:`flex gap-1.5`,children:(0,C.jsxs)(l,{type:`button`,variant:`outline`,size:`sm`,"aria-pressed":F,className:c(`h-7 gap-1.5 px-2.5 text-xs`,F&&`border-ring bg-accent`),onClick:()=>I(!F),children:[`managed`,(0,C.jsx)(`span`,{className:`font-normal text-muted-foreground`,children:F?`only`:`all`})]})})]}),(0,C.jsx)(`div`,{"aria-busy":j||void 0,className:`min-h-0 flex-1 overflow-y-auto`,children:j?(0,C.jsxs)(`span`,{className:`flex items-center gap-2 px-2 py-1.5 font-mono text-[10.5px] text-muted-foreground`,children:[(0,C.jsx)(ce,{className:`size-3`}),`Loading documents…`]}):N?(0,C.jsx)(f,{variant:`destructive`,className:`mt-1.5`,children:(0,C.jsx)(y,{children:N})}):q.length?q.map(e=>(0,C.jsxs)(`div`,{className:`flex flex-col gap-px pb-3.5`,children:[(0,C.jsxs)(`span`,{className:`flex items-center gap-2 px-2 py-1.5 font-mono text-[10.5px] text-muted-foreground`,children:[(0,C.jsx)(`span`,{className:`text-foreground/80`,children:e.label}),(0,C.jsx)(`span`,{children:e.docs.length})]}),e.docs.map(e=>(0,C.jsx)(Se,{document:e,selected:J?.id===e.id,onSelect:()=>t(e.id)},e.id))]},e.key)):(0,C.jsx)(ae,{className:`gap-2 p-4 md:p-4`,children:(0,C.jsxs)(ne,{children:[(0,C.jsx)(re,{className:`text-sm`,children:`No documents found.`}),(0,C.jsx)(ie,{className:`text-xs`,children:F?`Try another search, or include indexed files.`:`Try another search.`})]})})})]}),(0,C.jsx)(`section`,{ref:Y,className:c(`min-w-0 flex-1 overflow-y-auto px-6 py-6.5 sm:px-8.5`,J?`block`:`hidden lg:block`),children:(0,C.jsx)(`div`,{className:be,children:J?(0,C.jsxs)(C.Fragment,{children:[(0,C.jsxs)(l,{type:`button`,variant:`ghost`,size:`sm`,className:`-ml-2 mb-2 lg:hidden`,onClick:()=>t(``),children:[(0,C.jsx)(ee,{"aria-hidden":`true`}),`All documents`]}),(0,C.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2 font-mono text-[11px] text-muted-foreground`,children:[(0,C.jsx)(`span`,{children:J.id}),O,(0,C.jsx)(`span`,{children:J.documentKind}),O,(0,C.jsx)(`span`,{style:{color:s(J.status)},children:J.status}),O,(0,C.jsx)(`span`,{children:J.managed?`managed`:`indexed`}),(0,C.jsx)(`span`,{className:`flex-1`}),J.managed?(0,C.jsxs)(C.Fragment,{children:[(0,C.jsxs)(l,{type:`button`,variant:`outline`,size:`sm`,onClick:()=>we(e=>!e),children:[L?(0,C.jsx)(a,{"aria-hidden":`true`}):(0,C.jsx)(te,{"aria-hidden":`true`}),L?`Preview`:`Edit`]}),(0,C.jsxs)(l,{type:`button`,variant:`outline`,size:`sm`,onClick:()=>Me(J),children:[(0,C.jsx)(o,{"aria-hidden":`true`}),`Metadata`]})]}):null]}),(0,C.jsx)(`h2`,{className:`mt-3 mb-1.5 text-2xl font-semibold tracking-tight`,children:J.title}),(0,C.jsx)(`span`,{className:`font-mono text-[11px] text-muted-foreground [overflow-wrap:anywhere]`,children:J.path}),(0,C.jsxs)(`div`,{className:`mt-4.5 flex flex-wrap gap-2`,children:[(0,C.jsx)(E,{label:`kind`,value:J.documentKind}),(0,C.jsx)(E,{label:`status`,value:J.status}),(0,C.jsx)(E,{label:`reviewed`,value:J.reviewed||`—`}),(0,C.jsx)(E,{label:`owners`,value:J.owners?.join(`, `)||`—`}),(0,C.jsx)(E,{label:`backlinks`,value:String(J.incomingTotal??J.incoming.length)}),J.updated?(0,C.jsx)(E,{label:`updated`,value:J.updated}):null]}),J.freshness.length>0?(0,C.jsxs)(f,{role:`status`,className:`mt-4.5 max-w-2xl`,children:[(0,C.jsx)(r,{"aria-hidden":`true`,className:`text-sev-warning`}),(0,C.jsx)(y,{children:J.freshness.map(e=>(0,C.jsx)(`span`,{children:e.message},`${e.code}-${e.message}`))})]}):null,(0,C.jsx)(`div`,{className:`mt-6.5`,children:L&&J.managed?(0,C.jsx)(p,{value:J.body,revision:J.revision,onSave:async(e,t)=>{let n=await g.patchDocument(J.id,{body:e},t);_(e=>e.map(e=>e.id===J.id?n.record:e))}},J.id):J.body.trim()?(0,C.jsx)(ye,{source:J.body,headingPrefix:w,onOpen:$}):(0,C.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:J.managed?`This document is empty. Use Edit to write its first version.`:`This file has no body to render.`})}),J.outgoing.length||J.incoming.length||J.scope?.length?(0,C.jsxs)(`div`,{className:`mt-7 flex max-w-[70ch] flex-col gap-4.5`,children:[(0,C.jsx)(D,{label:`links to`,links:J.outgoing,onOpen:$}),(0,C.jsx)(D,{label:(J.incomingTotal??J.incoming.length)>J.incoming.length?`backlinks (${J.incoming.length} of ${J.incomingTotal})`:`backlinks`,links:J.incoming,onOpen:$}),J.scope?.length?(0,C.jsxs)(`section`,{className:`flex flex-col gap-1.5`,children:[(0,C.jsx)(`span`,{className:T,children:`scope`}),J.scope.map(e=>(0,C.jsx)(`span`,{className:`font-mono text-[10.5px] text-muted-foreground [overflow-wrap:anywhere]`,children:e},e))]}):null]}):null]}):(0,C.jsx)(`div`,{className:`flex h-full items-center justify-center text-xs text-muted-foreground`,children:j?`Loading documents…`:`Select a document from the list to read it.`})})}),Q?(0,C.jsx)(Ce,{entries:Z,activeId:Oe,onJump:ke}):null,(0,C.jsx)(de,{open:R!==null,onOpenChange:e=>{!e&&!B&&z(null)},children:(0,C.jsxs)(_e,{"aria-describedby":void 0,children:[(0,C.jsx)(pe,{children:(0,C.jsx)(ve,{children:`Edit metadata${R?` — ${R.id}`:``}`})}),R?(0,C.jsxs)(x,{className:`gap-4`,children:[(0,C.jsxs)(b,{children:[(0,C.jsx)(v,{htmlFor:`docs-meta-title`,children:`title`}),(0,C.jsx)(h,{id:`docs-meta-title`,value:R.title,onChange:e=>z({...R,title:e.target.value})})]}),(0,C.jsxs)(`div`,{className:`grid grid-cols-2 gap-2.5`,children:[(0,C.jsxs)(b,{className:`[&_[data-slot=native-select-wrapper]]:w-full`,children:[(0,C.jsx)(v,{htmlFor:`docs-meta-kind`,children:`kind`}),(0,C.jsx)(d,{id:`docs-meta-kind`,value:R.kind,onChange:e=>z({...R,kind:e.target.value}),children:Ae.map(e=>(0,C.jsx)(u,{value:e,children:e},e))})]}),(0,C.jsxs)(b,{className:`[&_[data-slot=native-select-wrapper]]:w-full`,children:[(0,C.jsx)(v,{htmlFor:`docs-meta-status`,children:`status`}),(0,C.jsx)(d,{id:`docs-meta-status`,value:R.status,onChange:e=>z({...R,status:e.target.value}),children:je.map(e=>(0,C.jsx)(u,{value:e,children:e},e))})]})]}),(0,C.jsxs)(`div`,{className:`grid grid-cols-2 gap-2.5`,children:[(0,C.jsxs)(b,{children:[(0,C.jsx)(v,{htmlFor:`docs-meta-owners`,children:`owners`}),(0,C.jsx)(h,{id:`docs-meta-owners`,value:R.owners,placeholder:`comma-separated`,onChange:e=>z({...R,owners:e.target.value})})]}),(0,C.jsxs)(b,{children:[(0,C.jsx)(v,{htmlFor:`docs-meta-reviewed`,children:`reviewed`}),(0,C.jsx)(h,{id:`docs-meta-reviewed`,type:`date`,value:R.reviewed,onChange:e=>z({...R,reviewed:e.target.value})})]})]}),H?(0,C.jsx)(f,{variant:`destructive`,children:(0,C.jsx)(y,{children:H})}):null]}):null,(0,C.jsxs)(fe,{children:[(0,C.jsx)(l,{type:`button`,variant:`outline`,disabled:B,onClick:()=>z(null),children:`Cancel`}),(0,C.jsx)(l,{type:`button`,disabled:B,onClick:()=>void Ne(),children:B?`Saving…`:`Save`})]})]})})]})}export{k as DocsView}; |
| import{n as e}from"./rolldown-runtime-CbXtAM7H.js";import{i as t,t as n}from"./react-Buq45Vzz.js";import{Ct as r,St as i,b as a,ft as o,vt as s,y as c,z as ee}from"./ui-primitives-wYj92QGw.js";import{f as l,i as te,m as u,o as ne,p as d,r as re,s as f,t as ie}from"./empty-BHqXimMR.js";import{n as p,t as m}from"./native-select-NN1SzVJL.js";import{B as ae,D as oe,L as se,R as ce,V as le,a as h,i as ue,o as g,s as de,z as fe}from"./index-F1UmdPYw.js";import{t as _}from"./progress-CKc41PRw.js";var v=e(t(),1),y=n();function b({className:e,...t}){return(0,y.jsx)(c,{"data-slot":`checkbox`,className:u(`peer size-4 shrink-0 rounded-[4px] border border-input shadow-xs transition-shadow outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:bg-input/30 dark:aria-invalid:ring-destructive/40 dark:data-[state=checked]:bg-primary`,e),...t,children:(0,y.jsx)(a,{"data-slot":`checkbox-indicator`,className:`grid place-content-center text-current transition-none`,children:(0,y.jsx)(s,{className:`size-3.5`})})})}function pe({className:e,...t}){return(0,y.jsx)(`div`,{"data-slot":`table-container`,className:`relative w-full overflow-x-auto`,children:(0,y.jsx)(`table`,{"data-slot":`table`,className:u(`w-full caption-bottom text-sm`,e),...t})})}function me({className:e,...t}){return(0,y.jsx)(`thead`,{"data-slot":`table-header`,className:u(`[&_tr]:border-b`,e),...t})}function he({className:e,...t}){return(0,y.jsx)(`tbody`,{"data-slot":`table-body`,className:u(`[&_tr:last-child]:border-0`,e),...t})}function x({className:e,...t}){return(0,y.jsx)(`tr`,{"data-slot":`table-row`,className:u(`border-b transition-colors hover:bg-muted/50 has-aria-expanded:bg-muted/50 data-[state=selected]:bg-muted`,e),...t})}function S({className:e,...t}){return(0,y.jsx)(`th`,{"data-slot":`table-head`,className:u(`h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]`,e),...t})}function C({className:e,...t}){return(0,y.jsx)(`td`,{"data-slot":`table-cell`,className:u(`p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]`,e),...t})}var w=[[`id`,`id`],[`title`,`title · claim`],[`status`,`status`],[`priority`,`prio`],[`type`,`type`],[`area`,`area`],[`epic`,`links`],[`updated`,`updated`]],T=new Map(h.map((e,t)=>[e,t])),E=new Map(g.map((e,t)=>[e,t])),D=w.length+1;function O(e,t){let n=new Map;for(let r of e){let e=r[t];typeof e==`string`&&n.set(e,(n.get(e)||0)+1)}return n}function k({title:e,values:t,counts:n,selected:r,color:i,onSelect:a}){let o=t.filter(e=>n.has(e));if(!o.length)return null;let s=Math.max(...o.map(e=>n.get(e)||0));return(0,y.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,y.jsx)(`span`,{className:`px-1.5 font-mono text-[10px] tracking-widest uppercase text-muted-foreground`,children:e}),o.map(e=>{let t=n.get(e)||0,o=r===e;return(0,y.jsxs)(`button`,{type:`button`,"aria-pressed":o,onClick:()=>a(o?``:e),className:u(`flex w-full cursor-pointer flex-col gap-1 rounded-md px-1.5 py-1 text-left transition-colors hover:bg-accent/50`,o&&`bg-accent`),children:[(0,y.jsxs)(`span`,{className:`flex w-full items-center gap-1.5`,children:[(0,y.jsx)(`span`,{className:u(`min-w-0 flex-1 truncate text-xs`,o?`font-medium text-foreground`:`text-muted-foreground`),children:e}),(0,y.jsx)(`span`,{className:`font-mono text-[11px] text-muted-foreground`,children:t})]}),(0,y.jsx)(_,{value:s?Math.round(t/s*100):0,className:u(`h-[5px] bg-muted [&>div]:bg-current`,!i&&`text-primary`),style:i?{color:i(e)}:void 0})]},e)})]})}function A({label:e,value:t,options:n,color:r,withDot:i,onChange:a}){return(0,y.jsxs)(`span`,{className:`inline-flex items-center gap-1.5`,style:{color:r},children:[i?(0,y.jsx)(`span`,{className:`size-1.5 shrink-0 rounded-full bg-current`,"aria-hidden":`true`}):null,(0,y.jsx)(m,{"aria-label":e,value:t,onChange:e=>a(e.target.value),className:`h-[22px] cursor-pointer border-transparent bg-transparent px-1 py-0 pr-8 font-mono text-[11px] text-inherit shadow-none dark:bg-transparent dark:hover:bg-transparent`,children:n.map(e=>(0,y.jsx)(p,{value:e,children:e},e))})]})}var ge=(0,v.memo)(function({task:e,epicId:t,checked:n,isOpen:r,onToggle:i,onOpen:a,onPatch:o}){let s=(e.depends?.length??0)+ +!!e.parent;return(0,y.jsxs)(x,{className:`h-[var(--row-h)] cursor-pointer`,"data-state":r?`selected`:void 0,tabIndex:0,onClick:()=>a(e.id),onKeyDown:t=>{t.key===`Enter`&&a(e.id)},children:[(0,y.jsx)(C,{className:u(`w-7 border-l-2 border-l-transparent`,r&&`border-l-primary`),onClick:e=>e.stopPropagation(),children:(0,y.jsx)(b,{"aria-label":`Select ${e.id}`,checked:n,onCheckedChange:()=>i(e.id)})}),(0,y.jsx)(C,{className:`font-mono text-xs text-muted-foreground`,children:e.id}),(0,y.jsx)(C,{className:`max-w-[520px]`,children:(0,y.jsxs)(`span`,{className:`flex min-w-0 items-baseline gap-2`,children:[(0,y.jsx)(`span`,{className:`min-w-0 truncate font-medium`,children:e.title}),e.claimed_by?(0,y.jsxs)(`span`,{className:`font-mono text-[10px] whitespace-nowrap text-muted-foreground/60`,children:[`· `,e.claimed_by]}):null]})}),(0,y.jsx)(C,{onClick:e=>e.stopPropagation(),children:(0,y.jsx)(A,{label:`Status for ${e.id}`,value:e.status,options:g,color:l(e.status),withDot:!0,onChange:t=>void o(e.id,{status:t}).catch(()=>void 0)})}),(0,y.jsx)(C,{onClick:e=>e.stopPropagation(),children:(0,y.jsx)(A,{label:`Priority for ${e.id}`,value:e.priority,options:h,color:f(e.priority),onChange:t=>void o(e.id,{priority:t}).catch(()=>void 0)})}),(0,y.jsx)(C,{className:`font-mono text-[11px] text-muted-foreground`,children:e.type}),(0,y.jsx)(C,{className:`font-mono text-[11px] text-muted-foreground`,children:e.area}),(0,y.jsxs)(C,{className:`font-mono text-[11px] text-muted-foreground/60`,children:[t?(0,y.jsx)(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),a(t)},className:u(`cursor-pointer text-primary hover:underline`,s>0&&`mr-1.5`),children:t}):null,s>0?`${s} ↔`:t?null:`—`]}),(0,y.jsx)(C,{className:`font-mono text-[11px] text-muted-foreground/60`,children:e.updated||`—`})]})});function j({tasks:e,allTasks:t,areas:n,filters:a,setFilters:s,epicIds:c,onOpen:u,onPatch:_,onBulkPatch:C}){let[A,j]=(0,v.useState)(()=>new Set),[_e,ve]=(0,v.useState)(null),[M,ye]=(0,v.useState)(`id`),[N,P]=(0,v.useState)(`desc`),[F,I]=(0,v.useState)(``),[L,R]=(0,v.useState)(``),[z,B]=(0,v.useState)(``),V=(0,v.useRef)(null),[H,be]=(0,v.useState)({start:0,end:40}),[U,xe]=(0,v.useState)(40),W=(0,v.useDeferredValue)(a),G=(0,v.useMemo)(()=>{let e=e=>ue(t,{...W,...e});return{status:O(e({status:``}),`status`),type:O(e({type:``,showIdeas:!0}),`type`),priority:O(e({priority:``}),`priority`),area:O(e({area:``}),`area`)}},[t,W]),K=(0,v.useMemo)(()=>{let t=[...e];return t.sort((e,t)=>{let n=0;return n=M===`priority`?(T.get(e.priority)||0)-(T.get(t.priority)||0):M===`status`?(E.get(e.status)||0)-(E.get(t.status)||0):M===`epic`?(c.get(e.id)||``).localeCompare(c.get(t.id)||``):String(e[M]||``).localeCompare(String(t[M]||``),void 0,{numeric:!0}),N===`asc`?n:-n}),t},[c,N,M,e]),q=(0,v.useRef)(0),Se=K.length>0,J=(0,v.useCallback)(()=>{let e=V.current;if(!e)return;let t=parseFloat(getComputedStyle(document.documentElement).getPropertyValue(`--row-h`))||40;xe(t);let n=Math.max(0,Math.floor(e.scrollTop/t)-10),r=Math.ceil(e.clientHeight/t);be({start:n,end:Math.min(q.current,n+r+20)})},[]);(0,v.useEffect)(()=>{let e=V.current;if(!e)return;e.addEventListener(`scroll`,J,{passive:!0}),window.addEventListener(`resize`,J);let t=new MutationObserver(J);return t.observe(document.documentElement,{attributes:!0,attributeFilter:[`data-density`]}),()=>{e.removeEventListener(`scroll`,J),window.removeEventListener(`resize`,J),t.disconnect()}},[J,Se]),(0,v.useEffect)(()=>{q.current=K.length,J()},[J,K.length]);let Ce=[a.search,a.status,a.area,a.type,a.priority,a.milestone,a.showIdeas,a.showClosed,M,N].join(`|`);(0,v.useEffect)(()=>{V.current&&(V.current.scrollTop=0),J()},[Ce,J]);let we=(0,v.useCallback)(e=>{j(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},[]),Te=(0,v.useCallback)(e=>{ve(e),u(e)},[u]),Y=(0,v.useMemo)(()=>K.map(e=>e.id),[K]),X=Y.length>0&&Y.every(e=>A.has(e)),Ee=Y.some(e=>A.has(e)),De=K.slice(H.start,H.end),Z=!!(F||L||z);function Oe(e){M===e?P(e=>e===`asc`?`desc`:`asc`):(ye(e),P(e===`id`?`desc`:`asc`))}async function ke(){let e={};if(F&&(e.status=F),L&&(e.priority=L),z&&(e.area=z),!(!Z||A.size===0))try{await C([...A],e),j(new Set),I(``),R(``),B(``)}catch{}}let Q=(0,y.jsxs)(y.Fragment,{children:[(0,y.jsx)(k,{title:`status`,values:g,counts:G.status,selected:a.status,color:l,onSelect:e=>s(t=>({...t,status:e}))}),(0,y.jsx)(k,{title:`priority`,values:h,counts:G.priority,selected:a.priority,color:f,onSelect:e=>s(t=>({...t,priority:e}))}),(0,y.jsx)(k,{title:`area`,values:n,counts:G.area,selected:a.area,onSelect:e=>s(t=>({...t,area:e}))}),(0,y.jsx)(k,{title:`type`,values:de,counts:G.type,selected:a.type,onSelect:e=>s(t=>({...t,type:e}))})]}),$=[a.status,a.priority,a.area,a.type].filter(Boolean).length;return(0,y.jsxs)(`div`,{className:`flex min-h-0 flex-1`,children:[(0,y.jsx)(`aside`,{"aria-label":`Backlog facets`,className:`hidden w-[204px] flex-none flex-col gap-5 overflow-y-auto border-r px-3.5 py-4 lg:flex`,children:Q}),(0,y.jsxs)(`div`,{className:`flex min-h-0 min-w-0 flex-1 flex-col`,children:[(0,y.jsxs)(`div`,{className:`flex flex-none items-center gap-2 px-3.5 pt-2.5 lg:hidden`,children:[(0,y.jsxs)(se,{children:[(0,y.jsx)(le,{asChild:!0,children:(0,y.jsxs)(d,{variant:`outline`,size:`sm`,className:`h-7 gap-1.5 px-2.5 text-xs`,children:[(0,y.jsx)(ee,{className:`size-3.5`}),`Facets`,$?(0,y.jsx)(`span`,{className:`font-mono text-[10px] text-muted-foreground`,children:$}):null]})}),(0,y.jsxs)(ce,{side:`left`,className:`w-[280px] gap-0 sm:max-w-[280px]`,children:[(0,y.jsx)(fe,{className:`pb-2`,children:(0,y.jsx)(ae,{className:`font-mono text-[11px] tracking-wide uppercase`,children:`Facets`})}),(0,y.jsx)(`div`,{className:`flex flex-col gap-5 overflow-y-auto px-4 pb-4`,children:Q})]})]}),(0,y.jsxs)(`span`,{className:`font-mono text-[10.5px] text-muted-foreground/70`,children:[K.length.toLocaleString(),` row`,K.length===1?``:`s`,` · scroll sideways for every column`]})]}),A.size>0&&(0,y.jsxs)(`div`,{role:`region`,"aria-label":`Bulk actions`,className:`mx-3.5 mt-2.5 mb-2.5 flex flex-none flex-wrap items-center gap-2 rounded-md border bg-muted/50 px-3 py-2`,children:[(0,y.jsxs)(`span`,{className:`font-mono text-[11px]`,children:[A.size,` selected`]}),(0,y.jsxs)(m,{"aria-label":`Set status`,value:F,onChange:e=>I(e.target.value),className:`h-7 px-2 py-0 pr-8 text-xs`,children:[(0,y.jsx)(p,{value:``,children:`status…`}),g.map(e=>(0,y.jsx)(p,{value:e,children:e},e))]}),(0,y.jsxs)(m,{"aria-label":`Set priority`,value:L,onChange:e=>R(e.target.value),className:`h-7 px-2 py-0 pr-8 text-xs`,children:[(0,y.jsx)(p,{value:``,children:`priority…`}),h.map(e=>(0,y.jsx)(p,{value:e,children:e},e))]}),(0,y.jsxs)(m,{"aria-label":`Set area`,value:z,onChange:e=>B(e.target.value),className:`h-7 px-2 py-0 pr-8 text-xs`,children:[(0,y.jsx)(p,{value:``,children:`area…`}),n.map(e=>(0,y.jsx)(p,{value:e,children:e},e))]}),(0,y.jsxs)(oe,{children:[(0,y.jsx)(d,{size:`sm`,className:`h-7`,disabled:!Z,onClick:()=>void ke(),children:`Apply`}),(0,y.jsx)(d,{size:`sm`,variant:`outline`,className:`h-7`,onClick:()=>j(new Set),children:`Clear`})]})]}),K.length===0?(0,y.jsx)(ie,{children:(0,y.jsxs)(te,{children:[(0,y.jsx)(ne,{children:`No cards match`}),(0,y.jsx)(re,{children:`Adjust filters or clear the search`})]})}):(0,y.jsx)(`div`,{ref:V,className:`min-w-0 flex-1 overflow-auto [&>[data-slot=table-container]]:overflow-visible`,children:(0,y.jsxs)(pe,{className:`text-[13px]`,children:[(0,y.jsx)(me,{children:(0,y.jsxs)(x,{className:`hover:bg-transparent`,children:[(0,y.jsx)(S,{className:`sticky top-0 z-10 w-7 bg-background`,children:(0,y.jsx)(b,{"aria-label":`Select all matching cards`,checked:X?!0:Ee?`indeterminate`:!1,onCheckedChange:()=>j(e=>{let t=new Set(e);return X?Y.forEach(e=>t.delete(e)):Y.forEach(e=>t.add(e)),t})})}),w.map(([e,t])=>(0,y.jsx)(S,{"aria-sort":M===e?N===`asc`?`ascending`:`descending`:`none`,className:`sticky top-0 z-10 bg-background`,children:(0,y.jsxs)(d,{variant:`ghost`,size:`sm`,onClick:()=>Oe(e),className:`-ml-2 h-7 gap-1 px-2 text-xs text-muted-foreground`,children:[t,M===e?N===`asc`?(0,y.jsx)(i,{className:`size-3`}):(0,y.jsx)(r,{className:`size-3`}):(0,y.jsx)(o,{className:`size-3 opacity-50`})]})},e))]})}),(0,y.jsxs)(he,{children:[H.start>0&&(0,y.jsx)(`tr`,{"aria-hidden":`true`,children:(0,y.jsx)(`td`,{colSpan:D,style:{height:H.start*U}})}),De.map(e=>(0,y.jsx)(ge,{task:e,epicId:c.get(e.id)||``,checked:A.has(e.id),isOpen:_e===e.id,onToggle:we,onOpen:Te,onPatch:_},e.id)),H.end<K.length&&(0,y.jsx)(`tr`,{"aria-hidden":`true`,children:(0,y.jsx)(`td`,{colSpan:D,style:{height:(K.length-H.end)*U}})})]})]})})]})]})}export{j as Explorer}; |
| import{n as e}from"./rolldown-runtime-CbXtAM7H.js";import{i as t,t as n}from"./react-Buq45Vzz.js";import{dt as r}from"./ui-primitives-wYj92QGw.js";import{a as i,f as a,i as o,o as s,p as c,r as l,t as u,u as d}from"./empty-BHqXimMR.js";import{$ as f,A as p,I as m,Q as h,T as g,et as _,j as v,k as y}from"./index-F1UmdPYw.js";var b=e(t(),1),x=n(),S=[{level:`error`,label:`errors`,hint:`must be fixed for a consistent workspace`,zeroHint:`the doctor does not block the release`},{level:`warning`,label:`warnings`,hint:`worth a look, nothing is broken yet`,zeroHint:`nothing worth flagging`},{level:`info`,label:`infos`,hint:`informational, no action required`,zeroHint:`no notices from the doctor`}];function C(e){return e.replace(/[-_.]+/g,` `)}var w={error:0,warning:1,info:2};function T({onOpen:e}){let[t,n]=(0,b.useState)(null),[T,E]=(0,b.useState)(``),[D,O]=(0,b.useState)(``),[k,A]=(0,b.useState)(0);y(()=>A(e=>e+1)),(0,b.useEffect)(()=>{let e=!0;return m.health().then(t=>{e&&n(t)}).catch(t=>{e&&E(t instanceof Error?t.message:String(t))}),()=>{e=!1}},[k]);let j=(0,b.useMemo)(()=>{if(!t)return[];let e=D?t.issues.filter(e=>e.severity===D):t.issues,n=new Map;for(let t of e){let e=n.get(t.code);e?e.push(t):n.set(t.code,[t])}return[...n.entries()].sort(([e,[t]],[n,[r]])=>{let i=w[t.severity]-w[r.severity];return i===0?e.localeCompare(n):i})},[t,D]);if(T)return(0,x.jsx)(`div`,{className:`p-3.5`,children:(0,x.jsx)(f,{variant:`destructive`,children:(0,x.jsx)(_,{children:T})})});if(!t)return(0,x.jsxs)(`div`,{className:`flex items-center gap-2 p-3.5`,"aria-busy":`true`,children:[(0,x.jsx)(g,{className:`size-3 text-muted-foreground`}),(0,x.jsx)(`span`,{className:`font-mono text-[11px] text-muted-foreground`,children:`running workfile doctor…`})]});let M=[[`cards`,t.modules?.cards??t.cards],[`docs`,t.modules?.docs],[`memory`,t.modules?.memory],[`changelog`,t.modules?.changelog]].filter(([,e])=>e!=null).map(([e,t])=>`${t.toLocaleString()} ${e}`).join(`, `),N=new Intl.DateTimeFormat(void 0,{dateStyle:`medium`,timeStyle:`short`}).format(new Date(t.generatedAt));return(0,x.jsxs)(`div`,{className:`flex-1 overflow-y-auto p-3.5`,children:[(0,x.jsx)(`div`,{className:`mb-2.5 flex gap-1.5`,children:S.map(({level:e,label:n})=>(0,x.jsxs)(c,{type:`button`,variant:`outline`,size:`sm`,"aria-pressed":D===e,className:`aria-pressed:border-ring aria-pressed:bg-accent`,onClick:()=>O(t=>t===e?``:e),children:[n,(0,x.jsx)(h,{variant:`secondary`,className:`px-1.5 font-mono text-[10.5px]`,children:t.counts[e]})]},e))}),(0,x.jsx)(`div`,{className:`flex flex-wrap gap-2.5`,children:S.map(({level:e,label:n,hint:r,zeroHint:i})=>{let o=t.counts[e],s=e===`error`&&o===0?a(`done`):d(e);return(0,x.jsxs)(v,{className:`relative min-w-[13rem] flex-1 gap-1 py-3 pl-5 pr-3.5`,children:[(0,x.jsx)(p,{edge:`left`,color:s}),(0,x.jsxs)(`span`,{className:`flex items-baseline gap-2`,children:[(0,x.jsx)(`span`,{className:`text-[26px] font-semibold tracking-tight`,style:{color:s},children:o}),(0,x.jsx)(`span`,{className:`font-mono text-[11px] text-muted-foreground`,children:n})]}),(0,x.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:o===0?i:r})]},e)})}),(0,x.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-2.5 gap-y-1 px-0.5 pt-4 pb-2`,children:[(0,x.jsxs)(`span`,{className:`font-mono text-[11px] text-muted-foreground`,children:[`grouped by code · `,M,` · checked `,N]}),(0,x.jsx)(`span`,{className:`ml-auto font-mono text-[10.5px] text-muted-foreground/70`,children:`workfile doctor --json`})]}),j.length===0?(0,x.jsx)(u,{className:`gap-2 p-10`,children:(0,x.jsxs)(o,{children:[(0,x.jsx)(i,{children:(0,x.jsx)(r,{"aria-hidden":`true`,size:20,style:{color:a(`done`)}})}),(0,x.jsx)(s,{className:`text-sm`,children:`All clear`}),(0,x.jsxs)(l,{className:`text-[12.5px]`,children:[`No `,D||`integrity`,` issues found.`]})]})}):(0,x.jsx)(`div`,{className:`flex flex-col gap-2`,children:j.map(([t,n])=>(0,x.jsxs)(v,{className:`gap-0 overflow-hidden py-0`,children:[(0,x.jsxs)(`div`,{className:`flex items-center gap-2 border-b px-3 py-1.5`,children:[(0,x.jsx)(`span`,{"aria-hidden":`true`,className:`size-[7px] rounded-full bg-current`,style:{color:d(n[0].severity)}}),(0,x.jsx)(`span`,{className:`font-mono text-[11.5px]`,children:t}),(0,x.jsx)(`span`,{className:`flex-1 text-[12.5px] text-muted-foreground`,children:C(t)}),(0,x.jsx)(`span`,{className:`font-mono text-[11px] text-muted-foreground/70`,children:n.length})]}),n.map((t,n)=>(0,x.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-2.5 gap-y-1 border-b px-3 py-[7px] last:border-0`,children:[t.id?(0,x.jsx)(c,{type:`button`,variant:`link`,className:`h-auto w-[82px] flex-[0_0_82px] justify-start p-0 font-mono text-[11px] font-normal`,onClick:()=>e(t.id),children:t.id}):(0,x.jsx)(`span`,{className:`w-[82px] flex-[0_0_82px] font-mono text-[11px] text-muted-foreground/70`,children:`—`}),(0,x.jsx)(`span`,{className:`min-w-[12rem] flex-1 text-[12.5px] text-muted-foreground`,children:t.message}),t.file?(0,x.jsx)(`span`,{className:`max-w-full truncate font-mono text-[10.5px] text-muted-foreground/70 sm:max-w-80`,title:t.file,children:t.file}):null]},`${t.id||t.file}-${n}`))]},t))})]})}export{T as HealthView}; |
| import{n as e}from"./rolldown-runtime-CbXtAM7H.js";import{i as t,t as n}from"./react-Buq45Vzz.js";import{K as r,N as i,_t as a,gt as o}from"./ui-primitives-wYj92QGw.js";import{f as s,l as c,m as l,p as u,r as d,t as f,u as p}from"./empty-BHqXimMR.js";import{n as m,t as h}from"./native-select-NN1SzVJL.js";import{$ as g,D as _,E as v,F as ee,G as y,H as b,I as x,K as S,M as C,N as w,O as te,P as ne,Q as T,Z as E,b as D,c as O,d as k,et as A,f as j,j as re,k as ie,l as M,p as N,q as P,u as F,v as I,w as ae,x as oe}from"./index-F1UmdPYw.js";import{t as se}from"./layout-QiuZ_k5v.js";var L=e(t(),1),R=n(),z=`text-[10px] font-medium tracking-widest uppercase text-muted-foreground`;function B(e){switch(e){case`added`:return s(`done`);case`changed`:return s(`doing`);case`fixed`:return s(`review`);case`removed`:return s(`blocked`);case`security`:return p(`error`);default:return s(`backlog`)}}function ce(e,t){let n=null;for(let t of e){let e=/^v?(\d+)\.(\d+)\.(\d+)/.exec(t.version);if(!e)continue;let r=[Number(e[1]),Number(e[2]),Number(e[3])];(n?r[0]-n[0]||r[1]-n[1]||r[2]-n[2]:1)>0&&(n=r)}return n?t.some(e=>[`added`,`removed`,`deprecated`].includes(e.type))?`${n[0]}.${n[1]+1}.0`:`${n[0]}.${n[1]}.${n[2]+1}`:`0.1.0`}function V(e){return e instanceof Error?e.message:String(e)}function H({label:e,value:t,options:n,onChange:r}){return(0,R.jsxs)(y,{children:[(0,R.jsx)(E,{asChild:!0,children:(0,R.jsxs)(u,{type:`button`,variant:`outline`,size:`sm`,"aria-label":e,className:l(`h-7 gap-1 px-2 text-xs`,t&&`border-ring bg-accent`),children:[e,(0,R.jsx)(`span`,{className:l(`font-normal`,!t&&`text-muted-foreground`),children:t||`all`}),(0,R.jsx)(a,{"aria-hidden":`true`,className:`size-3 text-muted-foreground`})]})}),(0,R.jsxs)(P,{align:`start`,children:[(0,R.jsx)(S,{checked:!t,onSelect:()=>r(``),children:`all`}),n.map(e=>(0,R.jsx)(S,{checked:t===e,onSelect:()=>r(e),children:e},e))]})]})}function U({record:e,selected:t,onSelect:n}){let r=e.kind===`release`?`release`:e.type,i=e.kind===`release`?`var(--primary)`:B(e.type),a=e.kind===`release`?`${e.fragments.length} fragment${e.fragments.length===1?``:`s`} · ${e.date}`:e.area;return(0,R.jsx)(v,{asChild:!0,variant:`outline`,size:`sm`,children:(0,R.jsxs)(`button`,{type:`button`,"aria-current":t?`true`:void 0,onClick:n,className:l(`flex-col flex-nowrap items-stretch gap-1 px-2.5 py-2 text-left shadow-xs`,t?`border-ring bg-accent`:`bg-card hover:border-ring`),children:[(0,R.jsxs)(`span`,{className:`flex items-baseline gap-2`,children:[(0,R.jsx)(`span`,{className:`font-mono text-[11px] text-muted-foreground`,children:e.id}),(0,R.jsx)(`span`,{className:`font-mono text-[10px]`,style:{color:i},children:r}),(0,R.jsx)(`span`,{className:`flex-1`}),(0,R.jsx)(`span`,{className:`max-w-[170px] truncate font-mono text-[10px] text-muted-foreground/70`,children:a})]}),(0,R.jsx)(`span`,{className:`text-sm leading-snug font-normal`,children:e.title})]})})}function W({label:e,records:t,selectedId:n,onSelect:r}){return t.length?(0,R.jsxs)(`div`,{role:`group`,"aria-label":e,className:`flex flex-col gap-1.5 pt-4`,children:[(0,R.jsxs)(`span`,{className:z,children:[e,` · `,t.length]}),t.map(e=>(0,R.jsx)(U,{record:e,selected:e.id===n,onSelect:()=>r(e.id)},e.id))]}):null}function G({id:e,title:t,relation:n,disabled:r,onOpen:i}){return(0,R.jsx)(v,{asChild:!0,variant:`outline`,size:`sm`,children:(0,R.jsxs)(`button`,{type:`button`,disabled:r,onClick:i,className:`flex-nowrap gap-2 bg-card px-2.5 py-1.5 text-left shadow-xs hover:border-ring disabled:pointer-events-none disabled:opacity-55`,children:[(0,R.jsx)(`span`,{className:`shrink-0 font-mono text-[11px] text-muted-foreground`,children:e}),(0,R.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-[12.5px]`,children:t}),n?(0,R.jsx)(T,{variant:`outline`,className:`shrink-0 font-mono text-[10px] font-normal text-muted-foreground`,children:n}):null]})})}function K({label:e,links:t,onOpen:n}){return t.length?(0,R.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,R.jsx)(`span`,{className:z,children:e}),t.map(t=>(0,R.jsx)(G,{id:t.id,title:t.title,relation:t.relation,disabled:t.disabled,onOpen:()=>n(t.id)},`${e}-${t.id}`))]}):null}function le(e){return e.map(e=>({id:e.id,title:e.title||`Missing record`,relation:e.relation,disabled:!e.exists&&!e.title}))}function ue({schema:e,areas:t,onClose:n,onCreated:r}){let[i,a]=(0,L.useState)({title:``,type:e.defaults.type,area:t[0]||`general`,visibility:e.defaults.visibility,body:``}),[o,s]=(0,L.useState)(!1),[c,l]=(0,L.useState)(``),d=(e,t)=>a(n=>({...n,[e]:t})),f=async()=>{s(!0);try{r((await x.createChange(i)).record)}catch(e){l(V(e))}finally{s(!1)}};return(0,R.jsx)(O,{open:!0,onOpenChange:e=>{e||n()},children:(0,R.jsxs)(M,{onOpenAutoFocus:e=>e.preventDefault(),children:[(0,R.jsxs)(j,{children:[(0,R.jsx)(N,{children:`New change fragment`}),(0,R.jsx)(F,{children:`Record one user- or operator-meaningful change.`})]}),(0,R.jsxs)(I,{children:[(0,R.jsx)(D,{htmlFor:`new-fragment-title`,children:`Title`}),(0,R.jsx)(b,{id:`new-fragment-title`,autoFocus:!0,required:!0,maxLength:120,value:i.title,onChange:e=>d(`title`,e.target.value)})]}),(0,R.jsxs)(`div`,{className:`grid grid-cols-3 gap-2.5`,children:[(0,R.jsxs)(I,{children:[(0,R.jsx)(D,{htmlFor:`new-fragment-type`,children:`Type`}),(0,R.jsx)(h,{id:`new-fragment-type`,value:i.type,onChange:e=>d(`type`,e.target.value),children:e.types.map(e=>(0,R.jsx)(m,{value:e,children:e},e))})]}),(0,R.jsxs)(I,{children:[(0,R.jsx)(D,{htmlFor:`new-fragment-area`,children:`Area`}),(0,R.jsx)(h,{id:`new-fragment-area`,value:i.area,onChange:e=>d(`area`,e.target.value),children:t.map(e=>(0,R.jsx)(m,{value:e,children:e},e))})]}),(0,R.jsxs)(I,{children:[(0,R.jsx)(D,{htmlFor:`new-fragment-visibility`,children:`Visibility`}),(0,R.jsx)(h,{id:`new-fragment-visibility`,value:i.visibility,onChange:e=>d(`visibility`,e.target.value),children:e.visibilities.map(e=>(0,R.jsx)(m,{value:e,children:e},e))})]})]}),(0,R.jsxs)(I,{children:[(0,R.jsx)(D,{htmlFor:`new-fragment-details`,children:`Details`}),(0,R.jsx)(ae,{id:`new-fragment-details`,rows:5,value:i.body,onChange:e=>d(`body`,e.target.value)})]}),c?(0,R.jsx)(g,{variant:`destructive`,"aria-live":`polite`,children:(0,R.jsx)(A,{children:c})}):null,(0,R.jsxs)(k,{children:[(0,R.jsx)(u,{type:`button`,variant:`outline`,onClick:n,children:`Cancel`}),(0,R.jsx)(u,{type:`button`,disabled:o||!i.title.trim(),onClick:()=>void f(),children:o?`Saving…`:`Create fragment`})]})]})})}function de({preview:e,suggestedVersion:t,onClose:n,onReleased:r}){let[i,a]=(0,L.useState)(t),[o,s]=(0,L.useState)(``),[c,l]=(0,L.useState)(!1),[d,f]=(0,L.useState)(``),p=async()=>{l(!0);try{await x.createRelease({version:i,title:o||void 0,fragmentIds:e.fragments.map(e=>e.id)}),r()}catch(e){f(V(e))}finally{l(!1)}};return(0,R.jsx)(O,{open:!0,onOpenChange:e=>{e||n()},children:(0,R.jsxs)(M,{className:`flex max-h-[85vh] flex-col sm:max-w-[640px]`,children:[(0,R.jsxs)(j,{children:[(0,R.jsx)(N,{children:`Release preparation`}),(0,R.jsxs)(F,{children:[e.fragments.length,` unreleased fragment`,e.fragments.length===1?``:`s`,` selected.`]})]}),(0,R.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col gap-4 overflow-y-auto`,children:[(0,R.jsxs)(`div`,{className:`grid grid-cols-[150px_1fr] gap-2.5`,children:[(0,R.jsxs)(I,{children:[(0,R.jsx)(D,{htmlFor:`release-version`,children:`Version`}),(0,R.jsx)(b,{id:`release-version`,className:`font-mono`,placeholder:`2.4.0`,value:i,onChange:e=>a(e.target.value)})]}),(0,R.jsxs)(I,{children:[(0,R.jsx)(D,{htmlFor:`release-title`,children:`Release title`}),(0,R.jsx)(b,{id:`release-title`,placeholder:`Optional curated title`,value:o,onChange:e=>s(e.target.value)})]})]}),e.groups.map(e=>(0,R.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,R.jsxs)(`span`,{className:z,style:{color:B(e.type)},children:[e.type,` · `,e.fragments.length]}),e.fragments.map(e=>(0,R.jsxs)(`span`,{className:`flex items-baseline gap-2 text-[12.5px]`,children:[(0,R.jsx)(`span`,{className:`shrink-0 font-mono text-[11px] text-muted-foreground`,children:e.id}),(0,R.jsx)(`span`,{className:`min-w-0 truncate`,children:e.title}),(0,R.jsx)(`span`,{className:`flex-1`}),(0,R.jsx)(`span`,{className:`font-mono text-[10px] text-muted-foreground/70`,children:e.area})]},e.id))]},e.type)),(0,R.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,R.jsx)(`span`,{className:z,children:`release notes preview`}),(0,R.jsx)(`div`,{className:`max-h-[220px] overflow-y-auto rounded-md border bg-background px-3 py-1`,children:(0,R.jsx)(oe,{source:e.markdown||`No release notes to render.`})})]}),d?(0,R.jsx)(g,{variant:`destructive`,"aria-live":`polite`,children:(0,R.jsx)(A,{children:d})}):null]}),(0,R.jsxs)(k,{children:[(0,R.jsx)(u,{type:`button`,variant:`outline`,onClick:n,children:`Cancel`}),(0,R.jsx)(u,{type:`button`,disabled:c||!i.trim()||!e.fragments.length,onClick:()=>void p(),children:c?`Releasing…`:`Create release`})]})]})})}function fe({record:e,schema:t,areas:n,onSaved:r}){let[i,a]=(0,L.useState)({title:e.title,type:e.type,area:e.area,visibility:e.visibility}),[o,s]=(0,L.useState)(!1),[c,l]=(0,L.useState)(``),d=(e,t)=>a(n=>({...n,[e]:t})),f={};for(let t of[`title`,`type`,`area`,`visibility`])i[t]!==e[t]&&(f[t]=i[t]);let g=Object.keys(f).length>0,_=n.includes(e.area)?n:[e.area,...n],v=async()=>{s(!0);try{let t=await x.patchChange(e.id,f,e.revision);l(``),r(t.record)}catch(e){l(V(e))}finally{s(!1)}};return(0,R.jsxs)(re,{className:`gap-2.5 rounded-lg py-3 shadow-xs`,children:[(0,R.jsx)(ne,{className:`px-3`,children:(0,R.jsx)(ee,{className:z,children:`edit fragment`})}),(0,R.jsxs)(C,{className:`flex flex-col gap-2.5 px-3`,children:[(0,R.jsxs)(I,{children:[(0,R.jsx)(D,{htmlFor:`edit-fragment-title`,children:`Title`}),(0,R.jsx)(b,{id:`edit-fragment-title`,maxLength:120,value:i.title,onChange:e=>d(`title`,e.target.value)})]}),(0,R.jsxs)(`div`,{className:`grid grid-cols-3 gap-2.5`,children:[(0,R.jsxs)(I,{children:[(0,R.jsx)(D,{htmlFor:`edit-fragment-type`,children:`Type`}),(0,R.jsx)(h,{id:`edit-fragment-type`,value:i.type,onChange:e=>d(`type`,e.target.value),children:t.types.map(e=>(0,R.jsx)(m,{value:e,children:e},e))})]}),(0,R.jsxs)(I,{children:[(0,R.jsx)(D,{htmlFor:`edit-fragment-area`,children:`Area`}),(0,R.jsx)(h,{id:`edit-fragment-area`,value:i.area,onChange:e=>d(`area`,e.target.value),children:_.map(e=>(0,R.jsx)(m,{value:e,children:e},e))})]}),(0,R.jsxs)(I,{children:[(0,R.jsx)(D,{htmlFor:`edit-fragment-visibility`,children:`Visibility`}),(0,R.jsx)(h,{id:`edit-fragment-visibility`,value:i.visibility,onChange:e=>d(`visibility`,e.target.value),children:t.visibilities.map(e=>(0,R.jsx)(m,{value:e,children:e},e))})]})]})]}),(0,R.jsxs)(w,{className:`gap-2.5 px-3`,children:[c?(0,R.jsx)(`span`,{className:`flex-1 text-xs`,style:{color:p(`error`)},"aria-live":`polite`,children:c}):(0,R.jsx)(`span`,{className:`flex-1`}),(0,R.jsx)(u,{type:`button`,variant:`outline`,size:`sm`,disabled:o||!g||!i.title.trim(),onClick:()=>void v(),children:o?`Saving…`:`Save changes`})]})]})}function pe({selectedId:e,onSelect:t,onOpenRecord:n,schema:a,areas:s}){let[m,h]=(0,L.useState)([]),[v,ee]=(0,L.useState)(``),[y,S]=(0,L.useState)(``),[C,w]=(0,L.useState)(``),[ne,E]=(0,L.useState)(!0),[D,O]=(0,L.useState)(``),[k,j]=(0,L.useState)(``),[M,N]=(0,L.useState)(!1),[P,F]=(0,L.useState)(null),[I,ae]=(0,L.useState)(`public`),[z,U]=(0,L.useState)({content:``,error:``,loading:!0}),[G,pe]=(0,L.useState)(0),me=()=>pe(e=>e+1);ie(e=>{te(e,`/changelog/`)&&me()}),(0,L.useEffect)(()=>{let e=!1,t=async()=>{E(!0);try{let t=await x.changelog(v.trim(),{state:y||void 0,visibility:C||void 0});if(e)return;h(t.records),O(``)}catch(t){e||O(V(t))}finally{e||E(!1)}},n=window.setTimeout(()=>void t(),v?180:0);return()=>{e=!0,window.clearTimeout(n)}},[v,y,C,G]),(0,L.useEffect)(()=>{let e=!1;return U(e=>({...e,loading:!0})),x.renderedChangelog(I).then(t=>{e||U({content:t.content,error:``,loading:!1})}).catch(t=>{e||U({content:``,error:V(t),loading:!1})}),()=>{e=!0}},[I,G]);let q=(0,L.useMemo)(()=>[...m].sort((e,t)=>{if(e.kind!==t.kind)return e.kind===`change`?-1:1;if(e.kind===`release`&&t.kind===`release`){let n=t.date.localeCompare(e.date);return n===0?t.id.localeCompare(e.id):n}return String(t.updated||``).localeCompare(String(e.updated||``))}),[m]),J=(0,L.useMemo)(()=>new Map(m.map(e=>[e.id,e])),[m]),Y=(0,L.useMemo)(()=>q.filter(e=>e.kind===`change`&&!e.released),[q]),he=(0,L.useMemo)(()=>q.filter(e=>e.kind===`change`&&e.released),[q]),X=(0,L.useMemo)(()=>q.filter(e=>e.kind===`release`),[q]),Z=(0,L.useMemo)(()=>ce(X,Y),[X,Y]),Q=e?J.get(e):void 0,$=e=>{if(J.has(e)){t(e);return}if(/^(CHG|REL)-/.test(e)){S(``),w(``),t(e);return}n(e)},ge=()=>{j(``),x.releasePreview().then(F).catch(e=>j(V(e)))},_e=Q?.issues.some(e=>e.severity===`error`)?`destructive`:`default`,ve=(0,R.jsxs)(u,{type:`button`,variant:`outline`,size:`sm`,onClick:()=>N(!0),children:[(0,R.jsx)(r,{"aria-hidden":`true`}),`New fragment`]});return(0,R.jsxs)(`div`,{className:`flex min-h-0 flex-1`,children:[(0,R.jsxs)(`div`,{className:l(`w-full shrink-0 flex-col border-r lg:flex lg:w-[400px]`,Q?`hidden`:`flex`),children:[(0,R.jsxs)(`div`,{className:`flex flex-col gap-2.5 p-3.5 pb-0`,children:[(0,R.jsxs)(re,{className:`flex-row items-center gap-2.5 border-primary bg-primary/10 p-3`,children:[(0,R.jsxs)(`span`,{className:`flex min-w-0 flex-1 flex-col gap-0.5`,children:[(0,R.jsxs)(`span`,{className:`text-[13px] font-semibold`,children:[Y.length,` unpublished fragment`,Y.length===1?``:`s`]}),(0,R.jsxs)(`span`,{className:`font-mono text-[10.5px] text-muted-foreground`,children:[`next: `,Z,` ·`,` `,a.releaseStrategy]})]}),(0,R.jsx)(u,{type:`button`,size:`sm`,className:`whitespace-nowrap`,onClick:ge,children:`Prepare release`})]}),k?(0,R.jsx)(g,{variant:`destructive`,"aria-live":`polite`,children:(0,R.jsx)(A,{children:k})}):null,(0,R.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,R.jsx)(b,{type:`search`,"aria-label":`Search history`,placeholder:`Search fragments and releases…`,value:v,onChange:e=>ee(e.target.value),className:`h-7 flex-1 px-2.5 text-xs md:text-xs`}),(0,R.jsx)(H,{label:`state`,value:y,options:[`unreleased`,`released`],onChange:S}),(0,R.jsx)(H,{label:`visibility`,value:C,options:a.visibilities,onChange:w})]})]}),(0,R.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto px-3.5 pb-6 [mask-image:linear-gradient(to_bottom,black_calc(100%-24px),transparent)]`,children:ne?(0,R.jsx)(`div`,{"aria-busy":`true`,className:`flex flex-col gap-2 pt-4`,children:Array.from({length:6},(e,t)=>(0,R.jsx)(`div`,{className:`h-[52px] animate-pulse rounded-md bg-muted`},t))}):D?(0,R.jsx)(g,{variant:`destructive`,className:`mt-4`,"aria-live":`polite`,children:(0,R.jsx)(A,{children:D})}):q.length?(0,R.jsxs)(R.Fragment,{children:[(0,R.jsx)(W,{label:`unpublished`,records:Y,selectedId:e,onSelect:t}),(0,R.jsx)(W,{label:`releases`,records:X,selectedId:e,onSelect:t}),(0,R.jsx)(W,{label:`published fragments`,records:he,selectedId:e,onSelect:t})]}):(0,R.jsx)(f,{className:`mt-4 gap-1 p-4 md:p-4`,children:(0,R.jsx)(d,{className:`text-xs`,children:`No history records match the filters.`})})})]}),(0,R.jsx)(`div`,{className:l(`min-w-0 flex-1 overflow-y-auto px-6 py-5 sm:px-8.5`,Q?`block`:`hidden lg:block`),children:(0,R.jsx)(`div`,{className:se,children:Q?(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(u,{type:`button`,variant:`ghost`,size:`sm`,className:`-ml-2 mb-2 lg:hidden`,onClick:()=>t(``),children:[(0,R.jsx)(o,{"aria-hidden":`true`}),`All history`]}),(0,R.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-2 gap-y-1 font-mono text-[11px]`,children:[(0,R.jsx)(`span`,{className:`whitespace-nowrap text-primary`,children:Q.id}),(0,R.jsx)(`span`,{className:`text-muted-foreground/60`,children:`·`}),(0,R.jsx)(`span`,{className:`text-muted-foreground/70`,children:Q.kind}),(0,R.jsx)(`span`,{className:`text-muted-foreground/60`,children:`·`}),Q.kind===`change`?(0,R.jsxs)(R.Fragment,{children:[(0,R.jsx)(`span`,{style:{color:B(Q.type)},children:Q.type}),(0,R.jsx)(`span`,{className:`text-muted-foreground/60`,children:`·`}),(0,R.jsx)(`span`,{className:`text-muted-foreground`,children:Q.area}),(0,R.jsx)(`span`,{className:`text-muted-foreground/60`,children:`·`}),(0,R.jsx)(`span`,{className:`text-muted-foreground`,children:Q.visibility}),(0,R.jsx)(`span`,{className:`text-muted-foreground/60`,children:`·`}),(0,R.jsx)(`span`,{style:{color:c(Q.released?`released`:`unreleased`)},children:Q.released?`released`:`unreleased`}),Q.updated?(0,R.jsxs)(R.Fragment,{children:[(0,R.jsx)(`span`,{className:`text-muted-foreground/60`,children:`·`}),(0,R.jsx)(`span`,{className:`text-muted-foreground/70`,children:Q.updated})]}):null]}):(0,R.jsxs)(R.Fragment,{children:[(0,R.jsx)(`span`,{className:`text-primary`,children:Q.version}),(0,R.jsx)(`span`,{className:`text-muted-foreground/60`,children:`·`}),(0,R.jsx)(`span`,{className:`text-muted-foreground`,children:Q.date}),Q.commit?(0,R.jsxs)(R.Fragment,{children:[(0,R.jsx)(`span`,{className:`text-muted-foreground/60`,children:`·`}),(0,R.jsx)(`span`,{className:`text-muted-foreground/70`,children:Q.commit})]}):null,(0,R.jsx)(`span`,{className:`text-muted-foreground/60`,children:`·`}),(0,R.jsxs)(`span`,{className:`text-muted-foreground/70`,children:[Q.fragments.length,` fragment`,Q.fragments.length===1?``:`s`]})]}),(0,R.jsxs)(`span`,{className:`ml-auto flex shrink-0 items-center gap-1`,children:[ve,(0,R.jsx)(u,{type:`button`,variant:`ghost`,size:`icon-sm`,"aria-label":`Close record`,title:`Back to the derived changelog`,onClick:()=>t(``),children:(0,R.jsx)(i,{"aria-hidden":`true`})})]})]}),(0,R.jsx)(`h2`,{className:`mt-2.5 mb-1 text-[26px] leading-tight font-semibold tracking-tight [text-wrap:pretty]`,children:Q.title}),(0,R.jsx)(`div`,{className:`font-mono text-[10.5px] break-all text-muted-foreground/70`,children:Q.path}),Q.issues.length>0?(0,R.jsx)(g,{variant:_e,className:`mt-3.5`,children:(0,R.jsx)(A,{className:`w-full gap-1`,children:Q.issues.map(e=>(0,R.jsxs)(`span`,{className:`flex items-baseline gap-2`,children:[(0,R.jsx)(`span`,{className:`shrink-0 font-mono text-[10.5px]`,style:{color:p(e.severity)},children:e.severity}),(0,R.jsx)(`span`,{children:e.message})]},`${e.code}-${e.message}`))})}):null,(0,R.jsx)(`div`,{className:`mt-4.5`,children:(0,R.jsx)(oe,{source:Q.body||`No additional notes.`,onOpen:$})}),(0,R.jsxs)(`div`,{className:`mt-5.5 flex flex-col gap-3.5`,children:[Q.kind===`change`?(0,R.jsx)(K,{label:`shipped in`,links:(Q.releaseIds||[]).map(e=>({id:e,title:J.get(e)?.title||`Open release`,relation:`release`})),onOpen:$}):(0,R.jsx)(K,{label:`fragments · ${Q.fragments.length}`,links:Q.fragments.map(e=>{let t=J.get(e);return{id:e,title:t?.title||`Open fragment`,relation:t?.kind===`change`?t.type:void 0}}),onOpen:$}),(0,R.jsx)(K,{label:`links to`,links:le(Q.outgoing),onOpen:$}),(0,R.jsx)(K,{label:`backlinks`,links:le(Q.incoming),onOpen:$})]}),Q.kind===`change`?(0,R.jsx)(`div`,{className:`mt-5.5`,children:(0,R.jsx)(fe,{record:Q,schema:a,areas:s,onSaved:e=>h(t=>t.map(t=>t.id===e.id?e:t))},`${Q.id}:${Q.revision}`)}):null]}):(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-2.5 gap-y-2 border-b pb-3`,children:[(0,R.jsx)(`span`,{className:`text-[13px] font-semibold`,children:`Derived changelog`}),(0,R.jsxs)(`span`,{className:`font-mono text-[11px] text-muted-foreground`,children:[`visibility `,I,` · CHANGELOG.md`]}),(0,R.jsxs)(`span`,{className:`ml-auto flex flex-wrap items-center gap-2.5`,children:[(0,R.jsx)(_,{children:a.visibilities.map(e=>(0,R.jsx)(u,{type:`button`,size:`sm`,variant:I===e?`default`:`outline`,"aria-pressed":I===e,className:`h-7 px-2.5 text-xs`,onClick:()=>ae(e),children:e},e))}),(0,R.jsx)(T,{variant:`outline`,className:`rounded-md font-mono text-[10.5px] font-normal whitespace-nowrap text-muted-foreground`,children:`render --write`}),ve]})]}),z.error?(0,R.jsx)(g,{variant:`destructive`,className:`mt-4`,"aria-live":`polite`,children:(0,R.jsx)(A,{children:z.error})}):(0,R.jsx)(`pre`,{className:`mt-4 font-mono text-xs leading-[1.75] whitespace-pre-wrap text-muted-foreground`,"aria-busy":z.loading||void 0,children:z.loading&&!z.content?`Rendering…`:z.content||`Nothing to render yet — create the first change fragment.`})]})})}),M?(0,R.jsx)(ue,{schema:a,areas:s,onClose:()=>N(!1),onCreated:e=>{N(!1),h(t=>[e,...t]),t(e.id)}}):null,P?(0,R.jsx)(de,{preview:P,suggestedVersion:Z,onClose:()=>F(null),onReleased:()=>{F(null),me()}}):null]})}export{pe as HistoryView}; |
Sorry, the diff of this file is too big to display
| import{n as e}from"./rolldown-runtime-CbXtAM7H.js";import{i as t,t as n}from"./react-Buq45Vzz.js";import{G as r,K as i,V as a,_t as o,it as s,q as c,vt as l}from"./ui-primitives-wYj92QGw.js";import{l as u,m as d,p as f,r as p,t as m,u as h}from"./empty-BHqXimMR.js";import{n as g,t as _}from"./native-select-NN1SzVJL.js";import{$ as v,E as y,G as b,H as x,I as S,J as C,M as ee,O as te,P as ne,Q as w,T,Z as E,_ as re,b as D,c as O,d as k,et as A,f as j,g as M,h as N,j as P,k as F,l as I,m as ie,p as L,q as R,v as z,w as B,x as V}from"./index-F1UmdPYw.js";var H=e(t(),1),U=n(),W=[`low`,`medium`,`high`],G=[`critical`,`high`,`medium`,`low`],ae=`[mask-image:linear-gradient(to_bottom,black_calc(100%_-_24px),transparent)]`;function oe(e){return e&&e[0].toUpperCase()+e.slice(1)}function K(e,t){return`${e} ${t}${e===1?``:`s`}`}function q(e){return{category:e===`learnings`||e===`decisions`,confidence:e===`learnings`,severity:e===`incidents`,expires:e===`context`,review_after:e===`context`}}function se(e){let t=[];switch(e.collection){case`learnings`:t.push(e.confidence,e.category,e.occurrences==null?null:`${e.occurrences}×`);break;case`decisions`:e.superseded_by?.length?t.push(`superseded by ${e.superseded_by.join(`, `)}`):e.supersedes?.length?t.push(`supersedes ${e.supersedes.join(`, `)}`):t.push(e.category);break;case`incidents`:t.push(e.severity,e.corrective_actions?.length?K(e.corrective_actions.length,`corrective action`):null);break;case`conventions`:t.push(e.owners?.length?e.owners.join(`, `):`no owner`);break;case`context`:t.push(e.expires?`expires ${e.expires}`:null,e.review_after?`review after ${e.review_after}`:null);break;default:t.push(e.category,e.severity)}return t.filter(Boolean).join(` · `)}function J({label:e,value:t,options:n,allLabel:r=`all`,onChange:i}){return(0,U.jsxs)(b,{children:[(0,U.jsx)(E,{asChild:!0,children:(0,U.jsxs)(f,{type:`button`,variant:`outline`,size:`sm`,"aria-label":e,className:d(`h-7 gap-1 rounded-full px-2.5 text-xs`,t&&`border-ring bg-accent`),children:[e,(0,U.jsx)(`span`,{className:`font-normal text-muted-foreground`,children:t||r}),(0,U.jsx)(o,{"aria-hidden":`true`,className:`size-3 text-muted-foreground`})]})}),(0,U.jsxs)(R,{align:`start`,sideOffset:4,children:[(0,U.jsxs)(C,{onSelect:()=>i(``),children:[r,t?null:(0,U.jsx)(l,{"aria-hidden":`true`,className:`ml-auto`})]}),n.map(e=>(0,U.jsxs)(C,{onSelect:()=>i(e.value),children:[e.color?(0,U.jsx)(`span`,{className:`size-2 shrink-0 rounded-full`,style:{backgroundColor:e.color},"aria-hidden":`true`}):null,e.label??e.value,t===e.value?(0,U.jsx)(l,{"aria-hidden":`true`,className:`ml-auto`}):null]},e.value))]})]})}function Y({id:e,label:t,children:n}){return(0,U.jsxs)(z,{className:`gap-1.5 [&_[data-slot=native-select-wrapper]]:w-full`,children:[(0,U.jsx)(D,{htmlFor:e,children:t}),n]})}function ce({record:e,selected:t,onSelect:n}){let r=se(e),i=e.lifecycleIssues?.length||0;return(0,U.jsx)(y,{asChild:!0,variant:`outline`,size:`sm`,className:`w-full flex-none flex-col items-stretch gap-1 rounded-lg bg-background px-2.5 py-2 text-left shadow-xs hover:border-ring aria-[current=true]:border-ring aria-[current=true]:bg-accent`,children:(0,U.jsxs)(`button`,{type:`button`,"aria-current":t?`true`:void 0,onClick:n,children:[(0,U.jsxs)(`span`,{className:`flex items-center justify-between gap-2`,children:[(0,U.jsx)(`span`,{className:`font-mono text-[11px] text-muted-foreground`,children:e.id}),(0,U.jsxs)(w,{variant:`outline`,className:`h-[18px] gap-1 rounded-md px-1.5 font-mono text-[10px] font-medium`,children:[(0,U.jsx)(`span`,{className:`size-[5px] shrink-0 rounded-full`,style:{backgroundColor:u(e.status)},"aria-hidden":`true`}),e.status]})]}),(0,U.jsx)(`span`,{className:`text-[13px] font-medium leading-snug`,children:e.title}),r||i?(0,U.jsxs)(`span`,{className:`font-mono text-[10.5px] text-muted-foreground`,children:[r,r&&i?` · `:null,i?(0,U.jsx)(`span`,{style:{color:h(`warning`)},children:K(i,`lifecycle warning`)}):null]}):null]})})}function X({issues:e,kind:t}){return e.length?(0,U.jsx)(U.Fragment,{children:e.map(e=>(0,U.jsx)(v,{variant:e.severity===`error`?`destructive`:`default`,className:`px-3 py-2`,children:(0,U.jsxs)(A,{className:`flex flex-wrap items-baseline gap-x-2 gap-y-0.5`,children:[(0,U.jsx)(`span`,{className:`font-mono text-[10.5px]`,style:{color:h(e.severity)},children:t===`lifecycle`?`lifecycle`:e.severity}),(0,U.jsx)(`span`,{children:e.message})]})},`${t}-${e.code}-${e.message}`))}):null}function Z({label:e,links:t,onOpen:n}){return t.length?(0,U.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,U.jsx)(`span`,{className:`text-[10px] font-medium uppercase tracking-wide text-muted-foreground`,children:e}),t.map(t=>{let r=!t.exists&&!t.title;return(0,U.jsx)(y,{asChild:!0,variant:`outline`,size:`sm`,className:`gap-2 rounded-lg px-2.5 py-2 text-left hover:border-ring disabled:pointer-events-none disabled:opacity-50`,children:(0,U.jsxs)(`button`,{type:`button`,disabled:r,onClick:()=>n(t.id),children:[(0,U.jsx)(`span`,{className:`w-[78px] shrink-0 truncate font-mono text-[11px] font-medium`,children:t.id}),(0,U.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-xs text-muted-foreground`,children:t.title||`Missing record`}),t.relation||t.kind?(0,U.jsx)(w,{variant:`secondary`,className:`h-[18px] rounded-md px-1.5 font-mono text-[10px] font-medium`,children:t.relation||t.kind}):null]})},`${e}-${t.id}`)})]}):null}function Q({message:e}){return e?(0,U.jsx)(v,{variant:`destructive`,className:`px-3 py-2`,children:(0,U.jsx)(A,{children:e})}):null}function le({schema:e,initialCollection:t,onClose:n,onCreated:r}){let i=e.collections.find(e=>e.id===t)||e.collections[0],[a,o]=(0,H.useState)({collection:i?.id||`learnings`,status:i?.statuses[0]||`active`,title:``,category:``,confidence:``,severity:``,expires:``,body:``}),[s,c]=(0,H.useState)(!1),[l,u]=(0,H.useState)(``),d=e.collections.find(e=>e.id===a.collection),p=q(a.collection),m=(e,t)=>o(n=>({...n,[e]:t})),h=t=>{let n=e.collections.find(e=>e.id===t);o(e=>({...e,collection:t,status:n?.statuses[0]||`active`}))},v=async()=>{c(!0);try{r((await S.createMemory({collection:a.collection,title:a.title,status:a.status,body:a.body,category:a.category||void 0,confidence:a.confidence||void 0,severity:a.severity||void 0,expires:a.expires||void 0})).record)}catch(e){u(e instanceof Error?e.message:String(e))}finally{c(!1)}};return(0,U.jsx)(O,{open:!0,onOpenChange:e=>{e||n()},children:(0,U.jsxs)(I,{className:`sm:max-w-[520px]`,"aria-describedby":void 0,children:[(0,U.jsx)(j,{children:(0,U.jsxs)(L,{children:[`New `,d?.singular||`record`]})}),(0,U.jsxs)(`div`,{className:`-m-1 flex max-h-[65vh] flex-col gap-3 overflow-y-auto p-1`,children:[(0,U.jsxs)(`div`,{className:`grid grid-cols-2 gap-2.5`,children:[(0,U.jsx)(Y,{id:`memory-create-collection`,label:`Collection`,children:(0,U.jsx)(_,{id:`memory-create-collection`,value:a.collection,onChange:e=>h(e.target.value),children:e.collections.map(e=>(0,U.jsx)(g,{value:e.id,children:e.id},e.id))})}),(0,U.jsx)(Y,{id:`memory-create-status`,label:`Status`,children:(0,U.jsx)(_,{id:`memory-create-status`,value:a.status,onChange:e=>m(`status`,e.target.value),children:(d?.statuses||[]).map(e=>(0,U.jsx)(g,{value:e,children:e},e))})})]}),(0,U.jsx)(Y,{id:`memory-create-title`,label:`Title`,children:(0,U.jsx)(x,{id:`memory-create-title`,autoFocus:!0,required:!0,maxLength:120,value:a.title,onChange:e=>m(`title`,e.target.value)})}),p.category||p.confidence||p.severity||p.expires?(0,U.jsxs)(`div`,{className:`grid grid-cols-2 gap-2.5`,children:[p.category?(0,U.jsx)(Y,{id:`memory-create-category`,label:`Category`,children:(0,U.jsx)(x,{id:`memory-create-category`,value:a.category,onChange:e=>m(`category`,e.target.value)})}):null,p.confidence?(0,U.jsx)(Y,{id:`memory-create-confidence`,label:`Confidence`,children:(0,U.jsxs)(_,{id:`memory-create-confidence`,value:a.confidence,onChange:e=>m(`confidence`,e.target.value),children:[(0,U.jsx)(g,{value:``,children:`not set`}),W.map(e=>(0,U.jsx)(g,{value:e,children:e},e))]})}):null,p.severity?(0,U.jsx)(Y,{id:`memory-create-severity`,label:`Severity`,children:(0,U.jsxs)(_,{id:`memory-create-severity`,value:a.severity,onChange:e=>m(`severity`,e.target.value),children:[(0,U.jsx)(g,{value:``,children:`not set`}),G.map(e=>(0,U.jsx)(g,{value:e,children:e},e))]})}):null,p.expires?(0,U.jsx)(Y,{id:`memory-create-expires`,label:`Expires`,children:(0,U.jsx)(x,{id:`memory-create-expires`,type:`date`,value:a.expires,onChange:e=>m(`expires`,e.target.value)})}):null]}):null,(0,U.jsx)(Y,{id:`memory-create-body`,label:`Details`,children:(0,U.jsx)(B,{id:`memory-create-body`,rows:8,value:a.body,onChange:e=>m(`body`,e.target.value)})}),(0,U.jsx)(Q,{message:l})]}),(0,U.jsxs)(k,{children:[(0,U.jsx)(f,{type:`button`,variant:`outline`,onClick:n,children:`Cancel`}),(0,U.jsx)(f,{type:`button`,disabled:s||!a.title.trim(),onClick:()=>void v(),children:s?(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(T,{"aria-hidden":`true`}),`Saving…`]}):`Create record`})]})]})})}function ue({record:e,statuses:t,onClose:n,onUpdated:r}){let i=q(e.collection),[a,o]=(0,H.useState)({title:e.title,status:e.status,category:e.category||``,confidence:e.confidence||``,severity:e.severity||``,expires:e.expires||``,review_after:e.review_after||``,body:e.body}),[s,c]=(0,H.useState)(!1),[l,u]=(0,H.useState)(``),d=(e,t)=>o(n=>({...n,[e]:t})),p=async()=>{let t={};a.title.trim()&&a.title!==e.title&&(t.title=a.title),a.status!==e.status&&(t.status=a.status),a.body!==e.body&&(t.body=a.body);for(let n of[`category`,`confidence`,`severity`,`expires`,`review_after`])a[n]!==(e[n]||``)&&(t[n]=a[n]||null);if(!Object.keys(t).length){n();return}c(!0);try{r((await S.patchMemory(e.id,t,e.revision)).record),n()}catch(e){u(e instanceof Error?e.message:String(e))}finally{c(!1)}};return(0,U.jsx)(O,{open:!0,onOpenChange:e=>{e||n()},children:(0,U.jsxs)(I,{className:`sm:max-w-[520px]`,"aria-describedby":void 0,children:[(0,U.jsx)(j,{children:(0,U.jsxs)(L,{children:[`Edit `,e.id]})}),(0,U.jsxs)(`div`,{className:`-m-1 flex max-h-[65vh] flex-col gap-3 overflow-y-auto p-1`,children:[(0,U.jsx)(Y,{id:`memory-edit-title`,label:`Title`,children:(0,U.jsx)(x,{id:`memory-edit-title`,autoFocus:!0,required:!0,maxLength:120,value:a.title,onChange:e=>d(`title`,e.target.value)})}),(0,U.jsxs)(`div`,{className:`grid grid-cols-2 gap-2.5`,children:[(0,U.jsx)(Y,{id:`memory-edit-status`,label:`Status`,children:(0,U.jsx)(_,{id:`memory-edit-status`,value:a.status,onChange:e=>d(`status`,e.target.value),children:(t.includes(a.status)?t:[a.status,...t]).map(e=>(0,U.jsx)(g,{value:e,children:e},e))})}),i.category?(0,U.jsx)(Y,{id:`memory-edit-category`,label:`Category`,children:(0,U.jsx)(x,{id:`memory-edit-category`,value:a.category,onChange:e=>d(`category`,e.target.value)})}):null,i.confidence?(0,U.jsx)(Y,{id:`memory-edit-confidence`,label:`Confidence`,children:(0,U.jsxs)(_,{id:`memory-edit-confidence`,value:a.confidence,onChange:e=>d(`confidence`,e.target.value),children:[(0,U.jsx)(g,{value:``,children:`not set`}),W.map(e=>(0,U.jsx)(g,{value:e,children:e},e))]})}):null,i.severity?(0,U.jsx)(Y,{id:`memory-edit-severity`,label:`Severity`,children:(0,U.jsxs)(_,{id:`memory-edit-severity`,value:a.severity,onChange:e=>d(`severity`,e.target.value),children:[(0,U.jsx)(g,{value:``,children:`not set`}),G.map(e=>(0,U.jsx)(g,{value:e,children:e},e))]})}):null,i.expires?(0,U.jsx)(Y,{id:`memory-edit-expires`,label:`Expires`,children:(0,U.jsx)(x,{id:`memory-edit-expires`,type:`date`,value:a.expires,onChange:e=>d(`expires`,e.target.value)})}):null,i.review_after?(0,U.jsx)(Y,{id:`memory-edit-review-after`,label:`Review after`,children:(0,U.jsx)(x,{id:`memory-edit-review-after`,type:`date`,value:a.review_after,onChange:e=>d(`review_after`,e.target.value)})}):null]}),(0,U.jsx)(Y,{id:`memory-edit-body`,label:`Details`,children:(0,U.jsx)(B,{id:`memory-edit-body`,rows:10,value:a.body,onChange:e=>d(`body`,e.target.value)})}),(0,U.jsx)(Q,{message:l})]}),(0,U.jsxs)(k,{children:[(0,U.jsx)(f,{type:`button`,variant:`outline`,onClick:n,children:`Cancel`}),(0,U.jsx)(f,{type:`button`,disabled:s||!a.title.trim(),onClick:()=>void p(),children:s?(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(T,{"aria-hidden":`true`}),`Saving…`]}):`Save changes`})]})]})})}function de({record:e,mode:t,onClose:n,onUpdated:r}){let[i,a]=(0,H.useState)(``),[o,s]=(0,H.useState)(!1),[c,l]=(0,H.useState)(``),u=async()=>{s(!0);try{r((t===`graduate`?await S.graduateMemory(e.id,i.split(`,`).map(e=>e.trim()).filter(Boolean),e.revision):await S.supersedeMemory(e.id,i.trim(),e.revision)).record),n()}catch(e){l(e instanceof Error?e.message:String(e))}finally{s(!1)}};return(0,U.jsx)(O,{open:!0,onOpenChange:e=>{e||n()},children:(0,U.jsxs)(I,{className:`sm:max-w-[420px]`,"aria-describedby":void 0,children:[(0,U.jsx)(j,{children:(0,U.jsxs)(L,{children:[t===`graduate`?`Graduate`:`Supersede`,` `,e.id]})}),(0,U.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,U.jsx)(Y,{id:`memory-lifecycle-target`,label:t===`graduate`?`Target IDs`:`Replacement ID`,children:(0,U.jsx)(x,{id:`memory-lifecycle-target`,autoFocus:!0,placeholder:t===`graduate`?`CONV-0001, DOC-0004`:`ADR-0009`,value:i,onChange:e=>a(e.target.value)})}),(0,U.jsx)(Q,{message:c})]}),(0,U.jsxs)(k,{children:[(0,U.jsx)(f,{type:`button`,variant:`outline`,onClick:n,children:`Cancel`}),(0,U.jsx)(f,{type:`button`,disabled:o||!i.trim(),onClick:()=>void u(),children:o?(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(T,{"aria-hidden":`true`}),`Saving…`]}):`Apply`})]})]})})}function fe({record:e,statuses:t,onOpenRelation:n,onOpenRecord:i,onUpdated:a,onDialogOpenChange:o}){let[l,d]=(0,H.useState)(!1),[p,m]=(0,H.useState)(``),g=l||!!p;(0,H.useEffect)(()=>{o?.(g)},[g,o]);let _=e.collection===`learnings`&&e.status!==`graduated`,v=[`learnings`,`decisions`,`conventions`].includes(e.collection),y=[[`status`,e.status,u(e.status)]];return e.category&&y.push([`category`,e.category]),e.confidence&&y.push([`confidence`,e.confidence]),e.severity&&y.push([`severity`,e.severity,h(e.severity)]),e.occurrences!=null&&y.push([`occurrences`,String(e.occurrences)]),e.expires&&y.push([`expires`,e.expires]),e.review_after&&y.push([`review after`,e.review_after]),e.started_at&&y.push([`started`,e.started_at]),e.resolved_at&&y.push([`resolved`,e.resolved_at]),e.graduated_to?.length&&y.push([`graduated to`,e.graduated_to.join(`, `)]),e.superseded_by?.length&&y.push([`superseded by`,e.superseded_by.join(`, `)]),e.owners?.length&&y.push([`owners`,e.owners.join(`, `)]),y.push([`updated`,e.updated||`—`]),(0,U.jsxs)(`aside`,{"aria-label":`Memory record`,className:`flex min-h-0 flex-col overflow-hidden border-l bg-background`,children:[(0,U.jsxs)(`div`,{className:`flex h-11 shrink-0 items-center gap-2 border-b px-3.5`,children:[(0,U.jsx)(`span`,{className:`font-mono text-[11px] text-muted-foreground`,children:e.id}),(0,U.jsx)(`span`,{className:`font-mono text-[11px] text-muted-foreground/60`,children:`·`}),(0,U.jsx)(`span`,{className:`font-mono text-[11px] text-muted-foreground`,children:e.collection}),(0,U.jsx)(`span`,{className:`font-mono text-[11px] text-muted-foreground/60`,children:`·`}),(0,U.jsx)(`span`,{className:`font-mono text-[11px]`,style:{color:u(e.status)},children:e.status})]}),(0,U.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col gap-3.5 overflow-y-auto p-4`,children:[(0,U.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,U.jsx)(`h2`,{className:`m-0 text-[17px] font-semibold leading-[1.3] tracking-[-0.01em] [text-wrap:pretty]`,children:e.title}),e.path?(0,U.jsx)(`span`,{className:`break-all font-mono text-[10.5px] text-muted-foreground`,children:e.path}):null]}),(0,U.jsx)(`div`,{className:`grid grid-cols-2 gap-x-3 gap-y-2`,children:y.map(([e,t,n])=>(0,U.jsxs)(`span`,{className:`flex flex-col gap-0.5`,children:[(0,U.jsx)(`span`,{className:`text-[10px] font-medium uppercase tracking-wide text-muted-foreground`,children:e}),(0,U.jsx)(`span`,{className:`text-sm`,style:n?{color:n}:void 0,children:t})]},e))}),(0,U.jsx)(X,{issues:e.issues,kind:`validation`}),(0,U.jsx)(X,{issues:e.lifecycleIssues||[],kind:`lifecycle`}),(0,U.jsx)(V,{className:`[--typeset-size:0.875rem]`,source:e.body||`No details recorded.`,onOpen:i}),(0,U.jsx)(Z,{label:`Links to`,links:e.outgoing,onOpen:n}),(0,U.jsx)(Z,{label:`Backlinks`,links:e.incoming,onOpen:n}),(0,U.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,U.jsxs)(f,{type:`button`,variant:`outline`,size:`sm`,onClick:()=>d(!0),children:[(0,U.jsx)(c,{"aria-hidden":`true`}),`Edit`]}),_?(0,U.jsxs)(f,{type:`button`,variant:`outline`,size:`sm`,onClick:()=>m(`graduate`),children:[(0,U.jsx)(s,{"aria-hidden":`true`}),`Graduate`]}):null,v?(0,U.jsxs)(f,{type:`button`,variant:`outline`,size:`sm`,onClick:()=>m(`supersede`),children:[(0,U.jsx)(r,{"aria-hidden":`true`}),`Supersede`]}):null]})]}),l?(0,U.jsx)(ue,{record:e,statuses:t,onClose:()=>d(!1),onUpdated:a}):null,p?(0,U.jsx)(de,{record:e,mode:p,onClose:()=>m(``),onUpdated:a}):null]})}function $(e,t){return e.find(e=>e.id===t)?.statuses||[]}function pe({selectedId:e,onSelect:t,onOpenRecord:n,schema:r}){let[o,s]=(0,H.useState)([]),[c,l]=(0,H.useState)(``),[h,g]=(0,H.useState)(``),[_,y]=(0,H.useState)(``),[b,x]=(0,H.useState)(!0),[C,E]=(0,H.useState)(``),[D,O]=(0,H.useState)(null),[k,j]=(0,H.useState)(()=>localStorage.getItem(`workfile-memory-drawer`)===`expanded`);(0,H.useEffect)(()=>{localStorage.setItem(`workfile-memory-drawer`,k?`expanded`:`normal`)},[k]);let I=(0,H.useRef)(!1),L=(0,H.useRef)(0),R=(0,H.useCallback)(e=>{L.current=performance.now(),t(e)},[t]),[z,B]=(0,H.useState)(0);F(e=>{te(e,`/memory/`)&&B(e=>e+1)}),(0,H.useEffect)(()=>{let e=async()=>{x(!0);try{let e=await S.memory(c.trim(),{collection:h||void 0,status:_||void 0});s(e.records),E(``)}catch(e){E(e instanceof Error?e.message:String(e))}finally{x(!1)}},t=window.setTimeout(()=>void e(),c?180:0);return()=>window.clearTimeout(t)},[c,h,_,z]);let V=(0,H.useMemo)(()=>[...o].sort((e,t)=>String(t.updated||``).localeCompare(String(e.updated||``))||e.title.localeCompare(t.title)),[o]),W=(0,H.useMemo)(()=>{let e=r.collections.filter(e=>!h||e.id===h).map(e=>({schema:e,records:V.filter(t=>t.collection===e.id)})),t=new Set(r.collections.map(e=>e.id)),n=V.filter(e=>!t.has(e.collection));return n.length&&e.push({schema:{id:`other`,singular:`record`,idPrefix:`?`,statuses:[]},records:n}),e},[r.collections,V,h]),G=V.find(t=>t.id===e),q=h?$(r.collections,h):[...new Set(r.collections.flatMap(e=>e.statuses))];return(0,U.jsxs)(U.Fragment,{children:[(0,U.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2 px-3.5 pt-3.5`,children:[(0,U.jsxs)(N,{className:`w-full min-w-[180px] sm:w-[260px]`,children:[(0,U.jsx)(M,{children:(0,U.jsx)(a,{"aria-hidden":`true`})}),(0,U.jsx)(re,{type:`search`,"aria-label":`Search workfile memory`,placeholder:`Search decisions, incidents, learnings…`,value:c,onChange:e=>l(e.target.value)})]}),(0,U.jsx)(J,{label:`collection`,value:h,options:r.collections.map(e=>({value:e.id})),onChange:e=>{g(e),y(``)}}),(0,U.jsx)(J,{label:`status`,value:_,options:q.map(e=>({value:e,color:u(e)})),onChange:y}),(0,U.jsx)(`span`,{className:`ml-auto flex shrink-0 items-center gap-1.5 whitespace-nowrap font-mono text-[11px] text-muted-foreground`,children:b?(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(T,{"aria-hidden":`true`,className:`size-3`}),`loading…`]}):K(o.length,`record`)})]}),C?(0,U.jsx)(v,{variant:`destructive`,className:`mx-3.5 mt-3 w-auto px-3 py-2`,children:(0,U.jsxs)(A,{children:[`Memory could not be loaded: `,C]})}):null,(0,U.jsx)(`div`,{className:`flex min-h-0 flex-1 gap-3 overflow-hidden p-3.5`,children:(0,U.jsx)(`div`,{className:`flex min-h-0 flex-1 gap-3 overflow-x-auto`,children:W.map(t=>(0,U.jsxs)(P,{className:`w-[272px] flex-none gap-0 overflow-hidden rounded-xl py-0 [--card-spacing:--spacing(2)]`,children:[(0,U.jsxs)(ne,{className:`flex flex-row items-center gap-2 border-b px-3 py-2`,children:[(0,U.jsx)(`span`,{className:`font-mono text-[11px] font-medium text-primary`,children:t.schema.idPrefix}),(0,U.jsx)(`span`,{className:`flex-1 text-[12.5px] font-semibold`,children:oe(t.schema.singular)}),(0,U.jsx)(w,{variant:`secondary`,className:`h-5 px-1.5 font-mono text-[11px] font-normal`,children:t.records.length}),t.schema.id===`other`?null:(0,U.jsx)(f,{type:`button`,variant:`ghost`,size:`icon-xs`,"aria-label":`New ${t.schema.singular}`,onClick:()=>O(t.schema.id),children:(0,U.jsx)(i,{"aria-hidden":`true`})})]}),(0,U.jsxs)(ee,{className:d(`flex min-h-0 flex-1 flex-col gap-2 overflow-y-auto p-2.5`,ae),children:[t.records.map(t=>(0,U.jsx)(ce,{record:t,selected:t.id===e,onSelect:()=>R(t.id)},t.id)),!t.records.length&&!b?(0,U.jsx)(m,{className:`gap-1 border border-dashed p-4 md:p-6`,children:(0,U.jsx)(p,{className:`font-mono text-xs`,children:`no records`})}):null]})]},t.schema.id))})}),(0,U.jsx)(ie,{open:!!G,expanded:k,label:`record`,description:`Details and lifecycle for the selected memory record.`,onOpenChange:e=>{e||t(``)},onExpandedChange:j,holdOpen:()=>I.current||performance.now()-L.current<200,children:G?(0,U.jsx)(fe,{record:G,statuses:$(r.collections,G.collection),onOpenRelation:e=>{o.some(t=>t.id===e)?R(e):n(e)},onOpenRecord:n,onUpdated:e=>s(t=>t.map(t=>t.id===e.id?e:t)),onDialogOpenChange:e=>{I.current=e}},G.id):null}),D===null?null:(0,U.jsx)(le,{schema:r,initialCollection:D,onClose:()=>O(null),onCreated:e=>{O(null),s(t=>[e,...t]),t(e.id)}})]})}export{pe as MemoryView}; |
| import{n as e}from"./rolldown-runtime-CbXtAM7H.js";import{i as t,t as n}from"./react-Buq45Vzz.js";import{W as r,Y as i,yt as a}from"./ui-primitives-wYj92QGw.js";import{a as o,f as s,i as c,m as l,n as u,o as d,p as f,r as p,s as m,t as h}from"./empty-BHqXimMR.js";import{W as g,a as _,x as v}from"./index-F1UmdPYw.js";import{t as y}from"./layout-QiuZ_k5v.js";import{t as b}from"./progress-CKc41PRw.js";var x=e(t(),1),S=n(),C=[{key:`N`,label:`Move to next`,status:`next`},{key:`D`,label:`Defer`,status:`deferred`},{key:`X`,label:`Discard`,status:`discarded`}];function w({tasks:e,repoRoot:t,repoUrl:n,onPatch:w,onOpen:T}){let[E,D]=(0,x.useState)(()=>new Set),[O,k]=(0,x.useState)(0),A=(0,x.useMemo)(()=>e.filter(e=>!E.has(e.id)),[E,e]),j=A[O]||A[0],M=e.length;(0,x.useEffect)(()=>{O>=A.length&&k(Math.max(0,A.length-1))},[O,A.length]);let N=(0,x.useCallback)(async(e,t=!0)=>{if(j){try{await w(j.id,e)}catch{return}t&&(D(e=>new Set(e).add(j.id)),k(e=>Math.min(e,Math.max(0,A.length-2))))}},[w,A.length,j]);(0,x.useEffect)(()=>{let e=e=>{if(e.ctrlKey||e.metaKey||e.altKey)return;let t=e.target;if([`INPUT`,`SELECT`,`TEXTAREA`].includes(t.tagName)||t.isContentEditable)return;let n=e.key.toUpperCase();if(n===`J`||e.key===`ArrowDown`)e.preventDefault(),k(e=>Math.min(A.length-1,e+1));else if(n===`K`||e.key===`ArrowUp`)e.preventDefault(),k(e=>Math.max(0,e-1));else if(/^[1-4]$/.test(n))e.preventDefault(),N({priority:_[Number(n)-1]},!1);else{let t=C.find(e=>e.key===n);t&&(e.preventDefault(),N({status:t.status}))}};return document.addEventListener(`keydown`,e),()=>document.removeEventListener(`keydown`,e)},[N,A.length]);let P=e=>n?`${n.replace(/\/+$/,``)}/blob/main/${e}`:`vscode://file${t}/${e}`;return j?(0,S.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col overflow-y-auto`,children:[(0,S.jsxs)(`div`,{className:`flex items-center gap-2.5 border-b bg-card px-3.5 py-2.5`,children:[(0,S.jsx)(b,{value:M?E.size/M*100:0,className:`max-w-[340px] flex-1`}),(0,S.jsxs)(`span`,{className:`font-mono text-[11px] text-muted-foreground`,children:[E.size,` of `,M,` processed`]}),(0,S.jsx)(`span`,{className:`flex-1`}),(0,S.jsxs)(f,{type:`button`,variant:`outline`,size:`sm`,disabled:O===0,onClick:()=>k(e=>Math.max(0,e-1)),children:[(0,S.jsx)(g,{children:`K`}),`Previous`]}),(0,S.jsxs)(`span`,{className:`font-mono text-[11px] text-muted-foreground tabular-nums`,children:[O+1,` / `,A.length]}),(0,S.jsxs)(f,{type:`button`,variant:`outline`,size:`sm`,disabled:O>=A.length-1,onClick:()=>k(e=>Math.min(A.length-1,e+1)),children:[(0,S.jsx)(g,{children:`J`}),`Next`]}),(0,S.jsxs)(f,{type:`button`,variant:`outline`,size:`sm`,onClick:()=>T(j.id),children:[(0,S.jsx)(i,{"aria-hidden":`true`}),`Open full card`]})]}),(0,S.jsxs)(`div`,{className:l(y,`px-6 py-7 sm:px-8`),children:[(0,S.jsxs)(`div`,{className:`flex items-center gap-2 font-mono text-[11px] text-muted-foreground`,children:[(0,S.jsx)(`span`,{children:j.id}),(0,S.jsx)(`span`,{className:`text-muted-foreground/60`,children:`·`}),(0,S.jsx)(`span`,{style:{color:s(j.status)},children:j.status}),(0,S.jsx)(`span`,{className:`text-muted-foreground/60`,children:`·`}),(0,S.jsx)(`span`,{children:j.area}),(0,S.jsx)(`span`,{className:`text-muted-foreground/60`,children:`·`}),(0,S.jsx)(`span`,{children:j.type})]}),(0,S.jsx)(`h2`,{className:`mt-3 mb-1 text-[26px] leading-[1.2] font-semibold tracking-tight [text-wrap:pretty]`,children:j.title}),j.file?(0,S.jsx)(`a`,{className:`font-mono text-[11px] text-muted-foreground/70 underline underline-offset-[3px]`,href:P(j.file),target:n?`_blank`:void 0,rel:n?`noreferrer`:void 0,children:j.file}):null,j.source?(0,S.jsxs)(`span`,{className:`mt-[3px] block font-mono text-[11px] text-muted-foreground/70`,children:[`source`,` `,(0,S.jsx)(`a`,{className:`font-mono underline underline-offset-[3px]`,href:P(j.source),target:n?`_blank`:void 0,rel:n?`noreferrer`:void 0,children:j.source})]}):null,(0,S.jsx)(`div`,{className:`mt-[22px]`,children:(0,S.jsx)(v,{source:j.body,onOpen:T})}),(0,S.jsxs)(`div`,{className:`mt-[30px] flex flex-wrap gap-2 border-t pt-[18px]`,children:[_.map((e,t)=>(0,S.jsxs)(f,{type:`button`,variant:`outline`,"aria-pressed":j.priority===e,style:j.priority===e?{borderColor:m(e)}:void 0,onClick:()=>void N({priority:e},!1),children:[(0,S.jsx)(g,{children:t+1}),(0,S.jsx)(`span`,{style:{color:m(e)},children:e})]},e)),C.map(e=>(0,S.jsxs)(f,{type:`button`,variant:`outline`,onClick:()=>void N({status:e.status}),children:[(0,S.jsx)(g,{children:e.key}),(0,S.jsx)(`span`,{style:{color:s(e.status)},children:e.label})]},e.key))]}),(0,S.jsx)(`span`,{className:`mt-3.5 block text-xs text-muted-foreground`,children:`Every action writes the card's frontmatter to disk immediately. Shortcuts work while focus is outside a form.`})]})]}):(0,S.jsxs)(h,{className:`gap-3 p-10`,children:[(0,S.jsxs)(c,{children:[(0,S.jsx)(o,{children:(0,S.jsx)(a,{"aria-hidden":`true`,size:20,style:{color:s(`done`)}})}),(0,S.jsx)(d,{className:`text-sm`,children:`Queue clear`}),(0,S.jsxs)(p,{className:`text-[12.5px]`,children:[`You processed `,E.size.toLocaleString(),` cards.`]})]}),(0,S.jsx)(u,{children:(0,S.jsxs)(f,{type:`button`,variant:`outline`,size:`sm`,onClick:()=>{D(new Set),k(0)},children:[(0,S.jsx)(r,{"aria-hidden":`true`}),`Start again`]})})]})}export{w as TriageView}; |
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
1825731
1.32%21905
1.47%