@robbeverhelst/do 1.351.0 → 1.353.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 +235 -27
  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.351.0";
14423
+ var VERSION = "1.353.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(),
@@ -20514,7 +20519,11 @@ var animalViewSchema = animalSchema.extend({
20514
20519
  updatedAt: exports_coerce.date()
20515
20520
  });
20516
20521
  var nodeRefSchema = object({ id: ulidSchema, title: string2() });
20517
- var animalHabitSchema = nodeRefSchema.extend({ doneToday: boolean2() });
20522
+ var animalHabitSchema = nodeRefSchema.extend({
20523
+ doneToday: boolean2(),
20524
+ timeOfDay: string2().nullable().optional(),
20525
+ routine: string2().nullable().optional()
20526
+ });
20518
20527
  var animalSupplySchema = nodeRefSchema.extend({
20519
20528
  quantity: number2(),
20520
20529
  unit: string2().nullable(),
@@ -21010,6 +21019,12 @@ var animalArrivedInputSchema = object({
21010
21019
  }).strict();
21011
21020
 
21012
21021
  // ../../packages/schema/src/operations/crud.ts
21022
+ var DELETE_REASON_QUERY = [
21023
+ {
21024
+ name: "reason",
21025
+ 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.`
21026
+ }
21027
+ ];
21013
21028
  function crudOperations(r) {
21014
21029
  const base = `/${r.segment}`;
21015
21030
  const one = `/${r.segment}/{id}`;
@@ -21072,6 +21087,7 @@ function crudOperations(r) {
21072
21087
  tag: r.tag,
21073
21088
  summary: `Delete a ${r.noun}`,
21074
21089
  description: `Delete a ${r.noun}; fires the \`${event}.deleted\` webhook.`,
21090
+ query: DELETE_REASON_QUERY,
21075
21091
  status: 204,
21076
21092
  response: { description: "Deleted." },
21077
21093
  errors: { 404: true },
@@ -22761,11 +22777,13 @@ var routineRunStepSchema = createSelectSchema(routineRunSteps, {
22761
22777
  });
22762
22778
  var routineRunStepViewSchema = routineRunStepSchema.extend({
22763
22779
  habit: habitSummarySchema.nullable().default(null),
22780
+ childKind: routineKindSchema.nullable().default(null),
22764
22781
  task: object({
22765
22782
  id: string2(),
22766
22783
  title: string2(),
22767
22784
  status: string2(),
22768
- dueAt: exports_coerce.date().nullable()
22785
+ dueAt: exports_coerce.date().nullable(),
22786
+ ref: string2().nullable().default(null)
22769
22787
  }).nullable().default(null)
22770
22788
  });
22771
22789
  var routineRunViewSchema = routineRunSchema.extend({
@@ -25644,7 +25662,8 @@ var contactSchema = createSelectSchema(contacts, {
25644
25662
  userId: string2().nullable().default(null),
25645
25663
  rhythmDays: number2().int().nullable().default(null),
25646
25664
  rhythmSnoozedUntil: string2().nullable().default(null),
25647
- emailInvalidAt: exports_coerce.date().nullable().default(null)
25665
+ emailInvalidAt: exports_coerce.date().nullable().default(null),
25666
+ knowsAbout: array(string2()).default([])
25648
25667
  });
25649
25668
  var contactImportantDateSchema = object({
25650
25669
  id: ulidSchema,
@@ -25677,6 +25696,18 @@ var contactImportantDateInputSchema = preprocess((v) => {
25677
25696
  eventDate: new Date(Date.UTC(YEARLESS_YEAR, d.eventDate.getUTCMonth(), d.eventDate.getUTCDate()))
25678
25697
  } : d));
25679
25698
  var websiteSchema = string2().trim().url().max(500).refine((v) => /^https?:\/\//i.test(v), "must start with http:// or https://");
25699
+ var KNOWS_ABOUT_PHRASE_MAX = 80;
25700
+ var KNOWS_ABOUT_MAX = 30;
25701
+ var knowsAboutSchema = array(string2().trim().max(KNOWS_ABOUT_PHRASE_MAX)).max(KNOWS_ABOUT_MAX).transform((phrases) => {
25702
+ const seen = new Set;
25703
+ return phrases.filter((phrase) => {
25704
+ const key = phrase.toLowerCase();
25705
+ if (!phrase || seen.has(key))
25706
+ return false;
25707
+ seen.add(key);
25708
+ return true;
25709
+ });
25710
+ });
25680
25711
  var createContactInputSchema = createInsertSchema(contacts, {
25681
25712
  id: ulidSchema,
25682
25713
  email: string2().email().nullish(),
@@ -25685,6 +25716,7 @@ var createContactInputSchema = createInsertSchema(contacts, {
25685
25716
  website: websiteSchema.nullish(),
25686
25717
  notes: string2().nullish(),
25687
25718
  tags: array(string2()).optional(),
25719
+ knowsAbout: knowsAboutSchema.optional(),
25688
25720
  lastContactedAt: exports_coerce.date().nullish(),
25689
25721
  rhythmDays: contactPeopleInputShape.rhythmDays,
25690
25722
  rhythmSnoozedUntil: contactPeopleInputShape.rhythmSnoozedUntil
@@ -25702,6 +25734,7 @@ var updateContactInputSchema = createUpdateSchema(contacts, {
25702
25734
  website: websiteSchema.nullish(),
25703
25735
  notes: string2().nullish(),
25704
25736
  tags: array(string2()).optional(),
25737
+ knowsAbout: knowsAboutSchema.optional(),
25705
25738
  lastContactedAt: exports_coerce.date().nullish(),
25706
25739
  rhythmDays: contactPeopleInputShape.rhythmDays,
25707
25740
  rhythmSnoozedUntil: contactPeopleInputShape.rhythmSnoozedUntil
@@ -35935,6 +35968,8 @@ var agentSessionSteps = pgTable("agent_session_steps", {
35935
35968
  detail: text("detail"),
35936
35969
  file: text("file"),
35937
35970
  change: text("change"),
35971
+ linesAdded: integer2("lines_added"),
35972
+ linesRemoved: integer2("lines_removed"),
35938
35973
  outcome: text("outcome"),
35939
35974
  url: text("url"),
35940
35975
  at: timestamp("at", { withTimezone: true }).notNull().defaultNow(),
@@ -35943,6 +35978,7 @@ var agentSessionSteps = pgTable("agent_session_steps", {
35943
35978
  index("agent_session_steps_worktree_idx").on(t.tenantId, t.host, t.worktreeId, t.at),
35944
35979
  check2("agent_session_steps_kind_check", sql`${t.kind} in ('start', 'read', 'edit', 'run', 'commit', 'push', 'pr', 'check', 'ask', 'answer', 'note', 'done')`),
35945
35980
  check2("agent_session_steps_change_check", sql`${t.change} is null or ${t.change} in ('added', 'edited', 'removed')`),
35981
+ check2("agent_session_steps_lines_check", sql`coalesce(${t.linesAdded}, 0) >= 0 and coalesce(${t.linesRemoved}, 0) >= 0`),
35946
35982
  check2("agent_session_steps_outcome_check", sql`${t.outcome} is null or ${t.outcome} in ('pass', 'fail')`)
35947
35983
  ]);
35948
35984
 
@@ -35978,6 +36014,8 @@ var createAgentSessionStepInputSchema = object({
35978
36014
  detail: string2().trim().min(1).max(600).nullish(),
35979
36015
  file: string2().trim().min(1).max(500).nullish(),
35980
36016
  change: agentSessionFileChangeSchema.nullish(),
36017
+ linesAdded: number2().int().nonnegative().max(1e6).nullish(),
36018
+ linesRemoved: number2().int().nonnegative().max(1e6).nullish(),
35981
36019
  outcome: agentSessionOutcomeSchema.nullish(),
35982
36020
  url: string2().trim().url().max(500).refine((u) => u.startsWith("https://"), "an https link").nullish(),
35983
36021
  at: exports_coerce.date().optional()
@@ -35985,6 +36023,13 @@ var createAgentSessionStepInputSchema = object({
35985
36023
  if ((v.file || v.change) && v.kind !== "edit") {
35986
36024
  ctx.addIssue({ code: "custom", path: ["file"], message: "file and change go on an edit" });
35987
36025
  }
36026
+ if ((v.linesAdded != null || v.linesRemoved != null) && !v.file) {
36027
+ ctx.addIssue({
36028
+ code: "custom",
36029
+ path: ["linesAdded"],
36030
+ message: "line counts need their file"
36031
+ });
36032
+ }
35988
36033
  if (v.change && !v.file) {
35989
36034
  ctx.addIssue({ code: "custom", path: ["change"], message: "a change needs its file" });
35990
36035
  }
@@ -37004,7 +37049,13 @@ var automationRunSummarySchema = object({
37004
37049
  });
37005
37050
  var automationListItemSchema = automationViewSchema.extend({
37006
37051
  madeBy: object({ userId: string2(), name: string2(), you: boolean2() }).nullable(),
37007
- lastRun: automationRunSummarySchema.nullable()
37052
+ lastRun: automationRunSummarySchema.nullable(),
37053
+ needs: object({
37054
+ connectionId: string2(),
37055
+ provider: string2(),
37056
+ title: string2(),
37057
+ reconnect: boolean2()
37058
+ }).nullable().default(null)
37008
37059
  });
37009
37060
  var automationRunNowSchema = object({ queued: literal(true) });
37010
37061
 
@@ -37637,6 +37688,11 @@ var reviewStreakSchema = object({
37637
37688
  graceBudget: countSchema2.optional(),
37638
37689
  kept30: reviewTallySchema.optional(),
37639
37690
  period: reviewTallySchema.optional(),
37691
+ today: object({
37692
+ state: reviewMarkStateSchema,
37693
+ value: number2().nonnegative().nullable(),
37694
+ target: number2().positive().nullable()
37695
+ }).optional(),
37640
37696
  paused: boolean2().optional()
37641
37697
  });
37642
37698
  var reviewProjectSchema = object({
@@ -39840,6 +39896,7 @@ var shareLinkSchema = createSelectSchema(shareLinks, {
39840
39896
  updatedAt: exports_coerce.date()
39841
39897
  });
39842
39898
  var shareLinkPublicSchema = shareLinkSchema.omit({ tokenHash: true });
39899
+ var shareLinkListedSchema = shareLinkPublicSchema.extend({ token: string2().nullable() });
39843
39900
  var createShareLinkInputSchema = createInsertSchema(shareLinks, {
39844
39901
  id: ulidSchema,
39845
39902
  nodeId: ulidSchema,
@@ -40087,6 +40144,32 @@ var shoppingListOperations = defineOperations({
40087
40144
  })
40088
40145
  });
40089
40146
 
40147
+ // ../../packages/schema/src/operations/space.ts
40148
+ var spaceOperations = defineOperations({
40149
+ address: {
40150
+ method: "get",
40151
+ path: "/space/address",
40152
+ scopes: ["settings:read"],
40153
+ tag: "Space",
40154
+ summary: "Get the Space's address",
40155
+ description: "The household's postal address as `{ address }`: one line, or null when none is set.",
40156
+ status: 200,
40157
+ response: { description: "The Space's address." }
40158
+ },
40159
+ setAddress: {
40160
+ method: "put",
40161
+ path: "/space/address",
40162
+ scopes: ["settings:write"],
40163
+ tag: "Space",
40164
+ summary: "Set the Space's address",
40165
+ description: "Set the household's postal address to one line (trimmed, at most 200 characters); `null` or a blank line clears it. Returns `{ address }`.",
40166
+ body: setSpaceAddressInputSchema,
40167
+ status: 200,
40168
+ response: { description: "The Space's address now." },
40169
+ errors: { 400: true }
40170
+ }
40171
+ });
40172
+
40090
40173
  // ../../packages/schema/src/db/tap-tags.ts
40091
40174
  var tapTagKind = pgEnum("tap_tag_kind", ["habit", "routine"]);
40092
40175
  var tapTags = pgTable("tap_tags", {
@@ -40503,6 +40586,7 @@ var taskOperations = defineOperations({
40503
40586
  tag: "Tasks",
40504
40587
  summary: "Delete a task",
40505
40588
  description: "Delete a task; fires the `task.deleted` webhook.",
40589
+ query: DELETE_REASON_QUERY,
40506
40590
  status: 204,
40507
40591
  response: { description: "Deleted." },
40508
40592
  errors: { 404: true },
@@ -42266,6 +42350,11 @@ function reachabilityWord(m, { timeZone } = {}) {
42266
42350
  const how = route === "same-machine" ? ", it lives here" : route === "local" ? ", local network" : route === "tailnet" ? ", over the tailnet" : "";
42267
42351
  return { text: `Orca reachable${how}`, kind: "done" };
42268
42352
  }
42353
+ function sessionsWhen(m) {
42354
+ if (!m.orca.reachable)
42355
+ return "idle";
42356
+ return m.running > 0 ? "now" : "today";
42357
+ }
42269
42358
  function lastSeen(m, now, timeZone) {
42270
42359
  if (m.orca.reachable)
42271
42360
  return "Now";
@@ -42278,7 +42367,7 @@ function machineFacts(m, { now = new Date, timeZone } = {}) {
42278
42367
  const disk = m.disk && m.disk.totalGb > 0 ? `${Math.round(m.disk.usedGb / m.disk.totalGb * 100)}% used` : "Unknown";
42279
42368
  const fourth = m.updatesWaiting && m.updatesWaiting > 0 ? { label: "Updates", value: `${m.updatesWaiting} waiting` } : m.battery ? { label: "Battery", value: m.battery === "charging" ? "Charging" : "On battery" } : m.uptimeDays !== null ? { label: "Uptime", value: plural(m.uptimeDays, "day", "days") } : { label: "Uptime", value: "Unknown" };
42280
42369
  return [
42281
- { label: "Sessions", value: String(m.sessions) },
42370
+ { label: "Sessions", value: `${m.sessions} ${sessionsWhen(m)}` },
42282
42371
  { label: "Last seen", value: lastSeen(m, now, timeZone) },
42283
42372
  { label: "Disk", value: disk },
42284
42373
  fourth
@@ -46808,6 +46897,22 @@ function renderKraken(data, mode) {
46808
46897
  }
46809
46898
  var commands11 = pairCommands(CONNECTION_COMMAND_SPECS, CONNECTION_HANDLERS);
46810
46899
 
46900
+ // ../../packages/domain/src/knows-about.ts
46901
+ var same = (a, b) => a.trim().toLowerCase() === b.trim().toLowerCase();
46902
+ function knowsAboutHas(list, phrase) {
46903
+ return list.some((p) => same(p, phrase));
46904
+ }
46905
+ function canAddKnowsAbout(list, draft) {
46906
+ const phrase = draft.trim();
46907
+ return phrase.length > 0 && phrase.length <= KNOWS_ABOUT_PHRASE_MAX && list.length < KNOWS_ABOUT_MAX && !knowsAboutHas(list, phrase);
46908
+ }
46909
+ function addKnowsAbout(list, draft) {
46910
+ return canAddKnowsAbout(list, draft) ? [...list, draft.trim()] : [...list];
46911
+ }
46912
+ function removeKnowsAbout(list, phrase) {
46913
+ return list.filter((p) => !same(p, phrase));
46914
+ }
46915
+
46811
46916
  // src/commands/contacts.ts
46812
46917
  var FIELD_FLAGS = [
46813
46918
  { name: "name", type: "string", description: "The display name (or pass it as the argument)." },
@@ -46837,6 +46942,21 @@ var FIELD_FLAGS = [
46837
46942
  description: "The circle ids they are in, comma-separated (replaces the membership)."
46838
46943
  },
46839
46944
  { name: "tags", type: "string", description: "Tags, comma-separated (replaces the tags)." },
46945
+ {
46946
+ name: "knows",
46947
+ type: "string",
46948
+ description: "What they know about, the go-to for, comma-separated (replaces the list; none clears it)."
46949
+ },
46950
+ {
46951
+ name: "knows-add",
46952
+ type: "string",
46953
+ description: `One more thing they know about ("the boat's engine"); a repeat is skipped.`
46954
+ },
46955
+ {
46956
+ name: "knows-remove",
46957
+ type: "string",
46958
+ description: "Take one thing off what they know about (ignoring case)."
46959
+ },
46840
46960
  { name: "notes", type: "string", description: "Long-form notes." },
46841
46961
  {
46842
46962
  name: "rhythm",
@@ -46862,10 +46982,10 @@ var CONTACT_COMMAND_SPECS = [
46862
46982
  flags: FIELD_FLAGS,
46863
46983
  scopes: [...contactOperations.update.scopes],
46864
46984
  returns: "ContactView",
46865
- 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)."
46985
+ 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."
46866
46986
  }
46867
46987
  ];
46868
- var MERGING_FLAGS = ["birthday", "no-year", "roles"];
46988
+ var MERGING_FLAGS = ["birthday", "no-year", "roles", "knows-add", "knows-remove"];
46869
46989
  var NULLABLE = ["email", "phone", "company", "website", "notes"];
46870
46990
  function list2(value) {
46871
46991
  return value.split(",").map((v) => v.trim()).filter((v) => v.length > 0);
@@ -46900,6 +47020,19 @@ function contactBodyFromFlags(flags, base, op, current) {
46900
47020
  const tags = flagString(flags, "tags");
46901
47021
  if (tags !== undefined)
46902
47022
  body.tags = isNone(tags) ? [] : list2(tags);
47023
+ const knows = flagString(flags, "knows");
47024
+ if (knows !== undefined)
47025
+ body.knowsAbout = isNone(knows) ? [] : list2(knows);
47026
+ const knowsAdd = flagString(flags, "knows-add");
47027
+ const knowsRemove = flagString(flags, "knows-remove");
47028
+ if (knowsAdd !== undefined || knowsRemove !== undefined) {
47029
+ let phrases = body.knowsAbout ?? current?.knowsAbout ?? [];
47030
+ if (knowsRemove !== undefined)
47031
+ phrases = removeKnowsAbout(phrases, knowsRemove);
47032
+ if (knowsAdd !== undefined)
47033
+ phrases = addKnowsAbout(phrases, knowsAdd);
47034
+ body.knowsAbout = phrases;
47035
+ }
46903
47036
  const circles = flagString(flags, "circles");
46904
47037
  if (circles !== undefined)
46905
47038
  body.circleIds = isNone(circles) ? [] : list2(circles);
@@ -52347,6 +52480,11 @@ var GLOBAL_FLAGS = [
52347
52480
  type: "boolean",
52348
52481
  description: "Permit a destructive verb (delete/revoke/remove-member). Off by default \u2014 a guardrail for autonomous agents."
52349
52482
  },
52483
+ {
52484
+ name: "reason",
52485
+ type: "string",
52486
+ description: `One line on why, for delete/archive (sent as ?reason=). An agent's shows in the Trash: "Deleted by <agent>: <reason>".`
52487
+ },
52350
52488
  {
52351
52489
  name: "dry-run",
52352
52490
  type: "boolean",
@@ -53904,6 +54042,12 @@ var commands36 = [
53904
54042
  type: "string",
53905
54043
  description: "An edit's change: added, edited or removed."
53906
54044
  },
54045
+ { name: "added", type: "string", description: "Lines an edit added to its file, e.g. 42." },
54046
+ {
54047
+ name: "removed",
54048
+ type: "string",
54049
+ description: "Lines an edit removed from its file, e.g. 17."
54050
+ },
53907
54051
  { name: "outcome", type: "string", description: "A run's outcome: pass or fail." },
53908
54052
  { name: "url", type: "string", description: "A pr step's pull request link (https)." }
53909
54053
  ],
@@ -53921,6 +54065,8 @@ var commands36 = [
53921
54065
  detail: flagString(flags, "detail"),
53922
54066
  file: flagString(flags, "file"),
53923
54067
  change: flagString(flags, "change"),
54068
+ linesAdded: flagCount(flags, "added"),
54069
+ linesRemoved: flagCount(flags, "removed"),
53924
54070
  outcome: flagString(flags, "outcome"),
53925
54071
  url: flagString(flags, "url")
53926
54072
  });
@@ -53931,6 +54077,10 @@ var commands36 = [
53931
54077
  }
53932
54078
  }
53933
54079
  ];
54080
+ function flagCount(flags, name) {
54081
+ const raw = flagString(flags, name);
54082
+ return raw === undefined ? undefined : Number(raw);
54083
+ }
53934
54084
 
53935
54085
  // src/commands/people.ts
53936
54086
  import { readFileSync as readFileSync9 } from "fs";
@@ -57504,7 +57654,7 @@ var commands52 = [
57504
57654
  ],
57505
57655
  scopes: [...shareLinkOperations.create.scopes],
57506
57656
  returns: "CreateShareLinkResult",
57507
- notes: "The signed token is returned once, in the create response."
57657
+ notes: "The signed token isn't shown once: `do link list <node>` gives it again until the link expires or is revoked."
57508
57658
  },
57509
57659
  run: async ({ args, flags, requireClient }) => {
57510
57660
  const node = requireArg(args, 0, "node id");
@@ -57527,7 +57677,7 @@ var commands52 = [
57527
57677
  args: [{ name: "node", required: true, description: "Node ULID." }],
57528
57678
  flags: [],
57529
57679
  scopes: [...shareLinkOperations.listForNode.scopes],
57530
- returns: "ShareLinkPublic"
57680
+ returns: "ShareLinkListed"
57531
57681
  },
57532
57682
  run: readOperation(shareLinkOperations.listForNode, renderList, { nodeId: "node id" })
57533
57683
  },
@@ -57552,8 +57702,64 @@ var commands52 = [
57552
57702
  }
57553
57703
  ];
57554
57704
 
57555
- // src/commands/tap-tags.ts
57705
+ // src/commands/space.ts
57556
57706
  var commands53 = [
57707
+ {
57708
+ spec: {
57709
+ path: ["space", "address"],
57710
+ summary: "Show the Space's postal address (null when none is set).",
57711
+ args: [],
57712
+ flags: [],
57713
+ scopes: [...spaceOperations.address.scopes],
57714
+ returns: "SpaceAddress",
57715
+ notes: `${routeOf(spaceOperations.address)}.`
57716
+ },
57717
+ run: readOperation(spaceOperations.address, renderRecord)
57718
+ },
57719
+ {
57720
+ spec: {
57721
+ path: ["space", "address", "set"],
57722
+ summary: "Set the Space's postal address to one line.",
57723
+ args: [
57724
+ {
57725
+ name: "address",
57726
+ required: true,
57727
+ description: 'One line, e.g. "Main Street 12, Springfield".'
57728
+ }
57729
+ ],
57730
+ flags: [],
57731
+ scopes: [...spaceOperations.setAddress.scopes],
57732
+ returns: "SpaceAddress",
57733
+ notes: `${routeOf(spaceOperations.setAddress)}. Trimmed, at most 200 characters.`
57734
+ },
57735
+ run: async ({ args, requireClient }) => {
57736
+ requireArg(args, 0, "address");
57737
+ const body = parseInput(setSpaceAddressInputSchema, { address: args.join(" ") });
57738
+ return {
57739
+ data: await requireClient().put(pathOf(spaceOperations.setAddress), body),
57740
+ render: renderRecord
57741
+ };
57742
+ }
57743
+ },
57744
+ {
57745
+ spec: {
57746
+ path: ["space", "address", "clear"],
57747
+ summary: "Clear the Space's postal address.",
57748
+ args: [],
57749
+ flags: [],
57750
+ scopes: [...spaceOperations.setAddress.scopes],
57751
+ returns: "SpaceAddress",
57752
+ notes: `${routeOf(spaceOperations.setAddress)} with \`{ "address": null }\`.`
57753
+ },
57754
+ run: async ({ requireClient }) => ({
57755
+ data: await requireClient().put(pathOf(spaceOperations.setAddress), { address: null }),
57756
+ render: renderRecord
57757
+ })
57758
+ }
57759
+ ];
57760
+
57761
+ // src/commands/tap-tags.ts
57762
+ var commands54 = [
57557
57763
  {
57558
57764
  spec: {
57559
57765
  path: ["tap-tags", "tap"],
@@ -57581,7 +57787,7 @@ var BY = {
57581
57787
  type: "string",
57582
57788
  description: "The blocking task's ref (DO-147) or ULID."
57583
57789
  };
57584
- var commands54 = [
57790
+ var commands55 = [
57585
57791
  defineCommand({
57586
57792
  operation: taskBlockOperations.addBlocker,
57587
57793
  path: ["tasks", "block"],
@@ -57647,7 +57853,7 @@ function renderSeries(data, mode) {
57647
57853
  }).join(`
57648
57854
  `);
57649
57855
  }
57650
- var commands55 = [
57856
+ var commands56 = [
57651
57857
  defineCommand({
57652
57858
  operation: taskSeriesOperations.make,
57653
57859
  path: ["tasks", "make-series"],
@@ -57802,7 +58008,7 @@ function repeatFromFlags(flags) {
57802
58008
  out.anchor = "from_completion";
57803
58009
  return out;
57804
58010
  }
57805
- var commands56 = [
58011
+ var commands57 = [
57806
58012
  {
57807
58013
  spec: {
57808
58014
  path: ["capture"],
@@ -58260,7 +58466,7 @@ var commands56 = [
58260
58466
  ];
58261
58467
 
58262
58468
  // src/commands/time-blocks.ts
58263
- var commands57 = [
58469
+ var commands58 = [
58264
58470
  {
58265
58471
  spec: {
58266
58472
  path: ["time-blocks", "record"],
@@ -58441,7 +58647,7 @@ function renderLandedCounts(data, mode) {
58441
58647
  return out.join(`
58442
58648
  `);
58443
58649
  }
58444
- var commands58 = [
58650
+ var commands59 = [
58445
58651
  {
58446
58652
  spec: {
58447
58653
  path: ["today"],
@@ -58813,7 +59019,7 @@ function renderViews(data, mode) {
58813
59019
  function renderView(data, mode) {
58814
59020
  return renderViews([data], mode);
58815
59021
  }
58816
- var commands59 = [
59022
+ var commands60 = [
58817
59023
  defineCommand({
58818
59024
  operation: workViewOperations.list,
58819
59025
  path: ["views", "list"],
@@ -58932,7 +59138,7 @@ var commands59 = [
58932
59138
  ];
58933
59139
 
58934
59140
  // src/commands/worktree-links.ts
58935
- var commands60 = [
59141
+ var commands61 = [
58936
59142
  {
58937
59143
  spec: {
58938
59144
  path: ["worktree-links", "list"],
@@ -59098,7 +59304,8 @@ var FEATURE_COMMANDS = [
59098
59304
  ...commands57,
59099
59305
  ...commands58,
59100
59306
  ...commands59,
59101
- ...commands60
59307
+ ...commands60,
59308
+ ...commands61
59102
59309
  ];
59103
59310
 
59104
59311
  // src/registry.ts
@@ -59291,7 +59498,8 @@ async function dispatchEntity(entity, rest, flags, requireClient) {
59291
59498
  }
59292
59499
  if (op === "delete")
59293
59500
  assertDestructiveAllowed(flags, `delete ${entity.name} ${id}`);
59294
- await client.delete(`${entity.path}/${id}`);
59501
+ const reason = flagString(flags, "reason");
59502
+ await client.delete(`${entity.path}/${id}`, reason ? { query: { reason } } : {});
59295
59503
  return {
59296
59504
  data: op === "archive" ? { ok: true, archived: id, softDelete: true } : { ok: true, deleted: id, softDelete: true },
59297
59505
  render: renderRecord
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@robbeverhelst/do",
3
- "version": "1.351.0",
3
+ "version": "1.353.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
  }