forge-openclaw-plugin 0.2.100 → 0.2.102

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (189) hide show
  1. package/dist/assets/{activity-page-5oyCFOns.js → activity-page-CgF7K2ww.js} +1 -1
  2. package/dist/assets/ai-surface-workspace-xtB5RFQu.js +1 -0
  3. package/dist/assets/atlas-panel-B3dPHCmZ.js +1 -0
  4. package/dist/assets/{board-BkDRaMp6.js → board-DqHzdCPQ.js} +1 -1
  5. package/dist/assets/{calendar-page-Bo2iua-a.js → calendar-page-C1Wfd2Fy.js} +1 -1
  6. package/dist/assets/{calendar-rules-DA1g3QUk.js → calendar-rules-CaZXtlxt.js} +1 -1
  7. package/dist/assets/calendar-week-toolbar-BZ_-X3Wb.js +1 -0
  8. package/dist/assets/{charts-P7EVhIog.js → charts-FcU0F3XV.js} +8 -8
  9. package/dist/assets/{companion-sync-lab-page-CosNknOK.js → companion-sync-lab-page-NgeK-O-P.js} +1 -1
  10. package/dist/assets/daily-metrics-dashboard-BMyL0Qr4.js +1 -0
  11. package/dist/assets/{entity-note-count-link-BmGDB572.js → entity-note-count-link-BrS1-O0o.js} +1 -1
  12. package/dist/assets/entity-notes-surface-CBylYDwy.js +1 -0
  13. package/dist/assets/{execution-board-CDRXQB85.js → execution-board-CpO2ch6v.js} +1 -1
  14. package/dist/assets/faceted-token-search-D7xPWfOl.js +1 -0
  15. package/dist/assets/flagship-signal-deck-BEFKOhvx.js +1 -0
  16. package/dist/assets/{floating-action-menu-CJkI2iFy.js → floating-action-menu-zzC2r0Ob.js} +1 -1
  17. package/dist/assets/{forms-BFlTgZ3W.js → forms-CmLAyGqz.js} +1 -1
  18. package/dist/assets/{goal-detail-page-cJvHaLMQ.js → goal-detail-page-JK_Nva8e.js} +1 -1
  19. package/dist/assets/goals-page-yeoJ06Vw.js +1 -0
  20. package/dist/assets/{graph-D6JLqDbD.js → graph-BTa79qum.js} +14 -14
  21. package/dist/assets/{habits-page-DKb96_mj.js → habits-page-Dx5EhkJi.js} +1 -1
  22. package/dist/assets/index-BHIKoiZ6.js +19 -0
  23. package/dist/assets/index-H8R-ABM3.css +1 -0
  24. package/dist/assets/insight-flow-dialog-BtIQXXsS.js +1 -0
  25. package/dist/assets/{insights-page-Dc9oFltJ.js → insights-page-CujrosD_.js} +1 -1
  26. package/dist/assets/{kanban-page-JAxerYh6.js → kanban-page-Q9NuIz5w.js} +1 -1
  27. package/dist/assets/knowledge-graph-page-DaJmlvvM.js +1 -0
  28. package/dist/assets/{life-force-page-BGDbQuVh.js → life-force-page-BGDkKfbJ.js} +1 -1
  29. package/dist/assets/{life-force-workspace-B1fYSXRC.js → life-force-workspace-CLVexVnb.js} +1 -1
  30. package/dist/assets/{maps-ClgJoCjz.js → maps-CF1RagUX.js} +1 -1
  31. package/dist/assets/metric-tile-4iMd_WnJ.js +1 -0
  32. package/dist/assets/{motion-BeD44FeG.js → motion-CfdU2F35.js} +1 -1
  33. package/dist/assets/movement-page-ClaoTNuX.js +1 -0
  34. package/dist/assets/note-markdown-CsGQhQXF.js +3 -0
  35. package/dist/assets/note-tags-input-DdZi93tj.js +1 -0
  36. package/dist/assets/notes-page-DYI8s3NN.js +1 -0
  37. package/dist/assets/{open-in-graph-button-Cg5VrKsC.js → open-in-graph-button-C0TGev7c.js} +1 -1
  38. package/dist/assets/orbit-map-DVXkfQdd.js +1 -0
  39. package/dist/assets/overview-page-BwMlFQKX.js +1 -0
  40. package/dist/assets/page-hero-oFHaAjtL.js +1 -0
  41. package/dist/assets/pill-cluster-7UZd_lHp.js +1 -0
  42. package/dist/assets/{preference-entity-handoff-button-D4WAs9pC.js → preference-entity-handoff-button-DOKV9bZc.js} +1 -1
  43. package/dist/assets/preferences-page-BrKEkmfD.js +1 -0
  44. package/dist/assets/{project-collections-DvaX20q_.js → project-collections-CZagCmeH.js} +1 -1
  45. package/dist/assets/{project-detail-page-drPIFZGb.js → project-detail-page-DogvVNEn.js} +1 -1
  46. package/dist/assets/{project-management-hierarchy-page-BUbRXvny.js → project-management-hierarchy-page-Dr7hW9PW.js} +1 -1
  47. package/dist/assets/{project-management-section-nav-C2Ud8Zdd.js → project-management-section-nav-BLdAgTge.js} +1 -1
  48. package/dist/assets/{projects-page-BGzEZUtg.js → projects-page-UKrby_5-.js} +1 -1
  49. package/dist/assets/psyche-behaviors-page-BeVlXvbj.js +5 -0
  50. package/dist/assets/psyche-flashcards-page-CqAWCO4E.js +1 -0
  51. package/dist/assets/psyche-goal-map-page-IyNnbk_W.js +1 -0
  52. package/dist/assets/psyche-graph-IkUQRaDK.js +1 -0
  53. package/dist/assets/{psyche-metrics-page-zYTJDbyZ.js → psyche-metrics-page-uai0a7Lx.js} +1 -1
  54. package/dist/assets/psyche-mode-guide-page-C7p-ABiF.js +1 -0
  55. package/dist/assets/psyche-modes-page-CLQ5V3w0.js +1 -0
  56. package/dist/assets/psyche-page-NQBHkkpU.js +1 -0
  57. package/dist/assets/psyche-patterns-page-BkRiNpI_.js +5 -0
  58. package/dist/assets/psyche-questionnaire-builder-page-Du-7HwPC.js +1 -0
  59. package/dist/assets/psyche-questionnaire-detail-page-C5-yf8MF.js +1 -0
  60. package/dist/assets/psyche-questionnaire-run-detail-page-CoSH5O6R.js +1 -0
  61. package/dist/assets/psyche-questionnaire-run-page-ChI7c1wy.js +1 -0
  62. package/dist/assets/psyche-questionnaires-page-xUcJJzbI.js +1 -0
  63. package/dist/assets/psyche-report-detail-page-BPrZCFZS.js +3 -0
  64. package/dist/assets/psyche-reports-page-D2EXJmm6.js +1 -0
  65. package/dist/assets/{psyche-schemas-HFmg37Wj.js → psyche-schemas-RcZYaokx.js} +1 -1
  66. package/dist/assets/psyche-schemas-beliefs-page-h0ooZ1lp.js +9 -0
  67. package/dist/assets/psyche-screen-time-page-_3-4LikV.js +1 -0
  68. package/dist/assets/psyche-self-observation-page-BdbCsgR5.js +1 -0
  69. package/dist/assets/psyche-values-page-DuUVki5e.js +5 -0
  70. package/dist/assets/report-chain-fields-BBMz0sGI.js +1 -0
  71. package/dist/assets/{rewards-page-C2HQjIAf.js → rewards-page-PZFPa6rR.js} +1 -1
  72. package/dist/assets/{scheduling-rules-editor-BHOpHOrV.js → scheduling-rules-editor-B9KNKsQz.js} +1 -1
  73. package/dist/assets/schema-badge-D93RcG36.js +1 -0
  74. package/dist/assets/schema-visuals-CvC9a3i6.js +1 -0
  75. package/dist/assets/select-menu-Cdq7foRu.js +1 -0
  76. package/dist/assets/{settings-agents-page-VuYXTiyc.js → settings-agents-page-DPx2F6wf.js} +3 -3
  77. package/dist/assets/{settings-bin-page-BNzvYaOk.js → settings-bin-page-COwP3gjo.js} +1 -1
  78. package/dist/assets/settings-calendar-page-C-ghE0YT.js +5 -0
  79. package/dist/assets/{settings-data-page-CGSlryuI.js → settings-data-page-CBubzKBw.js} +1 -1
  80. package/dist/assets/{settings-logs-page-BTK5fine.js → settings-logs-page-uOuXMeBm.js} +1 -1
  81. package/dist/assets/{settings-mobile-page-CRaObOGo.js → settings-mobile-page-C5rfj8_r.js} +1 -1
  82. package/dist/assets/settings-models-page-DijmUWdU.js +1 -0
  83. package/dist/assets/{settings-page-BP81Mb5R.js → settings-page-B4u5TR5g.js} +1 -1
  84. package/dist/assets/{settings-rewards-page-CDJ1PH2G.js → settings-rewards-page-COiTwkMH.js} +1 -1
  85. package/dist/assets/{settings-section-nav-CCFm27r2.js → settings-section-nav-Dc4IeVBt.js} +1 -1
  86. package/dist/assets/{settings-users-page-TdUocFPa.js → settings-users-page-DEGa5DNn.js} +1 -1
  87. package/dist/assets/settings-wiki-page-Cvsiz5_e.js +1 -0
  88. package/dist/assets/{sleep-page-cI1GMVzk.js → sleep-page-BnSOwkEU.js} +1 -1
  89. package/dist/assets/{sports-page-06LTqp0V.js → sports-page-l1RqXzA_.js} +1 -1
  90. package/dist/assets/{state-B-4sS1xO.js → state-VYvD1QVP.js} +1 -1
  91. package/dist/assets/{strategies-page-DXP9Kx8s.js → strategies-page-DEnPlpAs.js} +1 -1
  92. package/dist/assets/{strategy-detail-page-D6mx_Mik.js → strategy-detail-page-Ls8bxKeH.js} +1 -1
  93. package/dist/assets/strategy-dialog-DMyRKrWf.js +1 -0
  94. package/dist/assets/surface-Bfz_sLX6.js +1 -0
  95. package/dist/assets/{table-WfAPUppN.js → table-C0VTeqw0.js} +1 -1
  96. package/dist/assets/task-detail-page-CgrYgQLD.js +1 -0
  97. package/dist/assets/{timebox-planning-dialog-CaCnoslG.js → timebox-planning-dialog-Ww0NGLLo.js} +1 -1
  98. package/dist/assets/today-page-CIuFHMi1.js +1 -0
  99. package/dist/assets/training-load-page-BIwc648i.js +1 -0
  100. package/dist/assets/{ui-C13Nbgas.js → ui-CsEkP2V8.js} +4 -4
  101. package/dist/assets/use-psyche-focus-target-qxT5Oy_z.js +1 -0
  102. package/dist/assets/{vendor-DHkYh85p.js → vendor-kIz9EZnX.js} +237 -222
  103. package/dist/assets/{vitals-page-BQvEjTc6.js → vitals-page-Dz1Jt5H8.js} +1 -1
  104. package/dist/assets/{weekly-review-page-Tp6Q9CRj.js → weekly-review-page-BFpBe1kI.js} +1 -1
  105. package/dist/assets/weight-loss-page-BgMoBpBt.js +5 -0
  106. package/dist/assets/{wiki-article-markdown-DQYohmW2.js → wiki-article-markdown-gsPTXTg1.js} +1 -1
  107. package/dist/assets/{wiki-editor-page-Dem_3eZv.js → wiki-editor-page-BpAZHooY.js} +7 -7
  108. package/dist/assets/{wiki-ingest-history-page-BxoOcCoJ.js → wiki-ingest-history-page-C-ig8O22.js} +1 -1
  109. package/dist/assets/{wiki-ingest-modal-DhguKk3J.js → wiki-ingest-modal-BK4eQgqs.js} +1 -1
  110. package/dist/assets/{wiki-page-BLRxVXkl.js → wiki-page-CMTZ60Zt.js} +1 -1
  111. package/dist/assets/workbench-flow-page-BIpWUcLJ.js +5 -0
  112. package/dist/assets/workbench-page-CtCjYSRe.js +1 -0
  113. package/dist/assets/workout-detail-page-DD9IGN6l.js +2 -0
  114. package/dist/index.html +9 -9
  115. package/dist/openclaw/local-runtime.js +41 -14
  116. package/dist/server/server/migrations/067_weight_loss_daily_active_overrides.sql +13 -0
  117. package/dist/server/server/src/app.js +103 -30
  118. package/dist/server/server/src/health-weight-loss.js +457 -55
  119. package/dist/server/server/src/health.js +12 -4
  120. package/dist/server/server/src/movement.js +84 -1
  121. package/dist/server/server/src/openapi.js +123 -18
  122. package/dist/server/server/src/repositories/model-settings.js +12 -9
  123. package/dist/server/server/src/repositories/settings.js +19 -5
  124. package/dist/server/server/src/watch-mobile.js +22 -10
  125. package/dist/server/src/components/ui/info-tooltip.js +6 -6
  126. package/dist/server/src/lib/api.js +14 -4
  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/ai-surface-workspace-qgk_B57-.js +0 -1
  134. package/dist/assets/atlas-panel-rfH2qOez.js +0 -1
  135. package/dist/assets/calendar-week-toolbar-DU1Q4RYj.js +0 -1
  136. package/dist/assets/daily-metrics-dashboard-LjuGAB3f.js +0 -1
  137. package/dist/assets/entity-notes-surface-DgEgicaE.js +0 -1
  138. package/dist/assets/faceted-token-search-CE1YauRd.js +0 -1
  139. package/dist/assets/flagship-signal-deck-DDds90Gl.js +0 -1
  140. package/dist/assets/goals-page-f_39hvUV.js +0 -1
  141. package/dist/assets/index-BHTUu_4M.js +0 -19
  142. package/dist/assets/index-CZbuZQjw.css +0 -1
  143. package/dist/assets/insight-flow-dialog-pzAzyayN.js +0 -1
  144. package/dist/assets/knowledge-graph-page-UQ3skqEi.js +0 -1
  145. package/dist/assets/metric-tile-DX6TclqM.js +0 -1
  146. package/dist/assets/movement-page-6HP6nGJx.js +0 -1
  147. package/dist/assets/note-markdown-DiW2-5d3.js +0 -3
  148. package/dist/assets/note-tags-input-DDLXf54U.js +0 -1
  149. package/dist/assets/notes-page-BuguDjhz.js +0 -1
  150. package/dist/assets/orbit-map-GD05-0oS.js +0 -1
  151. package/dist/assets/overview-page-DuOs2OCB.js +0 -1
  152. package/dist/assets/page-hero-CQWo1Mm_.js +0 -1
  153. package/dist/assets/pill-cluster-BJogDRDJ.js +0 -1
  154. package/dist/assets/preferences-page-BaJTMU1I.js +0 -1
  155. package/dist/assets/psyche-behaviors-page-Dmm_Io9D.js +0 -5
  156. package/dist/assets/psyche-flashcards-page-BgNKJ6QJ.js +0 -1
  157. package/dist/assets/psyche-goal-map-page-DXJs98Vr.js +0 -1
  158. package/dist/assets/psyche-graph-CFgs_Bqc.js +0 -1
  159. package/dist/assets/psyche-mode-guide-page-XPgRfCOf.js +0 -1
  160. package/dist/assets/psyche-modes-page-B-GA8oRF.js +0 -1
  161. package/dist/assets/psyche-page--r6a3e1t.js +0 -1
  162. package/dist/assets/psyche-patterns-page-BM5-3bMm.js +0 -5
  163. package/dist/assets/psyche-questionnaire-builder-page-CJshQ-mg.js +0 -1
  164. package/dist/assets/psyche-questionnaire-detail-page-USmR5G5A.js +0 -1
  165. package/dist/assets/psyche-questionnaire-run-detail-page-D7iBCmTi.js +0 -1
  166. package/dist/assets/psyche-questionnaire-run-page-Cpil-kDh.js +0 -1
  167. package/dist/assets/psyche-questionnaires-page-C-_y3VwS.js +0 -1
  168. package/dist/assets/psyche-report-detail-page--dkSPRaj.js +0 -3
  169. package/dist/assets/psyche-reports-page-CUaOXmIN.js +0 -1
  170. package/dist/assets/psyche-schemas-beliefs-page-BX6xaap3.js +0 -9
  171. package/dist/assets/psyche-screen-time-page-CAAI4mD7.js +0 -1
  172. package/dist/assets/psyche-self-observation-page-BZ6FLuwa.js +0 -1
  173. package/dist/assets/psyche-values-page-yEV6MGt8.js +0 -5
  174. package/dist/assets/report-chain-fields-fZ8Xd4H6.js +0 -1
  175. package/dist/assets/schema-badge-DyKbxb51.js +0 -1
  176. package/dist/assets/schema-visuals-D6nxjbYC.js +0 -1
  177. package/dist/assets/select-menu-BX-pZNqL.js +0 -1
  178. package/dist/assets/settings-calendar-page-CjSFB53S.js +0 -5
  179. package/dist/assets/settings-models-page-DFshpYF8.js +0 -1
  180. package/dist/assets/settings-wiki-page-B2zX0QQG.js +0 -1
  181. package/dist/assets/strategy-dialog-BvzomTaF.js +0 -1
  182. package/dist/assets/task-detail-page-BIWIggdp.js +0 -1
  183. package/dist/assets/today-page-DO2mRPT2.js +0 -1
  184. package/dist/assets/training-load-page-CyZ0mlEr.js +0 -1
  185. package/dist/assets/use-psyche-focus-target-C1C_XjYG.js +0 -1
  186. package/dist/assets/weight-loss-page-BBzlhLVV.js +0 -1
  187. package/dist/assets/workbench-flow-page-DqMkCCTy.js +0 -5
  188. package/dist/assets/workbench-page-BWd02wPw.js +0 -1
  189. package/dist/assets/workout-detail-page-BD8u7GyL.js +0 -2
package/dist/index.html CHANGED
@@ -128,17 +128,17 @@
128
128
  }
129
129
  }
130
130
  </style>
131
- <script type="module" crossorigin src="/forge/assets/index-BHTUu_4M.js"></script>
132
- <link rel="modulepreload" crossorigin href="/forge/assets/vendor-DHkYh85p.js">
133
- <link rel="modulepreload" crossorigin href="/forge/assets/state-B-4sS1xO.js">
134
- <link rel="modulepreload" crossorigin href="/forge/assets/board-BkDRaMp6.js">
135
- <link rel="modulepreload" crossorigin href="/forge/assets/ui-C13Nbgas.js">
136
- <link rel="modulepreload" crossorigin href="/forge/assets/motion-BeD44FeG.js">
137
- <link rel="modulepreload" crossorigin href="/forge/assets/forms-BFlTgZ3W.js">
138
- <link rel="modulepreload" crossorigin href="/forge/assets/graph-D6JLqDbD.js">
131
+ <script type="module" crossorigin src="/forge/assets/index-BHIKoiZ6.js"></script>
132
+ <link rel="modulepreload" crossorigin href="/forge/assets/vendor-kIz9EZnX.js">
133
+ <link rel="modulepreload" crossorigin href="/forge/assets/state-VYvD1QVP.js">
134
+ <link rel="modulepreload" crossorigin href="/forge/assets/motion-CfdU2F35.js">
135
+ <link rel="modulepreload" crossorigin href="/forge/assets/ui-CsEkP2V8.js">
136
+ <link rel="modulepreload" crossorigin href="/forge/assets/forms-CmLAyGqz.js">
137
+ <link rel="modulepreload" crossorigin href="/forge/assets/board-DqHzdCPQ.js">
138
+ <link rel="modulepreload" crossorigin href="/forge/assets/graph-BTa79qum.js">
139
139
  <link rel="stylesheet" crossorigin href="/forge/assets/vendor-CRS-psbw.css">
140
140
  <link rel="stylesheet" crossorigin href="/forge/assets/graph-BZV40eAE.css">
141
- <link rel="stylesheet" crossorigin href="/forge/assets/index-CZbuZQjw.css">
141
+ <link rel="stylesheet" crossorigin href="/forge/assets/index-H8R-ABM3.css">
142
142
  </head>
143
143
  <body class="bg-canvas text-ink antialiased">
144
144
  <div id="root">
@@ -178,8 +178,16 @@ function shouldEnableManagedDevWeb(plan, env = process.env) {
178
178
  function getCurrentModuleRoot() {
179
179
  return path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "..");
180
180
  }
181
+ function uniquePaths(paths) {
182
+ return Array.from(new Set(paths.map((candidate) => path.resolve(candidate))));
183
+ }
181
184
  function buildLaunchPlanSearchPaths(moduleRoot) {
182
185
  const repoRoot = path.resolve(moduleRoot, "..");
186
+ const sourceRoots = uniquePaths([
187
+ repoRoot,
188
+ moduleRoot,
189
+ path.resolve(moduleRoot, "..", "..", "..")
190
+ ]);
183
191
  return {
184
192
  packagedEntries: [
185
193
  path.join(moduleRoot, "server", "index.js"),
@@ -188,14 +196,9 @@ function buildLaunchPlanSearchPaths(moduleRoot) {
188
196
  path.join(moduleRoot, "dist", "server", "server", "src", "index.js")
189
197
  ],
190
198
  packagedMigrations: path.join(moduleRoot, "server", "migrations"),
191
- sourceEntries: [
192
- path.join(repoRoot, "server", "src", "index.ts"),
193
- path.join(moduleRoot, "server", "src", "index.ts")
194
- ],
195
- tsxCliCandidates: [
196
- path.join(repoRoot, "node_modules", "tsx", "dist", "cli.mjs"),
197
- path.join(moduleRoot, "node_modules", "tsx", "dist", "cli.mjs")
198
- ],
199
+ sourceRoots,
200
+ sourceEntries: sourceRoots.map((root) => path.join(root, "server", "src", "index.ts")),
201
+ tsxCliCandidates: sourceRoots.map((root) => path.join(root, "node_modules", "tsx", "dist", "cli.mjs")),
199
202
  repoRoot
200
203
  };
201
204
  }
@@ -209,6 +212,20 @@ function formatLaunchPlanFailure(moduleRoot) {
209
212
  `tsx candidates: ${paths.tsxCliCandidates.join(", ")}.`
210
213
  ].join(" ");
211
214
  }
215
+ function resolveSourceRuntimeCandidate(paths) {
216
+ for (const sourceRoot of paths.sourceRoots) {
217
+ const entryFile = path.join(sourceRoot, "server", "src", "index.ts");
218
+ const tsxCli = path.join(sourceRoot, "node_modules", "tsx", "dist", "cli.mjs");
219
+ if (existsSync(entryFile) && existsSync(tsxCli)) {
220
+ return {
221
+ root: sourceRoot,
222
+ entryFile,
223
+ tsxCli
224
+ };
225
+ }
226
+ }
227
+ return null;
228
+ }
212
229
  function getRuntimeLogPath(config) {
213
230
  const origin = new URL(config.origin).hostname.toLowerCase().replace(/[^a-z0-9._-]+/g, "-");
214
231
  return path.join(homedir(), ".openclaw", "logs", FORGE_PLUGIN_ID, `${origin}-${config.port}.log`);
@@ -292,6 +309,18 @@ async function ensurePackagedRuntimeDependencies(plan, config) {
292
309
  function resolveLaunchPlan() {
293
310
  const moduleRoot = getCurrentModuleRoot();
294
311
  const paths = buildLaunchPlanSearchPaths(moduleRoot);
312
+ const sourceCandidate = resolveSourceRuntimeCandidate(paths);
313
+ if (isTruthyEnvFlag(process.env.FORGE_OPENCLAW_DEV)) {
314
+ if (sourceCandidate) {
315
+ return {
316
+ packageRoot: sourceCandidate.root,
317
+ entryFile: sourceCandidate.tsxCli,
318
+ mode: "source",
319
+ sourceEntryFile: sourceCandidate.entryFile
320
+ };
321
+ }
322
+ throw new Error(formatLaunchPlanFailure(moduleRoot));
323
+ }
295
324
  // Published or linked plugin package runtime.
296
325
  const packagedEntry = paths.packagedEntries.find((candidate) => existsSync(candidate));
297
326
  if (packagedEntry && existsSync(paths.packagedMigrations)) {
@@ -302,14 +331,12 @@ function resolveLaunchPlan() {
302
331
  };
303
332
  }
304
333
  // Source-tree fallback for local development before packaging.
305
- const sourceEntry = paths.sourceEntries.find((candidate) => existsSync(candidate));
306
- const tsxCli = paths.tsxCliCandidates.find((candidate) => existsSync(candidate));
307
- if (sourceEntry && tsxCli) {
334
+ if (sourceCandidate) {
308
335
  return {
309
- packageRoot: paths.repoRoot,
310
- entryFile: tsxCli,
336
+ packageRoot: sourceCandidate.root,
337
+ entryFile: sourceCandidate.tsxCli,
311
338
  mode: "source",
312
- sourceEntryFile: sourceEntry
339
+ sourceEntryFile: sourceCandidate.entryFile
313
340
  };
314
341
  }
315
342
  return null;
@@ -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);
@@ -67,7 +67,7 @@ import { createManagerRuntime } from "./managers/runtime.js";
67
67
  import { isManagerError } from "./managers/type-guards.js";
68
68
  import { buildCompanionPairingTransport, getCompanionIrohStatus, stopCompanionIroh } from "./services/companion-iroh.js";
69
69
  import { createCompanionPairingSession, createCompanionPairingSessionSchema, createSleepSession, createSleepSessionSchema, createWorkoutSession, createWorkoutSessionSchema, deleteSleepSession, deleteWorkoutSession, getCompanionPairingSessionById, getCompanionOverview, getFitnessViewData, getSleepSessionById, getSleepSessionDetailById, getSleepTimelineOverlaysForRange, getSleepViewData, getTrainingLoadViewData, getVitalsViewData, getHealthZoneProfileForUser, getMobileHealthSyncSessionStatus, getWorkoutSessionById, getWorkoutSessionDetailById, heartbeatCompanionPairing, heartbeatCompanionPairingSchema, healthZoneProfilePatchSchema, abortMobileHealthSyncSession, completeMobileHealthSyncSession, ingestMobileHealthSync, ingestMobileHealthSyncChunk, mobileHealthSyncChunkSchema, mobileHealthSyncSessionCompleteSchema, mobileHealthSyncSessionStartSchema, mobileHealthSyncSchema, patchHealthZoneProfileForUser, patchCompanionPairingSourceState, patchCompanionPairingSourceStateSchema, companionSourceKeySchema, requireValidPairing, startMobileHealthSyncSession, revokeAllCompanionPairingSessions, revokeAllCompanionPairingSessionsSchema, revokeCompanionPairingSession, updateMobileCompanionSourceState, updateMobileCompanionSourceStateSchema, verifyCompanionPairing, verifyCompanionPairingSchema, updateSleepMetadata, updateSleepMetadataSchema, updateWorkoutMetadata, updateWorkoutMetadataSchema } from "./health.js";
70
- import { createNutritionAppearanceCheckin, createNutritionBodyCheckin, createNutritionExperiment, createNutritionFoodLog, createNutritionGutCheckin, createNutritionSubjectiveCheckin, deleteNutritionFoodLog, getWeightLossViewData, lookupNutritionBarcode, nutritionAppearanceCheckinCreateSchema, nutritionBarcodeLookupSchema, nutritionBodyCheckinCreateSchema, nutritionExperimentCreateSchema, nutritionExperimentPatchSchema, nutritionFoodLogCreateSchema, nutritionFoodLogPatchSchema, nutritionFoodSearchSchema, nutritionGutCheckinCreateSchema, nutritionParseRequestSchema, nutritionSubjectiveCheckinCreateSchema, nutritionTargetUpdateSchema, parseNutritionFoodLogWithChatGpt, patchNutritionExperiment, patchNutritionFoodLog, searchNutritionFoods, updateNutritionTarget } from "./health-weight-loss.js";
70
+ import { createNutritionAppearanceCheckin, createNutritionBodyCheckin, createNutritionExperiment, createNutritionFoodLog, createNutritionGutCheckin, createNutritionSubjectiveCheckin, deleteNutritionFoodLog, getWeightLossViewData, lookupNutritionBarcode, nutritionAppearanceCheckinCreateSchema, nutritionBarcodeLookupSchema, nutritionBodyCheckinCreateSchema, nutritionExperimentCreateSchema, nutritionExperimentPatchSchema, nutritionFoodLogCreateSchema, nutritionFoodLogPatchSchema, nutritionFoodSearchSchema, nutritionGutCheckinCreateSchema, nutritionParseRequestSchema, nutritionSubjectiveCheckinCreateSchema, nutritionDailyActiveCaloriesUpdateSchema, nutritionTargetUpdateSchema, parseNutritionFoodLogWithChatGpt, patchNutritionExperiment, patchNutritionFoodLog, searchNutritionFoods, updateNutritionDailyActiveCalories, updateNutritionTarget } from "./health-weight-loss.js";
71
71
  import { analyzeMovementUserBoxPreflight, createMovementUserBox, createMovementPlace, deleteMovementUserBox, getMovementAllTimeSummary, getMovementBoxDetail, getMovementDayDetail, getMovementMobileBootstrap, getMovementTimeline, getMovementSelectionAggregate, getMovementSettings, getMovementTripDetail, getMovementMonthSummary, invalidateAutomaticMovementBox, listMovementPlaces, movementAutomaticBoxInvalidateSchema, movementMobileBootstrapSchema, movementMobilePlaceMutationSchema, movementMobileStayPatchSchema, movementMobileUserBoxCreateSchema, movementMobileUserBoxPreflightSchema, movementMobileUserBoxPatchSchema, movementMobileAutomaticBoxInvalidateSchema, movementMobileTimelineSchema, movementPlaceMutationSchema, movementPlacePatchSchema, movementSelectionAggregateSchema, movementStayPatchSchema, movementTripPatchSchema, movementUserBoxCreateSchema, movementUserBoxPreflightSchema, movementUserBoxPatchSchema, movementSettingsPatchSchema, movementTimelineQuerySchema, movementTripPointPatchSchema, deleteMovementStay, deleteMovementTrip, deleteMovementTripPoint, updateMovementPlace, updateMovementSettings, updateMovementStay, updateMovementTrip, updateMovementUserBox, updateMovementTripPoint, resolveMovementTimelineSegmentForBox } from "./movement.js";
72
72
  import { getScreenTimeAllTimeSummary, getScreenTimeDayDetail, getScreenTimeMonthSummary, getScreenTimeSettings, screenTimeSettingsPatchSchema, updateScreenTimeSettings } from "./screen-time.js";
73
73
  import { assertWatchReady, buildWatchBootstrap, ingestWatchCommandBatch, ingestWatchCaptureBatch, mobileWatchBootstrapSchema, mobileWatchCommandBatchSchema, mobileWatchCaptureBatchSchema, mobileWatchHabitCheckInSchema } from "./watch-mobile.js";
@@ -3408,6 +3408,18 @@ const AGENT_ONBOARDING_ENTITY_CONVERSATION_PLAYBOOKS = [
3408
3408
  "Move to a workout_session write only when one specific workout needs reflective context, tags, notes, or links."
3409
3409
  ]
3410
3410
  },
3411
+ {
3412
+ focus: "weight_loss",
3413
+ openingQuestion: "What food-body link are you trying to test or understand right now?",
3414
+ coachingGoal: "Review nutrition, body-composition, sport-fueling, appearance, gut-comfort, craving, and subjective-energy evidence before logging or changing anything.",
3415
+ askSequence: [
3416
+ "Ask whether the question is fat-loss pace, food intake, protein/fiber sufficiency, sport fuel, visual look, water retention, cravings, gut comfort, energy, or one meal reaction.",
3417
+ "Use forge_get_weight_loss_overview before asking the user to reconstruct recent food, weight, workouts, or subjective state from memory.",
3418
+ "Use forge_parse_food_log_with_chatgpt only for rough meal text or photo descriptions through Forge's configured openai-codex ChatGPT subscription connection, not a metered OpenAI Platform API path.",
3419
+ "Use the dedicated nutrition tools for food logs, body check-ins, appearance check-ins, subjective food effects, gut check-ins, nutrition patterns, and N-of-1 experiments instead of generic batch CRUD.",
3420
+ "Ask for the one outcome metric that would make a nutrition experiment interpretable before turning repeated observations into a hypothesis."
3421
+ ]
3422
+ },
3411
3423
  {
3412
3424
  focus: "preference_catalog",
3413
3425
  openingQuestion: "What decision or taste question should this catalog help with?",
@@ -4021,7 +4033,9 @@ function buildPlaybookRouteInfo(focus) {
4021
4033
  ? `Mutation: ${guide.preferredMutationPath}.`
4022
4034
  : null,
4023
4035
  guide?.preferredReadPath ? `Read: ${guide.preferredReadPath}.` : null,
4024
- guide?.preferredMutationTool ? `Tool: ${guide.preferredMutationTool}.` : null,
4036
+ guide?.preferredMutationTool
4037
+ ? `Tool: ${guide.preferredMutationTool}.`
4038
+ : null,
4025
4039
  `Entity type: ${focus}.`
4026
4040
  ]
4027
4041
  .filter(Boolean)
@@ -4696,6 +4710,7 @@ function buildAgentOnboardingPayload(request) {
4696
4710
  movement: "Forge Movement is the first-class mobility surface. It is a timeline of stays and trips: stays capture time spent in the same place, and trips capture travel between places. Use it for time-in-place questions, travel-history review, specific stay or trip edits, selected-span aggregates, known places, and links to other Forge records rather than pretending stays and trips are normal batch CRUD entities.",
4697
4711
  lifeForce: "Life Force is Forge's energy-budget and fatigue model. Read it through the dedicated life-force state and update it through focused profile, weekday-template, and fatigue-signal routes rather than generic entity CRUD.",
4698
4712
  workbench: "Workbench is Forge's graph-flow execution system. Treat flows, runs, published outputs, node results, and latest-node-output reads as a dedicated API family instead of a normal entity-batch surface.",
4713
+ weightLoss: "Weight Loss is Forge's nutrition, body-composition, sport-fueling, appearance, gut-comfort, craving, and subjective-energy surface. Read it through the health overview route and use the dedicated nutrition tools for food logs, body check-ins, appearance check-ins, subjective effects, gut check-ins, and N-of-1 experiments instead of inventing batch CRUD records.",
4699
4714
  psyche: "Forge Psyche is the reflective domain for values, patterns, behaviors, beliefs, modes, flashcards, and trigger reports. It is sensitive and should be handled deliberately."
4700
4715
  },
4701
4716
  psycheSubmoduleModel: {
@@ -4961,7 +4976,12 @@ function buildAgentOnboardingPayload(request) {
4961
4976
  classification: "specialized_domain_surface",
4962
4977
  aliases: ["life_force", "life-force", "Life Force"],
4963
4978
  summary: "Dedicated life-force API. Use it to read the current energy budget, drains, recommendations, and warnings, then patch only the parts that are meant to be user-controlled.",
4964
- routeKeys: ["overview", "profile", "weekdayTemplate", "fatigueSignal"],
4979
+ routeKeys: [
4980
+ "overview",
4981
+ "profile",
4982
+ "weekdayTemplate",
4983
+ "fatigueSignal"
4984
+ ],
4965
4985
  routeSelectionQuestions: [
4966
4986
  "Is the user trying to understand the overview, change durable profile assumptions, change a weekday curve, or log a right-now fatigue signal?",
4967
4987
  "What planning decision should the overview or correction change: workload, recovery, timeboxes, meetings, or task choice?",
@@ -4998,7 +5018,12 @@ function buildAgentOnboardingPayload(request) {
4998
5018
  classification: "specialized_domain_surface",
4999
5019
  aliases: ["lifeForce", "life-force", "Life Force"],
5000
5020
  summary: "Alias for the dedicated Life Force API keyed to the entity-style name `life_force`. Use the same overview, profile, weekday-template, and fatigue-signal routes as `lifeForce`.",
5001
- routeKeys: ["overview", "profile", "weekdayTemplate", "fatigueSignal"],
5021
+ routeKeys: [
5022
+ "overview",
5023
+ "profile",
5024
+ "weekdayTemplate",
5025
+ "fatigueSignal"
5026
+ ],
5002
5027
  routeSelectionQuestions: [
5003
5028
  "Is the user trying to understand the overview, change durable profile assumptions, change a weekday curve, or log a right-now fatigue signal?",
5004
5029
  "What planning decision should the overview or correction change: workload, recovery, timeboxes, meetings, or task choice?",
@@ -5274,7 +5299,21 @@ function buildAgentOnboardingPayload(request) {
5274
5299
  psycheSchemaCatalog: "/api/v1/psyche/schema-catalog",
5275
5300
  psycheEventTypes: "/api/v1/psyche/event-types",
5276
5301
  psycheEmotions: "/api/v1/psyche/emotions",
5277
- weightLoss: "/api/v1/health/weight-loss"
5302
+ weightLoss: "/api/v1/health/weight-loss",
5303
+ weightLossTarget: "/api/v1/health/weight-loss/target",
5304
+ weightLossDailyActiveCalories: "/api/v1/health/weight-loss/daily-active-calories",
5305
+ weightLossFoodsSearch: "/api/v1/health/weight-loss/foods/search",
5306
+ weightLossFoodsBarcode: "/api/v1/health/weight-loss/foods/barcode",
5307
+ weightLossFoodLogs: "/api/v1/health/weight-loss/food-logs",
5308
+ weightLossFoodLogDetail: "/api/v1/health/weight-loss/food-logs/:id",
5309
+ weightLossParse: "/api/v1/health/weight-loss/parse",
5310
+ weightLossBodyCheckins: "/api/v1/health/weight-loss/body-checkins",
5311
+ weightLossAppearanceCheckins: "/api/v1/health/weight-loss/appearance-checkins",
5312
+ weightLossSubjectiveCheckins: "/api/v1/health/weight-loss/subjective-checkins",
5313
+ weightLossGutCheckins: "/api/v1/health/weight-loss/gut-checkins",
5314
+ weightLossPatterns: "/api/v1/health/weight-loss/patterns",
5315
+ weightLossExperiments: "/api/v1/health/weight-loss/experiments",
5316
+ weightLossExperimentDetail: "/api/v1/health/weight-loss/experiments/:id"
5278
5317
  },
5279
5318
  recommendedPluginTools: {
5280
5319
  bootstrap: ["forge_get_operator_overview"],
@@ -5643,7 +5682,9 @@ function resolveEffectiveReadScope(query, auth) {
5643
5682
  : [...tokenUserIds]
5644
5683
  : requestedUserIds;
5645
5684
  return {
5646
- userIds: effectiveUserIds !== undefined ? Array.from(new Set(effectiveUserIds)) : undefined,
5685
+ userIds: effectiveUserIds !== undefined
5686
+ ? Array.from(new Set(effectiveUserIds))
5687
+ : undefined,
5647
5688
  enforceUserIds: tokenUserIds.length > 0,
5648
5689
  projectIds: auth.token?.scopePolicy.projectIds ?? [],
5649
5690
  tagIds: auth.token?.scopePolicy.tagIds ?? []
@@ -5678,8 +5719,7 @@ function applyProjectScope(projects, scope) {
5678
5719
  return projects;
5679
5720
  }
5680
5721
  return projects.filter((project) => {
5681
- if (scope.projectIds.length > 0 &&
5682
- !scope.projectIds.includes(project.id)) {
5722
+ if (scope.projectIds.length > 0 && !scope.projectIds.includes(project.id)) {
5683
5723
  return false;
5684
5724
  }
5685
5725
  if (scope.tagIds.length > 0 &&
@@ -5775,8 +5815,10 @@ function buildV1Context(scope = {
5775
5815
  });
5776
5816
  const projects = applyProjectScope(listProjectSummaries({ userIds: scopedUserIdsForReads }), scope);
5777
5817
  const tasks = applyTaskScope(filterOwnedEntities("task", listTasks(), scopedUserIdsForReads), scope);
5778
- const goals = applyGoalScope(filterOwnedEntities("goal", listGoals(), scopedUserIdsForReads), scope, new Set([...projects.map((project) => project.goalId), ...tasks.map((task) => task.goalId)]
5779
- .filter((value) => typeof value === "string" && value.length > 0)));
5818
+ const goals = applyGoalScope(filterOwnedEntities("goal", listGoals(), scopedUserIdsForReads), scope, new Set([
5819
+ ...projects.map((project) => project.goalId),
5820
+ ...tasks.map((task) => task.goalId)
5821
+ ].filter((value) => typeof value === "string" && value.length > 0)));
5780
5822
  const habits = applyHabitScope(filterOwnedEntities("habit", listHabits(), scopedUserIdsForReads), scope, new Set(goals.map((goal) => goal.id)), new Set(tasks.map((task) => task.id)));
5781
5823
  const strategies = applyStrategyScope(listStrategies({ userIds: scopedUserIdsForReads }), scope, new Set(goals.map((goal) => goal.id)));
5782
5824
  const dashboard = getDashboard({ userIds: scopedUserIdsForReads });
@@ -5822,7 +5864,11 @@ function buildV1Context(scope = {
5822
5864
  validScopedUserIds !== undefined &&
5823
5865
  validScopedUserIds.length === 0
5824
5866
  ? []
5825
- : listTaskRuns({ active: true, limit: 25, userIds: scopedUserIdsForReads }),
5867
+ : listTaskRuns({
5868
+ active: true,
5869
+ limit: 25,
5870
+ userIds: scopedUserIdsForReads
5871
+ }),
5826
5872
  activity: dashboard.recentActivity,
5827
5873
  lifeForce: buildLifeForcePayload(now, scopedUserIdsForReads)
5828
5874
  };
@@ -5897,8 +5943,10 @@ function buildOperatorContext(scope = {
5897
5943
  status: "active",
5898
5944
  userIds: scopedUserIdsForReads
5899
5945
  }), scope).filter((project) => project.activeTaskCount > 0 || project.completedTaskCount > 0);
5900
- const goals = applyGoalScope(filterOwnedEntities("goal", listGoals(), scopedUserIdsForReads), scope, new Set([...activeProjects.map((project) => project.goalId), ...tasks.map((task) => task.goalId)]
5901
- .filter((value) => typeof value === "string" && value.length > 0)));
5946
+ const goals = applyGoalScope(filterOwnedEntities("goal", listGoals(), scopedUserIdsForReads), scope, new Set([
5947
+ ...activeProjects.map((project) => project.goalId),
5948
+ ...tasks.map((task) => task.goalId)
5949
+ ].filter((value) => typeof value === "string" && value.length > 0)));
5902
5950
  const scopedHabits = applyHabitScope(dueHabits, scope, new Set(goals.map((goal) => goal.id)), new Set(tasks.map((task) => task.id))).slice(0, 12);
5903
5951
  const focusTasks = tasks.filter((task) => task.status === "focus" || task.status === "in_progress");
5904
5952
  const recommendedNextTask = focusTasks[0] ??
@@ -6283,7 +6331,9 @@ function compactOperatorContext(context) {
6283
6331
  tasks: tasks.slice(0, 5).map(compactTask)
6284
6332
  }
6285
6333
  ])),
6286
- recentActivity: context.recentActivity.slice(0, 10).map(compactActivityEvent),
6334
+ recentActivity: context.recentActivity
6335
+ .slice(0, 10)
6336
+ .map(compactActivityEvent),
6287
6337
  recentTaskRuns: context.recentTaskRuns.slice(0, 8).map(compactTaskRun),
6288
6338
  recommendedNextTask: context.recommendedNextTask
6289
6339
  ? compactTask(context.recommendedNextTask)
@@ -6339,7 +6389,9 @@ function compactFitness(fitness) {
6339
6389
  typeBreakdown: fitness.typeBreakdown.slice(0, 8),
6340
6390
  sessions: fitness.sessions.slice(0, 8).map((session) => ({
6341
6391
  id: session.id,
6342
- title: compactText(session.plannedContext || session.workoutTypeLabel || session.workoutType, 100),
6392
+ title: compactText(session.plannedContext ||
6393
+ session.workoutTypeLabel ||
6394
+ session.workoutType, 100),
6343
6395
  workoutType: session.workoutType,
6344
6396
  workoutTypeLabel: session.workoutTypeLabel,
6345
6397
  activityFamily: session.activityFamily,
@@ -6494,7 +6546,9 @@ function compactPsyche(psyche) {
6494
6546
  summaryFields: ["eventSituation", "customEventType"]
6495
6547
  })),
6496
6548
  schemaPressure: psyche.schemaPressure,
6497
- committedActions: psyche.committedActions.slice(0, 12).map((action) => compactText(action, 120)),
6549
+ committedActions: psyche.committedActions
6550
+ .slice(0, 12)
6551
+ .map((action) => compactText(action, 120)),
6498
6552
  detailRoute: "/api/v1/psyche/overview"
6499
6553
  };
6500
6554
  }
@@ -6672,7 +6726,9 @@ function buildOperatorOverview(request) {
6672
6726
  const canReadPsyche = auth.token
6673
6727
  ? hasTokenScope(auth.token, "psyche.read")
6674
6728
  : true;
6675
- const requestedDetailMode = typeof request.query?.detail === "string" ? request.query.detail : "compact";
6729
+ const requestedDetailMode = typeof request.query?.detail === "string"
6730
+ ? request.query.detail
6731
+ : "compact";
6676
6732
  const warnings = canReadPsyche
6677
6733
  ? []
6678
6734
  : [
@@ -6686,8 +6742,10 @@ function buildOperatorOverview(request) {
6686
6742
  const yesterdayRange = localDayRange(addDays(now, -1));
6687
6743
  const projects = applyProjectScope(listProjectSummaries({ userIds }), readScope);
6688
6744
  const tasks = applyTaskScope(filterOwnedEntities("task", listTasks(), userIds), readScope);
6689
- const goals = applyGoalScope(filterOwnedEntities("goal", listGoals(), userIds), readScope, new Set([...projects.map((project) => project.goalId), ...tasks.map((task) => task.goalId)]
6690
- .filter((value) => typeof value === "string" && value.length > 0)));
6745
+ const goals = applyGoalScope(filterOwnedEntities("goal", listGoals(), userIds), readScope, new Set([
6746
+ ...projects.map((project) => project.goalId),
6747
+ ...tasks.map((task) => task.goalId)
6748
+ ].filter((value) => typeof value === "string" && value.length > 0)));
6691
6749
  const habits = applyHabitScope(filterOwnedEntities("habit", listHabits(), userIds), readScope, new Set(goals.map((goal) => goal.id)), new Set(tasks.map((task) => task.id)));
6692
6750
  const operator = compactOperatorContext(buildOperatorContext(readScope));
6693
6751
  const overview = getOverviewContext(now, { userIds });
@@ -6699,7 +6757,9 @@ function buildOperatorOverview(request) {
6699
6757
  const vitals = compactVitals(getVitalsViewData(userIds));
6700
6758
  const weightLoss = compactWeightLoss(getWeightLossViewData(userIds));
6701
6759
  const lifeForce = compactLifeForce(buildLifeForcePayload(now, userIds));
6702
- const psyche = canReadPsyche ? compactPsyche(getPsycheOverview(userIds)) : null;
6760
+ const psyche = canReadPsyche
6761
+ ? compactPsyche(getPsycheOverview(userIds))
6762
+ : null;
6703
6763
  const onboarding = compactOnboardingPayload(buildAgentOnboardingPayload(request));
6704
6764
  const calendar = compactCalendarForDays(readCalendarOverview({
6705
6765
  from: yesterdayRange.from,
@@ -6737,8 +6797,7 @@ function buildOperatorOverview(request) {
6737
6797
  goals: goals.length,
6738
6798
  activeGoals: goals.filter((goal) => goal.status === "active").length,
6739
6799
  projects: projects.length,
6740
- activeProjects: projects.filter((project) => project.status === "active")
6741
- .length,
6800
+ activeProjects: projects.filter((project) => project.status === "active").length,
6742
6801
  tasks: tasks.length,
6743
6802
  focusTasks: tasks.filter((task) => task.status === "focus" || task.status === "in_progress").length,
6744
6803
  habits: habits.length
@@ -7285,7 +7344,9 @@ export async function buildServer(options = {}) {
7285
7344
  };
7286
7345
  });
7287
7346
  app.post("/api/v1/doctor/fixes", async (request) => {
7288
- requireScopedAccess(request.headers, ["write"], { route: "/api/v1/doctor/fixes" });
7347
+ requireScopedAccess(request.headers, ["write"], {
7348
+ route: "/api/v1/doctor/fixes"
7349
+ });
7289
7350
  const parsed = z
7290
7351
  .object({
7291
7352
  fixIds: z.array(z.string().min(1)).optional(),
@@ -7475,6 +7536,12 @@ export async function buildServer(options = {}) {
7475
7536
  target: updateNutritionTarget(nutritionTargetUpdateSchema.parse(request.body ?? {}))
7476
7537
  };
7477
7538
  });
7539
+ app.patch("/api/v1/health/weight-loss/daily-active-calories", async (request) => {
7540
+ requireScopedAccess(request.headers, ["write"], {
7541
+ route: "/api/v1/health/weight-loss/daily-active-calories"
7542
+ });
7543
+ return updateNutritionDailyActiveCalories(nutritionDailyActiveCaloriesUpdateSchema.parse(request.body ?? {}));
7544
+ });
7478
7545
  app.post("/api/v1/health/weight-loss/foods/search", async (request) => ({
7479
7546
  ...(await searchNutritionFoods(nutritionFoodSearchSchema.parse(request.body ?? {})))
7480
7547
  }));
@@ -7675,7 +7742,8 @@ export async function buildServer(options = {}) {
7675
7742
  const parsed = movementTimelineQuerySchema.parse(request.query ?? {});
7676
7743
  const userIds = parsed.userIds.length > 0
7677
7744
  ? parsed.userIds
7678
- : (resolveScopedUserIds(request.query) ?? []);
7745
+ : (resolveScopedUserIds(request.query) ??
7746
+ []);
7679
7747
  const movement = getMovementTimeline({
7680
7748
  ...parsed,
7681
7749
  userIds
@@ -7735,7 +7803,9 @@ export async function buildServer(options = {}) {
7735
7803
  };
7736
7804
  });
7737
7805
  app.post("/api/v1/movement/user-boxes/preflight", async (request) => {
7738
- requireScopedAccess(request.headers, ["write"], { route: "/api/v1/movement/user-boxes/preflight" });
7806
+ requireScopedAccess(request.headers, ["write"], {
7807
+ route: "/api/v1/movement/user-boxes/preflight"
7808
+ });
7739
7809
  const userId = resolveScopedUserIds(request.query)?.[0] ??
7740
7810
  getDefaultUser().id;
7741
7811
  return {
@@ -7764,7 +7834,9 @@ export async function buildServer(options = {}) {
7764
7834
  const userId = resolveScopedUserIds(request.query)?.[0] ??
7765
7835
  getDefaultUser().id;
7766
7836
  const { id } = request.params;
7767
- const result = deleteMovementUserBox(id, toActivityContext(auth), { userId });
7837
+ const result = deleteMovementUserBox(id, toActivityContext(auth), {
7838
+ userId
7839
+ });
7768
7840
  if (!result) {
7769
7841
  reply.code(404);
7770
7842
  return { error: "Movement user box not found" };
@@ -7783,7 +7855,8 @@ export async function buildServer(options = {}) {
7783
7855
  }
7784
7856
  reply.code(201);
7785
7857
  return {
7786
- box: resolveMovementTimelineSegmentForBox(userId, result.box.id) ?? result.box
7858
+ box: resolveMovementTimelineSegmentForBox(userId, result.box.id) ??
7859
+ result.box
7787
7860
  };
7788
7861
  });
7789
7862
  app.patch("/api/v1/movement/stays/:id", async (request, reply) => {
@@ -7998,7 +8071,8 @@ export async function buildServer(options = {}) {
7998
8071
  source: "system"
7999
8072
  });
8000
8073
  return {
8001
- box: resolveMovementTimelineSegmentForBox(pairing.user_id, created.id) ?? created
8074
+ box: resolveMovementTimelineSegmentForBox(pairing.user_id, created.id) ??
8075
+ created
8002
8076
  };
8003
8077
  });
8004
8078
  app.post("/api/v1/mobile/movement/user-boxes/preflight", async (request) => {
@@ -8055,8 +8129,7 @@ export async function buildServer(options = {}) {
8055
8129
  }
8056
8130
  reply.code(201);
8057
8131
  return {
8058
- box: resolveMovementTimelineSegmentForBox(pairing.user_id, result.box.id) ??
8059
- result.box
8132
+ box: resolveMovementTimelineSegmentForBox(pairing.user_id, result.box.id) ?? result.box
8060
8133
  };
8061
8134
  });
8062
8135
  app.patch("/api/v1/mobile/movement/stays/:id", async (request, reply) => {