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.
Files changed (146) hide show
  1. package/.env.example +11 -0
  2. package/CHANGELOG.md +56 -0
  3. package/LICENSE +21 -0
  4. package/QUICKSTART.md +174 -0
  5. package/README.md +227 -0
  6. package/dist/appDb.d.ts +32 -0
  7. package/dist/appDb.d.ts.map +1 -0
  8. package/dist/appDb.js +131 -0
  9. package/dist/appDb.js.map +1 -0
  10. package/dist/check.d.ts +9 -0
  11. package/dist/check.d.ts.map +1 -0
  12. package/dist/check.js +156 -0
  13. package/dist/check.js.map +1 -0
  14. package/dist/cli.d.ts +3 -0
  15. package/dist/cli.d.ts.map +1 -0
  16. package/dist/cli.js +187 -0
  17. package/dist/cli.js.map +1 -0
  18. package/dist/config.d.ts +28 -0
  19. package/dist/config.d.ts.map +1 -0
  20. package/dist/config.js +108 -0
  21. package/dist/config.js.map +1 -0
  22. package/dist/dashboard.d.ts +4 -0
  23. package/dist/dashboard.d.ts.map +1 -0
  24. package/dist/dashboard.js +111 -0
  25. package/dist/dashboard.js.map +1 -0
  26. package/dist/garmin/auth.d.ts +10 -0
  27. package/dist/garmin/auth.d.ts.map +1 -0
  28. package/dist/garmin/auth.js +81 -0
  29. package/dist/garmin/auth.js.map +1 -0
  30. package/dist/garmin/cache.d.ts +20 -0
  31. package/dist/garmin/cache.d.ts.map +1 -0
  32. package/dist/garmin/cache.js +115 -0
  33. package/dist/garmin/cache.js.map +1 -0
  34. package/dist/garmin/client.d.ts +5 -0
  35. package/dist/garmin/client.d.ts.map +1 -0
  36. package/dist/garmin/client.js +68 -0
  37. package/dist/garmin/client.js.map +1 -0
  38. package/dist/garmin/garminApiTypes.d.ts +70 -0
  39. package/dist/garmin/garminApiTypes.d.ts.map +1 -0
  40. package/dist/garmin/garminApiTypes.js +3 -0
  41. package/dist/garmin/garminApiTypes.js.map +1 -0
  42. package/dist/garmin/garminConnect.d.ts +17 -0
  43. package/dist/garmin/garminConnect.d.ts.map +1 -0
  44. package/dist/garmin/garminConnect.js +5 -0
  45. package/dist/garmin/garminConnect.js.map +1 -0
  46. package/dist/garmin/rawApi.d.ts +18 -0
  47. package/dist/garmin/rawApi.d.ts.map +1 -0
  48. package/dist/garmin/rawApi.js +53 -0
  49. package/dist/garmin/rawApi.js.map +1 -0
  50. package/dist/garmin/types.d.ts +68 -0
  51. package/dist/garmin/types.d.ts.map +1 -0
  52. package/dist/garmin/types.js +11 -0
  53. package/dist/garmin/types.js.map +1 -0
  54. package/dist/httpServer.d.ts +7 -0
  55. package/dist/httpServer.d.ts.map +1 -0
  56. package/dist/httpServer.js +386 -0
  57. package/dist/httpServer.js.map +1 -0
  58. package/dist/index.d.ts +3 -0
  59. package/dist/index.d.ts.map +1 -0
  60. package/dist/index.js +11 -0
  61. package/dist/index.js.map +1 -0
  62. package/dist/mcpConfig.d.ts +37 -0
  63. package/dist/mcpConfig.d.ts.map +1 -0
  64. package/dist/mcpConfig.js +83 -0
  65. package/dist/mcpConfig.js.map +1 -0
  66. package/dist/pairApi.d.ts +14 -0
  67. package/dist/pairApi.d.ts.map +1 -0
  68. package/dist/pairApi.js +34 -0
  69. package/dist/pairApi.js.map +1 -0
  70. package/dist/promptApi.d.ts +13 -0
  71. package/dist/promptApi.d.ts.map +1 -0
  72. package/dist/promptApi.js +102 -0
  73. package/dist/promptApi.js.map +1 -0
  74. package/dist/server.d.ts +10 -0
  75. package/dist/server.d.ts.map +1 -0
  76. package/dist/server.js +67 -0
  77. package/dist/server.js.map +1 -0
  78. package/dist/setup.d.ts +2 -0
  79. package/dist/setup.d.ts.map +1 -0
  80. package/dist/setup.js +194 -0
  81. package/dist/setup.js.map +1 -0
  82. package/dist/toolErrors.d.ts +2 -0
  83. package/dist/toolErrors.d.ts.map +1 -0
  84. package/dist/toolErrors.js +18 -0
  85. package/dist/toolErrors.js.map +1 -0
  86. package/dist/tools/activities.d.ts +11 -0
  87. package/dist/tools/activities.d.ts.map +1 -0
  88. package/dist/tools/activities.js +134 -0
  89. package/dist/tools/activities.js.map +1 -0
  90. package/dist/tools/bodyComposition.d.ts +7 -0
  91. package/dist/tools/bodyComposition.d.ts.map +1 -0
  92. package/dist/tools/bodyComposition.js +97 -0
  93. package/dist/tools/bodyComposition.js.map +1 -0
  94. package/dist/tools/heartRate.d.ts +7 -0
  95. package/dist/tools/heartRate.d.ts.map +1 -0
  96. package/dist/tools/heartRate.js +88 -0
  97. package/dist/tools/heartRate.js.map +1 -0
  98. package/dist/tools/index.d.ts +39 -0
  99. package/dist/tools/index.d.ts.map +1 -0
  100. package/dist/tools/index.js +77 -0
  101. package/dist/tools/index.js.map +1 -0
  102. package/dist/tools/recovery.d.ts +16 -0
  103. package/dist/tools/recovery.d.ts.map +1 -0
  104. package/dist/tools/recovery.js +214 -0
  105. package/dist/tools/recovery.js.map +1 -0
  106. package/dist/tools/sleep.d.ts +7 -0
  107. package/dist/tools/sleep.d.ts.map +1 -0
  108. package/dist/tools/sleep.js +93 -0
  109. package/dist/tools/sleep.js.map +1 -0
  110. package/dist/tools/stress.d.ts +7 -0
  111. package/dist/tools/stress.d.ts.map +1 -0
  112. package/dist/tools/stress.js +69 -0
  113. package/dist/tools/stress.js.map +1 -0
  114. package/dist/tools/trainingInsights.d.ts +7 -0
  115. package/dist/tools/trainingInsights.d.ts.map +1 -0
  116. package/dist/tools/trainingInsights.js +61 -0
  117. package/dist/tools/trainingInsights.js.map +1 -0
  118. package/dist/tools/types.d.ts +12 -0
  119. package/dist/tools/types.d.ts.map +1 -0
  120. package/dist/tools/types.js +2 -0
  121. package/dist/tools/types.js.map +1 -0
  122. package/dist/tools/vo2Max.d.ts +7 -0
  123. package/dist/tools/vo2Max.d.ts.map +1 -0
  124. package/dist/tools/vo2Max.js +72 -0
  125. package/dist/tools/vo2Max.js.map +1 -0
  126. package/dist/utils/batch.d.ts +2 -0
  127. package/dist/utils/batch.d.ts.map +1 -0
  128. package/dist/utils/batch.js +18 -0
  129. package/dist/utils/batch.js.map +1 -0
  130. package/dist/utils/helpers.d.ts +19 -0
  131. package/dist/utils/helpers.d.ts.map +1 -0
  132. package/dist/utils/helpers.js +131 -0
  133. package/dist/utils/helpers.js.map +1 -0
  134. package/dist/utils/logger.d.ts +4 -0
  135. package/dist/utils/logger.d.ts.map +1 -0
  136. package/dist/utils/logger.js +59 -0
  137. package/dist/utils/logger.js.map +1 -0
  138. package/dist/version.d.ts +2 -0
  139. package/dist/version.d.ts.map +1 -0
  140. package/dist/version.js +7 -0
  141. package/dist/version.js.map +1 -0
  142. package/dist/watchApi.d.ts +47 -0
  143. package/dist/watchApi.d.ts.map +1 -0
  144. package/dist/watchApi.js +222 -0
  145. package/dist/watchApi.js.map +1 -0
  146. package/package.json +77 -0
@@ -0,0 +1,386 @@
1
+ import http from "node:http";
2
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
3
+ import { closeCache } from "./garmin/cache.js";
4
+ import { closeAppDb, setSetting } from "./appDb.js";
5
+ import { assertGarminCredentials, assertMcpApiKey, appConfig } from "./config.js";
6
+ import { createMcpServerInstance } from "./server.js";
7
+ import { configureLogger, logger } from "./utils/logger.js";
8
+ import { buildWatchSummary } from "./watchApi.js";
9
+ import { requestPairing, checkPairStatus, approvePairing } from "./pairApi.js";
10
+ import { submitPrompt, getPromptStatus } from "./promptApi.js";
11
+ import { renderDashboard, renderPairSuccess, renderPairError } from "./dashboard.js";
12
+ // SECTION: HTTP MCP Server
13
+ const MAX_BODY_BYTES = 1024 * 1024;
14
+ const RATE_LIMIT_WINDOW_MS = 60_000;
15
+ const RATE_LIMIT_MAX_REQUESTS = 60;
16
+ const WATCH_API_CACHE_TTL_MS = 5 * 60_000;
17
+ const requestLog = new Map();
18
+ let watchApiCache = null;
19
+ function getClientKey(req) {
20
+ return req.socket.remoteAddress ?? "unknown";
21
+ }
22
+ function isRateLimited(clientKey) {
23
+ const now = Date.now();
24
+ const entry = requestLog.get(clientKey);
25
+ if (!entry || now - entry.windowStart >= RATE_LIMIT_WINDOW_MS) {
26
+ requestLog.set(clientKey, { count: 1, windowStart: now });
27
+ return false;
28
+ }
29
+ entry.count += 1;
30
+ return entry.count > RATE_LIMIT_MAX_REQUESTS;
31
+ }
32
+ function sendJson(res, statusCode, body) {
33
+ res.writeHead(statusCode, { "Content-Type": "application/json" });
34
+ res.end(JSON.stringify(body));
35
+ }
36
+ function normalizePathname(pathname) {
37
+ if (pathname.length > 1 && pathname.endsWith("/")) {
38
+ return pathname.slice(0, -1);
39
+ }
40
+ return pathname;
41
+ }
42
+ function isAuthorized(req, queryToken) {
43
+ const header = req.headers.authorization;
44
+ const headerToken = header?.startsWith("Bearer ") ? header.slice("Bearer ".length).trim() : null;
45
+ const token = headerToken ?? queryToken ?? null;
46
+ return token !== null && token.length > 0 && token === appConfig.mcpApiKey;
47
+ }
48
+ async function getCachedWatchSummary() {
49
+ const now = Date.now();
50
+ if (watchApiCache && now < watchApiCache.expiresAt) {
51
+ return watchApiCache.summary;
52
+ }
53
+ const summary = await buildWatchSummary();
54
+ watchApiCache = {
55
+ summary,
56
+ expiresAt: now + WATCH_API_CACHE_TTL_MS,
57
+ };
58
+ return summary;
59
+ }
60
+ async function readJsonBody(req) {
61
+ const chunks = [];
62
+ let total = 0;
63
+ for await (const chunk of req) {
64
+ const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
65
+ total += buffer.length;
66
+ if (total > MAX_BODY_BYTES) {
67
+ throw new Error("Request body too large");
68
+ }
69
+ chunks.push(buffer);
70
+ }
71
+ const raw = Buffer.concat(chunks).toString("utf8");
72
+ if (!raw) {
73
+ return undefined;
74
+ }
75
+ return JSON.parse(raw);
76
+ }
77
+ async function handleMcpRequest(req, res) {
78
+ if (!isAuthorized(req)) {
79
+ res.setHeader("WWW-Authenticate", 'Bearer realm="garmin-bud"');
80
+ sendJson(res, 401, {
81
+ error: "Unauthorized",
82
+ message: "Missing or invalid Authorization: Bearer token.",
83
+ });
84
+ return;
85
+ }
86
+ const clientKey = getClientKey(req);
87
+ if (isRateLimited(clientKey)) {
88
+ sendJson(res, 429, {
89
+ error: "Too Many Requests",
90
+ message: "Rate limit exceeded. Try again in a minute.",
91
+ });
92
+ return;
93
+ }
94
+ const server = createMcpServerInstance();
95
+ const transport = new StreamableHTTPServerTransport({
96
+ sessionIdGenerator: undefined,
97
+ });
98
+ try {
99
+ await server.connect(transport);
100
+ const parsedBody = req.method === "POST" ? await readJsonBody(req) : undefined;
101
+ await transport.handleRequest(req, res, parsedBody);
102
+ }
103
+ catch (error) {
104
+ logger.error({ error }, "HTTP MCP request failed");
105
+ if (!res.headersSent) {
106
+ sendJson(res, 500, {
107
+ jsonrpc: "2.0",
108
+ error: {
109
+ code: -32603,
110
+ message: "Internal server error",
111
+ },
112
+ id: null,
113
+ });
114
+ }
115
+ }
116
+ finally {
117
+ res.on("close", () => {
118
+ void transport.close();
119
+ void server.close();
120
+ });
121
+ }
122
+ }
123
+ export function createHttpMcpServer() {
124
+ let httpServer = null;
125
+ return {
126
+ async start() {
127
+ assertGarminCredentials();
128
+ assertMcpApiKey();
129
+ configureLogger(appConfig.logPath);
130
+ // Load Claude key saved via dashboard into process.env if not already set
131
+ const savedClaudeKey = (await import("./appDb.js")).getSetting("anthropic_api_key");
132
+ if (savedClaudeKey && !process.env["ANTHROPIC_API_KEY"]) {
133
+ process.env["ANTHROPIC_API_KEY"] = savedClaudeKey;
134
+ }
135
+ httpServer = http.createServer(async (req, res) => {
136
+ const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
137
+ const pathname = normalizePathname(url.pathname);
138
+ if (pathname === "/" || pathname === "") {
139
+ sendJson(res, 200, {
140
+ service: "garmin-bud",
141
+ endpoints: {
142
+ health: "/health",
143
+ watch: "/api/watch",
144
+ pair: "/api/pair",
145
+ prompt: "/api/prompt",
146
+ dashboard: "/dashboard",
147
+ mcp: "/mcp",
148
+ },
149
+ message: "Dashboard: GET /dashboard?token=YOUR_API_KEY",
150
+ });
151
+ return;
152
+ }
153
+ if (pathname === "/health") {
154
+ sendJson(res, 200, { status: "ok", service: "garmin-bud" });
155
+ return;
156
+ }
157
+ // --- Pairing ---
158
+ if (pathname === "/api/pair" && req.method === "POST") {
159
+ const result = requestPairing();
160
+ sendJson(res, 200, result);
161
+ return;
162
+ }
163
+ if (pathname.startsWith("/api/pair/") && pathname.endsWith("/status") && req.method === "GET") {
164
+ const code = pathname.slice("/api/pair/".length, -"/status".length);
165
+ const status = checkPairStatus(code);
166
+ if (!status) {
167
+ sendJson(res, 404, { error: "Pair code not found or expired" });
168
+ }
169
+ else {
170
+ sendJson(res, 200, status);
171
+ }
172
+ return;
173
+ }
174
+ // --- Prompt ---
175
+ if (pathname === "/api/prompt" && req.method === "POST") {
176
+ if (!isAuthorized(req)) {
177
+ res.setHeader("WWW-Authenticate", 'Bearer realm="garmin-bud"');
178
+ sendJson(res, 401, { error: "Unauthorized" });
179
+ return;
180
+ }
181
+ let body;
182
+ try {
183
+ body = await readJsonBody(req);
184
+ }
185
+ catch {
186
+ sendJson(res, 400, { error: "Invalid JSON body" });
187
+ return;
188
+ }
189
+ if (typeof body !== "object" || body === null || typeof body["prompt"] !== "string") {
190
+ sendJson(res, 400, { error: "Missing prompt field" });
191
+ return;
192
+ }
193
+ const prompt = body["prompt"].trim();
194
+ if (prompt.length === 0 || prompt.length > 500) {
195
+ sendJson(res, 400, { error: "Prompt must be 1–500 characters" });
196
+ return;
197
+ }
198
+ const result = submitPrompt(prompt);
199
+ sendJson(res, 202, result);
200
+ return;
201
+ }
202
+ if (pathname.startsWith("/api/prompt/") && req.method === "GET") {
203
+ if (!isAuthorized(req)) {
204
+ res.setHeader("WWW-Authenticate", 'Bearer realm="garmin-bud"');
205
+ sendJson(res, 401, { error: "Unauthorized" });
206
+ return;
207
+ }
208
+ const jobId = pathname.slice("/api/prompt/".length);
209
+ const status = getPromptStatus(jobId);
210
+ if (!status) {
211
+ sendJson(res, 404, { error: "Job not found" });
212
+ }
213
+ else {
214
+ sendJson(res, 200, status);
215
+ }
216
+ return;
217
+ }
218
+ // --- Dashboard ---
219
+ const queryToken = url.searchParams.get("token") ?? undefined;
220
+ if (pathname === "/dashboard") {
221
+ if (!isAuthorized(req, queryToken)) {
222
+ res.setHeader("WWW-Authenticate", 'Bearer realm="garmin-bud"');
223
+ res.writeHead(401, { "Content-Type": "text/html" });
224
+ res.end("<h1>401 Unauthorized</h1><p>Add <code>Authorization: Bearer YOUR_API_KEY</code> header, or use the URL <code>/dashboard?token=YOUR_API_KEY</code></p>");
225
+ return;
226
+ }
227
+ res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
228
+ res.end(renderDashboard());
229
+ return;
230
+ }
231
+ if (pathname === "/dashboard/pair/approve" && req.method === "POST") {
232
+ if (!isAuthorized(req, queryToken)) {
233
+ res.setHeader("WWW-Authenticate", 'Bearer realm="garmin-bud"');
234
+ res.writeHead(401, { "Content-Type": "text/html" });
235
+ res.end("<h1>401 Unauthorized</h1>");
236
+ return;
237
+ }
238
+ let formCode = null;
239
+ try {
240
+ const raw = await readJsonBody(req);
241
+ if (raw && typeof raw["code"] === "string") {
242
+ formCode = raw["code"];
243
+ }
244
+ }
245
+ catch {
246
+ // Try reading as URL-encoded form
247
+ }
248
+ if (!formCode) {
249
+ // Read as URL-encoded form
250
+ const chunks = [];
251
+ for await (const chunk of req) {
252
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
253
+ }
254
+ const raw = Buffer.concat(chunks).toString("utf8");
255
+ const params = new URLSearchParams(raw);
256
+ formCode = params.get("code");
257
+ }
258
+ if (!formCode) {
259
+ res.writeHead(400, { "Content-Type": "text/html; charset=utf-8" });
260
+ res.end(renderPairError("Missing code parameter."));
261
+ return;
262
+ }
263
+ const ok = approvePairing(formCode);
264
+ res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
265
+ res.end(ok ? renderPairSuccess(formCode) : renderPairError("Code not found or expired."));
266
+ return;
267
+ }
268
+ if (pathname === "/dashboard/settings" && req.method === "POST") {
269
+ if (!isAuthorized(req, queryToken)) {
270
+ res.setHeader("WWW-Authenticate", 'Bearer realm="garmin-bud"');
271
+ res.writeHead(401, { "Content-Type": "text/html" });
272
+ res.end("<h1>401 Unauthorized</h1>");
273
+ return;
274
+ }
275
+ const chunks = [];
276
+ for await (const chunk of req) {
277
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
278
+ }
279
+ const raw = Buffer.concat(chunks).toString("utf8");
280
+ const params = new URLSearchParams(raw);
281
+ const key = params.get("anthropic_api_key")?.trim();
282
+ if (key && key.length > 0) {
283
+ setSetting("anthropic_api_key", key);
284
+ process.env["ANTHROPIC_API_KEY"] = key;
285
+ }
286
+ res.writeHead(302, { Location: "/dashboard" });
287
+ res.end();
288
+ return;
289
+ }
290
+ if (pathname === "/api/watch") {
291
+ if (req.method !== "GET") {
292
+ sendJson(res, 405, { error: "Method Not Allowed", message: "Use GET for /api/watch." });
293
+ return;
294
+ }
295
+ if (!isAuthorized(req)) {
296
+ res.setHeader("WWW-Authenticate", 'Bearer realm="garmin-bud"');
297
+ sendJson(res, 401, {
298
+ error: "Unauthorized",
299
+ message: "Missing or invalid Authorization: Bearer token.",
300
+ });
301
+ return;
302
+ }
303
+ try {
304
+ const summary = await getCachedWatchSummary();
305
+ sendJson(res, 200, summary);
306
+ }
307
+ catch (error) {
308
+ logger.error({ error }, "Watch API request failed");
309
+ sendJson(res, 500, {
310
+ error: "Internal Server Error",
311
+ message: "Failed to build watch summary.",
312
+ });
313
+ }
314
+ return;
315
+ }
316
+ if (pathname === "/mcp") {
317
+ if (req.method !== "POST") {
318
+ sendJson(res, 405, {
319
+ jsonrpc: "2.0",
320
+ error: {
321
+ code: -32000,
322
+ message: "Method not allowed. Use POST for MCP requests.",
323
+ },
324
+ id: null,
325
+ });
326
+ return;
327
+ }
328
+ await handleMcpRequest(req, res);
329
+ return;
330
+ }
331
+ sendJson(res, 404, { error: "Not Found" });
332
+ });
333
+ await new Promise((resolve, reject) => {
334
+ httpServer.listen(appConfig.mcpPort, appConfig.mcpHost, (error) => {
335
+ if (error) {
336
+ reject(error);
337
+ return;
338
+ }
339
+ resolve();
340
+ });
341
+ });
342
+ logger.info({ host: appConfig.mcpHost, port: appConfig.mcpPort }, "GarminBud HTTP MCP server listening");
343
+ },
344
+ async close() {
345
+ if (!httpServer) {
346
+ return;
347
+ }
348
+ await new Promise((resolve, reject) => {
349
+ httpServer.close((error) => {
350
+ if (error) {
351
+ reject(error);
352
+ return;
353
+ }
354
+ resolve();
355
+ });
356
+ });
357
+ httpServer = null;
358
+ watchApiCache = null;
359
+ closeCache();
360
+ closeAppDb();
361
+ },
362
+ };
363
+ }
364
+ export function getRemoteConnectorInstructions(publicUrl) {
365
+ return [
366
+ "Remote MCP connector setup:",
367
+ "",
368
+ `1. Start the server: garmin-bud serve`,
369
+ `2. Expose HTTPS (e.g. Cloudflare Tunnel): cloudflared tunnel --url http://127.0.0.1:${appConfig.mcpPort}`,
370
+ `3. Use your public URL + /mcp as the connector endpoint`,
371
+ "",
372
+ "Claude.ai:",
373
+ "- Settings → Connectors → Add custom connector",
374
+ `- URL: ${publicUrl.replace(/\/$/, "")}/mcp`,
375
+ "- Authentication: Bearer token (your GARMIN_MCP_API_KEY from .env)",
376
+ "",
377
+ "ChatGPT (Developer Mode):",
378
+ "- Settings → Connectors → create MCP connector",
379
+ `- Server URL: ${publicUrl.replace(/\/$/, "")}/mcp`,
380
+ "- Auth: Bearer token with GARMIN_MCP_API_KEY",
381
+ "- Note: ChatGPT MCP auth behavior may differ; test after Claude.ai works",
382
+ "",
383
+ `Health check: ${publicUrl.replace(/\/$/, "")}/health`,
384
+ ].join("\n");
385
+ }
386
+ //# sourceMappingURL=httpServer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"httpServer.js","sourceRoot":"","sources":["../src/httpServer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ import { createCliProgram } from "./cli.js";
3
+ async function main() {
4
+ const program = createCliProgram();
5
+ await program.parseAsync(process.argv);
6
+ }
7
+ main().catch((error) => {
8
+ console.error(error instanceof Error ? error.message : error);
9
+ process.exit(1);
10
+ });
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE5C,KAAK,UAAU,IAAI;IACjB,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC;IACnC,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAC9D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,37 @@
1
+ export interface McpServerEntry {
2
+ command?: string;
3
+ args?: string[];
4
+ env?: Record<string, string>;
5
+ url?: string;
6
+ headers?: Record<string, string>;
7
+ timeout?: number;
8
+ }
9
+ export interface McpConfigFile {
10
+ mcpServers: Record<string, McpServerEntry>;
11
+ }
12
+ export interface DetectedMcpClient {
13
+ id: "cursor" | "claude-desktop";
14
+ label: string;
15
+ configPath: string;
16
+ }
17
+ export declare function getClaudeDesktopConfigPath(): string;
18
+ export declare function getCursorConfigPath(): string;
19
+ export declare function detectMcpClients(): DetectedMcpClient[];
20
+ export declare function readMcpConfig(configPath: string): McpConfigFile;
21
+ export declare function buildGarminBudServerEntry(credentials: {
22
+ email: string;
23
+ password: string;
24
+ distIndexPath: string;
25
+ }): McpServerEntry;
26
+ export declare function mergeGarminBudConfig(config: McpConfigFile, credentials: {
27
+ email: string;
28
+ password: string;
29
+ distIndexPath: string;
30
+ }): McpConfigFile;
31
+ export declare function writeMcpConfig(configPath: string, config: McpConfigFile): void;
32
+ export declare function configureGarminBudForClient(client: DetectedMcpClient, credentials: {
33
+ email: string;
34
+ password: string;
35
+ distIndexPath: string;
36
+ }): void;
37
+ //# sourceMappingURL=mcpConfig.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcpConfig.d.ts","sourceRoot":"","sources":["../src/mcpConfig.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,QAAQ,GAAG,gBAAgB,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,0BAA0B,IAAI,MAAM,CAYnD;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED,wBAAgB,gBAAgB,IAAI,iBAAiB,EAAE,CAsBtD;AAED,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa,CAiB/D;AAED,wBAAgB,yBAAyB,CAAC,WAAW,EAAE;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,cAAc,CAWjB;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,aAAa,EACrB,WAAW,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GACtE,aAAa,CAQf;AAED,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CAG9E;AAED,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,iBAAiB,EACzB,WAAW,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GACtE,IAAI,CAIN"}
@@ -0,0 +1,83 @@
1
+ import fs from "node:fs";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ export function getClaudeDesktopConfigPath() {
5
+ if (process.platform === "darwin") {
6
+ return path.join(os.homedir(), "Library", "Application Support", "Claude", "claude_desktop_config.json");
7
+ }
8
+ if (process.platform === "win32") {
9
+ const appData = process.env.APPDATA ?? path.join(os.homedir(), "AppData", "Roaming");
10
+ return path.join(appData, "Claude", "claude_desktop_config.json");
11
+ }
12
+ const configHome = process.env.XDG_CONFIG_HOME ?? path.join(os.homedir(), ".config");
13
+ return path.join(configHome, "Claude", "claude_desktop_config.json");
14
+ }
15
+ export function getCursorConfigPath() {
16
+ return path.join(os.homedir(), ".cursor", "mcp.json");
17
+ }
18
+ export function detectMcpClients() {
19
+ const clients = [];
20
+ const cursorPath = getCursorConfigPath();
21
+ const claudePath = getClaudeDesktopConfigPath();
22
+ if (fs.existsSync(path.dirname(cursorPath))) {
23
+ clients.push({
24
+ id: "cursor",
25
+ label: "Cursor",
26
+ configPath: cursorPath,
27
+ });
28
+ }
29
+ if (fs.existsSync(path.dirname(claudePath))) {
30
+ clients.push({
31
+ id: "claude-desktop",
32
+ label: "Claude Desktop",
33
+ configPath: claudePath,
34
+ });
35
+ }
36
+ return clients;
37
+ }
38
+ export function readMcpConfig(configPath) {
39
+ if (!fs.existsSync(configPath)) {
40
+ return { mcpServers: {} };
41
+ }
42
+ try {
43
+ const raw = fs.readFileSync(configPath, "utf8");
44
+ const parsed = JSON.parse(raw);
45
+ if (!parsed.mcpServers || typeof parsed.mcpServers !== "object") {
46
+ return { mcpServers: {} };
47
+ }
48
+ return { mcpServers: parsed.mcpServers };
49
+ }
50
+ catch {
51
+ throw new Error(`Could not read MCP config at ${configPath}. Fix the file or choose another client.`);
52
+ }
53
+ }
54
+ export function buildGarminBudServerEntry(credentials) {
55
+ const normalizedIndexPath = credentials.distIndexPath.replace(/\\/g, "/");
56
+ return {
57
+ command: "node",
58
+ args: [normalizedIndexPath, "start"],
59
+ env: {
60
+ GARMIN_EMAIL: credentials.email,
61
+ GARMIN_PASSWORD: credentials.password,
62
+ },
63
+ };
64
+ }
65
+ export function mergeGarminBudConfig(config, credentials) {
66
+ return {
67
+ ...config,
68
+ mcpServers: {
69
+ ...config.mcpServers,
70
+ "garmin-bud": buildGarminBudServerEntry(credentials),
71
+ },
72
+ };
73
+ }
74
+ export function writeMcpConfig(configPath, config) {
75
+ fs.mkdirSync(path.dirname(configPath), { recursive: true });
76
+ fs.writeFileSync(configPath, `${JSON.stringify(config, null, 2)}\n`, "utf8");
77
+ }
78
+ export function configureGarminBudForClient(client, credentials) {
79
+ const existing = readMcpConfig(client.configPath);
80
+ const merged = mergeGarminBudConfig(existing, credentials);
81
+ writeMcpConfig(client.configPath, merged);
82
+ }
83
+ //# sourceMappingURL=mcpConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcpConfig.js","sourceRoot":"","sources":["../src/mcpConfig.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export interface PairRequestResult {
2
+ code: string;
3
+ expires_in: number;
4
+ }
5
+ export interface PairStatusResult {
6
+ approved: boolean;
7
+ api_key?: string;
8
+ server_url?: string;
9
+ }
10
+ export declare function requestPairing(): PairRequestResult;
11
+ export declare function checkPairStatus(code: string): PairStatusResult | null;
12
+ export declare function approvePairing(code: string): boolean;
13
+ export declare function getPendingPairings(): import("./appDb.js").PairToken[];
14
+ //# sourceMappingURL=pairApi.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pairApi.d.ts","sourceRoot":"","sources":["../src/pairApi.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,cAAc,IAAI,iBAAiB,CAOlD;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAiBrE;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED,wBAAgB,kBAAkB,qCAEjC"}
@@ -0,0 +1,34 @@
1
+ import { createPairToken, getPairToken, approvePairToken, deletePairToken, listPendingPairTokens } from "./appDb.js";
2
+ import { appConfig } from "./config.js";
3
+ export function requestPairing() {
4
+ const token = createPairToken();
5
+ const now = Math.floor(Date.now() / 1000);
6
+ return {
7
+ code: token.code,
8
+ expires_in: token.expires_at - now,
9
+ };
10
+ }
11
+ export function checkPairStatus(code) {
12
+ const token = getPairToken(code);
13
+ if (!token)
14
+ return null;
15
+ const now = Math.floor(Date.now() / 1000);
16
+ if (token.expires_at < now)
17
+ return null;
18
+ if (token.approved_at !== null) {
19
+ deletePairToken(code);
20
+ return {
21
+ approved: true,
22
+ api_key: appConfig.mcpApiKey,
23
+ server_url: appConfig.publicUrl,
24
+ };
25
+ }
26
+ return { approved: false };
27
+ }
28
+ export function approvePairing(code) {
29
+ return approvePairToken(code);
30
+ }
31
+ export function getPendingPairings() {
32
+ return listPendingPairTokens();
33
+ }
34
+ //# sourceMappingURL=pairApi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pairApi.js","sourceRoot":"","sources":["../src/pairApi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACrH,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAexC,MAAM,UAAU,cAAc;IAC5B,MAAM,KAAK,GAAG,eAAe,EAAE,CAAC;IAChC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAC1C,OAAO;QACL,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,UAAU,EAAE,KAAK,CAAC,UAAU,GAAG,GAAG;KACnC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAExB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAC1C,IAAI,KAAK,CAAC,UAAU,GAAG,GAAG;QAAE,OAAO,IAAI,CAAC;IAExC,IAAI,KAAK,CAAC,WAAW,KAAK,IAAI,EAAE,CAAC;QAC/B,eAAe,CAAC,IAAI,CAAC,CAAC;QACtB,OAAO;YACL,QAAQ,EAAE,IAAI;YACd,OAAO,EAAE,SAAS,CAAC,SAAS;YAC5B,UAAU,EAAE,SAAS,CAAC,SAAS;SAChC,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,OAAO,qBAAqB,EAAE,CAAC;AACjC,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { buildWatchSummary } from "./watchApi.js";
2
+ export interface SubmitPromptResult {
3
+ job_id: string;
4
+ }
5
+ export declare function submitPrompt(prompt: string): SubmitPromptResult;
6
+ export interface PromptJobStatus {
7
+ status: "pending" | "running" | "done" | "error";
8
+ result?: string;
9
+ error?: string;
10
+ }
11
+ export declare function getPromptStatus(id: string): PromptJobStatus | null;
12
+ export declare function generateDailyInsight(summary: Awaited<ReturnType<typeof buildWatchSummary>>): Promise<string | null>;
13
+ //# sourceMappingURL=promptApi.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promptApi.d.ts","sourceRoot":"","sources":["../src/promptApi.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AA6DlD,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,kBAAkB,CAU/D;AAgBD,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;IACjD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAQlE;AAED,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC,GACrD,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAexB"}