@wirecat/cli-core 0.511.0 → 0.513.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 (43) hide show
  1. package/CHANGELOG.md +70 -0
  2. package/dist/calendar/mcp/index.d.ts +46 -10
  3. package/dist/calendar/mcp/index.js +60 -25
  4. package/dist/cli/list-query.d.ts +4 -2
  5. package/dist/cli/list-query.js +3 -3
  6. package/dist/cli/messenger/tasks-command.js +4 -5
  7. package/dist/entities/index.d.ts +35 -8
  8. package/dist/entities/task-results.d.ts +22 -7
  9. package/dist/entities/task-results.js +4 -1
  10. package/dist/entities/task.d.ts +18 -1
  11. package/dist/entities/task.js +12 -1
  12. package/dist/errors/reasons.js +1 -0
  13. package/dist/services/task-rules.js +2 -2
  14. package/dist/services/tasks.d.ts +1 -1
  15. package/dist/services/tasks.js +7 -5
  16. package/dist/store/index.d.ts +4 -1
  17. package/dist/store/index.js +2 -0
  18. package/dist/store/sqlite/knowledge.js +3 -2
  19. package/dist/store/sqlite/manifest.js +1 -0
  20. package/dist/store/sqlite/migrations.generated.js +12 -0
  21. package/dist/store/sqlite/person-preparation.js +1 -1
  22. package/dist/store/sqlite/schema.d.ts +48 -0
  23. package/dist/store/sqlite/schema.js +3 -0
  24. package/dist/store/sqlite/tags.d.ts +1 -2
  25. package/dist/store/sqlite/tags.js +18 -3
  26. package/dist/store/sqlite/task-board.d.ts +16 -0
  27. package/dist/store/sqlite/task-board.js +192 -0
  28. package/dist/store/sqlite/task-candidates.js +1 -1
  29. package/dist/store/sqlite/task-category-settings.js +1 -1
  30. package/dist/store/sqlite/task-close-store.js +6 -4
  31. package/dist/store/sqlite/task-pairs.js +4 -3
  32. package/dist/store/sqlite/task-relations.js +3 -2
  33. package/dist/store/sqlite/tasks.js +16 -5
  34. package/dist/store/sqlite/work-tasks.d.ts +96 -9
  35. package/dist/store/sqlite/work-tasks.js +236 -32
  36. package/dist/tasks/index.d.ts +2 -1
  37. package/dist/tasks/index.js +2 -1
  38. package/dist/tasks/model.d.ts +5 -2
  39. package/dist/tasks/model.js +5 -2
  40. package/dist/tasks/priority.d.ts +18 -0
  41. package/dist/tasks/priority.js +37 -0
  42. package/dist/tasks/service.js +2 -2
  43. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,76 @@ shape of this file.
7
7
 
8
8
  ## Unreleased
9
9
 
10
+ ## 0.513.0 — 01.11.2026
11
+
12
+ ### Added
13
+
14
+ - **`tasks.board(query, { limit, offset, sort, descending, zone })` and `tasks.boardCounts(query)`** list the owner's
15
+ project tasks across every project (an account's inbox is left out) with a Lucene query over `PROJECT_TASK_FIELDS`:
16
+ `state`, `kind`, `project` (`project:*` for all), `assignee` (`any`, `none`, `"person:12"`), `priority`,
17
+ `due` and `closed` with ranges, `overdue`, `ready`, and `text`, the words of the title and description
18
+ (prefixes; a task key too). The board sorts by `TASK_SORTS` and returns the total; the counts give how many tasks
19
+ hold each project, assignee, priority and state, each without the query's own terms on that field.
20
+ - **Store version 41: a decimal priority, an agent and a revision on every task** (`minCompatible` stays 34).
21
+ `tasks.priority_score` holds 0 to 1, higher first; `priorityLabel` reads it as low, medium, high or critical by
22
+ quarters. The old 0 (urgent) … 4 (low) became 0.875, 0.625, 0.375, 0.1875 and 0.0625, and the integer `priority`
23
+ column is still written from the score, so an older build reads a familiar number; when an older build writes the
24
+ integer, a trigger moves the score with it. `tasks.agent` names the agent working on a task, apart from its
25
+ assignees and its claim. `tasks.revision` is bumped by a trigger on every update, by any build.
26
+ - **`tasks.move(id, { status, before | after }, by)`** puts a project task beside another in its board column by giving
27
+ it a priority between its neighbours; the answer says when the label changed, and which tasks were spread out again
28
+ when the neighbours left no room. Into an empty column it needs no neighbour.
29
+ - **A stale write is refused**: `edit`, `assign`, `unassign` and `move` take `{ revision }` and refuse another with
30
+ `configuration_error`, reason `task.stale`, and the task's current revision. `assign` and `unassign` now bump the
31
+ task's revision too.
32
+ - **Every task write is in `task_events`**, in the same transaction: new kinds `agent`, `claimed`, `released`,
33
+ `next-check` (a follow-up time used to leave no event), `resolution`, `verdict`, `close-certainty` and `tags` (a
34
+ tag added to or removed from a task). The event id only grows, so it orders changes.
35
+ - **`priority:` and `agent:` query fields** on the board: `priority:high`, `priority:none`, `priority:[medium TO
36
+ critical]`, `priority:[0.6 TO 1]`; `agent:hermes`, `agent:none`.
37
+ - **The `task` entity** may carry `priority_label`, `agent`, `revision`, `assignments`, `ready` and `blocked_by`, as a
38
+ project task list gives them.
39
+
40
+ ### Changed — may break callers
41
+
42
+ - **A task's `priority` is a number from 0 to 1, higher first**, in `TaskDetails`, `TaskFields` and the task card
43
+ (`priority_label` beside it); it was 0 (urgent) … 4 (low). Lists order by it highest first. `tasks update
44
+ --priority` takes low, medium, high, critical or none, and still reads 0–4 as before.
45
+
46
+ ## 0.512.0 — 01.11.2026
47
+
48
+ ### Added
49
+
50
+ - **A project task has two more open states: `todo` and `in_progress`.** `TASK_STATES` is `open`, `todo`,
51
+ `in_progress`, `done`, `dismissed`; `CLOSED_STATES` and `isClosedState` name the closed ones. `tasks.edit` moves a
52
+ project task between any two of them, records each move as a `status` event, sets `started_at` the first time it
53
+ enters `in_progress`, and reopens a closed task: `closed_at`, who closed it and its reason are cleared. Readiness,
54
+ `readyTasks`, claims, a person's open tasks, reminders, duplicate checks and category counts treat both new states as
55
+ open work. A task from a message stays open or closed.
56
+ - **`tasks.board(query, { limit, offset, sort, descending, zone })` and `tasks.boardCounts(query)`** list the owner's
57
+ project tasks across every project (an account's inbox is left out) with a Lucene query over `PROJECT_TASK_FIELDS`:
58
+ `state`, `kind`, `project` (`project:*` for all), `assignee` (`any`, `none`, `"person:12"`), `priority` with
59
+ ranges, `due` and `closed` with ranges, `overdue`, `ready`, and `text`, the words of the title and description
60
+ (prefixes; a task key too). The board sorts by `TASK_SORTS` and returns the total; the counts give how many tasks
61
+ hold each project, assignee, priority and state, each without the query's own terms on that field.
62
+ - **`tasks.taskPeople()`** lists the owner and everyone who holds a role on a live task, with how many tasks.
63
+ - **`tasks.events(id)`** names who acted: `actor.name` is the person's or the bot's name, or null.
64
+ - **`listQuery(text, registry, command, { defaultField })`** reads a bare word as that field instead of refusing it.
65
+ - **`events_list` takes `page`**, as `events list --page` does. Without `account_id` each page is cut from every
66
+ account's events merged in time order, so it reads at most each account's first 1000 events; a page past that is
67
+ refused with `validation_error` and asks for `account_id`.
68
+
69
+ ### Changed — may break callers
70
+
71
+ - **`ClosedState` is `done | dismissed`**, no longer every state but `open`; a check of `state === "open"` for "not
72
+ closed" misses `todo` and `in_progress` — use `isClosedState`.
73
+ - **The calendar MCP tools `event_create` and `event_update` take `operation_id`, not `id`**, as `events create` and
74
+ `events update --following` take `--operation-id` since 0.510.0. The value is the same: the `operation_id` a lost
75
+ write's `outcome_unknown` names, and that error now says "repeat with operation_id". `id` is refused as an unknown
76
+ argument; change agent prompts that pass it.
77
+ - **`events_list` answers the shared list shape**: `page: { mode: "page", limit, has_more, next_page }` and a
78
+ `page.next` step, where it answered `page: 1` and `hasMore`. Read `page.has_more` instead of `hasMore`.
79
+
10
80
  ## 0.511.0 — 31.10.2026
11
81
 
12
82
  ## 0.510.0 — 31.10.2026
@@ -17,6 +17,7 @@ export declare const calendarTools: ({
17
17
  query?: undefined;
18
18
  timezone?: undefined;
19
19
  limit?: undefined;
20
+ page?: undefined;
20
21
  event?: undefined;
21
22
  } | {
22
23
  account_id: {
@@ -35,12 +36,19 @@ export declare const calendarTools: ({
35
36
  type: string;
36
37
  minimum: number;
37
38
  maximum: number;
39
+ description: string;
40
+ };
41
+ page: {
42
+ type: string;
43
+ minimum: number;
44
+ description: string;
38
45
  };
39
46
  event?: undefined;
40
47
  } | {
41
48
  query?: undefined;
42
49
  timezone?: undefined;
43
50
  limit?: undefined;
51
+ page?: undefined;
44
52
  event: {
45
53
  type: string;
46
54
  minLength: number;
@@ -53,6 +61,7 @@ export declare const calendarTools: ({
53
61
  query?: undefined;
54
62
  timezone?: undefined;
55
63
  limit?: undefined;
64
+ page?: undefined;
56
65
  event?: undefined;
57
66
  account_id?: undefined;
58
67
  };
@@ -78,6 +87,7 @@ export declare const calendarTools: ({
78
87
  query?: undefined;
79
88
  timezone?: undefined;
80
89
  limit?: undefined;
90
+ page?: undefined;
81
91
  event?: undefined;
82
92
  } | {
83
93
  account_id: {
@@ -96,12 +106,19 @@ export declare const calendarTools: ({
96
106
  type: string;
97
107
  minimum: number;
98
108
  maximum: number;
109
+ description: string;
110
+ };
111
+ page: {
112
+ type: string;
113
+ minimum: number;
114
+ description: string;
99
115
  };
100
116
  event?: undefined;
101
117
  } | {
102
118
  query?: undefined;
103
119
  timezone?: undefined;
104
120
  limit?: undefined;
121
+ page?: undefined;
105
122
  event: {
106
123
  type: string;
107
124
  minLength: number;
@@ -114,6 +131,7 @@ export declare const calendarTools: ({
114
131
  query?: undefined;
115
132
  timezone?: undefined;
116
133
  limit?: undefined;
134
+ page?: undefined;
117
135
  event?: undefined;
118
136
  account_id?: undefined;
119
137
  };
@@ -139,6 +157,7 @@ export declare const calendarTools: ({
139
157
  query?: undefined;
140
158
  timezone?: undefined;
141
159
  limit?: undefined;
160
+ page?: undefined;
142
161
  event?: undefined;
143
162
  } | {
144
163
  account_id: {
@@ -157,12 +176,19 @@ export declare const calendarTools: ({
157
176
  type: string;
158
177
  minimum: number;
159
178
  maximum: number;
179
+ description: string;
180
+ };
181
+ page: {
182
+ type: string;
183
+ minimum: number;
184
+ description: string;
160
185
  };
161
186
  event?: undefined;
162
187
  } | {
163
188
  query?: undefined;
164
189
  timezone?: undefined;
165
190
  limit?: undefined;
191
+ page?: undefined;
166
192
  event: {
167
193
  type: string;
168
194
  minLength: number;
@@ -175,6 +201,7 @@ export declare const calendarTools: ({
175
201
  query?: undefined;
176
202
  timezone?: undefined;
177
203
  limit?: undefined;
204
+ page?: undefined;
178
205
  event?: undefined;
179
206
  account_id?: undefined;
180
207
  };
@@ -200,6 +227,7 @@ export declare const calendarTools: ({
200
227
  query?: undefined;
201
228
  timezone?: undefined;
202
229
  limit?: undefined;
230
+ page?: undefined;
203
231
  event?: undefined;
204
232
  } | {
205
233
  account_id: {
@@ -218,12 +246,19 @@ export declare const calendarTools: ({
218
246
  type: string;
219
247
  minimum: number;
220
248
  maximum: number;
249
+ description: string;
250
+ };
251
+ page: {
252
+ type: string;
253
+ minimum: number;
254
+ description: string;
221
255
  };
222
256
  event?: undefined;
223
257
  } | {
224
258
  query?: undefined;
225
259
  timezone?: undefined;
226
260
  limit?: undefined;
261
+ page?: undefined;
227
262
  event: {
228
263
  type: string;
229
264
  minLength: number;
@@ -236,6 +271,7 @@ export declare const calendarTools: ({
236
271
  query?: undefined;
237
272
  timezone?: undefined;
238
273
  limit?: undefined;
274
+ page?: undefined;
239
275
  event?: undefined;
240
276
  account_id?: undefined;
241
277
  };
@@ -320,7 +356,7 @@ export declare const calendarWriteTools: ({
320
356
  type: string;
321
357
  description: string;
322
358
  };
323
- id: {
359
+ operation_id: {
324
360
  type: string;
325
361
  minLength: number;
326
362
  description: string;
@@ -399,7 +435,7 @@ export declare const calendarWriteTools: ({
399
435
  type: string;
400
436
  description: string;
401
437
  };
402
- id: {
438
+ operation_id: {
403
439
  type: string;
404
440
  minLength: number;
405
441
  description: string;
@@ -554,7 +590,7 @@ export declare const calendarWriteTools: ({
554
590
  type: string;
555
591
  description: string;
556
592
  };
557
- id: {
593
+ operation_id: {
558
594
  type: string;
559
595
  minLength: number;
560
596
  description: string;
@@ -633,7 +669,7 @@ export declare const calendarWriteTools: ({
633
669
  type: string;
634
670
  description: string;
635
671
  };
636
- id: {
672
+ operation_id: {
637
673
  type: string;
638
674
  minLength: number;
639
675
  description: string;
@@ -788,7 +824,7 @@ export declare const calendarWriteTools: ({
788
824
  type: string;
789
825
  description: string;
790
826
  };
791
- id: {
827
+ operation_id: {
792
828
  type: string;
793
829
  minLength: number;
794
830
  description: string;
@@ -867,7 +903,7 @@ export declare const calendarWriteTools: ({
867
903
  type: string;
868
904
  description: string;
869
905
  };
870
- id: {
906
+ operation_id: {
871
907
  type: string;
872
908
  minLength: number;
873
909
  description: string;
@@ -1022,7 +1058,7 @@ export declare const calendarWriteTools: ({
1022
1058
  type: string;
1023
1059
  description: string;
1024
1060
  };
1025
- id: {
1061
+ operation_id: {
1026
1062
  type: string;
1027
1063
  minLength: number;
1028
1064
  description: string;
@@ -1101,7 +1137,7 @@ export declare const calendarWriteTools: ({
1101
1137
  type: string;
1102
1138
  description: string;
1103
1139
  };
1104
- id: {
1140
+ operation_id: {
1105
1141
  type: string;
1106
1142
  minLength: number;
1107
1143
  description: string;
@@ -1256,7 +1292,7 @@ export declare const calendarWriteTools: ({
1256
1292
  type: string;
1257
1293
  description: string;
1258
1294
  };
1259
- id: {
1295
+ operation_id: {
1260
1296
  type: string;
1261
1297
  minLength: number;
1262
1298
  description: string;
@@ -1335,7 +1371,7 @@ export declare const calendarWriteTools: ({
1335
1371
  type: string;
1336
1372
  description: string;
1337
1373
  };
1338
- id: {
1374
+ operation_id: {
1339
1375
  type: string;
1340
1376
  minLength: number;
1341
1377
  description: string;
@@ -1,4 +1,5 @@
1
1
  import { CliError, errorObjectOf, mcpErrorResult } from "@wirecat/cli-base";
2
+ import { listOf } from "../../cli/envelope.js";
2
3
  import { isCliFailure } from "../../errors/failures.js";
3
4
  import { listed } from "../../meetings/index.js";
4
5
  import { agentResult, UNTRUSTED_NEUTRAL } from "../../meetings/mcp/index.js";
@@ -30,7 +31,13 @@ export const calendarTools = [
30
31
  description: "stored events, earliest first; `query` takes field terms joined by AND: starts_at (>=, <, or " +
31
32
  "[a TO b}), ends_at>=, changed_at>= (events new, moved or cancelled since, each with change and was), " +
32
33
  "calendar:<id>; a date in the zone given, UTC when absent; without starts_at or ends_at, from today on",
33
- properties: { account_id: integer, query: text, timezone: text, limit: { ...integer, maximum: 1000 } },
34
+ properties: {
35
+ account_id: integer,
36
+ query: text,
37
+ timezone: text,
38
+ limit: { ...integer, maximum: 1000, description: "events per page" },
39
+ page: { ...integer, description: "which page, starting at 1; page.next_page gives the next" },
40
+ },
34
41
  required: [],
35
42
  },
36
43
  {
@@ -63,7 +70,7 @@ const following = {
63
70
  type: "boolean",
64
71
  description: "this occurrence and every later one: the series ends before it, and a new one starts with the change",
65
72
  };
66
- const newId = { ...text, description: "the id an outcome_unknown named: a retry finds that event instead of a new one" };
73
+ const operationId = (description) => ({ ...text, description });
67
74
  const notify = {
68
75
  type: "boolean",
69
76
  description: "whether the provider mails the other attendees; required when there are any",
@@ -98,7 +105,7 @@ export const calendarWriteTools = [
98
105
  calendar: text,
99
106
  ...fields,
100
107
  notify,
101
- id: newId,
108
+ operation_id: operationId("the operation_id a create that ended in outcome_unknown named: a retry finds that event"),
102
109
  },
103
110
  required: ["calendar", "title"],
104
111
  destructive: false,
@@ -107,7 +114,14 @@ export const calendarWriteTools = [
107
114
  name: "event_update",
108
115
  description: "change an event, with series every occurrence of its repeating event and its repeat rule, or with following " +
109
116
  "this occurrence and every later one",
110
- properties: { ...target, ...fields, series: flag, following, notify, id: newId },
117
+ properties: {
118
+ ...target,
119
+ ...fields,
120
+ series: flag,
121
+ following,
122
+ notify,
123
+ operation_id: operationId("with following, the operation_id an outcome_unknown named: a retry finds that new series"),
124
+ },
111
125
  required: ["event"],
112
126
  destructive: true,
113
127
  },
@@ -159,7 +173,7 @@ const argumentsOf = (name, input) => {
159
173
  if (!Object.hasOwn(args, key))
160
174
  throw new CliError("validation_error", `missing argument: ${key}`);
161
175
  for (const [key, value] of Object.entries(args))
162
- if (["account_id", "limit"].includes(key) &&
176
+ if (["account_id", "limit", "page"].includes(key) &&
163
177
  (typeof value !== "number" || !Number.isSafeInteger(value) || value < 1))
164
178
  throw new CliError("validation_error", `${key} must be a positive integer`);
165
179
  else if ([
@@ -172,7 +186,7 @@ const argumentsOf = (name, input) => {
172
186
  "end_time",
173
187
  "start_date",
174
188
  "end_date",
175
- "id",
189
+ "operation_id",
176
190
  "repeat",
177
191
  "to_calendar",
178
192
  ].includes(key) &&
@@ -228,23 +242,9 @@ export const callCalendarTool = async (store, name, input, { accountIds, failure
228
242
  case "store_status":
229
243
  answer = listed((await Promise.all(accounts.map((id) => calendarStatus(store, id, { profile: profileOf(id), now }).then(({ items }) => items)))).flat());
230
244
  break;
231
- case "events_list": {
232
- const limit = args.limit ?? 100;
233
- const lists = await Promise.all(accounts.map(async (accountId) => eventsAnswer(store, await eventsFilter(args.query, {
234
- store,
235
- accountId,
236
- zone: args.timezone ?? "UTC",
237
- now,
238
- }).then((filter) => filter && { ...filter, limit }))));
239
- const items = lists
240
- .flatMap((one) => one.items)
241
- .sort((a, b) => (a.starts_at ?? "").localeCompare(b.starts_at ?? ""));
242
- answer = listed(items.slice(0, limit), {
243
- limit,
244
- hasMore: items.length > limit || lists.some((one) => one.hasMore),
245
- });
245
+ case "events_list":
246
+ answer = await eventsList(store, args, accounts, now);
246
247
  break;
247
- }
248
248
  case "event_show":
249
249
  answer = await eventAnswer((await eventIn()).details);
250
250
  break;
@@ -270,6 +270,41 @@ export const callCalendarTool = async (store, name, input, { accountIds, failure
270
270
  return { content, structuredContent, isError: true };
271
271
  }
272
272
  };
273
+ const EVENTS_READ = 1000;
274
+ /**
275
+ * One page of events across the accounts. Page n of several accounts is not each account's page n, so each one is
276
+ * read from its first event up to the page's end and the merge is cut there.
277
+ */
278
+ const eventsList = async (store, args, accounts, now) => {
279
+ const limit = args.limit ?? 100;
280
+ const page = args.page ?? 1;
281
+ const end = page * limit;
282
+ const merging = accounts.length > 1;
283
+ if (!Number.isSafeInteger(end))
284
+ throw new CliError("validation_error", "page is too far", { param: "page" });
285
+ if (merging && end > EVENTS_READ)
286
+ throw new CliError("validation_error", `page ${page} of ${limit} reads past event ${EVENTS_READ} of each account; name one with account_id`, { param: "account_id" });
287
+ const lists = await Promise.all(accounts.map(async (accountId) => {
288
+ const filter = await eventsFilter(args.query, {
289
+ store,
290
+ accountId,
291
+ zone: args.timezone ?? "UTC",
292
+ now,
293
+ });
294
+ return merging
295
+ ? eventsAnswer(store, filter && { ...filter, limit: end })
296
+ : eventsAnswer(store, filter && { ...filter, limit }, page);
297
+ }));
298
+ const merged = lists.flatMap((one) => one.items).sort((a, b) => (a.starts_at ?? "").localeCompare(b.starts_at ?? ""));
299
+ const items = merging ? merged.slice(end - limit, end) : merged;
300
+ return listOf("events_list", {
301
+ items,
302
+ limit,
303
+ page,
304
+ has_more: (merging && merged.length > end) || lists.some((one) => one.hasMore),
305
+ args: Object.fromEntries(["account_id", "query", "timezone"].filter((key) => args[key] !== undefined).map((key) => [key, args[key]])),
306
+ });
307
+ };
273
308
  const fieldsOf = (args) => ({
274
309
  ...(args.title === undefined ? {} : { title: args.title }),
275
310
  ...(args.start_time === undefined ? {} : { startTime: args.start_time }),
@@ -322,7 +357,7 @@ const writeTool = async (store, name, args, { asked, accounts, now, writes, }) =
322
357
  zone: args.timezone ?? "UTC",
323
358
  names: {
324
359
  notify: "notify: true or false",
325
- id: "id",
360
+ id: "operation_id",
326
361
  calendar: "calendar",
327
362
  series: "series",
328
363
  following: "following",
@@ -338,13 +373,13 @@ const writeTool = async (store, name, args, { asked, accounts, now, writes, }) =
338
373
  const result = name === "event_create"
339
374
  ? await createEvent(context, args.calendar, fieldsOf(args), {
340
375
  ...choice,
341
- ...(args.id === undefined ? {} : { id: args.id }),
376
+ ...(args.operation_id === undefined ? {} : { id: args.operation_id }),
342
377
  })
343
378
  : name === "event_update"
344
379
  ? await updateEvent(context, args.event, fieldsOf(args), {
345
380
  ...on,
346
381
  ...choice,
347
- ...(args.id === undefined ? {} : { id: args.id }),
382
+ ...(args.operation_id === undefined ? {} : { id: args.operation_id }),
348
383
  })
349
384
  : name === "event_delete"
350
385
  ? await deleteEvent(context, args.event, { ...on, ...choice })
@@ -18,9 +18,11 @@ export declare const unfilteredQuery: (entity: string, schema: Parameters<typeof
18
18
  export declare const commandPath: (command: Command) => string;
19
19
  /**
20
20
  * The query as typed, validated against the list's fields, with each default whose field it does not name;
21
- * `undefined` when nothing narrows the list. CLI and MCP read a list's query through this one function.
21
+ * `undefined` when nothing narrows the list. A bare word is refused unless the list names a `defaultField` for it. CLI and MCP read a list's query through this one function.
22
22
  */
23
- export declare const listQuery: (text: string, registry: QueryRegistry, command: string) => QueryAst | undefined;
23
+ export declare const listQuery: (text: string, registry: QueryRegistry, command: string, { defaultField }?: {
24
+ defaultField?: string;
25
+ }) => QueryAst | undefined;
24
26
  /** A list's `[query...]` as typed: the words after its arguments, or one string from MCP. */
25
27
  export type QueryWords = readonly string[] | string | undefined;
26
28
  /** The query a list's action or MCP tool received, as one string for `listQuery`. */
@@ -37,11 +37,11 @@ export const commandPath = (command) => {
37
37
  };
38
38
  /**
39
39
  * The query as typed, validated against the list's fields, with each default whose field it does not name;
40
- * `undefined` when nothing narrows the list. CLI and MCP read a list's query through this one function.
40
+ * `undefined` when nothing narrows the list. A bare word is refused unless the list names a `defaultField` for it. CLI and MCP read a list's query through this one function.
41
41
  */
42
- export const listQuery = (text, registry, command) => {
42
+ export const listQuery = (text, registry, command, { defaultField = "none" } = {}) => {
43
43
  const context = { command, guide: LIST_QUERY_GUIDE };
44
- const typed = text.trim() === "" ? undefined : parseLucene(text, { defaultField: "none", ...context });
44
+ const typed = text.trim() === "" ? undefined : parseLucene(text, { defaultField, ...context });
45
45
  if (typed)
46
46
  validateQuery(typed, registry, context);
47
47
  const named = typed ? fieldsNamed(typed) : new Set();
@@ -8,6 +8,7 @@ import { aheadOf, momentOf } from "../../services/moment.js";
8
8
  import { unlistedNote } from "../../services/task-categories.js";
9
9
  import { ARRIVAL_WINDOW, applyTaskRulesToChats } from "../../services/task-rules.js";
10
10
  import { CLAIM_LEASE_MS, closedStateOf, TASK_PAIR_QUERY, TASK_QUERY, taskLinkKindOf, taskTypeOf, } from "../../services/tasks.js";
11
+ import { PRIORITY_LABELS, priorityOf } from "../../tasks/index.js";
11
12
  import { actorOf, holderOf as holderIn } from "../author.js";
12
13
  import { environmentOf } from "../context.js";
13
14
  import { destroysNothing, LOCAL_READ, LOCAL_WRITE, ownerOnlyOption } from "../effects.js";
@@ -35,6 +36,8 @@ const suggestionLine = ({ as, by, certainty, reason }) => `close suggested: ${as
35
36
  const card = (task) => [
36
37
  `${task.key} ${task.status} ${task.type} ${task.category ?? "—"} ${task.title}`,
37
38
  `due ${when(task.dueAt)} next check ${when(task.nextCheckAt)} source ${task.source ?? "—"}`,
39
+ ...(task.priorityLabel === null ? [] : [`priority ${task.priorityLabel}`]),
40
+ ...(task.agent === null ? [] : [`agent ${task.agent}`]),
38
41
  ...(task.claimedBy === null ? [] : [`claimed by ${task.claimedBy} until ${when(task.claimedUntil)}`]),
39
42
  ...task.assignments.filter((one) => one.role === "assignee").map((one) => `assignee ${one.to}`),
40
43
  ...(task.closeSuggestion === null ? [] : [suggestionLine(task.closeSuggestion)]),
@@ -205,11 +208,7 @@ export const tasksCommand = (messenger) => {
205
208
  .description("update a task's text, schedule, category, assignees, priority or parent; nothing reaches the messenger")
206
209
  .argument("<task>", "the task's id or key, as tasks list shows it")
207
210
  .option("--category <name>", `${categoryHelp}; a change is kept in the task's history`)
208
- .option("--priority <n>", "priority from 0 (urgent) through 4 (low)", (value) => {
209
- if (!/^[0-4]$/.test(value))
210
- throw new CliError("validation_error", "--priority takes 0 through 4");
211
- return Number(value);
212
- })
211
+ .option("--priority <n>", `${PRIORITY_LABELS.join(", ")} or none; 0 (urgent) … 4 (low) still read as before`, priorityOf)
213
212
  .option("--parent <id>", "parent task in the same project; none clears it"), "send Alex the API token").action(async function (id) {
214
213
  const context = messengerContext(this, messenger);
215
214
  refuseLocalWrite(context, messenger.app.command, "tasks.update");
@@ -4758,13 +4758,25 @@ export declare const ENTITIES: {
4758
4758
  readonly title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
4759
4759
  readonly description: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
4760
4760
  readonly kind: v.PicklistSchema<readonly ["bug", "feature", "chore", "question", "request", "mention", "promise"], undefined>;
4761
- readonly state: v.PicklistSchema<readonly ["open", "done", "dismissed"], undefined>;
4761
+ readonly state: v.PicklistSchema<readonly ["open", "todo", "in_progress", "done", "dismissed"], undefined>;
4762
4762
  readonly origin: v.OptionalSchema<v.PicklistSchema<readonly ["rule", "agent", "owner"], undefined>, undefined>;
4763
4763
  readonly project: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
4764
4764
  readonly account: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
4765
4765
  readonly chat: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>, undefined>;
4766
4766
  readonly source_message: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>, undefined>;
4767
4767
  readonly priority: v.OptionalSchema<v.NullableSchema<v.NumberSchema<undefined>, undefined>, undefined>;
4768
+ readonly priority_label: v.OptionalSchema<v.NullableSchema<v.PicklistSchema<readonly ["low", "medium", "high", "critical"], undefined>, undefined>, undefined>;
4769
+ readonly agent: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
4770
+ readonly revision: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
4771
+ readonly assignments: v.OptionalSchema<v.ArraySchema<v.StrictObjectSchema<{
4772
+ readonly to: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
4773
+ readonly role: v.PicklistSchema<["assignee", "reviewer", "watcher"], undefined>;
4774
+ }, undefined>, undefined>, undefined>;
4775
+ readonly ready: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
4776
+ readonly blocked_by: v.OptionalSchema<v.ArraySchema<v.StrictObjectSchema<{
4777
+ readonly task: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
4778
+ readonly state: v.PicklistSchema<["open", "dismissed", "unavailable"], undefined>;
4779
+ }, undefined>, undefined>, undefined>;
4768
4780
  readonly parent: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>, undefined>;
4769
4781
  readonly due_at: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>, undefined>, undefined>;
4770
4782
  readonly closed_at: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>, undefined>, undefined>;
@@ -4820,8 +4832,11 @@ export declare const ENTITIES: {
4820
4832
  readonly title: v.StringSchema<undefined>;
4821
4833
  readonly description: v.NullableSchema<v.StringSchema<undefined>, undefined>;
4822
4834
  readonly type: v.PicklistSchema<readonly ["bug", "feature", "chore", "question", "request", "mention", "promise"], undefined>;
4823
- readonly status: v.PicklistSchema<readonly ["open", "done", "dismissed"], undefined>;
4835
+ readonly status: v.PicklistSchema<readonly ["open", "todo", "in_progress", "done", "dismissed"], undefined>;
4824
4836
  readonly priority: v.NullableSchema<v.NumberSchema<undefined>, undefined>;
4837
+ readonly priority_label: v.NullableSchema<v.PicklistSchema<readonly ["low", "medium", "high", "critical"], undefined>, undefined>;
4838
+ readonly agent: v.NullableSchema<v.StringSchema<undefined>, undefined>;
4839
+ readonly revision: v.NumberSchema<undefined>;
4825
4840
  readonly parent: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
4826
4841
  readonly source: v.NullableSchema<v.StringSchema<undefined>, undefined>;
4827
4842
  readonly due_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>, undefined>;
@@ -4882,7 +4897,7 @@ export declare const ENTITIES: {
4882
4897
  readonly account: v.StringSchema<undefined>;
4883
4898
  readonly group: v.StringSchema<undefined>;
4884
4899
  readonly kind: v.PicklistSchema<readonly ["question", "request", "mention", "promise"], undefined>;
4885
- readonly state: v.PicklistSchema<readonly ["open", "done", "dismissed"], undefined>;
4900
+ readonly state: v.PicklistSchema<readonly ["open", "todo", "in_progress", "done", "dismissed"], undefined>;
4886
4901
  readonly reason: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
4887
4902
  readonly origin: v.PicklistSchema<readonly ["rule", "agent", "owner"], undefined>;
4888
4903
  readonly created_at: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
@@ -4921,8 +4936,11 @@ export declare const ENTITIES: {
4921
4936
  readonly title: v.StringSchema<undefined>;
4922
4937
  readonly description: v.NullableSchema<v.StringSchema<undefined>, undefined>;
4923
4938
  readonly type: v.PicklistSchema<readonly ["bug", "feature", "chore", "question", "request", "mention", "promise"], undefined>;
4924
- readonly status: v.PicklistSchema<readonly ["open", "done", "dismissed"], undefined>;
4939
+ readonly status: v.PicklistSchema<readonly ["open", "todo", "in_progress", "done", "dismissed"], undefined>;
4925
4940
  readonly priority: v.NullableSchema<v.NumberSchema<undefined>, undefined>;
4941
+ readonly priority_label: v.NullableSchema<v.PicklistSchema<readonly ["low", "medium", "high", "critical"], undefined>, undefined>;
4942
+ readonly agent: v.NullableSchema<v.StringSchema<undefined>, undefined>;
4943
+ readonly revision: v.NumberSchema<undefined>;
4926
4944
  readonly parent: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
4927
4945
  readonly source: v.NullableSchema<v.StringSchema<undefined>, undefined>;
4928
4946
  readonly due_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>, undefined>;
@@ -4984,7 +5002,7 @@ export declare const ENTITIES: {
4984
5002
  readonly account: v.StringSchema<undefined>;
4985
5003
  readonly group: v.StringSchema<undefined>;
4986
5004
  readonly kind: v.PicklistSchema<readonly ["question", "request", "mention", "promise"], undefined>;
4987
- readonly state: v.PicklistSchema<readonly ["open", "done", "dismissed"], undefined>;
5005
+ readonly state: v.PicklistSchema<readonly ["open", "todo", "in_progress", "done", "dismissed"], undefined>;
4988
5006
  readonly reason: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
4989
5007
  readonly origin: v.PicklistSchema<readonly ["rule", "agent", "owner"], undefined>;
4990
5008
  readonly created_at: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
@@ -5023,8 +5041,11 @@ export declare const ENTITIES: {
5023
5041
  readonly title: v.StringSchema<undefined>;
5024
5042
  readonly description: v.NullableSchema<v.StringSchema<undefined>, undefined>;
5025
5043
  readonly type: v.PicklistSchema<readonly ["bug", "feature", "chore", "question", "request", "mention", "promise"], undefined>;
5026
- readonly status: v.PicklistSchema<readonly ["open", "done", "dismissed"], undefined>;
5044
+ readonly status: v.PicklistSchema<readonly ["open", "todo", "in_progress", "done", "dismissed"], undefined>;
5027
5045
  readonly priority: v.NullableSchema<v.NumberSchema<undefined>, undefined>;
5046
+ readonly priority_label: v.NullableSchema<v.PicklistSchema<readonly ["low", "medium", "high", "critical"], undefined>, undefined>;
5047
+ readonly agent: v.NullableSchema<v.StringSchema<undefined>, undefined>;
5048
+ readonly revision: v.NumberSchema<undefined>;
5028
5049
  readonly parent: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
5029
5050
  readonly source: v.NullableSchema<v.StringSchema<undefined>, undefined>;
5030
5051
  readonly due_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>, undefined>;
@@ -5153,8 +5174,11 @@ export declare const ENTITIES: {
5153
5174
  readonly title: v.StringSchema<undefined>;
5154
5175
  readonly description: v.NullableSchema<v.StringSchema<undefined>, undefined>;
5155
5176
  readonly type: v.PicklistSchema<readonly ["bug", "feature", "chore", "question", "request", "mention", "promise"], undefined>;
5156
- readonly status: v.PicklistSchema<readonly ["open", "done", "dismissed"], undefined>;
5177
+ readonly status: v.PicklistSchema<readonly ["open", "todo", "in_progress", "done", "dismissed"], undefined>;
5157
5178
  readonly priority: v.NullableSchema<v.NumberSchema<undefined>, undefined>;
5179
+ readonly priority_label: v.NullableSchema<v.PicklistSchema<readonly ["low", "medium", "high", "critical"], undefined>, undefined>;
5180
+ readonly agent: v.NullableSchema<v.StringSchema<undefined>, undefined>;
5181
+ readonly revision: v.NumberSchema<undefined>;
5158
5182
  readonly parent: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
5159
5183
  readonly source: v.NullableSchema<v.StringSchema<undefined>, undefined>;
5160
5184
  readonly due_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>, undefined>;
@@ -5248,8 +5272,11 @@ export declare const ENTITIES: {
5248
5272
  readonly title: v.StringSchema<undefined>;
5249
5273
  readonly description: v.NullableSchema<v.StringSchema<undefined>, undefined>;
5250
5274
  readonly type: v.PicklistSchema<readonly ["bug", "feature", "chore", "question", "request", "mention", "promise"], undefined>;
5251
- readonly status: v.PicklistSchema<readonly ["open", "done", "dismissed"], undefined>;
5275
+ readonly status: v.PicklistSchema<readonly ["open", "todo", "in_progress", "done", "dismissed"], undefined>;
5252
5276
  readonly priority: v.NullableSchema<v.NumberSchema<undefined>, undefined>;
5277
+ readonly priority_label: v.NullableSchema<v.PicklistSchema<readonly ["low", "medium", "high", "critical"], undefined>, undefined>;
5278
+ readonly agent: v.NullableSchema<v.StringSchema<undefined>, undefined>;
5279
+ readonly revision: v.NumberSchema<undefined>;
5253
5280
  readonly parent: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
5254
5281
  readonly source: v.NullableSchema<v.StringSchema<undefined>, undefined>;
5255
5282
  readonly due_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>, undefined>;