@wirecat/cli-core 0.399.0 → 0.401.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 (259) hide show
  1. package/CHANGELOG.md +111 -0
  2. package/README.md +1 -1
  3. package/dist/analysis/consents.d.ts +11 -6
  4. package/dist/analysis/consents.js +5 -2
  5. package/dist/cli/bot/mcp.js +2 -1
  6. package/dist/cli/bot/store.js +1 -1
  7. package/dist/cli/config-command.js +20 -1
  8. package/dist/cli/context.d.ts +2 -0
  9. package/dist/cli/context.js +1 -1
  10. package/dist/cli/effects.d.ts +4 -1
  11. package/dist/cli/effects.js +10 -2
  12. package/dist/cli/index.d.ts +3 -2
  13. package/dist/cli/index.js +3 -2
  14. package/dist/cli/json-fields.js +12 -1
  15. package/dist/cli/meeting-evidence-answer.d.ts +46 -0
  16. package/dist/cli/meeting-evidence-answer.js +22 -0
  17. package/dist/cli/meeting-preparation-answer.js +1 -13
  18. package/dist/cli/messenger/account-command.js +15 -6
  19. package/dist/cli/messenger/account-profile-query.d.ts +2 -0
  20. package/dist/cli/messenger/account-profile-query.js +13 -0
  21. package/dist/cli/messenger/account-sessions-command.js +1 -2
  22. package/dist/cli/messenger/admin-commands.js +12 -12
  23. package/dist/cli/messenger/admin-contacts-command.js +6 -3
  24. package/dist/cli/messenger/admin-folders-command.js +5 -5
  25. package/dist/cli/messenger/admin-moderation-command.js +4 -4
  26. package/dist/cli/messenger/admin-statistics-command.js +6 -14
  27. package/dist/cli/messenger/analysis-consents-query.d.ts +5 -0
  28. package/dist/cli/messenger/analysis-consents-query.js +20 -0
  29. package/dist/cli/messenger/archive-commands.js +3 -3
  30. package/dist/cli/messenger/attachments-command.js +3 -0
  31. package/dist/cli/messenger/backfill-command.js +5 -4
  32. package/dist/cli/messenger/chat-queries.d.ts +1 -0
  33. package/dist/cli/messenger/chat-queries.js +12 -2
  34. package/dist/cli/messenger/chats-command.js +2 -2
  35. package/dist/cli/messenger/chats-documents-command.js +7 -5
  36. package/dist/cli/messenger/chats-members-command.js +7 -3
  37. package/dist/cli/messenger/chats-read-command.js +1 -1
  38. package/dist/cli/messenger/chats-tracking-command.js +14 -6
  39. package/dist/cli/messenger/contacts-command.js +9 -5
  40. package/dist/cli/messenger/conversations-command.js +20 -16
  41. package/dist/cli/messenger/doctor-command.js +4 -1
  42. package/dist/cli/messenger/document-links-query.d.ts +2 -0
  43. package/dist/cli/messenger/document-links-query.js +9 -0
  44. package/dist/cli/messenger/download-command.js +1 -0
  45. package/dist/cli/messenger/flood-command.d.ts +2 -2
  46. package/dist/cli/messenger/flood-command.js +3 -3
  47. package/dist/cli/messenger/gaps-command.js +2 -2
  48. package/dist/cli/messenger/guard-commands.js +35 -13
  49. package/dist/cli/messenger/images-command.js +1 -0
  50. package/dist/cli/messenger/media-archive-command.js +2 -0
  51. package/dist/cli/messenger/media-archive-move-command.js +1 -0
  52. package/dist/cli/messenger/media-archive-timer-command.js +1 -1
  53. package/dist/cli/messenger/mentions-command.js +15 -2
  54. package/dist/cli/messenger/message-writes.d.ts +192 -2
  55. package/dist/cli/messenger/message-writes.js +6 -2
  56. package/dist/cli/messenger/messages-command.js +2 -0
  57. package/dist/cli/messenger/messages-delete-command.js +1 -0
  58. package/dist/cli/messenger/messages-edit-command.js +1 -0
  59. package/dist/cli/messenger/messages-evidence-command.js +3 -1
  60. package/dist/cli/messenger/messages-forward-command.js +1 -0
  61. package/dist/cli/messenger/messages-pin-command.js +3 -0
  62. package/dist/cli/messenger/messages-send-command.js +10 -6
  63. package/dist/cli/messenger/metadata-command.js +6 -1
  64. package/dist/cli/messenger/models-command.js +10 -5
  65. package/dist/cli/messenger/polls-command.js +4 -0
  66. package/dist/cli/messenger/private-people-command.js +3 -3
  67. package/dist/cli/messenger/rankings-command.js +6 -11
  68. package/dist/cli/messenger/reactions-command.js +2 -0
  69. package/dist/cli/messenger/recipients-query.d.ts +5 -0
  70. package/dist/cli/messenger/recipients-query.js +18 -0
  71. package/dist/cli/messenger/records-command.js +13 -8
  72. package/dist/cli/messenger/review.js +1 -1
  73. package/dist/cli/messenger/schedule-command.js +2 -2
  74. package/dist/cli/messenger/search-answers.js +2 -0
  75. package/dist/cli/messenger/search-command.js +3 -1
  76. package/dist/cli/messenger/searches-command.js +5 -1
  77. package/dist/cli/messenger/sends-query.d.ts +5 -0
  78. package/dist/cli/messenger/sends-query.js +33 -0
  79. package/dist/cli/messenger/serve-command.js +1 -0
  80. package/dist/cli/messenger/server-command.js +0 -3
  81. package/dist/cli/messenger/statistics-query.d.ts +14 -0
  82. package/dist/cli/messenger/statistics-query.js +143 -0
  83. package/dist/cli/messenger/stats-command.js +5 -5
  84. package/dist/cli/messenger/store-maintenance-command.js +10 -10
  85. package/dist/cli/messenger/stored.js +4 -1
  86. package/dist/cli/messenger/tags-command.js +7 -1
  87. package/dist/cli/messenger/tasks-command.js +57 -14
  88. package/dist/cli/messenger/transcribe-command.js +1 -0
  89. package/dist/cli/messenger/watch-answers.d.ts +6 -0
  90. package/dist/cli/messenger/watch-answers.js +69 -0
  91. package/dist/cli/messenger/watch-command.d.ts +1 -1
  92. package/dist/cli/messenger/watch-command.js +56 -7
  93. package/dist/cli/program.js +5 -1
  94. package/dist/cli/runs/command.js +25 -38
  95. package/dist/cli/runs/query.d.ts +5 -0
  96. package/dist/cli/runs/query.js +32 -0
  97. package/dist/cli/runs/search-command.d.ts +4 -0
  98. package/dist/cli/runs/search-command.js +27 -0
  99. package/dist/cli/runs/search-query.d.ts +4 -0
  100. package/dist/cli/runs/search-query.js +50 -0
  101. package/dist/cli/runs/search.d.ts +2 -1
  102. package/dist/cli/runs/search.js +6 -6
  103. package/dist/documents/index.d.ts +1 -0
  104. package/dist/documents/index.js +1 -0
  105. package/dist/domain/attachments.js +9 -1
  106. package/dist/domain/rankings-options.js +3 -3
  107. package/dist/entities/account-change.d.ts +89 -0
  108. package/dist/entities/account-change.js +20 -0
  109. package/dist/entities/account-profile.d.ts +7 -0
  110. package/dist/entities/account-profile.js +8 -0
  111. package/dist/entities/analysis-consent.d.ts +9 -0
  112. package/dist/entities/analysis-consent.js +4 -0
  113. package/dist/entities/attachment-results.d.ts +96 -0
  114. package/dist/entities/attachment-results.js +31 -0
  115. package/dist/entities/batch-result.d.ts +27 -0
  116. package/dist/entities/batch-result.js +18 -0
  117. package/dist/entities/chat-admin.d.ts +234 -0
  118. package/dist/entities/chat-admin.js +84 -0
  119. package/dist/entities/chat-change.d.ts +25 -0
  120. package/dist/entities/chat-change.js +11 -0
  121. package/dist/entities/chat-metadata.d.ts +34 -0
  122. package/dist/entities/chat-metadata.js +15 -0
  123. package/dist/entities/chat-moderation.d.ts +44 -0
  124. package/dist/entities/chat-moderation.js +37 -0
  125. package/dist/entities/chat-tracking.d.ts +26 -0
  126. package/dist/entities/chat-tracking.js +23 -0
  127. package/dist/entities/contact-activity.d.ts +52 -0
  128. package/dist/entities/contact-activity.js +42 -0
  129. package/dist/entities/contact-context.d.ts +1568 -0
  130. package/dist/entities/contact-context.js +191 -0
  131. package/dist/entities/contact-write.d.ts +22 -0
  132. package/dist/entities/contact-write.js +6 -0
  133. package/dist/entities/conversation-preparation.d.ts +63 -0
  134. package/dist/entities/conversation-preparation.js +23 -0
  135. package/dist/entities/conversation-results.d.ts +567 -0
  136. package/dist/entities/conversation-results.js +94 -0
  137. package/dist/entities/document-link.d.ts +13 -0
  138. package/dist/entities/document-link.js +11 -0
  139. package/dist/entities/extraction-report.d.ts +95 -0
  140. package/dist/entities/extraction-report.js +34 -0
  141. package/dist/entities/hit.d.ts +4 -0
  142. package/dist/entities/hit.js +4 -0
  143. package/dist/entities/image-embedding.d.ts +9 -0
  144. package/dist/entities/image-embedding.js +10 -0
  145. package/dist/entities/index.d.ts +8284 -1921
  146. package/dist/entities/index.js +178 -3
  147. package/dist/entities/listener.d.ts +2150 -0
  148. package/dist/entities/listener.js +46 -0
  149. package/dist/entities/media-archive.d.ts +43 -0
  150. package/dist/entities/media-archive.js +32 -0
  151. package/dist/entities/meeting-evidence.d.ts +86 -0
  152. package/dist/entities/meeting-evidence.js +25 -0
  153. package/dist/entities/meeting-preparation-parts.d.ts +14 -0
  154. package/dist/entities/meeting-preparation-parts.js +15 -13
  155. package/dist/entities/meeting-task-proposal.d.ts +14 -0
  156. package/dist/entities/meeting-task-proposal.js +19 -0
  157. package/dist/entities/meeting.d.ts +1 -1
  158. package/dist/entities/meeting.js +1 -1
  159. package/dist/entities/mention.d.ts +63 -0
  160. package/dist/entities/mention.js +44 -0
  161. package/dist/entities/message-change.d.ts +19 -0
  162. package/dist/entities/message-change.js +6 -0
  163. package/dist/entities/message-context.d.ts +617 -0
  164. package/dist/entities/message-context.js +20 -0
  165. package/dist/entities/message-read.d.ts +73 -0
  166. package/dist/entities/message-read.js +58 -0
  167. package/dist/entities/message-transfer.d.ts +379 -0
  168. package/dist/entities/message-transfer.js +83 -0
  169. package/dist/entities/message-write.d.ts +378 -0
  170. package/dist/entities/message-write.js +10 -0
  171. package/dist/entities/model-key.d.ts +14 -0
  172. package/dist/entities/model-key.js +10 -0
  173. package/dist/entities/poll.d.ts +40 -0
  174. package/dist/entities/poll.js +16 -0
  175. package/dist/entities/private-contact.d.ts +10 -0
  176. package/dist/entities/private-contact.js +4 -0
  177. package/dist/entities/reaction-change.d.ts +7 -0
  178. package/dist/entities/reaction-change.js +8 -0
  179. package/dist/entities/recipient.d.ts +29 -0
  180. package/dist/entities/recipient.js +11 -0
  181. package/dist/entities/recorded-run.d.ts +103 -0
  182. package/dist/entities/recorded-run.js +44 -0
  183. package/dist/entities/saved-search.d.ts +4 -0
  184. package/dist/entities/saved-search.js +2 -0
  185. package/dist/entities/send-attempt.d.ts +31 -0
  186. package/dist/entities/send-attempt.js +29 -0
  187. package/dist/entities/store-maintenance.d.ts +319 -0
  188. package/dist/entities/store-maintenance.js +145 -0
  189. package/dist/entities/store-records.d.ts +442 -0
  190. package/dist/entities/store-records.js +99 -0
  191. package/dist/entities/tag-change.d.ts +74 -0
  192. package/dist/entities/tag-change.js +31 -0
  193. package/dist/entities/task-pair.d.ts +31 -0
  194. package/dist/entities/task-pair.js +23 -0
  195. package/dist/entities/task-results.d.ts +524 -0
  196. package/dist/entities/task-results.js +142 -0
  197. package/dist/errors/reasons.js +3 -0
  198. package/dist/mcp/agent.d.ts +3 -1
  199. package/dist/mcp/agent.js +17 -10
  200. package/dist/mcp/bot/server.d.ts +2 -0
  201. package/dist/mcp/bot/server.js +1 -0
  202. package/dist/mcp/server.js +3 -1
  203. package/dist/mcp/tools/attachments.js +1 -0
  204. package/dist/meetings/cli/index.js +4 -2
  205. package/dist/meetings/cli/passage.js +1 -0
  206. package/dist/meetings/index.d.ts +2 -1
  207. package/dist/meetings/index.js +1 -0
  208. package/dist/meetings/links.d.ts +16 -0
  209. package/dist/meetings/read-answers.d.ts +185 -0
  210. package/dist/meetings/read-answers.js +213 -0
  211. package/dist/ports/messenger.d.ts +10 -1
  212. package/dist/runs/run.d.ts +10 -2
  213. package/dist/runs/run.js +11 -3
  214. package/dist/sends/guard.d.ts +1 -1
  215. package/dist/sends/guard.js +9 -5
  216. package/dist/sends/journal.d.ts +9 -2
  217. package/dist/sends/journal.js +9 -2
  218. package/dist/sends/permissions.d.ts +5 -1
  219. package/dist/sends/permissions.js +42 -2
  220. package/dist/sends/recipients.d.ts +8 -0
  221. package/dist/sends/recipients.js +9 -0
  222. package/dist/sends/upload.d.ts +4 -4
  223. package/dist/sends/upload.js +24 -20
  224. package/dist/services/admin-statistics.js +3 -3
  225. package/dist/services/chat-documents.d.ts +1 -0
  226. package/dist/services/chat-documents.js +9 -3
  227. package/dist/services/chats.d.ts +1 -1
  228. package/dist/services/chats.js +5 -2
  229. package/dist/services/documents/mirrors.d.ts +98 -0
  230. package/dist/services/documents/mirrors.js +144 -0
  231. package/dist/services/meeting-links.d.ts +2 -17
  232. package/dist/services/messages.js +1 -0
  233. package/dist/services/search-all-meetings.js +21 -8
  234. package/dist/services/task-rules.d.ts +1 -1
  235. package/dist/services/tasks.d.ts +2 -2
  236. package/dist/services/tasks.js +1 -1
  237. package/dist/store/exports.d.ts +1 -1
  238. package/dist/store/exports.js +1 -1
  239. package/dist/store/messages.d.ts +3 -1
  240. package/dist/store/messages.js +2 -2
  241. package/dist/store/roster.d.ts +4 -1
  242. package/dist/store/roster.js +2 -2
  243. package/dist/store/sqlite/chats.d.ts +12 -0
  244. package/dist/store/sqlite/chats.js +1 -0
  245. package/dist/store/sqlite/document-links.d.ts +1 -1
  246. package/dist/store/sqlite/document-links.js +5 -5
  247. package/dist/store/sqlite/drizzle/bun.js +3 -3
  248. package/dist/store/sqlite/drizzle/bun.js.map +1 -1
  249. package/dist/store/sqlite/drizzle/core.js +2 -2
  250. package/dist/store/sqlite/drizzle/core.js.map +1 -1
  251. package/dist/store/sqlite/drizzle/node.js +3 -3
  252. package/dist/store/sqlite/drizzle/node.js.map +1 -1
  253. package/dist/store/sqlite/drizzle/{shared-O7CTKP45.js → shared-HKXF6HKX.js} +57 -57
  254. package/dist/store/sqlite/drizzle/{shared-O7CTKP45.js.map → shared-HKXF6HKX.js.map} +1 -1
  255. package/dist/store/sqlite/involvements.js +2 -1
  256. package/dist/store/sqlite/roster.d.ts +2 -1
  257. package/dist/store/sqlite/roster.js +3 -2
  258. package/package.json +2 -2
  259. package/parity.json +14 -69
package/CHANGELOG.md CHANGED
@@ -5,6 +5,117 @@ Notable changes to `@wirecat/cli-core` (`@wirecat/cli-messaging` up to 0.261.0,
5
5
  minor version may break callers, and says how under "Changed — may break callers". `pnpm docs:check` checks the
6
6
  shape of this file.
7
7
 
8
+ ## Unreleased
9
+
10
+ ## 0.401.0 — 24.10.2026
11
+
12
+ ### Changed — may break callers
13
+
14
+ - **`events list` writes times as ISO 8601 and ids as strings**, as every other answer does: `starts_at`, `ends_at`, `deleted_at`, `created_at` and `updated_at` were epoch milliseconds, `id` and `event_series_id` numbers. No field is gone.
15
+
16
+ - **List duplicate-task pairs explicitly.** Use `tasks duplicates list [query...]` in CLI and MCP calls. The bare `tasks duplicates` group shows help or refuses in machine mode; it no longer reads the store. Reject and defer remain under that group.
17
+
18
+ ### Fixed
19
+
20
+ - **`search all` pages meeting matches.** With a meeting account in the search, `--page 2` repeated the meetings of the first page, and `has_more` could be false while meeting matches remained. The merged list is now read as deep as the page and cut, so pages follow on and `has_more` holds.
21
+
22
+ ### Added
23
+
24
+ - **Meeting answers keep what they knew.** A `search all` meeting hit carries its `scope` (transcript, chat or summary) and its stored line `id`, so two passages of one meeting stay apart. New entities `meeting_evidence`, `meeting_person_context` and `event`; `cli` exports `allAnswer`, `meetingEvidenceItem` and `meetingPersonContextItem`.
25
+
26
+ ## 0.400.0 — 24.10.2026
27
+
28
+ ### Fixed
29
+
30
+ - **Downloads skip service events and keyboards.** A message whose only attachment is a group event (`control`) or an inline keyboard no longer makes a media archive or `attachments download` fail with `provider.invalid-response`; both count as non-files like polls and links.
31
+
32
+ - Account lists accept profile and current-profile query terms, and declare their answer fields for discovery and projection.
33
+
34
+ - **Account change and privacy schemas.** Profile updates, ended sessions and privacy reads and writes declare their existing answers for field discovery and projection. Privacy fields remain optional where a messenger does not expose a setting.
35
+
36
+ - **`contacts timeline` stays in its account for tasks.** A task assigned to the person now shows only when its project belongs to the asked account or to no account; before, tasks from another account of the same messenger showed too. Task rows now also name the account of their project.
37
+
38
+ ### Added
39
+
40
+ - **Album sends.** `messages send` takes `--photo` and `--file` more than once, and its MCP tool takes a list for
41
+ `photo` and `file`; together they go as one album, photos first. Each photo or file counts as one send toward the
42
+ hourly limit. An adapter returns every message of the album as `Sent.messages`, and `--json` answers with a
43
+ `messages` list beside `message`, which stays the first. A messenger that cannot send an album refuses it before
44
+ anything goes. A single attachment sends and answers as before.
45
+
46
+ - **Mirror runner for folder sync.** `syncMirrors` syncs each of a CLI's mirrors both ways under one lock and reports
47
+ a partly failed mirror as a `mirror.partial` issue; `fileMirrorState`, `mirrorId`, `mirrorStatus` and
48
+ `conflictReport` are the state file, id, local plan and conflict report drive-cli's `mirrors` used, moved here so
49
+ other CLIs can mirror folders and a watcher can reuse the same run.
50
+
51
+ - **Meeting answer schemas.** `review`, `mentions list`, `stats meetings show` and `top`, `meetings people`, `meetings passage` and `meetings task-proposal` declare their answer entities (`meeting_review`, `meeting_link`, `meeting_stats`, `meeting_speaker`, `meeting_participants`, `meeting_passage`, `meeting_task_proposal`) for field discovery and projection. `meetings/` exports the item builders the meeting CLIs share: `meetingReviewItem`, `meetingLinkItem`, `meetingStatsItem`, `meetingSpeakerItem`.
52
+
53
+ - **Listener answers declare their fields.** Live messages and events, and the final serve summary, expose exact schemas for discovery and cross-CLI output contracts. Provider-only attachment references stay private.
54
+
55
+ - **Poll answer schemas.** Poll reads, vote and close receipts, and newly sent poll messages declare their answer entities for field discovery and projection.
56
+
57
+ - **Image embedding progress has declared fields.** Discovery and projection describe the bounded batch’s model, embedded, skipped and failed counts, and whether more pictures remain. The existing receipt and processing behavior stay unchanged.
58
+
59
+ - **Model key receipt schemas.** Storing or removing a model-provider key declares its provider and storage sources for field discovery and projection. No credential value appears in either schema or answer.
60
+
61
+ - Recipient lists accept ID and title queries without changing the allowlist state. Recipient commands declare their answer schemas for discovery and field projection.
62
+
63
+ - **Cached chat metadata declares its answers.** Cached reads describe absent or populated metadata; refresh receipts describe each successful chat or failure and whether more chats remain. Existing keys and cached-read behavior stay unchanged.
64
+
65
+ - **Contact answers have declared fields.** Address-book writes, private aliases and note removal, activity, bot checks, identity links, context and preparation expose their exact answer schemas. Context describes both the cross-account report and selected-chat message windows at every detail level. Field projection recognizes both shapes and refuses unknown fields before reading contact data. CLI, SDK and MCP receipts keep their existing shapes.
66
+
67
+ - **Mention answers have declared fields.** Mentions, details, linked domains, confirmed places, decisions and rebuild receipts expose their existing schemas for discovery, JSON field projection and MCP. Numeric local IDs and cross-account decision behavior stay unchanged.
68
+
69
+ - **Reaction answer schemas.** Add and remove declare the same reaction-change entity, including the operation id and a null reaction when removed. Field discovery and projection now describe these write receipts.
70
+
71
+ - **Tag changes declare their results.** Add and remove expose precise chat, contact, message and task target shapes. Automatic tagging describes each classification or failed chat, including preview status and remaining work; existing receipts and ownership claims stay unchanged.
72
+
73
+ - Send history includes a concrete example in help and command discovery.
74
+
75
+ - Chat document lists accept a source-message reference query, filtered in the store before link pagination, and declare their document-link answer fields.
76
+
77
+ - Doctor reports include a concrete creation example in help and command discovery.
78
+
79
+ - Send-attempt lists accept queries over their stored metadata before pagination. Continuation steps keep the query, and discovery declares the answer fields.
80
+
81
+ - **Clearing search history declares its receipt.** Discovery and JSON projection expose the existing cleared count; saved searches remain untouched.
82
+
83
+ - Recorded-run lists accept metadata queries before pagination, and recorded-run commands declare their answer schemas. Continuation steps keep the query.
84
+
85
+ - **Message read and write schemas.** Showing a message, sending, editing, forwarding, pinning, starring and deleting declare their existing answer entities for field discovery and projection. Write receipts retain their operation id.
86
+
87
+ - **Chat-state write schemas.** Muting, archiving, pinning, marking unread, deleting a chat and clearing its history declare their existing write receipts for field discovery and projection, including their operation ids.
88
+
89
+ - **Chat administration declares its answers.** Invite inspection, posting identities, read receipts, roster fetches, membership and group changes, invitations, join requests, administrators, folder writes and moderation expose their exact existing result fields, including operation identifiers and partial outcomes.
90
+
91
+ - **Message read schemas.** Evidence packets, voice transcripts and conversation links declare separate answer entities for field discovery and projection, preserving existing response keys.
92
+
93
+ - **Conversation results have declared schemas.** Builds, analysis, message batches, link changes, embedding progress, readiness, related conversations and search hits describe their existing answer fields for discovery and projection, including bounded preparation and empty batches.
94
+
95
+ - **Message context, downloads and sync have declared answers.** Context describes both message windows and bounded thread reports. Downloads retain file paths and partial extraction results; sync describes estimates, chat and all-chat progress, preparation and background jobs. General chat evidence packets and exact statistics evidence now explain their separate purposes in help and the guide.
96
+
97
+ - Analysis-consent lists accept chat and provider-identity queries, and consent commands declare their answer fields. Reading a filtered list leaves remembered permissions unchanged.
98
+
99
+ - **Attachment and media archive results have declared fields.** Extraction reports and streamed file rows, retained-file transfers, saved text, archive downloads, integrity checks, relocations and timer management describe their existing receipts. MCP resource/image transfers keep byte metadata in the same shape while carrying bytes separately.
100
+
101
+ - Tracked-chat lists accept a query over chat IDs and titles, filtered in the store. Tracking commands declare their answer schemas for field projection and discovery.
102
+
103
+ - **Task actions declare their answers.** Task cards, source previews, creation and close receipts, relationships, similarity and duplicate decisions, merges, categories and rule scans expose their exact existing fields for discovery and projection. Stored tasks and actions keep their behavior.
104
+
105
+ - **Store commands declare their answers.** Archive coverage, exports, selected-chat clearing, gap plans and repairs, background jobs, health checks, maintenance and backup/restore receipts describe their existing result fields. Missing-file and partial-result variants remain explicit; stored data and command behavior stay unchanged.
106
+
107
+ ### Changed — may break callers
108
+
109
+ - **MCP offers the writes no permission level stopped before.** `store backup|restore|migrate|repair|reset|clear|decrypt`, `store copies delete`, `server start|stop|restart`, model downloads, `schedule run|exec`, `doctor report create`, `account sessions end`, `chats delete|clear` and `bot store fetch` are MCP tools, each limited by a key named after its path (`store.reset`, `server.start`, `schedule.run`…), `ask` by default; set one to `deny` to keep an agent from it. `server`, `models`, `schedule`, `doctor` and `images` are now valid roots of a permission key. Command-line behaviour is unchanged. What to change in a CLI: a pinned MCP catalogue and a document listing what MCP leaves out.
110
+
111
+ - **Watch uses the shared JSONL contract.** Read each message or event from `{ type: "item", data }` and wait for the final `type: "end"` record. Message and event fields are snake_case, message values use the canonical read shape with references, and live counter observations remain available. Normal stops and timeouts finish complete; a source failure finishes incomplete and returns its failure code. Update readers of the old raw lines.
112
+
113
+ - **MCP offers the commands that change what a later run may do, behind `mcp.authority`.** `config set|unset`, `schedule command|agent|remove`, auto-reply rules and consents, recipients, chat rules, `server install`, `skill install`, model keys, media archive timers and `flood clear` are MCP tools again, offered only where the profile sets `permissions.mcp.authority` to `allow`; it is `deny` by default, so nothing changes until the owner turns it on. An agent cannot change that key through `config set`. What to change in a CLI: `grantsAuthority` no longer adds `mcp: false`, so `commands --json` no longer marks these commands, and a catalogue built with `toolsFromCommands` without `levels` lists them; update a pinned catalogue and a document that lists what MCP leaves out. A command of the CLI's own marked `grantsAuthority` (max `recipients add`) is gated the same way. A caller of `createBotServer` passes `authority: changesAuthorityAt(root)` to hide them; without it they are listed and refuse when called.
114
+
115
+ - **Diagnostic search is `search runs`.** Replace `runs search`; saved MCP requests use the new command path. Filters are query terms: `status:failed`, `error_code:timeout`, `operation:messages.download` and `profile:work`, alongside literal diagnostic words. Unsupported operators are refused; time bounds and paging remain options. The local search still needs no linked messenger profile, filters before pagination and returns diagnostic fields without message contents. No alias remains for the retired path.
116
+
117
+ - **Statistics select rows through their query.** Rankings use `message_kind:` with `posts`, `comments` or `all`, and author rankings `min_messages:5`; discussion uses `min_views:10` and `max_replies:0`; unanswered questions use `older_than:24h`. These predicates replace the corresponding filter flags and reach the existing SQL selection before aggregation or row limits. The same reports select chats with `chat:` and exact words with `exact:` instead of `--chat` and `--exact`; source and timezone remain options. Saved CLI/MCP requests must migrate. Stored selections and SDK parameters retain their meanings.
118
+
8
119
  ## 0.399.0 — 23.10.2026
9
120
 
10
121
  ### Changed — may break callers
package/README.md CHANGED
@@ -178,7 +178,7 @@ or a launchd agent.
178
178
  - **A permission level per command path:** deny, readonly, ask or allow. The most specific key wins, and a built-in
179
179
  default can only tighten what the owner set. No level lets an agent delete for everyone.
180
180
  - **A recipient list and an hourly limit** for sends, and a journal of every attempt that records the length of the
181
- text, never the text.
181
+ text, never the text. Each photo or file of an album counts as one send.
182
182
  - **A send id across retries.** A write whose outcome is unknown is never retried automatically; a retry under the
183
183
  same send id cannot send twice.
184
184
  - **Deletion asks first,** at most ten messages at a time.
@@ -4,9 +4,14 @@ export interface AnalysisConsent {
4
4
  provider: string;
5
5
  at: string;
6
6
  }
7
- export declare const analysisConsents: (store: MessageStore, account: AccountKey) => {
8
- list: () => Promise<AnalysisConsent[]>;
9
- has: (chat: string, provider: string) => Promise<boolean>;
10
- remember: (chat: string, provider: string) => Promise<void>;
11
- revoke: (chat?: string, provider?: string) => Promise<void>;
12
- };
7
+ export interface AnalysisConsentFilter {
8
+ chat?: string;
9
+ provider?: string;
10
+ }
11
+ export interface AnalysisConsents {
12
+ list(filter?: AnalysisConsentFilter): Promise<AnalysisConsent[]>;
13
+ has(chat: string, provider: string): Promise<boolean>;
14
+ remember(chat: string, provider: string): Promise<void>;
15
+ revoke(chat?: string, provider?: string): Promise<void>;
16
+ }
17
+ export declare const analysisConsents: (store: MessageStore, account: AccountKey) => AnalysisConsents;
@@ -1,7 +1,7 @@
1
1
  import { CliError } from "@wirecat/cli-base";
2
2
  const KEY = "analysis-consents-v1";
3
3
  export const analysisConsents = (store, account) => {
4
- const list = async () => {
4
+ const list = async (filter) => {
5
5
  const state = await store.sync.syncState(account, KEY);
6
6
  if (!state)
7
7
  return [];
@@ -10,7 +10,10 @@ export const analysisConsents = (store, account) => {
10
10
  if (!Array.isArray(items) ||
11
11
  items.some((item) => !item || typeof item.chat !== "string" || typeof item.provider !== "string" || typeof item.at !== "string"))
12
12
  throw new Error("invalid");
13
- return items;
13
+ return filter === undefined
14
+ ? items
15
+ : items.filter((item) => (filter.chat === undefined || item.chat === filter.chat) &&
16
+ (filter.provider === undefined || item.provider === filter.provider));
14
17
  }
15
18
  catch {
16
19
  throw new CliError("configuration_error", "stored analysis consent is invalid; revoke it before running analysis");
@@ -3,7 +3,7 @@ import { CliError } from "@wirecat/cli-base";
3
3
  import { annotate, describeProgram } from "@wirecat/cli-base/commands";
4
4
  import { Command } from "commander";
5
5
  import { environmentOf } from "../context.js";
6
- import { LOCAL_READ, REMOTE_WRITE } from "../effects.js";
6
+ import { changesAuthorityAt, LOCAL_READ, REMOTE_WRITE } from "../effects.js";
7
7
  import { itemOf, renderAnswer } from "../envelope.js";
8
8
  import { serverEntry } from "../messenger/mcp-command.js";
9
9
  import { nextStep, rootOf } from "../steps.js";
@@ -28,6 +28,7 @@ export const botMcpCommand = (bot) => {
28
28
  await serveBotOverStdio({
29
29
  bot,
30
30
  program: { run, commands: describeProgram(rootOf(this)) },
31
+ authority: changesAuthorityAt(rootOf(this)),
31
32
  settings: context.settings,
32
33
  levels: () => bot.resolveSettings(this.optsWithGlobals(), { env: context.env, kind: "bot" }).permissions,
33
34
  env: context.env,
@@ -20,7 +20,7 @@ const wholeNumber = (value) => {
20
20
  * personal `messages sync` does. Mounted for a messenger whose Bot API pages back through a chat.
21
21
  */
22
22
  export const botStoreCommand = (bot, fetching) => {
23
- const command = annotate(new Command("store"), { mcp: false }).description("the bot's local copy on this machine");
23
+ const command = new Command("store").description("the bot's local copy on this machine");
24
24
  const fetch = annotate(command.command("fetch"), { effects: FETCH })
25
25
  .description("fetch a chat's history into the bot's local copy, newest first; run it again to continue")
26
26
  .argument("<chat>", "a chat id, or the title of a chat this bot has seen")
@@ -2,8 +2,9 @@ import { CliError, pathsAreOverridden } from "@wirecat/cli-base";
2
2
  import { annotate } from "@wirecat/cli-base/commands";
3
3
  import { Command } from "commander";
4
4
  import { envName } from "../ports/app.js";
5
+ import { AUTHORITY_KEY } from "../sends/permissions.js";
5
6
  import { loadSnakeCaseConfig } from "./config-keys.js";
6
- import { baseContext } from "./context.js";
7
+ import { baseContext, environmentOf } from "./context.js";
7
8
  import { grantsAuthority, LOCAL_READ, LOCAL_WRITE } from "./effects.js";
8
9
  import { itemOf, renderAnswer } from "./envelope.js";
9
10
  import { knownBeside, knownPermissionKeys } from "./permission-keys.js";
@@ -94,6 +95,8 @@ export const configCommand = (app, config, { permissionKey } = {}) => {
94
95
  // The defaults are every other profile's settings too, and default_profile picks one of them.
95
96
  throw new CliError("permission_error", `this process is locked to profile ${settings.profile} (${lock}) — ${setting === "default_profile" ? setting : "--defaults"} changes other profiles`);
96
97
  }
98
+ if (environmentOf(this).agent)
99
+ refuseAuthorityKey(setting, action === "set" ? String(given) : undefined);
97
100
  if (action === "set")
98
101
  refuseUnknownKey(this, setting, String(given), permissionKey);
99
102
  const saved = config.changeSetting(settings.configPath, {
@@ -133,6 +136,22 @@ export const refuseUnknownKey = (command, setting, value, permissionKey) => {
133
136
  (beside.length > 0 ? ` — the known ones there are ${beside.join(", ")}` : ""));
134
137
  }
135
138
  };
139
+ /**
140
+ * An agent may hold `mcp.authority` and change other settings, but never the key that let it in: on any profile, in
141
+ * the defaults, or by replacing `permissions` whole. Only the owner, in a terminal, turns it on or off (NEED-1662).
142
+ */
143
+ const refuseAuthorityKey = (setting, value) => {
144
+ const keys = setting.startsWith("permissions.")
145
+ ? [setting.slice("permissions.".length)]
146
+ : setting === "permissions"
147
+ ? value === undefined
148
+ ? ["mcp"]
149
+ : objectKeys(value)
150
+ : [];
151
+ if (!keys.some((key) => key === "mcp" || key.startsWith("mcp.")))
152
+ return;
153
+ throw new CliError("permission_error", `an agent cannot change permissions.${AUTHORITY_KEY} — the owner sets it in a terminal`, { permission: AUTHORITY_KEY });
154
+ };
136
155
  /** The keys of a `permissions` object given whole; anything else is left to the schema to refuse. */
137
156
  const objectKeys = (value) => {
138
157
  try {
@@ -85,6 +85,8 @@ export interface AgentRun {
85
85
  failure: (error: ErrorObject) => void;
86
86
  /** The server's own stricter levels, `key=level`, as `mcp --permission` takes them; they never loosen. */
87
87
  overrides?: readonly string[];
88
+ /** The server's levels allow `mcp.authority`: a command that changes what a later run may do may run. */
89
+ authority?: boolean;
88
90
  }
89
91
  export interface RelayedRun {
90
92
  /** The profile serve holds; a command for another is refused before it touches the connection. */
@@ -72,7 +72,7 @@ export const baseContext = (command, resolveSettings) => {
72
72
  run: (body, { unbounded = false, name } = {}) => environment.app
73
73
  ? recorded({
74
74
  app: environment.app,
75
- // An agent's run is named `mcp <command>`, so `runs search` and `sends list` tell it from the owner's.
75
+ // An agent's run is named `mcp <command>`, so `search runs` and `sends list` tell it from the owner's.
76
76
  command: name ?? `${environment.agent ? "mcp " : ""}${commandPath(command)}`,
77
77
  profile: settings.profile,
78
78
  record: settings.record,
@@ -14,13 +14,16 @@ export declare const NO_EFFECTS: Effects;
14
14
  /**
15
15
  * Marks a local write that changes what a later run may do: a schedule, a setting, the recipient list, an
16
16
  * auto-reply, an agent's setup. `<PREFIX>_READ_ONLY` refuses it, or an agent under the lock could hand an
17
- * unlocked run the send it may not make itself (SEC-47). For the same reason no MCP server offers it (`mcp: false`).
17
+ * unlocked run the send it may not make itself (SEC-47). For the same reason an MCP server offers it only where the
18
+ * profile allows `mcp.authority`, which is off until the owner turns it on (NEED-1662).
18
19
  * `unless` names a flag that makes the run only look (`upgrade --check`), which the lock lets through.
19
20
  */
20
21
  export declare const grantsAuthority: <T extends Command>(command: T, { unless }?: {
21
22
  unless?: string;
22
23
  }) => T;
23
24
  export declare const changesAuthority: (command: Command) => boolean;
25
+ /** `changesAuthority` by command path under `root`, as an MCP catalogue asks it; an unknown path is not one. */
26
+ export declare const changesAuthorityAt: (root: Command) => (path: readonly string[]) => boolean;
24
27
  export declare const changesAuthorityNow: (command: Command) => boolean;
25
28
  /**
26
29
  * Marks a command that links or unlinks the account — `session start`, `session end`, a setup that logs in. It never
@@ -16,14 +16,22 @@ const AUTHORITY = new WeakMap();
16
16
  /**
17
17
  * Marks a local write that changes what a later run may do: a schedule, a setting, the recipient list, an
18
18
  * auto-reply, an agent's setup. `<PREFIX>_READ_ONLY` refuses it, or an agent under the lock could hand an
19
- * unlocked run the send it may not make itself (SEC-47). For the same reason no MCP server offers it (`mcp: false`).
19
+ * unlocked run the send it may not make itself (SEC-47). For the same reason an MCP server offers it only where the
20
+ * profile allows `mcp.authority`, which is off until the owner turns it on (NEED-1662).
20
21
  * `unless` names a flag that makes the run only look (`upgrade --check`), which the lock lets through.
21
22
  */
22
23
  export const grantsAuthority = (command, { unless } = {}) => {
23
24
  AUTHORITY.set(command, unless);
24
- return annotate(command, { mcp: false });
25
+ return command;
25
26
  };
26
27
  export const changesAuthority = (command) => AUTHORITY.has(command);
28
+ /** `changesAuthority` by command path under `root`, as an MCP catalogue asks it; an unknown path is not one. */
29
+ export const changesAuthorityAt = (root) => (path) => {
30
+ let at = root;
31
+ for (const word of path)
32
+ at = at?.commands.find((one) => one.name() === word);
33
+ return at !== undefined && changesAuthority(at);
34
+ };
27
35
  export const changesAuthorityNow = (command) => {
28
36
  if (!AUTHORITY.has(command))
29
37
  return false;
@@ -53,7 +53,7 @@ export { loadSnakeCaseConfig } from "./config-keys.js";
53
53
  export { type AgentRun, type BaseContext, type BaseEnvironment, baseContext, environmentOf, outputFor, provide, secretInputOf, } from "./context.js";
54
54
  export { type Closeable, withDeadline } from "./deadline.js";
55
55
  export { DEFAULT_CONFIG, ensureDefaultConfig } from "./default-config.js";
56
- export { changesAuthority, destroysNothing, FETCH, grantsAuthority, isLogin, isOtherServiceCall, isStoreChange, judgedEffects, judgedTargets, LOCAL_READ, LOCAL_WRITE, logsInOrOut, NO_EFFECTS, ownerOnlyOption, REMOTE_READ, REMOTE_WRITE, reachesOtherService, refuseUnderReadOnly, } from "./effects.js";
56
+ export { changesAuthority, changesAuthorityAt, destroysNothing, FETCH, grantsAuthority, isLogin, isOtherServiceCall, isStoreChange, judgedEffects, judgedTargets, LOCAL_READ, LOCAL_WRITE, logsInOrOut, NO_EFFECTS, ownerOnlyOption, REMOTE_READ, REMOTE_WRITE, reachesOtherService, refuseUnderReadOnly, } from "./effects.js";
57
57
  export { type AnswerOutput, answerSchema, type Body, type ItemBody, itemAnswer, itemOf, jsonlRecords, judgedAnswer, type ListBody, type ListInput, listOf, metaNow, printItem, renderAnswer, sealed, snakeKeys, snakeKeysKeeping, } from "./envelope.js";
58
58
  export { withAbort } from "./execution.js";
59
59
  export { checkGuide, checkStep, type GuideOptions, type GuideReference, type GuideStep, guideCommand, loadScenarios, MEMO_SCENARIOS, type Scenario, shellProblems, } from "./guide.js";
@@ -65,6 +65,7 @@ export { bufferedInput, type InputPolicy, inputPolicy, MAX_BUFFERED_INPUT, MAX_S
65
65
  export { answerFields, checkJson, type EntityFields, entityFields, type JsonFieldsResolver, type JsonRequest, liftJson, } from "./json-fields.js";
66
66
  export { commandPath, LIST_QUERY_GUIDE, listQuery, nativeField, nativeTerms, pagedList, pageOf, type QueryWords, queryArgument, queryHelp, queryTerms, searchText, termField, timeBounds, typedQuery, unfilteredQuery, withQuery, } from "./list-query.js";
67
67
  export { addMeetingBatchCommand, formatMeetingBatch, prepareMeetingBatch } from "./meeting-batch.js";
68
+ export { meetingEvidenceItem, meetingPersonContextItem } from "./meeting-evidence-answer.js";
68
69
  export { parseEvidenceFindingsJson, parseMeetingFindingsJson } from "./meeting-findings-input.js";
69
70
  export { meetingPreparationAnswer } from "./meeting-preparation-answer.js";
70
71
  export { addMeetingPreparationCommand } from "./meeting-preparation-command.js";
@@ -106,7 +107,7 @@ export { callsCommand, stickersCommand } from "./messenger/records-command.js";
106
107
  export { repliesCommand } from "./messenger/replies-command.js";
107
108
  export { reviewCommand } from "./messenger/review.js";
108
109
  export { scheduleCommand } from "./messenger/schedule-command.js";
109
- export { allHitItem, type HitItem, type MessageHitItem, messageHitItem, type NoteHitItem, noteHitItem, } from "./messenger/search-answers.js";
110
+ export { allAnswer, allHitItem, type HitItem, type MessageHitItem, messageHitItem, type NoteHitItem, noteHitItem, } from "./messenger/search-answers.js";
110
111
  export { searchCommand } from "./messenger/search-command.js";
111
112
  export { SEARCHES_QUERY, searchesCommand } from "./messenger/searches-command.js";
112
113
  export { serveCommand, servingProfiles } from "./messenger/serve-command.js";
package/dist/cli/index.js CHANGED
@@ -48,7 +48,7 @@ export { loadSnakeCaseConfig } from "./config-keys.js";
48
48
  export { baseContext, environmentOf, outputFor, provide, secretInputOf, } from "./context.js";
49
49
  export { withDeadline } from "./deadline.js";
50
50
  export { DEFAULT_CONFIG, ensureDefaultConfig } from "./default-config.js";
51
- export { changesAuthority, destroysNothing, FETCH, grantsAuthority, isLogin, isOtherServiceCall, isStoreChange, judgedEffects, judgedTargets, LOCAL_READ, LOCAL_WRITE, logsInOrOut, NO_EFFECTS, ownerOnlyOption, REMOTE_READ, REMOTE_WRITE, reachesOtherService, refuseUnderReadOnly, } from "./effects.js";
51
+ export { changesAuthority, changesAuthorityAt, destroysNothing, FETCH, grantsAuthority, isLogin, isOtherServiceCall, isStoreChange, judgedEffects, judgedTargets, LOCAL_READ, LOCAL_WRITE, logsInOrOut, NO_EFFECTS, ownerOnlyOption, REMOTE_READ, REMOTE_WRITE, reachesOtherService, refuseUnderReadOnly, } from "./effects.js";
52
52
  export { answerSchema, itemAnswer, itemOf, jsonlRecords, judgedAnswer, listOf, metaNow, printItem, renderAnswer, sealed, snakeKeys, snakeKeysKeeping, } from "./envelope.js";
53
53
  export { withAbort } from "./execution.js";
54
54
  export { checkGuide, checkStep, guideCommand, loadScenarios, MEMO_SCENARIOS, shellProblems, } from "./guide.js";
@@ -60,6 +60,7 @@ export { bufferedInput, inputPolicy, MAX_BUFFERED_INPUT, MAX_SECRET_INPUT, provi
60
60
  export { answerFields, checkJson, entityFields, liftJson, } from "./json-fields.js";
61
61
  export { commandPath, LIST_QUERY_GUIDE, listQuery, nativeField, nativeTerms, pagedList, pageOf, queryArgument, queryHelp, queryTerms, searchText, termField, timeBounds, typedQuery, unfilteredQuery, withQuery, } from "./list-query.js";
62
62
  export { addMeetingBatchCommand, formatMeetingBatch, prepareMeetingBatch } from "./meeting-batch.js";
63
+ export { meetingEvidenceItem, meetingPersonContextItem } from "./meeting-evidence-answer.js";
63
64
  export { parseEvidenceFindingsJson, parseMeetingFindingsJson } from "./meeting-findings-input.js";
64
65
  export { meetingPreparationAnswer } from "./meeting-preparation-answer.js";
65
66
  export { addMeetingPreparationCommand } from "./meeting-preparation-command.js";
@@ -101,7 +102,7 @@ export { callsCommand, stickersCommand } from "./messenger/records-command.js";
101
102
  export { repliesCommand } from "./messenger/replies-command.js";
102
103
  export { reviewCommand } from "./messenger/review.js";
103
104
  export { scheduleCommand } from "./messenger/schedule-command.js";
104
- export { allHitItem, messageHitItem, noteHitItem, } from "./messenger/search-answers.js";
105
+ export { allAnswer, allHitItem, messageHitItem, noteHitItem, } from "./messenger/search-answers.js";
105
106
  export { searchCommand } from "./messenger/search-command.js";
106
107
  export { SEARCHES_QUERY, searchesCommand } from "./messenger/searches-command.js";
107
108
  export { serveCommand, servingProfiles } from "./messenger/serve-command.js";
@@ -21,6 +21,17 @@ export const entityFields = (table) => {
21
21
  return name !== undefined && Object.hasOwn(table, name) ? namesOf(table[name]) : undefined;
22
22
  };
23
23
  };
24
+ const schemaFields = (schema) => {
25
+ if (typeof schema !== "object" || schema === null)
26
+ return undefined;
27
+ if ("entries" in schema && typeof schema.entries === "object" && schema.entries !== null)
28
+ return Object.keys(schema.entries);
29
+ if ("type" in schema && schema.type === "union" && "options" in schema && Array.isArray(schema.options)) {
30
+ const branches = schema.options.map(schemaFields);
31
+ return branches.every((fields) => fields !== undefined) ? [...new Set(branches.flat())] : undefined;
32
+ }
33
+ return undefined;
34
+ };
24
35
  /** The fields of the answer a command declares (`annotate(…, { output })`); nothing until it declares one. */
25
36
  export const answerFields = (command, resolve) => {
26
37
  const own = resolve?.(command);
@@ -28,7 +39,7 @@ export const answerFields = (command, resolve) => {
28
39
  return [...own];
29
40
  const name = declaredEntity(command);
30
41
  const schema = name === undefined ? undefined : ENTITIES[name];
31
- return schema && "entries" in schema ? namesOf(schema) : undefined;
42
+ return schemaFields(schema);
32
43
  };
33
44
  const PATHS = /^[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)*(,[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)*)*$/;
34
45
  const topOf = (fields, known) => fields.split(",").map((path) => {
@@ -0,0 +1,46 @@
1
+ import type { MeetingEvidencePacket, PersonMeetingContext } from "../services/index.js";
2
+ /** A meeting evidence packet with `ref`, `offset_ms` and string ids, as every answer that carries one names them. */
3
+ export declare const mapEvidence: (evidence: MeetingEvidencePacket) => {
4
+ schemaVersion: 1;
5
+ kind: "meeting";
6
+ source: string;
7
+ fingerprint: string;
8
+ limits: {
9
+ cues: number;
10
+ bytes: number;
11
+ maxReadBytes: number;
12
+ maxTranscriptPages: number;
13
+ };
14
+ contentBytes: number;
15
+ coverage: {
16
+ provided: number;
17
+ included: number;
18
+ omitted: number | null;
19
+ providedExact: boolean;
20
+ nextReference: string | null;
21
+ transcriptPages: number;
22
+ skippedUnavailable: number;
23
+ hasMore: boolean;
24
+ truncatedBy: "cues" | "bytes" | "transcripts" | null;
25
+ input: "bounded-meeting-pages";
26
+ archiveCompleteness: "unknown";
27
+ nextTranscriptId: string | null;
28
+ };
29
+ items: {
30
+ fingerprint: string;
31
+ contentHash: string | null;
32
+ position: number;
33
+ endMs: number;
34
+ speakerName: string | null;
35
+ text: string;
36
+ revision: "current" | "superseded";
37
+ ref: string;
38
+ offsetMs: number;
39
+ transcriptId: string | null;
40
+ speakerParticipantId: string | null;
41
+ }[];
42
+ };
43
+ /** `meetings evidence`: the `meeting_evidence` entity. */
44
+ export declare const meetingEvidenceItem: (evidence: MeetingEvidencePacket) => unknown;
45
+ /** `meetings context`: the `meeting_person_context` entity. */
46
+ export declare const meetingPersonContextItem: (context: PersonMeetingContext) => unknown;
@@ -0,0 +1,22 @@
1
+ import { snakeKeys } from "./envelope.js";
2
+ const id = (value) => (value === null ? null : String(value));
3
+ const mapCue = ({ reference, startMs, ...cue }) => ({
4
+ ...cue,
5
+ ref: reference,
6
+ offsetMs: startMs,
7
+ transcriptId: id(cue.transcriptId),
8
+ speakerParticipantId: id(cue.speakerParticipantId),
9
+ });
10
+ /** A meeting evidence packet with `ref`, `offset_ms` and string ids, as every answer that carries one names them. */
11
+ export const mapEvidence = (evidence) => ({
12
+ ...evidence,
13
+ coverage: { ...evidence.coverage, nextTranscriptId: id(evidence.coverage.nextTranscriptId) },
14
+ items: evidence.items.map(mapCue),
15
+ });
16
+ /** `meetings evidence`: the `meeting_evidence` entity. */
17
+ export const meetingEvidenceItem = (evidence) => snakeKeys(mapEvidence(evidence));
18
+ /** `meetings context`: the `meeting_person_context` entity. */
19
+ export const meetingPersonContextItem = (context) => snakeKeys({
20
+ ...context,
21
+ items: context.items.map(({ reference, cues, ...item }) => ({ ...item, ref: reference, cues: cues.map(mapCue) })),
22
+ });
@@ -3,6 +3,7 @@ import * as v from "valibot";
3
3
  import { meetingPreparation } from "../entities/index.js";
4
4
  import { itemOf, metaNow, sealed, snakeKeys } from "./envelope.js";
5
5
  import { mapPreparationCommunications } from "./meeting-communications.js";
6
+ import { mapEvidence } from "./meeting-evidence-answer.js";
6
7
  import { boundMeetingPreparationItem } from "./meeting-preparation-budget.js";
7
8
  import { mapPreparationProjectEvidence } from "./meeting-preparation-projects.js";
8
9
  const id = (value) => (value === null ? null : String(value));
@@ -17,19 +18,6 @@ const mapMeeting = (meeting) => {
17
18
  updatedAt: at(meeting.updatedAt),
18
19
  };
19
20
  };
20
- const mapEvidence = (evidence) => {
21
- return {
22
- ...evidence,
23
- coverage: { ...evidence.coverage, nextTranscriptId: id(evidence.coverage.nextTranscriptId) },
24
- items: evidence.items.map(({ reference, startMs, ...cue }) => ({
25
- ...cue,
26
- ref: reference,
27
- offsetMs: startMs,
28
- transcriptId: id(cue.transcriptId),
29
- speakerParticipantId: id(cue.speakerParticipantId),
30
- })),
31
- };
32
- };
33
21
  export const meetingPreparationAnswer = (packet) => {
34
22
  const candidate = packet.upcoming.candidate;
35
23
  const mapped = snakeKeys({
@@ -6,7 +6,9 @@ import { storePath } from "../../store/path.js";
6
6
  import { openStore } from "../../store/store.js";
7
7
  import { REMOTE_READ, REMOTE_WRITE } from "../effects.js";
8
8
  import { itemOf, renderAnswer } from "../envelope.js";
9
+ import { queryTerms, withQuery } from "../list-query.js";
9
10
  import { NONE_NAMED } from "../settings.js";
11
+ import { ACCOUNT_PROFILES_QUERY } from "./account-profile-query.js";
10
12
  import { accountSessionsCommand } from "./account-sessions-command.js";
11
13
  import { recalledAccount } from "./accounts.js";
12
14
  import { photoHelp, readProfilePhoto } from "./admin-commands.js";
@@ -18,16 +20,19 @@ export const accountCommand = (messenger) => {
18
20
  const tool = `${messenger.app.command} personal`;
19
21
  const account = new Command("account")
20
22
  .description("the logged-in account")
21
- .addCommand(annotate(new Command("list"), { effects: REMOTE_READ, examples: [`${tool} account list`] })
23
+ .addCommand(withQuery(annotate(new Command("list"), { effects: REMOTE_READ, examples: [`${tool} account list`] }), ACCOUNT_PROFILES_QUERY)
22
24
  .summary("profiles on this computer and their signed-in accounts")
23
25
  .description("every profile on this computer, and the account each is logged in as; asks the messenger nothing")
24
- .action(async function () {
26
+ .action(async function (words) {
27
+ const terms = queryTerms(words, ACCOUNT_PROFILES_QUERY, "account list");
25
28
  const context = messengerContext(this, messenger, { needsProfile: false });
26
29
  const { app, provider } = messenger;
27
30
  const current = context.settings.sources.profile === NONE_NAMED ? undefined : context.settings.profile;
28
- const profiles = [
29
- ...new Set([...(current === undefined ? [] : [current]), ...context.settings.profilesHere]),
30
- ].sort();
31
+ const profiles = [...new Set([...(current === undefined ? [] : [current]), ...context.settings.profilesHere])]
32
+ .filter((profile) => terms.get("profile") === undefined || profile === terms.get("profile"))
33
+ .filter((profile) => terms.get("current") === undefined ||
34
+ (profile === current) === (terms.get("current")?.toLowerCase() === "true"))
35
+ .sort();
31
36
  const store = existsSync(storePath(context.env))
32
37
  ? await openStore({ env: context.env }).catch(() => undefined)
33
38
  : undefined;
@@ -61,7 +66,11 @@ export const accountCommand = (messenger) => {
61
66
  const account = await context.withMessenger((connection) => connection.me());
62
67
  renderAnswer(this, context, itemOf(accountAnswer(messenger.provider, whole ? account : maskedAccount(account))));
63
68
  }))
64
- .addCommand(annotate(new Command("update"), { effects: REMOTE_WRITE, examples: [`${tool} account update --first-name Alex`] })
69
+ .addCommand(annotate(new Command("update"), {
70
+ effects: REMOTE_WRITE,
71
+ output: { entity: "account_change" },
72
+ examples: [`${tool} account update --first-name Alex`],
73
+ })
65
74
  .description("change the name, the description or the photo everyone sees on your profile")
66
75
  .option("--first-name <name>", "your first name")
67
76
  .option("--last-name <name>", "your last name")
@@ -0,0 +1,2 @@
1
+ import { type QueryRegistry } from "@wirecat/cli-base/query";
2
+ export declare const ACCOUNT_PROFILES_QUERY: QueryRegistry;
@@ -0,0 +1,13 @@
1
+ import { queryFieldsOf } from "@wirecat/cli-base/query";
2
+ import { accountProfile } from "../../entities/index.js";
3
+ export const ACCOUNT_PROFILES_QUERY = {
4
+ entity: "account_profile",
5
+ backend: "native",
6
+ fields: queryFieldsOf(accountProfile, {
7
+ native: ["profile", "current"],
8
+ examples: { profile: "profile:work", current: "current:true" },
9
+ }).map((field) => ({
10
+ ...field,
11
+ operators: field.operators.filter((operator) => operator === "term" || operator === "phrase"),
12
+ })),
13
+ };
@@ -23,10 +23,9 @@ export const accountSessionsCommand = (messenger) => {
23
23
  const found = await context.withMessenger((adapter) => capability(adapter, "sessions", "list the account's sessions")());
24
24
  renderAnswer(this, context, wholeList("account sessions list", found.map(sessionAnswer)));
25
25
  });
26
- // No MCP tool, at any permission level: it logs the owner out of the phone.
27
26
  sessions.addCommand(annotate(new Command("end"), {
28
27
  effects: REMOTE_WRITE,
29
- mcp: false,
28
+ output: { entity: "ended_account_sessions" },
30
29
  examples: [`${tool} account sessions end --others`],
31
30
  })
32
31
  .description("log out every other device, your phone included; this one stays")