forge-openclaw-plugin 0.2.99 → 0.2.101
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-copy-Bj4h9OcF.js +1 -0
- package/dist/assets/activity-page-CpjuNSHw.js +1 -0
- package/dist/assets/ai-surface-workspace-DEAFZruS.js +1 -0
- package/dist/assets/atlas-panel-CdVNPotj.js +1 -0
- package/dist/assets/{board-Ju0h0SeG.js → board-BkDRaMp6.js} +1 -1
- package/dist/assets/calendar-display-preferences-Cid-2RnL.js +1 -0
- package/dist/assets/calendar-page-DNNt6lfz.js +1 -0
- package/dist/assets/calendar-rules-DNJFNsxi.js +1 -0
- package/dist/assets/calendar-ui-Cy1XRwzV.js +1 -0
- package/dist/assets/calendar-week-toolbar-BbPwYeN0.js +1 -0
- package/dist/assets/charts-P7EVhIog.js +36 -0
- package/dist/assets/companion-sync-lab-page-KxEDigM6.js +1 -0
- package/dist/assets/daily-metrics-dashboard-B3cqJgDt.js +1 -0
- package/dist/assets/date-keys-Cj1G3TOn.js +1 -0
- package/dist/assets/entity-links-DwpxhW2H.js +1 -0
- package/dist/assets/entity-note-count-link-DrhjJZ4i.js +1 -0
- package/dist/assets/entity-notes-surface-CkcRsKJQ.js +1 -0
- package/dist/assets/execution-board-D07gOocB.js +1 -0
- package/dist/assets/faceted-token-search-BxRRcM3q.js +1 -0
- package/dist/assets/flagship-signal-deck-cmy82b8_.js +1 -0
- package/dist/assets/floating-action-menu-Fs_ZiUMo.js +1 -0
- package/dist/assets/forms-BFlTgZ3W.js +1 -0
- package/dist/assets/goal-detail-page-CqLiNz4f.js +1 -0
- package/dist/assets/goals-page-BTk7mg_T.js +1 -0
- package/dist/assets/graph-BZV40eAE.css +1 -0
- package/dist/assets/graph-D6JLqDbD.js +318 -0
- package/dist/assets/habits-page-BJxagdzx.js +1 -0
- package/dist/assets/health-link-options-Cpx8w7uM.js +1 -0
- package/dist/assets/index-CF4J4R9L.js +19 -0
- package/dist/assets/index-CZbuZQjw.css +1 -0
- package/dist/assets/insight-flow-dialog-8f3D0GuC.js +1 -0
- package/dist/assets/insights-page-D6rOa7uk.js +8 -0
- package/dist/assets/kanban-page-XQ7Se6dH.js +1 -0
- package/dist/assets/knowledge-graph-page-BtAg8iv3.js +1 -0
- package/dist/assets/life-force-page-Dy0JTS2G.js +1 -0
- package/dist/assets/life-force-workspace-OfyB9HJM.js +1 -0
- package/dist/assets/maps-B-YMMjus.css +1 -0
- package/dist/assets/maps-ClgJoCjz.js +803 -0
- package/dist/assets/metric-tile-DKpo-8xw.js +1 -0
- package/dist/assets/{motion-DRPJkN3a.js → motion-BeD44FeG.js} +1 -1
- package/dist/assets/movement-page-Bg_T_Stx.js +1 -0
- package/dist/assets/note-markdown-N-uxD3Xt.js +3 -0
- package/dist/assets/note-tags-input-Cdu7wiw6.js +1 -0
- package/dist/assets/notes-page-CKXnF_KU.js +1 -0
- package/dist/assets/open-in-graph-button-IXe9SGth.js +1 -0
- package/dist/assets/orbit-map-Dzi6KliQ.js +1 -0
- package/dist/assets/overview-page-1miYqaVS.js +1 -0
- package/dist/assets/page-hero-DRy5b2MU.js +1 -0
- package/dist/assets/pill-cluster-C9QczVJ2.js +1 -0
- package/dist/assets/preference-entity-handoff-button-5PzUn42S.js +1 -0
- package/dist/assets/preferences-page-DtNaF5Q3.js +1 -0
- package/dist/assets/project-collections-xPz2mlRr.js +1 -0
- package/dist/assets/project-detail-page-BXK5-4xW.js +1 -0
- package/dist/assets/project-management-hierarchy-page-DtRpMABw.js +1 -0
- package/dist/assets/project-management-section-nav-P3ixzPa-.js +1 -0
- package/dist/assets/projects-page-C5ViRuf4.js +1 -0
- package/dist/assets/psyche-behaviors-page-Dco46sC4.js +5 -0
- package/dist/assets/psyche-flashcards-page-ZcoEB8gV.js +1 -0
- package/dist/assets/psyche-goal-map-page-CLBAQOI0.js +1 -0
- package/dist/assets/psyche-graph-k4tX2tdp.js +1 -0
- package/dist/assets/psyche-metrics-page-CuR9oqEy.js +1 -0
- package/dist/assets/psyche-mode-guide-page-hIVXcCnE.js +1 -0
- package/dist/assets/psyche-modes-page-0lYtBlhO.js +1 -0
- package/dist/assets/psyche-page-VZ9k9ISp.js +1 -0
- package/dist/assets/psyche-patterns-page-gx5nmdGq.js +5 -0
- package/dist/assets/psyche-questionnaire-builder-page-Bn0TOISd.js +1 -0
- package/dist/assets/psyche-questionnaire-detail-page-CmVzSd_s.js +1 -0
- package/dist/assets/psyche-questionnaire-run-detail-page-BsMbmXCG.js +1 -0
- package/dist/assets/psyche-questionnaire-run-page-CgkRL2vi.js +1 -0
- package/dist/assets/psyche-questionnaires-page-D7V8uLXM.js +1 -0
- package/dist/assets/psyche-report-detail-page-OlFq57eL.js +3 -0
- package/dist/assets/psyche-reports-page-dVUZjna1.js +1 -0
- package/dist/assets/psyche-schemas-HFmg37Wj.js +1 -0
- package/dist/assets/psyche-schemas-beliefs-page-BCgc8FUd.js +9 -0
- package/dist/assets/psyche-screen-time-page-B_6BT_WN.js +1 -0
- package/dist/assets/psyche-self-observation-page-CEG5mluK.js +1 -0
- package/dist/assets/psyche-values-page-DRbRfEd6.js +5 -0
- package/dist/assets/query-cache-IQ8W-LNC.js +1 -0
- package/dist/assets/report-chain-fields-CALCV3V5.js +1 -0
- package/dist/assets/rewards-page-DmC4R_Ps.js +1 -0
- package/dist/assets/scheduling-rules-editor-D02s70hr.js +1 -0
- package/dist/assets/schema-badge-BZO-qNhO.js +1 -0
- package/dist/assets/schema-visuals-D6nxjbYC.js +1 -0
- package/dist/assets/select-menu-fYyreSdQ.js +1 -0
- package/dist/assets/settings-agents-page-C_v_hMJF.js +6 -0
- package/dist/assets/settings-bin-page-DY5bg81n.js +1 -0
- package/dist/assets/settings-calendar-page-D1CzE6cg.js +5 -0
- package/dist/assets/settings-data-page-CHRQFU9H.js +1 -0
- package/dist/assets/settings-logs-page-B04pUwEv.js +1 -0
- package/dist/assets/settings-mobile-page-D9kTlYDS.js +1 -0
- package/dist/assets/settings-models-page-D26270R2.js +1 -0
- package/dist/assets/settings-page-DYDTFlnv.js +1 -0
- package/dist/assets/settings-rewards-page-cl4vqqO_.js +1 -0
- package/dist/assets/settings-section-nav-DSOuht_F.js +1 -0
- package/dist/assets/settings-users-page-BU79JB_T.js +1 -0
- package/dist/assets/settings-wiki-page-DwAUlyA3.js +1 -0
- package/dist/assets/sleep-page-D8NbdhyS.js +1 -0
- package/dist/assets/sports-page-CV4Cnzwn.js +1 -0
- package/dist/assets/state-B-4sS1xO.js +1 -0
- package/dist/assets/strategies-page-C4qvXnql.js +1 -0
- package/dist/assets/strategy-detail-page-DJLo5rfy.js +1 -0
- package/dist/assets/strategy-dialog-D3AuUlVz.js +1 -0
- package/dist/assets/{table-DewbFlTh.js → table-WfAPUppN.js} +1 -1
- package/dist/assets/task-detail-page-z-9u9rF0.js +1 -0
- package/dist/assets/timebox-planning-dialog-DB6FLqmI.js +1 -0
- package/dist/assets/today-page-BKlu6gx5.js +1 -0
- package/dist/assets/training-load-page-CyJQqo_3.js +1 -0
- package/dist/assets/{ui-C2IvSrAz.js → ui-C13Nbgas.js} +4 -4
- package/dist/assets/use-psyche-focus-target-C1C_XjYG.js +1 -0
- package/dist/assets/vendor-CRS-psbw.css +1 -0
- package/dist/assets/vendor-DHkYh85p.js +1052 -0
- package/dist/assets/vitals-page-qre17Nw8.js +1 -0
- package/dist/assets/weekly-review-page-Cz4vkRcx.js +1 -0
- package/dist/assets/weight-loss-page-BQrnOI0y.js +1 -0
- package/dist/assets/wiki-article-markdown-DdiR2TJE.js +4 -0
- package/dist/assets/wiki-editor-page-DqwoqVFb.js +26 -0
- package/dist/assets/wiki-ingest-history-page--evBLbOw.js +1 -0
- package/dist/assets/wiki-ingest-modal--ohzFnj2.js +1 -0
- package/dist/assets/wiki-page-B_VJFBPA.js +1 -0
- package/dist/assets/workbench-flow-page-Du62mtJU.js +5 -0
- package/dist/assets/workbench-page-4MKr3iRm.js +1 -0
- package/dist/assets/workout-detail-page-DfUbYYw1.js +2 -0
- package/dist/index.html +148 -9
- package/dist/openclaw/tools.js +340 -0
- package/dist/server/server/migrations/065_weight_loss_nutrition_insights.sql +236 -0
- package/dist/server/server/migrations/066_watch_action_receipts.sql +20 -0
- package/dist/server/server/src/app.js +266 -13
- package/dist/server/server/src/health-weight-loss.js +1378 -0
- package/dist/server/server/src/health.js +188 -35
- package/dist/server/server/src/openapi.js +449 -0
- package/dist/server/server/src/services/context.js +6 -7
- package/dist/server/server/src/services/doctor.js +39 -4
- package/dist/server/server/src/services/gamification.js +146 -34
- package/dist/server/server/src/watch-mobile.js +576 -4
- package/dist/server/server/src/web.js +18 -5
- package/dist/server/src/components/ui/info-tooltip.js +48 -3
- package/dist/server/src/lib/api.js +131 -0
- package/dist/server/src/lib/weight-loss-types.js +1 -0
- package/openclaw.plugin.json +14 -1
- package/package.json +1 -1
- package/server/migrations/065_weight_loss_nutrition_insights.sql +236 -0
- package/server/migrations/066_watch_action_receipts.sql +20 -0
- package/skills/forge-openclaw/SKILL.md +26 -5
- package/skills/forge-openclaw/entity_conversation_playbooks.md +134 -5
- package/skills/forge-openclaw/psyche_entity_playbooks.md +45 -0
- package/dist/assets/index-Cn5Wpwau.css +0 -1
- package/dist/assets/index-CwvGs8n4.js +0 -91
- package/dist/assets/vendor-B-Lq_OG3.css +0 -1
- package/dist/assets/vendor-DL2K5ayT.js +0 -2186
|
@@ -3082,6 +3082,7 @@ function summarizeChunkPayload(family, payload) {
|
|
|
3082
3082
|
return { daySummaries: payload.vitals?.daySummaries.length ?? 0 };
|
|
3083
3083
|
case "movement":
|
|
3084
3084
|
return {
|
|
3085
|
+
knownPlaces: payload.movement?.knownPlaces.length ?? 0,
|
|
3085
3086
|
stays: payload.movement?.stays.length ?? 0,
|
|
3086
3087
|
trips: payload.movement?.trips.length ?? 0
|
|
3087
3088
|
};
|
|
@@ -3210,6 +3211,76 @@ function applyWorkoutEvidenceChunkImmediately(session, payload) {
|
|
|
3210
3211
|
}
|
|
3211
3212
|
});
|
|
3212
3213
|
}
|
|
3214
|
+
function markMobileHealthSyncChunkApplied(input) {
|
|
3215
|
+
const now = nowIso();
|
|
3216
|
+
getDatabase()
|
|
3217
|
+
.prepare(`UPDATE health_mobile_sync_chunks
|
|
3218
|
+
SET applied_at = ?, payload_summary_json = ?, updated_at = ?
|
|
3219
|
+
WHERE sync_session_id = ? AND chunk_id = ?`)
|
|
3220
|
+
.run(now, JSON.stringify({
|
|
3221
|
+
...input.payloadSummary,
|
|
3222
|
+
immediateApplied: true,
|
|
3223
|
+
immediateAppliedAt: now,
|
|
3224
|
+
immediateAppliedMode: input.mode
|
|
3225
|
+
}), now, input.syncSessionId, input.chunkId);
|
|
3226
|
+
}
|
|
3227
|
+
function mobileHealthSyncChunkWasImmediatelyApplied(chunk) {
|
|
3228
|
+
const summary = safeJsonParse(chunk.payload_summary_json, {});
|
|
3229
|
+
return summary.immediateApplied === true;
|
|
3230
|
+
}
|
|
3231
|
+
function applyMovementChunkImmediately(session, payload) {
|
|
3232
|
+
if (!payload.movement) {
|
|
3233
|
+
return false;
|
|
3234
|
+
}
|
|
3235
|
+
const pairing = mobileSyncSessionPairing(session);
|
|
3236
|
+
ingestMovementSync(pairing, payload.movement);
|
|
3237
|
+
return true;
|
|
3238
|
+
}
|
|
3239
|
+
function applyScreenTimeChunkImmediately(session, payload) {
|
|
3240
|
+
if (!payload.screenTime) {
|
|
3241
|
+
return false;
|
|
3242
|
+
}
|
|
3243
|
+
const pairing = mobileSyncSessionPairing(session);
|
|
3244
|
+
const metadata = mobileSyncSessionMetadata(session);
|
|
3245
|
+
ingestScreenTimeSync(pairing, payload.screenTime, metadata.device?.sourceDevice ?? pairing.device_name ?? "iPhone");
|
|
3246
|
+
return true;
|
|
3247
|
+
}
|
|
3248
|
+
function applyVitalsChunkImmediately(session, payload) {
|
|
3249
|
+
if (!payload.vitals) {
|
|
3250
|
+
return false;
|
|
3251
|
+
}
|
|
3252
|
+
const pairing = mobileSyncSessionPairing(session);
|
|
3253
|
+
for (const daySummary of payload.vitals.daySummaries) {
|
|
3254
|
+
upsertVitalDaySummary(pairing.user_id, daySummary);
|
|
3255
|
+
}
|
|
3256
|
+
return true;
|
|
3257
|
+
}
|
|
3258
|
+
function applyMobileHealthSyncChunkImmediately(session, family, payload) {
|
|
3259
|
+
switch (family) {
|
|
3260
|
+
case "workout_summaries":
|
|
3261
|
+
case "workout_archive":
|
|
3262
|
+
applyWorkoutChunkImmediately(session, family, payload.workouts ?? []);
|
|
3263
|
+
return "workout_progressive_apply";
|
|
3264
|
+
case "workout_time_series":
|
|
3265
|
+
case "workout_routes":
|
|
3266
|
+
applyWorkoutEvidenceChunkImmediately(session, payload);
|
|
3267
|
+
return "workout_evidence_progressive_apply";
|
|
3268
|
+
case "movement":
|
|
3269
|
+
return applyMovementChunkImmediately(session, payload)
|
|
3270
|
+
? "movement_progressive_apply"
|
|
3271
|
+
: null;
|
|
3272
|
+
case "screen_time":
|
|
3273
|
+
return applyScreenTimeChunkImmediately(session, payload)
|
|
3274
|
+
? "screen_time_progressive_apply"
|
|
3275
|
+
: null;
|
|
3276
|
+
case "vitals":
|
|
3277
|
+
return applyVitalsChunkImmediately(session, payload)
|
|
3278
|
+
? "vitals_progressive_apply"
|
|
3279
|
+
: null;
|
|
3280
|
+
default:
|
|
3281
|
+
return null;
|
|
3282
|
+
}
|
|
3283
|
+
}
|
|
3213
3284
|
function updateMobileSyncSessionProgress(syncSessionId) {
|
|
3214
3285
|
const progress = mobileSyncSessionProgress(syncSessionId);
|
|
3215
3286
|
getDatabase()
|
|
@@ -3376,40 +3447,44 @@ export function ingestMobileHealthSyncChunk(syncSessionId, payload, rawPayloadJs
|
|
|
3376
3447
|
mode: wirePayload.mode
|
|
3377
3448
|
});
|
|
3378
3449
|
}
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3450
|
+
return runInTransaction(() => {
|
|
3451
|
+
const now = nowIso();
|
|
3452
|
+
const payloadSummary = {
|
|
3453
|
+
...summarizeChunkPayload(parsed.family, wirePayload.payload),
|
|
3454
|
+
clientByteCount: parsed.byteCount,
|
|
3455
|
+
actualByteCount,
|
|
3456
|
+
compressedByteCount: wirePayload.compressedByteCount ?? null,
|
|
3457
|
+
serverChecksum,
|
|
3458
|
+
mode: wirePayload.mode
|
|
3459
|
+
};
|
|
3460
|
+
getDatabase()
|
|
3461
|
+
.prepare(`INSERT INTO health_mobile_sync_chunks (
|
|
3462
|
+
id, sync_session_id, chunk_id, sequence, family, checksum_sha256,
|
|
3463
|
+
record_count, byte_count, payload_json, payload_summary_json,
|
|
3464
|
+
received_at, applied_at, created_at, updated_at
|
|
3465
|
+
)
|
|
3466
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?)`)
|
|
3467
|
+
.run(mobileSyncChunkRecordId(), syncSessionId, parsed.chunkId, parsed.sequence, parsed.family, serverChecksum, parsed.recordCount, actualByteCount, payloadJson, JSON.stringify(payloadSummary), now, now, now);
|
|
3468
|
+
const appliedMode = applyMobileHealthSyncChunkImmediately(session, parsed.family, wirePayload.payload);
|
|
3469
|
+
if (appliedMode) {
|
|
3470
|
+
markMobileHealthSyncChunkApplied({
|
|
3471
|
+
syncSessionId,
|
|
3472
|
+
chunkId: parsed.chunkId,
|
|
3473
|
+
payloadSummary,
|
|
3474
|
+
mode: appliedMode
|
|
3475
|
+
});
|
|
3476
|
+
}
|
|
3477
|
+
const progress = updateMobileSyncSessionProgress(syncSessionId);
|
|
3478
|
+
return {
|
|
3479
|
+
accepted: true,
|
|
3480
|
+
duplicate: false,
|
|
3481
|
+
receivedCount: progress.chunkCount,
|
|
3482
|
+
receivedBytes: progress.receivedBytes,
|
|
3483
|
+
progress
|
|
3484
|
+
};
|
|
3485
|
+
});
|
|
3411
3486
|
}
|
|
3412
|
-
function mergeMobileHealthSyncChunks(session, chunks) {
|
|
3487
|
+
function mergeMobileHealthSyncChunks(session, chunks, options = {}) {
|
|
3413
3488
|
const pairing = getDatabase()
|
|
3414
3489
|
.prepare(`SELECT * FROM companion_pairing_sessions WHERE id = ?`)
|
|
3415
3490
|
.get(session.pairing_session_id);
|
|
@@ -3449,6 +3524,17 @@ function mergeMobileHealthSyncChunks(session, chunks) {
|
|
|
3449
3524
|
const tombstones = [];
|
|
3450
3525
|
for (const chunk of chunks.sort((left, right) => left.sequence - right.sequence)) {
|
|
3451
3526
|
const payload = mobileHealthSyncChunkPayloadSchema.parse(safeJsonParse(chunk.payload_json, {}));
|
|
3527
|
+
const skipRecords = options.skipImmediatelyApplied === true &&
|
|
3528
|
+
mobileHealthSyncChunkWasImmediatelyApplied(chunk);
|
|
3529
|
+
if (skipRecords) {
|
|
3530
|
+
if (payload.movement?.settings) {
|
|
3531
|
+
assembled.movement.settings = payload.movement.settings;
|
|
3532
|
+
}
|
|
3533
|
+
if (payload.screenTime?.settings) {
|
|
3534
|
+
assembled.screenTime.settings = payload.screenTime.settings;
|
|
3535
|
+
}
|
|
3536
|
+
continue;
|
|
3537
|
+
}
|
|
3452
3538
|
if (payload.sleepNights) {
|
|
3453
3539
|
assembled.sleepNights.push(...payload.sleepNights);
|
|
3454
3540
|
}
|
|
@@ -3556,6 +3642,73 @@ function validateMobileSyncExpectedCounts(syncSessionId, expectedCounts) {
|
|
|
3556
3642
|
throw new HttpError(409, "missing_required_chunks", "The HealthKit sync session is missing required chunks.", { families: missingFamilies });
|
|
3557
3643
|
}
|
|
3558
3644
|
}
|
|
3645
|
+
function aggregateMobileSyncChunkCounts(chunks) {
|
|
3646
|
+
const counts = {
|
|
3647
|
+
sleepNights: 0,
|
|
3648
|
+
sleepSegments: 0,
|
|
3649
|
+
sleepRawRecords: 0,
|
|
3650
|
+
workouts: 0,
|
|
3651
|
+
vitalsDaySummaries: 0,
|
|
3652
|
+
movementKnownPlaces: 0,
|
|
3653
|
+
movementStays: 0,
|
|
3654
|
+
movementTrips: 0,
|
|
3655
|
+
screenTimeDaySummaries: 0,
|
|
3656
|
+
screenTimeHourlySegments: 0
|
|
3657
|
+
};
|
|
3658
|
+
for (const chunk of chunks) {
|
|
3659
|
+
const summary = safeJsonParse(chunk.payload_summary_json, {});
|
|
3660
|
+
const numberValue = (key) => typeof summary[key] === "number" && Number.isFinite(summary[key])
|
|
3661
|
+
? summary[key]
|
|
3662
|
+
: 0;
|
|
3663
|
+
switch (chunk.family) {
|
|
3664
|
+
case "sleep_nights":
|
|
3665
|
+
counts.sleepNights += numberValue("sleepNights");
|
|
3666
|
+
break;
|
|
3667
|
+
case "sleep_segments":
|
|
3668
|
+
counts.sleepSegments += numberValue("sleepSegments");
|
|
3669
|
+
break;
|
|
3670
|
+
case "sleep_raw_records":
|
|
3671
|
+
counts.sleepRawRecords += numberValue("sleepRawRecords");
|
|
3672
|
+
break;
|
|
3673
|
+
case "workout_summaries":
|
|
3674
|
+
case "workout_archive":
|
|
3675
|
+
counts.workouts += numberValue("workouts");
|
|
3676
|
+
break;
|
|
3677
|
+
case "vitals":
|
|
3678
|
+
counts.vitalsDaySummaries += numberValue("daySummaries");
|
|
3679
|
+
break;
|
|
3680
|
+
case "movement":
|
|
3681
|
+
counts.movementKnownPlaces += numberValue("knownPlaces");
|
|
3682
|
+
counts.movementStays += numberValue("stays");
|
|
3683
|
+
counts.movementTrips += numberValue("trips");
|
|
3684
|
+
break;
|
|
3685
|
+
case "screen_time":
|
|
3686
|
+
counts.screenTimeDaySummaries += numberValue("daySummaries");
|
|
3687
|
+
counts.screenTimeHourlySegments += numberValue("hourlySegments");
|
|
3688
|
+
break;
|
|
3689
|
+
}
|
|
3690
|
+
}
|
|
3691
|
+
return counts;
|
|
3692
|
+
}
|
|
3693
|
+
function syncReceiptWithChunkCounts(sync, chunks) {
|
|
3694
|
+
const counts = aggregateMobileSyncChunkCounts(chunks);
|
|
3695
|
+
return {
|
|
3696
|
+
...sync,
|
|
3697
|
+
imported: {
|
|
3698
|
+
...sync.imported,
|
|
3699
|
+
sleepNights: Math.max(sync.imported.sleepNights ?? 0, counts.sleepNights),
|
|
3700
|
+
sleepSegments: Math.max(sync.imported.sleepSegments ?? 0, counts.sleepSegments),
|
|
3701
|
+
sleepRawRecords: Math.max(sync.imported.sleepRawRecords ?? 0, counts.sleepRawRecords),
|
|
3702
|
+
workouts: Math.max(sync.imported.workouts, counts.workouts),
|
|
3703
|
+
vitalsDaySummaries: Math.max(sync.imported.vitalsDaySummaries ?? 0, counts.vitalsDaySummaries),
|
|
3704
|
+
movementKnownPlaces: Math.max(sync.imported.movementKnownPlaces ?? 0, counts.movementKnownPlaces),
|
|
3705
|
+
movementStays: Math.max(sync.imported.movementStays ?? 0, counts.movementStays),
|
|
3706
|
+
movementTrips: Math.max(sync.imported.movementTrips ?? 0, counts.movementTrips),
|
|
3707
|
+
screenTimeDaySummaries: Math.max(sync.imported.screenTimeDaySummaries ?? 0, counts.screenTimeDaySummaries),
|
|
3708
|
+
screenTimeHourlySegments: Math.max(sync.imported.screenTimeHourlySegments ?? 0, counts.screenTimeHourlySegments)
|
|
3709
|
+
}
|
|
3710
|
+
};
|
|
3711
|
+
}
|
|
3559
3712
|
function markMobileSyncSessionFailed(session, error) {
|
|
3560
3713
|
const now = nowIso();
|
|
3561
3714
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -3589,7 +3742,7 @@ export function completeMobileHealthSyncSession(syncSessionId, payload) {
|
|
|
3589
3742
|
try {
|
|
3590
3743
|
return runInTransaction(() => {
|
|
3591
3744
|
validateMobileSyncExpectedCounts(syncSessionId, parsed.expectedCounts);
|
|
3592
|
-
const { assembled, tombstones } = mergeMobileHealthSyncChunks(session, chunks);
|
|
3745
|
+
const { assembled, tombstones } = mergeMobileHealthSyncChunks(session, chunks, { skipImmediatelyApplied: true });
|
|
3593
3746
|
const sync = ingestMobileHealthSync(assembled);
|
|
3594
3747
|
const deletedWorkoutCount = applyWorkoutTombstones(pairing, tombstones);
|
|
3595
3748
|
upsertMobileSyncFamilyCursors(pairing, parsed.finalCursor);
|
|
@@ -3601,7 +3754,7 @@ export function completeMobileHealthSyncSession(syncSessionId, payload) {
|
|
|
3601
3754
|
WHERE id = ?`)
|
|
3602
3755
|
.run(JSON.stringify(parsed.expectedCounts), now, now, syncSessionId);
|
|
3603
3756
|
return {
|
|
3604
|
-
...sync,
|
|
3757
|
+
...syncReceiptWithChunkCounts(sync, chunks),
|
|
3605
3758
|
upload: {
|
|
3606
3759
|
syncSessionId,
|
|
3607
3760
|
chunks: chunks.length,
|