@wirecat/cli-memo 0.131.25 → 0.131.26

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 (153) hide show
  1. package/dist/actions/actions.d.ts +1 -1
  2. package/dist/actions/actions.d.ts.map +1 -1
  3. package/dist/actions/actions.js +27 -8
  4. package/dist/actions/actions.js.map +1 -1
  5. package/dist/actions/command.d.ts +1 -1
  6. package/dist/actions/command.d.ts.map +1 -1
  7. package/dist/actions/command.js +1 -12
  8. package/dist/actions/command.js.map +1 -1
  9. package/dist/bin/memo.js +2 -2
  10. package/dist/bundle/{all-profiles-L2T7PQ7S.js → all-profiles-VULFSNYE.js} +5 -5
  11. package/dist/bundle/{anthropic-KWI2B4O2.js → anthropic-VXQ6ST2U.js} +3 -3
  12. package/dist/bundle/{app-server-GLDIS3HE.js → app-server-HQPELIPY.js} +35 -35
  13. package/dist/bundle/auto-3R4RFJGK.js +86 -0
  14. package/dist/bundle/{bun-SMKYTOGI.js → bun-2NMWL5YB.js} +2 -2
  15. package/dist/bundle/{bun-sqlite-PKY3JXMR.js → bun-sqlite-CT544OXO.js} +2 -2
  16. package/dist/bundle/{chunk-T3R6QHD2.js → chunk-254TXVLA.js} +1 -1
  17. package/dist/bundle/{chunk-VZ3K7IYC.js → chunk-2ND2XYME.js} +12 -9
  18. package/dist/bundle/{chunk-JVNSHN2J.js → chunk-3CVDHJER.js} +1 -1
  19. package/dist/bundle/{chunk-6OP743NB.js → chunk-3ZJE5TIG.js} +1 -1
  20. package/dist/bundle/{chunk-MZS3LIMW.js → chunk-4ENVJFRM.js} +27 -27
  21. package/dist/bundle/{chunk-KFZGI7BU.js → chunk-5FPQGUJA.js} +1 -1
  22. package/dist/bundle/{chunk-ENU2556X.js → chunk-6PRRZC7Z.js} +1 -1
  23. package/dist/bundle/{chunk-I5LIEFQR.js → chunk-6TJCRDNZ.js} +3 -3
  24. package/dist/bundle/{chunk-FS3ABWVX.js → chunk-7ISENDNK.js} +10 -10
  25. package/dist/bundle/{chunk-5ANNUWNM.js → chunk-7LMTWOTP.js} +1 -1
  26. package/dist/bundle/{chunk-XFDE6AL4.js → chunk-A4NZ2XOG.js} +7 -7
  27. package/dist/bundle/{chunk-WHVH72AD.js → chunk-A6PITALJ.js} +3 -1
  28. package/dist/bundle/{chunk-JLBKAIVT.js → chunk-AGMYCYSG.js} +150 -150
  29. package/dist/bundle/{chunk-ERQHZZNF.js → chunk-ARDUJR5Z.js} +1 -1
  30. package/dist/bundle/{chunk-NFTWNCEL.js → chunk-BELLQAWL.js} +7 -7
  31. package/dist/bundle/{chunk-D5ZV7PRP.js → chunk-BO4FN4UB.js} +2 -2
  32. package/dist/bundle/{chunk-UQS6Y2A7.js → chunk-CRC3AW6N.js} +2 -2
  33. package/dist/bundle/{chunk-EFTJ4RTT.js → chunk-CUWI6JIX.js} +5 -5
  34. package/dist/bundle/{chunk-ZVEGLXYB.js → chunk-CW3NJ764.js} +4 -4
  35. package/dist/bundle/{chunk-EEVUVWHW.js → chunk-DKKWZMR7.js} +1 -1
  36. package/dist/bundle/{chunk-QOWGFGG3.js → chunk-DUHXWFCB.js} +4 -4
  37. package/dist/bundle/{chunk-OGMTUMB7.js → chunk-FHY664YS.js} +3 -3
  38. package/dist/bundle/{chunk-MAUKGKRA.js → chunk-GJBK3M6X.js} +28 -4
  39. package/dist/bundle/{chunk-MWX7UJCL.js → chunk-GOEHJK2R.js} +4 -4
  40. package/dist/bundle/{chunk-5SKYUS4U.js → chunk-GPYGMETC.js} +284 -279
  41. package/dist/bundle/{chunk-PCT2CIYR.js → chunk-H6O6IQND.js} +3 -3
  42. package/dist/bundle/{chunk-UWUP3A5H.js → chunk-HN3EDDVX.js} +12 -12
  43. package/dist/bundle/{chunk-POXCMAM7.js → chunk-HVVBSM2C.js} +601 -396
  44. package/dist/bundle/{chunk-4AONXXP2.js → chunk-IJ34FAES.js} +11 -11
  45. package/dist/bundle/{chunk-LFNJ6CG6.js → chunk-IUM5XZWV.js} +5 -5
  46. package/dist/bundle/{chunk-QA674BMY.js → chunk-J57DDKF4.js} +1 -1
  47. package/dist/bundle/{chunk-RKLZQVKL.js → chunk-KFDPW2AR.js} +2 -2
  48. package/dist/bundle/{chunk-ILUTSRU3.js → chunk-KMZRXGTF.js} +1 -1
  49. package/dist/bundle/{chunk-ZUV337F2.js → chunk-KTDNFSXC.js} +20 -20
  50. package/dist/bundle/{chunk-7Y6O4UQB.js → chunk-LJZFMXDC.js} +20 -20
  51. package/dist/bundle/{chunk-E2WPSRCI.js → chunk-LMN7SYX4.js} +1 -1
  52. package/dist/bundle/{chunk-J7T6RSR5.js → chunk-M4QN77GH.js} +3 -3
  53. package/dist/bundle/{chunk-SBMBBVXF.js → chunk-M6O4DH5F.js} +1 -1
  54. package/dist/bundle/{chunk-INA5WGY7.js → chunk-MQAHMAJB.js} +1 -1
  55. package/dist/bundle/{chunk-RTII6JWI.js → chunk-NAM2Y63Z.js} +2 -2
  56. package/dist/bundle/{chunk-ZLB2CM7Z.js → chunk-NH2JSH24.js} +4 -4
  57. package/dist/bundle/{chunk-5GMOYTJQ.js → chunk-OYB3FUYQ.js} +1 -1
  58. package/dist/bundle/{chunk-YMAS7U5X.js → chunk-PWA3RNXN.js} +256 -257
  59. package/dist/bundle/{chunk-VGYXKQJE.js → chunk-QFW4MJIH.js} +219 -221
  60. package/dist/bundle/{chunk-ON5SHKHB.js → chunk-QKQ7A4L7.js} +43 -43
  61. package/dist/bundle/{chunk-QYDCVWD4.js → chunk-S3RBWUUA.js} +5 -5
  62. package/dist/bundle/{chunk-BNF2ZUNS.js → chunk-SY7M2DLJ.js} +8 -8
  63. package/dist/bundle/{chunk-5JYB6QKS.js → chunk-TKVRZZE3.js} +1 -13
  64. package/dist/bundle/{chunk-SW5YJCHC.js → chunk-TPFWNOPG.js} +4 -4
  65. package/dist/bundle/{chunk-JDDLDKC7.js → chunk-TXANQZEG.js} +2 -2
  66. package/dist/bundle/{chunk-BX7DVBWD.js → chunk-UZXCBBDC.js} +9 -9
  67. package/dist/bundle/{chunk-ZKZT6PCF.js → chunk-VL3YCTZD.js} +6 -6
  68. package/dist/bundle/{chunk-H5QHU5LZ.js → chunk-WRZ7JDA2.js} +5 -5
  69. package/dist/bundle/{chunk-IE27DJP3.js → chunk-XKGXVVYV.js} +4 -4
  70. package/dist/bundle/{chunk-QJJSMLBR.js → chunk-YFBKS5BW.js} +2 -2
  71. package/dist/bundle/{chunk-47EZNSMD.js → chunk-Z3YGDBBS.js} +2 -2
  72. package/dist/bundle/{chunk-WGHQXJHL.js → chunk-ZR3BPBS6.js} +7 -7
  73. package/dist/bundle/{command-contract-47EKA67S.js → command-contract-RQMIQKBS.js} +11 -11
  74. package/dist/bundle/{decode-EEDEXCHR.js → decode-7VB3CHK2.js} +2 -2
  75. package/dist/bundle/{echarts-36MD3UZF.js → echarts-45D6USAX.js} +2 -2
  76. package/dist/bundle/{embed-R6JZ4CDW.js → embed-KU2RGB24.js} +3 -3
  77. package/dist/bundle/{embedder-XUIOKCH6.js → embedder-E7YZDZ5Y.js} +6 -6
  78. package/dist/bundle/{entry-WOAZRQ5F.js → entry-N42HJMIN.js} +4 -4
  79. package/dist/bundle/failure-R355OCVE.js +66 -0
  80. package/dist/bundle/{first-run-3ZUSIFQJ.js → first-run-Y5YNAAO3.js} +5 -5
  81. package/dist/bundle/{first-screen-WQ2IDXDP.js → first-screen-SNPGBQFZ.js} +12 -12
  82. package/dist/bundle/{instructions-7VMPJMUM.js → instructions-6EFSPC7C.js} +1 -1
  83. package/dist/bundle/{mcp-I7LL7AJG.js → mcp-6Z7UKX7E.js} +35 -35
  84. package/dist/bundle/memo.js +6 -6
  85. package/dist/bundle/{node-SBHCG4ZC.js → node-OXC26QXO.js} +2 -2
  86. package/dist/bundle/{node-sqlite-EMKROM5U.js → node-sqlite-FNTICDEN.js} +3 -3
  87. package/dist/bundle/{oauth-OJPTUA5K.js → oauth-4JFOFCBB.js} +4 -4
  88. package/dist/bundle/{open-XI2AVS5B.js → open-WXFCCY7S.js} +2 -2
  89. package/dist/bundle/{openai-NCYTRZB6.js → openai-TPQKQNM7.js} +7 -7
  90. package/dist/bundle/{process-373B2EBA.js → process-YWPAOI6G.js} +1 -1
  91. package/dist/bundle/{program-VW7IJ755.js → program-WFUPN7XO.js} +560 -660
  92. package/dist/bundle/{prompt-L3KQBPNH.js → prompt-HJUH4EP4.js} +2 -2
  93. package/dist/bundle/{recognize-GFWZX4F6.js → recognize-DAIRHALM.js} +1 -1
  94. package/dist/bundle/{remote-5IGAYQBB.js → remote-MJLWTLAX.js} +4 -4
  95. package/dist/bundle/{rerank-6HWHGDFX.js → rerank-VAK5HSJE.js} +4 -4
  96. package/dist/bundle/{serve-AA7RKEOM.js → serve-M2A66WOW.js} +6 -6
  97. package/dist/bundle/server-33FB7QXW.js +48 -0
  98. package/dist/bundle/server-AIPDQO57.js +61 -0
  99. package/dist/bundle/{server-Z6L4U6HO.js → server-NN2CBVSX.js} +50 -50
  100. package/dist/bundle/{state-3WTPOBXR.js → state-6TBUXJOX.js} +3 -3
  101. package/dist/bundle/{store-LNP5BXUL.js → store-TJCL3QBY.js} +9 -9
  102. package/dist/bundle/store-maintenance-command-NKJV5A3G.js +48 -0
  103. package/dist/bundle/update-OXR3SNM2.js +69 -0
  104. package/dist/config.d.ts +13 -1
  105. package/dist/config.d.ts.map +1 -1
  106. package/dist/config.js +21 -1
  107. package/dist/config.js.map +1 -1
  108. package/dist/context/command.d.ts.map +1 -1
  109. package/dist/context/command.js +6 -2
  110. package/dist/context/command.js.map +1 -1
  111. package/dist/context/context.d.ts +2 -0
  112. package/dist/context/context.d.ts.map +1 -1
  113. package/dist/context/context.js +15 -0
  114. package/dist/context/context.js.map +1 -1
  115. package/dist/examples.d.ts.map +1 -1
  116. package/dist/examples.js +2 -1
  117. package/dist/examples.js.map +1 -1
  118. package/dist/mail/messages-command.d.ts.map +1 -1
  119. package/dist/mail/messages-command.js +9 -2
  120. package/dist/mail/messages-command.js.map +1 -1
  121. package/dist/mail/review-command.d.ts.map +1 -1
  122. package/dist/mail/review-command.js +5 -8
  123. package/dist/mail/review-command.js.map +1 -1
  124. package/dist/reasons.d.ts.map +1 -1
  125. package/dist/reasons.js +0 -12
  126. package/dist/reasons.js.map +1 -1
  127. package/dist/review/command.d.ts +0 -1
  128. package/dist/review/command.d.ts.map +1 -1
  129. package/dist/review/command.js +2 -10
  130. package/dist/review/command.js.map +1 -1
  131. package/dist/review/kinds.d.ts +4 -21
  132. package/dist/review/kinds.d.ts.map +1 -1
  133. package/dist/review/kinds.js +13 -174
  134. package/dist/review/kinds.js.map +1 -1
  135. package/dist/review/review.js +2 -2
  136. package/dist/review/review.js.map +1 -1
  137. package/dist/review/status.js +2 -2
  138. package/dist/review/status.js.map +1 -1
  139. package/dist/schedule/command.d.ts +2 -2
  140. package/dist/schedule/command.d.ts.map +1 -1
  141. package/dist/schedule/command.js +9 -4
  142. package/dist/schedule/command.js.map +1 -1
  143. package/dist/version.d.ts +1 -1
  144. package/dist/version.js +1 -1
  145. package/package.json +2 -2
  146. package/skills/mail-triage/SKILL.md +19 -11
  147. package/dist/bundle/auto-QFG57LR6.js +0 -86
  148. package/dist/bundle/failure-BHRE5S75.js +0 -66
  149. package/dist/bundle/server-MWUCYBJF.js +0 -61
  150. package/dist/bundle/server-XEY5AKKG.js +0 -48
  151. package/dist/bundle/store-maintenance-command-6HEGTKPL.js +0 -48
  152. package/dist/bundle/update-6GWVILUX.js +0 -69
  153. /package/dist/bundle/{chunk-MNDLWYNQ.js → chunk-DF7NE4ZG.js} +0 -0
@@ -6,17 +6,17 @@ import {
6
6
  autoState,
7
7
  lastAutoRun,
8
8
  recordAutoRun
9
- } from "./chunk-IE27DJP3.js";
9
+ } from "./chunk-XKGXVVYV.js";
10
10
  import {
11
11
  installer,
12
12
  latest,
13
13
  upgradeCommand
14
- } from "./chunk-H5QHU5LZ.js";
14
+ } from "./chunk-WRZ7JDA2.js";
15
15
  import {
16
16
  mcpOwnerAllowed,
17
17
  readOnlyAvailability,
18
18
  refuseWritesUnderLock
19
- } from "./chunk-QYDCVWD4.js";
19
+ } from "./chunk-S3RBWUUA.js";
20
20
  import {
21
21
  answers,
22
22
  atDetail as atDetail2,
@@ -26,7 +26,7 @@ import {
26
26
  trackAnswers,
27
27
  wholeList,
28
28
  withStore
29
- } from "./chunk-MWX7UJCL.js";
29
+ } from "./chunk-GOEHJK2R.js";
30
30
  import {
31
31
  DIALECTS,
32
32
  MEMO_SETTINGS,
@@ -42,23 +42,26 @@ import {
42
42
  noteFiles,
43
43
  rawConfig,
44
44
  readMemoId,
45
+ scheduleLimits,
45
46
  unsetConfigKey,
46
47
  updateConfig
47
- } from "./chunk-MAUKGKRA.js";
48
+ } from "./chunk-GJBK3M6X.js";
48
49
  import "./chunk-QP3KNC5D.js";
49
- import "./chunk-JDDLDKC7.js";
50
- import "./chunk-WGHQXJHL.js";
51
- import "./chunk-OGMTUMB7.js";
50
+ import "./chunk-TXANQZEG.js";
51
+ import "./chunk-ZR3BPBS6.js";
52
+ import "./chunk-FHY664YS.js";
52
53
  import {
53
54
  errorObject,
54
55
  recognisable
55
- } from "./chunk-PCT2CIYR.js";
56
+ } from "./chunk-H6O6IQND.js";
56
57
  import {
57
58
  DISCOVERY_DESCRIPTIONS,
58
59
  SUMMARY_UNTRUSTED,
59
60
  acknowledgeMark,
61
+ actorOf,
60
62
  addContractInfo,
61
63
  addMeetingPreparationCommand,
64
+ advancePastSkipped,
62
65
  backendRequest,
63
66
  catchUpQuery,
64
67
  checkJson,
@@ -66,8 +69,8 @@ import {
66
69
  dateOrNone,
67
70
  entityFields,
68
71
  guideCommand,
69
- holderHasMail,
70
72
  liftJson,
73
+ mailWaiting,
71
74
  marksOf,
72
75
  mcpServerCommand,
73
76
  modelCatalogueCommand,
@@ -97,9 +100,9 @@ import {
97
100
  tasksStatsCommand,
98
101
  unansweredHours,
99
102
  withSqliteSidecars
100
- } from "./chunk-POXCMAM7.js";
101
- import "./chunk-SBMBBVXF.js";
102
- import "./chunk-5GMOYTJQ.js";
103
+ } from "./chunk-HVVBSM2C.js";
104
+ import "./chunk-M6O4DH5F.js";
105
+ import "./chunk-OYB3FUYQ.js";
103
106
  import {
104
107
  MAIL_HIT_UNTRUSTED,
105
108
  allHitItem,
@@ -109,25 +112,24 @@ import {
109
112
  noteHitItem,
110
113
  offsetOf,
111
114
  shownOf
112
- } from "./chunk-ZUV337F2.js";
113
- import "./chunk-T3R6QHD2.js";
115
+ } from "./chunk-KTDNFSXC.js";
116
+ import "./chunk-254TXVLA.js";
114
117
  import {
115
118
  SKILL_TARGETS,
116
119
  skillCommand,
117
120
  skillPath,
118
121
  skillVersion
119
- } from "./chunk-VZ3K7IYC.js";
122
+ } from "./chunk-2ND2XYME.js";
120
123
  import {
121
124
  messageItem,
122
125
  modelGateway,
123
126
  storeInfo,
124
127
  storeSummary
125
- } from "./chunk-ON5SHKHB.js";
126
- import "./chunk-7Y6O4UQB.js";
128
+ } from "./chunk-QKQ7A4L7.js";
129
+ import "./chunk-LJZFMXDC.js";
127
130
  import {
128
131
  AGENDA_DEFAULTS,
129
132
  DEFAULT_BACKEND,
130
- FACT_SUMMARIES,
131
133
  LIST_QUERY_GUIDE,
132
134
  ORGANIZATIONS_QUERY,
133
135
  PROJECTS_QUERY,
@@ -190,18 +192,18 @@ import {
190
192
  termField,
191
193
  typedQuery,
192
194
  withQuery
193
- } from "./chunk-YMAS7U5X.js";
195
+ } from "./chunk-PWA3RNXN.js";
194
196
  import {
195
197
  readBoundedUtf8File,
196
198
  writeFileAtomic
197
- } from "./chunk-UWUP3A5H.js";
199
+ } from "./chunk-HN3EDDVX.js";
198
200
  import {
199
201
  commandsText,
200
202
  inSection,
201
203
  installHelp
202
- } from "./chunk-ZKZT6PCF.js";
204
+ } from "./chunk-VL3YCTZD.js";
203
205
  import "./chunk-HTQTIKWP.js";
204
- import "./chunk-UQS6Y2A7.js";
206
+ import "./chunk-CRC3AW6N.js";
205
207
  import {
206
208
  Command,
207
209
  FETCH,
@@ -242,22 +244,25 @@ import {
242
244
  text,
243
245
  time,
244
246
  untrusted
245
- } from "./chunk-JLBKAIVT.js";
246
- import "./chunk-NFTWNCEL.js";
247
- import "./chunk-FS3ABWVX.js";
247
+ } from "./chunk-AGMYCYSG.js";
248
+ import "./chunk-BELLQAWL.js";
249
+ import "./chunk-7ISENDNK.js";
248
250
  import {
249
251
  isNewer
250
252
  } from "./chunk-I7PL5WX2.js";
251
253
  import "./chunk-YPF6OS37.js";
252
- import "./chunk-I5LIEFQR.js";
253
- import "./chunk-BX7DVBWD.js";
254
- import "./chunk-WHVH72AD.js";
255
- import "./chunk-ZVEGLXYB.js";
254
+ import "./chunk-6TJCRDNZ.js";
255
+ import "./chunk-UZXCBBDC.js";
256
+ import {
257
+ mailHolderVariable,
258
+ readOnlyLockOf
259
+ } from "./chunk-A6PITALJ.js";
260
+ import "./chunk-CW3NJ764.js";
256
261
  import {
257
262
  releaseLock,
258
263
  takeLock
259
- } from "./chunk-D5ZV7PRP.js";
260
- import "./chunk-JVNSHN2J.js";
264
+ } from "./chunk-BO4FN4UB.js";
265
+ import "./chunk-3CVDHJER.js";
261
266
  import {
262
267
  EVIDENCE_FINDINGS_KIND,
263
268
  FINANCE_REVIEWS,
@@ -294,12 +299,11 @@ import {
294
299
  openStore,
295
300
  parseLocator,
296
301
  parseReference,
297
- proposerOfAction,
298
302
  providerNamed,
299
303
  queryFilter,
300
304
  refLabel,
301
305
  validateFields
302
- } from "./chunk-5SKYUS4U.js";
306
+ } from "./chunk-GPYGMETC.js";
303
307
  import {
304
308
  FACT_STATUSES,
305
309
  FACT_TYPES,
@@ -326,22 +330,22 @@ import {
326
330
  timezoneOf,
327
331
  validateQuery,
328
332
  walkQuery
329
- } from "./chunk-VGYXKQJE.js";
330
- import "./chunk-QA674BMY.js";
331
- import "./chunk-XFDE6AL4.js";
332
- import "./chunk-ZLB2CM7Z.js";
333
- import "./chunk-RTII6JWI.js";
334
- import "./chunk-EEVUVWHW.js";
335
- import "./chunk-ENU2556X.js";
336
- import "./chunk-6OP743NB.js";
337
- import "./chunk-QJJSMLBR.js";
338
- import "./chunk-LFNJ6CG6.js";
333
+ } from "./chunk-QFW4MJIH.js";
334
+ import "./chunk-J57DDKF4.js";
335
+ import "./chunk-A4NZ2XOG.js";
336
+ import "./chunk-NH2JSH24.js";
337
+ import "./chunk-NAM2Y63Z.js";
338
+ import "./chunk-DKKWZMR7.js";
339
+ import "./chunk-6PRRZC7Z.js";
340
+ import "./chunk-3ZJE5TIG.js";
341
+ import "./chunk-YFBKS5BW.js";
342
+ import "./chunk-IUM5XZWV.js";
339
343
  import {
340
344
  sharedModelsDirectory
341
- } from "./chunk-J7T6RSR5.js";
345
+ } from "./chunk-M4QN77GH.js";
342
346
  import {
343
347
  storePath
344
- } from "./chunk-INA5WGY7.js";
348
+ } from "./chunk-MQAHMAJB.js";
345
349
  import {
346
350
  provideTerminal,
347
351
  terminalOf
@@ -351,12 +355,12 @@ import {
351
355
  REASONS,
352
356
  STORE_CLIENT,
353
357
  VERSION
354
- } from "./chunk-5JYB6QKS.js";
358
+ } from "./chunk-TKVRZZE3.js";
355
359
  import "./chunk-KV4267S4.js";
356
360
  import "./chunk-LU3WKZBA.js";
357
361
  import "./chunk-D72URWJE.js";
358
- import "./chunk-EFTJ4RTT.js";
359
- import "./chunk-ILUTSRU3.js";
362
+ import "./chunk-CUWI6JIX.js";
363
+ import "./chunk-KMZRXGTF.js";
360
364
  import {
361
365
  createDeadline,
362
366
  createRenderer,
@@ -397,7 +401,7 @@ import {
397
401
  errorCodes,
398
402
  isCliError
399
403
  } from "./chunk-EB2IULWB.js";
400
- import "./chunk-E2WPSRCI.js";
404
+ import "./chunk-LMN7SYX4.js";
401
405
  import {
402
406
  __commonJS,
403
407
  __name,
@@ -10418,526 +10422,53 @@ var collect = /* @__PURE__ */ __name((value, previous = []) => [...previous, val
10418
10422
  var readScope = /* @__PURE__ */ __name((command, help = ONE_ACCOUNT_HELP) => sourceOptions(command, help).option("--json", "print JSON; --json=id,title keeps only those fields"), "readScope");
10419
10423
  var writeScope = /* @__PURE__ */ __name((command, help) => writeOptions(command, help).option("--json", "print JSON; --json=id,title keeps only those fields"), "writeScope");
10420
10424
 
10421
- // dist/notes/about.js
10422
- var isNoteReference = /* @__PURE__ */ __name((reference3) => /^(note|document):/.test(reference3), "isNoteReference");
10423
- var fold = /* @__PURE__ */ __name((value) => value.normalize("NFC").toLocaleLowerCase("en").trim().replace(/^@/, ""), "fold");
10424
- var refOf = /* @__PURE__ */ __name((note, anchor = null) => ({
10425
- ref: note.ref,
10426
- source: note.source,
10427
- folderId: note.folderId,
10428
- path: note.path,
10429
- title: note.title,
10430
- modifiedAt: note.updatedAt,
10431
- ...anchor === null ? {} : { anchor }
10432
- }), "refOf");
10433
- var PAGE = 500;
10434
- var notesReaching = /* @__PURE__ */ __name(async (store, subject) => {
10435
- const refs = [
10436
- subject.ref,
10437
- ...subject.person?.identities.map((identity) => formatReference({ type: "contact", provider: identity.provider, id: identity.id })) ?? []
10438
- ];
10439
- const live = /* @__PURE__ */ __name(async (links, via) => {
10440
- const found = [];
10441
- for (const link of links) {
10442
- if (!isNoteReference(link.from))
10443
- continue;
10444
- const note = await store.notes.resolveNote(link.from);
10445
- if (note && note.deletedAt === null)
10446
- found.push({ note, anchor: link.anchor, text: link.targetText, via });
10447
- }
10448
- return found;
10449
- }, "live");
10450
- const aboutOne = /* @__PURE__ */ __name(async (ref) => {
10451
- const notes2 = [];
10452
- for (let offset = 0; ; offset += PAGE) {
10453
- const page = await store.notes.notes({ about: ref, limit: PAGE, offset });
10454
- notes2.push(...page.items);
10455
- if (!page.hasMore)
10456
- return notes2;
10457
- }
10458
- }, "aboutOne");
10459
- const about = (await Promise.all(refs.map(aboutOne))).flat().map((note) => ({ note, anchor: null, text: null, via: "about" }));
10460
- const linking = await live((await Promise.all(refs.map((to) => store.notes.links({ to })))).flat().filter((link) => link.kind === "links-to"), "link");
10461
- const through = await live((await Promise.all(about.map(({ note }) => store.notes.links({ to: note.ref })))).flat().filter((link) => link.kind === "links-to"), "through");
10462
- const names = new Set([subject.person?.name, ...subject.person?.identities.map(({ name }) => name) ?? []].filter((name) => !!name?.trim()).map(fold));
10463
- const waiting = names.size === 0 ? [] : await live((await store.notes.links({ unresolved: true })).filter((link) => names.has(fold(link.targetText ?? ""))), "name");
10464
- return [...about, ...linking, ...through, ...waiting];
10465
- }, "notesReaching");
10466
- var notesAbout = /* @__PURE__ */ __name(async (store, subject, limit = 20) => {
10467
- const found = await notesReaching(store, subject);
10468
- const unique = /* @__PURE__ */ __name((via) => [
10469
- ...new Map(found.filter((item) => item.via === via).map((item) => [`${item.note.ref}#${item.anchor ?? ""}`, item])).values()
10470
- ].sort((a, b) => b.note.updatedAt.localeCompare(a.note.updatedAt)), "unique");
10471
- const [about, linking, through, waiting] = ["about", "link", "through", "name"].map(unique);
10472
- return {
10473
- subject: subject.ref,
10474
- name: subject.person?.name ?? null,
10475
- about: (about ?? []).slice(0, limit).map(({ note }) => refOf(note)),
10476
- linking: (linking ?? []).slice(0, limit).map(({ note, anchor }) => refOf(note, anchor)),
10477
- throughNotes: (through ?? []).slice(0, limit).map(({ note, anchor }) => refOf(note, anchor)),
10478
- waiting: (waiting ?? []).slice(0, limit).map(({ note, text: text3 }) => ({ ...refOf(note), text: text3 ?? "" })),
10479
- hasMore: [about, linking, through, waiting].some((list) => (list ?? []).length > limit)
10480
- };
10481
- }, "notesAbout");
10482
-
10483
- // dist/refs.js
10484
- var BARE = /^\d+$/;
10485
- var either = /* @__PURE__ */ __name((words2) => words2.length < 2 ? words2[0] ?? "" : `${words2.slice(0, -1).join(", ")} or ${words2.at(-1)}`, "either");
10486
- var refuseBareNumber = /* @__PURE__ */ __name(async (store, text3, kinds2, options = {}) => {
10487
- const value = text3.trim();
10488
- if (!BARE.test(value))
10489
- return;
10490
- const candidates = kinds2.map((kind) => `${kind}:${value}`);
10491
- const found = await store.refs.summaries(candidates);
10492
- const existing = candidates.filter((ref) => {
10493
- const state = found.get(ref)?.state;
10494
- return state !== void 0 && state !== "unavailable";
10495
- });
10496
- const guess = existing.length ? `did you mean ${either(existing)}?` : `no ${either(kinds2.map((kind) => kind === "msg" ? "message" : kind))} has id ${value}`;
10497
- const path = options.path ? `; to read a file named ${value}, give its path: ./${value}` : "";
10498
- throw new CliError("validation_error", `"${value}" is a bare number; ${guess}${path}`, {
10499
- reason: "ref.bare-number",
10500
- value,
10501
- suggestion: existing[0] ?? candidates[0]
10502
- });
10503
- }, "refuseBareNumber");
10504
-
10505
- // dist/store/held.js
10506
- var heldMessage = /* @__PURE__ */ __name(async (store, key, id, chatId) => {
10507
- if (key.provider === "email") {
10508
- const account2 = await store.accounts.storedAccount(key).catch(() => void 0);
10509
- const email = account2 ? await store.mail.email(account2.id, id) : null;
10510
- if (email)
10511
- return email.deletedAt === null ? {
10512
- text: [email.subject, email.bodyText].filter(Boolean).join("\n\n"),
10513
- senderId: email.fromAddress,
10514
- senderName: email.fromName,
10515
- timestamp: new Date(email.sentAt ?? email.receivedAt ?? email.createdAt).toISOString()
10516
- } : void 0;
10517
- }
10518
- return store.messages.message(key, id, { chatId });
10519
- }, "heldMessage");
10425
+ // node_modules/.pnpm/@wirecat+cli-core@0.569.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_8785fed449bbc2a6b34fc086f24a8413/node_modules/@wirecat/cli-core/dist/mail/account-key.js
10426
+ var mailAccountKey = /* @__PURE__ */ __name((address) => ({ provider: "email", account: address.toLowerCase() }), "mailAccountKey");
10520
10427
 
10521
- // dist/store/scope.js
10522
- var choices = /* @__PURE__ */ __name((keys) => keys.length ? `; choose one of ${keys.map(({ provider, account: account2 }) => `${provider}:${account2}`).join(", ")}` : "", "choices");
10523
- var selectAccount = /* @__PURE__ */ __name(async (store, scope) => {
10524
- const held = await store.accounts.accounts();
10525
- if (!scope.provider)
10526
- throw new CliError("validation_error", `give --account <provider>:<account>${choices(held)}`);
10527
- const matches2 = held.filter((key) => key.provider === scope.provider && (scope.account === void 0 || key.account === scope.account));
10528
- if (matches2.length !== 1)
10529
- throw new CliError(matches2.length ? "validation_error" : "not_found", matches2.length ? `several accounts match; give one${choices(matches2)}` : `the store holds no ${scope.provider} account matching this selection${choices(held)}`);
10530
- return matches2[0];
10531
- }, "selectAccount");
10532
- var meetingReference = /* @__PURE__ */ __name(async (store, id, scope) => {
10533
- if (!/^\d+$/.test(id))
10534
- throw new CliError("validation_error", "--meeting takes the meeting's id in the store");
10535
- const account2 = await store.accounts.storedAccount(await selectAccount(store, scope));
10536
- const found = await store.meetings.meeting(Number(id));
10537
- if (found === null || found.meeting.accountId !== account2.id)
10538
- throw new CliError("not_found", `the ${account2.provider} account ${account2.account} holds no meeting ${id}`);
10539
- return `meeting:${account2.id}/${found.meeting.id}`;
10540
- }, "meetingReference");
10541
- var selectTarget = /* @__PURE__ */ __name(async (store, input) => {
10542
- const choices2 = ["message", "chat", "contact", "person", "task", "organization", "project", "meeting"];
10543
- const selected = choices2.filter((name) => input[name] !== void 0);
10544
- if (selected.length !== 1)
10545
- throw new CliError("validation_error", "select exactly one of --message, --chat, --contact, --person, --task, --organization, --project or --meeting");
10546
- const type = selected[0];
10547
- if (type === "message") {
10548
- const locator = input.message;
10549
- let parsed;
10550
- try {
10551
- parsed = parseLocator(locator);
10552
- } catch {
10553
- throw new CliError("validation_error", "give a valid msg: source locator");
10554
- }
10555
- if (input.provider && parsed.provider !== input.provider || input.account && parsed.account !== input.account)
10556
- throw new CliError("validation_error", "locator and selected account disagree");
10557
- return { key: { provider: parsed.provider, account: parsed.account }, target: { type, locator } };
10428
+ // node_modules/.pnpm/@wirecat+cli-core@0.569.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_8785fed449bbc2a6b34fc086f24a8413/node_modules/@wirecat/cli-core/dist/mail/attachments.js
10429
+ var MAX_ATTACHMENT_CHARS = 2e5;
10430
+ var DEFAULT_ATTACHMENT_POLICY = { read: true, maxBytes: 10 * 1024 * 1024 };
10431
+ var POLICY_SKIPS = ["not-read", "too-large"];
10432
+ var addressOf = /* @__PURE__ */ __name(({ email, name }) => ({ address: email, name }), "addressOf");
10433
+ var readAttachments = /* @__PURE__ */ __name(async (mail, messageId, { loadEngine, maxAttachmentChars, at, signal, policy }, log) => {
10434
+ const files = [];
10435
+ for (const [position, part] of mail.attachments.entries()) {
10436
+ if (signal?.aborted)
10437
+ throw signal.reason;
10438
+ const skipped = part.bytes === null || policy === void 0 ? void 0 : !policy.read ? "not-read" : part.bytes.byteLength > policy.maxBytes ? "too-large" : void 0;
10439
+ const extraction = part.bytes === null ? { status: "unavailable" } : skipped ? { status: skipped } : await extractText(part.bytes, { kind: "file", name: part.name, mime: part.mime, path: part.name }, loadEngine, signal);
10440
+ log.push({ message: messageId, part: part.id, status: extraction.status });
10441
+ const extracted = extraction.status === "extracted" ? extraction : void 0;
10442
+ files.push({
10443
+ position,
10444
+ kind: "file",
10445
+ mime: part.mime,
10446
+ name: part.name,
10447
+ title: null,
10448
+ url: null,
10449
+ size: part.bytes === null ? null : part.bytes.byteLength,
10450
+ width: null,
10451
+ height: null,
10452
+ duration: null,
10453
+ providerRef: { message: messageId, part: part.id },
10454
+ localPath: null,
10455
+ text: extracted ? extracted.text.slice(0, maxAttachmentChars) : null,
10456
+ normalizedText: null,
10457
+ extraction: extracted ? "text" : "failed",
10458
+ extractor: extracted ? extracted.extractor : null,
10459
+ extractionError: extracted ? null : extraction.status,
10460
+ contentSha256: null,
10461
+ extractedAt: at
10462
+ });
10558
10463
  }
10559
- return { key: await selectAccount(store, input), target: { type, id: input[type] } };
10560
- }, "selectTarget");
10561
- var scopeOf = /* @__PURE__ */ __name(async (store, env, options, warn) => {
10562
- const value = writeAccountOf(options, warn);
10563
- return value === void 0 ? {} : oneAccountOf(store, env, value, "--account");
10564
- }, "scopeOf");
10464
+ return files;
10465
+ }, "readAttachments");
10565
10466
 
10566
- // dist/vocabulary/project.js
10567
- var canonicalProject = /* @__PURE__ */ __name(async (store, reference3, limits = {}) => {
10568
- if (/^project:[1-9]\d*$/.test(reference3)) {
10569
- const catalog = await store.knowledge.vocabulary({ kind: "project", ...limits });
10570
- if (!catalog.entries.some((entry2) => entry2.id === reference3.slice(8)))
10571
- throw new CliError("not_found", "the owner project is unavailable");
10572
- return reference3;
10573
- }
10574
- const found = await store.knowledge.resolveVocabulary(reference3, { kind: "project", ...limits });
10575
- if (found.matches.length !== 1)
10576
- throw new CliError(found.matches.length ? "validation_error" : "not_found", found.matches.length ? `${reference3} names ${found.matches.length} projects; give one by its key, as memo vocabulary show ${reference3} lists them` : `no project ${reference3}; memo projects list shows yours, memo projects add creates one`, { candidates: found.matches.map((entry2) => ({ id: entry2.id, key: entry2.key, name: entry2.name })) });
10577
- const entry = found.matches[0];
10578
- if (!entry)
10579
- throw new CliError("not_found", "the owner project is unavailable");
10580
- return `project:${entry.id}`;
10581
- }, "canonicalProject");
10467
+ // node_modules/.pnpm/@wirecat+cli-core@0.569.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_8785fed449bbc2a6b34fc086f24a8413/node_modules/@wirecat/cli-core/dist/mail/bulk.js
10468
+ var BULK = "bulk";
10469
+ var bulkBox = { externalId: "memo:bulk", name: "bulk", kind: BULK };
10582
10470
 
10583
- // dist/tasks/tasks.js
10584
- var personRef = /* @__PURE__ */ __name((person) => person.startsWith("person:") ? person : `person:${person}`, "personRef");
10585
- var fieldsOf2 = /* @__PURE__ */ __name((options) => ({
10586
- ...options.title === void 0 ? {} : { title: options.title },
10587
- ...options.priority === void 0 ? {} : { priority: options.priority },
10588
- ...options.parent === void 0 ? {} : { parent: options.parent },
10589
- ...options.description === void 0 ? {} : { description: options.description }
10590
- }), "fieldsOf");
10591
- var assignAll = /* @__PURE__ */ __name(async (store, env, id, people) => {
10592
- for (const person of people ?? [])
10593
- await store.tasks.assign(id, { to: personRef(person), role: "assignee" }, authorOf(env));
10594
- }, "assignAll");
10595
- var addToProject = /* @__PURE__ */ __name(async (store, env, options) => {
10596
- if (options.project === void 0 || options.title === void 0)
10597
- throw new CliError("validation_error", "a task without a source needs --project and --title");
10598
- if (options.into !== void 0 || options.new)
10599
- throw new CliError("validation_error", "--into and --new are for a task from a source");
10600
- const type = options.type ?? "chore";
10601
- if (!WORK_TASK_TYPES.includes(type))
10602
- throw new CliError("validation_error", `a task in a project is ${WORK_TASK_TYPES.join(", ")}`);
10603
- const task = await store.tasks.create({
10604
- project: await canonicalProject(store, options.project),
10605
- title: options.title,
10606
- type,
10607
- ...fieldsOf2(options),
10608
- ...options.due === void 0 || options.due === "none" ? {} : { dueAt: options.due },
10609
- ...options.status === void 0 ? {} : { status: options.status },
10610
- ...options.agent === void 0 ? {} : { agent: options.agent }
10611
- }, authorOf(env));
10612
- await assignAll(store, env, task.id, options.assignee);
10613
- return store.tasks.details(task.id);
10614
- }, "addToProject");
10615
- var folderOf = /* @__PURE__ */ __name(async (store, source) => {
10616
- const folderId = (await store.notes.resolveNote(source.trim()))?.folderId;
10617
- if (folderId == null)
10618
- return void 0;
10619
- const folder = (await store.accounts.storedAccounts()).find(({ id }) => String(id) === folderId);
10620
- return folder && { provider: folder.provider, account: folder.account };
10621
- }, "folderOf");
10622
- var addFromSource = /* @__PURE__ */ __name(async (store, env, source, options) => {
10623
- if (options.due !== void 0 || options.status !== void 0 || options.agent !== void 0)
10624
- throw new CliError("validation_error", "--due, --status and --agent are for a task in a project");
10625
- if (options.project !== void 0)
10626
- throw new CliError("validation_error", "a task from a source goes in its account; --project is for one without");
10627
- const type = options.type ?? "request";
10628
- if (WORK_TASK_TYPES.includes(type))
10629
- throw new CliError("validation_error", "a bug, feature or chore has no source: give --project and --title");
10630
- const native = isNoteReference(source.trim());
10631
- const parsed = native ? void 0 : parseLocator(source);
10632
- if (parsed && (options.provider && options.provider !== parsed.provider || options.account && options.account !== parsed.account))
10633
- throw new CliError("validation_error", "locator and selected account disagree");
10634
- const key = parsed ? { provider: parsed.provider, account: parsed.account } : (options.provider === void 0 ? await folderOf(store, source) : void 0) ?? await selectAccount(store, options);
10635
- if (parsed && parsed.provider !== "notes" && await heldMessage(store, key, parsed.message, parsed.chat) === void 0)
10636
- throw new CliError("not_found", "the task source is unavailable or deleted");
10637
- const author = authorOf(env);
10638
- const answer = await tasksService(storeOnlyDeps(store, key, { app: APP, env })).add(source, type, author === "owner" ? "owner" : "agent", void 0, {
10639
- ...options.into === void 0 ? {} : { attach: options.into },
10640
- ...options.new ? { new: true } : {}
10641
- }, author);
10642
- const fields = fieldsOf2(options);
10643
- if (Object.keys(fields).length === 0 && !options.assignee?.length)
10644
- return answer;
10645
- await store.tasks.edit(answer.task.id, fields, "owner");
10646
- await assignAll(store, env, answer.task.id, options.assignee);
10647
- return { ...answer, details: await store.tasks.details(answer.task.id) };
10648
- }, "addFromSource");
10649
- var addTask = /* @__PURE__ */ __name(async (store, env, source, options) => {
10650
- if (source === void 0)
10651
- return addToProject(store, env, options);
10652
- await refuseBareNumber(store, source, ["note", "document"]);
10653
- return addFromSource(store, env, source, options);
10654
- }, "addTask");
10655
- var checkOf = /* @__PURE__ */ __name((revision) => revision === void 0 ? {} : { revision }, "checkOf");
10656
- var closeTask = /* @__PURE__ */ __name(async (store, env, id, options) => {
10657
- if (await store.tasks.get(id) === void 0) {
10658
- const reason = options.reason === void 0 ? {} : { reason: options.reason };
10659
- return store.tasks.edit(id, { status: options.as, ...reason }, authorOf(env), checkOf(options.revision));
10660
- }
10661
- if (options.revision !== void 0)
10662
- throw new CliError("validation_error", "--revision checks a project task; a task from a message has none");
10663
- const key = await selectAccount(store, options);
10664
- return tasksService(storeOnlyDeps(store, key, { app: APP, env })).close(id, {
10665
- as: options.as,
10666
- by: "owner",
10667
- ...options.reason === void 0 ? {} : { reason: options.reason }
10668
- });
10669
- }, "closeTask");
10670
- var updateTask = /* @__PURE__ */ __name(async (store, env, id, options) => {
10671
- const fields = fieldsOf2(options);
10672
- const times = {
10673
- ...options.due === void 0 ? {} : { dueAt: options.due },
10674
- ...options.remindTime === void 0 ? {} : { nextCheckAt: options.remindTime }
10675
- };
10676
- if (Object.keys(fields).length + Object.keys(times).length === 0 && options.category === void 0 && options.assignee === void 0 && options.status === void 0 && options.agent === void 0 && options.project === void 0 && options.type === void 0)
10677
- throw new CliError("validation_error", "give --title, --description, --priority, --parent, --due, --remind-time, --category, --assignee, --status, --agent, --project or --type");
10678
- if (await store.tasks.get(id) === void 0) {
10679
- if (options.category !== void 0 || options.assignee !== void 0)
10680
- throw new CliError("validation_error", "--category and --assignee are for a task from a source; name a project task's people with tasks assign");
10681
- return store.tasks.edit(id, {
10682
- ...fields,
10683
- ...times,
10684
- ...options.status === void 0 ? {} : { status: options.status },
10685
- ...options.agent === void 0 ? {} : { agent: options.agent === "none" ? null : options.agent },
10686
- ...options.project === void 0 ? {} : { project: await canonicalProject(store, options.project) },
10687
- ...options.type === void 0 ? {} : { type: options.type }
10688
- }, authorOf(env), checkOf(options.revision));
10689
- }
10690
- if (options.status !== void 0 || options.agent !== void 0 || options.revision !== void 0 || options.project !== void 0 || options.type !== void 0)
10691
- throw new CliError("validation_error", "--status, --agent, --revision, --project and --type are for a project task; close a task from a message with tasks close");
10692
- if (options.priority !== void 0 || options.parent !== void 0)
10693
- throw new CliError("validation_error", "--priority and --parent are for a task in a project");
10694
- const assignees = options.assignee?.map((one2) => one2 === "sender" || one2 === "none" ? one2 : personRef(one2));
10695
- const key = await selectAccount(store, options);
10696
- return tasksService(storeOnlyDeps(store, key, { app: APP, env })).plan(id, {
10697
- ...options.title === void 0 ? {} : { title: options.title },
10698
- ...options.description === void 0 ? {} : { description: options.description },
10699
- ...times,
10700
- ...options.category === void 0 ? {} : { category: options.category },
10701
- ...assignees === void 0 ? {} : { assignees: assignees.length === 1 && assignees[0] === "none" ? null : assignees }
10702
- }, authorOf(env) === "owner" ? "owner" : "agent");
10703
- }, "updateTask");
10704
- var assignTask = /* @__PURE__ */ __name((store, env, id, person, role, revision) => store.tasks.assign(id, { to: personRef(person), role }, authorOf(env), checkOf(revision)), "assignTask");
10705
- var unassignTask = /* @__PURE__ */ __name((store, env, id, person, role, revision) => store.tasks.unassign(id, { to: personRef(person), role }, authorOf(env), checkOf(revision)), "unassignTask");
10706
- var moveTask = /* @__PURE__ */ __name((store, env, id, options) => {
10707
- const { revision, ...move } = options;
10708
- return store.tasks.move(id, move, authorOf(env), checkOf(revision));
10709
- }, "moveTask");
10710
- var commentTask = /* @__PURE__ */ __name((store, env, id, text3) => store.tasks.comment(id, text3, authorOf(env)), "commentTask");
10711
- var taskHistory = /* @__PURE__ */ __name(async (store, id) => {
10712
- const owner = (await store.people.owner())?.uid;
10713
- return (await store.tasks.events(id)).map((event) => ({
10714
- at: event.at,
10715
- kind: event.kind,
10716
- by: event.actor && {
10717
- ref: `${event.actor.type}:${event.actor.id}`,
10718
- name: event.actor.name,
10719
- owner: event.actor.type === "person" && String(event.actor.id) === String(owner)
10720
- },
10721
- changes: event.changes
10722
- }));
10723
- }, "taskHistory");
10724
-
10725
- // dist/review/kinds.js
10726
- var ownerOnly = /* @__PURE__ */ __name((row, source) => Object.assign(row, { source, ownerOnly: true }), "ownerOnly");
10727
- var wanted = /* @__PURE__ */ __name((row, filter) => ((filter.status ?? "proposed") === "all" || row.status === (filter.status ?? "proposed")) && (filter.project === void 0 || row.project === filter.project), "wanted");
10728
- var storedActions = /* @__PURE__ */ __name((store, kind, filter) => store.proposedActions.list({
10729
- kinds: [kind],
10730
- ...(filter.status ?? "proposed") === "proposed" ? { status: "proposed" } : {},
10731
- ...filter.by === void 0 ? {} : { proposedBy: filter.by },
10732
- limit: Math.min(filter.offset + filter.limit, 500)
10733
- }), "storedActions");
10734
- var accountName2 = /* @__PURE__ */ __name((action) => action.account === null ? null : `${action.account.provider}:${action.account.account}`, "accountName");
10735
- var meetingRow = /* @__PURE__ */ __name((action, batch) => {
10736
- const findings = batch.input.findings;
10737
- const projects = [...new Set(findings.map((one2) => "project" in one2 ? one2.project : void 0))];
10738
- const outcome = /* @__PURE__ */ __name((id) => batch.receipt?.items.find((item) => item.id === id)?.status ?? null, "outcome");
10739
- const references = [...new Set(findings.flatMap((finding) => finding.evidence.map((one2) => one2.reference)))];
10740
- return ownerOnly({
10741
- id: action.id,
10742
- kind: "meeting_findings",
10743
- status: batch.status === "proposed" ? "proposed" : batch.receipt?.accepted.length ? "confirmed" : "rejected",
10744
- project: projects.length === 1 && typeof projects[0] === "string" ? projects[0] : null,
10745
- subject: references[0] ?? `meeting_findings:${action.id}`,
10746
- object: null,
10747
- summary: `${findings.length} finding${findings.length === 1 ? "" : "s"}`,
10748
- proposedBy: proposerOfAction(action),
10749
- reason: action.reason,
10750
- evidence: references.slice(0, 5),
10751
- score: null,
10752
- signals: null,
10753
- parts: findings.map((finding) => ({
10754
- id: finding.id,
10755
- kind: finding.kind,
10756
- summary: FACT_SUMMARIES[finding.kind]?.(finding) ?? finding.kind,
10757
- outcome: outcome(finding.id)
10758
- })),
10759
- createdAt: action.createdAt
10760
- }, accountName2(action));
10761
- }, "meetingRow");
10762
- var meetingFindingsKind = /* @__PURE__ */ __name((store) => {
10763
- const batchOf2 = /* @__PURE__ */ __name(async (action) => {
10764
- if (action.account === null)
10765
- throw new CliError("not_found", `meeting findings ${action.id} name no account`);
10766
- return { account: action.account, batch: await store.meetingFindings.get(action.account, action.id) };
10767
- }, "batchOf");
10768
- return {
10769
- kind: "meeting_findings",
10770
- stored: [MEETING_FINDINGS_KIND],
10771
- parts: true,
10772
- list: /* @__PURE__ */ __name(async (filter) => {
10773
- const rows = [];
10774
- for (const action of await storedActions(store, MEETING_FINDINGS_KIND, filter)) {
10775
- const { batch } = await batchOf2(action);
10776
- rows.push(meetingRow(action, batch));
10777
- }
10778
- return rows.filter((row) => wanted(row, filter)).slice(0, filter.offset + filter.limit);
10779
- }, "list"),
10780
- get: /* @__PURE__ */ __name(async (id) => {
10781
- const action = await store.proposedActions.get(id);
10782
- return meetingRow(action, (await batchOf2(action)).batch);
10783
- }, "get"),
10784
- decide: /* @__PURE__ */ __name(async (id, { confirm, by, parts }) => {
10785
- const { account: account2, batch } = await batchOf2(await store.proposedActions.get(id));
10786
- const turnedDown = new Set(batch.previous.filter((one2) => one2.status === "rejected").map((one2) => one2.id));
10787
- const accept = !confirm ? [] : parts ?? batch.input.findings.map((finding) => finding.id).filter((one2) => !turnedDown.has(one2));
10788
- const reviewed = await store.meetingFindings.review(account2, id, { fingerprint: batch.fingerprint, accept, by });
10789
- const made = (reviewed.receipt?.items ?? []).flatMap((item) => item.status === "accepted" && item.reference && !item.reused ? [item.reference] : []);
10790
- return { id, kind: "meeting_findings", status: accept.length ? "confirmed" : "rejected", made };
10791
- }, "decide")
10792
- };
10793
- }, "meetingFindingsKind");
10794
- var accountOfSource = /* @__PURE__ */ __name((source) => {
10795
- const match = /^msg:([a-z][a-z0-9-]*)\/([^/]+)\//.exec(source ?? "");
10796
- return match?.[1] && match[2] ? { provider: match[1], account: decodeURIComponent(match[2]) } : {};
10797
- }, "accountOfSource");
10798
- var closeRow = /* @__PURE__ */ __name((task) => {
10799
- const suggestion = task.closeSuggestion;
10800
- if (suggestion === null)
10801
- return void 0;
10802
- return ownerOnly({
10803
- id: `close:${task.key}`,
10804
- kind: "task_close",
10805
- status: "proposed",
10806
- project: task.project,
10807
- subject: task.ref,
10808
- object: null,
10809
- summary: `close as ${suggestion.as}: ${task.title}`,
10810
- proposedBy: { type: "bot", id: suggestion.by, name: suggestion.by, kind: "agent" },
10811
- reason: suggestion.reason,
10812
- evidence: task.source === null ? [] : [task.source],
10813
- score: suggestion.certainty,
10814
- signals: null,
10815
- parts: null,
10816
- createdAt: suggestion.at
10817
- }, task.project);
10818
- }, "closeRow");
10819
- var taskCloseKind = /* @__PURE__ */ __name((store, env) => {
10820
- const suggested = /* @__PURE__ */ __name(async (limit) => store.tasks.find({
10821
- status: "open",
10822
- where: { sql: "t.close_suggested_as IS NOT NULL", params: [] },
10823
- limit
10824
- }), "suggested");
10825
- const taskOf = /* @__PURE__ */ __name(async (id) => {
10826
- const key = id.slice("close:".length);
10827
- const task = await store.tasks.details(key).catch(() => void 0);
10828
- const row = task && closeRow(task);
10829
- if (!task || !row)
10830
- throw new CliError("not_found", `no close waits on task ${key}`);
10831
- return { task, row };
10832
- }, "taskOf");
10833
- return {
10834
- kind: "task_close",
10835
- prefix: "close",
10836
- list: /* @__PURE__ */ __name(async (filter) => {
10837
- if ((filter.status ?? "proposed") !== "proposed" && filter.status !== "all")
10838
- return [];
10839
- const rows = (await suggested(filter.offset + filter.limit)).flatMap((task) => closeRow(task) ?? []);
10840
- const by = filter.by;
10841
- return rows.filter((row) => wanted(row, filter)).filter((row) => by === void 0 || by === "agent" || typeof by === "object" && row.proposedBy.type === "bot" && row.proposedBy.name === by.bot).sort((a, b) => b.createdAt.localeCompare(a.createdAt));
10842
- }, "list"),
10843
- get: /* @__PURE__ */ __name(async (id) => (await taskOf(id)).row, "get"),
10844
- decide: /* @__PURE__ */ __name(async (id, { confirm, reason }) => {
10845
- const { task } = await taskOf(id);
10846
- const suggestion = task.closeSuggestion;
10847
- if (!confirm || suggestion === null) {
10848
- await store.tasks.suggestClose(task.id, null, "owner");
10849
- return { id, kind: "task_close", status: "rejected", made: [] };
10850
- }
10851
- await closeTask(store, env, task.id, {
10852
- ...accountOfSource(task.source),
10853
- as: suggestion.as,
10854
- ...reason === void 0 ? {} : { reason }
10855
- });
10856
- return { id, kind: "task_close", status: "confirmed", made: [task.ref] };
10857
- }, "decide")
10858
- };
10859
- }, "taskCloseKind");
10860
- var REVIEW_KINDS = [
10861
- "relationship",
10862
- "relationship_update",
10863
- "key_document",
10864
- "fact",
10865
- "memory",
10866
- "findings",
10867
- "meeting_findings",
10868
- MAIL_FINDINGS_KIND,
10869
- "task_close",
10870
- "action",
10871
- "invoice",
10872
- "payment"
10873
- ];
10874
- var reviewRegistry = /* @__PURE__ */ __name((store, env) => {
10875
- const registry = proposalRegistry(store);
10876
- for (const kind of [meetingFindingsKind(store), taskCloseKind(store, env)])
10877
- try {
10878
- registry.register(kind);
10879
- } catch (error) {
10880
- if (!(error instanceof CliError) || error.code !== "configuration_error")
10881
- throw error;
10882
- }
10883
- const marked = /* @__PURE__ */ __name(async (row) => row.kind === MAIL_FINDINGS_KIND && row.source == null ? ownerOnly(row, accountName2(await store.proposedActions.get(row.id))) : row, "marked");
10884
- return {
10885
- ...registry,
10886
- list: /* @__PURE__ */ __name(async (filter) => {
10887
- const found = await registry.list(filter);
10888
- return { ...found, items: await Promise.all(found.items.map(marked)) };
10889
- }, "list"),
10890
- get: /* @__PURE__ */ __name(async (id) => marked(await registry.get(id)), "get")
10891
- };
10892
- }, "reviewRegistry");
10893
-
10894
- // node_modules/.pnpm/@wirecat+cli-core@0.567.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_90104be51d88dd1f434885448f73ba7c/node_modules/@wirecat/cli-core/dist/mail/account-key.js
10895
- var mailAccountKey = /* @__PURE__ */ __name((address) => ({ provider: "email", account: address.toLowerCase() }), "mailAccountKey");
10896
-
10897
- // node_modules/.pnpm/@wirecat+cli-core@0.567.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_90104be51d88dd1f434885448f73ba7c/node_modules/@wirecat/cli-core/dist/mail/attachments.js
10898
- var MAX_ATTACHMENT_CHARS = 2e5;
10899
- var DEFAULT_ATTACHMENT_POLICY = { read: true, maxBytes: 10 * 1024 * 1024 };
10900
- var POLICY_SKIPS = ["not-read", "too-large"];
10901
- var addressOf = /* @__PURE__ */ __name(({ email, name }) => ({ address: email, name }), "addressOf");
10902
- var readAttachments = /* @__PURE__ */ __name(async (mail, messageId, { loadEngine, maxAttachmentChars, at, signal, policy }, log) => {
10903
- const files = [];
10904
- for (const [position, part] of mail.attachments.entries()) {
10905
- if (signal?.aborted)
10906
- throw signal.reason;
10907
- const skipped = part.bytes === null || policy === void 0 ? void 0 : !policy.read ? "not-read" : part.bytes.byteLength > policy.maxBytes ? "too-large" : void 0;
10908
- const extraction = part.bytes === null ? { status: "unavailable" } : skipped ? { status: skipped } : await extractText(part.bytes, { kind: "file", name: part.name, mime: part.mime, path: part.name }, loadEngine, signal);
10909
- log.push({ message: messageId, part: part.id, status: extraction.status });
10910
- const extracted = extraction.status === "extracted" ? extraction : void 0;
10911
- files.push({
10912
- position,
10913
- kind: "file",
10914
- mime: part.mime,
10915
- name: part.name,
10916
- title: null,
10917
- url: null,
10918
- size: part.bytes === null ? null : part.bytes.byteLength,
10919
- width: null,
10920
- height: null,
10921
- duration: null,
10922
- providerRef: { message: messageId, part: part.id },
10923
- localPath: null,
10924
- text: extracted ? extracted.text.slice(0, maxAttachmentChars) : null,
10925
- normalizedText: null,
10926
- extraction: extracted ? "text" : "failed",
10927
- extractor: extracted ? extracted.extractor : null,
10928
- extractionError: extracted ? null : extraction.status,
10929
- contentSha256: null,
10930
- extractedAt: at
10931
- });
10932
- }
10933
- return files;
10934
- }, "readAttachments");
10935
-
10936
- // node_modules/.pnpm/@wirecat+cli-core@0.567.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_90104be51d88dd1f434885448f73ba7c/node_modules/@wirecat/cli-core/dist/mail/bulk.js
10937
- var BULK = "bulk";
10938
- var bulkBox = { externalId: "memo:bulk", name: "bulk", kind: BULK };
10939
-
10940
- // node_modules/.pnpm/@wirecat+cli-core@0.567.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_90104be51d88dd1f434885448f73ba7c/node_modules/@wirecat/cli-core/dist/mail/score.js
10471
+ // node_modules/.pnpm/@wirecat+cli-core@0.569.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_8785fed449bbc2a6b34fc086f24a8413/node_modules/@wirecat/cli-core/dist/mail/score.js
10941
10472
  var import_disposable_email_domains_js = __toESM(require_dist(), 1);
10942
10473
  var import_tldts = __toESM(require_cjs(), 1);
10943
10474
  var WEIGHTS = {
@@ -11045,7 +10576,7 @@ var scoreGroup = /* @__PURE__ */ __name((items, context) => {
11045
10576
  return { score: kept.reduce((sum, signal) => sum + WEIGHTS[signal], 0), signals: kept };
11046
10577
  }, "scoreGroup");
11047
10578
 
11048
- // node_modules/.pnpm/@wirecat+cli-core@0.567.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_90104be51d88dd1f434885448f73ba7c/node_modules/@wirecat/cli-core/dist/mail/presets.js
10579
+ // node_modules/.pnpm/@wirecat+cli-core@0.569.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_8785fed449bbc2a6b34fc086f24a8413/node_modules/@wirecat/cli-core/dist/mail/presets.js
11049
10580
  var PRESETS = {
11050
10581
  social: {
11051
10582
  about: "notifications from social networks",
@@ -11137,7 +10668,7 @@ var presetMatches = /* @__PURE__ */ __name((name, facts) => {
11137
10668
  return false;
11138
10669
  }, "presetMatches");
11139
10670
 
11140
- // node_modules/.pnpm/@wirecat+cli-core@0.567.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_90104be51d88dd1f434885448f73ba7c/node_modules/@wirecat/cli-core/dist/mail/probe.js
10671
+ // node_modules/.pnpm/@wirecat+cli-core@0.569.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_8785fed449bbc2a6b34fc086f24a8413/node_modules/@wirecat/cli-core/dist/mail/probe.js
11141
10672
  var share = /* @__PURE__ */ __name((part, whole2) => Math.round(part / whole2 * 100) / 100, "share");
11142
10673
  var isSent = /* @__PURE__ */ __name((item) => item.labels?.includes("Sent") || /(^|\/)sent\b/i.test(item.folder ?? ""), "isSent");
11143
10674
  var groupKey = /* @__PURE__ */ __name((headers) => headers.listId === void 0 ? `from:${headers.from}` : `list:${headers.listId}`, "groupKey");
@@ -11205,7 +10736,7 @@ var probeMail = /* @__PURE__ */ __name((items, limit, ages = /* @__PURE__ */ new
11205
10736
  };
11206
10737
  }, "probeMail");
11207
10738
 
11208
- // node_modules/.pnpm/@wirecat+cli-core@0.567.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_90104be51d88dd1f434885448f73ba7c/node_modules/@wirecat/cli-core/dist/mail/facts.js
10739
+ // node_modules/.pnpm/@wirecat+cli-core@0.569.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_8785fed449bbc2a6b34fc086f24a8413/node_modules/@wirecat/cli-core/dist/mail/facts.js
11209
10740
  var factsOf = /* @__PURE__ */ __name((listed, rules, ages = /* @__PURE__ */ new Map()) => {
11210
10741
  const grouped = rules.some(({ match }) => match.score_at_least !== void 0 || match.preset !== void 0);
11211
10742
  if (!grouped)
@@ -16476,12 +16007,12 @@ var PostalMime = class _PostalMime {
16476
16007
  }
16477
16008
  };
16478
16009
 
16479
- // node_modules/.pnpm/@wirecat+cli-core@0.567.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_90104be51d88dd1f434885448f73ba7c/node_modules/@wirecat/cli-core/dist/mail/headers.js
16010
+ // node_modules/.pnpm/@wirecat+cli-core@0.569.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_8785fed449bbc2a6b34fc086f24a8413/node_modules/@wirecat/cli-core/dist/mail/headers.js
16480
16011
  var unfold = /* @__PURE__ */ __name((text3) => text3.replace(/\r?\n[ \t]+/g, " "), "unfold");
16481
16012
  var field = /* @__PURE__ */ __name((unfolded, name) => new RegExp(`^${name}:[ \\t]*(.*?)\\r?$`, "im").exec(unfolded)?.[1], "field");
16482
- var fieldsOf3 = /* @__PURE__ */ __name((unfolded, name) => [...unfolded.matchAll(new RegExp(`^${name}:[ \\t]*(.*?)\\r?$`, "gim"))].map(([, value]) => value), "fieldsOf");
16013
+ var fieldsOf2 = /* @__PURE__ */ __name((unfolded, name) => [...unfolded.matchAll(new RegExp(`^${name}:[ \\t]*(.*?)\\r?$`, "gim"))].map(([, value]) => value), "fieldsOf");
16483
16014
  var authOf = /* @__PURE__ */ __name((unfolded) => {
16484
- const stamped = fieldsOf3(unfolded, "Authentication-Results").find((value) => /^mx\.google\.com\s*;/i.test(value));
16015
+ const stamped = fieldsOf2(unfolded, "Authentication-Results").find((value) => /^mx\.google\.com\s*;/i.test(value));
16485
16016
  if (stamped === void 0)
16486
16017
  return void 0;
16487
16018
  const results = [...stamped.matchAll(/\b(spf|dkim|dmarc)=([a-z]+)/gi)].map(([, method, result]) => [
@@ -16523,7 +16054,7 @@ var mailHeadersOf = /* @__PURE__ */ __name((raw) => {
16523
16054
  };
16524
16055
  }, "mailHeadersOf");
16525
16056
 
16526
- // node_modules/.pnpm/@wirecat+cli-core@0.567.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_90104be51d88dd1f434885448f73ba7c/node_modules/@wirecat/cli-core/dist/mail/parse.js
16057
+ // node_modules/.pnpm/@wirecat+cli-core@0.569.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_8785fed449bbc2a6b34fc086f24a8413/node_modules/@wirecat/cli-core/dist/mail/parse.js
16527
16058
  var MAX_BODY_CHARS = 1e6;
16528
16059
  var MAX_ATTACHMENTS = 50;
16529
16060
  var BRACKETED_ID = /<[^<>\s]+>/g;
@@ -16588,7 +16119,7 @@ var parseMail = /* @__PURE__ */ __name(async (raw, maxBodyChars = MAX_BODY_CHARS
16588
16119
  };
16589
16120
  }, "parseMail");
16590
16121
 
16591
- // node_modules/.pnpm/@wirecat+cli-core@0.567.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_90104be51d88dd1f434885448f73ba7c/node_modules/@wirecat/cli-core/dist/mail/email-input.js
16122
+ // node_modules/.pnpm/@wirecat+cli-core@0.569.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_8785fed449bbc2a6b34fc086f24a8413/node_modules/@wirecat/cli-core/dist/mail/email-input.js
16592
16123
  var sentAtOf = /* @__PURE__ */ __name((date, receivedAt) => {
16593
16124
  const sent = date === null ? Number.NaN : Date.parse(date);
16594
16125
  return Number.isNaN(sent) ? Date.parse(receivedAt) : sent;
@@ -16608,10 +16139,10 @@ var parsedEmail = /* @__PURE__ */ __name((mail, item, header, address) => ({
16608
16139
  outgoing: mail.from === null ? null : mail.from.email === address
16609
16140
  }), "parsedEmail");
16610
16141
 
16611
- // node_modules/.pnpm/@wirecat+cli-core@0.567.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_90104be51d88dd1f434885448f73ba7c/node_modules/@wirecat/cli-core/dist/mail/partial.js
16142
+ // node_modules/.pnpm/@wirecat+cli-core@0.569.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_8785fed449bbc2a6b34fc086f24a8413/node_modules/@wirecat/cli-core/dist/mail/partial.js
16612
16143
  var PARTIAL = "partial";
16613
16144
 
16614
- // node_modules/.pnpm/@wirecat+cli-core@0.567.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_90104be51d88dd1f434885448f73ba7c/node_modules/@wirecat/cli-core/dist/mail/read.js
16145
+ // node_modules/.pnpm/@wirecat+cli-core@0.569.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_8785fed449bbc2a6b34fc086f24a8413/node_modules/@wirecat/cli-core/dist/mail/read.js
16615
16146
  var lowerSuspicious = /* @__PURE__ */ __name((items, suspicious) => [
16616
16147
  ...items.filter((item) => !suspicious(item)),
16617
16148
  ...items.filter(suspicious)
@@ -16698,7 +16229,7 @@ var attachmentsText = /* @__PURE__ */ __name((hit) => (hit.attachments ?? []).ma
16698
16229
  ${file.text.replace(/\n/g, "\n ")}`;
16699
16230
  }).join("\n"), "attachmentsText");
16700
16231
 
16701
- // node_modules/.pnpm/@wirecat+cli-core@0.567.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_90104be51d88dd1f434885448f73ba7c/node_modules/@wirecat/cli-core/dist/mail/review.js
16232
+ // node_modules/.pnpm/@wirecat+cli-core@0.569.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_8785fed449bbc2a6b34fc086f24a8413/node_modules/@wirecat/cli-core/dist/mail/review.js
16702
16233
  var REVIEW_THREADS = 50;
16703
16234
  var REVIEW_PER_THREAD = 50;
16704
16235
  var OWED_DAYS = 30;
@@ -16722,7 +16253,7 @@ var syncedThrough = /* @__PURE__ */ __name(async (store, mailbox) => {
16722
16253
  return { until: void 0, complete: false };
16723
16254
  }
16724
16255
  }, "syncedThrough");
16725
- var wanted2 = /* @__PURE__ */ __name((thread, { noBulk, unansweredAfterHours, waitingAfterHours }, now) => {
16256
+ var wanted = /* @__PURE__ */ __name((thread, { noBulk, unansweredAfterHours, waitingAfterHours }, now) => {
16726
16257
  const newest2 = thread.newest;
16727
16258
  if (unansweredAfterHours !== void 0 || waitingAfterHours !== void 0) {
16728
16259
  const turn = mailTurn(newest2);
@@ -16747,7 +16278,7 @@ var reviewMail = /* @__PURE__ */ __name(async (store, mailbox, options) => {
16747
16278
  const startOf = /* @__PURE__ */ __name((thread) => points?.get(thread) ?? since, "startOf");
16748
16279
  const activity = account2 ? await store.mail.threadActivity(account2.id, since - DATED_SLACK) : [];
16749
16280
  const changed = activity.filter((thread) => Math.max(thread.lastEmailAt, thread.newest?.at ?? 0) > startOf(thread.threadId));
16750
- const picked = changed.map((thread) => ({ thread, as: wanted2(thread, options, now) }));
16281
+ const picked = changed.map((thread) => ({ thread, as: wanted(thread, options, now) }));
16751
16282
  const shown = picked.filter(({ as }) => as === "read").map(({ thread }) => thread);
16752
16283
  const read = shown.slice(0, REVIEW_THREADS);
16753
16284
  const skipped = shown.slice(REVIEW_THREADS).map(({ threadId, subject, lastEmailAt }) => ({
@@ -16796,14 +16327,14 @@ var reviewMail = /* @__PURE__ */ __name(async (store, mailbox, options) => {
16796
16327
  };
16797
16328
  }, "reviewMail");
16798
16329
 
16799
- // node_modules/.pnpm/@wirecat+cli-core@0.567.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_90104be51d88dd1f434885448f73ba7c/node_modules/@wirecat/cli-core/dist/mail/rules.js
16330
+ // node_modules/.pnpm/@wirecat+cli-core@0.569.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_8785fed449bbc2a6b34fc086f24a8413/node_modules/@wirecat/cli-core/dist/mail/rules.js
16800
16331
  var DAY_MS2 = 24 * 60 * 60 * 1e3;
16801
16332
  var domainOf = /* @__PURE__ */ __name((address) => address.slice(address.lastIndexOf("@") + 1), "domainOf");
16802
- var domainMatches = /* @__PURE__ */ __name((wanted3, sender) => {
16333
+ var domainMatches = /* @__PURE__ */ __name((wanted2, sender) => {
16803
16334
  if (sender === void 0)
16804
16335
  return false;
16805
16336
  const host = domainOf(sender);
16806
- const domain = wanted3.toLowerCase();
16337
+ const domain = wanted2.toLowerCase();
16807
16338
  return host === domain || host.endsWith(`.${domain}`);
16808
16339
  }, "domainMatches");
16809
16340
  var words = /* @__PURE__ */ __name((text3) => text3.toLowerCase().split(/\s+/).filter(Boolean), "words");
@@ -16868,7 +16399,7 @@ var tagsOf = /* @__PURE__ */ __name((rules, facts) => {
16868
16399
  }, "tagsOf");
16869
16400
  var conditionKeys = /* @__PURE__ */ __name((match) => Object.keys(match).filter((key) => match[key] !== void 0).sort(), "conditionKeys");
16870
16401
 
16871
- // node_modules/.pnpm/@wirecat+cli-core@0.567.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_90104be51d88dd1f434885448f73ba7c/node_modules/@wirecat/cli-core/dist/mail/rule-input.js
16402
+ // node_modules/.pnpm/@wirecat+cli-core@0.569.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_8785fed449bbc2a6b34fc086f24a8413/node_modules/@wirecat/cli-core/dist/mail/rule-input.js
16872
16403
  var STORE_ACTION = { keep: "full", envelope: "envelope", skip: "skip" };
16873
16404
  var LOWER = ["from", "domain", "list_id", "subject"];
16874
16405
  var conditionsOf = /* @__PURE__ */ __name((match) => Object.fromEntries(conditionKeys(match).map((key) => {
@@ -16898,7 +16429,7 @@ var ruleInput = /* @__PURE__ */ __name((rule, source = rule.source ?? "owner") =
16898
16429
  decidedAt: decidedAtOf(rule.decided_at)
16899
16430
  }), "ruleInput");
16900
16431
 
16901
- // node_modules/.pnpm/@wirecat+cli-core@0.567.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_90104be51d88dd1f434885448f73ba7c/node_modules/@wirecat/cli-core/dist/mail/rule-stored.js
16432
+ // node_modules/.pnpm/@wirecat+cli-core@0.569.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_8785fed449bbc2a6b34fc086f24a8413/node_modules/@wirecat/cli-core/dist/mail/rule-stored.js
16902
16433
  var ACTION_OF = { full: "keep", envelope: "envelope", skip: "skip" };
16903
16434
  var KINDS = {
16904
16435
  from: "string",
@@ -16967,7 +16498,7 @@ var storedMailRuleSet = /* @__PURE__ */ __name(async (store, account2, query) =>
16967
16498
  }, "storedMailRuleSet");
16968
16499
  var storedMailRules = /* @__PURE__ */ __name(async (store, account2, query) => (await storedMailRuleSet(store, account2, query)).rules, "storedMailRules");
16969
16500
 
16970
- // node_modules/.pnpm/@wirecat+cli-core@0.567.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_90104be51d88dd1f434885448f73ba7c/node_modules/@wirecat/cli-core/dist/mail/rule-tags.js
16501
+ // node_modules/.pnpm/@wirecat+cli-core@0.569.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_8785fed449bbc2a6b34fc086f24a8413/node_modules/@wirecat/cli-core/dist/mail/rule-tags.js
16971
16502
  var reuseOf = /* @__PURE__ */ __name((error) => {
16972
16503
  const { details } = error;
16973
16504
  return details?.reason === "tag-review.required" ? details.candidates?.[0]?.name : void 0;
@@ -17028,7 +16559,7 @@ var settleRuleTags = /* @__PURE__ */ __name(async (store, accountId, rules, outc
17028
16559
  }
17029
16560
  }, "settleRuleTags");
17030
16561
 
17031
- // node_modules/.pnpm/@wirecat+cli-core@0.567.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_90104be51d88dd1f434885448f73ba7c/node_modules/@wirecat/cli-core/dist/mail/sender-scores.js
16562
+ // node_modules/.pnpm/@wirecat+cli-core@0.569.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_8785fed449bbc2a6b34fc086f24a8413/node_modules/@wirecat/cli-core/dist/mail/sender-scores.js
17032
16563
  var SCORED = "mail_sender_scores";
17033
16564
  var DAY = 864e5;
17034
16565
  var RECENT = 2 * 365 * DAY;
@@ -17044,7 +16575,7 @@ var demotedSenders = /* @__PURE__ */ __name(async (store) => {
17044
16575
  return senders;
17045
16576
  }, "demotedSenders");
17046
16577
 
17047
- // node_modules/.pnpm/@wirecat+cli-core@0.567.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_90104be51d88dd1f434885448f73ba7c/node_modules/@wirecat/cli-core/dist/mail/server-query.js
16578
+ // node_modules/.pnpm/@wirecat+cli-core@0.569.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_8785fed449bbc2a6b34fc086f24a8413/node_modules/@wirecat/cli-core/dist/mail/server-query.js
17048
16579
  var DAY2 = 864e5;
17049
16580
  var empty = /* @__PURE__ */ __name(() => ({ words: [], from: [], to: [], cc: [], subject: [], body: [] }), "empty");
17050
16581
  var narrows = /* @__PURE__ */ __name((criteria) => criteria.words.length + criteria.from.length + criteria.to.length + criteria.cc.length + criteria.subject.length + criteria.body.length > 0 || criteria.since !== void 0 || criteria.before !== void 0 || criteria.seen !== void 0 || criteria.flagged !== void 0, "narrows");
@@ -17117,7 +16648,7 @@ var mailCriteriaOf = /* @__PURE__ */ __name((text3, { exact, timezone } = {}) =>
17117
16648
  };
17118
16649
  }, "mailCriteriaOf");
17119
16650
 
17120
- // node_modules/.pnpm/@wirecat+cli-core@0.567.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_90104be51d88dd1f434885448f73ba7c/node_modules/@wirecat/cli-core/dist/mail/server-search.js
16651
+ // node_modules/.pnpm/@wirecat+cli-core@0.569.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_8785fed449bbc2a6b34fc086f24a8413/node_modules/@wirecat/cli-core/dist/mail/server-search.js
17121
16652
  var refusal = {
17122
16653
  unsupported: "this mailbox's server cannot be searched \u2014 use --backend archive",
17123
16654
  offline: "--backend server needs the network \u2014 not with --offline",
@@ -17332,10 +16863,61 @@ var searchMailServer = /* @__PURE__ */ __name(async (store, mailbox, access, req
17332
16863
  return { report, sources };
17333
16864
  }, "searchMailServer");
17334
16865
 
17335
- // node_modules/.pnpm/@wirecat+cli-core@0.567.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_90104be51d88dd1f434885448f73ba7c/node_modules/@wirecat/cli-core/dist/mail/sync.js
16866
+ // node_modules/.pnpm/@wirecat+cli-core@0.569.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_8785fed449bbc2a6b34fc086f24a8413/node_modules/@wirecat/cli-core/dist/mail/sync.js
17336
16867
  var DAY3 = 864e5;
17337
16868
  var EDGE = 2 * DAY3;
17338
16869
 
16870
+ // dist/vocabulary/project.js
16871
+ var canonicalProject = /* @__PURE__ */ __name(async (store, reference3, limits = {}) => {
16872
+ if (/^project:[1-9]\d*$/.test(reference3)) {
16873
+ const catalog = await store.knowledge.vocabulary({ kind: "project", ...limits });
16874
+ if (!catalog.entries.some((entry2) => entry2.id === reference3.slice(8)))
16875
+ throw new CliError("not_found", "the owner project is unavailable");
16876
+ return reference3;
16877
+ }
16878
+ const found = await store.knowledge.resolveVocabulary(reference3, { kind: "project", ...limits });
16879
+ if (found.matches.length !== 1)
16880
+ throw new CliError(found.matches.length ? "validation_error" : "not_found", found.matches.length ? `${reference3} names ${found.matches.length} projects; give one by its key, as memo vocabulary show ${reference3} lists them` : `no project ${reference3}; memo projects list shows yours, memo projects add creates one`, { candidates: found.matches.map((entry2) => ({ id: entry2.id, key: entry2.key, name: entry2.name })) });
16881
+ const entry = found.matches[0];
16882
+ if (!entry)
16883
+ throw new CliError("not_found", "the owner project is unavailable");
16884
+ return `project:${entry.id}`;
16885
+ }, "canonicalProject");
16886
+
16887
+ // dist/review/kinds.js
16888
+ var REVIEW_KINDS = [
16889
+ "relationship",
16890
+ "relationship_update",
16891
+ "key_document",
16892
+ "fact",
16893
+ "memory",
16894
+ "findings",
16895
+ "meeting_findings",
16896
+ MAIL_FINDINGS_KIND,
16897
+ "task_close",
16898
+ "action",
16899
+ "invoice",
16900
+ "payment"
16901
+ ];
16902
+ var BY_ACCOUNT = [MEETING_FINDINGS_KIND, MAIL_FINDINGS_KIND];
16903
+ var reviewRegistry = /* @__PURE__ */ __name((store) => {
16904
+ const registry = proposalRegistry(store);
16905
+ const sourced = /* @__PURE__ */ __name(async (row) => {
16906
+ if (!BY_ACCOUNT.includes(row.kind))
16907
+ return row;
16908
+ const { account: account2 } = await store.proposedActions.get(row.id);
16909
+ return { ...row, source: account2 === null ? null : `${account2.provider}:${account2.account}` };
16910
+ }, "sourced");
16911
+ return {
16912
+ ...registry,
16913
+ list: /* @__PURE__ */ __name(async (filter) => {
16914
+ const found = await registry.list(filter);
16915
+ return { ...found, items: await Promise.all(found.items.map(sourced)) };
16916
+ }, "list"),
16917
+ get: /* @__PURE__ */ __name(async (id) => sourced(await registry.get(id)), "get")
16918
+ };
16919
+ }, "reviewRegistry");
16920
+
17339
16921
  // dist/review/review.js
17340
16922
  var STATUSES = ["proposed", "confirmed", "rejected", "all"];
17341
16923
  var REVIEW_QUERY = {
@@ -17367,8 +16949,8 @@ var filterOf = /* @__PURE__ */ __name(async (store, words2) => {
17367
16949
  }, "filterOf");
17368
16950
  var proposerName = /* @__PURE__ */ __name((proposer) => proposer.type === "bot" ? proposer.name : proposer.type === "person" ? "you" : "unknown", "proposerName");
17369
16951
  var labelsFor = /* @__PURE__ */ __name(async (store, refs) => {
17370
- const wanted3 = [...new Set(refs.filter((ref) => typeof ref === "string" && ref !== ""))];
17371
- const summaries = wanted3.length ? await store.refs.summaries(wanted3) : /* @__PURE__ */ new Map();
16952
+ const wanted2 = [...new Set(refs.filter((ref) => typeof ref === "string" && ref !== ""))];
16953
+ const summaries = wanted2.length ? await store.refs.summaries(wanted2) : /* @__PURE__ */ new Map();
17372
16954
  return (ref) => {
17373
16955
  if (ref === null)
17374
16956
  return null;
@@ -17427,12 +17009,12 @@ var reviewItem = /* @__PURE__ */ __name((row, label) => ({
17427
17009
  var rowRefs = /* @__PURE__ */ __name((row) => [row.subject, row.object, row.project], "rowRefs");
17428
17010
  var listReview = /* @__PURE__ */ __name(async (store, env, words2, { limit, page }) => {
17429
17011
  const filter = await filterOf(store, words2);
17430
- const found = await reviewRegistry(store, env).list({ ...filter, limit, offset: (page - 1) * limit });
17012
+ const found = await reviewRegistry(store).list({ ...filter, limit, offset: (page - 1) * limit });
17431
17013
  const label = await labelsFor(store, found.items.flatMap(rowRefs));
17432
17014
  return { items: found.items.map((row) => reviewItem(row, label)), hasMore: found.hasMore };
17433
17015
  }, "listReview");
17434
17016
  var showReview = /* @__PURE__ */ __name(async (store, env, id) => {
17435
- const row = await reviewRegistry(store, env).get(id);
17017
+ const row = await reviewRegistry(store).get(id);
17436
17018
  const label = await labelsFor(store, [...rowRefs(row), ...row.evidence]);
17437
17019
  return {
17438
17020
  ...reviewItem(row, label),
@@ -17551,15 +17133,60 @@ var decideOne = /* @__PURE__ */ __name(async (store, id, decision) => {
17551
17133
 
17552
17134
  // dist/page.js
17553
17135
  var pageOf = /* @__PURE__ */ __name(async (command, limit, read, { fallback = 100, cap = 500 } = {}) => {
17554
- const wanted3 = Math.min(limit ?? fallback, cap);
17555
- const rows = await read(Math.min(wanted3 + 1, cap));
17136
+ const wanted2 = Math.min(limit ?? fallback, cap);
17137
+ const rows = await read(Math.min(wanted2 + 1, cap));
17556
17138
  return listAnswer(command, {
17557
- items: rows.slice(0, wanted3),
17558
- limit: wanted3,
17559
- has_more: rows.length > wanted3 || rows.length === cap
17139
+ items: rows.slice(0, wanted2),
17140
+ limit: wanted2,
17141
+ has_more: rows.length > wanted2 || rows.length === cap
17560
17142
  });
17561
17143
  }, "pageOf");
17562
17144
 
17145
+ // dist/store/scope.js
17146
+ var choices = /* @__PURE__ */ __name((keys) => keys.length ? `; choose one of ${keys.map(({ provider, account: account2 }) => `${provider}:${account2}`).join(", ")}` : "", "choices");
17147
+ var selectAccount = /* @__PURE__ */ __name(async (store, scope) => {
17148
+ const held = await store.accounts.accounts();
17149
+ if (!scope.provider)
17150
+ throw new CliError("validation_error", `give --account <provider>:<account>${choices(held)}`);
17151
+ const matches2 = held.filter((key) => key.provider === scope.provider && (scope.account === void 0 || key.account === scope.account));
17152
+ if (matches2.length !== 1)
17153
+ throw new CliError(matches2.length ? "validation_error" : "not_found", matches2.length ? `several accounts match; give one${choices(matches2)}` : `the store holds no ${scope.provider} account matching this selection${choices(held)}`);
17154
+ return matches2[0];
17155
+ }, "selectAccount");
17156
+ var meetingReference = /* @__PURE__ */ __name(async (store, id, scope) => {
17157
+ if (!/^\d+$/.test(id))
17158
+ throw new CliError("validation_error", "--meeting takes the meeting's id in the store");
17159
+ const account2 = await store.accounts.storedAccount(await selectAccount(store, scope));
17160
+ const found = await store.meetings.meeting(Number(id));
17161
+ if (found === null || found.meeting.accountId !== account2.id)
17162
+ throw new CliError("not_found", `the ${account2.provider} account ${account2.account} holds no meeting ${id}`);
17163
+ return `meeting:${account2.id}/${found.meeting.id}`;
17164
+ }, "meetingReference");
17165
+ var selectTarget = /* @__PURE__ */ __name(async (store, input) => {
17166
+ const choices2 = ["message", "chat", "contact", "person", "task", "organization", "project", "meeting"];
17167
+ const selected = choices2.filter((name) => input[name] !== void 0);
17168
+ if (selected.length !== 1)
17169
+ throw new CliError("validation_error", "select exactly one of --message, --chat, --contact, --person, --task, --organization, --project or --meeting");
17170
+ const type = selected[0];
17171
+ if (type === "message") {
17172
+ const locator = input.message;
17173
+ let parsed;
17174
+ try {
17175
+ parsed = parseLocator(locator);
17176
+ } catch {
17177
+ throw new CliError("validation_error", "give a valid msg: source locator");
17178
+ }
17179
+ if (input.provider && parsed.provider !== input.provider || input.account && parsed.account !== input.account)
17180
+ throw new CliError("validation_error", "locator and selected account disagree");
17181
+ return { key: { provider: parsed.provider, account: parsed.account }, target: { type, locator } };
17182
+ }
17183
+ return { key: await selectAccount(store, input), target: { type, id: input[type] } };
17184
+ }, "selectTarget");
17185
+ var scopeOf = /* @__PURE__ */ __name(async (store, env, options, warn) => {
17186
+ const value = writeAccountOf(options, warn);
17187
+ return value === void 0 ? {} : oneAccountOf(store, env, value, "--account");
17188
+ }, "scopeOf");
17189
+
17563
17190
  // dist/actions/actions.js
17564
17191
  var ACTION_QUERY = {
17565
17192
  entity: "proposed_action",
@@ -17676,24 +17303,39 @@ var listActions = /* @__PURE__ */ __name((store, query, limit, options = {}) =>
17676
17303
  return pageOf("actions list", limit, async (most2) => actionItems(store, await store.proposedActions.list({ limit: most2, ...status === void 0 ? {} : { status } }), options));
17677
17304
  }, "listActions");
17678
17305
  var showAction = /* @__PURE__ */ __name(async (store, id) => (await actionItems(store, [await store.proposedActions.get(id)]))[0], "showAction");
17306
+ var BATCHES = {
17307
+ [EVIDENCE_FINDINGS_KIND]: {
17308
+ fingerprint: /* @__PURE__ */ __name(async (store, id) => (await store.evidenceFindings.get(id)).fingerprint, "fingerprint"),
17309
+ stale: "evidence-findings.stale",
17310
+ required: true
17311
+ },
17312
+ [MAIL_FINDINGS_KIND]: {
17313
+ fingerprint: /* @__PURE__ */ __name(async (store, id) => (await store.mailFindings.get(id)).fingerprint, "fingerprint"),
17314
+ stale: "mail-findings.stale",
17315
+ required: false
17316
+ }
17317
+ };
17679
17318
  var decideFindings = /* @__PURE__ */ __name(async (store, id, decision) => {
17680
- const action = await store.proposedActions.get(id);
17681
- if (action.kind !== EVIDENCE_FINDINGS_KIND) {
17319
+ const batch = BATCHES[(await store.proposedActions.get(id)).kind];
17320
+ if (!batch) {
17682
17321
  if (decision.accept.length || decision.fingerprint !== void 0)
17683
17322
  throw new CliError("validation_error", "finding IDs and --fingerprint are for a findings batch");
17684
17323
  return void 0;
17685
17324
  }
17686
- if (decision.fingerprint === void 0)
17325
+ if (decision.fingerprint === void 0 && batch.required)
17687
17326
  throw new CliError("validation_error", "a findings batch needs the --fingerprint actions show gives", {
17688
17327
  param: "fingerprint"
17689
17328
  });
17690
- await decideBatch(store, id, { ...decision, fingerprint: decision.fingerprint });
17329
+ await decideBatch(store, id, decision);
17691
17330
  return showAction(store, id);
17692
17331
  }, "decideFindings");
17693
17332
  var decideBatch = /* @__PURE__ */ __name(async (store, id, decision) => {
17694
- if ((await store.evidenceFindings.get(id)).fingerprint !== decision.fingerprint)
17695
- throw new CliError("validation_error", "evidence findings changed since they were read; stage a new batch", {
17696
- reason: "evidence-findings.stale"
17333
+ const batch = BATCHES[(await store.proposedActions.get(id)).kind];
17334
+ if (!batch)
17335
+ throw new CliError("validation_error", "not a findings batch");
17336
+ if (decision.fingerprint !== void 0 && await batch.fingerprint(store, id) !== decision.fingerprint)
17337
+ throw new CliError("validation_error", "the findings changed since they were read; stage a new batch", {
17338
+ reason: batch.stale
17697
17339
  });
17698
17340
  const parts = decision.confirm && decision.accept.length ? decision.accept.map((one2) => `${id}/${one2}`) : [id];
17699
17341
  const { decided, refused } = await proposalRegistry(store).decide(parts, decisionOf(decision.confirm, decision.by, decision.reason));
@@ -17735,14 +17377,6 @@ var actionsCommand = /* @__PURE__ */ __name((program, streams, env) => {
17735
17377
  byOption(annotate(actions.command("confirm"), { effects: LOCAL_WRITE })).summary("confirm it: a task to act on, or a findings batch's facts and tasks").description("confirm it: it becomes a task in the account that would act, nothing is sent; for a findings batch, create the named findings (all when none is named) and reject the rest").argument("<id>", "the action's id, as actions list gives it").argument("[findings...]", "a findings batch: the finding IDs to create").option("--fingerprint <hash>", "a findings batch: the fingerprint actions show gives").option("--reason <text>", "why, in a few words; required when an agent decides for you").option("--json", "print JSON; --json=id,title keeps only those fields").action(async (id, findings, options, command) => {
17736
17378
  const by = await deciderOf(command, env, { ...options, question: `confirm action ${id} as you, the owner?` });
17737
17379
  await run(options.json, async (store) => {
17738
- if ((await store.proposedActions.get(id)).kind === MAIL_FINDINGS_KIND) {
17739
- const parts = findings.length ? findings.map((finding) => `${id}/${finding}`) : [id];
17740
- const { decided, refused } = await reviewRegistry(store, env).decide(parts, decisionOf(true, by, options.reason));
17741
- const refusal2 = refused[0];
17742
- if (refusal2)
17743
- throw new CliError(refusal2.code, refusal2.message, { reason: refusal2.reason });
17744
- return itemAnswer({ decided });
17745
- }
17746
17380
  const findingsAnswer = await decideFindings(store, id, { ...options, accept: findings, confirm: true, by });
17747
17381
  if (findingsAnswer)
17748
17382
  return itemAnswer(findingsAnswer);
@@ -17789,12 +17423,50 @@ var agentsCommand = /* @__PURE__ */ __name((program, streams, env) => {
17789
17423
  withQuery(annotate(agents.command("list"), { effects: LOCAL_READ, output: { entity: "agent_action" } }).summary("one row per tool call, newest first: agent, tool, outcome and times").description("one row per tool call, newest first: agent, tool, tier, outcome and times, never its arguments"), AGENT_LOG_QUERY).option("--limit <n>", "most rows, up to 500", positive, 100).option("--json", "print JSON; --json=id,title keeps only those fields").action((words2, options) => run(options.json, (store) => listAgentActions(store, words2, options.limit)));
17790
17424
  }, "agentsCommand");
17791
17425
 
17426
+ // dist/refs.js
17427
+ var BARE = /^\d+$/;
17428
+ var either = /* @__PURE__ */ __name((words2) => words2.length < 2 ? words2[0] ?? "" : `${words2.slice(0, -1).join(", ")} or ${words2.at(-1)}`, "either");
17429
+ var refuseBareNumber = /* @__PURE__ */ __name(async (store, text3, kinds2, options = {}) => {
17430
+ const value = text3.trim();
17431
+ if (!BARE.test(value))
17432
+ return;
17433
+ const candidates = kinds2.map((kind) => `${kind}:${value}`);
17434
+ const found = await store.refs.summaries(candidates);
17435
+ const existing = candidates.filter((ref) => {
17436
+ const state = found.get(ref)?.state;
17437
+ return state !== void 0 && state !== "unavailable";
17438
+ });
17439
+ const guess = existing.length ? `did you mean ${either(existing)}?` : `no ${either(kinds2.map((kind) => kind === "msg" ? "message" : kind))} has id ${value}`;
17440
+ const path = options.path ? `; to read a file named ${value}, give its path: ./${value}` : "";
17441
+ throw new CliError("validation_error", `"${value}" is a bare number; ${guess}${path}`, {
17442
+ reason: "ref.bare-number",
17443
+ value,
17444
+ suggestion: existing[0] ?? candidates[0]
17445
+ });
17446
+ }, "refuseBareNumber");
17447
+
17448
+ // dist/store/held.js
17449
+ var heldMessage = /* @__PURE__ */ __name(async (store, key, id, chatId) => {
17450
+ if (key.provider === "email") {
17451
+ const account2 = await store.accounts.storedAccount(key).catch(() => void 0);
17452
+ const email = account2 ? await store.mail.email(account2.id, id) : null;
17453
+ if (email)
17454
+ return email.deletedAt === null ? {
17455
+ text: [email.subject, email.bodyText].filter(Boolean).join("\n\n"),
17456
+ senderId: email.fromAddress,
17457
+ senderName: email.fromName,
17458
+ timestamp: new Date(email.sentAt ?? email.receivedAt ?? email.createdAt).toISOString()
17459
+ } : void 0;
17460
+ }
17461
+ return store.messages.message(key, id, { chatId });
17462
+ }, "heldMessage");
17463
+
17792
17464
  // dist/knowledge/key-documents.js
17793
17465
  var KEYABLE = /^(note|document|msg):/;
17794
17466
  var projectOf = /* @__PURE__ */ __name(async (store, reference3) => {
17795
17467
  try {
17796
- const wanted3 = await canonicalProject(store, /^[1-9]\d*$/.test(reference3) ? `project:${reference3}` : reference3);
17797
- const query = validateQuery(parseLucene(`id:${wanted3.slice(8)}`), PROJECTS_QUERY);
17468
+ const wanted2 = await canonicalProject(store, /^[1-9]\d*$/.test(reference3) ? `project:${reference3}` : reference3);
17469
+ const query = validateQuery(parseLucene(`id:${wanted2.slice(8)}`), PROJECTS_QUERY);
17798
17470
  const project = (await store.knowledge.projects(query))[0];
17799
17471
  if (project)
17800
17472
  return project;
@@ -17895,6 +17567,68 @@ var keyFirst = /* @__PURE__ */ __name((items, keys) => [
17895
17567
  ...items.filter((item) => !keys.has(item.ref))
17896
17568
  ], "keyFirst");
17897
17569
 
17570
+ // dist/notes/about.js
17571
+ var isNoteReference = /* @__PURE__ */ __name((reference3) => /^(note|document):/.test(reference3), "isNoteReference");
17572
+ var fold = /* @__PURE__ */ __name((value) => value.normalize("NFC").toLocaleLowerCase("en").trim().replace(/^@/, ""), "fold");
17573
+ var refOf = /* @__PURE__ */ __name((note, anchor = null) => ({
17574
+ ref: note.ref,
17575
+ source: note.source,
17576
+ folderId: note.folderId,
17577
+ path: note.path,
17578
+ title: note.title,
17579
+ modifiedAt: note.updatedAt,
17580
+ ...anchor === null ? {} : { anchor }
17581
+ }), "refOf");
17582
+ var PAGE = 500;
17583
+ var notesReaching = /* @__PURE__ */ __name(async (store, subject) => {
17584
+ const refs = [
17585
+ subject.ref,
17586
+ ...subject.person?.identities.map((identity) => formatReference({ type: "contact", provider: identity.provider, id: identity.id })) ?? []
17587
+ ];
17588
+ const live = /* @__PURE__ */ __name(async (links, via) => {
17589
+ const found = [];
17590
+ for (const link of links) {
17591
+ if (!isNoteReference(link.from))
17592
+ continue;
17593
+ const note = await store.notes.resolveNote(link.from);
17594
+ if (note && note.deletedAt === null)
17595
+ found.push({ note, anchor: link.anchor, text: link.targetText, via });
17596
+ }
17597
+ return found;
17598
+ }, "live");
17599
+ const aboutOne = /* @__PURE__ */ __name(async (ref) => {
17600
+ const notes2 = [];
17601
+ for (let offset = 0; ; offset += PAGE) {
17602
+ const page = await store.notes.notes({ about: ref, limit: PAGE, offset });
17603
+ notes2.push(...page.items);
17604
+ if (!page.hasMore)
17605
+ return notes2;
17606
+ }
17607
+ }, "aboutOne");
17608
+ const about = (await Promise.all(refs.map(aboutOne))).flat().map((note) => ({ note, anchor: null, text: null, via: "about" }));
17609
+ const linking = await live((await Promise.all(refs.map((to) => store.notes.links({ to })))).flat().filter((link) => link.kind === "links-to"), "link");
17610
+ const through = await live((await Promise.all(about.map(({ note }) => store.notes.links({ to: note.ref })))).flat().filter((link) => link.kind === "links-to"), "through");
17611
+ const names = new Set([subject.person?.name, ...subject.person?.identities.map(({ name }) => name) ?? []].filter((name) => !!name?.trim()).map(fold));
17612
+ const waiting = names.size === 0 ? [] : await live((await store.notes.links({ unresolved: true })).filter((link) => names.has(fold(link.targetText ?? ""))), "name");
17613
+ return [...about, ...linking, ...through, ...waiting];
17614
+ }, "notesReaching");
17615
+ var notesAbout = /* @__PURE__ */ __name(async (store, subject, limit = 20) => {
17616
+ const found = await notesReaching(store, subject);
17617
+ const unique = /* @__PURE__ */ __name((via) => [
17618
+ ...new Map(found.filter((item) => item.via === via).map((item) => [`${item.note.ref}#${item.anchor ?? ""}`, item])).values()
17619
+ ].sort((a, b) => b.note.updatedAt.localeCompare(a.note.updatedAt)), "unique");
17620
+ const [about, linking, through, waiting] = ["about", "link", "through", "name"].map(unique);
17621
+ return {
17622
+ subject: subject.ref,
17623
+ name: subject.person?.name ?? null,
17624
+ about: (about ?? []).slice(0, limit).map(({ note }) => refOf(note)),
17625
+ linking: (linking ?? []).slice(0, limit).map(({ note, anchor }) => refOf(note, anchor)),
17626
+ throughNotes: (through ?? []).slice(0, limit).map(({ note, anchor }) => refOf(note, anchor)),
17627
+ waiting: (waiting ?? []).slice(0, limit).map(({ note, text: text3 }) => ({ ...refOf(note), text: text3 ?? "" })),
17628
+ hasMore: [about, linking, through, waiting].some((list) => (list ?? []).length > limit)
17629
+ };
17630
+ }, "notesAbout");
17631
+
17898
17632
  // dist/tasks/context.js
17899
17633
  var taskPage = /* @__PURE__ */ __name(async (store, key, options = {}) => {
17900
17634
  const page = await store.knowledge.taskIds(key, options);
@@ -18319,13 +18053,13 @@ var unbound = /* @__PURE__ */ __name((path) => new CliError("configuration_error
18319
18053
  var boundFolders = /* @__PURE__ */ __name(async (store, env, { only, strict = true } = {}) => {
18320
18054
  const known = new Set((await store.notes.folders()).map(({ id }) => id));
18321
18055
  const configured = noteFolders(loadConfig(env).notes);
18322
- const wanted3 = only === void 0 ? configured : only.map((name) => {
18056
+ const wanted2 = only === void 0 ? configured : only.map((name) => {
18323
18057
  const found = configured.find((folder) => folder.id === name || folder.path === resolve2(name));
18324
18058
  if (!found)
18325
18059
  throw unbound(resolve2(name));
18326
18060
  return found;
18327
18061
  });
18328
- return wanted3.flatMap((folder) => {
18062
+ return wanted2.flatMap((folder) => {
18329
18063
  if (folder.id !== null && known.has(folder.id))
18330
18064
  return [folder];
18331
18065
  if (strict)
@@ -18356,7 +18090,7 @@ import { createHash } from "node:crypto";
18356
18090
  import { existsSync, readFileSync as readFileSync2, statSync } from "node:fs";
18357
18091
  import { basename, extname, relative, sep } from "node:path";
18358
18092
 
18359
- // node_modules/.pnpm/@wirecat+cli-core@0.567.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_90104be51d88dd1f434885448f73ba7c/node_modules/@wirecat/cli-core/dist/services/documents/extraction.js
18093
+ // node_modules/.pnpm/@wirecat+cli-core@0.569.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_8785fed449bbc2a6b34fc086f24a8413/node_modules/@wirecat/cli-core/dist/services/documents/extraction.js
18360
18094
  var Proposal = object({
18361
18095
  kind: picklist(["summary", "digest", "fact", "preference"]),
18362
18096
  body: pipe(string(), trim(), minLength(1), maxLength(15e3)),
@@ -18364,10 +18098,10 @@ var Proposal = object({
18364
18098
  });
18365
18099
  var Proposals = object({ items: pipe(array(Proposal), maxLength(20)) });
18366
18100
 
18367
- // node_modules/.pnpm/@wirecat+cli-core@0.567.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_90104be51d88dd1f434885448f73ba7c/node_modules/@wirecat/cli-core/dist/services/documents/mirrors.js
18101
+ // node_modules/.pnpm/@wirecat+cli-core@0.569.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_8785fed449bbc2a6b34fc086f24a8413/node_modules/@wirecat/cli-core/dist/services/documents/mirrors.js
18368
18102
  var ID = pipe(string(), regex(/^[A-Za-z0-9_-]{1,200}$/));
18369
18103
 
18370
- // node_modules/.pnpm/@wirecat+cli-core@0.567.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_90104be51d88dd1f434885448f73ba7c/node_modules/@wirecat/cli-core/dist/services/documents/sync.js
18104
+ // node_modules/.pnpm/@wirecat+cli-core@0.569.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_8785fed449bbc2a6b34fc086f24a8413/node_modules/@wirecat/cli-core/dist/services/documents/sync.js
18371
18105
  var MAX_PICTURE_BYTES = 25 * 1024 * 1024;
18372
18106
 
18373
18107
  // dist/notes/links.js
@@ -18673,7 +18407,7 @@ var importNotesMap = /* @__PURE__ */ __name(async (store, env, folders) => {
18673
18407
  return linked2;
18674
18408
  }, "importNotesMap");
18675
18409
 
18676
- // node_modules/.pnpm/@wirecat+cli-core@0.567.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_90104be51d88dd1f434885448f73ba7c/node_modules/@wirecat/cli-core/dist/mail/cli/marks.js
18410
+ // node_modules/.pnpm/@wirecat+cli-core@0.569.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_8785fed449bbc2a6b34fc086f24a8413/node_modules/@wirecat/cli-core/dist/mail/cli/marks.js
18677
18411
  var iso = /* @__PURE__ */ __name((ms) => ms === null ? null : new Date(ms).toISOString(), "iso");
18678
18412
  var mailMark = strictObject({
18679
18413
  holder: string(),
@@ -18708,11 +18442,16 @@ var acknowledgeCommand = /* @__PURE__ */ __name((mail) => answerEntity(proposesO
18708
18442
  ]
18709
18443
  })), "mail_mark", mailMark).summary("move a holder's processing mark to what it has read").description("record that a holder \u2014 an agent or a pipeline \u2014 processed the mail `review --holder` gave it, with the cursor that review gave; the mark only moves forward, and mail still partial waits for the next review").requiredOption("--holder <name>", "whose mark: lower-case letters, digits and dashes, such as mail-triage").requiredOption("--cursor <cursor>", "the cursor `review --holder` gave").action(async function() {
18710
18444
  const { holder, cursor } = this.opts();
18445
+ const env = environmentOf(this).env ?? process.env;
18446
+ const named5 = env[mailHolderVariable(mail.app)]?.trim();
18447
+ const owner = actorOf(this) === "owner" && !readOnlyLockOf(mail.app, env);
18448
+ if (named5 ? named5 !== holder : !owner)
18449
+ throw new CliError("permission_error", named5 ? `this run moves only ${named5}'s mark, not ${holder}'s` : `an agent moves only the mark of the holder its schedule names (schedule agent --on-new-mail ${holder}); the owner moves any`, { reason: "mail.holder-not-yours" });
18711
18450
  const mark = await mail.read(this, (store, mailbox) => acknowledgeMark(store, mailbox, holder, cursor));
18712
18451
  renderAnswer(this, outputFor(this), itemOf(markItem(mark)), () => markText(mark));
18713
18452
  }), "acknowledgeCommand");
18714
18453
 
18715
- // node_modules/.pnpm/@wirecat+cli-core@0.567.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_90104be51d88dd1f434885448f73ba7c/node_modules/@wirecat/cli-core/dist/mail/cli/review.js
18454
+ // node_modules/.pnpm/@wirecat+cli-core@0.569.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_8785fed449bbc2a6b34fc086f24a8413/node_modules/@wirecat/cli-core/dist/mail/cli/review.js
18716
18455
  var DAY4 = 864e5;
18717
18456
  var REVIEW_UNTRUSTED = [...SUMMARY_UNTRUSTED, ...MAIL_HIT_UNTRUSTED];
18718
18457
  var MAIL_REVIEW_QUERY = defineQuery({
@@ -18775,13 +18514,14 @@ var reviewAnswer = /* @__PURE__ */ __name((found, mailbox, fresh, step) => {
18775
18514
  const cut2 = found.chats.filter((chat) => chat.more);
18776
18515
  const ref = /* @__PURE__ */ __name((thread) => formatReference({ type: "chat", ...mailbox, chat: thread }), "ref");
18777
18516
  const turns = found.unanswered !== void 0 || found.waiting !== void 0;
18778
- const wholeThreads = cut2.flatMap((chat) => step("mail-conversations.show", { conversation: ref(chat.id) }));
18517
+ const [first, ...rest] = cut2.map((chat) => ref(chat.id));
18518
+ const wholeThread = first === void 0 ? [] : step("mail-conversations.show", { conversation: first });
18779
18519
  const missing = [
18780
- ...cut2.length > 0 ? [
18520
+ ...first !== void 0 ? [
18781
18521
  {
18782
18522
  field: "items",
18783
- why: `only the newest emails of ${cut2.length} thread(s)`,
18784
- ...wholeThreads.length ? { step: "mail-conversations.show" } : {}
18523
+ why: `only the newest emails of ${cut2.length} thread(s)` + (rest.length ? `; read the others whole the same way: ${rest.join(", ")}` : ""),
18524
+ ...wholeThread.length ? { step: "mail-conversations.show" } : {}
18785
18525
  }
18786
18526
  ] : [],
18787
18527
  ...found.skipped.length > 0 ? [
@@ -18794,7 +18534,7 @@ var reviewAnswer = /* @__PURE__ */ __name((found, mailbox, fresh, step) => {
18794
18534
  ];
18795
18535
  const next = [
18796
18536
  ...!fresh && !turns ? step("mail-review.next", { query: `date>${quoted(found.complete ? found.until : found.since)}` }) : [],
18797
- ...wholeThreads
18537
+ ...wholeThread
18798
18538
  ];
18799
18539
  return listOf("review", {
18800
18540
  items: read.map((message) => ({
@@ -18941,7 +18681,7 @@ an agent over MCP, and each scheduled run.`).action(async function(query) {
18941
18681
  saved?.save(found.checked ?? {}, found.complete ? { through: found.until } : {});
18942
18682
  }), "mailReviewCommand");
18943
18683
 
18944
- // node_modules/.pnpm/@wirecat+cli-core@0.567.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_90104be51d88dd1f434885448f73ba7c/node_modules/@wirecat/cli-core/dist/mail/cli/index.js
18684
+ // node_modules/.pnpm/@wirecat+cli-core@0.569.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_8785fed449bbc2a6b34fc086f24a8413/node_modules/@wirecat/cli-core/dist/mail/cli/index.js
18945
18685
  var absentAccount = /* @__PURE__ */ __name((error) => {
18946
18686
  if (error instanceof CliError && error.code === "not_found")
18947
18687
  return void 0;
@@ -19227,7 +18967,7 @@ var mailReadCommands = sharedCommand((mail) => [
19227
18967
  // dist/review/status.js
19228
18968
  var MOST_PAGES = 10;
19229
18969
  var counted2 = /* @__PURE__ */ __name(async (store, env, filter, since) => {
19230
- const registry = reviewRegistry(store, env);
18970
+ const registry = reviewRegistry(store);
19231
18971
  const byKind = {};
19232
18972
  let total = 0;
19233
18973
  for (let page = 0; page < MOST_PAGES; page++) {
@@ -19242,12 +18982,12 @@ var counted2 = /* @__PURE__ */ __name(async (store, env, filter, since) => {
19242
18982
  return { total, byKind, complete: false };
19243
18983
  }, "counted");
19244
18984
  var waitingAbout = /* @__PURE__ */ __name(async (store, env, refs) => {
19245
- const wanted3 = new Set(refs);
19246
- const registry = reviewRegistry(store, env);
18985
+ const wanted2 = new Set(refs);
18986
+ const registry = reviewRegistry(store);
19247
18987
  let count2 = 0;
19248
18988
  for (let page = 0; page < MOST_PAGES; page++) {
19249
18989
  const found = await registry.list({ status: "proposed", limit: 50, offset: page * 50 });
19250
- count2 += found.items.filter((row) => [row.subject, row.object, row.project].some((ref) => ref !== null && wanted3.has(ref))).length;
18990
+ count2 += found.items.filter((row) => [row.subject, row.object, row.project].some((ref) => ref !== null && wanted2.has(ref))).length;
19251
18991
  if (!found.hasMore)
19252
18992
  return { count: count2, complete: true };
19253
18993
  }
@@ -19413,6 +19153,19 @@ var memoContext = /* @__PURE__ */ __name(async (store, reference3, { limit = 20,
19413
19153
  untrusted: UNTRUSTED_EVENT_FIELDS
19414
19154
  };
19415
19155
  }, "memoContext");
19156
+ var withOwnMailText = /* @__PURE__ */ __name((context) => {
19157
+ const own = /* @__PURE__ */ __name((message) => message?.provider === "email" ? { ...message, text: mailOwnText(message.text) } : message, "own");
19158
+ const { last, recent, mentions } = context.messages;
19159
+ return {
19160
+ ...context,
19161
+ messages: {
19162
+ ...context.messages,
19163
+ last: { fromThem: own(last.fromThem), fromMe: own(last.fromMe), fromThemAnywhere: own(last.fromThemAnywhere) },
19164
+ recent: { direct: recent.direct.map(own), groups: recent.groups.map(own) },
19165
+ mentions: mentions.map(own)
19166
+ }
19167
+ };
19168
+ }, "withOwnMailText");
19416
19169
 
19417
19170
  // dist/context/command.js
19418
19171
  var MAX_TEXT2 = 160;
@@ -19459,7 +19212,7 @@ var contextText = /* @__PURE__ */ __name(({ messages, events, notes: notes2, not
19459
19212
  }, "contextText");
19460
19213
  var contextCommand = /* @__PURE__ */ __name((program, streams, env) => {
19461
19214
  const { print } = answers(program, streams, env);
19462
- annotate(program.command("context"), { effects: LOCAL_READ }).description("messages, mail, notes and events about a person, each with a link to its source").argument("<person>", "<messenger>:<name or id>, e.g. telegram:Ana or email:ana@example.com, person:<id>, or person:me for you").option("--limit <n>", "most messages, notes and events of each kind", positive, 20).option("--json", "print JSON; --json=id,title keeps only those fields").option("--source <accounts>", "the account to read, as provider:account; required when the store holds several of that messenger").action(async (person, options) => {
19215
+ annotate(program.command("context"), { effects: LOCAL_READ }).description("messages, mail, notes and events about a person, each with a link to its source").argument("<person>", "<messenger>:<name or id>, e.g. telegram:Ana or email:ana@example.com, person:<id>, or person:me for you").option("--limit <n>", "most messages, notes and events of each kind", positive, 20).option("--json", "print JSON; --json=id,title keeps only those fields").option("--source <accounts>", "the account to read, as provider:account; required when the store holds several of that messenger").option("--trimmed", "each email's own text, without quoted earlier mail or the signature \u2014 for an agent's reads").action(async (person, options) => {
19463
19216
  const answer = await withStore(env, async (store) => {
19464
19217
  await importNotesMap(store, env, await boundFolders(store, env, { strict: false }));
19465
19218
  const source = options.source === void 0 ? void 0 : await contextAccountOf(store, env, person, options.source);
@@ -19469,7 +19222,10 @@ var contextCommand = /* @__PURE__ */ __name((program, streams, env) => {
19469
19222
  });
19470
19223
  const { uid, identities } = found.messages.person;
19471
19224
  const refs = [`person:${uid}`, ...identities.map(({ provider, id }) => `${provider}:${id}`)];
19472
- return { ...found, proposals: await waitingAbout(store, env, refs) };
19225
+ return {
19226
+ ...options.trimmed ? withOwnMailText(found) : found,
19227
+ proposals: await waitingAbout(store, env, refs)
19228
+ };
19473
19229
  });
19474
19230
  print(options.json, itemAnswer(answer), contextText(answer));
19475
19231
  });
@@ -21425,7 +21181,8 @@ var EXAMPLES = {
21425
21181
  ],
21426
21182
  "schedule agent": [
21427
21183
  "memo schedule agent triage claude 'read memo review status and list what needs me today' --at 08:45 --max-cost 1",
21428
- "memo schedule agent mail-triage claude 'Run memo skill show mail-triage and follow it.' --every 5m --on-new-mail mail-triage --max-cost 1"
21184
+ "memo schedule agent mail-triage claude 'Run memo skill show mail-triage and follow it.' --every 5m --on-new-mail mail-triage --mail-wait 1h --mail-batch 20 --max-cost 1 --max-cost-per-day 5",
21185
+ "memo schedule agent weekly claude 'read memo review status and sum up the week' --at 09:00 --model opus"
21429
21186
  ],
21430
21187
  "schedule list": ["memo schedule list", "memo schedule list kind:agent --json"],
21431
21188
  "schedule run": ["memo schedule run digest"],
@@ -22989,8 +22746,8 @@ var knowledgeCommands = /* @__PURE__ */ __name((program, streams, env) => {
22989
22746
  return ownedList("organizations list", options, (store) => store.knowledge.organizations(query));
22990
22747
  });
22991
22748
  annotate(organizations.command("context"), { effects: LOCAL_READ }).description("one organization by its id or organization:<id>: its relationships, the notes about or linking it, and its tags").summary("one organization: its relationships, notes and tags").argument("<organization>", "its id or organization:<id>").option("--json", "print JSON; --json=id,title keeps only those fields").action((reference3, options) => owned(options, async (store) => {
22992
- const wanted3 = reference3.replace(/^organization:/, "");
22993
- return contextOf(store, (await store.knowledge.organizations()).find((organization) => organization.id === wanted3), "organization", reference3);
22749
+ const wanted2 = reference3.replace(/^organization:/, "");
22750
+ return contextOf(store, (await store.knowledge.organizations()).find((organization) => organization.id === wanted2), "organization", reference3);
22994
22751
  }));
22995
22752
  const projects = program.command("projects").description("projects of yours, each with a short key");
22996
22753
  meetingProjectsCommand(projects, streams, env);
@@ -23130,11 +22887,10 @@ import { createReadStream as createReadStream3 } from "node:fs";
23130
22887
  // dist/mail/review-command.js
23131
22888
  var MAILBOX_HELP = `the one mailbox: ${MAIL_SOURCES}; may be left out when the store holds one mailbox`;
23132
22889
  var oneMailboxOf = /* @__PURE__ */ __name(async (store, env, source) => {
23133
- const mailboxes = source ? await mailboxesOf(store, env, source) : (await store.accounts.accounts()).filter((key) => key.provider === "email");
23134
- if (mailboxes.length === 1)
23135
- return mailboxes[0];
23136
- const names = mailboxes.map((key) => `email:${key.account}`).join(", ");
23137
- throw new CliError("validation_error", names ? `give --source with one mailbox: ${names}` : "the store holds no mailbox yet; run memo sync first", { reason: "mail.mailbox-needed", param: "source" });
22890
+ const key = await oneAccountOf(store, env, source ?? "email");
22891
+ if (key.provider !== "email")
22892
+ throw new CliError("validation_error", `${source} is not a mailbox \u2014 ${MAIL_SOURCES}`, { param: "source" });
22893
+ return key;
23138
22894
  }, "oneMailboxOf");
23139
22895
  var named3 = /* @__PURE__ */ __name((commands2, name) => {
23140
22896
  const found = commands2.find((command) => command.name() === name);
@@ -23276,7 +23032,11 @@ var citedBy = /* @__PURE__ */ __name(async (store, ref) => {
23276
23032
  var messagesCommand2 = /* @__PURE__ */ __name((program, streams, env) => {
23277
23033
  const { print } = answers(program, streams, env);
23278
23034
  const messages = program.command("messages").description("stored messenger messages and emails");
23279
- annotate(messages.command("show"), { effects: LOCAL_READ }).description("one stored message or email whole, with optional stored neighbours").argument("<message>", "the msg:provider/account/chat/message reference a search gives").option("--before-n <n>", "also this many earlier emails of its thread", whole, 0).option("--after-n <n>", "also this many later emails of its thread", whole, 0).option("--full", `whole attachment text, not the first ${ATTACHMENT_CHARS} characters of each, and the HTML and AMP versions of the body`).option("--json", "print JSON; --json=id,title keeps only those fields").action(async (reference3, options) => {
23035
+ annotate(messages.command("show"), { effects: LOCAL_READ }).description("one stored message or email whole, with optional stored neighbours").argument("<message>", "the msg:provider/account/chat/message reference a search gives").option("--before-n <n>", "also this many earlier emails of its thread", whole, 0).option("--after-n <n>", "also this many later emails of its thread", whole, 0).option("--full", `whole attachment text, not the first ${ATTACHMENT_CHARS} characters of each, and the HTML and AMP versions of the body`).option("--trimmed", "each email's own text, without quoted earlier mail or the signature \u2014 for an agent's reads").option("--json", "print JSON; --json=id,title keeps only those fields").action(async (reference3, options) => {
23036
+ if (options.trimmed && options.full)
23037
+ throw new CliError("validation_error", "--trimmed shows less of an email and --full more \u2014 give one", {
23038
+ param: "trimmed"
23039
+ });
23280
23040
  const locator = parseLocator(reference3);
23281
23041
  if (locator.provider !== "email") {
23282
23042
  const key = { provider: locator.provider, account: locator.account };
@@ -23304,6 +23064,7 @@ var messagesCommand2 = /* @__PURE__ */ __name((program, streams, env) => {
23304
23064
  });
23305
23065
  return Promise.all(shown.map(async (email) => ({
23306
23066
  ...email,
23067
+ ...options.trimmed ? { text: mailOwnText(email.text) } : {},
23307
23068
  ref: email.locator,
23308
23069
  fingerprint: await citedBy(store, email.locator)
23309
23070
  })));
@@ -23331,10 +23092,10 @@ var mcpCommandDefinition = /* @__PURE__ */ __name((program, streams, env, create
23331
23092
  }).summary("serve this profile's commands to an AI agent").description("serve memo commands over MCP on stdio or authenticated HTTP, limited by saved permissions").option("--permission <key=level>", "tighten one saved permission for this server; repeat for more keys", (value, previous = []) => [...previous, value]).option("--http", "serve on 127.0.0.1 behind an HTTPS tunnel with an owner access-code login").option("--port <port>", `local HTTP port (default ${DEFAULT_PORT}); requires --http`).option("--public-url <url>", "tunnel's HTTPS address without /mcp, or a path of it such as https://<name>.ts.net/memo; requires --http").action(async (options) => {
23332
23093
  if (!options.http && (options.port !== void 0 || options.publicUrl !== void 0))
23333
23094
  throw new CliError("validation_error", "--port and --public-url require --http");
23334
- const { createMemoServer } = await import("./server-Z6L4U6HO.js");
23095
+ const { createMemoServer } = await import("./server-NN2CBVSX.js");
23335
23096
  const build = /* @__PURE__ */ __name(() => createMemoServer(env, createProgram2, options.permission), "build");
23336
23097
  if (options.http) {
23337
- const { httpLockFile, mcpUrlOf, portOf, publicUrlOf, serveOverHttp } = await import("./mcp-I7LL7AJG.js");
23098
+ const { httpLockFile, mcpUrlOf, portOf, publicUrlOf, serveOverHttp } = await import("./mcp-6Z7UKX7E.js");
23338
23099
  const publicUrl = publicUrlOf(options.publicUrl, {
23339
23100
  missing: "--http",
23340
23101
  reaches: "the browser apps reach memo",
@@ -23386,7 +23147,7 @@ var mcpCommandDefinition = /* @__PURE__ */ __name((program, streams, env, create
23386
23147
  });
23387
23148
  });
23388
23149
  annotate(mcp2.command("revoke"), { effects: LOCAL_WRITE, mcp: false, examples: ["memo mcp revoke --json"] }).summary("forget every login given to a browser app").description("forget every login `memo mcp serve --http` gave a browser app; each app must log in again").option("--json", "print JSON").action(async function() {
23389
- const { revokeAll } = await import("./mcp-I7LL7AJG.js");
23150
+ const { revokeAll } = await import("./mcp-6Z7UKX7E.js");
23390
23151
  revokeAll(httpTokenFile(env));
23391
23152
  out.print(this.opts().json, itemAnswer({ revoked: true }));
23392
23153
  });
@@ -24306,13 +24067,6 @@ var ROW = {
24306
24067
  ],
24307
24068
  text: ["reason"]
24308
24069
  };
24309
- var CLOSE_ID = /^close:[A-Za-z][A-Za-z0-9]*-[1-9]\d*$/;
24310
- var reviewIds = /* @__PURE__ */ __name((words2) => {
24311
- const tokens = words2.flatMap((word) => word.split(",")).map((one2) => one2.trim());
24312
- const closes = tokens.filter((one2) => CLOSE_ID.test(one2));
24313
- const rest = tokens.filter((one2) => one2 !== "" && !CLOSE_ID.test(one2));
24314
- return [.../* @__PURE__ */ new Set([...rest.length || !closes.length ? parseProposalIds(rest) : [], ...closes])];
24315
- }, "reviewIds");
24316
24070
  var json4 = /* @__PURE__ */ __name((command) => command.option("--json", "print JSON; --json=id,title keeps only those fields"), "json");
24317
24071
  var reviewCommand = /* @__PURE__ */ __name((program, streams, env) => {
24318
24072
  const { print } = answers(program, streams, env);
@@ -24361,12 +24115,12 @@ var reviewCommand = /* @__PURE__ */ __name((program, streams, env) => {
24361
24115
  command.requiredOption("--reason <text>", "why it is turned down, in a few words");
24362
24116
  command.option("--compact", "one line per decision");
24363
24117
  command.action(async (words2, given) => {
24364
- const ids = reviewIds(words2);
24118
+ const ids = parseProposalIds(words2);
24365
24119
  const by = await deciderOf(command, env, {
24366
24120
  ...given,
24367
24121
  question: `${name} ${ids.length} proposal${ids.length === 1 ? "" : "s"} as you, the owner?`
24368
24122
  });
24369
- const result = await withStore(env, (store) => reviewRegistry(store, env).decide(ids, decisionOf(name === "confirm", by, given.reason)));
24123
+ const result = await withStore(env, (store) => reviewRegistry(store).decide(ids, decisionOf(name === "confirm", by, given.reason)));
24370
24124
  const issues = result.refused.map((one2) => ({
24371
24125
  code: one2.code,
24372
24126
  source: one2.id,
@@ -24601,7 +24355,11 @@ var scheduleCommand = /* @__PURE__ */ __name((env) => {
24601
24355
  const schedule = scheduleCommandFor({
24602
24356
  app: APP,
24603
24357
  context: /* @__PURE__ */ __name((command) => ({ ...outputFor(command), env, profile: "" }), "context"),
24604
- newMail: /* @__PURE__ */ __name((_command, holder) => withStore(env, (store) => holderHasMail(store, holder)), "newMail")
24358
+ newMail: /* @__PURE__ */ __name((_command, holder) => withStore(env, async (store) => {
24359
+ await advancePastSkipped(store, holder);
24360
+ return mailWaiting(store, holder);
24361
+ }), "newMail"),
24362
+ limits: /* @__PURE__ */ __name(() => scheduleLimits(env), "limits")
24605
24363
  });
24606
24364
  for (const one2 of schedule.commands)
24607
24365
  overrideSharedContract(one2, "Memo's output flag is command-local because this provider does not use the messenger program shell.", (command) => {
@@ -24724,8 +24482,8 @@ var scopeOf2 = /* @__PURE__ */ __name(async (store, env, source) => {
24724
24482
  return held;
24725
24483
  }, "scopeOf");
24726
24484
  var searchPeople = /* @__PURE__ */ __name(async (store, env, words2, { limit, source }) => {
24727
- const wanted3 = words2.flatMap((word) => fold3(word).split(/\s+/)).filter(Boolean);
24728
- if (wanted3.length === 0)
24485
+ const wanted2 = words2.flatMap((word) => fold3(word).split(/\s+/)).filter(Boolean);
24486
+ if (wanted2.length === 0)
24729
24487
  throw new CliError("validation_error", "give a part of the name to find");
24730
24488
  const accounts = await scopeOf2(store, env, source);
24731
24489
  const hits = /* @__PURE__ */ new Map();
@@ -24734,7 +24492,7 @@ var searchPeople = /* @__PURE__ */ __name(async (store, env, words2, { limit, so
24734
24492
  for (const contact of (await store.people.people(key.provider, { account: key.account })).all()) {
24735
24493
  const alias = contact.alias ?? null;
24736
24494
  const text3 = fold3([contact.name, contact.username, alias].filter(Boolean).join(" "));
24737
- if (!wanted3.every((word) => text3.includes(word)))
24495
+ if (!wanted2.every((word) => text3.includes(word)))
24738
24496
  continue;
24739
24497
  const identityKey = `${key.provider}\0${contact.id}`;
24740
24498
  if (!record2.has(identityKey))
@@ -24755,7 +24513,7 @@ var searchPeople = /* @__PURE__ */ __name(async (store, env, words2, { limit, so
24755
24513
  hits.set(ref, hit);
24756
24514
  }
24757
24515
  }
24758
- const first = wanted3.join(" ");
24516
+ const first = wanted2.join(" ");
24759
24517
  const rank = /* @__PURE__ */ __name((hit) => fold3(hit.name ?? "").startsWith(first) ? 0 : 1, "rank");
24760
24518
  const sorted = [...hits.values()].sort((a, b) => rank(a) - rank(b) || (a.name ?? "").localeCompare(b.name ?? "") || a.ref.localeCompare(b.ref));
24761
24519
  return { items: sorted.slice(0, limit), hasMore: sorted.length > limit, accounts };
@@ -25376,6 +25134,148 @@ var sharedTaskCommands = /* @__PURE__ */ __name((program, tasks, streams, env) =
25376
25134
  program.command("stats").description("statistics about what the store holds").addCommand(new Command("tasks").description("task statistics").addCommand(scoped2(tasksStatsCommand(messenger), env, warn)));
25377
25135
  }, "sharedTaskCommands");
25378
25136
 
25137
+ // dist/tasks/tasks.js
25138
+ var personRef = /* @__PURE__ */ __name((person) => person.startsWith("person:") ? person : `person:${person}`, "personRef");
25139
+ var fieldsOf3 = /* @__PURE__ */ __name((options) => ({
25140
+ ...options.title === void 0 ? {} : { title: options.title },
25141
+ ...options.priority === void 0 ? {} : { priority: options.priority },
25142
+ ...options.parent === void 0 ? {} : { parent: options.parent },
25143
+ ...options.description === void 0 ? {} : { description: options.description }
25144
+ }), "fieldsOf");
25145
+ var assignAll = /* @__PURE__ */ __name(async (store, env, id, people) => {
25146
+ for (const person of people ?? [])
25147
+ await store.tasks.assign(id, { to: personRef(person), role: "assignee" }, authorOf(env));
25148
+ }, "assignAll");
25149
+ var addToProject = /* @__PURE__ */ __name(async (store, env, options) => {
25150
+ if (options.project === void 0 || options.title === void 0)
25151
+ throw new CliError("validation_error", "a task without a source needs --project and --title");
25152
+ if (options.into !== void 0 || options.new)
25153
+ throw new CliError("validation_error", "--into and --new are for a task from a source");
25154
+ const type = options.type ?? "chore";
25155
+ if (!WORK_TASK_TYPES.includes(type))
25156
+ throw new CliError("validation_error", `a task in a project is ${WORK_TASK_TYPES.join(", ")}`);
25157
+ const task = await store.tasks.create({
25158
+ project: await canonicalProject(store, options.project),
25159
+ title: options.title,
25160
+ type,
25161
+ ...fieldsOf3(options),
25162
+ ...options.due === void 0 || options.due === "none" ? {} : { dueAt: options.due },
25163
+ ...options.status === void 0 ? {} : { status: options.status },
25164
+ ...options.agent === void 0 ? {} : { agent: options.agent }
25165
+ }, authorOf(env));
25166
+ await assignAll(store, env, task.id, options.assignee);
25167
+ return store.tasks.details(task.id);
25168
+ }, "addToProject");
25169
+ var folderOf = /* @__PURE__ */ __name(async (store, source) => {
25170
+ const folderId = (await store.notes.resolveNote(source.trim()))?.folderId;
25171
+ if (folderId == null)
25172
+ return void 0;
25173
+ const folder = (await store.accounts.storedAccounts()).find(({ id }) => String(id) === folderId);
25174
+ return folder && { provider: folder.provider, account: folder.account };
25175
+ }, "folderOf");
25176
+ var addFromSource = /* @__PURE__ */ __name(async (store, env, source, options) => {
25177
+ if (options.due !== void 0 || options.status !== void 0 || options.agent !== void 0)
25178
+ throw new CliError("validation_error", "--due, --status and --agent are for a task in a project");
25179
+ if (options.project !== void 0)
25180
+ throw new CliError("validation_error", "a task from a source goes in its account; --project is for one without");
25181
+ const type = options.type ?? "request";
25182
+ if (WORK_TASK_TYPES.includes(type))
25183
+ throw new CliError("validation_error", "a bug, feature or chore has no source: give --project and --title");
25184
+ const native = isNoteReference(source.trim());
25185
+ const parsed = native ? void 0 : parseLocator(source);
25186
+ if (parsed && (options.provider && options.provider !== parsed.provider || options.account && options.account !== parsed.account))
25187
+ throw new CliError("validation_error", "locator and selected account disagree");
25188
+ const key = parsed ? { provider: parsed.provider, account: parsed.account } : (options.provider === void 0 ? await folderOf(store, source) : void 0) ?? await selectAccount(store, options);
25189
+ if (parsed && parsed.provider !== "notes" && await heldMessage(store, key, parsed.message, parsed.chat) === void 0)
25190
+ throw new CliError("not_found", "the task source is unavailable or deleted");
25191
+ const author = authorOf(env);
25192
+ const answer = await tasksService(storeOnlyDeps(store, key, { app: APP, env })).add(source, type, author === "owner" ? "owner" : "agent", void 0, {
25193
+ ...options.into === void 0 ? {} : { attach: options.into },
25194
+ ...options.new ? { new: true } : {}
25195
+ }, author);
25196
+ const fields = fieldsOf3(options);
25197
+ if (Object.keys(fields).length === 0 && !options.assignee?.length)
25198
+ return answer;
25199
+ await store.tasks.edit(answer.task.id, fields, "owner");
25200
+ await assignAll(store, env, answer.task.id, options.assignee);
25201
+ return { ...answer, details: await store.tasks.details(answer.task.id) };
25202
+ }, "addFromSource");
25203
+ var addTask = /* @__PURE__ */ __name(async (store, env, source, options) => {
25204
+ if (source === void 0)
25205
+ return addToProject(store, env, options);
25206
+ await refuseBareNumber(store, source, ["note", "document"]);
25207
+ return addFromSource(store, env, source, options);
25208
+ }, "addTask");
25209
+ var checkOf = /* @__PURE__ */ __name((revision) => revision === void 0 ? {} : { revision }, "checkOf");
25210
+ var closeTask = /* @__PURE__ */ __name(async (store, env, id, options) => {
25211
+ if (await store.tasks.get(id) === void 0) {
25212
+ const reason = options.reason === void 0 ? {} : { reason: options.reason };
25213
+ return store.tasks.edit(id, { status: options.as, ...reason }, authorOf(env), checkOf(options.revision));
25214
+ }
25215
+ if (options.revision !== void 0)
25216
+ throw new CliError("validation_error", "--revision checks a project task; a task from a message has none");
25217
+ const key = await selectAccount(store, options);
25218
+ return tasksService(storeOnlyDeps(store, key, { app: APP, env })).close(id, {
25219
+ as: options.as,
25220
+ by: "owner",
25221
+ ...options.reason === void 0 ? {} : { reason: options.reason }
25222
+ });
25223
+ }, "closeTask");
25224
+ var updateTask = /* @__PURE__ */ __name(async (store, env, id, options) => {
25225
+ const fields = fieldsOf3(options);
25226
+ const times = {
25227
+ ...options.due === void 0 ? {} : { dueAt: options.due },
25228
+ ...options.remindTime === void 0 ? {} : { nextCheckAt: options.remindTime }
25229
+ };
25230
+ if (Object.keys(fields).length + Object.keys(times).length === 0 && options.category === void 0 && options.assignee === void 0 && options.status === void 0 && options.agent === void 0 && options.project === void 0 && options.type === void 0)
25231
+ throw new CliError("validation_error", "give --title, --description, --priority, --parent, --due, --remind-time, --category, --assignee, --status, --agent, --project or --type");
25232
+ if (await store.tasks.get(id) === void 0) {
25233
+ if (options.category !== void 0 || options.assignee !== void 0)
25234
+ throw new CliError("validation_error", "--category and --assignee are for a task from a source; name a project task's people with tasks assign");
25235
+ return store.tasks.edit(id, {
25236
+ ...fields,
25237
+ ...times,
25238
+ ...options.status === void 0 ? {} : { status: options.status },
25239
+ ...options.agent === void 0 ? {} : { agent: options.agent === "none" ? null : options.agent },
25240
+ ...options.project === void 0 ? {} : { project: await canonicalProject(store, options.project) },
25241
+ ...options.type === void 0 ? {} : { type: options.type }
25242
+ }, authorOf(env), checkOf(options.revision));
25243
+ }
25244
+ if (options.status !== void 0 || options.agent !== void 0 || options.revision !== void 0 || options.project !== void 0 || options.type !== void 0)
25245
+ throw new CliError("validation_error", "--status, --agent, --revision, --project and --type are for a project task; close a task from a message with tasks close");
25246
+ if (options.priority !== void 0 || options.parent !== void 0)
25247
+ throw new CliError("validation_error", "--priority and --parent are for a task in a project");
25248
+ const assignees = options.assignee?.map((one2) => one2 === "sender" || one2 === "none" ? one2 : personRef(one2));
25249
+ const key = await selectAccount(store, options);
25250
+ return tasksService(storeOnlyDeps(store, key, { app: APP, env })).plan(id, {
25251
+ ...options.title === void 0 ? {} : { title: options.title },
25252
+ ...options.description === void 0 ? {} : { description: options.description },
25253
+ ...times,
25254
+ ...options.category === void 0 ? {} : { category: options.category },
25255
+ ...assignees === void 0 ? {} : { assignees: assignees.length === 1 && assignees[0] === "none" ? null : assignees }
25256
+ }, authorOf(env) === "owner" ? "owner" : "agent");
25257
+ }, "updateTask");
25258
+ var assignTask = /* @__PURE__ */ __name((store, env, id, person, role, revision) => store.tasks.assign(id, { to: personRef(person), role }, authorOf(env), checkOf(revision)), "assignTask");
25259
+ var unassignTask = /* @__PURE__ */ __name((store, env, id, person, role, revision) => store.tasks.unassign(id, { to: personRef(person), role }, authorOf(env), checkOf(revision)), "unassignTask");
25260
+ var moveTask = /* @__PURE__ */ __name((store, env, id, options) => {
25261
+ const { revision, ...move } = options;
25262
+ return store.tasks.move(id, move, authorOf(env), checkOf(revision));
25263
+ }, "moveTask");
25264
+ var commentTask = /* @__PURE__ */ __name((store, env, id, text3) => store.tasks.comment(id, text3, authorOf(env)), "commentTask");
25265
+ var taskHistory = /* @__PURE__ */ __name(async (store, id) => {
25266
+ const owner = (await store.people.owner())?.uid;
25267
+ return (await store.tasks.events(id)).map((event) => ({
25268
+ at: event.at,
25269
+ kind: event.kind,
25270
+ by: event.actor && {
25271
+ ref: `${event.actor.type}:${event.actor.id}`,
25272
+ name: event.actor.name,
25273
+ owner: event.actor.type === "person" && String(event.actor.id) === String(owner)
25274
+ },
25275
+ changes: event.changes
25276
+ }));
25277
+ }, "taskHistory");
25278
+
25379
25279
  // dist/tasks/command.js
25380
25280
  var revisionOf = /* @__PURE__ */ __name((value) => {
25381
25281
  const number2 = Number(value);