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,59 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import pino from "pino";
|
|
4
|
+
import { appConfig } from "../config.js";
|
|
5
|
+
let loggerInstance = null;
|
|
6
|
+
function createStderrLogger() {
|
|
7
|
+
return pino({
|
|
8
|
+
level: process.env.LOG_LEVEL ?? "info",
|
|
9
|
+
}, pino.transport({
|
|
10
|
+
target: "pino-pretty",
|
|
11
|
+
options: {
|
|
12
|
+
colorize: true,
|
|
13
|
+
translateTime: "SYS:standard",
|
|
14
|
+
destination: 2,
|
|
15
|
+
},
|
|
16
|
+
}));
|
|
17
|
+
}
|
|
18
|
+
function createFileLogger(logPath) {
|
|
19
|
+
const directory = path.dirname(logPath);
|
|
20
|
+
fs.mkdirSync(directory, { recursive: true });
|
|
21
|
+
return pino({
|
|
22
|
+
level: process.env.LOG_LEVEL ?? "info",
|
|
23
|
+
}, pino.multistream([
|
|
24
|
+
{
|
|
25
|
+
stream: pino.destination({
|
|
26
|
+
dest: logPath,
|
|
27
|
+
sync: false,
|
|
28
|
+
mkdir: true,
|
|
29
|
+
}),
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
stream: pino.transport({
|
|
33
|
+
target: "pino-pretty",
|
|
34
|
+
options: {
|
|
35
|
+
colorize: true,
|
|
36
|
+
translateTime: "SYS:standard",
|
|
37
|
+
destination: 2,
|
|
38
|
+
},
|
|
39
|
+
}),
|
|
40
|
+
},
|
|
41
|
+
]));
|
|
42
|
+
}
|
|
43
|
+
function getLogger() {
|
|
44
|
+
if (!loggerInstance) {
|
|
45
|
+
loggerInstance = createStderrLogger();
|
|
46
|
+
}
|
|
47
|
+
return loggerInstance;
|
|
48
|
+
}
|
|
49
|
+
export function configureLogger(logPath = appConfig.logPath) {
|
|
50
|
+
loggerInstance = createFileLogger(logPath);
|
|
51
|
+
}
|
|
52
|
+
export const logger = new Proxy({}, {
|
|
53
|
+
get(_target, property, receiver) {
|
|
54
|
+
const instance = getLogger();
|
|
55
|
+
const value = Reflect.get(instance, property, receiver);
|
|
56
|
+
return typeof value === "function" ? value.bind(instance) : value;
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,IAAI,cAAc,GAAkB,IAAI,CAAC;AAEzC,SAAS,kBAAkB;IACzB,OAAO,IAAI,CACT;QACE,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM;KACvC,EACD,IAAI,CAAC,SAAS,CAAC;QACb,MAAM,EAAE,aAAa;QACrB,OAAO,EAAE;YACP,QAAQ,EAAE,IAAI;YACd,aAAa,EAAE,cAAc;YAC7B,WAAW,EAAE,CAAC;SACf;KACF,CAAC,CACH,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,OAAe;IACvC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACxC,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE7C,OAAO,IAAI,CACT;QACE,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM;KACvC,EACD,IAAI,CAAC,WAAW,CAAC;QACf;YACE,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC;gBACvB,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,KAAK;gBACX,KAAK,EAAE,IAAI;aACZ,CAAC;SACH;QACD;YACE,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC;gBACrB,MAAM,EAAE,aAAa;gBACrB,OAAO,EAAE;oBACP,QAAQ,EAAE,IAAI;oBACd,aAAa,EAAE,cAAc;oBAC7B,WAAW,EAAE,CAAC;iBACf;aACF,CAAC;SACH;KACF,CAAC,CACH,CAAC;AACJ,CAAC;AAED,SAAS,SAAS;IAChB,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,cAAc,GAAG,kBAAkB,EAAE,CAAC;IACxC,CAAC;IACD,OAAO,cAAc,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAO,GAAG,SAAS,CAAC,OAAO;IACzD,cAAc,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAW,IAAI,KAAK,CAAC,EAAY,EAAE;IACpD,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ;QAC7B,MAAM,QAAQ,GAAG,SAAS,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACxD,OAAO,OAAO,KAAK,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IACpE,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,cAAc,QAAc,CAAC"}
|
package/dist/version.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
const packageJsonPath = path.join(path.dirname(fileURLToPath(import.meta.url)), "..", "package.json");
|
|
5
|
+
const pkg = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
|
|
6
|
+
export const packageVersion = pkg.version;
|
|
7
|
+
//# sourceMappingURL=version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAC/B,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAC5C,IAAI,EACJ,cAAc,CACf,CAAC;AAEF,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,CAAwB,CAAC;AAExF,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,CAAC,OAAO,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export interface WatchRecovery {
|
|
2
|
+
score: number;
|
|
3
|
+
label: string;
|
|
4
|
+
}
|
|
5
|
+
export interface WatchSleep {
|
|
6
|
+
hours: number;
|
|
7
|
+
score: number | null;
|
|
8
|
+
label: string;
|
|
9
|
+
}
|
|
10
|
+
export interface WatchActivity {
|
|
11
|
+
name: string;
|
|
12
|
+
distance_km: number | null;
|
|
13
|
+
duration_min: number | null;
|
|
14
|
+
avg_hr: number | null;
|
|
15
|
+
date: string;
|
|
16
|
+
}
|
|
17
|
+
export interface WatchHeartRate {
|
|
18
|
+
resting: number;
|
|
19
|
+
max: number | null;
|
|
20
|
+
}
|
|
21
|
+
export interface WatchDailyOverview {
|
|
22
|
+
recovery: number | null;
|
|
23
|
+
sleep_h: number | null;
|
|
24
|
+
stress: number | null;
|
|
25
|
+
vo2max: number | null;
|
|
26
|
+
}
|
|
27
|
+
export interface WatchStress {
|
|
28
|
+
avg: number;
|
|
29
|
+
label: string;
|
|
30
|
+
}
|
|
31
|
+
export interface WatchVo2Max {
|
|
32
|
+
value: number;
|
|
33
|
+
trend: string;
|
|
34
|
+
}
|
|
35
|
+
export interface WatchSummary {
|
|
36
|
+
daily_overview: WatchDailyOverview;
|
|
37
|
+
recovery: WatchRecovery | null;
|
|
38
|
+
sleep: WatchSleep | null;
|
|
39
|
+
activity: WatchActivity | null;
|
|
40
|
+
stress: WatchStress | null;
|
|
41
|
+
vo2max: WatchVo2Max | null;
|
|
42
|
+
heart_rate: WatchHeartRate | null;
|
|
43
|
+
ai_insight: string | null;
|
|
44
|
+
updated_at: string;
|
|
45
|
+
}
|
|
46
|
+
export declare function buildWatchSummary(): Promise<WatchSummary>;
|
|
47
|
+
//# sourceMappingURL=watchApi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watchApi.d.ts","sourceRoot":"","sources":["../src/watchApi.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,cAAc,EAAE,kBAAkB,CAAC;IACnC,QAAQ,EAAE,aAAa,GAAG,IAAI,CAAC;IAC/B,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,aAAa,GAAG,IAAI,CAAC;IAC/B,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,cAAc,GAAG,IAAI,CAAC;IAClC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;CACpB;AAyOD,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,YAAY,CAAC,CAiC/D"}
|
package/dist/watchApi.js
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import { executeTool } from "./tools/index.js";
|
|
2
|
+
import { generateDailyInsight } from "./promptApi.js";
|
|
3
|
+
function isNoData(text) {
|
|
4
|
+
return /^No .+ found/i.test(text.trim());
|
|
5
|
+
}
|
|
6
|
+
function averageComponentScores(text) {
|
|
7
|
+
const components = [...text.matchAll(/- (?:HRV|Sleep|Stress|Resting HR):\s*(\d+)/gi)];
|
|
8
|
+
if (components.length === 0) {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
const total = components.reduce((sum, match) => sum + Number.parseInt(match[1] ?? "", 10), 0);
|
|
12
|
+
return Math.round(total / components.length);
|
|
13
|
+
}
|
|
14
|
+
function parseRecovery(text) {
|
|
15
|
+
if (isNoData(text)) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
const headerMatch = text.match(/Recovery score:\s*(null|\d+)\/100\s*(?:\(([^)]+)\))?/i);
|
|
19
|
+
if (!headerMatch) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
const rawScore = headerMatch[1]?.toLowerCase();
|
|
23
|
+
const status = headerMatch[2]?.trim().toLowerCase() ?? "";
|
|
24
|
+
const score = rawScore === "null" || !rawScore
|
|
25
|
+
? averageComponentScores(text)
|
|
26
|
+
: Number.parseInt(rawScore, 10);
|
|
27
|
+
if (score === null || !Number.isFinite(score)) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
let label = "Moderate";
|
|
31
|
+
if (status === "recovered") {
|
|
32
|
+
label = "Ready";
|
|
33
|
+
}
|
|
34
|
+
else if (status === "fatigued") {
|
|
35
|
+
label = "Rest";
|
|
36
|
+
}
|
|
37
|
+
else if (status === "good") {
|
|
38
|
+
label = "Light";
|
|
39
|
+
}
|
|
40
|
+
return { score, label };
|
|
41
|
+
}
|
|
42
|
+
function parseDurationHours(duration) {
|
|
43
|
+
const minutes = parseDurationMinutes(duration);
|
|
44
|
+
if (minutes === null) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
return Math.round((minutes / 60) * 10) / 10;
|
|
48
|
+
}
|
|
49
|
+
function parseDurationMinutes(duration) {
|
|
50
|
+
const hourMatch = duration.match(/(\d+)h/);
|
|
51
|
+
const minuteMatch = duration.match(/(\d+)m/);
|
|
52
|
+
const secondMatch = duration.match(/(\d+)s/);
|
|
53
|
+
const hours = hourMatch ? Number.parseInt(hourMatch[1] ?? "", 10) : 0;
|
|
54
|
+
const minutes = minuteMatch ? Number.parseInt(minuteMatch[1] ?? "", 10) : 0;
|
|
55
|
+
const seconds = secondMatch ? Number.parseInt(secondMatch[1] ?? "", 10) : 0;
|
|
56
|
+
if (!hourMatch && !minuteMatch && !secondMatch) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
return Math.round(hours * 60 + minutes + seconds / 60);
|
|
60
|
+
}
|
|
61
|
+
function parseSleep(text) {
|
|
62
|
+
if (isNoData(text)) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
const avgScoreMatch = text.match(/Average sleep score:\s*(\d+)/i);
|
|
66
|
+
const nightBlocks = text.split(/\n(?=\d{4}-\d{2}-\d{2}:)/);
|
|
67
|
+
const latestNight = nightBlocks.length > 1 ? nightBlocks[1] : nightBlocks[0];
|
|
68
|
+
const totalSleepMatch = latestNight?.match(/Total sleep:\s*([^\n]+)/i);
|
|
69
|
+
const scoreMatch = latestNight?.match(/Score:\s*(\d+)/i);
|
|
70
|
+
const hours = totalSleepMatch ? parseDurationHours(totalSleepMatch[1] ?? "") : null;
|
|
71
|
+
const score = scoreMatch
|
|
72
|
+
? Number.parseInt(scoreMatch[1] ?? "", 10)
|
|
73
|
+
: avgScoreMatch
|
|
74
|
+
? Number.parseInt(avgScoreMatch[1] ?? "", 10)
|
|
75
|
+
: null;
|
|
76
|
+
if (hours === null && score === null) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
let label = "Fair";
|
|
80
|
+
const effectiveScore = score ?? 0;
|
|
81
|
+
if (effectiveScore >= 80) {
|
|
82
|
+
label = "Great";
|
|
83
|
+
}
|
|
84
|
+
else if (effectiveScore >= 60) {
|
|
85
|
+
label = "Good";
|
|
86
|
+
}
|
|
87
|
+
else if (effectiveScore > 0 && effectiveScore < 60) {
|
|
88
|
+
label = "Poor";
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
hours: hours ?? 0,
|
|
92
|
+
score,
|
|
93
|
+
label,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
function parseActivity(text) {
|
|
97
|
+
if (isNoData(text)) {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
const nameMatch = text.match(/^Activity:\s*(.+)$/m);
|
|
101
|
+
const dateMatch = text.match(/^Date:\s*(.+)$/m);
|
|
102
|
+
const distanceKmMatch = text.match(/^Distance:\s*([\d.]+)\s*km/mi);
|
|
103
|
+
const distanceMMatch = text.match(/^Distance:\s*([\d.]+)\s*m$/mi);
|
|
104
|
+
if (!nameMatch) {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
let distanceKm = null;
|
|
108
|
+
if (distanceKmMatch) {
|
|
109
|
+
distanceKm = Math.round(Number.parseFloat(distanceKmMatch[1] ?? "") * 100) / 100;
|
|
110
|
+
}
|
|
111
|
+
else if (distanceMMatch) {
|
|
112
|
+
distanceKm = Math.round((Number.parseFloat(distanceMMatch[1] ?? "") / 1000) * 100) / 100;
|
|
113
|
+
}
|
|
114
|
+
const durationMatch = text.match(/^Duration:\s*([^\n]+)/m);
|
|
115
|
+
const avgHrMatch = text.match(/^Avg HR:\s*(\d+)\s*bpm/mi);
|
|
116
|
+
return {
|
|
117
|
+
name: nameMatch[1]?.trim() ?? "Activity",
|
|
118
|
+
distance_km: distanceKm,
|
|
119
|
+
duration_min: durationMatch ? parseDurationMinutes(durationMatch[1] ?? "") : null,
|
|
120
|
+
avg_hr: avgHrMatch ? Number.parseInt(avgHrMatch[1] ?? "", 10) : null,
|
|
121
|
+
date: dateMatch?.[1]?.trim() ?? "",
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
function stressLabel(avg) {
|
|
125
|
+
if (avg <= 25) {
|
|
126
|
+
return "Low";
|
|
127
|
+
}
|
|
128
|
+
if (avg <= 50) {
|
|
129
|
+
return "Medium";
|
|
130
|
+
}
|
|
131
|
+
return "High";
|
|
132
|
+
}
|
|
133
|
+
function parseStress(text) {
|
|
134
|
+
if (isNoData(text)) {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
const avgMatch = text.match(/Average stress:\s*(\d+)/i);
|
|
138
|
+
if (!avgMatch) {
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
const avg = Number.parseInt(avgMatch[1] ?? "", 10);
|
|
142
|
+
return { avg, label: stressLabel(avg) };
|
|
143
|
+
}
|
|
144
|
+
function parseVo2Max(text) {
|
|
145
|
+
if (isNoData(text)) {
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
const currentMatch = text.match(/Current VO2 max:\s*([\d.]+)/i);
|
|
149
|
+
const trendMatch = text.match(/Trend:\s*(\w+)/i);
|
|
150
|
+
if (!currentMatch) {
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
value: Math.round(Number.parseFloat(currentMatch[1] ?? "") * 10) / 10,
|
|
155
|
+
trend: trendMatch?.[1]?.trim() ?? "stable",
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
function parseHeartRate(text) {
|
|
159
|
+
if (isNoData(text)) {
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
const restingMatch = text.match(/Current resting HR:\s*(\d+)\s*bpm/i);
|
|
163
|
+
if (!restingMatch) {
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
const recentMaxMatch = text.match(/resting \d+ bpm, max (\d+) bpm/i);
|
|
167
|
+
const max = recentMaxMatch ? Number.parseInt(recentMaxMatch[1] ?? "", 10) : null;
|
|
168
|
+
return {
|
|
169
|
+
resting: Number.parseInt(restingMatch[1] ?? "", 10),
|
|
170
|
+
max,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
function buildDailyOverview(recovery, sleep, stress, vo2max) {
|
|
174
|
+
return {
|
|
175
|
+
recovery: recovery?.score ?? null,
|
|
176
|
+
sleep_h: sleep?.hours ?? null,
|
|
177
|
+
stress: stress?.avg ?? null,
|
|
178
|
+
vo2max: vo2max?.value ?? null,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
async function safeExecuteTool(name, args) {
|
|
182
|
+
try {
|
|
183
|
+
const result = await executeTool(name, args);
|
|
184
|
+
if (isNoData(result.text)) {
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
return result.text;
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
export async function buildWatchSummary() {
|
|
194
|
+
const [recoveryText, sleepText, activityText, stressText, vo2Text, heartRateText] = await Promise.all([
|
|
195
|
+
safeExecuteTool("get_recovery_status", {}),
|
|
196
|
+
safeExecuteTool("get_sleep_data", { nights: 1 }),
|
|
197
|
+
safeExecuteTool("get_latest_activity", {}),
|
|
198
|
+
safeExecuteTool("get_stress_levels", { days: 7 }),
|
|
199
|
+
safeExecuteTool("get_vo2_max_trends", { days: 30 }),
|
|
200
|
+
safeExecuteTool("get_heart_rate_trends", { days: 7 }),
|
|
201
|
+
]);
|
|
202
|
+
const recovery = recoveryText ? parseRecovery(recoveryText) : null;
|
|
203
|
+
const sleep = sleepText ? parseSleep(sleepText) : null;
|
|
204
|
+
const activity = activityText ? parseActivity(activityText) : null;
|
|
205
|
+
const stress = stressText ? parseStress(stressText) : null;
|
|
206
|
+
const vo2max = vo2Text ? parseVo2Max(vo2Text) : null;
|
|
207
|
+
const heartRate = heartRateText ? parseHeartRate(heartRateText) : null;
|
|
208
|
+
const partialSummary = {
|
|
209
|
+
daily_overview: buildDailyOverview(recovery, sleep, stress, vo2max),
|
|
210
|
+
recovery,
|
|
211
|
+
sleep,
|
|
212
|
+
activity,
|
|
213
|
+
stress,
|
|
214
|
+
vo2max,
|
|
215
|
+
heart_rate: heartRate,
|
|
216
|
+
ai_insight: null,
|
|
217
|
+
updated_at: new Date().toISOString(),
|
|
218
|
+
};
|
|
219
|
+
partialSummary.ai_insight = await generateDailyInsight(partialSummary);
|
|
220
|
+
return partialSummary;
|
|
221
|
+
}
|
|
222
|
+
//# sourceMappingURL=watchApi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watchApi.js","sourceRoot":"","sources":["../src/watchApi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAyDtD,SAAS,QAAQ,CAAC,IAAY;IAC5B,OAAO,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS,sBAAsB,CAAC,IAAY;IAC1C,MAAM,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,8CAA8C,CAAC,CAAC,CAAC;IACtF,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9F,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;AAC/C,CAAC;AAED,SAAS,aAAa,CAAC,IAAY;IACjC,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAC;IACxF,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,QAAQ,GAAG,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC;IAC/C,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC;IAC1D,MAAM,KAAK,GACT,QAAQ,KAAK,MAAM,IAAI,CAAC,QAAQ;QAC9B,CAAC,CAAC,sBAAsB,CAAC,IAAI,CAAC;QAC9B,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAEpC,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,KAAK,GAAG,UAAU,CAAC;IACvB,IAAI,MAAM,KAAK,WAAW,EAAE,CAAC;QAC3B,KAAK,GAAG,OAAO,CAAC;IAClB,CAAC;SAAM,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;QACjC,KAAK,GAAG,MAAM,CAAC;IACjB,CAAC;SAAM,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QAC7B,KAAK,GAAG,OAAO,CAAC;IAClB,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AAC1B,CAAC;AAED,SAAS,kBAAkB,CAAC,QAAgB;IAC1C,MAAM,OAAO,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAC/C,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC;AAC9C,CAAC;AAED,SAAS,oBAAoB,CAAC,QAAgB;IAC5C,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC3C,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC7C,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACtE,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5E,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAE5E,IAAI,CAAC,SAAS,IAAI,CAAC,WAAW,IAAI,CAAC,WAAW,EAAE,CAAC;QAC/C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,GAAG,OAAO,GAAG,OAAO,GAAG,EAAE,CAAC,CAAC;AACzD,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAC9B,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;IAClE,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC3D,MAAM,WAAW,GAAG,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAE7E,MAAM,eAAe,GAAG,WAAW,EAAE,KAAK,CAAC,0BAA0B,CAAC,CAAC;IACvE,MAAM,UAAU,GAAG,WAAW,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAEzD,MAAM,KAAK,GAAG,eAAe,CAAC,CAAC,CAAC,kBAAkB,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACpF,MAAM,KAAK,GAAG,UAAU;QACtB,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC;QAC1C,CAAC,CAAC,aAAa;YACb,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC;YAC7C,CAAC,CAAC,IAAI,CAAC;IAEX,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACrC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,KAAK,GAAG,MAAM,CAAC;IACnB,MAAM,cAAc,GAAG,KAAK,IAAI,CAAC,CAAC;IAClC,IAAI,cAAc,IAAI,EAAE,EAAE,CAAC;QACzB,KAAK,GAAG,OAAO,CAAC;IAClB,CAAC;SAAM,IAAI,cAAc,IAAI,EAAE,EAAE,CAAC;QAChC,KAAK,GAAG,MAAM,CAAC;IACjB,CAAC;SAAM,IAAI,cAAc,GAAG,CAAC,IAAI,cAAc,GAAG,EAAE,EAAE,CAAC;QACrD,KAAK,GAAG,MAAM,CAAC;IACjB,CAAC;IAED,OAAO;QACL,KAAK,EAAE,KAAK,IAAI,CAAC;QACjB,KAAK;QACL,KAAK;KACN,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,IAAY;IACjC,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACpD,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAChD,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;IACnE,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAElE,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,UAAU,GAAkB,IAAI,CAAC;IACrC,IAAI,eAAe,EAAE,CAAC;QACpB,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;IACnF,CAAC;SAAM,IAAI,cAAc,EAAE,CAAC;QAC1B,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;IAC3F,CAAC;IAED,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC3D,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAE1D,OAAO;QACL,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,UAAU;QACxC,WAAW,EAAE,UAAU;QACvB,YAAY,EAAE,aAAa,CAAC,CAAC,CAAC,oBAAoB,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI;QACjF,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI;QACpE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE;KACnC,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,GAAW;IAC9B,IAAI,GAAG,IAAI,EAAE,EAAE,CAAC;QACd,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,GAAG,IAAI,EAAE,EAAE,CAAC;QACd,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,WAAW,CAAC,IAAY;IAC/B,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;IACxD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IACnD,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;AAC1C,CAAC;AAED,SAAS,WAAW,CAAC,IAAY;IAC/B,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAChE,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAEjD,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO;QACL,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE;QACrE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,QAAQ;KAC3C,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,IAAY;IAClC,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACtE,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACrE,MAAM,GAAG,GAAG,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAEjF,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC;QACnD,GAAG;KACJ,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CACzB,QAA8B,EAC9B,KAAwB,EACxB,MAA0B,EAC1B,MAA0B;IAE1B,OAAO;QACL,QAAQ,EAAE,QAAQ,EAAE,KAAK,IAAI,IAAI;QACjC,OAAO,EAAE,KAAK,EAAE,KAAK,IAAI,IAAI;QAC7B,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,IAAI;QAC3B,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,IAAI;KAC9B,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,IAAY,EAAE,IAA6B;IACxE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC7C,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,MAAM,CAAC,IAAI,CAAC;IACrB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,MAAM,CAAC,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,aAAa,CAAC,GAC/E,MAAM,OAAO,CAAC,GAAG,CAAC;QAChB,eAAe,CAAC,qBAAqB,EAAE,EAAE,CAAC;QAC1C,eAAe,CAAC,gBAAgB,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;QAChD,eAAe,CAAC,qBAAqB,EAAE,EAAE,CAAC;QAC1C,eAAe,CAAC,mBAAmB,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QACjD,eAAe,CAAC,oBAAoB,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QACnD,eAAe,CAAC,uBAAuB,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;KACtD,CAAC,CAAC;IAEL,MAAM,QAAQ,GAAG,YAAY,CAAC,CAAC,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACnE,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACvD,MAAM,QAAQ,GAAG,YAAY,CAAC,CAAC,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACnE,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3D,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACrD,MAAM,SAAS,GAAG,aAAa,CAAC,CAAC,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAEvE,MAAM,cAAc,GAAG;QACrB,cAAc,EAAE,kBAAkB,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC;QACnE,QAAQ;QACR,KAAK;QACL,QAAQ;QACR,MAAM;QACN,MAAM;QACN,UAAU,EAAE,SAAS;QACrB,UAAU,EAAE,IAAqB;QACjC,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACrC,CAAC;IAEF,cAAc,CAAC,UAAU,GAAG,MAAM,oBAAoB,CAAC,cAAc,CAAC,CAAC;IAEvE,OAAO,cAAc,CAAC;AACxB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "garmin-bud",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "GarminBud — talk to your Garmin Connect data through Claude and other MCP clients",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"README.md",
|
|
10
|
+
"QUICKSTART.md",
|
|
11
|
+
"CHANGELOG.md",
|
|
12
|
+
"LICENSE",
|
|
13
|
+
".env.example"
|
|
14
|
+
],
|
|
15
|
+
"bin": {
|
|
16
|
+
"garmin-bud": "dist/index.js"
|
|
17
|
+
},
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsc",
|
|
20
|
+
"dev": "tsx src/index.ts start",
|
|
21
|
+
"start": "node dist/index.js start",
|
|
22
|
+
"test": "node --import tsx --test tests/auth.test.ts tests/cache.test.ts tests/tools.test.ts tests/integration.test.ts tests/mcpConfig.test.ts tests/rawApi.test.ts tests/httpServer.test.ts",
|
|
23
|
+
"test:vitest": "vitest run",
|
|
24
|
+
"test:watch": "vitest",
|
|
25
|
+
"test:coverage": "vitest run --coverage",
|
|
26
|
+
"lint": "eslint src tests",
|
|
27
|
+
"typecheck": "tsc --noEmit",
|
|
28
|
+
"prepublishOnly": "npm run build"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [
|
|
31
|
+
"garmin",
|
|
32
|
+
"garmin-connect",
|
|
33
|
+
"mcp",
|
|
34
|
+
"model-context-protocol",
|
|
35
|
+
"claude",
|
|
36
|
+
"fitness",
|
|
37
|
+
"health",
|
|
38
|
+
"garminbud"
|
|
39
|
+
],
|
|
40
|
+
"author": "Zsadigzade",
|
|
41
|
+
"license": "MIT",
|
|
42
|
+
"repository": {
|
|
43
|
+
"type": "git",
|
|
44
|
+
"url": "git+https://github.com/Zsadigzade/garmin-bud.git"
|
|
45
|
+
},
|
|
46
|
+
"homepage": "https://github.com/Zsadigzade/garmin-bud#readme",
|
|
47
|
+
"bugs": {
|
|
48
|
+
"url": "https://github.com/Zsadigzade/garmin-bud/issues"
|
|
49
|
+
},
|
|
50
|
+
"engines": {
|
|
51
|
+
"node": ">=20.0.0"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@eslint/js": "^10.0.1",
|
|
55
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
56
|
+
"@types/luxon": "^3.7.2",
|
|
57
|
+
"@types/node": "^26.0.1",
|
|
58
|
+
"@vitest/coverage-v8": "^4.1.9",
|
|
59
|
+
"eslint": "^10.5.0",
|
|
60
|
+
"tsx": "^4.22.4",
|
|
61
|
+
"typescript": "^6.0.3",
|
|
62
|
+
"typescript-eslint": "^8.62.0",
|
|
63
|
+
"vitest": "^4.1.9"
|
|
64
|
+
},
|
|
65
|
+
"dependencies": {
|
|
66
|
+
"@anthropic-ai/sdk": "^0.106.0",
|
|
67
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
68
|
+
"better-sqlite3": "^12.11.1",
|
|
69
|
+
"commander": "^15.0.0",
|
|
70
|
+
"dotenv": "^17.4.2",
|
|
71
|
+
"garmin-connect": "^1.6.2",
|
|
72
|
+
"luxon": "^3.7.2",
|
|
73
|
+
"pino": "^10.3.1",
|
|
74
|
+
"pino-pretty": "^13.1.3",
|
|
75
|
+
"zod": "^4.4.3"
|
|
76
|
+
}
|
|
77
|
+
}
|