@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
package/CHANGELOG.md CHANGED
@@ -5,6 +5,452 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [Unreleased]
9
+
10
+ ## [0.79.0] - 2026-11-01
11
+
12
+ ### Added
13
+
14
+ - `google.read`: the owner agent reads Gmail, Calendar and Sheets, and a Google Doc, Sheet or
15
+ Slides file as text, live through `gws`, which the daemon runs with its own sign-in. The agent
16
+ names the method as gws takes it (`service`, `argv`, `params`); read methods only, and no gws
17
+ flag is an input, so nothing is sent or uploaded. Each call runs in a directory of its own that
18
+ is removed after it, and a response gws writes to a file instead of printing (a parameter such
19
+ as `alt` or `callback` asking for another format) is refused, never left on disk. A list
20
+ returns one page with its `nextPageToken`; a result over 100,000 characters is refused with how
21
+ to narrow it. A replay turn cannot use it: Google read now is past the replay's window. A missing `gws`, no sign-in, a sign-in without the service, an API not enabled in
22
+ the client's Cloud project, and a rate or quota refusal each come back saying what to do. The
23
+ result is quoted as external evidence and each call is in `tool_traces`. The common session has
24
+ it in chat, source changes and reports, and an owner-role person in their own DM; members
25
+ without the role and room sessions do not. Drive files are still found with `drive.read` and
26
+ fetched with `drive.download`.
27
+ - Closing summaries for finished work. Every hour MAMA orders the work it saw closed or cancelled
28
+ since its first start with this version, ten items at a time. For each, the agent writes one
29
+ summary: the rounds, the points of outside feedback, who did what, and how it ended. Then a
30
+ later question reads one place. The order is checked item by item: a revision from the order's
31
+ run that leaves a description counts, as does a `work.no_update` naming an item whose summary
32
+ is already current. A status-only revision does not count. An item that
33
+ stays unchecked is ordered again, and after three orders it is logged as lost. `work.no_update`
34
+ can now name work items (`commitmentIds`) as well as observations.
35
+ - A daily board check. Once a day, before the first full report, MAMA orders work items to
36
+ compare with the board: up to ten open items whose Trello card moved after the item was last
37
+ revised, and up to ten items in progress or in review with no source event in over 30 days,
38
+ oldest first. The agent reads each card live and either revises the item with the reason or
39
+ says why it stays. Each item is checked like the closing summaries. An item that was kept, or
40
+ given up on after three tries, comes back only after it is revised again. The stale-work step
41
+ leaves the daily page, since this order now does it.
42
+ - Telegram commands MAMA answers itself, without a model turn, listed in the bot's command menu:
43
+ `/whoami` (your Telegram ID and whether MAMA knows you as an owner or a member), `/status`
44
+ (MAMA's version, whether a turn is running in this conversation, what waits; owners, in their
45
+ own DM, also see every conversation and the sources), `/new` (starts the conversation over;
46
+ refused while MAMA still works on something of that person's or a message of theirs waits) and
47
+ `/help`. In the common group an owner's commands act on the common session and a member's on
48
+ their own group conversation. Unregistered senders still get no answer, a command addressed to
49
+ another bot is left alone, and any other command goes to MAMA as a message.
50
+ - `mama init` sets up a new install and starts it:
51
+ - **Checks first, before writing anything:** the backend is installed, at least the verified
52
+ version, and signed in; Telegram accepts the bot token; the member and tool folders stay
53
+ outside HOME. Those folders default to a folder of the user's (`Shared/mama-<user>/…` in the Shared folder beside the home folders
54
+ on macOS, `/var/lib/mama/<user>/…` on Linux), and init refuses one another account owns or can
55
+ write.
56
+ - **Sign-in:** init signs nothing in. A backend that is not signed in stops it before anything
57
+ is written, and init names the login with the backend's full path (`claude auth login`, or
58
+ `codex login` in MAMA's Codex home, which init creates), for the person's agent to run.
59
+ `mama init --section model` runs that login on its terminal, and offers the only backend on
60
+ PATH as the default answer (#539).
61
+ - **Then in order:** writes the setup, registers the person running it as the first owner,
62
+ installs the document tools, installs and starts the service through `mama service`, and
63
+ waits until the daemon reports it is running and the viewer answers `/health`. Last, the
64
+ daemon runs one real backend turn in a session of its own, so the login is proven as the
65
+ service runs it; a failure names `mama logs` and `mama doctor`, and the install command run
66
+ again checks it after a fix.
67
+ - **Repeat-safe:** a failed run continues from its last finished step.
68
+ On a finished setup, init says so, names `mama doctor`, `mama service restart` and
69
+ `mama update`, and exits 0 (#538, #539).
70
+ - **No typed Telegram IDs:** last, the bot sends a six-digit code to whoever messages it
71
+ privately, and the code entered on the setup page names the first owner; that owner's
72
+ `/bind` in a group names the common channel. Messages the bot held from before are dropped, a
73
+ bot another program already reads is refused, and no `/bind` within 15 minutes stops setup
74
+ with the way to continue.
75
+ - **One part again:** `mama init --section <part>` asks one part of a finished setup again
76
+ (`telegram`, `model`, `timezone`, `connectors`, `discord`, `slack`, `jev`) while MAMA is
77
+ stopped. The answers get init's checks, the result must pass the checks MAMA runs at boot
78
+ (delivery routes included) before anything is written, tokens go only to `auth.env`, and the
79
+ other parts stay as they were. A new bot must already be in the common group.
80
+ - **Without a terminal:** `mama init --non-interactive` reads `MAMA_INIT_*` variables, and takes
81
+ the bot token and the pairing code on its setup page.
82
+ - **No longer offered:** the Kagemusha bridge, which a fresh install cannot use, and the
83
+ launch-agent question, since the service is installed for you.
84
+ - `/stop` in Telegram stops the turn running in that conversation and keeps the conversation: the
85
+ message it was answering is told it was interrupted and is not run again, and messages sent
86
+ after it still run. In the common group an owner stops the common session's turn and a member
87
+ their own.
88
+ - A daily release check. Once a day the daemon asks npm for the latest MAMA OS release and keeps
89
+ the answer. `mama status` and `mama doctor` show it without a network call of their own: a newer
90
+ release and how this install updates (`mama update`, or the git commands for a checkout), that
91
+ this version is current, or when the last check failed (#534).
92
+ - `mama update` updates an npm install to the latest release, or to the version you name:
93
+ - **Nothing changes first:** it asks the registry npm uses and shows the plan (`--dry-run`
94
+ stops there). It installs the new version next to the old one, so a failed download changes
95
+ nothing. A version older than the running one is refused (#535), and so is a release whose
96
+ Node.js range (`engines`) leaves out the Node that MAMA runs on (#539).
97
+ - **Then the swap:** it lets running turns finish as `mama stop` does, stops MAMA, takes a
98
+ backup with credentials and swaps the two versions. The new version writes `start.sh` and the
99
+ service file, checks the install, and starts with new work held. Once it runs and its viewer
100
+ answers, the held work runs, and the backup and the old version are removed (#535).
101
+ - **A failed step puts the old version back** with its own `start.sh` and service file, and
102
+ starts it. A check that newly fails under the new version counts as a failed step. The
103
+ database comes back from the backup only when the new version changed its schema, and the
104
+ report says how many inputs that arrived after the backup were dropped (#535).
105
+ - **Cut off:** if `mama update` itself is killed, `mama doctor`, and `mama status` on a stopped
106
+ install, name the `mama update --rollback` command that resolves it. `mama restore` refuses
107
+ until then (#535).
108
+ - **A git checkout** gets the commands that update it instead: stop, `git pull`,
109
+ `pnpm install`, `pnpm build`, `service install` and `service start` (#535).
110
+ - **The first update** needs a `start.sh` that this version's `mama service install` wrote, and
111
+ says so otherwise (#535).
112
+ - On an install the install command made, the report ends by naming the install command when
113
+ the new release pins another Node.js (#539).
114
+ - `/update` in Telegram updates MAMA. Only an owner can run it, in their own DM or in the common
115
+ group. It runs `mama update` as a job of its own, with no model turn, so it works even when the
116
+ backend does not. Progress comes back to the same chat: versions, steps and error codes, never a
117
+ path. While an update runs, another `/update` says only since when. A git checkout answers with
118
+ the commands that update it; asked in the group, those go to the owner's DM, since they name
119
+ folders on MAMA's machine. `/update` is in the bot's command menu (#536).
120
+ - An install command, `install.sh`, attached to each MAMA OS release starting with this one
121
+ (#538):
122
+ - It runs on macOS and Linux, on x64 or arm64, and reads no terminal. A new install is given
123
+ its backend (Claude Code or Codex) with `--backend`, and `--non-interactive` or `--no-init`.
124
+ - It puts Node.js in `~/.mama/node`, at a version it pins and checks by hash, MAMA OS in
125
+ `~/.mama/npm`, and a `mama` command in `~/.mama/bin`. The backend is installed with its
126
+ vendor's installer when none that runs is on PATH.
127
+ - It adds `~/.mama/bin` to PATH in a marked block of your shell's startup file (for fish it
128
+ prints the line instead), then runs `mama init --non-interactive`.
129
+ - On Linux it shows one `sudo` command and runs it: MAMA's folders under `/var/lib/mama`, and
130
+ linger, so the service keeps running after you log out. If sudo is refused, it prints the
131
+ command and goes on.
132
+ - Run again, it skips what is already in place. It will not take over a MAMA home that another
133
+ install set up.
134
+ - When a release pins another Node.js, running it again moves MAMA to that Node with
135
+ `mama update --node` (#539). That lets running turns finish, stops MAMA, swaps the Node in and
136
+ checks that MAMA starts on it. A new major version first rebuilds the installed packages for
137
+ that Node, before anything stops. If a step fails, the old Node is put back and started. If
138
+ the move is cut off, the next run of the install command finishes or undoes it, and
139
+ `mama status` and `mama doctor` say so.
140
+ - `mama doctor` warns when such an install runs another Node.js than its release pins (#539).
141
+ - How to get `gws` when a Google source needs it (Calendar, Gmail, Drive, Sheets). `mama init`,
142
+ `mama init --section connectors` and `mama doctor` look for it where MAMA's service runs it: on
143
+ start.sh's PATH, or, before `mama init` has written start.sh, on the PATH it will write, which
144
+ carries the folder where the terminal finds `gws`. When the service would not find it, they
145
+ print how to install it and how to sign in. On an install the install command made, both
146
+ commands use MAMA's own Node and put `gws` where the service finds it:
147
+ `PATH="$HOME/.mama/node/bin:$PATH" ~/.mama/node/bin/npm install -g --prefix ~/.mama/npm @googleworkspace/cli`,
148
+ then `PATH="$HOME/.mama/node/bin:$PATH" ~/.mama/npm/bin/gws auth login --scopes <scopes>`.
149
+ Other installs get `npm install -g @googleworkspace/cli` or `brew install googleworkspace-cli`,
150
+ then `gws auth login --scopes <scopes>`. The login names the OAuth scope of every Google source
151
+ that is on (see Changed), since one login serves them all. Before it, `mama init` and
152
+ `--section` name the OAuth client gws signs in through: a Desktop app client from Google Cloud
153
+ Console, saved as `~/.config/gws/client_secret.json`. When only the terminal finds `gws`, they
154
+ say that `mama service install` adds its folder. MAMA's service does not start while such a
155
+ source is on and `gws` is missing, and they say so: `mama init`, continuing a setup that
156
+ stopped, names `gws` again and says to install it now and run the install command again, and
157
+ `--section` no longer enables the source (below). Doctor's fix for a source that does not
158
+ start, or whose sign-in is refused, names the same login command, and the sources' own errors
159
+ point to `mama doctor` for those commands instead of a bare `gws auth login` (#543).
160
+ - `mama init --section connectors --non-interactive` enables sources without a terminal, for the
161
+ person's agent, while MAMA is stopped:
162
+ - It reads `MAMA_INIT_CONNECTORS`, a JSON object of `connectors.json` blocks keyed by source
163
+ name, checked as boot checks `connectors.json`. A source name or setting MAMA does not read is
164
+ refused.
165
+ - The tokens the sources read, as each source names them (Trello's key too), are entered on the
166
+ setup page, one field each, and go only to `auth.env`.
167
+ - The other parts of `mama init --section` still need a terminal.
168
+ - A source is enabled only once its tool is installed where MAMA's service finds it and signed
169
+ in, from either form of `mama init --section connectors`. With a Google source and `gws`
170
+ missing from start.sh's PATH, boot stopped; signed out, every poll failed. The section saves
171
+ nothing and prints how to install `gws`, or the OAuth client file and the login
172
+ (`gws auth login --scopes <scopes>`, naming the OAuth scope of every Google source that is on,
173
+ since one login serves them all), then "Then run this again." The sign-in is each source's own check, run in the
174
+ environment start.sh gives the daemon: one read with that source's own scope (Gmail its
175
+ profile, Drive `about`, Sheets its first spreadsheet, Calendar the calendar), so a sign-in made
176
+ for other services is refused too, with gws's reason.
177
+ - Each refusal of `mama init --section`, an expired setup page included, ends by saying MAMA is
178
+ still stopped and how to start it (`mama service install` first while no service is
179
+ installed). On an install the install command made, the section's lines
180
+ name `~/.mama/bin/mama`.
181
+ - An enabled source already in `connectors.json` that boot cannot build refuses the section, which
182
+ names it and says how to turn it off: its block with `"enabled": false` in
183
+ `MAMA_INIT_CONNECTORS`.
184
+ - `mama init --non-interactive` opens a setup page on this machine for the bot token and the
185
+ pairing code, once every other answer has been checked:
186
+ - The page listens on 127.0.0.1 at a path of 32 random bytes, and answers only a request whose
187
+ one Host header names `localhost`, `127.0.0.1` or `[::1]`, on any port. The address goes
188
+ only into `open.html`, a 0600 file in a 0700 folder, which init opens with `open` or `xdg-open`;
189
+ the address is never printed or passed as an argument, and the folder goes with the page. If
190
+ no browser opens, init prints the file's `file://` path.
191
+ - It takes the token, checked with Telegram, then the code the bot sent, by form POST. A refused
192
+ token or a wrong code is shown with its form again. After one token and one code it closes.
193
+ - Unused, it closes after 15 minutes, and setup stops without writing the setup; only the two
194
+ folders it made before the page opened stay. Neither the token nor the address appears in a
195
+ printed line or on the page.
196
+
197
+ ### Changed
198
+
199
+ - The Google login MAMA prints (setup, `init --section connectors`, `mama doctor`) asks for
200
+ explicit scopes, `gws auth login --scopes <scopes>`: read-only for Gmail, Calendar and Sheets,
201
+ and full Drive access, which `deliver.drive.file` needs to upload into the owner's folder and
202
+ set its readers. It was `-s <services>`, which in a terminal opened gws's scope picker and
203
+ otherwise asked for gws's defaults (`gmail.modify`, full Calendar and Sheets). An existing
204
+ sign-in keeps working; signing in again with the printed line narrows it.
205
+ - A closing summary, once checked, is not ordered again even if a later write clears or replaces
206
+ it. Before, an order was placed again when that happened within a week.
207
+ - `mama stop` lets running work finish first. MAMA claims nothing new: messages, source changes
208
+ and reports that arrive wait for the next start, and Telegram commands such as `/stop` still
209
+ answer. The stop waits until running turns finish and their replies are delivered, and prints
210
+ what it waits for. It gives up after one `agent.max_turn_ms` for each turn that may still run,
211
+ plus a minute, or when the daemon stops answering; then nothing changes and it exits 1.
212
+ `mama stop --now` stops at once, as before. `mama service stop`, `mama service restart`,
213
+ `mama uninstall` and, on macOS, `mama service uninstall` stop the same way, and `mama status`
214
+ shows while a stop holds new work. A daemon older than this version refuses to drain, and
215
+ `mama stop` then names `--now` (#533).
216
+ - `mama backup --restart` stops a running install the same way, backs it up and starts it again
217
+ through its service, also when the backup fails. Without an installed service it refuses before
218
+ it stops anything (#533).
219
+ - `mama status` shows the Node.js version the daemon runs (#539).
220
+ - `mama uninstall --data` also removes the program the install command put in the MAMA home
221
+ (Node.js, MAMA OS and the `mama` command), after everything else. Without `--data` it names that
222
+ program as staying. Both name the startup files that hold the install command's PATH block, for
223
+ you to remove. `mama backup` no longer lists that program as left out, since the install command
224
+ makes it again (#539).
225
+ - `mama service install`, for an npm install, also puts the npm prefix's `bin` folder on
226
+ `start.sh`'s PATH, where npm puts commands installed beside MAMA (#539).
227
+ - The install script asks nothing and runs from an agent's shell. A found backend must run before
228
+ the installer is skipped: its `--version` must exit 0 and print a version, so a shim with no
229
+ backend behind it gets the vendor's installer. A set-up install needs no flags: it runs
230
+ `mama init --non-interactive`, and without `--backend` it keeps the backend it has.
231
+ - Slack, Chatwork and Trello sources read only `MAMA_SLACK_TOKEN`, `MAMA_CHATWORK_TOKEN` and
232
+ `MAMA_TRELLO_TOKEN`, so the setup page never takes another secret, such as the owner bot's
233
+ token or `MAMA_AUTH_TOKEN`. A block without `auth.tokenName` reads that name. A Slack or
234
+ Chatwork block without one read `SLACK_BOT_TOKEN` or `CHATWORK_API_TOKEN` before; it now needs
235
+ `MAMA_SLACK_TOKEN` or `MAMA_CHATWORK_TOKEN` in `auth.env`, and doctor names the one missing. A
236
+ block that names any other variable stops boot until it is corrected, and doctor names it.
237
+ - `mama doctor`'s fix for a source token that is missing or refused names
238
+ `mama init --section connectors --non-interactive` with that source's block, whose setup page
239
+ takes the token, instead of `mama secret set`, which needs a terminal. A messenger's token
240
+ still names `mama secret set`.
241
+ - The package README and the install guide (`docs/start/owner-setup.md`) describe setup through
242
+ the person's agent: the sentence to give it, naming this repository, and the install command it
243
+ runs, with `npm install -g` for a person who keeps their own Node.js. The guide lists the
244
+ supported versions of Node.js, Claude Code, Codex and macOS with their sources, what the install
245
+ command makes, how a new Node.js release is moved to, and the known limits: no setup path yet for
246
+ Linux over SSH or without a desktop, and the document tools on a Mac account without its own
247
+ Homebrew.
248
+
249
+ ### Removed
250
+
251
+ - The interactive whole setup: bare `mama init` is now a usage error. `mama init --non-interactive`
252
+ is the setup, run by the person's agent ("Set up through your agent" in
253
+ `docs/start/owner-setup.md`), and its messages say to run the install command again. The tunnel
254
+ settings are read from the environment: `MAMA_CF_ACCESS_ISSUER`, `MAMA_CF_ACCESS_AUD` and
255
+ `MAMA_VIEWER_HOSTNAMES` together, and optionally `MAMA_VIEWER_OWNER_EMAILS`. Sources, Discord,
256
+ Slack and Jev are set up with `mama init --section`.
257
+ - The init variables `MAMA_INIT_OWNER_TELEGRAM_ID` and `MAMA_INIT_COMMON_CHAT_ID`, and
258
+ `MAMA_TELEGRAM_TOKEN` as an init variable (the secret name stays): the setup page takes the token,
259
+ and the bot's pairing code and `/bind` name the owner and the common group.
260
+ - The package no longer installs Express. Its only use was an old report router with write routes
261
+ that nothing ever served.
262
+
263
+ ### Fixed
264
+
265
+ - A Notion, Discord or Telegram source whose block names another token than its own is refused
266
+ when the source is built, in the section, doctor and boot; before, only its start in boot
267
+ refused it.
268
+ - Gmail, Drive and Sheets' sign-in check is a read with the source's own scope. It ran
269
+ `gws auth status`, which exits 0 signed in or not and does not say which services a sign-in
270
+ grants, so doctor reported a signed-out source, or one without its scope, as signed in.
271
+ - Calendar starts as the other Google sources do, when `gws` runs. Its calendar read is its sign-in
272
+ check, so a sign-in that ended (a testing-mode client's, after 7 days) fails its polls and
273
+ doctor's check instead of stopping MAMA at boot.
274
+ - A backend failure such as a signed-out Claude CLI or an API error no longer arrives as MAMA's
275
+ answer. The turn fails, its message is told it was interrupted, and `daemon.log` names the
276
+ error. Before, the CLI's error text was sent as the reply and the run was recorded as committed
277
+ (mama-core).
278
+ - A scheduled full report or reminder that a newer report already covered is no longer sent.
279
+ Before, a report whose first send failed stayed queued and kept being retried, so it could still
280
+ go out days late; one had waited 13 days. Reports already stuck this way close after the next
281
+ full report is sent (#542).
282
+ - After a report's send fails, MAMA no longer writes the same hour's report again every minute
283
+ (#542).
284
+ - If the clock is behind the latest report sent, MAMA queues no report and logs an error each
285
+ minute naming that report's time, until the clock passes it (#542).
286
+ - `mama stop` no longer refuses a MAMA that is just starting. In its first moments MAMA holds the
287
+ install before it can answer the stop or say which process it is. The stop used to report
288
+ "does not answer on its control socket" and leave it running, or report "unknown (pid 0) holds
289
+ the install" as still running after it had already stopped it (macOS). It now waits up to 5
290
+ seconds for MAMA to answer, then lets it finish what runs and stops it as usual. `mama stop
291
+ --now` waits the same way, only while the holder is still unnamed, before it stops the service.
292
+ Running the install command again right after a Node move was cut off hit this: the install
293
+ command stopped with "MAMA on it did not stop" and changed nothing (#546).
294
+
295
+ ### Security
296
+
297
+ - gws's credential store is now closed to the agents' own file reads and shell, as MAMA's own
298
+ credentials are (owner, 2026-10-31): its config directory (`~/.config/gws`, the legacy
299
+ `~/Library/Application Support/gws`, or the one `GOOGLE_WORKSPACE_CLI_CONFIG_DIR` names) and a
300
+ `GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE`. MAMA's Google sources and `google.read` run on that
301
+ sign-in, and an agent that could read it, or run `gws auth export` against it, could carry the
302
+ refresh token, with Drive write access, out in a reply or a fetched URL. Claude's Read rules
303
+ and shell sandbox and the Codex permission profile all deny it; the daemon's own gws calls are
304
+ unaffected. Other tools' credential stores stay as they were.
305
+ - Another website open in your browser can no longer read through MAMA's viewer in your name.
306
+ Before, a link or a page your browser had allowed onto this machine could make one viewer
307
+ request, such as a memory search with words it chose. MAMA ran that search as yours and kept
308
+ the words in its record of your actions. The viewer now answers such a request with 403 and runs
309
+ nothing. It records the request in `security-events.jsonl` as `cross_origin` and alerts you as
310
+ for other viewer security events. A page on another port of this machine counts as another
311
+ website. The viewer itself, a link or bookmark that opens it, curl and local tools work as
312
+ before. Through the tunnel, a bookmark to an `/api` address opened after your Cloudflare Access
313
+ sign-in expired comes back from the sign-in page as another website's request and gets 403;
314
+ open the viewer instead.
315
+ - The board's live updates allow 8 open connections at once. Another connection is refused with
316
+ 503 and a line in `daemon.log`, instead of each one adding memory without limit. The browser
317
+ does not retry a refused connection: that board keeps its content and its refresh button but
318
+ shows no live updates until the page is reloaded. A connection whose browser left while MAMA
319
+ was still checking its Cloudflare Access sign-in is no longer kept open for good.
320
+
321
+ ## [0.78.0] - 2026-10-16
322
+
323
+ ### Fixed
324
+
325
+ - A generated `start.sh` keeps the package manager's tool folders on PATH (`/opt/homebrew/bin`,
326
+ `/usr/local/bin`), when they exist, ahead of the system's. The agent's shell runs
327
+ the tools the owner installed there, such as python3 with its packages; they had been dropped.
328
+
329
+ - `member_root` and `tools_root` are compared by their real letter case, so on a case-insensitive
330
+ disk a root written as HOME in another case (`/USERS/name`) is refused as overlapping HOME,
331
+ instead of being accepted and placing member workspaces inside the owner's home.
332
+
333
+ ### Added
334
+
335
+ - `mama uninstall [--dry-run] [--data [--toolkit]]` stops whatever holds the install and removes
336
+ the service. With `--data`, once the MAMA home's path is typed back on a terminal, it also removes
337
+ the MAMA home, each registered person's folder under `member_root` and the retired ones, and the
338
+ common skills under `tools_root` (`--toolkit`: the toolkit's versions too); `member_root` and
339
+ `tools_root` go only once empty, so a misconfigured root loses nothing but MAMA's entries. Paths
340
+ the config sets outside the MAMA home are listed as staying. `--dry-run` lists it all.
341
+
342
+ - The daemon writes its own output to `daemon.log` (`logging.file`), rotated at 10 MB with five
343
+ compressed archives; `security-events.jsonl` rotates at 5 MB the same way. The service manager
344
+ keeps only what comes before the daemon reads its config, in `logs/crash.log`, which `start.sh`
345
+ empties at start past 1 MB (`mama service install` rewrites the launch files). Writes stay
346
+ synchronous, so no line is lost or reordered across a rotation, and the file is emptied in place,
347
+ never replaced, so a launch file that still redirects into it keeps working. A rotation that
348
+ fails is written to the log and tried again after another limit's worth.
349
+ - `mama logs [-n <lines>] [--follow]` prints the daemon log's last lines and follows it across a
350
+ rotation.
351
+
352
+ - MAMA OS refuses to open a database a newer version migrated, before anything writes to it, and
353
+ the daemon stops with a clean exit so its service does not restart into the refusal; other
354
+ commands print the refusal's own text. `mama doctor` checks the schema read-only against what this version knows, per migration source:
355
+ a newer one fails (install the version that wrote it, or restore a backup taken with this one),
356
+ an older one reports that the next start migrates it, and an unreadable file is reported.
357
+
358
+ - `mama restore <archive>` puts a `mama backup` archive onto a stopped install. The manifest is
359
+ read as untrusted: only the names a backup keeps, nothing beneath a link, credentials only in a
360
+ backup that says it holds them. Files are extracted and checked against their hashes, links
361
+ are made from the manifest (absolute ones too), and modes are set as recorded. The restored
362
+ config keeps the backup's settings with this install's paths, and each part goes where that
363
+ config puts it, folder by folder. Attachment paths in mailbox inputs and the connector event
364
+ index move to this install's roots in one pass, with the tables' update triggers set aside so
365
+ no event is renumbered and delivered again; raw stores and evidence keep theirs. Each
366
+ destination goes aside while its copy takes its name, under a write-ahead journal: a failure
367
+ puts everything back, and after an interruption the daemon and `mama doctor` refuse until
368
+ `mama restore --rollback` resolves it. The target keeps its credentials when the archive has
369
+ none, and its `start.sh`; the owner's Codex threads start over. While a restore is unfinished
370
+ the daemon, `register-owner` and `mama backup` refuse with a clean exit, so a service does not
371
+ restart into it.
372
+ - `mama backup` archives the wiki on its own wherever it is, so a restore puts it where that
373
+ install keeps its wiki.
374
+
375
+ - `mama backup [--include-secrets] [--logs]` writes one archive of a stopped install to
376
+ `~/.mama/backups/` (0600), the one folder the agents cannot read: the database copied with
377
+ SQLite's backup and checked with `integrity_check`, the raw stores checked too, the MAMA home's
378
+ state, the workspace, every person's folder under `member_root`, the published common skills,
379
+ the wiki MAMA writes and Jev's vocabulary, each where config puts it. A manifest records each
380
+ entry's mode, symlink target and SHA-256 and every configured path as written and as it really
381
+ is, and the archive is read back against it before it is kept. Credentials (auth.env, the Codex
382
+ login, the Jev key, an MCP configuration with servers besides MAMA's, and a config or start.sh
383
+ that holds a token) go in only with `--include-secrets`, logs only with `--logs`; Codex homes
384
+ and their sessions never (sessions start over after a restore). It names everything it left out,
385
+ and it is refused beside a running daemon and for a kept file or folder that is a link.
386
+
387
+ - `mama doctor` checks an install as its service would run it, without changing it: config and
388
+ `connectors.json` as boot loads them, `member_root`, the Node in `start.sh` (present, outside one
389
+ version's folder, and able to load MAMA's SQLite module), the backend on that script's `PATH`
390
+ with the daemon's environment (its version against the oldest one MAMA was verified on, Claude
391
+ Code 2.1.299 and Codex 0.160.1, and whether it is signed in), the shell sandbox (it starts one),
392
+ the secrets each enabled messenger and source needs and each source started as boot starts it and
393
+ asked whether its credentials work, the Telegram token and whether the bot is in the common group
394
+ and reads it, the toolkit, the daemon (answering, booted, each source's last poll) or the port it
395
+ would bind, the service manager and each log past its cap. Each problem names what to do, and it exits
396
+ 1 when a check fails. `--json` for scripts, `--offline` makes no network call (Telegram and the
397
+ sources are not asked), and `--report` prints a summary for a bug report: versions, platform,
398
+ setting and source names, the checks in doctor's own words, the last boot's stages and recent
399
+ errors reduced to failed stages, connector names and error codes. Paths, values, ids and message
400
+ text never enter it.
401
+
402
+ ### Changed
403
+
404
+ - The agents can no longer read `~/.mama/backups/`, which can hold every MAMA credential.
405
+ - Poll state is written to a temporary file and renamed into place; an unreadable one is kept as
406
+ `poll-state.json.corrupt-<time>-<pid>` with an error in the log, where it used to be dropped
407
+ without a word.
408
+
409
+ - A daemon that fails to boot prints the stage that failed and points to `mama doctor`.
410
+ - The Chatwork and Slack sources name the token they read (`auth.tokenName`) when asked what they
411
+ need; they named the default.
412
+ - The iMessage source opens `chat.db` read-only and only when it exists; a missing database used
413
+ to be created empty.
414
+ - `init` and `service install` write Homebrew's stable `opt/node` path into `start.sh` instead of
415
+ the versioned Cellar path that an upgrade removes. `service install` reads `$HOME`, `${HOME}` and
416
+ `~` in the old `PATH` as the home folder, so it no longer reports them as dropped.
417
+
418
+ - The daily page closes the day: the daily turn fixes what it got wrong (a revision with its
419
+ evidence for a wrong or stale item, a saved or revised lesson), saves an owner correction that
420
+ was only promised as a lesson (a standing rule is listed for the owner to confirm in the common
421
+ channel), settles up to ten items in progress or review whose latest source event is over 30
422
+ days old, and checks the previous day's lessons against what it can read. It had listed its
423
+ misses on the page only, and the next day repeated one.
424
+ - `work.list` takes `lastEventBefore`: items whose latest source event is before a time, for stale
425
+ work that a backfill or correction rewrote later (`changedBefore` compares write time).
426
+ - One process holds an install at a time. The daemon, a replay or backfill, and `register-owner`
427
+ take an exclusive lock on `~/.mama/runtime/daemon.lock` before they open the database, so a
428
+ second one is refused before it changes anything (a second daemon used to migrate the live
429
+ database, rewrite the workspace settings and reset the web fetch mode before failing). The
430
+ operating system releases the lock when the process ends; a failed stop keeps it until then. A
431
+ refused daemon exits cleanly.
432
+ - `mama status` asks the running daemon through `~/.mama/daemon.sock` and shows its version,
433
+ boot stage, running turns, waiting inputs, connectors and last error (`--json` for scripts); it
434
+ exits 0 when running and 3 when stopped, and it works on Linux, where it used to fail because it
435
+ called `launchctl`. `mama stop` unloads the LaunchAgent that runs the daemon or asks the daemon to stop, waits up to
436
+ two minutes until the install is released, and says when something else holds it or started in
437
+ its place.
438
+ - A stop during boot unwinds what has started; signals were handled only after boot.
439
+ - `mama service install|start|stop|restart|status|uninstall` writes and runs the service: a
440
+ LaunchAgent on macOS, a systemd user unit on Linux (`--enable-linger` keeps it running after
441
+ logout). Both restart the daemon only after a failure, so a stop or a refused second daemon stays
442
+ stopped; the LaunchAgent used to restart on every exit. The unit signals the daemon alone
443
+ (`KillMode=mixed`), so it stops its children in order. `install` regenerates `start.sh`, carries
444
+ its `export` lines over verbatim, names what else it does not reproduce and every change to what
445
+ the daemon runs (exec target, PATH, log level), keeps the replaced files under `runtime/`, and
446
+ refuses to replace a `start.sh` that mama did not write without `--replace`, or to write one when
447
+ the backend cannot be found. `start` starts a loaded LaunchAgent whose daemon has exited; on
448
+ Linux `mama stop` and `mama status` go through the unit.
449
+ - A daemon stopped by a signal exits 128 plus the signal's number (143 for SIGTERM), as a killed
450
+ process would, so its service brings it back; a stop asked for through `mama stop` exits 0.
451
+ - The generated `start.sh` exports `MAMA_LOG_LEVEL` from `config.yaml`'s `logging.level`. The core
452
+ logger reads only that variable, so a fresh install logged at `ERROR` whatever the config said.
453
+
8
454
  ## [0.77.0] - 2026-10-15
9
455
 
10
456
  ### Upgrading
package/README.md CHANGED
@@ -1,54 +1,82 @@
1
1
  # MAMA OS
2
2
 
3
- One owner agent on Claude or Codex watches connected work, keeps task revisions and evidence,
4
- answers on Telegram, publishes reports and a board, and recalls corrections.
3
+ A common session, a DM session per registered person and a group session per member, on Claude or
4
+ Codex, watch connected work, keep task revisions and evidence, answer in Telegram (each person's DM
5
+ and the common group), Discord or Slack, publish reports and a board, and recall corrections.
5
6
  [mama-core](../mama-core/README.md) supplies the shared engine.
6
7
 
7
- Current manifest: **0.77.0**. Install with `npm install -g @jungjaehoon/mama-os` (Node.js 22.13+)
8
- and follow [owner setup](../../docs/start/owner-setup.md).
8
+ Current manifest: **0.79.0**. Install it through your agent: on the Mac that will run MAMA, tell
9
+ Claude Code or Codex "Install MAMA OS from https://github.com/jungjaehoon-lifegamez/MAMA by
10
+ following its owner setup guide, docs/start/owner-setup.md". See
11
+ [owner setup](../../docs/start/owner-setup.md), with the supported versions.
9
12
 
10
13
  ## Start and operate
11
14
 
15
+ The agent runs the install command. It installs MAMA's own Node.js, MAMA OS and, when needed, the
16
+ backend, then sets MAMA up and starts it:
17
+
18
+ ```bash
19
+ curl -fsSL https://github.com/jungjaehoon-lifegamez/MAMA/releases/latest/download/install.sh | MAMA_INIT_MODEL=<model> sh -s -- --backend <claude|codex> --non-interactive
20
+ ```
21
+
22
+ With your own Node.js 22.13 or newer, install with npm instead, then run setup:
23
+
12
24
  ```bash
13
25
  npm install -g @jungjaehoon/mama-os
14
- mama init
26
+ MAMA_INIT_BACKEND=<claude|codex> MAMA_INIT_MODEL=<model> mama init --non-interactive
15
27
  ```
16
28
 
17
29
  From a checkout, run `pnpm install` and `pnpm build`, then use
18
- `node packages/standalone/dist/cli/index.js` in place of `mama`. Onboarding is terminal-only: the owner types tokens
19
- with echo off. It writes configuration and optional launchd files; backend login and service
20
- startup are separate steps.
21
-
22
- For Telegram's common session, create a group with the bot, even for a solo owner, and enter
23
- its negative group or supergroup ID in `mama init`. Private chats always enter personal sessions.
24
- Before starting the daemon, set `member_root` outside HOME in `config.yaml` and run
25
- `mama register-owner <telegram id>` for each owner's positive user ID.
26
-
27
- | Command | Purpose |
28
- | --------------------------------------------- | ------------------------------------------------ |
29
- | `mama init` | Set up the owner, backend and connectors |
30
- | `mama secret set <NAME>` / `mama secret list` | Rotate a token / list names only |
31
- | `mama daemon` | Run the configured daemon in the foreground |
32
- | `mama replay` | Replay prepared historical inputs in day windows |
33
- | `mama status` / `mama stop` | Report running/stopped / stop the process |
30
+ `node packages/standalone/dist/cli/index.js` in place of `mama`. Setup reads its answers from
31
+ `MAMA_INIT_*` variables and opens a page in the browser on this machine, where the owner enters the
32
+ bot token and the pairing code; nothing secret goes through the chat or a terminal. Sign in to the
33
+ backend first; setup checks it, writes the setup, registers the first owner, installs the document
34
+ toolkit and starts the service.
35
+
36
+ For Telegram's common session, create a group with the bot, even for a solo owner, and send
37
+ `/bind` there when setup asks. Private chats always enter personal sessions.
38
+ Setup pairs you through a code the bot sends you and registers you as the first owner; `mama register-owner <telegram id>` registers
39
+ another owner while the daemon is stopped.
40
+
41
+ | Command | Purpose |
42
+ | -------------------------------------------------- | ---------------------------------------------------- |
43
+ | `mama init --non-interactive` | Set up and start MAMA, with the first owner |
44
+ | `mama init --section connectors --non-interactive` | Enable sources, with MAMA stopped; the agent runs it |
45
+ | `mama register-owner <telegram id>` | Register another owner while MAMA is stopped |
46
+ | `mama tools install` | Install or update the document toolkit |
47
+ | `mama secret set <NAME>` / `mama secret list` | Rotate a token / list names only |
48
+ | `mama daemon` | Run the configured daemon in the foreground |
49
+ | `mama backfill <file>` | Write a prepared past-period backfill file |
50
+ | `mama replay` | Replay prepared historical inputs in day windows |
51
+ | `mama status` / `mama stop` | Report running/stopped / stop the process |
34
52
 
35
53
  See [CLI flags](../../docs/reference/cli.md) and
36
54
  [launchd management](../../docs/guides/troubleshooting.md).
37
55
 
38
56
  ## Current surface
39
57
 
40
- - **Owner chat:** Telegram, Discord or Slack, each with an allowed chat and owner sender
41
- ([messengers](../../docs/guides/messengers.md)).
42
- - **Five source connectors:** Chatwork, Slack, Trello, Kagemusha (read-only local bridge),
43
- and Google Calendar through `gws`.
58
+ - **Messengers:** in Telegram, a DM per registered person and the common group; Discord and
59
+ Slack keep one owner channel ([messengers](../../docs/guides/messengers.md)).
60
+ - **People:** each person's DM session has its own records, scheduled jobs, notices and skills;
61
+ an owner's DM also reads the common records. Members without the owner role work in the group
62
+ in a session of their own ([people and DMs](../../docs/guides/people.md)).
63
+ - **Sources:** Chatwork, Slack, Discord, Telegram groups, Trello, Notion, Google Calendar, Gmail,
64
+ Drive and Sheets through `gws`, iCal feeds, Obsidian, iMessage, Claude Code and a read-only
65
+ Kagemusha bridge ([sources](../../docs/guides/connectors.md)).
44
66
  - **Records:** tasks and revision history, a four-slot board, wiki pages, daily journals,
45
- lessons, preferences and constraints.
67
+ lessons, preferences, constraints, workflows and skills.
68
+ - **Documents:** a managed toolkit (`mama tools install`) with python-pptx, python-docx, openpyxl,
69
+ PyMuPDF, numpy, pandas, matplotlib, LibreOffice and Noto CJK fonts; on macOS `document.render`
70
+ turns a workspace file into a PDF and page images.
71
+ - **Web:** for owners, turns where a person speaks search the web and, on Claude, open pages;
72
+ turns with no person in them search the web but open pages only from the hosts in
73
+ `agent.autonomous_web_fetch`. Members without the owner role have no web tools.
46
74
  - **Reports:** live deltas, full reports at 08/13/18 and hourly reminders at 09–21, in the
47
75
  configured time zone.
48
76
  - **Viewer:** board, work, memory graph, wiki, logs and security events; read-only data routes.
49
77
  - **Files:** source attachment lookup/download, native workspace processing,
50
- `deliver.<messenger>.file` to the owner's chat and `deliver.drive.file` for files over the
51
- messengers' limit.
78
+ `deliver.<messenger>.file` to the caller's chat and `deliver.drive.file` for files over the
79
+ messengers' limit; an owner's DM fetches Drive files with `drive.download`.
52
80
 
53
81
  Assembly lives in `src/runtime/` and `src/cli/commands/daemon.ts`; actions in `src/api/`,
54
82
  collectors in `src/connectors/`, Telegram in `src/gateways/`, replay in `src/replay/`,
@@ -57,8 +85,8 @@ and viewer sources/assets in `ui/` and `public/viewer/`.
57
85
  ## Data, security and status
58
86
 
59
87
  OS state lives in `~/.mama/`; its database defaults to `~/.mama/memory.db`.
60
- `config.yaml` and `connectors.json` hold settings; terminal-entered credentials live in
61
- `auth.env` (0600). Both backends have workspace-only writes and credential-read exclusions.
88
+ `config.yaml` and `connectors.json` hold settings; credentials, entered on the setup page or at a
89
+ terminal, live in `auth.env` (0600). Both backends have workspace-only writes and credential-read exclusions.
62
90
  The viewer binds to `127.0.0.1:3847` by default; remote data access requires a bearer token
63
91
  or verified Access JWT. See [security](../../docs/guides/security.md).
64
92
 
@@ -70,6 +98,7 @@ The [public MCP server](../mcp-server/README.md) and
70
98
  [Replay](../../docs/guides/replay.md) · [Viewer](../../docs/guides/viewer.md).
71
99
 
72
100
  Completion is measured by [INTENT.md](../../INTENT.md); open live checks are in
101
+ [the work plan](../../docs/development/plan.md) and results in
73
102
  [checks.md](../../docs/development/checks.md). Run `pnpm test` inside this package, with isolated
74
103
  state as described in [testing](../../docs/development/testing.md).
75
104
 
@@ -0,0 +1,11 @@
1
+ -- A run's child runs are read by parent, and only the product reads them that way: the upkeep and
2
+ -- record-order runners wait for an order run's children, and the write-back scan reads and checks
3
+ -- each question turn with its children. Core never queries by parent, so the index lives with the
4
+ -- package that does. Without it every lookup scans model_runs; on a copy of a live install the
5
+ -- write-back scan took about 3 s per pass, and about 50 ms with this index.
6
+ CREATE INDEX IF NOT EXISTS idx_model_runs_parent
7
+ ON model_runs(parent_model_run_id)
8
+ WHERE parent_model_run_id IS NOT NULL;
9
+
10
+ INSERT OR IGNORE INTO schema_version (source, version, description)
11
+ VALUES ('standalone', 2, 'Index model runs by parent run, for the product runners that read children');
@@ -0,0 +1,15 @@
1
+ -- Upkeep subjects the runner has settled for good: checked, or lost after its last attempt.
2
+ -- Attempts are counted from the stored order rows, and the mailbox deletes acked rows after seven
3
+ -- days, so without this record a subject whose scan has no time bound (the board reconcile's stale
4
+ -- items) would be ordered three more times every week, kept or lost. A settled subject is never
5
+ -- ordered again; new work on the same thing is a new subject with a new key.
6
+ CREATE TABLE IF NOT EXISTS upkeep_settled (
7
+ kind TEXT NOT NULL,
8
+ subject_key TEXT NOT NULL,
9
+ state TEXT NOT NULL CHECK (state IN ('checked', 'lost')),
10
+ settled_at INTEGER NOT NULL,
11
+ PRIMARY KEY (kind, subject_key)
12
+ );
13
+
14
+ INSERT OR IGNORE INTO schema_version (source, version, description)
15
+ VALUES ('standalone', 3, 'Upkeep subjects settled for good, kept past the mailbox retention');