trainbud 0.5.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 (274) hide show
  1. package/.env.example +11 -0
  2. package/CHANGELOG.md +675 -0
  3. package/LICENSE +21 -0
  4. package/QUICKSTART.md +182 -0
  5. package/README.md +322 -0
  6. package/dist/appDb.d.ts +83 -0
  7. package/dist/appDb.d.ts.map +1 -0
  8. package/dist/appDb.js +239 -0
  9. package/dist/appDb.js.map +1 -0
  10. package/dist/check.d.ts +12 -0
  11. package/dist/check.d.ts.map +1 -0
  12. package/dist/check.js +230 -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 +457 -0
  17. package/dist/cli.js.map +1 -0
  18. package/dist/config.d.ts +61 -0
  19. package/dist/config.d.ts.map +1 -0
  20. package/dist/config.js +241 -0
  21. package/dist/config.js.map +1 -0
  22. package/dist/dashboard.d.ts +8 -0
  23. package/dist/dashboard.d.ts.map +1 -0
  24. package/dist/dashboard.js +1004 -0
  25. package/dist/dashboard.js.map +1 -0
  26. package/dist/dashboardCharts.d.ts +99 -0
  27. package/dist/dashboardCharts.d.ts.map +1 -0
  28. package/dist/dashboardCharts.js +317 -0
  29. package/dist/dashboardCharts.js.map +1 -0
  30. package/dist/dashboardData.d.ts +89 -0
  31. package/dist/dashboardData.d.ts.map +1 -0
  32. package/dist/dashboardData.js +228 -0
  33. package/dist/dashboardData.js.map +1 -0
  34. package/dist/detect/baseline.d.ts +17 -0
  35. package/dist/detect/baseline.d.ts.map +1 -0
  36. package/dist/detect/baseline.js +62 -0
  37. package/dist/detect/baseline.js.map +1 -0
  38. package/dist/detect/countdown.d.ts +30 -0
  39. package/dist/detect/countdown.d.ts.map +1 -0
  40. package/dist/detect/countdown.js +79 -0
  41. package/dist/detect/countdown.js.map +1 -0
  42. package/dist/detect/detectors.d.ts +20 -0
  43. package/dist/detect/detectors.d.ts.map +1 -0
  44. package/dist/detect/detectors.js +291 -0
  45. package/dist/detect/detectors.js.map +1 -0
  46. package/dist/detect/findings.d.ts +29 -0
  47. package/dist/detect/findings.d.ts.map +1 -0
  48. package/dist/detect/findings.js +2 -0
  49. package/dist/detect/findings.js.map +1 -0
  50. package/dist/detect/forecast.d.ts +33 -0
  51. package/dist/detect/forecast.d.ts.map +1 -0
  52. package/dist/detect/forecast.js +122 -0
  53. package/dist/detect/forecast.js.map +1 -0
  54. package/dist/detect/index.d.ts +50 -0
  55. package/dist/detect/index.d.ts.map +1 -0
  56. package/dist/detect/index.js +114 -0
  57. package/dist/detect/index.js.map +1 -0
  58. package/dist/detect/sleepQuality.d.ts +21 -0
  59. package/dist/detect/sleepQuality.d.ts.map +1 -0
  60. package/dist/detect/sleepQuality.js +164 -0
  61. package/dist/detect/sleepQuality.js.map +1 -0
  62. package/dist/detect/trimp.d.ts +22 -0
  63. package/dist/detect/trimp.d.ts.map +1 -0
  64. package/dist/detect/trimp.js +77 -0
  65. package/dist/detect/trimp.js.map +1 -0
  66. package/dist/detect/week.d.ts +31 -0
  67. package/dist/detect/week.d.ts.map +1 -0
  68. package/dist/detect/week.js +184 -0
  69. package/dist/detect/week.js.map +1 -0
  70. package/dist/garmin/auth.d.ts +10 -0
  71. package/dist/garmin/auth.d.ts.map +1 -0
  72. package/dist/garmin/auth.js +81 -0
  73. package/dist/garmin/auth.js.map +1 -0
  74. package/dist/garmin/cache.d.ts +42 -0
  75. package/dist/garmin/cache.d.ts.map +1 -0
  76. package/dist/garmin/cache.js +141 -0
  77. package/dist/garmin/cache.js.map +1 -0
  78. package/dist/garmin/client.d.ts +22 -0
  79. package/dist/garmin/client.d.ts.map +1 -0
  80. package/dist/garmin/client.js +237 -0
  81. package/dist/garmin/client.js.map +1 -0
  82. package/dist/garmin/daily.d.ts +24 -0
  83. package/dist/garmin/daily.d.ts.map +1 -0
  84. package/dist/garmin/daily.js +96 -0
  85. package/dist/garmin/daily.js.map +1 -0
  86. package/dist/garmin/garminApiTypes.d.ts +70 -0
  87. package/dist/garmin/garminApiTypes.d.ts.map +1 -0
  88. package/dist/garmin/garminApiTypes.js +3 -0
  89. package/dist/garmin/garminApiTypes.js.map +1 -0
  90. package/dist/garmin/garminConnect.d.ts +17 -0
  91. package/dist/garmin/garminConnect.d.ts.map +1 -0
  92. package/dist/garmin/garminConnect.js +5 -0
  93. package/dist/garmin/garminConnect.js.map +1 -0
  94. package/dist/garmin/partial.d.ts +32 -0
  95. package/dist/garmin/partial.d.ts.map +1 -0
  96. package/dist/garmin/partial.js +38 -0
  97. package/dist/garmin/partial.js.map +1 -0
  98. package/dist/garmin/rawApi.d.ts +59 -0
  99. package/dist/garmin/rawApi.d.ts.map +1 -0
  100. package/dist/garmin/rawApi.js +113 -0
  101. package/dist/garmin/rawApi.js.map +1 -0
  102. package/dist/garmin/types.d.ts +85 -0
  103. package/dist/garmin/types.d.ts.map +1 -0
  104. package/dist/garmin/types.js +11 -0
  105. package/dist/garmin/types.js.map +1 -0
  106. package/dist/history/capture.d.ts +12 -0
  107. package/dist/history/capture.d.ts.map +1 -0
  108. package/dist/history/capture.js +63 -0
  109. package/dist/history/capture.js.map +1 -0
  110. package/dist/history/context.d.ts +51 -0
  111. package/dist/history/context.d.ts.map +1 -0
  112. package/dist/history/context.js +122 -0
  113. package/dist/history/context.js.map +1 -0
  114. package/dist/history/fallback.d.ts +72 -0
  115. package/dist/history/fallback.d.ts.map +1 -0
  116. package/dist/history/fallback.js +185 -0
  117. package/dist/history/fallback.js.map +1 -0
  118. package/dist/history/ingest.d.ts +44 -0
  119. package/dist/history/ingest.d.ts.map +1 -0
  120. package/dist/history/ingest.js +347 -0
  121. package/dist/history/ingest.js.map +1 -0
  122. package/dist/history/scheduler.d.ts +20 -0
  123. package/dist/history/scheduler.d.ts.map +1 -0
  124. package/dist/history/scheduler.js +54 -0
  125. package/dist/history/scheduler.js.map +1 -0
  126. package/dist/history/schema.d.ts +41 -0
  127. package/dist/history/schema.d.ts.map +1 -0
  128. package/dist/history/schema.js +91 -0
  129. package/dist/history/schema.js.map +1 -0
  130. package/dist/history/store.d.ts +112 -0
  131. package/dist/history/store.d.ts.map +1 -0
  132. package/dist/history/store.js +282 -0
  133. package/dist/history/store.js.map +1 -0
  134. package/dist/httpServer.d.ts +55 -0
  135. package/dist/httpServer.d.ts.map +1 -0
  136. package/dist/httpServer.js +1027 -0
  137. package/dist/httpServer.js.map +1 -0
  138. package/dist/index.d.ts +3 -0
  139. package/dist/index.d.ts.map +1 -0
  140. package/dist/index.js +11 -0
  141. package/dist/index.js.map +1 -0
  142. package/dist/mcpConfig.d.ts +56 -0
  143. package/dist/mcpConfig.d.ts.map +1 -0
  144. package/dist/mcpConfig.js +106 -0
  145. package/dist/mcpConfig.js.map +1 -0
  146. package/dist/pairApi.d.ts +14 -0
  147. package/dist/pairApi.d.ts.map +1 -0
  148. package/dist/pairApi.js +38 -0
  149. package/dist/pairApi.js.map +1 -0
  150. package/dist/paths.d.ts +45 -0
  151. package/dist/paths.d.ts.map +1 -0
  152. package/dist/paths.js +105 -0
  153. package/dist/paths.js.map +1 -0
  154. package/dist/profile.d.ts +123 -0
  155. package/dist/profile.d.ts.map +1 -0
  156. package/dist/profile.js +327 -0
  157. package/dist/profile.js.map +1 -0
  158. package/dist/promptApi.d.ts +43 -0
  159. package/dist/promptApi.d.ts.map +1 -0
  160. package/dist/promptApi.js +328 -0
  161. package/dist/promptApi.js.map +1 -0
  162. package/dist/promptSuggestions.d.ts +16 -0
  163. package/dist/promptSuggestions.d.ts.map +1 -0
  164. package/dist/promptSuggestions.js +141 -0
  165. package/dist/promptSuggestions.js.map +1 -0
  166. package/dist/selfTest.d.ts +53 -0
  167. package/dist/selfTest.d.ts.map +1 -0
  168. package/dist/selfTest.js +225 -0
  169. package/dist/selfTest.js.map +1 -0
  170. package/dist/server.d.ts +10 -0
  171. package/dist/server.d.ts.map +1 -0
  172. package/dist/server.js +67 -0
  173. package/dist/server.js.map +1 -0
  174. package/dist/setup.d.ts +2 -0
  175. package/dist/setup.d.ts.map +1 -0
  176. package/dist/setup.js +210 -0
  177. package/dist/setup.js.map +1 -0
  178. package/dist/toolErrors.d.ts +2 -0
  179. package/dist/toolErrors.d.ts.map +1 -0
  180. package/dist/toolErrors.js +18 -0
  181. package/dist/toolErrors.js.map +1 -0
  182. package/dist/tools/activities.d.ts +18 -0
  183. package/dist/tools/activities.d.ts.map +1 -0
  184. package/dist/tools/activities.js +182 -0
  185. package/dist/tools/activities.js.map +1 -0
  186. package/dist/tools/bodyComposition.d.ts +10 -0
  187. package/dist/tools/bodyComposition.d.ts.map +1 -0
  188. package/dist/tools/bodyComposition.js +139 -0
  189. package/dist/tools/bodyComposition.js.map +1 -0
  190. package/dist/tools/context.d.ts +8 -0
  191. package/dist/tools/context.d.ts.map +1 -0
  192. package/dist/tools/context.js +148 -0
  193. package/dist/tools/context.js.map +1 -0
  194. package/dist/tools/findings.d.ts +7 -0
  195. package/dist/tools/findings.d.ts.map +1 -0
  196. package/dist/tools/findings.js +51 -0
  197. package/dist/tools/findings.js.map +1 -0
  198. package/dist/tools/heartRate.d.ts +10 -0
  199. package/dist/tools/heartRate.d.ts.map +1 -0
  200. package/dist/tools/heartRate.js +105 -0
  201. package/dist/tools/heartRate.js.map +1 -0
  202. package/dist/tools/index.d.ts +66 -0
  203. package/dist/tools/index.d.ts.map +1 -0
  204. package/dist/tools/index.js +101 -0
  205. package/dist/tools/index.js.map +1 -0
  206. package/dist/tools/payloads.d.ts +148 -0
  207. package/dist/tools/payloads.d.ts.map +1 -0
  208. package/dist/tools/payloads.js +2 -0
  209. package/dist/tools/payloads.js.map +1 -0
  210. package/dist/tools/recovery.d.ts +31 -0
  211. package/dist/tools/recovery.d.ts.map +1 -0
  212. package/dist/tools/recovery.js +350 -0
  213. package/dist/tools/recovery.js.map +1 -0
  214. package/dist/tools/sleep.d.ts +10 -0
  215. package/dist/tools/sleep.d.ts.map +1 -0
  216. package/dist/tools/sleep.js +124 -0
  217. package/dist/tools/sleep.js.map +1 -0
  218. package/dist/tools/stress.d.ts +11 -0
  219. package/dist/tools/stress.d.ts.map +1 -0
  220. package/dist/tools/stress.js +108 -0
  221. package/dist/tools/stress.js.map +1 -0
  222. package/dist/tools/trainingInsights.d.ts +15 -0
  223. package/dist/tools/trainingInsights.d.ts.map +1 -0
  224. package/dist/tools/trainingInsights.js +79 -0
  225. package/dist/tools/trainingInsights.js.map +1 -0
  226. package/dist/tools/types.d.ts +12 -0
  227. package/dist/tools/types.d.ts.map +1 -0
  228. package/dist/tools/types.js +2 -0
  229. package/dist/tools/types.js.map +1 -0
  230. package/dist/tools/vo2Max.d.ts +11 -0
  231. package/dist/tools/vo2Max.d.ts.map +1 -0
  232. package/dist/tools/vo2Max.js +110 -0
  233. package/dist/tools/vo2Max.js.map +1 -0
  234. package/dist/tools/week.d.ts +12 -0
  235. package/dist/tools/week.d.ts.map +1 -0
  236. package/dist/tools/week.js +74 -0
  237. package/dist/tools/week.js.map +1 -0
  238. package/dist/usage.d.ts +104 -0
  239. package/dist/usage.d.ts.map +1 -0
  240. package/dist/usage.js +247 -0
  241. package/dist/usage.js.map +1 -0
  242. package/dist/utils/batch.d.ts +2 -0
  243. package/dist/utils/batch.d.ts.map +1 -0
  244. package/dist/utils/batch.js +18 -0
  245. package/dist/utils/batch.js.map +1 -0
  246. package/dist/utils/helpers.d.ts +32 -0
  247. package/dist/utils/helpers.d.ts.map +1 -0
  248. package/dist/utils/helpers.js +188 -0
  249. package/dist/utils/helpers.js.map +1 -0
  250. package/dist/utils/jsonFile.d.ts +19 -0
  251. package/dist/utils/jsonFile.d.ts.map +1 -0
  252. package/dist/utils/jsonFile.js +24 -0
  253. package/dist/utils/jsonFile.js.map +1 -0
  254. package/dist/utils/logger.d.ts +4 -0
  255. package/dist/utils/logger.d.ts.map +1 -0
  256. package/dist/utils/logger.js +97 -0
  257. package/dist/utils/logger.js.map +1 -0
  258. package/dist/utils/secretFile.d.ts +15 -0
  259. package/dist/utils/secretFile.d.ts.map +1 -0
  260. package/dist/utils/secretFile.js +47 -0
  261. package/dist/utils/secretFile.js.map +1 -0
  262. package/dist/utils/stdio.d.ts +10 -0
  263. package/dist/utils/stdio.d.ts.map +1 -0
  264. package/dist/utils/stdio.js +70 -0
  265. package/dist/utils/stdio.js.map +1 -0
  266. package/dist/version.d.ts +2 -0
  267. package/dist/version.d.ts.map +1 -0
  268. package/dist/version.js +7 -0
  269. package/dist/version.js.map +1 -0
  270. package/dist/watchApi.d.ts +264 -0
  271. package/dist/watchApi.d.ts.map +1 -0
  272. package/dist/watchApi.js +333 -0
  273. package/dist/watchApi.js.map +1 -0
  274. package/package.json +77 -0
package/dist/cli.js ADDED
@@ -0,0 +1,457 @@
1
+ import { Command, InvalidArgumentError } from "commander";
2
+ import { authenticateGarmin, clearStoredSession, sessionExists } from "./garmin/auth.js";
3
+ import { closeCache, getCache } from "./garmin/cache.js";
4
+ import { resetGarminClient } from "./garmin/client.js";
5
+ import { createMcpServer } from "./server.js";
6
+ import { createHttpMcpServer, getRemoteConnectorInstructions } from "./httpServer.js";
7
+ import { assertGarminCredentials, appConfig, assertApiKey, deprecatedEnvNames } from "./config.js";
8
+ import { DATA_DIR_NAME, LEGACY_DATA_DIR_NAME, migrateLegacyDataDir } from "./paths.js";
9
+ import { configureLogger, logger } from "./utils/logger.js";
10
+ import { protectStdout } from "./utils/stdio.js";
11
+ import { packageVersion } from "./version.js";
12
+ import { runSetup } from "./setup.js";
13
+ import { withGarminClient } from "./garmin/client.js";
14
+ import { DEFAULT_SOURCES, runIngest } from "./history/ingest.js";
15
+ import { GarminApiError } from "./garmin/types.js";
16
+ import { startHistoryScheduler } from "./history/scheduler.js";
17
+ import { closeHistoryDb, historyStats, pruneRawPayloads, RAW_RETENTION_DAYS, RAW_REVISIONS_KEPT, } from "./history/store.js";
18
+ import { describeFindingsCoverage, runDetectors } from "./detect/index.js";
19
+ import { printLiveCheckResults, runLiveCheck } from "./check.js";
20
+ // SECTION: Bootstrap
21
+ //
22
+ // Runs before every command. Moves pre-0.3.0 state out of `.garmin/` and warns
23
+ // once about renamed environment variables, so an existing install keeps its
24
+ // session, cache and watch pairing across the rename.
25
+ /**
26
+ * A numeric option, or a clear refusal.
27
+ *
28
+ * Number.parseInt("abc") is NaN, and NaN flowed straight through: `--days abc`
29
+ * printed "Backfilling NaN days", every date arithmetic produced Invalid Date,
30
+ * and the run did nothing while reporting that it was working. `--delay-ms abc`
31
+ * was worse -- a NaN delay is not a pause, so the throttle between Garmin
32
+ * requests silently disappeared on the one command that makes hundreds of them.
33
+ */
34
+ function positiveIntOption(name, min = 1) {
35
+ return (value) => {
36
+ const parsed = Number.parseInt(value, 10);
37
+ if (!Number.isFinite(parsed) || parsed < min) {
38
+ throw new InvalidArgumentError(`${name} must be a whole number of at least ${min}. Got "${value}".`);
39
+ }
40
+ return parsed;
41
+ };
42
+ }
43
+ /**
44
+ * Print a failure the way its cause deserves.
45
+ *
46
+ * A Garmin rate limit is an expected, actionable wait, and it was being reported
47
+ * with `logger.error` plus a full stack trace — so the screen filled with a
48
+ * kilobyte of Cloudflare JSON and a stack, and the one line that mattered ("wait
49
+ * N seconds") was buried in the middle of it. That reads as a crash, and the
50
+ * natural response to a crash is to run the command again, which is exactly the
51
+ * behaviour that extends the block.
52
+ */
53
+ function reportCliFailure(error, fallback) {
54
+ const rateLimited = error instanceof GarminApiError && error.statusCode === 429 ? error : null;
55
+ if (rateLimited) {
56
+ logger.warn({ retryAfterSeconds: rateLimited.retryAfterSeconds }, fallback);
57
+ console.error("");
58
+ console.error(rateLimited.message);
59
+ console.error("Nothing was lost — every day already fetched is checkpointed.");
60
+ return;
61
+ }
62
+ logger.error({ error }, fallback);
63
+ console.error(error instanceof Error ? error.message : fallback);
64
+ }
65
+ function bootstrap() {
66
+ // stdio transport speaks MCP on stdout — never print there.
67
+ const notify = (message) => {
68
+ process.stderr.write(`${message}\n`);
69
+ };
70
+ try {
71
+ const result = migrateLegacyDataDir();
72
+ if (result.migrated) {
73
+ notify(`Migrated ${result.movedEntries?.length ?? 0} item(s) from ${LEGACY_DATA_DIR_NAME}/ to ${DATA_DIR_NAME}/.`);
74
+ }
75
+ }
76
+ catch (error) {
77
+ notify(`Could not migrate ${LEGACY_DATA_DIR_NAME}/ to ${DATA_DIR_NAME}/: ${error instanceof Error ? error.message : String(error)}`);
78
+ notify(`Move the directory manually, or run "trainbud setup" to start fresh.`);
79
+ }
80
+ const deprecated = deprecatedEnvNames();
81
+ if (deprecated.length > 0) {
82
+ notify(`Deprecated environment variable(s) in use: ${deprecated.join(", ")}. ` +
83
+ `These still work but were renamed to TRAINBUD_*; run "trainbud setup" to rewrite .env.`);
84
+ }
85
+ }
86
+ // SECTION: CLI Commands
87
+ async function runStart() {
88
+ assertGarminCredentials();
89
+ configureLogger(appConfig.logPath);
90
+ // Stdout is the MCP channel from here on, and a dependency's `console.log`
91
+ // lands on it. garmin-connect prints "login page title: ..." on every
92
+ // re-login, which puts two lines of English in the middle of a JSON-RPC
93
+ // stream and drops the client. See utils/stdio.ts.
94
+ protectStdout();
95
+ const server = createMcpServer();
96
+ const shutdown = async (signal) => {
97
+ logger.info({ signal }, "Shutting down TrainBud server");
98
+ await server.close();
99
+ closeCache();
100
+ process.exit(0);
101
+ };
102
+ process.once("SIGTERM", () => {
103
+ void shutdown("SIGTERM");
104
+ });
105
+ process.once("SIGINT", () => {
106
+ void shutdown("SIGINT");
107
+ });
108
+ process.once("exit", () => {
109
+ closeCache();
110
+ });
111
+ await server.start();
112
+ }
113
+ async function runAuth() {
114
+ configureLogger(appConfig.logPath);
115
+ clearStoredSession();
116
+ resetGarminClient();
117
+ await authenticateGarmin(true);
118
+ console.log("Garmin authentication successful. Session saved.");
119
+ }
120
+ function runCacheClear() {
121
+ const cache = getCache();
122
+ const removed = cache.clear();
123
+ console.log(`Cleared ${removed} cache entries.`);
124
+ }
125
+ async function runStatus() {
126
+ const cache = getCache();
127
+ const cacheStats = cache.stats();
128
+ console.log("TrainBud status");
129
+ console.log(`Session: ${sessionExists() ? "present" : "missing"}`);
130
+ console.log(`Cache entries: ${cacheStats.entries}`);
131
+ console.log(`Expired cache entries: ${cacheStats.expiredEntries}`);
132
+ const history = historyStats();
133
+ const span = history.oldestDate && history.newestDate
134
+ ? `${history.oldestDate} to ${history.newestDate}`
135
+ : "empty — run `trainbud backfill`";
136
+ console.log(`History span: ${span}`);
137
+ console.log(`History measurements: ${history.metricRows}`);
138
+ console.log(`History raw payloads: ${history.rawRows}`);
139
+ console.log(`History activities: ${history.activityRows}`);
140
+ if (history.emptyDays > 0) {
141
+ // Almost always days before the watch was bought. Reported so a small span
142
+ // reads as "that is all Garmin has" rather than as a broken backfill.
143
+ console.log(`Days Garmin had no data for: ${history.emptyDays}`);
144
+ }
145
+ closeHistoryDb();
146
+ }
147
+ async function runPrune(retentionDays) {
148
+ const before = historyStats();
149
+ const result = pruneRawPayloads(undefined, retentionDays);
150
+ const after = historyStats();
151
+ console.log("TrainBud prune — raw payload archive only");
152
+ console.log(`Dropped for being older than ${retentionDays} days: ${result.agedOut}`);
153
+ console.log(`Dropped for being past revision ${RAW_REVISIONS_KEPT} of a day: ${result.supersededRevisions}`);
154
+ console.log(`Raw payloads: ${before.rawRows} → ${after.rawRows}`);
155
+ console.log(`Measurements and activities untouched: ${after.metricRows} measurements, ${after.activityRows} activities.`);
156
+ closeHistoryDb();
157
+ }
158
+ async function runFindings() {
159
+ const result = runDetectors();
160
+ if (!result.coverage.ready) {
161
+ // Shared with the MCP tool and the watch prompt. Written here once, this
162
+ // surface printed "74 of the 14 days needed" on a 74-day store for as long
163
+ // as the stale case existed.
164
+ const coverage = describeFindingsCoverage(result.coverage);
165
+ console.log(coverage.detail);
166
+ if (coverage.fix) {
167
+ console.log(coverage.fix);
168
+ }
169
+ closeHistoryDb();
170
+ return;
171
+ }
172
+ console.log(`TrainBud findings — ${result.coverage.days} days of history`);
173
+ console.log("");
174
+ if (result.findings.length === 0) {
175
+ console.log("Nothing stands out against your own baselines.");
176
+ closeHistoryDb();
177
+ return;
178
+ }
179
+ for (const finding of result.findings) {
180
+ console.log(`[${finding.severity}] ${finding.headline}`);
181
+ console.log(` ${finding.detail}`);
182
+ console.log("");
183
+ }
184
+ console.log("General training guidance only. Not medical advice.");
185
+ closeHistoryDb();
186
+ }
187
+ async function runBackfill(options) {
188
+ assertGarminCredentials();
189
+ const sources = options.source?.length
190
+ ? options.source.map((name) => {
191
+ if (!DEFAULT_SOURCES.includes(name)) {
192
+ throw new Error(`Unknown source "${name}". Choose from: ${DEFAULT_SOURCES.join(", ")}`);
193
+ }
194
+ return name;
195
+ })
196
+ : DEFAULT_SOURCES;
197
+ const days = options.days ?? 365;
198
+ const delayMs = options.delayMs ?? 1000;
199
+ console.log(`Backfilling ${days} days from ${sources.length} sources, ${delayMs}ms apart.`);
200
+ console.log("Safe to interrupt — every day is checkpointed and the next run resumes.");
201
+ if (options.capture) {
202
+ console.log(`Capturing redacted responses to ${options.capture} — read them before committing.`);
203
+ }
204
+ console.log("");
205
+ const result = await withGarminClient(async (client) => runIngest(client, {
206
+ days,
207
+ delayMs,
208
+ sources,
209
+ captureDir: options.capture,
210
+ stopAfterEmptyDays: options.earlyStop === false ? 0 : undefined,
211
+ onProgress: (progress) => {
212
+ // One line per day so an hour-long run is legible and a stall is
213
+ // obvious. This is the only feedback the user gets while it walks a
214
+ // year.
215
+ console.log(`[${progress.done}/${progress.total}] ${progress.source} ${progress.date} — ${progress.outcome}`);
216
+ },
217
+ }));
218
+ console.log("");
219
+ console.log(`Done. ${result.fetched} fetched, ${result.errors} failed, ${result.skipped} skipped.`);
220
+ if (result.stoppedBy === "rate_limit") {
221
+ console.log("");
222
+ console.log("Garmin rate limited this run, so it stopped rather than making");
223
+ console.log("hundreds more requests that could not have succeeded. Wait a few");
224
+ console.log("minutes and run it again — every day already fetched is checkpointed.");
225
+ }
226
+ else if (result.errors > 0) {
227
+ console.log("Failed days are retried automatically on the next run.");
228
+ }
229
+ closeHistoryDb();
230
+ }
231
+ async function runCheck() {
232
+ const results = await runLiveCheck();
233
+ printLiveCheckResults(results);
234
+ if (results.some((result) => !result.ok)) {
235
+ process.exitCode = 1;
236
+ }
237
+ }
238
+ async function runServe() {
239
+ assertGarminCredentials();
240
+ assertApiKey();
241
+ const server = createHttpMcpServer();
242
+ // Catch up on start, then hourly while this process lives. Garmin retains
243
+ // the history, so a machine that was off overnight loses nothing -- the gap
244
+ // is simply the next run's work.
245
+ let stopHistory = null;
246
+ const shutdown = async (signal) => {
247
+ logger.info({ signal }, "Shutting down TrainBud HTTP server");
248
+ stopHistory?.();
249
+ closeHistoryDb();
250
+ await server.close();
251
+ process.exit(0);
252
+ };
253
+ process.once("SIGTERM", () => {
254
+ void shutdown("SIGTERM");
255
+ });
256
+ process.once("SIGINT", () => {
257
+ void shutdown("SIGINT");
258
+ });
259
+ await server.start();
260
+ stopHistory = startHistoryScheduler();
261
+ console.log(`TrainBud HTTP MCP server running at http://${appConfig.mcpHost}:${appConfig.mcpPort}/mcp`);
262
+ console.log(`Health check: http://${appConfig.mcpHost}:${appConfig.mcpPort}/health`);
263
+ console.log("");
264
+ console.log(getRemoteConnectorInstructions(`https://your-tunnel-url.example.com`));
265
+ }
266
+ export function createCliProgram() {
267
+ const program = new Command();
268
+ program.hook("preAction", () => {
269
+ bootstrap();
270
+ });
271
+ program
272
+ .name("trainbud")
273
+ .description("TrainBud — MCP server for Garmin Connect fitness data")
274
+ .version(packageVersion);
275
+ program
276
+ .command("start")
277
+ .description("Start the MCP server using stdio transport")
278
+ .action(async () => {
279
+ try {
280
+ await runStart();
281
+ }
282
+ catch (error) {
283
+ logger.error({ error }, "Failed to start MCP server");
284
+ process.exitCode = 1;
285
+ }
286
+ });
287
+ program
288
+ .command("auth")
289
+ .description("Force Garmin re-authentication")
290
+ .action(async () => {
291
+ try {
292
+ await runAuth();
293
+ }
294
+ catch (error) {
295
+ logger.error({ error }, "Garmin authentication failed");
296
+ console.error(error instanceof Error ? error.message : "Authentication failed");
297
+ process.exitCode = 1;
298
+ }
299
+ });
300
+ const cacheCommand = program.command("cache").description("Manage local cache");
301
+ cacheCommand
302
+ .command("clear")
303
+ .description("Clear all cached Garmin data")
304
+ .action(() => {
305
+ try {
306
+ runCacheClear();
307
+ }
308
+ catch (error) {
309
+ logger.error({ error }, "Failed to clear cache");
310
+ process.exitCode = 1;
311
+ }
312
+ });
313
+ program
314
+ .command("serve")
315
+ .description("Start remote MCP server (Streamable HTTP) for web AI connectors")
316
+ .option("-p, --port <number>", "HTTP port", positiveIntOption("--port"))
317
+ .option("-H, --host <host>", "Bind host")
318
+ .action(async (options) => {
319
+ try {
320
+ if (options.port) {
321
+ process.env.TRAINBUD_PORT = String(options.port);
322
+ }
323
+ if (options.host) {
324
+ process.env.TRAINBUD_HOST = options.host;
325
+ }
326
+ await runServe();
327
+ }
328
+ catch (error) {
329
+ logger.error({ error }, "Failed to start HTTP MCP server");
330
+ console.error(error instanceof Error ? error.message : "Failed to start HTTP MCP server");
331
+ process.exitCode = 1;
332
+ }
333
+ });
334
+ program
335
+ .command("backfill")
336
+ .description("Fetch Garmin history into the local store — resumable, safe to interrupt")
337
+ .option("-d, --days <number>", "How many days back to fetch", positiveIntOption("--days"))
338
+ .option("--delay-ms <number>", "Delay between requests", positiveIntOption("--delay-ms", 0))
339
+ .option("-s, --source <name>", "Limit to one source (repeatable)", (value, previous = []) => [...previous, value])
340
+ .option("--capture <dir>", "Also write each redacted response there, as a test fixture")
341
+ .option("--no-early-stop", "Keep asking past a long run of empty days instead of assuming the record has run out")
342
+ .action(async (options) => {
343
+ try {
344
+ await runBackfill(options);
345
+ }
346
+ catch (error) {
347
+ reportCliFailure(error, "Backfill failed");
348
+ process.exitCode = 1;
349
+ }
350
+ });
351
+ program
352
+ .command("findings")
353
+ .description("Show what stands out in your history, against your own baselines")
354
+ .action(async () => {
355
+ try {
356
+ await runFindings();
357
+ }
358
+ catch (error) {
359
+ logger.error({ error }, "Failed to compute findings");
360
+ console.error(error instanceof Error ? error.message : "Failed to compute findings");
361
+ process.exitCode = 1;
362
+ }
363
+ });
364
+ program
365
+ .command("setup")
366
+ .description("Interactive first-time setup — credentials, auth, and MCP client config")
367
+ .action(async () => {
368
+ try {
369
+ await runSetup();
370
+ }
371
+ catch (error) {
372
+ logger.error({ error }, "Setup failed");
373
+ console.error(error instanceof Error ? error.message : "Setup failed");
374
+ process.exitCode = 1;
375
+ }
376
+ });
377
+ program
378
+ .command("check")
379
+ .description("Run live diagnostics against all TrainBud tools")
380
+ .action(async () => {
381
+ try {
382
+ await runCheck();
383
+ }
384
+ catch (error) {
385
+ reportCliFailure(error, "Live check failed");
386
+ process.exitCode = 1;
387
+ }
388
+ });
389
+ // Separate from `check`, which exercises the Garmin tools. This asks the one
390
+ // question `check` cannot: what would the watch see if it called right now.
391
+ // The -400 report took days partly because every diagnostic ran on this
392
+ // machine, where everything was genuinely healthy; the broken hop was the one
393
+ // nothing looked at from the outside.
394
+ program
395
+ .command("doctor")
396
+ .description("Check what the watch would see: public URL, AI key, history depth")
397
+ .action(async () => {
398
+ try {
399
+ const { runSelfTest } = await import("./selfTest.js");
400
+ const result = await runSelfTest();
401
+ console.log("");
402
+ console.log("TrainBud doctor");
403
+ console.log("");
404
+ for (const check of result.checks) {
405
+ const mark = check.ok ? "✓" : check.warning ? "!" : "✗";
406
+ console.log(` ${mark} ${check.name}`);
407
+ console.log(` ${check.detail}`);
408
+ if (check.fix) {
409
+ console.log(` → ${check.fix}`);
410
+ }
411
+ console.log("");
412
+ }
413
+ if (!result.ok) {
414
+ process.exitCode = 1;
415
+ }
416
+ }
417
+ catch (error) {
418
+ logger.error({ error }, "Doctor failed");
419
+ console.error(error instanceof Error ? error.message : "Doctor failed");
420
+ process.exitCode = 1;
421
+ }
422
+ });
423
+ program
424
+ .command("prune")
425
+ .description("Bound the raw payload archive. Never touches measurements or activities.")
426
+ .option("--days <number>", `Drop raw payloads older than this many days (default ${RAW_RETENTION_DAYS})`, String(RAW_RETENTION_DAYS))
427
+ .action(async (options) => {
428
+ try {
429
+ const days = Number(options.days);
430
+ if (!Number.isFinite(days) || days < 1) {
431
+ console.error(`--days must be a positive number, got "${options.days}".`);
432
+ process.exitCode = 1;
433
+ return;
434
+ }
435
+ await runPrune(Math.floor(days));
436
+ }
437
+ catch (error) {
438
+ logger.error({ error }, "Prune failed");
439
+ console.error(error instanceof Error ? error.message : "Prune failed");
440
+ process.exitCode = 1;
441
+ }
442
+ });
443
+ program
444
+ .command("status")
445
+ .description("Show session and cache status")
446
+ .action(async () => {
447
+ try {
448
+ await runStatus();
449
+ }
450
+ catch (error) {
451
+ logger.error({ error }, "Failed to read status");
452
+ process.exitCode = 1;
453
+ }
454
+ });
455
+ return program;
456
+ }
457
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ import { getProjectRoot } from "./paths.js";
2
+ /** Legacy env var names still present in the environment, for a one-time warning. */
3
+ export declare function deprecatedEnvNames(): string[];
4
+ export declare function getSessionPath(): string;
5
+ export { getProjectRoot };
6
+ export declare function getEnvFilePath(): string;
7
+ export declare function getDistIndexPath(): string;
8
+ export declare function generateApiKey(): string;
9
+ /**
10
+ * Quote a value so dotenv reads back exactly what was written.
11
+ *
12
+ * Values were written bare, and dotenv treats an unquoted `#` as the start of a
13
+ * comment: a Garmin password containing one was silently truncated at that
14
+ * character, so setup "succeeded" and every login afterwards failed with bad
15
+ * credentials the user could see were correct. Measured, not assumed --
16
+ * `P=pa#ss` parses back as `pa`.
17
+ *
18
+ * Single quotes are preferred: dotenv does no unescaping inside them, so `#`,
19
+ * `"`, `$`, spaces and backslashes all survive verbatim. Double quotes are the
20
+ * fallback for a value containing a single quote. A value containing both
21
+ * cannot be represented -- dotenv has no escape that works inside either kind --
22
+ * so that is an error rather than a silent corruption.
23
+ */
24
+ export declare function quoteEnvValue(value: string): string;
25
+ /**
26
+ * Every assignment in an existing .env that this file does not manage.
27
+ *
28
+ * writeEnvFile rebuilt the file from a fixed template, so re-running
29
+ * `trainbud setup` deleted ANTHROPIC_API_KEY and TRAINBUD_PUBLIC_URL outright --
30
+ * a user who had followed the AI setup guide lost their key by running the
31
+ * command the guide tells them to run when something is wrong.
32
+ */
33
+ export declare function carriedEnvLines(existing: string): string[];
34
+ export declare function writeEnvFile(credentials: {
35
+ email: string;
36
+ password: string;
37
+ apiKey?: string;
38
+ }): string;
39
+ export declare const appConfig: {
40
+ readonly garminEmail: string;
41
+ readonly garminPassword: string;
42
+ readonly sessionPath: string;
43
+ readonly logPath: string;
44
+ readonly cachePath: string;
45
+ readonly cacheTtlActivities: number;
46
+ readonly cacheTtlSleep: number;
47
+ readonly cacheTtlStats: number;
48
+ readonly mcpHost: string;
49
+ readonly mcpPort: number;
50
+ readonly mcpApiKey: string;
51
+ readonly anthropicApiKey: string;
52
+ readonly publicUrl: string;
53
+ };
54
+ /**
55
+ * Why the watch setup file could not be read, when it exists but is unusable.
56
+ * `null` when it parsed, or when there is simply no file.
57
+ */
58
+ export declare function watchSetupReadError(): string | null;
59
+ export declare function assertApiKey(): void;
60
+ export declare function assertGarminCredentials(): void;
61
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAKA,OAAO,EAGL,cAAc,EAGf,MAAM,YAAY,CAAC;AAmCpB,qFAAqF;AACrF,wBAAgB,kBAAkB,IAAI,MAAM,EAAE,CAI7C;AAWD,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,OAAO,EAAE,cAAc,EAAE,CAAC;AAE1B,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAUnD;AA0BD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAW1D;AAED,wBAAgB,YAAY,CAAC,WAAW,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAwCtG;AAID,eAAO,MAAM,SAAS;0BACD,MAAM;6BAGH,MAAM;0BAGT,MAAM;sBAGV,MAAM;wBAGJ,MAAM;iCAGG,MAAM;4BAGX,MAAM;4BAGN,MAAM;sBAGZ,MAAM;sBAGN,MAAM;wBAGJ,MAAM;8BAGA,MAAM;wBAGZ,MAAM;CAkBxB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,GAAG,IAAI,CAEnD;AAED,wBAAgB,YAAY,IAAI,IAAI,CAMnC;AAED,wBAAgB,uBAAuB,IAAI,IAAI,CAM9C"}