@robbeverhelst/do 1.293.0 → 1.295.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 +273 -20
  2. package/package.json +1 -1
package/dist/do.js CHANGED
@@ -4750,6 +4750,7 @@ var moneyTransactions = pgTable("money_transactions", {
4750
4750
  onDelete: "set null"
4751
4751
  }),
4752
4752
  note: text("note"),
4753
+ orderItem: text("order_item"),
4753
4754
  businessShare: smallint("business_share").notNull().default(0),
4754
4755
  businessStatus: moneyBusinessStatus("business_status").notNull().default("none"),
4755
4756
  businessNote: text("business_note"),
@@ -5050,7 +5051,14 @@ var files = pgTable("files", {
5050
5051
  ]);
5051
5052
 
5052
5053
  // ../../packages/schema/src/db/guests.ts
5053
- var guestTier = pgEnum("guest_tier", ["ceremony", "reception", "dinner", "party"]);
5054
+ var guestTier = pgEnum("guest_tier", [
5055
+ "civil",
5056
+ "church",
5057
+ "ceremony",
5058
+ "reception",
5059
+ "dinner",
5060
+ "party"
5061
+ ]);
5054
5062
  var households = pgTable("households", {
5055
5063
  id: text("id").primaryKey().references(() => nodes.id),
5056
5064
  tenantId: text("tenant_id").notNull().references(() => tenants.id),
@@ -5083,6 +5091,23 @@ var guestTables = pgTable("guest_tables", {
5083
5091
  createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
5084
5092
  updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
5085
5093
  }, (t) => [index("guest_tables_list_idx").on(t.guestListId)]);
5094
+ var guestListEvents = pgTable("guest_list_events", {
5095
+ id: text("id").primaryKey(),
5096
+ tenantId: text("tenant_id").notNull().references(() => tenants.id),
5097
+ guestListId: text("guest_list_id").notNull().references(() => guestLists.id, { onDelete: "cascade" }),
5098
+ key: guestTier("key").notNull(),
5099
+ name: jsonb("name").$type().notNull(),
5100
+ startsAt: timestamp("starts_at", { withTimezone: true }),
5101
+ endsAt: timestamp("ends_at", { withTimezone: true }),
5102
+ placeName: text("place_name"),
5103
+ address: text("address"),
5104
+ mapUrl: text("map_url"),
5105
+ dressCode: jsonb("dress_code").$type(),
5106
+ note: jsonb("note").$type(),
5107
+ sort: integer("sort").notNull().default(0),
5108
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
5109
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
5110
+ }, (t) => [uniqueIndex("guest_list_events_key_uniq").on(t.guestListId, t.key)]);
5086
5111
  var guests = pgTable("guests", {
5087
5112
  id: text("id").primaryKey(),
5088
5113
  tenantId: text("tenant_id").notNull().references(() => tenants.id),
@@ -21324,7 +21349,11 @@ var houseAssetLinkSchema = object({
21324
21349
  title: string2(),
21325
21350
  type: string2(),
21326
21351
  kind: string2(),
21327
- direction: _enum2(["in", "out"])
21352
+ direction: _enum2(["in", "out"]),
21353
+ label: string2().nullable().default(null),
21354
+ context: string2().nullable().default(null),
21355
+ at: exports_coerce.date().nullable().default(null),
21356
+ timed: boolean3().default(false)
21328
21357
  });
21329
21358
  var houseAssetSchema = object({
21330
21359
  item: collectionItemDetailSchema,
@@ -21657,13 +21686,30 @@ var postRunSchema = object({
21657
21686
  });
21658
21687
  var POST_RECEIPT_ABOUT_VALUES = ["red_flags", "saved", "vet_visit"];
21659
21688
  var POST_RECEIPT_SOURCE_MAX = 80;
21660
- var postReceiptInputSchema = object({
21689
+ var postNodeReceiptInputSchema = object({
21661
21690
  nodeId: ulidSchema,
21662
21691
  parts: array(ulidSchema).min(1).max(10).optional(),
21663
21692
  about: _enum2(POST_RECEIPT_ABOUT_VALUES).optional(),
21664
21693
  source: string2().trim().min(1).max(POST_RECEIPT_SOURCE_MAX).optional(),
21665
21694
  personNotes: array(ulidSchema).min(1).max(10).optional()
21666
21695
  }).strict();
21696
+ var POST_MONEY_RECEIPT_ABOUT_VALUES = ["ask", "bill"];
21697
+ var webUrlSchema = string2().url().max(2000).refine((url) => /^https?:\/\//i.test(url), "must be an http(s) link");
21698
+ var postMoneyReceiptInputSchema = object({
21699
+ transactionId: ulidSchema,
21700
+ about: _enum2(POST_MONEY_RECEIPT_ABOUT_VALUES),
21701
+ odoo: object({
21702
+ openUrl: webUrlSchema,
21703
+ account: string2().trim().min(1).max(120).nullish()
21704
+ }).strict().optional(),
21705
+ undo: object({
21706
+ items: array(object({ id: ulidSchema }).passthrough()).min(1).max(200)
21707
+ }).optional()
21708
+ }).strict();
21709
+ var postReceiptInputSchema = union([
21710
+ postNodeReceiptInputSchema,
21711
+ postMoneyReceiptInputSchema
21712
+ ]);
21667
21713
  var postReceiptPartSchema = object({
21668
21714
  id: string2(),
21669
21715
  type: string2(),
@@ -21674,8 +21720,10 @@ var postReceiptSchema = object({
21674
21720
  nodeType: string2(),
21675
21721
  parts: array(string2()).optional(),
21676
21722
  partNodes: array(postReceiptPartSchema).optional(),
21677
- about: _enum2(POST_RECEIPT_ABOUT_VALUES).optional(),
21678
- source: string2().optional()
21723
+ about: _enum2([...POST_RECEIPT_ABOUT_VALUES, ...POST_MONEY_RECEIPT_ABOUT_VALUES]).optional(),
21724
+ source: string2().optional(),
21725
+ odoo: object({ openUrl: string2(), account: string2().nullish() }).optional(),
21726
+ undo: object({ items: array(object({ id: string2() }).passthrough()) }).optional()
21679
21727
  });
21680
21728
  var POST_TITLE_MAX = 200;
21681
21729
  var postTitleSchema = string2().trim().min(1).max(POST_TITLE_MAX);
@@ -23641,6 +23689,7 @@ var createMealLogInputSchema = object({
23641
23689
  photoFileId: ulidSchema.nullish(),
23642
23690
  items: array(mealLogItemInputSchema).min(1).max(40)
23643
23691
  }).strict();
23692
+ var logUsualMealInputSchema = object({ mealType: mealLogTypeSchema }).strict();
23644
23693
  var correctMealLogInputSchema = object({
23645
23694
  title: string2().trim().min(1).max(200).optional(),
23646
23695
  eatenAt: exports_coerce.date().optional(),
@@ -23846,7 +23895,10 @@ var FOOD_PATTERN_QUESTION_VALUES = [
23846
23895
  "flagged_meal_symptom",
23847
23896
  "coffee_sleep",
23848
23897
  "kcal_rating",
23849
- "weekly_kcal_weight"
23898
+ "weekly_kcal_weight",
23899
+ "fried_next_day",
23900
+ "skipped_breakfast_lunch",
23901
+ "big_dinner_sleep"
23850
23902
  ];
23851
23903
  var foodPatternQuestionSchema = _enum2(FOOD_PATTERN_QUESTION_VALUES);
23852
23904
  var foodPatternSideSchema = object({
@@ -23861,6 +23913,12 @@ var foodPatternWeekSchema = object({
23861
23913
  averageKcal: number2().nullable(),
23862
23914
  weightChange: number2().nullable()
23863
23915
  });
23916
+ var foodPatternDaySchema = object({
23917
+ day: civilDate,
23918
+ with: boolean3(),
23919
+ hit: boolean3().nullable(),
23920
+ value: number2().nullable()
23921
+ });
23864
23922
  var foodPatternAnswerSchema = object({
23865
23923
  question: foodPatternQuestionSchema,
23866
23924
  title: string2(),
@@ -23874,7 +23932,9 @@ var foodPatternAnswerSchema = object({
23874
23932
  neededDays: number2().int().nonnegative(),
23875
23933
  progress: object({ have: number2().int(), need: number2().int() }),
23876
23934
  examples: array(string2()),
23877
- weeks: array(foodPatternWeekSchema)
23935
+ weeks: array(foodPatternWeekSchema),
23936
+ unit: _enum2(["days", "nights", "weeks"]),
23937
+ behind: array(foodPatternDaySchema)
23878
23938
  });
23879
23939
  var FOOD_TRIAL_NOTE_MAX = 1000;
23880
23940
  var proposeFoodTrialInputSchema = object({
@@ -24694,7 +24754,8 @@ var sortMoneyTransactionInputSchema = object({
24694
24754
  businessShare: moneyBusinessShareSchema.optional(),
24695
24755
  businessStatus: moneySortBusinessStatusSchema.optional(),
24696
24756
  businessNote: moneyBusinessNoteSchema.nullish(),
24697
- taxTag: moneyTaxTagSchema.nullish()
24757
+ taxTag: moneyTaxTagSchema.nullish(),
24758
+ orderItem: string2().trim().min(1).max(200).nullish()
24698
24759
  }).strict();
24699
24760
  var createMoneyRuleInputSchema = object({
24700
24761
  id: ulidSchema,
@@ -25094,6 +25155,7 @@ var insuranceFieldsSchema = object({
25094
25155
  }).partial().strict();
25095
25156
  var contractFieldsSchema = object({
25096
25157
  customerNo: text4,
25158
+ product: text4,
25097
25159
  plan: text4,
25098
25160
  price: amount4,
25099
25161
  cadence: documentCadenceSchema,
@@ -25724,8 +25786,9 @@ var runAchievementsSchema = object({
25724
25786
  source: _enum2(["steam", "xbox", "psn", "manual"]).default("manual"),
25725
25787
  total: number2().int().min(0).max(5000).nullish(),
25726
25788
  enabled: boolean3().default(true),
25727
- unlocked: array(object({ name, on: isoDate.nullish(), hint: shortText.nullish() }).strict()).max(5000),
25728
- locked: array(object({ name, hint: shortText.nullish() }).strict()).max(5000).optional()
25789
+ unlocked: array(object({ name, on: isoDate.nullish(), hint: shortText.nullish(), key: ref.nullish() }).strict()).max(5000),
25790
+ locked: array(object({ name, hint: shortText.nullish(), key: ref.nullish() }).strict()).max(5000).optional(),
25791
+ syncedAt: string2().datetime({ offset: true }).nullish()
25729
25792
  }).strict();
25730
25793
  var runRareFindsSchema = object({
25731
25794
  place: shortText.nullish(),
@@ -25944,6 +26007,39 @@ var runsQuerySchema = object({
25944
26007
  theme: runThemeSchema.optional()
25945
26008
  }).strict();
25946
26009
 
26010
+ // ../../packages/schema/src/contracts/runs-steam.ts
26011
+ var steamIdSchema = string2().trim().regex(/^7656119\d{10}$/, "must be a SteamID64 (17 digits, starting 7656119)");
26012
+ var steamApiKeySchema = string2().trim().regex(/^[0-9A-Fa-f]{32}$/, "must be a Steam Web API key (32 letters and digits)");
26013
+ var steamAccountInputSchema = object({ steamId: steamIdSchema, apiKey: steamApiKeySchema }).strict();
26014
+ var steamAccountStatusSchema = object({
26015
+ connected: boolean3(),
26016
+ games: number2().int().nonnegative(),
26017
+ lastSyncedAt: string2().nullable()
26018
+ });
26019
+ var steamSyncInputSchema = object({ gameId: string2().trim().min(1).max(64).optional() }).strict();
26020
+ var steamSyncErrorValues = [
26021
+ "unauthorized",
26022
+ "private",
26023
+ "no_stats",
26024
+ "unavailable",
26025
+ "bad_response"
26026
+ ];
26027
+ var steamSyncErrorSchema = _enum2(steamSyncErrorValues);
26028
+ var steamGameSyncSchema = object({
26029
+ gameId: string2(),
26030
+ gameTitle: string2(),
26031
+ appId: number2().int(),
26032
+ outcome: _enum2(["ok", "failed"]),
26033
+ runs: number2().int().nonnegative(),
26034
+ unlocked: number2().int().nonnegative(),
26035
+ total: number2().int().nonnegative(),
26036
+ error: steamSyncErrorSchema.nullable()
26037
+ });
26038
+ var steamSyncResultSchema = object({
26039
+ syncedAt: string2(),
26040
+ games: array(steamGameSyncSchema)
26041
+ });
26042
+
25947
26043
  // ../../packages/schema/src/contracts/animals.ts
25948
26044
  var animalFormSchema = _enum2(animalForm.enumValues);
25949
26045
  var animalStatusSchema = _enum2(animalStatus.enumValues);
@@ -26436,7 +26532,7 @@ var animalsOverviewSchema = object({
26436
26532
  supplies: array(animalSupplySchema),
26437
26533
  habits: array(animalHabitSchema)
26438
26534
  }),
26439
- comingUp: array(keyDateViewSchema),
26535
+ comingUp: array(keyDateViewSchema.extend({ vet: string2().nullable() })),
26440
26536
  periods: array(periodViewSchema)
26441
26537
  });
26442
26538
  var animalHolidayModeSchema = object({
@@ -26617,7 +26713,8 @@ var moneyTaxEvidenceSchema = object({
26617
26713
  }))
26618
26714
  });
26619
26715
  var moneyOdooPushInputSchema = object({
26620
- note: string2().trim().min(1).max(500).optional()
26716
+ note: string2().trim().min(1).max(500).optional(),
26717
+ account: string2().trim().min(1).max(120).optional()
26621
26718
  }).strict();
26622
26719
  var moneyOdooReceiptSchema = object({
26623
26720
  transactionId: ulidSchema,
@@ -26627,7 +26724,8 @@ var moneyOdooReceiptSchema = object({
26627
26724
  amount: string2(),
26628
26725
  share: moneyBusinessShareSchema,
26629
26726
  attachments: number2().int().nonnegative(),
26630
- alreadyThere: boolean3()
26727
+ alreadyThere: boolean3(),
26728
+ account: string2().nullable().default(null)
26631
26729
  });
26632
26730
  var moneyOdooUndoResultSchema = object({
26633
26731
  transactionId: ulidSchema,
@@ -26868,7 +26966,7 @@ var guestListViewSchema = guestListSchema.extend({
26868
26966
  var createGuestListInputSchema = object({
26869
26967
  id: ulidSchema,
26870
26968
  projectId: ulidSchema,
26871
- tiers: array(guestTierSchema).min(1).max(4).optional(),
26969
+ tiers: array(guestTierSchema).min(1).max(6).optional(),
26872
26970
  caps: capsSchema.optional(),
26873
26971
  sides: array(sideSchema).max(4).optional(),
26874
26972
  rsvpBy: keyDateDaySchema.nullish()
@@ -26897,7 +26995,7 @@ var createGuestInputSchema = object({
26897
26995
  guestListId: ulidSchema,
26898
26996
  contactId: ulidSchema,
26899
26997
  side: sideSchema.nullish(),
26900
- tiers: array(guestTierSchema).max(4).optional(),
26998
+ tiers: array(guestTierSchema).max(6).optional(),
26901
26999
  rsvp: answersSchema.optional(),
26902
27000
  plusOne: boolean3().optional(),
26903
27001
  plusOneName: string2().trim().min(1).max(120).nullish(),
@@ -27019,6 +27117,35 @@ var submitRsvpInputSchema = object({
27019
27117
  }).strict()).min(1).max(30),
27020
27118
  address: householdAddressSchema.nullish()
27021
27119
  }).strict();
27120
+ var eventTextSchema = (max) => object({
27121
+ nl: string2().trim().min(1).max(max).optional(),
27122
+ pt: string2().trim().min(1).max(max).optional()
27123
+ }).strict().refine((t) => t.nl !== undefined || t.pt !== undefined, "give it in NL or PT");
27124
+ var guestEventKeySchema = guestTierSchema;
27125
+ var guestListEventSchema = createSelectSchema(guestListEvents, {
27126
+ name: object({ nl: string2().optional(), pt: string2().optional() }),
27127
+ dressCode: object({ nl: string2().optional(), pt: string2().optional() }).nullable(),
27128
+ note: object({ nl: string2().optional(), pt: string2().optional() }).nullable(),
27129
+ startsAt: exports_coerce.date().nullable(),
27130
+ endsAt: exports_coerce.date().nullable(),
27131
+ createdAt: exports_coerce.date(),
27132
+ updatedAt: exports_coerce.date()
27133
+ });
27134
+ var eventFields = {
27135
+ name: eventTextSchema(120),
27136
+ startsAt: exports_coerce.date().nullish(),
27137
+ endsAt: exports_coerce.date().nullish(),
27138
+ placeName: string2().trim().min(1).max(120).nullish(),
27139
+ address: string2().trim().min(1).max(300).nullish(),
27140
+ mapUrl: string2().trim().url().max(500).refine((u) => /^https?:\/\//.test(u), "expected an http(s) link").nullish(),
27141
+ dressCode: eventTextSchema(200).nullish(),
27142
+ note: eventTextSchema(1000).nullish(),
27143
+ sort: number2().int().min(0).max(1e4).optional()
27144
+ };
27145
+ var endsAfterStart2 = (e) => !e.startsAt || !e.endsAt || e.endsAt >= e.startsAt;
27146
+ var createGuestListEventInputSchema = object({ id: ulidSchema, guestListId: ulidSchema, key: guestEventKeySchema, ...eventFields }).strict().refine(endsAfterStart2, { message: "endsAt is before startsAt", path: ["endsAt"] });
27147
+ var updateGuestListEventInputSchema = object(eventFields).partial().strict().refine(endsAfterStart2, { message: "endsAt is before startsAt", path: ["endsAt"] });
27148
+ var guestListEventsQuerySchema = object({ guestListId: ulidSchema });
27022
27149
  var guestTableSchema = createSelectSchema(guestTables, {
27023
27150
  createdAt: exports_coerce.date(),
27024
27151
  updatedAt: exports_coerce.date()
@@ -28332,7 +28459,8 @@ var gameFacetSchema = object({
28332
28459
  platform: string2().min(1).max(120).nullish(),
28333
28460
  coverUrl,
28334
28461
  coverSources: coverSourcesSchema.nullish(),
28335
- completion: number2().int().min(0).max(100).nullish()
28462
+ completion: number2().int().min(0).max(100).nullish(),
28463
+ steamAppId: number2().int().positive().max(99999999).nullish()
28336
28464
  }).strict();
28337
28465
  var musicFacetSchema = object({
28338
28466
  artist: string2().min(1).max(200).nullish(),
@@ -28807,7 +28935,7 @@ function parseCapture2(input, now) {
28807
28935
 
28808
28936
  // src/meta.ts
28809
28937
  var CLI_NAME = "do";
28810
- var VERSION = "1.293.0";
28938
+ var VERSION = "1.295.0";
28811
28939
  var API_PREFIX = "/api/v1";
28812
28940
  var DEFAULT_API_URL = "http://localhost:3001";
28813
28941
 
@@ -29522,6 +29650,24 @@ var ENTITIES = [
29522
29650
  canDelete: true
29523
29651
  }
29524
29652
  },
29653
+ {
29654
+ name: "guest-list-events",
29655
+ path: "/guest-list-events",
29656
+ readScope: "contacts:read",
29657
+ returns: "GuestListEvent",
29658
+ canGet: true,
29659
+ listFlags: [
29660
+ { name: "list", description: "the guest list's id (required)", query: "guestListId" }
29661
+ ],
29662
+ write: {
29663
+ scope: "contacts:write",
29664
+ createSchema: createGuestListEventInputSchema,
29665
+ createInput: "CreateGuestListEventInput",
29666
+ updateSchema: updateGuestListEventInputSchema,
29667
+ updateInput: "UpdateGuestListEventInput",
29668
+ canDelete: true
29669
+ }
29670
+ },
29525
29671
  {
29526
29672
  name: "guest-tables",
29527
29673
  path: "/guest-tables",
@@ -31662,6 +31808,44 @@ var COMMAND_SPECS = [
31662
31808
  returns: "DoccleStatus",
31663
31809
  notes: "PATCH /api/v1/documents/doccle with { archiveAfterImport }."
31664
31810
  },
31811
+ {
31812
+ path: ["documents", "ask"],
31813
+ summary: "Ask the papers a question (doc_ask): the passages that answer, best first, each with its paper, file and page.",
31814
+ args: [
31815
+ {
31816
+ name: "question",
31817
+ required: true,
31818
+ description: '"Is water damage from a burst pipe covered?"'
31819
+ }
31820
+ ],
31821
+ flags: [
31822
+ { name: "document", type: "string", description: "Ask this paper only (document id)." },
31823
+ {
31824
+ name: "limit",
31825
+ type: "string",
31826
+ description: "How many passages at most (default 5, up to 20)."
31827
+ }
31828
+ ],
31829
+ scopes: ["documents:read"],
31830
+ returns: "DocumentAnswer",
31831
+ notes: "POST /api/v1/documents/ask with { question, documentId?, limit? }. Reads the papers' key fields and their files' text (a page per form feed). do writes no prose: word the answer from the passages, quote the pages, and say it is not legal advice. `withoutText` names the papers with no file text to read. An Only me paper answers only its owner's key with documents:private."
31832
+ },
31833
+ {
31834
+ path: ["documents", "search"],
31835
+ summary: "Search the papers' words (key fields and file text), a passage per hit.",
31836
+ args: [{ name: "words", required: true, description: "The words to find." }],
31837
+ flags: [
31838
+ { name: "document", type: "string", description: "Only this paper (document id)." },
31839
+ {
31840
+ name: "limit",
31841
+ type: "string",
31842
+ description: "How many hits at most (default 20, up to 50)."
31843
+ }
31844
+ ],
31845
+ scopes: ["documents:read"],
31846
+ returns: "{ q, hits: DocumentPassage[] }",
31847
+ notes: "GET /api/v1/documents/search?q=&documentId=&limit=."
31848
+ },
31665
31849
  {
31666
31850
  path: ["documents", "unmatched"],
31667
31851
  summary: "List the papers that ask for money (an amount due) and have no payment linked yet, oldest due first.",
@@ -33977,6 +34161,24 @@ var COMMAND_SPECS = [
33977
34161
  returns: "RunChangesResult",
33978
34162
  notes: "POST /api/v1/runs/{id}/checklists/{key}/tick. `do runs dex tick <run> 495 496 497`, `do runs dex tick <run> --bulk caught.txt` (up to 5000 ids). A dex the run doesn't have yet is made from the Pok\xE9mon pack's national dex."
33979
34163
  },
34164
+ {
34165
+ path: ["runs", "steam", "status"],
34166
+ summary: "Whether you've linked Steam, how many games have a Steam app id, and the last sync.",
34167
+ args: [],
34168
+ flags: [],
34169
+ scopes: ["collections:read"],
34170
+ returns: "SteamAccountStatus",
34171
+ notes: "GET /api/v1/runs/steam. Steam is linked in the app's Settings; the Steam ID and Web API key are never returned. A game takes part once its `steamAppId` is set."
34172
+ },
34173
+ {
34174
+ path: ["runs", "steam", "sync"],
34175
+ summary: "Sync your Steam achievements into your runs now, as the daily sync does.",
34176
+ args: [],
34177
+ flags: [{ name: "game", type: "string", description: "Only this game item ULID." }],
34178
+ scopes: ["collections:write"],
34179
+ returns: "SteamSyncResult",
34180
+ notes: "POST /api/v1/runs/steam/sync. Writes into each run whose achievements come from Steam or aren't kept yet; runs kept by hand are left alone. Per game: outcome, runs, unlocked, total and the error (unauthorized, private, no_stats, unavailable, bad_response). 409 before Steam is linked."
34181
+ },
33980
34182
  {
33981
34183
  path: ["runs", "sessions", "list"],
33982
34184
  summary: "A run's sessions, newest first, with recaps and change batches.",
@@ -34323,18 +34525,23 @@ var COMMAND_SPECS = [
34323
34525
  },
34324
34526
  {
34325
34527
  path: ["guest-lists", "export"],
34326
- summary: "Export for the caterer (CSV), the venue (CSV) or the floor plan (PDF) to stdout.",
34528
+ summary: "Export for the caterer (CSV) or the venue (CSV) to stdout, or save the floor plan (PDF) to a file.",
34327
34529
  args: [{ name: "id", required: true, description: "The guest list's id." }],
34328
34530
  flags: [
34329
34531
  {
34330
34532
  name: "kind",
34331
34533
  type: "string",
34332
34534
  description: "caterer (meals and diets per table), venue (who sits where) or floor-plan (PDF)."
34535
+ },
34536
+ {
34537
+ name: "out",
34538
+ type: "string",
34539
+ description: "Where to save the floor plan (default: the name the API gives it)."
34333
34540
  }
34334
34541
  ],
34335
34542
  scopes: ["contacts:read"],
34336
34543
  returns: "string",
34337
- notes: "Redirect to a file: `do guest-lists export <id> --kind floor-plan > plan.pdf`."
34544
+ notes: "A CSV goes to stdout (`> tables.csv`); the floor plan is saved: `do guest-lists export <id> --kind floor-plan --out plan.pdf`."
34338
34545
  },
34339
34546
  {
34340
34547
  path: ["rsvp-links", "list"],
@@ -37439,6 +37646,32 @@ var HANDLERS = {
37439
37646
  render: renderRecord
37440
37647
  };
37441
37648
  },
37649
+ "documents ask": async ({ args, flags, requireClient }) => {
37650
+ const question = args.join(" ").trim();
37651
+ if (!question)
37652
+ throw usageError('documents ask needs a question ("Is water damage covered?")');
37653
+ const limit = flagString(flags, "limit");
37654
+ const body = Object.fromEntries(Object.entries({
37655
+ question,
37656
+ documentId: flagString(flags, "document"),
37657
+ limit: limit === undefined ? undefined : Number(limit)
37658
+ }).filter(([, value]) => value !== undefined));
37659
+ return { data: await requireClient().post("/documents/ask", body), render: renderRecord };
37660
+ },
37661
+ "documents search": async ({ args, flags, requireClient }) => {
37662
+ const q = args.join(" ").trim();
37663
+ if (!q)
37664
+ throw usageError("documents search needs the words to find");
37665
+ const query = Object.fromEntries(Object.entries({
37666
+ q,
37667
+ documentId: flagString(flags, "document"),
37668
+ limit: flagString(flags, "limit")
37669
+ }).filter(([, value]) => value !== undefined));
37670
+ return {
37671
+ data: await requireClient().get("/documents/search", { query }),
37672
+ render: renderRecord
37673
+ };
37674
+ },
37442
37675
  "documents unmatched": async ({ requireClient }) => ({
37443
37676
  data: await requireClient().get("/documents/unmatched"),
37444
37677
  render: renderList
@@ -39073,6 +39306,16 @@ var HANDLERS = {
39073
39306
  render: renderRecord
39074
39307
  };
39075
39308
  },
39309
+ "runs steam status": async ({ requireClient }) => ({
39310
+ data: await requireClient().get("/runs/steam"),
39311
+ render: renderRecord
39312
+ }),
39313
+ "runs steam sync": async ({ flags, requireClient }) => {
39314
+ const body = parseInput(steamSyncInputSchema, {
39315
+ ...typeof flags.game === "string" ? { gameId: flags.game } : {}
39316
+ });
39317
+ return { data: await requireClient().post("/runs/steam/sync", body), render: renderRecord };
39318
+ },
39076
39319
  "runs sessions list": async ({ args, requireClient }) => {
39077
39320
  const id = requireArg(args, 0, "run id");
39078
39321
  return { data: await requireClient().get(`/runs/${id}/sessions`), render: renderList };
@@ -39580,7 +39823,17 @@ var HANDLERS = {
39580
39823
  "guest-lists export": async ({ args, flags, requireClient }) => {
39581
39824
  const id = requireArg(args, 0, "guest list id");
39582
39825
  const kind = parseInput(guestExportKindSchema, flagString(flags, "kind") ?? "venue");
39583
- const raw = await requireClient().getText(`/guest-lists/${id}/exports/${kind}`);
39826
+ const path = `/guest-lists/${id}/exports/${kind}`;
39827
+ if (kind === "floor-plan") {
39828
+ const file = await requireClient().getBytes(path);
39829
+ const out = flagString(flags, "out") ?? basename2(file.name ?? "floor-plan.pdf");
39830
+ writeFileSync2(out, file.bytes);
39831
+ return {
39832
+ data: { id, kind, saved: out, size: file.bytes.byteLength, type: file.contentType },
39833
+ render: renderRecord
39834
+ };
39835
+ }
39836
+ const raw = await requireClient().getText(path);
39584
39837
  return { raw, data: undefined, render: () => raw };
39585
39838
  },
39586
39839
  "rsvp-links list": async ({ flags, requireClient }) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@robbeverhelst/do",
3
- "version": "1.293.0",
3
+ "version": "1.295.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",