@milldr/crono 0.4.1 → 0.7.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/README.md +115 -13
- package/dist/automation/client.d.ts +5 -0
- package/dist/automation/client.d.ts.map +1 -0
- package/dist/automation/client.js +13 -0
- package/dist/automation/client.js.map +1 -0
- package/dist/automation/runner.d.ts +3 -0
- package/dist/automation/runner.d.ts.map +1 -0
- package/dist/automation/runner.js +150 -0
- package/dist/automation/runner.js.map +1 -0
- package/dist/automation/types.d.ts +75 -0
- package/dist/automation/types.d.ts.map +1 -0
- package/dist/automation/types.js +2 -0
- package/dist/automation/types.js.map +1 -0
- package/dist/commands/add.js +3 -3
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/biometrics.d.ts +10 -0
- package/dist/commands/biometrics.d.ts.map +1 -0
- package/dist/commands/biometrics.js +81 -0
- package/dist/commands/biometrics.js.map +1 -0
- package/dist/commands/diary.d.ts +1 -1
- package/dist/commands/diary.d.ts.map +1 -1
- package/dist/commands/diary.js +3 -3
- package/dist/commands/diary.js.map +1 -1
- package/dist/commands/export.d.ts +1 -0
- package/dist/commands/export.d.ts.map +1 -1
- package/dist/commands/export.js +45 -3
- package/dist/commands/export.js.map +1 -1
- package/dist/commands/log.js +3 -3
- package/dist/commands/log.js.map +1 -1
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +53 -26
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/quick-add.js +3 -3
- package/dist/commands/quick-add.js.map +1 -1
- package/dist/commands/recipes.d.ts +5 -0
- package/dist/commands/recipes.d.ts.map +1 -0
- package/dist/commands/recipes.js +35 -0
- package/dist/commands/recipes.js.map +1 -0
- package/dist/commands/weight.d.ts.map +1 -1
- package/dist/commands/weight.js +3 -3
- package/dist/commands/weight.js.map +1 -1
- package/dist/config.d.ts +6 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +6 -0
- package/dist/config.js.map +1 -1
- package/dist/cronometer/export.d.ts +1 -1
- package/dist/cronometer/export.d.ts.map +1 -1
- package/dist/cronometer/export.js +1 -0
- package/dist/cronometer/export.js.map +1 -1
- package/dist/cronometer/parse.d.ts +14 -0
- package/dist/cronometer/parse.d.ts.map +1 -1
- package/dist/cronometer/parse.js +62 -0
- package/dist/cronometer/parse.js.map +1 -1
- package/dist/index.js +23 -1
- package/dist/index.js.map +1 -1
- package/dist/kernel/add-custom-food.d.ts.map +1 -1
- package/dist/kernel/add-custom-food.js +6 -138
- package/dist/kernel/add-custom-food.js.map +1 -1
- package/dist/kernel/biometrics.d.ts +20 -0
- package/dist/kernel/biometrics.d.ts.map +1 -0
- package/dist/kernel/biometrics.js +171 -0
- package/dist/kernel/biometrics.js.map +1 -0
- package/dist/kernel/client.d.ts +4 -56
- package/dist/kernel/client.d.ts.map +1 -1
- package/dist/kernel/client.js +29 -274
- package/dist/kernel/client.js.map +1 -1
- package/dist/kernel/food-dialog.d.ts +13 -0
- package/dist/kernel/food-dialog.d.ts.map +1 -0
- package/dist/kernel/food-dialog.js +294 -0
- package/dist/kernel/food-dialog.js.map +1 -0
- package/dist/kernel/log-food.d.ts.map +1 -1
- package/dist/kernel/log-food.js +2 -186
- package/dist/kernel/log-food.js.map +1 -1
- package/dist/kernel/login.d.ts +1 -1
- package/dist/kernel/login.d.ts.map +1 -1
- package/dist/kernel/login.js +34 -4
- package/dist/kernel/login.js.map +1 -1
- package/dist/kernel/quick-add.d.ts.map +1 -1
- package/dist/kernel/quick-add.js +9 -195
- package/dist/kernel/quick-add.js.map +1 -1
- package/dist/kernel/recipes.d.ts +10 -0
- package/dist/kernel/recipes.d.ts.map +1 -0
- package/dist/kernel/recipes.js +38 -0
- package/dist/kernel/recipes.js.map +1 -0
- package/dist/playwright/client.d.ts +6 -0
- package/dist/playwright/client.d.ts.map +1 -0
- package/dist/playwright/client.js +41 -0
- package/dist/playwright/client.js.map +1 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -283,6 +283,77 @@ crono diary -r 7d --json
|
|
|
283
283
|
# → [{"date":"2026-02-11","calories":1847,"protein":168,"carbs":142,"fat":58}, ...]
|
|
284
284
|
```
|
|
285
285
|
|
|
286
|
+
### `crono biometrics`
|
|
287
|
+
|
|
288
|
+
Log biometrics to Cronometer (weight, body fat percentage, blood pressure). Defaults to today if no date is specified.
|
|
289
|
+
|
|
290
|
+
```bash
|
|
291
|
+
crono biometrics [options]
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
**Options:**
|
|
295
|
+
|
|
296
|
+
| Flag | Long | Description |
|
|
297
|
+
| ---- | --------------------- | ------------------------------------ |
|
|
298
|
+
| `-w` | `--weight <value>` | Weight value |
|
|
299
|
+
| `-b` | `--body-fat <value>` | Body fat percentage |
|
|
300
|
+
| `-s` | `--systolic <value>` | Systolic blood pressure (mmHg) |
|
|
301
|
+
| `-d` | `--diastolic <value>` | Diastolic blood pressure (mmHg) |
|
|
302
|
+
| | `--date <date>` | Date (YYYY-MM-DD, yesterday, -1d) |
|
|
303
|
+
| `-u` | `--unit <unit>` | Weight unit (kg or lbs), default: kg |
|
|
304
|
+
|
|
305
|
+
At least one biometric value is required. Blood pressure requires both systolic and diastolic values.
|
|
306
|
+
|
|
307
|
+
**Examples:**
|
|
308
|
+
|
|
309
|
+
```bash
|
|
310
|
+
# Log weight in kg (default)
|
|
311
|
+
crono biometrics --weight 90
|
|
312
|
+
|
|
313
|
+
# Log weight in lbs
|
|
314
|
+
crono biometrics --weight 198 --unit lbs
|
|
315
|
+
|
|
316
|
+
# Log body fat percentage
|
|
317
|
+
crono biometrics --body-fat 19
|
|
318
|
+
|
|
319
|
+
# Log blood pressure
|
|
320
|
+
crono biometrics --systolic 130 --diastolic 76
|
|
321
|
+
|
|
322
|
+
# Log weight for yesterday
|
|
323
|
+
crono biometrics --weight 90 --date yesterday
|
|
324
|
+
|
|
325
|
+
# Log multiple biometrics (requires multiple commands)
|
|
326
|
+
crono biometrics --weight 90
|
|
327
|
+
crono biometrics --body-fat 19
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### `crono recipes`
|
|
331
|
+
|
|
332
|
+
List your custom recipes from Cronometer.
|
|
333
|
+
|
|
334
|
+
```bash
|
|
335
|
+
crono recipes [options]
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
**Options:**
|
|
339
|
+
|
|
340
|
+
| Flag | Long | Description |
|
|
341
|
+
| ---- | -------- | -------------- |
|
|
342
|
+
| | `--json` | Output as JSON |
|
|
343
|
+
|
|
344
|
+
**Examples:**
|
|
345
|
+
|
|
346
|
+
```bash
|
|
347
|
+
# List all custom recipes
|
|
348
|
+
crono recipes
|
|
349
|
+
# → Chicken Stir Fry
|
|
350
|
+
# → Overnight Oats
|
|
351
|
+
# → 2 recipes
|
|
352
|
+
|
|
353
|
+
# JSON output for scripting
|
|
354
|
+
crono recipes --json
|
|
355
|
+
```
|
|
356
|
+
|
|
286
357
|
### `crono export`
|
|
287
358
|
|
|
288
359
|
Export data directly from Cronometer's API — no browser automation, much faster than `diary` or `weight`.
|
|
@@ -293,33 +364,47 @@ crono export <type> [options]
|
|
|
293
364
|
|
|
294
365
|
**Types:**
|
|
295
366
|
|
|
296
|
-
| Type | Description
|
|
297
|
-
| ------------ |
|
|
298
|
-
| `nutrition` | Daily
|
|
299
|
-
| `
|
|
300
|
-
| `
|
|
367
|
+
| Type | Granularity | Description |
|
|
368
|
+
| ------------ | ------------------ | --------------------------------------------------------------------------------------------- |
|
|
369
|
+
| `nutrition` | Daily totals | Aggregated calories + 60+ nutrient columns (vitamins, minerals, amino acids, omega 3/6, etc.) |
|
|
370
|
+
| `servings` | Per food entry | Time, meal, food name, amount, full nutrient breakdown — answers "what did I have for dinner" |
|
|
371
|
+
| `exercises` | Per exercise entry | Time, exercise name, duration, calories burned, group |
|
|
372
|
+
| `biometrics` | Per measurement | Weight, BP, plus anything Apple Health pushes in (heart rate, HRV, sleep) |
|
|
301
373
|
|
|
302
374
|
**Options:**
|
|
303
375
|
|
|
304
|
-
| Flag | Long | Description
|
|
305
|
-
| ---- | ----------------- |
|
|
306
|
-
| `-d` | `--date <date>` | Date (YYYY-MM-DD)
|
|
307
|
-
| `-r` | `--range <range>` | Range (7d, 30d, or YYYY-MM-DD:YYYY-MM-DD)
|
|
308
|
-
|
|
|
309
|
-
| | `--
|
|
376
|
+
| Flag | Long | Description |
|
|
377
|
+
| ---- | ----------------- | ----------------------------------------------------------------------- |
|
|
378
|
+
| `-d` | `--date <date>` | Date (YYYY-MM-DD) |
|
|
379
|
+
| `-r` | `--range <range>` | Range (7d, 30d, or YYYY-MM-DD:YYYY-MM-DD) |
|
|
380
|
+
| `-m` | `--meal <name>` | `servings` only: filter to a meal (Breakfast / Lunch / Dinner / Snacks) |
|
|
381
|
+
| | `--csv` | Output as raw CSV |
|
|
382
|
+
| | `--json` | Output as JSON |
|
|
310
383
|
|
|
311
384
|
`-d` and `-r` are mutually exclusive. `--csv` and `--json` are mutually exclusive.
|
|
312
385
|
|
|
313
386
|
**Examples:**
|
|
314
387
|
|
|
315
388
|
```bash
|
|
316
|
-
# Today's nutrition
|
|
389
|
+
# Today's nutrition (daily totals)
|
|
317
390
|
crono export nutrition
|
|
318
391
|
# → 1847 kcal | P: 168g | C: 142g | F: 58g
|
|
319
392
|
|
|
320
393
|
# Last 7 days of nutrition as JSON
|
|
321
394
|
crono export nutrition -r 7d --json
|
|
322
395
|
|
|
396
|
+
# What did I have for dinner today? (per-food breakdown)
|
|
397
|
+
crono export servings -m Dinner
|
|
398
|
+
# → 7:30 PM | Dinner | Beef Steak | 150g | 306 kcal | P: 46g C: 0g F: 13.5g
|
|
399
|
+
# → ...
|
|
400
|
+
# → Total: 672 kcal | P: 70.1g C: 43.5g F: 34.3g
|
|
401
|
+
|
|
402
|
+
# Yesterday's full food log
|
|
403
|
+
crono export servings -d yesterday
|
|
404
|
+
|
|
405
|
+
# Last 7 days of food entries as JSON (each entry includes all 60+ nutrient columns)
|
|
406
|
+
crono export servings -r 7d --json
|
|
407
|
+
|
|
323
408
|
# Today's exercises
|
|
324
409
|
crono export exercises
|
|
325
410
|
# → Running: 30 min, 350 kcal
|
|
@@ -333,6 +418,23 @@ crono export biometrics -r 30d
|
|
|
333
418
|
crono export nutrition -r 30d --csv
|
|
334
419
|
```
|
|
335
420
|
|
|
421
|
+
**Config:** `crono login` writes backend preference to `~/.config/crono/config.json`. Kernel remains the default; set `useKernel` to `false` to use a local Playwright browser profile instead:
|
|
422
|
+
|
|
423
|
+
```json
|
|
424
|
+
{
|
|
425
|
+
"useKernel": false,
|
|
426
|
+
"playwrightHeadless": true
|
|
427
|
+
}
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
Local Playwright session data is stored in `~/.config/crono/playwright-profile`.
|
|
431
|
+
|
|
432
|
+
When using the local Playwright backend, install the browser binaries once:
|
|
433
|
+
|
|
434
|
+
```bash
|
|
435
|
+
npx playwright install
|
|
436
|
+
```
|
|
437
|
+
|
|
336
438
|
**GWT overrides:** If Cronometer updates break the export, override GWT values in `~/.config/crono/config.json` or via environment variables:
|
|
337
439
|
|
|
338
440
|
```bash
|
|
@@ -343,7 +445,7 @@ export CRONO_GWT_HEADER=<new-value>
|
|
|
343
445
|
## Requirements
|
|
344
446
|
|
|
345
447
|
- Node.js 18+
|
|
346
|
-
- [Kernel.sh](https://kernel.sh) account (for browser automation)
|
|
448
|
+
- [Kernel.sh](https://kernel.sh) account (for Kernel browser automation)
|
|
347
449
|
- [Cronometer](https://cronometer.com) account
|
|
348
450
|
|
|
349
451
|
## Development
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { AutomationClient } from "./types.js";
|
|
2
|
+
export type AutomationBackend = "kernel" | "playwright";
|
|
3
|
+
export declare function getAutomationBackend(): AutomationBackend;
|
|
4
|
+
export declare function getAutomationClient(): Promise<AutomationClient>;
|
|
5
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/automation/client.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,YAAY,CAAC;AAExD,wBAAgB,oBAAoB,IAAI,iBAAiB,CAGxD;AAED,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAIrE"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { loadConfig } from "../config.js";
|
|
2
|
+
import { getKernelClient } from "../kernel/client.js";
|
|
3
|
+
import { getPlaywrightClient } from "../playwright/client.js";
|
|
4
|
+
export function getAutomationBackend() {
|
|
5
|
+
const config = loadConfig();
|
|
6
|
+
return config.useKernel === false ? "playwright" : "kernel";
|
|
7
|
+
}
|
|
8
|
+
export async function getAutomationClient() {
|
|
9
|
+
return getAutomationBackend() === "kernel"
|
|
10
|
+
? getKernelClient()
|
|
11
|
+
: getPlaywrightClient();
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/automation/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAK9D,MAAM,UAAU,oBAAoB;IAClC,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,OAAO,MAAM,CAAC,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC9D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACvC,OAAO,oBAAoB,EAAE,KAAK,QAAQ;QACxC,CAAC,CAAC,eAAe,EAAE;QACnB,CAAC,CAAC,mBAAmB,EAAE,CAAC;AAC5B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/automation/runner.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EACV,gBAAgB,EAEhB,wBAAwB,EASzB,MAAM,YAAY,CAAC;AAEpB,wBAAgB,sBAAsB,CACpC,aAAa,EAAE,wBAAwB,GACtC,gBAAgB,CA4GlB"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import * as p from "@clack/prompts";
|
|
2
|
+
import { getCredential } from "../credentials.js";
|
|
3
|
+
import { buildAddCustomFoodCode } from "../kernel/add-custom-food.js";
|
|
4
|
+
import { buildBiometricsCode } from "../kernel/biometrics.js";
|
|
5
|
+
import { buildDiaryCode } from "../kernel/diary.js";
|
|
6
|
+
import { buildLogFoodCode } from "../kernel/log-food.js";
|
|
7
|
+
import { buildRecipesCode } from "../kernel/recipes.js";
|
|
8
|
+
import { buildAutoLoginCode, buildLoginCheckCode, buildNavigateToLoginCode, } from "../kernel/login.js";
|
|
9
|
+
import { buildQuickAddCode } from "../kernel/quick-add.js";
|
|
10
|
+
import { buildWeightCode } from "../kernel/weight.js";
|
|
11
|
+
export function createAutomationClient(createRuntime) {
|
|
12
|
+
return {
|
|
13
|
+
addQuickEntry: (entry, onStatus) => withLoggedInRuntime(createRuntime, onStatus, async (runtime) => {
|
|
14
|
+
onStatus?.("Adding quick entry...");
|
|
15
|
+
const data = await executeAutomation(runtime, buildQuickAddCode(entry), 60);
|
|
16
|
+
if (!data.success) {
|
|
17
|
+
throw new Error(`Quick add failed: ${data.error ?? "Unknown error"}`);
|
|
18
|
+
}
|
|
19
|
+
}),
|
|
20
|
+
getWeight: (dates, onStatus) => withLoggedInRuntime(createRuntime, onStatus, async (runtime) => {
|
|
21
|
+
onStatus?.("Reading weight data...");
|
|
22
|
+
const data = await executeAutomation(runtime, buildWeightCode(dates), 60);
|
|
23
|
+
if (!data.success) {
|
|
24
|
+
throw new Error(`Weight read failed: ${data.error ?? "Unknown error"}`);
|
|
25
|
+
}
|
|
26
|
+
return data.entries ?? [];
|
|
27
|
+
}),
|
|
28
|
+
getDiary: (dates, onStatus, scrapeTargets) => withLoggedInRuntime(createRuntime, onStatus, async (runtime) => {
|
|
29
|
+
onStatus?.("Reading diary data...");
|
|
30
|
+
const data = await executeAutomation(runtime, buildDiaryCode(dates, scrapeTargets), 60);
|
|
31
|
+
if (!data.success) {
|
|
32
|
+
throw new Error(`Diary read failed: ${data.error ?? "Unknown error"}`);
|
|
33
|
+
}
|
|
34
|
+
return data.entries ?? [];
|
|
35
|
+
}),
|
|
36
|
+
addCustomFood: (entry, onStatus) => withLoggedInRuntime(createRuntime, onStatus, async (runtime) => {
|
|
37
|
+
onStatus?.("Creating custom food...");
|
|
38
|
+
const data = await executeAutomation(runtime, buildAddCustomFoodCode(entry), 120);
|
|
39
|
+
if (!data.success) {
|
|
40
|
+
throw new Error(`Custom food creation failed: ${data.error ?? "Unknown error"}`);
|
|
41
|
+
}
|
|
42
|
+
}),
|
|
43
|
+
logFood: (entry, onStatus) => withLoggedInRuntime(createRuntime, onStatus, async (runtime) => {
|
|
44
|
+
onStatus?.("Logging food to diary...");
|
|
45
|
+
const data = await executeAutomation(runtime, buildLogFoodCode(entry), 60);
|
|
46
|
+
if (!data.success) {
|
|
47
|
+
throw new Error(`Food logging failed: ${data.error ?? "Unknown error"}`);
|
|
48
|
+
}
|
|
49
|
+
}),
|
|
50
|
+
getRecipes: (onStatus) => withLoggedInRuntime(createRuntime, onStatus, async (runtime) => {
|
|
51
|
+
onStatus?.("Reading custom recipes...");
|
|
52
|
+
const data = await executeAutomation(runtime, buildRecipesCode(), 30);
|
|
53
|
+
if (!data.success) {
|
|
54
|
+
throw new Error(`Recipes read failed: ${data.error ?? "Unknown error"}`);
|
|
55
|
+
}
|
|
56
|
+
return data.recipes ?? [];
|
|
57
|
+
}),
|
|
58
|
+
logBiometric: (entry, onStatus) => withLoggedInRuntime(createRuntime, onStatus, async (runtime) => {
|
|
59
|
+
const typeLabel = entry.type === "weight"
|
|
60
|
+
? "weight"
|
|
61
|
+
: entry.type === "bodyfat"
|
|
62
|
+
? "body fat"
|
|
63
|
+
: "blood pressure";
|
|
64
|
+
onStatus?.(`Logging ${typeLabel}...`);
|
|
65
|
+
const data = await executeAutomation(runtime, buildBiometricsCode(entry), 60);
|
|
66
|
+
if (!data.success) {
|
|
67
|
+
throw new Error(`Biometric logging failed: ${data.error ?? "Unknown error"}`);
|
|
68
|
+
}
|
|
69
|
+
}),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
async function withLoggedInRuntime(createRuntime, onStatus, run) {
|
|
73
|
+
const username = getCredential("cronometer-username");
|
|
74
|
+
const password = getCredential("cronometer-password");
|
|
75
|
+
const hasAutoCredentials = !!(username && password);
|
|
76
|
+
const runtime = await createRuntime(hasAutoCredentials);
|
|
77
|
+
try {
|
|
78
|
+
await ensureLoggedIn(runtime, username, password, onStatus);
|
|
79
|
+
return await run(runtime);
|
|
80
|
+
}
|
|
81
|
+
finally {
|
|
82
|
+
await runtime.close();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
async function ensureLoggedIn(runtime, username, password, onStatus) {
|
|
86
|
+
onStatus?.("Checking Cronometer session...");
|
|
87
|
+
const data = await executeAutomation(runtime, buildLoginCheckCode(), 30);
|
|
88
|
+
if (data.loggedIn) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (username && password) {
|
|
92
|
+
await autoLogin(runtime, username, password, onStatus);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
await manualLogin(runtime);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
async function autoLogin(runtime, username, password, onStatus) {
|
|
99
|
+
onStatus?.("Logging into Cronometer...");
|
|
100
|
+
const data = await executeAutomation(runtime, buildAutoLoginCode(username, password), 60);
|
|
101
|
+
if (!data.loggedIn) {
|
|
102
|
+
const pageError = data.loginError?.toLowerCase() ?? "";
|
|
103
|
+
const isRateLimited = pageError.includes("too many") ||
|
|
104
|
+
pageError.includes("rate limit") ||
|
|
105
|
+
pageError.includes("try again later") ||
|
|
106
|
+
pageError.includes("temporarily");
|
|
107
|
+
if (isRateLimited) {
|
|
108
|
+
throw new Error(`Cronometer is rate-limiting login attempts. ${data.loginError}\n` +
|
|
109
|
+
"Please wait a few minutes and try again.");
|
|
110
|
+
}
|
|
111
|
+
throw new Error(`Auto-login failed: ${data.error ?? data.loginError ?? "Login verification failed"}.\n` +
|
|
112
|
+
"Your credentials may be incorrect. Run `crono login` to update them.");
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
async function manualLogin(runtime) {
|
|
116
|
+
p.log.warn("No stored Cronometer credentials found.");
|
|
117
|
+
p.log.info("Tip: run `crono login` to save credentials for automatic login.");
|
|
118
|
+
if (runtime.liveViewUrl) {
|
|
119
|
+
p.note(runtime.liveViewUrl, "Browser Live View");
|
|
120
|
+
}
|
|
121
|
+
await executeAutomation(runtime, buildNavigateToLoginCode(), 30);
|
|
122
|
+
p.log.info("Please log into Cronometer in the browser above.");
|
|
123
|
+
const confirmation = await p.text({
|
|
124
|
+
message: "Press Enter once you've logged in...",
|
|
125
|
+
defaultValue: "",
|
|
126
|
+
});
|
|
127
|
+
if (p.isCancel(confirmation)) {
|
|
128
|
+
throw new Error("Login cancelled by user.");
|
|
129
|
+
}
|
|
130
|
+
const data = await executeAutomation(runtime, buildLoginCheckCode(), 30);
|
|
131
|
+
if (!data.loggedIn) {
|
|
132
|
+
throw new Error("Login verification failed. Make sure you're fully logged in and try again.");
|
|
133
|
+
}
|
|
134
|
+
p.log.step("Logged in.");
|
|
135
|
+
}
|
|
136
|
+
async function executeAutomation(runtime, code, timeoutSec) {
|
|
137
|
+
const response = await runtime.execute(code, timeoutSec);
|
|
138
|
+
return unwrapExecutionResult(response, "Automation");
|
|
139
|
+
}
|
|
140
|
+
function unwrapExecutionResult(response, action) {
|
|
141
|
+
if (!response.success) {
|
|
142
|
+
const details = response.error ?? response.stderr ?? "Unknown error";
|
|
143
|
+
throw new Error(`${action} failed: ${details}`);
|
|
144
|
+
}
|
|
145
|
+
if (response.result === undefined || response.result === null) {
|
|
146
|
+
throw new Error(`${action} failed: no result returned`);
|
|
147
|
+
}
|
|
148
|
+
return response.result;
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/automation/runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAetD,MAAM,UAAU,sBAAsB,CACpC,aAAuC;IAEvC,OAAO;QACL,aAAa,EAAE,CAAC,KAAiB,EAAE,QAAgC,EAAE,EAAE,CACrE,mBAAmB,CAAC,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YAC7D,QAAQ,EAAE,CAAC,uBAAuB,CAAC,CAAC;YACpC,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAGjC,OAAO,EAAE,iBAAiB,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;YAC1C,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gBAClB,MAAM,IAAI,KAAK,CAAC,qBAAqB,IAAI,CAAC,KAAK,IAAI,eAAe,EAAE,CAAC,CAAC;YACxE,CAAC;QACH,CAAC,CAAC;QACJ,SAAS,EAAE,CAAC,KAAe,EAAE,QAAgC,EAAE,EAAE,CAC/D,mBAAmB,CAAC,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YAC7D,QAAQ,EAAE,CAAC,wBAAwB,CAAC,CAAC;YACrC,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAIjC,OAAO,EAAE,eAAe,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;YACxC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gBAClB,MAAM,IAAI,KAAK,CACb,uBAAuB,IAAI,CAAC,KAAK,IAAI,eAAe,EAAE,CACvD,CAAC;YACJ,CAAC;YACD,OAAO,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;QAC5B,CAAC,CAAC;QACJ,QAAQ,EAAE,CACR,KAAe,EACf,QAAgC,EAChC,aAAuB,EACvB,EAAE,CACF,mBAAmB,CAAC,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YAC7D,QAAQ,EAAE,CAAC,uBAAuB,CAAC,CAAC;YACpC,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAIjC,OAAO,EAAE,cAAc,CAAC,KAAK,EAAE,aAAa,CAAC,EAAE,EAAE,CAAC,CAAC;YACtD,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gBAClB,MAAM,IAAI,KAAK,CACb,sBAAsB,IAAI,CAAC,KAAK,IAAI,eAAe,EAAE,CACtD,CAAC;YACJ,CAAC;YACD,OAAO,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;QAC5B,CAAC,CAAC;QACJ,aAAa,EAAE,CAAC,KAAsB,EAAE,QAAgC,EAAE,EAAE,CAC1E,mBAAmB,CAAC,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YAC7D,QAAQ,EAAE,CAAC,yBAAyB,CAAC,CAAC;YACtC,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAGjC,OAAO,EAAE,sBAAsB,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC;YAChD,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gBAClB,MAAM,IAAI,KAAK,CACb,gCAAgC,IAAI,CAAC,KAAK,IAAI,eAAe,EAAE,CAChE,CAAC;YACJ,CAAC;QACH,CAAC,CAAC;QACJ,OAAO,EAAE,CAAC,KAAmB,EAAE,QAAgC,EAAE,EAAE,CACjE,mBAAmB,CAAC,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YAC7D,QAAQ,EAAE,CAAC,0BAA0B,CAAC,CAAC;YACvC,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAGjC,OAAO,EAAE,gBAAgB,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;YACzC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gBAClB,MAAM,IAAI,KAAK,CACb,wBAAwB,IAAI,CAAC,KAAK,IAAI,eAAe,EAAE,CACxD,CAAC;YACJ,CAAC;QACH,CAAC,CAAC;QACJ,UAAU,EAAE,CAAC,QAAgC,EAAE,EAAE,CAC/C,mBAAmB,CAAC,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YAC7D,QAAQ,EAAE,CAAC,2BAA2B,CAAC,CAAC;YACxC,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAIjC,OAAO,EAAE,gBAAgB,EAAE,EAAE,EAAE,CAAC,CAAC;YACpC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gBAClB,MAAM,IAAI,KAAK,CACb,wBAAwB,IAAI,CAAC,KAAK,IAAI,eAAe,EAAE,CACxD,CAAC;YACJ,CAAC;YACD,OAAO,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;QAC5B,CAAC,CAAC;QACJ,YAAY,EAAE,CAAC,KAAqB,EAAE,QAAgC,EAAE,EAAE,CACxE,mBAAmB,CAAC,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YAC7D,MAAM,SAAS,GACb,KAAK,CAAC,IAAI,KAAK,QAAQ;gBACrB,CAAC,CAAC,QAAQ;gBACV,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS;oBACxB,CAAC,CAAC,UAAU;oBACZ,CAAC,CAAC,gBAAgB,CAAC;YACzB,QAAQ,EAAE,CAAC,WAAW,SAAS,KAAK,CAAC,CAAC;YACtC,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAGjC,OAAO,EAAE,mBAAmB,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;YAC5C,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gBAClB,MAAM,IAAI,KAAK,CACb,6BAA6B,IAAI,CAAC,KAAK,IAAI,eAAe,EAAE,CAC7D,CAAC;YACJ,CAAC;QACH,CAAC,CAAC;KACL,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,mBAAmB,CAChC,aAAuC,EACvC,QAA6C,EAC7C,GAA+C;IAE/C,MAAM,QAAQ,GAAG,aAAa,CAAC,qBAAqB,CAAC,CAAC;IACtD,MAAM,QAAQ,GAAG,aAAa,CAAC,qBAAqB,CAAC,CAAC;IACtD,MAAM,kBAAkB,GAAG,CAAC,CAAC,CAAC,QAAQ,IAAI,QAAQ,CAAC,CAAC;IACpD,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,kBAAkB,CAAC,CAAC;IAExD,IAAI,CAAC;QACH,MAAM,cAAc,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAE5D,OAAO,MAAM,GAAG,CAAC,OAAO,CAAC,CAAC;IAC5B,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,cAAc,CAC3B,OAA0B,EAC1B,QAAuB,EACvB,QAAuB,EACvB,QAAgC;IAEhC,QAAQ,EAAE,CAAC,gCAAgC,CAAC,CAAC;IAE7C,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAIjC,OAAO,EAAE,mBAAmB,EAAE,EAAE,EAAE,CAAC,CAAC;IAEvC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClB,OAAO;IACT,CAAC;IAED,IAAI,QAAQ,IAAI,QAAQ,EAAE,CAAC;QACzB,MAAM,SAAS,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACzD,CAAC;SAAM,CAAC;QACN,MAAM,WAAW,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;AACH,CAAC;AAED,KAAK,UAAU,SAAS,CACtB,OAA0B,EAC1B,QAAgB,EAChB,QAAgB,EAChB,QAAgC;IAEhC,QAAQ,EAAE,CAAC,4BAA4B,CAAC,CAAC;IAEzC,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAMjC,OAAO,EAAE,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC;IAExD,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACnB,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;QACvD,MAAM,aAAa,GACjB,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC;YAC9B,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC;YAChC,SAAS,CAAC,QAAQ,CAAC,iBAAiB,CAAC;YACrC,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;QAEpC,IAAI,aAAa,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CACb,+CAA+C,IAAI,CAAC,UAAU,IAAI;gBAChE,0CAA0C,CAC7C,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,KAAK,CACb,sBAAsB,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,UAAU,IAAI,2BAA2B,KAAK;YACrF,sEAAsE,CACzE,CAAC;IACJ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,OAA0B;IACnD,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC;IACtD,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,iEAAiE,CAAC,CAAC;IAE9E,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;QACxB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,mBAAmB,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,EAAE,EAAE,EAAE,CAAC,CAAC;IACjE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAC;IAE/D,MAAM,YAAY,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC;QAChC,OAAO,EAAE,sCAAsC;QAC/C,YAAY,EAAE,EAAE;KACjB,CAAC,CAAC;IAEH,IAAI,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC9C,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAIjC,OAAO,EAAE,mBAAmB,EAAE,EAAE,EAAE,CAAC,CAAC;IAEvC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CACb,4EAA4E,CAC7E,CAAC;IACJ,CAAC;IAED,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;AAC3B,CAAC;AAED,KAAK,UAAU,iBAAiB,CAC9B,OAA0B,EAC1B,IAAY,EACZ,UAAkB;IAElB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,OAAO,CAAI,IAAI,EAAE,UAAU,CAAC,CAAC;IAC5D,OAAO,qBAAqB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;AACvD,CAAC;AAED,SAAS,qBAAqB,CAC5B,QAAwC,EACxC,MAAc;IAEd,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,IAAI,QAAQ,CAAC,MAAM,IAAI,eAAe,CAAC;QACrE,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,YAAY,OAAO,EAAE,CAAC,CAAC;IAClD,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;QAC9D,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,6BAA6B,CAAC,CAAC;IAC1D,CAAC;IAED,OAAO,QAAQ,CAAC,MAAM,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
export interface MacroEntry {
|
|
2
|
+
protein?: number;
|
|
3
|
+
carbs?: number;
|
|
4
|
+
fat?: number;
|
|
5
|
+
alcohol?: number;
|
|
6
|
+
meal?: string;
|
|
7
|
+
date?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface WeightData {
|
|
10
|
+
date: string;
|
|
11
|
+
weight: number | null;
|
|
12
|
+
unit: string;
|
|
13
|
+
}
|
|
14
|
+
export interface DiaryData {
|
|
15
|
+
date: string;
|
|
16
|
+
calories: number;
|
|
17
|
+
protein: number;
|
|
18
|
+
carbs: number;
|
|
19
|
+
fat: number;
|
|
20
|
+
targets?: {
|
|
21
|
+
calories: number | null;
|
|
22
|
+
protein: number | null;
|
|
23
|
+
carbs: number | null;
|
|
24
|
+
fat: number | null;
|
|
25
|
+
} | null;
|
|
26
|
+
exercise?: {
|
|
27
|
+
caloriesBurned: number;
|
|
28
|
+
} | null;
|
|
29
|
+
}
|
|
30
|
+
export interface CustomFoodEntry {
|
|
31
|
+
name: string;
|
|
32
|
+
protein?: number;
|
|
33
|
+
carbs?: number;
|
|
34
|
+
fat?: number;
|
|
35
|
+
calories?: number;
|
|
36
|
+
log?: string | boolean;
|
|
37
|
+
}
|
|
38
|
+
export interface LogFoodEntry {
|
|
39
|
+
name: string;
|
|
40
|
+
meal?: string;
|
|
41
|
+
servings?: number;
|
|
42
|
+
}
|
|
43
|
+
export interface RecipeData {
|
|
44
|
+
name: string;
|
|
45
|
+
}
|
|
46
|
+
export interface BiometricEntry {
|
|
47
|
+
type: "weight" | "bodyfat" | "bloodpressure";
|
|
48
|
+
value?: number;
|
|
49
|
+
unit?: string;
|
|
50
|
+
systolic?: number;
|
|
51
|
+
diastolic?: number;
|
|
52
|
+
date: string;
|
|
53
|
+
}
|
|
54
|
+
export interface AutomationClient {
|
|
55
|
+
addQuickEntry(entry: MacroEntry, onStatus?: (msg: string) => void): Promise<void>;
|
|
56
|
+
getWeight(dates: string[], onStatus?: (msg: string) => void): Promise<WeightData[]>;
|
|
57
|
+
getDiary(dates: string[], onStatus?: (msg: string) => void, scrapeTargets?: boolean): Promise<DiaryData[]>;
|
|
58
|
+
addCustomFood(entry: CustomFoodEntry, onStatus?: (msg: string) => void): Promise<void>;
|
|
59
|
+
logFood(entry: LogFoodEntry, onStatus?: (msg: string) => void): Promise<void>;
|
|
60
|
+
getRecipes(onStatus?: (msg: string) => void): Promise<RecipeData[]>;
|
|
61
|
+
logBiometric(entry: BiometricEntry, onStatus?: (msg: string) => void): Promise<void>;
|
|
62
|
+
}
|
|
63
|
+
export interface PlaywrightExecutionResponse<T = unknown> {
|
|
64
|
+
success: boolean;
|
|
65
|
+
error?: string;
|
|
66
|
+
result?: T;
|
|
67
|
+
stderr?: string;
|
|
68
|
+
}
|
|
69
|
+
export interface AutomationRuntime {
|
|
70
|
+
liveViewUrl?: string | null;
|
|
71
|
+
execute<T = unknown>(code: string, timeoutSec?: number): Promise<PlaywrightExecutionResponse<T>>;
|
|
72
|
+
close(): Promise<void>;
|
|
73
|
+
}
|
|
74
|
+
export type AutomationRuntimeFactory = (hasAutoCredentials: boolean) => Promise<AutomationRuntime>;
|
|
75
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/automation/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/automation/types.ts"],"names":[],"mappings":""}
|
package/dist/commands/add.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as p from "@clack/prompts";
|
|
2
|
-
import {
|
|
2
|
+
import { getAutomationClient } from "../automation/client.js";
|
|
3
3
|
import { formatKernelError } from "../kernel/errors.js";
|
|
4
4
|
const VALID_MEALS = ["breakfast", "lunch", "dinner", "snacks"];
|
|
5
5
|
export async function addCustomFood(name, options) {
|
|
@@ -40,8 +40,8 @@ export async function addCustomFood(name, options) {
|
|
|
40
40
|
const s = p.spinner();
|
|
41
41
|
s.start("Connecting...");
|
|
42
42
|
try {
|
|
43
|
-
const
|
|
44
|
-
await
|
|
43
|
+
const client = await getAutomationClient();
|
|
44
|
+
await client.addCustomFood({
|
|
45
45
|
name,
|
|
46
46
|
protein: options.protein,
|
|
47
47
|
carbs: options.carbs,
|
package/dist/commands/add.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add.js","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"add.js","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface BiometricsOptions {
|
|
2
|
+
weight?: number;
|
|
3
|
+
bodyFat?: number;
|
|
4
|
+
systolic?: number;
|
|
5
|
+
diastolic?: number;
|
|
6
|
+
date?: string;
|
|
7
|
+
unit?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function biometrics(options: BiometricsOptions): Promise<void>;
|
|
10
|
+
//# sourceMappingURL=biometrics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"biometrics.d.ts","sourceRoot":"","sources":["../../src/commands/biometrics.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsG1E"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import * as p from "@clack/prompts";
|
|
2
|
+
import { getAutomationClient } from "../automation/client.js";
|
|
3
|
+
import { formatKernelError } from "../kernel/errors.js";
|
|
4
|
+
import { parseDate, todayStr } from "../utils/date.js";
|
|
5
|
+
export async function biometrics(options) {
|
|
6
|
+
// Validate at least one biometric is provided
|
|
7
|
+
if (options.weight === undefined &&
|
|
8
|
+
options.bodyFat === undefined &&
|
|
9
|
+
(options.systolic === undefined || options.diastolic === undefined)) {
|
|
10
|
+
p.log.error("At least one biometric required: --weight, --body-fat, or both --systolic and --diastolic");
|
|
11
|
+
process.exit(1);
|
|
12
|
+
}
|
|
13
|
+
// Validate blood pressure requires both values
|
|
14
|
+
if ((options.systolic !== undefined && options.diastolic === undefined) ||
|
|
15
|
+
(options.systolic === undefined && options.diastolic !== undefined)) {
|
|
16
|
+
p.log.error("Blood pressure requires both --systolic and --diastolic");
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
// Validate weight unit
|
|
20
|
+
const unit = options.unit?.toLowerCase() || "kg";
|
|
21
|
+
if (unit !== "kg" && unit !== "lbs") {
|
|
22
|
+
p.log.error('Weight unit must be "kg" or "lbs"');
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
// Resolve date
|
|
26
|
+
let targetDate;
|
|
27
|
+
try {
|
|
28
|
+
targetDate = options.date ? parseDate(options.date) : todayStr();
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
p.log.error(String(error instanceof Error ? error.message : error));
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
p.intro("🍎 crono biometrics");
|
|
35
|
+
const s = p.spinner();
|
|
36
|
+
s.start("Connecting...");
|
|
37
|
+
try {
|
|
38
|
+
const client = await getAutomationClient();
|
|
39
|
+
// Log weight if provided
|
|
40
|
+
if (options.weight !== undefined) {
|
|
41
|
+
await client.logBiometric({
|
|
42
|
+
type: "weight",
|
|
43
|
+
value: options.weight,
|
|
44
|
+
unit,
|
|
45
|
+
date: targetDate,
|
|
46
|
+
}, (msg) => s.message(msg));
|
|
47
|
+
}
|
|
48
|
+
// Log body fat if provided
|
|
49
|
+
if (options.bodyFat !== undefined) {
|
|
50
|
+
await client.logBiometric({
|
|
51
|
+
type: "bodyfat",
|
|
52
|
+
value: options.bodyFat,
|
|
53
|
+
date: targetDate,
|
|
54
|
+
}, (msg) => s.message(msg));
|
|
55
|
+
}
|
|
56
|
+
// Log blood pressure if provided
|
|
57
|
+
if (options.systolic !== undefined && options.diastolic !== undefined) {
|
|
58
|
+
await client.logBiometric({
|
|
59
|
+
type: "bloodpressure",
|
|
60
|
+
systolic: options.systolic,
|
|
61
|
+
diastolic: options.diastolic,
|
|
62
|
+
date: targetDate,
|
|
63
|
+
}, (msg) => s.message(msg));
|
|
64
|
+
}
|
|
65
|
+
s.stop("Done.");
|
|
66
|
+
const logged = [];
|
|
67
|
+
if (options.weight !== undefined)
|
|
68
|
+
logged.push(`Weight: ${options.weight} ${unit}`);
|
|
69
|
+
if (options.bodyFat !== undefined)
|
|
70
|
+
logged.push(`Body Fat: ${options.bodyFat}%`);
|
|
71
|
+
if (options.systolic !== undefined && options.diastolic !== undefined)
|
|
72
|
+
logged.push(`Blood Pressure: ${options.systolic}/${options.diastolic} mmHg`);
|
|
73
|
+
p.outro(`Logged biometrics for ${targetDate}:\n ${logged.join("\n ")}`);
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
s.stop("Failed.");
|
|
77
|
+
p.log.error(`Failed to log biometrics: ${formatKernelError(error)}`);
|
|
78
|
+
process.exit(1);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=biometrics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"biometrics.js","sourceRoot":"","sources":["../../src/commands/biometrics.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/diary.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diary.d.ts","sourceRoot":"","sources":["../../src/commands/diary.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"diary.d.ts","sourceRoot":"","sources":["../../src/commands/diary.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAMxD,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAsB,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAgGhE;AA4BD,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAKvE;AAED,wBAAgB,eAAe,CAC7B,KAAK,EAAE,SAAS,EAChB,WAAW,EAAE,OAAO,EACpB,MAAM,CAAC,EAAE,MAAM,GACd,MAAM,CAwDR;AAED,wBAAgB,eAAe,CAC7B,OAAO,EAAE,SAAS,EAAE,EACpB,OAAO,EAAE,OAAO,EAChB,WAAW,EAAE,OAAO,GACnB,IAAI,CA2EN"}
|
package/dist/commands/diary.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as p from "@clack/prompts";
|
|
2
|
-
import {
|
|
2
|
+
import { getAutomationClient } from "../automation/client.js";
|
|
3
3
|
import { formatKernelError } from "../kernel/errors.js";
|
|
4
4
|
import { parseDate, parseRange, dateRange, todayStr } from "../utils/date.js";
|
|
5
5
|
import { exportData } from "../cronometer/export.js";
|
|
@@ -36,9 +36,9 @@ export async function diary(options) {
|
|
|
36
36
|
const s = options.json ? null : p.spinner();
|
|
37
37
|
s?.start("Connecting...");
|
|
38
38
|
try {
|
|
39
|
-
const
|
|
39
|
+
const client = await getAutomationClient();
|
|
40
40
|
// When --targets is used, fetch exercise data concurrently with diary scraping
|
|
41
|
-
const diaryPromise =
|
|
41
|
+
const diaryPromise = client.getDiary(dates, (msg) => s?.message(msg), options.targets);
|
|
42
42
|
let exerciseMap = null;
|
|
43
43
|
if (options.targets) {
|
|
44
44
|
// Determine date range for exercise export
|