@memorax/memorax-code 0.1.2 → 0.1.3

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 (242) hide show
  1. package/README.md +16 -12
  2. package/bin/memorax-code-npm-preinstall.mjs +7 -2
  3. package/bin/memorax-code-opencode.mjs +4 -0
  4. package/bin/memorax-code-plugin-postinstall.mjs +342 -93
  5. package/docs/configuration.md +144 -35
  6. package/docs/troubleshooting.md +73 -13
  7. package/lib/dsh-plugin-install.mjs +22 -0
  8. package/lib/memorax-code-adapter-common/src/hooks/capture-cwd-hook.mjs +21 -14
  9. package/lib/memorax-code-adapter-common/src/hooks/ensure-backend-runner.mjs +26 -7
  10. package/lib/memorax-code-adapter-common/src/hooks/memory-skill-reminder-hook.mjs +86 -95
  11. package/lib/memorax-code-adapter-common/src/hooks/memory-skill-reminder-policy.mjs +58 -0
  12. package/lib/memorax-code-adapter-common/src/repo-memory/repo-memory-auto-build.mjs +2 -2
  13. package/lib/memorax-code-adapter-common/src/repo-memory/repo-memory-job-supervisor.mjs +1 -1
  14. package/lib/memorax-code-adapter-common/src/windows-cli-invocation.mjs +13 -1
  15. package/lib/memorax-code-backend/dist/app/backend-server.js +210 -0
  16. package/lib/memorax-code-backend/dist/{server-observability.js → app/memory-observability.js} +4 -4
  17. package/lib/memorax-code-backend/dist/{backend-state.js → app/state.js} +1 -1
  18. package/lib/memorax-code-backend/dist/{claude-adapter-lifecycle.js → clients/claude/lifecycle.js} +2 -2
  19. package/lib/memorax-code-backend/dist/{claude-memory-hook-runtime.js → clients/claude/memory-hook-runtime.js} +7 -7
  20. package/lib/memorax-code-backend/dist/clients/codex/lifecycle.js +131 -0
  21. package/lib/memorax-code-backend/dist/{codex-memory-hook-runtime.js → clients/codex/memory-hook-runtime.js} +9 -9
  22. package/lib/memorax-code-backend/dist/{codex-plugin-hooks.js → clients/codex/plugin-hooks.js} +1 -1
  23. package/lib/memorax-code-backend/dist/{codex-plugin-install.js → clients/codex/plugin-install.js} +6 -6
  24. package/lib/memorax-code-backend/dist/clients/dsh/lifecycle.js +75 -0
  25. package/lib/memorax-code-backend/dist/clients/dsh/memory-hook-runtime.js +258 -0
  26. package/lib/memorax-code-backend/dist/clients/dsh/session-turn.js +249 -0
  27. package/lib/memorax-code-backend/dist/clients/opencode/lifecycle.js +54 -0
  28. package/lib/memorax-code-backend/dist/clients/opencode/memory-hook-runtime.js +277 -0
  29. package/lib/memorax-code-backend/dist/clients/opencode/message-turn.js +78 -0
  30. package/lib/memorax-code-backend/dist/codex-adapter-lifecycle.js +1 -131
  31. package/lib/memorax-code-backend/dist/{memorax-code-config.js → config/memorax-code.js} +32 -4
  32. package/lib/memorax-code-backend/dist/{server-cli.js → entrypoints/backend-cli.js} +137 -37
  33. package/lib/memorax-code-backend/dist/jsonl-append.js +1 -75
  34. package/lib/memorax-code-backend/dist/{active-client-selection.js → lifecycle/active-clients.js} +12 -1
  35. package/lib/memorax-code-backend/dist/{backend-service-cleanup.js → lifecycle/backend/cleanup.js} +1 -1
  36. package/lib/memorax-code-backend/dist/{backend-service-record.js → lifecycle/backend/record.js} +1 -1
  37. package/lib/memorax-code-backend/dist/{backend-service-result.js → lifecycle/backend/result.js} +2 -2
  38. package/lib/memorax-code-backend/dist/{service.js → lifecycle/backend/service.js} +16 -16
  39. package/lib/memorax-code-backend/dist/{backend-token-record.js → lifecycle/backend/token-record.js} +1 -1
  40. package/lib/memorax-code-backend/dist/{backend-service-token.js → lifecycle/backend/token.js} +2 -2
  41. package/lib/memorax-code-backend/dist/lifecycle/client-plugin-removal.js +109 -0
  42. package/lib/memorax-code-backend/dist/{client-selection.js → lifecycle/client-selection.js} +11 -5
  43. package/lib/memorax-code-backend/dist/{backend-lifecycle-lock.js → lifecycle/lock.js} +1 -1
  44. package/lib/memorax-code-backend/dist/{memorax-code-lifecycle.js → lifecycle/orchestrator.js} +325 -39
  45. package/lib/memorax-code-backend/dist/memorax-cli.js +1 -1
  46. package/lib/memorax-code-backend/dist/memorax-code.js +1 -1
  47. package/lib/memorax-code-backend/dist/{automatic-memory-retrieval.js → memory/automatic-retrieval.js} +3 -3
  48. package/lib/memorax-code-backend/dist/{automatic-memory-writeback.js → memory/automatic-writeback.js} +75 -21
  49. package/lib/memorax-code-backend/dist/{memory-cli.js → memory/cli.js} +23 -10
  50. package/lib/memorax-code-backend/dist/{memory-hook-command.js → memory/hook-command.js} +156 -9
  51. package/lib/memorax-code-backend/dist/memory/observability.js +1 -0
  52. package/lib/memorax-code-backend/dist/memory/payload-redaction.js +212 -0
  53. package/lib/memorax-code-backend/dist/{memory-reminder-trace-recorder.js → memory/reminder-trace-recorder.js} +20 -7
  54. package/lib/memorax-code-backend/dist/{repository-memory-context.js → memory/repository-session.js} +2 -2
  55. package/lib/memorax-code-backend/dist/{memory-service.js → memory/service.js} +27 -5
  56. package/lib/memorax-code-backend/dist/{memory-turn-coordinator.js → memory/turn-coordinator.js} +2 -1
  57. package/lib/memorax-code-backend/dist/{memory-writeback-buffer.js → memory/writeback-buffer.js} +3 -3
  58. package/lib/memorax-code-backend/dist/{memory-writeback-chunk.js → memory/writeback-chunk.js} +1 -1
  59. package/lib/memorax-code-backend/dist/{memory-writeback-reconciler.js → memory/writeback-reconciler.js} +6 -6
  60. package/lib/memorax-code-backend/dist/{memory-writeback-task-projection.js → memory/writeback-task-projection.js} +4 -4
  61. package/lib/memorax-code-backend/dist/{memorax-adapter.js → provider/memorax/adapter.js} +5 -5
  62. package/lib/memorax-code-backend/dist/{memorax-config.js → provider/memorax/config.js} +4 -4
  63. package/lib/memorax-code-backend/dist/{memorax-http.js → provider/memorax/http.js} +1 -1
  64. package/lib/memorax-code-backend/dist/{repo-memory-readiness.js → repository/readiness.js} +3 -3
  65. package/lib/memorax-code-backend/dist/server.js +3 -212
  66. package/lib/memorax-code-backend/dist/service-entrypoint.js +1 -1
  67. package/lib/memorax-code-backend/dist/{debug-log.js → shared/debug-log.js} +1 -1
  68. package/lib/memorax-code-backend/dist/shared/jsonl-append.js +75 -0
  69. package/lib/memorax-code-backend/dist/shared/windows-cli-invocation.js +148 -0
  70. package/lib/memorax-code-backend/dist/{trace-config.js → trace/config.js} +43 -5
  71. package/lib/memorax-code-backend/dist/{trace-context.js → trace/context.js} +53 -2
  72. package/lib/memorax-code-backend/dist/{trace-store.js → trace/store.js} +3 -3
  73. package/lib/memorax-code-backend/dist/{server-health.js → transport/http/health.js} +1 -1
  74. package/lib/memorax-code-backend/dist/{server-memory-hook.js → transport/http/memory-hook.js} +3 -3
  75. package/lib/memorax-code-backend/dist/{server-http.js → transport/http/request.js} +1 -1
  76. package/lib/memorax-code-backend/dist/{claude-local-transcript.js → viewer/history/claude-transcript.js} +3 -3
  77. package/lib/memorax-code-backend/dist/{memory-viewer-session-title.js → viewer/history/session-title.js} +1 -1
  78. package/lib/memorax-code-backend/dist/{server-memory-viewer.js → viewer/http/public-routes.js} +15 -15
  79. package/lib/memorax-code-backend/dist/viewer/model.js +1 -0
  80. package/lib/memorax-code-backend/dist/{memory-viewer-activity.js → viewer/projection/activity.js} +2 -2
  81. package/lib/memorax-code-backend/dist/{memory-viewer-history-projection.js → viewer/projection/history.js} +1 -1
  82. package/lib/memorax-code-backend/dist/{memory-viewer-observability.js → viewer/projection/observability.js} +1 -1
  83. package/lib/memorax-code-backend/dist/{memory-viewer-user-projection.js → viewer/projection/user.js} +1 -1
  84. package/lib/memorax-code-backend/dist/{memory-viewer-writeback-status.js → viewer/projection/writeback-status.js} +1 -1
  85. package/lib/memorax-code-backend/dist/{memory-viewer-store.js → viewer/store.js} +59 -32
  86. package/lib/memorax-code-backend/dist/{memory-viewer-user-html.js → viewer/ui/user-html.js} +11 -10
  87. package/lib/memorax-code-backend/dist/windows-cli-invocation.js +1 -148
  88. package/lib/memorax-code-backend/package.json +3 -3
  89. package/lib/memorax-code-claude-adapter/.claude-plugin/plugin.json +1 -1
  90. package/lib/memorax-code-claude-adapter/hooks/runtime-shell.json +1 -1
  91. package/lib/memorax-code-claude-adapter/package.json +1 -1
  92. package/lib/memorax-code-claude-adapter/skills/memorax-code/SKILL.md +11 -2
  93. package/lib/memorax-code-claude-adapter/skills/memorax-code/defaults.json +8 -5
  94. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/memorax-add.md +1 -1
  95. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/memorax-search.md +37 -9
  96. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/personal-read.md +1 -1
  97. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/personal-write.md +33 -13
  98. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/repo-build.md +62 -13
  99. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/repo-read.md +11 -4
  100. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/repo-templates.md +179 -59
  101. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/repo-update.md +18 -7
  102. package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/collect_all.py +122 -39
  103. package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/detect_updates.py +73 -10
  104. package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/github_resource_facets.py +9 -1
  105. package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +9 -1
  106. package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/validate_memory.py +23 -1
  107. package/lib/memorax-code-claude-adapter/src/plugin-install.mjs +1 -0
  108. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/.claude-plugin/plugin.json +1 -1
  109. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/hooks/runtime-shell.json +1 -1
  110. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/capture-cwd-hook.mjs +21 -14
  111. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/ensure-backend-runner.mjs +26 -7
  112. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/memory-skill-reminder-hook.mjs +86 -95
  113. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/memory-skill-reminder-policy.mjs +58 -0
  114. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/repo-memory/repo-memory-auto-build.mjs +2 -2
  115. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/repo-memory/repo-memory-job-supervisor.mjs +1 -1
  116. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/windows-cli-invocation.mjs +13 -1
  117. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/package.json +1 -1
  118. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/SKILL.md +11 -2
  119. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/defaults.json +8 -5
  120. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/memorax-add.md +1 -1
  121. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/memorax-search.md +37 -9
  122. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/personal-read.md +1 -1
  123. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/personal-write.md +33 -13
  124. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/repo-build.md +62 -13
  125. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/repo-read.md +11 -4
  126. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/repo-templates.md +179 -59
  127. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/repo-update.md +18 -7
  128. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/collect_all.py +122 -39
  129. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/detect_updates.py +73 -10
  130. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/github_resource_facets.py +9 -1
  131. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +9 -1
  132. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/validate_memory.py +23 -1
  133. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/src/plugin-install.mjs +1 -0
  134. package/lib/memorax-code-codex-adapter/.codex-plugin/plugin.json +1 -1
  135. package/lib/memorax-code-codex-adapter/hooks/runtime-shell.json +1 -1
  136. package/lib/memorax-code-codex-adapter/package.json +1 -1
  137. package/lib/memorax-code-codex-adapter/runtime-hooks/memory-skill-reminder.mjs +10 -2
  138. package/lib/memorax-code-codex-adapter/skills/memorax-code/SKILL.md +11 -2
  139. package/lib/memorax-code-codex-adapter/skills/memorax-code/defaults.json +8 -5
  140. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/memorax-add.md +1 -1
  141. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/memorax-search.md +37 -9
  142. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/personal-read.md +1 -1
  143. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/personal-write.md +33 -13
  144. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/repo-build.md +62 -13
  145. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/repo-read.md +11 -4
  146. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/repo-templates.md +179 -59
  147. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/repo-update.md +18 -7
  148. package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/collect_all.py +122 -39
  149. package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/detect_updates.py +73 -10
  150. package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/github_resource_facets.py +9 -1
  151. package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +9 -1
  152. package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/validate_memory.py +23 -1
  153. package/lib/memorax-code-dsh-adapter/cordis.patch.yml +10 -0
  154. package/lib/memorax-code-dsh-adapter/hooks/repo-memory-job.mjs +68 -0
  155. package/lib/memorax-code-dsh-adapter/package.json +69 -0
  156. package/lib/memorax-code-dsh-adapter/skills/memorax-code/SKILL.md +91 -0
  157. package/lib/memorax-code-dsh-adapter/skills/memorax-code/agents/claude.yaml +10 -0
  158. package/lib/memorax-code-dsh-adapter/skills/memorax-code/agents/openai.yaml +7 -0
  159. package/lib/memorax-code-dsh-adapter/skills/memorax-code/defaults.json +12 -0
  160. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/memorax-add.md +86 -0
  161. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/memorax-search.md +91 -0
  162. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/personal-read.md +46 -0
  163. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/personal-write.md +120 -0
  164. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/repo-build.md +319 -0
  165. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/repo-read.md +103 -0
  166. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/repo-templates.md +390 -0
  167. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/repo-update.md +127 -0
  168. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/collect_all.py +579 -0
  169. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/detect_updates.py +919 -0
  170. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/git_commit_facets.py +222 -0
  171. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/github_resource_facets.py +512 -0
  172. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +517 -0
  173. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/prepare_repo_memory.py +411 -0
  174. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/user_profile_memory.py +528 -0
  175. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/validate_memory.py +248 -0
  176. package/lib/memorax-code-dsh-adapter/src/backend-client.mjs +119 -0
  177. package/lib/memorax-code-dsh-adapter/src/dsh-message.mjs +32 -0
  178. package/lib/memorax-code-dsh-adapter/src/dsh-version.mjs +18 -0
  179. package/lib/memorax-code-dsh-adapter/src/http-client.mjs +55 -0
  180. package/lib/memorax-code-dsh-adapter/src/index.mjs +72 -0
  181. package/lib/memorax-code-dsh-adapter/src/personal-context-worker.mjs +48 -0
  182. package/lib/memorax-code-dsh-adapter/src/personal-context.mjs +114 -0
  183. package/lib/memorax-code-dsh-adapter/src/plugin.mjs +724 -0
  184. package/lib/memorax-code-dsh-adapter/src/profile-lifecycle.mjs +1289 -0
  185. package/lib/memorax-code-dsh-adapter/src/protocol.mjs +145 -0
  186. package/lib/memorax-code-dsh-adapter/src/runtime-state.mjs +132 -0
  187. package/lib/memorax-code-opencode-adapter/hooks/repo-memory-job.mjs +37 -0
  188. package/lib/memorax-code-opencode-adapter/package.json +10 -0
  189. package/lib/memorax-code-opencode-adapter/skills/memorax-code/SKILL.md +91 -0
  190. package/lib/memorax-code-opencode-adapter/skills/memorax-code/agents/claude.yaml +10 -0
  191. package/lib/memorax-code-opencode-adapter/skills/memorax-code/agents/openai.yaml +7 -0
  192. package/lib/memorax-code-opencode-adapter/skills/memorax-code/defaults.json +12 -0
  193. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/memorax-add.md +86 -0
  194. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/memorax-search.md +91 -0
  195. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/personal-read.md +46 -0
  196. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/personal-write.md +120 -0
  197. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/repo-build.md +319 -0
  198. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/repo-read.md +103 -0
  199. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/repo-templates.md +390 -0
  200. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/repo-update.md +127 -0
  201. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/collect_all.py +579 -0
  202. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/detect_updates.py +919 -0
  203. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/git_commit_facets.py +222 -0
  204. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/github_resource_facets.py +512 -0
  205. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +517 -0
  206. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/prepare_repo_memory.py +411 -0
  207. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/user_profile_memory.py +528 -0
  208. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/validate_memory.py +248 -0
  209. package/lib/memorax-code-opencode-adapter/src/adapter-paths.mjs +37 -0
  210. package/lib/memorax-code-opencode-adapter/src/cli.mjs +260 -0
  211. package/lib/memorax-code-opencode-adapter/src/diagnostics.mjs +31 -0
  212. package/lib/memorax-code-opencode-adapter/src/plugin-install.mjs +673 -0
  213. package/lib/memorax-code-opencode-adapter/src/plugin.mjs +536 -0
  214. package/lib/memorax-code-opencode-adapter/src/repo-memory-server-runner.mjs +207 -0
  215. package/lib/run-entrypoint.mjs +6 -0
  216. package/package.json +7 -3
  217. package/lib/memorax-code-backend/dist/client-plugin-removal.js +0 -67
  218. /package/lib/memorax-code-backend/dist/{claude-transcript-turn.js → clients/claude/transcript-turn.js} +0 -0
  219. /package/lib/memorax-code-backend/dist/{codex-effective-prompt.js → clients/codex/effective-prompt.js} +0 -0
  220. /package/lib/memorax-code-backend/dist/{codex-rollout-turn.js → clients/codex/rollout-turn.js} +0 -0
  221. /package/lib/memorax-code-backend/dist/{codex-session-turn-index.js → clients/codex/session-turn-index.js} +0 -0
  222. /package/lib/memorax-code-backend/dist/{codex-workspace-links.js → clients/codex/workspace-links.js} +0 -0
  223. /package/lib/memorax-code-backend/dist/{backend-env.js → config/backend-env.js} +0 -0
  224. /package/lib/memorax-code-backend/dist/{proxy-env.js → config/proxy-env.js} +0 -0
  225. /package/lib/memorax-code-backend/dist/{entrypoint.js → entrypoints/main.js} +0 -0
  226. /package/lib/memorax-code-backend/dist/{backend-process.js → lifecycle/backend/process.js} +0 -0
  227. /package/lib/memorax-code-backend/dist/{backend-shutdown-request.js → lifecycle/backend/shutdown-request.js} +0 -0
  228. /package/lib/memorax-code-backend/dist/{backend-status.js → lifecycle/backend/status.js} +0 -0
  229. /package/lib/memorax-code-backend/dist/{adapter-lifecycle-participant.js → lifecycle/contracts.js} +0 -0
  230. /package/lib/memorax-code-backend/dist/{install-watchdog.js → lifecycle/install-watchdog.js} +0 -0
  231. /package/lib/memorax-code-backend/dist/{memory-observability.js → lifecycle/participant.js} +0 -0
  232. /package/lib/memorax-code-backend/dist/{memory-project.js → memory/project.js} +0 -0
  233. /package/lib/memorax-code-backend/dist/{repository-memory-scope.js → repository/scope.js} +0 -0
  234. /package/lib/memorax-code-backend/dist/{incremental-jsonl-projection.js → shared/incremental-jsonl-projection.js} +0 -0
  235. /package/lib/memorax-code-backend/dist/{utils.js → shared/record.js} +0 -0
  236. /package/lib/memorax-code-backend/dist/{server-json.js → transport/http/json.js} +0 -0
  237. /package/lib/memorax-code-backend/dist/{memory-viewer-data-projection-cache.js → viewer/projection/cache.js} +0 -0
  238. /package/lib/memorax-code-backend/dist/{memory-viewer-event-identity.js → viewer/projection/event-identity.js} +0 -0
  239. /package/lib/memorax-code-backend/dist/{memory-viewer-redaction.js → viewer/projection/redaction.js} +0 -0
  240. /package/lib/memorax-code-backend/dist/{memory-viewer-turn-reference.js → viewer/projection/turn-reference.js} +0 -0
  241. /package/lib/memorax-code-backend/dist/{memory-viewer-icon.js → viewer/ui/icon.js} +0 -0
  242. /package/lib/memorax-code-backend/dist/{memory-viewer-logo.js → viewer/ui/logo.js} +0 -0
@@ -0,0 +1,724 @@
1
+ import {
2
+ createSkillReminderCommand,
3
+ createTurnStartCommand,
4
+ createWritebackCommand,
5
+ } from "./protocol.mjs";
6
+ import { loadDshPersonalContext } from "./personal-context.mjs";
7
+
8
+ export const PLUGIN_NAME = "memorax-code";
9
+ export const CONTEXT_SOURCE_PLUGIN = "memorax-code-dsh";
10
+ // DSH gives the whole app five seconds to dispose; leave time for downstream
11
+ // persistence and process cleanup after this plugin's accepted writes drain.
12
+ const DEFAULT_WRITEBACK_DRAIN_TIMEOUT_MS = 4_000;
13
+ const MAX_REMINDER_TRACE_TIMEOUT_MS = 1_000;
14
+ const MAX_RESUME_RECONCILIATION_WAIT_MS = 12_000;
15
+
16
+ /** Register DSH-native retrieval and durable Turn writeback listeners. */
17
+ export function registerMemoraxCodePlugin(ctx, dependencies) {
18
+ const assertEnabled = dependencies?.assertEnabled;
19
+ const backendClient = dependencies?.backendClient;
20
+ const createUserMessage = dependencies?.createUserMessage;
21
+ const loadPersonalContext = dependencies?.loadPersonalContext ?? loadDshPersonalContext;
22
+ const scheduleRepoMemoryBuild = dependencies?.scheduleRepoMemoryBuild;
23
+ const intervalTurns = dependencies?.intervalTurns;
24
+ const isReminderDue = dependencies?.isReminderDue;
25
+ const memoryReminderContext = nonEmptyString(dependencies?.memoryReminderContext);
26
+ const personalMemoryReminderContext = nonEmptyString(dependencies?.personalMemoryReminderContext);
27
+ const defer = dependencies?.defer ?? queueMicrotask;
28
+ const debug = dependencies?.debug ?? process.env.MEMORAX_CODE_DSH_DEBUG === "1";
29
+ const drainTimeoutMs = positiveInteger(
30
+ dependencies?.drainTimeoutMs,
31
+ DEFAULT_WRITEBACK_DRAIN_TIMEOUT_MS,
32
+ );
33
+ if (typeof backendClient?.recordTurnStart !== "function"
34
+ || typeof backendClient?.writebackTurn !== "function") {
35
+ throw new TypeError("memorax-code DSH plugin requires a Backend client");
36
+ }
37
+ if (typeof assertEnabled !== "function") {
38
+ throw new TypeError("memorax-code DSH plugin requires runtime enablement authority");
39
+ }
40
+ if (typeof createUserMessage !== "function") {
41
+ throw new TypeError("memorax-code DSH plugin requires createUserMessage");
42
+ }
43
+ if (typeof loadPersonalContext !== "function") {
44
+ throw new TypeError("memorax-code DSH plugin requires a personal context loader");
45
+ }
46
+ if (!positiveSafeInteger(intervalTurns)) {
47
+ throw new TypeError("memorax-code DSH plugin requires a positive reminder interval");
48
+ }
49
+ if (typeof isReminderDue !== "function") {
50
+ throw new TypeError("memorax-code DSH plugin requires a reminder policy");
51
+ }
52
+ if (!memoryReminderContext || !personalMemoryReminderContext) {
53
+ throw new TypeError("memorax-code DSH plugin requires reminder context");
54
+ }
55
+ if (typeof ctx?.sessions?.flush !== "function"
56
+ || typeof ctx?.sessionPersistence?.readFrom !== "function") {
57
+ throw new TypeError("memorax-code DSH plugin requires sessions and sessionPersistence");
58
+ }
59
+
60
+ const turns = new WeakMap();
61
+ const personalContexts = new WeakMap();
62
+ const pendingContextMessages = new WeakMap();
63
+ const writebackTails = new WeakMap();
64
+ const retrievalLifetime = new AbortController();
65
+ const resumeReconciliations = new WeakMap();
66
+ const writebackLifetime = new AbortController();
67
+ const pendingReminderTraces = new Set();
68
+ const pendingWritebacks = new Set();
69
+ let accepting = true;
70
+
71
+ ctx.on("agent/session-start", ({ agent, source }) => {
72
+ const session = agent?.session;
73
+ if (source !== "resume" || !isMemoryEligibleSession(session) || !accepting) return;
74
+ if (resumeReconciliations.has(session)) return;
75
+ const state = recoveredInterruptedTurn(session);
76
+ if (!state) return;
77
+ const onFailure = (error) => debugFailure(ctx, debug, "interrupted Turn recovery", error);
78
+ const pending = enqueueWriteback({
79
+ ctx,
80
+ backendClient,
81
+ session,
82
+ turn: state.turn,
83
+ state,
84
+ signal: writebackLifetime.signal,
85
+ writebackTails,
86
+ })
87
+ .catch(onFailure);
88
+ resumeReconciliations.set(session, pending);
89
+ trackPending(pendingWritebacks, pending);
90
+ });
91
+
92
+ ctx.on("session/event", (session, event) => {
93
+ if (!isMemoryEligibleSession(session) || !accepting) return;
94
+ if (event?.type === "user/message") {
95
+ const pendingContext = takePendingContextMessage(
96
+ pendingContextMessages,
97
+ session,
98
+ event.data,
99
+ );
100
+ if (pendingContext) {
101
+ pendingContext.personalContext.commit();
102
+ if (pendingContext.personalContext.triggers.length > 0) {
103
+ trackPending(pendingReminderTraces, recordSkillReminder({
104
+ backendClient,
105
+ ctx,
106
+ cwd: pendingContext.cwd,
107
+ debug,
108
+ personalContext: pendingContext.personalContext,
109
+ session,
110
+ turn: pendingContext.turn,
111
+ turns,
112
+ }));
113
+ }
114
+ }
115
+ return;
116
+ }
117
+ if (event?.type === "turn/start") {
118
+ const turn = event.data?.turn;
119
+ if (!positiveSafeInteger(turn) || !nonNegativeSafeInteger(event.seq)) return;
120
+ const sessionTurns = turnMap(turns, session);
121
+ if (sessionTurns.has(turn)) {
122
+ sessionTurns.set(turn, { invalid: true });
123
+ return;
124
+ }
125
+ sessionTurns.set(turn, {
126
+ startSeq: event.seq,
127
+ retrievalAttempted: false,
128
+ turnStartRecorded: false,
129
+ closed: false,
130
+ });
131
+ return;
132
+ }
133
+ if (event?.type !== "turn/end") return;
134
+ const turn = event.data?.turn;
135
+ if (!positiveSafeInteger(turn) || !nonNegativeSafeInteger(event.seq)) return;
136
+ discardPendingContextMessages(pendingContextMessages, session, turn);
137
+ const state = turns.get(session)?.get(turn);
138
+ if (!state || state.invalid || state.closed || event.seq < state.startSeq) return;
139
+ state.closed = true;
140
+ state.endSeq = event.seq;
141
+ // Wait one microtask so every session/event listener, including the
142
+ // persistence coordinator, has admitted turn/end before the flush barrier.
143
+ const onFailure = (error) => debugFailure(ctx, debug, "writeback", error);
144
+ const pending = deferPromise(defer, () => enqueueWriteback({
145
+ ctx,
146
+ backendClient,
147
+ session,
148
+ turn,
149
+ state,
150
+ signal: writebackLifetime.signal,
151
+ writebackTails,
152
+ }), onFailure)
153
+ .catch(onFailure)
154
+ .finally(() => turns.get(session)?.delete(turn));
155
+ trackPending(pendingWritebacks, pending);
156
+ });
157
+
158
+ ctx.on("session/disposed", (session) => {
159
+ discardPendingContextMessages(pendingContextMessages, session);
160
+ turns.delete(session);
161
+ resumeReconciliations.delete(session);
162
+ });
163
+
164
+ ctx.on("agent/pre-step", async ({ agent, turn, step, signal }, next) => {
165
+ const decision = await next();
166
+ if (decision?.kind !== "enter" || signal?.aborted || !accepting) return decision;
167
+ if (!isMemoryEligibleSession(agent?.session)) return decision;
168
+ const cwd = sessionCwd(agent.session);
169
+ if (!cwd) return decision;
170
+ if (!runtimeEnabled(assertEnabled, ctx, debug)) return decision;
171
+
172
+ const retrievalSignal = signal
173
+ ? AbortSignal.any([signal, retrievalLifetime.signal])
174
+ : retrievalLifetime.signal;
175
+ const recallContext = await collectRecallContext({
176
+ backendClient,
177
+ ctx,
178
+ debug,
179
+ decision,
180
+ scheduleRepoMemoryBuild,
181
+ session: agent.session,
182
+ signal: retrievalSignal,
183
+ step,
184
+ turn,
185
+ turns,
186
+ resumeReconciliations,
187
+ cwd,
188
+ });
189
+ if (signal?.aborted || !accepting || !runtimeEnabled(assertEnabled, ctx, debug)) {
190
+ return decision;
191
+ }
192
+ const personalContext = await collectPersonalContext({
193
+ ctx,
194
+ debug,
195
+ intervalTurns,
196
+ isReminderDue,
197
+ loadPersonalContext,
198
+ memoryReminderContext,
199
+ personalContexts,
200
+ personalMemoryReminderContext,
201
+ repoMemoryWorktree: turns.get(agent.session)?.get(turn)?.repoMemoryWorktree,
202
+ session: agent.session,
203
+ signal: retrievalSignal,
204
+ step,
205
+ turn,
206
+ });
207
+ if (signal?.aborted || !accepting || !runtimeEnabled(assertEnabled, ctx, debug)) {
208
+ personalContext?.discard();
209
+ return decision;
210
+ }
211
+ const context = [
212
+ recallContext,
213
+ personalContext?.context,
214
+ ].filter(Boolean).join("\n\n");
215
+ if (!context) {
216
+ personalContext?.commit();
217
+ return decision;
218
+ }
219
+ const contextMessage = createUserMessage({
220
+ content: [{ type: "text", text: context }],
221
+ source: contextSource((personalContext?.triggers.length ?? 0) > 0),
222
+ });
223
+ const result = {
224
+ kind: "enter",
225
+ messages: [
226
+ ...decision.messages,
227
+ contextMessage,
228
+ ],
229
+ };
230
+ if (personalContext) {
231
+ try {
232
+ stagePendingContextMessage(pendingContextMessages, agent.session, {
233
+ context,
234
+ cwd,
235
+ message: contextMessage,
236
+ personalContext,
237
+ turn,
238
+ });
239
+ } catch (error) {
240
+ personalContext.discard();
241
+ throw error;
242
+ }
243
+ }
244
+ return result;
245
+ });
246
+
247
+ if (typeof ctx.effect === "function") {
248
+ ctx.effect(() => async () => {
249
+ accepting = false;
250
+ retrievalLifetime.abort(new Error("memorax-code DSH plugin disposed"));
251
+ await Promise.all([
252
+ waitForPending(pendingWritebacks, drainTimeoutMs),
253
+ waitForPending(pendingReminderTraces, MAX_REMINDER_TRACE_TIMEOUT_MS),
254
+ ]);
255
+ writebackLifetime.abort(new Error("memorax-code DSH plugin disposed"));
256
+ }, "memorax-code.lifecycle");
257
+ }
258
+ }
259
+
260
+ function contextSource(isReminder) {
261
+ return isReminder
262
+ ? {
263
+ kind: "plugin",
264
+ plugin: CONTEXT_SOURCE_PLUGIN,
265
+ form: "notice",
266
+ summary: "MemoraX Code",
267
+ }
268
+ : { kind: "plugin", plugin: CONTEXT_SOURCE_PLUGIN };
269
+ }
270
+
271
+ function stagePendingContextMessage(pendingMessages, session, pending) {
272
+ const { message, ...staged } = pending;
273
+ const messageId = nonEmptyString(message?.id);
274
+ if (!messageId) throw new TypeError("memorax-code DSH context message requires an id");
275
+ if (pendingMessages.has(session)) throw new Error("memorax-code DSH context message already pending");
276
+ pendingMessages.set(session, { ...staged, messageId });
277
+ }
278
+
279
+ function takePendingContextMessage(pendingMessages, session, message) {
280
+ const messageId = nonEmptyString(message?.id);
281
+ if (!messageId
282
+ || message?.source?.kind !== "plugin"
283
+ || message.source.plugin !== CONTEXT_SOURCE_PLUGIN) return undefined;
284
+ const pending = pendingMessages.get(session);
285
+ if (!pending
286
+ || pending.messageId !== messageId
287
+ || textContent(message.content) !== pending.context) return undefined;
288
+ pendingMessages.delete(session);
289
+ return pending;
290
+ }
291
+
292
+ function discardPendingContextMessages(pendingMessages, session, turn) {
293
+ const pending = pendingMessages.get(session);
294
+ if (!pending || (turn !== undefined && pending.turn !== turn)) return;
295
+ pendingMessages.delete(session);
296
+ pending.personalContext.discard();
297
+ }
298
+
299
+ async function collectRecallContext(options) {
300
+ if (options.step !== 1) return undefined;
301
+ const state = options.turns.get(options.session)?.get(options.turn);
302
+ if (!state || state.invalid || state.closed) return undefined;
303
+ if (state.retrievalAttempted) {
304
+ try {
305
+ await waitForAbortable(
306
+ state.retrievalPending,
307
+ options.signal,
308
+ "DSH duplicate Turn retrieval wait aborted",
309
+ );
310
+ } catch {
311
+ // The pre-step boundary handles an aborted caller.
312
+ }
313
+ return undefined;
314
+ }
315
+ state.retrievalAttempted = true;
316
+ const prompt = userPrompt(options.decision.messages);
317
+ if (!prompt) return undefined;
318
+
319
+ const pending = (async () => {
320
+ try {
321
+ await waitForResumeReconciliation(
322
+ options.resumeReconciliations.get(options.session),
323
+ options.signal,
324
+ );
325
+ options.signal?.throwIfAborted();
326
+ const command = createTurnStartCommand({
327
+ sessionId: options.session.id,
328
+ turn: options.turn,
329
+ startSeq: state.startSeq,
330
+ cwd: options.cwd,
331
+ prompt,
332
+ });
333
+ const response = await options.backendClient.recordTurnStart(command, { signal: options.signal });
334
+ if (options.signal?.aborted) return undefined;
335
+ state.turnStartRecorded = true;
336
+ state.repoMemoryWorktree = nonEmptyString(response?.repoMemoryWorktree);
337
+ if (state.repoMemoryWorktree && typeof options.scheduleRepoMemoryBuild === "function") {
338
+ try {
339
+ options.scheduleRepoMemoryBuild(state.repoMemoryWorktree);
340
+ } catch (error) {
341
+ debugFailure(options.ctx, options.debug, "Repo Memory scheduling", error);
342
+ }
343
+ }
344
+ return nonEmptyString(response?.additionalContext);
345
+ } catch (error) {
346
+ debugFailure(options.ctx, options.debug, "retrieval", error);
347
+ return undefined;
348
+ }
349
+ })();
350
+ state.retrievalPending = pending;
351
+ try {
352
+ return await pending;
353
+ } finally {
354
+ if (state.retrievalPending === pending) state.retrievalPending = undefined;
355
+ }
356
+ }
357
+
358
+ async function collectPersonalContext(options) {
359
+ const state = personalContextState(options.personalContexts, options.session);
360
+ const projection = reminderProjection(
361
+ options.session,
362
+ options.turn,
363
+ options.intervalTurns,
364
+ options.memoryReminderContext,
365
+ options.personalMemoryReminderContext,
366
+ );
367
+ const firstObservation = !state.observed;
368
+ const compactionGeneration = projection.compactionGeneration;
369
+ const cadenceDue = options.step === 1
370
+ && options.isReminderDue(projection.cadenceTurnCount, options.intervalTurns);
371
+ const postCompactionDue = projection.postCompactionDue;
372
+ const includeProfile = firstObservation
373
+ || state.appliedCompactionGeneration < compactionGeneration;
374
+ const includeProcedure = firstObservation || cadenceDue;
375
+ if (!includeProfile && !includeProcedure) return undefined;
376
+ if (state.lastAttempt?.turn === options.turn
377
+ && state.lastAttempt?.compactionGeneration === compactionGeneration) return undefined;
378
+ const attempt = { turn: options.turn, compactionGeneration };
379
+ state.lastAttempt = attempt;
380
+
381
+ let loaded = false;
382
+ let profileContext;
383
+ let procedureContext;
384
+ if (options.repoMemoryWorktree) {
385
+ try {
386
+ const result = await options.loadPersonalContext({
387
+ cwd: options.repoMemoryWorktree,
388
+ includeProfile,
389
+ includeProcedure,
390
+ }, { signal: options.signal });
391
+ options.signal?.throwIfAborted();
392
+ loaded = true;
393
+ profileContext = nonEmptyString(result?.profileContext);
394
+ procedureContext = nonEmptyString(result?.procedureContext);
395
+ } catch (error) {
396
+ if (options.signal?.aborted && state.lastAttempt === attempt) {
397
+ state.lastAttempt = undefined;
398
+ }
399
+ debugFailure(options.ctx, options.debug, "personal context", error);
400
+ if (!cadenceDue && !postCompactionDue) return undefined;
401
+ }
402
+ }
403
+ const triggers = [
404
+ ...(cadenceDue ? ["cadence"] : []),
405
+ ...(postCompactionDue ? ["post_compaction"] : []),
406
+ ];
407
+ const reminderParts = [];
408
+ if (cadenceDue) reminderParts.push(options.memoryReminderContext);
409
+ if (postCompactionDue || (cadenceDue && firstObservation && profileContext)) {
410
+ reminderParts.push(options.personalMemoryReminderContext);
411
+ }
412
+ if (profileContext) reminderParts.push(profileContext);
413
+ if (procedureContext) reminderParts.push(procedureContext);
414
+ return {
415
+ context: reminderParts.join("\n\n"),
416
+ triggers,
417
+ commit() {
418
+ if (loaded) {
419
+ state.observed = true;
420
+ if (includeProfile) state.appliedCompactionGeneration = compactionGeneration;
421
+ }
422
+ },
423
+ discard() {
424
+ if (state.lastAttempt === attempt) state.lastAttempt = undefined;
425
+ },
426
+ };
427
+ }
428
+
429
+ async function recordSkillReminder(options) {
430
+ if (typeof options.backendClient.recordSkillReminder !== "function") return;
431
+ const turnState = options.turns.get(options.session)?.get(options.turn);
432
+ if (!turnState?.turnStartRecorded) return;
433
+ try {
434
+ await options.backendClient.recordSkillReminder(createSkillReminderCommand({
435
+ sessionId: options.session.id,
436
+ turn: options.turn,
437
+ cwd: options.cwd,
438
+ content: options.personalContext.context,
439
+ triggers: options.personalContext.triggers,
440
+ }), { signal: AbortSignal.timeout(MAX_REMINDER_TRACE_TIMEOUT_MS) });
441
+ } catch (error) {
442
+ debugFailure(options.ctx, options.debug, "reminder trace", error);
443
+ }
444
+ }
445
+
446
+ function enqueueWriteback(options) {
447
+ const previous = options.writebackTails.get(options.session) ?? Promise.resolve();
448
+ const current = previous
449
+ .catch(() => undefined)
450
+ .then(() => captureWriteback(
451
+ options.ctx,
452
+ options.backendClient,
453
+ options.session,
454
+ options.turn,
455
+ options.state,
456
+ options.signal,
457
+ ));
458
+ options.writebackTails.set(options.session, current);
459
+ return current.finally(() => {
460
+ if (options.writebackTails.get(options.session) === current) {
461
+ options.writebackTails.delete(options.session);
462
+ }
463
+ });
464
+ }
465
+
466
+ async function captureWriteback(ctx, backendClient, session, turn, state, signal) {
467
+ signal.throwIfAborted();
468
+ const participated = await ctx.sessions.flush(session);
469
+ if (!participated) throw new Error("DSH session flush had no persistence listener");
470
+ signal.throwIfAborted();
471
+ const persisted = await ctx.sessionPersistence.readFrom(session.id, state.startSeq, signal);
472
+ signal.throwIfAborted();
473
+ const cwd = sessionCwd(session);
474
+ if (!cwd) throw new Error("DSH session has no authoritative cwd");
475
+ const command = createWritebackCommand({
476
+ sessionId: session.id,
477
+ turn,
478
+ startSeq: state.startSeq,
479
+ endSeq: state.endSeq,
480
+ cwd,
481
+ sessionHeader: persisted?.meta,
482
+ events: persisted?.events,
483
+ });
484
+ await backendClient.writebackTurn(command, { signal });
485
+ }
486
+
487
+ function recoveredInterruptedTurn(session) {
488
+ const owned = ownedSessionEvents(session);
489
+ const firstLiveSeq = session?.firstLiveSeq;
490
+ if (!owned || !nonNegativeSafeInteger(firstLiveSeq)) return undefined;
491
+ const ownedSeedLength = firstLiveSeq - (session.header.seedLength ?? 0);
492
+ if (!nonNegativeSafeInteger(ownedSeedLength) || ownedSeedLength > owned.length) return undefined;
493
+ const events = owned.slice(0, ownedSeedLength);
494
+ const endIndex = events.findLastIndex((event) => (
495
+ event?.type === "turn/start" || event?.type === "turn/end"
496
+ ));
497
+ const end = events[endIndex];
498
+ const turn = end?.data?.turn;
499
+ if (end?.type !== "turn/end"
500
+ || end.data?.reason?.kind !== "interrupted"
501
+ || !positiveSafeInteger(turn)
502
+ || !nonNegativeSafeInteger(end.seq)) return undefined;
503
+ const start = events.slice(0, endIndex).findLast((event) => (
504
+ event?.type === "turn/start" || event?.type === "turn/end"
505
+ ));
506
+ if (start?.type !== "turn/start"
507
+ || start.data?.turn !== turn
508
+ || !nonNegativeSafeInteger(start.seq)
509
+ || start.seq > end.seq) return undefined;
510
+ return { turn, startSeq: start.seq, endSeq: end.seq };
511
+ }
512
+
513
+ async function waitForResumeReconciliation(promise, signal) {
514
+ if (!promise) return;
515
+ const timeout = AbortSignal.timeout(MAX_RESUME_RECONCILIATION_WAIT_MS);
516
+ const boundary = signal ? AbortSignal.any([signal, timeout]) : timeout;
517
+ await waitForAbortable(promise, boundary, "DSH interrupted Turn recovery wait aborted");
518
+ }
519
+
520
+ async function waitForAbortable(promise, signal, message) {
521
+ if (!promise) return;
522
+ if (!signal) {
523
+ await promise;
524
+ return;
525
+ }
526
+ signal.throwIfAborted();
527
+ let onAbort;
528
+ const aborted = new Promise((_, reject) => {
529
+ onAbort = () => reject(signal.reason instanceof Error ? signal.reason : new Error(message));
530
+ signal.addEventListener("abort", onAbort, { once: true });
531
+ if (signal.aborted) onAbort();
532
+ });
533
+ try {
534
+ await Promise.race([promise, aborted]);
535
+ } finally {
536
+ signal.removeEventListener("abort", onAbort);
537
+ }
538
+ }
539
+
540
+ export function isMemoryEligibleSession(session) {
541
+ const header = session?.header;
542
+ return typeof session?.id === "string"
543
+ && header !== null
544
+ && typeof header === "object"
545
+ && header.id === session.id
546
+ && header.origin === undefined
547
+ && (header.delegationDepth === undefined || header.delegationDepth === 0);
548
+ }
549
+
550
+ function userPrompt(messages) {
551
+ if (!Array.isArray(messages)) return undefined;
552
+ const parts = [];
553
+ for (const message of messages) {
554
+ if (message?.role !== "user" || message.source?.kind !== "user") continue;
555
+ const text = textContent(message.content);
556
+ if (text) parts.push(text);
557
+ }
558
+ return parts.length > 0 ? parts.join("\n\n") : undefined;
559
+ }
560
+
561
+ function textContent(content) {
562
+ if (!Array.isArray(content)) return undefined;
563
+ const parts = content.flatMap((block) => (
564
+ block?.type === "text" && typeof block.text === "string" && block.text.trim()
565
+ ? [block.text.trim()]
566
+ : []
567
+ ));
568
+ return parts.length > 0 ? parts.join("\n") : undefined;
569
+ }
570
+
571
+ function sessionCwd(session) {
572
+ return nonEmptyString(session?.header?.cwd);
573
+ }
574
+
575
+ function turnMap(turns, session) {
576
+ let sessionTurns = turns.get(session);
577
+ if (!sessionTurns) {
578
+ sessionTurns = new Map();
579
+ turns.set(session, sessionTurns);
580
+ }
581
+ return sessionTurns;
582
+ }
583
+
584
+ function personalContextState(personalContexts, session) {
585
+ let state = personalContexts.get(session);
586
+ if (!state) {
587
+ state = {
588
+ observed: false,
589
+ appliedCompactionGeneration: 0,
590
+ };
591
+ personalContexts.set(session, state);
592
+ }
593
+ return state;
594
+ }
595
+
596
+ function reminderProjection(
597
+ session,
598
+ turn,
599
+ intervalTurns,
600
+ memoryReminderContext,
601
+ personalMemoryReminderContext,
602
+ ) {
603
+ const events = ownedSessionEvents(session);
604
+ if (!events) {
605
+ return {
606
+ cadenceTurnCount: turn,
607
+ compactionGeneration: 0,
608
+ postCompactionDue: false,
609
+ };
610
+ }
611
+ let turnsSinceReminder;
612
+ let compactionGeneration = 0;
613
+ let postCompactionDue = false;
614
+ for (const event of events) {
615
+ if (event?.type === "turn/start" && turnsSinceReminder !== undefined) {
616
+ turnsSinceReminder += 1;
617
+ }
618
+ if (isSuccessfulCompaction(event)) {
619
+ compactionGeneration += 1;
620
+ postCompactionDue = true;
621
+ }
622
+ const reminderText = acceptedReminderText(event);
623
+ if (reminderText?.includes(memoryReminderContext)) turnsSinceReminder = 0;
624
+ if (reminderText?.includes(personalMemoryReminderContext)) postCompactionDue = false;
625
+ }
626
+ const cadenceTurnCount = turnsSinceReminder === undefined
627
+ ? 1
628
+ : turnsSinceReminder === 0
629
+ ? 0
630
+ : Math.min(turnsSinceReminder + 1, intervalTurns + 1);
631
+ return { cadenceTurnCount, compactionGeneration, postCompactionDue };
632
+ }
633
+
634
+ function ownedSessionEvents(session) {
635
+ if (!Array.isArray(session?.events)) return undefined;
636
+ const seedLength = session.header?.seedLength ?? 0;
637
+ if (!nonNegativeSafeInteger(seedLength) || seedLength > session.events.length) return undefined;
638
+ return session.events.slice(seedLength);
639
+ }
640
+
641
+ function isSuccessfulCompaction(event) {
642
+ return event?.type === "compaction/end"
643
+ && event.data !== null
644
+ && typeof event.data === "object"
645
+ && event.data.error === undefined;
646
+ }
647
+
648
+ function acceptedReminderText(event) {
649
+ if (event?.type !== "user/message"
650
+ || event.data?.source?.kind !== "plugin"
651
+ || event.data.source.plugin !== CONTEXT_SOURCE_PLUGIN
652
+ || event.data.source.form !== "notice") return undefined;
653
+ return textContent(event.data.content);
654
+ }
655
+
656
+ function positiveSafeInteger(value) {
657
+ return Number.isSafeInteger(value) && value > 0;
658
+ }
659
+
660
+ function positiveInteger(value, fallback) {
661
+ return Number.isSafeInteger(value) && value > 0 ? value : fallback;
662
+ }
663
+
664
+ function nonNegativeSafeInteger(value) {
665
+ return Number.isSafeInteger(value) && value >= 0;
666
+ }
667
+
668
+ function nonEmptyString(value) {
669
+ return typeof value === "string" && value.trim() ? value.trim() : undefined;
670
+ }
671
+
672
+ function runtimeEnabled(assertEnabled, ctx, debug) {
673
+ try {
674
+ assertEnabled();
675
+ return true;
676
+ } catch (error) {
677
+ debugFailure(ctx, debug, "runtime authority", error);
678
+ return false;
679
+ }
680
+ }
681
+
682
+ function debugFailure(ctx, debug, operation, error) {
683
+ if (!debug) return;
684
+ const detail = error instanceof Error ? error.message : String(error);
685
+ ctx.logger?.warn?.(`memorax-code ${operation} failed: ${detail}`);
686
+ }
687
+
688
+ function deferPromise(defer, operation, onFailure) {
689
+ return new Promise((resolve, reject) => {
690
+ try {
691
+ defer(() => {
692
+ const result = Promise.resolve().then(operation).catch(onFailure);
693
+ resolve(result);
694
+ return result;
695
+ });
696
+ } catch (error) {
697
+ reject(error);
698
+ }
699
+ });
700
+ }
701
+
702
+ function trackPending(pending, promise) {
703
+ pending.add(promise);
704
+ promise.then(
705
+ () => pending.delete(promise),
706
+ () => pending.delete(promise),
707
+ );
708
+ }
709
+
710
+ async function waitForPending(pending, timeoutMs) {
711
+ const accepted = [...pending];
712
+ if (accepted.length === 0) return;
713
+ let timer;
714
+ try {
715
+ await Promise.race([
716
+ Promise.allSettled(accepted),
717
+ new Promise((resolve) => {
718
+ timer = setTimeout(resolve, timeoutMs);
719
+ }),
720
+ ]);
721
+ } finally {
722
+ clearTimeout(timer);
723
+ }
724
+ }