@jungjaehoon/mama-os 0.76.0 → 0.78.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 (190) hide show
  1. package/CHANGELOG.md +182 -0
  2. package/README.md +25 -10
  3. package/dist/api/attachment-actions.d.ts.map +1 -1
  4. package/dist/api/attachment-actions.js +8 -7
  5. package/dist/api/attachment-actions.js.map +1 -1
  6. package/dist/api/code-act-actions.d.ts.map +1 -1
  7. package/dist/api/code-act-actions.js +5 -2
  8. package/dist/api/code-act-actions.js.map +1 -1
  9. package/dist/api/drive-actions.d.ts +4 -0
  10. package/dist/api/drive-actions.d.ts.map +1 -1
  11. package/dist/api/drive-actions.js +15 -7
  12. package/dist/api/drive-actions.js.map +1 -1
  13. package/dist/api/drive-delivery.d.ts.map +1 -1
  14. package/dist/api/drive-delivery.js +8 -3
  15. package/dist/api/drive-delivery.js.map +1 -1
  16. package/dist/api/member-enrollment.d.ts +2 -0
  17. package/dist/api/member-enrollment.d.ts.map +1 -1
  18. package/dist/api/member-enrollment.js +1 -1
  19. package/dist/api/member-enrollment.js.map +1 -1
  20. package/dist/api/member-lifecycle.d.ts +2 -0
  21. package/dist/api/member-lifecycle.d.ts.map +1 -1
  22. package/dist/api/member-lifecycle.js +1 -1
  23. package/dist/api/member-lifecycle.js.map +1 -1
  24. package/dist/api/owner-timezone-actions.d.ts +2 -0
  25. package/dist/api/owner-timezone-actions.d.ts.map +1 -1
  26. package/dist/api/owner-timezone-actions.js.map +1 -1
  27. package/dist/api/security-events.d.ts.map +1 -1
  28. package/dist/api/security-events.js +10 -1
  29. package/dist/api/security-events.js.map +1 -1
  30. package/dist/api/viewer-server.d.ts +1 -0
  31. package/dist/api/viewer-server.d.ts.map +1 -1
  32. package/dist/api/viewer-server.js +34 -0
  33. package/dist/api/viewer-server.js.map +1 -1
  34. package/dist/api/work-actions.d.ts.map +1 -1
  35. package/dist/api/work-actions.js +27 -2
  36. package/dist/api/work-actions.js.map +1 -1
  37. package/dist/cli/commands/backfill.d.ts.map +1 -1
  38. package/dist/cli/commands/backfill.js +1 -0
  39. package/dist/cli/commands/backfill.js.map +1 -1
  40. package/dist/cli/commands/backup.d.ts +13 -0
  41. package/dist/cli/commands/backup.d.ts.map +1 -0
  42. package/dist/cli/commands/backup.js +137 -0
  43. package/dist/cli/commands/backup.js.map +1 -0
  44. package/dist/cli/commands/control.d.ts +26 -0
  45. package/dist/cli/commands/control.d.ts.map +1 -0
  46. package/dist/cli/commands/control.js +193 -0
  47. package/dist/cli/commands/control.js.map +1 -0
  48. package/dist/cli/commands/daemon.d.ts +49 -3
  49. package/dist/cli/commands/daemon.d.ts.map +1 -1
  50. package/dist/cli/commands/daemon.js +253 -75
  51. package/dist/cli/commands/daemon.js.map +1 -1
  52. package/dist/cli/commands/doctor.d.ts +13 -0
  53. package/dist/cli/commands/doctor.d.ts.map +1 -0
  54. package/dist/cli/commands/doctor.js +216 -0
  55. package/dist/cli/commands/doctor.js.map +1 -0
  56. package/dist/cli/commands/init.d.ts.map +1 -1
  57. package/dist/cli/commands/init.js +3 -2
  58. package/dist/cli/commands/init.js.map +1 -1
  59. package/dist/cli/commands/logs.d.ts +9 -0
  60. package/dist/cli/commands/logs.d.ts.map +1 -0
  61. package/dist/cli/commands/logs.js +109 -0
  62. package/dist/cli/commands/logs.js.map +1 -0
  63. package/dist/cli/commands/register-owner.d.ts.map +1 -1
  64. package/dist/cli/commands/register-owner.js +12 -0
  65. package/dist/cli/commands/register-owner.js.map +1 -1
  66. package/dist/cli/commands/restore.d.ts +14 -0
  67. package/dist/cli/commands/restore.d.ts.map +1 -0
  68. package/dist/cli/commands/restore.js +130 -0
  69. package/dist/cli/commands/restore.js.map +1 -0
  70. package/dist/cli/commands/service.d.ts +28 -0
  71. package/dist/cli/commands/service.d.ts.map +1 -0
  72. package/dist/cli/commands/service.js +278 -0
  73. package/dist/cli/commands/service.js.map +1 -0
  74. package/dist/cli/commands/uninstall.d.ts +7 -0
  75. package/dist/cli/commands/uninstall.d.ts.map +1 -0
  76. package/dist/cli/commands/uninstall.js +262 -0
  77. package/dist/cli/commands/uninstall.js.map +1 -0
  78. package/dist/cli/index.js +67 -20
  79. package/dist/cli/index.js.map +1 -1
  80. package/dist/cli/launch-files.d.ts +83 -0
  81. package/dist/cli/launch-files.d.ts.map +1 -1
  82. package/dist/cli/launch-files.js +231 -15
  83. package/dist/cli/launch-files.js.map +1 -1
  84. package/dist/cli/runtime/backend-probe.d.ts +34 -0
  85. package/dist/cli/runtime/backend-probe.d.ts.map +1 -0
  86. package/dist/cli/runtime/backend-probe.js +83 -0
  87. package/dist/cli/runtime/backend-probe.js.map +1 -0
  88. package/dist/cli/runtime/backup.d.ts +114 -0
  89. package/dist/cli/runtime/backup.d.ts.map +1 -0
  90. package/dist/cli/runtime/backup.js +564 -0
  91. package/dist/cli/runtime/backup.js.map +1 -0
  92. package/dist/cli/runtime/claude-caller-config.d.ts +3 -1
  93. package/dist/cli/runtime/claude-caller-config.d.ts.map +1 -1
  94. package/dist/cli/runtime/claude-caller-config.js +14 -2
  95. package/dist/cli/runtime/claude-caller-config.js.map +1 -1
  96. package/dist/cli/runtime/daemon-control.d.ts +84 -0
  97. package/dist/cli/runtime/daemon-control.d.ts.map +1 -0
  98. package/dist/cli/runtime/daemon-control.js +266 -0
  99. package/dist/cli/runtime/daemon-control.js.map +1 -0
  100. package/dist/cli/runtime/diagnostics.d.ts +43 -0
  101. package/dist/cli/runtime/diagnostics.d.ts.map +1 -0
  102. package/dist/cli/runtime/diagnostics.js +953 -0
  103. package/dist/cli/runtime/diagnostics.js.map +1 -0
  104. package/dist/cli/runtime/restore.d.ts +98 -0
  105. package/dist/cli/runtime/restore.d.ts.map +1 -0
  106. package/dist/cli/runtime/restore.js +756 -0
  107. package/dist/cli/runtime/restore.js.map +1 -0
  108. package/dist/cli/runtime/systemd-service.d.ts +13 -0
  109. package/dist/cli/runtime/systemd-service.d.ts.map +1 -0
  110. package/dist/cli/runtime/systemd-service.js +32 -0
  111. package/dist/cli/runtime/systemd-service.js.map +1 -0
  112. package/dist/connectors/chatwork/index.js +1 -1
  113. package/dist/connectors/chatwork/index.js.map +1 -1
  114. package/dist/connectors/config-loader.d.ts +2 -1
  115. package/dist/connectors/config-loader.d.ts.map +1 -1
  116. package/dist/connectors/config-loader.js +3 -2
  117. package/dist/connectors/config-loader.js.map +1 -1
  118. package/dist/connectors/framework/polling-scheduler.d.ts.map +1 -1
  119. package/dist/connectors/framework/polling-scheduler.js +12 -11
  120. package/dist/connectors/framework/polling-scheduler.js.map +1 -1
  121. package/dist/connectors/imessage/index.d.ts.map +1 -1
  122. package/dist/connectors/imessage/index.js +2 -1
  123. package/dist/connectors/imessage/index.js.map +1 -1
  124. package/dist/connectors/slack/index.js +1 -1
  125. package/dist/connectors/slack/index.js.map +1 -1
  126. package/dist/runtime/action-surface.d.ts.map +1 -1
  127. package/dist/runtime/action-surface.js +6 -0
  128. package/dist/runtime/action-surface.js.map +1 -1
  129. package/dist/runtime/backend-security.d.ts +3 -0
  130. package/dist/runtime/backend-security.d.ts.map +1 -1
  131. package/dist/runtime/backend-security.js +13 -5
  132. package/dist/runtime/backend-security.js.map +1 -1
  133. package/dist/runtime/claude-caller-hook.d.ts +14 -0
  134. package/dist/runtime/claude-caller-hook.d.ts.map +1 -1
  135. package/dist/runtime/claude-caller-hook.js +21 -1
  136. package/dist/runtime/claude-caller-hook.js.map +1 -1
  137. package/dist/runtime/config.d.ts +8 -0
  138. package/dist/runtime/config.d.ts.map +1 -1
  139. package/dist/runtime/config.js +17 -4
  140. package/dist/runtime/config.js.map +1 -1
  141. package/dist/runtime/connectors.d.ts +21 -1
  142. package/dist/runtime/connectors.d.ts.map +1 -1
  143. package/dist/runtime/connectors.js +28 -17
  144. package/dist/runtime/connectors.js.map +1 -1
  145. package/dist/runtime/core-db.d.ts.map +1 -1
  146. package/dist/runtime/core-db.js +2 -0
  147. package/dist/runtime/core-db.js.map +1 -1
  148. package/dist/runtime/member-session.d.ts.map +1 -1
  149. package/dist/runtime/member-session.js +11 -3
  150. package/dist/runtime/member-session.js.map +1 -1
  151. package/dist/runtime/member-system-prompt.d.ts +2 -0
  152. package/dist/runtime/member-system-prompt.d.ts.map +1 -1
  153. package/dist/runtime/member-system-prompt.js +11 -3
  154. package/dist/runtime/member-system-prompt.js.map +1 -1
  155. package/dist/runtime/native-session.d.ts +2 -0
  156. package/dist/runtime/native-session.d.ts.map +1 -1
  157. package/dist/runtime/native-session.js +25 -4
  158. package/dist/runtime/native-session.js.map +1 -1
  159. package/dist/runtime/owner-authority.d.ts +2 -0
  160. package/dist/runtime/owner-authority.d.ts.map +1 -1
  161. package/dist/runtime/owner-authority.js +4 -0
  162. package/dist/runtime/owner-authority.js.map +1 -1
  163. package/dist/runtime/owner-runtime.d.ts +2 -0
  164. package/dist/runtime/owner-runtime.d.ts.map +1 -1
  165. package/dist/runtime/owner-runtime.js +3 -0
  166. package/dist/runtime/owner-runtime.js.map +1 -1
  167. package/dist/runtime/owner-system-prompt.d.ts.map +1 -1
  168. package/dist/runtime/owner-system-prompt.js +9 -7
  169. package/dist/runtime/owner-system-prompt.js.map +1 -1
  170. package/dist/runtime/principal-access.d.ts.map +1 -1
  171. package/dist/runtime/principal-access.js +1 -0
  172. package/dist/runtime/principal-access.js.map +1 -1
  173. package/dist/runtime/rotating-log.d.ts +44 -0
  174. package/dist/runtime/rotating-log.d.ts.map +1 -0
  175. package/dist/runtime/rotating-log.js +124 -0
  176. package/dist/runtime/rotating-log.js.map +1 -0
  177. package/dist/runtime/web-fetch-scope.d.ts +20 -0
  178. package/dist/runtime/web-fetch-scope.d.ts.map +1 -0
  179. package/dist/runtime/web-fetch-scope.js +68 -0
  180. package/dist/runtime/web-fetch-scope.js.map +1 -0
  181. package/dist/tools/document-toolkit.d.ts +2 -0
  182. package/dist/tools/document-toolkit.d.ts.map +1 -1
  183. package/dist/tools/document-toolkit.js +3 -1
  184. package/dist/tools/document-toolkit.js.map +1 -1
  185. package/dist/tools/office-render.d.ts.map +1 -1
  186. package/dist/tools/office-render.js +3 -0
  187. package/dist/tools/office-render.js.map +1 -1
  188. package/package.json +4 -3
  189. package/toolkit/requirements.in +11 -0
  190. package/toolkit/requirements.lock +984 -5
@@ -1 +1 @@
1
- {"version":3,"file":"claude-caller-config.js","sourceRoot":"","sources":["../../../src/cli/runtime/claude-caller-config.ts"],"names":[],"mappings":";;AAGA,sDAEC;AASD,wDAyCC;AAvDD,qCAAmD;AACnD,yCAA0C;AAE1C,SAAgB,qBAAqB;IACnC,OAAO,IAAA,gBAAI,EAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,uBAAuB,CAAC,CAAC;AACzE,CAAC;AAQD,gFAAgF;AAChF,SAAgB,sBAAsB,CACpC,YAAoB,EACpB,kBAAqC,EAAE,EACvC,YAAkC,EAClC,MAAM,GAAG,IAAA,gBAAI,EAAC,IAAA,mBAAO,EAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAE5C,YAAY,GAAG,IAAA,mBAAO,EAAC,YAAY,CAAC,CAAC;IACrC,MAAM,SAAS,GAAG,IAAA,gBAAI,EAAC,YAAY,EAAE,SAAS,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,CAAC,KAAa,EAAU,EAAE,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC;IAC/E,MAAM,OAAO,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,qBAAqB,EAAE,CAAC,EAAE,CAAC;IAC/E,MAAM,QAAQ,GAAG;QACf,KAAK,EAAE;YACL,UAAU,EAAE,CAAC,EAAE,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;SAClF;QACD,OAAO,EAAE;YACP,OAAO,EAAE,IAAI;YACb,iBAAiB,EAAE,IAAI;YACvB,wBAAwB,EAAE,IAAI;YAC9B,wBAAwB,EAAE,KAAK;YAC/B,gBAAgB,EAAE,EAAE;YACpB,UAAU,EAAE;gBACV,UAAU,EAAE,CAAC,YAAY,CAAC;gBAC1B,QAAQ,EAAE,CAAC,GAAG,eAAe,CAAC;gBAC9B,SAAS,EAAE,CAAC,SAAS,CAAC;aACvB;YACD,uFAAuF;YACvF,GAAG,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,GAAG,YAAY,EAAE,EAAE,CAAC;SACxE;QACD,GAAG,EAAE;YACH,kBAAkB,EAAE,MAAM;YAC1B,sFAAsF;YACtF,oCAAoC,EAAE,GAAG;SAC1C;KACF,CAAC;IACF,IAAA,mBAAS,EAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1C,IAAA,mBAAS,EAAC,IAAA,gBAAI,EAAC,YAAY,EAAE,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACxE,4FAA4F;IAC5F,IAAA,uBAAa,EAAC,IAAA,gBAAI,EAAC,SAAS,EAAE,eAAe,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;QACxF,IAAI,EAAE,KAAK;KACZ,CAAC,CAAC;IACH,IAAA,uBAAa,EAAC,IAAA,gBAAI,EAAC,SAAS,EAAE,qBAAqB,CAAC,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AACjF,CAAC"}
1
+ {"version":3,"file":"claude-caller-config.js","sourceRoot":"","sources":["../../../src/cli/runtime/claude-caller-config.ts"],"names":[],"mappings":";;AAGA,sDAEC;AASD,wDAqDC;AAnED,qCAAmD;AACnD,yCAA0C;AAE1C,SAAgB,qBAAqB;IACnC,OAAO,IAAA,gBAAI,EAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,uBAAuB,CAAC,CAAC;AACzE,CAAC;AAQD,gFAAgF;AAChF,SAAgB,sBAAsB,CACpC,YAAoB,EACpB,kBAAqC,EAAE,EACvC,YAAkC,EAClC,MAAM,GAAG,IAAA,gBAAI,EAAC,IAAA,mBAAO,EAAC,YAAY,CAAC,EAAE,MAAM,CAAC;AAC5C,iGAAiG;AACjG,gBAAyB;IAEzB,YAAY,GAAG,IAAA,mBAAO,EAAC,YAAY,CAAC,CAAC;IACrC,MAAM,SAAS,GAAG,IAAA,gBAAI,EAAC,YAAY,EAAE,SAAS,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,CAAC,KAAa,EAAU,EAAE,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC;IAC/E,MAAM,OAAO,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,qBAAqB,EAAE,CAAC,EAAE,CAAC;IAC/E,MAAM,QAAQ,GAAG;QACf,KAAK,EAAE;YACL,UAAU,EAAE;gBACV,EAAE,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE;gBACnE,GAAG,CAAC,gBAAgB,KAAK,SAAS;oBAChC,CAAC,CAAC,EAAE;oBACJ,CAAC,CAAC;wBACE;4BACE,OAAO,EAAE,UAAU;4BACnB,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,OAAO,IAAI,KAAK,CAAC,gBAAgB,CAAC,EAAE,EAAE,CAAC;yBAC/E;qBACF,CAAC;aACP;SACF;QACD,OAAO,EAAE;YACP,OAAO,EAAE,IAAI;YACb,iBAAiB,EAAE,IAAI;YACvB,wBAAwB,EAAE,IAAI;YAC9B,wBAAwB,EAAE,KAAK;YAC/B,gBAAgB,EAAE,EAAE;YACpB,UAAU,EAAE;gBACV,UAAU,EAAE,CAAC,YAAY,CAAC;gBAC1B,QAAQ,EAAE,CAAC,GAAG,eAAe,CAAC;gBAC9B,SAAS,EAAE,CAAC,SAAS,CAAC;aACvB;YACD,uFAAuF;YACvF,GAAG,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,GAAG,YAAY,EAAE,EAAE,CAAC;SACxE;QACD,GAAG,EAAE;YACH,kBAAkB,EAAE,MAAM;YAC1B,sFAAsF;YACtF,oCAAoC,EAAE,GAAG;SAC1C;KACF,CAAC;IACF,IAAA,mBAAS,EAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1C,IAAA,mBAAS,EAAC,IAAA,gBAAI,EAAC,YAAY,EAAE,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACxE,4FAA4F;IAC5F,IAAA,uBAAa,EAAC,IAAA,gBAAI,EAAC,SAAS,EAAE,eAAe,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;QACxF,IAAI,EAAE,KAAK;KACZ,CAAC,CAAC;IACH,IAAA,uBAAa,EAAC,IAAA,gBAAI,EAAC,SAAS,EAAE,qBAAqB,CAAC,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AACjF,CAAC"}
@@ -0,0 +1,84 @@
1
+ import { CliInputError } from '../prompt.js';
2
+ /**
3
+ * One install runs one process that owns its stores: the daemon, or a replay or backfill booted
4
+ * the same way, or register-owner. Its claim is an exclusive SQLite lock on `runtime/daemon.lock`,
5
+ * held for the process's life and released by the operating system when the process ends, so a
6
+ * crash, a reboot or a reused pid never leaves a claim behind. `runtime/daemon.holder.json` names
7
+ * the holder for `mama status`. The token for the control socket also lives under `runtime/`,
8
+ * which the agents' native reads deny, so a session that reaches the socket still cannot use it.
9
+ * The socket sits beside `runtime.sock` at the root, so it fits the same AF_UNIX path limit
10
+ * (104 bytes on macOS).
11
+ */
12
+ export interface DaemonControlPaths {
13
+ readonly lockPath: string;
14
+ readonly holderPath: string;
15
+ readonly socketPath: string;
16
+ readonly tokenPath: string;
17
+ }
18
+ export declare function daemonControlPaths(mamaRoot: string): DaemonControlPaths;
19
+ /** The journal an interrupted `mama restore` leaves; nothing may run on the install while it is there. */
20
+ export declare function restoreJournalPath(mamaRoot: string): string;
21
+ /** A half-switched install: a refusal, not a failure, so a service does not restart into it. */
22
+ export declare class RestorePendingError extends CliInputError {
23
+ readonly code = "MAMA_RESTORE_PENDING";
24
+ constructor();
25
+ }
26
+ /** Refuse to work on an install while a restore journal is open. */
27
+ export declare function refuseWhileRestoring(mamaRoot: string): void;
28
+ export interface LockOwner {
29
+ readonly pid: number;
30
+ readonly command: string;
31
+ readonly startedAt: number;
32
+ readonly nonce: string;
33
+ }
34
+ /** A CLI input error: the message names the holder and the fix, and carries no secret. */
35
+ export declare class InstallBusyError extends CliInputError {
36
+ readonly holder: LockOwner | null;
37
+ readonly code = "MAMA_INSTALL_BUSY";
38
+ constructor(holder: LockOwner | null, lockPath: string);
39
+ }
40
+ export interface InstallLock {
41
+ readonly owner: LockOwner;
42
+ release(): void;
43
+ }
44
+ /**
45
+ * Take the install's lock: an exclusive transaction on the lock database, kept open for the
46
+ * process's life. A held lock refuses after `busyTimeoutMs`, which only outlasts the moment a
47
+ * `mama status` probe reads the file.
48
+ */
49
+ export declare function acquireInstallLock(paths: DaemonControlPaths, command: string, options?: {
50
+ busyTimeoutMs?: number;
51
+ }): InstallLock;
52
+ /**
53
+ * The process that holds the install, or null when none does. Reading the lock database needs a
54
+ * shared lock, which the holder's exclusive one refuses; when nothing holds it, the read takes the
55
+ * shared lock for an instant only.
56
+ */
57
+ export declare function lockHolder(paths: DaemonControlPaths): LockOwner | null;
58
+ export type DaemonControlOp = 'status' | 'stop';
59
+ export interface DaemonControlHandlers {
60
+ status(): Promise<Record<string, unknown>> | Record<string, unknown>;
61
+ stop(): void;
62
+ }
63
+ export interface DaemonControlServer {
64
+ close(): Promise<void>;
65
+ }
66
+ /**
67
+ * Serve status and stop to the CLI. Only the lock holder calls this, so removing a socket left by
68
+ * a dead holder never removes a live one. Each boot writes a new token; a request without it is
69
+ * refused.
70
+ */
71
+ export declare function startDaemonControl(paths: DaemonControlPaths, handlers: DaemonControlHandlers): Promise<DaemonControlServer>;
72
+ export type DaemonControlReply = {
73
+ state: 'stopped';
74
+ holder: LockOwner | null;
75
+ } | {
76
+ state: 'running';
77
+ reply: Record<string, unknown>;
78
+ };
79
+ /**
80
+ * Ask the install's daemon. No token or no listening socket means nothing serves this install;
81
+ * a lock left behind is reported with its holder so a crashed process is visible.
82
+ */
83
+ export declare function requestDaemonControl(paths: DaemonControlPaths, op: DaemonControlOp, timeoutMs?: number): Promise<DaemonControlReply>;
84
+ //# sourceMappingURL=daemon-control.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon-control.d.ts","sourceRoot":"","sources":["../../../src/cli/runtime/daemon-control.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C;;;;;;;;;GASG;AAEH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,CAQvE;AAED,0GAA0G;AAC1G,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,gGAAgG;AAChG,qBAAa,mBAAoB,SAAQ,aAAa;IACpD,QAAQ,CAAC,IAAI,0BAA0B;;CAKxC;AAED,oEAAoE;AACpE,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAE3D;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,0FAA0F;AAC1F,qBAAa,gBAAiB,SAAQ,aAAa;IAG/C,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI;IAFnC,QAAQ,CAAC,IAAI,uBAAuB;gBAEzB,MAAM,EAAE,SAAS,GAAG,IAAI,EACjC,QAAQ,EAAE,MAAM;CASnB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,OAAO,IAAI,IAAI,CAAC;CACjB;AAqBD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,kBAAkB,EACzB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAA;CAAO,GACvC,WAAW,CA+Bb;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,kBAAkB,GAAG,SAAS,GAAG,IAAI,CActE;AAED,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEhD,MAAM,WAAW,qBAAqB;IACpC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrE,IAAI,IAAI,IAAI,CAAC;CACd;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAID;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,kBAAkB,EACzB,QAAQ,EAAE,qBAAqB,GAC9B,OAAO,CAAC,mBAAmB,CAAC,CAuE9B;AAED,MAAM,MAAM,kBAAkB,GAC1B;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAAA;CAAE,GAC9C;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC;AAEzD;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,kBAAkB,EACzB,EAAE,EAAE,eAAe,EACnB,SAAS,SAAQ,GAChB,OAAO,CAAC,kBAAkB,CAAC,CAwC7B"}
@@ -0,0 +1,266 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.InstallBusyError = exports.RestorePendingError = void 0;
7
+ exports.daemonControlPaths = daemonControlPaths;
8
+ exports.restoreJournalPath = restoreJournalPath;
9
+ exports.refuseWhileRestoring = refuseWhileRestoring;
10
+ exports.acquireInstallLock = acquireInstallLock;
11
+ exports.lockHolder = lockHolder;
12
+ exports.startDaemonControl = startDaemonControl;
13
+ exports.requestDaemonControl = requestDaemonControl;
14
+ const node_crypto_1 = require("node:crypto");
15
+ const node_fs_1 = require("node:fs");
16
+ const node_net_1 = require("node:net");
17
+ const node_path_1 = require("node:path");
18
+ const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
19
+ const prompt_js_1 = require("../prompt.js");
20
+ function daemonControlPaths(mamaRoot) {
21
+ const runtimeRoot = (0, node_path_1.join)(mamaRoot, 'runtime');
22
+ return {
23
+ lockPath: (0, node_path_1.join)(runtimeRoot, 'daemon.lock'),
24
+ holderPath: (0, node_path_1.join)(runtimeRoot, 'daemon.holder.json'),
25
+ socketPath: (0, node_path_1.join)(mamaRoot, 'daemon.sock'),
26
+ tokenPath: (0, node_path_1.join)(runtimeRoot, 'daemon.token'),
27
+ };
28
+ }
29
+ /** The journal an interrupted `mama restore` leaves; nothing may run on the install while it is there. */
30
+ function restoreJournalPath(mamaRoot) {
31
+ return (0, node_path_1.join)(mamaRoot, 'backups', '.restore-journal.json');
32
+ }
33
+ /** A half-switched install: a refusal, not a failure, so a service does not restart into it. */
34
+ class RestorePendingError extends prompt_js_1.CliInputError {
35
+ code = 'MAMA_RESTORE_PENDING';
36
+ constructor() {
37
+ super('An interrupted restore is unfinished; run mama restore --rollback first');
38
+ this.name = 'RestorePendingError';
39
+ }
40
+ }
41
+ exports.RestorePendingError = RestorePendingError;
42
+ /** Refuse to work on an install while a restore journal is open. */
43
+ function refuseWhileRestoring(mamaRoot) {
44
+ if ((0, node_fs_1.existsSync)(restoreJournalPath(mamaRoot)))
45
+ throw new RestorePendingError();
46
+ }
47
+ /** A CLI input error: the message names the holder and the fix, and carries no secret. */
48
+ class InstallBusyError extends prompt_js_1.CliInputError {
49
+ holder;
50
+ code = 'MAMA_INSTALL_BUSY';
51
+ constructor(holder, lockPath) {
52
+ super(holder === null
53
+ ? `MAMA is already running here (${lockPath}); stop it first: mama stop`
54
+ : `MAMA is already running here (${holder.command}, pid ${holder.pid}; ${lockPath}); stop it first: mama stop`);
55
+ this.holder = holder;
56
+ this.name = 'InstallBusyError';
57
+ }
58
+ }
59
+ exports.InstallBusyError = InstallBusyError;
60
+ function readHolder(path) {
61
+ try {
62
+ const value = JSON.parse((0, node_fs_1.readFileSync)(path, 'utf8'));
63
+ return typeof value.pid === 'number' &&
64
+ typeof value.command === 'string' &&
65
+ typeof value.startedAt === 'number' &&
66
+ typeof value.nonce === 'string'
67
+ ? value
68
+ : null;
69
+ }
70
+ catch (error) {
71
+ if (error.code === 'ENOENT')
72
+ return null;
73
+ throw error;
74
+ }
75
+ }
76
+ function isBusy(error) {
77
+ return error.code === 'SQLITE_BUSY';
78
+ }
79
+ /**
80
+ * Take the install's lock: an exclusive transaction on the lock database, kept open for the
81
+ * process's life. A held lock refuses after `busyTimeoutMs`, which only outlasts the moment a
82
+ * `mama status` probe reads the file.
83
+ */
84
+ function acquireInstallLock(paths, command, options = {}) {
85
+ (0, node_fs_1.mkdirSync)((0, node_path_1.join)(paths.lockPath, '..'), { recursive: true, mode: 0o700 });
86
+ const db = new better_sqlite3_1.default(paths.lockPath, { timeout: options.busyTimeoutMs ?? 2_000 });
87
+ try {
88
+ (0, node_fs_1.chmodSync)(paths.lockPath, 0o600);
89
+ db.pragma('locking_mode = EXCLUSIVE');
90
+ db.exec('BEGIN EXCLUSIVE');
91
+ }
92
+ catch (error) {
93
+ db.close();
94
+ if (isBusy(error))
95
+ throw new InstallBusyError(readHolder(paths.holderPath), paths.lockPath);
96
+ throw error;
97
+ }
98
+ const owner = {
99
+ pid: process.pid,
100
+ command,
101
+ startedAt: Date.now(),
102
+ nonce: (0, node_crypto_1.randomUUID)(),
103
+ };
104
+ const staged = `${paths.holderPath}.${owner.nonce}`;
105
+ (0, node_fs_1.writeFileSync)(staged, `${JSON.stringify(owner)}\n`, { mode: 0o600, flag: 'wx' });
106
+ (0, node_fs_1.renameSync)(staged, paths.holderPath);
107
+ let released = false;
108
+ return {
109
+ owner,
110
+ release: () => {
111
+ if (released)
112
+ return;
113
+ released = true;
114
+ if (readHolder(paths.holderPath)?.nonce === owner.nonce)
115
+ (0, node_fs_1.rmSync)(paths.holderPath);
116
+ db.close();
117
+ },
118
+ };
119
+ }
120
+ /**
121
+ * The process that holds the install, or null when none does. Reading the lock database needs a
122
+ * shared lock, which the holder's exclusive one refuses; when nothing holds it, the read takes the
123
+ * shared lock for an instant only.
124
+ */
125
+ function lockHolder(paths) {
126
+ if (!(0, node_fs_1.existsSync)(paths.lockPath))
127
+ return null;
128
+ const db = new better_sqlite3_1.default(paths.lockPath, { readonly: true, timeout: 0 });
129
+ try {
130
+ db.pragma('schema_version');
131
+ return null;
132
+ }
133
+ catch (error) {
134
+ if (!isBusy(error))
135
+ throw error;
136
+ return (readHolder(paths.holderPath) ?? { pid: 0, command: 'unknown', startedAt: 0, nonce: 'unknown' });
137
+ }
138
+ finally {
139
+ db.close();
140
+ }
141
+ }
142
+ const MAX_REQUEST_BYTES = 4096;
143
+ /**
144
+ * Serve status and stop to the CLI. Only the lock holder calls this, so removing a socket left by
145
+ * a dead holder never removes a live one. Each boot writes a new token; a request without it is
146
+ * refused.
147
+ */
148
+ async function startDaemonControl(paths, handlers) {
149
+ const token = (0, node_crypto_1.randomBytes)(32).toString('hex');
150
+ (0, node_fs_1.rmSync)(paths.tokenPath, { force: true });
151
+ (0, node_fs_1.writeFileSync)(paths.tokenPath, `${token}\n`, { mode: 0o600, flag: 'wx' });
152
+ (0, node_fs_1.rmSync)(paths.socketPath, { force: true });
153
+ const expected = Buffer.from(token, 'utf8');
154
+ const server = (0, node_net_1.createServer)((socket) => {
155
+ let buffer = '';
156
+ socket.setEncoding('utf8');
157
+ socket.setTimeout(5_000, () => socket.destroy());
158
+ socket.on('error', () => socket.destroy());
159
+ socket.on('data', (chunk) => {
160
+ buffer += chunk;
161
+ if (buffer.length > MAX_REQUEST_BYTES) {
162
+ socket.destroy();
163
+ return;
164
+ }
165
+ const newline = buffer.indexOf('\n');
166
+ if (newline === -1)
167
+ return;
168
+ const line = buffer.slice(0, newline);
169
+ buffer = '';
170
+ void answer(line).then((reply) => socket.end(`${JSON.stringify(reply)}\n`), (error) => socket.end(`${JSON.stringify({ ok: false, error: error instanceof Error ? error.message : String(error) })}\n`));
171
+ });
172
+ });
173
+ async function answer(line) {
174
+ let request;
175
+ try {
176
+ request = JSON.parse(line);
177
+ }
178
+ catch {
179
+ return { ok: false, error: 'invalid request' };
180
+ }
181
+ const given = Buffer.from(typeof request.token === 'string' ? request.token : '', 'utf8');
182
+ if (given.length !== expected.length || !(0, node_crypto_1.timingSafeEqual)(given, expected)) {
183
+ return { ok: false, error: 'unauthorized' };
184
+ }
185
+ if (request.op === 'status')
186
+ return { ok: true, status: await handlers.status() };
187
+ if (request.op === 'stop') {
188
+ handlers.stop();
189
+ return { ok: true };
190
+ }
191
+ return { ok: false, error: 'unknown op' };
192
+ }
193
+ try {
194
+ await new Promise((resolve, reject) => {
195
+ server.once('error', reject);
196
+ server.listen(paths.socketPath, () => {
197
+ server.off('error', reject);
198
+ resolve();
199
+ });
200
+ });
201
+ }
202
+ catch (error) {
203
+ (0, node_fs_1.rmSync)(paths.tokenPath, { force: true });
204
+ throw error;
205
+ }
206
+ (0, node_fs_1.chmodSync)(paths.socketPath, 0o600);
207
+ return {
208
+ close: () => new Promise((resolve) => {
209
+ server.close(() => {
210
+ (0, node_fs_1.rmSync)(paths.socketPath, { force: true });
211
+ (0, node_fs_1.rmSync)(paths.tokenPath, { force: true });
212
+ resolve();
213
+ });
214
+ }),
215
+ };
216
+ }
217
+ /**
218
+ * Ask the install's daemon. No token or no listening socket means nothing serves this install;
219
+ * a lock left behind is reported with its holder so a crashed process is visible.
220
+ */
221
+ async function requestDaemonControl(paths, op, timeoutMs = 5_000) {
222
+ let token;
223
+ try {
224
+ token = (0, node_fs_1.readFileSync)(paths.tokenPath, 'utf8').trim();
225
+ }
226
+ catch (error) {
227
+ if (error.code !== 'ENOENT')
228
+ throw error;
229
+ return { state: 'stopped', holder: lockHolder(paths) };
230
+ }
231
+ return await new Promise((resolve, reject) => {
232
+ const socket = (0, node_net_1.connect)(paths.socketPath);
233
+ let data = '';
234
+ socket.setEncoding('utf8');
235
+ socket.setTimeout(timeoutMs, () => {
236
+ socket.destroy();
237
+ reject(new Error(`The daemon did not answer within ${timeoutMs} ms`));
238
+ });
239
+ socket.on('connect', () => socket.write(`${JSON.stringify({ token, op })}\n`));
240
+ socket.on('data', (chunk) => {
241
+ data += chunk;
242
+ });
243
+ socket.on('end', () => {
244
+ try {
245
+ resolve({ state: 'running', reply: JSON.parse(data) });
246
+ }
247
+ catch {
248
+ reject(new Error('The daemon sent an unreadable reply'));
249
+ }
250
+ });
251
+ socket.on('error', (error) => {
252
+ if (error.code !== 'ENOENT' && error.code !== 'ECONNREFUSED') {
253
+ reject(error);
254
+ return;
255
+ }
256
+ // Inside an event handler a throw would be uncaught; the caller gets it instead.
257
+ try {
258
+ resolve({ state: 'stopped', holder: lockHolder(paths) });
259
+ }
260
+ catch (holderError) {
261
+ reject(holderError);
262
+ }
263
+ });
264
+ });
265
+ }
266
+ //# sourceMappingURL=daemon-control.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon-control.js","sourceRoot":"","sources":["../../../src/cli/runtime/daemon-control.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ import { loadConnector } from '../../connectors/index.js';
2
+ import { type ProbeRun } from './backend-probe.js';
3
+ import { type DaemonControlReply } from './daemon-control.js';
4
+ import { type ServiceRun } from './systemd-service.js';
5
+ export type CheckStatus = 'ok' | 'warn' | 'fail';
6
+ export interface Check {
7
+ readonly name: string;
8
+ readonly status: CheckStatus;
9
+ /** What doctor found, in its own words; the shareable report carries only this. */
10
+ readonly detail: string;
11
+ /** What doctor read from the install (paths, error messages); shown here, never reported. */
12
+ readonly context?: string;
13
+ /** What to do about a warn or fail. */
14
+ readonly fix?: string;
15
+ }
16
+ export interface DiagnosticsOptions {
17
+ home?: string;
18
+ configPath?: string;
19
+ platform?: NodeJS.Platform;
20
+ run?: ProbeRun;
21
+ serviceRun?: ServiceRun;
22
+ /** No network call: Telegram is not asked and sources are not started. */
23
+ offline?: boolean;
24
+ /** A Telegram Bot API call; tests replace it. */
25
+ telegramCall?: (token: string, method: string, params?: Record<string, string>) => Promise<Record<string, unknown>>;
26
+ findIn?: (name: string, dirs: string[]) => string | undefined;
27
+ /** Ask the install's daemon for its status; tests replace it. */
28
+ askStatus?: () => Promise<DaemonControlReply>;
29
+ /** Builds a source as boot does; tests replace it so no source reaches the network. */
30
+ loadSource?: typeof loadConnector;
31
+ /** How long each source may take to start and answer (default 20 s). */
32
+ sourceTimeoutMs?: number;
33
+ /** Whether something listens on the viewer's address; tests replace it. */
34
+ portInUse?: (port: number, host: string) => Promise<boolean>;
35
+ }
36
+ /**
37
+ * Check an install as its service would run it. Nothing here writes MAMA's files or starts a
38
+ * service; the database is opened read-only (which can leave its -wal and -shm beside it), and the
39
+ * backend's own status command may update the backend's config.
40
+ * Each check names what it found and, when it is not ok, what to do.
41
+ */
42
+ export declare function runDiagnostics(options?: DiagnosticsOptions): Promise<Check[]>;
43
+ //# sourceMappingURL=diagnostics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../../../src/cli/runtime/diagnostics.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAyB1D,OAAO,EAAkC,KAAK,QAAQ,EAAmB,MAAM,oBAAoB,CAAC;AACpG,OAAO,EAAsB,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAOlF,OAAO,EAAoB,KAAK,UAAU,EAAqB,MAAM,sBAAsB,CAAC;AAE5F,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC;AAEjD,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,mFAAmF;IACnF,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,6FAA6F;IAC7F,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,uCAAuC;IACvC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,GAAG,CAAC,EAAE,QAAQ,CAAC;IACf,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,0EAA0E;IAC1E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iDAAiD;IACjD,YAAY,CAAC,EAAE,CACb,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAC5B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACtC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,MAAM,GAAG,SAAS,CAAC;IAC9D,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAC9C,uFAAuF;IACvF,UAAU,CAAC,EAAE,OAAO,aAAa,CAAC;IAClC,wEAAwE;IACxE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,2EAA2E;IAC3E,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC9D;AAiFD;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,CAmSvF"}