@robbeverhelst/do 1.385.0 → 1.386.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 +157 -33
  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.386.0";
14424
14424
  var API_PREFIX = "/api/v1";
14425
14425
  var DEFAULT_API_URL = "http://localhost:3001";
14426
14426
 
@@ -19054,7 +19054,9 @@ var mealPlans = pgTable("meal_plans", {
19054
19054
  company: text("company"),
19055
19055
  leftoverPortions: integer2("leftover_portions"),
19056
19056
  leftoverEatBy: date5("leftover_eat_by", { mode: "string" }),
19057
- leftoverFrozen: boolean4("leftover_frozen").notNull().default(false)
19057
+ leftoverFrozen: boolean4("leftover_frozen").notNull().default(false),
19058
+ eaterUserIds: text("eater_user_ids").array().notNull().default([]),
19059
+ guests: integer2("guests").notNull().default(0)
19058
19060
  }, (t) => [
19059
19061
  index("meal_plans_tenant_planned_idx").on(t.tenantId, t.plannedFor),
19060
19062
  check2("meal_plans_state_check", sql`${t.state} IN ('planned', 'cooked', 'out', 'unsure', 'draft')`)
@@ -25090,7 +25092,10 @@ var blockTemplateInstanceSchema = object({
25090
25092
  routineId: string2().nullable()
25091
25093
  });
25092
25094
  var PLAN_VS_RECORD_RANGES = [7, 30, 90];
25095
+ var PLAN_VS_RECORD_MONTH_RANGES = ["month", "six", "year", "all"];
25096
+ var planVsRecordMonthRangeSchema = _enum2(PLAN_VS_RECORD_MONTH_RANGES);
25093
25097
  var planVsRecordQuerySchema = object({
25098
+ range: planVsRecordMonthRangeSchema.optional(),
25094
25099
  days: exports_coerce.number().refine((d) => PLAN_VS_RECORD_RANGES.includes(d), {
25095
25100
  message: "days must be 7, 30 or 90"
25096
25101
  }).default(30)
@@ -25144,6 +25149,7 @@ var planVsRecordSuggestionSchema = object({
25144
25149
  });
25145
25150
  var planVsRecordSchema = object({
25146
25151
  days: number2().int(),
25152
+ range: planVsRecordMonthRangeSchema.nullable().default(null),
25147
25153
  since: string2().nullable(),
25148
25154
  recordedDays: number2().int(),
25149
25155
  week: array(planVsRecordDaySchema),
@@ -35264,7 +35270,9 @@ var weekMenuFields = {
35264
35270
  company: string2().max(120).nullish(),
35265
35271
  leftoverPortions: number2().int().positive().nullish(),
35266
35272
  leftoverEatBy: civilDate2.nullish(),
35267
- leftoverFrozen: boolean2().optional()
35273
+ leftoverFrozen: boolean2().optional(),
35274
+ eaterUserIds: array(ulidSchema).max(50).optional(),
35275
+ guests: number2().int().min(0).max(99).optional()
35268
35276
  };
35269
35277
  var mealPlanSchema = createSelectSchema(mealPlans, {
35270
35278
  plannedFor: exports_coerce.date(),
@@ -35273,7 +35281,9 @@ var mealPlanSchema = createSelectSchema(mealPlans, {
35273
35281
  company: string2().nullable().default(null),
35274
35282
  leftoverPortions: number2().int().nullable().default(null),
35275
35283
  leftoverEatBy: string2().nullable().default(null),
35276
- leftoverFrozen: boolean2().default(false)
35284
+ leftoverFrozen: boolean2().default(false),
35285
+ eaterUserIds: array(string2()).default([]),
35286
+ guests: number2().int().default(0)
35277
35287
  });
35278
35288
  var createMealPlanInputSchema = createInsertSchema(mealPlans, {
35279
35289
  id: ulidSchema,
@@ -35340,6 +35350,8 @@ var mealWeekSlotSchema = object({
35340
35350
  cook: mealWeekCookSchema.nullable(),
35341
35351
  company: string2().nullable(),
35342
35352
  notes: string2().nullable(),
35353
+ eaters: array(mealWeekCookSchema).default([]),
35354
+ guests: number2().int().min(0).default(0),
35343
35355
  time: string2().nullable()
35344
35356
  });
35345
35357
  var mealWeekDaySchema = object({
@@ -35573,8 +35585,60 @@ var moneyOdooUndoResultSchema = object({
35573
35585
  line: string2()
35574
35586
  });
35575
35587
 
35576
- // ../../packages/schema/src/contracts/money-net-worth.ts
35588
+ // ../../packages/schema/src/contracts/money-flow.ts
35577
35589
  var amount5 = string2();
35590
+ var MONEY_FLOW_START = "start";
35591
+ var moneyFlowQuerySchema = object({
35592
+ from: union([moneyMonthSchema, literal(MONEY_FLOW_START)]).optional(),
35593
+ to: moneyMonthSchema.optional(),
35594
+ scope: moneyBudgetScopeSchema.optional()
35595
+ }).refine((q) => !q.from || q.from === MONEY_FLOW_START || !q.to || q.from <= q.to, {
35596
+ message: "from must not be after to",
35597
+ path: ["from"]
35598
+ });
35599
+ var moneyFlowSourceSchema = object({
35600
+ kind: _enum2(["income", "moved_in"]),
35601
+ categoryId: ulidSchema.nullable(),
35602
+ name: string2(),
35603
+ amount: amount5
35604
+ });
35605
+ var MONEY_FLOW_OUTS = [
35606
+ "fixed",
35607
+ "flexible",
35608
+ "moved_out",
35609
+ "goals",
35610
+ "invested",
35611
+ "kept"
35612
+ ];
35613
+ var moneyFlowOutKindSchema = _enum2(MONEY_FLOW_OUTS);
35614
+ var moneyFlowOutSchema = object({
35615
+ kind: moneyFlowOutKindSchema,
35616
+ name: string2(),
35617
+ amount: amount5
35618
+ });
35619
+ var moneyFlowCategorySchema = object({
35620
+ categoryId: ulidSchema.nullable(),
35621
+ name: string2(),
35622
+ amount: amount5
35623
+ });
35624
+ var moneyFlowSchema = object({
35625
+ scope: moneyBudgetScopeSchema,
35626
+ from: moneyMonthSchema,
35627
+ to: moneyMonthSchema,
35628
+ through: moneyMonthSchema,
35629
+ firstMonth: moneyMonthSchema.nullable(),
35630
+ in: amount5,
35631
+ sources: array(moneyFlowSourceSchema),
35632
+ fromSavings: amount5,
35633
+ outs: array(moneyFlowOutSchema),
35634
+ fixed: array(moneyFlowCategorySchema),
35635
+ flexible: array(moneyFlowCategorySchema),
35636
+ unsorted: amount5,
35637
+ saved: amount5
35638
+ });
35639
+
35640
+ // ../../packages/schema/src/contracts/money-net-worth.ts
35641
+ var amount6 = string2();
35578
35642
  var moneySnapshotSourceSchema = _enum2(moneySnapshotSource.enumValues);
35579
35643
  var moneyNetWorthQuerySchema = object({
35580
35644
  scope: moneyBudgetScopeSchema.optional(),
@@ -35582,9 +35646,9 @@ var moneyNetWorthQuerySchema = object({
35582
35646
  });
35583
35647
  var moneyNetWorthPointSchema = object({
35584
35648
  month: moneyMonthSchema,
35585
- total: amount5.nullable(),
35586
- have: amount5.nullable(),
35587
- owe: amount5.nullable()
35649
+ total: amount6.nullable(),
35650
+ have: amount6.nullable(),
35651
+ owe: amount6.nullable()
35588
35652
  });
35589
35653
  var moneyNetWorthAccountSchema = object({
35590
35654
  accountId: ulidSchema,
@@ -35592,7 +35656,7 @@ var moneyNetWorthAccountSchema = object({
35592
35656
  kind: moneyAccountKindSchema,
35593
35657
  visibility: _enum2(NODE_VISIBILITY_VALUES),
35594
35658
  currency: string2(),
35595
- value: amount5,
35659
+ value: amount6,
35596
35660
  source: moneySnapshotSourceSchema,
35597
35661
  month: moneyMonthSchema,
35598
35662
  pensionSubtype: moneyPensionSubtypeSchema.nullable(),
@@ -35609,11 +35673,11 @@ var moneyNetWorthUnknownSchema = moneyNetWorthAccountSchema.pick({
35609
35673
  var moneyNetWorthSchema = object({
35610
35674
  scope: moneyBudgetScopeSchema,
35611
35675
  month: moneyMonthSchema,
35612
- total: amount5,
35613
- have: amount5,
35614
- owe: amount5,
35615
- liquid: amount5,
35616
- locked: amount5,
35676
+ total: amount6,
35677
+ have: amount6,
35678
+ owe: amount6,
35679
+ liquid: amount6,
35680
+ locked: amount6,
35617
35681
  points: array(moneyNetWorthPointSchema),
35618
35682
  accounts: array(moneyNetWorthAccountSchema),
35619
35683
  complete: boolean2(),
@@ -35628,7 +35692,7 @@ var moneySnapshotSchema = object({
35628
35692
  id: ulidSchema,
35629
35693
  accountId: ulidSchema,
35630
35694
  month: moneyMonthSchema,
35631
- value: amount5,
35695
+ value: amount6,
35632
35696
  source: moneySnapshotSourceSchema
35633
35697
  });
35634
35698
 
@@ -35718,22 +35782,22 @@ var moneySettlementViewSchema = object({
35718
35782
  });
35719
35783
 
35720
35784
  // ../../packages/schema/src/contracts/money-year.ts
35721
- var amount6 = string2();
35785
+ var amount7 = string2();
35722
35786
  var moneyYearQuerySchema = object({
35723
35787
  year: exports_coerce.number().int().min(2000).max(2100).optional(),
35724
35788
  scope: moneyBudgetScopeSchema.optional()
35725
35789
  });
35726
35790
  var moneyYearMonthSchema = object({
35727
35791
  month: moneyMonthSchema,
35728
- income: amount6,
35729
- spent: amount6
35792
+ income: amount7,
35793
+ spent: amount7
35730
35794
  });
35731
35795
  var moneyYearCategorySchema = object({
35732
35796
  categoryId: ulidSchema.nullable(),
35733
35797
  name: string2(),
35734
35798
  group: _enum2(["fixed", "flexible", "income"]).nullable(),
35735
- amount: amount6,
35736
- lastYear: amount6
35799
+ amount: amount7,
35800
+ lastYear: amount7
35737
35801
  });
35738
35802
  var MONEY_YEAR_STREAM_CHANGES = ["new", "stopped", "up", "down", "same"];
35739
35803
  var moneyYearStreamChangeSchema = _enum2(MONEY_YEAR_STREAM_CHANGES);
@@ -35742,8 +35806,8 @@ var moneyYearStreamSchema = object({
35742
35806
  title: string2(),
35743
35807
  cadence: moneyCadenceSchema,
35744
35808
  visibility: _enum2(NODE_VISIBILITY_VALUES),
35745
- thisYear: amount6,
35746
- lastYear: amount6,
35809
+ thisYear: amount7,
35810
+ lastYear: amount7,
35747
35811
  change: moneyYearStreamChangeSchema
35748
35812
  });
35749
35813
  var moneyYearGoalSchema = object({
@@ -35752,14 +35816,14 @@ var moneyYearGoalSchema = object({
35752
35816
  visibility: _enum2(NODE_VISIBILITY_VALUES),
35753
35817
  status: moneyGoalStatusSchema,
35754
35818
  projectTitle: string2().nullable(),
35755
- thisYear: amount6,
35756
- saved: amount6,
35757
- target: amount6
35819
+ thisYear: amount7,
35820
+ saved: amount7,
35821
+ target: amount7
35758
35822
  });
35759
35823
  var moneyYearTotalsSchema = object({
35760
- income: amount6,
35761
- spent: amount6,
35762
- saved: amount6
35824
+ income: amount7,
35825
+ spent: amount7,
35826
+ saved: amount7
35763
35827
  });
35764
35828
  var moneyYearSchema = object({
35765
35829
  year: number2().int(),
@@ -36413,6 +36477,23 @@ var moneyOperations = defineOperations({
36413
36477
  response: { description: "The year." },
36414
36478
  errors: { 400: true }
36415
36479
  },
36480
+ flow: {
36481
+ method: "get",
36482
+ path: "/money/flow",
36483
+ scopes: ["finance:read"],
36484
+ tag: "Money",
36485
+ summary: "Get where the money went",
36486
+ 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`.",
36487
+ query: [
36488
+ { name: "from", description: "The first month, YYYY-MM, or start (default: to)." },
36489
+ { name: "to", description: "The last month, YYYY-MM (default this one)." },
36490
+ { name: "scope", description: "all, space or owner." }
36491
+ ],
36492
+ querySchema: moneyFlowQuerySchema,
36493
+ status: 200,
36494
+ response: { description: "The flow." },
36495
+ errors: { 400: true }
36496
+ },
36416
36497
  netWorthRead: {
36417
36498
  method: "get",
36418
36499
  path: "/money/net-worth",
@@ -41452,9 +41533,14 @@ var timeBlockOperations = defineOperations({
41452
41533
  scopes: ["calendar:read"],
41453
41534
  tag: "Calendar",
41454
41535
  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.',
41536
+ 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
41537
  query: [
41457
- { name: "days", description: "7, 30 (default) or 90.", type: "integer", enum: [7, 30, 90] }
41538
+ { name: "days", description: "7, 30 (default) or 90.", type: "integer", enum: [7, 30, 90] },
41539
+ {
41540
+ name: "range",
41541
+ description: "month, six, year or all, in place of days.",
41542
+ enum: ["month", "six", "year", "all"]
41543
+ }
41458
41544
  ],
41459
41545
  querySchema: planVsRecordQuerySchema,
41460
41546
  status: 200,
@@ -54372,6 +54458,33 @@ var commands34 = [
54372
54458
  render: renderRecord
54373
54459
  })
54374
54460
  }),
54461
+ defineCommand({
54462
+ operation: moneyOperations.flow,
54463
+ path: ["money", "flow"],
54464
+ summary: "Where the money went over a span of months: in by source, out to fixed, flexible, goals, invested and kept.",
54465
+ args: [],
54466
+ flags: [
54467
+ {
54468
+ name: "from",
54469
+ type: "string",
54470
+ description: "The first month, YYYY-MM, or start (default: --to)."
54471
+ },
54472
+ { name: "to", type: "string", description: "The last month, YYYY-MM (default this one)." },
54473
+ { name: "scope", type: "string", description: "all (default) | space | owner." }
54474
+ ],
54475
+ returns: "MoneyFlow",
54476
+ 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.",
54477
+ run: async ({ flags, requireClient }) => ({
54478
+ data: await requireClient().get(pathOf(moneyOperations.flow), {
54479
+ query: {
54480
+ from: flagString(flags, "from"),
54481
+ to: flagString(flags, "to"),
54482
+ scope: flagString(flags, "scope")
54483
+ }
54484
+ }),
54485
+ render: renderRecord
54486
+ })
54487
+ }),
54375
54488
  defineCommand({
54376
54489
  operation: moneyOperations.netWorthRead,
54377
54490
  path: ["money", "net-worth"],
@@ -59424,16 +59537,27 @@ var commands58 = [
59424
59537
  path: ["time-blocks", "plan-vs-record"],
59425
59538
  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
59539
  args: [],
59427
- flags: [{ name: "days", type: "string", description: "7, 30 (default) or 90." }],
59540
+ flags: [
59541
+ { name: "days", type: "string", description: "7, 30 (default) or 90." },
59542
+ {
59543
+ name: "range",
59544
+ type: "string",
59545
+ description: "month | six | year | all (Review's months), in place of --days."
59546
+ }
59547
+ ],
59428
59548
  scopes: [...timeBlockOperations.planVsRecord.scopes],
59429
59549
  returns: "PlanVsRecord",
59430
- notes: `${routeOf(timeBlockOperations.planVsRecord)}?days= (plan vs record). No score, no streak.`
59550
+ notes: `${routeOf(timeBlockOperations.planVsRecord)}?days= or ?range= (plan vs record). No score, no streak.`
59431
59551
  },
59432
59552
  run: async ({ flags, requireClient }) => {
59433
59553
  const days = flagString(flags, "days");
59554
+ const range = flagString(flags, "range");
59434
59555
  return {
59435
59556
  data: await requireClient().get(pathOf(timeBlockOperations.planVsRecord), {
59436
- query: days === undefined ? {} : { days }
59557
+ query: {
59558
+ ...days === undefined ? {} : { days },
59559
+ ...range === undefined ? {} : { range }
59560
+ }
59437
59561
  }),
59438
59562
  render: renderRecord
59439
59563
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@robbeverhelst/do",
3
- "version": "1.385.0",
3
+ "version": "1.386.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",