@robbeverhelst/do 1.339.2 → 1.341.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 +2379 -266
- 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.341.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),
|
|
@@ -18301,10 +18145,12 @@ var routineRunSteps = pgTable("routine_run_steps", {
|
|
|
18301
18145
|
id: text("id").primaryKey(),
|
|
18302
18146
|
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
18303
18147
|
runId: text("run_id").notNull().references(() => routineRuns.id),
|
|
18304
|
-
stepId: text("step_id").
|
|
18148
|
+
stepId: text("step_id").references(() => routineSteps.id),
|
|
18305
18149
|
title: text("title").notNull(),
|
|
18306
18150
|
refKind: routineStepRef("ref_kind").notNull().default("free"),
|
|
18307
18151
|
habitId: text("habit_id").references(() => habits.id),
|
|
18152
|
+
taskId: text("task_id").references(() => tasks.id),
|
|
18153
|
+
reason: text("reason"),
|
|
18308
18154
|
habitEntryId: text("habit_entry_id").references(() => habitEntries.id),
|
|
18309
18155
|
sortOrder: integer2("sort_order").notNull().default(0),
|
|
18310
18156
|
durationMinutes: integer2("duration_minutes"),
|
|
@@ -18319,6 +18165,8 @@ var routineRunSteps = pgTable("routine_run_steps", {
|
|
|
18319
18165
|
var projects = pgTable("projects", {
|
|
18320
18166
|
...leafColumns(),
|
|
18321
18167
|
status: projectStatus("status").notNull().default("planning"),
|
|
18168
|
+
priority: workPriority("priority").notNull().default("none"),
|
|
18169
|
+
number: integer2("number").notNull().default(0),
|
|
18322
18170
|
icon: text("icon"),
|
|
18323
18171
|
progress: integer2("progress").notNull().default(0),
|
|
18324
18172
|
startAt: timestamp("start_at", { withTimezone: true }),
|
|
@@ -18329,6 +18177,7 @@ var projects = pgTable("projects", {
|
|
|
18329
18177
|
finishNotYetAt: timestamp("finish_not_yet_at", { withTimezone: true })
|
|
18330
18178
|
}, (t) => [
|
|
18331
18179
|
index("projects_tenant_idx").on(t.tenantId),
|
|
18180
|
+
unique("projects_tenant_number_uniq").on(t.tenantId, t.number),
|
|
18332
18181
|
index("projects_tenant_area_idx").on(t.tenantId, t.areaId)
|
|
18333
18182
|
]);
|
|
18334
18183
|
var projectMilestones = pgTable("project_milestones", {
|
|
@@ -18370,6 +18219,191 @@ var userSettings = pgTable("user_settings", {
|
|
|
18370
18219
|
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
18371
18220
|
}, (t) => [unique("user_settings_tenant_user_uniq").on(t.tenantId, t.userId)]);
|
|
18372
18221
|
|
|
18222
|
+
// ../../packages/schema/src/db/challenges.ts
|
|
18223
|
+
var challengeSource = pgEnum("challenge_source", ["self", "system"]);
|
|
18224
|
+
var challengeSubjectType = pgEnum("challenge_subject_type", ["habit", "area", "tag"]);
|
|
18225
|
+
var challengePartKind = pgEnum("challenge_part_kind", ["habit", "task_series"]);
|
|
18226
|
+
var challenges = pgTable("challenges", {
|
|
18227
|
+
id: text("id").primaryKey(),
|
|
18228
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id, { onDelete: "cascade" }),
|
|
18229
|
+
title: text("title").notNull(),
|
|
18230
|
+
description: text("description"),
|
|
18231
|
+
source: challengeSource("source").notNull().default("self"),
|
|
18232
|
+
metric: text("metric").notNull(),
|
|
18233
|
+
subjectType: challengeSubjectType("subject_type"),
|
|
18234
|
+
subjectId: text("subject_id"),
|
|
18235
|
+
target: integer2("target").notNull(),
|
|
18236
|
+
startAt: timestamp("start_at", { withTimezone: true }).notNull(),
|
|
18237
|
+
endAt: timestamp("end_at", { withTimezone: true }).notNull(),
|
|
18238
|
+
projectId: text("project_id").references(() => projects.id, { onDelete: "set null" }),
|
|
18239
|
+
createdBy: text("created_by").references(() => users.id, { onDelete: "set null" }),
|
|
18240
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
18241
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
18242
|
+
}, (t) => [
|
|
18243
|
+
index("challenges_tenant_idx").on(t.tenantId),
|
|
18244
|
+
index("challenges_tenant_window_idx").on(t.tenantId, t.startAt, t.endAt),
|
|
18245
|
+
index("challenges_tenant_subject_idx").on(t.tenantId, t.subjectType, t.subjectId),
|
|
18246
|
+
index("challenges_tenant_project_idx").on(t.tenantId, t.projectId),
|
|
18247
|
+
check2("challenges_subject_pair_chk", sql`(${t.subjectType} IS NULL) = (${t.subjectId} IS NULL)`)
|
|
18248
|
+
]);
|
|
18249
|
+
var challengeParticipants = pgTable("challenge_participants", {
|
|
18250
|
+
id: text("id").primaryKey(),
|
|
18251
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id, { onDelete: "cascade" }),
|
|
18252
|
+
challengeId: text("challenge_id").notNull().references(() => challenges.id, { onDelete: "cascade" }),
|
|
18253
|
+
userId: text("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
|
|
18254
|
+
joinedAt: timestamp("joined_at", { withTimezone: true }).notNull().defaultNow()
|
|
18255
|
+
}, (t) => [
|
|
18256
|
+
unique("challenge_participants_challenge_user_uniq").on(t.challengeId, t.userId),
|
|
18257
|
+
index("challenge_participants_tenant_idx").on(t.tenantId),
|
|
18258
|
+
index("challenge_participants_user_idx").on(t.tenantId, t.userId)
|
|
18259
|
+
]);
|
|
18260
|
+
var challengeParts = pgTable("challenge_parts", {
|
|
18261
|
+
id: text("id").primaryKey(),
|
|
18262
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id, { onDelete: "cascade" }),
|
|
18263
|
+
challengeId: text("challenge_id").notNull().references(() => challenges.id, { onDelete: "cascade" }),
|
|
18264
|
+
kind: challengePartKind("kind").notNull(),
|
|
18265
|
+
subjectId: text("subject_id").notNull(),
|
|
18266
|
+
position: integer2("position").notNull()
|
|
18267
|
+
}, (t) => [
|
|
18268
|
+
index("challenge_parts_tenant_idx").on(t.tenantId),
|
|
18269
|
+
index("challenge_parts_challenge_idx").on(t.challengeId, t.position),
|
|
18270
|
+
index("challenge_parts_tenant_subject_idx").on(t.tenantId, t.kind, t.subjectId)
|
|
18271
|
+
]);
|
|
18272
|
+
|
|
18273
|
+
// ../../packages/schema/src/db/collaboration.ts
|
|
18274
|
+
var capability = pgEnum("collab_capability", ["view", "comment", "edit", "admin"]);
|
|
18275
|
+
var grantSubjectType = pgEnum("grant_subject_type", ["member", "role"]);
|
|
18276
|
+
var inviteType = pgEnum("invite_type", ["email", "link", "join_request", "guest"]);
|
|
18277
|
+
var inviteStatus = pgEnum("invite_status", ["pending", "accepted", "revoked", "expired"]);
|
|
18278
|
+
var permissionSets = pgTable("permission_sets", {
|
|
18279
|
+
id: text("id").primaryKey(),
|
|
18280
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
18281
|
+
name: text("name").notNull(),
|
|
18282
|
+
canView: boolean4("can_view").notNull().default(true),
|
|
18283
|
+
canComment: boolean4("can_comment").notNull().default(false),
|
|
18284
|
+
canEdit: boolean4("can_edit").notNull().default(false),
|
|
18285
|
+
canShare: boolean4("can_share").notNull().default(false),
|
|
18286
|
+
canManageMembers: boolean4("can_manage_members").notNull().default(false),
|
|
18287
|
+
canManageRoles: boolean4("can_manage_roles").notNull().default(false),
|
|
18288
|
+
canManageSpace: boolean4("can_manage_space").notNull().default(false),
|
|
18289
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
18290
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
18291
|
+
}, (t) => [unique("permission_sets_tenant_name_uniq").on(t.tenantId, t.name)]);
|
|
18292
|
+
var roles = pgTable("roles", {
|
|
18293
|
+
id: text("id").primaryKey(),
|
|
18294
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
18295
|
+
name: text("name").notNull(),
|
|
18296
|
+
description: text("description"),
|
|
18297
|
+
permissionSetId: text("permission_set_id").notNull().references(() => permissionSets.id),
|
|
18298
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
18299
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
18300
|
+
}, (t) => [unique("roles_tenant_name_uniq").on(t.tenantId, t.name)]);
|
|
18301
|
+
var invites = pgTable("invites", {
|
|
18302
|
+
id: text("id").primaryKey(),
|
|
18303
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
18304
|
+
type: inviteType("type").notNull(),
|
|
18305
|
+
email: text("email"),
|
|
18306
|
+
token: text("token").unique(),
|
|
18307
|
+
tokenHash: text("token_hash").unique(),
|
|
18308
|
+
tokenSealed: text("token_sealed"),
|
|
18309
|
+
role: baseRole("role").notNull().default("member"),
|
|
18310
|
+
customRoleId: text("custom_role_id").references(() => roles.id),
|
|
18311
|
+
invitedByUserId: text("invited_by_user_id").references(() => users.id),
|
|
18312
|
+
status: inviteStatus("status").notNull().default("pending"),
|
|
18313
|
+
accessUntil: timestamp("access_until", { withTimezone: true }),
|
|
18314
|
+
expiresAt: timestamp("expires_at", { withTimezone: true }),
|
|
18315
|
+
acceptedAt: timestamp("accepted_at", { withTimezone: true }),
|
|
18316
|
+
acceptedByUserId: text("accepted_by_user_id").references(() => users.id),
|
|
18317
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
18318
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
18319
|
+
}, (t) => [index("invites_tenant_status_idx").on(t.tenantId, t.status)]);
|
|
18320
|
+
var nodeGrants = pgTable("node_grants", {
|
|
18321
|
+
id: text("id").primaryKey(),
|
|
18322
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
18323
|
+
nodeId: text("node_id").notNull().references(() => nodes.id),
|
|
18324
|
+
subjectType: grantSubjectType("subject_type").notNull(),
|
|
18325
|
+
subjectId: text("subject_id").notNull(),
|
|
18326
|
+
capability: capability("capability").notNull(),
|
|
18327
|
+
assigned: boolean4("assigned").notNull().default(false),
|
|
18328
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
18329
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
18330
|
+
}, (t) => [
|
|
18331
|
+
unique("node_grants_node_subject_uniq").on(t.tenantId, t.nodeId, t.subjectType, t.subjectId),
|
|
18332
|
+
index("node_grants_tenant_node_idx").on(t.tenantId, t.nodeId),
|
|
18333
|
+
index("node_grants_node_idx").on(t.nodeId)
|
|
18334
|
+
]);
|
|
18335
|
+
var shareLinks = pgTable("share_links", {
|
|
18336
|
+
id: text("id").primaryKey(),
|
|
18337
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
18338
|
+
nodeId: text("node_id").notNull().references(() => nodes.id),
|
|
18339
|
+
tokenHash: text("token_hash").notNull().unique(),
|
|
18340
|
+
capability: capability("capability").notNull().default("view"),
|
|
18341
|
+
createdByUserId: text("created_by_user_id").references(() => users.id),
|
|
18342
|
+
expiresAt: timestamp("expires_at", { withTimezone: true }),
|
|
18343
|
+
revokedAt: timestamp("revoked_at", { withTimezone: true }),
|
|
18344
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
18345
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
18346
|
+
}, (t) => [
|
|
18347
|
+
index("share_links_tenant_node_idx").on(t.tenantId, t.nodeId),
|
|
18348
|
+
index("share_links_node_idx").on(t.nodeId)
|
|
18349
|
+
]);
|
|
18350
|
+
var shareLinkGuests = pgTable("share_link_guests", {
|
|
18351
|
+
id: text("id").primaryKey(),
|
|
18352
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
18353
|
+
shareLinkId: text("share_link_id").notNull().references(() => shareLinks.id, { onDelete: "cascade" }),
|
|
18354
|
+
name: text("name").notNull(),
|
|
18355
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
|
|
18356
|
+
}, (t) => [
|
|
18357
|
+
uniqueIndex("share_link_guests_link_name_uniq").on(t.shareLinkId, sql`lower(${t.name})`),
|
|
18358
|
+
index("share_link_guests_tenant_idx").on(t.tenantId)
|
|
18359
|
+
]);
|
|
18360
|
+
var comments = pgTable("comments", {
|
|
18361
|
+
id: text("id").primaryKey(),
|
|
18362
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
18363
|
+
nodeId: text("node_id").notNull().references(() => nodes.id),
|
|
18364
|
+
parentId: text("parent_id").references(() => comments.id),
|
|
18365
|
+
authorUserId: text("author_user_id").notNull().references(() => users.id),
|
|
18366
|
+
body: text("body").notNull(),
|
|
18367
|
+
editedAt: timestamp("edited_at", { withTimezone: true }),
|
|
18368
|
+
deletedAt: timestamp("deleted_at", { withTimezone: true }),
|
|
18369
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
18370
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
18371
|
+
}, (t) => [
|
|
18372
|
+
index("comments_tenant_node_created_idx").on(t.tenantId, t.nodeId, t.createdAt),
|
|
18373
|
+
index("comments_parent_idx").on(t.parentId),
|
|
18374
|
+
index("comments_node_idx").on(t.nodeId)
|
|
18375
|
+
]);
|
|
18376
|
+
var commentMentions = pgTable("comment_mentions", {
|
|
18377
|
+
id: text("id").primaryKey(),
|
|
18378
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
18379
|
+
commentId: text("comment_id").notNull().references(() => comments.id),
|
|
18380
|
+
mentionedUserId: text("mentioned_user_id").notNull().references(() => users.id),
|
|
18381
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
|
|
18382
|
+
}, (t) => [unique("comment_mentions_comment_user_uniq").on(t.commentId, t.mentionedUserId)]);
|
|
18383
|
+
var commentReactions = pgTable("comment_reactions", {
|
|
18384
|
+
id: text("id").primaryKey(),
|
|
18385
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
18386
|
+
commentId: text("comment_id").notNull().references(() => comments.id),
|
|
18387
|
+
userId: text("user_id").notNull().references(() => users.id),
|
|
18388
|
+
emoji: text("emoji").notNull(),
|
|
18389
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
|
|
18390
|
+
}, (t) => [unique("comment_reactions_comment_user_emoji_uniq").on(t.commentId, t.userId, t.emoji)]);
|
|
18391
|
+
var activityEvents = pgTable("activity_events", {
|
|
18392
|
+
id: text("id").primaryKey(),
|
|
18393
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id, { onDelete: "cascade" }),
|
|
18394
|
+
actorUserId: text("actor_user_id").references(() => users.id, { onDelete: "set null" }),
|
|
18395
|
+
actorAgentId: text("actor_agent_id"),
|
|
18396
|
+
action: text("action").notNull(),
|
|
18397
|
+
nodeId: text("node_id"),
|
|
18398
|
+
subjectType: text("subject_type"),
|
|
18399
|
+
subjectId: text("subject_id"),
|
|
18400
|
+
metadata: text("metadata"),
|
|
18401
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
|
|
18402
|
+
}, (t) => [
|
|
18403
|
+
index("activity_events_tenant_created_idx").on(t.tenantId, t.createdAt),
|
|
18404
|
+
index("activity_events_tenant_node_idx").on(t.tenantId, t.nodeId)
|
|
18405
|
+
]);
|
|
18406
|
+
|
|
18373
18407
|
// ../../packages/schema/src/db/contacts.ts
|
|
18374
18408
|
var contactKind = pgEnum("contact_kind", ["person", "organization"]);
|
|
18375
18409
|
var contacts = pgTable("contacts", {
|
|
@@ -18995,6 +19029,9 @@ var areaColorSchema = _enum2(areaColor.enumValues);
|
|
|
18995
19029
|
var reviewCadenceSchema = _enum2(reviewCadence.enumValues);
|
|
18996
19030
|
var projectStatusSchema = _enum2(projectStatus.enumValues);
|
|
18997
19031
|
var taskStatusSchema = _enum2(taskStatus.enumValues);
|
|
19032
|
+
var workPrioritySchema = _enum2(workPriority.enumValues);
|
|
19033
|
+
var OPEN_TASK_STATUSES = ["backlog", "todo", "in_progress", "waiting"];
|
|
19034
|
+
var BOARD_TASK_STATUSES = [...OPEN_TASK_STATUSES, "done"];
|
|
18998
19035
|
var routineKindSchema = _enum2(routineKind.enumValues);
|
|
18999
19036
|
var routineStepRefSchema = _enum2(routineStepRef.enumValues);
|
|
19000
19037
|
var routineRunStatusSchema = _enum2(routineRunStatus.enumValues);
|
|
@@ -19387,7 +19424,13 @@ var spaceSchema = createSelectSchema(tenants, {
|
|
|
19387
19424
|
createdAt: exports_coerce.date(),
|
|
19388
19425
|
updatedAt: exports_coerce.date(),
|
|
19389
19426
|
deletedAt: exports_coerce.date().nullable()
|
|
19390
|
-
}).omit({
|
|
19427
|
+
}).omit({
|
|
19428
|
+
gaardHouseUrl: true,
|
|
19429
|
+
awayFrom: true,
|
|
19430
|
+
awayUntil: true,
|
|
19431
|
+
lastTaskNumber: true,
|
|
19432
|
+
lastProjectNumber: true
|
|
19433
|
+
});
|
|
19391
19434
|
var backdropIdSchema = string2().trim().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, "a backdrop id is lowercase words joined by dashes").max(40);
|
|
19392
19435
|
var updateSpaceInputSchema = object({
|
|
19393
19436
|
name: string2().trim().min(1).max(120).optional(),
|
|
@@ -21598,6 +21641,17 @@ var noteMadeTaskSchema = object({
|
|
|
21598
21641
|
createdAt: exports_coerce.date(),
|
|
21599
21642
|
by: noteActorSchema
|
|
21600
21643
|
}).strict();
|
|
21644
|
+
var noteChecklistItemSchema = object({
|
|
21645
|
+
line: number2().int().nonnegative(),
|
|
21646
|
+
taskId: ulidSchema.nullable(),
|
|
21647
|
+
title: string2(),
|
|
21648
|
+
status: string2().nullable(),
|
|
21649
|
+
done: boolean2(),
|
|
21650
|
+
scheduledOn: exports_coerce.date().nullable(),
|
|
21651
|
+
completedAt: exports_coerce.date().nullable(),
|
|
21652
|
+
projectId: ulidSchema.nullable(),
|
|
21653
|
+
projectTitle: string2().nullable()
|
|
21654
|
+
}).strict();
|
|
21601
21655
|
var noteDetailsSchema = object({
|
|
21602
21656
|
noteId: ulidSchema,
|
|
21603
21657
|
links: array(noteLinkedNodeSchema),
|
|
@@ -21606,9 +21660,66 @@ var noteDetailsSchema = object({
|
|
|
21606
21660
|
createdBy: noteActorSchema,
|
|
21607
21661
|
editedBy: noteActorSchema,
|
|
21608
21662
|
seenBy: array(string2()),
|
|
21609
|
-
madeTasks: array(noteMadeTaskSchema)
|
|
21663
|
+
madeTasks: array(noteMadeTaskSchema),
|
|
21664
|
+
checklist: array(noteChecklistItemSchema).default([])
|
|
21610
21665
|
}).strict();
|
|
21611
21666
|
|
|
21667
|
+
// ../../packages/schema/src/db/project-updates.ts
|
|
21668
|
+
var projectUpdateStatus = pgEnum("project_update_status", [
|
|
21669
|
+
"on_track",
|
|
21670
|
+
"at_risk",
|
|
21671
|
+
"off_track",
|
|
21672
|
+
"milestone_done",
|
|
21673
|
+
"done"
|
|
21674
|
+
]);
|
|
21675
|
+
var PROJECT_UPDATE_BODY_MAX = 2000;
|
|
21676
|
+
var projectUpdates = pgTable("project_updates", {
|
|
21677
|
+
id: text("id").primaryKey(),
|
|
21678
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
21679
|
+
projectId: text("project_id").notNull().references(() => projects.id, { onDelete: "cascade" }),
|
|
21680
|
+
status: projectUpdateStatus("status").notNull(),
|
|
21681
|
+
body: text("body").notNull().default(""),
|
|
21682
|
+
authorUserId: text("author_user_id").references(() => users.id),
|
|
21683
|
+
authorAgentId: text("author_agent_id").references(() => agents.id),
|
|
21684
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
|
|
21685
|
+
}, (t) => [
|
|
21686
|
+
index("project_updates_project_created_idx").on(t.tenantId, t.projectId, t.createdAt),
|
|
21687
|
+
check2("project_updates_one_author_chk", sql`(${t.authorUserId} IS NULL) <> (${t.authorAgentId} IS NULL)`),
|
|
21688
|
+
check2("project_updates_body_len_chk", sql`char_length(${t.body}) <= 2000`)
|
|
21689
|
+
]);
|
|
21690
|
+
var projectLeads = pgTable("project_leads", {
|
|
21691
|
+
id: text("id").primaryKey(),
|
|
21692
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
21693
|
+
projectId: text("project_id").notNull().references(() => projects.id, { onDelete: "cascade" }),
|
|
21694
|
+
userId: text("user_id").notNull().references(() => users.id),
|
|
21695
|
+
position: integer2("position").notNull().default(0)
|
|
21696
|
+
}, (t) => [
|
|
21697
|
+
index("project_leads_project_idx").on(t.tenantId, t.projectId, t.position),
|
|
21698
|
+
unique("project_leads_project_user_uniq").on(t.projectId, t.userId),
|
|
21699
|
+
index("project_leads_user_idx").on(t.userId)
|
|
21700
|
+
]);
|
|
21701
|
+
|
|
21702
|
+
// ../../packages/schema/src/contracts/work-refs.ts
|
|
21703
|
+
var WORK_REF_PREFIX = "DO";
|
|
21704
|
+
var REF_RE = new RegExp(`^${WORK_REF_PREFIX}-(P)?([1-9]\\d{0,8})$`, "i");
|
|
21705
|
+
function parseWorkRef(raw) {
|
|
21706
|
+
const m = REF_RE.exec(raw.trim());
|
|
21707
|
+
if (!m)
|
|
21708
|
+
return null;
|
|
21709
|
+
return { kind: m[1] ? "project" : "task", number: Number(m[2]) };
|
|
21710
|
+
}
|
|
21711
|
+
|
|
21712
|
+
// ../../packages/schema/src/contracts/task-blocks.ts
|
|
21713
|
+
var taskIdOrRefSchema = string2().trim().refine((raw) => ulidSchema.safeParse(raw).success || parseWorkRef(raw)?.kind === "task", "a task's ULID or its ref, like DO-147");
|
|
21714
|
+
var addTaskBlockerInputSchema = object({ taskId: taskIdOrRefSchema }).strict();
|
|
21715
|
+
var taskBlockerSchema = object({
|
|
21716
|
+
id: ulidSchema,
|
|
21717
|
+
ref: string2().nullable(),
|
|
21718
|
+
title: string2(),
|
|
21719
|
+
status: taskStatusSchema,
|
|
21720
|
+
dueAt: exports_coerce.date().nullable()
|
|
21721
|
+
});
|
|
21722
|
+
|
|
21612
21723
|
// ../../packages/schema/src/contracts/task-source.ts
|
|
21613
21724
|
var taskSourceSchema = object({
|
|
21614
21725
|
kind: string2().trim().min(1).max(40),
|
|
@@ -21763,6 +21874,9 @@ var worktreeLinkListQuerySchema = object({
|
|
|
21763
21874
|
|
|
21764
21875
|
// ../../packages/schema/src/contracts/tasks.ts
|
|
21765
21876
|
var taskSchema = createSelectSchema(tasks, {
|
|
21877
|
+
priority: workPrioritySchema.default("none"),
|
|
21878
|
+
number: number2().int().nonnegative().default(0),
|
|
21879
|
+
deliverable: string2().nullable().default(null),
|
|
21766
21880
|
scheduledAt: exports_coerce.date().nullable(),
|
|
21767
21881
|
startAt: exports_coerce.date().nullable(),
|
|
21768
21882
|
dueAt: exports_coerce.date().nullable(),
|
|
@@ -21832,6 +21946,7 @@ var taskFilingSuggestionSchema = object({
|
|
|
21832
21946
|
});
|
|
21833
21947
|
var completedAtInputSchema = exports_coerce.date().refine((d) => d.getTime() <= Date.now() + 60000, "completedAt can't be in the future").nullish();
|
|
21834
21948
|
var taskNextStepSchema = string2().trim().min(1).max(500);
|
|
21949
|
+
var taskDeliverableSchema = string2().trim().min(1).max(500);
|
|
21835
21950
|
var taskViewSchema = taskSchema.omit({
|
|
21836
21951
|
ownerUserId: true,
|
|
21837
21952
|
ownerAgentId: true,
|
|
@@ -21847,6 +21962,7 @@ var taskViewSchema = taskSchema.omit({
|
|
|
21847
21962
|
movedFrom: true
|
|
21848
21963
|
}).extend({
|
|
21849
21964
|
title: string2(),
|
|
21965
|
+
ref: string2().nullable().default(null),
|
|
21850
21966
|
parentId: ulidSchema.nullable(),
|
|
21851
21967
|
sortOrder: number2().int().nonnegative().default(0),
|
|
21852
21968
|
createdAt: exports_coerce.date(),
|
|
@@ -21862,7 +21978,10 @@ var taskViewSchema = taskSchema.omit({
|
|
|
21862
21978
|
nextStep: string2().nullable().default(null),
|
|
21863
21979
|
completedBy: actorRefSchema.nullable().default(null),
|
|
21864
21980
|
worktreeLink: worktreeLinkSchema.nullable().default(null),
|
|
21865
|
-
filingSuggestion: taskFilingSuggestionSchema.nullable().default(null)
|
|
21981
|
+
filingSuggestion: taskFilingSuggestionSchema.nullable().default(null),
|
|
21982
|
+
blockedBy: array(taskBlockerSchema).default([]),
|
|
21983
|
+
blocks: number2().int().nonnegative().default(0),
|
|
21984
|
+
isBlocked: boolean2().default(false)
|
|
21866
21985
|
});
|
|
21867
21986
|
var taskProjectIdSchema = ulidSchema.nullish();
|
|
21868
21987
|
var taskAreaIdSchema = ulidSchema.nullish();
|
|
@@ -21878,9 +21997,11 @@ var createTaskInputSchema = createInsertSchema(tasks, {
|
|
|
21878
21997
|
areaId: taskAreaIdSchema,
|
|
21879
21998
|
placeId: ulidSchema.nullish(),
|
|
21880
21999
|
milestoneId: ulidSchema.nullish(),
|
|
21881
|
-
somedayAt: exports_coerce.date().nullish()
|
|
22000
|
+
somedayAt: exports_coerce.date().nullish(),
|
|
22001
|
+
deliverable: taskDeliverableSchema.nullish()
|
|
21882
22002
|
}).omit({
|
|
21883
22003
|
tenantId: true,
|
|
22004
|
+
number: true,
|
|
21884
22005
|
recurrenceRuleId: true,
|
|
21885
22006
|
startAt: true,
|
|
21886
22007
|
ownerUserId: true,
|
|
@@ -21928,10 +22049,12 @@ var updateTaskInputSchema = createUpdateSchema(tasks, {
|
|
|
21928
22049
|
areaId: taskAreaIdSchema,
|
|
21929
22050
|
placeId: ulidSchema.nullish(),
|
|
21930
22051
|
milestoneId: ulidSchema.nullish(),
|
|
21931
|
-
somedayAt: exports_coerce.date().nullish()
|
|
22052
|
+
somedayAt: exports_coerce.date().nullish(),
|
|
22053
|
+
deliverable: taskDeliverableSchema.nullish()
|
|
21932
22054
|
}).omit({
|
|
21933
22055
|
id: true,
|
|
21934
22056
|
tenantId: true,
|
|
22057
|
+
number: true,
|
|
21935
22058
|
recurrenceRuleId: true,
|
|
21936
22059
|
startAt: true,
|
|
21937
22060
|
ownerUserId: true,
|
|
@@ -21971,6 +22094,8 @@ var taskListFilterSchema = _enum2(["all", "unsorted", "starred"]);
|
|
|
21971
22094
|
|
|
21972
22095
|
// ../../packages/schema/src/contracts/projects.ts
|
|
21973
22096
|
var projectSchema = createSelectSchema(projects, {
|
|
22097
|
+
priority: workPrioritySchema.default("none"),
|
|
22098
|
+
number: number2().int().nonnegative().default(0),
|
|
21974
22099
|
icon: string2().nullable().default(null),
|
|
21975
22100
|
startAt: exports_coerce.date().nullable(),
|
|
21976
22101
|
dueAt: exports_coerce.date().nullable(),
|
|
@@ -21998,7 +22123,13 @@ var createProjectInputSchema = createInsertSchema(projects, {
|
|
|
21998
22123
|
dueAt: exports_coerce.date().nullish(),
|
|
21999
22124
|
areaId: ulidSchema.nullish(),
|
|
22000
22125
|
icon: projectIconSchema.nullish()
|
|
22001
|
-
}).omit({
|
|
22126
|
+
}).omit({
|
|
22127
|
+
tenantId: true,
|
|
22128
|
+
number: true,
|
|
22129
|
+
completedAt: true,
|
|
22130
|
+
finishProposedAt: true,
|
|
22131
|
+
finishNotYetAt: true
|
|
22132
|
+
}).extend({
|
|
22002
22133
|
title: string2().min(1),
|
|
22003
22134
|
parentId: ulidSchema.nullish(),
|
|
22004
22135
|
milestones: array(projectMilestoneInputSchema).optional(),
|
|
@@ -22010,15 +22141,39 @@ var updateProjectInputSchema = createUpdateSchema(projects, {
|
|
|
22010
22141
|
dueAt: exports_coerce.date().nullish(),
|
|
22011
22142
|
areaId: ulidSchema.nullish(),
|
|
22012
22143
|
icon: projectIconSchema.nullish()
|
|
22013
|
-
}).omit({ id: true, tenantId: true, completedAt: true, finishProposedAt: true }).extend({
|
|
22144
|
+
}).omit({ id: true, tenantId: true, number: true, completedAt: true, finishProposedAt: true }).extend({
|
|
22014
22145
|
title: string2().min(1).optional(),
|
|
22015
22146
|
finishNotYetAt: exports_coerce.date().nullish(),
|
|
22016
22147
|
parentId: ulidSchema.nullish(),
|
|
22017
22148
|
milestones: array(projectMilestoneInputSchema).optional(),
|
|
22018
|
-
notes: string2().nullish()
|
|
22149
|
+
notes: string2().nullish(),
|
|
22150
|
+
leadUserIds: array(ulidSchema).max(20).refine((ids) => new Set(ids).size === ids.length, "each lead once").optional()
|
|
22151
|
+
}).strict();
|
|
22152
|
+
var projectUpdateStatusSchema = _enum2(projectUpdateStatus.enumValues);
|
|
22153
|
+
var projectUpdateViewSchema = object({
|
|
22154
|
+
id: ulidSchema,
|
|
22155
|
+
projectId: ulidSchema,
|
|
22156
|
+
status: projectUpdateStatusSchema,
|
|
22157
|
+
body: string2(),
|
|
22158
|
+
authorUserId: string2().nullable(),
|
|
22159
|
+
authorAgentId: string2().nullable(),
|
|
22160
|
+
authorName: string2(),
|
|
22161
|
+
createdAt: exports_coerce.date()
|
|
22162
|
+
});
|
|
22163
|
+
var createProjectUpdateInputSchema = object({
|
|
22164
|
+
id: ulidSchema.optional(),
|
|
22165
|
+
status: projectUpdateStatusSchema,
|
|
22166
|
+
body: string2().trim().max(PROJECT_UPDATE_BODY_MAX).default("")
|
|
22019
22167
|
}).strict();
|
|
22168
|
+
var projectLatestUpdateSchema = object({
|
|
22169
|
+
id: ulidSchema,
|
|
22170
|
+
status: projectUpdateStatusSchema,
|
|
22171
|
+
createdAt: exports_coerce.date()
|
|
22172
|
+
});
|
|
22173
|
+
var projectLeadSchema = object({ userId: ulidSchema, name: string2() });
|
|
22020
22174
|
var projectViewSchema = projectSchema.extend({
|
|
22021
22175
|
title: string2(),
|
|
22176
|
+
ref: string2().nullable().default(null),
|
|
22022
22177
|
parentId: ulidSchema.nullable(),
|
|
22023
22178
|
createdAt: exports_coerce.date(),
|
|
22024
22179
|
updatedAt: exports_coerce.date(),
|
|
@@ -22029,7 +22184,9 @@ var projectViewSchema = projectSchema.extend({
|
|
|
22029
22184
|
taskCount: number2().int().min(0),
|
|
22030
22185
|
completedTaskCount: number2().int().min(0),
|
|
22031
22186
|
worktreeLink: worktreeLinkSchema.nullable().default(null),
|
|
22032
|
-
milestones: array(projectMilestoneSchema).default([])
|
|
22187
|
+
milestones: array(projectMilestoneSchema).default([]),
|
|
22188
|
+
leads: array(projectLeadSchema).default([]),
|
|
22189
|
+
latestUpdate: projectLatestUpdateSchema.nullable().default(null)
|
|
22033
22190
|
});
|
|
22034
22191
|
var projectDetailSchema = projectViewSchema.extend({
|
|
22035
22192
|
milestones: array(projectMilestoneSchema),
|
|
@@ -22205,10 +22362,18 @@ var routineRunSchema = createSelectSchema(routineRuns, {
|
|
|
22205
22362
|
completedAt: exports_coerce.date().nullable()
|
|
22206
22363
|
});
|
|
22207
22364
|
var routineRunStepSchema = createSelectSchema(routineRunSteps, {
|
|
22208
|
-
completedAt: exports_coerce.date().nullable()
|
|
22365
|
+
completedAt: exports_coerce.date().nullable(),
|
|
22366
|
+
taskId: string2().nullable().default(null),
|
|
22367
|
+
reason: string2().nullable().default(null)
|
|
22209
22368
|
});
|
|
22210
22369
|
var routineRunStepViewSchema = routineRunStepSchema.extend({
|
|
22211
|
-
habit: habitSummarySchema.nullable().default(null)
|
|
22370
|
+
habit: habitSummarySchema.nullable().default(null),
|
|
22371
|
+
task: object({
|
|
22372
|
+
id: string2(),
|
|
22373
|
+
title: string2(),
|
|
22374
|
+
status: string2(),
|
|
22375
|
+
dueAt: exports_coerce.date().nullable()
|
|
22376
|
+
}).nullable().default(null)
|
|
22212
22377
|
});
|
|
22213
22378
|
var routineRunViewSchema = routineRunSchema.extend({
|
|
22214
22379
|
routineTitle: string2(),
|
|
@@ -22282,6 +22447,44 @@ var routineRhythmResultSchema = object({
|
|
|
22282
22447
|
routines: array(routineRhythmSchema),
|
|
22283
22448
|
notices: array(routineNoticeSchema)
|
|
22284
22449
|
});
|
|
22450
|
+
var addRoutineTaskStepInputSchema = object({
|
|
22451
|
+
taskId: ulidSchema,
|
|
22452
|
+
reason: string2().min(1).max(280).optional()
|
|
22453
|
+
}).strict();
|
|
22454
|
+
var reorderRoutineStepsInputSchema = object({
|
|
22455
|
+
stepIds: array(ulidSchema).min(1).max(200).refine((ids) => new Set(ids).size === ids.length, "stepIds must not repeat")
|
|
22456
|
+
}).strict();
|
|
22457
|
+
var routineTodayStepKindSchema = _enum2(["step", "habit", "task"]);
|
|
22458
|
+
var routineTodayStepSchema = object({
|
|
22459
|
+
n: number2().int().positive(),
|
|
22460
|
+
title: string2(),
|
|
22461
|
+
kind: routineTodayStepKindSchema,
|
|
22462
|
+
meta: string2().nullable(),
|
|
22463
|
+
minutes: number2().int().nullable(),
|
|
22464
|
+
done: boolean2()
|
|
22465
|
+
});
|
|
22466
|
+
var routineTodayStateSchema = _enum2(["done", "running", "upcoming", "resting"]);
|
|
22467
|
+
var routineTodaySchema = object({
|
|
22468
|
+
id: string2(),
|
|
22469
|
+
title: string2(),
|
|
22470
|
+
icon: string2().nullable(),
|
|
22471
|
+
start: string2().nullable(),
|
|
22472
|
+
durationMinutes: number2().int().nonnegative(),
|
|
22473
|
+
state: routineTodayStateSchema,
|
|
22474
|
+
run: object({
|
|
22475
|
+
id: string2(),
|
|
22476
|
+
startedAt: exports_coerce.date(),
|
|
22477
|
+
completedAt: exports_coerce.date().nullable(),
|
|
22478
|
+
done: number2().int().nonnegative(),
|
|
22479
|
+
total: number2().int().nonnegative()
|
|
22480
|
+
}).nullable(),
|
|
22481
|
+
steps: array(routineTodayStepSchema),
|
|
22482
|
+
rhythm: array(routineDayStateSchema).length(14)
|
|
22483
|
+
});
|
|
22484
|
+
var routinesTodayResultSchema = object({
|
|
22485
|
+
today: ymdSchema,
|
|
22486
|
+
routines: array(routineTodaySchema)
|
|
22487
|
+
});
|
|
22285
22488
|
|
|
22286
22489
|
// ../../packages/schema/src/contracts/areas.ts
|
|
22287
22490
|
var areaPurposeSchema = string2().trim().max(140).transform((v) => v.length === 0 ? null : v);
|
|
@@ -22505,7 +22708,8 @@ var collectionTypeValues = [
|
|
|
22505
22708
|
"place",
|
|
22506
22709
|
"wine",
|
|
22507
22710
|
"wardrobe",
|
|
22508
|
-
"asset"
|
|
22711
|
+
"asset",
|
|
22712
|
+
"hobby"
|
|
22509
22713
|
];
|
|
22510
22714
|
var collectionTypeSchema = _enum2(collectionTypeValues);
|
|
22511
22715
|
var collectionViewValues = ["grid", "shelf", "map"];
|
|
@@ -22719,6 +22923,8 @@ var taskListQuerySchema = object({
|
|
|
22719
22923
|
areaId: ulidSchema.optional(),
|
|
22720
22924
|
projectId: ulidSchema.optional(),
|
|
22721
22925
|
status: csvList(taskStatusSchema).optional(),
|
|
22926
|
+
priority: csvList(workPrioritySchema).optional(),
|
|
22927
|
+
view: ulidSchema.optional(),
|
|
22722
22928
|
tag: tagListSchema.optional(),
|
|
22723
22929
|
updatedSince: instantQuerySchema.optional(),
|
|
22724
22930
|
dueBefore: instantQuerySchema.optional(),
|
|
@@ -24062,6 +24268,39 @@ var calendarOperations = defineOperations({
|
|
|
24062
24268
|
status: 200,
|
|
24063
24269
|
response: { description: "The event, after.", view: "Event" },
|
|
24064
24270
|
errors: { 400: true, 404: true }
|
|
24271
|
+
},
|
|
24272
|
+
status: {
|
|
24273
|
+
method: "get",
|
|
24274
|
+
path: "/calendar/status",
|
|
24275
|
+
scopes: ["calendar:read"],
|
|
24276
|
+
tag: "Calendar",
|
|
24277
|
+
summary: "Calendar connection status",
|
|
24278
|
+
description: "Each of the member's calendar connections: its `status` and `health` (`ok` \xB7 `retrying` \xB7 `reconnect` \xB7 `pending`), `lastError`, when do last wrote to its calendar (`lastPushAt`) and last pulled from it (`lastSyncAt`). `retrying` means a passing failure; the background sweep tries again. `reconnect` means the member has to reconnect in Settings. Needs a key that acts for a member.",
|
|
24279
|
+
status: 200,
|
|
24280
|
+
response: { description: "One entry per calendar connection.", list: true },
|
|
24281
|
+
errors: { 400: true }
|
|
24282
|
+
},
|
|
24283
|
+
push: {
|
|
24284
|
+
method: "post",
|
|
24285
|
+
path: "/calendar/push",
|
|
24286
|
+
scopes: ["calendar:write"],
|
|
24287
|
+
tag: "Calendar",
|
|
24288
|
+
summary: "Push to the calendar now",
|
|
24289
|
+
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.",
|
|
24290
|
+
status: 200,
|
|
24291
|
+
response: { description: "`{ pushed }`: one push result per connection." },
|
|
24292
|
+
errors: { 400: true }
|
|
24293
|
+
},
|
|
24294
|
+
refresh: {
|
|
24295
|
+
method: "post",
|
|
24296
|
+
path: "/calendar/refresh",
|
|
24297
|
+
scopes: ["calendar:write"],
|
|
24298
|
+
tag: "Calendar",
|
|
24299
|
+
summary: "Sync the calendar now",
|
|
24300
|
+
description: "Pull each of the member's calendar connections into do's mirror now (however recently it last synced), then push do's placements out. Returns `{ mirrored, pushed }`. Needs a key that acts for a member.",
|
|
24301
|
+
status: 200,
|
|
24302
|
+
response: { description: "What the pull and the push moved." },
|
|
24303
|
+
errors: { 400: true }
|
|
24065
24304
|
}
|
|
24066
24305
|
});
|
|
24067
24306
|
|
|
@@ -29069,6 +29308,32 @@ var guestListOverviewSchema = object({
|
|
|
29069
29308
|
invites: number2().int()
|
|
29070
29309
|
})
|
|
29071
29310
|
});
|
|
29311
|
+
var guestListGuestSchema = guestViewSchema.omit({ diet: true });
|
|
29312
|
+
var guestListHouseholdSchema = object({
|
|
29313
|
+
householdId: ulidSchema.nullable(),
|
|
29314
|
+
title: string2(),
|
|
29315
|
+
address: householdAddressSchema.nullable(),
|
|
29316
|
+
addressConfirmedAt: exports_coerce.date().nullable(),
|
|
29317
|
+
language: rsvpLanguageSchema,
|
|
29318
|
+
group: boolean2(),
|
|
29319
|
+
catererNotes: number2().int().min(0),
|
|
29320
|
+
guests: array(guestListGuestSchema)
|
|
29321
|
+
});
|
|
29322
|
+
var guestListSummarySchema = object({
|
|
29323
|
+
invited: number2().int(),
|
|
29324
|
+
households: number2().int(),
|
|
29325
|
+
coming: number2().int(),
|
|
29326
|
+
waiting: number2().int(),
|
|
29327
|
+
notComing: number2().int(),
|
|
29328
|
+
tables: number2().int(),
|
|
29329
|
+
notSeated: number2().int(),
|
|
29330
|
+
noAddress: number2().int()
|
|
29331
|
+
});
|
|
29332
|
+
var guestListHouseholdsViewSchema = object({
|
|
29333
|
+
guestList: guestListViewSchema,
|
|
29334
|
+
summary: guestListSummarySchema,
|
|
29335
|
+
households: array(guestListHouseholdSchema)
|
|
29336
|
+
});
|
|
29072
29337
|
var rsvpDigestQuerySchema = object({ since: exports_coerce.date().optional() }).strict();
|
|
29073
29338
|
var rsvpDigestSchema = object({
|
|
29074
29339
|
guestListId: string2(),
|
|
@@ -30700,6 +30965,21 @@ var housePlaceTileSchema = object({
|
|
|
30700
30965
|
gardenFeatureId: string2().nullable(),
|
|
30701
30966
|
thingCount: number2().int().min(0)
|
|
30702
30967
|
});
|
|
30968
|
+
var houseLowSchema = object({
|
|
30969
|
+
id: string2(),
|
|
30970
|
+
title: string2(),
|
|
30971
|
+
placeTitle: string2().nullable(),
|
|
30972
|
+
amountWords: string2(),
|
|
30973
|
+
state: _enum2(["low", "fine"])
|
|
30974
|
+
});
|
|
30975
|
+
var houseLoanRowSchema = object({
|
|
30976
|
+
itemId: string2(),
|
|
30977
|
+
title: string2(),
|
|
30978
|
+
direction: _enum2(["lent", "borrowed"]),
|
|
30979
|
+
who: string2(),
|
|
30980
|
+
since: day,
|
|
30981
|
+
dueBack: day.nullable()
|
|
30982
|
+
});
|
|
30703
30983
|
var houseOverviewSchema = object({
|
|
30704
30984
|
broken: array(houseBrokenSchema),
|
|
30705
30985
|
upkeepSoon: array(houseUpkeepSoonSchema),
|
|
@@ -30709,7 +30989,14 @@ var houseOverviewSchema = object({
|
|
|
30709
30989
|
toolCount: number2().int().min(0),
|
|
30710
30990
|
animalCount: number2().int().min(0),
|
|
30711
30991
|
toConfirm: number2().int().min(0).default(0),
|
|
30712
|
-
toConfirmTitles: array(string2()).max(3).default([])
|
|
30992
|
+
toConfirmTitles: array(string2()).max(3).default([]),
|
|
30993
|
+
low: array(houseLowSchema).max(5).default([]),
|
|
30994
|
+
loans: array(houseLoanRowSchema).max(5).default([]),
|
|
30995
|
+
lowCount: number2().int().min(0).default(0),
|
|
30996
|
+
lentCount: number2().int().min(0).default(0),
|
|
30997
|
+
borrowedCount: number2().int().min(0).default(0),
|
|
30998
|
+
upkeepThisMonth: number2().int().min(0).default(0),
|
|
30999
|
+
brokenWaitingCount: number2().int().min(0).default(0)
|
|
30713
31000
|
});
|
|
30714
31001
|
var upkeepScheduleSchema = object({
|
|
30715
31002
|
every: number2().int().min(1).max(365),
|
|
@@ -31033,6 +31320,166 @@ var householdOperations = defineOperations({
|
|
|
31033
31320
|
})
|
|
31034
31321
|
});
|
|
31035
31322
|
|
|
31323
|
+
// ../../packages/schema/src/contracts/inbox.ts
|
|
31324
|
+
var INBOX_KINDS = ["capture", "proposal", "answer"];
|
|
31325
|
+
var inboxKindSchema = _enum2(INBOX_KINDS);
|
|
31326
|
+
var inboxFilterSchema = _enum2(["all", ...INBOX_KINDS]);
|
|
31327
|
+
var inboxQuerySchema = object({
|
|
31328
|
+
kind: inboxFilterSchema.default("all")
|
|
31329
|
+
});
|
|
31330
|
+
var inboxIconSchema = _enum2(["mic", "edit", "camera", "echo", "agents", "bell"]);
|
|
31331
|
+
var inboxHueSchema = _enum2([
|
|
31332
|
+
"sage",
|
|
31333
|
+
"sky",
|
|
31334
|
+
"peach",
|
|
31335
|
+
"plum",
|
|
31336
|
+
"sun",
|
|
31337
|
+
"sea",
|
|
31338
|
+
"clay",
|
|
31339
|
+
"mist"
|
|
31340
|
+
]);
|
|
31341
|
+
var inboxActionSchema = object({
|
|
31342
|
+
id: string2(),
|
|
31343
|
+
label: string2(),
|
|
31344
|
+
key: string2().length(1),
|
|
31345
|
+
primary: boolean2(),
|
|
31346
|
+
route: string2().nullable().default(null)
|
|
31347
|
+
});
|
|
31348
|
+
var inboxItemSchema = object({
|
|
31349
|
+
id: ulidSchema,
|
|
31350
|
+
kind: inboxKindSchema,
|
|
31351
|
+
title: string2(),
|
|
31352
|
+
source: string2(),
|
|
31353
|
+
meta: string2(),
|
|
31354
|
+
icon: inboxIconSchema,
|
|
31355
|
+
hue: inboxHueSchema,
|
|
31356
|
+
createdAt: exports_coerce.date(),
|
|
31357
|
+
actions: array(inboxActionSchema)
|
|
31358
|
+
});
|
|
31359
|
+
var inboxCountsSchema = object({
|
|
31360
|
+
all: number2().int().nonnegative(),
|
|
31361
|
+
capture: number2().int().nonnegative(),
|
|
31362
|
+
proposal: number2().int().nonnegative(),
|
|
31363
|
+
answer: number2().int().nonnegative()
|
|
31364
|
+
});
|
|
31365
|
+
var inboxResponseSchema = object({
|
|
31366
|
+
counts: inboxCountsSchema,
|
|
31367
|
+
items: array(inboxItemSchema)
|
|
31368
|
+
});
|
|
31369
|
+
var INBOX_SORT_AS = ["task", "note", "habit", "log"];
|
|
31370
|
+
var inboxSortAsSchema = _enum2(INBOX_SORT_AS);
|
|
31371
|
+
var inboxFactSchema = object({ key: string2(), value: string2() });
|
|
31372
|
+
var inboxSortingSchema = object({
|
|
31373
|
+
id: ulidSchema,
|
|
31374
|
+
original: object({
|
|
31375
|
+
how: string2(),
|
|
31376
|
+
at: exports_coerce.date(),
|
|
31377
|
+
text: string2()
|
|
31378
|
+
}),
|
|
31379
|
+
becomes: inboxSortAsSchema,
|
|
31380
|
+
facts: array(inboxFactSchema),
|
|
31381
|
+
why: string2().nullable()
|
|
31382
|
+
});
|
|
31383
|
+
var inboxTaskFieldsSchema = updateTaskInputSchema.pick({
|
|
31384
|
+
title: true,
|
|
31385
|
+
notes: true,
|
|
31386
|
+
areaId: true,
|
|
31387
|
+
projectId: true,
|
|
31388
|
+
scheduledAt: true,
|
|
31389
|
+
allDay: true,
|
|
31390
|
+
dueAt: true,
|
|
31391
|
+
somedayAt: true,
|
|
31392
|
+
tags: true,
|
|
31393
|
+
owner: true
|
|
31394
|
+
});
|
|
31395
|
+
var inboxNoteFieldsSchema = createNoteInputSchema.pick({ areaId: true, body: true, tags: true }).extend({ title: string2().min(1).optional() }).strict();
|
|
31396
|
+
var inboxHabitFieldsSchema = createHabitInputSchema.pick({ areaId: true, period: true, frequencyCount: true, timeOfDay: true }).partial().extend({ title: string2().min(1).optional() }).strict();
|
|
31397
|
+
var inboxSortInputSchema = discriminatedUnion("as", [
|
|
31398
|
+
object({ as: literal("task"), fields: inboxTaskFieldsSchema.optional() }).strict(),
|
|
31399
|
+
object({ as: literal("note"), fields: inboxNoteFieldsSchema.optional() }).strict(),
|
|
31400
|
+
object({
|
|
31401
|
+
as: literal("habit"),
|
|
31402
|
+
fields: inboxHabitFieldsSchema.optional()
|
|
31403
|
+
}).strict(),
|
|
31404
|
+
object({
|
|
31405
|
+
as: literal("log"),
|
|
31406
|
+
fields: record(string2(), unknown()).optional()
|
|
31407
|
+
}).strict()
|
|
31408
|
+
]);
|
|
31409
|
+
var inboxSortResultSchema = object({
|
|
31410
|
+
id: ulidSchema,
|
|
31411
|
+
as: inboxSortAsSchema,
|
|
31412
|
+
homeId: ulidSchema
|
|
31413
|
+
});
|
|
31414
|
+
var inboxLetGoResultSchema = object({
|
|
31415
|
+
id: ulidSchema,
|
|
31416
|
+
status: literal("cancelled")
|
|
31417
|
+
});
|
|
31418
|
+
|
|
31419
|
+
// ../../packages/schema/src/operations/inbox.ts
|
|
31420
|
+
var ID = "The capture's id (an Unsorted task).";
|
|
31421
|
+
var inboxOperations = defineOperations({
|
|
31422
|
+
list: {
|
|
31423
|
+
method: "get",
|
|
31424
|
+
path: "/inbox",
|
|
31425
|
+
scopes: ["tasks:read"],
|
|
31426
|
+
tag: "Tasks",
|
|
31427
|
+
summary: "The Inbox",
|
|
31428
|
+
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.",
|
|
31429
|
+
query: [
|
|
31430
|
+
{
|
|
31431
|
+
name: "kind",
|
|
31432
|
+
description: "`all` (default), `capture`, `proposal` or `answer`.",
|
|
31433
|
+
enum: ["all", "capture", "proposal", "answer"]
|
|
31434
|
+
}
|
|
31435
|
+
],
|
|
31436
|
+
querySchema: inboxQuerySchema,
|
|
31437
|
+
status: 200,
|
|
31438
|
+
response: { description: "The Inbox.", view: "InboxResponse" },
|
|
31439
|
+
errors: { 400: true }
|
|
31440
|
+
},
|
|
31441
|
+
sorting: {
|
|
31442
|
+
method: "get",
|
|
31443
|
+
path: "/inbox/{id}/sorting",
|
|
31444
|
+
scopes: ["tasks:read"],
|
|
31445
|
+
tag: "Tasks",
|
|
31446
|
+
summary: "Sort a capture: the suggestion",
|
|
31447
|
+
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.",
|
|
31448
|
+
pathParams: { id: ID },
|
|
31449
|
+
status: 200,
|
|
31450
|
+
response: { description: "The sorting suggestion.", view: "InboxSorting" },
|
|
31451
|
+
errors: { 404: true }
|
|
31452
|
+
},
|
|
31453
|
+
sort: {
|
|
31454
|
+
method: "post",
|
|
31455
|
+
path: "/inbox/{id}/sort",
|
|
31456
|
+
scopes: ["tasks:write"],
|
|
31457
|
+
tag: "Tasks",
|
|
31458
|
+
summary: "Sort a capture",
|
|
31459
|
+
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.",
|
|
31460
|
+
pathParams: { id: ID },
|
|
31461
|
+
body: inboxSortInputSchema,
|
|
31462
|
+
status: 201,
|
|
31463
|
+
response: { description: "Where it went.", view: "InboxSortResult" },
|
|
31464
|
+
errors: { 400: true, 403: true, 404: true }
|
|
31465
|
+
},
|
|
31466
|
+
letGo: {
|
|
31467
|
+
method: "post",
|
|
31468
|
+
path: "/inbox/{id}/let-go",
|
|
31469
|
+
scopes: ["tasks:write"],
|
|
31470
|
+
tag: "Tasks",
|
|
31471
|
+
summary: "Let a capture go",
|
|
31472
|
+
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.',
|
|
31473
|
+
pathParams: { id: ID },
|
|
31474
|
+
status: 201,
|
|
31475
|
+
response: {
|
|
31476
|
+
description: "The capture, cancelled.",
|
|
31477
|
+
view: "InboxLetGoResult"
|
|
31478
|
+
},
|
|
31479
|
+
errors: { 404: true }
|
|
31480
|
+
}
|
|
31481
|
+
});
|
|
31482
|
+
|
|
31036
31483
|
// ../../packages/schema/src/db/incidents.ts
|
|
31037
31484
|
var incidentKind = pgEnum("incident_kind", [
|
|
31038
31485
|
"water",
|
|
@@ -31529,6 +31976,13 @@ var journalLinkSchema = object({
|
|
|
31529
31976
|
title: string2(),
|
|
31530
31977
|
type: string2()
|
|
31531
31978
|
});
|
|
31979
|
+
var JOURNAL_NOTES_WRITTEN_MAX = 5;
|
|
31980
|
+
var journalNoteWrittenSchema = object({
|
|
31981
|
+
id: string2(),
|
|
31982
|
+
title: string2(),
|
|
31983
|
+
tags: array(string2()),
|
|
31984
|
+
updatedAt: exports_coerce.date()
|
|
31985
|
+
});
|
|
31532
31986
|
var journalSnapshotSchema = object({
|
|
31533
31987
|
date: journalDateSchema,
|
|
31534
31988
|
timezone: string2().min(1),
|
|
@@ -31538,7 +31992,9 @@ var journalSnapshotSchema = object({
|
|
|
31538
31992
|
habits: array(journalHabitSchema),
|
|
31539
31993
|
events: array(journalEventSchema),
|
|
31540
31994
|
links: array(journalLinkSchema),
|
|
31541
|
-
files: array(fileViewSchema)
|
|
31995
|
+
files: array(fileViewSchema),
|
|
31996
|
+
tasksLeft: number2().int().nonnegative().default(0),
|
|
31997
|
+
notesWritten: array(journalNoteWrittenSchema).max(JOURNAL_NOTES_WRITTEN_MAX).default([])
|
|
31542
31998
|
});
|
|
31543
31999
|
var JOURNAL_RANGE_MAX_DAYS = 366;
|
|
31544
32000
|
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"] });
|
|
@@ -31556,7 +32012,8 @@ var journalDayListItemSchema = object({
|
|
|
31556
32012
|
links: array(journalLinkSchema).max(3),
|
|
31557
32013
|
source: journalDaySourceSchema.nullable().default(null),
|
|
31558
32014
|
landed: number2().int().nonnegative().default(0),
|
|
31559
|
-
habitsDone: number2().int().nonnegative().default(0)
|
|
32015
|
+
habitsDone: number2().int().nonnegative().default(0),
|
|
32016
|
+
words: number2().int().nonnegative().default(0)
|
|
31560
32017
|
});
|
|
31561
32018
|
var journalDayListSchema = object({
|
|
31562
32019
|
from: journalDateSchema,
|
|
@@ -32819,6 +33276,145 @@ var krakenLinkOperations = defineOperations({
|
|
|
32819
33276
|
}
|
|
32820
33277
|
});
|
|
32821
33278
|
|
|
33279
|
+
// ../../packages/schema/src/db/log-kinds.ts
|
|
33280
|
+
var LOG_DESTINATIONS = ["habits", "animals", "health", "journal"];
|
|
33281
|
+
var logKinds = pgTable("log_kinds", {
|
|
33282
|
+
id: text("id").primaryKey(),
|
|
33283
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
33284
|
+
word: text("word").notNull(),
|
|
33285
|
+
destination: text("destination", { enum: LOG_DESTINATIONS }).notNull(),
|
|
33286
|
+
likeKind: text("like_kind"),
|
|
33287
|
+
targetId: text("target_id"),
|
|
33288
|
+
createdBy: text("created_by").references(() => users.id, { onDelete: "set null" }),
|
|
33289
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
33290
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
33291
|
+
}, (t) => [unique("log_kinds_tenant_word_uniq").on(t.tenantId, t.word)]);
|
|
33292
|
+
var logEntries = pgTable("log_entries", {
|
|
33293
|
+
id: text("id").primaryKey(),
|
|
33294
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
33295
|
+
userId: text("user_id").references(() => users.id, { onDelete: "set null" }),
|
|
33296
|
+
kind: text("kind").notNull(),
|
|
33297
|
+
text: text("text").notNull(),
|
|
33298
|
+
amount: doublePrecision("amount"),
|
|
33299
|
+
unit: text("unit"),
|
|
33300
|
+
destination: text("destination", { enum: LOG_DESTINATIONS }).notNull(),
|
|
33301
|
+
targetId: text("target_id"),
|
|
33302
|
+
refId: text("ref_id"),
|
|
33303
|
+
what: text("what").notNull(),
|
|
33304
|
+
whereLabel: text("where_label").notNull(),
|
|
33305
|
+
occurredAt: timestamp("occurred_at", { withTimezone: true }).notNull(),
|
|
33306
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
|
|
33307
|
+
}, (t) => [index("log_entries_tenant_occurred_idx").on(t.tenantId, t.occurredAt)]);
|
|
33308
|
+
|
|
33309
|
+
// ../../packages/schema/src/contracts/log-entry.ts
|
|
33310
|
+
var logDestinationSchema = _enum2(LOG_DESTINATIONS);
|
|
33311
|
+
var logWordSchema = string2().trim().toLowerCase().min(2).max(40).regex(/^\p{L}[\p{L}\p{N}'-]*$/u, "one word");
|
|
33312
|
+
var lineSchema = string2().trim().min(1).max(500);
|
|
33313
|
+
var logPreviewInputSchema = object({ text: lineSchema }).strict();
|
|
33314
|
+
var logWriteInputSchema = object({
|
|
33315
|
+
text: lineSchema,
|
|
33316
|
+
kind: string2().trim().toLowerCase().min(1).max(40).optional(),
|
|
33317
|
+
destination: logDestinationSchema.optional()
|
|
33318
|
+
}).strict();
|
|
33319
|
+
var logDayQuerySchema = object({ day: exports_iso.date().optional() });
|
|
33320
|
+
var logPreviewSchema = object({
|
|
33321
|
+
kind: string2().nullable(),
|
|
33322
|
+
word: string2().nullable(),
|
|
33323
|
+
amount: number2().nullable(),
|
|
33324
|
+
unit: string2().nullable(),
|
|
33325
|
+
label: string2(),
|
|
33326
|
+
destination: logDestinationSchema.nullable(),
|
|
33327
|
+
goesTo: string2().nullable(),
|
|
33328
|
+
effect: string2().nullable(),
|
|
33329
|
+
icon: string2(),
|
|
33330
|
+
needsKind: boolean2()
|
|
33331
|
+
});
|
|
33332
|
+
var logEntryViewSchema = object({
|
|
33333
|
+
id: string2(),
|
|
33334
|
+
at: string2(),
|
|
33335
|
+
kind: string2(),
|
|
33336
|
+
what: string2(),
|
|
33337
|
+
where: string2(),
|
|
33338
|
+
destination: logDestinationSchema,
|
|
33339
|
+
text: string2(),
|
|
33340
|
+
amount: number2().nullable(),
|
|
33341
|
+
occurredAt: exports_coerce.date()
|
|
33342
|
+
});
|
|
33343
|
+
var logWriteResultSchema = object({
|
|
33344
|
+
entry: logEntryViewSchema,
|
|
33345
|
+
preview: logPreviewSchema,
|
|
33346
|
+
remembered: string2().nullable()
|
|
33347
|
+
});
|
|
33348
|
+
var logKindViewSchema = object({
|
|
33349
|
+
key: string2(),
|
|
33350
|
+
label: string2(),
|
|
33351
|
+
words: array(string2()),
|
|
33352
|
+
destination: logDestinationSchema,
|
|
33353
|
+
goesTo: string2(),
|
|
33354
|
+
icon: string2(),
|
|
33355
|
+
builtIn: boolean2(),
|
|
33356
|
+
likeKind: string2().nullable()
|
|
33357
|
+
});
|
|
33358
|
+
|
|
33359
|
+
// ../../packages/schema/src/operations/log.ts
|
|
33360
|
+
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.";
|
|
33361
|
+
var logOperations = defineOperations({
|
|
33362
|
+
preview: {
|
|
33363
|
+
method: "post",
|
|
33364
|
+
path: "/log/preview",
|
|
33365
|
+
scopes: ["habits:read"],
|
|
33366
|
+
tag: "Log",
|
|
33367
|
+
summary: "Preview a logged line",
|
|
33368
|
+
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.',
|
|
33369
|
+
body: logPreviewInputSchema,
|
|
33370
|
+
status: 200,
|
|
33371
|
+
response: { description: "What the line would do." },
|
|
33372
|
+
errors: { 400: true },
|
|
33373
|
+
operationId: "log_preview"
|
|
33374
|
+
},
|
|
33375
|
+
write: {
|
|
33376
|
+
method: "post",
|
|
33377
|
+
path: "/log",
|
|
33378
|
+
scopes: ["habits:write"],
|
|
33379
|
+
tag: "Log",
|
|
33380
|
+
summary: "Log something",
|
|
33381
|
+
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}`,
|
|
33382
|
+
body: logWriteInputSchema,
|
|
33383
|
+
status: 201,
|
|
33384
|
+
response: { description: "The entry, what it did, and the word remembered." },
|
|
33385
|
+
errors: {
|
|
33386
|
+
400: "The line is blank, its kind is unknown and none was given, or it needs an amount.",
|
|
33387
|
+
403: true
|
|
33388
|
+
},
|
|
33389
|
+
operationId: "log_write"
|
|
33390
|
+
},
|
|
33391
|
+
list: {
|
|
33392
|
+
method: "get",
|
|
33393
|
+
path: "/log",
|
|
33394
|
+
scopes: ["habits:read"],
|
|
33395
|
+
tag: "Log",
|
|
33396
|
+
summary: "List what was logged",
|
|
33397
|
+
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`.',
|
|
33398
|
+
query: [{ name: "day", description: "The day, YYYY-MM-DD; today by default.", format: "date" }],
|
|
33399
|
+
querySchema: logDayQuerySchema,
|
|
33400
|
+
status: 200,
|
|
33401
|
+
response: { description: "The day's logged lines.", list: true },
|
|
33402
|
+
errors: { 400: true },
|
|
33403
|
+
operationId: "log_list"
|
|
33404
|
+
},
|
|
33405
|
+
kinds: {
|
|
33406
|
+
method: "get",
|
|
33407
|
+
path: "/log/kinds",
|
|
33408
|
+
scopes: ["habits:read"],
|
|
33409
|
+
tag: "Log",
|
|
33410
|
+
summary: "List the kinds you log",
|
|
33411
|
+
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`).",
|
|
33412
|
+
status: 200,
|
|
33413
|
+
response: { description: "The kinds.", list: true },
|
|
33414
|
+
operationId: "log_kinds"
|
|
33415
|
+
}
|
|
33416
|
+
});
|
|
33417
|
+
|
|
32822
33418
|
// ../../packages/schema/src/db/mail.ts
|
|
32823
33419
|
var mailCampaignStatus = pgEnum("mail_campaign_status", [
|
|
32824
33420
|
"draft",
|
|
@@ -32918,11 +33514,11 @@ var mailLookShape = {
|
|
|
32918
33514
|
couple: string2().trim().min(1).max(120).optional(),
|
|
32919
33515
|
imagesUrl: url({ protocol: /^https$/ }).max(500).optional()
|
|
32920
33516
|
};
|
|
32921
|
-
var
|
|
33517
|
+
var lineSchema2 = string2().trim().min(1).max(2000);
|
|
32922
33518
|
var mailMessageCopySchema = object({
|
|
32923
33519
|
subject: string2().trim().min(1).max(200),
|
|
32924
33520
|
heading: string2().trim().min(1).max(200),
|
|
32925
|
-
paragraphs: array(
|
|
33521
|
+
paragraphs: array(lineSchema2).max(20).default([]),
|
|
32926
33522
|
button: object({ label: string2().trim().min(1).max(80), url: url() }).strict().nullish()
|
|
32927
33523
|
}).strict();
|
|
32928
33524
|
var mailMessageDataSchema = object({
|
|
@@ -32942,7 +33538,7 @@ var mailDaySchema = object({
|
|
|
32942
33538
|
var mailSaveTheDateCopySchema = object({
|
|
32943
33539
|
subject: string2().trim().min(1).max(200),
|
|
32944
33540
|
heading: string2().trim().min(1).max(200),
|
|
32945
|
-
paragraphs: array(
|
|
33541
|
+
paragraphs: array(lineSchema2).max(20).default([]),
|
|
32946
33542
|
button: string2().trim().min(1).max(80)
|
|
32947
33543
|
}).strict();
|
|
32948
33544
|
var mailSaveTheDateDataSchema = object({
|
|
@@ -36155,6 +36751,67 @@ var progressDayDetailSchema = object({
|
|
|
36155
36751
|
slipped: array(progressSlippedItemSchema)
|
|
36156
36752
|
});
|
|
36157
36753
|
|
|
36754
|
+
// ../../packages/schema/src/contracts/progress-review.ts
|
|
36755
|
+
var REVIEW_SPANS = ["week", "month"];
|
|
36756
|
+
var reviewSpanSchema = _enum2(REVIEW_SPANS);
|
|
36757
|
+
var reviewSummaryQuerySchema = object({
|
|
36758
|
+
span: reviewSpanSchema.default("week"),
|
|
36759
|
+
date: progressDateSchema.optional()
|
|
36760
|
+
});
|
|
36761
|
+
var countSchema2 = number2().int().nonnegative();
|
|
36762
|
+
var REVIEW_MARK_STATES = ["done", "missed", "open", "later", "not_due"];
|
|
36763
|
+
var reviewMarkStateSchema = _enum2(REVIEW_MARK_STATES);
|
|
36764
|
+
var reviewMarkSchema = object({
|
|
36765
|
+
date: progressDateSchema,
|
|
36766
|
+
state: reviewMarkStateSchema
|
|
36767
|
+
});
|
|
36768
|
+
var reviewNumbersSchema = object({
|
|
36769
|
+
tasksDone: countSchema2,
|
|
36770
|
+
tasksDoneDelta: number2().int(),
|
|
36771
|
+
habitTicks: countSchema2,
|
|
36772
|
+
habitDue: countSchema2,
|
|
36773
|
+
projectsMoved: countSchema2,
|
|
36774
|
+
challengesRunning: countSchema2
|
|
36775
|
+
});
|
|
36776
|
+
var reviewSeriesEntrySchema = object({
|
|
36777
|
+
key: string2().min(1),
|
|
36778
|
+
label: string2().min(1),
|
|
36779
|
+
tasksDone: countSchema2,
|
|
36780
|
+
habitTicks: countSchema2,
|
|
36781
|
+
current: boolean2()
|
|
36782
|
+
});
|
|
36783
|
+
var reviewStreakSchema = object({
|
|
36784
|
+
habitId: string2().min(1),
|
|
36785
|
+
title: string2(),
|
|
36786
|
+
scheduleLabel: string2().min(1),
|
|
36787
|
+
current: countSchema2,
|
|
36788
|
+
best: countSchema2,
|
|
36789
|
+
unitLabel: string2().min(1),
|
|
36790
|
+
marks: array(reviewMarkSchema)
|
|
36791
|
+
});
|
|
36792
|
+
var reviewProjectSchema = object({
|
|
36793
|
+
projectId: string2().min(1),
|
|
36794
|
+
title: string2(),
|
|
36795
|
+
done: countSchema2,
|
|
36796
|
+
total: countSchema2,
|
|
36797
|
+
targetDate: progressDateSchema.nullable()
|
|
36798
|
+
});
|
|
36799
|
+
var reviewSummarySchema = object({
|
|
36800
|
+
span: reviewSpanSchema,
|
|
36801
|
+
label: string2().min(1),
|
|
36802
|
+
from: progressDateSchema,
|
|
36803
|
+
to: progressDateSchema,
|
|
36804
|
+
rangeLabel: string2().min(1),
|
|
36805
|
+
timezone: string2().min(1),
|
|
36806
|
+
numbers: reviewNumbersSchema,
|
|
36807
|
+
series: array(reviewSeriesEntrySchema).length(8),
|
|
36808
|
+
streaks: array(reviewStreakSchema),
|
|
36809
|
+
projects: array(reviewProjectSchema)
|
|
36810
|
+
}).refine((s) => s.series.at(-1)?.current === true, {
|
|
36811
|
+
message: "the last series entry is the asked period",
|
|
36812
|
+
path: ["series"]
|
|
36813
|
+
}).refine((s) => s.from <= s.to, { message: "from is on or before to", path: ["from"] });
|
|
36814
|
+
|
|
36158
36815
|
// ../../packages/schema/src/operations/progress.ts
|
|
36159
36816
|
var NO_MEMBER3 = "The key acts for no member.";
|
|
36160
36817
|
var question = {
|
|
@@ -36196,6 +36853,33 @@ var progressOperations = defineOperations({
|
|
|
36196
36853
|
errors: { 400: true },
|
|
36197
36854
|
operationId: "get_progress_day"
|
|
36198
36855
|
},
|
|
36856
|
+
review: {
|
|
36857
|
+
method: "get",
|
|
36858
|
+
path: "/progress/review",
|
|
36859
|
+
scopes: ["tasks:read", "habits:read"],
|
|
36860
|
+
tag: "Reads",
|
|
36861
|
+
summary: "Review summary",
|
|
36862
|
+
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.",
|
|
36863
|
+
query: [
|
|
36864
|
+
{
|
|
36865
|
+
name: "span",
|
|
36866
|
+
description: "`week` (default) or `month`.",
|
|
36867
|
+
type: "string",
|
|
36868
|
+
enum: [...REVIEW_SPANS]
|
|
36869
|
+
},
|
|
36870
|
+
{
|
|
36871
|
+
name: "date",
|
|
36872
|
+
description: "A day (`YYYY-MM-DD`) in the period; default today.",
|
|
36873
|
+
type: "string",
|
|
36874
|
+
format: "date"
|
|
36875
|
+
}
|
|
36876
|
+
],
|
|
36877
|
+
querySchema: reviewSummaryQuerySchema,
|
|
36878
|
+
status: 200,
|
|
36879
|
+
response: { description: "The Review summary (`ReviewSummary`)." },
|
|
36880
|
+
errors: { 400: true },
|
|
36881
|
+
operationId: "get_progress_review"
|
|
36882
|
+
},
|
|
36199
36883
|
habits: {
|
|
36200
36884
|
method: "get",
|
|
36201
36885
|
path: "/progress/habits",
|
|
@@ -36331,6 +37015,46 @@ var projectOperations = defineOperations({
|
|
|
36331
37015
|
response: { description: "Detached." },
|
|
36332
37016
|
errors: { 404: true },
|
|
36333
37017
|
webhook: "project.task.detached"
|
|
37018
|
+
},
|
|
37019
|
+
listUpdates: {
|
|
37020
|
+
method: "get",
|
|
37021
|
+
path: "/projects/{id}/updates",
|
|
37022
|
+
pathParams: { id: "The project's ULID or its ref (`DO-P7`)." },
|
|
37023
|
+
scopes: ["projects:read"],
|
|
37024
|
+
tag: "Projects",
|
|
37025
|
+
summary: "List a project's updates",
|
|
37026
|
+
description: "The project's updates, newest first: each a status, a note, its author and date.",
|
|
37027
|
+
status: 200,
|
|
37028
|
+
response: { description: "The project's updates, newest first." },
|
|
37029
|
+
errors: { 404: true }
|
|
37030
|
+
},
|
|
37031
|
+
createUpdate: {
|
|
37032
|
+
method: "post",
|
|
37033
|
+
path: "/projects/{id}/updates",
|
|
37034
|
+
pathParams: { id: "The project's ULID or its ref (`DO-P7`)." },
|
|
37035
|
+
scopes: ["projects:write"],
|
|
37036
|
+
tag: "Projects",
|
|
37037
|
+
summary: "Post a project update",
|
|
37038
|
+
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.",
|
|
37039
|
+
body: createProjectUpdateInputSchema,
|
|
37040
|
+
status: 201,
|
|
37041
|
+
response: { description: "The posted update." },
|
|
37042
|
+
errors: { 400: true, 403: true, 404: true }
|
|
37043
|
+
},
|
|
37044
|
+
removeUpdate: {
|
|
37045
|
+
method: "delete",
|
|
37046
|
+
path: "/projects/{id}/updates/{updateId}",
|
|
37047
|
+
pathParams: {
|
|
37048
|
+
id: "The project's ULID or its ref (`DO-P7`).",
|
|
37049
|
+
updateId: "The update's ULID."
|
|
37050
|
+
},
|
|
37051
|
+
scopes: ["projects:write"],
|
|
37052
|
+
tag: "Projects",
|
|
37053
|
+
summary: "Delete a project update",
|
|
37054
|
+
description: "Delete an update; only its author (the member or the Agent) may.",
|
|
37055
|
+
status: 204,
|
|
37056
|
+
response: { description: "Deleted." },
|
|
37057
|
+
errors: { 403: true, 404: true }
|
|
36334
37058
|
}
|
|
36335
37059
|
});
|
|
36336
37060
|
|
|
@@ -36399,12 +37123,47 @@ var landedByActorSchema = object({
|
|
|
36399
37123
|
actor: actorRefSchema.nullable(),
|
|
36400
37124
|
count: number2().int().nonnegative()
|
|
36401
37125
|
});
|
|
37126
|
+
var landedQuerySchema = readWindowQuerySchema.extend({
|
|
37127
|
+
tz: string2().trim().min(1).max(64).optional()
|
|
37128
|
+
});
|
|
37129
|
+
var landedSectionSchema = _enum2(["work", "habits", "agents", "home", "food", "journal"]);
|
|
37130
|
+
var landedActorSchema = object({
|
|
37131
|
+
kind: _enum2(["you", "member", "echo", "agent"]),
|
|
37132
|
+
id: string2().nullable(),
|
|
37133
|
+
name: string2().nullable(),
|
|
37134
|
+
machine: string2().nullable().optional()
|
|
37135
|
+
});
|
|
37136
|
+
var landedItemSchema = object({
|
|
37137
|
+
at: exports_coerce.date(),
|
|
37138
|
+
title: string2(),
|
|
37139
|
+
where: string2(),
|
|
37140
|
+
section: landedSectionSchema,
|
|
37141
|
+
actor: landedActorSchema,
|
|
37142
|
+
ref: object({
|
|
37143
|
+
type: _enum2(["task", "habit_entry", "document", "shopping_item"]),
|
|
37144
|
+
id: string2()
|
|
37145
|
+
})
|
|
37146
|
+
});
|
|
37147
|
+
var landedDaySchema = object({
|
|
37148
|
+
date: string2().regex(/^\d{4}-\d{2}-\d{2}$/),
|
|
37149
|
+
you: number2().int().nonnegative(),
|
|
37150
|
+
agents: number2().int().nonnegative()
|
|
37151
|
+
});
|
|
36402
37152
|
var landedResponseSchema = object({
|
|
36403
37153
|
from: exports_coerce.date(),
|
|
36404
37154
|
to: exports_coerce.date(),
|
|
36405
37155
|
total: number2().int().nonnegative(),
|
|
36406
37156
|
byActor: array(landedByActorSchema),
|
|
36407
|
-
tasks: array(taskViewSchema)
|
|
37157
|
+
tasks: array(taskViewSchema),
|
|
37158
|
+
itemsTotal: number2().int().nonnegative().default(0),
|
|
37159
|
+
today: number2().int().nonnegative().default(0),
|
|
37160
|
+
previousWeekTotal: number2().int().nonnegative().default(0),
|
|
37161
|
+
byDay: array(landedDaySchema).default([]),
|
|
37162
|
+
bySection: array(object({
|
|
37163
|
+
section: landedSectionSchema,
|
|
37164
|
+
count: number2().int().nonnegative()
|
|
37165
|
+
})).default([]),
|
|
37166
|
+
items: array(landedItemSchema).default([])
|
|
36408
37167
|
});
|
|
36409
37168
|
var searchNodeTypeSchema = _enum2([
|
|
36410
37169
|
"task",
|
|
@@ -36470,9 +37229,15 @@ var readOperations = defineOperations({
|
|
|
36470
37229
|
scopes: ["tasks:read"],
|
|
36471
37230
|
tag: "Reads",
|
|
36472
37231
|
summary: "What landed",
|
|
36473
|
-
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.",
|
|
36474
|
-
query:
|
|
36475
|
-
|
|
37232
|
+
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`).",
|
|
37233
|
+
query: [
|
|
37234
|
+
...windowParams,
|
|
37235
|
+
{
|
|
37236
|
+
name: "tz",
|
|
37237
|
+
description: "The IANA zone the window's days are cut in (`Europe/Brussels`). Default UTC."
|
|
37238
|
+
}
|
|
37239
|
+
],
|
|
37240
|
+
querySchema: landedQuerySchema,
|
|
36476
37241
|
status: 200,
|
|
36477
37242
|
response: { description: "The Landed read.", view: "LandedResponse" },
|
|
36478
37243
|
operationId: "get_landed"
|
|
@@ -36732,6 +37497,17 @@ var roleOperations = defineOperations({
|
|
|
36732
37497
|
|
|
36733
37498
|
// ../../packages/schema/src/operations/routines.ts
|
|
36734
37499
|
var routineOperations = defineOperations({
|
|
37500
|
+
today: {
|
|
37501
|
+
method: "get",
|
|
37502
|
+
path: "/routines/today",
|
|
37503
|
+
scopes: ["routines:read"],
|
|
37504
|
+
tag: "Routines",
|
|
37505
|
+
summary: "Today's routines",
|
|
37506
|
+
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.",
|
|
37507
|
+
status: 200,
|
|
37508
|
+
response: { description: "`{ today, routines }`." },
|
|
37509
|
+
operationId: "routines_today"
|
|
37510
|
+
},
|
|
36735
37511
|
getRun: {
|
|
36736
37512
|
method: "get",
|
|
36737
37513
|
path: "/routines/runs/{runId}",
|
|
@@ -36887,6 +37663,34 @@ var routineOperations = defineOperations({
|
|
|
36887
37663
|
webhook: "routine.run.updated",
|
|
36888
37664
|
operationId: "routine_all_taken"
|
|
36889
37665
|
},
|
|
37666
|
+
reorderSteps: {
|
|
37667
|
+
method: "patch",
|
|
37668
|
+
path: "/routines/{id}/steps/order",
|
|
37669
|
+
scopes: ["routines:write"],
|
|
37670
|
+
tag: "Routines",
|
|
37671
|
+
summary: "Reorder a routine's steps",
|
|
37672
|
+
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`.",
|
|
37673
|
+
body: reorderRoutineStepsInputSchema,
|
|
37674
|
+
status: 200,
|
|
37675
|
+
response: { description: "The routine." },
|
|
37676
|
+
errors: { 400: true, 404: true },
|
|
37677
|
+
webhook: "routine.updated",
|
|
37678
|
+
operationId: "reorder_routine_steps"
|
|
37679
|
+
},
|
|
37680
|
+
addTaskStep: {
|
|
37681
|
+
method: "post",
|
|
37682
|
+
path: "/routines/{id}/runs/today/steps",
|
|
37683
|
+
scopes: ["routines:write"],
|
|
37684
|
+
tag: "Routines",
|
|
37685
|
+
summary: "Add a Work task to today's run",
|
|
37686
|
+
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`.",
|
|
37687
|
+
body: addRoutineTaskStepInputSchema,
|
|
37688
|
+
status: 201,
|
|
37689
|
+
response: { description: "Today's run." },
|
|
37690
|
+
errors: { 400: true, 404: true, 422: true },
|
|
37691
|
+
webhook: "routine.run.updated",
|
|
37692
|
+
operationId: "add_routine_task_step"
|
|
37693
|
+
},
|
|
36890
37694
|
startRun: {
|
|
36891
37695
|
method: "post",
|
|
36892
37696
|
path: "/routines/{id}/runs",
|
|
@@ -38516,6 +39320,40 @@ var tapTagOperations = defineOperations({
|
|
|
38516
39320
|
}
|
|
38517
39321
|
});
|
|
38518
39322
|
|
|
39323
|
+
// ../../packages/schema/src/operations/task-blocks.ts
|
|
39324
|
+
var pathParams5 = { id: "The blocked task's ULID or ref (`DO-148`)." };
|
|
39325
|
+
var taskBlockOperations = defineOperations({
|
|
39326
|
+
addBlocker: {
|
|
39327
|
+
method: "post",
|
|
39328
|
+
path: "/tasks/{id}/blocked-by",
|
|
39329
|
+
pathParams: pathParams5,
|
|
39330
|
+
scopes: ["tasks:write"],
|
|
39331
|
+
tag: "Tasks",
|
|
39332
|
+
summary: "Block a task by another",
|
|
39333
|
+
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.",
|
|
39334
|
+
body: addTaskBlockerInputSchema,
|
|
39335
|
+
status: 200,
|
|
39336
|
+
response: { description: "The blocked task.", view: "Task" },
|
|
39337
|
+
errors: {
|
|
39338
|
+
400: true,
|
|
39339
|
+
404: true,
|
|
39340
|
+
422: "A task can't wait on itself, or the link would make a loop."
|
|
39341
|
+
}
|
|
39342
|
+
},
|
|
39343
|
+
removeBlocker: {
|
|
39344
|
+
method: "delete",
|
|
39345
|
+
path: "/tasks/{id}/blocked-by/{blockerId}",
|
|
39346
|
+
pathParams: { ...pathParams5, blockerId: "The blocker's ULID or ref (`DO-147`)." },
|
|
39347
|
+
scopes: ["tasks:write"],
|
|
39348
|
+
tag: "Tasks",
|
|
39349
|
+
summary: "Unblock a task",
|
|
39350
|
+
description: "The blocker no longer blocks this task. A link that isn't there is a no-op.",
|
|
39351
|
+
status: 200,
|
|
39352
|
+
response: { description: "The task.", view: "Task" },
|
|
39353
|
+
errors: { 404: true }
|
|
39354
|
+
}
|
|
39355
|
+
});
|
|
39356
|
+
|
|
38519
39357
|
// ../../packages/schema/src/operations/tasks.ts
|
|
38520
39358
|
var taskListQuery = taskListQuerySchema.extend(paginationQuerySchema.shape).extend({ filter: taskListFilterSchema.optional().default("all") });
|
|
38521
39359
|
var taskOperations = defineOperations({
|
|
@@ -38539,7 +39377,15 @@ var taskOperations = defineOperations({
|
|
|
38539
39377
|
{ name: "projectId", description: "Only tasks attached to this project (ULID)." },
|
|
38540
39378
|
{
|
|
38541
39379
|
name: "status",
|
|
38542
|
-
description: "Only rows in any of these statuses (comma list or repeated key): `todo`, `in_progress`, `done`, `cancelled`."
|
|
39380
|
+
description: "Only rows in any of these statuses (comma list or repeated key): `backlog`, `todo`, `in_progress`, `waiting`, `done`, `cancelled`."
|
|
39381
|
+
},
|
|
39382
|
+
{
|
|
39383
|
+
name: "priority",
|
|
39384
|
+
description: "Only tasks with any of these priorities (comma list or repeated key): `none`, `low`, `medium`, `high`."
|
|
39385
|
+
},
|
|
39386
|
+
{
|
|
39387
|
+
name: "view",
|
|
39388
|
+
description: "Only the tasks a Work saved view matches (its ULID): exactly the ones its `count` counts."
|
|
38543
39389
|
},
|
|
38544
39390
|
{
|
|
38545
39391
|
name: "tag",
|
|
@@ -38611,7 +39457,7 @@ var taskOperations = defineOperations({
|
|
|
38611
39457
|
scopes: ["tasks:read"],
|
|
38612
39458
|
tag: "Tasks",
|
|
38613
39459
|
summary: "Get a task",
|
|
38614
|
-
description: "Fetch one task by id.",
|
|
39460
|
+
description: "Fetch one task by id (ULID) or by its ref (`DO-142`, case-insensitive).",
|
|
38615
39461
|
status: 200,
|
|
38616
39462
|
response: { description: "The task." },
|
|
38617
39463
|
errors: { 404: true }
|
|
@@ -39135,8 +39981,146 @@ var withingsOperations = defineOperations({
|
|
|
39135
39981
|
}
|
|
39136
39982
|
});
|
|
39137
39983
|
|
|
39984
|
+
// ../../packages/schema/src/db/work-views.ts
|
|
39985
|
+
var workSavedViews = pgTable("work_saved_views", {
|
|
39986
|
+
id: text("id").primaryKey(),
|
|
39987
|
+
tenantId: text("tenant_id").notNull().references(() => tenants.id),
|
|
39988
|
+
name: text("name").notNull(),
|
|
39989
|
+
filters: jsonb("filters").notNull().default({}),
|
|
39990
|
+
groupBy: text("group_by").notNull().default("none"),
|
|
39991
|
+
view: text("view").notNull().default("list"),
|
|
39992
|
+
sortOrder: integer2("sort_order").notNull().default(0),
|
|
39993
|
+
pinned: boolean4("pinned").notNull().default(false),
|
|
39994
|
+
defaultKey: text("default_key"),
|
|
39995
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
39996
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
|
|
39997
|
+
deletedAt: timestamp("deleted_at", { withTimezone: true })
|
|
39998
|
+
}, (t) => [
|
|
39999
|
+
index("work_saved_views_tenant_idx").on(t.tenantId, t.sortOrder)
|
|
40000
|
+
]);
|
|
40001
|
+
|
|
40002
|
+
// ../../packages/schema/src/contracts/work-views.ts
|
|
40003
|
+
var workViewGroupBySchema = _enum2([
|
|
40004
|
+
"area",
|
|
40005
|
+
"status",
|
|
40006
|
+
"project",
|
|
40007
|
+
"priority",
|
|
40008
|
+
"assignee",
|
|
40009
|
+
"none"
|
|
40010
|
+
]);
|
|
40011
|
+
var workViewKindSchema = _enum2(["list", "board", "timeline"]);
|
|
40012
|
+
var workViewWindowSchema = _enum2(["overdue", "today", "this_week", "next_week", "none"]);
|
|
40013
|
+
var workViewAssigneeSchema = union([
|
|
40014
|
+
_enum2(["me", "none"]),
|
|
40015
|
+
string2().regex(/^member:[0-9A-HJKMNP-TV-Z]{26}$/, "member:<ULID>"),
|
|
40016
|
+
string2().regex(/^agent:[0-9A-HJKMNP-TV-Z]{26}$/, "agent:<ULID>")
|
|
40017
|
+
]);
|
|
40018
|
+
var workViewFilterSchema = object({
|
|
40019
|
+
status: array(taskStatusSchema).min(1).optional(),
|
|
40020
|
+
notStatus: array(taskStatusSchema).min(1).optional(),
|
|
40021
|
+
areaIds: array(ulidSchema).min(1).optional(),
|
|
40022
|
+
projectIds: array(ulidSchema).min(1).optional(),
|
|
40023
|
+
labels: array(string2().trim().min(1).max(64)).min(1).optional(),
|
|
40024
|
+
priority: array(workPrioritySchema).min(1).optional(),
|
|
40025
|
+
assignee: workViewAssigneeSchema.optional(),
|
|
40026
|
+
waiting: boolean2().optional(),
|
|
40027
|
+
due: workViewWindowSchema.optional(),
|
|
40028
|
+
scheduled: workViewWindowSchema.optional(),
|
|
40029
|
+
when: workViewWindowSchema.optional()
|
|
40030
|
+
}).strict();
|
|
40031
|
+
var workViewDefaultKeySchema = _enum2(["all_open", "this_week", "waiting"]);
|
|
40032
|
+
var workViewNameSchema = string2().trim().min(1).max(80);
|
|
40033
|
+
var workSavedViewSchema = createSelectSchema(workSavedViews, {
|
|
40034
|
+
filters: workViewFilterSchema,
|
|
40035
|
+
groupBy: workViewGroupBySchema,
|
|
40036
|
+
view: workViewKindSchema,
|
|
40037
|
+
defaultKey: workViewDefaultKeySchema.nullable(),
|
|
40038
|
+
createdAt: exports_coerce.date(),
|
|
40039
|
+
updatedAt: exports_coerce.date(),
|
|
40040
|
+
deletedAt: exports_coerce.date().nullable()
|
|
40041
|
+
});
|
|
40042
|
+
var workViewSchema = workSavedViewSchema.omit({ tenantId: true, deletedAt: true }).extend({ count: number2().int().nonnegative() });
|
|
40043
|
+
var createWorkViewInputSchema = object({
|
|
40044
|
+
id: ulidSchema.optional(),
|
|
40045
|
+
name: workViewNameSchema,
|
|
40046
|
+
filters: workViewFilterSchema.default({}),
|
|
40047
|
+
groupBy: workViewGroupBySchema.default("none"),
|
|
40048
|
+
view: workViewKindSchema.default("list"),
|
|
40049
|
+
pinned: boolean2().optional(),
|
|
40050
|
+
sortOrder: number2().int().nonnegative().optional()
|
|
40051
|
+
}).strict();
|
|
40052
|
+
var updateWorkViewInputSchema = object({
|
|
40053
|
+
name: workViewNameSchema.optional(),
|
|
40054
|
+
filters: workViewFilterSchema.optional(),
|
|
40055
|
+
groupBy: workViewGroupBySchema.optional(),
|
|
40056
|
+
view: workViewKindSchema.optional(),
|
|
40057
|
+
pinned: boolean2().optional()
|
|
40058
|
+
}).strict();
|
|
40059
|
+
var reorderWorkViewsInputSchema = object({ ids: array(ulidSchema).min(1).max(200) }).strict();
|
|
40060
|
+
|
|
40061
|
+
// ../../packages/schema/src/operations/work-views.ts
|
|
40062
|
+
var workViewOperations = defineOperations({
|
|
40063
|
+
list: {
|
|
40064
|
+
method: "get",
|
|
40065
|
+
path: "/work-views",
|
|
40066
|
+
scopes: ["tasks:read"],
|
|
40067
|
+
tag: "Tasks",
|
|
40068
|
+
summary: "List Work saved views",
|
|
40069
|
+
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.",
|
|
40070
|
+
status: 200,
|
|
40071
|
+
response: { description: "The views, in order." }
|
|
40072
|
+
},
|
|
40073
|
+
create: {
|
|
40074
|
+
method: "post",
|
|
40075
|
+
path: "/work-views",
|
|
40076
|
+
scopes: ["tasks:write"],
|
|
40077
|
+
tag: "Tasks",
|
|
40078
|
+
summary: "Save a Work view",
|
|
40079
|
+
description: "A named filter (strict: an unknown key is a 400), with `groupBy` and `view`; it goes last unless `sortOrder` says where.",
|
|
40080
|
+
body: createWorkViewInputSchema,
|
|
40081
|
+
status: 201,
|
|
40082
|
+
response: { description: "The saved view, with its count." },
|
|
40083
|
+
errors: { 400: true }
|
|
40084
|
+
},
|
|
40085
|
+
reorder: {
|
|
40086
|
+
method: "post",
|
|
40087
|
+
path: "/work-views/reorder",
|
|
40088
|
+
scopes: ["tasks:write"],
|
|
40089
|
+
tag: "Tasks",
|
|
40090
|
+
summary: "Reorder Work views",
|
|
40091
|
+
description: "The listed views first, in the order given; any not listed keep their order after them. An unknown id is a 404.",
|
|
40092
|
+
body: reorderWorkViewsInputSchema,
|
|
40093
|
+
status: 200,
|
|
40094
|
+
response: { description: "The views, in their new order." },
|
|
40095
|
+
errors: { 400: true, 404: true }
|
|
40096
|
+
},
|
|
40097
|
+
update: {
|
|
40098
|
+
method: "patch",
|
|
40099
|
+
path: "/work-views/{id}",
|
|
40100
|
+
scopes: ["tasks:write"],
|
|
40101
|
+
tag: "Tasks",
|
|
40102
|
+
summary: "Update a Work view",
|
|
40103
|
+
description: "Rename it, or change its filters (replaced whole), grouping, view kind or pin.",
|
|
40104
|
+
body: updateWorkViewInputSchema,
|
|
40105
|
+
status: 200,
|
|
40106
|
+
response: { description: "The view, with its count." },
|
|
40107
|
+
errors: { 400: true, 404: true }
|
|
40108
|
+
},
|
|
40109
|
+
remove: {
|
|
40110
|
+
method: "delete",
|
|
40111
|
+
path: "/work-views/{id}",
|
|
40112
|
+
scopes: ["tasks:write"],
|
|
40113
|
+
tag: "Tasks",
|
|
40114
|
+
summary: "Delete a Work view",
|
|
40115
|
+
description: "Delete a view, a default one too; it isn't seeded again.",
|
|
40116
|
+
status: 204,
|
|
40117
|
+
response: { description: "Deleted." },
|
|
40118
|
+
errors: { 404: true }
|
|
40119
|
+
}
|
|
40120
|
+
});
|
|
40121
|
+
|
|
39138
40122
|
// ../../packages/schema/src/operations/worktree-links.ts
|
|
39139
|
-
var
|
|
40123
|
+
var pathParams6 = { nodeId: "The linked Task's or Project's ULID." };
|
|
39140
40124
|
var notLinkable = "No live Task or Project with that id in this Space (or, for GET, no link on it).";
|
|
39141
40125
|
var worktreeLinkOperations = defineOperations({
|
|
39142
40126
|
list: {
|
|
@@ -39162,7 +40146,7 @@ var worktreeLinkOperations = defineOperations({
|
|
|
39162
40146
|
get: {
|
|
39163
40147
|
method: "get",
|
|
39164
40148
|
path: "/worktree-links/{nodeId}",
|
|
39165
|
-
pathParams:
|
|
40149
|
+
pathParams: pathParams6,
|
|
39166
40150
|
scopes: ["orca:read"],
|
|
39167
40151
|
tag: "Orca",
|
|
39168
40152
|
summary: "Get a worktree link",
|
|
@@ -39174,7 +40158,7 @@ var worktreeLinkOperations = defineOperations({
|
|
|
39174
40158
|
set: {
|
|
39175
40159
|
method: "put",
|
|
39176
40160
|
path: "/worktree-links/{nodeId}",
|
|
39177
|
-
pathParams:
|
|
40161
|
+
pathParams: pathParams6,
|
|
39178
40162
|
scopes: ["orca:write"],
|
|
39179
40163
|
tag: "Orca",
|
|
39180
40164
|
summary: "Set a worktree link",
|
|
@@ -39188,7 +40172,7 @@ var worktreeLinkOperations = defineOperations({
|
|
|
39188
40172
|
clear: {
|
|
39189
40173
|
method: "delete",
|
|
39190
40174
|
path: "/worktree-links/{nodeId}",
|
|
39191
|
-
pathParams:
|
|
40175
|
+
pathParams: pathParams6,
|
|
39192
40176
|
scopes: ["orca:write"],
|
|
39193
40177
|
tag: "Orca",
|
|
39194
40178
|
summary: "Clear a worktree link",
|
|
@@ -39717,7 +40701,8 @@ var filmFacetSchema = object({
|
|
|
39717
40701
|
coverUrl,
|
|
39718
40702
|
episodeCount: number2().int().min(1).max(1e4).nullish(),
|
|
39719
40703
|
currentEpisode: number2().int().min(0).max(1e4).nullish(),
|
|
39720
|
-
format: string2().min(1).max(60).nullish()
|
|
40704
|
+
format: string2().min(1).max(60).nullish(),
|
|
40705
|
+
runtimeMinutes: number2().int().min(1).max(2000).nullish()
|
|
39721
40706
|
}).strict();
|
|
39722
40707
|
var gameFacetSchema = object({
|
|
39723
40708
|
platform: string2().min(1).max(120).nullish(),
|
|
@@ -39731,11 +40716,30 @@ var gameFacetSchema = object({
|
|
|
39731
40716
|
year: number2().int().min(1950).max(2100).nullish(),
|
|
39732
40717
|
playedWith: string2().min(1).max(120).nullish()
|
|
39733
40718
|
}).strict();
|
|
40719
|
+
var musicTrackSchema = object({
|
|
40720
|
+
pos: string2().min(1).max(8),
|
|
40721
|
+
title: string2().min(1).max(200),
|
|
40722
|
+
seconds: number2().int().min(0).max(36000).nullish()
|
|
40723
|
+
}).strict();
|
|
39734
40724
|
var musicFacetSchema = object({
|
|
39735
40725
|
artist: string2().min(1).max(200).nullish(),
|
|
39736
40726
|
year: number2().int().min(1860).max(2100).nullish(),
|
|
39737
40727
|
coverUrl,
|
|
39738
|
-
format: string2().min(1).max(60).nullish()
|
|
40728
|
+
format: string2().min(1).max(60).nullish(),
|
|
40729
|
+
edition: string2().min(1).max(60).nullish(),
|
|
40730
|
+
tracks: array(musicTrackSchema).max(60).nullish()
|
|
40731
|
+
}).strict();
|
|
40732
|
+
var hobbyFacetSchema = object({
|
|
40733
|
+
kind: string2().min(1).max(40).nullish(),
|
|
40734
|
+
progress: object({
|
|
40735
|
+
done: number2().int().min(0).max(1e5),
|
|
40736
|
+
total: number2().int().min(1).max(1e5),
|
|
40737
|
+
unit: string2().min(1).max(40)
|
|
40738
|
+
}).strict().nullish(),
|
|
40739
|
+
shelf: _enum2(["display", "boxed"]).default("display"),
|
|
40740
|
+
needsFix: boolean2().nullish(),
|
|
40741
|
+
fixNote: string2().min(1).max(200).nullish(),
|
|
40742
|
+
coverUrl
|
|
39739
40743
|
}).strict();
|
|
39740
40744
|
var placeFacetSchema = object({
|
|
39741
40745
|
address: string2().min(1).max(400).nullish(),
|
|
@@ -39963,6 +40967,16 @@ var COLLECTION_TYPES = {
|
|
|
39963
40967
|
facetSchema: assetFacetSchema,
|
|
39964
40968
|
view: "grid",
|
|
39965
40969
|
subtitleKey: "brand"
|
|
40970
|
+
},
|
|
40971
|
+
hobby: {
|
|
40972
|
+
key: "hobby",
|
|
40973
|
+
label: "Things",
|
|
40974
|
+
itemNoun: "thing",
|
|
40975
|
+
statuses: ["want", "doing", "have"],
|
|
40976
|
+
statusLabels: { want: "Want", doing: "Building", have: "Built" },
|
|
40977
|
+
facetSchema: hobbyFacetSchema,
|
|
40978
|
+
view: "grid",
|
|
40979
|
+
subtitleKey: "kind"
|
|
39966
40980
|
}
|
|
39967
40981
|
};
|
|
39968
40982
|
var COLLECTION_TYPE_LIST = collectionTypeValues.map((k) => COLLECTION_TYPES[k]);
|
|
@@ -40041,8 +41055,11 @@ var STATUS_MARK = {
|
|
|
40041
41055
|
done: "\u2713",
|
|
40042
41056
|
cancelled: "\u2717",
|
|
40043
41057
|
in_progress: "\u25D0",
|
|
40044
|
-
todo: "\u25CB"
|
|
41058
|
+
todo: "\u25CB",
|
|
41059
|
+
backlog: "\u25CC",
|
|
41060
|
+
waiting: "\u29D7"
|
|
40045
41061
|
};
|
|
41062
|
+
var PRIORITY_WORD = { low: "low", medium: "medium", high: "high" };
|
|
40046
41063
|
function suggestionText(s) {
|
|
40047
41064
|
const parts = [
|
|
40048
41065
|
[s.area, s.project].filter(Boolean).join(" \u203A ") || null,
|
|
@@ -40067,18 +41084,24 @@ function renderTask(data, mode) {
|
|
|
40067
41084
|
const date = when ? paint(mode, "dim", ` (${shortDate(when)})`) : "";
|
|
40068
41085
|
const by = t.createdBy?.kind === "agent" ? paint(mode, "dim", ` \xB7 by ${t.createdBy.name ?? "an agent"}`) : "";
|
|
40069
41086
|
const meta = [
|
|
41087
|
+
t.priority && PRIORITY_WORD[t.priority] ? `${PRIORITY_WORD[t.priority]} priority` : null,
|
|
40070
41088
|
t.owner ? `owner ${ownerText(t.owner)}` : null,
|
|
40071
|
-
t.nextStep ? `next: ${t.nextStep}` : null
|
|
41089
|
+
t.nextStep ? `next: ${t.nextStep}` : null,
|
|
41090
|
+
t.deliverable ? `delivers: ${t.deliverable}` : null
|
|
40072
41091
|
].filter(Boolean);
|
|
40073
41092
|
const waiting = t.waitingOn ? `
|
|
40074
41093
|
${paint(mode, "yellow", `\u29D7 waiting on ${t.waitingOn.name ?? "someone"}`)}` : "";
|
|
40075
41094
|
const metaLine = meta.length > 0 ? `
|
|
40076
41095
|
${paint(mode, "dim", meta.join(" \xB7 "))}` : "";
|
|
41096
|
+
const holding = (t.blockedBy ?? []).filter((b) => b.status !== "done");
|
|
41097
|
+
const blocked = t.isBlocked && holding.length > 0 ? `
|
|
41098
|
+
${paint(mode, "yellow", `\u2298 blocked by ${holding.map((b) => `${b.ref ?? ""} ${b.title ?? ""}`.trim()).join(", ")}`)}` : "";
|
|
40077
41099
|
const worktree = t.worktreeLink ? `
|
|
40078
41100
|
${paint(mode, "dim", `\u2387 ${worktreeText(t.worktreeLink)}`)}` : "";
|
|
40079
41101
|
const suggestion = t.filingSuggestion ? `
|
|
40080
41102
|
${paint(mode, "dim", `\u2726 ${suggestionText(t.filingSuggestion)}`)}` : "";
|
|
40081
|
-
|
|
41103
|
+
const ref = t.ref ? `${t.ref} ` : "";
|
|
41104
|
+
return `${mark} ${ref}${star}${t.title ?? "(untitled)"}${date}${by}${waiting}${blocked}${metaLine}${worktree}${suggestion}
|
|
40082
41105
|
${paint(mode, "dim", t.id)}`;
|
|
40083
41106
|
}
|
|
40084
41107
|
function renderToday(data, mode) {
|
|
@@ -40404,7 +41427,8 @@ function renderList(data, mode) {
|
|
|
40404
41427
|
const body = rows.length === 0 ? paint(mode, "dim", "(no records)") : [
|
|
40405
41428
|
`${rows.length} record(s):`,
|
|
40406
41429
|
...rows.map((row) => {
|
|
40407
|
-
const
|
|
41430
|
+
const ref = refOf(row);
|
|
41431
|
+
const label = ref ? `${ref} ${labelOf(row)}` : labelOf(row);
|
|
40408
41432
|
const id = idOf(row);
|
|
40409
41433
|
return id ? ` ${label} ${paint(mode, "dim", id)}` : ` ${label}`;
|
|
40410
41434
|
})
|
|
@@ -40415,6 +41439,12 @@ function renderList(data, mode) {
|
|
|
40415
41439
|
return `${body}
|
|
40416
41440
|
${paint(mode, "dim", `\u2026 more \u2014 rerun with --cursor ${nextCursor}`)}`;
|
|
40417
41441
|
}
|
|
41442
|
+
function refOf(row) {
|
|
41443
|
+
if (row === null || typeof row !== "object")
|
|
41444
|
+
return null;
|
|
41445
|
+
const ref = row.ref;
|
|
41446
|
+
return typeof ref === "string" && ref.length > 0 ? ref : null;
|
|
41447
|
+
}
|
|
40418
41448
|
function asPage(data) {
|
|
40419
41449
|
if (Array.isArray(data))
|
|
40420
41450
|
return { rows: data, nextCursor: null };
|
|
@@ -41116,6 +42146,43 @@ function renderEvents(data, mode) {
|
|
|
41116
42146
|
return events.map((e) => renderEvent(e, mode)).join(`
|
|
41117
42147
|
`);
|
|
41118
42148
|
}
|
|
42149
|
+
var CALENDAR_HEALTH = {
|
|
42150
|
+
ok: "ok",
|
|
42151
|
+
retrying: "retrying (a passing failure; the sweep tries again)",
|
|
42152
|
+
reconnect: "needs reconnecting in Settings",
|
|
42153
|
+
pending: "never finished connecting"
|
|
42154
|
+
};
|
|
42155
|
+
function renderCalendarStatus(data, mode) {
|
|
42156
|
+
const rows = data ?? [];
|
|
42157
|
+
if (rows.length === 0)
|
|
42158
|
+
return paint(mode, "dim", "No calendar connected.");
|
|
42159
|
+
const at = (iso) => iso ? shortDate(iso) : "never";
|
|
42160
|
+
return rows.map((s) => {
|
|
42161
|
+
const health = CALENDAR_HEALTH[s.health ?? ""] ?? s.health ?? "?";
|
|
42162
|
+
const lines = [
|
|
42163
|
+
`${paint(mode, "bold", s.account ?? s.provider ?? "calendar")} \u2014 ${health}`,
|
|
42164
|
+
` last push ${at(s.lastPushAt)} \xB7 last sync ${at(s.lastSyncAt)}`,
|
|
42165
|
+
...s.lastError ? [` ${paint(mode, "dim", s.lastError)}`] : [],
|
|
42166
|
+
` ${paint(mode, "dim", s.connectionId)}`
|
|
42167
|
+
];
|
|
42168
|
+
return lines.join(`
|
|
42169
|
+
`);
|
|
42170
|
+
}).join(`
|
|
42171
|
+
`);
|
|
42172
|
+
}
|
|
42173
|
+
function renderCalendarPush(data, mode) {
|
|
42174
|
+
const rows = data ?? [];
|
|
42175
|
+
if (rows.length === 0)
|
|
42176
|
+
return paint(mode, "dim", "No calendar to push to.");
|
|
42177
|
+
return rows.map((p) => p.error ? `${p.connectionId}: not pushed \u2014 ${p.error}` : `${p.connectionId}: ${p.created ?? 0} created \xB7 ${p.updated ?? 0} updated \xB7 ${p.deleted ?? 0} removed \xB7 ${p.skipped ?? 0} already in sync${p.failed ? ` \xB7 ${p.failed} failed` : ""}`).join(`
|
|
42178
|
+
`);
|
|
42179
|
+
}
|
|
42180
|
+
function renderCalendarRefresh(data, mode) {
|
|
42181
|
+
const r = data;
|
|
42182
|
+
const pulled = (r.mirrored ?? []).map((m) => `${m.connectionId}: pulled ${m.created ?? 0} new \xB7 ${m.updated ?? 0} changed \xB7 ${m.cancelled ?? 0} cancelled`);
|
|
42183
|
+
return [...pulled, renderCalendarPush(r.pushed ?? [], mode)].join(`
|
|
42184
|
+
`);
|
|
42185
|
+
}
|
|
41119
42186
|
|
|
41120
42187
|
// src/command-helpers.ts
|
|
41121
42188
|
function applyPageFlags(query, flags) {
|
|
@@ -41255,6 +42322,9 @@ function mergePreview(before, changes) {
|
|
|
41255
42322
|
}
|
|
41256
42323
|
|
|
41257
42324
|
// src/entities.ts
|
|
42325
|
+
function taskStatusWire(value) {
|
|
42326
|
+
return value.trim().toLowerCase().replace(/-/g, "_");
|
|
42327
|
+
}
|
|
41258
42328
|
var AREA_FLAG = {
|
|
41259
42329
|
name: "area",
|
|
41260
42330
|
description: "only rows in this area id",
|
|
@@ -41316,7 +42386,12 @@ var ENTITIES = [
|
|
|
41316
42386
|
{ name: "project", description: "only tasks in this project id", query: "projectId" },
|
|
41317
42387
|
{
|
|
41318
42388
|
name: "status",
|
|
41319
|
-
description: "only these statuses, comma-separated (todo,
|
|
42389
|
+
description: "only these statuses, comma-separated (backlog,todo,in-progress,waiting,done,cancelled)",
|
|
42390
|
+
normalize: taskStatusWire
|
|
42391
|
+
},
|
|
42392
|
+
{
|
|
42393
|
+
name: "priority",
|
|
42394
|
+
description: "only these priorities, comma-separated (none,low,medium,high)"
|
|
41320
42395
|
},
|
|
41321
42396
|
{ name: "tag", description: "only tasks carrying every listed tag, comma-separated" },
|
|
41322
42397
|
UPDATED_SINCE_FLAG,
|
|
@@ -42806,6 +43881,51 @@ var commands5 = [
|
|
|
42806
43881
|
render: renderEvent
|
|
42807
43882
|
};
|
|
42808
43883
|
}
|
|
43884
|
+
},
|
|
43885
|
+
{
|
|
43886
|
+
spec: {
|
|
43887
|
+
path: ["calendar", "status"],
|
|
43888
|
+
summary: "How each of the member's calendar connections is doing: ok, retrying or needs reconnecting, the last failure, and when do last pushed to and synced from it.",
|
|
43889
|
+
args: [],
|
|
43890
|
+
flags: [],
|
|
43891
|
+
scopes: [...calendarOperations.status.scopes],
|
|
43892
|
+
returns: "CalendarConnectionStatus[]",
|
|
43893
|
+
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.`
|
|
43894
|
+
},
|
|
43895
|
+
run: async ({ requireClient }) => ({
|
|
43896
|
+
data: (await requireClient().getPage(pathOf(calendarOperations.status))).data,
|
|
43897
|
+
render: renderCalendarStatus
|
|
43898
|
+
})
|
|
43899
|
+
},
|
|
43900
|
+
{
|
|
43901
|
+
spec: {
|
|
43902
|
+
path: ["calendar", "push"],
|
|
43903
|
+
summary: "Push do's timed tasks, deadlines, Time blocks and routines to the member's calendar now. Idempotent.",
|
|
43904
|
+
args: [],
|
|
43905
|
+
flags: [],
|
|
43906
|
+
scopes: [...calendarOperations.push.scopes],
|
|
43907
|
+
returns: "{ pushed: CalendarPushResult[] }",
|
|
43908
|
+
notes: `${routeOf(calendarOperations.push)}. A connection that needs reconnecting is left out. Needs a key that acts for a member.`
|
|
43909
|
+
},
|
|
43910
|
+
run: async ({ requireClient }) => ({
|
|
43911
|
+
data: (await requireClient().post(pathOf(calendarOperations.push), {})).pushed,
|
|
43912
|
+
render: renderCalendarPush
|
|
43913
|
+
})
|
|
43914
|
+
},
|
|
43915
|
+
{
|
|
43916
|
+
spec: {
|
|
43917
|
+
path: ["calendar", "refresh"],
|
|
43918
|
+
summary: "Sync the member's calendar now: pull their calendars into do, then push do's placements out.",
|
|
43919
|
+
args: [],
|
|
43920
|
+
flags: [],
|
|
43921
|
+
scopes: [...calendarOperations.refresh.scopes],
|
|
43922
|
+
returns: "{ mirrored, pushed }",
|
|
43923
|
+
notes: `${routeOf(calendarOperations.refresh)}. Pulls however recently it last synced. Needs a key that acts for a member.`
|
|
43924
|
+
},
|
|
43925
|
+
run: async ({ requireClient }) => ({
|
|
43926
|
+
data: await requireClient().post(pathOf(calendarOperations.refresh), {}),
|
|
43927
|
+
render: renderCalendarRefresh
|
|
43928
|
+
})
|
|
42809
43929
|
}
|
|
42810
43930
|
];
|
|
42811
43931
|
|
|
@@ -43051,7 +44171,11 @@ var commands8 = [
|
|
|
43051
44171
|
summary: "List Collection Items, optionally sliced by Type / Status / tag.",
|
|
43052
44172
|
args: [],
|
|
43053
44173
|
flags: [
|
|
43054
|
-
{
|
|
44174
|
+
{
|
|
44175
|
+
name: "type",
|
|
44176
|
+
type: "string",
|
|
44177
|
+
description: "Filter to one Type (book|film|game|\u2026|hobby)."
|
|
44178
|
+
},
|
|
43055
44179
|
{
|
|
43056
44180
|
name: "status",
|
|
43057
44181
|
type: "string",
|
|
@@ -43094,7 +44218,11 @@ var commands8 = [
|
|
|
43094
44218
|
summary: "Add a Collection Item (the title may embed #tag).",
|
|
43095
44219
|
args: [{ name: "title", required: true, description: "Item title; may embed #tag." }],
|
|
43096
44220
|
flags: [
|
|
43097
|
-
{
|
|
44221
|
+
{
|
|
44222
|
+
name: "type",
|
|
44223
|
+
type: "string",
|
|
44224
|
+
description: "Type (book|film|game|music|place|wine|wardrobe|hobby)."
|
|
44225
|
+
},
|
|
43098
44226
|
{
|
|
43099
44227
|
name: "status",
|
|
43100
44228
|
type: "string",
|
|
@@ -43106,15 +44234,16 @@ var commands8 = [
|
|
|
43106
44234
|
grammar: {
|
|
43107
44235
|
"#tag": "Adds a tag. Repeatable: '#scifi #2024'."
|
|
43108
44236
|
},
|
|
43109
|
-
notes:
|
|
44237
|
+
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"}}}\'`.'
|
|
43110
44238
|
},
|
|
43111
44239
|
run: async ({ args, flags, requireClient }) => {
|
|
43112
44240
|
const { title, tags } = parseTitleTags(args);
|
|
43113
44241
|
if (title.length === 0)
|
|
43114
44242
|
throw usageError('collection add needs a title, e.g. `do collection add "Dune" --type book`');
|
|
43115
|
-
const type = requireFlag(flags, "type", "collection add needs --type <book|film|game|music|place|wine>");
|
|
44243
|
+
const type = requireFlag(flags, "type", "collection add needs --type <book|film|game|music|place|wine|wardrobe|hobby>");
|
|
43116
44244
|
const body = parseInput(createCollectionItemInputSchema, {
|
|
43117
44245
|
id: ulid3(),
|
|
44246
|
+
...readDataFlag(flags),
|
|
43118
44247
|
type,
|
|
43119
44248
|
title,
|
|
43120
44249
|
...tags.length > 0 ? { tags } : {},
|
|
@@ -47389,8 +48518,126 @@ var commands22 = [
|
|
|
47389
48518
|
}
|
|
47390
48519
|
];
|
|
47391
48520
|
|
|
47392
|
-
// src/commands/
|
|
48521
|
+
// src/commands/inbox.ts
|
|
48522
|
+
function renderInbox(data, _mode) {
|
|
48523
|
+
const d = data;
|
|
48524
|
+
const items = d.items ?? [];
|
|
48525
|
+
const c = d.counts ?? {};
|
|
48526
|
+
const head = `${c.all ?? items.length} waiting \xB7 ${c.capture ?? 0} captures \xB7 ${c.proposal ?? 0} proposals \xB7 ${c.answer ?? 0} need an answer`;
|
|
48527
|
+
if (items.length === 0)
|
|
48528
|
+
return `${head}
|
|
48529
|
+
Nothing waits here.`;
|
|
48530
|
+
const lines = items.map((item) => {
|
|
48531
|
+
const primary = item.actions.find((a) => a.primary);
|
|
48532
|
+
const action = primary ? ` [${primary.label} (${primary.key})]` : "";
|
|
48533
|
+
return `${item.id} ${item.kind.padEnd(8)} ${item.title} \u2014 ${item.source} \xB7 ${item.meta}${action}`;
|
|
48534
|
+
});
|
|
48535
|
+
return [head, ...lines].join(`
|
|
48536
|
+
`);
|
|
48537
|
+
}
|
|
48538
|
+
function renderSorting(data, _mode) {
|
|
48539
|
+
const d = data;
|
|
48540
|
+
return [
|
|
48541
|
+
`Captured by ${d.original.how}: \u201C${d.original.text}\u201D`,
|
|
48542
|
+
`Becomes a ${d.becomes}`,
|
|
48543
|
+
...d.facts.map((f) => ` ${f.key}: ${f.value}`),
|
|
48544
|
+
...d.why ? [d.why] : []
|
|
48545
|
+
].join(`
|
|
48546
|
+
`);
|
|
48547
|
+
}
|
|
47393
48548
|
var commands23 = [
|
|
48549
|
+
defineCommand({
|
|
48550
|
+
operation: inboxOperations.list,
|
|
48551
|
+
path: ["inbox"],
|
|
48552
|
+
summary: "The Inbox: captures, the agent's proposals and notifications that need an answer, oldest first, with per-kind counts.",
|
|
48553
|
+
flags: [
|
|
48554
|
+
{
|
|
48555
|
+
name: "kind",
|
|
48556
|
+
type: "string",
|
|
48557
|
+
description: "all (default), capture, proposal or answer."
|
|
48558
|
+
}
|
|
48559
|
+
],
|
|
48560
|
+
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`.",
|
|
48561
|
+
run: async ({ flags, requireClient }) => {
|
|
48562
|
+
const kind = flagString(flags, "kind");
|
|
48563
|
+
if (kind !== undefined && !inboxFilterSchema.safeParse(kind).success) {
|
|
48564
|
+
throw usageError(`--kind must be one of ${inboxFilterSchema.options.join(", ")}`);
|
|
48565
|
+
}
|
|
48566
|
+
return {
|
|
48567
|
+
data: await requireClient().get(pathOf(inboxOperations.list), {
|
|
48568
|
+
query: { kind }
|
|
48569
|
+
}),
|
|
48570
|
+
render: renderInbox
|
|
48571
|
+
};
|
|
48572
|
+
}
|
|
48573
|
+
}),
|
|
48574
|
+
defineCommand({
|
|
48575
|
+
operation: inboxOperations.sorting,
|
|
48576
|
+
path: ["inbox", "sorting"],
|
|
48577
|
+
summary: "The sorting pane for a capture: what it becomes and what the agent filled in.",
|
|
48578
|
+
args: [{ name: "id", required: true, description: "The capture's id." }],
|
|
48579
|
+
run: async ({ args, requireClient }) => ({
|
|
48580
|
+
data: await requireClient().get(pathOf(inboxOperations.sorting, { id: requireArg(args, 0, "id") })),
|
|
48581
|
+
render: renderSorting
|
|
48582
|
+
})
|
|
48583
|
+
}),
|
|
48584
|
+
defineCommand({
|
|
48585
|
+
operation: inboxOperations.sort,
|
|
48586
|
+
path: ["inbox", "sort"],
|
|
48587
|
+
summary: "Sort a capture into its home: a task, note, habit or log entry.",
|
|
48588
|
+
args: [{ name: "id", required: true, description: "The capture's id." }],
|
|
48589
|
+
flags: [
|
|
48590
|
+
{
|
|
48591
|
+
name: "as",
|
|
48592
|
+
type: "string",
|
|
48593
|
+
description: "task, note, habit or log (required)."
|
|
48594
|
+
},
|
|
48595
|
+
{
|
|
48596
|
+
name: "area",
|
|
48597
|
+
type: "string",
|
|
48598
|
+
description: "File it in this Area (id); a task without one takes the agent's suggestion."
|
|
48599
|
+
},
|
|
48600
|
+
{
|
|
48601
|
+
name: "title",
|
|
48602
|
+
type: "string",
|
|
48603
|
+
description: "A new title for what it becomes."
|
|
48604
|
+
}
|
|
48605
|
+
],
|
|
48606
|
+
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.",
|
|
48607
|
+
run: async ({ args, flags, requireClient }) => {
|
|
48608
|
+
const id = requireArg(args, 0, "id");
|
|
48609
|
+
const as = requireFlag(flags, "as", `inbox sort needs --as ${INBOX_SORT_AS.join("|")}`);
|
|
48610
|
+
if (!INBOX_SORT_AS.includes(as)) {
|
|
48611
|
+
throw usageError(`--as must be one of ${INBOX_SORT_AS.join(", ")} (got \`${as}\`)`);
|
|
48612
|
+
}
|
|
48613
|
+
const area = flagString(flags, "area");
|
|
48614
|
+
const title = flagString(flags, "title");
|
|
48615
|
+
const fields = {
|
|
48616
|
+
...area ? { areaId: area } : {},
|
|
48617
|
+
...title ? { title } : {}
|
|
48618
|
+
};
|
|
48619
|
+
const body = Object.keys(fields).length > 0 ? { as, fields } : { as };
|
|
48620
|
+
return {
|
|
48621
|
+
data: await requireClient().post(pathOf(inboxOperations.sort, { id }), body),
|
|
48622
|
+
render: renderRecord
|
|
48623
|
+
};
|
|
48624
|
+
}
|
|
48625
|
+
}),
|
|
48626
|
+
defineCommand({
|
|
48627
|
+
operation: inboxOperations.letGo,
|
|
48628
|
+
path: ["inbox", "let-go"],
|
|
48629
|
+
summary: "Let a capture go: cancelled, out of the Inbox, never counted as Landed.",
|
|
48630
|
+
args: [{ name: "id", required: true, description: "The capture's id." }],
|
|
48631
|
+
notes: ". Changed your mind? `do task reopen <id>`.",
|
|
48632
|
+
run: async ({ args, requireClient }) => ({
|
|
48633
|
+
data: await requireClient().post(pathOf(inboxOperations.letGo, { id: requireArg(args, 0, "id") }), {}),
|
|
48634
|
+
render: renderRecord
|
|
48635
|
+
})
|
|
48636
|
+
})
|
|
48637
|
+
];
|
|
48638
|
+
|
|
48639
|
+
// src/commands/incidents.ts
|
|
48640
|
+
var commands24 = [
|
|
47394
48641
|
{
|
|
47395
48642
|
spec: {
|
|
47396
48643
|
path: ["incidents", "open"],
|
|
@@ -47619,7 +48866,7 @@ function journalDateArg(args, verb) {
|
|
|
47619
48866
|
}
|
|
47620
48867
|
return date;
|
|
47621
48868
|
}
|
|
47622
|
-
var
|
|
48869
|
+
var commands25 = [
|
|
47623
48870
|
defineCommand({
|
|
47624
48871
|
operation: journalOperations.day,
|
|
47625
48872
|
path: ["journal", "day"],
|
|
@@ -48171,7 +49418,7 @@ var commands24 = [
|
|
|
48171
49418
|
];
|
|
48172
49419
|
|
|
48173
49420
|
// src/commands/keys.ts
|
|
48174
|
-
var
|
|
49421
|
+
var commands26 = [
|
|
48175
49422
|
{
|
|
48176
49423
|
spec: {
|
|
48177
49424
|
path: ["keys", "list"],
|
|
@@ -48230,8 +49477,108 @@ var commands25 = [
|
|
|
48230
49477
|
}
|
|
48231
49478
|
];
|
|
48232
49479
|
|
|
49480
|
+
// src/commands/log.ts
|
|
49481
|
+
function previewLine(preview, mode) {
|
|
49482
|
+
const effect = preview.effect ? paint(mode, "dim", ` \xB7 ${preview.effect}`) : "";
|
|
49483
|
+
return `${preview.label} \u2192 ${preview.goesTo ?? "?"}${effect}`;
|
|
49484
|
+
}
|
|
49485
|
+
function renderPreview(data, mode) {
|
|
49486
|
+
return `Would log: ${previewLine(data, mode)}`;
|
|
49487
|
+
}
|
|
49488
|
+
function renderWritten(data, mode) {
|
|
49489
|
+
const { preview, remembered } = data;
|
|
49490
|
+
const learnt = remembered ? `
|
|
49491
|
+
${paint(mode, "dim", `Remembered "${remembered}": next time it goes there without asking.`)}` : "";
|
|
49492
|
+
return `Logged: ${previewLine(preview, mode)}${learnt}`;
|
|
49493
|
+
}
|
|
49494
|
+
function renderLogged(data, mode) {
|
|
49495
|
+
const rows = (data.data ?? data) || [];
|
|
49496
|
+
if (rows.length === 0)
|
|
49497
|
+
return paint(mode, "dim", "(nothing logged)");
|
|
49498
|
+
return rows.map((e) => `${e.at} ${e.what} ${paint(mode, "dim", e.where)}`).join(`
|
|
49499
|
+
`);
|
|
49500
|
+
}
|
|
49501
|
+
var KIND_FLAG = {
|
|
49502
|
+
name: "kind",
|
|
49503
|
+
type: "string",
|
|
49504
|
+
description: "The kind of an unknown word (pages, eggs, health, note, or a word taught before); remembered for the Space."
|
|
49505
|
+
};
|
|
49506
|
+
var commands27 = [
|
|
49507
|
+
{
|
|
49508
|
+
spec: {
|
|
49509
|
+
path: ["log"],
|
|
49510
|
+
summary: 'Log one line ("pages 34", "eggs 4"): preview where it goes and what it does, then write it into its section.',
|
|
49511
|
+
args: [{ name: "line", required: true, description: 'The line, e.g. "pages 34".' }],
|
|
49512
|
+
flags: [
|
|
49513
|
+
{ name: "dry-run", type: "boolean", description: "Preview only; write nothing." },
|
|
49514
|
+
KIND_FLAG,
|
|
49515
|
+
{
|
|
49516
|
+
name: "destination",
|
|
49517
|
+
type: "string",
|
|
49518
|
+
description: "The section for an unknown word instead of a kind: habits, animals, health, journal."
|
|
49519
|
+
}
|
|
49520
|
+
],
|
|
49521
|
+
scopes: [...logOperations.write.scopes],
|
|
49522
|
+
returns: "LogWriteResult",
|
|
49523
|
+
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.`
|
|
49524
|
+
},
|
|
49525
|
+
run: async ({ args, flags, requireClient }) => {
|
|
49526
|
+
const text = args.join(" ").trim();
|
|
49527
|
+
if (!text)
|
|
49528
|
+
throw usageError('log needs a line, e.g. `do log "pages 34"`');
|
|
49529
|
+
const kind = flagString(flags, "kind");
|
|
49530
|
+
const destination = flagString(flags, "destination");
|
|
49531
|
+
const client = requireClient();
|
|
49532
|
+
const preview = await client.post(pathOf(logOperations.preview), { text });
|
|
49533
|
+
if (flagBool(flags, "dry-run"))
|
|
49534
|
+
return { data: preview, render: renderPreview };
|
|
49535
|
+
if (preview.needsKind && !kind && !destination) {
|
|
49536
|
+
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);
|
|
49537
|
+
}
|
|
49538
|
+
const written = await client.post(pathOf(logOperations.write), {
|
|
49539
|
+
text,
|
|
49540
|
+
...kind ? { kind } : {},
|
|
49541
|
+
...destination ? { destination } : {}
|
|
49542
|
+
});
|
|
49543
|
+
return { data: written, render: renderWritten };
|
|
49544
|
+
}
|
|
49545
|
+
},
|
|
49546
|
+
{
|
|
49547
|
+
spec: {
|
|
49548
|
+
path: ["log", "list"],
|
|
49549
|
+
summary: "What was logged through Log something on a day (today by default).",
|
|
49550
|
+
args: [],
|
|
49551
|
+
flags: [{ name: "day", type: "string", description: "The day, YYYY-MM-DD." }],
|
|
49552
|
+
scopes: [...logOperations.list.scopes],
|
|
49553
|
+
returns: "LogEntryView[]",
|
|
49554
|
+
notes: `${routeOf(logOperations.list)}. Health and Journal lines show only to their member.`
|
|
49555
|
+
},
|
|
49556
|
+
run: async ({ flags, requireClient }) => ({
|
|
49557
|
+
data: await requireClient().get(pathOf(logOperations.list), {
|
|
49558
|
+
query: { day: flagString(flags, "day") }
|
|
49559
|
+
}),
|
|
49560
|
+
render: renderLogged
|
|
49561
|
+
})
|
|
49562
|
+
},
|
|
49563
|
+
{
|
|
49564
|
+
spec: {
|
|
49565
|
+
path: ["log", "kinds"],
|
|
49566
|
+
summary: "The kinds this Space logs, and where each is kept.",
|
|
49567
|
+
args: [],
|
|
49568
|
+
flags: [],
|
|
49569
|
+
scopes: [...logOperations.kinds.scopes],
|
|
49570
|
+
returns: "LogKindView[]",
|
|
49571
|
+
notes: routeOf(logOperations.kinds)
|
|
49572
|
+
},
|
|
49573
|
+
run: async ({ requireClient }) => ({
|
|
49574
|
+
data: await requireClient().get(pathOf(logOperations.kinds)),
|
|
49575
|
+
render: renderRecord
|
|
49576
|
+
})
|
|
49577
|
+
}
|
|
49578
|
+
];
|
|
49579
|
+
|
|
48233
49580
|
// src/commands/mail-campaigns.ts
|
|
48234
|
-
var
|
|
49581
|
+
var commands28 = [
|
|
48235
49582
|
{
|
|
48236
49583
|
spec: {
|
|
48237
49584
|
path: ["mail-campaigns", "list"],
|
|
@@ -48546,7 +49893,7 @@ async function serveMcp(io, target) {
|
|
|
48546
49893
|
}
|
|
48547
49894
|
|
|
48548
49895
|
// src/commands/mcp.ts
|
|
48549
|
-
var
|
|
49896
|
+
var commands29 = [
|
|
48550
49897
|
{
|
|
48551
49898
|
spec: {
|
|
48552
49899
|
path: ["mcp"],
|
|
@@ -48591,7 +49938,7 @@ var commands27 = [
|
|
|
48591
49938
|
];
|
|
48592
49939
|
|
|
48593
49940
|
// src/commands/members.ts
|
|
48594
|
-
var
|
|
49941
|
+
var commands30 = [
|
|
48595
49942
|
{
|
|
48596
49943
|
spec: {
|
|
48597
49944
|
path: ["invite", "create"],
|
|
@@ -48716,7 +50063,7 @@ var commands28 = [
|
|
|
48716
50063
|
];
|
|
48717
50064
|
|
|
48718
50065
|
// src/commands/metrics.ts
|
|
48719
|
-
var
|
|
50066
|
+
var commands31 = [
|
|
48720
50067
|
{
|
|
48721
50068
|
spec: {
|
|
48722
50069
|
path: ["metrics", "list"],
|
|
@@ -48844,7 +50191,7 @@ async function setModuleVisibility(args, requireClient, on) {
|
|
|
48844
50191
|
render: renderRecord
|
|
48845
50192
|
};
|
|
48846
50193
|
}
|
|
48847
|
-
var
|
|
50194
|
+
var commands32 = [
|
|
48848
50195
|
{
|
|
48849
50196
|
spec: {
|
|
48850
50197
|
path: ["modules", "list"],
|
|
@@ -49068,7 +50415,7 @@ function shareFlag(flags) {
|
|
|
49068
50415
|
function localMonth(now) {
|
|
49069
50416
|
return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}`;
|
|
49070
50417
|
}
|
|
49071
|
-
var
|
|
50418
|
+
var commands33 = [
|
|
49072
50419
|
defineCommand({
|
|
49073
50420
|
operation: moneyOperations.listAccounts,
|
|
49074
50421
|
path: ["money", "accounts"],
|
|
@@ -50210,7 +51557,7 @@ var commands31 = [
|
|
|
50210
51557
|
];
|
|
50211
51558
|
|
|
50212
51559
|
// src/commands/notes.ts
|
|
50213
|
-
var
|
|
51560
|
+
var commands34 = [
|
|
50214
51561
|
{
|
|
50215
51562
|
spec: {
|
|
50216
51563
|
path: ["notes", "backlinks"],
|
|
@@ -50332,7 +51679,7 @@ var commands32 = [
|
|
|
50332
51679
|
];
|
|
50333
51680
|
|
|
50334
51681
|
// src/commands/orca.ts
|
|
50335
|
-
var
|
|
51682
|
+
var commands35 = [
|
|
50336
51683
|
{
|
|
50337
51684
|
spec: {
|
|
50338
51685
|
path: ["orca", "list"],
|
|
@@ -50662,7 +52009,7 @@ function linkBody(args) {
|
|
|
50662
52009
|
return parseInput(familyTreeLinkInputSchema, { kind, a: ref, b: other });
|
|
50663
52010
|
throw usageError("the kind is parent, child or partner");
|
|
50664
52011
|
}
|
|
50665
|
-
var
|
|
52012
|
+
var commands36 = [
|
|
50666
52013
|
{
|
|
50667
52014
|
spec: {
|
|
50668
52015
|
path: ["people", "propose"],
|
|
@@ -51351,7 +52698,7 @@ var commands34 = [
|
|
|
51351
52698
|
|
|
51352
52699
|
// src/commands/places.ts
|
|
51353
52700
|
import { readFileSync as readFileSync10 } from "fs";
|
|
51354
|
-
var
|
|
52701
|
+
var commands37 = [
|
|
51355
52702
|
{
|
|
51356
52703
|
spec: {
|
|
51357
52704
|
path: ["places", "import"],
|
|
@@ -51408,7 +52755,7 @@ async function planDecision({ args, requireClient }, verb) {
|
|
|
51408
52755
|
render: renderPlan
|
|
51409
52756
|
};
|
|
51410
52757
|
}
|
|
51411
|
-
var
|
|
52758
|
+
var commands38 = [
|
|
51412
52759
|
{
|
|
51413
52760
|
spec: {
|
|
51414
52761
|
path: ["plans", "list"],
|
|
@@ -51635,7 +52982,7 @@ var commands36 = [
|
|
|
51635
52982
|
];
|
|
51636
52983
|
|
|
51637
52984
|
// src/commands/presets.ts
|
|
51638
|
-
var
|
|
52985
|
+
var commands39 = [
|
|
51639
52986
|
{
|
|
51640
52987
|
spec: {
|
|
51641
52988
|
path: ["presets", "list"],
|
|
@@ -51689,7 +53036,50 @@ var commands37 = [
|
|
|
51689
53036
|
];
|
|
51690
53037
|
|
|
51691
53038
|
// src/commands/progress.ts
|
|
51692
|
-
var
|
|
53039
|
+
var MARK = {
|
|
53040
|
+
done: "\u25CF",
|
|
53041
|
+
missed: "\u2715",
|
|
53042
|
+
open: "\u25CB",
|
|
53043
|
+
later: "\xB7",
|
|
53044
|
+
not_due: " "
|
|
53045
|
+
};
|
|
53046
|
+
var signed = (n) => n > 0 ? `+${n}` : String(n);
|
|
53047
|
+
function renderReviewSummary(data, mode) {
|
|
53048
|
+
const r = data;
|
|
53049
|
+
const n = r.numbers;
|
|
53050
|
+
const out = [
|
|
53051
|
+
paint(mode, "bold", `${r.label} \xB7 ${r.rangeLabel}`),
|
|
53052
|
+
` Tasks done ${n.tasksDone} (${signed(n.tasksDoneDelta)} on the ${r.span} before)`,
|
|
53053
|
+
` Habits ${n.habitTicks} of ${n.habitDue} due`,
|
|
53054
|
+
` Projects ${n.projectsMoved} moved \xB7 Challenges ${n.challengesRunning} running`,
|
|
53055
|
+
"",
|
|
53056
|
+
paint(mode, "bold", "Last 8")
|
|
53057
|
+
];
|
|
53058
|
+
const keyWidth = Math.max(0, ...r.series.map((p) => p.key.length));
|
|
53059
|
+
for (const p of r.series) {
|
|
53060
|
+
const row = ` ${p.key.padEnd(keyWidth)} ${String(p.tasksDone).padStart(3)} tasks ${String(p.habitTicks).padStart(3)} habits`;
|
|
53061
|
+
out.push(p.current ? paint(mode, "cyan", row) : row);
|
|
53062
|
+
}
|
|
53063
|
+
out.push("", paint(mode, "bold", "Streaks"));
|
|
53064
|
+
if (r.streaks.length === 0)
|
|
53065
|
+
out.push(paint(mode, "dim", " (no habits yet)"));
|
|
53066
|
+
const titleWidth = Math.max(0, ...r.streaks.map((s) => s.title.length));
|
|
53067
|
+
for (const s of r.streaks) {
|
|
53068
|
+
const marks = s.marks.map((m) => MARK[m.state]).join(" ");
|
|
53069
|
+
out.push(` ${s.title.padEnd(titleWidth)} ${s.unitLabel} \xB7 best ${s.best} ${marks} ${paint(mode, "dim", s.scheduleLabel)}`);
|
|
53070
|
+
}
|
|
53071
|
+
out.push("", paint(mode, "bold", "Projects"));
|
|
53072
|
+
if (r.projects.length === 0)
|
|
53073
|
+
out.push(paint(mode, "dim", " (no open projects)"));
|
|
53074
|
+
const projectWidth = Math.max(0, ...r.projects.map((p) => p.title.length));
|
|
53075
|
+
for (const p of r.projects) {
|
|
53076
|
+
const target = p.targetDate ? paint(mode, "dim", ` \xB7 by ${p.targetDate}`) : "";
|
|
53077
|
+
out.push(` ${p.title.padEnd(projectWidth)} ${p.done} of ${p.total} tasks${target}`);
|
|
53078
|
+
}
|
|
53079
|
+
return out.join(`
|
|
53080
|
+
`);
|
|
53081
|
+
}
|
|
53082
|
+
var commands40 = [
|
|
51693
53083
|
{
|
|
51694
53084
|
spec: {
|
|
51695
53085
|
path: ["progress"],
|
|
@@ -51709,6 +53099,38 @@ var commands38 = [
|
|
|
51709
53099
|
render: renderProgress
|
|
51710
53100
|
})
|
|
51711
53101
|
},
|
|
53102
|
+
{
|
|
53103
|
+
spec: {
|
|
53104
|
+
path: ["review", "summary"],
|
|
53105
|
+
summary: "Plan > Review: the week's or month's numbers, the last 8 periods, habit streaks and open projects.",
|
|
53106
|
+
args: [],
|
|
53107
|
+
flags: [
|
|
53108
|
+
{ name: "span", type: "string", description: "week (default) or month." },
|
|
53109
|
+
{
|
|
53110
|
+
name: "date",
|
|
53111
|
+
type: "string",
|
|
53112
|
+
description: "A day in the period, YYYY-MM-DD; default today."
|
|
53113
|
+
}
|
|
53114
|
+
],
|
|
53115
|
+
scopes: [...progressOperations.review.scopes],
|
|
53116
|
+
returns: "ReviewSummary",
|
|
53117
|
+
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.`
|
|
53118
|
+
},
|
|
53119
|
+
run: async ({ flags, requireClient }) => {
|
|
53120
|
+
const span = flagString(flags, "span");
|
|
53121
|
+
const date = flagString(flags, "date");
|
|
53122
|
+
const query = parseInput(reviewSummaryQuerySchema, {
|
|
53123
|
+
...span ? { span } : {},
|
|
53124
|
+
...date ? { date } : {}
|
|
53125
|
+
});
|
|
53126
|
+
return {
|
|
53127
|
+
data: await requireClient().get(pathOf(progressOperations.review), {
|
|
53128
|
+
query: { span: query.span, ...query.date ? { date: query.date } : {} }
|
|
53129
|
+
}),
|
|
53130
|
+
render: renderReviewSummary
|
|
53131
|
+
};
|
|
53132
|
+
}
|
|
53133
|
+
},
|
|
51712
53134
|
{
|
|
51713
53135
|
spec: {
|
|
51714
53136
|
path: ["progress", "day"],
|
|
@@ -51842,8 +53264,281 @@ var commands38 = [
|
|
|
51842
53264
|
}
|
|
51843
53265
|
];
|
|
51844
53266
|
|
|
53267
|
+
// src/commands/projects.ts
|
|
53268
|
+
var PROJECT_ARG = {
|
|
53269
|
+
name: "id",
|
|
53270
|
+
required: true,
|
|
53271
|
+
description: "Project ref (DO-P7, any case) or ULID."
|
|
53272
|
+
};
|
|
53273
|
+
var UPDATE_STATUSES = projectUpdateStatusSchema.options.map((s) => s.replace(/_/g, "-"));
|
|
53274
|
+
function updateStatus(raw) {
|
|
53275
|
+
return raw.trim().toLowerCase().replace(/[-\s]+/g, "_");
|
|
53276
|
+
}
|
|
53277
|
+
function updateLine(u, mode) {
|
|
53278
|
+
const date = (u.createdAt ?? "").slice(0, 10);
|
|
53279
|
+
const status = (u.status ?? "").replace(/_/g, "-");
|
|
53280
|
+
const body = u.body ? ` ${u.body}` : "";
|
|
53281
|
+
const by = u.authorName ? paint(mode, "dim", ` \u2014 ${u.authorName}`) : "";
|
|
53282
|
+
return `${date} ${paint(mode, "bold", status)}${body}${by}`;
|
|
53283
|
+
}
|
|
53284
|
+
function renderUpdates(data, mode) {
|
|
53285
|
+
const updates = data ?? [];
|
|
53286
|
+
if (updates.length === 0)
|
|
53287
|
+
return paint(mode, "dim", "No updates yet.");
|
|
53288
|
+
return updates.map((u) => updateLine(u, mode)).join(`
|
|
53289
|
+
`);
|
|
53290
|
+
}
|
|
53291
|
+
var commands41 = [
|
|
53292
|
+
defineCommand({
|
|
53293
|
+
operation: projectOperations.update,
|
|
53294
|
+
path: ["projects", "set"],
|
|
53295
|
+
summary: "Set a project's priority.",
|
|
53296
|
+
returns: "ProjectView",
|
|
53297
|
+
args: [PROJECT_ARG],
|
|
53298
|
+
flags: [{ name: "priority", type: "string", description: "none, low, medium or high." }],
|
|
53299
|
+
run: async ({ args, flags, requireClient }) => {
|
|
53300
|
+
const id = requireArg(args, 0, "project id");
|
|
53301
|
+
const priority = flagString(flags, "priority");
|
|
53302
|
+
if (priority === undefined)
|
|
53303
|
+
throw usageError("projects set needs --priority");
|
|
53304
|
+
const body = parseInput(updateProjectInputSchema, {
|
|
53305
|
+
priority: priority.trim().toLowerCase()
|
|
53306
|
+
});
|
|
53307
|
+
return {
|
|
53308
|
+
data: await requireClient().patch(pathOf(projectOperations.update, { id }), body),
|
|
53309
|
+
render: renderRecord
|
|
53310
|
+
};
|
|
53311
|
+
}
|
|
53312
|
+
}),
|
|
53313
|
+
defineCommand({
|
|
53314
|
+
operation: projectOperations.createUpdate,
|
|
53315
|
+
path: ["projects", "update"],
|
|
53316
|
+
summary: "Post a project update (--status and a note), or change the project (--data, --leads).",
|
|
53317
|
+
returns: "ProjectUpdateView",
|
|
53318
|
+
args: [
|
|
53319
|
+
PROJECT_ARG,
|
|
53320
|
+
{ name: "note", required: false, description: "The update's note (up to 2000 characters)." }
|
|
53321
|
+
],
|
|
53322
|
+
flags: [
|
|
53323
|
+
{
|
|
53324
|
+
name: "status",
|
|
53325
|
+
type: "string",
|
|
53326
|
+
description: `Post an update with this status: ${UPDATE_STATUSES.join(", ")}.`
|
|
53327
|
+
},
|
|
53328
|
+
{
|
|
53329
|
+
name: "data",
|
|
53330
|
+
type: "string",
|
|
53331
|
+
description: "UpdateProjectInput as JSON, or @path to read it from a file."
|
|
53332
|
+
},
|
|
53333
|
+
{
|
|
53334
|
+
name: "leads",
|
|
53335
|
+
type: "string",
|
|
53336
|
+
description: "The project's leads, as member user ids, comma-separated; '' clears them."
|
|
53337
|
+
},
|
|
53338
|
+
{ name: "dry-run", type: "boolean", description: "Show the change, send nothing." }
|
|
53339
|
+
],
|
|
53340
|
+
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>`.",
|
|
53341
|
+
run: async ({ args, flags, requireClient }) => {
|
|
53342
|
+
const id = requireArg(args, 0, "project id");
|
|
53343
|
+
const note = args.slice(1).join(" ");
|
|
53344
|
+
const status = flagString(flags, "status");
|
|
53345
|
+
const leads = flagString(flags, "leads");
|
|
53346
|
+
const dryRun = flagBool(flags, "dry-run");
|
|
53347
|
+
if (status !== undefined) {
|
|
53348
|
+
if (flags.data !== undefined || leads !== undefined) {
|
|
53349
|
+
throw usageError("--status posts an update; change the project in a separate call");
|
|
53350
|
+
}
|
|
53351
|
+
const body = parseInput(createProjectUpdateInputSchema, {
|
|
53352
|
+
status: updateStatus(status),
|
|
53353
|
+
body: note
|
|
53354
|
+
});
|
|
53355
|
+
if (dryRun) {
|
|
53356
|
+
return {
|
|
53357
|
+
data: { dryRun: true, op: "create", entity: "project update", id, after: body },
|
|
53358
|
+
render: renderRecord
|
|
53359
|
+
};
|
|
53360
|
+
}
|
|
53361
|
+
return {
|
|
53362
|
+
data: await requireClient().post(pathOf(projectOperations.createUpdate, { id }), body),
|
|
53363
|
+
render: (data, mode) => updateLine(data, mode)
|
|
53364
|
+
};
|
|
53365
|
+
}
|
|
53366
|
+
if (note)
|
|
53367
|
+
throw usageError("a note needs --status (on-track, at-risk, \u2026)");
|
|
53368
|
+
const fields = readDataFlag(flags);
|
|
53369
|
+
if (leads !== undefined) {
|
|
53370
|
+
fields.leadUserIds = leads.split(",").map((s) => s.trim()).filter(Boolean);
|
|
53371
|
+
}
|
|
53372
|
+
const body = parseInput(updateProjectInputSchema, fields);
|
|
53373
|
+
if (Object.keys(body).length === 0) {
|
|
53374
|
+
throw usageError("nothing to change \u2014 pass --status, --data or --leads");
|
|
53375
|
+
}
|
|
53376
|
+
const client = requireClient();
|
|
53377
|
+
if (dryRun) {
|
|
53378
|
+
const before = await client.get(pathOf(projectOperations.get, { id }));
|
|
53379
|
+
return {
|
|
53380
|
+
data: {
|
|
53381
|
+
dryRun: true,
|
|
53382
|
+
op: "update",
|
|
53383
|
+
entity: "projects",
|
|
53384
|
+
id,
|
|
53385
|
+
before,
|
|
53386
|
+
after: mergePreview(before, body),
|
|
53387
|
+
changes: body
|
|
53388
|
+
},
|
|
53389
|
+
render: renderRecord
|
|
53390
|
+
};
|
|
53391
|
+
}
|
|
53392
|
+
return {
|
|
53393
|
+
data: await client.patch(pathOf(projectOperations.update, { id }), body),
|
|
53394
|
+
render: renderRecord
|
|
53395
|
+
};
|
|
53396
|
+
}
|
|
53397
|
+
}),
|
|
53398
|
+
defineCommand({
|
|
53399
|
+
operation: projectOperations.listUpdates,
|
|
53400
|
+
path: ["projects", "updates"],
|
|
53401
|
+
summary: "A project's updates, newest first.",
|
|
53402
|
+
returns: "ProjectUpdateView[]",
|
|
53403
|
+
args: [PROJECT_ARG],
|
|
53404
|
+
run: async ({ args, requireClient }) => {
|
|
53405
|
+
const id = requireArg(args, 0, "project id");
|
|
53406
|
+
return {
|
|
53407
|
+
data: await requireClient().get(pathOf(projectOperations.listUpdates, { id })),
|
|
53408
|
+
render: renderUpdates
|
|
53409
|
+
};
|
|
53410
|
+
}
|
|
53411
|
+
}),
|
|
53412
|
+
defineCommand({
|
|
53413
|
+
operation: projectOperations.removeUpdate,
|
|
53414
|
+
path: ["projects", "delete-update"],
|
|
53415
|
+
summary: "Delete one of your own updates on a project.",
|
|
53416
|
+
returns: "void",
|
|
53417
|
+
args: [PROJECT_ARG, { name: "updateId", required: true, description: "The update's ULID." }],
|
|
53418
|
+
notes: ". Needs --allow-destructive; only the update's author (the member or the Agent) may.",
|
|
53419
|
+
run: async ({ args, flags, requireClient }) => {
|
|
53420
|
+
const id = requireArg(args, 0, "project id");
|
|
53421
|
+
const updateId = requireArg(args, 1, "update id");
|
|
53422
|
+
assertDestructiveAllowed(flags, `delete update ${updateId} on ${id}`);
|
|
53423
|
+
await requireClient().delete(pathOf(projectOperations.removeUpdate, { id, updateId }));
|
|
53424
|
+
return { data: { ok: true, deleted: updateId }, render: renderRecord };
|
|
53425
|
+
}
|
|
53426
|
+
})
|
|
53427
|
+
];
|
|
53428
|
+
|
|
53429
|
+
// src/commands/routines.ts
|
|
53430
|
+
var STATE_WORDS = {
|
|
53431
|
+
done: "done",
|
|
53432
|
+
running: "under way",
|
|
53433
|
+
upcoming: "to come",
|
|
53434
|
+
resting: "resting"
|
|
53435
|
+
};
|
|
53436
|
+
function renderRoutinesToday(data, mode) {
|
|
53437
|
+
const d = data;
|
|
53438
|
+
const list = d.routines ?? [];
|
|
53439
|
+
if (list.length === 0)
|
|
53440
|
+
return "No routines today.";
|
|
53441
|
+
return list.map((r) => {
|
|
53442
|
+
const progress = r.run ? ` \xB7 ${r.run.done}/${r.run.total}` : "";
|
|
53443
|
+
const head = `${r.start ?? "--:--"} ${r.title} ${paint(mode, "dim", `${STATE_WORDS[r.state] ?? r.state}${progress} ${r.id}`)}`;
|
|
53444
|
+
const steps = r.steps.map((s) => {
|
|
53445
|
+
const meta = s.meta ? paint(mode, "dim", ` \xB7 ${s.meta}`) : "";
|
|
53446
|
+
const kind = s.kind === "step" ? "" : ` [${s.kind}]`;
|
|
53447
|
+
return ` ${s.done ? "\u2713" : "\u25CB"} ${s.n}. ${s.title}${kind}${meta}`;
|
|
53448
|
+
});
|
|
53449
|
+
return [head, ...steps].join(`
|
|
53450
|
+
`);
|
|
53451
|
+
}).join(`
|
|
53452
|
+
`);
|
|
53453
|
+
}
|
|
53454
|
+
function renderRoutineTaskAdded(data) {
|
|
53455
|
+
const run = data;
|
|
53456
|
+
const last = run.steps?.at(-1)?.title ?? "the task";
|
|
53457
|
+
return `${run.routineTitle ?? "(routine)"}: ${last} is the last step of today's run.`;
|
|
53458
|
+
}
|
|
53459
|
+
var commands42 = [
|
|
53460
|
+
{
|
|
53461
|
+
spec: {
|
|
53462
|
+
path: ["routines", "today"],
|
|
53463
|
+
summary: "Today's routines by start: their state, steps (step, habit, task) and 14 days.",
|
|
53464
|
+
args: [],
|
|
53465
|
+
flags: [],
|
|
53466
|
+
scopes: [...routineOperations.today.scopes],
|
|
53467
|
+
returns: "RoutinesTodayResult",
|
|
53468
|
+
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).`
|
|
53469
|
+
},
|
|
53470
|
+
run: async ({ requireClient }) => ({
|
|
53471
|
+
data: await requireClient().get(pathOf(routineOperations.today)),
|
|
53472
|
+
render: renderRoutinesToday
|
|
53473
|
+
})
|
|
53474
|
+
},
|
|
53475
|
+
{
|
|
53476
|
+
spec: {
|
|
53477
|
+
path: ["routines", "add-task"],
|
|
53478
|
+
summary: "Add a Work task due today to the end of today's run of a routine.",
|
|
53479
|
+
args: [
|
|
53480
|
+
{ name: "id", required: true, description: "Routine ULID (`do routines today`)." },
|
|
53481
|
+
{ name: "task", required: true, description: "Task ULID; it must be due today." }
|
|
53482
|
+
],
|
|
53483
|
+
flags: [
|
|
53484
|
+
{
|
|
53485
|
+
name: "reason",
|
|
53486
|
+
type: "string",
|
|
53487
|
+
description: 'The line shown with it ("Call the plumber is due today in Work, so I added it to the end of this routine.").'
|
|
53488
|
+
}
|
|
53489
|
+
],
|
|
53490
|
+
scopes: [...routineOperations.addTaskStep.scopes],
|
|
53491
|
+
returns: "RoutineRunView",
|
|
53492
|
+
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.`
|
|
53493
|
+
},
|
|
53494
|
+
run: async ({ args, flags, requireClient }) => {
|
|
53495
|
+
const id = requireArg(args, 0, "routine id");
|
|
53496
|
+
const taskId = requireArg(args, 1, "task id");
|
|
53497
|
+
const reason = flagString(flags, "reason");
|
|
53498
|
+
const input = parseInput(addRoutineTaskStepInputSchema, {
|
|
53499
|
+
taskId,
|
|
53500
|
+
...reason !== undefined ? { reason } : {}
|
|
53501
|
+
});
|
|
53502
|
+
return {
|
|
53503
|
+
data: await requireClient().post(pathOf(routineOperations.addTaskStep, { id }), input),
|
|
53504
|
+
render: renderRoutineTaskAdded
|
|
53505
|
+
};
|
|
53506
|
+
}
|
|
53507
|
+
},
|
|
53508
|
+
{
|
|
53509
|
+
spec: {
|
|
53510
|
+
path: ["routines", "reorder"],
|
|
53511
|
+
summary: "Put a routine's steps in a new order.",
|
|
53512
|
+
args: [
|
|
53513
|
+
{ name: "id", required: true, description: "Routine ULID." },
|
|
53514
|
+
{
|
|
53515
|
+
name: "steps",
|
|
53516
|
+
required: true,
|
|
53517
|
+
description: "Every step ULID of the routine, in the new order, space- or comma-separated."
|
|
53518
|
+
}
|
|
53519
|
+
],
|
|
53520
|
+
flags: [],
|
|
53521
|
+
scopes: [...routineOperations.reorderSteps.scopes],
|
|
53522
|
+
returns: "RoutineView",
|
|
53523
|
+
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.`
|
|
53524
|
+
},
|
|
53525
|
+
run: async ({ args, requireClient }) => {
|
|
53526
|
+
const id = requireArg(args, 0, "routine id");
|
|
53527
|
+
const stepIds = args.slice(1).flatMap((a) => a.split(",")).map((s) => s.trim()).filter(Boolean);
|
|
53528
|
+
if (stepIds.length === 0) {
|
|
53529
|
+
throw usageError("routines reorder needs the step ids in their new order, e.g. `do routines reorder <routine> <step> <step>`");
|
|
53530
|
+
}
|
|
53531
|
+
const input = parseInput(reorderRoutineStepsInputSchema, { stepIds });
|
|
53532
|
+
return {
|
|
53533
|
+
data: await requireClient().patch(pathOf(routineOperations.reorderSteps, { id }), input),
|
|
53534
|
+
render: (data) => `${data.title ?? "(routine)"}: steps reordered.`
|
|
53535
|
+
};
|
|
53536
|
+
}
|
|
53537
|
+
}
|
|
53538
|
+
];
|
|
53539
|
+
|
|
51845
53540
|
// src/commands/rsvp-answers.ts
|
|
51846
|
-
var
|
|
53541
|
+
var commands43 = [
|
|
51847
53542
|
{
|
|
51848
53543
|
spec: {
|
|
51849
53544
|
path: ["rsvp-answers", "list"],
|
|
@@ -51897,7 +53592,7 @@ var commands39 = [
|
|
|
51897
53592
|
];
|
|
51898
53593
|
|
|
51899
53594
|
// src/commands/rsvp-links.ts
|
|
51900
|
-
var
|
|
53595
|
+
var commands44 = [
|
|
51901
53596
|
{
|
|
51902
53597
|
spec: {
|
|
51903
53598
|
path: ["rsvp-links", "list"],
|
|
@@ -51993,7 +53688,7 @@ var commands40 = [
|
|
|
51993
53688
|
];
|
|
51994
53689
|
|
|
51995
53690
|
// src/commands/rsvp-questions.ts
|
|
51996
|
-
var
|
|
53691
|
+
var commands45 = [
|
|
51997
53692
|
{
|
|
51998
53693
|
spec: {
|
|
51999
53694
|
path: ["rsvp-questions", "presets"],
|
|
@@ -52565,7 +54260,7 @@ function sessionFlags(flags) {
|
|
|
52565
54260
|
body.occurredOn = on;
|
|
52566
54261
|
return body;
|
|
52567
54262
|
}
|
|
52568
|
-
var
|
|
54263
|
+
var commands46 = [
|
|
52569
54264
|
{
|
|
52570
54265
|
spec: {
|
|
52571
54266
|
path: ["runs", "change"],
|
|
@@ -52882,7 +54577,7 @@ var commands42 = [
|
|
|
52882
54577
|
];
|
|
52883
54578
|
|
|
52884
54579
|
// src/commands/search.ts
|
|
52885
|
-
var
|
|
54580
|
+
var commands47 = [
|
|
52886
54581
|
{
|
|
52887
54582
|
spec: {
|
|
52888
54583
|
path: ["search"],
|
|
@@ -52915,7 +54610,7 @@ var commands43 = [
|
|
|
52915
54610
|
];
|
|
52916
54611
|
|
|
52917
54612
|
// src/commands/seating-proposals.ts
|
|
52918
|
-
var
|
|
54613
|
+
var commands48 = [
|
|
52919
54614
|
{
|
|
52920
54615
|
spec: {
|
|
52921
54616
|
path: ["seating-proposals", "list"],
|
|
@@ -53002,7 +54697,7 @@ var commands44 = [
|
|
|
53002
54697
|
];
|
|
53003
54698
|
|
|
53004
54699
|
// src/commands/sensors.ts
|
|
53005
|
-
var
|
|
54700
|
+
var commands49 = [
|
|
53006
54701
|
{
|
|
53007
54702
|
spec: {
|
|
53008
54703
|
path: ["sensors", "status"],
|
|
@@ -53162,7 +54857,7 @@ var commands45 = [
|
|
|
53162
54857
|
];
|
|
53163
54858
|
|
|
53164
54859
|
// src/commands/settings.ts
|
|
53165
|
-
var
|
|
54860
|
+
var commands50 = [
|
|
53166
54861
|
{
|
|
53167
54862
|
spec: {
|
|
53168
54863
|
path: ["settings", "get"],
|
|
@@ -53195,7 +54890,7 @@ var commands46 = [
|
|
|
53195
54890
|
];
|
|
53196
54891
|
|
|
53197
54892
|
// src/commands/sharing.ts
|
|
53198
|
-
var
|
|
54893
|
+
var commands51 = [
|
|
53199
54894
|
{
|
|
53200
54895
|
spec: {
|
|
53201
54896
|
path: ["share"],
|
|
@@ -53328,7 +55023,7 @@ var commands47 = [
|
|
|
53328
55023
|
];
|
|
53329
55024
|
|
|
53330
55025
|
// src/commands/tap-tags.ts
|
|
53331
|
-
var
|
|
55026
|
+
var commands52 = [
|
|
53332
55027
|
{
|
|
53333
55028
|
spec: {
|
|
53334
55029
|
path: ["tap-tags", "tap"],
|
|
@@ -53349,6 +55044,48 @@ var commands48 = [
|
|
|
53349
55044
|
}
|
|
53350
55045
|
];
|
|
53351
55046
|
|
|
55047
|
+
// src/commands/task-blocks.ts
|
|
55048
|
+
var ID2 = { name: "id", required: true, description: "The blocked task's ref (DO-148) or ULID." };
|
|
55049
|
+
var BY = {
|
|
55050
|
+
name: "by",
|
|
55051
|
+
type: "string",
|
|
55052
|
+
description: "The blocking task's ref (DO-147) or ULID."
|
|
55053
|
+
};
|
|
55054
|
+
var commands53 = [
|
|
55055
|
+
defineCommand({
|
|
55056
|
+
operation: taskBlockOperations.addBlocker,
|
|
55057
|
+
path: ["tasks", "block"],
|
|
55058
|
+
summary: "Block a task by another, until that one is Done.",
|
|
55059
|
+
args: [ID2],
|
|
55060
|
+
flags: [BY],
|
|
55061
|
+
notes: " \u2014 a self-link or a loop (two tasks waiting on each other) is refused.",
|
|
55062
|
+
run: async ({ args, flags, requireClient }) => {
|
|
55063
|
+
const id = requireArg(args, 0, "task id");
|
|
55064
|
+
const by = requireFlag(flags, "by", "tasks block needs --by <task>");
|
|
55065
|
+
const body = parseInput(addTaskBlockerInputSchema, { taskId: by });
|
|
55066
|
+
return {
|
|
55067
|
+
data: await requireClient().post(pathOf(taskBlockOperations.addBlocker, { id }), body),
|
|
55068
|
+
render: renderTask
|
|
55069
|
+
};
|
|
55070
|
+
}
|
|
55071
|
+
}),
|
|
55072
|
+
defineCommand({
|
|
55073
|
+
operation: taskBlockOperations.removeBlocker,
|
|
55074
|
+
path: ["tasks", "unblock"],
|
|
55075
|
+
summary: "Lift a block: the other task no longer blocks this one.",
|
|
55076
|
+
args: [ID2],
|
|
55077
|
+
flags: [BY],
|
|
55078
|
+
run: async ({ args, flags, requireClient }) => {
|
|
55079
|
+
const id = requireArg(args, 0, "task id");
|
|
55080
|
+
const blockerId = requireFlag(flags, "by", "tasks unblock needs --by <task>");
|
|
55081
|
+
return {
|
|
55082
|
+
data: await requireClient().delete(pathOf(taskBlockOperations.removeBlocker, { id, blockerId })),
|
|
55083
|
+
render: renderTask
|
|
55084
|
+
};
|
|
55085
|
+
}
|
|
55086
|
+
})
|
|
55087
|
+
];
|
|
55088
|
+
|
|
53352
55089
|
// src/capture.ts
|
|
53353
55090
|
function parseCapture2(input, now) {
|
|
53354
55091
|
const parsed = parseCapture(input, now);
|
|
@@ -53359,7 +55096,7 @@ function parseCapture2(input, now) {
|
|
|
53359
55096
|
}
|
|
53360
55097
|
|
|
53361
55098
|
// src/commands/tasks.ts
|
|
53362
|
-
var
|
|
55099
|
+
var commands54 = [
|
|
53363
55100
|
{
|
|
53364
55101
|
spec: {
|
|
53365
55102
|
path: ["capture"],
|
|
@@ -53438,7 +55175,7 @@ var commands49 = [
|
|
|
53438
55175
|
spec: {
|
|
53439
55176
|
path: ["task", "done"],
|
|
53440
55177
|
summary: "Mark a task done (idempotent \u2014 a no-op success if already done).",
|
|
53441
|
-
args: [{ name: "id", required: true, description: "Task ULID." }],
|
|
55178
|
+
args: [{ name: "id", required: true, description: "Task ULID or ref (DO-142)." }],
|
|
53442
55179
|
flags: [
|
|
53443
55180
|
{
|
|
53444
55181
|
name: "at",
|
|
@@ -53471,7 +55208,7 @@ var commands49 = [
|
|
|
53471
55208
|
spec: {
|
|
53472
55209
|
path: ["task", "cancel"],
|
|
53473
55210
|
summary: "Drop a task: status cancelled, never counted as Landed.",
|
|
53474
|
-
args: [{ name: "id", required: true, description: "Task ULID." }],
|
|
55211
|
+
args: [{ name: "id", required: true, description: "Task ULID or ref (DO-142)." }],
|
|
53475
55212
|
flags: [],
|
|
53476
55213
|
scopes: [...taskOperations.cancel.scopes],
|
|
53477
55214
|
returns: "Task",
|
|
@@ -53489,7 +55226,7 @@ var commands49 = [
|
|
|
53489
55226
|
spec: {
|
|
53490
55227
|
path: ["tasks", "accept"],
|
|
53491
55228
|
summary: "Accept a task Proposed by the agent: it joins the plan as suggested (day, Deadline, Area kept).",
|
|
53492
|
-
args: [{ name: "id", required: true, description: "Task ULID." }],
|
|
55229
|
+
args: [{ name: "id", required: true, description: "Task ULID or ref (DO-142)." }],
|
|
53493
55230
|
flags: [],
|
|
53494
55231
|
scopes: [...taskOperations.accept.scopes],
|
|
53495
55232
|
returns: "Task",
|
|
@@ -53507,7 +55244,7 @@ var commands49 = [
|
|
|
53507
55244
|
spec: {
|
|
53508
55245
|
path: ["tasks", "dismiss"],
|
|
53509
55246
|
summary: "Not now on a task Proposed by the agent: it leaves the Inbox for a week, still proposed.",
|
|
53510
|
-
args: [{ name: "id", required: true, description: "Task ULID." }],
|
|
55247
|
+
args: [{ name: "id", required: true, description: "Task ULID or ref (DO-142)." }],
|
|
53511
55248
|
flags: [],
|
|
53512
55249
|
scopes: [...taskOperations.notNow.scopes],
|
|
53513
55250
|
returns: "Task",
|
|
@@ -53525,7 +55262,7 @@ var commands49 = [
|
|
|
53525
55262
|
spec: {
|
|
53526
55263
|
path: ["tasks", "ready"],
|
|
53527
55264
|
summary: "Mark a task Ready for you: its Owner finished something the member should look at (a draft, a link, a worktree).",
|
|
53528
|
-
args: [{ name: "id", required: true, description: "Task ULID." }],
|
|
55265
|
+
args: [{ name: "id", required: true, description: "Task ULID or ref (DO-142)." }],
|
|
53529
55266
|
flags: [
|
|
53530
55267
|
{
|
|
53531
55268
|
name: "note",
|
|
@@ -53551,7 +55288,7 @@ var commands49 = [
|
|
|
53551
55288
|
spec: {
|
|
53552
55289
|
path: ["task", "reopen"],
|
|
53553
55290
|
summary: "Reopen a done or cancelled task (status todo; clears completedAt).",
|
|
53554
|
-
args: [{ name: "id", required: true, description: "Task ULID." }],
|
|
55291
|
+
args: [{ name: "id", required: true, description: "Task ULID or ref (DO-142)." }],
|
|
53555
55292
|
flags: [],
|
|
53556
55293
|
scopes: [...taskOperations.update.scopes],
|
|
53557
55294
|
returns: "Task"
|
|
@@ -53569,7 +55306,7 @@ var commands49 = [
|
|
|
53569
55306
|
spec: {
|
|
53570
55307
|
path: ["task", "snooze"],
|
|
53571
55308
|
summary: "Push a task's scheduled date forward.",
|
|
53572
|
-
args: [{ name: "id", required: true, description: "Task ULID." }],
|
|
55309
|
+
args: [{ name: "id", required: true, description: "Task ULID or ref (DO-142)." }],
|
|
53573
55310
|
flags: [
|
|
53574
55311
|
{ name: "days", type: "string", description: "Days from now to reschedule.", default: "1" },
|
|
53575
55312
|
{
|
|
@@ -53606,7 +55343,7 @@ var commands49 = [
|
|
|
53606
55343
|
spec: {
|
|
53607
55344
|
path: ["task", "schedule"],
|
|
53608
55345
|
summary: "Plan a task at a day or a time, so a timed one shows on the calendar.",
|
|
53609
|
-
args: [{ name: "id", required: true, description: "Task ULID." }],
|
|
55346
|
+
args: [{ name: "id", required: true, description: "Task ULID or ref (DO-142)." }],
|
|
53610
55347
|
flags: [
|
|
53611
55348
|
{
|
|
53612
55349
|
name: "at",
|
|
@@ -53664,11 +55401,65 @@ var commands49 = [
|
|
|
53664
55401
|
render: renderRecord
|
|
53665
55402
|
};
|
|
53666
55403
|
}
|
|
53667
|
-
}
|
|
55404
|
+
},
|
|
55405
|
+
defineCommand({
|
|
55406
|
+
operation: taskOperations.get,
|
|
55407
|
+
path: ["tasks", "show"],
|
|
55408
|
+
summary: "Show one task by its ref (DO-142) or ULID.",
|
|
55409
|
+
returns: "Task",
|
|
55410
|
+
args: [{ name: "id", required: true, description: "Task ref (DO-142, any case) or ULID." }],
|
|
55411
|
+
flags: [],
|
|
55412
|
+
run: async ({ args, requireClient }) => {
|
|
55413
|
+
const id = requireArg(args, 0, "task id");
|
|
55414
|
+
return {
|
|
55415
|
+
data: await requireClient().get(pathOf(taskOperations.get, { id })),
|
|
55416
|
+
render: renderTask
|
|
55417
|
+
};
|
|
55418
|
+
}
|
|
55419
|
+
}),
|
|
55420
|
+
defineCommand({
|
|
55421
|
+
operation: taskOperations.update,
|
|
55422
|
+
path: ["tasks", "set"],
|
|
55423
|
+
summary: "Set a task's status, priority or deliverable.",
|
|
55424
|
+
returns: "Task",
|
|
55425
|
+
args: [{ name: "id", required: true, description: "Task ref (DO-142, any case) or ULID." }],
|
|
55426
|
+
flags: [
|
|
55427
|
+
{
|
|
55428
|
+
name: "status",
|
|
55429
|
+
type: "string",
|
|
55430
|
+
description: "backlog, todo, in-progress, waiting or done (cancel drops it: `do task cancel`)."
|
|
55431
|
+
},
|
|
55432
|
+
{ name: "priority", type: "string", description: "none, low, medium or high." },
|
|
55433
|
+
{
|
|
55434
|
+
name: "deliverable",
|
|
55435
|
+
type: "string",
|
|
55436
|
+
description: "What finishing it hands over, in a line; an empty string clears it."
|
|
55437
|
+
}
|
|
55438
|
+
],
|
|
55439
|
+
notes: " \u2014 setting a waiting-on party moves an open task to waiting, clearing it moves it back to todo, unless --status says otherwise.",
|
|
55440
|
+
run: async ({ args, flags, requireClient }) => {
|
|
55441
|
+
const id = requireArg(args, 0, "task id");
|
|
55442
|
+
const status = flagString(flags, "status");
|
|
55443
|
+
const priority = flagString(flags, "priority");
|
|
55444
|
+
const deliverable = flagString(flags, "deliverable");
|
|
55445
|
+
if (status === undefined && priority === undefined && deliverable === undefined) {
|
|
55446
|
+
throw usageError("tasks set needs --status, --priority or --deliverable");
|
|
55447
|
+
}
|
|
55448
|
+
const body = parseInput(updateTaskInputSchema, {
|
|
55449
|
+
...status !== undefined ? { status: taskStatusWire(status) } : {},
|
|
55450
|
+
...priority !== undefined ? { priority: priority.trim().toLowerCase() } : {},
|
|
55451
|
+
...deliverable !== undefined ? { deliverable: deliverable.trim() || null } : {}
|
|
55452
|
+
});
|
|
55453
|
+
return {
|
|
55454
|
+
data: await requireClient().patch(pathOf(taskOperations.update, { id }), body),
|
|
55455
|
+
render: renderTask
|
|
55456
|
+
};
|
|
55457
|
+
}
|
|
55458
|
+
})
|
|
53668
55459
|
];
|
|
53669
55460
|
|
|
53670
55461
|
// src/commands/time-blocks.ts
|
|
53671
|
-
var
|
|
55462
|
+
var commands55 = [
|
|
53672
55463
|
{
|
|
53673
55464
|
spec: {
|
|
53674
55465
|
path: ["time-blocks", "record"],
|
|
@@ -53722,7 +55513,7 @@ var commands50 = [
|
|
|
53722
55513
|
];
|
|
53723
55514
|
|
|
53724
55515
|
// src/today.ts
|
|
53725
|
-
var OPEN_STATUSES = new Set(
|
|
55516
|
+
var OPEN_STATUSES = new Set(OPEN_TASK_STATUSES);
|
|
53726
55517
|
function isTaskLike(value) {
|
|
53727
55518
|
return typeof value === "object" && value !== null && typeof value.id === "string";
|
|
53728
55519
|
}
|
|
@@ -53808,7 +55599,48 @@ var FROM_EARLIER_ANSWERS = ["today", "later", "someday", "let-go"];
|
|
|
53808
55599
|
function localDayStart(now) {
|
|
53809
55600
|
return new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
|
53810
55601
|
}
|
|
53811
|
-
|
|
55602
|
+
function localWeek(now) {
|
|
55603
|
+
const back = (now.getDay() + 6) % 7;
|
|
55604
|
+
const from = new Date(now.getFullYear(), now.getMonth(), now.getDate() - back);
|
|
55605
|
+
return {
|
|
55606
|
+
from,
|
|
55607
|
+
to: new Date(from.getFullYear(), from.getMonth(), from.getDate() + 7)
|
|
55608
|
+
};
|
|
55609
|
+
}
|
|
55610
|
+
function landedWho(actor) {
|
|
55611
|
+
if (!actor || actor.kind === "you")
|
|
55612
|
+
return "you";
|
|
55613
|
+
if (actor.kind === "agent") {
|
|
55614
|
+
const name = actor.name ?? "agent";
|
|
55615
|
+
return actor.machine ? `${name} on ${actor.machine}` : name;
|
|
55616
|
+
}
|
|
55617
|
+
return actor.name ?? (actor.kind === "echo" ? "your agent" : "a member");
|
|
55618
|
+
}
|
|
55619
|
+
function renderLandedCounts(data, mode) {
|
|
55620
|
+
const base = renderLanded(data, mode);
|
|
55621
|
+
const c = data;
|
|
55622
|
+
if (c.itemsTotal === undefined)
|
|
55623
|
+
return base;
|
|
55624
|
+
const out = [
|
|
55625
|
+
base,
|
|
55626
|
+
"",
|
|
55627
|
+
paint(mode, "bold", `Across sections \xB7 ${c.itemsTotal} (today ${c.today ?? 0}, before ${c.previousWeekTotal ?? 0})`)
|
|
55628
|
+
];
|
|
55629
|
+
for (const d of c.byDay ?? [])
|
|
55630
|
+
out.push(` ${d.date} ${d.you} by you \xB7 ${d.agents} by agents`);
|
|
55631
|
+
const sections = (c.bySection ?? []).map((s) => `${s.section} ${s.count}`).join(" \xB7 ");
|
|
55632
|
+
if (sections)
|
|
55633
|
+
out.push(` ${sections}`);
|
|
55634
|
+
const items = c.items ?? [];
|
|
55635
|
+
if (items.length > 0)
|
|
55636
|
+
out.push("");
|
|
55637
|
+
for (const i of items) {
|
|
55638
|
+
out.push(` ${i.title} ${paint(mode, "dim", `\xB7 ${i.where} \xB7 ${landedWho(i.actor)}`)}`);
|
|
55639
|
+
}
|
|
55640
|
+
return out.join(`
|
|
55641
|
+
`);
|
|
55642
|
+
}
|
|
55643
|
+
var commands56 = [
|
|
53812
55644
|
{
|
|
53813
55645
|
spec: {
|
|
53814
55646
|
path: ["today"],
|
|
@@ -53944,22 +55776,47 @@ var commands51 = [
|
|
|
53944
55776
|
{
|
|
53945
55777
|
spec: {
|
|
53946
55778
|
path: ["landed"],
|
|
53947
|
-
summary: "What got done in a window (by completedAt), split by who finished it.",
|
|
55779
|
+
summary: "What got done in a window (by completedAt), split by who finished it, and counted by day and section.",
|
|
53948
55780
|
args: [],
|
|
53949
55781
|
flags: [
|
|
53950
|
-
{
|
|
53951
|
-
|
|
55782
|
+
{
|
|
55783
|
+
name: "from",
|
|
55784
|
+
type: "string",
|
|
55785
|
+
description: "Window start (ISO); default today, UTC."
|
|
55786
|
+
},
|
|
55787
|
+
{
|
|
55788
|
+
name: "to",
|
|
55789
|
+
type: "string",
|
|
55790
|
+
description: "Window end (ISO); default a day after from."
|
|
55791
|
+
},
|
|
55792
|
+
{
|
|
55793
|
+
name: "week",
|
|
55794
|
+
type: "boolean",
|
|
55795
|
+
description: "This local week, Monday to Monday (instead of --from/--to)."
|
|
55796
|
+
},
|
|
55797
|
+
{
|
|
55798
|
+
name: "tz",
|
|
55799
|
+
type: "string",
|
|
55800
|
+
description: "IANA zone the days are cut in; default this machine's."
|
|
55801
|
+
}
|
|
53952
55802
|
],
|
|
53953
55803
|
scopes: [...readOperations.landed.scopes],
|
|
53954
55804
|
returns: "LandedResponse",
|
|
53955
|
-
notes: "Cancelled tasks never count. For a week: --from <monday> --to <next monday>."
|
|
55805
|
+
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>."
|
|
53956
55806
|
},
|
|
53957
|
-
run: async ({ flags, requireClient }) =>
|
|
53958
|
-
|
|
53959
|
-
|
|
53960
|
-
|
|
53961
|
-
|
|
53962
|
-
|
|
55807
|
+
run: async ({ flags, requireClient }) => {
|
|
55808
|
+
const week = flagBool(flags, "week") ? localWeek(new Date) : null;
|
|
55809
|
+
return {
|
|
55810
|
+
data: await requireClient().get(pathOf(readOperations.landed), {
|
|
55811
|
+
query: {
|
|
55812
|
+
from: flagString(flags, "from") ?? week?.from.toISOString(),
|
|
55813
|
+
to: flagString(flags, "to") ?? week?.to.toISOString(),
|
|
55814
|
+
tz: flagString(flags, "tz") ?? Intl.DateTimeFormat().resolvedOptions().timeZone
|
|
55815
|
+
}
|
|
55816
|
+
}),
|
|
55817
|
+
render: renderLandedCounts
|
|
55818
|
+
};
|
|
55819
|
+
}
|
|
53963
55820
|
},
|
|
53964
55821
|
{
|
|
53965
55822
|
spec: {
|
|
@@ -54024,8 +55881,257 @@ var commands51 = [
|
|
|
54024
55881
|
}
|
|
54025
55882
|
];
|
|
54026
55883
|
|
|
55884
|
+
// src/commands/work-views.ts
|
|
55885
|
+
var FILTER_FLAGS = [
|
|
55886
|
+
{
|
|
55887
|
+
name: "status",
|
|
55888
|
+
type: "string",
|
|
55889
|
+
description: "Any of these statuses (backlog,todo,in-progress,waiting,done)."
|
|
55890
|
+
},
|
|
55891
|
+
{
|
|
55892
|
+
name: "not-status",
|
|
55893
|
+
type: "string",
|
|
55894
|
+
description: "None of these statuses, e.g. done."
|
|
55895
|
+
},
|
|
55896
|
+
{ name: "area", type: "string", description: "Any of these Area ids, comma-separated." },
|
|
55897
|
+
{
|
|
55898
|
+
name: "project",
|
|
55899
|
+
type: "string",
|
|
55900
|
+
description: "Any of these Project ids, comma-separated."
|
|
55901
|
+
},
|
|
55902
|
+
{
|
|
55903
|
+
name: "label",
|
|
55904
|
+
type: "string",
|
|
55905
|
+
description: "Any of these labels (tags), comma-separated."
|
|
55906
|
+
},
|
|
55907
|
+
{
|
|
55908
|
+
name: "priority",
|
|
55909
|
+
type: "string",
|
|
55910
|
+
description: "Any of these priorities (none,low,medium,high)."
|
|
55911
|
+
},
|
|
55912
|
+
{
|
|
55913
|
+
name: "assignee",
|
|
55914
|
+
type: "string",
|
|
55915
|
+
description: "me, none, member:<id> or agent:<id>."
|
|
55916
|
+
},
|
|
55917
|
+
{
|
|
55918
|
+
name: "waiting",
|
|
55919
|
+
type: "string",
|
|
55920
|
+
description: "true = only Waiting, false = none of them."
|
|
55921
|
+
},
|
|
55922
|
+
{
|
|
55923
|
+
name: "due",
|
|
55924
|
+
type: "string",
|
|
55925
|
+
description: "overdue, today, this_week, next_week or none."
|
|
55926
|
+
},
|
|
55927
|
+
{
|
|
55928
|
+
name: "scheduled",
|
|
55929
|
+
type: "string",
|
|
55930
|
+
description: "The planned day: overdue, today, this_week, next_week or none."
|
|
55931
|
+
},
|
|
55932
|
+
{
|
|
55933
|
+
name: "when",
|
|
55934
|
+
type: "string",
|
|
55935
|
+
description: "Due or planned in: overdue, today, this_week, next_week or none."
|
|
55936
|
+
}
|
|
55937
|
+
];
|
|
55938
|
+
var SHAPE_FLAGS = [
|
|
55939
|
+
{
|
|
55940
|
+
name: "group",
|
|
55941
|
+
type: "string",
|
|
55942
|
+
description: "area, status, project, priority, assignee or none."
|
|
55943
|
+
},
|
|
55944
|
+
{ name: "view", type: "string", description: "list, board or timeline." },
|
|
55945
|
+
{
|
|
55946
|
+
name: "pin",
|
|
55947
|
+
type: "string",
|
|
55948
|
+
description: "true pins it to Work's top row, false unpins."
|
|
55949
|
+
}
|
|
55950
|
+
];
|
|
55951
|
+
var list3 = (raw) => raw.split(",").map((s) => s.trim()).filter(Boolean);
|
|
55952
|
+
function filtersOf(flags) {
|
|
55953
|
+
const out = {};
|
|
55954
|
+
const lists = [
|
|
55955
|
+
["status", "status", taskStatusWire],
|
|
55956
|
+
["not-status", "notStatus", taskStatusWire],
|
|
55957
|
+
["area", "areaIds", (v) => v],
|
|
55958
|
+
["project", "projectIds", (v) => v],
|
|
55959
|
+
["label", "labels", (v) => v],
|
|
55960
|
+
["priority", "priority", (v) => v.toLowerCase()]
|
|
55961
|
+
];
|
|
55962
|
+
for (const [flag, key, norm] of lists) {
|
|
55963
|
+
const values = flagStrings(flags, flag).flatMap(list3);
|
|
55964
|
+
if (values.length > 0)
|
|
55965
|
+
out[key] = values.map(norm);
|
|
55966
|
+
}
|
|
55967
|
+
const assignee = flagString(flags, "assignee");
|
|
55968
|
+
if (assignee)
|
|
55969
|
+
out.assignee = assignee.trim();
|
|
55970
|
+
const waiting = flagString(flags, "waiting");
|
|
55971
|
+
if (waiting !== undefined)
|
|
55972
|
+
out.waiting = waiting !== "false";
|
|
55973
|
+
for (const key of ["due", "scheduled", "when"]) {
|
|
55974
|
+
const v = flagString(flags, key);
|
|
55975
|
+
if (v)
|
|
55976
|
+
out[key] = v.trim().toLowerCase().replace(/-/g, "_");
|
|
55977
|
+
}
|
|
55978
|
+
return Object.keys(out).length > 0 ? out : null;
|
|
55979
|
+
}
|
|
55980
|
+
function shapeOf(flags) {
|
|
55981
|
+
const out = {};
|
|
55982
|
+
const group = flagString(flags, "group");
|
|
55983
|
+
if (group)
|
|
55984
|
+
out.groupBy = group.trim().toLowerCase();
|
|
55985
|
+
const view = flagString(flags, "view");
|
|
55986
|
+
if (view)
|
|
55987
|
+
out.view = view.trim().toLowerCase();
|
|
55988
|
+
const pin = flagString(flags, "pin");
|
|
55989
|
+
if (pin !== undefined)
|
|
55990
|
+
out.pinned = pin !== "false";
|
|
55991
|
+
return out;
|
|
55992
|
+
}
|
|
55993
|
+
async function findView(client, nameOrId) {
|
|
55994
|
+
const page = await client.get(pathOf(workViewOperations.list));
|
|
55995
|
+
const views = Array.isArray(page) ? page : page.data;
|
|
55996
|
+
const key = nameOrId.trim().toLowerCase();
|
|
55997
|
+
const view = views.find((v) => v.id === nameOrId) ?? views.find((v) => v.name.toLowerCase() === key);
|
|
55998
|
+
if (!view) {
|
|
55999
|
+
throw new CliError("not_found", `no Work view named \`${nameOrId}\` \u2014 run \`do views list\``, EXIT.NOT_FOUND);
|
|
56000
|
+
}
|
|
56001
|
+
return view;
|
|
56002
|
+
}
|
|
56003
|
+
function renderViews(data, mode) {
|
|
56004
|
+
const page = data;
|
|
56005
|
+
const views = Array.isArray(page) ? page : page.data;
|
|
56006
|
+
if (views.length === 0)
|
|
56007
|
+
return paint(mode, "dim", "(no views)");
|
|
56008
|
+
const width = Math.max(...views.map((v) => v.name.length));
|
|
56009
|
+
return views.map((v) => ` ${v.pinned ? "\u2605 " : " "}${v.name.padEnd(width)} ${String(v.count).padStart(4)} ${paint(mode, "dim", v.id)}`).join(`
|
|
56010
|
+
`);
|
|
56011
|
+
}
|
|
56012
|
+
function renderView(data, mode) {
|
|
56013
|
+
return renderViews([data], mode);
|
|
56014
|
+
}
|
|
56015
|
+
var commands57 = [
|
|
56016
|
+
defineCommand({
|
|
56017
|
+
operation: workViewOperations.list,
|
|
56018
|
+
path: ["views", "list"],
|
|
56019
|
+
summary: "List the Work saved views, each with its live count.",
|
|
56020
|
+
returns: "WorkView[]",
|
|
56021
|
+
run: async ({ requireClient }) => ({
|
|
56022
|
+
data: await requireClient().get(pathOf(workViewOperations.list)),
|
|
56023
|
+
render: renderViews
|
|
56024
|
+
})
|
|
56025
|
+
}),
|
|
56026
|
+
defineCommand({
|
|
56027
|
+
operation: taskOperations.list,
|
|
56028
|
+
path: ["views", "show"],
|
|
56029
|
+
summary: "The tasks a Work saved view matches (exactly its count).",
|
|
56030
|
+
args: [{ name: "view", required: true, description: "The view's name (any case) or id." }],
|
|
56031
|
+
scopes: [...new Set([...workViewOperations.list.scopes, ...taskOperations.list.scopes])],
|
|
56032
|
+
returns: "Task[]",
|
|
56033
|
+
notes: " with ?view=<id>, after the view is found by name in the views list.",
|
|
56034
|
+
run: async ({ args, requireClient }) => {
|
|
56035
|
+
const client = requireClient();
|
|
56036
|
+
const view = await findView(client, requireArg(args, 0, "view"));
|
|
56037
|
+
return {
|
|
56038
|
+
data: await client.getPage(pathOf(taskOperations.list), { query: { view: view.id } }),
|
|
56039
|
+
render: renderList
|
|
56040
|
+
};
|
|
56041
|
+
}
|
|
56042
|
+
}),
|
|
56043
|
+
defineCommand({
|
|
56044
|
+
operation: workViewOperations.create,
|
|
56045
|
+
path: ["views", "save"],
|
|
56046
|
+
summary: "Save a Work view: a name, its filters, and how Work groups and draws it.",
|
|
56047
|
+
args: [{ name: "name", required: true, description: "The view's name." }],
|
|
56048
|
+
flags: [...FILTER_FLAGS, ...SHAPE_FLAGS],
|
|
56049
|
+
returns: "WorkView",
|
|
56050
|
+
run: async ({ args, flags, requireClient }) => {
|
|
56051
|
+
const name = args.join(" ").trim();
|
|
56052
|
+
if (!name)
|
|
56053
|
+
throw usageError('views save needs a name, e.g. `do views save "Deep work"`');
|
|
56054
|
+
const body = parseInput(createWorkViewInputSchema, {
|
|
56055
|
+
name,
|
|
56056
|
+
filters: filtersOf(flags) ?? {},
|
|
56057
|
+
...shapeOf(flags)
|
|
56058
|
+
});
|
|
56059
|
+
return {
|
|
56060
|
+
data: await requireClient().post(pathOf(workViewOperations.create), body),
|
|
56061
|
+
render: renderView
|
|
56062
|
+
};
|
|
56063
|
+
}
|
|
56064
|
+
}),
|
|
56065
|
+
defineCommand({
|
|
56066
|
+
operation: workViewOperations.update,
|
|
56067
|
+
path: ["views", "update"],
|
|
56068
|
+
summary: "Rename a Work view, or change its filters (replaced whole), grouping or kind.",
|
|
56069
|
+
args: [{ name: "view", required: true, description: "The view's name (any case) or id." }],
|
|
56070
|
+
flags: [
|
|
56071
|
+
{ name: "name", type: "string", description: "Its new name." },
|
|
56072
|
+
...FILTER_FLAGS,
|
|
56073
|
+
...SHAPE_FLAGS
|
|
56074
|
+
],
|
|
56075
|
+
returns: "WorkView",
|
|
56076
|
+
run: async ({ args, flags, requireClient }) => {
|
|
56077
|
+
const client = requireClient();
|
|
56078
|
+
const view = await findView(client, requireArg(args, 0, "view"));
|
|
56079
|
+
const filters = filtersOf(flags);
|
|
56080
|
+
const rename = flagString(flags, "name");
|
|
56081
|
+
const body = parseInput(updateWorkViewInputSchema, {
|
|
56082
|
+
...rename !== undefined ? { name: rename } : {},
|
|
56083
|
+
...filters ? { filters } : {},
|
|
56084
|
+
...shapeOf(flags)
|
|
56085
|
+
});
|
|
56086
|
+
if (Object.keys(body).length === 0) {
|
|
56087
|
+
throw usageError("views update needs --name, a filter flag, --group, --view or --pin");
|
|
56088
|
+
}
|
|
56089
|
+
return {
|
|
56090
|
+
data: await client.patch(pathOf(workViewOperations.update, { id: view.id }), body),
|
|
56091
|
+
render: renderView
|
|
56092
|
+
};
|
|
56093
|
+
}
|
|
56094
|
+
}),
|
|
56095
|
+
defineCommand({
|
|
56096
|
+
operation: workViewOperations.reorder,
|
|
56097
|
+
path: ["views", "reorder"],
|
|
56098
|
+
summary: "Put the Work views in this order (names or ids); the rest keep theirs after.",
|
|
56099
|
+
args: [{ name: "views", required: true, description: "Views by name or id, in order." }],
|
|
56100
|
+
returns: "WorkView[]",
|
|
56101
|
+
run: async ({ args, requireClient }) => {
|
|
56102
|
+
if (args.length === 0)
|
|
56103
|
+
throw usageError("views reorder needs the views in order");
|
|
56104
|
+
const client = requireClient();
|
|
56105
|
+
const ids = [];
|
|
56106
|
+
for (const arg of args)
|
|
56107
|
+
ids.push((await findView(client, arg)).id);
|
|
56108
|
+
const body = parseInput(reorderWorkViewsInputSchema, { ids });
|
|
56109
|
+
return {
|
|
56110
|
+
data: await client.post(pathOf(workViewOperations.reorder), body),
|
|
56111
|
+
render: renderViews
|
|
56112
|
+
};
|
|
56113
|
+
}
|
|
56114
|
+
}),
|
|
56115
|
+
defineCommand({
|
|
56116
|
+
operation: workViewOperations.remove,
|
|
56117
|
+
path: ["views", "delete"],
|
|
56118
|
+
summary: "Delete a Work view (a default one too; it isn't seeded again).",
|
|
56119
|
+
args: [{ name: "view", required: true, description: "The view's name (any case) or id." }],
|
|
56120
|
+
returns: "{ ok, deleted }",
|
|
56121
|
+
run: async ({ args, requireClient }) => {
|
|
56122
|
+
const client = requireClient();
|
|
56123
|
+
const view = await findView(client, requireArg(args, 0, "view"));
|
|
56124
|
+
await client.delete(pathOf(workViewOperations.remove, { id: view.id }));
|
|
56125
|
+
return {
|
|
56126
|
+
data: { ok: true, deleted: view.id, name: view.name },
|
|
56127
|
+
render: () => `Deleted the view ${view.name}.`
|
|
56128
|
+
};
|
|
56129
|
+
}
|
|
56130
|
+
})
|
|
56131
|
+
];
|
|
56132
|
+
|
|
54027
56133
|
// src/commands/worktree-links.ts
|
|
54028
|
-
var
|
|
56134
|
+
var commands58 = [
|
|
54029
56135
|
{
|
|
54030
56136
|
spec: {
|
|
54031
56137
|
path: ["worktree-links", "list"],
|
|
@@ -54183,7 +56289,13 @@ var FEATURE_COMMANDS = [
|
|
|
54183
56289
|
...commands49,
|
|
54184
56290
|
...commands50,
|
|
54185
56291
|
...commands51,
|
|
54186
|
-
...commands52
|
|
56292
|
+
...commands52,
|
|
56293
|
+
...commands53,
|
|
56294
|
+
...commands54,
|
|
56295
|
+
...commands55,
|
|
56296
|
+
...commands56,
|
|
56297
|
+
...commands57,
|
|
56298
|
+
...commands58
|
|
54187
56299
|
];
|
|
54188
56300
|
|
|
54189
56301
|
// src/registry.ts
|
|
@@ -54309,7 +56421,8 @@ async function dispatchEntity(entity, rest, flags, requireClient) {
|
|
|
54309
56421
|
query[key] = f.sends;
|
|
54310
56422
|
continue;
|
|
54311
56423
|
}
|
|
54312
|
-
const
|
|
56424
|
+
const raw = flags[f.name] === true ? "true" : flagString(flags, f.name);
|
|
56425
|
+
const value = raw !== undefined && f.normalize ? f.normalize(raw) : raw;
|
|
54313
56426
|
if (value !== undefined)
|
|
54314
56427
|
query[key] = value;
|
|
54315
56428
|
else if (f.required)
|