@robbeverhelst/do 1.340.0 → 1.342.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.
- package/dist/do.js +2519 -343
- package/package.json +1 -1
package/dist/do.js
CHANGED
|
@@ -14418,7 +14418,7 @@ var configError = (message) => new CliError("config", message, EXIT.CONFIG);
|
|
|
14418
14418
|
|
|
14419
14419
|
// src/meta.ts
|
|
14420
14420
|
var CLI_NAME = "do";
|
|
14421
|
-
var VERSION = "1.
|
|
14421
|
+
var VERSION = "1.342.0";
|
|
14422
14422
|
var API_PREFIX = "/api/v1";
|
|
14423
14423
|
var DEFAULT_API_URL = "http://localhost:3001";
|
|
14424
14424
|
|
|
@@ -14852,8 +14852,8 @@ function httpMessage(status, body) {
|
|
|
14852
14852
|
if (typeof e === "string")
|
|
14853
14853
|
return e;
|
|
14854
14854
|
const inner = e?.message;
|
|
14855
|
-
if (typeof inner === "string"
|
|
14856
|
-
return `${inner} (HTTP 413)
|
|
14855
|
+
if (typeof inner === "string")
|
|
14856
|
+
return status === 413 ? `${inner} (HTTP 413)` : inner;
|
|
14857
14857
|
}
|
|
14858
14858
|
if (typeof body === "string" && body.length > 0)
|
|
14859
14859
|
return body;
|
|
@@ -17642,6 +17642,7 @@ function uniqueIndex(name) {
|
|
|
17642
17642
|
|
|
17643
17643
|
// ../../packages/schema/src/db/tenancy.ts
|
|
17644
17644
|
var baseRole = pgEnum("base_role", ["owner", "admin", "member", "guest"]);
|
|
17645
|
+
var workPriority = pgEnum("work_priority", ["none", "low", "medium", "high"]);
|
|
17645
17646
|
var tenants = pgTable("tenants", {
|
|
17646
17647
|
id: text("id").primaryKey(),
|
|
17647
17648
|
name: text("name").notNull(),
|
|
@@ -17649,6 +17650,8 @@ var tenants = pgTable("tenants", {
|
|
|
17649
17650
|
gaardHouseUrl: text("gaard_house_url"),
|
|
17650
17651
|
awayFrom: date5("away_from", { mode: "string" }),
|
|
17651
17652
|
awayUntil: date5("away_until", { mode: "string" }),
|
|
17653
|
+
lastTaskNumber: integer2("last_task_number").notNull().default(0),
|
|
17654
|
+
lastProjectNumber: integer2("last_project_number").notNull().default(0),
|
|
17652
17655
|
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
17653
17656
|
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
|
|
17654
17657
|
deletedAt: timestamp("deleted_at", { withTimezone: true })
|
|
@@ -17883,176 +17886,6 @@ var automationRuns = pgTable("automation_runs", {
|
|
|
17883
17886
|
index("automation_runs_tenant_automation_created_idx").on(t.tenantId, t.automationId, t.createdAt)
|
|
17884
17887
|
]);
|
|
17885
17888
|
|
|
17886
|
-
// ../../packages/schema/src/db/challenges.ts
|
|
17887
|
-
var challengeSource = pgEnum("challenge_source", ["self", "system"]);
|
|
17888
|
-
var challengeSubjectType = pgEnum("challenge_subject_type", ["habit", "area", "tag"]);
|
|
17889
|
-
var challenges = pgTable("challenges", {
|
|
17890
|
-
id: text("id").primaryKey(),
|
|
17891
|
-
tenantId: text("tenant_id").notNull().references(() => tenants.id, { onDelete: "cascade" }),
|
|
17892
|
-
title: text("title").notNull(),
|
|
17893
|
-
description: text("description"),
|
|
17894
|
-
source: challengeSource("source").notNull().default("self"),
|
|
17895
|
-
metric: text("metric").notNull(),
|
|
17896
|
-
subjectType: challengeSubjectType("subject_type"),
|
|
17897
|
-
subjectId: text("subject_id"),
|
|
17898
|
-
target: integer2("target").notNull(),
|
|
17899
|
-
startAt: timestamp("start_at", { withTimezone: true }).notNull(),
|
|
17900
|
-
endAt: timestamp("end_at", { withTimezone: true }).notNull(),
|
|
17901
|
-
createdBy: text("created_by").references(() => users.id, { onDelete: "set null" }),
|
|
17902
|
-
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
17903
|
-
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
17904
|
-
}, (t) => [
|
|
17905
|
-
index("challenges_tenant_idx").on(t.tenantId),
|
|
17906
|
-
index("challenges_tenant_window_idx").on(t.tenantId, t.startAt, t.endAt),
|
|
17907
|
-
index("challenges_tenant_subject_idx").on(t.tenantId, t.subjectType, t.subjectId),
|
|
17908
|
-
check2("challenges_subject_pair_chk", sql`(${t.subjectType} IS NULL) = (${t.subjectId} IS NULL)`)
|
|
17909
|
-
]);
|
|
17910
|
-
var challengeParticipants = pgTable("challenge_participants", {
|
|
17911
|
-
id: text("id").primaryKey(),
|
|
17912
|
-
tenantId: text("tenant_id").notNull().references(() => tenants.id, { onDelete: "cascade" }),
|
|
17913
|
-
challengeId: text("challenge_id").notNull().references(() => challenges.id, { onDelete: "cascade" }),
|
|
17914
|
-
userId: text("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
|
|
17915
|
-
joinedAt: timestamp("joined_at", { withTimezone: true }).notNull().defaultNow()
|
|
17916
|
-
}, (t) => [
|
|
17917
|
-
unique("challenge_participants_challenge_user_uniq").on(t.challengeId, t.userId),
|
|
17918
|
-
index("challenge_participants_tenant_idx").on(t.tenantId),
|
|
17919
|
-
index("challenge_participants_user_idx").on(t.tenantId, t.userId)
|
|
17920
|
-
]);
|
|
17921
|
-
|
|
17922
|
-
// ../../packages/schema/src/db/collaboration.ts
|
|
17923
|
-
var capability = pgEnum("collab_capability", ["view", "comment", "edit", "admin"]);
|
|
17924
|
-
var grantSubjectType = pgEnum("grant_subject_type", ["member", "role"]);
|
|
17925
|
-
var inviteType = pgEnum("invite_type", ["email", "link", "join_request", "guest"]);
|
|
17926
|
-
var inviteStatus = pgEnum("invite_status", ["pending", "accepted", "revoked", "expired"]);
|
|
17927
|
-
var permissionSets = pgTable("permission_sets", {
|
|
17928
|
-
id: text("id").primaryKey(),
|
|
17929
|
-
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
17930
|
-
name: text("name").notNull(),
|
|
17931
|
-
canView: boolean4("can_view").notNull().default(true),
|
|
17932
|
-
canComment: boolean4("can_comment").notNull().default(false),
|
|
17933
|
-
canEdit: boolean4("can_edit").notNull().default(false),
|
|
17934
|
-
canShare: boolean4("can_share").notNull().default(false),
|
|
17935
|
-
canManageMembers: boolean4("can_manage_members").notNull().default(false),
|
|
17936
|
-
canManageRoles: boolean4("can_manage_roles").notNull().default(false),
|
|
17937
|
-
canManageSpace: boolean4("can_manage_space").notNull().default(false),
|
|
17938
|
-
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
17939
|
-
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
17940
|
-
}, (t) => [unique("permission_sets_tenant_name_uniq").on(t.tenantId, t.name)]);
|
|
17941
|
-
var roles = pgTable("roles", {
|
|
17942
|
-
id: text("id").primaryKey(),
|
|
17943
|
-
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
17944
|
-
name: text("name").notNull(),
|
|
17945
|
-
description: text("description"),
|
|
17946
|
-
permissionSetId: text("permission_set_id").notNull().references(() => permissionSets.id),
|
|
17947
|
-
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
17948
|
-
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
17949
|
-
}, (t) => [unique("roles_tenant_name_uniq").on(t.tenantId, t.name)]);
|
|
17950
|
-
var invites = pgTable("invites", {
|
|
17951
|
-
id: text("id").primaryKey(),
|
|
17952
|
-
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
17953
|
-
type: inviteType("type").notNull(),
|
|
17954
|
-
email: text("email"),
|
|
17955
|
-
token: text("token").unique(),
|
|
17956
|
-
tokenHash: text("token_hash").unique(),
|
|
17957
|
-
tokenSealed: text("token_sealed"),
|
|
17958
|
-
role: baseRole("role").notNull().default("member"),
|
|
17959
|
-
customRoleId: text("custom_role_id").references(() => roles.id),
|
|
17960
|
-
invitedByUserId: text("invited_by_user_id").references(() => users.id),
|
|
17961
|
-
status: inviteStatus("status").notNull().default("pending"),
|
|
17962
|
-
accessUntil: timestamp("access_until", { withTimezone: true }),
|
|
17963
|
-
expiresAt: timestamp("expires_at", { withTimezone: true }),
|
|
17964
|
-
acceptedAt: timestamp("accepted_at", { withTimezone: true }),
|
|
17965
|
-
acceptedByUserId: text("accepted_by_user_id").references(() => users.id),
|
|
17966
|
-
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
17967
|
-
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
17968
|
-
}, (t) => [index("invites_tenant_status_idx").on(t.tenantId, t.status)]);
|
|
17969
|
-
var nodeGrants = pgTable("node_grants", {
|
|
17970
|
-
id: text("id").primaryKey(),
|
|
17971
|
-
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
17972
|
-
nodeId: text("node_id").notNull().references(() => nodes.id),
|
|
17973
|
-
subjectType: grantSubjectType("subject_type").notNull(),
|
|
17974
|
-
subjectId: text("subject_id").notNull(),
|
|
17975
|
-
capability: capability("capability").notNull(),
|
|
17976
|
-
assigned: boolean4("assigned").notNull().default(false),
|
|
17977
|
-
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
17978
|
-
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
17979
|
-
}, (t) => [
|
|
17980
|
-
unique("node_grants_node_subject_uniq").on(t.tenantId, t.nodeId, t.subjectType, t.subjectId),
|
|
17981
|
-
index("node_grants_tenant_node_idx").on(t.tenantId, t.nodeId),
|
|
17982
|
-
index("node_grants_node_idx").on(t.nodeId)
|
|
17983
|
-
]);
|
|
17984
|
-
var shareLinks = pgTable("share_links", {
|
|
17985
|
-
id: text("id").primaryKey(),
|
|
17986
|
-
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
17987
|
-
nodeId: text("node_id").notNull().references(() => nodes.id),
|
|
17988
|
-
tokenHash: text("token_hash").notNull().unique(),
|
|
17989
|
-
capability: capability("capability").notNull().default("view"),
|
|
17990
|
-
createdByUserId: text("created_by_user_id").references(() => users.id),
|
|
17991
|
-
expiresAt: timestamp("expires_at", { withTimezone: true }),
|
|
17992
|
-
revokedAt: timestamp("revoked_at", { withTimezone: true }),
|
|
17993
|
-
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
17994
|
-
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
17995
|
-
}, (t) => [
|
|
17996
|
-
index("share_links_tenant_node_idx").on(t.tenantId, t.nodeId),
|
|
17997
|
-
index("share_links_node_idx").on(t.nodeId)
|
|
17998
|
-
]);
|
|
17999
|
-
var shareLinkGuests = pgTable("share_link_guests", {
|
|
18000
|
-
id: text("id").primaryKey(),
|
|
18001
|
-
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
18002
|
-
shareLinkId: text("share_link_id").notNull().references(() => shareLinks.id, { onDelete: "cascade" }),
|
|
18003
|
-
name: text("name").notNull(),
|
|
18004
|
-
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
|
|
18005
|
-
}, (t) => [
|
|
18006
|
-
uniqueIndex("share_link_guests_link_name_uniq").on(t.shareLinkId, sql`lower(${t.name})`),
|
|
18007
|
-
index("share_link_guests_tenant_idx").on(t.tenantId)
|
|
18008
|
-
]);
|
|
18009
|
-
var comments = pgTable("comments", {
|
|
18010
|
-
id: text("id").primaryKey(),
|
|
18011
|
-
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
18012
|
-
nodeId: text("node_id").notNull().references(() => nodes.id),
|
|
18013
|
-
parentId: text("parent_id").references(() => comments.id),
|
|
18014
|
-
authorUserId: text("author_user_id").notNull().references(() => users.id),
|
|
18015
|
-
body: text("body").notNull(),
|
|
18016
|
-
editedAt: timestamp("edited_at", { withTimezone: true }),
|
|
18017
|
-
deletedAt: timestamp("deleted_at", { withTimezone: true }),
|
|
18018
|
-
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
18019
|
-
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
18020
|
-
}, (t) => [
|
|
18021
|
-
index("comments_tenant_node_created_idx").on(t.tenantId, t.nodeId, t.createdAt),
|
|
18022
|
-
index("comments_parent_idx").on(t.parentId),
|
|
18023
|
-
index("comments_node_idx").on(t.nodeId)
|
|
18024
|
-
]);
|
|
18025
|
-
var commentMentions = pgTable("comment_mentions", {
|
|
18026
|
-
id: text("id").primaryKey(),
|
|
18027
|
-
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
18028
|
-
commentId: text("comment_id").notNull().references(() => comments.id),
|
|
18029
|
-
mentionedUserId: text("mentioned_user_id").notNull().references(() => users.id),
|
|
18030
|
-
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
|
|
18031
|
-
}, (t) => [unique("comment_mentions_comment_user_uniq").on(t.commentId, t.mentionedUserId)]);
|
|
18032
|
-
var commentReactions = pgTable("comment_reactions", {
|
|
18033
|
-
id: text("id").primaryKey(),
|
|
18034
|
-
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
18035
|
-
commentId: text("comment_id").notNull().references(() => comments.id),
|
|
18036
|
-
userId: text("user_id").notNull().references(() => users.id),
|
|
18037
|
-
emoji: text("emoji").notNull(),
|
|
18038
|
-
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
|
|
18039
|
-
}, (t) => [unique("comment_reactions_comment_user_emoji_uniq").on(t.commentId, t.userId, t.emoji)]);
|
|
18040
|
-
var activityEvents = pgTable("activity_events", {
|
|
18041
|
-
id: text("id").primaryKey(),
|
|
18042
|
-
tenantId: text("tenant_id").notNull().references(() => tenants.id, { onDelete: "cascade" }),
|
|
18043
|
-
actorUserId: text("actor_user_id").references(() => users.id, { onDelete: "set null" }),
|
|
18044
|
-
actorAgentId: text("actor_agent_id"),
|
|
18045
|
-
action: text("action").notNull(),
|
|
18046
|
-
nodeId: text("node_id"),
|
|
18047
|
-
subjectType: text("subject_type"),
|
|
18048
|
-
subjectId: text("subject_id"),
|
|
18049
|
-
metadata: text("metadata"),
|
|
18050
|
-
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
|
|
18051
|
-
}, (t) => [
|
|
18052
|
-
index("activity_events_tenant_created_idx").on(t.tenantId, t.createdAt),
|
|
18053
|
-
index("activity_events_tenant_node_idx").on(t.tenantId, t.nodeId)
|
|
18054
|
-
]);
|
|
18055
|
-
|
|
18056
17889
|
// ../../packages/schema/src/db/places.ts
|
|
18057
17890
|
var placeKindValues = ["room", "building", "outdoor", "storage", "elsewhere"];
|
|
18058
17891
|
var places = pgTable("places", {
|
|
@@ -18069,7 +17902,14 @@ var places = pgTable("places", {
|
|
|
18069
17902
|
}, (t) => [index("places_tenant_idx").on(t.tenantId, t.levelOrder)]);
|
|
18070
17903
|
|
|
18071
17904
|
// ../../packages/schema/src/db/domain.ts
|
|
18072
|
-
var taskStatus = pgEnum("task_status", [
|
|
17905
|
+
var taskStatus = pgEnum("task_status", [
|
|
17906
|
+
"backlog",
|
|
17907
|
+
"todo",
|
|
17908
|
+
"in_progress",
|
|
17909
|
+
"waiting",
|
|
17910
|
+
"done",
|
|
17911
|
+
"cancelled"
|
|
17912
|
+
]);
|
|
18073
17913
|
var habitMeasurementType = pgEnum("habit_measurement_type", [
|
|
18074
17914
|
"binary",
|
|
18075
17915
|
"quantitative",
|
|
@@ -18098,6 +17938,9 @@ var occurrenceStatus = pgEnum("occurrence_status", [
|
|
|
18098
17938
|
var tasks = pgTable("tasks", {
|
|
18099
17939
|
...leafColumns(),
|
|
18100
17940
|
status: taskStatus("status").notNull().default("todo"),
|
|
17941
|
+
priority: workPriority("priority").notNull().default("none"),
|
|
17942
|
+
number: integer2("number").notNull().default(0),
|
|
17943
|
+
deliverable: text("deliverable"),
|
|
18101
17944
|
starred: boolean4("starred").notNull().default(false),
|
|
18102
17945
|
allDay: boolean4("all_day").notNull().default(true),
|
|
18103
17946
|
scheduledAt: timestamp("scheduled_at", { withTimezone: true }),
|
|
@@ -18142,6 +17985,7 @@ var tasks = pgTable("tasks", {
|
|
|
18142
17985
|
movedFrom: timestamp("moved_from", { withTimezone: true })
|
|
18143
17986
|
}, (t) => [
|
|
18144
17987
|
index("tasks_tenant_project_idx").on(t.tenantId, t.projectId),
|
|
17988
|
+
unique("tasks_tenant_number_uniq").on(t.tenantId, t.number),
|
|
18145
17989
|
index("tasks_tenant_place_idx").on(t.tenantId, t.placeId),
|
|
18146
17990
|
index("tasks_milestone_idx").on(t.milestoneId),
|
|
18147
17991
|
index("tasks_tenant_owner_agent_idx").on(t.tenantId, t.ownerAgentId, t.ownerDesk),
|
|
@@ -18176,7 +18020,10 @@ var habits = pgTable("habits", {
|
|
|
18176
18020
|
pausedFrom: date5("paused_from", { mode: "string" }),
|
|
18177
18021
|
pausedUntil: date5("paused_until", { mode: "string" }),
|
|
18178
18022
|
remind: boolean4("remind").notNull().default(false),
|
|
18179
|
-
retiredAt: timestamp("retired_at", { withTimezone: true })
|
|
18023
|
+
retiredAt: timestamp("retired_at", { withTimezone: true }),
|
|
18024
|
+
eventSourceId: text("event_source_id"),
|
|
18025
|
+
eventMatch: text("event_match"),
|
|
18026
|
+
eventOffset: text("event_offset")
|
|
18180
18027
|
}, (t) => [
|
|
18181
18028
|
index("habits_tenant_idx").on(t.tenantId),
|
|
18182
18029
|
index("habits_tenant_area_idx").on(t.tenantId, t.areaId),
|
|
@@ -18206,6 +18053,8 @@ var recurrenceRules = pgTable("recurrence_rules", {
|
|
|
18206
18053
|
interval: integer2("interval").notNull().default(1),
|
|
18207
18054
|
freq: recurrenceFreq("freq"),
|
|
18208
18055
|
byDay: text("by_day").array(),
|
|
18056
|
+
byMonthDay: integer2("by_month_day"),
|
|
18057
|
+
startsOn: date5("starts_on", { mode: "string" }),
|
|
18209
18058
|
timeOfDay: text("time_of_day"),
|
|
18210
18059
|
until: timestamp("until", { withTimezone: true }),
|
|
18211
18060
|
count: integer2("count"),
|
|
@@ -18301,10 +18150,12 @@ var routineRunSteps = pgTable("routine_run_steps", {
|
|
|
18301
18150
|
id: text("id").primaryKey(),
|
|
18302
18151
|
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
18303
18152
|
runId: text("run_id").notNull().references(() => routineRuns.id),
|
|
18304
|
-
stepId: text("step_id").
|
|
18153
|
+
stepId: text("step_id").references(() => routineSteps.id),
|
|
18305
18154
|
title: text("title").notNull(),
|
|
18306
18155
|
refKind: routineStepRef("ref_kind").notNull().default("free"),
|
|
18307
18156
|
habitId: text("habit_id").references(() => habits.id),
|
|
18157
|
+
taskId: text("task_id").references(() => tasks.id),
|
|
18158
|
+
reason: text("reason"),
|
|
18308
18159
|
habitEntryId: text("habit_entry_id").references(() => habitEntries.id),
|
|
18309
18160
|
sortOrder: integer2("sort_order").notNull().default(0),
|
|
18310
18161
|
durationMinutes: integer2("duration_minutes"),
|
|
@@ -18319,6 +18170,8 @@ var routineRunSteps = pgTable("routine_run_steps", {
|
|
|
18319
18170
|
var projects = pgTable("projects", {
|
|
18320
18171
|
...leafColumns(),
|
|
18321
18172
|
status: projectStatus("status").notNull().default("planning"),
|
|
18173
|
+
priority: workPriority("priority").notNull().default("none"),
|
|
18174
|
+
number: integer2("number").notNull().default(0),
|
|
18322
18175
|
icon: text("icon"),
|
|
18323
18176
|
progress: integer2("progress").notNull().default(0),
|
|
18324
18177
|
startAt: timestamp("start_at", { withTimezone: true }),
|
|
@@ -18329,6 +18182,7 @@ var projects = pgTable("projects", {
|
|
|
18329
18182
|
finishNotYetAt: timestamp("finish_not_yet_at", { withTimezone: true })
|
|
18330
18183
|
}, (t) => [
|
|
18331
18184
|
index("projects_tenant_idx").on(t.tenantId),
|
|
18185
|
+
unique("projects_tenant_number_uniq").on(t.tenantId, t.number),
|
|
18332
18186
|
index("projects_tenant_area_idx").on(t.tenantId, t.areaId)
|
|
18333
18187
|
]);
|
|
18334
18188
|
var projectMilestones = pgTable("project_milestones", {
|
|
@@ -18370,6 +18224,191 @@ var userSettings = pgTable("user_settings", {
|
|
|
18370
18224
|
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
18371
18225
|
}, (t) => [unique("user_settings_tenant_user_uniq").on(t.tenantId, t.userId)]);
|
|
18372
18226
|
|
|
18227
|
+
// ../../packages/schema/src/db/challenges.ts
|
|
18228
|
+
var challengeSource = pgEnum("challenge_source", ["self", "system"]);
|
|
18229
|
+
var challengeSubjectType = pgEnum("challenge_subject_type", ["habit", "area", "tag"]);
|
|
18230
|
+
var challengePartKind = pgEnum("challenge_part_kind", ["habit", "task_series"]);
|
|
18231
|
+
var challenges = pgTable("challenges", {
|
|
18232
|
+
id: text("id").primaryKey(),
|
|
18233
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id, { onDelete: "cascade" }),
|
|
18234
|
+
title: text("title").notNull(),
|
|
18235
|
+
description: text("description"),
|
|
18236
|
+
source: challengeSource("source").notNull().default("self"),
|
|
18237
|
+
metric: text("metric").notNull(),
|
|
18238
|
+
subjectType: challengeSubjectType("subject_type"),
|
|
18239
|
+
subjectId: text("subject_id"),
|
|
18240
|
+
target: integer2("target").notNull(),
|
|
18241
|
+
startAt: timestamp("start_at", { withTimezone: true }).notNull(),
|
|
18242
|
+
endAt: timestamp("end_at", { withTimezone: true }).notNull(),
|
|
18243
|
+
projectId: text("project_id").references(() => projects.id, { onDelete: "set null" }),
|
|
18244
|
+
createdBy: text("created_by").references(() => users.id, { onDelete: "set null" }),
|
|
18245
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
18246
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
18247
|
+
}, (t) => [
|
|
18248
|
+
index("challenges_tenant_idx").on(t.tenantId),
|
|
18249
|
+
index("challenges_tenant_window_idx").on(t.tenantId, t.startAt, t.endAt),
|
|
18250
|
+
index("challenges_tenant_subject_idx").on(t.tenantId, t.subjectType, t.subjectId),
|
|
18251
|
+
index("challenges_tenant_project_idx").on(t.tenantId, t.projectId),
|
|
18252
|
+
check2("challenges_subject_pair_chk", sql`(${t.subjectType} IS NULL) = (${t.subjectId} IS NULL)`)
|
|
18253
|
+
]);
|
|
18254
|
+
var challengeParticipants = pgTable("challenge_participants", {
|
|
18255
|
+
id: text("id").primaryKey(),
|
|
18256
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id, { onDelete: "cascade" }),
|
|
18257
|
+
challengeId: text("challenge_id").notNull().references(() => challenges.id, { onDelete: "cascade" }),
|
|
18258
|
+
userId: text("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
|
|
18259
|
+
joinedAt: timestamp("joined_at", { withTimezone: true }).notNull().defaultNow()
|
|
18260
|
+
}, (t) => [
|
|
18261
|
+
unique("challenge_participants_challenge_user_uniq").on(t.challengeId, t.userId),
|
|
18262
|
+
index("challenge_participants_tenant_idx").on(t.tenantId),
|
|
18263
|
+
index("challenge_participants_user_idx").on(t.tenantId, t.userId)
|
|
18264
|
+
]);
|
|
18265
|
+
var challengeParts = pgTable("challenge_parts", {
|
|
18266
|
+
id: text("id").primaryKey(),
|
|
18267
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id, { onDelete: "cascade" }),
|
|
18268
|
+
challengeId: text("challenge_id").notNull().references(() => challenges.id, { onDelete: "cascade" }),
|
|
18269
|
+
kind: challengePartKind("kind").notNull(),
|
|
18270
|
+
subjectId: text("subject_id").notNull(),
|
|
18271
|
+
position: integer2("position").notNull()
|
|
18272
|
+
}, (t) => [
|
|
18273
|
+
index("challenge_parts_tenant_idx").on(t.tenantId),
|
|
18274
|
+
index("challenge_parts_challenge_idx").on(t.challengeId, t.position),
|
|
18275
|
+
index("challenge_parts_tenant_subject_idx").on(t.tenantId, t.kind, t.subjectId)
|
|
18276
|
+
]);
|
|
18277
|
+
|
|
18278
|
+
// ../../packages/schema/src/db/collaboration.ts
|
|
18279
|
+
var capability = pgEnum("collab_capability", ["view", "comment", "edit", "admin"]);
|
|
18280
|
+
var grantSubjectType = pgEnum("grant_subject_type", ["member", "role"]);
|
|
18281
|
+
var inviteType = pgEnum("invite_type", ["email", "link", "join_request", "guest"]);
|
|
18282
|
+
var inviteStatus = pgEnum("invite_status", ["pending", "accepted", "revoked", "expired"]);
|
|
18283
|
+
var permissionSets = pgTable("permission_sets", {
|
|
18284
|
+
id: text("id").primaryKey(),
|
|
18285
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
18286
|
+
name: text("name").notNull(),
|
|
18287
|
+
canView: boolean4("can_view").notNull().default(true),
|
|
18288
|
+
canComment: boolean4("can_comment").notNull().default(false),
|
|
18289
|
+
canEdit: boolean4("can_edit").notNull().default(false),
|
|
18290
|
+
canShare: boolean4("can_share").notNull().default(false),
|
|
18291
|
+
canManageMembers: boolean4("can_manage_members").notNull().default(false),
|
|
18292
|
+
canManageRoles: boolean4("can_manage_roles").notNull().default(false),
|
|
18293
|
+
canManageSpace: boolean4("can_manage_space").notNull().default(false),
|
|
18294
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
18295
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
18296
|
+
}, (t) => [unique("permission_sets_tenant_name_uniq").on(t.tenantId, t.name)]);
|
|
18297
|
+
var roles = pgTable("roles", {
|
|
18298
|
+
id: text("id").primaryKey(),
|
|
18299
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
18300
|
+
name: text("name").notNull(),
|
|
18301
|
+
description: text("description"),
|
|
18302
|
+
permissionSetId: text("permission_set_id").notNull().references(() => permissionSets.id),
|
|
18303
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
18304
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
18305
|
+
}, (t) => [unique("roles_tenant_name_uniq").on(t.tenantId, t.name)]);
|
|
18306
|
+
var invites = pgTable("invites", {
|
|
18307
|
+
id: text("id").primaryKey(),
|
|
18308
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
18309
|
+
type: inviteType("type").notNull(),
|
|
18310
|
+
email: text("email"),
|
|
18311
|
+
token: text("token").unique(),
|
|
18312
|
+
tokenHash: text("token_hash").unique(),
|
|
18313
|
+
tokenSealed: text("token_sealed"),
|
|
18314
|
+
role: baseRole("role").notNull().default("member"),
|
|
18315
|
+
customRoleId: text("custom_role_id").references(() => roles.id),
|
|
18316
|
+
invitedByUserId: text("invited_by_user_id").references(() => users.id),
|
|
18317
|
+
status: inviteStatus("status").notNull().default("pending"),
|
|
18318
|
+
accessUntil: timestamp("access_until", { withTimezone: true }),
|
|
18319
|
+
expiresAt: timestamp("expires_at", { withTimezone: true }),
|
|
18320
|
+
acceptedAt: timestamp("accepted_at", { withTimezone: true }),
|
|
18321
|
+
acceptedByUserId: text("accepted_by_user_id").references(() => users.id),
|
|
18322
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
18323
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
18324
|
+
}, (t) => [index("invites_tenant_status_idx").on(t.tenantId, t.status)]);
|
|
18325
|
+
var nodeGrants = pgTable("node_grants", {
|
|
18326
|
+
id: text("id").primaryKey(),
|
|
18327
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
18328
|
+
nodeId: text("node_id").notNull().references(() => nodes.id),
|
|
18329
|
+
subjectType: grantSubjectType("subject_type").notNull(),
|
|
18330
|
+
subjectId: text("subject_id").notNull(),
|
|
18331
|
+
capability: capability("capability").notNull(),
|
|
18332
|
+
assigned: boolean4("assigned").notNull().default(false),
|
|
18333
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
18334
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
18335
|
+
}, (t) => [
|
|
18336
|
+
unique("node_grants_node_subject_uniq").on(t.tenantId, t.nodeId, t.subjectType, t.subjectId),
|
|
18337
|
+
index("node_grants_tenant_node_idx").on(t.tenantId, t.nodeId),
|
|
18338
|
+
index("node_grants_node_idx").on(t.nodeId)
|
|
18339
|
+
]);
|
|
18340
|
+
var shareLinks = pgTable("share_links", {
|
|
18341
|
+
id: text("id").primaryKey(),
|
|
18342
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
18343
|
+
nodeId: text("node_id").notNull().references(() => nodes.id),
|
|
18344
|
+
tokenHash: text("token_hash").notNull().unique(),
|
|
18345
|
+
capability: capability("capability").notNull().default("view"),
|
|
18346
|
+
createdByUserId: text("created_by_user_id").references(() => users.id),
|
|
18347
|
+
expiresAt: timestamp("expires_at", { withTimezone: true }),
|
|
18348
|
+
revokedAt: timestamp("revoked_at", { withTimezone: true }),
|
|
18349
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
18350
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
18351
|
+
}, (t) => [
|
|
18352
|
+
index("share_links_tenant_node_idx").on(t.tenantId, t.nodeId),
|
|
18353
|
+
index("share_links_node_idx").on(t.nodeId)
|
|
18354
|
+
]);
|
|
18355
|
+
var shareLinkGuests = pgTable("share_link_guests", {
|
|
18356
|
+
id: text("id").primaryKey(),
|
|
18357
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
18358
|
+
shareLinkId: text("share_link_id").notNull().references(() => shareLinks.id, { onDelete: "cascade" }),
|
|
18359
|
+
name: text("name").notNull(),
|
|
18360
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
|
|
18361
|
+
}, (t) => [
|
|
18362
|
+
uniqueIndex("share_link_guests_link_name_uniq").on(t.shareLinkId, sql`lower(${t.name})`),
|
|
18363
|
+
index("share_link_guests_tenant_idx").on(t.tenantId)
|
|
18364
|
+
]);
|
|
18365
|
+
var comments = pgTable("comments", {
|
|
18366
|
+
id: text("id").primaryKey(),
|
|
18367
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
18368
|
+
nodeId: text("node_id").notNull().references(() => nodes.id),
|
|
18369
|
+
parentId: text("parent_id").references(() => comments.id),
|
|
18370
|
+
authorUserId: text("author_user_id").notNull().references(() => users.id),
|
|
18371
|
+
body: text("body").notNull(),
|
|
18372
|
+
editedAt: timestamp("edited_at", { withTimezone: true }),
|
|
18373
|
+
deletedAt: timestamp("deleted_at", { withTimezone: true }),
|
|
18374
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
18375
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
18376
|
+
}, (t) => [
|
|
18377
|
+
index("comments_tenant_node_created_idx").on(t.tenantId, t.nodeId, t.createdAt),
|
|
18378
|
+
index("comments_parent_idx").on(t.parentId),
|
|
18379
|
+
index("comments_node_idx").on(t.nodeId)
|
|
18380
|
+
]);
|
|
18381
|
+
var commentMentions = pgTable("comment_mentions", {
|
|
18382
|
+
id: text("id").primaryKey(),
|
|
18383
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
18384
|
+
commentId: text("comment_id").notNull().references(() => comments.id),
|
|
18385
|
+
mentionedUserId: text("mentioned_user_id").notNull().references(() => users.id),
|
|
18386
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
|
|
18387
|
+
}, (t) => [unique("comment_mentions_comment_user_uniq").on(t.commentId, t.mentionedUserId)]);
|
|
18388
|
+
var commentReactions = pgTable("comment_reactions", {
|
|
18389
|
+
id: text("id").primaryKey(),
|
|
18390
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
18391
|
+
commentId: text("comment_id").notNull().references(() => comments.id),
|
|
18392
|
+
userId: text("user_id").notNull().references(() => users.id),
|
|
18393
|
+
emoji: text("emoji").notNull(),
|
|
18394
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
|
|
18395
|
+
}, (t) => [unique("comment_reactions_comment_user_emoji_uniq").on(t.commentId, t.userId, t.emoji)]);
|
|
18396
|
+
var activityEvents = pgTable("activity_events", {
|
|
18397
|
+
id: text("id").primaryKey(),
|
|
18398
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id, { onDelete: "cascade" }),
|
|
18399
|
+
actorUserId: text("actor_user_id").references(() => users.id, { onDelete: "set null" }),
|
|
18400
|
+
actorAgentId: text("actor_agent_id"),
|
|
18401
|
+
action: text("action").notNull(),
|
|
18402
|
+
nodeId: text("node_id"),
|
|
18403
|
+
subjectType: text("subject_type"),
|
|
18404
|
+
subjectId: text("subject_id"),
|
|
18405
|
+
metadata: text("metadata"),
|
|
18406
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
|
|
18407
|
+
}, (t) => [
|
|
18408
|
+
index("activity_events_tenant_created_idx").on(t.tenantId, t.createdAt),
|
|
18409
|
+
index("activity_events_tenant_node_idx").on(t.tenantId, t.nodeId)
|
|
18410
|
+
]);
|
|
18411
|
+
|
|
18373
18412
|
// ../../packages/schema/src/db/contacts.ts
|
|
18374
18413
|
var contactKind = pgEnum("contact_kind", ["person", "organization"]);
|
|
18375
18414
|
var contacts = pgTable("contacts", {
|
|
@@ -18995,6 +19034,9 @@ var areaColorSchema = _enum2(areaColor.enumValues);
|
|
|
18995
19034
|
var reviewCadenceSchema = _enum2(reviewCadence.enumValues);
|
|
18996
19035
|
var projectStatusSchema = _enum2(projectStatus.enumValues);
|
|
18997
19036
|
var taskStatusSchema = _enum2(taskStatus.enumValues);
|
|
19037
|
+
var workPrioritySchema = _enum2(workPriority.enumValues);
|
|
19038
|
+
var OPEN_TASK_STATUSES = ["backlog", "todo", "in_progress", "waiting"];
|
|
19039
|
+
var BOARD_TASK_STATUSES = [...OPEN_TASK_STATUSES, "done"];
|
|
18998
19040
|
var routineKindSchema = _enum2(routineKind.enumValues);
|
|
18999
19041
|
var routineStepRefSchema = _enum2(routineStepRef.enumValues);
|
|
19000
19042
|
var routineRunStatusSchema = _enum2(routineRunStatus.enumValues);
|
|
@@ -19387,7 +19429,13 @@ var spaceSchema = createSelectSchema(tenants, {
|
|
|
19387
19429
|
createdAt: exports_coerce.date(),
|
|
19388
19430
|
updatedAt: exports_coerce.date(),
|
|
19389
19431
|
deletedAt: exports_coerce.date().nullable()
|
|
19390
|
-
}).omit({
|
|
19432
|
+
}).omit({
|
|
19433
|
+
gaardHouseUrl: true,
|
|
19434
|
+
awayFrom: true,
|
|
19435
|
+
awayUntil: true,
|
|
19436
|
+
lastTaskNumber: true,
|
|
19437
|
+
lastProjectNumber: true
|
|
19438
|
+
});
|
|
19391
19439
|
var backdropIdSchema = string2().trim().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, "a backdrop id is lowercase words joined by dashes").max(40);
|
|
19392
19440
|
var updateSpaceInputSchema = object({
|
|
19393
19441
|
name: string2().trim().min(1).max(120).optional(),
|
|
@@ -21226,6 +21274,75 @@ var animalOperations = defineOperations({
|
|
|
21226
21274
|
// ../../packages/schema/src/contracts/habit-sources.ts
|
|
21227
21275
|
var habitSourceSchema = _enum2(["manual", "google_fit", "strava", "github"]);
|
|
21228
21276
|
|
|
21277
|
+
// ../../packages/schema/src/contracts/recurrence.ts
|
|
21278
|
+
var recurrenceRuleSchema = createSelectSchema(recurrenceRules, {
|
|
21279
|
+
until: exports_coerce.date().nullable(),
|
|
21280
|
+
byMonthDay: number2().int().nullable().default(null),
|
|
21281
|
+
startsOn: exports_iso.date().nullable().default(null)
|
|
21282
|
+
});
|
|
21283
|
+
var occurrenceSchema = createSelectSchema(occurrences, {
|
|
21284
|
+
occurrenceDate: exports_coerce.date(),
|
|
21285
|
+
completedAt: exports_coerce.date().nullable()
|
|
21286
|
+
});
|
|
21287
|
+
var byDayCodeSchema = _enum2(["MO", "TU", "WE", "TH", "FR", "SA", "SU"]);
|
|
21288
|
+
var byDayOrdinalSchema = _enum2(["1", "2", "3", "4", "-1"]);
|
|
21289
|
+
var byDaySchema = union([
|
|
21290
|
+
byDayCodeSchema,
|
|
21291
|
+
templateLiteral([byDayOrdinalSchema, byDayCodeSchema])
|
|
21292
|
+
]);
|
|
21293
|
+
var BY_DAY_RE = /^(-1|[1-4])?(MO|TU|WE|TH|FR|SA|SU)$/;
|
|
21294
|
+
function parseByDay(code) {
|
|
21295
|
+
const m = BY_DAY_RE.exec(code);
|
|
21296
|
+
if (!m)
|
|
21297
|
+
return null;
|
|
21298
|
+
return { ordinal: m[1] ? Number(m[1]) : null, weekday: m[2] };
|
|
21299
|
+
}
|
|
21300
|
+
var recurrenceRuleParams = {
|
|
21301
|
+
timezone: string2().min(1).default("UTC"),
|
|
21302
|
+
interval: number2().int().positive().default(1),
|
|
21303
|
+
mode: recurrenceModeSchema,
|
|
21304
|
+
timeOfDay: string2().regex(/^([01]\d|2[0-3]):[0-5]\d$/, "time-of-day must be HH:MM (24h)").nullish(),
|
|
21305
|
+
freq: recurrenceFreqSchema.optional(),
|
|
21306
|
+
byDay: array(byDaySchema).optional(),
|
|
21307
|
+
until: exports_coerce.date().optional(),
|
|
21308
|
+
count: number2().int().positive().optional(),
|
|
21309
|
+
unit: recurrenceUnitSchema.optional(),
|
|
21310
|
+
anchor: recurrenceAnchorSchema.optional()
|
|
21311
|
+
};
|
|
21312
|
+
function refineRecurrenceRule(v, ctx) {
|
|
21313
|
+
if (v.mode === "rigid" && !v.freq) {
|
|
21314
|
+
ctx.addIssue({ code: "custom", path: ["freq"], message: "rigid rules require a freq" });
|
|
21315
|
+
}
|
|
21316
|
+
const ordinal = v.byDay?.findIndex((code) => parseByDay(code)?.ordinal != null) ?? -1;
|
|
21317
|
+
if (ordinal >= 0 && v.freq !== "monthly" && v.freq !== "yearly") {
|
|
21318
|
+
ctx.addIssue({
|
|
21319
|
+
code: "custom",
|
|
21320
|
+
path: ["byDay", ordinal],
|
|
21321
|
+
message: "an ordinal weekday (1SU, -1FR) needs a monthly or yearly freq"
|
|
21322
|
+
});
|
|
21323
|
+
}
|
|
21324
|
+
if (v.mode === "flexible") {
|
|
21325
|
+
if (!v.unit) {
|
|
21326
|
+
ctx.addIssue({ code: "custom", path: ["unit"], message: "flexible rules require a unit" });
|
|
21327
|
+
}
|
|
21328
|
+
if (!v.anchor) {
|
|
21329
|
+
ctx.addIssue({
|
|
21330
|
+
code: "custom",
|
|
21331
|
+
path: ["anchor"],
|
|
21332
|
+
message: "flexible rules require an anchor"
|
|
21333
|
+
});
|
|
21334
|
+
}
|
|
21335
|
+
}
|
|
21336
|
+
}
|
|
21337
|
+
var createRecurrenceRuleInputSchema = object({
|
|
21338
|
+
templateId: ulidSchema,
|
|
21339
|
+
...recurrenceRuleParams
|
|
21340
|
+
}).superRefine(refineRecurrenceRule);
|
|
21341
|
+
var updateRecurrenceRuleInputSchema = object({ ...recurrenceRuleParams }).superRefine(refineRecurrenceRule);
|
|
21342
|
+
var updateOccurrenceInputSchema = createUpdateSchema(occurrences, {
|
|
21343
|
+
occurrenceDate: exports_coerce.date().optional()
|
|
21344
|
+
}).pick({ occurrenceDate: true, status: true }).strict();
|
|
21345
|
+
|
|
21229
21346
|
// ../../packages/schema/src/contracts/habits.ts
|
|
21230
21347
|
var habitSchema = createSelectSchema(habits, {
|
|
21231
21348
|
source: habitSourceSchema.default("manual"),
|
|
@@ -21235,7 +21352,10 @@ var habitSchema = createSelectSchema(habits, {
|
|
|
21235
21352
|
pausedFrom: exports_iso.date().nullable().default(null),
|
|
21236
21353
|
pausedUntil: exports_iso.date().nullable().default(null),
|
|
21237
21354
|
remind: boolean2().default(false),
|
|
21238
|
-
retiredAt: exports_coerce.date().nullable().default(null)
|
|
21355
|
+
retiredAt: exports_coerce.date().nullable().default(null),
|
|
21356
|
+
eventSourceId: string2().nullable().default(null),
|
|
21357
|
+
eventMatch: string2().nullable().default(null),
|
|
21358
|
+
eventOffset: string2().nullable().default(null)
|
|
21239
21359
|
});
|
|
21240
21360
|
var habitEntrySchema = createSelectSchema(habitEntries, {
|
|
21241
21361
|
occurredAt: exports_coerce.date(),
|
|
@@ -21254,6 +21374,30 @@ var habitTimeOfDaySchema = union([
|
|
|
21254
21374
|
]);
|
|
21255
21375
|
var habitAliasSchema = string2().trim().min(1).max(60);
|
|
21256
21376
|
var habitAliasesSchema = array(habitAliasSchema).max(12).transform((aliases) => aliases.filter((a, i) => aliases.findIndex((b) => b.toLowerCase() === a.toLowerCase()) === i));
|
|
21377
|
+
var habitScheduleSchema = discriminatedUnion("kind", [
|
|
21378
|
+
object({ kind: literal("daily") }),
|
|
21379
|
+
object({
|
|
21380
|
+
kind: literal("weekdays"),
|
|
21381
|
+
days: array(byDayCodeSchema).min(1).max(7).refine((days) => new Set(days).size === days.length, "each weekday once")
|
|
21382
|
+
}),
|
|
21383
|
+
object({
|
|
21384
|
+
kind: literal("every"),
|
|
21385
|
+
interval: number2().int().min(2),
|
|
21386
|
+
unit: _enum2(["day", "week"]),
|
|
21387
|
+
anchor: exports_iso.date()
|
|
21388
|
+
}),
|
|
21389
|
+
object({
|
|
21390
|
+
kind: literal("monthly"),
|
|
21391
|
+
dayOfMonth: union([number2().int().min(1).max(31), literal(-1)])
|
|
21392
|
+
}),
|
|
21393
|
+
object({
|
|
21394
|
+
kind: literal("event"),
|
|
21395
|
+
sourceId: ulidSchema,
|
|
21396
|
+
match: string2().trim().min(1).max(120),
|
|
21397
|
+
offset: _enum2(["day_before_evening", "same_day"])
|
|
21398
|
+
})
|
|
21399
|
+
]);
|
|
21400
|
+
var eventColumns = { eventSourceId: true, eventMatch: true, eventOffset: true };
|
|
21257
21401
|
var createHabitInputSchema = createInsertSchema(habits, {
|
|
21258
21402
|
id: ulidSchema,
|
|
21259
21403
|
source: habitSourceSchema.optional(),
|
|
@@ -21267,8 +21411,9 @@ var createHabitInputSchema = createInsertSchema(habits, {
|
|
|
21267
21411
|
aliases: habitAliasesSchema.optional(),
|
|
21268
21412
|
timeOfDay: habitTimeOfDaySchema.nullish(),
|
|
21269
21413
|
remind: boolean2().optional()
|
|
21270
|
-
}).omit({ tenantId: true, recurrenceRuleId: true, retiredAt: true }).extend({
|
|
21414
|
+
}).omit({ tenantId: true, recurrenceRuleId: true, retiredAt: true, ...eventColumns }).extend({
|
|
21271
21415
|
title: string2().min(1),
|
|
21416
|
+
schedule: habitScheduleSchema.optional(),
|
|
21272
21417
|
displayKind: string2().min(1).nullish()
|
|
21273
21418
|
});
|
|
21274
21419
|
var updateHabitInputSchema = createUpdateSchema(habits, {
|
|
@@ -21289,8 +21434,12 @@ var updateHabitInputSchema = createUpdateSchema(habits, {
|
|
|
21289
21434
|
recurrenceRuleId: true,
|
|
21290
21435
|
pausedFrom: true,
|
|
21291
21436
|
pausedUntil: true,
|
|
21292
|
-
retiredAt: true
|
|
21293
|
-
|
|
21437
|
+
retiredAt: true,
|
|
21438
|
+
...eventColumns
|
|
21439
|
+
}).extend({
|
|
21440
|
+
title: string2().min(1).optional(),
|
|
21441
|
+
schedule: habitScheduleSchema.optional()
|
|
21442
|
+
});
|
|
21294
21443
|
var HABIT_ENTRY_NOTE_MAX = 280;
|
|
21295
21444
|
var habitEntryNoteSchema = string2().trim().max(HABIT_ENTRY_NOTE_MAX).transform((note) => note === "" ? null : note);
|
|
21296
21445
|
var createHabitEntryInputSchema = createInsertSchema(habitEntries, {
|
|
@@ -21344,7 +21493,9 @@ var habitSummarySchema = habitSchema.extend({
|
|
|
21344
21493
|
inRoutines: array(habitRoutineRefSchema).default([]),
|
|
21345
21494
|
lastCheckIn: habitLastCheckInSchema.nullable().default(null),
|
|
21346
21495
|
pause: habitPauseSchema.nullable().default(null),
|
|
21347
|
-
today: habitTodaySchema.default({ due: true, done: false })
|
|
21496
|
+
today: habitTodaySchema.default({ due: true, done: false }),
|
|
21497
|
+
schedule: habitScheduleSchema.default({ kind: "daily" }),
|
|
21498
|
+
nextDue: array(exports_iso.date()).default([])
|
|
21348
21499
|
});
|
|
21349
21500
|
var habitHeatmapCellSchema = object({
|
|
21350
21501
|
date: string2(),
|
|
@@ -21598,6 +21749,17 @@ var noteMadeTaskSchema = object({
|
|
|
21598
21749
|
createdAt: exports_coerce.date(),
|
|
21599
21750
|
by: noteActorSchema
|
|
21600
21751
|
}).strict();
|
|
21752
|
+
var noteChecklistItemSchema = object({
|
|
21753
|
+
line: number2().int().nonnegative(),
|
|
21754
|
+
taskId: ulidSchema.nullable(),
|
|
21755
|
+
title: string2(),
|
|
21756
|
+
status: string2().nullable(),
|
|
21757
|
+
done: boolean2(),
|
|
21758
|
+
scheduledOn: exports_coerce.date().nullable(),
|
|
21759
|
+
completedAt: exports_coerce.date().nullable(),
|
|
21760
|
+
projectId: ulidSchema.nullable(),
|
|
21761
|
+
projectTitle: string2().nullable()
|
|
21762
|
+
}).strict();
|
|
21601
21763
|
var noteDetailsSchema = object({
|
|
21602
21764
|
noteId: ulidSchema,
|
|
21603
21765
|
links: array(noteLinkedNodeSchema),
|
|
@@ -21606,9 +21768,66 @@ var noteDetailsSchema = object({
|
|
|
21606
21768
|
createdBy: noteActorSchema,
|
|
21607
21769
|
editedBy: noteActorSchema,
|
|
21608
21770
|
seenBy: array(string2()),
|
|
21609
|
-
madeTasks: array(noteMadeTaskSchema)
|
|
21771
|
+
madeTasks: array(noteMadeTaskSchema),
|
|
21772
|
+
checklist: array(noteChecklistItemSchema).default([])
|
|
21610
21773
|
}).strict();
|
|
21611
21774
|
|
|
21775
|
+
// ../../packages/schema/src/db/project-updates.ts
|
|
21776
|
+
var projectUpdateStatus = pgEnum("project_update_status", [
|
|
21777
|
+
"on_track",
|
|
21778
|
+
"at_risk",
|
|
21779
|
+
"off_track",
|
|
21780
|
+
"milestone_done",
|
|
21781
|
+
"done"
|
|
21782
|
+
]);
|
|
21783
|
+
var PROJECT_UPDATE_BODY_MAX = 2000;
|
|
21784
|
+
var projectUpdates = pgTable("project_updates", {
|
|
21785
|
+
id: text("id").primaryKey(),
|
|
21786
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
21787
|
+
projectId: text("project_id").notNull().references(() => projects.id, { onDelete: "cascade" }),
|
|
21788
|
+
status: projectUpdateStatus("status").notNull(),
|
|
21789
|
+
body: text("body").notNull().default(""),
|
|
21790
|
+
authorUserId: text("author_user_id").references(() => users.id),
|
|
21791
|
+
authorAgentId: text("author_agent_id").references(() => agents.id),
|
|
21792
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
|
|
21793
|
+
}, (t) => [
|
|
21794
|
+
index("project_updates_project_created_idx").on(t.tenantId, t.projectId, t.createdAt),
|
|
21795
|
+
check2("project_updates_one_author_chk", sql`(${t.authorUserId} IS NULL) <> (${t.authorAgentId} IS NULL)`),
|
|
21796
|
+
check2("project_updates_body_len_chk", sql`char_length(${t.body}) <= 2000`)
|
|
21797
|
+
]);
|
|
21798
|
+
var projectLeads = pgTable("project_leads", {
|
|
21799
|
+
id: text("id").primaryKey(),
|
|
21800
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
21801
|
+
projectId: text("project_id").notNull().references(() => projects.id, { onDelete: "cascade" }),
|
|
21802
|
+
userId: text("user_id").notNull().references(() => users.id),
|
|
21803
|
+
position: integer2("position").notNull().default(0)
|
|
21804
|
+
}, (t) => [
|
|
21805
|
+
index("project_leads_project_idx").on(t.tenantId, t.projectId, t.position),
|
|
21806
|
+
unique("project_leads_project_user_uniq").on(t.projectId, t.userId),
|
|
21807
|
+
index("project_leads_user_idx").on(t.userId)
|
|
21808
|
+
]);
|
|
21809
|
+
|
|
21810
|
+
// ../../packages/schema/src/contracts/work-refs.ts
|
|
21811
|
+
var WORK_REF_PREFIX = "DO";
|
|
21812
|
+
var REF_RE = new RegExp(`^${WORK_REF_PREFIX}-(P)?([1-9]\\d{0,8})$`, "i");
|
|
21813
|
+
function parseWorkRef(raw) {
|
|
21814
|
+
const m = REF_RE.exec(raw.trim());
|
|
21815
|
+
if (!m)
|
|
21816
|
+
return null;
|
|
21817
|
+
return { kind: m[1] ? "project" : "task", number: Number(m[2]) };
|
|
21818
|
+
}
|
|
21819
|
+
|
|
21820
|
+
// ../../packages/schema/src/contracts/task-blocks.ts
|
|
21821
|
+
var taskIdOrRefSchema = string2().trim().refine((raw) => ulidSchema.safeParse(raw).success || parseWorkRef(raw)?.kind === "task", "a task's ULID or its ref, like DO-147");
|
|
21822
|
+
var addTaskBlockerInputSchema = object({ taskId: taskIdOrRefSchema }).strict();
|
|
21823
|
+
var taskBlockerSchema = object({
|
|
21824
|
+
id: ulidSchema,
|
|
21825
|
+
ref: string2().nullable(),
|
|
21826
|
+
title: string2(),
|
|
21827
|
+
status: taskStatusSchema,
|
|
21828
|
+
dueAt: exports_coerce.date().nullable()
|
|
21829
|
+
});
|
|
21830
|
+
|
|
21612
21831
|
// ../../packages/schema/src/contracts/task-source.ts
|
|
21613
21832
|
var taskSourceSchema = object({
|
|
21614
21833
|
kind: string2().trim().min(1).max(40),
|
|
@@ -21763,6 +21982,9 @@ var worktreeLinkListQuerySchema = object({
|
|
|
21763
21982
|
|
|
21764
21983
|
// ../../packages/schema/src/contracts/tasks.ts
|
|
21765
21984
|
var taskSchema = createSelectSchema(tasks, {
|
|
21985
|
+
priority: workPrioritySchema.default("none"),
|
|
21986
|
+
number: number2().int().nonnegative().default(0),
|
|
21987
|
+
deliverable: string2().nullable().default(null),
|
|
21766
21988
|
scheduledAt: exports_coerce.date().nullable(),
|
|
21767
21989
|
startAt: exports_coerce.date().nullable(),
|
|
21768
21990
|
dueAt: exports_coerce.date().nullable(),
|
|
@@ -21832,6 +22054,7 @@ var taskFilingSuggestionSchema = object({
|
|
|
21832
22054
|
});
|
|
21833
22055
|
var completedAtInputSchema = exports_coerce.date().refine((d) => d.getTime() <= Date.now() + 60000, "completedAt can't be in the future").nullish();
|
|
21834
22056
|
var taskNextStepSchema = string2().trim().min(1).max(500);
|
|
22057
|
+
var taskDeliverableSchema = string2().trim().min(1).max(500);
|
|
21835
22058
|
var taskViewSchema = taskSchema.omit({
|
|
21836
22059
|
ownerUserId: true,
|
|
21837
22060
|
ownerAgentId: true,
|
|
@@ -21847,6 +22070,7 @@ var taskViewSchema = taskSchema.omit({
|
|
|
21847
22070
|
movedFrom: true
|
|
21848
22071
|
}).extend({
|
|
21849
22072
|
title: string2(),
|
|
22073
|
+
ref: string2().nullable().default(null),
|
|
21850
22074
|
parentId: ulidSchema.nullable(),
|
|
21851
22075
|
sortOrder: number2().int().nonnegative().default(0),
|
|
21852
22076
|
createdAt: exports_coerce.date(),
|
|
@@ -21862,7 +22086,10 @@ var taskViewSchema = taskSchema.omit({
|
|
|
21862
22086
|
nextStep: string2().nullable().default(null),
|
|
21863
22087
|
completedBy: actorRefSchema.nullable().default(null),
|
|
21864
22088
|
worktreeLink: worktreeLinkSchema.nullable().default(null),
|
|
21865
|
-
filingSuggestion: taskFilingSuggestionSchema.nullable().default(null)
|
|
22089
|
+
filingSuggestion: taskFilingSuggestionSchema.nullable().default(null),
|
|
22090
|
+
blockedBy: array(taskBlockerSchema).default([]),
|
|
22091
|
+
blocks: number2().int().nonnegative().default(0),
|
|
22092
|
+
isBlocked: boolean2().default(false)
|
|
21866
22093
|
});
|
|
21867
22094
|
var taskProjectIdSchema = ulidSchema.nullish();
|
|
21868
22095
|
var taskAreaIdSchema = ulidSchema.nullish();
|
|
@@ -21878,9 +22105,11 @@ var createTaskInputSchema = createInsertSchema(tasks, {
|
|
|
21878
22105
|
areaId: taskAreaIdSchema,
|
|
21879
22106
|
placeId: ulidSchema.nullish(),
|
|
21880
22107
|
milestoneId: ulidSchema.nullish(),
|
|
21881
|
-
somedayAt: exports_coerce.date().nullish()
|
|
22108
|
+
somedayAt: exports_coerce.date().nullish(),
|
|
22109
|
+
deliverable: taskDeliverableSchema.nullish()
|
|
21882
22110
|
}).omit({
|
|
21883
22111
|
tenantId: true,
|
|
22112
|
+
number: true,
|
|
21884
22113
|
recurrenceRuleId: true,
|
|
21885
22114
|
startAt: true,
|
|
21886
22115
|
ownerUserId: true,
|
|
@@ -21928,10 +22157,12 @@ var updateTaskInputSchema = createUpdateSchema(tasks, {
|
|
|
21928
22157
|
areaId: taskAreaIdSchema,
|
|
21929
22158
|
placeId: ulidSchema.nullish(),
|
|
21930
22159
|
milestoneId: ulidSchema.nullish(),
|
|
21931
|
-
somedayAt: exports_coerce.date().nullish()
|
|
22160
|
+
somedayAt: exports_coerce.date().nullish(),
|
|
22161
|
+
deliverable: taskDeliverableSchema.nullish()
|
|
21932
22162
|
}).omit({
|
|
21933
22163
|
id: true,
|
|
21934
22164
|
tenantId: true,
|
|
22165
|
+
number: true,
|
|
21935
22166
|
recurrenceRuleId: true,
|
|
21936
22167
|
startAt: true,
|
|
21937
22168
|
ownerUserId: true,
|
|
@@ -21971,6 +22202,8 @@ var taskListFilterSchema = _enum2(["all", "unsorted", "starred"]);
|
|
|
21971
22202
|
|
|
21972
22203
|
// ../../packages/schema/src/contracts/projects.ts
|
|
21973
22204
|
var projectSchema = createSelectSchema(projects, {
|
|
22205
|
+
priority: workPrioritySchema.default("none"),
|
|
22206
|
+
number: number2().int().nonnegative().default(0),
|
|
21974
22207
|
icon: string2().nullable().default(null),
|
|
21975
22208
|
startAt: exports_coerce.date().nullable(),
|
|
21976
22209
|
dueAt: exports_coerce.date().nullable(),
|
|
@@ -21998,7 +22231,13 @@ var createProjectInputSchema = createInsertSchema(projects, {
|
|
|
21998
22231
|
dueAt: exports_coerce.date().nullish(),
|
|
21999
22232
|
areaId: ulidSchema.nullish(),
|
|
22000
22233
|
icon: projectIconSchema.nullish()
|
|
22001
|
-
}).omit({
|
|
22234
|
+
}).omit({
|
|
22235
|
+
tenantId: true,
|
|
22236
|
+
number: true,
|
|
22237
|
+
completedAt: true,
|
|
22238
|
+
finishProposedAt: true,
|
|
22239
|
+
finishNotYetAt: true
|
|
22240
|
+
}).extend({
|
|
22002
22241
|
title: string2().min(1),
|
|
22003
22242
|
parentId: ulidSchema.nullish(),
|
|
22004
22243
|
milestones: array(projectMilestoneInputSchema).optional(),
|
|
@@ -22010,15 +22249,39 @@ var updateProjectInputSchema = createUpdateSchema(projects, {
|
|
|
22010
22249
|
dueAt: exports_coerce.date().nullish(),
|
|
22011
22250
|
areaId: ulidSchema.nullish(),
|
|
22012
22251
|
icon: projectIconSchema.nullish()
|
|
22013
|
-
}).omit({ id: true, tenantId: true, completedAt: true, finishProposedAt: true }).extend({
|
|
22252
|
+
}).omit({ id: true, tenantId: true, number: true, completedAt: true, finishProposedAt: true }).extend({
|
|
22014
22253
|
title: string2().min(1).optional(),
|
|
22015
22254
|
finishNotYetAt: exports_coerce.date().nullish(),
|
|
22016
22255
|
parentId: ulidSchema.nullish(),
|
|
22017
22256
|
milestones: array(projectMilestoneInputSchema).optional(),
|
|
22018
|
-
notes: string2().nullish()
|
|
22257
|
+
notes: string2().nullish(),
|
|
22258
|
+
leadUserIds: array(ulidSchema).max(20).refine((ids) => new Set(ids).size === ids.length, "each lead once").optional()
|
|
22259
|
+
}).strict();
|
|
22260
|
+
var projectUpdateStatusSchema = _enum2(projectUpdateStatus.enumValues);
|
|
22261
|
+
var projectUpdateViewSchema = object({
|
|
22262
|
+
id: ulidSchema,
|
|
22263
|
+
projectId: ulidSchema,
|
|
22264
|
+
status: projectUpdateStatusSchema,
|
|
22265
|
+
body: string2(),
|
|
22266
|
+
authorUserId: string2().nullable(),
|
|
22267
|
+
authorAgentId: string2().nullable(),
|
|
22268
|
+
authorName: string2(),
|
|
22269
|
+
createdAt: exports_coerce.date()
|
|
22270
|
+
});
|
|
22271
|
+
var createProjectUpdateInputSchema = object({
|
|
22272
|
+
id: ulidSchema.optional(),
|
|
22273
|
+
status: projectUpdateStatusSchema,
|
|
22274
|
+
body: string2().trim().max(PROJECT_UPDATE_BODY_MAX).default("")
|
|
22019
22275
|
}).strict();
|
|
22276
|
+
var projectLatestUpdateSchema = object({
|
|
22277
|
+
id: ulidSchema,
|
|
22278
|
+
status: projectUpdateStatusSchema,
|
|
22279
|
+
createdAt: exports_coerce.date()
|
|
22280
|
+
});
|
|
22281
|
+
var projectLeadSchema = object({ userId: ulidSchema, name: string2() });
|
|
22020
22282
|
var projectViewSchema = projectSchema.extend({
|
|
22021
22283
|
title: string2(),
|
|
22284
|
+
ref: string2().nullable().default(null),
|
|
22022
22285
|
parentId: ulidSchema.nullable(),
|
|
22023
22286
|
createdAt: exports_coerce.date(),
|
|
22024
22287
|
updatedAt: exports_coerce.date(),
|
|
@@ -22029,7 +22292,9 @@ var projectViewSchema = projectSchema.extend({
|
|
|
22029
22292
|
taskCount: number2().int().min(0),
|
|
22030
22293
|
completedTaskCount: number2().int().min(0),
|
|
22031
22294
|
worktreeLink: worktreeLinkSchema.nullable().default(null),
|
|
22032
|
-
milestones: array(projectMilestoneSchema).default([])
|
|
22295
|
+
milestones: array(projectMilestoneSchema).default([]),
|
|
22296
|
+
leads: array(projectLeadSchema).default([]),
|
|
22297
|
+
latestUpdate: projectLatestUpdateSchema.nullable().default(null)
|
|
22033
22298
|
});
|
|
22034
22299
|
var projectDetailSchema = projectViewSchema.extend({
|
|
22035
22300
|
milestones: array(projectMilestoneSchema),
|
|
@@ -22037,73 +22302,6 @@ var projectDetailSchema = projectViewSchema.extend({
|
|
|
22037
22302
|
});
|
|
22038
22303
|
var attachTaskInputSchema = object({ taskId: ulidSchema });
|
|
22039
22304
|
|
|
22040
|
-
// ../../packages/schema/src/contracts/recurrence.ts
|
|
22041
|
-
var recurrenceRuleSchema = createSelectSchema(recurrenceRules, {
|
|
22042
|
-
until: exports_coerce.date().nullable()
|
|
22043
|
-
});
|
|
22044
|
-
var occurrenceSchema = createSelectSchema(occurrences, {
|
|
22045
|
-
occurrenceDate: exports_coerce.date(),
|
|
22046
|
-
completedAt: exports_coerce.date().nullable()
|
|
22047
|
-
});
|
|
22048
|
-
var byDayCodeSchema = _enum2(["MO", "TU", "WE", "TH", "FR", "SA", "SU"]);
|
|
22049
|
-
var byDayOrdinalSchema = _enum2(["1", "2", "3", "4", "-1"]);
|
|
22050
|
-
var byDaySchema = union([
|
|
22051
|
-
byDayCodeSchema,
|
|
22052
|
-
templateLiteral([byDayOrdinalSchema, byDayCodeSchema])
|
|
22053
|
-
]);
|
|
22054
|
-
var BY_DAY_RE = /^(-1|[1-4])?(MO|TU|WE|TH|FR|SA|SU)$/;
|
|
22055
|
-
function parseByDay(code) {
|
|
22056
|
-
const m = BY_DAY_RE.exec(code);
|
|
22057
|
-
if (!m)
|
|
22058
|
-
return null;
|
|
22059
|
-
return { ordinal: m[1] ? Number(m[1]) : null, weekday: m[2] };
|
|
22060
|
-
}
|
|
22061
|
-
var recurrenceRuleParams = {
|
|
22062
|
-
timezone: string2().min(1).default("UTC"),
|
|
22063
|
-
interval: number2().int().positive().default(1),
|
|
22064
|
-
mode: recurrenceModeSchema,
|
|
22065
|
-
timeOfDay: string2().regex(/^([01]\d|2[0-3]):[0-5]\d$/, "time-of-day must be HH:MM (24h)").nullish(),
|
|
22066
|
-
freq: recurrenceFreqSchema.optional(),
|
|
22067
|
-
byDay: array(byDaySchema).optional(),
|
|
22068
|
-
until: exports_coerce.date().optional(),
|
|
22069
|
-
count: number2().int().positive().optional(),
|
|
22070
|
-
unit: recurrenceUnitSchema.optional(),
|
|
22071
|
-
anchor: recurrenceAnchorSchema.optional()
|
|
22072
|
-
};
|
|
22073
|
-
function refineRecurrenceRule(v, ctx) {
|
|
22074
|
-
if (v.mode === "rigid" && !v.freq) {
|
|
22075
|
-
ctx.addIssue({ code: "custom", path: ["freq"], message: "rigid rules require a freq" });
|
|
22076
|
-
}
|
|
22077
|
-
const ordinal = v.byDay?.findIndex((code) => parseByDay(code)?.ordinal != null) ?? -1;
|
|
22078
|
-
if (ordinal >= 0 && v.freq !== "monthly" && v.freq !== "yearly") {
|
|
22079
|
-
ctx.addIssue({
|
|
22080
|
-
code: "custom",
|
|
22081
|
-
path: ["byDay", ordinal],
|
|
22082
|
-
message: "an ordinal weekday (1SU, -1FR) needs a monthly or yearly freq"
|
|
22083
|
-
});
|
|
22084
|
-
}
|
|
22085
|
-
if (v.mode === "flexible") {
|
|
22086
|
-
if (!v.unit) {
|
|
22087
|
-
ctx.addIssue({ code: "custom", path: ["unit"], message: "flexible rules require a unit" });
|
|
22088
|
-
}
|
|
22089
|
-
if (!v.anchor) {
|
|
22090
|
-
ctx.addIssue({
|
|
22091
|
-
code: "custom",
|
|
22092
|
-
path: ["anchor"],
|
|
22093
|
-
message: "flexible rules require an anchor"
|
|
22094
|
-
});
|
|
22095
|
-
}
|
|
22096
|
-
}
|
|
22097
|
-
}
|
|
22098
|
-
var createRecurrenceRuleInputSchema = object({
|
|
22099
|
-
templateId: ulidSchema,
|
|
22100
|
-
...recurrenceRuleParams
|
|
22101
|
-
}).superRefine(refineRecurrenceRule);
|
|
22102
|
-
var updateRecurrenceRuleInputSchema = object({ ...recurrenceRuleParams }).superRefine(refineRecurrenceRule);
|
|
22103
|
-
var updateOccurrenceInputSchema = createUpdateSchema(occurrences, {
|
|
22104
|
-
occurrenceDate: exports_coerce.date().optional()
|
|
22105
|
-
}).pick({ occurrenceDate: true, status: true }).strict();
|
|
22106
|
-
|
|
22107
22305
|
// ../../packages/schema/src/contracts/routines.ts
|
|
22108
22306
|
var routineDayTimesSchema = partialRecord(_enum2(["MO", "TU", "WE", "TH", "FR", "SA", "SU"]), string2().regex(/^([01]\d|2[0-3]):[0-5]\d$/));
|
|
22109
22307
|
var routineSchema = createSelectSchema(routines);
|
|
@@ -22205,10 +22403,18 @@ var routineRunSchema = createSelectSchema(routineRuns, {
|
|
|
22205
22403
|
completedAt: exports_coerce.date().nullable()
|
|
22206
22404
|
});
|
|
22207
22405
|
var routineRunStepSchema = createSelectSchema(routineRunSteps, {
|
|
22208
|
-
completedAt: exports_coerce.date().nullable()
|
|
22406
|
+
completedAt: exports_coerce.date().nullable(),
|
|
22407
|
+
taskId: string2().nullable().default(null),
|
|
22408
|
+
reason: string2().nullable().default(null)
|
|
22209
22409
|
});
|
|
22210
22410
|
var routineRunStepViewSchema = routineRunStepSchema.extend({
|
|
22211
|
-
habit: habitSummarySchema.nullable().default(null)
|
|
22411
|
+
habit: habitSummarySchema.nullable().default(null),
|
|
22412
|
+
task: object({
|
|
22413
|
+
id: string2(),
|
|
22414
|
+
title: string2(),
|
|
22415
|
+
status: string2(),
|
|
22416
|
+
dueAt: exports_coerce.date().nullable()
|
|
22417
|
+
}).nullable().default(null)
|
|
22212
22418
|
});
|
|
22213
22419
|
var routineRunViewSchema = routineRunSchema.extend({
|
|
22214
22420
|
routineTitle: string2(),
|
|
@@ -22282,6 +22488,44 @@ var routineRhythmResultSchema = object({
|
|
|
22282
22488
|
routines: array(routineRhythmSchema),
|
|
22283
22489
|
notices: array(routineNoticeSchema)
|
|
22284
22490
|
});
|
|
22491
|
+
var addRoutineTaskStepInputSchema = object({
|
|
22492
|
+
taskId: ulidSchema,
|
|
22493
|
+
reason: string2().min(1).max(280).optional()
|
|
22494
|
+
}).strict();
|
|
22495
|
+
var reorderRoutineStepsInputSchema = object({
|
|
22496
|
+
stepIds: array(ulidSchema).min(1).max(200).refine((ids) => new Set(ids).size === ids.length, "stepIds must not repeat")
|
|
22497
|
+
}).strict();
|
|
22498
|
+
var routineTodayStepKindSchema = _enum2(["step", "habit", "task"]);
|
|
22499
|
+
var routineTodayStepSchema = object({
|
|
22500
|
+
n: number2().int().positive(),
|
|
22501
|
+
title: string2(),
|
|
22502
|
+
kind: routineTodayStepKindSchema,
|
|
22503
|
+
meta: string2().nullable(),
|
|
22504
|
+
minutes: number2().int().nullable(),
|
|
22505
|
+
done: boolean2()
|
|
22506
|
+
});
|
|
22507
|
+
var routineTodayStateSchema = _enum2(["done", "running", "upcoming", "resting"]);
|
|
22508
|
+
var routineTodaySchema = object({
|
|
22509
|
+
id: string2(),
|
|
22510
|
+
title: string2(),
|
|
22511
|
+
icon: string2().nullable(),
|
|
22512
|
+
start: string2().nullable(),
|
|
22513
|
+
durationMinutes: number2().int().nonnegative(),
|
|
22514
|
+
state: routineTodayStateSchema,
|
|
22515
|
+
run: object({
|
|
22516
|
+
id: string2(),
|
|
22517
|
+
startedAt: exports_coerce.date(),
|
|
22518
|
+
completedAt: exports_coerce.date().nullable(),
|
|
22519
|
+
done: number2().int().nonnegative(),
|
|
22520
|
+
total: number2().int().nonnegative()
|
|
22521
|
+
}).nullable(),
|
|
22522
|
+
steps: array(routineTodayStepSchema),
|
|
22523
|
+
rhythm: array(routineDayStateSchema).length(14)
|
|
22524
|
+
});
|
|
22525
|
+
var routinesTodayResultSchema = object({
|
|
22526
|
+
today: ymdSchema,
|
|
22527
|
+
routines: array(routineTodaySchema)
|
|
22528
|
+
});
|
|
22285
22529
|
|
|
22286
22530
|
// ../../packages/schema/src/contracts/areas.ts
|
|
22287
22531
|
var areaPurposeSchema = string2().trim().max(140).transform((v) => v.length === 0 ? null : v);
|
|
@@ -22505,7 +22749,8 @@ var collectionTypeValues = [
|
|
|
22505
22749
|
"place",
|
|
22506
22750
|
"wine",
|
|
22507
22751
|
"wardrobe",
|
|
22508
|
-
"asset"
|
|
22752
|
+
"asset",
|
|
22753
|
+
"hobby"
|
|
22509
22754
|
];
|
|
22510
22755
|
var collectionTypeSchema = _enum2(collectionTypeValues);
|
|
22511
22756
|
var collectionViewValues = ["grid", "shelf", "map"];
|
|
@@ -22719,6 +22964,8 @@ var taskListQuerySchema = object({
|
|
|
22719
22964
|
areaId: ulidSchema.optional(),
|
|
22720
22965
|
projectId: ulidSchema.optional(),
|
|
22721
22966
|
status: csvList(taskStatusSchema).optional(),
|
|
22967
|
+
priority: csvList(workPrioritySchema).optional(),
|
|
22968
|
+
view: ulidSchema.optional(),
|
|
22722
22969
|
tag: tagListSchema.optional(),
|
|
22723
22970
|
updatedSince: instantQuerySchema.optional(),
|
|
22724
22971
|
dueBefore: instantQuerySchema.optional(),
|
|
@@ -24082,7 +24329,7 @@ var calendarOperations = defineOperations({
|
|
|
24082
24329
|
summary: "Push to the calendar now",
|
|
24083
24330
|
description: "Reconcile do's placements (timed tasks, deadlines, Time blocks, timed routine occurrences) onto do's own calendar in each of the member's usable connections, now rather than at the next sweep. Idempotent: a settled calendar is all `skipped`. A connection that needs reconnecting is left out. Needs a key that acts for a member.",
|
|
24084
24331
|
status: 200,
|
|
24085
|
-
response: { description: "
|
|
24332
|
+
response: { description: "`{ pushed }`: one push result per connection." },
|
|
24086
24333
|
errors: { 400: true }
|
|
24087
24334
|
},
|
|
24088
24335
|
refresh: {
|
|
@@ -29102,6 +29349,32 @@ var guestListOverviewSchema = object({
|
|
|
29102
29349
|
invites: number2().int()
|
|
29103
29350
|
})
|
|
29104
29351
|
});
|
|
29352
|
+
var guestListGuestSchema = guestViewSchema.omit({ diet: true });
|
|
29353
|
+
var guestListHouseholdSchema = object({
|
|
29354
|
+
householdId: ulidSchema.nullable(),
|
|
29355
|
+
title: string2(),
|
|
29356
|
+
address: householdAddressSchema.nullable(),
|
|
29357
|
+
addressConfirmedAt: exports_coerce.date().nullable(),
|
|
29358
|
+
language: rsvpLanguageSchema,
|
|
29359
|
+
group: boolean2(),
|
|
29360
|
+
catererNotes: number2().int().min(0),
|
|
29361
|
+
guests: array(guestListGuestSchema)
|
|
29362
|
+
});
|
|
29363
|
+
var guestListSummarySchema = object({
|
|
29364
|
+
invited: number2().int(),
|
|
29365
|
+
households: number2().int(),
|
|
29366
|
+
coming: number2().int(),
|
|
29367
|
+
waiting: number2().int(),
|
|
29368
|
+
notComing: number2().int(),
|
|
29369
|
+
tables: number2().int(),
|
|
29370
|
+
notSeated: number2().int(),
|
|
29371
|
+
noAddress: number2().int()
|
|
29372
|
+
});
|
|
29373
|
+
var guestListHouseholdsViewSchema = object({
|
|
29374
|
+
guestList: guestListViewSchema,
|
|
29375
|
+
summary: guestListSummarySchema,
|
|
29376
|
+
households: array(guestListHouseholdSchema)
|
|
29377
|
+
});
|
|
29105
29378
|
var rsvpDigestQuerySchema = object({ since: exports_coerce.date().optional() }).strict();
|
|
29106
29379
|
var rsvpDigestSchema = object({
|
|
29107
29380
|
guestListId: string2(),
|
|
@@ -30733,6 +31006,21 @@ var housePlaceTileSchema = object({
|
|
|
30733
31006
|
gardenFeatureId: string2().nullable(),
|
|
30734
31007
|
thingCount: number2().int().min(0)
|
|
30735
31008
|
});
|
|
31009
|
+
var houseLowSchema = object({
|
|
31010
|
+
id: string2(),
|
|
31011
|
+
title: string2(),
|
|
31012
|
+
placeTitle: string2().nullable(),
|
|
31013
|
+
amountWords: string2(),
|
|
31014
|
+
state: _enum2(["low", "fine"])
|
|
31015
|
+
});
|
|
31016
|
+
var houseLoanRowSchema = object({
|
|
31017
|
+
itemId: string2(),
|
|
31018
|
+
title: string2(),
|
|
31019
|
+
direction: _enum2(["lent", "borrowed"]),
|
|
31020
|
+
who: string2(),
|
|
31021
|
+
since: day,
|
|
31022
|
+
dueBack: day.nullable()
|
|
31023
|
+
});
|
|
30736
31024
|
var houseOverviewSchema = object({
|
|
30737
31025
|
broken: array(houseBrokenSchema),
|
|
30738
31026
|
upkeepSoon: array(houseUpkeepSoonSchema),
|
|
@@ -30742,7 +31030,14 @@ var houseOverviewSchema = object({
|
|
|
30742
31030
|
toolCount: number2().int().min(0),
|
|
30743
31031
|
animalCount: number2().int().min(0),
|
|
30744
31032
|
toConfirm: number2().int().min(0).default(0),
|
|
30745
|
-
toConfirmTitles: array(string2()).max(3).default([])
|
|
31033
|
+
toConfirmTitles: array(string2()).max(3).default([]),
|
|
31034
|
+
low: array(houseLowSchema).max(5).default([]),
|
|
31035
|
+
loans: array(houseLoanRowSchema).max(5).default([]),
|
|
31036
|
+
lowCount: number2().int().min(0).default(0),
|
|
31037
|
+
lentCount: number2().int().min(0).default(0),
|
|
31038
|
+
borrowedCount: number2().int().min(0).default(0),
|
|
31039
|
+
upkeepThisMonth: number2().int().min(0).default(0),
|
|
31040
|
+
brokenWaitingCount: number2().int().min(0).default(0)
|
|
30746
31041
|
});
|
|
30747
31042
|
var upkeepScheduleSchema = object({
|
|
30748
31043
|
every: number2().int().min(1).max(365),
|
|
@@ -31066,6 +31361,166 @@ var householdOperations = defineOperations({
|
|
|
31066
31361
|
})
|
|
31067
31362
|
});
|
|
31068
31363
|
|
|
31364
|
+
// ../../packages/schema/src/contracts/inbox.ts
|
|
31365
|
+
var INBOX_KINDS = ["capture", "proposal", "answer"];
|
|
31366
|
+
var inboxKindSchema = _enum2(INBOX_KINDS);
|
|
31367
|
+
var inboxFilterSchema = _enum2(["all", ...INBOX_KINDS]);
|
|
31368
|
+
var inboxQuerySchema = object({
|
|
31369
|
+
kind: inboxFilterSchema.default("all")
|
|
31370
|
+
});
|
|
31371
|
+
var inboxIconSchema = _enum2(["mic", "edit", "camera", "echo", "agents", "bell"]);
|
|
31372
|
+
var inboxHueSchema = _enum2([
|
|
31373
|
+
"sage",
|
|
31374
|
+
"sky",
|
|
31375
|
+
"peach",
|
|
31376
|
+
"plum",
|
|
31377
|
+
"sun",
|
|
31378
|
+
"sea",
|
|
31379
|
+
"clay",
|
|
31380
|
+
"mist"
|
|
31381
|
+
]);
|
|
31382
|
+
var inboxActionSchema = object({
|
|
31383
|
+
id: string2(),
|
|
31384
|
+
label: string2(),
|
|
31385
|
+
key: string2().length(1),
|
|
31386
|
+
primary: boolean2(),
|
|
31387
|
+
route: string2().nullable().default(null)
|
|
31388
|
+
});
|
|
31389
|
+
var inboxItemSchema = object({
|
|
31390
|
+
id: ulidSchema,
|
|
31391
|
+
kind: inboxKindSchema,
|
|
31392
|
+
title: string2(),
|
|
31393
|
+
source: string2(),
|
|
31394
|
+
meta: string2(),
|
|
31395
|
+
icon: inboxIconSchema,
|
|
31396
|
+
hue: inboxHueSchema,
|
|
31397
|
+
createdAt: exports_coerce.date(),
|
|
31398
|
+
actions: array(inboxActionSchema)
|
|
31399
|
+
});
|
|
31400
|
+
var inboxCountsSchema = object({
|
|
31401
|
+
all: number2().int().nonnegative(),
|
|
31402
|
+
capture: number2().int().nonnegative(),
|
|
31403
|
+
proposal: number2().int().nonnegative(),
|
|
31404
|
+
answer: number2().int().nonnegative()
|
|
31405
|
+
});
|
|
31406
|
+
var inboxResponseSchema = object({
|
|
31407
|
+
counts: inboxCountsSchema,
|
|
31408
|
+
items: array(inboxItemSchema)
|
|
31409
|
+
});
|
|
31410
|
+
var INBOX_SORT_AS = ["task", "note", "habit", "log"];
|
|
31411
|
+
var inboxSortAsSchema = _enum2(INBOX_SORT_AS);
|
|
31412
|
+
var inboxFactSchema = object({ key: string2(), value: string2() });
|
|
31413
|
+
var inboxSortingSchema = object({
|
|
31414
|
+
id: ulidSchema,
|
|
31415
|
+
original: object({
|
|
31416
|
+
how: string2(),
|
|
31417
|
+
at: exports_coerce.date(),
|
|
31418
|
+
text: string2()
|
|
31419
|
+
}),
|
|
31420
|
+
becomes: inboxSortAsSchema,
|
|
31421
|
+
facts: array(inboxFactSchema),
|
|
31422
|
+
why: string2().nullable()
|
|
31423
|
+
});
|
|
31424
|
+
var inboxTaskFieldsSchema = updateTaskInputSchema.pick({
|
|
31425
|
+
title: true,
|
|
31426
|
+
notes: true,
|
|
31427
|
+
areaId: true,
|
|
31428
|
+
projectId: true,
|
|
31429
|
+
scheduledAt: true,
|
|
31430
|
+
allDay: true,
|
|
31431
|
+
dueAt: true,
|
|
31432
|
+
somedayAt: true,
|
|
31433
|
+
tags: true,
|
|
31434
|
+
owner: true
|
|
31435
|
+
});
|
|
31436
|
+
var inboxNoteFieldsSchema = createNoteInputSchema.pick({ areaId: true, body: true, tags: true }).extend({ title: string2().min(1).optional() }).strict();
|
|
31437
|
+
var inboxHabitFieldsSchema = createHabitInputSchema.pick({ areaId: true, period: true, frequencyCount: true, timeOfDay: true }).partial().extend({ title: string2().min(1).optional() }).strict();
|
|
31438
|
+
var inboxSortInputSchema = discriminatedUnion("as", [
|
|
31439
|
+
object({ as: literal("task"), fields: inboxTaskFieldsSchema.optional() }).strict(),
|
|
31440
|
+
object({ as: literal("note"), fields: inboxNoteFieldsSchema.optional() }).strict(),
|
|
31441
|
+
object({
|
|
31442
|
+
as: literal("habit"),
|
|
31443
|
+
fields: inboxHabitFieldsSchema.optional()
|
|
31444
|
+
}).strict(),
|
|
31445
|
+
object({
|
|
31446
|
+
as: literal("log"),
|
|
31447
|
+
fields: record(string2(), unknown()).optional()
|
|
31448
|
+
}).strict()
|
|
31449
|
+
]);
|
|
31450
|
+
var inboxSortResultSchema = object({
|
|
31451
|
+
id: ulidSchema,
|
|
31452
|
+
as: inboxSortAsSchema,
|
|
31453
|
+
homeId: ulidSchema
|
|
31454
|
+
});
|
|
31455
|
+
var inboxLetGoResultSchema = object({
|
|
31456
|
+
id: ulidSchema,
|
|
31457
|
+
status: literal("cancelled")
|
|
31458
|
+
});
|
|
31459
|
+
|
|
31460
|
+
// ../../packages/schema/src/operations/inbox.ts
|
|
31461
|
+
var ID = "The capture's id (an Unsorted task).";
|
|
31462
|
+
var inboxOperations = defineOperations({
|
|
31463
|
+
list: {
|
|
31464
|
+
method: "get",
|
|
31465
|
+
path: "/inbox",
|
|
31466
|
+
scopes: ["tasks:read"],
|
|
31467
|
+
tag: "Tasks",
|
|
31468
|
+
summary: "The Inbox",
|
|
31469
|
+
description: "Everything that waits on you, in one list, oldest first: Unsorted captures (open, top-level tasks with no place yet), the agent's proposals (proposed tasks not set aside with Not now) and the key's member's notifications that still need an answer (unanswered, not expired, carrying buttons). Each item has exactly one primary action with its key, plus a secondary where its kind has one: a capture `File (e)`, a proposal `Approve (a)` + `Decline (d)`, an answer its own button + `Remind me (z)` when it carries one. `counts` is always the whole Inbox, whatever `kind` filters. A machine-only key has no notifications, so no answers.",
|
|
31470
|
+
query: [
|
|
31471
|
+
{
|
|
31472
|
+
name: "kind",
|
|
31473
|
+
description: "`all` (default), `capture`, `proposal` or `answer`.",
|
|
31474
|
+
enum: ["all", "capture", "proposal", "answer"]
|
|
31475
|
+
}
|
|
31476
|
+
],
|
|
31477
|
+
querySchema: inboxQuerySchema,
|
|
31478
|
+
status: 200,
|
|
31479
|
+
response: { description: "The Inbox.", view: "InboxResponse" },
|
|
31480
|
+
errors: { 400: true }
|
|
31481
|
+
},
|
|
31482
|
+
sorting: {
|
|
31483
|
+
method: "get",
|
|
31484
|
+
path: "/inbox/{id}/sorting",
|
|
31485
|
+
scopes: ["tasks:read"],
|
|
31486
|
+
tag: "Tasks",
|
|
31487
|
+
summary: "Sort a capture: the suggestion",
|
|
31488
|
+
description: "The sorting pane for one capture: how and when it came in and what was said, what it becomes (a Task unless it reads as an idea, then a Note), and the facts the agent filled in from its filing suggestion (Goes to, Status, Scheduled, Labels, Owner), with `why` in a line. 404 when the id is no capture in the Inbox.",
|
|
31489
|
+
pathParams: { id: ID },
|
|
31490
|
+
status: 200,
|
|
31491
|
+
response: { description: "The sorting suggestion.", view: "InboxSorting" },
|
|
31492
|
+
errors: { 404: true }
|
|
31493
|
+
},
|
|
31494
|
+
sort: {
|
|
31495
|
+
method: "post",
|
|
31496
|
+
path: "/inbox/{id}/sort",
|
|
31497
|
+
scopes: ["tasks:write"],
|
|
31498
|
+
tag: "Tasks",
|
|
31499
|
+
summary: "Sort a capture",
|
|
31500
|
+
description: "File the capture into its home and out of the Inbox. `task`: it stays the same task, filed with `fields` (absent ones from the agent's suggestion: Area or Project, Owner, the planned day), and needs a place (an Area, Project, day, Deadline or Someday); `note`: a Note with the capture's title and notes (needs `notes:write` too); `habit`: a daily yes/no Habit by the capture's title (needs `habits:write` too). A capture that became a Note or Habit is removed from Tasks, so it never counts as Landed. `log` is 400 until the Log something writer lands.",
|
|
31501
|
+
pathParams: { id: ID },
|
|
31502
|
+
body: inboxSortInputSchema,
|
|
31503
|
+
status: 201,
|
|
31504
|
+
response: { description: "Where it went.", view: "InboxSortResult" },
|
|
31505
|
+
errors: { 400: true, 403: true, 404: true }
|
|
31506
|
+
},
|
|
31507
|
+
letGo: {
|
|
31508
|
+
method: "post",
|
|
31509
|
+
path: "/inbox/{id}/let-go",
|
|
31510
|
+
scopes: ["tasks:write"],
|
|
31511
|
+
tag: "Tasks",
|
|
31512
|
+
summary: "Let a capture go",
|
|
31513
|
+
description: 'Drop the capture: it is cancelled (an ending, not a delete; undo with `PATCH /tasks/{id}` `{ status: "todo" }`), leaves the Inbox and never counts as Landed. 404 when the id is no capture in the Inbox.',
|
|
31514
|
+
pathParams: { id: ID },
|
|
31515
|
+
status: 201,
|
|
31516
|
+
response: {
|
|
31517
|
+
description: "The capture, cancelled.",
|
|
31518
|
+
view: "InboxLetGoResult"
|
|
31519
|
+
},
|
|
31520
|
+
errors: { 404: true }
|
|
31521
|
+
}
|
|
31522
|
+
});
|
|
31523
|
+
|
|
31069
31524
|
// ../../packages/schema/src/db/incidents.ts
|
|
31070
31525
|
var incidentKind = pgEnum("incident_kind", [
|
|
31071
31526
|
"water",
|
|
@@ -31562,6 +32017,13 @@ var journalLinkSchema = object({
|
|
|
31562
32017
|
title: string2(),
|
|
31563
32018
|
type: string2()
|
|
31564
32019
|
});
|
|
32020
|
+
var JOURNAL_NOTES_WRITTEN_MAX = 5;
|
|
32021
|
+
var journalNoteWrittenSchema = object({
|
|
32022
|
+
id: string2(),
|
|
32023
|
+
title: string2(),
|
|
32024
|
+
tags: array(string2()),
|
|
32025
|
+
updatedAt: exports_coerce.date()
|
|
32026
|
+
});
|
|
31565
32027
|
var journalSnapshotSchema = object({
|
|
31566
32028
|
date: journalDateSchema,
|
|
31567
32029
|
timezone: string2().min(1),
|
|
@@ -31571,7 +32033,9 @@ var journalSnapshotSchema = object({
|
|
|
31571
32033
|
habits: array(journalHabitSchema),
|
|
31572
32034
|
events: array(journalEventSchema),
|
|
31573
32035
|
links: array(journalLinkSchema),
|
|
31574
|
-
files: array(fileViewSchema)
|
|
32036
|
+
files: array(fileViewSchema),
|
|
32037
|
+
tasksLeft: number2().int().nonnegative().default(0),
|
|
32038
|
+
notesWritten: array(journalNoteWrittenSchema).max(JOURNAL_NOTES_WRITTEN_MAX).default([])
|
|
31575
32039
|
});
|
|
31576
32040
|
var JOURNAL_RANGE_MAX_DAYS = 366;
|
|
31577
32041
|
var journalRangeQuerySchema = object({ from: journalDateSchema, to: journalDateSchema }).refine((q) => q.from <= q.to, { message: "from must be on or before to", path: ["to"] }).refine((q) => (Date.parse(`${q.to}T00:00:00Z`) - Date.parse(`${q.from}T00:00:00Z`)) / 86400000 < JOURNAL_RANGE_MAX_DAYS, { message: `a range covers at most ${JOURNAL_RANGE_MAX_DAYS} days`, path: ["to"] });
|
|
@@ -31589,7 +32053,8 @@ var journalDayListItemSchema = object({
|
|
|
31589
32053
|
links: array(journalLinkSchema).max(3),
|
|
31590
32054
|
source: journalDaySourceSchema.nullable().default(null),
|
|
31591
32055
|
landed: number2().int().nonnegative().default(0),
|
|
31592
|
-
habitsDone: number2().int().nonnegative().default(0)
|
|
32056
|
+
habitsDone: number2().int().nonnegative().default(0),
|
|
32057
|
+
words: number2().int().nonnegative().default(0)
|
|
31593
32058
|
});
|
|
31594
32059
|
var journalDayListSchema = object({
|
|
31595
32060
|
from: journalDateSchema,
|
|
@@ -32852,6 +33317,145 @@ var krakenLinkOperations = defineOperations({
|
|
|
32852
33317
|
}
|
|
32853
33318
|
});
|
|
32854
33319
|
|
|
33320
|
+
// ../../packages/schema/src/db/log-kinds.ts
|
|
33321
|
+
var LOG_DESTINATIONS = ["habits", "animals", "health", "journal"];
|
|
33322
|
+
var logKinds = pgTable("log_kinds", {
|
|
33323
|
+
id: text("id").primaryKey(),
|
|
33324
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
33325
|
+
word: text("word").notNull(),
|
|
33326
|
+
destination: text("destination", { enum: LOG_DESTINATIONS }).notNull(),
|
|
33327
|
+
likeKind: text("like_kind"),
|
|
33328
|
+
targetId: text("target_id"),
|
|
33329
|
+
createdBy: text("created_by").references(() => users.id, { onDelete: "set null" }),
|
|
33330
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
33331
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
33332
|
+
}, (t) => [unique("log_kinds_tenant_word_uniq").on(t.tenantId, t.word)]);
|
|
33333
|
+
var logEntries = pgTable("log_entries", {
|
|
33334
|
+
id: text("id").primaryKey(),
|
|
33335
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
33336
|
+
userId: text("user_id").references(() => users.id, { onDelete: "set null" }),
|
|
33337
|
+
kind: text("kind").notNull(),
|
|
33338
|
+
text: text("text").notNull(),
|
|
33339
|
+
amount: doublePrecision("amount"),
|
|
33340
|
+
unit: text("unit"),
|
|
33341
|
+
destination: text("destination", { enum: LOG_DESTINATIONS }).notNull(),
|
|
33342
|
+
targetId: text("target_id"),
|
|
33343
|
+
refId: text("ref_id"),
|
|
33344
|
+
what: text("what").notNull(),
|
|
33345
|
+
whereLabel: text("where_label").notNull(),
|
|
33346
|
+
occurredAt: timestamp("occurred_at", { withTimezone: true }).notNull(),
|
|
33347
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
|
|
33348
|
+
}, (t) => [index("log_entries_tenant_occurred_idx").on(t.tenantId, t.occurredAt)]);
|
|
33349
|
+
|
|
33350
|
+
// ../../packages/schema/src/contracts/log-entry.ts
|
|
33351
|
+
var logDestinationSchema = _enum2(LOG_DESTINATIONS);
|
|
33352
|
+
var logWordSchema = string2().trim().toLowerCase().min(2).max(40).regex(/^\p{L}[\p{L}\p{N}'-]*$/u, "one word");
|
|
33353
|
+
var lineSchema = string2().trim().min(1).max(500);
|
|
33354
|
+
var logPreviewInputSchema = object({ text: lineSchema }).strict();
|
|
33355
|
+
var logWriteInputSchema = object({
|
|
33356
|
+
text: lineSchema,
|
|
33357
|
+
kind: string2().trim().toLowerCase().min(1).max(40).optional(),
|
|
33358
|
+
destination: logDestinationSchema.optional()
|
|
33359
|
+
}).strict();
|
|
33360
|
+
var logDayQuerySchema = object({ day: exports_iso.date().optional() });
|
|
33361
|
+
var logPreviewSchema = object({
|
|
33362
|
+
kind: string2().nullable(),
|
|
33363
|
+
word: string2().nullable(),
|
|
33364
|
+
amount: number2().nullable(),
|
|
33365
|
+
unit: string2().nullable(),
|
|
33366
|
+
label: string2(),
|
|
33367
|
+
destination: logDestinationSchema.nullable(),
|
|
33368
|
+
goesTo: string2().nullable(),
|
|
33369
|
+
effect: string2().nullable(),
|
|
33370
|
+
icon: string2(),
|
|
33371
|
+
needsKind: boolean2()
|
|
33372
|
+
});
|
|
33373
|
+
var logEntryViewSchema = object({
|
|
33374
|
+
id: string2(),
|
|
33375
|
+
at: string2(),
|
|
33376
|
+
kind: string2(),
|
|
33377
|
+
what: string2(),
|
|
33378
|
+
where: string2(),
|
|
33379
|
+
destination: logDestinationSchema,
|
|
33380
|
+
text: string2(),
|
|
33381
|
+
amount: number2().nullable(),
|
|
33382
|
+
occurredAt: exports_coerce.date()
|
|
33383
|
+
});
|
|
33384
|
+
var logWriteResultSchema = object({
|
|
33385
|
+
entry: logEntryViewSchema,
|
|
33386
|
+
preview: logPreviewSchema,
|
|
33387
|
+
remembered: string2().nullable()
|
|
33388
|
+
});
|
|
33389
|
+
var logKindViewSchema = object({
|
|
33390
|
+
key: string2(),
|
|
33391
|
+
label: string2(),
|
|
33392
|
+
words: array(string2()),
|
|
33393
|
+
destination: logDestinationSchema,
|
|
33394
|
+
goesTo: string2(),
|
|
33395
|
+
icon: string2(),
|
|
33396
|
+
builtIn: boolean2(),
|
|
33397
|
+
likeKind: string2().nullable()
|
|
33398
|
+
});
|
|
33399
|
+
|
|
33400
|
+
// ../../packages/schema/src/operations/log.ts
|
|
33401
|
+
var SECTION_SCOPES = "A line kept in Animals also needs `animals:write`; in Health or the Journal, `health:write` or `journal:write` held by name, on a key that acts for a member.";
|
|
33402
|
+
var logOperations = defineOperations({
|
|
33403
|
+
preview: {
|
|
33404
|
+
method: "post",
|
|
33405
|
+
path: "/log/preview",
|
|
33406
|
+
scopes: ["habits:read"],
|
|
33407
|
+
tag: "Log",
|
|
33408
|
+
summary: "Preview a logged line",
|
|
33409
|
+
description: 'Parse one line ("pages 34", "eggs 4") without writing anything: its `kind` and `amount`, a `label` ("34 pages, today"), where it\'s kept (`goesTo`: "Habits, Read 20 pages") and what it does (`effect`: "Ticks it, streak 32 days", or null). `needsKind` is true when the agent doesn\'t know the word yet: ask once (the kinds from `GET /api/v1/log/kinds`) and send `kind` on the write.',
|
|
33410
|
+
body: logPreviewInputSchema,
|
|
33411
|
+
status: 200,
|
|
33412
|
+
response: { description: "What the line would do." },
|
|
33413
|
+
errors: { 400: true },
|
|
33414
|
+
operationId: "log_preview"
|
|
33415
|
+
},
|
|
33416
|
+
write: {
|
|
33417
|
+
method: "post",
|
|
33418
|
+
path: "/log",
|
|
33419
|
+
scopes: ["habits:write"],
|
|
33420
|
+
tag: "Log",
|
|
33421
|
+
summary: "Log something",
|
|
33422
|
+
description: `Write one line into its section: a habit check-in with the amount, the animals log (eggs on the flock), the Health log or a Journal note. For an unknown word send \`kind\` (a built-in's key or a remembered word) or \`destination\`: the word is remembered for the Space, so the next line with it previews without asking. Returns the entry, its preview and the word remembered (or null). ${SECTION_SCOPES}`,
|
|
33423
|
+
body: logWriteInputSchema,
|
|
33424
|
+
status: 201,
|
|
33425
|
+
response: { description: "The entry, what it did, and the word remembered." },
|
|
33426
|
+
errors: {
|
|
33427
|
+
400: "The line is blank, its kind is unknown and none was given, or it needs an amount.",
|
|
33428
|
+
403: true
|
|
33429
|
+
},
|
|
33430
|
+
operationId: "log_write"
|
|
33431
|
+
},
|
|
33432
|
+
list: {
|
|
33433
|
+
method: "get",
|
|
33434
|
+
path: "/log",
|
|
33435
|
+
scopes: ["habits:read"],
|
|
33436
|
+
tag: "Log",
|
|
33437
|
+
summary: "List what was logged",
|
|
33438
|
+
description: 'The lines written through Log something on `day` (the member\'s day; today by default), oldest first: `{ at: "08:10", what: "Eggs, 4", where: "Animals, Coop" }`. A Health or Journal line shows only to the member who logged it, on a key holding that section\'s read scope by name; an Animals line needs `animals:read`.',
|
|
33439
|
+
query: [{ name: "day", description: "The day, YYYY-MM-DD; today by default.", format: "date" }],
|
|
33440
|
+
querySchema: logDayQuerySchema,
|
|
33441
|
+
status: 200,
|
|
33442
|
+
response: { description: "The day's logged lines.", list: true },
|
|
33443
|
+
errors: { 400: true },
|
|
33444
|
+
operationId: "log_list"
|
|
33445
|
+
},
|
|
33446
|
+
kinds: {
|
|
33447
|
+
method: "get",
|
|
33448
|
+
path: "/log/kinds",
|
|
33449
|
+
scopes: ["habits:read"],
|
|
33450
|
+
tag: "Log",
|
|
33451
|
+
summary: "List the kinds you log",
|
|
33452
|
+
description: "The Space's kinds: the built-ins (Pages read \u2192 Habits, Eggs \u2192 Animals, A health entry \u2192 Health, A note \u2192 Journal) and every word it taught the agent, each with its words and where it's kept (`goesTo`).",
|
|
33453
|
+
status: 200,
|
|
33454
|
+
response: { description: "The kinds.", list: true },
|
|
33455
|
+
operationId: "log_kinds"
|
|
33456
|
+
}
|
|
33457
|
+
});
|
|
33458
|
+
|
|
32855
33459
|
// ../../packages/schema/src/db/mail.ts
|
|
32856
33460
|
var mailCampaignStatus = pgEnum("mail_campaign_status", [
|
|
32857
33461
|
"draft",
|
|
@@ -32951,11 +33555,11 @@ var mailLookShape = {
|
|
|
32951
33555
|
couple: string2().trim().min(1).max(120).optional(),
|
|
32952
33556
|
imagesUrl: url({ protocol: /^https$/ }).max(500).optional()
|
|
32953
33557
|
};
|
|
32954
|
-
var
|
|
33558
|
+
var lineSchema2 = string2().trim().min(1).max(2000);
|
|
32955
33559
|
var mailMessageCopySchema = object({
|
|
32956
33560
|
subject: string2().trim().min(1).max(200),
|
|
32957
33561
|
heading: string2().trim().min(1).max(200),
|
|
32958
|
-
paragraphs: array(
|
|
33562
|
+
paragraphs: array(lineSchema2).max(20).default([]),
|
|
32959
33563
|
button: object({ label: string2().trim().min(1).max(80), url: url() }).strict().nullish()
|
|
32960
33564
|
}).strict();
|
|
32961
33565
|
var mailMessageDataSchema = object({
|
|
@@ -32975,7 +33579,7 @@ var mailDaySchema = object({
|
|
|
32975
33579
|
var mailSaveTheDateCopySchema = object({
|
|
32976
33580
|
subject: string2().trim().min(1).max(200),
|
|
32977
33581
|
heading: string2().trim().min(1).max(200),
|
|
32978
|
-
paragraphs: array(
|
|
33582
|
+
paragraphs: array(lineSchema2).max(20).default([]),
|
|
32979
33583
|
button: string2().trim().min(1).max(80)
|
|
32980
33584
|
}).strict();
|
|
32981
33585
|
var mailSaveTheDateDataSchema = object({
|
|
@@ -36188,6 +36792,67 @@ var progressDayDetailSchema = object({
|
|
|
36188
36792
|
slipped: array(progressSlippedItemSchema)
|
|
36189
36793
|
});
|
|
36190
36794
|
|
|
36795
|
+
// ../../packages/schema/src/contracts/progress-review.ts
|
|
36796
|
+
var REVIEW_SPANS = ["week", "month"];
|
|
36797
|
+
var reviewSpanSchema = _enum2(REVIEW_SPANS);
|
|
36798
|
+
var reviewSummaryQuerySchema = object({
|
|
36799
|
+
span: reviewSpanSchema.default("week"),
|
|
36800
|
+
date: progressDateSchema.optional()
|
|
36801
|
+
});
|
|
36802
|
+
var countSchema2 = number2().int().nonnegative();
|
|
36803
|
+
var REVIEW_MARK_STATES = ["done", "missed", "open", "later", "not_due"];
|
|
36804
|
+
var reviewMarkStateSchema = _enum2(REVIEW_MARK_STATES);
|
|
36805
|
+
var reviewMarkSchema = object({
|
|
36806
|
+
date: progressDateSchema,
|
|
36807
|
+
state: reviewMarkStateSchema
|
|
36808
|
+
});
|
|
36809
|
+
var reviewNumbersSchema = object({
|
|
36810
|
+
tasksDone: countSchema2,
|
|
36811
|
+
tasksDoneDelta: number2().int(),
|
|
36812
|
+
habitTicks: countSchema2,
|
|
36813
|
+
habitDue: countSchema2,
|
|
36814
|
+
projectsMoved: countSchema2,
|
|
36815
|
+
challengesRunning: countSchema2
|
|
36816
|
+
});
|
|
36817
|
+
var reviewSeriesEntrySchema = object({
|
|
36818
|
+
key: string2().min(1),
|
|
36819
|
+
label: string2().min(1),
|
|
36820
|
+
tasksDone: countSchema2,
|
|
36821
|
+
habitTicks: countSchema2,
|
|
36822
|
+
current: boolean2()
|
|
36823
|
+
});
|
|
36824
|
+
var reviewStreakSchema = object({
|
|
36825
|
+
habitId: string2().min(1),
|
|
36826
|
+
title: string2(),
|
|
36827
|
+
scheduleLabel: string2().min(1),
|
|
36828
|
+
current: countSchema2,
|
|
36829
|
+
best: countSchema2,
|
|
36830
|
+
unitLabel: string2().min(1),
|
|
36831
|
+
marks: array(reviewMarkSchema)
|
|
36832
|
+
});
|
|
36833
|
+
var reviewProjectSchema = object({
|
|
36834
|
+
projectId: string2().min(1),
|
|
36835
|
+
title: string2(),
|
|
36836
|
+
done: countSchema2,
|
|
36837
|
+
total: countSchema2,
|
|
36838
|
+
targetDate: progressDateSchema.nullable()
|
|
36839
|
+
});
|
|
36840
|
+
var reviewSummarySchema = object({
|
|
36841
|
+
span: reviewSpanSchema,
|
|
36842
|
+
label: string2().min(1),
|
|
36843
|
+
from: progressDateSchema,
|
|
36844
|
+
to: progressDateSchema,
|
|
36845
|
+
rangeLabel: string2().min(1),
|
|
36846
|
+
timezone: string2().min(1),
|
|
36847
|
+
numbers: reviewNumbersSchema,
|
|
36848
|
+
series: array(reviewSeriesEntrySchema).length(8),
|
|
36849
|
+
streaks: array(reviewStreakSchema),
|
|
36850
|
+
projects: array(reviewProjectSchema)
|
|
36851
|
+
}).refine((s) => s.series.at(-1)?.current === true, {
|
|
36852
|
+
message: "the last series entry is the asked period",
|
|
36853
|
+
path: ["series"]
|
|
36854
|
+
}).refine((s) => s.from <= s.to, { message: "from is on or before to", path: ["from"] });
|
|
36855
|
+
|
|
36191
36856
|
// ../../packages/schema/src/operations/progress.ts
|
|
36192
36857
|
var NO_MEMBER3 = "The key acts for no member.";
|
|
36193
36858
|
var question = {
|
|
@@ -36229,6 +36894,33 @@ var progressOperations = defineOperations({
|
|
|
36229
36894
|
errors: { 400: true },
|
|
36230
36895
|
operationId: "get_progress_day"
|
|
36231
36896
|
},
|
|
36897
|
+
review: {
|
|
36898
|
+
method: "get",
|
|
36899
|
+
path: "/progress/review",
|
|
36900
|
+
scopes: ["tasks:read", "habits:read"],
|
|
36901
|
+
tag: "Reads",
|
|
36902
|
+
summary: "Review summary",
|
|
36903
|
+
description: "Plan > Review in one read, for the ISO week (Monday to Sunday) or calendar month holding `date` (default: the one holding today, in the key's member's saved timezone): the headline numbers (tasks done, mine and the agents', against the period before; habit days met and due; projects with a task done; challenges running), tasks done and habit days met for the last 8 periods (oldest first, the last one the asked period), one streak row per live habit (current and best run, `unitLabel` `N days` for a daily habit and `N in a row` otherwise, and a mark per day of the week or per week of the month: done, missed, open, later or not_due, a day it isn't due that never breaks the run), and each open project's tasks done of its total, the most recently active first.",
|
|
36904
|
+
query: [
|
|
36905
|
+
{
|
|
36906
|
+
name: "span",
|
|
36907
|
+
description: "`week` (default) or `month`.",
|
|
36908
|
+
type: "string",
|
|
36909
|
+
enum: [...REVIEW_SPANS]
|
|
36910
|
+
},
|
|
36911
|
+
{
|
|
36912
|
+
name: "date",
|
|
36913
|
+
description: "A day (`YYYY-MM-DD`) in the period; default today.",
|
|
36914
|
+
type: "string",
|
|
36915
|
+
format: "date"
|
|
36916
|
+
}
|
|
36917
|
+
],
|
|
36918
|
+
querySchema: reviewSummaryQuerySchema,
|
|
36919
|
+
status: 200,
|
|
36920
|
+
response: { description: "The Review summary (`ReviewSummary`)." },
|
|
36921
|
+
errors: { 400: true },
|
|
36922
|
+
operationId: "get_progress_review"
|
|
36923
|
+
},
|
|
36232
36924
|
habits: {
|
|
36233
36925
|
method: "get",
|
|
36234
36926
|
path: "/progress/habits",
|
|
@@ -36364,6 +37056,46 @@ var projectOperations = defineOperations({
|
|
|
36364
37056
|
response: { description: "Detached." },
|
|
36365
37057
|
errors: { 404: true },
|
|
36366
37058
|
webhook: "project.task.detached"
|
|
37059
|
+
},
|
|
37060
|
+
listUpdates: {
|
|
37061
|
+
method: "get",
|
|
37062
|
+
path: "/projects/{id}/updates",
|
|
37063
|
+
pathParams: { id: "The project's ULID or its ref (`DO-P7`)." },
|
|
37064
|
+
scopes: ["projects:read"],
|
|
37065
|
+
tag: "Projects",
|
|
37066
|
+
summary: "List a project's updates",
|
|
37067
|
+
description: "The project's updates, newest first: each a status, a note, its author and date.",
|
|
37068
|
+
status: 200,
|
|
37069
|
+
response: { description: "The project's updates, newest first." },
|
|
37070
|
+
errors: { 404: true }
|
|
37071
|
+
},
|
|
37072
|
+
createUpdate: {
|
|
37073
|
+
method: "post",
|
|
37074
|
+
path: "/projects/{id}/updates",
|
|
37075
|
+
pathParams: { id: "The project's ULID or its ref (`DO-P7`)." },
|
|
37076
|
+
scopes: ["projects:write"],
|
|
37077
|
+
tag: "Projects",
|
|
37078
|
+
summary: "Post a project update",
|
|
37079
|
+
description: "Write a dated status note on the project (`on_track`, `at_risk`, `off_track`, `milestone_done` or `done`). It is attributed to the key's Agent, or else to the key's member; a machine key with neither is a 403.",
|
|
37080
|
+
body: createProjectUpdateInputSchema,
|
|
37081
|
+
status: 201,
|
|
37082
|
+
response: { description: "The posted update." },
|
|
37083
|
+
errors: { 400: true, 403: true, 404: true }
|
|
37084
|
+
},
|
|
37085
|
+
removeUpdate: {
|
|
37086
|
+
method: "delete",
|
|
37087
|
+
path: "/projects/{id}/updates/{updateId}",
|
|
37088
|
+
pathParams: {
|
|
37089
|
+
id: "The project's ULID or its ref (`DO-P7`).",
|
|
37090
|
+
updateId: "The update's ULID."
|
|
37091
|
+
},
|
|
37092
|
+
scopes: ["projects:write"],
|
|
37093
|
+
tag: "Projects",
|
|
37094
|
+
summary: "Delete a project update",
|
|
37095
|
+
description: "Delete an update; only its author (the member or the Agent) may.",
|
|
37096
|
+
status: 204,
|
|
37097
|
+
response: { description: "Deleted." },
|
|
37098
|
+
errors: { 403: true, 404: true }
|
|
36367
37099
|
}
|
|
36368
37100
|
});
|
|
36369
37101
|
|
|
@@ -36432,12 +37164,47 @@ var landedByActorSchema = object({
|
|
|
36432
37164
|
actor: actorRefSchema.nullable(),
|
|
36433
37165
|
count: number2().int().nonnegative()
|
|
36434
37166
|
});
|
|
37167
|
+
var landedQuerySchema = readWindowQuerySchema.extend({
|
|
37168
|
+
tz: string2().trim().min(1).max(64).optional()
|
|
37169
|
+
});
|
|
37170
|
+
var landedSectionSchema = _enum2(["work", "habits", "agents", "home", "food", "journal"]);
|
|
37171
|
+
var landedActorSchema = object({
|
|
37172
|
+
kind: _enum2(["you", "member", "echo", "agent"]),
|
|
37173
|
+
id: string2().nullable(),
|
|
37174
|
+
name: string2().nullable(),
|
|
37175
|
+
machine: string2().nullable().optional()
|
|
37176
|
+
});
|
|
37177
|
+
var landedItemSchema = object({
|
|
37178
|
+
at: exports_coerce.date(),
|
|
37179
|
+
title: string2(),
|
|
37180
|
+
where: string2(),
|
|
37181
|
+
section: landedSectionSchema,
|
|
37182
|
+
actor: landedActorSchema,
|
|
37183
|
+
ref: object({
|
|
37184
|
+
type: _enum2(["task", "habit_entry", "document", "shopping_item"]),
|
|
37185
|
+
id: string2()
|
|
37186
|
+
})
|
|
37187
|
+
});
|
|
37188
|
+
var landedDaySchema = object({
|
|
37189
|
+
date: string2().regex(/^\d{4}-\d{2}-\d{2}$/),
|
|
37190
|
+
you: number2().int().nonnegative(),
|
|
37191
|
+
agents: number2().int().nonnegative()
|
|
37192
|
+
});
|
|
36435
37193
|
var landedResponseSchema = object({
|
|
36436
37194
|
from: exports_coerce.date(),
|
|
36437
37195
|
to: exports_coerce.date(),
|
|
36438
37196
|
total: number2().int().nonnegative(),
|
|
36439
37197
|
byActor: array(landedByActorSchema),
|
|
36440
|
-
tasks: array(taskViewSchema)
|
|
37198
|
+
tasks: array(taskViewSchema),
|
|
37199
|
+
itemsTotal: number2().int().nonnegative().default(0),
|
|
37200
|
+
today: number2().int().nonnegative().default(0),
|
|
37201
|
+
previousWeekTotal: number2().int().nonnegative().default(0),
|
|
37202
|
+
byDay: array(landedDaySchema).default([]),
|
|
37203
|
+
bySection: array(object({
|
|
37204
|
+
section: landedSectionSchema,
|
|
37205
|
+
count: number2().int().nonnegative()
|
|
37206
|
+
})).default([]),
|
|
37207
|
+
items: array(landedItemSchema).default([])
|
|
36441
37208
|
});
|
|
36442
37209
|
var searchNodeTypeSchema = _enum2([
|
|
36443
37210
|
"task",
|
|
@@ -36503,9 +37270,15 @@ var readOperations = defineOperations({
|
|
|
36503
37270
|
scopes: ["tasks:read"],
|
|
36504
37271
|
tag: "Reads",
|
|
36505
37272
|
summary: "What landed",
|
|
36506
|
-
description: "What got done in the window by `completedAt` (cancelled tasks never count): the total, a per-Actor split (who finished each \u2014 a member or an Agent), and the tasks, most recently finished first.",
|
|
36507
|
-
query:
|
|
36508
|
-
|
|
37273
|
+
description: "What got done in the window by `completedAt` (cancelled tasks never count): the total, a per-Actor split (who finished each \u2014 a member or an Agent), and the tasks, most recently finished first. Across sections too: `items` (done tasks, habit check-ins, agent sessions' finished tasks, papers filed, shopping lines ticked by anyone; newest last, each with who did it and where it lives), `byDay` (each day of the window in `tz`, by you vs by agents), `bySection` (most first), `itemsTotal`, `today` and `previousWeekTotal` (the same-length window just before). The Agent's and agents' work counts in every total and is marked by `actor.kind` (`echo` / `agent`).",
|
|
37274
|
+
query: [
|
|
37275
|
+
...windowParams,
|
|
37276
|
+
{
|
|
37277
|
+
name: "tz",
|
|
37278
|
+
description: "The IANA zone the window's days are cut in (`Europe/Brussels`). Default UTC."
|
|
37279
|
+
}
|
|
37280
|
+
],
|
|
37281
|
+
querySchema: landedQuerySchema,
|
|
36509
37282
|
status: 200,
|
|
36510
37283
|
response: { description: "The Landed read.", view: "LandedResponse" },
|
|
36511
37284
|
operationId: "get_landed"
|
|
@@ -36765,6 +37538,17 @@ var roleOperations = defineOperations({
|
|
|
36765
37538
|
|
|
36766
37539
|
// ../../packages/schema/src/operations/routines.ts
|
|
36767
37540
|
var routineOperations = defineOperations({
|
|
37541
|
+
today: {
|
|
37542
|
+
method: "get",
|
|
37543
|
+
path: "/routines/today",
|
|
37544
|
+
scopes: ["routines:read"],
|
|
37545
|
+
tag: "Routines",
|
|
37546
|
+
summary: "Today's routines",
|
|
37547
|
+
description: "The routines on the key's member's today (due by their rule, with a slot today, or run today), by start: each with its start (\"HH:MM\", null without a clock time), length, state (`done`, `running`, `upcoming`, `resting`), today's run (`startedAt`, `completedAt`, `done`, `total`) or null, its numbered steps with their kind (`step`, `habit`, `task`), a meta line and whether each is done, and `rhythm`, its last 14 days (`all`, `some`, `none`, `off`), oldest first.",
|
|
37548
|
+
status: 200,
|
|
37549
|
+
response: { description: "`{ today, routines }`." },
|
|
37550
|
+
operationId: "routines_today"
|
|
37551
|
+
},
|
|
36768
37552
|
getRun: {
|
|
36769
37553
|
method: "get",
|
|
36770
37554
|
path: "/routines/runs/{runId}",
|
|
@@ -36920,6 +37704,34 @@ var routineOperations = defineOperations({
|
|
|
36920
37704
|
webhook: "routine.run.updated",
|
|
36921
37705
|
operationId: "routine_all_taken"
|
|
36922
37706
|
},
|
|
37707
|
+
reorderSteps: {
|
|
37708
|
+
method: "patch",
|
|
37709
|
+
path: "/routines/{id}/steps/order",
|
|
37710
|
+
scopes: ["routines:write"],
|
|
37711
|
+
tag: "Routines",
|
|
37712
|
+
summary: "Reorder a routine's steps",
|
|
37713
|
+
description: "Put the routine's template steps in a new order: `stepIds` names each step once, and each takes its index as its position. A list that isn't exactly the routine's steps is a 400. Runs already started keep their order. Fires `routine.updated`.",
|
|
37714
|
+
body: reorderRoutineStepsInputSchema,
|
|
37715
|
+
status: 200,
|
|
37716
|
+
response: { description: "The routine." },
|
|
37717
|
+
errors: { 400: true, 404: true },
|
|
37718
|
+
webhook: "routine.updated",
|
|
37719
|
+
operationId: "reorder_routine_steps"
|
|
37720
|
+
},
|
|
37721
|
+
addTaskStep: {
|
|
37722
|
+
method: "post",
|
|
37723
|
+
path: "/routines/{id}/runs/today/steps",
|
|
37724
|
+
scopes: ["routines:write"],
|
|
37725
|
+
tag: "Routines",
|
|
37726
|
+
summary: "Add a Work task to today's run",
|
|
37727
|
+
description: "Pull a Work task due today into today's run of the routine (the key's member's day) as a step at the end, starting today's run when there's none. The routine's own steps are unchanged. `reason` is the line shown with it (\"Call the plumber is due today in Work, so I added it to the end of this routine.\"). A task not due today is a 422; one already in today's run changes nothing. Ticking the step completes the task in Work; undo reopens it. Fires `routine.run.updated`.",
|
|
37728
|
+
body: addRoutineTaskStepInputSchema,
|
|
37729
|
+
status: 201,
|
|
37730
|
+
response: { description: "Today's run." },
|
|
37731
|
+
errors: { 400: true, 404: true, 422: true },
|
|
37732
|
+
webhook: "routine.run.updated",
|
|
37733
|
+
operationId: "add_routine_task_step"
|
|
37734
|
+
},
|
|
36923
37735
|
startRun: {
|
|
36924
37736
|
method: "post",
|
|
36925
37737
|
path: "/routines/{id}/runs",
|
|
@@ -38549,6 +39361,40 @@ var tapTagOperations = defineOperations({
|
|
|
38549
39361
|
}
|
|
38550
39362
|
});
|
|
38551
39363
|
|
|
39364
|
+
// ../../packages/schema/src/operations/task-blocks.ts
|
|
39365
|
+
var pathParams5 = { id: "The blocked task's ULID or ref (`DO-148`)." };
|
|
39366
|
+
var taskBlockOperations = defineOperations({
|
|
39367
|
+
addBlocker: {
|
|
39368
|
+
method: "post",
|
|
39369
|
+
path: "/tasks/{id}/blocked-by",
|
|
39370
|
+
pathParams: pathParams5,
|
|
39371
|
+
scopes: ["tasks:write"],
|
|
39372
|
+
tag: "Tasks",
|
|
39373
|
+
summary: "Block a task by another",
|
|
39374
|
+
description: "`taskId` (a ULID or ref) blocks this task until it's Done. Both must be live in the Space; a task can't block itself, and a link that would make tasks wait on each other is a 422. Already linked is a no-op.",
|
|
39375
|
+
body: addTaskBlockerInputSchema,
|
|
39376
|
+
status: 200,
|
|
39377
|
+
response: { description: "The blocked task.", view: "Task" },
|
|
39378
|
+
errors: {
|
|
39379
|
+
400: true,
|
|
39380
|
+
404: true,
|
|
39381
|
+
422: "A task can't wait on itself, or the link would make a loop."
|
|
39382
|
+
}
|
|
39383
|
+
},
|
|
39384
|
+
removeBlocker: {
|
|
39385
|
+
method: "delete",
|
|
39386
|
+
path: "/tasks/{id}/blocked-by/{blockerId}",
|
|
39387
|
+
pathParams: { ...pathParams5, blockerId: "The blocker's ULID or ref (`DO-147`)." },
|
|
39388
|
+
scopes: ["tasks:write"],
|
|
39389
|
+
tag: "Tasks",
|
|
39390
|
+
summary: "Unblock a task",
|
|
39391
|
+
description: "The blocker no longer blocks this task. A link that isn't there is a no-op.",
|
|
39392
|
+
status: 200,
|
|
39393
|
+
response: { description: "The task.", view: "Task" },
|
|
39394
|
+
errors: { 404: true }
|
|
39395
|
+
}
|
|
39396
|
+
});
|
|
39397
|
+
|
|
38552
39398
|
// ../../packages/schema/src/operations/tasks.ts
|
|
38553
39399
|
var taskListQuery = taskListQuerySchema.extend(paginationQuerySchema.shape).extend({ filter: taskListFilterSchema.optional().default("all") });
|
|
38554
39400
|
var taskOperations = defineOperations({
|
|
@@ -38572,7 +39418,15 @@ var taskOperations = defineOperations({
|
|
|
38572
39418
|
{ name: "projectId", description: "Only tasks attached to this project (ULID)." },
|
|
38573
39419
|
{
|
|
38574
39420
|
name: "status",
|
|
38575
|
-
description: "Only rows in any of these statuses (comma list or repeated key): `todo`, `in_progress`, `done`, `cancelled`."
|
|
39421
|
+
description: "Only rows in any of these statuses (comma list or repeated key): `backlog`, `todo`, `in_progress`, `waiting`, `done`, `cancelled`."
|
|
39422
|
+
},
|
|
39423
|
+
{
|
|
39424
|
+
name: "priority",
|
|
39425
|
+
description: "Only tasks with any of these priorities (comma list or repeated key): `none`, `low`, `medium`, `high`."
|
|
39426
|
+
},
|
|
39427
|
+
{
|
|
39428
|
+
name: "view",
|
|
39429
|
+
description: "Only the tasks a Work saved view matches (its ULID): exactly the ones its `count` counts."
|
|
38576
39430
|
},
|
|
38577
39431
|
{
|
|
38578
39432
|
name: "tag",
|
|
@@ -38644,7 +39498,7 @@ var taskOperations = defineOperations({
|
|
|
38644
39498
|
scopes: ["tasks:read"],
|
|
38645
39499
|
tag: "Tasks",
|
|
38646
39500
|
summary: "Get a task",
|
|
38647
|
-
description: "Fetch one task by id.",
|
|
39501
|
+
description: "Fetch one task by id (ULID) or by its ref (`DO-142`, case-insensitive).",
|
|
38648
39502
|
status: 200,
|
|
38649
39503
|
response: { description: "The task." },
|
|
38650
39504
|
errors: { 404: true }
|
|
@@ -39168,8 +40022,146 @@ var withingsOperations = defineOperations({
|
|
|
39168
40022
|
}
|
|
39169
40023
|
});
|
|
39170
40024
|
|
|
40025
|
+
// ../../packages/schema/src/db/work-views.ts
|
|
40026
|
+
var workSavedViews = pgTable("work_saved_views", {
|
|
40027
|
+
id: text("id").primaryKey(),
|
|
40028
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
40029
|
+
name: text("name").notNull(),
|
|
40030
|
+
filters: jsonb("filters").notNull().default({}),
|
|
40031
|
+
groupBy: text("group_by").notNull().default("none"),
|
|
40032
|
+
view: text("view").notNull().default("list"),
|
|
40033
|
+
sortOrder: integer2("sort_order").notNull().default(0),
|
|
40034
|
+
pinned: boolean4("pinned").notNull().default(false),
|
|
40035
|
+
defaultKey: text("default_key"),
|
|
40036
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
40037
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
|
|
40038
|
+
deletedAt: timestamp("deleted_at", { withTimezone: true })
|
|
40039
|
+
}, (t) => [
|
|
40040
|
+
index("work_saved_views_tenant_idx").on(t.tenantId, t.sortOrder)
|
|
40041
|
+
]);
|
|
40042
|
+
|
|
40043
|
+
// ../../packages/schema/src/contracts/work-views.ts
|
|
40044
|
+
var workViewGroupBySchema = _enum2([
|
|
40045
|
+
"area",
|
|
40046
|
+
"status",
|
|
40047
|
+
"project",
|
|
40048
|
+
"priority",
|
|
40049
|
+
"assignee",
|
|
40050
|
+
"none"
|
|
40051
|
+
]);
|
|
40052
|
+
var workViewKindSchema = _enum2(["list", "board", "timeline"]);
|
|
40053
|
+
var workViewWindowSchema = _enum2(["overdue", "today", "this_week", "next_week", "none"]);
|
|
40054
|
+
var workViewAssigneeSchema = union([
|
|
40055
|
+
_enum2(["me", "none"]),
|
|
40056
|
+
string2().regex(/^member:[0-9A-HJKMNP-TV-Z]{26}$/, "member:<ULID>"),
|
|
40057
|
+
string2().regex(/^agent:[0-9A-HJKMNP-TV-Z]{26}$/, "agent:<ULID>")
|
|
40058
|
+
]);
|
|
40059
|
+
var workViewFilterSchema = object({
|
|
40060
|
+
status: array(taskStatusSchema).min(1).optional(),
|
|
40061
|
+
notStatus: array(taskStatusSchema).min(1).optional(),
|
|
40062
|
+
areaIds: array(ulidSchema).min(1).optional(),
|
|
40063
|
+
projectIds: array(ulidSchema).min(1).optional(),
|
|
40064
|
+
labels: array(string2().trim().min(1).max(64)).min(1).optional(),
|
|
40065
|
+
priority: array(workPrioritySchema).min(1).optional(),
|
|
40066
|
+
assignee: workViewAssigneeSchema.optional(),
|
|
40067
|
+
waiting: boolean2().optional(),
|
|
40068
|
+
due: workViewWindowSchema.optional(),
|
|
40069
|
+
scheduled: workViewWindowSchema.optional(),
|
|
40070
|
+
when: workViewWindowSchema.optional()
|
|
40071
|
+
}).strict();
|
|
40072
|
+
var workViewDefaultKeySchema = _enum2(["all_open", "this_week", "waiting"]);
|
|
40073
|
+
var workViewNameSchema = string2().trim().min(1).max(80);
|
|
40074
|
+
var workSavedViewSchema = createSelectSchema(workSavedViews, {
|
|
40075
|
+
filters: workViewFilterSchema,
|
|
40076
|
+
groupBy: workViewGroupBySchema,
|
|
40077
|
+
view: workViewKindSchema,
|
|
40078
|
+
defaultKey: workViewDefaultKeySchema.nullable(),
|
|
40079
|
+
createdAt: exports_coerce.date(),
|
|
40080
|
+
updatedAt: exports_coerce.date(),
|
|
40081
|
+
deletedAt: exports_coerce.date().nullable()
|
|
40082
|
+
});
|
|
40083
|
+
var workViewSchema = workSavedViewSchema.omit({ tenantId: true, deletedAt: true }).extend({ count: number2().int().nonnegative() });
|
|
40084
|
+
var createWorkViewInputSchema = object({
|
|
40085
|
+
id: ulidSchema.optional(),
|
|
40086
|
+
name: workViewNameSchema,
|
|
40087
|
+
filters: workViewFilterSchema.default({}),
|
|
40088
|
+
groupBy: workViewGroupBySchema.default("none"),
|
|
40089
|
+
view: workViewKindSchema.default("list"),
|
|
40090
|
+
pinned: boolean2().optional(),
|
|
40091
|
+
sortOrder: number2().int().nonnegative().optional()
|
|
40092
|
+
}).strict();
|
|
40093
|
+
var updateWorkViewInputSchema = object({
|
|
40094
|
+
name: workViewNameSchema.optional(),
|
|
40095
|
+
filters: workViewFilterSchema.optional(),
|
|
40096
|
+
groupBy: workViewGroupBySchema.optional(),
|
|
40097
|
+
view: workViewKindSchema.optional(),
|
|
40098
|
+
pinned: boolean2().optional()
|
|
40099
|
+
}).strict();
|
|
40100
|
+
var reorderWorkViewsInputSchema = object({ ids: array(ulidSchema).min(1).max(200) }).strict();
|
|
40101
|
+
|
|
40102
|
+
// ../../packages/schema/src/operations/work-views.ts
|
|
40103
|
+
var workViewOperations = defineOperations({
|
|
40104
|
+
list: {
|
|
40105
|
+
method: "get",
|
|
40106
|
+
path: "/work-views",
|
|
40107
|
+
scopes: ["tasks:read"],
|
|
40108
|
+
tag: "Tasks",
|
|
40109
|
+
summary: "List Work saved views",
|
|
40110
|
+
description: "The Space's saved Work views in order, each with its filters, grouping, view kind and live `count` of the tasks the key may view that it matches. A Space's first read seeds All open, This week and Waiting on someone.",
|
|
40111
|
+
status: 200,
|
|
40112
|
+
response: { description: "The views, in order." }
|
|
40113
|
+
},
|
|
40114
|
+
create: {
|
|
40115
|
+
method: "post",
|
|
40116
|
+
path: "/work-views",
|
|
40117
|
+
scopes: ["tasks:write"],
|
|
40118
|
+
tag: "Tasks",
|
|
40119
|
+
summary: "Save a Work view",
|
|
40120
|
+
description: "A named filter (strict: an unknown key is a 400), with `groupBy` and `view`; it goes last unless `sortOrder` says where.",
|
|
40121
|
+
body: createWorkViewInputSchema,
|
|
40122
|
+
status: 201,
|
|
40123
|
+
response: { description: "The saved view, with its count." },
|
|
40124
|
+
errors: { 400: true }
|
|
40125
|
+
},
|
|
40126
|
+
reorder: {
|
|
40127
|
+
method: "post",
|
|
40128
|
+
path: "/work-views/reorder",
|
|
40129
|
+
scopes: ["tasks:write"],
|
|
40130
|
+
tag: "Tasks",
|
|
40131
|
+
summary: "Reorder Work views",
|
|
40132
|
+
description: "The listed views first, in the order given; any not listed keep their order after them. An unknown id is a 404.",
|
|
40133
|
+
body: reorderWorkViewsInputSchema,
|
|
40134
|
+
status: 200,
|
|
40135
|
+
response: { description: "The views, in their new order." },
|
|
40136
|
+
errors: { 400: true, 404: true }
|
|
40137
|
+
},
|
|
40138
|
+
update: {
|
|
40139
|
+
method: "patch",
|
|
40140
|
+
path: "/work-views/{id}",
|
|
40141
|
+
scopes: ["tasks:write"],
|
|
40142
|
+
tag: "Tasks",
|
|
40143
|
+
summary: "Update a Work view",
|
|
40144
|
+
description: "Rename it, or change its filters (replaced whole), grouping, view kind or pin.",
|
|
40145
|
+
body: updateWorkViewInputSchema,
|
|
40146
|
+
status: 200,
|
|
40147
|
+
response: { description: "The view, with its count." },
|
|
40148
|
+
errors: { 400: true, 404: true }
|
|
40149
|
+
},
|
|
40150
|
+
remove: {
|
|
40151
|
+
method: "delete",
|
|
40152
|
+
path: "/work-views/{id}",
|
|
40153
|
+
scopes: ["tasks:write"],
|
|
40154
|
+
tag: "Tasks",
|
|
40155
|
+
summary: "Delete a Work view",
|
|
40156
|
+
description: "Delete a view, a default one too; it isn't seeded again.",
|
|
40157
|
+
status: 204,
|
|
40158
|
+
response: { description: "Deleted." },
|
|
40159
|
+
errors: { 404: true }
|
|
40160
|
+
}
|
|
40161
|
+
});
|
|
40162
|
+
|
|
39171
40163
|
// ../../packages/schema/src/operations/worktree-links.ts
|
|
39172
|
-
var
|
|
40164
|
+
var pathParams6 = { nodeId: "The linked Task's or Project's ULID." };
|
|
39173
40165
|
var notLinkable = "No live Task or Project with that id in this Space (or, for GET, no link on it).";
|
|
39174
40166
|
var worktreeLinkOperations = defineOperations({
|
|
39175
40167
|
list: {
|
|
@@ -39195,7 +40187,7 @@ var worktreeLinkOperations = defineOperations({
|
|
|
39195
40187
|
get: {
|
|
39196
40188
|
method: "get",
|
|
39197
40189
|
path: "/worktree-links/{nodeId}",
|
|
39198
|
-
pathParams:
|
|
40190
|
+
pathParams: pathParams6,
|
|
39199
40191
|
scopes: ["orca:read"],
|
|
39200
40192
|
tag: "Orca",
|
|
39201
40193
|
summary: "Get a worktree link",
|
|
@@ -39207,7 +40199,7 @@ var worktreeLinkOperations = defineOperations({
|
|
|
39207
40199
|
set: {
|
|
39208
40200
|
method: "put",
|
|
39209
40201
|
path: "/worktree-links/{nodeId}",
|
|
39210
|
-
pathParams:
|
|
40202
|
+
pathParams: pathParams6,
|
|
39211
40203
|
scopes: ["orca:write"],
|
|
39212
40204
|
tag: "Orca",
|
|
39213
40205
|
summary: "Set a worktree link",
|
|
@@ -39221,7 +40213,7 @@ var worktreeLinkOperations = defineOperations({
|
|
|
39221
40213
|
clear: {
|
|
39222
40214
|
method: "delete",
|
|
39223
40215
|
path: "/worktree-links/{nodeId}",
|
|
39224
|
-
pathParams:
|
|
40216
|
+
pathParams: pathParams6,
|
|
39225
40217
|
scopes: ["orca:write"],
|
|
39226
40218
|
tag: "Orca",
|
|
39227
40219
|
summary: "Clear a worktree link",
|
|
@@ -39750,7 +40742,8 @@ var filmFacetSchema = object({
|
|
|
39750
40742
|
coverUrl,
|
|
39751
40743
|
episodeCount: number2().int().min(1).max(1e4).nullish(),
|
|
39752
40744
|
currentEpisode: number2().int().min(0).max(1e4).nullish(),
|
|
39753
|
-
format: string2().min(1).max(60).nullish()
|
|
40745
|
+
format: string2().min(1).max(60).nullish(),
|
|
40746
|
+
runtimeMinutes: number2().int().min(1).max(2000).nullish()
|
|
39754
40747
|
}).strict();
|
|
39755
40748
|
var gameFacetSchema = object({
|
|
39756
40749
|
platform: string2().min(1).max(120).nullish(),
|
|
@@ -39764,11 +40757,30 @@ var gameFacetSchema = object({
|
|
|
39764
40757
|
year: number2().int().min(1950).max(2100).nullish(),
|
|
39765
40758
|
playedWith: string2().min(1).max(120).nullish()
|
|
39766
40759
|
}).strict();
|
|
40760
|
+
var musicTrackSchema = object({
|
|
40761
|
+
pos: string2().min(1).max(8),
|
|
40762
|
+
title: string2().min(1).max(200),
|
|
40763
|
+
seconds: number2().int().min(0).max(36000).nullish()
|
|
40764
|
+
}).strict();
|
|
39767
40765
|
var musicFacetSchema = object({
|
|
39768
40766
|
artist: string2().min(1).max(200).nullish(),
|
|
39769
40767
|
year: number2().int().min(1860).max(2100).nullish(),
|
|
39770
40768
|
coverUrl,
|
|
39771
|
-
format: string2().min(1).max(60).nullish()
|
|
40769
|
+
format: string2().min(1).max(60).nullish(),
|
|
40770
|
+
edition: string2().min(1).max(60).nullish(),
|
|
40771
|
+
tracks: array(musicTrackSchema).max(60).nullish()
|
|
40772
|
+
}).strict();
|
|
40773
|
+
var hobbyFacetSchema = object({
|
|
40774
|
+
kind: string2().min(1).max(40).nullish(),
|
|
40775
|
+
progress: object({
|
|
40776
|
+
done: number2().int().min(0).max(1e5),
|
|
40777
|
+
total: number2().int().min(1).max(1e5),
|
|
40778
|
+
unit: string2().min(1).max(40)
|
|
40779
|
+
}).strict().nullish(),
|
|
40780
|
+
shelf: _enum2(["display", "boxed"]).default("display"),
|
|
40781
|
+
needsFix: boolean2().nullish(),
|
|
40782
|
+
fixNote: string2().min(1).max(200).nullish(),
|
|
40783
|
+
coverUrl
|
|
39772
40784
|
}).strict();
|
|
39773
40785
|
var placeFacetSchema = object({
|
|
39774
40786
|
address: string2().min(1).max(400).nullish(),
|
|
@@ -39996,6 +41008,16 @@ var COLLECTION_TYPES = {
|
|
|
39996
41008
|
facetSchema: assetFacetSchema,
|
|
39997
41009
|
view: "grid",
|
|
39998
41010
|
subtitleKey: "brand"
|
|
41011
|
+
},
|
|
41012
|
+
hobby: {
|
|
41013
|
+
key: "hobby",
|
|
41014
|
+
label: "Things",
|
|
41015
|
+
itemNoun: "thing",
|
|
41016
|
+
statuses: ["want", "doing", "have"],
|
|
41017
|
+
statusLabels: { want: "Want", doing: "Building", have: "Built" },
|
|
41018
|
+
facetSchema: hobbyFacetSchema,
|
|
41019
|
+
view: "grid",
|
|
41020
|
+
subtitleKey: "kind"
|
|
39999
41021
|
}
|
|
40000
41022
|
};
|
|
40001
41023
|
var COLLECTION_TYPE_LIST = collectionTypeValues.map((k) => COLLECTION_TYPES[k]);
|
|
@@ -40074,8 +41096,11 @@ var STATUS_MARK = {
|
|
|
40074
41096
|
done: "\u2713",
|
|
40075
41097
|
cancelled: "\u2717",
|
|
40076
41098
|
in_progress: "\u25D0",
|
|
40077
|
-
todo: "\u25CB"
|
|
41099
|
+
todo: "\u25CB",
|
|
41100
|
+
backlog: "\u25CC",
|
|
41101
|
+
waiting: "\u29D7"
|
|
40078
41102
|
};
|
|
41103
|
+
var PRIORITY_WORD = { low: "low", medium: "medium", high: "high" };
|
|
40079
41104
|
function suggestionText(s) {
|
|
40080
41105
|
const parts = [
|
|
40081
41106
|
[s.area, s.project].filter(Boolean).join(" \u203A ") || null,
|
|
@@ -40100,18 +41125,24 @@ function renderTask(data, mode) {
|
|
|
40100
41125
|
const date = when ? paint(mode, "dim", ` (${shortDate(when)})`) : "";
|
|
40101
41126
|
const by = t.createdBy?.kind === "agent" ? paint(mode, "dim", ` \xB7 by ${t.createdBy.name ?? "an agent"}`) : "";
|
|
40102
41127
|
const meta = [
|
|
41128
|
+
t.priority && PRIORITY_WORD[t.priority] ? `${PRIORITY_WORD[t.priority]} priority` : null,
|
|
40103
41129
|
t.owner ? `owner ${ownerText(t.owner)}` : null,
|
|
40104
|
-
t.nextStep ? `next: ${t.nextStep}` : null
|
|
41130
|
+
t.nextStep ? `next: ${t.nextStep}` : null,
|
|
41131
|
+
t.deliverable ? `delivers: ${t.deliverable}` : null
|
|
40105
41132
|
].filter(Boolean);
|
|
40106
41133
|
const waiting = t.waitingOn ? `
|
|
40107
41134
|
${paint(mode, "yellow", `\u29D7 waiting on ${t.waitingOn.name ?? "someone"}`)}` : "";
|
|
40108
41135
|
const metaLine = meta.length > 0 ? `
|
|
40109
41136
|
${paint(mode, "dim", meta.join(" \xB7 "))}` : "";
|
|
41137
|
+
const holding = (t.blockedBy ?? []).filter((b) => b.status !== "done");
|
|
41138
|
+
const blocked = t.isBlocked && holding.length > 0 ? `
|
|
41139
|
+
${paint(mode, "yellow", `\u2298 blocked by ${holding.map((b) => `${b.ref ?? ""} ${b.title ?? ""}`.trim()).join(", ")}`)}` : "";
|
|
40110
41140
|
const worktree = t.worktreeLink ? `
|
|
40111
41141
|
${paint(mode, "dim", `\u2387 ${worktreeText(t.worktreeLink)}`)}` : "";
|
|
40112
41142
|
const suggestion = t.filingSuggestion ? `
|
|
40113
41143
|
${paint(mode, "dim", `\u2726 ${suggestionText(t.filingSuggestion)}`)}` : "";
|
|
40114
|
-
|
|
41144
|
+
const ref = t.ref ? `${t.ref} ` : "";
|
|
41145
|
+
return `${mark} ${ref}${star}${t.title ?? "(untitled)"}${date}${by}${waiting}${blocked}${metaLine}${worktree}${suggestion}
|
|
40115
41146
|
${paint(mode, "dim", t.id)}`;
|
|
40116
41147
|
}
|
|
40117
41148
|
function renderToday(data, mode) {
|
|
@@ -40437,7 +41468,8 @@ function renderList(data, mode) {
|
|
|
40437
41468
|
const body = rows.length === 0 ? paint(mode, "dim", "(no records)") : [
|
|
40438
41469
|
`${rows.length} record(s):`,
|
|
40439
41470
|
...rows.map((row) => {
|
|
40440
|
-
const
|
|
41471
|
+
const ref = refOf(row);
|
|
41472
|
+
const label = ref ? `${ref} ${labelOf(row)}` : labelOf(row);
|
|
40441
41473
|
const id = idOf(row);
|
|
40442
41474
|
return id ? ` ${label} ${paint(mode, "dim", id)}` : ` ${label}`;
|
|
40443
41475
|
})
|
|
@@ -40448,6 +41480,12 @@ function renderList(data, mode) {
|
|
|
40448
41480
|
return `${body}
|
|
40449
41481
|
${paint(mode, "dim", `\u2026 more \u2014 rerun with --cursor ${nextCursor}`)}`;
|
|
40450
41482
|
}
|
|
41483
|
+
function refOf(row) {
|
|
41484
|
+
if (row === null || typeof row !== "object")
|
|
41485
|
+
return null;
|
|
41486
|
+
const ref = row.ref;
|
|
41487
|
+
return typeof ref === "string" && ref.length > 0 ? ref : null;
|
|
41488
|
+
}
|
|
40451
41489
|
function asPage(data) {
|
|
40452
41490
|
if (Array.isArray(data))
|
|
40453
41491
|
return { rows: data, nextCursor: null };
|
|
@@ -41325,6 +42363,9 @@ function mergePreview(before, changes) {
|
|
|
41325
42363
|
}
|
|
41326
42364
|
|
|
41327
42365
|
// src/entities.ts
|
|
42366
|
+
function taskStatusWire(value) {
|
|
42367
|
+
return value.trim().toLowerCase().replace(/-/g, "_");
|
|
42368
|
+
}
|
|
41328
42369
|
var AREA_FLAG = {
|
|
41329
42370
|
name: "area",
|
|
41330
42371
|
description: "only rows in this area id",
|
|
@@ -41386,7 +42427,12 @@ var ENTITIES = [
|
|
|
41386
42427
|
{ name: "project", description: "only tasks in this project id", query: "projectId" },
|
|
41387
42428
|
{
|
|
41388
42429
|
name: "status",
|
|
41389
|
-
description: "only these statuses, comma-separated (todo,
|
|
42430
|
+
description: "only these statuses, comma-separated (backlog,todo,in-progress,waiting,done,cancelled)",
|
|
42431
|
+
normalize: taskStatusWire
|
|
42432
|
+
},
|
|
42433
|
+
{
|
|
42434
|
+
name: "priority",
|
|
42435
|
+
description: "only these priorities, comma-separated (none,low,medium,high)"
|
|
41390
42436
|
},
|
|
41391
42437
|
{ name: "tag", description: "only tasks carrying every listed tag, comma-separated" },
|
|
41392
42438
|
UPDATED_SINCE_FLAG,
|
|
@@ -42888,7 +43934,7 @@ var commands5 = [
|
|
|
42888
43934
|
notes: `${routeOf(calendarOperations.status)}. retrying = a passing failure the sweep retries; reconnect = the member reconnects in Settings. Needs a key that acts for a member.`
|
|
42889
43935
|
},
|
|
42890
43936
|
run: async ({ requireClient }) => ({
|
|
42891
|
-
data: await requireClient().
|
|
43937
|
+
data: (await requireClient().getPage(pathOf(calendarOperations.status))).data,
|
|
42892
43938
|
render: renderCalendarStatus
|
|
42893
43939
|
})
|
|
42894
43940
|
},
|
|
@@ -42899,11 +43945,11 @@ var commands5 = [
|
|
|
42899
43945
|
args: [],
|
|
42900
43946
|
flags: [],
|
|
42901
43947
|
scopes: [...calendarOperations.push.scopes],
|
|
42902
|
-
returns: "CalendarPushResult[]",
|
|
43948
|
+
returns: "{ pushed: CalendarPushResult[] }",
|
|
42903
43949
|
notes: `${routeOf(calendarOperations.push)}. A connection that needs reconnecting is left out. Needs a key that acts for a member.`
|
|
42904
43950
|
},
|
|
42905
43951
|
run: async ({ requireClient }) => ({
|
|
42906
|
-
data: await requireClient().post(pathOf(calendarOperations.push), {}),
|
|
43952
|
+
data: (await requireClient().post(pathOf(calendarOperations.push), {})).pushed,
|
|
42907
43953
|
render: renderCalendarPush
|
|
42908
43954
|
})
|
|
42909
43955
|
},
|
|
@@ -43166,7 +44212,11 @@ var commands8 = [
|
|
|
43166
44212
|
summary: "List Collection Items, optionally sliced by Type / Status / tag.",
|
|
43167
44213
|
args: [],
|
|
43168
44214
|
flags: [
|
|
43169
|
-
{
|
|
44215
|
+
{
|
|
44216
|
+
name: "type",
|
|
44217
|
+
type: "string",
|
|
44218
|
+
description: "Filter to one Type (book|film|game|\u2026|hobby)."
|
|
44219
|
+
},
|
|
43170
44220
|
{
|
|
43171
44221
|
name: "status",
|
|
43172
44222
|
type: "string",
|
|
@@ -43209,7 +44259,11 @@ var commands8 = [
|
|
|
43209
44259
|
summary: "Add a Collection Item (the title may embed #tag).",
|
|
43210
44260
|
args: [{ name: "title", required: true, description: "Item title; may embed #tag." }],
|
|
43211
44261
|
flags: [
|
|
43212
|
-
{
|
|
44262
|
+
{
|
|
44263
|
+
name: "type",
|
|
44264
|
+
type: "string",
|
|
44265
|
+
description: "Type (book|film|game|music|place|wine|wardrobe|hobby)."
|
|
44266
|
+
},
|
|
43213
44267
|
{
|
|
43214
44268
|
name: "status",
|
|
43215
44269
|
type: "string",
|
|
@@ -43221,15 +44275,16 @@ var commands8 = [
|
|
|
43221
44275
|
grammar: {
|
|
43222
44276
|
"#tag": "Adds a tag. Repeatable: '#scifi #2024'."
|
|
43223
44277
|
},
|
|
43224
|
-
notes:
|
|
44278
|
+
notes: '--type is required; the per-Type facet rides --data (validated server-side against the Type), e.g. `do collection add "Castle" --type hobby --status doing --data \'{"facet":{"kind":"LEGO","progress":{"done":7,"total":12,"unit":"bag"}}}\'`.'
|
|
43225
44279
|
},
|
|
43226
44280
|
run: async ({ args, flags, requireClient }) => {
|
|
43227
44281
|
const { title, tags } = parseTitleTags(args);
|
|
43228
44282
|
if (title.length === 0)
|
|
43229
44283
|
throw usageError('collection add needs a title, e.g. `do collection add "Dune" --type book`');
|
|
43230
|
-
const type = requireFlag(flags, "type", "collection add needs --type <book|film|game|music|place|wine>");
|
|
44284
|
+
const type = requireFlag(flags, "type", "collection add needs --type <book|film|game|music|place|wine|wardrobe|hobby>");
|
|
43231
44285
|
const body = parseInput(createCollectionItemInputSchema, {
|
|
43232
44286
|
id: ulid3(),
|
|
44287
|
+
...readDataFlag(flags),
|
|
43233
44288
|
type,
|
|
43234
44289
|
title,
|
|
43235
44290
|
...tags.length > 0 ? { tags } : {},
|
|
@@ -45975,7 +47030,144 @@ var commands19 = [
|
|
|
45975
47030
|
];
|
|
45976
47031
|
|
|
45977
47032
|
// src/commands/habits.ts
|
|
47033
|
+
var SCHEDULE_FLAGS = [
|
|
47034
|
+
{ name: "every-day", type: "boolean", description: "Due every day." },
|
|
47035
|
+
{
|
|
47036
|
+
name: "on",
|
|
47037
|
+
type: "string",
|
|
47038
|
+
description: "Due on these weekdays, comma-separated (mo,we,fr)."
|
|
47039
|
+
},
|
|
47040
|
+
{
|
|
47041
|
+
name: "every",
|
|
47042
|
+
type: "string",
|
|
47043
|
+
description: "Due every N days or weeks (3d, 2w), counted in calendar days from --from, never from the last check-in."
|
|
47044
|
+
},
|
|
47045
|
+
{
|
|
47046
|
+
name: "from",
|
|
47047
|
+
type: "string",
|
|
47048
|
+
description: "The day --every counts from, YYYY-MM-DD (default today)."
|
|
47049
|
+
},
|
|
47050
|
+
{
|
|
47051
|
+
name: "monthly",
|
|
47052
|
+
type: "string",
|
|
47053
|
+
description: "Due monthly on this day of the month: 1\u201331 (a 31 falls on a shorter month's last day), or last."
|
|
47054
|
+
},
|
|
47055
|
+
{ name: "data", type: "string", description: "JSON for any other field of the contract." }
|
|
47056
|
+
];
|
|
47057
|
+
var SCHEDULE_NOTES = "One of --every-day, --on mo,we,fr, --every 3d|2w [--from YYYY-MM-DD], --monthly 1|last sets its schedule; days it isn't due never break the streak. Without one, it keeps `period` + `frequencyCount` (3\xD7 a week). The reply's `nextDue` lists its next 4 due days.";
|
|
47058
|
+
function localToday() {
|
|
47059
|
+
const now = new Date;
|
|
47060
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
47061
|
+
return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}`;
|
|
47062
|
+
}
|
|
47063
|
+
function scheduleFromFlags(flags, today = localToday()) {
|
|
47064
|
+
const on = flagString(flags, "on");
|
|
47065
|
+
const every = flagString(flags, "every");
|
|
47066
|
+
const monthly = flagString(flags, "monthly");
|
|
47067
|
+
const given = [flagBool(flags, "every-day"), on, every, monthly].filter((v) => v !== undefined && v !== false);
|
|
47068
|
+
if (given.length > 1)
|
|
47069
|
+
throw usageError("pick one schedule: --every-day, --on, --every or --monthly");
|
|
47070
|
+
if (flagString(flags, "from") !== undefined && every === undefined)
|
|
47071
|
+
throw usageError("--from goes with --every");
|
|
47072
|
+
if (flagBool(flags, "every-day"))
|
|
47073
|
+
return { kind: "daily" };
|
|
47074
|
+
if (on !== undefined) {
|
|
47075
|
+
const days = on.split(",").map((d) => d.trim().toUpperCase()).filter((d) => d.length > 0);
|
|
47076
|
+
return { kind: "weekdays", days };
|
|
47077
|
+
}
|
|
47078
|
+
if (every !== undefined) {
|
|
47079
|
+
const m = /^(\d+)\s*([dw])$/i.exec(every.trim());
|
|
47080
|
+
if (!m)
|
|
47081
|
+
throw usageError("--every takes a number of days or weeks: 3d or 2w");
|
|
47082
|
+
return {
|
|
47083
|
+
kind: "every",
|
|
47084
|
+
interval: Number(m[1]),
|
|
47085
|
+
unit: m[2]?.toLowerCase() === "w" ? "week" : "day",
|
|
47086
|
+
anchor: flagString(flags, "from") ?? today
|
|
47087
|
+
};
|
|
47088
|
+
}
|
|
47089
|
+
if (monthly !== undefined) {
|
|
47090
|
+
const day = monthly.trim().toLowerCase() === "last" ? -1 : Number(monthly);
|
|
47091
|
+
if (!Number.isInteger(day))
|
|
47092
|
+
throw usageError("--monthly takes a day of the month (1\u201331) or last");
|
|
47093
|
+
return { kind: "monthly", dayOfMonth: day };
|
|
47094
|
+
}
|
|
47095
|
+
return;
|
|
47096
|
+
}
|
|
45978
47097
|
var commands20 = [
|
|
47098
|
+
{
|
|
47099
|
+
spec: {
|
|
47100
|
+
path: ["habits", "create"],
|
|
47101
|
+
summary: "Create a habit, with an optional schedule (every day, weekdays, every N, monthly).",
|
|
47102
|
+
args: [{ name: "title", required: false, description: "The habit's title." }],
|
|
47103
|
+
flags: SCHEDULE_FLAGS,
|
|
47104
|
+
scopes: [...habitOperations.create.scopes],
|
|
47105
|
+
returns: "HabitSummary",
|
|
47106
|
+
notes: `${routeOf(habitOperations.create)}. --data carries the rest of a CreateHabitInput; the id is minted and a yes/no measurement assumed when omitted. ${SCHEDULE_NOTES} e.g. \`do habits create "Water the plants" --every 3d\`.`
|
|
47107
|
+
},
|
|
47108
|
+
run: async ({ args, flags, requireClient }) => {
|
|
47109
|
+
const title = args.join(" ").trim();
|
|
47110
|
+
const schedule = scheduleFromFlags(flags);
|
|
47111
|
+
const body = parseInput(createHabitInputSchema, {
|
|
47112
|
+
id: ulid3(),
|
|
47113
|
+
measurementType: "binary",
|
|
47114
|
+
...title ? { title } : {},
|
|
47115
|
+
...readDataFlag(flags),
|
|
47116
|
+
...schedule ? { schedule } : {}
|
|
47117
|
+
});
|
|
47118
|
+
if (flagBool(flags, "dry-run")) {
|
|
47119
|
+
return {
|
|
47120
|
+
data: { dryRun: true, op: "create", entity: "habits", after: body },
|
|
47121
|
+
render: renderRecord
|
|
47122
|
+
};
|
|
47123
|
+
}
|
|
47124
|
+
return {
|
|
47125
|
+
data: await requireClient().post(pathOf(habitOperations.create), body),
|
|
47126
|
+
render: renderRecord
|
|
47127
|
+
};
|
|
47128
|
+
}
|
|
47129
|
+
},
|
|
47130
|
+
{
|
|
47131
|
+
spec: {
|
|
47132
|
+
path: ["habits", "update"],
|
|
47133
|
+
summary: "Change a habit: its schedule (--every-day, --on, --every, --monthly) or --data.",
|
|
47134
|
+
args: [{ name: "id", required: true, description: "Habit ULID." }],
|
|
47135
|
+
flags: SCHEDULE_FLAGS,
|
|
47136
|
+
scopes: [...habitOperations.update.scopes],
|
|
47137
|
+
returns: "HabitSummary",
|
|
47138
|
+
notes: `${routeOf(habitOperations.update)}. Only what you pass changes. ${SCHEDULE_NOTES}`
|
|
47139
|
+
},
|
|
47140
|
+
run: async ({ args, flags, requireClient }) => {
|
|
47141
|
+
const id = requireArg(args, 0, "habit id");
|
|
47142
|
+
const schedule = scheduleFromFlags(flags);
|
|
47143
|
+
const body = parseInput(updateHabitInputSchema, {
|
|
47144
|
+
...readDataFlag(flags),
|
|
47145
|
+
...schedule ? { schedule } : {}
|
|
47146
|
+
});
|
|
47147
|
+
if (Object.keys(body).length === 0)
|
|
47148
|
+
throw usageError("nothing to change \u2014 pass a schedule flag such as --on mo,we, or --data");
|
|
47149
|
+
const client = requireClient();
|
|
47150
|
+
if (flagBool(flags, "dry-run")) {
|
|
47151
|
+
const before = await client.get(pathOf(habitOperations.get, { id }));
|
|
47152
|
+
return {
|
|
47153
|
+
data: {
|
|
47154
|
+
dryRun: true,
|
|
47155
|
+
op: "update",
|
|
47156
|
+
entity: "habits",
|
|
47157
|
+
id,
|
|
47158
|
+
before,
|
|
47159
|
+
after: mergePreview(before, body),
|
|
47160
|
+
changes: body
|
|
47161
|
+
},
|
|
47162
|
+
render: renderRecord
|
|
47163
|
+
};
|
|
47164
|
+
}
|
|
47165
|
+
return {
|
|
47166
|
+
data: await client.patch(pathOf(habitOperations.update, { id }), body),
|
|
47167
|
+
render: renderRecord
|
|
47168
|
+
};
|
|
47169
|
+
}
|
|
47170
|
+
},
|
|
45979
47171
|
{
|
|
45980
47172
|
spec: {
|
|
45981
47173
|
path: ["habit", "log"],
|
|
@@ -47504,8 +48696,126 @@ var commands22 = [
|
|
|
47504
48696
|
}
|
|
47505
48697
|
];
|
|
47506
48698
|
|
|
47507
|
-
// src/commands/
|
|
48699
|
+
// src/commands/inbox.ts
|
|
48700
|
+
function renderInbox(data, _mode) {
|
|
48701
|
+
const d = data;
|
|
48702
|
+
const items = d.items ?? [];
|
|
48703
|
+
const c = d.counts ?? {};
|
|
48704
|
+
const head = `${c.all ?? items.length} waiting \xB7 ${c.capture ?? 0} captures \xB7 ${c.proposal ?? 0} proposals \xB7 ${c.answer ?? 0} need an answer`;
|
|
48705
|
+
if (items.length === 0)
|
|
48706
|
+
return `${head}
|
|
48707
|
+
Nothing waits here.`;
|
|
48708
|
+
const lines = items.map((item) => {
|
|
48709
|
+
const primary = item.actions.find((a) => a.primary);
|
|
48710
|
+
const action = primary ? ` [${primary.label} (${primary.key})]` : "";
|
|
48711
|
+
return `${item.id} ${item.kind.padEnd(8)} ${item.title} \u2014 ${item.source} \xB7 ${item.meta}${action}`;
|
|
48712
|
+
});
|
|
48713
|
+
return [head, ...lines].join(`
|
|
48714
|
+
`);
|
|
48715
|
+
}
|
|
48716
|
+
function renderSorting(data, _mode) {
|
|
48717
|
+
const d = data;
|
|
48718
|
+
return [
|
|
48719
|
+
`Captured by ${d.original.how}: \u201C${d.original.text}\u201D`,
|
|
48720
|
+
`Becomes a ${d.becomes}`,
|
|
48721
|
+
...d.facts.map((f) => ` ${f.key}: ${f.value}`),
|
|
48722
|
+
...d.why ? [d.why] : []
|
|
48723
|
+
].join(`
|
|
48724
|
+
`);
|
|
48725
|
+
}
|
|
47508
48726
|
var commands23 = [
|
|
48727
|
+
defineCommand({
|
|
48728
|
+
operation: inboxOperations.list,
|
|
48729
|
+
path: ["inbox"],
|
|
48730
|
+
summary: "The Inbox: captures, the agent's proposals and notifications that need an answer, oldest first, with per-kind counts.",
|
|
48731
|
+
flags: [
|
|
48732
|
+
{
|
|
48733
|
+
name: "kind",
|
|
48734
|
+
type: "string",
|
|
48735
|
+
description: "all (default), capture, proposal or answer."
|
|
48736
|
+
}
|
|
48737
|
+
],
|
|
48738
|
+
notes: ". Each row names its one primary action and key (File e \xB7 Approve a \xB7 Decline d); approve and decline a proposal with `do tasks accept <id>` / `do task cancel <id>`, sort a capture with `do inbox sort`.",
|
|
48739
|
+
run: async ({ flags, requireClient }) => {
|
|
48740
|
+
const kind = flagString(flags, "kind");
|
|
48741
|
+
if (kind !== undefined && !inboxFilterSchema.safeParse(kind).success) {
|
|
48742
|
+
throw usageError(`--kind must be one of ${inboxFilterSchema.options.join(", ")}`);
|
|
48743
|
+
}
|
|
48744
|
+
return {
|
|
48745
|
+
data: await requireClient().get(pathOf(inboxOperations.list), {
|
|
48746
|
+
query: { kind }
|
|
48747
|
+
}),
|
|
48748
|
+
render: renderInbox
|
|
48749
|
+
};
|
|
48750
|
+
}
|
|
48751
|
+
}),
|
|
48752
|
+
defineCommand({
|
|
48753
|
+
operation: inboxOperations.sorting,
|
|
48754
|
+
path: ["inbox", "sorting"],
|
|
48755
|
+
summary: "The sorting pane for a capture: what it becomes and what the agent filled in.",
|
|
48756
|
+
args: [{ name: "id", required: true, description: "The capture's id." }],
|
|
48757
|
+
run: async ({ args, requireClient }) => ({
|
|
48758
|
+
data: await requireClient().get(pathOf(inboxOperations.sorting, { id: requireArg(args, 0, "id") })),
|
|
48759
|
+
render: renderSorting
|
|
48760
|
+
})
|
|
48761
|
+
}),
|
|
48762
|
+
defineCommand({
|
|
48763
|
+
operation: inboxOperations.sort,
|
|
48764
|
+
path: ["inbox", "sort"],
|
|
48765
|
+
summary: "Sort a capture into its home: a task, note, habit or log entry.",
|
|
48766
|
+
args: [{ name: "id", required: true, description: "The capture's id." }],
|
|
48767
|
+
flags: [
|
|
48768
|
+
{
|
|
48769
|
+
name: "as",
|
|
48770
|
+
type: "string",
|
|
48771
|
+
description: "task, note, habit or log (required)."
|
|
48772
|
+
},
|
|
48773
|
+
{
|
|
48774
|
+
name: "area",
|
|
48775
|
+
type: "string",
|
|
48776
|
+
description: "File it in this Area (id); a task without one takes the agent's suggestion."
|
|
48777
|
+
},
|
|
48778
|
+
{
|
|
48779
|
+
name: "title",
|
|
48780
|
+
type: "string",
|
|
48781
|
+
description: "A new title for what it becomes."
|
|
48782
|
+
}
|
|
48783
|
+
],
|
|
48784
|
+
notes: ". A task keeps its id and is filed (the agent's suggestion unless --area); a note or habit is made from it (needs notes:write or habits:write) and the capture removed. `log` waits for the Log something writer.",
|
|
48785
|
+
run: async ({ args, flags, requireClient }) => {
|
|
48786
|
+
const id = requireArg(args, 0, "id");
|
|
48787
|
+
const as = requireFlag(flags, "as", `inbox sort needs --as ${INBOX_SORT_AS.join("|")}`);
|
|
48788
|
+
if (!INBOX_SORT_AS.includes(as)) {
|
|
48789
|
+
throw usageError(`--as must be one of ${INBOX_SORT_AS.join(", ")} (got \`${as}\`)`);
|
|
48790
|
+
}
|
|
48791
|
+
const area = flagString(flags, "area");
|
|
48792
|
+
const title = flagString(flags, "title");
|
|
48793
|
+
const fields = {
|
|
48794
|
+
...area ? { areaId: area } : {},
|
|
48795
|
+
...title ? { title } : {}
|
|
48796
|
+
};
|
|
48797
|
+
const body = Object.keys(fields).length > 0 ? { as, fields } : { as };
|
|
48798
|
+
return {
|
|
48799
|
+
data: await requireClient().post(pathOf(inboxOperations.sort, { id }), body),
|
|
48800
|
+
render: renderRecord
|
|
48801
|
+
};
|
|
48802
|
+
}
|
|
48803
|
+
}),
|
|
48804
|
+
defineCommand({
|
|
48805
|
+
operation: inboxOperations.letGo,
|
|
48806
|
+
path: ["inbox", "let-go"],
|
|
48807
|
+
summary: "Let a capture go: cancelled, out of the Inbox, never counted as Landed.",
|
|
48808
|
+
args: [{ name: "id", required: true, description: "The capture's id." }],
|
|
48809
|
+
notes: ". Changed your mind? `do task reopen <id>`.",
|
|
48810
|
+
run: async ({ args, requireClient }) => ({
|
|
48811
|
+
data: await requireClient().post(pathOf(inboxOperations.letGo, { id: requireArg(args, 0, "id") }), {}),
|
|
48812
|
+
render: renderRecord
|
|
48813
|
+
})
|
|
48814
|
+
})
|
|
48815
|
+
];
|
|
48816
|
+
|
|
48817
|
+
// src/commands/incidents.ts
|
|
48818
|
+
var commands24 = [
|
|
47509
48819
|
{
|
|
47510
48820
|
spec: {
|
|
47511
48821
|
path: ["incidents", "open"],
|
|
@@ -47734,7 +49044,7 @@ function journalDateArg(args, verb) {
|
|
|
47734
49044
|
}
|
|
47735
49045
|
return date;
|
|
47736
49046
|
}
|
|
47737
|
-
var
|
|
49047
|
+
var commands25 = [
|
|
47738
49048
|
defineCommand({
|
|
47739
49049
|
operation: journalOperations.day,
|
|
47740
49050
|
path: ["journal", "day"],
|
|
@@ -48286,7 +49596,7 @@ var commands24 = [
|
|
|
48286
49596
|
];
|
|
48287
49597
|
|
|
48288
49598
|
// src/commands/keys.ts
|
|
48289
|
-
var
|
|
49599
|
+
var commands26 = [
|
|
48290
49600
|
{
|
|
48291
49601
|
spec: {
|
|
48292
49602
|
path: ["keys", "list"],
|
|
@@ -48345,8 +49655,108 @@ var commands25 = [
|
|
|
48345
49655
|
}
|
|
48346
49656
|
];
|
|
48347
49657
|
|
|
49658
|
+
// src/commands/log.ts
|
|
49659
|
+
function previewLine(preview, mode) {
|
|
49660
|
+
const effect = preview.effect ? paint(mode, "dim", ` \xB7 ${preview.effect}`) : "";
|
|
49661
|
+
return `${preview.label} \u2192 ${preview.goesTo ?? "?"}${effect}`;
|
|
49662
|
+
}
|
|
49663
|
+
function renderPreview(data, mode) {
|
|
49664
|
+
return `Would log: ${previewLine(data, mode)}`;
|
|
49665
|
+
}
|
|
49666
|
+
function renderWritten(data, mode) {
|
|
49667
|
+
const { preview, remembered } = data;
|
|
49668
|
+
const learnt = remembered ? `
|
|
49669
|
+
${paint(mode, "dim", `Remembered "${remembered}": next time it goes there without asking.`)}` : "";
|
|
49670
|
+
return `Logged: ${previewLine(preview, mode)}${learnt}`;
|
|
49671
|
+
}
|
|
49672
|
+
function renderLogged(data, mode) {
|
|
49673
|
+
const rows = (data.data ?? data) || [];
|
|
49674
|
+
if (rows.length === 0)
|
|
49675
|
+
return paint(mode, "dim", "(nothing logged)");
|
|
49676
|
+
return rows.map((e) => `${e.at} ${e.what} ${paint(mode, "dim", e.where)}`).join(`
|
|
49677
|
+
`);
|
|
49678
|
+
}
|
|
49679
|
+
var KIND_FLAG = {
|
|
49680
|
+
name: "kind",
|
|
49681
|
+
type: "string",
|
|
49682
|
+
description: "The kind of an unknown word (pages, eggs, health, note, or a word taught before); remembered for the Space."
|
|
49683
|
+
};
|
|
49684
|
+
var commands27 = [
|
|
49685
|
+
{
|
|
49686
|
+
spec: {
|
|
49687
|
+
path: ["log"],
|
|
49688
|
+
summary: 'Log one line ("pages 34", "eggs 4"): preview where it goes and what it does, then write it into its section.',
|
|
49689
|
+
args: [{ name: "line", required: true, description: 'The line, e.g. "pages 34".' }],
|
|
49690
|
+
flags: [
|
|
49691
|
+
{ name: "dry-run", type: "boolean", description: "Preview only; write nothing." },
|
|
49692
|
+
KIND_FLAG,
|
|
49693
|
+
{
|
|
49694
|
+
name: "destination",
|
|
49695
|
+
type: "string",
|
|
49696
|
+
description: "The section for an unknown word instead of a kind: habits, animals, health, journal."
|
|
49697
|
+
}
|
|
49698
|
+
],
|
|
49699
|
+
scopes: [...logOperations.write.scopes],
|
|
49700
|
+
returns: "LogWriteResult",
|
|
49701
|
+
notes: `${routeOf(logOperations.preview)}, then ${routeOf(logOperations.write)}. An unknown word stops at the preview (needsKind): rerun with --kind. A line kept in Animals, Health or the Journal needs that section's scope too.`
|
|
49702
|
+
},
|
|
49703
|
+
run: async ({ args, flags, requireClient }) => {
|
|
49704
|
+
const text = args.join(" ").trim();
|
|
49705
|
+
if (!text)
|
|
49706
|
+
throw usageError('log needs a line, e.g. `do log "pages 34"`');
|
|
49707
|
+
const kind = flagString(flags, "kind");
|
|
49708
|
+
const destination = flagString(flags, "destination");
|
|
49709
|
+
const client = requireClient();
|
|
49710
|
+
const preview = await client.post(pathOf(logOperations.preview), { text });
|
|
49711
|
+
if (flagBool(flags, "dry-run"))
|
|
49712
|
+
return { data: preview, render: renderPreview };
|
|
49713
|
+
if (preview.needsKind && !kind && !destination) {
|
|
49714
|
+
throw usageError(`"${preview.word ?? text}" is a kind this Space doesn't know yet: rerun with --kind <pages|eggs|health|note> (see \`do log kinds\`).`, preview);
|
|
49715
|
+
}
|
|
49716
|
+
const written = await client.post(pathOf(logOperations.write), {
|
|
49717
|
+
text,
|
|
49718
|
+
...kind ? { kind } : {},
|
|
49719
|
+
...destination ? { destination } : {}
|
|
49720
|
+
});
|
|
49721
|
+
return { data: written, render: renderWritten };
|
|
49722
|
+
}
|
|
49723
|
+
},
|
|
49724
|
+
{
|
|
49725
|
+
spec: {
|
|
49726
|
+
path: ["log", "list"],
|
|
49727
|
+
summary: "What was logged through Log something on a day (today by default).",
|
|
49728
|
+
args: [],
|
|
49729
|
+
flags: [{ name: "day", type: "string", description: "The day, YYYY-MM-DD." }],
|
|
49730
|
+
scopes: [...logOperations.list.scopes],
|
|
49731
|
+
returns: "LogEntryView[]",
|
|
49732
|
+
notes: `${routeOf(logOperations.list)}. Health and Journal lines show only to their member.`
|
|
49733
|
+
},
|
|
49734
|
+
run: async ({ flags, requireClient }) => ({
|
|
49735
|
+
data: await requireClient().get(pathOf(logOperations.list), {
|
|
49736
|
+
query: { day: flagString(flags, "day") }
|
|
49737
|
+
}),
|
|
49738
|
+
render: renderLogged
|
|
49739
|
+
})
|
|
49740
|
+
},
|
|
49741
|
+
{
|
|
49742
|
+
spec: {
|
|
49743
|
+
path: ["log", "kinds"],
|
|
49744
|
+
summary: "The kinds this Space logs, and where each is kept.",
|
|
49745
|
+
args: [],
|
|
49746
|
+
flags: [],
|
|
49747
|
+
scopes: [...logOperations.kinds.scopes],
|
|
49748
|
+
returns: "LogKindView[]",
|
|
49749
|
+
notes: routeOf(logOperations.kinds)
|
|
49750
|
+
},
|
|
49751
|
+
run: async ({ requireClient }) => ({
|
|
49752
|
+
data: await requireClient().get(pathOf(logOperations.kinds)),
|
|
49753
|
+
render: renderRecord
|
|
49754
|
+
})
|
|
49755
|
+
}
|
|
49756
|
+
];
|
|
49757
|
+
|
|
48348
49758
|
// src/commands/mail-campaigns.ts
|
|
48349
|
-
var
|
|
49759
|
+
var commands28 = [
|
|
48350
49760
|
{
|
|
48351
49761
|
spec: {
|
|
48352
49762
|
path: ["mail-campaigns", "list"],
|
|
@@ -48661,7 +50071,7 @@ async function serveMcp(io, target) {
|
|
|
48661
50071
|
}
|
|
48662
50072
|
|
|
48663
50073
|
// src/commands/mcp.ts
|
|
48664
|
-
var
|
|
50074
|
+
var commands29 = [
|
|
48665
50075
|
{
|
|
48666
50076
|
spec: {
|
|
48667
50077
|
path: ["mcp"],
|
|
@@ -48706,7 +50116,7 @@ var commands27 = [
|
|
|
48706
50116
|
];
|
|
48707
50117
|
|
|
48708
50118
|
// src/commands/members.ts
|
|
48709
|
-
var
|
|
50119
|
+
var commands30 = [
|
|
48710
50120
|
{
|
|
48711
50121
|
spec: {
|
|
48712
50122
|
path: ["invite", "create"],
|
|
@@ -48831,7 +50241,7 @@ var commands28 = [
|
|
|
48831
50241
|
];
|
|
48832
50242
|
|
|
48833
50243
|
// src/commands/metrics.ts
|
|
48834
|
-
var
|
|
50244
|
+
var commands31 = [
|
|
48835
50245
|
{
|
|
48836
50246
|
spec: {
|
|
48837
50247
|
path: ["metrics", "list"],
|
|
@@ -48959,7 +50369,7 @@ async function setModuleVisibility(args, requireClient, on) {
|
|
|
48959
50369
|
render: renderRecord
|
|
48960
50370
|
};
|
|
48961
50371
|
}
|
|
48962
|
-
var
|
|
50372
|
+
var commands32 = [
|
|
48963
50373
|
{
|
|
48964
50374
|
spec: {
|
|
48965
50375
|
path: ["modules", "list"],
|
|
@@ -49183,7 +50593,7 @@ function shareFlag(flags) {
|
|
|
49183
50593
|
function localMonth(now) {
|
|
49184
50594
|
return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}`;
|
|
49185
50595
|
}
|
|
49186
|
-
var
|
|
50596
|
+
var commands33 = [
|
|
49187
50597
|
defineCommand({
|
|
49188
50598
|
operation: moneyOperations.listAccounts,
|
|
49189
50599
|
path: ["money", "accounts"],
|
|
@@ -50325,7 +51735,7 @@ var commands31 = [
|
|
|
50325
51735
|
];
|
|
50326
51736
|
|
|
50327
51737
|
// src/commands/notes.ts
|
|
50328
|
-
var
|
|
51738
|
+
var commands34 = [
|
|
50329
51739
|
{
|
|
50330
51740
|
spec: {
|
|
50331
51741
|
path: ["notes", "backlinks"],
|
|
@@ -50447,7 +51857,7 @@ var commands32 = [
|
|
|
50447
51857
|
];
|
|
50448
51858
|
|
|
50449
51859
|
// src/commands/orca.ts
|
|
50450
|
-
var
|
|
51860
|
+
var commands35 = [
|
|
50451
51861
|
{
|
|
50452
51862
|
spec: {
|
|
50453
51863
|
path: ["orca", "list"],
|
|
@@ -50777,7 +52187,7 @@ function linkBody(args) {
|
|
|
50777
52187
|
return parseInput(familyTreeLinkInputSchema, { kind, a: ref, b: other });
|
|
50778
52188
|
throw usageError("the kind is parent, child or partner");
|
|
50779
52189
|
}
|
|
50780
|
-
var
|
|
52190
|
+
var commands36 = [
|
|
50781
52191
|
{
|
|
50782
52192
|
spec: {
|
|
50783
52193
|
path: ["people", "propose"],
|
|
@@ -51466,7 +52876,7 @@ var commands34 = [
|
|
|
51466
52876
|
|
|
51467
52877
|
// src/commands/places.ts
|
|
51468
52878
|
import { readFileSync as readFileSync10 } from "fs";
|
|
51469
|
-
var
|
|
52879
|
+
var commands37 = [
|
|
51470
52880
|
{
|
|
51471
52881
|
spec: {
|
|
51472
52882
|
path: ["places", "import"],
|
|
@@ -51523,7 +52933,7 @@ async function planDecision({ args, requireClient }, verb) {
|
|
|
51523
52933
|
render: renderPlan
|
|
51524
52934
|
};
|
|
51525
52935
|
}
|
|
51526
|
-
var
|
|
52936
|
+
var commands38 = [
|
|
51527
52937
|
{
|
|
51528
52938
|
spec: {
|
|
51529
52939
|
path: ["plans", "list"],
|
|
@@ -51750,7 +53160,7 @@ var commands36 = [
|
|
|
51750
53160
|
];
|
|
51751
53161
|
|
|
51752
53162
|
// src/commands/presets.ts
|
|
51753
|
-
var
|
|
53163
|
+
var commands39 = [
|
|
51754
53164
|
{
|
|
51755
53165
|
spec: {
|
|
51756
53166
|
path: ["presets", "list"],
|
|
@@ -51804,7 +53214,50 @@ var commands37 = [
|
|
|
51804
53214
|
];
|
|
51805
53215
|
|
|
51806
53216
|
// src/commands/progress.ts
|
|
51807
|
-
var
|
|
53217
|
+
var MARK = {
|
|
53218
|
+
done: "\u25CF",
|
|
53219
|
+
missed: "\u2715",
|
|
53220
|
+
open: "\u25CB",
|
|
53221
|
+
later: "\xB7",
|
|
53222
|
+
not_due: " "
|
|
53223
|
+
};
|
|
53224
|
+
var signed = (n) => n > 0 ? `+${n}` : String(n);
|
|
53225
|
+
function renderReviewSummary(data, mode) {
|
|
53226
|
+
const r = data;
|
|
53227
|
+
const n = r.numbers;
|
|
53228
|
+
const out = [
|
|
53229
|
+
paint(mode, "bold", `${r.label} \xB7 ${r.rangeLabel}`),
|
|
53230
|
+
` Tasks done ${n.tasksDone} (${signed(n.tasksDoneDelta)} on the ${r.span} before)`,
|
|
53231
|
+
` Habits ${n.habitTicks} of ${n.habitDue} due`,
|
|
53232
|
+
` Projects ${n.projectsMoved} moved \xB7 Challenges ${n.challengesRunning} running`,
|
|
53233
|
+
"",
|
|
53234
|
+
paint(mode, "bold", "Last 8")
|
|
53235
|
+
];
|
|
53236
|
+
const keyWidth = Math.max(0, ...r.series.map((p) => p.key.length));
|
|
53237
|
+
for (const p of r.series) {
|
|
53238
|
+
const row = ` ${p.key.padEnd(keyWidth)} ${String(p.tasksDone).padStart(3)} tasks ${String(p.habitTicks).padStart(3)} habits`;
|
|
53239
|
+
out.push(p.current ? paint(mode, "cyan", row) : row);
|
|
53240
|
+
}
|
|
53241
|
+
out.push("", paint(mode, "bold", "Streaks"));
|
|
53242
|
+
if (r.streaks.length === 0)
|
|
53243
|
+
out.push(paint(mode, "dim", " (no habits yet)"));
|
|
53244
|
+
const titleWidth = Math.max(0, ...r.streaks.map((s) => s.title.length));
|
|
53245
|
+
for (const s of r.streaks) {
|
|
53246
|
+
const marks = s.marks.map((m) => MARK[m.state]).join(" ");
|
|
53247
|
+
out.push(` ${s.title.padEnd(titleWidth)} ${s.unitLabel} \xB7 best ${s.best} ${marks} ${paint(mode, "dim", s.scheduleLabel)}`);
|
|
53248
|
+
}
|
|
53249
|
+
out.push("", paint(mode, "bold", "Projects"));
|
|
53250
|
+
if (r.projects.length === 0)
|
|
53251
|
+
out.push(paint(mode, "dim", " (no open projects)"));
|
|
53252
|
+
const projectWidth = Math.max(0, ...r.projects.map((p) => p.title.length));
|
|
53253
|
+
for (const p of r.projects) {
|
|
53254
|
+
const target = p.targetDate ? paint(mode, "dim", ` \xB7 by ${p.targetDate}`) : "";
|
|
53255
|
+
out.push(` ${p.title.padEnd(projectWidth)} ${p.done} of ${p.total} tasks${target}`);
|
|
53256
|
+
}
|
|
53257
|
+
return out.join(`
|
|
53258
|
+
`);
|
|
53259
|
+
}
|
|
53260
|
+
var commands40 = [
|
|
51808
53261
|
{
|
|
51809
53262
|
spec: {
|
|
51810
53263
|
path: ["progress"],
|
|
@@ -51824,6 +53277,38 @@ var commands38 = [
|
|
|
51824
53277
|
render: renderProgress
|
|
51825
53278
|
})
|
|
51826
53279
|
},
|
|
53280
|
+
{
|
|
53281
|
+
spec: {
|
|
53282
|
+
path: ["review", "summary"],
|
|
53283
|
+
summary: "Plan > Review: the week's or month's numbers, the last 8 periods, habit streaks and open projects.",
|
|
53284
|
+
args: [],
|
|
53285
|
+
flags: [
|
|
53286
|
+
{ name: "span", type: "string", description: "week (default) or month." },
|
|
53287
|
+
{
|
|
53288
|
+
name: "date",
|
|
53289
|
+
type: "string",
|
|
53290
|
+
description: "A day in the period, YYYY-MM-DD; default today."
|
|
53291
|
+
}
|
|
53292
|
+
],
|
|
53293
|
+
scopes: [...progressOperations.review.scopes],
|
|
53294
|
+
returns: "ReviewSummary",
|
|
53295
|
+
notes: `${routeOf(progressOperations.review)} \u2014 the ISO week (Monday to Sunday) or calendar month holding the day, in your saved timezone. Tasks done count yours and your agents' as Progress does; a streak reads \`N days\` for a daily habit and \`N in a row\` otherwise, and a day a habit isn't due never breaks it.`
|
|
53296
|
+
},
|
|
53297
|
+
run: async ({ flags, requireClient }) => {
|
|
53298
|
+
const span = flagString(flags, "span");
|
|
53299
|
+
const date = flagString(flags, "date");
|
|
53300
|
+
const query = parseInput(reviewSummaryQuerySchema, {
|
|
53301
|
+
...span ? { span } : {},
|
|
53302
|
+
...date ? { date } : {}
|
|
53303
|
+
});
|
|
53304
|
+
return {
|
|
53305
|
+
data: await requireClient().get(pathOf(progressOperations.review), {
|
|
53306
|
+
query: { span: query.span, ...query.date ? { date: query.date } : {} }
|
|
53307
|
+
}),
|
|
53308
|
+
render: renderReviewSummary
|
|
53309
|
+
};
|
|
53310
|
+
}
|
|
53311
|
+
},
|
|
51827
53312
|
{
|
|
51828
53313
|
spec: {
|
|
51829
53314
|
path: ["progress", "day"],
|
|
@@ -51957,8 +53442,281 @@ var commands38 = [
|
|
|
51957
53442
|
}
|
|
51958
53443
|
];
|
|
51959
53444
|
|
|
53445
|
+
// src/commands/projects.ts
|
|
53446
|
+
var PROJECT_ARG = {
|
|
53447
|
+
name: "id",
|
|
53448
|
+
required: true,
|
|
53449
|
+
description: "Project ref (DO-P7, any case) or ULID."
|
|
53450
|
+
};
|
|
53451
|
+
var UPDATE_STATUSES = projectUpdateStatusSchema.options.map((s) => s.replace(/_/g, "-"));
|
|
53452
|
+
function updateStatus(raw) {
|
|
53453
|
+
return raw.trim().toLowerCase().replace(/[-\s]+/g, "_");
|
|
53454
|
+
}
|
|
53455
|
+
function updateLine(u, mode) {
|
|
53456
|
+
const date = (u.createdAt ?? "").slice(0, 10);
|
|
53457
|
+
const status = (u.status ?? "").replace(/_/g, "-");
|
|
53458
|
+
const body = u.body ? ` ${u.body}` : "";
|
|
53459
|
+
const by = u.authorName ? paint(mode, "dim", ` \u2014 ${u.authorName}`) : "";
|
|
53460
|
+
return `${date} ${paint(mode, "bold", status)}${body}${by}`;
|
|
53461
|
+
}
|
|
53462
|
+
function renderUpdates(data, mode) {
|
|
53463
|
+
const updates = data ?? [];
|
|
53464
|
+
if (updates.length === 0)
|
|
53465
|
+
return paint(mode, "dim", "No updates yet.");
|
|
53466
|
+
return updates.map((u) => updateLine(u, mode)).join(`
|
|
53467
|
+
`);
|
|
53468
|
+
}
|
|
53469
|
+
var commands41 = [
|
|
53470
|
+
defineCommand({
|
|
53471
|
+
operation: projectOperations.update,
|
|
53472
|
+
path: ["projects", "set"],
|
|
53473
|
+
summary: "Set a project's priority.",
|
|
53474
|
+
returns: "ProjectView",
|
|
53475
|
+
args: [PROJECT_ARG],
|
|
53476
|
+
flags: [{ name: "priority", type: "string", description: "none, low, medium or high." }],
|
|
53477
|
+
run: async ({ args, flags, requireClient }) => {
|
|
53478
|
+
const id = requireArg(args, 0, "project id");
|
|
53479
|
+
const priority = flagString(flags, "priority");
|
|
53480
|
+
if (priority === undefined)
|
|
53481
|
+
throw usageError("projects set needs --priority");
|
|
53482
|
+
const body = parseInput(updateProjectInputSchema, {
|
|
53483
|
+
priority: priority.trim().toLowerCase()
|
|
53484
|
+
});
|
|
53485
|
+
return {
|
|
53486
|
+
data: await requireClient().patch(pathOf(projectOperations.update, { id }), body),
|
|
53487
|
+
render: renderRecord
|
|
53488
|
+
};
|
|
53489
|
+
}
|
|
53490
|
+
}),
|
|
53491
|
+
defineCommand({
|
|
53492
|
+
operation: projectOperations.createUpdate,
|
|
53493
|
+
path: ["projects", "update"],
|
|
53494
|
+
summary: "Post a project update (--status and a note), or change the project (--data, --leads).",
|
|
53495
|
+
returns: "ProjectUpdateView",
|
|
53496
|
+
args: [
|
|
53497
|
+
PROJECT_ARG,
|
|
53498
|
+
{ name: "note", required: false, description: "The update's note (up to 2000 characters)." }
|
|
53499
|
+
],
|
|
53500
|
+
flags: [
|
|
53501
|
+
{
|
|
53502
|
+
name: "status",
|
|
53503
|
+
type: "string",
|
|
53504
|
+
description: `Post an update with this status: ${UPDATE_STATUSES.join(", ")}.`
|
|
53505
|
+
},
|
|
53506
|
+
{
|
|
53507
|
+
name: "data",
|
|
53508
|
+
type: "string",
|
|
53509
|
+
description: "UpdateProjectInput as JSON, or @path to read it from a file."
|
|
53510
|
+
},
|
|
53511
|
+
{
|
|
53512
|
+
name: "leads",
|
|
53513
|
+
type: "string",
|
|
53514
|
+
description: "The project's leads, as member user ids, comma-separated; '' clears them."
|
|
53515
|
+
},
|
|
53516
|
+
{ name: "dry-run", type: "boolean", description: "Show the change, send nothing." }
|
|
53517
|
+
],
|
|
53518
|
+
notes: ". Shadows the generic `projects update`: with --status it posts an update, attributed to the key's Agent or member; without, it PATCHes /api/v1/projects/{id} with --data and --leads. Read updates with `do projects updates <id>`.",
|
|
53519
|
+
run: async ({ args, flags, requireClient }) => {
|
|
53520
|
+
const id = requireArg(args, 0, "project id");
|
|
53521
|
+
const note = args.slice(1).join(" ");
|
|
53522
|
+
const status = flagString(flags, "status");
|
|
53523
|
+
const leads = flagString(flags, "leads");
|
|
53524
|
+
const dryRun = flagBool(flags, "dry-run");
|
|
53525
|
+
if (status !== undefined) {
|
|
53526
|
+
if (flags.data !== undefined || leads !== undefined) {
|
|
53527
|
+
throw usageError("--status posts an update; change the project in a separate call");
|
|
53528
|
+
}
|
|
53529
|
+
const body = parseInput(createProjectUpdateInputSchema, {
|
|
53530
|
+
status: updateStatus(status),
|
|
53531
|
+
body: note
|
|
53532
|
+
});
|
|
53533
|
+
if (dryRun) {
|
|
53534
|
+
return {
|
|
53535
|
+
data: { dryRun: true, op: "create", entity: "project update", id, after: body },
|
|
53536
|
+
render: renderRecord
|
|
53537
|
+
};
|
|
53538
|
+
}
|
|
53539
|
+
return {
|
|
53540
|
+
data: await requireClient().post(pathOf(projectOperations.createUpdate, { id }), body),
|
|
53541
|
+
render: (data, mode) => updateLine(data, mode)
|
|
53542
|
+
};
|
|
53543
|
+
}
|
|
53544
|
+
if (note)
|
|
53545
|
+
throw usageError("a note needs --status (on-track, at-risk, \u2026)");
|
|
53546
|
+
const fields = readDataFlag(flags);
|
|
53547
|
+
if (leads !== undefined) {
|
|
53548
|
+
fields.leadUserIds = leads.split(",").map((s) => s.trim()).filter(Boolean);
|
|
53549
|
+
}
|
|
53550
|
+
const body = parseInput(updateProjectInputSchema, fields);
|
|
53551
|
+
if (Object.keys(body).length === 0) {
|
|
53552
|
+
throw usageError("nothing to change \u2014 pass --status, --data or --leads");
|
|
53553
|
+
}
|
|
53554
|
+
const client = requireClient();
|
|
53555
|
+
if (dryRun) {
|
|
53556
|
+
const before = await client.get(pathOf(projectOperations.get, { id }));
|
|
53557
|
+
return {
|
|
53558
|
+
data: {
|
|
53559
|
+
dryRun: true,
|
|
53560
|
+
op: "update",
|
|
53561
|
+
entity: "projects",
|
|
53562
|
+
id,
|
|
53563
|
+
before,
|
|
53564
|
+
after: mergePreview(before, body),
|
|
53565
|
+
changes: body
|
|
53566
|
+
},
|
|
53567
|
+
render: renderRecord
|
|
53568
|
+
};
|
|
53569
|
+
}
|
|
53570
|
+
return {
|
|
53571
|
+
data: await client.patch(pathOf(projectOperations.update, { id }), body),
|
|
53572
|
+
render: renderRecord
|
|
53573
|
+
};
|
|
53574
|
+
}
|
|
53575
|
+
}),
|
|
53576
|
+
defineCommand({
|
|
53577
|
+
operation: projectOperations.listUpdates,
|
|
53578
|
+
path: ["projects", "updates"],
|
|
53579
|
+
summary: "A project's updates, newest first.",
|
|
53580
|
+
returns: "ProjectUpdateView[]",
|
|
53581
|
+
args: [PROJECT_ARG],
|
|
53582
|
+
run: async ({ args, requireClient }) => {
|
|
53583
|
+
const id = requireArg(args, 0, "project id");
|
|
53584
|
+
return {
|
|
53585
|
+
data: await requireClient().get(pathOf(projectOperations.listUpdates, { id })),
|
|
53586
|
+
render: renderUpdates
|
|
53587
|
+
};
|
|
53588
|
+
}
|
|
53589
|
+
}),
|
|
53590
|
+
defineCommand({
|
|
53591
|
+
operation: projectOperations.removeUpdate,
|
|
53592
|
+
path: ["projects", "delete-update"],
|
|
53593
|
+
summary: "Delete one of your own updates on a project.",
|
|
53594
|
+
returns: "void",
|
|
53595
|
+
args: [PROJECT_ARG, { name: "updateId", required: true, description: "The update's ULID." }],
|
|
53596
|
+
notes: ". Needs --allow-destructive; only the update's author (the member or the Agent) may.",
|
|
53597
|
+
run: async ({ args, flags, requireClient }) => {
|
|
53598
|
+
const id = requireArg(args, 0, "project id");
|
|
53599
|
+
const updateId = requireArg(args, 1, "update id");
|
|
53600
|
+
assertDestructiveAllowed(flags, `delete update ${updateId} on ${id}`);
|
|
53601
|
+
await requireClient().delete(pathOf(projectOperations.removeUpdate, { id, updateId }));
|
|
53602
|
+
return { data: { ok: true, deleted: updateId }, render: renderRecord };
|
|
53603
|
+
}
|
|
53604
|
+
})
|
|
53605
|
+
];
|
|
53606
|
+
|
|
53607
|
+
// src/commands/routines.ts
|
|
53608
|
+
var STATE_WORDS = {
|
|
53609
|
+
done: "done",
|
|
53610
|
+
running: "under way",
|
|
53611
|
+
upcoming: "to come",
|
|
53612
|
+
resting: "resting"
|
|
53613
|
+
};
|
|
53614
|
+
function renderRoutinesToday(data, mode) {
|
|
53615
|
+
const d = data;
|
|
53616
|
+
const list = d.routines ?? [];
|
|
53617
|
+
if (list.length === 0)
|
|
53618
|
+
return "No routines today.";
|
|
53619
|
+
return list.map((r) => {
|
|
53620
|
+
const progress = r.run ? ` \xB7 ${r.run.done}/${r.run.total}` : "";
|
|
53621
|
+
const head = `${r.start ?? "--:--"} ${r.title} ${paint(mode, "dim", `${STATE_WORDS[r.state] ?? r.state}${progress} ${r.id}`)}`;
|
|
53622
|
+
const steps = r.steps.map((s) => {
|
|
53623
|
+
const meta = s.meta ? paint(mode, "dim", ` \xB7 ${s.meta}`) : "";
|
|
53624
|
+
const kind = s.kind === "step" ? "" : ` [${s.kind}]`;
|
|
53625
|
+
return ` ${s.done ? "\u2713" : "\u25CB"} ${s.n}. ${s.title}${kind}${meta}`;
|
|
53626
|
+
});
|
|
53627
|
+
return [head, ...steps].join(`
|
|
53628
|
+
`);
|
|
53629
|
+
}).join(`
|
|
53630
|
+
`);
|
|
53631
|
+
}
|
|
53632
|
+
function renderRoutineTaskAdded(data) {
|
|
53633
|
+
const run = data;
|
|
53634
|
+
const last = run.steps?.at(-1)?.title ?? "the task";
|
|
53635
|
+
return `${run.routineTitle ?? "(routine)"}: ${last} is the last step of today's run.`;
|
|
53636
|
+
}
|
|
53637
|
+
var commands42 = [
|
|
53638
|
+
{
|
|
53639
|
+
spec: {
|
|
53640
|
+
path: ["routines", "today"],
|
|
53641
|
+
summary: "Today's routines by start: their state, steps (step, habit, task) and 14 days.",
|
|
53642
|
+
args: [],
|
|
53643
|
+
flags: [],
|
|
53644
|
+
scopes: [...routineOperations.today.scopes],
|
|
53645
|
+
returns: "RoutinesTodayResult",
|
|
53646
|
+
notes: `${routeOf(routineOperations.today)}. Today is your saved time zone's day. A routine is on it when its rule has it due, it has a slot today, or it ran today. Each step's \`kind\` is step, habit or task (a Work task); \`rhythm\` is its last 14 days, oldest first (all, some, none, off).`
|
|
53647
|
+
},
|
|
53648
|
+
run: async ({ requireClient }) => ({
|
|
53649
|
+
data: await requireClient().get(pathOf(routineOperations.today)),
|
|
53650
|
+
render: renderRoutinesToday
|
|
53651
|
+
})
|
|
53652
|
+
},
|
|
53653
|
+
{
|
|
53654
|
+
spec: {
|
|
53655
|
+
path: ["routines", "add-task"],
|
|
53656
|
+
summary: "Add a Work task due today to the end of today's run of a routine.",
|
|
53657
|
+
args: [
|
|
53658
|
+
{ name: "id", required: true, description: "Routine ULID (`do routines today`)." },
|
|
53659
|
+
{ name: "task", required: true, description: "Task ULID; it must be due today." }
|
|
53660
|
+
],
|
|
53661
|
+
flags: [
|
|
53662
|
+
{
|
|
53663
|
+
name: "reason",
|
|
53664
|
+
type: "string",
|
|
53665
|
+
description: 'The line shown with it ("Call the plumber is due today in Work, so I added it to the end of this routine.").'
|
|
53666
|
+
}
|
|
53667
|
+
],
|
|
53668
|
+
scopes: [...routineOperations.addTaskStep.scopes],
|
|
53669
|
+
returns: "RoutineRunView",
|
|
53670
|
+
notes: `${routeOf(routineOperations.addTaskStep)}. Starts today's run when there's none; the routine's own steps are unchanged. A task not due today is a 422; adding it again changes nothing. Ticking the step completes the task in Work, undo reopens it.`
|
|
53671
|
+
},
|
|
53672
|
+
run: async ({ args, flags, requireClient }) => {
|
|
53673
|
+
const id = requireArg(args, 0, "routine id");
|
|
53674
|
+
const taskId = requireArg(args, 1, "task id");
|
|
53675
|
+
const reason = flagString(flags, "reason");
|
|
53676
|
+
const input = parseInput(addRoutineTaskStepInputSchema, {
|
|
53677
|
+
taskId,
|
|
53678
|
+
...reason !== undefined ? { reason } : {}
|
|
53679
|
+
});
|
|
53680
|
+
return {
|
|
53681
|
+
data: await requireClient().post(pathOf(routineOperations.addTaskStep, { id }), input),
|
|
53682
|
+
render: renderRoutineTaskAdded
|
|
53683
|
+
};
|
|
53684
|
+
}
|
|
53685
|
+
},
|
|
53686
|
+
{
|
|
53687
|
+
spec: {
|
|
53688
|
+
path: ["routines", "reorder"],
|
|
53689
|
+
summary: "Put a routine's steps in a new order.",
|
|
53690
|
+
args: [
|
|
53691
|
+
{ name: "id", required: true, description: "Routine ULID." },
|
|
53692
|
+
{
|
|
53693
|
+
name: "steps",
|
|
53694
|
+
required: true,
|
|
53695
|
+
description: "Every step ULID of the routine, in the new order, space- or comma-separated."
|
|
53696
|
+
}
|
|
53697
|
+
],
|
|
53698
|
+
flags: [],
|
|
53699
|
+
scopes: [...routineOperations.reorderSteps.scopes],
|
|
53700
|
+
returns: "RoutineView",
|
|
53701
|
+
notes: `${routeOf(routineOperations.reorderSteps)}. Name each step once; a list that isn't exactly the routine's steps is a 400. Runs already started keep their order.`
|
|
53702
|
+
},
|
|
53703
|
+
run: async ({ args, requireClient }) => {
|
|
53704
|
+
const id = requireArg(args, 0, "routine id");
|
|
53705
|
+
const stepIds = args.slice(1).flatMap((a) => a.split(",")).map((s) => s.trim()).filter(Boolean);
|
|
53706
|
+
if (stepIds.length === 0) {
|
|
53707
|
+
throw usageError("routines reorder needs the step ids in their new order, e.g. `do routines reorder <routine> <step> <step>`");
|
|
53708
|
+
}
|
|
53709
|
+
const input = parseInput(reorderRoutineStepsInputSchema, { stepIds });
|
|
53710
|
+
return {
|
|
53711
|
+
data: await requireClient().patch(pathOf(routineOperations.reorderSteps, { id }), input),
|
|
53712
|
+
render: (data) => `${data.title ?? "(routine)"}: steps reordered.`
|
|
53713
|
+
};
|
|
53714
|
+
}
|
|
53715
|
+
}
|
|
53716
|
+
];
|
|
53717
|
+
|
|
51960
53718
|
// src/commands/rsvp-answers.ts
|
|
51961
|
-
var
|
|
53719
|
+
var commands43 = [
|
|
51962
53720
|
{
|
|
51963
53721
|
spec: {
|
|
51964
53722
|
path: ["rsvp-answers", "list"],
|
|
@@ -52012,7 +53770,7 @@ var commands39 = [
|
|
|
52012
53770
|
];
|
|
52013
53771
|
|
|
52014
53772
|
// src/commands/rsvp-links.ts
|
|
52015
|
-
var
|
|
53773
|
+
var commands44 = [
|
|
52016
53774
|
{
|
|
52017
53775
|
spec: {
|
|
52018
53776
|
path: ["rsvp-links", "list"],
|
|
@@ -52108,7 +53866,7 @@ var commands40 = [
|
|
|
52108
53866
|
];
|
|
52109
53867
|
|
|
52110
53868
|
// src/commands/rsvp-questions.ts
|
|
52111
|
-
var
|
|
53869
|
+
var commands45 = [
|
|
52112
53870
|
{
|
|
52113
53871
|
spec: {
|
|
52114
53872
|
path: ["rsvp-questions", "presets"],
|
|
@@ -52680,7 +54438,7 @@ function sessionFlags(flags) {
|
|
|
52680
54438
|
body.occurredOn = on;
|
|
52681
54439
|
return body;
|
|
52682
54440
|
}
|
|
52683
|
-
var
|
|
54441
|
+
var commands46 = [
|
|
52684
54442
|
{
|
|
52685
54443
|
spec: {
|
|
52686
54444
|
path: ["runs", "change"],
|
|
@@ -52997,7 +54755,7 @@ var commands42 = [
|
|
|
52997
54755
|
];
|
|
52998
54756
|
|
|
52999
54757
|
// src/commands/search.ts
|
|
53000
|
-
var
|
|
54758
|
+
var commands47 = [
|
|
53001
54759
|
{
|
|
53002
54760
|
spec: {
|
|
53003
54761
|
path: ["search"],
|
|
@@ -53030,7 +54788,7 @@ var commands43 = [
|
|
|
53030
54788
|
];
|
|
53031
54789
|
|
|
53032
54790
|
// src/commands/seating-proposals.ts
|
|
53033
|
-
var
|
|
54791
|
+
var commands48 = [
|
|
53034
54792
|
{
|
|
53035
54793
|
spec: {
|
|
53036
54794
|
path: ["seating-proposals", "list"],
|
|
@@ -53117,7 +54875,7 @@ var commands44 = [
|
|
|
53117
54875
|
];
|
|
53118
54876
|
|
|
53119
54877
|
// src/commands/sensors.ts
|
|
53120
|
-
var
|
|
54878
|
+
var commands49 = [
|
|
53121
54879
|
{
|
|
53122
54880
|
spec: {
|
|
53123
54881
|
path: ["sensors", "status"],
|
|
@@ -53277,7 +55035,7 @@ var commands45 = [
|
|
|
53277
55035
|
];
|
|
53278
55036
|
|
|
53279
55037
|
// src/commands/settings.ts
|
|
53280
|
-
var
|
|
55038
|
+
var commands50 = [
|
|
53281
55039
|
{
|
|
53282
55040
|
spec: {
|
|
53283
55041
|
path: ["settings", "get"],
|
|
@@ -53310,7 +55068,7 @@ var commands46 = [
|
|
|
53310
55068
|
];
|
|
53311
55069
|
|
|
53312
55070
|
// src/commands/sharing.ts
|
|
53313
|
-
var
|
|
55071
|
+
var commands51 = [
|
|
53314
55072
|
{
|
|
53315
55073
|
spec: {
|
|
53316
55074
|
path: ["share"],
|
|
@@ -53443,7 +55201,7 @@ var commands47 = [
|
|
|
53443
55201
|
];
|
|
53444
55202
|
|
|
53445
55203
|
// src/commands/tap-tags.ts
|
|
53446
|
-
var
|
|
55204
|
+
var commands52 = [
|
|
53447
55205
|
{
|
|
53448
55206
|
spec: {
|
|
53449
55207
|
path: ["tap-tags", "tap"],
|
|
@@ -53464,6 +55222,48 @@ var commands48 = [
|
|
|
53464
55222
|
}
|
|
53465
55223
|
];
|
|
53466
55224
|
|
|
55225
|
+
// src/commands/task-blocks.ts
|
|
55226
|
+
var ID2 = { name: "id", required: true, description: "The blocked task's ref (DO-148) or ULID." };
|
|
55227
|
+
var BY = {
|
|
55228
|
+
name: "by",
|
|
55229
|
+
type: "string",
|
|
55230
|
+
description: "The blocking task's ref (DO-147) or ULID."
|
|
55231
|
+
};
|
|
55232
|
+
var commands53 = [
|
|
55233
|
+
defineCommand({
|
|
55234
|
+
operation: taskBlockOperations.addBlocker,
|
|
55235
|
+
path: ["tasks", "block"],
|
|
55236
|
+
summary: "Block a task by another, until that one is Done.",
|
|
55237
|
+
args: [ID2],
|
|
55238
|
+
flags: [BY],
|
|
55239
|
+
notes: " \u2014 a self-link or a loop (two tasks waiting on each other) is refused.",
|
|
55240
|
+
run: async ({ args, flags, requireClient }) => {
|
|
55241
|
+
const id = requireArg(args, 0, "task id");
|
|
55242
|
+
const by = requireFlag(flags, "by", "tasks block needs --by <task>");
|
|
55243
|
+
const body = parseInput(addTaskBlockerInputSchema, { taskId: by });
|
|
55244
|
+
return {
|
|
55245
|
+
data: await requireClient().post(pathOf(taskBlockOperations.addBlocker, { id }), body),
|
|
55246
|
+
render: renderTask
|
|
55247
|
+
};
|
|
55248
|
+
}
|
|
55249
|
+
}),
|
|
55250
|
+
defineCommand({
|
|
55251
|
+
operation: taskBlockOperations.removeBlocker,
|
|
55252
|
+
path: ["tasks", "unblock"],
|
|
55253
|
+
summary: "Lift a block: the other task no longer blocks this one.",
|
|
55254
|
+
args: [ID2],
|
|
55255
|
+
flags: [BY],
|
|
55256
|
+
run: async ({ args, flags, requireClient }) => {
|
|
55257
|
+
const id = requireArg(args, 0, "task id");
|
|
55258
|
+
const blockerId = requireFlag(flags, "by", "tasks unblock needs --by <task>");
|
|
55259
|
+
return {
|
|
55260
|
+
data: await requireClient().delete(pathOf(taskBlockOperations.removeBlocker, { id, blockerId })),
|
|
55261
|
+
render: renderTask
|
|
55262
|
+
};
|
|
55263
|
+
}
|
|
55264
|
+
})
|
|
55265
|
+
];
|
|
55266
|
+
|
|
53467
55267
|
// src/capture.ts
|
|
53468
55268
|
function parseCapture2(input, now) {
|
|
53469
55269
|
const parsed = parseCapture(input, now);
|
|
@@ -53474,7 +55274,7 @@ function parseCapture2(input, now) {
|
|
|
53474
55274
|
}
|
|
53475
55275
|
|
|
53476
55276
|
// src/commands/tasks.ts
|
|
53477
|
-
var
|
|
55277
|
+
var commands54 = [
|
|
53478
55278
|
{
|
|
53479
55279
|
spec: {
|
|
53480
55280
|
path: ["capture"],
|
|
@@ -53553,7 +55353,7 @@ var commands49 = [
|
|
|
53553
55353
|
spec: {
|
|
53554
55354
|
path: ["task", "done"],
|
|
53555
55355
|
summary: "Mark a task done (idempotent \u2014 a no-op success if already done).",
|
|
53556
|
-
args: [{ name: "id", required: true, description: "Task ULID." }],
|
|
55356
|
+
args: [{ name: "id", required: true, description: "Task ULID or ref (DO-142)." }],
|
|
53557
55357
|
flags: [
|
|
53558
55358
|
{
|
|
53559
55359
|
name: "at",
|
|
@@ -53586,7 +55386,7 @@ var commands49 = [
|
|
|
53586
55386
|
spec: {
|
|
53587
55387
|
path: ["task", "cancel"],
|
|
53588
55388
|
summary: "Drop a task: status cancelled, never counted as Landed.",
|
|
53589
|
-
args: [{ name: "id", required: true, description: "Task ULID." }],
|
|
55389
|
+
args: [{ name: "id", required: true, description: "Task ULID or ref (DO-142)." }],
|
|
53590
55390
|
flags: [],
|
|
53591
55391
|
scopes: [...taskOperations.cancel.scopes],
|
|
53592
55392
|
returns: "Task",
|
|
@@ -53604,7 +55404,7 @@ var commands49 = [
|
|
|
53604
55404
|
spec: {
|
|
53605
55405
|
path: ["tasks", "accept"],
|
|
53606
55406
|
summary: "Accept a task Proposed by the agent: it joins the plan as suggested (day, Deadline, Area kept).",
|
|
53607
|
-
args: [{ name: "id", required: true, description: "Task ULID." }],
|
|
55407
|
+
args: [{ name: "id", required: true, description: "Task ULID or ref (DO-142)." }],
|
|
53608
55408
|
flags: [],
|
|
53609
55409
|
scopes: [...taskOperations.accept.scopes],
|
|
53610
55410
|
returns: "Task",
|
|
@@ -53622,7 +55422,7 @@ var commands49 = [
|
|
|
53622
55422
|
spec: {
|
|
53623
55423
|
path: ["tasks", "dismiss"],
|
|
53624
55424
|
summary: "Not now on a task Proposed by the agent: it leaves the Inbox for a week, still proposed.",
|
|
53625
|
-
args: [{ name: "id", required: true, description: "Task ULID." }],
|
|
55425
|
+
args: [{ name: "id", required: true, description: "Task ULID or ref (DO-142)." }],
|
|
53626
55426
|
flags: [],
|
|
53627
55427
|
scopes: [...taskOperations.notNow.scopes],
|
|
53628
55428
|
returns: "Task",
|
|
@@ -53640,7 +55440,7 @@ var commands49 = [
|
|
|
53640
55440
|
spec: {
|
|
53641
55441
|
path: ["tasks", "ready"],
|
|
53642
55442
|
summary: "Mark a task Ready for you: its Owner finished something the member should look at (a draft, a link, a worktree).",
|
|
53643
|
-
args: [{ name: "id", required: true, description: "Task ULID." }],
|
|
55443
|
+
args: [{ name: "id", required: true, description: "Task ULID or ref (DO-142)." }],
|
|
53644
55444
|
flags: [
|
|
53645
55445
|
{
|
|
53646
55446
|
name: "note",
|
|
@@ -53666,7 +55466,7 @@ var commands49 = [
|
|
|
53666
55466
|
spec: {
|
|
53667
55467
|
path: ["task", "reopen"],
|
|
53668
55468
|
summary: "Reopen a done or cancelled task (status todo; clears completedAt).",
|
|
53669
|
-
args: [{ name: "id", required: true, description: "Task ULID." }],
|
|
55469
|
+
args: [{ name: "id", required: true, description: "Task ULID or ref (DO-142)." }],
|
|
53670
55470
|
flags: [],
|
|
53671
55471
|
scopes: [...taskOperations.update.scopes],
|
|
53672
55472
|
returns: "Task"
|
|
@@ -53684,7 +55484,7 @@ var commands49 = [
|
|
|
53684
55484
|
spec: {
|
|
53685
55485
|
path: ["task", "snooze"],
|
|
53686
55486
|
summary: "Push a task's scheduled date forward.",
|
|
53687
|
-
args: [{ name: "id", required: true, description: "Task ULID." }],
|
|
55487
|
+
args: [{ name: "id", required: true, description: "Task ULID or ref (DO-142)." }],
|
|
53688
55488
|
flags: [
|
|
53689
55489
|
{ name: "days", type: "string", description: "Days from now to reschedule.", default: "1" },
|
|
53690
55490
|
{
|
|
@@ -53721,7 +55521,7 @@ var commands49 = [
|
|
|
53721
55521
|
spec: {
|
|
53722
55522
|
path: ["task", "schedule"],
|
|
53723
55523
|
summary: "Plan a task at a day or a time, so a timed one shows on the calendar.",
|
|
53724
|
-
args: [{ name: "id", required: true, description: "Task ULID." }],
|
|
55524
|
+
args: [{ name: "id", required: true, description: "Task ULID or ref (DO-142)." }],
|
|
53725
55525
|
flags: [
|
|
53726
55526
|
{
|
|
53727
55527
|
name: "at",
|
|
@@ -53779,11 +55579,65 @@ var commands49 = [
|
|
|
53779
55579
|
render: renderRecord
|
|
53780
55580
|
};
|
|
53781
55581
|
}
|
|
53782
|
-
}
|
|
55582
|
+
},
|
|
55583
|
+
defineCommand({
|
|
55584
|
+
operation: taskOperations.get,
|
|
55585
|
+
path: ["tasks", "show"],
|
|
55586
|
+
summary: "Show one task by its ref (DO-142) or ULID.",
|
|
55587
|
+
returns: "Task",
|
|
55588
|
+
args: [{ name: "id", required: true, description: "Task ref (DO-142, any case) or ULID." }],
|
|
55589
|
+
flags: [],
|
|
55590
|
+
run: async ({ args, requireClient }) => {
|
|
55591
|
+
const id = requireArg(args, 0, "task id");
|
|
55592
|
+
return {
|
|
55593
|
+
data: await requireClient().get(pathOf(taskOperations.get, { id })),
|
|
55594
|
+
render: renderTask
|
|
55595
|
+
};
|
|
55596
|
+
}
|
|
55597
|
+
}),
|
|
55598
|
+
defineCommand({
|
|
55599
|
+
operation: taskOperations.update,
|
|
55600
|
+
path: ["tasks", "set"],
|
|
55601
|
+
summary: "Set a task's status, priority or deliverable.",
|
|
55602
|
+
returns: "Task",
|
|
55603
|
+
args: [{ name: "id", required: true, description: "Task ref (DO-142, any case) or ULID." }],
|
|
55604
|
+
flags: [
|
|
55605
|
+
{
|
|
55606
|
+
name: "status",
|
|
55607
|
+
type: "string",
|
|
55608
|
+
description: "backlog, todo, in-progress, waiting or done (cancel drops it: `do task cancel`)."
|
|
55609
|
+
},
|
|
55610
|
+
{ name: "priority", type: "string", description: "none, low, medium or high." },
|
|
55611
|
+
{
|
|
55612
|
+
name: "deliverable",
|
|
55613
|
+
type: "string",
|
|
55614
|
+
description: "What finishing it hands over, in a line; an empty string clears it."
|
|
55615
|
+
}
|
|
55616
|
+
],
|
|
55617
|
+
notes: " \u2014 setting a waiting-on party moves an open task to waiting, clearing it moves it back to todo, unless --status says otherwise.",
|
|
55618
|
+
run: async ({ args, flags, requireClient }) => {
|
|
55619
|
+
const id = requireArg(args, 0, "task id");
|
|
55620
|
+
const status = flagString(flags, "status");
|
|
55621
|
+
const priority = flagString(flags, "priority");
|
|
55622
|
+
const deliverable = flagString(flags, "deliverable");
|
|
55623
|
+
if (status === undefined && priority === undefined && deliverable === undefined) {
|
|
55624
|
+
throw usageError("tasks set needs --status, --priority or --deliverable");
|
|
55625
|
+
}
|
|
55626
|
+
const body = parseInput(updateTaskInputSchema, {
|
|
55627
|
+
...status !== undefined ? { status: taskStatusWire(status) } : {},
|
|
55628
|
+
...priority !== undefined ? { priority: priority.trim().toLowerCase() } : {},
|
|
55629
|
+
...deliverable !== undefined ? { deliverable: deliverable.trim() || null } : {}
|
|
55630
|
+
});
|
|
55631
|
+
return {
|
|
55632
|
+
data: await requireClient().patch(pathOf(taskOperations.update, { id }), body),
|
|
55633
|
+
render: renderTask
|
|
55634
|
+
};
|
|
55635
|
+
}
|
|
55636
|
+
})
|
|
53783
55637
|
];
|
|
53784
55638
|
|
|
53785
55639
|
// src/commands/time-blocks.ts
|
|
53786
|
-
var
|
|
55640
|
+
var commands55 = [
|
|
53787
55641
|
{
|
|
53788
55642
|
spec: {
|
|
53789
55643
|
path: ["time-blocks", "record"],
|
|
@@ -53837,7 +55691,7 @@ var commands50 = [
|
|
|
53837
55691
|
];
|
|
53838
55692
|
|
|
53839
55693
|
// src/today.ts
|
|
53840
|
-
var OPEN_STATUSES = new Set(
|
|
55694
|
+
var OPEN_STATUSES = new Set(OPEN_TASK_STATUSES);
|
|
53841
55695
|
function isTaskLike(value) {
|
|
53842
55696
|
return typeof value === "object" && value !== null && typeof value.id === "string";
|
|
53843
55697
|
}
|
|
@@ -53923,7 +55777,48 @@ var FROM_EARLIER_ANSWERS = ["today", "later", "someday", "let-go"];
|
|
|
53923
55777
|
function localDayStart(now) {
|
|
53924
55778
|
return new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
|
53925
55779
|
}
|
|
53926
|
-
|
|
55780
|
+
function localWeek(now) {
|
|
55781
|
+
const back = (now.getDay() + 6) % 7;
|
|
55782
|
+
const from = new Date(now.getFullYear(), now.getMonth(), now.getDate() - back);
|
|
55783
|
+
return {
|
|
55784
|
+
from,
|
|
55785
|
+
to: new Date(from.getFullYear(), from.getMonth(), from.getDate() + 7)
|
|
55786
|
+
};
|
|
55787
|
+
}
|
|
55788
|
+
function landedWho(actor) {
|
|
55789
|
+
if (!actor || actor.kind === "you")
|
|
55790
|
+
return "you";
|
|
55791
|
+
if (actor.kind === "agent") {
|
|
55792
|
+
const name = actor.name ?? "agent";
|
|
55793
|
+
return actor.machine ? `${name} on ${actor.machine}` : name;
|
|
55794
|
+
}
|
|
55795
|
+
return actor.name ?? (actor.kind === "echo" ? "your agent" : "a member");
|
|
55796
|
+
}
|
|
55797
|
+
function renderLandedCounts(data, mode) {
|
|
55798
|
+
const base = renderLanded(data, mode);
|
|
55799
|
+
const c = data;
|
|
55800
|
+
if (c.itemsTotal === undefined)
|
|
55801
|
+
return base;
|
|
55802
|
+
const out = [
|
|
55803
|
+
base,
|
|
55804
|
+
"",
|
|
55805
|
+
paint(mode, "bold", `Across sections \xB7 ${c.itemsTotal} (today ${c.today ?? 0}, before ${c.previousWeekTotal ?? 0})`)
|
|
55806
|
+
];
|
|
55807
|
+
for (const d of c.byDay ?? [])
|
|
55808
|
+
out.push(` ${d.date} ${d.you} by you \xB7 ${d.agents} by agents`);
|
|
55809
|
+
const sections = (c.bySection ?? []).map((s) => `${s.section} ${s.count}`).join(" \xB7 ");
|
|
55810
|
+
if (sections)
|
|
55811
|
+
out.push(` ${sections}`);
|
|
55812
|
+
const items = c.items ?? [];
|
|
55813
|
+
if (items.length > 0)
|
|
55814
|
+
out.push("");
|
|
55815
|
+
for (const i of items) {
|
|
55816
|
+
out.push(` ${i.title} ${paint(mode, "dim", `\xB7 ${i.where} \xB7 ${landedWho(i.actor)}`)}`);
|
|
55817
|
+
}
|
|
55818
|
+
return out.join(`
|
|
55819
|
+
`);
|
|
55820
|
+
}
|
|
55821
|
+
var commands56 = [
|
|
53927
55822
|
{
|
|
53928
55823
|
spec: {
|
|
53929
55824
|
path: ["today"],
|
|
@@ -54059,22 +55954,47 @@ var commands51 = [
|
|
|
54059
55954
|
{
|
|
54060
55955
|
spec: {
|
|
54061
55956
|
path: ["landed"],
|
|
54062
|
-
summary: "What got done in a window (by completedAt), split by who finished it.",
|
|
55957
|
+
summary: "What got done in a window (by completedAt), split by who finished it, and counted by day and section.",
|
|
54063
55958
|
args: [],
|
|
54064
55959
|
flags: [
|
|
54065
|
-
{
|
|
54066
|
-
|
|
55960
|
+
{
|
|
55961
|
+
name: "from",
|
|
55962
|
+
type: "string",
|
|
55963
|
+
description: "Window start (ISO); default today, UTC."
|
|
55964
|
+
},
|
|
55965
|
+
{
|
|
55966
|
+
name: "to",
|
|
55967
|
+
type: "string",
|
|
55968
|
+
description: "Window end (ISO); default a day after from."
|
|
55969
|
+
},
|
|
55970
|
+
{
|
|
55971
|
+
name: "week",
|
|
55972
|
+
type: "boolean",
|
|
55973
|
+
description: "This local week, Monday to Monday (instead of --from/--to)."
|
|
55974
|
+
},
|
|
55975
|
+
{
|
|
55976
|
+
name: "tz",
|
|
55977
|
+
type: "string",
|
|
55978
|
+
description: "IANA zone the days are cut in; default this machine's."
|
|
55979
|
+
}
|
|
54067
55980
|
],
|
|
54068
55981
|
scopes: [...readOperations.landed.scopes],
|
|
54069
55982
|
returns: "LandedResponse",
|
|
54070
|
-
notes: "Cancelled tasks never count. For a week: --from <monday> --to <next monday>."
|
|
55983
|
+
notes: "Cancelled tasks never count. Across sections: tasks, habit check-ins, agent sessions, papers filed and shopping ticks; your agent's and agents' work counts and is marked. For a week: --week, or --from <monday> --to <next monday>."
|
|
54071
55984
|
},
|
|
54072
|
-
run: async ({ flags, requireClient }) =>
|
|
54073
|
-
|
|
54074
|
-
|
|
54075
|
-
|
|
54076
|
-
|
|
54077
|
-
|
|
55985
|
+
run: async ({ flags, requireClient }) => {
|
|
55986
|
+
const week = flagBool(flags, "week") ? localWeek(new Date) : null;
|
|
55987
|
+
return {
|
|
55988
|
+
data: await requireClient().get(pathOf(readOperations.landed), {
|
|
55989
|
+
query: {
|
|
55990
|
+
from: flagString(flags, "from") ?? week?.from.toISOString(),
|
|
55991
|
+
to: flagString(flags, "to") ?? week?.to.toISOString(),
|
|
55992
|
+
tz: flagString(flags, "tz") ?? Intl.DateTimeFormat().resolvedOptions().timeZone
|
|
55993
|
+
}
|
|
55994
|
+
}),
|
|
55995
|
+
render: renderLandedCounts
|
|
55996
|
+
};
|
|
55997
|
+
}
|
|
54078
55998
|
},
|
|
54079
55999
|
{
|
|
54080
56000
|
spec: {
|
|
@@ -54139,8 +56059,257 @@ var commands51 = [
|
|
|
54139
56059
|
}
|
|
54140
56060
|
];
|
|
54141
56061
|
|
|
56062
|
+
// src/commands/work-views.ts
|
|
56063
|
+
var FILTER_FLAGS = [
|
|
56064
|
+
{
|
|
56065
|
+
name: "status",
|
|
56066
|
+
type: "string",
|
|
56067
|
+
description: "Any of these statuses (backlog,todo,in-progress,waiting,done)."
|
|
56068
|
+
},
|
|
56069
|
+
{
|
|
56070
|
+
name: "not-status",
|
|
56071
|
+
type: "string",
|
|
56072
|
+
description: "None of these statuses, e.g. done."
|
|
56073
|
+
},
|
|
56074
|
+
{ name: "area", type: "string", description: "Any of these Area ids, comma-separated." },
|
|
56075
|
+
{
|
|
56076
|
+
name: "project",
|
|
56077
|
+
type: "string",
|
|
56078
|
+
description: "Any of these Project ids, comma-separated."
|
|
56079
|
+
},
|
|
56080
|
+
{
|
|
56081
|
+
name: "label",
|
|
56082
|
+
type: "string",
|
|
56083
|
+
description: "Any of these labels (tags), comma-separated."
|
|
56084
|
+
},
|
|
56085
|
+
{
|
|
56086
|
+
name: "priority",
|
|
56087
|
+
type: "string",
|
|
56088
|
+
description: "Any of these priorities (none,low,medium,high)."
|
|
56089
|
+
},
|
|
56090
|
+
{
|
|
56091
|
+
name: "assignee",
|
|
56092
|
+
type: "string",
|
|
56093
|
+
description: "me, none, member:<id> or agent:<id>."
|
|
56094
|
+
},
|
|
56095
|
+
{
|
|
56096
|
+
name: "waiting",
|
|
56097
|
+
type: "string",
|
|
56098
|
+
description: "true = only Waiting, false = none of them."
|
|
56099
|
+
},
|
|
56100
|
+
{
|
|
56101
|
+
name: "due",
|
|
56102
|
+
type: "string",
|
|
56103
|
+
description: "overdue, today, this_week, next_week or none."
|
|
56104
|
+
},
|
|
56105
|
+
{
|
|
56106
|
+
name: "scheduled",
|
|
56107
|
+
type: "string",
|
|
56108
|
+
description: "The planned day: overdue, today, this_week, next_week or none."
|
|
56109
|
+
},
|
|
56110
|
+
{
|
|
56111
|
+
name: "when",
|
|
56112
|
+
type: "string",
|
|
56113
|
+
description: "Due or planned in: overdue, today, this_week, next_week or none."
|
|
56114
|
+
}
|
|
56115
|
+
];
|
|
56116
|
+
var SHAPE_FLAGS = [
|
|
56117
|
+
{
|
|
56118
|
+
name: "group",
|
|
56119
|
+
type: "string",
|
|
56120
|
+
description: "area, status, project, priority, assignee or none."
|
|
56121
|
+
},
|
|
56122
|
+
{ name: "view", type: "string", description: "list, board or timeline." },
|
|
56123
|
+
{
|
|
56124
|
+
name: "pin",
|
|
56125
|
+
type: "string",
|
|
56126
|
+
description: "true pins it to Work's top row, false unpins."
|
|
56127
|
+
}
|
|
56128
|
+
];
|
|
56129
|
+
var list3 = (raw) => raw.split(",").map((s) => s.trim()).filter(Boolean);
|
|
56130
|
+
function filtersOf(flags) {
|
|
56131
|
+
const out = {};
|
|
56132
|
+
const lists = [
|
|
56133
|
+
["status", "status", taskStatusWire],
|
|
56134
|
+
["not-status", "notStatus", taskStatusWire],
|
|
56135
|
+
["area", "areaIds", (v) => v],
|
|
56136
|
+
["project", "projectIds", (v) => v],
|
|
56137
|
+
["label", "labels", (v) => v],
|
|
56138
|
+
["priority", "priority", (v) => v.toLowerCase()]
|
|
56139
|
+
];
|
|
56140
|
+
for (const [flag, key, norm] of lists) {
|
|
56141
|
+
const values = flagStrings(flags, flag).flatMap(list3);
|
|
56142
|
+
if (values.length > 0)
|
|
56143
|
+
out[key] = values.map(norm);
|
|
56144
|
+
}
|
|
56145
|
+
const assignee = flagString(flags, "assignee");
|
|
56146
|
+
if (assignee)
|
|
56147
|
+
out.assignee = assignee.trim();
|
|
56148
|
+
const waiting = flagString(flags, "waiting");
|
|
56149
|
+
if (waiting !== undefined)
|
|
56150
|
+
out.waiting = waiting !== "false";
|
|
56151
|
+
for (const key of ["due", "scheduled", "when"]) {
|
|
56152
|
+
const v = flagString(flags, key);
|
|
56153
|
+
if (v)
|
|
56154
|
+
out[key] = v.trim().toLowerCase().replace(/-/g, "_");
|
|
56155
|
+
}
|
|
56156
|
+
return Object.keys(out).length > 0 ? out : null;
|
|
56157
|
+
}
|
|
56158
|
+
function shapeOf(flags) {
|
|
56159
|
+
const out = {};
|
|
56160
|
+
const group = flagString(flags, "group");
|
|
56161
|
+
if (group)
|
|
56162
|
+
out.groupBy = group.trim().toLowerCase();
|
|
56163
|
+
const view = flagString(flags, "view");
|
|
56164
|
+
if (view)
|
|
56165
|
+
out.view = view.trim().toLowerCase();
|
|
56166
|
+
const pin = flagString(flags, "pin");
|
|
56167
|
+
if (pin !== undefined)
|
|
56168
|
+
out.pinned = pin !== "false";
|
|
56169
|
+
return out;
|
|
56170
|
+
}
|
|
56171
|
+
async function findView(client, nameOrId) {
|
|
56172
|
+
const page = await client.get(pathOf(workViewOperations.list));
|
|
56173
|
+
const views = Array.isArray(page) ? page : page.data;
|
|
56174
|
+
const key = nameOrId.trim().toLowerCase();
|
|
56175
|
+
const view = views.find((v) => v.id === nameOrId) ?? views.find((v) => v.name.toLowerCase() === key);
|
|
56176
|
+
if (!view) {
|
|
56177
|
+
throw new CliError("not_found", `no Work view named \`${nameOrId}\` \u2014 run \`do views list\``, EXIT.NOT_FOUND);
|
|
56178
|
+
}
|
|
56179
|
+
return view;
|
|
56180
|
+
}
|
|
56181
|
+
function renderViews(data, mode) {
|
|
56182
|
+
const page = data;
|
|
56183
|
+
const views = Array.isArray(page) ? page : page.data;
|
|
56184
|
+
if (views.length === 0)
|
|
56185
|
+
return paint(mode, "dim", "(no views)");
|
|
56186
|
+
const width = Math.max(...views.map((v) => v.name.length));
|
|
56187
|
+
return views.map((v) => ` ${v.pinned ? "\u2605 " : " "}${v.name.padEnd(width)} ${String(v.count).padStart(4)} ${paint(mode, "dim", v.id)}`).join(`
|
|
56188
|
+
`);
|
|
56189
|
+
}
|
|
56190
|
+
function renderView(data, mode) {
|
|
56191
|
+
return renderViews([data], mode);
|
|
56192
|
+
}
|
|
56193
|
+
var commands57 = [
|
|
56194
|
+
defineCommand({
|
|
56195
|
+
operation: workViewOperations.list,
|
|
56196
|
+
path: ["views", "list"],
|
|
56197
|
+
summary: "List the Work saved views, each with its live count.",
|
|
56198
|
+
returns: "WorkView[]",
|
|
56199
|
+
run: async ({ requireClient }) => ({
|
|
56200
|
+
data: await requireClient().get(pathOf(workViewOperations.list)),
|
|
56201
|
+
render: renderViews
|
|
56202
|
+
})
|
|
56203
|
+
}),
|
|
56204
|
+
defineCommand({
|
|
56205
|
+
operation: taskOperations.list,
|
|
56206
|
+
path: ["views", "show"],
|
|
56207
|
+
summary: "The tasks a Work saved view matches (exactly its count).",
|
|
56208
|
+
args: [{ name: "view", required: true, description: "The view's name (any case) or id." }],
|
|
56209
|
+
scopes: [...new Set([...workViewOperations.list.scopes, ...taskOperations.list.scopes])],
|
|
56210
|
+
returns: "Task[]",
|
|
56211
|
+
notes: " with ?view=<id>, after the view is found by name in the views list.",
|
|
56212
|
+
run: async ({ args, requireClient }) => {
|
|
56213
|
+
const client = requireClient();
|
|
56214
|
+
const view = await findView(client, requireArg(args, 0, "view"));
|
|
56215
|
+
return {
|
|
56216
|
+
data: await client.getPage(pathOf(taskOperations.list), { query: { view: view.id } }),
|
|
56217
|
+
render: renderList
|
|
56218
|
+
};
|
|
56219
|
+
}
|
|
56220
|
+
}),
|
|
56221
|
+
defineCommand({
|
|
56222
|
+
operation: workViewOperations.create,
|
|
56223
|
+
path: ["views", "save"],
|
|
56224
|
+
summary: "Save a Work view: a name, its filters, and how Work groups and draws it.",
|
|
56225
|
+
args: [{ name: "name", required: true, description: "The view's name." }],
|
|
56226
|
+
flags: [...FILTER_FLAGS, ...SHAPE_FLAGS],
|
|
56227
|
+
returns: "WorkView",
|
|
56228
|
+
run: async ({ args, flags, requireClient }) => {
|
|
56229
|
+
const name = args.join(" ").trim();
|
|
56230
|
+
if (!name)
|
|
56231
|
+
throw usageError('views save needs a name, e.g. `do views save "Deep work"`');
|
|
56232
|
+
const body = parseInput(createWorkViewInputSchema, {
|
|
56233
|
+
name,
|
|
56234
|
+
filters: filtersOf(flags) ?? {},
|
|
56235
|
+
...shapeOf(flags)
|
|
56236
|
+
});
|
|
56237
|
+
return {
|
|
56238
|
+
data: await requireClient().post(pathOf(workViewOperations.create), body),
|
|
56239
|
+
render: renderView
|
|
56240
|
+
};
|
|
56241
|
+
}
|
|
56242
|
+
}),
|
|
56243
|
+
defineCommand({
|
|
56244
|
+
operation: workViewOperations.update,
|
|
56245
|
+
path: ["views", "update"],
|
|
56246
|
+
summary: "Rename a Work view, or change its filters (replaced whole), grouping or kind.",
|
|
56247
|
+
args: [{ name: "view", required: true, description: "The view's name (any case) or id." }],
|
|
56248
|
+
flags: [
|
|
56249
|
+
{ name: "name", type: "string", description: "Its new name." },
|
|
56250
|
+
...FILTER_FLAGS,
|
|
56251
|
+
...SHAPE_FLAGS
|
|
56252
|
+
],
|
|
56253
|
+
returns: "WorkView",
|
|
56254
|
+
run: async ({ args, flags, requireClient }) => {
|
|
56255
|
+
const client = requireClient();
|
|
56256
|
+
const view = await findView(client, requireArg(args, 0, "view"));
|
|
56257
|
+
const filters = filtersOf(flags);
|
|
56258
|
+
const rename = flagString(flags, "name");
|
|
56259
|
+
const body = parseInput(updateWorkViewInputSchema, {
|
|
56260
|
+
...rename !== undefined ? { name: rename } : {},
|
|
56261
|
+
...filters ? { filters } : {},
|
|
56262
|
+
...shapeOf(flags)
|
|
56263
|
+
});
|
|
56264
|
+
if (Object.keys(body).length === 0) {
|
|
56265
|
+
throw usageError("views update needs --name, a filter flag, --group, --view or --pin");
|
|
56266
|
+
}
|
|
56267
|
+
return {
|
|
56268
|
+
data: await client.patch(pathOf(workViewOperations.update, { id: view.id }), body),
|
|
56269
|
+
render: renderView
|
|
56270
|
+
};
|
|
56271
|
+
}
|
|
56272
|
+
}),
|
|
56273
|
+
defineCommand({
|
|
56274
|
+
operation: workViewOperations.reorder,
|
|
56275
|
+
path: ["views", "reorder"],
|
|
56276
|
+
summary: "Put the Work views in this order (names or ids); the rest keep theirs after.",
|
|
56277
|
+
args: [{ name: "views", required: true, description: "Views by name or id, in order." }],
|
|
56278
|
+
returns: "WorkView[]",
|
|
56279
|
+
run: async ({ args, requireClient }) => {
|
|
56280
|
+
if (args.length === 0)
|
|
56281
|
+
throw usageError("views reorder needs the views in order");
|
|
56282
|
+
const client = requireClient();
|
|
56283
|
+
const ids = [];
|
|
56284
|
+
for (const arg of args)
|
|
56285
|
+
ids.push((await findView(client, arg)).id);
|
|
56286
|
+
const body = parseInput(reorderWorkViewsInputSchema, { ids });
|
|
56287
|
+
return {
|
|
56288
|
+
data: await client.post(pathOf(workViewOperations.reorder), body),
|
|
56289
|
+
render: renderViews
|
|
56290
|
+
};
|
|
56291
|
+
}
|
|
56292
|
+
}),
|
|
56293
|
+
defineCommand({
|
|
56294
|
+
operation: workViewOperations.remove,
|
|
56295
|
+
path: ["views", "delete"],
|
|
56296
|
+
summary: "Delete a Work view (a default one too; it isn't seeded again).",
|
|
56297
|
+
args: [{ name: "view", required: true, description: "The view's name (any case) or id." }],
|
|
56298
|
+
returns: "{ ok, deleted }",
|
|
56299
|
+
run: async ({ args, requireClient }) => {
|
|
56300
|
+
const client = requireClient();
|
|
56301
|
+
const view = await findView(client, requireArg(args, 0, "view"));
|
|
56302
|
+
await client.delete(pathOf(workViewOperations.remove, { id: view.id }));
|
|
56303
|
+
return {
|
|
56304
|
+
data: { ok: true, deleted: view.id, name: view.name },
|
|
56305
|
+
render: () => `Deleted the view ${view.name}.`
|
|
56306
|
+
};
|
|
56307
|
+
}
|
|
56308
|
+
})
|
|
56309
|
+
];
|
|
56310
|
+
|
|
54142
56311
|
// src/commands/worktree-links.ts
|
|
54143
|
-
var
|
|
56312
|
+
var commands58 = [
|
|
54144
56313
|
{
|
|
54145
56314
|
spec: {
|
|
54146
56315
|
path: ["worktree-links", "list"],
|
|
@@ -54298,7 +56467,13 @@ var FEATURE_COMMANDS = [
|
|
|
54298
56467
|
...commands49,
|
|
54299
56468
|
...commands50,
|
|
54300
56469
|
...commands51,
|
|
54301
|
-
...commands52
|
|
56470
|
+
...commands52,
|
|
56471
|
+
...commands53,
|
|
56472
|
+
...commands54,
|
|
56473
|
+
...commands55,
|
|
56474
|
+
...commands56,
|
|
56475
|
+
...commands57,
|
|
56476
|
+
...commands58
|
|
54302
56477
|
];
|
|
54303
56478
|
|
|
54304
56479
|
// src/registry.ts
|
|
@@ -54424,7 +56599,8 @@ async function dispatchEntity(entity, rest, flags, requireClient) {
|
|
|
54424
56599
|
query[key] = f.sends;
|
|
54425
56600
|
continue;
|
|
54426
56601
|
}
|
|
54427
|
-
const
|
|
56602
|
+
const raw = flags[f.name] === true ? "true" : flagString(flags, f.name);
|
|
56603
|
+
const value = raw !== undefined && f.normalize ? f.normalize(raw) : raw;
|
|
54428
56604
|
if (value !== undefined)
|
|
54429
56605
|
query[key] = value;
|
|
54430
56606
|
else if (f.required)
|