forge-openclaw-plugin 0.2.84 → 0.2.86

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/index.html CHANGED
@@ -13,7 +13,7 @@
13
13
  />
14
14
  <link rel="icon" type="image/png" href="/forge/assets/favicon-BCHm9dUV.ico" />
15
15
  <link rel="alternate icon" href="/forge/assets/favicon-BCHm9dUV.ico" />
16
- <script type="module" crossorigin src="/forge/assets/index-D7BNRYkR.js"></script>
16
+ <script type="module" crossorigin src="/forge/assets/index-BNvUaA6y.js"></script>
17
17
  <link rel="modulepreload" crossorigin href="/forge/assets/vendor-BVU0cZC9.js">
18
18
  <link rel="modulepreload" crossorigin href="/forge/assets/board-DKxKOwax.js">
19
19
  <link rel="modulepreload" crossorigin href="/forge/assets/ui-3Wd4pVaA.js">
@@ -901,10 +901,13 @@ function mapSleepRawLog(row) {
901
901
  createdAt: row.created_at
902
902
  };
903
903
  }
904
- function mapWorkoutSession(row) {
904
+ function mapWorkoutSession(row, options = {}) {
905
905
  const provenance = safeJsonParse(row.provenance_json, {});
906
906
  const derived = safeJsonParse(row.derived_json, {});
907
- const analytics = getStoredWorkoutAnalytics(row);
907
+ const includeAnalytics = options.includeAnalytics ?? true;
908
+ const analytics = includeAnalytics
909
+ ? getStoredWorkoutAnalytics(row)
910
+ : undefined;
908
911
  const presentation = buildWorkoutSessionPresentation({
909
912
  source: row.source,
910
913
  sourceType: row.source_type,
@@ -950,7 +953,7 @@ function mapWorkoutSession(row) {
950
953
  annotations: safeJsonParse(row.annotations_json, {}),
951
954
  provenance,
952
955
  derived,
953
- analytics,
956
+ ...(analytics ? { analytics } : {}),
954
957
  generatedFromHabitId: row.generated_from_habit_id,
955
958
  generatedFromCheckInId: row.generated_from_check_in_id,
956
959
  reconciliationStatus: row.reconciliation_status,
@@ -1151,7 +1154,7 @@ export function listSleepSessions(userIds) {
1151
1154
  return listSleepRows(userIds).map(mapSleepSession);
1152
1155
  }
1153
1156
  export function listWorkoutSessions(userIds) {
1154
- return listWorkoutRows(userIds).map(mapWorkoutSession);
1157
+ return listWorkoutRows(userIds).map((row) => mapWorkoutSession(row));
1155
1158
  }
1156
1159
  export function getSleepSessionById(sleepId) {
1157
1160
  ensureLegacyAppleSleepHistoryRepaired();
@@ -2928,7 +2931,7 @@ function mobileSyncSessionPairing(session) {
2928
2931
  function mobileSyncSessionMetadata(session) {
2929
2932
  return safeJsonParse(session.source_metadata_json, {});
2930
2933
  }
2931
- function applyWorkoutSummaryChunkImmediately(session, workouts) {
2934
+ function applyWorkoutChunkImmediately(session, family, workouts) {
2932
2935
  if (workouts.length === 0) {
2933
2936
  return;
2934
2937
  }
@@ -2982,10 +2985,58 @@ function applyWorkoutSummaryChunkImmediately(session, workouts) {
2982
2985
  .run(device.sourceDevice, JSON.stringify({
2983
2986
  progressiveChunk: true,
2984
2987
  syncSessionId: session.id,
2988
+ family,
2985
2989
  workouts: workouts.length
2986
2990
  }), workouts.length, createdCount, updatedCount, mergedCount, now, now, runId);
2987
2991
  });
2988
2992
  }
2993
+ function applyWorkoutEvidenceChunkImmediately(session, payload) {
2994
+ const timeSeries = payload.workoutTimeSeries ?? [];
2995
+ const routes = payload.workoutRoutes ?? [];
2996
+ if (timeSeries.length === 0 && routes.length === 0) {
2997
+ return;
2998
+ }
2999
+ const pairing = mobileSyncSessionPairing(session);
3000
+ runInTransaction(() => {
3001
+ const rowsToRecompute = new Map();
3002
+ for (const entry of timeSeries) {
3003
+ const row = getDatabase()
3004
+ .prepare(`SELECT *
3005
+ FROM health_workout_sessions
3006
+ WHERE user_id = ? AND source = 'apple_health' AND external_uid = ?`)
3007
+ .get(pairing.user_id, entry.externalUid);
3008
+ if (!row || entry.samples.length === 0) {
3009
+ continue;
3010
+ }
3011
+ upsertWorkoutTimeSeries({
3012
+ workoutId: row.id,
3013
+ userId: pairing.user_id,
3014
+ samples: entry.samples
3015
+ });
3016
+ rowsToRecompute.set(row.id, row);
3017
+ }
3018
+ for (const entry of routes) {
3019
+ const row = getDatabase()
3020
+ .prepare(`SELECT *
3021
+ FROM health_workout_sessions
3022
+ WHERE user_id = ? AND source = 'apple_health' AND external_uid = ?`)
3023
+ .get(pairing.user_id, entry.externalUid);
3024
+ if (!row || entry.routePoints.length === 0) {
3025
+ continue;
3026
+ }
3027
+ upsertWorkoutRoutePoints({
3028
+ workoutId: row.id,
3029
+ userId: pairing.user_id,
3030
+ points: entry.routePoints
3031
+ });
3032
+ rowsToRecompute.set(row.id, row);
3033
+ }
3034
+ for (const row of rowsToRecompute.values()) {
3035
+ recomputeAndStoreWorkoutAnalytics(row);
3036
+ summarizeUserHealthDay(pairing.user_id, dayKey(row.started_at));
3037
+ }
3038
+ });
3039
+ }
2989
3040
  function updateMobileSyncSessionProgress(syncSessionId) {
2990
3041
  const chunks = getDatabase()
2991
3042
  .prepare(`SELECT family, record_count, byte_count
@@ -3201,8 +3252,13 @@ export function ingestMobileHealthSyncChunk(syncSessionId, payload, rawPayloadJs
3201
3252
  serverChecksum,
3202
3253
  mode: wirePayload.mode
3203
3254
  }), now, now, now, now);
3204
- if (parsed.family === "workout_summaries") {
3205
- applyWorkoutSummaryChunkImmediately(session, wirePayload.payload.workouts ?? []);
3255
+ if (parsed.family === "workout_summaries" ||
3256
+ parsed.family === "workout_archive") {
3257
+ applyWorkoutChunkImmediately(session, parsed.family, wirePayload.payload.workouts ?? []);
3258
+ }
3259
+ else if (parsed.family === "workout_time_series" ||
3260
+ parsed.family === "workout_routes") {
3261
+ applyWorkoutEvidenceChunkImmediately(session, wirePayload.payload);
3206
3262
  }
3207
3263
  const progress = updateMobileSyncSessionProgress(syncSessionId);
3208
3264
  return {
@@ -3669,7 +3725,7 @@ export function getCompanionOverview(userIds) {
3669
3725
  WHERE user_id IN (${userIds.map(() => "?").join(",")})`
3670
3726
  : `SELECT COUNT(*) AS count FROM health_sleep_raw_logs`)
3671
3727
  .get(...(userIds ?? []));
3672
- const workouts = listWorkoutRows(userIds).map(mapWorkoutSession);
3728
+ const workouts = listWorkoutRows(userIds).map((row) => mapWorkoutSession(row));
3673
3729
  const vitalsRows = listDailySummaryRows("vitals", userIds);
3674
3730
  const vitalsMetricEntries = vitalsRows.reduce((sum, row) => {
3675
3731
  const metrics = safeJsonParse(row.metrics_json, {});
@@ -3897,9 +3953,17 @@ function buildFitnessVitalsTrend(rows) {
3897
3953
  }));
3898
3954
  }
3899
3955
  export function getFitnessViewData(userIds) {
3900
- const workouts = listWorkoutRows(userIds).map(mapWorkoutSession);
3956
+ const workoutRows = listWorkoutRows(userIds);
3957
+ const recent = workoutRows
3958
+ .slice(0, 40)
3959
+ .map((row) => mapWorkoutSession(row, { includeAnalytics: true }));
3960
+ const browserSessions = workoutRows
3961
+ .slice(0, 2000)
3962
+ .map((row, index) => mapWorkoutSession(row, { includeAnalytics: index < 40 }));
3963
+ const analysisSessions = workoutRows
3964
+ .slice(0, 500)
3965
+ .map((row) => mapWorkoutSession(row, { includeAnalytics: true }));
3901
3966
  const vitalsTrend = buildFitnessVitalsTrend(listDailySummaryRows("vitals", userIds));
3902
- const recent = workouts.slice(0, 40);
3903
3967
  const weekly = recent.filter((session) => Date.now() - Date.parse(session.startedAt) <= 7 * 24 * 60 * 60 * 1000);
3904
3968
  const weeklyVolumeSeconds = weekly.reduce((sum, session) => sum + session.durationSeconds, 0);
3905
3969
  const exerciseMinutes = weekly.reduce((sum, session) => sum + (session.exerciseMinutes ?? session.durationSeconds / 60), 0);
@@ -4012,8 +4076,8 @@ export function getFitnessViewData(userIds) {
4012
4076
  energyKcal: metrics.energyKcal
4013
4077
  })),
4014
4078
  vitalsTrend,
4015
- analysisSessions: workouts,
4016
- sessions: recent
4079
+ analysisSessions,
4080
+ sessions: browserSessions
4017
4081
  };
4018
4082
  }
4019
4083
  function averageNullable(values) {
@@ -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.84",
5
+ "version": "0.2.86",
6
6
  "activation": {
7
7
  "onStartup": true,
8
8
  "onCapabilities": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "forge-openclaw-plugin",
3
- "version": "0.2.84",
3
+ "version": "0.2.86",
4
4
  "description": "Curated OpenClaw adapter for the Forge collaboration API, UI entrypoint, and localhost auto-start runtime.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",