forge-openclaw-plugin 0.2.101 → 0.2.103

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 (227) hide show
  1. package/dist/assets/activity-page-Dv6X5ZCV.js +1 -0
  2. package/dist/assets/ai-surface-workspace-CutiG6uS.js +1 -0
  3. package/dist/assets/atlas-panel-jgMRyaHn.js +1 -0
  4. package/dist/assets/{board-BkDRaMp6.js → board-dIX6etHh.js} +1 -1
  5. package/dist/assets/calendar-page-q7Nm5E2U.js +1 -0
  6. package/dist/assets/calendar-rules-DPFsfiRl.js +1 -0
  7. package/dist/assets/calendar-week-toolbar-nVhgB-0s.js +1 -0
  8. package/dist/assets/{charts-P7EVhIog.js → charts-DFnEuIMB.js} +8 -8
  9. package/dist/assets/companion-sync-lab-page-CJ8UTij8.js +1 -0
  10. package/dist/assets/daily-metrics-dashboard-CiJkkkd1.js +1 -0
  11. package/dist/assets/entity-note-count-link-RzBB6ujx.js +1 -0
  12. package/dist/assets/entity-notes-surface-Djz50HvD.js +1 -0
  13. package/dist/assets/execution-board-CtPhI-58.js +1 -0
  14. package/dist/assets/faceted-token-search-DEC6ANa9.js +1 -0
  15. package/dist/assets/flagship-signal-deck-CtHC3mql.js +1 -0
  16. package/dist/assets/floating-action-menu-CKQRhff9.js +1 -0
  17. package/dist/assets/{forms-BFlTgZ3W.js → forms-hB0SqEh-.js} +1 -1
  18. package/dist/assets/goal-detail-page-CF5fNQeR.js +1 -0
  19. package/dist/assets/goals-page-fsY8NzGB.js +1 -0
  20. package/dist/assets/{graph-D6JLqDbD.js → graph-DDUZNRsO.js} +14 -14
  21. package/dist/assets/habits-page-COoGz4kj.js +1 -0
  22. package/dist/assets/index-BAXYM89v.css +1 -0
  23. package/dist/assets/index-EqQsXoat.js +19 -0
  24. package/dist/assets/insight-flow-dialog-DtX_5W7g.js +1 -0
  25. package/dist/assets/insights-page-cBd74ObU.js +8 -0
  26. package/dist/assets/kanban-page-CYav9THw.js +1 -0
  27. package/dist/assets/knowledge-graph-page-D2A-W1jE.js +1 -0
  28. package/dist/assets/{life-force-page-Dy0JTS2G.js → life-force-page-CACGlNhq.js} +1 -1
  29. package/dist/assets/life-force-workspace-BJ4N1I78.js +1 -0
  30. package/dist/assets/{maps-ClgJoCjz.js → maps-C-yOWiDN.js} +1 -1
  31. package/dist/assets/metric-tile-CMadwnGz.js +1 -0
  32. package/dist/assets/{motion-BeD44FeG.js → motion-Lt5B1XuE.js} +1 -1
  33. package/dist/assets/movement-page-D5VqFd2q.js +1 -0
  34. package/dist/assets/note-markdown-BzK2Qlgr.js +3 -0
  35. package/dist/assets/note-tags-input-CZzqJMLc.js +1 -0
  36. package/dist/assets/notes-page-D3Hsh90C.js +1 -0
  37. package/dist/assets/{open-in-graph-button-IXe9SGth.js → open-in-graph-button-BFPKfyK3.js} +1 -1
  38. package/dist/assets/orbit-map-CnyfSmOG.js +1 -0
  39. package/dist/assets/overview-page-CXdWrOV1.js +1 -0
  40. package/dist/assets/page-hero-ffKzgyW3.js +1 -0
  41. package/dist/assets/pill-cluster-C2D0h3lx.js +1 -0
  42. package/dist/assets/{preference-entity-handoff-button-5PzUn42S.js → preference-entity-handoff-button-Dj3V6VxL.js} +1 -1
  43. package/dist/assets/preferences-page-Jo8Gw386.js +1 -0
  44. package/dist/assets/project-collections-qSqp90HN.js +1 -0
  45. package/dist/assets/{project-detail-page-BXK5-4xW.js → project-detail-page-BifhiLQX.js} +1 -1
  46. package/dist/assets/project-management-hierarchy-page-DZ_9klIc.js +1 -0
  47. package/dist/assets/project-management-section-nav-BImLCVvf.js +1 -0
  48. package/dist/assets/projects-page-ptcx6H38.js +1 -0
  49. package/dist/assets/psyche-behaviors-page-BDwXyDta.js +5 -0
  50. package/dist/assets/psyche-flashcards-page-DL1BP1jX.js +1 -0
  51. package/dist/assets/psyche-goal-map-page-ovcpisx1.js +1 -0
  52. package/dist/assets/psyche-graph-EP5GL612.js +1 -0
  53. package/dist/assets/{psyche-metrics-page-CuR9oqEy.js → psyche-metrics-page-Bcu813Rg.js} +1 -1
  54. package/dist/assets/psyche-mode-guide-page-C0g27Xpt.js +1 -0
  55. package/dist/assets/psyche-modes-page-BjKjX5MR.js +1 -0
  56. package/dist/assets/psyche-page-F4tF2W70.js +1 -0
  57. package/dist/assets/psyche-patterns-page-B-14hukK.js +5 -0
  58. package/dist/assets/psyche-questionnaire-builder-page-BdXmoHvK.js +1 -0
  59. package/dist/assets/psyche-questionnaire-detail-page-Cu5uwlJu.js +1 -0
  60. package/dist/assets/psyche-questionnaire-run-detail-page-C3R4PClg.js +1 -0
  61. package/dist/assets/psyche-questionnaire-run-page-Div3iDdt.js +1 -0
  62. package/dist/assets/psyche-questionnaires-page-DpqAPQCp.js +1 -0
  63. package/dist/assets/psyche-report-detail-page-BvWVDKP3.js +3 -0
  64. package/dist/assets/psyche-reports-page-BrbWUlAq.js +1 -0
  65. package/dist/assets/{psyche-schemas-HFmg37Wj.js → psyche-schemas-Dxj554nU.js} +1 -1
  66. package/dist/assets/psyche-schemas-beliefs-page-DYKvAtSD.js +9 -0
  67. package/dist/assets/psyche-screen-time-page-CAOKCyQw.js +1 -0
  68. package/dist/assets/psyche-self-observation-page-F0MVA0UH.js +1 -0
  69. package/dist/assets/psyche-values-page-DyvX-d0o.js +5 -0
  70. package/dist/assets/report-chain-fields-CeC1cJFS.js +1 -0
  71. package/dist/assets/rewards-page-C2loyODo.js +1 -0
  72. package/dist/assets/scheduling-rules-editor-D40AC2jR.js +1 -0
  73. package/dist/assets/schema-badge-FY7818qB.js +1 -0
  74. package/dist/assets/schema-visuals-CvC9a3i6.js +1 -0
  75. package/dist/assets/select-menu-DJsCG6rM.js +1 -0
  76. package/dist/assets/settings-agents-page-BFkJ5AAD.js +6 -0
  77. package/dist/assets/settings-bin-page-D3-Ab-iA.js +1 -0
  78. package/dist/assets/settings-calendar-page-ly_mSTAD.js +5 -0
  79. package/dist/assets/settings-data-page-D7QOqNf-.js +1 -0
  80. package/dist/assets/settings-logs-page-Ca87HEUx.js +1 -0
  81. package/dist/assets/settings-mobile-page-D0jejZot.js +1 -0
  82. package/dist/assets/settings-models-page-DPDsZjSc.js +1 -0
  83. package/dist/assets/settings-page-1cArlSPM.js +1 -0
  84. package/dist/assets/settings-rewards-page-Db4BV1DC.js +1 -0
  85. package/dist/assets/{settings-section-nav-DSOuht_F.js → settings-section-nav-DP9o4peU.js} +1 -1
  86. package/dist/assets/settings-users-page-BHFyDSsd.js +1 -0
  87. package/dist/assets/settings-wiki-page-BNaiupBm.js +1 -0
  88. package/dist/assets/sleep-page-BmOPF0yD.js +1 -0
  89. package/dist/assets/sports-page-BldIiclr.js +1 -0
  90. package/dist/assets/{state-B-4sS1xO.js → state-vCcAT5Hq.js} +1 -1
  91. package/dist/assets/strategies-page-CaTN99qj.js +1 -0
  92. package/dist/assets/strategy-detail-page-DsgFTd-U.js +1 -0
  93. package/dist/assets/strategy-dialog-7X7peRzu.js +1 -0
  94. package/dist/assets/surface-CJI17F3n.js +1 -0
  95. package/dist/assets/{table-WfAPUppN.js → table-BNqMG3_S.js} +1 -1
  96. package/dist/assets/task-detail-page-M1sIIPA8.js +1 -0
  97. package/dist/assets/timebox-planning-dialog-ByojN0AN.js +1 -0
  98. package/dist/assets/today-page-BjDijtn8.js +1 -0
  99. package/dist/assets/training-load-page-BPRmaWmF.js +1 -0
  100. package/dist/assets/{ui-C13Nbgas.js → ui-C1iwpj2-.js} +4 -4
  101. package/dist/assets/use-psyche-focus-target-Ct-acS9G.js +1 -0
  102. package/dist/assets/vendor-Dnkkx2co.js +1067 -0
  103. package/dist/assets/{vitals-page-qre17Nw8.js → vitals-page-CE9zdGLF.js} +1 -1
  104. package/dist/assets/weekly-review-page-CzhTv90n.js +1 -0
  105. package/dist/assets/weight-loss-page-Bp_cIk78.js +5 -0
  106. package/dist/assets/wiki-article-markdown-Dok2uy2p.js +4 -0
  107. package/dist/assets/wiki-editor-page-BuW32Y3f.js +26 -0
  108. package/dist/assets/wiki-ingest-history-page-DZKSBNHV.js +1 -0
  109. package/dist/assets/wiki-ingest-modal-DyqBEZcC.js +1 -0
  110. package/dist/assets/wiki-page-DqxlbLKG.js +1 -0
  111. package/dist/assets/workbench-flow-page-C4nc9jUg.js +5 -0
  112. package/dist/assets/workbench-page-BnyR7SL0.js +1 -0
  113. package/dist/assets/workout-detail-page-DT-c5cHL.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 +125 -33
  118. package/dist/server/server/src/health-weight-loss.js +554 -77
  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 +21 -12
  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/components/workbench-boxes/shared/generic-node-view.js +13 -5
  126. package/dist/server/src/lib/api.js +24 -5
  127. package/dist/server/src/lib/theme-system.js +8 -0
  128. package/openclaw.plugin.json +1 -1
  129. package/package.json +3 -3
  130. package/server/migrations/067_weight_loss_daily_active_overrides.sql +13 -0
  131. package/skills/forge-openclaw/SKILL.md +13 -0
  132. package/skills/forge-openclaw/entity_conversation_playbooks.md +7 -1
  133. package/dist/assets/activity-page-CpjuNSHw.js +0 -1
  134. package/dist/assets/ai-surface-workspace-DEAFZruS.js +0 -1
  135. package/dist/assets/atlas-panel-CdVNPotj.js +0 -1
  136. package/dist/assets/calendar-page-DNNt6lfz.js +0 -1
  137. package/dist/assets/calendar-rules-DNJFNsxi.js +0 -1
  138. package/dist/assets/calendar-week-toolbar-BbPwYeN0.js +0 -1
  139. package/dist/assets/companion-sync-lab-page-KxEDigM6.js +0 -1
  140. package/dist/assets/daily-metrics-dashboard-B3cqJgDt.js +0 -1
  141. package/dist/assets/entity-note-count-link-DrhjJZ4i.js +0 -1
  142. package/dist/assets/entity-notes-surface-CkcRsKJQ.js +0 -1
  143. package/dist/assets/execution-board-D07gOocB.js +0 -1
  144. package/dist/assets/faceted-token-search-BxRRcM3q.js +0 -1
  145. package/dist/assets/flagship-signal-deck-cmy82b8_.js +0 -1
  146. package/dist/assets/floating-action-menu-Fs_ZiUMo.js +0 -1
  147. package/dist/assets/goal-detail-page-CqLiNz4f.js +0 -1
  148. package/dist/assets/goals-page-BTk7mg_T.js +0 -1
  149. package/dist/assets/habits-page-BJxagdzx.js +0 -1
  150. package/dist/assets/index-CF4J4R9L.js +0 -19
  151. package/dist/assets/index-CZbuZQjw.css +0 -1
  152. package/dist/assets/insight-flow-dialog-8f3D0GuC.js +0 -1
  153. package/dist/assets/insights-page-D6rOa7uk.js +0 -8
  154. package/dist/assets/kanban-page-XQ7Se6dH.js +0 -1
  155. package/dist/assets/knowledge-graph-page-BtAg8iv3.js +0 -1
  156. package/dist/assets/life-force-workspace-OfyB9HJM.js +0 -1
  157. package/dist/assets/metric-tile-DKpo-8xw.js +0 -1
  158. package/dist/assets/movement-page-Bg_T_Stx.js +0 -1
  159. package/dist/assets/note-markdown-N-uxD3Xt.js +0 -3
  160. package/dist/assets/note-tags-input-Cdu7wiw6.js +0 -1
  161. package/dist/assets/notes-page-CKXnF_KU.js +0 -1
  162. package/dist/assets/orbit-map-Dzi6KliQ.js +0 -1
  163. package/dist/assets/overview-page-1miYqaVS.js +0 -1
  164. package/dist/assets/page-hero-DRy5b2MU.js +0 -1
  165. package/dist/assets/pill-cluster-C9QczVJ2.js +0 -1
  166. package/dist/assets/preferences-page-DtNaF5Q3.js +0 -1
  167. package/dist/assets/project-collections-xPz2mlRr.js +0 -1
  168. package/dist/assets/project-management-hierarchy-page-DtRpMABw.js +0 -1
  169. package/dist/assets/project-management-section-nav-P3ixzPa-.js +0 -1
  170. package/dist/assets/projects-page-C5ViRuf4.js +0 -1
  171. package/dist/assets/psyche-behaviors-page-Dco46sC4.js +0 -5
  172. package/dist/assets/psyche-flashcards-page-ZcoEB8gV.js +0 -1
  173. package/dist/assets/psyche-goal-map-page-CLBAQOI0.js +0 -1
  174. package/dist/assets/psyche-graph-k4tX2tdp.js +0 -1
  175. package/dist/assets/psyche-mode-guide-page-hIVXcCnE.js +0 -1
  176. package/dist/assets/psyche-modes-page-0lYtBlhO.js +0 -1
  177. package/dist/assets/psyche-page-VZ9k9ISp.js +0 -1
  178. package/dist/assets/psyche-patterns-page-gx5nmdGq.js +0 -5
  179. package/dist/assets/psyche-questionnaire-builder-page-Bn0TOISd.js +0 -1
  180. package/dist/assets/psyche-questionnaire-detail-page-CmVzSd_s.js +0 -1
  181. package/dist/assets/psyche-questionnaire-run-detail-page-BsMbmXCG.js +0 -1
  182. package/dist/assets/psyche-questionnaire-run-page-CgkRL2vi.js +0 -1
  183. package/dist/assets/psyche-questionnaires-page-D7V8uLXM.js +0 -1
  184. package/dist/assets/psyche-report-detail-page-OlFq57eL.js +0 -3
  185. package/dist/assets/psyche-reports-page-dVUZjna1.js +0 -1
  186. package/dist/assets/psyche-schemas-beliefs-page-BCgc8FUd.js +0 -9
  187. package/dist/assets/psyche-screen-time-page-B_6BT_WN.js +0 -1
  188. package/dist/assets/psyche-self-observation-page-CEG5mluK.js +0 -1
  189. package/dist/assets/psyche-values-page-DRbRfEd6.js +0 -5
  190. package/dist/assets/report-chain-fields-CALCV3V5.js +0 -1
  191. package/dist/assets/rewards-page-DmC4R_Ps.js +0 -1
  192. package/dist/assets/scheduling-rules-editor-D02s70hr.js +0 -1
  193. package/dist/assets/schema-badge-BZO-qNhO.js +0 -1
  194. package/dist/assets/schema-visuals-D6nxjbYC.js +0 -1
  195. package/dist/assets/select-menu-fYyreSdQ.js +0 -1
  196. package/dist/assets/settings-agents-page-C_v_hMJF.js +0 -6
  197. package/dist/assets/settings-bin-page-DY5bg81n.js +0 -1
  198. package/dist/assets/settings-calendar-page-D1CzE6cg.js +0 -5
  199. package/dist/assets/settings-data-page-CHRQFU9H.js +0 -1
  200. package/dist/assets/settings-logs-page-B04pUwEv.js +0 -1
  201. package/dist/assets/settings-mobile-page-D9kTlYDS.js +0 -1
  202. package/dist/assets/settings-models-page-D26270R2.js +0 -1
  203. package/dist/assets/settings-page-DYDTFlnv.js +0 -1
  204. package/dist/assets/settings-rewards-page-cl4vqqO_.js +0 -1
  205. package/dist/assets/settings-users-page-BU79JB_T.js +0 -1
  206. package/dist/assets/settings-wiki-page-DwAUlyA3.js +0 -1
  207. package/dist/assets/sleep-page-D8NbdhyS.js +0 -1
  208. package/dist/assets/sports-page-CV4Cnzwn.js +0 -1
  209. package/dist/assets/strategies-page-C4qvXnql.js +0 -1
  210. package/dist/assets/strategy-detail-page-DJLo5rfy.js +0 -1
  211. package/dist/assets/strategy-dialog-D3AuUlVz.js +0 -1
  212. package/dist/assets/task-detail-page-z-9u9rF0.js +0 -1
  213. package/dist/assets/timebox-planning-dialog-DB6FLqmI.js +0 -1
  214. package/dist/assets/today-page-BKlu6gx5.js +0 -1
  215. package/dist/assets/training-load-page-CyJQqo_3.js +0 -1
  216. package/dist/assets/use-psyche-focus-target-C1C_XjYG.js +0 -1
  217. package/dist/assets/vendor-DHkYh85p.js +0 -1052
  218. package/dist/assets/weekly-review-page-Cz4vkRcx.js +0 -1
  219. package/dist/assets/weight-loss-page-BQrnOI0y.js +0 -1
  220. package/dist/assets/wiki-article-markdown-DdiR2TJE.js +0 -4
  221. package/dist/assets/wiki-editor-page-DqwoqVFb.js +0 -26
  222. package/dist/assets/wiki-ingest-history-page--evBLbOw.js +0 -1
  223. package/dist/assets/wiki-ingest-modal--ohzFnj2.js +0 -1
  224. package/dist/assets/wiki-page-B_VJFBPA.js +0 -1
  225. package/dist/assets/workbench-flow-page-Du62mtJU.js +0 -5
  226. package/dist/assets/workbench-page-4MKr3iRm.js +0 -1
  227. package/dist/assets/workout-detail-page-DfUbYYw1.js +0 -2
@@ -740,7 +740,7 @@ export async function listFlashcards(userIds) {
740
740
  {
741
741
  entityTypes: ["flashcard"],
742
742
  userIds: coerceUserIds(userIds),
743
- limit: 500
743
+ limit: 200
744
744
  }
745
745
  ]
746
746
  });
@@ -1756,9 +1756,18 @@ export function getVitalsView(userIds) {
1756
1756
  const suffix = search.size > 0 ? `?${search.toString()}` : "";
1757
1757
  return request(`/api/v1/health/vitals${suffix}`);
1758
1758
  }
1759
- export function getWeightLossView(userIds) {
1759
+ export function getWeightLossView(userIds, options) {
1760
1760
  const search = new URLSearchParams();
1761
1761
  appendUserIds(search, coerceUserIds(userIds));
1762
+ if (options?.dateKey) {
1763
+ search.set("dateKey", options.dateKey);
1764
+ }
1765
+ if (options?.dayStartAt) {
1766
+ search.set("dayStartAt", options.dayStartAt);
1767
+ }
1768
+ if (options?.dayEndAt) {
1769
+ search.set("dayEndAt", options.dayEndAt);
1770
+ }
1762
1771
  const suffix = search.size > 0 ? `?${search.toString()}` : "";
1763
1772
  return request(`/api/v1/health/weight-loss${suffix}`);
1764
1773
  }
@@ -1771,6 +1780,15 @@ export function updateNutritionTarget(patch, userIds) {
1771
1780
  body: JSON.stringify(patch)
1772
1781
  });
1773
1782
  }
1783
+ export function updateNutritionDailyActiveCalories(patch, userIds) {
1784
+ const search = new URLSearchParams();
1785
+ appendUserIds(search, coerceUserIds(userIds));
1786
+ const suffix = search.size > 0 ? `?${search.toString()}` : "";
1787
+ return request(`/api/v1/health/weight-loss/daily-active-calories${suffix}`, {
1788
+ method: "PATCH",
1789
+ body: JSON.stringify(patch)
1790
+ });
1791
+ }
1774
1792
  export function searchNutritionFoods(input) {
1775
1793
  const search = new URLSearchParams();
1776
1794
  appendUserIds(search, coerceUserIds(input.userIds));
@@ -1821,9 +1839,10 @@ export function parseNutritionFoodLogWithChatGpt(input) {
1821
1839
  method: "POST",
1822
1840
  body: JSON.stringify({
1823
1841
  text: input.text,
1824
- imageDescription: input.imageDescription,
1825
- loggedAt: input.loggedAt,
1826
- mealLabel: input.mealLabel
1842
+ mealTime: input.mealTime,
1843
+ imageRefs: input.imageRefs,
1844
+ connectionId: input.connectionId,
1845
+ commitCandidate: input.commitCandidate
1827
1846
  })
1828
1847
  });
1829
1848
  }
@@ -31,6 +31,7 @@ const CUSTOM_THEME_STORAGE_KEYS = [
31
31
  "--secondary",
32
32
  "--tertiary",
33
33
  "--surface",
34
+ "--canvas",
34
35
  "--surface-low",
35
36
  "--surface-panel",
36
37
  "--surface-high",
@@ -41,6 +42,9 @@ const CUSTOM_THEME_STORAGE_KEYS = [
41
42
  "--card-gradient",
42
43
  "--card-shadow",
43
44
  "--card-shadow-hover",
45
+ "--ui-accent",
46
+ "--ui-ink",
47
+ "--ui-ink-muted",
44
48
  "--forge-body-ambient-primary",
45
49
  "--forge-body-ambient-secondary",
46
50
  "--forge-body-gradient-start",
@@ -271,6 +275,7 @@ export function buildForgeThemeVariables(theme) {
271
275
  "--secondary": theme.secondary,
272
276
  "--tertiary": theme.tertiary,
273
277
  "--surface": theme.canvas,
278
+ "--canvas": theme.canvas,
274
279
  "--surface-low": theme.panelLow,
275
280
  "--surface-panel": theme.panel,
276
281
  "--surface-high": theme.panelHigh,
@@ -281,6 +286,9 @@ export function buildForgeThemeVariables(theme) {
281
286
  "--card-gradient": `linear-gradient(180deg, ${alpha(cardTop, 0.96)}, ${alpha(theme.panelLow, 0.94)})`,
282
287
  "--card-shadow": `0 24px 60px ${alpha(theme.canvas, 0.3)}`,
283
288
  "--card-shadow-hover": `0 32px 80px ${alpha(theme.canvas, 0.38)}`,
289
+ "--ui-accent": theme.primary,
290
+ "--ui-ink": theme.ink,
291
+ "--ui-ink-muted": alpha(theme.ink, 0.58),
284
292
  "--forge-body-ambient-primary": alpha(theme.primary, 0.2),
285
293
  "--forge-body-ambient-secondary": alpha(theme.secondary, 0.14),
286
294
  "--forge-body-gradient-start": mixHex(theme.panel, theme.primary, 0.08),
@@ -2,7 +2,7 @@
2
2
  "id": "forge-openclaw-plugin",
3
3
  "name": "Forge",
4
4
  "description": "Curated OpenClaw adapter for the Forge collaboration API, UI entrypoint, and localhost auto-start runtime.",
5
- "version": "0.2.101",
5
+ "version": "0.2.103",
6
6
  "activation": {
7
7
  "onStartup": true,
8
8
  "onCapabilities": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "forge-openclaw-plugin",
3
- "version": "0.2.101",
3
+ "version": "0.2.103",
4
4
  "description": "Curated OpenClaw adapter for the Forge collaboration API, UI entrypoint, and localhost auto-start runtime.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -47,10 +47,10 @@
47
47
  "openclaw": "2026.5.4"
48
48
  },
49
49
  "dependencies": {
50
+ "@azure/msal-node": "^5.1.2",
50
51
  "@dnd-kit/core": "^6.3.1",
51
52
  "@dnd-kit/sortable": "^10.0.0",
52
53
  "@dnd-kit/utilities": "^3.2.2",
53
- "@azure/msal-node": "^5.1.2",
54
54
  "@fastify/cors": "^10.0.1",
55
55
  "@fastify/multipart": "^9.4.0",
56
56
  "@fontsource-variable/plus-jakarta-sans": "^5.2.8",
@@ -89,7 +89,7 @@
89
89
  "react-hook-form": "^7.57.0",
90
90
  "react-is": "^19.2.5",
91
91
  "react-redux": "^9.2.0",
92
- "react-router-dom": "^7.13.1",
92
+ "react-router-dom": "^7.16.0",
93
93
  "recharts": "^3.1.0",
94
94
  "sigma": "^3.0.2",
95
95
  "tailwind-merge": "^3.3.1",
@@ -0,0 +1,13 @@
1
+ CREATE TABLE IF NOT EXISTS nutrition_daily_energy_overrides (
2
+ id TEXT PRIMARY KEY,
3
+ user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
4
+ day_key TEXT NOT NULL,
5
+ active_calories_kcal REAL NOT NULL,
6
+ notes TEXT NOT NULL DEFAULT '',
7
+ created_at TEXT NOT NULL,
8
+ updated_at TEXT NOT NULL,
9
+ UNIQUE (user_id, day_key)
10
+ );
11
+
12
+ CREATE INDEX IF NOT EXISTS idx_nutrition_daily_energy_overrides_user_day
13
+ ON nutrition_daily_energy_overrides(user_id, day_key DESC);
@@ -802,6 +802,19 @@ When the user asks which Forge tools are available, list exactly these tools:
802
802
  `forge_get_sleep_overview`
803
803
  `forge_get_sports_overview`
804
804
  `forge_get_training_load_overview`
805
+ `forge_get_weight_loss_overview`
806
+ `forge_search_nutrition_foods`
807
+ `forge_search_foods`
808
+ `forge_lookup_nutrition_barcode`
809
+ `forge_log_food`
810
+ `forge_parse_food_log_with_chatgpt`
811
+ `forge_log_body_checkin`
812
+ `forge_log_appearance_checkin`
813
+ `forge_log_subjective_food_effect`
814
+ `forge_log_gut_checkin`
815
+ `forge_get_nutrition_patterns`
816
+ `forge_start_nutrition_experiment`
817
+ `forge_update_nutrition_experiment`
805
818
  `forge_update_sleep_session`
806
819
  `forge_update_workout_session`
807
820
  `forge_get_preferences_workspace`
@@ -408,7 +408,7 @@ still knowing the exact write/read family before it acts.
408
408
  user wants training-load trends, acute/chronic ratio, HR zone distribution,
409
409
  threshold exposure, VO2max/resting-HR context, or optimization targets before
410
410
  deciding whether a specific `workout_session` needs notes or links.
411
- - `weight_loss`: nutrition and body-composition health surface. Use
411
+ - `weight_loss`: health read model plus dedicated nutrition write workflow. Use
412
412
  `forge_get_weight_loss_overview` or `/api/v1/health/weight-loss` when the user
413
413
  wants calorie balance, food quality, protein/fiber targets, training fuel,
414
414
  body trend, aesthetic look, subjective energy, cravings, gut comfort,
@@ -1616,6 +1616,12 @@ Route note:
1616
1616
  overview. Do not invent generic batch entities for food logs or body check-ins
1617
1617
  when the dedicated tools exist.
1618
1618
 
1619
+ Ready to review when:
1620
+
1621
+ - the food, body, training-fuel, gut, craving, appearance, energy, or experiment
1622
+ question is clear enough to choose the overview, log, check-in, or experiment
1623
+ path
1624
+
1619
1625
  Preferred opening question:
1620
1626
 
1621
1627
  - "What food-body link are you trying to test or understand right now?"
@@ -1 +0,0 @@
1
- import{j as e,aC as x,c2 as k}from"./vendor-DHkYh85p.js";import{j as A,i as C,k as E}from"./state-B-4sS1xO.js";import{C as w,B as I,U as P,f,u as R,i as S,r as L,L as T,E as U,a as q,l as Q}from"./index-CF4J4R9L.js";import{P as _}from"./page-hero-DRy5b2MU.js";import{u as F,f as g,g as H,c as M}from"./table-WfAPUppN.js";import{g as p,a as v}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";const n=M(),y=[n.accessor("title",{header:"Event",cell:t=>{const s=p(t.row.original);return s?e.jsx(x,{to:s,className:"font-medium text-white transition hover:text-[var(--primary)]",children:t.getValue()}):e.jsx("div",{className:"font-medium text-white",children:t.getValue()})}}),n.accessor("source",{header:"Source",cell:t=>e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.16em] text-white/50",children:t.getValue()})}),n.display({id:"owner",header:"Owner",cell:t=>t.row.original.user?e.jsx(P,{user:t.row.original.user,compact:!0}):e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/32",children:"Unowned"})}),n.accessor("createdAt",{header:"When",cell:t=>e.jsx("div",{className:"text-sm text-white/55",children:f(t.getValue())})}),n.display({id:"actions",header:"Open",cell:t=>{const s=p(t.row.original);return s?e.jsx(x,{to:s,className:"inline-flex text-[11px] uppercase tracking-[0.16em] text-[var(--primary)] transition hover:text-white",children:"Open"}):e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/32",children:"Archive only"})}})];function V({rows:t,onRemove:s}){const l=s?[...y,n.display({id:"remove",header:"Correct",cell:i=>e.jsx(I,{variant:"ghost",className:"h-auto px-0 py-0 text-[11px] uppercase tracking-[0.16em] text-white/55",onClick:()=>{s(i.row.original.id)},children:"Remove log"})})]:y,o=F({columns:l,data:t,getCoreRowModel:H()});return e.jsx(w,{className:"overflow-hidden p-0",children:e.jsxs("table",{className:"w-full border-collapse",children:[e.jsx("thead",{children:o.getHeaderGroups().map(i=>e.jsx("tr",{className:"bg-white/[0.03]",children:i.headers.map(a=>e.jsx("th",{className:"px-5 py-4 text-left font-label text-[11px] uppercase tracking-[0.18em] text-white/40",children:a.isPlaceholder?null:g(a.column.columnDef.header,a.getContext())},a.id))},i.id))}),e.jsx("tbody",{children:o.getRowModel().rows.map(i=>e.jsx("tr",{className:"bg-white/[0.015] transition hover:bg-white/[0.035]",children:i.getVisibleCells().map(a=>e.jsx("td",{className:"px-5 py-4 align-top",children:g(a.column.columnDef.cell,a.getContext())},a.id))},i.id))})]})})}function Z(){var u;const t=R(),s=Array.isArray(t.selectedUserIds)?t.selectedUserIds:[],[l]=k(),o=A(),i=l.get("entityId")??void 0,a=l.get("entityType")??void 0,j=l.get("eventId"),d=C({queryKey:["activity-archive",a,i,...s],queryFn:()=>Q({limit:100,entityType:a,entityId:i,userIds:s})}),b=E({mutationFn:c=>L(c),onSuccess:async()=>{await Promise.all([o.invalidateQueries({queryKey:["activity-archive"]}),S(o),o.invalidateQueries({queryKey:["task-context"]}),o.invalidateQueries({queryKey:["project-board"]})])}}),m=((u=d.data)==null?void 0:u.activity)??[];if(d.isLoading)return e.jsx(T,{eyebrow:"Evidence archive",title:"Loading activity",description:"Pulling the visible audit trail, grouped evidence, and correction history."});if(d.isError)return e.jsx(U,{eyebrow:"Evidence archive",error:d.error,onRetry:()=>void d.refetch()});if(m.length===0)return e.jsx(q,{eyebrow:"Evidence archive",title:i?"No evidence matched this filter":"No activity recorded yet",description:i?"Forge could not find visible events for this specific entity yet. Try a broader archive view or create some work first.":"As you complete work, log runs, or make corrections, the audit trail will appear here."});const N=m.reduce((c,h)=>{const r=h.createdAt.slice(0,10);return c[r]=[...c[r]??[],h],c},{});return e.jsxs("div",{className:"grid gap-5",children:[e.jsx(_,{title:"Activity",description:i?"This filtered archive shows the evidence connected to the item you opened, so you can confirm what changed and when.":"Activity is your visible audit trail. Use it to inspect progress, confirm corrections, and trace work back to the goal, project, or task it came from.",badge:`${m.length} recent events`}),e.jsxs("section",{className:"grid gap-5 xl:grid-cols-[minmax(0,1.1fr)_minmax(0,0.9fr)]",children:[e.jsx(V,{rows:m,onRemove:async c=>{await b.mutateAsync(c)}}),e.jsx("div",{className:"grid gap-4",children:Object.entries(N).slice(0,6).map(([c,h])=>e.jsxs(w,{children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:c}),e.jsx("div",{className:"mt-4 grid gap-3",children:h.slice(0,3).map(r=>e.jsxs("div",{className:`rounded-[18px] p-4 ${j===r.id?"bg-[rgba(192,193,255,0.12)] shadow-[inset_0_0_0_1px_rgba(192,193,255,0.2)]":"bg-white/[0.04]"}`,children:[e.jsx("div",{className:"font-medium text-white",children:r.title}),e.jsx("div",{className:"mt-2 text-sm text-white/58",children:r.description}),e.jsx("div",{className:"mt-3 text-[11px] uppercase tracking-[0.16em] text-white/35",children:f(r.createdAt)}),p(r)&&v(r)?e.jsx(x,{to:p(r),className:"mt-3 inline-flex text-[11px] uppercase tracking-[0.16em] text-[var(--primary)]",children:v(r)}):null]},r.id))})]},c))})]})]})}export{Z as ActivityPage};
@@ -1 +0,0 @@
1
- import{r as m,j as i,cL as Q,cT as ee,bT as te,cU as ie,cV as ne,cW as se,cX as re,cY as ae,aC as le,b1 as oe}from"./vendor-DHkYh85p.js";import{u as de,a as ce,P as ue,D as he,c as fe,S as me,v as xe,d as pe,b as be,C as ge}from"./board-BkDRaMp6.js";import{i as ve,k as J}from"./state-B-4sS1xO.js";import{cU as je,cV as Ne,B as H,Z as W,cW as ye,C as we,cX as Se}from"./index-CF4J4R9L.js";const S={lg:1280,md:996,sm:768,xs:480},R={lg:12,md:10,sm:6,xs:4,xxs:2},We="forge.surface-layout.v3";function X(e){return`${We}.${e}`}function A(e,n,s){return Math.min(Math.max(e,n),s)}function Ce(e){return e>=S.lg?"lg":e>=S.md?"md":e>=S.sm?"sm":e>=S.xs?"xs":"xxs"}function Ee(e,n){const s=R[n];if(n==="lg")return A(e.defaultWidth,e.minWidth??1,Math.min(e.maxWidth??s,s));const r=Math.round(e.defaultWidth/R.lg*s);return A(Math.max(e.minWidth??1,r||(e.minWidth??1)),e.minWidth??1,Math.min(e.maxWidth??s,s))}function Me(e){return{hidden:e.defaultHidden??!1,fullWidth:e.defaultFullWidth??!1,titleVisible:e.defaultTitleVisible??!0,descriptionVisible:e.defaultDescriptionVisible??!0}}function T(e,n){const s=[...n.filter(r=>r.defaultPlacement==="top"),...n.filter(r=>r.defaultPlacement!=="top")];return{surfaceId:e,order:s.map(r=>r.id),widgets:Object.fromEntries(n.map(r=>[r.id,Me(r)])),updatedAt:new Date(0).toISOString()}}function V(e,n,s){const r=T(e,n),l=new Set(n.map(o=>o.id)),c=((s==null?void 0:s.order)??[]).filter(o=>l.has(o)),x=r.order.filter(o=>!c.includes(o)),u=Object.fromEntries(n.map(o=>{var N,v,f,b,g;const h=(N=s==null?void 0:s.widgets)==null?void 0:N[o.id];return[o.id,{...r.widgets[o.id],hidden:(h==null?void 0:h.hidden)??((v=r.widgets[o.id])==null?void 0:v.hidden)??!1,fullWidth:(h==null?void 0:h.fullWidth)??((f=r.widgets[o.id])==null?void 0:f.fullWidth)??!1,titleVisible:(h==null?void 0:h.titleVisible)??((b=r.widgets[o.id])==null?void 0:b.titleVisible)??!0,descriptionVisible:(h==null?void 0:h.descriptionVisible)??((g=r.widgets[o.id])==null?void 0:g.descriptionVisible)??!0}]}));return{surfaceId:e,order:[...c,...x],widgets:u,updatedAt:typeof(s==null?void 0:s.updatedAt)=="string"?s.updatedAt:r.updatedAt}}function Ve(e,n){const s=new Map(n.order.map((r,l)=>[r,l]));return[...e].sort((r,l)=>{const c=s.get(r.id)??Number.MAX_SAFE_INTEGER,x=s.get(l.id)??Number.MAX_SAFE_INTEGER;return c!==x?c-x:r.id.localeCompare(l.id)})}function ke(e,n,s){const r=e.indexOf(n);if(r===-1)return e;const l=A(s,0,e.length-1);if(r===l)return e;const c=[...e];return c.splice(r,1),c.splice(l,0,n),c}function k(e){if(typeof window>"u")return null;try{const n=window.localStorage.getItem(X(e));return n?JSON.parse(n):null}catch{return null}}function O(e){if(!(typeof window>"u"))try{window.localStorage.setItem(X(e.surfaceId),JSON.stringify(e))}catch{}}const Oe=500;function G(e,n){return e.surfaceId===n.surfaceId&&JSON.stringify(e.order)===JSON.stringify(n.order)&&JSON.stringify(e.widgets)===JSON.stringify(n.widgets)}function Re({definition:e,preferences:n,editing:s,width:r,children:l}){const c=r<=4;return e.surfaceChrome==="none"?i.jsx("div",{"data-surface-card":"true",className:W("min-w-0",s&&"rounded-[28px] ring-1 ring-white/8 ring-inset"),children:l}):i.jsxs(we,{"data-surface-card":"true",className:W("surface-grid-card flex min-w-0 flex-col gap-3 overflow-visible p-4 md:p-5",s&&"ring-1 ring-white/8"),children:[n.titleVisible||n.descriptionVisible&&e.description?i.jsxs("div",{className:"min-w-0",children:[n.titleVisible?i.jsx("div",{className:"truncate text-[0.72rem] font-semibold uppercase tracking-[0.16em] text-white/40",children:e.title}):null,n.descriptionVisible&&e.description&&!c?i.jsx("div",{className:"mt-1 text-[12px] leading-5 text-white/52",children:e.description}):null]}):null,i.jsx("div",{className:"min-h-0 flex-1",children:l})]})}function Ae({widget:e,preferences:n,index:s,total:r,onMove:l,onToggleHidden:c,onToggleFullWidth:x}){const u=be({id:e.id});return i.jsxs("div",{ref:u.setNodeRef,style:{transform:ge.Transform.toString(u.transform),transition:u.transition},className:"flex min-w-0 items-center gap-2 rounded-[18px] border border-white/8 bg-white/[0.04] px-3 py-2.5",children:[i.jsx("button",{type:"button",className:"inline-flex size-8 shrink-0 items-center justify-center rounded-full bg-white/[0.05] text-white/50 transition hover:bg-white/[0.08] hover:text-white","aria-label":`Drag ${e.title}`,...u.attributes,...u.listeners,children:i.jsx(te,{className:"size-4"})}),i.jsxs("div",{className:"min-w-0 flex-1",children:[i.jsx("div",{className:"truncate text-sm font-medium text-white",children:e.title}),e.description?i.jsx("div",{className:"truncate text-[12px] text-white/48",children:e.description}):null]}),i.jsxs("div",{className:"flex shrink-0 items-center gap-1",children:[i.jsx("button",{type:"button",className:"inline-flex size-8 items-center justify-center rounded-full bg-white/[0.05] text-white/60 transition hover:bg-white/[0.08] hover:text-white disabled:opacity-40",onClick:()=>l(s-1),disabled:s===0,"aria-label":`Move ${e.title} up`,children:i.jsx(ie,{className:"size-3.5"})}),i.jsx("button",{type:"button",className:"inline-flex size-8 items-center justify-center rounded-full bg-white/[0.05] text-white/60 transition hover:bg-white/[0.08] hover:text-white disabled:opacity-40",onClick:()=>l(s+1),disabled:s===r-1,"aria-label":`Move ${e.title} down`,children:i.jsx(ne,{className:"size-3.5"})}),i.jsxs("button",{type:"button",className:W("inline-flex h-8 items-center gap-2 rounded-full px-3 text-[12px] transition",n.fullWidth?"bg-[var(--primary)] text-slate-950":"bg-white/[0.05] text-white/72 hover:bg-white/[0.08] hover:text-white"),onClick:x,children:[n.fullWidth?i.jsx(se,{className:"size-3.5"}):i.jsx(re,{className:"size-3.5"}),n.fullWidth?"Normal width":"Full width"]}),e.removable!==!1?i.jsxs("button",{type:"button",className:"inline-flex h-8 items-center gap-2 rounded-full bg-white/[0.05] px-3 text-[12px] text-white/72 transition hover:bg-white/[0.08] hover:text-white",onClick:c,children:[i.jsx(ae,{className:"size-3.5"}),"Hide"]}):null]})]})}function Te({surfaceId:e,widgets:n,defaultEditing:s=!1,actions:r,normalizeLayout:l}){var U;const c=m.useMemo(()=>JSON.stringify(n.map(t=>({id:t.id,defaultWidth:t.defaultWidth,defaultHidden:t.defaultHidden,defaultPlacement:t.defaultPlacement,defaultFullWidth:t.defaultFullWidth,defaultTitleVisible:t.defaultTitleVisible,defaultDescriptionVisible:t.defaultDescriptionVisible}))),[n]),x=m.useMemo(()=>{const t=T(e,n);return l?l(t):t},[l,e,c]),u=t=>l?l(t):t,[o,h]=m.useState(s),[N,v]=m.useState(1280),[f,b]=m.useState(()=>u(V(e,n,k(e)??x))),g=m.useRef(null),P=m.useRef(!1),y=m.useRef(u(V(e,n,k(e)??x))),F=m.useRef(null),I=de(ce(ue,{activationConstraint:{distance:6}})),C=ve({queryKey:["forge-surface-layout",e],queryFn:()=>Se(e)}),z=(U=C==null?void 0:C.data)==null?void 0:U.layout,D=J({mutationFn:t=>je(e,{order:t.order,widgets:t.widgets})}),q=J({mutationFn:()=>Ne(e)});m.useEffect(()=>{const t=u(V(e,n,z??k(e)??x));b(a=>G(a,t)?a:t),O(t),y.current=t,P.current=!0},[x,z,l,e,c,n]),m.useEffect(()=>{const t=F.current;if(!t||typeof ResizeObserver>"u")return;const a=new ResizeObserver(d=>{var j;const p=((j=d[0])==null?void 0:j.contentRect.width)??t.clientWidth;v(Math.max(320,Math.round(p)))});return a.observe(t),v(Math.max(320,Math.round(t.clientWidth||1280))),()=>a.disconnect()},[]),m.useEffect(()=>{if(P.current&&!G(f,y.current))return O(f),g.current!==null&&window.clearTimeout(g.current),g.current=window.setTimeout(()=>{const t=f;D.mutateAsync(t).then(()=>{y.current=t})},Oe),()=>{g.current!==null&&window.clearTimeout(g.current)}},[f,D,e]);const L=Ce(N),E=R[L],$=m.useMemo(()=>Ve(n,f),[f,n]),w=$.filter(t=>{var a;return!((a=f.widgets[t.id])!=null&&a.hidden)}),_=$.filter(t=>{var a;return(a=f.widgets[t.id])==null?void 0:a.hidden});function M(t,a){b(d=>u({...d,widgets:{...d.widgets,[t]:{...d.widgets[t],...a}}}))}function K(t,a){b(d=>u({...d,order:ke(d.order,t,a)}))}function Y(t){const{active:a,over:d}=t;!d||a.id===d.id||b(p=>{const j=p.order.indexOf(String(a.id)),B=p.order.indexOf(String(d.id));return j===-1||B===-1?p:u({...p,order:pe(p.order,j,B)})})}function Z(){const t=u(T(e,n));b(t),O(t),y.current=t,q.mutateAsync()}return i.jsxs("div",{className:"grid gap-4",children:[o?i.jsx(he,{sensors:I,collisionDetection:fe,onDragEnd:Y,children:i.jsxs("div",{className:"grid gap-3 rounded-[24px] border border-white/8 bg-white/[0.03] p-4",children:[i.jsx("div",{className:"text-[12px] uppercase tracking-[0.16em] text-white/40",children:"Visible boxes"}),i.jsx(me,{items:w.map(t=>t.id),strategy:xe,children:i.jsx("div",{className:"grid gap-2",children:w.map((t,a)=>{const d=f.widgets[t.id]??{hidden:!1,fullWidth:!1,titleVisible:!0,descriptionVisible:!0};return i.jsx(Ae,{widget:t,preferences:d,index:a,total:w.length,onMove:p=>K(t.id,p),onToggleHidden:()=>M(t.id,{hidden:!0}),onToggleFullWidth:()=>M(t.id,{fullWidth:!d.fullWidth})},t.id)})})}),_.length>0?i.jsxs(i.Fragment,{children:[i.jsx("div",{className:"pt-2 text-[12px] uppercase tracking-[0.16em] text-white/40",children:"Hidden boxes"}),i.jsx("div",{className:"flex flex-wrap gap-2",children:_.map(t=>i.jsx("button",{type:"button",className:"rounded-full bg-white/[0.06] px-3 py-2 text-sm text-white/76 transition hover:bg-white/[0.1] hover:text-white",onClick:()=>M(t.id,{hidden:!1}),children:t.title},t.id))})]}):null]})}):null,i.jsxs("div",{ref:F,className:"relative",children:[i.jsx("div",{className:"pointer-events-none absolute top-3 right-3 z-20 flex max-w-[calc(100%-1.5rem)] flex-wrap items-center justify-end gap-1.5",children:i.jsxs("div",{className:"pointer-events-auto flex flex-wrap items-center justify-end gap-1.5",children:[r,o?i.jsxs(H,{type:"button",size:"sm",variant:"secondary",className:"h-8 rounded-full border-white/10 bg-[rgba(30,39,69,0.82)] px-2.5 text-[12px] text-white/78 backdrop-blur-xl hover:bg-[rgba(37,47,81,0.94)] hover:text-white",onClick:Z,children:[i.jsx(Q,{className:"size-3.5"}),i.jsx("span",{className:"hidden sm:inline",children:"Reset"})]}):null,i.jsxs(H,{type:"button",size:"sm",variant:o?"primary":"secondary",className:W("h-8 rounded-full px-2 text-[12px] backdrop-blur-xl [&>span]:gap-1.5",o?"bg-[var(--primary)] text-slate-950 hover:opacity-95":"border-white/10 bg-[rgba(30,39,69,0.82)] text-white/78 hover:bg-[rgba(37,47,81,0.94)] hover:text-white"),onClick:()=>h(t=>!t),children:[i.jsx(ee,{className:"size-3.5"}),i.jsx("span",{className:"hidden xl:inline",children:o?"Done":"Layout"})]})]})}),i.jsx("div",{className:"surface-flow-grid",style:{display:"grid",gap:"16px",gridTemplateColumns:`repeat(${E}, minmax(0, 1fr))`,alignItems:"start"},children:w.map(t=>{const a=f.widgets[t.id]??{hidden:!1,fullWidth:!1,titleVisible:!0,descriptionVisible:!0},d=a.fullWidth?E:Math.min(Ee(t,L),E);return i.jsx("div",{style:{gridColumn:`span ${d} / span ${d}`},children:i.jsx(Re,{definition:t,preferences:a,editing:o,width:d,children:i.jsx(ye,{boxId:t.workbenchBoxId??`surface:${e}:${t.id}`,surfaceId:e,children:t.render({compact:d<=4,width:d,editing:o,preferences:a})})})},t.id)})})]})]})}function Le({surfaceId:e,baseWidgets:n,actions:s,normalizeLayout:r}){return i.jsx(Te,{surfaceId:e,widgets:n,normalizeLayout:r,actions:i.jsxs(i.Fragment,{children:[s,i.jsxs(le,{to:`/workbench?surface=${encodeURIComponent(e)}`,className:"inline-flex h-8 items-center gap-1.5 rounded-full border border-white/10 bg-[rgba(32,40,70,0.78)] px-2.5 text-[12px] font-medium text-white/78 backdrop-blur-xl transition hover:border-white/16 hover:bg-[rgba(40,49,82,0.9)] hover:text-white",children:[i.jsx(oe,{className:"size-3.5"}),i.jsx("span",{className:"hidden sm:inline",children:"Workbench"})]})]})})}export{Le as A};
@@ -1 +0,0 @@
1
- import{j as a}from"./vendor-DHkYh85p.js";import{aq as d,Z as o}from"./index-CF4J4R9L.js";function c({eyebrow:n,title:e,description:r,titleHelp:t,tone:i="default",children:l,className:s}){const g={default:"bg-[linear-gradient(180deg,rgba(17,24,35,0.96),rgba(11,16,24,0.94))]",mint:"bg-[radial-gradient(circle_at_top_left,rgba(110,231,183,0.14),transparent_42%),linear-gradient(180deg,rgba(14,28,31,0.96),rgba(10,20,24,0.94))]",sky:"bg-[radial-gradient(circle_at_top_left,rgba(125,211,252,0.14),transparent_42%),linear-gradient(180deg,rgba(16,25,34,0.96),rgba(10,17,24,0.94))]",violet:"bg-[radial-gradient(circle_at_top_left,rgba(196,181,253,0.14),transparent_42%),linear-gradient(180deg,rgba(20,19,35,0.96),rgba(12,13,24,0.94))]",rose:"bg-[radial-gradient(circle_at_top_left,rgba(251,113,133,0.14),transparent_42%),linear-gradient(180deg,rgba(31,18,24,0.96),rgba(18,11,16,0.94))]",amber:"bg-[radial-gradient(circle_at_top_left,rgba(251,191,36,0.14),transparent_42%),linear-gradient(180deg,rgba(32,24,16,0.96),rgba(20,15,10,0.94))]"};return a.jsxs("section",{className:o("min-w-0 overflow-hidden rounded-[30px] border border-white/8 px-4 py-5 shadow-[0_24px_70px_rgba(4,8,18,0.28)] sm:px-5 lg:px-6",g[i],s),children:[a.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/42",children:n}),a.jsxs("div",{className:"mt-3 flex min-w-0 items-start gap-2",children:[a.jsx("h2",{className:"min-w-0 font-display text-[clamp(1.8rem,3.2vw,3rem)] leading-none text-white",children:e}),t?a.jsx(d,{content:t,label:`Explain ${e.toLowerCase()}`,className:"mt-1 shrink-0"}):null]}),r?a.jsx("p",{className:"mt-3 max-w-3xl text-sm leading-7 text-white/60",children:r}):null,a.jsx("div",{className:"mt-5 min-w-0",children:l})]})}export{c as A};
@@ -1 +0,0 @@
1
- import{r as p,j as e,aV as tt,aG as He,c3 as Lt,b5 as Rt,c2 as Kt,c4 as oe,c5 as Me,c6 as Ht,c7 as ze,c8 as Bt,c9 as Ut,bF as at,ca as $e,bc as Wt,cb as it,bg as Qt}from"./vendor-DHkYh85p.js";import{w as qt,j as Zt,i as rt,k as $}from"./state-B-4sS1xO.js";import{g as bt,b as Be,F as j,I as P,T as Gt,e as be,c as S,d as ee,h as ce,j as we,k as We,m as Yt,n as wt,Q as Qe,o as vt,p as ft,q as Xt,u as Jt,s as Vt,t as ea,v as ta,w as aa,x as ia,y as nt,z as ra,A as na,D as sa,G as la,H as ye,S as oa,E as da,C as Z,J as ca,K as ma,B as G,M as ua,i as ha,N as pa,O as ga}from"./index-CF4J4R9L.js";import{C as xa}from"./calendar-week-toolbar-BbPwYeN0.js";import{T as ya,a as ba}from"./timebox-planning-dialog-DB6FLqmI.js";import{W as Ue,m as st,a as wa,s as _e,b as Le,c as va,f as Re}from"./calendar-ui-Cy1XRwzV.js";import{P as fa}from"./page-hero-DRy5b2MU.js";import{F as ka}from"./floating-action-menu-Fs_ZiUMo.js";import{r as ja,b as Aa,g as lt}from"./calendar-display-preferences-Cid-2RnL.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";function ot(a,n){const d=new Date(a);return Number.isNaN(d.getTime())?n:d.toISOString()}function de(a){const n=new Date(a);return new Date(n.getTime()-n.getTimezoneOffset()*6e4).toISOString().slice(0,16)}function dt(a,n){var y,b,v,m,N;const d=new Date,w=new Date(d.getTime()+30*6e4),x=new Date(w.getTime()+60*6e4);return{title:(n==null?void 0:n.title)??(a==null?void 0:a.title)??"",description:(n==null?void 0:n.description)??(a==null?void 0:a.description)??"",location:(n==null?void 0:n.location)??(a==null?void 0:a.location)??"",placeAddress:((y=n==null?void 0:n.place)==null?void 0:y.address)??((b=a==null?void 0:a.place)==null?void 0:b.address)??"",placeTimezone:((v=n==null?void 0:n.place)==null?void 0:v.timezone)??((m=a==null?void 0:a.place)==null?void 0:m.timezone)??"",startAtLocal:a?de(a.startAt):n!=null&&n.startAt?de(n.startAt):de(w.toISOString()),endAtLocal:a?de(a.endAt):n!=null&&n.endAt?de(n.endAt):de(x.toISOString()),timezone:(n==null?void 0:n.timezone)??(a==null?void 0:a.timezone)??Intl.DateTimeFormat().resolvedOptions().timeZone??"UTC",availability:(n==null?void 0:n.availability)??(a==null?void 0:a.availability)??"busy",activityPresetKey:ft(a==null?void 0:a.actionProfile),customSustainRateApPerHour:vt(a==null?void 0:a.actionProfile),preferredCalendarId:n&&"preferredCalendarId"in n?n.preferredCalendarId:(a==null?void 0:a.calendarId)??void 0,categoriesText:((N=n==null?void 0:n.categories)==null?void 0:N.join(", "))??(a==null?void 0:a.categories.join(", "))??"",linkQuery:"",links:(n==null?void 0:n.links)??(a==null?void 0:a.links.map(F=>({entityType:F.entityType,entityId:F.entityId,relationshipType:F.relationshipType,label:`${F.entityType.replaceAll("_"," ")} · ${F.entityId}`})))??[]}}function Sa({open:a,onOpenChange:n,writableCalendars:d,linkOptions:w,event:x,seed:y,onSubmit:b,pending:v=!1}){const[m,N]=p.useState(()=>dt(x,y)),[F,c]=p.useState(null);p.useEffect(()=>{a&&(N(dt(x,y)),c(null))},[x,a,y]);const A=p.useMemo(()=>w.map(s=>{const g=bt(s.entityType);return{value:`${s.entityType}:${s.entityId}`,label:s.label,description:s.subtitle,searchText:`${s.label} ${s.subtitle} ${s.entityType}`,kind:g??void 0,menuBadge:g?e.jsx(Be,{kind:g,label:s.label,compact:!0,gradient:!1}):void 0,badge:g?e.jsx(Be,{kind:g,label:s.label,compact:!0}):void 0}}),[w]),u=p.useMemo(()=>[{id:"identity",eyebrow:"Event",title:x?"Refine the Forge event":"Create a Forge calendar event",description:"This event belongs to Forge first. If you choose a writable calendar, Forge will also project it to the connected provider.",render:(s,g)=>e.jsxs("div",{className:"grid gap-4",children:[e.jsx(j,{label:"Title",children:e.jsx(P,{value:s.title,onChange:o=>g({title:o.target.value}),placeholder:"Weekly research supervision"})}),e.jsx(j,{label:"Description",children:e.jsx(Gt,{value:s.description,onChange:o=>g({description:o.target.value}),placeholder:"Agenda, context, or outcomes you want this event to carry."})}),e.jsx(j,{label:"Location",children:e.jsx(P,{value:s.location,onChange:o=>g({location:o.target.value}),placeholder:"Clinic room 2 or Zoom"})}),e.jsx(j,{label:"Place address",children:e.jsx(P,{value:s.placeAddress,onChange:o=>g({placeAddress:o.target.value}),placeholder:"Bahnhofstrasse 10, Zurich"})}),e.jsx(j,{label:"Place timezone",children:e.jsx(P,{value:s.placeTimezone,onChange:o=>g({placeTimezone:o.target.value}),placeholder:"Europe/Zurich"})})]})},{id:"timing",eyebrow:"Timing",title:"Set the time and visibility",description:"Forge stores the real event window, timezone, and whether it should behave like a busy or free slot for scheduling rules.",render:(s,g)=>e.jsxs("div",{className:"grid gap-4",children:[(()=>{const o=new Date().toISOString(),_=new Date(Date.now()+3600*1e3).toISOString(),M=be({title:s.title,availability:s.availability,activityPresetKey:s.activityPresetKey,customSustainRateApPerHour:s.customSustainRateApPerHour,startAt:ot(s.startAtLocal,o),endAt:ot(s.endAtLocal,_)});return e.jsxs("div",{className:"rounded-[22px] border border-white/8 bg-white/[0.04] p-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(S,{className:"bg-white/[0.08] text-white/74",children:ee(M.rateApPerHour)}),e.jsx(S,{className:"bg-white/[0.08] text-white/74",children:ce(M.totalAp)})]}),e.jsx("div",{className:"mt-3 text-sm leading-6 text-white/58",children:"Availability controls whether the event blocks planning. The activity profile controls AP drain, and you can override it with a custom AP per hour."})]})})(),e.jsx(j,{label:"Activity profile",children:e.jsx(we,{value:s.activityPresetKey??(s.availability==="busy"?"meeting":"light_context"),columns:3,onChange:o=>g({activityPresetKey:o}),options:We().filter(o=>o.key!=="task_inherited").map(o=>({value:o.key,label:o.label,description:`${ee(o.defaultRateApPerHour)} · ${o.description}`}))})}),e.jsx(j,{label:"Custom AP per hour",children:e.jsx(P,{type:"number",min:0,step:.5,value:s.customSustainRateApPerHour??"",onChange:o=>g({customSustainRateApPerHour:o.target.value.trim()===""?null:Number(o.target.value)}),placeholder:"Leave empty to use the activity default"})}),e.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[e.jsx(j,{label:"Starts",children:e.jsx(P,{type:"datetime-local",value:s.startAtLocal,onChange:o=>g({startAtLocal:o.target.value})})}),e.jsx(j,{label:"Ends",children:e.jsx(P,{type:"datetime-local",value:s.endAtLocal,onChange:o=>g({endAtLocal:o.target.value})})})]}),e.jsx(j,{label:"Timezone",children:e.jsx(P,{value:s.timezone,onChange:o=>g({timezone:o.target.value}),placeholder:"Europe/Zurich"})}),e.jsx(j,{label:"Availability",children:e.jsx(we,{value:s.availability,onChange:o=>g({availability:o}),options:[{value:"busy",label:"Busy",description:"This event should block timebox recommendations and rule checks."},{value:"free",label:"Free",description:"This event stays visible in the calendar without blocking work."}]})})]})},{id:"links",eyebrow:"Meaning",title:"Connect the event to Forge entities",description:"Attach this event to strategies, goals, projects, tasks, or habits so the calendar carries multi-user operating context instead of staying isolated.",render:(s,g)=>e.jsx("div",{className:"grid gap-4",children:e.jsx(j,{label:"Search Forge entities",description:"Search across human and bot-owned entities; the linked records use the same icon, color, and owner system as the rest of Forge.",children:e.jsx(Yt,{options:A,selectedValues:s.links.map(o=>`${o.entityType}:${o.entityId}`),onChange:o=>{g({links:o.map(_=>{const[M,...L]=_.split(":"),R=L.join(":"),te=w.find(me=>me.entityType===M&&me.entityId===R);return te?{entityType:te.entityType,entityId:te.entityId,relationshipType:"context",label:te.label}:null}).filter(_=>_!==null)})},placeholder:"Search strategies, goals, projects, tasks, habits, human, or bot owners",emptyMessage:"No matching Forge entities found."})})})},{id:"projection",eyebrow:"Projection",title:"Choose where this event should live remotely",description:"You can keep the event local to Forge, or choose a writable connected calendar so Forge also keeps a synced remote copy.",render:(s,g)=>e.jsxs("div",{className:"grid gap-4",children:[e.jsxs("div",{className:"grid gap-3",children:[d.length>0?e.jsxs("button",{type:"button",onClick:()=>g({preferredCalendarId:void 0}),className:`rounded-[22px] border px-4 py-4 text-left transition ${s.preferredCalendarId===void 0?"border-[rgba(125,211,252,0.28)] bg-[rgba(125,211,252,0.14)] text-white":"border-white/8 bg-white/[0.04] text-white/72 hover:bg-white/[0.07]"}`,children:[e.jsxs("div",{className:"flex items-center gap-2 font-medium",children:[e.jsx(tt,{className:"size-4"}),"Default synced calendar"]}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-white/55",children:"Let Forge use the default writable connected calendar automatically."})]}):null,e.jsxs("button",{type:"button",onClick:()=>g({preferredCalendarId:null}),className:`rounded-[22px] border px-4 py-4 text-left transition ${s.preferredCalendarId===null?"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.07]"}`,children:[e.jsxs("div",{className:"flex items-center gap-2 font-medium",children:[e.jsx(He,{className:"size-4"}),"Forge only"]}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-white/55",children:"Keep the event in Forge without creating a remote provider copy yet."})]}),d.map(o=>e.jsxs("button",{type:"button",onClick:()=>g({preferredCalendarId:o.id}),className:`rounded-[22px] border px-4 py-4 text-left transition ${s.preferredCalendarId===o.id?"border-[rgba(125,211,252,0.28)] bg-[rgba(125,211,252,0.14)] text-white":"border-white/8 bg-white/[0.04] text-white/72 hover:bg-white/[0.07]"}`,children:[e.jsxs("div",{className:"flex items-center gap-2 font-medium",children:[e.jsx(tt,{className:"size-4"}),wt(o)]}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-white/55",children:o.description||`${o.timezone} · writable`})]},o.id))]}),e.jsxs("div",{className:"grid gap-2 rounded-[22px] border border-white/8 bg-white/[0.04] p-4 text-sm text-white/66",children:[e.jsxs("div",{className:"flex items-center gap-2 font-medium text-white",children:[e.jsx(Lt,{className:"size-4 text-[var(--primary)]"}),"Categories and filtering"]}),e.jsx(P,{value:s.categoriesText,onChange:o=>g({categoriesText:o.target.value}),placeholder:"meeting, clinic, research"})]})]})}],[x,w,A,d]);return e.jsx(Qe,{open:a,onOpenChange:n,eyebrow:x?"Edit event":"New event",title:x?"Edit calendar event":"Create calendar event",description:"Forge-owned events can stay local or publish to a connected provider calendar.",value:m,onChange:N,draftPersistenceKey:x?`calendar.event.${x.id}`:"calendar.event.new",steps:u,onSubmit:async()=>{if(!m.title.trim()){c("Add an event title before saving.");return}if(!m.startAtLocal||!m.endAtLocal){c("Set both the start and end time before saving.");return}if(new Date(m.endAtLocal).getTime()<=new Date(m.startAtLocal).getTime()){c("The event end time must be after the start time.");return}c(null),await b({title:m.title.trim(),description:m.description.trim(),location:m.location.trim(),place:{label:m.location.trim(),address:m.placeAddress.trim(),timezone:m.placeTimezone.trim(),latitude:null,longitude:null,source:m.placeAddress.trim()?"manual":"",externalPlaceId:""},startAt:new Date(m.startAtLocal).toISOString(),endAt:new Date(m.endAtLocal).toISOString(),timezone:m.timezone.trim()||"UTC",availability:m.availability,activityPresetKey:m.activityPresetKey,customSustainRateApPerHour:m.customSustainRateApPerHour,categories:m.categoriesText.split(",").map(s=>s.trim()).filter(Boolean),links:m.links.map(s=>({entityType:s.entityType,entityId:s.entityId,relationshipType:s.relationshipType})),...m.preferredCalendarId!==void 0?{preferredCalendarId:m.preferredCalendarId}:{}})},submitLabel:x?"Save event":"Create event",pending:v,pendingLabel:x?"Saving":"Creating",error:F})}function Na({open:a,onOpenChange:n,initialTitle:d,pending:w=!1,onSubmit:x}){const[y,b]=p.useState(d),[v,m]=p.useState(null);return p.useEffect(()=>{a&&(b(d),m(null))},[d,a]),e.jsx(Qe,{open:a,onOpenChange:n,eyebrow:"Calendar",title:"Quick rename",description:"Rename the event without reopening the full event guide.",value:{title:y},onChange:N=>b(N.title),draftPersistenceKey:`calendar.quick-rename.${d}`,steps:[{id:"rename",eyebrow:"Rename",title:"Update the event title",description:"Keep the rename fast and direct. Everything else on the event stays unchanged.",render:(N,F)=>e.jsx(j,{label:"Event title",children:e.jsx(P,{value:N.title,onChange:c=>F({title:c.target.value}),placeholder:"Weekly research supervision"})})}],submitLabel:"Save title",pending:w,pendingLabel:"Saving",error:v,onSubmit:async()=>{const N=y.trim();if(!N){m("Add a title before saving.");return}m(null),await x(N),n(!1)}})}function ct(a){if(a)return{title:a.title,kind:a.kind,color:a.color,timezone:a.timezone,weekDays:a.weekDays,startMinute:a.startMinute,endMinute:a.endMinute,startsOn:a.startsOn,endsOn:a.endsOn,blockingState:a.blockingState,activityPresetKey:ft(a.actionProfile),customSustainRateApPerHour:vt(a.actionProfile)};const n=Ue[0];return{title:n.title,kind:n.kind,color:n.color,timezone:typeof Intl<"u"&&Intl.DateTimeFormat().resolvedOptions().timeZone||"UTC",weekDays:[1,2,3,4,5],startMinute:n.startMinute,endMinute:n.endMinute,startsOn:null,endsOn:null,blockingState:n.blockingState,activityPresetKey:n.kind==="main_activity"?"deep_work":n.kind==="secondary_activity"?"admin":n.kind==="holiday"?"holiday_leisure":n.kind==="rest"?"recovery_break":"maintenance",customSustainRateApPerHour:null}}function mt(a){return a??""}function Ke({draft:a}){const n=Xt({kind:a.kind,startMinute:a.startMinute,endMinute:a.endMinute,activityPresetKey:a.activityPresetKey,customSustainRateApPerHour:a.customSustainRateApPerHour}),d=a.endMinute>a.startMinute?a.endMinute-a.startMinute:1440-a.startMinute+a.endMinute;return e.jsxs("div",{className:"rounded-[22px] border border-white/8 bg-white/[0.04] p-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(S,{className:"bg-white/[0.08] text-white/74",children:ee(n.rateApPerHour)}),e.jsxs(S,{className:"bg-white/[0.08] text-white/74",children:[ce(n.totalAp)," / block"]}),e.jsxs(S,{className:"bg-white/[0.08] text-white/74",children:[Math.round(d/60),"h ",d%60,"m"]})]}),e.jsx("div",{className:"mt-3 text-sm leading-6 text-white/58",children:"This is the default Life Force container drain for each occurrence of the block when no richer task run or timebox already covers that window."})]})}function Ta({open:a,onOpenChange:n,onSubmit:d,pending:w=!1,template:x=null}){const[y,b]=p.useState(()=>ct(x)),[v,m]=p.useState(null),N=x!==null;p.useEffect(()=>{a&&(m(null),b(ct(x)))},[a,x]);const F=p.useMemo(()=>[{id:"preset",eyebrow:"Preset",title:"Start from a recurring block that already matches the rhythm",description:"Use a preset to seed the schedule, then tune the dates and recurrence in the next step.",render:(c,A)=>e.jsxs("div",{className:"grid gap-4",children:[e.jsx(Ke,{draft:c}),e.jsx(j,{label:"Activity profile",children:e.jsx(we,{value:c.activityPresetKey??"maintenance",columns:3,onChange:u=>A({activityPresetKey:u,customSustainRateApPerHour:c.customSustainRateApPerHour}),options:We().filter(u=>u.key!=="task_inherited").map(u=>({value:u.key,label:u.label,description:`${ee(u.defaultRateApPerHour)} · ${u.description}`}))})}),e.jsx(j,{label:"Custom AP per hour",children:e.jsx(P,{type:"number",min:0,step:.5,value:c.customSustainRateApPerHour??"",onChange:u=>A({customSustainRateApPerHour:u.target.value.trim()===""?null:Number(u.target.value)}),placeholder:"Leave empty to use the activity default"})}),e.jsx(j,{label:"Block type",children:e.jsx(we,{value:c.kind,columns:3,onChange:u=>{const s=Ue.find(g=>g.kind===u);if(s){const g=s.kind==="holiday"?[0,1,2,3,4,5,6]:[1,2,3,4,5];A({kind:s.kind,title:s.title,color:s.color,weekDays:g,startMinute:s.startMinute,endMinute:s.endMinute,blockingState:s.blockingState,activityPresetKey:s.kind==="main_activity"?"deep_work":s.kind==="secondary_activity"?"admin":s.kind==="holiday"?"holiday_leisure":s.kind==="rest"?"recovery_break":"maintenance",customSustainRateApPerHour:null});return}A({kind:"custom",title:"Custom block",color:"#7dd3fc",activityPresetKey:"maintenance",customSustainRateApPerHour:null})},options:[...Ue.map(u=>({value:u.kind,label:u.title,description:`${st(u.startMinute)}-${st(u.endMinute)}`})),{value:"custom",label:"Custom",description:"Build a different recurring window."}]})})]})},{id:"shape",eyebrow:"Schedule",title:"Define when this recurring block should exist",description:"Weekdays and times describe the recurring pattern. Optional start and end dates bound when the template is active.",render:(c,A)=>e.jsxs("div",{className:"grid gap-4",children:[e.jsx(Ke,{draft:c}),e.jsx(j,{label:"Block title",children:e.jsx(P,{value:c.title,onChange:u=>A({title:u.target.value}),placeholder:"Main Activity"})}),e.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[e.jsx(j,{label:"Start minute",children:e.jsx(P,{type:"number",min:0,max:1440,step:15,value:c.startMinute,onChange:u=>A({startMinute:Number(u.target.value)||0})})}),e.jsx(j,{label:"End minute",children:e.jsx(P,{type:"number",min:0,max:1440,step:15,value:c.endMinute,onChange:u=>A({endMinute:Number(u.target.value)||0})})})]}),e.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[e.jsx(j,{label:"Start date",children:e.jsx(P,{type:"date",value:mt(c.startsOn),onChange:u=>A({startsOn:u.target.value.trim()||null})})}),e.jsx(j,{label:"End date",children:e.jsx(P,{type:"date",value:mt(c.endsOn),onChange:u=>A({endsOn:u.target.value.trim()||null})})})]}),e.jsx("div",{className:"text-sm leading-6 text-white/54",children:"Leave the end date empty to keep repeating indefinitely. Holiday blocks work well with all seven weekdays and `0-1440`, and they still carry AP load because leisure and holiday time are real activities."}),e.jsx(j,{label:"Weekdays",children:e.jsx("div",{className:"flex flex-wrap gap-2",children:wa.map((u,s)=>{const g=c.weekDays.includes(s);return e.jsx("button",{type:"button",onClick:()=>A({weekDays:g?c.weekDays.filter(o=>o!==s):[...c.weekDays,s].sort((o,_)=>o-_)}),className:`rounded-full px-3 py-2 text-sm transition ${g?"bg-[var(--primary)]/18 text-[var(--primary)] shadow-[inset_0_0_0_1px_rgba(192,193,255,0.24)]":"bg-white/[0.05] text-white/62 hover:bg-white/[0.08]"}`,children:u},u)})})})]})},{id:"policy",eyebrow:"Policy",title:"Tell Forge whether this block allows or blocks work",description:"Use blocked mode for time that should normally stop optional work. Use allowed mode for protected focus windows.",render:(c,A)=>e.jsxs("div",{className:"grid gap-4",children:[e.jsx(Ke,{draft:c}),e.jsx(j,{label:"Work effect",children:e.jsx(we,{value:c.blockingState,onChange:u=>A({blockingState:u}),options:[{value:"blocked",label:"Blocks work",description:"Starting blocked tasks should require an explicit override."},{value:"allowed",label:"Allows work",description:"Use this for protected windows where the right tasks should fit."}]})}),e.jsx(j,{label:"Color",children:e.jsxs("div",{className:"flex items-center gap-3 rounded-[22px] border border-white/8 bg-white/6 px-4 py-3",children:[e.jsx("input",{className:"h-10 w-12 rounded-lg border border-white/10 bg-transparent",type:"color",value:c.color,onChange:u=>A({color:u.target.value})}),e.jsx(P,{className:"border-none bg-transparent px-0 py-0",value:c.color,onChange:u=>A({color:u.target.value})})]})})]})}],[]);return e.jsx(Qe,{open:a,onOpenChange:n,eyebrow:"Calendar",title:N?"Edit work block":"Create a work block",description:N?"Adjust the recurring pattern, date bounds, or work policy for this block.":"Build recurring half-day, holiday, or custom blocks so Forge can understand when work should be protected or blocked.",value:y,onChange:b,draftPersistenceKey:x?`calendar.work-block.${x.id}`:"calendar.work-block.new",steps:F,submitLabel:N?"Save changes":"Save work block",pending:w,pendingLabel:N?"Saving changes":"Saving",error:v,onSubmit:async()=>{if(!y.title.trim()){m("Give the block a title so it stays readable in the calendar.");return}if(y.weekDays.length===0){m("Select at least one weekday for the recurring block.");return}if(y.endMinute<=y.startMinute){m("The end minute needs to be later than the start minute.");return}if(y.startsOn&&y.endsOn&&y.endsOn<y.startsOn){m("The end date needs to be on or after the start date.");return}try{m(null),await d({...y,title:y.title.trim()}),n(!1)}catch(c){m(c instanceof Error?c.message:"Forge could not save this work block.")}}})}const Ne=qt(a=>({entry:null,setEntry:n=>a({entry:n}),clear:()=>a({entry:null}),completePaste:()=>a(n=>{var d;return{entry:((d=n.entry)==null?void 0:d.mode)==="cut"?null:n.entry}})}));function Ca(a){const n=new Date(a);n.setUTCHours(9,0,0,0);const d=new Date(n.getTime()+3600*1e3);return{startAt:n.toISOString(),endAt:d.toISOString(),timezone:Intl.DateTimeFormat().resolvedOptions().timeZone??"UTC",availability:"busy"}}function ut(a){var b;const n=Math.max(60,Math.floor((Date.parse(a.endsAt)-Date.parse(a.startsAt))/1e3)),d=((b=We().find(v=>v.key===a.activityPresetKey))==null?void 0:b.defaultRateApPerHour)??100/24,w=a.customSustainRateApPerHour??d,x=Number((n/3600*w).toFixed(2)),y=new Date().toISOString();return{id:`preview_${a.entityType}_${a.entityId}`,profileKey:`${String(a.entityType)}_${a.entityId}`,title:a.title,entityType:a.entityType,mode:"container",startupAp:0,totalCostAp:x,expectedDurationSeconds:n,sustainRateApPerHour:w,demandWeights:{activation:.1,focus:.35,vigor:.1,composure:.15,flow:.3},doubleCountPolicy:"container_only",sourceMethod:a.customSustainRateApPerHour!==null&&a.customSustainRateApPerHour!==void 0?"manual":a.activityPresetKey?"seeded":"inferred",costBand:w>=10?"standard":"light",recoveryEffect:0,metadata:{activityPresetKey:a.activityPresetKey??null,customSustainRateApPerHour:a.customSustainRateApPerHour??null},createdAt:y,updatedAt:y}}function ht(a){const n=typeof a.location=="string"?a.location:"",d=a.place??{label:n,address:"",timezone:"",latitude:null,longitude:null,source:"",externalPlaceId:""};return{...a,place:{label:d.label||n,address:d.address??"",timezone:d.timezone??"",latitude:d.latitude??null,longitude:d.longitude??null,source:d.source??"",externalPlaceId:d.externalPlaceId??""}}}function pt(a,n){const d=new Date(a.startAt),x=new Date(a.endAt).getTime()-d.getTime(),y=new Date(n);y.setUTCHours(d.getUTCHours(),d.getUTCMinutes(),0,0);const b=new Date(y.getTime()+x);return{startAt:y.toISOString(),endAt:b.toISOString()}}function gt(a){return{type:"calendar_event",eventId:a.id,title:a.title,description:a.description,location:a.location,startAt:a.startAt,endAt:a.endAt,timezone:a.timezone,availability:a.availability,preferredCalendarId:a.calendarId,categories:a.categories,links:a.links.map(n=>({entityType:n.entityType,entityId:n.entityId,relationshipType:n.relationshipType}))}}function Ia(a){switch(a){case"apple":return"Apple";case"google":return"Google";case"caldav":return"CalDAV";case"native":return"Forge";default:return"Derived"}}function Pa(a,n){var d;if(a.calendarId){const w=(d=n.get(a.calendarId))==null?void 0:d.trim();if(w)return w}return a.originType==="native"?"Forge only":Ia(a.originType)}function xt(a){switch(a){case"main_activity":return"Main activity";case"secondary_activity":return"Secondary activity";case"third_activity":return"Third activity";case"rest":return"Rest";case"holiday":return"Holiday";default:return"Custom"}}function yt(a){return a.startsOn&&a.endsOn?`${a.startsOn} to ${a.endsOn}`:a.startsOn?`From ${a.startsOn}`:a.endsOn?`Until ${a.endsOn}`:"Repeats with no end date"}function Qa(){var Ye,Xe,Je,Ve,et;const a=Rt(),[n,d]=Kt(),w=Jt(),x=Array.isArray(w.selectedUserIds)?w.selectedUserIds:[],y=Vt(x),b=Zt(),v=Ne(t=>t.entry),m=Ne(t=>t.setEntry),N=Ne(t=>t.clear),F=Ne(t=>t.completePaste),[c,A]=p.useState(()=>_e()),[u,s]=p.useState(null),[g,o]=p.useState(null),[_,M]=p.useState(!1),[L,R]=p.useState(null),[te,me]=p.useState(!1),[Te,ae]=p.useState(!1),[Y,ue]=p.useState(null),[kt,ie]=p.useState(!1),[Ce,re]=p.useState(null),[ne,Ie]=p.useState(null),he=p.useMemo(()=>ja(),[]),[jt,se]=p.useState(null),[k,pe]=p.useState(null),[Pe,K]=p.useState(null),ve=n.get("timeboxId"),H=p.useMemo(()=>{const t=c.toISOString(),r=Le(c,7).toISOString();return{from:t,to:r}},[c]),X=rt({queryKey:["forge-calendar-overview",H.from,H.to,...x],queryFn:()=>pa({...H,userIds:x})}),B=rt({queryKey:["forge-life-force",...x],queryFn:()=>ga(x)}),z=["forge-calendar-overview",H.from,H.to,...x],fe=t=>{if(t.deletedAt)return!1;const r=new Date(t.startAt).getTime();return r>=new Date(H.from).getTime()&&r<new Date(H.to).getTime()},ge=t=>{b.setQueryData(z,r=>r&&t(r))},E=async()=>{await Promise.all([b.invalidateQueries({queryKey:["forge-calendar-overview"]}),ha(b),b.invalidateQueries({queryKey:["task-context"]}),b.invalidateQueries({queryKey:["project-board"]})])},qe=$({mutationFn:t=>ea({...t,userId:t.userId??y}),onSuccess:E}),Ze=$({mutationFn:({templateId:t,patch:r})=>ta(t,r),onSuccess:E}),De=$({mutationFn:aa,onSuccess:E}),At=$({mutationFn:t=>ia({...t,userId:y}),onSuccess:E}),St=$({mutationFn:({timeboxId:t,startsAt:r,endsAt:l})=>nt(t,{startsAt:r,endsAt:l}),onSuccess:E}),Nt=$({mutationFn:({timeboxId:t,patch:r})=>nt(t,r),onSuccess:E}),Tt=$({mutationFn:ra,onSuccess:async()=>{ue(null),ae(!1),await E()}}),ke=$({mutationFn:t=>na({...t,userId:t.userId??y}),onMutate:async t=>{var h,C,U,W,le,V,D;K({tone:"saving",message:"Saving event changes in the background…"}),await b.cancelQueries({queryKey:z});const r=b.getQueryData(z),l=(r==null?void 0:r.calendar.calendars.find(I=>I.canWrite&&I.selectedForSync))??(r==null?void 0:r.calendar.calendars.find(I=>I.canWrite))??null,T=new Date().toISOString(),O=`calendar_event_optimistic_${Date.now()}`,i={id:O,connectionId:(l==null?void 0:l.connectionId)??null,calendarId:t.preferredCalendarId===void 0?(l==null?void 0:l.id)??null:t.preferredCalendarId,remoteId:null,ownership:"forge",originType:"native",status:"confirmed",title:t.title,description:t.description??"",location:t.location??"",place:{label:((h=t.place)==null?void 0:h.label)??t.location??"",address:((C=t.place)==null?void 0:C.address)??"",timezone:((U=t.place)==null?void 0:U.timezone)??t.timezone??Intl.DateTimeFormat().resolvedOptions().timeZone??"UTC",latitude:((W=t.place)==null?void 0:W.latitude)??null,longitude:((le=t.place)==null?void 0:le.longitude)??null,source:((V=t.place)==null?void 0:V.source)??"forge",externalPlaceId:((D=t.place)==null?void 0:D.externalPlaceId)??""},startAt:t.startAt,endAt:t.endAt,timezone:t.timezone??Intl.DateTimeFormat().resolvedOptions().timeZone??"UTC",isAllDay:t.isAllDay??!1,availability:t.availability??"busy",eventType:t.eventType??"general",categories:t.categories??[],sourceMappings:[],links:(t.links??[]).map((I,Q)=>({id:`calendar_event_link_optimistic_${Date.now()}_${Q}`,entityType:I.entityType,entityId:I.entityId,relationshipType:I.relationshipType??"context",createdAt:T,updatedAt:T})),actionProfile:ut({entityType:"calendar_event",entityId:O,title:t.title,startsAt:t.startAt,endsAt:t.endAt,activityPresetKey:t.activityPresetKey??null,customSustainRateApPerHour:t.customSustainRateApPerHour??null}),remoteUpdatedAt:null,deletedAt:null,createdAt:T,updatedAt:T};return r&&fe(i)&&ge(I=>({...I,calendar:{...I.calendar,events:[i,...I.calendar.events]}})),{previous:r,optimisticEventId:i.id}},onError:(t,r,l)=>{l!=null&&l.previous&&b.setQueryData(z,l.previous),K({tone:"error",message:t instanceof Error?t.message:"Forge could not sync that event change."})},onSuccess:({event:t},r,l)=>{K(null),ge(T=>({...T,calendar:{...T.calendar,events:(fe(t)?[t,...T.calendar.events.filter(O=>O.id!==(l==null?void 0:l.optimisticEventId))]:T.calendar.events.filter(O=>O.id!==(l==null?void 0:l.optimisticEventId))).filter((O,i,h)=>h.findIndex(C=>C.id===O.id)===i)}}))},onSettled:E}),J=$({mutationFn:({eventId:t,patch:r})=>sa(t,r),onMutate:async({eventId:t,patch:r})=>{K({tone:"saving",message:"Saving event changes in the background…"}),await b.cancelQueries({queryKey:z});const l=b.getQueryData(z);return l&&ge(T=>{var C,U,W,le,V;const O=T.calendar.events.find(D=>D.id===t);if(!O)return T;const i=ht(O),h={...i,...r,place:r.place?{...i.place,...r.place}:i.place,calendarId:r.preferredCalendarId===void 0?i.calendarId:r.preferredCalendarId,links:((C=r.links)==null?void 0:C.map((D,I)=>{var Q,Se;return{id:((Q=i.links[I])==null?void 0:Q.id)??`calendar_event_link_optimistic_${Date.now()}_${I}`,entityType:D.entityType,entityId:D.entityId,relationshipType:D.relationshipType??"context",createdAt:((Se=i.links[I])==null?void 0:Se.createdAt)??i.createdAt,updatedAt:new Date().toISOString()}}))??i.links,actionProfile:ut({entityType:"calendar_event",entityId:t,title:r.title??i.title,startsAt:r.startAt??i.startAt,endsAt:r.endAt??i.endAt,activityPresetKey:r.activityPresetKey===void 0?(W=(U=i.actionProfile)==null?void 0:U.metadata)==null?void 0:W.activityPresetKey:r.activityPresetKey,customSustainRateApPerHour:r.customSustainRateApPerHour===void 0?typeof((V=(le=i.actionProfile)==null?void 0:le.metadata)==null?void 0:V.customSustainRateApPerHour)=="number"?i.actionProfile.metadata.customSustainRateApPerHour:null:r.customSustainRateApPerHour}),updatedAt:new Date().toISOString()};return{...T,calendar:{...T.calendar,events:T.calendar.events.map(D=>D.id===t?h:D).filter(fe)}}}),{previous:l}},onError:(t,r,l)=>{l!=null&&l.previous&&b.setQueryData(z,l.previous),K({tone:"error",message:t instanceof Error?t.message:"Forge could not sync that event change."})},onSuccess:({event:t})=>{K(null),ge(r=>({...r,calendar:{...r.calendar,events:r.calendar.events.map(l=>l.id===t.id?t:l).filter(fe)}}))},onSettled:E}),Oe=$({mutationFn:la,onMutate:async t=>{K({tone:"saving",message:"Removing the event in the background…"}),await b.cancelQueries({queryKey:z});const r=b.getQueryData(z);return r&&ge(l=>({...l,calendar:{...l.calendar,events:l.calendar.events.filter(T=>T.id!==t)}})),{previous:r}},onError:(t,r,l)=>{l!=null&&l.previous&&b.setQueryData(z,l.previous),K({tone:"error",message:t instanceof Error?t.message:"Forge could not delete that event."})},onSuccess:()=>{K(null)},onSettled:E}),je=(Ye=X.data)==null?void 0:Ye.calendar,Ae=p.useMemo(()=>va(c),[c]),f=p.useMemo(()=>je?{...je,events:je.events.map(ht)}:{generatedAt:"",providers:[],connections:[],calendars:[],events:[],workBlockTemplates:[],workBlockInstances:[],timeboxes:[]},[je]),Ct=p.useMemo(()=>new Map(f.calendars.map(t=>[t.id,wt(t)])),[f.calendars]),Fe=p.useMemo(()=>Aa(f.calendars,he.calendarColors),[he.calendarColors,f.calendars]),It=ke.isPending||J.isPending||Oe.isPending,Pt=f.timeboxes.filter(t=>t.status==="planned"),Dt=f.calendars.filter(t=>t.canWrite),xe=(t,r)=>r?`${t} · ${r}`:t,Ee=[...w.snapshot.goals.map(t=>({entityType:"goal",entityId:t.id,label:t.title,subtitle:xe("Goal",ye(t.user))})),...w.snapshot.projects.map(t=>({entityType:"project",entityId:t.id,label:t.title,subtitle:xe("Project",ye(t.user))})),...w.snapshot.tasks.map(t=>({entityType:"task",entityId:t.id,label:t.title,subtitle:xe("Task",ye(t.user))})),...w.snapshot.strategies.map(t=>({entityType:"strategy",entityId:t.id,label:t.title,subtitle:xe("Strategy",ye(t.user))})),...w.snapshot.habits.map(t=>({entityType:"habit",entityId:t.id,label:t.title,subtitle:xe("Habit",ye(t.user))}))],Ot=p.useMemo(()=>new Map(Ee.map(t=>[`${t.entityType}:${t.entityId}`,t.label])),[Ee]),Ft=f.connections.length===0?"No providers connected":`${f.connections.filter(t=>t.status==="connected").length}/${f.connections.length} healthy`,q=(v==null?void 0:v.items.filter(t=>t.type==="calendar_event"))??[];p.useEffect(()=>{if(!ve)return;const t=f.timeboxes.find(l=>l.id===ve);if(!t)return;const r=_e(new Date(t.startsAt));if(r.getTime()!==c.getTime()){A(r);return}((Y==null?void 0:Y.id)!==t.id||!Te)&&(ue(t),ae(!0))},[ve,f.timeboxes,Y==null?void 0:Y.id,Te,c]);const Ge=()=>{if(!ve)return;const t=new URLSearchParams(n);t.delete("timeboxId"),d(t,{replace:!0})},Et=t=>{ae(t),t||(ue(null),Ge())},Mt=t=>{re(null),se(Ca(t)),ie(!0)},zt=async(t,r)=>{const l=pt({startAt:t.startAt,endAt:t.endAt},r);await J.mutateAsync({eventId:t.id,patch:l})},$t=async t=>{if(q.length!==0){for(const r of q){const l=pt(r,t);(v==null?void 0:v.mode)==="cut"?await J.mutateAsync({eventId:r.eventId,patch:l}):await ke.mutateAsync({title:r.title,description:r.description,location:r.location,startAt:l.startAt,endAt:l.endAt,timezone:r.timezone,availability:r.availability,preferredCalendarId:r.preferredCalendarId,categories:r.categories,links:r.links})}F()}},_t=p.useMemo(()=>{if(!k)return[];if(k.kind==="day"){const r=Ae.find(l=>l.toISOString().slice(0,10)===k.dayKey);return r?[{id:"create-event",label:"Create event",description:"Open the event guide with this day already selected.",icon:oe,onSelect:()=>Mt(r)},{id:"create-work-block",label:"Create work block",description:"Open the guided work-block flow while you are looking at this day.",icon:Me,onSelect:()=>{R(null),M(!0)}},{id:"paste",label:(v==null?void 0:v.mode)==="cut"?"Paste moved event":"Paste copied event",description:q.length>0?`${q.length} calendar item${q.length===1?"":"s"} ready to paste here.`:v?"The current clipboard entry does not contain calendar events.":"Copy or cut an event first, then paste it into this day.",icon:Ht,disabled:q.length===0,onSelect:()=>void $t(r)}]:[]}if(k.kind==="work-block"){const r=f.workBlockTemplates.find(l=>l.id===k.templateId);return r?[{id:"edit-work-block",label:"Edit",description:"Adjust the recurring pattern, date bounds, or work policy.",icon:oe,onSelect:()=>{R(r),M(!0)}},{id:"delete-work-block",label:"Delete",description:"Remove this recurring work block from Forge.",icon:ze,tone:"danger",onSelect:()=>{(L==null?void 0:L.id)===r.id&&R(null),De.mutateAsync(r.id)}}]:[]}const t=f.events.find(r=>r.id===k.eventId);return t?[{id:"rename",label:"Quick rename",description:"Change the event title without opening the full event flow.",icon:oe,onSelect:()=>Ie(t)},{id:"copy",label:"Copy",description:"Put this event on the Forge clipboard so you can paste it into another day.",icon:Bt,onSelect:()=>m({id:`clipboard_${t.id}_${Date.now()}`,mode:"copy",source:"calendar",label:t.title,createdAt:new Date().toISOString(),items:[gt(t)]})},{id:"cut",label:"Cut",description:"Move this event by pasting it into another day.",icon:Ut,onSelect:()=>m({id:`clipboard_cut_${t.id}_${Date.now()}`,mode:"cut",source:"calendar",label:t.title,createdAt:new Date().toISOString(),items:[gt(t)]})},{id:"delete",label:"Delete",description:"Remove the event from Forge and delete any connected remote projection.",icon:ze,tone:"danger",onSelect:()=>{(v==null?void 0:v.mode)==="cut"&&q.some(r=>r.eventId===t.id)&&N(),Oe.mutateAsync(t.id)}}]:[]},[N,q,v,Ae,Oe,De,k,f.events,f.workBlockTemplates,L,m]);return X.isLoading?e.jsx(oa,{}):X.isError||!X.data?e.jsx(da,{eyebrow:"Calendar",error:X.error??new Error("Calendar data is unavailable"),onRetry:()=>void X.refetch()}):e.jsxs("div",{className:"grid gap-5",children:[e.jsx(fa,{entityKind:"project",titleText:"Calendar",title:"Calendar",description:"See the real week first, then open guided flows for work blocks, task rules, timeboxing, and provider setup.",badge:`${f.connections.length} connection${f.connections.length===1?"":"s"}`}),(Xe=B.data)!=null&&Xe.lifeForce?e.jsxs(Z,{className:"grid gap-3 rounded-[28px] border border-white/8 bg-[linear-gradient(180deg,rgba(15,25,36,0.98),rgba(9,15,26,0.96))] p-4 md:grid-cols-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.18em] text-white/40",children:"Life Force today"}),e.jsxs("div",{className:"mt-2 text-3xl font-semibold text-white",children:[Math.round(B.data.lifeForce.spentTodayAp),e.jsxs("span",{className:"ml-2 text-lg text-white/44",children:["/ ",Math.round(B.data.lifeForce.dailyBudgetAp)," AP"]})]})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.18em] text-white/40",children:"Instant headroom"}),e.jsxs("div",{className:"mt-2 text-2xl font-semibold text-[var(--primary)]",children:[B.data.lifeForce.instantFreeApPerHour.toFixed(1)," AP/h"]}),e.jsx("div",{className:"mt-2 text-sm text-white/58",children:"Calendar containers now speak the same AP language as live work."})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.18em] text-white/40",children:"Forecast"}),e.jsxs("div",{className:"mt-2 text-2xl font-semibold text-white",children:[Math.round(B.data.lifeForce.forecastAp)," AP"]}),e.jsxs("div",{className:"mt-2 text-sm text-white/58",children:["Planned remaining ",ce(B.data.lifeForce.plannedRemainingAp)]})]})]}):null,e.jsxs(Z,{className:"grid gap-4 rounded-[32px] border border-white/8 bg-[linear-gradient(180deg,rgba(17,28,39,0.985),rgba(10,17,29,0.985))]",children:[e.jsx(xa,{description:"The calendar is the priority surface here. Connected provider events, recurring work blocks, and owned task timeboxes all stay visible together.",weekStart:c,status:Pe?e.jsx("div",{className:`inline-flex max-w-full items-center gap-2 rounded-full px-3 py-1.5 text-xs ${Pe.tone==="error"?"border border-rose-400/20 bg-rose-400/10 text-rose-200":"border border-[var(--primary)]/18 bg-[var(--primary)]/12 text-[var(--primary)]"}`,children:Pe.message}):null,badges:e.jsxs(e.Fragment,{children:[(Je=B.data)!=null&&Je.lifeForce?e.jsxs(S,{className:"bg-white/[0.08] text-white/74",children:[Math.round(B.data.lifeForce.spentTodayAp),"/",Math.round(B.data.lifeForce.dailyBudgetAp)," AP"]}):null,It?e.jsxs(S,{className:"bg-white/[0.08] text-white/78",children:[e.jsx(at,{className:"mr-1 size-3.5 animate-spin"}),"Syncing changes"]}):null,v?e.jsxs(S,{className:"bg-white/[0.08] text-white/74",children:[v.mode==="cut"?"Cut":"Copied"," · ",v.label]}):null]}),onPrevious:()=>A(Le(c,-7)),onCurrent:()=>A(_e()),onNext:()=>A(Le(c,7))}),e.jsx("div",{className:"grid gap-3 [grid-template-columns:repeat(auto-fit,minmax(min(100%,17rem),1fr))] 2xl:[grid-template-columns:repeat(7,minmax(0,1fr))]",children:Ae.map(t=>{const r=t.toISOString().slice(0,10),l=f.events.filter(i=>i.startAt.slice(0,10)===r&&!i.deletedAt),T=f.workBlockInstances.filter(i=>i.dateKey===r),O=f.timeboxes.filter(i=>i.startsAt.slice(0,10)===r);return e.jsxs("div",{"data-calendar-day":r,onClick:i=>{i.target.closest("[data-calendar-item='true']")||pe({kind:"day",dayKey:r,position:{x:i.clientX,y:i.clientY}})},onDragOver:i=>{i.preventDefault()},onDrop:i=>{i.preventDefault();const h=i.dataTransfer.getData("text/forge-event-id")||g;if(h){const Q=f.events.find(Se=>Se.id===h);Q&&zt(Q,t),o(null);return}const C=i.dataTransfer.getData("text/forge-timebox-id")||u;if(!C)return;const U=f.timeboxes.find(Q=>Q.id===C);if(!U)return;const W=new Date(U.startsAt),V=new Date(U.endsAt).getTime()-W.getTime(),D=new Date(t);D.setUTCHours(W.getUTCHours(),W.getUTCMinutes(),0,0);const I=new Date(D.getTime()+V);St.mutateAsync({timeboxId:C,startsAt:D.toISOString(),endsAt:I.toISOString()}),s(null)},className:"min-w-0 overflow-hidden rounded-[24px] border border-white/6 bg-white/[0.03] p-3 transition hover:border-white/12 hover:bg-white/[0.045]",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3 rounded-[18px] bg-[rgba(10,16,30,0.96)] px-3 py-2 text-sm font-medium text-white",children:[e.jsx("span",{className:"min-w-0 truncate",children:Re(t)}),e.jsx("button",{type:"button","aria-label":`Open actions for ${Re(t)}`,className:"rounded-full bg-white/[0.06] p-2 text-white/58 transition hover:bg-white/[0.1] hover:text-white",onClick:i=>{i.stopPropagation(),pe({kind:"day",dayKey:r,position:{x:i.clientX,y:i.clientY}})},children:e.jsx($e,{className:"size-4"})})]}),e.jsxs("div",{className:"mt-3 grid min-w-0 gap-2",children:[T.map(i=>e.jsxs("div",{"data-calendar-item":"true",className:"min-w-0 overflow-hidden rounded-[18px] px-3 py-2 text-sm text-white",style:{backgroundColor:`${i.color}22`,border:`1px solid ${i.color}55`},children:[(()=>{const h=ca(i);return e.jsxs("div",{className:"flex min-w-0 items-start justify-between gap-2",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("div",{className:"min-w-0 [overflow-wrap:anywhere] font-medium",children:i.title}),e.jsxs("div",{className:"mt-1 flex min-w-0 flex-wrap items-center gap-1.5",children:[e.jsx(S,{size:"sm",className:"shrink-0 bg-white/[0.08] text-white/78",children:i.blockingState}),e.jsx(S,{size:"sm",className:"shrink-0 bg-white/[0.08] text-white/78",children:xt(i.kind)}),h.rateApPerHour>0?e.jsxs(e.Fragment,{children:[e.jsx(S,{size:"sm",className:"shrink-0 bg-[var(--primary)]/14 text-[var(--primary)]",children:ee(h.rateApPerHour)}),e.jsx(S,{size:"sm",className:"shrink-0 bg-white/[0.08] text-white/72",children:ce(h.totalAp)})]}):e.jsx(S,{size:"sm",className:"shrink-0 bg-emerald-400/12 text-emerald-100",children:"Recovery"})]})]}),e.jsx("button",{type:"button","aria-label":`Open actions for ${i.title}`,className:"rounded-full bg-white/[0.05] p-1.5 text-white/56 transition hover:bg-white/[0.1] hover:text-white",onClick:C=>{C.stopPropagation(),pe({kind:"work-block",templateId:i.templateId,position:{x:C.clientX,y:C.clientY}})},children:e.jsx($e,{className:"size-4"})})]})})(),e.jsxs("div",{className:"mt-1 text-white/60",children:[new Date(i.startAt).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})," ","-"," ",new Date(i.endAt).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})]}),e.jsx("div",{className:"mt-2 text-xs text-white/48",children:yt(f.workBlockTemplates.find(h=>h.id===i.templateId)??{id:i.templateId,title:i.title,kind:i.kind,color:i.color,startsOn:null,endsOn:null,blockingState:i.blockingState,createdAt:i.createdAt,updatedAt:i.updatedAt})})]},i.id)),l.map(i=>e.jsxs("div",{"data-calendar-item":"true",draggable:!0,onDragStart:h=>{o(i.id),h.dataTransfer.setData("text/forge-event-id",i.id)},onClick:h=>{h.stopPropagation(),re(i),se(null),ie(!0)},className:`min-w-0 cursor-move overflow-hidden rounded-[18px] px-3 py-2 text-left text-sm text-white/82 transition ${he.useCalendarColors?"hover:brightness-110":"border border-white/10 bg-white/[0.05] hover:border-white/18 hover:bg-white/[0.08] hover:shadow-[0_12px_32px_rgba(4,9,20,0.22)]"}`,style:he.useCalendarColors?{backgroundColor:`${(i.calendarId?Fe[i.calendarId]:null)??lt(`origin:${i.originType}`)}1f`,border:`1px solid ${(i.calendarId?Fe[i.calendarId]:null)??lt(`origin:${i.originType}`)}55`}:void 0,children:[(be(i),e.jsxs("div",{className:"flex min-w-0 items-start justify-between gap-2",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("div",{className:"line-clamp-2 [overflow-wrap:anywhere] font-medium",children:i.title}),e.jsxs("div",{className:"mt-1 text-white/55",children:[new Date(i.startAt).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})," ","-"," ",new Date(i.endAt).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})]})]}),e.jsx("div",{className:"flex shrink-0 items-center gap-1.5",children:e.jsx("button",{type:"button","aria-label":`Open quick actions for ${i.title}`,className:"rounded-full bg-white/[0.05] p-1.5 text-white/56 transition hover:bg-white/[0.1] hover:text-white",onClick:h=>{h.stopPropagation(),pe({kind:"event",eventId:i.id,position:{x:h.clientX,y:h.clientY}})},children:e.jsx($e,{className:"size-4"})})})]})),e.jsxs("div",{className:"mt-2 flex min-w-0 flex-wrap items-center gap-1.5",children:[e.jsx(S,{size:"sm",className:"max-w-full bg-white/[0.08] px-2 py-0.5 text-[10px] uppercase tracking-[0.14em] text-white/70",children:Pa(i,Ct)}),be(i).rateApPerHour>0?e.jsxs(e.Fragment,{children:[e.jsx(S,{size:"sm",className:"bg-[var(--primary)]/14 px-2 py-0.5 text-[10px] uppercase tracking-[0.14em] text-[var(--primary)]",children:ee(be(i).rateApPerHour)}),e.jsx(S,{size:"sm",className:"bg-white/[0.08] px-2 py-0.5 text-[10px] uppercase tracking-[0.14em] text-white/70",children:ce(be(i).totalAp)})]}):null,i.calendarId&&he.useCalendarColors?e.jsx("span",{"aria-hidden":"true",className:"size-2.5 shrink-0 rounded-full",style:{backgroundColor:Fe[i.calendarId]}}):null]}),i.place.address||i.place.timezone?e.jsxs("div",{className:"mt-2 text-xs leading-5 text-white/50",children:[i.place.address||i.location,i.place.address&&i.place.timezone?" · ":"",i.place.timezone]}):null,i.links.length>0?e.jsx("div",{className:"mt-2 flex min-w-0 flex-wrap gap-1.5",children:i.links.slice(0,3).map(h=>{const C=bt(h.entityType);return C?e.jsx(Be,{kind:C,label:Ot.get(`${h.entityType}:${h.entityId}`)??h.entityType,compact:!0,gradient:!1},h.id):e.jsx(S,{className:"bg-white/[0.08] text-white/72",children:h.entityType},h.id)})}):null]},i.id)),O.map(i=>e.jsxs("div",{"data-calendar-item":"true",draggable:!0,onDragStart:h=>{s(i.id),h.dataTransfer.setData("text/forge-timebox-id",i.id)},onClick:()=>{ue(i),ae(!0)},className:"min-w-0 cursor-move overflow-hidden rounded-[18px] border border-[rgba(192,193,255,0.18)] bg-[linear-gradient(180deg,rgba(67,72,112,0.34),rgba(43,47,80,0.32))] px-3 py-2 text-left text-sm text-white/82 shadow-[inset_0_0_0_1px_rgba(192,193,255,0.08)] transition hover:border-[rgba(192,193,255,0.32)] hover:bg-[linear-gradient(180deg,rgba(74,79,122,0.4),rgba(48,53,92,0.36))]",children:[(()=>{const h=ma(i);return e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"flex min-w-0 items-start justify-between gap-2",children:e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("div",{className:"line-clamp-2 font-medium leading-5 text-white",children:i.title}),e.jsxs("div",{className:"mt-1 flex items-center gap-2 text-white/58",children:[e.jsx(Wt,{className:"size-3.5 shrink-0"}),new Date(i.startsAt).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})," ","-"," ",new Date(i.endsAt).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})]})]})}),e.jsxs("div",{className:"mt-2 flex min-w-0 flex-wrap items-center gap-1.5",children:[e.jsx(S,{size:"sm",className:"bg-white/[0.08] px-2 py-0.5 text-[10px] uppercase tracking-[0.14em] text-white/72",children:i.status}),e.jsx(S,{size:"sm",className:"bg-[var(--primary)]/14 px-2 py-0.5 text-[10px] uppercase tracking-[0.14em] text-[var(--primary)]",children:ee(h.rateApPerHour)}),e.jsx(S,{size:"sm",className:"bg-white/[0.08] px-2 py-0.5 text-[10px] uppercase tracking-[0.14em] text-white/72",children:ce(h.totalAp)})]})]})})(),e.jsxs("div",{className:"mt-2 flex flex-wrap gap-2",children:[e.jsx("button",{type:"button",onClick:h=>{h.stopPropagation(),ue(i),ae(!0)},className:"rounded-[999px] bg-white/[0.08] px-2.5 py-1 text-[10px] uppercase tracking-[0.14em] text-white/78 transition hover:bg-white/[0.14]",children:"Edit"}),e.jsx("button",{type:"button",onClick:h=>{h.stopPropagation(),a(`/tasks/${i.taskId}`)},className:"rounded-[999px] bg-white/[0.08] px-2.5 py-1 text-[10px] uppercase tracking-[0.14em] text-white/78 transition hover:bg-white/[0.14]",children:"Open task"})]})]},i.id)),T.length===0&&l.length===0&&O.length===0?e.jsx("div",{className:"min-h-[10rem] rounded-[18px] border border-dashed border-white/8 px-3 py-4 text-sm leading-8 text-white/42",children:"Nothing scheduled here yet. Click inside this day to create, block, or paste."}):null]})]},r)})})]}),e.jsxs("section",{className:"grid gap-5 xl:grid-cols-[minmax(0,1.2fr)_minmax(0,0.8fr)]",children:[e.jsxs("div",{className:"grid gap-4 md:grid-cols-3",children:[e.jsxs(Z,{className:"rounded-[28px] border border-white/8 bg-[linear-gradient(180deg,rgba(18,28,38,0.98),rgba(11,17,28,0.98))]",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"rounded-[18px] bg-[var(--primary)]/14 p-3 text-[var(--primary)]",children:e.jsx(oe,{className:"size-4"})}),e.jsxs("div",{children:[e.jsx("div",{className:"font-medium text-white",children:"Create event"}),e.jsx("div",{className:"mt-1 text-sm text-white/56",children:"Add a native Forge event with linked context."})]})]}),e.jsx("p",{className:"mt-4 text-sm leading-6 text-white/62",children:"Create a real calendar event even with no provider connected, then project it remotely whenever you choose."}),e.jsx("div",{className:"mt-4",children:e.jsxs(G,{onClick:()=>{R(null),re(null),se(null),ie(!0)},children:[e.jsx(oe,{className:"size-4"}),"Open event guide"]})})]}),e.jsxs(Z,{className:"rounded-[28px] border border-white/8 bg-[linear-gradient(180deg,rgba(18,28,38,0.98),rgba(11,17,28,0.98))]",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"rounded-[18px] bg-[var(--primary)]/14 p-3 text-[var(--primary)]",children:e.jsx(Me,{className:"size-4"})}),e.jsxs("div",{children:[e.jsx("div",{className:"font-medium text-white",children:"Create work block"}),e.jsx("div",{className:"mt-1 text-sm text-white/56",children:"Block main activity or protect creative windows."})]})]}),e.jsx("p",{className:"mt-4 text-sm leading-6 text-white/62",children:"Open the guided flow to create half-day presets, holidays, or custom recurring work blocks."}),e.jsx("div",{className:"mt-4",children:e.jsxs(G,{onClick:()=>{R(null),M(!0)},children:[e.jsx(Me,{className:"size-4"}),"Open work-block guide"]})})]}),e.jsxs(Z,{className:"rounded-[28px] border border-white/8 bg-[linear-gradient(180deg,rgba(18,28,38,0.98),rgba(11,17,28,0.98))]",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"rounded-[18px] bg-[var(--primary)]/14 p-3 text-[var(--primary)]",children:e.jsx(He,{className:"size-4"})}),e.jsxs("div",{children:[e.jsx("div",{className:"font-medium text-white",children:"Plan timebox"}),e.jsx("div",{className:"mt-1 text-sm text-white/56",children:"Let Forge recommend valid upcoming slots."})]})]}),e.jsx("p",{className:"mt-4 text-sm leading-6 text-white/62",children:"Choose a task, review the suggested windows, and schedule directly into the calendar."}),e.jsx("div",{className:"mt-4",children:e.jsxs(G,{onClick:()=>ae(!0),children:[e.jsx(He,{className:"size-4"}),"Open planning guide"]})})]}),e.jsxs(Z,{className:"rounded-[28px] border border-white/8 bg-[linear-gradient(180deg,rgba(18,28,38,0.98),rgba(11,17,28,0.98))]",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"rounded-[18px] bg-[var(--primary)]/14 p-3 text-[var(--primary)]",children:e.jsx(it,{className:"size-4"})}),e.jsxs("div",{children:[e.jsx("div",{className:"font-medium text-white",children:"Manage provider settings"}),e.jsx("div",{className:"mt-1 text-sm text-white/56",children:Ft})]})]}),e.jsx("p",{className:"mt-4 text-sm leading-6 text-white/62",children:"Provider connections and setup instructions now live in Settings so the calendar view can stay focused on the week."}),e.jsxs("div",{className:"mt-4 flex flex-wrap gap-2",children:[e.jsxs(G,{variant:"secondary",onClick:()=>a("/settings/calendar"),children:[e.jsx(Qt,{className:"size-4"}),"Open calendar settings"]}),e.jsxs(G,{variant:"secondary",onClick:()=>a("/settings/calendar?intent=connect"),children:[e.jsx(it,{className:"size-4"}),"Connect provider"]})]})]})]}),e.jsxs("div",{className:"grid gap-4",children:[e.jsxs(Z,{className:"rounded-[28px] border border-white/8 bg-[linear-gradient(180deg,rgba(18,28,38,0.98),rgba(11,17,28,0.98))]",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.18em] text-white/45",children:"This week"}),e.jsx("p",{className:"mt-2 text-sm leading-6 text-white/60",children:"Quick status for the currently visible week."})]}),e.jsxs(G,{variant:"secondary",onClick:()=>void X.refetch(),children:[e.jsx(at,{className:"size-4"}),"Refresh view"]})]}),e.jsxs("div",{className:"mt-4 grid gap-3 sm:grid-cols-3",children:[e.jsxs("div",{className:"rounded-[22px] bg-white/[0.04] px-4 py-4",children:[e.jsx("div",{className:"text-sm text-white/54",children:"Provider events"}),e.jsx("div",{className:"mt-2 font-display text-3xl text-white",children:f.events.length})]}),e.jsxs("div",{className:"rounded-[22px] bg-white/[0.04] px-4 py-4",children:[e.jsx("div",{className:"text-sm text-white/54",children:"Work blocks"}),e.jsx("div",{className:"mt-2 font-display text-3xl text-white",children:f.workBlockInstances.length})]}),e.jsxs("div",{className:"rounded-[22px] bg-white/[0.04] px-4 py-4",children:[e.jsx("div",{className:"text-sm text-white/54",children:"Planned timeboxes"}),e.jsx("div",{className:"mt-2 font-display text-3xl text-white",children:Pt.length})]})]})]}),e.jsxs(Z,{className:"rounded-[28px] border border-white/8 bg-[linear-gradient(180deg,rgba(18,28,38,0.98),rgba(11,17,28,0.98))]",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.18em] text-white/45",children:"Guided actions"}),e.jsxs("div",{className:"mt-3 grid gap-3",children:[e.jsxs("button",{type:"button",onClick:()=>me(!0),className:"rounded-[22px] border border-white/8 bg-white/[0.04] px-4 py-4 text-left transition hover:bg-white/[0.06]",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsx("div",{className:"font-medium text-white",children:"Adjust task blocking rules"}),e.jsx(S,{className:"bg-white/[0.08] text-white/74",children:"Guided"})]}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-white/58",children:"Decide which work blocks, calendar conditions, and event keywords should block or allow a task."})]}),e.jsxs("div",{className:"rounded-[22px] border border-white/8 bg-white/[0.04] px-4 py-4",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsx("div",{className:"font-medium text-white",children:"Active templates"}),e.jsx(S,{className:"bg-white/[0.08] text-white/74",children:f.workBlockTemplates.length})]}),e.jsxs("div",{className:"mt-3 grid gap-2",children:[f.workBlockTemplates.slice(0,4).map(t=>e.jsxs("div",{className:"rounded-[18px] bg-white/[0.04] px-3 py-3 text-sm text-white/74",children:[e.jsx("div",{className:"font-medium text-white",children:t.title}),e.jsxs("div",{className:"mt-1 text-white/56",children:[xt(t.kind)," · ",t.weekDays.length," day",t.weekDays.length===1?"":"s"," · ",t.blockingState]}),e.jsx("div",{className:"mt-1 text-white/46",children:yt(t)}),e.jsxs("div",{className:"mt-3 flex flex-wrap gap-2",children:[e.jsxs(G,{variant:"secondary",size:"sm",onClick:()=>{R(t),M(!0)},children:[e.jsx(oe,{className:"size-3.5"}),"Edit"]}),e.jsxs(G,{variant:"secondary",size:"sm",onClick:()=>void De.mutateAsync(t.id),children:[e.jsx(ze,{className:"size-3.5"}),"Delete"]})]})]},t.id)),f.workBlockTemplates.length===0?e.jsx("div",{className:"text-sm text-white/52",children:"No recurring templates yet. Open the work-block guide to create the first one."}):null]})]})]})]})]})]}),e.jsx(Ta,{open:_,onOpenChange:t=>{M(t),t||R(null)},pending:qe.isPending||Ze.isPending,template:L,onSubmit:async t=>{if(L){await Ze.mutateAsync({templateId:L.id,patch:t});return}await qe.mutateAsync(t)}}),e.jsx(ya,{open:te,onOpenChange:me,tasks:w.snapshot.tasks,onSave:async({taskId:t,schedulingRules:r,plannedDurationSeconds:l})=>{await ua(t,{schedulingRules:r,plannedDurationSeconds:l}),await w.refresh(),await E(),await b.invalidateQueries({queryKey:["task-context",t]})}}),e.jsx(ba,{open:Te,onOpenChange:Et,tasks:w.snapshot.tasks,editingTimebox:Y,from:H.from,to:H.to,onCreateTimebox:async t=>{await At.mutateAsync(t)},onUpdateTimebox:async(t,r)=>{await Nt.mutateAsync({timeboxId:t,patch:r})},onDeleteTimebox:async t=>{await Tt.mutateAsync(t),Ge()}}),e.jsx(Sa,{open:kt,onOpenChange:t=>{ie(t),t||(re(null),se(null))},writableCalendars:Dt,linkOptions:Ee,event:Ce,seed:jt??void 0,onSubmit:async t=>{if(Ce){const r=Ce.id;ie(!1),re(null),se(null),J.mutateAsync({eventId:r,patch:t}).catch(()=>{});return}else{ie(!1),re(null),se(null),ke.mutateAsync(t).catch(()=>{});return}},pending:ke.isPending||J.isPending}),e.jsx(Na,{open:ne!==null,onOpenChange:t=>{t||Ie(null)},initialTitle:(ne==null?void 0:ne.title)??"",pending:J.isPending,onSubmit:async t=>{if(!ne)return;const r=ne.id;Ie(null),J.mutateAsync({eventId:r,patch:{title:t}}).catch(()=>{})}}),e.jsx(ka,{open:k!==null,title:(k==null?void 0:k.kind)==="event"?((Ve=f.events.find(t=>t.id===k.eventId))==null?void 0:Ve.title)??"Event actions":(k==null?void 0:k.kind)==="work-block"?((et=f.workBlockTemplates.find(t=>t.id===k.templateId))==null?void 0:et.title)??"Work block actions":(k==null?void 0:k.kind)==="day"?Re(Ae.find(t=>t.toISOString().slice(0,10)===k.dayKey)??c):"Calendar actions",subtitle:(k==null?void 0:k.kind)==="day"?"Choose what to create or paste into this day.":(k==null?void 0:k.kind)==="work-block"?"Edit or remove this recurring work block.":v?`Clipboard ready: ${v.label}`:"Quick calendar event actions.",items:_t,position:(k==null?void 0:k.position)??null,onClose:()=>pe(null)})]})}export{Qa as CalendarPage};
@@ -1 +0,0 @@
1
- import{r as g,j as a}from"./vendor-DHkYh85p.js";import{i as D}from"./state-B-4sS1xO.js";import{Q as K,cY as C,F as y,j as I,I as B,B as R,T as S,cZ as $}from"./index-CF4J4R9L.js";const W=[10,15,30,45,60];function A(){return{mode:"add",minutes:15,note:""}}function U({open:s,onOpenChange:t,entityType:p,entityId:u,targetLabel:r,currentCreditedSeconds:m,pending:w=!1,onSubmit:h}){const[c,b]=g.useState(A),[v,k]=g.useState(null);g.useEffect(()=>{s&&(b(A()),k(null))},[s]);const e=D({queryKey:["forge-xp-metrics"],queryFn:$,enabled:s}),d=g.useMemo(()=>{var x;const o=(x=e.data)==null?void 0:x.metrics.rules.find(f=>f.code==="task_run_progress"),l=Math.max(1,Number((o==null?void 0:o.config.intervalMinutes)??10)),n=Number((o==null?void 0:o.config.fixedXp)??4);return{intervalMinutes:l,fixedXp:n,intervalSeconds:l*60}},[e.data]),i=g.useMemo(()=>{const o=Math.max(0,Math.trunc(c.minutes||0)),l=c.mode==="add"?o:-o,n=Math.max(0,Math.floor(m/60)),x=l>=0?l:-Math.min(Math.abs(l),n),f=Math.max(0,m+x*60),T=Math.floor(Math.max(0,m)/d.intervalSeconds),M=Math.floor(f/d.intervalSeconds)-T;return{requestedDeltaMinutes:l,appliedDeltaMinutes:x,nextCreditedSeconds:f,bucketDelta:M,xpDelta:M*d.fixedXp,maxRemovableMinutes:n}},[d.fixedXp,d.intervalSeconds,m,c.minutes,c.mode]),N=[{id:"adjustment",eyebrow:p==="task"?"Task work":"Project work",title:`Adjust tracked work for ${r}`,description:"Use this for retrospective minute corrections. Forge will add or remove tracked minutes and adjust progress XP automatically when a reward bucket is crossed.",render:(o,l)=>a.jsxs(a.Fragment,{children:[a.jsx(y,{label:"Mode",labelHelp:"Add minutes when work happened off-timer. Remove minutes when the tracked total needs a correction.",children:a.jsx(I,{value:o.mode,onChange:n=>l({mode:n}),options:[{value:"add",label:"Add minutes",description:"Record extra work that already happened."},{value:"remove",label:"Remove minutes",description:"Correct tracked time without deleting the work history."}]})}),a.jsx(y,{label:"Minutes",description:`Currently tracked: ${Math.floor(m/60)} minutes.`,hint:o.mode==="remove"?`You can remove up to ${i.maxRemovableMinutes} whole minutes from the current credited total.`:void 0,children:a.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[a.jsx(B,{type:"number",min:1,className:"w-36",value:o.minutes,onChange:n=>l({minutes:Number(n.target.value)||0})}),a.jsx("div",{className:"flex flex-wrap gap-2",children:W.map(n=>a.jsxs(R,{type:"button",variant:o.minutes===n?"primary":"secondary",onClick:()=>l({minutes:n}),children:[n," min"]},n))})]})}),a.jsxs("div",{className:"rounded-[24px] border border-white/8 bg-white/[0.04] p-4",children:[a.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/42",children:"Preview"}),a.jsxs("div",{className:"mt-3 grid gap-3 md:grid-cols-3",children:[a.jsxs("div",{className:"rounded-[18px] bg-white/[0.03] px-4 py-3",children:[a.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/42",children:"Applied minutes"}),a.jsxs("div",{className:"mt-2 text-lg text-white",children:[i.appliedDeltaMinutes>0?"+":"",i.appliedDeltaMinutes]})]}),a.jsxs("div",{className:"rounded-[18px] bg-white/[0.03] px-4 py-3",children:[a.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/42",children:"XP delta"}),a.jsxs("div",{className:"mt-2 text-lg text-white",children:[i.xpDelta>0?"+":"",i.xpDelta]})]}),a.jsxs("div",{className:"rounded-[18px] bg-white/[0.03] px-4 py-3",children:[a.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/42",children:"New tracked total"}),a.jsxs("div",{className:"mt-2 text-lg text-white",children:[Math.floor(i.nextCreditedSeconds/60)," min"]})]})]}),a.jsxs("div",{className:"mt-3 text-sm leading-6 text-white/58",children:["Reward cadence: ",d.fixedXp," XP every"," ",d.intervalMinutes," credited minutes."," ",i.bucketDelta===0?"This change does not cross a reward bucket.":`This change crosses ${Math.abs(i.bucketDelta)} reward bucket${Math.abs(i.bucketDelta)===1?"":"s"}.`]})]}),a.jsx(y,{label:"Note",description:"Optional context for why this correction is being added. The note stays attached to the adjustment metadata.",children:a.jsx(S,{className:"min-h-28",value:o.note,onChange:n=>l({note:n.target.value}),placeholder:"Captured the review session that happened away from the live timer."})})]})}];return a.jsx(K,{open:s,onOpenChange:t,eyebrow:p==="task"?"Adjust task work":"Adjust project work",title:`Adjust work for ${r}`,description:"Add or remove tracked minutes without creating a live task run.",value:c,onChange:b,draftPersistenceKey:`work-adjustment.${p}.${u}`,steps:N,submitLabel:"Save adjustment",pending:w,pendingLabel:"Saving adjustment...",error:v,onSubmit:async()=>{var x;k(null);const o=Math.max(0,Math.trunc(c.minutes||0)),l=c.mode==="add"?o:-o,n=C.safeParse({entityType:p,entityId:u,deltaMinutes:l,note:c.note});if(!n.success){k(((x=n.error.issues[0])==null?void 0:x.message)??"Enter a valid minute adjustment.");return}try{await h({entityType:p,entityId:u,deltaMinutes:n.data.deltaMinutes,note:n.data.note||void 0}),t(!1)}catch(f){k(f instanceof Error?f.message:"Could not save the work adjustment right now.")}}})}const E={allowWorkBlockKinds:[],blockWorkBlockKinds:[],allowCalendarIds:[],blockCalendarIds:[],allowEventTypes:[],blockEventTypes:[],allowEventKeywords:[],blockEventKeywords:[],allowAvailability:[],blockAvailability:[]};function X(s){return s.map(t=>t.trim().toLowerCase()).filter(Boolean)}function j(s,t){const p=X(s);if(p.length===0)return!1;const u=t.join(" ").toLowerCase();return p.some(r=>u.includes(r))}function F(s){return s.allowWorkBlockKinds.length>0||s.allowCalendarIds.length>0||s.allowEventTypes.length>0||s.allowEventKeywords.length>0||s.allowAvailability.length>0}function P(s,t){return s??t??E}function Y(s){const t=s.rules??E,u=(s.at??new Date).getTime(),r=s.overview,m=(r==null?void 0:r.workBlockInstances.filter(e=>{const d=new Date(e.startAt).getTime(),i=new Date(e.endAt).getTime();return d<=u&&u<i}))??[],w=(r==null?void 0:r.events.filter(e=>{if(e.deletedAt)return!1;const d=new Date(e.startAt).getTime(),i=new Date(e.endAt).getTime();return d<=u&&u<i}))??[],h=[],c=m.some(e=>t.blockWorkBlockKinds.includes(e.kind))||w.some(e=>(e.calendarId?t.blockCalendarIds.includes(e.calendarId):!1)||t.blockEventTypes.includes(e.eventType)||t.blockAvailability.includes(e.availability)||j(t.blockEventKeywords,[e.title,e.description,e.location,...e.categories]));c&&(m.some(e=>t.blockWorkBlockKinds.includes(e.kind))&&h.push("The current work block is marked as blocked."),w.some(e=>e.calendarId?t.blockCalendarIds.includes(e.calendarId):!1)&&h.push("The active calendar belongs to a blocked calendar source."),w.some(e=>t.blockEventTypes.includes(e.eventType))&&h.push("The active calendar event type is blocked."),w.some(e=>t.blockAvailability.includes(e.availability))&&h.push("The active calendar availability is blocked."),w.some(e=>j(t.blockEventKeywords,[e.title,e.description,e.location,...e.categories]))&&h.push("The active calendar event matches a blocked keyword."));const b=F(t),v=m.some(e=>t.allowWorkBlockKinds.includes(e.kind))||w.some(e=>(e.calendarId?t.allowCalendarIds.includes(e.calendarId):!1)||t.allowEventTypes.includes(e.eventType)||t.allowAvailability.includes(e.availability)||j(t.allowEventKeywords,[e.title,e.description,e.location,...e.categories]));!c&&b&&!v&&h.push("The current calendar context does not match the allowed rules yet.");const k=[...m.map(e=>`${e.title} (${e.kind.replaceAll("_"," ")})`),...w.map(e=>e.title)];return h.length>0?{blocked:!0,label:"Blocked right now",tone:"blocked",conflicts:h,context:k}:k.length>0?{blocked:!1,label:"Allowed right now",tone:"allowed",conflicts:[],context:k}:{blocked:!1,label:b?"Waiting for an allowed calendar context":"No live calendar conflict right now",tone:b?"waiting":"allowed",conflicts:[],context:[]}}function z(s,t){return P(s.schedulingRules,t)}export{U as W,Y as e,z as g};
@@ -1 +0,0 @@
1
- import{j as e,aV as m}from"./vendor-DHkYh85p.js";import{c as d,B as a}from"./index-CF4J4R9L.js";import{f as o}from"./calendar-ui-Cy1XRwzV.js";function f({eyebrow:r="Week view",description:i,weekStart:t,status:s,badges:l,onPrevious:n,onCurrent:c,onNext:x}){return 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/45",children:r}),e.jsx("p",{className:"mt-2 max-w-3xl text-sm leading-6 text-white/60",children:i}),s?e.jsx("div",{className:"mt-3",children:s}):null]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsxs(d,{className:"bg-[var(--primary)]/14 text-[var(--primary)]",children:[e.jsx(m,{className:"mr-1 size-3.5"}),"Week of ",o(t)]}),l,e.jsx(a,{variant:"secondary",onClick:n,children:"Previous"}),e.jsx(a,{variant:"secondary",onClick:c,children:"This week"}),e.jsx(a,{variant:"secondary",onClick:x,children:"Next"})]})]})}export{f as C};
@@ -1 +0,0 @@
1
- import{j as e}from"./vendor-DHkYh85p.js";import{C as g,c as s}from"./index-CF4J4R9L.js";import{P as y}from"./page-hero-DRy5b2MU.js";import"./state-B-4sS1xO.js";import"./board-BkDRaMp6.js";import"./ui-C13Nbgas.js";import"./motion-BeD44FeG.js";import"./forms-BFlTgZ3W.js";import"./graph-D6JLqDbD.js";const N=[{id:"health-ready",title:"Health ready",desiredEnabled:!0,appliedEnabled:!0,authorizationStatus:"approved",syncEligible:!0,lastObservedAt:"2026-04-12T09:00:00.000Z"},{id:"movement-pending-phone",title:"Movement pending on phone",desiredEnabled:!0,appliedEnabled:!1,authorizationStatus:"pending",syncEligible:!1,lastObservedAt:"2026-04-12T09:04:00.000Z"},{id:"screen-time-denied",title:"Screen Time denied",desiredEnabled:!0,appliedEnabled:!0,authorizationStatus:"denied",syncEligible:!1,lastObservedAt:"2026-04-12T08:54:00.000Z"},{id:"health-off",title:"Health off",desiredEnabled:!1,appliedEnabled:!1,authorizationStatus:"disabled",syncEligible:!1,lastObservedAt:null}],f=[{id:"gap-stay",title:"Quiet short gap",gapSeconds:1080,displacementMeters:42,hasStartBoundary:!0,hasEndBoundary:!0},{id:"gap-short-jump",title:"Suppressed short jump",gapSeconds:240,displacementMeters:260,hasStartBoundary:!0,hasEndBoundary:!0},{id:"gap-trip",title:"Repaired move",gapSeconds:1320,displacementMeters:1850,hasStartBoundary:!0,hasEndBoundary:!0},{id:"gap-missing-long",title:"Long missing gap",gapSeconds:7200,displacementMeters:320,hasStartBoundary:!0,hasEndBoundary:!0},{id:"gap-missing-boundary",title:"Missing boundary anchor",gapSeconds:960,displacementMeters:null,hasStartBoundary:!1,hasEndBoundary:!0}],k=[{id:"overnight-gap-before-move",title:"Exact overnight stay-gap-move bug",rangeStart:"2026-04-05T21:15:00.000Z",rangeEnd:"2026-04-06T02:40:00.000Z",segments:[{id:"stay-home-evening",kind:"stay",startedAt:"2026-04-05T21:15:00.000Z",endedAt:"2026-04-05T21:30:00.000Z",placeLabel:"Home",placeExternalUid:"place_home",startCoordinate:{latitude:46.5191,longitude:6.6323},endCoordinate:{latitude:46.5191,longitude:6.6323}},{id:"trip-night-move",kind:"trip",startedAt:"2026-04-06T02:34:00.000Z",endedAt:"2026-04-06T02:40:00.000Z",placeLabel:"Night move",placeExternalUid:null,startCoordinate:{latitude:46.5216,longitude:6.6404},endCoordinate:{latitude:46.5226,longitude:6.6424}}]},{id:"repeated-home-stays",title:"Repeated home stays coalesce",rangeStart:"2026-04-05T07:00:00.000Z",rangeEnd:"2026-04-05T08:44:00.000Z",segments:[{id:"stay-home-1",kind:"stay",startedAt:"2026-04-05T07:00:00.000Z",endedAt:"2026-04-05T08:00:00.000Z",placeLabel:"Home",placeExternalUid:"place_home",startCoordinate:{latitude:46.5191,longitude:6.6323},endCoordinate:{latitude:46.5191,longitude:6.6323}},{id:"stay-home-2",kind:"stay",startedAt:"2026-04-05T08:20:00.000Z",endedAt:"2026-04-05T08:40:00.000Z",placeLabel:"Home",placeExternalUid:"place_home",startCoordinate:{latitude:46.51912,longitude:6.63231},endCoordinate:{latitude:46.51912,longitude:6.63231}},{id:"trip-start-anchor",kind:"trip",startedAt:"2026-04-05T08:44:00.000Z",endedAt:"2026-04-05T08:49:00.000Z",placeLabel:"Walk out",placeExternalUid:null,startCoordinate:{latitude:46.5217,longitude:6.6405},endCoordinate:{latitude:46.5221,longitude:6.6412}}]}],E=[{id:"user-override-home-window",title:"User-defined missing box overrides one automatic home stay",rawMeasurements:[{id:"raw-stay-home",label:"Raw stay · Home",startedAt:"2026-04-05T08:00:00.000Z",endedAt:"2026-04-05T10:00:00.000Z"}],automaticBoxes:[{id:"auto-stay-home",kind:"stay",origin:"recorded",startedAt:"2026-04-05T08:00:00.000Z",endedAt:"2026-04-05T10:00:00.000Z",title:"Home"}],userBoxes:[{id:"user-missing-home-window",kind:"missing",origin:"user_invalidated",startedAt:"2026-04-05T08:30:00.000Z",endedAt:"2026-04-05T09:00:00.000Z",title:"User invalidated automatic movement",overrideCount:1}],projectedBoxes:[{id:"projected-home-early",kind:"stay",sourceKind:"automatic",origin:"recorded",startedAt:"2026-04-05T08:00:00.000Z",endedAt:"2026-04-05T08:30:00.000Z",title:"Home",overrideCount:0},{id:"projected-home-user-missing",kind:"missing",sourceKind:"user_defined",origin:"user_invalidated",startedAt:"2026-04-05T08:30:00.000Z",endedAt:"2026-04-05T09:00:00.000Z",title:"User invalidated automatic movement",overrideCount:1},{id:"projected-home-late",kind:"stay",sourceKind:"automatic",origin:"recorded",startedAt:"2026-04-05T09:00:00.000Z",endedAt:"2026-04-05T10:00:00.000Z",title:"Home",overrideCount:0}]}],w=3600,T=300,_=100;function x(t,i){return Math.max(0,Math.round((Date.parse(i)-Date.parse(t))/1e3))}function S(t,i){if(!t||!i)return null;const a=6371e3,m=(i.latitude-t.latitude)*Math.PI/180,l=(i.longitude-t.longitude)*Math.PI/180,h=t.latitude*Math.PI/180,c=i.latitude*Math.PI/180,p=Math.sin(m/2)**2+Math.cos(h)*Math.cos(c)*Math.sin(l/2)**2,r=2*Math.atan2(Math.sqrt(p),Math.sqrt(1-p));return a*r}function M(t,i){if(t.placeExternalUid&&i.placeExternalUid&&t.placeExternalUid===i.placeExternalUid)return!0;const a=S(t.endCoordinate,i.startCoordinate);return a!==null&&a<=_}function C(t){return t.gapSeconds>3600?{kind:"missing",origin:"missing",reason:"Gap exceeded one hour, so Forge keeps it as explicit missing data.",suppressedShortJump:!1}:!t.hasStartBoundary||!t.hasEndBoundary||t.displacementMeters===null?{kind:"missing",origin:"missing",reason:"One or both boundary anchors were missing, so the gap stays missing instead of inventing movement.",suppressedShortJump:!1}:t.displacementMeters<=100?{kind:"stay",origin:"repaired_gap",reason:"Boundary displacement stayed within 100 m, so the gap repairs into one stay.",suppressedShortJump:!1}:t.gapSeconds<300?{kind:"stay",origin:"repaired_gap",reason:"The jump crossed 100 m but stayed under five minutes, so Forge suppresses it into stay continuity.",suppressedShortJump:!0}:{kind:"trip",origin:"repaired_gap",reason:"The gap stayed under one hour, crossed 100 m, and lasted at least five minutes, so Forge repairs it into a move.",suppressedShortJump:!1}}function L(t){var b,v,j,A;const i=[...t.segments].sort((d,o)=>d.startedAt.localeCompare(o.startedAt)),a=[];if(i.length===0)return{segments:[],uncoveredIntervals:[]};const m=i[0];x(t.rangeStart,m.startedAt)>0&&a.push({id:`missing_${t.rangeStart}_${m.startedAt}`,kind:"missing",origin:"missing",startedAt:t.rangeStart,endedAt:m.startedAt,title:"Missing data"}),i.forEach((d,o)=>{if(o>0){const n=i[o-1],u=x(n.endedAt,d.startedAt);u>0&&(u>w?a.push({id:`missing_${n.id}_${d.id}`,kind:"missing",origin:"missing",startedAt:n.endedAt,endedAt:d.startedAt,title:"Missing data"}):M(n,d)?a.push({id:`repaired_stay_${n.id}_${d.id}`,kind:"stay",origin:"repaired_gap",startedAt:n.endedAt,endedAt:d.startedAt,title:n.placeLabel??d.placeLabel??"Repaired stay"}):S(n.endCoordinate,d.startCoordinate)===null?a.push({id:`missing_${n.id}_${d.id}`,kind:"missing",origin:"missing",startedAt:n.endedAt,endedAt:d.startedAt,title:"Missing data"}):u<T?a.push({id:`repaired_short_jump_${n.id}_${d.id}`,kind:"stay",origin:"repaired_gap",startedAt:n.endedAt,endedAt:d.startedAt,title:n.placeLabel??d.placeLabel??"Repaired stay"}):a.push({id:`repaired_trip_${n.id}_${d.id}`,kind:"trip",origin:"repaired_gap",startedAt:n.endedAt,endedAt:d.startedAt,title:"Repaired move"}))}a.push({id:d.id,kind:d.kind,origin:"recorded",startedAt:d.startedAt,endedAt:d.endedAt,title:d.placeLabel??d.kind})});const l=i[i.length-1],h=x(l.endedAt,t.rangeEnd);h>0&&(l.kind==="stay"&&h<=w?a.push({id:`continued_${l.id}_${t.rangeEnd}`,kind:"stay",origin:"continued_stay",startedAt:l.endedAt,endedAt:t.rangeEnd,title:l.placeLabel??"Continued stay"}):a.push({id:`missing_${l.endedAt}_${t.rangeEnd}`,kind:"missing",origin:"missing",startedAt:l.endedAt,endedAt:t.rangeEnd,title:"Missing data"}));const c=[];for(const d of a){const o=c[c.length-1];if(o&&o.kind==="stay"&&d.kind==="stay"&&(o.origin!=="recorded"||d.origin!=="recorded")&&o.endedAt===d.startedAt){c[c.length-1]={...o,id:`${o.id}_${d.id}`,origin:o.origin==="continued_stay"||d.origin==="continued_stay"?"continued_stay":"repaired_gap",endedAt:d.endedAt};continue}c.push(d)}const p=[],r=[...c].sort((d,o)=>d.startedAt.localeCompare(o.startedAt));((b=r[0])==null?void 0:b.startedAt)!==t.rangeStart&&p.push({startedAt:t.rangeStart,endedAt:((v=r[0])==null?void 0:v.startedAt)??t.rangeEnd});for(let d=1;d<r.length;d+=1)r[d-1].endedAt!==r[d].startedAt&&p.push({startedAt:r[d-1].endedAt,endedAt:r[d].startedAt});return((j=r[r.length-1])==null?void 0:j.endedAt)!==t.rangeEnd&&p.push({startedAt:((A=r[r.length-1])==null?void 0:A.endedAt)??t.rangeStart,endedAt:t.rangeEnd}),{segments:r,uncoveredIntervals:p}}function Z(t){return t?new Date(t).toLocaleString():"Waiting for device update"}function F(){return e.jsxs("div",{className:"mx-auto grid w-full max-w-[1180px] gap-5",children:[e.jsx(y,{title:"Companion Sync Lab",description:"Deterministic fixtures for source-state reconciliation and movement gap repair. This route is dev-only and exists to make QA faster than recreating every phone state by hand.",badge:"Dev only"}),e.jsxs("section",{className:"grid gap-4 lg:grid-cols-[1.05fr_0.95fr]",children:[e.jsxs(g,{className:"grid gap-4 rounded-[28px] border border-white/8 bg-[linear-gradient(180deg,rgba(10,17,31,0.96),rgba(8,13,24,0.92))] p-5",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/42",children:"Source matrix"}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-white/58",children:"These rows mirror the pairing source-state contract that the web and phone now share."})]}),e.jsx("div",{className:"grid gap-3",children:N.map(t=>e.jsxs("div",{className:"grid gap-2 rounded-[20px] border border-white/8 bg-white/[0.03] px-4 py-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("div",{className:"text-sm font-medium text-white",children:t.title}),e.jsx(s,{tone:t.desiredEnabled?"signal":"meta",children:t.desiredEnabled?"Enabled":"Off"}),e.jsx(s,{tone:"meta",children:t.desiredEnabled===t.appliedEnabled?"Applied":"Pending on phone"})]}),e.jsxs("div",{className:"grid gap-1 text-xs text-white/56 sm:grid-cols-2",children:[e.jsxs("div",{children:["Authorization: ",t.authorizationStatus]}),e.jsxs("div",{children:["Sync eligible: ",t.syncEligible?"Yes":"No"]}),e.jsxs("div",{children:["Desired: ",t.desiredEnabled?"On":"Off"]}),e.jsxs("div",{children:["Applied: ",t.appliedEnabled?"On":"Off"]}),e.jsxs("div",{className:"sm:col-span-2",children:["Last observed: ",Z(t.lastObservedAt)]})]})]},t.id))})]}),e.jsxs(g,{className:"grid gap-4 rounded-[28px] border border-white/8 bg-[linear-gradient(180deg,rgba(10,17,31,0.96),rgba(8,13,24,0.92))] p-5",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/42",children:"Gap classifier"}),e.jsxs("div",{className:"mt-2 text-sm leading-6 text-white/58",children:["Every gap resolves to exactly one of ",e.jsx("code",{children:"stay"}),","," ",e.jsx("code",{children:"trip"}),", or ",e.jsx("code",{children:"missing"}),"."]})]}),e.jsx("div",{className:"grid gap-3",children:f.map(t=>{const i=C(t);return e.jsxs("div",{className:"grid gap-2 rounded-[20px] border border-white/8 bg-white/[0.03] px-4 py-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("div",{className:"text-sm font-medium text-white",children:t.title}),e.jsx(s,{tone:i.kind==="missing"?"meta":i.kind==="trip"?"signal":"default",children:i.kind}),e.jsx(s,{tone:"meta",children:i.origin}),i.suppressedShortJump?e.jsx(s,{className:"bg-amber-400/10 text-amber-100",children:"Suppressed short jump"}):null]}),e.jsxs("div",{className:"grid gap-1 text-xs text-white/56 sm:grid-cols-2",children:[e.jsxs("div",{children:["Gap: ",Math.round(t.gapSeconds/60)," min"]}),e.jsxs("div",{children:["Displacement:"," ",t.displacementMeters===null?"unknown":`${Math.round(t.displacementMeters)} m`]}),e.jsxs("div",{children:["Start boundary: ",t.hasStartBoundary?"present":"missing"]}),e.jsxs("div",{children:["End boundary: ",t.hasEndBoundary?"present":"missing"]})]}),e.jsx("div",{className:"text-sm leading-6 text-white/72",children:i.reason})]},t.id)})})]})]}),e.jsxs(g,{className:"grid gap-4 rounded-[28px] border border-white/8 bg-[linear-gradient(180deg,rgba(10,17,31,0.96),rgba(8,13,24,0.92))] p-5",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/42",children:"Coverage preview"}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-white/58",children:"These fixtures normalize a full window and highlight whether any interval would still be left uncovered."})]}),e.jsx("div",{className:"grid gap-3",children:k.map(t=>{const i=L(t);return e.jsxs("div",{className:"grid gap-3 rounded-[20px] border border-white/8 bg-white/[0.03] px-4 py-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("div",{className:"text-sm font-medium text-white",children:t.title}),e.jsx(s,{className:i.uncoveredIntervals.length===0?"bg-emerald-400/10 text-emerald-100":"bg-rose-400/10 text-rose-100",children:i.uncoveredIntervals.length===0?"Coverage locked":"Coverage broken"}),e.jsxs(s,{tone:"meta",children:[i.segments.length," normalized segment",i.segments.length===1?"":"s"]})]}),e.jsx("div",{className:"grid gap-2",children:i.segments.map(a=>e.jsxs("div",{className:"flex flex-wrap items-center gap-2 rounded-[16px] border border-white/6 bg-white/[0.02] px-3 py-2 text-xs text-white/68",children:[e.jsx(s,{tone:a.kind==="trip"?"signal":a.kind==="missing"?"meta":"default",children:a.kind}),e.jsx(s,{tone:"meta",children:a.origin}),e.jsxs("span",{children:[new Date(a.startedAt).toLocaleTimeString()," → ",new Date(a.endedAt).toLocaleTimeString()]}),e.jsx("span",{className:"text-white/48",children:a.title})]},a.id))}),i.uncoveredIntervals.length>0?e.jsx("div",{className:"grid gap-2",children:i.uncoveredIntervals.map(a=>e.jsxs("div",{className:"rounded-[14px] border border-rose-400/18 bg-rose-500/10 px-3 py-2 text-xs text-rose-100",children:["Uncovered: ",new Date(a.startedAt).toLocaleTimeString()," →"," ",new Date(a.endedAt).toLocaleTimeString()]},`${a.startedAt}-${a.endedAt}`))}):null]},t.id)})})]}),e.jsxs(g,{className:"grid gap-4 rounded-[28px] border border-white/8 bg-[linear-gradient(180deg,rgba(10,17,31,0.96),rgba(8,13,24,0.92))] p-5",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/42",children:"Canonical box layers"}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-white/58",children:"Raw phone measurements stay immutable. Forge generates automatic boxes from them, user-defined boxes override them, and the final projected boxes are what both the web and iPhone should render."})]}),e.jsx("div",{className:"grid gap-4",children:E.map(t=>e.jsxs("div",{className:"grid gap-4 rounded-[20px] border border-white/8 bg-white/[0.03] px-4 py-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("div",{className:"text-sm font-medium text-white",children:t.title}),e.jsxs(s,{tone:"meta",children:["Raw: ",t.rawMeasurements.length]}),e.jsxs(s,{tone:"meta",children:["Automatic: ",t.automaticBoxes.length]}),e.jsxs(s,{tone:"meta",children:["User: ",t.userBoxes.length]}),e.jsxs(s,{tone:"signal",children:["Projected: ",t.projectedBoxes.length]})]}),e.jsxs("div",{className:"grid gap-3 xl:grid-cols-4",children:[e.jsxs("div",{className:"grid gap-2 rounded-[16px] border border-white/6 bg-black/10 p-3",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/42",children:"Raw measurements"}),t.rawMeasurements.map(i=>e.jsxs("div",{className:"rounded-[14px] border border-white/6 bg-white/[0.03] px-3 py-2 text-xs text-white/68",children:[e.jsx("div",{className:"font-medium text-white",children:i.label}),e.jsxs("div",{children:[new Date(i.startedAt).toLocaleTimeString()," →"," ",new Date(i.endedAt).toLocaleTimeString()]})]},i.id))]}),e.jsxs("div",{className:"grid gap-2 rounded-[16px] border border-white/6 bg-black/10 p-3",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/42",children:"Automatic boxes"}),t.automaticBoxes.map(i=>e.jsxs("div",{className:"rounded-[14px] border border-white/6 bg-white/[0.03] px-3 py-2 text-xs text-white/68",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(s,{tone:i.kind==="trip"?"signal":i.kind==="missing"?"meta":"default",children:i.kind}),e.jsx(s,{tone:"meta",children:i.origin})]}),e.jsx("div",{className:"mt-2 font-medium text-white",children:i.title}),e.jsxs("div",{children:[new Date(i.startedAt).toLocaleTimeString()," →"," ",new Date(i.endedAt).toLocaleTimeString()]})]},i.id))]}),e.jsxs("div",{className:"grid gap-2 rounded-[16px] border border-white/6 bg-black/10 p-3",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/42",children:"User-defined boxes"}),t.userBoxes.map(i=>e.jsxs("div",{className:"rounded-[14px] border border-white/6 bg-white/[0.03] px-3 py-2 text-xs text-white/68",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(s,{tone:i.kind==="missing"?"meta":"default",children:i.kind}),e.jsx(s,{className:"bg-pink-400/10 text-pink-100",children:i.origin})]}),e.jsx("div",{className:"mt-2 font-medium text-white",children:i.title}),e.jsxs("div",{children:[new Date(i.startedAt).toLocaleTimeString()," →"," ",new Date(i.endedAt).toLocaleTimeString()]}),e.jsxs("div",{className:"mt-1 text-white/52",children:["Overrides ",i.overrideCount," automatic box",i.overrideCount===1?"":"es"]})]},i.id))]}),e.jsxs("div",{className:"grid gap-2 rounded-[16px] border border-white/6 bg-black/10 p-3",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/42",children:"Projected visible boxes"}),t.projectedBoxes.map(i=>e.jsxs("div",{className:"rounded-[14px] border border-white/6 bg-white/[0.03] px-3 py-2 text-xs text-white/68",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(s,{tone:i.kind==="trip"?"signal":i.kind==="missing"?"meta":"default",children:i.kind}),e.jsx(s,{tone:"meta",children:i.sourceKind})]}),e.jsx("div",{className:"mt-2 font-medium text-white",children:i.title}),e.jsxs("div",{children:[new Date(i.startedAt).toLocaleTimeString()," →"," ",new Date(i.endedAt).toLocaleTimeString()]}),e.jsxs("div",{className:"mt-1 text-white/52",children:[i.origin,i.overrideCount>0?` · overrides ${i.overrideCount}`:""]})]},i.id))]})]})]},t.id))})]})]})}export{F as CompanionSyncLabPage};
@@ -1 +0,0 @@
1
- import{bU as j,j as e,d1 as M,d2 as V,aI as _,d3 as S,d4 as P,d5 as L,aG as T,aX as z,r as u,cX as R,aK as $}from"./vendor-DHkYh85p.js";import{R as K,P as F,O as B,C as O,T as A,D as W,a as I}from"./ui-C13Nbgas.js";import{C as v,Z as x,c}from"./index-CF4J4R9L.js";import{R as X,e as E,C as G,X as H,Y,d as U,T as Z,B as q,a as J}from"./charts-P7EVhIog.js";function m(a){return a?new Date(`${a}T12:00:00`).toLocaleDateString(void 0,{month:"short",day:"numeric"}):"No date yet"}function Q(a,s){return s==="cumulative"?a.total??a.latest??a.maximum??a.average:a.latest??a.average??a.maximum??a.minimum}function d(a,s){if(s==null)return"No reading";const t=a.unit==="steps"||a.unit==="flights"||a.unit==="kcal"||a.unit==="min"||a.unit==="swears"||a.unit==="conversations"||a.unit==="messages"?0:(a.unit==="%",1);return`${s.toLocaleString(void 0,{maximumFractionDigits:t,minimumFractionDigits:t===0||s>=100?0:1})} ${a.unit}`}function w(a){return a.deltaValue==null?"No baseline yet":`${a.deltaValue>0?"+":""}${d(a,a.deltaValue)}`}function ee(a){return Math.round(a*10)/10}function N(a,s){return Q(a,s)}function b(a){const s=a.days.map(t=>N(t,a.aggregation)).filter(t=>t!=null);return s.length===0?{minimum:null,average:null,maximum:null,count:0}:{minimum:Math.min(...s),average:s.reduce((t,i)=>t+i,0)/s.length,maximum:Math.max(...s),count:s.length}}function y(a){return new Date(`${a}T12:00:00`).toLocaleDateString(void 0,{month:"short",day:"numeric"})}function ae({active:a,payload:s,label:t,metric:i}){var r;if(!a||!(s!=null&&s.length)||typeof t!="string")return null;const l=((r=s.find(n=>typeof n.value=="number"))==null?void 0:r.value)??null;return e.jsxs("div",{className:"rounded-[18px] border border-white/10 bg-[rgba(9,13,24,0.94)] px-3 py-2 shadow-[0_18px_48px_rgba(0,0,0,0.38)] backdrop-blur-xl",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/40",children:y(t)}),e.jsx("div",{className:"mt-1 text-sm font-semibold text-white",children:d(i,l)})]})}function k({metric:a,height:s=180,detailed:t=!1}){const i=u.useMemo(()=>b(a),[a]),l=u.useMemo(()=>a.days.map(o=>({dateKey:o.dateKey,value:N(o,a.aggregation),sampleCount:o.sampleCount})),[a]),r=l.map(o=>o.value).filter(o=>o!=null),n=r.length>0?Math.min(...r):0,p=r.length>0?Math.max(...r):1,f=Math.max((p-n)*.12,a.unit==="%"?2:1),C=g(a.category),h=`metric-gradient-${a.metric.replace(/[^a-z0-9]/gi,"-")}`;return r.length===0?e.jsx("div",{className:"flex items-center justify-center rounded-[22px] border border-dashed border-white/8 bg-white/[0.025] text-sm text-white/40",style:{height:s},children:"Waiting for chart data"}):e.jsx("div",{className:x("overflow-hidden rounded-[22px] border bg-[radial-gradient(circle_at_top_left,rgba(171,232,255,0.08),transparent_34%),rgba(255,255,255,0.025)] p-3",C.ring),style:{height:s},children:e.jsx(X,{width:"100%",height:"100%",children:e.jsxs(E,{data:l,margin:{top:t?18:8,right:t?18:4,bottom:t?12:0,left:t?8:0},children:[e.jsx("defs",{children:e.jsxs("linearGradient",{id:h,x1:"0",y1:"0",x2:"0",y2:"1",children:[e.jsx("stop",{offset:"0%",stopColor:"rgba(171,232,255,0.55)"}),e.jsx("stop",{offset:"56%",stopColor:"rgba(251,191,36,0.22)"}),e.jsx("stop",{offset:"100%",stopColor:"rgba(251,191,36,0.02)"})]})}),e.jsx(G,{stroke:"rgba(255,255,255,0.07)",vertical:t}),e.jsx(H,{dataKey:"dateKey",tickFormatter:y,minTickGap:t?22:34,tick:{fill:"rgba(255,255,255,0.46)",fontSize:11},axisLine:{stroke:"rgba(255,255,255,0.1)"},tickLine:!1}),e.jsx(Y,{width:t?62:36,domain:[Math.max(0,n-f),p+f],tickFormatter:o=>d(a,Number(o)).replace(` ${a.unit}`,""),tick:{fill:"rgba(255,255,255,0.46)",fontSize:11},axisLine:!1,tickLine:!1}),i.average!=null?e.jsx(U,{y:ee(i.average),stroke:"rgba(255,255,255,0.34)",strokeDasharray:"5 5",ifOverflow:"extendDomain"}):null,e.jsx(Z,{cursor:{stroke:"rgba(255,255,255,0.22)",strokeWidth:1},content:e.jsx(ae,{metric:a})}),a.aggregation==="cumulative"?e.jsx(q,{dataKey:"value",radius:[8,8,2,2],fill:`url(#${h})`,maxBarSize:t?34:20}):e.jsx(J,{type:"monotone",dataKey:"value",stroke:"rgba(171,232,255,0.92)",strokeWidth:t?3:2,fill:`url(#${h})`,dot:t?{r:3,fill:"rgba(251,191,36,0.9)"}:!1,activeDot:{r:5,fill:"rgba(251,191,36,0.95)"}})]})})})}function te({metric:a,open:s,onOpenChange:t}){const i=b(a),l=g(a.category);return e.jsx(K,{open:s,onOpenChange:t,children:e.jsxs(F,{children:[e.jsx(B,{className:"fixed inset-0 z-50 bg-[rgba(3,7,18,0.82)] backdrop-blur-xl"}),e.jsxs(O,{className:"fixed inset-3 z-[51] grid min-h-0 overflow-hidden rounded-[32px] border border-white/10 bg-[radial-gradient(circle_at_top_left,rgba(171,232,255,0.12),transparent_34%),linear-gradient(180deg,rgba(12,18,32,0.98),rgba(7,10,20,0.99))] shadow-[0_34px_110px_rgba(0,0,0,0.58)] sm:inset-5",children:[e.jsxs(A,{className:"sr-only",children:[a.label," chart"]}),e.jsx(W,{className:"sr-only",children:"Full-screen time-series chart for the selected daily metric."}),e.jsxs("div",{className:"grid min-h-0 grid-rows-[auto_minmax(0,1fr)]",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-4 border-b border-white/8 px-5 py-4 sm:px-6",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"text-[11px] uppercase tracking-[0.18em] text-white/40",children:[a.category," time series"]}),e.jsx("div",{className:"mt-1 text-2xl font-semibold text-white sm:text-3xl",children:a.label}),e.jsxs("div",{className:"mt-2 flex flex-wrap gap-2 text-xs text-white/54",children:[e.jsx(c,{className:l.badge,children:a.aggregation}),e.jsxs(c,{tone:"meta",children:[a.coverageDays," tracked days"]}),e.jsxs(c,{tone:"meta",children:["latest ",m(a.latestDateKey)]})]})]}),e.jsx(I,{asChild:!0,children:e.jsx("button",{type:"button",className:"inline-flex size-11 items-center justify-center rounded-full border border-white/10 bg-white/[0.06] text-white/72 transition hover:bg-white/[0.1] hover:text-white","aria-label":"Close metric chart",children:e.jsx($,{className:"size-5"})})})]}),e.jsxs("div",{className:"grid min-h-0 gap-4 overflow-y-auto p-4 sm:p-6 lg:grid-cols-[minmax(0,1fr)_18rem]",children:[e.jsx(k,{metric:a,height:560,detailed:!0}),e.jsx("div",{className:"grid content-start gap-3",children:[["Latest",a.latestValue],["Period min",i.minimum],["Period average",i.average],["Period max",i.maximum],["Baseline",a.baselineValue],["Delta",a.deltaValue]].map(([r,n])=>e.jsxs("div",{className:"rounded-[22px] border border-white/8 bg-white/[0.035] px-4 py-3",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/38",children:r}),e.jsx("div",{className:"mt-1 text-xl font-semibold text-white",children:d(a,typeof n=="number"?n:null)})]},String(r)))})]})]})]})]})})}function se(a){return a.deltaValue==null||a.deltaValue===0?"steady":a.deltaValue>0?"up":"down"}function g(a){switch(a){case"recovery":return{ring:"border-[rgba(255,122,167,0.18)]",badge:"bg-[rgba(255,122,167,0.16)] text-[rgb(255,179,205)]",glow:"from-[rgba(255,122,167,0.2)] via-[rgba(109,76,255,0.06)] to-transparent"};case"cardio":return{ring:"border-[rgba(109,173,255,0.22)]",badge:"bg-[rgba(109,173,255,0.16)] text-[rgb(186,220,255)]",glow:"from-[rgba(109,173,255,0.22)] via-[rgba(64,108,255,0.08)] to-transparent"};case"breathing":return{ring:"border-[rgba(111,232,195,0.2)]",badge:"bg-[rgba(111,232,195,0.15)] text-[rgb(195,255,237)]",glow:"from-[rgba(111,232,195,0.2)] via-[rgba(29,154,123,0.08)] to-transparent"};case"composition":return{ring:"border-[rgba(247,211,110,0.18)]",badge:"bg-[rgba(247,211,110,0.15)] text-[rgb(255,235,176)]",glow:"from-[rgba(247,211,110,0.18)] via-[rgba(184,128,24,0.08)] to-transparent"};case"temperature":return{ring:"border-[rgba(255,153,102,0.18)]",badge:"bg-[rgba(255,153,102,0.16)] text-[rgb(255,214,190)]",glow:"from-[rgba(255,153,102,0.2)] via-[rgba(255,91,46,0.06)] to-transparent"};case"conversationTone":return{ring:"border-[rgba(251,191,36,0.2)]",badge:"bg-[rgba(251,191,36,0.16)] text-[rgb(255,232,166)]",glow:"from-[rgba(251,191,36,0.18)] via-[rgba(244,114,182,0.08)] to-transparent"};default:return{ring:"border-[rgba(163,174,208,0.16)]",badge:"bg-[rgba(163,174,208,0.14)] text-[rgb(220,228,255)]",glow:"from-[rgba(163,174,208,0.14)] via-[rgba(112,120,167,0.06)] to-transparent"}}}function D(a){switch(a){case"restingHeartRate":case"walkingHeartRateAverage":case"heartRateRecoveryOneMinute":return z;case"heartRateVariabilitySDNN":case"vo2Max":return T;case"oxygenSaturation":case"respiratoryRate":return L;case"bodyMass":case"bodyFatPercentage":case"leanBodyMass":return P;case"stepCount":case"flightsClimbed":case"appleExerciseTime":return S;case"basalEnergyBurned":return _;case"swearingMessagePercent":return V;case"devrageSwearCount":return M;default:return j}}function oe({title:a,description:s,metric:t,emptyDescription:i}){const l=t?D(t.metric):j,r=g(t?t.category:"default"),n=t?se(t):"steady";return e.jsxs(v,{className:x("relative overflow-hidden rounded-[28px] border bg-[rgba(12,18,36,0.82)] p-5 shadow-[0_18px_60px_rgba(4,8,18,0.3)]",r.ring),children:[e.jsx("div",{className:x("pointer-events-none absolute inset-0 bg-gradient-to-br opacity-90",r.glow)}),e.jsxs("div",{className:"relative grid gap-4",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{className:"grid gap-1",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.18em] text-white/38",children:a}),e.jsx("div",{className:"text-sm leading-6 text-white/56",children:s})]}),e.jsx("div",{className:"rounded-[18px] border border-white/10 bg-white/[0.05] p-3 text-white/80",children:e.jsx(l,{className:"size-5"})})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx("div",{className:"text-xl font-semibold text-white",children:t?d(t,t.latestValue):"No signal yet"}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-xs text-white/56",children:[t?e.jsx(c,{className:r.badge,children:t.label}):null,t?e.jsx(c,{className:x("border-none",n==="up"?"bg-[rgba(111,232,195,0.14)] text-[rgb(190,255,231)]":n==="down"?"bg-[rgba(255,122,167,0.14)] text-[rgb(255,193,215)]":"bg-white/[0.08] text-white/72"),children:w(t)}):null,t?e.jsxs(c,{tone:"meta",children:[t.coverageDays," days tracked"]}):null]}),e.jsx("div",{className:"text-xs text-white/48",children:t?`Latest reading on ${m(t.latestDateKey)}`:i??"Forge will populate this card as soon as daily readings are available."})]})]})]})}function re({metric:a}){const[s,t]=u.useState(!1),i=D(a.metric),l=g(a.category),r=a.days.at(-1),n=b(a);return e.jsxs(v,{className:x("overflow-hidden rounded-[28px] border bg-[linear-gradient(180deg,rgba(12,18,36,0.94),rgba(8,12,24,0.98))] p-5",l.ring),children:[e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"flex items-start gap-4",children:[e.jsx("div",{className:"rounded-[18px] border border-white/10 bg-white/[0.04] p-3 text-white/84",children:e.jsx(i,{className:"size-5"})}),e.jsxs("div",{className:"grid gap-1",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/38",children:a.category}),e.jsx("div",{className:"text-xl font-semibold text-white",children:a.label}),e.jsxs("div",{className:"text-sm text-white/52",children:[a.coverageDays," tracked day",a.coverageDays===1?"":"s"]})]})]}),e.jsxs("div",{className:"flex shrink-0 flex-wrap items-center justify-end gap-2",children:[e.jsx(c,{className:l.badge,children:a.aggregation}),e.jsxs("button",{type:"button",className:"inline-flex min-h-9 items-center gap-2 rounded-full border border-white/10 bg-white/[0.055] px-3 py-1.5 text-xs font-medium text-white/72 transition hover:bg-white/[0.09] hover:text-white",onClick:()=>t(!0),children:[e.jsx(R,{className:"size-3.5"}),"Full screen"]})]})]}),e.jsxs("div",{className:"mt-5 grid gap-4 md:grid-cols-[minmax(0,0.95fr)_minmax(220px,1.05fr)]",children:[e.jsxs("div",{className:"grid gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/38",children:"Latest"}),e.jsx("div",{className:"mt-1 text-3xl font-semibold text-white",children:d(a,a.latestValue)}),e.jsx("div",{className:"mt-1 text-sm text-white/52",children:a.latestDateKey?`Latest reading on ${m(a.latestDateKey)}`:"Waiting for the first successful reading"})]}),e.jsxs("div",{className:"grid gap-2 rounded-[22px] border border-white/8 bg-white/[0.03] p-4 text-sm text-white/70",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{children:"Baseline"}),e.jsx("span",{className:"font-medium text-white",children:d(a,a.baselineValue)})]}),e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{children:"Delta"}),e.jsx("span",{className:x("font-medium",a.deltaValue==null?"text-white/58":a.deltaValue>0?"text-[rgb(190,255,231)]":a.deltaValue<0?"text-[rgb(255,198,219)]":"text-white"),children:w(a)})]}),e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{children:"Latest samples"}),e.jsx("span",{className:"font-medium text-white",children:(r==null?void 0:r.sampleCount)??0})]})]})]}),e.jsxs("div",{className:"grid gap-3",children:[e.jsx(k,{metric:a}),e.jsxs("div",{className:"grid grid-cols-3 gap-2 text-xs text-white/48",children:[e.jsxs("div",{className:"rounded-[16px] border border-white/8 bg-white/[0.025] px-3 py-2",children:[e.jsx("div",{children:"Period min"}),e.jsx("div",{className:"mt-1 font-medium text-white/78",children:d(a,n.minimum)})]}),e.jsxs("div",{className:"rounded-[16px] border border-white/8 bg-white/[0.025] px-3 py-2",children:[e.jsx("div",{children:"Period avg"}),e.jsx("div",{className:"mt-1 font-medium text-white/78",children:d(a,n.average)})]}),e.jsxs("div",{className:"rounded-[16px] border border-white/8 bg-white/[0.025] px-3 py-2",children:[e.jsx("div",{children:"Period max"}),e.jsx("div",{className:"mt-1 font-medium text-white/78",children:d(a,n.maximum)})]})]})]})]}),e.jsx(te,{metric:a,open:s,onOpenChange:t})]})}function ce({groups:a}){return e.jsx("section",{className:"grid gap-5",children:a.map(s=>e.jsxs("div",{className:"grid gap-4",children:[e.jsxs("div",{className:"flex flex-wrap items-end justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.18em] text-white/38",children:s.category}),e.jsxs("div",{className:"mt-1 text-2xl font-semibold text-white",children:[s.metrics.length," signals in this lane"]})]}),e.jsxs(c,{className:g(s.category).badge,children:[s.coverageDays," days of coverage"]})]}),e.jsx("div",{className:"grid gap-4 xl:grid-cols-2",children:s.metrics.map(t=>e.jsx(re,{metric:t},t.metric))})]},s.category))})}export{ce as M,oe as S,m as f,g as m};
@@ -1 +0,0 @@
1
- import{b5 as l,j as i,aS as x}from"./vendor-DHkYh85p.js";import{ap as f,cQ as h}from"./index-CF4J4R9L.js";function g({entityType:s,entityId:a,count:r,compact:o=!1,className:p=""}){const n=l(),e=f(s,a);return e?i.jsxs("span",{role:"link",tabIndex:0,className:`inline-flex items-center rounded-full border border-white/10 bg-white/[0.05] text-white/72 transition hover:bg-white/[0.09] hover:text-white ${o?"min-h-5 gap-1 px-2 py-0.5 text-[10px]":"min-h-10 gap-2 px-3 py-2 text-xs"} ${p}`,onClick:t=>{t.stopPropagation(),n(e)},onKeyDown:t=>{(t.key==="Enter"||t.key===" ")&&(t.preventDefault(),t.stopPropagation(),n(e))},children:[i.jsx(x,{className:o?"size-3":"size-3.5"}),h(r)]}):null}export{g as E};
@@ -1 +0,0 @@
1
- import{r as l,j as e,b4 as $e,b3 as We,cR as Ke,ce as Xe,c7 as Pe}from"./vendor-DHkYh85p.js";import{j as Ye,i as x,k as X}from"./state-B-4sS1xO.js";import{u as Ze,bv as Y,cP as et,cq as m,ao as tt,bm as st,bn as at,C as it,aq as nt,c as j,cQ as rt,B as y,I as w,T as ze,bu as f,i as lt,bD as ot,bw as dt,bx as ct,by as mt,bz as ut,bA as pt,bB as ht,bC as xt}from"./index-CF4J4R9L.js";import{N as Z}from"./note-markdown-N-uxD3Xt.js";import{n as ee,N as Fe,f as yt,p as gt,b as vt}from"./note-tags-input-Cdu7wiw6.js";function bt(o,d,c){return o.links.filter(p=>!(p.entityType===d&&p.entityId===c))}function jt(o,d){return o.entityType===d.entityType&&o.entityId===d.entityId&&(o.anchorKey??null)===(d.anchorKey??null)}function te(o){const d=new Set;return o.filter(c=>{const p=`${c.entityType}:${c.entityId}:${c.anchorKey??""}`;return d.has(p)?!1:(d.add(p),!0)})}function Me(o,d,c){return gt(o)??vt(d,c)}function St({entityType:o,entityId:d,anchorKey:c,includeAnchorlessWhenAnchored:p=!1,title:Qe="Notes",description:Be="Markdown notes linked to this entity stay searchable, editable, and visible alongside the work.",invalidateQueryKeys:Ve=[],compact:se=!1}){var Se,De,_e,Te,Le,Ie,Ee,qe,Ae;const u=Ze(),L=Ye(),[I,Oe]=l.useState(""),[ae,E]=l.useState(!1),[v,q]=l.useState(""),[ie,A]=l.useState(!1),[Ue,$]=l.useState({entityType:"goal",entityId:""}),[ne,K]=l.useState([]),[re,P]=l.useState([]),[le,z]=l.useState(""),[oe,F]=l.useState(""),[de,M]=l.useState("days"),[He,Q]=l.useState(null),[b,B]=l.useState(""),[ce,N]=l.useState(!1),[V,O]=l.useState([]),[Re,U]=l.useState({entityType:"goal",entityId:""}),[me,k]=l.useState([]),[ue,C]=l.useState(""),[pe,S]=l.useState(""),[he,D]=l.useState("days"),H=Y(c),xe=et(o,c),g=x({queryKey:["notes",o,d],queryFn:()=>ot({linkedEntityType:o,linkedEntityId:d,limit:100})}),ye=x({queryKey:["forge-psyche-values"],queryFn:dt}),ge=x({queryKey:["forge-psyche-patterns"],queryFn:ct}),ve=x({queryKey:["forge-psyche-behaviors"],queryFn:mt}),be=x({queryKey:["forge-psyche-beliefs"],queryFn:ut}),je=x({queryKey:["forge-psyche-modes"],queryFn:pt}),we=x({queryKey:["forge-psyche-flashcards"],queryFn:ht}),fe=x({queryKey:["forge-psyche-reports"],queryFn:xt}),R=l.useMemo(()=>{var t,r,i,a,h,n,_,T;return{goal:u.snapshot.goals.map(s=>({id:s.id,label:m(s.title,s.user)})),project:u.snapshot.dashboard.projects.map(s=>({id:s.id,label:m(s.title,s.user)})),task:u.snapshot.tasks.map(s=>({id:s.id,label:m(s.title,s.user)})),strategy:u.snapshot.strategies.map(s=>({id:s.id,label:m(s.title,s.user)})),habit:u.snapshot.habits.map(s=>({id:s.id,label:m(s.title,s.user)})),tag:u.snapshot.tags.map(s=>({id:s.id,label:m(s.name,s.user)})),note:(((t=g.data)==null?void 0:t.notes)??[]).map(s=>({id:s.id,label:s.contentPlain||s.contentMarkdown})),insight:[],psyche_value:(((r=ye.data)==null?void 0:r.values)??[]).map(s=>({id:s.id,label:m(s.title,s.user)})),behavior_pattern:(((i=ge.data)==null?void 0:i.patterns)??[]).map(s=>({id:s.id,label:m(s.title,s.user)})),behavior:(((a=ve.data)==null?void 0:a.behaviors)??[]).map(s=>({id:s.id,label:m(s.title,s.user)})),belief_entry:(((h=be.data)==null?void 0:h.beliefs)??[]).map(s=>({id:s.id,label:m(s.statement,s.user)})),mode_profile:(((n=je.data)==null?void 0:n.modes)??[]).map(s=>({id:s.id,label:m(s.title,s.user)})),flashcard:(((_=we.data)==null?void 0:_.flashcards)??[]).map(s=>({id:s.id,label:m(s.title||s.message,s.user)})),mode_guide_session:[],event_type:[],emotion_definition:[],trigger_report:(((T=fe.data)==null?void 0:T.reports)??[]).map(s=>({id:s.id,label:m(s.title,s.user)})),calendar_event:[],work_block_template:[],task_timebox:[],preference_catalog:[],preference_catalog_item:[],preference_context:[],preference_item:[],questionnaire_instrument:[],sleep_session:[],workout_session:[]}},[(Se=ve.data)==null?void 0:Se.behaviors,(De=be.data)==null?void 0:De.beliefs,(_e=we.data)==null?void 0:_e.flashcards,(Te=je.data)==null?void 0:Te.modes,(Le=g.data)==null?void 0:Le.notes,(Ie=ge.data)==null?void 0:Ie.patterns,(Ee=fe.data)==null?void 0:Ee.reports,u.snapshot.dashboard.projects,u.snapshot.goals,u.snapshot.habits,u.snapshot.strategies,u.snapshot.tags,u.snapshot.tasks,(qe=ye.data)==null?void 0:qe.values]),G=async()=>{await Promise.all([L.invalidateQueries({queryKey:["notes",o,d]}),lt(L),...Ve.map(t=>L.invalidateQueries({queryKey:t}))])},Ne=X({mutationFn:async t=>tt({contentMarkdown:t,tags:ee(re),destroyAt:Me(le,oe,de),links:te([{entityType:o,entityId:d,anchorKey:c??null},...ne])}),onSuccess:async()=>{q(""),A(!1),K([]),$({entityType:"goal",entityId:""}),P([]),z(""),F(""),M("days"),await G()}}),ke=X({mutationFn:async({noteId:t,contentMarkdown:r,links:i,tags:a,destroyAt:h})=>st(t,{contentMarkdown:r,links:i,tags:a,destroyAt:h}),onSuccess:async()=>{Q(null),B(""),N(!1),O([]),U({entityType:"goal",entityId:""}),k([]),C(""),S(""),D("days"),await G()}}),Ge=X({mutationFn:async t=>at(t),onSuccess:G}),J=l.useMemo(()=>{var r;return(((r=g.data)==null?void 0:r.notes)??[]).filter(i=>c===void 0?!0:i.links.some(a=>a.entityType===o&&a.entityId===d&&((a.anchorKey??null)===c||p&&(a.anchorKey??null)===null))).filter(i=>{const a=I.trim().toLowerCase();return a?`${i.contentPlain} ${i.author??""} ${(i.tags??[]).join(" ")}`.toLowerCase().includes(a):!0})},[c,d,o,p,(Ae=g.data)==null?void 0:Ae.notes,I]),Je=(t,r,i)=>{const a=t.entityId.trim();return a?(r(te([...i,{entityType:t.entityType,entityId:a,anchorKey:null}])),!0):!1},W=t=>{var i,a;const r=(i=R[t.entityType])==null?void 0:i.find(h=>h.id===t.entityId);return(a=r==null?void 0:r.label)!=null&&a.trim()?r.label.trim():`Deleted ${f(t.entityType)}`},Ce=(t,r,i,a,h)=>e.jsxs("div",{className:"rounded-[20px] bg-white/[0.03] p-4",children:[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/38",children:"Linked entities"}),e.jsxs(j,{className:"bg-white/[0.08] text-white/68",children:[t.length," linked"]})]}),e.jsx("div",{className:"mt-3 flex flex-wrap gap-2",children:t.map(n=>{const _=t.length>1;return e.jsxs("div",{className:"inline-flex items-center gap-2 rounded-full bg-white/[0.08] px-3 py-2 text-sm text-white/72",children:[e.jsxs("span",{children:[f(n.entityType)," · ",W(n)]}),n.anchorKey?e.jsx("span",{className:"rounded-full bg-white/[0.08] px-2 py-0.5 text-[11px] text-white/54",children:Y(n.anchorKey)}):null,e.jsx("button",{type:"button",disabled:!_,className:"text-white/44 transition hover:text-white disabled:cursor-not-allowed disabled:opacity-30",onClick:()=>r(t.filter(T=>!jt(T,n))),"aria-label":`Remove ${f(n.entityType)} link to ${W(n)}`,children:e.jsx(Pe,{className:"size-3.5"})})]},`${h}-${n.entityType}-${n.entityId}-${n.anchorKey??""}`)})}),e.jsxs("div",{className:"mt-4 grid gap-3 md:grid-cols-[minmax(0,11rem)_minmax(0,1fr)_auto]",children:[e.jsx("select",{className:"rounded-[14px] bg-white/[0.06] px-3 py-3 text-white",value:i.entityType,onChange:n=>a({...i,entityType:n.target.value,entityId:""}),children:["goal","project","task","strategy","habit","tag","note","psyche_value","behavior_pattern","behavior","belief_entry","mode_profile","mode_guide_session","flashcard","event_type","emotion_definition","trigger_report"].map(n=>e.jsx("option",{value:n,children:f(n)},n))}),e.jsxs("select",{className:"min-w-0 rounded-[14px] bg-white/[0.06] px-3 py-3 text-white",value:i.entityId,onChange:n=>a({...i,entityId:n.target.value}),children:[e.jsx("option",{value:"",children:(R[i.entityType]??[]).length>0?"Choose linked item":"No linked items available"}),(R[i.entityType]??[]).map(n=>e.jsx("option",{value:n.id,children:n.label},n.id))]}),e.jsx(y,{variant:"secondary",disabled:!i.entityId,onClick:()=>{Je(i,r,t)&&a({...i,entityId:""})},children:"Add link"})]})]});return e.jsx(it,{id:"notes",className:se?"min-w-0 overflow-hidden p-0":"min-w-0 overflow-hidden",children:e.jsxs("div",{className:se?"p-4":void 0,children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:Qe}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-white/60",children:Be}),H?e.jsxs("div",{className:"mt-3 inline-flex items-center gap-2 rounded-full bg-white/[0.05] px-3 py-2 text-xs text-white/64",children:[e.jsxs("span",{children:["Pinned to ",H]}),xe?e.jsx(nt,{content:xe,label:`Explain ${H}`}):null]}):null]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(j,{className:"bg-white/[0.08] text-white/72",children:rt(J.length)}),ae?null:e.jsxs(y,{type:"button",size:"sm",onClick:()=>E(!0),children:[e.jsx($e,{className:"size-4"}),"Add note"]})]})]}),e.jsxs("div",{className:"mt-4 flex items-center gap-2 rounded-[22px] border border-white/8 bg-white/[0.04] px-3 py-3",children:[e.jsx(We,{className:"size-4 text-white/34"}),e.jsx(w,{value:I,onChange:t=>Oe(t.target.value),placeholder:"Search notes by content, author, or note tag",className:"border-0 bg-transparent px-0 py-0"})]}),ae?e.jsxs("div",{className:"mt-4 rounded-[24px] border border-white/8 bg-white/[0.04] p-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm text-white/70",children:[e.jsx($e,{className:"size-4 text-[var(--secondary)]"}),"Add note"]}),e.jsxs(y,{type:"button",variant:"secondary",size:"sm",className:"gap-2",onClick:()=>A(t=>!t),children:[e.jsx(Ke,{className:"size-4"}),ie?"Back to editor":"Preview"]})]}),e.jsx("div",{className:"mt-3",children:ie?e.jsxs("div",{className:"rounded-[20px] bg-[rgba(9,14,25,0.78)] p-4",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/38",children:"Preview"}),e.jsx("div",{className:"mt-3",children:v.trim()?e.jsx(Z,{markdown:v}):e.jsx("div",{className:"text-sm leading-6 text-white/42",children:"Markdown preview appears here once you have note content."})})]}):e.jsx(ze,{value:v,onChange:t=>q(t.target.value),placeholder:"Write in Markdown. Summaries, blockers, what changed, and why all work well here.",className:"min-h-[12rem]"})}),e.jsx("div",{className:"mt-3",children:Ce(te([{entityType:o,entityId:d,anchorKey:c??null},...ne]),t=>K(t.filter(r=>!(r.entityType===o&&r.entityId===d&&(r.anchorKey??null)===(c??null)))),Ue,$,"composer-note-links")}),e.jsxs("div",{className:"mt-3 grid gap-3 lg:grid-cols-[minmax(0,1.15fr)_minmax(0,0.85fr)]",children:[e.jsx(Fe,{value:re,onChange:P}),e.jsxs("div",{className:"grid gap-3 rounded-[20px] bg-white/[0.03] p-4",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/38",children:"Ephemeral auto-destroy"}),e.jsx("div",{className:"mt-2 text-xs leading-5 text-white/46",children:"Set an exact destroy time or a relative delay. Leaving both blank keeps the note durable."})]}),e.jsx(w,{type:"datetime-local",value:le,onChange:t=>z(t.target.value)}),e.jsxs("div",{className:"grid gap-3 md:grid-cols-[minmax(0,1fr)_10rem]",children:[e.jsx(w,{type:"number",min:"1",value:oe,onChange:t=>F(t.target.value),placeholder:"Destroy after"}),e.jsxs("select",{className:"rounded-[14px] border border-white/10 bg-white/[0.04] px-3 py-3 text-sm text-white",value:de,onChange:t=>M(t.target.value),children:[e.jsx("option",{value:"hours",children:"Hours"}),e.jsx("option",{value:"days",children:"Days"})]})]})]})]}),e.jsxs("div",{className:"mt-3 flex flex-wrap justify-end gap-2",children:[e.jsx(y,{type:"button",variant:"secondary",onClick:()=>{E(!1),A(!1),q(""),K([]),$({entityType:"goal",entityId:""}),P([]),z(""),F(""),M("days")},children:"Cancel"}),e.jsx(y,{pending:Ne.isPending,pendingLabel:"Saving",disabled:v.trim().length===0,onClick:async()=>{await Ne.mutateAsync(v.trim()),E(!1)},children:"Save note"})]})]}):null,e.jsxs("div",{className:"mt-4 grid gap-3",children:[g.isLoading?e.jsx("div",{className:"rounded-[20px] bg-white/[0.04] p-4 text-sm text-white/56",children:"Loading notes…"}):null,!g.isLoading&&J.length===0?e.jsx("div",{className:"rounded-[20px] bg-white/[0.04] p-4 text-sm text-white/56",children:"No notes are linked here yet."}):null,J.map(t=>{const r=He===t.id,i=bt(t,o,d);return e.jsxs("article",{className:"rounded-[24px] border border-white/8 bg-white/[0.04] p-4",children:[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:"text-xs uppercase tracking-[0.16em] text-white/38",children:[(t.author??"Unknown author").toString()," •"," ",new Date(t.updatedAt).toLocaleString()]}),e.jsxs("div",{className:"mt-2 flex flex-wrap gap-2",children:[i.map(a=>e.jsxs(j,{className:"bg-white/[0.08] text-white/68",wrap:!0,children:[f(a.entityType)," ·"," ",W(a),a.anchorKey?` · ${Y(a.anchorKey)}`:""]},`${t.id}-${a.entityType}-${a.entityId}-${a.anchorKey??""}`)),(t.tags??[]).map(a=>e.jsx(j,{className:"bg-cyan-400/10 text-cyan-50",wrap:!0,children:a},`${t.id}-tag-${a}`)),t.destroyAt?e.jsxs(j,{className:"bg-amber-400/10 text-amber-100",wrap:!0,children:["Ephemeral · deletes"," ",new Date(t.destroyAt).toLocaleString()]}):null]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("button",{type:"button",className:"inline-flex size-9 items-center justify-center rounded-full bg-white/[0.06] text-white/60 transition hover:bg-white/[0.1] hover:text-white",onClick:()=>{Q(t.id),B(t.contentMarkdown),N(!1),O(t.links),U({entityType:"goal",entityId:""}),k(ee(t.tags??[])),C(yt(t.destroyAt??null)),S(""),D("days")},children:e.jsx(Xe,{className:"size-4"})}),e.jsx("button",{type:"button",className:"inline-flex size-9 items-center justify-center rounded-full bg-rose-500/10 text-rose-200 transition hover:bg-rose-500/16",onClick:()=>{Ge.mutateAsync(t.id)},children:e.jsx(Pe,{className:"size-4"})})]})]}),r?e.jsxs("div",{className:"mt-4",children:[e.jsx("div",{className:"flex flex-wrap items-center justify-end gap-2",children:e.jsxs(y,{type:"button",variant:"secondary",size:"sm",className:"gap-2",onClick:()=>N(a=>!a),children:[e.jsx(Ke,{className:"size-4"}),ce?"Back to editor":"Preview"]})}),e.jsx("div",{className:"mt-3",children:ce?e.jsxs("div",{className:"rounded-[20px] bg-[rgba(9,14,25,0.78)] p-4",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/38",children:"Preview"}),e.jsx("div",{className:"mt-3",children:b.trim()?e.jsx(Z,{markdown:b}):e.jsx("div",{className:"text-sm text-white/42",children:"No content yet."})})]}):e.jsx(ze,{value:b,onChange:a=>B(a.target.value),className:"min-h-[12rem]"})}),e.jsxs("div",{className:"mt-3 grid gap-3 lg:grid-cols-[minmax(0,1.15fr)_minmax(0,0.85fr)]",children:[e.jsx(Fe,{value:me,onChange:k}),e.jsxs("div",{className:"grid gap-3 rounded-[20px] bg-white/[0.03] p-4",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/38",children:"Ephemeral auto-destroy"}),e.jsx("div",{className:"mt-2 text-xs leading-5 text-white/46",children:"Set an exact destroy time or a relative delay. Leaving both blank keeps the note durable."})]}),e.jsx(w,{type:"datetime-local",value:ue,onChange:a=>C(a.target.value)}),e.jsxs("div",{className:"grid gap-3 md:grid-cols-[minmax(0,1fr)_10rem]",children:[e.jsx(w,{type:"number",min:"1",value:pe,onChange:a=>S(a.target.value),placeholder:"Destroy after"}),e.jsxs("select",{className:"rounded-[14px] border border-white/10 bg-white/[0.04] px-3 py-3 text-sm text-white",value:he,onChange:a=>D(a.target.value),children:[e.jsx("option",{value:"hours",children:"Hours"}),e.jsx("option",{value:"days",children:"Days"})]})]})]})]}),e.jsx("div",{className:"mt-3",children:Ce(V,O,Re,U,`edit-note-links-${t.id}`)}),e.jsxs("div",{className:"mt-3 flex flex-wrap justify-end gap-2",children:[e.jsx(y,{variant:"secondary",onClick:()=>{Q(null),N(!1),k([]),C(""),S(""),D("days")},children:"Cancel"}),e.jsx(y,{pending:ke.isPending,pendingLabel:"Saving",disabled:b.trim().length===0||V.length===0,onClick:async()=>{await ke.mutateAsync({noteId:t.id,contentMarkdown:b.trim(),links:V,tags:ee(me),destroyAt:Me(ue,pe,he)})},children:"Save changes"})]})]}):e.jsx("div",{className:"mt-4",children:e.jsx(Z,{markdown:t.contentMarkdown})})]},t.id)})]})]})})}export{St as E};