@robbeverhelst/do 1.419.0 → 1.420.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/do.js +516 -58
  2. package/package.json +1 -1
package/dist/do.js CHANGED
@@ -14420,7 +14420,7 @@ var configError = (message) => new CliError("config", message, EXIT.CONFIG);
14420
14420
 
14421
14421
  // src/meta.ts
14422
14422
  var CLI_NAME = "do";
14423
- var VERSION = "1.419.0";
14423
+ var VERSION = "1.420.0";
14424
14424
  var API_PREFIX = "/api/v1";
14425
14425
  var DEFAULT_API_URL = "http://localhost:3001";
14426
14426
 
@@ -28625,6 +28625,268 @@ var documentOperations = defineOperations({
28625
28625
  }
28626
28626
  });
28627
28627
 
28628
+ // ../../packages/schema/src/db/agent-chat-threads.ts
28629
+ var agentChatThreads = pgTable("agent_chat_threads", {
28630
+ id: text("id").primaryKey(),
28631
+ tenantId: text("tenant_id").notNull().references(() => tenants.id),
28632
+ userId: text("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
28633
+ title: text("title"),
28634
+ slug: text("slug"),
28635
+ standing: boolean4("standing").notNull().default(false),
28636
+ push: text("push").notNull().default("all"),
28637
+ areaIds: text("area_ids").array().notNull().default([]),
28638
+ peopleCapture: boolean4("people_capture").notNull().default(true),
28639
+ kind: text("kind"),
28640
+ anchorType: text("anchor_type"),
28641
+ anchorId: text("anchor_id"),
28642
+ parentId: text("parent_id"),
28643
+ notifyLevel: text("notify_level"),
28644
+ icon: text("icon"),
28645
+ description: text("description"),
28646
+ memoryScope: text("memory_scope"),
28647
+ lastMessageAt: timestamp("last_message_at", { withTimezone: true }),
28648
+ archivedAt: timestamp("archived_at", { withTimezone: true }),
28649
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
28650
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
28651
+ }, (t) => [
28652
+ index("agent_chat_threads_member_idx").on(t.tenantId, t.userId, t.updatedAt),
28653
+ uniqueIndex("agent_chat_threads_slug_uniq").on(t.tenantId, t.userId, t.slug).where(sql`${t.slug} is not null`)
28654
+ ]);
28655
+ var agentChatTurns = pgTable("agent_chat_turns", {
28656
+ id: text("id").primaryKey(),
28657
+ tenantId: text("tenant_id").notNull().references(() => tenants.id),
28658
+ threadId: text("thread_id").notNull().references(() => agentChatThreads.id, { onDelete: "cascade" }),
28659
+ userId: text("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
28660
+ question: text("question").notNull(),
28661
+ context: jsonb("context").$type().notNull(),
28662
+ reply: text("reply").notNull().default(""),
28663
+ status: text("status").notNull().default("streaming"),
28664
+ error: text("error"),
28665
+ since: text("since"),
28666
+ changes: jsonb("changes").$type().notNull().default([]),
28667
+ confirmations: jsonb("confirmations").$type().notNull().default([]),
28668
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
28669
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
28670
+ }, (t) => [index("agent_chat_turns_thread_idx").on(t.threadId, t.createdAt)]);
28671
+ var agentChatPosts = pgTable("agent_chat_posts", {
28672
+ id: text("id").primaryKey(),
28673
+ tenantId: text("tenant_id").notNull().references(() => tenants.id),
28674
+ threadId: text("thread_id").notNull().references(() => agentChatThreads.id, { onDelete: "cascade" }),
28675
+ userId: text("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
28676
+ author: text("author").notNull(),
28677
+ agentId: text("agent_id").references(() => agents.id),
28678
+ externalId: text("external_id"),
28679
+ kind: text("kind").notNull().default("message"),
28680
+ level: text("level"),
28681
+ text: text("text").notNull().default(""),
28682
+ final: boolean4("final").notNull().default(true),
28683
+ replyToId: text("reply_to_id"),
28684
+ relayOfPostId: text("relay_of_post_id").references(() => agentChatPosts.id, {
28685
+ onDelete: "set null"
28686
+ }),
28687
+ runStatus: text("run_status"),
28688
+ brief: jsonb("brief").$type(),
28689
+ card: jsonb("card").$type(),
28690
+ digestKey: text("digest_key"),
28691
+ title: text("title"),
28692
+ runSteps: jsonb("run_steps").$type(),
28693
+ runEndedAt: timestamp("run_ended_at", { withTimezone: true }),
28694
+ prompt: jsonb("prompt").$type(),
28695
+ receipt: jsonb("receipt").$type(),
28696
+ attachments: jsonb("attachments").$type().notNull().default([]),
28697
+ context: jsonb("context").$type(),
28698
+ deliveredAt: timestamp("delivered_at", { withTimezone: true }),
28699
+ seenAt: timestamp("seen_at", { withTimezone: true }),
28700
+ readAt: timestamp("read_at", { withTimezone: true }),
28701
+ fallbackAt: timestamp("fallback_at", { withTimezone: true }),
28702
+ fallbackAckedAt: timestamp("fallback_acked_at", { withTimezone: true }),
28703
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
28704
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
28705
+ deletedAt: timestamp("deleted_at", { withTimezone: true })
28706
+ }, (t) => [
28707
+ index("agent_chat_posts_thread_idx").on(t.threadId, t.createdAt),
28708
+ uniqueIndex("agent_chat_posts_external_uniq").on(t.tenantId, t.agentId, t.externalId).where(sql`${t.externalId} is not null`),
28709
+ index("agent_chat_posts_undelivered_idx").on(t.tenantId, t.createdAt).where(sql`${t.author} = 'member' and ${t.deliveredAt} is null`),
28710
+ index("agent_chat_posts_needs_you_unseen_idx").on(t.tenantId, t.userId, t.createdAt).where(sql`${t.author} = 'agent' and ${t.level} = 'needs_you' and ${t.seenAt} is null and ${t.deletedAt} is null`)
28711
+ ]);
28712
+
28713
+ // ../../packages/schema/src/db/echo-schedules.ts
28714
+ var ECHO_SCHEDULE_LEVELS = ["now", "today", "digest", "silent"];
28715
+ var ECHO_SCHEDULE_RUN_STATUSES = ["ok", "failed", "unanswered"];
28716
+ var echoSchedules = pgTable("echo_schedules", {
28717
+ id: text("id").primaryKey(),
28718
+ tenantId: text("tenant_id").notNull().references(() => tenants.id),
28719
+ userId: text("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
28720
+ key: text("key").notNull(),
28721
+ name: text("name").notNull(),
28722
+ threadId: text("thread_id").notNull().references(() => agentChatThreads.id, { onDelete: "cascade" }),
28723
+ agentId: text("agent_id").references(() => agents.id),
28724
+ desk: text("desk"),
28725
+ times: text("times").array().notNull(),
28726
+ everyMinutes: integer2("every_minutes"),
28727
+ weekdays: integer2("weekdays").array().notNull().default([]),
28728
+ level: text("level").notNull().default("today"),
28729
+ levelNote: text("level_note"),
28730
+ pausedAt: timestamp("paused_at", { withTimezone: true }),
28731
+ runRequestedAt: timestamp("run_requested_at", { withTimezone: true }),
28732
+ lastRunAt: timestamp("last_run_at", { withTimezone: true }),
28733
+ lastStatus: text("last_status"),
28734
+ lastNote: text("last_note"),
28735
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
28736
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
28737
+ }, (t) => [
28738
+ index("echo_schedules_member_idx").on(t.tenantId, t.userId),
28739
+ uniqueIndex("echo_schedules_key_uniq").on(t.tenantId, t.userId, t.key),
28740
+ check2("echo_schedules_level_chk", sql`${t.level} IN ('now', 'today', 'digest', 'silent')`),
28741
+ check2("echo_schedules_last_status_chk", sql`${t.lastStatus} IS NULL OR ${t.lastStatus} IN ('ok', 'failed', 'unanswered')`)
28742
+ ]);
28743
+
28744
+ // ../../packages/schema/src/contracts/echo-schedules.ts
28745
+ var echoScheduleLevelSchema = _enum2(ECHO_SCHEDULE_LEVELS);
28746
+ var echoScheduleRunStatusSchema = _enum2(ECHO_SCHEDULE_RUN_STATUSES);
28747
+ var clock = string2().regex(/^([01]\d|2[0-3]):[0-5]\d$/, "a time as HH:MM");
28748
+ var echoScheduleKeySchema = string2().regex(/^[a-z0-9][a-z0-9-]{0,39}$/, "lower-case letters, digits and dashes, at most 40");
28749
+ var times = array(clock).min(1).max(12);
28750
+ var weekdays = array(number2().int().min(1).max(7)).max(7).refine((d) => new Set(d).size === d.length, "each weekday once");
28751
+ var everyMinutes = number2().int().min(15).max(10080);
28752
+ var echoScheduleSchema = object({
28753
+ id: ulidSchema,
28754
+ key: string2(),
28755
+ name: string2(),
28756
+ thread: object({
28757
+ id: string2(),
28758
+ title: string2().nullable(),
28759
+ slug: string2().nullable(),
28760
+ icon: string2().nullable()
28761
+ }),
28762
+ agentId: string2().nullable(),
28763
+ desk: string2().nullable(),
28764
+ times: array(string2()),
28765
+ everyMinutes: number2().int().nullable(),
28766
+ weekdays: array(number2().int()),
28767
+ level: echoScheduleLevelSchema,
28768
+ levelNote: string2().nullable(),
28769
+ paused: boolean2(),
28770
+ runRequested: boolean2(),
28771
+ lastRunAt: exports_coerce.date().nullable(),
28772
+ lastStatus: echoScheduleRunStatusSchema.nullable(),
28773
+ lastNote: string2().nullable(),
28774
+ createdAt: exports_coerce.date(),
28775
+ updatedAt: exports_coerce.date()
28776
+ });
28777
+ var putEchoScheduleInputSchema = object({
28778
+ name: string2().trim().min(1).max(80),
28779
+ thread: string2().trim().min(1).max(40),
28780
+ desk: string2().trim().min(1).max(40).nullish(),
28781
+ times,
28782
+ everyMinutes: everyMinutes.nullish(),
28783
+ weekdays: weekdays.optional(),
28784
+ level: echoScheduleLevelSchema.optional(),
28785
+ levelNote: string2().trim().min(1).max(120).nullish()
28786
+ }).strict();
28787
+ var updateEchoScheduleInputSchema = object({
28788
+ level: echoScheduleLevelSchema.optional(),
28789
+ paused: boolean2().optional()
28790
+ }).strict().refine((v) => v.level !== undefined || v.paused !== undefined, "level or paused");
28791
+ var reportEchoScheduleRunInputSchema = object({
28792
+ status: echoScheduleRunStatusSchema,
28793
+ note: string2().trim().min(1).max(200).nullish(),
28794
+ at: exports_coerce.date().optional()
28795
+ }).strict();
28796
+ var echoScheduleKeyParamSchema = object({ key: echoScheduleKeySchema });
28797
+
28798
+ // ../../packages/schema/src/operations/echo-schedules.ts
28799
+ var NO_USER = "The key has no user identity (scheduled posts are per member).";
28800
+ var KEY = {
28801
+ key: {
28802
+ description: "The job's handle, the agent's own (`wake`, `pings`): lower-case letters, digits and dashes.",
28803
+ pattern: "^[a-z0-9][a-z0-9-]{0,39}$"
28804
+ }
28805
+ };
28806
+ var KEY_SCHEMA = { key: echoScheduleKeySchema };
28807
+ var VIEW = "`{ id, key, name, thread: { id, title, slug, icon }, agentId, desk, times, everyMinutes, weekdays, level, levelNote, paused, runRequested, lastRunAt, lastStatus, lastNote }`";
28808
+ var echoScheduleOperations = defineOperations({
28809
+ list: {
28810
+ method: "get",
28811
+ path: "/echo/schedules",
28812
+ scopes: ["agents:read"],
28813
+ tag: "Agents",
28814
+ summary: "List the scheduled posts",
28815
+ description: `Every job that posts into the member's threads on a clock, by name: ${VIEW}. \`times\` are \`HH:MM\` on the member's wall clock; with \`everyMinutes\` the job repeats from the first until midnight; \`weekdays\` are ISO (1 = Monday), empty for every day. \`level\` says how its posts land (\`now\` pushes, \`today\` a card in its thread, \`digest\` folded into one line, \`silent\` only in its history). A \`paused\` job doesn't run; \`runRequested\` asks for a run now.`,
28816
+ status: 200,
28817
+ response: { description: "The scheduled posts.", list: true },
28818
+ errors: { 403: NO_USER }
28819
+ },
28820
+ put: {
28821
+ method: "put",
28822
+ path: "/echo/schedules/{key}",
28823
+ pathParams: KEY,
28824
+ pathParamSchemas: KEY_SCHEMA,
28825
+ scopes: ["agents:write"],
28826
+ tag: "Agents",
28827
+ summary: "Declare a scheduled post",
28828
+ description: "The agent declares a job, or redeclares it: `name`, the member's standing `thread` it posts to (by slug), the `desk` that runs it, `times` (`HH:MM`, at most 12), `everyMinutes` (15 to 10080) and `weekdays`, and `level` with a `levelNote`. A new key makes the job (level `today` unless given); a known one updates it, keeping the member's level and pause. A thread the member doesn't have is a 404. The calling agent is recorded as the one that runs it.",
28829
+ body: putEchoScheduleInputSchema,
28830
+ status: 200,
28831
+ response: { description: "The scheduled post." },
28832
+ errors: { 400: true, 403: NO_USER, 404: "No such thread." }
28833
+ },
28834
+ update: {
28835
+ method: "patch",
28836
+ path: "/echo/schedules/{key}",
28837
+ pathParams: KEY,
28838
+ pathParamSchemas: KEY_SCHEMA,
28839
+ scopes: ["agents:write"],
28840
+ tag: "Agents",
28841
+ summary: "Change a scheduled post's level or pause it",
28842
+ description: "How its posts land (`level`: `now`, `today`, `digest` or `silent`) and whether it runs (`paused`). An unknown key is a 404.",
28843
+ body: updateEchoScheduleInputSchema,
28844
+ status: 200,
28845
+ response: { description: "The scheduled post." },
28846
+ errors: { 400: true, 403: NO_USER, 404: true }
28847
+ },
28848
+ runNow: {
28849
+ method: "post",
28850
+ path: "/echo/schedules/{key}/run",
28851
+ pathParams: KEY,
28852
+ pathParamSchemas: KEY_SCHEMA,
28853
+ scopes: ["agents:write"],
28854
+ tag: "Agents",
28855
+ summary: "Ask for a scheduled post now",
28856
+ description: "Asks the agent to run the job now: it reads `runRequested` on the job until it reports the run. A paused job is a 409. An unknown key is a 404.",
28857
+ status: 200,
28858
+ response: { description: "The scheduled post." },
28859
+ errors: { 403: NO_USER, 404: true, 409: "The job is paused." }
28860
+ },
28861
+ report: {
28862
+ method: "post",
28863
+ path: "/echo/schedules/{key}/runs",
28864
+ pathParams: KEY,
28865
+ pathParamSchemas: KEY_SCHEMA,
28866
+ scopes: ["agents:write"],
28867
+ tag: "Agents",
28868
+ summary: "Report a scheduled post's run",
28869
+ description: "The agent says how a run went (`status`: `ok`, `failed`, or `unanswered` for a check-in nobody answered), with a short `note` and when (`at`, default now). It clears a run asked for. An unknown key is a 404.",
28870
+ body: reportEchoScheduleRunInputSchema,
28871
+ status: 200,
28872
+ response: { description: "The scheduled post." },
28873
+ errors: { 400: true, 403: NO_USER, 404: true }
28874
+ },
28875
+ remove: {
28876
+ method: "delete",
28877
+ path: "/echo/schedules/{key}",
28878
+ pathParams: KEY,
28879
+ pathParamSchemas: KEY_SCHEMA,
28880
+ scopes: ["agents:write"],
28881
+ tag: "Agents",
28882
+ summary: "Remove a scheduled post",
28883
+ description: "The agent no longer runs the job. An unknown key is a 404.",
28884
+ status: 204,
28885
+ response: { description: "Removed." },
28886
+ errors: { 403: NO_USER, 404: true }
28887
+ }
28888
+ });
28889
+
28628
28890
  // ../../packages/schema/src/contracts/echo-threads.ts
28629
28891
  var echoTurnStatusSchema = _enum2(["streaming", "done", "error", "cancelled"]);
28630
28892
  var echoTurnConfirmationSchema = agentConfirmationSchema.extend({
@@ -28825,7 +29087,7 @@ var createEchoThreadInputSchema = object({
28825
29087
  }).strict();
28826
29088
 
28827
29089
  // ../../packages/schema/src/operations/echo-threads.ts
28828
- var NO_USER = "The key has no user identity (threads are per member).";
29090
+ var NO_USER2 = "The key has no user identity (threads are per member).";
28829
29091
  var echoThreadOperations = defineOperations({
28830
29092
  list: {
28831
29093
  method: "get",
@@ -28846,7 +29108,7 @@ var echoThreadOperations = defineOperations({
28846
29108
  querySchema: echoThreadsQuerySchema,
28847
29109
  status: 200,
28848
29110
  response: { description: "The member's threads.", list: true },
28849
- errors: { 400: true, 403: NO_USER }
29111
+ errors: { 400: true, 403: NO_USER2 }
28850
29112
  },
28851
29113
  create: {
28852
29114
  method: "post",
@@ -28859,7 +29121,7 @@ var echoThreadOperations = defineOperations({
28859
29121
  bodyOptional: true,
28860
29122
  status: 201,
28861
29123
  response: { description: "The new current thread." },
28862
- errors: { 403: NO_USER }
29124
+ errors: { 403: NO_USER2 }
28863
29125
  },
28864
29126
  current: {
28865
29127
  method: "get",
@@ -28870,7 +29132,7 @@ var echoThreadOperations = defineOperations({
28870
29132
  description: "The thread the agent panel opens on (the most recently used), with its turns oldest first: question, reply, `status` (`streaming` | `done` | `error` | `cancelled`), the change-feed cursor `since`, the changes and the confirmations. `{ thread: null }` before the first.",
28871
29133
  status: 200,
28872
29134
  response: { description: "`{ thread }`." },
28873
- errors: { 403: NO_USER }
29135
+ errors: { 403: NO_USER2 }
28874
29136
  },
28875
29137
  briefs: {
28876
29138
  method: "get",
@@ -28890,7 +29152,7 @@ var echoThreadOperations = defineOperations({
28890
29152
  querySchema: echoBriefsQuerySchema,
28891
29153
  status: 200,
28892
29154
  response: { description: "`{ briefs }`." },
28893
- errors: { 400: true, 403: NO_USER }
29155
+ errors: { 400: true, 403: NO_USER2 }
28894
29156
  },
28895
29157
  get: {
28896
29158
  method: "get",
@@ -28901,7 +29163,7 @@ var echoThreadOperations = defineOperations({
28901
29163
  description: "One of the member's threads with its turns, oldest first. Another member's thread is a 404.",
28902
29164
  status: 200,
28903
29165
  response: { description: "The thread." },
28904
- errors: { 403: NO_USER, 404: true }
29166
+ errors: { 403: NO_USER2, 404: true }
28905
29167
  },
28906
29168
  update: {
28907
29169
  method: "patch",
@@ -28913,7 +29175,7 @@ var echoThreadOperations = defineOperations({
28913
29175
  body: updateEchoThreadInputSchema,
28914
29176
  status: 200,
28915
29177
  response: { description: "The thread as the list shows it, with its `push`." },
28916
- errors: { 400: true, 403: NO_USER, 404: true }
29178
+ errors: { 400: true, 403: NO_USER2, 404: true }
28917
29179
  },
28918
29180
  addStanding: {
28919
29181
  method: "post",
@@ -28925,7 +29187,7 @@ var echoThreadOperations = defineOperations({
28925
29187
  body: createStandingThreadInputSchema,
28926
29188
  status: 201,
28927
29189
  response: { description: "The standing thread." },
28928
- errors: { 400: true, 403: NO_USER, 409: true }
29190
+ errors: { 400: true, 403: NO_USER2, 409: true }
28929
29191
  }
28930
29192
  });
28931
29193
 
@@ -44640,7 +44902,7 @@ var PART_LABEL = {
44640
44902
  evening: "Evening",
44641
44903
  anytime: "Any time today"
44642
44904
  };
44643
- function clock(at, timezone) {
44905
+ function clock2(at, timezone) {
44644
44906
  return new Intl.DateTimeFormat("en-GB", {
44645
44907
  timeZone: timezone,
44646
44908
  hour: "2-digit",
@@ -44671,7 +44933,7 @@ function habitLines(day, mode) {
44671
44933
  if (h.week)
44672
44934
  meta.push(`${h.week.done} of ${h.week.target} this week`);
44673
44935
  if (h.last?.by && civilDay(h.last.at, day.timezone) === day.date) {
44674
- meta.push(`${h.last.by}, ${clock(h.last.at, day.timezone)}`);
44936
+ meta.push(`${h.last.by}, ${clock2(h.last.at, day.timezone)}`);
44675
44937
  }
44676
44938
  const tail = meta.length > 0 ? paint(mode, "dim", ` \xB7 ${meta.join(" \xB7 ")}`) : "";
44677
44939
  lines.push(` ${mark} ${h.title}${tail} ${paint(mode, "dim", h.habitId)}`);
@@ -50412,10 +50674,205 @@ var commands16 = [
50412
50674
  }
50413
50675
  ];
50414
50676
 
50677
+ // src/commands/echo-schedules.ts
50678
+ var LEVELS = ["now", "today", "digest", "silent"];
50679
+ var STATUSES = ["ok", "failed", "unanswered"];
50680
+ var DAYS = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"];
50681
+ var KEY_ARG = {
50682
+ name: "key",
50683
+ required: true,
50684
+ description: "The job's handle (`wake`, `pings`): lower-case letters, digits and dashes."
50685
+ };
50686
+ function oneOf(value, allowed, what) {
50687
+ if (!allowed.includes(value))
50688
+ throw usageError(`${what} is one of ${allowed.join(", ")}`);
50689
+ return value;
50690
+ }
50691
+ function weekdaysOf(days) {
50692
+ return days.split(",").map((d) => {
50693
+ const i = DAYS.indexOf(d.trim().toLowerCase().slice(0, 3));
50694
+ if (i < 0)
50695
+ throw usageError(`--days takes mon,tue,\u2026,sun; got "${d}"`);
50696
+ return i + 1;
50697
+ });
50698
+ }
50699
+ var keyPath = (op, args) => pathOf(op, { key: requireArg(args, 0, "job key") });
50700
+ var commands17 = [
50701
+ {
50702
+ spec: {
50703
+ path: ["echo", "schedules", "list"],
50704
+ summary: "List your scheduled posts: the agent's jobs on a clock, by name.",
50705
+ args: [],
50706
+ flags: [],
50707
+ scopes: [...echoScheduleOperations.list.scopes],
50708
+ returns: "EchoSchedule[]",
50709
+ notes: "times are HH:MM on your wall clock; everyMinutes repeats from the first; paused jobs don't run; runRequested asks for a run now."
50710
+ },
50711
+ run: async ({ requireClient }) => ({
50712
+ data: await requireClient().getPage(pathOf(echoScheduleOperations.list)),
50713
+ render: renderList
50714
+ })
50715
+ },
50716
+ {
50717
+ spec: {
50718
+ path: ["echo", "schedules", "set"],
50719
+ summary: "Declare a scheduled post (the agent's): a new key makes it, a known key updates it.",
50720
+ args: [KEY_ARG],
50721
+ flags: [
50722
+ { name: "name", type: "string", description: "What it's called (Wake message)." },
50723
+ {
50724
+ name: "thread",
50725
+ type: "string",
50726
+ description: "The standing thread it posts to, by slug."
50727
+ },
50728
+ { name: "at", type: "string", description: "When, HH:MM, comma-separated (07:00,16:30)." },
50729
+ {
50730
+ name: "every",
50731
+ type: "string",
50732
+ description: "Repeat every N minutes from the first time."
50733
+ },
50734
+ { name: "days", type: "string", description: "Only on these days: mon,tue,\u2026,sun." },
50735
+ { name: "desk", type: "string", description: "The desk that runs it (build)." },
50736
+ {
50737
+ name: "level",
50738
+ type: "string",
50739
+ description: "A new job's level: now, today, digest or silent."
50740
+ },
50741
+ {
50742
+ name: "note",
50743
+ type: "string",
50744
+ description: "A word on the level (Now only on an incident)."
50745
+ }
50746
+ ],
50747
+ scopes: [...echoScheduleOperations.put.scopes],
50748
+ returns: "EchoSchedule",
50749
+ notes: "A redeclare keeps your level and pause. An unknown thread is a 404."
50750
+ },
50751
+ run: async ({ args, flags, requireClient }) => {
50752
+ const name = flagString(flags, "name");
50753
+ const thread = flagString(flags, "thread");
50754
+ const at = flagString(flags, "at");
50755
+ if (!name || !thread || !at)
50756
+ throw usageError("--name, --thread and --at are required");
50757
+ const every = flagString(flags, "every");
50758
+ const days = flagString(flags, "days");
50759
+ const desk = flagString(flags, "desk");
50760
+ const level = flagString(flags, "level");
50761
+ const note = flagString(flags, "note");
50762
+ return {
50763
+ data: await requireClient().put(keyPath(echoScheduleOperations.put, args), {
50764
+ name,
50765
+ thread,
50766
+ times: at.split(",").map((t) => t.trim()),
50767
+ ...every ? { everyMinutes: Number(every) } : {},
50768
+ ...days ? { weekdays: weekdaysOf(days) } : {},
50769
+ ...desk ? { desk } : {},
50770
+ ...level ? { level: oneOf(level, LEVELS, "--level") } : {},
50771
+ ...note ? { levelNote: note } : {}
50772
+ }),
50773
+ render: renderRecord
50774
+ };
50775
+ }
50776
+ },
50777
+ {
50778
+ spec: {
50779
+ path: ["echo", "schedules", "level"],
50780
+ summary: "Set how a scheduled post lands: now, today, digest or silent.",
50781
+ args: [
50782
+ KEY_ARG,
50783
+ { name: "level", required: true, description: "now, today, digest or silent." }
50784
+ ],
50785
+ flags: [],
50786
+ scopes: [...echoScheduleOperations.update.scopes],
50787
+ returns: "EchoSchedule",
50788
+ notes: "now pushes; today is a card in its thread; digest folds into one line; silent stays in its history."
50789
+ },
50790
+ run: async ({ args, requireClient }) => ({
50791
+ data: await requireClient().patch(keyPath(echoScheduleOperations.update, args), {
50792
+ level: oneOf(requireArg(args, 1, "level"), LEVELS, "level")
50793
+ }),
50794
+ render: renderRecord
50795
+ })
50796
+ },
50797
+ ...["pause", "resume"].map((verb) => ({
50798
+ spec: {
50799
+ path: ["echo", "schedules", verb],
50800
+ summary: verb === "pause" ? "Pause a scheduled post: the agent skips it." : "Resume a paused scheduled post.",
50801
+ args: [KEY_ARG],
50802
+ flags: [],
50803
+ scopes: [...echoScheduleOperations.update.scopes],
50804
+ returns: "EchoSchedule",
50805
+ notes: "An unknown key is a 404."
50806
+ },
50807
+ run: async ({ args, requireClient }) => ({
50808
+ data: await requireClient().patch(keyPath(echoScheduleOperations.update, args), {
50809
+ paused: verb === "pause"
50810
+ }),
50811
+ render: renderRecord
50812
+ })
50813
+ })),
50814
+ {
50815
+ spec: {
50816
+ path: ["echo", "schedules", "run"],
50817
+ summary: "Ask the agent to run a scheduled post now.",
50818
+ args: [KEY_ARG],
50819
+ flags: [],
50820
+ scopes: [...echoScheduleOperations.runNow.scopes],
50821
+ returns: "EchoSchedule",
50822
+ notes: "The job reads runRequested until the agent reports a run. A paused job is a 409."
50823
+ },
50824
+ run: async ({ args, requireClient }) => ({
50825
+ data: await requireClient().post(keyPath(echoScheduleOperations.runNow, args), {}),
50826
+ render: renderRecord
50827
+ })
50828
+ },
50829
+ {
50830
+ spec: {
50831
+ path: ["echo", "schedules", "ran"],
50832
+ summary: "Report a scheduled post's run (the agent's): ok, failed or unanswered.",
50833
+ args: [KEY_ARG, { name: "status", required: true, description: "ok, failed or unanswered." }],
50834
+ flags: [
50835
+ { name: "note", type: "string", description: "A word on the run (2 differences)." },
50836
+ { name: "at", type: "string", description: "When it ran (ISO); default now." }
50837
+ ],
50838
+ scopes: [...echoScheduleOperations.report.scopes],
50839
+ returns: "EchoSchedule",
50840
+ notes: "Clears a run asked for."
50841
+ },
50842
+ run: async ({ args, flags, requireClient }) => {
50843
+ const note = flagString(flags, "note");
50844
+ const at = flagString(flags, "at");
50845
+ return {
50846
+ data: await requireClient().post(keyPath(echoScheduleOperations.report, args), {
50847
+ status: oneOf(requireArg(args, 1, "status"), STATUSES, "status"),
50848
+ ...note ? { note } : {},
50849
+ ...at ? { at } : {}
50850
+ }),
50851
+ render: renderRecord
50852
+ };
50853
+ }
50854
+ },
50855
+ {
50856
+ spec: {
50857
+ path: ["echo", "schedules", "rm"],
50858
+ summary: "Remove a scheduled post (the agent no longer runs it).",
50859
+ args: [KEY_ARG],
50860
+ flags: [],
50861
+ scopes: [...echoScheduleOperations.remove.scopes],
50862
+ returns: "nothing",
50863
+ notes: "An unknown key is a 404."
50864
+ },
50865
+ run: async ({ args, requireClient }) => {
50866
+ await requireClient().delete(keyPath(echoScheduleOperations.remove, args));
50867
+ return { data: { removed: requireArg(args, 0, "job key") }, render: renderRecord };
50868
+ }
50869
+ }
50870
+ ];
50871
+
50415
50872
  // src/commands/files.ts
50416
50873
  import { readFileSync as readFileSync5, writeFileSync as writeFileSync2 } from "fs";
50417
50874
  import { basename as basename2 } from "path";
50418
- var commands17 = [
50875
+ var commands18 = [
50419
50876
  {
50420
50877
  spec: {
50421
50878
  path: ["files", "list"],
@@ -50585,7 +51042,7 @@ var commands17 = [
50585
51042
  ];
50586
51043
 
50587
51044
  // src/commands/food.ts
50588
- var commands18 = [
51045
+ var commands19 = [
50589
51046
  {
50590
51047
  spec: {
50591
51048
  path: ["foods", "search"],
@@ -51140,7 +51597,7 @@ var commands18 = [
51140
51597
  // src/commands/guest-lists.ts
51141
51598
  import { writeFileSync as writeFileSync3 } from "fs";
51142
51599
  import { basename as basename3 } from "path";
51143
- var commands19 = [
51600
+ var commands20 = [
51144
51601
  {
51145
51602
  spec: {
51146
51603
  path: ["guest-lists", "overview"],
@@ -51230,7 +51687,7 @@ var commands19 = [
51230
51687
  ];
51231
51688
 
51232
51689
  // src/commands/guests.ts
51233
- var commands20 = [
51690
+ var commands21 = [
51234
51691
  {
51235
51692
  spec: {
51236
51693
  path: ["guests", "sent"],
@@ -51315,7 +51772,7 @@ function renderItems(data, mode) {
51315
51772
  var habitArg = { name: "id", required: true, description: "The checklist habit's ULID." };
51316
51773
  var itemArg = { name: "item-id", required: true, description: "The item's ULID." };
51317
51774
  var NOT_CHECKLIST = "A habit that isn't a checklist answers 409.";
51318
- var commands21 = [
51775
+ var commands22 = [
51319
51776
  {
51320
51777
  spec: {
51321
51778
  path: ["habit", "items"],
@@ -51669,7 +52126,7 @@ function seasonFromFlags(flags) {
51669
52126
  const season = flagString(flags, "season");
51670
52127
  return season === undefined ? {} : { activeMonths: seasonFromFlag(season) };
51671
52128
  }
51672
- var commands22 = [
52129
+ var commands23 = [
51673
52130
  {
51674
52131
  spec: {
51675
52132
  path: ["habits", "create"],
@@ -52918,7 +53375,7 @@ function healthRecordHandlers() {
52918
53375
  }
52919
53376
  return out;
52920
53377
  }
52921
- var commands23 = pairCommands(HEALTH_COMMAND_SPECS, {
53378
+ var commands24 = pairCommands(HEALTH_COMMAND_SPECS, {
52922
53379
  ...healthRecordHandlers(),
52923
53380
  "health record": async ({ flags, requireClient }) => {
52924
53381
  const body = parseInput(logHealthInputSchema, readDataFlag(flags));
@@ -53233,7 +53690,7 @@ var commands23 = pairCommands(HEALTH_COMMAND_SPECS, {
53233
53690
  });
53234
53691
 
53235
53692
  // src/commands/house.ts
53236
- var commands24 = [
53693
+ var commands25 = [
53237
53694
  {
53238
53695
  spec: {
53239
53696
  path: ["house"],
@@ -53515,7 +53972,7 @@ function renderSorting(data, _mode) {
53515
53972
  ].join(`
53516
53973
  `);
53517
53974
  }
53518
- var commands25 = [
53975
+ var commands26 = [
53519
53976
  defineCommand({
53520
53977
  operation: inboxOperations.list,
53521
53978
  path: ["inbox"],
@@ -53607,7 +54064,7 @@ var commands25 = [
53607
54064
  ];
53608
54065
 
53609
54066
  // src/commands/incidents.ts
53610
- var commands26 = [
54067
+ var commands27 = [
53611
54068
  {
53612
54069
  spec: {
53613
54070
  path: ["incidents", "open"],
@@ -53836,7 +54293,7 @@ function journalDateArg(args, verb) {
53836
54293
  }
53837
54294
  return date;
53838
54295
  }
53839
- var commands27 = [
54296
+ var commands28 = [
53840
54297
  defineCommand({
53841
54298
  operation: journalOperations.day,
53842
54299
  path: ["journal", "day"],
@@ -54399,7 +54856,7 @@ function renderCreatedKey(data, mode) {
54399
54856
  ].join(`
54400
54857
  `);
54401
54858
  }
54402
- var commands28 = [
54859
+ var commands29 = [
54403
54860
  {
54404
54861
  spec: {
54405
54862
  path: ["keys", "list"],
@@ -54535,7 +54992,7 @@ var KIND_FLAG2 = {
54535
54992
  type: "string",
54536
54993
  description: "The kind of an unknown word (pages, eggs, health, note, or a word taught before); remembered for the Space."
54537
54994
  };
54538
- var commands29 = [
54995
+ var commands30 = [
54539
54996
  {
54540
54997
  spec: {
54541
54998
  path: ["log"],
@@ -54610,7 +55067,7 @@ var commands29 = [
54610
55067
  ];
54611
55068
 
54612
55069
  // src/commands/mail-campaigns.ts
54613
- var commands30 = [
55070
+ var commands31 = [
54614
55071
  {
54615
55072
  spec: {
54616
55073
  path: ["mail-campaigns", "list"],
@@ -54925,7 +55382,7 @@ async function serveMcp(io, target) {
54925
55382
  }
54926
55383
 
54927
55384
  // src/commands/mcp.ts
54928
- var commands31 = [
55385
+ var commands32 = [
54929
55386
  {
54930
55387
  spec: {
54931
55388
  path: ["mcp"],
@@ -54970,7 +55427,7 @@ var commands31 = [
54970
55427
  ];
54971
55428
 
54972
55429
  // src/commands/members.ts
54973
- var commands32 = [
55430
+ var commands33 = [
54974
55431
  {
54975
55432
  spec: {
54976
55433
  path: ["invite", "create"],
@@ -55095,7 +55552,7 @@ var commands32 = [
55095
55552
  ];
55096
55553
 
55097
55554
  // src/commands/metrics.ts
55098
- var commands33 = [
55555
+ var commands34 = [
55099
55556
  {
55100
55557
  spec: {
55101
55558
  path: ["metrics", "list"],
@@ -55223,7 +55680,7 @@ async function setModuleVisibility(args, requireClient, on) {
55223
55680
  render: renderRecord
55224
55681
  };
55225
55682
  }
55226
- var commands34 = [
55683
+ var commands35 = [
55227
55684
  {
55228
55685
  spec: {
55229
55686
  path: ["modules", "list"],
@@ -55452,7 +55909,7 @@ function shareFlag(flags) {
55452
55909
  function localMonth(now) {
55453
55910
  return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}`;
55454
55911
  }
55455
- var commands35 = [
55912
+ var commands36 = [
55456
55913
  defineCommand({
55457
55914
  operation: moneyOperations.listAccounts,
55458
55915
  path: ["money", "accounts"],
@@ -56621,7 +57078,7 @@ var commands35 = [
56621
57078
  ];
56622
57079
 
56623
57080
  // src/commands/notes.ts
56624
- var commands36 = [
57081
+ var commands37 = [
56625
57082
  {
56626
57083
  spec: {
56627
57084
  path: ["notes", "backlinks"],
@@ -56743,7 +57200,7 @@ var commands36 = [
56743
57200
  ];
56744
57201
 
56745
57202
  // src/commands/orca.ts
56746
- var commands37 = [
57203
+ var commands38 = [
56747
57204
  {
56748
57205
  spec: {
56749
57206
  path: ["orca", "list"],
@@ -57109,7 +57566,7 @@ function linkBody(args) {
57109
57566
  return parseInput(familyTreeLinkInputSchema, { kind, a: ref, b: other });
57110
57567
  throw usageError("the kind is parent, child or partner");
57111
57568
  }
57112
- var commands38 = [
57569
+ var commands39 = [
57113
57570
  {
57114
57571
  spec: {
57115
57572
  path: ["people", "propose"],
@@ -57798,7 +58255,7 @@ var commands38 = [
57798
58255
 
57799
58256
  // src/commands/places.ts
57800
58257
  import { readFileSync as readFileSync10 } from "fs";
57801
- var commands39 = [
58258
+ var commands40 = [
57802
58259
  {
57803
58260
  spec: {
57804
58261
  path: ["places", "import"],
@@ -57855,7 +58312,7 @@ async function planDecision({ args, requireClient }, verb) {
57855
58312
  render: renderPlan
57856
58313
  };
57857
58314
  }
57858
- var commands40 = [
58315
+ var commands41 = [
57859
58316
  {
57860
58317
  spec: {
57861
58318
  path: ["plans", "list"],
@@ -58082,7 +58539,7 @@ var commands40 = [
58082
58539
  ];
58083
58540
 
58084
58541
  // src/commands/presets.ts
58085
- var commands41 = [
58542
+ var commands42 = [
58086
58543
  {
58087
58544
  spec: {
58088
58545
  path: ["presets", "list"],
@@ -58179,7 +58636,7 @@ function renderReviewSummary(data, mode) {
58179
58636
  return out.join(`
58180
58637
  `);
58181
58638
  }
58182
- var commands42 = [
58639
+ var commands43 = [
58183
58640
  {
58184
58641
  spec: {
58185
58642
  path: ["progress"],
@@ -58388,7 +58845,7 @@ function renderUpdates(data, mode) {
58388
58845
  return updates.map((u) => updateLine(u, mode)).join(`
58389
58846
  `);
58390
58847
  }
58391
- var commands43 = [
58848
+ var commands44 = [
58392
58849
  defineCommand({
58393
58850
  operation: projectOperations.update,
58394
58851
  path: ["projects", "set"],
@@ -58985,7 +59442,7 @@ var routineCommands = [
58985
59442
  }
58986
59443
  }
58987
59444
  ];
58988
- var commands44 = [
59445
+ var commands45 = [
58989
59446
  ...routineCommands,
58990
59447
  {
58991
59448
  spec: {
@@ -59108,7 +59565,7 @@ var commands44 = [
59108
59565
  ];
59109
59566
 
59110
59567
  // src/commands/rsvp-answers.ts
59111
- var commands45 = [
59568
+ var commands46 = [
59112
59569
  {
59113
59570
  spec: {
59114
59571
  path: ["rsvp-answers", "list"],
@@ -59162,7 +59619,7 @@ var commands45 = [
59162
59619
  ];
59163
59620
 
59164
59621
  // src/commands/rsvp-links.ts
59165
- var commands46 = [
59622
+ var commands47 = [
59166
59623
  {
59167
59624
  spec: {
59168
59625
  path: ["rsvp-links", "list"],
@@ -59258,7 +59715,7 @@ var commands46 = [
59258
59715
  ];
59259
59716
 
59260
59717
  // src/commands/rsvp-questions.ts
59261
- var commands47 = [
59718
+ var commands48 = [
59262
59719
  {
59263
59720
  spec: {
59264
59721
  path: ["rsvp-questions", "presets"],
@@ -59830,7 +60287,7 @@ function sessionFlags(flags) {
59830
60287
  body.occurredOn = on;
59831
60288
  return body;
59832
60289
  }
59833
- var commands48 = [
60290
+ var commands49 = [
59834
60291
  {
59835
60292
  spec: {
59836
60293
  path: ["runs", "change"],
@@ -60147,7 +60604,7 @@ var commands48 = [
60147
60604
  ];
60148
60605
 
60149
60606
  // src/commands/search.ts
60150
- var commands49 = [
60607
+ var commands50 = [
60151
60608
  {
60152
60609
  spec: {
60153
60610
  path: ["search"],
@@ -60180,7 +60637,7 @@ var commands49 = [
60180
60637
  ];
60181
60638
 
60182
60639
  // src/commands/seating-proposals.ts
60183
- var commands50 = [
60640
+ var commands51 = [
60184
60641
  {
60185
60642
  spec: {
60186
60643
  path: ["seating-proposals", "list"],
@@ -60267,7 +60724,7 @@ var commands50 = [
60267
60724
  ];
60268
60725
 
60269
60726
  // src/commands/sensors.ts
60270
- var commands51 = [
60727
+ var commands52 = [
60271
60728
  {
60272
60729
  spec: {
60273
60730
  path: ["sensors", "status"],
@@ -60427,7 +60884,7 @@ var commands51 = [
60427
60884
  ];
60428
60885
 
60429
60886
  // src/commands/settings.ts
60430
- var commands52 = [
60887
+ var commands53 = [
60431
60888
  {
60432
60889
  spec: {
60433
60890
  path: ["settings", "get"],
@@ -60461,7 +60918,7 @@ var commands52 = [
60461
60918
  ];
60462
60919
 
60463
60920
  // src/commands/sharing.ts
60464
- var commands53 = [
60921
+ var commands54 = [
60465
60922
  {
60466
60923
  spec: {
60467
60924
  path: ["share"],
@@ -60594,7 +61051,7 @@ var commands53 = [
60594
61051
  ];
60595
61052
 
60596
61053
  // src/commands/space.ts
60597
- var commands54 = [
61054
+ var commands55 = [
60598
61055
  {
60599
61056
  spec: {
60600
61057
  path: ["space", "address"],
@@ -60650,7 +61107,7 @@ var commands54 = [
60650
61107
  ];
60651
61108
 
60652
61109
  // src/commands/tap-tags.ts
60653
- var commands55 = [
61110
+ var commands56 = [
60654
61111
  {
60655
61112
  spec: {
60656
61113
  path: ["tap-tags", "tap"],
@@ -60678,7 +61135,7 @@ var BY = {
60678
61135
  type: "string",
60679
61136
  description: "The blocking task's ref (DO-147) or ULID."
60680
61137
  };
60681
- var commands56 = [
61138
+ var commands57 = [
60682
61139
  defineCommand({
60683
61140
  operation: taskBlockOperations.addBlocker,
60684
61141
  path: ["tasks", "block"],
@@ -60744,7 +61201,7 @@ function renderSeries(data, mode) {
60744
61201
  }).join(`
60745
61202
  `);
60746
61203
  }
60747
- var commands57 = [
61204
+ var commands58 = [
60748
61205
  defineCommand({
60749
61206
  operation: taskSeriesOperations.make,
60750
61207
  path: ["tasks", "make-series"],
@@ -60899,7 +61356,7 @@ function repeatFromFlags(flags) {
60899
61356
  out.anchor = "from_completion";
60900
61357
  return out;
60901
61358
  }
60902
- var commands58 = [
61359
+ var commands59 = [
60903
61360
  {
60904
61361
  spec: {
60905
61362
  path: ["capture"],
@@ -61357,7 +61814,7 @@ var commands58 = [
61357
61814
  ];
61358
61815
 
61359
61816
  // src/commands/time-blocks.ts
61360
- var commands59 = [
61817
+ var commands60 = [
61361
61818
  {
61362
61819
  spec: {
61363
61820
  path: ["time-blocks", "record"],
@@ -61549,7 +62006,7 @@ function renderLandedCounts(data, mode) {
61549
62006
  return out.join(`
61550
62007
  `);
61551
62008
  }
61552
- var commands60 = [
62009
+ var commands61 = [
61553
62010
  {
61554
62011
  spec: {
61555
62012
  path: ["today"],
@@ -61921,7 +62378,7 @@ function renderViews(data, mode) {
61921
62378
  function renderView(data, mode) {
61922
62379
  return renderViews([data], mode);
61923
62380
  }
61924
- var commands61 = [
62381
+ var commands62 = [
61925
62382
  defineCommand({
61926
62383
  operation: workViewOperations.list,
61927
62384
  path: ["views", "list"],
@@ -62040,7 +62497,7 @@ var commands61 = [
62040
62497
  ];
62041
62498
 
62042
62499
  // src/commands/worktree-links.ts
62043
- var commands62 = [
62500
+ var commands63 = [
62044
62501
  {
62045
62502
  spec: {
62046
62503
  path: ["worktree-links", "list"],
@@ -62208,7 +62665,8 @@ var FEATURE_COMMANDS = [
62208
62665
  ...commands59,
62209
62666
  ...commands60,
62210
62667
  ...commands61,
62211
- ...commands62
62668
+ ...commands62,
62669
+ ...commands63
62212
62670
  ];
62213
62671
 
62214
62672
  // src/registry.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@robbeverhelst/do",
3
- "version": "1.419.0",
3
+ "version": "1.420.0",
4
4
  "private": false,
5
5
  "description": "do — the agent-drivable CLI over the public /api/v1 surface",
6
6
  "homepage": "https://github.com/robbeverhelst/do/tree/main/apps/cli",