forge-openclaw-plugin 0.2.102 → 0.2.104
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.
- package/dist/assets/activity-page-Dv6X5ZCV.js +1 -0
- package/dist/assets/{ai-surface-workspace-xtB5RFQu.js → ai-surface-workspace-CutiG6uS.js} +1 -1
- package/dist/assets/{atlas-panel-B3dPHCmZ.js → atlas-panel-jgMRyaHn.js} +1 -1
- package/dist/assets/{board-DqHzdCPQ.js → board-dIX6etHh.js} +1 -1
- package/dist/assets/calendar-page-q7Nm5E2U.js +1 -0
- package/dist/assets/calendar-rules-DPFsfiRl.js +1 -0
- package/dist/assets/{calendar-week-toolbar-BZ_-X3Wb.js → calendar-week-toolbar-nVhgB-0s.js} +1 -1
- package/dist/assets/{charts-FcU0F3XV.js → charts-DFnEuIMB.js} +1 -1
- package/dist/assets/companion-sync-lab-page-CJ8UTij8.js +1 -0
- package/dist/assets/{daily-metrics-dashboard-BMyL0Qr4.js → daily-metrics-dashboard-CiJkkkd1.js} +1 -1
- package/dist/assets/entity-note-count-link-RzBB6ujx.js +1 -0
- package/dist/assets/{entity-notes-surface-CBylYDwy.js → entity-notes-surface-Djz50HvD.js} +1 -1
- package/dist/assets/execution-board-CtPhI-58.js +1 -0
- package/dist/assets/{faceted-token-search-D7xPWfOl.js → faceted-token-search-DEC6ANa9.js} +1 -1
- package/dist/assets/{flagship-signal-deck-BEFKOhvx.js → flagship-signal-deck-CtHC3mql.js} +1 -1
- package/dist/assets/floating-action-menu-CKQRhff9.js +1 -0
- package/dist/assets/{forms-CmLAyGqz.js → forms-hB0SqEh-.js} +1 -1
- package/dist/assets/goal-detail-page-CF5fNQeR.js +1 -0
- package/dist/assets/goals-page-fsY8NzGB.js +1 -0
- package/dist/assets/{graph-BTa79qum.js → graph-DDUZNRsO.js} +1 -1
- package/dist/assets/habits-page-COoGz4kj.js +1 -0
- package/dist/assets/index-BAXYM89v.css +1 -0
- package/dist/assets/index-EqQsXoat.js +19 -0
- package/dist/assets/{insight-flow-dialog-BtIQXXsS.js → insight-flow-dialog-DtX_5W7g.js} +1 -1
- package/dist/assets/insights-page-cBd74ObU.js +8 -0
- package/dist/assets/kanban-page-CYav9THw.js +1 -0
- package/dist/assets/knowledge-graph-page-D2A-W1jE.js +1 -0
- package/dist/assets/{life-force-page-BGDkKfbJ.js → life-force-page-CACGlNhq.js} +1 -1
- package/dist/assets/life-force-workspace-BJ4N1I78.js +1 -0
- package/dist/assets/{maps-CF1RagUX.js → maps-C-yOWiDN.js} +1 -1
- package/dist/assets/{metric-tile-4iMd_WnJ.js → metric-tile-CMadwnGz.js} +1 -1
- package/dist/assets/{motion-CfdU2F35.js → motion-Lt5B1XuE.js} +1 -1
- package/dist/assets/movement-page-D5VqFd2q.js +1 -0
- package/dist/assets/{note-markdown-CsGQhQXF.js → note-markdown-BzK2Qlgr.js} +1 -1
- package/dist/assets/{note-tags-input-DdZi93tj.js → note-tags-input-CZzqJMLc.js} +1 -1
- package/dist/assets/notes-page-D3Hsh90C.js +1 -0
- package/dist/assets/{open-in-graph-button-C0TGev7c.js → open-in-graph-button-BFPKfyK3.js} +1 -1
- package/dist/assets/{orbit-map-DVXkfQdd.js → orbit-map-CnyfSmOG.js} +1 -1
- package/dist/assets/{overview-page-BwMlFQKX.js → overview-page-CXdWrOV1.js} +1 -1
- package/dist/assets/{page-hero-oFHaAjtL.js → page-hero-ffKzgyW3.js} +1 -1
- package/dist/assets/pill-cluster-C2D0h3lx.js +1 -0
- package/dist/assets/{preference-entity-handoff-button-DOKV9bZc.js → preference-entity-handoff-button-Dj3V6VxL.js} +1 -1
- package/dist/assets/preferences-page-Jo8Gw386.js +1 -0
- package/dist/assets/project-collections-qSqp90HN.js +1 -0
- package/dist/assets/{project-detail-page-DogvVNEn.js → project-detail-page-BifhiLQX.js} +1 -1
- package/dist/assets/project-management-hierarchy-page-DZ_9klIc.js +1 -0
- package/dist/assets/project-management-section-nav-BImLCVvf.js +1 -0
- package/dist/assets/projects-page-ptcx6H38.js +1 -0
- package/dist/assets/{psyche-behaviors-page-BeVlXvbj.js → psyche-behaviors-page-BDwXyDta.js} +1 -1
- package/dist/assets/{psyche-flashcards-page-CqAWCO4E.js → psyche-flashcards-page-DL1BP1jX.js} +1 -1
- package/dist/assets/{psyche-goal-map-page-IyNnbk_W.js → psyche-goal-map-page-ovcpisx1.js} +1 -1
- package/dist/assets/{psyche-graph-IkUQRaDK.js → psyche-graph-EP5GL612.js} +1 -1
- package/dist/assets/{psyche-metrics-page-uai0a7Lx.js → psyche-metrics-page-Bcu813Rg.js} +1 -1
- package/dist/assets/{psyche-mode-guide-page-C7p-ABiF.js → psyche-mode-guide-page-C0g27Xpt.js} +1 -1
- package/dist/assets/{psyche-modes-page-CLQ5V3w0.js → psyche-modes-page-BjKjX5MR.js} +1 -1
- package/dist/assets/{psyche-page-NQBHkkpU.js → psyche-page-F4tF2W70.js} +1 -1
- package/dist/assets/{psyche-patterns-page-BkRiNpI_.js → psyche-patterns-page-B-14hukK.js} +1 -1
- package/dist/assets/{psyche-questionnaire-builder-page-Du-7HwPC.js → psyche-questionnaire-builder-page-BdXmoHvK.js} +1 -1
- package/dist/assets/{psyche-questionnaire-detail-page-C5-yf8MF.js → psyche-questionnaire-detail-page-Cu5uwlJu.js} +1 -1
- package/dist/assets/{psyche-questionnaire-run-detail-page-CoSH5O6R.js → psyche-questionnaire-run-detail-page-C3R4PClg.js} +1 -1
- package/dist/assets/{psyche-questionnaire-run-page-ChI7c1wy.js → psyche-questionnaire-run-page-Div3iDdt.js} +1 -1
- package/dist/assets/{psyche-questionnaires-page-xUcJJzbI.js → psyche-questionnaires-page-DpqAPQCp.js} +1 -1
- package/dist/assets/{psyche-report-detail-page-BPrZCFZS.js → psyche-report-detail-page-BvWVDKP3.js} +1 -1
- package/dist/assets/{psyche-reports-page-D2EXJmm6.js → psyche-reports-page-BrbWUlAq.js} +1 -1
- package/dist/assets/{psyche-schemas-RcZYaokx.js → psyche-schemas-Dxj554nU.js} +1 -1
- package/dist/assets/{psyche-schemas-beliefs-page-h0ooZ1lp.js → psyche-schemas-beliefs-page-DYKvAtSD.js} +1 -1
- package/dist/assets/{psyche-screen-time-page-_3-4LikV.js → psyche-screen-time-page-CAOKCyQw.js} +1 -1
- package/dist/assets/{psyche-self-observation-page-BdbCsgR5.js → psyche-self-observation-page-F0MVA0UH.js} +1 -1
- package/dist/assets/{psyche-values-page-DuUVki5e.js → psyche-values-page-DyvX-d0o.js} +1 -1
- package/dist/assets/{report-chain-fields-BBMz0sGI.js → report-chain-fields-CeC1cJFS.js} +1 -1
- package/dist/assets/rewards-page-C2loyODo.js +1 -0
- package/dist/assets/scheduling-rules-editor-D40AC2jR.js +1 -0
- package/dist/assets/{schema-badge-D93RcG36.js → schema-badge-FY7818qB.js} +1 -1
- package/dist/assets/{select-menu-Cdq7foRu.js → select-menu-DJsCG6rM.js} +1 -1
- package/dist/assets/settings-agents-page-BFkJ5AAD.js +6 -0
- package/dist/assets/settings-bin-page-D3-Ab-iA.js +1 -0
- package/dist/assets/settings-calendar-page-ly_mSTAD.js +5 -0
- package/dist/assets/settings-data-page-D7QOqNf-.js +1 -0
- package/dist/assets/settings-logs-page-Ca87HEUx.js +1 -0
- package/dist/assets/settings-mobile-page-D0jejZot.js +1 -0
- package/dist/assets/settings-models-page-DPDsZjSc.js +1 -0
- package/dist/assets/settings-page-1cArlSPM.js +1 -0
- package/dist/assets/settings-rewards-page-Db4BV1DC.js +1 -0
- package/dist/assets/{settings-section-nav-Dc4IeVBt.js → settings-section-nav-DP9o4peU.js} +1 -1
- package/dist/assets/settings-users-page-BHFyDSsd.js +1 -0
- package/dist/assets/settings-wiki-page-BNaiupBm.js +1 -0
- package/dist/assets/sleep-page-BmOPF0yD.js +1 -0
- package/dist/assets/sports-page-BldIiclr.js +1 -0
- package/dist/assets/{state-VYvD1QVP.js → state-vCcAT5Hq.js} +1 -1
- package/dist/assets/strategies-page-CaTN99qj.js +1 -0
- package/dist/assets/strategy-detail-page-DsgFTd-U.js +1 -0
- package/dist/assets/{strategy-dialog-DMyRKrWf.js → strategy-dialog-7X7peRzu.js} +1 -1
- package/dist/assets/{surface-Bfz_sLX6.js → surface-CJI17F3n.js} +1 -1
- package/dist/assets/{table-C0VTeqw0.js → table-BNqMG3_S.js} +1 -1
- package/dist/assets/task-detail-page-M1sIIPA8.js +1 -0
- package/dist/assets/timebox-planning-dialog-ByojN0AN.js +1 -0
- package/dist/assets/today-page-BjDijtn8.js +1 -0
- package/dist/assets/training-load-page-BPRmaWmF.js +1 -0
- package/dist/assets/{ui-CsEkP2V8.js → ui-C1iwpj2-.js} +1 -1
- package/dist/assets/{use-psyche-focus-target-qxT5Oy_z.js → use-psyche-focus-target-Ct-acS9G.js} +1 -1
- package/dist/assets/{vendor-kIz9EZnX.js → vendor-Dnkkx2co.js} +3 -3
- package/dist/assets/{vitals-page-Dz1Jt5H8.js → vitals-page-CE9zdGLF.js} +1 -1
- package/dist/assets/weekly-review-page-CzhTv90n.js +1 -0
- package/dist/assets/weight-loss-page-Bp_cIk78.js +5 -0
- package/dist/assets/wiki-article-markdown-Dok2uy2p.js +4 -0
- package/dist/assets/wiki-editor-page-BuW32Y3f.js +26 -0
- package/dist/assets/wiki-ingest-history-page-DZKSBNHV.js +1 -0
- package/dist/assets/wiki-ingest-modal-DyqBEZcC.js +1 -0
- package/dist/assets/wiki-page-DqxlbLKG.js +1 -0
- package/dist/assets/workbench-flow-page-C4nc9jUg.js +5 -0
- package/dist/assets/workbench-page-BnyR7SL0.js +1 -0
- package/dist/assets/{workout-detail-page-DD9IGN6l.js → workout-detail-page-DT-c5cHL.js} +2 -2
- package/dist/index.html +9 -9
- package/dist/server/server/src/app.js +22 -3
- package/dist/server/server/src/health-weight-loss.js +114 -39
- package/dist/server/server/src/repositories/model-settings.js +9 -3
- package/dist/server/server/src/watch-mobile.js +28 -0
- package/dist/server/src/components/workbench-boxes/shared/generic-node-view.js +13 -5
- package/dist/server/src/lib/api.js +10 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/dist/assets/activity-page-CgF7K2ww.js +0 -1
- package/dist/assets/calendar-page-C1Wfd2Fy.js +0 -1
- package/dist/assets/calendar-rules-CaZXtlxt.js +0 -1
- package/dist/assets/companion-sync-lab-page-NgeK-O-P.js +0 -1
- package/dist/assets/entity-note-count-link-BrS1-O0o.js +0 -1
- package/dist/assets/execution-board-CpO2ch6v.js +0 -1
- package/dist/assets/floating-action-menu-zzC2r0Ob.js +0 -1
- package/dist/assets/goal-detail-page-JK_Nva8e.js +0 -1
- package/dist/assets/goals-page-yeoJ06Vw.js +0 -1
- package/dist/assets/habits-page-Dx5EhkJi.js +0 -1
- package/dist/assets/index-BHIKoiZ6.js +0 -19
- package/dist/assets/index-H8R-ABM3.css +0 -1
- package/dist/assets/insights-page-CujrosD_.js +0 -8
- package/dist/assets/kanban-page-Q9NuIz5w.js +0 -1
- package/dist/assets/knowledge-graph-page-DaJmlvvM.js +0 -1
- package/dist/assets/life-force-workspace-CLVexVnb.js +0 -1
- package/dist/assets/movement-page-ClaoTNuX.js +0 -1
- package/dist/assets/notes-page-DYI8s3NN.js +0 -1
- package/dist/assets/pill-cluster-7UZd_lHp.js +0 -1
- package/dist/assets/preferences-page-BrKEkmfD.js +0 -1
- package/dist/assets/project-collections-CZagCmeH.js +0 -1
- package/dist/assets/project-management-hierarchy-page-Dr7hW9PW.js +0 -1
- package/dist/assets/project-management-section-nav-BLdAgTge.js +0 -1
- package/dist/assets/projects-page-UKrby_5-.js +0 -1
- package/dist/assets/rewards-page-PZFPa6rR.js +0 -1
- package/dist/assets/scheduling-rules-editor-B9KNKsQz.js +0 -1
- package/dist/assets/settings-agents-page-DPx2F6wf.js +0 -6
- package/dist/assets/settings-bin-page-COwP3gjo.js +0 -1
- package/dist/assets/settings-calendar-page-C-ghE0YT.js +0 -5
- package/dist/assets/settings-data-page-CBubzKBw.js +0 -1
- package/dist/assets/settings-logs-page-uOuXMeBm.js +0 -1
- package/dist/assets/settings-mobile-page-C5rfj8_r.js +0 -1
- package/dist/assets/settings-models-page-DijmUWdU.js +0 -1
- package/dist/assets/settings-page-B4u5TR5g.js +0 -1
- package/dist/assets/settings-rewards-page-COiTwkMH.js +0 -1
- package/dist/assets/settings-users-page-DEGa5DNn.js +0 -1
- package/dist/assets/settings-wiki-page-Cvsiz5_e.js +0 -1
- package/dist/assets/sleep-page-BnSOwkEU.js +0 -1
- package/dist/assets/sports-page-l1RqXzA_.js +0 -1
- package/dist/assets/strategies-page-DEnPlpAs.js +0 -1
- package/dist/assets/strategy-detail-page-Ls8bxKeH.js +0 -1
- package/dist/assets/task-detail-page-CgrYgQLD.js +0 -1
- package/dist/assets/timebox-planning-dialog-Ww0NGLLo.js +0 -1
- package/dist/assets/today-page-CIuFHMi1.js +0 -1
- package/dist/assets/training-load-page-BIwc648i.js +0 -1
- package/dist/assets/weekly-review-page-BFpBe1kI.js +0 -1
- package/dist/assets/weight-loss-page-BgMoBpBt.js +0 -5
- package/dist/assets/wiki-article-markdown-gsPTXTg1.js +0 -4
- package/dist/assets/wiki-editor-page-BpAZHooY.js +0 -26
- package/dist/assets/wiki-ingest-history-page-C-ig8O22.js +0 -1
- package/dist/assets/wiki-ingest-modal-BK4eQgqs.js +0 -1
- package/dist/assets/wiki-page-CMTZ60Zt.js +0 -1
- package/dist/assets/workbench-flow-page-BIpWUcLJ.js +0 -5
- package/dist/assets/workbench-page-CtCjYSRe.js +0 -1
|
@@ -3,6 +3,7 @@ import { z } from "zod";
|
|
|
3
3
|
import { getDatabase, runInTransaction } from "./db.js";
|
|
4
4
|
import { getSettings } from "./repositories/settings.js";
|
|
5
5
|
import { getDefaultUser, resolveUserForMutation } from "./repositories/users.js";
|
|
6
|
+
import { readEncryptedSecret } from "./repositories/calendar.js";
|
|
6
7
|
const optionalNumberSchema = z
|
|
7
8
|
.union([z.coerce.number().finite(), z.null()])
|
|
8
9
|
.optional();
|
|
@@ -88,6 +89,11 @@ export const nutritionDailyActiveCaloriesUpdateSchema = z.object({
|
|
|
88
89
|
export const nutritionFoodLogCreateSchema = z.object({
|
|
89
90
|
userId: z.string().trim().min(1).optional(),
|
|
90
91
|
loggedAt: z.string().datetime().optional(),
|
|
92
|
+
dayKey: z
|
|
93
|
+
.string()
|
|
94
|
+
.regex(/^\d{4}-\d{2}-\d{2}$/)
|
|
95
|
+
.nullable()
|
|
96
|
+
.optional(),
|
|
91
97
|
mealLabel: z.string().trim().default(""),
|
|
92
98
|
source: z
|
|
93
99
|
.enum(["manual", "search", "barcode", "chatgpt", "photo", "saved_meal"])
|
|
@@ -210,6 +216,9 @@ function newId(prefix) {
|
|
|
210
216
|
function dayKey(value) {
|
|
211
217
|
return value.slice(0, 10);
|
|
212
218
|
}
|
|
219
|
+
function normalizeDayKey(value, fallbackIso) {
|
|
220
|
+
return value ?? dayKey(fallbackIso);
|
|
221
|
+
}
|
|
213
222
|
function jsonString(value) {
|
|
214
223
|
return JSON.stringify(value ?? null);
|
|
215
224
|
}
|
|
@@ -293,10 +302,9 @@ function getDailyEnergyOverride(userId, dateKey) {
|
|
|
293
302
|
return mapDailyEnergyOverride(row);
|
|
294
303
|
}
|
|
295
304
|
function buildStoredEnergyModel(input) {
|
|
296
|
-
const
|
|
297
|
-
const start = new Date(
|
|
298
|
-
start.setUTCDate(
|
|
299
|
-
const todayKey = today.toISOString().slice(0, 10);
|
|
305
|
+
const todayKey = input.dateKey;
|
|
306
|
+
const start = new Date(`${todayKey}T00:00:00.000Z`);
|
|
307
|
+
start.setUTCDate(start.getUTCDate() - 6);
|
|
300
308
|
const startKey = start.toISOString().slice(0, 10);
|
|
301
309
|
const dailySummaryRows = getDatabase()
|
|
302
310
|
.prepare(`SELECT date_key, metrics_json
|
|
@@ -344,6 +352,25 @@ function buildStoredEnergyModel(input) {
|
|
|
344
352
|
row.date_key,
|
|
345
353
|
n(row.movement_calories_kcal) || null
|
|
346
354
|
]));
|
|
355
|
+
const todayWorkoutEnergyFromRange = input.dayStartAt && input.dayEndAt
|
|
356
|
+
? getDatabase()
|
|
357
|
+
.prepare(`SELECT SUM(active_energy_kcal) AS active_energy_kcal,
|
|
358
|
+
SUM(total_energy_kcal) AS total_energy_kcal
|
|
359
|
+
FROM health_workout_sessions
|
|
360
|
+
WHERE user_id = ?
|
|
361
|
+
AND started_at >= ?
|
|
362
|
+
AND started_at < ?`)
|
|
363
|
+
.get(input.userId, input.dayStartAt, input.dayEndAt)
|
|
364
|
+
: null;
|
|
365
|
+
const todayMovementCaloriesFromRange = input.dayStartAt && input.dayEndAt
|
|
366
|
+
? getDatabase()
|
|
367
|
+
.prepare(`SELECT SUM(calories_kcal) AS movement_calories_kcal
|
|
368
|
+
FROM movement_trips
|
|
369
|
+
WHERE user_id = ?
|
|
370
|
+
AND started_at >= ?
|
|
371
|
+
AND started_at < ?`)
|
|
372
|
+
.get(input.userId, input.dayStartAt, input.dayEndAt)
|
|
373
|
+
: null;
|
|
347
374
|
const activeEnergyAverage = average(dailyHealthKit.map((day) => day.activeEnergyKcal));
|
|
348
375
|
const restingEnergyAverage = average(dailyHealthKit.map((day) => day.restingEnergyKcal));
|
|
349
376
|
const workoutEnergyAverage = average([...workoutByDay.values()]);
|
|
@@ -356,8 +383,14 @@ function buildStoredEnergyModel(input) {
|
|
|
356
383
|
const todayHealthKitActive = dailyHealthKit.find((day) => day.dateKey === todayKey)?.activeEnergyKcal ??
|
|
357
384
|
null;
|
|
358
385
|
const todayStepCount = dailyHealthKit.find((day) => day.dateKey === todayKey)?.stepCount ?? null;
|
|
359
|
-
const todayWorkoutEnergy =
|
|
360
|
-
|
|
386
|
+
const todayWorkoutEnergy = todayWorkoutEnergyFromRange != null
|
|
387
|
+
? n(todayWorkoutEnergyFromRange.active_energy_kcal) ||
|
|
388
|
+
n(todayWorkoutEnergyFromRange.total_energy_kcal) ||
|
|
389
|
+
null
|
|
390
|
+
: (workoutByDay.get(todayKey) ?? null);
|
|
391
|
+
const todayMovementCalories = todayMovementCaloriesFromRange != null
|
|
392
|
+
? n(todayMovementCaloriesFromRange.movement_calories_kcal) || null
|
|
393
|
+
: (movementByDay.get(todayKey) ?? null);
|
|
361
394
|
const todayWorkoutMovementCalories = todayWorkoutEnergy != null || todayMovementCalories != null
|
|
362
395
|
? n(todayWorkoutEnergy) + n(todayMovementCalories)
|
|
363
396
|
: null;
|
|
@@ -365,27 +398,35 @@ function buildStoredEnergyModel(input) {
|
|
|
365
398
|
stepCount: todayStepCount,
|
|
366
399
|
weightKg: input.latestWeightKg
|
|
367
400
|
});
|
|
401
|
+
const todayStepCaloriesForActiveBudget = todayStepEstimatedCalories != null &&
|
|
402
|
+
(todayWorkoutEnergy != null ||
|
|
403
|
+
todayMovementCalories != null ||
|
|
404
|
+
todayStepEstimatedCalories > baselineActiveCalories)
|
|
405
|
+
? todayStepEstimatedCalories
|
|
406
|
+
: null;
|
|
368
407
|
const todayFallbackPartCount = [
|
|
369
408
|
todayWorkoutEnergy,
|
|
370
409
|
todayMovementCalories,
|
|
371
|
-
|
|
410
|
+
todayStepCaloriesForActiveBudget
|
|
372
411
|
].filter((value) => value != null).length;
|
|
373
412
|
const todayFallbackActiveCalories = todayFallbackPartCount > 0
|
|
374
413
|
? n(todayWorkoutEnergy) +
|
|
375
414
|
n(todayMovementCalories) +
|
|
376
|
-
n(
|
|
415
|
+
n(todayStepCaloriesForActiveBudget)
|
|
377
416
|
: null;
|
|
378
417
|
const todayObservedActiveCalories = todayHealthKitActive ?? todayFallbackActiveCalories;
|
|
379
418
|
const todayFallbackSource = (() => {
|
|
380
419
|
if (todayWorkoutEnergy != null &&
|
|
381
420
|
todayMovementCalories != null &&
|
|
382
|
-
|
|
421
|
+
todayStepCaloriesForActiveBudget != null) {
|
|
383
422
|
return "today_workout_movement_step_energy";
|
|
384
423
|
}
|
|
385
|
-
if (todayWorkoutEnergy != null &&
|
|
424
|
+
if (todayWorkoutEnergy != null &&
|
|
425
|
+
todayStepCaloriesForActiveBudget != null) {
|
|
386
426
|
return "today_workout_step_energy";
|
|
387
427
|
}
|
|
388
|
-
if (todayMovementCalories != null &&
|
|
428
|
+
if (todayMovementCalories != null &&
|
|
429
|
+
todayStepCaloriesForActiveBudget != null) {
|
|
389
430
|
return "today_movement_step_energy";
|
|
390
431
|
}
|
|
391
432
|
if (todayWorkoutEnergy != null && todayMovementCalories != null) {
|
|
@@ -397,7 +438,7 @@ function buildStoredEnergyModel(input) {
|
|
|
397
438
|
if (todayMovementCalories != null) {
|
|
398
439
|
return "today_movement_trip_calories";
|
|
399
440
|
}
|
|
400
|
-
if (
|
|
441
|
+
if (todayStepCaloriesForActiveBudget != null) {
|
|
401
442
|
return "today_step_estimate";
|
|
402
443
|
}
|
|
403
444
|
return "default_active_calories";
|
|
@@ -416,7 +457,8 @@ function buildStoredEnergyModel(input) {
|
|
|
416
457
|
const estimatedTdeeKcal = activeBurnKcal != null && restingEnergyAverage != null
|
|
417
458
|
? round(activeBurnKcal + restingEnergyAverage, 0)
|
|
418
459
|
: input.inferredTdee;
|
|
419
|
-
const
|
|
460
|
+
const hasHealthKitDailyActiveEnergy = activeEnergyAverage != null;
|
|
461
|
+
const hasHealthKitEnergy = hasHealthKitDailyActiveEnergy ||
|
|
420
462
|
restingEnergyAverage != null ||
|
|
421
463
|
workoutEnergyAverage != null;
|
|
422
464
|
const hasMovementEnergy = movementCaloriesAverage != null;
|
|
@@ -454,6 +496,8 @@ function buildStoredEnergyModel(input) {
|
|
|
454
496
|
: null,
|
|
455
497
|
workoutEnergyKcal: workoutEnergyAverage != null ? round(workoutEnergyAverage, 0) : null,
|
|
456
498
|
averageCalorieIntake: input.averageCalories,
|
|
499
|
+
recentFoodLogCount: input.recentFoodLogCount,
|
|
500
|
+
recentFoodLogDayCount: input.recentFoodLogDayCount,
|
|
457
501
|
currentDeficitEstimate: estimatedTdeeKcal != null
|
|
458
502
|
? round(input.averageCalories - estimatedTdeeKcal, 0)
|
|
459
503
|
: null,
|
|
@@ -469,7 +513,7 @@ function buildStoredEnergyModel(input) {
|
|
|
469
513
|
exerciseMinutesAverage: average(dailyHealthKit.map((day) => day.exerciseMinutes)),
|
|
470
514
|
stepCountAverage: average(dailyHealthKit.map((day) => day.stepCount)),
|
|
471
515
|
sourceAvailability: {
|
|
472
|
-
healthKitDailyEnergy:
|
|
516
|
+
healthKitDailyEnergy: hasHealthKitDailyActiveEnergy,
|
|
473
517
|
movementTripCalories: hasMovementEnergy,
|
|
474
518
|
workoutEnergy: workoutEnergyAverage != null
|
|
475
519
|
}
|
|
@@ -657,6 +701,7 @@ export function createNutritionFoodLog(input) {
|
|
|
657
701
|
const parsed = nutritionFoodLogCreateSchema.parse(input);
|
|
658
702
|
const userId = resolveWriteUser(parsed.userId);
|
|
659
703
|
const loggedAt = parsed.loggedAt ?? nowIso();
|
|
704
|
+
const logDayKey = normalizeDayKey(parsed.dayKey, loggedAt);
|
|
660
705
|
const id = newId("meal");
|
|
661
706
|
const now = nowIso();
|
|
662
707
|
runInTransaction(() => {
|
|
@@ -666,7 +711,7 @@ export function createNutritionFoodLog(input) {
|
|
|
666
711
|
place_id, stay_id, workout_id, sleep_id, day_key, image_refs_json,
|
|
667
712
|
parser_provenance_json, links_json, created_at, updated_at
|
|
668
713
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
|
|
669
|
-
.run(id, userId, loggedAt, parsed.mealLabel, parsed.source, parsed.confirmationState, parsed.notes, parsed.placeId ?? null, parsed.stayId ?? null, parsed.workoutId ?? null, parsed.sleepId ?? null,
|
|
714
|
+
.run(id, userId, loggedAt, parsed.mealLabel, parsed.source, parsed.confirmationState, parsed.notes, parsed.placeId ?? null, parsed.stayId ?? null, parsed.workoutId ?? null, parsed.sleepId ?? null, logDayKey, jsonString(parsed.imageRefs), jsonString(parsed.parserProvenance), jsonString(parsed.links), now, now);
|
|
670
715
|
for (const item of parsed.items) {
|
|
671
716
|
insertMealItem(id, item);
|
|
672
717
|
}
|
|
@@ -680,6 +725,7 @@ export function patchNutritionFoodLog(logId, input) {
|
|
|
680
725
|
return null;
|
|
681
726
|
}
|
|
682
727
|
const nextLoggedAt = parsed.loggedAt ?? existing.loggedAt;
|
|
728
|
+
const nextDayKey = normalizeDayKey(parsed.dayKey, nextLoggedAt);
|
|
683
729
|
const now = nowIso();
|
|
684
730
|
runInTransaction(() => {
|
|
685
731
|
getDatabase()
|
|
@@ -689,7 +735,7 @@ export function patchNutritionFoodLog(logId, input) {
|
|
|
689
735
|
day_key = ?, image_refs_json = ?, parser_provenance_json = ?,
|
|
690
736
|
links_json = ?, updated_at = ?
|
|
691
737
|
WHERE id = ?`)
|
|
692
|
-
.run(nextLoggedAt, parsed.mealLabel ?? existing.mealLabel, parsed.source ?? existing.source, parsed.confirmationState ?? existing.confirmationState, parsed.notes ?? existing.notes, parsed.placeId !== undefined ? parsed.placeId : existing.placeId, parsed.stayId !== undefined ? parsed.stayId : existing.stayId, parsed.workoutId !== undefined ? parsed.workoutId : existing.workoutId, parsed.sleepId !== undefined ? parsed.sleepId : existing.sleepId,
|
|
738
|
+
.run(nextLoggedAt, parsed.mealLabel ?? existing.mealLabel, parsed.source ?? existing.source, parsed.confirmationState ?? existing.confirmationState, parsed.notes ?? existing.notes, parsed.placeId !== undefined ? parsed.placeId : existing.placeId, parsed.stayId !== undefined ? parsed.stayId : existing.stayId, parsed.workoutId !== undefined ? parsed.workoutId : existing.workoutId, parsed.sleepId !== undefined ? parsed.sleepId : existing.sleepId, nextDayKey, jsonString(parsed.imageRefs ?? existing.imageRefs), jsonString(parsed.parserProvenance ?? existing.parserProvenance), jsonString(parsed.links ?? existing.links), now, logId);
|
|
693
739
|
if (parsed.items) {
|
|
694
740
|
getDatabase()
|
|
695
741
|
.prepare(`DELETE FROM nutrition_meal_items WHERE log_id = ?`)
|
|
@@ -1035,9 +1081,8 @@ function listExperiments(userId, limit = 20) {
|
|
|
1035
1081
|
updatedAt: row.updated_at
|
|
1036
1082
|
}));
|
|
1037
1083
|
}
|
|
1038
|
-
function buildTodayLedger(logs, target, dynamicTargetCalories, activeAdjustmentCalories, activeCaloriesSource) {
|
|
1039
|
-
const
|
|
1040
|
-
const todayLogs = logs.filter((log) => log.dayKey === today);
|
|
1084
|
+
function buildTodayLedger(logs, target, dateKey, dynamicTargetCalories, activeAdjustmentCalories, activeCaloriesSource) {
|
|
1085
|
+
const todayLogs = logs.filter((log) => log.dayKey === dateKey);
|
|
1041
1086
|
const totals = todayLogs.reduce((acc, log) => ({
|
|
1042
1087
|
calories: acc.calories + log.totals.calories,
|
|
1043
1088
|
proteinGrams: acc.proteinGrams + log.totals.proteinGrams,
|
|
@@ -1058,7 +1103,7 @@ function buildTodayLedger(logs, target, dynamicTargetCalories, activeAdjustmentC
|
|
|
1058
1103
|
alcoholGrams: 0
|
|
1059
1104
|
});
|
|
1060
1105
|
return {
|
|
1061
|
-
dateKey
|
|
1106
|
+
dateKey,
|
|
1062
1107
|
meals: todayLogs,
|
|
1063
1108
|
totals,
|
|
1064
1109
|
plannedTargetCalories: target.calorieTarget,
|
|
@@ -1267,10 +1312,10 @@ function buildGeneratedHypotheses(logs, subjective, gut, appearance) {
|
|
|
1267
1312
|
}
|
|
1268
1313
|
return cards;
|
|
1269
1314
|
}
|
|
1270
|
-
export function getWeightLossViewData(userIds) {
|
|
1315
|
+
export function getWeightLossViewData(userIds, options = {}) {
|
|
1271
1316
|
const generatedAt = new Date().toISOString();
|
|
1272
1317
|
const userId = resolveReadUser(userIds);
|
|
1273
|
-
const todayKey = generatedAt.slice(0, 10);
|
|
1318
|
+
const todayKey = options.dateKey ?? generatedAt.slice(0, 10);
|
|
1274
1319
|
const targetRow = getDatabase()
|
|
1275
1320
|
.prepare(`SELECT * FROM nutrition_targets WHERE user_id = ?`)
|
|
1276
1321
|
.get(userId);
|
|
@@ -1287,7 +1332,10 @@ export function getWeightLossViewData(userIds) {
|
|
|
1287
1332
|
const recentLogs = logs.slice(0, 14);
|
|
1288
1333
|
const recentTotals = sumItems(recentLogs.flatMap((log) => log.items));
|
|
1289
1334
|
const trackedDays = new Set(logs.map((log) => log.dayKey)).size;
|
|
1290
|
-
const
|
|
1335
|
+
const recentTrackedDays = new Set(recentLogs.map((log) => log.dayKey)).size;
|
|
1336
|
+
const averageCalories = recentTrackedDays > 0
|
|
1337
|
+
? round(recentTotals.calories / recentTrackedDays, 0)
|
|
1338
|
+
: 0;
|
|
1291
1339
|
const inferredTdee = target.calorieTarget != null
|
|
1292
1340
|
? round(target.calorieTarget + Math.abs(n(target.weeklyRateGoalKg)) * 1100, 0)
|
|
1293
1341
|
: null;
|
|
@@ -1295,14 +1343,19 @@ export function getWeightLossViewData(userIds) {
|
|
|
1295
1343
|
const dailyActiveOverride = getDailyEnergyOverride(userId, todayKey);
|
|
1296
1344
|
const energyModel = buildStoredEnergyModel({
|
|
1297
1345
|
userId,
|
|
1346
|
+
dateKey: todayKey,
|
|
1347
|
+
dayStartAt: options.dayStartAt,
|
|
1348
|
+
dayEndAt: options.dayEndAt,
|
|
1298
1349
|
inferredTdee,
|
|
1299
1350
|
averageCalories,
|
|
1351
|
+
recentFoodLogCount: recentLogs.length,
|
|
1352
|
+
recentFoodLogDayCount: recentTrackedDays,
|
|
1300
1353
|
defaultActiveCalories,
|
|
1301
1354
|
latestWeightKg: weightTrend.latestWeightKg,
|
|
1302
1355
|
dailyActiveOverride
|
|
1303
1356
|
});
|
|
1304
1357
|
const todayTargetCalories = Math.max(0, round(target.calorieTarget + energyModel.todayTargetAdjustmentKcal, 0));
|
|
1305
|
-
const todayLedger = buildTodayLedger(logs, target, todayTargetCalories, energyModel.todayTargetAdjustmentKcal, energyModel.todayActiveCaloriesSource);
|
|
1358
|
+
const todayLedger = buildTodayLedger(logs, target, todayKey, todayTargetCalories, energyModel.todayTargetAdjustmentKcal, energyModel.todayActiveCaloriesSource);
|
|
1306
1359
|
return {
|
|
1307
1360
|
generatedAt,
|
|
1308
1361
|
userId,
|
|
@@ -1641,25 +1694,13 @@ function extractJsonObject(text) {
|
|
|
1641
1694
|
}
|
|
1642
1695
|
return trimmed;
|
|
1643
1696
|
}
|
|
1644
|
-
function
|
|
1645
|
-
const settings = getSettings();
|
|
1646
|
-
const selectedConnectionId = connectionId?.trim() ||
|
|
1647
|
-
settings.modelSettings.forgeAgent.basicChat.connectionId ||
|
|
1648
|
-
settings.modelSettings.forgeAgent.wiki.connectionId ||
|
|
1649
|
-
"";
|
|
1650
|
-
if (!selectedConnectionId) {
|
|
1651
|
-
return null;
|
|
1652
|
-
}
|
|
1653
|
-
const row = getDatabase()
|
|
1654
|
-
.prepare(`SELECT provider, auth_mode, base_url, model, secret_id, enabled
|
|
1655
|
-
FROM ai_model_connections
|
|
1656
|
-
WHERE id = ?`)
|
|
1657
|
-
.get(selectedConnectionId);
|
|
1697
|
+
function mapNutritionCodexProfileRow(row) {
|
|
1658
1698
|
if (!row ||
|
|
1659
1699
|
row.enabled !== 1 ||
|
|
1660
1700
|
row.provider !== "openai-codex" ||
|
|
1661
1701
|
row.auth_mode !== "oauth" ||
|
|
1662
|
-
!row.secret_id
|
|
1702
|
+
!row.secret_id ||
|
|
1703
|
+
!readEncryptedSecret(row.secret_id)) {
|
|
1663
1704
|
return null;
|
|
1664
1705
|
}
|
|
1665
1706
|
return {
|
|
@@ -1671,6 +1712,40 @@ function getNutritionCodexProfile(connectionId) {
|
|
|
1671
1712
|
metadata: {}
|
|
1672
1713
|
};
|
|
1673
1714
|
}
|
|
1715
|
+
function getNutritionCodexProfile(connectionId) {
|
|
1716
|
+
const settings = getSettings();
|
|
1717
|
+
const selectedConnectionIds = [
|
|
1718
|
+
connectionId?.trim(),
|
|
1719
|
+
settings.modelSettings.forgeAgent.basicChat.connectionId,
|
|
1720
|
+
settings.modelSettings.forgeAgent.wiki.connectionId
|
|
1721
|
+
].filter((id) => Boolean(id));
|
|
1722
|
+
for (const selectedConnectionId of new Set(selectedConnectionIds)) {
|
|
1723
|
+
const row = getDatabase()
|
|
1724
|
+
.prepare(`SELECT provider, auth_mode, base_url, model, secret_id, enabled
|
|
1725
|
+
FROM ai_model_connections
|
|
1726
|
+
WHERE id = ?`)
|
|
1727
|
+
.get(selectedConnectionId);
|
|
1728
|
+
const profile = mapNutritionCodexProfileRow(row);
|
|
1729
|
+
if (profile) {
|
|
1730
|
+
return profile;
|
|
1731
|
+
}
|
|
1732
|
+
}
|
|
1733
|
+
const fallbackRows = getDatabase()
|
|
1734
|
+
.prepare(`SELECT provider, auth_mode, base_url, model, secret_id, enabled
|
|
1735
|
+
FROM ai_model_connections
|
|
1736
|
+
WHERE provider = 'openai-codex'
|
|
1737
|
+
AND auth_mode = 'oauth'
|
|
1738
|
+
AND enabled = 1
|
|
1739
|
+
ORDER BY updated_at DESC`)
|
|
1740
|
+
.all();
|
|
1741
|
+
for (const row of fallbackRows) {
|
|
1742
|
+
const profile = mapNutritionCodexProfileRow(row);
|
|
1743
|
+
if (profile) {
|
|
1744
|
+
return profile;
|
|
1745
|
+
}
|
|
1746
|
+
}
|
|
1747
|
+
return null;
|
|
1748
|
+
}
|
|
1674
1749
|
const parsedMealItemSchema = z.object({
|
|
1675
1750
|
name: z.string().trim().min(1),
|
|
1676
1751
|
quantity: z.coerce.number().positive().default(1),
|
|
@@ -124,15 +124,16 @@ export function upsertAiModelConnection(input, secrets, options = {}) {
|
|
|
124
124
|
WHERE id = ?`)
|
|
125
125
|
.get(parsed.id.trim())
|
|
126
126
|
: undefined;
|
|
127
|
-
const id = existing?.id ??
|
|
128
|
-
`mdl_${randomUUID().replaceAll("-", "").slice(0, 10)}`;
|
|
127
|
+
const id = existing?.id ?? `mdl_${randomUUID().replaceAll("-", "").slice(0, 10)}`;
|
|
129
128
|
const now = new Date().toISOString();
|
|
130
129
|
const provider = parsed.provider;
|
|
131
130
|
const authMode = parsed.authMode ?? defaultAuthMode(provider);
|
|
132
131
|
const baseUrl = parsed.baseUrl?.trim() ||
|
|
133
132
|
existing?.base_url ||
|
|
134
133
|
defaultBaseUrlForProvider(provider);
|
|
135
|
-
let secretId = existing?.secret_id
|
|
134
|
+
let secretId = existing?.secret_id && readEncryptedSecret(existing.secret_id)
|
|
135
|
+
? existing.secret_id
|
|
136
|
+
: null;
|
|
136
137
|
let accountLabel = existing?.account_label ?? null;
|
|
137
138
|
if (parsed.provider === "mock") {
|
|
138
139
|
secretId = null;
|
|
@@ -152,6 +153,11 @@ export function upsertAiModelConnection(input, secrets, options = {}) {
|
|
|
152
153
|
accountLabel = options.oauthCredential.accountId;
|
|
153
154
|
storeEncryptedSecret(secretId, secrets.sealJson(options.oauthCredential), `${parsed.label} AI OAuth connection`);
|
|
154
155
|
}
|
|
156
|
+
if (parsed.provider !== "mock" && !secretId) {
|
|
157
|
+
throw new Error(authMode === "oauth"
|
|
158
|
+
? "Reconnect OAuth before saving this model connection. The existing credential is missing from Forge's encrypted secret store."
|
|
159
|
+
: "Enter the API key before saving this model connection. The existing credential is missing from Forge's encrypted secret store.");
|
|
160
|
+
}
|
|
155
161
|
getDatabase()
|
|
156
162
|
.prepare(`INSERT INTO ai_model_connections (
|
|
157
163
|
id, label, provider, auth_mode, base_url, model, account_label, secret_id, enabled, metadata_json, created_at, updated_at
|
|
@@ -968,8 +968,24 @@ function processWatchCommand(pairing, command) {
|
|
|
968
968
|
}
|
|
969
969
|
case "capture_event": {
|
|
970
970
|
const rawPayload = command.payload;
|
|
971
|
+
const reservedCapturePayloadKeys = new Set([
|
|
972
|
+
"eventType",
|
|
973
|
+
"recordedAt",
|
|
974
|
+
"promptId",
|
|
975
|
+
"linkedContext",
|
|
976
|
+
"placeId",
|
|
977
|
+
"stayId",
|
|
978
|
+
"tripId",
|
|
979
|
+
"workoutId"
|
|
980
|
+
]);
|
|
981
|
+
const eventPayload = typeof rawPayload.payload === "object" &&
|
|
982
|
+
rawPayload.payload != null &&
|
|
983
|
+
Array.isArray(rawPayload.payload) === false
|
|
984
|
+
? rawPayload.payload
|
|
985
|
+
: Object.fromEntries(Object.entries(rawPayload).filter(([key]) => !reservedCapturePayloadKeys.has(key)));
|
|
971
986
|
const payload = captureCommandPayloadSchema.parse({
|
|
972
987
|
...rawPayload,
|
|
988
|
+
payload: eventPayload,
|
|
973
989
|
linkedContext: typeof rawPayload.linkedContext === "object" &&
|
|
974
990
|
rawPayload.linkedContext != null &&
|
|
975
991
|
Array.isArray(rawPayload.linkedContext) === false
|
|
@@ -1101,6 +1117,15 @@ function commandErrorPayload(error) {
|
|
|
1101
1117
|
message: error instanceof Error ? error.message : "Unknown watch command error"
|
|
1102
1118
|
};
|
|
1103
1119
|
}
|
|
1120
|
+
function isPermanentWatchCommandError(error) {
|
|
1121
|
+
if (error instanceof ZodError) {
|
|
1122
|
+
return true;
|
|
1123
|
+
}
|
|
1124
|
+
if (error instanceof HttpError) {
|
|
1125
|
+
return error.statusCode >= 400 && error.statusCode < 500;
|
|
1126
|
+
}
|
|
1127
|
+
return false;
|
|
1128
|
+
}
|
|
1104
1129
|
export function ingestWatchCommandBatch(pairing, input) {
|
|
1105
1130
|
assertWatchReady(pairing);
|
|
1106
1131
|
const parsed = mobileWatchCommandBatchSchema.parse(input);
|
|
@@ -1126,6 +1151,9 @@ export function ingestWatchCommandBatch(pairing, input) {
|
|
|
1126
1151
|
}));
|
|
1127
1152
|
}
|
|
1128
1153
|
catch (error) {
|
|
1154
|
+
if (!isPermanentWatchCommandError(error)) {
|
|
1155
|
+
throw error;
|
|
1156
|
+
}
|
|
1129
1157
|
const errorPayload = commandErrorPayload(error);
|
|
1130
1158
|
receipts.push(writeActionReceipt(pairing, command, {
|
|
1131
1159
|
status: "failed",
|
|
@@ -3,22 +3,30 @@ import { Handle, Position } from "@xyflow/react";
|
|
|
3
3
|
import { useState } from "react";
|
|
4
4
|
import { InfoTooltip } from "../../../components/ui/info-tooltip.js";
|
|
5
5
|
import { cn } from "../../../lib/utils.js";
|
|
6
|
+
const nodeEyebrowClass = "flex items-center gap-1 text-[10px] uppercase tracking-[0.18em] text-[var(--ui-ink-faint)]";
|
|
7
|
+
const nodePillClass = "rounded-full border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] px-2.5 py-1 text-[10px] uppercase tracking-[0.16em] text-[var(--ui-ink-soft)]";
|
|
8
|
+
const nodeSoftPanelClass = "rounded-[18px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] px-3 py-2 text-[11px] text-[var(--ui-ink-soft)]";
|
|
9
|
+
const nodeCodePanelClass = "rounded-[18px] border border-[var(--ui-border-subtle)] bg-[var(--ui-code-bg)] p-3 text-[var(--ui-code-text)]";
|
|
6
10
|
function describePort(port) {
|
|
7
|
-
return [
|
|
11
|
+
return [
|
|
12
|
+
port.kind,
|
|
13
|
+
port.modelName,
|
|
14
|
+
port.itemKind ? `item:${port.itemKind}` : null
|
|
15
|
+
]
|
|
8
16
|
.filter(Boolean)
|
|
9
17
|
.join(" · ");
|
|
10
18
|
}
|
|
11
19
|
function PortList({ title, ports, align }) {
|
|
12
|
-
return (_jsxs("div", { className: "grid gap-1.5", children: [_jsxs("div", { className: cn(
|
|
20
|
+
return (_jsxs("div", { className: "grid gap-1.5", children: [_jsxs("div", { className: cn(nodeEyebrowClass, align === "left" ? "text-left" : "text-right"), children: [_jsx("span", { children: title }), _jsx(InfoTooltip, { content: align === "left"
|
|
13
21
|
? "Inputs are values this box expects from upstream nodes."
|
|
14
|
-
: "Outputs are values this box publishes for downstream nodes.", label: align === "left" ? "Explain box inputs" : "Explain box outputs" })] }), ports.length === 0 ? (_jsx("div", { className: "rounded-full border border-dashed border-
|
|
22
|
+
: "Outputs are values this box publishes for downstream nodes.", label: align === "left" ? "Explain box inputs" : "Explain box outputs" })] }), ports.length === 0 ? (_jsx("div", { className: "rounded-full border border-dashed border-[var(--ui-border-subtle)] px-3 py-1.5 text-[11px] text-[var(--ui-ink-faint)]", children: "None" })) : null, ports.map((port) => (_jsxs("div", { className: cn("relative rounded-[16px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] px-3 py-2 text-[11px] text-[var(--ui-ink-soft)]", align === "left" ? "pl-5 text-left" : "pr-5 text-right"), children: [_jsx(Handle, { type: align === "left" ? "target" : "source", position: align === "left" ? Position.Left : Position.Right, id: port.key, className: "!size-2.5 !border !border-[var(--ui-surface-1)] !bg-[var(--primary)]", style: {
|
|
15
23
|
[align]: 6
|
|
16
|
-
} }), _jsx("div", { children: port.label }), _jsx("div", { className: "mt-1 text-[10px] text-
|
|
24
|
+
} }), _jsx("div", { children: port.label }), _jsx("div", { className: "mt-1 text-[10px] text-[var(--ui-ink-faint)]", children: describePort(port) })] }, port.key)))] }));
|
|
17
25
|
}
|
|
18
26
|
export function createGenericWorkbenchNodeView(definition) {
|
|
19
27
|
return function GenericWorkbenchNodeView(_props) {
|
|
20
28
|
const [schemaOpen, setSchemaOpen] = useState(false);
|
|
21
|
-
return (_jsxs("div", { className: "min-w-[280px] rounded-[24px] border border-
|
|
29
|
+
return (_jsxs("div", { className: "min-w-[280px] rounded-[24px] border border-[var(--ui-border-subtle)] bg-[image:var(--ui-surface-modal)] p-3 shadow-[var(--ui-shadow-floating)]", children: [_jsxs("div", { className: "flex items-start justify-between gap-3", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("div", { className: "truncate text-sm font-semibold text-[var(--ui-ink-strong)]", children: definition.title }), _jsx("div", { className: "mt-1 line-clamp-2 text-[12px] leading-5 text-[var(--ui-ink-soft)]", children: definition.description })] }), _jsx("div", { className: nodePillClass, children: "box" })] }), definition.params.length > 0 ? (_jsxs("div", { className: `mt-3 ${nodeSoftPanelClass}`, children: [definition.params.length, " param", definition.params.length === 1 ? "" : "s", " configurable in the flow editor"] })) : null, definition.tools.length > 0 ? (_jsxs("div", { className: `mt-2 ${nodeSoftPanelClass}`, children: [definition.tools.length, " tool", definition.tools.length === 1 ? "" : "s", " available"] })) : null, _jsx("div", { className: "mt-2", children: _jsx("button", { type: "button", className: "rounded-full border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] px-3 py-1.5 text-[11px] text-[var(--ui-ink-soft)] transition hover:bg-[var(--ui-surface-hover)] hover:text-[var(--ui-ink-strong)]", onClick: () => setSchemaOpen((current) => !current), children: schemaOpen ? "Hide schema" : "Preview schema" }) }), _jsxs("div", { className: "mt-3 grid grid-cols-[minmax(0,1fr)_minmax(0,1fr)] gap-3", children: [_jsx(PortList, { title: "Inputs", ports: definition.inputs, align: "left" }), _jsx(PortList, { title: "Outputs", ports: definition.output, align: "right" })] }), schemaOpen ? (_jsxs("div", { className: `mt-3 ${nodeCodePanelClass}`, children: [_jsxs("div", { className: "flex items-center gap-2 text-[10px] uppercase tracking-[0.18em] text-[var(--ui-ink-faint)]", children: [_jsx("span", { children: "Box contract" }), _jsx(InfoTooltip, { content: "This preview summarizes what the box consumes, publishes, and what tools it can expose to AI nodes.", label: "Explain box contract preview" })] }), _jsx("pre", { className: "mt-2 overflow-auto whitespace-pre-wrap text-[11px] leading-5", children: JSON.stringify({
|
|
22
30
|
inputs: definition.inputs.map(({ key, kind, required, description, modelName, itemKind, shape, exampleValue }) => ({
|
|
23
31
|
key,
|
|
24
32
|
kind,
|
|
@@ -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
|
}
|
package/openclaw.plugin.json
CHANGED
|
@@ -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.
|
|
5
|
+
"version": "0.2.104",
|
|
6
6
|
"activation": {
|
|
7
7
|
"onStartup": true,
|
|
8
8
|
"onCapabilities": [
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{j as e,aC as x,c2 as k}from"./vendor-kIz9EZnX.js";import{j as A,i as C,k as E}from"./state-VYvD1QVP.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-BHIKoiZ6.js";import{P as _}from"./page-hero-oFHaAjtL.js";import{u as F,f as g,g as H,c as M}from"./table-C0VTeqw0.js";import{g as p,a as v}from"./entity-links-DwpxhW2H.js";import"./motion-CfdU2F35.js";import"./ui-CsEkP2V8.js";import"./forms-CmLAyGqz.js";import"./board-DqHzdCPQ.js";import"./graph-BTa79qum.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};
|