garmin-bud 0.2.0
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/.env.example +11 -0
- package/CHANGELOG.md +56 -0
- package/LICENSE +21 -0
- package/QUICKSTART.md +174 -0
- package/README.md +227 -0
- package/dist/appDb.d.ts +32 -0
- package/dist/appDb.d.ts.map +1 -0
- package/dist/appDb.js +131 -0
- package/dist/appDb.js.map +1 -0
- package/dist/check.d.ts +9 -0
- package/dist/check.d.ts.map +1 -0
- package/dist/check.js +156 -0
- package/dist/check.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +187 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +28 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +108 -0
- package/dist/config.js.map +1 -0
- package/dist/dashboard.d.ts +4 -0
- package/dist/dashboard.d.ts.map +1 -0
- package/dist/dashboard.js +111 -0
- package/dist/dashboard.js.map +1 -0
- package/dist/garmin/auth.d.ts +10 -0
- package/dist/garmin/auth.d.ts.map +1 -0
- package/dist/garmin/auth.js +81 -0
- package/dist/garmin/auth.js.map +1 -0
- package/dist/garmin/cache.d.ts +20 -0
- package/dist/garmin/cache.d.ts.map +1 -0
- package/dist/garmin/cache.js +115 -0
- package/dist/garmin/cache.js.map +1 -0
- package/dist/garmin/client.d.ts +5 -0
- package/dist/garmin/client.d.ts.map +1 -0
- package/dist/garmin/client.js +68 -0
- package/dist/garmin/client.js.map +1 -0
- package/dist/garmin/garminApiTypes.d.ts +70 -0
- package/dist/garmin/garminApiTypes.d.ts.map +1 -0
- package/dist/garmin/garminApiTypes.js +3 -0
- package/dist/garmin/garminApiTypes.js.map +1 -0
- package/dist/garmin/garminConnect.d.ts +17 -0
- package/dist/garmin/garminConnect.d.ts.map +1 -0
- package/dist/garmin/garminConnect.js +5 -0
- package/dist/garmin/garminConnect.js.map +1 -0
- package/dist/garmin/rawApi.d.ts +18 -0
- package/dist/garmin/rawApi.d.ts.map +1 -0
- package/dist/garmin/rawApi.js +53 -0
- package/dist/garmin/rawApi.js.map +1 -0
- package/dist/garmin/types.d.ts +68 -0
- package/dist/garmin/types.d.ts.map +1 -0
- package/dist/garmin/types.js +11 -0
- package/dist/garmin/types.js.map +1 -0
- package/dist/httpServer.d.ts +7 -0
- package/dist/httpServer.d.ts.map +1 -0
- package/dist/httpServer.js +386 -0
- package/dist/httpServer.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/mcpConfig.d.ts +37 -0
- package/dist/mcpConfig.d.ts.map +1 -0
- package/dist/mcpConfig.js +83 -0
- package/dist/mcpConfig.js.map +1 -0
- package/dist/pairApi.d.ts +14 -0
- package/dist/pairApi.d.ts.map +1 -0
- package/dist/pairApi.js +34 -0
- package/dist/pairApi.js.map +1 -0
- package/dist/promptApi.d.ts +13 -0
- package/dist/promptApi.d.ts.map +1 -0
- package/dist/promptApi.js +102 -0
- package/dist/promptApi.js.map +1 -0
- package/dist/server.d.ts +10 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +67 -0
- package/dist/server.js.map +1 -0
- package/dist/setup.d.ts +2 -0
- package/dist/setup.d.ts.map +1 -0
- package/dist/setup.js +194 -0
- package/dist/setup.js.map +1 -0
- package/dist/toolErrors.d.ts +2 -0
- package/dist/toolErrors.d.ts.map +1 -0
- package/dist/toolErrors.js +18 -0
- package/dist/toolErrors.js.map +1 -0
- package/dist/tools/activities.d.ts +11 -0
- package/dist/tools/activities.d.ts.map +1 -0
- package/dist/tools/activities.js +134 -0
- package/dist/tools/activities.js.map +1 -0
- package/dist/tools/bodyComposition.d.ts +7 -0
- package/dist/tools/bodyComposition.d.ts.map +1 -0
- package/dist/tools/bodyComposition.js +97 -0
- package/dist/tools/bodyComposition.js.map +1 -0
- package/dist/tools/heartRate.d.ts +7 -0
- package/dist/tools/heartRate.d.ts.map +1 -0
- package/dist/tools/heartRate.js +88 -0
- package/dist/tools/heartRate.js.map +1 -0
- package/dist/tools/index.d.ts +39 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +77 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/recovery.d.ts +16 -0
- package/dist/tools/recovery.d.ts.map +1 -0
- package/dist/tools/recovery.js +214 -0
- package/dist/tools/recovery.js.map +1 -0
- package/dist/tools/sleep.d.ts +7 -0
- package/dist/tools/sleep.d.ts.map +1 -0
- package/dist/tools/sleep.js +93 -0
- package/dist/tools/sleep.js.map +1 -0
- package/dist/tools/stress.d.ts +7 -0
- package/dist/tools/stress.d.ts.map +1 -0
- package/dist/tools/stress.js +69 -0
- package/dist/tools/stress.js.map +1 -0
- package/dist/tools/trainingInsights.d.ts +7 -0
- package/dist/tools/trainingInsights.d.ts.map +1 -0
- package/dist/tools/trainingInsights.js +61 -0
- package/dist/tools/trainingInsights.js.map +1 -0
- package/dist/tools/types.d.ts +12 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/dist/tools/types.js +2 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/tools/vo2Max.d.ts +7 -0
- package/dist/tools/vo2Max.d.ts.map +1 -0
- package/dist/tools/vo2Max.js +72 -0
- package/dist/tools/vo2Max.js.map +1 -0
- package/dist/utils/batch.d.ts +2 -0
- package/dist/utils/batch.d.ts.map +1 -0
- package/dist/utils/batch.js +18 -0
- package/dist/utils/batch.js.map +1 -0
- package/dist/utils/helpers.d.ts +19 -0
- package/dist/utils/helpers.d.ts.map +1 -0
- package/dist/utils/helpers.js +131 -0
- package/dist/utils/helpers.js.map +1 -0
- package/dist/utils/logger.d.ts +4 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +59 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +7 -0
- package/dist/version.js.map +1 -0
- package/dist/watchApi.d.ts +47 -0
- package/dist/watchApi.d.ts.map +1 -0
- package/dist/watchApi.js +222 -0
- package/dist/watchApi.js.map +1 -0
- package/package.json +77 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { appConfig } from "../config.js";
|
|
2
|
+
import { buildToolCacheKey, withCache } from "../garmin/cache.js";
|
|
3
|
+
import { withGarminClient } from "../garmin/client.js";
|
|
4
|
+
import { mapInBatches } from "../utils/batch.js";
|
|
5
|
+
import { formatDuration, formatIsoDate, getDateRange, } from "../utils/helpers.js";
|
|
6
|
+
// SECTION: Sleep Mapping
|
|
7
|
+
function mapSleepData(date, sleepData) {
|
|
8
|
+
const dailySleep = sleepData.dailySleepDTO;
|
|
9
|
+
if (!dailySleep) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
return {
|
|
13
|
+
date: formatIsoDate(date),
|
|
14
|
+
totalSleepSeconds: dailySleep.sleepTimeSeconds,
|
|
15
|
+
deepSleepSeconds: dailySleep.deepSleepSeconds,
|
|
16
|
+
lightSleepSeconds: dailySleep.lightSleepSeconds,
|
|
17
|
+
remSleepSeconds: dailySleep.remSleepSeconds,
|
|
18
|
+
awakeCount: dailySleep.awakeCount,
|
|
19
|
+
sleepScore: dailySleep.sleepScores?.overall?.value ?? null,
|
|
20
|
+
avgSleepStress: dailySleep.avgSleepStress ?? null,
|
|
21
|
+
avgOvernightHrv: sleepData.avgOvernightHrv ?? null,
|
|
22
|
+
hrvStatus: sleepData.hrvStatus ?? null,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
async function fetchSleepNights(days) {
|
|
26
|
+
const dates = getDateRange(days);
|
|
27
|
+
return withGarminClient(async (client) => {
|
|
28
|
+
const nights = await mapInBatches(dates, async (date) => {
|
|
29
|
+
try {
|
|
30
|
+
const sleepData = await client.getSleepData(date);
|
|
31
|
+
return mapSleepData(date, sleepData);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
return nights.filter((night) => night !== null);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function formatSleepNight(night) {
|
|
41
|
+
return [
|
|
42
|
+
`${night.date}:`,
|
|
43
|
+
` Total sleep: ${formatDuration(night.totalSleepSeconds)}`,
|
|
44
|
+
` Deep: ${formatDuration(night.deepSleepSeconds)} | Light: ${formatDuration(night.lightSleepSeconds)} | REM: ${formatDuration(night.remSleepSeconds)}`,
|
|
45
|
+
` Score: ${night.sleepScore ?? "n/a"} | Awakenings: ${night.awakeCount}`,
|
|
46
|
+
` Avg sleep stress: ${night.avgSleepStress ?? "n/a"}`,
|
|
47
|
+
].join("\n");
|
|
48
|
+
}
|
|
49
|
+
// SECTION: Tool Handler
|
|
50
|
+
export async function getSleepDataTool(input) {
|
|
51
|
+
const nights = input.nights ?? 7;
|
|
52
|
+
const cacheKey = buildToolCacheKey("get_sleep_data", { nights });
|
|
53
|
+
const sleepNights = await withCache(cacheKey, appConfig.cacheTtlSleep, async () => {
|
|
54
|
+
return fetchSleepNights(nights);
|
|
55
|
+
});
|
|
56
|
+
if (sleepNights.length === 0) {
|
|
57
|
+
return {
|
|
58
|
+
type: "text",
|
|
59
|
+
text: `No sleep data found for the last ${nights} nights.`,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
const averageScoreValues = sleepNights
|
|
63
|
+
.map((night) => night.sleepScore)
|
|
64
|
+
.filter((score) => score !== null);
|
|
65
|
+
const averageScore = averageScoreValues.length > 0
|
|
66
|
+
? Math.round(averageScoreValues.reduce((sum, score) => sum + score, 0) /
|
|
67
|
+
averageScoreValues.length)
|
|
68
|
+
: null;
|
|
69
|
+
const lines = [
|
|
70
|
+
`Sleep summary for last ${sleepNights.length} recorded nights:`,
|
|
71
|
+
averageScore !== null ? `Average sleep score: ${averageScore}` : "",
|
|
72
|
+
"",
|
|
73
|
+
...sleepNights.map(formatSleepNight),
|
|
74
|
+
].filter(Boolean);
|
|
75
|
+
return {
|
|
76
|
+
type: "text",
|
|
77
|
+
text: lines.join("\n"),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
export const sleepToolDefinitions = [
|
|
81
|
+
{
|
|
82
|
+
name: "get_sleep_data",
|
|
83
|
+
description: "Returns sleep duration, quality score, stage breakdown, and interruptions for recent nights.",
|
|
84
|
+
inputSchema: {
|
|
85
|
+
nights: {
|
|
86
|
+
type: "number",
|
|
87
|
+
description: "Number of recent nights to include. Defaults to 7.",
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
handler: getSleepDataTool,
|
|
91
|
+
},
|
|
92
|
+
];
|
|
93
|
+
//# sourceMappingURL=sleep.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sleep.js","sourceRoot":"","sources":["../../src/tools/sleep.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ToolTextResult } from "../garmin/types.js";
|
|
2
|
+
import type { ToolDefinition } from "./types.js";
|
|
3
|
+
export declare function getStressLevels(input: {
|
|
4
|
+
days?: number;
|
|
5
|
+
}): Promise<ToolTextResult>;
|
|
6
|
+
export declare const stressToolDefinitions: ToolDefinition[];
|
|
7
|
+
//# sourceMappingURL=stress.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stress.d.ts","sourceRoot":"","sources":["../../src/tools/stress.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAqBjD,wBAAsB,eAAe,CAAC,KAAK,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAuCvF;AAED,eAAO,MAAM,qBAAqB,EAAE,cAAc,EAYjD,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { appConfig } from "../config.js";
|
|
2
|
+
import { buildToolCacheKey, withCache } from "../garmin/cache.js";
|
|
3
|
+
import { withGarminClient } from "../garmin/client.js";
|
|
4
|
+
import { fetchDailyStress, mapDailyStress, } from "../garmin/rawApi.js";
|
|
5
|
+
import { mapInBatches } from "../utils/batch.js";
|
|
6
|
+
import { average, calculateTrend, getDateRange } from "../utils/helpers.js";
|
|
7
|
+
async function fetchStressDays(days) {
|
|
8
|
+
const dates = getDateRange(days);
|
|
9
|
+
return withGarminClient(async (client) => {
|
|
10
|
+
const summaries = await mapInBatches(dates, async (date) => {
|
|
11
|
+
try {
|
|
12
|
+
const payload = await fetchDailyStress(client, date);
|
|
13
|
+
return mapDailyStress(date, payload);
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
return summaries.filter((entry) => entry !== null);
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
export async function getStressLevels(input) {
|
|
23
|
+
const days = input.days ?? 7;
|
|
24
|
+
const cacheKey = buildToolCacheKey("get_stress_levels", { days });
|
|
25
|
+
const summaries = await withCache(cacheKey, appConfig.cacheTtlStats, async () => {
|
|
26
|
+
return fetchStressDays(days);
|
|
27
|
+
});
|
|
28
|
+
if (summaries.length === 0) {
|
|
29
|
+
return {
|
|
30
|
+
type: "text",
|
|
31
|
+
text: `No stress data found for the last ${days} days.`,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
const averages = summaries
|
|
35
|
+
.map((entry) => entry.averageStress)
|
|
36
|
+
.filter((value) => value !== null);
|
|
37
|
+
const trend = calculateTrend(averages, true);
|
|
38
|
+
const avgStress = averages.length > 0 ? Math.round(average(averages)) : null;
|
|
39
|
+
const lines = summaries.slice(0, 7).map((entry) => {
|
|
40
|
+
return `${entry.date}: avg ${entry.averageStress ?? "n/a"}, max ${entry.maxStress ?? "n/a"}`;
|
|
41
|
+
});
|
|
42
|
+
return {
|
|
43
|
+
type: "text",
|
|
44
|
+
text: [
|
|
45
|
+
`Stress levels over ${summaries.length} recorded days:`,
|
|
46
|
+
avgStress !== null ? `Average stress: ${avgStress}` : "",
|
|
47
|
+
averages.length > 1 ? `Trend: ${trend}` : "",
|
|
48
|
+
"",
|
|
49
|
+
"Recent days:",
|
|
50
|
+
...lines,
|
|
51
|
+
]
|
|
52
|
+
.filter(Boolean)
|
|
53
|
+
.join("\n"),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
export const stressToolDefinitions = [
|
|
57
|
+
{
|
|
58
|
+
name: "get_stress_levels",
|
|
59
|
+
description: "Returns daily stress averages and trends from Garmin Connect.",
|
|
60
|
+
inputSchema: {
|
|
61
|
+
days: {
|
|
62
|
+
type: "number",
|
|
63
|
+
description: "Number of days to analyze. Defaults to 7.",
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
handler: getStressLevels,
|
|
67
|
+
},
|
|
68
|
+
];
|
|
69
|
+
//# sourceMappingURL=stress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stress.js","sourceRoot":"","sources":["../../src/tools/stress.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ToolTextResult } from "../garmin/types.js";
|
|
2
|
+
import type { ToolDefinition } from "./types.js";
|
|
3
|
+
export declare function getTrainingInsights(input: {
|
|
4
|
+
days?: number;
|
|
5
|
+
}): Promise<ToolTextResult>;
|
|
6
|
+
export declare const trainingInsightsToolDefinitions: ToolDefinition[];
|
|
7
|
+
//# sourceMappingURL=trainingInsights.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trainingInsights.d.ts","sourceRoot":"","sources":["../../src/tools/trainingInsights.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,wBAAsB,mBAAmB,CAAC,KAAK,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CA8C3F;AAED,eAAO,MAAM,+BAA+B,EAAE,cAAc,EAa3D,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { filterActivitiesByRange } from "../utils/helpers.js";
|
|
2
|
+
import { DateTime } from "luxon";
|
|
3
|
+
import { getActivitiesPool, formatActivitySummary } from "./activities.js";
|
|
4
|
+
import { getSleepDataTool } from "./sleep.js";
|
|
5
|
+
import { getRecoveryStatus } from "./recovery.js";
|
|
6
|
+
import { getStressLevels } from "./stress.js";
|
|
7
|
+
export async function getTrainingInsights(input) {
|
|
8
|
+
const days = input.days ?? 7;
|
|
9
|
+
const endDate = DateTime.now().toISODate();
|
|
10
|
+
const startDate = DateTime.now().minus({ days }).toISODate();
|
|
11
|
+
const { activities: pool } = await getActivitiesPool();
|
|
12
|
+
const ranged = filterActivitiesByRange(pool, startDate ?? "", endDate ?? "");
|
|
13
|
+
const latest = pool[0] ?? null;
|
|
14
|
+
const [sleep, recovery, stress] = await Promise.all([
|
|
15
|
+
getSleepDataTool({ nights: days }),
|
|
16
|
+
getRecoveryStatus({}),
|
|
17
|
+
getStressLevels({ days }),
|
|
18
|
+
]);
|
|
19
|
+
const activityLines = ranged.length > 0
|
|
20
|
+
? ranged.map((activity, index) => {
|
|
21
|
+
return `${index + 1}. ${activity.name} (${activity.type}) — ${activity.startTimeLocal}`;
|
|
22
|
+
})
|
|
23
|
+
: [`No activities found between ${startDate} and ${endDate}.`];
|
|
24
|
+
const sections = [
|
|
25
|
+
"Training insights summary",
|
|
26
|
+
`Period: ${startDate} to ${endDate}`,
|
|
27
|
+
"",
|
|
28
|
+
"## Latest activity",
|
|
29
|
+
latest ? formatActivitySummary(latest) : "No activities found.",
|
|
30
|
+
"",
|
|
31
|
+
"## Activities in period",
|
|
32
|
+
...activityLines,
|
|
33
|
+
"",
|
|
34
|
+
"## Sleep",
|
|
35
|
+
sleep.text,
|
|
36
|
+
"",
|
|
37
|
+
"## Recovery",
|
|
38
|
+
recovery.text,
|
|
39
|
+
"",
|
|
40
|
+
"## Stress",
|
|
41
|
+
stress.text,
|
|
42
|
+
];
|
|
43
|
+
return {
|
|
44
|
+
type: "text",
|
|
45
|
+
text: sections.join("\n"),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export const trainingInsightsToolDefinitions = [
|
|
49
|
+
{
|
|
50
|
+
name: "get_training_insights",
|
|
51
|
+
description: "Returns a combined weekly training summary: latest activity, recent workouts, sleep, recovery, and stress.",
|
|
52
|
+
inputSchema: {
|
|
53
|
+
days: {
|
|
54
|
+
type: "number",
|
|
55
|
+
description: "Number of days to summarize. Defaults to 7.",
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
handler: getTrainingInsights,
|
|
59
|
+
},
|
|
60
|
+
];
|
|
61
|
+
//# sourceMappingURL=trainingInsights.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trainingInsights.js","sourceRoot":"","sources":["../../src/tools/trainingInsights.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAC3E,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAI9C,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,KAAwB;IAChE,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC;IAC7B,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,SAAS,EAAE,CAAC;IAC3C,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC;IAE7D,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,MAAM,iBAAiB,EAAE,CAAC;IACvD,MAAM,MAAM,GAAG,uBAAuB,CAAC,IAAI,EAAE,SAAS,IAAI,EAAE,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC;IAC7E,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;IAE/B,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAClD,gBAAgB,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QAClC,iBAAiB,CAAC,EAAE,CAAC;QACrB,eAAe,CAAC,EAAE,IAAI,EAAE,CAAC;KAC1B,CAAC,CAAC;IAEH,MAAM,aAAa,GACjB,MAAM,CAAC,MAAM,GAAG,CAAC;QACf,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE;YAC7B,OAAO,GAAG,KAAK,GAAG,CAAC,KAAK,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,OAAO,QAAQ,CAAC,cAAc,EAAE,CAAC;QAC1F,CAAC,CAAC;QACJ,CAAC,CAAC,CAAC,+BAA+B,SAAS,QAAQ,OAAO,GAAG,CAAC,CAAC;IAEnE,MAAM,QAAQ,GAAG;QACf,2BAA2B;QAC3B,WAAW,SAAS,OAAO,OAAO,EAAE;QACpC,EAAE;QACF,oBAAoB;QACpB,MAAM,CAAC,CAAC,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,sBAAsB;QAC/D,EAAE;QACF,yBAAyB;QACzB,GAAG,aAAa;QAChB,EAAE;QACF,UAAU;QACV,KAAK,CAAC,IAAI;QACV,EAAE;QACF,aAAa;QACb,QAAQ,CAAC,IAAI;QACb,EAAE;QACF,WAAW;QACX,MAAM,CAAC,IAAI;KACZ,CAAC;IAEF,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;KAC1B,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,+BAA+B,GAAqB;IAC/D;QACE,IAAI,EAAE,uBAAuB;QAC7B,WAAW,EACT,4GAA4G;QAC9G,WAAW,EAAE;YACX,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,6CAA6C;aAC3D;SACF;QACD,OAAO,EAAE,mBAAmB;KAC7B;CACF,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ToolTextResult } from "../garmin/types.js";
|
|
2
|
+
export interface ToolInputSchema {
|
|
3
|
+
type: string;
|
|
4
|
+
description: string;
|
|
5
|
+
}
|
|
6
|
+
export interface ToolDefinition {
|
|
7
|
+
name: string;
|
|
8
|
+
description: string;
|
|
9
|
+
inputSchema: Record<string, ToolInputSchema> | Record<string, never>;
|
|
10
|
+
handler: (input: Record<string, unknown>) => Promise<ToolTextResult>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/tools/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACrE,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;CACtE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/tools/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ToolTextResult } from "../garmin/types.js";
|
|
2
|
+
import type { ToolDefinition } from "./types.js";
|
|
3
|
+
export declare function getVo2MaxTrends(input: {
|
|
4
|
+
days?: number;
|
|
5
|
+
}): Promise<ToolTextResult>;
|
|
6
|
+
export declare const vo2MaxToolDefinitions: ToolDefinition[];
|
|
7
|
+
//# sourceMappingURL=vo2Max.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vo2Max.d.ts","sourceRoot":"","sources":["../../src/tools/vo2Max.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAqBjD,wBAAsB,eAAe,CAAC,KAAK,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CA2CvF;AAED,eAAO,MAAM,qBAAqB,EAAE,cAAc,EAYjD,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { appConfig } from "../config.js";
|
|
2
|
+
import { buildToolCacheKey, withCache } from "../garmin/cache.js";
|
|
3
|
+
import { withGarminClient } from "../garmin/client.js";
|
|
4
|
+
import { fetchMaxMetrics, mapMaxMetrics } from "../garmin/rawApi.js";
|
|
5
|
+
import { mapInBatches } from "../utils/batch.js";
|
|
6
|
+
import { calculateTrend, getDateRange } from "../utils/helpers.js";
|
|
7
|
+
async function fetchVo2MaxDays(days) {
|
|
8
|
+
const dates = getDateRange(days);
|
|
9
|
+
return withGarminClient(async (client) => {
|
|
10
|
+
const entries = await mapInBatches(dates, async (date) => {
|
|
11
|
+
try {
|
|
12
|
+
const payload = await fetchMaxMetrics(client, date);
|
|
13
|
+
return mapMaxMetrics(date, payload);
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
return entries.filter((entry) => entry !== null);
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
export async function getVo2MaxTrends(input) {
|
|
23
|
+
const days = input.days ?? 30;
|
|
24
|
+
const cacheKey = buildToolCacheKey("get_vo2_max_trends", { days });
|
|
25
|
+
const entries = await withCache(cacheKey, appConfig.cacheTtlStats, async () => {
|
|
26
|
+
return fetchVo2MaxDays(days);
|
|
27
|
+
});
|
|
28
|
+
if (entries.length === 0) {
|
|
29
|
+
return {
|
|
30
|
+
type: "text",
|
|
31
|
+
text: `No VO2 max data found for the last ${days} days.`,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
const values = entries
|
|
35
|
+
.map((entry) => entry.vo2Max)
|
|
36
|
+
.filter((value) => value !== null);
|
|
37
|
+
const trend = calculateTrend(values, false);
|
|
38
|
+
const current = entries[0]?.vo2Max ?? null;
|
|
39
|
+
const previous = entries.at(-1)?.vo2Max ?? null;
|
|
40
|
+
const lines = entries.slice(0, 10).map((entry) => {
|
|
41
|
+
const cycling = entry.vo2MaxCycling !== null ? `, cycling ${entry.vo2MaxCycling}` : "";
|
|
42
|
+
return `${entry.date}: VO2 max ${entry.vo2Max ?? "n/a"}${cycling}`;
|
|
43
|
+
});
|
|
44
|
+
return {
|
|
45
|
+
type: "text",
|
|
46
|
+
text: [
|
|
47
|
+
`VO2 max trends over ${entries.length} recorded days:`,
|
|
48
|
+
current !== null ? `Current VO2 max: ${current}` : "",
|
|
49
|
+
previous !== null && entries.length > 1 ? `Oldest in range: ${previous}` : "",
|
|
50
|
+
values.length > 1 ? `Trend: ${trend}` : "",
|
|
51
|
+
"",
|
|
52
|
+
"Recent entries:",
|
|
53
|
+
...lines,
|
|
54
|
+
]
|
|
55
|
+
.filter(Boolean)
|
|
56
|
+
.join("\n"),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
export const vo2MaxToolDefinitions = [
|
|
60
|
+
{
|
|
61
|
+
name: "get_vo2_max_trends",
|
|
62
|
+
description: "Returns VO2 max fitness trends over time from Garmin Connect.",
|
|
63
|
+
inputSchema: {
|
|
64
|
+
days: {
|
|
65
|
+
type: "number",
|
|
66
|
+
description: "Number of days to analyze. Defaults to 30.",
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
handler: getVo2MaxTrends,
|
|
70
|
+
},
|
|
71
|
+
];
|
|
72
|
+
//# sourceMappingURL=vo2Max.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vo2Max.js","sourceRoot":"","sources":["../../src/tools/vo2Max.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch.d.ts","sourceRoot":"","sources":["../../src/utils/batch.ts"],"names":[],"mappings":"AAEA,wBAAsB,YAAY,CAAC,CAAC,EAAE,CAAC,EACrC,KAAK,EAAE,CAAC,EAAE,EACV,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,EAC3B,WAAW,SAAsB,GAChC,OAAO,CAAC,CAAC,EAAE,CAAC,CAkBd"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const DEFAULT_CONCURRENCY = 6;
|
|
2
|
+
export async function mapInBatches(items, fn, concurrency = DEFAULT_CONCURRENCY) {
|
|
3
|
+
if (items.length === 0) {
|
|
4
|
+
return [];
|
|
5
|
+
}
|
|
6
|
+
const results = new Array(items.length);
|
|
7
|
+
let index = 0;
|
|
8
|
+
async function worker() {
|
|
9
|
+
while (index < items.length) {
|
|
10
|
+
const current = index++;
|
|
11
|
+
results[current] = await fn(items[current]);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
const workers = Array.from({ length: Math.min(concurrency, items.length) }, () => worker());
|
|
15
|
+
await Promise.all(workers);
|
|
16
|
+
return results;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=batch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch.js","sourceRoot":"","sources":["../../src/utils/batch.ts"],"names":[],"mappings":"AAAA,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAE9B,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,KAAU,EACV,EAA2B,EAC3B,WAAW,GAAG,mBAAmB;IAEjC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,OAAO,GAAQ,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7C,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,KAAK,UAAU,MAAM;QACnB,OAAO,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;YAC5B,MAAM,OAAO,GAAG,KAAK,EAAE,CAAC;YACxB,OAAO,CAAC,OAAO,CAAC,GAAG,MAAM,EAAE,CAAC,KAAK,CAAC,OAAO,CAAM,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;IAC5F,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC3B,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { DateTime } from "luxon";
|
|
2
|
+
import type { ActivitySummary } from "../garmin/types.js";
|
|
3
|
+
export type TrendDirection = "improving" | "declining" | "stable" | "insufficient_data";
|
|
4
|
+
export declare function parseIsoDate(value: string): Date;
|
|
5
|
+
export declare function formatIsoDate(date: Date): string;
|
|
6
|
+
export declare function getDateRange(days: number): Date[];
|
|
7
|
+
export declare function getYesterday(): Date;
|
|
8
|
+
export declare function getDatesBetween(startDate: string, endDate: string): Date[];
|
|
9
|
+
export declare function parseActivityLocalDateTime(value: string): DateTime;
|
|
10
|
+
export declare function filterActivitiesByRange(activities: ActivitySummary[], startDate: string, endDate: string): ActivitySummary[];
|
|
11
|
+
export declare function formatDuration(seconds: number): string;
|
|
12
|
+
export declare function formatDistanceMeters(meters: number): string;
|
|
13
|
+
export declare function formatPaceMetersPerSecond(metersPerSecond: number): string;
|
|
14
|
+
export declare function calculateTrend(values: number[], lowerIsBetter?: boolean): TrendDirection;
|
|
15
|
+
export declare function average(values: number[]): number;
|
|
16
|
+
export declare function clamp(value: number, min: number, max: number): number;
|
|
17
|
+
export declare function hashParams(params: Record<string, unknown>): string;
|
|
18
|
+
export declare function sanitizeErrorMessage(message: string): string;
|
|
19
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/utils/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,WAAW,GAAG,QAAQ,GAAG,mBAAmB,CAAC;AAExF,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAMhD;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAEhD;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,CASjD;AAED,wBAAgB,YAAY,IAAI,IAAI,CAEnC;AAED,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,EAAE,CAqB1E;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAYlE;AAED,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,eAAe,EAAE,EAC7B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,eAAe,EAAE,CAYnB;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CActD;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAM3D;AAED,wBAAgB,yBAAyB,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CASzE;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,aAAa,UAAQ,GAAG,cAAc,CA6BtF;AAED,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAMhD;AAED,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAErE;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAGlE;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAK5D"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { DateTime } from "luxon";
|
|
2
|
+
export function parseIsoDate(value) {
|
|
3
|
+
const parsed = DateTime.fromISO(value, { zone: "utc" });
|
|
4
|
+
if (!parsed.isValid) {
|
|
5
|
+
throw new Error(`Invalid date "${value}". Use ISO 8601 format such as 2026-06-01.`);
|
|
6
|
+
}
|
|
7
|
+
return parsed.toJSDate();
|
|
8
|
+
}
|
|
9
|
+
export function formatIsoDate(date) {
|
|
10
|
+
return DateTime.fromJSDate(date, { zone: "utc" }).toISODate() ?? "";
|
|
11
|
+
}
|
|
12
|
+
export function getDateRange(days) {
|
|
13
|
+
const dates = [];
|
|
14
|
+
const today = DateTime.utc().startOf("day");
|
|
15
|
+
for (let offset = 0; offset < days; offset += 1) {
|
|
16
|
+
dates.push(today.minus({ days: offset }).toJSDate());
|
|
17
|
+
}
|
|
18
|
+
return dates;
|
|
19
|
+
}
|
|
20
|
+
export function getYesterday() {
|
|
21
|
+
return DateTime.utc().minus({ days: 1 }).startOf("day").toJSDate();
|
|
22
|
+
}
|
|
23
|
+
export function getDatesBetween(startDate, endDate) {
|
|
24
|
+
const start = DateTime.fromISO(startDate, { zone: "utc" }).startOf("day");
|
|
25
|
+
const end = DateTime.fromISO(endDate, { zone: "utc" }).startOf("day");
|
|
26
|
+
if (!start.isValid || !end.isValid) {
|
|
27
|
+
throw new Error("Invalid date range. Use ISO 8601 dates such as 2026-06-01.");
|
|
28
|
+
}
|
|
29
|
+
if (end < start) {
|
|
30
|
+
throw new Error("end_date must be on or after start_date.");
|
|
31
|
+
}
|
|
32
|
+
const dates = [];
|
|
33
|
+
let cursor = start;
|
|
34
|
+
while (cursor <= end) {
|
|
35
|
+
dates.push(cursor.toJSDate());
|
|
36
|
+
cursor = cursor.plus({ days: 1 });
|
|
37
|
+
}
|
|
38
|
+
return dates;
|
|
39
|
+
}
|
|
40
|
+
export function parseActivityLocalDateTime(value) {
|
|
41
|
+
const fromIso = DateTime.fromISO(value, { setZone: true });
|
|
42
|
+
if (fromIso.isValid) {
|
|
43
|
+
return fromIso;
|
|
44
|
+
}
|
|
45
|
+
const fromSql = DateTime.fromSQL(value, { setZone: true });
|
|
46
|
+
if (fromSql.isValid) {
|
|
47
|
+
return fromSql;
|
|
48
|
+
}
|
|
49
|
+
return DateTime.invalid("unparsable");
|
|
50
|
+
}
|
|
51
|
+
export function filterActivitiesByRange(activities, startDate, endDate) {
|
|
52
|
+
const start = DateTime.fromISO(startDate, { zone: "utc" }).startOf("day");
|
|
53
|
+
const end = DateTime.fromISO(endDate, { zone: "utc" }).startOf("day");
|
|
54
|
+
return activities.filter((activity) => {
|
|
55
|
+
const activityDay = parseActivityLocalDateTime(activity.startTimeLocal).startOf("day");
|
|
56
|
+
if (!activityDay.isValid) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
return activityDay.toMillis() >= start.toMillis() && activityDay.toMillis() <= end.toMillis();
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
export function formatDuration(seconds) {
|
|
63
|
+
const hours = Math.floor(seconds / 3600);
|
|
64
|
+
const minutes = Math.floor((seconds % 3600) / 60);
|
|
65
|
+
const remainingSeconds = Math.floor(seconds % 60);
|
|
66
|
+
if (hours > 0) {
|
|
67
|
+
return `${hours}h ${minutes}m ${remainingSeconds}s`;
|
|
68
|
+
}
|
|
69
|
+
if (minutes > 0) {
|
|
70
|
+
return `${minutes}m ${remainingSeconds}s`;
|
|
71
|
+
}
|
|
72
|
+
return `${remainingSeconds}s`;
|
|
73
|
+
}
|
|
74
|
+
export function formatDistanceMeters(meters) {
|
|
75
|
+
if (meters >= 1000) {
|
|
76
|
+
return `${(meters / 1000).toFixed(2)} km`;
|
|
77
|
+
}
|
|
78
|
+
return `${meters.toFixed(0)} m`;
|
|
79
|
+
}
|
|
80
|
+
export function formatPaceMetersPerSecond(metersPerSecond) {
|
|
81
|
+
if (metersPerSecond <= 0) {
|
|
82
|
+
return "n/a";
|
|
83
|
+
}
|
|
84
|
+
const secondsPerKm = 1000 / metersPerSecond;
|
|
85
|
+
const minutes = Math.floor(secondsPerKm / 60);
|
|
86
|
+
const seconds = Math.round(secondsPerKm % 60);
|
|
87
|
+
return `${minutes}:${seconds.toString().padStart(2, "0")} /km`;
|
|
88
|
+
}
|
|
89
|
+
export function calculateTrend(values, lowerIsBetter = false) {
|
|
90
|
+
const filtered = values.filter((value) => Number.isFinite(value));
|
|
91
|
+
if (filtered.length < 2) {
|
|
92
|
+
return "insufficient_data";
|
|
93
|
+
}
|
|
94
|
+
const midpoint = Math.floor(filtered.length / 2);
|
|
95
|
+
const recent = filtered.slice(0, midpoint);
|
|
96
|
+
const older = filtered.slice(midpoint);
|
|
97
|
+
if (recent.length === 0 || older.length === 0) {
|
|
98
|
+
return "insufficient_data";
|
|
99
|
+
}
|
|
100
|
+
const recentAverage = average(recent);
|
|
101
|
+
const olderAverage = average(older);
|
|
102
|
+
const delta = recentAverage - olderAverage;
|
|
103
|
+
const threshold = Math.max(Math.abs(olderAverage) * 0.02, 0.5);
|
|
104
|
+
if (Math.abs(delta) <= threshold) {
|
|
105
|
+
return "stable";
|
|
106
|
+
}
|
|
107
|
+
if (lowerIsBetter) {
|
|
108
|
+
return delta < 0 ? "improving" : "declining";
|
|
109
|
+
}
|
|
110
|
+
return delta > 0 ? "improving" : "declining";
|
|
111
|
+
}
|
|
112
|
+
export function average(values) {
|
|
113
|
+
if (values.length === 0) {
|
|
114
|
+
return 0;
|
|
115
|
+
}
|
|
116
|
+
return values.reduce((sum, value) => sum + value, 0) / values.length;
|
|
117
|
+
}
|
|
118
|
+
export function clamp(value, min, max) {
|
|
119
|
+
return Math.min(max, Math.max(min, value));
|
|
120
|
+
}
|
|
121
|
+
export function hashParams(params) {
|
|
122
|
+
const sortedEntries = Object.entries(params).sort(([left], [right]) => left.localeCompare(right));
|
|
123
|
+
return JSON.stringify(Object.fromEntries(sortedEntries));
|
|
124
|
+
}
|
|
125
|
+
export function sanitizeErrorMessage(message) {
|
|
126
|
+
return message
|
|
127
|
+
.replace(/[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/g, "[email]")
|
|
128
|
+
.replace(/(?:[A-Za-z]:\\|\/)[^\s]+/g, "[path]")
|
|
129
|
+
.replace(/\bpassword[^\s]*/gi, "[redacted]");
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/utils/helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AA0DnC,wBAAgB,eAAe,CAAC,OAAO,SAAoB,GAAG,IAAI,CAEjE;AAED,eAAO,MAAM,MAAM,EAAE,MAMnB,CAAC"}
|