@wirecat/cli-memo 0.131.75 → 0.131.77

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 (224) hide show
  1. package/dist/actions/actions.d.ts +1 -0
  2. package/dist/actions/actions.d.ts.map +1 -1
  3. package/dist/actions/actions.js +3 -3
  4. package/dist/actions/actions.js.map +1 -1
  5. package/dist/actions/command.d.ts.map +1 -1
  6. package/dist/actions/command.js +3 -1
  7. package/dist/actions/command.js.map +1 -1
  8. package/dist/agents/command.d.ts.map +1 -1
  9. package/dist/agents/command.js +3 -2
  10. package/dist/agents/command.js.map +1 -1
  11. package/dist/agents/log.d.ts +1 -1
  12. package/dist/agents/log.d.ts.map +1 -1
  13. package/dist/agents/log.js +5 -4
  14. package/dist/agents/log.js.map +1 -1
  15. package/dist/bin/memo.js +2 -2
  16. package/dist/bin/memo.js.map +1 -1
  17. package/dist/bundle/{all-profiles-LUGN5BHP.js → all-profiles-4UWCPMRQ.js} +10 -8
  18. package/dist/bundle/{anthropic-W7JXDZPL.js → anthropic-HECHQVOK.js} +7 -5
  19. package/dist/bundle/{app-server-TRRARE66.js → app-server-GQEQWFYQ.js} +42 -40
  20. package/dist/bundle/auto-3O7JD27U.js +91 -0
  21. package/dist/bundle/{bun-S3JZIN4S.js → bun-IWGIAD7H.js} +2 -2
  22. package/dist/bundle/{bun-sqlite-X3WQN3CV.js → bun-sqlite-VJFM4TVN.js} +7 -5
  23. package/dist/bundle/{chunk-KDBAY5JZ.js → chunk-2DLCQ4AK.js} +1 -1
  24. package/dist/bundle/{chunk-W46O6RJ5.js → chunk-2IQWMWMC.js} +42 -130
  25. package/dist/bundle/{chunk-4O2MYFYC.js → chunk-3EPBPSP6.js} +1 -1
  26. package/dist/bundle/{chunk-KEBL3PY4.js → chunk-3QBRLN6T.js} +2 -2
  27. package/dist/bundle/{chunk-V7BDQIZS.js → chunk-3URQNBDV.js} +2 -2
  28. package/dist/bundle/{chunk-UU3OAPGO.js → chunk-4EFQOTNQ.js} +7 -7
  29. package/dist/bundle/{chunk-RZS24U4N.js → chunk-4VO2RJAE.js} +12 -10
  30. package/dist/bundle/{chunk-WKLF7CAM.js → chunk-5APYWW46.js} +34 -32
  31. package/dist/bundle/{chunk-VYCLOFPC.js → chunk-6A37YXAL.js} +6 -184
  32. package/dist/bundle/{chunk-346PWQJF.js → chunk-6RN34ZWU.js} +6 -6
  33. package/dist/bundle/{chunk-WZHCQ4VZ.js → chunk-6VISMU6R.js} +8 -8
  34. package/dist/bundle/{chunk-ZP2XI5DR.js → chunk-76T57Y3Q.js} +6 -6
  35. package/dist/bundle/{chunk-FGMFJUHR.js → chunk-7YALAAL4.js} +734 -374
  36. package/dist/bundle/{chunk-KA5MDFLU.js → chunk-A3QZXQI3.js} +1 -1
  37. package/dist/bundle/{chunk-4XI7S3PO.js → chunk-A54EZ6DV.js} +15 -15
  38. package/dist/bundle/{chunk-5RLCKP5E.js → chunk-AH6V2UJZ.js} +22 -18
  39. package/dist/bundle/{chunk-2EZFUIL4.js → chunk-BA6GHX5B.js} +27 -27
  40. package/dist/bundle/{chunk-E74VWHZ2.js → chunk-BFEXVALS.js} +1 -1
  41. package/dist/bundle/{chunk-XPSXVUZG.js → chunk-BNOSAHVH.js} +3 -3
  42. package/dist/bundle/{chunk-ZXW5FPH2.js → chunk-C3HS26N5.js} +1 -1
  43. package/dist/bundle/{chunk-VFKCZJFT.js → chunk-CFZZUGUD.js} +22 -22
  44. package/dist/bundle/{chunk-KYJBGCTC.js → chunk-CPKS7JKX.js} +2 -2
  45. package/dist/bundle/{chunk-7Y4HUYI3.js → chunk-D7KQYLAN.js} +8 -8
  46. package/dist/bundle/{chunk-LX3OSTBD.js → chunk-DE5BNDIA.js} +4 -4
  47. package/dist/bundle/{chunk-SJD4KTK2.js → chunk-DJYMK7EI.js} +4 -4
  48. package/dist/bundle/{chunk-EWRHTZD3.js → chunk-DNPE4LOZ.js} +11 -11
  49. package/dist/bundle/chunk-EXFRC4OT.js +106 -0
  50. package/dist/bundle/{chunk-XMHWGHID.js → chunk-EY46RMMS.js} +183 -158
  51. package/dist/bundle/{chunk-UIAGASGP.js → chunk-HFZHXP4U.js} +6 -6
  52. package/dist/bundle/{chunk-QYJJBE56.js → chunk-HKDUGTWQ.js} +3 -3
  53. package/dist/bundle/{chunk-VB4OLJHK.js → chunk-HWIKY7KF.js} +3 -3
  54. package/dist/bundle/{chunk-2QND7VJS.js → chunk-INXIJXU2.js} +7 -7
  55. package/dist/bundle/{chunk-OWUEEVF6.js → chunk-IYINNZQE.js} +13 -12
  56. package/dist/bundle/{chunk-YLYZNPAZ.js → chunk-JKLJM7EG.js} +2 -2
  57. package/dist/bundle/{chunk-6VMIMAZ2.js → chunk-JSGRDE5Q.js} +302 -298
  58. package/dist/bundle/{chunk-G45BLLDR.js → chunk-JTLPFUIQ.js} +4 -4
  59. package/dist/bundle/{chunk-4QGUBKN5.js → chunk-KTBPBMNR.js} +6 -6
  60. package/dist/bundle/{chunk-ZTZLAGZA.js → chunk-KYW7RWGE.js} +3 -3
  61. package/dist/bundle/{chunk-6I4DOBSD.js → chunk-LHVNZ25W.js} +13 -13
  62. package/dist/bundle/{chunk-SIQDO5DN.js → chunk-LO74ISD6.js} +4 -4
  63. package/dist/bundle/{chunk-XQ3RZU3J.js → chunk-M4MM4QUM.js} +1 -1
  64. package/dist/bundle/{chunk-6AOPUQTC.js → chunk-MRUE3BWX.js} +1 -1
  65. package/dist/bundle/{chunk-QKWM4VK4.js → chunk-MZHH5XMX.js} +2 -2
  66. package/dist/bundle/{chunk-SCYHDYLI.js → chunk-NGWUFB4K.js} +1 -1
  67. package/dist/bundle/{chunk-NR633L2N.js → chunk-OAWNQZ3V.js} +4 -4
  68. package/dist/bundle/{chunk-SIOPF2UG.js → chunk-OB3OPV55.js} +6 -6
  69. package/dist/bundle/{chunk-E2PSOSTN.js → chunk-OQSIFLZS.js} +2 -2
  70. package/dist/bundle/{chunk-4KDORB7C.js → chunk-PPARTGFE.js} +10 -10
  71. package/dist/bundle/{chunk-YB4KGUXY.js → chunk-QNJ6O6J4.js} +3 -3
  72. package/dist/bundle/{chunk-GFVSZY4J.js → chunk-S5T4SO7I.js} +8 -2
  73. package/dist/bundle/{chunk-YDTGYYOR.js → chunk-SHO3T3F2.js} +4 -4
  74. package/dist/bundle/{chunk-6FTZ53TT.js → chunk-TFXKS2WG.js} +1 -1
  75. package/dist/bundle/{chunk-5CTOWPOL.js → chunk-TIHQFMH2.js} +12 -10
  76. package/dist/bundle/{chunk-XQHOMQNZ.js → chunk-TXXKLYJQ.js} +4 -4
  77. package/dist/bundle/{chunk-ZISVFVQU.js → chunk-UD5JUJES.js} +365 -364
  78. package/dist/bundle/{chunk-KUFOM3SB.js → chunk-UDRKGCDS.js} +2 -2
  79. package/dist/bundle/chunk-UIS44ZMF.js +185 -0
  80. package/dist/bundle/{chunk-AOHT5FNX.js → chunk-VIY77EDM.js} +48 -48
  81. package/dist/bundle/{chunk-MPZBV5RL.js → chunk-VMTTWF2M.js} +8 -8
  82. package/dist/bundle/{chunk-IQIM4UC7.js → chunk-W36BMC6F.js} +5 -5
  83. package/dist/bundle/{chunk-JINEHQ2T.js → chunk-WZZ426CJ.js} +99 -84
  84. package/dist/bundle/chunk-X2SA73EE.js +200 -0
  85. package/dist/bundle/{chunk-BDVM5652.js → chunk-XLZPP5MB.js} +1 -1
  86. package/dist/bundle/{chunk-LPGE6ACC.js → chunk-YABNPKKQ.js} +2 -2
  87. package/dist/bundle/{chunk-ZL63GL3Y.js → chunk-YZ4J67GU.js} +3 -3
  88. package/dist/bundle/{chunk-C6MWOBEL.js → chunk-ZPB3VTS7.js} +22 -12
  89. package/dist/bundle/{chunk-W64FO6DD.js → chunk-ZPPMGXER.js} +400 -37
  90. package/dist/bundle/command-contract-SEDOYJIJ.js +34 -0
  91. package/dist/bundle/{command-server-entry-XVUPTSSH.js → command-server-entry-TQBKNSM3.js} +71 -53
  92. package/dist/bundle/{decode-METZOSMG.js → decode-VFRSEIBD.js} +7 -5
  93. package/dist/bundle/{dispatch-PHB2Y6ZL.js → dispatch-N73TJNYM.js} +3 -3
  94. package/dist/bundle/{echarts-EBSP4VCK.js → echarts-DP2GC2C6.js} +2 -2
  95. package/dist/bundle/{embed-GVVU7N7W.js → embed-BIINGRNY.js} +8 -6
  96. package/dist/bundle/{embedder-6BZOYAXV.js → embedder-2AUO2PHQ.js} +11 -9
  97. package/dist/bundle/entry-APUFP74B.js +23 -0
  98. package/dist/bundle/entry-LGJ2Y7AS.js +78 -0
  99. package/dist/bundle/failure-5QSMH2CD.js +71 -0
  100. package/dist/bundle/{failure-OBT7CUVW.js → failure-IPHFR3KW.js} +3 -2
  101. package/dist/bundle/{first-run-HQ4GA4EF.js → first-run-7UMKRQL7.js} +11 -9
  102. package/dist/bundle/first-screen-H5CQSLIX.js +32 -0
  103. package/dist/bundle/{instructions-VDKK3Y5Z.js → instructions-WDKCHEG6.js} +1 -1
  104. package/dist/bundle/mcp-3HKOGYHL.js +92 -0
  105. package/dist/bundle/memo.js +9 -56
  106. package/dist/bundle/{node-HWGZYNUX.js → node-QBL3F2VF.js} +2 -2
  107. package/dist/bundle/{node-sqlite-PSYENWGS.js → node-sqlite-WFKC73E5.js} +8 -6
  108. package/dist/bundle/{oauth-TQGMUJK2.js → oauth-4PT7N4SE.js} +9 -7
  109. package/dist/bundle/{open-KDDJDKCE.js → open-I7XENSGI.js} +7 -5
  110. package/dist/bundle/openai-DUSBTUFI.js +26 -0
  111. package/dist/bundle/{process-APNTXJJE.js → process-TVXEHAK6.js} +1 -1
  112. package/dist/bundle/{program-OGDARQTX.js → program-3X4EPBEW.js} +587 -234
  113. package/dist/bundle/{prompt-BMBZCLGF.js → prompt-QRYXTON7.js} +7 -5
  114. package/dist/bundle/{recognize-3SEY2MAR.js → recognize-ZLDPIN36.js} +6 -4
  115. package/dist/bundle/{remote-ODH54UXO.js → remote-3GRP5YE3.js} +9 -7
  116. package/dist/bundle/{rerank-JQHBNTUK.js → rerank-6B2FI6LN.js} +9 -7
  117. package/dist/bundle/serve-ZP3TEANT.js +24 -0
  118. package/dist/bundle/{server-ADPO4V4B.js → server-3SJJNNSX.js} +63 -59
  119. package/dist/bundle/server-72VZYABL.js +50 -0
  120. package/dist/bundle/server-UY47EXPQ.js +64 -0
  121. package/dist/bundle/{state-M3VGXSV4.js → state-JDH2X2CY.js} +8 -6
  122. package/dist/bundle/{store-GSZAXU3A.js → store-FDNYGJUF.js} +14 -12
  123. package/dist/bundle/store-maintenance-command-5LFS45JM.js +49 -0
  124. package/dist/bundle/update-257J2SPM.js +74 -0
  125. package/dist/digest/backfill.d.ts.map +1 -1
  126. package/dist/digest/backfill.js +2 -1
  127. package/dist/digest/backfill.js.map +1 -1
  128. package/dist/digest/digest-commands.d.ts.map +1 -1
  129. package/dist/digest/digest-commands.js +2 -1
  130. package/dist/digest/digest-commands.js.map +1 -1
  131. package/dist/doctor/command.d.ts.map +1 -1
  132. package/dist/doctor/command.js +2 -1
  133. package/dist/doctor/command.js.map +1 -1
  134. package/dist/examples.d.ts.map +1 -1
  135. package/dist/examples.js +13 -1
  136. package/dist/examples.js.map +1 -1
  137. package/dist/exit-code.d.ts +7 -0
  138. package/dist/exit-code.d.ts.map +1 -0
  139. package/dist/exit-code.js +19 -0
  140. package/dist/exit-code.js.map +1 -0
  141. package/dist/facts/command.d.ts.map +1 -1
  142. package/dist/facts/command.js +3 -2
  143. package/dist/facts/command.js.map +1 -1
  144. package/dist/facts/fact.d.ts +1 -1
  145. package/dist/facts/fact.d.ts.map +1 -1
  146. package/dist/facts/fact.js +3 -3
  147. package/dist/facts/fact.js.map +1 -1
  148. package/dist/mcp/catalogue.d.ts +3 -0
  149. package/dist/mcp/catalogue.d.ts.map +1 -1
  150. package/dist/mcp/catalogue.js +1 -0
  151. package/dist/mcp/catalogue.js.map +1 -1
  152. package/dist/memories/command.d.ts.map +1 -1
  153. package/dist/memories/command.js +3 -2
  154. package/dist/memories/command.js.map +1 -1
  155. package/dist/memories/memory.d.ts +1 -1
  156. package/dist/memories/memory.d.ts.map +1 -1
  157. package/dist/memories/memory.js +2 -2
  158. package/dist/memories/memory.js.map +1 -1
  159. package/dist/page.d.ts +14 -5
  160. package/dist/page.d.ts.map +1 -1
  161. package/dist/page.js +11 -5
  162. package/dist/page.js.map +1 -1
  163. package/dist/program.d.ts +3 -1
  164. package/dist/program.d.ts.map +1 -1
  165. package/dist/program.js +7 -1
  166. package/dist/program.js.map +1 -1
  167. package/dist/reasons.d.ts.map +1 -1
  168. package/dist/reasons.js +6 -0
  169. package/dist/reasons.js.map +1 -1
  170. package/dist/records/import.d.ts.map +1 -1
  171. package/dist/records/import.js +60 -5
  172. package/dist/records/import.js.map +1 -1
  173. package/dist/records/input.d.ts +6 -2
  174. package/dist/records/input.d.ts.map +1 -1
  175. package/dist/records/input.js +87 -3
  176. package/dist/records/input.js.map +1 -1
  177. package/dist/run/entry.d.ts +7 -0
  178. package/dist/run/entry.d.ts.map +1 -0
  179. package/dist/run/entry.js +62 -0
  180. package/dist/run/entry.js.map +1 -0
  181. package/dist/run/import.d.ts.map +1 -1
  182. package/dist/run/import.js +2 -1
  183. package/dist/run/import.js.map +1 -1
  184. package/dist/sources/command.d.ts.map +1 -1
  185. package/dist/sources/command.js +55 -4
  186. package/dist/sources/command.js.map +1 -1
  187. package/dist/sources/read.d.ts +29 -2
  188. package/dist/sources/read.d.ts.map +1 -1
  189. package/dist/sources/read.js +67 -5
  190. package/dist/sources/read.js.map +1 -1
  191. package/dist/sources/readers/ai-model.d.ts +4 -0
  192. package/dist/sources/readers/ai-model.d.ts.map +1 -0
  193. package/dist/sources/readers/ai-model.js +74 -0
  194. package/dist/sources/readers/ai-model.js.map +1 -0
  195. package/dist/sources/readers/index.d.ts +1 -0
  196. package/dist/sources/readers/index.d.ts.map +1 -1
  197. package/dist/sources/readers/index.js +3 -1
  198. package/dist/sources/readers/index.js.map +1 -1
  199. package/dist/sources/readers/keys.js +1 -1
  200. package/dist/sources/readers/keys.js.map +1 -1
  201. package/dist/sources/readers/types.d.ts +5 -2
  202. package/dist/sources/readers/types.d.ts.map +1 -1
  203. package/dist/sources/readers/types.js +1 -1
  204. package/dist/sources/readers/types.js.map +1 -1
  205. package/dist/sources/suggest-command.d.ts.map +1 -1
  206. package/dist/sources/suggest-command.js +16 -5
  207. package/dist/sources/suggest-command.js.map +1 -1
  208. package/dist/version.d.ts +1 -1
  209. package/dist/version.js +1 -1
  210. package/package.json +2 -2
  211. package/dist/bundle/auto-AQAKW55Z.js +0 -89
  212. package/dist/bundle/chunk-XPCTY6XV.js +0 -116
  213. package/dist/bundle/command-contract-QQG343ZQ.js +0 -32
  214. package/dist/bundle/entry-TBOYUMWB.js +0 -21
  215. package/dist/bundle/failure-EKMEAYZH.js +0 -69
  216. package/dist/bundle/first-screen-6T65PQ37.js +0 -30
  217. package/dist/bundle/mcp-DEY765VA.js +0 -90
  218. package/dist/bundle/openai-QPGCUM4T.js +0 -24
  219. package/dist/bundle/serve-C22ZONSM.js +0 -22
  220. package/dist/bundle/server-3UX245DY.js +0 -62
  221. package/dist/bundle/server-6G5XF3V5.js +0 -48
  222. package/dist/bundle/store-maintenance-command-QMTALGSQ.js +0 -47
  223. package/dist/bundle/update-HDJ23IV5.js +0 -72
  224. /package/dist/bundle/{chunk-IXSUVHW6.js → chunk-6AALVDEA.js} +0 -0
@@ -6,18 +6,18 @@ import {
6
6
  autoState,
7
7
  lastAutoRun,
8
8
  recordAutoRun
9
- } from "./chunk-ZP2XI5DR.js";
9
+ } from "./chunk-76T57Y3Q.js";
10
10
  import {
11
11
  installer,
12
12
  latest,
13
13
  upgradeCommand
14
- } from "./chunk-2QND7VJS.js";
14
+ } from "./chunk-INXIJXU2.js";
15
15
  import {
16
16
  mcpOwnerAllowed,
17
17
  memoLevels,
18
18
  readOnlyAvailability,
19
19
  refuseWritesUnderLock
20
- } from "./chunk-346PWQJF.js";
20
+ } from "./chunk-6RN34ZWU.js";
21
21
  import {
22
22
  answers,
23
23
  atDetail,
@@ -29,18 +29,21 @@ import {
29
29
  trackAnswers,
30
30
  wholeList,
31
31
  withStore
32
- } from "./chunk-7Y4HUYI3.js";
32
+ } from "./chunk-D7KQYLAN.js";
33
33
  import {
34
34
  ATTACHMENT_CHARS,
35
35
  DIALECTS,
36
36
  MEMO_SETTINGS,
37
37
  NOTE_EXTENSIONS,
38
38
  OWED_DAYS,
39
+ TABLE_RECORD_TYPES,
40
+ TableError,
39
41
  attachmentsText,
40
42
  bulkTriage,
41
43
  configPath,
42
44
  decisionPolicy,
43
45
  dialectOf,
46
+ envelopeOfCsv,
44
47
  grantedLevel,
45
48
  hitText,
46
49
  inspectConfig,
@@ -56,20 +59,26 @@ import {
56
59
  noteFiles,
57
60
  rawConfig,
58
61
  readMemoId,
62
+ recordColumns,
63
+ recordTemplate,
59
64
  scheduleLimits,
60
65
  searchMail,
61
66
  showMail,
62
67
  unsetConfigKey,
63
68
  updateConfig
64
- } from "./chunk-W64FO6DD.js";
69
+ } from "./chunk-ZPPMGXER.js";
65
70
  import "./chunk-QP3KNC5D.js";
66
- import "./chunk-YB4KGUXY.js";
67
- import "./chunk-4KDORB7C.js";
68
- import "./chunk-NR633L2N.js";
71
+ import "./chunk-QNJ6O6J4.js";
72
+ import "./chunk-PPARTGFE.js";
73
+ import "./chunk-OAWNQZ3V.js";
69
74
  import {
70
75
  errorObject,
71
76
  recognisable
72
- } from "./chunk-5CTOWPOL.js";
77
+ } from "./chunk-TIHQFMH2.js";
78
+ import {
79
+ provideTerminal,
80
+ terminalOf
81
+ } from "./chunk-BPGYTJNB.js";
73
82
  import {
74
83
  AGENT_INPUT_MAX_CHARS,
75
84
  DISCOVERY_DESCRIPTIONS,
@@ -80,6 +89,10 @@ import {
80
89
  addMeetingPreparationCommand,
81
90
  advancePastSkipped,
82
91
  agentSchedule,
92
+ aiImageReader,
93
+ aiLeavesComputer,
94
+ aiSettingPath,
95
+ aiTextReader,
83
96
  backfillScheduleRun,
84
97
  baseStagesCommand,
85
98
  calendarOf,
@@ -112,6 +125,7 @@ import {
112
125
  projectStatusSchema,
113
126
  projectStatusText,
114
127
  projectWindowOf,
128
+ readAiSetting,
115
129
  readMailFindingsJson,
116
130
  readSchedule,
117
131
  recordRuns,
@@ -137,34 +151,34 @@ import {
137
151
  thisMachine,
138
152
  withSqliteSidecars,
139
153
  writeSchedule
140
- } from "./chunk-FGMFJUHR.js";
141
- import "./chunk-E74VWHZ2.js";
142
- import "./chunk-KA5MDFLU.js";
143
- import "./chunk-BDVM5652.js";
154
+ } from "./chunk-7YALAAL4.js";
155
+ import "./chunk-BFEXVALS.js";
156
+ import "./chunk-A3QZXQI3.js";
157
+ import "./chunk-XLZPP5MB.js";
144
158
  import {
145
159
  allHitItem,
146
160
  coverageGaps,
147
161
  messageHitItem,
148
162
  noteHitItem,
149
163
  shownOf
150
- } from "./chunk-VFKCZJFT.js";
151
- import "./chunk-YLYZNPAZ.js";
164
+ } from "./chunk-CFZZUGUD.js";
165
+ import "./chunk-JKLJM7EG.js";
152
166
  import {
153
167
  REASONS as REASONS2,
154
168
  SKILL_TARGETS,
155
169
  skillCommand,
156
170
  skillPath,
157
171
  skillVersion
158
- } from "./chunk-C6MWOBEL.js";
159
- import "./chunk-LX3OSTBD.js";
172
+ } from "./chunk-ZPB3VTS7.js";
173
+ import "./chunk-DE5BNDIA.js";
160
174
  import {
161
175
  recoveryNotes,
162
176
  storeInfo,
163
177
  storeRecoveryCheck,
164
178
  storeRecoveryRun,
165
179
  storeSummary
166
- } from "./chunk-AOHT5FNX.js";
167
- import "./chunk-4XI7S3PO.js";
180
+ } from "./chunk-VIY77EDM.js";
181
+ import "./chunk-A54EZ6DV.js";
168
182
  import {
169
183
  LIST_QUERY_GUIDE,
170
184
  RESOURCES_SEARCHED,
@@ -209,6 +223,7 @@ import {
209
223
  moveGroupMember,
210
224
  nativeField,
211
225
  nativeTerms,
226
+ ocrImage,
212
227
  organizationContext,
213
228
  parseProposalIds,
214
229
  personBusiness,
@@ -240,31 +255,31 @@ import {
240
255
  timeLimit,
241
256
  typedQuery,
242
257
  withQuery
243
- } from "./chunk-6VMIMAZ2.js";
258
+ } from "./chunk-JSGRDE5Q.js";
244
259
  import {
245
260
  readBoundedUtf8File,
246
261
  writeFileAtomic
247
- } from "./chunk-6I4DOBSD.js";
262
+ } from "./chunk-LHVNZ25W.js";
248
263
  import {
249
264
  releaseLock,
250
265
  servingProfiles,
251
266
  takeLock
252
- } from "./chunk-ZL63GL3Y.js";
253
- import "./chunk-ZTZLAGZA.js";
267
+ } from "./chunk-YZ4J67GU.js";
268
+ import "./chunk-KYW7RWGE.js";
254
269
  import {
255
270
  commandsText,
256
271
  inSection,
257
272
  installHelp
258
- } from "./chunk-WZHCQ4VZ.js";
273
+ } from "./chunk-6VISMU6R.js";
259
274
  import "./chunk-HTQTIKWP.js";
260
- import "./chunk-EWRHTZD3.js";
275
+ import "./chunk-DNPE4LOZ.js";
261
276
  import {
262
277
  isNewer
263
- } from "./chunk-KEBL3PY4.js";
278
+ } from "./chunk-3QBRLN6T.js";
264
279
  import "./chunk-OYKQX4H3.js";
265
- import "./chunk-OWUEEVF6.js";
266
- import "./chunk-XPSXVUZG.js";
267
- import "./chunk-E2PSOSTN.js";
280
+ import "./chunk-IYINNZQE.js";
281
+ import "./chunk-BNOSAHVH.js";
282
+ import "./chunk-OQSIFLZS.js";
268
283
  import {
269
284
  EVIDENCE_FINDINGS_KIND,
270
285
  MAIL_FINDINGS_KIND,
@@ -304,29 +319,25 @@ import {
304
319
  refLabel,
305
320
  storedProfilesFor,
306
321
  writesWithOf
307
- } from "./chunk-ZISVFVQU.js";
308
- import "./chunk-MPZBV5RL.js";
309
- import "./chunk-XQ3RZU3J.js";
310
- import "./chunk-SJD4KTK2.js";
311
- import "./chunk-SIOPF2UG.js";
312
- import {
313
- provideTerminal,
314
- terminalOf
315
- } from "./chunk-BPGYTJNB.js";
322
+ } from "./chunk-UD5JUJES.js";
323
+ import "./chunk-VMTTWF2M.js";
324
+ import "./chunk-M4MM4QUM.js";
325
+ import "./chunk-DJYMK7EI.js";
326
+ import "./chunk-OB3OPV55.js";
316
327
  import {
317
328
  APP,
318
329
  REASONS,
319
330
  STORE_CLIENT,
320
331
  VERSION
321
- } from "./chunk-GFVSZY4J.js";
332
+ } from "./chunk-S5T4SO7I.js";
322
333
  import "./chunk-NT5IOEEK.js";
323
334
  import "./chunk-D72URWJE.js";
324
- import "./chunk-XPCTY6XV.js";
325
- import "./chunk-6FTZ53TT.js";
326
- import "./chunk-QYJJBE56.js";
327
- import "./chunk-UIAGASGP.js";
328
- import "./chunk-SCYHDYLI.js";
329
- import "./chunk-G45BLLDR.js";
335
+ import "./chunk-UIS44ZMF.js";
336
+ import "./chunk-TFXKS2WG.js";
337
+ import "./chunk-HKDUGTWQ.js";
338
+ import "./chunk-HFZHXP4U.js";
339
+ import "./chunk-NGWUFB4K.js";
340
+ import "./chunk-JTLPFUIQ.js";
330
341
  import {
331
342
  Command,
332
343
  DEFAULT_TEXT_MODEL,
@@ -366,11 +377,11 @@ import {
366
377
  snakeKeys,
367
378
  textModels,
368
379
  textModelsFile
369
- } from "./chunk-XMHWGHID.js";
370
- import "./chunk-UU3OAPGO.js";
371
- import "./chunk-6AOPUQTC.js";
372
- import "./chunk-XQHOMQNZ.js";
373
- import "./chunk-KUFOM3SB.js";
380
+ } from "./chunk-EY46RMMS.js";
381
+ import "./chunk-4EFQOTNQ.js";
382
+ import "./chunk-MRUE3BWX.js";
383
+ import "./chunk-TXXKLYJQ.js";
384
+ import "./chunk-UDRKGCDS.js";
374
385
  import {
375
386
  CATALOG_KINDS,
376
387
  CATEGORIES,
@@ -443,15 +454,15 @@ import {
443
454
  timezoneOf,
444
455
  validateQuery,
445
456
  walkQuery
446
- } from "./chunk-JINEHQ2T.js";
447
- import "./chunk-VB4OLJHK.js";
448
- import "./chunk-4QGUBKN5.js";
457
+ } from "./chunk-WZZ426CJ.js";
458
+ import "./chunk-HWIKY7KF.js";
459
+ import "./chunk-KTBPBMNR.js";
449
460
  import {
450
461
  sharedModelsDirectory
451
- } from "./chunk-SIQDO5DN.js";
462
+ } from "./chunk-LO74ISD6.js";
452
463
  import {
453
464
  storePath
454
- } from "./chunk-LPGE6ACC.js";
465
+ } from "./chunk-YABNPKKQ.js";
455
466
  import "./chunk-G5GW3FFJ.js";
456
467
  import {
457
468
  Credentials,
@@ -466,7 +477,9 @@ import {
466
477
  readBatchInput,
467
478
  resolvePaths,
468
479
  writeSecurely
469
- } from "./chunk-W46O6RJ5.js";
480
+ } from "./chunk-2IQWMWMC.js";
481
+ import "./chunk-EXFRC4OT.js";
482
+ import "./chunk-X2SA73EE.js";
470
483
  import {
471
484
  MAX_NEXT_STEPS,
472
485
  array,
@@ -488,13 +501,13 @@ import {
488
501
  trim,
489
502
  union,
490
503
  unknown
491
- } from "./chunk-VYCLOFPC.js";
504
+ } from "./chunk-6A37YXAL.js";
492
505
  import "./chunk-Y5E2WNWB.js";
493
506
  import {
494
507
  CliError,
495
508
  errorCodes,
496
509
  isCliError
497
- } from "./chunk-2EZFUIL4.js";
510
+ } from "./chunk-BA6GHX5B.js";
498
511
  import {
499
512
  __name
500
513
  } from "./chunk-ZVVMGPBJ.js";
@@ -516,16 +529,16 @@ var fromTerminal = /* @__PURE__ */ __name(async (question) => {
516
529
  } catch {
517
530
  return null;
518
531
  }
519
- const reader = createInterface({ input, output: process.stderr, terminal: true });
532
+ const reader2 = createInterface({ input, output: process.stderr, terminal: true });
520
533
  try {
521
534
  return await new Promise((resolve6, reject) => {
522
535
  const cancel = /* @__PURE__ */ __name(() => reject(new CliError("cancelled", "cancelled \u2014 nothing was done")), "cancel");
523
- reader.once("SIGINT", cancel);
524
- reader.once("close", cancel);
525
- reader.question(question, resolve6);
536
+ reader2.once("SIGINT", cancel);
537
+ reader2.once("close", cancel);
538
+ reader2.question(question, resolve6);
526
539
  });
527
540
  } finally {
528
- reader.close();
541
+ reader2.close();
529
542
  input.destroy();
530
543
  }
531
544
  }, "fromTerminal");
@@ -874,7 +887,7 @@ var readScope = /* @__PURE__ */ __name((command, help = ONE_ACCOUNT_HELP) => sou
874
887
  var writeScope = /* @__PURE__ */ __name((command, help) => writeOptions(command, help).option("--json", "print JSON; --json=id,title keeps only those fields"), "writeScope");
875
888
  var jsonOption = /* @__PURE__ */ __name((command, fields = "ref,title") => command.option("--json", `print JSON; --json=${fields} keeps only those fields`), "jsonOption");
876
889
 
877
- // node_modules/.pnpm/@wirecat+cli-core@0.624.0_@wirecat+cli-base@0.95.0_commander@15.0.0_esbuild@0.28.2_type_845871b12d72ec55150c07203d8cbfbb/node_modules/@wirecat/cli-core/dist/mail/sender-scores.js
890
+ // node_modules/.pnpm/@wirecat+cli-core@0.628.0_@wirecat+cli-base@0.95.0_commander@15.0.0_esbuild@0.28.2_type_ae6a34897f184099b1a87c0d4b483e54/node_modules/@wirecat/cli-core/dist/mail/sender-scores.js
878
891
  var SCORED = "mail_sender_scores";
879
892
  var DAY = 864e5;
880
893
  var RECENT = 2 * 365 * DAY;
@@ -890,7 +903,7 @@ var demotedSenders = /* @__PURE__ */ __name(async (store) => {
890
903
  return senders;
891
904
  }, "demotedSenders");
892
905
 
893
- // node_modules/.pnpm/@wirecat+cli-core@0.624.0_@wirecat+cli-base@0.95.0_commander@15.0.0_esbuild@0.28.2_type_845871b12d72ec55150c07203d8cbfbb/node_modules/@wirecat/cli-core/dist/mail/sync.js
906
+ // node_modules/.pnpm/@wirecat+cli-core@0.628.0_@wirecat+cli-base@0.95.0_commander@15.0.0_esbuild@0.28.2_type_ae6a34897f184099b1a87c0d4b483e54/node_modules/@wirecat/cli-core/dist/mail/sync.js
894
907
  var DAY2 = 864e5;
895
908
  var EDGE = 2 * DAY2;
896
909
 
@@ -1293,13 +1306,18 @@ var decideOne = /* @__PURE__ */ __name(async (store, env, id, decision) => {
1293
1306
  }, "decideOne");
1294
1307
 
1295
1308
  // dist/page.js
1296
- var pageOf = /* @__PURE__ */ __name(async (command, limit, read, { fallback = 100, cap = 500 } = {}) => {
1309
+ var pageOf = /* @__PURE__ */ __name(async (command, limit, read, { fallback = 100, cap = 500, page, args, shape = /* @__PURE__ */ __name((rows) => rows, "shape") } = {}) => {
1297
1310
  const wanted = Math.min(limit ?? fallback, cap);
1298
- const rows = await read(Math.min(wanted + 1, cap));
1311
+ const offset = ((page ?? 1) - 1) * wanted;
1312
+ const rows = await read(Math.min(wanted + 1, cap), offset);
1313
+ const full = rows.length === cap && wanted === cap;
1314
+ const more = rows.length > wanted || full && (page === void 0 || (await read(1, offset + cap)).length > 0);
1299
1315
  return listAnswer(command, {
1300
- items: rows.slice(0, wanted),
1316
+ items: await shape(rows.slice(0, wanted)),
1301
1317
  limit: wanted,
1302
- has_more: rows.length > wanted || rows.length === cap
1318
+ has_more: more,
1319
+ ...page === void 0 ? {} : { page },
1320
+ ...args === void 0 ? {} : { args }
1303
1321
  });
1304
1322
  }, "pageOf");
1305
1323
 
@@ -1461,8 +1479,8 @@ var actionItems = /* @__PURE__ */ __name(async (store, actions, { brief = false
1461
1479
  }, "actionItems");
1462
1480
  var listActions = /* @__PURE__ */ __name((store, query, limit, options = {}) => {
1463
1481
  const status = queryTerms(query, ACTION_QUERY, "actions list").get("status");
1464
- const { keep: keep2 = /* @__PURE__ */ __name(async (rows) => rows, "keep"), ...shown3 } = options;
1465
- return pageOf("actions list", limit, async (most) => actionItems(store, await keep2(await store.proposedActions.list({ limit: most, ...status === void 0 ? {} : { status } })), shown3));
1482
+ const { keep: keep2 = /* @__PURE__ */ __name(async (rows) => rows, "keep"), page, ...shown3 } = options;
1483
+ return pageOf("actions list", limit, (most, offset) => store.proposedActions.list({ limit: most, offset, ...status === void 0 ? {} : { status } }), { page, args: { query: typedQuery(query) }, shape: /* @__PURE__ */ __name(async (rows) => actionItems(store, await keep2(rows), shown3), "shape") });
1466
1484
  }, "listActions");
1467
1485
  var showAction = /* @__PURE__ */ __name(async (store, id) => (await actionItems(store, [await store.proposedActions.get(id)]))[0], "showAction");
1468
1486
  var BATCHES = {
@@ -1534,8 +1552,9 @@ var actionsCommand = /* @__PURE__ */ __name((program, streams, env) => {
1534
1552
  const key = await writeAccount(store, env, { account: account2 }, (text3) => streams.diagnostic(text3));
1535
1553
  return itemAnswer(await propose(store, env, { ...options, ...key, kind }, by));
1536
1554
  }));
1537
- withQuery(annotate(actions.command("list"), { effects: LOCAL_READ, output: { entity: "proposed_action" } }).description("proposed actions, newest first"), ACTION_QUERY).option("--limit <n>", "most actions, up to 500", positive, 100).option("--brief", "without each findings batch's cited sources").option("--json", "print JSON; --json=id,title keeps only those fields").action((words, options) => run(options.json, async (store) => stripped(store, env, await listActions(store, words, options.limit, {
1555
+ withQuery(annotate(actions.command("list"), { effects: LOCAL_READ, output: { entity: "proposed_action" } }).description("proposed actions, newest first"), ACTION_QUERY).option("--limit <n>", "most actions on a page, up to 500", positive, 100).option("--page <n>", "which page, from 1", positive, 1).option("--brief", "without each findings batch's cited sources").option("--json", "print JSON; --json=id,title keeps only those fields").action((words, options) => run(options.json, async (store) => stripped(store, env, await listActions(store, words, options.limit, {
1538
1556
  brief: options.brief === true,
1557
+ page: options.page,
1539
1558
  keep: /* @__PURE__ */ __name((rows) => actionsIn(store, env, rows), "keep")
1540
1559
  }))));
1541
1560
  annotate(actions.command("show"), { effects: LOCAL_READ }).description("one proposed action; a findings batch with its fingerprint and sources").argument("<id>", "the action's id, as actions list gives it").option("--json", "print JSON; --json=id,title keeps only those fields").action((id, options) => run(options.json, async (store) => {
@@ -1575,22 +1594,23 @@ var AGENT_LOG_QUERY = {
1575
1594
  termField("agent", "kw", "agent:tg-mcp", { relation: "the calls of this agent, as actor.name names it" })
1576
1595
  ]
1577
1596
  };
1578
- var listAgentActions = /* @__PURE__ */ __name((store, query, limit) => {
1597
+ var listAgentActions = /* @__PURE__ */ __name((store, query, limit, page) => {
1579
1598
  const terms2 = queryTerms(query, AGENT_LOG_QUERY, "agents list");
1580
1599
  const tool = terms2.get("tool");
1581
1600
  const agent = terms2.get("agent");
1582
- return pageOf("agents list", limit, (most) => store.agentActions.list({
1601
+ return pageOf("agents list", limit, (most, offset) => store.agentActions.list({
1583
1602
  ...tool === void 0 ? {} : { tool },
1584
1603
  ...agent === void 0 ? {} : { agent },
1585
- limit: most
1586
- }));
1604
+ limit: most,
1605
+ offset
1606
+ }), { page, args: { query: typedQuery(query) } });
1587
1607
  }, "listAgentActions");
1588
1608
 
1589
1609
  // dist/agents/command.js
1590
1610
  var agentsCommand = /* @__PURE__ */ __name((program, streams, env) => {
1591
1611
  const { run } = answers(program, streams, env);
1592
1612
  const agents = program.command("agents").description("what agents did through the MCP servers that share the store");
1593
- 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((words, options) => run(options.json, (store) => listAgentActions(store, words, options.limit)));
1613
+ 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 on a page, up to 500", positive, 100).option("--page <n>", "which page, from 1", positive, 1).option("--json", "print JSON; --json=id,title keeps only those fields").action((words, options) => run(options.json, (store) => listAgentActions(store, words, options.limit, options.page)));
1594
1614
  }, "agentsCommand");
1595
1615
 
1596
1616
  // dist/refs.js
@@ -2328,7 +2348,7 @@ import { createHash } from "node:crypto";
2328
2348
  import { existsSync, readFileSync as readFileSync2, statSync } from "node:fs";
2329
2349
  import { basename, extname, relative, sep } from "node:path";
2330
2350
 
2331
- // node_modules/.pnpm/@wirecat+cli-core@0.624.0_@wirecat+cli-base@0.95.0_commander@15.0.0_esbuild@0.28.2_type_845871b12d72ec55150c07203d8cbfbb/node_modules/@wirecat/cli-core/dist/services/documents/extraction.js
2351
+ // node_modules/.pnpm/@wirecat+cli-core@0.628.0_@wirecat+cli-base@0.95.0_commander@15.0.0_esbuild@0.28.2_type_ae6a34897f184099b1a87c0d4b483e54/node_modules/@wirecat/cli-core/dist/services/documents/extraction.js
2332
2352
  var Proposal = object({
2333
2353
  kind: picklist(["summary", "digest", "fact", "preference"]),
2334
2354
  body: pipe(string(), trim(), minLength(1), maxLength(15e3)),
@@ -2336,13 +2356,13 @@ var Proposal = object({
2336
2356
  });
2337
2357
  var Proposals = object({ items: pipe(array(Proposal), maxLength(20)) });
2338
2358
 
2339
- // node_modules/.pnpm/@wirecat+cli-core@0.624.0_@wirecat+cli-base@0.95.0_commander@15.0.0_esbuild@0.28.2_type_845871b12d72ec55150c07203d8cbfbb/node_modules/@wirecat/cli-core/dist/services/documents/mirrors.js
2359
+ // node_modules/.pnpm/@wirecat+cli-core@0.628.0_@wirecat+cli-base@0.95.0_commander@15.0.0_esbuild@0.28.2_type_ae6a34897f184099b1a87c0d4b483e54/node_modules/@wirecat/cli-core/dist/services/documents/mirrors.js
2340
2360
  var ID = pipe(string(), regex(/^[A-Za-z0-9_-]{1,200}$/));
2341
2361
 
2342
- // node_modules/.pnpm/@wirecat+cli-core@0.624.0_@wirecat+cli-base@0.95.0_commander@15.0.0_esbuild@0.28.2_type_845871b12d72ec55150c07203d8cbfbb/node_modules/@wirecat/cli-core/dist/services/documents/sync.js
2362
+ // node_modules/.pnpm/@wirecat+cli-core@0.628.0_@wirecat+cli-base@0.95.0_commander@15.0.0_esbuild@0.28.2_type_ae6a34897f184099b1a87c0d4b483e54/node_modules/@wirecat/cli-core/dist/services/documents/sync.js
2343
2363
  var MAX_PICTURE_BYTES = 25 * 1024 * 1024;
2344
2364
 
2345
- // node_modules/.pnpm/@wirecat+cli-core@0.624.0_@wirecat+cli-base@0.95.0_commander@15.0.0_esbuild@0.28.2_type_845871b12d72ec55150c07203d8cbfbb/node_modules/@wirecat/cli-core/dist/fetch/addresses.js
2365
+ // node_modules/.pnpm/@wirecat+cli-core@0.628.0_@wirecat+cli-base@0.95.0_commander@15.0.0_esbuild@0.28.2_type_ae6a34897f184099b1a87c0d4b483e54/node_modules/@wirecat/cli-core/dist/fetch/addresses.js
2346
2366
  import { isIP } from "node:net";
2347
2367
  var within3 = /* @__PURE__ */ __name((address, [prefix, bits]) => {
2348
2368
  for (let bit = 0; bit < bits; bit++) {
@@ -2413,7 +2433,7 @@ var isPublicAddress = /* @__PURE__ */ __name((address) => {
2413
2433
  return within3(bytes, [[32], 3]) && !V6_PRIVATE.some((prefix) => within3(bytes, prefix));
2414
2434
  }, "isPublicAddress");
2415
2435
 
2416
- // node_modules/.pnpm/@wirecat+cli-core@0.624.0_@wirecat+cli-base@0.95.0_commander@15.0.0_esbuild@0.28.2_type_845871b12d72ec55150c07203d8cbfbb/node_modules/@wirecat/cli-core/dist/fetch/page.js
2436
+ // node_modules/.pnpm/@wirecat+cli-core@0.628.0_@wirecat+cli-base@0.95.0_commander@15.0.0_esbuild@0.28.2_type_ae6a34897f184099b1a87c0d4b483e54/node_modules/@wirecat/cli-core/dist/fetch/page.js
2417
2437
  import { lookup as dnsLookup } from "node:dns/promises";
2418
2438
  import { request as httpRequest } from "node:http";
2419
2439
  import { request as httpsRequest } from "node:https";
@@ -4773,6 +4793,25 @@ var SHELL_OVERRIDES = { search, doctor, skill, mcp, commands, notes, meetings };
4773
4793
  import { existsSync as existsSync9, readdirSync as readdirSync5 } from "node:fs";
4774
4794
  import { join as join8 } from "node:path";
4775
4795
 
4796
+ // dist/exit-code.js
4797
+ var setters = /* @__PURE__ */ new WeakMap();
4798
+ var rootOf = /* @__PURE__ */ __name((command) => {
4799
+ let root = command;
4800
+ while (root.parent)
4801
+ root = root.parent;
4802
+ return root;
4803
+ }, "rootOf");
4804
+ var keepExitCode = /* @__PURE__ */ __name((program, set) => {
4805
+ setters.set(program, set);
4806
+ }, "keepExitCode");
4807
+ var setExitCode = /* @__PURE__ */ __name((command, code) => {
4808
+ const set = setters.get(rootOf(command));
4809
+ if (set)
4810
+ set(code);
4811
+ else
4812
+ process.exitCode = code;
4813
+ }, "setExitCode");
4814
+
4776
4815
  // dist/digest/brief.js
4777
4816
  import { spawnSync } from "node:child_process";
4778
4817
  import { existsSync as existsSync4, mkdtempSync, readFileSync as readFileSync5, rmSync as rmSync3, writeFileSync as writeFileSync3 } from "node:fs";
@@ -5239,7 +5278,7 @@ var signedInAccount = /* @__PURE__ */ __name((tool, profile, env) => {
5239
5278
  return void 0;
5240
5279
  }
5241
5280
  }, "signedInAccount");
5242
- var profileFor = /* @__PURE__ */ __name((provider, account2, env, chosen2 = {}) => {
5281
+ var profileFor = /* @__PURE__ */ __name((provider, account2, env, chosen3 = {}) => {
5243
5282
  const tool = messengerToolOf(provider);
5244
5283
  if (!tool)
5245
5284
  return void 0;
@@ -5247,7 +5286,7 @@ var profileFor = /* @__PURE__ */ __name((provider, account2, env, chosen2 = {})
5247
5286
  const profiles = existsSync5(dir) ? readdirSync2(dir).filter((name2) => name2.endsWith(".json")).map((name2) => name2.slice(0, -".json".length)).sort() : [];
5248
5287
  const accountOf = /* @__PURE__ */ __name((profile) => signedInAccount(tool, profile, env), "accountOf");
5249
5288
  const all = profiles.join(", ") || "none";
5250
- const pick = chosen2[tool.tool];
5289
+ const pick = chosen3[tool.tool];
5251
5290
  if (pick !== void 0) {
5252
5291
  if (!profiles.includes(pick))
5253
5292
  return { why: `${tool.tool} profile ${pick} is not signed in here; profiles: ${all}`, profiles };
@@ -5330,14 +5369,14 @@ var answerOf = /* @__PURE__ */ __name((stdout) => {
5330
5369
  }
5331
5370
  }, "answerOf");
5332
5371
  var MARGIN_MS = 5e3;
5333
- var messengerFetcher = /* @__PURE__ */ __name(({ env, note, chosen: chosen2 = {}, run = runChild, now = Date.now }) => {
5372
+ var messengerFetcher = /* @__PURE__ */ __name(({ env, note, chosen: chosen3 = {}, run = runChild, now = Date.now }) => {
5334
5373
  const binaries = /* @__PURE__ */ new Map();
5335
5374
  return {
5336
5375
  fetch: /* @__PURE__ */ __name(async ({ account: account2, chatId, after, until, signal }) => {
5337
5376
  const tool = messengerToolOf(account2.provider);
5338
5377
  if (!tool)
5339
5378
  return { state: "failed", reason: `no WireCat messenger CLI syncs ${account2.provider}` };
5340
- const found = profileFor(account2.provider, account2.account, env, chosen2);
5379
+ const found = profileFor(account2.provider, account2.account, env, chosen3);
5341
5380
  if (!found || !("profile" in found))
5342
5381
  return { state: "failed", reason: found?.why ?? "no profile" };
5343
5382
  if (!binaries.has(tool.tool))
@@ -5394,23 +5433,23 @@ var isEvent = /* @__PURE__ */ __name((line3) => {
5394
5433
  return false;
5395
5434
  }
5396
5435
  }, "isEvent");
5397
- var chatCommand = /* @__PURE__ */ __name((chat, words, env, chosen2) => {
5436
+ var chatCommand = /* @__PURE__ */ __name((chat, words, env, chosen3) => {
5398
5437
  const tool = messengerToolOf(chat.provider);
5399
5438
  if (!tool)
5400
5439
  return null;
5401
- const found = profileFor(chat.provider, chat.account, env, chosen2);
5440
+ const found = profileFor(chat.provider, chat.account, env, chosen3);
5402
5441
  const line3 = /* @__PURE__ */ __name((profile) => `${tool.tool} ${profile} ${words}`, "line");
5403
5442
  if (found && "profile" in found)
5404
5443
  return { command: line3(found.profile) };
5405
5444
  return { command: null, line: line3("<profile>"), why: found?.why ?? "no profile" };
5406
5445
  }, "chatCommand");
5407
- var chatSync = /* @__PURE__ */ __name((chat, since, env, chosen2 = {}) => (
5446
+ var chatSync = /* @__PURE__ */ __name((chat, since, env, chosen3 = {}) => (
5408
5447
  // A negative group id needs no `--`: no WireCat CLI has a digit short option.
5409
- chatCommand(chat, `messages sync ${chat.chat} --since-time ${since}`, env, chosen2)
5448
+ chatCommand(chat, `messages sync ${chat.chat} --since-time ${since}`, env, chosen3)
5410
5449
  ), "chatSync");
5411
- var chatRead = /* @__PURE__ */ __name((chat, since, env, chosen2 = {}) => chatCommand(chat, `messages list --compact ${chat.chat} "date>=${since}"`, env, chosen2), "chatRead");
5412
- var syncHint = /* @__PURE__ */ __name((chat, since, env, chosen2 = {}) => {
5413
- const sync = chatSync(chat, since, env, chosen2);
5450
+ var chatRead = /* @__PURE__ */ __name((chat, since, env, chosen3 = {}) => chatCommand(chat, `messages list --compact ${chat.chat} "date>=${since}"`, env, chosen3), "chatRead");
5451
+ var syncHint = /* @__PURE__ */ __name((chat, since, env, chosen3 = {}) => {
5452
+ const sync = chatSync(chat, since, env, chosen3);
5414
5453
  if (!sync)
5415
5454
  return null;
5416
5455
  return sync.command ?? `${sync.line} (${sync.why})`;
@@ -6534,7 +6573,7 @@ var digestCommands = /* @__PURE__ */ __name((digest, print, env) => {
6534
6573
  return;
6535
6574
  }
6536
6575
  if (last.exitCode !== 0)
6537
- process.exitCode = 1;
6576
+ setExitCode(command, 1);
6538
6577
  print(given2.json, itemAnswer({ name: name2, ...last }), `${name2}: ${last.exitCode === 0 ? "built" : `failed (exit ${last.exitCode})`} \u2014 ${last.output}`);
6539
6578
  });
6540
6579
  for (const [verb, paused] of [
@@ -6667,7 +6706,7 @@ var digestCommand = /* @__PURE__ */ __name((program, streams, env) => {
6667
6706
  }
6668
6707
  const costUsd = cents(built.reduce((sum, one2) => sum + (one2.costUsd ?? 0), 0));
6669
6708
  if (built.some((one2) => one2.exitCode !== 0))
6670
- process.exitCode = 1;
6709
+ setExitCode(command, 1);
6671
6710
  print(given2.json, itemAnswer({ ...estimate, built, left, costUsd }), [
6672
6711
  ...built.map((one2) => `${one2.date}: ${one2.exitCode === 0 ? "built" : `failed (exit ${one2.exitCode})`}${one2.costUsd === null ? "" : `, ${usd(one2.costUsd)}`}`),
6673
6712
  ...skipped.length ? [`Skipped, a digest exists: ${skipped.join(", ")}.`] : [],
@@ -6916,7 +6955,7 @@ var doctorCommandDefinition = /* @__PURE__ */ __name((program, streams, env) =>
6916
6955
  for (const fix of fixes)
6917
6956
  streams.diagnostic(`to make it private: ${fix}`);
6918
6957
  if (diagnosis.problems.length > 0)
6919
- process.exitCode = 1;
6958
+ setExitCode(program, 1);
6920
6959
  });
6921
6960
  }, "doctorCommandDefinition");
6922
6961
  var doctorCommand = /* @__PURE__ */ __name((...args) => {
@@ -6929,7 +6968,7 @@ var doctorCommand = /* @__PURE__ */ __name((...args) => {
6929
6968
  }, SHELL_OVERRIDES.doctor);
6930
6969
  }, "doctorCommand");
6931
6970
 
6932
- // node_modules/.pnpm/@wirecat+cli-core@0.624.0_@wirecat+cli-base@0.95.0_commander@15.0.0_esbuild@0.28.2_type_845871b12d72ec55150c07203d8cbfbb/node_modules/@wirecat/cli-core/dist/calendar/sync.js
6971
+ // node_modules/.pnpm/@wirecat+cli-core@0.628.0_@wirecat+cli-base@0.95.0_commander@15.0.0_esbuild@0.28.2_type_ae6a34897f184099b1a87c0d4b483e54/node_modules/@wirecat/cli-core/dist/calendar/sync.js
6933
6972
  var DAY8 = 864e5;
6934
6973
  var SLOTS_EVERY = 7 * DAY8;
6935
6974
  var isWindow = /* @__PURE__ */ __name((value) => typeof value?.from === "number" && typeof value.to === "number", "isWindow");
@@ -7009,10 +7048,10 @@ var calendarStatus = /* @__PURE__ */ __name(async (store, accountId, { profile,
7009
7048
  return { items, page: 1, limit: Math.max(1, items.length), hasMore: false };
7010
7049
  }, "calendarStatus");
7011
7050
 
7012
- // node_modules/.pnpm/@wirecat+cli-core@0.624.0_@wirecat+cli-base@0.95.0_commander@15.0.0_esbuild@0.28.2_type_845871b12d72ec55150c07203d8cbfbb/node_modules/@wirecat/cli-core/dist/calendar/feeds.js
7051
+ // node_modules/.pnpm/@wirecat+cli-core@0.628.0_@wirecat+cli-base@0.95.0_commander@15.0.0_esbuild@0.28.2_type_ae6a34897f184099b1a87c0d4b483e54/node_modules/@wirecat/cli-core/dist/calendar/feeds.js
7013
7052
  var FEED_LIMITS = { maxBytes: 10 * 1024 * 1024, timeoutMs: 3e4, redirects: 5 };
7014
7053
 
7015
- // node_modules/.pnpm/@wirecat+cli-core@0.624.0_@wirecat+cli-base@0.95.0_commander@15.0.0_esbuild@0.28.2_type_845871b12d72ec55150c07203d8cbfbb/node_modules/@wirecat/cli-core/dist/calendar/reads.js
7054
+ // node_modules/.pnpm/@wirecat+cli-core@0.628.0_@wirecat+cli-base@0.95.0_commander@15.0.0_esbuild@0.28.2_type_ae6a34897f184099b1a87c0d4b483e54/node_modules/@wirecat/cli-core/dist/calendar/reads.js
7016
7055
  var LIST = "events list";
7017
7056
  var EVENT_TYPES = [
7018
7057
  "default",
@@ -7089,7 +7128,7 @@ var accountsMeta = /* @__PURE__ */ __name(async (store, accounts, skipped, now)
7089
7128
  };
7090
7129
  }, "accountsMeta");
7091
7130
 
7092
- // node_modules/.pnpm/@wirecat+cli-core@0.624.0_@wirecat+cli-base@0.95.0_commander@15.0.0_esbuild@0.28.2_type_845871b12d72ec55150c07203d8cbfbb/node_modules/@wirecat/cli-core/dist/calendar/writer.js
7131
+ // node_modules/.pnpm/@wirecat+cli-core@0.628.0_@wirecat+cli-base@0.95.0_commander@15.0.0_esbuild@0.28.2_type_ae6a34897f184099b1a87c0d4b483e54/node_modules/@wirecat/cli-core/dist/calendar/writer.js
7093
7132
  var EVENTS_NOTIFY_KEY = "events.notify";
7094
7133
  var EVENTS_DELETE_SERIES_KEY = "events.delete.series";
7095
7134
  var EVENTS_REMIND_HOOK_KEY = "events.remind.hook";
@@ -7155,10 +7194,10 @@ var readAccounts = /* @__PURE__ */ __name(async (store) => {
7155
7194
  return read;
7156
7195
  }, "readAccounts");
7157
7196
  var narrowed = /* @__PURE__ */ __name((accounts, value) => {
7158
- const chosen2 = accounts.filter(({ key }) => accountName(key) === value || key.provider === value);
7159
- if (chosen2.length === 0)
7197
+ const chosen3 = accounts.filter(({ key }) => accountName(key) === value || key.provider === value);
7198
+ if (chosen3.length === 0)
7160
7199
  throw new CliError("not_found", `account:${value} names no calendar account \u2014 the store holds ${accounts.map(({ key }) => accountName(key)).join(", ") || "none"}`, { reason: "events.account-unknown" });
7161
- return chosen2;
7200
+ return chosen3;
7162
7201
  }, "narrowed");
7163
7202
  var calendarOf2 = /* @__PURE__ */ __name((accounts, value) => {
7164
7203
  const all = accounts.flatMap((account2) => account2.calendars.map((calendar) => ({ account: account2, calendar })));
@@ -7332,6 +7371,10 @@ var EXAMPLES = {
7332
7371
  "memo sources add https://example.org/release-notes --title 'Release notes' --json",
7333
7372
  "memo sources add - --title 'Call with Kai' --subject person:12"
7334
7373
  ],
7374
+ "sources preview": [
7375
+ "memo sources preview https://example.org/release-notes",
7376
+ "memo sources preview https://example.org/release-notes --json=title,excerpt"
7377
+ ],
7335
7378
  "sources suggest": [
7336
7379
  "memo sources suggest document:42",
7337
7380
  "memo sources suggest document:42 --subject person:12 --json",
@@ -7632,7 +7675,15 @@ var EXAMPLES = {
7632
7675
  "memo records import envelope.json --account rentals --json",
7633
7676
  "memo records import contacts.vcf --account phone:pixel --region gb"
7634
7677
  ],
7635
- "records check": ["memo records check - --account rentals"],
7678
+ "records check": [
7679
+ "memo records check - --account rentals",
7680
+ "memo records check invoices.csv --type invoice --account sheet:rentals"
7681
+ ],
7682
+ "records templates list": ["memo records templates list --json", "memo records templates list type:invoice"],
7683
+ "records templates show": [
7684
+ "memo records templates show invoice --locale ru",
7685
+ "memo records templates show invoice --format json --account sheet:rentals"
7686
+ ],
7636
7687
  "records list": [
7637
7688
  "memo records list waiting:true --account sheet:rentals",
7638
7689
  "memo records list type:organization --account sheet:rentals --json",
@@ -7920,7 +7971,7 @@ var memoryItem = /* @__PURE__ */ __name(({ body, ...memory }) => ({
7920
7971
  createdAt: memory.createdAt,
7921
7972
  updatedAt: memory.updatedAt
7922
7973
  }), "memoryItem");
7923
- var listMemories = /* @__PURE__ */ __name(async (store, query, limit) => {
7974
+ var listMemories = /* @__PURE__ */ __name(async (store, query, limit, page) => {
7924
7975
  const terms2 = queryTerms(query, MEMORY_QUERY, "memories list");
7925
7976
  const project = terms2.get("project");
7926
7977
  const filters = {
@@ -7930,7 +7981,7 @@ var listMemories = /* @__PURE__ */ __name(async (store, query, limit) => {
7930
7981
  ...terms2.has("subject") ? { subject: terms2.get("subject") } : {},
7931
7982
  ...project === void 0 ? {} : { project: await canonicalProject(store, project) }
7932
7983
  };
7933
- return pageOf("memories list", limit, async (most) => (await store.memories.list({ ...filters, limit: most })).map(memoryItem));
7984
+ return pageOf("memories list", limit, async (most, offset) => (await store.memories.list({ ...filters, limit: most, offset })).map(memoryItem), { page, args: { query: typedQuery(query) } });
7934
7985
  }, "listMemories");
7935
7986
  var SEARCH = { command: "search memories", guide: LIST_QUERY_GUIDE };
7936
7987
  var MEMORY_FIELDS = /* @__PURE__ */ new Set(["text", ...MEMORY_QUERY.fields.map(({ name: name2 }) => name2)]);
@@ -8055,7 +8106,7 @@ var memoriesCommand = /* @__PURE__ */ __name((program, streams, env) => {
8055
8106
  ...options.supersedes === void 0 ? {} : { supersedes: options.supersedes }
8056
8107
  }, await by).catch(explainQuote))));
8057
8108
  });
8058
- withQuery(annotate(memories.command("list"), { effects: LOCAL_READ }).description("memories, newest first"), MEMORY_QUERY).option("--limit <n>", "most memories, up to 500", positive, 100).option("--json", "print JSON; --json=id,title keeps only those fields").action((words, { json: json5, limit }) => run(json5, async (store) => stripped(store, env, await listMemories(store, words, limit))));
8109
+ withQuery(annotate(memories.command("list"), { effects: LOCAL_READ }).description("memories, newest first"), MEMORY_QUERY).option("--limit <n>", "most memories on a page, up to 500", positive, 100).option("--page <n>", "which page, from 1", positive, 1).option("--json", "print JSON; --json=id,title keeps only those fields").action((words, { json: json5, limit, page }) => run(json5, async (store) => stripped(store, env, await listMemories(store, words, limit, page))));
8059
8110
  annotate(memories.command("show"), { effects: LOCAL_READ, output: { entity: "memory" } }).description("one memory with its evidence").argument("<ref>", "memory:<id>").option("--sources", "read each piece of evidence back: who, when, a short excerpt, and whether it is gone").option("--json", "print JSON; --json=id,title keeps only those fields").action((ref, options) => run(options.json, async (store) => itemAnswer(await stripped(store, env, {
8060
8111
  ...memoryItem(await store.memories.get(ref)),
8061
8112
  ...options.sources ? await sourcesIn(store, env, await store.memories.sources(ref)) : {}
@@ -8127,7 +8178,7 @@ var factItem = /* @__PURE__ */ __name(({ type, statement, source, confirmedBy, .
8127
8178
  updated_at: fact.updatedAt,
8128
8179
  confirmed_by: confirmedBy
8129
8180
  }), "factItem");
8130
- var listFacts = /* @__PURE__ */ __name(async (store, query, limit) => {
8181
+ var listFacts = /* @__PURE__ */ __name(async (store, query, limit, page) => {
8131
8182
  const terms2 = queryTerms(query, FACT_QUERY, "facts list");
8132
8183
  const project = terms2.get("project");
8133
8184
  const filters = {
@@ -8136,7 +8187,7 @@ var listFacts = /* @__PURE__ */ __name(async (store, query, limit) => {
8136
8187
  ...project === void 0 ? {} : { project: await canonicalProject(store, project) },
8137
8188
  ...terms2.has("subject") ? { subject: terms2.get("subject") } : {}
8138
8189
  };
8139
- return pageOf("facts list", limit, async (most) => (await store.facts.list({ ...filters, limit: most })).map(factItem));
8190
+ return pageOf("facts list", limit, async (most, offset) => (await store.facts.list({ ...filters, limit: most, offset })).map(factItem), { page, args: { query: typedQuery(query) } });
8140
8191
  }, "listFacts");
8141
8192
 
8142
8193
  // dist/facts/facts.js
@@ -8177,7 +8228,7 @@ var factsCommand = /* @__PURE__ */ __name((program, streams, env) => {
8177
8228
  ...options.supersedes === void 0 ? {} : { supersedes: options.supersedes }
8178
8229
  }).catch(explainQuote))));
8179
8230
  });
8180
- withQuery(annotate(facts.command("list"), { effects: LOCAL_READ }).description("facts, latest first"), FACT_QUERY).option("--limit <n>", "most facts, up to 500", positive, 100).option("--json", "print JSON; --json=id,title keeps only those fields").action((words, { json: json5, limit }) => run(json5, async (store) => stripped(store, env, await listFacts(store, words, limit))));
8231
+ withQuery(annotate(facts.command("list"), { effects: LOCAL_READ }).description("facts, latest first"), FACT_QUERY).option("--limit <n>", "most facts on a page, up to 500", positive, 100).option("--page <n>", "which page, from 1", positive, 1).option("--json", "print JSON; --json=id,title keeps only those fields").action((words, { json: json5, limit, page }) => run(json5, async (store) => stripped(store, env, await listFacts(store, words, limit, page))));
8181
8232
  annotate(facts.command("show"), { effects: LOCAL_READ, output: { entity: "fact" } }).description("one fact with its evidence").argument("<ref>", "fact:<id>").option("--sources", "read each piece of evidence back: who, when, a short excerpt, and whether it is gone").option("--json", "print JSON; --json=id,title keeps only those fields").action((ref, options) => run(options.json, async (store) => itemAnswer(await stripped(store, env, {
8182
8233
  ...factItem(await store.facts.get(ref)),
8183
8234
  ...options.sources ? await sourcesIn(store, env, await store.facts.sources(ref)) : {}
@@ -9786,7 +9837,7 @@ var projectGatherCommand = /* @__PURE__ */ __name((projects, print, env, warn) =
9786
9837
  // Declared as a fetch for --sync-first; cli-base fixes effects per command, and without it nothing leaves this machine.
9787
9838
  annotate(projects.command("evidence"), { effects: FETCH, partial: true }).description("cited references about a project in stored messages, mail, meeting transcripts and imported notes folders. The project's name, its key, each of its aliases and each --alias, each --context-query and each --contact name is its own search: every word of it must appear in one text, in any order, as whole words; their hits are joined. Every message of a chat confirmed as the project's (memo relationships add chat:<provider>/<account>/<chat> project:<id>) is read too, when --source holds its account, and so is everything a confirmed person member of the project wrote (as --contact person:<id>, without aliases). New mail and documents are indexed for search first, unless --no-catch-up. Reads what the store holds; with --sync-first it first syncs the linked chats the store lacks for the window by running their messenger CLI (tg, max, wa) with the profile signed in to each chat's account, or the one --sync-profile names when several are; proposes and confirms nothing. A partial answer exits 0 with meta.complete false").summary("find what the store holds about a project: names, words, people, linked chats").argument("<project>", "an existing project's id, key, exact name or alias, or a new project's name").requiredOption("--source <accounts>", `where to look, or all: ${ACCOUNTS_HELP}`).option("--alias <name>", "another name of the project, searched on its own; repeat for more", collect, []).option("--context-query <words>", "more words that all appear in one text; repeat for another search", collect, []).option("--contact <person>", "a name to search, or person:<id> to read what that person's stored identities wrote and search the aliases you gave them; what only names them or comes from them is context, not the project", collect, []).option("--since-time <time>", "how far back: days (90d, at most 730d) or a start date (2026-09-01)", "60d").option("--before-time <time>", "fixed exclusive end: ISO 8601 timestamp with UTC offset; days back count from it").option("--limit <n>", "new references at most, up to 500", positive, 100).option("--max-pages <pages>", "store pages read at most this run, up to 512", positive).option("--cursor <cursor>", "continue a stopped search from its checkpoint, with the same options").option("--before-n <n>", "messages before each message hit, shown as its context, at most 5", whole, 2).option("--after-n <n>", "messages after each message hit, shown as its context, at most 5", whole, 2).option("--no-catch-up", "read the search index as it is, without indexing new mail and documents first").addOption(cliOnly(new Option("--sync-first", "first sync the linked chats the store does not hold back to --since-time, through their messenger CLI; off by default"))).addOption(cliOnly(new Option("--sync-time <duration>", "time for all of --sync-first's syncs together").default("3m"))).addOption(cliOnly(new Option("--sync-profile <tool=profile>", "the messenger profile to sync as when several are signed in to a chat's account, such as max=default; repeat for another tool. It must be signed in to that account").argParser(syncProfileOf))).option("--purpose <purpose>", "the linked chats' purposes to read, comma-separated: work, sales, support, other, or all; default work", purposeList).option("--include-proposed", "also read chats and members proposed for the project, after the confirmed ones").option("--json", "print JSON; --json=id,title keeps only those fields").action(async (project, options) => {
9788
9839
  const maxFetchMs = parseDuration(options.syncTime, "--sync-time");
9789
- const chosen2 = options.syncProfile ?? {};
9840
+ const chosen3 = options.syncProfile ?? {};
9790
9841
  const { found, scan } = await withStore(env, async (store) => {
9791
9842
  const found2 = await gatherStoredProject(store, {
9792
9843
  project,
@@ -9804,7 +9855,7 @@ var projectGatherCommand = /* @__PURE__ */ __name((projects, print, env, warn) =
9804
9855
  ...options.cursor === void 0 ? {} : { checkpoint: options.cursor },
9805
9856
  ...options.purpose ? { purposes: options.purpose } : {},
9806
9857
  ...options.includeProposed ? { includeProposed: true } : {},
9807
- ...options.syncFirst ? { fetcher: messengerFetcher({ env, note: warn, chosen: chosen2 }), maxFetchMs } : {}
9858
+ ...options.syncFirst ? { fetcher: messengerFetcher({ env, note: warn, chosen: chosen3 }), maxFetchMs } : {}
9808
9859
  });
9809
9860
  const known2 = await projectOf(store, project).catch((error) => {
9810
9861
  if (error instanceof CliError && error.code === "not_found")
@@ -9814,7 +9865,7 @@ var projectGatherCommand = /* @__PURE__ */ __name((projects, print, env, warn) =
9814
9865
  return { found: found2, scan: known2 ? await scanStep(store, known2, options.source) : [] };
9815
9866
  });
9816
9867
  const since = new Date(found.window.after).toISOString().slice(0, 10);
9817
- const syncs = found.linkedChats.map((one2) => one2.completeness === null || one2.completeness.state === "complete" ? null : chatSync(one2, since, env, chosen2));
9868
+ const syncs = found.linkedChats.map((one2) => one2.completeness === null || one2.completeness.state === "complete" ? null : chatSync(one2, since, env, chosen3));
9818
9869
  const parts2 = projectAnswerParts(options.sinceTime, found);
9819
9870
  const blocked = [...new Set(syncs.flatMap((one2) => one2 && one2.command === null ? [one2.why] : []))];
9820
9871
  const missing = [...parts2.missing ?? [], ...blocked.map((why) => ({ field: "sync_command", why }))];
@@ -9823,7 +9874,7 @@ var projectGatherCommand = /* @__PURE__ */ __name((projects, print, env, warn) =
9823
9874
  ...found,
9824
9875
  linkedChats: found.linkedChats.map((one2, i) => ({ ...one2, syncCommand: syncs[i]?.command ?? null }))
9825
9876
  }, { ...parts2, ...missing.length ? { missing } : {}, ...next.length ? { next } : {} }), projectEvidenceText(found, {
9826
- sync: /* @__PURE__ */ __name((chat, at2) => syncHint(chat, at2, env, chosen2), "sync"),
9877
+ sync: /* @__PURE__ */ __name((chat, at2) => syncHint(chat, at2, env, chosen3), "sync"),
9827
9878
  showDocument: "memo notes show"
9828
9879
  }));
9829
9880
  })
@@ -9869,7 +9920,7 @@ var projectStatusCommand = /* @__PURE__ */ __name((projects, print, env) => answ
9869
9920
  reason: "output.conflict",
9870
9921
  param: "--compact"
9871
9922
  });
9872
- const chosen2 = options.syncProfile ?? {};
9923
+ const chosen3 = options.syncProfile ?? {};
9873
9924
  const { found, finance, open: open2 } = await withStore(env, async (store) => {
9874
9925
  const scope = await groupScopeOf(store, env);
9875
9926
  const status = await projectStatus(store, {
@@ -9887,8 +9938,8 @@ var projectStatusCommand = /* @__PURE__ */ __name((projects, print, env) => answ
9887
9938
  const blocked = /* @__PURE__ */ new Set();
9888
9939
  const step = outside(blocked);
9889
9940
  const hints = {
9890
- sync: /* @__PURE__ */ __name((chat, since) => step("messages.sync", chatSync(linked(chat), since, env, chosen2)), "sync"),
9891
- read: /* @__PURE__ */ __name((chat, since) => step("messages.list", chatRead(linked(chat), since, env, chosen2)), "read"),
9941
+ sync: /* @__PURE__ */ __name((chat, since) => step("messages.sync", chatSync(linked(chat), since, env, chosen3)), "sync"),
9942
+ read: /* @__PURE__ */ __name((chat, since) => step("messages.list", chatRead(linked(chat), since, env, chosen3)), "read"),
9892
9943
  line: /* @__PURE__ */ __name((one2) => one2.kind === "command" ? one2.line ?? one2.command : one2.why, "line")
9893
9944
  };
9894
9945
  const lock = groupLockOf(APP, env);
@@ -10813,10 +10864,10 @@ var mcpCommandDefinition = /* @__PURE__ */ __name((program, streams, env, create
10813
10864
  }).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) => {
10814
10865
  if (!options.http && (options.port !== void 0 || options.publicUrl !== void 0))
10815
10866
  throw new CliError("validation_error", "--port and --public-url require --http");
10816
- const { createMemoServer } = await import("./server-ADPO4V4B.js");
10867
+ const { createMemoServer } = await import("./server-3SJJNNSX.js");
10817
10868
  const build = /* @__PURE__ */ __name(() => createMemoServer(env, createProgram2, options.permission), "build");
10818
10869
  if (options.http) {
10819
- const { httpLockFile, mcpUrlOf, portOf, publicUrlOf, serveOverHttp } = await import("./mcp-DEY765VA.js");
10870
+ const { httpLockFile, mcpUrlOf, portOf, publicUrlOf, serveOverHttp } = await import("./mcp-3HKOGYHL.js");
10820
10871
  const publicUrl = publicUrlOf(options.publicUrl, {
10821
10872
  missing: "--http",
10822
10873
  reaches: "the browser apps reach memo",
@@ -10868,7 +10919,7 @@ var mcpCommandDefinition = /* @__PURE__ */ __name((program, streams, env, create
10868
10919
  });
10869
10920
  });
10870
10921
  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() {
10871
- const { revokeAll } = await import("./mcp-DEY765VA.js");
10922
+ const { revokeAll } = await import("./mcp-3HKOGYHL.js");
10872
10923
  revokeAll(httpTokenFile(env));
10873
10924
  out.print(this.opts().json, itemAnswer({ revoked: true }));
10874
10925
  });
@@ -11289,10 +11340,10 @@ var internalNotes = /* @__PURE__ */ __name(async (store) => {
11289
11340
  }, "internalNotes");
11290
11341
  var titleOf2 = /* @__PURE__ */ __name((note) => note.title ?? (note.text.split("\n").find((line3) => line3.trim())?.trim().slice(0, MAX_TITLE) || note.id), "titleOf");
11291
11342
  var exportTarget = /* @__PURE__ */ __name((config, dir, format) => {
11292
- const chosen2 = typeof dir === "string" ? dir : config.notes?.export?.dir;
11293
- if (chosen2 === void 0)
11343
+ const chosen3 = typeof dir === "string" ? dir : config.notes?.export?.dir;
11344
+ if (chosen3 === void 0)
11294
11345
  throw new CliError("configuration_error", "name a folder \u2014 --output-dir <dir>, --export <dir>, or notes.export.dir in the config");
11295
- return { dir: resolve3(chosen2), format: format ?? config.notes?.export?.format ?? "obsidian" };
11346
+ return { dir: resolve3(chosen3), format: format ?? config.notes?.export?.format ?? "obsidian" };
11296
11347
  }, "exportTarget");
11297
11348
  var exportInternal = /* @__PURE__ */ __name(async (store, { dir, format, notes: notes2 }) => {
11298
11349
  const exported = [];
@@ -11777,16 +11828,16 @@ var identitiesCommands = /* @__PURE__ */ __name((people, program, streams, env)
11777
11828
  byOption(annotate(people.command("unlink"), { effects: LOCAL_WRITE }).summary("take identities off a person, to one new person; only you").description("take identities off their person: one gets a person of its own again, several move together to one new person; only you, and no automatic match joins them back").argument("<identities...>", "the identities that leave, each <messenger>:<id> exactly, all of one person")).option("--json", "print JSON; --json=id,title keeps only those fields").action(async (refs, options, command) => {
11778
11829
  await asOwner(command, env, `unlink ${refs.join(" ")}?`);
11779
11830
  const person = await withStore(env, async (store) => {
11780
- const chosen2 = [];
11831
+ const chosen3 = [];
11781
11832
  for (const ref of refs)
11782
- chosen2.push(await exactIdentityOf(store, ref));
11783
- const [first] = chosen2;
11784
- if (chosen2.length === 1)
11833
+ chosen3.push(await exactIdentityOf(store, ref));
11834
+ const [first] = chosen3;
11835
+ if (chosen3.length === 1)
11785
11836
  return store.people.unlinkIdentity(first, { method: "unlink", by: "owner" });
11786
11837
  const held = await store.people.personOf(first);
11787
11838
  if (held === void 0)
11788
11839
  throw new CliError("not_found", `the store has no person for "${refs[0]}"`, { reason: "person.not-found" });
11789
- return store.people.split(held.uid, chosen2, "owner");
11840
+ return store.people.split(held.uid, chosen3, "owner");
11790
11841
  });
11791
11842
  print(options.json, itemAnswer(personAnswer(person)), `person:${person.uid}`);
11792
11843
  });
@@ -11961,7 +12012,66 @@ var peopleCommand = /* @__PURE__ */ __name((program, streams, env) => {
11961
12012
  }, "peopleCommand");
11962
12013
 
11963
12014
  // dist/records/input.js
11964
- import { open } from "node:fs/promises";
12015
+ import { open, readFile } from "node:fs/promises";
12016
+ import { basename as basename3 } from "node:path";
12017
+ import { text as streamText } from "node:stream/consumers";
12018
+
12019
+ // dist/records/mapping.js
12020
+ var RECORD_QUERY = {
12021
+ entity: "source_record",
12022
+ backend: "native",
12023
+ fields: [
12024
+ termField("type", "kw", "type:organization"),
12025
+ termField("waiting", "bool", "waiting:true"),
12026
+ termField("flagged", "bool", "flagged:true"),
12027
+ termField("unmatched", "bool", "unmatched:true"),
12028
+ termField("entity", "ref", 'entity:"organization:3"'),
12029
+ termField("batch", "kw", "batch:2026-11-07"),
12030
+ termField("deleted", "bool", "deleted:true")
12031
+ ]
12032
+ };
12033
+ var sourceOf5 = /* @__PURE__ */ __name((account2) => {
12034
+ const [provider = "", ...rest] = (account2 ?? "").trim().split(":");
12035
+ const name2 = rest.join(":");
12036
+ if (!provider || !name2)
12037
+ throw new CliError("validation_error", "name the source as --account <provider>:<account>, such as sheet:rentals", {
12038
+ param: "--account"
12039
+ });
12040
+ return { provider, account: name2 };
12041
+ }, "sourceOf");
12042
+ var recordOf = /* @__PURE__ */ __name((record2) => {
12043
+ const from = record2.startsWith("custom:") ? "custom:".length : 0;
12044
+ const at2 = record2.indexOf(":", from);
12045
+ if (at2 <= from || at2 === record2.length - 1)
12046
+ throw new CliError("validation_error", `${record2} is not <type>:<external_id>, such as organization:client or custom:quote:Q-7`, { param: "record" });
12047
+ return { type: record2.slice(0, at2), externalId: record2.slice(at2 + 1) };
12048
+ }, "recordOf");
12049
+ var RECORD_HELP = "<type>:<external_id> as the source names it, such as organization:client or custom:quote:Q-7";
12050
+ var ACCOUNT_HELP = "the source, <provider>:<account> as the envelope's source names it, such as sheet:rentals";
12051
+ var recordMappingCommands = /* @__PURE__ */ __name((records, program, streams, env) => {
12052
+ const { run } = answers(program, streams, env);
12053
+ withQuery(annotate(records.command("list"), { effects: LOCAL_READ }).description("a source's records, newest first; waiting:true lists those that wait for a record they name, unmatched:true the people, organizations and projects whose identifiers fit more than one of yours, entity: those mapped to one of your entries"), RECORD_QUERY).summary("a source's records; waiting:true lists what needs records link").option("--account <account>", ACCOUNT_HELP).option("--limit <n>", "most records, up to 500", positive, 100).option("--json", "print JSON; --json=type,external_id,entity keeps only those fields").action((words, given2) => run(given2.json, async (store) => {
12054
+ const source = sourceOf5(given2.account);
12055
+ const terms2 = queryTerms(words, RECORD_QUERY, "records list");
12056
+ const filter = {
12057
+ ...source,
12058
+ ...terms2.has("type") ? { type: terms2.get("type") } : {},
12059
+ ...terms2.get("waiting") === "true" ? { waiting: true } : {},
12060
+ ...terms2.get("flagged") === "true" ? { flagged: true } : {},
12061
+ ...terms2.get("unmatched") === "true" ? { unmatched: true } : {},
12062
+ ...terms2.has("entity") ? { entity: terms2.get("entity") } : {},
12063
+ ...terms2.has("batch") ? { batch: terms2.get("batch") } : {},
12064
+ ...terms2.has("deleted") ? { deleted: terms2.get("deleted") === "true" } : {}
12065
+ };
12066
+ return pageOf("records list", given2.limit, (most) => store.records.list({ ...filter, limit: most }));
12067
+ }));
12068
+ byOption(annotate(records.command("link"), { effects: LOCAL_WRITE, output: { entity: "source_record" } }).description("say which of your entries a source's record is (organization:client is organization:3); never done by name. Records that waited for it become proposals in memo review. Only you link; an agent is refused").summary("say which of your entries a source's record is").argument("<record>", RECORD_HELP).argument("<ref>", "your entry of the same type: person:<id>, organization:<id> or project:<id>").option("--account <account>", ACCOUNT_HELP).option("--json", "print JSON; --json=type,external_id,entity keeps only those fields")).action(async (record2, ref, given2, command) => {
12069
+ const by = await whoRuns(command, env, { asOwner: given2.asOwner, question: `link ${record2} to ${ref} as you?` });
12070
+ await run(given2.json, async (store) => itemAnswer(await store.records.map({ ...sourceOf5(given2.account), ...recordOf(record2) }, ref, by)));
12071
+ });
12072
+ }, "recordMappingCommands");
12073
+
12074
+ // dist/records/input.js
11965
12075
  var PHONE = "phone";
11966
12076
  var BOM = /^\uFEFF/;
11967
12077
  var errnoOf = /* @__PURE__ */ __name((error) => typeof error === "object" && error !== null && "code" in error ? String(error.code) : void 0, "errnoOf");
@@ -12011,7 +12121,9 @@ var deviceOf = /* @__PURE__ */ __name((given2) => {
12011
12121
  });
12012
12122
  return given2.slice(at2 + 1);
12013
12123
  }, "deviceOf");
12014
- var importRecords = /* @__PURE__ */ __name(async (store, { file, stdin, account: account2, dryRun, onIssue, region }) => {
12124
+ var importRecords = /* @__PURE__ */ __name(async (store, { file, stdin, account: account2, dryRun, onIssue, region, type }) => {
12125
+ if (type !== void 0 || file.toLowerCase().endsWith(".csv"))
12126
+ return importSheet(store, { file, stdin, account: account2, dryRun, onIssue, type });
12015
12127
  const iterator = (await linesOf(file, stdin))[Symbol.asyncIterator]();
12016
12128
  const before = [];
12017
12129
  let next = await iterator.next();
@@ -12071,61 +12183,77 @@ var importRecords = /* @__PURE__ */ __name(async (store, { file, stdin, account:
12071
12183
  const envelope = envelopeOfText(await whole2([first]));
12072
12184
  return ingest(store, envelope, { account: accountIn2(envelope, account2), dryRun, onIssue });
12073
12185
  }, "importRecords");
12074
-
12075
- // dist/records/mapping.js
12076
- var RECORD_QUERY = {
12077
- entity: "source_record",
12078
- backend: "native",
12079
- fields: [
12080
- termField("type", "kw", "type:organization"),
12081
- termField("waiting", "bool", "waiting:true"),
12082
- termField("flagged", "bool", "flagged:true"),
12083
- termField("unmatched", "bool", "unmatched:true"),
12084
- termField("entity", "ref", 'entity:"organization:3"'),
12085
- termField("batch", "kw", "batch:2026-11-07"),
12086
- termField("deleted", "bool", "deleted:true")
12087
- ]
12088
- };
12089
- var sourceOf5 = /* @__PURE__ */ __name((account2) => {
12090
- const [provider = "", ...rest] = (account2 ?? "").trim().split(":");
12091
- const name2 = rest.join(":");
12092
- if (!provider || !name2)
12093
- throw new CliError("validation_error", "name the source as --account <provider>:<account>, such as sheet:rentals", {
12094
- param: "--account"
12095
- });
12096
- return { provider, account: name2 };
12097
- }, "sourceOf");
12098
- var recordOf = /* @__PURE__ */ __name((record2) => {
12099
- const from = record2.startsWith("custom:") ? "custom:".length : 0;
12100
- const at2 = record2.indexOf(":", from);
12101
- if (at2 <= from || at2 === record2.length - 1)
12102
- throw new CliError("validation_error", `${record2} is not <type>:<external_id>, such as organization:client or custom:quote:Q-7`, { param: "record" });
12103
- return { type: record2.slice(0, at2), externalId: record2.slice(at2 + 1) };
12104
- }, "recordOf");
12105
- var RECORD_HELP = "<type>:<external_id> as the source names it, such as organization:client or custom:quote:Q-7";
12106
- var ACCOUNT_HELP = "the source, <provider>:<account> as the envelope's source names it, such as sheet:rentals";
12107
- var recordMappingCommands = /* @__PURE__ */ __name((records, program, streams, env) => {
12108
- const { run } = answers(program, streams, env);
12109
- withQuery(annotate(records.command("list"), { effects: LOCAL_READ }).description("a source's records, newest first; waiting:true lists those that wait for a record they name, unmatched:true the people, organizations and projects whose identifiers fit more than one of yours, entity: those mapped to one of your entries"), RECORD_QUERY).summary("a source's records; waiting:true lists what needs records link").option("--account <account>", ACCOUNT_HELP).option("--limit <n>", "most records, up to 500", positive, 100).option("--json", "print JSON; --json=type,external_id,entity keeps only those fields").action((words, given2) => run(given2.json, async (store) => {
12110
- const source = sourceOf5(given2.account);
12111
- const terms2 = queryTerms(words, RECORD_QUERY, "records list");
12112
- const filter = {
12113
- ...source,
12114
- ...terms2.has("type") ? { type: terms2.get("type") } : {},
12115
- ...terms2.get("waiting") === "true" ? { waiting: true } : {},
12116
- ...terms2.get("flagged") === "true" ? { flagged: true } : {},
12117
- ...terms2.get("unmatched") === "true" ? { unmatched: true } : {},
12118
- ...terms2.has("entity") ? { entity: terms2.get("entity") } : {},
12119
- ...terms2.has("batch") ? { batch: terms2.get("batch") } : {},
12120
- ...terms2.has("deleted") ? { deleted: terms2.get("deleted") === "true" } : {}
12121
- };
12122
- return pageOf("records list", given2.limit, (most) => store.records.list({ ...filter, limit: most }));
12123
- }));
12124
- byOption(annotate(records.command("link"), { effects: LOCAL_WRITE, output: { entity: "source_record" } }).description("say which of your entries a source's record is (organization:client is organization:3); never done by name. Records that waited for it become proposals in memo review. Only you link; an agent is refused").summary("say which of your entries a source's record is").argument("<record>", RECORD_HELP).argument("<ref>", "your entry of the same type: person:<id>, organization:<id> or project:<id>").option("--account <account>", ACCOUNT_HELP).option("--json", "print JSON; --json=type,external_id,entity keeps only those fields")).action(async (record2, ref, given2, command) => {
12125
- const by = await whoRuns(command, env, { asOwner: given2.asOwner, question: `link ${record2} to ${ref} as you?` });
12126
- await run(given2.json, async (store) => itemAnswer(await store.records.map({ ...sourceOf5(given2.account), ...recordOf(record2) }, ref, by)));
12186
+ var placed = /* @__PURE__ */ __name((items, placeOf) => items.map((item) => {
12187
+ const place = placeOf(item.pointer);
12188
+ return place ? { ...item, place } : item;
12189
+ }), "placed");
12190
+ var sheetText2 = /* @__PURE__ */ __name(async (file, stdin) => {
12191
+ if (file === "-")
12192
+ return streamText(stdin);
12193
+ try {
12194
+ return await readFile(file, "utf8");
12195
+ } catch (error) {
12196
+ if (errnoOf(error) === "ENOENT")
12197
+ throw new CliError("not_found", `no records file ${file}: give a file that exists, or - for stdin`, {
12198
+ reason: "records.file-missing",
12199
+ path: file
12200
+ });
12201
+ throw new CliError("validation_error", `the records file ${file} cannot be read`, {
12202
+ reason: "records.file-unreadable",
12203
+ path: file
12204
+ });
12205
+ }
12206
+ }, "sheetText");
12207
+ var placeText = /* @__PURE__ */ __name((place) => place ? `line ${place.line}${place.column ? `, column ${place.column}` : ""}` : "", "placeText");
12208
+ var refusedSheet = /* @__PURE__ */ __name((dryRun, source, errors) => ({
12209
+ dryRun,
12210
+ source,
12211
+ created: 0,
12212
+ updated: 0,
12213
+ unchanged: 0,
12214
+ deleted: 0,
12215
+ refused: errors.length,
12216
+ proposed: [],
12217
+ waiting: [],
12218
+ flagged: [],
12219
+ unmatched: [],
12220
+ ignored: [],
12221
+ relationships: { added: 0, kept: 0, restored: 0, withdrawn: 0, proposed: 0, skippedOwnerRejected: 0 },
12222
+ notices: [],
12223
+ errors,
12224
+ truncated: false
12225
+ }), "refusedSheet");
12226
+ var importSheet = /* @__PURE__ */ __name(async (store, { file, stdin, account: account2, dryRun, onIssue, type }) => {
12227
+ if (!type || !TABLE_RECORD_TYPES.includes(type))
12228
+ throw new CliError("validation_error", `a CSV sheet holds one type: --type ${TABLE_RECORD_TYPES.join("|")}`, {
12229
+ param: "--type"
12230
+ });
12231
+ const source = sourceOf5(account2);
12232
+ const batch = `${file === "-" ? "stdin" : basename3(file)}-${(/* @__PURE__ */ new Date()).toISOString()}`;
12233
+ let read;
12234
+ try {
12235
+ read = envelopeOfCsv(await sheetText2(file, stdin), { type, source: { ...source, batch_id: batch } });
12236
+ } catch (error) {
12237
+ if (!(error instanceof TableError))
12238
+ throw error;
12239
+ for (const one2 of error.errors)
12240
+ onIssue(one2);
12241
+ return refusedSheet(dryRun, { ...source, batchId: batch }, error.errors);
12242
+ }
12243
+ const receipt = await ingest(store, read.envelope, {
12244
+ account: source.account,
12245
+ dryRun,
12246
+ onIssue: /* @__PURE__ */ __name((issue) => onIssue({ ...issue, ...read.placeOf(issue.pointer) ? { place: read.placeOf(issue.pointer) } : {} }), "onIssue")
12127
12247
  });
12128
- }, "recordMappingCommands");
12248
+ return {
12249
+ ...receipt,
12250
+ waiting: placed(receipt.waiting, read.placeOf),
12251
+ flagged: placed(receipt.flagged, read.placeOf),
12252
+ unmatched: placed(receipt.unmatched, read.placeOf),
12253
+ ignored: placed(receipt.ignored, read.placeOf),
12254
+ errors: placed(receipt.errors, read.placeOf)
12255
+ };
12256
+ }, "importSheet");
12129
12257
 
12130
12258
  // dist/records/record-commands.js
12131
12259
  var INCOMING = 100;
@@ -12190,8 +12318,14 @@ var recordCommands = /* @__PURE__ */ __name((records, { run, print }, withStore2
12190
12318
 
12191
12319
  // dist/records/import.js
12192
12320
  var kindsOf = /* @__PURE__ */ __name((proposed) => [...new Set(proposed.map((ref) => ref.slice(0, ref.indexOf(":"))))], "kindsOf");
12321
+ var LOCALES = ["en", "ru", "es"];
12322
+ var TEMPLATES_QUERY = defineQuery({
12323
+ entity: "records_templates",
12324
+ backend: "native",
12325
+ fields: [termField("type", "kw", "type:invoice")]
12326
+ });
12193
12327
  var pointerOf = /* @__PURE__ */ __name((pointer) => pointer || "/", "pointerOf");
12194
- var refusedLine = /* @__PURE__ */ __name((one2) => `refused ${pointerOf(one2.pointer)} \xB7 ${one2.message} (${one2.code})`, "refusedLine");
12328
+ var refusedLine = /* @__PURE__ */ __name((one2) => `refused ${one2.place ? placeText(one2.place) : pointerOf(one2.pointer)} \xB7 ${one2.message} (${one2.code})`, "refusedLine");
12195
12329
  var receiptText = /* @__PURE__ */ __name((receipt) => [
12196
12330
  `${receipt.dryRun ? "would import" : "imported"} ${receipt.source?.batchId ?? "nothing"}: ${receipt.created} created, ${receipt.updated} updated, ${receipt.unchanged} unchanged, ${receipt.deleted} deleted, ${receipt.refused} refused`,
12197
12331
  ...receipt.proposed.length ? [
@@ -12210,7 +12344,7 @@ var recordsCommand = /* @__PURE__ */ __name((program, streams, env) => {
12210
12344
  const answered = answers(program, streams, env);
12211
12345
  const { print } = answered;
12212
12346
  const records = program.command("records").description("what a source said, kept per account; what it says about money waits for your review").summary("what a source said, kept per account");
12213
- const importing = /* @__PURE__ */ __name((command, dryRun) => command.argument("<file>", "a records envelope as JSON, JSONL (a header line, then a record per line, read as it streams) or a vCard address book (.vcf, into phone:<device>); - for stdin").option("--account <account>", "the source the envelope is for: <provider>:<account> (sheet:rentals) or its source.account alone; phone:<device> for a vCard file").option("--region <country>", "a vCard file's country for phone numbers without +, such as ru or gb; without it they are kept, not matched").option("--json", "print JSON; --json=created,errors keeps only those fields").action(async (file, given2) => {
12347
+ const importing = /* @__PURE__ */ __name((command, dryRun) => command.argument("<file>", "a records envelope as JSON, JSONL (a header line, then a record per line, read as it streams), a CSV sheet of one --type, or a vCard address book (.vcf, into phone:<device>); - for stdin").option("--type <type>", `the one type a CSV sheet holds: ${TABLE_RECORD_TYPES.join(", ")}`).option("--account <account>", "the source the envelope is for: <provider>:<account> (sheet:rentals) or its source.account alone; phone:<device> for a vCard file").option("--region <country>", "a vCard file's country for phone numbers without +, such as ru or gb; without it they are kept, not matched").option("--json", "print JSON; --json=created,errors keeps only those fields").action(async (file, given2) => {
12214
12348
  const account2 = given2.account?.trim();
12215
12349
  if (!account2)
12216
12350
  throw new CliError("validation_error", "name the source account the envelope is for: --account <account>", {
@@ -12223,7 +12357,8 @@ var recordsCommand = /* @__PURE__ */ __name((program, streams, env) => {
12223
12357
  dryRun: dryRun ?? given2.dryRun === true,
12224
12358
  onIssue: /* @__PURE__ */ __name((issue) => streams.diagnostic(`${refusedLine(issue)}
12225
12359
  `), "onIssue"),
12226
- ...given2.region === void 0 ? {} : { region: given2.region }
12360
+ ...given2.region === void 0 ? {} : { region: given2.region },
12361
+ ...given2.type === void 0 ? {} : { type: given2.type }
12227
12362
  }));
12228
12363
  const issues = receipt.errors.map((one2) => ({
12229
12364
  code: "validation_error",
@@ -12238,6 +12373,34 @@ var recordsCommand = /* @__PURE__ */ __name((program, streams, env) => {
12238
12373
  annotate(records.command("check"), { effects: LOCAL_WRITE, output: { entity: "records_receipt" } }).description(`what records import would do with the file, as its receipt, writing nothing; ${HOLDS_LOCK}`).summary("check a records file against the store; write nothing"),
12239
12374
  true
12240
12375
  );
12376
+ const templates = records.command("templates").description("files to fill for records import: a CSV header row or a JSON envelope, one type each").summary("files to fill for records import");
12377
+ withQuery(annotate(templates.command("list"), { effects: LOCAL_READ, output: { entity: "records_templates" } }), TEMPLATES_QUERY).description("the types a sheet can hold, and their columns: whether each is required, its shape and its values").summary("the types a sheet can hold, with their columns").option("--json", "print JSON; --json=types keeps only those fields").action((words, given2) => {
12378
+ const terms2 = nativeTerms(listQuery(typedQuery(words), TEMPLATES_QUERY, "records templates list"), "records templates list");
12379
+ const wanted = terms2.get("type")?.value;
12380
+ const types = TABLE_RECORD_TYPES.filter((one2) => wanted === void 0 || one2 === wanted).map((one2) => ({
12381
+ type: one2,
12382
+ columns: recordColumns(one2)
12383
+ }));
12384
+ return print(given2.json, itemAnswer({ types }), types.map((one2) => one2.type).join("\n"));
12385
+ });
12386
+ annotate(templates.command("show"), { effects: LOCAL_READ, output: { entity: "records_template" } }).description("the file to fill for one type: the CSV header row (with a byte-order mark, so Excel reads it as UTF-8) or a JSON envelope of one example record").summary("the CSV or JSON file to fill for one type").argument("<type>", `one of ${TABLE_RECORD_TYPES.join(", ")}`).option("--format <format>", "csv or json", "csv").option("--locale <code>", "the language of the Excel that opens it: en takes , and ru or es take ;", "en").option("--account <account>", "the source a JSON template names: <provider>:<account>, such as sheet:rentals").option("--json", "print JSON; --json=text keeps only those fields").action((type, given2) => {
12387
+ if (!TABLE_RECORD_TYPES.includes(type))
12388
+ throw new CliError("validation_error", `no template for ${type}: use one of ${TABLE_RECORD_TYPES.join(", ")}`, {
12389
+ param: "type"
12390
+ });
12391
+ if (given2.format !== "csv" && given2.format !== "json")
12392
+ throw new CliError("validation_error", "--format is csv or json", { param: "--format" });
12393
+ if (!LOCALES.includes(given2.locale))
12394
+ throw new CliError("validation_error", `--locale is one of ${LOCALES.join(", ")}`, { param: "--locale" });
12395
+ const source = given2.account === void 0 ? void 0 : sourceOf5(given2.account);
12396
+ const text3 = recordTemplate(type, given2.format, {
12397
+ separator: given2.locale === "en" ? "," : ";",
12398
+ ...source ? { source } : {}
12399
+ });
12400
+ if (given2.json)
12401
+ return print(true, itemAnswer({ type, format: given2.format, columns: recordColumns(type), text: text3 }));
12402
+ streams.data(text3);
12403
+ });
12241
12404
  recordMappingCommands(records, program, streams, env);
12242
12405
  recordCommands(records, answered, (work) => withStore(env, work));
12243
12406
  }, "recordsCommand");
@@ -12723,7 +12886,7 @@ var syncCommand = /* @__PURE__ */ __name((program, streams, env, signal, keyring
12723
12886
  recordAutoRun(env, startedAt, failedReason(run.failed));
12724
12887
  print(options.json, answer(), text2(run));
12725
12888
  if (run.failed.length > 0)
12726
- process.exitCode = 1;
12889
+ setExitCode(program, 1);
12727
12890
  }, "sync");
12728
12891
  }, "syncCommand");
12729
12892
 
@@ -13356,7 +13519,7 @@ ${note.text}`);
13356
13519
 
13357
13520
  // dist/sources/read.js
13358
13521
  import { readFileSync as readFileSync11, statSync as statSync5 } from "node:fs";
13359
- import { basename as basename3, extname as extname2 } from "node:path";
13522
+ import { basename as basename4, extname as extname2 } from "node:path";
13360
13523
  var SOURCE_TEXT_CHARS = 2e5;
13361
13524
  var URL_LIKE = /^[a-z][a-z0-9+.-]*:\/\//i;
13362
13525
  var isUrl = /* @__PURE__ */ __name((given2) => URL_LIKE.test(given2), "isUrl");
@@ -13433,7 +13596,12 @@ var firstLine2 = /* @__PURE__ */ __name((text3) => {
13433
13596
  const line3 = text3.trimStart().split("\n", 1)[0]?.trim() ?? "";
13434
13597
  return line3 ? line3.slice(0, 120) : null;
13435
13598
  }, "firstLine");
13436
- var titleIn = /* @__PURE__ */ __name((metadata) => typeof metadata?.title === "string" && metadata.title.trim() ? metadata.title.trim().slice(0, 500) : null, "titleIn");
13599
+ var metaText = /* @__PURE__ */ __name((metadata, key) => {
13600
+ const value = metadata?.[key];
13601
+ const first = (Array.isArray(value) ? value : [value]).find((v) => typeof v === "string" && v.trim());
13602
+ return first ? first.trim().slice(0, 500) : null;
13603
+ }, "metaText");
13604
+ var titleIn = /* @__PURE__ */ __name((metadata) => metaText(metadata, "title"), "titleIn");
13437
13605
  var readStdin = /* @__PURE__ */ __name(async (stdin) => {
13438
13606
  const chunks = [];
13439
13607
  let size = 0;
@@ -13464,9 +13632,9 @@ var readText = /* @__PURE__ */ __name(async (stdin, { maxChars }) => {
13464
13632
  title: firstLine2(text3)
13465
13633
  };
13466
13634
  }, "readText");
13467
- var readFile = /* @__PURE__ */ __name(async (path, { maxChars, load = importEngine }) => {
13635
+ var readFile2 = /* @__PURE__ */ __name(async (path, { maxChars, load = importEngine, image }) => {
13468
13636
  const stat = statSync5(path, { throwIfNoEntry: false });
13469
- const name2 = basename3(path);
13637
+ const name2 = basename4(path);
13470
13638
  if (!stat)
13471
13639
  throw new CliError("not_found", `no file ${path}`, { path });
13472
13640
  if (!stat.isFile())
@@ -13485,6 +13653,42 @@ var readFile = /* @__PURE__ */ __name(async (path, { maxChars, load = importEngi
13485
13653
  bytes,
13486
13654
  size: bytes.byteLength
13487
13655
  };
13656
+ const byName = name2.replace(/\.[^.]+$/, "") || name2;
13657
+ if (found.status === "needs-agent" && mime?.startsWith("image/") && image) {
13658
+ const reader2 = image();
13659
+ if ("refused" in reader2)
13660
+ return {
13661
+ ...base,
13662
+ text: "",
13663
+ read: "no-text",
13664
+ extractor: found.extractor ?? null,
13665
+ truncated: false,
13666
+ title: byName,
13667
+ image: { read_by: null, reason: reader2.refused }
13668
+ };
13669
+ const seen = await ocrImage(bytes, reader2.pipeline);
13670
+ if (seen.status === "extracted") {
13671
+ const { text: text4, cut: cut3 } = bounded(seen.text, maxChars);
13672
+ return {
13673
+ ...base,
13674
+ text: text4,
13675
+ read: "extracted",
13676
+ extractor: seen.extractor,
13677
+ truncated: cut3,
13678
+ title: byName,
13679
+ image: { read_by: reader2.by, reason: null }
13680
+ };
13681
+ }
13682
+ return {
13683
+ ...base,
13684
+ text: "",
13685
+ read: "no-text",
13686
+ extractor: reader2.pipeline.extractor,
13687
+ truncated: false,
13688
+ title: byName,
13689
+ image: { read_by: null, reason: seen.status === "needs-agent" ? "image.unsupported" : "ai.failed" }
13690
+ };
13691
+ }
13488
13692
  if (found.status === "needs-agent")
13489
13693
  return {
13490
13694
  ...base,
@@ -13492,7 +13696,7 @@ var readFile = /* @__PURE__ */ __name(async (path, { maxChars, load = importEngi
13492
13696
  read: "no-text",
13493
13697
  extractor: found.extractor ?? null,
13494
13698
  truncated: false,
13495
- title: name2.replace(/\.[^.]+$/, "") || name2
13699
+ title: byName
13496
13700
  };
13497
13701
  if (found.status !== "extracted")
13498
13702
  throw refusal(found, name2);
@@ -13505,7 +13709,7 @@ var readFile = /* @__PURE__ */ __name(async (path, { maxChars, load = importEngi
13505
13709
  read: "extracted",
13506
13710
  extractor: found.extractor,
13507
13711
  truncated: cut2 || found.truncated === true,
13508
- title: titleIn(found.metadata) ?? (name2.replace(/\.[^.]+$/, "") || name2),
13712
+ title: titleIn(found.metadata) ?? byName,
13509
13713
  ...found.metadata ? { metadata: found.metadata } : {},
13510
13714
  ...found.sections ? { sections: found.sections } : {}
13511
13715
  };
@@ -13529,6 +13733,91 @@ var readPage2 = /* @__PURE__ */ __name(async (address, { maxChars, fetch: fetch2
13529
13733
  ...page.sections ? { sections: page.sections } : {}
13530
13734
  };
13531
13735
  }, "readPage");
13736
+ var EXCERPT_CHARS = 800;
13737
+ var previewOf = /* @__PURE__ */ __name((read) => {
13738
+ const flat = read.text.replace(/\s+/g, " ").trim();
13739
+ return {
13740
+ url: read.url ?? null,
13741
+ title: read.title,
13742
+ site: read.url ? new URL(read.url).hostname : null,
13743
+ description: metaText(read.metadata, "description"),
13744
+ // By code point, so an emoji at the cut is never split into half a character.
13745
+ excerpt: flat ? Array.from(flat).slice(0, EXCERPT_CHARS).join("") : null,
13746
+ kind: read.kind,
13747
+ mime: read.mime ?? null,
13748
+ read: read.read,
13749
+ // The store keeps the text trimmed, and sources add answers its length.
13750
+ chars: read.text.trim().length,
13751
+ truncated: read.truncated
13752
+ };
13753
+ }, "previewOf");
13754
+
13755
+ // dist/sources/readers/ai-model.js
13756
+ var SET = "memo models ai set";
13757
+ var chosen = /* @__PURE__ */ __name((context) => aiTextReader({
13758
+ app: APP,
13759
+ env: context.env,
13760
+ fetch: context.fetch,
13761
+ ...context.keyring ? { keyring: context.keyring } : {},
13762
+ ...context.signal ? { signal: context.signal } : {}
13763
+ }), "chosen");
13764
+ var setting = /* @__PURE__ */ __name((env) => {
13765
+ try {
13766
+ return readAiSetting(aiSettingPath(env));
13767
+ } catch {
13768
+ return void 0;
13769
+ }
13770
+ }, "setting");
13771
+ var reader = /* @__PURE__ */ __name((context) => {
13772
+ try {
13773
+ return chosen(context);
13774
+ } catch {
13775
+ return { refused: "ai.not-set" };
13776
+ }
13777
+ }, "reader");
13778
+ var problemOf = /* @__PURE__ */ __name((refused2) => refused2 === "ai.not-set" ? `no AI model is chosen: ${SET}` : `the AI model has no key: ${SET} --secret-stdin`, "problemOf");
13779
+ var aiModel = {
13780
+ id: "ai-model",
13781
+ title: "AI model",
13782
+ provider: "ai-model",
13783
+ leavesComputer: /* @__PURE__ */ __name((env) => {
13784
+ const found = setting(env);
13785
+ return found === void 0 || aiLeavesComputer(found);
13786
+ }, "leavesComputer"),
13787
+ modelOf: /* @__PURE__ */ __name((env) => {
13788
+ const found = setting(env);
13789
+ return found ? `${found.provider}/${found.model}` : null;
13790
+ }, "modelOf"),
13791
+ readsFiles: false,
13792
+ needsModel: false,
13793
+ probe: /* @__PURE__ */ __name(async (context) => {
13794
+ const found = reader(context);
13795
+ const refused2 = "refused" in found ? found.refused : void 0;
13796
+ return {
13797
+ available: refused2 !== "ai.not-set",
13798
+ signedIn: refused2 === void 0,
13799
+ version: null,
13800
+ models: "refused" in found ? null : [found.by],
13801
+ problem: refused2 === void 0 ? null : problemOf(refused2)
13802
+ };
13803
+ }, "probe"),
13804
+ read: /* @__PURE__ */ __name(async (context, { system, prompt }) => {
13805
+ const found = reader(context);
13806
+ if ("refused" in found)
13807
+ throw new CliError("configuration_error", problemOf(found.refused), {
13808
+ reason: found.refused === "ai.not-set" ? "reader.ai-not-set" : "reader.no-key"
13809
+ });
13810
+ try {
13811
+ return await found.complete({ purpose: "sources", system, prompt, maxTokens: 4096 });
13812
+ } catch (error) {
13813
+ if (isCliError(error) && error.code === "rate_limited")
13814
+ throw new CliError("rate_limited", `${found.by} says the limit is reached; try later`, {
13815
+ reason: "reader.limit"
13816
+ });
13817
+ throw new CliError("invalid_response", `${found.by} failed: memo models ai check names the cause (key, model, credit or address)`, { reason: "reader.failed" });
13818
+ }
13819
+ }, "read")
13820
+ };
13532
13821
 
13533
13822
  // dist/sources/readers/keys.js
13534
13823
  var providerKeys = /* @__PURE__ */ __name(({ env, keyring }) => {
@@ -13537,9 +13826,10 @@ var providerKeys = /* @__PURE__ */ __name(({ env, keyring }) => {
13537
13826
  configDir: resolvePaths(where).config,
13538
13827
  service: APP.appName,
13539
13828
  isolated: isMovedRun(where),
13540
- storage: "keyring",
13541
13829
  env,
13542
- ...keyring ? { keyring } : {}
13830
+ ...keyring ? { keyring } : {},
13831
+ warn: /* @__PURE__ */ __name((message) => process.stderr.write(`${message}
13832
+ `), "warn")
13543
13833
  });
13544
13834
  const account2 = /* @__PURE__ */ __name((provider) => `embeddings:${provider}`, "account");
13545
13835
  return {
@@ -13833,10 +14123,13 @@ var ollama = {
13833
14123
  }, "read")
13834
14124
  };
13835
14125
 
14126
+ // dist/sources/readers/types.js
14127
+ var leavesComputer = /* @__PURE__ */ __name((reader2, env) => typeof reader2.leavesComputer === "function" ? reader2.leavesComputer(env) : reader2.leavesComputer, "leavesComputer");
14128
+
13836
14129
  // dist/sources/readers/index.js
13837
- var READERS = [claudeCode, codex, ollama, openaiReader, anthropicReader];
13838
- var READER_IDS = READERS.map((reader) => reader.id);
13839
- var readerOf = /* @__PURE__ */ __name((id) => READERS.find((reader) => reader.id === id), "readerOf");
14130
+ var READERS = [aiModel, claudeCode, codex, ollama, openaiReader, anthropicReader];
14131
+ var READER_IDS = READERS.map((reader2) => reader2.id);
14132
+ var readerOf = /* @__PURE__ */ __name((id) => READERS.find((reader2) => reader2.id === id), "readerOf");
13840
14133
 
13841
14134
  // dist/sources/suggest.js
13842
14135
  import { createHash as createHash4, randomUUID as randomUUID2 } from "node:crypto";
@@ -13930,12 +14223,12 @@ var knownFacts = /* @__PURE__ */ __name(async (store, ref) => {
13930
14223
  return known2;
13931
14224
  }, "knownFacts");
13932
14225
  var suggestFacts = /* @__PURE__ */ __name(async (store, context, input) => {
13933
- const { record: record2, reader, model, subject } = input;
13934
- const key = batchKey({ fingerprint: record2.fingerprint, reader: reader.id, model, subject, again: input.again });
14226
+ const { record: record2, reader: reader2, model, subject } = input;
14227
+ const key = batchKey({ fingerprint: record2.fingerprint, reader: reader2.id, model, subject, again: input.again });
13935
14228
  const held = await stagedUnder(store, key);
13936
14229
  if (held)
13937
14230
  return { key, reused: true, batch: held, dropped: [] };
13938
- const answer = await reader.read(context, { system: SYSTEM, prompt: promptFor(record2), model });
14231
+ const answer = await reader2.read(context, { system: SYSTEM, prompt: promptFor(record2), model });
13939
14232
  const { facts, dropped } = factsIn(answer, record2.text);
13940
14233
  const known2 = await knownFacts(store, record2.reference);
13941
14234
  const fresh = facts.filter((fact) => {
@@ -13959,7 +14252,7 @@ var suggestFacts = /* @__PURE__ */ __name(async (store, context, input) => {
13959
14252
  evidence: [{ reference: record2.reference, fingerprint: record2.fingerprint, quote: fact.quote }]
13960
14253
  }))
13961
14254
  };
13962
- const batch = await store.evidenceFindings.stage(findings, { bot: READER_BOT, model: `${reader.id}/${model ?? "default"}` }, { ownerOnly: true });
14255
+ const batch = await store.evidenceFindings.stage(findings, { bot: READER_BOT, model: `${reader2.id}/${model ?? "default"}` }, { ownerOnly: true });
13963
14256
  return { key, reused: false, batch, dropped };
13964
14257
  }, "suggestFacts");
13965
14258
 
@@ -13982,7 +14275,11 @@ var unknownReader = /* @__PURE__ */ __name((id) => {
13982
14275
  readers: READER_IDS
13983
14276
  });
13984
14277
  }, "unknownReader");
13985
- var chosen = /* @__PURE__ */ __name((env, who, given2) => {
14278
+ var fixedModel = /* @__PURE__ */ __name((reader2) => new CliError("validation_error", `${reader2.title} reads with the model memo models ai set chose; --model is not taken`, {
14279
+ reason: "input.invalid",
14280
+ param: "model"
14281
+ }), "fixedModel");
14282
+ var chosen2 = /* @__PURE__ */ __name((env, who, given2) => {
13986
14283
  if (who !== "owner" && (given2.reader !== void 0 || given2.model !== void 0))
13987
14284
  throw new CliError("permission_error", "only the owner picks the reader; an agent uses the one the owner chose", {
13988
14285
  reason: "reader.owner-picks"
@@ -13991,11 +14288,16 @@ var chosen = /* @__PURE__ */ __name((env, who, given2) => {
13991
14288
  const id = given2.reader ?? config?.reader;
13992
14289
  if (id === void 0)
13993
14290
  throw new CliError("configuration_error", `no reader is chosen for sources; the owner picks one of ${READER_IDS.join(", ")} with memo sources readers set <reader>, or names it with --provider`, { reason: "reader.none-chosen", readers: READER_IDS });
13994
- const reader = readerOf(id) ?? unknownReader(id);
14291
+ const reader2 = readerOf(id) ?? unknownReader(id);
14292
+ if (reader2.modelOf) {
14293
+ if (given2.model !== void 0)
14294
+ throw fixedModel(reader2);
14295
+ return { reader: reader2, model: reader2.modelOf(env) };
14296
+ }
13995
14297
  const model = given2.model ?? (given2.reader === void 0 || given2.reader === config?.reader ? config?.model : void 0);
13996
- if (reader.needsModel && !model)
13997
- throw new CliError("configuration_error", `${reader.title} reads only with a model the owner names: memo sources readers set ${reader.id} --model <model>`, { reason: "reader.model-missing" });
13998
- return { reader, model: model ?? null };
14298
+ if (reader2.needsModel && !model)
14299
+ throw new CliError("configuration_error", `${reader2.title} reads only with a model the owner names: memo sources readers set ${reader2.id} --model <model>`, { reason: "reader.model-missing" });
14300
+ return { reader: reader2, model: model ?? null };
13999
14301
  }, "chosen");
14000
14302
  var documentRef = /* @__PURE__ */ __name(async (store, reference2) => {
14001
14303
  await refuseBareNumber(store, reference2, ["document", "note"]);
@@ -14017,7 +14319,7 @@ var readerCommands = /* @__PURE__ */ __name((program, sources, streams, env, dep
14017
14319
  if (isAgentServer(command, env))
14018
14320
  throw new CliError("permission_error", "over MCP an agent cannot send a source's text to a reader");
14019
14321
  const who = await whoRuns(command, env, { asOwner: options.asOwner, question: "read this source as you?" });
14020
- const { reader, model } = chosen(env, who, { reader: options.provider, model: options.model });
14322
+ const { reader: reader2, model } = chosen2(env, who, { reader: options.provider, model: options.model });
14021
14323
  const item = await withStore(env, async (store) => {
14022
14324
  const ref = await documentRef(store, reference2);
14023
14325
  const subject = options.subject === void 0 ? null : (await subjectOf(store, options.subject)).ref;
@@ -14031,16 +14333,16 @@ var readerCommands = /* @__PURE__ */ __name((program, sources, streams, env, dep
14031
14333
  throw new CliError("not_found", `${ref} is not stored`, { reason: "input.invalid" });
14032
14334
  const done = await suggestFacts(store, context(), {
14033
14335
  record: record2,
14034
- reader,
14336
+ reader: reader2,
14035
14337
  model,
14036
14338
  subject,
14037
14339
  again: options.rescan === true
14038
14340
  });
14039
14341
  return {
14040
14342
  ref,
14041
- reader: reader.id,
14343
+ reader: reader2.id,
14042
14344
  model,
14043
- leavesComputer: reader.leavesComputer,
14345
+ leavesComputer: leavesComputer(reader2, env),
14044
14346
  reused: done.reused,
14045
14347
  batch: done.batch?.id ?? null,
14046
14348
  fingerprint: done.batch?.fingerprint ?? null,
@@ -14057,7 +14359,7 @@ var readerCommands = /* @__PURE__ */ __name((program, sources, streams, env, dep
14057
14359
  };
14058
14360
  });
14059
14361
  print(options.json, itemAnswer(item), [
14060
- item.batch === null ? `${item.ref} ${reader.title} found no fact the text supports` : `${item.ref} ${item.facts.length} fact${item.facts.length === 1 ? "" : "s"} waiting for you in batch ${item.batch}${item.reused ? " (read before; the reader was not asked again)" : ""}`,
14362
+ item.batch === null ? `${item.ref} ${reader2.title} found no fact the text supports` : `${item.ref} ${item.facts.length} fact${item.facts.length === 1 ? "" : "s"} waiting for you in batch ${item.batch}${item.reused ? " (read before; the reader was not asked again)" : ""}`,
14061
14363
  ...item.facts.map((fact) => ` ${fact.id} ${fact.statement}
14062
14364
  "${fact.quote}"`),
14063
14365
  ...item.dropped.length ? [` dropped ${item.dropped.length}: ${item.dropped.map((d) => d.why).join(", ")}`] : [],
@@ -14072,21 +14374,21 @@ var readerCommands = /* @__PURE__ */ __name((program, sources, streams, env, dep
14072
14374
  const terms2 = nativeTerms(listQuery(typedQuery(words), READERS_QUERY, "sources readers list"), "sources readers list");
14073
14375
  const config = loadConfig(env).sources;
14074
14376
  const wanted = terms2.get("id")?.value;
14075
- const all = await Promise.all(READERS.filter((reader) => wanted === void 0 || reader.id === wanted).map(async (reader) => {
14076
- const probe = await reader.probe(context());
14077
- const picked = config?.reader === reader.id;
14377
+ const all = await Promise.all(READERS.filter((reader2) => wanted === void 0 || reader2.id === wanted).map(async (reader2) => {
14378
+ const probe = await reader2.probe(context());
14379
+ const picked = config?.reader === reader2.id;
14078
14380
  return {
14079
- id: reader.id,
14080
- title: reader.title,
14081
- provider: reader.provider,
14381
+ id: reader2.id,
14382
+ title: reader2.title,
14383
+ provider: reader2.provider,
14082
14384
  available: probe.available,
14083
14385
  signedIn: probe.signedIn,
14084
14386
  version: probe.version,
14085
- model: picked ? config?.model ?? null : null,
14387
+ model: reader2.modelOf ? reader2.modelOf(env) : picked ? config?.model ?? null : null,
14086
14388
  models: probe.models,
14087
- needsModel: reader.needsModel,
14088
- leavesComputer: reader.leavesComputer,
14089
- readsFiles: reader.readsFiles,
14389
+ needsModel: reader2.needsModel,
14390
+ leavesComputer: leavesComputer(reader2, env),
14391
+ readsFiles: reader2.readsFiles,
14090
14392
  chosen: picked,
14091
14393
  problem: probe.problem
14092
14394
  };
@@ -14103,20 +14405,22 @@ var readerCommands = /* @__PURE__ */ __name((program, sources, streams, env, dep
14103
14405
  throw new CliError("permission_error", "only the owner picks the reader that reads a source", {
14104
14406
  reason: "reader.owner-picks"
14105
14407
  });
14106
- const reader = readerOf(id) ?? unknownReader(id);
14107
- if (reader.needsModel && !options.model?.trim())
14108
- throw new CliError("validation_error", `${reader.title} needs --model <model>`, {
14408
+ const reader2 = readerOf(id) ?? unknownReader(id);
14409
+ if (reader2.modelOf && options.model !== void 0)
14410
+ throw fixedModel(reader2);
14411
+ if (reader2.needsModel && !options.model?.trim())
14412
+ throw new CliError("validation_error", `${reader2.title} needs --model <model>`, {
14109
14413
  reason: "reader.model-missing",
14110
14414
  param: "model"
14111
14415
  });
14112
14416
  const model = options.model?.trim() || void 0;
14113
- updateConfig((config) => ({ ...config, sources: { reader: reader.id, ...model ? { model } : {} } }), env);
14417
+ updateConfig((config) => ({ ...config, sources: { reader: reader2.id, ...model ? { model } : {} } }), env);
14114
14418
  print(options.json, itemAnswer({
14115
- reader: reader.id,
14419
+ reader: reader2.id,
14116
14420
  model: model ?? null,
14117
- leavesComputer: reader.leavesComputer,
14118
- readsFiles: reader.readsFiles
14119
- }), `sources are read with ${reader.title}${model ? ` (${model})` : ""}`);
14421
+ leavesComputer: leavesComputer(reader2, env),
14422
+ readsFiles: reader2.readsFiles
14423
+ }), `sources are read with ${reader2.title}${model ? ` (${model})` : ""}`);
14120
14424
  });
14121
14425
  }, "readerCommands");
14122
14426
 
@@ -14167,6 +14471,16 @@ var citing = /* @__PURE__ */ __name(async (store, ref) => {
14167
14471
  const of = /* @__PURE__ */ __name((type) => [...new Set(links.flatMap(({ from }) => from.startsWith(`${type}:`) ? [from] : []))], "of");
14168
14472
  return { facts: of("fact"), memories: of("memory") };
14169
14473
  }, "citing");
14474
+ var IMAGE_WHY = {
14475
+ "ai.not-set": "kept by its name: no AI model is chosen (memo models ai set)",
14476
+ "ai.images-not-allowed": "kept by its name: images may not go to your AI model (memo models ai set \u2026 --allow-remote)",
14477
+ "ai.key-missing": "kept by its name: no key is stored for your AI model (memo models ai set \u2026 --secret-stdin)",
14478
+ "ai.owner-only": "kept by its name: only your own add sends an image to your AI model, not an agent's",
14479
+ "ai.setting-invalid": "kept by its name: the ai section of the WireCat config is not one memo can read (memo models ai set)",
14480
+ "image.unsupported": "kept by its name: the model reads PNG, JPEG and WebP up to 4 MB",
14481
+ "ai.failed": "kept by its name: your AI model could not read it (memo models ai check)"
14482
+ };
14483
+ var imageLine = /* @__PURE__ */ __name((image) => image.read_by ? `read by ${image.read_by}` : IMAGE_WHY[image.reason ?? "ai.failed"], "imageLine");
14170
14484
  var sourcesCommand = /* @__PURE__ */ __name((program, streams, env, { fetch: fetch2, readers = {} } = {}) => {
14171
14485
  const { print, run } = answers(program, streams, env);
14172
14486
  const sources = program.command("sources").summary("files, web pages and text you add by hand").description("sources you add by hand: pasted text, a file or a web page, kept as searchable documents");
@@ -14182,7 +14496,19 @@ var sourcesCommand = /* @__PURE__ */ __name((program, streams, env, { fetch: fet
14182
14496
  const maxChars = options.maxChars ?? SOURCE_TEXT_CHARS;
14183
14497
  const who = await whoRuns(command, env, { asOwner: options.asOwner, question: "add this source as yours?" });
14184
14498
  const by = who === "owner" ? "owner" : { bot: who.bot, reason: options.reason?.trim() || "memo sources add" };
14185
- const read = await (kind === "text" ? readText(environmentOf(command).stdin ?? process.stdin, { maxChars }) : kind === "url" ? readPage2(given2, { maxChars, ...fetch2 ? { fetch: fetch2 } : {} }) : readFile(given2, { maxChars })).catch((error) => {
14499
+ const read = await (kind === "text" ? readText(environmentOf(command).stdin ?? process.stdin, { maxChars }) : kind === "url" ? readPage2(given2, { maxChars, ...fetch2 ? { fetch: fetch2 } : {} }) : readFile2(given2, {
14500
+ maxChars,
14501
+ // An agent's add never sends the owner's image off this computer; the consent was for the owner's own adds.
14502
+ image: /* @__PURE__ */ __name(() => {
14503
+ if (who !== "owner")
14504
+ return { refused: "ai.owner-only" };
14505
+ try {
14506
+ return aiImageReader({ app: APP, env, keyring: readers.keyring, fetch: readers.fetch });
14507
+ } catch {
14508
+ return { refused: "ai.setting-invalid" };
14509
+ }
14510
+ }, "image")
14511
+ })).catch((error) => {
14186
14512
  throw withNextStep(error);
14187
14513
  });
14188
14514
  const content = {
@@ -14238,7 +14564,8 @@ var sourcesCommand = /* @__PURE__ */ __name((program, streams, env, { fetch: fet
14238
14564
  words: text3,
14239
14565
  meaning: text3 && searchModelPresent(env) && loadConfig(env).notes?.embed !== false
14240
14566
  },
14241
- subjects: saved.subjects
14567
+ subjects: saved.subjects,
14568
+ ...read.image ? { image: read.image } : {}
14242
14569
  };
14243
14570
  });
14244
14571
  print(options.json, itemAnswer(item), [
@@ -14246,9 +14573,30 @@ var sourcesCommand = /* @__PURE__ */ __name((program, streams, env, { fetch: fet
14246
14573
  ` ${item.title ?? ""} ${item.kind}${item.mime ? ` \xB7 ${item.mime}` : ""} \xB7 ${item.chars} characters${item.truncated === true ? " (only the first part is kept)" : ""}`,
14247
14574
  ` kept: ${item.kept === "copy" ? "its text and a copy of the file" : item.kept === "text" ? "its text" : "nothing new"}`,
14248
14575
  ` search: ${item.searchable.words ? "by words" : "by its title and subjects only"}${item.searchable.meaning ? " and by meaning after memo sync" : ""}`,
14576
+ ...item.image ? [` image: ${imageLine(item.image)}`] : [],
14249
14577
  ...item.subjects.length ? [` about: ${item.subjects.join(", ")}`] : []
14250
14578
  ].join("\n"));
14251
14579
  });
14580
+ annotate(sources.command("preview"), { effects: REMOTE_READ, output: { entity: "source_preview" } }).summary("read a web page as sources add would, and keep nothing").description("read a web page as sources add would, with the same refusals, and say what would be kept; nothing is saved").argument("<url>", "an http(s) address").option("--json", "print JSON; --json=title,excerpt keeps only those fields").action(async (given2, options, command) => {
14581
+ if (isAgentServer2(command, env))
14582
+ throw new CliError("permission_error", "an agent over MCP cannot make memo fetch an address", {
14583
+ reason: "source.agent-fetch"
14584
+ });
14585
+ if (argumentKind(given2) !== "url")
14586
+ throw new CliError("validation_error", "give an http(s) address; a file is previewed by the app that picked it", {
14587
+ reason: "input.invalid"
14588
+ });
14589
+ const read = await readPage2(given2, { maxChars: SOURCE_TEXT_CHARS, ...fetch2 ? { fetch: fetch2 } : {} }).catch((error) => {
14590
+ throw withNextStep(error);
14591
+ });
14592
+ const item = previewOf(read);
14593
+ print(options.json, itemAnswer(item), [
14594
+ `${item.url} nothing saved`,
14595
+ ` ${item.title ?? ""} ${item.kind}${item.mime ? ` \xB7 ${item.mime}` : ""} \xB7 ${item.chars} characters${item.truncated ? " (only the first part would be kept)" : ""}`,
14596
+ ...item.description ? [` ${item.description}`] : [],
14597
+ ...item.excerpt ? [` \u201C${item.excerpt}\u201D`] : []
14598
+ ].join("\n"));
14599
+ });
14252
14600
  annotate(sources.command("show"), { effects: LOCAL_READ, output: { entity: "source_detail" } }).summary("one source: its text, what is kept, and what cites it").description("one source: its text, what is kept, what it is about, and the facts, memories and batches citing it").argument("<ref>", "document:<id>, as sources add answered").option("--bytes <bytes>", `most UTF-8 bytes of its text, up to ${MAX_TEXT_BYTES} (default ${TEXT_BYTES})`, between(1, MAX_TEXT_BYTES, "--bytes")).option("--json", "print JSON; --json=id,title keeps only those fields").action((reference2, options) => run(options.json, async (store) => {
14253
14601
  const ref = await documentRef2(store, reference2);
14254
14602
  const source = await store.notes.addedSource(ref);
@@ -14970,6 +15318,7 @@ var OWN_ENTITIES = entityFields({
14970
15318
  "searchable",
14971
15319
  "subjects"
14972
15320
  ],
15321
+ source_preview: ["url", "title", "site", "description", "excerpt", "kind", "mime", "read", "chars", "truncated"],
14973
15322
  source_detail: [
14974
15323
  "ref",
14975
15324
  "title",
@@ -15257,6 +15606,8 @@ var OWN_ENTITIES = entityFields({
15257
15606
  "updated_at",
15258
15607
  "deleted_at"
15259
15608
  ],
15609
+ records_templates: ["types"],
15610
+ records_template: ["type", "format", "columns", "text"],
15260
15611
  records_receipt: [
15261
15612
  "dry_run",
15262
15613
  "source",
@@ -15535,11 +15886,13 @@ var FIRST_SCREEN = {
15535
15886
  profile: false,
15536
15887
  start: "memo folders add <path>"
15537
15888
  };
15538
- var createProgram = /* @__PURE__ */ __name(({ streams: raw = processStreams, env: given2 = process.env, signal, terminal, keyring, fetchPage: fetchPage2, group, stdin, readerFetch, system } = {}) => {
15889
+ var createProgram = /* @__PURE__ */ __name(({ streams: raw = processStreams, env: given2 = process.env, signal, terminal, keyring, fetchPage: fetchPage2, group, stdin, readerFetch, system, setExitCode: setExitCode2 } = {}) => {
15539
15890
  const env = group === void 0 ? given2 : { ...given2, MEMO_GROUP: group };
15540
15891
  const fields = jsonFields(raw, OWN_ENTITIES);
15541
15892
  const { streams } = fields;
15542
15893
  const program = new Command("memo").description("context about people across messengers, notes and mail").version(VERSION).option("--debug", "on failure, show the full error record: cause and stack");
15894
+ if (setExitCode2)
15895
+ keepExitCode(program, setExitCode2);
15543
15896
  refuseWritesUnderLock(program, env);
15544
15897
  scopeRunsToGroup(program, env, group);
15545
15898
  provideTerminal(program, terminal);