@robbeverhelst/do 1.283.0 → 1.285.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/dist/do.js +198 -6
- package/package.json +1 -1
package/dist/do.js
CHANGED
|
@@ -5822,6 +5822,7 @@ var journalImportItems = pgTable("journal_import_items", {
|
|
|
5822
5822
|
body: text("body"),
|
|
5823
5823
|
rating: doublePrecision("rating"),
|
|
5824
5824
|
ratingQuestion: text("rating_question"),
|
|
5825
|
+
sleep: doublePrecision("sleep"),
|
|
5825
5826
|
highlight: text("highlight"),
|
|
5826
5827
|
milestoneCandidate: boolean("milestone_candidate").notNull().default(false),
|
|
5827
5828
|
health: boolean("health").notNull().default(false),
|
|
@@ -22474,6 +22475,7 @@ var journalImportItemInputSchema = object({
|
|
|
22474
22475
|
body: string2().trim().min(1).max(20000).nullish(),
|
|
22475
22476
|
rating: number2().min(1).max(10).nullish(),
|
|
22476
22477
|
ratingQuestion: string2().trim().min(1).max(80).nullish(),
|
|
22478
|
+
sleep: number2().min(0).max(24).nullish(),
|
|
22477
22479
|
highlight: string2().trim().min(1).max(200).nullish(),
|
|
22478
22480
|
milestoneCandidate: boolean3().default(false),
|
|
22479
22481
|
health: boolean3().default(false),
|
|
@@ -22502,6 +22504,7 @@ var journalImportItemSchema = object({
|
|
|
22502
22504
|
body: string2().nullable(),
|
|
22503
22505
|
rating: number2().nullable(),
|
|
22504
22506
|
ratingQuestion: string2().nullable(),
|
|
22507
|
+
sleep: number2().nullable().default(null),
|
|
22505
22508
|
highlight: string2().nullable(),
|
|
22506
22509
|
milestoneCandidate: boolean3(),
|
|
22507
22510
|
health: boolean3(),
|
|
@@ -22526,6 +22529,7 @@ var journalImportOverviewSchema = object({
|
|
|
22526
22529
|
ratings: number2().int(),
|
|
22527
22530
|
unclearRatings: array(string2()),
|
|
22528
22531
|
milestoneCandidates: number2().int(),
|
|
22532
|
+
sleep: number2().int().default(0),
|
|
22529
22533
|
health: number2().int(),
|
|
22530
22534
|
links: number2().int()
|
|
22531
22535
|
}),
|
|
@@ -23548,7 +23552,8 @@ var foodWeekSchema = object({
|
|
|
23548
23552
|
points: array(object({ day: civilDate, value: number2() })),
|
|
23549
23553
|
trend: array(object({ day: civilDate, value: number2() })),
|
|
23550
23554
|
latest: number2().nullable(),
|
|
23551
|
-
perWeek: number2().nullable()
|
|
23555
|
+
perWeek: number2().nullable(),
|
|
23556
|
+
source: metricSourceSchema.nullable()
|
|
23552
23557
|
}),
|
|
23553
23558
|
numbers: object({
|
|
23554
23559
|
completeDays: number2().int(),
|
|
@@ -25305,6 +25310,7 @@ var runQuestSchema = object({
|
|
|
25305
25310
|
status: runQuestStatusSchema.default("active"),
|
|
25306
25311
|
objective: text5.nullish(),
|
|
25307
25312
|
hint: shortText.nullish(),
|
|
25313
|
+
reward: shortText.nullish(),
|
|
25308
25314
|
place: shortText.nullish(),
|
|
25309
25315
|
steps: array(object({
|
|
25310
25316
|
text: shortText.pipe(string2().min(1)),
|
|
@@ -25318,7 +25324,8 @@ var runQuestSchema = object({
|
|
|
25318
25324
|
}).strict();
|
|
25319
25325
|
var runNextStepsSchema = object({
|
|
25320
25326
|
items: array(shortText.pipe(string2().min(1))).max(3),
|
|
25321
|
-
pinned: boolean3().default(false)
|
|
25327
|
+
pinned: boolean3().default(false),
|
|
25328
|
+
note: text5.nullish()
|
|
25322
25329
|
}).strict();
|
|
25323
25330
|
var runChoiceSchema = object({
|
|
25324
25331
|
ref: ref.nullish(),
|
|
@@ -25336,7 +25343,7 @@ var runChoiceSchema = object({
|
|
|
25336
25343
|
var runHomeSchema = object({
|
|
25337
25344
|
ref: ref.nullish(),
|
|
25338
25345
|
name,
|
|
25339
|
-
role: _enum2(["home", "collector", "storage", "planned"]).default("home"),
|
|
25346
|
+
role: _enum2(["home", "collector", "storage", "planned", "later"]).default("home"),
|
|
25340
25347
|
place: shortText.nullish(),
|
|
25341
25348
|
upgrades: array(object({ name, done: boolean3().default(false) }).strict()).max(40).optional(),
|
|
25342
25349
|
steward: shortText.nullish(),
|
|
@@ -26002,10 +26009,78 @@ var animalLogInputSchema = discriminatedUnion("kind", [
|
|
|
26002
26009
|
occurredAt: occurredAtSchema
|
|
26003
26010
|
}).strict()
|
|
26004
26011
|
]);
|
|
26012
|
+
var animalVetVisitSourceSchema = _enum2(["sticker", "photo", "said"]);
|
|
26013
|
+
var visitTextSchema = string2().trim().min(1).max(120);
|
|
26014
|
+
var visitCostSchema = object({
|
|
26015
|
+
amount: number2().positive().max(1e5),
|
|
26016
|
+
currency: string2().trim().length(3).default("EUR")
|
|
26017
|
+
}).strict();
|
|
26018
|
+
var animalVetVisitInputSchema = object({
|
|
26019
|
+
id: ulidSchema,
|
|
26020
|
+
at: exports_coerce.date().optional(),
|
|
26021
|
+
vetContactId: ulidSchema.optional(),
|
|
26022
|
+
clinician: visitTextSchema.optional(),
|
|
26023
|
+
reason: visitTextSchema.optional(),
|
|
26024
|
+
vaccine: object({ name: visitTextSchema, source: animalVetVisitSourceSchema.optional() }).strict().optional(),
|
|
26025
|
+
dewormer: visitTextSchema.optional(),
|
|
26026
|
+
weight: object({
|
|
26027
|
+
value: number2().positive().max(200000),
|
|
26028
|
+
unit: _enum2(["g", "kg"]).default("kg")
|
|
26029
|
+
}).strict().optional(),
|
|
26030
|
+
nextDates: array(object({
|
|
26031
|
+
id: ulidSchema,
|
|
26032
|
+
label: visitTextSchema,
|
|
26033
|
+
date: string2().regex(/^\d{4}-\d{2}-\d{2}$/, "expected YYYY-MM-DD")
|
|
26034
|
+
}).strict()).max(5).default([]),
|
|
26035
|
+
files: array(object({ id: ulidSchema, name: visitTextSchema.optional() }).strict()).max(5).default([]),
|
|
26036
|
+
cost: visitCostSchema.optional()
|
|
26037
|
+
}).strict();
|
|
26038
|
+
var animalVetVisitPatchSchema = object({
|
|
26039
|
+
vetContactId: ulidSchema.nullable().optional(),
|
|
26040
|
+
clinician: visitTextSchema.nullable().optional(),
|
|
26041
|
+
reason: visitTextSchema.nullable().optional(),
|
|
26042
|
+
vaccine: object({ name: visitTextSchema, source: animalVetVisitSourceSchema.optional() }).strict().nullable().optional(),
|
|
26043
|
+
dewormer: visitTextSchema.nullable().optional(),
|
|
26044
|
+
cost: visitCostSchema.nullable().optional()
|
|
26045
|
+
}).strict().refine((v) => Object.keys(v).length > 0, { message: "Change at least one field." });
|
|
26046
|
+
var animalVetVisitSchema = object({
|
|
26047
|
+
id: ulidSchema,
|
|
26048
|
+
animal: object({
|
|
26049
|
+
id: ulidSchema,
|
|
26050
|
+
title: string2(),
|
|
26051
|
+
speciesKey: string2().nullable(),
|
|
26052
|
+
speciesClass: animalClassSchema.nullable()
|
|
26053
|
+
}),
|
|
26054
|
+
at: exports_coerce.date(),
|
|
26055
|
+
vet: nodeRefSchema.nullable(),
|
|
26056
|
+
clinician: string2().nullable(),
|
|
26057
|
+
reason: string2().nullable(),
|
|
26058
|
+
vaccine: object({ name: string2(), source: animalVetVisitSourceSchema.nullable() }).nullable(),
|
|
26059
|
+
dewormer: string2().nullable(),
|
|
26060
|
+
weight: object({
|
|
26061
|
+
grams: number2(),
|
|
26062
|
+
deltaGrams: number2().nullable(),
|
|
26063
|
+
since: string2().nullable()
|
|
26064
|
+
}).nullable(),
|
|
26065
|
+
keyDates: array(object({ id: string2(), label: string2(), date: string2() })),
|
|
26066
|
+
files: array(object({ id: string2(), name: string2() })),
|
|
26067
|
+
cost: object({ amount: number2(), currency: string2() }).nullable(),
|
|
26068
|
+
byAgent: boolean3(),
|
|
26069
|
+
undone: boolean3()
|
|
26070
|
+
});
|
|
26005
26071
|
var animalTimelineEntrySchema = object({
|
|
26006
26072
|
id: string2(),
|
|
26007
26073
|
at: exports_coerce.date(),
|
|
26008
|
-
kind: _enum2([
|
|
26074
|
+
kind: _enum2([
|
|
26075
|
+
"weight",
|
|
26076
|
+
"length",
|
|
26077
|
+
"eggs",
|
|
26078
|
+
"note",
|
|
26079
|
+
"vet_visit",
|
|
26080
|
+
"period_started",
|
|
26081
|
+
"period_ended",
|
|
26082
|
+
"key_date"
|
|
26083
|
+
]),
|
|
26009
26084
|
animalId: ulidSchema,
|
|
26010
26085
|
animalTitle: string2(),
|
|
26011
26086
|
value: number2().nullable(),
|
|
@@ -26057,7 +26132,8 @@ var animalHandoverTripSchema = object({
|
|
|
26057
26132
|
houseNote: string2().nullable(),
|
|
26058
26133
|
holidayMode: animalHolidayModeSchema,
|
|
26059
26134
|
sharedUntil: string2().nullable(),
|
|
26060
|
-
agentNote: string2().nullable()
|
|
26135
|
+
agentNote: string2().nullable(),
|
|
26136
|
+
calendar: string2().nullable()
|
|
26061
26137
|
});
|
|
26062
26138
|
var animalHandoverAnimalSchema = object({
|
|
26063
26139
|
id: ulidSchema,
|
|
@@ -26074,6 +26150,7 @@ var animalHandoverAnimalSchema = object({
|
|
|
26074
26150
|
var animalHandoverContactSchema = object({
|
|
26075
26151
|
id: ulidSchema,
|
|
26076
26152
|
title: string2(),
|
|
26153
|
+
kind: _enum2(["vet", "member"]),
|
|
26077
26154
|
label: string2().nullable(),
|
|
26078
26155
|
phone: string2().nullable()
|
|
26079
26156
|
});
|
|
@@ -26088,6 +26165,7 @@ var animalHandoverSchema = object({
|
|
|
26088
26165
|
contacts: array(animalHandoverContactSchema),
|
|
26089
26166
|
supplies: array(animalHandoverSupplySchema),
|
|
26090
26167
|
habits: array(animalHandoverHabitSchema),
|
|
26168
|
+
sensors: boolean3(),
|
|
26091
26169
|
generatedAt: exports_coerce.date()
|
|
26092
26170
|
});
|
|
26093
26171
|
var animalHolidayModeInputSchema = animalHolidayModeSchema.partial().extend({ periodId: ulidSchema }).strict().refine((v) => Object.keys(v).length > 1, { message: "Turn at least one switch." });
|
|
@@ -28361,7 +28439,7 @@ function parseCapture2(input, now) {
|
|
|
28361
28439
|
|
|
28362
28440
|
// src/meta.ts
|
|
28363
28441
|
var CLI_NAME = "do";
|
|
28364
|
-
var VERSION = "1.
|
|
28442
|
+
var VERSION = "1.285.0";
|
|
28365
28443
|
var API_PREFIX = "/api/v1";
|
|
28366
28444
|
var DEFAULT_API_URL = "http://localhost:3001";
|
|
28367
28445
|
|
|
@@ -29845,6 +29923,41 @@ var HEALTH = /\b(symptoms?|stomach|nausea|headaches?|migraine|doctor|GP|medicati
|
|
|
29845
29923
|
var NOISE = /\b(PR monitor|GitHub daily|deploy(?:ment)? watch\w*|cron|heartbeat|sales prospects?)\b/i;
|
|
29846
29924
|
var MILESTONE = /\b(first|went live|is live|win:|moved in|arrived|wedding|engaged)\b/i;
|
|
29847
29925
|
var PR_REF = /\bPR\s*#\d+/gi;
|
|
29926
|
+
var SLEPT = /\bslept\s*~?\s*(\d{1,2})\s*h(?:\s*(\d{1,2}))?/i;
|
|
29927
|
+
var SLEEP_HOURS = /\bsleep\s*:?\s*~?\s*(\d{1,2}(?:\.\d+)?)\s*h\b/i;
|
|
29928
|
+
var atClock = (word) => [
|
|
29929
|
+
new RegExp(`\\b${word}\\b\\D{0,12}?(\\d{1,2})[:.h](\\d{2})`, "i"),
|
|
29930
|
+
new RegExp(`(\\d{1,2})[:.h](\\d{2})\\D{0,6}?\\b${word}\\b`, "i")
|
|
29931
|
+
];
|
|
29932
|
+
var BED_AT = atClock("(?:bed|asleep|lights out)");
|
|
29933
|
+
var WOKE_AT = atClock("(?:woke(?: up)?|wake(?: up)?|awake|got up|up at)");
|
|
29934
|
+
function sleepOf(raw) {
|
|
29935
|
+
const lines = raw.map(plain);
|
|
29936
|
+
for (const line of lines) {
|
|
29937
|
+
const slept = SLEPT.exec(line);
|
|
29938
|
+
if (slept)
|
|
29939
|
+
return Number(slept[1]) + Number(slept[2] ?? 0) / 60;
|
|
29940
|
+
const hours = SLEEP_HOURS.exec(line);
|
|
29941
|
+
if (hours)
|
|
29942
|
+
return Number(hours[1]);
|
|
29943
|
+
}
|
|
29944
|
+
const clock = (patterns) => {
|
|
29945
|
+
for (const line of lines) {
|
|
29946
|
+
for (const re of patterns) {
|
|
29947
|
+
const m = re.exec(line);
|
|
29948
|
+
if (m)
|
|
29949
|
+
return Number(m[1]) * 60 + Number(m[2]);
|
|
29950
|
+
}
|
|
29951
|
+
}
|
|
29952
|
+
return null;
|
|
29953
|
+
};
|
|
29954
|
+
const bed = clock(BED_AT);
|
|
29955
|
+
const woke = clock(WOKE_AT);
|
|
29956
|
+
if (bed === null || woke === null)
|
|
29957
|
+
return null;
|
|
29958
|
+
const minutes = (woke - bed + 24 * 60) % (24 * 60);
|
|
29959
|
+
return minutes >= 120 && minutes <= 16 * 60 ? Math.round(minutes / 60 * 100) / 100 : null;
|
|
29960
|
+
}
|
|
29848
29961
|
var TASK_DONE = /^\s*[-*]\s*\[x\]/i;
|
|
29849
29962
|
function section(text, heading) {
|
|
29850
29963
|
const lines = text.split(/\r?\n/);
|
|
@@ -29910,6 +30023,7 @@ function parseDailyNote(path, day, text) {
|
|
|
29910
30023
|
}
|
|
29911
30024
|
const milestoneLine = all.find((l) => MILESTONE.test(l) && !HEALTH.test(l) && !NOISE.test(l) && plain(l).length > 0);
|
|
29912
30025
|
const highlight = milestoneLine ? firstSentence(plain(milestoneLine), 80) : null;
|
|
30026
|
+
const sleep = sleepOf(all);
|
|
29913
30027
|
const prs = (text.match(PR_REF) ?? []).length;
|
|
29914
30028
|
const tasks = all.filter((l) => TASK_DONE.test(l)).length;
|
|
29915
30029
|
return {
|
|
@@ -29922,6 +30036,7 @@ function parseDailyNote(path, day, text) {
|
|
|
29922
30036
|
body,
|
|
29923
30037
|
rating,
|
|
29924
30038
|
ratingQuestion,
|
|
30039
|
+
...sleep !== null ? { sleep } : {},
|
|
29925
30040
|
highlight,
|
|
29926
30041
|
milestoneCandidate: Boolean(highlight),
|
|
29927
30042
|
health,
|
|
@@ -33333,6 +33448,54 @@ var COMMAND_SPECS = [
|
|
|
33333
33448
|
returns: "AnimalTimelineEntry",
|
|
33334
33449
|
notes: 'POST /api/v1/animals/{id}/log (`animal_log`). `do animals log <hens> eggs 2`, `do animals log <dog> weight 37.8 --unit kg`, `do animals log <hen> note "eating again"`. Eggs are the day\'s count: logging again that day replaces it.'
|
|
33335
33450
|
},
|
|
33451
|
+
{
|
|
33452
|
+
path: ["animals", "vet-visit"],
|
|
33453
|
+
summary: "Log a vet visit in one call: where, the vaccine, the dewormer, the weight, the next dates, the photos, the cost.",
|
|
33454
|
+
args: [{ name: "id", required: true, description: "Animal ULID." }],
|
|
33455
|
+
flags: [
|
|
33456
|
+
{
|
|
33457
|
+
name: "data",
|
|
33458
|
+
type: "string",
|
|
33459
|
+
description: "JSON: { vetContactId?, clinician?, reason?, vaccine?: { name, source? }, dewormer?, weight?: { value, unit? }, nextDates?: [{ label, date }], files?: [{ id, name? }], cost?: { amount, currency? }, at? }. The visit's and each date's ids are minted."
|
|
33460
|
+
}
|
|
33461
|
+
],
|
|
33462
|
+
scopes: ["animals:write"],
|
|
33463
|
+
returns: "AnimalVetVisit",
|
|
33464
|
+
notes: 'POST /api/v1/animals/{id}/vet-visits (`animal_vet_visit`, mockup 03). The visit is the receipt: post it with `receipt: { nodeId: <visit id> }`. `do animals vet-visit <dog> --data \'{"reason":"booster","vaccine":{"name":"DHPPi + L4","source":"sticker"},"weight":{"value":37.8}}\'`.'
|
|
33465
|
+
},
|
|
33466
|
+
{
|
|
33467
|
+
path: ["animals", "vet-visit-get"],
|
|
33468
|
+
summary: "Read a vet visit as its receipt reads.",
|
|
33469
|
+
args: [{ name: "visitId", required: true, description: "Vet visit ULID." }],
|
|
33470
|
+
flags: [],
|
|
33471
|
+
scopes: ["animals:read"],
|
|
33472
|
+
returns: "AnimalVetVisit",
|
|
33473
|
+
notes: "GET /api/v1/animals/vet-visits/{visitId}."
|
|
33474
|
+
},
|
|
33475
|
+
{
|
|
33476
|
+
path: ["animals", "vet-visit-edit"],
|
|
33477
|
+
summary: "Put a vet visit's fields right (the receipt's Edit).",
|
|
33478
|
+
args: [{ name: "visitId", required: true, description: "Vet visit ULID." }],
|
|
33479
|
+
flags: [
|
|
33480
|
+
{
|
|
33481
|
+
name: "data",
|
|
33482
|
+
type: "string",
|
|
33483
|
+
description: "JSON: any of vetContactId, clinician, reason, vaccine, dewormer, cost (null clears one)."
|
|
33484
|
+
}
|
|
33485
|
+
],
|
|
33486
|
+
scopes: ["animals:write"],
|
|
33487
|
+
returns: "AnimalVetVisit",
|
|
33488
|
+
notes: "PATCH /api/v1/animals/vet-visits/{visitId}. The newest version wins."
|
|
33489
|
+
},
|
|
33490
|
+
{
|
|
33491
|
+
path: ["animals", "vet-visit-undo"],
|
|
33492
|
+
summary: "Take a vet visit back (the receipt's Undo).",
|
|
33493
|
+
args: [{ name: "visitId", required: true, description: "Vet visit ULID." }],
|
|
33494
|
+
flags: [],
|
|
33495
|
+
scopes: ["animals:write"],
|
|
33496
|
+
returns: "AnimalVetVisit",
|
|
33497
|
+
notes: "POST /api/v1/animals/vet-visits/{visitId}/undo. The visit, its weight, its key dates and the filed photos all go back."
|
|
33498
|
+
},
|
|
33336
33499
|
{
|
|
33337
33500
|
path: ["runs", "change"],
|
|
33338
33501
|
summary: "Apply a chat update to a run: its changes, with a receipt and Undo.",
|
|
@@ -38293,6 +38456,35 @@ var HANDLERS = {
|
|
|
38293
38456
|
const body = parseInput(animalLogInputSchema, { ...fact, ...at ? { occurredAt: at } : {} });
|
|
38294
38457
|
return { data: await requireClient().post(`/animals/${id}/log`, body), render: renderRecord };
|
|
38295
38458
|
},
|
|
38459
|
+
"animals vet-visit": async ({ args, flags, requireClient }) => {
|
|
38460
|
+
const id = requireArg(args, 0, "animal id");
|
|
38461
|
+
const raw = readDataFlag(flags);
|
|
38462
|
+
const body = parseInput(animalVetVisitInputSchema, {
|
|
38463
|
+
id: ulid3(),
|
|
38464
|
+
...raw,
|
|
38465
|
+
nextDates: (raw.nextDates ?? []).map((d) => ({ id: ulid3(), ...d }))
|
|
38466
|
+
});
|
|
38467
|
+
return {
|
|
38468
|
+
data: await requireClient().post(`/animals/${id}/vet-visits`, body),
|
|
38469
|
+
render: renderRecord
|
|
38470
|
+
};
|
|
38471
|
+
},
|
|
38472
|
+
"animals vet-visit-get": async ({ args, requireClient }) => ({
|
|
38473
|
+
data: await requireClient().get(`/animals/vet-visits/${requireArg(args, 0, "visit id")}`),
|
|
38474
|
+
render: renderRecord
|
|
38475
|
+
}),
|
|
38476
|
+
"animals vet-visit-edit": async ({ args, flags, requireClient }) => {
|
|
38477
|
+
const visitId = requireArg(args, 0, "visit id");
|
|
38478
|
+
const body = parseInput(animalVetVisitPatchSchema, readDataFlag(flags));
|
|
38479
|
+
return {
|
|
38480
|
+
data: await requireClient().patch(`/animals/vet-visits/${visitId}`, body),
|
|
38481
|
+
render: renderRecord
|
|
38482
|
+
};
|
|
38483
|
+
},
|
|
38484
|
+
"animals vet-visit-undo": async ({ args, requireClient }) => ({
|
|
38485
|
+
data: await requireClient().post(`/animals/vet-visits/${requireArg(args, 0, "visit id")}/undo`, {}),
|
|
38486
|
+
render: renderRecord
|
|
38487
|
+
}),
|
|
38296
38488
|
"runs change": async ({ args, flags, requireClient }) => {
|
|
38297
38489
|
const id = requireArg(args, 0, "run id");
|
|
38298
38490
|
const body = { ...readDataFlag(flags) };
|
package/package.json
CHANGED