loki-mode 6.74.3 → 6.74.4

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 (62) hide show
  1. package/SKILL.md +2 -2
  2. package/VERSION +1 -1
  3. package/dashboard/__init__.py +1 -1
  4. package/docs/INSTALLATION.md +1 -1
  5. package/mcp/__init__.py +1 -1
  6. package/package.json +1 -1
  7. package/web-app/dist/assets/{AdminPage-DZhVlTXm.js → AdminPage-Cwqm_kDg.js} +1 -1
  8. package/web-app/dist/assets/{Avatar-Bbw5Q-Wz.js → Avatar-BgcFY2E5.js} +1 -1
  9. package/web-app/dist/assets/{Badge-iZ84_iz4.js → Badge-DeFGfZLB.js} +1 -1
  10. package/web-app/dist/assets/{Button-DO-Xq3YT.js → Button-Dg1EkPtN.js} +1 -1
  11. package/web-app/dist/assets/{ComparePage-CMjaGKwJ.js → ComparePage-D-wvMVP2.js} +1 -1
  12. package/web-app/dist/assets/{GitHubIssuesPanel-TLudouS-.js → GitHubIssuesPanel-B_Jm7CmJ.js} +1 -1
  13. package/web-app/dist/assets/{GitHubPRsPanel-bjj0yQTk.js → GitHubPRsPanel-B5i8Q99N.js} +1 -1
  14. package/web-app/dist/assets/{HomePage-t5G7OAGE.js → HomePage-CUDTdntY.js} +1 -1
  15. package/web-app/dist/assets/{LoginPage-CeQRXV4C.js → LoginPage-BobwVXx5.js} +1 -1
  16. package/web-app/dist/assets/{MetricsPage-B2zKVyJq.js → MetricsPage-DmM--20B.js} +1 -1
  17. package/web-app/dist/assets/{NotFoundPage-CxCe17V-.js → NotFoundPage-6_gjeogD.js} +1 -1
  18. package/web-app/dist/assets/{ProjectPage-B1Wti2GW.js → ProjectPage-C3R2wbFt.js} +5 -5
  19. package/web-app/dist/assets/{ProjectsPage-BDWfVwLK.js → ProjectsPage-DQr06iBk.js} +1 -1
  20. package/web-app/dist/assets/{SettingsPage-DlH1leQV.js → SettingsPage-eROlGKB9.js} +1 -1
  21. package/web-app/dist/assets/{ShowcasePage-DPnh3esb.js → ShowcasePage-DEA5tT_R.js} +1 -1
  22. package/web-app/dist/assets/{SystemSettingsPage-DZLDjoUr.js → SystemSettingsPage-C_rIbgZg.js} +1 -1
  23. package/web-app/dist/assets/{TeamsPage-BbYt_ldg.js → TeamsPage-DZGoYZnD.js} +1 -1
  24. package/web-app/dist/assets/{TemplatesPage-BuiIghxK.js → TemplatesPage-DVblWpbO.js} +1 -1
  25. package/web-app/dist/assets/{TerminalOutput-xGAottmX.js → TerminalOutput-DnESY9zk.js} +1 -1
  26. package/web-app/dist/assets/{activity-CmQBMOsV.js → activity-COLsZyo1.js} +1 -1
  27. package/web-app/dist/assets/{bell-BzaVT-q-.js → bell-BjLe9xXk.js} +1 -1
  28. package/web-app/dist/assets/{bot-CwK5RJjE.js → bot-Dz62aBIi.js} +1 -1
  29. package/web-app/dist/assets/{check-CxwV5Bzq.js → check-BQPQjkH4.js} +1 -1
  30. package/web-app/dist/assets/{chevron-left--TWMaYeL.js → chevron-left-BVvOVUQ8.js} +1 -1
  31. package/web-app/dist/assets/{circle-alert-BeU0GAf7.js → circle-alert-DqoLW238.js} +1 -1
  32. package/web-app/dist/assets/{clock-CasItKBM.js → clock-Cn9fFUva.js} +1 -1
  33. package/web-app/dist/assets/{cloud-p2bU6CXv.js → cloud-COJxbgUu.js} +1 -1
  34. package/web-app/dist/assets/{copy-BD_1Idwb.js → copy-DOn0hVgy.js} +1 -1
  35. package/web-app/dist/assets/{database-DpRtc5nU.js → database-Bj3Llvnk.js} +1 -1
  36. package/web-app/dist/assets/{dollar-sign-22E4a6bP.js → dollar-sign-BcmncygQ.js} +1 -1
  37. package/web-app/dist/assets/{file-code-corner-D1Re8J8b.js → file-code-corner-BysxoSyu.js} +1 -1
  38. package/web-app/dist/assets/{file-plus-BuKNP2FZ.js → file-plus-Dwi1MqSS.js} +1 -1
  39. package/web-app/dist/assets/{folder-open-DI7rcz5V.js → folder-open-WzXNCq2x.js} +1 -1
  40. package/web-app/dist/assets/{git-commit-horizontal-C4J-dLq2.js → git-commit-horizontal-D85UUfNF.js} +1 -1
  41. package/web-app/dist/assets/{globe-3vM1jtqs.js → globe-CegT0VaL.js} +1 -1
  42. package/web-app/dist/assets/{hammer-ukr7gJ35.js → hammer-ZGKvu_xy.js} +1 -1
  43. package/web-app/dist/assets/{index-BYtEgkrl.js → index-_2iPl2nX.js} +2 -2
  44. package/web-app/dist/assets/{layers-DZtUCskD.js → layers-B40lki5j.js} +1 -1
  45. package/web-app/dist/assets/{lightbulb-CS390qaD.js → lightbulb-CFSoqUsV.js} +1 -1
  46. package/web-app/dist/assets/{loader-circle-BB_MVBmf.js → loader-circle-womi7Brk.js} +1 -1
  47. package/web-app/dist/assets/{lock-BtBqgsZ0.js → lock-CEWBb_SL.js} +1 -1
  48. package/web-app/dist/assets/{mail-rabbO_5W.js → mail-DimGrYf8.js} +1 -1
  49. package/web-app/dist/assets/{package-MkQHuN6g.js → package-DysIuuIJ.js} +1 -1
  50. package/web-app/dist/assets/{plus-C_Sb_op9.js → plus-DG1hW27_.js} +1 -1
  51. package/web-app/dist/assets/{refresh-cw-DEs70a7E.js → refresh-cw-X31ig0S6.js} +1 -1
  52. package/web-app/dist/assets/{rotate-ccw-DvMVZ3AX.js → rotate-ccw-CBXooICo.js} +1 -1
  53. package/web-app/dist/assets/{save-DOEP5ubi.js → save-DQVrWTjZ.js} +1 -1
  54. package/web-app/dist/assets/{server-DJBVZTUn.js → server-BYAMALfa.js} +1 -1
  55. package/web-app/dist/assets/{shield-alert-xdJ97H55.js → shield-alert-B3G7vLiW.js} +1 -1
  56. package/web-app/dist/assets/{trash-2-DuD7ogiq.js → trash-2-ChVunC-C.js} +1 -1
  57. package/web-app/dist/assets/{trending-down-BYq7V2Q5.js → trending-down-DgsuOE2t.js} +1 -1
  58. package/web-app/dist/assets/{trending-up-BeD-iNQC.js → trending-up-CZHZsGeN.js} +1 -1
  59. package/web-app/dist/assets/{usePolling-2LO_f1l4.js → usePolling-ns_dFCVn.js} +1 -1
  60. package/web-app/dist/assets/{user-CJc2DWfN.js → user-FQUrWHhF.js} +1 -1
  61. package/web-app/dist/index.html +1 -1
  62. package/web-app/server.py +62 -8
@@ -1,4 +1,4 @@
1
- import{c as $,j as e,r as u,w as D,g as P,h as R,u as z,a as E,m as L,k as M,E as A}from"./index-BYtEgkrl.js";import{B as C}from"./Button-DO-Xq3YT.js";import{B as _}from"./Badge-iZ84_iz4.js";import{L as U}from"./lightbulb-CS390qaD.js";import{T as I}from"./trending-up-BeD-iNQC.js";import{T as H,M as O}from"./trending-down-BYq7V2Q5.js";import{u as Y}from"./usePolling-2LO_f1l4.js";import{R as q}from"./refresh-cw-DEs70a7E.js";import{P as S}from"./plus-C_Sb_op9.js";import{F as G}from"./folder-open-DI7rcz5V.js";import{C as K}from"./copy-BD_1Idwb.js";import{T as Q}from"./trash-2-DuD7ogiq.js";import"./clock-CasItKBM.js";import"./circle-alert-BeU0GAf7.js";import"./check-CxwV5Bzq.js";/**
1
+ import{c as $,j as e,r as u,w as D,g as P,h as R,u as z,a as E,m as L,k as M,E as A}from"./index-_2iPl2nX.js";import{B as C}from"./Button-Dg1EkPtN.js";import{B as _}from"./Badge-DeFGfZLB.js";import{L as U}from"./lightbulb-CFSoqUsV.js";import{T as I}from"./trending-up-CZHZsGeN.js";import{T as H,M as O}from"./trending-down-DgsuOE2t.js";import{u as Y}from"./usePolling-ns_dFCVn.js";import{R as q}from"./refresh-cw-X31ig0S6.js";import{P as S}from"./plus-DG1hW27_.js";import{F as G}from"./folder-open-WzXNCq2x.js";import{C as K}from"./copy-DOn0hVgy.js";import{T as Q}from"./trash-2-ChVunC-C.js";import"./clock-Cn9fFUva.js";import"./circle-alert-DqoLW238.js";import"./check-BQPQjkH4.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as tt,j as e,r as t,x as fe,a as se,y as st,O as at,K as nt,I as ot,m as it,E as lt}from"./index-BYtEgkrl.js";import{E as rt,R as ct}from"./rotate-ccw-DvMVZ3AX.js";import{H as dt}from"./hammer-ukr7gJ35.js";import{C as ut}from"./cloud-p2bU6CXv.js";import{L as xt}from"./loader-circle-BB_MVBmf.js";import{C as mt}from"./check-CxwV5Bzq.js";import{C as pt}from"./circle-alert-BeU0GAf7.js";/**
1
+ import{c as tt,j as e,r as t,x as fe,a as se,y as st,O as at,K as nt,I as ot,m as it,E as lt}from"./index-_2iPl2nX.js";import{E as rt,R as ct}from"./rotate-ccw-CBXooICo.js";import{H as dt}from"./hammer-ZGKvu_xy.js";import{C as ut}from"./cloud-COJxbgUu.js";import{L as xt}from"./loader-circle-womi7Brk.js";import{C as mt}from"./check-BQPQjkH4.js";import{C as pt}from"./circle-alert-DqoLW238.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1 +1 @@
1
- import{j as e,r as c,g as m,h as p,X as h,u}from"./index-BYtEgkrl.js";const x=[{label:"Q1 2026",period:"Jan - Mar",features:[{name:"Multi-provider support (5 providers)",status:"completed"},{name:"Memory system with vector search",status:"completed"},{name:"Purple Lab web UI",status:"completed"},{name:"Enterprise auth (OIDC, RBAC)",status:"completed"},{name:"Legacy system healing",status:"completed"}]},{label:"Q2 2026",period:"Apr - Jun",features:[{name:"Real-time collaboration (multi-user)",status:"in-progress"},{name:"Visual workflow builder",status:"in-progress"},{name:"Plugin marketplace",status:"planned"},{name:"Custom agent creation UI",status:"planned"}]},{label:"Q3 2026",period:"Jul - Sep",features:[{name:"Cloud deployment integration",status:"planned"},{name:"Team analytics dashboard",status:"planned"},{name:"AI-powered debugging assistant",status:"planned"},{name:"Mobile companion app",status:"planned"}]},{label:"Q4 2026",period:"Oct - Dec",features:[{name:"Multi-repo orchestration",status:"planned"},{name:"Custom model fine-tuning",status:"planned"},{name:"Compliance report generation",status:"planned"},{name:"On-prem cluster mode",status:"planned"}]}],l={completed:{dot:"bg-[#1FC5A8]",text:"text-[#36342E]",label:"Shipped"},"in-progress":{dot:"bg-[#553DE9]",text:"text-[#36342E]",label:"In Progress"},planned:{dot:"bg-[#939084]",text:"text-[#6B6960]",label:"Planned"}};function b(){return e.jsxs("div",{className:"py-8",children:[e.jsx("h3",{className:"text-xl font-bold text-[#36342E] mb-2",children:"Product Roadmap"}),e.jsx("p",{className:"text-sm text-[#6B6960] mb-8",children:"Where we have been and where we are heading."}),e.jsx("div",{className:"flex gap-6 mb-6",children:["completed","in-progress","planned"].map(t=>e.jsxs("div",{className:"flex items-center gap-2 text-xs",children:[e.jsx("span",{className:`w-2.5 h-2.5 rounded-full ${l[t].dot}`}),e.jsx("span",{className:"text-[#6B6960]",children:l[t].label})]},t))}),e.jsxs("div",{className:"relative",children:[e.jsx("div",{className:"absolute left-[7px] top-2 bottom-2 w-0.5 bg-[#ECEAE3]"}),e.jsx("div",{className:"space-y-8",children:x.map((t,i)=>e.jsxs("div",{className:"relative pl-8",children:[e.jsx("div",{className:`absolute left-0 top-1 w-[15px] h-[15px] rounded-full border-2 border-white shadow-sm ${i===0?"bg-[#1FC5A8]":i===1?"bg-[#553DE9]":"bg-[#ECEAE3]"}`}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-baseline gap-2 mb-3",children:[e.jsx("h4",{className:"text-base font-bold text-[#36342E]",children:t.label}),e.jsx("span",{className:"text-xs text-[#939084]",children:t.period}),i===1&&e.jsx("span",{className:"px-2 py-0.5 text-xs font-medium rounded-full bg-[#553DE9]/10 text-[#553DE9]",children:"Current"})]}),e.jsx("div",{className:"space-y-2",children:t.features.map(a=>{const s=l[a.status];return e.jsxs("div",{className:"flex items-center gap-2.5",children:[e.jsx("span",{className:`w-2 h-2 rounded-full flex-shrink-0 ${s.dot}`}),e.jsx("span",{className:`text-sm ${s.text}`,children:a.name})]},a.name)})})]})]},t.label))})]})]})}const n=[{version:"6.71.1",date:"Mar 24, 2026",features:["BuildProgressBar server integration with cost, ETA, and phase data","Sprint 1 complete: BuildProgressBar, CommandPalette, dark mode, sidebar theme toggle","Quick-start API, dark mode prep, theme hook foundation"]},{version:"6.70.0",date:"Mar 22, 2026",features:["Embedded Loki Dashboard in Purple Lab workspace","Panel toggles, modern UI, bigger fonts, smooth transitions","Sprint 1 foundation with quick-start API"]},{version:"6.69.0",date:"Mar 20, 2026",features:["Purple Lab IDE workspace with Monaco editor","AI chat panel for iterative development","Activity panel with build log and quality gates"]}];function g(){const[t,i]=c.useState(!1),a=t?n:n.slice(0,2);return e.jsxs("div",{className:"bg-white border border-[#ECEAE3] rounded-xl p-4 shadow-sm",children:[e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsx("h4",{className:"text-sm font-bold text-[#36342E]",children:"Recent Changes"}),e.jsx("a",{href:"https://github.com/asklokesh/loki-mode/blob/main/CHANGELOG.md",target:"_blank",rel:"noopener noreferrer",className:"text-xs text-[#553DE9] hover:text-[#4832c7] font-medium",children:"View all"})]}),e.jsx("div",{className:"space-y-3",children:a.map(s=>e.jsxs("div",{className:"pb-3 border-b border-[#ECEAE3] last:border-b-0 last:pb-0",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1.5",children:[e.jsxs("span",{className:"px-1.5 py-0.5 text-xs font-mono font-bold rounded bg-[#553DE9]/10 text-[#553DE9]",children:["v",s.version]}),e.jsx("span",{className:"text-xs text-[#939084]",children:s.date})]}),e.jsx("ul",{className:"space-y-1",children:s.features.map((r,o)=>e.jsx("li",{className:"text-xs text-[#6B6960] pl-3 relative before:content-[''] before:absolute before:left-0 before:top-[7px] before:w-1.5 before:h-1.5 before:rounded-full before:bg-[#ECEAE3]",children:r},o))})]},s.version))}),n.length>2&&e.jsxs("button",{onClick:()=>i(!t),className:"mt-2 flex items-center gap-1 text-xs text-[#6B6960] hover:text-[#36342E] transition-colors",children:[t?e.jsx(m,{size:12}):e.jsx(p,{size:12}),t?"Show less":`Show ${n.length-2} more`]})]})}const f={default:"bg-[#F8F4F0] text-[#36342E] border-[#ECEAE3] dark:bg-[#222228] dark:text-[#E8E6E3] dark:border-[#2A2A30]",primary:"bg-[#553DE9]/10 text-[#553DE9] border-[#553DE9]/20 dark:bg-[#553DE9]/20 dark:text-[#7B6BEF] dark:border-[#553DE9]/30",success:"bg-[#1FC5A8]/10 text-[#1FC5A8] border-[#1FC5A8]/20",warning:"bg-[#E5A940]/10 text-[#E5A940] border-[#E5A940]/20",danger:"bg-[#C45B5B]/10 text-[#C45B5B] border-[#C45B5B]/20",info:"bg-[#3B82F6]/10 text-[#3B82F6] border-[#3B82F6]/20"};function E({label:t,color:i="default",removable:a=!1,onClick:s,onRemove:r,className:o=""}){return e.jsxs("span",{className:`inline-flex items-center gap-1 px-2.5 py-0.5 text-xs font-medium rounded-full border transition-colors ${f[i]} ${s?"cursor-pointer hover:opacity-80":""} ${o}`,onClick:s,role:s?"button":void 0,children:[t,a&&e.jsx("button",{type:"button",onClick:d=>{d.stopPropagation(),r==null||r()},className:"inline-flex items-center justify-center w-3.5 h-3.5 rounded-full hover:bg-black/10 dark:hover:bg-white/10 transition-colors","aria-label":`Remove ${t}`,children:e.jsx(h,{size:10})})]})}const w=[{title:"SaaS Dashboard",description:"Admin dashboard with user analytics, charts, and real-time data visualization.",techStack:["React","Tailwind","Chart.js"],buildTime:"~25 min",gradient:"from-[#553DE9] to-[#7B6BEF]",prompt:"Build a SaaS admin dashboard with user analytics, charts showing MRR and churn, and a table of recent signups"},{title:"REST API Server",description:"Production-ready API with authentication, validation, and database integration.",techStack:["Node.js","Express","PostgreSQL"],buildTime:"~20 min",gradient:"from-[#1FC5A8] to-[#38D9A9]",prompt:"Build a REST API server with JWT authentication, user CRUD, input validation, and PostgreSQL database"},{title:"E-commerce Store",description:"Online store with product catalog, cart, checkout, and payment integration.",techStack:["Next.js","Stripe","Prisma"],buildTime:"~45 min",gradient:"from-[#E93D82] to-[#F06595]",prompt:"Build an e-commerce store with product listings, shopping cart, Stripe checkout, and order management"},{title:"Portfolio Website",description:"Personal portfolio with animations, project showcase, and contact form.",techStack:["React","Framer Motion","Tailwind"],buildTime:"~15 min",gradient:"from-[#F59F00] to-[#FCC419]",prompt:"Build a developer portfolio website with animated sections, project gallery, skills list, and contact form"},{title:"CLI Tool",description:"Command-line tool with subcommands, flags, configuration, and colorful output.",techStack:["Node.js","Commander","Chalk"],buildTime:"~15 min",gradient:"from-[#36342E] to-[#6B6960]",prompt:"Build a CLI tool with subcommands for file management: list, copy, move, and search with glob patterns"},{title:"Discord Bot",description:"Interactive bot with slash commands, moderation, and custom responses.",techStack:["Discord.js","Node.js","SQLite"],buildTime:"~20 min",gradient:"from-[#5865F2] to-[#7289DA]",prompt:"Build a Discord bot with slash commands for polls, reminders, moderation (kick/ban), and a leveling system"},{title:"Blog Platform",description:"Full-featured blog with markdown support, categories, and RSS feed.",techStack:["React","MDX","Tailwind"],buildTime:"~30 min",gradient:"from-[#845EF7] to-[#B197FC]",prompt:"Build a blog platform with MDX support, category filtering, search, RSS feed, and a clean reading experience"},{title:"Task Manager",description:"Kanban-style task board with drag-and-drop, labels, and persistence.",techStack:["React","DnD Kit","SQLite"],buildTime:"~25 min",gradient:"from-[#2F71E3] to-[#5C93E8]",prompt:"Build a task manager with kanban board, drag-and-drop cards, labels, due dates, and local SQLite storage"},{title:"Weather App",description:"Weather dashboard with location search, forecasts, and beautiful visualizations.",techStack:["React","OpenWeatherMap","Chart.js"],buildTime:"~15 min",gradient:"from-[#0EA5E9] to-[#38BDF8]",prompt:"Build a weather app with city search, 5-day forecast, current conditions, and temperature charts"},{title:"Chat Application",description:"Real-time chat with rooms, typing indicators, and message history.",techStack:["React","WebSocket","Node.js"],buildTime:"~30 min",gradient:"from-[#22C55E] to-[#4ADE80]",prompt:"Build a real-time chat application with chat rooms, user presence, typing indicators, and message history"},{title:"Landing Page",description:"Conversion-optimized landing page with hero, features, pricing, and CTA sections.",techStack:["HTML","Tailwind","Alpine.js"],buildTime:"~10 min",gradient:"from-[#F97316] to-[#FB923C]",prompt:"Build a SaaS landing page with hero section, feature grid, pricing table, testimonials, and email signup"},{title:"Mobile App",description:"Cross-platform mobile app with navigation, state management, and native features.",techStack:["React Native","Expo","TypeScript"],buildTime:"~35 min",gradient:"from-[#DC2626] to-[#F87171]",prompt:"Build a React Native mobile app with tab navigation, a home feed, profile page, and push notifications setup"}];function j(){const t=u(),i=a=>{sessionStorage.setItem("pl_showcase_prompt",a),t("/")};return e.jsx("div",{className:"min-h-screen bg-[#FAF9F6]",children:e.jsxs("div",{className:"max-w-6xl mx-auto px-6 py-8",children:[e.jsxs("div",{className:"mb-8",children:[e.jsx("h1",{className:"text-2xl font-bold text-[#36342E]",children:"Showcase"}),e.jsx("p",{className:"text-[#6B6960] mt-1",children:'Explore example projects you can build with Loki Mode. Click "Build This" to start any project instantly.'})]}),e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-5",children:w.map(a=>e.jsxs("div",{className:"bg-white border border-[#ECEAE3] rounded-xl overflow-hidden shadow-sm hover:shadow-md transition-shadow flex flex-col",children:[e.jsx("div",{className:`h-28 bg-gradient-to-br ${a.gradient} flex items-end p-4`,children:e.jsx("h3",{className:"text-lg font-bold text-white drop-shadow-sm",children:a.title})}),e.jsxs("div",{className:"p-4 flex-1 flex flex-col",children:[e.jsx("p",{className:"text-sm text-[#6B6960] mb-3",children:a.description}),e.jsx("div",{className:"flex flex-wrap gap-1.5 mb-3",children:a.techStack.map(s=>e.jsx(E,{label:s,color:"default"},s))}),e.jsxs("div",{className:"mt-auto pt-3 border-t border-[#ECEAE3] flex items-center justify-between",children:[e.jsxs("span",{className:"text-xs text-[#939084]",children:["Est. ",a.buildTime]}),e.jsx("button",{onClick:()=>i(a.prompt),className:"px-4 py-1.5 text-sm font-semibold rounded-lg bg-[#553DE9] text-white hover:bg-[#4832c7] transition-colors",children:"Build This"})]})]})]},a.title))}),e.jsx("div",{className:"mt-12",children:e.jsx(b,{})}),e.jsx("div",{className:"mt-8 max-w-md",children:e.jsx(g,{})})]})})}export{j as default};
1
+ import{j as e,r as c,g as m,h as p,X as h,u}from"./index-_2iPl2nX.js";const x=[{label:"Q1 2026",period:"Jan - Mar",features:[{name:"Multi-provider support (5 providers)",status:"completed"},{name:"Memory system with vector search",status:"completed"},{name:"Purple Lab web UI",status:"completed"},{name:"Enterprise auth (OIDC, RBAC)",status:"completed"},{name:"Legacy system healing",status:"completed"}]},{label:"Q2 2026",period:"Apr - Jun",features:[{name:"Real-time collaboration (multi-user)",status:"in-progress"},{name:"Visual workflow builder",status:"in-progress"},{name:"Plugin marketplace",status:"planned"},{name:"Custom agent creation UI",status:"planned"}]},{label:"Q3 2026",period:"Jul - Sep",features:[{name:"Cloud deployment integration",status:"planned"},{name:"Team analytics dashboard",status:"planned"},{name:"AI-powered debugging assistant",status:"planned"},{name:"Mobile companion app",status:"planned"}]},{label:"Q4 2026",period:"Oct - Dec",features:[{name:"Multi-repo orchestration",status:"planned"},{name:"Custom model fine-tuning",status:"planned"},{name:"Compliance report generation",status:"planned"},{name:"On-prem cluster mode",status:"planned"}]}],l={completed:{dot:"bg-[#1FC5A8]",text:"text-[#36342E]",label:"Shipped"},"in-progress":{dot:"bg-[#553DE9]",text:"text-[#36342E]",label:"In Progress"},planned:{dot:"bg-[#939084]",text:"text-[#6B6960]",label:"Planned"}};function b(){return e.jsxs("div",{className:"py-8",children:[e.jsx("h3",{className:"text-xl font-bold text-[#36342E] mb-2",children:"Product Roadmap"}),e.jsx("p",{className:"text-sm text-[#6B6960] mb-8",children:"Where we have been and where we are heading."}),e.jsx("div",{className:"flex gap-6 mb-6",children:["completed","in-progress","planned"].map(t=>e.jsxs("div",{className:"flex items-center gap-2 text-xs",children:[e.jsx("span",{className:`w-2.5 h-2.5 rounded-full ${l[t].dot}`}),e.jsx("span",{className:"text-[#6B6960]",children:l[t].label})]},t))}),e.jsxs("div",{className:"relative",children:[e.jsx("div",{className:"absolute left-[7px] top-2 bottom-2 w-0.5 bg-[#ECEAE3]"}),e.jsx("div",{className:"space-y-8",children:x.map((t,i)=>e.jsxs("div",{className:"relative pl-8",children:[e.jsx("div",{className:`absolute left-0 top-1 w-[15px] h-[15px] rounded-full border-2 border-white shadow-sm ${i===0?"bg-[#1FC5A8]":i===1?"bg-[#553DE9]":"bg-[#ECEAE3]"}`}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-baseline gap-2 mb-3",children:[e.jsx("h4",{className:"text-base font-bold text-[#36342E]",children:t.label}),e.jsx("span",{className:"text-xs text-[#939084]",children:t.period}),i===1&&e.jsx("span",{className:"px-2 py-0.5 text-xs font-medium rounded-full bg-[#553DE9]/10 text-[#553DE9]",children:"Current"})]}),e.jsx("div",{className:"space-y-2",children:t.features.map(a=>{const s=l[a.status];return e.jsxs("div",{className:"flex items-center gap-2.5",children:[e.jsx("span",{className:`w-2 h-2 rounded-full flex-shrink-0 ${s.dot}`}),e.jsx("span",{className:`text-sm ${s.text}`,children:a.name})]},a.name)})})]})]},t.label))})]})]})}const n=[{version:"6.71.1",date:"Mar 24, 2026",features:["BuildProgressBar server integration with cost, ETA, and phase data","Sprint 1 complete: BuildProgressBar, CommandPalette, dark mode, sidebar theme toggle","Quick-start API, dark mode prep, theme hook foundation"]},{version:"6.70.0",date:"Mar 22, 2026",features:["Embedded Loki Dashboard in Purple Lab workspace","Panel toggles, modern UI, bigger fonts, smooth transitions","Sprint 1 foundation with quick-start API"]},{version:"6.69.0",date:"Mar 20, 2026",features:["Purple Lab IDE workspace with Monaco editor","AI chat panel for iterative development","Activity panel with build log and quality gates"]}];function g(){const[t,i]=c.useState(!1),a=t?n:n.slice(0,2);return e.jsxs("div",{className:"bg-white border border-[#ECEAE3] rounded-xl p-4 shadow-sm",children:[e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsx("h4",{className:"text-sm font-bold text-[#36342E]",children:"Recent Changes"}),e.jsx("a",{href:"https://github.com/asklokesh/loki-mode/blob/main/CHANGELOG.md",target:"_blank",rel:"noopener noreferrer",className:"text-xs text-[#553DE9] hover:text-[#4832c7] font-medium",children:"View all"})]}),e.jsx("div",{className:"space-y-3",children:a.map(s=>e.jsxs("div",{className:"pb-3 border-b border-[#ECEAE3] last:border-b-0 last:pb-0",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1.5",children:[e.jsxs("span",{className:"px-1.5 py-0.5 text-xs font-mono font-bold rounded bg-[#553DE9]/10 text-[#553DE9]",children:["v",s.version]}),e.jsx("span",{className:"text-xs text-[#939084]",children:s.date})]}),e.jsx("ul",{className:"space-y-1",children:s.features.map((r,o)=>e.jsx("li",{className:"text-xs text-[#6B6960] pl-3 relative before:content-[''] before:absolute before:left-0 before:top-[7px] before:w-1.5 before:h-1.5 before:rounded-full before:bg-[#ECEAE3]",children:r},o))})]},s.version))}),n.length>2&&e.jsxs("button",{onClick:()=>i(!t),className:"mt-2 flex items-center gap-1 text-xs text-[#6B6960] hover:text-[#36342E] transition-colors",children:[t?e.jsx(m,{size:12}):e.jsx(p,{size:12}),t?"Show less":`Show ${n.length-2} more`]})]})}const f={default:"bg-[#F8F4F0] text-[#36342E] border-[#ECEAE3] dark:bg-[#222228] dark:text-[#E8E6E3] dark:border-[#2A2A30]",primary:"bg-[#553DE9]/10 text-[#553DE9] border-[#553DE9]/20 dark:bg-[#553DE9]/20 dark:text-[#7B6BEF] dark:border-[#553DE9]/30",success:"bg-[#1FC5A8]/10 text-[#1FC5A8] border-[#1FC5A8]/20",warning:"bg-[#E5A940]/10 text-[#E5A940] border-[#E5A940]/20",danger:"bg-[#C45B5B]/10 text-[#C45B5B] border-[#C45B5B]/20",info:"bg-[#3B82F6]/10 text-[#3B82F6] border-[#3B82F6]/20"};function E({label:t,color:i="default",removable:a=!1,onClick:s,onRemove:r,className:o=""}){return e.jsxs("span",{className:`inline-flex items-center gap-1 px-2.5 py-0.5 text-xs font-medium rounded-full border transition-colors ${f[i]} ${s?"cursor-pointer hover:opacity-80":""} ${o}`,onClick:s,role:s?"button":void 0,children:[t,a&&e.jsx("button",{type:"button",onClick:d=>{d.stopPropagation(),r==null||r()},className:"inline-flex items-center justify-center w-3.5 h-3.5 rounded-full hover:bg-black/10 dark:hover:bg-white/10 transition-colors","aria-label":`Remove ${t}`,children:e.jsx(h,{size:10})})]})}const w=[{title:"SaaS Dashboard",description:"Admin dashboard with user analytics, charts, and real-time data visualization.",techStack:["React","Tailwind","Chart.js"],buildTime:"~25 min",gradient:"from-[#553DE9] to-[#7B6BEF]",prompt:"Build a SaaS admin dashboard with user analytics, charts showing MRR and churn, and a table of recent signups"},{title:"REST API Server",description:"Production-ready API with authentication, validation, and database integration.",techStack:["Node.js","Express","PostgreSQL"],buildTime:"~20 min",gradient:"from-[#1FC5A8] to-[#38D9A9]",prompt:"Build a REST API server with JWT authentication, user CRUD, input validation, and PostgreSQL database"},{title:"E-commerce Store",description:"Online store with product catalog, cart, checkout, and payment integration.",techStack:["Next.js","Stripe","Prisma"],buildTime:"~45 min",gradient:"from-[#E93D82] to-[#F06595]",prompt:"Build an e-commerce store with product listings, shopping cart, Stripe checkout, and order management"},{title:"Portfolio Website",description:"Personal portfolio with animations, project showcase, and contact form.",techStack:["React","Framer Motion","Tailwind"],buildTime:"~15 min",gradient:"from-[#F59F00] to-[#FCC419]",prompt:"Build a developer portfolio website with animated sections, project gallery, skills list, and contact form"},{title:"CLI Tool",description:"Command-line tool with subcommands, flags, configuration, and colorful output.",techStack:["Node.js","Commander","Chalk"],buildTime:"~15 min",gradient:"from-[#36342E] to-[#6B6960]",prompt:"Build a CLI tool with subcommands for file management: list, copy, move, and search with glob patterns"},{title:"Discord Bot",description:"Interactive bot with slash commands, moderation, and custom responses.",techStack:["Discord.js","Node.js","SQLite"],buildTime:"~20 min",gradient:"from-[#5865F2] to-[#7289DA]",prompt:"Build a Discord bot with slash commands for polls, reminders, moderation (kick/ban), and a leveling system"},{title:"Blog Platform",description:"Full-featured blog with markdown support, categories, and RSS feed.",techStack:["React","MDX","Tailwind"],buildTime:"~30 min",gradient:"from-[#845EF7] to-[#B197FC]",prompt:"Build a blog platform with MDX support, category filtering, search, RSS feed, and a clean reading experience"},{title:"Task Manager",description:"Kanban-style task board with drag-and-drop, labels, and persistence.",techStack:["React","DnD Kit","SQLite"],buildTime:"~25 min",gradient:"from-[#2F71E3] to-[#5C93E8]",prompt:"Build a task manager with kanban board, drag-and-drop cards, labels, due dates, and local SQLite storage"},{title:"Weather App",description:"Weather dashboard with location search, forecasts, and beautiful visualizations.",techStack:["React","OpenWeatherMap","Chart.js"],buildTime:"~15 min",gradient:"from-[#0EA5E9] to-[#38BDF8]",prompt:"Build a weather app with city search, 5-day forecast, current conditions, and temperature charts"},{title:"Chat Application",description:"Real-time chat with rooms, typing indicators, and message history.",techStack:["React","WebSocket","Node.js"],buildTime:"~30 min",gradient:"from-[#22C55E] to-[#4ADE80]",prompt:"Build a real-time chat application with chat rooms, user presence, typing indicators, and message history"},{title:"Landing Page",description:"Conversion-optimized landing page with hero, features, pricing, and CTA sections.",techStack:["HTML","Tailwind","Alpine.js"],buildTime:"~10 min",gradient:"from-[#F97316] to-[#FB923C]",prompt:"Build a SaaS landing page with hero section, feature grid, pricing table, testimonials, and email signup"},{title:"Mobile App",description:"Cross-platform mobile app with navigation, state management, and native features.",techStack:["React Native","Expo","TypeScript"],buildTime:"~35 min",gradient:"from-[#DC2626] to-[#F87171]",prompt:"Build a React Native mobile app with tab navigation, a home feed, profile page, and push notifications setup"}];function j(){const t=u(),i=a=>{sessionStorage.setItem("pl_showcase_prompt",a),t("/")};return e.jsx("div",{className:"min-h-screen bg-[#FAF9F6]",children:e.jsxs("div",{className:"max-w-6xl mx-auto px-6 py-8",children:[e.jsxs("div",{className:"mb-8",children:[e.jsx("h1",{className:"text-2xl font-bold text-[#36342E]",children:"Showcase"}),e.jsx("p",{className:"text-[#6B6960] mt-1",children:'Explore example projects you can build with Loki Mode. Click "Build This" to start any project instantly.'})]}),e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-5",children:w.map(a=>e.jsxs("div",{className:"bg-white border border-[#ECEAE3] rounded-xl overflow-hidden shadow-sm hover:shadow-md transition-shadow flex flex-col",children:[e.jsx("div",{className:`h-28 bg-gradient-to-br ${a.gradient} flex items-end p-4`,children:e.jsx("h3",{className:"text-lg font-bold text-white drop-shadow-sm",children:a.title})}),e.jsxs("div",{className:"p-4 flex-1 flex flex-col",children:[e.jsx("p",{className:"text-sm text-[#6B6960] mb-3",children:a.description}),e.jsx("div",{className:"flex flex-wrap gap-1.5 mb-3",children:a.techStack.map(s=>e.jsx(E,{label:s,color:"default"},s))}),e.jsxs("div",{className:"mt-auto pt-3 border-t border-[#ECEAE3] flex items-center justify-between",children:[e.jsxs("span",{className:"text-xs text-[#939084]",children:["Est. ",a.buildTime]}),e.jsx("button",{onClick:()=>i(a.prompt),className:"px-4 py-1.5 text-sm font-semibold rounded-lg bg-[#553DE9] text-white hover:bg-[#4832c7] transition-colors",children:"Build This"})]})]})]},a.title))}),e.jsx("div",{className:"mt-12",children:e.jsx(b,{})}),e.jsx("div",{className:"mt-8 max-w-md",children:e.jsx(g,{})})]})})}export{j as default};
@@ -1,4 +1,4 @@
1
- import{c as M,r as o,j as e,w as C,x as S,T as D,Q as K}from"./index-BYtEgkrl.js";import{B as h}from"./Button-DO-Xq3YT.js";import{P as L}from"./plus-C_Sb_op9.js";import{C as g}from"./check-CxwV5Bzq.js";import{C as U}from"./copy-BD_1Idwb.js";import{R as q}from"./refresh-cw-DEs70a7E.js";import{E as B,R as _}from"./rotate-ccw-DvMVZ3AX.js";import{C as $}from"./clock-CasItKBM.js";import{T as G}from"./trash-2-DuD7ogiq.js";import{S as W}from"./server-DJBVZTUn.js";import{H as Y}from"./hammer-ukr7gJ35.js";import{B as V}from"./bell-BzaVT-q-.js";import{D as H}from"./database-DpRtc5nU.js";import{S as Q}from"./shield-alert-xdJ97H55.js";import{S as f}from"./save-DOEP5ubi.js";/**
1
+ import{c as M,r as o,j as e,w as C,x as S,T as D,Q as K}from"./index-_2iPl2nX.js";import{B as h}from"./Button-Dg1EkPtN.js";import{P as L}from"./plus-DG1hW27_.js";import{C as g}from"./check-BQPQjkH4.js";import{C as U}from"./copy-DOn0hVgy.js";import{R as q}from"./refresh-cw-X31ig0S6.js";import{E as B,R as _}from"./rotate-ccw-CBXooICo.js";import{C as $}from"./clock-Cn9fFUva.js";import{T as G}from"./trash-2-ChVunC-C.js";import{S as W}from"./server-BYAMALfa.js";import{H as Y}from"./hammer-ZGKvu_xy.js";import{B as V}from"./bell-BjLe9xXk.js";import{D as H}from"./database-Bj3Llvnk.js";import{S as Q}from"./shield-alert-B3G7vLiW.js";import{S as f}from"./save-DQVrWTjZ.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as P,r,j as e,U as w,X as B,h as z,x as U,a as F,w as O,b as V,g as H,M as q,R as K,l as Y,V as G,Y as X}from"./index-BYtEgkrl.js";import{B as N}from"./Button-DO-Xq3YT.js";import{U as M,A as D}from"./Avatar-Bbw5Q-Wz.js";import{M as J}from"./mail-rabbO_5W.js";import{L as Q}from"./lock-BtBqgsZ0.js";import{A as k}from"./activity-CmQBMOsV.js";import{P as _}from"./plus-C_Sb_op9.js";import{S as W}from"./save-DOEP5ubi.js";import{T as Z}from"./trash-2-DuD7ogiq.js";import{U as ee}from"./user-CJc2DWfN.js";import{C as $}from"./clock-CasItKBM.js";import{F as te}from"./file-code-corner-D1Re8J8b.js";import{F as se}from"./file-plus-BuKNP2FZ.js";import{H as ae}from"./hammer-ukr7gJ35.js";/**
1
+ import{c as P,r,j as e,U as w,X as B,h as z,x as U,a as F,w as O,b as V,g as H,M as q,R as K,l as Y,V as G,Y as X}from"./index-_2iPl2nX.js";import{B as N}from"./Button-Dg1EkPtN.js";import{U as M,A as D}from"./Avatar-BgcFY2E5.js";import{M as J}from"./mail-DimGrYf8.js";import{L as Q}from"./lock-CEWBb_SL.js";import{A as k}from"./activity-COLsZyo1.js";import{P as _}from"./plus-DG1hW27_.js";import{S as W}from"./save-DQVrWTjZ.js";import{T as Z}from"./trash-2-ChVunC-C.js";import{U as ee}from"./user-FQUrWHhF.js";import{C as $}from"./clock-Cn9fFUva.js";import{F as te}from"./file-code-corner-BysxoSyu.js";import{F as se}from"./file-plus-Dwi1MqSS.js";import{H as ae}from"./hammer-ZGKvu_xy.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as F,r as o,j as e,b as q,U as V,d as O,v as B,R as D,u as z,a as J,X as I,x as K,F as T,t as Z,H as X,A as ee,m as W,i as te}from"./index-BYtEgkrl.js";import{B as N}from"./Button-DO-Xq3YT.js";import{u as se}from"./usePolling-2LO_f1l4.js";import{C as ie}from"./chevron-left--TWMaYeL.js";import{C as P}from"./clock-CasItKBM.js";import{L as ae}from"./lightbulb-CS390qaD.js";import{L as le}from"./layers-DZtUCskD.js";import{C as S}from"./check-CxwV5Bzq.js";import{P as L}from"./package-MkQHuN6g.js";import{G as re}from"./globe-3vM1jtqs.js";import{S as ne}from"./server-DJBVZTUn.js";import{B as oe}from"./bot-CwK5RJjE.js";import{D as ce}from"./database-DpRtc5nU.js";import{P as de}from"./plus-C_Sb_op9.js";/**
1
+ import{c as F,r as o,j as e,b as q,U as V,d as O,v as B,R as D,u as z,a as J,X as I,x as K,F as T,t as Z,H as X,A as ee,m as W,i as te}from"./index-_2iPl2nX.js";import{B as N}from"./Button-Dg1EkPtN.js";import{u as se}from"./usePolling-ns_dFCVn.js";import{C as ie}from"./chevron-left-BVvOVUQ8.js";import{C as P}from"./clock-Cn9fFUva.js";import{L as ae}from"./lightbulb-CFSoqUsV.js";import{L as le}from"./layers-B40lki5j.js";import{C as S}from"./check-BQPQjkH4.js";import{P as L}from"./package-DysIuuIJ.js";import{G as re}from"./globe-CegT0VaL.js";import{S as ne}from"./server-BYAMALfa.js";import{B as oe}from"./bot-Dz62aBIi.js";import{D as ce}from"./database-Bj3Llvnk.js";import{P as de}from"./plus-DG1hW27_.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as p,r as l,j as e,T as j,h as y,b as N}from"./index-BYtEgkrl.js";import{L as S}from"./lock-BtBqgsZ0.js";/**
1
+ import{c as p,r as l,j as e,T as j,h as y,b as N}from"./index-_2iPl2nX.js";import{L as S}from"./lock-CEWBb_SL.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as t}from"./index-BYtEgkrl.js";/**
1
+ import{c as t}from"./index-_2iPl2nX.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as e}from"./index-BYtEgkrl.js";/**
1
+ import{c as e}from"./index-_2iPl2nX.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as t}from"./index-BYtEgkrl.js";/**
1
+ import{c as t}from"./index-_2iPl2nX.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c}from"./index-BYtEgkrl.js";/**
1
+ import{c}from"./index-_2iPl2nX.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as e}from"./index-BYtEgkrl.js";/**
1
+ import{c as e}from"./index-_2iPl2nX.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as e}from"./index-BYtEgkrl.js";/**
1
+ import{c as e}from"./index-_2iPl2nX.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c}from"./index-BYtEgkrl.js";/**
1
+ import{c}from"./index-_2iPl2nX.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as o}from"./index-BYtEgkrl.js";/**
1
+ import{c as o}from"./index-_2iPl2nX.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c}from"./index-BYtEgkrl.js";/**
1
+ import{c}from"./index-_2iPl2nX.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as e}from"./index-BYtEgkrl.js";/**
1
+ import{c as e}from"./index-_2iPl2nX.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as o}from"./index-BYtEgkrl.js";/**
1
+ import{c as o}from"./index-_2iPl2nX.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as e}from"./index-BYtEgkrl.js";/**
1
+ import{c as e}from"./index-_2iPl2nX.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as a}from"./index-BYtEgkrl.js";/**
1
+ import{c as a}from"./index-_2iPl2nX.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as a}from"./index-BYtEgkrl.js";/**
1
+ import{c as a}from"./index-_2iPl2nX.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as o}from"./index-BYtEgkrl.js";/**
1
+ import{c as o}from"./index-_2iPl2nX.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c}from"./index-BYtEgkrl.js";/**
1
+ import{c}from"./index-_2iPl2nX.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as a}from"./index-BYtEgkrl.js";/**
1
+ import{c as a}from"./index-_2iPl2nX.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/HomePage-t5G7OAGE.js","assets/usePolling-2LO_f1l4.js","assets/TerminalOutput-xGAottmX.js","assets/lock-BtBqgsZ0.js","assets/Badge-iZ84_iz4.js","assets/clock-CasItKBM.js","assets/circle-alert-BeU0GAf7.js","assets/check-CxwV5Bzq.js","assets/package-MkQHuN6g.js","assets/cloud-p2bU6CXv.js","assets/hammer-ukr7gJ35.js","assets/chevron-left--TWMaYeL.js","assets/layers-DZtUCskD.js","assets/mail-rabbO_5W.js","assets/bell-BzaVT-q-.js","assets/file-code-corner-D1Re8J8b.js","assets/ProjectPage-B1Wti2GW.js","assets/Button-DO-Xq3YT.js","assets/file-plus-BuKNP2FZ.js","assets/activity-CmQBMOsV.js","assets/bot-CwK5RJjE.js","assets/loader-circle-BB_MVBmf.js","assets/dollar-sign-22E4a6bP.js","assets/refresh-cw-DEs70a7E.js","assets/globe-3vM1jtqs.js","assets/copy-BD_1Idwb.js","assets/git-commit-horizontal-C4J-dLq2.js","assets/plus-C_Sb_op9.js","assets/trash-2-DuD7ogiq.js","assets/rotate-ccw-DvMVZ3AX.js","assets/trending-down-BYq7V2Q5.js","assets/save-DOEP5ubi.js","assets/trending-up-BeD-iNQC.js","assets/folder-open-DI7rcz5V.js","assets/server-DJBVZTUn.js","assets/ProjectPage-9CEnUXvW.css","assets/ProjectsPage-BDWfVwLK.js","assets/lightbulb-CS390qaD.js","assets/TemplatesPage-BuiIghxK.js","assets/database-DpRtc5nU.js","assets/SettingsPage-DlH1leQV.js","assets/TeamsPage-BbYt_ldg.js","assets/Avatar-Bbw5Q-Wz.js","assets/user-CJc2DWfN.js","assets/AdminPage-DZhVlTXm.js","assets/shield-alert-xdJ97H55.js","assets/SystemSettingsPage-DZLDjoUr.js","assets/MetricsPage-B2zKVyJq.js"])))=>i.map(i=>d[i]);
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/HomePage-CUDTdntY.js","assets/usePolling-ns_dFCVn.js","assets/TerminalOutput-DnESY9zk.js","assets/lock-CEWBb_SL.js","assets/Badge-DeFGfZLB.js","assets/clock-Cn9fFUva.js","assets/circle-alert-DqoLW238.js","assets/check-BQPQjkH4.js","assets/package-DysIuuIJ.js","assets/cloud-COJxbgUu.js","assets/hammer-ZGKvu_xy.js","assets/chevron-left-BVvOVUQ8.js","assets/layers-B40lki5j.js","assets/mail-DimGrYf8.js","assets/bell-BjLe9xXk.js","assets/file-code-corner-BysxoSyu.js","assets/ProjectPage-C3R2wbFt.js","assets/Button-Dg1EkPtN.js","assets/file-plus-Dwi1MqSS.js","assets/activity-COLsZyo1.js","assets/bot-Dz62aBIi.js","assets/loader-circle-womi7Brk.js","assets/dollar-sign-BcmncygQ.js","assets/refresh-cw-X31ig0S6.js","assets/globe-CegT0VaL.js","assets/copy-DOn0hVgy.js","assets/git-commit-horizontal-D85UUfNF.js","assets/plus-DG1hW27_.js","assets/trash-2-ChVunC-C.js","assets/rotate-ccw-CBXooICo.js","assets/trending-down-DgsuOE2t.js","assets/save-DQVrWTjZ.js","assets/trending-up-CZHZsGeN.js","assets/folder-open-WzXNCq2x.js","assets/server-BYAMALfa.js","assets/ProjectPage-9CEnUXvW.css","assets/ProjectsPage-DQr06iBk.js","assets/lightbulb-CFSoqUsV.js","assets/TemplatesPage-DVblWpbO.js","assets/database-Bj3Llvnk.js","assets/SettingsPage-eROlGKB9.js","assets/TeamsPage-DZGoYZnD.js","assets/Avatar-BgcFY2E5.js","assets/user-FQUrWHhF.js","assets/AdminPage-Cwqm_kDg.js","assets/shield-alert-B3G7vLiW.js","assets/SystemSettingsPage-C_rIbgZg.js","assets/MetricsPage-DmM--20B.js"])))=>i.map(i=>d[i]);
2
2
  var F0=Object.defineProperty;var I0=(i,c,r)=>c in i?F0(i,c,{enumerable:!0,configurable:!0,writable:!0,value:r}):i[c]=r;var Ln=(i,c,r)=>I0(i,typeof c!="symbol"?c+"":c,r);(function(){const c=document.createElement("link").relList;if(c&&c.supports&&c.supports("modulepreload"))return;for(const d of document.querySelectorAll('link[rel="modulepreload"]'))o(d);new MutationObserver(d=>{for(const m of d)if(m.type==="childList")for(const p of m.addedNodes)p.tagName==="LINK"&&p.rel==="modulepreload"&&o(p)}).observe(document,{childList:!0,subtree:!0});function r(d){const m={};return d.integrity&&(m.integrity=d.integrity),d.referrerPolicy&&(m.referrerPolicy=d.referrerPolicy),d.crossOrigin==="use-credentials"?m.credentials="include":d.crossOrigin==="anonymous"?m.credentials="omit":m.credentials="same-origin",m}function o(d){if(d.ep)return;d.ep=!0;const m=r(d);fetch(d.href,m)}})();function P0(i){return i&&i.__esModule&&Object.prototype.hasOwnProperty.call(i,"default")?i.default:i}var ks={exports:{}},Bn={};/**
3
3
  * @license React
4
4
  * react-jsx-runtime.production.js
@@ -430,4 +430,4 @@ Reason, Act, Reflect, Verify -- the AI's thinking process. It plans what to do (
430
430
  from { opacity: 0; transform: translateX(100%); }
431
431
  to { opacity: 1; transform: translateX(0); }
432
432
  }
433
- `}),h.jsx("span",{className:`flex-shrink-0 mt-0.5 ${p.icon}`,children:h.jsx(p.IconComponent,{size:18})}),h.jsxs("div",{className:"flex-1 min-w-0",children:[h.jsx("p",{className:"text-sm font-medium text-[#201515] dark:text-[#E8E6E3]",children:o}),d&&h.jsx("p",{className:"text-xs text-[#6B6960] dark:text-[#8A8880] mt-0.5",children:d})]}),h.jsx("button",{onClick:x,className:"flex-shrink-0 text-[#939084] hover:text-[#36342E] dark:hover:text-[#E8E6E3] transition-colors","aria-label":"Dismiss notification",children:h.jsx(ea,{size:14})})]})}function f2({notifications:i,onDismiss:c}){return i.length===0?null:h.jsx("div",{className:"fixed top-4 right-4 z-[9999] flex flex-col gap-2 pointer-events-none","aria-live":"polite",children:i.map(r=>h.jsx(r2,{notification:r,onDismiss:c},r.id))})}const Cm=v.createContext({notify:()=>"",dismiss:()=>{},dismissAll:()=>{}});let d2=0;function h2({children:i}){const[c,r]=v.useState([]),o=v.useCallback(E=>{const x=`notif-${++d2}-${Date.now()}`,y={...E,id:x};if(r(z=>[...z,y]),document.hidden&&"Notification"in window)if(Notification.permission==="granted")try{new Notification(E.title,{body:E.message||""})}catch{}else Notification.permission!=="denied"&&Notification.requestPermission().then(z=>{if(z==="granted")try{new Notification(E.title,{body:E.message||""})}catch{}});return x},[]),d=v.useCallback(E=>{r(x=>x.filter(y=>y.id!==E))},[]),m=v.useCallback(()=>{r([])},[]),p=v.useMemo(()=>({notify:o,dismiss:d,dismissAll:m}),[o,d,m]);return h.jsxs(Cm.Provider,{value:p,children:[i,h.jsx(f2,{notifications:c,onDismiss:d})]})}function O2(){return v.useContext(Cm)}function Xh({children:i}){const{user:c,loading:r,isLocalMode:o}=Sm();return r?h.jsx("div",{className:"h-screen bg-[#FAF9F6] flex items-center justify-center text-[#6B6960] text-sm",children:"Loading..."}):o?h.jsx(h.Fragment,{children:i}):c?h.jsx(h.Fragment,{children:i}):h.jsx(c1,{to:"/login",replace:!0})}function yi({variant:i="text",width:c,height:r,className:o=""}){const d="animate-pulse bg-[#ECEAE3]/60 rounded";if(i==="circle"){const m=c||"2rem";return h.jsx("div",{className:`${d} rounded-full flex-shrink-0 ${o}`,style:{width:m,height:m}})}return i==="block"?h.jsx("div",{className:`${d} rounded-btn ${o}`,style:{width:c||"100%",height:r||"4rem"}}):h.jsx("div",{className:`${d} rounded-btn ${o}`,style:{width:c||"100%",height:r||"0.75rem"}})}function M2(){return h.jsx("div",{className:"p-4 space-y-3",children:[...Array(12)].map((i,c)=>h.jsxs("div",{className:"flex items-center gap-3",children:[h.jsx(yi,{variant:"text",width:"1.5rem",height:"10px",className:"flex-shrink-0 opacity-40"}),h.jsx(yi,{variant:"text",width:`${20+Math.random()*60}%`,height:"10px"})]},c))})}typeof window<"u"&&window.addEventListener("beforeunload",i=>{delete i.returnValue});const m2=v.lazy(()=>bt(()=>import("./HomePage-t5G7OAGE.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]))),y2=v.lazy(()=>bt(()=>import("./ProjectPage-B1Wti2GW.js").then(i=>i.P),__vite__mapDeps([16,2,3,17,8,15,18,5,19,20,7,21,10,22,23,6,24,25,26,27,28,29,30,31,32,12,33,34,35]))),p2=v.lazy(()=>bt(()=>import("./ProjectsPage-BDWfVwLK.js"),__vite__mapDeps([36,17,4,5,6,7,37,32,30,1,23,27,33,25,28]))),v2=v.lazy(()=>bt(()=>import("./TemplatesPage-BuiIghxK.js"),__vite__mapDeps([38,17,1,11,5,37,12,7,8,24,34,20,39,27]))),g2=v.lazy(()=>bt(()=>import("./SettingsPage-DlH1leQV.js"),__vite__mapDeps([40,29,10,9,21,7,6]))),b2=v.lazy(()=>bt(()=>import("./LoginPage-CeQRXV4C.js"),[])),x2=v.lazy(()=>bt(()=>import("./TeamsPage-BbYt_ldg.js"),__vite__mapDeps([41,17,42,13,3,19,27,31,28,43,5,15,18,10]))),S2=v.lazy(()=>bt(()=>import("./AdminPage-DZhVlTXm.js"),__vite__mapDeps([44,17,32,5,42,19,23,24,11,13,7,22,43,39,3,10,45,34]))),E2=v.lazy(()=>bt(()=>import("./SystemSettingsPage-DZLDjoUr.js"),__vite__mapDeps([46,17,27,7,25,23,29,5,28,34,10,14,39,45,31]))),_2=v.lazy(()=>bt(()=>import("./MetricsPage-B2zKVyJq.js"),__vite__mapDeps([47,26,11,15,27,30,5,22,12,32]))),T2=v.lazy(()=>bt(()=>import("./ShowcasePage-DPnh3esb.js"),[])),z2=v.lazy(()=>bt(()=>import("./ComparePage-CMjaGKwJ.js"),[])),N2=v.lazy(()=>bt(()=>import("./NotFoundPage-CxCe17V-.js"),[]));function vt(){return h.jsxs("div",{className:"h-screen bg-[#FAF9F6] flex flex-col items-center justify-center gap-3",children:[h.jsx(yi,{variant:"block",width:"200px",height:"24px"}),h.jsx(yi,{variant:"text",width:"140px",height:"12px",className:"opacity-50"})]})}function C2(){return h.jsx(Ag,{children:h.jsx(h2,{children:h.jsxs(r1,{children:[h.jsx(Pe,{path:"/login",element:h.jsx(v.Suspense,{fallback:h.jsx(vt,{}),children:h.jsx(b2,{})})}),h.jsx(Pe,{path:"/project/:sessionId",element:h.jsx(Xh,{children:h.jsx(v.Suspense,{fallback:h.jsx(vt,{}),children:h.jsx(y2,{})})})}),h.jsxs(Pe,{element:h.jsx(Xh,{children:h.jsx(s2,{})}),children:[h.jsx(Pe,{path:"/",element:h.jsx(v.Suspense,{fallback:h.jsx(vt,{}),children:h.jsx(m2,{})})}),h.jsx(Pe,{path:"/projects",element:h.jsx(v.Suspense,{fallback:h.jsx(vt,{}),children:h.jsx(p2,{})})}),h.jsx(Pe,{path:"/templates",element:h.jsx(v.Suspense,{fallback:h.jsx(vt,{}),children:h.jsx(v2,{})})}),h.jsx(Pe,{path:"/settings",element:h.jsx(v.Suspense,{fallback:h.jsx(vt,{}),children:h.jsx(g2,{})})}),h.jsx(Pe,{path:"/teams",element:h.jsx(v.Suspense,{fallback:h.jsx(vt,{}),children:h.jsx(x2,{})})}),h.jsx(Pe,{path:"/metrics",element:h.jsx(v.Suspense,{fallback:h.jsx(vt,{}),children:h.jsx(_2,{})})}),h.jsx(Pe,{path:"/showcase",element:h.jsx(v.Suspense,{fallback:h.jsx(vt,{}),children:h.jsx(T2,{})})}),h.jsx(Pe,{path:"/compare",element:h.jsx(v.Suspense,{fallback:h.jsx(vt,{}),children:h.jsx(z2,{})})}),h.jsx(Pe,{path:"/admin",element:h.jsx(v.Suspense,{fallback:h.jsx(vt,{}),children:h.jsx(S2,{})})}),h.jsx(Pe,{path:"/admin/settings",element:h.jsx(v.Suspense,{fallback:h.jsx(vt,{}),children:h.jsx(E2,{})})}),h.jsx(Pe,{path:"*",element:h.jsx(v.Suspense,{fallback:h.jsx(vt,{}),children:h.jsx(N2,{})})})]})]})})})}op.createRoot(document.getElementById("root")).render(h.jsx(v.StrictMode,{children:h.jsx(w1,{children:h.jsx(C2,{})})}));export{cm as $,fm as A,dm as B,mm as C,M2 as D,vv as E,pm as F,zv as G,rm as H,Ov as I,yi as J,vm as K,co as L,so as M,A2 as N,Zv as O,gm as P,Sm as Q,oo as R,ag as S,pg as T,gg as U,O2 as V,R2 as W,ea as X,Sv as Y,zg as Z,bt as _,Ba as a,Rv as a0,Dh as b,W as c,rg as d,c2 as e,Eg as f,hm as g,lv as h,mg as i,h as j,fv as k,sv as l,eg as m,Vg as n,Xg as o,iv as p,cg as q,v as r,Gv as s,ro as t,lo as u,ev as v,ug as w,ym as x,bm as y,Kv as z};
433
+ `}),h.jsx("span",{className:`flex-shrink-0 mt-0.5 ${p.icon}`,children:h.jsx(p.IconComponent,{size:18})}),h.jsxs("div",{className:"flex-1 min-w-0",children:[h.jsx("p",{className:"text-sm font-medium text-[#201515] dark:text-[#E8E6E3]",children:o}),d&&h.jsx("p",{className:"text-xs text-[#6B6960] dark:text-[#8A8880] mt-0.5",children:d})]}),h.jsx("button",{onClick:x,className:"flex-shrink-0 text-[#939084] hover:text-[#36342E] dark:hover:text-[#E8E6E3] transition-colors","aria-label":"Dismiss notification",children:h.jsx(ea,{size:14})})]})}function f2({notifications:i,onDismiss:c}){return i.length===0?null:h.jsx("div",{className:"fixed top-4 right-4 z-[9999] flex flex-col gap-2 pointer-events-none","aria-live":"polite",children:i.map(r=>h.jsx(r2,{notification:r,onDismiss:c},r.id))})}const Cm=v.createContext({notify:()=>"",dismiss:()=>{},dismissAll:()=>{}});let d2=0;function h2({children:i}){const[c,r]=v.useState([]),o=v.useCallback(E=>{const x=`notif-${++d2}-${Date.now()}`,y={...E,id:x};if(r(z=>[...z,y]),document.hidden&&"Notification"in window)if(Notification.permission==="granted")try{new Notification(E.title,{body:E.message||""})}catch{}else Notification.permission!=="denied"&&Notification.requestPermission().then(z=>{if(z==="granted")try{new Notification(E.title,{body:E.message||""})}catch{}});return x},[]),d=v.useCallback(E=>{r(x=>x.filter(y=>y.id!==E))},[]),m=v.useCallback(()=>{r([])},[]),p=v.useMemo(()=>({notify:o,dismiss:d,dismissAll:m}),[o,d,m]);return h.jsxs(Cm.Provider,{value:p,children:[i,h.jsx(f2,{notifications:c,onDismiss:d})]})}function O2(){return v.useContext(Cm)}function Xh({children:i}){const{user:c,loading:r,isLocalMode:o}=Sm();return r?h.jsx("div",{className:"h-screen bg-[#FAF9F6] flex items-center justify-center text-[#6B6960] text-sm",children:"Loading..."}):o?h.jsx(h.Fragment,{children:i}):c?h.jsx(h.Fragment,{children:i}):h.jsx(c1,{to:"/login",replace:!0})}function yi({variant:i="text",width:c,height:r,className:o=""}){const d="animate-pulse bg-[#ECEAE3]/60 rounded";if(i==="circle"){const m=c||"2rem";return h.jsx("div",{className:`${d} rounded-full flex-shrink-0 ${o}`,style:{width:m,height:m}})}return i==="block"?h.jsx("div",{className:`${d} rounded-btn ${o}`,style:{width:c||"100%",height:r||"4rem"}}):h.jsx("div",{className:`${d} rounded-btn ${o}`,style:{width:c||"100%",height:r||"0.75rem"}})}function M2(){return h.jsx("div",{className:"p-4 space-y-3",children:[...Array(12)].map((i,c)=>h.jsxs("div",{className:"flex items-center gap-3",children:[h.jsx(yi,{variant:"text",width:"1.5rem",height:"10px",className:"flex-shrink-0 opacity-40"}),h.jsx(yi,{variant:"text",width:`${20+Math.random()*60}%`,height:"10px"})]},c))})}typeof window<"u"&&window.addEventListener("beforeunload",i=>{delete i.returnValue});const m2=v.lazy(()=>bt(()=>import("./HomePage-CUDTdntY.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]))),y2=v.lazy(()=>bt(()=>import("./ProjectPage-C3R2wbFt.js").then(i=>i.P),__vite__mapDeps([16,2,3,17,8,15,18,5,19,20,7,21,10,22,23,6,24,25,26,27,28,29,30,31,32,12,33,34,35]))),p2=v.lazy(()=>bt(()=>import("./ProjectsPage-DQr06iBk.js"),__vite__mapDeps([36,17,4,5,6,7,37,32,30,1,23,27,33,25,28]))),v2=v.lazy(()=>bt(()=>import("./TemplatesPage-DVblWpbO.js"),__vite__mapDeps([38,17,1,11,5,37,12,7,8,24,34,20,39,27]))),g2=v.lazy(()=>bt(()=>import("./SettingsPage-eROlGKB9.js"),__vite__mapDeps([40,29,10,9,21,7,6]))),b2=v.lazy(()=>bt(()=>import("./LoginPage-BobwVXx5.js"),[])),x2=v.lazy(()=>bt(()=>import("./TeamsPage-DZGoYZnD.js"),__vite__mapDeps([41,17,42,13,3,19,27,31,28,43,5,15,18,10]))),S2=v.lazy(()=>bt(()=>import("./AdminPage-Cwqm_kDg.js"),__vite__mapDeps([44,17,32,5,42,19,23,24,11,13,7,22,43,39,3,10,45,34]))),E2=v.lazy(()=>bt(()=>import("./SystemSettingsPage-C_rIbgZg.js"),__vite__mapDeps([46,17,27,7,25,23,29,5,28,34,10,14,39,45,31]))),_2=v.lazy(()=>bt(()=>import("./MetricsPage-DmM--20B.js"),__vite__mapDeps([47,26,11,15,27,30,5,22,12,32]))),T2=v.lazy(()=>bt(()=>import("./ShowcasePage-DEA5tT_R.js"),[])),z2=v.lazy(()=>bt(()=>import("./ComparePage-D-wvMVP2.js"),[])),N2=v.lazy(()=>bt(()=>import("./NotFoundPage-6_gjeogD.js"),[]));function vt(){return h.jsxs("div",{className:"h-screen bg-[#FAF9F6] flex flex-col items-center justify-center gap-3",children:[h.jsx(yi,{variant:"block",width:"200px",height:"24px"}),h.jsx(yi,{variant:"text",width:"140px",height:"12px",className:"opacity-50"})]})}function C2(){return h.jsx(Ag,{children:h.jsx(h2,{children:h.jsxs(r1,{children:[h.jsx(Pe,{path:"/login",element:h.jsx(v.Suspense,{fallback:h.jsx(vt,{}),children:h.jsx(b2,{})})}),h.jsx(Pe,{path:"/project/:sessionId",element:h.jsx(Xh,{children:h.jsx(v.Suspense,{fallback:h.jsx(vt,{}),children:h.jsx(y2,{})})})}),h.jsxs(Pe,{element:h.jsx(Xh,{children:h.jsx(s2,{})}),children:[h.jsx(Pe,{path:"/",element:h.jsx(v.Suspense,{fallback:h.jsx(vt,{}),children:h.jsx(m2,{})})}),h.jsx(Pe,{path:"/projects",element:h.jsx(v.Suspense,{fallback:h.jsx(vt,{}),children:h.jsx(p2,{})})}),h.jsx(Pe,{path:"/templates",element:h.jsx(v.Suspense,{fallback:h.jsx(vt,{}),children:h.jsx(v2,{})})}),h.jsx(Pe,{path:"/settings",element:h.jsx(v.Suspense,{fallback:h.jsx(vt,{}),children:h.jsx(g2,{})})}),h.jsx(Pe,{path:"/teams",element:h.jsx(v.Suspense,{fallback:h.jsx(vt,{}),children:h.jsx(x2,{})})}),h.jsx(Pe,{path:"/metrics",element:h.jsx(v.Suspense,{fallback:h.jsx(vt,{}),children:h.jsx(_2,{})})}),h.jsx(Pe,{path:"/showcase",element:h.jsx(v.Suspense,{fallback:h.jsx(vt,{}),children:h.jsx(T2,{})})}),h.jsx(Pe,{path:"/compare",element:h.jsx(v.Suspense,{fallback:h.jsx(vt,{}),children:h.jsx(z2,{})})}),h.jsx(Pe,{path:"/admin",element:h.jsx(v.Suspense,{fallback:h.jsx(vt,{}),children:h.jsx(S2,{})})}),h.jsx(Pe,{path:"/admin/settings",element:h.jsx(v.Suspense,{fallback:h.jsx(vt,{}),children:h.jsx(E2,{})})}),h.jsx(Pe,{path:"*",element:h.jsx(v.Suspense,{fallback:h.jsx(vt,{}),children:h.jsx(N2,{})})})]})]})})})}op.createRoot(document.getElementById("root")).render(h.jsx(v.StrictMode,{children:h.jsx(w1,{children:h.jsx(C2,{})})}));export{cm as $,fm as A,dm as B,mm as C,M2 as D,vv as E,pm as F,zv as G,rm as H,Ov as I,yi as J,vm as K,co as L,so as M,A2 as N,Zv as O,gm as P,Sm as Q,oo as R,ag as S,pg as T,gg as U,O2 as V,R2 as W,ea as X,Sv as Y,zg as Z,bt as _,Ba as a,Rv as a0,Dh as b,W as c,rg as d,c2 as e,Eg as f,hm as g,lv as h,mg as i,h as j,fv as k,sv as l,eg as m,Vg as n,Xg as o,iv as p,cg as q,v as r,Gv as s,ro as t,lo as u,ev as v,ug as w,ym as x,bm as y,Kv as z};
@@ -1,4 +1,4 @@
1
- import{c as a}from"./index-BYtEgkrl.js";/**
1
+ import{c as a}from"./index-_2iPl2nX.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c}from"./index-BYtEgkrl.js";/**
1
+ import{c}from"./index-_2iPl2nX.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c}from"./index-BYtEgkrl.js";/**
1
+ import{c}from"./index-_2iPl2nX.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c}from"./index-BYtEgkrl.js";/**
1
+ import{c}from"./index-_2iPl2nX.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as e}from"./index-BYtEgkrl.js";/**
1
+ import{c as e}from"./index-_2iPl2nX.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as a}from"./index-BYtEgkrl.js";/**
1
+ import{c as a}from"./index-_2iPl2nX.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as e}from"./index-BYtEgkrl.js";/**
1
+ import{c as e}from"./index-_2iPl2nX.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as e}from"./index-BYtEgkrl.js";/**
1
+ import{c as e}from"./index-_2iPl2nX.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as e}from"./index-BYtEgkrl.js";/**
1
+ import{c as e}from"./index-_2iPl2nX.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as a}from"./index-BYtEgkrl.js";/**
1
+ import{c as a}from"./index-_2iPl2nX.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as e}from"./index-BYtEgkrl.js";/**
1
+ import{c as e}from"./index-_2iPl2nX.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as e}from"./index-BYtEgkrl.js";/**
1
+ import{c as e}from"./index-_2iPl2nX.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as a}from"./index-BYtEgkrl.js";/**
1
+ import{c as a}from"./index-_2iPl2nX.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as n}from"./index-BYtEgkrl.js";/**
1
+ import{c as n}from"./index-_2iPl2nX.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as e}from"./index-BYtEgkrl.js";/**
1
+ import{c as e}from"./index-_2iPl2nX.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1 +1 @@
1
- import{r as e}from"./index-BYtEgkrl.js";function m(s,u=2e3,a=!0){const[c,l]=e.useState(null),[f,o]=e.useState(null),[i,d]=e.useState(!0),r=e.useRef(!0),n=e.useCallback(async()=>{try{const t=await s();r.current&&(l(t),o(null))}catch(t){r.current&&o(t instanceof Error?t.message:"Unknown error")}finally{r.current&&d(!1)}},[s]);return e.useEffect(()=>{if(r.current=!0,!a)return;n();const t=setInterval(n,u);return()=>{r.current=!1,clearInterval(t)}},[n,u,a]),{data:c,error:f,loading:i,refresh:n}}export{m as u};
1
+ import{r as e}from"./index-_2iPl2nX.js";function m(s,u=2e3,a=!0){const[c,l]=e.useState(null),[f,o]=e.useState(null),[i,d]=e.useState(!0),r=e.useRef(!0),n=e.useCallback(async()=>{try{const t=await s();r.current&&(l(t),o(null))}catch(t){r.current&&o(t instanceof Error?t.message:"Unknown error")}finally{r.current&&d(!1)}},[s]);return e.useEffect(()=>{if(r.current=!0,!a)return;n();const t=setInterval(n,u);return()=>{r.current=!1,clearInterval(t)}},[n,u,a]),{data:c,error:f,loading:i,refresh:n}}export{m as u};
@@ -1,4 +1,4 @@
1
- import{c}from"./index-BYtEgkrl.js";/**
1
+ import{c}from"./index-_2iPl2nX.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -8,7 +8,7 @@
8
8
  <link rel="preconnect" href="https://fonts.googleapis.com">
9
9
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
10
10
  <link href="https://fonts.googleapis.com/css2?family=DM+Serif+Display&family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
11
- <script type="module" crossorigin src="/assets/index-BYtEgkrl.js"></script>
11
+ <script type="module" crossorigin src="/assets/index-_2iPl2nX.js"></script>
12
12
  <link rel="stylesheet" crossorigin href="/assets/index-CVM4A1Fw.css">
13
13
  </head>
14
14
  <body class="bg-background text-ink font-sans antialiased">
package/web-app/server.py CHANGED
@@ -144,6 +144,10 @@ class SessionState:
144
144
  self.ws_clients: set[WebSocket] = set()
145
145
  self._reader_task: Optional[asyncio.Task] = None
146
146
  self._lock = asyncio.Lock()
147
+ # Monotonic generation counter: incremented on each new session start so
148
+ # that a stale _read_process_output finally-block from a previous session
149
+ # does not clobber the running flag of the current session.
150
+ self._generation: int = 0
147
151
 
148
152
  async def cleanup(self) -> None:
149
153
  """Cancel reader task and close process pipes."""
@@ -172,6 +176,7 @@ class SessionState:
172
176
  self.start_time = 0
173
177
  self.log_lines = []
174
178
  self.log_lines_total = 0
179
+ # NOTE: self._generation is NOT reset -- it must monotonically increase
175
180
 
176
181
 
177
182
  def _kill_tracked_child_processes() -> None:
@@ -2399,8 +2404,14 @@ async def _broadcast(msg: dict) -> None:
2399
2404
  session.ws_clients.discard(ws)
2400
2405
 
2401
2406
 
2402
- async def _read_process_output() -> None:
2403
- """Background task: read loki stdout/stderr and broadcast lines."""
2407
+ async def _read_process_output(generation: int) -> None:
2408
+ """Background task: read loki stdout/stderr and broadcast lines.
2409
+
2410
+ ``generation`` ties this reader to a specific session start. The finally
2411
+ block only clears ``session.running`` when the generation still matches,
2412
+ preventing a stale reader from a previous session from clobbering the
2413
+ running flag of a newer session (BUG-RACE-001).
2414
+ """
2404
2415
  proc = session.process
2405
2416
  if proc is None or proc.stdout is None:
2406
2417
  return
@@ -2431,10 +2442,18 @@ async def _read_process_output() -> None:
2431
2442
  except Exception:
2432
2443
  logger.error("Process output reader failed", exc_info=True)
2433
2444
  finally:
2434
- # Process ended -- acquire lock before mutating state
2445
+ # Process ended -- acquire lock before mutating state.
2446
+ # Only clear running if this reader still owns the current session;
2447
+ # a newer session may have bumped _generation already (BUG-RACE-001).
2448
+ is_current = False
2435
2449
  async with session._lock:
2436
- session.running = False
2437
- await _broadcast({"type": "session_end", "data": {"message": "Session ended"}})
2450
+ if session._generation == generation:
2451
+ session.running = False
2452
+ is_current = True
2453
+ # Only broadcast session_end for the current session; a stale
2454
+ # reader from a previous session must not signal the UI.
2455
+ if is_current:
2456
+ await _broadcast({"type": "session_end", "data": {"message": "Session ended"}})
2438
2457
 
2439
2458
 
2440
2459
  def _build_file_tree(root: Path, max_depth: int = 8, _depth: int = 0) -> list[dict]:
@@ -2678,11 +2697,19 @@ async def start_session(req: StartRequest) -> JSONResponse:
2678
2697
  session.project_dir = project_dir
2679
2698
  session.start_time = time.time()
2680
2699
 
2700
+ # Bump generation so stale reader tasks from previous sessions
2701
+ # cannot clobber this session's running flag (BUG-RACE-001).
2702
+ session._generation += 1
2703
+ current_gen = session._generation
2704
+
2681
2705
  # Track this PID so loki web stop knows it's ours
2682
2706
  _track_child_pid(proc.pid)
2683
2707
 
2684
- # Start background output reader
2685
- session._reader_task = asyncio.create_task(_read_process_output())
2708
+ # Start background output reader -- pass generation so its finally
2709
+ # block only clears running if it still belongs to the current session.
2710
+ session._reader_task = asyncio.create_task(
2711
+ _read_process_output(current_gen)
2712
+ )
2686
2713
 
2687
2714
  # Start file watcher for the project directory
2688
2715
  file_watcher.start(
@@ -2853,7 +2880,17 @@ async def get_status() -> JSONResponse:
2853
2880
  is_running = session.running
2854
2881
  if session.process and is_running:
2855
2882
  if session.process.poll() is not None:
2856
- is_running = False
2883
+ # BUG-RACE-001: The process has exited, but if the session was
2884
+ # started very recently (within 5 seconds), report "running" with
2885
+ # a "starting" phase so the UI does not flash "stopped" before the
2886
+ # build has had time to initialise. The reader task's finally
2887
+ # block will clear session.running properly once it catches up.
2888
+ elapsed_since_start = time.time() - session.start_time
2889
+ if elapsed_since_start < 5.0:
2890
+ # Keep is_running True -- the reader task hasn't caught up yet
2891
+ pass
2892
+ else:
2893
+ is_running = False
2857
2894
 
2858
2895
  # Try to read .loki state files for richer status
2859
2896
  loki_dir = _loki_dir()
@@ -2930,6 +2967,21 @@ async def get_status() -> JSONResponse:
2930
2967
 
2931
2968
  uptime = time.time() - session.start_time if is_running else 0
2932
2969
 
2970
+ # BUG-RACE-001: If the session is running but no phase has been written
2971
+ # to disk yet (the loki process is still initialising), report a
2972
+ # "starting" phase so the UI shows meaningful feedback instead of "idle".
2973
+ if is_running and phase == "idle" and session.start_time > 0:
2974
+ elapsed_since_start = time.time() - session.start_time
2975
+ if elapsed_since_start < 15.0:
2976
+ phase = "starting"
2977
+
2978
+ # If process has exited, include exit code and last output for debugging
2979
+ exit_code = None
2980
+ last_output = []
2981
+ if session.process and session.process.poll() is not None:
2982
+ exit_code = session.process.returncode
2983
+ last_output = session.log_lines[-20:] if session.log_lines else []
2984
+
2933
2985
  return JSONResponse(content={
2934
2986
  "running": is_running,
2935
2987
  "paused": session.paused,
@@ -2948,6 +3000,8 @@ async def get_status() -> JSONResponse:
2948
3000
  "max_iterations": max_iterations,
2949
3001
  "cost": round(cost_usd, 4),
2950
3002
  "start_time": session.start_time if session.start_time > 0 else 0,
3003
+ "exit_code": exit_code,
3004
+ "last_output": last_output,
2951
3005
  })
2952
3006
 
2953
3007