@robbeverhelst/do 1.172.1 → 1.174.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 +71 -7
  2. package/package.json +1 -1
package/dist/do.js CHANGED
@@ -3703,7 +3703,10 @@ var projects = pgTable("projects", {
3703
3703
  progress: integer("progress").notNull().default(0),
3704
3704
  startAt: timestamp("start_at", { withTimezone: true }),
3705
3705
  dueAt: timestamp("due_at", { withTimezone: true }),
3706
- areaId: text("area_id").references(() => areas.id)
3706
+ areaId: text("area_id").references(() => areas.id),
3707
+ completedAt: timestamp("completed_at", { withTimezone: true }),
3708
+ finishProposedAt: timestamp("finish_proposed_at", { withTimezone: true }),
3709
+ finishNotYetAt: timestamp("finish_not_yet_at", { withTimezone: true })
3707
3710
  }, (t) => [
3708
3711
  index("projects_tenant_idx").on(t.tenantId),
3709
3712
  index("projects_tenant_area_idx").on(t.tenantId, t.areaId)
@@ -3733,6 +3736,9 @@ var userSettings = pgTable("user_settings", {
3733
3736
  backdrop: text("backdrop"),
3734
3737
  enabledModules: text("enabled_modules").array().notNull().default([]),
3735
3738
  autoRollOverdue: boolean("auto_roll_overdue").notNull().default(false),
3739
+ pinnedAreaIds: text("pinned_area_ids").array().notNull().default([]),
3740
+ focusAreaId: text("focus_area_id"),
3741
+ focusUntil: timestamp("focus_until", { withTimezone: true }),
3736
3742
  createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
3737
3743
  updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
3738
3744
  }, (t) => [unique("user_settings_tenant_user_uniq").on(t.tenantId, t.userId)]);
@@ -19087,7 +19093,10 @@ var routineRunUndoInputSchema = object({
19087
19093
  // ../../packages/schema/src/contracts/projects.ts
19088
19094
  var projectSchema = createSelectSchema(projects, {
19089
19095
  startAt: exports_coerce.date().nullable(),
19090
- dueAt: exports_coerce.date().nullable()
19096
+ dueAt: exports_coerce.date().nullable(),
19097
+ completedAt: exports_coerce.date().nullish(),
19098
+ finishProposedAt: exports_coerce.date().nullish(),
19099
+ finishNotYetAt: exports_coerce.date().nullish()
19091
19100
  });
19092
19101
  var projectMilestoneSchema = createSelectSchema(projectMilestones, {
19093
19102
  dueAt: exports_coerce.date().nullable(),
@@ -19107,7 +19116,7 @@ var createProjectInputSchema = createInsertSchema(projects, {
19107
19116
  startAt: exports_coerce.date().nullish(),
19108
19117
  dueAt: exports_coerce.date().nullish(),
19109
19118
  areaId: ulidSchema.nullish()
19110
- }).omit({ tenantId: true }).extend({
19119
+ }).omit({ tenantId: true, completedAt: true, finishProposedAt: true, finishNotYetAt: true }).extend({
19111
19120
  title: string2().min(1),
19112
19121
  parentId: ulidSchema.nullish(),
19113
19122
  milestones: array(projectMilestoneInputSchema).optional(),
@@ -19118,8 +19127,9 @@ var updateProjectInputSchema = createUpdateSchema(projects, {
19118
19127
  startAt: exports_coerce.date().nullish(),
19119
19128
  dueAt: exports_coerce.date().nullish(),
19120
19129
  areaId: ulidSchema.nullish()
19121
- }).omit({ id: true, tenantId: true }).extend({
19130
+ }).omit({ id: true, tenantId: true, completedAt: true, finishProposedAt: true }).extend({
19122
19131
  title: string2().min(1).optional(),
19132
+ finishNotYetAt: exports_coerce.date().nullish(),
19123
19133
  parentId: ulidSchema.nullish(),
19124
19134
  milestones: array(projectMilestoneInputSchema).optional(),
19125
19135
  notes: string2().nullish()
@@ -19599,7 +19609,11 @@ function setModuleEnabled(enabled, key, on) {
19599
19609
  }
19600
19610
 
19601
19611
  // ../../packages/schema/src/contracts/settings.ts
19612
+ var PINNED_AREAS_MAX = 5;
19602
19613
  var userSettingsSchema = createSelectSchema(userSettings, {
19614
+ pinnedAreaIds: array(string2()).default([]),
19615
+ focusAreaId: string2().nullable().default(null),
19616
+ focusUntil: exports_coerce.date().nullable().default(null),
19603
19617
  createdAt: exports_coerce.date(),
19604
19618
  updatedAt: exports_coerce.date()
19605
19619
  }).omit({ autoRollOverdue: true });
@@ -19613,14 +19627,17 @@ var updateUserSettingsInputSchema = createUpdateSchema(userSettings, {
19613
19627
  accent: settingsAccentSchema.optional(),
19614
19628
  sunCity: string2().trim().max(80).transform((city) => city === "" ? null : city).nullish(),
19615
19629
  backdrop: backdropIdSchema.nullish(),
19616
- enabledModules: array(string2().trim().min(1)).transform(normalizeEnabledModules).optional()
19630
+ enabledModules: array(string2().trim().min(1)).transform(normalizeEnabledModules).optional(),
19631
+ pinnedAreaIds: array(ulidSchema).transform((ids) => [...new Set(ids)]).pipe(array(ulidSchema).max(PINNED_AREAS_MAX)).optional(),
19632
+ focusAreaId: ulidSchema.nullish()
19617
19633
  }).omit({
19618
19634
  id: true,
19619
19635
  tenantId: true,
19620
19636
  userId: true,
19621
19637
  createdAt: true,
19622
19638
  updatedAt: true,
19623
- autoRollOverdue: true
19639
+ autoRollOverdue: true,
19640
+ focusUntil: true
19624
19641
  }).strict();
19625
19642
 
19626
19643
  // ../../packages/schema/src/contracts/shopping.ts
@@ -21334,7 +21351,7 @@ function parseCapture2(input, now) {
21334
21351
 
21335
21352
  // src/meta.ts
21336
21353
  var CLI_NAME = "do";
21337
- var VERSION = "1.172.1";
21354
+ var VERSION = "1.174.0";
21338
21355
  var API_PREFIX = "/api/v1";
21339
21356
  var DEFAULT_API_URL = "http://localhost:3001";
21340
21357
 
@@ -23061,6 +23078,33 @@ var COMMAND_SPECS = [
23061
23078
  returns: "AreaView",
23062
23079
  notes: "PATCH /api/v1/areas/{id} { restingUntil: null }. Nothing was lost while it rested."
23063
23080
  },
23081
+ {
23082
+ path: ["areas", "focus"],
23083
+ summary: "Focus on one Area for the rest of the day: Now, Tasks and Calendar show only it.",
23084
+ args: [{ name: "id", required: false, description: "Area ULID (omit with --off)." }],
23085
+ flags: [{ name: "off", type: "boolean", description: "Show everything again." }],
23086
+ scopes: ["settings:write"],
23087
+ returns: "UserSettings",
23088
+ notes: "PATCH /api/v1/settings { focusAreaId }. Clears itself at the end of the member's day (focusUntil); hidden tasks don't move or go overdue."
23089
+ },
23090
+ {
23091
+ path: ["areas", "pin"],
23092
+ summary: "Pin an Area under Life in the desktop sidebar (up to five).",
23093
+ args: [{ name: "id", required: true, description: "Area ULID." }],
23094
+ flags: [],
23095
+ scopes: ["settings:read", "settings:write"],
23096
+ returns: "UserSettings",
23097
+ notes: "Reads then patches settings.pinnedAreaIds; a pinned Area stays where it is."
23098
+ },
23099
+ {
23100
+ path: ["areas", "unpin"],
23101
+ summary: "Take an Area out of the desktop sidebar.",
23102
+ args: [{ name: "id", required: true, description: "Area ULID." }],
23103
+ flags: [],
23104
+ scopes: ["settings:read", "settings:write"],
23105
+ returns: "UserSettings",
23106
+ notes: "Reads then patches settings.pinnedAreaIds."
23107
+ },
23064
23108
  {
23065
23109
  path: ["places", "import"],
23066
23110
  summary: "Import the rooms of the house once from Gaard's house.json.",
@@ -25320,6 +25364,16 @@ var HANDLERS = {
25320
25364
  const input = parseInput(updateAreaInputSchema, { restingUntil: null });
25321
25365
  return { data: await requireClient().patch(`/areas/${id}`, input), render: renderRecord };
25322
25366
  },
25367
+ "areas focus": async ({ args, flags, requireClient }) => {
25368
+ const off = flagBool(flags, "off");
25369
+ const id = off ? null : args[0];
25370
+ if (id === undefined)
25371
+ throw usageError("areas focus needs an area id, or --off to show everything");
25372
+ const body = parseInput(updateUserSettingsInputSchema, { focusAreaId: id });
25373
+ return { data: await requireClient().patch("/settings", body), render: renderRecord };
25374
+ },
25375
+ "areas pin": async ({ args, requireClient }) => setAreaPinned(args, requireClient, true),
25376
+ "areas unpin": async ({ args, requireClient }) => setAreaPinned(args, requireClient, false),
25323
25377
  "places import": async ({ args, flags, requireClient }) => {
25324
25378
  const path = requireArg(args, 0, "house.json path");
25325
25379
  let file;
@@ -25538,6 +25592,16 @@ async function setModuleVisibility(args, requireClient, on) {
25538
25592
  const body = parseInput(updateUserSettingsInputSchema, { enabledModules });
25539
25593
  return { data: await client.patch("/settings", body), render: renderRecord };
25540
25594
  }
25595
+ async function setAreaPinned(args, requireClient, pinned) {
25596
+ const id = requireArg(args, 0, "area id");
25597
+ const client = requireClient();
25598
+ const settings = await client.get("/settings");
25599
+ const rest = (settings.pinnedAreaIds ?? []).filter((x) => x !== id);
25600
+ const body = parseInput(updateUserSettingsInputSchema, {
25601
+ pinnedAreaIds: pinned ? [...rest, id] : rest
25602
+ });
25603
+ return { data: await client.patch("/settings", body), render: renderRecord };
25604
+ }
25541
25605
  function parseTitleTags(args) {
25542
25606
  const titleWords = [];
25543
25607
  const tags = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@robbeverhelst/do",
3
- "version": "1.172.1",
3
+ "version": "1.174.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",