@robbeverhelst/do 1.296.0 → 1.297.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 (2) hide show
  1. package/dist/do.js +1761 -1289
  2. package/package.json +1 -1
package/dist/do.js CHANGED
@@ -4496,6 +4496,26 @@ var periods = pgTable("periods", {
4496
4496
  index("periods_tenant_starts_idx").on(t.tenantId, t.startsAt)
4497
4497
  ]);
4498
4498
 
4499
+ // ../../packages/schema/src/db/sensors.ts
4500
+ var sensorProvider = pgEnum("sensor_provider", ["home_assistant", "unifi"]);
4501
+ var sensorTarget = pgEnum("sensor_target", ["place", "asset"]);
4502
+ var sensorLinks = pgTable("sensor_links", {
4503
+ id: text("id").primaryKey(),
4504
+ tenantId: text("tenant_id").notNull().references(() => tenants.id),
4505
+ provider: sensorProvider("provider").notNull(),
4506
+ externalId: text("external_id").notNull(),
4507
+ nodeId: text("node_id").notNull().references(() => nodes.id),
4508
+ target: sensorTarget("target").notNull(),
4509
+ reading: text("reading").notNull(),
4510
+ label: text("label"),
4511
+ createdBy: text("created_by").references(() => users.id, { onDelete: "set null" }),
4512
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
4513
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
4514
+ }, (t) => [
4515
+ uniqueIndex("sensor_links_entity_idx").on(t.tenantId, t.provider, t.externalId),
4516
+ index("sensor_links_node_idx").on(t.nodeId)
4517
+ ]);
4518
+
4499
4519
  // ../../packages/schema/src/db/planning-rules.ts
4500
4520
  var planningRuleKind = pgEnum("planning_rule_kind", [
4501
4521
  "fixed_time",
@@ -4579,6 +4599,17 @@ var animals = pgTable("animals", {
4579
4599
  breeding: animalBreeding("breeding").notNull().default("avoid"),
4580
4600
  areaId: text("area_id").references(() => areas.id, { onDelete: "set null" })
4581
4601
  }, (t) => [index("animals_tenant_idx").on(t.tenantId), index("animals_species_idx").on(t.speciesId)]);
4602
+ var animalLostCards = pgTable("animal_lost_cards", {
4603
+ animalId: text("animal_id").primaryKey().references(() => animals.id, { onDelete: "cascade" }),
4604
+ tenantId: text("tenant_id").notNull().references(() => tenants.id),
4605
+ token: text("token").notNull().unique(),
4606
+ photoFileId: text("photo_file_id"),
4607
+ phone: text("phone"),
4608
+ showChipped: boolean("show_chipped").notNull().default(false),
4609
+ note: text("note"),
4610
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
4611
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
4612
+ }, (t) => [index("animal_lost_cards_tenant_idx").on(t.tenantId)]);
4582
4613
 
4583
4614
  // ../../packages/schema/src/db/integrations.ts
4584
4615
  var connectionStatus = pgEnum("connection_status", [
@@ -20635,7 +20666,8 @@ var metricSourceSchema = _enum2([
20635
20666
  "device",
20636
20667
  "agent",
20637
20668
  "google_fit",
20638
- "google_health"
20669
+ "google_health",
20670
+ "health_connect"
20639
20671
  ]);
20640
20672
  var loggedMetricSourceSchema = _enum2(["manual", "device", "agent"]);
20641
20673
  var metricPointSchema = object({
@@ -20670,6 +20702,21 @@ var logMetricInputSchema = object({
20670
20702
  occurredAt: exports_coerce.date().optional(),
20671
20703
  source: loggedMetricSourceSchema.optional()
20672
20704
  }).strict();
20705
+ var HEALTH_CONNECT_METRICS = ["weight", "sleep", "bedtime"];
20706
+ var importedMetricPointSchema = object({
20707
+ key: _enum2(HEALTH_CONNECT_METRICS),
20708
+ value: number2().finite(),
20709
+ occurredAt: exports_coerce.date(),
20710
+ recordId: string2().min(1).max(200)
20711
+ }).strict();
20712
+ var importMetricsInputSchema = object({
20713
+ source: literal("health_connect"),
20714
+ points: array(importedMetricPointSchema).min(1).max(500)
20715
+ }).strict();
20716
+ var importMetricsResultSchema = object({
20717
+ imported: number2().int().min(0),
20718
+ skipped: number2().int().min(0)
20719
+ });
20673
20720
  function bedtimeMinutes(clock) {
20674
20721
  const m = /^([01]?\d|2[0-3]):([0-5]\d)$/.exec(clock.trim());
20675
20722
  if (!m)
@@ -21306,405 +21353,1192 @@ var assetUpkeepSchema = object({
21306
21353
  repairs: array(taskViewSchema)
21307
21354
  });
21308
21355
 
21309
- // ../../packages/schema/src/contracts/house.ts
21310
- var day = string2().regex(/^\d{4}-\d{2}-\d{2}$/, "must be a calendar day (YYYY-MM-DD)");
21311
- var houseBrokenSchema = object({
21312
- item: collectionItemViewSchema,
21313
- repair: taskViewSchema.nullable()
21314
- });
21315
- var houseUpkeepSoonSchema = object({
21316
- task: taskViewSchema,
21317
- itemId: string2(),
21318
- itemTitle: string2(),
21319
- nextOn: day.nullable(),
21320
- placeTitle: string2().nullable().default(null),
21321
- lastOn: day.nullable().default(null)
21322
- });
21323
- var housePlaceTileSchema = object({
21324
- id: string2(),
21325
- title: string2(),
21326
- kind: string2(),
21327
- gardenFeatureId: string2().nullable(),
21328
- thingCount: number2().int().min(0)
21356
+ // ../../packages/schema/src/contracts/key-dates.ts
21357
+ var keyDateDaySchema = string2().regex(/^\d{4}-\d{2}-\d{2}$/, "expected YYYY-MM-DD").refine((s) => {
21358
+ const d = new Date(`${s}T00:00:00Z`);
21359
+ return !Number.isNaN(d.getTime()) && d.toISOString().slice(0, 10) === s;
21360
+ }, "not a real date");
21361
+ var keyDateRepeatSchema = _enum2(["yearly"]);
21362
+ var keyDateSchema = createSelectSchema(keyDates, {
21363
+ date: keyDateDaySchema,
21364
+ confirmedAt: exports_coerce.date().nullable(),
21365
+ createdAt: exports_coerce.date(),
21366
+ updatedAt: exports_coerce.date()
21329
21367
  });
21330
- var houseOverviewSchema = object({
21331
- broken: array(houseBrokenSchema),
21332
- upkeepSoon: array(houseUpkeepSoonSchema),
21333
- places: array(housePlaceTileSchema),
21334
- thingCount: number2().int().min(0),
21335
- upkeepCount: number2().int().min(0),
21336
- toolCount: number2().int().min(0),
21337
- animalCount: number2().int().min(0),
21338
- toConfirm: number2().int().min(0).default(0)
21368
+ var keyDateViewSchema = keyDateSchema.extend({
21369
+ nodeTitle: string2(),
21370
+ nodeType: string2(),
21371
+ repeat: keyDateRepeatSchema.nullable(),
21372
+ nextOn: keyDateDaySchema,
21373
+ task: object({
21374
+ id: ulidSchema,
21375
+ status: string2(),
21376
+ dueAt: exports_coerce.date().nullable(),
21377
+ title: string2().nullable().optional(),
21378
+ area: string2().nullable().optional()
21379
+ }).nullable()
21339
21380
  });
21340
- var upkeepScheduleSchema = object({
21341
- every: number2().int().min(1).max(365),
21342
- unit: _enum2(["day", "week", "month", "year"]),
21343
- startOn: day.optional()
21344
- }).strict();
21345
- var setAssetUpkeepInputSchema = object({
21346
- title: string2().trim().min(1).max(200),
21347
- schedule: upkeepScheduleSchema,
21348
- placeId: ulidSchema.nullish(),
21349
- areaId: ulidSchema.nullish(),
21350
- nextStep: string2().trim().max(500).nullish()
21381
+ var leadDaysSchema = number2().int().min(0).max(366);
21382
+ var sourceSchema = string2().trim().min(1).max(120);
21383
+ var createKeyDateInputSchema = object({
21384
+ id: ulidSchema,
21385
+ nodeId: ulidSchema,
21386
+ kind: keyDateKindSchema.optional(),
21387
+ label: string2().trim().min(1).max(200).nullish(),
21388
+ date: keyDateDaySchema,
21389
+ yearKnown: boolean3().optional(),
21390
+ repeat: keyDateRepeatSchema.nullish(),
21391
+ leadDays: leadDaysSchema.optional(),
21392
+ derivedFrom: string2().trim().min(1).max(120).nullish(),
21393
+ source: sourceSchema.optional(),
21394
+ confirmed: boolean3().optional()
21351
21395
  }).strict();
21352
- var fileAssetInputSchema = object({
21353
- id: ulidSchema.optional(),
21354
- title: string2().trim().min(1).max(200),
21355
- placeId: ulidSchema.nullish(),
21356
- areaId: ulidSchema.nullish(),
21357
- status: _enum2(["want", "have"]).optional(),
21358
- facet: record(string2(), unknown()).optional(),
21359
- tags: array(string2().min(1).max(60)).max(20).optional(),
21360
- fileIds: array(ulidSchema).max(20).optional(),
21361
- match: boolean3().default(true),
21362
- upkeep: setAssetUpkeepInputSchema.optional(),
21363
- fault: object({
21364
- note: string2().trim().min(1).max(2000),
21365
- repairTitle: string2().trim().min(1).max(200).optional()
21366
- }).strict().optional()
21396
+ var updateKeyDateInputSchema = object({
21397
+ kind: keyDateKindSchema.optional(),
21398
+ label: string2().trim().min(1).max(200).nullish(),
21399
+ date: keyDateDaySchema.optional(),
21400
+ yearKnown: boolean3().optional(),
21401
+ repeat: keyDateRepeatSchema.nullish(),
21402
+ leadDays: leadDaysSchema.optional(),
21403
+ derivedFrom: string2().trim().min(1).max(120).nullish(),
21404
+ source: sourceSchema.optional(),
21405
+ confirmed: boolean3().optional()
21367
21406
  }).strict();
21368
- var houseReceiptSchema = object({
21369
- itemId: string2(),
21370
- created: boolean3(),
21371
- before: object({
21372
- facet: record(string2(), unknown()).nullable(),
21373
- placeId: string2().nullable(),
21374
- status: string2()
21375
- }).nullable(),
21376
- taskIds: array(string2()),
21377
- entryIds: array(string2()),
21378
- files: array(object({ id: string2(), previousOwnerId: string2().nullable() }))
21407
+ var keyDatesQuerySchema = object({
21408
+ nodeId: ulidSchema.optional(),
21409
+ kind: keyDateKindSchema.optional(),
21410
+ from: keyDateDaySchema.optional(),
21411
+ to: keyDateDaySchema.optional()
21379
21412
  });
21380
- var houseWriteResultSchema = object({
21381
- item: collectionItemDetailSchema,
21382
- receipt: houseReceiptSchema
21413
+
21414
+ // ../../packages/schema/src/contracts/periods.ts
21415
+ var periodKindSchema = _enum2(periodKind.enumValues);
21416
+ var periodRuleSchema = record(string2(), unknown());
21417
+ var periodSchema = createSelectSchema(periods, {
21418
+ startsAt: exports_coerce.date(),
21419
+ endsAt: exports_coerce.date().nullable(),
21420
+ plannedEndAt: exports_coerce.date().nullable(),
21421
+ rule: periodRuleSchema,
21422
+ createdAt: exports_coerce.date(),
21423
+ updatedAt: exports_coerce.date()
21383
21424
  });
21384
- var undoHouseWriteInputSchema = houseReceiptSchema.strict();
21385
- var houseTrailStepSchema = object({ id: string2(), title: string2() });
21386
- var houseAssetPartSchema = object({
21387
- id: string2(),
21388
- title: string2(),
21389
- quantity: number2(),
21390
- unit: string2().nullable(),
21391
- lowStockThreshold: number2().nullable()
21425
+ var periodViewSchema = periodSchema.extend({
21426
+ nodeTitle: string2(),
21427
+ nodeType: string2(),
21428
+ active: boolean3()
21392
21429
  });
21393
- var houseAssetLinkSchema = object({
21394
- nodeId: string2(),
21395
- title: string2(),
21396
- type: string2(),
21397
- kind: string2(),
21398
- direction: _enum2(["in", "out"]),
21399
- label: string2().nullable().default(null),
21400
- context: string2().nullable().default(null),
21401
- at: exports_coerce.date().nullable().default(null),
21402
- timed: boolean3().default(false)
21430
+ var noteSchema2 = string2().trim().min(1).max(500);
21431
+ function endsAfterStart(p, ctx) {
21432
+ if (!p.startsAt)
21433
+ return;
21434
+ for (const key of ["endsAt", "plannedEndAt"]) {
21435
+ const at = p[key];
21436
+ if (at && at < p.startsAt) {
21437
+ ctx.addIssue({ code: "custom", path: [key], message: `${key} is before startsAt` });
21438
+ }
21439
+ }
21440
+ }
21441
+ var createPeriodInputSchema = object({
21442
+ id: ulidSchema,
21443
+ nodeId: ulidSchema,
21444
+ kind: periodKindSchema.optional(),
21445
+ startsAt: exports_coerce.date(),
21446
+ endsAt: exports_coerce.date().nullish(),
21447
+ plannedEndAt: exports_coerce.date().nullish(),
21448
+ rule: periodRuleSchema.optional(),
21449
+ note: noteSchema2.nullish()
21450
+ }).strict().superRefine(endsAfterStart);
21451
+ var updatePeriodInputSchema = object({
21452
+ kind: periodKindSchema.optional(),
21453
+ startsAt: exports_coerce.date().optional(),
21454
+ endsAt: exports_coerce.date().nullish(),
21455
+ plannedEndAt: exports_coerce.date().nullish(),
21456
+ rule: periodRuleSchema.optional(),
21457
+ note: noteSchema2.nullish()
21458
+ }).strict().superRefine(endsAfterStart);
21459
+ var periodsQuerySchema = object({
21460
+ nodeId: ulidSchema.optional(),
21461
+ kind: periodKindSchema.optional(),
21462
+ active: _enum2(["true", "false"]).transform((v) => v === "true").optional()
21403
21463
  });
21404
- var houseAssetSchema = object({
21405
- item: collectionItemDetailSchema,
21406
- trail: array(houseTrailStepSchema),
21407
- parts: array(houseAssetPartSchema),
21408
- linked: array(houseAssetLinkSchema),
21409
- warrantyUntil: day.nullable(),
21410
- visibility: _enum2(NODE_VISIBILITY_VALUES).default("space")
21464
+
21465
+ // ../../packages/schema/src/contracts/animals.ts
21466
+ var animalFormSchema = _enum2(animalForm.enumValues);
21467
+ var animalStatusSchema = _enum2(animalStatus.enumValues);
21468
+ var animalAcquiredHowSchema = _enum2(animalAcquiredHow.enumValues);
21469
+ var animalSexSchema = _enum2(animalSex.enumValues);
21470
+ var animalBreedingSchema = _enum2(animalBreeding.enumValues);
21471
+ var animalClassSchema = _enum2(animalClass.enumValues);
21472
+ var animalLegalSchema = _enum2(animalLegal.enumValues);
21473
+ var animalBornOnSchema = string2().regex(/^\d{4}(-(0[1-9]|1[0-2])(-(0[1-9]|[12]\d|3[01]))?)?$/, "expected YYYY, YYYY-MM or YYYY-MM-DD");
21474
+ var animalIdsSchema = object({
21475
+ chipNoMasked: string2().trim().min(1).max(40).optional(),
21476
+ passportNoMasked: string2().trim().min(1).max(40).optional(),
21477
+ ringNo: string2().trim().min(1).max(40).optional(),
21478
+ ringYear: number2().int().min(1900).max(2200).optional(),
21479
+ ringIssuer: string2().trim().min(1).max(80).optional(),
21480
+ ringType: _enum2(["open", "closed"]).optional()
21481
+ }).strict();
21482
+ function isMaskedNumber(value) {
21483
+ const shown = value.replace(/[\s*\u2022xX.-]/g, "");
21484
+ return shown.length <= 4 && shown.length < value.replace(/\s/g, "").length;
21485
+ }
21486
+ var maskedIdsSchema = animalIdsSchema.superRefine((ids, ctx) => {
21487
+ for (const key of ["chipNoMasked", "passportNoMasked"]) {
21488
+ const v = ids[key];
21489
+ if (v && !isMaskedNumber(v)) {
21490
+ ctx.addIssue({
21491
+ code: "custom",
21492
+ path: [key],
21493
+ message: "mask all but the last four characters (e.g. ***********1234)"
21494
+ });
21495
+ }
21496
+ }
21411
21497
  });
21412
- var setAssetVisibilityInputSchema = object({ visibility: _enum2(NODE_VISIBILITY_VALUES) }).strict();
21413
- var linkAssetPartInputSchema = object({ inventoryItemId: ulidSchema }).strict();
21414
- var lendAssetInputSchema = object({
21415
- direction: _enum2(["lent", "borrowed"]),
21416
- who: string2().trim().min(1).max(200),
21417
- contactId: ulidSchema.nullish(),
21418
- since: day.optional(),
21419
- dueBack: day.nullish(),
21420
- note: string2().trim().max(500).nullish()
21498
+ var animalScheduleStepSchema = object({
21499
+ key: string2().trim().min(1).max(40),
21500
+ label: string2().trim().min(1).max(120),
21501
+ everyMonths: number2().int().min(1).max(120)
21421
21502
  }).strict();
21422
- var returnAssetInputSchema = object({
21423
- on: day.optional(),
21424
- note: string2().trim().max(500).nullish()
21503
+ var animalSpeciesSchema = createSelectSchema(animalSpecies, {
21504
+ incompatibleWith: array(string2()),
21505
+ defaultSchedule: array(animalScheduleStepSchema),
21506
+ createdAt: exports_coerce.date()
21507
+ });
21508
+ var speciesKeySchema = string2().regex(/^[a-z][a-z0-9_]{1,39}$/, "a lowercase slug, e.g. hermann_tortoise");
21509
+ var createAnimalSpeciesInputSchema = object({
21510
+ id: ulidSchema,
21511
+ key: speciesKeySchema,
21512
+ commonName: string2().trim().min(1).max(120),
21513
+ commonNameNl: string2().trim().min(1).max(120).nullish(),
21514
+ latin: string2().trim().min(1).max(120).nullish(),
21515
+ class: animalClassSchema.optional(),
21516
+ legal: animalLegalSchema.optional(),
21517
+ hibernates: boolean3().optional(),
21518
+ defaultForm: animalFormSchema.optional(),
21519
+ minGroupSize: number2().int().min(1).max(1000).nullish(),
21520
+ incompatibleWith: array(speciesKeySchema).max(20).optional(),
21521
+ defaultSchedule: array(animalScheduleStepSchema).max(20).optional(),
21522
+ careSheetMd: string2().trim().min(1).max(20000).nullish()
21425
21523
  }).strict();
21426
- var houseValueProofSchema = _enum2(["receipt_photo", "receipt", "photo", "none"]);
21427
- var houseValueRowSchema = object({
21428
- id: string2(),
21429
- title: string2(),
21430
- model: string2().nullable(),
21431
- placeId: string2().nullable(),
21432
- placeTitle: string2().nullable(),
21433
- placeGroup: string2().nullable().default(null),
21434
- withHouse: boolean3().default(false),
21435
- paidApprox: boolean3().default(false),
21436
- borrowedFrom: string2().nullable().default(null),
21437
- bought: day.nullable(),
21438
- paid: number2().nullable(),
21439
- now: number2().nullable(),
21440
- nowSource: string2().nullable(),
21441
- proof: houseValueProofSchema,
21442
- excluded: boolean3(),
21443
- visibility: _enum2(["space", "owner"])
21524
+ var updateAnimalSpeciesInputSchema = createAnimalSpeciesInputSchema.omit({ id: true, key: true }).partial().strict();
21525
+ var DEWORM = {
21526
+ key: "deworm",
21527
+ label: "Deworm",
21528
+ everyMonths: 3
21529
+ };
21530
+ var BOOSTER = { key: "booster", label: "Yearly booster", everyMonths: 12 };
21531
+ var NATIVE_FINCH = {
21532
+ class: "bird",
21533
+ legal: "native_closed_ring"
21534
+ };
21535
+ var EXOTIC_FINCH = {
21536
+ class: "bird",
21537
+ legal: "none",
21538
+ defaultForm: "group",
21539
+ minGroupSize: 2
21540
+ };
21541
+ var ANIMAL_SPECIES_SEED = [
21542
+ {
21543
+ key: "dog",
21544
+ commonName: "Dog",
21545
+ commonNameNl: "Hond",
21546
+ latin: "Canis familiaris",
21547
+ class: "mammal",
21548
+ legal: "dog_id",
21549
+ defaultSchedule: [DEWORM, BOOSTER]
21550
+ },
21551
+ {
21552
+ key: "cat",
21553
+ commonName: "Cat",
21554
+ commonNameNl: "Kat",
21555
+ latin: "Felis catus",
21556
+ class: "mammal",
21557
+ legal: "cat_id",
21558
+ defaultSchedule: [DEWORM, BOOSTER]
21559
+ },
21560
+ {
21561
+ key: "chicken",
21562
+ commonName: "Chicken",
21563
+ commonNameNl: "Kip",
21564
+ latin: "Gallus gallus domesticus",
21565
+ class: "bird",
21566
+ defaultForm: "group",
21567
+ minGroupSize: 3,
21568
+ defaultSchedule: [
21569
+ { key: "mite_check", label: "Mite check", everyMonths: 1 },
21570
+ { key: "deworm", label: "Deworm", everyMonths: 6 }
21571
+ ]
21572
+ },
21573
+ {
21574
+ key: "duck",
21575
+ commonName: "Duck",
21576
+ commonNameNl: "Eend",
21577
+ latin: "Anas platyrhynchos domesticus",
21578
+ class: "bird",
21579
+ defaultForm: "group",
21580
+ minGroupSize: 2
21581
+ },
21582
+ {
21583
+ key: "quail",
21584
+ commonName: "Quail",
21585
+ commonNameNl: "Kwartel",
21586
+ latin: "Coturnix japonica",
21587
+ class: "bird",
21588
+ defaultForm: "group",
21589
+ minGroupSize: 3
21590
+ },
21591
+ {
21592
+ key: "hermann_tortoise",
21593
+ commonName: "Hermann's tortoise",
21594
+ commonNameNl: "Griekse landschildpad",
21595
+ latin: "Testudo hermanni",
21596
+ class: "reptile",
21597
+ legal: "cites_a",
21598
+ hibernates: true,
21599
+ defaultSchedule: [{ key: "health_check", label: "Health check", everyMonths: 12 }]
21600
+ },
21601
+ {
21602
+ key: "zebra_finch",
21603
+ commonName: "Zebra finch",
21604
+ commonNameNl: "Zebravink",
21605
+ latin: "Taeniopygia guttata",
21606
+ ...EXOTIC_FINCH
21607
+ },
21608
+ {
21609
+ key: "bengalese_finch",
21610
+ commonName: "Bengalese finch",
21611
+ commonNameNl: "Japans meeuwtje",
21612
+ latin: "Lonchura striata domestica",
21613
+ ...EXOTIC_FINCH
21614
+ },
21615
+ {
21616
+ key: "star_finch",
21617
+ commonName: "Star finch",
21618
+ commonNameNl: "Binsenastrild",
21619
+ latin: "Bathilda ruficauda",
21620
+ ...EXOTIC_FINCH
21621
+ },
21622
+ {
21623
+ key: "diamond_dove",
21624
+ commonName: "Diamond dove",
21625
+ commonNameNl: "Diamantduif",
21626
+ latin: "Geopelia cuneata",
21627
+ ...EXOTIC_FINCH
21628
+ },
21629
+ {
21630
+ key: "bullfinch",
21631
+ commonName: "Eurasian bullfinch",
21632
+ commonNameNl: "Goudvink",
21633
+ latin: "Pyrrhula pyrrhula",
21634
+ ...NATIVE_FINCH
21635
+ },
21636
+ {
21637
+ key: "bearded_reedling",
21638
+ commonName: "Bearded reedling",
21639
+ commonNameNl: "Baardmannetje",
21640
+ latin: "Panurus biarmicus",
21641
+ ...NATIVE_FINCH
21642
+ },
21643
+ {
21644
+ key: "siskin",
21645
+ commonName: "Eurasian siskin",
21646
+ commonNameNl: "Sijs",
21647
+ latin: "Spinus spinus",
21648
+ ...NATIVE_FINCH
21649
+ },
21650
+ {
21651
+ key: "goldfinch",
21652
+ commonName: "European goldfinch",
21653
+ commonNameNl: "Putter",
21654
+ latin: "Carduelis carduelis",
21655
+ ...NATIVE_FINCH
21656
+ },
21657
+ {
21658
+ key: "linnet",
21659
+ commonName: "Common linnet",
21660
+ commonNameNl: "Kneu",
21661
+ latin: "Linaria cannabina",
21662
+ ...NATIVE_FINCH
21663
+ },
21664
+ {
21665
+ key: "rabbit",
21666
+ commonName: "Rabbit",
21667
+ commonNameNl: "Konijn",
21668
+ latin: "Oryctolagus cuniculus",
21669
+ class: "mammal",
21670
+ defaultForm: "group",
21671
+ minGroupSize: 2,
21672
+ incompatibleWith: ["guinea_pig"],
21673
+ defaultSchedule: [{ key: "vaccine", label: "Myxo/RHD vaccine", everyMonths: 12 }]
21674
+ },
21675
+ {
21676
+ key: "guinea_pig",
21677
+ commonName: "Guinea pig",
21678
+ commonNameNl: "Cavia",
21679
+ latin: "Cavia porcellus",
21680
+ class: "mammal",
21681
+ defaultForm: "group",
21682
+ minGroupSize: 2,
21683
+ incompatibleWith: ["rabbit"]
21684
+ }
21685
+ ];
21686
+ var animalSchema = createSelectSchema(animals, {
21687
+ ids: animalIdsSchema
21444
21688
  });
21445
- var houseValueSchema = object({
21446
- rows: array(houseValueRowSchema),
21447
- totals: object({
21448
- now: number2(),
21449
- paid: number2(),
21450
- newForOld: number2().default(0)
21451
- }),
21452
- policy: object({
21453
- documentId: string2(),
21454
- title: string2(),
21455
- insuredValue: number2(),
21456
- lastClaim: object({ kind: string2(), on: day }).nullable().default(null)
21457
- }).nullable()
21689
+ var animalSpeciesRefSchema = object({
21690
+ id: ulidSchema,
21691
+ key: string2(),
21692
+ commonName: string2(),
21693
+ latin: string2().nullable(),
21694
+ class: animalClassSchema,
21695
+ legal: animalLegalSchema,
21696
+ hibernates: boolean3()
21458
21697
  });
21459
- var upkeepMonthMarkSchema = _enum2(["done", "due", "planned", "late"]).nullable();
21460
- var houseUpkeepRoutineSchema = object({
21461
- taskId: string2(),
21698
+ var animalViewSchema = animalSchema.extend({
21462
21699
  title: string2(),
21463
- itemId: string2(),
21464
- itemTitle: string2(),
21465
- category: string2().nullable(),
21466
- months: array(upkeepMonthMarkSchema).length(12),
21467
- bookedOn: day.nullable().default(null),
21468
- itemState: string2().nullable().default(null),
21469
- certified: boolean3().default(false)
21700
+ parentId: ulidSchema.nullable(),
21701
+ species: animalSpeciesRefSchema.nullable(),
21702
+ memberCount: number2().int(),
21703
+ heads: number2().int(),
21704
+ createdAt: exports_coerce.date(),
21705
+ updatedAt: exports_coerce.date()
21470
21706
  });
21471
- var houseUpkeepNeedSchema = object({
21472
- id: string2(),
21473
- kind: _enum2(["supply", "loan"]).default("supply"),
21474
- title: string2(),
21707
+ var nodeRefSchema = object({ id: ulidSchema, title: string2() });
21708
+ var animalHabitSchema = nodeRefSchema.extend({ doneToday: boolean3() });
21709
+ var animalSupplySchema = nodeRefSchema.extend({
21475
21710
  quantity: number2(),
21476
21711
  unit: string2().nullable(),
21477
- low: boolean3(),
21478
- itemTitle: string2(),
21479
- who: string2().nullable().default(null),
21480
- dueBack: day.nullable().default(null)
21712
+ lowStock: boolean3(),
21713
+ dailyUse: number2().nullable(),
21714
+ perHead: boolean3(),
21715
+ daysLeft: number2().int().nullable(),
21716
+ full: number2().nullable(),
21717
+ onList: string2().nullable()
21481
21718
  });
21482
- var houseUpkeepYearSchema = object({
21483
- year: number2().int(),
21484
- currentMonth: number2().int().min(1).max(12).nullable(),
21485
- routines: array(houseUpkeepRoutineSchema),
21486
- needsMonth: number2().int().min(1).max(12),
21487
- needs: array(houseUpkeepNeedSchema),
21488
- spent: object({
21489
- total: number2(),
21490
- repairs: number2(),
21491
- services: number2(),
21492
- parts: number2().default(0)
21493
- })
21719
+ var animalDayCountSchema = object({ day: string2(), count: number2().int() });
21720
+ var animalWeightPointSchema = object({
21721
+ day: string2(),
21722
+ grams: number2(),
21723
+ at: exports_coerce.date()
21494
21724
  });
21495
- var houseUpkeepYearQuerySchema = object({ year: exports_coerce.number().int().min(2000).max(2100).optional() }).strict();
21496
-
21497
- // ../../packages/schema/src/contracts/agent-chat.ts
21498
- var agentConnectionSourceSchema = _enum2(["space", "env"]);
21499
- var agentGatewayStatusSchema = _enum2(["connected", "offline", "not_connected"]);
21500
- var agentGatewayStateSchema = object({
21501
- status: agentGatewayStatusSchema,
21502
- connectedAt: exports_coerce.date().nullable(),
21503
- seenAt: exports_coerce.date().nullable(),
21504
- disconnectedAt: exports_coerce.date().nullable()
21725
+ var animalFileSchema = object({
21726
+ id: ulidSchema,
21727
+ name: string2(),
21728
+ mime: string2(),
21729
+ size: number2().int(),
21730
+ createdAt: exports_coerce.date()
21505
21731
  });
21506
- var agentConnectionSchema = object({
21507
- connected: boolean3(),
21508
- source: agentConnectionSourceSchema.nullable(),
21509
- endpoint: string2().nullable(),
21510
- model: string2().nullable(),
21511
- hasKey: boolean3(),
21512
- agentId: string2().nullable(),
21513
- agentName: string2().nullable().default(null),
21514
- autoFile: boolean3(),
21515
- updatedAt: exports_coerce.date().nullable(),
21516
- gateway: agentGatewayStateSchema.nullable().default(null)
21732
+ var animalVetSchema = nodeRefSchema.extend({ role: string2().nullable() });
21733
+ var animalPaperSchema = nodeRefSchema.extend({
21734
+ status: _enum2(documentStatus.enumValues),
21735
+ reference: string2().nullable()
21517
21736
  });
21518
- var agentEndpointSchema = string2().trim().max(2000).url().refine((value) => /^https?:\/\//i.test(value), "endpoint must be an http(s) URL");
21519
- var saveAgentConnectionInputSchema = object({
21520
- endpoint: agentEndpointSchema.nullable(),
21521
- apiKey: string2().trim().min(1).max(4000).nullable().optional(),
21522
- model: string2().trim().min(1).max(200).nullable().optional(),
21523
- agentId: string2().trim().min(1).max(64).nullable().optional(),
21524
- autoFile: boolean3().optional()
21525
- }).strict().refine((input) => input.endpoint !== null || Boolean(input.agentId), {
21526
- message: "a connection without an endpoint names its agent",
21527
- path: ["agentId"]
21737
+ var animalLinksSchema = object({
21738
+ place: nodeRefSchema.nullable(),
21739
+ vets: array(animalVetSchema),
21740
+ cameFrom: nodeRefSchema.nullable(),
21741
+ habits: array(animalHabitSchema),
21742
+ supplies: array(animalSupplySchema),
21743
+ papers: array(animalPaperSchema),
21744
+ files: array(animalFileSchema),
21745
+ healthVisits: object({ count: number2().int(), lastAt: exports_coerce.date().nullable() }),
21746
+ assets: array(nodeRefSchema.extend({ location: string2().nullable() })),
21747
+ companions: array(nodeRefSchema)
21528
21748
  });
21529
- var agentPageContextSchema = object({
21530
- route: string2().trim().min(1).max(500).startsWith("/"),
21531
- nodeId: string2().trim().min(1).max(64).nullable(),
21532
- focusArea: object({
21533
- id: string2().trim().min(1).max(64),
21534
- title: string2().trim().min(1).max(200)
21535
- }).nullish()
21536
- }).strict();
21537
- var echoDeviceSchema = _enum2(["phone", "desktop"]);
21538
- var agentChatInputSchema = object({
21539
- message: string2().trim().max(8000),
21540
- context: agentPageContextSchema,
21541
- threadId: string2().trim().min(1).max(64).optional(),
21542
- steer: boolean3().optional(),
21543
- attachments: array(string2().trim().min(1).max(64)).max(20).optional(),
21544
- replyTo: string2().trim().min(1).max(64).optional(),
21545
- device: echoDeviceSchema.optional()
21546
- }).strict().refine((input) => input.message.length > 0 || (input.attachments?.length ?? 0) > 0, {
21547
- message: "write something or attach a file",
21548
- path: ["message"]
21749
+ var animalPapersCheckSchema = object({
21750
+ needed: string2(),
21751
+ onFile: boolean3()
21549
21752
  });
21550
- var agentChatStopInputSchema = object({ threadId: string2().trim().min(1).max(64) }).strict();
21551
- var agentChatStopResultSchema = object({ stop: _enum2(["sent", "offline"]) });
21552
- var agentChatEventSchema = discriminatedUnion("type", [
21753
+ var animalMemberSchema = animalViewSchema.extend({
21754
+ papersCheck: animalPapersCheckSchema.nullable()
21755
+ });
21756
+ var SHED_READING_TYPES = {
21757
+ temp: "shed.temp",
21758
+ humidity: "shed.humidity",
21759
+ heater: "shed.heater",
21760
+ water: "shed.water_pct",
21761
+ door: "shed.door",
21762
+ feeder: "shed.feed_kg",
21763
+ light: "shed.light"
21764
+ };
21765
+ var animalRoomReadingSchema = object({
21766
+ kind: _enum2(Object.keys(SHED_READING_TYPES)),
21767
+ value: number2().nullable(),
21768
+ unit: string2().nullable(),
21769
+ text: string2().nullable(),
21770
+ detail: string2().nullish(),
21771
+ device: string2().nullish(),
21772
+ at: exports_coerce.date()
21773
+ });
21774
+ var animalRoomAlertSchema = object({
21775
+ id: string2(),
21776
+ at: exports_coerce.date(),
21777
+ text: string2(),
21778
+ detail: string2().nullable(),
21779
+ source: _enum2(["camera", "power", "other"])
21780
+ });
21781
+ var animalRoomSchema = object({
21782
+ place: nodeRefSchema,
21783
+ readings: array(animalRoomReadingSchema),
21784
+ temperature24h: array(object({ at: exports_coerce.date(), value: number2() })),
21785
+ alerts: array(animalRoomAlertSchema)
21786
+ });
21787
+ var animalDetailSchema = animalViewSchema.extend({
21788
+ group: nodeRefSchema.nullable(),
21789
+ members: array(animalMemberSchema),
21790
+ links: animalLinksSchema,
21791
+ weights: array(animalWeightPointSchema),
21792
+ latestLength: object({ mm: number2(), at: exports_coerce.date() }).nullable(),
21793
+ eggs: array(animalDayCountSchema),
21794
+ periods: array(periodViewSchema),
21795
+ keyDates: array(keyDateViewSchema),
21796
+ papersCheck: animalPapersCheckSchema.nullable(),
21797
+ room: animalRoomSchema.nullable()
21798
+ });
21799
+ var titleSchema = string2().trim().min(1).max(120);
21800
+ var shortText = (max) => string2().trim().min(1).max(max);
21801
+ var idList = array(ulidSchema).max(20);
21802
+ var animalFieldsSchema = object({
21803
+ title: titleSchema,
21804
+ form: animalFormSchema,
21805
+ speciesId: ulidSchema.nullish(),
21806
+ speciesKey: speciesKeySchema,
21807
+ breed: shortText(120).nullish(),
21808
+ sex: animalSexSchema.nullish(),
21809
+ bornOn: animalBornOnSchema.nullish(),
21810
+ bornApprox: boolean3(),
21811
+ acquiredOn: keyDateDaySchema.nullish(),
21812
+ acquiredHow: animalAcquiredHowSchema.nullish(),
21813
+ status: animalStatusSchema,
21814
+ endedOn: keyDateDaySchema.nullish(),
21815
+ endNote: shortText(500).nullish(),
21816
+ headCount: number2().int().min(0).max(1e4).nullish(),
21817
+ ids: maskedIdsSchema,
21818
+ markings: shortText(200).nullish(),
21819
+ breeding: animalBreedingSchema,
21820
+ groupId: ulidSchema.nullish(),
21821
+ areaId: ulidSchema.nullish(),
21822
+ placeId: ulidSchema.nullish(),
21823
+ vetIds: idList,
21824
+ cameFromId: ulidSchema.nullish(),
21825
+ habitIds: idList,
21826
+ supplyIds: idList,
21827
+ paperIds: idList,
21828
+ assetIds: idList
21829
+ });
21830
+ var createAnimalInputSchema = animalFieldsSchema.partial().required({ title: true }).extend({ id: ulidSchema }).strict();
21831
+ var updateAnimalInputSchema = animalFieldsSchema.partial().strict();
21832
+ var animalsQuerySchema = object({
21833
+ status: animalStatusSchema.optional(),
21834
+ form: animalFormSchema.optional(),
21835
+ groupId: ulidSchema.optional(),
21836
+ includeEnded: _enum2(["true", "false"]).transform((v) => v === "true").optional()
21837
+ });
21838
+ var occurredAtSchema = exports_coerce.date().optional();
21839
+ var animalLogInputSchema = discriminatedUnion("kind", [
21553
21840
  object({
21554
- type: literal("turn"),
21555
- id: string2(),
21556
- threadId: string2(),
21557
- since: string2().nullable()
21558
- }),
21559
- object({ type: literal("delta"), text: string2() }),
21560
- object({ type: literal("done") }),
21561
- object({ type: literal("error"), message: string2() }),
21841
+ kind: literal("weight"),
21842
+ value: number2().positive().max(200000),
21843
+ unit: _enum2(["g", "kg"]).default("g"),
21844
+ occurredAt: occurredAtSchema
21845
+ }).strict(),
21562
21846
  object({
21563
- type: literal("posted"),
21564
- threadId: string2(),
21565
- postId: string2(),
21566
- delivery: _enum2(["sent", "waiting"])
21567
- })
21568
- ]);
21569
- var agentChangeValueSchema = union([
21570
- string2(),
21571
- number2(),
21572
- boolean3(),
21573
- _null3(),
21574
- array(string2())
21847
+ kind: literal("length"),
21848
+ value: number2().positive().max(5000),
21849
+ occurredAt: occurredAtSchema
21850
+ }).strict(),
21851
+ object({
21852
+ kind: literal("eggs"),
21853
+ count: number2().int().min(0).max(500),
21854
+ occurredAt: occurredAtSchema
21855
+ }).strict(),
21856
+ object({
21857
+ kind: literal("note"),
21858
+ text: string2().trim().min(1).max(1000),
21859
+ occurredAt: occurredAtSchema
21860
+ }).strict()
21575
21861
  ]);
21576
- var agentChangeFieldSchema = object({
21577
- field: string2(),
21578
- before: agentChangeValueSchema,
21579
- after: agentChangeValueSchema,
21580
- beforeLabel: string2().nullable().optional(),
21581
- afterLabel: string2().nullable().optional()
21862
+ var animalVetVisitSourceSchema = _enum2(["sticker", "photo", "said"]);
21863
+ var visitTextSchema = string2().trim().min(1).max(120);
21864
+ var visitCostSchema = object({
21865
+ amount: number2().positive().max(1e5),
21866
+ currency: string2().trim().length(3).default("EUR")
21867
+ }).strict();
21868
+ var animalVetVisitInputSchema = object({
21869
+ id: ulidSchema,
21870
+ at: exports_coerce.date().optional(),
21871
+ vetContactId: ulidSchema.optional(),
21872
+ clinician: visitTextSchema.optional(),
21873
+ reason: visitTextSchema.optional(),
21874
+ vaccine: object({ name: visitTextSchema, source: animalVetVisitSourceSchema.optional() }).strict().optional(),
21875
+ dewormer: visitTextSchema.optional(),
21876
+ weight: object({
21877
+ value: number2().positive().max(200000),
21878
+ unit: _enum2(["g", "kg"]).default("kg")
21879
+ }).strict().optional(),
21880
+ nextDates: array(object({
21881
+ id: ulidSchema,
21882
+ label: visitTextSchema,
21883
+ date: string2().regex(/^\d{4}-\d{2}-\d{2}$/, "expected YYYY-MM-DD")
21884
+ }).strict()).max(5).default([]),
21885
+ files: array(object({ id: ulidSchema, name: visitTextSchema.optional() }).strict()).max(5).default([]),
21886
+ cost: visitCostSchema.optional()
21887
+ }).strict();
21888
+ var animalVetVisitPatchSchema = object({
21889
+ vetContactId: ulidSchema.nullable().optional(),
21890
+ clinician: visitTextSchema.nullable().optional(),
21891
+ reason: visitTextSchema.nullable().optional(),
21892
+ vaccine: object({ name: visitTextSchema, source: animalVetVisitSourceSchema.optional() }).strict().nullable().optional(),
21893
+ dewormer: visitTextSchema.nullable().optional(),
21894
+ cost: visitCostSchema.nullable().optional()
21895
+ }).strict().refine((v) => Object.keys(v).length > 0, { message: "Change at least one field." });
21896
+ var animalVetVisitSchema = object({
21897
+ id: ulidSchema,
21898
+ animal: object({
21899
+ id: ulidSchema,
21900
+ title: string2(),
21901
+ speciesKey: string2().nullable(),
21902
+ speciesClass: animalClassSchema.nullable()
21903
+ }),
21904
+ at: exports_coerce.date(),
21905
+ vet: nodeRefSchema.nullable(),
21906
+ clinician: string2().nullable(),
21907
+ reason: string2().nullable(),
21908
+ vaccine: object({ name: string2(), source: animalVetVisitSourceSchema.nullable() }).nullable(),
21909
+ dewormer: string2().nullable(),
21910
+ weight: object({
21911
+ grams: number2(),
21912
+ deltaGrams: number2().nullable(),
21913
+ since: string2().nullable()
21914
+ }).nullable(),
21915
+ keyDates: array(object({ id: string2(), label: string2(), date: string2() })),
21916
+ files: array(object({ id: string2(), name: string2() })),
21917
+ cost: object({ amount: number2(), currency: string2() }).nullable(),
21918
+ byAgent: boolean3(),
21919
+ undone: boolean3()
21582
21920
  });
21583
- var agentChangeSchema = object({
21584
- entity: changeEntitySchema,
21921
+ var animalTimelineEntrySchema = object({
21585
21922
  id: string2(),
21586
- op: changeOpSchema,
21587
- changedAt: exports_coerce.date(),
21588
- title: string2().nullable(),
21589
- actor: actorRefSchema,
21590
- cursor: string2().optional(),
21591
- fields: array(agentChangeFieldSchema).optional(),
21592
- checkIn: object({
21593
- value: number2(),
21594
- unit: string2().nullable(),
21595
- measurementType: habitMeasurementTypeSchema
21596
- }).optional()
21923
+ at: exports_coerce.date(),
21924
+ kind: _enum2([
21925
+ "weight",
21926
+ "length",
21927
+ "eggs",
21928
+ "note",
21929
+ "vet_visit",
21930
+ "period_started",
21931
+ "period_ended",
21932
+ "key_date"
21933
+ ]),
21934
+ animalId: ulidSchema,
21935
+ animalTitle: string2(),
21936
+ value: number2().nullable(),
21937
+ text: string2().nullable(),
21938
+ byAgent: boolean3().default(false)
21597
21939
  });
21598
- var agentChangesPageSchema = object({
21599
- data: array(agentChangeSchema),
21600
- nextCursor: string2()
21940
+ var animalTimelineQuerySchema = object({
21941
+ days: exports_coerce.number().int().min(1).max(3650).default(90)
21601
21942
  });
21602
- var agentChangesQuerySchema = object({
21603
- since: string2().refine((s) => s === "now" || /^\d+-\d+$/.test(s), {
21604
- message: "since must be a cursor from a prior page's nextCursor, or 'now'"
21943
+ var animalEggsTodaySchema = object({
21944
+ animalId: ulidSchema,
21945
+ title: string2(),
21946
+ today: number2().int(),
21947
+ heads: number2().int(),
21948
+ last7: array(animalDayCountSchema)
21949
+ });
21950
+ var animalsOverviewSchema = object({
21951
+ animals: array(animalViewSchema),
21952
+ today: object({
21953
+ day: string2(),
21954
+ eggs: array(animalEggsTodaySchema),
21955
+ supplies: array(animalSupplySchema),
21956
+ habits: array(animalHabitSchema)
21605
21957
  }),
21606
- node: string2().trim().min(1).max(64).optional()
21958
+ comingUp: array(keyDateViewSchema.extend({ vet: string2().nullable() })),
21959
+ periods: array(periodViewSchema)
21607
21960
  });
21608
- var agentConfirmationKindSchema = _enum2(["delete", "cancel", "google", "orca", "bulk"]);
21609
- var agentConfirmationStatusSchema = _enum2([
21610
- "pending",
21611
- "confirmed",
21612
- "done",
21613
- "failed",
21614
- "declined"
21615
- ]);
21616
- var agentConfirmationItemSchema = object({
21617
- id: string2(),
21618
- title: string2().nullable(),
21619
- area: string2().nullable().optional(),
21620
- dueAt: exports_coerce.date().nullable().optional()
21961
+ var animalHolidayModeSchema = object({
21962
+ popHole: boolean3(),
21963
+ heater: boolean3(),
21964
+ alerts: boolean3(),
21965
+ dailyPhoto: boolean3(),
21966
+ feedReorder: boolean3()
21621
21967
  });
21622
- var agentConfirmationSchema = object({
21623
- id: string2(),
21624
- kind: agentConfirmationKindSchema,
21625
- summary: string2(),
21626
- items: array(agentConfirmationItemSchema),
21627
- method: string2(),
21628
- path: string2(),
21629
- status: agentConfirmationStatusSchema,
21630
- agent: object({ id: string2(), name: string2().nullable() }),
21631
- createdAt: exports_coerce.date(),
21632
- decidedAt: exports_coerce.date().nullable()
21968
+ var animalHandoverRuleSchema = object({
21969
+ sitter: string2().trim().min(1).max(120).optional(),
21970
+ houseNote: string2().trim().min(1).max(300).optional(),
21971
+ holidayMode: animalHolidayModeSchema.partial().optional(),
21972
+ share: object({ tokenHash: string2(), until: string2() }).optional(),
21973
+ agentNote: string2().trim().min(1).max(500).optional()
21974
+ }).passthrough();
21975
+ var animalHandoverQuerySchema = object({ periodId: ulidSchema.optional() });
21976
+ var animalHandoverTripSchema = object({
21977
+ periodId: ulidSchema.nullable(),
21978
+ title: string2(),
21979
+ from: string2(),
21980
+ to: string2(),
21981
+ sitter: string2().nullable(),
21982
+ houseNote: string2().nullable(),
21983
+ holidayMode: animalHolidayModeSchema,
21984
+ sharedUntil: string2().nullable(),
21985
+ agentNote: string2().nullable(),
21986
+ calendar: string2().nullable()
21633
21987
  });
21634
- var agentUndoInputSchema = object({
21635
- id: string2().trim().min(1).max(64),
21636
- since: string2().regex(/^\d+-\d+$/, "since must be a change-feed cursor")
21637
- }).strict();
21638
- var agentUndoResultSchema = object({
21639
- id: string2(),
21640
- undone: _enum2(["removed", "restored"])
21988
+ var animalHandoverAnimalSchema = object({
21989
+ id: ulidSchema,
21990
+ title: string2(),
21991
+ form: animalFormSchema,
21992
+ heads: number2().int(),
21993
+ species: string2().nullable(),
21994
+ speciesKey: string2().nullable(),
21995
+ speciesClass: animalClassSchema.nullable(),
21996
+ asleep: boolean3(),
21997
+ steps: array(string2()),
21998
+ aside: string2().nullable()
21641
21999
  });
21642
- var agentRedoResultSchema = object({
21643
- id: string2(),
21644
- redone: literal(true)
22000
+ var animalHandoverContactSchema = object({
22001
+ id: ulidSchema,
22002
+ title: string2(),
22003
+ kind: _enum2(["vet", "member"]),
22004
+ label: string2().nullable(),
22005
+ phone: string2().nullable()
21645
22006
  });
21646
- var agentFilingSchema = object({
21647
- confident: boolean3().default(false),
21648
- areaId: string2().nullable().optional(),
21649
- owner: string2().nullable().optional(),
21650
- date: string2().regex(/^\d{4}-\d{2}-\d{2}$/).nullable().optional()
22007
+ var animalHandoverSupplySchema = animalSupplySchema.extend({
22008
+ lastsTrip: boolean3().nullable()
21651
22009
  });
21652
-
21653
- // ../../packages/schema/src/contracts/agent-gateway.ts
21654
- var AGENT_GATEWAY_VERSION = 1;
21655
- var AGENT_GATEWAY_MAX_FRAME_BYTES = 1024 * 1024;
21656
- var threadSlugSchema = string2().regex(/^[a-z0-9][a-z0-9-]{0,39}$/, "a thread slug is lower-case, like `build`");
21657
- var postLevelSchema = _enum2(["needs_you", "told", "for_later", "silent"]);
21658
- var postKindSchema = _enum2(["message", "brief", "card", "run"]);
21659
- var runStatusSchema = _enum2(["running", "needs_you", "done", "failed", "stopped"]);
21660
- var externalIdSchema = string2().min(1).max(200).regex(/^[\x21-\x7e]+$/, "printable ASCII without spaces");
21661
- var AGENT_POST_TEXT_MAX = 64000;
21662
- var postTextSchema = string2().max(AGENT_POST_TEXT_MAX);
21663
- var briefVerbSchema = object({
21664
- label: string2().trim().min(1).max(24),
21665
- href: string2().max(2000).regex(/^(\/(?!\/)|https:\/\/)/, "a path in do (`/tasks`) or an https link").optional(),
21666
- say: string2().trim().min(1).max(500).optional()
21667
- }).strict().refine((v) => v.href === undefined !== (v.say === undefined), {
21668
- message: "a verb has either href or say"
22010
+ var animalHandoverHabitSchema = nodeRefSchema.extend({ restsThroughTrip: boolean3() });
22011
+ var animalHandoverSchema = object({
22012
+ trip: animalHandoverTripSchema.nullable(),
22013
+ areaId: ulidSchema.nullable(),
22014
+ animals: array(animalHandoverAnimalSchema),
22015
+ contacts: array(animalHandoverContactSchema),
22016
+ supplies: array(animalHandoverSupplySchema),
22017
+ habits: array(animalHandoverHabitSchema),
22018
+ sensors: boolean3(),
22019
+ generatedAt: exports_coerce.date()
21669
22020
  });
21670
- var briefRowSchema = object({
21671
- text: string2().trim().min(1).max(200),
21672
- meta: string2().trim().max(200).optional(),
21673
- icon: string2().max(24).optional(),
21674
- verb: briefVerbSchema.optional()
21675
- }).strict();
21676
- var BRIEF_ROWS_MAX = 8;
21677
- var briefSchema = object({
21678
- label: string2().trim().min(1).max(40),
21679
- title: string2().trim().min(1).max(200),
21680
- rows: array(briefRowSchema).max(BRIEF_ROWS_MAX).default([])
22021
+ var animalHolidayModeInputSchema = animalHolidayModeSchema.partial().extend({ periodId: ulidSchema }).strict().refine((v) => Object.keys(v).length > 1, { message: "Turn at least one switch." });
22022
+ var animalHandoverShareInputSchema = object({ periodId: ulidSchema }).strict();
22023
+ var animalHandoverShareSchema = object({
22024
+ token: string2(),
22025
+ path: string2(),
22026
+ until: string2()
22027
+ });
22028
+ var animalLostCardInputSchema = object({
22029
+ photoFileId: ulidSchema.nullish(),
22030
+ phone: string2().trim().regex(/^\+?[0-9][0-9 ()./-]{4,30}$/, "A phone number: digits, spaces, + ( ) . / -").nullish(),
22031
+ showChipped: boolean3().optional(),
22032
+ note: string2().trim().min(1).max(200).nullish()
21681
22033
  }).strict();
21682
- var gatewayMemberSchema = object({
21683
- id: string2().min(1),
22034
+ var animalLostCardPhotoSchema = object({ id: ulidSchema, name: string2() });
22035
+ var animalLostCardPublicSchema = object({
21684
22036
  name: string2(),
21685
- role: baseRoleSchema
22037
+ speciesKey: string2().nullable(),
22038
+ kind: string2().nullable(),
22039
+ missing: boolean3(),
22040
+ hasPhoto: boolean3(),
22041
+ phone: string2().nullable(),
22042
+ chipped: boolean3(),
22043
+ note: string2().nullable()
21686
22044
  });
21687
- var gatewayThreadSchema = object({
21688
- id: ulidSchema,
21689
- memberId: string2().min(1),
21690
- slug: threadSlugSchema.nullable(),
21691
- title: string2().nullable(),
21692
- standing: boolean3(),
21693
- deleted: boolean3().optional()
22045
+ var animalLostCardStateSchema = object({
22046
+ card: object({
22047
+ path: string2(),
22048
+ photoFileId: ulidSchema.nullable(),
22049
+ phone: string2().nullable(),
22050
+ showChipped: boolean3(),
22051
+ note: string2().nullable(),
22052
+ since: exports_coerce.date(),
22053
+ preview: animalLostCardPublicSchema
22054
+ }).nullable(),
22055
+ photos: array(animalLostCardPhotoSchema),
22056
+ chipOnFile: boolean3()
22057
+ });
22058
+
22059
+ // ../../packages/schema/src/contracts/sensors.ts
22060
+ var sensorProviderValues = ["home_assistant", "unifi"];
22061
+ var sensorProviderSchema = _enum2(sensorProviderValues);
22062
+ var sensorTargetValues = ["place", "asset"];
22063
+ var sensorTargetSchema = _enum2(sensorTargetValues);
22064
+ var PLACE_SENSOR_READINGS = Object.keys(SHED_READING_TYPES);
22065
+ var ASSET_READING_TYPES = {
22066
+ state: "asset.state",
22067
+ power: "asset.power",
22068
+ energy: "asset.energy"
22069
+ };
22070
+ var ASSET_SENSOR_READINGS = Object.keys(ASSET_READING_TYPES);
22071
+ var sensorReadingValues = [
22072
+ ...new Set([...PLACE_SENSOR_READINGS, ...ASSET_SENSOR_READINGS])
22073
+ ];
22074
+ var sensorReadingSchema = _enum2(sensorReadingValues);
22075
+ var SENSOR_DATAPOINT_TYPES = [
22076
+ ...Object.values(SHED_READING_TYPES),
22077
+ ...Object.values(ASSET_READING_TYPES)
22078
+ ];
22079
+ var homeAssistantLinkInputSchema = object({
22080
+ baseUrl: string2().trim().url().refine((u) => /^https?:\/\//i.test(u), "must start with http:// or https://"),
22081
+ token: string2().trim().min(1).max(2000)
22082
+ }).strict();
22083
+ var homeAssistantStatusSchema = object({
22084
+ linked: boolean3(),
22085
+ host: string2().nullable(),
22086
+ links: number2().int().nonnegative(),
22087
+ lastReadingAt: string2().nullable()
22088
+ });
22089
+ var homeAssistantErrorValues = ["unauthorized", "unavailable", "bad_response"];
22090
+ var homeAssistantErrorSchema = _enum2(homeAssistantErrorValues);
22091
+ var sensorSyncResultSchema = object({
22092
+ syncedAt: string2(),
22093
+ entities: number2().int().nonnegative(),
22094
+ written: number2().int().nonnegative(),
22095
+ skipped: number2().int().nonnegative(),
22096
+ missing: array(string2()),
22097
+ error: homeAssistantErrorSchema.nullable()
21694
22098
  });
21695
- var AGENT_ATTACHMENT_MAX_BYTES = 25 * 1024 * 1024;
21696
- var AGENT_ATTACHMENTS_MAX = 20;
21697
- var attachmentKindSchema = _enum2(["image", "voice", "audio", "video", "file"]);
21698
- var gatewayAttachmentSchema = object({
22099
+ var sensorLinkRowSchema = createSelectSchema(sensorLinks, {
22100
+ createdAt: exports_coerce.date(),
22101
+ updatedAt: exports_coerce.date()
22102
+ });
22103
+ var sensorLinkSchema = object({
21699
22104
  id: ulidSchema,
21700
- kind: attachmentKindSchema,
21701
- mime: string2().min(1),
22105
+ provider: sensorProviderSchema,
22106
+ externalId: string2(),
22107
+ nodeId: ulidSchema,
22108
+ target: sensorTargetSchema,
22109
+ reading: string2(),
22110
+ label: string2().nullable(),
22111
+ nodeTitle: string2(),
22112
+ createdAt: exports_coerce.date()
22113
+ });
22114
+ var createSensorLinkInputSchema = object({
22115
+ provider: sensorProviderSchema.default("home_assistant"),
22116
+ externalId: string2().trim().min(1).max(255),
22117
+ nodeId: ulidSchema,
22118
+ reading: sensorReadingSchema,
22119
+ label: string2().trim().min(1).max(200).nullish()
22120
+ }).strict();
22121
+ var sensorLinksQuerySchema = object({ nodeId: ulidSchema.optional() });
22122
+ var homeAssistantEntitySchema = object({
22123
+ entityId: string2(),
21702
22124
  name: string2(),
21703
- size: number2().int().nonnegative(),
21704
- durationMs: number2().int().nonnegative().optional(),
21705
- transcript: string2().optional()
22125
+ domain: string2(),
22126
+ state: string2(),
22127
+ unit: string2().nullable(),
22128
+ deviceClass: string2().nullable(),
22129
+ lastUpdated: string2(),
22130
+ suggested: object({ place: string2().nullable(), asset: string2().nullable() }),
22131
+ link: sensorLinkSchema.nullable()
21706
22132
  });
21707
- var AGENT_VOICE_MAX_MS = 5 * 60 * 1000;
22133
+ var assetReadingSchema = object({
22134
+ kind: _enum2(ASSET_SENSOR_READINGS),
22135
+ value: number2().nullable(),
22136
+ unit: string2().nullable(),
22137
+ text: string2().nullable(),
22138
+ device: string2().nullable(),
22139
+ at: exports_coerce.date()
22140
+ });
22141
+
22142
+ // ../../packages/schema/src/contracts/house.ts
22143
+ var day = string2().regex(/^\d{4}-\d{2}-\d{2}$/, "must be a calendar day (YYYY-MM-DD)");
22144
+ var houseBrokenSchema = object({
22145
+ item: collectionItemViewSchema,
22146
+ repair: taskViewSchema.nullable()
22147
+ });
22148
+ var houseUpkeepSoonSchema = object({
22149
+ task: taskViewSchema,
22150
+ itemId: string2(),
22151
+ itemTitle: string2(),
22152
+ nextOn: day.nullable(),
22153
+ placeTitle: string2().nullable().default(null),
22154
+ lastOn: day.nullable().default(null)
22155
+ });
22156
+ var housePlaceTileSchema = object({
22157
+ id: string2(),
22158
+ title: string2(),
22159
+ kind: string2(),
22160
+ gardenFeatureId: string2().nullable(),
22161
+ thingCount: number2().int().min(0)
22162
+ });
22163
+ var houseOverviewSchema = object({
22164
+ broken: array(houseBrokenSchema),
22165
+ upkeepSoon: array(houseUpkeepSoonSchema),
22166
+ places: array(housePlaceTileSchema),
22167
+ thingCount: number2().int().min(0),
22168
+ upkeepCount: number2().int().min(0),
22169
+ toolCount: number2().int().min(0),
22170
+ animalCount: number2().int().min(0),
22171
+ toConfirm: number2().int().min(0).default(0)
22172
+ });
22173
+ var upkeepScheduleSchema = object({
22174
+ every: number2().int().min(1).max(365),
22175
+ unit: _enum2(["day", "week", "month", "year"]),
22176
+ startOn: day.optional()
22177
+ }).strict();
22178
+ var setAssetUpkeepInputSchema = object({
22179
+ title: string2().trim().min(1).max(200),
22180
+ schedule: upkeepScheduleSchema,
22181
+ placeId: ulidSchema.nullish(),
22182
+ areaId: ulidSchema.nullish(),
22183
+ nextStep: string2().trim().max(500).nullish()
22184
+ }).strict();
22185
+ var fileAssetInputSchema = object({
22186
+ id: ulidSchema.optional(),
22187
+ title: string2().trim().min(1).max(200),
22188
+ placeId: ulidSchema.nullish(),
22189
+ areaId: ulidSchema.nullish(),
22190
+ status: _enum2(["want", "have"]).optional(),
22191
+ facet: record(string2(), unknown()).optional(),
22192
+ tags: array(string2().min(1).max(60)).max(20).optional(),
22193
+ fileIds: array(ulidSchema).max(20).optional(),
22194
+ match: boolean3().default(true),
22195
+ upkeep: setAssetUpkeepInputSchema.optional(),
22196
+ fault: object({
22197
+ note: string2().trim().min(1).max(2000),
22198
+ repairTitle: string2().trim().min(1).max(200).optional()
22199
+ }).strict().optional()
22200
+ }).strict();
22201
+ var houseReceiptSchema = object({
22202
+ itemId: string2(),
22203
+ created: boolean3(),
22204
+ before: object({
22205
+ facet: record(string2(), unknown()).nullable(),
22206
+ placeId: string2().nullable(),
22207
+ status: string2()
22208
+ }).nullable(),
22209
+ taskIds: array(string2()),
22210
+ entryIds: array(string2()),
22211
+ files: array(object({ id: string2(), previousOwnerId: string2().nullable() }))
22212
+ });
22213
+ var houseWriteResultSchema = object({
22214
+ item: collectionItemDetailSchema,
22215
+ receipt: houseReceiptSchema
22216
+ });
22217
+ var undoHouseWriteInputSchema = houseReceiptSchema.strict();
22218
+ var houseTrailStepSchema = object({ id: string2(), title: string2() });
22219
+ var houseAssetPartSchema = object({
22220
+ id: string2(),
22221
+ title: string2(),
22222
+ quantity: number2(),
22223
+ unit: string2().nullable(),
22224
+ lowStockThreshold: number2().nullable()
22225
+ });
22226
+ var houseAssetLinkSchema = object({
22227
+ nodeId: string2(),
22228
+ title: string2(),
22229
+ type: string2(),
22230
+ kind: string2(),
22231
+ direction: _enum2(["in", "out"]),
22232
+ label: string2().nullable().default(null),
22233
+ context: string2().nullable().default(null),
22234
+ at: exports_coerce.date().nullable().default(null),
22235
+ timed: boolean3().default(false)
22236
+ });
22237
+ var houseAssetSchema = object({
22238
+ item: collectionItemDetailSchema,
22239
+ trail: array(houseTrailStepSchema),
22240
+ parts: array(houseAssetPartSchema),
22241
+ linked: array(houseAssetLinkSchema),
22242
+ warrantyUntil: day.nullable(),
22243
+ visibility: _enum2(NODE_VISIBILITY_VALUES).default("space"),
22244
+ readings: array(assetReadingSchema).default([])
22245
+ });
22246
+ var setAssetVisibilityInputSchema = object({ visibility: _enum2(NODE_VISIBILITY_VALUES) }).strict();
22247
+ var linkAssetPartInputSchema = object({ inventoryItemId: ulidSchema }).strict();
22248
+ var lendAssetInputSchema = object({
22249
+ direction: _enum2(["lent", "borrowed"]),
22250
+ who: string2().trim().min(1).max(200),
22251
+ contactId: ulidSchema.nullish(),
22252
+ since: day.optional(),
22253
+ dueBack: day.nullish(),
22254
+ note: string2().trim().max(500).nullish()
22255
+ }).strict();
22256
+ var returnAssetInputSchema = object({
22257
+ on: day.optional(),
22258
+ note: string2().trim().max(500).nullish()
22259
+ }).strict();
22260
+ var houseValueProofSchema = _enum2(["receipt_photo", "receipt", "photo", "none"]);
22261
+ var houseValueRowSchema = object({
22262
+ id: string2(),
22263
+ title: string2(),
22264
+ model: string2().nullable(),
22265
+ placeId: string2().nullable(),
22266
+ placeTitle: string2().nullable(),
22267
+ placeGroup: string2().nullable().default(null),
22268
+ withHouse: boolean3().default(false),
22269
+ paidApprox: boolean3().default(false),
22270
+ borrowedFrom: string2().nullable().default(null),
22271
+ bought: day.nullable(),
22272
+ paid: number2().nullable(),
22273
+ now: number2().nullable(),
22274
+ nowSource: string2().nullable(),
22275
+ proof: houseValueProofSchema,
22276
+ excluded: boolean3(),
22277
+ visibility: _enum2(["space", "owner"])
22278
+ });
22279
+ var houseValueSchema = object({
22280
+ rows: array(houseValueRowSchema),
22281
+ totals: object({
22282
+ now: number2(),
22283
+ paid: number2(),
22284
+ newForOld: number2().default(0)
22285
+ }),
22286
+ policy: object({
22287
+ documentId: string2(),
22288
+ title: string2(),
22289
+ insuredValue: number2(),
22290
+ lastClaim: object({ kind: string2(), on: day }).nullable().default(null)
22291
+ }).nullable()
22292
+ });
22293
+ var upkeepMonthMarkSchema = _enum2(["done", "due", "planned", "late"]).nullable();
22294
+ var houseUpkeepRoutineSchema = object({
22295
+ taskId: string2(),
22296
+ title: string2(),
22297
+ itemId: string2(),
22298
+ itemTitle: string2(),
22299
+ category: string2().nullable(),
22300
+ months: array(upkeepMonthMarkSchema).length(12),
22301
+ bookedOn: day.nullable().default(null),
22302
+ itemState: string2().nullable().default(null),
22303
+ certified: boolean3().default(false)
22304
+ });
22305
+ var houseUpkeepNeedSchema = object({
22306
+ id: string2(),
22307
+ kind: _enum2(["supply", "loan"]).default("supply"),
22308
+ title: string2(),
22309
+ quantity: number2(),
22310
+ unit: string2().nullable(),
22311
+ low: boolean3(),
22312
+ itemTitle: string2(),
22313
+ who: string2().nullable().default(null),
22314
+ dueBack: day.nullable().default(null)
22315
+ });
22316
+ var houseUpkeepYearSchema = object({
22317
+ year: number2().int(),
22318
+ currentMonth: number2().int().min(1).max(12).nullable(),
22319
+ routines: array(houseUpkeepRoutineSchema),
22320
+ needsMonth: number2().int().min(1).max(12),
22321
+ needs: array(houseUpkeepNeedSchema),
22322
+ spent: object({
22323
+ total: number2(),
22324
+ repairs: number2(),
22325
+ services: number2(),
22326
+ parts: number2().default(0)
22327
+ })
22328
+ });
22329
+ var houseUpkeepYearQuerySchema = object({ year: exports_coerce.number().int().min(2000).max(2100).optional() }).strict();
22330
+
22331
+ // ../../packages/schema/src/contracts/agent-chat.ts
22332
+ var agentConnectionSourceSchema = _enum2(["space", "env"]);
22333
+ var agentGatewayStatusSchema = _enum2(["connected", "offline", "not_connected"]);
22334
+ var agentGatewayStateSchema = object({
22335
+ status: agentGatewayStatusSchema,
22336
+ connectedAt: exports_coerce.date().nullable(),
22337
+ seenAt: exports_coerce.date().nullable(),
22338
+ disconnectedAt: exports_coerce.date().nullable()
22339
+ });
22340
+ var agentConnectionSchema = object({
22341
+ connected: boolean3(),
22342
+ source: agentConnectionSourceSchema.nullable(),
22343
+ endpoint: string2().nullable(),
22344
+ model: string2().nullable(),
22345
+ hasKey: boolean3(),
22346
+ agentId: string2().nullable(),
22347
+ agentName: string2().nullable().default(null),
22348
+ autoFile: boolean3(),
22349
+ updatedAt: exports_coerce.date().nullable(),
22350
+ gateway: agentGatewayStateSchema.nullable().default(null)
22351
+ });
22352
+ var agentEndpointSchema = string2().trim().max(2000).url().refine((value) => /^https?:\/\//i.test(value), "endpoint must be an http(s) URL");
22353
+ var saveAgentConnectionInputSchema = object({
22354
+ endpoint: agentEndpointSchema.nullable(),
22355
+ apiKey: string2().trim().min(1).max(4000).nullable().optional(),
22356
+ model: string2().trim().min(1).max(200).nullable().optional(),
22357
+ agentId: string2().trim().min(1).max(64).nullable().optional(),
22358
+ autoFile: boolean3().optional()
22359
+ }).strict().refine((input) => input.endpoint !== null || Boolean(input.agentId), {
22360
+ message: "a connection without an endpoint names its agent",
22361
+ path: ["agentId"]
22362
+ });
22363
+ var agentPageContextSchema = object({
22364
+ route: string2().trim().min(1).max(500).startsWith("/"),
22365
+ nodeId: string2().trim().min(1).max(64).nullable(),
22366
+ focusArea: object({
22367
+ id: string2().trim().min(1).max(64),
22368
+ title: string2().trim().min(1).max(200)
22369
+ }).nullish()
22370
+ }).strict();
22371
+ var echoDeviceSchema = _enum2(["phone", "desktop"]);
22372
+ var agentChatInputSchema = object({
22373
+ message: string2().trim().max(8000),
22374
+ context: agentPageContextSchema,
22375
+ threadId: string2().trim().min(1).max(64).optional(),
22376
+ steer: boolean3().optional(),
22377
+ attachments: array(string2().trim().min(1).max(64)).max(20).optional(),
22378
+ replyTo: string2().trim().min(1).max(64).optional(),
22379
+ device: echoDeviceSchema.optional()
22380
+ }).strict().refine((input) => input.message.length > 0 || (input.attachments?.length ?? 0) > 0, {
22381
+ message: "write something or attach a file",
22382
+ path: ["message"]
22383
+ });
22384
+ var agentChatStopInputSchema = object({ threadId: string2().trim().min(1).max(64) }).strict();
22385
+ var agentChatStopResultSchema = object({ stop: _enum2(["sent", "offline"]) });
22386
+ var agentChatEventSchema = discriminatedUnion("type", [
22387
+ object({
22388
+ type: literal("turn"),
22389
+ id: string2(),
22390
+ threadId: string2(),
22391
+ since: string2().nullable()
22392
+ }),
22393
+ object({ type: literal("delta"), text: string2() }),
22394
+ object({ type: literal("done") }),
22395
+ object({ type: literal("error"), message: string2() }),
22396
+ object({
22397
+ type: literal("posted"),
22398
+ threadId: string2(),
22399
+ postId: string2(),
22400
+ delivery: _enum2(["sent", "waiting"])
22401
+ })
22402
+ ]);
22403
+ var agentChangeValueSchema = union([
22404
+ string2(),
22405
+ number2(),
22406
+ boolean3(),
22407
+ _null3(),
22408
+ array(string2())
22409
+ ]);
22410
+ var agentChangeFieldSchema = object({
22411
+ field: string2(),
22412
+ before: agentChangeValueSchema,
22413
+ after: agentChangeValueSchema,
22414
+ beforeLabel: string2().nullable().optional(),
22415
+ afterLabel: string2().nullable().optional()
22416
+ });
22417
+ var agentChangeSchema = object({
22418
+ entity: changeEntitySchema,
22419
+ id: string2(),
22420
+ op: changeOpSchema,
22421
+ changedAt: exports_coerce.date(),
22422
+ title: string2().nullable(),
22423
+ actor: actorRefSchema,
22424
+ cursor: string2().optional(),
22425
+ fields: array(agentChangeFieldSchema).optional(),
22426
+ checkIn: object({
22427
+ value: number2(),
22428
+ unit: string2().nullable(),
22429
+ measurementType: habitMeasurementTypeSchema
22430
+ }).optional()
22431
+ });
22432
+ var agentChangesPageSchema = object({
22433
+ data: array(agentChangeSchema),
22434
+ nextCursor: string2()
22435
+ });
22436
+ var agentChangesQuerySchema = object({
22437
+ since: string2().refine((s) => s === "now" || /^\d+-\d+$/.test(s), {
22438
+ message: "since must be a cursor from a prior page's nextCursor, or 'now'"
22439
+ }),
22440
+ node: string2().trim().min(1).max(64).optional()
22441
+ });
22442
+ var agentConfirmationKindSchema = _enum2(["delete", "cancel", "google", "orca", "bulk"]);
22443
+ var agentConfirmationStatusSchema = _enum2([
22444
+ "pending",
22445
+ "confirmed",
22446
+ "done",
22447
+ "failed",
22448
+ "declined"
22449
+ ]);
22450
+ var agentConfirmationItemSchema = object({
22451
+ id: string2(),
22452
+ title: string2().nullable(),
22453
+ area: string2().nullable().optional(),
22454
+ dueAt: exports_coerce.date().nullable().optional()
22455
+ });
22456
+ var agentConfirmationSchema = object({
22457
+ id: string2(),
22458
+ kind: agentConfirmationKindSchema,
22459
+ summary: string2(),
22460
+ items: array(agentConfirmationItemSchema),
22461
+ method: string2(),
22462
+ path: string2(),
22463
+ status: agentConfirmationStatusSchema,
22464
+ agent: object({ id: string2(), name: string2().nullable() }),
22465
+ createdAt: exports_coerce.date(),
22466
+ decidedAt: exports_coerce.date().nullable()
22467
+ });
22468
+ var agentUndoInputSchema = object({
22469
+ id: string2().trim().min(1).max(64),
22470
+ since: string2().regex(/^\d+-\d+$/, "since must be a change-feed cursor")
22471
+ }).strict();
22472
+ var agentUndoResultSchema = object({
22473
+ id: string2(),
22474
+ undone: _enum2(["removed", "restored"])
22475
+ });
22476
+ var agentRedoResultSchema = object({
22477
+ id: string2(),
22478
+ redone: literal(true)
22479
+ });
22480
+ var agentFilingSchema = object({
22481
+ confident: boolean3().default(false),
22482
+ areaId: string2().nullable().optional(),
22483
+ owner: string2().nullable().optional(),
22484
+ date: string2().regex(/^\d{4}-\d{2}-\d{2}$/).nullable().optional()
22485
+ });
22486
+
22487
+ // ../../packages/schema/src/contracts/agent-gateway.ts
22488
+ var AGENT_GATEWAY_VERSION = 1;
22489
+ var AGENT_GATEWAY_MAX_FRAME_BYTES = 1024 * 1024;
22490
+ var threadSlugSchema = string2().regex(/^[a-z0-9][a-z0-9-]{0,39}$/, "a thread slug is lower-case, like `build`");
22491
+ var postLevelSchema = _enum2(["needs_you", "told", "for_later", "silent"]);
22492
+ var postKindSchema = _enum2(["message", "brief", "card", "run"]);
22493
+ var runStatusSchema = _enum2(["running", "needs_you", "done", "failed", "stopped"]);
22494
+ var externalIdSchema = string2().min(1).max(200).regex(/^[\x21-\x7e]+$/, "printable ASCII without spaces");
22495
+ var AGENT_POST_TEXT_MAX = 64000;
22496
+ var postTextSchema = string2().max(AGENT_POST_TEXT_MAX);
22497
+ var briefVerbSchema = object({
22498
+ label: string2().trim().min(1).max(24),
22499
+ href: string2().max(2000).regex(/^(\/(?!\/)|https:\/\/)/, "a path in do (`/tasks`) or an https link").optional(),
22500
+ say: string2().trim().min(1).max(500).optional()
22501
+ }).strict().refine((v) => v.href === undefined !== (v.say === undefined), {
22502
+ message: "a verb has either href or say"
22503
+ });
22504
+ var briefRowSchema = object({
22505
+ text: string2().trim().min(1).max(200),
22506
+ meta: string2().trim().max(200).optional(),
22507
+ icon: string2().max(24).optional(),
22508
+ verb: briefVerbSchema.optional()
22509
+ }).strict();
22510
+ var BRIEF_ROWS_MAX = 8;
22511
+ var briefSchema = object({
22512
+ label: string2().trim().min(1).max(40),
22513
+ title: string2().trim().min(1).max(200),
22514
+ rows: array(briefRowSchema).max(BRIEF_ROWS_MAX).default([])
22515
+ }).strict();
22516
+ var gatewayMemberSchema = object({
22517
+ id: string2().min(1),
22518
+ name: string2(),
22519
+ role: baseRoleSchema
22520
+ });
22521
+ var gatewayThreadSchema = object({
22522
+ id: ulidSchema,
22523
+ memberId: string2().min(1),
22524
+ slug: threadSlugSchema.nullable(),
22525
+ title: string2().nullable(),
22526
+ standing: boolean3(),
22527
+ deleted: boolean3().optional()
22528
+ });
22529
+ var AGENT_ATTACHMENT_MAX_BYTES = 25 * 1024 * 1024;
22530
+ var AGENT_ATTACHMENTS_MAX = 20;
22531
+ var attachmentKindSchema = _enum2(["image", "voice", "audio", "video", "file"]);
22532
+ var gatewayAttachmentSchema = object({
22533
+ id: ulidSchema,
22534
+ kind: attachmentKindSchema,
22535
+ mime: string2().min(1),
22536
+ name: string2(),
22537
+ size: number2().int().nonnegative(),
22538
+ durationMs: number2().int().nonnegative().optional(),
22539
+ transcript: string2().optional()
22540
+ });
22541
+ var AGENT_VOICE_MAX_MS = 5 * 60 * 1000;
21708
22542
  var AGENT_TRANSCRIPT_MAX = 20000;
21709
22543
  var inboundMessageSchema = object({
21710
22544
  id: ulidSchema,
@@ -22325,6 +23159,20 @@ var healthSummarySchema = object({
22325
23159
  trends: array(healthTrendSchema).default([])
22326
23160
  });
22327
23161
  var healthSummaryQuerySchema = object({ episodeId: ulidSchema.optional() });
23162
+ var healthMedicalIdSchema = object({
23163
+ name: string2().nullable(),
23164
+ bloodGroup: string2().nullable(),
23165
+ allergies: array(string2()),
23166
+ heightCm: number2().nullable(),
23167
+ medications: array(object({
23168
+ id: string2(),
23169
+ title: string2(),
23170
+ dose: string2().nullable(),
23171
+ kind: healthMedicationKindSchema,
23172
+ schedule: healthMedicationScheduleSchema
23173
+ })),
23174
+ emergencyContact: object({ id: string2(), name: string2(), phone: string2().nullable() }).nullable()
23175
+ });
22328
23176
 
22329
23177
  // ../../packages/schema/src/contracts/health-labs.ts
22330
23178
  var LAB_GROUP_VALUES = [
@@ -22785,10 +23633,10 @@ var JOURNAL_MILESTONE_PRECISION_VALUES = ["year", "month", "day"];
22785
23633
  var journalMilestonePrecisionSchema = _enum2(JOURNAL_MILESTONE_PRECISION_VALUES);
22786
23634
  var journalMilestoneStatusSchema = _enum2(["suggested", "kept"]);
22787
23635
  var journalMilestoneVisibilitySchema = _enum2(["owner", "space"]);
22788
- var titleSchema = string2().trim().min(1).max(200);
23636
+ var titleSchema2 = string2().trim().min(1).max(200);
22789
23637
  var descriptionSchema = string2().trim().min(1).max(2000);
22790
23638
  var journalCreateMilestoneInputSchema = object({
22791
- title: titleSchema,
23639
+ title: titleSchema2,
22792
23640
  kind: journalMilestoneKindSchema.default("other"),
22793
23641
  happenedOn: journalDateSchema,
22794
23642
  precision: journalMilestonePrecisionSchema.default("day"),
@@ -22803,7 +23651,7 @@ var journalCreateMilestoneInputSchema = object({
22803
23651
  path: ["remindYearly"]
22804
23652
  });
22805
23653
  var journalUpdateMilestoneInputSchema = object({
22806
- title: titleSchema.optional(),
23654
+ title: titleSchema2.optional(),
22807
23655
  kind: journalMilestoneKindSchema.optional(),
22808
23656
  happenedOn: journalDateSchema.optional(),
22809
23657
  precision: journalMilestonePrecisionSchema.optional(),
@@ -24225,62 +25073,6 @@ var mealPlanCookResultSchema = object({
24225
25073
  ingredients: array(cookedIngredientSchema)
24226
25074
  });
24227
25075
 
24228
- // ../../packages/schema/src/contracts/key-dates.ts
24229
- var keyDateDaySchema = string2().regex(/^\d{4}-\d{2}-\d{2}$/, "expected YYYY-MM-DD").refine((s) => {
24230
- const d = new Date(`${s}T00:00:00Z`);
24231
- return !Number.isNaN(d.getTime()) && d.toISOString().slice(0, 10) === s;
24232
- }, "not a real date");
24233
- var keyDateRepeatSchema = _enum2(["yearly"]);
24234
- var keyDateSchema = createSelectSchema(keyDates, {
24235
- date: keyDateDaySchema,
24236
- confirmedAt: exports_coerce.date().nullable(),
24237
- createdAt: exports_coerce.date(),
24238
- updatedAt: exports_coerce.date()
24239
- });
24240
- var keyDateViewSchema = keyDateSchema.extend({
24241
- nodeTitle: string2(),
24242
- nodeType: string2(),
24243
- repeat: keyDateRepeatSchema.nullable(),
24244
- nextOn: keyDateDaySchema,
24245
- task: object({
24246
- id: ulidSchema,
24247
- status: string2(),
24248
- dueAt: exports_coerce.date().nullable()
24249
- }).nullable()
24250
- });
24251
- var leadDaysSchema = number2().int().min(0).max(366);
24252
- var sourceSchema = string2().trim().min(1).max(120);
24253
- var createKeyDateInputSchema = object({
24254
- id: ulidSchema,
24255
- nodeId: ulidSchema,
24256
- kind: keyDateKindSchema.optional(),
24257
- label: string2().trim().min(1).max(200).nullish(),
24258
- date: keyDateDaySchema,
24259
- yearKnown: boolean3().optional(),
24260
- repeat: keyDateRepeatSchema.nullish(),
24261
- leadDays: leadDaysSchema.optional(),
24262
- derivedFrom: string2().trim().min(1).max(120).nullish(),
24263
- source: sourceSchema.optional(),
24264
- confirmed: boolean3().optional()
24265
- }).strict();
24266
- var updateKeyDateInputSchema = object({
24267
- kind: keyDateKindSchema.optional(),
24268
- label: string2().trim().min(1).max(200).nullish(),
24269
- date: keyDateDaySchema.optional(),
24270
- yearKnown: boolean3().optional(),
24271
- repeat: keyDateRepeatSchema.nullish(),
24272
- leadDays: leadDaysSchema.optional(),
24273
- derivedFrom: string2().trim().min(1).max(120).nullish(),
24274
- source: sourceSchema.optional(),
24275
- confirmed: boolean3().optional()
24276
- }).strict();
24277
- var keyDatesQuerySchema = object({
24278
- nodeId: ulidSchema.optional(),
24279
- kind: keyDateKindSchema.optional(),
24280
- from: keyDateDaySchema.optional(),
24281
- to: keyDateDaySchema.optional()
24282
- });
24283
-
24284
25076
  // ../../packages/schema/src/contracts/people.ts
24285
25077
  var sourceSchema2 = string2().trim().min(1).max(120);
24286
25078
  var rhythmDaysSchema = number2().int().min(1).max(366);
@@ -25246,9 +26038,12 @@ var insuranceFieldsSchema = object({
25246
26038
  product: text4,
25247
26039
  insuredObject: text4,
25248
26040
  insuredValue: amount4,
26041
+ buildingValue: amount4,
25249
26042
  premium: amount4,
25250
26043
  cadence: documentCadenceSchema,
26044
+ paymentMethod: text4,
25251
26045
  deductible: amount4,
26046
+ deductibleIndexed: boolean3(),
25252
26047
  extras: array(text4).max(30),
25253
26048
  claimPhone: phone,
25254
26049
  claimHours: text4,
@@ -25384,11 +26179,28 @@ var documentLinkSchema = object({
25384
26179
  title: string2(),
25385
26180
  type: string2(),
25386
26181
  kind: string2(),
25387
- direction: _enum2(["in", "out"])
26182
+ direction: _enum2(["in", "out"]),
26183
+ facts: object({
26184
+ dueOn: keyDateDaySchema.nullable(),
26185
+ status: string2().nullable(),
26186
+ amount: number2().nullable(),
26187
+ cadence: string2().nullable(),
26188
+ area: string2().nullable(),
26189
+ roles: array(string2()),
26190
+ phone: string2().nullable(),
26191
+ papers: array(object({ title: string2(), certType: string2().nullable() }))
26192
+ }).partial().default({})
26193
+ });
26194
+ var documentBrokerSchema = object({
26195
+ id: ulidSchema,
26196
+ title: string2(),
26197
+ phone: string2().nullable()
25388
26198
  });
25389
26199
  var documentDetailSchema = documentViewSchema.extend({
25390
26200
  keyDates: array(keyDateViewSchema),
25391
- linked: array(documentLinkSchema).default([])
26201
+ linked: array(documentLinkSchema).default([]),
26202
+ providerRoles: array(string2()).default([]),
26203
+ broker: documentBrokerSchema.nullable().default(null)
25392
26204
  });
25393
26205
  var fieldsInputSchema = record(string2(), unknown());
25394
26206
  function checkFields(kind, fields, ctx) {
@@ -25539,57 +26351,6 @@ var incidentsQuerySchema = object({
25539
26351
  policyId: ulidSchema.optional()
25540
26352
  });
25541
26353
 
25542
- // ../../packages/schema/src/contracts/periods.ts
25543
- var periodKindSchema = _enum2(periodKind.enumValues);
25544
- var periodRuleSchema = record(string2(), unknown());
25545
- var periodSchema = createSelectSchema(periods, {
25546
- startsAt: exports_coerce.date(),
25547
- endsAt: exports_coerce.date().nullable(),
25548
- plannedEndAt: exports_coerce.date().nullable(),
25549
- rule: periodRuleSchema,
25550
- createdAt: exports_coerce.date(),
25551
- updatedAt: exports_coerce.date()
25552
- });
25553
- var periodViewSchema = periodSchema.extend({
25554
- nodeTitle: string2(),
25555
- nodeType: string2(),
25556
- active: boolean3()
25557
- });
25558
- var noteSchema2 = string2().trim().min(1).max(500);
25559
- function endsAfterStart(p, ctx) {
25560
- if (!p.startsAt)
25561
- return;
25562
- for (const key of ["endsAt", "plannedEndAt"]) {
25563
- const at = p[key];
25564
- if (at && at < p.startsAt) {
25565
- ctx.addIssue({ code: "custom", path: [key], message: `${key} is before startsAt` });
25566
- }
25567
- }
25568
- }
25569
- var createPeriodInputSchema = object({
25570
- id: ulidSchema,
25571
- nodeId: ulidSchema,
25572
- kind: periodKindSchema.optional(),
25573
- startsAt: exports_coerce.date(),
25574
- endsAt: exports_coerce.date().nullish(),
25575
- plannedEndAt: exports_coerce.date().nullish(),
25576
- rule: periodRuleSchema.optional(),
25577
- note: noteSchema2.nullish()
25578
- }).strict().superRefine(endsAfterStart);
25579
- var updatePeriodInputSchema = object({
25580
- kind: periodKindSchema.optional(),
25581
- startsAt: exports_coerce.date().optional(),
25582
- endsAt: exports_coerce.date().nullish(),
25583
- plannedEndAt: exports_coerce.date().nullish(),
25584
- rule: periodRuleSchema.optional(),
25585
- note: noteSchema2.nullish()
25586
- }).strict().superRefine(endsAfterStart);
25587
- var periodsQuerySchema = object({
25588
- nodeId: ulidSchema.optional(),
25589
- kind: periodKindSchema.optional(),
25590
- active: _enum2(["true", "false"]).transform((v) => v === "true").optional()
25591
- });
25592
-
25593
26354
  // ../../packages/schema/src/contracts/planning-rules.ts
25594
26355
  var PLANNING_RULE_KINDS = planningRuleKind.enumValues;
25595
26356
  var planningRuleKindSchema = _enum2(PLANNING_RULE_KINDS);
@@ -25765,27 +26526,27 @@ var runPlayStatusValues = [
25765
26526
  var runPlayStatusSchema = _enum2(runPlayStatusValues);
25766
26527
  var name = string2().trim().min(1).max(200);
25767
26528
  var text5 = string2().trim().max(2000);
25768
- var shortText = string2().trim().max(300);
26529
+ var shortText2 = string2().trim().max(300);
25769
26530
  var isoDate = string2().regex(/^\d{4}-\d{2}-\d{2}$/, "must be an ISO date (YYYY-MM-DD)");
25770
26531
  var ref = string2().trim().min(1).max(200);
25771
26532
  var runCharacterSchema = object({
25772
26533
  name,
25773
26534
  pronoun: _enum2(["he", "she", "they"]).nullish(),
25774
- subtitle: shortText.nullish(),
26535
+ subtitle: shortText2.nullish(),
25775
26536
  level: number2().int().min(0).max(1e4).nullish(),
25776
- build: shortText.nullish(),
25777
- stats: array(object({ k: name, v: union([number2(), shortText]) }).strict()).max(40).optional(),
25778
- traits: array(shortText).max(20).optional(),
26537
+ build: shortText2.nullish(),
26538
+ stats: array(object({ k: name, v: union([number2(), shortText2]) }).strict()).max(40).optional(),
26539
+ traits: array(shortText2).max(20).optional(),
25779
26540
  backstory: text5.nullish(),
25780
- rules: array(shortText).max(30).optional(),
25781
- faith: shortText.nullish()
26541
+ rules: array(shortText2).max(30).optional(),
26542
+ faith: shortText2.nullish()
25782
26543
  }).strict();
25783
26544
  var runArcSchema = object({
25784
- title: shortText.nullish(),
26545
+ title: shortText2.nullish(),
25785
26546
  chapters: array(object({
25786
26547
  key: name,
25787
26548
  name,
25788
- range: shortText.nullish(),
26549
+ range: shortText2.nullish(),
25789
26550
  moral: text5.nullish()
25790
26551
  }).strict()).max(40),
25791
26552
  current: name.nullish()
@@ -25793,7 +26554,7 @@ var runArcSchema = object({
25793
26554
  var runStepStatusValues = ["done", "now", "todo", "skipped"];
25794
26555
  var runStepStatusSchema = _enum2(runStepStatusValues);
25795
26556
  var runOrderStepSchema = object({
25796
- text: shortText.pipe(string2().min(1)),
26557
+ text: shortText2.pipe(string2().min(1)),
25797
26558
  status: runStepStatusSchema.default("todo"),
25798
26559
  questRef: ref.nullish()
25799
26560
  }).strict();
@@ -25802,33 +26563,33 @@ var runQuestStatusSchema = _enum2(runQuestStatusValues);
25802
26563
  var runQuestSchema = object({
25803
26564
  ref: ref.nullish(),
25804
26565
  name,
25805
- line: shortText.nullish(),
26566
+ line: shortText2.nullish(),
25806
26567
  status: runQuestStatusSchema.default("active"),
25807
26568
  objective: text5.nullish(),
25808
- hint: shortText.nullish(),
25809
- reward: shortText.nullish(),
25810
- place: shortText.nullish(),
26569
+ hint: shortText2.nullish(),
26570
+ reward: shortText2.nullish(),
26571
+ place: shortText2.nullish(),
25811
26572
  steps: array(object({
25812
- text: shortText.pipe(string2().min(1)),
26573
+ text: shortText2.pipe(string2().min(1)),
25813
26574
  done: boolean3().default(false),
25814
26575
  now: boolean3().optional(),
25815
- hint: shortText.nullish()
26576
+ hint: shortText2.nullish()
25816
26577
  }).strict()).max(40).optional(),
25817
- pausedAt: shortText.nullish(),
26578
+ pausedAt: shortText2.nullish(),
25818
26579
  why: text5.nullish(),
25819
26580
  revisitAt: name.nullish()
25820
26581
  }).strict();
25821
26582
  var runNextStepsSchema = object({
25822
- items: array(shortText.pipe(string2().min(1))).max(3),
26583
+ items: array(shortText2.pipe(string2().min(1))).max(3),
25823
26584
  pinned: boolean3().default(false),
25824
26585
  note: text5.nullish()
25825
26586
  }).strict();
25826
26587
  var runChoiceSchema = object({
25827
26588
  ref: ref.nullish(),
25828
26589
  title: name,
25829
- place: shortText.nullish(),
26590
+ place: shortText2.nullish(),
25830
26591
  status: _enum2(["made", "planned"]).default("made"),
25831
- options: array(shortText).max(6).optional(),
26592
+ options: array(shortText2).max(6).optional(),
25832
26593
  why: text5.nullish(),
25833
26594
  consequence: text5.nullish(),
25834
26595
  revisitAt: name.nullish(),
@@ -25840,9 +26601,9 @@ var runHomeSchema = object({
25840
26601
  ref: ref.nullish(),
25841
26602
  name,
25842
26603
  role: _enum2(["home", "collector", "storage", "planned", "later"]).default("home"),
25843
- place: shortText.nullish(),
26604
+ place: shortText2.nullish(),
25844
26605
  upgrades: array(object({ name, done: boolean3().default(false) }).strict()).max(40).optional(),
25845
- steward: shortText.nullish(),
26606
+ steward: shortText2.nullish(),
25846
26607
  note: text5.nullish()
25847
26608
  }).strict();
25848
26609
  var runPersonSchema = object({
@@ -25850,7 +26611,7 @@ var runPersonSchema = object({
25850
26611
  name,
25851
26612
  role: _enum2(["child", "spouse", "steward", "follower", "pet", "rival", "other"]),
25852
26613
  status: _enum2(["with", "planned", "lost"]).default("with"),
25853
- home: shortText.nullish(),
26614
+ home: shortText2.nullish(),
25854
26615
  note: text5.nullish()
25855
26616
  }).strict();
25856
26617
  var runMountSchema = object({
@@ -25862,850 +26623,287 @@ var runUniqueSchema = object({
25862
26623
  ref: ref.nullish(),
25863
26624
  name,
25864
26625
  status: _enum2(["have", "now", "want"]).default("have"),
25865
- source: shortText.nullish(),
25866
- displayAt: shortText.nullish(),
26626
+ source: shortText2.nullish(),
26627
+ displayAt: shortText2.nullish(),
25867
26628
  set: name.nullish()
25868
26629
  }).strict();
25869
26630
  var runChecklistSchema = object({
25870
26631
  key: string2().trim().min(1).max(60).regex(/^[a-z0-9][a-z0-9_-]*$/, "must be a lowercase slug"),
25871
26632
  label: name,
25872
26633
  total: number2().int().min(0).max(5000).nullish(),
25873
- items: array(object({ id: ref, label: shortText.nullish() }).strict()).max(5000).optional(),
26634
+ items: array(object({ id: ref, label: shortText2.nullish() }).strict()).max(5000).optional(),
25874
26635
  done: array(ref).max(5000),
25875
- notes: record(ref, shortText).optional(),
26636
+ notes: record(ref, shortText2).optional(),
25876
26637
  carrying: array(ref).max(5000).optional(),
25877
- legend: shortText.nullish()
26638
+ legend: shortText2.nullish()
25878
26639
  }).strict();
25879
26640
  var runTeamMemberSchema = object({
25880
26641
  species: name,
25881
- nick: shortText.nullish(),
26642
+ nick: shortText2.nullish(),
25882
26643
  level: number2().int().min(1).max(100).nullish(),
25883
- nature: shortText.nullish(),
25884
- types: array(shortText).max(2).optional(),
25885
- moves: array(shortText).max(4).optional(),
26644
+ nature: shortText2.nullish(),
26645
+ types: array(shortText2).max(2).optional(),
26646
+ moves: array(shortText2).max(4).optional(),
25886
26647
  hp: number2().int().min(0).max(100).nullish(),
25887
- note: shortText.nullish(),
26648
+ note: shortText2.nullish(),
25888
26649
  status: _enum2(["team", "plan", "boxed"]).default("team")
25889
26650
  }).strict();
25890
26651
  var runAchievementsSchema = object({
25891
26652
  source: _enum2(["steam", "xbox", "psn", "manual"]).default("manual"),
25892
26653
  total: number2().int().min(0).max(5000).nullish(),
25893
26654
  enabled: boolean3().default(true),
25894
- unlocked: array(object({ name, on: isoDate.nullish(), hint: shortText.nullish(), key: ref.nullish() }).strict()).max(5000),
25895
- locked: array(object({ name, hint: shortText.nullish(), key: ref.nullish() }).strict()).max(5000).optional(),
26655
+ unlocked: array(object({ name, on: isoDate.nullish(), hint: shortText2.nullish(), key: ref.nullish() }).strict()).max(5000),
26656
+ locked: array(object({ name, hint: shortText2.nullish(), key: ref.nullish() }).strict()).max(5000).optional(),
25896
26657
  syncedAt: string2().datetime({ offset: true }).nullish()
25897
26658
  }).strict();
25898
26659
  var runRareFindsSchema = object({
25899
- place: shortText.nullish(),
25900
- items: array(shortText).max(200),
26660
+ place: shortText2.nullish(),
26661
+ items: array(shortText2).max(200),
25901
26662
  note: text5.nullish()
25902
26663
  }).strict();
25903
26664
  var runInstallSchema = object({
25904
- edition: shortText.nullish(),
26665
+ edition: shortText2.nullish(),
25905
26666
  mods: array(object({ name, url: string2().url().max(2000).nullish() }).strict()).max(200).default([]),
25906
- savePath: string2().trim().max(500).nullish(),
25907
- lastBackup: isoDate.nullish(),
25908
- notes: text5.nullish()
25909
- }).strict();
25910
- var SAVE_SCREENSHOT_MAX_BASE64 = 1500000;
25911
- var runSaveFields = {
25912
- game: _enum2(["skyrim"]).default("skyrim"),
25913
- fileName: shortText.nullish(),
25914
- saveNumber: number2().int().min(0).max(1e9),
25915
- playerName: name,
25916
- level: number2().int().min(0).max(1e4),
25917
- location: shortText,
25918
- race: shortText.nullish(),
25919
- sex: _enum2(["male", "female"]).nullish(),
25920
- playTimeMinutes: number2().int().min(0).max(1e4 * 60).nullish(),
25921
- savedAt: string2().datetime({ offset: true }).nullish(),
25922
- gameDate: object({
25923
- text: shortText.pipe(string2().min(1)),
25924
- hour: number2().min(0).max(24).nullish(),
25925
- daysPassed: number2().min(0).max(1e6).nullish()
25926
- }).strict().nullish(),
25927
- plugins: array(shortText).max(600).optional(),
25928
- stats: record(shortText, number2().int()).refine((r) => Object.keys(r).length <= 300, "at most 300 stats").optional()
25929
- };
25930
- var runSaveSchema = object({
25931
- ...runSaveFields,
25932
- screenshotFileId: string2().min(1).max(64).nullish(),
25933
- uploadedAt: string2().datetime({ offset: true })
25934
- }).strict();
25935
- var uploadRunSaveHeaderInputSchema = object({
25936
- ...runSaveFields,
25937
- screenshot: string2().max(SAVE_SCREENSHOT_MAX_BASE64).regex(/^[A-Za-z0-9+/]+={0,2}$/, "must be base64").nullish()
25938
- }).strict();
25939
- var runFacetSchema = object({
25940
- theme: runThemeSchema.default("generic"),
25941
- edition: shortText.nullish(),
25942
- platform: shortText.nullish(),
25943
- modeFlags: array(shortText).max(20).optional(),
25944
- character: runCharacterSchema.nullish(),
25945
- arc: runArcSchema.nullish(),
25946
- orderOfPlay: array(runOrderStepSchema).max(200).optional(),
25947
- quests: array(runQuestSchema).max(500).optional(),
25948
- nextSteps: runNextStepsSchema.nullish(),
25949
- choices: array(runChoiceSchema).max(300).optional(),
25950
- homes: array(runHomeSchema).max(100).optional(),
25951
- people: array(runPersonSchema).max(200).optional(),
25952
- mounts: array(runMountSchema).max(50).optional(),
25953
- team: array(runTeamMemberSchema).max(30).optional(),
25954
- checklists: array(runChecklistSchema).max(30).optional(),
25955
- uniques: array(runUniqueSchema).max(1000).optional(),
25956
- achievements: runAchievementsSchema.nullish(),
25957
- rareFinds: runRareFindsSchema.nullish(),
25958
- install: runInstallSchema.nullish(),
25959
- save: runSaveSchema.nullish(),
25960
- money: object({ goal: shortText.nullish(), purpose: shortText.nullish() }).strict().nullish(),
25961
- links: array(object({ label: name, url: string2().url().max(2000) }).strict()).max(50).optional()
25962
- }).strict();
25963
- var runListSectionValues = [
25964
- "orderOfPlay",
25965
- "quests",
25966
- "choices",
25967
- "homes",
25968
- "people",
25969
- "mounts",
25970
- "team",
25971
- "checklists",
25972
- "uniques",
25973
- "links"
25974
- ];
25975
- var runListSectionSchema = _enum2(runListSectionValues);
25976
- var runValueSectionValues = [
25977
- "theme",
25978
- "edition",
25979
- "platform",
25980
- "modeFlags",
25981
- "character",
25982
- "arc",
25983
- "nextSteps",
25984
- "achievements",
25985
- "rareFinds",
25986
- "install",
25987
- "save",
25988
- "money"
25989
- ];
25990
- var runValueSectionSchema = _enum2(runValueSectionValues);
25991
- var label = string2().trim().min(1).max(120);
25992
- var runChangeSchema = discriminatedUnion("op", [
25993
- object({
25994
- op: literal("set"),
25995
- section: runValueSectionSchema,
25996
- value: unknown(),
25997
- label: label.optional()
25998
- }).strict(),
25999
- object({
26000
- op: literal("merge"),
26001
- section: _enum2([
26002
- "character",
26003
- "arc",
26004
- "nextSteps",
26005
- "achievements",
26006
- "rareFinds",
26007
- "install",
26008
- "money"
26009
- ]),
26010
- value: record(string2(), unknown()),
26011
- label: label.optional()
26012
- }).strict(),
26013
- object({
26014
- op: literal("upsert"),
26015
- section: runListSectionSchema,
26016
- value: record(string2(), unknown()),
26017
- label: label.optional()
26018
- }).strict(),
26019
- object({
26020
- op: literal("remove"),
26021
- section: runListSectionSchema,
26022
- match: string2().trim().min(1).max(200),
26023
- label: label.optional()
26024
- }).strict(),
26025
- object({
26026
- op: literal("tick"),
26027
- section: literal("checklists"),
26028
- key: string2().trim().min(1).max(60),
26029
- ids: array(ref).min(1).max(5000),
26030
- done: boolean3().default(true),
26031
- label: label.optional()
26032
- }).strict()
26033
- ]);
26034
- var runAppliedChangeSchema = object({ op: string2(), section: string2(), label: string2() }).passthrough();
26035
- var runChangeBatchSchema = object({
26036
- id: string2(),
26037
- at: exports_coerce.date(),
26038
- message: string2().nullable().default(null),
26039
- changes: array(runAppliedChangeSchema),
26040
- before: record(string2(), unknown()),
26041
- undoneAt: exports_coerce.date().nullable().default(null)
26042
- });
26043
- var RUN_SESSION_IDLE_MS = 6 * 60 * 60 * 1000;
26044
- var applyRunChangesInputSchema = object({
26045
- changes: array(runChangeSchema).min(1).max(100),
26046
- message: string2().trim().min(1).max(2000).nullish(),
26047
- sessionId: ulidSchema.optional(),
26048
- newSession: boolean3().optional(),
26049
- recap: string2().trim().min(1).max(2000).optional(),
26050
- occurredOn: isoDate.optional()
26051
- }).strict();
26052
- var tickRunChecklistInputSchema = object({
26053
- ids: array(ref).min(1).max(5000),
26054
- done: boolean3().default(true),
26055
- message: string2().trim().min(1).max(2000).nullish(),
26056
- sessionId: ulidSchema.optional()
26057
- }).strict();
26058
- var undoRunChangesInputSchema = object({ batchId: string2().min(1).max(64).optional() }).strict();
26059
- var runSessionSchema = collectionEntrySchema.pick({ id: true, occurredOn: true, note: true, minutes: true, createdAt: true }).extend({ batches: array(runChangeBatchSchema) });
26060
- var createRunSessionInputSchema = object({
26061
- id: ulidSchema.optional(),
26062
- occurredOn: isoDate.optional(),
26063
- recap: string2().trim().min(1).max(2000).nullish(),
26064
- minutes: number2().int().min(0).max(24 * 60).nullish()
26065
- }).strict();
26066
- var updateRunSessionInputSchema = object({
26067
- occurredOn: isoDate.optional(),
26068
- recap: string2().trim().min(1).max(2000).nullish(),
26069
- minutes: number2().int().min(0).max(24 * 60).nullish()
26070
- }).strict();
26071
- var runViewSchema = object({
26072
- id: string2(),
26073
- gameId: string2(),
26074
- gameTitle: string2(),
26075
- title: string2(),
26076
- status: string2(),
26077
- facet: runFacetSchema,
26078
- lastPlayedOn: string2().nullable(),
26079
- sessionCount: number2().int(),
26080
- createdAt: exports_coerce.date(),
26081
- updatedAt: exports_coerce.date()
26082
- });
26083
- var runDetailSchema = runViewSchema.extend({
26084
- sessions: array(runSessionSchema)
26085
- });
26086
- var runChangesResultSchema = object({
26087
- run: runDetailSchema,
26088
- sessionId: string2(),
26089
- batch: runChangeBatchSchema
26090
- });
26091
- var runSaveHeaderResultSchema = object({
26092
- run: runDetailSchema,
26093
- unchanged: boolean3(),
26094
- sessionId: string2().nullable(),
26095
- batch: runChangeBatchSchema.nullable()
26096
- });
26097
- var createRunInputSchema = object({
26098
- id: ulidSchema,
26099
- gameId: ulidSchema,
26100
- title: name,
26101
- status: runPlayStatusSchema.optional(),
26102
- facet: runFacetSchema.optional()
26103
- }).strict();
26104
- var updateRunInputSchema = object({
26105
- title: name.optional(),
26106
- status: runPlayStatusSchema.optional(),
26107
- facet: runFacetSchema.optional()
26108
- }).strict();
26109
- var runsQuerySchema = object({
26110
- gameId: ulidSchema.optional(),
26111
- status: runPlayStatusSchema.optional(),
26112
- theme: runThemeSchema.optional()
26113
- }).strict();
26114
-
26115
- // ../../packages/schema/src/contracts/runs-steam.ts
26116
- var steamIdSchema = string2().trim().regex(/^7656119\d{10}$/, "must be a SteamID64 (17 digits, starting 7656119)");
26117
- var steamApiKeySchema = string2().trim().regex(/^[0-9A-Fa-f]{32}$/, "must be a Steam Web API key (32 letters and digits)");
26118
- var steamAccountInputSchema = object({ steamId: steamIdSchema, apiKey: steamApiKeySchema }).strict();
26119
- var steamAccountStatusSchema = object({
26120
- connected: boolean3(),
26121
- games: number2().int().nonnegative(),
26122
- lastSyncedAt: string2().nullable()
26123
- });
26124
- var steamSyncInputSchema = object({ gameId: string2().trim().min(1).max(64).optional() }).strict();
26125
- var steamSyncErrorValues = [
26126
- "unauthorized",
26127
- "private",
26128
- "no_stats",
26129
- "unavailable",
26130
- "bad_response"
26131
- ];
26132
- var steamSyncErrorSchema = _enum2(steamSyncErrorValues);
26133
- var steamGameSyncSchema = object({
26134
- gameId: string2(),
26135
- gameTitle: string2(),
26136
- appId: number2().int(),
26137
- outcome: _enum2(["ok", "failed"]),
26138
- runs: number2().int().nonnegative(),
26139
- unlocked: number2().int().nonnegative(),
26140
- total: number2().int().nonnegative(),
26141
- error: steamSyncErrorSchema.nullable()
26142
- });
26143
- var steamSyncResultSchema = object({
26144
- syncedAt: string2(),
26145
- games: array(steamGameSyncSchema)
26146
- });
26147
-
26148
- // ../../packages/schema/src/contracts/animals.ts
26149
- var animalFormSchema = _enum2(animalForm.enumValues);
26150
- var animalStatusSchema = _enum2(animalStatus.enumValues);
26151
- var animalAcquiredHowSchema = _enum2(animalAcquiredHow.enumValues);
26152
- var animalSexSchema = _enum2(animalSex.enumValues);
26153
- var animalBreedingSchema = _enum2(animalBreeding.enumValues);
26154
- var animalClassSchema = _enum2(animalClass.enumValues);
26155
- var animalLegalSchema = _enum2(animalLegal.enumValues);
26156
- var animalBornOnSchema = string2().regex(/^\d{4}(-(0[1-9]|1[0-2])(-(0[1-9]|[12]\d|3[01]))?)?$/, "expected YYYY, YYYY-MM or YYYY-MM-DD");
26157
- var animalIdsSchema = object({
26158
- chipNoMasked: string2().trim().min(1).max(40).optional(),
26159
- passportNoMasked: string2().trim().min(1).max(40).optional(),
26160
- ringNo: string2().trim().min(1).max(40).optional(),
26161
- ringYear: number2().int().min(1900).max(2200).optional(),
26162
- ringIssuer: string2().trim().min(1).max(80).optional(),
26163
- ringType: _enum2(["open", "closed"]).optional()
26164
- }).strict();
26165
- function isMaskedNumber(value) {
26166
- const shown = value.replace(/[\s*\u2022xX.-]/g, "");
26167
- return shown.length <= 4 && shown.length < value.replace(/\s/g, "").length;
26168
- }
26169
- var maskedIdsSchema = animalIdsSchema.superRefine((ids, ctx) => {
26170
- for (const key of ["chipNoMasked", "passportNoMasked"]) {
26171
- const v = ids[key];
26172
- if (v && !isMaskedNumber(v)) {
26173
- ctx.addIssue({
26174
- code: "custom",
26175
- path: [key],
26176
- message: "mask all but the last four characters (e.g. ***********1234)"
26177
- });
26178
- }
26179
- }
26180
- });
26181
- var animalScheduleStepSchema = object({
26182
- key: string2().trim().min(1).max(40),
26183
- label: string2().trim().min(1).max(120),
26184
- everyMonths: number2().int().min(1).max(120)
26185
- }).strict();
26186
- var animalSpeciesSchema = createSelectSchema(animalSpecies, {
26187
- incompatibleWith: array(string2()),
26188
- defaultSchedule: array(animalScheduleStepSchema),
26189
- createdAt: exports_coerce.date()
26190
- });
26191
- var speciesKeySchema = string2().regex(/^[a-z][a-z0-9_]{1,39}$/, "a lowercase slug, e.g. hermann_tortoise");
26192
- var createAnimalSpeciesInputSchema = object({
26193
- id: ulidSchema,
26194
- key: speciesKeySchema,
26195
- commonName: string2().trim().min(1).max(120),
26196
- commonNameNl: string2().trim().min(1).max(120).nullish(),
26197
- latin: string2().trim().min(1).max(120).nullish(),
26198
- class: animalClassSchema.optional(),
26199
- legal: animalLegalSchema.optional(),
26200
- hibernates: boolean3().optional(),
26201
- defaultForm: animalFormSchema.optional(),
26202
- minGroupSize: number2().int().min(1).max(1000).nullish(),
26203
- incompatibleWith: array(speciesKeySchema).max(20).optional(),
26204
- defaultSchedule: array(animalScheduleStepSchema).max(20).optional(),
26205
- careSheetMd: string2().trim().min(1).max(20000).nullish()
26206
- }).strict();
26207
- var updateAnimalSpeciesInputSchema = createAnimalSpeciesInputSchema.omit({ id: true, key: true }).partial().strict();
26208
- var DEWORM = {
26209
- key: "deworm",
26210
- label: "Deworm",
26211
- everyMonths: 3
26212
- };
26213
- var BOOSTER = { key: "booster", label: "Yearly booster", everyMonths: 12 };
26214
- var NATIVE_FINCH = {
26215
- class: "bird",
26216
- legal: "native_closed_ring"
26217
- };
26218
- var EXOTIC_FINCH = {
26219
- class: "bird",
26220
- legal: "none",
26221
- defaultForm: "group",
26222
- minGroupSize: 2
26223
- };
26224
- var ANIMAL_SPECIES_SEED = [
26225
- {
26226
- key: "dog",
26227
- commonName: "Dog",
26228
- commonNameNl: "Hond",
26229
- latin: "Canis familiaris",
26230
- class: "mammal",
26231
- legal: "dog_id",
26232
- defaultSchedule: [DEWORM, BOOSTER]
26233
- },
26234
- {
26235
- key: "cat",
26236
- commonName: "Cat",
26237
- commonNameNl: "Kat",
26238
- latin: "Felis catus",
26239
- class: "mammal",
26240
- legal: "cat_id",
26241
- defaultSchedule: [DEWORM, BOOSTER]
26242
- },
26243
- {
26244
- key: "chicken",
26245
- commonName: "Chicken",
26246
- commonNameNl: "Kip",
26247
- latin: "Gallus gallus domesticus",
26248
- class: "bird",
26249
- defaultForm: "group",
26250
- minGroupSize: 3,
26251
- defaultSchedule: [
26252
- { key: "mite_check", label: "Mite check", everyMonths: 1 },
26253
- { key: "deworm", label: "Deworm", everyMonths: 6 }
26254
- ]
26255
- },
26256
- {
26257
- key: "duck",
26258
- commonName: "Duck",
26259
- commonNameNl: "Eend",
26260
- latin: "Anas platyrhynchos domesticus",
26261
- class: "bird",
26262
- defaultForm: "group",
26263
- minGroupSize: 2
26264
- },
26265
- {
26266
- key: "quail",
26267
- commonName: "Quail",
26268
- commonNameNl: "Kwartel",
26269
- latin: "Coturnix japonica",
26270
- class: "bird",
26271
- defaultForm: "group",
26272
- minGroupSize: 3
26273
- },
26274
- {
26275
- key: "hermann_tortoise",
26276
- commonName: "Hermann's tortoise",
26277
- commonNameNl: "Griekse landschildpad",
26278
- latin: "Testudo hermanni",
26279
- class: "reptile",
26280
- legal: "cites_a",
26281
- hibernates: true,
26282
- defaultSchedule: [{ key: "health_check", label: "Health check", everyMonths: 12 }]
26283
- },
26284
- {
26285
- key: "zebra_finch",
26286
- commonName: "Zebra finch",
26287
- commonNameNl: "Zebravink",
26288
- latin: "Taeniopygia guttata",
26289
- ...EXOTIC_FINCH
26290
- },
26291
- {
26292
- key: "bengalese_finch",
26293
- commonName: "Bengalese finch",
26294
- commonNameNl: "Japans meeuwtje",
26295
- latin: "Lonchura striata domestica",
26296
- ...EXOTIC_FINCH
26297
- },
26298
- {
26299
- key: "star_finch",
26300
- commonName: "Star finch",
26301
- commonNameNl: "Binsenastrild",
26302
- latin: "Bathilda ruficauda",
26303
- ...EXOTIC_FINCH
26304
- },
26305
- {
26306
- key: "diamond_dove",
26307
- commonName: "Diamond dove",
26308
- commonNameNl: "Diamantduif",
26309
- latin: "Geopelia cuneata",
26310
- ...EXOTIC_FINCH
26311
- },
26312
- {
26313
- key: "bullfinch",
26314
- commonName: "Eurasian bullfinch",
26315
- commonNameNl: "Goudvink",
26316
- latin: "Pyrrhula pyrrhula",
26317
- ...NATIVE_FINCH
26318
- },
26319
- {
26320
- key: "bearded_reedling",
26321
- commonName: "Bearded reedling",
26322
- commonNameNl: "Baardmannetje",
26323
- latin: "Panurus biarmicus",
26324
- ...NATIVE_FINCH
26325
- },
26326
- {
26327
- key: "siskin",
26328
- commonName: "Eurasian siskin",
26329
- commonNameNl: "Sijs",
26330
- latin: "Spinus spinus",
26331
- ...NATIVE_FINCH
26332
- },
26333
- {
26334
- key: "goldfinch",
26335
- commonName: "European goldfinch",
26336
- commonNameNl: "Putter",
26337
- latin: "Carduelis carduelis",
26338
- ...NATIVE_FINCH
26339
- },
26340
- {
26341
- key: "linnet",
26342
- commonName: "Common linnet",
26343
- commonNameNl: "Kneu",
26344
- latin: "Linaria cannabina",
26345
- ...NATIVE_FINCH
26346
- },
26347
- {
26348
- key: "rabbit",
26349
- commonName: "Rabbit",
26350
- commonNameNl: "Konijn",
26351
- latin: "Oryctolagus cuniculus",
26352
- class: "mammal",
26353
- defaultForm: "group",
26354
- minGroupSize: 2,
26355
- incompatibleWith: ["guinea_pig"],
26356
- defaultSchedule: [{ key: "vaccine", label: "Myxo/RHD vaccine", everyMonths: 12 }]
26357
- },
26358
- {
26359
- key: "guinea_pig",
26360
- commonName: "Guinea pig",
26361
- commonNameNl: "Cavia",
26362
- latin: "Cavia porcellus",
26363
- class: "mammal",
26364
- defaultForm: "group",
26365
- minGroupSize: 2,
26366
- incompatibleWith: ["rabbit"]
26367
- }
26368
- ];
26369
- var animalSchema = createSelectSchema(animals, {
26370
- ids: animalIdsSchema
26371
- });
26372
- var animalSpeciesRefSchema = object({
26373
- id: ulidSchema,
26374
- key: string2(),
26375
- commonName: string2(),
26376
- latin: string2().nullable(),
26377
- class: animalClassSchema,
26378
- legal: animalLegalSchema,
26379
- hibernates: boolean3()
26380
- });
26381
- var animalViewSchema = animalSchema.extend({
26382
- title: string2(),
26383
- parentId: ulidSchema.nullable(),
26384
- species: animalSpeciesRefSchema.nullable(),
26385
- memberCount: number2().int(),
26386
- heads: number2().int(),
26387
- createdAt: exports_coerce.date(),
26388
- updatedAt: exports_coerce.date()
26389
- });
26390
- var nodeRefSchema = object({ id: ulidSchema, title: string2() });
26391
- var animalHabitSchema = nodeRefSchema.extend({ doneToday: boolean3() });
26392
- var animalSupplySchema = nodeRefSchema.extend({
26393
- quantity: number2(),
26394
- unit: string2().nullable(),
26395
- lowStock: boolean3(),
26396
- dailyUse: number2().nullable(),
26397
- perHead: boolean3(),
26398
- daysLeft: number2().int().nullable(),
26399
- full: number2().nullable(),
26400
- onList: string2().nullable()
26401
- });
26402
- var animalDayCountSchema = object({ day: string2(), count: number2().int() });
26403
- var animalWeightPointSchema = object({
26404
- day: string2(),
26405
- grams: number2(),
26406
- at: exports_coerce.date()
26407
- });
26408
- var animalFileSchema = object({
26409
- id: ulidSchema,
26410
- name: string2(),
26411
- mime: string2(),
26412
- size: number2().int(),
26413
- createdAt: exports_coerce.date()
26414
- });
26415
- var animalVetSchema = nodeRefSchema.extend({ role: string2().nullable() });
26416
- var animalPaperSchema = nodeRefSchema.extend({
26417
- status: _enum2(documentStatus.enumValues),
26418
- reference: string2().nullable()
26419
- });
26420
- var animalLinksSchema = object({
26421
- place: nodeRefSchema.nullable(),
26422
- vets: array(animalVetSchema),
26423
- cameFrom: nodeRefSchema.nullable(),
26424
- habits: array(animalHabitSchema),
26425
- supplies: array(animalSupplySchema),
26426
- papers: array(animalPaperSchema),
26427
- files: array(animalFileSchema),
26428
- healthVisits: object({ count: number2().int(), lastAt: exports_coerce.date().nullable() }),
26429
- assets: array(nodeRefSchema.extend({ location: string2().nullable() })),
26430
- companions: array(nodeRefSchema)
26431
- });
26432
- var animalPapersCheckSchema = object({
26433
- needed: string2(),
26434
- onFile: boolean3()
26435
- });
26436
- var animalMemberSchema = animalViewSchema.extend({
26437
- papersCheck: animalPapersCheckSchema.nullable()
26438
- });
26439
- var SHED_READING_TYPES = {
26440
- temp: "shed.temp",
26441
- heater: "shed.heater",
26442
- water: "shed.water_pct",
26443
- door: "shed.door",
26444
- feeder: "shed.feed_kg",
26445
- light: "shed.light"
26446
- };
26447
- var animalRoomReadingSchema = object({
26448
- kind: _enum2(Object.keys(SHED_READING_TYPES)),
26449
- value: number2().nullable(),
26450
- unit: string2().nullable(),
26451
- text: string2().nullable(),
26452
- detail: string2().nullish(),
26453
- device: string2().nullish(),
26454
- at: exports_coerce.date()
26455
- });
26456
- var animalRoomAlertSchema = object({
26457
- id: string2(),
26458
- at: exports_coerce.date(),
26459
- text: string2(),
26460
- detail: string2().nullable(),
26461
- source: _enum2(["camera", "power", "other"])
26462
- });
26463
- var animalRoomSchema = object({
26464
- place: nodeRefSchema,
26465
- readings: array(animalRoomReadingSchema),
26466
- temperature24h: array(object({ at: exports_coerce.date(), value: number2() })),
26467
- alerts: array(animalRoomAlertSchema)
26468
- });
26469
- var animalDetailSchema = animalViewSchema.extend({
26470
- group: nodeRefSchema.nullable(),
26471
- members: array(animalMemberSchema),
26472
- links: animalLinksSchema,
26473
- weights: array(animalWeightPointSchema),
26474
- latestLength: object({ mm: number2(), at: exports_coerce.date() }).nullable(),
26475
- eggs: array(animalDayCountSchema),
26476
- periods: array(periodViewSchema),
26477
- keyDates: array(keyDateViewSchema),
26478
- papersCheck: animalPapersCheckSchema.nullable(),
26479
- room: animalRoomSchema.nullable()
26480
- });
26481
- var titleSchema2 = string2().trim().min(1).max(120);
26482
- var shortText2 = (max) => string2().trim().min(1).max(max);
26483
- var idList = array(ulidSchema).max(20);
26484
- var animalFieldsSchema = object({
26485
- title: titleSchema2,
26486
- form: animalFormSchema,
26487
- speciesId: ulidSchema.nullish(),
26488
- speciesKey: speciesKeySchema,
26489
- breed: shortText2(120).nullish(),
26490
- sex: animalSexSchema.nullish(),
26491
- bornOn: animalBornOnSchema.nullish(),
26492
- bornApprox: boolean3(),
26493
- acquiredOn: keyDateDaySchema.nullish(),
26494
- acquiredHow: animalAcquiredHowSchema.nullish(),
26495
- status: animalStatusSchema,
26496
- endedOn: keyDateDaySchema.nullish(),
26497
- endNote: shortText2(500).nullish(),
26498
- headCount: number2().int().min(0).max(1e4).nullish(),
26499
- ids: maskedIdsSchema,
26500
- markings: shortText2(200).nullish(),
26501
- breeding: animalBreedingSchema,
26502
- groupId: ulidSchema.nullish(),
26503
- areaId: ulidSchema.nullish(),
26504
- placeId: ulidSchema.nullish(),
26505
- vetIds: idList,
26506
- cameFromId: ulidSchema.nullish(),
26507
- habitIds: idList,
26508
- supplyIds: idList,
26509
- paperIds: idList,
26510
- assetIds: idList
26511
- });
26512
- var createAnimalInputSchema = animalFieldsSchema.partial().required({ title: true }).extend({ id: ulidSchema }).strict();
26513
- var updateAnimalInputSchema = animalFieldsSchema.partial().strict();
26514
- var animalsQuerySchema = object({
26515
- status: animalStatusSchema.optional(),
26516
- form: animalFormSchema.optional(),
26517
- groupId: ulidSchema.optional(),
26518
- includeEnded: _enum2(["true", "false"]).transform((v) => v === "true").optional()
26519
- });
26520
- var occurredAtSchema = exports_coerce.date().optional();
26521
- var animalLogInputSchema = discriminatedUnion("kind", [
26667
+ savePath: string2().trim().max(500).nullish(),
26668
+ lastBackup: isoDate.nullish(),
26669
+ notes: text5.nullish()
26670
+ }).strict();
26671
+ var SAVE_SCREENSHOT_MAX_BASE64 = 1500000;
26672
+ var runSaveFields = {
26673
+ game: _enum2(["skyrim"]).default("skyrim"),
26674
+ fileName: shortText2.nullish(),
26675
+ saveNumber: number2().int().min(0).max(1e9),
26676
+ playerName: name,
26677
+ level: number2().int().min(0).max(1e4),
26678
+ location: shortText2,
26679
+ race: shortText2.nullish(),
26680
+ sex: _enum2(["male", "female"]).nullish(),
26681
+ playTimeMinutes: number2().int().min(0).max(1e4 * 60).nullish(),
26682
+ savedAt: string2().datetime({ offset: true }).nullish(),
26683
+ gameDate: object({
26684
+ text: shortText2.pipe(string2().min(1)),
26685
+ hour: number2().min(0).max(24).nullish(),
26686
+ daysPassed: number2().min(0).max(1e6).nullish()
26687
+ }).strict().nullish(),
26688
+ plugins: array(shortText2).max(600).optional(),
26689
+ stats: record(shortText2, number2().int()).refine((r) => Object.keys(r).length <= 300, "at most 300 stats").optional()
26690
+ };
26691
+ var runSaveSchema = object({
26692
+ ...runSaveFields,
26693
+ screenshotFileId: string2().min(1).max(64).nullish(),
26694
+ uploadedAt: string2().datetime({ offset: true })
26695
+ }).strict();
26696
+ var uploadRunSaveHeaderInputSchema = object({
26697
+ ...runSaveFields,
26698
+ screenshot: string2().max(SAVE_SCREENSHOT_MAX_BASE64).regex(/^[A-Za-z0-9+/]+={0,2}$/, "must be base64").nullish()
26699
+ }).strict();
26700
+ var runFacetSchema = object({
26701
+ theme: runThemeSchema.default("generic"),
26702
+ edition: shortText2.nullish(),
26703
+ platform: shortText2.nullish(),
26704
+ modeFlags: array(shortText2).max(20).optional(),
26705
+ character: runCharacterSchema.nullish(),
26706
+ arc: runArcSchema.nullish(),
26707
+ orderOfPlay: array(runOrderStepSchema).max(200).optional(),
26708
+ quests: array(runQuestSchema).max(500).optional(),
26709
+ nextSteps: runNextStepsSchema.nullish(),
26710
+ choices: array(runChoiceSchema).max(300).optional(),
26711
+ homes: array(runHomeSchema).max(100).optional(),
26712
+ people: array(runPersonSchema).max(200).optional(),
26713
+ mounts: array(runMountSchema).max(50).optional(),
26714
+ team: array(runTeamMemberSchema).max(30).optional(),
26715
+ checklists: array(runChecklistSchema).max(30).optional(),
26716
+ uniques: array(runUniqueSchema).max(1000).optional(),
26717
+ achievements: runAchievementsSchema.nullish(),
26718
+ rareFinds: runRareFindsSchema.nullish(),
26719
+ install: runInstallSchema.nullish(),
26720
+ save: runSaveSchema.nullish(),
26721
+ money: object({ goal: shortText2.nullish(), purpose: shortText2.nullish() }).strict().nullish(),
26722
+ links: array(object({ label: name, url: string2().url().max(2000) }).strict()).max(50).optional()
26723
+ }).strict();
26724
+ var runListSectionValues = [
26725
+ "orderOfPlay",
26726
+ "quests",
26727
+ "choices",
26728
+ "homes",
26729
+ "people",
26730
+ "mounts",
26731
+ "team",
26732
+ "checklists",
26733
+ "uniques",
26734
+ "links"
26735
+ ];
26736
+ var runListSectionSchema = _enum2(runListSectionValues);
26737
+ var runValueSectionValues = [
26738
+ "theme",
26739
+ "edition",
26740
+ "platform",
26741
+ "modeFlags",
26742
+ "character",
26743
+ "arc",
26744
+ "nextSteps",
26745
+ "achievements",
26746
+ "rareFinds",
26747
+ "install",
26748
+ "save",
26749
+ "money"
26750
+ ];
26751
+ var runValueSectionSchema = _enum2(runValueSectionValues);
26752
+ var label = string2().trim().min(1).max(120);
26753
+ var runChangeSchema = discriminatedUnion("op", [
26522
26754
  object({
26523
- kind: literal("weight"),
26524
- value: number2().positive().max(200000),
26525
- unit: _enum2(["g", "kg"]).default("g"),
26526
- occurredAt: occurredAtSchema
26755
+ op: literal("set"),
26756
+ section: runValueSectionSchema,
26757
+ value: unknown(),
26758
+ label: label.optional()
26527
26759
  }).strict(),
26528
26760
  object({
26529
- kind: literal("length"),
26530
- value: number2().positive().max(5000),
26531
- occurredAt: occurredAtSchema
26761
+ op: literal("merge"),
26762
+ section: _enum2([
26763
+ "character",
26764
+ "arc",
26765
+ "nextSteps",
26766
+ "achievements",
26767
+ "rareFinds",
26768
+ "install",
26769
+ "money"
26770
+ ]),
26771
+ value: record(string2(), unknown()),
26772
+ label: label.optional()
26532
26773
  }).strict(),
26533
26774
  object({
26534
- kind: literal("eggs"),
26535
- count: number2().int().min(0).max(500),
26536
- occurredAt: occurredAtSchema
26775
+ op: literal("upsert"),
26776
+ section: runListSectionSchema,
26777
+ value: record(string2(), unknown()),
26778
+ label: label.optional()
26537
26779
  }).strict(),
26538
26780
  object({
26539
- kind: literal("note"),
26540
- text: string2().trim().min(1).max(1000),
26541
- occurredAt: occurredAtSchema
26781
+ op: literal("remove"),
26782
+ section: runListSectionSchema,
26783
+ match: string2().trim().min(1).max(200),
26784
+ label: label.optional()
26785
+ }).strict(),
26786
+ object({
26787
+ op: literal("tick"),
26788
+ section: literal("checklists"),
26789
+ key: string2().trim().min(1).max(60),
26790
+ ids: array(ref).min(1).max(5000),
26791
+ done: boolean3().default(true),
26792
+ label: label.optional()
26542
26793
  }).strict()
26543
26794
  ]);
26544
- var animalVetVisitSourceSchema = _enum2(["sticker", "photo", "said"]);
26545
- var visitTextSchema = string2().trim().min(1).max(120);
26546
- var visitCostSchema = object({
26547
- amount: number2().positive().max(1e5),
26548
- currency: string2().trim().length(3).default("EUR")
26549
- }).strict();
26550
- var animalVetVisitInputSchema = object({
26551
- id: ulidSchema,
26552
- at: exports_coerce.date().optional(),
26553
- vetContactId: ulidSchema.optional(),
26554
- clinician: visitTextSchema.optional(),
26555
- reason: visitTextSchema.optional(),
26556
- vaccine: object({ name: visitTextSchema, source: animalVetVisitSourceSchema.optional() }).strict().optional(),
26557
- dewormer: visitTextSchema.optional(),
26558
- weight: object({
26559
- value: number2().positive().max(200000),
26560
- unit: _enum2(["g", "kg"]).default("kg")
26561
- }).strict().optional(),
26562
- nextDates: array(object({
26563
- id: ulidSchema,
26564
- label: visitTextSchema,
26565
- date: string2().regex(/^\d{4}-\d{2}-\d{2}$/, "expected YYYY-MM-DD")
26566
- }).strict()).max(5).default([]),
26567
- files: array(object({ id: ulidSchema, name: visitTextSchema.optional() }).strict()).max(5).default([]),
26568
- cost: visitCostSchema.optional()
26569
- }).strict();
26570
- var animalVetVisitPatchSchema = object({
26571
- vetContactId: ulidSchema.nullable().optional(),
26572
- clinician: visitTextSchema.nullable().optional(),
26573
- reason: visitTextSchema.nullable().optional(),
26574
- vaccine: object({ name: visitTextSchema, source: animalVetVisitSourceSchema.optional() }).strict().nullable().optional(),
26575
- dewormer: visitTextSchema.nullable().optional(),
26576
- cost: visitCostSchema.nullable().optional()
26577
- }).strict().refine((v) => Object.keys(v).length > 0, { message: "Change at least one field." });
26578
- var animalVetVisitSchema = object({
26579
- id: ulidSchema,
26580
- animal: object({
26581
- id: ulidSchema,
26582
- title: string2(),
26583
- speciesKey: string2().nullable(),
26584
- speciesClass: animalClassSchema.nullable()
26585
- }),
26586
- at: exports_coerce.date(),
26587
- vet: nodeRefSchema.nullable(),
26588
- clinician: string2().nullable(),
26589
- reason: string2().nullable(),
26590
- vaccine: object({ name: string2(), source: animalVetVisitSourceSchema.nullable() }).nullable(),
26591
- dewormer: string2().nullable(),
26592
- weight: object({
26593
- grams: number2(),
26594
- deltaGrams: number2().nullable(),
26595
- since: string2().nullable()
26596
- }).nullable(),
26597
- keyDates: array(object({ id: string2(), label: string2(), date: string2() })),
26598
- files: array(object({ id: string2(), name: string2() })),
26599
- cost: object({ amount: number2(), currency: string2() }).nullable(),
26600
- byAgent: boolean3(),
26601
- undone: boolean3()
26602
- });
26603
- var animalTimelineEntrySchema = object({
26795
+ var runAppliedChangeSchema = object({ op: string2(), section: string2(), label: string2() }).passthrough();
26796
+ var runChangeBatchSchema = object({
26604
26797
  id: string2(),
26605
26798
  at: exports_coerce.date(),
26606
- kind: _enum2([
26607
- "weight",
26608
- "length",
26609
- "eggs",
26610
- "note",
26611
- "vet_visit",
26612
- "period_started",
26613
- "period_ended",
26614
- "key_date"
26615
- ]),
26616
- animalId: ulidSchema,
26617
- animalTitle: string2(),
26618
- value: number2().nullable(),
26619
- text: string2().nullable(),
26620
- byAgent: boolean3().default(false)
26621
- });
26622
- var animalTimelineQuerySchema = object({
26623
- days: exports_coerce.number().int().min(1).max(3650).default(90)
26799
+ message: string2().nullable().default(null),
26800
+ changes: array(runAppliedChangeSchema),
26801
+ before: record(string2(), unknown()),
26802
+ undoneAt: exports_coerce.date().nullable().default(null)
26624
26803
  });
26625
- var animalEggsTodaySchema = object({
26626
- animalId: ulidSchema,
26804
+ var RUN_SESSION_IDLE_MS = 6 * 60 * 60 * 1000;
26805
+ var applyRunChangesInputSchema = object({
26806
+ changes: array(runChangeSchema).min(1).max(100),
26807
+ message: string2().trim().min(1).max(2000).nullish(),
26808
+ sessionId: ulidSchema.optional(),
26809
+ newSession: boolean3().optional(),
26810
+ recap: string2().trim().min(1).max(2000).optional(),
26811
+ occurredOn: isoDate.optional()
26812
+ }).strict();
26813
+ var tickRunChecklistInputSchema = object({
26814
+ ids: array(ref).min(1).max(5000),
26815
+ done: boolean3().default(true),
26816
+ message: string2().trim().min(1).max(2000).nullish(),
26817
+ sessionId: ulidSchema.optional()
26818
+ }).strict();
26819
+ var undoRunChangesInputSchema = object({ batchId: string2().min(1).max(64).optional() }).strict();
26820
+ var runSessionSchema = collectionEntrySchema.pick({ id: true, occurredOn: true, note: true, minutes: true, createdAt: true }).extend({ batches: array(runChangeBatchSchema) });
26821
+ var createRunSessionInputSchema = object({
26822
+ id: ulidSchema.optional(),
26823
+ occurredOn: isoDate.optional(),
26824
+ recap: string2().trim().min(1).max(2000).nullish(),
26825
+ minutes: number2().int().min(0).max(24 * 60).nullish()
26826
+ }).strict();
26827
+ var updateRunSessionInputSchema = object({
26828
+ occurredOn: isoDate.optional(),
26829
+ recap: string2().trim().min(1).max(2000).nullish(),
26830
+ minutes: number2().int().min(0).max(24 * 60).nullish()
26831
+ }).strict();
26832
+ var runViewSchema = object({
26833
+ id: string2(),
26834
+ gameId: string2(),
26835
+ gameTitle: string2(),
26627
26836
  title: string2(),
26628
- today: number2().int(),
26629
- heads: number2().int(),
26630
- last7: array(animalDayCountSchema)
26631
- });
26632
- var animalsOverviewSchema = object({
26633
- animals: array(animalViewSchema),
26634
- today: object({
26635
- day: string2(),
26636
- eggs: array(animalEggsTodaySchema),
26637
- supplies: array(animalSupplySchema),
26638
- habits: array(animalHabitSchema)
26639
- }),
26640
- comingUp: array(keyDateViewSchema.extend({ vet: string2().nullable() })),
26641
- periods: array(periodViewSchema)
26837
+ status: string2(),
26838
+ facet: runFacetSchema,
26839
+ lastPlayedOn: string2().nullable(),
26840
+ sessionCount: number2().int(),
26841
+ createdAt: exports_coerce.date(),
26842
+ updatedAt: exports_coerce.date()
26642
26843
  });
26643
- var animalHolidayModeSchema = object({
26644
- popHole: boolean3(),
26645
- heater: boolean3(),
26646
- alerts: boolean3(),
26647
- dailyPhoto: boolean3(),
26648
- feedReorder: boolean3()
26844
+ var runDetailSchema = runViewSchema.extend({
26845
+ sessions: array(runSessionSchema)
26649
26846
  });
26650
- var animalHandoverRuleSchema = object({
26651
- sitter: string2().trim().min(1).max(120).optional(),
26652
- houseNote: string2().trim().min(1).max(300).optional(),
26653
- holidayMode: animalHolidayModeSchema.partial().optional(),
26654
- share: object({ tokenHash: string2(), until: string2() }).optional(),
26655
- agentNote: string2().trim().min(1).max(500).optional()
26656
- }).passthrough();
26657
- var animalHandoverQuerySchema = object({ periodId: ulidSchema.optional() });
26658
- var animalHandoverTripSchema = object({
26659
- periodId: ulidSchema.nullable(),
26660
- title: string2(),
26661
- from: string2(),
26662
- to: string2(),
26663
- sitter: string2().nullable(),
26664
- houseNote: string2().nullable(),
26665
- holidayMode: animalHolidayModeSchema,
26666
- sharedUntil: string2().nullable(),
26667
- agentNote: string2().nullable(),
26668
- calendar: string2().nullable()
26847
+ var runChangesResultSchema = object({
26848
+ run: runDetailSchema,
26849
+ sessionId: string2(),
26850
+ batch: runChangeBatchSchema
26669
26851
  });
26670
- var animalHandoverAnimalSchema = object({
26671
- id: ulidSchema,
26672
- title: string2(),
26673
- form: animalFormSchema,
26674
- heads: number2().int(),
26675
- species: string2().nullable(),
26676
- speciesKey: string2().nullable(),
26677
- speciesClass: animalClassSchema.nullable(),
26678
- asleep: boolean3(),
26679
- steps: array(string2()),
26680
- aside: string2().nullable()
26852
+ var runSaveHeaderResultSchema = object({
26853
+ run: runDetailSchema,
26854
+ unchanged: boolean3(),
26855
+ sessionId: string2().nullable(),
26856
+ batch: runChangeBatchSchema.nullable()
26681
26857
  });
26682
- var animalHandoverContactSchema = object({
26858
+ var createRunInputSchema = object({
26683
26859
  id: ulidSchema,
26684
- title: string2(),
26685
- kind: _enum2(["vet", "member"]),
26686
- label: string2().nullable(),
26687
- phone: string2().nullable()
26688
- });
26689
- var animalHandoverSupplySchema = animalSupplySchema.extend({
26690
- lastsTrip: boolean3().nullable()
26860
+ gameId: ulidSchema,
26861
+ title: name,
26862
+ status: runPlayStatusSchema.optional(),
26863
+ facet: runFacetSchema.optional()
26864
+ }).strict();
26865
+ var updateRunInputSchema = object({
26866
+ title: name.optional(),
26867
+ status: runPlayStatusSchema.optional(),
26868
+ facet: runFacetSchema.optional()
26869
+ }).strict();
26870
+ var runsQuerySchema = object({
26871
+ gameId: ulidSchema.optional(),
26872
+ status: runPlayStatusSchema.optional(),
26873
+ theme: runThemeSchema.optional()
26874
+ }).strict();
26875
+
26876
+ // ../../packages/schema/src/contracts/runs-steam.ts
26877
+ var steamIdSchema = string2().trim().regex(/^7656119\d{10}$/, "must be a SteamID64 (17 digits, starting 7656119)");
26878
+ var steamApiKeySchema = string2().trim().regex(/^[0-9A-Fa-f]{32}$/, "must be a Steam Web API key (32 letters and digits)");
26879
+ var steamAccountInputSchema = object({ steamId: steamIdSchema, apiKey: steamApiKeySchema }).strict();
26880
+ var steamAccountStatusSchema = object({
26881
+ connected: boolean3(),
26882
+ games: number2().int().nonnegative(),
26883
+ lastSyncedAt: string2().nullable()
26691
26884
  });
26692
- var animalHandoverHabitSchema = nodeRefSchema.extend({ restsThroughTrip: boolean3() });
26693
- var animalHandoverSchema = object({
26694
- trip: animalHandoverTripSchema.nullable(),
26695
- areaId: ulidSchema.nullable(),
26696
- animals: array(animalHandoverAnimalSchema),
26697
- contacts: array(animalHandoverContactSchema),
26698
- supplies: array(animalHandoverSupplySchema),
26699
- habits: array(animalHandoverHabitSchema),
26700
- sensors: boolean3(),
26701
- generatedAt: exports_coerce.date()
26885
+ var steamSyncInputSchema = object({ gameId: string2().trim().min(1).max(64).optional() }).strict();
26886
+ var steamSyncErrorValues = [
26887
+ "unauthorized",
26888
+ "private",
26889
+ "no_stats",
26890
+ "unavailable",
26891
+ "bad_response"
26892
+ ];
26893
+ var steamSyncErrorSchema = _enum2(steamSyncErrorValues);
26894
+ var steamGameSyncSchema = object({
26895
+ gameId: string2(),
26896
+ gameTitle: string2(),
26897
+ appId: number2().int(),
26898
+ outcome: _enum2(["ok", "failed"]),
26899
+ runs: number2().int().nonnegative(),
26900
+ unlocked: number2().int().nonnegative(),
26901
+ total: number2().int().nonnegative(),
26902
+ error: steamSyncErrorSchema.nullable()
26702
26903
  });
26703
- var animalHolidayModeInputSchema = animalHolidayModeSchema.partial().extend({ periodId: ulidSchema }).strict().refine((v) => Object.keys(v).length > 1, { message: "Turn at least one switch." });
26704
- var animalHandoverShareInputSchema = object({ periodId: ulidSchema }).strict();
26705
- var animalHandoverShareSchema = object({
26706
- token: string2(),
26707
- path: string2(),
26708
- until: string2()
26904
+ var steamSyncResultSchema = object({
26905
+ syncedAt: string2(),
26906
+ games: array(steamGameSyncSchema)
26709
26907
  });
26710
26908
 
26711
26909
  // ../../packages/schema/src/contracts/money-splits.ts
@@ -27584,6 +27782,53 @@ var rsvpAnswersQuerySchema = object({
27584
27782
  householdId: ulidSchema.optional()
27585
27783
  });
27586
27784
 
27785
+ // ../../packages/schema/src/contracts/google-contacts.ts
27786
+ var googleContactsModeSchema = _enum2(["off", "fake", "live"]);
27787
+ var googleContactsStatusSchema = object({
27788
+ available: boolean3(),
27789
+ mode: googleContactsModeSchema,
27790
+ connected: boolean3(),
27791
+ account: string2().nullable()
27792
+ });
27793
+ var googleContactsConnectResultSchema = object({
27794
+ connectionId: ulidSchema,
27795
+ authorizationUrl: string2()
27796
+ });
27797
+ var GOOGLE_CONTACT_FIELDS = ["email", "phone", "birthday"];
27798
+ var googleContactFieldSchema = _enum2(GOOGLE_CONTACT_FIELDS);
27799
+ var googleContactCandidateSchema = object({
27800
+ resourceName: string2(),
27801
+ name: string2(),
27802
+ emails: array(string2()),
27803
+ phones: array(string2()),
27804
+ birthday: object({ date: string2().regex(/^\d{4}-\d{2}-\d{2}$/), yearKnown: boolean3() }).nullable(),
27805
+ match: object({
27806
+ contactId: ulidSchema,
27807
+ title: string2(),
27808
+ by: _enum2(["email", "phone", "name"])
27809
+ }).nullable(),
27810
+ adds: array(googleContactFieldSchema)
27811
+ });
27812
+ var googleContactsQuerySchema = object({
27813
+ q: string2().trim().max(120).optional()
27814
+ });
27815
+ var googleContactsListSchema = object({
27816
+ status: googleContactsStatusSchema,
27817
+ candidates: array(googleContactCandidateSchema)
27818
+ });
27819
+ var importGoogleContactsInputSchema = object({
27820
+ resourceNames: array(string2().trim().regex(/^people\/[A-Za-z0-9_-]{1,120}$/, "a Google person id")).min(1).max(200)
27821
+ }).strict();
27822
+ var googleContactsImportResultSchema = object({
27823
+ created: array(object({ contactId: ulidSchema, title: string2() })),
27824
+ merged: array(object({
27825
+ contactId: ulidSchema,
27826
+ title: string2(),
27827
+ added: array(googleContactFieldSchema)
27828
+ })),
27829
+ missing: array(string2())
27830
+ });
27831
+
27587
27832
  // ../../packages/schema/src/contracts/calendar.ts
27588
27833
  var calendarEventLinkSchema = createSelectSchema(calendarEventLinks, {
27589
27834
  createdAt: exports_coerce.date(),
@@ -29176,7 +29421,7 @@ function parseCapture2(input, now) {
29176
29421
 
29177
29422
  // src/meta.ts
29178
29423
  var CLI_NAME = "do";
29179
- var VERSION = "1.296.0";
29424
+ var VERSION = "1.297.0";
29180
29425
  var API_PREFIX = "/api/v1";
29181
29426
  var DEFAULT_API_URL = "http://localhost:3001";
29182
29427
 
@@ -30349,6 +30594,15 @@ var HEALTH_COMMAND_SPECS = [
30349
30594
  scopes: READ,
30350
30595
  returns: "HealthProfile"
30351
30596
  },
30597
+ {
30598
+ path: ["health", "medical-id"],
30599
+ summary: "Show your Medical ID: name, blood group, allergies, current medications, height, emergency contact.",
30600
+ args: [],
30601
+ flags: [],
30602
+ scopes: READ,
30603
+ returns: "HealthMedicalId",
30604
+ notes: "The few facts someone helping in an emergency needs. The emergency contact comes with their name and phone; a field not set is null. Each read by a key is logged for the member."
30605
+ },
30352
30606
  {
30353
30607
  path: ["health", "profile", "set"],
30354
30608
  summary: `Set profile fields (--data '{"bloodGroup":"A+"}', --notes "Kell negative").`,
@@ -32017,6 +32271,21 @@ var COMMAND_SPECS = [
32017
32271
  returns: "Metric",
32018
32272
  notes: "Logging again the same day replaces that day's point. A bedtime belongs to the night's wake day (logged at 23:30 or the next morning, it lands on the morning). The key must act for a member."
32019
32273
  },
32274
+ {
32275
+ path: ["metrics", "import"],
32276
+ summary: "Import a batch of weight, sleep and bedtime values read off Health Connect (what the Android app sends).",
32277
+ args: [],
32278
+ flags: [
32279
+ {
32280
+ name: "data",
32281
+ type: "string",
32282
+ description: 'The batch as JSON: {"points":[{"key":"sleep","value":7.5,"occurredAt":"2026-10-20T07:00:00Z","recordId":"\u2026"}]} (source defaults to health_connect).'
32283
+ }
32284
+ ],
32285
+ scopes: ["habits:write"],
32286
+ returns: "ImportMetricsResult",
32287
+ notes: "POST /api/v1/metrics/import. Each record lands once (its recordId); one already imported, out of range or in the future is skipped. At most 500 points."
32288
+ },
32020
32289
  {
32021
32290
  path: ["documents", "file"],
32022
32291
  summary: "File a paper in one call (doc_file): the provider, the document, its file and a receipt card.",
@@ -34389,6 +34658,39 @@ var COMMAND_SPECS = [
34389
34658
  returns: "AnimalVetVisit",
34390
34659
  notes: "POST /api/v1/animals/vet-visits/{visitId}/undo. The visit, its weight, its key dates and the filed photos all go back."
34391
34660
  },
34661
+ {
34662
+ path: ["animals", "lost-card"],
34663
+ summary: "An animal's lost-pet card: on or off, its link, and what it could show.",
34664
+ args: [{ name: "id", required: true, description: "Animal ULID." }],
34665
+ flags: [],
34666
+ scopes: ["animals:read"],
34667
+ returns: "AnimalLostCardState",
34668
+ notes: "GET /api/v1/animals/{id}/lost-card. `card` is null while it's off; else its `path` (`/lost/<token>`, the page a QR code opens), what it shows and `preview` (the finder's page). `photos` are the pictures on the animal it may show; `chipOnFile` says whether it can say chipped."
34669
+ },
34670
+ {
34671
+ path: ["animals", "lost-card-set"],
34672
+ summary: "Turn an animal's lost-pet card on, or change what it shows.",
34673
+ args: [{ name: "id", required: true, description: "Animal ULID." }],
34674
+ flags: [
34675
+ {
34676
+ name: "data",
34677
+ type: "string",
34678
+ description: 'JSON: `{ "phone": "+32 470 \u2026", "photoFileId": "\u2026", "showChipped": true, "note": "\u2026" }`; null takes a field off.'
34679
+ }
34680
+ ],
34681
+ scopes: ["animals:write"],
34682
+ returns: "AnimalLostCardState",
34683
+ notes: "PUT /api/v1/animals/{id}/lost-card. An individual still with the household (a lost one included). The name always shows; the photo must be a picture on the animal; `showChipped` needs its chip on file and never shows the number. The link stays the same while the card is on."
34684
+ },
34685
+ {
34686
+ path: ["animals", "lost-card-off"],
34687
+ summary: "Turn an animal's lost-pet card off (its link stops working).",
34688
+ args: [{ name: "id", required: true, description: "Animal ULID." }],
34689
+ flags: [],
34690
+ scopes: ["animals:write"],
34691
+ returns: "void",
34692
+ notes: "DELETE /api/v1/animals/{id}/lost-card. Destructive: a printed QR stops working, so it needs --allow-destructive. Turning it on again makes a new link."
34693
+ },
34392
34694
  {
34393
34695
  path: ["runs", "change"],
34394
34696
  summary: "Apply a chat update to a run: its changes, with a receipt and Undo.",
@@ -34483,6 +34785,74 @@ var COMMAND_SPECS = [
34483
34785
  returns: "SteamSyncResult",
34484
34786
  notes: "POST /api/v1/runs/steam/sync. Writes into each run whose achievements come from Steam or aren't kept yet; runs kept by hand are left alone. Per game: outcome, runs, unlocked, total and the error (unauthorized, private, no_stats, unavailable, bad_response). 409 before Steam is linked."
34485
34787
  },
34788
+ {
34789
+ path: ["sensors", "status"],
34790
+ summary: "Whether the Space has linked Home Assistant, how many entities are mapped, the newest reading.",
34791
+ args: [],
34792
+ flags: [],
34793
+ scopes: ["places:read"],
34794
+ returns: "HomeAssistantStatus",
34795
+ notes: "GET /api/v1/sensors/home-assistant. Home Assistant is linked in the app's Settings \u2192 Home; the token is never returned."
34796
+ },
34797
+ {
34798
+ path: ["sensors", "entities"],
34799
+ summary: "Every entity Home Assistant has, with its state, the reading it likely gives and what it's mapped to.",
34800
+ args: [],
34801
+ flags: [],
34802
+ scopes: ["places:read"],
34803
+ returns: "HomeAssistantEntity[]",
34804
+ notes: "GET /api/v1/sensors/home-assistant/entities. 409 before Home Assistant is linked; 503 when it doesn't answer."
34805
+ },
34806
+ {
34807
+ path: ["sensors", "sync"],
34808
+ summary: "Read every mapped entity now and put its state on the ledger, as the five-minute sync does.",
34809
+ args: [],
34810
+ flags: [],
34811
+ scopes: ["places:write"],
34812
+ returns: "SensorSyncResult",
34813
+ notes: "POST /api/v1/sensors/home-assistant/sync. A room's readings feed its card and the room alarm; an asset's show on its page. Returns entities, written, skipped, missing and the error (unauthorized, unavailable, bad_response). 409 before Home Assistant is linked."
34814
+ },
34815
+ {
34816
+ path: ["sensors", "links"],
34817
+ summary: "The mapped entities, or the ones on one Place or asset.",
34818
+ args: [],
34819
+ flags: [{ name: "node", type: "string", description: "Only the mappings on this node ULID." }],
34820
+ scopes: ["places:read"],
34821
+ returns: "SensorLink[]",
34822
+ notes: "GET /api/v1/sensors/links."
34823
+ },
34824
+ {
34825
+ path: ["sensors", "map"],
34826
+ summary: "Map a Home Assistant entity to a Place, an asset or an animal's room.",
34827
+ args: [
34828
+ {
34829
+ name: "entity",
34830
+ required: true,
34831
+ description: "The entity id, e.g. sensor.shed_temperature."
34832
+ },
34833
+ { name: "node", required: true, description: "The Place, asset or animal ULID." }
34834
+ ],
34835
+ flags: [
34836
+ {
34837
+ name: "reading",
34838
+ type: "string",
34839
+ description: "A room's temp|humidity|heater|water|door|feeder|light, or an asset's state|power|energy."
34840
+ },
34841
+ { name: "label", type: "string", description: "A name for it (Home Assistant's own)." }
34842
+ ],
34843
+ scopes: ["places:write"],
34844
+ returns: "SensorLink",
34845
+ notes: "POST /api/v1/sensors/links. An animal maps to the Place it's housed in (409 when it has none). Mapping an entity again moves it."
34846
+ },
34847
+ {
34848
+ path: ["sensors", "unmap"],
34849
+ summary: "Unmap an entity; the readings it gave stay.",
34850
+ args: [{ name: "link", required: true, description: "The sensor link ULID." }],
34851
+ flags: [],
34852
+ scopes: ["places:write"],
34853
+ returns: "None",
34854
+ notes: "DELETE /api/v1/sensors/links/{id}."
34855
+ },
34486
34856
  {
34487
34857
  path: ["runs", "sessions", "list"],
34488
34858
  summary: "A run's sessions, newest first, with recaps and change batches.",
@@ -34630,6 +35000,30 @@ var COMMAND_SPECS = [
34630
35000
  returns: "PeopleOverview",
34631
35001
  notes: "The Sunday card is `--days 7`. Rhythm is a wish: niceToSee lists only who came round and isn't snoozed, longest first. Never say overdue."
34632
35002
  },
35003
+ {
35004
+ path: ["people", "google"],
35005
+ summary: "Your Google Contacts, to pick from: who they'd merge into and what importing adds.",
35006
+ args: [],
35007
+ flags: [{ name: "q", type: "string", description: "A name or email to narrow to." }],
35008
+ scopes: ["contacts:read"],
35009
+ returns: "GoogleContactsList",
35010
+ notes: "Connecting needs a browser (People \u2192 Import). Not connected: candidates is empty and status.connected false. A key with no member is forbidden."
35011
+ },
35012
+ {
35013
+ path: ["people", "google-import"],
35014
+ summary: "Import the people you picked from Google Contacts (merging, never duplicating).",
35015
+ args: [
35016
+ {
35017
+ name: "resourceNames",
35018
+ required: true,
35019
+ description: "Google person ids (people/c123), as `do people google` lists them."
35020
+ }
35021
+ ],
35022
+ flags: [],
35023
+ scopes: ["contacts:write"],
35024
+ returns: "GoogleContactsImportResult",
35025
+ notes: "Each merges into the contact it matches (email, then phone, then a unique name) and fills in only a missing email, phone or birthday; the rest become new contacts. Ids Google no longer has come back as missing. Not connected is a conflict."
35026
+ },
34633
35027
  {
34634
35028
  path: ["people", "brief"],
34635
35029
  summary: "Before you see them: last seen, life updates, follow-ups, gift ideas, dates.",
@@ -38639,6 +39033,13 @@ var HANDLERS = {
38639
39033
  });
38640
39034
  return { data: await requireClient().post(`/metrics/${key}`, input), render: renderRecord };
38641
39035
  },
39036
+ "metrics import": async ({ flags, requireClient }) => {
39037
+ const input = parseInput(importMetricsInputSchema, {
39038
+ source: "health_connect",
39039
+ ...readDataFlag(flags)
39040
+ });
39041
+ return { data: await requireClient().post("/metrics/import", input), render: renderRecord };
39042
+ },
38642
39043
  "agents list": async ({ requireClient }) => ({
38643
39044
  data: await requireClient().getPage("/agents"),
38644
39045
  render: renderList
@@ -39606,6 +40007,24 @@ var HANDLERS = {
39606
40007
  data: await requireClient().post(`/animals/vet-visits/${requireArg(args, 0, "visit id")}/undo`, {}),
39607
40008
  render: renderRecord
39608
40009
  }),
40010
+ "animals lost-card": async ({ args, requireClient }) => ({
40011
+ data: await requireClient().get(`/animals/${requireArg(args, 0, "animal id")}/lost-card`),
40012
+ render: renderRecord
40013
+ }),
40014
+ "animals lost-card-set": async ({ args, flags, requireClient }) => {
40015
+ const id = requireArg(args, 0, "animal id");
40016
+ const body = parseInput(animalLostCardInputSchema, readDataFlag(flags));
40017
+ return {
40018
+ data: await requireClient().put(`/animals/${id}/lost-card`, body),
40019
+ render: renderRecord
40020
+ };
40021
+ },
40022
+ "animals lost-card-off": async ({ args, flags, requireClient }) => {
40023
+ const id = requireArg(args, 0, "animal id");
40024
+ assertDestructiveAllowed(flags, `turn off the lost-pet card of ${id} (its printed QR stops working)`);
40025
+ await requireClient().delete(`/animals/${id}/lost-card`);
40026
+ return { data: { ok: true, animalId: id }, render: renderRecord };
40027
+ },
39609
40028
  "runs change": async ({ args, flags, requireClient }) => {
39610
40029
  const id = requireArg(args, 0, "run id");
39611
40030
  const body = { ...readDataFlag(flags) };
@@ -39693,6 +40112,38 @@ var HANDLERS = {
39693
40112
  });
39694
40113
  return { data: await requireClient().post("/runs/steam/sync", body), render: renderRecord };
39695
40114
  },
40115
+ "sensors status": async ({ requireClient }) => ({
40116
+ data: await requireClient().get("/sensors/home-assistant"),
40117
+ render: renderRecord
40118
+ }),
40119
+ "sensors entities": async ({ requireClient }) => ({
40120
+ data: await requireClient().get("/sensors/home-assistant/entities"),
40121
+ render: renderList
40122
+ }),
40123
+ "sensors sync": async ({ requireClient }) => ({
40124
+ data: await requireClient().post("/sensors/home-assistant/sync", {}),
40125
+ render: renderRecord
40126
+ }),
40127
+ "sensors links": async ({ flags, requireClient }) => ({
40128
+ data: await requireClient().get("/sensors/links", {
40129
+ query: { nodeId: flagString(flags, "node") }
40130
+ }),
40131
+ render: renderList
40132
+ }),
40133
+ "sensors map": async ({ args, flags, requireClient }) => {
40134
+ const body = parseInput(createSensorLinkInputSchema, {
40135
+ externalId: requireArg(args, 0, "entity id"),
40136
+ nodeId: requireArg(args, 1, "node id"),
40137
+ reading: flagString(flags, "reading"),
40138
+ ...flagString(flags, "label") ? { label: flagString(flags, "label") } : {}
40139
+ });
40140
+ return { data: await requireClient().post("/sensors/links", body), render: renderRecord };
40141
+ },
40142
+ "sensors unmap": async ({ args, requireClient }) => {
40143
+ const id = requireArg(args, 0, "sensor link id");
40144
+ await requireClient().delete(`/sensors/links/${id}`);
40145
+ return { data: { ok: true, unmapped: id }, render: renderRecord };
40146
+ },
39696
40147
  "runs sessions list": async ({ args, requireClient }) => {
39697
40148
  const id = requireArg(args, 0, "run id");
39698
40149
  return { data: await requireClient().get(`/runs/${id}/sessions`), render: renderList };
@@ -39770,6 +40221,10 @@ var HANDLERS = {
39770
40221
  render: renderRecord
39771
40222
  };
39772
40223
  },
40224
+ "health medical-id": async ({ requireClient }) => ({
40225
+ data: await requireClient().get("/health/medical-id"),
40226
+ render: renderRecord
40227
+ }),
39773
40228
  "health summary": async ({ flags, requireClient }) => ({
39774
40229
  data: await requireClient().get("/health/summary", {
39775
40230
  query: { episodeId: flagString(flags, "episode") }
@@ -40017,6 +40472,23 @@ var HANDLERS = {
40017
40472
  const query = days ? { days } : {};
40018
40473
  return { data: await requireClient().get("/people/overview", { query }), render: renderRecord };
40019
40474
  },
40475
+ "people google": async ({ flags, requireClient }) => {
40476
+ const q = flagString(flags, "q");
40477
+ return {
40478
+ data: await requireClient().get("/people/google-contacts", { query: q ? { q } : {} }),
40479
+ render: renderRecord
40480
+ };
40481
+ },
40482
+ "people google-import": async ({ args, requireClient }) => {
40483
+ if (args.length === 0) {
40484
+ throw usageError("people google-import needs Google person ids, e.g. people/c123");
40485
+ }
40486
+ const body = parseInput(importGoogleContactsInputSchema, { resourceNames: args });
40487
+ return {
40488
+ data: await requireClient().post("/people/google-contacts/import", body),
40489
+ render: renderRecord
40490
+ };
40491
+ },
40020
40492
  "people brief": async ({ args, requireClient }) => {
40021
40493
  const id = requireArg(args, 0, "contact id");
40022
40494
  return { data: await requireClient().get(`/people/${id}/brief`), render: renderRecord };