@robbeverhelst/do 1.348.0 → 1.350.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 +544 -88
  2. package/package.json +1 -1
package/dist/do.js CHANGED
@@ -14420,7 +14420,7 @@ var configError = (message) => new CliError("config", message, EXIT.CONFIG);
14420
14420
 
14421
14421
  // src/meta.ts
14422
14422
  var CLI_NAME = "do";
14423
- var VERSION = "1.348.0";
14423
+ var VERSION = "1.350.0";
14424
14424
  var API_PREFIX = "/api/v1";
14425
14425
  var DEFAULT_API_URL = "http://localhost:3001";
14426
14426
 
@@ -18049,7 +18049,8 @@ var habitEntries = pgTable("habit_entries", {
18049
18049
  createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
18050
18050
  externalId: text("external_id"),
18051
18051
  agentId: text("agent_id"),
18052
- note: text("note")
18052
+ note: text("note"),
18053
+ matchedName: text("matched_name")
18053
18054
  }, (t) => [
18054
18055
  index("habit_entries_habit_occurred_idx").on(t.habitId, t.occurredAt),
18055
18056
  uniqueIndex("habit_entries_habit_external_uniq").on(t.habitId, t.externalId).where(sql`${t.externalId} IS NOT NULL`)
@@ -19218,7 +19219,10 @@ var agentChangeSchema = object({
19218
19219
  checkIn: object({
19219
19220
  value: number2(),
19220
19221
  unit: string2().nullable(),
19221
- measurementType: habitMeasurementTypeSchema
19222
+ measurementType: habitMeasurementTypeSchema,
19223
+ matched: string2().nullish(),
19224
+ target: number2().nullish(),
19225
+ dayValue: number2().nullish()
19222
19226
  }).optional()
19223
19227
  });
19224
19228
  var agentChangesPageSchema = object({
@@ -20825,7 +20829,10 @@ var animalHandoverContactSchema = object({
20825
20829
  var animalHandoverSupplySchema = animalSupplySchema.extend({
20826
20830
  lastsTrip: boolean2().nullable()
20827
20831
  });
20828
- var animalHandoverHabitSchema = nodeRefSchema.extend({ restsThroughTrip: boolean2() });
20832
+ var animalHandoverHabitSchema = nodeRefSchema.extend({
20833
+ restsThroughTrip: boolean2(),
20834
+ timeOfDay: string2().nullable().default(null)
20835
+ });
20829
20836
  var animalHandoverSchema = object({
20830
20837
  trip: animalHandoverTripSchema.nullable(),
20831
20838
  areaId: ulidSchema.nullable(),
@@ -21408,7 +21415,8 @@ var habitEntrySchema = createSelectSchema(habitEntries, {
21408
21415
  externalId: string2().nullish(),
21409
21416
  kind: habitEntryKindSchema.default("check_in"),
21410
21417
  agentId: string2().nullish(),
21411
- note: string2().nullish()
21418
+ note: string2().nullish(),
21419
+ matchedName: string2().nullish()
21412
21420
  }).extend({
21413
21421
  by: string2().nullish()
21414
21422
  });
@@ -21495,7 +21503,8 @@ var updateHabitInputSchema = createUpdateSchema(habits, {
21495
21503
  ...eventColumns
21496
21504
  }).extend({
21497
21505
  title: string2().min(1).optional(),
21498
- schedule: habitScheduleSchema.optional()
21506
+ schedule: habitScheduleSchema.optional(),
21507
+ displayKind: string2().trim().min(1).max(40).optional()
21499
21508
  });
21500
21509
  var HABIT_ENTRY_NOTE_MAX = 280;
21501
21510
  var habitEntryNoteSchema = string2().trim().max(HABIT_ENTRY_NOTE_MAX).transform((note) => note === "" ? null : note);
@@ -21523,7 +21532,9 @@ var habitStreakSchema = object({
21523
21532
  });
21524
21533
  var habitRoutineRefSchema = object({
21525
21534
  id: ulidSchema,
21526
- title: string2()
21535
+ title: string2(),
21536
+ path: array(string2()).default([]),
21537
+ step: number2().int().positive().nullable().default(null)
21527
21538
  });
21528
21539
  var habitLastCheckInSchema = object({
21529
21540
  at: exports_coerce.date(),
@@ -21603,20 +21614,49 @@ var habitCheckInByTitleInputSchema = object({
21603
21614
  value: number2().nonnegative().optional(),
21604
21615
  mode: habitCheckInModeSchema.default("add"),
21605
21616
  occurredAt: union([civilDateSchema, exports_coerce.date()]).optional(),
21606
- note: habitEntryNoteSchema.nullish()
21617
+ note: habitEntryNoteSchema.nullish(),
21618
+ again: boolean2().optional()
21607
21619
  }).strict();
21608
21620
  var habitCandidateSchema = object({
21609
21621
  id: ulidSchema,
21610
21622
  title: string2(),
21611
- aliases: array(string2())
21623
+ aliases: array(string2()),
21624
+ standing: string2().optional()
21625
+ });
21626
+ var habitCheckInQuestionSchema = object({
21627
+ prompt: string2(),
21628
+ options: array(string2()).min(2)
21612
21629
  });
21613
21630
  var habitCheckInAmbiguousSchema = object({
21614
21631
  error: object({
21615
21632
  code: literal("ambiguous_habit"),
21616
21633
  message: string2(),
21617
- details: object({ candidates: array(habitCandidateSchema).min(2) })
21634
+ details: object({
21635
+ candidates: array(habitCandidateSchema).min(2),
21636
+ question: habitCheckInQuestionSchema.optional()
21637
+ })
21638
+ })
21639
+ });
21640
+ var habitCheckInAlreadyMetSchema = object({
21641
+ error: object({
21642
+ code: literal("already_met"),
21643
+ message: string2(),
21644
+ details: object({ habit: habitCandidateSchema, question: habitCheckInQuestionSchema })
21618
21645
  })
21619
21646
  });
21647
+ var habitCheckInReceiptSchema = object({
21648
+ entryId: ulidSchema,
21649
+ habitId: ulidSchema,
21650
+ title: string2(),
21651
+ matched: string2(),
21652
+ value: number2(),
21653
+ occurredAt: exports_coerce.date(),
21654
+ paused: boolean2(),
21655
+ says: string2()
21656
+ });
21657
+ var habitCheckInByTitleResultSchema = habitSummarySchema.extend({
21658
+ receipt: habitCheckInReceiptSchema.nullable()
21659
+ });
21620
21660
  var habitAliasInputSchema = object({ alias: habitAliasSchema }).strict();
21621
21661
  var habitSkipInputSchema = object({
21622
21662
  date: exports_iso.date().optional(),
@@ -24669,6 +24709,198 @@ var calendarOperations = defineOperations({
24669
24709
  }
24670
24710
  });
24671
24711
 
24712
+ // ../../packages/schema/src/contracts/challenges.ts
24713
+ var challengeStatusSchema = _enum2(["upcoming", "active", "ended"]);
24714
+ var challengeSchema = createSelectSchema(challenges, {
24715
+ startAt: exports_coerce.date(),
24716
+ endAt: exports_coerce.date(),
24717
+ createdAt: exports_coerce.date(),
24718
+ updatedAt: exports_coerce.date()
24719
+ });
24720
+ var createChallengeInputSchema = createInsertSchema(challenges, {
24721
+ id: ulidSchema,
24722
+ title: string2().min(1),
24723
+ description: string2().nullish(),
24724
+ metric: string2().min(1),
24725
+ target: number2().int().positive(),
24726
+ startAt: exports_coerce.date(),
24727
+ endAt: exports_coerce.date(),
24728
+ subjectType: challengeSubjectTypeSchema.nullish(),
24729
+ subjectId: string2().min(1).nullish()
24730
+ }).omit({ tenantId: true, source: true, createdBy: true, createdAt: true, updatedAt: true }).strict().refine((v) => v.endAt > v.startAt, {
24731
+ message: "endAt must be after startAt",
24732
+ path: ["endAt"]
24733
+ }).refine((v) => v.subjectType == null === (v.subjectId == null), {
24734
+ message: "subjectType and subjectId must be set together",
24735
+ path: ["subjectId"]
24736
+ });
24737
+ var challengePartKindSchema = _enum2(challengePartKind.enumValues);
24738
+ var createChallengePartInputSchema = object({
24739
+ kind: challengePartKindSchema,
24740
+ subjectId: ulidSchema,
24741
+ resumeOnStart: boolean2().optional()
24742
+ }).strict().refine((p) => !p.resumeOnStart || p.kind === "habit", {
24743
+ message: "only a habit part can resume on the start day",
24744
+ path: ["resumeOnStart"]
24745
+ });
24746
+ var CHALLENGE_MAX_PARTS = 5;
24747
+ var createChallengeWithPartsInputSchema = object({
24748
+ id: ulidSchema.optional(),
24749
+ title: string2().trim().min(1),
24750
+ description: string2().nullish(),
24751
+ startOn: exports_iso.date(),
24752
+ endOn: exports_iso.date(),
24753
+ projectId: ulidSchema.nullish(),
24754
+ parts: array(createChallengePartInputSchema).min(1).max(CHALLENGE_MAX_PARTS)
24755
+ }).strict().refine((v) => v.endOn >= v.startOn, {
24756
+ message: "endOn must not be before startOn",
24757
+ path: ["endOn"]
24758
+ });
24759
+ var updateChallengeInputSchema = object({
24760
+ title: string2().trim().min(1),
24761
+ description: string2().nullish(),
24762
+ startOn: exports_iso.date(),
24763
+ endOn: exports_iso.date(),
24764
+ projectId: ulidSchema.nullish(),
24765
+ parts: array(createChallengePartInputSchema).min(1).max(CHALLENGE_MAX_PARTS)
24766
+ }).strict().refine((v) => v.endOn >= v.startOn, {
24767
+ message: "endOn must not be before startOn",
24768
+ path: ["endOn"]
24769
+ });
24770
+ var createChallengeRequestSchema = union([
24771
+ createChallengeWithPartsInputSchema,
24772
+ createChallengeInputSchema
24773
+ ]);
24774
+ var listChallengesQuerySchema = object({ projectId: ulidSchema.optional(), habitId: ulidSchema.optional() }).strict();
24775
+ var challengePartStatusSchema = _enum2(["done", "running", "waiting"]);
24776
+ var challengePartViewSchema = object({
24777
+ kind: challengePartKindSchema,
24778
+ subjectId: string2(),
24779
+ title: string2().nullable(),
24780
+ scheduleLabel: string2(),
24781
+ done: number2().int().nonnegative(),
24782
+ due: number2().int().nonnegative(),
24783
+ status: challengePartStatusSchema,
24784
+ note: string2().nullable(),
24785
+ resumeOnStart: boolean2().optional()
24786
+ });
24787
+ var challengeDayStatusSchema = _enum2(["met", "missed", "open", "later"]);
24788
+ var challengeDaySchema = object({
24789
+ date: exports_iso.date(),
24790
+ status: challengeDayStatusSchema
24791
+ });
24792
+ var joinChallengeInputSchema = object({ id: ulidSchema }).strict();
24793
+ var challengeViewSchema = challengeSchema.extend({
24794
+ participantCount: number2().int().nonnegative(),
24795
+ joined: boolean2(),
24796
+ progress: number2().int().nonnegative(),
24797
+ status: challengeStatusSchema,
24798
+ completed: boolean2(),
24799
+ subjectTitle: string2().nullable(),
24800
+ dayNumber: number2().int().nonnegative(),
24801
+ dayCount: number2().int().nonnegative(),
24802
+ projectTitle: string2().nullable(),
24803
+ parts: array(challengePartViewSchema),
24804
+ days: array(challengeDaySchema)
24805
+ });
24806
+ var challengeLeaderboardEntrySchema = object({
24807
+ userId: ulidSchema,
24808
+ email: string2(),
24809
+ progress: number2().int().nonnegative(),
24810
+ rank: number2().int().positive(),
24811
+ completed: boolean2()
24812
+ });
24813
+ var selfComparisonMetricSchema = object({
24814
+ metric: string2(),
24815
+ thisWeek: number2().int().nonnegative(),
24816
+ fourWeekAverage: number2().nonnegative(),
24817
+ deltaPct: number2().nullable(),
24818
+ personalBest: number2().int().nonnegative(),
24819
+ isPersonalBest: boolean2()
24820
+ });
24821
+ var selfComparisonSchema = object({
24822
+ weekStart: exports_coerce.date(),
24823
+ metrics: array(selfComparisonMetricSchema)
24824
+ });
24825
+
24826
+ // ../../packages/schema/src/operations/challenges.ts
24827
+ var NO_MEMBER = "The key acts for no member.";
24828
+ var challengeOperations = defineOperations({
24829
+ list: {
24830
+ method: "get",
24831
+ path: "/challenges",
24832
+ scopes: ["habits:read"],
24833
+ tag: "Habits",
24834
+ summary: "List challenges",
24835
+ description: "Every challenge in the key's Space, newest first, each with its status (upcoming, active or ended), Day N of M, its parts with done vs due so far and their status, its days (met, missed, open or later) and its linked project. `projectId` or `habitId` keeps the challenges a project or a habit is in.",
24836
+ query: [
24837
+ { name: "projectId", description: "Only the challenges linked to this project." },
24838
+ { name: "habitId", description: "Only the challenges with this habit as a part." }
24839
+ ],
24840
+ querySchema: listChallengesQuerySchema,
24841
+ status: 200,
24842
+ response: { description: "The Space's challenges.", list: true },
24843
+ errors: { 400: true, 403: NO_MEMBER }
24844
+ },
24845
+ get: {
24846
+ method: "get",
24847
+ path: "/challenges/{id}",
24848
+ scopes: ["habits:read"],
24849
+ tag: "Habits",
24850
+ summary: "Show a challenge",
24851
+ description: "One challenge with the key's member's progress: Day N of M, each part's schedule, done vs due, status and next note, and each calendar day's state.",
24852
+ status: 200,
24853
+ response: { description: "The challenge." },
24854
+ errors: { 403: NO_MEMBER, 404: true }
24855
+ },
24856
+ create: {
24857
+ method: "post",
24858
+ path: "/challenges",
24859
+ scopes: ["habits:write"],
24860
+ tag: "Habits",
24861
+ summary: "Create a challenge",
24862
+ description: "A challenge from `startOn` to `endOn` (both included) with one to five parts (`habit` or `task_series`, each by id; a paused habit part may `resumeOnStart`) and an optional `projectId`; or a legacy metric challenge (`metric`, `target`, `startAt`, `endAt`). The key's member joins it.",
24863
+ body: createChallengeRequestSchema,
24864
+ status: 201,
24865
+ response: { description: "The created challenge." },
24866
+ errors: { 400: true, 403: NO_MEMBER, 409: true }
24867
+ },
24868
+ update: {
24869
+ method: "patch",
24870
+ path: "/challenges/{id}",
24871
+ scopes: ["habits:write"],
24872
+ tag: "Habits",
24873
+ summary: "Update a challenge",
24874
+ description: "The whole form again: title, description, start and end day, project and parts (replaced in their order).",
24875
+ body: updateChallengeInputSchema,
24876
+ status: 200,
24877
+ response: { description: "The challenge." },
24878
+ errors: { 400: true, 403: NO_MEMBER, 404: true }
24879
+ },
24880
+ end: {
24881
+ method: "post",
24882
+ path: "/challenges/{id}/end",
24883
+ scopes: ["habits:write"],
24884
+ tag: "Habits",
24885
+ summary: "End a challenge early",
24886
+ description: "Its window closes now and it reads as ended. One that hasn't started is a 400 (delete it instead).",
24887
+ status: 200,
24888
+ response: { description: "The ended challenge." },
24889
+ errors: { 400: true, 403: NO_MEMBER, 404: true }
24890
+ },
24891
+ remove: {
24892
+ method: "delete",
24893
+ path: "/challenges/{id}",
24894
+ scopes: ["habits:write"],
24895
+ tag: "Habits",
24896
+ summary: "Delete a challenge",
24897
+ description: "Gone for good, with its parts and who joined; its habits and task series stay.",
24898
+ status: 204,
24899
+ response: { description: "Deleted." },
24900
+ errors: { 403: NO_MEMBER, 404: true }
24901
+ }
24902
+ });
24903
+
24672
24904
  // ../../packages/schema/src/operations/changes.ts
24673
24905
  var changesOperations = defineOperations({
24674
24906
  list: {
@@ -28869,7 +29101,7 @@ var foodPatternsSchema = object({
28869
29101
  });
28870
29102
 
28871
29103
  // ../../packages/schema/src/operations/food-log.ts
28872
- var NO_MEMBER = "The key holds no health scope by name, or has no member behind it.";
29104
+ var NO_MEMBER2 = "The key holds no health scope by name, or has no member behind it.";
28873
29105
  var HIDDEN2 = "No such meal, or it isn't the key's member's.";
28874
29106
  var RECEIPT2 = "The meal with its `receipt`: a headline with the kcal range, a confidence word (close \xB7 estimate \xB7 rough), a line per item with its source, and the Undo / Edit / Save as my meal calls.";
28875
29107
  var ITEM = "Each item: `label` and one of `foodId` (from `GET /api/v1/foods/search`), `productId` or `recipeId`, with `grams`, `quantity` + `unit` (`2 boterham`, `1 el`) or `servings`; optional `gramsLow`/`gramsHigh` and `matchConfidence`. With no reference, an `estimate` `{kcal, proteinG, carbsG, fatG}` (a labelled guess). The numbers are computed: table \xD7 grams.";
@@ -28890,7 +29122,7 @@ var foodLogOperations = defineOperations({
28890
29122
  querySchema: mealLogListQuerySchema,
28891
29123
  status: 200,
28892
29124
  response: { description: "The meals." },
28893
- errors: { 400: true, 403: NO_MEMBER }
29125
+ errors: { 400: true, 403: NO_MEMBER2 }
28894
29126
  },
28895
29127
  create: {
28896
29128
  method: "post",
@@ -28902,7 +29134,7 @@ var foodLogOperations = defineOperations({
28902
29134
  body: createMealLogInputSchema,
28903
29135
  status: 201,
28904
29136
  response: { description: RECEIPT2 },
28905
- errors: { 400: true, 403: NO_MEMBER },
29137
+ errors: { 400: true, 403: NO_MEMBER2 },
28906
29138
  operationId: "food_log"
28907
29139
  },
28908
29140
  get: {
@@ -29012,7 +29244,7 @@ var foodLogOperations = defineOperations({
29012
29244
  body: writeFoodWeekReadInputSchema,
29013
29245
  status: 200,
29014
29246
  response: { description: "The food week, with its read." },
29015
- errors: { 400: true, 403: NO_MEMBER },
29247
+ errors: { 400: true, 403: NO_MEMBER2 },
29016
29248
  operationId: "food_week_read"
29017
29249
  },
29018
29250
  removeWeekRead: {
@@ -29026,7 +29258,7 @@ var foodLogOperations = defineOperations({
29026
29258
  querySchema: foodWeekReadQuerySchema,
29027
29259
  status: 204,
29028
29260
  response: { description: "Taken back." },
29029
- errors: { 400: true, 403: NO_MEMBER },
29261
+ errors: { 400: true, 403: NO_MEMBER2 },
29030
29262
  operationId: "food_week_read_remove"
29031
29263
  },
29032
29264
  patterns: {
@@ -29050,7 +29282,7 @@ var foodLogOperations = defineOperations({
29050
29282
  body: proposeFoodTrialInputSchema,
29051
29283
  status: 201,
29052
29284
  response: { description: "The trial, proposed." },
29053
- errors: { 400: true, 403: NO_MEMBER },
29285
+ errors: { 400: true, 403: NO_MEMBER2 },
29054
29286
  operationId: "food_trial"
29055
29287
  },
29056
29288
  stopTrial: {
@@ -29081,7 +29313,7 @@ var foodLogOperations = defineOperations({
29081
29313
  querySchema: foodDaysQuerySchema,
29082
29314
  status: 200,
29083
29315
  response: { description: "The days." },
29084
- errors: { 400: true, 403: NO_MEMBER }
29316
+ errors: { 400: true, 403: NO_MEMBER2 }
29085
29317
  },
29086
29318
  day: {
29087
29319
  method: "get",
@@ -29094,7 +29326,7 @@ var foodLogOperations = defineOperations({
29094
29326
  description: "One day: its meals, its total (null when nothing is logged) and the household's planned meals for it.",
29095
29327
  status: 200,
29096
29328
  response: { description: "The day." },
29097
- errors: { 400: true, 403: NO_MEMBER }
29329
+ errors: { 400: true, 403: NO_MEMBER2 }
29098
29330
  },
29099
29331
  recall: {
29100
29332
  method: "get",
@@ -29105,7 +29337,7 @@ var foodLogOperations = defineOperations({
29105
29337
  description: `What the member eats often: their most-logged meals of the last 30 days (with the last one's id, to log it again) and their saved meals. Use it before asking what "the usual" is.`,
29106
29338
  status: 200,
29107
29339
  response: { description: "Frequent and saved meals." },
29108
- errors: { 403: NO_MEMBER },
29340
+ errors: { 403: NO_MEMBER2 },
29109
29341
  operationId: "food_recall"
29110
29342
  }
29111
29343
  });
@@ -30185,14 +30417,14 @@ var habitOperations = defineOperations({
30185
30417
  scopes: ["habits:write"],
30186
30418
  tag: "Habits",
30187
30419
  summary: "Check in a habit by title",
30188
- description: 'Check in the habit whose `title` or one of whose aliases is this (case-insensitive) \u2014 "wake", "did my run", "meditated". `value` defaults to 1. `mode: "add"` (default) logs it on top of the day ("12 pages"); `mode: "set"` makes it the day\'s total ("read 40 total") by writing one entry with the difference, keeping earlier check-ins (amount habits only, else 400). `occurredAt` back-dates it: an instant, or a `YYYY-MM-DD` member\'s day (noon in their zone); `set` works on the member\'s day it lands in. Several matching habits are a 409 with `error.code: "ambiguous_habit"` and `error.details.candidates` (`id`, `title`, `aliases`) to ask which; none is a 404 naming close titles; a habit counted from an ingest (Google Fit, Strava, GitHub) is a 409 \u2014 it checks itself in. An Agent\'s key records an `agent` check-in naming the Agent. `note` puts a short note on the check-in ("drill done, felt heavy" \u2192 `note: "felt heavy"`); a `set` that changes nothing puts it on the day\'s latest check-in. The refreshed habit\'s `lastCheckIn.id` is the entry, for adding a note later. Returns the refreshed habit; fires `habit.updated`.',
30420
+ description: 'Check in the habit whose `title` or one of whose aliases is this (case-insensitive) \u2014 "wake", "did my run", "meditated". `value` defaults to 1. `mode: "add"` (default) logs it on top of the day ("12 pages"); `mode: "set"` makes it the day\'s total ("read 40 total") by writing one entry with the difference, keeping earlier check-ins (amount habits only, else 400). `occurredAt` back-dates it: an instant, or a `YYYY-MM-DD` member\'s day (noon in their zone); `set` works on the member\'s day it lands in. Several matching habits are a 409 with `error.code: "ambiguous_habit"`, `error.details.candidates` (`id`, `title`, `aliases`, `standing`: "done, 07:03", "tonight") and `error.details.question` ("Which one? \u2026", one answer per habit and "Neither") to ask which, never a guessed tick; none is a 404 naming close titles; a habit counted from an ingest (Google Fit, Strava, GitHub) is a 409 ("Checked in by Google Fit: \u2026 counts itself.") \u2014 it checks itself in; a yes/no habit already done today is a 409 `already_met` with `error.details.habit` and `error.details.question` ("\u2026 Tick it again?"), unless `again: true`. A paused habit is ticked; its streak waits. An Agent\'s key records an `agent` check-in naming the Agent. `note` puts a short note on the check-in ("drill done, felt heavy" \u2192 `note: "felt heavy"`); a `set` that changes nothing puts it on the day\'s latest check-in. The refreshed habit\'s `lastCheckIn.id` is the entry, for adding a note later. Returns the refreshed habit with its `receipt` (`entryId`, undone with `DELETE /habits/{id}/check-ins/{entryId}`; `habitId`, `title`, `matched`: the alias or title the words matched, `value`, `occurredAt`, `paused`, `says`: "Water the plants, 3 of 4"), null when a `set` changed nothing; fires `habit.updated`.',
30189
30421
  body: habitCheckInByTitleInputSchema,
30190
30422
  status: 201,
30191
- response: { description: "The refreshed habit." },
30423
+ response: { description: "The refreshed habit, with its check-in's receipt." },
30192
30424
  errors: {
30193
30425
  400: true,
30194
30426
  404: true,
30195
- 409: "Several habits answer to the title (with the candidates), or it is counted from an ingest."
30427
+ 409: "Several habits answer to the title (with the candidates and the question), it is counted from an ingest, or a yes/no habit is already done today (already_met)."
30196
30428
  },
30197
30429
  webhook: "habit.updated"
30198
30430
  },
@@ -34408,7 +34640,7 @@ var memberOperations = defineOperations({
34408
34640
  });
34409
34641
 
34410
34642
  // ../../packages/schema/src/operations/metrics.ts
34411
- var NO_MEMBER2 = "The key acts for no member.";
34643
+ var NO_MEMBER3 = "The key acts for no member.";
34412
34644
  var metricOperations = defineOperations({
34413
34645
  list: {
34414
34646
  method: "get",
@@ -34423,7 +34655,7 @@ var metricOperations = defineOperations({
34423
34655
  querySchema: metricsQuerySchema,
34424
34656
  status: 200,
34425
34657
  response: { description: "Every Metric with its points." },
34426
- errors: { 403: NO_MEMBER2 }
34658
+ errors: { 403: NO_MEMBER3 }
34427
34659
  },
34428
34660
  sessions: {
34429
34661
  method: "get",
@@ -34438,7 +34670,7 @@ var metricOperations = defineOperations({
34438
34670
  querySchema: sessionsQuerySchema,
34439
34671
  status: 200,
34440
34672
  response: { description: "The sessions." },
34441
- errors: { 403: NO_MEMBER2 }
34673
+ errors: { 403: NO_MEMBER3 }
34442
34674
  },
34443
34675
  import: {
34444
34676
  method: "post",
@@ -34450,7 +34682,7 @@ var metricOperations = defineOperations({
34450
34682
  body: importMetricsInputSchema,
34451
34683
  status: 201,
34452
34684
  response: { description: "How many points landed and how many were skipped." },
34453
- errors: { 400: true, 403: NO_MEMBER2 }
34685
+ errors: { 400: true, 403: NO_MEMBER3 }
34454
34686
  },
34455
34687
  log: {
34456
34688
  method: "post",
@@ -34469,7 +34701,7 @@ var metricOperations = defineOperations({
34469
34701
  body: logMetricInputSchema,
34470
34702
  status: 201,
34471
34703
  response: { description: "The Metric." },
34472
- errors: { 400: true, 403: NO_MEMBER2 }
34704
+ errors: { 400: true, 403: NO_MEMBER3 }
34473
34705
  }
34474
34706
  });
34475
34707
 
@@ -37431,7 +37663,7 @@ var reviewSummarySchema = object({
37431
37663
  }).refine((s) => s.from <= s.to, { message: "from is on or before to", path: ["from"] });
37432
37664
 
37433
37665
  // ../../packages/schema/src/operations/progress.ts
37434
- var NO_MEMBER3 = "The key acts for no member.";
37666
+ var NO_MEMBER4 = "The key acts for no member.";
37435
37667
  var question = {
37436
37668
  question: { description: "The question's key.", enum: insightsQuestionSchema.options }
37437
37669
  };
@@ -37520,7 +37752,7 @@ var progressOperations = defineOperations({
37520
37752
  querySchema: githubCommitsQuerySchema,
37521
37753
  status: 200,
37522
37754
  response: { description: "The split." },
37523
- errors: { 400: true, 403: NO_MEMBER3 }
37755
+ errors: { 400: true, 403: NO_MEMBER4 }
37524
37756
  },
37525
37757
  questions: {
37526
37758
  method: "get",
@@ -37531,7 +37763,7 @@ var progressOperations = defineOperations({
37531
37763
  description: "Insights' answers to its fixed questions, for the key's member only: late nights vs the next day's rating, the morning routine vs the day, good runs, bedtime this week vs usual, what the best days have in common, reading this week vs usual. Each is `shown`, `no_difference` or `collecting` (with `neededDays`); recomputed weekly (Monday 04:00 in the member's zone). Quote `sentence` and `footer` verbatim; a pattern goes together, never a cause. Mention only a Medium or High one.",
37532
37764
  status: 200,
37533
37765
  response: { description: "This week's answers.", view: "InsightsAnswersResponse" },
37534
- errors: { 403: NO_MEMBER3 },
37766
+ errors: { 403: NO_MEMBER4 },
37535
37767
  operationId: "get_insights"
37536
37768
  },
37537
37769
  dismiss: {
@@ -37572,7 +37804,7 @@ var progressOperations = defineOperations({
37572
37804
  body: memberActivityInputSchema,
37573
37805
  status: 201,
37574
37806
  response: { description: "Recorded." },
37575
- errors: { 400: true, 403: NO_MEMBER3 },
37807
+ errors: { 400: true, 403: NO_MEMBER4 },
37576
37808
  operationId: "record_member_activity"
37577
37809
  }
37578
37810
  });
@@ -45031,8 +45263,225 @@ var commands5 = [
45031
45263
  }
45032
45264
  ];
45033
45265
 
45034
- // src/commands/changes.ts
45266
+ // src/commands/challenges.ts
45267
+ var STATUS_TITLE = { active: "Active", upcoming: "Upcoming", ended: "Ended" };
45268
+ var DAY_MARK = { met: "\u25CF", missed: "\u25CB", open: "\u25CC", later: "\xB7" };
45269
+ var day3 = (at) => new Date(at).toISOString().slice(0, 10);
45270
+ function when(c) {
45271
+ if (c.status === "upcoming")
45272
+ return `starts ${day3(c.startAt)}`;
45273
+ if (c.status === "ended")
45274
+ return `ended ${day3(c.endAt)}`;
45275
+ return `Day ${c.dayNumber} of ${c.dayCount}`;
45276
+ }
45277
+ function kept(c) {
45278
+ if (c.parts.length === 0)
45279
+ return `${c.progress} / ${c.target} ${c.metric}`;
45280
+ const met = c.days.filter((d) => d.status === "met").length;
45281
+ const settled = c.days.filter((d) => d.status === "met" || d.status === "missed").length;
45282
+ return `kept ${met} of ${settled} ${settled === 1 ? "day" : "days"}`;
45283
+ }
45284
+ function oneLine(c, mode) {
45285
+ const project = c.projectTitle ? ` ${paint(mode, "dim", `\xB7 ${c.projectTitle}`)}` : "";
45286
+ return ` ${c.title} ${when(c)} ${kept(c)}${project} ${paint(mode, "dim", c.id)}`;
45287
+ }
45288
+ function renderChallenges(data, mode) {
45289
+ const page = data;
45290
+ const list = Array.isArray(page) ? page : page.data;
45291
+ if (list.length === 0)
45292
+ return paint(mode, "dim", "(no challenges)");
45293
+ return ["active", "upcoming", "ended"].map((status) => {
45294
+ const rows = list.filter((c) => c.status === status);
45295
+ if (rows.length === 0)
45296
+ return null;
45297
+ return [paint(mode, "bold", STATUS_TITLE[status]), ...rows.map((c) => oneLine(c, mode))].join(`
45298
+ `);
45299
+ }).filter((group) => group !== null).join(`
45300
+
45301
+ `);
45302
+ }
45303
+ function renderChallenge(data, mode) {
45304
+ const c = data;
45305
+ const head = [
45306
+ `${paint(mode, "bold", c.title)} ${STATUS_TITLE[c.status]} ${when(c)}`,
45307
+ ` ${day3(c.startAt)} to ${day3(c.endAt)}${c.projectTitle ? ` \xB7 ${c.projectTitle}` : ""} ${kept(c)}`
45308
+ ];
45309
+ if (c.parts.length === 0) {
45310
+ const lens = c.subjectTitle ? ` (${c.subjectTitle})` : "";
45311
+ return [...head, ` ${c.metric}: ${c.progress} of ${c.target}${lens}`].join(`
45312
+ `);
45313
+ }
45314
+ const parts = c.parts.map((p) => {
45315
+ const mark = p.status === "done" ? "\u2713" : p.status === "running" ? "\u25B8" : "\xB7";
45316
+ const note = p.note ? ` ${paint(mode, "dim", p.note)}` : "";
45317
+ return ` ${mark} ${p.title ?? "(gone)"} ${paint(mode, "dim", p.scheduleLabel)} ${p.done} of ${p.due} ${p.status}${note}`;
45318
+ });
45319
+ const strip = c.days.map((d) => DAY_MARK[d.status]).join("");
45320
+ return [
45321
+ ...head,
45322
+ "",
45323
+ "Parts",
45324
+ ...parts,
45325
+ "",
45326
+ `Days ${strip}`,
45327
+ paint(mode, "dim", " \u25CF met \u25CB missed \u25CC today \xB7 later")
45328
+ ].join(`
45329
+ `);
45330
+ }
45331
+ var PART_GRAMMAR = "`habit:<id>` or `series:<id>` (a task series); repeat --part for up to five, in order.";
45332
+ function partOf(raw, resume) {
45333
+ const [kind, id] = raw.split(":", 2);
45334
+ if (!id || kind !== "habit" && kind !== "series") {
45335
+ throw usageError(`--part takes ${PART_GRAMMAR} Got "${raw}".`);
45336
+ }
45337
+ if (kind === "series")
45338
+ return { kind: "task_series", subjectId: id };
45339
+ return { kind: "habit", subjectId: id, ...resume.has(id) ? { resumeOnStart: true } : {} };
45340
+ }
45341
+ var FORM_FLAGS = [
45342
+ { name: "from", type: "string", description: "The first day, YYYY-MM-DD." },
45343
+ { name: "to", type: "string", description: "The last day, YYYY-MM-DD (included)." },
45344
+ { name: "part", type: "string", description: `A part: ${PART_GRAMMAR}` },
45345
+ { name: "project", type: "string", description: "The project it's for (its id)." },
45346
+ { name: "description", type: "string", description: "What it's for, in a line." },
45347
+ {
45348
+ name: "resume-on-start",
45349
+ type: "string",
45350
+ description: "A paused habit part (its id) to bring back on the first day; repeat it."
45351
+ }
45352
+ ];
45035
45353
  var commands6 = [
45354
+ defineCommand({
45355
+ operation: challengeOperations.list,
45356
+ path: ["challenges", "list"],
45357
+ summary: "List the challenges: Active, Upcoming, Ended, with Day N of M.",
45358
+ flags: [
45359
+ { name: "project", type: "string", description: "Only those linked to this project." },
45360
+ { name: "habit", type: "string", description: "Only those with this habit as a part." }
45361
+ ],
45362
+ returns: "ChallengeView[]",
45363
+ run: async ({ flags, requireClient }) => {
45364
+ const project = flagString(flags, "project");
45365
+ const habit = flagString(flags, "habit");
45366
+ const query = new URLSearchParams({
45367
+ ...project ? { projectId: project } : {},
45368
+ ...habit ? { habitId: habit } : {}
45369
+ }).toString();
45370
+ return {
45371
+ data: await requireClient().get(`${pathOf(challengeOperations.list)}${query ? `?${query}` : ""}`),
45372
+ render: renderChallenges
45373
+ };
45374
+ }
45375
+ }),
45376
+ defineCommand({
45377
+ operation: challengeOperations.get,
45378
+ path: ["challenges", "show"],
45379
+ summary: "Show a challenge: its parts with done vs due, and a mark per day.",
45380
+ args: [{ name: "challenge", required: true, description: "The challenge's id." }],
45381
+ returns: "ChallengeView",
45382
+ run: async ({ args, requireClient }) => ({
45383
+ data: await requireClient().get(pathOf(challengeOperations.get, { id: requireArg(args, 0, "challenge") })),
45384
+ render: renderChallenge
45385
+ })
45386
+ }),
45387
+ defineCommand({
45388
+ operation: challengeOperations.create,
45389
+ path: ["challenges", "create"],
45390
+ summary: "Create a challenge from --from to --to with one to five --part.",
45391
+ args: [{ name: "title", required: true, description: "The challenge's title." }],
45392
+ flags: [...FORM_FLAGS],
45393
+ returns: "ChallengeView",
45394
+ run: async ({ args, flags, requireClient }) => {
45395
+ const title = args.join(" ").trim();
45396
+ const resume = new Set(flagStrings(flags, "resume-on-start"));
45397
+ const project = flagString(flags, "project");
45398
+ const description = flagString(flags, "description");
45399
+ const body = parseInput(createChallengeWithPartsInputSchema, {
45400
+ id: ulid3(),
45401
+ title,
45402
+ startOn: flagString(flags, "from"),
45403
+ endOn: flagString(flags, "to"),
45404
+ parts: flagStrings(flags, "part").map((p) => partOf(p, resume)),
45405
+ ...project ? { projectId: project } : {},
45406
+ ...description ? { description } : {}
45407
+ });
45408
+ return {
45409
+ data: await requireClient().post(pathOf(challengeOperations.create), body),
45410
+ render: renderChallenge
45411
+ };
45412
+ }
45413
+ }),
45414
+ defineCommand({
45415
+ operation: challengeOperations.update,
45416
+ path: ["challenges", "update"],
45417
+ summary: "Change a challenge: what you pass replaces it; --part replaces all its parts.",
45418
+ args: [{ name: "challenge", required: true, description: "The challenge's id." }],
45419
+ flags: [
45420
+ { name: "title", type: "string", description: "A new title." },
45421
+ ...FORM_FLAGS,
45422
+ { name: "no-project", type: "boolean", description: "Unlink its project." }
45423
+ ],
45424
+ returns: "ChallengeView",
45425
+ run: async ({ args, flags, requireClient }) => {
45426
+ const id = requireArg(args, 0, "challenge");
45427
+ const client = requireClient();
45428
+ const now = await client.get(pathOf(challengeOperations.get, { id }));
45429
+ if (now.parts.length === 0) {
45430
+ throw usageError("A metric challenge has no parts to edit; end it or delete it instead.");
45431
+ }
45432
+ const resume = new Set(flagStrings(flags, "resume-on-start"));
45433
+ const given = flagStrings(flags, "part");
45434
+ const parts = given.length ? given.map((p) => partOf(p, resume)) : now.parts.map((p) => p.kind === "habit" ? {
45435
+ kind: "habit",
45436
+ subjectId: p.subjectId,
45437
+ ...p.resumeOnStart || resume.has(p.subjectId) ? { resumeOnStart: true } : {}
45438
+ } : { kind: p.kind, subjectId: p.subjectId });
45439
+ const description = flagString(flags, "description");
45440
+ const body = parseInput(updateChallengeInputSchema, {
45441
+ title: flagString(flags, "title") ?? now.title,
45442
+ description: description ?? now.description ?? null,
45443
+ startOn: flagString(flags, "from") ?? day3(now.startAt),
45444
+ endOn: flagString(flags, "to") ?? day3(now.endAt),
45445
+ projectId: flagBool(flags, "no-project") ? null : flagString(flags, "project") ?? now.projectId,
45446
+ parts
45447
+ });
45448
+ return {
45449
+ data: await client.patch(pathOf(challengeOperations.update, { id }), body),
45450
+ render: renderChallenge
45451
+ };
45452
+ }
45453
+ }),
45454
+ defineCommand({
45455
+ operation: challengeOperations.end,
45456
+ path: ["challenges", "end"],
45457
+ summary: "End a challenge early: it closes today and reads as ended.",
45458
+ args: [{ name: "challenge", required: true, description: "The challenge's id." }],
45459
+ returns: "ChallengeView",
45460
+ run: async ({ args, requireClient }) => ({
45461
+ data: await requireClient().post(pathOf(challengeOperations.end, { id: requireArg(args, 0, "challenge") }), {}),
45462
+ render: (data, mode) => `Ended early.
45463
+ ${renderChallenge(data, mode)}`
45464
+ })
45465
+ }),
45466
+ defineCommand({
45467
+ operation: challengeOperations.remove,
45468
+ path: ["challenges", "rm"],
45469
+ summary: "Delete a challenge; its habits and task series stay.",
45470
+ args: [{ name: "challenge", required: true, description: "The challenge's id." }],
45471
+ returns: "{ ok, deleted }",
45472
+ run: async ({ args, requireClient }) => {
45473
+ const id = requireArg(args, 0, "challenge");
45474
+ await requireClient().delete(pathOf(challengeOperations.remove, { id }));
45475
+ return {
45476
+ data: { ok: true, deleted: id },
45477
+ render: () => "Deleted the challenge. Its habits and task series stay."
45478
+ };
45479
+ }
45480
+ })
45481
+ ];
45482
+
45483
+ // src/commands/changes.ts
45484
+ var commands7 = [
45036
45485
  {
45037
45486
  spec: {
45038
45487
  path: ["changes"],
@@ -45083,7 +45532,7 @@ function redact(secret) {
45083
45532
  return "********";
45084
45533
  return `${secret.slice(0, 6)}\u2026${secret.slice(-2)}`;
45085
45534
  }
45086
- var commands7 = [
45535
+ var commands8 = [
45087
45536
  {
45088
45537
  spec: {
45089
45538
  path: ["whoami"],
@@ -45251,7 +45700,7 @@ var whereFlags = (flags) => ({
45251
45700
  ...flagString(flags, "chapter") ? { chapter: flagString(flags, "chapter") } : {},
45252
45701
  ...flagString(flags, "linked-note") ? { linkedNoteId: flagString(flags, "linked-note") } : {}
45253
45702
  });
45254
- var commands8 = [
45703
+ var commands9 = [
45255
45704
  {
45256
45705
  spec: {
45257
45706
  path: ["collection", "types"],
@@ -45691,7 +46140,7 @@ var commands8 = [
45691
46140
  ];
45692
46141
 
45693
46142
  // src/commands/comments.ts
45694
- var commands9 = [
46143
+ var commands10 = [
45695
46144
  {
45696
46145
  spec: {
45697
46146
  path: ["comment"],
@@ -46356,7 +46805,7 @@ function renderKraken(data, mode) {
46356
46805
  return lines.join(`
46357
46806
  `);
46358
46807
  }
46359
- var commands10 = pairCommands(CONNECTION_COMMAND_SPECS, CONNECTION_HANDLERS);
46808
+ var commands11 = pairCommands(CONNECTION_COMMAND_SPECS, CONNECTION_HANDLERS);
46360
46809
 
46361
46810
  // src/commands/contacts.ts
46362
46811
  var FIELD_FLAGS = [
@@ -46498,7 +46947,7 @@ function contactBodyFromFlags(flags, base, op, current) {
46498
46947
  }
46499
46948
  return body;
46500
46949
  }
46501
- var commands11 = pairCommands(CONTACT_COMMAND_SPECS, {
46950
+ var commands12 = pairCommands(CONTACT_COMMAND_SPECS, {
46502
46951
  "contacts create": async ({ args, flags, requireClient }) => {
46503
46952
  const name = args.join(" ").trim();
46504
46953
  const base = { id: ulid3(), ...name ? { title: name } : {}, ...readDataFlag(flags) };
@@ -46544,7 +46993,7 @@ var commands11 = pairCommands(CONTACT_COMMAND_SPECS, {
46544
46993
  });
46545
46994
 
46546
46995
  // src/commands/data-export.ts
46547
- var commands12 = [
46996
+ var commands13 = [
46548
46997
  {
46549
46998
  spec: {
46550
46999
  path: ["export"],
@@ -46583,7 +47032,7 @@ function dayDateArg(args, verb) {
46583
47032
  }
46584
47033
  return date;
46585
47034
  }
46586
- var commands13 = [
47035
+ var commands14 = [
46587
47036
  {
46588
47037
  spec: {
46589
47038
  path: ["days", "record"],
@@ -46709,7 +47158,7 @@ var commands13 = [
46709
47158
  // src/commands/documents.ts
46710
47159
  import { readFileSync as readFileSync4 } from "fs";
46711
47160
  import { basename } from "path";
46712
- var commands14 = [
47161
+ var commands15 = [
46713
47162
  {
46714
47163
  spec: {
46715
47164
  path: ["documents", "file"],
@@ -47088,7 +47537,7 @@ async function echoThreadId(client, ref) {
47088
47537
  function splitList(value) {
47089
47538
  return value.split(",").map((v) => v.trim()).filter((v) => v.length > 0);
47090
47539
  }
47091
- var commands15 = [
47540
+ var commands16 = [
47092
47541
  {
47093
47542
  spec: {
47094
47543
  path: ["echo", "post"],
@@ -47407,7 +47856,7 @@ var commands15 = [
47407
47856
  // src/commands/files.ts
47408
47857
  import { readFileSync as readFileSync5, writeFileSync as writeFileSync2 } from "fs";
47409
47858
  import { basename as basename2 } from "path";
47410
- var commands16 = [
47859
+ var commands17 = [
47411
47860
  {
47412
47861
  spec: {
47413
47862
  path: ["files", "list"],
@@ -47577,7 +48026,7 @@ var commands16 = [
47577
48026
  ];
47578
48027
 
47579
48028
  // src/commands/food.ts
47580
- var commands17 = [
48029
+ var commands18 = [
47581
48030
  {
47582
48031
  spec: {
47583
48032
  path: ["foods", "search"],
@@ -48122,7 +48571,7 @@ var commands17 = [
48122
48571
  // src/commands/guest-lists.ts
48123
48572
  import { writeFileSync as writeFileSync3 } from "fs";
48124
48573
  import { basename as basename3 } from "path";
48125
- var commands18 = [
48574
+ var commands19 = [
48126
48575
  {
48127
48576
  spec: {
48128
48577
  path: ["guest-lists", "overview"],
@@ -48212,7 +48661,7 @@ var commands18 = [
48212
48661
  ];
48213
48662
 
48214
48663
  // src/commands/guests.ts
48215
- var commands19 = [
48664
+ var commands20 = [
48216
48665
  {
48217
48666
  spec: {
48218
48667
  path: ["guests", "sent"],
@@ -48376,7 +48825,7 @@ function seasonFromFlags(flags) {
48376
48825
  const season = flagString(flags, "season");
48377
48826
  return season === undefined ? {} : { activeMonths: seasonFromFlag(season) };
48378
48827
  }
48379
- var commands20 = [
48828
+ var commands21 = [
48380
48829
  {
48381
48830
  spec: {
48382
48831
  path: ["habits", "create"],
@@ -48519,11 +48968,16 @@ var commands20 = [
48519
48968
  name: "note",
48520
48969
  type: "string",
48521
48970
  description: 'A short note on the check-in ("felt heavy"), at most 280 characters.'
48971
+ },
48972
+ {
48973
+ name: "again",
48974
+ type: "boolean",
48975
+ description: "Tick a yes/no habit that's already done today once more."
48522
48976
  }
48523
48977
  ],
48524
48978
  scopes: [...habitOperations.checkInByTitle.scopes],
48525
48979
  returns: "HabitSummary",
48526
- notes: `${routeOf(habitOperations.checkInByTitle)}. Title or alias, case-insensitive; several matches \u2192 409 with error.details.candidates (id, title, aliases), none \u2192 404 naming close titles; a habit counted from Google Fit, Strava or GitHub \u2192 409. --set writes the difference to the day's total as its own check-in. An Agent's key records the check-in as that Agent's ("<agent>, 07:12"). --note puts a short note on it ("drill done, felt heavy" \u2192 --note "felt heavy"); the reply's lastCheckIn.id is the check-in, for \`do habit note\` later.`
48980
+ notes: `${routeOf(habitOperations.checkInByTitle)}. Title or alias, case-insensitive; several matches \u2192 409 with error.details.candidates (id, title, aliases, standing) and error.details.question (which one, with "Neither"), none \u2192 404 naming close titles; a habit counted from Google Fit, Strava or GitHub \u2192 409 ("Checked in by \u2026"); a yes/no habit already done today \u2192 409 already_met with its question, unless --again. The reply's receipt names the habit, the alias it matched, the value and time, its words ("Water the plants, 3 of 4"; a paused habit's "the streak waits") and entryId, the check-in to undo. --set writes the difference to the day's total as its own check-in. An Agent's key records the check-in as that Agent's ("<agent>, 07:12"). --note puts a short note on it ("drill done, felt heavy" \u2192 --note "felt heavy"); the reply's lastCheckIn.id is the check-in, for \`do habit note\` later.`
48527
48981
  },
48528
48982
  run: async ({ args, flags, requireClient }) => {
48529
48983
  const title = args.join(" ").trim();
@@ -48543,7 +48997,8 @@ var commands20 = [
48543
48997
  ...value !== undefined ? { value } : {},
48544
48998
  mode: set ? "set" : "add",
48545
48999
  ...at ? { occurredAt: at } : {},
48546
- ...note !== undefined ? { note } : {}
49000
+ ...note !== undefined ? { note } : {},
49001
+ ...flags.again === true ? { again: true } : {}
48547
49002
  });
48548
49003
  return {
48549
49004
  data: await requireClient().post(pathOf(habitOperations.checkInByTitle), input),
@@ -49510,7 +49965,7 @@ function healthRecordHandlers() {
49510
49965
  }
49511
49966
  return out;
49512
49967
  }
49513
- var commands21 = pairCommands(HEALTH_COMMAND_SPECS, {
49968
+ var commands22 = pairCommands(HEALTH_COMMAND_SPECS, {
49514
49969
  ...healthRecordHandlers(),
49515
49970
  "health record": async ({ flags, requireClient }) => {
49516
49971
  const body = parseInput(logHealthInputSchema, readDataFlag(flags));
@@ -49780,7 +50235,7 @@ var commands21 = pairCommands(HEALTH_COMMAND_SPECS, {
49780
50235
  });
49781
50236
 
49782
50237
  // src/commands/house.ts
49783
- var commands22 = [
50238
+ var commands23 = [
49784
50239
  {
49785
50240
  spec: {
49786
50241
  path: ["house"],
@@ -50062,7 +50517,7 @@ function renderSorting(data, _mode) {
50062
50517
  ].join(`
50063
50518
  `);
50064
50519
  }
50065
- var commands23 = [
50520
+ var commands24 = [
50066
50521
  defineCommand({
50067
50522
  operation: inboxOperations.list,
50068
50523
  path: ["inbox"],
@@ -50154,7 +50609,7 @@ var commands23 = [
50154
50609
  ];
50155
50610
 
50156
50611
  // src/commands/incidents.ts
50157
- var commands24 = [
50612
+ var commands25 = [
50158
50613
  {
50159
50614
  spec: {
50160
50615
  path: ["incidents", "open"],
@@ -50383,7 +50838,7 @@ function journalDateArg(args, verb) {
50383
50838
  }
50384
50839
  return date;
50385
50840
  }
50386
- var commands25 = [
50841
+ var commands26 = [
50387
50842
  defineCommand({
50388
50843
  operation: journalOperations.day,
50389
50844
  path: ["journal", "day"],
@@ -50946,7 +51401,7 @@ function renderCreatedKey(data, mode) {
50946
51401
  ].join(`
50947
51402
  `);
50948
51403
  }
50949
- var commands26 = [
51404
+ var commands27 = [
50950
51405
  {
50951
51406
  spec: {
50952
51407
  path: ["keys", "list"],
@@ -51082,7 +51537,7 @@ var KIND_FLAG = {
51082
51537
  type: "string",
51083
51538
  description: "The kind of an unknown word (pages, eggs, health, note, or a word taught before); remembered for the Space."
51084
51539
  };
51085
- var commands27 = [
51540
+ var commands28 = [
51086
51541
  {
51087
51542
  spec: {
51088
51543
  path: ["log"],
@@ -51157,7 +51612,7 @@ var commands27 = [
51157
51612
  ];
51158
51613
 
51159
51614
  // src/commands/mail-campaigns.ts
51160
- var commands28 = [
51615
+ var commands29 = [
51161
51616
  {
51162
51617
  spec: {
51163
51618
  path: ["mail-campaigns", "list"],
@@ -51472,7 +51927,7 @@ async function serveMcp(io, target) {
51472
51927
  }
51473
51928
 
51474
51929
  // src/commands/mcp.ts
51475
- var commands29 = [
51930
+ var commands30 = [
51476
51931
  {
51477
51932
  spec: {
51478
51933
  path: ["mcp"],
@@ -51517,7 +51972,7 @@ var commands29 = [
51517
51972
  ];
51518
51973
 
51519
51974
  // src/commands/members.ts
51520
- var commands30 = [
51975
+ var commands31 = [
51521
51976
  {
51522
51977
  spec: {
51523
51978
  path: ["invite", "create"],
@@ -51642,7 +52097,7 @@ var commands30 = [
51642
52097
  ];
51643
52098
 
51644
52099
  // src/commands/metrics.ts
51645
- var commands31 = [
52100
+ var commands32 = [
51646
52101
  {
51647
52102
  spec: {
51648
52103
  path: ["metrics", "list"],
@@ -51770,7 +52225,7 @@ async function setModuleVisibility(args, requireClient, on) {
51770
52225
  render: renderRecord
51771
52226
  };
51772
52227
  }
51773
- var commands32 = [
52228
+ var commands33 = [
51774
52229
  {
51775
52230
  spec: {
51776
52231
  path: ["modules", "list"],
@@ -51994,7 +52449,7 @@ function shareFlag(flags) {
51994
52449
  function localMonth(now) {
51995
52450
  return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}`;
51996
52451
  }
51997
- var commands33 = [
52452
+ var commands34 = [
51998
52453
  defineCommand({
51999
52454
  operation: moneyOperations.listAccounts,
52000
52455
  path: ["money", "accounts"],
@@ -53136,7 +53591,7 @@ var commands33 = [
53136
53591
  ];
53137
53592
 
53138
53593
  // src/commands/notes.ts
53139
- var commands34 = [
53594
+ var commands35 = [
53140
53595
  {
53141
53596
  spec: {
53142
53597
  path: ["notes", "backlinks"],
@@ -53258,7 +53713,7 @@ var commands34 = [
53258
53713
  ];
53259
53714
 
53260
53715
  // src/commands/orca.ts
53261
- var commands35 = [
53716
+ var commands36 = [
53262
53717
  {
53263
53718
  spec: {
53264
53719
  path: ["orca", "list"],
@@ -53612,7 +54067,7 @@ function linkBody(args) {
53612
54067
  return parseInput(familyTreeLinkInputSchema, { kind, a: ref, b: other });
53613
54068
  throw usageError("the kind is parent, child or partner");
53614
54069
  }
53615
- var commands36 = [
54070
+ var commands37 = [
53616
54071
  {
53617
54072
  spec: {
53618
54073
  path: ["people", "propose"],
@@ -54301,7 +54756,7 @@ var commands36 = [
54301
54756
 
54302
54757
  // src/commands/places.ts
54303
54758
  import { readFileSync as readFileSync10 } from "fs";
54304
- var commands37 = [
54759
+ var commands38 = [
54305
54760
  {
54306
54761
  spec: {
54307
54762
  path: ["places", "import"],
@@ -54358,7 +54813,7 @@ async function planDecision({ args, requireClient }, verb) {
54358
54813
  render: renderPlan
54359
54814
  };
54360
54815
  }
54361
- var commands38 = [
54816
+ var commands39 = [
54362
54817
  {
54363
54818
  spec: {
54364
54819
  path: ["plans", "list"],
@@ -54585,7 +55040,7 @@ var commands38 = [
54585
55040
  ];
54586
55041
 
54587
55042
  // src/commands/presets.ts
54588
- var commands39 = [
55043
+ var commands40 = [
54589
55044
  {
54590
55045
  spec: {
54591
55046
  path: ["presets", "list"],
@@ -54682,7 +55137,7 @@ function renderReviewSummary(data, mode) {
54682
55137
  return out.join(`
54683
55138
  `);
54684
55139
  }
54685
- var commands40 = [
55140
+ var commands41 = [
54686
55141
  {
54687
55142
  spec: {
54688
55143
  path: ["progress"],
@@ -54891,7 +55346,7 @@ function renderUpdates(data, mode) {
54891
55346
  return updates.map((u) => updateLine(u, mode)).join(`
54892
55347
  `);
54893
55348
  }
54894
- var commands41 = [
55349
+ var commands42 = [
54895
55350
  defineCommand({
54896
55351
  operation: projectOperations.update,
54897
55352
  path: ["projects", "set"],
@@ -55488,7 +55943,7 @@ var routineCommands = [
55488
55943
  }
55489
55944
  }
55490
55945
  ];
55491
- var commands42 = [
55946
+ var commands43 = [
55492
55947
  ...routineCommands,
55493
55948
  {
55494
55949
  spec: {
@@ -55611,7 +56066,7 @@ var commands42 = [
55611
56066
  ];
55612
56067
 
55613
56068
  // src/commands/rsvp-answers.ts
55614
- var commands43 = [
56069
+ var commands44 = [
55615
56070
  {
55616
56071
  spec: {
55617
56072
  path: ["rsvp-answers", "list"],
@@ -55665,7 +56120,7 @@ var commands43 = [
55665
56120
  ];
55666
56121
 
55667
56122
  // src/commands/rsvp-links.ts
55668
- var commands44 = [
56123
+ var commands45 = [
55669
56124
  {
55670
56125
  spec: {
55671
56126
  path: ["rsvp-links", "list"],
@@ -55761,7 +56216,7 @@ var commands44 = [
55761
56216
  ];
55762
56217
 
55763
56218
  // src/commands/rsvp-questions.ts
55764
- var commands45 = [
56219
+ var commands46 = [
55765
56220
  {
55766
56221
  spec: {
55767
56222
  path: ["rsvp-questions", "presets"],
@@ -56333,7 +56788,7 @@ function sessionFlags(flags) {
56333
56788
  body.occurredOn = on;
56334
56789
  return body;
56335
56790
  }
56336
- var commands46 = [
56791
+ var commands47 = [
56337
56792
  {
56338
56793
  spec: {
56339
56794
  path: ["runs", "change"],
@@ -56650,7 +57105,7 @@ var commands46 = [
56650
57105
  ];
56651
57106
 
56652
57107
  // src/commands/search.ts
56653
- var commands47 = [
57108
+ var commands48 = [
56654
57109
  {
56655
57110
  spec: {
56656
57111
  path: ["search"],
@@ -56683,7 +57138,7 @@ var commands47 = [
56683
57138
  ];
56684
57139
 
56685
57140
  // src/commands/seating-proposals.ts
56686
- var commands48 = [
57141
+ var commands49 = [
56687
57142
  {
56688
57143
  spec: {
56689
57144
  path: ["seating-proposals", "list"],
@@ -56770,7 +57225,7 @@ var commands48 = [
56770
57225
  ];
56771
57226
 
56772
57227
  // src/commands/sensors.ts
56773
- var commands49 = [
57228
+ var commands50 = [
56774
57229
  {
56775
57230
  spec: {
56776
57231
  path: ["sensors", "status"],
@@ -56930,7 +57385,7 @@ var commands49 = [
56930
57385
  ];
56931
57386
 
56932
57387
  // src/commands/settings.ts
56933
- var commands50 = [
57388
+ var commands51 = [
56934
57389
  {
56935
57390
  spec: {
56936
57391
  path: ["settings", "get"],
@@ -56964,7 +57419,7 @@ var commands50 = [
56964
57419
  ];
56965
57420
 
56966
57421
  // src/commands/sharing.ts
56967
- var commands51 = [
57422
+ var commands52 = [
56968
57423
  {
56969
57424
  spec: {
56970
57425
  path: ["share"],
@@ -57097,7 +57552,7 @@ var commands51 = [
57097
57552
  ];
57098
57553
 
57099
57554
  // src/commands/tap-tags.ts
57100
- var commands52 = [
57555
+ var commands53 = [
57101
57556
  {
57102
57557
  spec: {
57103
57558
  path: ["tap-tags", "tap"],
@@ -57125,7 +57580,7 @@ var BY = {
57125
57580
  type: "string",
57126
57581
  description: "The blocking task's ref (DO-147) or ULID."
57127
57582
  };
57128
- var commands53 = [
57583
+ var commands54 = [
57129
57584
  defineCommand({
57130
57585
  operation: taskBlockOperations.addBlocker,
57131
57586
  path: ["tasks", "block"],
@@ -57191,7 +57646,7 @@ function renderSeries(data, mode) {
57191
57646
  }).join(`
57192
57647
  `);
57193
57648
  }
57194
- var commands54 = [
57649
+ var commands55 = [
57195
57650
  defineCommand({
57196
57651
  operation: taskSeriesOperations.make,
57197
57652
  path: ["tasks", "make-series"],
@@ -57346,7 +57801,7 @@ function repeatFromFlags(flags) {
57346
57801
  out.anchor = "from_completion";
57347
57802
  return out;
57348
57803
  }
57349
- var commands55 = [
57804
+ var commands56 = [
57350
57805
  {
57351
57806
  spec: {
57352
57807
  path: ["capture"],
@@ -57804,7 +58259,7 @@ var commands55 = [
57804
58259
  ];
57805
58260
 
57806
58261
  // src/commands/time-blocks.ts
57807
- var commands56 = [
58262
+ var commands57 = [
57808
58263
  {
57809
58264
  spec: {
57810
58265
  path: ["time-blocks", "record"],
@@ -57985,7 +58440,7 @@ function renderLandedCounts(data, mode) {
57985
58440
  return out.join(`
57986
58441
  `);
57987
58442
  }
57988
- var commands57 = [
58443
+ var commands58 = [
57989
58444
  {
57990
58445
  spec: {
57991
58446
  path: ["today"],
@@ -58357,7 +58812,7 @@ function renderViews(data, mode) {
58357
58812
  function renderView(data, mode) {
58358
58813
  return renderViews([data], mode);
58359
58814
  }
58360
- var commands58 = [
58815
+ var commands59 = [
58361
58816
  defineCommand({
58362
58817
  operation: workViewOperations.list,
58363
58818
  path: ["views", "list"],
@@ -58476,7 +58931,7 @@ var commands58 = [
58476
58931
  ];
58477
58932
 
58478
58933
  // src/commands/worktree-links.ts
58479
- var commands59 = [
58934
+ var commands60 = [
58480
58935
  {
58481
58936
  spec: {
58482
58937
  path: ["worktree-links", "list"],
@@ -58641,7 +59096,8 @@ var FEATURE_COMMANDS = [
58641
59096
  ...commands56,
58642
59097
  ...commands57,
58643
59098
  ...commands58,
58644
- ...commands59
59099
+ ...commands59,
59100
+ ...commands60
58645
59101
  ];
58646
59102
 
58647
59103
  // src/registry.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@robbeverhelst/do",
3
- "version": "1.348.0",
3
+ "version": "1.350.0",
4
4
  "private": false,
5
5
  "description": "do — the agent-drivable CLI over the public /api/v1 surface",
6
6
  "homepage": "https://github.com/robbeverhelst/do/tree/main/apps/cli",