vibedoc 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-build-manifest.json +23 -19
  3. package/.next/app-path-routes-manifest.json +1 -1
  4. package/.next/build-manifest.json +2 -2
  5. package/.next/prerender-manifest.js +1 -1
  6. package/.next/prerender-manifest.json +1 -1
  7. package/.next/server/app/(app)/activity/page_client-reference-manifest.js +1 -1
  8. package/.next/server/app/(app)/board/page_client-reference-manifest.js +1 -1
  9. package/.next/server/app/(app)/docs/page.js +1 -1
  10. package/.next/server/app/(app)/docs/page_client-reference-manifest.js +1 -1
  11. package/.next/server/app/(app)/memory/page_client-reference-manifest.js +1 -1
  12. package/.next/server/app/(app)/settings/page_client-reference-manifest.js +1 -1
  13. package/.next/server/app/(app)/setup/page.js +2 -1
  14. package/.next/server/app/(app)/setup/page.js.nft.json +1 -1
  15. package/.next/server/app/(app)/setup/page_client-reference-manifest.js +1 -1
  16. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  17. package/.next/server/app/_not-found.html +1 -1
  18. package/.next/server/app/_not-found.rsc +1 -1
  19. package/.next/server/app/activity.html +1 -1
  20. package/.next/server/app/activity.rsc +2 -2
  21. package/.next/server/app/api/mcp/route.js +2 -2
  22. package/.next/server/app/api/mcp/route.js.nft.json +1 -1
  23. package/.next/server/app/api/setup/generate/route.js +7 -7
  24. package/.next/server/app/api/setup/generate/route.js.nft.json +1 -1
  25. package/.next/server/app/board.html +1 -1
  26. package/.next/server/app/board.rsc +2 -2
  27. package/.next/server/app/docs.html +1 -1
  28. package/.next/server/app/docs.rsc +3 -3
  29. package/.next/server/app/index.html +1 -1
  30. package/.next/server/app/index.rsc +1 -1
  31. package/.next/server/app/memory.html +1 -1
  32. package/.next/server/app/memory.rsc +2 -2
  33. package/.next/server/app/page_client-reference-manifest.js +1 -1
  34. package/.next/server/app/settings.html +1 -1
  35. package/.next/server/app/settings.rsc +2 -2
  36. package/.next/server/app/setup.html +1 -1
  37. package/.next/server/app/setup.rsc +3 -3
  38. package/.next/server/app-paths-manifest.json +10 -10
  39. package/.next/server/chunks/118.js +2107 -0
  40. package/.next/server/chunks/191.js +1558 -501
  41. package/.next/server/middleware-build-manifest.js +1 -1
  42. package/.next/server/pages/404.html +1 -1
  43. package/.next/server/pages/500.html +1 -1
  44. package/.next/server/pages-manifest.json +1 -1
  45. package/.next/server/server-reference-manifest.js +1 -1
  46. package/.next/server/server-reference-manifest.json +1 -1
  47. package/.next/static/chunks/5179-76391417caead0bc.js +1 -0
  48. package/.next/static/chunks/6441-8a1066f99fe4fead.js +1 -0
  49. package/.next/static/chunks/app/(app)/docs/{page-17670ed46c3594e6.js → page-f5615cefbd3d1c64.js} +1 -1
  50. package/.next/static/chunks/app/(app)/{layout-34b4046ccf919d3f.js → layout-ef459e6f184dba6b.js} +1 -1
  51. package/.next/static/chunks/app/(app)/setup/page-a47e3a9a44666f50.js +1 -0
  52. package/.next/static/css/48c54dd7bfa2411e.css +5 -0
  53. package/package.json +1 -1
  54. package/.next/server/chunks/661.js +0 -1050
  55. package/.next/static/chunks/845-f90ef49ed88a44a2.js +0 -1
  56. package/.next/static/chunks/app/(app)/setup/page-5fd7500bd578e730.js +0 -1
  57. package/.next/static/css/518ce8dddf398f57.css +0 -5
  58. /package/.next/static/{moF7Sng2pYdyIpULgHRjM → SozubT4AiNYJ3ynkRV0zo}/_buildManifest.js +0 -0
  59. /package/.next/static/{moF7Sng2pYdyIpULgHRjM → SozubT4AiNYJ3ynkRV0zo}/_ssgManifest.js +0 -0
@@ -1,4 +1,4 @@
1
- exports.id=191,exports.ids=[191],exports.modules={1562:(e,t,a)=>{Promise.resolve().then(a.t.bind(a,9388,23)),Promise.resolve().then(a.t.bind(a,1152,23)),Promise.resolve().then(a.t.bind(a,2764,23)),Promise.resolve().then(a.t.bind(a,6894,23)),Promise.resolve().then(a.t.bind(a,3299,23)),Promise.resolve().then(a.t.bind(a,184,23))},9788:(e,t,a)=>{Promise.resolve().then(a.bind(a,151))},103:()=>{},151:(e,t,a)=>{"use strict";a.r(t),a.d(t,{default:()=>eh});var s=a(7486),r=a(618),n=a(6811),i=a(6266);function o(){return s.jsx("div",{className:"min-h-screen flex items-center justify-center",children:(0,s.jsxs)("div",{className:"text-center",children:[s.jsx("div",{className:"flex gap-1.5 justify-center mb-4",children:[0,1,2].map(e=>s.jsx("div",{className:"w-2 h-2 rounded-full bg-accent animate-pulse-dot",style:{animationDelay:`${.15*e}s`}},e))}),s.jsx("p",{className:"text-muted text-sm font-mono",children:"Loading project..."})]})})}var d=a(9228);function l({projects:e,activeProject:t,currentName:a,onSelect:r}){return(0,s.jsxs)(d.h_,{children:[s.jsx(d.$F,{asChild:!0,children:(0,s.jsxs)("button",{className:"flex items-center gap-1.5 px-3 py-1.5 rounded-md bg-surface2 border border-border text-sm hover:border-border2 transition-colors",children:[s.jsx("span",{className:"text-txt font-medium truncate max-w-[200px]",children:a||"Select project"}),s.jsx("span",{className:"text-muted text-xs",children:"▾"})]})}),s.jsx(d.AW,{className:"w-64 bg-surface border-border2 text-txt",align:"start",children:0===e.length?s.jsx("div",{className:"px-3 py-2 text-sm text-muted",children:"No projects found"}):e.map(e=>s.jsx(d.Xi,{onClick:()=>r(e.root),className:`cursor-pointer hover:bg-surface2 focus:bg-surface2 ${e.root===t?"text-accent":""}`,children:(0,s.jsxs)("div",{children:[s.jsx("div",{className:"font-medium",children:e.name}),s.jsx("div",{className:"text-xs text-muted truncate font-mono",children:e.root})]})},e.root))})]})}var c=a(5819);function u({board:e}){return(0,s.jsxs)("div",{className:"flex items-center gap-1.5",children:[(0,s.jsxs)(c.C,{variant:"secondary",className:"gap-1 text-xs font-mono text-amber",children:["\uD83D\uDD28 ",e["in-progress"]||0]}),(0,s.jsxs)(c.C,{variant:"secondary",className:"gap-1 text-xs font-mono text-muted",children:["\uD83D\uDCCB ",e.todo||0]}),(0,s.jsxs)(c.C,{variant:"secondary",className:"gap-1 text-xs font-mono text-teal",children:["✅ ",e.done||0]})]})}var m=a(5098);function p({active:e}){return(0,s.jsxs)("div",{className:"flex items-center gap-1.5 text-xs font-mono text-muted",children:[s.jsx("div",{className:(0,m.cn)("w-1.5 h-1.5 rounded-full transition-colors duration-500",e?"bg-teal shadow-[0_0_6px_#4fd8b4]":"bg-border2")}),s.jsx("span",{children:e?"live update":"connected"})]})}var f=a(8942),h=a(4039),b=a(1317),g=a(3068),x=a(2162),v=a(6637),y=a(2439),N=a(2153);let w=y.fC;y.xz,y.x8;let j=y.h_,k=r.forwardRef(({className:e,...t},a)=>s.jsx(y.aV,{className:(0,m.cn)("fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",e),...t,ref:a}));k.displayName=y.aV.displayName;let C=(0,h.j)("fixed z-50 gap-4 bg-white p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500 dark:bg-slate-950",{variants:{side:{top:"inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",bottom:"inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",left:"inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",right:"inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm"}},defaultVariants:{side:"right"}}),R=r.forwardRef(({side:e="right",className:t,children:a,...r},n)=>(0,s.jsxs)(j,{children:[s.jsx(k,{}),(0,s.jsxs)(y.VY,{ref:n,className:(0,m.cn)(C({side:e}),t),...r,children:[a,(0,s.jsxs)(y.x8,{className:"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-white transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-slate-950 focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-slate-100 dark:ring-offset-slate-950 dark:focus:ring-slate-300 dark:data-[state=open]:bg-slate-800",children:[s.jsx(N.Z,{className:"h-4 w-4"}),s.jsx("span",{className:"sr-only",children:"Close"})]})]})]}));R.displayName=y.VY.displayName;let E=({className:e,...t})=>s.jsx("div",{className:(0,m.cn)("flex flex-col space-y-2 text-center sm:text-left",e),...t});E.displayName="SheetHeader";let S=r.forwardRef(({className:e,...t},a)=>s.jsx(y.Dx,{ref:a,className:(0,m.cn)("text-lg font-semibold text-slate-950 dark:text-slate-50",e),...t}));S.displayName=y.Dx.displayName;let A=r.forwardRef(({className:e,...t},a)=>s.jsx(y.dk,{ref:a,className:(0,m.cn)("text-sm text-slate-500 dark:text-slate-400",e),...t}));function P({className:e,...t}){return s.jsx("div",{className:(0,m.cn)("animate-pulse rounded-md bg-slate-100 dark:bg-slate-800",e),...t})}A.displayName=y.dk.displayName;var T=a(5875);let D=r.createContext(null);function I(){let e=r.useContext(D);if(!e)throw Error("useSidebar must be used within a SidebarProvider.");return e}let _=r.forwardRef(({defaultOpen:e=!0,open:t,onOpenChange:a,className:n,style:i,children:o,...d},l)=>{let c=function(){let[e,t]=r.useState(void 0);return r.useEffect(()=>{let e=window.matchMedia("(max-width: 767px)"),a=()=>{t(window.innerWidth<768)};return e.addEventListener("change",a),t(window.innerWidth<768),()=>e.removeEventListener("change",a)},[]),!!e}(),[u,p]=r.useState(!1),[f,h]=r.useState(e),b=t??f,g=r.useCallback(e=>{let t="function"==typeof e?e(b):e;a?a(t):h(t),document.cookie=`sidebar_state=${t}; path=/; max-age=604800`},[a,b]),x=r.useCallback(()=>c?p(e=>!e):g(e=>!e),[c,g,p]);r.useEffect(()=>{let e=e=>{"b"===e.key&&(e.metaKey||e.ctrlKey)&&(e.preventDefault(),x())};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[x]);let v=b?"expanded":"collapsed",y=r.useMemo(()=>({state:v,open:b,setOpen:g,isMobile:c,openMobile:u,setOpenMobile:p,toggleSidebar:x}),[v,b,g,c,u,p,x]);return s.jsx(D.Provider,{value:y,children:s.jsx(T.pn,{delayDuration:0,children:s.jsx("div",{style:{"--sidebar-width":"16rem","--sidebar-width-icon":"3rem",...i},className:(0,m.cn)("group/sidebar-wrapper flex min-h-svh w-full has-[[data-variant=inset]]:bg-sidebar",n),ref:l,...d,children:o})})})});_.displayName="SidebarProvider";let O=r.forwardRef(({side:e="left",variant:t="sidebar",collapsible:a="offcanvas",className:r,children:n,...i},o)=>{let{isMobile:d,state:l,openMobile:c,setOpenMobile:u}=I();return"none"===a?s.jsx("div",{className:(0,m.cn)("flex h-full w-[--sidebar-width] flex-col bg-sidebar text-sidebar-foreground",r),ref:o,...i,children:n}):d?s.jsx(w,{open:c,onOpenChange:u,...i,children:(0,s.jsxs)(R,{"data-sidebar":"sidebar","data-mobile":"true",className:"w-[--sidebar-width] bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden",style:{"--sidebar-width":"18rem"},side:e,children:[(0,s.jsxs)(E,{className:"sr-only",children:[s.jsx(S,{children:"Sidebar"}),s.jsx(A,{children:"Displays the mobile sidebar."})]}),s.jsx("div",{className:"flex h-full w-full flex-col",children:n})]})}):(0,s.jsxs)("div",{ref:o,className:"group peer hidden text-sidebar-foreground md:block","data-state":l,"data-collapsible":"collapsed"===l?a:"","data-variant":t,"data-side":e,children:[s.jsx("div",{className:(0,m.cn)("relative w-[--sidebar-width] bg-transparent transition-[width] duration-200 ease-linear","group-data-[collapsible=offcanvas]:w-0","group-data-[side=right]:rotate-180","floating"===t||"inset"===t?"group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4))]":"group-data-[collapsible=icon]:w-[--sidebar-width-icon]")}),s.jsx("div",{className:(0,m.cn)("fixed inset-y-0 z-10 hidden h-svh w-[--sidebar-width] transition-[left,right,width] duration-200 ease-linear md:flex","left"===e?"left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]":"right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]","floating"===t||"inset"===t?"p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4)_+2px)]":"group-data-[collapsible=icon]:w-[--sidebar-width-icon] group-data-[side=left]:border-r group-data-[side=right]:border-l",r),...i,children:s.jsx("div",{"data-sidebar":"sidebar",className:"flex h-full w-full flex-col bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:border-sidebar-border group-data-[variant=floating]:shadow",children:n})})]})});O.displayName="Sidebar";let z=r.forwardRef(({className:e,onClick:t,...a},r)=>{let{toggleSidebar:n}=I();return(0,s.jsxs)(g.z,{ref:r,"data-sidebar":"trigger",variant:"ghost",size:"icon",className:(0,m.cn)("h-7 w-7",e),onClick:e=>{t?.(e),n()},...a,children:[s.jsx(b.Z,{}),s.jsx("span",{className:"sr-only",children:"Toggle Sidebar"})]})});z.displayName="SidebarTrigger",r.forwardRef(({className:e,...t},a)=>{let{toggleSidebar:r}=I();return s.jsx("button",{ref:a,"data-sidebar":"rail","aria-label":"Toggle Sidebar",tabIndex:-1,onClick:r,title:"Toggle Sidebar",className:(0,m.cn)("absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] hover:after:bg-sidebar-border group-data-[side=left]:-right-4 group-data-[side=right]:left-0 sm:flex","[[data-side=left]_&]:cursor-w-resize [[data-side=right]_&]:cursor-e-resize","[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize","group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full group-data-[collapsible=offcanvas]:hover:bg-sidebar","[[data-side=left][data-collapsible=offcanvas]_&]:-right-2","[[data-side=right][data-collapsible=offcanvas]_&]:-left-2",e),...t})}).displayName="SidebarRail";let M=r.forwardRef(({className:e,...t},a)=>s.jsx("main",{ref:a,className:(0,m.cn)("relative flex w-full flex-1 flex-col bg-white dark:bg-slate-950","md:peer-data-[variant=inset]:m-2 md:peer-data-[state=collapsed]:peer-data-[variant=inset]:ml-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow",e),...t}));M.displayName="SidebarInset",r.forwardRef(({className:e,...t},a)=>s.jsx(x.I,{ref:a,"data-sidebar":"input",className:(0,m.cn)("h-8 w-full bg-white shadow-none focus-visible:ring-2 focus-visible:ring-sidebar-ring dark:bg-slate-950",e),...t})).displayName="SidebarInput";let U=r.forwardRef(({className:e,...t},a)=>s.jsx("div",{ref:a,"data-sidebar":"header",className:(0,m.cn)("flex flex-col gap-2 p-2",e),...t}));U.displayName="SidebarHeader",r.forwardRef(({className:e,...t},a)=>s.jsx("div",{ref:a,"data-sidebar":"footer",className:(0,m.cn)("flex flex-col gap-2 p-2",e),...t})).displayName="SidebarFooter";let L=r.forwardRef(({className:e,...t},a)=>s.jsx(v.Z,{ref:a,"data-sidebar":"separator",className:(0,m.cn)("mx-2 w-auto bg-sidebar-border",e),...t}));L.displayName="SidebarSeparator";let q=r.forwardRef(({className:e,...t},a)=>s.jsx("div",{ref:a,"data-sidebar":"content",className:(0,m.cn)("flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden",e),...t}));q.displayName="SidebarContent";let B=r.forwardRef(({className:e,...t},a)=>s.jsx("div",{ref:a,"data-sidebar":"group",className:(0,m.cn)("relative flex w-full min-w-0 flex-col p-2",e),...t}));B.displayName="SidebarGroup";let K=r.forwardRef(({className:e,asChild:t=!1,...a},r)=>{let n=t?f.g7:"div";return s.jsx(n,{ref:r,"data-sidebar":"group-label",className:(0,m.cn)("flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium text-sidebar-foreground/70 outline-none ring-sidebar-ring transition-[margin,opacity] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0","group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0",e),...a})});K.displayName="SidebarGroupLabel",r.forwardRef(({className:e,asChild:t=!1,...a},r)=>{let n=t?f.g7:"button";return s.jsx(n,{ref:r,"data-sidebar":"group-action",className:(0,m.cn)("absolute right-3 top-3.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-none ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0","after:absolute after:-inset-2 after:md:hidden","group-data-[collapsible=icon]:hidden",e),...a})}).displayName="SidebarGroupAction";let F=r.forwardRef(({className:e,...t},a)=>s.jsx("div",{ref:a,"data-sidebar":"group-content",className:(0,m.cn)("w-full text-sm",e),...t}));F.displayName="SidebarGroupContent";let G=r.forwardRef(({className:e,...t},a)=>s.jsx("ul",{ref:a,"data-sidebar":"menu",className:(0,m.cn)("flex w-full min-w-0 flex-col gap-1",e),...t}));G.displayName="SidebarMenu";let V=r.forwardRef(({className:e,...t},a)=>s.jsx("li",{ref:a,"data-sidebar":"menu-item",className:(0,m.cn)("group/menu-item relative",e),...t}));V.displayName="SidebarMenuItem";let Z=(0,h.j)("peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-none ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-[[data-sidebar=menu-action]]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:!size-8 group-data-[collapsible=icon]:!p-2 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0",{variants:{variant:{default:"hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",outline:"bg-white shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))] dark:bg-slate-950"},size:{default:"h-8 text-sm",sm:"h-7 text-xs",lg:"h-12 text-sm group-data-[collapsible=icon]:!p-0"}},defaultVariants:{variant:"default",size:"default"}}),$=r.forwardRef(({asChild:e=!1,isActive:t=!1,variant:a="default",size:r="default",tooltip:n,className:i,...o},d)=>{let l=e?f.g7:"button",{isMobile:c,state:u}=I(),p=s.jsx(l,{ref:d,"data-sidebar":"menu-button","data-size":r,"data-active":t,className:(0,m.cn)(Z({variant:a,size:r}),i),...o});return n?("string"==typeof n&&(n={children:n}),(0,s.jsxs)(T.u,{children:[s.jsx(T.aJ,{asChild:!0,children:p}),s.jsx(T._v,{side:"right",align:"center",hidden:"collapsed"!==u||c,...n})]})):p});function W({summary:e,projects:t,activeProject:a,liveIndicator:r,onProjectChange:n}){return(0,s.jsxs)("header",{className:"h-12 border-b border-border flex items-center px-4 gap-4 flex-shrink-0 bg-surface/80 backdrop-blur-sm sticky top-0 z-50",children:[s.jsx(z,{className:"-ml-1"}),s.jsx(v.Z,{orientation:"vertical",className:"mr-2 h-4"}),(0,s.jsxs)("div",{className:"flex items-center gap-2 flex-shrink-0",children:[s.jsx("div",{className:"w-6 h-6 rounded-md bg-gradient-to-br from-accent to-teal flex items-center justify-center text-xs",children:"⬡"}),s.jsx("span",{className:"font-mono text-xs text-muted tracking-widest uppercase",children:"VibeDoc"})]}),s.jsx(l,{projects:t,activeProject:a,currentName:e?.name||"",onSelect:n}),e&&s.jsx(u,{board:e.tasks.board}),s.jsx("div",{className:"flex-1"}),s.jsx(p,{active:r}),(0,s.jsxs)("div",{className:"hidden md:flex items-center gap-1.5 px-2 py-1 rounded bg-surface2 border border-border",children:[s.jsx("span",{className:"text-xs font-mono text-muted",children:"MCP"}),s.jsx("code",{className:"text-xs font-mono text-accent",children:"localhost:3000/api/mcp"})]})]})}$.displayName="SidebarMenuButton",r.forwardRef(({className:e,asChild:t=!1,showOnHover:a=!1,...r},n)=>{let i=t?f.g7:"button";return s.jsx(i,{ref:n,"data-sidebar":"menu-action",className:(0,m.cn)("absolute right-1 top-1.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-none ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 peer-hover/menu-button:text-sidebar-accent-foreground [&>svg]:size-4 [&>svg]:shrink-0","after:absolute after:-inset-2 after:md:hidden","peer-data-[size=sm]/menu-button:top-1","peer-data-[size=default]/menu-button:top-1.5","peer-data-[size=lg]/menu-button:top-2.5","group-data-[collapsible=icon]:hidden",a&&"group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 peer-data-[active=true]/menu-button:text-sidebar-accent-foreground md:opacity-0",e),...r})}).displayName="SidebarMenuAction",r.forwardRef(({className:e,...t},a)=>s.jsx("div",{ref:a,"data-sidebar":"menu-badge",className:(0,m.cn)("pointer-events-none absolute right-1 flex h-5 min-w-5 select-none items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums text-sidebar-foreground","peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground","peer-data-[size=sm]/menu-button:top-1","peer-data-[size=default]/menu-button:top-1.5","peer-data-[size=lg]/menu-button:top-2.5","group-data-[collapsible=icon]:hidden",e),...t})).displayName="SidebarMenuBadge",r.forwardRef(({className:e,showIcon:t=!1,...a},n)=>{let i=r.useMemo(()=>`${Math.floor(40*Math.random())+50}%`,[]);return(0,s.jsxs)("div",{ref:n,"data-sidebar":"menu-skeleton",className:(0,m.cn)("flex h-8 items-center gap-2 rounded-md px-2",e),...a,children:[t&&s.jsx(P,{className:"size-4 rounded-md","data-sidebar":"menu-skeleton-icon"}),s.jsx(P,{className:"h-4 max-w-[--skeleton-width] flex-1","data-sidebar":"menu-skeleton-text",style:{"--skeleton-width":i}})]})}).displayName="SidebarMenuSkeleton",r.forwardRef(({className:e,...t},a)=>s.jsx("ul",{ref:a,"data-sidebar":"menu-sub",className:(0,m.cn)("mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l border-sidebar-border px-2.5 py-0.5","group-data-[collapsible=icon]:hidden",e),...t})).displayName="SidebarMenuSub",r.forwardRef(({...e},t)=>s.jsx("li",{ref:t,...e})).displayName="SidebarMenuSubItem",r.forwardRef(({asChild:e=!1,size:t="md",isActive:a,className:r,...n},i)=>{let o=e?f.g7:"a";return s.jsx(o,{ref:i,"data-sidebar":"menu-sub-button","data-size":t,"data-active":a,className:(0,m.cn)("flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sidebar-foreground outline-none ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground","data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground","sm"===t&&"text-xs","md"===t&&"text-sm","group-data-[collapsible=icon]:hidden",r),...n})}).displayName="SidebarMenuSubButton";var J=a(3596),H=a(7987),Y=a(9529),X=a(8673),Q=a(5314),ee=a(6034),et=a(771),ea=a(4119),es=a(7834),er=a(8165);let en=[{href:"/board",icon:J.Z,label:"Board"},{href:"/docs",icon:H.Z,label:"Docs"},{href:"/activity",icon:Y.Z,label:"Activity"},{href:"/memory",icon:X.Z,label:"Memory"},{href:"/settings",icon:Q.Z,label:"Settings"}],ei=[{status:"in-progress",icon:ee.Z,label:"Active"},{status:"blocked",icon:et.Z,label:"Blocked"},{status:"todo",icon:ea.Z,label:"Todo"},{status:"done",icon:es.Z,label:"Done"}];function eo({board:e}){let t=(0,n.usePathname)();return(0,s.jsxs)(O,{collapsible:"icon",children:[s.jsx(U,{children:(0,s.jsxs)("div",{className:"flex items-center gap-2 px-2 py-1",children:[s.jsx("div",{className:"w-6 h-6 rounded-md bg-gradient-to-br from-accent to-teal flex items-center justify-center text-xs flex-shrink-0",children:"⬡"}),s.jsx("span",{className:"font-mono text-xs text-muted tracking-widest uppercase group-data-[collapsible=icon]:hidden",children:"VibeDoc"})]})}),(0,s.jsxs)(q,{children:[s.jsx(B,{children:s.jsx(F,{children:s.jsx(G,{children:en.map(({href:e,icon:a,label:r})=>s.jsx(V,{children:s.jsx($,{asChild:!0,isActive:t.startsWith(e),tooltip:r,children:(0,s.jsxs)(er.default,{href:e,children:[s.jsx(a,{}),s.jsx("span",{children:r})]})})},e))})})}),e&&(0,s.jsxs)(s.Fragment,{children:[s.jsx(L,{}),(0,s.jsxs)(B,{children:[s.jsx(K,{children:"Board"}),s.jsx(F,{children:s.jsx(G,{children:ei.map(({status:t,icon:a,label:r})=>{let n=e[t]?.length||0;return s.jsx(V,{children:(0,s.jsxs)($,{tooltip:`${r}: ${n}`,children:[s.jsx(a,{}),s.jsx("span",{children:r}),s.jsx("span",{className:"ml-auto font-mono text-xs",children:n})]})},t)})})})]})]})]})]})}var ed=a(2126),el=a(194),ec=a(9516),eu=a(8650),em=a(2119);function ep({open:e,onClose:t,onOpenDoc:a,onNewDoc:i,rootParam:o}){let d=(0,n.useRouter)(),[l,c]=(0,r.useState)(""),[u,p]=(0,r.useState)([]),[f,h]=(0,r.useState)(0),b=[{label:"New Doc",icon:ed.Z,action:()=>{i?.(),t()}},{label:"Go to Board",icon:J.Z,action:()=>{d.push("/board"),t()}},{label:"Go to Activity",icon:el.Z,action:()=>{d.push("/activity"),t()}},{label:"Go to Memory",icon:X.Z,action:()=>{d.push("/memory"),t()}}];function g(e){a(e.path),t()}let v=""===l;return s.jsx(eu.Vq,{open:e,onOpenChange:e=>{e||t()},children:(0,s.jsxs)(eu.cZ,{className:"max-w-lg p-0 overflow-hidden bg-surface border-border gap-0",children:[s.jsx(eu.$N,{className:"sr-only",children:"Command Palette"}),(0,s.jsxs)("div",{className:"flex items-center px-4 h-12",children:[s.jsx(ec.Z,{className:"h-4 w-4 text-muted shrink-0 mr-3"}),s.jsx(x.I,{autoFocus:!0,value:l,onChange:e=>c(e.target.value),onKeyDown:function(e){let t=u.length>0,a=t?u.length:b.length;"ArrowDown"===e.key?(e.preventDefault(),h(e=>Math.min(e+1,a-1))):"ArrowUp"===e.key?(e.preventDefault(),h(e=>Math.max(e-1,0))):"Enter"===e.key&&(t&&u[f]?g(u[f]):!t&&l.length<2&&b[f]&&b[f].action())},placeholder:"Search docs…",className:"border-0 bg-transparent h-full text-sm shadow-none focus-visible:ring-0 px-0 placeholder:text-muted"})]}),s.jsx("div",{className:"border-t border-border"}),(0,s.jsxs)(em.x,{className:"max-h-72",children:[v&&s.jsx("div",{className:"py-1",children:b.map((e,t)=>(0,s.jsxs)("button",{onClick:e.action,onMouseEnter:()=>h(t),className:(0,m.cn)("flex items-center gap-3 w-full px-4 py-2 text-sm text-left transition-colors",f===t?"bg-accent/10 text-txt":"text-muted hover:text-txt"),children:[s.jsx(e.icon,{className:"h-4 w-4 shrink-0"}),e.label]},e.label))}),!v&&u.length>0&&s.jsx("div",{className:"py-1",children:u.map((e,t)=>(0,s.jsxs)("button",{onClick:()=>g(e),onMouseEnter:()=>h(t),className:(0,m.cn)("flex items-center justify-between w-full px-4 py-2 text-sm text-left transition-colors",f===t?"bg-accent/10":"hover:bg-accent/5"),children:[s.jsx("span",{className:"font-medium text-txt truncate",children:e.name}),e.section&&s.jsx("span",{className:"text-xs text-muted ml-3 shrink-0 truncate max-w-[40%]",children:e.section})]},e.path))}),!v&&l.length>=2&&0===u.length&&s.jsx("div",{className:"px-4 py-6 text-center text-sm text-muted",children:"No docs found"})]})]})})}var ef=a(9195);function eh({children:e}){return s.jsx(i.w,{children:s.jsx(eg,{children:e})})}let eb=[{key:"Cmd+K",description:"Open command palette"},{key:"b",description:"Go to Board"},{key:"d",description:"Go to Docs"},{key:"a",description:"Go to Activity"},{key:"m",description:"Go to Memory"},{key:"/",description:"Focus doc search"},{key:"?",description:"Toggle this help"},{key:"Esc",description:"Close panel / modal"}];function eg({children:e}){let{loading:t,summary:a,projects:d,activeProject:l,liveIndicator:c,onProjectChange:u,board:m,openDoc:p,rootParam:f}=(0,i.q)();(0,n.useRouter)(),(0,n.usePathname)();let[h,b]=(0,r.useState)(!1),[g,x]=(0,r.useState)(!1),[v,y]=(0,r.useState)(!1);return t?s.jsx(o,{}):(0,s.jsxs)(_,{children:[s.jsx(eo,{board:m}),(0,s.jsxs)(M,{children:[s.jsx(W,{summary:a,projects:d,activeProject:l,liveIndicator:c,onProjectChange:u}),s.jsx("main",{className:"flex-1 overflow-y-auto",children:e}),s.jsx(ep,{open:g,onClose:()=>x(!1),onOpenDoc:p,onNewDoc:()=>{x(!1),y(!0)},rootParam:f}),s.jsx(ef.t,{open:v,onOpenChange:y,rootParam:f,onDocCreated:async e=>{await p(e)}}),h&&(0,s.jsxs)(s.Fragment,{children:[s.jsx("div",{className:"fixed inset-0 z-50 bg-black/60",onClick:()=>b(!1)}),(0,s.jsxs)("div",{className:"fixed z-50 top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-80 bg-surface border border-border rounded-xl shadow-2xl p-5",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between mb-4",children:[s.jsx("span",{className:"font-display text-sm font-semibold text-txt",children:"Keyboard shortcuts"}),s.jsx("button",{onClick:()=>b(!1),className:"text-muted hover:text-txt transition-colors text-lg leading-none",children:"\xd7"})]}),s.jsx("table",{className:"w-full text-xs",children:s.jsx("tbody",{children:eb.map(({key:e,description:t})=>(0,s.jsxs)("tr",{className:"border-t border-border first:border-0",children:[s.jsx("td",{className:"py-1.5 pr-4",children:s.jsx("kbd",{className:"font-mono bg-surface2 border border-border rounded px-1.5 py-0.5 text-accent",children:e})}),s.jsx("td",{className:"py-1.5 text-muted",children:t})]},e))})})]})]})]})]})}},9195:(e,t,a)=>{"use strict";a.d(t,{t:()=>f});var s=a(7486),r=a(618),n=a(9421),i=a(4987),o=a(5098),d=a(8650),l=a(3068),c=a(2162),u=a(2119);let m=new Date().toISOString().split("T")[0],p=[{id:"blank",name:"Blank Document",description:"Empty markdown file",defaultPath:"docs/untitled.md",content:"# Untitled\n\n"},{id:"claude-md",name:"CLAUDE.md",description:"AI agent instructions for Claude Code",defaultPath:"CLAUDE.md",content:`# {{PROJECT_NAME}} — Agent Instructions
1
+ exports.id=191,exports.ids=[191],exports.modules={1562:(e,t,a)=>{Promise.resolve().then(a.t.bind(a,9388,23)),Promise.resolve().then(a.t.bind(a,1152,23)),Promise.resolve().then(a.t.bind(a,2764,23)),Promise.resolve().then(a.t.bind(a,6894,23)),Promise.resolve().then(a.t.bind(a,3299,23)),Promise.resolve().then(a.t.bind(a,184,23))},9788:(e,t,a)=>{Promise.resolve().then(a.bind(a,151))},103:()=>{},151:(e,t,a)=>{"use strict";a.r(t),a.d(t,{default:()=>ef});var s=a(7486),r=a(618),i=a(6811),n=a(6266);function o(){return s.jsx("div",{className:"min-h-screen flex items-center justify-center",children:(0,s.jsxs)("div",{className:"text-center",children:[s.jsx("div",{className:"flex gap-1.5 justify-center mb-4",children:[0,1,2].map(e=>s.jsx("div",{className:"w-2 h-2 rounded-full bg-accent animate-pulse-dot",style:{animationDelay:`${.15*e}s`}},e))}),s.jsx("p",{className:"text-muted text-sm font-mono",children:"Loading project..."})]})})}var d=a(9228);function l({projects:e,activeProject:t,currentName:a,onSelect:r}){return(0,s.jsxs)(d.h_,{children:[s.jsx(d.$F,{asChild:!0,children:(0,s.jsxs)("button",{className:"flex items-center gap-1.5 px-3 py-1.5 rounded-md bg-surface2 border border-border text-sm hover:border-border2 transition-colors",children:[s.jsx("span",{className:"text-txt font-medium truncate max-w-[200px]",children:a||"Select project"}),s.jsx("span",{className:"text-muted text-xs",children:"▾"})]})}),s.jsx(d.AW,{className:"w-64 bg-surface border-border2 text-txt",align:"start",children:0===e.length?s.jsx("div",{className:"px-3 py-2 text-sm text-muted",children:"No projects found"}):e.map(e=>s.jsx(d.Xi,{onClick:()=>r(e.root),className:`cursor-pointer hover:bg-surface2 focus:bg-surface2 ${e.root===t?"text-accent":""}`,children:(0,s.jsxs)("div",{children:[s.jsx("div",{className:"font-medium",children:e.name}),s.jsx("div",{className:"text-xs text-muted truncate font-mono",children:e.root})]})},e.root))})]})}var c=a(5819);function u({board:e}){return(0,s.jsxs)("div",{className:"flex items-center gap-1.5",children:[(0,s.jsxs)(c.C,{variant:"secondary",className:"gap-1 text-xs font-mono text-amber",children:["\uD83D\uDD28 ",e["in-progress"]||0]}),(0,s.jsxs)(c.C,{variant:"secondary",className:"gap-1 text-xs font-mono text-muted",children:["\uD83D\uDCCB ",e.todo||0]}),(0,s.jsxs)(c.C,{variant:"secondary",className:"gap-1 text-xs font-mono text-teal",children:["✅ ",e.done||0]})]})}var p=a(5098);function m({active:e}){return(0,s.jsxs)("div",{className:"flex items-center gap-1.5 text-xs font-mono text-muted",children:[s.jsx("div",{className:(0,p.cn)("w-1.5 h-1.5 rounded-full transition-colors duration-500",e?"bg-teal shadow-[0_0_6px_#4fd8b4]":"bg-border2")}),s.jsx("span",{children:e?"live update":"connected"})]})}var h=a(8942),f=a(4039),g=a(1317),b=a(3068),x=a(2162),y=a(6637),v=a(2439),w=a(2153);let k=v.fC;v.xz,v.x8;let N=v.h_,C=r.forwardRef(({className:e,...t},a)=>s.jsx(v.aV,{className:(0,p.cn)("fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",e),...t,ref:a}));C.displayName=v.aV.displayName;let R=(0,f.j)("fixed z-50 gap-4 bg-white p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500 dark:bg-slate-950",{variants:{side:{top:"inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",bottom:"inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",left:"inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",right:"inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm"}},defaultVariants:{side:"right"}}),E=r.forwardRef(({side:e="right",className:t,children:a,...r},i)=>(0,s.jsxs)(N,{children:[s.jsx(C,{}),(0,s.jsxs)(v.VY,{ref:i,className:(0,p.cn)(R({side:e}),t),...r,children:[a,(0,s.jsxs)(v.x8,{className:"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-white transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-slate-950 focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-slate-100 dark:ring-offset-slate-950 dark:focus:ring-slate-300 dark:data-[state=open]:bg-slate-800",children:[s.jsx(w.Z,{className:"h-4 w-4"}),s.jsx("span",{className:"sr-only",children:"Close"})]})]})]}));E.displayName=v.VY.displayName;let S=({className:e,...t})=>s.jsx("div",{className:(0,p.cn)("flex flex-col space-y-2 text-center sm:text-left",e),...t});S.displayName="SheetHeader";let j=r.forwardRef(({className:e,...t},a)=>s.jsx(v.Dx,{ref:a,className:(0,p.cn)("text-lg font-semibold text-slate-950 dark:text-slate-50",e),...t}));j.displayName=v.Dx.displayName;let P=r.forwardRef(({className:e,...t},a)=>s.jsx(v.dk,{ref:a,className:(0,p.cn)("text-sm text-slate-500 dark:text-slate-400",e),...t}));function A({className:e,...t}){return s.jsx("div",{className:(0,p.cn)("animate-pulse rounded-md bg-slate-100 dark:bg-slate-800",e),...t})}P.displayName=v.dk.displayName;var _=a(5875);let T=r.createContext(null);function D(){let e=r.useContext(T);if(!e)throw Error("useSidebar must be used within a SidebarProvider.");return e}let I=r.forwardRef(({defaultOpen:e=!0,open:t,onOpenChange:a,className:i,style:n,children:o,...d},l)=>{let c=function(){let[e,t]=r.useState(void 0);return r.useEffect(()=>{let e=window.matchMedia("(max-width: 767px)"),a=()=>{t(window.innerWidth<768)};return e.addEventListener("change",a),t(window.innerWidth<768),()=>e.removeEventListener("change",a)},[]),!!e}(),[u,m]=r.useState(!1),[h,f]=r.useState(e),g=t??h,b=r.useCallback(e=>{let t="function"==typeof e?e(g):e;a?a(t):f(t),document.cookie=`sidebar_state=${t}; path=/; max-age=604800`},[a,g]),x=r.useCallback(()=>c?m(e=>!e):b(e=>!e),[c,b,m]);r.useEffect(()=>{let e=e=>{"b"===e.key&&(e.metaKey||e.ctrlKey)&&(e.preventDefault(),x())};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[x]);let y=g?"expanded":"collapsed",v=r.useMemo(()=>({state:y,open:g,setOpen:b,isMobile:c,openMobile:u,setOpenMobile:m,toggleSidebar:x}),[y,g,b,c,u,m,x]);return s.jsx(T.Provider,{value:v,children:s.jsx(_.pn,{delayDuration:0,children:s.jsx("div",{style:{"--sidebar-width":"16rem","--sidebar-width-icon":"3rem",...n},className:(0,p.cn)("group/sidebar-wrapper flex min-h-svh w-full has-[[data-variant=inset]]:bg-sidebar",i),ref:l,...d,children:o})})})});I.displayName="SidebarProvider";let O=r.forwardRef(({side:e="left",variant:t="sidebar",collapsible:a="offcanvas",className:r,children:i,...n},o)=>{let{isMobile:d,state:l,openMobile:c,setOpenMobile:u}=D();return"none"===a?s.jsx("div",{className:(0,p.cn)("flex h-full w-[--sidebar-width] flex-col bg-sidebar text-sidebar-foreground",r),ref:o,...n,children:i}):d?s.jsx(k,{open:c,onOpenChange:u,...n,children:(0,s.jsxs)(E,{"data-sidebar":"sidebar","data-mobile":"true",className:"w-[--sidebar-width] bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden",style:{"--sidebar-width":"18rem"},side:e,children:[(0,s.jsxs)(S,{className:"sr-only",children:[s.jsx(j,{children:"Sidebar"}),s.jsx(P,{children:"Displays the mobile sidebar."})]}),s.jsx("div",{className:"flex h-full w-full flex-col",children:i})]})}):(0,s.jsxs)("div",{ref:o,className:"group peer hidden text-sidebar-foreground md:block","data-state":l,"data-collapsible":"collapsed"===l?a:"","data-variant":t,"data-side":e,children:[s.jsx("div",{className:(0,p.cn)("relative w-[--sidebar-width] bg-transparent transition-[width] duration-200 ease-linear","group-data-[collapsible=offcanvas]:w-0","group-data-[side=right]:rotate-180","floating"===t||"inset"===t?"group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4))]":"group-data-[collapsible=icon]:w-[--sidebar-width-icon]")}),s.jsx("div",{className:(0,p.cn)("fixed inset-y-0 z-10 hidden h-svh w-[--sidebar-width] transition-[left,right,width] duration-200 ease-linear md:flex","left"===e?"left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]":"right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]","floating"===t||"inset"===t?"p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4)_+2px)]":"group-data-[collapsible=icon]:w-[--sidebar-width-icon] group-data-[side=left]:border-r group-data-[side=right]:border-l",r),...n,children:s.jsx("div",{"data-sidebar":"sidebar",className:"flex h-full w-full flex-col bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:border-sidebar-border group-data-[variant=floating]:shadow",children:i})})]})});O.displayName="Sidebar";let M=r.forwardRef(({className:e,onClick:t,...a},r)=>{let{toggleSidebar:i}=D();return(0,s.jsxs)(b.z,{ref:r,"data-sidebar":"trigger",variant:"ghost",size:"icon",className:(0,p.cn)("h-7 w-7",e),onClick:e=>{t?.(e),i()},...a,children:[s.jsx(g.Z,{}),s.jsx("span",{className:"sr-only",children:"Toggle Sidebar"})]})});M.displayName="SidebarTrigger",r.forwardRef(({className:e,...t},a)=>{let{toggleSidebar:r}=D();return s.jsx("button",{ref:a,"data-sidebar":"rail","aria-label":"Toggle Sidebar",tabIndex:-1,onClick:r,title:"Toggle Sidebar",className:(0,p.cn)("absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] hover:after:bg-sidebar-border group-data-[side=left]:-right-4 group-data-[side=right]:left-0 sm:flex","[[data-side=left]_&]:cursor-w-resize [[data-side=right]_&]:cursor-e-resize","[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize","group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full group-data-[collapsible=offcanvas]:hover:bg-sidebar","[[data-side=left][data-collapsible=offcanvas]_&]:-right-2","[[data-side=right][data-collapsible=offcanvas]_&]:-left-2",e),...t})}).displayName="SidebarRail";let L=r.forwardRef(({className:e,...t},a)=>s.jsx("main",{ref:a,className:(0,p.cn)("relative flex w-full flex-1 flex-col bg-white dark:bg-slate-950","md:peer-data-[variant=inset]:m-2 md:peer-data-[state=collapsed]:peer-data-[variant=inset]:ml-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow",e),...t}));L.displayName="SidebarInset",r.forwardRef(({className:e,...t},a)=>s.jsx(x.I,{ref:a,"data-sidebar":"input",className:(0,p.cn)("h-8 w-full bg-white shadow-none focus-visible:ring-2 focus-visible:ring-sidebar-ring dark:bg-slate-950",e),...t})).displayName="SidebarInput";let U=r.forwardRef(({className:e,...t},a)=>s.jsx("div",{ref:a,"data-sidebar":"header",className:(0,p.cn)("flex flex-col gap-2 p-2",e),...t}));U.displayName="SidebarHeader",r.forwardRef(({className:e,...t},a)=>s.jsx("div",{ref:a,"data-sidebar":"footer",className:(0,p.cn)("flex flex-col gap-2 p-2",e),...t})).displayName="SidebarFooter";let z=r.forwardRef(({className:e,...t},a)=>s.jsx(y.Z,{ref:a,"data-sidebar":"separator",className:(0,p.cn)("mx-2 w-auto bg-sidebar-border",e),...t}));z.displayName="SidebarSeparator";let G=r.forwardRef(({className:e,...t},a)=>s.jsx("div",{ref:a,"data-sidebar":"content",className:(0,p.cn)("flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden",e),...t}));G.displayName="SidebarContent";let q=r.forwardRef(({className:e,...t},a)=>s.jsx("div",{ref:a,"data-sidebar":"group",className:(0,p.cn)("relative flex w-full min-w-0 flex-col p-2",e),...t}));q.displayName="SidebarGroup";let B=r.forwardRef(({className:e,asChild:t=!1,...a},r)=>{let i=t?h.g7:"div";return s.jsx(i,{ref:r,"data-sidebar":"group-label",className:(0,p.cn)("flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium text-sidebar-foreground/70 outline-none ring-sidebar-ring transition-[margin,opacity] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0","group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0",e),...a})});B.displayName="SidebarGroupLabel",r.forwardRef(({className:e,asChild:t=!1,...a},r)=>{let i=t?h.g7:"button";return s.jsx(i,{ref:r,"data-sidebar":"group-action",className:(0,p.cn)("absolute right-3 top-3.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-none ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0","after:absolute after:-inset-2 after:md:hidden","group-data-[collapsible=icon]:hidden",e),...a})}).displayName="SidebarGroupAction";let W=r.forwardRef(({className:e,...t},a)=>s.jsx("div",{ref:a,"data-sidebar":"group-content",className:(0,p.cn)("w-full text-sm",e),...t}));W.displayName="SidebarGroupContent";let F=r.forwardRef(({className:e,...t},a)=>s.jsx("ul",{ref:a,"data-sidebar":"menu",className:(0,p.cn)("flex w-full min-w-0 flex-col gap-1",e),...t}));F.displayName="SidebarMenu";let H=r.forwardRef(({className:e,...t},a)=>s.jsx("li",{ref:a,"data-sidebar":"menu-item",className:(0,p.cn)("group/menu-item relative",e),...t}));H.displayName="SidebarMenuItem";let K=(0,f.j)("peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-none ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-[[data-sidebar=menu-action]]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:!size-8 group-data-[collapsible=icon]:!p-2 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0",{variants:{variant:{default:"hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",outline:"bg-white shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))] dark:bg-slate-950"},size:{default:"h-8 text-sm",sm:"h-7 text-xs",lg:"h-12 text-sm group-data-[collapsible=icon]:!p-0"}},defaultVariants:{variant:"default",size:"default"}}),$=r.forwardRef(({asChild:e=!1,isActive:t=!1,variant:a="default",size:r="default",tooltip:i,className:n,...o},d)=>{let l=e?h.g7:"button",{isMobile:c,state:u}=D(),m=s.jsx(l,{ref:d,"data-sidebar":"menu-button","data-size":r,"data-active":t,className:(0,p.cn)(K({variant:a,size:r}),n),...o});return i?("string"==typeof i&&(i={children:i}),(0,s.jsxs)(_.u,{children:[s.jsx(_.aJ,{asChild:!0,children:m}),s.jsx(_._v,{side:"right",align:"center",hidden:"collapsed"!==u||c,...i})]})):m});function V({summary:e,projects:t,activeProject:a,liveIndicator:r,onProjectChange:i}){return(0,s.jsxs)("header",{className:"h-12 border-b border-border flex items-center px-4 gap-4 flex-shrink-0 bg-surface/80 backdrop-blur-sm sticky top-0 z-50",children:[s.jsx(M,{className:"-ml-1"}),s.jsx(y.Z,{orientation:"vertical",className:"mr-2 h-4"}),(0,s.jsxs)("div",{className:"flex items-center gap-2 flex-shrink-0",children:[s.jsx("div",{className:"w-6 h-6 rounded-md bg-gradient-to-br from-accent to-teal flex items-center justify-center text-xs",children:"⬡"}),s.jsx("span",{className:"font-mono text-xs text-muted tracking-widest uppercase",children:"VibeDoc"})]}),s.jsx(l,{projects:t,activeProject:a,currentName:e?.name||"",onSelect:i}),e&&s.jsx(u,{board:e.tasks.board}),s.jsx("div",{className:"flex-1"}),s.jsx(m,{active:r}),(0,s.jsxs)("div",{className:"hidden md:flex items-center gap-1.5 px-2 py-1 rounded bg-surface2 border border-border",children:[s.jsx("span",{className:"text-xs font-mono text-muted",children:"MCP"}),s.jsx("code",{className:"text-xs font-mono text-accent",children:"localhost:3000/api/mcp"})]})]})}$.displayName="SidebarMenuButton",r.forwardRef(({className:e,asChild:t=!1,showOnHover:a=!1,...r},i)=>{let n=t?h.g7:"button";return s.jsx(n,{ref:i,"data-sidebar":"menu-action",className:(0,p.cn)("absolute right-1 top-1.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-none ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 peer-hover/menu-button:text-sidebar-accent-foreground [&>svg]:size-4 [&>svg]:shrink-0","after:absolute after:-inset-2 after:md:hidden","peer-data-[size=sm]/menu-button:top-1","peer-data-[size=default]/menu-button:top-1.5","peer-data-[size=lg]/menu-button:top-2.5","group-data-[collapsible=icon]:hidden",a&&"group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 peer-data-[active=true]/menu-button:text-sidebar-accent-foreground md:opacity-0",e),...r})}).displayName="SidebarMenuAction",r.forwardRef(({className:e,...t},a)=>s.jsx("div",{ref:a,"data-sidebar":"menu-badge",className:(0,p.cn)("pointer-events-none absolute right-1 flex h-5 min-w-5 select-none items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums text-sidebar-foreground","peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground","peer-data-[size=sm]/menu-button:top-1","peer-data-[size=default]/menu-button:top-1.5","peer-data-[size=lg]/menu-button:top-2.5","group-data-[collapsible=icon]:hidden",e),...t})).displayName="SidebarMenuBadge",r.forwardRef(({className:e,showIcon:t=!1,...a},i)=>{let n=r.useMemo(()=>`${Math.floor(40*Math.random())+50}%`,[]);return(0,s.jsxs)("div",{ref:i,"data-sidebar":"menu-skeleton",className:(0,p.cn)("flex h-8 items-center gap-2 rounded-md px-2",e),...a,children:[t&&s.jsx(A,{className:"size-4 rounded-md","data-sidebar":"menu-skeleton-icon"}),s.jsx(A,{className:"h-4 max-w-[--skeleton-width] flex-1","data-sidebar":"menu-skeleton-text",style:{"--skeleton-width":n}})]})}).displayName="SidebarMenuSkeleton",r.forwardRef(({className:e,...t},a)=>s.jsx("ul",{ref:a,"data-sidebar":"menu-sub",className:(0,p.cn)("mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l border-sidebar-border px-2.5 py-0.5","group-data-[collapsible=icon]:hidden",e),...t})).displayName="SidebarMenuSub",r.forwardRef(({...e},t)=>s.jsx("li",{ref:t,...e})).displayName="SidebarMenuSubItem",r.forwardRef(({asChild:e=!1,size:t="md",isActive:a,className:r,...i},n)=>{let o=e?h.g7:"a";return s.jsx(o,{ref:n,"data-sidebar":"menu-sub-button","data-size":t,"data-active":a,className:(0,p.cn)("flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sidebar-foreground outline-none ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground","data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground","sm"===t&&"text-xs","md"===t&&"text-sm","group-data-[collapsible=icon]:hidden",r),...i})}).displayName="SidebarMenuSubButton";var Y=a(3596),J=a(7987),Z=a(9529),X=a(8673),Q=a(5314),ee=a(6034),et=a(771),ea=a(4119),es=a(7834),er=a(8165);let ei=[{href:"/board",icon:Y.Z,label:"Board"},{href:"/docs",icon:J.Z,label:"Docs"},{href:"/activity",icon:Z.Z,label:"Activity"},{href:"/memory",icon:X.Z,label:"Memory"},{href:"/settings",icon:Q.Z,label:"Settings"}],en=[{status:"in-progress",icon:ee.Z,label:"Active"},{status:"blocked",icon:et.Z,label:"Blocked"},{status:"todo",icon:ea.Z,label:"Todo"},{status:"done",icon:es.Z,label:"Done"}];function eo({board:e}){let t=(0,i.usePathname)();return(0,s.jsxs)(O,{collapsible:"icon",children:[s.jsx(U,{children:(0,s.jsxs)("div",{className:"flex items-center gap-2 px-2 py-1",children:[s.jsx("div",{className:"w-6 h-6 rounded-md bg-gradient-to-br from-accent to-teal flex items-center justify-center text-xs flex-shrink-0",children:"⬡"}),s.jsx("span",{className:"font-mono text-xs text-muted tracking-widest uppercase group-data-[collapsible=icon]:hidden",children:"VibeDoc"})]})}),(0,s.jsxs)(G,{children:[s.jsx(q,{children:s.jsx(W,{children:s.jsx(F,{children:ei.map(({href:e,icon:a,label:r})=>s.jsx(H,{children:s.jsx($,{asChild:!0,isActive:t.startsWith(e),tooltip:r,children:(0,s.jsxs)(er.default,{href:e,children:[s.jsx(a,{}),s.jsx("span",{children:r})]})})},e))})})}),e&&(0,s.jsxs)(s.Fragment,{children:[s.jsx(z,{}),(0,s.jsxs)(q,{children:[s.jsx(B,{children:"Board"}),s.jsx(W,{children:s.jsx(F,{children:en.map(({status:t,icon:a,label:r})=>{let i=e[t]?.length||0;return s.jsx(H,{children:(0,s.jsxs)($,{tooltip:`${r}: ${i}`,children:[s.jsx(a,{}),s.jsx("span",{children:r}),s.jsx("span",{className:"ml-auto font-mono text-xs",children:i})]})},t)})})})]})]})]})]})}var ed=a(2126),el=a(194),ec=a(9516),eu=a(8650),ep=a(2119);function em({open:e,onClose:t,onOpenDoc:a,onNewDoc:n,rootParam:o}){let d=(0,i.useRouter)(),[l,c]=(0,r.useState)(""),[u,m]=(0,r.useState)([]),[h,f]=(0,r.useState)(0),g=[{label:"New Doc",icon:ed.Z,action:()=>{n?.(),t()}},{label:"Go to Board",icon:Y.Z,action:()=>{d.push("/board"),t()}},{label:"Go to Activity",icon:el.Z,action:()=>{d.push("/activity"),t()}},{label:"Go to Memory",icon:X.Z,action:()=>{d.push("/memory"),t()}}];function b(e){a(e.path),t()}let y=""===l;return s.jsx(eu.Vq,{open:e,onOpenChange:e=>{e||t()},children:(0,s.jsxs)(eu.cZ,{className:"max-w-lg p-0 overflow-hidden bg-surface border-border gap-0",children:[s.jsx(eu.$N,{className:"sr-only",children:"Command Palette"}),(0,s.jsxs)("div",{className:"flex items-center px-4 h-12",children:[s.jsx(ec.Z,{className:"h-4 w-4 text-muted shrink-0 mr-3"}),s.jsx(x.I,{autoFocus:!0,value:l,onChange:e=>c(e.target.value),onKeyDown:function(e){let t=u.length>0,a=t?u.length:g.length;"ArrowDown"===e.key?(e.preventDefault(),f(e=>Math.min(e+1,a-1))):"ArrowUp"===e.key?(e.preventDefault(),f(e=>Math.max(e-1,0))):"Enter"===e.key&&(t&&u[h]?b(u[h]):!t&&l.length<2&&g[h]&&g[h].action())},placeholder:"Search docs…",className:"border-0 bg-transparent h-full text-sm shadow-none focus-visible:ring-0 px-0 placeholder:text-muted"})]}),s.jsx("div",{className:"border-t border-border"}),(0,s.jsxs)(ep.x,{className:"max-h-72",children:[y&&s.jsx("div",{className:"py-1",children:g.map((e,t)=>(0,s.jsxs)("button",{onClick:e.action,onMouseEnter:()=>f(t),className:(0,p.cn)("flex items-center gap-3 w-full px-4 py-2 text-sm text-left transition-colors",h===t?"bg-accent/10 text-txt":"text-muted hover:text-txt"),children:[s.jsx(e.icon,{className:"h-4 w-4 shrink-0"}),e.label]},e.label))}),!y&&u.length>0&&s.jsx("div",{className:"py-1",children:u.map((e,t)=>(0,s.jsxs)("button",{onClick:()=>b(e),onMouseEnter:()=>f(t),className:(0,p.cn)("flex items-center justify-between w-full px-4 py-2 text-sm text-left transition-colors",h===t?"bg-accent/10":"hover:bg-accent/5"),children:[s.jsx("span",{className:"font-medium text-txt truncate",children:e.name}),e.section&&s.jsx("span",{className:"text-xs text-muted ml-3 shrink-0 truncate max-w-[40%]",children:e.section})]},e.path))}),!y&&l.length>=2&&0===u.length&&s.jsx("div",{className:"px-4 py-6 text-center text-sm text-muted",children:"No docs found"})]})]})})}var eh=a(9239);function ef({children:e}){return s.jsx(n.w,{children:s.jsx(eb,{children:e})})}let eg=[{key:"Cmd+K",description:"Open command palette"},{key:"b",description:"Go to Board"},{key:"d",description:"Go to Docs"},{key:"a",description:"Go to Activity"},{key:"m",description:"Go to Memory"},{key:"/",description:"Focus doc search"},{key:"?",description:"Toggle this help"},{key:"Esc",description:"Close panel / modal"}];function eb({children:e}){let{loading:t,summary:a,projects:d,activeProject:l,liveIndicator:c,onProjectChange:u,board:p,openDoc:m,rootParam:h}=(0,n.q)();(0,i.useRouter)(),(0,i.usePathname)();let[f,g]=(0,r.useState)(!1),[b,x]=(0,r.useState)(!1),[y,v]=(0,r.useState)(!1);return t?s.jsx(o,{}):(0,s.jsxs)(I,{children:[s.jsx(eo,{board:p}),(0,s.jsxs)(L,{children:[s.jsx(V,{summary:a,projects:d,activeProject:l,liveIndicator:c,onProjectChange:u}),s.jsx("main",{className:"flex-1 overflow-y-auto",children:e}),s.jsx(em,{open:b,onClose:()=>x(!1),onOpenDoc:m,onNewDoc:()=>{x(!1),v(!0)},rootParam:h}),s.jsx(eh.t,{open:y,onOpenChange:v,rootParam:h,onDocCreated:async e=>{await m(e)}}),f&&(0,s.jsxs)(s.Fragment,{children:[s.jsx("div",{className:"fixed inset-0 z-50 bg-black/60",onClick:()=>g(!1)}),(0,s.jsxs)("div",{className:"fixed z-50 top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-80 bg-surface border border-border rounded-xl shadow-2xl p-5",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between mb-4",children:[s.jsx("span",{className:"font-display text-sm font-semibold text-txt",children:"Keyboard shortcuts"}),s.jsx("button",{onClick:()=>g(!1),className:"text-muted hover:text-txt transition-colors text-lg leading-none",children:"\xd7"})]}),s.jsx("table",{className:"w-full text-xs",children:s.jsx("tbody",{children:eg.map(({key:e,description:t})=>(0,s.jsxs)("tr",{className:"border-t border-border first:border-0",children:[s.jsx("td",{className:"py-1.5 pr-4",children:s.jsx("kbd",{className:"font-mono bg-surface2 border border-border rounded px-1.5 py-0.5 text-accent",children:e})}),s.jsx("td",{className:"py-1.5 text-muted",children:t})]},e))})})]})]})]})]})}},9239:(e,t,a)=>{"use strict";a.d(t,{t:()=>m});var s=a(7486),r=a(618),i=a(9421),n=a(4987),o=a(5098),d=a(8650),l=a(3068),c=a(2162),u=a(2119),p=a(8508);function m({open:e,onOpenChange:t,rootParam:a,onDocCreated:m}){let[h,f]=(0,r.useState)(1),[g,b]=(0,r.useState)(null),[x,y]=(0,r.useState)(""),[v,w]=(0,r.useState)(""),[k,N]=(0,r.useState)(!1);async function C(){if(g&&x.trim()){w(""),N(!0);try{let e=await fetch(`/api/docs${a}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:x.trim(),content:g.content})});if(409===e.status){w("File already exists"),N(!1);return}if(!e.ok){let t=await e.json();w(t.error||"Failed to create file"),N(!1);return}t(!1),m(x.trim())}catch{w("Network error"),N(!1)}}}return s.jsx(d.Vq,{open:e,onOpenChange:t,children:(0,s.jsxs)(d.cZ,{className:"max-w-2xl bg-surface border-border",children:[s.jsx(d.fK,{children:s.jsx(d.$N,{className:"text-txt text-sm font-semibold",children:1===h?"Choose a template":"Confirm file path"})}),1===h&&s.jsx(u.x,{className:"max-h-[420px]",children:s.jsx("div",{className:"grid grid-cols-3 gap-2 p-1",children:p.x.map(e=>(0,s.jsxs)("button",{onClick:()=>{b(e),y(e.defaultPath),w(""),f(2)},className:(0,o.cn)("flex flex-col items-start gap-1.5 p-3 rounded-lg border border-border text-left","bg-surface2 hover:bg-surface2/80 hover:border-accent/50 transition-colors"),children:[(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[s.jsx(i.Z,{className:"h-3.5 w-3.5 text-accent shrink-0"}),s.jsx("span",{className:"text-xs font-medium text-txt",children:e.name})]}),s.jsx("p",{className:"text-[11px] text-muted leading-relaxed",children:e.description}),s.jsx("p",{className:"text-[10px] text-muted/60 font-mono truncate w-full",children:e.defaultPath})]},e.id))})}),2===h&&g&&(0,s.jsxs)("div",{className:"space-y-4",children:[(0,s.jsxs)("div",{className:"flex items-start gap-3 p-3 rounded-lg bg-surface2 border border-border",children:[s.jsx(i.Z,{className:"h-4 w-4 text-accent shrink-0 mt-0.5"}),(0,s.jsxs)("div",{children:[s.jsx("p",{className:"text-xs font-medium text-txt",children:g.name}),s.jsx("p",{className:"text-[11px] text-muted mt-0.5",children:g.description})]})]}),(0,s.jsxs)("div",{className:"space-y-1.5",children:[s.jsx("label",{className:"text-[11px] font-medium text-muted uppercase tracking-wider",children:"File path"}),s.jsx(c.I,{autoFocus:!0,value:x,onChange:e=>{y(e.target.value),w("")},onKeyDown:e=>{"Enter"===e.key&&C()},placeholder:"docs/my-document.md",className:"h-8 text-xs bg-surface2 border-border font-mono"}),v&&s.jsx("p",{className:"text-[11px] text-red-400",children:v})]}),(0,s.jsxs)("div",{className:"flex items-center justify-between pt-1",children:[(0,s.jsxs)(l.z,{variant:"ghost",size:"sm",onClick:()=>f(1),className:"h-7 text-xs text-muted hover:text-txt gap-1.5",children:[s.jsx(n.Z,{className:"h-3 w-3"}),"Back"]}),s.jsx(l.z,{size:"sm",onClick:C,disabled:k||!x.trim(),className:"h-7 text-xs bg-accent hover:bg-accent/90 text-white",children:k?"Creating…":"Create"})]})]})]})})}},5819:(e,t,a)=>{"use strict";a.d(t,{C:()=>o});var s=a(7486);a(618);var r=a(4039),i=a(5098);let n=(0,r.j)("inline-flex items-center rounded-full border border-slate-200 px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-slate-950 focus:ring-offset-2 dark:border-slate-800 dark:focus:ring-slate-300",{variants:{variant:{default:"border-transparent bg-slate-900 text-slate-50 hover:bg-slate-900/80 dark:bg-slate-50 dark:text-slate-900 dark:hover:bg-slate-50/80",secondary:"border-transparent bg-slate-100 text-slate-900 hover:bg-slate-100/80 dark:bg-slate-800 dark:text-slate-50 dark:hover:bg-slate-800/80",destructive:"border-transparent bg-red-500 text-slate-50 hover:bg-red-500/80 dark:bg-red-900 dark:text-slate-50 dark:hover:bg-red-900/80",outline:"text-slate-950 dark:text-slate-50"}},defaultVariants:{variant:"default"}});function o({className:e,variant:t,...a}){return s.jsx("div",{className:(0,i.cn)(n({variant:t}),e),...a})}},3068:(e,t,a)=>{"use strict";a.d(t,{z:()=>l});var s=a(7486),r=a(618),i=a(8942),n=a(4039),o=a(5098);let d=(0,n.j)("inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-white transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-950 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 dark:ring-offset-slate-950 dark:focus-visible:ring-slate-300",{variants:{variant:{default:"bg-slate-900 text-slate-50 hover:bg-slate-900/90 dark:bg-slate-50 dark:text-slate-900 dark:hover:bg-slate-50/90",destructive:"bg-red-500 text-slate-50 hover:bg-red-500/90 dark:bg-red-900 dark:text-slate-50 dark:hover:bg-red-900/90",outline:"border border-slate-200 bg-white hover:bg-slate-100 hover:text-slate-900 dark:border-slate-800 dark:bg-slate-950 dark:hover:bg-slate-800 dark:hover:text-slate-50",secondary:"bg-slate-100 text-slate-900 hover:bg-slate-100/80 dark:bg-slate-800 dark:text-slate-50 dark:hover:bg-slate-800/80",ghost:"hover:bg-slate-100 hover:text-slate-900 dark:hover:bg-slate-800 dark:hover:text-slate-50",link:"text-slate-900 underline-offset-4 hover:underline dark:text-slate-50"},size:{default:"h-10 px-4 py-2",sm:"h-9 rounded-md px-3",lg:"h-11 rounded-md px-8",icon:"h-10 w-10"}},defaultVariants:{variant:"default",size:"default"}}),l=r.forwardRef(({className:e,variant:t,size:a,asChild:r=!1,...n},l)=>{let c=r?i.g7:"button";return s.jsx(c,{className:(0,o.cn)(d({variant:t,size:a,className:e})),ref:l,...n})});l.displayName="Button"},8650:(e,t,a)=>{"use strict";a.d(t,{$N:()=>m,Vq:()=>d,cZ:()=>u,fK:()=>p});var s=a(7486),r=a(618),i=a(2439),n=a(2153),o=a(5098);let d=i.fC;i.xz;let l=i.h_;i.x8;let c=r.forwardRef(({className:e,...t},a)=>s.jsx(i.aV,{ref:a,className:(0,o.cn)("fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",e),...t}));c.displayName=i.aV.displayName;let u=r.forwardRef(({className:e,children:t,...a},r)=>(0,s.jsxs)(l,{children:[s.jsx(c,{}),(0,s.jsxs)(i.VY,{ref:r,className:(0,o.cn)("fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border border-slate-200 bg-white p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg dark:border-slate-800 dark:bg-slate-950",e),...a,children:[t,(0,s.jsxs)(i.x8,{className:"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-white transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-slate-950 focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-slate-100 data-[state=open]:text-slate-500 dark:ring-offset-slate-950 dark:focus:ring-slate-300 dark:data-[state=open]:bg-slate-800 dark:data-[state=open]:text-slate-400",children:[s.jsx(n.Z,{className:"h-4 w-4"}),s.jsx("span",{className:"sr-only",children:"Close"})]})]})]}));u.displayName=i.VY.displayName;let p=({className:e,...t})=>s.jsx("div",{className:(0,o.cn)("flex flex-col space-y-1.5 text-center sm:text-left",e),...t});p.displayName="DialogHeader";let m=r.forwardRef(({className:e,...t},a)=>s.jsx(i.Dx,{ref:a,className:(0,o.cn)("text-lg font-semibold leading-none tracking-tight",e),...t}));m.displayName=i.Dx.displayName,r.forwardRef(({className:e,...t},a)=>s.jsx(i.dk,{ref:a,className:(0,o.cn)("text-sm text-slate-500 dark:text-slate-400",e),...t})).displayName=i.dk.displayName},9228:(e,t,a)=>{"use strict";a.d(t,{$F:()=>u,AW:()=>p,Xi:()=>m,h_:()=>c});var s=a(7486),r=a(618),i=a(79),n=a(8953),o=a(9644),d=a(3399),l=a(5098);let c=i.fC,u=i.xz;i.ZA,i.Uv,i.Tr,i.Ee,r.forwardRef(({className:e,inset:t,children:a,...r},o)=>(0,s.jsxs)(i.fF,{ref:o,className:(0,l.cn)("flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-slate-100 data-[state=open]:bg-slate-100 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 dark:focus:bg-slate-800 dark:data-[state=open]:bg-slate-800",t&&"pl-8",e),...r,children:[a,s.jsx(n.Z,{className:"ml-auto"})]})).displayName=i.fF.displayName,r.forwardRef(({className:e,...t},a)=>s.jsx(i.tu,{ref:a,className:(0,l.cn)("z-50 min-w-[8rem] overflow-hidden rounded-md border border-slate-200 bg-white p-1 text-slate-950 shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-dropdown-menu-content-transform-origin] dark:border-slate-800 dark:bg-slate-950 dark:text-slate-50",e),...t})).displayName=i.tu.displayName;let p=r.forwardRef(({className:e,sideOffset:t=4,...a},r)=>s.jsx(i.Uv,{children:s.jsx(i.VY,{ref:r,sideOffset:t,className:(0,l.cn)("z-50 max-h-[var(--radix-dropdown-menu-content-available-height)] min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border border-slate-200 bg-white p-1 text-slate-950 shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-dropdown-menu-content-transform-origin] dark:border-slate-800 dark:bg-slate-950 dark:text-slate-50",e),...a})}));p.displayName=i.VY.displayName;let m=r.forwardRef(({className:e,inset:t,...a},r)=>s.jsx(i.ck,{ref:r,className:(0,l.cn)("relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-slate-100 focus:text-slate-900 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 dark:focus:bg-slate-800 dark:focus:text-slate-50",t&&"pl-8",e),...a}));m.displayName=i.ck.displayName,r.forwardRef(({className:e,children:t,checked:a,...r},n)=>(0,s.jsxs)(i.oC,{ref:n,className:(0,l.cn)("relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-slate-100 focus:text-slate-900 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-slate-800 dark:focus:text-slate-50",e),checked:a,...r,children:[s.jsx("span",{className:"absolute left-2 flex h-3.5 w-3.5 items-center justify-center",children:s.jsx(i.wU,{children:s.jsx(o.Z,{className:"h-4 w-4"})})}),t]})).displayName=i.oC.displayName,r.forwardRef(({className:e,children:t,...a},r)=>(0,s.jsxs)(i.Rk,{ref:r,className:(0,l.cn)("relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-slate-100 focus:text-slate-900 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-slate-800 dark:focus:text-slate-50",e),...a,children:[s.jsx("span",{className:"absolute left-2 flex h-3.5 w-3.5 items-center justify-center",children:s.jsx(i.wU,{children:s.jsx(d.Z,{className:"h-2 w-2 fill-current"})})}),t]})).displayName=i.Rk.displayName,r.forwardRef(({className:e,inset:t,...a},r)=>s.jsx(i.__,{ref:r,className:(0,l.cn)("px-2 py-1.5 text-sm font-semibold",t&&"pl-8",e),...a})).displayName=i.__.displayName,r.forwardRef(({className:e,...t},a)=>s.jsx(i.Z0,{ref:a,className:(0,l.cn)("-mx-1 my-1 h-px bg-slate-100 dark:bg-slate-800",e),...t})).displayName=i.Z0.displayName},2162:(e,t,a)=>{"use strict";a.d(t,{I:()=>n});var s=a(7486),r=a(618),i=a(5098);let n=r.forwardRef(({className:e,type:t,...a},r)=>s.jsx("input",{type:t,className:(0,i.cn)("flex h-10 w-full rounded-md border border-slate-200 bg-white px-3 py-2 text-base ring-offset-white file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-slate-950 placeholder:text-slate-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-950 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:border-slate-800 dark:bg-slate-950 dark:ring-offset-slate-950 dark:file:text-slate-50 dark:placeholder:text-slate-400 dark:focus-visible:ring-slate-300",e),ref:r,...a}));n.displayName="Input"},2119:(e,t,a)=>{"use strict";a.d(t,{x:()=>o});var s=a(7486),r=a(618),i=a(7051),n=a(5098);let o=r.forwardRef(({className:e,children:t,...a},r)=>(0,s.jsxs)(i.fC,{ref:r,className:(0,n.cn)("relative overflow-hidden",e),...a,children:[s.jsx(i.l_,{className:"h-full w-full rounded-[inherit]",children:t}),s.jsx(d,{}),s.jsx(i.Ns,{})]}));o.displayName=i.fC.displayName;let d=r.forwardRef(({className:e,orientation:t="vertical",...a},r)=>s.jsx(i.gb,{ref:r,orientation:t,className:(0,n.cn)("flex touch-none select-none transition-colors","vertical"===t&&"h-full w-2.5 border-l border-l-transparent p-[1px]","horizontal"===t&&"h-2.5 flex-col border-t border-t-transparent p-[1px]",e),...a,children:s.jsx(i.q4,{className:"relative flex-1 rounded-full bg-slate-200 dark:bg-slate-800"})}));d.displayName=i.gb.displayName},6637:(e,t,a)=>{"use strict";a.d(t,{Z:()=>o});var s=a(7486),r=a(618),i=a(7168),n=a(5098);let o=r.forwardRef(({className:e,orientation:t="horizontal",decorative:a=!0,...r},o)=>s.jsx(i.f,{ref:o,decorative:a,orientation:t,className:(0,n.cn)("shrink-0 bg-slate-200 dark:bg-slate-800","horizontal"===t?"h-[1px] w-full":"h-full w-[1px]",e),...r}));o.displayName=i.f.displayName},5875:(e,t,a)=>{"use strict";a.d(t,{_v:()=>c,aJ:()=>l,pn:()=>o,u:()=>d});var s=a(7486),r=a(618),i=a(6448),n=a(5098);let o=i.zt,d=i.fC,l=i.xz,c=r.forwardRef(({className:e,sideOffset:t=4,...a},r)=>s.jsx(i.VY,{ref:r,sideOffset:t,className:(0,n.cn)("z-50 overflow-hidden rounded-md border border-slate-200 bg-white px-3 py-1.5 text-sm text-slate-950 shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-tooltip-content-transform-origin] dark:border-slate-800 dark:bg-slate-950 dark:text-slate-50",e),...a}));c.displayName=i.VY.displayName},6266:(e,t,a)=>{"use strict";a.d(t,{q:()=>o,w:()=>d});var s=a(7486),r=a(618),i=a(6811);let n=(0,r.createContext)(null);function o(){let e=(0,r.useContext)(n);if(!e)throw Error("useApp must be used inside AppProvider");return e}function d({children:e}){let t=(0,i.useRouter)(),[a,o]=(0,r.useState)([]),[d,l]=(0,r.useState)(""),[c,u]=(0,r.useState)(null),[p,m]=(0,r.useState)(null),[h,f]=(0,r.useState)([]),[g,b]=(0,r.useState)(!0),[x,y]=(0,r.useState)(!1),[v,w]=(0,r.useState)(null);(0,r.useRef)(null);let k=d?`?root=${encodeURIComponent(d)}`:"",N=(0,r.useCallback)(async e=>{let t=e||d;if(!t)return;let a=`?root=${encodeURIComponent(t)}`;try{let[e,t,s]=await Promise.all([fetch(`/api/summary${a}`).then(e=>e.json()),fetch(`/api/tasks${a}`).then(e=>e.json()),fetch(`/api/activity${a}&limit=30`).then(e=>e.json())]);u(e),m(t.board),f(Array.isArray(s)?s:[])}catch{}b(!1)},[d]),C=(0,r.useCallback)(async(e,t)=>{m(a=>{let s;if(!a)return a;let r=structuredClone(a);for(let a of Object.keys(r)){let i=r[a].findIndex(t=>t.id===e);-1!==i&&(s={...r[a][i],status:t},r[a]=r[a].filter(t=>t.id!==e))}return s&&r[t]&&(r[t]=[s,...r[t]]),r});try{await fetch(`/api/tasks${k}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({taskId:e,status:t,actor:"human"})}),N()}catch{N()}},[k,N]),R=(0,r.useCallback)(async e=>{let a=await fetch(`/api/docs${k}&read=${encodeURIComponent(e)}`);w(await a.json()),t.push("/docs")},[k,t]);return s.jsx(n.Provider,{value:{projects:a,activeProject:d,summary:c,board:p,activity:h,liveIndicator:x,loading:g,selectedDoc:v,setSelectedDoc:w,rootParam:k,onProjectChange:function(e){l(e),N(e)},refresh:N,moveTask:C,openDoc:R},children:e})}},8508:(e,t,a)=>{"use strict";a.d(t,{x:()=>o});let s=[{id:"claude-md",name:"CLAUDE.md",description:"AI agent instructions for Claude Code",defaultPath:"CLAUDE.md",category:"ai-agent",content:`# {{PROJECT_NAME}} — Agent Instructions
2
2
 
3
3
  ## What this is
4
4
  {{DESCRIPTION}}
@@ -12,7 +12,7 @@ exports.id=191,exports.ids=[191],exports.modules={1562:(e,t,a)=>{Promise.resolve
12
12
  ## Commands
13
13
  \`\`\`bash
14
14
  # Install dependencies
15
- npm install
15
+ {{PACKAGE_MANAGER}} install
16
16
 
17
17
  # Start development
18
18
  npm run dev
@@ -24,10 +24,15 @@ npm run build
24
24
  npm test
25
25
  \`\`\`
26
26
 
27
- ## Key architecture rules
28
- - Follow existing patterns before introducing new abstractions
29
- - Keep modules small and focused
30
- - Write tests for business logic
27
+ ## Architecture
28
+ - Primary language: {{PRIMARY_LANGUAGE}}
29
+ - Deployment: {{DEPLOYMENT_PLATFORM}}
30
+ - Key directories: \`src/\`, \`docs/\`, \`tests/\`
31
+ - See \`docs/architecture/overview.md\` for full details
32
+
33
+ ## Read before coding
34
+ - @docs/architecture/overview.md
35
+ - @CONTRIBUTING.md
31
36
 
32
37
  ## Key conventions
33
38
  {{CONVENTIONS}}
@@ -36,11 +41,18 @@ npm test
36
41
  {{KEY_FEATURES}}
37
42
 
38
43
  ## Non-negotiables
39
- - Keep code clean and well-documented
44
+ - Always run \`npm run build\` before marking a task done — build must pass
45
+ - Never use localStorage — causes SSR/client mismatch
46
+ - Never commit secrets or credentials
40
47
  - Maintain test coverage
41
48
  - Follow security best practices
42
- - Never commit secrets or credentials
43
- `},{id:"agents-md",name:"AGENTS.md",description:"AI agent instructions (multi-agent / OpenAI)",defaultPath:"AGENTS.md",content:`# {{PROJECT_NAME}} — Agent Instructions
49
+
50
+ ## Code style
51
+ - Follow existing patterns before introducing new abstractions
52
+ - Keep modules small and focused
53
+ - Write tests for business logic
54
+ - Prefer explicit over implicit
55
+ `},{id:"agents-md",name:"AGENTS.md",description:"AI agent instructions (multi-agent / OpenAI)",defaultPath:"AGENTS.md",category:"ai-agent",content:`# {{PROJECT_NAME}} — Agent Instructions
44
56
 
45
57
  ## Overview
46
58
  {{DESCRIPTION}}
@@ -63,7 +75,7 @@ npm test
63
75
  - Follow existing code patterns
64
76
  - Write tests for new features
65
77
  - Never commit secrets or credentials
66
- `},{id:"gemini-md",name:"GEMINI.md",description:"AI agent instructions for Gemini CLI",defaultPath:"GEMINI.md",content:`# {{PROJECT_NAME}} — Gemini Agent Instructions
78
+ `},{id:"gemini-md",name:"GEMINI.md",description:"AI agent instructions for Gemini CLI",defaultPath:"GEMINI.md",category:"ai-agent",content:`# {{PROJECT_NAME}} — Gemini Agent Instructions
67
79
 
68
80
  ## What this is
69
81
  {{DESCRIPTION}}
@@ -93,7 +105,7 @@ npm test
93
105
  - Follow existing code patterns
94
106
  - Write tests for new features
95
107
  - Never commit secrets or credentials
96
- `},{id:"cursorrules",name:".cursorrules",description:"Cursor IDE rules for AI assistance",defaultPath:".cursorrules",content:`# {{PROJECT_NAME}} — Cursor Rules
108
+ `},{id:"cursorrules",name:".cursorrules",description:"Cursor IDE rules for AI assistance",defaultPath:".cursorrules",category:"ai-agent",content:`# {{PROJECT_NAME}} — Cursor Rules
97
109
 
98
110
  ## Project overview
99
111
  {{DESCRIPTION}}
@@ -115,7 +127,7 @@ npm test
115
127
  - Don't break existing tests
116
128
  - Don't commit secrets or credentials
117
129
  - Don't over-engineer simple solutions
118
- `},{id:"windsurfrules",name:".windsurfrules",description:"Windsurf IDE rules for AI assistance",defaultPath:".windsurfrules",content:`# {{PROJECT_NAME}} — Windsurf Rules
130
+ `},{id:"windsurfrules",name:".windsurfrules",description:"Windsurf IDE rules for AI assistance",defaultPath:".windsurfrules",category:"ai-agent",content:`# {{PROJECT_NAME}} — Windsurf Rules
119
131
 
120
132
  ## Project overview
121
133
  {{DESCRIPTION}}
@@ -135,7 +147,7 @@ npm test
135
147
  - Don't introduce breaking changes
136
148
  - Don't commit secrets or credentials
137
149
  - Maintain test coverage
138
- `},{id:"copilot-instructions",name:"Copilot Instructions",description:"GitHub Copilot custom instructions",defaultPath:".github/copilot-instructions.md",content:`# GitHub Copilot Instructions — {{PROJECT_NAME}}
150
+ `},{id:"copilot-instructions",name:"Copilot Instructions",description:"GitHub Copilot custom instructions",defaultPath:".github/copilot-instructions.md",category:"ai-agent",content:`# GitHub Copilot Instructions — {{PROJECT_NAME}}
139
151
 
140
152
  ## Project overview
141
153
  {{DESCRIPTION}}
@@ -159,727 +171,1041 @@ npm test
159
171
  - Write tests for all new functionality
160
172
  - Maintain existing test coverage
161
173
  - Use the project's established testing patterns
162
- `},{id:"prd",name:"PRD",description:"Product requirements document",defaultPath:"docs/prd.md",content:`# Product Requirements {{PROJECT_NAME}}
174
+ `}],r=[{id:"contributing",name:"CONTRIBUTING.md",description:"Contribution guidelines",defaultPath:"CONTRIBUTING.md",category:"github",content:`# Contributing to {{PROJECT_NAME}}
163
175
 
164
- **Status:** Draft
165
- **Last updated:** {{DATE}}
166
- **Author:**
167
- **Stakeholders:**
176
+ Thank you for your interest in contributing!
168
177
 
169
- ## Problem statement
170
- {{DESCRIPTION}}
178
+ ## Getting started
171
179
 
172
- ## Goals
173
- -
174
- -
180
+ 1. Fork the repository
181
+ 2. Clone your fork: \`git clone {{REPO_URL}}\`
182
+ 3. Create a feature branch: \`git checkout -b feat/your-feature\`
183
+ 4. Make your changes
184
+ 5. Submit a pull request
175
185
 
176
- ## Non-goals
177
- -
178
- -
186
+ ## Branch naming
179
187
 
180
- ## User stories
181
- | As a... | I want to... | So that... |
182
- |---------|--------------|------------|
183
- | user | | |
188
+ | Type | Pattern | Example |
189
+ |------|---------|---------|
190
+ | Feature | \`feat/<description>\` | \`feat/user-auth\` |
191
+ | Fix | \`fix/<description>\` | \`fix/login-crash\` |
192
+ | Chore | \`chore/<description>\` | \`chore/update-deps\` |
193
+ | Docs | \`docs/<description>\` | \`docs/api-guide\` |
194
+ | Refactor | \`refactor/<description>\` | \`refactor/auth-module\` |
195
+ | Release | \`release/<version>\` | \`release/v1.2.0\` |
184
196
 
185
- ## Requirements
197
+ ## Commit conventions
186
198
 
187
- ### Functional
188
- {{KEY_FEATURES}}
199
+ We use [Conventional Commits](https://conventionalcommits.org):
189
200
 
190
- ### Non-functional
191
- - Performance:
192
- - Security:
193
- - Reliability:
194
- - Scalability:
201
+ | Type | When to use |
202
+ |------|------------|
203
+ | \`feat\` | New feature |
204
+ | \`fix\` | Bug fix |
205
+ | \`docs\` | Documentation only |
206
+ | \`refactor\` | Code change that's neither fix nor feature |
207
+ | \`test\` | Adding or updating tests |
208
+ | \`chore\` | Build process, dependencies, tooling |
209
+ | \`perf\` | Performance improvement |
210
+ | \`ci\` | CI/CD changes |
211
+
212
+ Examples:
213
+ \`\`\`
214
+ feat: add user authentication
215
+ fix: resolve login redirect issue
216
+ docs: update API reference
217
+ chore: upgrade dependencies
218
+ feat!: redesign auth API (breaking change — note the !)
219
+ \`\`\`
195
220
 
196
- ## Success metrics
197
- | Metric | Current | Target |
198
- |--------|---------|--------|
199
- | | | |
221
+ ## PR size guidance
200
222
 
201
- ## Timeline
202
- | Milestone | Target date |
203
- |-----------|-------------|
204
- | | |
223
+ | Size | Lines changed | Guidance |
224
+ |------|--------------|---------|
225
+ | Small | < 400 lines | Ideal — fast to review |
226
+ | Medium | 400–800 lines | Acceptable — add extra context in description |
227
+ | Large | > 800 lines | Needs discussion before opening — split if possible |
205
228
 
206
- ## Open questions
207
- -
208
- `},{id:"architecture-overview",name:"Architecture Overview",description:"System architecture doc",defaultPath:"docs/architecture/overview.md",content:`# Architecture Overview — {{PROJECT_NAME}}
229
+ Large PRs slow down the team and increase the chance of missed issues. When in doubt, split.
209
230
 
210
- **Last updated:** {{DATE}}
231
+ ## Pull request process
211
232
 
212
- ## Summary
213
- {{DESCRIPTION}}
233
+ 1. Fill out the PR template completely
234
+ 2. Ensure all CI checks pass
235
+ 3. Request review from at least one maintainer
236
+ 4. Address all review comments
237
+ 5. Squash commits before merge
214
238
 
215
- ## Tech stack
216
- {{TECH_STACK}}
239
+ ## Code review checklist
217
240
 
218
- ## System diagram
241
+ **Author:**
242
+ - [ ] Self-reviewed the diff before requesting review
243
+ - [ ] PR description explains the "why", not just the "what"
244
+ - [ ] Tests added/updated and passing
245
+ - [ ] No secrets or credentials in code
246
+ - [ ] Breaking changes noted in PR description
219
247
 
220
- \`\`\`mermaid
221
- graph TB
222
- Client["Client"] --> API["API Layer"]
223
- API --> DB["Database"]
224
- API --> Cache["Cache"]
225
- \`\`\`
248
+ **Reviewer:**
249
+ - [ ] Code is correct and handles edge cases
250
+ - [ ] No obvious performance issues
251
+ - [ ] Tests are meaningful (not just coverage padding)
252
+ - [ ] Naming is clear and consistent with the codebase
253
+ - [ ] Documentation updated if public API changed
226
254
 
227
- ## Components
255
+ ## Code style
256
+ {{CONVENTIONS}}
228
257
 
229
- | Component | Responsibility | Tech |
230
- |-----------|---------------|------|
231
- | | | |
258
+ ## Reporting bugs
232
259
 
233
- ## Data flow
260
+ Open an issue with:
261
+ - Description of the bug
262
+ - Steps to reproduce
263
+ - Expected vs actual behavior
264
+ - Environment details
265
+ `},{id:"security",name:"SECURITY.md",description:"Security policy and vulnerability reporting",defaultPath:"SECURITY.md",category:"github",content:`# Security Policy — {{PROJECT_NAME}}
234
266
 
235
- 1.
236
- 2.
237
- 3.
267
+ ## Supported versions
238
268
 
239
- ## Key decisions
240
- -
269
+ | Version | Supported |
270
+ |---------|-----------|
271
+ | latest | ✅ |
272
+ | < 1.0 | ❌ |
241
273
 
242
- ## Security considerations
243
- - Authentication:
244
- - Authorization:
245
- - Data validation:
246
- - Secrets management:
274
+ ## Reporting a vulnerability
247
275
 
248
- ## Scalability notes
249
- -
250
- `},{id:"api-reference",name:"API Reference",description:"API endpoints reference",defaultPath:"docs/api-reference.md",content:`# API Reference — {{PROJECT_NAME}}
276
+ **Please do not report security vulnerabilities through public GitHub issues.**
251
277
 
252
- **Last updated:** {{DATE}}
278
+ To report a security issue, email: **security@example.com**
253
279
 
254
- ## Base URL
280
+ You may optionally encrypt your report using our PGP key (key ID: \`0x00000000\`, available on keys.openpgp.org).
255
281
 
256
- \`\`\`
257
- https://api.example.com/v1
258
- \`\`\`
282
+ Include:
283
+ - Description of the vulnerability
284
+ - Steps to reproduce
285
+ - Potential impact
286
+ - Any suggested mitigations
259
287
 
260
- ## Authentication
288
+ You will receive a response within **48 hours**. We will:
289
+ 1. Confirm receipt of your report
290
+ 2. Investigate and assess the issue
291
+ 3. Release a fix or mitigation
292
+ 4. Credit you in the release notes (unless you prefer anonymity)
261
293
 
262
- All requests require a bearer token in the Authorization header:
294
+ ## Vulnerability SLAs
263
295
 
264
- \`\`\`
265
- Authorization: Bearer <token>
266
- \`\`\`
296
+ | Severity | Fix SLA |
297
+ |----------|---------|
298
+ | Critical | 48 hours |
299
+ | High | 7 days |
300
+ | Medium | 30 days |
301
+ | Low | 90 days |
267
302
 
268
- ## Rate limiting
303
+ Dependabot alerts for **critical** vulnerabilities must be resolved within 48 hours. Run \`npm audit\` in CI on every PR.
269
304
 
270
- - **Limit:** 1000 requests/hour per API key
271
- - **Headers:** \`X-RateLimit-Limit\`, \`X-RateLimit-Remaining\`, \`X-RateLimit-Reset\`
305
+ ## Secrets rotation schedule
272
306
 
273
- ## Pagination
307
+ | Secret | Rotation | Owner |
308
+ |--------|----------|-------|
309
+ | JWT signing key | Every 90 days | Platform team |
310
+ | Database passwords | Every 180 days | Platform team |
311
+ | API keys (third-party) | On staff change | Security team |
312
+ | Deploy tokens | Every 90 days | DevOps |
274
313
 
275
- List endpoints support cursor-based pagination:
314
+ ## OWASP Top 10 checklist
276
315
 
277
- \`\`\`
278
- GET /resources?cursor=<cursor>&limit=20
279
- \`\`\`
316
+ - [ ] **A01 Broken Access Control** — Enforce authorization on every endpoint; deny by default
317
+ - [ ] **A02 Cryptographic Failures** — Use TLS everywhere; never store plaintext secrets; use bcrypt/argon2 for passwords
318
+ - [ ] **A03 Injection** — Use parameterized queries; validate and sanitize all input
319
+ - [ ] **A04 Insecure Design** — Threat model new features; use principle of least privilege
320
+ - [ ] **A05 Security Misconfiguration** — Harden defaults; disable unused features; set security headers
321
+ - [ ] **A06 Vulnerable Components** — Run \`npm audit\` in CI; automate with Dependabot
322
+ - [ ] **A07 Auth Failures** — Implement MFA; lock accounts after failed attempts; use secure session management
323
+ - [ ] **A08 Software Integrity Failures** — Verify checksums; use lockfiles; pin CI action versions
324
+ - [ ] **A09 Logging Failures** — Log auth events, access failures; never log secrets or PII
325
+ - [ ] **A10 SSRF** — Validate and allowlist URLs for any server-side requests
280
326
 
281
- ## Error codes
327
+ ## Security best practices
282
328
 
283
- | Code | Meaning |
284
- |------|---------|
285
- | 400 | Bad request invalid parameters |
286
- | 401 | Unauthorized missing or invalid token |
287
- | 403 | Forbidden insufficient permissions |
288
- | 404 | Not found |
289
- | 422 | Unprocessable entity — validation error |
290
- | 429 | Too many requests |
291
- | 500 | Internal server error |
329
+ When contributing to this project:
330
+ - Never commit secrets, tokens, or credentials
331
+ - Use environment variables for all sensitive configuration
332
+ - Validate and sanitize all user input
333
+ - Follow the principle of least privilege
334
+ - Keep dependencies up to date
335
+ `},{id:"pr-template",name:"PR Template",description:"Pull request template",defaultPath:".github/pull_request_template.md",category:"github",content:`## Description
292
336
 
293
- ## Endpoints
337
+ <!-- Briefly describe the changes and why they were made -->
294
338
 
295
- ### GET /resource
339
+ ## Type of change
296
340
 
297
- **Description:** List resources
341
+ - [ ] Bug fix (non-breaking change that fixes an issue)
342
+ - [ ] New feature (non-breaking change that adds functionality)
343
+ - [ ] Breaking change (fix or feature that would cause existing functionality to change)
344
+ - [ ] Documentation update
345
+ - [ ] Refactor / code cleanup
346
+ - [ ] Dependency update
298
347
 
299
- **Query parameters:**
300
- - \`limit\` (integer, default 20) — items per page
301
- - \`cursor\` (string) — pagination cursor
348
+ ## Related issues
302
349
 
303
- **Response:**
304
- \`\`\`json
305
- {
306
- "data": [],
307
- "cursor": null,
308
- "total": 0
309
- }
310
- \`\`\`
350
+ Closes #
311
351
 
312
- ### POST /resource
352
+ ## How to test
313
353
 
314
- **Description:** Create a resource
354
+ 1.
355
+ 2.
356
+ 3.
315
357
 
316
- **Request body:**
317
- \`\`\`json
318
- {}
319
- \`\`\`
358
+ ## Screenshots / recordings
320
359
 
321
- **Response:**
322
- \`\`\`json
323
- {}
324
- \`\`\`
325
- `},{id:"runbook",name:"Runbook",description:"Operational runbook",defaultPath:"docs/runbook.md",content:`# Runbook — {{PROJECT_NAME}}
360
+ <!-- If applicable, add screenshots or screen recordings -->
326
361
 
327
- **Last updated:** {{DATE}}
362
+ ## Checklist
328
363
 
329
- ## Overview
330
- {{DESCRIPTION}}
364
+ - [ ] My code follows the project's style guidelines
365
+ - [ ] I have performed a self-review of my changes
366
+ - [ ] I have added tests that prove my fix or feature works
367
+ - [ ] New and existing unit tests pass locally
368
+ - [ ] I have updated documentation if needed
369
+ - [ ] No secrets or credentials are included
370
+ `},{id:"bug-report",name:"Bug Report Template",description:"GitHub issue template for bugs",defaultPath:".github/ISSUE_TEMPLATE/bug_report.md",category:"github",content:`---
371
+ name: Bug report
372
+ about: Create a report to help us improve
373
+ labels: bug
374
+ ---
331
375
 
332
- ## SLOs
376
+ ## Describe the bug
333
377
 
334
- | Metric | Target |
335
- |--------|--------|
336
- | Availability | 99.9% |
337
- | P95 latency | < 500ms |
338
- | Error rate | < 0.1% |
378
+ A clear and concise description of what the bug is.
339
379
 
340
- ## Environments
380
+ ## Steps to reproduce
341
381
 
342
- | Env | URL | Purpose |
343
- |-----|-----|---------|
344
- | Production | | Live traffic |
345
- | Staging | | Pre-release testing |
346
- | Development | | Local dev |
382
+ 1. Go to '...'
383
+ 2. Click on '...'
384
+ 3. See error
347
385
 
348
- ## Alerting
386
+ ## Expected behavior
349
387
 
350
- | Alert | Threshold | Severity | Action |
351
- |-------|-----------|----------|--------|
352
- | | | | |
388
+ A clear and concise description of what you expected to happen.
353
389
 
354
- ## On-call contacts
390
+ ## Actual behavior
355
391
 
356
- | Role | Name | Contact |
357
- |------|------|---------|
358
- | Primary | | |
359
- | Secondary | | |
392
+ What actually happened.
360
393
 
361
- ## Procedures
394
+ ## Screenshots
362
395
 
363
- ### Deploy
396
+ If applicable, add screenshots to help explain your problem.
364
397
 
365
- 1.
366
- 2.
367
- 3.
398
+ ## Environment
368
399
 
369
- ### Rollback
400
+ - OS: [e.g. macOS 14]
401
+ - Browser: [e.g. Chrome 120]
402
+ - Version: [e.g. 1.2.3]
403
+ - Node.js: [e.g. 20.x]
370
404
 
371
- 1.
372
- 2.
373
- 3.
405
+ ## Additional context
374
406
 
375
- ### Troubleshooting
407
+ Add any other context about the problem here.
408
+ `},{id:"feature-request",name:"Feature Request Template",description:"GitHub issue template for features",defaultPath:".github/ISSUE_TEMPLATE/feature_request.md",category:"github",content:`---
409
+ name: Feature request
410
+ about: Suggest an idea for this project
411
+ labels: enhancement
412
+ ---
376
413
 
377
- #### High error rate
378
- 1. Check application logs
379
- 2. Check downstream dependencies
380
- 3. Review recent deploys
414
+ ## Problem
381
415
 
382
- #### High latency
383
- 1. Check database query times
384
- 2. Check cache hit rates
385
- 3. Review resource utilization
416
+ Is your feature request related to a problem? Please describe.
417
+ A clear and concise description of what the problem is.
386
418
 
387
- ## Escalation path
419
+ ## Proposed solution
388
420
 
389
- 1. On-call engineer
390
- 2. Team lead
391
- 3. Engineering manager
392
- `},{id:"adr",name:"Architecture Decision",description:"Architecture Decision Record",defaultPath:"docs/architecture/decisions/ADR-001.md",content:`# ADR-001: Title
421
+ A clear and concise description of what you want to happen.
393
422
 
394
- **Status:** Proposed
395
- **Date:** {{DATE}}
396
- **Deciders:**
423
+ ## Alternatives considered
397
424
 
398
- ## Context
399
- What is the issue that we're seeing that is motivating this decision or change?
425
+ A clear and concise description of any alternative solutions or features you've considered.
400
426
 
401
- ## Decision
402
- What is the change that we're proposing and/or doing?
427
+ ## Implementation notes
403
428
 
404
- ## Rationale
405
- Why did we choose this option?
429
+ Any thoughts on how this might be implemented?
406
430
 
407
- ## Alternatives considered
408
- - **Option A:** Description — pros/cons
409
- - **Option B:** Description — pros/cons
431
+ ## Additional context
410
432
 
411
- ## Consequences
433
+ Add any other context, mockups, or screenshots about the feature request here.
434
+ `}],i=[{id:"changelog",name:"CHANGELOG.md",description:"Keep a Changelog format",defaultPath:"CHANGELOG.md",category:"process",content:`# Changelog — {{PROJECT_NAME}}
412
435
 
413
- ### Positive
436
+ All notable changes to this project will be documented in this file.
437
+
438
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
439
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
440
+
441
+ ## [Unreleased]
442
+
443
+ ### Added
414
444
  -
415
445
 
416
- ### Negative
446
+ ### Changed
417
447
  -
418
448
 
419
- ### Neutral
449
+ ### Fixed
420
450
  -
421
- `},{id:"meeting-notes",name:"Meeting Notes",description:"Meeting notes template",defaultPath:`docs/meetings/${m}.md`,content:`# Meeting Notes — ${m}
422
451
 
423
- **Attendees:**
424
- **Facilitator:**
452
+ ### Removed
453
+ -
425
454
 
426
- ## Agenda
455
+ ## [1.0.0] — {{DATE}}
427
456
 
428
- 1.
429
- 2.
457
+ ### Added
458
+ - Initial release
459
+ `},{id:"deployment",name:"DEPLOYMENT.md",description:"Deployment guide and procedures",defaultPath:"DEPLOYMENT.md",category:"process",content:`# Deployment Guide — {{PROJECT_NAME}}
430
460
 
431
- ## Notes
461
+ **Last updated:** {{DATE}}
432
462
 
433
- ## Decisions
463
+ ## Environments
434
464
 
435
- ## Action items
465
+ | Environment | URL | Branch | Auto-deploy |
466
+ |-------------|-----|--------|-------------|
467
+ | Production | | \`main\` | No |
468
+ | Staging | | \`develop\` | Yes |
469
+ | Preview | | PRs | Yes |
436
470
 
437
- | Action | Owner | Due |
438
- |--------|-------|-----|
439
- | | | |
471
+ ## Prerequisites
440
472
 
441
- ## Next meeting
442
- `},{id:"onboarding",name:"Onboarding Guide",description:"Developer onboarding guide",defaultPath:"docs/onboarding.md",content:`# Developer Onboarding — {{PROJECT_NAME}}
473
+ - Access to deployment platform
474
+ - Environment variables configured (see \`.env.example\`)
475
+ - CI/CD pipeline passing
476
+
477
+ ## Deploy to production
478
+
479
+ \`\`\`bash
480
+ # 1. Ensure tests pass
481
+ npm test
482
+
483
+ # 2. Build and verify
484
+ npm run build
485
+
486
+ # 3. Merge to main
487
+ git checkout main && git merge develop
488
+
489
+ # 4. Tag the release
490
+ git tag v1.x.x && git push --tags
491
+ \`\`\`
492
+
493
+ ## Environment variables
494
+
495
+ | Variable | Required | Description |
496
+ |----------|----------|-------------|
497
+ | | Yes | |
498
+
499
+ ## Rollback procedure
500
+
501
+ 1. Identify the last stable release tag
502
+ 2. \`git checkout <tag>\`
503
+ 3. Redeploy the previous version
504
+ 4. Verify the rollback with smoke tests
505
+
506
+ ## Smoke tests
507
+
508
+ After every deploy, verify:
509
+ - [ ] App loads at production URL
510
+ - [ ] Auth flow works
511
+ - [ ] Core features functional
512
+ - [ ] No error spikes in monitoring
513
+
514
+ ## Contacts
515
+
516
+ | Role | Contact |
517
+ |------|---------|
518
+ | On-call | |
519
+ | Release manager | |
520
+ `},{id:"testing",name:"TESTING.md",description:"Testing strategy and guide",defaultPath:"TESTING.md",category:"process",content:`# Testing Guide — {{PROJECT_NAME}}
443
521
 
444
522
  **Last updated:** {{DATE}}
445
523
 
446
- ## Overview
447
- {{DESCRIPTION}}
524
+ ## Test pyramid
448
525
 
449
- ## Prerequisites
450
- - [ ] Access to repository ({{REPO_URL}})
451
- - [ ] Access to staging environment
452
- - [ ] Accounts: (list required accounts/services)
526
+ \`\`\`
527
+ /\\
528
+ /E2E\\ 10% Critical user flows only
529
+ /------\\
530
+ /Integr. \\ 20% — API, DB, service boundaries
531
+ /----------\\
532
+ / Unit \\ 70% — Functions, logic, utilities
533
+ /______________\\
534
+ \`\`\`
453
535
 
454
- ## Day 1 checklist
455
- - [ ] Clone the repository
456
- - [ ] Set up local development environment
457
- - [ ] Run the app locally
458
- - [ ] Read the architecture overview
459
- - [ ] Meet the team
536
+ ## Test strategy
460
537
 
461
- ## Environment setup
538
+ | Layer | Type | Tool | Coverage target |
539
+ |-------|------|------|----------------|
540
+ | Unit | Functions/logic | {{TEST_FRAMEWORK}} | 80%+ |
541
+ | Integration | API/DB | {{TEST_FRAMEWORK}} | 70%+ |
542
+ | E2E | User flows | Playwright | Key paths |
543
+
544
+ ## Coverage targets by directory
545
+
546
+ | Directory | Target | Rationale |
547
+ |-----------|--------|-----------|
548
+ | \`src/lib/\` | 90%+ | Core business logic |
549
+ | \`src/api/\` | 80%+ | API handlers |
550
+ | \`src/components/\` | 60%+ | UI — focus on logic, not rendering |
551
+ | \`src/utils/\` | 90%+ | Pure utility functions |
552
+
553
+ ## Running tests
462
554
 
463
555
  \`\`\`bash
464
- # Clone
465
- git clone {{REPO_URL}}
466
- cd {{PROJECT_NAME}}
556
+ # Run all tests
557
+ npm test
467
558
 
468
- # Install dependencies
469
- npm install
559
+ # Run with coverage
560
+ npm run test:coverage
470
561
 
471
- # Copy environment variables
472
- cp .env.example .env.local
562
+ # Run E2E tests
563
+ npm run test:e2e
473
564
 
474
- # Start development server
475
- npm run dev
565
+ # Watch mode
566
+ npm run test:watch
476
567
  \`\`\`
477
568
 
478
- ## Tech stack
479
- {{TECH_STACK}}
569
+ ## Writing tests
480
570
 
481
- ## IDE setup
482
- - Recommended: VS Code or Cursor
483
- - Install recommended extensions (see \`.vscode/extensions.json\`)
484
- - Enable format on save
571
+ ### Unit test example
485
572
 
486
- ## Project structure
573
+ \`\`\`typescript
574
+ describe('MyFunction', () => {
575
+ it('should return expected value', () => {
576
+ expect(myFunction(input)).toBe(expected)
577
+ })
578
+ })
579
+ \`\`\`
580
+
581
+ ### Integration test guidelines
582
+ - Use a real database (not mocks) for DB tests
583
+ - Reset state between tests
584
+ - Test happy path and error cases
487
585
 
586
+ ### E2E test guidelines
587
+ - Cover critical user journeys
588
+ - Use stable selectors (\`data-testid\`)
589
+ - Run against staging environment
590
+
591
+ ### Playwright config example
592
+
593
+ \`\`\`typescript
594
+ // playwright.config.ts
595
+ import { defineConfig, devices } from '@playwright/test'
596
+
597
+ export default defineConfig({
598
+ testDir: './e2e',
599
+ fullyParallel: true,
600
+ forbidOnly: !!process.env.CI,
601
+ retries: process.env.CI ? 2 : 0,
602
+ reporter: 'html',
603
+ use: {
604
+ baseURL: process.env.PLAYWRIGHT_BASE_URL ?? 'http://localhost:3000',
605
+ trace: 'on-first-retry',
606
+ },
607
+ projects: [
608
+ {name: 'chromium', use: {...devices['Desktop Chrome']}},
609
+ {name: 'Mobile Safari', use: {...devices['iPhone 13']}},
610
+ ],
611
+ webServer: {
612
+ command: 'npm run dev',
613
+ url: 'http://localhost:3000',
614
+ reuseExistingServer: !process.env.CI,
615
+ },
616
+ })
488
617
  \`\`\`
489
- (describe key directories here)
618
+
619
+ ## Flaky test policy
620
+
621
+ 1. **Quarantine immediately** — tag with \`@flaky\` and skip in CI (\`test.skip\`)
622
+ 2. **Create a ticket** — track as a P2 bug with a 2-week SLA to fix
623
+ 3. **Root cause** — common causes: timing issues, shared state, network calls
624
+ 4. **Fix or delete** — flaky tests are worse than no tests (false confidence)
625
+
626
+ Quarantine example:
627
+ \`\`\`typescript
628
+ test.skip('flaky: timing issue with animation', async ({ page }) => {
629
+ // TODO: fix by waiting for animation end event instead of sleep
630
+ })
490
631
  \`\`\`
491
632
 
492
- ## Key concepts
633
+ ## Test organization
634
+
635
+ \`\`\`
636
+ src/
637
+ __tests__/ # Unit tests
638
+ __integration__/ # Integration tests
639
+ e2e/ # E2E tests
640
+ \`\`\`
641
+
642
+ ## CI/CD
643
+
644
+ Tests run automatically on every PR. PRs cannot merge with failing tests.
645
+ `},{id:"glossary",name:"Glossary",description:"Project terminology reference",defaultPath:"docs/glossary.md",category:"process",content:`# Glossary — {{PROJECT_NAME}}
646
+
647
+ **Last updated:** {{DATE}}
648
+
649
+ This document defines terms used throughout the project documentation and codebase.
650
+
651
+ ## Terms
652
+
653
+ | Term | Definition |
654
+ |------|------------|
655
+ | | |
656
+
657
+ ## Acronyms
658
+
659
+ | Acronym | Full form | Meaning |
660
+ |---------|-----------|---------|
661
+ | | | |
662
+
663
+ ## Domain concepts
664
+
665
+ <!-- Add domain-specific concepts here -->
666
+
667
+ ---
668
+
669
+ *Keep this document updated as new terminology is introduced.*
670
+ `}],n=new Date().toISOString().split("T")[0],o=[...s,...r,...i,{id:"prd",name:"PRD",description:"Product requirements document",defaultPath:"docs/prd.md",category:"technical",content:`# Product Requirements — {{PROJECT_NAME}}
671
+
672
+ **Status:** Draft
673
+ **Last updated:** {{DATE}}
674
+ **Author:**
675
+ **Stakeholders:**
676
+
677
+ ## Problem statement
678
+ {{DESCRIPTION}}
679
+
680
+ ## Goals
681
+ -
493
682
  -
494
683
 
495
- ## Common tasks
684
+ ## Non-goals
685
+ -
686
+ -
496
687
 
497
- ### Running tests
498
- \`\`\`bash
499
- npm test
688
+ ## User stories
689
+ | As a... | I want to... | So that... |
690
+ |---------|--------------|------------|
691
+ | user | | |
692
+
693
+ ## Requirements
694
+
695
+ ### Functional
696
+ {{KEY_FEATURES}}
697
+
698
+ ### Non-functional
699
+ - Performance:
700
+ - Security:
701
+ - Reliability:
702
+ - Scalability:
703
+
704
+ ## Success metrics
705
+ | Metric | Current | Target |
706
+ |--------|---------|--------|
707
+ | | | |
708
+
709
+ ## Timeline
710
+ | Milestone | Target date |
711
+ |-----------|-------------|
712
+ | | |
713
+
714
+ ## Open questions
715
+ -
716
+ `},{id:"architecture-overview",name:"Architecture Overview",description:"System architecture doc",defaultPath:"docs/architecture/overview.md",category:"technical",content:`# Architecture Overview — {{PROJECT_NAME}}
717
+
718
+ **Last updated:** {{DATE}}
719
+
720
+ ## Summary
721
+ {{DESCRIPTION}}
722
+
723
+ ## Tech stack
724
+ {{TECH_STACK}}
725
+
726
+ ## System diagram
727
+
728
+ ### Context (C4 Level 1)
729
+
730
+ \`\`\`mermaid
731
+ graph TB
732
+ User["User"] --> System["{{PROJECT_NAME}}"]
733
+ System --> ExternalAPI["External APIs"]
734
+ System --> DB["Database"]
500
735
  \`\`\`
501
736
 
502
- ### Building for production
503
- \`\`\`bash
504
- npm run build
737
+ ### Container (C4 Level 2)
738
+
739
+ \`\`\`mermaid
740
+ graph TB
741
+ Client["Web Client<br/>(Browser)"] --> API["API Server<br/>(Node.js)"]
742
+ API --> DB["Database<br/>(PostgreSQL)"]
743
+ API --> Cache["Cache<br/>(Redis)"]
744
+ API --> Queue["Job Queue"]
505
745
  \`\`\`
506
746
 
507
- ## Key contacts
747
+ ## Components
508
748
 
509
- | Role | Name | Contact |
510
- |------|------|---------|
511
- | | | |
749
+ | Component | Responsibility | Tech |
750
+ |-----------|---------------|------|
751
+ | | | |
512
752
 
513
- ## Resources
514
- - Architecture overview: \`docs/architecture/overview.md\`
515
- - API reference: \`docs/api-reference.md\`
516
- - Runbook: \`docs/runbook.md\`
517
- `},{id:"contributing",name:"CONTRIBUTING.md",description:"Contribution guidelines",defaultPath:"CONTRIBUTING.md",content:`# Contributing to {{PROJECT_NAME}}
753
+ ## Data flow
518
754
 
519
- Thank you for your interest in contributing!
755
+ 1.
756
+ 2.
757
+ 3.
520
758
 
521
- ## Getting started
759
+ ## Key decisions
522
760
 
523
- 1. Fork the repository
524
- 2. Clone your fork: \`git clone {{REPO_URL}}\`
525
- 3. Create a feature branch: \`git checkout -b feat/your-feature\`
526
- 4. Make your changes
527
- 5. Submit a pull request
761
+ | Decision | Chosen | Alternative | Rationale |
762
+ |----------|--------|-------------|-----------|
763
+ | | | | |
528
764
 
529
- ## Branch naming
765
+ ## ADR log
530
766
 
531
- | Type | Pattern | Example |
532
- |------|---------|---------|
533
- | Feature | \`feat/<description>\` | \`feat/user-auth\` |
534
- | Fix | \`fix/<description>\` | \`fix/login-crash\` |
535
- | Chore | \`chore/<description>\` | \`chore/update-deps\` |
536
- | Docs | \`docs/<description>\` | \`docs/api-guide\` |
767
+ | ADR | Title | Status | Date |
768
+ |-----|-------|--------|------|
769
+ | 001 | | Accepted | {{DATE}} |
537
770
 
538
- ## Commit conventions
771
+ ## Non-goals
772
+
773
+ - <!-- What this system explicitly does NOT do -->
774
+
775
+ ## Security considerations
776
+ - Authentication:
777
+ - Authorization:
778
+ - Data validation:
779
+ - Secrets management:
780
+
781
+ ## Scalability notes
782
+ -
783
+ `},{id:"api-reference",name:"API Reference",description:"API endpoints reference",defaultPath:"docs/api-reference.md",category:"technical",content:`# API Reference — {{PROJECT_NAME}}
784
+
785
+ **Last updated:** {{DATE}}
539
786
 
540
- We use [Conventional Commits](https://conventionalcommits.org):
787
+ ## Base URL
541
788
 
542
789
  \`\`\`
543
- feat: add user authentication
544
- fix: resolve login redirect issue
545
- docs: update API reference
546
- chore: upgrade dependencies
790
+ https://api.example.com/v1
547
791
  \`\`\`
548
792
 
549
- ## Pull request process
793
+ ## Versioning
550
794
 
551
- 1. Fill out the PR template completely
552
- 2. Ensure all CI checks pass
553
- 3. Request review from at least one maintainer
554
- 4. Address all review comments
555
- 5. Squash commits before merge
795
+ This API uses URL-based versioning (\`/v1/\`, \`/v2/\`, etc.).
556
796
 
557
- ## PR review checklist
797
+ - The current stable version is \`v1\`.
798
+ - Deprecated versions are supported for 12 months after a new version is released.
799
+ - Breaking changes always increment the major version.
558
800
 
559
- - [ ] Code follows project conventions
560
- - [ ] Tests added/updated
561
- - [ ] Documentation updated if needed
562
- - [ ] No secrets or credentials in code
563
- - [ ] Breaking changes documented
801
+ ## Authentication
564
802
 
565
- ## Code style
566
- {{CONVENTIONS}}
803
+ All requests require a bearer token in the Authorization header:
567
804
 
568
- ## Reporting bugs
805
+ \`\`\`
806
+ Authorization: Bearer <token>
807
+ \`\`\`
569
808
 
570
- Open an issue with:
571
- - Description of the bug
572
- - Steps to reproduce
573
- - Expected vs actual behavior
574
- - Environment details
575
- `},{id:"security",name:"SECURITY.md",description:"Security policy and vulnerability reporting",defaultPath:"SECURITY.md",content:`# Security Policy — {{PROJECT_NAME}}
809
+ ### Token refresh
576
810
 
577
- ## Supported versions
811
+ Tokens expire after 1 hour. Refresh using:
578
812
 
579
- | Version | Supported |
580
- |---------|-----------|
581
- | latest | ✅ |
582
- | < 1.0 | ❌ |
813
+ \`\`\`
814
+ POST /auth/refresh
815
+ Content-Type: application/json
583
816
 
584
- ## Reporting a vulnerability
817
+ {"refreshToken": "<refresh_token>"}
818
+ \`\`\`
585
819
 
586
- **Please do not report security vulnerabilities through public GitHub issues.**
820
+ **Response:**
821
+ \`\`\`json
822
+ {"accessToken": "...", "refreshToken": "...", "expiresIn": 3600}
823
+ \`\`\`
587
824
 
588
- To report a security issue, email: security@example.com
825
+ ## Rate limiting
589
826
 
590
- Include:
591
- - Description of the vulnerability
592
- - Steps to reproduce
593
- - Potential impact
594
- - Any suggested mitigations
827
+ - **Limit:** 1000 requests/hour per API key
828
+ - **Headers:** \`X-RateLimit-Limit\`, \`X-RateLimit-Remaining\`, \`X-RateLimit-Reset\`
595
829
 
596
- You will receive a response within 48 hours. We will:
597
- 1. Confirm receipt of your report
598
- 2. Investigate and assess the issue
599
- 3. Release a fix or mitigation
600
- 4. Credit you in the release notes (unless you prefer anonymity)
830
+ ## Pagination
601
831
 
602
- ## Security best practices
832
+ List endpoints support cursor-based pagination:
603
833
 
604
- When contributing to this project:
605
- - Never commit secrets, tokens, or credentials
606
- - Use environment variables for all sensitive configuration
607
- - Validate and sanitize all user input
608
- - Follow the principle of least privilege
609
- - Keep dependencies up to date
610
- `},{id:"pr-template",name:"PR Template",description:"Pull request template",defaultPath:".github/pull_request_template.md",content:`## Description
834
+ \`\`\`
835
+ GET /resources?cursor=<cursor>&limit=20
836
+ \`\`\`
611
837
 
612
- <!-- Briefly describe the changes and why they were made -->
838
+ ## Error format
613
839
 
614
- ## Type of change
840
+ All errors follow a standard envelope:
615
841
 
616
- - [ ] Bug fix (non-breaking change that fixes an issue)
617
- - [ ] New feature (non-breaking change that adds functionality)
618
- - [ ] Breaking change (fix or feature that would cause existing functionality to change)
619
- - [ ] Documentation update
620
- - [ ] Refactor / code cleanup
621
- - [ ] Dependency update
842
+ \`\`\`json
843
+ {
844
+ "code": "VALIDATION_ERROR",
845
+ "message": "Human-readable description",
846
+ "details": [{"field": "email", "issue": "invalid format"}]
847
+ }
848
+ \`\`\`
622
849
 
623
- ## Related issues
850
+ ## Error codes
624
851
 
625
- Closes #
852
+ | Code | Meaning |
853
+ |------|---------|
854
+ | 400 | Bad request — invalid parameters |
855
+ | 401 | Unauthorized — missing or invalid token |
856
+ | 403 | Forbidden — insufficient permissions |
857
+ | 404 | Not found |
858
+ | 422 | Unprocessable entity — validation error |
859
+ | 429 | Too many requests |
860
+ | 500 | Internal server error |
626
861
 
627
- ## How to test
862
+ ## Webhooks
628
863
 
629
- 1.
630
- 2.
631
- 3.
864
+ ### Signature verification
632
865
 
633
- ## Screenshots / recordings
866
+ All webhook payloads are signed with HMAC-SHA256. Verify the signature:
634
867
 
635
- <!-- If applicable, add screenshots or screen recordings -->
868
+ \`\`\`
869
+ X-Webhook-Signature: sha256=<hmac_hex>
870
+ \`\`\`
636
871
 
637
- ## Checklist
872
+ \`\`\`typescript
873
+ import crypto from 'crypto'
874
+
875
+ function verifyWebhook(payload: string, signature: string, secret: string): boolean {
876
+ const expected = crypto
877
+ .createHmac('sha256', secret)
878
+ .update(payload)
879
+ .digest('hex')
880
+ return crypto.timingSafeEqual(
881
+ Buffer.from(\`sha256=\${expected}\`),
882
+ Buffer.from(signature)
883
+ )
884
+ }
885
+ \`\`\`
638
886
 
639
- - [ ] My code follows the project's style guidelines
640
- - [ ] I have performed a self-review of my changes
641
- - [ ] I have added tests that prove my fix or feature works
642
- - [ ] New and existing unit tests pass locally
643
- - [ ] I have updated documentation if needed
644
- - [ ] No secrets or credentials are included
645
- `},{id:"bug-report",name:"Bug Report Template",description:"GitHub issue template for bugs",defaultPath:".github/ISSUE_TEMPLATE/bug_report.md",content:`---
646
- name: Bug report
647
- about: Create a report to help us improve
648
- labels: bug
649
- ---
887
+ ## Endpoints
650
888
 
651
- ## Describe the bug
889
+ ### GET /resource
652
890
 
653
- A clear and concise description of what the bug is.
891
+ **Description:** List resources
654
892
 
655
- ## Steps to reproduce
893
+ **Query parameters:**
894
+ - \`limit\` (integer, default 20) — items per page
895
+ - \`cursor\` (string) — pagination cursor
656
896
 
657
- 1. Go to '...'
658
- 2. Click on '...'
659
- 3. See error
897
+ **Response:**
898
+ \`\`\`json
899
+ {
900
+ "data": [],
901
+ "cursor": null,
902
+ "total": 0
903
+ }
904
+ \`\`\`
660
905
 
661
- ## Expected behavior
906
+ ### POST /resource
662
907
 
663
- A clear and concise description of what you expected to happen.
908
+ **Description:** Create a resource
664
909
 
665
- ## Actual behavior
910
+ **Request body:**
911
+ \`\`\`json
912
+ {}
913
+ \`\`\`
666
914
 
667
- What actually happened.
915
+ **Response:**
916
+ \`\`\`json
917
+ {}
918
+ \`\`\`
919
+ `},{id:"runbook",name:"Runbook",description:"Operational runbook",defaultPath:"docs/runbook.md",category:"technical",content:`# Runbook — {{PROJECT_NAME}}
668
920
 
669
- ## Screenshots
921
+ **Last updated:** {{DATE}}
670
922
 
671
- If applicable, add screenshots to help explain your problem.
923
+ ## Overview
924
+ {{DESCRIPTION}}
672
925
 
673
- ## Environment
926
+ ## SLOs
674
927
 
675
- - OS: [e.g. macOS 14]
676
- - Browser: [e.g. Chrome 120]
677
- - Version: [e.g. 1.2.3]
678
- - Node.js: [e.g. 20.x]
928
+ | Metric | Target |
929
+ |--------|--------|
930
+ | Availability | 99.9% |
931
+ | P95 latency | < 500ms |
932
+ | Error rate | < 0.1% |
679
933
 
680
- ## Additional context
934
+ ## Environments
681
935
 
682
- Add any other context about the problem here.
683
- `},{id:"feature-request",name:"Feature Request Template",description:"GitHub issue template for features",defaultPath:".github/ISSUE_TEMPLATE/feature_request.md",content:`---
684
- name: Feature request
685
- about: Suggest an idea for this project
686
- labels: enhancement
687
- ---
936
+ | Env | URL | Purpose |
937
+ |-----|-----|---------|
938
+ | Production | | Live traffic |
939
+ | Staging | | Pre-release testing |
940
+ | Development | | Local dev |
688
941
 
689
- ## Problem
942
+ ## Alerting
690
943
 
691
- Is your feature request related to a problem? Please describe.
692
- A clear and concise description of what the problem is.
944
+ | Alert | Threshold | Severity | Action |
945
+ |-------|-----------|----------|--------|
946
+ | | | | |
693
947
 
694
- ## Proposed solution
948
+ ## On-call contacts
695
949
 
696
- A clear and concise description of what you want to happen.
950
+ | Role | Name | Contact |
951
+ |------|------|---------|
952
+ | Primary | | |
953
+ | Secondary | | |
697
954
 
698
- ## Alternatives considered
955
+ ## Escalation matrix
699
956
 
700
- A clear and concise description of any alternative solutions or features you've considered.
957
+ | Time since incident | Contact | Method |
958
+ |--------------------|---------|--------|
959
+ | 0–15 min | On-call engineer | PagerDuty / phone |
960
+ | 15–30 min | Team lead | Slack + phone |
961
+ | 30+ min | Engineering manager | Phone + email |
701
962
 
702
- ## Implementation notes
963
+ ## Procedures
703
964
 
704
- Any thoughts on how this might be implemented?
965
+ ### Deploy
705
966
 
706
- ## Additional context
967
+ 1.
968
+ 2.
969
+ 3.
707
970
 
708
- Add any other context, mockups, or screenshots about the feature request here.
709
- `},{id:"changelog",name:"CHANGELOG.md",description:"Keep a Changelog format",defaultPath:"CHANGELOG.md",content:`# Changelog — {{PROJECT_NAME}}
971
+ ### Rollback
710
972
 
711
- All notable changes to this project will be documented in this file.
973
+ **When to rollback:**
712
974
 
713
- The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
714
- and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
975
+ | Signal | Action |
976
+ |--------|--------|
977
+ | Error rate > 1% after deploy | Immediate rollback |
978
+ | P95 latency doubled | Rollback if no fix in 15 min |
979
+ | Health check failing | Immediate rollback |
980
+ | Critical bug reported | Rollback within 30 min |
715
981
 
716
- ## [Unreleased]
982
+ **Rollback steps:**
717
983
 
718
- ### Added
719
- -
984
+ \`\`\`bash
985
+ # 1. Identify last stable release
986
+ git log --oneline --tags --simplify-by-decoration | head -5
720
987
 
721
- ### Changed
722
- -
988
+ # 2. Deploy previous version
989
+ git checkout <previous-tag>
990
+ npm run build && npm run deploy
723
991
 
724
- ### Fixed
725
- -
992
+ # 3. Verify rollback
993
+ curl -f https://your-app.com/health
994
+ \`\`\`
726
995
 
727
- ### Removed
728
- -
996
+ ### Troubleshooting
729
997
 
730
- ## [1.0.0] {{DATE}}
998
+ #### High error rate
999
+ \`\`\`bash
1000
+ # Check recent application logs
1001
+ tail -f /var/log/app/error.log
731
1002
 
732
- ### Added
733
- - Initial release
734
- `},{id:"deployment",name:"DEPLOYMENT.md",description:"Deployment guide and procedures",defaultPath:"DEPLOYMENT.md",content:`# Deployment Guide — {{PROJECT_NAME}}
1003
+ # Check error counts by endpoint
1004
+ grep "ERROR" /var/log/app/app.log | awk '{print $5}' | sort | uniq -c | sort -rn | head -10
735
1005
 
736
- **Last updated:** {{DATE}}
1006
+ # Review recent deploys
1007
+ git log --oneline -10
1008
+ \`\`\`
737
1009
 
738
- ## Environments
1010
+ 1. Check application logs for exception traces
1011
+ 2. Check downstream dependencies (database, cache, external APIs)
1012
+ 3. Review recent deploys — consider rollback if deploy-correlated
739
1013
 
740
- | Environment | URL | Branch | Auto-deploy |
741
- |-------------|-----|--------|-------------|
742
- | Production | | \`main\` | No |
743
- | Staging | | \`develop\` | Yes |
744
- | Preview | | PRs | Yes |
1014
+ #### High latency
1015
+ \`\`\`bash
1016
+ # Check database slow query log
1017
+ psql $DATABASE_URL -c "SELECT query, calls, mean_exec_time FROM pg_stat_statements ORDER BY mean_exec_time DESC LIMIT 10;"
745
1018
 
746
- ## Prerequisites
1019
+ # Check cache hit rate
1020
+ redis-cli info stats | grep hit_rate
747
1021
 
748
- - Access to deployment platform
749
- - Environment variables configured (see \`.env.example\`)
750
- - CI/CD pipeline passing
1022
+ # Check CPU/memory
1023
+ top -b -n 1 | head -20
1024
+ \`\`\`
751
1025
 
752
- ## Deploy to production
1026
+ 1. Check database query times (slow query log)
1027
+ 2. Check cache hit rates
1028
+ 3. Review resource utilization (CPU, memory, connections)
753
1029
 
1030
+ #### Service won't start
754
1031
  \`\`\`bash
755
- # 1. Ensure tests pass
756
- npm test
1032
+ # Check environment variables
1033
+ env | grep -E "DATABASE|REDIS|PORT"
757
1034
 
758
- # 2. Build and verify
759
- npm run build
1035
+ # Test database connectivity
1036
+ psql $DATABASE_URL -c "SELECT 1"
760
1037
 
761
- # 3. Merge to main
762
- git checkout main && git merge develop
1038
+ # Check port availability
1039
+ lsof -i :3000
1040
+ \`\`\`
763
1041
 
764
- # 4. Tag the release
765
- git tag v1.x.x && git push --tags
1042
+ #### Database connection issues
1043
+ \`\`\`bash
1044
+ # Check connection pool status
1045
+ psql $DATABASE_URL -c "SELECT count(*), state FROM pg_stat_activity GROUP BY state;"
1046
+
1047
+ # Check max connections
1048
+ psql $DATABASE_URL -c "SHOW max_connections;"
766
1049
  \`\`\`
767
1050
 
768
- ## Environment variables
1051
+ #### Memory leak suspected
1052
+ \`\`\`bash
1053
+ # Monitor memory over time
1054
+ watch -n 5 'ps aux --sort=-%mem | head -5'
1055
+
1056
+ # Capture heap snapshot (Node.js)
1057
+ kill -USR2 <pid>
1058
+ \`\`\`
1059
+ `},{id:"adr",name:"Architecture Decision",description:"Architecture Decision Record",defaultPath:"docs/architecture/decisions/ADR-001.md",category:"technical",content:`# ADR-001: Title
1060
+
1061
+ **Status:** Proposed
1062
+ **Date:** {{DATE}}
1063
+ **Deciders:**
1064
+
1065
+ ## Context
1066
+ What is the issue that we're seeing that is motivating this decision or change?
769
1067
 
770
- | Variable | Required | Description |
771
- |----------|----------|-------------|
772
- | | Yes | |
1068
+ ## Decision
1069
+ What is the change that we're proposing and/or doing?
773
1070
 
774
- ## Rollback procedure
1071
+ ## Rationale
1072
+ Why did we choose this option?
775
1073
 
776
- 1. Identify the last stable release tag
777
- 2. \`git checkout <tag>\`
778
- 3. Redeploy the previous version
779
- 4. Verify the rollback with smoke tests
1074
+ ## Alternatives considered
1075
+ - **Option A:** Description — pros/cons
1076
+ - **Option B:** Description — pros/cons
780
1077
 
781
- ## Smoke tests
1078
+ ## Consequences
782
1079
 
783
- After every deploy, verify:
784
- - [ ] App loads at production URL
785
- - [ ] Auth flow works
786
- - [ ] Core features functional
787
- - [ ] No error spikes in monitoring
1080
+ ### Positive
1081
+ -
788
1082
 
789
- ## Contacts
1083
+ ### Negative
1084
+ -
790
1085
 
791
- | Role | Contact |
792
- |------|---------|
793
- | On-call | |
794
- | Release manager | |
795
- `},{id:"testing",name:"TESTING.md",description:"Testing strategy and guide",defaultPath:"TESTING.md",content:`# Testing Guide — {{PROJECT_NAME}}
1086
+ ### Neutral
1087
+ -
1088
+ `},{id:"onboarding",name:"Onboarding Guide",description:"Developer onboarding guide",defaultPath:"docs/onboarding.md",category:"technical",content:`# Developer Onboarding — {{PROJECT_NAME}}
796
1089
 
797
1090
  **Last updated:** {{DATE}}
798
1091
 
799
- ## Test strategy
1092
+ ## Overview
1093
+ {{DESCRIPTION}}
800
1094
 
801
- | Layer | Type | Tool | Coverage target |
802
- |-------|------|------|----------------|
803
- | Unit | Functions/logic | {{TEST_FRAMEWORK}} | 80%+ |
804
- | Integration | API/DB | {{TEST_FRAMEWORK}} | 70%+ |
805
- | E2E | User flows | Playwright | Key paths |
1095
+ ## Prerequisites
1096
+ - [ ] Access to repository ({{REPO_URL}})
1097
+ - [ ] Access to staging environment
1098
+ - [ ] Accounts: (list required accounts/services)
806
1099
 
807
- ## Running tests
1100
+ ## Day 1: Get running
1101
+
1102
+ - [ ] Clone the repository and set up local environment
1103
+ - [ ] Run the app locally and verify it works
1104
+ - [ ] Read the architecture overview (\`docs/architecture/overview.md\`)
1105
+ - [ ] Meet your team lead and get a tour of the codebase
808
1106
 
809
1107
  \`\`\`bash
810
- # Run all tests
811
- npm test
1108
+ # Clone
1109
+ git clone {{REPO_URL}}
1110
+ cd {{PROJECT_NAME}}
812
1111
 
813
- # Run with coverage
814
- npm run test:coverage
1112
+ # Install dependencies
1113
+ npm install
815
1114
 
816
- # Run E2E tests
817
- npm run test:e2e
1115
+ # Copy environment variables
1116
+ cp .env.example .env.local
1117
+ # Edit .env.local with real values (ask your team lead)
818
1118
 
819
- # Watch mode
820
- npm run test:watch
1119
+ # Start development server
1120
+ npm run dev
821
1121
  \`\`\`
822
1122
 
823
- ## Writing tests
1123
+ ## Week 1: Get productive
824
1124
 
825
- ### Unit test example
1125
+ - [ ] Complete the environment setup checklist below
1126
+ - [ ] Read \`CONTRIBUTING.md\` and understand the PR process
1127
+ - [ ] Submit your first PR (even a small doc fix counts)
1128
+ - [ ] Attend team standup and sprint planning
1129
+ - [ ] Review 2–3 recent merged PRs to understand code patterns
1130
+ - [ ] Shadow a code review
826
1131
 
827
- \`\`\`typescript
828
- describe('MyFunction', () => {
829
- it('should return expected value', () => {
830
- expect(myFunction(input)).toBe(expected)
831
- })
832
- })
1132
+ ## Month 1: Get comfortable
1133
+
1134
+ - [ ] Deliver your first feature end-to-end
1135
+ - [ ] Lead a code review
1136
+ - [ ] Identify one piece of tech debt and create a ticket
1137
+ - [ ] Update this onboarding doc with anything that was unclear
1138
+
1139
+ ## Environment setup
1140
+
1141
+ \`\`\`bash
1142
+ # Install dependencies
1143
+ npm install
1144
+
1145
+ # Copy environment variables
1146
+ cp .env.example .env.local
1147
+
1148
+ # Start development server
1149
+ npm run dev
833
1150
  \`\`\`
834
1151
 
835
- ### Integration test guidelines
836
- - Use a real database (not mocks) for DB tests
837
- - Reset state between tests
838
- - Test happy path and error cases
1152
+ ## Tech stack
1153
+ {{TECH_STACK}}
839
1154
 
840
- ### E2E test guidelines
841
- - Cover critical user journeys
842
- - Use stable selectors (\`data-testid\`)
843
- - Run against staging environment
1155
+ ## IDE setup
1156
+ - Recommended: VS Code or Cursor
1157
+ - Install recommended extensions (see \`.vscode/extensions.json\`)
1158
+ - Enable format on save
844
1159
 
845
- ## Test organization
1160
+ ## Project structure
846
1161
 
847
1162
  \`\`\`
848
- src/
849
- __tests__/ # Unit tests
850
- __integration__/ # Integration tests
851
- e2e/ # E2E tests
1163
+ (describe key directories here)
852
1164
  \`\`\`
853
1165
 
854
- ## CI/CD
855
-
856
- Tests run automatically on every PR. PRs cannot merge with failing tests.
857
- `},{id:"glossary",name:"Glossary",description:"Project terminology reference",defaultPath:"docs/glossary.md",content:`# Glossary — {{PROJECT_NAME}}
1166
+ ## Key concepts
1167
+ -
858
1168
 
859
- **Last updated:** {{DATE}}
1169
+ ## Common tasks
860
1170
 
861
- This document defines terms used throughout the project documentation and codebase.
1171
+ ### Running tests
1172
+ \`\`\`bash
1173
+ npm test
1174
+ \`\`\`
862
1175
 
863
- ## Terms
1176
+ ### Building for production
1177
+ \`\`\`bash
1178
+ npm run build
1179
+ \`\`\`
864
1180
 
865
- | Term | Definition |
866
- |------|------------|
867
- | | |
1181
+ ## Common pitfalls
868
1182
 
869
- ## Acronyms
1183
+ 1. **Forgetting to copy .env.local** — the app won't start without required env vars. Copy from \`.env.example\` and fill in real values.
1184
+ 2. **Running \`npm install\` instead of the project's package manager** — check \`package.json\` for the \`packageManager\` field or look for a lock file (\`pnpm-lock.yaml\`, \`yarn.lock\`).
1185
+ 3. **Committing to \`main\` directly** — always branch and open a PR. Direct pushes to \`main\` are blocked.
1186
+ 4. **Skipping tests** — CI will catch you, but it's faster to run \`npm test\` locally before pushing.
1187
+ 5. **Not reading existing patterns** — before adding a new abstraction, search the codebase for how similar problems are solved.
870
1188
 
871
- | Acronym | Full form | Meaning |
872
- |---------|-----------|---------|
873
- | | | |
1189
+ ## Your first PR
874
1190
 
875
- ## Domain concepts
1191
+ 1. Pick a small, well-defined issue labelled \`good first issue\`
1192
+ 2. Create a branch: \`git checkout -b feat/your-name-first-pr\`
1193
+ 3. Make the change and add a test
1194
+ 4. Open a PR with the PR template filled out
1195
+ 5. Ask for a review in the team Slack channel
876
1196
 
877
- <!-- Add domain-specific concepts here -->
1197
+ ## Key contacts
878
1198
 
879
- ---
1199
+ | Role | Name | Contact |
1200
+ |------|------|---------|
1201
+ | | | |
880
1202
 
881
- *Keep this document updated as new terminology is introduced.*
882
- `},{id:"database",name:"Database Docs",description:"Database schema and design reference",defaultPath:"docs/DATABASE.md",content:`# Database Documentation — {{PROJECT_NAME}}
1203
+ ## Resources
1204
+ - Architecture overview: \`docs/architecture/overview.md\`
1205
+ - API reference: \`docs/api-reference.md\`
1206
+ - Runbook: \`docs/runbook.md\`
1207
+ - Contributing guide: \`CONTRIBUTING.md\`
1208
+ `},{id:"database",name:"Database Docs",description:"Database schema and design reference",defaultPath:"docs/DATABASE.md",category:"technical",content:`# Database Documentation — {{PROJECT_NAME}}
883
1209
 
884
1210
  **Last updated:** {{DATE}}
885
1211
 
@@ -941,7 +1267,7 @@ psql $DATABASE_URL < backup.sql
941
1267
  ## Performance notes
942
1268
 
943
1269
  -
944
- `},{id:"openapi",name:"OpenAPI Spec",description:"OpenAPI 3.0 API specification scaffold",defaultPath:"docs/api-spec.yaml",content:`openapi: 3.0.3
1270
+ `},{id:"openapi",name:"OpenAPI Spec",description:"OpenAPI 3.0 API specification scaffold",defaultPath:"docs/api-spec.yaml",category:"technical",content:`openapi: 3.0.3
945
1271
  info:
946
1272
  title: {{PROJECT_NAME}} API
947
1273
  description: |
@@ -1047,4 +1373,735 @@ components:
1047
1373
  application/json:
1048
1374
  schema:
1049
1375
  $ref: '#/components/schemas/Error'
1050
- `}];function f({open:e,onOpenChange:t,rootParam:a,onDocCreated:m}){let[f,h]=(0,r.useState)(1),[b,g]=(0,r.useState)(null),[x,v]=(0,r.useState)(""),[y,N]=(0,r.useState)(""),[w,j]=(0,r.useState)(!1);async function k(){if(b&&x.trim()){N(""),j(!0);try{let e=await fetch(`/api/docs${a}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:x.trim(),content:b.content})});if(409===e.status){N("File already exists"),j(!1);return}if(!e.ok){let t=await e.json();N(t.error||"Failed to create file"),j(!1);return}t(!1),m(x.trim())}catch{N("Network error"),j(!1)}}}return s.jsx(d.Vq,{open:e,onOpenChange:t,children:(0,s.jsxs)(d.cZ,{className:"max-w-2xl bg-surface border-border",children:[s.jsx(d.fK,{children:s.jsx(d.$N,{className:"text-txt text-sm font-semibold",children:1===f?"Choose a template":"Confirm file path"})}),1===f&&s.jsx(u.x,{className:"max-h-[420px]",children:s.jsx("div",{className:"grid grid-cols-3 gap-2 p-1",children:p.map(e=>(0,s.jsxs)("button",{onClick:()=>{g(e),v(e.defaultPath),N(""),h(2)},className:(0,o.cn)("flex flex-col items-start gap-1.5 p-3 rounded-lg border border-border text-left","bg-surface2 hover:bg-surface2/80 hover:border-accent/50 transition-colors"),children:[(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[s.jsx(n.Z,{className:"h-3.5 w-3.5 text-accent shrink-0"}),s.jsx("span",{className:"text-xs font-medium text-txt",children:e.name})]}),s.jsx("p",{className:"text-[11px] text-muted leading-relaxed",children:e.description}),s.jsx("p",{className:"text-[10px] text-muted/60 font-mono truncate w-full",children:e.defaultPath})]},e.id))})}),2===f&&b&&(0,s.jsxs)("div",{className:"space-y-4",children:[(0,s.jsxs)("div",{className:"flex items-start gap-3 p-3 rounded-lg bg-surface2 border border-border",children:[s.jsx(n.Z,{className:"h-4 w-4 text-accent shrink-0 mt-0.5"}),(0,s.jsxs)("div",{children:[s.jsx("p",{className:"text-xs font-medium text-txt",children:b.name}),s.jsx("p",{className:"text-[11px] text-muted mt-0.5",children:b.description})]})]}),(0,s.jsxs)("div",{className:"space-y-1.5",children:[s.jsx("label",{className:"text-[11px] font-medium text-muted uppercase tracking-wider",children:"File path"}),s.jsx(c.I,{autoFocus:!0,value:x,onChange:e=>{v(e.target.value),N("")},onKeyDown:e=>{"Enter"===e.key&&k()},placeholder:"docs/my-document.md",className:"h-8 text-xs bg-surface2 border-border font-mono"}),y&&s.jsx("p",{className:"text-[11px] text-red-400",children:y})]}),(0,s.jsxs)("div",{className:"flex items-center justify-between pt-1",children:[(0,s.jsxs)(l.z,{variant:"ghost",size:"sm",onClick:()=>h(1),className:"h-7 text-xs text-muted hover:text-txt gap-1.5",children:[s.jsx(i.Z,{className:"h-3 w-3"}),"Back"]}),s.jsx(l.z,{size:"sm",onClick:k,disabled:w||!x.trim(),className:"h-7 text-xs bg-accent hover:bg-accent/90 text-white",children:w?"Creating…":"Create"})]})]})]})})}},5819:(e,t,a)=>{"use strict";a.d(t,{C:()=>o});var s=a(7486);a(618);var r=a(4039),n=a(5098);let i=(0,r.j)("inline-flex items-center rounded-full border border-slate-200 px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-slate-950 focus:ring-offset-2 dark:border-slate-800 dark:focus:ring-slate-300",{variants:{variant:{default:"border-transparent bg-slate-900 text-slate-50 hover:bg-slate-900/80 dark:bg-slate-50 dark:text-slate-900 dark:hover:bg-slate-50/80",secondary:"border-transparent bg-slate-100 text-slate-900 hover:bg-slate-100/80 dark:bg-slate-800 dark:text-slate-50 dark:hover:bg-slate-800/80",destructive:"border-transparent bg-red-500 text-slate-50 hover:bg-red-500/80 dark:bg-red-900 dark:text-slate-50 dark:hover:bg-red-900/80",outline:"text-slate-950 dark:text-slate-50"}},defaultVariants:{variant:"default"}});function o({className:e,variant:t,...a}){return s.jsx("div",{className:(0,n.cn)(i({variant:t}),e),...a})}},3068:(e,t,a)=>{"use strict";a.d(t,{z:()=>l});var s=a(7486),r=a(618),n=a(8942),i=a(4039),o=a(5098);let d=(0,i.j)("inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-white transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-950 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 dark:ring-offset-slate-950 dark:focus-visible:ring-slate-300",{variants:{variant:{default:"bg-slate-900 text-slate-50 hover:bg-slate-900/90 dark:bg-slate-50 dark:text-slate-900 dark:hover:bg-slate-50/90",destructive:"bg-red-500 text-slate-50 hover:bg-red-500/90 dark:bg-red-900 dark:text-slate-50 dark:hover:bg-red-900/90",outline:"border border-slate-200 bg-white hover:bg-slate-100 hover:text-slate-900 dark:border-slate-800 dark:bg-slate-950 dark:hover:bg-slate-800 dark:hover:text-slate-50",secondary:"bg-slate-100 text-slate-900 hover:bg-slate-100/80 dark:bg-slate-800 dark:text-slate-50 dark:hover:bg-slate-800/80",ghost:"hover:bg-slate-100 hover:text-slate-900 dark:hover:bg-slate-800 dark:hover:text-slate-50",link:"text-slate-900 underline-offset-4 hover:underline dark:text-slate-50"},size:{default:"h-10 px-4 py-2",sm:"h-9 rounded-md px-3",lg:"h-11 rounded-md px-8",icon:"h-10 w-10"}},defaultVariants:{variant:"default",size:"default"}}),l=r.forwardRef(({className:e,variant:t,size:a,asChild:r=!1,...i},l)=>{let c=r?n.g7:"button";return s.jsx(c,{className:(0,o.cn)(d({variant:t,size:a,className:e})),ref:l,...i})});l.displayName="Button"},8650:(e,t,a)=>{"use strict";a.d(t,{$N:()=>p,Vq:()=>d,cZ:()=>u,fK:()=>m});var s=a(7486),r=a(618),n=a(2439),i=a(2153),o=a(5098);let d=n.fC;n.xz;let l=n.h_;n.x8;let c=r.forwardRef(({className:e,...t},a)=>s.jsx(n.aV,{ref:a,className:(0,o.cn)("fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",e),...t}));c.displayName=n.aV.displayName;let u=r.forwardRef(({className:e,children:t,...a},r)=>(0,s.jsxs)(l,{children:[s.jsx(c,{}),(0,s.jsxs)(n.VY,{ref:r,className:(0,o.cn)("fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border border-slate-200 bg-white p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg dark:border-slate-800 dark:bg-slate-950",e),...a,children:[t,(0,s.jsxs)(n.x8,{className:"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-white transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-slate-950 focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-slate-100 data-[state=open]:text-slate-500 dark:ring-offset-slate-950 dark:focus:ring-slate-300 dark:data-[state=open]:bg-slate-800 dark:data-[state=open]:text-slate-400",children:[s.jsx(i.Z,{className:"h-4 w-4"}),s.jsx("span",{className:"sr-only",children:"Close"})]})]})]}));u.displayName=n.VY.displayName;let m=({className:e,...t})=>s.jsx("div",{className:(0,o.cn)("flex flex-col space-y-1.5 text-center sm:text-left",e),...t});m.displayName="DialogHeader";let p=r.forwardRef(({className:e,...t},a)=>s.jsx(n.Dx,{ref:a,className:(0,o.cn)("text-lg font-semibold leading-none tracking-tight",e),...t}));p.displayName=n.Dx.displayName,r.forwardRef(({className:e,...t},a)=>s.jsx(n.dk,{ref:a,className:(0,o.cn)("text-sm text-slate-500 dark:text-slate-400",e),...t})).displayName=n.dk.displayName},9228:(e,t,a)=>{"use strict";a.d(t,{$F:()=>u,AW:()=>m,Xi:()=>p,h_:()=>c});var s=a(7486),r=a(618),n=a(79),i=a(8953),o=a(9644),d=a(3399),l=a(5098);let c=n.fC,u=n.xz;n.ZA,n.Uv,n.Tr,n.Ee,r.forwardRef(({className:e,inset:t,children:a,...r},o)=>(0,s.jsxs)(n.fF,{ref:o,className:(0,l.cn)("flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-slate-100 data-[state=open]:bg-slate-100 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 dark:focus:bg-slate-800 dark:data-[state=open]:bg-slate-800",t&&"pl-8",e),...r,children:[a,s.jsx(i.Z,{className:"ml-auto"})]})).displayName=n.fF.displayName,r.forwardRef(({className:e,...t},a)=>s.jsx(n.tu,{ref:a,className:(0,l.cn)("z-50 min-w-[8rem] overflow-hidden rounded-md border border-slate-200 bg-white p-1 text-slate-950 shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-dropdown-menu-content-transform-origin] dark:border-slate-800 dark:bg-slate-950 dark:text-slate-50",e),...t})).displayName=n.tu.displayName;let m=r.forwardRef(({className:e,sideOffset:t=4,...a},r)=>s.jsx(n.Uv,{children:s.jsx(n.VY,{ref:r,sideOffset:t,className:(0,l.cn)("z-50 max-h-[var(--radix-dropdown-menu-content-available-height)] min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border border-slate-200 bg-white p-1 text-slate-950 shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-dropdown-menu-content-transform-origin] dark:border-slate-800 dark:bg-slate-950 dark:text-slate-50",e),...a})}));m.displayName=n.VY.displayName;let p=r.forwardRef(({className:e,inset:t,...a},r)=>s.jsx(n.ck,{ref:r,className:(0,l.cn)("relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-slate-100 focus:text-slate-900 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 dark:focus:bg-slate-800 dark:focus:text-slate-50",t&&"pl-8",e),...a}));p.displayName=n.ck.displayName,r.forwardRef(({className:e,children:t,checked:a,...r},i)=>(0,s.jsxs)(n.oC,{ref:i,className:(0,l.cn)("relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-slate-100 focus:text-slate-900 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-slate-800 dark:focus:text-slate-50",e),checked:a,...r,children:[s.jsx("span",{className:"absolute left-2 flex h-3.5 w-3.5 items-center justify-center",children:s.jsx(n.wU,{children:s.jsx(o.Z,{className:"h-4 w-4"})})}),t]})).displayName=n.oC.displayName,r.forwardRef(({className:e,children:t,...a},r)=>(0,s.jsxs)(n.Rk,{ref:r,className:(0,l.cn)("relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-slate-100 focus:text-slate-900 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-slate-800 dark:focus:text-slate-50",e),...a,children:[s.jsx("span",{className:"absolute left-2 flex h-3.5 w-3.5 items-center justify-center",children:s.jsx(n.wU,{children:s.jsx(d.Z,{className:"h-2 w-2 fill-current"})})}),t]})).displayName=n.Rk.displayName,r.forwardRef(({className:e,inset:t,...a},r)=>s.jsx(n.__,{ref:r,className:(0,l.cn)("px-2 py-1.5 text-sm font-semibold",t&&"pl-8",e),...a})).displayName=n.__.displayName,r.forwardRef(({className:e,...t},a)=>s.jsx(n.Z0,{ref:a,className:(0,l.cn)("-mx-1 my-1 h-px bg-slate-100 dark:bg-slate-800",e),...t})).displayName=n.Z0.displayName},2162:(e,t,a)=>{"use strict";a.d(t,{I:()=>i});var s=a(7486),r=a(618),n=a(5098);let i=r.forwardRef(({className:e,type:t,...a},r)=>s.jsx("input",{type:t,className:(0,n.cn)("flex h-10 w-full rounded-md border border-slate-200 bg-white px-3 py-2 text-base ring-offset-white file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-slate-950 placeholder:text-slate-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-950 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:border-slate-800 dark:bg-slate-950 dark:ring-offset-slate-950 dark:file:text-slate-50 dark:placeholder:text-slate-400 dark:focus-visible:ring-slate-300",e),ref:r,...a}));i.displayName="Input"},2119:(e,t,a)=>{"use strict";a.d(t,{x:()=>o});var s=a(7486),r=a(618),n=a(7051),i=a(5098);let o=r.forwardRef(({className:e,children:t,...a},r)=>(0,s.jsxs)(n.fC,{ref:r,className:(0,i.cn)("relative overflow-hidden",e),...a,children:[s.jsx(n.l_,{className:"h-full w-full rounded-[inherit]",children:t}),s.jsx(d,{}),s.jsx(n.Ns,{})]}));o.displayName=n.fC.displayName;let d=r.forwardRef(({className:e,orientation:t="vertical",...a},r)=>s.jsx(n.gb,{ref:r,orientation:t,className:(0,i.cn)("flex touch-none select-none transition-colors","vertical"===t&&"h-full w-2.5 border-l border-l-transparent p-[1px]","horizontal"===t&&"h-2.5 flex-col border-t border-t-transparent p-[1px]",e),...a,children:s.jsx(n.q4,{className:"relative flex-1 rounded-full bg-slate-200 dark:bg-slate-800"})}));d.displayName=n.gb.displayName},6637:(e,t,a)=>{"use strict";a.d(t,{Z:()=>o});var s=a(7486),r=a(618),n=a(7168),i=a(5098);let o=r.forwardRef(({className:e,orientation:t="horizontal",decorative:a=!0,...r},o)=>s.jsx(n.f,{ref:o,decorative:a,orientation:t,className:(0,i.cn)("shrink-0 bg-slate-200 dark:bg-slate-800","horizontal"===t?"h-[1px] w-full":"h-full w-[1px]",e),...r}));o.displayName=n.f.displayName},5875:(e,t,a)=>{"use strict";a.d(t,{_v:()=>c,aJ:()=>l,pn:()=>o,u:()=>d});var s=a(7486),r=a(618),n=a(6448),i=a(5098);let o=n.zt,d=n.fC,l=n.xz,c=r.forwardRef(({className:e,sideOffset:t=4,...a},r)=>s.jsx(n.VY,{ref:r,sideOffset:t,className:(0,i.cn)("z-50 overflow-hidden rounded-md border border-slate-200 bg-white px-3 py-1.5 text-sm text-slate-950 shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-tooltip-content-transform-origin] dark:border-slate-800 dark:bg-slate-950 dark:text-slate-50",e),...a}));c.displayName=n.VY.displayName},6266:(e,t,a)=>{"use strict";a.d(t,{q:()=>o,w:()=>d});var s=a(7486),r=a(618),n=a(6811);let i=(0,r.createContext)(null);function o(){let e=(0,r.useContext)(i);if(!e)throw Error("useApp must be used inside AppProvider");return e}function d({children:e}){let t=(0,n.useRouter)(),[a,o]=(0,r.useState)([]),[d,l]=(0,r.useState)(""),[c,u]=(0,r.useState)(null),[m,p]=(0,r.useState)(null),[f,h]=(0,r.useState)([]),[b,g]=(0,r.useState)(!0),[x,v]=(0,r.useState)(!1),[y,N]=(0,r.useState)(null);(0,r.useRef)(null);let w=d?`?root=${encodeURIComponent(d)}`:"",j=(0,r.useCallback)(async e=>{let t=e||d;if(!t)return;let a=`?root=${encodeURIComponent(t)}`;try{let[e,t,s]=await Promise.all([fetch(`/api/summary${a}`).then(e=>e.json()),fetch(`/api/tasks${a}`).then(e=>e.json()),fetch(`/api/activity${a}&limit=30`).then(e=>e.json())]);u(e),p(t.board),h(Array.isArray(s)?s:[])}catch{}g(!1)},[d]),k=(0,r.useCallback)(async(e,t)=>{p(a=>{let s;if(!a)return a;let r=structuredClone(a);for(let a of Object.keys(r)){let n=r[a].findIndex(t=>t.id===e);-1!==n&&(s={...r[a][n],status:t},r[a]=r[a].filter(t=>t.id!==e))}return s&&r[t]&&(r[t]=[s,...r[t]]),r});try{await fetch(`/api/tasks${w}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({taskId:e,status:t,actor:"human"})}),j()}catch{j()}},[w,j]),C=(0,r.useCallback)(async e=>{let a=await fetch(`/api/docs${w}&read=${encodeURIComponent(e)}`);N(await a.json()),t.push("/docs")},[w,t]);return s.jsx(i.Provider,{value:{projects:a,activeProject:d,summary:c,board:m,activity:f,liveIndicator:x,loading:b,selectedDoc:y,setSelectedDoc:N,rootParam:w,onProjectChange:function(e){l(e),j(e)},refresh:j,moveTask:k,openDoc:C},children:e})}},5098:(e,t,a)=>{"use strict";a.d(t,{cn:()=>n});var s=a(9360),r=a(2646);function n(...e){return(0,r.m6)((0,s.W)(e))}},2026:(e,t,a)=>{"use strict";a.r(t),a.d(t,{$$typeof:()=>i,__esModule:()=>n,default:()=>o});var s=a(2334);let r=(0,s.createProxy)(String.raw`/Users/hoangnguyen/Documents/nextjs/vibedoc/src/app/(app)/layout.tsx`),{__esModule:n,$$typeof:i}=r;r.default;let o=(0,s.createProxy)(String.raw`/Users/hoangnguyen/Documents/nextjs/vibedoc/src/app/(app)/layout.tsx#default`)},7831:(e,t,a)=>{"use strict";a.r(t),a.d(t,{default:()=>n,metadata:()=>r});var s=a(9703);a(5260);let r={title:"VibeDoc",description:"Project intelligence for AI-assisted development"};function n({children:e}){return s.jsx("html",{lang:"en",className:"dark",children:s.jsx("body",{className:"bg-bg text-txt min-h-screen",children:e})})}},5260:()=>{}};
1376
+ `},{id:"meeting-notes",name:"Meeting Notes",description:"Meeting notes template",defaultPath:`docs/meetings/${n}.md`,category:"technical",content:`# Meeting Notes — ${n}
1377
+
1378
+ **Attendees:**
1379
+ **Facilitator:**
1380
+
1381
+ ## Agenda
1382
+
1383
+ 1.
1384
+ 2.
1385
+
1386
+ ## Notes
1387
+
1388
+ ## Decisions
1389
+
1390
+ ## Action items
1391
+
1392
+ | Action | Owner | Due |
1393
+ |--------|-------|-----|
1394
+ | | | |
1395
+
1396
+ ## Next meeting
1397
+ `},{id:"blank",name:"Blank Document",description:"Empty markdown file",defaultPath:"docs/untitled.md",category:"technical",content:"# Untitled\n\n"},{id:"dockerfile",name:"Dockerfile",description:"Multi-stage Docker build with health check",defaultPath:"Dockerfile",category:"infrastructure",content:`# Stage 1: Install dependencies
1398
+ FROM node:20-alpine AS deps
1399
+ RUN apk add --no-cache libc6-compat
1400
+ WORKDIR /app
1401
+ COPY package*.json ./
1402
+ RUN npm ci --only=production
1403
+
1404
+ # Stage 2: Build
1405
+ FROM node:20-alpine AS builder
1406
+ WORKDIR /app
1407
+ COPY --from=deps /app/node_modules ./node_modules
1408
+ COPY . .
1409
+ RUN npm run build
1410
+
1411
+ # Stage 3: Run
1412
+ FROM node:20-alpine AS runner
1413
+ WORKDIR /app
1414
+ ENV NODE_ENV=production
1415
+ RUN addgroup --system --gid 1001 nodejs
1416
+ RUN adduser --system --uid 1001 appuser
1417
+ COPY --from=builder /app/dist ./dist
1418
+ COPY --from=deps /app/node_modules ./node_modules
1419
+ COPY package*.json ./
1420
+ USER appuser
1421
+ EXPOSE 3000
1422
+ HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \\
1423
+ CMD wget -qO- http://localhost:3000/health || exit 1
1424
+ CMD ["node", "dist/index.js"]
1425
+ `},{id:"docker-compose",name:"docker-compose.yml",description:"Docker Compose with app, Postgres, and Redis",defaultPath:"docker-compose.yml",category:"infrastructure",content:`# Docker Compose V2+ (no version key needed)
1426
+ services:
1427
+ app:
1428
+ build: .
1429
+ ports:
1430
+ - "3000:3000"
1431
+ environment:
1432
+ DATABASE_URL: postgresql://postgres:password@db:5432/{{PROJECT_NAME}}
1433
+ REDIS_URL: redis://redis:6379
1434
+ depends_on:
1435
+ db:
1436
+ condition: service_healthy
1437
+ redis:
1438
+ condition: service_healthy
1439
+
1440
+ db:
1441
+ image: postgres:16-alpine
1442
+ environment:
1443
+ POSTGRES_PASSWORD: password
1444
+ POSTGRES_DB: {{PROJECT_NAME}}
1445
+ healthcheck:
1446
+ test: ["CMD-SHELL", "pg_isready -U postgres"]
1447
+ interval: 10s
1448
+ timeout: 5s
1449
+ retries: 5
1450
+ volumes:
1451
+ - postgres_data:/var/lib/postgresql/data
1452
+
1453
+ redis:
1454
+ image: redis:7-alpine
1455
+ healthcheck:
1456
+ test: ["CMD", "redis-cli", "ping"]
1457
+ interval: 10s
1458
+ timeout: 5s
1459
+ retries: 5
1460
+ volumes:
1461
+ - redis_data:/data
1462
+
1463
+ volumes:
1464
+ postgres_data:
1465
+ redis_data:
1466
+ `},{id:"dockerignore",name:".dockerignore",description:"Docker build context exclusions",defaultPath:".dockerignore",category:"infrastructure",content:`node_modules
1467
+ npm-debug.log*
1468
+ .git
1469
+ .gitignore
1470
+ .env*
1471
+ !.env.example
1472
+ dist
1473
+ build
1474
+ coverage
1475
+ .nyc_output
1476
+ *.test.*
1477
+ *.spec.*
1478
+ __tests__
1479
+ e2e
1480
+ .github
1481
+ docs
1482
+ README.md
1483
+ CHANGELOG.md
1484
+ `},{id:"makefile",name:"Makefile",description:"Makefile with common dev/build/deploy targets",defaultPath:"Makefile",category:"infrastructure",content:`.PHONY: help dev build test lint docker-up docker-down migrate clean
1485
+
1486
+ help: ## Show this help
1487
+ @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\\033[36m%-20s\\033[0m %s\\n", $$1, $$2}'
1488
+
1489
+ dev: ## Start development server
1490
+ npm run dev
1491
+
1492
+ build: ## Build for production
1493
+ npm run build
1494
+
1495
+ test: ## Run all tests
1496
+ npm test
1497
+
1498
+ lint: ## Run linter
1499
+ npm run lint
1500
+
1501
+ docker-up: ## Start Docker services
1502
+ docker compose up -d
1503
+
1504
+ docker-down: ## Stop Docker services
1505
+ docker compose down
1506
+
1507
+ migrate: ## Run database migrations
1508
+ npm run db:migrate
1509
+
1510
+ clean: ## Remove build artifacts
1511
+ rm -rf dist build .next coverage node_modules/.cache
1512
+ `},{id:"env-example",name:".env.example",description:"Annotated environment variables template",defaultPath:".env.example",category:"infrastructure",content:`# App Config
1513
+ NODE_ENV=development
1514
+ PORT=3000
1515
+ APP_URL=http://localhost:3000
1516
+ LOG_LEVEL=info
1517
+
1518
+ # Database
1519
+ DATABASE_URL=postgresql://user:password@localhost:5432/{{PROJECT_NAME}}_dev
1520
+
1521
+ # Auth
1522
+ JWT_SECRET=your-super-secret-jwt-key-change-in-production
1523
+ JWT_EXPIRES_IN=7d
1524
+ SESSION_SECRET=your-session-secret-change-in-production
1525
+
1526
+ # External Services
1527
+ # STRIPE_SECRET_KEY=sk_test_...
1528
+ # SENDGRID_API_KEY=SG....
1529
+ # AWS_ACCESS_KEY_ID=
1530
+ # AWS_SECRET_ACCESS_KEY=
1531
+ # AWS_REGION=us-east-1
1532
+ # AWS_S3_BUCKET=
1533
+
1534
+ # Observability
1535
+ # SENTRY_DSN=https://...@sentry.io/...
1536
+ # DATADOG_API_KEY=
1537
+ # NEW_RELIC_LICENSE_KEY=
1538
+ `},{id:"nginx-conf",name:"nginx.conf",description:"Nginx reverse proxy with gzip, security headers, rate limiting",defaultPath:"nginx/nginx.conf",category:"infrastructure",content:`events {
1539
+ worker_connections 1024;
1540
+ }
1541
+
1542
+ http {
1543
+ gzip on;
1544
+ gzip_types text/plain text/css application/json application/javascript text/xml;
1545
+ gzip_min_length 1000;
1546
+
1547
+ # Rate limiting
1548
+ limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
1549
+
1550
+ server {
1551
+ listen 80;
1552
+ server_name _;
1553
+
1554
+ # Security headers
1555
+ add_header X-Frame-Options "SAMEORIGIN" always;
1556
+ add_header X-Content-Type-Options "nosniff" always;
1557
+ add_header X-XSS-Protection "1; mode=block" always;
1558
+ add_header Referrer-Policy "strict-origin-when-cross-origin" always;
1559
+ add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
1560
+
1561
+ location /api/ {
1562
+ limit_req zone=api burst=20 nodelay;
1563
+ proxy_pass http://app:3000;
1564
+ proxy_http_version 1.1;
1565
+ proxy_set_header Upgrade $http_upgrade;
1566
+ proxy_set_header Connection 'upgrade';
1567
+ proxy_set_header Host $host;
1568
+ proxy_set_header X-Real-IP $remote_addr;
1569
+ proxy_cache_bypass $http_upgrade;
1570
+ }
1571
+
1572
+ location / {
1573
+ proxy_pass http://app:3000;
1574
+ proxy_http_version 1.1;
1575
+ proxy_set_header Host $host;
1576
+ proxy_set_header X-Real-IP $remote_addr;
1577
+ }
1578
+ }
1579
+ }
1580
+ `},{id:"ci-workflow",name:"CI Workflow",description:"GitHub Actions CI: lint, typecheck, test matrix, coverage",defaultPath:".github/workflows/ci.yml",category:"github-actions",content:`name: CI
1581
+ on:
1582
+ push:
1583
+ branches: [main, develop]
1584
+ pull_request:
1585
+ branches: [main, develop]
1586
+
1587
+ jobs:
1588
+ lint:
1589
+ runs-on: ubuntu-latest
1590
+ steps:
1591
+ - uses: actions/checkout@v4
1592
+ - uses: actions/setup-node@v4
1593
+ with: {node-version: '20', cache: 'npm'}
1594
+ - run: npm ci
1595
+ - run: npm run lint
1596
+ - run: npm run typecheck
1597
+
1598
+ test:
1599
+ runs-on: ubuntu-latest
1600
+ strategy:
1601
+ matrix:
1602
+ node-version: ['20', '22']
1603
+ steps:
1604
+ - uses: actions/checkout@v4
1605
+ - uses: actions/setup-node@v4
1606
+ with: {node-version: '\${{ matrix.node-version }}', cache: 'npm'}
1607
+ - run: npm ci
1608
+ - run: npm run test:coverage
1609
+ - uses: codecov/codecov-action@v4
1610
+ if: matrix.node-version == '20'
1611
+
1612
+ build:
1613
+ runs-on: ubuntu-latest
1614
+ needs: [lint, test]
1615
+ steps:
1616
+ - uses: actions/checkout@v4
1617
+ - uses: actions/setup-node@v4
1618
+ with: {node-version: '20', cache: 'npm'}
1619
+ - run: npm ci
1620
+ - run: npm run build
1621
+ `},{id:"cd-workflow",name:"CD Workflow",description:"GitHub Actions CD: deploy to production with health check",defaultPath:".github/workflows/cd.yml",category:"github-actions",content:`name: CD
1622
+ on:
1623
+ push:
1624
+ branches: [main]
1625
+
1626
+ jobs:
1627
+ deploy:
1628
+ runs-on: ubuntu-latest
1629
+ # needs: [ci] # Uncomment if using a reusable CI workflow
1630
+ environment: production
1631
+ steps:
1632
+ - uses: actions/checkout@v4
1633
+ - uses: actions/setup-node@v4
1634
+ with: {node-version: '20', cache: 'npm'}
1635
+ - run: npm ci
1636
+ - run: npm run build
1637
+ - name: Deploy
1638
+ env:
1639
+ DEPLOY_TOKEN: \${{ secrets.DEPLOY_TOKEN }}
1640
+ DEPLOY_URL: \${{ secrets.DEPLOY_URL }}
1641
+ run: |
1642
+ # Add your deployment command here
1643
+ # e.g.: npx railway deploy, vercel deploy --prod, etc.
1644
+ echo "Deploy to production"
1645
+ - name: Health check
1646
+ run: |
1647
+ sleep 30
1648
+ curl -f \${{ secrets.APP_URL }}/health || exit 1
1649
+ `},{id:"security-scan",name:"Security Scan",description:"GitHub Actions security: npm audit + CodeQL analysis",defaultPath:".github/workflows/security.yml",category:"github-actions",content:`name: Security
1650
+ on:
1651
+ push:
1652
+ branches: [main]
1653
+ schedule:
1654
+ - cron: '0 0 * * 1' # Weekly on Monday
1655
+
1656
+ jobs:
1657
+ audit:
1658
+ runs-on: ubuntu-latest
1659
+ steps:
1660
+ - uses: actions/checkout@v4
1661
+ - uses: actions/setup-node@v4
1662
+ with: {node-version: '20', cache: 'npm'}
1663
+ - run: npm ci
1664
+ - run: npm audit --audit-level=high
1665
+
1666
+ codeql:
1667
+ runs-on: ubuntu-latest
1668
+ permissions:
1669
+ actions: read
1670
+ contents: read
1671
+ security-events: write
1672
+ steps:
1673
+ - uses: actions/checkout@v4
1674
+ - uses: github/codeql-action/init@v3
1675
+ with: {languages: javascript}
1676
+ - uses: github/codeql-action/autobuild@v3
1677
+ - uses: github/codeql-action/analyze@v3
1678
+ `},{id:"dependabot-config",name:"Dependabot Config",description:"Dependabot config: npm + GitHub Actions weekly updates",defaultPath:".github/dependabot.yml",category:"github-actions",content:`version: 2
1679
+ updates:
1680
+ - package-ecosystem: npm
1681
+ directory: "/"
1682
+ schedule:
1683
+ interval: weekly
1684
+ day: monday
1685
+ groups:
1686
+ minor-and-patch:
1687
+ update-types: ["minor", "patch"]
1688
+ ignore:
1689
+ - dependency-name: "*"
1690
+ update-types: ["version-update:semver-major"]
1691
+
1692
+ - package-ecosystem: github-actions
1693
+ directory: "/"
1694
+ schedule:
1695
+ interval: weekly
1696
+ day: monday
1697
+ `},{id:"release-workflow",name:"Release Workflow",description:"GitHub Actions release: GitHub Release + Docker image to GHCR",defaultPath:".github/workflows/release.yml",category:"github-actions",content:`name: Release
1698
+ on:
1699
+ push:
1700
+ tags: ['v*']
1701
+
1702
+ jobs:
1703
+ release:
1704
+ runs-on: ubuntu-latest
1705
+ permissions:
1706
+ contents: write
1707
+ packages: write
1708
+ steps:
1709
+ - uses: actions/checkout@v4
1710
+ - name: Create GitHub Release
1711
+ uses: softprops/action-gh-release@v2
1712
+ with:
1713
+ generate_release_notes: true
1714
+ - name: Log in to GHCR
1715
+ uses: docker/login-action@v3
1716
+ with:
1717
+ registry: ghcr.io
1718
+ username: \${{ github.actor }}
1719
+ password: \${{ secrets.GITHUB_TOKEN }}
1720
+ - name: Build and push Docker image
1721
+ uses: docker/build-push-action@v5
1722
+ with:
1723
+ context: .
1724
+ push: true
1725
+ tags: |
1726
+ ghcr.io/\${{ github.repository }}:\${{ github.ref_name }}
1727
+ ghcr.io/\${{ github.repository }}:latest
1728
+ `},{id:"codeowners",name:"CODEOWNERS",description:"GitHub CODEOWNERS file for review assignments",defaultPath:".github/CODEOWNERS",category:"github",content:`# IMPORTANT: Replace {{PROJECT_NAME}} below with your GitHub organization name
1729
+ # (org name and project name are often different)
1730
+ # Format: @org-name/team-slug
1731
+
1732
+ # Global owners - review all changes
1733
+ * @{{PROJECT_NAME}}/maintainers
1734
+
1735
+ # Documentation
1736
+ docs/ @{{PROJECT_NAME}}/docs
1737
+ *.md @{{PROJECT_NAME}}/docs
1738
+
1739
+ # CI/CD config
1740
+ .github/ @{{PROJECT_NAME}}/devops
1741
+ Dockerfile @{{PROJECT_NAME}}/devops
1742
+ docker-compose*.yml @{{PROJECT_NAME}}/devops
1743
+
1744
+ # Security-sensitive files
1745
+ **/auth/ @{{PROJECT_NAME}}/security
1746
+ **/security/ @{{PROJECT_NAME}}/security
1747
+ SECURITY.md @{{PROJECT_NAME}}/security
1748
+ `},{id:"eslintrc",name:"ESLint Config",description:"ESLint config with TypeScript strict rules",defaultPath:".eslintrc.json",category:"code-quality",content:`{
1749
+ "extends": [
1750
+ "eslint:recommended",
1751
+ "plugin:@typescript-eslint/recommended",
1752
+ "plugin:@typescript-eslint/recommended-requiring-type-checking"
1753
+ ],
1754
+ "parser": "@typescript-eslint/parser",
1755
+ "parserOptions": {
1756
+ "project": true,
1757
+ "tsconfigRootDir": "."
1758
+ },
1759
+ "plugins": ["@typescript-eslint"],
1760
+ "rules": {
1761
+ "no-console": "warn",
1762
+ "no-unused-vars": "off",
1763
+ "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
1764
+ "@typescript-eslint/no-explicit-any": "warn",
1765
+ "@typescript-eslint/consistent-type-imports": "error",
1766
+ "@typescript-eslint/no-floating-promises": "error"
1767
+ },
1768
+ "ignorePatterns": ["dist/", "build/", "node_modules/", "*.config.js"]
1769
+ }
1770
+ `},{id:"prettierrc",name:"Prettier Config",description:"Prettier formatting config",defaultPath:".prettierrc",category:"code-quality",content:`{
1771
+ "semi": false,
1772
+ "singleQuote": true,
1773
+ "trailingComma": "es5",
1774
+ "printWidth": 100,
1775
+ "tabWidth": 2,
1776
+ "useTabs": false,
1777
+ "bracketSpacing": true,
1778
+ "arrowParens": "avoid"
1779
+ }
1780
+ `},{id:"tsconfig-strict",name:"tsconfig (strict)",description:"TypeScript config with strict settings for Node/ESM",defaultPath:"tsconfig.json",category:"code-quality",content:`{
1781
+ "compilerOptions": {
1782
+ "target": "ES2022",
1783
+ "lib": ["ES2022"],
1784
+ "module": "NodeNext",
1785
+ "moduleResolution": "NodeNext",
1786
+ "outDir": "dist",
1787
+ "rootDir": "src",
1788
+ "strict": true,
1789
+ "noUncheckedIndexedAccess": true,
1790
+ "exactOptionalPropertyTypes": true,
1791
+ "noImplicitReturns": true,
1792
+ "noFallthroughCasesInSwitch": true,
1793
+ "noImplicitOverride": true,
1794
+ "esModuleInterop": true,
1795
+ "skipLibCheck": true,
1796
+ "forceConsistentCasingInFileNames": true,
1797
+ "paths": {
1798
+ "@/*": ["./src/*"]
1799
+ }
1800
+ },
1801
+ "include": ["src/**/*"],
1802
+ "exclude": ["node_modules", "dist"]
1803
+ }
1804
+ `},{id:"editorconfig",name:".editorconfig",description:"EditorConfig for consistent editor settings",defaultPath:".editorconfig",category:"code-quality",content:`root = true
1805
+
1806
+ [*]
1807
+ indent_style = space
1808
+ indent_size = 2
1809
+ end_of_line = lf
1810
+ charset = utf-8
1811
+ trim_trailing_whitespace = true
1812
+ insert_final_newline = true
1813
+
1814
+ [*.md]
1815
+ trim_trailing_whitespace = false
1816
+
1817
+ [Makefile]
1818
+ indent_style = tab
1819
+
1820
+ [*.{yml,yaml}]
1821
+ indent_size = 2
1822
+ `},{id:"lint-staged",name:"lint-staged Config",description:"lint-staged config for pre-commit formatting and linting",defaultPath:".lintstagedrc.json",category:"code-quality",content:`{
1823
+ "*.{ts,tsx}": ["eslint --fix", "prettier --write"],
1824
+ "*.{js,jsx}": ["eslint --fix", "prettier --write"],
1825
+ "*.{json,md,yml,yaml}": ["prettier --write"],
1826
+ "*.{css,scss}": ["prettier --write"]
1827
+ }
1828
+ `},{id:"commitlint",name:"commitlint Config",description:"commitlint config enforcing Conventional Commits",defaultPath:"commitlint.config.js",category:"code-quality",content:`module.exports = {
1829
+ extends: ['@commitlint/config-conventional'],
1830
+ rules: {
1831
+ 'type-enum': [2, 'always', [
1832
+ 'feat', 'fix', 'docs', 'style', 'refactor',
1833
+ 'perf', 'test', 'chore', 'revert', 'ci', 'build'
1834
+ ]],
1835
+ 'scope-case': [2, 'always', 'lower-case'],
1836
+ 'subject-case': [2, 'always', 'lower-case'],
1837
+ 'subject-max-length': [2, 'always', 100],
1838
+ 'body-max-line-length': [2, 'always', 200],
1839
+ },
1840
+ }
1841
+ `},{id:"husky-setup",name:"Husky Setup Doc",description:"Documentation for Husky git hooks setup",defaultPath:".husky/README.md",category:"code-quality",content:`# Husky Git Hooks
1842
+
1843
+ This project uses [Husky](https://typicode.github.io/husky/) to enforce code quality at commit time.
1844
+
1845
+ ## Setup
1846
+
1847
+ After cloning and running \`npm install\`, Husky hooks are auto-installed via the \`prepare\` script.
1848
+
1849
+ If hooks aren't running, install manually:
1850
+
1851
+ \`\`\`
1852
+ npx husky install
1853
+ \`\`\`
1854
+
1855
+ ## Hooks
1856
+
1857
+ | Hook | Command | Purpose |
1858
+ |------|---------|---------|
1859
+ | pre-commit | \`lint-staged\` | Lint and format staged files |
1860
+ | commit-msg | \`commitlint\` | Validate commit message format |
1861
+ | pre-push | \`npm test\` | Run tests before pushing |
1862
+
1863
+ ## Skip hooks (emergencies only)
1864
+
1865
+ \`\`\`
1866
+ git commit --no-verify -m "emergency fix"
1867
+ \`\`\`
1868
+
1869
+ Use sparingly. CI will still catch failures.
1870
+ `},{id:"vscode-settings",name:"VS Code Settings",description:"VS Code workspace settings for the project",defaultPath:".vscode/settings.json",category:"code-quality",content:`{
1871
+ "editor.formatOnSave": true,
1872
+ "editor.defaultFormatter": "esbenp.prettier-vscode",
1873
+ "editor.codeActionsOnSave": {
1874
+ "source.fixAll.eslint": "explicit",
1875
+ "source.organizeImports": "explicit"
1876
+ },
1877
+ "typescript.preferences.importModuleSpecifier": "non-relative",
1878
+ "typescript.tsdk": "node_modules/typescript/lib",
1879
+ "files.eol": "\\n",
1880
+ "files.trimTrailingWhitespace": true,
1881
+ "files.insertFinalNewline": true,
1882
+ "[markdown]": {
1883
+ "editor.formatOnSave": false
1884
+ }
1885
+ }
1886
+ `},{id:"vscode-extensions",name:"VS Code Extensions",description:"Recommended VS Code extensions for the project",defaultPath:".vscode/extensions.json",category:"code-quality",content:`{
1887
+ "recommendations": [
1888
+ "esbenp.prettier-vscode",
1889
+ "dbaeumer.vscode-eslint",
1890
+ "ms-vscode.vscode-typescript-next",
1891
+ "bradlc.vscode-tailwindcss",
1892
+ "eamodio.gitlens",
1893
+ "usernamehw.errorlens",
1894
+ "streetsidesoftware.code-spell-checker",
1895
+ "github.copilot",
1896
+ "christian-kohler.path-intellisense"
1897
+ ]
1898
+ }
1899
+ `},{id:"health-check-doc",name:"Health Check Guide",description:"Health check endpoint documentation with Kubernetes config",defaultPath:"docs/health-checks.md",category:"monitoring",content:`# Health Checks — {{PROJECT_NAME}}
1900
+
1901
+ **Last updated:** {{DATE}}
1902
+
1903
+ ## Overview
1904
+
1905
+ Health check endpoints allow load balancers and orchestrators to verify service status.
1906
+
1907
+ ## Endpoints
1908
+
1909
+ | Endpoint | Purpose | Auth required |
1910
+ |----------|---------|---------------|
1911
+ | \`GET /health\` | Liveness probe — is the process running? | No |
1912
+ | \`GET /health/ready\` | Readiness probe — can the service handle traffic? | No |
1913
+ | \`GET /health/detailed\` | Full dependency status | Yes (internal) |
1914
+
1915
+ ## Liveness Check (\`GET /health\`)
1916
+
1917
+ Returns 200 if the process is alive, regardless of dependency status.
1918
+
1919
+ \`\`\`json
1920
+ {"status": "ok", "uptime": 1234}
1921
+ \`\`\`
1922
+
1923
+ ## Readiness Check (\`GET /health/ready\`)
1924
+
1925
+ Returns 200 only if all critical dependencies are healthy.
1926
+
1927
+ \`\`\`json
1928
+ {
1929
+ "status": "ready",
1930
+ "dependencies": {
1931
+ "database": "ok",
1932
+ "redis": "ok",
1933
+ "external_api": "degraded"
1934
+ }
1935
+ }
1936
+ \`\`\`
1937
+
1938
+ Returns 503 if any critical dependency is unhealthy.
1939
+
1940
+ ## Kubernetes Configuration
1941
+
1942
+ \`\`\`yaml
1943
+ livenessProbe:
1944
+ httpGet:
1945
+ path: /health
1946
+ port: 3000
1947
+ initialDelaySeconds: 30
1948
+ periodSeconds: 10
1949
+ readinessProbe:
1950
+ httpGet:
1951
+ path: /health/ready
1952
+ port: 3000
1953
+ initialDelaySeconds: 5
1954
+ periodSeconds: 5
1955
+ \`\`\`
1956
+ `},{id:"slo-doc",name:"SLO/SLA Document",description:"Service Level Objectives with error budget and burn rate alerts",defaultPath:"docs/slo.md",category:"monitoring",content:`# Service Level Objectives — {{PROJECT_NAME}}
1957
+
1958
+ **Last updated:** {{DATE}}
1959
+ **Owner:** Platform Team
1960
+
1961
+ ## Availability SLO
1962
+
1963
+ | Metric | Target | Error Budget (30 days) |
1964
+ |--------|--------|----------------------|
1965
+ | Availability | 99.9% | 43.8 minutes |
1966
+ | Success rate | 99.5% | — |
1967
+
1968
+ ## Latency SLO
1969
+
1970
+ | Percentile | Target |
1971
+ |------------|--------|
1972
+ | p50 | < 100ms |
1973
+ | p95 | < 500ms |
1974
+ | p99 | < 1000ms |
1975
+
1976
+ ## Error Budget Policy
1977
+
1978
+ | Burn Rate | Alert Window | Severity | Action |
1979
+ |-----------|-------------|----------|--------|
1980
+ | > 14.4x | 1 hour | Critical | Page on-call immediately |
1981
+ | > 6x | 6 hours | High | Page on-call |
1982
+ | > 3x | 24 hours | Medium | Ticket + monitor |
1983
+ | > 1x | 72 hours | Low | Review in standup |
1984
+
1985
+ ## Consequences of Exhausting Error Budget
1986
+
1987
+ - Feature freeze until budget replenishes
1988
+ - Reliability sprint prioritized over new features
1989
+ - Post-mortem required for any budget burn > 50%
1990
+
1991
+ ## Measurement
1992
+
1993
+ - Uptime tracked via synthetic monitoring (Pingdom / UptimeRobot)
1994
+ - Latency tracked via APM (Datadog / New Relic)
1995
+ - Error rate from application logs + Sentry
1996
+ `},{id:"incident-runbook",name:"Incident Runbook",description:"Incident response runbook with severity levels and escalation",defaultPath:"docs/incident-runbook.md",category:"monitoring",content:`# Incident Runbook — {{PROJECT_NAME}}
1997
+
1998
+ **Last updated:** {{DATE}}
1999
+
2000
+ ## Severity Levels
2001
+
2002
+ | Severity | Definition | Response Time | Example |
2003
+ |----------|-----------|---------------|---------|
2004
+ | P0 | Complete outage, all users affected | 15 minutes | Site down |
2005
+ | P1 | Major feature broken, >50% users affected | 30 minutes | Login broken |
2006
+ | P2 | Significant degradation, subset of users | 2 hours | Slow API |
2007
+ | P3 | Minor issue, workaround available | Next business day | Cosmetic bug |
2008
+
2009
+ ## Roles
2010
+
2011
+ | Role | Responsibility |
2012
+ |------|---------------|
2013
+ | Incident Commander (IC) | Owns resolution, coordinates team, communicates status |
2014
+ | Tech Lead | Diagnoses root cause, coordinates fixes |
2015
+ | Comms Lead | Updates status page, notifies stakeholders |
2016
+
2017
+ ## Response Process
2018
+
2019
+ ### 0–15 minutes (Detect & Triage)
2020
+ 1. Confirm the incident (not a false alarm)
2021
+ 2. Assign Incident Commander
2022
+ 3. Create incident Slack channel: \`#incident-YYYYMMDD-description\`
2023
+ 4. Set severity level
2024
+ 5. Start incident timeline document
2025
+
2026
+ ### 15–60 minutes (Investigate)
2027
+ 1. Identify scope: what's broken, who's affected
2028
+ 2. Check recent deployments (\`git log\`, deployment history)
2029
+ 3. Review error rates and logs
2030
+ 4. Consider rollback if recent deploy is suspected
2031
+
2032
+ ### Mitigation
2033
+ 1. Apply fix or rollback
2034
+ 2. Monitor for improvement
2035
+ 3. Update status page
2036
+ 4. Notify stakeholders
2037
+
2038
+ ## Post-Incident Checklist
2039
+
2040
+ - [ ] Incident resolved and verified
2041
+ - [ ] Status page updated to "resolved"
2042
+ - [ ] Stakeholders notified
2043
+ - [ ] Timeline documented
2044
+ - [ ] Post-mortem scheduled (P0/P1) or ticket created (P2)
2045
+ - [ ] Action items created in project tracker
2046
+ `},{id:"postmortem",name:"Postmortem Template",description:"Blameless postmortem template with five-whys and action items",defaultPath:"docs/postmortem-template.md",category:"monitoring",content:`# Postmortem: [Title]
2047
+
2048
+ **Date:** {{DATE}}
2049
+ **Severity:** P[0-3]
2050
+ **Duration:**
2051
+ **Author:**
2052
+ **Reviewers:**
2053
+
2054
+ > This postmortem follows a blameless culture. We focus on systems and processes, not individuals.
2055
+
2056
+ ## Summary
2057
+
2058
+ <!-- 2-3 sentence summary: what happened, why it matters, what we're doing about it -->
2059
+
2060
+ ## Impact
2061
+
2062
+ - **Users affected:**
2063
+ - **Duration:**
2064
+ - **Revenue impact:**
2065
+ - **Data loss:**
2066
+
2067
+ ## Timeline
2068
+
2069
+ | Time (UTC) | Event |
2070
+ |------------|-------|
2071
+ | 00:00 | Monitoring alert fired |
2072
+ | 00:05 | On-call engineer paged |
2073
+ | 00:15 | Incident confirmed, IC assigned |
2074
+ | 00:30 | Root cause identified |
2075
+ | 01:00 | Fix deployed |
2076
+ | 01:15 | Incident resolved |
2077
+
2078
+ ## Root Cause Analysis (Five Whys)
2079
+
2080
+ **Problem:** [Describe the issue]
2081
+
2082
+ 1. **Why?** [First cause]
2083
+ 2. **Why?** [Second cause]
2084
+ 3. **Why?** [Third cause]
2085
+ 4. **Why?** [Fourth cause]
2086
+ 5. **Why?** [Root cause]
2087
+
2088
+ ## What Went Well
2089
+
2090
+ -
2091
+ -
2092
+
2093
+ ## What Could Have Gone Better
2094
+
2095
+ -
2096
+ -
2097
+
2098
+ ## Action Items
2099
+
2100
+ | Action | Owner | Due Date | Priority |
2101
+ |--------|-------|----------|----------|
2102
+ | | | | P[0-3] |
2103
+
2104
+ ## Lessons Learned
2105
+
2106
+ <!-- Key takeaways to share with the wider team -->
2107
+ `}]},5098:(e,t,a)=>{"use strict";a.d(t,{cn:()=>i});var s=a(9360),r=a(2646);function i(...e){return(0,r.m6)((0,s.W)(e))}},2026:(e,t,a)=>{"use strict";a.r(t),a.d(t,{$$typeof:()=>n,__esModule:()=>i,default:()=>o});var s=a(2334);let r=(0,s.createProxy)(String.raw`/Users/hoangnguyen/Documents/nextjs/vibedoc/src/app/(app)/layout.tsx`),{__esModule:i,$$typeof:n}=r;r.default;let o=(0,s.createProxy)(String.raw`/Users/hoangnguyen/Documents/nextjs/vibedoc/src/app/(app)/layout.tsx#default`)},7831:(e,t,a)=>{"use strict";a.r(t),a.d(t,{default:()=>i,metadata:()=>r});var s=a(9703);a(5260);let r={title:"VibeDoc",description:"Project intelligence for AI-assisted development"};function i({children:e}){return s.jsx("html",{lang:"en",className:"dark",children:s.jsx("body",{className:"bg-bg text-txt min-h-screen",children:e})})}},5260:()=>{}};