@flexkit/studio 0.2.32 → 0.2.34

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 (157) hide show
  1. package/dist/activity-nav-button-ZHQOZBCC.js +2 -0
  2. package/dist/{activity-nav-button-E4I4YC3X.js.map → activity-nav-button-ZHQOZBCC.js.map} +1 -1
  3. package/dist/astro.js +1 -1
  4. package/dist/chat-page-7XT4K75G.js +4 -0
  5. package/dist/chat-page-7XT4K75G.js.map +1 -0
  6. package/dist/chunk-2FCVATRT.js +4 -0
  7. package/dist/{chunk-R2O4WC3H.js.map → chunk-2FCVATRT.js.map} +1 -1
  8. package/dist/{chunk-ERCVR23U.js → chunk-36DLIVZF.js} +2 -2
  9. package/dist/{chunk-ERCVR23U.js.map → chunk-36DLIVZF.js.map} +1 -1
  10. package/dist/{chunk-ONB3FWK5.js → chunk-3OBELKJU.js} +2 -2
  11. package/dist/{chunk-ONB3FWK5.js.map → chunk-3OBELKJU.js.map} +1 -1
  12. package/dist/chunk-4ZWQ44NZ.js +2 -0
  13. package/dist/{chunk-2NXQF2F7.js.map → chunk-4ZWQ44NZ.js.map} +1 -1
  14. package/dist/chunk-5JUG4BEF.js +2 -0
  15. package/dist/chunk-5JUG4BEF.js.map +1 -0
  16. package/dist/{chunk-XV7U33XQ.js → chunk-6AJRQSFO.js} +3 -3
  17. package/dist/{chunk-XV7U33XQ.js.map → chunk-6AJRQSFO.js.map} +1 -1
  18. package/dist/chunk-7JA6SI5H.js +2 -0
  19. package/dist/{chunk-5AJXR47U.js.map → chunk-7JA6SI5H.js.map} +1 -1
  20. package/dist/{chunk-SZEGGBOC.js → chunk-A4DPLZZF.js} +2 -2
  21. package/dist/{chunk-SZEGGBOC.js.map → chunk-A4DPLZZF.js.map} +1 -1
  22. package/dist/{chunk-C4XLDODU.js → chunk-C2KPTRYM.js} +3 -1
  23. package/dist/{chunk-GSGPULRL.js → chunk-CHNQZU2P.js} +2 -2
  24. package/dist/{chunk-GSGPULRL.js.map → chunk-CHNQZU2P.js.map} +1 -1
  25. package/dist/chunk-DFBG7PUJ.js +10 -0
  26. package/dist/{chunk-JAPZBEBZ.js.map → chunk-DFBG7PUJ.js.map} +1 -1
  27. package/dist/{chunk-V7C4EHK3.js → chunk-DSLPTDZX.js} +2 -2
  28. package/dist/{chunk-V7C4EHK3.js.map → chunk-DSLPTDZX.js.map} +1 -1
  29. package/dist/{chunk-EMFHKTAV.js → chunk-EUWIIL3X.js} +2 -2
  30. package/dist/{chunk-EMFHKTAV.js.map → chunk-EUWIIL3X.js.map} +1 -1
  31. package/dist/chunk-G5N6HEPW.js +2 -0
  32. package/dist/chunk-G5N6HEPW.js.map +1 -0
  33. package/dist/chunk-HR4QZ5TD.js +3 -0
  34. package/dist/chunk-HR4QZ5TD.js.map +1 -0
  35. package/dist/chunk-KO2JLLUJ.js +2 -0
  36. package/dist/chunk-KO2JLLUJ.js.map +1 -0
  37. package/dist/chunk-MBBE4RND.js +3 -0
  38. package/dist/chunk-MBBE4RND.js.map +1 -0
  39. package/dist/{chunk-USNXQOMJ.js → chunk-N33S7BSG.js} +2 -2
  40. package/dist/{chunk-USNXQOMJ.js.map → chunk-N33S7BSG.js.map} +1 -1
  41. package/dist/{chunk-KN7OJFEX.js → chunk-N52JTYBJ.js} +2 -2
  42. package/dist/{chunk-KN7OJFEX.js.map → chunk-N52JTYBJ.js.map} +1 -1
  43. package/dist/{chunk-KR27GOH6.js → chunk-PC5Z37LT.js} +3 -3
  44. package/dist/{chunk-KR27GOH6.js.map → chunk-PC5Z37LT.js.map} +1 -1
  45. package/dist/{chunk-2NQ2RZ2M.js → chunk-PSECMZJC.js} +3 -3
  46. package/dist/{chunk-2NQ2RZ2M.js.map → chunk-PSECMZJC.js.map} +1 -1
  47. package/dist/chunk-RBGXXVF4.js +7 -0
  48. package/dist/{chunk-NNISUDZX.js.map → chunk-RBGXXVF4.js.map} +1 -1
  49. package/dist/chunk-RULCANNM.js +7 -0
  50. package/dist/chunk-RULCANNM.js.map +1 -0
  51. package/dist/chunk-S7Z6KKIN.js +2 -0
  52. package/dist/chunk-S7Z6KKIN.js.map +1 -0
  53. package/dist/{chunk-AY2RXJWS.js → chunk-U6NFYYTF.js} +2 -2
  54. package/dist/{chunk-AY2RXJWS.js.map → chunk-U6NFYYTF.js.map} +1 -1
  55. package/dist/chunk-VFV44YZB.js +2 -0
  56. package/dist/{chunk-54AXLGAK.js.map → chunk-VFV44YZB.js.map} +1 -1
  57. package/dist/chunk-VRDTHLA3.js +3 -0
  58. package/dist/chunk-VRDTHLA3.js.map +1 -0
  59. package/dist/chunk-WU2KCXBC.js +2 -0
  60. package/dist/{chunk-5LGIALCK.js.map → chunk-WU2KCXBC.js.map} +1 -1
  61. package/dist/chunk-X3SHNHHM.js +2 -0
  62. package/dist/chunk-X3SHNHHM.js.map +1 -0
  63. package/dist/chunk-XYFS6X74.js +2 -0
  64. package/dist/{chunk-JWJJZVP3.js.map → chunk-XYFS6X74.js.map} +1 -1
  65. package/dist/chunk-YC7PBLTK.js +2 -0
  66. package/dist/{chunk-MRHZN4G4.js.map → chunk-YC7PBLTK.js.map} +1 -1
  67. package/dist/electron.js +1 -1
  68. package/dist/{entry-CA2QAEHN.js → entry-APJ4V7PW.js} +2 -2
  69. package/dist/{entry-CA2QAEHN.js.map → entry-APJ4V7PW.js.map} +1 -1
  70. package/dist/index.css +43 -0
  71. package/dist/index.d.ts +10 -1
  72. package/dist/index.js +8 -8
  73. package/dist/index.js.map +1 -1
  74. package/dist/list-7IHDJM54.js +3 -0
  75. package/dist/{list-Q2KAEJ26.js.map → list-7IHDJM54.js.map} +1 -1
  76. package/dist/list-7WFALOUT.js +2 -0
  77. package/dist/{list-UMMVRYVD.js.map → list-7WFALOUT.js.map} +1 -1
  78. package/dist/nextjs.js +1 -1
  79. package/dist/pages-BV3ABSFQ.js +5 -0
  80. package/dist/{pages-KZ66JVNU.js.map → pages-BV3ABSFQ.js.map} +1 -1
  81. package/dist/plugin-pages-OWGJPPWV.js +2 -0
  82. package/dist/{plugin-pages-SR2WSUKZ.js.map → plugin-pages-OWGJPPWV.js.map} +1 -1
  83. package/dist/project-selector-V5N2724B.js +2 -0
  84. package/dist/project-selector-V5N2724B.js.map +1 -0
  85. package/dist/record-links-3P3XSW66.js +2 -0
  86. package/dist/{record-links-3WZGSVFU.js.map → record-links-3P3XSW66.js.map} +1 -1
  87. package/dist/root-F2GTYDJM.js +2 -0
  88. package/dist/{root-6QTQUYK4.js.map → root-F2GTYDJM.js.map} +1 -1
  89. package/dist/root-GBBZ3DX5.js +31 -0
  90. package/dist/{root-7BUVDOMV.js.map → root-GBBZ3DX5.js.map} +1 -1
  91. package/dist/root-J62PBDZ2.js +2 -0
  92. package/dist/{root-2VBLPRG7.js.map → root-J62PBDZ2.js.map} +1 -1
  93. package/dist/root-LYRL7VPN.js +14 -0
  94. package/dist/{root-LFJ5BQSY.js.map → root-LYRL7VPN.js.map} +1 -1
  95. package/dist/root-NIL2UHKS.js +2 -0
  96. package/dist/{root-OXS3QQX6.js.map → root-NIL2UHKS.js.map} +1 -1
  97. package/dist/root-RGZZYETM.js +23 -0
  98. package/dist/{root-FZLKYL5W.js.map → root-RGZZYETM.js.map} +1 -1
  99. package/dist/search-IIGNCQEZ.js +2 -0
  100. package/dist/{search-AZK3Q2KX.js.map → search-IIGNCQEZ.js.map} +1 -1
  101. package/dist/skills-pages-T52MF4DO.js +2 -0
  102. package/dist/{skills-pages-7IYBJ4QI.js.map → skills-pages-T52MF4DO.js.map} +1 -1
  103. package/dist/source-IJAAJDGW.js +2 -0
  104. package/dist/{source-4BP5PJ2N.js.map → source-IJAAJDGW.js.map} +1 -1
  105. package/dist/spec-renderer-Z6GVHLFU.js +2 -0
  106. package/dist/{spec-renderer-3GAVSV52.js.map → spec-renderer-Z6GVHLFU.js.map} +1 -1
  107. package/dist/tanstack-start.js +1 -1
  108. package/dist/ui.js +1 -1
  109. package/dist/user-nav-ZH63YHX7.js +2 -0
  110. package/dist/{user-nav-OWTTAXZS.js.map → user-nav-ZH63YHX7.js.map} +1 -1
  111. package/package.json +2 -2
  112. package/dist/activity-nav-button-E4I4YC3X.js +0 -2
  113. package/dist/chat-page-7UB3BMBF.js +0 -4
  114. package/dist/chat-page-7UB3BMBF.js.map +0 -1
  115. package/dist/chunk-2NXQF2F7.js +0 -2
  116. package/dist/chunk-32ZU4MLE.js +0 -2
  117. package/dist/chunk-32ZU4MLE.js.map +0 -1
  118. package/dist/chunk-54AXLGAK.js +0 -2
  119. package/dist/chunk-5AJXR47U.js +0 -2
  120. package/dist/chunk-5LGIALCK.js +0 -2
  121. package/dist/chunk-6NRQMG26.js +0 -2
  122. package/dist/chunk-6NRQMG26.js.map +0 -1
  123. package/dist/chunk-AKQ6ELDX.js +0 -2
  124. package/dist/chunk-AKQ6ELDX.js.map +0 -1
  125. package/dist/chunk-DGIY4SKN.js +0 -7
  126. package/dist/chunk-DGIY4SKN.js.map +0 -1
  127. package/dist/chunk-HDOIOXMP.js +0 -2
  128. package/dist/chunk-HDOIOXMP.js.map +0 -1
  129. package/dist/chunk-HZOD2HOF.js +0 -3
  130. package/dist/chunk-HZOD2HOF.js.map +0 -1
  131. package/dist/chunk-JAPZBEBZ.js +0 -10
  132. package/dist/chunk-JWJJZVP3.js +0 -2
  133. package/dist/chunk-MRHZN4G4.js +0 -2
  134. package/dist/chunk-NNISUDZX.js +0 -7
  135. package/dist/chunk-O2QMYUPS.js +0 -2
  136. package/dist/chunk-O2QMYUPS.js.map +0 -1
  137. package/dist/chunk-R2O4WC3H.js +0 -4
  138. package/dist/chunk-WPCPL2TQ.js +0 -3
  139. package/dist/chunk-WPCPL2TQ.js.map +0 -1
  140. package/dist/list-Q2KAEJ26.js +0 -3
  141. package/dist/list-UMMVRYVD.js +0 -2
  142. package/dist/pages-KZ66JVNU.js +0 -5
  143. package/dist/plugin-pages-SR2WSUKZ.js +0 -2
  144. package/dist/project-selector-72VM6SUI.js +0 -2
  145. package/dist/project-selector-72VM6SUI.js.map +0 -1
  146. package/dist/record-links-3WZGSVFU.js +0 -2
  147. package/dist/root-2VBLPRG7.js +0 -2
  148. package/dist/root-6QTQUYK4.js +0 -2
  149. package/dist/root-7BUVDOMV.js +0 -31
  150. package/dist/root-FZLKYL5W.js +0 -23
  151. package/dist/root-LFJ5BQSY.js +0 -14
  152. package/dist/root-OXS3QQX6.js +0 -2
  153. package/dist/search-AZK3Q2KX.js +0 -2
  154. package/dist/skills-pages-7IYBJ4QI.js +0 -2
  155. package/dist/source-4BP5PJ2N.js +0 -2
  156. package/dist/spec-renderer-3GAVSV52.js +0 -2
  157. package/dist/user-nav-OWTTAXZS.js +0 -2
@@ -1,2 +1,2 @@
1
- import'./index.css';import {g}from'./chunk-WPCPL2TQ.js';function n(e){return e?e!=="viewer":true}function r(){let[,e]=g();return n(e.user?.role)}export{n as a,r as b};//# sourceMappingURL=chunk-V7C4EHK3.js.map
2
- //# sourceMappingURL=chunk-V7C4EHK3.js.map
1
+ import'./index.css';import {g}from'./chunk-MBBE4RND.js';function n(e){return e?e!=="viewer":true}function r(){let[,e]=g();return n(e.user?.role)}export{n as a,r as b};//# sourceMappingURL=chunk-DSLPTDZX.js.map
2
+ //# sourceMappingURL=chunk-DSLPTDZX.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/permissions.ts"],"names":["canMutateData","role","useCanMutate","auth","useAuth"],"mappings":"wDAWO,SAASA,CAAAA,CAAcC,CAAAA,CAA0C,CACtE,OAAKA,CAAAA,CAIEA,IAAS,QAAA,CAHP,IAIX,CAEO,SAASC,CAAAA,EAAwB,CACtC,GAAM,EAAGC,CAAI,CAAA,CAAIC,CAAAA,EAAQ,CAEzB,OAAOJ,CAAAA,CAAcG,CAAAA,CAAK,IAAA,EAAM,IAAI,CACtC","file":"chunk-V7C4EHK3.js","sourcesContent":["'use client';\n\nimport { useAuth } from '../auth/auth-context';\n\n/**\n * Viewers are read-only: the GraphQL route and the automations API reject\n * their mutations server-side. This helper only mirrors that rule in the UI\n * so restricted actions render as disabled instead of failing on submit.\n * While the role is still unknown (auth loading) actions stay enabled and\n * the server remains the source of truth.\n */\nexport function canMutateData(role: string | null | undefined): boolean {\n if (!role) {\n return true;\n }\n\n return role !== 'viewer';\n}\n\nexport function useCanMutate(): boolean {\n const [, auth] = useAuth();\n\n return canMutateData(auth.user?.role);\n}\n"]}
1
+ {"version":3,"sources":["../src/core/permissions.ts"],"names":["canMutateData","role","useCanMutate","auth","useAuth"],"mappings":"wDAWO,SAASA,CAAAA,CAAcC,CAAAA,CAA0C,CACtE,OAAKA,CAAAA,CAIEA,IAAS,QAAA,CAHP,IAIX,CAEO,SAASC,CAAAA,EAAwB,CACtC,GAAM,EAAGC,CAAI,CAAA,CAAIC,CAAAA,EAAQ,CAEzB,OAAOJ,CAAAA,CAAcG,CAAAA,CAAK,IAAA,EAAM,IAAI,CACtC","file":"chunk-DSLPTDZX.js","sourcesContent":["'use client';\n\nimport { useAuth } from '../auth/auth-context';\n\n/**\n * Viewers are read-only: the GraphQL route and the automations API reject\n * their mutations server-side. This helper only mirrors that rule in the UI\n * so restricted actions render as disabled instead of failing on submit.\n * While the role is still unknown (auth loading) actions stay enabled and\n * the server remains the source of truth.\n */\nexport function canMutateData(role: string | null | undefined): boolean {\n if (!role) {\n return true;\n }\n\n return role !== 'viewer';\n}\n\nexport function useCanMutate(): boolean {\n const [, auth] = useAuth();\n\n return canMutateData(auth.user?.role);\n}\n"]}
@@ -1,2 +1,2 @@
1
- import'./index.css';import {N,R as R$1,S,T,V,W,X,P}from'./chunk-DGIY4SKN.js';import {LibraryIcon,CheckCircle2Icon,LoaderCircleIcon,CircleAlertIcon}from'lucide-react';import {useSearchParams,useLocation,NavLink}from'react-router-dom';import {jsx,jsxs}from'react/jsx-runtime';var f=NavLink,y=[{icon:jsx(LibraryIcon,{className:"fk:size-4",strokeWidth:2}),label:"All documents",status:null},{icon:jsx(CheckCircle2Icon,{className:"fk:size-4",strokeWidth:2}),label:"Ready",status:"ready"},{icon:jsx(LoaderCircleIcon,{className:"fk:size-4",strokeWidth:2}),label:"Indexing",status:"processing"},{icon:jsx(CircleAlertIcon,{className:"fk:size-4",strokeWidth:2}),label:"Failed",status:"failed"}];function I(){let[n]=useSearchParams(),t=n.get("status");return t==="ready"||t==="processing"||t==="failed"?t:void 0}function R(){let{pathname:n}=useLocation(),t=I(),m=/\/knowledge\/?$/.test(n),s=/^(.*\/knowledge)(?:\/|$)/.exec(n)?.[1]??"knowledge";return jsxs(N,{collapsible:"icon",variant:"inset",children:[jsx(R$1,{children:jsxs(S,{children:[jsx(T,{children:"Documents"}),jsx(V,{children:y.map(a=>jsx(W,{children:jsx(X,{asChild:true,isActive:m&&(t??null)===a.status,tooltip:a.label,children:jsxs(f,{end:true,to:a.status?`${s}?status=${a.status}`:s,children:[a.icon,jsx("span",{children:a.label})]})})},a.label))})]})}),jsx(P,{})]})}export{I as a,R as b};//# sourceMappingURL=chunk-EMFHKTAV.js.map
2
- //# sourceMappingURL=chunk-EMFHKTAV.js.map
1
+ import'./index.css';import {L,P,Q,R as R$1,T,U,V,N}from'./chunk-RULCANNM.js';import {LibraryIcon,CheckCircle2Icon,LoaderCircleIcon,CircleAlertIcon}from'lucide-react';import {useSearchParams,useLocation,NavLink}from'react-router-dom';import {jsx,jsxs}from'react/jsx-runtime';var f=NavLink,y=[{icon:jsx(LibraryIcon,{className:"fk:size-4",strokeWidth:2}),label:"All documents",status:null},{icon:jsx(CheckCircle2Icon,{className:"fk:size-4",strokeWidth:2}),label:"Ready",status:"ready"},{icon:jsx(LoaderCircleIcon,{className:"fk:size-4",strokeWidth:2}),label:"Indexing",status:"processing"},{icon:jsx(CircleAlertIcon,{className:"fk:size-4",strokeWidth:2}),label:"Failed",status:"failed"}];function I(){let[n]=useSearchParams(),t=n.get("status");return t==="ready"||t==="processing"||t==="failed"?t:void 0}function R(){let{pathname:n}=useLocation(),t=I(),m=/\/knowledge\/?$/.test(n),s=/^(.*\/knowledge)(?:\/|$)/.exec(n)?.[1]??"knowledge";return jsxs(L,{collapsible:"icon",variant:"inset",children:[jsx(P,{children:jsxs(Q,{children:[jsx(R$1,{children:"Documents"}),jsx(T,{children:y.map(a=>jsx(U,{children:jsx(V,{asChild:true,isActive:m&&(t??null)===a.status,tooltip:a.label,children:jsxs(f,{end:true,to:a.status?`${s}?status=${a.status}`:s,children:[a.icon,jsx("span",{children:a.label})]})})},a.label))})]})}),jsx(N,{})]})}export{I as a,R as b};//# sourceMappingURL=chunk-EUWIIL3X.js.map
2
+ //# sourceMappingURL=chunk-EUWIIL3X.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/apps/knowledge/sidebar.tsx"],"names":["NavLinkCompat","NavLink","FILTERS","jsx","LibraryIcon","CheckCircle2Icon","LoaderCircleIcon","CircleAlertIcon","useKnowledgeStatusFilter","searchParams","useSearchParams","value","KnowledgeSidebar","pathname","useLocation","status","onList","base","jsxs","Sidebar","SidebarContent","SidebarGroup","SidebarGroupLabel","SidebarMenu","filter","SidebarMenuItem","SidebarMenuButton","SidebarRail"],"mappings":"kRAeA,IAAMA,CAAAA,CAAgBC,OAAAA,CAMhBC,CAAAA,CAAwF,CAC5F,CAAE,IAAA,CAAMC,GAAAA,CAACC,WAAAA,CAAA,CAAY,SAAA,CAAU,YAAY,WAAA,CAAa,CAAA,CAAG,CAAA,CAAI,KAAA,CAAO,eAAA,CAAiB,MAAA,CAAQ,IAAK,CAAA,CACpG,CAAE,IAAA,CAAMD,GAAAA,CAACE,gBAAAA,CAAA,CAAiB,UAAU,WAAA,CAAY,WAAA,CAAa,CAAA,CAAG,CAAA,CAAI,KAAA,CAAO,OAAA,CAAS,OAAQ,OAAQ,CAAA,CACpG,CAAE,IAAA,CAAMF,GAAAA,CAACG,gBAAAA,CAAA,CAAiB,SAAA,CAAU,WAAA,CAAY,WAAA,CAAa,CAAA,CAAG,CAAA,CAAI,KAAA,CAAO,WAAY,MAAA,CAAQ,YAAa,CAAA,CAC5G,CAAE,IAAA,CAAMH,GAAAA,CAACI,gBAAA,CAAgB,SAAA,CAAU,WAAA,CAAY,WAAA,CAAa,CAAA,CAAG,CAAA,CAAI,MAAO,QAAA,CAAU,MAAA,CAAQ,QAAS,CACvG,CAAA,CAGO,SAASC,GAA8D,CAC5E,GAAM,CAACC,CAAY,CAAA,CAAIC,eAAAA,GACjBC,CAAAA,CAAQF,CAAAA,CAAa,GAAA,CAAI,QAAQ,CAAA,CAEvC,OAAOE,CAAAA,GAAU,OAAA,EAAWA,CAAAA,GAAU,YAAA,EAAgBA,CAAAA,GAAU,QAAA,CAAWA,CAAAA,CAAQ,MACrF,CAEO,SAASC,CAAAA,EAAgC,CAC9C,GAAM,CAAE,QAAA,CAAAC,CAAS,CAAA,CAAIC,WAAAA,EAAY,CAC3BC,CAAAA,CAASP,CAAAA,EAAyB,CAClCQ,EAAS,iBAAA,CAAkB,IAAA,CAAKH,CAAQ,CAAA,CAExCI,CAAAA,CAAO,0BAAA,CAA2B,KAAKJ,CAAQ,CAAA,GAAI,CAAC,CAAA,EAAK,WAAA,CAE/D,OACEK,KAACC,CAAAA,CAAA,CAAa,WAAA,CAAY,MAAA,CAAO,OAAA,CAAQ,OAAA,CACvC,UAAAhB,GAAAA,CAACiB,GAAAA,CAAA,CACC,QAAA,CAAAF,IAAAA,CAACG,CAAAA,CAAA,CACC,QAAA,CAAA,CAAAlB,GAAAA,CAACmB,CAAAA,CAAA,CAAkB,QAAA,CAAA,WAAA,CAAS,CAAA,CAC5BnB,GAAAA,CAACoB,CAAAA,CAAA,CACE,QAAA,CAAArB,CAAAA,CAAQ,GAAA,CAAKsB,CAAAA,EACZrB,GAAAA,CAACsB,EAAA,CACC,QAAA,CAAAtB,GAAAA,CAACuB,CAAAA,CAAA,CACC,OAAA,CAAO,KACP,QAAA,CAAUV,CAAAA,EAAAA,CAAWD,CAAAA,EAAU,IAAA,IAAUS,CAAAA,CAAO,MAAA,CAChD,QAASA,CAAAA,CAAO,KAAA,CAEhB,QAAA,CAAAN,IAAAA,CAAClB,CAAAA,CAAA,CAAc,IAAG,IAAA,CAAC,EAAA,CAAIwB,CAAAA,CAAO,MAAA,CAAS,CAAA,EAAGP,CAAI,WAAWO,CAAAA,CAAO,MAAM,CAAA,CAAA,CAAKP,CAAAA,CACxE,QAAA,CAAA,CAAAO,CAAAA,CAAO,KACRrB,GAAAA,CAAC,MAAA,CAAA,CAAM,QAAA,CAAAqB,CAAAA,CAAO,KAAA,CAAM,CAAA,CAAA,CACtB,EACF,CAAA,CAAA,CAVoBA,CAAAA,CAAO,KAW7B,CACD,CAAA,CACH,CAAA,CAAA,CACF,CAAA,CACF,CAAA,CACArB,GAAAA,CAACwB,CAAAA,CAAA,EAAY,CAAA,CAAA,CACf,CAEJ","file":"chunk-EMFHKTAV.js","sourcesContent":["import type { JSX } from 'react';\nimport { CheckCircle2Icon, CircleAlertIcon, LibraryIcon, LoaderCircleIcon } from 'lucide-react';\nimport { NavLink, useLocation, useSearchParams } from 'react-router-dom';\nimport {\n SidebarContent,\n SidebarGroup,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarPanel,\n SidebarRail,\n} from '../../ui';\nimport type { KnowledgeSourceStatus } from './knowledge';\n\nconst NavLinkCompat = NavLink as unknown as React.ComponentType<{\n children?: React.ReactNode;\n end?: boolean;\n to: string;\n}>;\n\nconst FILTERS: { icon: JSX.Element; label: string; status: KnowledgeSourceStatus | null }[] = [\n { icon: <LibraryIcon className=\"fk:size-4\" strokeWidth={2} />, label: 'All documents', status: null },\n { icon: <CheckCircle2Icon className=\"fk:size-4\" strokeWidth={2} />, label: 'Ready', status: 'ready' },\n { icon: <LoaderCircleIcon className=\"fk:size-4\" strokeWidth={2} />, label: 'Indexing', status: 'processing' },\n { icon: <CircleAlertIcon className=\"fk:size-4\" strokeWidth={2} />, label: 'Failed', status: 'failed' },\n];\n\n/** The status the list is filtered on, read from `?status=`; anything else means every document. */\nexport function useKnowledgeStatusFilter(): KnowledgeSourceStatus | undefined {\n const [searchParams] = useSearchParams();\n const value = searchParams.get('status');\n\n return value === 'ready' || value === 'processing' || value === 'failed' ? value : undefined;\n}\n\nexport function KnowledgeSidebar(): JSX.Element {\n const { pathname } = useLocation();\n const status = useKnowledgeStatusFilter();\n const onList = /\\/knowledge\\/?$/.test(pathname);\n // Links resolve against the app root whether the list or a document is open.\n const base = /^(.*\\/knowledge)(?:\\/|$)/.exec(pathname)?.[1] ?? 'knowledge';\n\n return (\n <SidebarPanel collapsible=\"icon\" variant=\"inset\">\n <SidebarContent>\n <SidebarGroup>\n <SidebarGroupLabel>Documents</SidebarGroupLabel>\n <SidebarMenu>\n {FILTERS.map((filter) => (\n <SidebarMenuItem key={filter.label}>\n <SidebarMenuButton\n asChild\n isActive={onList && (status ?? null) === filter.status}\n tooltip={filter.label}\n >\n <NavLinkCompat end to={filter.status ? `${base}?status=${filter.status}` : base}>\n {filter.icon}\n <span>{filter.label}</span>\n </NavLinkCompat>\n </SidebarMenuButton>\n </SidebarMenuItem>\n ))}\n </SidebarMenu>\n </SidebarGroup>\n </SidebarContent>\n <SidebarRail />\n </SidebarPanel>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/apps/knowledge/sidebar.tsx"],"names":["NavLinkCompat","NavLink","FILTERS","jsx","LibraryIcon","CheckCircle2Icon","LoaderCircleIcon","CircleAlertIcon","useKnowledgeStatusFilter","searchParams","useSearchParams","value","KnowledgeSidebar","pathname","useLocation","status","onList","base","jsxs","Sidebar","SidebarContent","SidebarGroup","SidebarGroupLabel","SidebarMenu","filter","SidebarMenuItem","SidebarMenuButton","SidebarRail"],"mappings":"kRAeA,IAAMA,CAAAA,CAAgBC,OAAAA,CAMhBC,CAAAA,CAAwF,CAC5F,CAAE,IAAA,CAAMC,GAAAA,CAACC,WAAAA,CAAA,CAAY,SAAA,CAAU,YAAY,WAAA,CAAa,CAAA,CAAG,CAAA,CAAI,KAAA,CAAO,eAAA,CAAiB,MAAA,CAAQ,IAAK,CAAA,CACpG,CAAE,IAAA,CAAMD,GAAAA,CAACE,gBAAAA,CAAA,CAAiB,UAAU,WAAA,CAAY,WAAA,CAAa,CAAA,CAAG,CAAA,CAAI,KAAA,CAAO,OAAA,CAAS,OAAQ,OAAQ,CAAA,CACpG,CAAE,IAAA,CAAMF,GAAAA,CAACG,gBAAAA,CAAA,CAAiB,SAAA,CAAU,WAAA,CAAY,WAAA,CAAa,CAAA,CAAG,CAAA,CAAI,KAAA,CAAO,WAAY,MAAA,CAAQ,YAAa,CAAA,CAC5G,CAAE,IAAA,CAAMH,GAAAA,CAACI,gBAAA,CAAgB,SAAA,CAAU,WAAA,CAAY,WAAA,CAAa,CAAA,CAAG,CAAA,CAAI,MAAO,QAAA,CAAU,MAAA,CAAQ,QAAS,CACvG,CAAA,CAGO,SAASC,GAA8D,CAC5E,GAAM,CAACC,CAAY,CAAA,CAAIC,eAAAA,GACjBC,CAAAA,CAAQF,CAAAA,CAAa,GAAA,CAAI,QAAQ,CAAA,CAEvC,OAAOE,CAAAA,GAAU,OAAA,EAAWA,CAAAA,GAAU,YAAA,EAAgBA,CAAAA,GAAU,QAAA,CAAWA,CAAAA,CAAQ,MACrF,CAEO,SAASC,CAAAA,EAAgC,CAC9C,GAAM,CAAE,QAAA,CAAAC,CAAS,CAAA,CAAIC,WAAAA,EAAY,CAC3BC,CAAAA,CAASP,CAAAA,EAAyB,CAClCQ,EAAS,iBAAA,CAAkB,IAAA,CAAKH,CAAQ,CAAA,CAExCI,CAAAA,CAAO,0BAAA,CAA2B,KAAKJ,CAAQ,CAAA,GAAI,CAAC,CAAA,EAAK,WAAA,CAE/D,OACEK,KAACC,CAAAA,CAAA,CAAa,WAAA,CAAY,MAAA,CAAO,OAAA,CAAQ,OAAA,CACvC,UAAAhB,GAAAA,CAACiB,CAAAA,CAAA,CACC,QAAA,CAAAF,IAAAA,CAACG,CAAAA,CAAA,CACC,QAAA,CAAA,CAAAlB,GAAAA,CAACmB,GAAAA,CAAA,CAAkB,QAAA,CAAA,WAAA,CAAS,CAAA,CAC5BnB,GAAAA,CAACoB,CAAAA,CAAA,CACE,QAAA,CAAArB,CAAAA,CAAQ,GAAA,CAAKsB,CAAAA,EACZrB,GAAAA,CAACsB,EAAA,CACC,QAAA,CAAAtB,GAAAA,CAACuB,CAAAA,CAAA,CACC,OAAA,CAAO,KACP,QAAA,CAAUV,CAAAA,EAAAA,CAAWD,CAAAA,EAAU,IAAA,IAAUS,CAAAA,CAAO,MAAA,CAChD,QAASA,CAAAA,CAAO,KAAA,CAEhB,QAAA,CAAAN,IAAAA,CAAClB,CAAAA,CAAA,CAAc,IAAG,IAAA,CAAC,EAAA,CAAIwB,CAAAA,CAAO,MAAA,CAAS,CAAA,EAAGP,CAAI,WAAWO,CAAAA,CAAO,MAAM,CAAA,CAAA,CAAKP,CAAAA,CACxE,QAAA,CAAA,CAAAO,CAAAA,CAAO,KACRrB,GAAAA,CAAC,MAAA,CAAA,CAAM,QAAA,CAAAqB,CAAAA,CAAO,KAAA,CAAM,CAAA,CAAA,CACtB,EACF,CAAA,CAAA,CAVoBA,CAAAA,CAAO,KAW7B,CACD,CAAA,CACH,CAAA,CAAA,CACF,CAAA,CACF,CAAA,CACArB,GAAAA,CAACwB,CAAAA,CAAA,EAAY,CAAA,CAAA,CACf,CAEJ","file":"chunk-EUWIIL3X.js","sourcesContent":["import type { JSX } from 'react';\nimport { CheckCircle2Icon, CircleAlertIcon, LibraryIcon, LoaderCircleIcon } from 'lucide-react';\nimport { NavLink, useLocation, useSearchParams } from 'react-router-dom';\nimport {\n SidebarContent,\n SidebarGroup,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarPanel,\n SidebarRail,\n} from '../../ui';\nimport type { KnowledgeSourceStatus } from './knowledge';\n\nconst NavLinkCompat = NavLink as unknown as React.ComponentType<{\n children?: React.ReactNode;\n end?: boolean;\n to: string;\n}>;\n\nconst FILTERS: { icon: JSX.Element; label: string; status: KnowledgeSourceStatus | null }[] = [\n { icon: <LibraryIcon className=\"fk:size-4\" strokeWidth={2} />, label: 'All documents', status: null },\n { icon: <CheckCircle2Icon className=\"fk:size-4\" strokeWidth={2} />, label: 'Ready', status: 'ready' },\n { icon: <LoaderCircleIcon className=\"fk:size-4\" strokeWidth={2} />, label: 'Indexing', status: 'processing' },\n { icon: <CircleAlertIcon className=\"fk:size-4\" strokeWidth={2} />, label: 'Failed', status: 'failed' },\n];\n\n/** The status the list is filtered on, read from `?status=`; anything else means every document. */\nexport function useKnowledgeStatusFilter(): KnowledgeSourceStatus | undefined {\n const [searchParams] = useSearchParams();\n const value = searchParams.get('status');\n\n return value === 'ready' || value === 'processing' || value === 'failed' ? value : undefined;\n}\n\nexport function KnowledgeSidebar(): JSX.Element {\n const { pathname } = useLocation();\n const status = useKnowledgeStatusFilter();\n const onList = /\\/knowledge\\/?$/.test(pathname);\n // Links resolve against the app root whether the list or a document is open.\n const base = /^(.*\\/knowledge)(?:\\/|$)/.exec(pathname)?.[1] ?? 'knowledge';\n\n return (\n <SidebarPanel collapsible=\"icon\" variant=\"inset\">\n <SidebarContent>\n <SidebarGroup>\n <SidebarGroupLabel>Documents</SidebarGroupLabel>\n <SidebarMenu>\n {FILTERS.map((filter) => (\n <SidebarMenuItem key={filter.label}>\n <SidebarMenuButton\n asChild\n isActive={onList && (status ?? null) === filter.status}\n tooltip={filter.label}\n >\n <NavLinkCompat end to={filter.status ? `${base}?status=${filter.status}` : base}>\n {filter.icon}\n <span>{filter.label}</span>\n </NavLinkCompat>\n </SidebarMenuButton>\n </SidebarMenuItem>\n ))}\n </SidebarMenu>\n </SidebarGroup>\n </SidebarContent>\n <SidebarRail />\n </SidebarPanel>\n );\n}\n"]}
@@ -0,0 +1,2 @@
1
+ import'./index.css';import {a}from'./chunk-X3SHNHHM.js';import {Label,Switch}from'radix-ui';import {jsx}from'react/jsx-runtime';import {cva}from'class-variance-authority';function m({className:e,...t}){return jsx(Label.Root,{"data-slot":"label",className:a("fk:flex fk:items-center fk:gap-2 fk:text-sm fk:leading-none fk:font-medium fk:select-none fk:group-data-[disabled=true]:pointer-events-none fk:group-data-[disabled=true]:opacity-50 fk:peer-disabled:cursor-not-allowed fk:peer-disabled:opacity-50",e),...t})}function x({className:e,type:t,...i}){return jsx("input",{type:t,"data-slot":"input",className:a("fk:h-9 fk:w-full fk:min-w-0 fk:rounded-md fk:border fk:border-input fk:bg-background fk:px-3 fk:py-1 fk:text-base fk:shadow-xs fk:transition-[color,box-shadow] fk:outline-none fk:selection:bg-primary fk:selection:text-primary-foreground fk:file:inline-flex fk:file:h-7 fk:file:border-0 fk:file:bg-transparent fk:file:text-sm fk:file:font-medium fk:file:text-foreground fk:placeholder:text-muted-foreground fk:disabled:pointer-events-none fk:disabled:cursor-not-allowed fk:disabled:opacity-50 fk:md:text-sm fk:dark:bg-input/30 fk:corner-squircle","fk:focus-visible:border-ring fk:focus-visible:ring-[3px] fk:focus-visible:ring-ring/50","fk:aria-invalid:border-destructive fk:aria-invalid:ring-destructive/20 fk:dark:aria-invalid:ring-destructive/40",e),...i})}function P({className:e,size:t="default",...i}){return jsx(Switch.Root,{"data-slot":"switch","data-size":t,className:a("fk:peer fk:group/switch fk:inline-flex fk:shrink-0 fk:items-center fk:rounded-full fk:border fk:border-transparent fk:shadow-xs fk:transition-all fk:outline-none fk:focus-visible:border-ring fk:focus-visible:ring-[3px] fk:focus-visible:ring-ring/50 fk:disabled:cursor-not-allowed fk:disabled:opacity-50 fk:data-[size=default]:h-5 fk:data-[size=default]:w-8 fk:data-[size=sm]:h-3.5 fk:data-[size=sm]:w-6 fk:data-[state=checked]:bg-success fk:data-[state=unchecked]:bg-input fk:dark:data-[state=unchecked]:bg-input/80 fk:corner-squircle",e),...i,children:jsx(Switch.Thumb,{"data-slot":"switch-thumb",className:a("fk:pointer-events-none fk:block fk:rounded-full fk:bg-white fk:ring-0 fk:transition-transform fk:group-data-[size=default]/switch:size-3.75 fk:group-data-[size=sm]/switch:size-3 fk:data-[state=checked]:translate-x-[calc(100%-2px)] fk:data-[state=unchecked]:translate-x-0.25 fk:dark:data-[state=checked]:bg-white fk:dark:data-[state=unchecked]:bg-white fk:corner-squircle")})})}function q({className:e,...t}){return jsx("textarea",{"data-slot":"textarea",className:a("fk:flex fk:field-sizing-content fk:min-h-16 fk:w-full fk:rounded-md fk:border fk:border-input fk:bg-background fk:px-3 fk:py-2 fk:text-base fk:shadow-xs fk:transition-[color,box-shadow] fk:outline-none fk:placeholder:text-muted-foreground fk:focus-visible:border-ring fk:focus-visible:ring-[3px] fk:focus-visible:ring-ring/50 fk:disabled:cursor-not-allowed fk:disabled:opacity-50 fk:aria-invalid:border-destructive fk:aria-invalid:ring-destructive/20 fk:md:text-sm fk:dark:bg-input/30 fk:dark:aria-invalid:ring-destructive/40 fk:corner-squircle",e),...t})}var c=cva("fk:relative fk:w-full fk:rounded-lg fk:border fk:px-4 fk:py-3 fk:[&>svg~*]:pl-7 fk:[&>svg+div]:translate-y-[-3px] fk:[&>svg]:absolute fk:[&>svg]:left-4 fk:[&>svg]:top-4 fk:[&>svg]:text-foreground fk:corner-squircle",{variants:{variant:{default:"fk:bg-card fk:text-card-foreground",destructive:"fk:border-none fk:text-destructive fk:bg-destructive-foreground fk:[&>svg]:text-destructive"}},defaultVariants:{variant:"default"}});function T({className:e,variant:t,...i}){return jsx("div",{"data-slot":"alert",role:"alert",className:a(c({variant:t}),e),...i})}function D({className:e,...t}){return jsx("div",{"data-slot":"alert-title",className:a("fk:col-start-2 fk:line-clamp-1 fk:min-h-4 fk:font-medium fk:tracking-tight",e),...t})}function I({className:e,...t}){return jsx("div",{"data-slot":"alert-description",className:a("fk:text-sm fk:[&_p]:leading-relaxed",e),...t})}export{m as a,x as b,P as c,q as d,T as e,D as f,I as g};//# sourceMappingURL=chunk-G5N6HEPW.js.map
2
+ //# sourceMappingURL=chunk-G5N6HEPW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/ui/primitives/label.tsx","../src/ui/primitives/input.tsx","../src/ui/primitives/switch.tsx","../src/ui/primitives/textarea.tsx","../src/ui/primitives/alert.tsx"],"names":["Label","className","props","jsx","LabelPrimitive","cn","Input","type","Switch","size","SwitchPrimitive","Textarea","alertVariants","cva","Alert","variant","AlertTitle","AlertDescription"],"mappings":"2KAMA,SAASA,CAAAA,CAAM,CAAE,SAAA,CAAAC,CAAAA,CAAW,GAAGC,CAAM,EAAqD,CACxF,OACEC,GAAAA,CAACC,KAAAA,CAAe,IAAA,CAAf,CACC,WAAA,CAAU,OAAA,CACV,SAAA,CAAWC,CAAAA,CACT,sPAAA,CACAJ,CACF,CAAA,CACC,GAAGC,EACN,CAEJ,CCdA,SAASI,CAAAA,CAAM,CAAE,SAAA,CAAAL,CAAAA,CAAW,IAAA,CAAAM,CAAAA,CAAM,GAAGL,CAAM,CAAA,CAAkC,CAC3E,OACEC,GAAAA,CAAC,OAAA,CAAA,CACC,IAAA,CAAMI,CAAAA,CACN,WAAA,CAAU,OAAA,CACV,SAAA,CAAWF,CAAAA,CACT,kiBAAA,CACA,wFAAA,CACA,iHAAA,CACAJ,CACF,CAAA,CACC,GAAGC,CAAAA,CACN,CAEJ,CCXA,SAASM,CAAAA,CAAO,CACd,SAAA,CAAAP,CAAAA,CACA,IAAA,CAAAQ,CAAAA,CAAO,SAAA,CACP,GAAGP,CACL,CAAA,CAEG,CACD,OACEC,GAAAA,CAACO,MAAAA,CAAgB,IAAA,CAAhB,CACC,WAAA,CAAU,QAAA,CACV,WAAA,CAAWD,EACX,SAAA,CAAWJ,CAAAA,CACT,whBAAA,CACAJ,CACF,CAAA,CACC,GAAGC,CAAAA,CAEJ,QAAA,CAAAC,GAAAA,CAACO,MAAAA,CAAgB,KAAA,CAAhB,CACC,WAAA,CAAU,cAAA,CACV,SAAA,CAAWL,CAAAA,CACT,oXACF,CAAA,CACF,CAAA,CACF,CAEJ,CC5BA,SAASM,CAAAA,CAAS,CAAE,SAAA,CAAAV,CAAAA,CAAW,GAAGC,CAAM,CAAA,CAAqC,CAC3E,OACEC,GAAAA,CAAC,UAAA,CAAA,CACC,WAAA,CAAU,UAAA,CACV,SAAA,CAAWE,CAAAA,CACT,kiBAAA,CACAJ,CACF,CAAA,CACC,GAAGC,CAAAA,CACN,CAEJ,CCVA,IAAMU,CAAAA,CAAgBC,GAAAA,CACpB,wNAAA,CACA,CACE,QAAA,CAAU,CACR,QAAS,CACP,OAAA,CAAW,oCAAA,CACX,WAAA,CAAa,6FACf,CACF,CAAA,CACA,eAAA,CAAiB,CACf,OAAA,CAAS,SACX,CACF,CACF,CAAA,CAEA,SAASC,CAAAA,CAAM,CAAE,SAAA,CAAAb,CAAAA,CAAW,OAAA,CAAAc,CAAAA,CAAS,GAAGb,CAAM,CAAA,CAAqE,CACjH,OAAOC,GAAAA,CAAC,KAAA,CAAA,CAAI,WAAA,CAAU,OAAA,CAAQ,KAAK,OAAA,CAAQ,SAAA,CAAWE,CAAAA,CAAGO,CAAAA,CAAc,CAAE,OAAA,CAAAG,CAAQ,CAAC,CAAA,CAAGd,CAAS,CAAA,CAAI,GAAGC,CAAAA,CAAO,CAC9G,CAEA,SAASc,CAAAA,CAAW,CAAE,SAAA,CAAAf,CAAAA,CAAW,GAAGC,CAAM,CAAA,CAAgC,CACxE,OACEC,GAAAA,CAAC,KAAA,CAAA,CACC,WAAA,CAAU,aAAA,CACV,SAAA,CAAWE,EAAG,4EAAA,CAA8EJ,CAAS,CAAA,CACpG,GAAGC,CAAAA,CACN,CAEJ,CAEA,SAASe,CAAAA,CAAiB,CAAE,SAAA,CAAAhB,CAAAA,CAAW,GAAGC,CAAM,CAAA,CAAgC,CAC9E,OACEC,GAAAA,CAAC,KAAA,CAAA,CAAI,WAAA,CAAU,mBAAA,CAAoB,SAAA,CAAWE,CAAAA,CAAG,qCAAA,CAAuCJ,CAAS,CAAA,CAAI,GAAGC,CAAAA,CAAO,CAEnH","file":"chunk-G5N6HEPW.js","sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { Label as LabelPrimitive } from 'radix-ui';\nimport { cn } from '../lib/utils';\n\nfunction Label({ className, ...props }: React.ComponentProps<typeof LabelPrimitive.Root>) {\n return (\n <LabelPrimitive.Root\n data-slot=\"label\"\n className={cn(\n 'fk:flex fk:items-center fk:gap-2 fk:text-sm fk:leading-none fk:font-medium fk:select-none fk:group-data-[disabled=true]:pointer-events-none fk:group-data-[disabled=true]:opacity-50 fk:peer-disabled:cursor-not-allowed fk:peer-disabled:opacity-50',\n className\n )}\n {...props}\n />\n );\n}\n\nexport { Label };\n","import * as React from 'react';\nimport { cn } from '../lib/utils';\n\nfunction Input({ className, type, ...props }: React.ComponentProps<'input'>) {\n return (\n <input\n type={type}\n data-slot=\"input\"\n className={cn(\n 'fk:h-9 fk:w-full fk:min-w-0 fk:rounded-md fk:border fk:border-input fk:bg-background fk:px-3 fk:py-1 fk:text-base fk:shadow-xs fk:transition-[color,box-shadow] fk:outline-none fk:selection:bg-primary fk:selection:text-primary-foreground fk:file:inline-flex fk:file:h-7 fk:file:border-0 fk:file:bg-transparent fk:file:text-sm fk:file:font-medium fk:file:text-foreground fk:placeholder:text-muted-foreground fk:disabled:pointer-events-none fk:disabled:cursor-not-allowed fk:disabled:opacity-50 fk:md:text-sm fk:dark:bg-input/30 fk:corner-squircle',\n 'fk:focus-visible:border-ring fk:focus-visible:ring-[3px] fk:focus-visible:ring-ring/50',\n 'fk:aria-invalid:border-destructive fk:aria-invalid:ring-destructive/20 fk:dark:aria-invalid:ring-destructive/40',\n className\n )}\n {...props}\n />\n );\n}\n\nexport { Input };\n","'use client';\n\nimport * as React from 'react';\nimport { Switch as SwitchPrimitive } from 'radix-ui';\nimport { cn } from '../lib/utils';\n\nfunction Switch({\n className,\n size = 'default',\n ...props\n}: React.ComponentProps<typeof SwitchPrimitive.Root> & {\n size?: 'sm' | 'default';\n}) {\n return (\n <SwitchPrimitive.Root\n data-slot=\"switch\"\n data-size={size}\n className={cn(\n 'fk:peer fk:group/switch fk:inline-flex fk:shrink-0 fk:items-center fk:rounded-full fk:border fk:border-transparent fk:shadow-xs fk:transition-all fk:outline-none fk:focus-visible:border-ring fk:focus-visible:ring-[3px] fk:focus-visible:ring-ring/50 fk:disabled:cursor-not-allowed fk:disabled:opacity-50 fk:data-[size=default]:h-5 fk:data-[size=default]:w-8 fk:data-[size=sm]:h-3.5 fk:data-[size=sm]:w-6 fk:data-[state=checked]:bg-success fk:data-[state=unchecked]:bg-input fk:dark:data-[state=unchecked]:bg-input/80 fk:corner-squircle',\n className\n )}\n {...props}\n >\n <SwitchPrimitive.Thumb\n data-slot=\"switch-thumb\"\n className={cn(\n 'fk:pointer-events-none fk:block fk:rounded-full fk:bg-white fk:ring-0 fk:transition-transform fk:group-data-[size=default]/switch:size-3.75 fk:group-data-[size=sm]/switch:size-3 fk:data-[state=checked]:translate-x-[calc(100%-2px)] fk:data-[state=unchecked]:translate-x-0.25 fk:dark:data-[state=checked]:bg-white fk:dark:data-[state=unchecked]:bg-white fk:corner-squircle'\n )}\n />\n </SwitchPrimitive.Root>\n );\n}\n\nexport { Switch };\n","import * as React from 'react';\nimport { cn } from '../lib/utils';\n\nfunction Textarea({ className, ...props }: React.ComponentProps<'textarea'>) {\n return (\n <textarea\n data-slot=\"textarea\"\n className={cn(\n 'fk:flex fk:field-sizing-content fk:min-h-16 fk:w-full fk:rounded-md fk:border fk:border-input fk:bg-background fk:px-3 fk:py-2 fk:text-base fk:shadow-xs fk:transition-[color,box-shadow] fk:outline-none fk:placeholder:text-muted-foreground fk:focus-visible:border-ring fk:focus-visible:ring-[3px] fk:focus-visible:ring-ring/50 fk:disabled:cursor-not-allowed fk:disabled:opacity-50 fk:aria-invalid:border-destructive fk:aria-invalid:ring-destructive/20 fk:md:text-sm fk:dark:bg-input/30 fk:dark:aria-invalid:ring-destructive/40 fk:corner-squircle',\n className\n )}\n {...props}\n />\n );\n}\n\nexport { Textarea };\n","import * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../lib/utils';\n\nconst alertVariants = cva(\n 'fk:relative fk:w-full fk:rounded-lg fk:border fk:px-4 fk:py-3 fk:[&>svg~*]:pl-7 fk:[&>svg+div]:translate-y-[-3px] fk:[&>svg]:absolute fk:[&>svg]:left-4 fk:[&>svg]:top-4 fk:[&>svg]:text-foreground fk:corner-squircle',\n {\n variants: {\n variant: {\n 'default': 'fk:bg-card fk:text-card-foreground',\n destructive: 'fk:border-none fk:text-destructive fk:bg-destructive-foreground fk:[&>svg]:text-destructive',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n }\n);\n\nfunction Alert({ className, variant, ...props }: React.ComponentProps<'div'> & VariantProps<typeof alertVariants>) {\n return <div data-slot=\"alert\" role=\"alert\" className={cn(alertVariants({ variant }), className)} {...props} />;\n}\n\nfunction AlertTitle({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"alert-title\"\n className={cn('fk:col-start-2 fk:line-clamp-1 fk:min-h-4 fk:font-medium fk:tracking-tight', className)}\n {...props}\n />\n );\n}\n\nfunction AlertDescription({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div data-slot=\"alert-description\" className={cn('fk:text-sm fk:[&_p]:leading-relaxed', className)} {...props} />\n );\n}\n\nexport { Alert, AlertTitle, AlertDescription };\n"]}
@@ -0,0 +1,3 @@
1
+ import'./index.css';import {d as d$1}from'./chunk-VRDTHLA3.js';import {c}from'./chunk-MBBE4RND.js';import {mutate}from'swr';function i(t){return `/api/flexkit/${t}/starter`}async function d(t,e,a,c="Something went wrong. Please try again."){try{let s=await fetch(t,{method:e,credentials:"same-origin",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)}),r=await s.json().catch(()=>({}));return s.ok?{ok:!0,...r}:{ok:!1,code:r.code??"unknown_error",message:r.error??c}}catch{return {ok:false,code:"network_error",message:"Flexkit is not reachable. Check your connection and try again."}}}function w(t){return d(c.me,"PATCH",{displayName:t})}function b(t,e){return d(i(t),"POST",e)}function g(t){return t?.state==="queued"||t?.state==="deploying"||t?.state==="seeding"}function T(t){return [`I'm setting up Flexkit for my business: ${t.trim()}`,"","Design a schema for it: propose the entities, fields and relationships we need to run it day to day, and market scopes if we sell in more than one market. Keep it practical and complete enough to use from the start. Once the schema is deployed, offer to add a few realistic sample records."].join(`
2
+ `)}var x=["Which variants are running low on stock, and what is already on order?","Why are Orb Pendant Lamps being returned? Look at the returns, reviews and support tickets.","Which products are missing prices, titles or SEO copy in the UK or US?","Show last month\u2019s revenue by market and sales channel.","Which open support tickets need attention today?"],v=["Design a schema for my business. Ask me what you need to know first.","Set up a product catalog with variants, prices per market and stock per warehouse.","Help me import my products from a spreadsheet."];function _(t){let e=t.trim();return e?e.length>48?"Project names can be up to 48 characters.":null:"Give your project a name."}function O(t,e,a){switch(t){case "starter":return {kind:"starter",template:"commerce",sampleData:e};case "describe":return {kind:"describe",description:a};case "empty":return {kind:"empty"}}}var h=2e3,f=300,u=new Set;async function y(t){let e=await fetch(i(t),{credentials:"include"});return e.ok?(await e.json()).starter??"missing":null}function k(t){return t.state==="seeding"||t.state==="completed"}function F({fetchStatus:t,projectId:e,publish:a=r=>mutate(i(e),{starter:r},{revalidate:false}),revalidate:c=d$1,sleep:s=r=>new Promise(o=>setTimeout(o,r))}){if(u.has(e))return;u.add(e);let r=t??(()=>y(e));(async()=>{let o=false;try{for(let l=0;l<f;l+=1){await s(h);let n=null;try{n=await r();}catch{n=null;}if(n==="missing")return;if(n!==null&&(await a(n),!o&&k(n)&&(o=!0,await c(e)),!g(n)))return}}finally{u.delete(e);}})();}export{i as a,d as b,w as c,b as d,g as e,T as f,x as g,v as h,_ as i,O as j,F as k};//# sourceMappingURL=chunk-HR4QZ5TD.js.map
3
+ //# sourceMappingURL=chunk-HR4QZ5TD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/config/onboarding.ts","../src/apps/ai/starter-watch.ts"],"names":["starterPath","projectId","send","url","method","body","fallbackMessage","response","json","saveDisplayName","displayName","userApiPaths","applyStarter","starter","isStarterRunning","status","describeBusinessPrompt","description","COMMERCE_STARTER_PROMPTS","EMPTY_STARTER_PROMPTS","validateProjectName","name","trimmed","toProjectStart","kind","sampleData","POLL_INTERVAL_MS","POLL_LIMIT","watching","fetchStarter","starterSchemaDeployed","watchStarter","fetchStatus","publish","mutate","revalidate","revalidateProjectSchema","sleep","ms","resolve","load","schemaLoaded","attempt"],"mappings":"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","file":"chunk-HR4QZ5TD.js","sourcesContent":["import { userApiPaths } from '../api-paths';\n\n/** Starter templates a new project can begin from; the backend owns their schema and sample data. */\nexport type StarterTemplate = 'commerce';\n\nexport type StarterStatus = {\n template: StarterTemplate;\n sampleData: boolean;\n state: 'queued' | 'deploying' | 'seeding' | 'completed' | 'failed';\n progress?: { done: number; total: number };\n error?: string;\n completedAt?: string;\n};\n\n/** How the user chose to start a new project, carried to its AI chat in the navigation state. */\nexport type ProjectStart =\n | { kind: 'starter'; template: StarterTemplate; sampleData: boolean }\n | { kind: 'describe'; description: string }\n | { kind: 'empty' };\n\n/** Navigation state the onboarding hands the AI chat of a new project. */\nexport type OnboardingNavigationState = { onboardingPrompt?: string };\n\nexport function starterPath(projectId: string): string {\n return `/api/flexkit/${projectId}/starter`;\n}\n\nexport type Failure = { ok: false; code: string; message: string };\n\n/** A JSON request to the hosted BFF, with its failures mapped to a message the UI can show. */\nexport async function send<T>(\n url: string,\n method: 'PATCH' | 'POST',\n body: unknown,\n fallbackMessage = 'Something went wrong. Please try again.'\n): Promise<({ ok: true } & T) | Failure> {\n try {\n const response = await fetch(url, {\n method,\n credentials: 'same-origin',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n });\n const json = (await response.json().catch(() => ({}))) as { code?: string; error?: string } & T;\n\n if (response.ok) {\n return { ok: true, ...json };\n }\n\n return {\n ok: false,\n code: json.code ?? 'unknown_error',\n message: json.error ?? fallbackMessage,\n };\n } catch {\n return {\n ok: false,\n code: 'network_error',\n message: 'Flexkit is not reachable. Check your connection and try again.',\n };\n }\n}\n\n/** Hosted mode: saves the signed-in user's display name. */\nexport function saveDisplayName(displayName: string): Promise<{ ok: true } | Failure> {\n return send(userApiPaths.me, 'PATCH', { displayName });\n}\n\n/** Applies a starter template to a new, empty project; the schema and sample data arrive in the background. */\nexport function applyStarter(\n projectId: string,\n starter: { template: StarterTemplate; sampleData: boolean }\n): Promise<({ ok: true } & { starter: StarterStatus }) | Failure> {\n return send<{ starter: StarterStatus }>(starterPath(projectId), 'POST', starter);\n}\n\nexport function isStarterRunning(status: StarterStatus | null | undefined): boolean {\n return status?.state === 'queued' || status?.state === 'deploying' || status?.state === 'seeding';\n}\n\n/** The first message of a project whose owner described the business instead of picking a template. */\nexport function describeBusinessPrompt(description: string): string {\n return [\n `I'm setting up Flexkit for my business: ${description.trim()}`,\n '',\n 'Design a schema for it: propose the entities, fields and relationships we need to run it day to day, and market scopes if we sell in more than one market. Keep it practical and complete enough to use from the start. Once the schema is deployed, offer to add a few realistic sample records.',\n ].join('\\n');\n}\n\n/** Questions the commerce sample store can answer; each one finds a problem planted in the data. */\nexport const COMMERCE_STARTER_PROMPTS = [\n 'Which variants are running low on stock, and what is already on order?',\n 'Why are Orb Pendant Lamps being returned? Look at the returns, reviews and support tickets.',\n 'Which products are missing prices, titles or SEO copy in the UK or US?',\n 'Show last month’s revenue by market and sales channel.',\n 'Which open support tickets need attention today?',\n] as const;\n\nexport const EMPTY_STARTER_PROMPTS = [\n 'Design a schema for my business. Ask me what you need to know first.',\n 'Set up a product catalog with variants, prices per market and stock per warehouse.',\n 'Help me import my products from a spreadsheet.',\n] as const;\n\n/** Only what the field can tell; the backend owns the character rules and says what it refuses. */\nexport function validateProjectName(name: string): string | null {\n const trimmed = name.trim();\n\n if (!trimmed) {\n return 'Give your project a name.';\n }\n\n if (trimmed.length > 48) {\n return 'Project names can be up to 48 characters.';\n }\n\n return null;\n}\n\n/** The choice on the last step, as sent to the backend and the AI chat. */\nexport function toProjectStart(kind: ProjectStart['kind'], sampleData: boolean, description: string): ProjectStart {\n switch (kind) {\n case 'starter':\n return { kind: 'starter', template: 'commerce', sampleData };\n case 'describe':\n return { kind: 'describe', description };\n case 'empty':\n return { kind: 'empty' };\n }\n}\n","import { mutate } from 'swr';\nimport { isStarterRunning, starterPath, type StarterStatus } from '../../core/config/onboarding';\nimport { revalidateProjectSchema } from '../../core/config/use-project-schemas';\n\nconst POLL_INTERVAL_MS = 2_000;\n/** About ten minutes; a starter usually finishes in two. */\nconst POLL_LIMIT = 300;\nconst watching = new Set<string>();\n\n/** `null` = transient failure (keep polling). */\nexport type StarterFetcher = () => Promise<StarterStatus | null | 'missing'>;\n\nasync function fetchStarter(projectId: string): Promise<StarterStatus | null | 'missing'> {\n const response = await fetch(starterPath(projectId), { credentials: 'include' });\n\n if (!response.ok) {\n return null;\n }\n\n const body = (await response.json()) as { starter?: StarterStatus | null };\n\n return body.starter ?? 'missing';\n}\n\n/** The schema is live once the starter got past its deploy. */\nexport function starterSchemaDeployed(status: StarterStatus): boolean {\n return status.state === 'seeding' || status.state === 'completed';\n}\n\n/**\n * Follows a running starter until it settles, independently of which\n * component started it and of navigation inside the Studio. Shares its\n * results through the SWR cache of `starterPath`, and reloads the project\n * schema once, as soon as the starter's schema is deployed.\n */\nexport function watchStarter({\n fetchStatus,\n projectId,\n publish = (status) => mutate(starterPath(projectId), { starter: status }, { revalidate: false }),\n revalidate = revalidateProjectSchema,\n sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms)),\n}: {\n fetchStatus?: StarterFetcher;\n projectId: string;\n publish?: (_status: StarterStatus) => Promise<unknown>;\n revalidate?: (_projectId: string) => Promise<unknown>;\n sleep?: (_ms: number) => Promise<void>;\n}): void {\n if (watching.has(projectId)) {\n return;\n }\n\n watching.add(projectId);\n\n const load = fetchStatus ?? (() => fetchStarter(projectId));\n\n void (async () => {\n let schemaLoaded = false;\n\n try {\n for (let attempt = 0; attempt < POLL_LIMIT; attempt += 1) {\n await sleep(POLL_INTERVAL_MS);\n\n let status: StarterStatus | null | 'missing' = null;\n\n try {\n status = await load();\n } catch {\n status = null;\n }\n\n if (status === 'missing') {\n return;\n }\n\n if (status === null) {\n continue;\n }\n\n await publish(status);\n\n if (!schemaLoaded && starterSchemaDeployed(status)) {\n schemaLoaded = true;\n await revalidate(projectId);\n }\n\n if (!isStarterRunning(status)) {\n return;\n }\n }\n } finally {\n watching.delete(projectId);\n }\n })();\n}\n"]}
@@ -0,0 +1,2 @@
1
+ import'./index.css';import {c as c$3,i,j,d as d$2,k,f,b as b$1}from'./chunk-HR4QZ5TD.js';import {c as c$4}from'./chunk-MBBE4RND.js';import {e,g,a,b,c as c$1,d as d$1}from'./chunk-G5N6HEPW.js';import {a as a$1,d,c,e as e$1,g as g$1}from'./chunk-S7Z6KKIN.js';import {c as c$2,a as a$2}from'./chunk-X3SHNHHM.js';import {useId,useState}from'react';import {useNavigate}from'react-router-dom';import {ShoppingBag,MessageSquareText,Sparkles,Loader2}from'lucide-react';import ve,{mutate}from'swr';import {jsx,jsxs}from'react/jsx-runtime';function Le(e,t,o=[]){return o.find(n=>n.id===e)?.name??t.find(n=>n.projectId===e)?.title??e}function He(e,t){let o=new Map;for(let n of e){let m=t.find(c=>c.id===n),f=m?.team.id??"",s=o.get(f)??{label:m?.team.name??"",projectIds:[]};s.projectIds.push(n),o.set(f,s);}return o.size<=1?[{label:null,projectIds:e}]:[...o.values()].map(n=>({label:n.label||null,projectIds:n.projectIds}))}var se="Could not create the project. Please try again.";async function ie(e){let t=await b$1(c$4.myProjects,"POST",e,se);return t.ok?!t.project?.id||!t.team?.id?{ok:false,code:"unknown_error",message:se}:{ok:true,project:t.project,team:t.team}:t}function me(e){return e.filter(t=>t.role==="owner")}function de(e){return `/${e}/ai/agent`}var H="hosted-session";async function he(){try{let e=await fetch(c$4.me,{credentials:"same-origin"});return e.status===401?{kind:"anonymous"}:e.ok?{kind:"ready",data:await e.json()}:{kind:"error",message:`Flexkit answered ${String(e.status)} while loading your projects.`}}catch(e){return {kind:"error",message:e instanceof Error?e.message:"Flexkit is not reachable."}}}function xe(e){return e?e.kind==="anonymous"?{status:"anonymous"}:e.kind==="error"?{status:"error",message:e.message}:{status:"ready",projects:e.data.projects,teams:e.data.teams??[],user:e.data.user}:{status:"loading"}}function Ue(){let{data:e}=ve(H,he,{revalidateOnFocus:false,revalidateOnReconnect:false,shouldRetryOnError:false});return xe(e)}function Pe(e,t){if(e?.kind!=="ready"||e.data.projects.some(m=>m.id===t.project.id))return e;let o=e.data.teams??[],n={avatarUrl:null,id:t.project.id,name:t.project.name,readOnly:false,role:"owner",suspended:false,team:t.team};return {kind:"ready",data:{...e.data,projects:[...e.data.projects,n],teams:o.some(m=>m.id===t.team.id)?o:[...o,{...t.team,role:"owner"}]}}}async function F(e){await mutate(H,t=>Pe(t,e),{revalidate:false});}function we(e,t){return e?.kind!=="ready"?e:{kind:"ready",data:{...e.data,user:{...e.data.user,displayName:t}}}}async function ce(e){await mutate(H,t=>we(t,e),{revalidate:false});}function rt({askForName:e$2=false,isFirstProject:t=false,onCancel:o,onCreated:n,teams:m}){let f$1=useNavigate(),s={you:useId(),name:useId(),team:useId(),description:useId(),sample:useId()},c$2=me(m),[E,j$1]=useState(e$2?"you":"project"),[R,ue]=useState(""),[h,fe]=useState(""),[U,pe]=useState(null),x=c$2.some(a=>a.id===U)?U??"":c$2[0]?.id??"",[k$1,P]=useState("starter"),[B,ke]=useState(true),[w,ge]=useState(""),[N,l]=useState(null),[u,g$2]=useState(false),[C,ye]=useState(null);async function be(){let a=R.trim();if(!a){l("Tell us your name.");return}l(null),g$2(true);let p=await c$3(a);if(g$2(false),!p.ok){l(p.message);return}await ce(a),j$1("project");}function Se(){let a=i(h);l(a),a||j$1("start");}async function je(){if(k$1==="describe"&&!w.trim()){l("Describe your business in a sentence or two, or pick another way to start.");return}l(null),g$2(true);let a=C??await ie({name:h.trim(),...x?{teamId:x}:{}});if(!a.ok){l(a.message),g$2(false),a.code==="invalid_name"&&j$1("project");return}ye(a);let p=a.project.id,y=j(k$1,B,w),T={};if(y.kind==="starter"){let $=await d$2(p,{template:y.template,sampleData:y.sampleData});if(!$.ok){l(`${a.project.name} was created, but the starter could not be applied: ${$.message}`),g$2(false);return}k({projectId:p});}else y.kind==="describe"&&(T={onboardingPrompt:f(y.description)});let K=de(p);t?(f$1(K,{state:T}),await F(a)):(await F(a),f$1(K,{state:T})),n?.(p);}let O=N?jsx(e,{variant:"destructive",children:jsx(g,{children:N})}):null;return E==="you"?jsxs(M,{onSubmit:()=>{be();},children:[jsxs("div",{className:"fk:flex fk:flex-col fk:gap-2",children:[jsx(a,{htmlFor:s.you,children:"Your name"}),jsx(b,{autoComplete:"name",autoFocus:true,disabled:u,id:s.you,maxLength:80,onChange:a=>{ue(a.target.value);},placeholder:"e.g. Ann Meyer",value:R}),jsx("p",{className:"fk:text-xs fk:text-muted-foreground",children:"Your teammates see it on changes and comments."})]}),O,jsx(A,{isSubmitting:u,submitLabel:"Continue"})]}):E==="project"?jsxs(M,{onSubmit:Se,children:[jsxs("div",{className:"fk:flex fk:flex-col fk:gap-2",children:[jsx(a,{htmlFor:s.name,children:"Project name"}),jsx(b,{"aria-invalid":N?true:void 0,autoComplete:"off",autoFocus:true,id:s.name,maxLength:48,onChange:a=>{fe(a.target.value);},placeholder:"e.g. Aven Living",value:h}),jsx("p",{className:"fk:text-xs fk:text-muted-foreground",children:"Usually your store or company name. You can change it later."})]}),c$2.length>1?jsxs("div",{className:"fk:flex fk:flex-col fk:gap-2",children:[jsx(a,{htmlFor:s.team,children:"Team"}),jsxs(a$1,{onValueChange:pe,value:x,children:[jsx(d,{id:s.team,children:jsx(c,{})}),jsx(e$1,{children:c$2.map(a=>jsx(g$1,{value:a.id,children:a.name},a.id))})]})]}):null,O,jsx(A,{onCancel:o,submitLabel:"Continue"})]}):jsxs(M,{onSubmit:()=>{je();},children:[jsxs("div",{className:"fk:flex fk:flex-col fk:gap-2",children:[jsx("p",{className:"fk:text-sm fk:font-medium",id:`${s.name}-start`,children:"How do you want to start?"}),jsxs("div",{"aria-labelledby":`${s.name}-start`,className:"fk:flex fk:flex-col fk:gap-2",role:"radiogroup",children:[jsx(D,{checked:k$1==="starter",description:"22 ready-made entities for catalog, inventory, orders, customers and marketing, with EU, UK and US markets.",disabled:u,icon:ShoppingBag,onSelect:()=>{P("starter");},recommended:true,title:"Commerce starter",children:jsxs("div",{className:"fk:flex fk:items-center fk:justify-between fk:gap-3 fk:pt-1",children:[jsx(a,{className:"fk:text-xs fk:font-normal fk:text-muted-foreground",htmlFor:s.sample,children:"Add a sample store (Aven Living) to try things out"}),jsx(c$1,{checked:B,disabled:u,id:s.sample,onCheckedChange:ke})]})}),jsx(D,{checked:k$1==="describe",description:"Tell the agent what you sell and how you work; it proposes a schema for you to review.",disabled:u,icon:MessageSquareText,onSelect:()=>{P("describe");},title:"Describe your business",children:jsx(d$1,{"aria-label":"Your business",autoFocus:true,disabled:u,id:s.description,maxLength:2e3,onChange:a=>{ge(a.target.value);},placeholder:"e.g. We sell handmade ceramics online and to 40 shops in Europe, with seasonal collections.",rows:3,value:w})}),jsx(D,{checked:k$1==="empty",description:"Start with an empty project and build the schema in the chat.",disabled:u,icon:Sparkles,onSelect:()=>{P("empty");},title:"Start from scratch"})]})]}),O,jsx(A,{isSubmitting:u,onBack:C?void 0:()=>{l(null),j$1("project");},submitLabel:C?"Continue":"Create project"})]})}function M({children:e,onSubmit:t}){return jsx("form",{className:"fk:flex fk:w-full fk:flex-col fk:gap-4",onSubmit:o=>{o.preventDefault(),t();},children:e})}function A({isSubmitting:e=false,onBack:t,onCancel:o,submitLabel:n}){let m=t??o;return jsxs("div",{className:"fk:flex fk:justify-end fk:gap-2",children:[m?jsx(c$2,{disabled:e,onClick:m,type:"button",variant:"outline",children:t?"Back":"Cancel"}):null,jsxs(c$2,{className:m?void 0:"fk:w-full",disabled:e,type:"submit",children:[e?jsx(Loader2,{className:"fk:h-4 fk:w-4 fk:animate-spin"}):null,n]})]})}function D({checked:e,children:t,description:o,disabled:n,icon:m,onSelect:f,recommended:s=false,title:c}){return jsxs("div",{className:a$2("fk:rounded-lg fk:border fk:p-3 fk:transition-colors",e?"fk:border-foreground/70 fk:bg-muted/50 fk:ring-1 fk:ring-foreground/20":"fk:border-border fk:hover:bg-muted/30"),children:[jsxs("button",{"aria-checked":e,className:"fk:flex fk:w-full fk:items-start fk:gap-3 fk:text-left fk:disabled:opacity-60",disabled:n,onClick:f,role:"radio",type:"button",children:[jsx(m,{className:"fk:mt-0.5 fk:h-4 fk:w-4 fk:shrink-0 fk:text-muted-foreground"}),jsxs("span",{className:"fk:flex fk:flex-col fk:gap-0.5",children:[jsxs("span",{className:"fk:flex fk:items-center fk:gap-2 fk:text-sm fk:font-medium",children:[c,s?jsx("span",{className:"fk:rounded-full fk:bg-primary/10 fk:px-2 fk:py-0.5 fk:text-[11px] fk:font-medium fk:text-primary",children:"Recommended"}):null]}),jsx("span",{className:"fk:text-xs fk:text-muted-foreground",children:o})]})]}),e&&t?jsx("div",{className:"fk:mt-2 fk:pl-7",children:t}):null]})}export{Le as a,He as b,Ue as c,rt as d};//# sourceMappingURL=chunk-KO2JLLUJ.js.map
2
+ //# sourceMappingURL=chunk-KO2JLLUJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/ui/components/project-label.ts","../src/core/config/create-project.ts","../src/core/config/use-hosted-session.ts","../src/ui/components/new-project-flow.tsx"],"names":["getProjectLabel","projectId","projects","projectSummaries","project","groupProjectIdsByTeam","projectIds","teams","id","summary","key","group","FALLBACK_MESSAGE","createHostedProject","input","outcome","send","userApiPaths","ownedTeams","team","newProjectPath","SESSION_KEY","fetchMe","response","error","toHostedSession","useHostedSession","data","useSWR","withCreatedProject","created","rememberCreatedProject","mutate","current","withDisplayName","displayName","rememberDisplayName","NewProjectFlow","askForName","isFirstProject","onCancel","onCreated","navigate","useNavigate","ids","useId","owned","step","setStep","useState","setDisplayName","name","setName","pickedTeamId","setPickedTeamId","selectedTeamId","startKind","setStartKind","sampleData","setSampleData","description","setDescription","setError","isSubmitting","setIsSubmitting","setCreated","submitName","trimmed","saveDisplayName","submitProjectName","invalid","validateProjectName","createProject","start","toProjectStart","state","applied","applyStarter","watchStarter","describeBusinessPrompt","path","errorAlert","jsx","Alert","AlertDescription","jsxs","StepForm","Label","Input","event","StepActions","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","StartOption","ShoppingBag","Switch","MessageSquareText","Textarea","Sparkles","children","onSubmit","onBack","submitLabel","secondary","Button","Loader2","checked","disabled","Icon","onSelect","recommended","title","cn"],"mappings":"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","file":"chunk-KO2JLLUJ.js","sourcesContent":["import type { ProjectSummary, ProjectUiConfig } from '../../core/config/types';\n\n/** Name of a project: the listed name, else the deployed schema title, else the id. */\nexport function getProjectLabel(\n projectId: string,\n projects: ProjectUiConfig[],\n projectSummaries: ProjectSummary[] = []\n): string {\n return (\n projectSummaries.find((project) => project.id === projectId)?.name ??\n projects.find((project) => project.projectId === projectId)?.title ??\n projectId\n );\n}\n\n/** Groups ids by team when the summaries span more than one team; otherwise a single unnamed group. */\nexport function groupProjectIdsByTeam(\n projectIds: string[],\n projectSummaries: ProjectSummary[]\n): { label: string | null; projectIds: string[] }[] {\n const teams = new Map<string, { label: string; projectIds: string[] }>();\n\n for (const id of projectIds) {\n const summary = projectSummaries.find((project) => project.id === id);\n const key = summary?.team.id ?? '';\n const group = teams.get(key) ?? { label: summary?.team.name ?? '', projectIds: [] };\n group.projectIds.push(id);\n teams.set(key, group);\n }\n\n if (teams.size <= 1) {\n return [{ label: null, projectIds }];\n }\n\n return [...teams.values()].map((group) => ({ label: group.label || null, projectIds: group.projectIds }));\n}\n","import { userApiPaths } from '../api-paths';\nimport { send } from './onboarding';\nimport type { HostedTeam } from './types';\n\n/** What `POST /api/me/projects` answers: the new project and the team it went to (possibly a new personal team). */\nexport type CreatedProject = { project: { id: string; name: string }; team: { id: string; name: string } };\n\nexport type CreateProjectOutcome = ({ ok: true } & CreatedProject) | { ok: false; code: string; message: string };\n\nconst FALLBACK_MESSAGE = 'Could not create the project. Please try again.';\n\n/** Hosted mode: creates a project for the signed-in user (Free plan, user as owner). */\nexport async function createHostedProject(input: { name: string; teamId?: string }): Promise<CreateProjectOutcome> {\n const outcome = await send<Partial<CreatedProject>>(userApiPaths.myProjects, 'POST', input, FALLBACK_MESSAGE);\n\n if (!outcome.ok) {\n return outcome;\n }\n\n if (!outcome.project?.id || !outcome.team?.id) {\n return { ok: false, code: 'unknown_error', message: FALLBACK_MESSAGE };\n }\n\n return { ok: true, project: outcome.project, team: outcome.team };\n}\n\n/** Teams the user may create projects in, in the order `/api/me` lists them (oldest first). */\nexport function ownedTeams(teams: HostedTeam[]): HostedTeam[] {\n return teams.filter((team) => team.role === 'owner');\n}\n\n/**\n * Where a new project opens: the AI chat, which can design its schema. The\n * chat route itself, not `/ai`: that redirect would drop the navigation state\n * carrying the onboarding prompt.\n */\nexport function newProjectPath(projectId: string): string {\n return `/${projectId}/ai/agent`;\n}\n","'use client';\n\nimport useSWR, { mutate } from 'swr';\nimport { userApiPaths } from '../api-paths';\nimport type { CreatedProject } from './create-project';\nimport type { HostedTeam, HostedUser, ProjectSummary } from './types';\n\nexport type HostedSession =\n | { status: 'loading' }\n | { status: 'anonymous' }\n | { status: 'error'; message: string }\n | { status: 'ready'; user: HostedUser; projects: ProjectSummary[]; teams: HostedTeam[] };\n\n/** `teams` is missing from backends older than Studio onboarding. */\ntype MeResponse = { projects: ProjectSummary[]; teams?: HostedTeam[]; user: HostedUser };\n\nconst SESSION_KEY = 'hosted-session';\nexport type MeOutcome =\n | { kind: 'anonymous' }\n | { kind: 'error'; message: string }\n | { kind: 'ready'; data: MeResponse };\n\nasync function fetchMe(): Promise<MeOutcome> {\n try {\n const response = await fetch(userApiPaths.me, { credentials: 'same-origin' });\n\n if (response.status === 401) {\n return { kind: 'anonymous' };\n }\n\n if (!response.ok) {\n return { kind: 'error', message: `Flexkit answered ${String(response.status)} while loading your projects.` };\n }\n\n return { kind: 'ready', data: (await response.json()) as MeResponse };\n } catch (error) {\n return { kind: 'error', message: error instanceof Error ? error.message : 'Flexkit is not reachable.' };\n }\n}\n\nexport function toHostedSession(outcome: MeOutcome | undefined): HostedSession {\n if (!outcome) {\n return { status: 'loading' };\n }\n\n if (outcome.kind === 'anonymous') {\n return { status: 'anonymous' };\n }\n\n if (outcome.kind === 'error') {\n return { status: 'error', message: outcome.message };\n }\n\n return {\n status: 'ready',\n projects: outcome.data.projects,\n teams: outcome.data.teams ?? [],\n user: outcome.data.user,\n };\n}\n\n/**\n * Hosted mode: who is signed in and which projects they can open. Fetched once\n * per page load; `rememberCreatedProject` adds a project the user just created.\n */\nexport function useHostedSession(): HostedSession {\n const { data } = useSWR(SESSION_KEY, fetchMe, {\n revalidateOnFocus: false,\n revalidateOnReconnect: false,\n shouldRetryOnError: false,\n });\n\n return toHostedSession(data);\n}\n\n/** The session with a just-created project (and its team, if new) added; the user owns both. */\nexport function withCreatedProject(outcome: MeOutcome | undefined, created: CreatedProject): MeOutcome | undefined {\n if (outcome?.kind !== 'ready' || outcome.data.projects.some((project) => project.id === created.project.id)) {\n return outcome;\n }\n\n const teams = outcome.data.teams ?? [];\n const project: ProjectSummary = {\n avatarUrl: null,\n id: created.project.id,\n name: created.project.name,\n readOnly: false,\n role: 'owner',\n suspended: false,\n team: created.team,\n };\n\n return {\n kind: 'ready',\n data: {\n ...outcome.data,\n projects: [...outcome.data.projects, project],\n teams: teams.some((team) => team.id === created.team.id) ? teams : [...teams, { ...created.team, role: 'owner' }],\n },\n };\n}\n\n/**\n * Adds a project the user just created to the session, so the Studio can open\n * it at once. No `/api/me` round trip: the create response says everything the\n * session needs, and a failed re-read must not hide a project that exists.\n */\nexport async function rememberCreatedProject(created: CreatedProject): Promise<void> {\n await mutate<MeOutcome>(SESSION_KEY, (current) => withCreatedProject(current, created), { revalidate: false });\n}\n\n/** The session with the signed-in user's new display name. */\nexport function withDisplayName(outcome: MeOutcome | undefined, displayName: string): MeOutcome | undefined {\n if (outcome?.kind !== 'ready') {\n return outcome;\n }\n\n return { kind: 'ready', data: { ...outcome.data, user: { ...outcome.data.user, displayName } } };\n}\n\n/** Shows a display name the user just saved, without re-reading `/api/me`. */\nexport async function rememberDisplayName(displayName: string): Promise<void> {\n await mutate<MeOutcome>(SESSION_KEY, (current) => withDisplayName(current, displayName), { revalidate: false });\n}\n","import { useId, useState, type JSX, type ReactNode } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { Loader2, MessageSquareText, ShoppingBag, Sparkles, type LucideIcon } from 'lucide-react';\nimport { watchStarter } from '../../apps/ai/starter-watch';\nimport {\n createHostedProject,\n newProjectPath,\n ownedTeams,\n type CreateProjectOutcome,\n} from '../../core/config/create-project';\nimport {\n applyStarter,\n describeBusinessPrompt,\n saveDisplayName,\n toProjectStart,\n validateProjectName,\n type OnboardingNavigationState,\n type ProjectStart,\n} from '../../core/config/onboarding';\nimport type { HostedTeam } from '../../core/config/types';\nimport { rememberCreatedProject, rememberDisplayName } from '../../core/config/use-hosted-session';\nimport { cn } from '../lib/utils';\nimport { Alert, AlertDescription } from '../primitives/alert';\nimport { Button } from '../primitives/button';\nimport { Input } from '../primitives/input';\nimport { Label } from '../primitives/label';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../primitives/select';\nimport { Switch } from '../primitives/switch';\nimport { Textarea } from '../primitives/textarea';\n\ntype Step = 'you' | 'project' | 'start';\ntype StartKind = ProjectStart['kind'];\n\n/**\n * Hosted mode: create a project in at most three short steps. Your name (only\n * when the account has none, e.g. an email sign-up), the project name, and how\n * to start: the commerce starter (schema plus an optional sample store), a\n * description the agent turns into a schema, or an empty project. The project\n * then opens in its AI chat.\n */\nexport function NewProjectFlow({\n askForName = false,\n isFirstProject = false,\n onCancel,\n onCreated,\n teams,\n}: {\n /** Ask for the user's own name first. */\n askForName?: boolean;\n /**\n * The user has no project yet, so the Studio shows this at `/`. Leave `/`\n * before the session lists the project: there, `/` redirects to the project\n * root instead of its AI chat.\n */\n isFirstProject?: boolean;\n onCancel?: () => void;\n /** Called with the new project's id once the Studio opened it. */\n onCreated?: (projectId: string) => void;\n teams: HostedTeam[];\n}): JSX.Element {\n const navigate = useNavigate();\n const ids = { you: useId(), name: useId(), team: useId(), description: useId(), sample: useId() };\n const owned = ownedTeams(teams);\n const [step, setStep] = useState<Step>(askForName ? 'you' : 'project');\n const [displayName, setDisplayName] = useState('');\n const [name, setName] = useState('');\n const [pickedTeamId, setPickedTeamId] = useState<string | null>(null);\n // Follow the teams prop: a pick that is no longer owned falls back to the first owned team.\n const selectedTeamId = owned.some((team) => team.id === pickedTeamId) ? (pickedTeamId ?? '') : (owned[0]?.id ?? '');\n const [startKind, setStartKind] = useState<StartKind>('starter');\n const [sampleData, setSampleData] = useState(true);\n const [description, setDescription] = useState('');\n const [error, setError] = useState<string | null>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n // Set once the project exists, so a failed starter is retried on it instead of creating another project.\n const [created, setCreated] = useState<Extract<CreateProjectOutcome, { ok: true }> | null>(null);\n\n async function submitName(): Promise<void> {\n const trimmed = displayName.trim();\n\n if (!trimmed) {\n setError('Tell us your name.');\n\n return;\n }\n\n setError(null);\n setIsSubmitting(true);\n\n const outcome = await saveDisplayName(trimmed);\n\n setIsSubmitting(false);\n\n if (!outcome.ok) {\n setError(outcome.message);\n\n return;\n }\n\n await rememberDisplayName(trimmed);\n setStep('project');\n }\n\n function submitProjectName(): void {\n const invalid = validateProjectName(name);\n\n setError(invalid);\n\n if (!invalid) {\n setStep('start');\n }\n }\n\n async function createProject(): Promise<void> {\n if (startKind === 'describe' && !description.trim()) {\n setError('Describe your business in a sentence or two, or pick another way to start.');\n\n return;\n }\n\n setError(null);\n setIsSubmitting(true);\n\n // No owned team yet: let the backend create the personal team.\n const outcome =\n created ??\n (await createHostedProject({\n name: name.trim(),\n ...(selectedTeamId ? { teamId: selectedTeamId } : {}),\n }));\n\n if (!outcome.ok) {\n setError(outcome.message);\n setIsSubmitting(false);\n\n if (outcome.code === 'invalid_name') {\n setStep('project');\n }\n\n return;\n }\n\n setCreated(outcome);\n\n const projectId = outcome.project.id;\n const start = toProjectStart(startKind, sampleData, description);\n let state: OnboardingNavigationState = {};\n\n if (start.kind === 'starter') {\n const applied = await applyStarter(projectId, { template: start.template, sampleData: start.sampleData });\n\n if (!applied.ok) {\n setError(`${outcome.project.name} was created, but the starter could not be applied: ${applied.message}`);\n setIsSubmitting(false);\n\n return;\n }\n\n watchStarter({ projectId });\n } else if (start.kind === 'describe') {\n state = { onboardingPrompt: describeBusinessPrompt(start.description) };\n }\n\n const path = newProjectPath(projectId);\n\n // Inside a project the Studio only opens ids the session lists, so add it first there.\n if (isFirstProject) {\n navigate(path, { state });\n await rememberCreatedProject(outcome);\n } else {\n await rememberCreatedProject(outcome);\n navigate(path, { state });\n }\n\n onCreated?.(projectId);\n }\n\n const errorAlert = error ? (\n <Alert variant=\"destructive\">\n <AlertDescription>{error}</AlertDescription>\n </Alert>\n ) : null;\n\n if (step === 'you') {\n return (\n <StepForm onSubmit={() => void submitName()}>\n <div className=\"fk:flex fk:flex-col fk:gap-2\">\n <Label htmlFor={ids.you}>Your name</Label>\n <Input\n autoComplete=\"name\"\n autoFocus\n disabled={isSubmitting}\n id={ids.you}\n maxLength={80}\n onChange={(event) => {\n setDisplayName(event.target.value);\n }}\n placeholder=\"e.g. Ann Meyer\"\n value={displayName}\n />\n <p className=\"fk:text-xs fk:text-muted-foreground\">Your teammates see it on changes and comments.</p>\n </div>\n {errorAlert}\n <StepActions isSubmitting={isSubmitting} submitLabel=\"Continue\" />\n </StepForm>\n );\n }\n\n if (step === 'project') {\n return (\n <StepForm onSubmit={submitProjectName}>\n <div className=\"fk:flex fk:flex-col fk:gap-2\">\n <Label htmlFor={ids.name}>Project name</Label>\n <Input\n aria-invalid={error ? true : undefined}\n autoComplete=\"off\"\n autoFocus\n id={ids.name}\n maxLength={48}\n onChange={(event) => {\n setName(event.target.value);\n }}\n placeholder=\"e.g. Aven Living\"\n value={name}\n />\n <p className=\"fk:text-xs fk:text-muted-foreground\">\n Usually your store or company name. You can change it later.\n </p>\n </div>\n {owned.length > 1 ? (\n <div className=\"fk:flex fk:flex-col fk:gap-2\">\n <Label htmlFor={ids.team}>Team</Label>\n <Select onValueChange={setPickedTeamId} value={selectedTeamId}>\n <SelectTrigger id={ids.team}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {owned.map((team) => (\n <SelectItem key={team.id} value={team.id}>\n {team.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n ) : null}\n {errorAlert}\n <StepActions onCancel={onCancel} submitLabel=\"Continue\" />\n </StepForm>\n );\n }\n\n return (\n <StepForm onSubmit={() => void createProject()}>\n <div className=\"fk:flex fk:flex-col fk:gap-2\">\n <p className=\"fk:text-sm fk:font-medium\" id={`${ids.name}-start`}>\n How do you want to start?\n </p>\n <div aria-labelledby={`${ids.name}-start`} className=\"fk:flex fk:flex-col fk:gap-2\" role=\"radiogroup\">\n <StartOption\n checked={startKind === 'starter'}\n description=\"22 ready-made entities for catalog, inventory, orders, customers and marketing, with EU, UK and US markets.\"\n disabled={isSubmitting}\n icon={ShoppingBag}\n onSelect={() => {\n setStartKind('starter');\n }}\n recommended\n title=\"Commerce starter\"\n >\n <div className=\"fk:flex fk:items-center fk:justify-between fk:gap-3 fk:pt-1\">\n <Label className=\"fk:text-xs fk:font-normal fk:text-muted-foreground\" htmlFor={ids.sample}>\n Add a sample store (Aven Living) to try things out\n </Label>\n <Switch checked={sampleData} disabled={isSubmitting} id={ids.sample} onCheckedChange={setSampleData} />\n </div>\n </StartOption>\n <StartOption\n checked={startKind === 'describe'}\n description=\"Tell the agent what you sell and how you work; it proposes a schema for you to review.\"\n disabled={isSubmitting}\n icon={MessageSquareText}\n onSelect={() => {\n setStartKind('describe');\n }}\n title=\"Describe your business\"\n >\n <Textarea\n aria-label=\"Your business\"\n autoFocus\n disabled={isSubmitting}\n id={ids.description}\n maxLength={2000}\n onChange={(event) => {\n setDescription(event.target.value);\n }}\n placeholder=\"e.g. We sell handmade ceramics online and to 40 shops in Europe, with seasonal collections.\"\n rows={3}\n value={description}\n />\n </StartOption>\n <StartOption\n checked={startKind === 'empty'}\n description=\"Start with an empty project and build the schema in the chat.\"\n disabled={isSubmitting}\n icon={Sparkles}\n onSelect={() => {\n setStartKind('empty');\n }}\n title=\"Start from scratch\"\n />\n </div>\n </div>\n {errorAlert}\n <StepActions\n isSubmitting={isSubmitting}\n onBack={\n created\n ? undefined\n : () => {\n setError(null);\n setStep('project');\n }\n }\n submitLabel={created ? 'Continue' : 'Create project'}\n />\n </StepForm>\n );\n}\n\nfunction StepForm({ children, onSubmit }: { children: ReactNode; onSubmit: () => void }): JSX.Element {\n return (\n <form\n className=\"fk:flex fk:w-full fk:flex-col fk:gap-4\"\n onSubmit={(event) => {\n event.preventDefault();\n onSubmit();\n }}\n >\n {children}\n </form>\n );\n}\n\nfunction StepActions({\n isSubmitting = false,\n onBack,\n onCancel,\n submitLabel,\n}: {\n isSubmitting?: boolean;\n onBack?: () => void;\n onCancel?: () => void;\n submitLabel: string;\n}): JSX.Element {\n const secondary = onBack ?? onCancel;\n\n return (\n <div className=\"fk:flex fk:justify-end fk:gap-2\">\n {secondary ? (\n <Button disabled={isSubmitting} onClick={secondary} type=\"button\" variant=\"outline\">\n {onBack ? 'Back' : 'Cancel'}\n </Button>\n ) : null}\n <Button className={secondary ? undefined : 'fk:w-full'} disabled={isSubmitting} type=\"submit\">\n {isSubmitting ? <Loader2 className=\"fk:h-4 fk:w-4 fk:animate-spin\" /> : null}\n {submitLabel}\n </Button>\n </div>\n );\n}\n\nfunction StartOption({\n checked,\n children,\n description,\n disabled,\n icon: Icon,\n onSelect,\n recommended = false,\n title,\n}: {\n checked: boolean;\n children?: ReactNode;\n description: string;\n disabled: boolean;\n icon: LucideIcon;\n onSelect: () => void;\n recommended?: boolean;\n title: string;\n}): JSX.Element {\n return (\n <div\n className={cn(\n 'fk:rounded-lg fk:border fk:p-3 fk:transition-colors',\n checked\n ? 'fk:border-foreground/70 fk:bg-muted/50 fk:ring-1 fk:ring-foreground/20'\n : 'fk:border-border fk:hover:bg-muted/30'\n )}\n >\n <button\n aria-checked={checked}\n className=\"fk:flex fk:w-full fk:items-start fk:gap-3 fk:text-left fk:disabled:opacity-60\"\n disabled={disabled}\n onClick={onSelect}\n role=\"radio\"\n type=\"button\"\n >\n <Icon className=\"fk:mt-0.5 fk:h-4 fk:w-4 fk:shrink-0 fk:text-muted-foreground\" />\n <span className=\"fk:flex fk:flex-col fk:gap-0.5\">\n <span className=\"fk:flex fk:items-center fk:gap-2 fk:text-sm fk:font-medium\">\n {title}\n {recommended ? (\n <span className=\"fk:rounded-full fk:bg-primary/10 fk:px-2 fk:py-0.5 fk:text-[11px] fk:font-medium fk:text-primary\">\n Recommended\n </span>\n ) : null}\n </span>\n <span className=\"fk:text-xs fk:text-muted-foreground\">{description}</span>\n </span>\n </button>\n {checked && children ? <div className=\"fk:mt-2 fk:pl-7\">{children}</div> : null}\n </div>\n );\n}\n"]}
@@ -0,0 +1,3 @@
1
+ import'./index.css';import {c}from'./chunk-5CVDMZUI.js';import {createContext,useContext}from'react';import S from'swr';import {useParams,useHref}from'react-router-dom';import {jsx}from'react/jsx-runtime';var p=c,l=`https://${p}`,n=t=>t?`https://${t}.api.${p}`:l,w=`${l}/images/`,e="-",f={authProviders:`/api/flexkit/${e}/auth/providers`,clientErrors:`/api/flexkit/${e}/client-errors`,logout:`/api/flexkit/${e}/auth/logout`,productEvents:`/api/flexkit/${e}/product-events`,me:`/api/flexkit/${e}/me`,myProjects:`/api/flexkit/${e}/me/projects`,notificationPreferences:`/api/flexkit/${e}/me/notification-preferences`,push:`/api/flexkit/${e}/me/push`,otpConfirm:`/api/flexkit/${e}/auth/otp/confirm`,otpSend:`/api/flexkit/${e}/auth/otp/send`};function a(t=""){return {assets:`/api/flexkit/${t}/assets`,authProviders:`/api/flexkit/${t}/auth/providers`,completion:`/api/flexkit/${t}/completion`,currentUser:`/api/flexkit/${t}/users/me`,loginOtpConfirm:`${n(t)}/auth/otp/confirm`,loginOtpSend:`${n(t)}/auth/otp/send`,logout:i=>{let o=new URLSearchParams({redirect:i});return `/api/flexkit/${t}/auth/logout?${o.toString()}`},schema:`/api/flexkit/${t}/schema`,search:`/api/flexkit/${t}/search`,sessionId:`${n(t)}/api/auth/login/session`}}async function m(t){try{await fetch(f.logout,{credentials:"same-origin",method:"POST"});}catch{}await fetch("/api/flexkit/logout",{credentials:"include",method:"GET"}),window.location.assign(t);}function u(t="projects"){let{projectId:i}=useParams(),o=useHref(`/${i??""}`),s=useHref("/"),{data:g,isLoading:x}=S(i?a(i).currentUser:null,$=>fetch($,{mode:"cors",credentials:"include"}).then(r=>r.json()).then(r=>({...r,spaces:r.spaces??[]})));return [!!i&&x,{user:g,logout:async()=>{if(t==="hosted"){await m(s);return}await fetch(a(i??"").logout(o),{method:"POST",mode:"cors",credentials:"include"}),await fetch("/api/flexkit/logout",{method:"GET",credentials:"include"}),window.location.reload();}}]}var d=createContext([true,{user:null,logout:()=>Promise.resolve()}]);function B({children:t,mode:i="projects"}){let[o,s]=u(i);return jsx(d.Provider,{value:[o,s],children:t})}function J(){return useContext(d)}
2
+ export{l as a,w as b,f as c,a as d,m as e,B as f,J as g};//# sourceMappingURL=chunk-MBBE4RND.js.map
3
+ //# sourceMappingURL=chunk-MBBE4RND.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/api-paths.ts","../src/auth/hosted-logout.ts","../src/auth/use-auth-service.ts","../src/auth/auth-context.tsx"],"names":["domain","flexkitDomain","baseApiUrl","baseProjectApiUrl","projectId","IMAGES_BASE_URL","USER_API_SEGMENT","userApiPaths","apiPaths","redirectPath","params","signOutHosted","rootHref","useAuthService","mode","useParams","projectHref","useHref","user","isLoadingUser","useSWR","url","res","data","AuthContext","createContext","AuthProvider","children","isLoading","auth","jsx","useAuth","useContext"],"mappings":"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","file":"chunk-MBBE4RND.js","sourcesContent":["import { flexkitDomain } from './domains';\n\nconst domain = flexkitDomain;\nexport const baseApiUrl = `https://${domain}`;\nconst baseProjectApiUrl = (projectId?: string): string =>\n projectId ? `https://${projectId}.api.${domain}` : baseApiUrl;\n\ninterface ApiPaths {\n assets: string;\n authProviders: string;\n completion: string;\n currentUser: string;\n loginOtpConfirm: string;\n loginOtpSend: string;\n /** `redirectPath` is the absolute in-app path to return to after logout. */\n logout: (redirectPath: string) => string;\n /** Deployed project schema, scopes, spaces, title and menu groups. */\n schema: string;\n search: string;\n sessionId: string;\n}\n\nexport const IMAGES_BASE_URL = `${baseApiUrl}/images/`;\n\n/**\n * Reserved BFF segment for user-level (project-less) Flexkit API calls:\n * `/api/flexkit/-/me` is proxied to `https://<flexkitDomain>/api/me` with the\n * session as a bearer token. Project ids are ten characters, so `-` can never\n * collide with one.\n */\nexport const USER_API_SEGMENT = '-';\n\nexport const userApiPaths = {\n authProviders: `/api/flexkit/${USER_API_SEGMENT}/auth/providers`,\n /** POST: Studio error reports (see core/error/error-reporter.ts). */\n clientErrors: `/api/flexkit/${USER_API_SEGMENT}/client-errors`,\n logout: `/api/flexkit/${USER_API_SEGMENT}/auth/logout`,\n /** POST: product events only Studio sees (see core/analytics/product-events.ts). */\n productEvents: `/api/flexkit/${USER_API_SEGMENT}/product-events`,\n /** Signed-in user, every project they can open, and their teams. */\n me: `/api/flexkit/${USER_API_SEGMENT}/me`,\n /** POST `{ name, teamId? }`: create a project owned by the signed-in user. */\n myProjects: `/api/flexkit/${USER_API_SEGMENT}/me/projects`,\n /** The signed-in user's notification preferences (desktop kinds, approval email). */\n notificationPreferences: `/api/flexkit/${USER_API_SEGMENT}/me/notification-preferences`,\n /** Web Push: GET the VAPID public key, POST or DELETE this browser's subscription. */\n push: `/api/flexkit/${USER_API_SEGMENT}/me/push`,\n otpConfirm: `/api/flexkit/${USER_API_SEGMENT}/auth/otp/confirm`,\n otpSend: `/api/flexkit/${USER_API_SEGMENT}/auth/otp/send`,\n} as const;\n\nexport function apiPaths(projectId = ''): ApiPaths {\n return {\n assets: `/api/flexkit/${projectId}/assets`,\n authProviders: `/api/flexkit/${projectId}/auth/providers`,\n completion: `/api/flexkit/${projectId}/completion`,\n currentUser: `/api/flexkit/${projectId}/users/me`,\n loginOtpConfirm: `${baseProjectApiUrl(projectId)}/auth/otp/confirm`,\n loginOtpSend: `${baseProjectApiUrl(projectId)}/auth/otp/send`,\n logout: (redirectPath: string) => {\n const params = new URLSearchParams({ redirect: redirectPath });\n\n return `/api/flexkit/${projectId}/auth/logout?${params.toString()}`;\n },\n schema: `/api/flexkit/${projectId}/schema`,\n search: `/api/flexkit/${projectId}/search`,\n sessionId: `${baseProjectApiUrl(projectId)}/api/auth/login/session`,\n };\n}\n","import { userApiPaths } from '../core/api-paths';\n\n/** Hosted mode sign-out: end the Flexkit session, drop the first-party cookie, go back to the Studio root. */\nexport async function signOutHosted(rootHref: string): Promise<void> {\n try {\n await fetch(userApiPaths.logout, { credentials: 'same-origin', method: 'POST' });\n } catch {\n // The cookie is cleared below either way; the session expires server-side.\n }\n\n await fetch('/api/flexkit/logout', { credentials: 'include', method: 'GET' });\n window.location.assign(rootHref);\n}\n","'use client';\n\nimport useSWR from 'swr';\nimport { useHref, useParams } from 'react-router-dom';\nimport { apiPaths } from '../core/api-paths';\nimport type { StudioMode } from '../core/config/types';\nimport { signOutHosted } from './hosted-logout';\nimport type { AuthService, User } from './types';\n\nexport default function useAuthService(mode: StudioMode = 'projects'): AuthService {\n const { projectId } = useParams();\n // Absolute path of the current project under the router basename.\n const projectHref = useHref(`/${projectId ?? ''}`);\n const rootHref = useHref('/');\n // Role and spaces are per project, so there is nothing to ask until a project is open.\n const { data: user, isLoading: isLoadingUser } = useSWR(projectId ? apiPaths(projectId).currentUser : null, (url: string) =>\n fetch(url, { mode: 'cors', credentials: 'include' })\n .then((res) => res.json() as Promise<User>)\n .then((data) => ({ ...data, spaces: data.spaces ?? [] }))\n );\n const isLoading = Boolean(projectId) && isLoadingUser;\n\n return [\n isLoading,\n {\n user,\n logout: async () => {\n if (mode === 'hosted') {\n await signOutHosted(rootHref);\n\n return;\n }\n\n // wipe remote session\n await fetch(apiPaths(projectId ?? '').logout(projectHref), {\n method: 'POST',\n mode: 'cors',\n credentials: 'include',\n });\n\n // delete first-party auth cookie\n await fetch('/api/flexkit/logout', { method: 'GET', credentials: 'include' });\n\n window.location.reload();\n },\n },\n ];\n}\n","'use client';\n\nimport { createContext, JSX, useContext } from 'react';\nimport useAuthService from './use-auth-service';\nimport type { Auth, AuthService, User } from './types';\nimport type { StudioMode } from '../core/config/types';\n\nconst AuthContext = createContext([\n true,\n {\n user: null as User | null,\n logout: () => Promise.resolve(),\n } as Auth,\n]);\n\nexport function AuthProvider({\n children,\n mode = 'projects',\n}: {\n children: React.ReactNode;\n mode?: StudioMode;\n}): JSX.Element {\n const [isLoading, auth] = useAuthService(mode);\n\n return <AuthContext.Provider value={[isLoading, auth]}>{children}</AuthContext.Provider>;\n}\n\nexport function useAuth(): AuthService {\n return useContext(AuthContext) as AuthService;\n}\n"]}
@@ -1,2 +1,2 @@
1
- import'./index.css';import {a}from'./chunk-O2QMYUPS.js';import {Tooltip}from'radix-ui';import {jsx,jsxs}from'react/jsx-runtime';function d({delayDuration:t=0,...e}){return jsx(Tooltip.Provider,{"data-slot":"tooltip-provider",delayDuration:t,...e})}function s({...t}){return jsx(Tooltip.Root,{"data-slot":"tooltip",...t})}function m({...t}){return jsx(Tooltip.Trigger,{"data-slot":"tooltip-trigger",...t})}function k({...t}){return jsx(Tooltip.Portal,{...t})}function c({className:t,sideOffset:e=0,children:n,...a$1}){return jsx(Tooltip.Portal,{children:jsxs(Tooltip.Content,{"data-slot":"tooltip-content",sideOffset:e,className:a("fk:z-50 fk:w-fit fk:origin-(--radix-tooltip-content-transform-origin) fk:animate-in fk:rounded-md fk:bg-foreground fk:px-3 fk:py-1.5 fk:text-xs fk:text-balance fk:text-background fk:fade-in-0 fk:zoom-in-95 fk:data-[side=bottom]:slide-in-from-top-2 fk:data-[side=left]:slide-in-from-right-2 fk:data-[side=right]:slide-in-from-left-2 fk:data-[side=top]:slide-in-from-bottom-2 fk:data-[state=closed]:animate-out fk:data-[state=closed]:fade-out-0 fk:data-[state=closed]:zoom-out-95 fk:corner-squircle",t),...a$1,children:[n,jsx(Tooltip.Arrow,{className:"fk:z-50 fk:size-2.5 fk:translate-y-[calc(-50%-2px)] fk:rotate-45 fk:rounded-[2px] fk:bg-foreground fk:fill-foreground fk:corner-squircle"})]})})}export{d as a,s as b,m as c,k as d,c as e};//# sourceMappingURL=chunk-USNXQOMJ.js.map
2
- //# sourceMappingURL=chunk-USNXQOMJ.js.map
1
+ import'./index.css';import {a}from'./chunk-X3SHNHHM.js';import {Tooltip}from'radix-ui';import {jsx,jsxs}from'react/jsx-runtime';function d({delayDuration:t=0,...e}){return jsx(Tooltip.Provider,{"data-slot":"tooltip-provider",delayDuration:t,...e})}function s({...t}){return jsx(Tooltip.Root,{"data-slot":"tooltip",...t})}function m({...t}){return jsx(Tooltip.Trigger,{"data-slot":"tooltip-trigger",...t})}function k({...t}){return jsx(Tooltip.Portal,{...t})}function c({className:t,sideOffset:e=0,children:n,...a$1}){return jsx(Tooltip.Portal,{children:jsxs(Tooltip.Content,{"data-slot":"tooltip-content",sideOffset:e,className:a("fk:z-50 fk:w-fit fk:origin-(--radix-tooltip-content-transform-origin) fk:animate-in fk:rounded-md fk:bg-foreground fk:px-3 fk:py-1.5 fk:text-xs fk:text-balance fk:text-background fk:fade-in-0 fk:zoom-in-95 fk:data-[side=bottom]:slide-in-from-top-2 fk:data-[side=left]:slide-in-from-right-2 fk:data-[side=right]:slide-in-from-left-2 fk:data-[side=top]:slide-in-from-bottom-2 fk:data-[state=closed]:animate-out fk:data-[state=closed]:fade-out-0 fk:data-[state=closed]:zoom-out-95 fk:corner-squircle",t),...a$1,children:[n,jsx(Tooltip.Arrow,{className:"fk:z-50 fk:size-2.5 fk:translate-y-[calc(-50%-2px)] fk:rotate-45 fk:rounded-[2px] fk:bg-foreground fk:fill-foreground fk:corner-squircle"})]})})}export{d as a,s as b,m as c,k as d,c as e};//# sourceMappingURL=chunk-N33S7BSG.js.map
2
+ //# sourceMappingURL=chunk-N33S7BSG.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/ui/primitives/tooltip.tsx"],"names":["TooltipProvider","delayDuration","props","jsx","TooltipPrimitive","Tooltip","TooltipTrigger","TooltipPortal","TooltipContent","className","sideOffset","children","jsxs","cn"],"mappings":"gIAMA,SAASA,CAAAA,CAAgB,CAAE,aAAA,CAAAC,CAAAA,CAAgB,CAAA,CAAG,GAAGC,CAAM,CAAA,CAA2D,CAChH,OAAOC,GAAAA,CAACC,OAAAA,CAAiB,QAAA,CAAjB,CAA0B,WAAA,CAAU,kBAAA,CAAmB,aAAA,CAAeH,CAAAA,CAAgB,GAAGC,EAAO,CAC1G,CAEA,SAASG,CAAAA,CAAQ,CAAE,GAAGH,CAAM,CAAA,CAAuD,CACjF,OAAOC,GAAAA,CAACC,OAAAA,CAAiB,IAAA,CAAjB,CAAsB,WAAA,CAAU,SAAA,CAAW,GAAGF,CAAAA,CAAO,CAC/D,CAEA,SAASI,CAAAA,CAAe,CAAE,GAAGJ,CAAM,CAAA,CAA0D,CAC3F,OAAOC,GAAAA,CAACC,OAAAA,CAAiB,OAAA,CAAjB,CAAyB,YAAU,iBAAA,CAAmB,GAAGF,CAAAA,CAAO,CAC1E,CAEA,SAASK,CAAAA,CAAc,CAAE,GAAGL,CAAM,CAAA,CAAyD,CACzF,OAAOC,GAAAA,CAACC,OAAAA,CAAiB,MAAA,CAAjB,CAAyB,GAAGF,CAAAA,CAAO,CAC7C,CAEA,SAASM,CAAAA,CAAe,CACtB,SAAA,CAAAC,CAAAA,CACA,UAAA,CAAAC,CAAAA,CAAa,CAAA,CACb,QAAA,CAAAC,CAAAA,CACA,GAAGT,GACL,CAAA,CAA0D,CACxD,OACEC,GAAAA,CAACC,OAAAA,CAAiB,MAAA,CAAjB,CACC,QAAA,CAAAQ,IAAAA,CAACR,OAAAA,CAAiB,OAAA,CAAjB,CACC,WAAA,CAAU,iBAAA,CACV,UAAA,CAAYM,CAAAA,CACZ,SAAA,CAAWG,CAAAA,CACT,kfAAA,CACAJ,CACF,CAAA,CACC,GAAGP,GAAAA,CAEH,QAAA,CAAA,CAAAS,CAAAA,CACDR,GAAAA,CAACC,OAAAA,CAAiB,KAAA,CAAjB,CAAuB,SAAA,CAAU,0IAAA,CAA2I,CAAA,CAAA,CAC/K,EACF,CAEJ","file":"chunk-USNXQOMJ.js","sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { Tooltip as TooltipPrimitive } from 'radix-ui';\nimport { cn } from '../lib/utils';\n\nfunction TooltipProvider({ delayDuration = 0, ...props }: React.ComponentProps<typeof TooltipPrimitive.Provider>) {\n return <TooltipPrimitive.Provider data-slot=\"tooltip-provider\" delayDuration={delayDuration} {...props} />;\n}\n\nfunction Tooltip({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Root>) {\n return <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />;\n}\n\nfunction TooltipTrigger({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />;\n}\n\nfunction TooltipPortal({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Portal>) {\n return <TooltipPrimitive.Portal {...props} />;\n}\n\nfunction TooltipContent({\n className,\n sideOffset = 0,\n children,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Content>) {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n data-slot=\"tooltip-content\"\n sideOffset={sideOffset}\n className={cn(\n 'fk:z-50 fk:w-fit fk:origin-(--radix-tooltip-content-transform-origin) fk:animate-in fk:rounded-md fk:bg-foreground fk:px-3 fk:py-1.5 fk:text-xs fk:text-balance fk:text-background fk:fade-in-0 fk:zoom-in-95 fk:data-[side=bottom]:slide-in-from-top-2 fk:data-[side=left]:slide-in-from-right-2 fk:data-[side=right]:slide-in-from-left-2 fk:data-[side=top]:slide-in-from-bottom-2 fk:data-[state=closed]:animate-out fk:data-[state=closed]:fade-out-0 fk:data-[state=closed]:zoom-out-95 fk:corner-squircle',\n className\n )}\n {...props}\n >\n {children}\n <TooltipPrimitive.Arrow className=\"fk:z-50 fk:size-2.5 fk:translate-y-[calc(-50%-2px)] fk:rotate-45 fk:rounded-[2px] fk:bg-foreground fk:fill-foreground fk:corner-squircle\" />\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n );\n}\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider, TooltipPortal };\n"]}
1
+ {"version":3,"sources":["../src/ui/primitives/tooltip.tsx"],"names":["TooltipProvider","delayDuration","props","jsx","TooltipPrimitive","Tooltip","TooltipTrigger","TooltipPortal","TooltipContent","className","sideOffset","children","jsxs","cn"],"mappings":"gIAMA,SAASA,CAAAA,CAAgB,CAAE,aAAA,CAAAC,CAAAA,CAAgB,CAAA,CAAG,GAAGC,CAAM,CAAA,CAA2D,CAChH,OAAOC,GAAAA,CAACC,OAAAA,CAAiB,QAAA,CAAjB,CAA0B,WAAA,CAAU,kBAAA,CAAmB,aAAA,CAAeH,CAAAA,CAAgB,GAAGC,EAAO,CAC1G,CAEA,SAASG,CAAAA,CAAQ,CAAE,GAAGH,CAAM,CAAA,CAAuD,CACjF,OAAOC,GAAAA,CAACC,OAAAA,CAAiB,IAAA,CAAjB,CAAsB,WAAA,CAAU,SAAA,CAAW,GAAGF,CAAAA,CAAO,CAC/D,CAEA,SAASI,CAAAA,CAAe,CAAE,GAAGJ,CAAM,CAAA,CAA0D,CAC3F,OAAOC,GAAAA,CAACC,OAAAA,CAAiB,OAAA,CAAjB,CAAyB,YAAU,iBAAA,CAAmB,GAAGF,CAAAA,CAAO,CAC1E,CAEA,SAASK,CAAAA,CAAc,CAAE,GAAGL,CAAM,CAAA,CAAyD,CACzF,OAAOC,GAAAA,CAACC,OAAAA,CAAiB,MAAA,CAAjB,CAAyB,GAAGF,CAAAA,CAAO,CAC7C,CAEA,SAASM,CAAAA,CAAe,CACtB,SAAA,CAAAC,CAAAA,CACA,UAAA,CAAAC,CAAAA,CAAa,CAAA,CACb,QAAA,CAAAC,CAAAA,CACA,GAAGT,GACL,CAAA,CAA0D,CACxD,OACEC,GAAAA,CAACC,OAAAA,CAAiB,MAAA,CAAjB,CACC,QAAA,CAAAQ,IAAAA,CAACR,OAAAA,CAAiB,OAAA,CAAjB,CACC,WAAA,CAAU,iBAAA,CACV,UAAA,CAAYM,CAAAA,CACZ,SAAA,CAAWG,CAAAA,CACT,kfAAA,CACAJ,CACF,CAAA,CACC,GAAGP,GAAAA,CAEH,QAAA,CAAA,CAAAS,CAAAA,CACDR,GAAAA,CAACC,OAAAA,CAAiB,KAAA,CAAjB,CAAuB,SAAA,CAAU,0IAAA,CAA2I,CAAA,CAAA,CAC/K,EACF,CAEJ","file":"chunk-N33S7BSG.js","sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { Tooltip as TooltipPrimitive } from 'radix-ui';\nimport { cn } from '../lib/utils';\n\nfunction TooltipProvider({ delayDuration = 0, ...props }: React.ComponentProps<typeof TooltipPrimitive.Provider>) {\n return <TooltipPrimitive.Provider data-slot=\"tooltip-provider\" delayDuration={delayDuration} {...props} />;\n}\n\nfunction Tooltip({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Root>) {\n return <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />;\n}\n\nfunction TooltipTrigger({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />;\n}\n\nfunction TooltipPortal({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Portal>) {\n return <TooltipPrimitive.Portal {...props} />;\n}\n\nfunction TooltipContent({\n className,\n sideOffset = 0,\n children,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Content>) {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n data-slot=\"tooltip-content\"\n sideOffset={sideOffset}\n className={cn(\n 'fk:z-50 fk:w-fit fk:origin-(--radix-tooltip-content-transform-origin) fk:animate-in fk:rounded-md fk:bg-foreground fk:px-3 fk:py-1.5 fk:text-xs fk:text-balance fk:text-background fk:fade-in-0 fk:zoom-in-95 fk:data-[side=bottom]:slide-in-from-top-2 fk:data-[side=left]:slide-in-from-right-2 fk:data-[side=right]:slide-in-from-left-2 fk:data-[side=top]:slide-in-from-bottom-2 fk:data-[state=closed]:animate-out fk:data-[state=closed]:fade-out-0 fk:data-[state=closed]:zoom-out-95 fk:corner-squircle',\n className\n )}\n {...props}\n >\n {children}\n <TooltipPrimitive.Arrow className=\"fk:z-50 fk:size-2.5 fk:translate-y-[calc(-50%-2px)] fk:rotate-45 fk:rounded-[2px] fk:bg-foreground fk:fill-foreground fk:corner-squircle\" />\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n );\n}\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider, TooltipPortal };\n"]}
@@ -1,2 +1,2 @@
1
- import'./index.css';import {c as c$1}from'./chunk-WPCPL2TQ.js';import {b as b$1}from'./chunk-5CVDMZUI.js';import y from'swr';var d="1970-01-01T00:00:00.000Z";function I(t){return t.chatId?`agent/chats/${t.chatId}`:t.automationId&&t.automationRunId?`automations/${t.automationId}/runs/${t.automationRunId}`:null}function b(t){return t.chatId?"View chat":t.automationId&&t.automationRunId?"View run":null}var l={answered:"Answered",approved:"Approved",cancelled:"Cancelled",dismissed:"Dismissed",expired:"Expired",rejected:"Rejected"};function m(t){return t.kind==="automation_failure"?"Failed":t.kind==="automation_result"?"Result":t.kind==="monitor_event"?"Monitor":t.resolution?l[t.resolution]:!t.requiresAction||t.state==="done"||t.state==="dismissed"?null:t.kind==="question"?"Needs answer":"Needs approval"}function w(t){return t.kind==="automation_failure"?"failure":p(t)?"attention":"neutral"}function p(t){return t.requiresAction&&t.resolvedAt===null&&t.state!=="dismissed"&&t.state!=="done"}function N({mutedKinds:t=[],newItems:n,since:e}){let i=n.reduce((o,u)=>o===null||u.createdAt>o?u.createdAt:o,null);if(e===null)return {notifications:[],since:i??d};let r=n.filter(o=>o.createdAt>e&&!t.includes(o.kind)),s=i!==null&&i>e?i:e;return r.length===0?{notifications:[],since:s}:r.length>3?{notifications:[{body:"Open Activity in Flexkit Studio to review them.",path:"activity",tag:`flexkit-activity-batch:${s}`,title:`${r.length.toString()} new items in Activity`}],since:s}:{notifications:r.map(o=>({body:o.body??"",path:`activity/${encodeURIComponent(o.id)}`,tag:`flexkit-activity:${o.id}`,title:o.title})),since:s}}var A={approvalEmail:true,desktopMutedKinds:[]};async function c(t,n){let e=await fetch(t,{credentials:"same-origin",...n,headers:{"Content-Type":"application/json",...n?.headers}});if(!e.ok)throw new Error(`Request failed with ${e.status.toString()}.`);return await e.json()}function k(){let{data:t,error:n,mutate:e}=y(c$1.notificationPreferences,i=>c(i));return {isLoaded:t!==void 0||n!==void 0,mutate:e,preferences:t?.preferences??A}}function R(t){return c(c$1.notificationPreferences,{body:JSON.stringify(t),method:"PUT"})}function g(){return typeof window<"u"&&b$1()===void 0&&typeof Notification<"u"&&"serviceWorker"in navigator&&"PushManager"in window}function v(t){let n=`${t}${"=".repeat((4-t.length%4)%4)}`.replace(/-/g,"+").replace(/_/g,"/"),e=atob(n),i=new Uint8Array(new ArrayBuffer(e.length));for(let r=0;r<e.length;r+=1)i[r]=e.charCodeAt(r);return i}async function E(){if(!g()||Notification.permission!=="granted")return false;let{publicKey:t}=await c(c$1.push);if(!t)return false;await navigator.serviceWorker.register("/sw.js",{scope:"/"});let{pushManager:n}=await navigator.serviceWorker.ready,e=v(t),i=await n.getSubscription();return i&&!h(i.options.applicationServerKey,e)&&(await i.unsubscribe(),i=null),i??=await n.subscribe({applicationServerKey:e,userVisibleOnly:true}),await c(c$1.push,{body:JSON.stringify(i.toJSON()),method:"POST"}),true}function h(t,n){return !t||t.byteLength!==n.byteLength?false:new Uint8Array(t).every((i,r)=>i===n[r])}export{I as a,b,m as c,w as d,p as e,N as f,k as g,R as h,E as i};//# sourceMappingURL=chunk-KN7OJFEX.js.map
2
- //# sourceMappingURL=chunk-KN7OJFEX.js.map
1
+ import'./index.css';import {c as c$1}from'./chunk-MBBE4RND.js';import {b as b$1}from'./chunk-5CVDMZUI.js';import y from'swr';var d="1970-01-01T00:00:00.000Z";function I(t){return t.chatId?`agent/chats/${t.chatId}`:t.automationId&&t.automationRunId?`automations/${t.automationId}/runs/${t.automationRunId}`:null}function b(t){return t.chatId?"View chat":t.automationId&&t.automationRunId?"View run":null}var l={answered:"Answered",approved:"Approved",cancelled:"Cancelled",dismissed:"Dismissed",expired:"Expired",rejected:"Rejected"};function m(t){return t.kind==="automation_failure"?"Failed":t.kind==="automation_result"?"Result":t.kind==="monitor_event"?"Monitor":t.resolution?l[t.resolution]:!t.requiresAction||t.state==="done"||t.state==="dismissed"?null:t.kind==="question"?"Needs answer":"Needs approval"}function w(t){return t.kind==="automation_failure"?"failure":p(t)?"attention":"neutral"}function p(t){return t.requiresAction&&t.resolvedAt===null&&t.state!=="dismissed"&&t.state!=="done"}function N({mutedKinds:t=[],newItems:n,since:e}){let i=n.reduce((o,u)=>o===null||u.createdAt>o?u.createdAt:o,null);if(e===null)return {notifications:[],since:i??d};let r=n.filter(o=>o.createdAt>e&&!t.includes(o.kind)),s=i!==null&&i>e?i:e;return r.length===0?{notifications:[],since:s}:r.length>3?{notifications:[{body:"Open Activity in Flexkit Studio to review them.",path:"activity",tag:`flexkit-activity-batch:${s}`,title:`${r.length.toString()} new items in Activity`}],since:s}:{notifications:r.map(o=>({body:o.body??"",path:`activity/${encodeURIComponent(o.id)}`,tag:`flexkit-activity:${o.id}`,title:o.title})),since:s}}var A={approvalEmail:true,desktopMutedKinds:[]};async function c(t,n){let e=await fetch(t,{credentials:"same-origin",...n,headers:{"Content-Type":"application/json",...n?.headers}});if(!e.ok)throw new Error(`Request failed with ${e.status.toString()}.`);return await e.json()}function k(){let{data:t,error:n,mutate:e}=y(c$1.notificationPreferences,i=>c(i));return {isLoaded:t!==void 0||n!==void 0,mutate:e,preferences:t?.preferences??A}}function R(t){return c(c$1.notificationPreferences,{body:JSON.stringify(t),method:"PUT"})}function g(){return typeof window<"u"&&b$1()===void 0&&typeof Notification<"u"&&"serviceWorker"in navigator&&"PushManager"in window}function v(t){let n=`${t}${"=".repeat((4-t.length%4)%4)}`.replace(/-/g,"+").replace(/_/g,"/"),e=atob(n),i=new Uint8Array(new ArrayBuffer(e.length));for(let r=0;r<e.length;r+=1)i[r]=e.charCodeAt(r);return i}async function E(){if(!g()||Notification.permission!=="granted")return false;let{publicKey:t}=await c(c$1.push);if(!t)return false;await navigator.serviceWorker.register("/sw.js",{scope:"/"});let{pushManager:n}=await navigator.serviceWorker.ready,e=v(t),i=await n.getSubscription();return i&&!h(i.options.applicationServerKey,e)&&(await i.unsubscribe(),i=null),i??=await n.subscribe({applicationServerKey:e,userVisibleOnly:true}),await c(c$1.push,{body:JSON.stringify(i.toJSON()),method:"POST"}),true}function h(t,n){return !t||t.byteLength!==n.byteLength?false:new Uint8Array(t).every((i,r)=>i===n[r])}export{I as a,b,m as c,w as d,p as e,N as f,k as g,R as h,E as i};//# sourceMappingURL=chunk-N52JTYBJ.js.map
2
+ //# sourceMappingURL=chunk-N52JTYBJ.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/apps/ai/activity.ts","../src/apps/ai/notification-settings.ts"],"names":["EPOCH","getActivitySourcePath","item","getActivitySourceLabel","RESOLUTION_LABELS","getActivityStatusLabel","getActivityStatusTone","isActivityItemOpen","planActivityNotifications","mutedKinds","newItems","since","newest","latest","fresh","nextSince","DEFAULT_NOTIFICATION_PREFERENCES","userRequest","url","init","response","useNotificationPreferences","data","error","mutate","useSWR","userApiPaths","saveNotificationPreferences","preferences","isWebPushSupported","getDesktop","decodeApplicationServerKey","base64Url","base64","binary","bytes","index","ensurePushSubscription","publicKey","pushManager","applicationServerKey","subscription","sameKey","current","expected","byte"],"mappings":"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","file":"chunk-KN7OJFEX.js","sourcesContent":["import type { ActivityItem, ActivityItemKind, ActivityItemResolution } from './types';\n\n/** More new items than this in one poll are announced by a single summary notification. */\nconst MAX_SEPARATE_NOTIFICATIONS = 3;\n\n/** Watermark before the first item exists: every later unread item is new. */\nconst EPOCH = '1970-01-01T00:00:00.000Z';\n\nexport interface ActivityNotification {\n body: string;\n /** AI-app relative path opened on click, e.g. `activity/<id>`. */\n path: string;\n /** Same tag = same notification across tabs and repeated polls. */\n tag: string;\n title: string;\n}\n\n/** Path, relative to the AI app, of the chat or run an item came from. */\nexport function getActivitySourcePath(item: ActivityItem): string | null {\n if (item.chatId) {\n return `agent/chats/${item.chatId}`;\n }\n\n if (item.automationId && item.automationRunId) {\n return `automations/${item.automationId}/runs/${item.automationRunId}`;\n }\n\n return null;\n}\n\nexport function getActivitySourceLabel(item: ActivityItem): string | null {\n if (item.chatId) {\n return 'View chat';\n }\n\n return item.automationId && item.automationRunId ? 'View run' : null;\n}\n\nconst RESOLUTION_LABELS: { [key in ActivityItemResolution]: string } = {\n answered: 'Answered',\n approved: 'Approved',\n cancelled: 'Cancelled',\n dismissed: 'Dismissed',\n expired: 'Expired',\n rejected: 'Rejected',\n};\n\n/** Short status for a row: what happened to it, or that it still waits on the viewer. */\nexport function getActivityStatusLabel(item: ActivityItem): string | null {\n if (item.kind === 'automation_failure') {\n return 'Failed';\n }\n\n if (item.kind === 'automation_result') {\n return 'Result';\n }\n\n if (item.kind === 'monitor_event') {\n return 'Monitor';\n }\n\n if (item.resolution) {\n return RESOLUTION_LABELS[item.resolution];\n }\n\n if (!item.requiresAction || item.state === 'done' || item.state === 'dismissed') {\n return null;\n }\n\n return item.kind === 'question' ? 'Needs answer' : 'Needs approval';\n}\n\n/** How a row's status badge reads: waiting on the viewer, a failure, or neutral. */\nexport function getActivityStatusTone(item: ActivityItem): 'attention' | 'failure' | 'neutral' {\n if (item.kind === 'automation_failure') {\n return 'failure';\n }\n\n return isActivityItemOpen(item) ? 'attention' : 'neutral';\n}\n\n/** True while the item still waits on the viewer. */\nexport function isActivityItemOpen(item: ActivityItem): boolean {\n return item.requiresAction && item.resolvedAt === null && item.state !== 'dismissed' && item.state !== 'done';\n}\n\n/**\n * Turns one summary poll into desktop notifications and the next watermark.\n * The first poll (no watermark yet) only seeds it, so opening Studio never\n * replays notifications for items the user already had.\n */\nexport function planActivityNotifications({\n mutedKinds = [],\n newItems,\n since,\n}: {\n /** Kinds the viewer turned off for desktop notifications; they still move the watermark. */\n mutedKinds?: ActivityItemKind[];\n newItems: ActivityItem[];\n since: string | null;\n}): { notifications: ActivityNotification[]; since: string } {\n const newest = newItems.reduce<string | null>(\n (latest, item) => (latest === null || item.createdAt > latest ? item.createdAt : latest),\n null\n );\n\n if (since === null) {\n return { notifications: [], since: newest ?? EPOCH };\n }\n\n const fresh = newItems.filter((item) => item.createdAt > since && !mutedKinds.includes(item.kind));\n const nextSince = newest !== null && newest > since ? newest : since;\n\n if (fresh.length === 0) {\n return { notifications: [], since: nextSince };\n }\n\n if (fresh.length > MAX_SEPARATE_NOTIFICATIONS) {\n return {\n notifications: [\n {\n body: 'Open Activity in Flexkit Studio to review them.',\n path: 'activity',\n tag: `flexkit-activity-batch:${nextSince}`,\n title: `${fresh.length.toString()} new items in Activity`,\n },\n ],\n since: nextSince,\n };\n }\n\n return {\n notifications: fresh.map((item) => ({\n body: item.body ?? '',\n path: `activity/${encodeURIComponent(item.id)}`,\n tag: `flexkit-activity:${item.id}`,\n title: item.title,\n })),\n since: nextSince,\n };\n}\n","import useSWR, { type KeyedMutator } from 'swr';\nimport { userApiPaths } from '../../core/api-paths';\nimport { getDesktop } from '../../core/desktop';\nimport type { ActivityItemKind } from './types';\n\n/** A person's notification choices, shared by every project they open. */\nexport interface NotificationPreferences {\n /** Email an approval request left unread past the project's delay. */\n approvalEmail: boolean;\n /** Kinds that never raise a desktop notification. */\n desktopMutedKinds: ActivityItemKind[];\n}\n\nexport const DEFAULT_NOTIFICATION_PREFERENCES: NotificationPreferences = { approvalEmail: true, desktopMutedKinds: [] };\n\nasync function userRequest<T>(url: string, init?: RequestInit): Promise<T> {\n const response = await fetch(url, {\n credentials: 'same-origin',\n ...init,\n headers: { 'Content-Type': 'application/json', ...init?.headers },\n });\n\n if (!response.ok) {\n throw new Error(`Request failed with ${response.status.toString()}.`);\n }\n\n return (await response.json()) as T;\n}\n\nexport function useNotificationPreferences(): {\n /** False until the stored preferences arrived (or could not be loaded, which means the defaults). */\n isLoaded: boolean;\n mutate: KeyedMutator<{ preferences: NotificationPreferences }>;\n preferences: NotificationPreferences;\n} {\n const { data, error, mutate } = useSWR<{ preferences: NotificationPreferences }>(\n userApiPaths.notificationPreferences,\n (url: string) => userRequest<{ preferences: NotificationPreferences }>(url)\n );\n\n return {\n isLoaded: data !== undefined || error !== undefined,\n mutate,\n preferences: data?.preferences ?? DEFAULT_NOTIFICATION_PREFERENCES,\n };\n}\n\nexport function saveNotificationPreferences(preferences: NotificationPreferences): Promise<{ preferences: NotificationPreferences }> {\n return userRequest(userApiPaths.notificationPreferences, { body: JSON.stringify(preferences), method: 'PUT' });\n}\n\nexport function isWebPushSupported(): boolean {\n // The desktop app keeps polling while it runs in the background and notifies natively.\n return (\n typeof window !== 'undefined' &&\n getDesktop() === undefined &&\n typeof Notification !== 'undefined' &&\n 'serviceWorker' in navigator &&\n 'PushManager' in window\n );\n}\n\n/** The VAPID public key as the bytes `PushManager.subscribe` expects. */\nexport function decodeApplicationServerKey(base64Url: string): Uint8Array<ArrayBuffer> {\n const base64 = `${base64Url}${'='.repeat((4 - (base64Url.length % 4)) % 4)}`.replace(/-/g, '+').replace(/_/g, '/');\n const binary = atob(base64);\n const bytes = new Uint8Array(new ArrayBuffer(binary.length));\n\n for (let index = 0; index < binary.length; index += 1) {\n bytes[index] = binary.charCodeAt(index);\n }\n\n return bytes;\n}\n\n/**\n * Hosted Studio only: registers the service worker and saves this browser's\n * push subscription for the signed-in user, so Activity items arrive while no\n * Studio tab is open. Needs notification permission; never asks for it.\n * Safe to call on every load: an existing subscription is saved again.\n * Returns false when Web Push is unavailable here.\n */\nexport async function ensurePushSubscription(): Promise<boolean> {\n if (!isWebPushSupported() || Notification.permission !== 'granted') {\n return false;\n }\n\n const { publicKey } = await userRequest<{ publicKey: string | null }>(userApiPaths.push);\n\n if (!publicKey) {\n return false;\n }\n\n await navigator.serviceWorker.register('/sw.js', { scope: '/' });\n\n const { pushManager } = await navigator.serviceWorker.ready;\n const applicationServerKey = decodeApplicationServerKey(publicKey);\n let subscription = await pushManager.getSubscription();\n\n // A subscription made with an older key would never receive again.\n if (subscription && !sameKey(subscription.options.applicationServerKey, applicationServerKey)) {\n await subscription.unsubscribe();\n subscription = null;\n }\n\n subscription ??= await pushManager.subscribe({ applicationServerKey, userVisibleOnly: true });\n\n await userRequest(userApiPaths.push, { body: JSON.stringify(subscription.toJSON()), method: 'POST' });\n\n return true;\n}\n\nfunction sameKey(current: ArrayBuffer | null, expected: Uint8Array): boolean {\n if (!current || current.byteLength !== expected.byteLength) {\n return false;\n }\n\n const bytes = new Uint8Array(current);\n\n return bytes.every((byte, index) => byte === expected[index]);\n}\n"]}
1
+ {"version":3,"sources":["../src/apps/ai/activity.ts","../src/apps/ai/notification-settings.ts"],"names":["EPOCH","getActivitySourcePath","item","getActivitySourceLabel","RESOLUTION_LABELS","getActivityStatusLabel","getActivityStatusTone","isActivityItemOpen","planActivityNotifications","mutedKinds","newItems","since","newest","latest","fresh","nextSince","DEFAULT_NOTIFICATION_PREFERENCES","userRequest","url","init","response","useNotificationPreferences","data","error","mutate","useSWR","userApiPaths","saveNotificationPreferences","preferences","isWebPushSupported","getDesktop","decodeApplicationServerKey","base64Url","base64","binary","bytes","index","ensurePushSubscription","publicKey","pushManager","applicationServerKey","subscription","sameKey","current","expected","byte"],"mappings":"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","file":"chunk-N52JTYBJ.js","sourcesContent":["import type { ActivityItem, ActivityItemKind, ActivityItemResolution } from './types';\n\n/** More new items than this in one poll are announced by a single summary notification. */\nconst MAX_SEPARATE_NOTIFICATIONS = 3;\n\n/** Watermark before the first item exists: every later unread item is new. */\nconst EPOCH = '1970-01-01T00:00:00.000Z';\n\nexport interface ActivityNotification {\n body: string;\n /** AI-app relative path opened on click, e.g. `activity/<id>`. */\n path: string;\n /** Same tag = same notification across tabs and repeated polls. */\n tag: string;\n title: string;\n}\n\n/** Path, relative to the AI app, of the chat or run an item came from. */\nexport function getActivitySourcePath(item: ActivityItem): string | null {\n if (item.chatId) {\n return `agent/chats/${item.chatId}`;\n }\n\n if (item.automationId && item.automationRunId) {\n return `automations/${item.automationId}/runs/${item.automationRunId}`;\n }\n\n return null;\n}\n\nexport function getActivitySourceLabel(item: ActivityItem): string | null {\n if (item.chatId) {\n return 'View chat';\n }\n\n return item.automationId && item.automationRunId ? 'View run' : null;\n}\n\nconst RESOLUTION_LABELS: { [key in ActivityItemResolution]: string } = {\n answered: 'Answered',\n approved: 'Approved',\n cancelled: 'Cancelled',\n dismissed: 'Dismissed',\n expired: 'Expired',\n rejected: 'Rejected',\n};\n\n/** Short status for a row: what happened to it, or that it still waits on the viewer. */\nexport function getActivityStatusLabel(item: ActivityItem): string | null {\n if (item.kind === 'automation_failure') {\n return 'Failed';\n }\n\n if (item.kind === 'automation_result') {\n return 'Result';\n }\n\n if (item.kind === 'monitor_event') {\n return 'Monitor';\n }\n\n if (item.resolution) {\n return RESOLUTION_LABELS[item.resolution];\n }\n\n if (!item.requiresAction || item.state === 'done' || item.state === 'dismissed') {\n return null;\n }\n\n return item.kind === 'question' ? 'Needs answer' : 'Needs approval';\n}\n\n/** How a row's status badge reads: waiting on the viewer, a failure, or neutral. */\nexport function getActivityStatusTone(item: ActivityItem): 'attention' | 'failure' | 'neutral' {\n if (item.kind === 'automation_failure') {\n return 'failure';\n }\n\n return isActivityItemOpen(item) ? 'attention' : 'neutral';\n}\n\n/** True while the item still waits on the viewer. */\nexport function isActivityItemOpen(item: ActivityItem): boolean {\n return item.requiresAction && item.resolvedAt === null && item.state !== 'dismissed' && item.state !== 'done';\n}\n\n/**\n * Turns one summary poll into desktop notifications and the next watermark.\n * The first poll (no watermark yet) only seeds it, so opening Studio never\n * replays notifications for items the user already had.\n */\nexport function planActivityNotifications({\n mutedKinds = [],\n newItems,\n since,\n}: {\n /** Kinds the viewer turned off for desktop notifications; they still move the watermark. */\n mutedKinds?: ActivityItemKind[];\n newItems: ActivityItem[];\n since: string | null;\n}): { notifications: ActivityNotification[]; since: string } {\n const newest = newItems.reduce<string | null>(\n (latest, item) => (latest === null || item.createdAt > latest ? item.createdAt : latest),\n null\n );\n\n if (since === null) {\n return { notifications: [], since: newest ?? EPOCH };\n }\n\n const fresh = newItems.filter((item) => item.createdAt > since && !mutedKinds.includes(item.kind));\n const nextSince = newest !== null && newest > since ? newest : since;\n\n if (fresh.length === 0) {\n return { notifications: [], since: nextSince };\n }\n\n if (fresh.length > MAX_SEPARATE_NOTIFICATIONS) {\n return {\n notifications: [\n {\n body: 'Open Activity in Flexkit Studio to review them.',\n path: 'activity',\n tag: `flexkit-activity-batch:${nextSince}`,\n title: `${fresh.length.toString()} new items in Activity`,\n },\n ],\n since: nextSince,\n };\n }\n\n return {\n notifications: fresh.map((item) => ({\n body: item.body ?? '',\n path: `activity/${encodeURIComponent(item.id)}`,\n tag: `flexkit-activity:${item.id}`,\n title: item.title,\n })),\n since: nextSince,\n };\n}\n","import useSWR, { type KeyedMutator } from 'swr';\nimport { userApiPaths } from '../../core/api-paths';\nimport { getDesktop } from '../../core/desktop';\nimport type { ActivityItemKind } from './types';\n\n/** A person's notification choices, shared by every project they open. */\nexport interface NotificationPreferences {\n /** Email an approval request left unread past the project's delay. */\n approvalEmail: boolean;\n /** Kinds that never raise a desktop notification. */\n desktopMutedKinds: ActivityItemKind[];\n}\n\nexport const DEFAULT_NOTIFICATION_PREFERENCES: NotificationPreferences = { approvalEmail: true, desktopMutedKinds: [] };\n\nasync function userRequest<T>(url: string, init?: RequestInit): Promise<T> {\n const response = await fetch(url, {\n credentials: 'same-origin',\n ...init,\n headers: { 'Content-Type': 'application/json', ...init?.headers },\n });\n\n if (!response.ok) {\n throw new Error(`Request failed with ${response.status.toString()}.`);\n }\n\n return (await response.json()) as T;\n}\n\nexport function useNotificationPreferences(): {\n /** False until the stored preferences arrived (or could not be loaded, which means the defaults). */\n isLoaded: boolean;\n mutate: KeyedMutator<{ preferences: NotificationPreferences }>;\n preferences: NotificationPreferences;\n} {\n const { data, error, mutate } = useSWR<{ preferences: NotificationPreferences }>(\n userApiPaths.notificationPreferences,\n (url: string) => userRequest<{ preferences: NotificationPreferences }>(url)\n );\n\n return {\n isLoaded: data !== undefined || error !== undefined,\n mutate,\n preferences: data?.preferences ?? DEFAULT_NOTIFICATION_PREFERENCES,\n };\n}\n\nexport function saveNotificationPreferences(preferences: NotificationPreferences): Promise<{ preferences: NotificationPreferences }> {\n return userRequest(userApiPaths.notificationPreferences, { body: JSON.stringify(preferences), method: 'PUT' });\n}\n\nexport function isWebPushSupported(): boolean {\n // The desktop app keeps polling while it runs in the background and notifies natively.\n return (\n typeof window !== 'undefined' &&\n getDesktop() === undefined &&\n typeof Notification !== 'undefined' &&\n 'serviceWorker' in navigator &&\n 'PushManager' in window\n );\n}\n\n/** The VAPID public key as the bytes `PushManager.subscribe` expects. */\nexport function decodeApplicationServerKey(base64Url: string): Uint8Array<ArrayBuffer> {\n const base64 = `${base64Url}${'='.repeat((4 - (base64Url.length % 4)) % 4)}`.replace(/-/g, '+').replace(/_/g, '/');\n const binary = atob(base64);\n const bytes = new Uint8Array(new ArrayBuffer(binary.length));\n\n for (let index = 0; index < binary.length; index += 1) {\n bytes[index] = binary.charCodeAt(index);\n }\n\n return bytes;\n}\n\n/**\n * Hosted Studio only: registers the service worker and saves this browser's\n * push subscription for the signed-in user, so Activity items arrive while no\n * Studio tab is open. Needs notification permission; never asks for it.\n * Safe to call on every load: an existing subscription is saved again.\n * Returns false when Web Push is unavailable here.\n */\nexport async function ensurePushSubscription(): Promise<boolean> {\n if (!isWebPushSupported() || Notification.permission !== 'granted') {\n return false;\n }\n\n const { publicKey } = await userRequest<{ publicKey: string | null }>(userApiPaths.push);\n\n if (!publicKey) {\n return false;\n }\n\n await navigator.serviceWorker.register('/sw.js', { scope: '/' });\n\n const { pushManager } = await navigator.serviceWorker.ready;\n const applicationServerKey = decodeApplicationServerKey(publicKey);\n let subscription = await pushManager.getSubscription();\n\n // A subscription made with an older key would never receive again.\n if (subscription && !sameKey(subscription.options.applicationServerKey, applicationServerKey)) {\n await subscription.unsubscribe();\n subscription = null;\n }\n\n subscription ??= await pushManager.subscribe({ applicationServerKey, userVisibleOnly: true });\n\n await userRequest(userApiPaths.push, { body: JSON.stringify(subscription.toJSON()), method: 'POST' });\n\n return true;\n}\n\nfunction sameKey(current: ArrayBuffer | null, expected: Uint8Array): boolean {\n if (!current || current.byteLength !== expected.byteLength) {\n return false;\n }\n\n const bytes = new Uint8Array(current);\n\n return bytes.every((byte, index) => byte === expected[index]);\n}\n"]}
@@ -1,4 +1,4 @@
1
- import'./index.css';import {e,d,a as a$2,c,b as b$1}from'./chunk-XV7U33XQ.js';import {a}from'./chunk-YDVO6XWD.js';import {a as a$1}from'./chunk-ERDARDGB.js';import {b,c as c$1}from'./chunk-HZOD2HOF.js';import {find,propEq,omit,pick,toPairs,uniq,uniqBy,prop}from'ramda';import {useState,useRef,useMemo,useEffect,useCallback}from'react';import {gql,NetworkStatus}from'@apollo/client';import {useQuery}from'@apollo/client/react';var Wt=25,mn=3,Kt=3,hn=["id","string"],$n=["date","datetime","duration","time"],$t=`_id
1
+ import'./index.css';import {e,d,a as a$2,c,b as b$1}from'./chunk-6AJRQSFO.js';import {a}from'./chunk-YDVO6XWD.js';import {a as a$1}from'./chunk-ERDARDGB.js';import {b,c as c$1}from'./chunk-VRDTHLA3.js';import {find,propEq,omit,pick,toPairs,uniq,uniqBy,prop}from'ramda';import {useState,useRef,useMemo,useEffect,useCallback}from'react';import {gql,NetworkStatus}from'@apollo/client';import {useQuery}from'@apollo/client/react';var Wt=25,mn=3,Kt=3,hn=["id","string"],$n=["date","datetime","duration","time"],$t=`_id
2
2
  originalFilename
3
3
  mimeType
4
4
  path
@@ -374,5 +374,5 @@ ${A} ]
374
374
  }
375
375
  }
376
376
  }
377
- `}}var et=t=>t.charAt(0).toUpperCase()+t.slice(1);function x(t){let n=t.split(/[^0-9A-Za-z]+/).filter(Boolean).map(et).join("");return n?/^[A-Za-z_]/.test(n)?n:`Entity${n}`:"Entity"}function D(t,n){return n==="_assets"?b:find(propEq(n,"plural"))(t)}function re(t,n,e){if(!t||typeof t!="object")return {};let r=D(e,n);if(!r)return {};let i=`update${et(n)}`,s=t[i];if(!s||typeof s!="object")return {};let o=s[n],l=Array.isArray(o)?o[0]:void 0;return !l||typeof l!="object"?{}:r.attributes.reduce((c,u)=>{if(a(u)!=="local")return c;let d=B(l[u.name])?._id;return typeof d!="string"||d.length===0?c:{...c,[u.name]:d}},{})}var dt=null,_t=new Set,rn=[],Rt=new Set,It=new Set,wt=new Set;function ue(t,n){if(t==="_asset"||t==="_assets")return `Get${x(b.plural)}`;let e=n.find(s=>s.plural===t),r=n.find(s=>s.name===t),i=e?.plural??r?.plural??t;return `Get${x(i)}`}function sn(t){return Rt.add(t),()=>{Rt.delete(t);}}function on(t){return It.add(t),()=>{It.delete(t);}}function un(t){return wt.add(t),()=>{wt.delete(t);}}function le(t,n,e){let r=new Set(e.filter(Boolean));if(r.size>0)for(let i of It)i(n,r);return Dn(t,n)}function ce(t,n){let e=n.filter(r=>!!r._id);if(e.length!==0)for(let r of wt)r(t,e);}function Dn(t,n){return _t.add(n),new Promise((e,r)=>{rn.push({resolve:e,reject:r}),dt&&clearTimeout(dt),dt=setTimeout(()=>{let i=new Set(_t),s=rn.splice(0);_t.clear(),dt=null,Promise.all([...Rt].map(o=>Promise.resolve(o(i)))).then(()=>{for(let{resolve:o}of s)o();}).catch(o=>{console.error("Error refreshing entity lists:",o);for(let{reject:l}of s)l(o);});},50);})}function Ae({entityNamePlural:t,schema:n,scope:e$1,variables:r,isForm:i,selection:s="full",includeCount:o=true,fetchPolicy:l}){let[c$1,u]=useState({count:0,results:[]}),[a,d$1]=useState(false),[f,p]=useState(false),[m,h]=useState(null),A=useRef(false),g=useRef(false),y=useRef(0),E=useRef(null),C=useRef(null),F=`${t}Total`,b=D(n,t),V=r?.where===void 0&&(b?.spaces?.length??0)===0&&(m?.field!==F||m.schema!==n)?"total":"aggregate",J=useMemo(()=>gql(at(t,e$1,n,{selection:s,countMode:V,includeCount:o}).query),[t,e$1,n,s,V,o]),$=useMemo(()=>gql(at(t,e$1,n,{selection:s,includeCount:false}).query),[t,e$1,n,s]),{schemaErrorMessage:R,setSchemaErrorMessage:k}=e(),{loading:H,data:v,fetchMore:st,refetch:ot,error:Lt,networkStatus:Y}=useQuery(J,{variables:r,notifyOnNetworkStatusChange:true,fetchPolicy:l}),Ft=useRef(st),gt=useRef(ot),Ct=useRef($),Tt=useRef(Y),Mt=useRef(r);Ft.current=st,gt.current=ot,Ct.current=$,Mt.current=r;let yt=o&&d(Lt,F),Qt=V==="total"&&yt,G=yt?void 0:Lt,N=yt&&!v?.[t],qt=a$2(G),P=c(G),{isProjectDisabled:dn,isProjectReadOnly:fn}=(()=>{if(qt?.statusCode===403){let I=b$1(qt.bodyText);if(I&&typeof I.code=="string"){if(I.code==="PROJECT_PAUSED")return {isProjectDisabled:true,isProjectReadOnly:false};if(I.code==="READ_ONLY_MODE")return {isProjectDisabled:false,isProjectReadOnly:true}}return {isProjectDisabled:true,isProjectReadOnly:false}}return {isProjectDisabled:false,isProjectReadOnly:false}})();useEffect(()=>{Qt&&h({field:F,schema:n});},[n,Qt,F]);let pn=useCallback(I=>{if(A.current||g.current)return;A.current=true,d$1(true);let{limit:Q}=I.variables,q=y.current;Ft.current({...I,query:Ct.current,variables:{...Mt.current,...I.variables,offset:q,limit:Q}}).then(({data:X})=>{let M=it({data:X,entityNamePlural:t,isForm:i,schema:n,scope:e$1}),j=M.results.length;y.current=q+(j===0?0:Math.min(j,Q)),u(T=>{let W=uniqBy(prop("_id"),[...T.results,...M.results]);return W.length===T.results.length?{count:T.results.length,results:T.results}:{count:M.count||T.count,results:W}});}).catch(X=>{console.error("Error fetching more data:",X);}).finally(()=>{A.current=false,d$1(false);});},[t,i,n,e$1]),gn=useCallback(I=>{if(g.current)return Promise.resolve();let Q=I?.preserve===true;return g.current=true,A.current=false,d$1(false),Q||(E.current=null,C.current=null,y.current=0,p(true),u({count:0,results:[]})),gt.current().then(({data:q})=>{let X=JSON.stringify({entityNamePlural:t,scope:e$1,selection:s,includeCount:o,variables:r}),M=it({data:q,entityNamePlural:t,isForm:i,schema:n,scope:e$1});E.current=X,C.current=null,y.current=pt(r)+M.results.length,u(M);}).catch(q=>{console.error("Error reloading data:",q);}).finally(()=>{g.current=false,p(false);})},[t,i,n,e$1,s,o,r]);return useEffect(()=>{if(P){k(P);return}v&&R&&!G&&k(null);},[v,G,R,P,k]),useEffect(()=>{if(G||P||N)return;let I=JSON.stringify({entityNamePlural:t,scope:e$1,selection:s,includeCount:o,variables:r});if(E.current===I)return;if(H&&C.current!==I){C.current=I,y.current=0,u({count:0,results:[]});return}if(H)return;let Q=it({data:v,entityNamePlural:t,isForm:i,schema:n,scope:e$1});E.current=I,C.current=null,y.current=pt(r)+Q.results.length,u(Q);},[v,G,t,i,H,N,n,P,e$1,s,o,r]),useEffect(()=>{let I=Tt.current;if(Tt.current=Y,G||P||g.current||N||I!==NetworkStatus.refetch||Y!==NetworkStatus.ready||!v)return;let Q=JSON.stringify({entityNamePlural:t,scope:e$1,selection:s,includeCount:o,variables:r}),q=it({data:v,entityNamePlural:t,isForm:i,schema:n,scope:e$1});E.current=Q,C.current=null,y.current=pt(r)+q.results.length,u(q);},[v,G,t,i,N,Y,n,P,e$1,s,o,r]),useEffect(()=>{if(i)return;let I=`Get${x(t)}`,Q=sn(M=>{if(!(!M.has(I)||A.current||g.current))return gt.current().then(({data:j})=>{let T=JSON.stringify({entityNamePlural:t,scope:e$1,selection:s,includeCount:o,variables:r}),W=it({data:j,entityNamePlural:t,isForm:i,schema:n,scope:e$1});E.current=T,C.current=null,y.current=pt(r)+W.results.length,u(W);}).catch(j=>{console.error("Error soft-refreshing entity list:",j);})}),q=on((M,j)=>{M===I&&u(T=>{let W=T.results.filter(kt=>{let vt=typeof kt._id=="string"?kt._id:void 0;return !vt||!j.has(vt)}),xt=T.results.length-W.length;return xt===0?T:{count:Math.max(0,T.count-xt),results:W}});}),X=un((M,j)=>{M===I&&u(T=>zn(T,j,r?.sort));});return ()=>{Q(),q(),X();}},[t,i,n,e$1,s,o,r]),{isLoading:H&&Y!==NetworkStatus.refetch||f||N,isLoadingMore:a,fetchMore:pn,reload:gn,count:c$1.count,data:c$1.results,isProjectDisabled:dn,isProjectReadOnly:fn,schemaErrorMessage:R}}function pt(t){let n=t?.offset;return typeof n=="number"&&Number.isFinite(n)?n:0}function it(t){let n=t.entityNamePlural;return t.data?.[n]?t.isForm?Yt(t.entityNamePlural,t.scope,t.data,t.schema):Ht(t.entityNamePlural,t.scope,t.data,t.schema):{count:0,results:[]}}function zn(t,n,e){let r=new Map(n.map(o=>[o._id,o])),i=false,s=t.results.map(o=>{let l=typeof o._id=="string"?o._id:void 0;if(!l)return o;let c=r.get(l);return c?(i=true,{...o,...c.attributes}):o});return i?{count:t.count,results:Gn(s,e)}:t}function Gn(t,n){if(!Array.isArray(n)||n.length===0)return t;let[e]=n;if(!e||typeof e!="object")return t;let[r]=Object.entries(e),[i,s]=r??[];if(!i||s!=="ASC"&&s!=="DESC")return t;let o=s==="DESC"?-1:1;return [...t].sort((l,c)=>{let u=l[i],a=c[i],d=typeof u=="string"?u:"",f=typeof a=="string"?a:"";return d.localeCompare(f)*o})}export{Wt as a,Jt as b,En as c,Zn as d,at as e,Ht as f,Hn as g,Yn as h,Nn as i,te as j,ne as k,ee as l,D as m,re as n,ue as o,le as p,ce as q,Dn as r,Ae as s};//# sourceMappingURL=chunk-KR27GOH6.js.map
378
- //# sourceMappingURL=chunk-KR27GOH6.js.map
377
+ `}}var et=t=>t.charAt(0).toUpperCase()+t.slice(1);function x(t){let n=t.split(/[^0-9A-Za-z]+/).filter(Boolean).map(et).join("");return n?/^[A-Za-z_]/.test(n)?n:`Entity${n}`:"Entity"}function D(t,n){return n==="_assets"?b:find(propEq(n,"plural"))(t)}function re(t,n,e){if(!t||typeof t!="object")return {};let r=D(e,n);if(!r)return {};let i=`update${et(n)}`,s=t[i];if(!s||typeof s!="object")return {};let o=s[n],l=Array.isArray(o)?o[0]:void 0;return !l||typeof l!="object"?{}:r.attributes.reduce((c,u)=>{if(a(u)!=="local")return c;let d=B(l[u.name])?._id;return typeof d!="string"||d.length===0?c:{...c,[u.name]:d}},{})}var dt=null,_t=new Set,rn=[],Rt=new Set,It=new Set,wt=new Set;function ue(t,n){if(t==="_asset"||t==="_assets")return `Get${x(b.plural)}`;let e=n.find(s=>s.plural===t),r=n.find(s=>s.name===t),i=e?.plural??r?.plural??t;return `Get${x(i)}`}function sn(t){return Rt.add(t),()=>{Rt.delete(t);}}function on(t){return It.add(t),()=>{It.delete(t);}}function un(t){return wt.add(t),()=>{wt.delete(t);}}function le(t,n,e){let r=new Set(e.filter(Boolean));if(r.size>0)for(let i of It)i(n,r);return Dn(t,n)}function ce(t,n){let e=n.filter(r=>!!r._id);if(e.length!==0)for(let r of wt)r(t,e);}function Dn(t,n){return _t.add(n),new Promise((e,r)=>{rn.push({resolve:e,reject:r}),dt&&clearTimeout(dt),dt=setTimeout(()=>{let i=new Set(_t),s=rn.splice(0);_t.clear(),dt=null,Promise.all([...Rt].map(o=>Promise.resolve(o(i)))).then(()=>{for(let{resolve:o}of s)o();}).catch(o=>{console.error("Error refreshing entity lists:",o);for(let{reject:l}of s)l(o);});},50);})}function Ae({entityNamePlural:t,schema:n,scope:e$1,variables:r,isForm:i,selection:s="full",includeCount:o=true,fetchPolicy:l}){let[c$1,u]=useState({count:0,results:[]}),[a,d$1]=useState(false),[f,p]=useState(false),[m,h]=useState(null),A=useRef(false),g=useRef(false),y=useRef(0),E=useRef(null),C=useRef(null),F=`${t}Total`,b=D(n,t),V=r?.where===void 0&&(b?.spaces?.length??0)===0&&(m?.field!==F||m.schema!==n)?"total":"aggregate",J=useMemo(()=>gql(at(t,e$1,n,{selection:s,countMode:V,includeCount:o}).query),[t,e$1,n,s,V,o]),$=useMemo(()=>gql(at(t,e$1,n,{selection:s,includeCount:false}).query),[t,e$1,n,s]),{schemaErrorMessage:R,setSchemaErrorMessage:k}=e(),{loading:H,data:v,fetchMore:st,refetch:ot,error:Lt,networkStatus:Y}=useQuery(J,{variables:r,notifyOnNetworkStatusChange:true,fetchPolicy:l}),Ft=useRef(st),gt=useRef(ot),Ct=useRef($),Tt=useRef(Y),Mt=useRef(r);Ft.current=st,gt.current=ot,Ct.current=$,Mt.current=r;let yt=o&&d(Lt,F),Qt=V==="total"&&yt,G=yt?void 0:Lt,N=yt&&!v?.[t],qt=a$2(G),P=c(G),{isProjectDisabled:dn,isProjectReadOnly:fn}=(()=>{if(qt?.statusCode===403){let I=b$1(qt.bodyText);if(I&&typeof I.code=="string"){if(I.code==="PROJECT_PAUSED")return {isProjectDisabled:true,isProjectReadOnly:false};if(I.code==="READ_ONLY_MODE")return {isProjectDisabled:false,isProjectReadOnly:true}}return {isProjectDisabled:true,isProjectReadOnly:false}}return {isProjectDisabled:false,isProjectReadOnly:false}})();useEffect(()=>{Qt&&h({field:F,schema:n});},[n,Qt,F]);let pn=useCallback(I=>{if(A.current||g.current)return;A.current=true,d$1(true);let{limit:Q}=I.variables,q=y.current;Ft.current({...I,query:Ct.current,variables:{...Mt.current,...I.variables,offset:q,limit:Q}}).then(({data:X})=>{let M=it({data:X,entityNamePlural:t,isForm:i,schema:n,scope:e$1}),j=M.results.length;y.current=q+(j===0?0:Math.min(j,Q)),u(T=>{let W=uniqBy(prop("_id"),[...T.results,...M.results]);return W.length===T.results.length?{count:T.results.length,results:T.results}:{count:M.count||T.count,results:W}});}).catch(X=>{console.error("Error fetching more data:",X);}).finally(()=>{A.current=false,d$1(false);});},[t,i,n,e$1]),gn=useCallback(I=>{if(g.current)return Promise.resolve();let Q=I?.preserve===true;return g.current=true,A.current=false,d$1(false),Q||(E.current=null,C.current=null,y.current=0,p(true),u({count:0,results:[]})),gt.current().then(({data:q})=>{let X=JSON.stringify({entityNamePlural:t,scope:e$1,selection:s,includeCount:o,variables:r}),M=it({data:q,entityNamePlural:t,isForm:i,schema:n,scope:e$1});E.current=X,C.current=null,y.current=pt(r)+M.results.length,u(M);}).catch(q=>{console.error("Error reloading data:",q);}).finally(()=>{g.current=false,p(false);})},[t,i,n,e$1,s,o,r]);return useEffect(()=>{if(P){k(P);return}v&&R&&!G&&k(null);},[v,G,R,P,k]),useEffect(()=>{if(G||P||N)return;let I=JSON.stringify({entityNamePlural:t,scope:e$1,selection:s,includeCount:o,variables:r});if(E.current===I)return;if(H&&C.current!==I){C.current=I,y.current=0,u({count:0,results:[]});return}if(H)return;let Q=it({data:v,entityNamePlural:t,isForm:i,schema:n,scope:e$1});E.current=I,C.current=null,y.current=pt(r)+Q.results.length,u(Q);},[v,G,t,i,H,N,n,P,e$1,s,o,r]),useEffect(()=>{let I=Tt.current;if(Tt.current=Y,G||P||g.current||N||I!==NetworkStatus.refetch||Y!==NetworkStatus.ready||!v)return;let Q=JSON.stringify({entityNamePlural:t,scope:e$1,selection:s,includeCount:o,variables:r}),q=it({data:v,entityNamePlural:t,isForm:i,schema:n,scope:e$1});E.current=Q,C.current=null,y.current=pt(r)+q.results.length,u(q);},[v,G,t,i,N,Y,n,P,e$1,s,o,r]),useEffect(()=>{if(i)return;let I=`Get${x(t)}`,Q=sn(M=>{if(!(!M.has(I)||A.current||g.current))return gt.current().then(({data:j})=>{let T=JSON.stringify({entityNamePlural:t,scope:e$1,selection:s,includeCount:o,variables:r}),W=it({data:j,entityNamePlural:t,isForm:i,schema:n,scope:e$1});E.current=T,C.current=null,y.current=pt(r)+W.results.length,u(W);}).catch(j=>{console.error("Error soft-refreshing entity list:",j);})}),q=on((M,j)=>{M===I&&u(T=>{let W=T.results.filter(kt=>{let vt=typeof kt._id=="string"?kt._id:void 0;return !vt||!j.has(vt)}),xt=T.results.length-W.length;return xt===0?T:{count:Math.max(0,T.count-xt),results:W}});}),X=un((M,j)=>{M===I&&u(T=>zn(T,j,r?.sort));});return ()=>{Q(),q(),X();}},[t,i,n,e$1,s,o,r]),{isLoading:H&&Y!==NetworkStatus.refetch||f||N,isLoadingMore:a,fetchMore:pn,reload:gn,count:c$1.count,data:c$1.results,isProjectDisabled:dn,isProjectReadOnly:fn,schemaErrorMessage:R}}function pt(t){let n=t?.offset;return typeof n=="number"&&Number.isFinite(n)?n:0}function it(t){let n=t.entityNamePlural;return t.data?.[n]?t.isForm?Yt(t.entityNamePlural,t.scope,t.data,t.schema):Ht(t.entityNamePlural,t.scope,t.data,t.schema):{count:0,results:[]}}function zn(t,n,e){let r=new Map(n.map(o=>[o._id,o])),i=false,s=t.results.map(o=>{let l=typeof o._id=="string"?o._id:void 0;if(!l)return o;let c=r.get(l);return c?(i=true,{...o,...c.attributes}):o});return i?{count:t.count,results:Gn(s,e)}:t}function Gn(t,n){if(!Array.isArray(n)||n.length===0)return t;let[e]=n;if(!e||typeof e!="object")return t;let[r]=Object.entries(e),[i,s]=r??[];if(!i||s!=="ASC"&&s!=="DESC")return t;let o=s==="DESC"?-1:1;return [...t].sort((l,c)=>{let u=l[i],a=c[i],d=typeof u=="string"?u:"",f=typeof a=="string"?a:"";return d.localeCompare(f)*o})}export{Wt as a,Jt as b,En as c,Zn as d,at as e,Ht as f,Hn as g,Yn as h,Nn as i,te as j,ne as k,ee as l,D as m,re as n,ue as o,le as p,ce as q,Dn as r,Ae as s};//# sourceMappingURL=chunk-PC5Z37LT.js.map
378
+ //# sourceMappingURL=chunk-PC5Z37LT.js.map