forge-openclaw-plugin 0.2.101 → 0.2.102

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 (188) hide show
  1. package/dist/assets/{activity-page-CpjuNSHw.js → activity-page-CgF7K2ww.js} +1 -1
  2. package/dist/assets/ai-surface-workspace-xtB5RFQu.js +1 -0
  3. package/dist/assets/atlas-panel-B3dPHCmZ.js +1 -0
  4. package/dist/assets/{board-BkDRaMp6.js → board-DqHzdCPQ.js} +1 -1
  5. package/dist/assets/{calendar-page-DNNt6lfz.js → calendar-page-C1Wfd2Fy.js} +1 -1
  6. package/dist/assets/{calendar-rules-DNJFNsxi.js → calendar-rules-CaZXtlxt.js} +1 -1
  7. package/dist/assets/calendar-week-toolbar-BZ_-X3Wb.js +1 -0
  8. package/dist/assets/{charts-P7EVhIog.js → charts-FcU0F3XV.js} +8 -8
  9. package/dist/assets/{companion-sync-lab-page-KxEDigM6.js → companion-sync-lab-page-NgeK-O-P.js} +1 -1
  10. package/dist/assets/daily-metrics-dashboard-BMyL0Qr4.js +1 -0
  11. package/dist/assets/{entity-note-count-link-DrhjJZ4i.js → entity-note-count-link-BrS1-O0o.js} +1 -1
  12. package/dist/assets/entity-notes-surface-CBylYDwy.js +1 -0
  13. package/dist/assets/{execution-board-D07gOocB.js → execution-board-CpO2ch6v.js} +1 -1
  14. package/dist/assets/faceted-token-search-D7xPWfOl.js +1 -0
  15. package/dist/assets/flagship-signal-deck-BEFKOhvx.js +1 -0
  16. package/dist/assets/{floating-action-menu-Fs_ZiUMo.js → floating-action-menu-zzC2r0Ob.js} +1 -1
  17. package/dist/assets/{forms-BFlTgZ3W.js → forms-CmLAyGqz.js} +1 -1
  18. package/dist/assets/{goal-detail-page-CqLiNz4f.js → goal-detail-page-JK_Nva8e.js} +1 -1
  19. package/dist/assets/goals-page-yeoJ06Vw.js +1 -0
  20. package/dist/assets/{graph-D6JLqDbD.js → graph-BTa79qum.js} +14 -14
  21. package/dist/assets/{habits-page-BJxagdzx.js → habits-page-Dx5EhkJi.js} +1 -1
  22. package/dist/assets/index-BHIKoiZ6.js +19 -0
  23. package/dist/assets/index-H8R-ABM3.css +1 -0
  24. package/dist/assets/insight-flow-dialog-BtIQXXsS.js +1 -0
  25. package/dist/assets/{insights-page-D6rOa7uk.js → insights-page-CujrosD_.js} +1 -1
  26. package/dist/assets/{kanban-page-XQ7Se6dH.js → kanban-page-Q9NuIz5w.js} +1 -1
  27. package/dist/assets/knowledge-graph-page-DaJmlvvM.js +1 -0
  28. package/dist/assets/{life-force-page-Dy0JTS2G.js → life-force-page-BGDkKfbJ.js} +1 -1
  29. package/dist/assets/{life-force-workspace-OfyB9HJM.js → life-force-workspace-CLVexVnb.js} +1 -1
  30. package/dist/assets/{maps-ClgJoCjz.js → maps-CF1RagUX.js} +1 -1
  31. package/dist/assets/metric-tile-4iMd_WnJ.js +1 -0
  32. package/dist/assets/{motion-BeD44FeG.js → motion-CfdU2F35.js} +1 -1
  33. package/dist/assets/movement-page-ClaoTNuX.js +1 -0
  34. package/dist/assets/note-markdown-CsGQhQXF.js +3 -0
  35. package/dist/assets/note-tags-input-DdZi93tj.js +1 -0
  36. package/dist/assets/notes-page-DYI8s3NN.js +1 -0
  37. package/dist/assets/{open-in-graph-button-IXe9SGth.js → open-in-graph-button-C0TGev7c.js} +1 -1
  38. package/dist/assets/orbit-map-DVXkfQdd.js +1 -0
  39. package/dist/assets/overview-page-BwMlFQKX.js +1 -0
  40. package/dist/assets/page-hero-oFHaAjtL.js +1 -0
  41. package/dist/assets/pill-cluster-7UZd_lHp.js +1 -0
  42. package/dist/assets/{preference-entity-handoff-button-5PzUn42S.js → preference-entity-handoff-button-DOKV9bZc.js} +1 -1
  43. package/dist/assets/preferences-page-BrKEkmfD.js +1 -0
  44. package/dist/assets/{project-collections-xPz2mlRr.js → project-collections-CZagCmeH.js} +1 -1
  45. package/dist/assets/{project-detail-page-BXK5-4xW.js → project-detail-page-DogvVNEn.js} +1 -1
  46. package/dist/assets/{project-management-hierarchy-page-DtRpMABw.js → project-management-hierarchy-page-Dr7hW9PW.js} +1 -1
  47. package/dist/assets/{project-management-section-nav-P3ixzPa-.js → project-management-section-nav-BLdAgTge.js} +1 -1
  48. package/dist/assets/{projects-page-C5ViRuf4.js → projects-page-UKrby_5-.js} +1 -1
  49. package/dist/assets/psyche-behaviors-page-BeVlXvbj.js +5 -0
  50. package/dist/assets/psyche-flashcards-page-CqAWCO4E.js +1 -0
  51. package/dist/assets/psyche-goal-map-page-IyNnbk_W.js +1 -0
  52. package/dist/assets/psyche-graph-IkUQRaDK.js +1 -0
  53. package/dist/assets/{psyche-metrics-page-CuR9oqEy.js → psyche-metrics-page-uai0a7Lx.js} +1 -1
  54. package/dist/assets/psyche-mode-guide-page-C7p-ABiF.js +1 -0
  55. package/dist/assets/psyche-modes-page-CLQ5V3w0.js +1 -0
  56. package/dist/assets/psyche-page-NQBHkkpU.js +1 -0
  57. package/dist/assets/psyche-patterns-page-BkRiNpI_.js +5 -0
  58. package/dist/assets/psyche-questionnaire-builder-page-Du-7HwPC.js +1 -0
  59. package/dist/assets/psyche-questionnaire-detail-page-C5-yf8MF.js +1 -0
  60. package/dist/assets/psyche-questionnaire-run-detail-page-CoSH5O6R.js +1 -0
  61. package/dist/assets/psyche-questionnaire-run-page-ChI7c1wy.js +1 -0
  62. package/dist/assets/psyche-questionnaires-page-xUcJJzbI.js +1 -0
  63. package/dist/assets/psyche-report-detail-page-BPrZCFZS.js +3 -0
  64. package/dist/assets/psyche-reports-page-D2EXJmm6.js +1 -0
  65. package/dist/assets/{psyche-schemas-HFmg37Wj.js → psyche-schemas-RcZYaokx.js} +1 -1
  66. package/dist/assets/psyche-schemas-beliefs-page-h0ooZ1lp.js +9 -0
  67. package/dist/assets/psyche-screen-time-page-_3-4LikV.js +1 -0
  68. package/dist/assets/psyche-self-observation-page-BdbCsgR5.js +1 -0
  69. package/dist/assets/psyche-values-page-DuUVki5e.js +5 -0
  70. package/dist/assets/report-chain-fields-BBMz0sGI.js +1 -0
  71. package/dist/assets/{rewards-page-DmC4R_Ps.js → rewards-page-PZFPa6rR.js} +1 -1
  72. package/dist/assets/{scheduling-rules-editor-D02s70hr.js → scheduling-rules-editor-B9KNKsQz.js} +1 -1
  73. package/dist/assets/schema-badge-D93RcG36.js +1 -0
  74. package/dist/assets/schema-visuals-CvC9a3i6.js +1 -0
  75. package/dist/assets/select-menu-Cdq7foRu.js +1 -0
  76. package/dist/assets/{settings-agents-page-C_v_hMJF.js → settings-agents-page-DPx2F6wf.js} +3 -3
  77. package/dist/assets/{settings-bin-page-DY5bg81n.js → settings-bin-page-COwP3gjo.js} +1 -1
  78. package/dist/assets/settings-calendar-page-C-ghE0YT.js +5 -0
  79. package/dist/assets/{settings-data-page-CHRQFU9H.js → settings-data-page-CBubzKBw.js} +1 -1
  80. package/dist/assets/{settings-logs-page-B04pUwEv.js → settings-logs-page-uOuXMeBm.js} +1 -1
  81. package/dist/assets/{settings-mobile-page-D9kTlYDS.js → settings-mobile-page-C5rfj8_r.js} +1 -1
  82. package/dist/assets/settings-models-page-DijmUWdU.js +1 -0
  83. package/dist/assets/{settings-page-DYDTFlnv.js → settings-page-B4u5TR5g.js} +1 -1
  84. package/dist/assets/{settings-rewards-page-cl4vqqO_.js → settings-rewards-page-COiTwkMH.js} +1 -1
  85. package/dist/assets/{settings-section-nav-DSOuht_F.js → settings-section-nav-Dc4IeVBt.js} +1 -1
  86. package/dist/assets/{settings-users-page-BU79JB_T.js → settings-users-page-DEGa5DNn.js} +1 -1
  87. package/dist/assets/settings-wiki-page-Cvsiz5_e.js +1 -0
  88. package/dist/assets/{sleep-page-D8NbdhyS.js → sleep-page-BnSOwkEU.js} +1 -1
  89. package/dist/assets/{sports-page-CV4Cnzwn.js → sports-page-l1RqXzA_.js} +1 -1
  90. package/dist/assets/{state-B-4sS1xO.js → state-VYvD1QVP.js} +1 -1
  91. package/dist/assets/{strategies-page-C4qvXnql.js → strategies-page-DEnPlpAs.js} +1 -1
  92. package/dist/assets/{strategy-detail-page-DJLo5rfy.js → strategy-detail-page-Ls8bxKeH.js} +1 -1
  93. package/dist/assets/strategy-dialog-DMyRKrWf.js +1 -0
  94. package/dist/assets/surface-Bfz_sLX6.js +1 -0
  95. package/dist/assets/{table-WfAPUppN.js → table-C0VTeqw0.js} +1 -1
  96. package/dist/assets/task-detail-page-CgrYgQLD.js +1 -0
  97. package/dist/assets/{timebox-planning-dialog-DB6FLqmI.js → timebox-planning-dialog-Ww0NGLLo.js} +1 -1
  98. package/dist/assets/today-page-CIuFHMi1.js +1 -0
  99. package/dist/assets/training-load-page-BIwc648i.js +1 -0
  100. package/dist/assets/{ui-C13Nbgas.js → ui-CsEkP2V8.js} +4 -4
  101. package/dist/assets/use-psyche-focus-target-qxT5Oy_z.js +1 -0
  102. package/dist/assets/{vendor-DHkYh85p.js → vendor-kIz9EZnX.js} +237 -222
  103. package/dist/assets/{vitals-page-qre17Nw8.js → vitals-page-Dz1Jt5H8.js} +1 -1
  104. package/dist/assets/{weekly-review-page-Cz4vkRcx.js → weekly-review-page-BFpBe1kI.js} +1 -1
  105. package/dist/assets/weight-loss-page-BgMoBpBt.js +5 -0
  106. package/dist/assets/{wiki-article-markdown-DdiR2TJE.js → wiki-article-markdown-gsPTXTg1.js} +1 -1
  107. package/dist/assets/{wiki-editor-page-DqwoqVFb.js → wiki-editor-page-BpAZHooY.js} +7 -7
  108. package/dist/assets/{wiki-ingest-history-page--evBLbOw.js → wiki-ingest-history-page-C-ig8O22.js} +1 -1
  109. package/dist/assets/{wiki-ingest-modal--ohzFnj2.js → wiki-ingest-modal-BK4eQgqs.js} +1 -1
  110. package/dist/assets/{wiki-page-B_VJFBPA.js → wiki-page-CMTZ60Zt.js} +1 -1
  111. package/dist/assets/workbench-flow-page-BIpWUcLJ.js +5 -0
  112. package/dist/assets/workbench-page-CtCjYSRe.js +1 -0
  113. package/dist/assets/workout-detail-page-DD9IGN6l.js +2 -0
  114. package/dist/index.html +9 -9
  115. package/dist/openclaw/local-runtime.js +41 -14
  116. package/dist/server/server/migrations/067_weight_loss_daily_active_overrides.sql +13 -0
  117. package/dist/server/server/src/app.js +103 -30
  118. package/dist/server/server/src/health-weight-loss.js +457 -55
  119. package/dist/server/server/src/health.js +12 -4
  120. package/dist/server/server/src/movement.js +84 -1
  121. package/dist/server/server/src/openapi.js +123 -18
  122. package/dist/server/server/src/repositories/model-settings.js +12 -9
  123. package/dist/server/server/src/repositories/settings.js +19 -5
  124. package/dist/server/src/components/ui/info-tooltip.js +6 -6
  125. package/dist/server/src/lib/api.js +14 -4
  126. package/dist/server/src/lib/theme-system.js +8 -0
  127. package/openclaw.plugin.json +1 -1
  128. package/package.json +3 -3
  129. package/server/migrations/067_weight_loss_daily_active_overrides.sql +13 -0
  130. package/skills/forge-openclaw/SKILL.md +13 -0
  131. package/skills/forge-openclaw/entity_conversation_playbooks.md +7 -1
  132. package/dist/assets/ai-surface-workspace-DEAFZruS.js +0 -1
  133. package/dist/assets/atlas-panel-CdVNPotj.js +0 -1
  134. package/dist/assets/calendar-week-toolbar-BbPwYeN0.js +0 -1
  135. package/dist/assets/daily-metrics-dashboard-B3cqJgDt.js +0 -1
  136. package/dist/assets/entity-notes-surface-CkcRsKJQ.js +0 -1
  137. package/dist/assets/faceted-token-search-BxRRcM3q.js +0 -1
  138. package/dist/assets/flagship-signal-deck-cmy82b8_.js +0 -1
  139. package/dist/assets/goals-page-BTk7mg_T.js +0 -1
  140. package/dist/assets/index-CF4J4R9L.js +0 -19
  141. package/dist/assets/index-CZbuZQjw.css +0 -1
  142. package/dist/assets/insight-flow-dialog-8f3D0GuC.js +0 -1
  143. package/dist/assets/knowledge-graph-page-BtAg8iv3.js +0 -1
  144. package/dist/assets/metric-tile-DKpo-8xw.js +0 -1
  145. package/dist/assets/movement-page-Bg_T_Stx.js +0 -1
  146. package/dist/assets/note-markdown-N-uxD3Xt.js +0 -3
  147. package/dist/assets/note-tags-input-Cdu7wiw6.js +0 -1
  148. package/dist/assets/notes-page-CKXnF_KU.js +0 -1
  149. package/dist/assets/orbit-map-Dzi6KliQ.js +0 -1
  150. package/dist/assets/overview-page-1miYqaVS.js +0 -1
  151. package/dist/assets/page-hero-DRy5b2MU.js +0 -1
  152. package/dist/assets/pill-cluster-C9QczVJ2.js +0 -1
  153. package/dist/assets/preferences-page-DtNaF5Q3.js +0 -1
  154. package/dist/assets/psyche-behaviors-page-Dco46sC4.js +0 -5
  155. package/dist/assets/psyche-flashcards-page-ZcoEB8gV.js +0 -1
  156. package/dist/assets/psyche-goal-map-page-CLBAQOI0.js +0 -1
  157. package/dist/assets/psyche-graph-k4tX2tdp.js +0 -1
  158. package/dist/assets/psyche-mode-guide-page-hIVXcCnE.js +0 -1
  159. package/dist/assets/psyche-modes-page-0lYtBlhO.js +0 -1
  160. package/dist/assets/psyche-page-VZ9k9ISp.js +0 -1
  161. package/dist/assets/psyche-patterns-page-gx5nmdGq.js +0 -5
  162. package/dist/assets/psyche-questionnaire-builder-page-Bn0TOISd.js +0 -1
  163. package/dist/assets/psyche-questionnaire-detail-page-CmVzSd_s.js +0 -1
  164. package/dist/assets/psyche-questionnaire-run-detail-page-BsMbmXCG.js +0 -1
  165. package/dist/assets/psyche-questionnaire-run-page-CgkRL2vi.js +0 -1
  166. package/dist/assets/psyche-questionnaires-page-D7V8uLXM.js +0 -1
  167. package/dist/assets/psyche-report-detail-page-OlFq57eL.js +0 -3
  168. package/dist/assets/psyche-reports-page-dVUZjna1.js +0 -1
  169. package/dist/assets/psyche-schemas-beliefs-page-BCgc8FUd.js +0 -9
  170. package/dist/assets/psyche-screen-time-page-B_6BT_WN.js +0 -1
  171. package/dist/assets/psyche-self-observation-page-CEG5mluK.js +0 -1
  172. package/dist/assets/psyche-values-page-DRbRfEd6.js +0 -5
  173. package/dist/assets/report-chain-fields-CALCV3V5.js +0 -1
  174. package/dist/assets/schema-badge-BZO-qNhO.js +0 -1
  175. package/dist/assets/schema-visuals-D6nxjbYC.js +0 -1
  176. package/dist/assets/select-menu-fYyreSdQ.js +0 -1
  177. package/dist/assets/settings-calendar-page-D1CzE6cg.js +0 -5
  178. package/dist/assets/settings-models-page-D26270R2.js +0 -1
  179. package/dist/assets/settings-wiki-page-DwAUlyA3.js +0 -1
  180. package/dist/assets/strategy-dialog-D3AuUlVz.js +0 -1
  181. package/dist/assets/task-detail-page-z-9u9rF0.js +0 -1
  182. package/dist/assets/today-page-BKlu6gx5.js +0 -1
  183. package/dist/assets/training-load-page-CyJQqo_3.js +0 -1
  184. package/dist/assets/use-psyche-focus-target-C1C_XjYG.js +0 -1
  185. package/dist/assets/weight-loss-page-BQrnOI0y.js +0 -1
  186. package/dist/assets/workbench-flow-page-Du62mtJU.js +0 -5
  187. package/dist/assets/workbench-page-4MKr3iRm.js +0 -1
  188. package/dist/assets/workout-detail-page-DfUbYYw1.js +0 -2
@@ -1 +0,0 @@
1
- import{cc as dt,b5 as ct,r as f,j as e,bc as de,aL as Ue,bB as Ke,cd as ot,bE as mt,ce as xt,aV as ne,aC as y,b2 as Ee,aG as ht,be as ut,cy as pt,aP as Me,bg as gt,bo as wt}from"./vendor-DHkYh85p.js";import{j as jt,i as _,k as v}from"./state-B-4sS1xO.js";import{P as bt,u as kt,s as ft,ay as vt,r as Nt,eO as yt,eP as St,at as Tt,as as It,x as At,y as Ct,z as $t,S as Dt,E as Re,a8 as Pt,V as Fe,C as Et,B as g,Z as O,c as i,b as H,U as Oe,h as S,d as re,aq as We,K as Le,az as Mt,aS as Rt,i as Ft,eQ as Ot,N as Be,O as Lt}from"./index-CF4J4R9L.js";import{a as Bt,T as qt}from"./timebox-planning-dialog-DB6FLqmI.js";import{O as zt}from"./open-in-graph-button-IXe9SGth.js";import{N as G}from"./note-markdown-N-uxD3Xt.js";import{E as Ut}from"./entity-notes-surface-CkcRsKJQ.js";import{P as Kt}from"./preference-entity-handoff-button-5PzUn42S.js";import{g as Wt,e as Qt,W as _t}from"./calendar-rules-DNJFNsxi.js";import{P as Ht}from"./page-hero-DRy5b2MU.js";import{g as Gt,a as Vt}from"./activity-copy-Bj4h9OcF.js";import{g as qe,a as ze}from"./entity-links-DwpxhW2H.js";import"./board-BkDRaMp6.js";import"./ui-C13Nbgas.js";import"./motion-BeD44FeG.js";import"./forms-BFlTgZ3W.js";import"./graph-D6JLqDbD.js";import"./scheduling-rules-editor-D02s70hr.js";import"./calendar-ui-Cy1XRwzV.js";import"./note-tags-input-Cdu7wiw6.js";function h({label:r,help:m}){return e.jsxs("div",{className:"flex items-center gap-2 text-sm text-white/58",children:[e.jsx("span",{children:r}),m?e.jsx(We,{content:m,label:`Explain ${r}`}):null]})}const V=[{status:"backlog",label:"Backlog",description:"Not started yet.",icon:de},{status:"focus",label:"Focus",description:"Ready to start soon.",icon:Ue},{status:"in_progress",label:"In progress",description:"Work is active now.",icon:Ke},{status:"blocked",label:"Blocked",description:"Something is stopping progress.",icon:ot},{status:"done",label:"Done",description:"The task is completed.",icon:mt}],Zt={issue:{label:"Issue",noun:"issue",descriptor:"Vertical slice issue",heroDescription:"Track the vertical slice, keep the acceptance bar explicit, and surface the execution context without losing the product-level story."},task:{label:"Task",noun:"task",descriptor:"AI session task",heroDescription:"Drive one focused AI execution session, keep the work contract crisp, and show the concrete evidence of what changed."},subtask:{label:"Subtask",noun:"subtask",descriptor:"Granular child step",heroDescription:"Keep the child step sharply scoped, trace its parent chain, and make the work evidence visible without opening the editor."}},Jt={commit:{label:"Commit",className:"bg-emerald-500/12 text-emerald-100"},branch:{label:"Branch",className:"bg-sky-500/12 text-sky-100"},pull_request:{label:"Pull request",className:"bg-fuchsia-500/12 text-fuchsia-100"}};function le(r){return r==="issue"?"issue":"task"}function Xt(r,m){switch(r){case"goal":return`/goals/${m}`;case"project":return`/projects/${m}`;case"task":return`/tasks/${m}`;case"strategy":return`/strategies/${m}`;case"habit":return"/habits";default:return null}}function C(r){if(!r||r<=0)return"0 min";if(r<3600)return`${Math.max(1,Math.round(r/60))} min`;const m=Math.floor(r/3600),c=Math.round(r%3600/60);return c===0?`${m} h`:`${m} h ${c} min`}function $({eyebrow:r,title:m,description:c,children:d,className:b}){return e.jsxs("div",{className:O("rounded-[24px] border border-white/8 bg-[linear-gradient(180deg,rgba(255,255,255,0.05),rgba(255,255,255,0.025))] p-4 sm:p-5",b),children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/42",children:r}),e.jsx("div",{className:"mt-2 text-lg font-medium text-white",children:m}),c?e.jsx("p",{className:"mt-2 text-sm leading-6 text-white/56",children:c}):null,e.jsx("div",{className:"mt-4",children:d})]})}function u({label:r,value:m,hint:c,className:d}){return e.jsxs("div",{className:O("rounded-[18px] border border-white/8 bg-white/[0.035] px-4 py-3",d),children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/40",children:r}),e.jsx("div",{className:"mt-2 text-base font-medium text-white",children:m}),c?e.jsx("div",{className:"mt-1 text-sm leading-5 text-white/52",children:c}):null]})}function bs(){var Se,Te,Ie,Ae,Ce,$e,De;const{t:r,formatDate:m,formatDateTime:c}=bt(),d=kt(),b=Array.isArray(d.selectedUserIds)?d.selectedUserIds:[],j=dt(),Qe=ct(),k=jt(),L=ft(b),[_e,ce]=f.useState(!1),[He,oe]=f.useState(!1),[Ge,D]=f.useState(!1),[Ve,me]=f.useState(!1),[Ze,Z]=f.useState(!1),[Je,B]=f.useState(null),[q,Xe]=f.useState(()=>typeof window<"u"?window.matchMedia("(max-width: 1023px)").matches:!1),[J]=f.useState(()=>{const t=new Date,a=new Date(t);a.setHours(0,0,0,0);const n=new Date(t);return n.setHours(23,59,59,999),{from:a.toISOString(),to:n.toISOString()}}),[P]=f.useState(()=>{const t=new Date,a=new Date(t);a.setHours(0,0,0,0);const n=new Date(a);return n.setDate(n.getDate()+7),n.setHours(23,59,59,999),{from:a.toISOString(),to:n.toISOString()}});f.useEffect(()=>{if(typeof window>"u"||typeof window.matchMedia!="function")return;const t=window.matchMedia("(max-width: 1023px)"),a=n=>Xe(n?n.matches:t.matches);return a(),typeof t.addEventListener=="function"?(t.addEventListener("change",a),()=>t.removeEventListener("change",a)):(t.addListener(a),()=>t.removeListener(a))},[]);const I=_({queryKey:["task-context",j.taskId],queryFn:()=>Ot(j.taskId),enabled:!!j.taskId}),Ye=_({queryKey:["task-calendar-overview",j.taskId,J.from,J.to,...b],queryFn:()=>Be({...J,userIds:b}),enabled:!!j.taskId}),T=_({queryKey:["forge-life-force",...b],queryFn:async()=>(await Lt(b)).lifeForce}),et=_({queryKey:["task-calendar-overview",j.taskId,P.from,P.to,...b],queryFn:()=>Be({...P,userIds:b}),enabled:!!j.taskId}),w=async()=>{await Promise.all([Ft(k),k.invalidateQueries({queryKey:["task-context",j.taskId]}),k.invalidateQueries({queryKey:["activity-archive"]}),k.invalidateQueries({queryKey:["project-board"]}),k.invalidateQueries({queryKey:["forge-xp-metrics"]}),k.invalidateQueries({queryKey:["forge-reward-ledger"]}),k.invalidateQueries({queryKey:["forge-operator-context"]}),k.invalidateQueries({queryKey:["task-calendar-overview",j.taskId]}),k.invalidateQueries({queryKey:["forge-calendar-overview"]})])},z=v({mutationFn:({taskId:t,patch:a})=>d.patchTask(t,a),onSuccess:w}),tt=v({mutationFn:t=>vt(t),onSuccess:w}),st=v({mutationFn:t=>Nt(t),onSuccess:w}),xe=v({mutationFn:({runId:t,actor:a,note:n})=>yt(t,{actor:a,note:n??""}),onSuccess:w}),he=v({mutationFn:({runId:t,actor:a,note:n})=>St(t,{actor:a,note:n??""}),onSuccess:w}),X=v({mutationFn:Tt,onSuccess:w}),ue=v({mutationFn:t=>It(t),onSuccess:w}),Y=v({mutationFn:At,onSuccess:w}),pe=v({mutationFn:({timeboxId:t,patch:a})=>Ct(t,a),onSuccess:w}),at=v({mutationFn:$t,onSuccess:w}),s=I.data;if(I.isLoading)return e.jsx(Dt,{});if(I.isError)return e.jsx(Re,{eyebrow:r("common.taskDetail.errorEyebrow"),error:I.error,onRetry:()=>void I.refetch()});if(!s)return e.jsx(Re,{eyebrow:r("common.taskDetail.errorEyebrow"),error:new Error(r("common.taskDetail.emptyPayload")),onRetry:()=>void I.refetch()});const p=s.activeTaskRun??null,x=s.task.actionPointSummary??null,ge=V.find(t=>t.status===s.task.status)??V[0],E=s.task.level??"task",we=s.task.aiInstructions??"",it=Wt(s.task,(Se=s.project)==null?void 0:Se.schedulingRules),A=Qt({rules:it,overview:(Te=Ye.data)==null?void 0:Te.calendar}),U=(((Ie=et.data)==null?void 0:Ie.calendar.timeboxes)??[]).filter(t=>t.taskId===s.task.id).sort((t,a)=>Date.parse(t.startsAt)-Date.parse(a.startsAt)),ee=U[0]??null,o=Zt[E],te=le(E),je=d.snapshot.workItems??d.snapshot.tasks??[],K=s.task.parentWorkItemId?je.find(t=>t.id===s.task.parentWorkItemId)??null:null,be=je.filter(t=>t.parentWorkItemId===s.task.id).sort((t,a)=>t.sortOrder-a.sortOrder),nt=d.snapshot.tags??[],ke=(s.task.tagIds??[]).map(t=>nt.find(a=>a.id===t)??null).filter(t=>!!t),se=s.task.acceptanceCriteria??[],fe=s.task.blockerLinks??[],W=s.task.gitRefs??[],l=s.task.completionReport,ve=new Set((l==null?void 0:l.linkedGitRefIds)??[]),ae=W.filter(t=>ve.has(t.id)),Ne=W.filter(t=>!ve.has(t.id)),ie=((Ae=s.task.user)==null?void 0:Ae.kind)==="bot"||((Ce=s.task.ownerUser)==null?void 0:Ce.kind)==="bot",M=(s.task.assignees??[]).filter(t=>t.kind==="bot"),Q=we.trim().length>0,N=q?"w-full justify-start":"",rt=t=>{switch(t){case"active":return"Active";case"completed":return"Completed";case"released":return"Paused";case"timed_out":return"Timed out";default:return t}},ye=async t=>{await d.patchTaskStatus(s.task.id,t),await w(),Z(!1)},lt=async()=>{window.confirm(`Delete ${o.noun} "${s.task.title}"?`)&&(await ue.mutateAsync(s.task.id),Qe(s.project?`/projects/${s.project.id}`:s.goal?`/goals/${s.goal.id}`:"/kanban"))};return e.jsxs("div",{className:"grid gap-5",children:[e.jsx(Ht,{entityKind:te,title:e.jsx(Fe,{kind:te,label:s.task.title,variant:"heading",size:"lg",lines:3,className:"max-w-full",labelClassName:"[overflow-wrap:anywhere]"}),titleText:s.task.title,description:s.task.description?e.jsx(G,{markdown:s.task.description,className:"[&>p]:text-[13px] [&>p]:leading-6 [&>blockquote]:text-[13px] [&>ul]:text-[13px] [&>ol]:text-[13px]"}):o.heroDescription,badge:x?`${s.task.points} xp · ${Math.round(x.totalCostAp)} AP`:`${s.task.points} xp`,actions:e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx(Pt,{metrics:d.snapshot.metrics}),e.jsx(Kt,{userId:L,domain:"tasks",entityType:"task",entityId:s.task.id,label:s.task.title,description:s.task.description}),e.jsx(zt,{entityType:"task",entityId:s.task.id})]})}),e.jsxs(Et,{className:"min-w-0 overflow-hidden",children:[e.jsxs("div",{className:"flex min-w-0 flex-wrap items-start justify-between gap-4",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:o.label}),e.jsx("div",{className:"mt-2",children:e.jsx(Fe,{kind:te,label:s.task.title,variant:"heading",size:"xl",lines:3,className:"max-w-full",labelClassName:"[overflow-wrap:anywhere]"})}),e.jsx("div",{className:"mt-3 text-sm leading-6 text-white/60",children:s.task.description?e.jsx(G,{markdown:s.task.description,className:"[&>p]:text-sm [&>p]:leading-6 [&>blockquote]:text-sm [&>ul]:text-sm [&>ol]:text-sm"}):`This page shows the ${o.noun}, where it belongs, what is driving it, and the concrete evidence of what has happened on it so far.`})]}),e.jsx("div",{className:O("shrink-0",q?"w-full":""),children:e.jsxs("div",{className:O("flex flex-wrap items-center gap-2",q&&"grid w-full grid-cols-1"),children:[e.jsxs(g,{className:N,pending:I.isFetching,pendingLabel:p?"Opening":"Starting",onClick:async()=>{await d.startTaskNow(s.task.id),await w()},children:[e.jsx(Ke,{className:"size-4 fill-current"}),p?"Focus work":"Start work"]}),p?e.jsxs(e.Fragment,{children:[e.jsx(g,{className:N,variant:"secondary",pending:xe.isPending,pendingLabel:"Pausing",onClick:async()=>{await xe.mutateAsync({runId:p.id,actor:p.actor,note:p.note})},children:"Pause"}),e.jsx(g,{className:N,variant:"secondary",pending:he.isPending,pendingLabel:"Completing",onClick:async()=>{await he.mutateAsync({runId:p.id,actor:p.actor,note:p.note})},children:"Complete"})]}):null,e.jsxs(g,{className:N,variant:"secondary",onClick:()=>Z(!0),children:[e.jsx(ge.icon,{className:"size-4"}),"Change status"]}),e.jsxs(g,{className:N,variant:"secondary",onClick:()=>ce(!0),children:[e.jsx(xt,{className:"size-4"}),"Edit ",o.noun]}),e.jsxs(g,{className:N,variant:"secondary",onClick:()=>oe(!0),children:[e.jsx(de,{className:"size-4"}),"Adjust work"]}),e.jsxs(g,{className:N,variant:"secondary",pending:Y.isPending,pendingLabel:"Planning",onClick:()=>D(!0),children:[e.jsx(ne,{className:"size-4"}),"Time Box"]}),s.task.status==="done"?e.jsx(g,{className:N,variant:"secondary",onClick:async()=>{await tt.mutateAsync(s.task.id)},children:"Mark as not done"}):null,e.jsxs(g,{className:O(N,"text-rose-200 hover:bg-rose-500/10"),variant:"ghost",pending:ue.isPending,pendingLabel:r("common.taskDetail.deleting"),onClick:()=>void lt(),children:["Delete ",o.noun]})]})})]}),e.jsxs("div",{className:"mt-5 flex flex-wrap gap-2",children:[e.jsx(i,{className:"bg-[var(--primary)]/14 text-[var(--primary)]",children:o.label}),e.jsx(i,{className:"bg-white/[0.08] text-white/72",children:o.descriptor}),e.jsx(i,{className:"bg-white/[0.08] text-white/72",children:ge.label}),e.jsx(i,{className:"bg-white/[0.08] text-white/72",children:r(`common.enums.priority.${s.task.priority}`)}),e.jsx(i,{className:"bg-white/[0.08] text-white/72",children:r(`common.enums.effort.${s.task.effort}`)}),e.jsx(i,{className:"bg-white/[0.08] text-white/72",children:r(`common.enums.energy.${s.task.energy}`)}),e.jsxs(i,{className:"bg-white/[0.08] text-white/72",children:[s.task.points," xp"]}),s.task.time.totalCreditedSeconds>0?e.jsxs(i,{className:"bg-white/[0.08] text-white/72",children:[Math.floor(s.task.time.totalCreditedSeconds/60)," min tracked"]}):null,p?e.jsx(i,{className:"bg-emerald-500/12 text-emerald-200",children:"Timer active"}):null,s.task.executionMode?e.jsx(i,{className:s.task.executionMode==="afk"?"bg-emerald-500/12 text-emerald-100":"bg-amber-500/12 text-amber-100",children:s.task.executionMode.toUpperCase()}):null,Q?e.jsx(i,{className:"bg-sky-500/12 text-sky-100",children:"AI brief ready"}):null,ie||M.length>0?e.jsx(i,{className:"bg-fuchsia-500/12 text-fuchsia-100",children:"Bot collaboration live"}):null,ee?e.jsx(y,{to:`/calendar?timeboxId=${encodeURIComponent(ee.id)}`,className:"inline-flex",children:e.jsxs(i,{className:"cursor-pointer bg-[var(--primary)]/16 text-[var(--primary)] transition hover:bg-[var(--primary)]/24",children:["Timeboxed · ",c(ee.startsAt)]})}):null]}),q?null:e.jsxs("div",{className:"mt-5",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:"Status"}),e.jsx("div",{className:"mt-3 grid gap-2 md:grid-cols-2 xl:grid-cols-5",children:V.map(t=>{const a=t.icon,n=t.status===s.task.status;return e.jsxs("button",{type:"button",disabled:n||z.isPending,className:`rounded-[18px] border px-3.5 py-3 text-left transition ${n?"border-[rgba(192,193,255,0.28)] bg-[rgba(192,193,255,0.14)] text-white":"border-white/8 bg-white/[0.04] text-white/72 hover:bg-white/[0.08]"}`,onClick:()=>void ye(t.status),children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(a,{className:"size-4 shrink-0 text-[var(--primary)]"}),e.jsx("span",{className:"font-medium",children:t.label})]}),e.jsx("div",{className:"mt-2 text-xs leading-5 text-white/54",children:t.description})]},t.status)})})]}),e.jsxs("div",{className:"mt-5 grid gap-4 xl:grid-cols-[minmax(0,1.15fr)_minmax(0,1fr)_minmax(0,1fr)]",children:[e.jsx($,{eyebrow:"Hierarchy",title:"Context map",description:`See where this ${o.noun} sits in the larger planning ladder without opening the board.`,children:e.jsxs("div",{className:"grid gap-4",children:[e.jsxs("div",{children:[e.jsx(h,{label:"Project",help:`The project is the main work stream this ${o.noun} belongs to.`}),e.jsx("div",{className:"mt-2",children:s.project?e.jsx(y,{to:`/projects/${s.project.id}`,className:"inline-flex max-w-full",children:e.jsx(H,{kind:"project",label:s.project.title,compact:!0,gradient:!1,wrap:!0,className:"max-w-full"})}):e.jsx(i,{className:"bg-white/[0.08] text-white/65",children:"No project linked"})})]}),e.jsxs("div",{children:[e.jsx(h,{label:"Goal",help:"The goal shows the longer-term result this work supports."}),e.jsx("div",{className:"mt-2",children:s.goal?e.jsx(y,{to:`/goals/${s.goal.id}`,className:"inline-flex max-w-full",children:e.jsx(H,{kind:"goal",label:s.goal.title,compact:!0,gradient:!1,wrap:!0,className:"max-w-full"})}):e.jsx(i,{className:"bg-white/[0.08] text-white/65",children:"No goal linked"})})]}),e.jsxs("div",{children:[e.jsx(h,{label:"Parent item",help:"Issues parent tasks, tasks parent subtasks, and split child items stay legible here."}),e.jsx("div",{className:"mt-2",children:K?e.jsx(y,{to:`/tasks/${K.id}`,className:"inline-flex max-w-full",children:e.jsx(H,{kind:le(K.level),label:K.title,compact:!0,gradient:!1,wrap:!0,className:"max-w-full"})}):e.jsx(i,{className:"bg-white/[0.08] text-white/65",children:"No parent work item"})})]}),e.jsxs("div",{children:[e.jsx(h,{label:"Child items",help:"Child work items let you scan the next layer down without leaving the detail view."}),e.jsx("div",{className:"mt-2 flex flex-wrap gap-2",children:be.length>0?be.map(t=>e.jsx(y,{to:`/tasks/${t.id}`,className:"inline-flex max-w-full",children:e.jsx(H,{kind:le(t.level),label:t.title,compact:!0,gradient:!1,wrap:!0,className:"max-w-full"})},t.id)):e.jsx(i,{className:"bg-white/[0.08] text-white/65",children:"No child work items"})})]})]})}),e.jsx($,{eyebrow:"Execution",title:"Execution profile",description:"Surface the operating mode, AI posture, tags, and blockers as a single readable brief.",children:e.jsxs("div",{className:"grid gap-3",children:[e.jsx(u,{label:"Work-item type",value:o.descriptor,hint:E==="task"?"Tasks are meant to fit one focused AI session.":E==="issue"?"Issues hold the vertical slice and its delivery contract.":"Subtasks stay intentionally small and concrete."}),e.jsxs("div",{className:"grid gap-3 sm:grid-cols-2",children:[e.jsx(u,{label:"Execution mode",value:s.task.executionMode?s.task.executionMode.toUpperCase():"Not set"}),e.jsx(u,{label:"AI posture",value:Q?"AI brief ready":E==="issue"?"Issue narrative only":"Needs AI brief"})]}),e.jsxs("div",{children:[e.jsx(h,{label:"Tags",help:"Tags shape filtering and fast scanning across the board and hierarchy views."}),e.jsx("div",{className:"mt-2 flex flex-wrap gap-2",children:ke.length>0?ke.map(t=>e.jsx(i,{className:"bg-white/[0.08] text-white/72",children:t.name},t.id)):e.jsx(i,{className:"bg-white/[0.08] text-white/65",children:"No tags"})})]}),e.jsxs("div",{children:[e.jsx(h,{label:"Blockers",help:"Blockers tie this work item to the entities that currently constrain it."}),e.jsx("div",{className:"mt-2 flex flex-wrap gap-2",children:fe.length>0?fe.map(t=>{const a=Xt(t.entityType,t.entityId),n=e.jsx(i,{wrap:!0,className:"bg-amber-500/12 text-amber-100",children:t.label??`${t.entityType} · ${t.entityId}`},`${t.entityType}:${t.entityId}`);return a?e.jsx(y,{to:a,className:"inline-flex max-w-full",children:n},`${t.entityType}:${t.entityId}`):n}):e.jsx(i,{className:"bg-white/[0.08] text-white/65",children:"No blockers linked"})})]})]})}),e.jsx($,{eyebrow:"People and timing",title:"Accountability surface",description:"Show who owns the work, who is helping, and when the record moved.",children:e.jsxs("div",{className:"grid gap-3",children:[e.jsx(u,{label:"Owner",value:e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[s.task.user?e.jsx(Oe,{user:s.task.user,compact:!0}):null,e.jsx("span",{children:s.task.owner}),ie?e.jsxs(i,{className:"bg-fuchsia-500/12 text-fuchsia-100",children:[e.jsx(Ee,{className:"mr-1 size-3.5"}),"Bot owner"]}):null]})}),e.jsxs("div",{children:[e.jsx(h,{label:"Assignees"}),e.jsx("div",{className:"mt-2 flex flex-wrap gap-2",children:s.task.assignees&&s.task.assignees.length>0?s.task.assignees.map(t=>e.jsxs("div",{className:"inline-flex items-center gap-2 rounded-full border border-white/8 bg-white/[0.05] px-3 py-1.5 text-sm text-white/72",children:[e.jsx(Oe,{user:t,compact:!0}),e.jsx("span",{children:t.displayName}),t.kind==="bot"?e.jsx(Ee,{className:"size-3.5 text-fuchsia-200"}):null]},t.id)):e.jsx(i,{className:"bg-white/[0.08] text-white/65",children:"No assignees"})})]}),e.jsxs("div",{className:"grid gap-3 sm:grid-cols-2",children:[e.jsx(u,{label:"Due date",value:m(s.task.dueDate),hint:`Use due dates only when timing materially matters for this ${o.noun}.`}),e.jsx(u,{label:"Completed",value:s.task.completedAt?c(s.task.completedAt):"Not completed"})]}),e.jsxs("div",{className:"grid gap-3 sm:grid-cols-2",children:[e.jsx(u,{label:"Created",value:c(s.task.createdAt)}),e.jsx(u,{label:"Updated",value:c(s.task.updatedAt)})]})]})})]}),Q||se.length>0||l||W.length>0?e.jsxs("div",{className:"mt-5 grid gap-4 xl:grid-cols-[minmax(0,1.05fr)_minmax(0,1fr)]",children:[e.jsx($,{eyebrow:"Execution brief",title:"AI and delivery instructions",description:"The narrative, criteria, and execution intent live together so the detail view can stand on its own.",children:e.jsxs("div",{className:"grid gap-4",children:[e.jsxs("div",{className:"rounded-[20px] border border-white/8 bg-white/[0.03] p-4",children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm text-white/62",children:[e.jsx(ht,{className:"size-4 text-[var(--primary)]"}),e.jsx("span",{children:"AI instructions"})]}),e.jsx("div",{className:"mt-3 text-sm leading-6 text-white/72",children:Q?e.jsx(G,{markdown:we,className:"[&>p]:text-sm [&>p]:leading-6 [&>blockquote]:text-sm [&>ul]:text-sm [&>ol]:text-sm"}):`No AI instructions have been written for this ${o.noun} yet.`})]}),e.jsxs("div",{className:"rounded-[20px] border border-white/8 bg-white/[0.03] p-4",children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm text-white/62",children:[e.jsx(Ue,{className:"size-4 text-emerald-200"}),e.jsx("span",{children:"Acceptance criteria"})]}),se.length>0?e.jsx("div",{className:"mt-3 grid gap-2",children:se.map((t,a)=>e.jsx("div",{className:"rounded-[16px] border border-white/8 bg-white/[0.04] px-4 py-3 text-sm leading-6 text-white/72",children:t},`${s.task.id}-criterion-${a}`))}):e.jsx("div",{className:"mt-3 rounded-[16px] border border-dashed border-white/10 px-4 py-3 text-sm text-white/52",children:"No acceptance criteria captured yet."})]})]})}),e.jsx($,{eyebrow:"Evidence",title:"Work done, changed files, and git traceability",description:"Show the work summary, file footprint, and linked refs directly in the detail view.",children:e.jsxs("div",{className:"grid gap-4",children:[e.jsxs("div",{className:"rounded-[20px] border border-white/8 bg-white/[0.03] p-4",children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm text-white/62",children:[e.jsx(ut,{className:"size-4 text-sky-200"}),e.jsx("span",{children:"Work summary"})]}),e.jsx("div",{className:"mt-3 text-sm leading-6 text-white/72",children:l!=null&&l.workSummary?e.jsx(G,{markdown:l.workSummary,className:"[&>p]:text-sm [&>p]:leading-6 [&>blockquote]:text-sm [&>ul]:text-sm [&>ol]:text-sm"}):"No work summary yet."})]}),e.jsxs("div",{className:"rounded-[20px] border border-white/8 bg-white/[0.03] p-4",children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm text-white/62",children:[e.jsx(pt,{className:"size-4 text-amber-200"}),e.jsx("span",{children:"Changed files"})]}),e.jsx("div",{className:"mt-3 flex flex-wrap gap-2",children:l!=null&&l.modifiedFiles&&l.modifiedFiles.length>0?l.modifiedFiles.map(t=>e.jsx(i,{wrap:!0,className:"bg-white/[0.08] font-mono text-[11px] text-white/74",children:t},t)):e.jsx(i,{className:"bg-white/[0.08] text-white/65",children:"No changed files listed"})})]}),e.jsxs("div",{className:"rounded-[20px] border border-white/8 bg-white/[0.03] p-4",children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm text-white/62",children:[e.jsx(Me,{className:"size-4 text-fuchsia-200"}),e.jsx("span",{children:"Git refs"})]}),e.jsxs("div",{className:"mt-3 grid gap-3",children:[[ae,Ne].filter(t=>t.length>0).map((t,a)=>e.jsxs("div",{className:"grid gap-2",children:[ae.length>0&&Ne.length>0?e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/38",children:a===0?"Linked in completion report":"Other recorded refs"}):null,t.map(n=>{const R=Jt[n.refType],F=e.jsxs("div",{className:"rounded-[16px] border border-white/8 bg-white/[0.04] px-4 py-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(i,{className:R.className,children:R.label}),e.jsx("div",{className:"font-mono text-sm text-white/84",children:n.refValue})]}),e.jsx("div",{className:"mt-2 text-sm text-white/58",children:n.displayTitle||n.repository||n.provider})]});return n.url?e.jsxs("a",{href:n.url,target:"_blank",rel:"noreferrer",className:"group block",children:[F,e.jsxs("div",{className:"mt-2 inline-flex items-center gap-1 text-[11px] uppercase tracking-[0.16em] text-[var(--primary)]",children:["Open ref",e.jsx(gt,{className:"size-3.5 transition group-hover:translate-x-0.5 group-hover:-translate-y-0.5"})]})]},n.id):e.jsx("div",{children:F},n.id)})]},`git-group-${a}`)),W.length===0?e.jsx(i,{className:"bg-white/[0.08] text-white/65",children:"No git refs recorded"}):null]})]})]})})]}):null,e.jsxs("div",{className:"mt-5 grid gap-4 xl:grid-cols-[minmax(0,1fr)_minmax(0,1fr)]",children:[e.jsxs($,{eyebrow:"Work done",title:"Execution ledger",description:"Surface tracked work, credited work, and manual adjustments without opening the timer history.",children:[e.jsxs("div",{className:"grid gap-3 sm:grid-cols-2 xl:grid-cols-4",children:[e.jsx(u,{label:"Tracked total",value:C(s.task.time.totalTrackedSeconds)}),e.jsx(u,{label:"Credited total",value:C(s.task.time.totalCreditedSeconds)}),e.jsx(u,{label:"Live work",value:C(s.task.time.liveCreditedSeconds)}),e.jsx(u,{label:"Manual adjustments",value:C(s.task.time.manualAdjustedSeconds)})]}),e.jsxs("div",{className:"mt-3 flex flex-wrap gap-2",children:[e.jsxs(i,{className:"bg-white/[0.08] text-white/72",children:["Today credited ",C(s.task.time.todayCreditedSeconds??0)]}),e.jsxs(i,{className:"bg-white/[0.08] text-white/72",children:["Live tracked ",C(s.task.time.liveTrackedSeconds)]}),e.jsxs(i,{className:"bg-white/[0.08] text-white/72",children:["Active runs ",s.task.time.activeRunCount]})]})]}),e.jsxs($,{eyebrow:"Workflow health",title:"Signal scan",description:"A fast read on how ready this work item is for execution and closeout.",children:[e.jsxs("div",{className:"grid gap-3 sm:grid-cols-2",children:[e.jsx(u,{label:"Closeout readiness",value:l!=null&&l.workSummary||ae.length>0?"Evidence present":"Needs closeout evidence",hint:($e=l==null?void 0:l.modifiedFiles)!=null&&$e.length?`${l.modifiedFiles.length} changed file${l.modifiedFiles.length===1?"":"s"} listed`:"No changed-file evidence captured yet."}),e.jsx(u,{label:"Collaboration model",value:ie||M.length>0?"Human + bot":s.task.assignees&&s.task.assignees.length>0?"Shared human work":"Single owner",hint:M.length>0?`${M.length} bot assignee${M.length===1?"":"s"} attached`:"No bot assignee attached."})]}),e.jsxs("div",{className:"mt-3 flex flex-wrap gap-2",children:[e.jsxs(i,{className:"bg-white/[0.08] text-white/72",children:["Priority ",r(`common.enums.priority.${s.task.priority}`)]}),e.jsxs(i,{className:"bg-white/[0.08] text-white/72",children:["Effort ",r(`common.enums.effort.${s.task.effort}`)]}),e.jsxs(i,{className:"bg-white/[0.08] text-white/72",children:["Energy ",r(`common.enums.energy.${s.task.energy}`)]}),e.jsxs(i,{className:"bg-white/[0.08] text-white/72",children:["Duration ",C(s.task.plannedDurationSeconds)]})]})]})]}),e.jsxs("div",{className:"mt-5 rounded-[20px] bg-white/[0.04] p-4",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:"Action Point load"}),e.jsxs("div",{className:"mt-4 grid gap-3 sm:grid-cols-2 xl:grid-cols-4",children:[e.jsxs("div",{className:"rounded-[16px] bg-white/[0.03] px-3.5 py-3",children:[e.jsx(h,{label:"Total cost"}),e.jsx("div",{className:"mt-2 text-lg text-white",children:x?S(x.totalCostAp):"Not calibrated"})]}),e.jsxs("div",{className:"rounded-[16px] bg-white/[0.03] px-3.5 py-3",children:[e.jsx(h,{label:"Today debit"}),e.jsx("div",{className:"mt-2 text-lg text-white",children:x?S(x.spentTodayAp):"0 AP"})]}),e.jsxs("div",{className:"rounded-[16px] bg-white/[0.03] px-3.5 py-3",children:[e.jsx(h,{label:"Sustain rate"}),e.jsx("div",{className:"mt-2 text-lg text-white",children:x?re(x.sustainRateApPerHour):"0 AP/h"})]}),e.jsxs("div",{className:"rounded-[16px] bg-white/[0.03] px-3.5 py-3",children:[e.jsx(h,{label:"Expected duration"}),e.jsx("div",{className:"mt-2 text-lg text-white",children:x?`${Math.round(x.expectedDurationSeconds/3600)} h`:"No target"})]})]}),e.jsxs("div",{className:"mt-3 flex flex-wrap gap-2",children:[(De=s.task.splitSuggestion)!=null&&De.shouldSplit?e.jsx(i,{className:"bg-amber-400/12 text-amber-100",children:"Split it"}):null,x?e.jsxs(i,{className:"bg-white/[0.08] text-white/72",children:["Remaining ",S(x.remainingAp)]}):null,x?e.jsxs(i,{className:"bg-white/[0.08] text-white/72",children:["Spent total ",S(x.spentTotalAp)]}):null,x?e.jsx(i,{className:"bg-white/[0.08] text-white/72",children:x.costBand}):null]}),e.jsx("p",{className:"mt-3 text-sm leading-6 text-white/58",children:"This task only debits the Action Points you actually worked today. Marking it done does not consume the full estimate by itself."})]}),e.jsxs("div",{className:"mt-5 rounded-[20px] bg-white/[0.04] p-4",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:"Today's Life Force context"}),e.jsxs("div",{className:"mt-4 grid gap-3 sm:grid-cols-3",children:[e.jsxs("div",{className:"rounded-[16px] bg-white/[0.03] px-3.5 py-3",children:[e.jsx(h,{label:"Daily AP"}),e.jsx("div",{className:"mt-2 text-lg text-white",children:T.data?`${S(T.data.spentTodayAp)} / ${S(T.data.dailyBudgetAp)}`:"Loading..."})]}),e.jsxs("div",{className:"rounded-[16px] bg-white/[0.03] px-3.5 py-3",children:[e.jsx(h,{label:"Instant headroom"}),e.jsx("div",{className:"mt-2 text-lg text-white",children:T.data?re(T.data.instantFreeApPerHour):"Loading..."})]}),e.jsxs("div",{className:"rounded-[16px] bg-white/[0.03] px-3.5 py-3",children:[e.jsx(h,{label:"Forecast"}),e.jsx("div",{className:"mt-2 text-lg text-white",children:T.data?`${S(T.data.forecastAp)} / ${S(T.data.dailyBudgetAp)}`:"Loading..."})]})]})]}),e.jsxs("div",{className:"mt-5 rounded-[20px] bg-white/[0.04] p-4",children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm text-white/58",children:[e.jsx("span",{children:"Current timer"}),e.jsx(We,{content:"This shows whether work is running on the task right now and how much time has been credited.",label:"Explain current timer"})]}),e.jsx("div",{className:"mt-3 text-white",children:p?`${p.timerMode==="planned"?"Planned":"Unlimited"} timer active with ${Math.floor(p.creditedSeconds/60)} credited minutes.`:"No timer is running on this task right now."})]}),e.jsxs("div",{className:"mt-5 grid gap-4 xl:grid-cols-[minmax(0,1fr)_20rem]",children:[e.jsxs("div",{className:"rounded-[20px] bg-white/[0.04] p-4",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:"Task scheduling"}),e.jsxs("div",{className:"mt-4 grid gap-3 sm:grid-cols-2",children:[e.jsxs("div",{className:"rounded-[16px] bg-white/[0.03] px-3.5 py-3",children:[e.jsx(h,{label:"Rule source"}),e.jsx("div",{className:"mt-2 text-white",children:s.task.schedulingRules?"Task-specific override":"Uses project defaults"})]}),e.jsxs("div",{className:"rounded-[16px] bg-white/[0.03] px-3.5 py-3",children:[e.jsx(h,{label:"Planned duration"}),e.jsx("div",{className:"mt-2 text-white",children:s.task.plannedDurationSeconds?`${Math.round(s.task.plannedDurationSeconds/60)} min`:"No duration target"})]})]}),e.jsx("p",{className:"mt-4 text-sm leading-6 text-white/58",children:"Scheduling rules now live behind the guided modal flow instead of an inline editor. Use it to change eligible blocks, blocked contexts, and the planning duration without overcrowding the task page."}),e.jsxs("div",{className:"mt-4 flex flex-wrap gap-2",children:[e.jsxs(g,{onClick:()=>me(!0),children:[e.jsx(ne,{className:"size-4"}),"Edit task scheduling"]}),e.jsx(y,{to:"/calendar",children:e.jsx(g,{variant:"secondary",children:"Open calendar workspace"})})]})]}),e.jsxs("div",{className:"rounded-[20px] bg-white/[0.04] p-4",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:"Calendar status"}),e.jsxs("div",{className:"mt-3 flex flex-wrap gap-2",children:[e.jsx(i,{className:A.tone==="blocked"?"bg-rose-500/14 text-rose-100":A.tone==="waiting"?"bg-amber-500/14 text-amber-100":"bg-emerald-500/14 text-emerald-100",children:A.label}),e.jsx(i,{className:"bg-white/[0.08] text-white/72",children:s.task.schedulingRules?"Task override":"Using project defaults"}),s.task.plannedDurationSeconds?e.jsxs(i,{className:"bg-white/[0.08] text-white/72",children:[Math.round(s.task.plannedDurationSeconds/60)," min target"]}):null]}),e.jsx("p",{className:"mt-3 text-sm leading-6 text-white/58",children:"Forge checks these rules before a live run starts. If the current calendar context is blocked, you can still override with an explicit reason."}),A.context.length>0?e.jsxs("div",{className:"mt-4",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/40",children:"Current context"}),e.jsx("div",{className:"mt-2 flex flex-wrap gap-2",children:A.context.map(t=>e.jsx(i,{className:"bg-white/[0.08] text-white/72",children:t},t))})]}):null,A.conflicts.length>0?e.jsx("div",{className:"mt-4 grid gap-2",children:A.conflicts.map(t=>e.jsx("div",{className:"rounded-[16px] bg-rose-500/10 px-3 py-2 text-sm text-rose-100",children:t},t))}):null,e.jsx("div",{className:"mt-4 flex flex-wrap gap-2",children:e.jsxs(g,{pending:Y.isPending||pe.isPending,pendingLabel:"Planning",onClick:()=>{B(null),D(!0)},children:[e.jsx(ne,{className:"size-4"}),"Time Box"]})})]})]}),e.jsxs("div",{className:"mt-5 rounded-[20px] bg-white/[0.04] p-4",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:"Scheduled blocks"}),e.jsx("p",{className:"mt-2 text-sm leading-6 text-white/58",children:"Open a scheduled block to edit the day, the hour range, or the AP profile tied to this task."})]}),e.jsx(i,{className:"bg-white/[0.08] text-white/72",children:U.length})]}),e.jsxs("div",{className:"mt-4 grid gap-3",children:[U.length===0?e.jsx("div",{className:"rounded-[18px] bg-white/[0.03] px-4 py-4 text-sm text-white/55",children:"No future timeboxes are attached to this task yet."}):null,U.map(t=>e.jsxs("div",{role:"button",tabIndex:0,onClick:()=>{B(t),D(!0)},onKeyDown:a=>{(a.key==="Enter"||a.key===" ")&&(a.preventDefault(),B(t),D(!0))},className:"rounded-[18px] border border-white/8 bg-[linear-gradient(180deg,rgba(26,32,49,0.86),rgba(16,21,34,0.86))] p-4 text-left transition hover:bg-[linear-gradient(180deg,rgba(30,36,54,0.92),rgba(18,23,37,0.92))]",children:[e.jsx("div",{className:"flex flex-wrap items-start justify-between gap-3",children:e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("div",{className:"line-clamp-2 font-medium leading-6 text-white",children:t.title}),e.jsxs("div",{className:"mt-1 flex items-center gap-2 text-sm text-white/58",children:[e.jsx(de,{className:"size-3.5 shrink-0"}),c(t.startsAt)," to ",c(t.endsAt)]})]})}),e.jsxs("div",{className:"mt-3 flex flex-wrap gap-2",children:[e.jsx(i,{className:"bg-white/[0.08] text-white/72",children:t.source}),e.jsx(i,{className:"bg-white/[0.08] text-white/72",children:t.status}),e.jsx(i,{className:"bg-[var(--primary)]/14 text-[var(--primary)]",children:re(Le(t).rateApPerHour)}),e.jsx(i,{className:"bg-white/[0.08] text-white/72",children:S(Le(t).totalAp)}),t.overrideReason?e.jsx(i,{className:"bg-white/[0.08] text-white/72",children:t.overrideReason}):null]}),e.jsxs("div",{className:"mt-4 flex flex-wrap gap-2",children:[e.jsx("span",{className:"rounded-[999px] bg-white/[0.08] px-3 py-1 text-xs text-white/72",children:"Edit in guide"}),e.jsx(y,{to:`/calendar?timeboxId=${encodeURIComponent(t.id)}`,onClick:a=>a.stopPropagation(),className:"rounded-[999px] bg-white/[0.08] px-3 py-1 text-xs text-white/72 transition hover:bg-white/[0.12]",children:"Open in calendar"})]})]},t.id))]})]}),e.jsx("div",{className:"mt-5",children:e.jsx(Ut,{entityType:"task",entityId:s.task.id,title:`${o.label} notes`,description:`Capture real progress, blockers, and context in Markdown so the ${o.noun} keeps a durable work log.`,invalidateQueryKeys:[["task-context",j.taskId],...s.task.projectId?[["project-board",s.task.projectId]]:[]]})}),e.jsxs("div",{className:"mt-5",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:"Activity"}),e.jsxs("div",{className:"mt-4 grid gap-3",children:[s.activity.length===0?e.jsx("div",{className:"rounded-[18px] bg-white/[0.04] p-4 text-sm text-white/55",children:"No activity has been recorded for this task yet."}):null,s.activity.map(t=>e.jsxs("div",{className:"rounded-[18px] bg-white/[0.04] p-4",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"font-medium text-white",children:Gt(t)}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-white/58",children:Vt(t)}),e.jsx("div",{className:"mt-3 text-[11px] uppercase tracking-[0.16em] text-white/35",children:c(t.createdAt)})]}),e.jsx(g,{variant:"ghost",className:"shrink-0",onClick:async()=>{await st.mutateAsync(t.id)},children:"Remove"})]}),qe(t)&&ze(t)?e.jsx(y,{to:qe(t),className:"mt-3 inline-flex text-[11px] uppercase tracking-[0.16em] text-[var(--primary)]",children:ze(t)}):null]},t.id))]})]}),e.jsxs("div",{className:"mt-5",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:"Timer sessions"}),e.jsxs("div",{className:"mt-4 grid gap-3",children:[s.taskRuns.length===0?e.jsx("div",{className:"rounded-[18px] bg-white/[0.04] p-4 text-sm text-white/55",children:"No timer sessions have been recorded for this task yet."}):null,s.taskRuns.map(t=>{var a,n,R,F,Pe;return e.jsxs("div",{className:"rounded-[18px] bg-white/[0.04] p-4",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsx("div",{className:"font-medium text-white",children:t.actor}),e.jsx(i,{children:rt(t.status)})]}),(a=t.gitContext)!=null&&a.branch||(n=t.gitContext)!=null&&n.pullRequestNumber?e.jsxs("div",{className:"mt-3 flex flex-wrap gap-2",children:[(R=t.gitContext)!=null&&R.branch?e.jsxs(i,{className:"bg-sky-500/12 text-sky-100",children:[e.jsx(Me,{className:"mr-1 size-3"}),t.gitContext.branch]}):null,(F=t.gitContext)!=null&&F.pullRequestNumber?e.jsxs(i,{className:"bg-fuchsia-500/12 text-fuchsia-100",children:[e.jsx(wt,{className:"mr-1 size-3"}),"PR #",t.gitContext.pullRequestNumber]}):null,(Pe=t.gitContext)!=null&&Pe.repository?e.jsx(i,{className:"bg-white/[0.08] text-white/68",children:t.gitContext.repository}):null]}):null,e.jsx("div",{className:"mt-2 text-sm text-white/58",children:t.note||r("common.labels.noRunNote")}),e.jsx("div",{className:"mt-3 text-[11px] uppercase tracking-[0.16em] text-white/35",children:c(t.updatedAt)})]},t.id)})]})]})]}),e.jsx(Mt,{open:_e,goals:d.snapshot.goals,projects:d.snapshot.dashboard.projects,workItems:d.snapshot.workItems,tags:d.snapshot.tags,users:d.snapshot.users,editingTask:s.task,defaultUserId:s.task.userId??L,onRefreshEntities:d.refresh,currentCreditedSeconds:s.task.time.totalCreditedSeconds,onOpenChange:ce,onAdjustTrackedTime:async t=>{await X.mutateAsync(t)},onSubmit:async(t,a)=>{a&&await z.mutateAsync({taskId:a,patch:t})}}),e.jsx(_t,{open:He,onOpenChange:oe,entityType:"task",entityId:s.task.id,targetLabel:s.task.title,currentCreditedSeconds:s.task.time.totalCreditedSeconds,pending:X.isPending,onSubmit:async t=>{await X.mutateAsync(t)}}),e.jsx(Bt,{open:Ge,onOpenChange:t=>{D(t),t||B(null)},tasks:[s.task],initialTaskId:s.task.id,lockedTaskId:s.task.id,editingTimebox:Je,from:P.from,to:P.to,userIds:b,onCreateTimebox:async t=>{await Y.mutateAsync({...t,userId:L??void 0})},onUpdateTimebox:async(t,a)=>{await pe.mutateAsync({timeboxId:t,patch:{...a,userId:L??void 0}})},onDeleteTimebox:async t=>{await at.mutateAsync(t)}}),e.jsx(qt,{open:Ve,onOpenChange:me,tasks:[s.task],onSave:async({taskId:t,schedulingRules:a,plannedDurationSeconds:n})=>{await z.mutateAsync({taskId:t,patch:{schedulingRules:a,plannedDurationSeconds:n}}),await k.invalidateQueries({queryKey:["task-calendar-overview",j.taskId]})}}),e.jsx(Rt,{open:Ze,onOpenChange:Z,eyebrow:`${o.label} status`,title:"Change status",description:`Pick the state that best matches where this ${o.noun} is right now.`,children:e.jsx("div",{className:"grid gap-3",children:V.map(t=>{const a=t.icon,n=t.status===s.task.status;return e.jsx("button",{type:"button",disabled:n||z.isPending,className:`rounded-[22px] border px-4 py-4 text-left transition ${n?"border-[rgba(192,193,255,0.28)] bg-[rgba(192,193,255,0.14)] text-white":"border-white/8 bg-white/[0.04] text-white/72 hover:bg-white/[0.08]"}`,onClick:()=>void ye(t.status),children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(a,{className:"size-4 shrink-0 text-[var(--primary)]"}),e.jsxs("div",{children:[e.jsx("div",{className:"font-medium",children:t.label}),e.jsx("div",{className:"mt-1 text-sm text-white/54",children:t.description})]})]})},t.status)})})})]})}export{bs as TaskDetailPage};
@@ -1 +0,0 @@
1
- import{j as e,aC as f,b8 as E,bB as b,bE as H,b5 as P,r as T,aV as B,cA as L}from"./vendor-DHkYh85p.js";import{i as X}from"./state-B-4sS1xO.js";import{A as _}from"./ai-surface-workspace-DEAFZruS.js";import{P as I,aq as C,c as x,_ as F,b as k,V as S,B as O,u as $,a as U,eR as M,eS as V,C as v,W as z,eT as q,eU as K,eV as Q,bG as G,bH as J,bI as Y,bJ as Z,bK as ee,N as te}from"./index-CF4J4R9L.js";import{E as W}from"./entity-note-count-link-DrhjJZ4i.js";import{a as se}from"./life-force-workspace-OfyB9HJM.js";import{P as R}from"./page-hero-DRy5b2MU.js";import"./board-BkDRaMp6.js";import"./ui-C13Nbgas.js";import"./motion-BeD44FeG.js";import"./forms-BFlTgZ3W.js";import"./graph-D6JLqDbD.js";import"./floating-action-menu-Fs_ZiUMo.js";import"./charts-P7EVhIog.js";function D(s,t){return t.find(c=>c.id===s.goalId)??null}function ae(s,t){return s.tagIds.map(c=>t.find(o=>o.id===c)).filter(Boolean)}function ie(s,t){(s.key==="Enter"||s.key===" ")&&(s.preventDefault(),t())}function ne(s,t){switch(s.status){case"backlog":return{label:t.backlog,action:"start",icon:b};case"focus":return{label:t.focus,action:"start",icon:b};case"in_progress":return{label:t.in_progress,nextStatus:"done",action:"move",icon:H};case"blocked":return{label:t.blocked,action:"start",icon:b};default:return null}}function re({tasks:s,timeline:t,goals:c,tags:o,notesSummaryByEntity:j,selectedTaskId:w,onSelectTask:r,onMove:p,onStartTask:u}){const{t:l,formatDate:y}=I(),N={backlog:l("common.dailyRunway.actionBacklog"),focus:l("common.dailyRunway.actionFocus"),in_progress:l("common.dailyRunway.actionProgress"),blocked:l("common.dailyRunway.actionBlocked")};return e.jsxs("div",{className:"grid min-w-0 gap-4 2xl:grid-cols-[minmax(0,1.3fr)_minmax(17rem,0.9fr)]",children:[e.jsxs("div",{className:"min-w-0 rounded-[24px] bg-white/[0.04] p-4",children:[e.jsxs("div",{className:"flex min-w-0 items-start justify-between gap-4",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:l("common.dailyRunway.runwayEyebrow")}),e.jsx(C,{content:"These are the tasks that matter most for today. Click a card to open the task details. Use Start to begin work immediately."})]}),e.jsx("h4",{className:"mt-2 font-display text-2xl text-white",children:l("common.dailyRunway.runwayTitle")})]}),e.jsx(x,{className:"shrink-0 text-[var(--primary)]",children:l(s.length===1?"common.dailyRunway.prioritiesOne":"common.dailyRunway.prioritiesOther",{count:s.length})})]}),e.jsx("div",{className:"mt-4 grid min-w-0 gap-3",children:s.map((a,g)=>{const d=ne(a,N),i=ae(a,o).slice(0,2),n=D(a,c),h=w===a.id,A=F(j,"task",a.id).count;return e.jsxs("article",{role:"button",tabIndex:0,"aria-pressed":h,className:`grid w-full gap-3 rounded-[22px] px-4 py-4 text-left transition ${h?"bg-[linear-gradient(180deg,rgba(192,193,255,0.16),rgba(192,193,255,0.05))] shadow-[inset_0_0_0_1px_rgba(192,193,255,0.2)]":"bg-white/[0.03] hover:bg-white/[0.06]"}`,onClick:()=>r(a.id),onKeyDown:m=>ie(m,()=>r(a.id)),children:[e.jsxs("div",{className:"flex min-w-0 items-start justify-between gap-4",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:l("common.dailyRunway.runwayItem",{index:g+1})}),e.jsxs("div",{className:"mt-2 flex flex-wrap items-center gap-2",children:[n?e.jsx(f,{to:`/goals/${n.id}`,className:"min-w-0 max-w-full transition hover:opacity-85",onClick:m=>m.stopPropagation(),children:e.jsx(k,{kind:"goal",label:n.title,compact:!0,gradient:!1})}):e.jsx(k,{kind:"goal",label:l("common.dailyRunway.unassigned"),compact:!0,gradient:!1}),a.time.activeRunCount>0?e.jsx(x,{className:"bg-emerald-500/12 text-emerald-200",children:"Live"}):null]}),e.jsx("div",{className:"mt-2",children:e.jsx(f,{to:`/tasks/${a.id}`,className:"block min-w-0 max-w-full transition hover:opacity-85",onClick:m=>m.stopPropagation(),children:e.jsx(S,{kind:"task",label:a.title,variant:"heading",size:"md"})})}),e.jsx("p",{className:"mt-2 text-sm leading-6 text-white/60",children:a.description||l("common.dailyRunway.noNote")})]}),e.jsx(x,{className:"shrink-0 self-start",children:a.status.replaceAll("_"," ")})]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsxs(x,{className:"bg-[var(--primary)]/14 text-[var(--primary)]",children:[a.points," xp"]}),e.jsx(W,{entityType:"task",entityId:a.id,count:A}),a.time.totalCreditedSeconds>0?e.jsxs(x,{className:"bg-white/[0.08] text-white/70",children:[Math.floor(a.time.totalCreditedSeconds/60)," min tracked"]}):null,e.jsx(x,{className:"bg-white/[0.08] text-white/70",children:a.effort}),e.jsx(x,{className:"bg-white/[0.08] text-white/70",children:y(a.dueDate)}),i.map(m=>e.jsx(x,{className:"bg-white/[0.08]",style:{color:m.color},children:m.name},m.id))]}),e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/40",children:a.owner}),d?e.jsxs(O,{variant:d.action==="start"?"primary":"secondary",className:"px-3 py-2 text-[11px] uppercase tracking-[0.16em]",onClick:async m=>{if(m.stopPropagation(),d.action==="start"){await u(a.id);return}d.nextStatus&&await p(a.id,d.nextStatus)},children:[e.jsx(d.icon,{className:"mr-2 size-3.5"}),d.label]}):null]})]},a.id)})})]}),e.jsxs("div",{className:"min-w-0 rounded-[24px] bg-white/[0.04] p-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:l("common.dailyRunway.timelineEyebrow")}),e.jsx(C,{content:"This groups today's tasks by status, so you can see what is already moving, what is ready to start, what is blocked, and what is done."})]}),e.jsx("h4",{className:"mt-2 font-display text-2xl text-white",children:l("common.dailyRunway.timelineTitle")}),e.jsx("div",{className:"mt-4 grid min-w-0 gap-3",children:t.map(a=>e.jsxs("div",{className:"min-w-0 overflow-hidden rounded-[20px] bg-white/[0.03] p-4",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsx("div",{className:"font-medium text-white",children:a.label}),e.jsx(x,{className:"bg-white/[0.08] text-white/65",children:a.tasks.length})]}),e.jsxs("div",{className:"mt-3 grid gap-2",children:[a.tasks.slice(0,3).map(g=>{const d=D(g,c);return e.jsxs(f,{to:`/tasks/${g.id}`,className:"flex min-w-0 items-center justify-between gap-3 overflow-hidden rounded-[16px] bg-white/[0.03] px-3 py-3 text-left transition hover:bg-white/[0.06]",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx(S,{kind:"task",label:g.title,className:"max-w-full",labelClassName:"[overflow-wrap:anywhere]"}),e.jsx("div",{className:"mt-2",children:e.jsx(k,{kind:"goal",label:(d==null?void 0:d.title)??l("common.dailyRunway.unassigned"),compact:!0,gradient:!1})})]}),e.jsx(E,{className:"size-4 shrink-0 text-white/35"})]},g.id)}),a.tasks.length===0?e.jsx("div",{className:"text-sm text-white/42",children:l("common.dailyRunway.emptyBucket")}):null]})]},a.id))})]})]})}const le=5;function de(){const s=new Date;s.setHours(0,0,0,0);const t=new Date(s);return t.setDate(t.getDate()+1),{start:s,end:t,from:s.toISOString(),to:t.toISOString()}}function oe(s,t){const c=new Date(s.startAt),o=new Date(s.endAt);return c<t.end&&o>t.start}function ce(s){if(s.isAllDay)return"All day";const t=new Intl.DateTimeFormat(void 0,{hour:"numeric",minute:"2-digit"});return`${t.format(new Date(s.startAt))} - ${t.format(new Date(s.endAt))}`}function Te(){var d;const{t:s}=I(),t=$(),c=P(),o=T.useMemo(()=>de(),[]),j=Array.isArray(t.selectedUserIds)?t.selectedUserIds:[],w=X({queryKey:["forge-calendar-overview",o.from,o.to,...j],queryFn:()=>te({from:o.from,to:o.to,userIds:j})}),r=t.snapshot.today.directive.task,p=t.snapshot.today.milestoneRewards.find(i=>!i.completed)??t.snapshot.today.milestoneRewards[0]??null,u=t.snapshot.risk.blockedTasks[0]??t.snapshot.risk.overdueTasks[0]??null,l=Math.max(0,t.snapshot.metrics.nextLevelXp-t.snapshot.metrics.currentLevelXp),y=T.useMemo(()=>{var i;return(((i=w.data)==null?void 0:i.calendar.events)??[]).filter(n=>!n.deletedAt&&n.status!=="cancelled"&&oe(n,o)).sort((n,h)=>new Date(n.startAt).getTime()-new Date(h.startAt).getTime())},[(d=w.data)==null?void 0:d.calendar.events,o]),N=y.slice(0,le);if(!(t.snapshot.lifeForce!==void 0||r!==null||t.snapshot.overview.topTasks.length>0||t.snapshot.today.dueHabits.length>0||t.snapshot.today.dailyQuests.length>0||t.snapshot.today.milestoneRewards.length>0||y.length>0)&&!w.isLoading)return e.jsxs("div",{className:"grid gap-4",children:[e.jsx(R,{title:"Today",titleText:"Today",description:"Start a task, earn XP, and keep today's work clear.",badge:`${t.snapshot.metrics.weeklyXp} weekly xp`}),e.jsx(U,{eyebrow:s("common.todayPage.heroEyebrow"),title:s("common.todayPage.emptyTitle"),description:s("common.todayPage.emptyDescription"),action:e.jsx(f,{to:"/goals",className:"inline-flex min-h-10 min-w-max shrink-0 items-center justify-center rounded-full bg-[var(--primary)] px-4 py-2 text-sm font-medium whitespace-nowrap text-slate-950 transition hover:opacity-90",children:s("common.todayPage.emptyAction")})})]});const g=[{id:"hero",title:"Today",description:"Compact page header.",defaultWidth:12,defaultHeight:2,removable:!1,surfaceChrome:"none",defaultTitleVisible:!1,defaultDescriptionVisible:!1,render:()=>e.jsx(M,{children:e.jsx(R,{title:"Today",titleText:"Today",description:(r==null?void 0:r.description)??"Start one real task, collect XP, and keep today's work moving.",badge:`${t.snapshot.metrics.weeklyXp} weekly xp`})})},{id:"life-force",title:"Life Force",description:"Instant headroom, AP use today, and tiredness signals.",defaultWidth:12,defaultHeight:3,minWidth:5,render:()=>e.jsx(se,{selectedUserIds:t.selectedUserIds,fallbackLifeForce:t.snapshot.lifeForce,onRefresh:t.refresh})},{id:"metrics",title:"Live metrics",description:"XP, level, and momentum stay visible but lighter than before.",defaultWidth:5,defaultHeight:4,minWidth:4,render:({compact:i})=>e.jsx(V,{children:e.jsxs("div",{className:"grid gap-3 sm:grid-cols-2",children:[e.jsxs(v,{className:"p-4",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/38",children:"Weekly XP"}),e.jsx("div",{className:"mt-2 font-display text-4xl text-[var(--primary)]",children:t.snapshot.metrics.weeklyXp}),e.jsxs("div",{className:"mt-1 text-sm text-white/56",children:[t.snapshot.metrics.totalXp," total XP"]})]}),e.jsxs(v,{className:"p-4",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/38",children:"Level"}),e.jsx("div",{className:"mt-2 font-display text-4xl text-white",children:t.snapshot.metrics.level}),e.jsxs("div",{className:"mt-1 text-sm text-white/56",children:[l," xp to the next level"]}),i?null:e.jsx("div",{className:"mt-3",children:e.jsx(z,{value:t.snapshot.metrics.currentLevelXp/t.snapshot.metrics.nextLevelXp*100,tone:"tertiary"})})]}),e.jsxs(v,{className:"p-4",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/38",children:"Momentum"}),e.jsxs("div",{className:"mt-2 font-display text-4xl text-white",children:[t.snapshot.metrics.momentumScore,"%"]}),e.jsxs("div",{className:"mt-1 text-sm text-white/56",children:[t.snapshot.metrics.streakDays," day streak"]})]}),e.jsxs(v,{className:"p-4",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/38",children:"Next reward"}),e.jsx("div",{className:"mt-2 text-base font-semibold text-white",children:(p==null?void 0:p.title)??"Keep showing up"}),e.jsx("div",{className:"mt-1 text-sm text-white/56",children:(p==null?void 0:p.progressLabel)??"The next visible win comes from a task completion or aligned habit check-in."})]})]})})},{id:"runway",title:"Runway",description:"The execution lane itself can be widened or narrowed.",defaultWidth:7,defaultHeight:6,minWidth:5,render:()=>e.jsx(q,{children:e.jsx(re,{tasks:t.snapshot.overview.topTasks,timeline:t.snapshot.today.timeline,goals:t.snapshot.goals,tags:t.snapshot.tags,notesSummaryByEntity:t.snapshot.dashboard.notesSummaryByEntity,selectedTaskId:(r==null?void 0:r.id)??null,onSelectTask:i=>c(`/tasks/${i}`),onStartTask:async i=>{await t.startTaskNow(i)},onMove:async(i,n)=>{await t.patchTaskStatus(i,n)}})})},{id:"calendar",title:"Calendar",description:"Today's events stay grouped with their results instead of splitting search from outcome.",defaultWidth:5,defaultHeight:5,minWidth:4,render:({compact:i})=>e.jsx(K,{children:e.jsxs("div",{className:"grid gap-3",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("div",{className:"flex min-w-0 items-center gap-3",children:[e.jsx("div",{className:"inline-flex size-10 shrink-0 items-center justify-center rounded-2xl bg-[var(--primary)]/14 text-[var(--primary)]",children:e.jsx(B,{className:"size-4"})}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/38",children:"Today's calendar"}),e.jsx("div",{className:"text-sm font-semibold text-white",children:new Intl.DateTimeFormat(void 0,{weekday:"short",month:"short",day:"numeric"}).format(o.start)}),e.jsxs("div",{className:"text-sm text-white/58",children:[y.length," event",y.length===1?"":"s"]})]})]}),e.jsxs(f,{to:"/calendar",className:"inline-flex shrink-0 items-center gap-2 rounded-full bg-white/[0.06] px-3 py-2 text-xs font-medium text-white/72 transition hover:bg-white/[0.1] hover:text-white",children:["Open calendar",e.jsx(L,{className:"size-3.5"})]})]}),y.length===0?e.jsx("div",{className:"rounded-[18px] bg-white/[0.04] px-4 py-4 text-sm text-white/58",children:"Nothing is scheduled yet for today."}):N.map(n=>e.jsxs("button",{type:"button",className:"grid min-w-0 gap-2 rounded-[18px] bg-white/[0.04] px-3 py-3 text-left transition hover:bg-white/[0.07]",onClick:()=>c("/calendar"),children:[e.jsxs("div",{className:"flex min-w-0 items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("div",{className:"truncate text-sm font-medium text-white",children:n.title}),e.jsx("div",{className:"mt-1 text-sm text-white/58",children:ce(n)})]}),e.jsx(x,{className:"shrink-0 bg-white/[0.08] text-white/72",children:n.originType==="native"?"Forge":n.originType})]}),!i&&n.description?e.jsx("div",{className:"line-clamp-2 text-sm leading-6 text-white/52",children:n.description}):null]},n.id))]})})},{id:"focus",title:"Current focus",description:"Current task, comeback task, and due habits stay in one movable stack.",defaultWidth:12,defaultHeight:4,minWidth:6,render:({compact:i})=>{var n;return e.jsx(Q,{children:e.jsxs("div",{className:"grid min-w-0 gap-4 xl:grid-cols-[minmax(0,1.2fr)_minmax(0,0.8fr)]",children:[e.jsxs("div",{className:"rounded-[20px] bg-white/[0.04] p-4",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/38",children:"Current task"}),r?e.jsx(W,{entityType:"task",entityId:r.id,count:((n=t.snapshot.dashboard.notesSummaryByEntity[`task:${r.id}`])==null?void 0:n.count)??0}):null]}),e.jsx("div",{className:"mt-3 text-base font-semibold text-white",children:(r==null?void 0:r.title)??"Pick a task from the runway"}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-white/58",children:(r==null?void 0:r.description)??"Once a task is active, the timer rail and this panel stay aligned."}),r?e.jsx("button",{type:"button",className:"mt-4 inline-flex min-h-10 items-center justify-center rounded-2xl bg-[rgba(192,193,255,0.16)] px-3.5 py-2 text-sm font-medium text-[var(--primary)] transition hover:bg-[rgba(192,193,255,0.24)]",onClick:async()=>{await t.startTaskNow(r.id)},children:"Start work"}):null]}),e.jsxs("div",{className:"grid gap-3",children:[e.jsxs("div",{className:"rounded-[20px] bg-white/[0.04] p-4",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/38",children:"Recovery task"}),e.jsx("div",{className:"mt-3 text-sm font-semibold text-white",children:(u==null?void 0:u.title)??"No blocked or overdue task is dominating today"}),i?null:e.jsx("div",{className:"mt-2 text-sm leading-6 text-white/56",children:(u==null?void 0:u.description)??"If something slips, it will surface here as the clean comeback move."})]}),e.jsxs("div",{className:"rounded-[20px] bg-white/[0.04] p-4",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/38",children:"Due habits"}),e.jsx("div",{className:"mt-3 grid gap-2",children:t.snapshot.today.dueHabits.slice(0,i?2:3).map(h=>e.jsxs("div",{className:"flex items-center justify-between gap-3 rounded-[16px] bg-white/[0.04] px-3 py-2.5",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"truncate text-sm font-medium text-white",children:h.title}),i?null:e.jsx("div",{className:"text-sm text-white/52",children:h.frequency})]}),e.jsxs(x,{className:"bg-[rgba(78,222,163,0.14)] text-[var(--secondary)]",children:[h.rewardXp," xp"]})]},h.id))})]})]})]})})}},{id:"time",title:"Clock",description:"Optional utility widget.",defaultWidth:3,defaultHeight:2,defaultHidden:!0,render:({compact:i})=>e.jsx(G,{compact:i})},{id:"weather",title:"Weather",description:"Optional utility widget.",defaultWidth:3,defaultHeight:2,defaultHidden:!0,render:({compact:i})=>e.jsx(J,{compact:i})},{id:"mini-calendar",title:"Mini calendar",description:"Optional utility widget.",defaultWidth:4,defaultHeight:3,defaultHidden:!0,render:({compact:i})=>e.jsx(Y,{compact:i})},{id:"spotify",title:"Spotify",description:"Optional utility widget.",defaultWidth:4,defaultHeight:2,defaultHidden:!0,render:()=>e.jsx(Z,{surfaceId:"today"})},{id:"quick-capture",title:"Quick capture",description:"Save a note or wiki draft without leaving Today.",defaultWidth:5,defaultHeight:3,defaultHidden:!0,render:({compact:i})=>{var n;return e.jsx(ee,{compact:i,defaultUserId:t.selectedUserIds[0]??((n=t.snapshot.users[0])==null?void 0:n.id)??null})}}];return e.jsx(_,{surfaceId:"today",baseWidgets:g})}export{Te as TodayPage};
@@ -1 +0,0 @@
1
- import{r as x,j as e,du as B,aL as D,bU as W,aH as Z,cg as P,bJ as $,dv as F,bK as V}from"./vendor-DHkYh85p.js";import{i as U}from"./state-B-4sS1xO.js";import{C as m,aq as b,c as T,u as q,S as G,E as Q,eL as Y}from"./index-CF4J4R9L.js";import{f as K,C as L,X as R,Y as j,T as z,B as v,e as A,a as X,b as E,j as J,P as ee,k as te,l as ae,g as ie}from"./charts-P7EVhIog.js";import{P as se}from"./page-hero-DRy5b2MU.js";import"./board-BkDRaMp6.js";import"./ui-C13Nbgas.js";import"./motion-BeD44FeG.js";import"./forms-BFlTgZ3W.js";import"./graph-D6JLqDbD.js";function _({height:a,children:t}){const o=x.useRef(null),[r,l]=x.useState(0);return x.useEffect(()=>{const i=o.current;if(!i)return;const c=()=>{l(Math.max(0,Math.floor(i.getBoundingClientRect().width)))};if(c(),typeof ResizeObserver>"u")return window.addEventListener("resize",c),()=>window.removeEventListener("resize",c);const f=new ResizeObserver(c);return f.observe(i),()=>f.disconnect()},[]),e.jsx("div",{ref:o,style:{height:a},className:"min-w-0",children:r>24?t({width:r,height:a}):null})}const I=["below_z1","zone_1","zone_2","zone_3","zone_4","zone_5"],H={below_z1:"Below Z1",zone_1:"Z1",zone_2:"Z2",zone_3:"Z3",zone_4:"Z4",zone_5:"Z5"},re={below_z1:"#94a3b8",zone_1:"#38bdf8",zone_2:"#22c55e",zone_3:"#eab308",zone_4:"#f97316",zone_5:"#ef4444"},y={timeInZone:"Each block totals the minutes Forge can place into adaptive HRR zones from stored heart-rate samples. Weekly is the default planning view because it matches common training microcycles; monthly and daily views help detect longer trends or recent spikes.",smartMode:"Smart modes do not change the underlying data. They change the coaching lens: combat readiness prioritizes hard-day spacing and controlled high intensity, aerobic base prioritizes low-zone development, and endurance pro compares the distribution with pyramidal or polarized endurance planning patterns.",interpretation:"This paragraph explains what the selected mode concludes from the latest load balance, zone distribution, hard-day count, and data confidence. It is a planning summary, not a medical clearance.",drivers:"Drivers are the signals helping the selected mode: examples include enough easy/base work, controlled high-zone share, stable acute/chronic load, or improving data quality.",limiters:"Limiters are the signals that should constrain the next block. If Forge lists a limiter, the next target should usually solve that before adding more hard work.",targets:"Next targets translate the selected mode into a practical week and next workout. The range is intentionally bounded so training can progress without turning every good week into a maximal week."};function ne(a){return a.key==="combat_readiness"?"Combat":a.key==="aerobic_base"?"Base":"Endurance"}function oe(a){return a>=82?"signal":a>=65?"default":"meta"}function le(a){switch(a){case"vo2max_4x4":return"4x4 VO2max";case"zone_2_base":return"Zone 2 / base";case"technical_kickboxing":return"Technical kickboxing";case"easy_aerobic":return"Easy aerobic";case"recovery":return"Recovery";default:return a.replaceAll("_"," ")}}function de(a,t){return t==="daily"?a.bucketKey.slice(5):t==="monthly"?a.bucketKey.slice(2):a.bucketKey.replace(/^20/,"'")}function ce(a,t){const o=t==="daily"?30:12;return a.slice(-o).map(r=>({bucket:de(r,t),total:Math.round(r.durationMinutes),load:r.trainingLoad,confidence:r.confidence,...Object.fromEntries(I.map(l=>[l,r.zoneMinutes[l]??0]))}))}function he(a,t){return a.zoneTimeSeries[t]}function xe({mode:a}){return e.jsxs("div",{className:"grid gap-3 lg:grid-cols-2",children:[e.jsxs("div",{className:"rounded-[8px] border border-white/8 bg-white/[0.035] p-3",children:[e.jsxs("div",{className:"flex items-center gap-2 text-[11px] uppercase tracking-[0.16em] text-white/44",children:[e.jsx(W,{className:"size-3.5"}),"Drivers",e.jsx(b,{label:"Explain training drivers",title:"Drivers",content:y.drivers})]}),e.jsx("div",{className:"mt-3 grid gap-2 text-[12px] leading-5 text-white/62",children:(a.drivers.length>0?a.drivers:["No positive driver is strong enough yet."]).map(t=>e.jsx("div",{children:t},t))})]}),e.jsxs("div",{className:"rounded-[8px] border border-white/8 bg-white/[0.035] p-3",children:[e.jsxs("div",{className:"flex items-center gap-2 text-[11px] uppercase tracking-[0.16em] text-white/44",children:[e.jsx(Z,{className:"size-3.5"}),"Limiters",e.jsx(b,{label:"Explain training limiters",title:"Limiters",content:y.limiters})]}),e.jsx("div",{className:"mt-3 grid gap-2 text-[12px] leading-5 text-white/62",children:(a.limitingFactors.length>0?a.limitingFactors:["No major limiter in this mode right now."]).map(t=>e.jsx("div",{children:t},t))})]})]})}function me({trainingLoad:a}){const[t,o]=x.useState(a.trainingIntelligence.defaultMode),[r,l]=x.useState("weekly"),i=a.trainingIntelligence.modes.find(n=>n.key===t)??a.trainingIntelligence.modes[0],c=he(a,r),f=x.useMemo(()=>ce(c,r),[c,r]),C=c.slice(-8).reverse();return i?e.jsxs("section",{className:"grid gap-4 xl:grid-cols-[minmax(0,1.25fr)_minmax(340px,0.75fr)]",children:[e.jsxs(m,{className:"overflow-hidden",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("div",{className:"font-label text-[10px] uppercase tracking-[0.18em] text-white/45",children:"Zone intelligence"}),e.jsx(b,{label:"Explain zone intelligence",title:"Time in zone",content:y.timeInZone})]}),e.jsx("div",{className:"mt-2 text-lg text-white",children:"Time in zone by training block"}),e.jsx("div",{className:"mt-1 max-w-2xl text-[12px] leading-5 text-white/50",children:"Weekly by default because most training plans are adjusted week by week. The stacked bars preserve the full zone split, while the table adds load rate, hard days, and data confidence."})]}),e.jsx("div",{className:"grid grid-cols-3 gap-1 rounded-[8px] border border-white/8 bg-white/[0.035] p-1",children:[["weekly","Week"],["monthly","Month"],["daily","90d"]].map(([n,u])=>e.jsx("button",{type:"button",className:`rounded-[6px] px-3 py-1.5 text-[12px] ${r===n?"bg-white/[0.12] text-white":"text-white/54"}`,onClick:()=>l(n),children:u},n))})]}),e.jsx("div",{className:"mt-5",children:e.jsx(_,{height:320,children:({width:n,height:u})=>e.jsxs(K,{data:f,width:n,height:u,children:[e.jsx(L,{stroke:"rgba(255,255,255,0.08)",vertical:!1}),e.jsx(R,{dataKey:"bucket",tick:{fill:"rgba(255,255,255,0.54)",fontSize:10}}),e.jsx(j,{tick:{fill:"rgba(255,255,255,0.54)",fontSize:10},width:42}),e.jsx(z,{formatter:(p,d)=>[`${Number(p).toFixed(0)} min`,H[d]??String(d)],contentStyle:{background:"rgba(6,10,18,0.96)",border:"1px solid rgba(255,255,255,0.12)",borderRadius:8,color:"white"}}),I.map(p=>e.jsx(v,{dataKey:p,stackId:"zones",fill:re[p],name:p},p))]})})}),e.jsxs("div",{className:"mt-4 overflow-x-auto rounded-[8px] border border-white/8",children:[e.jsxs("div",{className:"grid min-w-[760px] grid-cols-[96px_72px_72px_repeat(6,64px)_72px_80px] bg-white/[0.045] px-3 py-2 text-[10px] uppercase tracking-[0.14em] text-white/42",children:[e.jsx("div",{children:"Block"}),e.jsx("div",{children:"Load"}),e.jsx("div",{children:"TRIMP/min"}),I.map(n=>e.jsx("div",{children:H[n]},n)),e.jsx("div",{children:"Hard"}),e.jsx("div",{children:"Quality"})]}),C.map(n=>e.jsxs("div",{className:"grid min-w-[760px] grid-cols-[96px_72px_72px_repeat(6,64px)_72px_80px] border-t border-white/8 px-3 py-2 text-[12px] text-white/62",children:[e.jsx("div",{className:"text-white",children:n.bucketKey}),e.jsx("div",{children:n.trainingLoad}),e.jsx("div",{children:n.loadPerMinute}),I.map(u=>e.jsx("div",{children:n.zoneMinutes[u]},u)),e.jsx("div",{children:n.hardDayCount}),e.jsx("div",{children:n.confidence})]},n.bucketKey))]})]}),e.jsxs(m,{className:"overflow-hidden",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("div",{className:"font-label text-[10px] uppercase tracking-[0.18em] text-white/45",children:"Smart training mode"}),e.jsx(b,{label:"Explain smart training modes",title:"Training mode",content:y.smartMode})]}),e.jsx("div",{className:"mt-2 text-lg text-white",children:i.label})]}),e.jsxs(T,{tone:oe(i.score),children:[i.score,"/100"]})]}),e.jsx("div",{className:"mt-4 grid grid-cols-3 gap-1 rounded-[8px] border border-white/8 bg-white/[0.035] p-1",children:a.trainingIntelligence.modes.map(n=>e.jsx("button",{type:"button",className:`rounded-[6px] px-2 py-2 text-[12px] ${n.key===i.key?"bg-white/[0.12] text-white":"text-white/54"}`,onClick:()=>o(n.key),children:ne(n)},n.key))}),e.jsxs("div",{className:"mt-4 rounded-[8px] border border-white/8 bg-white/[0.035] p-3",children:[e.jsxs("div",{className:"flex items-center gap-2 text-[11px] uppercase tracking-[0.16em] text-white/44",children:[e.jsx(B,{className:"size-3.5"}),"Interpretation",e.jsx(b,{label:"Explain this interpretation",title:"Interpretation",content:y.interpretation})]}),e.jsx("div",{className:"mt-3 text-[13px] leading-5 text-white/72",children:i.summary}),e.jsxs("div",{className:"mt-3 grid grid-cols-2 gap-2 text-[11px] text-white/50",children:[e.jsxs("div",{children:["Balance: ",i.loadBalance.status]}),e.jsxs("div",{children:["Confidence: ",i.confidence]}),e.jsxs("div",{children:["ACWR: ",i.loadBalance.acuteChronicRatio??"n/a"]}),e.jsxs("div",{children:["Baseline:"," ",i.loadBalance.latestWeekBaselineLoadRatio??"n/a","x"]})]})]}),e.jsx("div",{className:"mt-4",children:e.jsx(xe,{mode:i})}),e.jsxs("div",{className:"mt-4 grid gap-3 rounded-[8px] border border-white/8 bg-white/[0.035] p-3",children:[e.jsxs("div",{className:"flex items-center gap-2 text-[11px] uppercase tracking-[0.16em] text-white/44",children:[e.jsx(D,{className:"size-3.5"}),"Next targets",e.jsx(b,{label:"Explain next training targets",title:"Next targets",content:y.targets})]}),e.jsxs("div",{className:"grid gap-2 text-[12px] leading-5 text-white/62",children:[e.jsxs("div",{children:["Next week: ",i.nextWeekTargets.totalMinutesRange[0],"-",i.nextWeekTargets.totalMinutesRange[1]," min · max"," ",i.nextWeekTargets.maxHardSessions," hard sessions · at least ",i.nextWeekTargets.minimumEasyMinutes," easy/base min."]}),e.jsxs("div",{children:["Next workout:"," ",e.jsx("span",{className:"text-white",children:le(i.nextWorkout.recommendedType)})," ","for ",i.nextWorkout.durationMinutesRange[0],"-",i.nextWorkout.durationMinutesRange[1]," min, ceiling"," ",i.nextWorkout.intensityCeiling,"."]}),e.jsx("div",{className:"text-white/50",children:i.nextWorkout.reason}),i.nextWeekTargets.warning?e.jsx("div",{className:"rounded-[6px] bg-amber-300/10 px-2 py-1 text-amber-100/82",children:i.nextWeekTargets.warning}):null]})]})]})]}):null}const ue={low:"#22c55e",moderate:"#f59e0b",high:"#ef4444"},ge={below_z1:"#94a3b8",zone_1:"#38bdf8",zone_2:"#22c55e",zone_3:"#eab308",zone_4:"#f97316",zone_5:"#ef4444"},h={hero:"Forge estimates cardiovascular training stress from stored workouts, heart-rate samples, adaptive heart-rate-reserve zones, and recent vitals. Use this page to decide whether the next training block should build aerobic base, hold load steady, sharpen intensity, or recover. The numbers support coaching decisions; they are not medical diagnosis.",acuteLoad:"Acute load is the last seven days of Forge's TRIMP-like internal load. It rises when workouts are longer, harder, or spend more time in high heart-rate zones. Compare it with chronic load before adding hard sessions.",chronicBase:"Chronic base is the average weekly load over the last 28 days. It is Forge's estimate of the current load you have recently proven you can absorb.",acwr:"ACWR is acute load divided by chronic weekly load. Values near 1.0 usually mean the current week resembles the recent base. High values ask for recovery checks; low values suggest underloading. Treat it as a flag, not a verdict.",vo2max:"VO2max is the latest available wearable estimate in ml/kg/min. Forge shows the recent change when enough points exist, but wearable VO2max can move with device model, terrain, heat, and workout type.",weeklyMap:"This chart combines weekly internal load, training hours, and the share of time in zones 4 and 5. It helps reveal whether fatigue comes from total volume, hard intensity, or both.",adaptationRadar:"The radar compresses six signals into one coach view: current load, base capacity, acute/chronic balance, heart-rate data quality, high-intensity pressure, and VO2max movement.",intensityTarget:"This compares your recent or all-time low, moderate, and high intensity distribution with broad target bands used in endurance and combat-sport conditioning. The target is a planning reference, not a rule.",hrZones:"These bars show minutes in each adaptive HRR zone. Zone 2 is commonly used for aerobic base, zones 4 and 5 for threshold and VO2max work, and below-zone time often reflects warm-up, recovery, or missing cardiovascular load.",dailyTexture:"Daily texture shows whether load spikes are coming from easy volume, threshold work, or high-intensity minutes. It is useful for spacing hard days and avoiding accidental clusters.",sessionSignals:"Recent workout rows expose the session evidence behind the summary: date, activity, training load, high-zone share, heart-rate response, and data confidence.",sportContribution:"Sport contribution groups load by workout type. In kickboxing and other combat sports, wrist heart rate can undercount short striking spikes, so compare this with how the session actually felt."};function O(a,t=0){return a==null||Number.isNaN(a)?"n/a":`${(a*100).toFixed(t)}%`}function k(a,t=0){return a==null||Number.isNaN(a)?"n/a":a.toFixed(t)}function pe(a){switch(a){case"productive":return{label:"Productive",tone:"signal",text:"Acute load is close to the current chronic base."};case"underloaded":return{label:"Underloaded",tone:"meta",text:"The recent week is below the four-week baseline."};case"overload_watch":return{label:"Watch load",tone:"default",text:"Acute load or strain is elevated enough to deserve recovery checks."};default:return{label:"Building signal",tone:"meta",text:"Forge needs more recent training evidence for a cleaner read."}}}function M({label:a,value:t,detail:o,help:r,icon:l}){return e.jsxs(m,{className:"relative min-h-[136px] overflow-hidden",children:[e.jsx("div",{className:"absolute right-3 top-3 rounded-[8px] border border-white/8 bg-white/[0.045] p-2 text-white/58",children:e.jsx(l,{className:"size-4"})}),e.jsxs("div",{className:"flex max-w-[80%] items-center gap-1.5",children:[e.jsx("div",{className:"font-label text-[10px] uppercase tracking-[0.18em] text-white/45",children:a}),e.jsx(b,{label:`Explain ${a}`,title:a,content:r})]}),e.jsx("div",{className:"mt-4 font-display text-4xl leading-none text-white",children:t}),e.jsx("div",{className:"mt-3 max-w-[24rem] text-[12px] leading-5 text-white/56",children:o})]})}function w({eyebrow:a,title:t,description:o,help:r,action:l}){return e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("div",{className:"font-label text-[10px] uppercase tracking-[0.18em] text-white/45",children:a}),e.jsx(b,{label:`Explain ${a}`,title:t,content:r})]}),e.jsx("div",{className:"mt-2 text-lg text-white",children:t}),o?e.jsx("div",{className:"mt-1 max-w-2xl text-[12px] leading-5 text-white/50",children:o}):null]}),l?e.jsx("div",{className:"shrink-0",children:l}):null]})}function be(a){return a.weeklyLoad.map(t=>({week:t.weekKey.replace(/^20/,"'"),load:t.trainingLoad,hours:t.durationHours,loadPerHour:t.loadPerHour,high:Math.round(t.highPercentage*100),moderate:Math.round(t.moderatePercentage*100),low:Math.round(t.lowPercentage*100)}))}function we(a){return a.dailyLoad.map(t=>({date:t.dateKey.slice(5),load:t.trainingLoad,high:t.highIntensityMinutes,moderate:t.moderateIntensityMinutes,low:t.lowIntensityMinutes}))}function fe(a,t){return(t==="recent"?a.recentIntensityDistribution:a.intensityDistribution).map(r=>({...r,percent:Math.round(r.percentage*100),targetLow:Math.round(r.targetRange[0]*100),targetHigh:Math.round(r.targetRange[1]*100),fill:ue[r.key]??"#f8fafc"}))}function je(a,t){return(t==="recent"?a.recentZoneTotals:a.zoneTotals).map(r=>({...r,minutes:Math.round(r.seconds/60),percent:Math.round(r.percentage*100),fill:ge[r.key]??"#f8fafc"}))}function ve(a){const t=a.summary,o=t.acuteChronicRatio==null?45:Math.max(0,Math.min(100,100-Math.abs(t.acuteChronicRatio-1)*80));return[{axis:"Load",value:Math.min(100,t.acuteLoad7d/3)},{axis:"Base",value:Math.min(100,t.chronicWeeklyLoad28d/3)},{axis:"Balance",value:o},{axis:"Quality",value:Math.min(100,t.averageHeartRateCoverage*100)},{axis:"High",value:Math.min(100,t.highIntensityMinutes7d*1.8)},{axis:"VO2",value:t.vo2MaxDelta==null?50:Math.max(0,Math.min(100,50+t.vo2MaxDelta*10))}]}function ye({sessions:a}){return e.jsxs("div",{className:"overflow-hidden rounded-[8px] border border-white/8",children:[e.jsxs("div",{className:"grid grid-cols-[88px_minmax(118px,1fr)_64px_72px_72px] bg-white/[0.045] px-3 py-2 text-[10px] uppercase tracking-[0.16em] text-white/42",children:[e.jsx("div",{children:"Date"}),e.jsx("div",{children:"Session"}),e.jsx("div",{children:"Load"}),e.jsx("div",{children:"Z4+Z5"}),e.jsx("div",{children:"HR"})]}),e.jsx("div",{className:"max-h-[370px] overflow-auto",children:a.slice(0,20).map(t=>e.jsxs("div",{className:"grid grid-cols-[88px_minmax(118px,1fr)_64px_72px_72px] border-t border-white/6 px-3 py-2 text-[12px] text-white/66",children:[e.jsx("div",{className:"text-white/52",children:t.dateKey.slice(5)}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"truncate text-white/86",children:t.workoutTypeLabel}),e.jsxs("div",{className:"mt-0.5 text-[10px] text-white/42",children:[k(t.durationMinutes,0),"m ·"," ",t.confidence]})]}),e.jsx("div",{className:"text-white",children:k(t.trainingLoad,0)}),e.jsx("div",{children:O(t.highIntensityPercentage)}),e.jsxs("div",{children:[t.averageHr?Math.round(t.averageHr):"n/a",t.maxHr?`/${Math.round(t.maxHr)}`:""]})]},t.id))})]})}function Se(){const a=q(),t=Array.isArray(a.selectedUserIds)?a.selectedUserIds:[],[o,r]=x.useState("recent"),l=U({queryKey:["forge-training-load",...t],queryFn:async()=>(await Y(t)).trainingLoad}),i=l.data,c=pe((i==null?void 0:i.summary.readiness)??"insufficient_data"),f=x.useMemo(()=>i?be(i):[],[i]),C=x.useMemo(()=>i?we(i):[],[i]),n=x.useMemo(()=>i?fe(i,o):[],[o,i]),u=x.useMemo(()=>i?je(i,o):[],[o,i]),p=x.useMemo(()=>i?ve(i):[],[i]);if(l.isLoading)return e.jsx(G,{eyebrow:"Training Load",title:"Loading cardiovascular model",description:"Computing acute load, zone distribution, and target bands from workout evidence.",columns:3,blocks:8});if(l.isError||!i)return e.jsx(Q,{eyebrow:"Training Load",error:l.error??new Error("Training load data unavailable"),onRetry:()=>void l.refetch()});const{summary:d}=i;return e.jsxs("div",{className:"grid gap-5",children:[e.jsx(se,{eyebrow:"Health",entityKind:"habit",title:"Training Load",titleText:"Training Load",description:"Forge estimates cardiovascular training stress from workout duration, heart-rate response, adaptive HRR zones, and recent vitals so you can plan the next training block with clearer load and recovery context.",helpContent:h.hero,badge:`${d.sessionCount} sessions · ${d.reliableSessionCount} high-resolution`,actions:e.jsx(T,{tone:c.tone,children:c.label})}),e.jsxs("section",{className:"grid gap-4 lg:grid-cols-4",children:[M({label:"Acute load",value:k(d.acuteLoad7d,0),detail:`Last 7 days of internal load. ${c.text}`,help:h.acuteLoad,icon:$}),M({label:"Chronic base",value:k(d.chronicWeeklyLoad28d,0),detail:"Average weekly load across the last 28 days.",help:h.chronicBase,icon:F}),M({label:"ACWR",value:k(d.acuteChronicRatio,2),detail:"Acute load divided by chronic weekly load. Useful as a flag, not a verdict.",help:h.acwr,icon:W}),M({label:"VO2 max",value:d.vo2MaxLatest?k(d.vo2MaxLatest,1):"n/a",detail:d.vo2MaxDelta==null?"No delta available yet.":`${d.vo2MaxDelta>=0?"+":""}${d.vo2MaxDelta} since the first recent point.`,help:h.vo2max,icon:V})]}),e.jsx(me,{trainingLoad:i}),e.jsxs("section",{className:"grid gap-4 xl:grid-cols-[minmax(0,1.35fr)_minmax(320px,0.65fr)]",children:[e.jsxs(m,{className:"overflow-hidden",children:[e.jsx(w,{eyebrow:"Weekly load map",title:"Load, hours, and high-intensity share over the last 26 weeks.",description:"Load estimates internal stress; hours show volume; the red line shows how much of each week landed in zones 4 and 5.",help:h.weeklyMap,action:e.jsx(T,{tone:"meta",children:"TRIMP · HRR zones"})}),e.jsx("div",{className:"mt-5",children:e.jsx(_,{height:340,children:({width:s,height:g})=>e.jsxs(A,{data:f,width:s,height:g,children:[e.jsx("defs",{children:e.jsxs("linearGradient",{id:"trainingLoadFill",x1:"0",y1:"0",x2:"0",y2:"1",children:[e.jsx("stop",{offset:"0%",stopColor:"#38bdf8",stopOpacity:.38}),e.jsx("stop",{offset:"100%",stopColor:"#38bdf8",stopOpacity:.04})]})}),e.jsx(L,{stroke:"rgba(255,255,255,0.08)",vertical:!1}),e.jsx(R,{dataKey:"week",tick:{fill:"rgba(255,255,255,0.54)",fontSize:10}}),e.jsx(j,{yAxisId:"load",tick:{fill:"rgba(255,255,255,0.54)",fontSize:10},width:42}),e.jsx(j,{yAxisId:"pct",orientation:"right",domain:[0,100],tick:{fill:"rgba(255,255,255,0.54)",fontSize:10},width:38}),e.jsx(z,{contentStyle:{background:"rgba(6,10,18,0.96)",border:"1px solid rgba(255,255,255,0.12)",borderRadius:8,color:"white"}}),e.jsx(X,{yAxisId:"load",type:"monotone",dataKey:"load",name:"Training load",stroke:"#38bdf8",fill:"url(#trainingLoadFill)",strokeWidth:2}),e.jsx(v,{yAxisId:"load",dataKey:"hours",name:"Hours",fill:"#a78bfa",radius:[3,3,0,0]}),e.jsx(E,{yAxisId:"pct",type:"monotone",dataKey:"high",name:"Z4+Z5 %",stroke:"#ef4444",strokeWidth:2.4,dot:{r:2}})]})})})]}),e.jsxs(m,{className:"overflow-hidden",children:[e.jsx(w,{eyebrow:"Adaptation radar",title:"Current signal balance",description:"A compact coach view of load, base, balance, data quality, high-intensity pressure, and VO2max movement.",help:h.adaptationRadar}),e.jsx("div",{className:"mt-4",children:e.jsx(_,{height:300,children:({width:s,height:g})=>e.jsxs(J,{data:p,width:s,height:g,children:[e.jsx(ee,{stroke:"rgba(255,255,255,0.12)"}),e.jsx(te,{dataKey:"axis",tick:{fill:"rgba(255,255,255,0.64)",fontSize:10}}),e.jsx(ae,{dataKey:"value",stroke:"#22c55e",fill:"#22c55e",fillOpacity:.24}),e.jsx(z,{contentStyle:{background:"rgba(6,10,18,0.96)",border:"1px solid rgba(255,255,255,0.12)",borderRadius:8,color:"white"}})]})})})]})]}),e.jsxs("section",{className:"grid gap-4 xl:grid-cols-[minmax(0,0.8fr)_minmax(0,1.2fr)]",children:[e.jsxs(m,{children:[e.jsx(w,{eyebrow:"Intensity target",title:"Distribution vs target bands",description:"Compare the selected time window with broad low, moderate, and high intensity bands.",help:h.intensityTarget,action:e.jsx("div",{className:"grid grid-cols-2 gap-1 rounded-[8px] border border-white/8 bg-white/[0.035] p-1",children:[["recent","28d"],["all","All"]].map(([s,g])=>e.jsx("button",{type:"button",className:`rounded-[6px] px-3 py-1.5 text-[12px] ${o===s?"bg-white/[0.12] text-white":"text-white/54"}`,onClick:()=>r(s),children:g},s))})}),e.jsx("div",{className:"mt-4 grid gap-3",children:n.map(s=>e.jsxs("div",{className:"grid gap-2",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3 text-[12px]",children:[e.jsx("span",{className:"text-white/74",children:s.label}),e.jsxs("span",{className:"text-white",children:[s.percent,"% · target ",s.targetLow,"-",s.targetHigh,"%"]})]}),e.jsxs("div",{className:"relative h-3 overflow-hidden rounded-full bg-white/[0.08]",children:[e.jsx("div",{className:"absolute inset-y-0 rounded-full bg-white/[0.12]",style:{left:`${s.targetLow}%`,width:`${Math.max(2,s.targetHigh-s.targetLow)}%`}}),e.jsx("div",{className:"relative h-full rounded-full",style:{width:`${Math.max(1,s.percent)}%`,background:s.fill}})]})]},s.key))}),e.jsx("div",{className:"mt-5 grid gap-2 rounded-[8px] border border-white/8 bg-white/[0.035] p-3 text-[12px] leading-5 text-white/54",children:i.targetModel.monitoringNotes.map(s=>e.jsxs("div",{className:"flex gap-2",children:[e.jsx(D,{className:"mt-0.5 size-3.5 shrink-0 text-[var(--primary)]"}),e.jsx("span",{children:s})]},s))})]}),e.jsxs(m,{children:[e.jsx(w,{eyebrow:"HR zones",title:`Detailed zone distribution for ${o==="recent"?"the last 28 days":"all available sessions"}.`,help:h.hrZones}),e.jsx("div",{className:"mt-4",children:e.jsx(_,{height:290,children:({width:s,height:g})=>e.jsxs(K,{data:u,width:s,height:g,children:[e.jsx(L,{stroke:"rgba(255,255,255,0.08)",vertical:!1}),e.jsx(R,{dataKey:"label",interval:0,tick:{fill:"rgba(255,255,255,0.56)",fontSize:10}}),e.jsx(j,{tick:{fill:"rgba(255,255,255,0.56)",fontSize:10},width:38}),e.jsx(z,{formatter:(N,S)=>[S==="minutes"?`${N} min`:`${N}%`,S],contentStyle:{background:"rgba(6,10,18,0.96)",border:"1px solid rgba(255,255,255,0.12)",borderRadius:8,color:"white"}}),e.jsx(v,{dataKey:"minutes",name:"minutes",radius:[4,4,0,0],children:u.map(N=>e.jsx(ie,{fill:N.fill},N.key))})]})})})]})]}),e.jsxs("section",{className:"grid gap-4 xl:grid-cols-[minmax(0,1fr)_420px]",children:[e.jsxs(m,{children:[e.jsx(w,{eyebrow:"Daily load texture",title:"Easy, threshold, and high-intensity minutes against daily load.",help:h.dailyTexture}),e.jsx("div",{className:"mt-4",children:e.jsx(_,{height:310,children:({width:s,height:g})=>e.jsxs(A,{data:C,width:s,height:g,children:[e.jsx(L,{stroke:"rgba(255,255,255,0.08)",vertical:!1}),e.jsx(R,{dataKey:"date",tick:{fill:"rgba(255,255,255,0.54)",fontSize:10}}),e.jsx(j,{yAxisId:"minutes",tick:{fill:"rgba(255,255,255,0.54)",fontSize:10},width:38}),e.jsx(j,{yAxisId:"load",orientation:"right",tick:{fill:"rgba(255,255,255,0.54)",fontSize:10},width:38}),e.jsx(z,{contentStyle:{background:"rgba(6,10,18,0.96)",border:"1px solid rgba(255,255,255,0.12)",borderRadius:8,color:"white"}}),e.jsx(v,{yAxisId:"minutes",dataKey:"low",stackId:"zones",fill:"#22c55e",name:"low min"}),e.jsx(v,{yAxisId:"minutes",dataKey:"moderate",stackId:"zones",fill:"#f59e0b",name:"threshold min"}),e.jsx(v,{yAxisId:"minutes",dataKey:"high",stackId:"zones",fill:"#ef4444",name:"high min"}),e.jsx(E,{yAxisId:"load",type:"monotone",dataKey:"load",stroke:"#38bdf8",strokeWidth:2.2,dot:!1})]})})})]}),e.jsxs(m,{children:[e.jsx(w,{eyebrow:"Session signals",title:"Recent workouts",help:h.sessionSignals,action:e.jsxs(T,{tone:"meta",children:[d.hardDayCount7d," hard days / 7d"]})}),e.jsx("div",{className:"mt-4",children:e.jsx(ye,{sessions:i.sessionSignals})})]})]}),e.jsxs("section",{className:"grid gap-4 lg:grid-cols-[minmax(0,1fr)_minmax(0,1fr)]",children:[e.jsxs(m,{children:[e.jsx(w,{eyebrow:"Sport contribution",title:"Load by workout type",help:h.sportContribution}),e.jsx("div",{className:"mt-3 grid gap-3",children:i.activityBreakdown.slice(0,8).map(s=>e.jsxs("div",{className:"grid gap-2 rounded-[8px] border border-white/8 bg-white/[0.035] p-3 sm:grid-cols-[minmax(0,1fr)_76px_76px_76px]",children:[e.jsxs("div",{children:[e.jsx("div",{className:"truncate text-sm text-white",children:s.workoutTypeLabel}),e.jsxs("div",{className:"mt-1 text-[11px] text-white/46",children:[s.sessionCount," sessions ·"," ",s.activityFamilyLabel]})]}),e.jsxs("div",{className:"text-[12px] text-white/62",children:[e.jsxs("span",{className:"block text-white",children:[s.durationHours,"h"]}),"volume"]}),e.jsxs("div",{className:"text-[12px] text-white/62",children:[e.jsx("span",{className:"block text-white",children:s.trainingLoad}),"load"]}),e.jsxs("div",{className:"text-[12px] text-white/62",children:[e.jsx("span",{className:"block text-white",children:O(s.highPercentage)}),"high"]})]},s.workoutType))})]}),e.jsxs(m,{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(P,{className:"size-4 text-amber-300"}),e.jsx("div",{className:"font-label text-[10px] uppercase tracking-[0.18em] text-white/45",children:"Interpretation guardrails"})]}),e.jsxs("div",{className:"mt-4 grid gap-3 text-[12px] leading-5 text-white/56",children:[e.jsx("p",{children:"Forge is estimating training stress from heart-rate reserve zones and a TRIMP-like load. This is good for trend decisions, but it is not a substitute for lactate testing, gas exchange thresholds, or coach-led periodization."}),e.jsx("p",{children:"Combat sports add sensor noise: wrist HR can miss short spikes during punching and clinch work. Treat high-intensity minutes as minimum evidence when the session had a lot of arm motion."}),e.jsx("p",{children:"The practical target is not maximum Z5. Keep hard combat sessions meaningful, then add easy aerobic base when the high-intensity share is already high."})]})]})]})]})}export{Se as TrainingLoadPage};
@@ -1 +0,0 @@
1
- import{r as t}from"./vendor-DHkYh85p.js";function a(e){return e.replaceAll("\\","\\\\").replaceAll('"','\\"')}function c(e){t.useEffect(()=>{if(!e||typeof document>"u")return;const n=window.requestAnimationFrame(()=>{const r=document.querySelector(`[data-psyche-focus-id="${a(e)}"]`);r&&r.scrollIntoView({behavior:"smooth",block:"center",inline:"nearest"})});return()=>window.cancelAnimationFrame(n)},[e])}function s(e){return e?"border-[rgba(125,211,252,0.28)] bg-[linear-gradient(180deg,rgba(125,211,252,0.14),rgba(255,255,255,0.06))] shadow-[0_24px_60px_rgba(56,189,248,0.14)]":""}export{s as p,c as u};
@@ -1 +0,0 @@
1
- import{r as d,j as e,bL as B,dx as ue,bJ as pe,bU as be,aG as je,du as ne,dy as ve,bI as fe,bs as we,dz as Ne,cL as ye}from"./vendor-DHkYh85p.js";import{j as ke,i as Ce,k as u}from"./state-B-4sS1xO.js";import{P as Ge}from"./page-hero-DRy5b2MU.js";import{u as Se,eW as D,eX as Fe,eY as Me,eZ as Le,e_ as Pe,e$ as $e,f0 as Be,f1 as Te,L as Ee,E as Ie,C as h,c as f,T as Ae,I as m,B as p,Z as de,f2 as Ke}from"./index-CF4J4R9L.js";import"./board-BkDRaMp6.js";import"./ui-C13Nbgas.js";import"./motion-BeD44FeG.js";import"./forms-BFlTgZ3W.js";import"./graph-D6JLqDbD.js";function H(s){return typeof s=="number"&&Number.isFinite(s)?s:null}function v(s){return typeof s=="string"&&s.trim()?s:null}function l(s,r=0){const i=H(s);return i===null?"n/a":i.toFixed(r)}function le(s,r=0){const i=H(s);return i===null?"n/a":`${i>0?"+":""}${i.toFixed(r)}`}function g(s){const r=H(s);return r===null?"n/a":`${r.toFixed(1)}/10`}function Qe(s){return Array.isArray(s)?s.filter(r=>!!r&&typeof r=="object"&&!Array.isArray(r)):[]}function x({label:s,value:r,detail:i,icon:b,tone:o="default"}){const w=o==="green"?"bg-emerald-300/10 text-emerald-100":o==="amber"?"bg-amber-300/10 text-amber-100":o==="rose"?"bg-rose-300/10 text-rose-100":"bg-indigo-300/10 text-indigo-100";return e.jsxs(h,{className:"grid gap-4 border-white/8 bg-white/[0.045] p-5",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsx("div",{className:de("rounded-2xl p-2.5",w),children:e.jsx(b,{className:"size-5"})}),e.jsx("div",{className:"text-right text-[11px] uppercase tracking-[0.16em] text-white/38",children:s})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-3xl font-semibold text-white",children:r}),e.jsx("p",{className:"mt-2 text-sm leading-6 text-white/58",children:i})]})]})}function oe({meal:s,onLogAgain:r,pending:i=!1}){const b=s.items.slice(0,3).map(o=>o.name).join(", ");return e.jsxs("div",{className:"grid gap-2 rounded-[22px] border border-white/8 bg-white/[0.04] p-4",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"truncate text-sm font-medium text-white",children:s.mealLabel??"Meal"}),e.jsx("div",{className:"truncate text-xs text-white/42",children:b||s.notes||"No items"})]}),e.jsxs(f,{className:"bg-white/[0.08] text-white/70",children:[s.totals.calories.toFixed(0)," kcal"]})]}),e.jsxs("div",{className:"grid grid-cols-3 gap-2 text-xs text-white/56",children:[e.jsxs("span",{children:[s.totals.proteinGrams.toFixed(0),"g protein"]}),e.jsxs("span",{children:[s.totals.fiberGrams.toFixed(0),"g fiber"]}),e.jsx("span",{children:s.confirmationState})]}),r?e.jsxs(p,{type:"button",size:"sm",variant:"ghost",pending:i,onClick:()=>r(s),children:[e.jsx(ye,{className:"size-4"}),"Log again"]}):null]})}function ce({food:s,onLog:r,pending:i}){return e.jsxs("div",{className:"grid gap-3 rounded-[22px] border border-white/8 bg-white/[0.04] p-4 md:grid-cols-[minmax(0,1fr)_auto] md:items-center",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"truncate text-sm font-medium text-white",children:s.name}),e.jsx("div",{className:"mt-1 truncate text-xs text-white/44",children:[s.brand,s.servingLabel,s.source].filter(Boolean).join(" · ")}),e.jsxs("div",{className:"mt-3 flex flex-wrap gap-2 text-xs text-white/56",children:[e.jsxs("span",{children:[l(s.calories)," kcal"]}),e.jsxs("span",{children:[l(s.proteinGrams),"g protein"]}),e.jsxs("span",{children:[l(s.fiberGrams),"g fiber"]}),s.novaGroup?e.jsxs("span",{children:["NOVA ",s.novaGroup]}):null]})]}),e.jsxs(p,{type:"button",size:"sm",variant:"secondary",pending:i,onClick:()=>r(s),children:[e.jsx(B,{className:"size-4"}),"Log"]})]})}function Oe(){var re;const s=Se(),r=ke(),i=s.selectedUserIds,b=d.useMemo(()=>["forge-weight-loss-view",...i],[i]),[o,w]=d.useState(""),[T,E]=d.useState(""),[U,I]=d.useState(""),[A,me]=d.useState(""),[K,ge]=d.useState(""),[k,V]=d.useState(""),[C,O]=d.useState(""),[G,Z]=d.useState(""),[S,J]=d.useState(""),j=Ce({queryKey:b,queryFn:async()=>(await Ke(i)).weightLoss}),N=()=>r.invalidateQueries({queryKey:b}),X=u({mutationFn:async()=>D({mealLabel:"Quick log",source:"manual",confirmationState:"confirmed",notes:o.trim()||null,items:[{name:o.trim()||"Manual food entry",quantity:1,unit:"entry",calories:Number(T)||null,proteinGrams:Number(U)||null,confidence:.55,tags:["quick-log"]}]},i),onSuccess:()=>{w(""),E(""),I(""),N()}}),Y=u({mutationFn:async()=>Fe({text:o,mealLabel:"ChatGPT parsed meal",userIds:i}),onSuccess:()=>{w(""),E(""),I(""),N()}}),Q=u({mutationFn:async()=>(await Me({query:A,userIds:i})).foods}),q=u({mutationFn:async()=>(await Le({barcode:K,userIds:i})).food}),F=u({mutationFn:async t=>D({mealLabel:"Catalog food",source:t.barcode?"barcode":"manual",confirmationState:"confirmed",items:[{name:t.name,brand:t.brand,quantity:1,unit:t.servingLabel??"serving",calories:t.calories,proteinGrams:t.proteinGrams,carbohydrateGrams:t.carbohydrateGrams,fatGrams:t.fatGrams,fiberGrams:t.fiberGrams,sugarGrams:t.sugarGrams,sodiumMg:t.sodiumMg,potassiumMg:t.potassiumMg,caffeineMg:t.caffeineMg,alcoholGrams:t.alcoholGrams,glycemicIndex:t.glycemicIndex,novaGroup:t.novaGroup,tags:t.tags,confidence:.82}]},i),onSuccess:()=>{N()}}),M=u({mutationFn:async t=>D({mealLabel:t.mealLabel??"Saved meal",source:"saved_meal",confirmationState:"confirmed",notes:t.notes,items:t.items.map(a=>({name:a.name,brand:a.brand,quantity:a.quantity,unit:a.unit,calories:a.calories,proteinGrams:a.proteinGrams,carbohydrateGrams:a.carbohydrateGrams,fatGrams:a.fatGrams,fiberGrams:a.fiberGrams,sugarGrams:a.sugarGrams,sodiumMg:a.sodiumMg,potassiumMg:a.potassiumMg,caffeineMg:a.caffeineMg,alcoholGrams:a.alcoholGrams,glycemicIndex:a.glycemicIndex,novaGroup:a.novaGroup,fermented:a.fermented,probiotic:a.probiotic,fodmapLevel:a.fodmapLevel,tags:a.tags,confidence:a.confidence??.85}))},i),onSuccess:()=>{N()}}),ee=u({mutationFn:async()=>{await Promise.all([k.trim()?Pe({weightKg:Number(k)},i):Promise.resolve(),C.trim()?$e({energy:Number(C),timeRelation:"current"},i):Promise.resolve(),G.trim()?Be({bloating:Number(G)},i):Promise.resolve(),S.trim()?Te({aestheticScore:Number(S)},i):Promise.resolve()])},onSuccess:()=>{V(""),O(""),Z(""),J(""),N()}});if(j.isLoading)return e.jsx(Ee,{title:"Loading weight-loss signals",description:"Combining food logs, HealthKit, movement, workouts, body check-ins, subjective state, and gut signals."});if(j.isError||!j.data)return e.jsx(Ie,{error:j.error??new Error("Weight-loss view unavailable"),onRetry:()=>void j.refetch()});const n=j.data,c=n.todayLedger,y=c.totals,_=y.calories,z=c.targetCalories-_,xe=c.targetCalories>0?Math.min(140,Math.max(0,_/c.targetCalories*100)):0,L=n.energyModel,te=n.weightTrend,P=n.foodQuality,W=n.trainingFuel,R=n.subjective,se=n.gut,$=n.dataQuality,ae=Qe(n.hypotheses),he=Q.data??[],ie=q.data??null;return e.jsxs("div",{className:"mx-auto grid w-full max-w-[1500px] gap-5",children:[e.jsx(Ge,{title:"Weight Loss",description:"A Forge-native body composition lab: calories and protein, but also sport fuel, visual look, energy, gut comfort, cravings, and testable food hypotheses.",badge:`${n.summary.loggedMealCount} food logs`}),e.jsxs("section",{className:"grid gap-4 xl:grid-cols-4",children:[e.jsx(x,{label:"Today",value:`${_.toFixed(0)} kcal`,detail:`${z.toFixed(0)} kcal remaining against a ${c.targetCalories.toFixed(0)} kcal target.`,icon:B,tone:z>=0?"green":"rose"}),e.jsx(x,{label:"Protein",value:`${y.proteinGrams.toFixed(0)}g`,detail:`${n.target.proteinGramsTarget.toFixed(0)}g target. Forge treats protein as the anchor for dieting without looking flat or under-recovered.`,icon:ue}),e.jsx(x,{label:"Energy gap",value:le(L.estimatedDailyEnergyBalanceKcal),detail:`TDEE estimate ${l(L.estimatedTdeeKcal)} kcal, movement ${l(L.movementCaloriesKcal)} kcal, active burn ${l(L.activeBurnKcal)} kcal.`,icon:pe,tone:"amber"}),e.jsx(x,{label:"Weight trend",value:le(te.sevenDayRateKg,2),detail:`Latest ${l(te.latestWeightKg,1)} kg. Trend uses check-ins, not noisy single weigh-ins.`,icon:be,tone:"green"})]}),e.jsxs("section",{className:"grid gap-4 xl:grid-cols-[minmax(0,1.08fr)_minmax(360px,0.92fr)]",children:[e.jsxs(h,{className:"grid gap-5 border-white/8 bg-[radial-gradient(circle_at_top_left,rgba(52,211,153,0.14),transparent_34%),linear-gradient(180deg,rgba(14,21,34,0.98),rgba(8,12,24,0.98))] p-5",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.18em] text-white/40",children:"Quick capture"}),e.jsx("h2",{className:"mt-1 text-2xl font-semibold text-white",children:"Food, photo description, or rough meal"}),e.jsx("p",{className:"mt-2 max-w-3xl text-sm leading-6 text-white/58",children:"Use natural language for ChatGPT parsing through the `openai-codex` subscription connection, or log manually when you only know rough calories."})]}),e.jsx(f,{className:"bg-emerald-300/10 text-emerald-50",children:"subscription parser"})]}),e.jsx(Ae,{value:o,onChange:t=>w(t.target.value),placeholder:"Example: 3 eggs, two slices of sourdough, Greek yogurt with honey, espresso. Felt sharp for training but a bit bloated later."}),e.jsxs("div",{className:"grid gap-3 md:grid-cols-2",children:[e.jsx(m,{inputMode:"decimal",value:T,onChange:t=>E(t.target.value),placeholder:"Manual kcal"}),e.jsx(m,{inputMode:"decimal",value:U,onChange:t=>I(t.target.value),placeholder:"Manual protein g"})]}),e.jsxs("div",{className:"flex flex-wrap gap-3",children:[e.jsxs(p,{type:"button",pending:Y.isPending,disabled:!o.trim(),onClick:()=>Y.mutate(),children:[e.jsx(je,{className:"size-4"}),"Parse with ChatGPT"]}),e.jsxs(p,{type:"button",variant:"secondary",pending:X.isPending,disabled:!o.trim()&&!T.trim(),onClick:()=>X.mutate(),children:[e.jsx(B,{className:"size-4"}),"Manual log"]})]}),n.recentMeals.length>0?e.jsxs("div",{className:"grid gap-3",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.18em] text-white/40",children:"Saved and recent meals"}),e.jsx("div",{className:"grid gap-3 md:grid-cols-2",children:n.recentMeals.slice(0,4).map(t=>e.jsx(oe,{meal:t,pending:M.isPending,onLogAgain:a=>M.mutate(a)},`saved-${t.id}`))})]}):null]}),e.jsxs(h,{className:"grid gap-4 border-white/8 bg-white/[0.045] p-5",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.18em] text-white/40",children:"Body state"}),e.jsx("h2",{className:"mt-1 text-xl font-semibold text-white",children:"Check-in loop"})]}),e.jsxs("div",{className:"grid gap-3 sm:grid-cols-2",children:[e.jsx(m,{value:k,inputMode:"decimal",onChange:t=>V(t.target.value),placeholder:"Weight kg"}),e.jsx(m,{value:C,inputMode:"decimal",onChange:t=>O(t.target.value),placeholder:"Energy 0-10"}),e.jsx(m,{value:G,inputMode:"decimal",onChange:t=>Z(t.target.value),placeholder:"Bloating 0-10"}),e.jsx(m,{value:S,inputMode:"decimal",onChange:t=>J(t.target.value),placeholder:"Look 0-10"})]}),e.jsxs(p,{type:"button",variant:"secondary",pending:ee.isPending,disabled:!k.trim()&&!C.trim()&&!G.trim()&&!S.trim(),onClick:()=>ee.mutate(),children:[e.jsx(ne,{className:"size-4"}),"Save check-in"]}),e.jsxs("div",{className:"grid grid-cols-2 gap-3 text-sm text-white/58",children:[e.jsxs("div",{className:"rounded-[18px] border border-white/8 bg-white/[0.04] p-3",children:["Energy avg ",e.jsx("span",{className:"text-white",children:g(R.averageEnergy)})]}),e.jsxs("div",{className:"rounded-[18px] border border-white/8 bg-white/[0.04] p-3",children:["Gut comfort ",e.jsx("span",{className:"text-white",children:g(se.gutComfortScore)})]}),e.jsxs("div",{className:"rounded-[18px] border border-white/8 bg-white/[0.04] p-3",children:["Look avg ",e.jsx("span",{className:"text-white",children:g((re=n.appearanceCheckins[0])==null?void 0:re.aestheticScore)})]}),e.jsxs("div",{className:"rounded-[18px] border border-white/8 bg-white/[0.04] p-3",children:["Cravings ",e.jsx("span",{className:"text-white",children:g(R.averageCravings)})]})]})]})]}),e.jsxs("section",{className:"grid gap-4 xl:grid-cols-[minmax(360px,0.9fr)_minmax(0,1.1fr)]",children:[e.jsxs(h,{className:"grid gap-4 border-white/8 bg-white/[0.045] p-5",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.18em] text-white/40",children:"Catalog"}),e.jsx("h2",{className:"mt-1 text-xl font-semibold text-white",children:"Food search and barcode"})]}),e.jsx(ve,{className:"size-5 text-white/42"})]}),e.jsxs("div",{className:"grid gap-3 md:grid-cols-[minmax(0,1fr)_auto]",children:[e.jsx(m,{value:A,onChange:t=>me(t.target.value),placeholder:"Search food database"}),e.jsx(p,{type:"button",variant:"secondary",pending:Q.isPending,disabled:!A.trim(),onClick:()=>Q.mutate(),children:"Search"})]}),e.jsxs("div",{className:"grid gap-3 md:grid-cols-[minmax(0,1fr)_auto]",children:[e.jsx(m,{value:K,onChange:t=>ge(t.target.value),placeholder:"Barcode"}),e.jsx(p,{type:"button",variant:"secondary",pending:q.isPending,disabled:!K.trim(),onClick:()=>q.mutate(),children:"Lookup"})]}),ie?e.jsx(ce,{food:ie,pending:F.isPending,onLog:t=>F.mutate(t)}):null,e.jsx("div",{className:"grid gap-3",children:he.slice(0,6).map(t=>e.jsx(ce,{food:t,pending:F.isPending,onLog:a=>F.mutate(a)},t.id))})]}),e.jsxs(h,{className:"grid gap-5 border-white/8 bg-white/[0.045] p-5",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.18em] text-white/40",children:"Today ledger"}),e.jsx("h2",{className:"mt-1 text-xl font-semibold text-white",children:"Calories, macros, and meal evidence"})]}),e.jsxs(f,{className:"bg-white/[0.08] text-white/70",children:[c.meals.length," meals"]})]}),e.jsxs("div",{children:[e.jsx("div",{className:"h-3 overflow-hidden rounded-full bg-white/[0.08]",children:e.jsx("div",{className:de("h-full rounded-full",z>=0?"bg-emerald-300":"bg-rose-300"),style:{width:`${Math.min(100,xe)}%`}})}),e.jsxs("div",{className:"mt-3 grid gap-2 text-sm text-white/58 sm:grid-cols-4",children:[e.jsxs("span",{children:[y.carbohydrateGrams.toFixed(0),"g carbs"]}),e.jsxs("span",{children:[y.fatGrams.toFixed(0),"g fat"]}),e.jsxs("span",{children:[y.fiberGrams.toFixed(0),"g fiber"]}),e.jsxs("span",{children:[c.unconfirmedCount," unconfirmed"]})]})]}),e.jsx("div",{className:"grid gap-3",children:c.meals.length>0?c.meals.map(t=>e.jsx(oe,{meal:t,pending:M.isPending,onLogAgain:a=>M.mutate(a)},t.id)):e.jsx("div",{className:"rounded-[22px] border border-dashed border-white/12 p-5 text-sm text-white/50",children:"No meals logged today yet."})})]})]}),e.jsxs("section",{className:"grid gap-4 xl:grid-cols-4",children:[e.jsx(x,{label:"Food quality",value:g(P.qualityScore),detail:`Fiber density ${l(P.fiberPer1000Kcal,1)}g/1000 kcal, protein density ${l(P.proteinPer1000Kcal,1)}g/1000 kcal, ultra-processed share ${l(P.ultraProcessedShare,0)}%.`,icon:B,tone:"green"}),e.jsx(x,{label:"Training fuel",value:g(W.fuelingScore),detail:`Recent workout load ${l(W.recentTrainingLoad)} with ${l(W.carbsPerTrainingLoad,1)}g carbs per load unit.`,icon:fe,tone:"amber"}),e.jsx(x,{label:"Subjective",value:g(R.averageFocus),detail:"Focus, energy, hunger, cravings, and performance are tracked as food-effect evidence, not diary fluff.",icon:ne}),e.jsx(x,{label:"Gut",value:g(se.averageBloating),detail:"Bloating, reflux, stool type, and suspected triggers help Forge connect food choices to comfort and look.",icon:we,tone:"rose"})]}),e.jsxs("section",{className:"grid gap-4 xl:grid-cols-[minmax(0,1fr)_minmax(360px,0.8fr)]",children:[e.jsxs(h,{className:"grid gap-4 border-white/8 bg-white/[0.045] p-5",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.18em] text-white/40",children:"Hypotheses"}),e.jsx("h2",{className:"mt-1 text-xl font-semibold text-white",children:"Food and body pattern candidates"})]}),e.jsx("div",{className:"grid gap-3 md:grid-cols-2",children:ae.length>0?ae.slice(0,6).map((t,a)=>e.jsxs("div",{className:"rounded-[22px] border border-white/8 bg-white/[0.04] p-4",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsx(f,{className:"bg-indigo-300/10 text-indigo-50",children:v(t.metric)??"pattern"}),e.jsx("span",{className:"text-xs text-white/40",children:l(t.confidence,2)})]}),e.jsx("div",{className:"mt-3 text-sm font-medium text-white",children:v(t.label)??"Candidate pattern"}),e.jsx("p",{className:"mt-2 text-sm leading-6 text-white/56",children:v(t.description)??"Forge needs more paired meals and check-ins to harden this signal."})]},String(t.key??a))):e.jsx("div",{className:"rounded-[22px] border border-dashed border-white/12 p-5 text-sm text-white/50 md:col-span-2",children:"Log meals plus energy, gut, and look check-ins for a few days to generate pattern candidates."})})]}),e.jsxs(h,{className:"grid content-start gap-4 border-white/8 bg-white/[0.045] p-5",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"rounded-2xl bg-cyan-300/10 p-2.5 text-cyan-100",children:e.jsx(Ne,{className:"size-5"})}),e.jsxs("div",{children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.18em] text-white/40",children:"Experiments"}),e.jsx("h2",{className:"text-xl font-semibold text-white",children:"N-of-1 lab"})]})]}),e.jsxs("div",{className:"grid gap-3",children:[n.experiments.slice(0,4).map((t,a)=>e.jsxs("div",{className:"rounded-[22px] border border-white/8 bg-white/[0.04] p-4",children:[e.jsx("div",{className:"text-sm font-medium text-white",children:v(t.title)??"Nutrition experiment"}),e.jsx("p",{className:"mt-2 text-sm leading-6 text-white/56",children:v(t.hypothesis)??v(t.intervention)??"No hypothesis recorded."})]},String(t.id??a))),n.experiments.length===0?e.jsx("div",{className:"rounded-[22px] border border-dashed border-white/12 p-5 text-sm text-white/50",children:"Start experiments from OpenClaw or the API: caffeine timing, fiber ramp, low-FODMAP trial, carb timing, sodium/puffiness, or pre-training fueling."}):null]})]})]}),e.jsxs(h,{className:"grid gap-4 border-white/8 bg-white/[0.045] p-5",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.18em] text-white/40",children:"Data quality"}),e.jsx("h2",{className:"mt-1 text-xl font-semibold text-white",children:"Confidence, coverage, and next evidence"})]}),e.jsxs(f,{className:"bg-white/[0.08] text-white/70",children:[n.summary.dataQualityScore.toFixed(0),"% coverage"]})]}),e.jsxs("div",{className:"grid gap-3 md:grid-cols-3",children:[e.jsxs("div",{className:"rounded-[22px] border border-white/8 bg-white/[0.04] p-4",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/36",children:"Source confidence"}),e.jsx("div",{className:"mt-2 text-lg font-semibold text-white",children:$.sourceConfidence}),e.jsx("p",{className:"mt-2 text-sm leading-6 text-white/54",children:"Food parsing stays candidate-based until accepted; wearable burn is treated as a trend input."})]}),e.jsxs("div",{className:"rounded-[22px] border border-white/8 bg-white/[0.04] p-4",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/36",children:"Missing check-ins"}),e.jsx("div",{className:"mt-3 flex flex-wrap gap-2",children:$.missingHighValueCheckins.length>0?$.missingHighValueCheckins.map(t=>e.jsx(f,{className:"bg-amber-300/10 text-amber-50",children:t},t)):e.jsx("span",{className:"text-sm text-white/58",children:"Core evidence loop is covered."})})]}),e.jsxs("div",{className:"rounded-[22px] border border-white/8 bg-white/[0.04] p-4",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/36",children:"Next best cue"}),e.jsx("p",{className:"mt-2 text-sm leading-6 text-white/58",children:$.notes}),e.jsxs("div",{className:"mt-3 text-xs text-white/42",children:[c.unconfirmedCount," unconfirmed candidate",c.unconfirmedCount===1?"":"s"]})]})]})]})]})}export{Oe as WeightLossPage};
@@ -1,5 +0,0 @@
1
- import{r as x,j as e,c7 as Ae,aC as ra,bk as na,bB as ze,bX as vt,ca as la,cm as ia,dG as oa,dH as _t,dI as Rt,aG as Et,b2 as da,dJ as Ot,dD as Pt,dK as Kt,dL as At,dM as zt,cr as ca,cc as ua,b5 as pa}from"./vendor-DHkYh85p.js";import{O as ha}from"./open-in-graph-button-IXe9SGth.js";import{P as ma}from"./page-hero-DRy5b2MU.js";import{fr as xa,fs as ga,F as C,B as I,a9 as Mt,b as jt,fp as ba,Z as R,aq as V,Q as fa,ft as ya,fu as wa,aU as va,fv as kt,fw as ja,fx as ka,fy as Na,fz as Ca,fA as Sa,fB as Ia,fC as Ta,L as Fa,a as _a,E as Ra}from"./index-CF4J4R9L.js";import{i as Ea,B as Oa,a as Pa,b as Ka,c as Aa,H as za,P as Nt}from"./graph-D6JLqDbD.js";import{R as Ma,P as Wa,O as $a,C as Ha,T as La,D as Ua,a as qa}from"./ui-C13Nbgas.js";import{F as Ba}from"./faceted-token-search-BxRRcM3q.js";import"./state-B-4sS1xO.js";import"./board-BkDRaMp6.js";import"./motion-BeD44FeG.js";import"./forms-BFlTgZ3W.js";function je(a){switch(a){case"exec":return 4;case"read_write":return 3;case"write":return 2;case"read":default:return 1}}function Va(a,i){return je(a)>=je(i)?a:i}function Ct(a,i){return a==="forge.search_entities"?"Search across Forge entities. You can optionally narrow the search to specific entity types.":a==="forge.create_note"?"Create a Forge note from generated content or captured markdown.":a==="forge.update_task_status"?"Move a task between execution states such as backlog, focus, in progress, blocked, and done.":i.sort((r,l)=>l.length-r.length)[0]??"Workbench tool"}function Da(a){const i=new Map;for(const r of a)for(const l of r.tools){const c=i.get(l.key);if(!c){i.set(l.key,{key:l.key,label:l.label,description:Ct(l.key,[l.description]),accessMode:l.accessMode,argsSchema:l.argsSchema,sources:[r.title],sourceSurfaceIds:r.surfaceId?[r.surfaceId]:[]});continue}c.accessMode=Va(c.accessMode,l.accessMode),c.label=c.label.length>=l.label.length?c.label:l.label,c.description=Ct(l.key,[c.description,l.description]),c.argsSchema=c.argsSchema??l.argsSchema,c.sources.includes(r.title)||c.sources.push(r.title),r.surfaceId&&!c.sourceSurfaceIds.includes(r.surfaceId)&&c.sourceSurfaceIds.push(r.surfaceId)}return[...i.values()].sort((r,l)=>{const c=je(l.accessMode)-je(r.accessMode);return c!==0?c:r.label.localeCompare(l.label)})}const w="rounded-[18px] border border-white/10 bg-black/20 px-4 py-3 text-sm text-white outline-none",We=[...ya],Wt={summary:"border-amber-300/28 bg-amber-300/12 text-amber-100",markdown:"border-violet-300/28 bg-violet-300/12 text-violet-100",text:"border-sky-300/28 bg-sky-300/12 text-sky-100",number:"border-emerald-300/28 bg-emerald-300/12 text-emerald-100",boolean:"border-lime-300/28 bg-lime-300/12 text-lime-100",entity:"border-fuchsia-300/28 bg-fuchsia-300/12 text-fuchsia-100",entity_list:"border-pink-300/28 bg-pink-300/12 text-pink-100",context:"border-cyan-300/28 bg-cyan-300/12 text-cyan-100",metrics:"border-teal-300/28 bg-teal-300/12 text-teal-100",filters:"border-orange-300/28 bg-orange-300/12 text-orange-100",record:"border-indigo-300/28 bg-indigo-300/12 text-indigo-100",record_list:"border-purple-300/28 bg-purple-300/12 text-purple-100",selection:"border-rose-300/28 bg-rose-300/12 text-rose-100",timeline:"border-blue-300/28 bg-blue-300/12 text-blue-100",json:"border-slate-300/28 bg-slate-300/12 text-slate-100",object:"border-slate-300/28 bg-slate-300/12 text-slate-100",array:"border-zinc-300/28 bg-zinc-300/12 text-zinc-100",tool:"border-red-300/28 bg-red-300/12 text-red-100"};function ve(a){return typeof a=="string"?a:typeof a=="number"||typeof a=="boolean"?String(a):Array.isArray(a)||a&&typeof a=="object"?JSON.stringify(a,null,2):""}function $t(a,i){if(a==="array"||a==="entity_list"||a==="record_list"||a==="object"||a==="json"||a==="record"||a==="context"||a==="filters"||a==="metrics"||a==="timeline"||a==="selection"||a==="entity"){if(!i.trim())return"";try{return JSON.parse(i)}catch{return i}}if(a==="boolean")return i.trim()?i.trim().toLowerCase()==="true"?!0:i.trim().toLowerCase()==="false"?!1:i:"";if(a==="number"){const r=i.trim();if(!r)return"";const l=Number(r);return Number.isFinite(l)?l:i}return i}function Ga(a,i){if(i==null||typeof i=="string"&&i.trim().length===0)return!a.required;switch(a.kind){case"text":case"markdown":case"summary":return typeof i=="string";case"number":return typeof i=="number"&&Number.isFinite(i);case"boolean":return typeof i=="boolean";case"array":case"entity_list":case"record_list":return Array.isArray(i);case"object":case"json":case"record":case"context":case"filters":case"metrics":case"timeline":case"selection":case"entity":return!!i&&typeof i=="object";default:return!0}}function Ht(a){switch(a){case"box":case"box_input":return{inputs:[],outputs:[{key:"summary",label:"Summary",kind:"summary",description:"Human-readable summary of the box snapshot.",modelName:"WorkbenchBoxSummary"}]};case"user_input":return{inputs:[],outputs:[{key:"message",label:"Message",kind:"text",description:"Raw user message passed into the flow.",modelName:"WorkbenchUserMessage"},{key:"context",label:"Structured context",kind:"context",description:"Structured context fields that arrived with the user input.",modelName:"WorkbenchUserContext"}]};case"value":return{inputs:[],outputs:[{key:"value",label:"Value",kind:"record",description:"Literal value emitted by this node.",modelName:"WorkbenchLiteralValue"}]};case"functor":case"chat":return{inputs:[{key:"input",label:"Flow input",kind:"context",required:!1,description:"Context gathered from upstream nodes."}],outputs:[{key:"answer",label:"Answer",kind:"markdown",description:"Primary answer returned by this AI node.",modelName:"WorkbenchAiAnswer"}]};case"merge":return{inputs:[{key:"left",label:"Left input",kind:"context",required:!1,description:"First context record to merge."},{key:"right",label:"Right input",kind:"context",required:!1,description:"Second context record to merge."}],outputs:[{key:"merged",label:"Merged context",kind:"context",description:"Combined context assembled from upstream nodes.",modelName:"WorkbenchMergedContext"}]};case"template":return{inputs:[{key:"input",label:"Template input",kind:"context",required:!1,description:"Structured context available to the template."}],outputs:[{key:"rendered",label:"Rendered output",kind:"markdown",description:"Rendered text produced by the template node.",modelName:"WorkbenchTemplateOutput"}]};case"pick_key":return{inputs:[{key:"object",label:"Source object",kind:"object",required:!1,description:"Object record the node should read from."}],outputs:[{key:"selected",label:"Selected value",kind:"record",description:"Value extracted from the chosen key.",modelName:"WorkbenchSelectedValue"}]};case"output":return{inputs:[{key:"result",label:"Published result",kind:"context",required:!1,description:"Final value the flow should publish."}],outputs:[]}}}function Ja(a){switch(a){case"box":case"box_input":return{icon:e.jsx(ca,{className:"size-4"}),badge:"box"};case"chat":return{icon:e.jsx(zt,{className:"size-4"}),badge:"chat"};case"functor":return{icon:e.jsx(Et,{className:"size-4"}),badge:"functor"};case"output":return{icon:e.jsx(At,{className:"size-4"}),badge:"output"};case"value":return{icon:e.jsx(Rt,{className:"size-4"}),badge:"value"};case"merge":return{icon:e.jsx(Ot,{className:"size-4"}),badge:"merge"};case"template":return{icon:e.jsx(Pt,{className:"size-4"}),badge:"template"};case"pick_key":return{icon:e.jsx(Kt,{className:"size-4"}),badge:"pick key"};default:return{icon:e.jsx(_t,{className:"size-4"}),badge:"input"}}}function Lt(a,i){var c,p,m,o;const r=(n,u)=>n.map((h,y)=>{const b=kt(h),g=b.key==="primary"?u==="output"?a.type==="functor"||a.type==="chat"?"answer":a.type==="box"||a.type==="box_input"?"summary":a.type==="value"?"value":a.type==="merge"?"merged":a.type==="template"?"rendered":a.type==="pick_key"?"selected":"result":a.type==="functor"||a.type==="chat"?"input":a.type==="output"?"result":b.key:b.key;return kt({...b,key:g,kind:g===b.key?b.kind:void 0})});if(a.type==="box"||a.type==="box_input"){const n=i.find(u=>u.id===a.data.boxId);return{inputs:r((n==null?void 0:n.inputs)??[],"input"),outputs:(c=n==null?void 0:n.output)!=null&&c.length?r(n.output,"output"):r([{key:"summary",label:"Summary",kind:"summary",description:"Human-readable summary of the box snapshot.",modelName:"WorkbenchBoxSummary"}],"output"),enabledToolKeys:(p=a.data.enabledToolKeys)!=null&&p.length?a.data.enabledToolKeys:((n==null?void 0:n.tools)??[]).map(u=>u.key),boxId:(n==null?void 0:n.id)??a.data.boxId??null}}const l=Ht(a.type);return{inputs:r((m=a.data.inputs)!=null&&m.length?a.data.inputs:l.inputs,"input"),outputs:r((o=a.data.outputs)!=null&&o.length?a.data.outputs:l.outputs,"output"),enabledToolKeys:a.data.enabledToolKeys??[],boxId:a.data.boxId??null}}function Qa(a,i){var l,c,p;const r=(l=a.data.outputKey)==null?void 0:l.trim();return!r||r==="primary"?((c=i[0])==null?void 0:c.key)??"":i.some(m=>m.key===r)?r:((p=i[0])==null?void 0:p.key)??r}function St(a,i,r){var l,c;return i.length===0?null:!a||a==="primary"?r&&i.some(p=>p.key===r)?r:((l=i[0])==null?void 0:l.key)??null:i.some(p=>p.key===a)?a:r&&i.some(p=>p.key===r)?r:((c=i[0])==null?void 0:c.key)??null}function Me(a,i){const r=a.graph.nodes.map(p=>{const m=Lt(p,i),o={...p,data:{...p.data,inputs:m.inputs,outputs:m.outputs,outputKey:Qa(p,m.outputs)}};return $e(o,i)}),l=new Map(r.map(p=>[p.id,p])),c=a.graph.edges.map(p=>{var h,y,b,g;const m=l.get(p.source),o=l.get(p.target),n=St(p.sourceHandle,(m==null?void 0:m.data.outputs)??[],(y=(h=m==null?void 0:m.data.outputs)==null?void 0:h[0])==null?void 0:y.key),u=St(p.targetHandle,(o==null?void 0:o.data.inputs)??[],(g=(b=o==null?void 0:o.data.inputs)==null?void 0:b[0])==null?void 0:g.key);return Ut({...p,sourceHandle:n,targetHandle:u})});return{nodes:r,edges:c}}function $e(a,i){const r=Lt(a,i);return{id:a.id,type:"workbench",position:a.position,data:{...a.data,nodeType:a.type==="box_input"?"box":a.type,boxId:r.boxId,enabledToolKeys:r.enabledToolKeys,inputs:r.inputs,outputs:r.outputs,params:a.data.params??[],paramValues:a.data.paramValues??{}}}}function Ut(a){return{id:a.id,source:a.source,target:a.target,sourceHandle:a.sourceHandle??void 0,targetHandle:a.targetHandle??void 0,label:a.label??void 0,style:{stroke:"rgba(188, 194, 255, 0.44)",strokeWidth:1.6}}}function qt(a){return{id:a.id,type:a.data.nodeType==="box"?"box":a.data.nodeType,position:a.position,data:{label:a.data.label,description:a.data.description,boxId:a.data.boxId??null,prompt:a.data.prompt??"",promptTemplate:a.data.promptTemplate??"",systemPrompt:a.data.systemPrompt??"",outputKey:a.data.outputKey??"",enabledToolKeys:a.data.enabledToolKeys??[],inputs:a.data.inputs??[],outputs:a.data.outputs??[],params:a.data.params??[],paramValues:a.data.paramValues??{},template:a.data.template??"",selectedKey:a.data.selectedKey??"",valueType:a.data.valueType??"string",valueLiteral:a.data.valueLiteral??"",modelConfig:a.data.modelConfig}}}function Ya(a){return{id:a.id,source:a.source,target:a.target,sourceHandle:a.sourceHandle??null,targetHandle:a.targetHandle??null,label:typeof a.label=="string"?a.label:null}}function It(a,i,r){var c;const l=Ht(a);return{id:`node_${crypto.randomUUID().replaceAll("-","").slice(0,8)}`,type:"workbench",position:{x:120+i.length%3*320,y:80+Math.floor(i.length/3)*220},data:{nodeType:a,label:(r==null?void 0:r.title)??(a==="functor"?"Functor":a==="chat"?"Chat node":a==="output"?"Output":a==="value"?"Value":a==="template"?"Template":a==="pick_key"?"Pick key":a==="merge"?"Merge":"User input"),description:(r==null?void 0:r.description)??(a==="box"?"Registered Forge box.":a==="chat"?"Conversational flow node.":a==="functor"?"Single transformation node.":"Workbench node."),boxId:(r==null?void 0:r.id)??null,enabledToolKeys:((r==null?void 0:r.tools)??[]).map(p=>p.key),inputs:(r==null?void 0:r.inputs)??l.inputs,outputs:(r==null?void 0:r.output)??l.outputs,params:(r==null?void 0:r.params)??[],paramValues:{},prompt:"",promptTemplate:"",systemPrompt:"",template:"",selectedKey:"",valueType:"string",valueLiteral:"",outputKey:((c=((r==null?void 0:r.output)??l.outputs)[0])==null?void 0:c.key)??"summary",modelConfig:{connectionId:null,provider:null,baseUrl:null,model:"",thinking:null,verbosity:null}}}}function Xa(a){return[a.kind,a.modelName,a.itemKind?`item:${a.itemKind}`:null].filter(Boolean).join(" · ")}function Za(a,i){switch(a){case"dirty":return"Unsaved changes";case"saving":return"Saving…";case"saved":return"All changes saved";case"error":return i?`Save failed: ${i}`:"Save failed";default:return"Saved"}}function es(a){const i=crypto.randomUUID().replaceAll("-","").slice(0,4);return{key:`${a}_${i}`,label:a==="input"?"New input":"New output",kind:a==="input"?"context":"record",description:"",required:!1,modelName:a==="input"?"WorkbenchInputContract":"WorkbenchOutputContract"}}function ts(){return{key:`flow_input_${crypto.randomUUID().replaceAll("-","").slice(0,4)}`,label:"New flow input",kind:"text",description:"",required:!1,modelName:"WorkbenchFlowInput",bindings:[]}}function ke({kind:a}){return e.jsx("span",{className:R("inline-flex items-center rounded-full border px-2.5 py-1 text-[10px] uppercase tracking-[0.16em]",Wt[a]??"border-white/12 bg-white/[0.05] text-white/60"),children:a.replaceAll("_"," ")})}function M({label:a,onClick:i,emphasis:r=!1}){return e.jsx("button",{type:"button",className:R("rounded-full border px-3 py-1.5 text-[11px] font-medium transition",r?"border-[rgba(192,193,255,0.32)] bg-[rgba(192,193,255,0.18)] text-white hover:bg-[rgba(192,193,255,0.24)]":"border-white/10 bg-white/[0.05] text-white/60 hover:bg-white/[0.08] hover:text-white"),onPointerDown:l=>l.stopPropagation(),onClick:l=>{l.stopPropagation(),i()},children:a})}function we({title:a,description:i,ports:r,onChange:l,prefix:c}){return e.jsxs("div",{className:"grid gap-3 rounded-[24px] border border-white/8 bg-white/[0.03] p-4",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm font-medium text-white",children:[e.jsx("span",{children:a}),e.jsx(V,{content:i,label:`Explain ${a.toLowerCase()}`})]}),e.jsx("div",{className:"mt-1 text-sm leading-6 text-white/54",children:i})]}),e.jsxs(I,{type:"button",variant:"secondary",size:"sm",onClick:()=>l([...r??[],es(c)]),children:["Add ",c]})]}),e.jsxs("div",{className:"grid gap-3",children:[r.length===0?e.jsxs("div",{className:"rounded-[18px] border border-dashed border-white/10 px-4 py-3 text-sm text-white/42",children:["No ",c,"s defined yet."]}):null,r.map((p,m)=>e.jsxs("div",{className:"grid gap-3 rounded-[20px] border border-white/8 bg-black/20 p-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(ke,{kind:p.kind}),e.jsx("span",{className:"text-sm font-medium text-white",children:p.label})]}),e.jsx(I,{type:"button",variant:"ghost",size:"sm",onClick:()=>l(r.filter((o,n)=>n!==m)),children:"Remove"})]}),e.jsxs("div",{className:"grid gap-3 md:grid-cols-2",children:[e.jsx(C,{label:"Key",description:"Downstream nodes reference this exact key.",labelHelp:"Keep keys stable once edges depend on them. Use snake_case names that describe the value clearly.",children:e.jsx("input",{value:p.key,onChange:o=>l(r.map((n,u)=>u===m?{...n,key:o.target.value}:n)),className:w})}),e.jsx(C,{label:"Label",description:"Readable name shown in the graph editor.",children:e.jsx("input",{value:p.label,onChange:o=>l(r.map((n,u)=>u===m?{...n,label:o.target.value}:n)),className:w})})]}),e.jsxs("div",{className:"grid gap-3 md:grid-cols-2",children:[e.jsx(C,{label:"Value type",description:"This colors the port and tells the flow what sort of value should move through it.",children:e.jsx("select",{value:p.kind,onChange:o=>l(r.map((n,u)=>u===m?{...n,kind:o.target.value}:n)),className:w,children:We.map(o=>e.jsx("option",{value:o,children:o.replaceAll("_"," ")},o))})}),e.jsx(C,{label:"Model name",description:"Semantic model name for this port, used in previews and runtime contracts.",children:e.jsx("input",{value:p.modelName??"",onChange:o=>l(r.map((n,u)=>u===m?{...n,modelName:o.target.value||void 0}:n)),placeholder:"WorkbenchTaskSearchResults",className:w})})]}),e.jsxs("div",{className:"grid gap-3 md:grid-cols-2",children:[e.jsx(C,{label:"Item kind",description:"Optional entity or item subtype when this port carries a collection.",children:e.jsx("input",{value:p.itemKind??"",onChange:o=>l(r.map((n,u)=>u===m?{...n,itemKind:o.target.value||void 0}:n)),placeholder:"task",className:w})}),e.jsx(C,{label:"Example value",description:"Short example shown in collapsed previews.",children:e.jsx("input",{value:p.exampleValue??"",onChange:o=>l(r.map((n,u)=>u===m?{...n,exampleValue:o.target.value||void 0}:n)),placeholder:c==="input"?"task ids and filters":"summarized result",className:w})})]}),e.jsx(C,{label:"Expectation",description:"Describe what should actually be inside this value so the graph stays legible.",children:e.jsx("textarea",{rows:3,value:p.description??"",onChange:o=>l(r.map((n,u)=>u===m?{...n,description:o.target.value||void 0}:n)),placeholder:c==="input"?"Explain what upstream nodes should provide here.":"Explain what downstream nodes can expect from this output.",className:w})}),e.jsxs("details",{className:"rounded-[18px] border border-white/8 bg-white/[0.03] p-4",children:[e.jsx("summary",{className:"cursor-pointer text-sm font-medium text-white",children:"Shape fields"}),e.jsxs("div",{className:"mt-3 grid gap-3",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsx("div",{className:"text-sm leading-6 text-white/54",children:"Describe the object structure or list item shape this port carries."}),e.jsx(I,{type:"button",variant:"secondary",size:"sm",onClick:()=>l(r.map((o,n)=>n===m?{...o,shape:[...o.shape??[],{key:`field_${crypto.randomUUID().replaceAll("-","").slice(0,4)}`,label:"New field",kind:"text",required:!1}]}:o)),children:"Add field"})]}),(p.shape??[]).length===0?e.jsx("div",{className:"rounded-[16px] border border-dashed border-white/10 px-4 py-3 text-sm text-white/42",children:"No explicit structure fields yet."}):null,(p.shape??[]).map((o,n)=>e.jsxs("div",{className:"grid gap-3 rounded-[16px] border border-white/8 bg-black/20 p-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[e.jsx(ke,{kind:o.kind}),e.jsx(I,{type:"button",variant:"ghost",size:"sm",onClick:()=>l(r.map((u,h)=>h===m?{...u,shape:(u.shape??[]).filter((y,b)=>b!==n)}:u)),children:"Remove field"})]}),e.jsxs("div",{className:"grid gap-3 md:grid-cols-2",children:[e.jsx("input",{value:o.key,onChange:u=>l(r.map((h,y)=>y===m?{...h,shape:(h.shape??[]).map((b,g)=>g===n?{...b,key:u.target.value}:b)}:h)),placeholder:"field_key",className:w}),e.jsx("input",{value:o.label,onChange:u=>l(r.map((h,y)=>y===m?{...h,shape:(h.shape??[]).map((b,g)=>g===n?{...b,label:u.target.value}:b)}:h)),placeholder:"Field label",className:w})]}),e.jsxs("div",{className:"grid gap-3 md:grid-cols-2",children:[e.jsx("select",{value:o.kind,onChange:u=>l(r.map((h,y)=>y===m?{...h,shape:(h.shape??[]).map((b,g)=>g===n?{...b,kind:u.target.value}:b)}:h)),className:w,children:We.map(u=>e.jsx("option",{value:u,children:u.replaceAll("_"," ")},u))}),e.jsxs("label",{className:"flex items-center gap-2 rounded-[18px] border border-white/10 bg-black/20 px-4 py-3 text-sm text-white/64",children:[e.jsx("input",{type:"checkbox",checked:!!o.required,onChange:u=>l(r.map((h,y)=>y===m?{...h,shape:(h.shape??[]).map((b,g)=>g===n?{...b,required:u.target.checked}:b)}:h))}),"Required field"]})]}),e.jsx("textarea",{rows:2,value:o.description??"",onChange:u=>l(r.map((h,y)=>y===m?{...h,shape:(h.shape??[]).map((b,g)=>g===n?{...b,description:u.target.value||void 0}:b)}:h)),placeholder:"What should this field contain?",className:w})]},`${p.key}-shape-${o.key}-${n}`))]})]}),e.jsxs("label",{className:"flex items-center gap-2 text-sm text-white/64",children:[e.jsx("input",{type:"checkbox",checked:!!p.required,onChange:o=>l(r.map((n,u)=>u===m?{...n,required:o.target.checked}:n))}),"Required port"]})]},`${c}-${p.key}-${m}`))]})]})}function as({inputs:a,nodes:i,onChange:r}){return e.jsxs("div",{className:"grid gap-3 rounded-[24px] border border-white/8 bg-white/[0.03] p-4",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm font-medium text-white",children:[e.jsx("span",{children:"Flow inputs"}),e.jsx(V,{content:"These are the typed inputs your Workbench flow exposes to the API and the Run modal.",label:"Explain flow inputs"})]}),e.jsx("div",{className:"mt-1 text-sm leading-6 text-white/54",children:"Define the external contract once, then bind each input to the node inputs or parameters that should consume it."})]}),e.jsx(I,{type:"button",variant:"secondary",size:"sm",onClick:()=>r([...a??[],ts()]),children:"Add flow input"})]}),a.length===0?e.jsx("div",{className:"rounded-[18px] border border-dashed border-white/10 px-4 py-3 text-sm text-white/42",children:"No public flow inputs defined yet."}):null,e.jsx("div",{className:"grid gap-3",children:a.map((l,c)=>{const p=i.filter(o=>(o.data.inputs??[]).length>0||(o.data.params??[]).length>0),m=o=>r(a.map((n,u)=>u===c?{...n,...o}:n));return e.jsxs("div",{className:"grid gap-3 rounded-[20px] border border-white/8 bg-black/20 p-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(ke,{kind:l.kind}),e.jsx("span",{className:"text-sm font-medium text-white",children:l.label})]}),e.jsx(I,{type:"button",variant:"ghost",size:"sm",onClick:()=>r(a.filter((o,n)=>n!==c)),children:"Remove"})]}),e.jsxs("div",{className:"grid gap-3 md:grid-cols-2",children:[e.jsx(C,{label:"Key",description:"External API key callers will send.",children:e.jsx("input",{value:l.key,onChange:o=>m({key:o.target.value}),className:w})}),e.jsx(C,{label:"Label",description:"Human-readable name used in the Run modal.",children:e.jsx("input",{value:l.label,onChange:o=>m({label:o.target.value}),className:w})})]}),e.jsxs("div",{className:"grid gap-3 md:grid-cols-2",children:[e.jsx(C,{label:"Value type",description:"Expected type for this flow input.",children:e.jsx("select",{value:l.kind,onChange:o=>m({kind:o.target.value}),className:w,children:We.map(o=>e.jsx("option",{value:o,children:o.replaceAll("_"," ")},o))})}),e.jsx(C,{label:"Default value",description:"Used when a caller omits this input.",children:e.jsx("textarea",{rows:3,value:ve(l.defaultValue),onChange:o=>m({defaultValue:$t(l.kind,o.target.value)}),className:w})})]}),e.jsx(C,{label:"Description",description:"Explain what callers should send here.",children:e.jsx("textarea",{rows:3,value:l.description??"",onChange:o=>m({description:o.target.value}),className:w})}),e.jsxs("label",{className:"flex items-center gap-2 text-sm text-white/64",children:[e.jsx("input",{type:"checkbox",checked:!!l.required,onChange:o=>m({required:o.target.checked})}),"Required input"]}),e.jsxs("div",{className:"grid gap-2 rounded-[18px] border border-white/8 bg-white/[0.03] p-3",children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm text-white",children:["Bindings",e.jsx(V,{content:"Bind this public input to one or more node inputs or parameters. If you leave bindings empty and a node uses the same key, Forge will auto-bind it by key.",label:"Explain bindings"})]}),(l.bindings??[]).map((o,n)=>{const u=i.find(y=>y.id===o.nodeId)??null,h=o.targetKind==="param"?(u==null?void 0:u.data.params)??[]:(u==null?void 0:u.data.inputs)??[];return e.jsxs("div",{className:"grid gap-3 rounded-[16px] bg-black/20 p-3 md:grid-cols-[1.2fr_1fr_1fr_auto]",children:[e.jsxs("select",{value:o.nodeId,onChange:y=>m({bindings:(l.bindings??[]).map((b,g)=>g===n?{...b,nodeId:y.target.value,targetKey:""}:b)}),className:w,children:[e.jsx("option",{value:"",children:"Select node"}),p.map(y=>e.jsx("option",{value:y.id,children:y.data.label},y.id))]}),e.jsxs("select",{value:o.targetKind,onChange:y=>m({bindings:(l.bindings??[]).map((b,g)=>g===n?{...b,targetKind:y.target.value,targetKey:""}:b)}),className:w,children:[e.jsx("option",{value:"input",children:"Node input"}),e.jsx("option",{value:"param",children:"Node parameter"})]}),e.jsxs("select",{value:o.targetKey,onChange:y=>m({bindings:(l.bindings??[]).map((b,g)=>g===n?{...b,targetKey:y.target.value}:b)}),className:w,children:[e.jsx("option",{value:"",children:"Select target"}),h.map(y=>e.jsx("option",{value:y.key,children:y.label},y.key))]}),e.jsx(I,{type:"button",variant:"ghost",size:"sm",onClick:()=>m({bindings:(l.bindings??[]).filter((y,b)=>b!==n)}),children:"Remove"})]},`${o.nodeId}-${o.targetKey}-${n}`)}),e.jsx(I,{type:"button",variant:"secondary",size:"sm",onClick:()=>m({bindings:[...l.bindings??[],{nodeId:"",targetKind:"input",targetKey:""}]}),children:"Add binding"})]})]},`${l.key}-${c}`)})})]})}function Tt({side:a,ports:i,collapsed:r}){return e.jsxs("div",{className:"grid gap-1.5",children:[e.jsxs("div",{className:R("flex items-center gap-1 px-1 text-[10px] font-medium uppercase tracking-[0.18em] text-white/34",a==="left"?"text-left":"text-right"),children:[e.jsx("span",{children:a==="left"?"Inputs":"Outputs"}),e.jsx(V,{content:a==="left"?"Inputs are values this node expects from earlier nodes in the flow.":"Outputs are the values this node publishes for later nodes to consume.",label:a==="left"?"Explain node inputs":"Explain node outputs"})]}),i.length===0?e.jsx("div",{className:R("rounded-full border border-dashed border-white/8 px-3 py-1.5 text-[11px] text-white/28",a==="left"?"text-left":"text-right"),children:"None"}):null,i.map(l=>e.jsxs("div",{className:R("relative min-h-6 rounded-[16px] border px-3 py-2 text-[11px] tracking-[0.01em] text-white/62",a==="left"?"pl-5 text-left":"pr-5 text-right",r?"bg-white/[0.02]":"bg-white/[0.04]",Wt[l.kind]??"border-white/8"),children:[e.jsx(za,{type:a==="left"?"target":"source",position:a==="left"?Nt.Left:Nt.Right,id:l.key,className:"!size-2.5 !border !border-white/80 !bg-[#b8c5ff]",style:{[a]:6}}),r?null:e.jsxs("div",{children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("span",{children:l.label}),e.jsx(ke,{kind:l.kind})]}),e.jsx("div",{className:"mt-1 text-[10px] text-white/36",children:Xa(l)})]})]},`${a}-${l.key}`))]})}function ss(a){var u,h,y,b;const i=wa(a.data.boxId??null),[r,l]=x.useState(!1),[c,p]=x.useState(!1),m=Ja(a.data.nodeType),o=((u=a.data.params)==null?void 0:u.length)??0,n=`${((h=a.data.inputs)==null?void 0:h.length)??0} in · ${((y=a.data.outputs)==null?void 0:y.length)??0} out`;if(i&&a.data.nodeType==="box"){const g=i.NodeView;return e.jsxs("div",{className:"relative",children:[e.jsxs("div",{className:"absolute right-3 top-3 z-10 flex flex-wrap items-center justify-end gap-2",children:[e.jsx(M,{label:"Edit",onClick:()=>{var k,F;return(F=(k=a.data).onEditRequest)==null?void 0:F.call(k)}}),e.jsx(M,{label:n,onClick:()=>{var k,F;return(F=(k=a.data).onContractEditRequest)==null?void 0:F.call(k)}}),o>0?e.jsx(M,{label:`${o} parameter${o===1?"":"s"}`,onClick:()=>{var k,F;return(F=(k=a.data).onParameterEditRequest)==null?void 0:F.call(k)},emphasis:!0}):null]}),e.jsx("div",{className:R("rounded-[28px] p-[2px] transition",a.selected?"bg-[linear-gradient(135deg,rgba(191,198,255,0.6),rgba(67,98,255,0.28))]":"bg-transparent"),children:e.jsx(g,{nodeId:a.id,inputs:void 0,params:void 0,compact:!1})})]})}return e.jsxs("div",{className:R("min-w-[270px] rounded-[24px] border border-white/10 bg-[linear-gradient(180deg,rgba(20,28,45,0.98),rgba(11,16,29,0.98))] p-3 shadow-[0_26px_80px_rgba(0,0,0,0.4)]",a.selected&&"border-[rgba(191,198,255,0.52)]"),children:[e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2 text-white",children:[m.icon,e.jsx("div",{className:"truncate text-sm font-semibold",children:a.data.label})]}),a.data.description?e.jsx("div",{className:"mt-1 line-clamp-2 text-[12px] leading-5 text-white/48",children:a.data.description}):null]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(M,{label:r?"Show ports":"Hide labels",onClick:()=>l(g=>!g)}),e.jsx("div",{className:"rounded-full bg-white/[0.06] px-2.5 py-1 text-[10px] uppercase tracking-[0.16em] text-white/56",children:m.badge})]})]}),a.data.boxId?e.jsx("div",{className:"mt-3 rounded-full bg-white/[0.05] px-3 py-1.5 text-[11px] text-white/56",children:a.data.boxId}):null,e.jsxs("div",{className:"mt-3 flex flex-wrap gap-2",children:[(b=a.data.enabledToolKeys)!=null&&b.length?e.jsxs("div",{className:"rounded-full bg-white/[0.05] px-3 py-1.5 text-[11px] text-white/56",children:[a.data.enabledToolKeys.length," tool",a.data.enabledToolKeys.length===1?"":"s"," enabled"]}):null,e.jsx(M,{label:c?"Hide schema":"Preview schema",onClick:()=>p(g=>!g)}),e.jsx(M,{label:"Edit",onClick:()=>{var g,k;return(k=(g=a.data).onEditRequest)==null?void 0:k.call(g)}}),e.jsx(M,{label:n,onClick:()=>{var g,k;return(k=(g=a.data).onContractEditRequest)==null?void 0:k.call(g)}}),o>0?e.jsx(M,{label:`${o} parameter${o===1?"":"s"}`,onClick:()=>{var g,k;return(k=(g=a.data).onParameterEditRequest)==null?void 0:k.call(g)},emphasis:!0}):null]}),e.jsxs("div",{className:"mt-3 grid grid-cols-[minmax(0,1fr)_minmax(0,1fr)] gap-3",children:[e.jsx(Tt,{side:"left",ports:a.data.inputs??[],collapsed:r}),e.jsx(Tt,{side:"right",ports:a.data.outputs??[],collapsed:r})]}),c?e.jsxs("div",{className:"mt-3 rounded-[18px] border border-white/8 bg-black/20 p-3",children:[e.jsxs("div",{className:"flex items-center gap-2 text-[10px] uppercase tracking-[0.18em] text-white/38",children:[e.jsx("span",{children:"Node contract"}),e.jsx(V,{content:"This preview shows the shape of the values and tools this node exposes inside the flow graph.",label:"Explain node contract preview"})]}),e.jsx("pre",{className:"mt-2 overflow-auto whitespace-pre-wrap text-[11px] leading-5 text-white/64",children:JSON.stringify({inputs:(a.data.inputs??[]).map(({key:g,kind:k,required:F})=>({key:g,kind:k,required:!!F})),outputs:(a.data.outputs??[]).map(({key:g,kind:k,required:F})=>({key:g,kind:k,required:!!F})),tools:a.data.enabledToolKeys??[]},null,2)})]}):null]})}const rs={workbench:ss};function ie(a){return a==="functor"||a==="chat"}function ns(a){const i=a instanceof Mt||a instanceof Error?a.message:String(a);return i.includes("No model connection is configured for this connector node.")?["This flow uses an AI node, but Forge does not have any model connection configured yet.","Open Settings > Models, add a model connection, then run the flow again.","Once a model exists, the node can use the default model automatically or you can pick a specific model inside the node editor."].join(`
2
-
3
- `):i}function ls(a){return a.map(({key:i,kind:r,required:l,description:c,modelName:p,itemKind:m,shape:o,exampleValue:n})=>({key:i,kind:r,required:!!l,description:c,modelName:p,itemKind:m,shape:o,exampleValue:n}))}function is(a){const i=Array.from(new Set(a.map(l=>l.trim()).filter(Boolean)));return(i.includes("answer")?i:["answer",...i]).map(l=>({key:l,label:l==="answer"?"Answer":l.split(/[_-]+/).map(c=>c.charAt(0).toUpperCase()+c.slice(1)).join(" "),kind:l==="answer"?"markdown":"record",description:l==="answer"?"Primary answer returned by this AI node.":`Named output published for downstream nodes under "${l}".`,modelName:l==="answer"?"WorkbenchAiAnswer":`Workbench${l.split(/[_-]+/).map(c=>c.charAt(0).toUpperCase()+c.slice(1)).join("")}`,exampleValue:l==="answer"?"Concise answer":void 0}))}function os(a,i){return Bt(a,i)[0]??null}function Bt(a,i){var m,o;const r=[],l=new Map(a.map(n=>[n.id,n]));a.length===0&&r.push("Add at least one node before running the flow.");const c=a.filter(n=>n.data.nodeType==="output");c.length===0&&r.push("Add an Output node so Forge knows what result the flow should publish.");const p=new Map;for(const n of i){p.set(n.target,(p.get(n.target)??0)+1);const u=l.get(n.source),h=l.get(n.target),y=(u==null?void 0:u.data.outputs)??[],b=(h==null?void 0:h.data.inputs)??[];u&&(n.sourceHandle&&!y.some(g=>g.key===n.sourceHandle)?r.push(`Edge from "${u.data.label}" points to missing output "${n.sourceHandle}". Update the edge or restore that output contract.`):!n.sourceHandle&&y.length>1&&r.push(`Edge from "${u.data.label}" does not name which output it should use. Pick one explicit output handle.`)),h&&(n.targetHandle&&!b.some(g=>g.key===n.targetHandle)?r.push(`Edge into "${h.data.label}" points to missing input "${n.targetHandle}". Update the edge or restore that input contract.`):!n.targetHandle&&b.length>1&&r.push(`Edge into "${h.data.label}" does not name which input it should feed. Pick one explicit input handle.`))}for(const n of c){(p.get(n.id)??0)===0&&r.push(`Connect something into the output node "${n.data.label}" so the flow has something to return.`);const u=i.filter(h=>h.target===n.id).flatMap(h=>{const y=l.get(h.source),b=(y==null?void 0:y.data.outputs)??[];return h.sourceHandle?b.filter(g=>g.key===h.sourceHandle).map(g=>g.key):b.map(g=>g.key)});n.data.outputKey&&u.length>0&&!u.includes(n.data.outputKey)&&r.push(`Output node "${n.data.label}" is configured to publish "${n.data.outputKey}", but that key is not arriving from its upstream nodes.`)}for(const n of a){const u=p.get(n.id)??0,h=i.filter(y=>y.source===n.id).length;n.data.nodeType!=="user_input"&&n.data.nodeType!=="value"&&u===0&&n.data.nodeType!=="box"&&r.push(`Connect an upstream source into "${n.data.label}" so it has real input to work with.`),n.data.nodeType==="merge"&&u<2&&r.push(`Merge node "${n.data.label}" should receive both left and right inputs before you run it.`),n.data.nodeType==="template"&&!(n.data.template??"").trim()&&r.push(`Add a template string to "${n.data.label}" before running the flow.`),n.data.nodeType==="pick_key"&&!(n.data.selectedKey??"").trim()&&r.push(`Choose which key "${n.data.label}" should pick from incoming objects.`),n.data.nodeType!=="output"&&h===0&&r.push(`Connect the output of "${n.data.label}" somewhere useful or remove the node from the graph.`)}for(const n of a)ie(n.data.nodeType)&&!((m=n.data.promptTemplate)!=null&&m.trim()||(o=n.data.prompt)!=null&&o.trim())&&r.push(`Add a prompt to the AI node "${n.data.label}" before running the flow.`);return r}function le({open:a,onOpenChange:i,title:r,description:l,children:c}){return e.jsx(Ma,{open:a,onOpenChange:i,children:e.jsxs(Wa,{children:[e.jsx($a,{className:"fixed inset-0 z-50 bg-[rgba(3,7,18,0.72)] backdrop-blur-sm"}),e.jsxs(Ha,{className:"fixed inset-x-4 bottom-4 top-4 z-50 mx-auto flex max-w-[min(44rem,calc(100vw-2rem))] flex-col overflow-hidden rounded-[32px] border border-white/10 bg-[linear-gradient(180deg,rgba(12,18,33,0.985),rgba(8,13,24,0.985))] shadow-[0_36px_96px_rgba(0,0,0,0.46)] md:left-1/2 md:right-auto md:top-[8vh] md:h-[min(82vh,58rem)] md:w-[min(44rem,calc(100vw-1.25rem))] md:-translate-x-1/2 md:bottom-auto",children:[e.jsxs("div",{className:"flex items-start justify-between gap-4 border-b border-white/8 px-5 py-4 backdrop-blur-xl",children:[e.jsxs("div",{children:[e.jsx(La,{className:"font-display text-[1.28rem] tracking-[-0.04em] text-white",children:r}),l?e.jsx(Ua,{className:"mt-1 text-sm leading-6 text-white/54",children:l}):null]}),e.jsx(qa,{asChild:!0,children:e.jsx(va,{"aria-label":"Close workbench flow dialog"})})]}),e.jsx("div",{className:"min-h-0 flex-1 overflow-y-auto overscroll-contain px-5 py-5",children:c})]})]})})}function Ft({title:a,description:i,kind:r,publicInputs:l,nodes:c,edges:p}){return{title:a,description:i,kind:r,publicInputs:l,graph:{nodes:c.map(qt),edges:p.map(Ya)}}}function ds({flow:a,boxes:i,modelConnections:r,runs:l,onSave:c,onDelete:p,onRun:m,onChat:o}){var Ze,et,tt,at,st,rt,nt,lt,it,ot,dt,ct,ut,pt,ht,mt,xt,gt,bt,ft,yt,wt;const[n,u]=x.useState(a.title),[h,y]=x.useState(a.description),[b,g]=x.useState(a.kind),[k,F]=x.useState(a.publicInputs??[]),[T,W]=x.useState(()=>Me(a,i).nodes),[E,Q]=x.useState(()=>Me(a,i).edges),[oe,Ne]=x.useState(null),[Vt,de]=x.useState(!1),[He,$]=x.useState(!1),[ce,ue]=x.useState("overview"),[Dt,Ce]=x.useState(void 0),[Gt,pe]=x.useState(!1),[Jt,Se]=x.useState(!1),[Ie,Te]=x.useState(!1),[Fe,Qt]=x.useState(""),[_e,Yt]=x.useState([]),[Re,Xt]=x.useState(""),[H,Y]=x.useState({}),[Ee,Zt]=x.useState(!0),[he,L]=x.useState(null),[X,U]=x.useState("idle"),[ea,me]=x.useState(null),[D,Le]=x.useState(((Ze=l[0])==null?void 0:Ze.id)??null),[xe,Ue]=x.useState(null),O=x.useMemo(()=>JSON.stringify(Ft({title:a.title,description:a.description,kind:a.kind,publicInputs:a.publicInputs??[],nodes:a.graph.nodes.map(t=>$e(t,i)),edges:a.graph.edges.map(Ut)})),[i,a]),G=x.useRef(O),Oe=x.useRef(O),qe=x.useRef({}),ge=x.useRef(O),be=x.useRef(null),fe=x.useRef(!1);x.useEffect(()=>{if(O===Oe.current)return;Oe.current=O,G.current=O,ge.current=O,u(a.title),y(a.description),g(a.kind),F(a.publicInputs??[]);const t=Me(a,i);W(t.nodes),Q(t.edges),U("idle"),me(null)},[i,a,O]),x.useEffect(()=>{Y(Object.fromEntries((a.publicInputs??[]).filter(t=>t.defaultValue!==void 0).map(t=>[t.key,t.defaultValue])))},[a.publicInputs]),x.useEffect(()=>{var t;Le(((t=l[0])==null?void 0:t.id)??null)},[l]),x.useEffect(()=>{W(t=>t.map(s=>s.data.nodeType!=="box"||!s.data.boxId?s:$e(qt(s),i)))},[i]);const ta=x.useMemo(()=>Array.from(new Set(i.map(s=>s.category))).map(s=>({id:`category:${s}`,label:s,description:"Workbench box category"})),[i]),Be=x.useMemo(()=>{const t=Fe.trim().toLowerCase();return i.filter(s=>{const d=t.length===0||[s.title,s.description,s.category,s.routePath??"",...s.tags].join(" ").toLowerCase().includes(t),j=_e.every(N=>N.startsWith("category:")?s.category===N.replace("category:",""):!0);return d&&j})},[_e,Fe,i]),f=x.useMemo(()=>T.find(t=>t.id===oe)??null,[T,oe]),Z=l[0]??null,q=l.find(t=>t.id===D)??Z??null,J=xa({flowId:a.id,runId:D??""},{skip:!D||!Ie}),P=((et=J.data)==null?void 0:et.nodeResults.find(t=>t.nodeId===xe))??null,K=ga({flowId:a.id,runId:D??"",nodeId:xe??""},{skip:!D||!xe||!Ie}),ye=x.useMemo(()=>Bt(T,E),[T,E]),Ve=x.useMemo(()=>T.some(t=>ie(t.data.nodeType)),[T]),Pe=x.useMemo(()=>T.some(t=>t.data.nodeType==="user_input")||(k??[]).length===0,[T,k]);x.useEffect(()=>{var s,d;const t=((d=(s=J.data)==null?void 0:s.nodeResults[0])==null?void 0:d.nodeId)??null;Ue(t)},[(tt=J.data)==null?void 0:tt.nodeResults]);const De=x.useMemo(()=>!!(f&&f.data.nodeType!=="box"&&f.data.nodeType!=="box_input"),[f]),Ge=x.useMemo(()=>f?E.filter(t=>t.target===f.id).flatMap(t=>{const s=T.find(j=>j.id===t.source),d=(s==null?void 0:s.data.outputs)??[];return t.sourceHandle?d.filter(j=>j.key===t.sourceHandle):d}):[],[E,T,f]),ee=x.useMemo(()=>Da(i),[i]),te=x.useMemo(()=>{if(!f||!ie(f.data.nodeType))return[];const t=new Set(f.data.enabledToolKeys??[]);return ee.filter(s=>t.has(s.key))},[ee,f]),Ke=x.useMemo(()=>Ft({title:n,description:h,kind:b,publicInputs:k,nodes:T,edges:E}),[h,E,b,T,k,n]),ae=x.useMemo(()=>JSON.stringify(Ke),[Ke]),Je=ae!==G.current;x.useEffect(()=>{if(qe.current=Ke,ge.current=ae,ae===G.current){me(null),U(t=>t==="saved"?t:"idle");return}U(t=>t==="saving"?t:"dirty")},[ae]);const aa=x.useMemo(()=>!f||!ie(f.data.nodeType)?[]:[{id:"overview",eyebrow:f.data.nodeType==="chat"?"Chat node":"Functor node",title:"Define what this node is responsible for",description:"Give the node a clear role in the flow before configuring prompts and models.",render:(t,s)=>e.jsxs(e.Fragment,{children:[e.jsx(C,{label:"Label",description:"This is the name shown on the canvas and in debug traces.",children:e.jsx("input",{value:t.label,onChange:d=>s({label:d.target.value}),className:w})}),e.jsx(C,{label:"Description",description:"Explain what this node should do with the incoming flow context.",children:e.jsx("textarea",{rows:4,value:t.description,onChange:d=>s({description:d.target.value}),className:w})})]})},{id:"prompts",eyebrow:"Prompts",title:"Set the prompt contract",description:"Separate the main prompt from the system instruction so this node stays easier to maintain.",render:(t,s)=>e.jsxs(e.Fragment,{children:[e.jsx(C,{label:"Prompt template",description:"This is the main instruction the node sends with the current flow input.",children:e.jsx("textarea",{rows:8,value:t.promptTemplate??t.prompt??"",onChange:d=>s({promptTemplate:d.target.value,prompt:d.target.value}),className:w})}),e.jsx(C,{label:"System prompt",description:"Use this for durable behavior and output rules that should stay consistent.",children:e.jsx("textarea",{rows:5,value:t.systemPrompt??"",onChange:d=>s({systemPrompt:d.target.value}),className:w})})]})},{id:"model",eyebrow:"Model",title:"Choose how this node reaches a model",description:"Pick a specific model connection or leave it on the Forge default once models are configured.",render:(t,s)=>{var d,j,N;return e.jsxs(e.Fragment,{children:[r.length===0?e.jsx("div",{className:"rounded-[20px] border border-amber-400/20 bg-amber-400/10 px-4 py-3 text-sm leading-6 text-amber-100",children:"No model connection is configured yet. Open Settings > Models, add one connection, then come back here."}):null,e.jsx(C,{label:"Model connection",description:"This can stay empty if you want the node to use Forge's default configured model.",children:e.jsxs("select",{value:((d=t.modelConfig)==null?void 0:d.connectionId)??"",onChange:v=>{var A,z;const S=r.find(B=>B.id===v.target.value);s({modelConfig:{connectionId:(S==null?void 0:S.id)??null,provider:(S==null?void 0:S.provider)??null,baseUrl:(S==null?void 0:S.baseUrl)??null,model:(S==null?void 0:S.model)??"",thinking:((A=t.modelConfig)==null?void 0:A.thinking)??null,verbosity:((z=t.modelConfig)==null?void 0:z.verbosity)??null}})},className:w,children:[e.jsx("option",{value:"",children:"Use Forge default model"}),r.map(v=>e.jsx("option",{value:v.id,children:v.label},v.id))]})}),e.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[e.jsx(C,{label:"Thinking effort",description:"Optional reasoning setting for models that support it.",children:e.jsxs("select",{value:((j=t.modelConfig)==null?void 0:j.thinking)??"",onChange:v=>{var S,A,z,B,ne;return s({modelConfig:{connectionId:((S=t.modelConfig)==null?void 0:S.connectionId)??null,provider:((A=t.modelConfig)==null?void 0:A.provider)??null,baseUrl:((z=t.modelConfig)==null?void 0:z.baseUrl)??null,model:((B=t.modelConfig)==null?void 0:B.model)??"",thinking:v.target.value||null,verbosity:((ne=t.modelConfig)==null?void 0:ne.verbosity)??null}})},className:w,children:[e.jsx("option",{value:"",children:"Default"}),e.jsx("option",{value:"low",children:"Low"}),e.jsx("option",{value:"medium",children:"Medium"}),e.jsx("option",{value:"high",children:"High"})]})}),e.jsx(C,{label:"Verbosity",description:"Optional output detail setting for models that support it.",children:e.jsxs("select",{value:((N=t.modelConfig)==null?void 0:N.verbosity)??"",onChange:v=>{var S,A,z,B,ne;return s({modelConfig:{connectionId:((S=t.modelConfig)==null?void 0:S.connectionId)??null,provider:((A=t.modelConfig)==null?void 0:A.provider)??null,baseUrl:((z=t.modelConfig)==null?void 0:z.baseUrl)??null,model:((B=t.modelConfig)==null?void 0:B.model)??"",thinking:((ne=t.modelConfig)==null?void 0:ne.thinking)??null,verbosity:v.target.value||null}})},className:w,children:[e.jsx("option",{value:"",children:"Default"}),e.jsx("option",{value:"low",children:"Low"}),e.jsx("option",{value:"medium",children:"Medium"}),e.jsx("option",{value:"high",children:"High"})]})})]})]})}},{id:"contracts",eyebrow:"Contracts",title:"Define the input and output contract",description:"Give this AI node truthful port names, value types, and expectations so the graph stays readable.",render:(t,s)=>e.jsxs("div",{className:"grid gap-4",children:[e.jsx(we,{title:"Inputs",description:"Name the upstream values this AI node expects to receive.",ports:t.inputs??[],onChange:d=>s({inputs:d}),prefix:"input"}),e.jsx(we,{title:"Outputs",description:"Describe exactly what this AI node will publish for later nodes.",ports:t.outputs??[],onChange:d=>s({outputs:d}),prefix:"output"})]})},{id:"tools",eyebrow:"Outputs and tools",title:"Control what this node can call and publish",description:"Keep tool access tight and name any extra outputs the rest of the flow should consume.",render:(t,s)=>e.jsxs(e.Fragment,{children:[e.jsx(C,{label:"Enabled tools",description:"Only checked tools will be available to this AI node during execution.",children:e.jsx("div",{className:"grid max-h-[18rem] gap-2 overflow-y-auto pr-1",children:ee.length>0?ee.map(d=>{const j=(t.enabledToolKeys??[]).includes(d.key);return e.jsxs("label",{className:"flex items-start gap-3 rounded-[16px] bg-white/[0.03] px-3 py-2 text-left",children:[e.jsx("input",{type:"checkbox",checked:j,onChange:N=>{const v=new Set(t.enabledToolKeys??[]);N.target.checked?v.add(d.key):v.delete(d.key),s({enabledToolKeys:[...v]})}}),e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm text-white",children:[e.jsx("span",{children:d.label}),e.jsx("span",{className:"rounded-full bg-white/[0.06] px-2 py-0.5 text-[10px] uppercase tracking-[0.16em] text-white/48",children:d.accessMode.replace("_"," ")})]}),e.jsx("div",{className:"text-[12px] leading-5 text-white/46",children:d.description}),d.sources.length>0?e.jsx("div",{className:"mt-2 flex flex-wrap gap-2",children:d.sources.map(N=>e.jsx("span",{className:"rounded-full bg-white/[0.05] px-2 py-1 text-[10px] text-white/44",children:N},`${d.key}-${N}`))}):null,e.jsx("div",{className:"mt-1 font-mono text-[10px] text-white/32",children:d.key}),d.argsSchema?e.jsxs("details",{className:"mt-2 rounded-[14px] border border-white/8 bg-black/20 px-3 py-2",children:[e.jsx("summary",{className:"cursor-pointer text-[11px] text-white/56",children:"Preview tool arguments"}),e.jsx("pre",{className:"mt-2 overflow-auto whitespace-pre-wrap text-[10px] leading-5 text-white/44",children:JSON.stringify(d.argsSchema,null,2)})]}):null]})]},d.key)}):e.jsx("div",{className:"text-sm text-white/48",children:"No registered Forge tools are available yet."})})}),e.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[e.jsx(C,{label:"Enabled tool preview",description:"Collapsed by default in the node card, this is the contract the AI node can call at run time.",children:e.jsxs("details",{className:"rounded-[18px] border border-white/8 bg-black/20 px-4 py-3",children:[e.jsx("summary",{className:"cursor-pointer text-sm text-white/70",children:te.length>0?`${te.length} tool contract${te.length===1?"":"s"}`:"No tool contract yet"}),e.jsx("pre",{className:"mt-3 overflow-auto whitespace-pre-wrap text-[11px] leading-5 text-white/58",children:JSON.stringify(te.map(d=>({key:d.key,label:d.label,accessMode:d.accessMode,sources:d.sources,argsSchema:d.argsSchema})),null,2)})]})}),e.jsx(C,{label:"Output preview",description:"This is the structure downstream nodes will see from this AI node.",children:e.jsxs("details",{className:"rounded-[18px] border border-white/8 bg-black/20 px-4 py-3",children:[e.jsxs("summary",{className:"cursor-pointer text-sm text-white/70",children:[(t.outputs??[]).length," published output",(t.outputs??[]).length===1?"":"s"]}),e.jsx("pre",{className:"mt-3 overflow-auto whitespace-pre-wrap text-[11px] leading-5 text-white/58",children:JSON.stringify(ls(t.outputs??[]),null,2)})]})})]}),e.jsx(C,{label:"Named outputs",description:"Add comma-separated output keys when later nodes should read more than the primary answer.",children:e.jsx("input",{value:(t.outputs??[]).filter(d=>d.key!=="answer").map(d=>d.key).join(", "),onChange:d=>s({outputs:is(["answer",...d.target.value.split(",")])}),placeholder:"summary, plan, next_steps",className:w})}),e.jsxs("div",{className:"rounded-[20px] border border-white/8 bg-white/[0.03] p-4",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.18em] text-white/40",children:"Danger zone"}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-white/58",children:"Remove this node from the graph if you no longer need it."}),e.jsxs(I,{type:"button",variant:"secondary",className:"mt-4",onClick:()=>{Qe(f.id),$(!1)},children:[e.jsx(Ae,{className:"size-4"}),"Delete node"]})]})]})}],[ee,r,te,f]),se=x.useCallback(async()=>{const t=ge.current,s=qe.current;if(t===G.current)return U("saved"),!0;if(be.current)return fe.current=!0,be.current;U("saving"),me(null);const d=c(s).then(()=>(G.current=t,Oe.current=t,U("saved"),!0)).catch(j=>{const N=j instanceof Mt||j instanceof Error?j.message:String(j);return me(N),U("error"),!1}).finally(()=>{be.current=null,fe.current&&ge.current!==G.current?(fe.current=!1,se()):fe.current=!1});return be.current=d,d},[c]);x.useEffect(()=>{if(!Je)return;const t=window.setTimeout(()=>{se()},2e3);return()=>window.clearTimeout(t)},[Je,se,ae]);const re=x.useCallback((t,s="overview")=>{Ne(t),ue(s),Ce(s==="contracts"?"contracts":"overview"),$(!0)},[]),sa=x.useMemo(()=>T.map(t=>({...t,data:{...t.data,onEditRequest:()=>re(t.id,"overview"),onContractEditRequest:()=>re(t.id,"contracts"),onParameterEditRequest:()=>re(t.id,"parameters")}})),[T,re]);function _(t){oe&&W(s=>s.map(d=>d.id===oe?t(d):d))}function Qe(t){W(s=>s.filter(d=>d.id!==t)),Q(s=>s.filter(d=>d.source!==t&&d.target!==t)),Ne(s=>s===t?null:s)}async function Ye(){await se()}async function Xe(t){if(!await se()){L("Forge could not save the latest flow changes before running. Fix the save error and try again.");return}const d=os(T,E);if(d){L(d);return}if(Ve&&r.length===0){L(["This flow includes an AI node, but no model is configured in Forge yet.","Open Settings > Models, add a model connection, then try again."].join(`
4
-
5
- `));return}L(null);const j={};for(const N of k){const v=H[N.key];if(!Ga(N,v)){L(`Flow input "${N.label}" must match the ${N.kind} type.`);return}v!=null&&!(typeof v=="string"&&v.trim().length===0)&&(j[N.key]=v)}try{t==="run"?await m({userInput:Pe?Re:"",inputs:j,debug:Ee}):await o({userInput:Pe?Re:"",inputs:j,debug:Ee}),pe(!1)}catch(N){L(ns(N))}}return e.jsxs("div",{className:"grid gap-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[e.jsxs("div",{className:"flex min-w-0 items-center gap-3",children:[e.jsxs(ra,{to:"/workbench",className:"inline-flex h-9 items-center gap-2 rounded-full bg-white/[0.05] px-3 text-sm text-white/68 transition hover:bg-white/[0.08] hover:text-white",children:[e.jsx(na,{className:"size-4"}),"Flows"]}),e.jsxs("div",{className:"min-w-0",children:[e.jsx(jt,{kind:"workbench",label:"Workbench Flow",compact:!0,gradient:!1}),e.jsx("div",{className:"truncate font-display text-[1.55rem] tracking-[-0.05em] text-white",children:n})]})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(jt,{kind:ba(b),label:b==="chat"?"Chat flow":"Functor flow",compact:!0,gradient:!1}),e.jsx("div",{className:R("rounded-full border px-3 py-2 text-[12px]",X==="error"?"border-rose-300/20 bg-rose-300/10 text-rose-100":X==="saving"?"border-sky-300/20 bg-sky-300/10 text-sky-100":X==="dirty"?"border-amber-300/20 bg-amber-300/10 text-amber-100":"border-emerald-300/20 bg-emerald-300/10 text-emerald-100"),children:Za(X,ea)}),Z?e.jsxs("button",{type:"button",className:"rounded-full bg-white/[0.05] px-3 py-2 text-[12px] text-white/58 transition hover:bg-white/[0.08] hover:text-white",onClick:()=>Te(!0),children:["Latest ",Z.mode," · ",Z.status]}):null,e.jsxs(I,{type:"button",variant:"secondary",onClick:()=>pe(!0),children:[e.jsx(ze,{className:"size-4"}),"Run"]}),e.jsxs(I,{type:"button",variant:"primary",pending:X==="saving",pendingLabel:"Saving…",onClick:()=>void Ye(),children:[e.jsx(vt,{className:"size-4"}),"Save now"]})]})]}),e.jsxs("div",{className:"relative h-[76vh] overflow-hidden rounded-[32px] border border-white/8 bg-[linear-gradient(180deg,rgba(10,15,26,0.98),rgba(7,11,20,0.98))]",children:[ye.length>0?e.jsxs("div",{className:"pointer-events-none absolute left-4 top-4 z-20 max-w-[32rem] rounded-[24px] border border-amber-300/20 bg-[rgba(61,40,9,0.88)] p-4 shadow-[0_18px_48px_rgba(0,0,0,0.35)] backdrop-blur-xl",children:[e.jsxs("div",{className:"pointer-events-auto flex items-center gap-2 text-[11px] uppercase tracking-[0.18em] text-amber-100/76",children:[e.jsx("span",{children:"Graph checks"}),e.jsx(V,{content:"These are preflight issues Forge found in the current graph before runtime. Fixing them here should prevent brittle run failures later.",label:"Explain graph checks"})]}),e.jsx("ul",{className:"mt-3 grid gap-2 text-sm leading-6 text-amber-50",children:ye.map(t=>e.jsx("li",{className:"list-inside list-disc",children:t},t))})]}):null,e.jsx(Ea,{nodeTypes:rs,nodes:sa,edges:E,onNodesChange:t=>W(s=>Aa(t,s)),onEdgesChange:t=>Q(s=>Ka(t,s)),onConnect:t=>Q(s=>Pa({...t,id:`edge_${crypto.randomUUID().replaceAll("-","").slice(0,8)}`,style:{stroke:"rgba(188, 194, 255, 0.44)",strokeWidth:1.6}},s)),onEdgeClick:(t,s)=>{Q(d=>d.filter(j=>j.id!==s.id))},onNodeClick:(t,s)=>{Ne(s.id)},onNodeDoubleClick:(t,s)=>{re(s.id,"overview")},fitView:!0,proOptions:{hideAttribution:!0},className:"bg-transparent",children:e.jsx(Oa,{color:"rgba(255,255,255,0.055)",gap:28})}),e.jsx("div",{className:"pointer-events-none absolute right-4 bottom-4 z-20 flex flex-col gap-2",children:e.jsxs("div",{className:"pointer-events-auto flex flex-col items-end gap-2",children:[e.jsxs("button",{type:"button",className:"inline-flex h-11 items-center gap-2 rounded-full bg-[rgba(31,41,69,0.92)] px-4 text-sm font-medium text-white shadow-[0_18px_42px_rgba(0,0,0,0.35)] transition hover:bg-[rgba(42,54,88,0.96)]",onClick:()=>de(!0),children:[e.jsx(la,{className:"size-4"}),"Add node"]}),e.jsxs("button",{type:"button",className:"inline-flex h-11 items-center gap-2 rounded-full bg-[rgba(31,41,69,0.92)] px-4 text-sm font-medium text-white shadow-[0_18px_42px_rgba(0,0,0,0.35)] transition hover:bg-[rgba(42,54,88,0.96)]",onClick:()=>Se(!0),children:[e.jsx(ia,{className:"size-4"}),"Flow settings"]}),e.jsxs("button",{type:"button",className:"inline-flex h-11 items-center gap-2 rounded-full bg-[rgba(31,41,69,0.92)] px-4 text-sm font-medium text-white shadow-[0_18px_42px_rgba(0,0,0,0.35)] transition hover:bg-[rgba(42,54,88,0.96)]",onClick:()=>pe(!0),children:[e.jsx(ze,{className:"size-4"}),"Run flow"]}),Z?e.jsxs("button",{type:"button",className:"inline-flex h-11 items-center gap-2 rounded-full bg-[rgba(31,41,69,0.92)] px-4 text-sm font-medium text-white shadow-[0_18px_42px_rgba(0,0,0,0.35)] transition hover:bg-[rgba(42,54,88,0.96)]",onClick:()=>Te(!0),children:[e.jsx(oa,{className:"size-4"}),"Latest trace"]}):null]})})]}),e.jsx(le,{open:Vt,onOpenChange:de,title:"Add node",description:"Add a Forge box, AI node, or utility node to the flow.",children:e.jsxs("div",{className:"grid gap-4",children:[e.jsx("div",{className:"grid gap-2 sm:grid-cols-2",children:[{type:"user_input",label:"User input",icon:e.jsx(_t,{className:"size-4"})},{type:"value",label:"Value",icon:e.jsx(Rt,{className:"size-4"})},{type:"functor",label:"Functor",icon:e.jsx(Et,{className:"size-4"})},{type:"chat",label:"Chat",icon:e.jsx(da,{className:"size-4"})},{type:"merge",label:"Merge",icon:e.jsx(Ot,{className:"size-4"})},{type:"template",label:"Template",icon:e.jsx(Pt,{className:"size-4"})},{type:"pick_key",label:"Pick key",icon:e.jsx(Kt,{className:"size-4"})},{type:"output",label:"Output",icon:e.jsx(At,{className:"size-4"})}].map(t=>e.jsxs("button",{type:"button",className:"flex items-center gap-3 rounded-[20px] bg-white/[0.04] px-4 py-3 text-left text-white transition hover:bg-white/[0.08]",onClick:()=>{W(s=>[...s,It(t.type,s)]),de(!1)},children:[t.icon,e.jsx("span",{children:t.label})]},t.type))}),e.jsx(Ba,{title:"Forge boxes",description:"",query:Fe,onQueryChange:Qt,options:ta,selectedOptionIds:_e,onSelectedOptionIdsChange:Yt,resultSummary:`${Be.length} boxes`,placeholder:"Search visible Forge boxes by title, route, or category",emptyStateMessage:"No boxes match the current query."}),e.jsx("div",{className:"grid max-h-[18rem] gap-2 overflow-auto pr-1",children:Be.map(t=>e.jsxs("button",{type:"button",className:"rounded-[20px] bg-white/[0.04] px-4 py-3 text-left transition hover:bg-white/[0.08]",onClick:()=>{W(s=>[...s,It("box",s,t)]),de(!1)},children:[e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsx("div",{className:"text-sm font-medium text-white",children:t.title}),e.jsxs("div",{className:"flex shrink-0 flex-wrap gap-2 text-[10px] uppercase tracking-[0.14em] text-white/42",children:[e.jsxs("span",{children:[t.output.length," output",t.output.length===1?"":"s"]}),e.jsxs("span",{children:[t.tools.length," tool",t.tools.length===1?"":"s"]})]})]}),e.jsx("div",{className:"mt-1 text-[12px] leading-5 text-white/50",children:t.description}),e.jsxs("div",{className:"mt-3 flex flex-wrap gap-2",children:[e.jsx("div",{className:"rounded-full bg-white/[0.05] px-2.5 py-1 text-[11px] text-white/56",children:t.category}),t.routePath?e.jsx("div",{className:"rounded-full bg-white/[0.05] px-2.5 py-1 text-[11px] text-white/56",children:t.routePath}):null]})]},t.id))})]})}),f&&ie(f.data.nodeType)?e.jsx(fa,{open:He,onOpenChange:t=>{$(t),t||Ce(void 0)},eyebrow:`Workbench · ${f.data.nodeType==="chat"?"Chat node":"Functor node"}`,title:f.data.label??"Edit node",description:"Configure this AI node with the same paged editor Forge uses elsewhere.",value:f.data,onChange:t=>_(s=>({...s,data:t})),draftPersistenceKey:`workbench.ai-node.${f.id}`,steps:aa,initialStepId:Dt,onSubmit:async()=>{$(!1),Ce(void 0)},submitLabel:"Done",contentClassName:"md:w-[min(60rem,calc(100vw-1.5rem))]"}):e.jsx(le,{open:He,onOpenChange:t=>{$(t),t||ue("overview")},title:(f==null?void 0:f.data.label)??"Edit node",description:"Edit the selected node without covering the graph with permanent forms.",children:f?e.jsxs("div",{className:"grid gap-3",children:[e.jsx("div",{className:"flex flex-wrap gap-2 rounded-full bg-white/[0.04] p-1",children:[{id:"overview",label:"Overview"},{id:"contracts",label:"Contracts"},{id:"parameters",label:"Parameters"}].filter(t=>t.id!=="contracts"||De).filter(t=>{var s;return t.id!=="parameters"||(((s=f.data.params)==null?void 0:s.length)??0)>0}).map(t=>e.jsx("button",{type:"button",className:R("rounded-full px-3 py-2 text-sm transition",ce===t.id?"bg-[rgba(192,193,255,0.18)] text-white":"text-white/58 hover:bg-white/[0.05] hover:text-white"),onClick:()=>ue(t.id),children:t.label},t.id))}),ce==="overview"?e.jsxs("div",{className:"grid gap-3",children:[e.jsx("input",{value:f.data.label,onChange:t=>_(s=>({...s,data:{...s.data,label:t.target.value}})),className:w}),e.jsx("textarea",{rows:3,value:f.data.description,onChange:t=>_(s=>({...s,data:{...s.data,description:t.target.value}})),className:w}),f.data.nodeType==="box"||f.data.nodeType==="box_input"?e.jsxs("select",{value:f.data.boxId??"",onChange:t=>{const s=i.find(d=>d.id===t.target.value);_(d=>({...d,data:{...d.data,boxId:t.target.value,label:(s==null?void 0:s.title)??d.data.label,description:(s==null?void 0:s.description)??d.data.description,inputs:(s==null?void 0:s.inputs)??[],outputs:(s==null?void 0:s.output)??[],params:(s==null?void 0:s.params)??[],enabledToolKeys:((s==null?void 0:s.tools)??[]).map(j=>j.key)}}))},className:w,children:[e.jsx("option",{value:"",children:"Select Forge box"}),i.map(t=>e.jsx("option",{value:t.id,children:t.title},t.id))]}):null,f.data.nodeType==="template"?e.jsx("textarea",{rows:4,value:f.data.template??"",onChange:t=>_(s=>({...s,data:{...s.data,template:t.target.value}})),placeholder:"Template string",className:w}):null,f.data.nodeType==="pick_key"?e.jsx("input",{value:f.data.selectedKey??"",onChange:t=>_(s=>({...s,data:{...s.data,selectedKey:t.target.value}})),placeholder:"Key to select from object input",className:w}):null,f.data.nodeType==="output"?e.jsxs("div",{className:"grid gap-3",children:[e.jsx("select",{value:f.data.outputKey??"answer",onChange:t=>_(s=>({...s,data:{...s.data,outputKey:t.target.value}})),className:w,children:Ge.length>0?Ge.map(t=>e.jsxs("option",{value:t.key,children:[t.label," (",t.key,")"]},t.key)):e.jsx("option",{value:f.data.outputKey??"answer",children:f.data.outputKey??"answer"})}),e.jsx("div",{className:"rounded-[18px] border border-white/8 bg-white/[0.03] px-4 py-3 text-sm leading-6 text-white/58",children:"Publish one upstream output as the flow result. If the output key is missing from the graph, Forge will flag it in graph checks."})]}):null,f.data.nodeType==="value"?e.jsxs(e.Fragment,{children:[e.jsx("select",{value:f.data.valueType??"string",onChange:t=>_(s=>({...s,data:{...s.data,valueType:t.target.value}})),className:w,children:["string","number","boolean","null","array","object"].map(t=>e.jsx("option",{value:t,children:t},t))}),e.jsx("textarea",{rows:4,value:f.data.valueLiteral??"",onChange:t=>_(s=>({...s,data:{...s.data,valueLiteral:t.target.value}})),placeholder:"Value literal or JSON",className:w})]}):null]}):null,ce==="contracts"?De?e.jsxs("div",{className:"grid gap-4",children:[e.jsx(we,{title:"Inputs",description:"Name the values this node expects so upstream wiring stays obvious.",ports:f.data.inputs??[],onChange:t=>_(s=>({...s,data:{...s.data,inputs:t}})),prefix:"input"}),e.jsx(we,{title:"Outputs",description:"Describe exactly what this node publishes, including semantic model names.",ports:f.data.outputs??[],onChange:t=>_(s=>({...s,data:{...s.data,outputs:t}})),prefix:"output"})]}):e.jsx("div",{className:"rounded-[20px] border border-white/8 bg-white/[0.03] px-4 py-4 text-sm leading-6 text-white/58",children:"This node inherits its contract from the registered Forge box. Edit the box definition in the registry when the contract itself needs to change."}):null,ce==="parameters"?e.jsxs("div",{className:"grid gap-3",children:[(f.data.params??[]).length===0?e.jsx("div",{className:"rounded-[20px] border border-white/8 bg-white/[0.03] px-4 py-4 text-sm leading-6 text-white/58",children:"This node does not expose any configurable parameters."}):null,(f.data.params??[]).map(t=>{var s,d,j;return e.jsxs("div",{className:"grid gap-2",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.18em] text-white/40",children:t.label}),t.kind==="boolean"?e.jsxs("label",{className:"flex items-center gap-3 rounded-[18px] border border-white/10 bg-black/20 px-4 py-3 text-sm text-white",children:[e.jsx("input",{type:"checkbox",checked:!!((s=f.data.paramValues)!=null&&s[t.key]),onChange:N=>_(v=>({...v,data:{...v.data,paramValues:{...v.data.paramValues??{},[t.key]:N.target.checked}}}))}),t.description??"Enabled"]}):t.kind==="array"||t.kind==="json"?e.jsx("textarea",{value:ve((d=f.data.paramValues)==null?void 0:d[t.key]),onChange:N=>_(v=>({...v,data:{...v.data,paramValues:{...v.data.paramValues??{},[t.key]:N.target.value}}})),placeholder:t.description??t.label,className:R(w,"min-h-[104px] resize-y")}):e.jsx("input",{type:t.kind==="number"?"number":"text",value:ve((j=f.data.paramValues)==null?void 0:j[t.key]),onChange:N=>_(v=>({...v,data:{...v.data,paramValues:{...v.data.paramValues??{},[t.key]:$t(t.kind,N.target.value)}}})),placeholder:t.description??t.label,className:w})]},t.key)})]}):null,e.jsxs("div",{className:"flex flex-wrap justify-between gap-2 pt-2",children:[e.jsxs(I,{type:"button",variant:"secondary",onClick:()=>{Qe(f.id),$(!1)},children:[e.jsx(Ae,{className:"size-4"}),"Delete node"]}),e.jsx(I,{type:"button",variant:"primary",onClick:()=>{$(!1),ue("overview")},children:"Done"})]})]}):null}),e.jsx(le,{open:Jt,onOpenChange:Se,title:"Flow settings",description:"Edit the flow identity and persistence without covering the graph with permanent forms.",children:e.jsxs("div",{className:"grid gap-3",children:[e.jsx("input",{value:n,onChange:t=>u(t.target.value),placeholder:"Flow title",className:w}),e.jsx("textarea",{rows:4,value:h,onChange:t=>y(t.target.value),placeholder:"Flow description",className:w}),e.jsxs("select",{value:b,onChange:t=>g(t.target.value),className:w,children:[e.jsx("option",{value:"functor",children:"Functor flow"}),e.jsx("option",{value:"chat",children:"Chat flow"})]}),e.jsx(as,{inputs:k,nodes:T,onChange:F}),e.jsx("div",{className:"rounded-[18px] border border-white/8 bg-white/[0.03] px-4 py-3 text-sm text-white/58",children:a.id}),e.jsxs("div",{className:"flex flex-wrap justify-between gap-2 pt-2",children:[e.jsxs(I,{type:"button",variant:"secondary",onClick:async()=>{await p()},children:[e.jsx(Ae,{className:"size-4"}),"Delete flow"]}),e.jsxs(I,{type:"button",variant:"primary",onClick:async()=>{await Ye(),Se(!1)},children:[e.jsx(vt,{className:"size-4"}),"Save settings"]})]})]})}),e.jsx(le,{open:Gt,onOpenChange:t=>{pe(t),t&&L(null)},title:"Run flow",description:"Run the flow or chat with it and keep the debug trace for every node.",children:e.jsxs("div",{className:"grid gap-3",children:[he?e.jsx("div",{className:"rounded-[20px] border border-rose-400/20 bg-rose-400/10 px-4 py-3 text-sm leading-6 text-rose-100",children:he}):null,!he&&ye.length>0?e.jsxs("div",{className:"rounded-[20px] border border-amber-400/20 bg-amber-400/10 px-4 py-3 text-sm leading-6 text-amber-100",children:[e.jsx("div",{className:"font-medium",children:"Fix these graph issues before running:"}),e.jsx("ul",{className:"mt-2 grid gap-1",children:ye.slice(0,4).map(t=>e.jsxs("li",{children:["• ",t]},t))})]}):null,!he&&Ve&&r.length===0?e.jsx("div",{className:"rounded-[20px] border border-sky-400/20 bg-sky-400/10 px-4 py-3 text-sm leading-6 text-sky-100",children:"This flow contains AI nodes, but Forge does not have a model connection yet. Open Settings > Models, add one connection, then come back and run the flow."}):null,k.length>0?e.jsxs("div",{className:"grid gap-3 rounded-[20px] border border-white/8 bg-white/[0.03] p-4",children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm text-white",children:["Flow inputs",e.jsx(V,{content:"These are the typed inputs this flow exposes through the API and the Run modal.",label:"Explain flow inputs"})]}),e.jsx("div",{className:"grid gap-3",children:k.map(t=>e.jsx(C,{label:t.label,description:t.description||"Typed input for this flow.",children:t.kind==="boolean"?e.jsxs("label",{className:"flex items-center gap-2 text-sm text-white/68",children:[e.jsx("input",{type:"checkbox",checked:!!H[t.key],onChange:s=>Y(d=>({...d,[t.key]:s.target.checked}))}),t.label]}):t.kind==="number"?e.jsx("input",{type:"number",value:typeof H[t.key]=="number"?String(H[t.key]):"",onChange:s=>Y(d=>({...d,[t.key]:s.target.value.trim().length===0?void 0:Number(s.target.value)})),className:w}):t.kind==="array"||t.kind==="entity_list"||t.kind==="record_list"||t.kind==="object"||t.kind==="json"||t.kind==="record"||t.kind==="context"||t.kind==="filters"||t.kind==="metrics"||t.kind==="timeline"||t.kind==="selection"||t.kind==="entity"?e.jsx("textarea",{rows:4,value:ve(H[t.key]),onChange:s=>{const d=s.target.value;let j=d;if(!d.trim())j=void 0;else try{j=JSON.parse(d)}catch{j=d}Y(N=>({...N,[t.key]:j}))},placeholder:'{"key":"value"}',className:w}):e.jsx("input",{value:typeof H[t.key]=="string"?H[t.key]:"",onChange:s=>Y(d=>({...d,[t.key]:s.target.value})),placeholder:t.exampleValue||t.label,className:w})},t.key))})]}):null,Pe?e.jsx("textarea",{rows:5,value:Re,onChange:t=>Xt(t.target.value),placeholder:"User input",className:w}):null,e.jsxs("label",{className:"flex items-center gap-2 text-sm text-white/64",children:[e.jsx("input",{type:"checkbox",checked:Ee,onChange:t=>Zt(t.target.checked)}),"Return debug trace"]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsxs(I,{type:"button",variant:"primary",onClick:()=>void Xe("run"),children:[e.jsx(ze,{className:"size-4"}),"Run"]}),e.jsxs(I,{type:"button",variant:"secondary",onClick:()=>void Xe("chat"),children:[e.jsx(zt,{className:"size-4"}),"Chat"]})]}),e.jsx("div",{className:"grid gap-2 pt-2",children:l.slice(0,5).map(t=>{var s;return e.jsxs("div",{className:"rounded-[18px] border border-white/8 bg-white/[0.04] px-4 py-3",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3 text-[12px] text-white/48",children:[e.jsx("span",{children:t.mode}),e.jsx("span",{children:new Date(t.createdAt).toLocaleString()})]}),e.jsx("div",{className:"mt-2 text-sm text-white/78",children:((s=t.result)==null?void 0:s.primaryText)??t.error??"No output yet."})]},t.id)})})]})}),e.jsx(le,{open:Ie,onOpenChange:Te,title:"Run inspector",description:"Inspect whole-flow outputs and stable node-level results for any saved run.",children:q?e.jsx("div",{className:"grid gap-4",children:e.jsxs("div",{className:"grid gap-3 md:grid-cols-[0.9fr_1.1fr]",children:[e.jsxs("div",{className:"rounded-[20px] border border-white/8 bg-white/[0.04] p-4",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.18em] text-white/42",children:"Run history"}),e.jsx("div",{className:"mt-3 grid gap-2",children:l.slice(0,12).map(t=>{var s;return e.jsxs("button",{type:"button",className:R("rounded-[18px] border px-4 py-3 text-left transition",D===t.id?"border-[var(--secondary)]/40 bg-[var(--secondary)]/12":"border-white/8 bg-black/20 hover:bg-white/[0.05]"),onClick:()=>Le(t.id),children:[e.jsxs("div",{className:"flex items-center justify-between gap-3 text-[12px] text-white/50",children:[e.jsx("span",{children:t.mode}),e.jsx("span",{children:new Date(t.createdAt).toLocaleString()})]}),e.jsx("div",{className:"mt-2 text-sm text-white/80",children:((s=t.result)==null?void 0:s.primaryText)??t.error??"No output yet."})]},t.id)})})]}),e.jsxs("div",{className:"grid gap-3",children:[e.jsxs("div",{className:"rounded-[20px] border border-white/8 bg-white/[0.04] p-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3 text-[12px] text-white/50",children:[e.jsx("span",{children:q.mode}),e.jsx("span",{children:new Date(q.createdAt).toLocaleString()})]}),e.jsx("div",{className:"mt-3 text-sm leading-6 text-white/82",children:((at=q.result)==null?void 0:at.primaryText)??q.error??"No output yet."}),(st=q.result)!=null&&st.outputs?e.jsxs("details",{className:"mt-3 rounded-[16px] bg-black/20 p-3",children:[e.jsx("summary",{className:"cursor-pointer text-[11px] uppercase tracking-[0.16em] text-white/38",children:"Published outputs"}),e.jsx("pre",{className:"mt-3 overflow-auto whitespace-pre-wrap text-[12px] leading-5 text-white/66",children:JSON.stringify(q.result.outputs,null,2)})]}):null]}),(((rt=J.data)==null?void 0:rt.nodeResults)??[]).length>0?e.jsxs("div",{className:"grid gap-3 xl:grid-cols-[0.9fr_1.1fr]",children:[e.jsxs("div",{className:"rounded-[20px] border border-white/8 bg-white/[0.04] p-4",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.18em] text-white/42",children:"Node results"}),e.jsx("div",{className:"mt-3 grid gap-2",children:(((nt=J.data)==null?void 0:nt.nodeResults)??[]).map(t=>e.jsx("button",{type:"button",className:R("rounded-[18px] border px-4 py-3 text-left transition",xe===t.nodeId?"border-[var(--secondary)]/40 bg-[var(--secondary)]/12":"border-white/8 bg-black/20 hover:bg-white/[0.05]"),onClick:()=>Ue(t.nodeId),children:e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-sm text-white",children:t.label}),e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/40",children:t.nodeType})]}),e.jsxs("div",{className:"rounded-full bg-white/[0.05] px-3 py-1 text-[11px] text-white/56",children:[Object.keys(t.outputMap).length," outputs"]})]})},t.nodeId))})]}),e.jsx("div",{className:"rounded-[20px] border border-white/8 bg-white/[0.04] p-4",children:P||(lt=K.data)!=null&&lt.nodeResult?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-sm font-medium text-white",children:(ot=((it=K.data)==null?void 0:it.nodeResult)??P)==null?void 0:ot.label}),e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/38",children:(ct=((dt=K.data)==null?void 0:dt.nodeResult)??P)==null?void 0:ct.nodeType})]}),e.jsxs("div",{className:"rounded-full bg-white/[0.05] px-3 py-1 text-[11px] text-white/56",children:[(((pt=((ut=K.data)==null?void 0:ut.nodeResult)??P)==null?void 0:pt.tools)??[]).length," ","tool",(((mt=((ht=K.data)==null?void 0:ht.nodeResult)??P)==null?void 0:mt.tools)??[]).length===1?"":"s"]})]}),e.jsxs("div",{className:"mt-3 grid gap-3",children:[e.jsxs("details",{className:"rounded-[16px] bg-black/20 p-3",children:[e.jsx("summary",{className:"cursor-pointer text-[11px] uppercase tracking-[0.16em] text-white/38",children:"Inputs"}),e.jsx("pre",{className:"mt-3 overflow-auto whitespace-pre-wrap text-[12px] leading-5 text-white/66",children:JSON.stringify(((gt=((xt=K.data)==null?void 0:xt.nodeResult)??P)==null?void 0:gt.input)??[],null,2)})]}),e.jsxs("details",{className:"rounded-[16px] bg-black/20 p-3",children:[e.jsx("summary",{className:"cursor-pointer text-[11px] uppercase tracking-[0.16em] text-white/38",children:"Output map"}),e.jsx("pre",{className:"mt-3 overflow-auto whitespace-pre-wrap text-[12px] leading-5 text-white/66",children:JSON.stringify(((ft=((bt=K.data)==null?void 0:bt.nodeResult)??P)==null?void 0:ft.outputMap)??{},null,2)})]}),e.jsxs("details",{className:"rounded-[16px] bg-black/20 p-3",children:[e.jsx("summary",{className:"cursor-pointer text-[11px] uppercase tracking-[0.16em] text-white/38",children:"Payload"}),e.jsx("pre",{className:"mt-3 overflow-auto whitespace-pre-wrap text-[12px] leading-5 text-white/66",children:JSON.stringify(((wt=((yt=K.data)==null?void 0:yt.nodeResult)??P)==null?void 0:wt.payload)??null,null,2)})]})]})]}):e.jsx("div",{className:"text-sm text-white/56",children:"Pick a node result to inspect its resolved inputs and outputs."})})]}):e.jsx("div",{className:"rounded-[20px] border border-white/8 bg-white/[0.04] p-4 text-sm text-white/56",children:J.isFetching?"Loading node results…":"This run does not have stored node results yet."})]})]})}):e.jsx("div",{className:"text-sm text-white/56",children:"Run the flow once to inspect its published outputs and node-level results here."})})]})}function vs(){const a=ua(),i=pa(),r=a.flowId??"",l=ja(),c=ka(r,{skip:r.length===0}),p=Na(),[m]=Ca(),[o]=Sa(),[n]=Ia(),[u]=Ta();return c.isLoading||p.isLoading?e.jsx(Fa,{eyebrow:"Workbench Flow",title:"Loading flow",description:"Preparing the Workbench graph editor."}):c.isError||p.isError||!c.data?!c.data&&!c.isError&&!p.isError?e.jsx(_a,{eyebrow:"Workbench Flow",title:"Flow unavailable",description:"Forge could not find that flow."}):e.jsx(Ra,{eyebrow:"Workbench Flow",error:c.error??p.error??null}):e.jsxs("div",{className:"grid gap-5",children:[e.jsx(ma,{entityKind:c.data.flow.kind,title:c.data.flow.title,titleText:c.data.flow.title,description:c.data.flow.description||"Inspect, run, and publish this Workbench flow.",badge:c.data.flow.kind,actions:e.jsx(ha,{entityType:"workbench_flow",entityId:c.data.flow.id})}),e.jsx(ds,{flow:c.data.flow,boxes:l,modelConnections:(p.data.settings.modelSettings.connections??[]).map(h=>({id:h.id,label:h.label,provider:h.provider,model:h.model,baseUrl:h.baseUrl})),runs:c.data.runs,onSave:async h=>{await m({flowId:r,patch:h}).unwrap()},onDelete:async()=>{await o(r).unwrap(),i("/workbench")},onRun:async h=>{await n({flowId:r,input:h}).unwrap()},onChat:async h=>{await u({flowId:r,input:h}).unwrap()}})]})}export{vs as WorkbenchFlowPage};
@@ -1 +0,0 @@
1
- import{b5 as j,c2 as v,r as o,j as t}from"./vendor-DHkYh85p.js";import{j as S,i as N,k as F}from"./state-B-4sS1xO.js";import{F as C}from"./faceted-token-search-BxRRcM3q.js";import{P as I}from"./page-hero-DRy5b2MU.js";import{fo as Q,B as p,b as W,fp as q,fq as K}from"./index-CF4J4R9L.js";import"./board-BkDRaMp6.js";import"./ui-C13Nbgas.js";import"./motion-BeD44FeG.js";import"./forms-BFlTgZ3W.js";import"./graph-D6JLqDbD.js";function R(){var u;const l=j(),m=S(),[f]=v(),g=f.get("surface"),[i,b]=o.useState(""),[c,w]=o.useState([]),x=N({queryKey:["forge-workbench-flows"],queryFn:K}),d=F({mutationFn:e=>Q({title:e==="chat"?"New chat flow":"New flow",description:e==="chat"?"Conversational workbench flow.":"Reusable workbench transformation flow.",kind:e,homeSurfaceId:g}),onSuccess:({flow:e})=>{m.invalidateQueries({queryKey:["forge-workbench-flows"]}),l(`/workbench/${e.id}`)}}),a=((u=x.data)==null?void 0:u.flows)??[],y=o.useMemo(()=>{const e=[{id:"kind:functor",label:"Functor",description:"Single transformation flows"},{id:"kind:chat",label:"Chat",description:"Conversational flows with user input"}],r=Array.from(new Set(a.map(s=>s.homeSurfaceId).filter(s=>!!s))).map(s=>({id:`surface:${s}`,label:s,description:"Home surface"}));return[...e,...r]},[a]),h=o.useMemo(()=>{const e=i.trim().toLowerCase();return a.filter(r=>{const s=e.length===0||[r.title,r.description,r.kind,r.homeSurfaceId??"",...r.graph.nodes.map(n=>n.data.label)].join(" ").toLowerCase().includes(e),k=c.every(n=>n.startsWith("kind:")?r.kind===n.replace("kind:",""):n.startsWith("surface:")?r.homeSurfaceId===n.replace("surface:",""):!0);return s&&k})},[a,i,c]);return t.jsxs("div",{className:"grid gap-5",children:[t.jsx(I,{entityKind:"workbench",title:"Workbench",titleText:"Workbench",description:"Search and launch reusable Forge flows, then open a flow to edit its graph, tools, prompts, and outputs.",badge:`${a.length} flows`}),t.jsxs("div",{className:"flex flex-wrap gap-2",children:[t.jsx(p,{type:"button",variant:"primary",onClick:()=>void d.mutateAsync("functor"),children:"New flow"}),t.jsx(p,{type:"button",variant:"secondary",onClick:()=>void d.mutateAsync("chat"),children:"New chat flow"})]}),t.jsx(C,{title:"Flow search",description:"Filter by flow kind or surface, then open a flow to edit or run it.",query:i,onQueryChange:b,options:y,selectedOptionIds:c,onSelectedOptionIdsChange:w,resultSummary:`${h.length} of ${a.length} flows`,placeholder:"Search flow title, description, nodes, or home surface"}),t.jsx("div",{className:"grid gap-3 lg:grid-cols-2",children:h.map(e=>t.jsxs("button",{type:"button",className:"rounded-[26px] border border-white/8 bg-[linear-gradient(180deg,rgba(20,28,46,0.92),rgba(10,16,29,0.96))] p-5 text-left transition hover:border-white/12 hover:bg-[linear-gradient(180deg,rgba(24,34,55,0.94),rgba(12,18,34,0.98))]",onClick:()=>l(`/workbench/${e.id}`),children:[t.jsxs("div",{className:"flex items-start justify-between gap-4",children:[t.jsxs("div",{className:"min-w-0",children:[t.jsx("div",{className:"truncate text-lg font-semibold text-white",children:e.title}),t.jsx("div",{className:"mt-1 line-clamp-2 text-sm leading-6 text-white/54",children:e.description||"No description yet."})]}),t.jsx(W,{kind:q(e.kind),label:e.kind==="chat"?"Chat flow":"Functor flow",compact:!0,gradient:!1})]}),t.jsxs("div",{className:"mt-4 flex flex-wrap gap-2 text-[12px] text-white/44",children:[t.jsxs("span",{children:[e.graph.nodes.length," nodes"]}),t.jsxs("span",{children:[e.graph.edges.length," edges"]}),e.homeSurfaceId?t.jsx("span",{children:e.homeSurfaceId}):null]})]},e.id))})]})}export{R as WorkbenchPage};
@@ -1,2 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/maps-ClgJoCjz.js","assets/vendor-DHkYh85p.js","assets/vendor-CRS-psbw.css","assets/maps-B-YMMjus.css"])))=>i.map(i=>d[i]);
2
- import{eH as $,S as H,E as B,c as j,C as c,T as D,I as E,B as F,eM as P,eN as I}from"./index-CF4J4R9L.js";import{cc as K,r as p,j as e,aC as W,bk as Q,bK as O,bU as q,dw as Z,bX as U}from"./vendor-DHkYh85p.js";import{j as X,i as Y,k as G}from"./state-B-4sS1xO.js";import"./maps-ClgJoCjz.js";import{P as V}from"./page-hero-DRy5b2MU.js";import{R as M,A as J,C as ee,X as C,Y as T,T as _,a as te,f as se,B as ae}from"./charts-P7EVhIog.js";import"./board-BkDRaMp6.js";import"./ui-C13Nbgas.js";import"./motion-BeD44FeG.js";import"./forms-BFlTgZ3W.js";import"./graph-D6JLqDbD.js";const A={below_z1:"#94a3b8",zone_1:"#38bdf8",zone_2:"#22c55e",zone_3:"#eab308",zone_4:"#f97316",zone_5:"#ef4444"};function v(t){return t?`${Math.round(t/60)}m`:"0m"}function z(t,a){const l=new Intl.DateTimeFormat(void 0,{weekday:"short",day:"numeric",month:"short"}),n=new Intl.DateTimeFormat(void 0,{hour:"2-digit",minute:"2-digit"});return`${l.format(new Date(t))} · ${n.format(new Date(t))} - ${n.format(new Date(a))}`}function ie(t,a){if(typeof t=="number"){const l=Number.isInteger(t)?String(t):t.toFixed(1);return a&&a!=="count"?`${l} ${a}`:l}return typeof t=="boolean"?t?"Yes":"No":t==null?"n/a":String(t)}function re(t){return t.length===0?null:{minLat:Math.min(...t.map(a=>a.latitude)),maxLat:Math.max(...t.map(a=>a.latitude)),minLon:Math.min(...t.map(a=>a.longitude)),maxLon:Math.max(...t.map(a=>a.longitude))}}function ne({points:t}){var w;const a=p.useRef(null),[l,n]=p.useState(!1),x=typeof window<"u"?((w=window.localStorage.getItem("forge.map.tile-url"))==null?void 0:w.trim())??"":"";p.useEffect(()=>{let h=!1,i=null;if(!x||!a.current||t.length<2){n(!1);return}return P(()=>import("./maps-ClgJoCjz.js").then(r=>r.m),__vite__mapDeps([0,1,2,3])).then(r=>{h||!a.current||(i=new r.Map({container:a.current,style:{version:8,sources:{tiles:{type:"raster",tiles:[x],tileSize:256}},layers:[{id:"tiles",type:"raster",source:"tiles"}]},center:[t[0].longitude,t[0].latitude],zoom:13,attributionControl:!1}),i.on("load",()=>{if(!i)return;const d=t.map(m=>[m.longitude,m.latitude]);i.addSource("route",{type:"geojson",data:{type:"Feature",properties:{},geometry:{type:"LineString",coordinates:d}}}),i.addLayer({id:"route",type:"line",source:"route",paint:{"line-color":"#f97316","line-width":4}});const u=d.reduce((m,g)=>m.extend(g),new r.LngLatBounds(d[0],d[0]));i.fitBounds(u,{padding:44,maxZoom:15}),n(!0)}))}),()=>{h=!0,i==null||i.remove()}},[t,x]);const o=re(t),f=p.useMemo(()=>{if(!o||t.length<2)return"";const h=720,i=280,r=Math.max(1e-6,o.maxLon-o.minLon),d=Math.max(1e-6,o.maxLat-o.minLat);return t.map(u=>{const m=(u.longitude-o.minLon)/r*h,g=i-(u.latitude-o.minLat)/d*i;return`${m.toFixed(1)},${g.toFixed(1)}`}).join(" ")},[o,t]);return e.jsxs("div",{className:"relative min-h-[280px] overflow-hidden rounded-[8px] border border-white/10 bg-white/[0.035]",children:[e.jsx("div",{ref:a,className:"absolute inset-0"}),l?null:e.jsxs("svg",{viewBox:"0 0 720 280",className:"absolute inset-0 h-full w-full",children:[e.jsx("rect",{width:"720",height:"280",fill:"rgba(255,255,255,0.025)"}),f?e.jsx("polyline",{points:f,fill:"none",stroke:"#f97316",strokeWidth:"5",strokeLinecap:"round",strokeLinejoin:"round"}):null]}),e.jsx("div",{className:"absolute left-3 top-3 rounded-[8px] border border-white/10 bg-black/50 px-3 py-2 text-xs text-white/70 backdrop-blur",children:x?"Local-first map tiles configured":"No tile source configured; showing private route shape only"})]})}function le({zones:t}){return e.jsx("div",{className:"grid gap-3",children:t.map(a=>e.jsxs("div",{className:"grid gap-2",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3 text-sm",children:[e.jsx("span",{className:"text-white/72",children:a.label}),e.jsxs("span",{className:"text-white",children:[(a.percentage*100).toFixed(1),"% · ",v(a.seconds)]})]}),e.jsx("div",{className:"h-2 overflow-hidden rounded-full bg-white/[0.08]",children:e.jsx("div",{className:"h-full rounded-full",style:{width:`${Math.max(1,a.percentage*100)}%`,background:A[a.key]??"#f8fafc"}})})]},a.key))})}function je(){var g,N,y,b,k,S,L,R;const{workoutId:t=""}=K(),a=X(),l=Y({queryKey:["workout-detail",t],queryFn:()=>I(t),enabled:t.length>0}),n=l.data,[x,o]=p.useState(""),[f,w]=p.useState("");p.useEffect(()=>{n!=null&&n.workout&&(o(n.workout.meaningText??""),w(n.workout.tags.join(", ")))},[n==null?void 0:n.workout]);const h=G({mutationFn:()=>$(t,{meaningText:x,tags:f.split(",").map(s=>s.trim()).filter(Boolean)}),onSuccess:async()=>{await a.invalidateQueries({queryKey:["workout-detail",t]}),await a.invalidateQueries({queryKey:["forge-fitness"]})}});if(l.isLoading)return e.jsx(H,{title:"Loading workout"});if(l.isError||!n)return e.jsx(B,{eyebrow:"Workout detail",error:l.error??new Error("Forge could not load this workout detail."),onRetry:()=>void l.refetch()});const{workout:i,analytics:r,evidence:d}=n,u=d.timeSeries.filter(s=>s.metricKey==="heart_rate").map(s=>({time:new Date(s.startedAt).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"}),bpm:s.value})),m=r.zoneDurations.map(s=>({zone:s.label,minutes:Math.round(s.seconds/60),fill:A[s.key]??"#f8fafc"}));return e.jsxs("div",{className:"grid gap-6",children:[e.jsxs(W,{to:"/sports",className:"inline-flex w-fit items-center gap-2 text-sm text-white/62 transition hover:text-white",children:[e.jsx(Q,{className:"size-4"}),"Back to sports"]}),e.jsx(V,{eyebrow:"Workout evidence",title:i.workoutTypeLabel??i.workoutType,description:`${z(i.startedAt,i.endedAt)} · ${i.sourceDevice||"Apple Health"}`,actions:e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx(j,{children:v(i.durationSeconds)}),e.jsxs(j,{tone:"meta",children:[r.confidence," HR zones"]}),(g=r.routeSummary)!=null&&g.hasRoute?e.jsxs(j,{tone:"meta",children:[r.routeSummary.pointCount," route points"]}):null]})}),e.jsxs("section",{className:"grid gap-4 lg:grid-cols-4",children:[e.jsxs(c,{children:[e.jsx("div",{className:"text-sm text-white/58",children:"Avg HR"}),e.jsx("div",{className:"mt-3 font-display text-4xl text-white",children:r.hrSummary.averageHr??i.averageHeartRate??"n/a"}),e.jsx("div",{className:"mt-1 text-sm text-white/48",children:"bpm"})]}),e.jsxs(c,{children:[e.jsx("div",{className:"text-sm text-white/58",children:"Max HR"}),e.jsx("div",{className:"mt-3 font-display text-4xl text-white",children:r.hrSummary.maxHr??i.maxHeartRate??"n/a"}),e.jsx("div",{className:"mt-1 text-sm text-white/48",children:"bpm"})]}),e.jsxs(c,{children:[e.jsx("div",{className:"text-sm text-white/58",children:"Training load"}),e.jsx("div",{className:"mt-3 font-display text-4xl text-white",children:r.load.trimp??"n/a"}),e.jsx("div",{className:"mt-1 text-sm text-white/48",children:"Forge TRIMP"})]}),e.jsxs(c,{children:[e.jsx("div",{className:"text-sm text-white/58",children:"HR coverage"}),e.jsxs("div",{className:"mt-3 font-display text-4xl text-white",children:[Math.round((r.dataQuality.sampleCoverage??0)*100),"%"]}),e.jsxs("div",{className:"mt-1 text-sm text-white/48",children:[r.dataQuality.heartRateSampleCount??0," samples"]})]})]}),e.jsxs("section",{className:"grid min-w-0 gap-4 xl:grid-cols-[minmax(0,1.25fr)_minmax(280px,0.75fr)]",children:[e.jsxs(c,{className:"min-h-[360px] min-w-0 overflow-hidden",children:[e.jsxs("div",{className:"flex items-center gap-2 text-white",children:[e.jsx(O,{className:"size-4 text-[var(--primary)]"}),"Heart-rate timeline"]}),e.jsx("div",{className:"mt-4 h-[300px]",children:u.length>0?e.jsx(M,{width:"100%",height:"100%",children:e.jsxs(J,{data:u,children:[e.jsx("defs",{children:e.jsxs("linearGradient",{id:"hrFill",x1:"0",y1:"0",x2:"0",y2:"1",children:[e.jsx("stop",{offset:"0%",stopColor:"#ef4444",stopOpacity:.38}),e.jsx("stop",{offset:"100%",stopColor:"#ef4444",stopOpacity:.04})]})}),e.jsx(ee,{stroke:"rgba(255,255,255,0.08)",vertical:!1}),e.jsx(C,{dataKey:"time",interval:"preserveStartEnd",tick:{fill:"rgba(255,255,255,0.55)",fontSize:11}}),e.jsx(T,{tick:{fill:"rgba(255,255,255,0.55)",fontSize:11},width:42}),e.jsx(_,{contentStyle:{background:"rgba(8,12,22,0.94)",border:"1px solid rgba(255,255,255,0.12)",borderRadius:8,color:"white"}}),e.jsx(te,{type:"monotone",dataKey:"bpm",stroke:"#ef4444",fill:"url(#hrFill)",strokeWidth:2,dot:!1})]})}):e.jsx("div",{className:"grid h-full place-items-center rounded-[8px] bg-white/[0.035] text-sm text-white/54",children:"No raw HR timeline has been synced for this workout yet."})})]}),e.jsxs(c,{className:"min-w-0 overflow-hidden",children:[e.jsxs("div",{className:"flex items-center gap-2 text-white",children:[e.jsx(q,{className:"size-4 text-[var(--primary)]"}),"Zone mix"]}),e.jsx("div",{className:"mt-4",children:e.jsx(le,{zones:r.zoneDurations})}),e.jsx("div",{className:"mt-5 h-[180px]",children:e.jsx(M,{width:"100%",height:"100%",children:e.jsxs(se,{data:m,children:[e.jsx(C,{dataKey:"zone",tick:{fill:"rgba(255,255,255,0.55)",fontSize:10}}),e.jsx(T,{tick:{fill:"rgba(255,255,255,0.55)",fontSize:10},width:34}),e.jsx(_,{contentStyle:{background:"rgba(8,12,22,0.94)",border:"1px solid rgba(255,255,255,0.12)",borderRadius:8,color:"white"}}),e.jsx(ae,{dataKey:"minutes",radius:[4,4,0,0]})]})})})]})]}),e.jsxs("section",{className:"grid min-w-0 gap-4 xl:grid-cols-[minmax(0,1fr)_360px]",children:[e.jsxs(c,{className:"min-w-0 overflow-hidden",children:[e.jsxs("div",{className:"flex items-center gap-2 text-white",children:[e.jsx(Z,{className:"size-4 text-[var(--primary)]"}),"Route"]}),e.jsx("div",{className:"mt-4",children:d.routePoints.length>1?e.jsx(ne,{points:d.routePoints}):e.jsx("div",{className:"grid min-h-[240px] place-items-center rounded-[8px] bg-white/[0.035] text-sm text-white/54",children:"No route evidence is available for this workout."})})]}),e.jsxs(c,{className:"min-w-0 overflow-hidden",children:[e.jsx("div",{className:"text-white",children:"Captured metrics"}),e.jsx("div",{className:"mt-4 grid gap-3",children:(((N=i.details)==null?void 0:N.metrics)??[]).slice(0,14).map(s=>e.jsxs("div",{className:"rounded-[8px] bg-white/[0.04] px-3 py-2",children:[e.jsx("div",{className:"text-sm text-white/58",children:s.label}),e.jsx("div",{className:"mt-1 text-white",children:ie(s.value,s.unit)})]},`${s.category}:${s.key}:${s.statistic}`))})]})]}),e.jsxs("section",{className:"grid min-w-0 gap-4 lg:grid-cols-[minmax(0,1fr)_minmax(280px,0.7fr)]",children:[e.jsxs(c,{className:"min-w-0 overflow-hidden",children:[e.jsx("div",{className:"text-white",children:"Events and phases"}),e.jsxs("div",{className:"mt-4 grid gap-3",children:[[...((y=i.details)==null?void 0:y.events)??[],...((b=i.details)==null?void 0:b.components)??[]].slice(0,18).map(s=>e.jsxs("div",{className:"rounded-[8px] bg-white/[0.04] px-4 py-3",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsx("div",{className:"text-white",children:"label"in s?s.label:s.activity.canonicalLabel}),e.jsx(j,{tone:"meta",children:v(s.durationSeconds)})]}),e.jsx("div",{className:"mt-1 text-sm text-white/52",children:z(s.startedAt,s.endedAt??s.startedAt)})]},`${"type"in s?s.type:s.externalUid}:${s.startedAt}`)),(((S=(k=i.details)==null?void 0:k.events)==null?void 0:S.length)??0)+(((R=(L=i.details)==null?void 0:L.components)==null?void 0:R.length)??0)===0?e.jsx("div",{className:"rounded-[8px] bg-white/[0.035] p-4 text-sm text-white/52",children:"No provider events or phases were captured."}):null]})]}),e.jsxs(c,{className:"min-w-0 overflow-hidden",children:[e.jsx("div",{className:"text-white",children:"Reflection"}),e.jsxs("div",{className:"mt-4 grid gap-4",children:[e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:"text-sm text-white/58",children:"Meaning and impact"}),e.jsx(D,{className:"min-h-[160px]",value:x,onChange:s=>o(s.target.value)})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:"text-sm text-white/58",children:"Tags"}),e.jsx(E,{value:f,onChange:s=>w(s.target.value)})]}),e.jsxs(F,{type:"button",pending:h.isPending,pendingLabel:"Saving",onClick:()=>h.mutate(),children:[e.jsx(U,{className:"size-4"}),"Save reflection"]})]})]})]})]})}export{je as WorkoutDetailPage};