@lovelybunch/api 1.0.76 → 1.0.77-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. package/dist/config/oauth.d.ts +33 -0
  2. package/dist/config/oauth.js +43 -0
  3. package/dist/lib/auth/auth-manager.d.ts +21 -1
  4. package/dist/lib/auth/auth-manager.js +57 -3
  5. package/dist/lib/auth/clerk-verifier.d.ts +22 -0
  6. package/dist/lib/auth/clerk-verifier.js +30 -0
  7. package/dist/lib/terminal/terminal-manager.js +2 -1
  8. package/dist/middleware/auth.js +40 -3
  9. package/dist/routes/api/v1/auth/route.js +90 -0
  10. package/dist/routes/api/v1/auth-settings/route.js +83 -2
  11. package/dist/routes/api/v1/events/status/route.d.ts +1 -1
  12. package/dist/routes/api/v1/jobs/[id]/route.d.ts +8 -8
  13. package/dist/routes/api/v1/jobs/[id]/run/route.d.ts +2 -2
  14. package/dist/routes/api/v1/jobs/[id]/runs/[runId]/route.d.ts +2 -2
  15. package/dist/routes/api/v1/jobs/route.d.ts +8 -8
  16. package/dist/routes/api/v1/jobs/status/route.d.ts +1 -1
  17. package/dist/routes/api/v1/mail/route.d.ts +3 -3
  18. package/dist/routes/api/v1/tasks/[id]/route.d.ts +4 -4
  19. package/dist/routes/api/v1/tasks/[id]/steps/[stepId]/route.d.ts +2 -2
  20. package/dist/routes/api/v1/tasks/route.d.ts +1 -1
  21. package/dist/server-with-static.js +36 -17
  22. package/dist/server.js +12 -0
  23. package/package.json +25 -23
  24. package/static/assets/{ActivityPage-sJEQn6DK.js → ActivityPage-DqSj7XDx.js} +1 -1
  25. package/static/assets/{AgentsContextEditPage-DU3qIXk9.js → AgentsContextEditPage-C5afMo09.js} +1 -1
  26. package/static/assets/AgentsContextPage-IrZGdiYt.js +1 -0
  27. package/static/assets/{ApiKeysSettingsPage-Bg84BQHV.js → ApiKeysSettingsPage-CFBTIYNp.js} +2 -2
  28. package/static/assets/AuthSettingsPage-LU7DFMG6.js +11 -0
  29. package/static/assets/{CallbackPage-BFn0Np2S.js → CallbackPage-Beg0ZLv4.js} +1 -1
  30. package/static/assets/CoconutCallbackPage-BuBYbeY-.js +1 -0
  31. package/static/assets/CodePage-C9auBWu3.js +2 -0
  32. package/static/assets/{CollapsibleSection-CNs1mvsZ.js → CollapsibleSection-C3uaXDrK.js} +1 -1
  33. package/static/assets/{DashboardPage-DMJSzzgD.js → DashboardPage-DK2uEtcQ.js} +2 -2
  34. package/static/assets/{GitPage-uqene8zj.js → GitPage-BgfZ5rXn.js} +2 -2
  35. package/static/assets/{GitSettingsPage-CLswbZsT.js → GitSettingsPage-DIhaZgDD.js} +2 -2
  36. package/static/assets/{IdentityPage-BDTPXEo7.js → IdentityPage-6_IEyGmH.js} +2 -2
  37. package/static/assets/{ImplementationStepsEditor-D4cvhPhz.js → ImplementationStepsEditor-BXjs77nI.js} +1 -1
  38. package/static/assets/IntegrationsSettingsPage-Cu-C86-i.js +1 -0
  39. package/static/assets/JobDetailPage-BWd0sz7w.js +1 -0
  40. package/static/assets/KnowledgeDetailPage-Cx0NiVN5.js +1 -0
  41. package/static/assets/KnowledgeEditPage-Dtp9Ceyp.js +1 -0
  42. package/static/assets/{KnowledgePage-B2zI3xwW.js → KnowledgePage-DRavibOT.js} +2 -2
  43. package/static/assets/LoginPage-Bn-55dqi.js +1 -0
  44. package/static/assets/MailInboxPage-B-mzoocZ.js +1 -0
  45. package/static/assets/MailProcessingModal-B5HFIwxh.js +1 -0
  46. package/static/assets/MailReadPage-DVVICNmn.js +1 -0
  47. package/static/assets/MailSentPage-BmqXLEIF.js +1 -0
  48. package/static/assets/McpSettingsPage-D6hW-2uy.js +1 -0
  49. package/static/assets/{MemoryEditPage-DXSQoCT4.js → MemoryEditPage-Cw2oWAW2.js} +1 -1
  50. package/static/assets/MemoryPage-BKNQlp0x.js +1 -0
  51. package/static/assets/{NewKnowledgePage-deMsezK8.js → NewKnowledgePage-zWnjfGF1.js} +1 -1
  52. package/static/assets/{NewSkillPage-DRYWdrlV.js → NewSkillPage-eqK5nwnk.js} +1 -1
  53. package/static/assets/{NewTaskPage-B6xdic5_.js → NewTaskPage-BcOmFrza.js} +2 -2
  54. package/static/assets/{NotFoundPage-Bxu9uKFO.js → NotFoundPage-CKcBMXOQ.js} +1 -1
  55. package/static/assets/{NotificationsSettingsPage-CLgtsCVM.js → NotificationsSettingsPage-DETz35D7.js} +1 -1
  56. package/static/assets/PromptsSettingsPage-8--L7lw4.js +1 -0
  57. package/static/assets/{ResourceDetailPage-CMPDRdVM.js → ResourceDetailPage-BH-A0yn7.js} +1 -1
  58. package/static/assets/{ResourcesPage-DspYILfG.js → ResourcesPage-CfdKptfd.js} +1 -1
  59. package/static/assets/{RoleEditPage-DXtzicVZ.js → RoleEditPage-DfqF4tLW.js} +1 -1
  60. package/static/assets/RolePage-CCwufp_f.js +1 -0
  61. package/static/assets/{RulesSettingsPage-E8V9cexV.js → RulesSettingsPage-dzUPGors.js} +4 -4
  62. package/static/assets/{RunDetailPage-DsxkqFst.js → RunDetailPage-B9I5nrOb.js} +1 -1
  63. package/static/assets/SchedulePage-7Ufvzd34.js +4 -0
  64. package/static/assets/SkillDetailPage-DCjWVhUE.js +1 -0
  65. package/static/assets/{SkillEditPage-DwyebzFV.js → SkillEditPage-BA-ebFGI.js} +1 -1
  66. package/static/assets/{SkillsPage-CauK65X_.js → SkillsPage-QqNzKzhn.js} +2 -2
  67. package/static/assets/{SkillsSettingsPage-DXMRv3jR.js → SkillsSettingsPage-DPXiPnWO.js} +1 -1
  68. package/static/assets/SourceInput-0S84iX2C.js +1 -0
  69. package/static/assets/{TagInput-Ct-WRvTs.js → TagInput-C_2MLj_1.js} +1 -1
  70. package/static/assets/{TaskDetailPage-CApk2iBh.js → TaskDetailPage-6E7isObV.js} +2 -2
  71. package/static/assets/{TaskEditPage-NgOVShfK.js → TaskEditPage-Bd1DFoK3.js} +1 -1
  72. package/static/assets/{TasksPage-BoPrP_Rl.js → TasksPage-CeWPVVwj.js} +1 -1
  73. package/static/assets/{TeamEditPage-ChY6mYm8.js → TeamEditPage-CgYsqeq9.js} +1 -1
  74. package/static/assets/TeamPage-CEojyLvc.js +1 -0
  75. package/static/assets/{TerminalPage-CRhcscF2.js → TerminalPage-D-LJMND7.js} +1 -1
  76. package/static/assets/{TerminalSessionPage-CSCQg2sn.js → TerminalSessionPage-BGHgOQhV.js} +2 -2
  77. package/static/assets/{UserPreferencesPage-DxCSWJnS.js → UserPreferencesPage-D5nGgztl.js} +1 -1
  78. package/static/assets/{UserSettingsPage-DKkOLNPV.js → UserSettingsPage-Dv6fSWWx.js} +1 -1
  79. package/static/assets/UtilitiesPage-hCM0KDs8.js +1 -0
  80. package/static/assets/{alert-Dw_RSroN.js → alert-DxBTp_In.js} +1 -1
  81. package/static/assets/{arrow-down-UClxXzT-.js → arrow-down-Be4lZFzF.js} +1 -1
  82. package/static/assets/{arrow-left-DWmf9YJp.js → arrow-left-DzGSl0dC.js} +1 -1
  83. package/static/assets/{arrow-up-fLCh7Hvh.js → arrow-up-6HVzdiIw.js} +1 -1
  84. package/static/assets/{arrow-up-down-Btc3okb3.js → arrow-up-down-C9lUuyDO.js} +1 -1
  85. package/static/assets/{badge-vIqE5SOP.js → badge-DyF_7_dv.js} +1 -1
  86. package/static/assets/{browser-modal-DgMJTsMd.js → browser-modal-DKHn0FAC.js} +2 -2
  87. package/static/assets/{card-DPLdBoa5.js → card-DW9yx9FC.js} +1 -1
  88. package/static/assets/{chevron-left-CiNaLX-v.js → chevron-left-CJjrbO2y.js} +1 -1
  89. package/static/assets/{chevron-up-DFd-7wxW.js → chevron-up-BrSqNhfU.js} +1 -1
  90. package/static/assets/{chevrons-up-BfU70OcQ.js → chevrons-up-wQrNHZqU.js} +1 -1
  91. package/static/assets/{circle-alert-Mv00T-P2.js → circle-alert-ByPjREVD.js} +1 -1
  92. package/static/assets/{circle-check-xMiP6SLO.js → circle-check-D7peX4CI.js} +1 -1
  93. package/static/assets/{circle-check-big-BEY1IoIP.js → circle-check-big--yqXPZzU.js} +1 -1
  94. package/static/assets/{circle-play-iZZwaGbV.js → circle-play-C2th8mzN.js} +1 -1
  95. package/static/assets/{circle-x-z3iynaE7.js → circle-x-Oj6Gai3s.js} +1 -1
  96. package/static/assets/{clipboard-C8wZRPDH.js → clipboard-qigxJPlJ.js} +1 -1
  97. package/static/assets/{clock-C_9shc08.js → clock-JhtahL2B.js} +1 -1
  98. package/static/assets/{code-DH-sRhus.js → code-DcBDG3ah.js} +1 -1
  99. package/static/assets/{download-CE8b59ER.js → download-BBjLPrfj.js} +1 -1
  100. package/static/assets/{external-link-DPyKt8NE.js → external-link-DDneC3kx.js} +1 -1
  101. package/static/assets/{eye-BpGD-yoS.js → eye-Bl23BbY6.js} +1 -1
  102. package/static/assets/{folder-git-2-BIw4zbmy.js → folder-git-2-BBe22u2y.js} +1 -1
  103. package/static/assets/{globe-CUo7eHKN.js → globe-C3j3aWiD.js} +1 -1
  104. package/static/assets/{index-UXL5-kaP.js → index-0zkOcODK.js} +105 -105
  105. package/static/assets/{index-ClO9-JVh.js → index-B-9XKFgb.js} +1 -1
  106. package/static/assets/{index-Cdwx6Zps.js → index-CWt3zgDI.js} +1 -1
  107. package/static/assets/{index-Bkt1rQVV.js → index-Cbo5QxHl.js} +1 -1
  108. package/static/assets/{index-iB8oed57.js → index-D2rSjJPF.js} +1 -1
  109. package/static/assets/{index-Bfb3OTwj.js → index-DFfxOZw8.js} +1 -1
  110. package/static/assets/{index-B07hel4U.js → index-DUwRskPW.js} +1 -1
  111. package/static/assets/index-DVMcu9sQ.css +1 -0
  112. package/static/assets/{index-CpJ0uBf3.js → index-DaAZbWZV.js} +1 -1
  113. package/static/assets/{index-BCwmQxLC.js → index-DdDCTC_d.js} +1 -1
  114. package/static/assets/{index-jaRIZ6SY.js → index-DdSybLsG.js} +1 -1
  115. package/static/assets/{index-BaR4iUzg.js → index-DgFdrtDt.js} +1 -1
  116. package/static/assets/{index-CTouvf2d.js → index-DkobSVA-.js} +1 -1
  117. package/static/assets/{index-CsBxEWw5.js → index-DuWsaYa4.js} +1 -1
  118. package/static/assets/{index-CGbmjmEy.js → index-DukcrMyC.js} +1 -1
  119. package/static/assets/{index-BOKaM9K-.js → index-I6ZfnFaA.js} +1 -1
  120. package/static/assets/{index-Dkr9CBL7.js → index-QZn_aaqg.js} +1 -1
  121. package/static/assets/{index-C65b3D5_.js → index-UM1qitEs.js} +1 -1
  122. package/static/assets/{index-DZAYfTI2.js → index-r07pPAcM.js} +1 -1
  123. package/static/assets/{index-DnZKG-_7.js → index-xBQb0rMo.js} +1 -1
  124. package/static/assets/{info-D-UNBNx2.js → info-DWORrO-s.js} +1 -1
  125. package/static/assets/{label-8VKluf9w.js → label-DyhnItJm.js} +1 -1
  126. package/static/assets/{markdown-editor-DBdRsbP2.js → markdown-editor-C8LFQE7K.js} +38 -38
  127. package/static/assets/{message-square-CO8kDUed.js → message-square-CiISW36v.js} +1 -1
  128. package/static/assets/{paperclip-DlLXZbru.js → paperclip-DRufaOtA.js} +1 -1
  129. package/static/assets/{pause-zSiaxJBu.js → pause-GqIUdKFa.js} +1 -1
  130. package/static/assets/{pipeline-builders-Bkf0wt_O.js → pipeline-builders-DrEjlsbH.js} +1 -1
  131. package/static/assets/{play-DVBhRokt.js → play-CkuTY54l.js} +1 -1
  132. package/static/assets/{radio-group-CThYUcA4.js → radio-group-ClpV676y.js} +1 -1
  133. package/static/assets/{refresh-cw-tXYl1ePu.js → refresh-cw-CYBx0C_n.js} +1 -1
  134. package/static/assets/{search-BxF7Wwex.js → search-DxiQuWo1.js} +1 -1
  135. package/static/assets/{select-CyHFRA1Y.js → select-D_L7OXwN.js} +1 -1
  136. package/static/assets/{server-lRxThHjr.js → server-CgjJESGe.js} +1 -1
  137. package/static/assets/{switch-BUpDbrux.js → switch-DXojpqQ8.js} +1 -1
  138. package/static/assets/{tabs-DkvCmQEX.js → tabs-zdz4RlY5.js} +1 -1
  139. package/static/assets/{tag-CkcZNLnh.js → tag-CeaYtqPJ.js} +1 -1
  140. package/static/assets/terminal-preview-CspSfoko.js +1 -0
  141. package/static/assets/{triangle-alert-CmjG_mbF.js → triangle-alert-DTdlIh6V.js} +1 -1
  142. package/static/assets/{use-terminal-D3iV7-iC.js → use-terminal-DkVoTttR.js} +1 -1
  143. package/static/assets/{video-CY_dOujm.js → video-5zJ0jcFw.js} +1 -1
  144. package/static/index.html +2 -2
  145. package/dist/routes/api/v1/context/architecture/route.d.ts +0 -3
  146. package/dist/routes/api/v1/context/architecture/route.js +0 -245
  147. package/dist/routes/api/v1/context/project/route.d.ts +0 -3
  148. package/dist/routes/api/v1/context/project/route.js +0 -200
  149. package/static/assets/AgentsContextPage-tJ-LhFYb.js +0 -1
  150. package/static/assets/AuthSettingsPage-Bwr7uP3z.js +0 -11
  151. package/static/assets/CodePage-kp4s3wCJ.js +0 -2
  152. package/static/assets/IntegrationsSettingsPage-o7NXZGt9.js +0 -1
  153. package/static/assets/JobDetailPage-DuEiPz6X.js +0 -1
  154. package/static/assets/KnowledgeDetailPage-DFVud_VC.js +0 -1
  155. package/static/assets/KnowledgeEditPage-XG6HKK7E.js +0 -1
  156. package/static/assets/LoginPage-CUJRxwXy.js +0 -1
  157. package/static/assets/MailInboxPage-BlCG-tba.js +0 -1
  158. package/static/assets/MailProcessingModal-BJIdHOqK.js +0 -1
  159. package/static/assets/MailReadPage-MoNo_gmW.js +0 -1
  160. package/static/assets/MailSentPage-QzpuIJmT.js +0 -1
  161. package/static/assets/McpSettingsPage-BZcCGkGM.js +0 -1
  162. package/static/assets/MemoryPage-oBnyuvSf.js +0 -1
  163. package/static/assets/PromptsSettingsPage-BWaELCjG.js +0 -1
  164. package/static/assets/RolePage-DafGURGp.js +0 -1
  165. package/static/assets/SchedulePage-B2YvNDHr.js +0 -4
  166. package/static/assets/SkillDetailPage-CWkqSfuT.js +0 -1
  167. package/static/assets/SourceInput-C0iKqbQ1.js +0 -1
  168. package/static/assets/TeamPage-DH-dJhFG.js +0 -1
  169. package/static/assets/UtilitiesPage-CBNSvixW.js +0 -1
  170. package/static/assets/index-BcCuKdbf.css +0 -1
  171. package/static/assets/terminal-preview-CLWDhoOZ.js +0 -1
@@ -1,4 +1,4 @@
1
- import{c as a}from"./index-UXL5-kaP.js";/**
1
+ import{c as a}from"./index-0zkOcODK.js";/**
2
2
  * @license lucide-react v0.542.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c}from"./index-UXL5-kaP.js";/**
1
+ import{c}from"./index-0zkOcODK.js";/**
2
2
  * @license lucide-react v0.542.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as e}from"./index-UXL5-kaP.js";/**
1
+ import{c as e}from"./index-0zkOcODK.js";/**
2
2
  * @license lucide-react v0.542.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- const u="Use .nut/context/project.md and .nut/context/architecture.md for reference.";function l(e,t,n,i=!0){const s=[];return i&&(s.push(["## Task","","- Review and begin working on the following task:",` .nut/tasks/${e}.md`,"- Retrieve your firstName, lastName, and email address from: .nut/config.json and use this identity for task updates, comments, git commits, etc."].join(`
1
+ const u="Use .nut/context/role.md for reference.";function l(e,t,n,i=!0){const s=[];return i&&(s.push(["## Task","","- Review and begin working on the following task:",` .nut/tasks/${e}.md`,"- Retrieve your firstName, lastName, and email address from: .nut/config.json and use this identity for task updates, comments, git commits, etc."].join(`
2
2
  `)),s.push(["## Task Lifecycle","","1. Before beginning any work, set the task to active:",` nut task update ${e} --status active`,"","2. Work through the existing plan steps, updating each as you go:",` nut task step-update ${e} <stepId> --status active (when starting a step)`,` nut task step-update ${e} <stepId> --status done (when complete)`,` nut task step-update ${e} <stepId> --status failed --error "reason"`,` nut task step-update ${e} <stepId> --status skipped (if not applicable)`,` If no steps exist yet, add them: nut task step ${e} "Step description"`,"","3. If you need human clarification or input, block the task and stop work:",` nut task update ${e} --status blocked`,` nut task comment ${e} "Describe what you need" --author "firstName lastName"`,"","4. When implementation is complete and ready for review:",` nut task update ${e} --status review`,` nut task comment ${e} "Summary of what was done" --author "firstName lastName"`,"","### Handling Revision Requests","","If the task status is 'revision', the user has reviewed your work and left feedback.","Read the most recent comment(s) carefully, address the feedback, then set back to review:",` nut task update ${e} --status review`].join(`
3
3
  `)),s.push(["## Abilities","","Beyond task management, the following are at your disposal and should be factored into the plan where appropriate (each command has its own --help):","- Knowledge documents (for research outputs, notes, and reference material):",' - nut knowledge create "Title" --content "# Title\\n\\nContent here"'," - nut knowledge list / get / update","- Resource library (images, audio, video, or existing files):"," - nut resource ls / add ./file.png",' - nut resource image "description" --save',' - nut resource audio "description" --save',"- Skills (specialized, reusable modules with an official registry):"," - nut skill list / nut skill registry list","- Also available: git, gh, node, python"].join(`
4
4
  `)),s.push(["## Operational Rules","","- DO use the nut CLI to update task and step status as progress changes","- DO NOT edit files outside the scope of the approved task (unless instructed by the Additional Instructions below)"].join(`
@@ -1,4 +1,4 @@
1
- import{c as a}from"./index-UXL5-kaP.js";/**
1
+ import{c as a}from"./index-0zkOcODK.js";/**
2
2
  * @license lucide-react v0.542.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1 +1 @@
1
- import{r as n,be as E,al as K,af as T,j as a,ag as N,bg as U,aj as x,ak as C,bf as V,ai as g,b4 as z,ao as H,an as $,e as I,bC as W}from"./index-UXL5-kaP.js";var w="Radio",[X,j]=N(w),[Y,J]=X(w),k=n.forwardRef((r,t)=>{const{__scopeRadio:e,name:d,checked:o=!1,required:s,disabled:i,value:p="on",onCheck:f,form:R,...v}=r,[l,m]=n.useState(null),c=C(t,y=>m(y)),u=n.useRef(!1),b=l?R||!!l.closest("form"):!0;return a.jsxs(Y,{scope:e,checked:o,disabled:i,children:[a.jsx(x.button,{type:"button",role:"radio","aria-checked":o,"data-state":S(o),"data-disabled":i?"":void 0,disabled:i,value:p,...v,ref:c,onClick:g(r.onClick,y=>{o||f?.(),b&&(u.current=y.isPropagationStopped(),u.current||y.stopPropagation())})}),b&&a.jsx(P,{control:l,bubbles:!u.current,name:d,value:p,checked:o,required:s,disabled:i,form:R,style:{transform:"translateX(-100%)"}})]})});k.displayName=w;var _="RadioIndicator",G=n.forwardRef((r,t)=>{const{__scopeRadio:e,forceMount:d,...o}=r,s=J(_,e);return a.jsx(z,{present:d||s.checked,children:a.jsx(x.span,{"data-state":S(s.checked),"data-disabled":s.disabled?"":void 0,...o,ref:t})})});G.displayName=_;var Q="RadioBubbleInput",P=n.forwardRef(({__scopeRadio:r,control:t,checked:e,bubbles:d=!0,...o},s)=>{const i=n.useRef(null),p=C(i,s),f=H(e),R=$(t);return n.useEffect(()=>{const v=i.current;if(!v)return;const l=window.HTMLInputElement.prototype,c=Object.getOwnPropertyDescriptor(l,"checked").set;if(f!==e&&c){const u=new Event("click",{bubbles:d});c.call(v,e),v.dispatchEvent(u)}},[f,e,d]),a.jsx(x.input,{type:"radio","aria-hidden":!0,defaultChecked:e,...o,tabIndex:-1,ref:p,style:{...o.style,...R,position:"absolute",pointerEvents:"none",opacity:0,margin:0}})});P.displayName=Q;function S(r){return r?"checked":"unchecked"}var Z=["ArrowUp","ArrowDown","ArrowLeft","ArrowRight"],h="RadioGroup",[ee,de]=N(h,[E,j]),A=E(),D=j(),[oe,re]=ee(h),M=n.forwardRef((r,t)=>{const{__scopeRadioGroup:e,name:d,defaultValue:o,value:s,required:i=!1,disabled:p=!1,orientation:f,dir:R,loop:v=!0,onValueChange:l,...m}=r,c=A(e),u=K(R),[b,y]=T({prop:s,defaultProp:o??null,onChange:l,caller:h});return a.jsx(oe,{scope:e,name:d,required:i,disabled:p,value:b,onValueChange:y,children:a.jsx(U,{asChild:!0,...c,orientation:f,dir:u,loop:v,children:a.jsx(x.div,{role:"radiogroup","aria-required":i,"aria-orientation":f,"data-disabled":p?"":void 0,dir:u,...m,ref:t})})})});M.displayName=h;var O="RadioGroupItem",F=n.forwardRef((r,t)=>{const{__scopeRadioGroup:e,disabled:d,...o}=r,s=re(O,e),i=s.disabled||d,p=A(e),f=D(e),R=n.useRef(null),v=C(t,R),l=s.value===o.value,m=n.useRef(!1);return n.useEffect(()=>{const c=b=>{Z.includes(b.key)&&(m.current=!0)},u=()=>m.current=!1;return document.addEventListener("keydown",c),document.addEventListener("keyup",u),()=>{document.removeEventListener("keydown",c),document.removeEventListener("keyup",u)}},[]),a.jsx(V,{asChild:!0,...p,focusable:!i,active:l,children:a.jsx(k,{disabled:i,required:s.required,checked:l,...f,...o,name:s.name,ref:v,onCheck:()=>s.onValueChange(o.value),onKeyDown:g(c=>{c.key==="Enter"&&c.preventDefault()}),onFocus:g(o.onFocus,()=>{m.current&&R.current?.click()})})})});F.displayName=O;var ae="RadioGroupIndicator",L=n.forwardRef((r,t)=>{const{__scopeRadioGroup:e,...d}=r,o=D(e);return a.jsx(G,{...o,...d,ref:t})});L.displayName=ae;var q=M,B=F,te=L;const se=n.forwardRef(({className:r,...t},e)=>a.jsx(q,{className:I("grid gap-2",r),...t,ref:e}));se.displayName=q.displayName;const ne=n.forwardRef(({className:r,...t},e)=>a.jsx(B,{ref:e,className:I("aspect-square h-4 w-4 rounded-full border border-primary text-primary ring-offset-background focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",r),...t,children:a.jsx(te,{className:"flex items-center justify-center",children:a.jsx(W,{className:"h-2.5 w-2.5 fill-current text-current"})})}));ne.displayName=B.displayName;export{se as R,ne as a};
1
+ import{r as n,bi as E,ap as K,aj as T,j as a,ak as N,bk as U,an as x,ao as w,bj as V,am as g,b8 as z,as as H,ar as $,e as j,bG as W}from"./index-0zkOcODK.js";var C="Radio",[X,k]=N(C),[Y,J]=X(C),I=n.forwardRef((r,t)=>{const{__scopeRadio:e,name:d,checked:o=!1,required:s,disabled:i,value:p="on",onCheck:f,form:R,...v}=r,[l,m]=n.useState(null),c=w(t,y=>m(y)),u=n.useRef(!1),b=l?R||!!l.closest("form"):!0;return a.jsxs(Y,{scope:e,checked:o,disabled:i,children:[a.jsx(x.button,{type:"button",role:"radio","aria-checked":o,"data-state":S(o),"data-disabled":i?"":void 0,disabled:i,value:p,...v,ref:c,onClick:g(r.onClick,y=>{o||f?.(),b&&(u.current=y.isPropagationStopped(),u.current||y.stopPropagation())})}),b&&a.jsx(P,{control:l,bubbles:!u.current,name:d,value:p,checked:o,required:s,disabled:i,form:R,style:{transform:"translateX(-100%)"}})]})});I.displayName=C;var G="RadioIndicator",_=n.forwardRef((r,t)=>{const{__scopeRadio:e,forceMount:d,...o}=r,s=J(G,e);return a.jsx(z,{present:d||s.checked,children:a.jsx(x.span,{"data-state":S(s.checked),"data-disabled":s.disabled?"":void 0,...o,ref:t})})});_.displayName=G;var Q="RadioBubbleInput",P=n.forwardRef(({__scopeRadio:r,control:t,checked:e,bubbles:d=!0,...o},s)=>{const i=n.useRef(null),p=w(i,s),f=H(e),R=$(t);return n.useEffect(()=>{const v=i.current;if(!v)return;const l=window.HTMLInputElement.prototype,c=Object.getOwnPropertyDescriptor(l,"checked").set;if(f!==e&&c){const u=new Event("click",{bubbles:d});c.call(v,e),v.dispatchEvent(u)}},[f,e,d]),a.jsx(x.input,{type:"radio","aria-hidden":!0,defaultChecked:e,...o,tabIndex:-1,ref:p,style:{...o.style,...R,position:"absolute",pointerEvents:"none",opacity:0,margin:0}})});P.displayName=Q;function S(r){return r?"checked":"unchecked"}var Z=["ArrowUp","ArrowDown","ArrowLeft","ArrowRight"],h="RadioGroup",[ee,de]=N(h,[E,k]),A=E(),D=k(),[oe,re]=ee(h),M=n.forwardRef((r,t)=>{const{__scopeRadioGroup:e,name:d,defaultValue:o,value:s,required:i=!1,disabled:p=!1,orientation:f,dir:R,loop:v=!0,onValueChange:l,...m}=r,c=A(e),u=K(R),[b,y]=T({prop:s,defaultProp:o??null,onChange:l,caller:h});return a.jsx(oe,{scope:e,name:d,required:i,disabled:p,value:b,onValueChange:y,children:a.jsx(U,{asChild:!0,...c,orientation:f,dir:u,loop:v,children:a.jsx(x.div,{role:"radiogroup","aria-required":i,"aria-orientation":f,"data-disabled":p?"":void 0,dir:u,...m,ref:t})})})});M.displayName=h;var O="RadioGroupItem",F=n.forwardRef((r,t)=>{const{__scopeRadioGroup:e,disabled:d,...o}=r,s=re(O,e),i=s.disabled||d,p=A(e),f=D(e),R=n.useRef(null),v=w(t,R),l=s.value===o.value,m=n.useRef(!1);return n.useEffect(()=>{const c=b=>{Z.includes(b.key)&&(m.current=!0)},u=()=>m.current=!1;return document.addEventListener("keydown",c),document.addEventListener("keyup",u),()=>{document.removeEventListener("keydown",c),document.removeEventListener("keyup",u)}},[]),a.jsx(V,{asChild:!0,...p,focusable:!i,active:l,children:a.jsx(I,{disabled:i,required:s.required,checked:l,...f,...o,name:s.name,ref:v,onCheck:()=>s.onValueChange(o.value),onKeyDown:g(c=>{c.key==="Enter"&&c.preventDefault()}),onFocus:g(o.onFocus,()=>{m.current&&R.current?.click()})})})});F.displayName=O;var ae="RadioGroupIndicator",L=n.forwardRef((r,t)=>{const{__scopeRadioGroup:e,...d}=r,o=D(e);return a.jsx(_,{...o,...d,ref:t})});L.displayName=ae;var q=M,B=F,te=L;const se=n.forwardRef(({className:r,...t},e)=>a.jsx(q,{className:j("grid gap-2",r),...t,ref:e}));se.displayName=q.displayName;const ne=n.forwardRef(({className:r,...t},e)=>a.jsx(B,{ref:e,className:j("aspect-square h-4 w-4 rounded-full border border-primary text-primary ring-offset-background focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",r),...t,children:a.jsx(te,{className:"flex items-center justify-center",children:a.jsx(W,{className:"h-2.5 w-2.5 fill-current text-current"})})}));ne.displayName=B.displayName;export{se as R,ne as a};
@@ -1,4 +1,4 @@
1
- import{c as e}from"./index-UXL5-kaP.js";/**
1
+ import{c as e}from"./index-0zkOcODK.js";/**
2
2
  * @license lucide-react v0.542.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c}from"./index-UXL5-kaP.js";/**
1
+ import{c}from"./index-0zkOcODK.js";/**
2
2
  * @license lucide-react v0.542.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1 +1 @@
1
- import{r as o,j as e,e as r,n as d,ad as y}from"./index-UXL5-kaP.js";import{R as N,V as g,T as n,I as j,P as b,C as i,a as S,b as c,d as v,c as R,e as m,f as p,L as f,S as x}from"./index-DnZKG-_7.js";import{C}from"./chevron-up-DFd-7wxW.js";const k=N,E=g,I=o.forwardRef(({className:t,children:s,...a},l)=>e.jsxs(n,{ref:l,className:r("flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",t),...a,children:[s,e.jsx(j,{asChild:!0,children:e.jsx(d,{className:"h-4 w-4 opacity-50"})})]}));I.displayName=n.displayName;const u=o.forwardRef(({className:t,...s},a)=>e.jsx(m,{ref:a,className:r("flex cursor-default items-center justify-center py-1",t),...s,children:e.jsx(C,{className:"h-4 w-4"})}));u.displayName=m.displayName;const h=o.forwardRef(({className:t,...s},a)=>e.jsx(p,{ref:a,className:r("flex cursor-default items-center justify-center py-1",t),...s,children:e.jsx(d,{className:"h-4 w-4"})}));h.displayName=p.displayName;const B=o.forwardRef(({className:t,children:s,position:a="popper",...l},w)=>e.jsx(b,{children:e.jsxs(i,{ref:w,className:r("relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",a==="popper"&&"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",t),position:a,...l,children:[e.jsx(u,{}),e.jsx(S,{className:r("p-1",a==="popper"&&"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"),children:s}),e.jsx(h,{})]})}));B.displayName=i.displayName;const T=o.forwardRef(({className:t,...s},a)=>e.jsx(f,{ref:a,className:r("px-2 py-1.5 text-sm font-semibold",t),...s}));T.displayName=f.displayName;const V=o.forwardRef(({className:t,children:s,...a},l)=>e.jsxs(c,{ref:l,className:r("relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",t),...a,children:[e.jsx("span",{className:"absolute right-2 flex h-3.5 w-3.5 items-center justify-center",children:e.jsx(v,{children:e.jsx(y,{className:"h-4 w-4"})})}),e.jsx(R,{children:s})]}));V.displayName=c.displayName;const z=o.forwardRef(({className:t,...s},a)=>e.jsx(x,{ref:a,className:r("-mx-1 my-1 h-px bg-muted",t),...s}));z.displayName=x.displayName;export{k as S,I as a,E as b,B as c,V as d};
1
+ import{r as o,j as e,e as r,n as d,ah as y}from"./index-0zkOcODK.js";import{R as N,V as g,T as n,I as j,P as b,C as i,a as S,b as c,d as v,c as R,e as m,f as p,L as f,S as x}from"./index-xBQb0rMo.js";import{C}from"./chevron-up-BrSqNhfU.js";const k=N,E=g,I=o.forwardRef(({className:t,children:s,...a},l)=>e.jsxs(n,{ref:l,className:r("flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",t),...a,children:[s,e.jsx(j,{asChild:!0,children:e.jsx(d,{className:"h-4 w-4 opacity-50"})})]}));I.displayName=n.displayName;const u=o.forwardRef(({className:t,...s},a)=>e.jsx(m,{ref:a,className:r("flex cursor-default items-center justify-center py-1",t),...s,children:e.jsx(C,{className:"h-4 w-4"})}));u.displayName=m.displayName;const h=o.forwardRef(({className:t,...s},a)=>e.jsx(p,{ref:a,className:r("flex cursor-default items-center justify-center py-1",t),...s,children:e.jsx(d,{className:"h-4 w-4"})}));h.displayName=p.displayName;const B=o.forwardRef(({className:t,children:s,position:a="popper",...l},w)=>e.jsx(b,{children:e.jsxs(i,{ref:w,className:r("relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",a==="popper"&&"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",t),position:a,...l,children:[e.jsx(u,{}),e.jsx(S,{className:r("p-1",a==="popper"&&"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"),children:s}),e.jsx(h,{})]})}));B.displayName=i.displayName;const T=o.forwardRef(({className:t,...s},a)=>e.jsx(f,{ref:a,className:r("px-2 py-1.5 text-sm font-semibold",t),...s}));T.displayName=f.displayName;const V=o.forwardRef(({className:t,children:s,...a},l)=>e.jsxs(c,{ref:l,className:r("relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",t),...a,children:[e.jsx("span",{className:"absolute right-2 flex h-3.5 w-3.5 items-center justify-center",children:e.jsx(v,{children:e.jsx(y,{className:"h-4 w-4"})})}),e.jsx(R,{children:s})]}));V.displayName=c.displayName;const z=o.forwardRef(({className:t,...s},a)=>e.jsx(x,{ref:a,className:r("-mx-1 my-1 h-px bg-muted",t),...s}));z.displayName=x.displayName;export{k as S,I as a,E as b,B as c,V as d};
@@ -1,4 +1,4 @@
1
- import{c as e}from"./index-UXL5-kaP.js";/**
1
+ import{c as e}from"./index-0zkOcODK.js";/**
2
2
  * @license lucide-react v0.542.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1 +1 @@
1
- import{r as c,j as e,e as i}from"./index-UXL5-kaP.js";const d=c.forwardRef(({className:s,onCheckedChange:r,onChange:t,...o},n)=>{const l=a=>{t?.(a),r?.(a.target.checked)};return e.jsxs("label",{className:i("relative inline-flex cursor-pointer",s),children:[e.jsx("input",{type:"checkbox",className:"sr-only peer",onChange:l,ref:n,...o}),e.jsx("div",{className:"block bg-gray-300 w-9 h-5 rounded-full transition-colors duration-200 ease-in-out peer-checked:bg-blue-600"}),e.jsx("div",{className:"absolute left-0 top-0 bg-white w-4 h-4 rounded-full mt-0.5 ml-0.5 transition-transform duration-200 ease-in-out transform peer-checked:translate-x-4 shadow"})]})});d.displayName="Switch";export{d as S};
1
+ import{r as c,j as e,e as i}from"./index-0zkOcODK.js";const d=c.forwardRef(({className:s,onCheckedChange:r,onChange:t,...o},n)=>{const l=a=>{t?.(a),r?.(a.target.checked)};return e.jsxs("label",{className:i("relative inline-flex cursor-pointer",s),children:[e.jsx("input",{type:"checkbox",className:"sr-only peer",onChange:l,ref:n,...o}),e.jsx("div",{className:"block bg-gray-300 w-9 h-5 rounded-full transition-colors duration-200 ease-in-out peer-checked:bg-blue-600"}),e.jsx("div",{className:"absolute left-0 top-0 bg-white w-4 h-4 rounded-full mt-0.5 ml-0.5 transition-transform duration-200 ease-in-out transform peer-checked:translate-x-4 shadow"})]})});d.displayName="Switch";export{d as S};
@@ -1 +1 @@
1
- import{r as l,al as F,af as $,j as c,ag as D,b2 as V,aj as g,be as y,bg as k,bf as G,ai as m,b4 as L,e as T}from"./index-UXL5-kaP.js";var p="Tabs",[K,Q]=D(p,[y]),h=y(),[B,x]=K(p),N=l.forwardRef((e,a)=>{const{__scopeTabs:t,value:o,onValueChange:i,defaultValue:d,orientation:n="horizontal",dir:u,activationMode:b="automatic",...v}=e,r=F(u),[s,f]=$({prop:o,onChange:i,defaultProp:d??"",caller:p});return c.jsx(B,{scope:t,baseId:V(),value:s,onValueChange:f,orientation:n,dir:r,activationMode:b,children:c.jsx(g.div,{dir:r,"data-orientation":n,...v,ref:a})})});N.displayName=p;var C="TabsList",j=l.forwardRef((e,a)=>{const{__scopeTabs:t,loop:o=!0,...i}=e,d=x(C,t),n=h(t);return c.jsx(k,{asChild:!0,...n,orientation:d.orientation,dir:d.dir,loop:o,children:c.jsx(g.div,{role:"tablist","aria-orientation":d.orientation,...i,ref:a})})});j.displayName=C;var I="TabsTrigger",R=l.forwardRef((e,a)=>{const{__scopeTabs:t,value:o,disabled:i=!1,...d}=e,n=x(I,t),u=h(t),b=A(n.baseId,o),v=E(n.baseId,o),r=o===n.value;return c.jsx(G,{asChild:!0,...u,focusable:!i,active:r,children:c.jsx(g.button,{type:"button",role:"tab","aria-selected":r,"aria-controls":v,"data-state":r?"active":"inactive","data-disabled":i?"":void 0,disabled:i,id:b,...d,ref:a,onMouseDown:m(e.onMouseDown,s=>{!i&&s.button===0&&s.ctrlKey===!1?n.onValueChange(o):s.preventDefault()}),onKeyDown:m(e.onKeyDown,s=>{[" ","Enter"].includes(s.key)&&n.onValueChange(o)}),onFocus:m(e.onFocus,()=>{const s=n.activationMode!=="manual";!r&&!i&&s&&n.onValueChange(o)})})})});R.displayName=I;var w="TabsContent",_=l.forwardRef((e,a)=>{const{__scopeTabs:t,value:o,forceMount:i,children:d,...n}=e,u=x(w,t),b=A(u.baseId,o),v=E(u.baseId,o),r=o===u.value,s=l.useRef(r);return l.useEffect(()=>{const f=requestAnimationFrame(()=>s.current=!1);return()=>cancelAnimationFrame(f)},[]),c.jsx(L,{present:i||r,children:({present:f})=>c.jsx(g.div,{"data-state":r?"active":"inactive","data-orientation":u.orientation,role:"tabpanel","aria-labelledby":b,hidden:!f,id:v,tabIndex:0,...n,ref:a,style:{...e.style,animationDuration:s.current?"0s":void 0},children:f&&d})})});_.displayName=w;function A(e,a){return`${e}-trigger-${a}`}function E(e,a){return`${e}-content-${a}`}var q=N,S=j,M=R,P=_;const U=q,z=l.forwardRef(({className:e,...a},t)=>c.jsx(S,{ref:t,className:T("inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",e),...a}));z.displayName=S.displayName;const H=l.forwardRef(({className:e,...a},t)=>c.jsx(M,{ref:t,className:T("inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow",e),...a}));H.displayName=M.displayName;const O=l.forwardRef(({className:e,...a},t)=>c.jsx(P,{ref:t,className:T("mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",e),...a}));O.displayName=P.displayName;export{U as T,z as a,H as b,O as c};
1
+ import{r as l,ap as F,aj as k,j as c,ak as $,b6 as D,an as g,bi as y,bk as V,bj as G,am as m,b8 as L,e as T}from"./index-0zkOcODK.js";var p="Tabs",[K,Q]=$(p,[y]),h=y(),[B,x]=K(p),N=l.forwardRef((e,a)=>{const{__scopeTabs:t,value:o,onValueChange:i,defaultValue:d,orientation:n="horizontal",dir:u,activationMode:f="automatic",...v}=e,r=F(u),[s,b]=k({prop:o,onChange:i,defaultProp:d??"",caller:p});return c.jsx(B,{scope:t,baseId:D(),value:s,onValueChange:b,orientation:n,dir:r,activationMode:f,children:c.jsx(g.div,{dir:r,"data-orientation":n,...v,ref:a})})});N.displayName=p;var C="TabsList",j=l.forwardRef((e,a)=>{const{__scopeTabs:t,loop:o=!0,...i}=e,d=x(C,t),n=h(t);return c.jsx(V,{asChild:!0,...n,orientation:d.orientation,dir:d.dir,loop:o,children:c.jsx(g.div,{role:"tablist","aria-orientation":d.orientation,...i,ref:a})})});j.displayName=C;var I="TabsTrigger",R=l.forwardRef((e,a)=>{const{__scopeTabs:t,value:o,disabled:i=!1,...d}=e,n=x(I,t),u=h(t),f=A(n.baseId,o),v=E(n.baseId,o),r=o===n.value;return c.jsx(G,{asChild:!0,...u,focusable:!i,active:r,children:c.jsx(g.button,{type:"button",role:"tab","aria-selected":r,"aria-controls":v,"data-state":r?"active":"inactive","data-disabled":i?"":void 0,disabled:i,id:f,...d,ref:a,onMouseDown:m(e.onMouseDown,s=>{!i&&s.button===0&&s.ctrlKey===!1?n.onValueChange(o):s.preventDefault()}),onKeyDown:m(e.onKeyDown,s=>{[" ","Enter"].includes(s.key)&&n.onValueChange(o)}),onFocus:m(e.onFocus,()=>{const s=n.activationMode!=="manual";!r&&!i&&s&&n.onValueChange(o)})})})});R.displayName=I;var w="TabsContent",_=l.forwardRef((e,a)=>{const{__scopeTabs:t,value:o,forceMount:i,children:d,...n}=e,u=x(w,t),f=A(u.baseId,o),v=E(u.baseId,o),r=o===u.value,s=l.useRef(r);return l.useEffect(()=>{const b=requestAnimationFrame(()=>s.current=!1);return()=>cancelAnimationFrame(b)},[]),c.jsx(L,{present:i||r,children:({present:b})=>c.jsx(g.div,{"data-state":r?"active":"inactive","data-orientation":u.orientation,role:"tabpanel","aria-labelledby":f,hidden:!b,id:v,tabIndex:0,...n,ref:a,style:{...e.style,animationDuration:s.current?"0s":void 0},children:b&&d})})});_.displayName=w;function A(e,a){return`${e}-trigger-${a}`}function E(e,a){return`${e}-content-${a}`}var q=N,S=j,M=R,P=_;const U=q,z=l.forwardRef(({className:e,...a},t)=>c.jsx(S,{ref:t,className:T("inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",e),...a}));z.displayName=S.displayName;const H=l.forwardRef(({className:e,...a},t)=>c.jsx(M,{ref:t,className:T("inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow",e),...a}));H.displayName=M.displayName;const O=l.forwardRef(({className:e,...a},t)=>c.jsx(P,{ref:t,className:T("mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",e),...a}));O.displayName=P.displayName;export{U as T,z as a,H as b,O as c};
@@ -1,4 +1,4 @@
1
- import{c}from"./index-UXL5-kaP.js";/**
1
+ import{c}from"./index-0zkOcODK.js";/**
2
2
  * @license lucide-react v0.542.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -0,0 +1 @@
1
+ import{r as t,a7 as M,j as m}from"./index-0zkOcODK.js";import{x as T,a as k}from"./xterm-DTxiCjtJ.js";function B(n){if(!n||typeof n!="object")return!1;const i=n,u=i.type==="snapshot"||i.type==="data",l=i.data===void 0||typeof i.data=="string";return u&&l}function N({sessionId:n,className:i,heightPx:u=160,maxScrollback:l=200}){const b=t.useRef(null),v=t.useRef(null),w=t.useRef(null),x=t.useRef(null),[R,S]=t.useState(!0),c=t.useRef([]),a=t.useRef(null);return t.useEffect(()=>{const o=b.current;if(!o||!n)return;const e=new T.Terminal({disableStdin:!0,cursorBlink:!1,convertEol:!0,scrollback:Math.max(50,Math.min(l,1e3)),fontSize:12,fontFamily:"'IBM Plex Mono', 'Source Code Pro', 'Fira Code', ui-monospace, Menlo, Monaco, monospace",lineHeight:1.25,letterSpacing:.3,theme:{background:"#1a1b26",foreground:"#c0caf5",cursor:"#c0caf5",selectionBackground:"#33467c",black:"#15161e",red:"#f7768e",green:"#9ece6a",yellow:"#e0af68",blue:"#7aa2f7",magenta:"#bb9af7",cyan:"#7dcfff",white:"#a9b1d6",brightBlack:"#414868",brightRed:"#f7768e",brightGreen:"#9ece6a",brightYellow:"#e0af68",brightBlue:"#7aa2f7",brightMagenta:"#bb9af7",brightCyan:"#7dcfff",brightWhite:"#c0caf5"}}),h=new k.FitAddon;e.loadAddon(h),e.open(o),o.style.height=`${u}px`,v.current=e,w.current=h;const f=()=>{try{const r=o.getBoundingClientRect();r.width>8&&r.height>8&&e.element&&h.fit()}catch{}},j=setTimeout(()=>f(),100),p=new ResizeObserver(()=>f());p.observe(o);const y=()=>{document.visibilityState==="visible"&&setTimeout(f,50)};document.addEventListener("visibilitychange",y);const d=new WebSocket(`${M}/ws/terminal-preview/${n}`);x.current=d,d.onopen=()=>S(!1);const E=()=>{a.current=null;const r=c.current;if(r.length){c.current=[];try{e.write(r.join(""))}catch{}}},F=()=>{a.current===null&&(a.current=requestAnimationFrame(E))};return d.onmessage=r=>{let g;try{g=JSON.parse(r.data)}catch{return}if(!B(g))return;const s=g;if(s?.type==="snapshot"){if(e.reset(),c.current=[],s.data)try{e.write(s.data)}catch{}f()}else s?.type==="data"&&s.data&&(c.current.push(String(s.data)),F())},()=>{clearTimeout(j),p.disconnect(),document.removeEventListener("visibilitychange",y);try{d.close()}catch{}a.current!==null&&cancelAnimationFrame(a.current),a.current=null,c.current=[],e.dispose()}},[n,u,l]),m.jsxs("div",{className:`relative w-full ${i||""}`.trim(),children:[R&&m.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-gray-50/60 z-10",children:m.jsx("div",{className:"text-xs text-muted-foreground",children:"Loading preview…"})}),m.jsx("div",{ref:b,className:"border border-muted rounded overflow-hidden"})]})}export{N as T};
@@ -1,4 +1,4 @@
1
- import{c as e}from"./index-UXL5-kaP.js";/**
1
+ import{c as e}from"./index-0zkOcODK.js";/**
2
2
  * @license lucide-react v0.542.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1 +1 @@
1
- import{r as i,ac as v,A as f}from"./index-UXL5-kaP.js";function j(){const[y,p]=i.useState([]),[m,c]=i.useState(!1),[d,o]=i.useState(null),{refresh:w}=v(),S=i.useCallback(async(s,n)=>{try{c(!0),o(null);const e=await fetch(`${f}/api/v1/terminal/${s}/create`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({startupCommand:n})});if(!e.ok){const t=await e.json();throw new Error(t.error||"Failed to create terminal session")}const r=await e.json();return await w(),r.sessionId}catch(e){const r=e instanceof Error?e.message:"Unknown error";return o(r),null}finally{c(!1)}},[w]),g=i.useCallback(async s=>{try{c(!0),o(null);let n;if(s.startsWith("session-")){const r=s.split("-");n=`${r[0]}-${r[1]}`}else{const r=s.split("-");n=`${r[0]}-${r[1]}`}const e=await fetch(`${f}/api/v1/terminal/${n}/destroy`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sessionId:s})});if(!e.ok){const r=await e.json();throw new Error(r.error||"Failed to destroy terminal session")}return p(r=>r.filter(t=>t.id!==s)),await w(),!0}catch(n){const e=n instanceof Error?n.message:"Unknown error";return o(e),!1}finally{c(!1)}},[w]),$=i.useCallback(async(s,n,e)=>{try{o(null);let r;if(s.startsWith("session-")){const a=s.split("-");r=`${a[0]}-${a[1]}`}else{const a=s.split("-");r=`${a[0]}-${a[1]}`}const t=await fetch(`${f}/api/v1/terminal/${r}/resize`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sessionId:s,cols:n,rows:e})});if(!t.ok){const a=await t.json();throw new Error(a.error||"Failed to resize terminal session")}return!0}catch(r){const t=r instanceof Error?r.message:"Unknown error";return o(t),!1}},[]),k=i.useCallback(async(s,n,e)=>{try{c(!0),o(null);const r=new URLSearchParams;s&&r.set("taskId",s),n&&(r.set("withPreview","true"),e&&Number.isFinite(e)&&r.set("lines",String(e)));const t=`${f}/api/v1/terminal/sessions${r.toString()?`?${r.toString()}`:""}`,a=await fetch(t);if(!a.ok){const l=await a.json();throw new Error(l.error||"Failed to fetch terminal sessions")}const u=await a.json();p(u.sessions)}catch(r){const t=r instanceof Error?r.message:"Unknown error";o(t)}finally{c(!1)}},[]),E=i.useCallback(async(s,n=8)=>{try{o(null);const e=new URLSearchParams;e.set("sessionId",s),e.set("withPreview","true"),e.set("lines",String(n)),e.set("colorize","true");const r=`${f}/api/v1/terminal/sessions?${e.toString()}`,t=await fetch(r);if(!t.ok){const l=await t.json().catch(()=>({}));throw new Error(l.error||"Failed to fetch preview")}const a=await t.json(),u=Array.isArray(a?.sessions)&&a.sessions[0]?.preview?a.sessions[0].preview:[];return p(l=>l.map(h=>h.id===s?{...h,preview:u}:h)),u}catch(e){const r=e instanceof Error?e.message:"Unknown error";return o(r),[]}},[]);return{sessions:y,loading:m,error:d,createSession:S,destroySession:g,resizeSession:$,refreshSessions:k,fetchPreview:E}}export{j as u};
1
+ import{r as i,ag as v,A as f}from"./index-0zkOcODK.js";function j(){const[y,p]=i.useState([]),[m,c]=i.useState(!1),[d,o]=i.useState(null),{refresh:w}=v(),S=i.useCallback(async(s,n)=>{try{c(!0),o(null);const e=await fetch(`${f}/api/v1/terminal/${s}/create`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({startupCommand:n})});if(!e.ok){const t=await e.json();throw new Error(t.error||"Failed to create terminal session")}const r=await e.json();return await w(),r.sessionId}catch(e){const r=e instanceof Error?e.message:"Unknown error";return o(r),null}finally{c(!1)}},[w]),g=i.useCallback(async s=>{try{c(!0),o(null);let n;if(s.startsWith("session-")){const r=s.split("-");n=`${r[0]}-${r[1]}`}else{const r=s.split("-");n=`${r[0]}-${r[1]}`}const e=await fetch(`${f}/api/v1/terminal/${n}/destroy`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sessionId:s})});if(!e.ok){const r=await e.json();throw new Error(r.error||"Failed to destroy terminal session")}return p(r=>r.filter(t=>t.id!==s)),await w(),!0}catch(n){const e=n instanceof Error?n.message:"Unknown error";return o(e),!1}finally{c(!1)}},[w]),$=i.useCallback(async(s,n,e)=>{try{o(null);let r;if(s.startsWith("session-")){const a=s.split("-");r=`${a[0]}-${a[1]}`}else{const a=s.split("-");r=`${a[0]}-${a[1]}`}const t=await fetch(`${f}/api/v1/terminal/${r}/resize`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sessionId:s,cols:n,rows:e})});if(!t.ok){const a=await t.json();throw new Error(a.error||"Failed to resize terminal session")}return!0}catch(r){const t=r instanceof Error?r.message:"Unknown error";return o(t),!1}},[]),k=i.useCallback(async(s,n,e)=>{try{c(!0),o(null);const r=new URLSearchParams;s&&r.set("taskId",s),n&&(r.set("withPreview","true"),e&&Number.isFinite(e)&&r.set("lines",String(e)));const t=`${f}/api/v1/terminal/sessions${r.toString()?`?${r.toString()}`:""}`,a=await fetch(t);if(!a.ok){const l=await a.json();throw new Error(l.error||"Failed to fetch terminal sessions")}const u=await a.json();p(u.sessions)}catch(r){const t=r instanceof Error?r.message:"Unknown error";o(t)}finally{c(!1)}},[]),E=i.useCallback(async(s,n=8)=>{try{o(null);const e=new URLSearchParams;e.set("sessionId",s),e.set("withPreview","true"),e.set("lines",String(n)),e.set("colorize","true");const r=`${f}/api/v1/terminal/sessions?${e.toString()}`,t=await fetch(r);if(!t.ok){const l=await t.json().catch(()=>({}));throw new Error(l.error||"Failed to fetch preview")}const a=await t.json(),u=Array.isArray(a?.sessions)&&a.sessions[0]?.preview?a.sessions[0].preview:[];return p(l=>l.map(h=>h.id===s?{...h,preview:u}:h)),u}catch(e){const r=e instanceof Error?e.message:"Unknown error";return o(r),[]}},[]);return{sessions:y,loading:m,error:d,createSession:S,destroySession:g,resizeSession:$,refreshSessions:k,fetchPreview:E}}export{j as u};
@@ -1,4 +1,4 @@
1
- import{c as e}from"./index-UXL5-kaP.js";/**
1
+ import{c as e}from"./index-0zkOcODK.js";/**
2
2
  * @license lucide-react v0.542.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
package/static/index.html CHANGED
@@ -8,8 +8,8 @@
8
8
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
9
9
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap" rel="stylesheet">
10
10
  <title>Coconut - Agentic Development Environment</title>
11
- <script type="module" crossorigin src="/assets/index-UXL5-kaP.js"></script>
12
- <link rel="stylesheet" crossorigin href="/assets/index-BcCuKdbf.css">
11
+ <script type="module" crossorigin src="/assets/index-0zkOcODK.js"></script>
12
+ <link rel="stylesheet" crossorigin href="/assets/index-DVMcu9sQ.css">
13
13
  </head>
14
14
  <body class="font-inter">
15
15
  <div id="root"></div>
@@ -1,3 +0,0 @@
1
- import { Hono } from 'hono';
2
- declare const app: Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
3
- export default app;
@@ -1,245 +0,0 @@
1
- import { Hono } from 'hono';
2
- import { promises as fs } from 'fs';
3
- import path from 'path';
4
- import matter from 'gray-matter';
5
- import { findGaitDirectory } from '../../../../../lib/gait-path.js';
6
- import { getLogger, ContextKinds } from '@lovelybunch/core/logging';
7
- import { requireAuth } from '../../../../../middleware/auth.js';
8
- // Helper function to generate a simple summary from content
9
- function generateSummary(content, maxLines = 3, maxChars = 200) {
10
- // Remove markdown formatting for cleaner summary
11
- const cleanContent = content
12
- .replace(/^#+\s+/gm, '') // Remove headings
13
- .replace(/[*_`]/g, '') // Remove bold, italic, code
14
- .replace(/\[([^\]]+)\]\([^)]+\)/g, '$1') // Convert links to text
15
- .trim();
16
- // Get first few lines
17
- const lines = cleanContent.split('\n').filter(line => line.trim().length > 0);
18
- const summary = lines.slice(0, maxLines).join(' ');
19
- // Truncate if too long
20
- return summary.length > maxChars
21
- ? summary.substring(0, maxChars) + '...'
22
- : summary;
23
- }
24
- const app = new Hono();
25
- async function getArchitecturePath() {
26
- const gaitDir = await findGaitDirectory();
27
- if (!gaitDir)
28
- return null;
29
- return path.join(gaitDir, 'context');
30
- }
31
- /**
32
- * GET /api/v1/context/architecture
33
- * Load architecture document
34
- */
35
- app.get('/', async (c) => {
36
- try {
37
- const architecturePath = await getArchitecturePath();
38
- if (!architecturePath) {
39
- return c.json({
40
- success: false,
41
- error: 'GAIT directory not found'
42
- }, 404);
43
- }
44
- // Ensure directory exists
45
- await fs.mkdir(architecturePath, { recursive: true });
46
- // Look for architecture.md file
47
- const filePath = path.join(architecturePath, 'architecture.md');
48
- try {
49
- const fileContent = await fs.readFile(filePath, 'utf-8');
50
- const { data, content } = matter(fileContent);
51
- // Extract title from first heading or use default
52
- const title = content.match(/^#\s+(.+)$/m)?.[1] || 'Architecture Overview';
53
- const document = {
54
- filename: 'architecture.md',
55
- metadata: {
56
- ...data,
57
- updated: data.updated || new Date().toISOString().split('T')[0],
58
- type: 'architecture',
59
- category: 'design',
60
- tags: data.tags || []
61
- },
62
- content,
63
- title
64
- };
65
- return c.json({
66
- success: true,
67
- document
68
- });
69
- }
70
- catch (fileError) {
71
- // If file doesn't exist, return default content
72
- const defaultContent = `# Architecture Overview
73
-
74
- This document describes the overall architecture and design patterns used in this project.
75
-
76
- ## System Architecture
77
-
78
- Describe the high-level system architecture, including major components and their relationships.
79
-
80
- ## Design Patterns
81
-
82
- Document the key design patterns and architectural principles followed in this project.
83
-
84
- ### Frontend Architecture
85
-
86
- - Component structure
87
- - State management
88
- - Routing approach
89
- - UI/UX patterns
90
-
91
- ### Backend Architecture
92
-
93
- - API design
94
- - Data layer
95
- - Service architecture
96
- - Authentication & authorization
97
-
98
- ## Data Flow
99
-
100
- Explain how data flows through the system, including:
101
-
102
- - Request/response cycles
103
- - Data transformations
104
- - Caching strategies
105
- - Error handling
106
-
107
- ## Technology Decisions
108
-
109
- Document key technology choices and the reasoning behind them:
110
-
111
- - Framework selections
112
- - Database choices
113
- - Third-party integrations
114
- - Development tools
115
-
116
- ## Deployment Architecture
117
-
118
- Describe the deployment strategy and infrastructure:
119
-
120
- - Environment setup
121
- - CI/CD pipeline
122
- - Monitoring and logging
123
- - Scaling considerations
124
-
125
- ## Security Considerations
126
-
127
- Outline security measures and best practices:
128
-
129
- - Authentication mechanisms
130
- - Data protection
131
- - API security
132
- - Infrastructure security
133
-
134
- ## Performance Considerations
135
-
136
- Document performance optimization strategies:
137
-
138
- - Caching layers
139
- - Database optimization
140
- - Frontend performance
141
- - Monitoring and metrics
142
- `;
143
- const document = {
144
- filename: 'architecture.md',
145
- metadata: {
146
- version: '1.0',
147
- updated: new Date().toISOString().split('T')[0],
148
- type: 'architecture',
149
- category: 'design',
150
- tags: []
151
- },
152
- content: defaultContent,
153
- title: 'Architecture Overview'
154
- };
155
- return c.json({
156
- success: true,
157
- document
158
- });
159
- }
160
- }
161
- catch (error) {
162
- console.error('Error loading architecture document:', error);
163
- return c.json({
164
- success: false,
165
- error: 'Failed to load architecture document'
166
- }, 500);
167
- }
168
- });
169
- /**
170
- * PUT /api/v1/context/architecture
171
- * Update architecture document
172
- */
173
- app.put('/', async (c) => {
174
- try {
175
- const body = await c.req.json();
176
- if (!body.content) {
177
- return c.json({ success: false, error: 'Content is required' }, 400);
178
- }
179
- const architecturePath = await getArchitecturePath();
180
- if (!architecturePath) {
181
- return c.json({ success: false, error: 'GAIT directory not found' }, 404);
182
- }
183
- await fs.mkdir(architecturePath, { recursive: true });
184
- const filePath = path.join(architecturePath, 'architecture.md');
185
- // Read current content if it exists
186
- let currentData = {};
187
- try {
188
- const currentContent = await fs.readFile(filePath, 'utf-8');
189
- const { data } = matter(currentContent);
190
- currentData = data;
191
- }
192
- catch {
193
- // File doesn't exist, use defaults
194
- }
195
- // Prepare updated metadata
196
- const updatedMetadata = {
197
- ...currentData,
198
- ...body.metadata,
199
- updated: new Date().toISOString().split('T')[0],
200
- type: 'architecture',
201
- category: 'design',
202
- version: currentData.version || '1.0'
203
- };
204
- // Create the markdown content with frontmatter
205
- const fileContent = matter.stringify(body.content, updatedMetadata);
206
- await fs.writeFile(filePath, fileContent, 'utf-8');
207
- // Extract updated title
208
- const title = body.title ||
209
- body.content.match(/^#\s+(.+)$/m)?.[1] ||
210
- 'Architecture Overview';
211
- // Log architecture update event
212
- try {
213
- const session = await requireAuth(c);
214
- const actor = session ? `human:${session.email}` : "human:unknown";
215
- const logger = getLogger();
216
- logger.log({
217
- kind: ContextKinds.ARCHITECTURE_UPDATE,
218
- actor,
219
- subject: `context:architecture.md`,
220
- tags: ["context", "architecture"],
221
- payload: {
222
- title,
223
- summary: generateSummary(body.content),
224
- }
225
- });
226
- }
227
- catch (logError) {
228
- console.error('Error logging architecture update:', logError);
229
- }
230
- return c.json({
231
- success: true,
232
- document: {
233
- filename: 'architecture.md',
234
- title,
235
- metadata: updatedMetadata,
236
- content: body.content
237
- }
238
- });
239
- }
240
- catch (error) {
241
- console.error('Error updating architecture document:', error);
242
- return c.json({ success: false, error: 'Failed to update architecture document' }, 500);
243
- }
244
- });
245
- export default app;
@@ -1,3 +0,0 @@
1
- import { Hono } from 'hono';
2
- declare const app: Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
3
- export default app;
@@ -1,200 +0,0 @@
1
- import { Hono } from 'hono';
2
- import { promises as fs } from 'fs';
3
- import path from 'path';
4
- import matter from 'gray-matter';
5
- import { findGaitDirectory } from '../../../../../lib/gait-path.js';
6
- import { getLogger, ContextKinds } from '@lovelybunch/core/logging';
7
- import { requireAuth } from '../../../../../middleware/auth.js';
8
- // Helper function to generate a simple summary from content
9
- function generateSummary(content, maxLines = 3, maxChars = 200) {
10
- // Remove markdown formatting for cleaner summary
11
- const cleanContent = content
12
- .replace(/^#+\s+/gm, '') // Remove headings
13
- .replace(/[*_`]/g, '') // Remove bold, italic, code
14
- .replace(/\[([^\]]+)\]\([^)]+\)/g, '$1') // Convert links to text
15
- .trim();
16
- // Get first few lines
17
- const lines = cleanContent.split('\n').filter(line => line.trim().length > 0);
18
- const summary = lines.slice(0, maxLines).join(' ');
19
- // Truncate if too long
20
- return summary.length > maxChars
21
- ? summary.substring(0, maxChars) + '...'
22
- : summary;
23
- }
24
- const app = new Hono();
25
- async function getProjectPath() {
26
- const gaitDir = await findGaitDirectory();
27
- if (!gaitDir)
28
- return null;
29
- return path.join(gaitDir, 'context');
30
- }
31
- /**
32
- * GET /api/v1/context/project
33
- * Load project overview document
34
- */
35
- app.get('/', async (c) => {
36
- try {
37
- const projectPath = await getProjectPath();
38
- if (!projectPath) {
39
- return c.json({
40
- success: false,
41
- error: 'GAIT directory not found'
42
- }, 404);
43
- }
44
- // Ensure directory exists
45
- await fs.mkdir(projectPath, { recursive: true });
46
- // Look for project.md file
47
- const filePath = path.join(projectPath, 'project.md');
48
- try {
49
- const fileContent = await fs.readFile(filePath, 'utf-8');
50
- const { data, content } = matter(fileContent);
51
- // Extract title from first heading or use default
52
- const title = content.match(/^#\s+(.+)$/m)?.[1] || 'Project Overview';
53
- const document = {
54
- filename: 'project.md',
55
- metadata: {
56
- ...data,
57
- updated: data.updated || new Date().toISOString().split('T')[0],
58
- type: 'project',
59
- category: 'overview',
60
- tags: data.tags || []
61
- },
62
- content,
63
- title
64
- };
65
- return c.json({
66
- success: true,
67
- document
68
- });
69
- }
70
- catch (fileError) {
71
- // If file doesn't exist, return default content
72
- const defaultContent = `# Project Overview
73
-
74
- This document provides an overview of the project, including its purpose, goals, and key information.
75
-
76
- ## Purpose
77
-
78
- Describe the main purpose and objectives of this project.
79
-
80
- ## Key Features
81
-
82
- - Feature 1
83
- - Feature 2
84
- - Feature 3
85
-
86
- ## Technology Stack
87
-
88
- List the main technologies, frameworks, and tools used in this project.
89
-
90
- ## Getting Started
91
-
92
- Provide instructions for setting up and running the project locally.
93
-
94
- ## Documentation
95
-
96
- Links to additional documentation, guides, and resources.
97
- `;
98
- const document = {
99
- filename: 'project.md',
100
- metadata: {
101
- version: '1.0',
102
- updated: new Date().toISOString().split('T')[0],
103
- type: 'project',
104
- category: 'overview',
105
- tags: []
106
- },
107
- content: defaultContent,
108
- title: 'Project Overview'
109
- };
110
- return c.json({
111
- success: true,
112
- document
113
- });
114
- }
115
- }
116
- catch (error) {
117
- console.error('Error loading project document:', error);
118
- return c.json({
119
- success: false,
120
- error: 'Failed to load project document'
121
- }, 500);
122
- }
123
- });
124
- /**
125
- * PUT /api/v1/context/project
126
- * Update project overview document
127
- */
128
- app.put('/', async (c) => {
129
- try {
130
- const body = await c.req.json();
131
- if (!body.content) {
132
- return c.json({ success: false, error: 'Content is required' }, 400);
133
- }
134
- const projectPath = await getProjectPath();
135
- if (!projectPath) {
136
- return c.json({ success: false, error: 'GAIT directory not found' }, 404);
137
- }
138
- await fs.mkdir(projectPath, { recursive: true });
139
- const filePath = path.join(projectPath, 'project.md');
140
- // Read current content if it exists
141
- let currentData = {};
142
- try {
143
- const currentContent = await fs.readFile(filePath, 'utf-8');
144
- const { data } = matter(currentContent);
145
- currentData = data;
146
- }
147
- catch {
148
- // File doesn't exist, use defaults
149
- }
150
- // Prepare updated metadata
151
- const updatedMetadata = {
152
- ...currentData,
153
- ...body.metadata,
154
- updated: new Date().toISOString().split('T')[0],
155
- type: 'project',
156
- category: 'overview',
157
- version: currentData.version || '1.0'
158
- };
159
- // Create the markdown content with frontmatter
160
- const fileContent = matter.stringify(body.content, updatedMetadata);
161
- await fs.writeFile(filePath, fileContent, 'utf-8');
162
- // Extract updated title
163
- const title = body.title ||
164
- body.content.match(/^#\s+(.+)$/m)?.[1] ||
165
- 'Project Overview';
166
- // Log project update event
167
- try {
168
- const session = await requireAuth(c);
169
- const actor = session ? `human:${session.email}` : "human:unknown";
170
- const logger = getLogger();
171
- logger.log({
172
- kind: ContextKinds.PROJECT_UPDATE,
173
- actor,
174
- subject: `context:project.md`,
175
- tags: ["context", "project"],
176
- payload: {
177
- title,
178
- summary: generateSummary(body.content),
179
- }
180
- });
181
- }
182
- catch (logError) {
183
- console.error('Error logging project update:', logError);
184
- }
185
- return c.json({
186
- success: true,
187
- document: {
188
- filename: 'project.md',
189
- title,
190
- metadata: updatedMetadata,
191
- content: body.content
192
- }
193
- });
194
- }
195
- catch (error) {
196
- console.error('Error updating project document:', error);
197
- return c.json({ success: false, error: 'Failed to update project document' }, 500);
198
- }
199
- });
200
- export default app;