@murphai/murph 0.2.7 → 0.2.10

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 (336) hide show
  1. package/CHANGELOG.md +81 -0
  2. package/config.schema.json +36 -3
  3. package/dist/cli-entry.d.ts.map +1 -1
  4. package/dist/cli-entry.js +7 -5
  5. package/dist/cli-entry.js.map +1 -1
  6. package/dist/commands/automation.d.ts +4 -8
  7. package/dist/commands/automation.d.ts.map +1 -1
  8. package/dist/commands/automation.js +2 -2
  9. package/dist/commands/automation.js.map +1 -1
  10. package/dist/commands/document.d.ts.map +1 -1
  11. package/dist/commands/document.js +1 -1
  12. package/dist/commands/document.js.map +1 -1
  13. package/dist/commands/intervention.d.ts.map +1 -1
  14. package/dist/commands/intervention.js +1 -1
  15. package/dist/commands/intervention.js.map +1 -1
  16. package/dist/commands/meal.d.ts +1 -1
  17. package/dist/commands/meal.d.ts.map +1 -1
  18. package/dist/commands/meal.js +53 -3
  19. package/dist/commands/meal.js.map +1 -1
  20. package/dist/commands/route.d.ts.map +1 -1
  21. package/dist/commands/route.js +6 -6
  22. package/dist/commands/route.js.map +1 -1
  23. package/dist/commands/search.d.ts.map +1 -1
  24. package/dist/commands/search.js +2 -1
  25. package/dist/commands/search.js.map +1 -1
  26. package/dist/commands/workout.d.ts.map +1 -1
  27. package/dist/commands/workout.js +1 -1
  28. package/dist/commands/workout.js.map +1 -1
  29. package/dist/incur.generated.d.ts +9 -0
  30. package/dist/incur.generated.d.ts.map +1 -1
  31. package/dist/vault-cli-bootstrap.d.ts +1 -1
  32. package/dist/vault-cli-bootstrap.d.ts.map +1 -1
  33. package/dist/vault-cli-bootstrap.js +2 -2
  34. package/dist/vault-cli-bootstrap.js.map +1 -1
  35. package/dist/vault-cli-command-manifest.d.ts +3 -0
  36. package/dist/vault-cli-command-manifest.d.ts.map +1 -1
  37. package/dist/vault-cli-command-manifest.js +4 -0
  38. package/dist/vault-cli-command-manifest.js.map +1 -1
  39. package/dist/vault-cli.d.ts +6 -0
  40. package/dist/vault-cli.d.ts.map +1 -1
  41. package/dist/vault-cli.js +19 -8
  42. package/dist/vault-cli.js.map +1 -1
  43. package/node_modules/@murphai/assistant-cli/dist/assistant/service.d.ts +2 -2
  44. package/node_modules/@murphai/assistant-engine/dist/assistant/channels/descriptors.d.ts.map +1 -1
  45. package/node_modules/@murphai/assistant-engine/dist/assistant/channels/descriptors.js +1 -16
  46. package/node_modules/@murphai/assistant-engine/dist/assistant/channels/descriptors.js.map +1 -1
  47. package/node_modules/@murphai/assistant-engine/dist/assistant/channels/helpers.d.ts +2 -12
  48. package/node_modules/@murphai/assistant-engine/dist/assistant/channels/helpers.d.ts.map +1 -1
  49. package/node_modules/@murphai/assistant-engine/dist/assistant/channels/helpers.js +23 -43
  50. package/node_modules/@murphai/assistant-engine/dist/assistant/channels/helpers.js.map +1 -1
  51. package/node_modules/@murphai/assistant-engine/dist/assistant/channels/registry.d.ts.map +1 -1
  52. package/node_modules/@murphai/assistant-engine/dist/assistant/channels/registry.js +3 -2
  53. package/node_modules/@murphai/assistant-engine/dist/assistant/channels/registry.js.map +1 -1
  54. package/node_modules/@murphai/assistant-engine/dist/assistant/channels/types.d.ts +1 -1
  55. package/node_modules/@murphai/assistant-engine/dist/assistant/channels/types.d.ts.map +1 -1
  56. package/node_modules/@murphai/assistant-engine/dist/assistant/cron/notification-delivery.d.ts +6 -0
  57. package/node_modules/@murphai/assistant-engine/dist/assistant/cron/notification-delivery.d.ts.map +1 -0
  58. package/node_modules/@murphai/assistant-engine/dist/assistant/cron/notification-delivery.js +21 -0
  59. package/node_modules/@murphai/assistant-engine/dist/assistant/cron/notification-delivery.js.map +1 -0
  60. package/node_modules/@murphai/assistant-engine/dist/assistant/cron/store.d.ts +0 -2
  61. package/node_modules/@murphai/assistant-engine/dist/assistant/cron/store.d.ts.map +1 -1
  62. package/node_modules/@murphai/assistant-engine/dist/assistant/cron/store.js +0 -1
  63. package/node_modules/@murphai/assistant-engine/dist/assistant/cron/store.js.map +1 -1
  64. package/node_modules/@murphai/assistant-engine/dist/assistant/cron.d.ts.map +1 -1
  65. package/node_modules/@murphai/assistant-engine/dist/assistant/cron.js +67 -43
  66. package/node_modules/@murphai/assistant-engine/dist/assistant/cron.js.map +1 -1
  67. package/node_modules/@murphai/assistant-engine/dist/assistant/notification-turn.d.ts +25 -0
  68. package/node_modules/@murphai/assistant-engine/dist/assistant/notification-turn.d.ts.map +1 -0
  69. package/node_modules/@murphai/assistant-engine/dist/assistant/notification-turn.js +201 -0
  70. package/node_modules/@murphai/assistant-engine/dist/assistant/notification-turn.js.map +1 -0
  71. package/node_modules/@murphai/assistant-engine/dist/assistant/outbox/dispatch-state.d.ts +38 -0
  72. package/node_modules/@murphai/assistant-engine/dist/assistant/outbox/dispatch-state.d.ts.map +1 -0
  73. package/node_modules/@murphai/assistant-engine/dist/assistant/outbox/dispatch-state.js +215 -0
  74. package/node_modules/@murphai/assistant-engine/dist/assistant/outbox/dispatch-state.js.map +1 -0
  75. package/node_modules/@murphai/assistant-engine/dist/assistant/outbox/retry-policy.d.ts.map +1 -1
  76. package/node_modules/@murphai/assistant-engine/dist/assistant/outbox/retry-policy.js +77 -41
  77. package/node_modules/@murphai/assistant-engine/dist/assistant/outbox/retry-policy.js.map +1 -1
  78. package/node_modules/@murphai/assistant-engine/dist/assistant/outbox.d.ts.map +1 -1
  79. package/node_modules/@murphai/assistant-engine/dist/assistant/outbox.js +4 -201
  80. package/node_modules/@murphai/assistant-engine/dist/assistant/outbox.js.map +1 -1
  81. package/node_modules/@murphai/assistant-engine/dist/assistant/provider-config.d.ts.map +1 -1
  82. package/node_modules/@murphai/assistant-engine/dist/assistant/provider-config.js +10 -3
  83. package/node_modules/@murphai/assistant-engine/dist/assistant/provider-config.js.map +1 -1
  84. package/node_modules/@murphai/assistant-engine/dist/assistant/provider-turn-runner.d.ts +9 -0
  85. package/node_modules/@murphai/assistant-engine/dist/assistant/provider-turn-runner.d.ts.map +1 -1
  86. package/node_modules/@murphai/assistant-engine/dist/assistant/provider-turn-runner.js +60 -25
  87. package/node_modules/@murphai/assistant-engine/dist/assistant/provider-turn-runner.js.map +1 -1
  88. package/node_modules/@murphai/assistant-engine/dist/assistant/providers/openai-compatible.d.ts.map +1 -1
  89. package/node_modules/@murphai/assistant-engine/dist/assistant/providers/openai-compatible.js +20 -58
  90. package/node_modules/@murphai/assistant-engine/dist/assistant/providers/openai-compatible.js.map +1 -1
  91. package/node_modules/@murphai/assistant-engine/dist/assistant/redaction.d.ts +4 -8
  92. package/node_modules/@murphai/assistant-engine/dist/assistant/redaction.d.ts.map +1 -1
  93. package/node_modules/@murphai/assistant-engine/dist/assistant/redaction.js +3 -37
  94. package/node_modules/@murphai/assistant-engine/dist/assistant/redaction.js.map +1 -1
  95. package/node_modules/@murphai/assistant-engine/dist/assistant/service.d.ts +8 -5
  96. package/node_modules/@murphai/assistant-engine/dist/assistant/service.d.ts.map +1 -1
  97. package/node_modules/@murphai/assistant-engine/dist/assistant/service.js +5 -0
  98. package/node_modules/@murphai/assistant-engine/dist/assistant/service.js.map +1 -1
  99. package/node_modules/@murphai/assistant-engine/dist/assistant/state-ids.d.ts +0 -1
  100. package/node_modules/@murphai/assistant-engine/dist/assistant/state-ids.d.ts.map +1 -1
  101. package/node_modules/@murphai/assistant-engine/dist/assistant/state-ids.js +3 -8
  102. package/node_modules/@murphai/assistant-engine/dist/assistant/state-ids.js.map +1 -1
  103. package/node_modules/@murphai/assistant-engine/dist/assistant/state-secrets.d.ts.map +1 -1
  104. package/node_modules/@murphai/assistant-engine/dist/assistant/state-secrets.js +9 -15
  105. package/node_modules/@murphai/assistant-engine/dist/assistant/state-secrets.js.map +1 -1
  106. package/node_modules/@murphai/assistant-engine/dist/assistant/system-prompt.d.ts +8 -0
  107. package/node_modules/@murphai/assistant-engine/dist/assistant/system-prompt.d.ts.map +1 -1
  108. package/node_modules/@murphai/assistant-engine/dist/assistant/system-prompt.js +30 -4
  109. package/node_modules/@murphai/assistant-engine/dist/assistant/system-prompt.js.map +1 -1
  110. package/node_modules/@murphai/assistant-engine/dist/assistant/turn-finalizer.d.ts +3 -0
  111. package/node_modules/@murphai/assistant-engine/dist/assistant/turn-finalizer.d.ts.map +1 -1
  112. package/node_modules/@murphai/assistant-engine/dist/assistant/turn-finalizer.js +19 -11
  113. package/node_modules/@murphai/assistant-engine/dist/assistant/turn-finalizer.js.map +1 -1
  114. package/node_modules/@murphai/assistant-engine/dist/assistant-cli-tools/capability-definitions.d.ts +3 -3
  115. package/node_modules/@murphai/assistant-engine/dist/assistant-cli-tools/capability-definitions.d.ts.map +1 -1
  116. package/node_modules/@murphai/assistant-engine/dist/assistant-cli-tools/capability-definitions.js +35 -17
  117. package/node_modules/@murphai/assistant-engine/dist/assistant-cli-tools/capability-definitions.js.map +1 -1
  118. package/node_modules/@murphai/assistant-engine/dist/assistant-cli-tools/catalog-profiles.d.ts +1 -0
  119. package/node_modules/@murphai/assistant-engine/dist/assistant-cli-tools/catalog-profiles.d.ts.map +1 -1
  120. package/node_modules/@murphai/assistant-engine/dist/assistant-cli-tools/catalog-profiles.js +14 -0
  121. package/node_modules/@murphai/assistant-engine/dist/assistant-cli-tools/catalog-profiles.js.map +1 -1
  122. package/node_modules/@murphai/assistant-engine/dist/assistant-cli-tools/policy-wrappers.d.ts.map +1 -1
  123. package/node_modules/@murphai/assistant-engine/dist/assistant-cli-tools/policy-wrappers.js +1 -0
  124. package/node_modules/@murphai/assistant-engine/dist/assistant-cli-tools/policy-wrappers.js.map +1 -1
  125. package/node_modules/@murphai/assistant-engine/dist/assistant-cli-tools.d.ts +1 -1
  126. package/node_modules/@murphai/assistant-engine/dist/assistant-cli-tools.d.ts.map +1 -1
  127. package/node_modules/@murphai/assistant-engine/dist/assistant-cli-tools.js +1 -1
  128. package/node_modules/@murphai/assistant-engine/dist/assistant-cli-tools.js.map +1 -1
  129. package/node_modules/@murphai/assistant-engine/dist/inbox-model-contracts.d.ts +1 -4
  130. package/node_modules/@murphai/assistant-engine/dist/inbox-model-contracts.d.ts.map +1 -1
  131. package/node_modules/@murphai/assistant-engine/dist/inbox-model-contracts.js +1 -1
  132. package/node_modules/@murphai/assistant-engine/dist/inbox-model-contracts.js.map +1 -1
  133. package/node_modules/@murphai/assistant-engine/dist/inbox-model-harness.js +1 -1
  134. package/node_modules/@murphai/assistant-engine/dist/inbox-model-harness.js.map +1 -1
  135. package/node_modules/@murphai/assistant-engine/dist/model-harness.d.ts +4 -0
  136. package/node_modules/@murphai/assistant-engine/dist/model-harness.d.ts.map +1 -1
  137. package/node_modules/@murphai/assistant-engine/dist/model-harness.js +46 -25
  138. package/node_modules/@murphai/assistant-engine/dist/model-harness.js.map +1 -1
  139. package/node_modules/@murphai/assistant-engine/package.json +2 -2
  140. package/node_modules/@murphai/assistantd/package.json +1 -1
  141. package/node_modules/@murphai/core/dist/automation.d.ts +1 -1
  142. package/node_modules/@murphai/core/dist/automation.d.ts.map +1 -1
  143. package/node_modules/@murphai/core/dist/automation.js +13 -16
  144. package/node_modules/@murphai/core/dist/automation.js.map +1 -1
  145. package/node_modules/@murphai/core/dist/bank/foods.d.ts.map +1 -1
  146. package/node_modules/@murphai/core/dist/bank/foods.js +29 -0
  147. package/node_modules/@murphai/core/dist/bank/foods.js.map +1 -1
  148. package/node_modules/@murphai/core/dist/bank/types.d.ts +3 -1
  149. package/node_modules/@murphai/core/dist/bank/types.d.ts.map +1 -1
  150. package/node_modules/@murphai/core/dist/bank/types.js.map +1 -1
  151. package/node_modules/@murphai/core/dist/mutations.d.ts +3 -2
  152. package/node_modules/@murphai/core/dist/mutations.d.ts.map +1 -1
  153. package/node_modules/@murphai/core/dist/mutations.js +6 -3
  154. package/node_modules/@murphai/core/dist/mutations.js.map +1 -1
  155. package/node_modules/@murphai/core/dist/nutrition.d.ts +6 -0
  156. package/node_modules/@murphai/core/dist/nutrition.d.ts.map +1 -0
  157. package/node_modules/@murphai/core/dist/nutrition.js +69 -0
  158. package/node_modules/@murphai/core/dist/nutrition.js.map +1 -0
  159. package/node_modules/@murphai/core/package.json +1 -1
  160. package/node_modules/@murphai/device-syncd/README.md +4 -2
  161. package/node_modules/@murphai/device-syncd/dist/callback-redirect.d.ts +11 -0
  162. package/node_modules/@murphai/device-syncd/dist/callback-redirect.d.ts.map +1 -0
  163. package/node_modules/@murphai/device-syncd/dist/callback-redirect.js +51 -0
  164. package/node_modules/@murphai/device-syncd/dist/callback-redirect.js.map +1 -0
  165. package/node_modules/@murphai/device-syncd/dist/client.d.ts +21 -0
  166. package/node_modules/@murphai/device-syncd/dist/client.d.ts.map +1 -1
  167. package/node_modules/@murphai/device-syncd/dist/client.js.map +1 -1
  168. package/node_modules/@murphai/device-syncd/dist/hosted-runtime.d.ts.map +1 -1
  169. package/node_modules/@murphai/device-syncd/dist/hosted-runtime.js +11 -30
  170. package/node_modules/@murphai/device-syncd/dist/hosted-runtime.js.map +1 -1
  171. package/node_modules/@murphai/device-syncd/dist/http.d.ts +1 -5
  172. package/node_modules/@murphai/device-syncd/dist/http.d.ts.map +1 -1
  173. package/node_modules/@murphai/device-syncd/dist/http.js +10 -26
  174. package/node_modules/@murphai/device-syncd/dist/http.js.map +1 -1
  175. package/node_modules/@murphai/device-syncd/dist/index.d.ts +1 -0
  176. package/node_modules/@murphai/device-syncd/dist/index.d.ts.map +1 -1
  177. package/node_modules/@murphai/device-syncd/dist/index.js +1 -0
  178. package/node_modules/@murphai/device-syncd/dist/index.js.map +1 -1
  179. package/node_modules/@murphai/device-syncd/dist/public-ingress.d.ts +2 -1
  180. package/node_modules/@murphai/device-syncd/dist/public-ingress.d.ts.map +1 -1
  181. package/node_modules/@murphai/device-syncd/dist/public-ingress.js +22 -12
  182. package/node_modules/@murphai/device-syncd/dist/public-ingress.js.map +1 -1
  183. package/node_modules/@murphai/device-syncd/dist/service.d.ts.map +1 -1
  184. package/node_modules/@murphai/device-syncd/dist/service.js +1 -1
  185. package/node_modules/@murphai/device-syncd/dist/service.js.map +1 -1
  186. package/node_modules/@murphai/device-syncd/dist/store/oauth-states.d.ts +2 -2
  187. package/node_modules/@murphai/device-syncd/dist/store/oauth-states.d.ts.map +1 -1
  188. package/node_modules/@murphai/device-syncd/dist/store/oauth-states.js +20 -4
  189. package/node_modules/@murphai/device-syncd/dist/store/oauth-states.js.map +1 -1
  190. package/node_modules/@murphai/device-syncd/dist/store/webhook-traces.d.ts +1 -1
  191. package/node_modules/@murphai/device-syncd/dist/store/webhook-traces.d.ts.map +1 -1
  192. package/node_modules/@murphai/device-syncd/dist/store/webhook-traces.js +18 -4
  193. package/node_modules/@murphai/device-syncd/dist/store/webhook-traces.js.map +1 -1
  194. package/node_modules/@murphai/device-syncd/dist/store.d.ts +2 -2
  195. package/node_modules/@murphai/device-syncd/dist/store.d.ts.map +1 -1
  196. package/node_modules/@murphai/device-syncd/dist/store.js +2 -2
  197. package/node_modules/@murphai/device-syncd/dist/store.js.map +1 -1
  198. package/node_modules/@murphai/device-syncd/dist/types.d.ts +12 -23
  199. package/node_modules/@murphai/device-syncd/dist/types.d.ts.map +1 -1
  200. package/node_modules/@murphai/device-syncd/dist/types.js.map +1 -1
  201. package/node_modules/@murphai/device-syncd/package.json +4 -0
  202. package/node_modules/@murphai/gateway-local/package.json +1 -1
  203. package/node_modules/@murphai/importers/package.json +1 -1
  204. package/node_modules/@murphai/inbox-services/package.json +1 -1
  205. package/node_modules/@murphai/inboxd/README.md +2 -1
  206. package/node_modules/@murphai/inboxd/dist/index.d.ts +1 -1
  207. package/node_modules/@murphai/inboxd/dist/index.d.ts.map +1 -1
  208. package/node_modules/@murphai/inboxd/dist/index.js +1 -1
  209. package/node_modules/@murphai/inboxd/dist/index.js.map +1 -1
  210. package/node_modules/@murphai/inboxd/dist/indexing/persist.d.ts +2 -26
  211. package/node_modules/@murphai/inboxd/dist/indexing/persist.d.ts.map +1 -1
  212. package/node_modules/@murphai/inboxd/dist/indexing/persist.js +245 -241
  213. package/node_modules/@murphai/inboxd/dist/indexing/persist.js.map +1 -1
  214. package/node_modules/@murphai/inboxd/dist/kernel/pipeline.js +1 -1
  215. package/node_modules/@murphai/inboxd/dist/kernel/pipeline.js.map +1 -1
  216. package/node_modules/@murphai/inboxd/package.json +1 -1
  217. package/node_modules/@murphai/operator-config/dist/assistant/provider-config.d.ts.map +1 -1
  218. package/node_modules/@murphai/operator-config/dist/assistant/provider-config.js +1 -2
  219. package/node_modules/@murphai/operator-config/dist/assistant/provider-config.js.map +1 -1
  220. package/node_modules/@murphai/operator-config/dist/assistant/redaction.d.ts +1 -0
  221. package/node_modules/@murphai/operator-config/dist/assistant/redaction.d.ts.map +1 -1
  222. package/node_modules/@murphai/operator-config/dist/assistant/redaction.js +8 -2
  223. package/node_modules/@murphai/operator-config/dist/assistant/redaction.js.map +1 -1
  224. package/node_modules/@murphai/operator-config/dist/assistant/target-runtime.d.ts +1 -1
  225. package/node_modules/@murphai/operator-config/dist/assistant/target-runtime.d.ts.map +1 -1
  226. package/node_modules/@murphai/operator-config/dist/assistant/target-runtime.js +36 -31
  227. package/node_modules/@murphai/operator-config/dist/assistant/target-runtime.js.map +1 -1
  228. package/node_modules/@murphai/operator-config/dist/assistant-cli-contracts.d.ts +30 -40
  229. package/node_modules/@murphai/operator-config/dist/assistant-cli-contracts.d.ts.map +1 -1
  230. package/node_modules/@murphai/operator-config/dist/assistant-cli-contracts.js +28 -21
  231. package/node_modules/@murphai/operator-config/dist/assistant-cli-contracts.js.map +1 -1
  232. package/node_modules/@murphai/operator-config/dist/device-sync-client.d.ts +1 -22
  233. package/node_modules/@murphai/operator-config/dist/device-sync-client.d.ts.map +1 -1
  234. package/node_modules/@murphai/operator-config/dist/device-sync-client.js.map +1 -1
  235. package/node_modules/@murphai/operator-config/dist/vault-cli-contracts.js +1 -1
  236. package/node_modules/@murphai/operator-config/dist/vault-cli-contracts.js.map +1 -1
  237. package/node_modules/@murphai/operator-config/package.json +7 -2
  238. package/node_modules/@murphai/query/README.md +2 -0
  239. package/node_modules/@murphai/query/dist/automation.d.ts +1 -1
  240. package/node_modules/@murphai/query/dist/automation.d.ts.map +1 -1
  241. package/node_modules/@murphai/query/dist/automation.js +7 -8
  242. package/node_modules/@murphai/query/dist/automation.js.map +1 -1
  243. package/node_modules/@murphai/query/dist/entity-families.d.ts +2 -0
  244. package/node_modules/@murphai/query/dist/entity-families.d.ts.map +1 -0
  245. package/node_modules/@murphai/query/dist/entity-families.js +20 -0
  246. package/node_modules/@murphai/query/dist/entity-families.js.map +1 -0
  247. package/node_modules/@murphai/query/dist/health/bank-registry-query-metadata.d.ts +1 -3
  248. package/node_modules/@murphai/query/dist/health/bank-registry-query-metadata.d.ts.map +1 -1
  249. package/node_modules/@murphai/query/dist/health/bank-registry-query-metadata.js +1 -4
  250. package/node_modules/@murphai/query/dist/health/bank-registry-query-metadata.js.map +1 -1
  251. package/node_modules/@murphai/query/dist/health/registries.d.ts +6 -1
  252. package/node_modules/@murphai/query/dist/health/registries.d.ts.map +1 -1
  253. package/node_modules/@murphai/query/dist/health/registries.js.map +1 -1
  254. package/node_modules/@murphai/query/dist/index.d.ts +3 -1
  255. package/node_modules/@murphai/query/dist/index.d.ts.map +1 -1
  256. package/node_modules/@murphai/query/dist/index.js +2 -1
  257. package/node_modules/@murphai/query/dist/index.js.map +1 -1
  258. package/node_modules/@murphai/query/dist/meal-nutrition.d.ts +31 -0
  259. package/node_modules/@murphai/query/dist/meal-nutrition.d.ts.map +1 -0
  260. package/node_modules/@murphai/query/dist/meal-nutrition.js +127 -0
  261. package/node_modules/@murphai/query/dist/meal-nutrition.js.map +1 -0
  262. package/node_modules/@murphai/query/dist/model.d.ts +0 -1
  263. package/node_modules/@murphai/query/dist/model.d.ts.map +1 -1
  264. package/node_modules/@murphai/query/dist/model.js +1 -19
  265. package/node_modules/@murphai/query/dist/model.js.map +1 -1
  266. package/node_modules/@murphai/query/package.json +6 -1
  267. package/node_modules/@murphai/runtime-state/README.md +2 -1
  268. package/node_modules/@murphai/runtime-state/dist/assistant-ids.d.ts +3 -0
  269. package/node_modules/@murphai/runtime-state/dist/assistant-ids.d.ts.map +1 -0
  270. package/node_modules/@murphai/runtime-state/dist/assistant-ids.js +14 -0
  271. package/node_modules/@murphai/runtime-state/dist/assistant-ids.js.map +1 -0
  272. package/node_modules/@murphai/runtime-state/package.json +4 -0
  273. package/node_modules/@murphai/setup-cli/dist/setup-services/operator-defaults.d.ts +27 -0
  274. package/node_modules/@murphai/setup-cli/dist/setup-services/operator-defaults.d.ts.map +1 -0
  275. package/node_modules/@murphai/setup-cli/dist/setup-services/operator-defaults.js +92 -0
  276. package/node_modules/@murphai/setup-cli/dist/setup-services/operator-defaults.js.map +1 -0
  277. package/node_modules/@murphai/setup-cli/dist/setup-services/tool-provisioning.d.ts +29 -0
  278. package/node_modules/@murphai/setup-cli/dist/setup-services/tool-provisioning.d.ts.map +1 -0
  279. package/node_modules/@murphai/setup-cli/dist/setup-services/tool-provisioning.js +306 -0
  280. package/node_modules/@murphai/setup-cli/dist/setup-services/tool-provisioning.js.map +1 -0
  281. package/node_modules/@murphai/setup-cli/dist/setup-services.d.ts.map +1 -1
  282. package/node_modules/@murphai/setup-cli/dist/setup-services.js +20 -405
  283. package/node_modules/@murphai/setup-cli/dist/setup-services.js.map +1 -1
  284. package/node_modules/@murphai/vault-usecases/dist/query-runtime.d.ts +10 -3
  285. package/node_modules/@murphai/vault-usecases/dist/query-runtime.d.ts.map +1 -1
  286. package/node_modules/@murphai/vault-usecases/dist/query-runtime.js +1 -2
  287. package/node_modules/@murphai/vault-usecases/dist/query-runtime.js.map +1 -1
  288. package/node_modules/@murphai/vault-usecases/dist/runtime.d.ts +1 -1
  289. package/node_modules/@murphai/vault-usecases/dist/runtime.d.ts.map +1 -1
  290. package/node_modules/@murphai/vault-usecases/dist/runtime.js +1 -1
  291. package/node_modules/@murphai/vault-usecases/dist/runtime.js.map +1 -1
  292. package/node_modules/@murphai/vault-usecases/dist/usecases/food.d.ts +49 -12
  293. package/node_modules/@murphai/vault-usecases/dist/usecases/food.d.ts.map +1 -1
  294. package/node_modules/@murphai/vault-usecases/dist/usecases/food.js +20 -4
  295. package/node_modules/@murphai/vault-usecases/dist/usecases/food.js.map +1 -1
  296. package/node_modules/@murphai/vault-usecases/dist/usecases/integrated-services.d.ts.map +1 -1
  297. package/node_modules/@murphai/vault-usecases/dist/usecases/integrated-services.js +21 -2
  298. package/node_modules/@murphai/vault-usecases/dist/usecases/integrated-services.js.map +1 -1
  299. package/node_modules/@murphai/vault-usecases/dist/usecases/intervention.d.ts +2 -1
  300. package/node_modules/@murphai/vault-usecases/dist/usecases/intervention.d.ts.map +1 -1
  301. package/node_modules/@murphai/vault-usecases/dist/usecases/intervention.js.map +1 -1
  302. package/node_modules/@murphai/vault-usecases/dist/usecases/types.d.ts +23 -2
  303. package/node_modules/@murphai/vault-usecases/dist/usecases/types.d.ts.map +1 -1
  304. package/node_modules/@murphai/vault-usecases/dist/usecases/workout-measurement.d.ts +2 -2
  305. package/node_modules/@murphai/vault-usecases/dist/usecases/workout-measurement.d.ts.map +1 -1
  306. package/node_modules/@murphai/vault-usecases/dist/usecases/workout-measurement.js.map +1 -1
  307. package/node_modules/@murphai/vault-usecases/dist/usecases/workout.d.ts +2 -2
  308. package/node_modules/@murphai/vault-usecases/dist/usecases/workout.d.ts.map +1 -1
  309. package/node_modules/@murphai/vault-usecases/dist/usecases/workout.js +73 -1
  310. package/node_modules/@murphai/vault-usecases/dist/usecases/workout.js.map +1 -1
  311. package/node_modules/@murphai/vault-usecases/package.json +1 -1
  312. package/package.json +4 -4
  313. package/dist/runner-vault-cli-bin.d.ts +0 -3
  314. package/dist/runner-vault-cli-bin.d.ts.map +0 -1
  315. package/dist/runner-vault-cli-bin.js +0 -8
  316. package/dist/runner-vault-cli-bin.js.map +0 -1
  317. package/dist/runner-vault-cli-command-manifest.d.ts +0 -9
  318. package/dist/runner-vault-cli-command-manifest.d.ts.map +0 -1
  319. package/dist/runner-vault-cli-command-manifest.js +0 -71
  320. package/dist/runner-vault-cli-command-manifest.js.map +0 -1
  321. package/dist/runner-vault-cli.d.ts +0 -10
  322. package/dist/runner-vault-cli.d.ts.map +0 -1
  323. package/dist/runner-vault-cli.js +0 -22
  324. package/dist/runner-vault-cli.js.map +0 -1
  325. package/node_modules/@murphai/core/dist/storage-spine.d.ts +0 -3
  326. package/node_modules/@murphai/core/dist/storage-spine.d.ts.map +0 -1
  327. package/node_modules/@murphai/core/dist/storage-spine.js +0 -3
  328. package/node_modules/@murphai/core/dist/storage-spine.js.map +0 -1
  329. package/node_modules/@murphai/operator-config/dist/assistant/state-ids.d.ts +0 -2
  330. package/node_modules/@murphai/operator-config/dist/assistant/state-ids.d.ts.map +0 -1
  331. package/node_modules/@murphai/operator-config/dist/assistant/state-ids.js +0 -7
  332. package/node_modules/@murphai/operator-config/dist/assistant/state-ids.js.map +0 -1
  333. package/node_modules/@murphai/query/dist/health/health-registry-query-metadata.d.ts +0 -3
  334. package/node_modules/@murphai/query/dist/health/health-registry-query-metadata.d.ts.map +0 -1
  335. package/node_modules/@murphai/query/dist/health/health-registry-query-metadata.js +0 -2
  336. package/node_modules/@murphai/query/dist/health/health-registry-query-metadata.js.map +0 -1
@@ -1,25 +1,11 @@
1
1
  import path from "node:path";
2
2
  import { createHash } from "node:crypto";
3
- import { mkdir, readFile, realpath, rename, stat } from "node:fs/promises";
3
+ import { readFile, realpath, stat } from "node:fs/promises";
4
4
  import { tmpdir } from "node:os";
5
5
  import { assertContract, inboxCaptureRecordSchema, } from "@murphai/contracts";
6
- import { acquireCanonicalWriteLock, applyCanonicalWriteBatch, loadVault, readJsonlRecords, VAULT_LAYOUT, walkVaultFiles, withCanonicalWriteLockScope, } from "@murphai/core";
7
- import { buildAttachmentId, createDeterministicInboxCaptureId, createInboxCaptureIdentityKey, assertVaultPathOnDisk, normalizeStoredAttachments, normalizeAccountKey, normalizeRelativePath, redactSensitivePaths, resolveVaultPath, sanitizeFileName, sanitizeSegment, sha256File, walkNamedFiles, } from "../shared.js";
8
- import { INBOX_CAPTURE_LEDGER_DIRECTORY, buildInboxCaptureAuditPathForStoredAt, buildInboxCaptureAuditRecord, buildInboxCaptureEventPathForOccurredAt, buildInboxCaptureEventRecord, buildInboxCaptureLedgerPath, buildInboxCaptureLedgerPathForOccurredAt, buildInboxCaptureRecord, } from "./persist/canonical-records.js";
9
- const STORED_CAPTURE_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_-]*$/u;
10
- const QUARANTINED_INVALID_CAPTURE_ID_SUFFIX = "quarantined-invalid-capture-id";
11
- class UnsafeStoredCaptureIdError extends Error {
12
- captureId;
13
- canonicalCaptureId;
14
- absolutePath;
15
- constructor(input) {
16
- super(`Stored inbox envelope at ${input.absolutePath} contains unsafe captureId "${input.captureId}".`);
17
- this.name = "UnsafeStoredCaptureIdError";
18
- this.captureId = input.captureId;
19
- this.canonicalCaptureId = input.canonicalCaptureId;
20
- this.absolutePath = input.absolutePath;
21
- }
22
- }
6
+ import { acquireCanonicalWriteLock, applyCanonicalWriteBatch, loadVault, listWriteOperationMetadataPaths, readJsonlRecords, readStoredWriteOperation, VAULT_LAYOUT, walkVaultFiles, withCanonicalWriteLockScope, } from "@murphai/core";
7
+ import { buildAttachmentId, createDeterministicInboxCaptureId, createInboxCaptureIdentityKey, normalizeStoredAttachments, normalizeAccountKey, normalizeRelativePath, redactSensitivePaths, resolveVaultPath, sanitizeFileName, sanitizeSegment, sha256File, } from "../shared.js";
8
+ import { INBOX_CAPTURE_LEDGER_DIRECTORY, buildInboxCaptureLedgerPathForOccurredAt, buildInboxCaptureRecord, } from "./persist/canonical-records.js";
23
9
  export async function ensureInboxVault(vaultRoot) {
24
10
  await loadVault({ vaultRoot });
25
11
  }
@@ -204,23 +190,6 @@ async function prepareRawCapturePersistence({ captureId, eventId, input, storedA
204
190
  rawContents,
205
191
  };
206
192
  }
207
- export async function persistRawCapture({ vaultRoot, captureId, eventId, input, storedAt = new Date().toISOString(), }) {
208
- const prepared = await prepareRawCapturePersistence({
209
- captureId,
210
- eventId,
211
- input,
212
- storedAt,
213
- });
214
- await applyCanonicalWriteBatch({
215
- vaultRoot,
216
- operationType: "inbox_capture_raw_persist",
217
- summary: `Persist inbox capture ${captureId}`,
218
- occurredAt: prepared.stored.storedAt,
219
- rawCopies: prepared.rawCopies,
220
- rawContents: prepared.rawContents,
221
- });
222
- return prepared.stored;
223
- }
224
193
  export async function persistCanonicalInboxCapture({ vaultRoot, captureId, eventId, input, storedAt = new Date().toISOString(), }) {
225
194
  const prepared = await prepareRawCapturePersistence({
226
195
  captureId,
@@ -266,37 +235,29 @@ export async function findStoredCaptureEnvelope(input) {
266
235
  if (storedRecord) {
267
236
  return inboxCaptureRecordToStoredCaptureEnvelope(storedRecord);
268
237
  }
269
- const expectedPath = await resolveVaultPath(input.vaultRoot, buildInboxEnvelopePath(input.inbound, captureId));
270
- const expectedEnvelope = await readStoredCaptureEnvelope(expectedPath);
271
- if (expectedEnvelope) {
272
- return expectedEnvelope;
238
+ const expectedEnvelopePath = buildInboxEnvelopePath(input.inbound, captureId);
239
+ const expectedCapturePath = buildInboxCaptureLedgerPathForOccurredAt(input.inbound.occurredAt);
240
+ const recoverableOperations = await listRecoverableInboxCaptureOperations(input.vaultRoot);
241
+ const recoverableOperation = recoverableOperations.get(expectedEnvelopePath);
242
+ if (!recoverableOperation || recoverableOperation.capturePath !== expectedCapturePath) {
243
+ return null;
273
244
  }
274
- const accountRoot = await resolveVaultPath(input.vaultRoot, buildInboxAccountDirectory(input.inbound));
275
- const envelopeFiles = await walkInboxEnvelopeFiles(accountRoot);
276
- let selected = null;
277
- const identityKey = createInboxCaptureIdentityKey(input.inbound);
278
- for (const envelopePath of envelopeFiles) {
279
- const envelope = await readStoredCaptureEnvelope(envelopePath);
280
- if (!envelope || createInboxCaptureIdentityKey(envelope.input) !== identityKey) {
281
- continue;
282
- }
283
- const entry = { absolutePath: envelopePath, envelope };
284
- if (!selected || compareEnvelopeEntries(entry, selected) < 0) {
285
- selected = entry;
286
- }
287
- }
288
- return selected?.envelope ?? null;
245
+ return await readStoredCaptureEnvelope({
246
+ vaultRoot: input.vaultRoot,
247
+ relativePath: expectedEnvelopePath,
248
+ });
289
249
  }
290
250
  export async function ensureStoredCaptureCanonicalEvidence(input) {
291
- const capturePath = buildInboxCaptureLedgerPath(input.envelope);
251
+ const relativePath = buildInboxCaptureLedgerPathForOccurredAt(input.envelope.input.occurredAt);
292
252
  await withCanonicalWriteLockScope(input.vaultRoot, async () => {
293
253
  const lock = await acquireCanonicalWriteLock(input.vaultRoot);
294
254
  try {
295
- const captureRecords = await readInboxCaptureRecordsIfPresent({
255
+ const records = await readInboxCaptureRecordsIfPresent({
296
256
  vaultRoot: input.vaultRoot,
297
- relativePath: capturePath,
257
+ relativePath,
298
258
  });
299
- if (findMatchingInboxCaptureRecord(captureRecords, input.envelope)) {
259
+ const identityKey = createInboxCaptureIdentityKey(input.envelope.input);
260
+ if (selectMatchingInboxCaptureRecord(records, identityKey, input.envelope.captureId)) {
300
261
  return;
301
262
  }
302
263
  await applyCanonicalWriteBatch({
@@ -306,7 +267,7 @@ export async function ensureStoredCaptureCanonicalEvidence(input) {
306
267
  occurredAt: input.envelope.stored.storedAt,
307
268
  jsonlAppends: [
308
269
  {
309
- relativePath: capturePath,
270
+ relativePath,
310
271
  record: buildInboxCaptureRecord({
311
272
  eventId: input.envelope.eventId,
312
273
  inbound: input.envelope.input,
@@ -321,53 +282,6 @@ export async function ensureStoredCaptureCanonicalEvidence(input) {
321
282
  }
322
283
  });
323
284
  }
324
- export async function appendInboxCaptureEvent(input) {
325
- const vault = await loadVault({ vaultRoot: input.vaultRoot });
326
- const relativePath = buildInboxCaptureEventPathForOccurredAt(input.occurredAt);
327
- const record = buildInboxCaptureEventRecord({
328
- eventId: input.eventId,
329
- inbound: input.inbound,
330
- stored: input.stored,
331
- timeZone: vault.metadata.timezone,
332
- });
333
- await applyCanonicalWriteBatch({
334
- vaultRoot: input.vaultRoot,
335
- operationType: "inbox_capture_event_append",
336
- summary: `Append inbox capture event ${input.eventId}`,
337
- occurredAt: input.stored.storedAt,
338
- jsonlAppends: [
339
- {
340
- relativePath,
341
- record,
342
- },
343
- ],
344
- });
345
- return { relativePath, record };
346
- }
347
- export async function appendImportAudit(input) {
348
- const relativePath = buildInboxCaptureAuditPathForStoredAt(input.stored.storedAt);
349
- const record = buildInboxCaptureAuditRecord({
350
- auditId: input.auditId,
351
- eventId: input.eventId,
352
- inbound: input.inbound,
353
- stored: input.stored,
354
- capturePath: input.capturePath,
355
- eventPath: input.eventPath,
356
- });
357
- await applyCanonicalWriteBatch({
358
- vaultRoot: input.vaultRoot,
359
- operationType: "inbox_capture_audit_append",
360
- summary: `Append inbox capture audit ${input.auditId}`,
361
- occurredAt: input.stored.storedAt,
362
- jsonlAppends: [
363
- {
364
- relativePath,
365
- record,
366
- },
367
- ],
368
- });
369
- return { relativePath, record };
370
- }
371
285
  export async function rebuildRuntimeFromVault(input) {
372
286
  const canonicalRecords = await listCanonicalInboxCaptureRecords(input.vaultRoot);
373
287
  const restoredIdentityKeys = new Set();
@@ -385,47 +299,24 @@ export async function rebuildRuntimeFromVault(input) {
385
299
  });
386
300
  restoredIdentityKeys.add(record.identityKey);
387
301
  }
388
- const inboxRoot = await resolveVaultPath(input.vaultRoot, VAULT_LAYOUT.rawInboxDirectory);
389
- try {
390
- await mkdir(inboxRoot, { recursive: true });
391
- }
392
- catch {
393
- return;
394
- }
395
- await assertVaultPathOnDisk(input.vaultRoot, inboxRoot);
396
- const envelopeFiles = await walkInboxEnvelopeFiles(inboxRoot);
397
- const canonicalEntries = new Map();
398
- for (const envelopePath of envelopeFiles) {
399
- const envelope = await readStoredCaptureEnvelope(envelopePath);
400
- if (!envelope) {
401
- continue;
402
- }
403
- const identityKey = createInboxCaptureIdentityKey(envelope.input);
404
- if (restoredIdentityKeys.has(identityKey)) {
405
- continue;
406
- }
407
- const entry = { absolutePath: envelopePath, envelope };
408
- const current = canonicalEntries.get(identityKey);
409
- if (!current || compareEnvelopeEntries(entry, current) < 0) {
410
- canonicalEntries.set(identityKey, entry);
411
- }
412
- }
413
- for (const entry of [...canonicalEntries.values()].sort(compareEnvelopeEntries)) {
302
+ const recoverableOperations = await listRecoverableInboxCaptureOperations(input.vaultRoot);
303
+ const recoveredEnvelopes = await listRecoverableRawCaptureEnvelopes(input.vaultRoot, restoredIdentityKeys, recoverableOperations);
304
+ for (const envelope of recoveredEnvelopes) {
414
305
  await ensureStoredCaptureCanonicalEvidence({
415
306
  vaultRoot: input.vaultRoot,
416
- envelope: entry.envelope,
307
+ envelope,
417
308
  });
418
309
  const captureId = input.runtime.upsertCaptureIndex({
419
- captureId: entry.envelope.captureId,
420
- eventId: entry.envelope.eventId,
421
- input: entry.envelope.input,
422
- stored: entry.envelope.stored,
310
+ captureId: envelope.captureId,
311
+ eventId: envelope.eventId,
312
+ input: envelope.input,
313
+ stored: envelope.stored,
423
314
  });
424
315
  input.runtime.enqueueDerivedJobs({
425
316
  captureId,
426
- stored: entry.envelope.stored,
317
+ stored: envelope.stored,
427
318
  });
428
- restoredIdentityKeys.add(createInboxCaptureIdentityKey(entry.envelope.input));
319
+ restoredIdentityKeys.add(createInboxCaptureIdentityKey(envelope.input));
429
320
  }
430
321
  }
431
322
  function buildInboxAccountDirectory(input) {
@@ -439,71 +330,78 @@ function buildInboxCaptureDirectory(input, captureId) {
439
330
  function buildInboxEnvelopePath(input, captureId) {
440
331
  return normalizeRelativePath(path.posix.join(buildInboxCaptureDirectory(input, captureId), "envelope.json"));
441
332
  }
442
- async function walkInboxEnvelopeFiles(directory) {
333
+ async function readStoredCaptureEnvelope(input) {
334
+ const absolutePath = await resolveVaultPath(input.vaultRoot, input.relativePath);
443
335
  try {
444
- return (await walkNamedFiles(directory, "envelope.json", { skipDirectories: ["attachments"] })).sort();
336
+ return normalizeStoredCaptureEnvelope(JSON.parse(await readFile(absolutePath, "utf8")), input.relativePath);
445
337
  }
446
338
  catch (error) {
447
339
  if (isMissingFileError(error)) {
448
- return [];
340
+ return null;
449
341
  }
450
342
  throw error;
451
343
  }
452
344
  }
453
- async function readStoredCaptureEnvelope(absolutePath) {
454
- try {
455
- return normalizeStoredCaptureEnvelope(JSON.parse(await readFile(absolutePath, "utf8")), absolutePath);
345
+ function normalizeStoredCaptureEnvelope(value, relativePath) {
346
+ const context = `stored inbox envelope at ${relativePath}`;
347
+ const envelope = expectRecord(value, context);
348
+ if (envelope.schema !== "murph.inbox-envelope.v1") {
349
+ throw new TypeError(`Expected canonical "schema" in ${context}.`);
456
350
  }
457
- catch (error) {
458
- if (isMissingFileError(error)) {
459
- return null;
460
- }
461
- if (error instanceof UnsafeStoredCaptureIdError) {
462
- await quarantineStoredCaptureEnvelope(absolutePath);
463
- return null;
464
- }
465
- throw error;
351
+ const inbound = buildSanitizedInboundCapture(normalizeStoredCaptureInboundInput(envelope.input, `${context}.input`));
352
+ const captureId = createDeterministicInboxCaptureId(inbound);
353
+ const eventId = requireStringField(envelope, "eventId", context);
354
+ const storedAt = requireStringField(envelope, "storedAt", context);
355
+ if (requireStringField(envelope, "captureId", context) !== captureId) {
356
+ throw new TypeError(`Stored inbox envelope at ${relativePath} must use the deterministic captureId.`);
466
357
  }
467
- }
468
- function normalizeStoredCaptureEnvelope(envelope, absolutePath) {
469
- if (!envelope || typeof envelope !== "object") {
470
- throw new TypeError(`Expected stored inbox envelope object at ${absolutePath}.`);
358
+ const storedRecord = expectRecord(envelope.stored, `${context}.stored`);
359
+ const sourceDirectory = requireStringField(storedRecord, "sourceDirectory", `${context}.stored`);
360
+ const envelopePath = requireStringField(storedRecord, "envelopePath", `${context}.stored`);
361
+ const attachmentsValue = storedRecord.attachments;
362
+ if (!Array.isArray(attachmentsValue)) {
363
+ throw new TypeError(`Expected canonical "attachments" array in ${context}.stored.`);
471
364
  }
472
- if (!envelope.stored || typeof envelope.stored !== "object") {
473
- throw new TypeError(`Missing canonical "stored" payload in stored inbox envelope at ${absolutePath}.`);
365
+ if (requireStringField(storedRecord, "captureId", `${context}.stored`) !== captureId) {
366
+ throw new TypeError(`Stored inbox envelope at ${relativePath} has a mismatched stored.captureId.`);
474
367
  }
475
- if (!envelope.input || typeof envelope.input !== "object") {
476
- throw new TypeError(`Missing canonical "input" payload in stored inbox envelope at ${absolutePath}.`);
368
+ if (requireStringField(storedRecord, "eventId", `${context}.stored`) !== eventId) {
369
+ throw new TypeError(`Stored inbox envelope at ${relativePath} has a mismatched stored.eventId.`);
477
370
  }
478
- if (typeof envelope.input.source !== "string" || envelope.input.source.trim().length === 0) {
479
- throw new TypeError(`Missing canonical "input.source" in stored inbox envelope at ${absolutePath}.`);
371
+ if (requireStringField(storedRecord, "storedAt", `${context}.stored`) !== storedAt) {
372
+ throw new TypeError(`Stored inbox envelope at ${relativePath} has a mismatched stored.storedAt.`);
480
373
  }
481
- if (typeof envelope.input.externalId !== "string" || envelope.input.externalId.trim().length === 0) {
482
- throw new TypeError(`Missing canonical "input.externalId" in stored inbox envelope at ${absolutePath}.`);
374
+ const expectedSourceDirectory = buildInboxCaptureDirectory(inbound, captureId);
375
+ if (sourceDirectory !== expectedSourceDirectory) {
376
+ throw new TypeError(`Stored inbox envelope at ${relativePath} has a mismatched stored.sourceDirectory.`);
483
377
  }
484
- if (!Array.isArray(envelope.stored.attachments)) {
485
- throw new TypeError(`Missing canonical "stored.attachments" array in stored inbox envelope at ${absolutePath}.`);
378
+ const expectedEnvelopePath = buildInboxEnvelopePath(inbound, captureId);
379
+ if (envelopePath !== expectedEnvelopePath) {
380
+ throw new TypeError(`Stored inbox envelope at ${relativePath} has a mismatched stored.envelopePath.`);
486
381
  }
487
- const canonicalCaptureId = createDeterministicInboxCaptureId(envelope.input);
488
- const captureId = normalizeStoredCaptureId({
489
- captureId: envelope.captureId,
490
- canonicalCaptureId,
491
- absolutePath,
382
+ const attachments = normalizeStoredAttachments(captureId, attachmentsValue, `${context}.stored.attachments`).map((attachment) => {
383
+ const expectedAttachmentId = buildAttachmentId(captureId, attachment.ordinal);
384
+ if (attachment.attachmentId !== expectedAttachmentId) {
385
+ throw new TypeError(`Stored inbox envelope at ${relativePath} has a mismatched attachmentId for ordinal ${attachment.ordinal}.`);
386
+ }
387
+ return {
388
+ ...attachment,
389
+ attachmentId: expectedAttachmentId,
390
+ originalPath: null,
391
+ };
492
392
  });
493
- return {
494
- ...envelope,
495
- captureId,
393
+ return inboxCaptureRecordToStoredCaptureEnvelope(buildInboxCaptureRecord({
394
+ eventId,
395
+ inbound,
496
396
  stored: {
497
- ...envelope.stored,
498
397
  captureId,
499
- eventId: envelope.eventId,
500
- attachments: normalizeStoredAttachmentsForCaptureId({
501
- captureId,
502
- attachments: envelope.stored.attachments,
503
- absolutePath,
504
- }),
398
+ eventId,
399
+ storedAt,
400
+ sourceDirectory,
401
+ envelopePath,
402
+ attachments,
505
403
  },
506
- };
404
+ }));
507
405
  }
508
406
  async function readJsonlRecordsIfPresent(input) {
509
407
  try {
@@ -518,24 +416,80 @@ async function readJsonlRecordsIfPresent(input) {
518
416
  throw error;
519
417
  }
520
418
  }
521
- function compareEnvelopeEntries(left, right) {
522
- const idComparison = comparePreferenceScore(left) - comparePreferenceScore(right);
523
- if (idComparison !== 0) {
524
- return idComparison;
419
+ async function listRecoverableRawCaptureEnvelopes(vaultRoot, restoredIdentityKeys, recoverableOperations) {
420
+ const selectedByIdentityKey = new Map();
421
+ for (const relativePath of [...recoverableOperations.keys()].sort()) {
422
+ const envelope = await readStoredCaptureEnvelope({ vaultRoot, relativePath });
423
+ if (!envelope) {
424
+ continue;
425
+ }
426
+ const identityKey = createInboxCaptureIdentityKey(envelope.input);
427
+ if (restoredIdentityKeys.has(identityKey)) {
428
+ continue;
429
+ }
430
+ const current = selectedByIdentityKey.get(identityKey);
431
+ const candidate = { relativePath, envelope };
432
+ if (!current || compareEnvelopeEntries(candidate, current) < 0) {
433
+ selectedByIdentityKey.set(identityKey, candidate);
434
+ }
525
435
  }
436
+ return [...selectedByIdentityKey.values()].sort(compareEnvelopeEntries).map((entry) => entry.envelope);
437
+ }
438
+ async function listRecoverableInboxCaptureOperations(vaultRoot) {
439
+ const relativePaths = await listWriteOperationMetadataPaths(vaultRoot);
440
+ const selected = new Map();
441
+ for (const relativePath of relativePaths) {
442
+ let operation;
443
+ try {
444
+ operation = await readStoredWriteOperation(vaultRoot, relativePath);
445
+ }
446
+ catch {
447
+ continue;
448
+ }
449
+ const recoverable = selectRecoverableInboxCaptureOperation(operation);
450
+ if (!recoverable) {
451
+ continue;
452
+ }
453
+ const current = selected.get(recoverable.envelopePath);
454
+ if (!current || current.updatedAt.localeCompare(recoverable.updatedAt) < 0) {
455
+ selected.set(recoverable.envelopePath, recoverable);
456
+ }
457
+ }
458
+ return selected;
459
+ }
460
+ function selectRecoverableInboxCaptureOperation(operation) {
461
+ if (operation.operationType !== "inbox_capture_persist") {
462
+ return null;
463
+ }
464
+ if (operation.status === "committed" || operation.status === "rolled_back") {
465
+ return null;
466
+ }
467
+ const envelopeAction = operation.actions.find((action) => action.kind === "raw_copy" &&
468
+ action.targetRelativePath.startsWith(`${VAULT_LAYOUT.rawInboxDirectory}/`) &&
469
+ action.targetRelativePath.endsWith("/envelope.json") &&
470
+ (action.state === "applied" || action.state === "reused"));
471
+ const captureAction = operation.actions.find((action) => action.kind === "jsonl_append" &&
472
+ action.targetRelativePath.startsWith(`${INBOX_CAPTURE_LEDGER_DIRECTORY}/`) &&
473
+ action.state === "staged");
474
+ if (!envelopeAction || !captureAction) {
475
+ return null;
476
+ }
477
+ return {
478
+ envelopePath: envelopeAction.targetRelativePath,
479
+ capturePath: captureAction.targetRelativePath,
480
+ updatedAt: operation.updatedAt,
481
+ };
482
+ }
483
+ function compareEnvelopeEntries(left, right) {
526
484
  const storedAtComparison = left.envelope.stored.storedAt.localeCompare(right.envelope.stored.storedAt);
527
485
  if (storedAtComparison !== 0) {
528
486
  return storedAtComparison;
529
487
  }
530
- const captureComparison = left.envelope.captureId.localeCompare(right.envelope.captureId);
531
- if (captureComparison !== 0) {
532
- return captureComparison;
488
+ const captureIdComparison = left.envelope.captureId.localeCompare(right.envelope.captureId);
489
+ if (captureIdComparison !== 0) {
490
+ return captureIdComparison;
533
491
  }
534
- return left.absolutePath.localeCompare(right.absolutePath);
535
- }
536
- function comparePreferenceScore(entry) {
537
- const canonicalCaptureId = createDeterministicInboxCaptureId(entry.envelope.input);
538
- return path.basename(path.dirname(entry.absolutePath)) === canonicalCaptureId ? 0 : 1;
492
+ return left.relativePath.localeCompare(right.relativePath);
539
493
  }
540
494
  function inboxCaptureRecordToStoredCaptureEnvelope(record) {
541
495
  const input = {
@@ -666,10 +620,6 @@ function compareInboxCaptureRecords(left, right) {
666
620
  }
667
621
  return left.envelopePath.localeCompare(right.envelopePath);
668
622
  }
669
- function findMatchingInboxCaptureRecord(records, envelope) {
670
- const identityKey = createInboxCaptureIdentityKey(envelope.input);
671
- return selectMatchingInboxCaptureRecord(records, identityKey, envelope.captureId);
672
- }
673
623
  function stripEphemeralAttachmentFields(attachment) {
674
624
  const { data, ...sanitized } = attachment;
675
625
  return sanitized;
@@ -684,55 +634,109 @@ function buildUnstoredAttachment(input) {
684
634
  sha256: null,
685
635
  };
686
636
  }
687
- function normalizeStoredCaptureId(input) {
688
- const captureId = typeof input.captureId === "string" ? input.captureId.trim() : "";
689
- if (!captureId) {
690
- throw new TypeError(`Missing canonical "captureId" in stored inbox envelope at ${input.absolutePath}.`);
637
+ function normalizeStoredCaptureInboundInput(value, context) {
638
+ const input = expectRecord(value, context);
639
+ const thread = expectRecord(input.thread, `${context}.thread`);
640
+ const actor = expectRecord(input.actor, `${context}.actor`);
641
+ const raw = expectRecord(input.raw, `${context}.raw`);
642
+ const attachmentsValue = input.attachments;
643
+ if (!Array.isArray(attachmentsValue)) {
644
+ throw new TypeError(`Expected canonical "attachments" array in ${context}.`);
691
645
  }
692
- if (!STORED_CAPTURE_ID_PATTERN.test(captureId)) {
693
- throw new UnsafeStoredCaptureIdError({
694
- captureId,
695
- canonicalCaptureId: input.canonicalCaptureId,
696
- absolutePath: input.absolutePath,
697
- });
646
+ return {
647
+ source: requireStringField(input, "source", context),
648
+ externalId: requireStringField(input, "externalId", context),
649
+ accountId: readOptionalNullableStringField(input, "accountId", context),
650
+ thread: {
651
+ id: requireStringField(thread, "id", `${context}.thread`),
652
+ title: readOptionalNullableStringField(thread, "title", `${context}.thread`),
653
+ isDirect: readOptionalBooleanField(thread, "isDirect", `${context}.thread`),
654
+ },
655
+ actor: {
656
+ id: readOptionalNullableStringField(actor, "id", `${context}.actor`),
657
+ displayName: readOptionalNullableStringField(actor, "displayName", `${context}.actor`),
658
+ isSelf: requireBooleanField(actor, "isSelf", `${context}.actor`),
659
+ },
660
+ occurredAt: requireStringField(input, "occurredAt", context),
661
+ receivedAt: readOptionalNullableStringField(input, "receivedAt", context),
662
+ text: readOptionalNullableStringField(input, "text", context) ?? null,
663
+ attachments: attachmentsValue.map((attachment, index) => normalizeStoredCaptureInboundAttachment(attachment, `${context}.attachments[${index}]`)),
664
+ raw,
665
+ };
666
+ }
667
+ function normalizeStoredCaptureInboundAttachment(value, context) {
668
+ const attachment = expectRecord(value, context);
669
+ const kind = requireStringField(attachment, "kind", context);
670
+ if (!isInboundAttachmentKind(kind)) {
671
+ throw new TypeError(`Unsupported canonical attachment kind "${kind}" in ${context}.`);
698
672
  }
699
- return input.canonicalCaptureId;
673
+ return {
674
+ externalId: readOptionalNullableStringField(attachment, "externalId", context),
675
+ kind,
676
+ mime: readOptionalNullableStringField(attachment, "mime", context),
677
+ originalPath: null,
678
+ fileName: readOptionalNullableStringField(attachment, "fileName", context),
679
+ byteSize: readOptionalNullableNumberField(attachment, "byteSize", context),
680
+ };
700
681
  }
701
- function normalizeStoredAttachmentsForCaptureId(input) {
702
- const normalizedAttachments = normalizeStoredAttachments(input.captureId, input.attachments, `stored inbox envelope at ${input.absolutePath}`);
703
- return normalizedAttachments.map((attachment) => ({
704
- ...attachment,
705
- attachmentId: buildAttachmentId(input.captureId, attachment.ordinal),
706
- }));
682
+ function expectRecord(value, context) {
683
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
684
+ throw new TypeError(`Expected object in ${context}.`);
685
+ }
686
+ return value;
707
687
  }
708
- async function quarantineStoredCaptureEnvelope(absolutePath) {
709
- const quarantinePath = await resolveQuarantinedEnvelopePath(absolutePath);
710
- try {
711
- await rename(absolutePath, quarantinePath);
688
+ function requireStringField(value, field, context) {
689
+ const fieldValue = value[field];
690
+ if (typeof fieldValue !== "string" || fieldValue.trim().length === 0) {
691
+ throw new TypeError(`Expected canonical "${field}" string in ${context}.`);
712
692
  }
713
- catch (error) {
714
- if (isMissingFileError(error)) {
715
- return;
716
- }
717
- throw error;
693
+ return fieldValue;
694
+ }
695
+ function requireBooleanField(value, field, context) {
696
+ const fieldValue = value[field];
697
+ if (typeof fieldValue !== "boolean") {
698
+ throw new TypeError(`Expected canonical "${field}" boolean in ${context}.`);
718
699
  }
700
+ return fieldValue;
719
701
  }
720
- async function resolveQuarantinedEnvelopePath(absolutePath) {
721
- const parsed = path.parse(absolutePath);
722
- for (let index = 0; index < 1000; index += 1) {
723
- const suffix = index === 0 ? "" : `-${index}`;
724
- const candidate = path.join(parsed.dir, `${parsed.name}.${QUARANTINED_INVALID_CAPTURE_ID_SUFFIX}${suffix}${parsed.ext}`);
725
- try {
726
- await stat(candidate);
727
- }
728
- catch (error) {
729
- if (isMissingFileError(error)) {
730
- return candidate;
731
- }
732
- throw error;
733
- }
702
+ function readOptionalBooleanField(value, field, context) {
703
+ const fieldValue = value[field];
704
+ if (fieldValue === undefined) {
705
+ return undefined;
706
+ }
707
+ if (typeof fieldValue !== "boolean") {
708
+ throw new TypeError(`Expected canonical "${field}" boolean in ${context}.`);
734
709
  }
735
- throw new TypeError(`Unable to quarantine stored inbox envelope at ${absolutePath}.`);
710
+ return fieldValue;
711
+ }
712
+ function readOptionalNullableStringField(value, field, context) {
713
+ const fieldValue = value[field];
714
+ if (fieldValue === undefined) {
715
+ return undefined;
716
+ }
717
+ if (fieldValue === null) {
718
+ return null;
719
+ }
720
+ if (typeof fieldValue !== "string") {
721
+ throw new TypeError(`Expected canonical "${field}" string in ${context}.`);
722
+ }
723
+ return fieldValue;
724
+ }
725
+ function readOptionalNullableNumberField(value, field, context) {
726
+ const fieldValue = value[field];
727
+ if (fieldValue === undefined) {
728
+ return undefined;
729
+ }
730
+ if (fieldValue === null) {
731
+ return null;
732
+ }
733
+ if (typeof fieldValue !== "number" || !Number.isFinite(fieldValue)) {
734
+ throw new TypeError(`Expected canonical "${field}" number in ${context}.`);
735
+ }
736
+ return fieldValue;
737
+ }
738
+ function isInboundAttachmentKind(value) {
739
+ return ["image", "audio", "video", "document", "other"].includes(value);
736
740
  }
737
741
  function isMissingFileError(error) {
738
742
  return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";