forge-openclaw-plugin 0.2.111 → 0.2.112
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-BdeoV3N4.js → activity-page-DPPiiyLO.js} +1 -1
- package/dist/assets/{ai-surface-workspace-BCbQUekv.js → ai-surface-workspace-B_fV9C4s.js} +1 -1
- package/dist/assets/{atlas-panel-DTnRBOZx.js → atlas-panel-BPTJyMcI.js} +1 -1
- package/dist/assets/{calendar-page-YDexXy_e.js → calendar-page-D4DcRQv7.js} +1 -1
- package/dist/assets/{calendar-rules-B_aOcMi3.js → calendar-rules-Cl_xMrBn.js} +1 -1
- package/dist/assets/{calendar-week-toolbar-BTbIzq3e.js → calendar-week-toolbar-BARSOEO9.js} +1 -1
- package/dist/assets/{companion-sync-lab-page-DKouMut9.js → companion-sync-lab-page-COFYDI3w.js} +1 -1
- package/dist/assets/{daily-metrics-dashboard-B3UCGG1t.js → daily-metrics-dashboard-BNGQlJkQ.js} +1 -1
- package/dist/assets/{entity-note-count-link-DUxobQUt.js → entity-note-count-link-BX93WYgh.js} +1 -1
- package/dist/assets/{entity-notes-surface-BdHBn8rx.js → entity-notes-surface-CBlKc-x-.js} +1 -1
- package/dist/assets/{execution-board-R5-oyf-Z.js → execution-board-Dh41UeKR.js} +1 -1
- package/dist/assets/{faceted-token-search-DtO6OUwQ.js → faceted-token-search-BgxYH_gW.js} +1 -1
- package/dist/assets/{flagship-signal-deck-B9k46sWA.js → flagship-signal-deck-bolzzK8q.js} +1 -1
- package/dist/assets/{floating-action-menu-DBzfnJOx.js → floating-action-menu-C5H-Wr2B.js} +1 -1
- package/dist/assets/{goal-detail-page-Mr_gnZ2l.js → goal-detail-page-CQeFnGDJ.js} +1 -1
- package/dist/assets/{goals-page-BG7FuqK1.js → goals-page-BTg9crEK.js} +1 -1
- package/dist/assets/{habits-page-CGdaOqL3.js → habits-page-C4vqk346.js} +1 -1
- package/dist/assets/{index-BP9__l6C.js → index-By3tQxiE.js} +2 -2
- package/dist/assets/{insight-flow-dialog-BUv06Vn-.js → insight-flow-dialog-JPYCsTKI.js} +1 -1
- package/dist/assets/{insights-page-BgD1_1we.js → insights-page-CFhVMlVL.js} +1 -1
- package/dist/assets/{kanban-page-DvZSN-Bi.js → kanban-page-DC3IDsnh.js} +1 -1
- package/dist/assets/{knowledge-graph-page-BXWXtPvo.js → knowledge-graph-page-DucyRYTZ.js} +1 -1
- package/dist/assets/{life-force-page-CwjHvpzu.js → life-force-page-UrXfxaSO.js} +1 -1
- package/dist/assets/{life-force-workspace-Ct70SsNQ.js → life-force-workspace-BhPNH7ad.js} +1 -1
- package/dist/assets/{metric-tile-DCxLxNli.js → metric-tile-DtRPjN4V.js} +1 -1
- package/dist/assets/{movement-page-C06ebiYk.js → movement-page-DCIdTQEN.js} +1 -1
- package/dist/assets/{note-markdown-3wB52NOn.js → note-markdown-CepDxj3v.js} +1 -1
- package/dist/assets/{note-tags-input-Blg5Gqz_.js → note-tags-input-BXYaDkOr.js} +1 -1
- package/dist/assets/{notes-page-CSkjizyK.js → notes-page-Bl1LlCLo.js} +1 -1
- package/dist/assets/{open-in-graph-button-CDHxzS8B.js → open-in-graph-button-C263zl5l.js} +1 -1
- package/dist/assets/{orbit-map-OV-GcUZl.js → orbit-map-Cb_AJyIj.js} +1 -1
- package/dist/assets/{overview-page-Cw3pI34n.js → overview-page-C2yLity7.js} +1 -1
- package/dist/assets/{page-hero-DgnhI5es.js → page-hero-5RTqAI88.js} +1 -1
- package/dist/assets/{pill-cluster-DIGkIvKN.js → pill-cluster-CBrrtZBm.js} +1 -1
- package/dist/assets/{preference-entity-handoff-button-LT_GBuqB.js → preference-entity-handoff-button-BQzg2J4k.js} +1 -1
- package/dist/assets/{preferences-page-Dkvz7nkU.js → preferences-page-DekYF-Yz.js} +1 -1
- package/dist/assets/{project-collections-BsAT8WYE.js → project-collections-BVXB8PPF.js} +1 -1
- package/dist/assets/{project-detail-page-DsJUWg8k.js → project-detail-page-CQlrLEn9.js} +1 -1
- package/dist/assets/{project-management-hierarchy-page-CIy0wAp8.js → project-management-hierarchy-page--mzM_zRE.js} +1 -1
- package/dist/assets/{project-management-section-nav-ClB2S1FW.js → project-management-section-nav-DQl0qRWy.js} +1 -1
- package/dist/assets/{projects-page-Da1bZLSH.js → projects-page-Dr_0NdVP.js} +1 -1
- package/dist/assets/{psyche-behaviors-page-D0uwf78o.js → psyche-behaviors-page-DOUaCWON.js} +1 -1
- package/dist/assets/{psyche-flashcards-page-e_qwwsOf.js → psyche-flashcards-page-BA84fO_X.js} +1 -1
- package/dist/assets/{psyche-goal-map-page-BIY028Wx.js → psyche-goal-map-page-DpXAg1Vf.js} +1 -1
- package/dist/assets/{psyche-graph-Y1UKALEm.js → psyche-graph-BxcbAbXt.js} +1 -1
- package/dist/assets/{psyche-metrics-page-DDkGJzo_.js → psyche-metrics-page-D8JQEoOl.js} +1 -1
- package/dist/assets/{psyche-mode-guide-page-C7mD9uiv.js → psyche-mode-guide-page-CBlIS5N_.js} +1 -1
- package/dist/assets/{psyche-modes-page-RUdaOQWr.js → psyche-modes-page-DE6KDK_1.js} +1 -1
- package/dist/assets/{psyche-page-D3FZy__c.js → psyche-page-Dkh7R2Dc.js} +1 -1
- package/dist/assets/{psyche-patterns-page-BSD35F41.js → psyche-patterns-page-DbCNRuww.js} +1 -1
- package/dist/assets/{psyche-questionnaire-builder-page-BpgUTMgj.js → psyche-questionnaire-builder-page-DnraDj1H.js} +1 -1
- package/dist/assets/{psyche-questionnaire-detail-page-DwjyjNhg.js → psyche-questionnaire-detail-page-DQ6zNQkk.js} +1 -1
- package/dist/assets/{psyche-questionnaire-run-detail-page-mJ-DgeB-.js → psyche-questionnaire-run-detail-page-BGrOIX0B.js} +1 -1
- package/dist/assets/{psyche-questionnaire-run-page-YuMBkH1G.js → psyche-questionnaire-run-page-Bg3BhBHb.js} +1 -1
- package/dist/assets/{psyche-questionnaires-page-CNglToKh.js → psyche-questionnaires-page-BEreTNjG.js} +1 -1
- package/dist/assets/{psyche-report-detail-page-CV6tbLxz.js → psyche-report-detail-page-Br9KlJBG.js} +1 -1
- package/dist/assets/{psyche-reports-page-BEOe8OPA.js → psyche-reports-page-Bk6QpAEF.js} +1 -1
- package/dist/assets/{psyche-schemas-beliefs-page-KIRqmO8C.js → psyche-schemas-beliefs-page-Db8d2ga7.js} +1 -1
- package/dist/assets/{psyche-screen-time-page-DvXuwgU1.js → psyche-screen-time-page-NazHUAkT.js} +1 -1
- package/dist/assets/{psyche-self-observation-page-E6yDPBm1.js → psyche-self-observation-page-H6FToucM.js} +1 -1
- package/dist/assets/{psyche-values-page-CSLG7C6a.js → psyche-values-page-DqM382-6.js} +1 -1
- package/dist/assets/{report-chain-fields-BYEp3tRr.js → report-chain-fields-nW4zndrM.js} +1 -1
- package/dist/assets/{rewards-page-pAa_MIte.js → rewards-page-C-tZVnIK.js} +1 -1
- package/dist/assets/{scheduling-rules-editor-BmGrjC9q.js → scheduling-rules-editor-DGF-044c.js} +1 -1
- package/dist/assets/{schema-badge-IVJ4SoeC.js → schema-badge-57AJ3FY-.js} +1 -1
- package/dist/assets/{select-menu-BE5AIdgO.js → select-menu-mfaklv7r.js} +1 -1
- package/dist/assets/{settings-agents-page-hqI0IaNx.js → settings-agents-page-CPJeeYg0.js} +1 -1
- package/dist/assets/{settings-bin-page-2bPjFtZ3.js → settings-bin-page-D3eX5aNf.js} +1 -1
- package/dist/assets/{settings-calendar-page-u_TfZJEh.js → settings-calendar-page-Bgx8NIsP.js} +1 -1
- package/dist/assets/{settings-data-page-DSQ14F2i.js → settings-data-page-BuMSUjpp.js} +1 -1
- package/dist/assets/{settings-logs-page-BU0CJhDM.js → settings-logs-page-CHb2GNUM.js} +1 -1
- package/dist/assets/{settings-mobile-page-B1fQ61BB.js → settings-mobile-page-ClUvXhJg.js} +1 -1
- package/dist/assets/{settings-models-page-B0Dis_c_.js → settings-models-page-njK6D7zc.js} +1 -1
- package/dist/assets/{settings-page-V4ibXIp9.js → settings-page-Dm--cx6B.js} +1 -1
- package/dist/assets/{settings-rewards-page-DeCGBNn5.js → settings-rewards-page-3aShLM3A.js} +1 -1
- package/dist/assets/{settings-section-nav-DV5umEkp.js → settings-section-nav-BWox23Qv.js} +1 -1
- package/dist/assets/{settings-users-page-BB8Dzd_P.js → settings-users-page-D-hEPpgQ.js} +1 -1
- package/dist/assets/{settings-wiki-page-B0k0KRsU.js → settings-wiki-page-CC-rOtDm.js} +1 -1
- package/dist/assets/{sleep-page-CPwUb-em.js → sleep-page-Cm_Ei2w1.js} +1 -1
- package/dist/assets/{sports-page-Cl4vZVwh.js → sports-page-CqSI-j-H.js} +1 -1
- package/dist/assets/{strategies-page-DhFXf-g3.js → strategies-page-BuJ4zLLv.js} +1 -1
- package/dist/assets/{strategy-detail-page-B2gotRKI.js → strategy-detail-page-CLmy0jbW.js} +1 -1
- package/dist/assets/{strategy-dialog-DD1bbrRB.js → strategy-dialog-DnJix1ys.js} +1 -1
- package/dist/assets/{surface-98myBzix.js → surface-DRNu5Fpz.js} +1 -1
- package/dist/assets/{task-detail-page-nx4eQbMW.js → task-detail-page-DTnNjW33.js} +1 -1
- package/dist/assets/{timebox-planning-dialog-DoZ9zUra.js → timebox-planning-dialog-DckIr1K4.js} +1 -1
- package/dist/assets/{today-page-7BH7Yne1.js → today-page-Cgk4HBPK.js} +1 -1
- package/dist/assets/{training-load-page-E82pNn1-.js → training-load-page-C-7iINaB.js} +1 -1
- package/dist/assets/{vitals-page-D64WlwVv.js → vitals-page-CqE4bYMf.js} +1 -1
- package/dist/assets/{weekly-review-page-BkRxxm7Q.js → weekly-review-page-DFmuzzig.js} +1 -1
- package/dist/assets/{weight-loss-page-DPbg7rTC.js → weight-loss-page-CWtgeuti.js} +3 -3
- package/dist/assets/{wiki-article-markdown-B0Q6082A.js → wiki-article-markdown-BkQg8Hne.js} +1 -1
- package/dist/assets/{wiki-editor-page-Tkb50wEA.js → wiki-editor-page-BYKcdX5I.js} +1 -1
- package/dist/assets/{wiki-ingest-history-page-CcQzkZRr.js → wiki-ingest-history-page-D_p4myw1.js} +1 -1
- package/dist/assets/{wiki-ingest-modal-D6yft0Qb.js → wiki-ingest-modal-C-CidueO.js} +1 -1
- package/dist/assets/{wiki-page-DEND1jmD.js → wiki-page-DYpg9ZEO.js} +1 -1
- package/dist/assets/{workbench-flow-page-CkNI03j_.js → workbench-flow-page-Q3r2IJty.js} +1 -1
- package/dist/assets/{workbench-page-W3zQpeWr.js → workbench-page-BFfWMGm6.js} +1 -1
- package/dist/assets/{workout-detail-page-BVSZv53z.js → workout-detail-page-DeDyz1Kk.js} +1 -1
- package/dist/index.html +1 -1
- package/dist/server/server/src/health-weight-loss.js +30 -11
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/maps-C-yOWiDN.js","assets/vendor-Dnkkx2co.js","assets/vendor-CRS-psbw.css","assets/maps-B-YMMjus.css"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{eH as D,S as H,E as B,c as j,C as c,T as E,I as P,B as I,eM as K,eN as W}from"./index-BP9__l6C.js";import{cc as Q,r as h,j as e,aC as O,bk as q,bG as Z,bL as G,dw as X,bX as Y}from"./vendor-Dnkkx2co.js";import{j as U,i as V,k as J}from"./state-vCcAT5Hq.js";import"./maps-C-yOWiDN.js";import{P as ee}from"./page-hero-DgnhI5es.js";import{R as C,A as te,C as ae,X as T,Y as _,T as z,a as se,e as ie,B as re}from"./charts-DFnEuIMB.js";import"./motion-Lt5B1XuE.js";import"./ui-C1iwpj2-.js";import"./forms-hB0SqEh-.js";import"./board-dIX6etHh.js";import"./graph-DDUZNRsO.js";const A={below_z1:"#94a3b8",zone_1:"#38bdf8",zone_2:"#22c55e",zone_3:"#eab308",zone_4:"#f97316",zone_5:"#ef4444"};function k(t){return t?`${Math.round(t/60)}m`:"0m"}function F(t,s){const o=new Intl.DateTimeFormat(void 0,{weekday:"short",day:"numeric",month:"short"}),n=new Intl.DateTimeFormat(void 0,{hour:"2-digit",minute:"2-digit"});return`${o.format(new Date(t))} · ${n.format(new Date(t))} - ${n.format(new Date(s))}`}function $(t){const s=typeof t=="number"?Math.floor(t):Number.parseFloat(String(t??""));return Number.isFinite(s)?new Date(s).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"}):""}function ne(t,s){if(typeof t=="number"){const o=Number.isInteger(t)?String(t):t.toFixed(1);return s&&s!=="count"?`${o} ${s}`:o}return typeof t=="boolean"?t?"Yes":"No":t==null?"n/a":String(t)}function oe(t){return t.length===0?null:{minLat:Math.min(...t.map(s=>s.latitude)),maxLat:Math.max(...t.map(s=>s.latitude)),minLon:Math.min(...t.map(s=>s.longitude)),maxLon:Math.max(...t.map(s=>s.longitude))}}function le({points:t}){var g;const s=h.useRef(null),[o,n]=h.useState(!1),u=typeof window<"u"?((g=window.localStorage.getItem("forge.map.tile-url"))==null?void 0:g.trim())??"":"";h.useEffect(()=>{let x=!1,i=null;if(!u||!s.current||t.length<2){n(!1);return}return K(()=>import("./maps-C-yOWiDN.js").then(r=>r.m),__vite__mapDeps([0,1,2,3])).then(r=>{x||!s.current||(i=new r.Map({container:s.current,style:{version:8,sources:{tiles:{type:"raster",tiles:[u],tileSize:256}},layers:[{id:"tiles",type:"raster",source:"tiles"}]},center:[t[0].longitude,t[0].latitude],zoom:13,attributionControl:!1}),i.on("load",()=>{if(!i)return;const d=t.map(m=>[m.longitude,m.latitude]);i.addSource("route",{type:"geojson",data:{type:"Feature",properties:{},geometry:{type:"LineString",coordinates:d}}}),i.addLayer({id:"route",type:"line",source:"route",paint:{"line-color":"#f97316","line-width":4}});const f=d.reduce((m,p)=>m.extend(p),new r.LngLatBounds(d[0],d[0]));i.fitBounds(f,{padding:44,maxZoom:15}),n(!0)}))}),()=>{x=!0,i==null||i.remove()}},[t,u]);const l=oe(t),v=h.useMemo(()=>{if(!l||t.length<2)return"";const x=720,i=280,r=Math.max(1e-6,l.maxLon-l.minLon),d=Math.max(1e-6,l.maxLat-l.minLat);return t.map(f=>{const m=(f.longitude-l.minLon)/r*x,p=i-(f.latitude-l.minLat)/d*i;return`${m.toFixed(1)},${p.toFixed(1)}`}).join(" ")},[l,t]);return e.jsxs("div",{className:"relative min-h-[280px] overflow-hidden rounded-[8px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)]",children:[e.jsx("div",{ref:s,className:"absolute inset-0"}),o?null:e.jsxs("svg",{viewBox:"0 0 720 280",className:"absolute inset-0 h-full w-full",children:[e.jsx("rect",{width:"720",height:"280",fill:"var(--ui-surface-1)"}),v?e.jsx("polyline",{points:v,fill:"none",stroke:"#f97316",strokeWidth:"5",strokeLinecap:"round",strokeLinejoin:"round"}):null]}),e.jsx("div",{className:"absolute left-3 top-3 max-w-[calc(100%-1.5rem)] rounded-[8px] border border-[var(--ui-border-subtle)] bg-[var(--surface-glass)] px-3 py-2 text-xs text-[var(--ui-ink-medium)] backdrop-blur",children:u?"Local-first map tiles configured":"No tile source configured; showing private route shape only"})]})}function de({zones:t}){return e.jsx("div",{className:"grid gap-3",children:t.map(s=>e.jsxs("div",{className:"grid gap-2",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3 text-sm",children:[e.jsx("span",{className:"min-w-0 break-words text-[var(--ui-ink-medium)] [overflow-wrap:anywhere]",children:s.label}),e.jsxs("span",{className:"shrink-0 text-[var(--ui-ink-strong)]",children:[(s.percentage*100).toFixed(1),"% · ",k(s.seconds)]})]}),e.jsx("div",{className:"h-2 overflow-hidden rounded-full bg-[var(--ui-surface-2)]",children:e.jsx("div",{className:"h-full rounded-full",style:{width:`${Math.max(1,s.percentage*100)}%`,background:A[s.key]??"#f8fafc"}})})]},s.key))})}function ke(){var p,N,b,y,S,L,M,R;const{workoutId:t=""}=Q(),s=U(),o=V({queryKey:["workout-detail",t],queryFn:()=>W(t),enabled:t.length>0}),n=o.data,[u,l]=h.useState(""),[v,g]=h.useState("");h.useEffect(()=>{n!=null&&n.workout&&(l(n.workout.meaningText??""),g(n.workout.tags.join(", ")))},[n==null?void 0:n.workout]);const x=J({mutationFn:()=>D(t,{meaningText:u,tags:v.split(",").map(a=>a.trim()).filter(Boolean)}),onSuccess:async()=>{await s.invalidateQueries({queryKey:["workout-detail",t]}),await s.invalidateQueries({queryKey:["forge-fitness"]})}});if(o.isLoading)return e.jsx(H,{title:"Loading workout"});if(o.isError||!n)return e.jsx(B,{eyebrow:"Workout detail",error:o.error??new Error("Forge could not load this workout detail."),onRetry:()=>void o.refetch()});const{workout:i,analytics:r,evidence:d}=n,f=d.timeSeries.filter(a=>a.metricKey==="heart_rate").map((a,w)=>({time:Date.parse(a.startedAt)+w/1e3,bpm:a.value})),m=r.zoneDurations.map(a=>({zone:a.label,minutes:Math.round(a.seconds/60),fill:A[a.key]??"#f8fafc"}));return e.jsxs("div",{className:"grid gap-6",children:[e.jsxs(O,{to:"/sports",className:"inline-flex w-fit items-center gap-2 text-sm text-[var(--ui-ink-soft)] transition hover:text-[var(--ui-ink-strong)]",children:[e.jsx(q,{className:"size-4"}),"Back to sports"]}),e.jsx(ee,{eyebrow:"Workout evidence",title:i.workoutTypeLabel??i.workoutType,description:`${F(i.startedAt,i.endedAt)} · ${i.sourceDevice||"Apple Health"}`,actions:e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx(j,{children:k(i.durationSeconds)}),e.jsxs(j,{tone:"meta",children:[r.confidence," HR zones"]}),(p=r.routeSummary)!=null&&p.hasRoute?e.jsxs(j,{tone:"meta",children:[r.routeSummary.pointCount," route points"]}):null]})}),e.jsxs("section",{className:"grid gap-4 lg:grid-cols-4",children:[e.jsxs(c,{children:[e.jsx("div",{className:"text-sm text-[var(--ui-ink-soft)]",children:"Avg HR"}),e.jsx("div",{className:"mt-3 font-display text-4xl text-[var(--ui-ink-strong)]",children:r.hrSummary.averageHr??i.averageHeartRate??"n/a"}),e.jsx("div",{className:"mt-1 text-sm text-[var(--ui-ink-faint)]",children:"bpm"})]}),e.jsxs(c,{children:[e.jsx("div",{className:"text-sm text-[var(--ui-ink-soft)]",children:"Max HR"}),e.jsx("div",{className:"mt-3 font-display text-4xl text-[var(--ui-ink-strong)]",children:r.hrSummary.maxHr??i.maxHeartRate??"n/a"}),e.jsx("div",{className:"mt-1 text-sm text-[var(--ui-ink-faint)]",children:"bpm"})]}),e.jsxs(c,{children:[e.jsx("div",{className:"text-sm text-[var(--ui-ink-soft)]",children:"Training load"}),e.jsx("div",{className:"mt-3 font-display text-4xl text-[var(--ui-ink-strong)]",children:r.load.trimp??"n/a"}),e.jsx("div",{className:"mt-1 text-sm text-[var(--ui-ink-faint)]",children:"Forge TRIMP"})]}),e.jsxs(c,{children:[e.jsx("div",{className:"text-sm text-[var(--ui-ink-soft)]",children:"HR coverage"}),e.jsxs("div",{className:"mt-3 font-display text-4xl text-[var(--ui-ink-strong)]",children:[Math.round((r.dataQuality.sampleCoverage??0)*100),"%"]}),e.jsxs("div",{className:"mt-1 text-sm text-[var(--ui-ink-faint)]",children:[r.dataQuality.heartRateSampleCount??0," samples"]})]})]}),e.jsxs("section",{className:"grid min-w-0 gap-4 xl:grid-cols-[minmax(0,1.25fr)_minmax(280px,0.75fr)]",children:[e.jsxs(c,{className:"min-h-[360px] min-w-0 overflow-hidden",children:[e.jsxs("div",{className:"flex items-center gap-2 text-[var(--ui-ink-strong)]",children:[e.jsx(Z,{className:"size-4 text-[var(--primary)]"}),"Heart-rate timeline"]}),e.jsx("div",{className:"mt-4 h-[300px]",children:f.length>0?e.jsx(C,{width:"100%",height:"100%",children:e.jsxs(te,{data:f,children:[e.jsx("defs",{children:e.jsxs("linearGradient",{id:"hrFill",x1:"0",y1:"0",x2:"0",y2:"1",children:[e.jsx("stop",{offset:"0%",stopColor:"#ef4444",stopOpacity:.38}),e.jsx("stop",{offset:"100%",stopColor:"#ef4444",stopOpacity:.04})]})}),e.jsx(ae,{stroke:"var(--ui-border-subtle)",vertical:!1}),e.jsx(T,{dataKey:"time",interval:"preserveStartEnd",tick:{fill:"var(--ui-ink-soft)",fontSize:11},tickFormatter:$,type:"number",domain:["dataMin","dataMax"]}),e.jsx(_,{tick:{fill:"var(--ui-ink-soft)",fontSize:11},width:42}),e.jsx(z,{labelFormatter:$,contentStyle:{background:"var(--surface-glass)",border:"1px solid var(--ui-border-subtle)",borderRadius:8,color:"var(--ui-ink-strong)"}}),e.jsx(se,{type:"monotone",dataKey:"bpm",stroke:"#ef4444",fill:"url(#hrFill)",strokeWidth:2,dot:!1})]})}):e.jsx("div",{className:"grid h-full place-items-center rounded-[8px] bg-[var(--ui-surface-1)] text-sm text-[var(--ui-ink-soft)]",children:"No raw HR timeline has been synced for this workout yet."})})]}),e.jsxs(c,{className:"min-w-0 overflow-hidden",children:[e.jsxs("div",{className:"flex items-center gap-2 text-[var(--ui-ink-strong)]",children:[e.jsx(G,{className:"size-4 text-[var(--primary)]"}),"Zone mix"]}),e.jsx("div",{className:"mt-4",children:e.jsx(de,{zones:r.zoneDurations})}),e.jsx("div",{className:"mt-5 h-[180px]",children:e.jsx(C,{width:"100%",height:"100%",children:e.jsxs(ie,{data:m,children:[e.jsx(T,{dataKey:"zone",tick:{fill:"var(--ui-ink-soft)",fontSize:10}}),e.jsx(_,{tick:{fill:"var(--ui-ink-soft)",fontSize:10},width:34}),e.jsx(z,{contentStyle:{background:"var(--surface-glass)",border:"1px solid var(--ui-border-subtle)",borderRadius:8,color:"var(--ui-ink-strong)"}}),e.jsx(re,{dataKey:"minutes",radius:[4,4,0,0]})]})})})]})]}),e.jsxs("section",{className:"grid min-w-0 gap-4 xl:grid-cols-[minmax(0,1fr)_360px]",children:[e.jsxs(c,{className:"min-w-0 overflow-hidden",children:[e.jsxs("div",{className:"flex items-center gap-2 text-[var(--ui-ink-strong)]",children:[e.jsx(X,{className:"size-4 text-[var(--primary)]"}),"Route"]}),e.jsx("div",{className:"mt-4",children:d.routePoints.length>1?e.jsx(le,{points:d.routePoints}):e.jsx("div",{className:"grid min-h-[240px] place-items-center rounded-[8px] bg-[var(--ui-surface-1)] text-sm text-[var(--ui-ink-soft)]",children:"No route evidence is available for this workout."})})]}),e.jsxs(c,{className:"min-w-0 overflow-hidden",children:[e.jsx("div",{className:"text-[var(--ui-ink-strong)]",children:"Captured metrics"}),e.jsx("div",{className:"mt-4 grid gap-3",children:(((N=i.details)==null?void 0:N.metrics)??[]).slice(0,14).map(a=>e.jsxs("div",{className:"min-w-0 rounded-[8px] bg-[var(--ui-surface-1)] px-3 py-2",children:[e.jsx("div",{className:"break-words text-sm text-[var(--ui-ink-soft)] [overflow-wrap:anywhere]",children:a.label}),e.jsx("div",{className:"mt-1 break-words text-[var(--ui-ink-strong)] [overflow-wrap:anywhere]",children:ne(a.value,a.unit)})]},`${a.category}:${a.key}:${a.statistic}`))})]})]}),e.jsxs("section",{className:"grid min-w-0 gap-4 lg:grid-cols-[minmax(0,1fr)_minmax(280px,0.7fr)]",children:[e.jsxs(c,{className:"min-w-0 overflow-hidden",children:[e.jsx("div",{className:"text-[var(--ui-ink-strong)]",children:"Events and phases"}),e.jsxs("div",{className:"mt-4 grid gap-3",children:[[...((b=i.details)==null?void 0:b.events)??[],...((y=i.details)==null?void 0:y.components)??[]].slice(0,18).map((a,w)=>e.jsxs("div",{className:"min-w-0 rounded-[8px] bg-[var(--ui-surface-1)] px-4 py-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[e.jsx("div",{className:"min-w-0 break-words text-[var(--ui-ink-strong)] [overflow-wrap:anywhere]",children:"label"in a?a.label:a.activity.canonicalLabel}),e.jsx(j,{tone:"meta",children:k(a.durationSeconds)})]}),e.jsx("div",{className:"mt-1 text-sm text-[var(--ui-ink-soft)]",children:F(a.startedAt,a.endedAt??a.startedAt)})]},`${"type"in a?a.type:a.externalUid}:${a.startedAt}:${w}`)),(((L=(S=i.details)==null?void 0:S.events)==null?void 0:L.length)??0)+(((R=(M=i.details)==null?void 0:M.components)==null?void 0:R.length)??0)===0?e.jsx("div",{className:"rounded-[8px] bg-[var(--ui-surface-1)] p-4 text-sm text-[var(--ui-ink-soft)]",children:"No provider events or phases were captured."}):null]})]}),e.jsxs(c,{className:"min-w-0 overflow-hidden",children:[e.jsx("div",{className:"text-[var(--ui-ink-strong)]",children:"Reflection"}),e.jsxs("div",{className:"mt-4 grid gap-4",children:[e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:"text-sm text-[var(--ui-ink-soft)]",children:"Meaning and impact"}),e.jsx(E,{className:"min-h-[160px]",value:u,onChange:a=>l(a.target.value)})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:"text-sm text-[var(--ui-ink-soft)]",children:"Tags"}),e.jsx(P,{value:v,onChange:a=>g(a.target.value)})]}),e.jsxs(I,{type:"button",pending:x.isPending,pendingLabel:"Saving",onClick:()=>x.mutate(),children:[e.jsx(Y,{className:"size-4"}),"Save reflection"]})]})]})]})]})}export{ke as WorkoutDetailPage};
|
|
2
|
+
import{eH as D,S as H,E as B,c as j,C as c,T as E,I as P,B as I,eM as K,eN as W}from"./index-By3tQxiE.js";import{cc as Q,r as h,j as e,aC as O,bk as q,bG as Z,bL as G,dw as X,bX as Y}from"./vendor-Dnkkx2co.js";import{j as U,i as V,k as J}from"./state-vCcAT5Hq.js";import"./maps-C-yOWiDN.js";import{P as ee}from"./page-hero-5RTqAI88.js";import{R as C,A as te,C as ae,X as T,Y as _,T as z,a as se,e as ie,B as re}from"./charts-DFnEuIMB.js";import"./motion-Lt5B1XuE.js";import"./ui-C1iwpj2-.js";import"./forms-hB0SqEh-.js";import"./board-dIX6etHh.js";import"./graph-DDUZNRsO.js";const A={below_z1:"#94a3b8",zone_1:"#38bdf8",zone_2:"#22c55e",zone_3:"#eab308",zone_4:"#f97316",zone_5:"#ef4444"};function k(t){return t?`${Math.round(t/60)}m`:"0m"}function F(t,s){const o=new Intl.DateTimeFormat(void 0,{weekday:"short",day:"numeric",month:"short"}),n=new Intl.DateTimeFormat(void 0,{hour:"2-digit",minute:"2-digit"});return`${o.format(new Date(t))} · ${n.format(new Date(t))} - ${n.format(new Date(s))}`}function $(t){const s=typeof t=="number"?Math.floor(t):Number.parseFloat(String(t??""));return Number.isFinite(s)?new Date(s).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"}):""}function ne(t,s){if(typeof t=="number"){const o=Number.isInteger(t)?String(t):t.toFixed(1);return s&&s!=="count"?`${o} ${s}`:o}return typeof t=="boolean"?t?"Yes":"No":t==null?"n/a":String(t)}function oe(t){return t.length===0?null:{minLat:Math.min(...t.map(s=>s.latitude)),maxLat:Math.max(...t.map(s=>s.latitude)),minLon:Math.min(...t.map(s=>s.longitude)),maxLon:Math.max(...t.map(s=>s.longitude))}}function le({points:t}){var g;const s=h.useRef(null),[o,n]=h.useState(!1),u=typeof window<"u"?((g=window.localStorage.getItem("forge.map.tile-url"))==null?void 0:g.trim())??"":"";h.useEffect(()=>{let x=!1,i=null;if(!u||!s.current||t.length<2){n(!1);return}return K(()=>import("./maps-C-yOWiDN.js").then(r=>r.m),__vite__mapDeps([0,1,2,3])).then(r=>{x||!s.current||(i=new r.Map({container:s.current,style:{version:8,sources:{tiles:{type:"raster",tiles:[u],tileSize:256}},layers:[{id:"tiles",type:"raster",source:"tiles"}]},center:[t[0].longitude,t[0].latitude],zoom:13,attributionControl:!1}),i.on("load",()=>{if(!i)return;const d=t.map(m=>[m.longitude,m.latitude]);i.addSource("route",{type:"geojson",data:{type:"Feature",properties:{},geometry:{type:"LineString",coordinates:d}}}),i.addLayer({id:"route",type:"line",source:"route",paint:{"line-color":"#f97316","line-width":4}});const f=d.reduce((m,p)=>m.extend(p),new r.LngLatBounds(d[0],d[0]));i.fitBounds(f,{padding:44,maxZoom:15}),n(!0)}))}),()=>{x=!0,i==null||i.remove()}},[t,u]);const l=oe(t),v=h.useMemo(()=>{if(!l||t.length<2)return"";const x=720,i=280,r=Math.max(1e-6,l.maxLon-l.minLon),d=Math.max(1e-6,l.maxLat-l.minLat);return t.map(f=>{const m=(f.longitude-l.minLon)/r*x,p=i-(f.latitude-l.minLat)/d*i;return`${m.toFixed(1)},${p.toFixed(1)}`}).join(" ")},[l,t]);return e.jsxs("div",{className:"relative min-h-[280px] overflow-hidden rounded-[8px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)]",children:[e.jsx("div",{ref:s,className:"absolute inset-0"}),o?null:e.jsxs("svg",{viewBox:"0 0 720 280",className:"absolute inset-0 h-full w-full",children:[e.jsx("rect",{width:"720",height:"280",fill:"var(--ui-surface-1)"}),v?e.jsx("polyline",{points:v,fill:"none",stroke:"#f97316",strokeWidth:"5",strokeLinecap:"round",strokeLinejoin:"round"}):null]}),e.jsx("div",{className:"absolute left-3 top-3 max-w-[calc(100%-1.5rem)] rounded-[8px] border border-[var(--ui-border-subtle)] bg-[var(--surface-glass)] px-3 py-2 text-xs text-[var(--ui-ink-medium)] backdrop-blur",children:u?"Local-first map tiles configured":"No tile source configured; showing private route shape only"})]})}function de({zones:t}){return e.jsx("div",{className:"grid gap-3",children:t.map(s=>e.jsxs("div",{className:"grid gap-2",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3 text-sm",children:[e.jsx("span",{className:"min-w-0 break-words text-[var(--ui-ink-medium)] [overflow-wrap:anywhere]",children:s.label}),e.jsxs("span",{className:"shrink-0 text-[var(--ui-ink-strong)]",children:[(s.percentage*100).toFixed(1),"% · ",k(s.seconds)]})]}),e.jsx("div",{className:"h-2 overflow-hidden rounded-full bg-[var(--ui-surface-2)]",children:e.jsx("div",{className:"h-full rounded-full",style:{width:`${Math.max(1,s.percentage*100)}%`,background:A[s.key]??"#f8fafc"}})})]},s.key))})}function ke(){var p,N,b,y,S,L,M,R;const{workoutId:t=""}=Q(),s=U(),o=V({queryKey:["workout-detail",t],queryFn:()=>W(t),enabled:t.length>0}),n=o.data,[u,l]=h.useState(""),[v,g]=h.useState("");h.useEffect(()=>{n!=null&&n.workout&&(l(n.workout.meaningText??""),g(n.workout.tags.join(", ")))},[n==null?void 0:n.workout]);const x=J({mutationFn:()=>D(t,{meaningText:u,tags:v.split(",").map(a=>a.trim()).filter(Boolean)}),onSuccess:async()=>{await s.invalidateQueries({queryKey:["workout-detail",t]}),await s.invalidateQueries({queryKey:["forge-fitness"]})}});if(o.isLoading)return e.jsx(H,{title:"Loading workout"});if(o.isError||!n)return e.jsx(B,{eyebrow:"Workout detail",error:o.error??new Error("Forge could not load this workout detail."),onRetry:()=>void o.refetch()});const{workout:i,analytics:r,evidence:d}=n,f=d.timeSeries.filter(a=>a.metricKey==="heart_rate").map((a,w)=>({time:Date.parse(a.startedAt)+w/1e3,bpm:a.value})),m=r.zoneDurations.map(a=>({zone:a.label,minutes:Math.round(a.seconds/60),fill:A[a.key]??"#f8fafc"}));return e.jsxs("div",{className:"grid gap-6",children:[e.jsxs(O,{to:"/sports",className:"inline-flex w-fit items-center gap-2 text-sm text-[var(--ui-ink-soft)] transition hover:text-[var(--ui-ink-strong)]",children:[e.jsx(q,{className:"size-4"}),"Back to sports"]}),e.jsx(ee,{eyebrow:"Workout evidence",title:i.workoutTypeLabel??i.workoutType,description:`${F(i.startedAt,i.endedAt)} · ${i.sourceDevice||"Apple Health"}`,actions:e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx(j,{children:k(i.durationSeconds)}),e.jsxs(j,{tone:"meta",children:[r.confidence," HR zones"]}),(p=r.routeSummary)!=null&&p.hasRoute?e.jsxs(j,{tone:"meta",children:[r.routeSummary.pointCount," route points"]}):null]})}),e.jsxs("section",{className:"grid gap-4 lg:grid-cols-4",children:[e.jsxs(c,{children:[e.jsx("div",{className:"text-sm text-[var(--ui-ink-soft)]",children:"Avg HR"}),e.jsx("div",{className:"mt-3 font-display text-4xl text-[var(--ui-ink-strong)]",children:r.hrSummary.averageHr??i.averageHeartRate??"n/a"}),e.jsx("div",{className:"mt-1 text-sm text-[var(--ui-ink-faint)]",children:"bpm"})]}),e.jsxs(c,{children:[e.jsx("div",{className:"text-sm text-[var(--ui-ink-soft)]",children:"Max HR"}),e.jsx("div",{className:"mt-3 font-display text-4xl text-[var(--ui-ink-strong)]",children:r.hrSummary.maxHr??i.maxHeartRate??"n/a"}),e.jsx("div",{className:"mt-1 text-sm text-[var(--ui-ink-faint)]",children:"bpm"})]}),e.jsxs(c,{children:[e.jsx("div",{className:"text-sm text-[var(--ui-ink-soft)]",children:"Training load"}),e.jsx("div",{className:"mt-3 font-display text-4xl text-[var(--ui-ink-strong)]",children:r.load.trimp??"n/a"}),e.jsx("div",{className:"mt-1 text-sm text-[var(--ui-ink-faint)]",children:"Forge TRIMP"})]}),e.jsxs(c,{children:[e.jsx("div",{className:"text-sm text-[var(--ui-ink-soft)]",children:"HR coverage"}),e.jsxs("div",{className:"mt-3 font-display text-4xl text-[var(--ui-ink-strong)]",children:[Math.round((r.dataQuality.sampleCoverage??0)*100),"%"]}),e.jsxs("div",{className:"mt-1 text-sm text-[var(--ui-ink-faint)]",children:[r.dataQuality.heartRateSampleCount??0," samples"]})]})]}),e.jsxs("section",{className:"grid min-w-0 gap-4 xl:grid-cols-[minmax(0,1.25fr)_minmax(280px,0.75fr)]",children:[e.jsxs(c,{className:"min-h-[360px] min-w-0 overflow-hidden",children:[e.jsxs("div",{className:"flex items-center gap-2 text-[var(--ui-ink-strong)]",children:[e.jsx(Z,{className:"size-4 text-[var(--primary)]"}),"Heart-rate timeline"]}),e.jsx("div",{className:"mt-4 h-[300px]",children:f.length>0?e.jsx(C,{width:"100%",height:"100%",children:e.jsxs(te,{data:f,children:[e.jsx("defs",{children:e.jsxs("linearGradient",{id:"hrFill",x1:"0",y1:"0",x2:"0",y2:"1",children:[e.jsx("stop",{offset:"0%",stopColor:"#ef4444",stopOpacity:.38}),e.jsx("stop",{offset:"100%",stopColor:"#ef4444",stopOpacity:.04})]})}),e.jsx(ae,{stroke:"var(--ui-border-subtle)",vertical:!1}),e.jsx(T,{dataKey:"time",interval:"preserveStartEnd",tick:{fill:"var(--ui-ink-soft)",fontSize:11},tickFormatter:$,type:"number",domain:["dataMin","dataMax"]}),e.jsx(_,{tick:{fill:"var(--ui-ink-soft)",fontSize:11},width:42}),e.jsx(z,{labelFormatter:$,contentStyle:{background:"var(--surface-glass)",border:"1px solid var(--ui-border-subtle)",borderRadius:8,color:"var(--ui-ink-strong)"}}),e.jsx(se,{type:"monotone",dataKey:"bpm",stroke:"#ef4444",fill:"url(#hrFill)",strokeWidth:2,dot:!1})]})}):e.jsx("div",{className:"grid h-full place-items-center rounded-[8px] bg-[var(--ui-surface-1)] text-sm text-[var(--ui-ink-soft)]",children:"No raw HR timeline has been synced for this workout yet."})})]}),e.jsxs(c,{className:"min-w-0 overflow-hidden",children:[e.jsxs("div",{className:"flex items-center gap-2 text-[var(--ui-ink-strong)]",children:[e.jsx(G,{className:"size-4 text-[var(--primary)]"}),"Zone mix"]}),e.jsx("div",{className:"mt-4",children:e.jsx(de,{zones:r.zoneDurations})}),e.jsx("div",{className:"mt-5 h-[180px]",children:e.jsx(C,{width:"100%",height:"100%",children:e.jsxs(ie,{data:m,children:[e.jsx(T,{dataKey:"zone",tick:{fill:"var(--ui-ink-soft)",fontSize:10}}),e.jsx(_,{tick:{fill:"var(--ui-ink-soft)",fontSize:10},width:34}),e.jsx(z,{contentStyle:{background:"var(--surface-glass)",border:"1px solid var(--ui-border-subtle)",borderRadius:8,color:"var(--ui-ink-strong)"}}),e.jsx(re,{dataKey:"minutes",radius:[4,4,0,0]})]})})})]})]}),e.jsxs("section",{className:"grid min-w-0 gap-4 xl:grid-cols-[minmax(0,1fr)_360px]",children:[e.jsxs(c,{className:"min-w-0 overflow-hidden",children:[e.jsxs("div",{className:"flex items-center gap-2 text-[var(--ui-ink-strong)]",children:[e.jsx(X,{className:"size-4 text-[var(--primary)]"}),"Route"]}),e.jsx("div",{className:"mt-4",children:d.routePoints.length>1?e.jsx(le,{points:d.routePoints}):e.jsx("div",{className:"grid min-h-[240px] place-items-center rounded-[8px] bg-[var(--ui-surface-1)] text-sm text-[var(--ui-ink-soft)]",children:"No route evidence is available for this workout."})})]}),e.jsxs(c,{className:"min-w-0 overflow-hidden",children:[e.jsx("div",{className:"text-[var(--ui-ink-strong)]",children:"Captured metrics"}),e.jsx("div",{className:"mt-4 grid gap-3",children:(((N=i.details)==null?void 0:N.metrics)??[]).slice(0,14).map(a=>e.jsxs("div",{className:"min-w-0 rounded-[8px] bg-[var(--ui-surface-1)] px-3 py-2",children:[e.jsx("div",{className:"break-words text-sm text-[var(--ui-ink-soft)] [overflow-wrap:anywhere]",children:a.label}),e.jsx("div",{className:"mt-1 break-words text-[var(--ui-ink-strong)] [overflow-wrap:anywhere]",children:ne(a.value,a.unit)})]},`${a.category}:${a.key}:${a.statistic}`))})]})]}),e.jsxs("section",{className:"grid min-w-0 gap-4 lg:grid-cols-[minmax(0,1fr)_minmax(280px,0.7fr)]",children:[e.jsxs(c,{className:"min-w-0 overflow-hidden",children:[e.jsx("div",{className:"text-[var(--ui-ink-strong)]",children:"Events and phases"}),e.jsxs("div",{className:"mt-4 grid gap-3",children:[[...((b=i.details)==null?void 0:b.events)??[],...((y=i.details)==null?void 0:y.components)??[]].slice(0,18).map((a,w)=>e.jsxs("div",{className:"min-w-0 rounded-[8px] bg-[var(--ui-surface-1)] px-4 py-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[e.jsx("div",{className:"min-w-0 break-words text-[var(--ui-ink-strong)] [overflow-wrap:anywhere]",children:"label"in a?a.label:a.activity.canonicalLabel}),e.jsx(j,{tone:"meta",children:k(a.durationSeconds)})]}),e.jsx("div",{className:"mt-1 text-sm text-[var(--ui-ink-soft)]",children:F(a.startedAt,a.endedAt??a.startedAt)})]},`${"type"in a?a.type:a.externalUid}:${a.startedAt}:${w}`)),(((L=(S=i.details)==null?void 0:S.events)==null?void 0:L.length)??0)+(((R=(M=i.details)==null?void 0:M.components)==null?void 0:R.length)??0)===0?e.jsx("div",{className:"rounded-[8px] bg-[var(--ui-surface-1)] p-4 text-sm text-[var(--ui-ink-soft)]",children:"No provider events or phases were captured."}):null]})]}),e.jsxs(c,{className:"min-w-0 overflow-hidden",children:[e.jsx("div",{className:"text-[var(--ui-ink-strong)]",children:"Reflection"}),e.jsxs("div",{className:"mt-4 grid gap-4",children:[e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:"text-sm text-[var(--ui-ink-soft)]",children:"Meaning and impact"}),e.jsx(E,{className:"min-h-[160px]",value:u,onChange:a=>l(a.target.value)})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:"text-sm text-[var(--ui-ink-soft)]",children:"Tags"}),e.jsx(P,{value:v,onChange:a=>g(a.target.value)})]}),e.jsxs(I,{type:"button",pending:x.isPending,pendingLabel:"Saving",onClick:()=>x.mutate(),children:[e.jsx(Y,{className:"size-4"}),"Save reflection"]})]})]})]})]})}export{ke as WorkoutDetailPage};
|
package/dist/index.html
CHANGED
|
@@ -130,7 +130,7 @@
|
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
132
|
</style>
|
|
133
|
-
<script type="module" crossorigin src="/forge/assets/index-
|
|
133
|
+
<script type="module" crossorigin src="/forge/assets/index-By3tQxiE.js"></script>
|
|
134
134
|
<link rel="modulepreload" crossorigin href="/forge/assets/vendor-Dnkkx2co.js">
|
|
135
135
|
<link rel="modulepreload" crossorigin href="/forge/assets/state-vCcAT5Hq.js">
|
|
136
136
|
<link rel="modulepreload" crossorigin href="/forge/assets/motion-Lt5B1XuE.js">
|
|
@@ -5,6 +5,7 @@ import { getSettings } from "./repositories/settings.js";
|
|
|
5
5
|
import { getDefaultUser, resolveUserForMutation } from "./repositories/users.js";
|
|
6
6
|
import { readEncryptedSecret } from "./repositories/calendar.js";
|
|
7
7
|
import { hallNiddkWeeklyRateKgToDailyEnergyAdjustment } from "../../src/lib/weight-loss-energy-model.js";
|
|
8
|
+
const ACTIVE_BASELINE_WINDOW_DAYS = 7;
|
|
8
9
|
const optionalNumberSchema = z
|
|
9
10
|
.union([z.coerce.number().finite(), z.null()])
|
|
10
11
|
.optional();
|
|
@@ -397,7 +398,7 @@ function getDailyEnergyOverride(userId, dateKey) {
|
|
|
397
398
|
function buildStoredEnergyModel(input) {
|
|
398
399
|
const todayKey = input.dateKey;
|
|
399
400
|
const start = new Date(`${todayKey}T00:00:00.000Z`);
|
|
400
|
-
start.setUTCDate(start.getUTCDate() -
|
|
401
|
+
start.setUTCDate(start.getUTCDate() - ACTIVE_BASELINE_WINDOW_DAYS);
|
|
401
402
|
const startKey = start.toISOString().slice(0, 10);
|
|
402
403
|
const dailySummaryRows = getDatabase()
|
|
403
404
|
.prepare(`SELECT date_key, metrics_json
|
|
@@ -405,8 +406,9 @@ function buildStoredEnergyModel(input) {
|
|
|
405
406
|
WHERE user_id = ?
|
|
406
407
|
AND summary_type = 'vitals'
|
|
407
408
|
AND date_key >= ?
|
|
409
|
+
AND date_key <= ?
|
|
408
410
|
ORDER BY date_key DESC`)
|
|
409
|
-
.all(input.userId, startKey);
|
|
411
|
+
.all(input.userId, startKey, todayKey);
|
|
410
412
|
const dailyHealthKit = dailySummaryRows.map((row) => {
|
|
411
413
|
const metrics = parseJson(row.metrics_json, {});
|
|
412
414
|
return {
|
|
@@ -427,8 +429,9 @@ function buildStoredEnergyModel(input) {
|
|
|
427
429
|
FROM health_workout_sessions
|
|
428
430
|
WHERE user_id = ?
|
|
429
431
|
AND date(started_at) >= ?
|
|
432
|
+
AND date(started_at) <= ?
|
|
430
433
|
GROUP BY date(started_at)`)
|
|
431
|
-
.all(input.userId, startKey);
|
|
434
|
+
.all(input.userId, startKey, todayKey);
|
|
432
435
|
const movementRows = getDatabase()
|
|
433
436
|
.prepare(`SELECT date(started_at) AS date_key,
|
|
434
437
|
NULL AS active_energy_kcal,
|
|
@@ -437,8 +440,9 @@ function buildStoredEnergyModel(input) {
|
|
|
437
440
|
FROM movement_trips
|
|
438
441
|
WHERE user_id = ?
|
|
439
442
|
AND date(started_at) >= ?
|
|
443
|
+
AND date(started_at) <= ?
|
|
440
444
|
GROUP BY date(started_at)`)
|
|
441
|
-
.all(input.userId, startKey);
|
|
445
|
+
.all(input.userId, startKey, todayKey);
|
|
442
446
|
const workoutByDay = new Map(workoutRows.map((row) => [
|
|
443
447
|
row.date_key,
|
|
444
448
|
n(row.active_energy_kcal) || n(row.total_energy_kcal) || null
|
|
@@ -466,7 +470,8 @@ function buildStoredEnergyModel(input) {
|
|
|
466
470
|
AND started_at < ?`)
|
|
467
471
|
.get(input.userId, input.dayStartAt, input.dayEndAt)
|
|
468
472
|
: null;
|
|
469
|
-
const
|
|
473
|
+
const activeBaselineHealthKitDays = dailyHealthKit.filter((day) => day.dateKey < todayKey && day.activeEnergyKcal != null);
|
|
474
|
+
const activeEnergyAverage = average(activeBaselineHealthKitDays.map((day) => day.activeEnergyKcal));
|
|
470
475
|
const restingEvidenceDays = dailyHealthKit.filter((day) => day.restingEnergyKcal != null);
|
|
471
476
|
const restingExclusionReasons = [];
|
|
472
477
|
const qualifiedRestingDays = restingEvidenceDays.filter((day) => {
|
|
@@ -520,13 +525,17 @@ function buildStoredEnergyModel(input) {
|
|
|
520
525
|
}
|
|
521
526
|
return qualifiedRestingDays.length > 0 ? "high" : "medium";
|
|
522
527
|
})();
|
|
523
|
-
const
|
|
524
|
-
const
|
|
528
|
+
const workoutBaselineEntries = [...workoutByDay.entries()].filter(([dateKey, value]) => dateKey < todayKey && value != null);
|
|
529
|
+
const movementBaselineEntries = [...movementByDay.entries()].filter(([dateKey, value]) => dateKey < todayKey && value != null);
|
|
530
|
+
const workoutBaselineValues = workoutBaselineEntries.map(([, value]) => value);
|
|
531
|
+
const movementBaselineValues = movementBaselineEntries.map(([, value]) => value);
|
|
532
|
+
const workoutEnergyAverage = average(workoutBaselineValues);
|
|
533
|
+
const movementCaloriesAverage = average(movementBaselineValues);
|
|
525
534
|
const fallbackActiveBurn = workoutEnergyAverage != null || movementCaloriesAverage != null
|
|
526
535
|
? n(workoutEnergyAverage) + n(movementCaloriesAverage)
|
|
527
536
|
: null;
|
|
528
|
-
const activeBurnKcal = activeEnergyAverage ?? fallbackActiveBurn;
|
|
529
|
-
const baselineActiveCalories =
|
|
537
|
+
const activeBurnKcal = activeEnergyAverage ?? fallbackActiveBurn ?? input.defaultActiveCalories;
|
|
538
|
+
const baselineActiveCalories = activeBurnKcal ?? 0;
|
|
530
539
|
const todayHealthKitActive = dailyHealthKit.find((day) => day.dateKey === todayKey)?.activeEnergyKcal ??
|
|
531
540
|
null;
|
|
532
541
|
const todayStepCount = dailyHealthKit.find((day) => day.dateKey === todayKey)?.stepCount ?? null;
|
|
@@ -636,6 +645,12 @@ function buildStoredEnergyModel(input) {
|
|
|
636
645
|
inferredTdee: input.inferredTdee,
|
|
637
646
|
estimatedTdeeKcal,
|
|
638
647
|
activeBurnKcal: activeBurnKcal != null ? round(activeBurnKcal, 0) : null,
|
|
648
|
+
activeBaselineWindowDays: ACTIVE_BASELINE_WINDOW_DAYS,
|
|
649
|
+
activeBaselineEvidenceDays: new Set([
|
|
650
|
+
...activeBaselineHealthKitDays.map((day) => day.dateKey),
|
|
651
|
+
...workoutBaselineEntries.map(([dateKey]) => dateKey),
|
|
652
|
+
...movementBaselineEntries.map(([dateKey]) => dateKey)
|
|
653
|
+
]).size,
|
|
639
654
|
baselineActiveCaloriesKcal: round(baselineActiveCalories, 0),
|
|
640
655
|
todayActiveCaloriesKcal: round(todayActiveCalories, 0),
|
|
641
656
|
todayObservedActiveCaloriesKcal: todayObservedActiveCalories != null
|
|
@@ -673,8 +688,12 @@ function buildStoredEnergyModel(input) {
|
|
|
673
688
|
...workoutRows.map((row) => row.date_key),
|
|
674
689
|
...movementRows.map((row) => row.date_key)
|
|
675
690
|
]).size,
|
|
676
|
-
exerciseMinutesAverage: average(dailyHealthKit
|
|
677
|
-
|
|
691
|
+
exerciseMinutesAverage: average(dailyHealthKit
|
|
692
|
+
.filter((day) => day.dateKey < todayKey)
|
|
693
|
+
.map((day) => day.exerciseMinutes)),
|
|
694
|
+
stepCountAverage: average(dailyHealthKit
|
|
695
|
+
.filter((day) => day.dateKey < todayKey)
|
|
696
|
+
.map((day) => day.stepCount)),
|
|
678
697
|
sourceAvailability: {
|
|
679
698
|
healthKitDailyEnergy: hasHealthKitDailyActiveEnergy,
|
|
680
699
|
movementTripCalories: hasMovementEnergy,
|
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.112",
|
|
6
6
|
"activation": {
|
|
7
7
|
"onStartup": true,
|
|
8
8
|
"onCapabilities": [
|
package/package.json
CHANGED