@robbeverhelst/do 1.350.0 → 1.352.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 +193 -24
  2. package/package.json +8 -2
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.350.0";
14423
+ var VERSION = "1.352.0";
14424
14424
  var API_PREFIX = "/api/v1";
14425
14425
  var DEFAULT_API_URL = "http://localhost:3001";
14426
14426
 
@@ -14722,8 +14722,8 @@ class DoClient {
14722
14722
  put(path, body) {
14723
14723
  return this.request("PUT", path, { body });
14724
14724
  }
14725
- delete(path) {
14726
- return this.request("DELETE", path, {});
14725
+ delete(path, opts = {}) {
14726
+ return this.request("DELETE", path, opts);
14727
14727
  }
14728
14728
  upload(path, form) {
14729
14729
  return this.request("POST", path, { form });
@@ -17650,6 +17650,7 @@ var tenants = pgTable("tenants", {
17650
17650
  name: text("name").notNull(),
17651
17651
  backdrop: text("backdrop"),
17652
17652
  gaardHouseUrl: text("gaard_house_url"),
17653
+ address: text("address"),
17653
17654
  awayFrom: date5("away_from", { mode: "string" }),
17654
17655
  awayUntil: date5("away_until", { mode: "string" }),
17655
17656
  lastTaskNumber: integer2("last_task_number").notNull().default(0),
@@ -18455,6 +18456,7 @@ var contacts = pgTable("contacts", {
18455
18456
  website: text("website"),
18456
18457
  notes: text("notes"),
18457
18458
  tags: text("tags").array().notNull().default([]),
18459
+ knowsAbout: text("knows_about").array().notNull().default([]),
18458
18460
  lastContactedAt: timestamp("last_contacted_at", { withTimezone: true }),
18459
18461
  keepInTouchRuleId: text("keep_in_touch_rule_id").references(() => recurrenceRules.id),
18460
18462
  rhythmDays: integer2("rhythm_days"),
@@ -19475,7 +19477,8 @@ var oauthIdentitySchema = createSelectSchema(oauthIdentities, {
19475
19477
  var spaceSchema = createSelectSchema(tenants, {
19476
19478
  createdAt: exports_coerce.date(),
19477
19479
  updatedAt: exports_coerce.date(),
19478
- deletedAt: exports_coerce.date().nullable()
19480
+ deletedAt: exports_coerce.date().nullable(),
19481
+ address: string2().nullable().default(null)
19479
19482
  }).omit({
19480
19483
  gaardHouseUrl: true,
19481
19484
  awayFrom: true,
@@ -19484,12 +19487,14 @@ var spaceSchema = createSelectSchema(tenants, {
19484
19487
  lastProjectNumber: true
19485
19488
  });
19486
19489
  var backdropIdSchema = string2().trim().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, "a backdrop id is lowercase words joined by dashes").max(40);
19490
+ var spaceAddressSchema = string2().trim().max(200).transform((line) => line || null).nullable();
19487
19491
  var updateSpaceInputSchema = object({
19488
19492
  name: string2().trim().min(1).max(120).optional(),
19489
- backdrop: backdropIdSchema.nullable().optional()
19490
- }).strict().refine((input) => input.name !== undefined || input.backdrop !== undefined, {
19491
- message: "nothing to update"
19492
- });
19493
+ backdrop: backdropIdSchema.nullable().optional(),
19494
+ address: spaceAddressSchema.optional()
19495
+ }).strict().refine((input) => input.name !== undefined || input.backdrop !== undefined || input.address !== undefined, { message: "nothing to update" });
19496
+ var setSpaceAddressInputSchema = object({ address: spaceAddressSchema }).strict();
19497
+ var spaceAddressViewSchema = object({ address: string2().nullable() });
19493
19498
  var onboardingResultSchema = object({ onboardingCompleted: boolean2() });
19494
19499
  var authMethodsSchema = object({
19495
19500
  hasPassword: boolean2(),
@@ -21010,6 +21015,12 @@ var animalArrivedInputSchema = object({
21010
21015
  }).strict();
21011
21016
 
21012
21017
  // ../../packages/schema/src/operations/crud.ts
21018
+ var DELETE_REASON_QUERY = [
21019
+ {
21020
+ name: "reason",
21021
+ description: `An Agent's one line on why (first line, up to 280 characters); the Trash shows it as "Deleted by <agent>: <reason>". Ignored for a member's key.`
21022
+ }
21023
+ ];
21013
21024
  function crudOperations(r) {
21014
21025
  const base = `/${r.segment}`;
21015
21026
  const one = `/${r.segment}/{id}`;
@@ -21072,6 +21083,7 @@ function crudOperations(r) {
21072
21083
  tag: r.tag,
21073
21084
  summary: `Delete a ${r.noun}`,
21074
21085
  description: `Delete a ${r.noun}; fires the \`${event}.deleted\` webhook.`,
21086
+ query: DELETE_REASON_QUERY,
21075
21087
  status: 204,
21076
21088
  response: { description: "Deleted." },
21077
21089
  errors: { 404: true },
@@ -21551,6 +21563,7 @@ var habitPauseSchema = object({
21551
21563
  var habitTodaySchema = object({
21552
21564
  due: boolean2(),
21553
21565
  done: boolean2(),
21566
+ resting: boolean2().optional(),
21554
21567
  week: object({ done: number2().int().nonnegative(), target: number2().int().positive() }).optional()
21555
21568
  });
21556
21569
  var habitSummarySchema = habitSchema.extend({
@@ -25643,7 +25656,8 @@ var contactSchema = createSelectSchema(contacts, {
25643
25656
  userId: string2().nullable().default(null),
25644
25657
  rhythmDays: number2().int().nullable().default(null),
25645
25658
  rhythmSnoozedUntil: string2().nullable().default(null),
25646
- emailInvalidAt: exports_coerce.date().nullable().default(null)
25659
+ emailInvalidAt: exports_coerce.date().nullable().default(null),
25660
+ knowsAbout: array(string2()).default([])
25647
25661
  });
25648
25662
  var contactImportantDateSchema = object({
25649
25663
  id: ulidSchema,
@@ -25676,6 +25690,18 @@ var contactImportantDateInputSchema = preprocess((v) => {
25676
25690
  eventDate: new Date(Date.UTC(YEARLESS_YEAR, d.eventDate.getUTCMonth(), d.eventDate.getUTCDate()))
25677
25691
  } : d));
25678
25692
  var websiteSchema = string2().trim().url().max(500).refine((v) => /^https?:\/\//i.test(v), "must start with http:// or https://");
25693
+ var KNOWS_ABOUT_PHRASE_MAX = 80;
25694
+ var KNOWS_ABOUT_MAX = 30;
25695
+ var knowsAboutSchema = array(string2().trim().max(KNOWS_ABOUT_PHRASE_MAX)).max(KNOWS_ABOUT_MAX).transform((phrases) => {
25696
+ const seen = new Set;
25697
+ return phrases.filter((phrase) => {
25698
+ const key = phrase.toLowerCase();
25699
+ if (!phrase || seen.has(key))
25700
+ return false;
25701
+ seen.add(key);
25702
+ return true;
25703
+ });
25704
+ });
25679
25705
  var createContactInputSchema = createInsertSchema(contacts, {
25680
25706
  id: ulidSchema,
25681
25707
  email: string2().email().nullish(),
@@ -25684,6 +25710,7 @@ var createContactInputSchema = createInsertSchema(contacts, {
25684
25710
  website: websiteSchema.nullish(),
25685
25711
  notes: string2().nullish(),
25686
25712
  tags: array(string2()).optional(),
25713
+ knowsAbout: knowsAboutSchema.optional(),
25687
25714
  lastContactedAt: exports_coerce.date().nullish(),
25688
25715
  rhythmDays: contactPeopleInputShape.rhythmDays,
25689
25716
  rhythmSnoozedUntil: contactPeopleInputShape.rhythmSnoozedUntil
@@ -25701,6 +25728,7 @@ var updateContactInputSchema = createUpdateSchema(contacts, {
25701
25728
  website: websiteSchema.nullish(),
25702
25729
  notes: string2().nullish(),
25703
25730
  tags: array(string2()).optional(),
25731
+ knowsAbout: knowsAboutSchema.optional(),
25704
25732
  lastContactedAt: exports_coerce.date().nullish(),
25705
25733
  rhythmDays: contactPeopleInputShape.rhythmDays,
25706
25734
  rhythmSnoozedUntil: contactPeopleInputShape.rhythmSnoozedUntil
@@ -37003,7 +37031,13 @@ var automationRunSummarySchema = object({
37003
37031
  });
37004
37032
  var automationListItemSchema = automationViewSchema.extend({
37005
37033
  madeBy: object({ userId: string2(), name: string2(), you: boolean2() }).nullable(),
37006
- lastRun: automationRunSummarySchema.nullable()
37034
+ lastRun: automationRunSummarySchema.nullable(),
37035
+ needs: object({
37036
+ connectionId: string2(),
37037
+ provider: string2(),
37038
+ title: string2(),
37039
+ reconnect: boolean2()
37040
+ }).nullable().default(null)
37007
37041
  });
37008
37042
  var automationRunNowSchema = object({ queued: literal(true) });
37009
37043
 
@@ -39839,6 +39873,7 @@ var shareLinkSchema = createSelectSchema(shareLinks, {
39839
39873
  updatedAt: exports_coerce.date()
39840
39874
  });
39841
39875
  var shareLinkPublicSchema = shareLinkSchema.omit({ tokenHash: true });
39876
+ var shareLinkListedSchema = shareLinkPublicSchema.extend({ token: string2().nullable() });
39842
39877
  var createShareLinkInputSchema = createInsertSchema(shareLinks, {
39843
39878
  id: ulidSchema,
39844
39879
  nodeId: ulidSchema,
@@ -40086,6 +40121,32 @@ var shoppingListOperations = defineOperations({
40086
40121
  })
40087
40122
  });
40088
40123
 
40124
+ // ../../packages/schema/src/operations/space.ts
40125
+ var spaceOperations = defineOperations({
40126
+ address: {
40127
+ method: "get",
40128
+ path: "/space/address",
40129
+ scopes: ["settings:read"],
40130
+ tag: "Space",
40131
+ summary: "Get the Space's address",
40132
+ description: "The household's postal address as `{ address }`: one line, or null when none is set.",
40133
+ status: 200,
40134
+ response: { description: "The Space's address." }
40135
+ },
40136
+ setAddress: {
40137
+ method: "put",
40138
+ path: "/space/address",
40139
+ scopes: ["settings:write"],
40140
+ tag: "Space",
40141
+ summary: "Set the Space's address",
40142
+ description: "Set the household's postal address to one line (trimmed, at most 200 characters); `null` or a blank line clears it. Returns `{ address }`.",
40143
+ body: setSpaceAddressInputSchema,
40144
+ status: 200,
40145
+ response: { description: "The Space's address now." },
40146
+ errors: { 400: true }
40147
+ }
40148
+ });
40149
+
40089
40150
  // ../../packages/schema/src/db/tap-tags.ts
40090
40151
  var tapTagKind = pgEnum("tap_tag_kind", ["habit", "routine"]);
40091
40152
  var tapTags = pgTable("tap_tags", {
@@ -40502,6 +40563,7 @@ var taskOperations = defineOperations({
40502
40563
  tag: "Tasks",
40503
40564
  summary: "Delete a task",
40504
40565
  description: "Delete a task; fires the `task.deleted` webhook.",
40566
+ query: DELETE_REASON_QUERY,
40505
40567
  status: 204,
40506
40568
  response: { description: "Deleted." },
40507
40569
  errors: { 404: true },
@@ -46807,6 +46869,22 @@ function renderKraken(data, mode) {
46807
46869
  }
46808
46870
  var commands11 = pairCommands(CONNECTION_COMMAND_SPECS, CONNECTION_HANDLERS);
46809
46871
 
46872
+ // ../../packages/domain/src/knows-about.ts
46873
+ var same = (a, b) => a.trim().toLowerCase() === b.trim().toLowerCase();
46874
+ function knowsAboutHas(list, phrase) {
46875
+ return list.some((p) => same(p, phrase));
46876
+ }
46877
+ function canAddKnowsAbout(list, draft) {
46878
+ const phrase = draft.trim();
46879
+ return phrase.length > 0 && phrase.length <= KNOWS_ABOUT_PHRASE_MAX && list.length < KNOWS_ABOUT_MAX && !knowsAboutHas(list, phrase);
46880
+ }
46881
+ function addKnowsAbout(list, draft) {
46882
+ return canAddKnowsAbout(list, draft) ? [...list, draft.trim()] : [...list];
46883
+ }
46884
+ function removeKnowsAbout(list, phrase) {
46885
+ return list.filter((p) => !same(p, phrase));
46886
+ }
46887
+
46810
46888
  // src/commands/contacts.ts
46811
46889
  var FIELD_FLAGS = [
46812
46890
  { name: "name", type: "string", description: "The display name (or pass it as the argument)." },
@@ -46836,6 +46914,21 @@ var FIELD_FLAGS = [
46836
46914
  description: "The circle ids they are in, comma-separated (replaces the membership)."
46837
46915
  },
46838
46916
  { name: "tags", type: "string", description: "Tags, comma-separated (replaces the tags)." },
46917
+ {
46918
+ name: "knows",
46919
+ type: "string",
46920
+ description: "What they know about, the go-to for, comma-separated (replaces the list; none clears it)."
46921
+ },
46922
+ {
46923
+ name: "knows-add",
46924
+ type: "string",
46925
+ description: `One more thing they know about ("the boat's engine"); a repeat is skipped.`
46926
+ },
46927
+ {
46928
+ name: "knows-remove",
46929
+ type: "string",
46930
+ description: "Take one thing off what they know about (ignoring case)."
46931
+ },
46839
46932
  { name: "notes", type: "string", description: "Long-form notes." },
46840
46933
  {
46841
46934
  name: "rhythm",
@@ -46861,10 +46954,10 @@ var CONTACT_COMMAND_SPECS = [
46861
46954
  flags: FIELD_FLAGS,
46862
46955
  scopes: [...contactOperations.update.scopes],
46863
46956
  returns: "ContactView",
46864
- notes: "Only the flags you pass change. `none` clears a field (--email none, --birthday none). --birthday keeps the contact's other dates; --roles, --circles and --tags replace the list (a role it already has keeps its details)."
46957
+ notes: "Only the flags you pass change. `none` clears a field (--email none, --birthday none). --birthday keeps the contact's other dates; --roles, --circles, --tags and --knows replace the list (a role it already has keeps its details); --knows-add and --knows-remove change one phrase of what they know about."
46865
46958
  }
46866
46959
  ];
46867
- var MERGING_FLAGS = ["birthday", "no-year", "roles"];
46960
+ var MERGING_FLAGS = ["birthday", "no-year", "roles", "knows-add", "knows-remove"];
46868
46961
  var NULLABLE = ["email", "phone", "company", "website", "notes"];
46869
46962
  function list2(value) {
46870
46963
  return value.split(",").map((v) => v.trim()).filter((v) => v.length > 0);
@@ -46899,6 +46992,19 @@ function contactBodyFromFlags(flags, base, op, current) {
46899
46992
  const tags = flagString(flags, "tags");
46900
46993
  if (tags !== undefined)
46901
46994
  body.tags = isNone(tags) ? [] : list2(tags);
46995
+ const knows = flagString(flags, "knows");
46996
+ if (knows !== undefined)
46997
+ body.knowsAbout = isNone(knows) ? [] : list2(knows);
46998
+ const knowsAdd = flagString(flags, "knows-add");
46999
+ const knowsRemove = flagString(flags, "knows-remove");
47000
+ if (knowsAdd !== undefined || knowsRemove !== undefined) {
47001
+ let phrases = body.knowsAbout ?? current?.knowsAbout ?? [];
47002
+ if (knowsRemove !== undefined)
47003
+ phrases = removeKnowsAbout(phrases, knowsRemove);
47004
+ if (knowsAdd !== undefined)
47005
+ phrases = addKnowsAbout(phrases, knowsAdd);
47006
+ body.knowsAbout = phrases;
47007
+ }
46902
47008
  const circles = flagString(flags, "circles");
46903
47009
  if (circles !== undefined)
46904
47010
  body.circleIds = isNone(circles) ? [] : list2(circles);
@@ -52346,6 +52452,11 @@ var GLOBAL_FLAGS = [
52346
52452
  type: "boolean",
52347
52453
  description: "Permit a destructive verb (delete/revoke/remove-member). Off by default \u2014 a guardrail for autonomous agents."
52348
52454
  },
52455
+ {
52456
+ name: "reason",
52457
+ type: "string",
52458
+ description: `One line on why, for delete/archive (sent as ?reason=). An agent's shows in the Trash: "Deleted by <agent>: <reason>".`
52459
+ },
52349
52460
  {
52350
52461
  name: "dry-run",
52351
52462
  type: "boolean",
@@ -57503,7 +57614,7 @@ var commands52 = [
57503
57614
  ],
57504
57615
  scopes: [...shareLinkOperations.create.scopes],
57505
57616
  returns: "CreateShareLinkResult",
57506
- notes: "The signed token is returned once, in the create response."
57617
+ notes: "The signed token isn't shown once: `do link list <node>` gives it again until the link expires or is revoked."
57507
57618
  },
57508
57619
  run: async ({ args, flags, requireClient }) => {
57509
57620
  const node = requireArg(args, 0, "node id");
@@ -57526,7 +57637,7 @@ var commands52 = [
57526
57637
  args: [{ name: "node", required: true, description: "Node ULID." }],
57527
57638
  flags: [],
57528
57639
  scopes: [...shareLinkOperations.listForNode.scopes],
57529
- returns: "ShareLinkPublic"
57640
+ returns: "ShareLinkListed"
57530
57641
  },
57531
57642
  run: readOperation(shareLinkOperations.listForNode, renderList, { nodeId: "node id" })
57532
57643
  },
@@ -57551,8 +57662,64 @@ var commands52 = [
57551
57662
  }
57552
57663
  ];
57553
57664
 
57554
- // src/commands/tap-tags.ts
57665
+ // src/commands/space.ts
57555
57666
  var commands53 = [
57667
+ {
57668
+ spec: {
57669
+ path: ["space", "address"],
57670
+ summary: "Show the Space's postal address (null when none is set).",
57671
+ args: [],
57672
+ flags: [],
57673
+ scopes: [...spaceOperations.address.scopes],
57674
+ returns: "SpaceAddress",
57675
+ notes: `${routeOf(spaceOperations.address)}.`
57676
+ },
57677
+ run: readOperation(spaceOperations.address, renderRecord)
57678
+ },
57679
+ {
57680
+ spec: {
57681
+ path: ["space", "address", "set"],
57682
+ summary: "Set the Space's postal address to one line.",
57683
+ args: [
57684
+ {
57685
+ name: "address",
57686
+ required: true,
57687
+ description: 'One line, e.g. "Main Street 12, Springfield".'
57688
+ }
57689
+ ],
57690
+ flags: [],
57691
+ scopes: [...spaceOperations.setAddress.scopes],
57692
+ returns: "SpaceAddress",
57693
+ notes: `${routeOf(spaceOperations.setAddress)}. Trimmed, at most 200 characters.`
57694
+ },
57695
+ run: async ({ args, requireClient }) => {
57696
+ requireArg(args, 0, "address");
57697
+ const body = parseInput(setSpaceAddressInputSchema, { address: args.join(" ") });
57698
+ return {
57699
+ data: await requireClient().put(pathOf(spaceOperations.setAddress), body),
57700
+ render: renderRecord
57701
+ };
57702
+ }
57703
+ },
57704
+ {
57705
+ spec: {
57706
+ path: ["space", "address", "clear"],
57707
+ summary: "Clear the Space's postal address.",
57708
+ args: [],
57709
+ flags: [],
57710
+ scopes: [...spaceOperations.setAddress.scopes],
57711
+ returns: "SpaceAddress",
57712
+ notes: `${routeOf(spaceOperations.setAddress)} with \`{ "address": null }\`.`
57713
+ },
57714
+ run: async ({ requireClient }) => ({
57715
+ data: await requireClient().put(pathOf(spaceOperations.setAddress), { address: null }),
57716
+ render: renderRecord
57717
+ })
57718
+ }
57719
+ ];
57720
+
57721
+ // src/commands/tap-tags.ts
57722
+ var commands54 = [
57556
57723
  {
57557
57724
  spec: {
57558
57725
  path: ["tap-tags", "tap"],
@@ -57580,7 +57747,7 @@ var BY = {
57580
57747
  type: "string",
57581
57748
  description: "The blocking task's ref (DO-147) or ULID."
57582
57749
  };
57583
- var commands54 = [
57750
+ var commands55 = [
57584
57751
  defineCommand({
57585
57752
  operation: taskBlockOperations.addBlocker,
57586
57753
  path: ["tasks", "block"],
@@ -57646,7 +57813,7 @@ function renderSeries(data, mode) {
57646
57813
  }).join(`
57647
57814
  `);
57648
57815
  }
57649
- var commands55 = [
57816
+ var commands56 = [
57650
57817
  defineCommand({
57651
57818
  operation: taskSeriesOperations.make,
57652
57819
  path: ["tasks", "make-series"],
@@ -57801,7 +57968,7 @@ function repeatFromFlags(flags) {
57801
57968
  out.anchor = "from_completion";
57802
57969
  return out;
57803
57970
  }
57804
- var commands56 = [
57971
+ var commands57 = [
57805
57972
  {
57806
57973
  spec: {
57807
57974
  path: ["capture"],
@@ -58259,7 +58426,7 @@ var commands56 = [
58259
58426
  ];
58260
58427
 
58261
58428
  // src/commands/time-blocks.ts
58262
- var commands57 = [
58429
+ var commands58 = [
58263
58430
  {
58264
58431
  spec: {
58265
58432
  path: ["time-blocks", "record"],
@@ -58440,7 +58607,7 @@ function renderLandedCounts(data, mode) {
58440
58607
  return out.join(`
58441
58608
  `);
58442
58609
  }
58443
- var commands58 = [
58610
+ var commands59 = [
58444
58611
  {
58445
58612
  spec: {
58446
58613
  path: ["today"],
@@ -58812,7 +58979,7 @@ function renderViews(data, mode) {
58812
58979
  function renderView(data, mode) {
58813
58980
  return renderViews([data], mode);
58814
58981
  }
58815
- var commands59 = [
58982
+ var commands60 = [
58816
58983
  defineCommand({
58817
58984
  operation: workViewOperations.list,
58818
58985
  path: ["views", "list"],
@@ -58931,7 +59098,7 @@ var commands59 = [
58931
59098
  ];
58932
59099
 
58933
59100
  // src/commands/worktree-links.ts
58934
- var commands60 = [
59101
+ var commands61 = [
58935
59102
  {
58936
59103
  spec: {
58937
59104
  path: ["worktree-links", "list"],
@@ -59097,7 +59264,8 @@ var FEATURE_COMMANDS = [
59097
59264
  ...commands57,
59098
59265
  ...commands58,
59099
59266
  ...commands59,
59100
- ...commands60
59267
+ ...commands60,
59268
+ ...commands61
59101
59269
  ];
59102
59270
 
59103
59271
  // src/registry.ts
@@ -59290,7 +59458,8 @@ async function dispatchEntity(entity, rest, flags, requireClient) {
59290
59458
  }
59291
59459
  if (op === "delete")
59292
59460
  assertDestructiveAllowed(flags, `delete ${entity.name} ${id}`);
59293
- await client.delete(`${entity.path}/${id}`);
59461
+ const reason = flagString(flags, "reason");
59462
+ await client.delete(`${entity.path}/${id}`, reason ? { query: { reason } } : {});
59294
59463
  return {
59295
59464
  data: op === "archive" ? { ok: true, archived: id, softDelete: true } : { ok: true, deleted: id, softDelete: true },
59296
59465
  render: renderRecord
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@robbeverhelst/do",
3
- "version": "1.350.0",
3
+ "version": "1.352.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",
@@ -27,7 +27,7 @@
27
27
  "compile": "bun build --compile src/index.ts --outfile do",
28
28
  "prepublishOnly": "bun run bundle",
29
29
  "typecheck": "tsc --noEmit",
30
- "build": "tsc --noEmit",
30
+ "build": "bun run bundle",
31
31
  "test": "bun test",
32
32
  "test:coverage": "bun test --coverage"
33
33
  },
@@ -39,5 +39,11 @@
39
39
  "@types/node": "^25.9.3",
40
40
  "ulidx": "^2.4.1",
41
41
  "zod": "^4.4.3"
42
+ },
43
+ "do": {
44
+ "tier": "backend",
45
+ "coverage": {
46
+ "floor": 90
47
+ }
42
48
  }
43
49
  }