@robbeverhelst/do 1.385.0 → 1.387.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 +742 -115
  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.385.0";
14423
+ var VERSION = "1.387.0";
14424
14424
  var API_PREFIX = "/api/v1";
14425
14425
  var DEFAULT_API_URL = "http://localhost:3001";
14426
14426
 
@@ -18033,7 +18033,8 @@ var habits = pgTable("habits", {
18033
18033
  eventMatch: text("event_match"),
18034
18034
  eventOffset: text("event_offset"),
18035
18035
  durationMinutes: integer2("duration_minutes"),
18036
- activeMonths: integer2("active_months").array()
18036
+ activeMonths: integer2("active_months").array(),
18037
+ checklist: boolean4("checklist").notNull().default(false)
18037
18038
  }, (t) => [
18038
18039
  index("habits_tenant_idx").on(t.tenantId),
18039
18040
  index("habits_tenant_area_idx").on(t.tenantId, t.areaId),
@@ -19054,7 +19055,9 @@ var mealPlans = pgTable("meal_plans", {
19054
19055
  company: text("company"),
19055
19056
  leftoverPortions: integer2("leftover_portions"),
19056
19057
  leftoverEatBy: date5("leftover_eat_by", { mode: "string" }),
19057
- leftoverFrozen: boolean4("leftover_frozen").notNull().default(false)
19058
+ leftoverFrozen: boolean4("leftover_frozen").notNull().default(false),
19059
+ eaterUserIds: text("eater_user_ids").array().notNull().default([]),
19060
+ guests: integer2("guests").notNull().default(0)
19058
19061
  }, (t) => [
19059
19062
  index("meal_plans_tenant_planned_idx").on(t.tenantId, t.plannedFor),
19060
19063
  check2("meal_plans_state_check", sql`${t.state} IN ('planned', 'cooked', 'out', 'unsure', 'draft')`)
@@ -22023,8 +22026,36 @@ var animalOperations = defineOperations({
22023
22026
  }
22024
22027
  });
22025
22028
 
22026
- // ../../packages/schema/src/contracts/habit-sources.ts
22027
- var habitSourceSchema = _enum2(["manual", "google_fit", "strava", "github"]);
22029
+ // ../../packages/schema/src/db/habit-items.ts
22030
+ var habitItems = pgTable("habit_items", {
22031
+ id: text("id").primaryKey(),
22032
+ tenantId: text("tenant_id").notNull().references(() => tenants.id),
22033
+ habitId: text("habit_id").notNull().references(() => habits.id),
22034
+ title: text("title").notNull(),
22035
+ position: integer2("position").notNull().default(0),
22036
+ byDay: text("by_day").array(),
22037
+ timeOfDay: text("time_of_day"),
22038
+ archivedAt: timestamp("archived_at", { withTimezone: true }),
22039
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
22040
+ }, (t) => [
22041
+ index("habit_items_habit_idx").on(t.tenantId, t.habitId, t.position),
22042
+ check2("habit_items_time_of_day_chk", sql`${t.timeOfDay} IS NULL OR ${t.timeOfDay} IN ('morning', 'midday', 'evening')`)
22043
+ ]);
22044
+ var habitItemTicks = pgTable("habit_item_ticks", {
22045
+ id: text("id").primaryKey(),
22046
+ tenantId: text("tenant_id").notNull().references(() => tenants.id),
22047
+ habitId: text("habit_id").notNull().references(() => habits.id),
22048
+ itemId: text("item_id").notNull().references(() => habitItems.id),
22049
+ day: date5("day", { mode: "string" }).notNull(),
22050
+ tickedAt: timestamp("ticked_at", { withTimezone: true }).notNull().defaultNow(),
22051
+ source: habitEntrySource("source").notNull().default("manual"),
22052
+ userId: text("user_id"),
22053
+ agentId: text("agent_id"),
22054
+ routineRunStepId: text("routine_run_step_id")
22055
+ }, (t) => [
22056
+ uniqueIndex("habit_item_ticks_item_day_uniq").on(t.itemId, t.day),
22057
+ index("habit_item_ticks_habit_day_idx").on(t.tenantId, t.habitId, t.day)
22058
+ ]);
22028
22059
 
22029
22060
  // ../../packages/schema/src/contracts/recurrence.ts
22030
22061
  var recurrenceRuleSchema = createSelectSchema(recurrenceRules, {
@@ -22096,6 +22127,71 @@ var updateOccurrenceInputSchema = createUpdateSchema(occurrences, {
22096
22127
  occurrenceDate: exports_coerce.date().optional()
22097
22128
  }).pick({ occurrenceDate: true, status: true }).strict();
22098
22129
 
22130
+ // ../../packages/schema/src/contracts/habit-items.ts
22131
+ var civilDate = exports_iso.date();
22132
+ var habitItemTimeOfDaySchema = _enum2(["morning", "midday", "evening"]);
22133
+ var itemTitleSchema = string2().trim().min(1).max(120);
22134
+ var itemByDaySchema = array(byDayCodeSchema).min(1).max(7).refine((d) => new Set(d).size === d.length, "each weekday once");
22135
+ var habitItemSchema = createSelectSchema(habitItems, {
22136
+ byDay: array(string2()).nullable(),
22137
+ timeOfDay: string2().nullable(),
22138
+ archivedAt: exports_coerce.date().nullable(),
22139
+ createdAt: exports_coerce.date()
22140
+ });
22141
+ var habitItemTickSchema = createSelectSchema(habitItemTicks, {
22142
+ tickedAt: exports_coerce.date()
22143
+ });
22144
+ var createHabitItemInputSchema = object({
22145
+ id: ulidSchema,
22146
+ title: itemTitleSchema,
22147
+ byDay: itemByDaySchema.nullish(),
22148
+ timeOfDay: habitItemTimeOfDaySchema.nullish(),
22149
+ position: number2().int().min(0).optional()
22150
+ }).strict();
22151
+ var updateHabitItemInputSchema = object({
22152
+ title: itemTitleSchema.optional(),
22153
+ byDay: itemByDaySchema.nullish(),
22154
+ timeOfDay: habitItemTimeOfDaySchema.nullish()
22155
+ }).strict();
22156
+ var reorderHabitItemsInputSchema = object({
22157
+ ids: array(ulidSchema).min(1).max(100).refine((ids) => new Set(ids).size === ids.length, "each item once")
22158
+ }).strict();
22159
+ var habitItemTickInputSchema = object({ date: civilDate.optional() }).strict();
22160
+ var habitTickAllInputSchema = object({
22161
+ date: civilDate.optional(),
22162
+ except: array(ulidSchema).max(100).optional()
22163
+ }).strict();
22164
+ var habitChecklistQuerySchema = object({ date: civilDate.optional() });
22165
+ var habitItemTickedBySchema = object({
22166
+ source: _enum2(habitEntrySource.enumValues),
22167
+ userId: string2().nullable(),
22168
+ agentId: string2().nullable()
22169
+ });
22170
+ var habitChecklistItemSchema = object({
22171
+ id: ulidSchema,
22172
+ title: string2(),
22173
+ position: number2().int(),
22174
+ byDay: array(string2()).nullable(),
22175
+ timeOfDay: habitItemTimeOfDaySchema.nullable(),
22176
+ due: boolean2(),
22177
+ ticked: boolean2(),
22178
+ tickedAt: exports_coerce.date().nullable(),
22179
+ tickedBy: habitItemTickedBySchema.nullable()
22180
+ });
22181
+ var habitChecklistDaySchema = object({
22182
+ habitId: ulidSchema,
22183
+ date: civilDate,
22184
+ items: array(habitChecklistItemSchema),
22185
+ due: number2().int().min(0),
22186
+ ticked: number2().int().min(0),
22187
+ percent: number2().int().min(0).max(100),
22188
+ done: boolean2()
22189
+ });
22190
+ var habitItemListSchema = array(habitItemSchema);
22191
+
22192
+ // ../../packages/schema/src/contracts/habit-sources.ts
22193
+ var habitSourceSchema = _enum2(["manual", "google_fit", "strava", "github"]);
22194
+
22099
22195
  // ../../packages/schema/src/contracts/habits.ts
22100
22196
  var habitSchema = createSelectSchema(habits, {
22101
22197
  source: habitSourceSchema.default("manual"),
@@ -22111,7 +22207,8 @@ var habitSchema = createSelectSchema(habits, {
22111
22207
  eventMatch: string2().nullable().default(null),
22112
22208
  eventOffset: string2().nullable().default(null),
22113
22209
  durationMinutes: number2().int().nullable().default(null),
22114
- activeMonths: array(number2().int()).nullable().default(null)
22210
+ activeMonths: array(number2().int()).nullable().default(null),
22211
+ checklist: boolean2().default(false)
22115
22212
  });
22116
22213
  var habitEntrySchema = createSelectSchema(habitEntries, {
22117
22214
  occurredAt: exports_coerce.date(),
@@ -22179,11 +22276,13 @@ var createHabitInputSchema = createInsertSchema(habits, {
22179
22276
  dayTimes: weekdayTimesSchema.nullish(),
22180
22277
  remind: boolean2().optional(),
22181
22278
  durationMinutes: habitDurationMinutesSchema.nullish(),
22182
- activeMonths: habitActiveMonthsSchema.optional()
22279
+ activeMonths: habitActiveMonthsSchema.optional(),
22280
+ checklist: boolean2().optional()
22183
22281
  }).omit({ tenantId: true, recurrenceRuleId: true, retiredAt: true, ...eventColumns }).extend({
22184
22282
  title: string2().min(1),
22185
22283
  schedule: habitScheduleSchema.optional(),
22186
- displayKind: string2().min(1).nullish()
22284
+ displayKind: string2().min(1).nullish(),
22285
+ items: array(createHabitItemInputSchema).max(100).optional()
22187
22286
  });
22188
22287
  var updateHabitInputSchema = createUpdateSchema(habits, {
22189
22288
  source: habitSourceSchema.optional(),
@@ -22207,6 +22306,7 @@ var updateHabitInputSchema = createUpdateSchema(habits, {
22207
22306
  pausedFrom: true,
22208
22307
  pausedUntil: true,
22209
22308
  retiredAt: true,
22309
+ checklist: true,
22210
22310
  ...eventColumns
22211
22311
  }).extend({
22212
22312
  title: string2().min(1).optional(),
@@ -25090,7 +25190,10 @@ var blockTemplateInstanceSchema = object({
25090
25190
  routineId: string2().nullable()
25091
25191
  });
25092
25192
  var PLAN_VS_RECORD_RANGES = [7, 30, 90];
25193
+ var PLAN_VS_RECORD_MONTH_RANGES = ["month", "six", "year", "all"];
25194
+ var planVsRecordMonthRangeSchema = _enum2(PLAN_VS_RECORD_MONTH_RANGES);
25093
25195
  var planVsRecordQuerySchema = object({
25196
+ range: planVsRecordMonthRangeSchema.optional(),
25094
25197
  days: exports_coerce.number().refine((d) => PLAN_VS_RECORD_RANGES.includes(d), {
25095
25198
  message: "days must be 7, 30 or 90"
25096
25199
  }).default(30)
@@ -25144,6 +25247,7 @@ var planVsRecordSuggestionSchema = object({
25144
25247
  });
25145
25248
  var planVsRecordSchema = object({
25146
25249
  days: number2().int(),
25250
+ range: planVsRecordMonthRangeSchema.nullable().default(null),
25147
25251
  since: string2().nullable(),
25148
25252
  recordedDays: number2().int(),
25149
25253
  week: array(planVsRecordDaySchema),
@@ -29670,12 +29774,12 @@ var foodDaySchema = object({
29670
29774
  meals: number2().int(),
29671
29775
  completeness: _enum2(FOOD_DAY_COMPLETENESS_VALUES)
29672
29776
  });
29673
- var civilDate = string2().regex(/^\d{4}-\d{2}-\d{2}$/, "a date is YYYY-MM-DD");
29674
- var foodDateSchema = civilDate;
29777
+ var civilDate2 = string2().regex(/^\d{4}-\d{2}-\d{2}$/, "a date is YYYY-MM-DD");
29778
+ var foodDateSchema = civilDate2;
29675
29779
  var mealLogListQuerySchema = object({ from: exports_coerce.date(), to: exports_coerce.date() }).refine((q) => q.from < q.to, { message: "from must be before to" }).refine((q) => q.to.getTime() - q.from.getTime() <= 92 * 24 * 60 * 60 * 1000, {
29676
29780
  message: "ask for at most 92 days"
29677
29781
  });
29678
- var foodDaysQuerySchema = object({ from: civilDate, to: civilDate }).refine((q) => q.from <= q.to, { message: "from must not be after to" });
29782
+ var foodDaysQuerySchema = object({ from: civilDate2, to: civilDate2 }).refine((q) => q.from <= q.to, { message: "from must not be after to" });
29679
29783
  var FOOD_AFTER_MARK_VALUES = ["tired", "symptom"];
29680
29784
  var plannedMealSchema = object({
29681
29785
  id: string2(),
@@ -29707,7 +29811,7 @@ var foodDayIntakeSchema = object({
29707
29811
  note: string2().nullable()
29708
29812
  });
29709
29813
  var foodDayViewSchema = object({
29710
- date: civilDate,
29814
+ date: civilDate2,
29711
29815
  logs: array(mealLogViewSchema),
29712
29816
  total: foodDaySchema.nullable(),
29713
29817
  planned: array(plannedMealSchema),
@@ -29719,7 +29823,7 @@ var MEAL_AFTER_KIND_VALUES = ["symptom", "episode", "dose", "sleep", "rating"];
29719
29823
  var mealAfterEntrySchema = object({
29720
29824
  kind: _enum2(MEAL_AFTER_KIND_VALUES),
29721
29825
  at: exports_coerce.date().nullable(),
29722
- day: civilDate.nullable(),
29826
+ day: civilDate2.nullable(),
29723
29827
  label: string2(),
29724
29828
  bodyRegion: bodyRegionSchema.nullable(),
29725
29829
  severity: number2().int().nullable(),
@@ -29751,7 +29855,7 @@ var mealContextSchema = object({
29751
29855
  triggerText: string2().nullable()
29752
29856
  }).nullable()
29753
29857
  });
29754
- var foodWeekQuerySchema = object({ start: civilDate.optional() });
29858
+ var foodWeekQuerySchema = object({ start: civilDate2.optional() });
29755
29859
  var foodWeekMealSchema = object({
29756
29860
  id: string2(),
29757
29861
  title: string2(),
@@ -29762,7 +29866,7 @@ var foodWeekMealSchema = object({
29762
29866
  marks: array(_enum2(FOOD_AFTER_MARK_VALUES))
29763
29867
  });
29764
29868
  var foodWeekDaySchema = object({
29765
- day: civilDate,
29869
+ day: civilDate2,
29766
29870
  total: foodDaySchema.nullable(),
29767
29871
  meals: array(foodWeekMealSchema),
29768
29872
  planned: object({ meals: number2().int(), kcal: number2().nullable() }),
@@ -29771,10 +29875,10 @@ var foodWeekDaySchema = object({
29771
29875
  });
29772
29876
  var FOOD_WEEK_READ_MAX = 2000;
29773
29877
  var writeFoodWeekReadInputSchema = object({
29774
- start: civilDate,
29878
+ start: civilDate2,
29775
29879
  body: string2().trim().min(1).max(FOOD_WEEK_READ_MAX)
29776
29880
  }).strict();
29777
- var foodWeekReadQuerySchema = object({ start: civilDate });
29881
+ var foodWeekReadQuerySchema = object({ start: civilDate2 });
29778
29882
  var foodWeekReadSchema = object({
29779
29883
  id: string2(),
29780
29884
  body: string2(),
@@ -29782,14 +29886,14 @@ var foodWeekReadSchema = object({
29782
29886
  updatedAt: exports_coerce.date()
29783
29887
  });
29784
29888
  var foodWeekSchema = object({
29785
- start: civilDate,
29786
- end: civilDate,
29889
+ start: civilDate2,
29890
+ end: civilDate2,
29787
29891
  week: number2().int(),
29788
29892
  days: array(foodWeekDaySchema),
29789
29893
  usualKcal: number2().nullable(),
29790
29894
  weight: object({
29791
- points: array(object({ day: civilDate, value: number2() })),
29792
- trend: array(object({ day: civilDate, value: number2() })),
29895
+ points: array(object({ day: civilDate2, value: number2() })),
29896
+ trend: array(object({ day: civilDate2, value: number2() })),
29793
29897
  latest: number2().nullable(),
29794
29898
  perWeek: number2().nullable(),
29795
29899
  source: metricSourceSchema.nullable()
@@ -29800,7 +29904,7 @@ var foodWeekSchema = object({
29800
29904
  averageProteinG: number2().nullable(),
29801
29905
  dinnersPlanned: number2().int(),
29802
29906
  dinnersAsPlanned: number2().int(),
29803
- dinnersNearBed: array(civilDate),
29907
+ dinnersNearBed: array(civilDate2),
29804
29908
  meals: number2().int(),
29805
29909
  tiredAfter: number2().int(),
29806
29910
  tiredAfterLunch: number2().int()
@@ -29857,13 +29961,13 @@ var foodPatternSideSchema = object({
29857
29961
  mean: number2().nullable()
29858
29962
  });
29859
29963
  var foodPatternWeekSchema = object({
29860
- start: civilDate,
29964
+ start: civilDate2,
29861
29965
  week: number2().int(),
29862
29966
  averageKcal: number2().nullable(),
29863
29967
  weightChange: number2().nullable()
29864
29968
  });
29865
29969
  var foodPatternDaySchema = object({
29866
- day: civilDate,
29970
+ day: civilDate2,
29867
29971
  with: boolean2(),
29868
29972
  hit: boolean2().nullable(),
29869
29973
  value: number2().nullable()
@@ -29891,7 +29995,7 @@ var proposeFoodTrialInputSchema = object({
29891
29995
  question: foodPatternQuestionSchema,
29892
29996
  title: string2().trim().min(1).max(120),
29893
29997
  note: string2().trim().min(1).max(FOOD_TRIAL_NOTE_MAX),
29894
- startsOn: civilDate,
29998
+ startsOn: civilDate2,
29895
29999
  days: number2().int().min(7).max(28).default(14)
29896
30000
  }).strict();
29897
30001
  var foodTrialSchema = object({
@@ -29900,15 +30004,15 @@ var foodTrialSchema = object({
29900
30004
  title: string2(),
29901
30005
  note: string2(),
29902
30006
  state: _enum2(["proposed", "running"]),
29903
- startsOn: civilDate,
29904
- endsOn: civilDate,
30007
+ startsOn: civilDate2,
30008
+ endsOn: civilDate2,
29905
30009
  days: number2().int(),
29906
30010
  day: number2().int().nullable(),
29907
30011
  author: _enum2(["me", "agent"])
29908
30012
  });
29909
30013
  var foodPatternsSchema = object({
29910
- from: civilDate,
29911
- to: civilDate,
30014
+ from: civilDate2,
30015
+ to: civilDate2,
29912
30016
  windowDays: number2().int().positive(),
29913
30017
  loggedDays: number2().int().nonnegative(),
29914
30018
  answers: array(foodPatternAnswerSchema),
@@ -31092,6 +31196,8 @@ var guestOperations = defineOperations({
31092
31196
  });
31093
31197
 
31094
31198
  // ../../packages/schema/src/operations/habits.ts
31199
+ var item = { itemId: "The item's ULID." };
31200
+ var notChecklist = "A habit that isn't a checklist answers 409.";
31095
31201
  var habitListQuery = habitListQuerySchema.extend(paginationQuerySchema.shape);
31096
31202
  var habitOperations = defineOperations({
31097
31203
  list: {
@@ -31405,6 +31511,133 @@ var habitOperations = defineOperations({
31405
31511
  errors: { 404: true },
31406
31512
  webhook: "habit.updated",
31407
31513
  operationId: "undo_habit_check_in"
31514
+ },
31515
+ listItems: {
31516
+ method: "get",
31517
+ path: "/habits/{id}/items",
31518
+ scopes: ["habits:read"],
31519
+ tag: "Habits",
31520
+ summary: "List a checklist habit's items",
31521
+ description: `A checklist habit is one habit made of small items; ticking them fills its day (6 of 9 is 67%). Its live items, in order, each with its weekdays (\`byDay\`, null = every day) and part of the day. ${notChecklist}`,
31522
+ status: 200,
31523
+ response: { description: "The items, in order." },
31524
+ errors: { 404: true, 409: true },
31525
+ operationId: "list_habit_items"
31526
+ },
31527
+ addItem: {
31528
+ method: "post",
31529
+ path: "/habits/{id}/items",
31530
+ scopes: ["habits:write"],
31531
+ tag: "Habits",
31532
+ summary: "Add an item to a checklist habit",
31533
+ description: `Body \`{ id, title, byDay?, timeOfDay?, position? }\`: the item goes last, or at \`position\`. Returns the items. ${notChecklist}`,
31534
+ body: createHabitItemInputSchema,
31535
+ status: 201,
31536
+ response: { description: "The items, in order." },
31537
+ errors: { 400: true, 404: true, 409: true },
31538
+ webhook: "habit.updated",
31539
+ operationId: "add_habit_item"
31540
+ },
31541
+ updateItem: {
31542
+ method: "patch",
31543
+ path: "/habits/{id}/items/{itemId}",
31544
+ pathParams: item,
31545
+ scopes: ["habits:write"],
31546
+ tag: "Habits",
31547
+ summary: "Rename an item or change when it's due",
31548
+ description: `Body \`{ title?, byDay?, timeOfDay? }\`; null clears its weekdays or part of the day. Returns the items. ${notChecklist}`,
31549
+ body: updateHabitItemInputSchema,
31550
+ status: 200,
31551
+ response: { description: "The items, in order." },
31552
+ errors: { 400: true, 404: true, 409: true },
31553
+ webhook: "habit.updated",
31554
+ operationId: "update_habit_item"
31555
+ },
31556
+ reorderItems: {
31557
+ method: "put",
31558
+ path: "/habits/{id}/items/order",
31559
+ scopes: ["habits:write"],
31560
+ tag: "Habits",
31561
+ summary: "Reorder a checklist habit's items",
31562
+ description: `Body \`{ ids }\`: every live item's id, once each, first to last (400 otherwise). Returns the items. ${notChecklist}`,
31563
+ body: reorderHabitItemsInputSchema,
31564
+ status: 200,
31565
+ response: { description: "The items, in order." },
31566
+ errors: { 400: true, 404: true, 409: true },
31567
+ webhook: "habit.updated",
31568
+ operationId: "reorder_habit_items"
31569
+ },
31570
+ archiveItem: {
31571
+ method: "delete",
31572
+ path: "/habits/{id}/items/{itemId}",
31573
+ pathParams: item,
31574
+ scopes: ["habits:write"],
31575
+ tag: "Habits",
31576
+ summary: "Remove an item from a checklist habit",
31577
+ description: `The item is archived, never deleted: the days it was ticked keep their count, and from today it's no longer due. Returns the items left. ${notChecklist}`,
31578
+ status: 200,
31579
+ response: { description: "The items left, in order." },
31580
+ errors: { 404: true, 409: true },
31581
+ webhook: "habit.updated",
31582
+ operationId: "remove_habit_item"
31583
+ },
31584
+ checklist: {
31585
+ method: "get",
31586
+ path: "/habits/{id}/checklist",
31587
+ scopes: ["habits:read"],
31588
+ tag: "Habits",
31589
+ summary: "A checklist habit's day",
31590
+ description: `The day's items (each due or not, ticked or not, when and by whom), how many are due and ticked, the percent (6 of 9 \u2192 67) and \`done\`. \`date\` (YYYY-MM-DD) defaults to today in the member's zone. The habit's own day value is this percent (target 100), so its streak counts a day at 100%. ${notChecklist}`,
31591
+ query: [{ name: "date", description: "The day (YYYY-MM-DD); today when absent." }],
31592
+ querySchema: habitChecklistQuerySchema,
31593
+ status: 200,
31594
+ response: { description: "The checklist on the day." },
31595
+ errors: { 400: true, 404: true, 409: true },
31596
+ operationId: "get_habit_checklist"
31597
+ },
31598
+ tickItem: {
31599
+ method: "post",
31600
+ path: "/habits/{id}/items/{itemId}/tick",
31601
+ pathParams: item,
31602
+ scopes: ["habits:write"],
31603
+ tag: "Habits",
31604
+ summary: "Tick an item",
31605
+ description: `Body \`{ date? }\` (today when absent). Ticking a ticked item changes nothing. An Agent's key ticks it as that Agent's. Returns the day; fires \`habit.updated\`. ${notChecklist}`,
31606
+ body: habitItemTickInputSchema,
31607
+ status: 200,
31608
+ response: { description: "The checklist on the day." },
31609
+ errors: { 400: true, 404: true, 409: true },
31610
+ webhook: "habit.updated",
31611
+ operationId: "tick_habit_item"
31612
+ },
31613
+ untickItem: {
31614
+ method: "post",
31615
+ path: "/habits/{id}/items/{itemId}/untick",
31616
+ pathParams: item,
31617
+ scopes: ["habits:write"],
31618
+ tag: "Habits",
31619
+ summary: "Untick an item",
31620
+ description: `Body \`{ date? }\` (today when absent): undo a tick. Returns the day; fires \`habit.updated\`. ${notChecklist}`,
31621
+ body: habitItemTickInputSchema,
31622
+ status: 200,
31623
+ response: { description: "The checklist on the day." },
31624
+ errors: { 400: true, 404: true, 409: true },
31625
+ webhook: "habit.updated",
31626
+ operationId: "untick_habit_item"
31627
+ },
31628
+ tickAll: {
31629
+ method: "post",
31630
+ path: "/habits/{id}/items/tick-all",
31631
+ scopes: ["habits:write"],
31632
+ tag: "Habits",
31633
+ summary: "Tick every item due",
31634
+ description: `"All": body \`{ date?, except? }\` ticks every item due on the day (today when absent) but the ones in \`except\`, which end up unticked: "all done except the water". Returns the day; fires \`habit.updated\`. ${notChecklist}`,
31635
+ body: habitTickAllInputSchema,
31636
+ status: 200,
31637
+ response: { description: "The checklist on the day." },
31638
+ errors: { 400: true, 404: true, 409: true },
31639
+ webhook: "habit.updated",
31640
+ operationId: "tick_all_habit_items"
31408
31641
  }
31409
31642
  });
31410
31643
 
@@ -35257,14 +35490,16 @@ var mailCampaignOperations = defineOperations({
35257
35490
 
35258
35491
  // ../../packages/schema/src/contracts/meal-plans.ts
35259
35492
  var mealPlanStateSchema = _enum2(MEAL_PLAN_STATES);
35260
- var civilDate2 = string2().regex(/^\d{4}-\d{2}-\d{2}$/, "a date is YYYY-MM-DD");
35493
+ var civilDate3 = string2().regex(/^\d{4}-\d{2}-\d{2}$/, "a date is YYYY-MM-DD");
35261
35494
  var weekMenuFields = {
35262
35495
  state: mealPlanStateSchema.optional(),
35263
35496
  cookUserId: ulidSchema.nullish(),
35264
35497
  company: string2().max(120).nullish(),
35265
35498
  leftoverPortions: number2().int().positive().nullish(),
35266
- leftoverEatBy: civilDate2.nullish(),
35267
- leftoverFrozen: boolean2().optional()
35499
+ leftoverEatBy: civilDate3.nullish(),
35500
+ leftoverFrozen: boolean2().optional(),
35501
+ eaterUserIds: array(ulidSchema).max(50).optional(),
35502
+ guests: number2().int().min(0).max(99).optional()
35268
35503
  };
35269
35504
  var mealPlanSchema = createSelectSchema(mealPlans, {
35270
35505
  plannedFor: exports_coerce.date(),
@@ -35273,7 +35508,9 @@ var mealPlanSchema = createSelectSchema(mealPlans, {
35273
35508
  company: string2().nullable().default(null),
35274
35509
  leftoverPortions: number2().int().nullable().default(null),
35275
35510
  leftoverEatBy: string2().nullable().default(null),
35276
- leftoverFrozen: boolean2().default(false)
35511
+ leftoverFrozen: boolean2().default(false),
35512
+ eaterUserIds: array(string2()).default([]),
35513
+ guests: number2().int().default(0)
35277
35514
  });
35278
35515
  var createMealPlanInputSchema = createInsertSchema(mealPlans, {
35279
35516
  id: ulidSchema,
@@ -35323,10 +35560,10 @@ var mealPlanCookResultSchema = object({
35323
35560
  });
35324
35561
  var cookMealPlanInputSchema = object({
35325
35562
  leftoverPortions: number2().int().positive().nullish(),
35326
- leftoverEatBy: civilDate2.nullish()
35563
+ leftoverEatBy: civilDate3.nullish()
35327
35564
  }).strict();
35328
- var mealWeekQuerySchema = object({ start: civilDate2.optional() });
35329
- var acceptMealDraftInputSchema = object({ start: civilDate2 }).strict();
35565
+ var mealWeekQuerySchema = object({ start: civilDate3.optional() });
35566
+ var acceptMealDraftInputSchema = object({ start: civilDate3 }).strict();
35330
35567
  var mealWeekCookSchema = object({
35331
35568
  userId: string2(),
35332
35569
  name: string2(),
@@ -35340,10 +35577,12 @@ var mealWeekSlotSchema = object({
35340
35577
  cook: mealWeekCookSchema.nullable(),
35341
35578
  company: string2().nullable(),
35342
35579
  notes: string2().nullable(),
35580
+ eaters: array(mealWeekCookSchema).default([]),
35581
+ guests: number2().int().min(0).default(0),
35343
35582
  time: string2().nullable()
35344
35583
  });
35345
35584
  var mealWeekDaySchema = object({
35346
- date: civilDate2,
35585
+ date: civilDate3,
35347
35586
  isToday: boolean2(),
35348
35587
  dinner: mealWeekSlotSchema.nullable(),
35349
35588
  lunch: mealWeekSlotSchema.nullable()
@@ -35352,19 +35591,19 @@ var mealWeekLeftoverSchema = object({
35352
35591
  mealPlanId: ulidSchema,
35353
35592
  title: string2(),
35354
35593
  portions: number2().int(),
35355
- cookedOn: civilDate2,
35356
- eatBy: civilDate2.nullable(),
35594
+ cookedOn: civilDate3,
35595
+ eatBy: civilDate3.nullable(),
35357
35596
  frozen: boolean2()
35358
35597
  });
35359
35598
  var mealWeekDraftDaySchema = object({
35360
- date: civilDate2,
35599
+ date: civilDate3,
35361
35600
  dinner: mealWeekSlotSchema.nullable(),
35362
35601
  why: string2().nullable()
35363
35602
  });
35364
35603
  var mealWeekSchema = object({
35365
35604
  week: number2().int().min(1).max(53),
35366
- start: civilDate2,
35367
- end: civilDate2,
35605
+ start: civilDate3,
35606
+ end: civilDate3,
35368
35607
  days: array(mealWeekDaySchema).length(7),
35369
35608
  summary: object({
35370
35609
  planned: number2().int().min(0),
@@ -35573,8 +35812,60 @@ var moneyOdooUndoResultSchema = object({
35573
35812
  line: string2()
35574
35813
  });
35575
35814
 
35576
- // ../../packages/schema/src/contracts/money-net-worth.ts
35815
+ // ../../packages/schema/src/contracts/money-flow.ts
35577
35816
  var amount5 = string2();
35817
+ var MONEY_FLOW_START = "start";
35818
+ var moneyFlowQuerySchema = object({
35819
+ from: union([moneyMonthSchema, literal(MONEY_FLOW_START)]).optional(),
35820
+ to: moneyMonthSchema.optional(),
35821
+ scope: moneyBudgetScopeSchema.optional()
35822
+ }).refine((q) => !q.from || q.from === MONEY_FLOW_START || !q.to || q.from <= q.to, {
35823
+ message: "from must not be after to",
35824
+ path: ["from"]
35825
+ });
35826
+ var moneyFlowSourceSchema = object({
35827
+ kind: _enum2(["income", "moved_in"]),
35828
+ categoryId: ulidSchema.nullable(),
35829
+ name: string2(),
35830
+ amount: amount5
35831
+ });
35832
+ var MONEY_FLOW_OUTS = [
35833
+ "fixed",
35834
+ "flexible",
35835
+ "moved_out",
35836
+ "goals",
35837
+ "invested",
35838
+ "kept"
35839
+ ];
35840
+ var moneyFlowOutKindSchema = _enum2(MONEY_FLOW_OUTS);
35841
+ var moneyFlowOutSchema = object({
35842
+ kind: moneyFlowOutKindSchema,
35843
+ name: string2(),
35844
+ amount: amount5
35845
+ });
35846
+ var moneyFlowCategorySchema = object({
35847
+ categoryId: ulidSchema.nullable(),
35848
+ name: string2(),
35849
+ amount: amount5
35850
+ });
35851
+ var moneyFlowSchema = object({
35852
+ scope: moneyBudgetScopeSchema,
35853
+ from: moneyMonthSchema,
35854
+ to: moneyMonthSchema,
35855
+ through: moneyMonthSchema,
35856
+ firstMonth: moneyMonthSchema.nullable(),
35857
+ in: amount5,
35858
+ sources: array(moneyFlowSourceSchema),
35859
+ fromSavings: amount5,
35860
+ outs: array(moneyFlowOutSchema),
35861
+ fixed: array(moneyFlowCategorySchema),
35862
+ flexible: array(moneyFlowCategorySchema),
35863
+ unsorted: amount5,
35864
+ saved: amount5
35865
+ });
35866
+
35867
+ // ../../packages/schema/src/contracts/money-net-worth.ts
35868
+ var amount6 = string2();
35578
35869
  var moneySnapshotSourceSchema = _enum2(moneySnapshotSource.enumValues);
35579
35870
  var moneyNetWorthQuerySchema = object({
35580
35871
  scope: moneyBudgetScopeSchema.optional(),
@@ -35582,9 +35873,9 @@ var moneyNetWorthQuerySchema = object({
35582
35873
  });
35583
35874
  var moneyNetWorthPointSchema = object({
35584
35875
  month: moneyMonthSchema,
35585
- total: amount5.nullable(),
35586
- have: amount5.nullable(),
35587
- owe: amount5.nullable()
35876
+ total: amount6.nullable(),
35877
+ have: amount6.nullable(),
35878
+ owe: amount6.nullable()
35588
35879
  });
35589
35880
  var moneyNetWorthAccountSchema = object({
35590
35881
  accountId: ulidSchema,
@@ -35592,7 +35883,7 @@ var moneyNetWorthAccountSchema = object({
35592
35883
  kind: moneyAccountKindSchema,
35593
35884
  visibility: _enum2(NODE_VISIBILITY_VALUES),
35594
35885
  currency: string2(),
35595
- value: amount5,
35886
+ value: amount6,
35596
35887
  source: moneySnapshotSourceSchema,
35597
35888
  month: moneyMonthSchema,
35598
35889
  pensionSubtype: moneyPensionSubtypeSchema.nullable(),
@@ -35609,11 +35900,11 @@ var moneyNetWorthUnknownSchema = moneyNetWorthAccountSchema.pick({
35609
35900
  var moneyNetWorthSchema = object({
35610
35901
  scope: moneyBudgetScopeSchema,
35611
35902
  month: moneyMonthSchema,
35612
- total: amount5,
35613
- have: amount5,
35614
- owe: amount5,
35615
- liquid: amount5,
35616
- locked: amount5,
35903
+ total: amount6,
35904
+ have: amount6,
35905
+ owe: amount6,
35906
+ liquid: amount6,
35907
+ locked: amount6,
35617
35908
  points: array(moneyNetWorthPointSchema),
35618
35909
  accounts: array(moneyNetWorthAccountSchema),
35619
35910
  complete: boolean2(),
@@ -35628,7 +35919,7 @@ var moneySnapshotSchema = object({
35628
35919
  id: ulidSchema,
35629
35920
  accountId: ulidSchema,
35630
35921
  month: moneyMonthSchema,
35631
- value: amount5,
35922
+ value: amount6,
35632
35923
  source: moneySnapshotSourceSchema
35633
35924
  });
35634
35925
 
@@ -35718,22 +36009,22 @@ var moneySettlementViewSchema = object({
35718
36009
  });
35719
36010
 
35720
36011
  // ../../packages/schema/src/contracts/money-year.ts
35721
- var amount6 = string2();
36012
+ var amount7 = string2();
35722
36013
  var moneyYearQuerySchema = object({
35723
36014
  year: exports_coerce.number().int().min(2000).max(2100).optional(),
35724
36015
  scope: moneyBudgetScopeSchema.optional()
35725
36016
  });
35726
36017
  var moneyYearMonthSchema = object({
35727
36018
  month: moneyMonthSchema,
35728
- income: amount6,
35729
- spent: amount6
36019
+ income: amount7,
36020
+ spent: amount7
35730
36021
  });
35731
36022
  var moneyYearCategorySchema = object({
35732
36023
  categoryId: ulidSchema.nullable(),
35733
36024
  name: string2(),
35734
36025
  group: _enum2(["fixed", "flexible", "income"]).nullable(),
35735
- amount: amount6,
35736
- lastYear: amount6
36026
+ amount: amount7,
36027
+ lastYear: amount7
35737
36028
  });
35738
36029
  var MONEY_YEAR_STREAM_CHANGES = ["new", "stopped", "up", "down", "same"];
35739
36030
  var moneyYearStreamChangeSchema = _enum2(MONEY_YEAR_STREAM_CHANGES);
@@ -35742,8 +36033,8 @@ var moneyYearStreamSchema = object({
35742
36033
  title: string2(),
35743
36034
  cadence: moneyCadenceSchema,
35744
36035
  visibility: _enum2(NODE_VISIBILITY_VALUES),
35745
- thisYear: amount6,
35746
- lastYear: amount6,
36036
+ thisYear: amount7,
36037
+ lastYear: amount7,
35747
36038
  change: moneyYearStreamChangeSchema
35748
36039
  });
35749
36040
  var moneyYearGoalSchema = object({
@@ -35752,14 +36043,14 @@ var moneyYearGoalSchema = object({
35752
36043
  visibility: _enum2(NODE_VISIBILITY_VALUES),
35753
36044
  status: moneyGoalStatusSchema,
35754
36045
  projectTitle: string2().nullable(),
35755
- thisYear: amount6,
35756
- saved: amount6,
35757
- target: amount6
36046
+ thisYear: amount7,
36047
+ saved: amount7,
36048
+ target: amount7
35758
36049
  });
35759
36050
  var moneyYearTotalsSchema = object({
35760
- income: amount6,
35761
- spent: amount6,
35762
- saved: amount6
36051
+ income: amount7,
36052
+ spent: amount7,
36053
+ saved: amount7
35763
36054
  });
35764
36055
  var moneyYearSchema = object({
35765
36056
  year: number2().int(),
@@ -36413,6 +36704,23 @@ var moneyOperations = defineOperations({
36413
36704
  response: { description: "The year." },
36414
36705
  errors: { 400: true }
36415
36706
  },
36707
+ flow: {
36708
+ method: "get",
36709
+ path: "/money/flow",
36710
+ scopes: ["finance:read"],
36711
+ tag: "Money",
36712
+ summary: "Get where the money went",
36713
+ description: "What came in over a span of months and where it went, as the flow chart draws it: `sources` (each income category, null `categoryId` for income not sorted yet, and with a `scope` narrower than `all` `moved_in`, money moved in from the other budget accounts; biggest first) adding up to `in`; `outs` in the chart's order, only what's above zero: `fixed` and `flexible` spending (refunds netted, plain transfers left out; what isn't sorted yet sits under flexible), `moved_out` (to the other budget accounts, with a narrower scope), `goals` (a deposit linked to a goal, or spending toward it from the budget), `invested` (transfers into an investment or a pension account) and `kept` (what's left); `fromSavings` when more went out than came in. `fixed` and `flexible` by category, biggest first, with `unsorted`, and `saved` (goals, invested and kept). Read over the accounts counted in the budget; another member's Only me account or goal never adds to it. `from` and `to` are months (`YYYY-MM`; `to` this month and `from` `to` by default, `from=start` the ledger's first month, `firstMonth`); a span under way counts to this month (`through`). `scope`: `all` (default), `space` or `owner`.",
36714
+ query: [
36715
+ { name: "from", description: "The first month, YYYY-MM, or start (default: to)." },
36716
+ { name: "to", description: "The last month, YYYY-MM (default this one)." },
36717
+ { name: "scope", description: "all, space or owner." }
36718
+ ],
36719
+ querySchema: moneyFlowQuerySchema,
36720
+ status: 200,
36721
+ response: { description: "The flow." },
36722
+ errors: { 400: true }
36723
+ },
36416
36724
  netWorthRead: {
36417
36725
  method: "get",
36418
36726
  path: "/money/net-worth",
@@ -41452,9 +41760,14 @@ var timeBlockOperations = defineOperations({
41452
41760
  scopes: ["calendar:read"],
41453
41761
  tag: "Calendar",
41454
41762
  summary: "Plan vs what happened",
41455
- description: 'How the key\'s member\'s life blocks went against their plan over the last `days` (7, 30 or 90; default 30): `week`, last week (Monday to Sunday) as strips (each block\'s planned and recorded minutes into the day, and the day in words, "Held mostly", "Evening went elsewhere"); `hours`, where that week\'s time went per group of kinds, recorded against planned; `moves`, which blocks move over the range\'s weekdays and how, in words ("Lunch \xB7 60\u201375 min \xB7 Runs about twice the 30 planned \xB7 17 of 22"), counting a record once it\'s confirmed or 48 h old, each with `latestId` (its latest block); `evening`, the weekday evenings\' tasks (Tasks planned from 17:00) held, in words with the days work ran past 17:30, and a confidence word, or null; and `suggestion`, one template length to change ("plan it like it is", apply with `PATCH /api/v1/block-templates/{id}` `{ minutes }`) or null. Moving is information, not a miss: no score, no streak.',
41763
+ description: "How the key's member's life blocks went against their plan over the last `days` (7, 30 or 90; default 30), or a month `range` in its place (Review's Range menu: `month`, this month so far; `six`, from the first of the month five back; `year`, this year so far; `all`, since the first recorded block; the response says its `days` and `range`): `week`, last week (Monday to Sunday) as strips (each block's planned and recorded minutes into the day, and the day in words, \"Held mostly\", \"Evening went elsewhere\"); `hours`, where that week's time went per group of kinds, recorded against planned; `moves`, which blocks move over the range's weekdays and how, in words (\"Lunch \xB7 60\u201375 min \xB7 Runs about twice the 30 planned \xB7 17 of 22\"), counting a record once it's confirmed or 48 h old, each with `latestId` (its latest block); `evening`, the weekday evenings' tasks (Tasks planned from 17:00) held, in words with the days work ran past 17:30, and a confidence word, or null; and `suggestion`, one template length to change (\"plan it like it is\", apply with `PATCH /api/v1/block-templates/{id}` `{ minutes }`) or null. Moving is information, not a miss: no score, no streak.",
41456
41764
  query: [
41457
- { name: "days", description: "7, 30 (default) or 90.", type: "integer", enum: [7, 30, 90] }
41765
+ { name: "days", description: "7, 30 (default) or 90.", type: "integer", enum: [7, 30, 90] },
41766
+ {
41767
+ name: "range",
41768
+ description: "month, six, year or all, in place of days.",
41769
+ enum: ["month", "six", "year", "all"]
41770
+ }
41458
41771
  ],
41459
41772
  querySchema: planVsRecordQuerySchema,
41460
41773
  status: 200,
@@ -41501,9 +41814,9 @@ var todayOperations = defineOperations({
41501
41814
  // ../../packages/schema/src/contracts/waste-calendar.ts
41502
41815
  var WASTE_KIND_VALUES = ["rest", "pmd", "paper", "garden", "glass", "other"];
41503
41816
  var wasteKindSchema = _enum2(WASTE_KIND_VALUES);
41504
- var civilDate3 = exports_iso.date();
41817
+ var civilDate4 = exports_iso.date();
41505
41818
  var wasteCollectionSchema = object({
41506
- date: civilDate3,
41819
+ date: civilDate4,
41507
41820
  kinds: array(wasteKindSchema).min(1),
41508
41821
  movedBy: string2().min(1).optional()
41509
41822
  });
@@ -49743,6 +50056,281 @@ var commands20 = [
49743
50056
  }
49744
50057
  ];
49745
50058
 
50059
+ // src/commands/habit-items.ts
50060
+ var DATE_FLAG = {
50061
+ name: "date",
50062
+ type: "string",
50063
+ description: "The day (YYYY-MM-DD); today in your zone when absent."
50064
+ };
50065
+ var WHEN_FLAGS = [
50066
+ {
50067
+ name: "on",
50068
+ type: "string",
50069
+ description: "Its weekdays, e.g. mo,we,fr; every day when absent."
50070
+ },
50071
+ {
50072
+ name: "part",
50073
+ type: "string",
50074
+ description: "Its part of the day: morning, midday or evening."
50075
+ }
50076
+ ];
50077
+ function itemWhenFromFlags(flags) {
50078
+ const out = {};
50079
+ const on = flagString(flags, "on");
50080
+ if (on !== undefined)
50081
+ out.byDay = on.split(",").map((d) => d.trim().toUpperCase().slice(0, 2)).filter(Boolean);
50082
+ if (flagBool(flags, "every-day"))
50083
+ out.byDay = null;
50084
+ const part = flagString(flags, "part");
50085
+ if (part !== undefined)
50086
+ out.timeOfDay = part === "any" ? null : part.trim().toLowerCase();
50087
+ return out;
50088
+ }
50089
+ function renderChecklist(data, mode) {
50090
+ const parsed = habitChecklistDaySchema.safeParse(data);
50091
+ if (!parsed.success)
50092
+ return renderRecord(data, mode);
50093
+ const day = parsed.data;
50094
+ const lines = day.items.map((i) => {
50095
+ const mark = i.ticked ? paint(mode, "green", "\u2713") : i.due ? "\xB7" : " ";
50096
+ const off = i.due ? "" : paint(mode, "dim", " (not due)");
50097
+ return `${mark} ${i.title}${off} ${paint(mode, "dim", i.id)}`;
50098
+ });
50099
+ lines.push(paint(mode, "dim", `${day.date}: ${day.ticked} of ${day.due}, ${day.percent}%${day.done ? ", done" : ""}`));
50100
+ return lines.join(`
50101
+ `);
50102
+ }
50103
+ function renderItems(data, mode) {
50104
+ const parsed = habitItemListSchema.safeParse(data);
50105
+ if (!parsed.success)
50106
+ return renderRecord(data, mode);
50107
+ if (parsed.data.length === 0)
50108
+ return "No items yet.";
50109
+ return parsed.data.map((i, n) => {
50110
+ const when = [i.byDay?.join(","), i.timeOfDay].filter(Boolean).join(" \xB7 ");
50111
+ return `${n + 1}. ${i.title}${when ? paint(mode, "dim", ` (${when})`) : ""} ${paint(mode, "dim", i.id)}`;
50112
+ }).join(`
50113
+ `);
50114
+ }
50115
+ var habitArg = { name: "id", required: true, description: "The checklist habit's ULID." };
50116
+ var itemArg = { name: "item-id", required: true, description: "The item's ULID." };
50117
+ var NOT_CHECKLIST = "A habit that isn't a checklist answers 409.";
50118
+ var commands21 = [
50119
+ {
50120
+ spec: {
50121
+ path: ["habit", "items"],
50122
+ summary: "List a checklist habit's items, in order.",
50123
+ args: [habitArg],
50124
+ flags: [],
50125
+ scopes: [...habitOperations.listItems.scopes],
50126
+ returns: "HabitItem[]",
50127
+ notes: `${routeOf(habitOperations.listItems)}. A checklist habit is one habit of small items; ticking them fills its day (6 of 9 is 67%). Make one with \`do habits create "<title>" --data '{"checklist":true,"items":[{"id":"<ulid>","title":"Item A"}]}'\`. ${NOT_CHECKLIST}`
50128
+ },
50129
+ run: async ({ args, requireClient }) => ({
50130
+ data: await requireClient().get(pathOf(habitOperations.listItems, { id: requireArg(args, 0, "habit id") })),
50131
+ render: renderItems
50132
+ })
50133
+ },
50134
+ {
50135
+ spec: {
50136
+ path: ["habit", "item", "add"],
50137
+ summary: "Add an item to a checklist habit.",
50138
+ args: [habitArg, { name: "title", required: true, description: "The item's title." }],
50139
+ flags: [
50140
+ ...WHEN_FLAGS,
50141
+ { name: "at", type: "string", description: "Its place, 1 first; last when absent." }
50142
+ ],
50143
+ scopes: [...habitOperations.addItem.scopes],
50144
+ returns: "HabitItem[]",
50145
+ notes: `${routeOf(habitOperations.addItem)}. e.g. \`do habit item add <id> "Morning glass of water" --part morning\`. ${NOT_CHECKLIST}`
50146
+ },
50147
+ run: async ({ args, flags, requireClient }) => {
50148
+ const id = requireArg(args, 0, "habit id");
50149
+ const title = args.slice(1).join(" ").trim();
50150
+ if (!title)
50151
+ throw usageError('habit item add needs a title, e.g. `do habit item add <id> "Item A"`');
50152
+ const at = flagString(flags, "at");
50153
+ const input = parseInput(createHabitItemInputSchema, {
50154
+ id: ulid3(),
50155
+ title,
50156
+ ...itemWhenFromFlags(flags),
50157
+ ...at !== undefined ? { position: Math.max(0, Number(at) - 1) } : {}
50158
+ });
50159
+ return {
50160
+ data: await requireClient().post(pathOf(habitOperations.addItem, { id }), input),
50161
+ render: renderItems
50162
+ };
50163
+ }
50164
+ },
50165
+ {
50166
+ spec: {
50167
+ path: ["habit", "item", "edit"],
50168
+ summary: "Rename an item or change when it's due.",
50169
+ args: [habitArg, itemArg],
50170
+ flags: [
50171
+ { name: "title", type: "string", description: "Its new title." },
50172
+ ...WHEN_FLAGS,
50173
+ { name: "every-day", type: "boolean", description: "Due every day again." }
50174
+ ],
50175
+ scopes: [...habitOperations.updateItem.scopes],
50176
+ returns: "HabitItem[]",
50177
+ notes: `${routeOf(habitOperations.updateItem)}. --part any clears its part of the day. ${NOT_CHECKLIST}`
50178
+ },
50179
+ run: async ({ args, flags, requireClient }) => {
50180
+ const id = requireArg(args, 0, "habit id");
50181
+ const itemId = requireArg(args, 1, "item id");
50182
+ const title = flagString(flags, "title");
50183
+ const input = parseInput(updateHabitItemInputSchema, {
50184
+ ...title !== undefined ? { title } : {},
50185
+ ...itemWhenFromFlags(flags)
50186
+ });
50187
+ if (Object.keys(input).length === 0)
50188
+ throw usageError("nothing to change \u2014 pass --title, --on, --every-day or --part");
50189
+ return {
50190
+ data: await requireClient().patch(pathOf(habitOperations.updateItem, { id, itemId }), input),
50191
+ render: renderItems
50192
+ };
50193
+ }
50194
+ },
50195
+ {
50196
+ spec: {
50197
+ path: ["habit", "item", "order"],
50198
+ summary: "Put a checklist habit's items in a new order.",
50199
+ args: [
50200
+ habitArg,
50201
+ { name: "item-ids", required: true, description: "Every item's ULID, first to last." }
50202
+ ],
50203
+ flags: [],
50204
+ scopes: [...habitOperations.reorderItems.scopes],
50205
+ returns: "HabitItem[]",
50206
+ notes: `${routeOf(habitOperations.reorderItems)}. Name every item on the list once (400 otherwise). ${NOT_CHECKLIST}`
50207
+ },
50208
+ run: async ({ args, requireClient }) => {
50209
+ const id = requireArg(args, 0, "habit id");
50210
+ const input = parseInput(reorderHabitItemsInputSchema, { ids: args.slice(1) });
50211
+ return {
50212
+ data: await requireClient().put(pathOf(habitOperations.reorderItems, { id }), input),
50213
+ render: renderItems
50214
+ };
50215
+ }
50216
+ },
50217
+ {
50218
+ spec: {
50219
+ path: ["habit", "item", "rm"],
50220
+ summary: "Remove an item from a checklist habit (archived; its past ticks keep counting).",
50221
+ args: [habitArg, itemArg],
50222
+ flags: [],
50223
+ scopes: [...habitOperations.archiveItem.scopes],
50224
+ returns: "HabitItem[]",
50225
+ notes: `${routeOf(habitOperations.archiveItem)}. ${NOT_CHECKLIST}`
50226
+ },
50227
+ run: async ({ args, requireClient }) => {
50228
+ const id = requireArg(args, 0, "habit id");
50229
+ const itemId = requireArg(args, 1, "item id");
50230
+ return {
50231
+ data: await requireClient().delete(pathOf(habitOperations.archiveItem, { id, itemId })),
50232
+ render: renderItems
50233
+ };
50234
+ }
50235
+ },
50236
+ {
50237
+ spec: {
50238
+ path: ["habit", "checklist"],
50239
+ summary: "A checklist habit's day: each item due and ticked, and the percent.",
50240
+ args: [habitArg],
50241
+ flags: [DATE_FLAG],
50242
+ scopes: [...habitOperations.checklist.scopes],
50243
+ returns: "HabitChecklistDay",
50244
+ notes: `${routeOf(habitOperations.checklist)}. The habit's day value is this percent (target 100). ${NOT_CHECKLIST}`
50245
+ },
50246
+ run: async ({ args, flags, requireClient }) => {
50247
+ const id = requireArg(args, 0, "habit id");
50248
+ const date = flagString(flags, "date");
50249
+ const q = date ? `?${new URLSearchParams({ date })}` : "";
50250
+ return {
50251
+ data: await requireClient().get(`${pathOf(habitOperations.checklist, { id })}${q}`),
50252
+ render: renderChecklist
50253
+ };
50254
+ }
50255
+ },
50256
+ {
50257
+ spec: {
50258
+ path: ["habit", "tick"],
50259
+ summary: "Tick an item of a checklist habit.",
50260
+ args: [habitArg, itemArg],
50261
+ flags: [DATE_FLAG],
50262
+ scopes: [...habitOperations.tickItem.scopes],
50263
+ returns: "HabitChecklistDay",
50264
+ notes: `${routeOf(habitOperations.tickItem)}. A ticked item stays ticked. An Agent's key ticks it as that Agent's. ${NOT_CHECKLIST}`
50265
+ },
50266
+ run: async ({ args, flags, requireClient }) => {
50267
+ const id = requireArg(args, 0, "habit id");
50268
+ const itemId = requireArg(args, 1, "item id");
50269
+ const input = parseInput(habitItemTickInputSchema, dateOf(flags));
50270
+ return {
50271
+ data: await requireClient().post(pathOf(habitOperations.tickItem, { id, itemId }), input),
50272
+ render: renderChecklist
50273
+ };
50274
+ }
50275
+ },
50276
+ {
50277
+ spec: {
50278
+ path: ["habit", "untick"],
50279
+ summary: "Untick an item of a checklist habit.",
50280
+ args: [habitArg, itemArg],
50281
+ flags: [DATE_FLAG],
50282
+ scopes: [...habitOperations.untickItem.scopes],
50283
+ returns: "HabitChecklistDay",
50284
+ notes: `${routeOf(habitOperations.untickItem)}. ${NOT_CHECKLIST}`
50285
+ },
50286
+ run: async ({ args, flags, requireClient }) => {
50287
+ const id = requireArg(args, 0, "habit id");
50288
+ const itemId = requireArg(args, 1, "item id");
50289
+ const input = parseInput(habitItemTickInputSchema, dateOf(flags));
50290
+ return {
50291
+ data: await requireClient().post(pathOf(habitOperations.untickItem, { id, itemId }), input),
50292
+ render: renderChecklist
50293
+ };
50294
+ }
50295
+ },
50296
+ {
50297
+ spec: {
50298
+ path: ["habit", "tick-all"],
50299
+ summary: 'Tick every item due ("All"), or all but some: "all done except one".',
50300
+ args: [habitArg],
50301
+ flags: [
50302
+ DATE_FLAG,
50303
+ {
50304
+ name: "except",
50305
+ type: "string",
50306
+ description: "Item ULIDs to leave unticked, comma-separated."
50307
+ }
50308
+ ],
50309
+ scopes: [...habitOperations.tickAll.scopes],
50310
+ returns: "HabitChecklistDay",
50311
+ notes: `${routeOf(habitOperations.tickAll)}. The items in --except end up unticked (unticked if they were). Find their ids with \`do habit checklist <id>\`. ${NOT_CHECKLIST}`
50312
+ },
50313
+ run: async ({ args, flags, requireClient }) => {
50314
+ const id = requireArg(args, 0, "habit id");
50315
+ const except = flagString(flags, "except");
50316
+ const input = parseInput(habitTickAllInputSchema, {
50317
+ ...dateOf(flags),
50318
+ ...except ? {
50319
+ except: except.split(",").map((s) => s.trim()).filter(Boolean)
50320
+ } : {}
50321
+ });
50322
+ return {
50323
+ data: await requireClient().post(pathOf(habitOperations.tickAll, { id }), input),
50324
+ render: renderChecklist
50325
+ };
50326
+ }
50327
+ }
50328
+ ];
50329
+ function dateOf(flags) {
50330
+ const date = flagString(flags, "date");
50331
+ return date ? { date } : {};
50332
+ }
50333
+
49746
50334
  // src/commands/habits.ts
49747
50335
  var SCHEDULE_FLAGS = [
49748
50336
  { name: "every-day", type: "boolean", description: "Due every day." },
@@ -49881,7 +50469,7 @@ function seasonFromFlags(flags) {
49881
50469
  const season = flagString(flags, "season");
49882
50470
  return season === undefined ? {} : { activeMonths: seasonFromFlag(season) };
49883
50471
  }
49884
- var commands21 = [
50472
+ var commands22 = [
49885
50473
  {
49886
50474
  spec: {
49887
50475
  path: ["habits", "create"],
@@ -51021,7 +51609,7 @@ function healthRecordHandlers() {
51021
51609
  }
51022
51610
  return out;
51023
51611
  }
51024
- var commands22 = pairCommands(HEALTH_COMMAND_SPECS, {
51612
+ var commands23 = pairCommands(HEALTH_COMMAND_SPECS, {
51025
51613
  ...healthRecordHandlers(),
51026
51614
  "health record": async ({ flags, requireClient }) => {
51027
51615
  const body = parseInput(logHealthInputSchema, readDataFlag(flags));
@@ -51291,7 +51879,7 @@ var commands22 = pairCommands(HEALTH_COMMAND_SPECS, {
51291
51879
  });
51292
51880
 
51293
51881
  // src/commands/house.ts
51294
- var commands23 = [
51882
+ var commands24 = [
51295
51883
  {
51296
51884
  spec: {
51297
51885
  path: ["house"],
@@ -51573,7 +52161,7 @@ function renderSorting(data, _mode) {
51573
52161
  ].join(`
51574
52162
  `);
51575
52163
  }
51576
- var commands24 = [
52164
+ var commands25 = [
51577
52165
  defineCommand({
51578
52166
  operation: inboxOperations.list,
51579
52167
  path: ["inbox"],
@@ -51665,7 +52253,7 @@ var commands24 = [
51665
52253
  ];
51666
52254
 
51667
52255
  // src/commands/incidents.ts
51668
- var commands25 = [
52256
+ var commands26 = [
51669
52257
  {
51670
52258
  spec: {
51671
52259
  path: ["incidents", "open"],
@@ -51894,7 +52482,7 @@ function journalDateArg(args, verb) {
51894
52482
  }
51895
52483
  return date;
51896
52484
  }
51897
- var commands26 = [
52485
+ var commands27 = [
51898
52486
  defineCommand({
51899
52487
  operation: journalOperations.day,
51900
52488
  path: ["journal", "day"],
@@ -52457,7 +53045,7 @@ function renderCreatedKey(data, mode) {
52457
53045
  ].join(`
52458
53046
  `);
52459
53047
  }
52460
- var commands27 = [
53048
+ var commands28 = [
52461
53049
  {
52462
53050
  spec: {
52463
53051
  path: ["keys", "list"],
@@ -52593,7 +53181,7 @@ var KIND_FLAG2 = {
52593
53181
  type: "string",
52594
53182
  description: "The kind of an unknown word (pages, eggs, health, note, or a word taught before); remembered for the Space."
52595
53183
  };
52596
- var commands28 = [
53184
+ var commands29 = [
52597
53185
  {
52598
53186
  spec: {
52599
53187
  path: ["log"],
@@ -52668,7 +53256,7 @@ var commands28 = [
52668
53256
  ];
52669
53257
 
52670
53258
  // src/commands/mail-campaigns.ts
52671
- var commands29 = [
53259
+ var commands30 = [
52672
53260
  {
52673
53261
  spec: {
52674
53262
  path: ["mail-campaigns", "list"],
@@ -52983,7 +53571,7 @@ async function serveMcp(io, target) {
52983
53571
  }
52984
53572
 
52985
53573
  // src/commands/mcp.ts
52986
- var commands30 = [
53574
+ var commands31 = [
52987
53575
  {
52988
53576
  spec: {
52989
53577
  path: ["mcp"],
@@ -53028,7 +53616,7 @@ var commands30 = [
53028
53616
  ];
53029
53617
 
53030
53618
  // src/commands/members.ts
53031
- var commands31 = [
53619
+ var commands32 = [
53032
53620
  {
53033
53621
  spec: {
53034
53622
  path: ["invite", "create"],
@@ -53153,7 +53741,7 @@ var commands31 = [
53153
53741
  ];
53154
53742
 
53155
53743
  // src/commands/metrics.ts
53156
- var commands32 = [
53744
+ var commands33 = [
53157
53745
  {
53158
53746
  spec: {
53159
53747
  path: ["metrics", "list"],
@@ -53281,7 +53869,7 @@ async function setModuleVisibility(args, requireClient, on) {
53281
53869
  render: renderRecord
53282
53870
  };
53283
53871
  }
53284
- var commands33 = [
53872
+ var commands34 = [
53285
53873
  {
53286
53874
  spec: {
53287
53875
  path: ["modules", "list"],
@@ -53510,7 +54098,7 @@ function shareFlag(flags) {
53510
54098
  function localMonth(now) {
53511
54099
  return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}`;
53512
54100
  }
53513
- var commands34 = [
54101
+ var commands35 = [
53514
54102
  defineCommand({
53515
54103
  operation: moneyOperations.listAccounts,
53516
54104
  path: ["money", "accounts"],
@@ -54372,6 +54960,33 @@ var commands34 = [
54372
54960
  render: renderRecord
54373
54961
  })
54374
54962
  }),
54963
+ defineCommand({
54964
+ operation: moneyOperations.flow,
54965
+ path: ["money", "flow"],
54966
+ summary: "Where the money went over a span of months: in by source, out to fixed, flexible, goals, invested and kept.",
54967
+ args: [],
54968
+ flags: [
54969
+ {
54970
+ name: "from",
54971
+ type: "string",
54972
+ description: "The first month, YYYY-MM, or start (default: --to)."
54973
+ },
54974
+ { name: "to", type: "string", description: "The last month, YYYY-MM (default this one)." },
54975
+ { name: "scope", type: "string", description: "all (default) | space | owner." }
54976
+ ],
54977
+ returns: "MoneyFlow",
54978
+ notes: ". sources (income by category, moved_in with a narrower scope) adding up to in; outs in the chart's order (fixed \xB7 flexible \xB7 moved_out \xB7 goals \xB7 invested \xB7 kept), only what's above zero; fromSavings when more went out than came in; fixed and flexible by category, with unsorted (what isn't sorted sits under flexible) and saved. `do money flow --from 2026-05 --to 2026-10`; `--from start` reads since the ledger begins.",
54979
+ run: async ({ flags, requireClient }) => ({
54980
+ data: await requireClient().get(pathOf(moneyOperations.flow), {
54981
+ query: {
54982
+ from: flagString(flags, "from"),
54983
+ to: flagString(flags, "to"),
54984
+ scope: flagString(flags, "scope")
54985
+ }
54986
+ }),
54987
+ render: renderRecord
54988
+ })
54989
+ }),
54375
54990
  defineCommand({
54376
54991
  operation: moneyOperations.netWorthRead,
54377
54992
  path: ["money", "net-worth"],
@@ -54652,7 +55267,7 @@ var commands34 = [
54652
55267
  ];
54653
55268
 
54654
55269
  // src/commands/notes.ts
54655
- var commands35 = [
55270
+ var commands36 = [
54656
55271
  {
54657
55272
  spec: {
54658
55273
  path: ["notes", "backlinks"],
@@ -54774,7 +55389,7 @@ var commands35 = [
54774
55389
  ];
54775
55390
 
54776
55391
  // src/commands/orca.ts
54777
- var commands36 = [
55392
+ var commands37 = [
54778
55393
  {
54779
55394
  spec: {
54780
55395
  path: ["orca", "list"],
@@ -55140,7 +55755,7 @@ function linkBody(args) {
55140
55755
  return parseInput(familyTreeLinkInputSchema, { kind, a: ref, b: other });
55141
55756
  throw usageError("the kind is parent, child or partner");
55142
55757
  }
55143
- var commands37 = [
55758
+ var commands38 = [
55144
55759
  {
55145
55760
  spec: {
55146
55761
  path: ["people", "propose"],
@@ -55829,7 +56444,7 @@ var commands37 = [
55829
56444
 
55830
56445
  // src/commands/places.ts
55831
56446
  import { readFileSync as readFileSync10 } from "fs";
55832
- var commands38 = [
56447
+ var commands39 = [
55833
56448
  {
55834
56449
  spec: {
55835
56450
  path: ["places", "import"],
@@ -55886,7 +56501,7 @@ async function planDecision({ args, requireClient }, verb) {
55886
56501
  render: renderPlan
55887
56502
  };
55888
56503
  }
55889
- var commands39 = [
56504
+ var commands40 = [
55890
56505
  {
55891
56506
  spec: {
55892
56507
  path: ["plans", "list"],
@@ -56113,7 +56728,7 @@ var commands39 = [
56113
56728
  ];
56114
56729
 
56115
56730
  // src/commands/presets.ts
56116
- var commands40 = [
56731
+ var commands41 = [
56117
56732
  {
56118
56733
  spec: {
56119
56734
  path: ["presets", "list"],
@@ -56210,7 +56825,7 @@ function renderReviewSummary(data, mode) {
56210
56825
  return out.join(`
56211
56826
  `);
56212
56827
  }
56213
- var commands41 = [
56828
+ var commands42 = [
56214
56829
  {
56215
56830
  spec: {
56216
56831
  path: ["progress"],
@@ -56419,7 +57034,7 @@ function renderUpdates(data, mode) {
56419
57034
  return updates.map((u) => updateLine(u, mode)).join(`
56420
57035
  `);
56421
57036
  }
56422
- var commands42 = [
57037
+ var commands43 = [
56423
57038
  defineCommand({
56424
57039
  operation: projectOperations.update,
56425
57040
  path: ["projects", "set"],
@@ -57016,7 +57631,7 @@ var routineCommands = [
57016
57631
  }
57017
57632
  }
57018
57633
  ];
57019
- var commands43 = [
57634
+ var commands44 = [
57020
57635
  ...routineCommands,
57021
57636
  {
57022
57637
  spec: {
@@ -57139,7 +57754,7 @@ var commands43 = [
57139
57754
  ];
57140
57755
 
57141
57756
  // src/commands/rsvp-answers.ts
57142
- var commands44 = [
57757
+ var commands45 = [
57143
57758
  {
57144
57759
  spec: {
57145
57760
  path: ["rsvp-answers", "list"],
@@ -57193,7 +57808,7 @@ var commands44 = [
57193
57808
  ];
57194
57809
 
57195
57810
  // src/commands/rsvp-links.ts
57196
- var commands45 = [
57811
+ var commands46 = [
57197
57812
  {
57198
57813
  spec: {
57199
57814
  path: ["rsvp-links", "list"],
@@ -57289,7 +57904,7 @@ var commands45 = [
57289
57904
  ];
57290
57905
 
57291
57906
  // src/commands/rsvp-questions.ts
57292
- var commands46 = [
57907
+ var commands47 = [
57293
57908
  {
57294
57909
  spec: {
57295
57910
  path: ["rsvp-questions", "presets"],
@@ -57861,7 +58476,7 @@ function sessionFlags(flags) {
57861
58476
  body.occurredOn = on;
57862
58477
  return body;
57863
58478
  }
57864
- var commands47 = [
58479
+ var commands48 = [
57865
58480
  {
57866
58481
  spec: {
57867
58482
  path: ["runs", "change"],
@@ -58178,7 +58793,7 @@ var commands47 = [
58178
58793
  ];
58179
58794
 
58180
58795
  // src/commands/search.ts
58181
- var commands48 = [
58796
+ var commands49 = [
58182
58797
  {
58183
58798
  spec: {
58184
58799
  path: ["search"],
@@ -58211,7 +58826,7 @@ var commands48 = [
58211
58826
  ];
58212
58827
 
58213
58828
  // src/commands/seating-proposals.ts
58214
- var commands49 = [
58829
+ var commands50 = [
58215
58830
  {
58216
58831
  spec: {
58217
58832
  path: ["seating-proposals", "list"],
@@ -58298,7 +58913,7 @@ var commands49 = [
58298
58913
  ];
58299
58914
 
58300
58915
  // src/commands/sensors.ts
58301
- var commands50 = [
58916
+ var commands51 = [
58302
58917
  {
58303
58918
  spec: {
58304
58919
  path: ["sensors", "status"],
@@ -58458,7 +59073,7 @@ var commands50 = [
58458
59073
  ];
58459
59074
 
58460
59075
  // src/commands/settings.ts
58461
- var commands51 = [
59076
+ var commands52 = [
58462
59077
  {
58463
59078
  spec: {
58464
59079
  path: ["settings", "get"],
@@ -58492,7 +59107,7 @@ var commands51 = [
58492
59107
  ];
58493
59108
 
58494
59109
  // src/commands/sharing.ts
58495
- var commands52 = [
59110
+ var commands53 = [
58496
59111
  {
58497
59112
  spec: {
58498
59113
  path: ["share"],
@@ -58625,7 +59240,7 @@ var commands52 = [
58625
59240
  ];
58626
59241
 
58627
59242
  // src/commands/space.ts
58628
- var commands53 = [
59243
+ var commands54 = [
58629
59244
  {
58630
59245
  spec: {
58631
59246
  path: ["space", "address"],
@@ -58681,7 +59296,7 @@ var commands53 = [
58681
59296
  ];
58682
59297
 
58683
59298
  // src/commands/tap-tags.ts
58684
- var commands54 = [
59299
+ var commands55 = [
58685
59300
  {
58686
59301
  spec: {
58687
59302
  path: ["tap-tags", "tap"],
@@ -58709,7 +59324,7 @@ var BY = {
58709
59324
  type: "string",
58710
59325
  description: "The blocking task's ref (DO-147) or ULID."
58711
59326
  };
58712
- var commands55 = [
59327
+ var commands56 = [
58713
59328
  defineCommand({
58714
59329
  operation: taskBlockOperations.addBlocker,
58715
59330
  path: ["tasks", "block"],
@@ -58775,7 +59390,7 @@ function renderSeries(data, mode) {
58775
59390
  }).join(`
58776
59391
  `);
58777
59392
  }
58778
- var commands56 = [
59393
+ var commands57 = [
58779
59394
  defineCommand({
58780
59395
  operation: taskSeriesOperations.make,
58781
59396
  path: ["tasks", "make-series"],
@@ -58930,7 +59545,7 @@ function repeatFromFlags(flags) {
58930
59545
  out.anchor = "from_completion";
58931
59546
  return out;
58932
59547
  }
58933
- var commands57 = [
59548
+ var commands58 = [
58934
59549
  {
58935
59550
  spec: {
58936
59551
  path: ["capture"],
@@ -59388,7 +60003,7 @@ var commands57 = [
59388
60003
  ];
59389
60004
 
59390
60005
  // src/commands/time-blocks.ts
59391
- var commands58 = [
60006
+ var commands59 = [
59392
60007
  {
59393
60008
  spec: {
59394
60009
  path: ["time-blocks", "record"],
@@ -59424,16 +60039,27 @@ var commands58 = [
59424
60039
  path: ["time-blocks", "plan-vs-record"],
59425
60040
  summary: "How the life blocks went against their plan: last week day by day, where the time went, which blocks move (in words), and one template change worth making.",
59426
60041
  args: [],
59427
- flags: [{ name: "days", type: "string", description: "7, 30 (default) or 90." }],
60042
+ flags: [
60043
+ { name: "days", type: "string", description: "7, 30 (default) or 90." },
60044
+ {
60045
+ name: "range",
60046
+ type: "string",
60047
+ description: "month | six | year | all (Review's months), in place of --days."
60048
+ }
60049
+ ],
59428
60050
  scopes: [...timeBlockOperations.planVsRecord.scopes],
59429
60051
  returns: "PlanVsRecord",
59430
- notes: `${routeOf(timeBlockOperations.planVsRecord)}?days= (plan vs record). No score, no streak.`
60052
+ notes: `${routeOf(timeBlockOperations.planVsRecord)}?days= or ?range= (plan vs record). No score, no streak.`
59431
60053
  },
59432
60054
  run: async ({ flags, requireClient }) => {
59433
60055
  const days = flagString(flags, "days");
60056
+ const range = flagString(flags, "range");
59434
60057
  return {
59435
60058
  data: await requireClient().get(pathOf(timeBlockOperations.planVsRecord), {
59436
- query: days === undefined ? {} : { days }
60059
+ query: {
60060
+ ...days === undefined ? {} : { days },
60061
+ ...range === undefined ? {} : { range }
60062
+ }
59437
60063
  }),
59438
60064
  render: renderRecord
59439
60065
  };
@@ -59569,7 +60195,7 @@ function renderLandedCounts(data, mode) {
59569
60195
  return out.join(`
59570
60196
  `);
59571
60197
  }
59572
- var commands59 = [
60198
+ var commands60 = [
59573
60199
  {
59574
60200
  spec: {
59575
60201
  path: ["today"],
@@ -59941,7 +60567,7 @@ function renderViews(data, mode) {
59941
60567
  function renderView(data, mode) {
59942
60568
  return renderViews([data], mode);
59943
60569
  }
59944
- var commands60 = [
60570
+ var commands61 = [
59945
60571
  defineCommand({
59946
60572
  operation: workViewOperations.list,
59947
60573
  path: ["views", "list"],
@@ -60060,7 +60686,7 @@ var commands60 = [
60060
60686
  ];
60061
60687
 
60062
60688
  // src/commands/worktree-links.ts
60063
- var commands61 = [
60689
+ var commands62 = [
60064
60690
  {
60065
60691
  spec: {
60066
60692
  path: ["worktree-links", "list"],
@@ -60227,7 +60853,8 @@ var FEATURE_COMMANDS = [
60227
60853
  ...commands58,
60228
60854
  ...commands59,
60229
60855
  ...commands60,
60230
- ...commands61
60856
+ ...commands61,
60857
+ ...commands62
60231
60858
  ];
60232
60859
 
60233
60860
  // src/registry.ts