@jungjaehoon/mama-os 0.77.0 → 0.79.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (338) hide show
  1. package/CHANGELOG.md +446 -0
  2. package/README.md +59 -30
  3. package/db/migrations/002-model-runs-parent-index.sql +11 -0
  4. package/db/migrations/003-upkeep-settled.sql +15 -0
  5. package/dist/api/google-read-actions.d.ts +30 -0
  6. package/dist/api/google-read-actions.d.ts.map +1 -0
  7. package/dist/api/google-read-actions.js +256 -0
  8. package/dist/api/google-read-actions.js.map +1 -0
  9. package/dist/api/record-actions.d.ts.map +1 -1
  10. package/dist/api/record-actions.js +23 -5
  11. package/dist/api/record-actions.js.map +1 -1
  12. package/dist/api/report-handler.d.ts +0 -6
  13. package/dist/api/report-handler.d.ts.map +1 -1
  14. package/dist/api/report-handler.js +0 -54
  15. package/dist/api/report-handler.js.map +1 -1
  16. package/dist/api/security-events.d.ts +1 -1
  17. package/dist/api/security-events.d.ts.map +1 -1
  18. package/dist/api/security-events.js +10 -1
  19. package/dist/api/security-events.js.map +1 -1
  20. package/dist/api/source-actions.d.ts +9 -0
  21. package/dist/api/source-actions.d.ts.map +1 -1
  22. package/dist/api/source-actions.js +49 -0
  23. package/dist/api/source-actions.js.map +1 -1
  24. package/dist/api/viewer-request-security.d.ts +14 -1
  25. package/dist/api/viewer-request-security.d.ts.map +1 -1
  26. package/dist/api/viewer-request-security.js +26 -3
  27. package/dist/api/viewer-request-security.js.map +1 -1
  28. package/dist/api/viewer-server.d.ts +8 -0
  29. package/dist/api/viewer-server.d.ts.map +1 -1
  30. package/dist/api/viewer-server.js +66 -0
  31. package/dist/api/viewer-server.js.map +1 -1
  32. package/dist/api/work-actions.d.ts +19 -2
  33. package/dist/api/work-actions.d.ts.map +1 -1
  34. package/dist/api/work-actions.js +42 -2
  35. package/dist/api/work-actions.js.map +1 -1
  36. package/dist/cli/commands/backfill.d.ts.map +1 -1
  37. package/dist/cli/commands/backfill.js +1 -0
  38. package/dist/cli/commands/backfill.js.map +1 -1
  39. package/dist/cli/commands/backup.d.ts +14 -0
  40. package/dist/cli/commands/backup.d.ts.map +1 -0
  41. package/dist/cli/commands/backup.js +174 -0
  42. package/dist/cli/commands/backup.js.map +1 -0
  43. package/dist/cli/commands/control.d.ts +44 -0
  44. package/dist/cli/commands/control.d.ts.map +1 -0
  45. package/dist/cli/commands/control.js +354 -0
  46. package/dist/cli/commands/control.js.map +1 -0
  47. package/dist/cli/commands/daemon.d.ts +60 -3
  48. package/dist/cli/commands/daemon.d.ts.map +1 -1
  49. package/dist/cli/commands/daemon.js +454 -78
  50. package/dist/cli/commands/daemon.js.map +1 -1
  51. package/dist/cli/commands/doctor.d.ts +13 -0
  52. package/dist/cli/commands/doctor.d.ts.map +1 -0
  53. package/dist/cli/commands/doctor.js +216 -0
  54. package/dist/cli/commands/doctor.js.map +1 -0
  55. package/dist/cli/commands/init-questions.d.ts +98 -0
  56. package/dist/cli/commands/init-questions.d.ts.map +1 -0
  57. package/dist/cli/commands/init-questions.js +420 -0
  58. package/dist/cli/commands/init-questions.js.map +1 -0
  59. package/dist/cli/commands/init-section.d.ts +13 -0
  60. package/dist/cli/commands/init-section.d.ts.map +1 -0
  61. package/dist/cli/commands/init-section.js +375 -0
  62. package/dist/cli/commands/init-section.js.map +1 -0
  63. package/dist/cli/commands/init.d.ts +56 -2
  64. package/dist/cli/commands/init.d.ts.map +1 -1
  65. package/dist/cli/commands/init.js +562 -350
  66. package/dist/cli/commands/init.js.map +1 -1
  67. package/dist/cli/commands/logs.d.ts +9 -0
  68. package/dist/cli/commands/logs.d.ts.map +1 -0
  69. package/dist/cli/commands/logs.js +109 -0
  70. package/dist/cli/commands/logs.js.map +1 -0
  71. package/dist/cli/commands/node-move.d.ts +20 -0
  72. package/dist/cli/commands/node-move.d.ts.map +1 -0
  73. package/dist/cli/commands/node-move.js +289 -0
  74. package/dist/cli/commands/node-move.js.map +1 -0
  75. package/dist/cli/commands/register-owner.d.ts +3 -0
  76. package/dist/cli/commands/register-owner.d.ts.map +1 -1
  77. package/dist/cli/commands/register-owner.js +14 -0
  78. package/dist/cli/commands/register-owner.js.map +1 -1
  79. package/dist/cli/commands/restore.d.ts +16 -0
  80. package/dist/cli/commands/restore.d.ts.map +1 -0
  81. package/dist/cli/commands/restore.js +137 -0
  82. package/dist/cli/commands/restore.js.map +1 -0
  83. package/dist/cli/commands/service.d.ts +44 -0
  84. package/dist/cli/commands/service.d.ts.map +1 -0
  85. package/dist/cli/commands/service.js +306 -0
  86. package/dist/cli/commands/service.js.map +1 -0
  87. package/dist/cli/commands/tools.d.ts +1 -1
  88. package/dist/cli/commands/tools.d.ts.map +1 -1
  89. package/dist/cli/commands/tools.js +8 -3
  90. package/dist/cli/commands/tools.js.map +1 -1
  91. package/dist/cli/commands/uninstall.d.ts +7 -0
  92. package/dist/cli/commands/uninstall.d.ts.map +1 -0
  93. package/dist/cli/commands/uninstall.js +335 -0
  94. package/dist/cli/commands/uninstall.js.map +1 -0
  95. package/dist/cli/commands/update.d.ts +59 -0
  96. package/dist/cli/commands/update.d.ts.map +1 -0
  97. package/dist/cli/commands/update.js +948 -0
  98. package/dist/cli/commands/update.js.map +1 -0
  99. package/dist/cli/index.js +74 -23
  100. package/dist/cli/index.js.map +1 -1
  101. package/dist/cli/launch-files.d.ts +119 -0
  102. package/dist/cli/launch-files.d.ts.map +1 -1
  103. package/dist/cli/launch-files.js +324 -15
  104. package/dist/cli/launch-files.js.map +1 -1
  105. package/dist/cli/prompt.d.ts +2 -1
  106. package/dist/cli/prompt.d.ts.map +1 -1
  107. package/dist/cli/prompt.js +5 -2
  108. package/dist/cli/prompt.js.map +1 -1
  109. package/dist/cli/runtime/backend-probe.d.ts +34 -0
  110. package/dist/cli/runtime/backend-probe.d.ts.map +1 -0
  111. package/dist/cli/runtime/backend-probe.js +83 -0
  112. package/dist/cli/runtime/backend-probe.js.map +1 -0
  113. package/dist/cli/runtime/backup.d.ts +130 -0
  114. package/dist/cli/runtime/backup.d.ts.map +1 -0
  115. package/dist/cli/runtime/backup.js +592 -0
  116. package/dist/cli/runtime/backup.js.map +1 -0
  117. package/dist/cli/runtime/daemon-control.d.ts +169 -0
  118. package/dist/cli/runtime/daemon-control.d.ts.map +1 -0
  119. package/dist/cli/runtime/daemon-control.js +441 -0
  120. package/dist/cli/runtime/daemon-control.js.map +1 -0
  121. package/dist/cli/runtime/default-roots.d.ts +27 -0
  122. package/dist/cli/runtime/default-roots.d.ts.map +1 -0
  123. package/dist/cli/runtime/default-roots.js +61 -0
  124. package/dist/cli/runtime/default-roots.js.map +1 -0
  125. package/dist/cli/runtime/diagnostics.d.ts +68 -0
  126. package/dist/cli/runtime/diagnostics.d.ts.map +1 -0
  127. package/dist/cli/runtime/diagnostics.js +1139 -0
  128. package/dist/cli/runtime/diagnostics.js.map +1 -0
  129. package/dist/cli/runtime/init-state.d.ts +20 -0
  130. package/dist/cli/runtime/init-state.d.ts.map +1 -0
  131. package/dist/cli/runtime/init-state.js +51 -0
  132. package/dist/cli/runtime/init-state.js.map +1 -0
  133. package/dist/cli/runtime/install-kind.d.ts +54 -0
  134. package/dist/cli/runtime/install-kind.d.ts.map +1 -0
  135. package/dist/cli/runtime/install-kind.js +164 -0
  136. package/dist/cli/runtime/install-kind.js.map +1 -0
  137. package/dist/cli/runtime/node-move-journal.d.ts +44 -0
  138. package/dist/cli/runtime/node-move-journal.d.ts.map +1 -0
  139. package/dist/cli/runtime/node-move-journal.js +48 -0
  140. package/dist/cli/runtime/node-move-journal.js.map +1 -0
  141. package/dist/cli/runtime/release-check.d.ts +94 -0
  142. package/dist/cli/runtime/release-check.d.ts.map +1 -0
  143. package/dist/cli/runtime/release-check.js +316 -0
  144. package/dist/cli/runtime/release-check.js.map +1 -0
  145. package/dist/cli/runtime/restore.d.ts +98 -0
  146. package/dist/cli/runtime/restore.d.ts.map +1 -0
  147. package/dist/cli/runtime/restore.js +756 -0
  148. package/dist/cli/runtime/restore.js.map +1 -0
  149. package/dist/cli/runtime/setup-page.d.ts +57 -0
  150. package/dist/cli/runtime/setup-page.d.ts.map +1 -0
  151. package/dist/cli/runtime/setup-page.js +266 -0
  152. package/dist/cli/runtime/setup-page.js.map +1 -0
  153. package/dist/cli/runtime/source-tools.d.ts +60 -0
  154. package/dist/cli/runtime/source-tools.d.ts.map +1 -0
  155. package/dist/cli/runtime/source-tools.js +170 -0
  156. package/dist/cli/runtime/source-tools.js.map +1 -0
  157. package/dist/cli/runtime/systemd-service.d.ts +13 -0
  158. package/dist/cli/runtime/systemd-service.d.ts.map +1 -0
  159. package/dist/cli/runtime/systemd-service.js +32 -0
  160. package/dist/cli/runtime/systemd-service.js.map +1 -0
  161. package/dist/cli/runtime/telegram-pairing.d.ts +73 -0
  162. package/dist/cli/runtime/telegram-pairing.d.ts.map +1 -0
  163. package/dist/cli/runtime/telegram-pairing.js +184 -0
  164. package/dist/cli/runtime/telegram-pairing.js.map +1 -0
  165. package/dist/cli/runtime/update-journal.d.ts +135 -0
  166. package/dist/cli/runtime/update-journal.d.ts.map +1 -0
  167. package/dist/cli/runtime/update-journal.js +144 -0
  168. package/dist/cli/runtime/update-journal.js.map +1 -0
  169. package/dist/cli/runtime/update-progress.d.ts +95 -0
  170. package/dist/cli/runtime/update-progress.d.ts.map +1 -0
  171. package/dist/cli/runtime/update-progress.js +154 -0
  172. package/dist/cli/runtime/update-progress.js.map +1 -0
  173. package/dist/cli/runtime/update-request.d.ts +58 -0
  174. package/dist/cli/runtime/update-request.d.ts.map +1 -0
  175. package/dist/cli/runtime/update-request.js +172 -0
  176. package/dist/cli/runtime/update-request.js.map +1 -0
  177. package/dist/connectors/calendar/index.d.ts +5 -1
  178. package/dist/connectors/calendar/index.d.ts.map +1 -1
  179. package/dist/connectors/calendar/index.js +19 -28
  180. package/dist/connectors/calendar/index.js.map +1 -1
  181. package/dist/connectors/chatwork/index.d.ts.map +1 -1
  182. package/dist/connectors/chatwork/index.js +7 -3
  183. package/dist/connectors/chatwork/index.js.map +1 -1
  184. package/dist/connectors/config-loader.d.ts +7 -1
  185. package/dist/connectors/config-loader.d.ts.map +1 -1
  186. package/dist/connectors/config-loader.js +11 -2
  187. package/dist/connectors/config-loader.js.map +1 -1
  188. package/dist/connectors/discord/index.d.ts.map +1 -1
  189. package/dist/connectors/discord/index.js +4 -3
  190. package/dist/connectors/discord/index.js.map +1 -1
  191. package/dist/connectors/drive/index.d.ts.map +1 -1
  192. package/dist/connectors/drive/index.js +15 -13
  193. package/dist/connectors/drive/index.js.map +1 -1
  194. package/dist/connectors/framework/gws-utils.d.ts +62 -0
  195. package/dist/connectors/framework/gws-utils.d.ts.map +1 -1
  196. package/dist/connectors/framework/gws-utils.js +133 -3
  197. package/dist/connectors/framework/gws-utils.js.map +1 -1
  198. package/dist/connectors/framework/polling-scheduler.d.ts.map +1 -1
  199. package/dist/connectors/framework/polling-scheduler.js +12 -11
  200. package/dist/connectors/framework/polling-scheduler.js.map +1 -1
  201. package/dist/connectors/framework/types.d.ts +24 -0
  202. package/dist/connectors/framework/types.d.ts.map +1 -1
  203. package/dist/connectors/framework/types.js +9 -0
  204. package/dist/connectors/framework/types.js.map +1 -1
  205. package/dist/connectors/gmail/index.d.ts.map +1 -1
  206. package/dist/connectors/gmail/index.js +14 -13
  207. package/dist/connectors/gmail/index.js.map +1 -1
  208. package/dist/connectors/imessage/index.d.ts.map +1 -1
  209. package/dist/connectors/imessage/index.js +2 -1
  210. package/dist/connectors/imessage/index.js.map +1 -1
  211. package/dist/connectors/index.d.ts +4 -4
  212. package/dist/connectors/index.d.ts.map +1 -1
  213. package/dist/connectors/index.js +4 -10
  214. package/dist/connectors/index.js.map +1 -1
  215. package/dist/connectors/notion/index.d.ts.map +1 -1
  216. package/dist/connectors/notion/index.js +5 -3
  217. package/dist/connectors/notion/index.js.map +1 -1
  218. package/dist/connectors/sheets/index.d.ts.map +1 -1
  219. package/dist/connectors/sheets/index.js +17 -12
  220. package/dist/connectors/sheets/index.js.map +1 -1
  221. package/dist/connectors/slack/index.d.ts.map +1 -1
  222. package/dist/connectors/slack/index.js +9 -3
  223. package/dist/connectors/slack/index.js.map +1 -1
  224. package/dist/connectors/telegram/index.d.ts.map +1 -1
  225. package/dist/connectors/telegram/index.js +4 -3
  226. package/dist/connectors/telegram/index.js.map +1 -1
  227. package/dist/connectors/trello/index.d.ts +1 -1
  228. package/dist/connectors/trello/index.d.ts.map +1 -1
  229. package/dist/connectors/trello/index.js +10 -5
  230. package/dist/connectors/trello/index.js.map +1 -1
  231. package/dist/gateways/discord.d.ts +6 -0
  232. package/dist/gateways/discord.d.ts.map +1 -1
  233. package/dist/gateways/discord.js +38 -27
  234. package/dist/gateways/discord.js.map +1 -1
  235. package/dist/gateways/slack.d.ts +6 -0
  236. package/dist/gateways/slack.d.ts.map +1 -1
  237. package/dist/gateways/slack.js +38 -27
  238. package/dist/gateways/slack.js.map +1 -1
  239. package/dist/gateways/telegram-commands.d.ts +124 -0
  240. package/dist/gateways/telegram-commands.d.ts.map +1 -0
  241. package/dist/gateways/telegram-commands.js +131 -0
  242. package/dist/gateways/telegram-commands.js.map +1 -0
  243. package/dist/gateways/telegram.d.ts +20 -0
  244. package/dist/gateways/telegram.d.ts.map +1 -1
  245. package/dist/gateways/telegram.js +138 -34
  246. package/dist/gateways/telegram.js.map +1 -1
  247. package/dist/gateways/turn-contract.d.ts +11 -0
  248. package/dist/gateways/turn-contract.d.ts.map +1 -1
  249. package/dist/runtime/action-surface.d.ts +1 -1
  250. package/dist/runtime/action-surface.d.ts.map +1 -1
  251. package/dist/runtime/action-surface.js +10 -0
  252. package/dist/runtime/action-surface.js.map +1 -1
  253. package/dist/runtime/backend-security.d.ts +26 -2
  254. package/dist/runtime/backend-security.d.ts.map +1 -1
  255. package/dist/runtime/backend-security.js +63 -10
  256. package/dist/runtime/backend-security.js.map +1 -1
  257. package/dist/runtime/config.d.ts +3 -0
  258. package/dist/runtime/config.d.ts.map +1 -1
  259. package/dist/runtime/config.js +4 -4
  260. package/dist/runtime/config.js.map +1 -1
  261. package/dist/runtime/connectors.d.ts +21 -1
  262. package/dist/runtime/connectors.d.ts.map +1 -1
  263. package/dist/runtime/connectors.js +28 -17
  264. package/dist/runtime/connectors.js.map +1 -1
  265. package/dist/runtime/core-db.d.ts.map +1 -1
  266. package/dist/runtime/core-db.js +2 -0
  267. package/dist/runtime/core-db.js.map +1 -1
  268. package/dist/runtime/member-paths.d.ts +15 -7
  269. package/dist/runtime/member-paths.d.ts.map +1 -1
  270. package/dist/runtime/member-paths.js +64 -12
  271. package/dist/runtime/member-paths.js.map +1 -1
  272. package/dist/runtime/member-session.d.ts +4 -0
  273. package/dist/runtime/member-session.d.ts.map +1 -1
  274. package/dist/runtime/member-session.js +23 -2
  275. package/dist/runtime/member-session.js.map +1 -1
  276. package/dist/runtime/native-session.d.ts +2 -0
  277. package/dist/runtime/native-session.d.ts.map +1 -1
  278. package/dist/runtime/native-session.js +1 -0
  279. package/dist/runtime/native-session.js.map +1 -1
  280. package/dist/runtime/owner-runtime.d.ts +63 -1
  281. package/dist/runtime/owner-runtime.d.ts.map +1 -1
  282. package/dist/runtime/owner-runtime.js +180 -3
  283. package/dist/runtime/owner-runtime.js.map +1 -1
  284. package/dist/runtime/owner-system-prompt.d.ts.map +1 -1
  285. package/dist/runtime/owner-system-prompt.js +6 -5
  286. package/dist/runtime/owner-system-prompt.js.map +1 -1
  287. package/dist/runtime/principal-access.d.ts +2 -0
  288. package/dist/runtime/principal-access.d.ts.map +1 -1
  289. package/dist/runtime/principal-access.js +7 -0
  290. package/dist/runtime/principal-access.js.map +1 -1
  291. package/dist/runtime/principal-sessions.d.ts.map +1 -1
  292. package/dist/runtime/principal-sessions.js +8 -1
  293. package/dist/runtime/principal-sessions.js.map +1 -1
  294. package/dist/runtime/record-orders.d.ts.map +1 -1
  295. package/dist/runtime/record-orders.js +3 -29
  296. package/dist/runtime/record-orders.js.map +1 -1
  297. package/dist/runtime/report-scheduler.d.ts +9 -2
  298. package/dist/runtime/report-scheduler.d.ts.map +1 -1
  299. package/dist/runtime/report-scheduler.js +37 -10
  300. package/dist/runtime/report-scheduler.js.map +1 -1
  301. package/dist/runtime/rotating-log.d.ts +44 -0
  302. package/dist/runtime/rotating-log.d.ts.map +1 -0
  303. package/dist/runtime/rotating-log.js +124 -0
  304. package/dist/runtime/rotating-log.js.map +1 -0
  305. package/dist/runtime/stimulus-delivery.d.ts +3 -0
  306. package/dist/runtime/stimulus-delivery.d.ts.map +1 -1
  307. package/dist/runtime/stimulus-delivery.js +19 -3
  308. package/dist/runtime/stimulus-delivery.js.map +1 -1
  309. package/dist/runtime/tools-paths.d.ts +7 -0
  310. package/dist/runtime/tools-paths.d.ts.map +1 -1
  311. package/dist/runtime/tools-paths.js +11 -5
  312. package/dist/runtime/tools-paths.js.map +1 -1
  313. package/dist/runtime/upkeep-close.d.ts +17 -0
  314. package/dist/runtime/upkeep-close.d.ts.map +1 -0
  315. package/dist/runtime/upkeep-close.js +127 -0
  316. package/dist/runtime/upkeep-close.js.map +1 -0
  317. package/dist/runtime/upkeep-orders.d.ts +124 -0
  318. package/dist/runtime/upkeep-orders.d.ts.map +1 -0
  319. package/dist/runtime/upkeep-orders.js +310 -0
  320. package/dist/runtime/upkeep-orders.js.map +1 -0
  321. package/dist/runtime/upkeep-reconcile.d.ts +25 -0
  322. package/dist/runtime/upkeep-reconcile.d.ts.map +1 -0
  323. package/dist/runtime/upkeep-reconcile.js +231 -0
  324. package/dist/runtime/upkeep-reconcile.js.map +1 -0
  325. package/dist/runtime/upkeep-writeback.d.ts +22 -0
  326. package/dist/runtime/upkeep-writeback.d.ts.map +1 -0
  327. package/dist/runtime/upkeep-writeback.js +203 -0
  328. package/dist/runtime/upkeep-writeback.js.map +1 -0
  329. package/dist/tools/document-toolkit.d.ts +2 -0
  330. package/dist/tools/document-toolkit.d.ts.map +1 -1
  331. package/dist/tools/document-toolkit.js +2 -0
  332. package/dist/tools/document-toolkit.js.map +1 -1
  333. package/dist/utils/untrusted-content.d.ts.map +1 -1
  334. package/dist/utils/untrusted-content.js +8 -1
  335. package/dist/utils/untrusted-content.js.map +1 -1
  336. package/install/install.sh +457 -0
  337. package/install/node.json +9 -0
  338. package/package.json +5 -5
@@ -0,0 +1,95 @@
1
+ import { defaultTelegramCall } from './diagnostics.js';
2
+ export type UpdateProgress = {
3
+ readonly kind: 'plan';
4
+ readonly from: string;
5
+ readonly to: string;
6
+ } | {
7
+ readonly kind: 'current';
8
+ readonly version: string;
9
+ } | {
10
+ readonly kind: 'step';
11
+ readonly from: string;
12
+ readonly to: string;
13
+ readonly step: number;
14
+ }
15
+ /** A step of the new version failed; the rollback reports next. */
16
+ | {
17
+ readonly kind: 'failed';
18
+ readonly from: string;
19
+ readonly to: string;
20
+ readonly step: number;
21
+ readonly code: string | null;
22
+ }
23
+ /** The stop or the snapshot failed; nothing was swapped. */
24
+ | {
25
+ readonly kind: 'not_updated';
26
+ readonly from: string;
27
+ readonly to: string;
28
+ readonly step: number;
29
+ readonly code: string;
30
+ } | {
31
+ readonly kind: 'rolling_back';
32
+ readonly from: string;
33
+ readonly to: string;
34
+ } | {
35
+ readonly kind: 'rolled_back';
36
+ readonly from: string;
37
+ readonly to: string;
38
+ readonly step: number;
39
+ } | {
40
+ readonly kind: 'rollback_stopped';
41
+ readonly from: string;
42
+ readonly to: string;
43
+ }
44
+ /** `running`: the daemon answered the release; false when it is not running now. */
45
+ | {
46
+ readonly kind: 'updated';
47
+ readonly from: string;
48
+ readonly to: string;
49
+ readonly running: boolean;
50
+ }
51
+ /** The update ended on an error: a refusal before anything changed, or a step that threw. */
52
+ | {
53
+ readonly kind: 'error';
54
+ readonly code: string;
55
+ };
56
+ /** The step table's names (update.md, PR 3), for the chat. */
57
+ export declare const UPDATE_STEP_NAMES: Readonly<Record<number, string>>;
58
+ /** A code as the chat may see it: a token, never free text. */
59
+ export declare function progressCode(value: unknown): string | null;
60
+ export declare function progressText(event: UpdateProgress): string;
61
+ export interface ProgressSink {
62
+ send(event: UpdateProgress): void;
63
+ /**
64
+ * Wait until every event sent so far has gone out (or failed and been logged). Past
65
+ * PROGRESS_FLUSH_DEADLINE_MS, step messages not yet sent are dropped and counted in the log;
66
+ * the outcomes (updated, failed, rolled back, …) are still sent, each within its own timeout.
67
+ */
68
+ flush(): Promise<void>;
69
+ }
70
+ /**
71
+ * One send's limit. The flushes before a child CLI and at the end run while MAMA is stopped, so
72
+ * a Bot API that does not answer must not hold the install down; Telegram answers in well under
73
+ * a second when it answers at all.
74
+ */
75
+ export declare const PROGRESS_SEND_TIMEOUT_MS = 3000;
76
+ /**
77
+ * How long a flush waits for step messages: past it, the steps still queued are dropped, so a
78
+ * slow Bot API holds the stopped install for this plus the few outcome sends at most.
79
+ */
80
+ export declare const PROGRESS_FLUSH_DEADLINE_MS = 5000;
81
+ export declare const NO_PROGRESS: ProgressSink;
82
+ export type TelegramCall = typeof defaultTelegramCall;
83
+ /**
84
+ * Progress to the /update's chat through the Bot API's sendMessage alone: the daemon may be
85
+ * stopped, and a getUpdates here would take its updates. The chat comes from
86
+ * runtime/update-request.json and the bot token alone from auth.env, as doctor reads it. A send
87
+ * that fails is logged (to update.log, the job's output) and the update goes on. Repeats of a step
88
+ * (the journal is saved more than once in a step) are sent once.
89
+ */
90
+ export declare function telegramProgress(options: {
91
+ root: string;
92
+ log: (line: string) => void;
93
+ call?: TelegramCall;
94
+ }): ProgressSink;
95
+ //# sourceMappingURL=update-progress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-progress.d.ts","sourceRoot":"","sources":["../../../src/cli/runtime/update-progress.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NO_PROGRESS = exports.PROGRESS_FLUSH_DEADLINE_MS = exports.PROGRESS_SEND_TIMEOUT_MS = exports.UPDATE_STEP_NAMES = void 0;
4
+ exports.progressCode = progressCode;
5
+ exports.progressText = progressText;
6
+ exports.telegramProgress = telegramProgress;
7
+ const daemon_js_1 = require("../commands/daemon.js");
8
+ const diagnostics_js_1 = require("./diagnostics.js");
9
+ const update_request_js_1 = require("./update-request.js");
10
+ /** The step table's names (update.md, PR 3), for the chat. */
11
+ exports.UPDATE_STEP_NAMES = {
12
+ 5: 'stage the new version',
13
+ 6: 'drain and stop',
14
+ 7: 'snapshot',
15
+ 8: 'swap',
16
+ 9: 'hand over to the new version',
17
+ 10: 'service files',
18
+ 11: 'doctor',
19
+ 12: 'toolkit',
20
+ 13: 'start held',
21
+ 14: 'wait for the boot',
22
+ };
23
+ const VERSION = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/;
24
+ const CODE = /^[A-Za-z0-9_.]{1,64}$/;
25
+ function version(value) {
26
+ return VERSION.test(value) ? value : 'unknown';
27
+ }
28
+ /** A code as the chat may see it: a token, never free text. */
29
+ function progressCode(value) {
30
+ return typeof value === 'string' && CODE.test(value) ? value : null;
31
+ }
32
+ function step(number) {
33
+ const name = exports.UPDATE_STEP_NAMES[number];
34
+ return name === undefined ? `step ${number}` : `step ${number} (${name})`;
35
+ }
36
+ function progressText(event) {
37
+ switch (event.kind) {
38
+ case 'plan':
39
+ return `update ${version(event.from)} → ${version(event.to)}: starting`;
40
+ case 'current':
41
+ return `already on ${version(event.version)}`;
42
+ case 'step':
43
+ return `update ${version(event.from)} → ${version(event.to)}: ${step(event.step)}`;
44
+ case 'failed':
45
+ return `update ${version(event.from)} → ${version(event.to)}: ${step(event.step)} failed${progressCode(event.code) === null ? '' : `: ${progressCode(event.code)}`}`;
46
+ case 'not_updated':
47
+ return `not updated: ${step(event.step)} failed: ${progressCode(event.code) ?? 'UNKNOWN'}; ${version(event.from)} stays installed`;
48
+ case 'rolling_back':
49
+ return `rolling back to ${version(event.from)}`;
50
+ case 'rolled_back':
51
+ return `rolled back: ${version(event.from)} runs again; ${step(event.step)} of the update to ${version(event.to)} failed`;
52
+ case 'rollback_stopped':
53
+ return `the rollback to ${version(event.from)} stopped; MAMA stays stopped until mama update --rollback runs on its machine`;
54
+ case 'updated':
55
+ return event.running
56
+ ? `updated: ${version(event.from)} → ${version(event.to)}; it runs`
57
+ : `updated: ${version(event.from)} → ${version(event.to)}; MAMA is not running now; start it on its machine`;
58
+ case 'error':
59
+ return `update ended: ${progressCode(event.code) ?? 'UNKNOWN'}; the update log on MAMA's machine has the details`;
60
+ }
61
+ }
62
+ /**
63
+ * One send's limit. The flushes before a child CLI and at the end run while MAMA is stopped, so
64
+ * a Bot API that does not answer must not hold the install down; Telegram answers in well under
65
+ * a second when it answers at all.
66
+ */
67
+ exports.PROGRESS_SEND_TIMEOUT_MS = 3_000;
68
+ /**
69
+ * How long a flush waits for step messages: past it, the steps still queued are dropped, so a
70
+ * slow Bot API holds the stopped install for this plus the few outcome sends at most.
71
+ */
72
+ exports.PROGRESS_FLUSH_DEADLINE_MS = 5_000;
73
+ exports.NO_PROGRESS = {
74
+ send: () => { },
75
+ flush: async () => { },
76
+ };
77
+ /**
78
+ * Progress to the /update's chat through the Bot API's sendMessage alone: the daemon may be
79
+ * stopped, and a getUpdates here would take its updates. The chat comes from
80
+ * runtime/update-request.json and the bot token alone from auth.env, as doctor reads it. A send
81
+ * that fails is logged (to update.log, the job's output) and the update goes on. Repeats of a step
82
+ * (the journal is saved more than once in a step) are sent once.
83
+ */
84
+ function telegramProgress(options) {
85
+ const call = options.call ?? diagnostics_js_1.defaultTelegramCall;
86
+ let target = null;
87
+ let chain = Promise.resolve();
88
+ /** Step messages queued and not yet begun; a flush past its deadline drops them. */
89
+ let queuedSteps = 0;
90
+ let generation = 0;
91
+ let lastStep = null;
92
+ const deliver = async (text) => {
93
+ try {
94
+ if (target === null) {
95
+ const request = (0, update_request_js_1.readUpdateRequest)((0, update_request_js_1.updateRequestPath)(options.root));
96
+ if (request === null)
97
+ throw new Error('no runtime/update-request.json');
98
+ const name = daemon_js_1.MESSENGER_SECRETS.telegram[0];
99
+ const token = (0, diagnostics_js_1.readAuthEnv)(options.root)[name];
100
+ if (!token?.trim())
101
+ throw new Error(`auth.env has no ${name}`);
102
+ target = { token, chatId: request.chatId };
103
+ }
104
+ const reply = await call(target.token, 'sendMessage', { chat_id: target.chatId, text }, exports.PROGRESS_SEND_TIMEOUT_MS);
105
+ if (reply.ok !== true) {
106
+ options.log(`update progress not sent: Telegram answered ${String(reply.error_code ?? 'not ok')}`);
107
+ }
108
+ }
109
+ catch (error) {
110
+ const text = error instanceof Error ? `${error.name}: ${error.message}` : String(error);
111
+ // The request's URL holds the token; an error that quotes it does not reach the log.
112
+ const token = target?.token;
113
+ options.log(`update progress not sent: ${token ? text.split(token).join('<token>') : text}`);
114
+ }
115
+ };
116
+ return {
117
+ send: (event) => {
118
+ if (event.kind === 'step') {
119
+ if (event.step === lastStep)
120
+ return;
121
+ lastStep = event.step;
122
+ }
123
+ const text = progressText(event);
124
+ const queuedIn = generation;
125
+ const isStep = event.kind === 'step';
126
+ if (isStep)
127
+ queuedSteps += 1;
128
+ chain = chain.then(async () => {
129
+ if (isStep) {
130
+ queuedSteps -= 1;
131
+ if (queuedIn !== generation)
132
+ return;
133
+ }
134
+ await deliver(text);
135
+ });
136
+ },
137
+ flush: async () => {
138
+ let timer;
139
+ const late = new Promise((resolve) => {
140
+ timer = setTimeout(() => resolve('late'), exports.PROGRESS_FLUSH_DEADLINE_MS);
141
+ });
142
+ const outcome = await Promise.race([chain.then(() => 'sent'), late]);
143
+ clearTimeout(timer);
144
+ if (outcome === 'late') {
145
+ // Steps queued now are skipped; the one in flight and the outcomes still go, each
146
+ // within PROGRESS_SEND_TIMEOUT_MS.
147
+ options.log(`update progress: ${queuedSteps} step message(s) not sent within ${exports.PROGRESS_FLUSH_DEADLINE_MS} ms; dropped`);
148
+ generation += 1;
149
+ await chain;
150
+ }
151
+ },
152
+ };
153
+ }
154
+ //# sourceMappingURL=update-progress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-progress.js","sourceRoot":"","sources":["../../../src/cli/runtime/update-progress.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ import type { UpdateOrigin } from '../../gateways/telegram-commands.js';
2
+ import type { ServiceRun } from './systemd-service.js';
3
+ /** The systemd unit the update job runs as on Linux. */
4
+ export declare const UPDATE_JOB_UNIT = "mama-update";
5
+ /** The /update an update job reports to; kept after the run, so a repeat of it is refused. */
6
+ export interface UpdateRequest {
7
+ readonly chatId: string;
8
+ readonly messageId: number;
9
+ readonly receivedAt: string;
10
+ }
11
+ /** Under runtime/, which the agents' native reads deny. */
12
+ export declare function updateRequestPath(mamaRoot: string): string;
13
+ export declare function readUpdateRequest(path: string): UpdateRequest | null;
14
+ export type UpdateJobResult = {
15
+ readonly kind: 'started';
16
+ readonly from: string;
17
+ readonly to: string | null;
18
+ }
19
+ /**
20
+ * `lock`: an updater holds update.lock, a terminal's `mama update` or an /update's; `job`: the
21
+ * update job runs (it reports to its request's chat). `since`: when the lock was taken, or the
22
+ * request's time; null when unknown.
23
+ */
24
+ | {
25
+ readonly kind: 'busy';
26
+ readonly source: 'lock' | 'job';
27
+ readonly since: number | null;
28
+ } | {
29
+ readonly kind: 'repeated';
30
+ } | {
31
+ readonly kind: 'checkout';
32
+ readonly steps: readonly string[];
33
+ } | {
34
+ readonly kind: 'not_updatable';
35
+ readonly reason: string;
36
+ };
37
+ export interface UpdateJobOptions {
38
+ readonly mamaRoot: string;
39
+ readonly home: string;
40
+ readonly origin: UpdateOrigin;
41
+ /** The running daemon's version. */
42
+ readonly version: string;
43
+ readonly platform: NodeJS.Platform;
44
+ /** launchctl and systemd-run go through it; tests record them. */
45
+ readonly run: ServiceRun;
46
+ readonly uid: number;
47
+ /** The daemon's log: what the reply leaves out is named there. */
48
+ readonly log: (line: string) => void;
49
+ readonly now?: () => Date;
50
+ }
51
+ /**
52
+ * Start `mama update` for an /update. In order: the install kind (a checkout gets its git
53
+ * steps); an updater holding update.lock, or the job still running, is left alone; a message
54
+ * already recorded is refused, since a daemon killed before it confirmed its offset receives it
55
+ * again; then the request is recorded, the job's files written, and the job started.
56
+ */
57
+ export declare function requestUpdate(options: UpdateJobOptions): UpdateJobResult;
58
+ //# sourceMappingURL=update-request.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-request.d.ts","sourceRoot":"","sources":["../../../src/cli/runtime/update-request.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAC;AAExE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAWvD,wDAAwD;AACxD,eAAO,MAAM,eAAe,gBAAgB,CAAC;AAE7C,8FAA8F;AAC9F,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,2DAA2D;AAC3D,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAapE;AASD,MAAM,MAAM,eAAe,GACvB;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE;AACjF;;;;GAIG;GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GACzF;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;CAAE,GAC7B;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GAChE;IAAE,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,oCAAoC;IACpC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC;IACnC,kEAAkE;IAClE,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC;IACzB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,kEAAkE;IAClE,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B;AAmDD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,gBAAgB,GAAG,eAAe,CA4DxE"}
@@ -0,0 +1,172 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UPDATE_JOB_UNIT = void 0;
4
+ exports.updateRequestPath = updateRequestPath;
5
+ exports.readUpdateRequest = readUpdateRequest;
6
+ exports.requestUpdate = requestUpdate;
7
+ const node_fs_1 = require("node:fs");
8
+ const node_path_1 = require("node:path");
9
+ const launch_files_js_1 = require("../launch-files.js");
10
+ const daemon_control_js_1 = require("./daemon-control.js");
11
+ const install_kind_js_1 = require("./install-kind.js");
12
+ const release_check_js_1 = require("./release-check.js");
13
+ const update_journal_js_1 = require("./update-journal.js");
14
+ /*
15
+ * /update, the daemon's side (docs/development/work/update.md, PR 4): it starts `mama update` as
16
+ * a job of its own, which outlives the daemon's stop, and records where its progress goes.
17
+ */
18
+ /** The systemd unit the update job runs as on Linux. */
19
+ exports.UPDATE_JOB_UNIT = 'mama-update';
20
+ /** Under runtime/, which the agents' native reads deny. */
21
+ function updateRequestPath(mamaRoot) {
22
+ return (0, node_path_1.join)(mamaRoot, 'runtime', 'update-request.json');
23
+ }
24
+ function readUpdateRequest(path) {
25
+ if (!(0, node_fs_1.existsSync)(path))
26
+ return null;
27
+ const value = JSON.parse((0, node_fs_1.readFileSync)(path, 'utf8'));
28
+ if (value === null ||
29
+ typeof value !== 'object' ||
30
+ typeof value.chatId !== 'string' ||
31
+ typeof value.messageId !== 'number' ||
32
+ typeof value.receivedAt !== 'string') {
33
+ throw new Error(`${path} is not an update request MAMA wrote`);
34
+ }
35
+ return value;
36
+ }
37
+ function writeStaged(path, content, mode) {
38
+ const staged = `${path}.${process.pid}.tmp`;
39
+ (0, node_fs_1.writeFileSync)(staged, content, { mode });
40
+ (0, node_fs_1.chmodSync)(staged, mode);
41
+ (0, node_fs_1.renameSync)(staged, path);
42
+ }
43
+ /**
44
+ * The update job as `launchctl print` shows it: not loaded; finished (the top-level `state = not
45
+ * running` with a real `last exit code`, or a `last terminating signal` for a job killed by one),
46
+ * which a new /update boots out; or anything else loaded, which runs or is starting. Two /update messages are answered concurrently, and right after a bootstrap the job
47
+ * can be loaded with no pid yet; booting that out would kill the update the first one started.
48
+ */
49
+ function launchdJob(run, uid) {
50
+ const result = run('launchctl', ['print', `gui/${uid}/${launch_files_js_1.UPDATE_JOB_LABEL}`]);
51
+ if (result.error)
52
+ throw result.error;
53
+ if (result.status === 113)
54
+ return 'none';
55
+ if (result.status !== 0) {
56
+ throw new Error(`launchctl print ${launch_files_js_1.UPDATE_JOB_LABEL} failed: exit ${String(result.status)}`);
57
+ }
58
+ // Top-level lines carry one tab; the nested sections' own `state = active` lines carry two.
59
+ const state = /^\tstate = (.+?)\s*$/m.exec(result.stdout)?.[1];
60
+ const exited = /^\tlast exit code = (?!\(never exited\))\S/m.test(result.stdout) ||
61
+ /^\tlast terminating signal = \S/m.test(result.stdout);
62
+ return state === 'not running' && exited ? 'finished' : 'running';
63
+ }
64
+ /** Run launchctl or systemd-run; a failure throws with the command and its own words. */
65
+ function check(run, command, args) {
66
+ const result = run(command, args);
67
+ if (result.error)
68
+ throw new Error(`${command} ${args[0]} could not run: ${result.error.message}`);
69
+ if (result.status !== 0) {
70
+ const detail = `${result.stderr ?? ''}`.trim() || `exit ${String(result.status)}`;
71
+ throw new Error(`${command} ${args.join(' ')} failed: ${detail}`);
72
+ }
73
+ }
74
+ /** systemd states in which the update unit still runs. */
75
+ const SYSTEMD_RUNNING = new Set(['active', 'activating', 'deactivating', 'reloading']);
76
+ /** Whether the update job still runs: the request file must not change under it. */
77
+ function jobRuns(options) {
78
+ if (options.platform === 'darwin') {
79
+ const job = launchdJob(options.run, options.uid);
80
+ return { loaded: job !== 'none', running: job === 'running' };
81
+ }
82
+ if (options.platform === 'linux') {
83
+ // `is-active` exits non-zero for a unit that does not run; its word says which state.
84
+ const result = options.run('systemctl', ['--user', 'is-active', `${exports.UPDATE_JOB_UNIT}.service`]);
85
+ if (result.error)
86
+ throw result.error;
87
+ return { loaded: false, running: SYSTEMD_RUNNING.has(`${result.stdout ?? ''}`.trim()) };
88
+ }
89
+ throw new Error('/update runs the updater as a launchd or systemd job: macOS and Linux only');
90
+ }
91
+ /**
92
+ * Start `mama update` for an /update. In order: the install kind (a checkout gets its git
93
+ * steps); an updater holding update.lock, or the job still running, is left alone; a message
94
+ * already recorded is refused, since a daemon killed before it confirmed its offset receives it
95
+ * again; then the request is recorded, the job's files written, and the job started.
96
+ */
97
+ function requestUpdate(options) {
98
+ const { mamaRoot, home } = options;
99
+ const install = (0, install_kind_js_1.installKind)(mamaRoot, home);
100
+ if (install.kind === 'checkout')
101
+ return { kind: 'checkout', steps: (0, install_kind_js_1.updateSteps)(install) };
102
+ if (install.kind === 'other')
103
+ return { kind: 'not_updatable', reason: install.reason };
104
+ const holder = (0, daemon_control_js_1.lockHolder)((0, update_journal_js_1.updatePaths)(mamaRoot).lock);
105
+ if (holder !== null)
106
+ return { kind: 'busy', source: 'lock', since: holder.startedAt || null };
107
+ const requestPath = updateRequestPath(mamaRoot);
108
+ const previous = readUpdateRequest(requestPath);
109
+ const job = jobRuns(options);
110
+ if (job.running) {
111
+ return {
112
+ kind: 'busy',
113
+ source: 'job',
114
+ since: previous === null ? null : Date.parse(previous.receivedAt),
115
+ };
116
+ }
117
+ if (previous?.chatId === options.origin.chatId && previous.messageId === options.origin.messageId)
118
+ return { kind: 'repeated' };
119
+ const now = options.now?.() ?? new Date();
120
+ const request = {
121
+ chatId: options.origin.chatId,
122
+ messageId: options.origin.messageId,
123
+ receivedAt: now.toISOString(),
124
+ };
125
+ writeStaged(requestPath, `${JSON.stringify(request)}\n`, 0o600);
126
+ const script = (0, node_path_1.join)(mamaRoot, 'runtime', 'update.sh');
127
+ writeStaged(script, (0, launch_files_js_1.updateScript)({
128
+ home,
129
+ start: (0, node_fs_1.readFileSync)((0, node_path_1.join)(mamaRoot, 'start.sh'), 'utf8'),
130
+ nodePath: install.nodePath,
131
+ cliPath: install.cliPath,
132
+ }), 0o700);
133
+ // Before the job starts: nothing that can throw runs after it.
134
+ const to = cachedNewer(mamaRoot, options.version, options.log);
135
+ const log = (0, node_path_1.join)(mamaRoot, 'logs', 'update.log');
136
+ if (options.platform === 'darwin') {
137
+ const plist = (0, node_path_1.join)(mamaRoot, 'runtime', 'update.plist');
138
+ writeStaged(plist, (0, launch_files_js_1.updateAgent)(home), 0o600);
139
+ const domain = `gui/${options.uid}`;
140
+ // A finished job stays loaded without a pid; its label bootstraps again once booted out.
141
+ if (job.loaded)
142
+ check(options.run, 'launchctl', ['bootout', `${domain}/${launch_files_js_1.UPDATE_JOB_LABEL}`]);
143
+ check(options.run, 'launchctl', ['bootstrap', domain, plist]);
144
+ }
145
+ else {
146
+ check(options.run, 'systemd-run', [
147
+ '--user',
148
+ `--unit=${exports.UPDATE_JOB_UNIT}`,
149
+ '--collect',
150
+ `--property=StandardOutput=append:${log}`,
151
+ `--property=StandardError=append:${log}`,
152
+ script,
153
+ ]);
154
+ }
155
+ return { kind: 'started', from: options.version, to };
156
+ }
157
+ /**
158
+ * The cached release check's newer version, for the reply only: the updater asks npm itself
159
+ * (step 2), so a cache that is a day old, failed or unreadable leaves the reply without one.
160
+ */
161
+ function cachedNewer(mamaRoot, running, log) {
162
+ try {
163
+ const latest = (0, release_check_js_1.readReleaseCheck)((0, release_check_js_1.releaseCheckPath)(mamaRoot))?.latest ?? null;
164
+ return latest !== null && (0, release_check_js_1.compareReleases)(latest, running) > 0 ? latest : null;
165
+ }
166
+ catch (error) {
167
+ // /update repairs installs (R7): a release check it cannot read leaves only the reply short.
168
+ log(`update request: the cached release check cannot be read (${error instanceof Error ? error.message : String(error)}); the reply names no target`);
169
+ return null;
170
+ }
171
+ }
172
+ //# sourceMappingURL=update-request.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-request.js","sourceRoot":"","sources":["../../../src/cli/runtime/update-request.ts"],"names":[],"mappings":"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"}
@@ -13,7 +13,11 @@ export declare class CalendarConnector implements IConnector {
13
13
  constructor(config: ConnectorConfig, statePath: string);
14
14
  commitPoll(): void;
15
15
  abortPollHandoff(): void;
16
- private verifyAccess;
16
+ /**
17
+ * Starting needs only gws, as for the other Google sources. The sign-in is the read check in
18
+ * authenticate(): a sign-in that has ended (a testing-mode client's, after 7 days) fails each
19
+ * poll and doctor's check, and does not stop MAMA from starting.
20
+ */
17
21
  init(): Promise<void>;
18
22
  dispose(): Promise<void>;
19
23
  healthCheck(): Promise<ConnectorHealth>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/connectors/calendar/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EACf,eAAe,EACf,UAAU,EACV,cAAc,EACd,mBAAmB,EACpB,MAAM,uBAAuB,CAAC;AAqC/B,qBAAa,iBAAkB,YAAW,UAAU;IAgBhD,OAAO,CAAC,QAAQ,CAAC,SAAS;IAf5B,QAAQ,CAAC,IAAI,cAAc;IAC3B,QAAQ,CAAC,IAAI,EAAG,KAAK,CAAU;IAC/B,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,SAAS,CAAqB;IAItC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoD;IAC9E,8FAA8F;IAC9F,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IACrC,OAAO,CAAC,aAAa,CAA4B;gBAG/C,MAAM,EAAE,eAAe,EACN,SAAS,EAAE,MAAM;IAwBpC,UAAU,IAAI,IAAI;IAOlB,gBAAgB,IAAI,IAAI;YAIV,YAAY;IAWpB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAarB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAExB,WAAW,IAAI,OAAO,CAAC,eAAe,CAAC;IAS7C,mBAAmB,IAAI,eAAe,EAAE;IAYlC,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC;IAShC,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;CAiHjF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/connectors/calendar/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EACf,eAAe,EACf,UAAU,EACV,cAAc,EACd,mBAAmB,EACpB,MAAM,uBAAuB,CAAC;AA6C/B,qBAAa,iBAAkB,YAAW,UAAU;IAgBhD,OAAO,CAAC,QAAQ,CAAC,SAAS;IAf5B,QAAQ,CAAC,IAAI,cAAc;IAC3B,QAAQ,CAAC,IAAI,EAAG,KAAK,CAAU;IAC/B,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,SAAS,CAAqB;IAItC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoD;IAC9E,8FAA8F;IAC9F,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IACrC,OAAO,CAAC,aAAa,CAA4B;gBAG/C,MAAM,EAAE,eAAe,EACN,SAAS,EAAE,MAAM;IAwBpC,UAAU,IAAI,IAAI;IAOlB,gBAAgB,IAAI,IAAI;IAIxB;;;;OAIG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAQrB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAExB,WAAW,IAAI,OAAO,CAAC,eAAe,CAAC;IAS7C,mBAAmB,IAAI,eAAe,EAAE;IAUlC,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC;IAWhC,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;CAiHjF"}
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CalendarConnector = void 0;
4
4
  /** Google Calendar snapshots through the authorised gws CLI on the daemon's PATH. */
5
5
  const node_crypto_1 = require("node:crypto");
6
+ const types_js_1 = require("../framework/types.js");
6
7
  const gws_utils_js_1 = require("../framework/gws-utils.js");
7
8
  const connector_state_js_1 = require("../framework/connector-state.js");
8
9
  const MAX_EVENT_LIST_PAGES = 20;
@@ -61,27 +62,17 @@ class CalendarConnector {
61
62
  abortPollHandoff() {
62
63
  this.pendingSynced = null;
63
64
  }
64
- async verifyAccess() {
65
- // auth status can succeed without Calendar scope. Exercise the read permission itself.
66
- await (0, gws_utils_js_1.execGwsAsync)([
67
- 'calendar',
68
- 'events',
69
- 'list',
70
- '--params',
71
- JSON.stringify({ calendarId: this.calendars[0]?.id ?? 'primary', maxResults: 1 }),
72
- ]);
73
- }
65
+ /**
66
+ * Starting needs only gws, as for the other Google sources. The sign-in is the read check in
67
+ * authenticate(): a sign-in that has ended (a testing-mode client's, after 7 days) fails each
68
+ * poll and doctor's check, and does not stop MAMA from starting.
69
+ */
74
70
  async init() {
75
71
  try {
76
- await this.verifyAccess();
77
- this.lastError = undefined;
72
+ await (0, gws_utils_js_1.execGwsTextAsync)(['--version']);
78
73
  }
79
74
  catch (error) {
80
- this.lastError =
81
- error.code === 'ENOENT'
82
- ? 'Calendar: install gws and add its bin directory to the daemon PATH in ~/.mama/start.sh; then run: gws auth login'
83
- : 'Calendar: gws cannot read the primary calendar. Run: gws auth login with Google Calendar read access, then retry.';
84
- throw new Error(this.lastError, { cause: error });
75
+ throw new Error(`Calendar: ${(0, gws_utils_js_1.gwsUnavailable)(error)}`, { cause: error });
85
76
  }
86
77
  }
87
78
  async dispose() { }
@@ -96,21 +87,21 @@ class CalendarConnector {
96
87
  getAuthRequirements() {
97
88
  return [
98
89
  {
99
- type: 'cli',
100
- cli: 'gws',
101
- cliAuthCommand: 'gws auth login',
102
- description: 'Google Calendar read access through Google Workspace CLI. Run: gws auth login',
90
+ ...(0, types_js_1.cliAuth)(gws_utils_js_1.gwsTool),
91
+ scope: 'calendar',
92
+ description: `Google Workspace CLI sign-in with ${gws_utils_js_1.gwsTool.loginScope('calendar')}; ${gws_utils_js_1.gwsLogin}`,
103
93
  },
104
94
  ];
105
95
  }
106
96
  async authenticate() {
107
- try {
108
- await this.verifyAccess();
109
- return true;
110
- }
111
- catch {
112
- return false;
113
- }
97
+ this.lastError = await (0, gws_utils_js_1.gwsReadRefusal)('Calendar', 'the calendar', [
98
+ 'calendar',
99
+ 'events',
100
+ 'list',
101
+ '--params',
102
+ JSON.stringify({ calendarId: this.calendars[0]?.id ?? 'primary', maxResults: 1 }),
103
+ ]);
104
+ return this.lastError === undefined;
114
105
  }
115
106
  async poll(since, cursor) {
116
107
  const items = [];