@memorax/memorax-code 0.1.1 → 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 (246) 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 +424 -108
  5. package/docs/configuration.md +153 -29
  6. package/docs/troubleshooting.md +93 -7
  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 +38 -0
  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} +16 -9
  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} +18 -11
  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} +157 -34
  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 +3 -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} +82 -21
  49. package/lib/memorax-code-backend/dist/{memory-cli.js → memory/cli.js} +45 -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} +25 -4
  55. package/lib/memorax-code-backend/dist/{memory-service.js → memory/service.js} +30 -6
  56. package/lib/memorax-code-backend/dist/{memory-turn-coordinator.js → memory/turn-coordinator.js} +7 -3
  57. package/lib/memorax-code-backend/dist/{memory-writeback-buffer.js → memory/writeback-buffer.js} +31 -2
  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/{repository-memory-scope.js → repository/scope.js} +81 -33
  66. package/lib/memorax-code-backend/dist/server.js +3 -212
  67. package/lib/memorax-code-backend/dist/service-entrypoint.js +1 -1
  68. package/lib/memorax-code-backend/dist/{debug-log.js → shared/debug-log.js} +1 -1
  69. package/lib/memorax-code-backend/dist/shared/jsonl-append.js +75 -0
  70. package/lib/memorax-code-backend/dist/shared/windows-cli-invocation.js +148 -0
  71. package/lib/memorax-code-backend/dist/{trace-config.js → trace/config.js} +43 -5
  72. package/lib/memorax-code-backend/dist/{trace-context.js → trace/context.js} +53 -2
  73. package/lib/memorax-code-backend/dist/{trace-store.js → trace/store.js} +3 -3
  74. package/lib/memorax-code-backend/dist/{server-health.js → transport/http/health.js} +1 -1
  75. package/lib/memorax-code-backend/dist/{server-memory-hook.js → transport/http/memory-hook.js} +3 -3
  76. package/lib/memorax-code-backend/dist/{server-http.js → transport/http/request.js} +1 -1
  77. package/lib/memorax-code-backend/dist/{claude-local-transcript.js → viewer/history/claude-transcript.js} +3 -3
  78. package/lib/memorax-code-backend/dist/{memory-viewer-session-title.js → viewer/history/session-title.js} +1 -1
  79. package/lib/memorax-code-backend/dist/{server-memory-viewer.js → viewer/http/public-routes.js} +25 -14
  80. package/lib/memorax-code-backend/dist/viewer/model.js +1 -0
  81. package/lib/memorax-code-backend/dist/{memory-viewer-activity.js → viewer/projection/activity.js} +2 -2
  82. package/lib/memorax-code-backend/dist/{memory-viewer-history-projection.js → viewer/projection/history.js} +1 -1
  83. package/lib/memorax-code-backend/dist/{memory-viewer-observability.js → viewer/projection/observability.js} +1 -1
  84. package/lib/memorax-code-backend/dist/{memory-viewer-user-projection.js → viewer/projection/user.js} +1 -1
  85. package/lib/memorax-code-backend/dist/{memory-viewer-writeback-status.js → viewer/projection/writeback-status.js} +1 -1
  86. package/lib/memorax-code-backend/dist/{memory-viewer-store.js → viewer/store.js} +59 -32
  87. package/lib/memorax-code-backend/dist/viewer/ui/icon.js +1 -0
  88. package/lib/memorax-code-backend/dist/{memory-viewer-user-html.js → viewer/ui/user-html.js} +14 -12
  89. package/lib/memorax-code-backend/dist/windows-cli-invocation.js +1 -148
  90. package/lib/memorax-code-backend/package.json +3 -3
  91. package/lib/memorax-code-claude-adapter/.claude-plugin/plugin.json +1 -1
  92. package/lib/memorax-code-claude-adapter/hooks/runtime-shell.json +1 -1
  93. package/lib/memorax-code-claude-adapter/package.json +1 -1
  94. package/lib/memorax-code-claude-adapter/runtime-hooks/memory-turn.mjs +5 -0
  95. package/lib/memorax-code-claude-adapter/skills/memorax-code/SKILL.md +23 -15
  96. package/lib/memorax-code-claude-adapter/skills/memorax-code/defaults.json +8 -5
  97. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/memorax-add.md +5 -1
  98. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/memorax-search.md +40 -10
  99. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/personal-read.md +1 -1
  100. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/personal-write.md +33 -13
  101. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/repo-build.md +62 -13
  102. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/repo-read.md +11 -4
  103. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/repo-templates.md +179 -59
  104. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/repo-update.md +18 -7
  105. package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/collect_all.py +122 -39
  106. package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/detect_updates.py +73 -10
  107. package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/github_resource_facets.py +9 -1
  108. package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +9 -1
  109. package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/validate_memory.py +23 -1
  110. package/lib/memorax-code-claude-adapter/src/plugin-install.mjs +2 -0
  111. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/.claude-plugin/plugin.json +1 -1
  112. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/hooks/runtime-shell.json +1 -1
  113. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/capture-cwd-hook.mjs +21 -14
  114. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/ensure-backend-runner.mjs +26 -7
  115. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/memory-skill-reminder-hook.mjs +86 -95
  116. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/memory-skill-reminder-policy.mjs +58 -0
  117. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/repo-memory/repo-memory-auto-build.mjs +38 -0
  118. 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
  119. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/windows-cli-invocation.mjs +13 -1
  120. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/package.json +1 -1
  121. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/runtime-hooks/memory-turn.mjs +5 -0
  122. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/SKILL.md +23 -15
  123. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/defaults.json +8 -5
  124. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/memorax-add.md +5 -1
  125. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/memorax-search.md +40 -10
  126. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/personal-read.md +1 -1
  127. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/personal-write.md +33 -13
  128. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/repo-build.md +62 -13
  129. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/repo-read.md +11 -4
  130. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/repo-templates.md +179 -59
  131. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/repo-update.md +18 -7
  132. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/collect_all.py +122 -39
  133. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/detect_updates.py +73 -10
  134. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/github_resource_facets.py +9 -1
  135. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +9 -1
  136. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/validate_memory.py +23 -1
  137. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/src/plugin-install.mjs +2 -0
  138. package/lib/memorax-code-codex-adapter/.codex-plugin/plugin.json +1 -1
  139. package/lib/memorax-code-codex-adapter/hooks/runtime-shell.json +1 -1
  140. package/lib/memorax-code-codex-adapter/package.json +1 -1
  141. package/lib/memorax-code-codex-adapter/runtime-hooks/memory-skill-reminder.mjs +16 -2
  142. package/lib/memorax-code-codex-adapter/skills/memorax-code/SKILL.md +23 -15
  143. package/lib/memorax-code-codex-adapter/skills/memorax-code/defaults.json +8 -5
  144. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/memorax-add.md +5 -1
  145. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/memorax-search.md +40 -10
  146. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/personal-read.md +1 -1
  147. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/personal-write.md +33 -13
  148. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/repo-build.md +62 -13
  149. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/repo-read.md +11 -4
  150. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/repo-templates.md +179 -59
  151. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/repo-update.md +18 -7
  152. package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/collect_all.py +122 -39
  153. package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/detect_updates.py +73 -10
  154. package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/github_resource_facets.py +9 -1
  155. package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +9 -1
  156. package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/validate_memory.py +23 -1
  157. package/lib/memorax-code-dsh-adapter/cordis.patch.yml +10 -0
  158. package/lib/memorax-code-dsh-adapter/hooks/repo-memory-job.mjs +68 -0
  159. package/lib/memorax-code-dsh-adapter/package.json +69 -0
  160. package/lib/memorax-code-dsh-adapter/skills/memorax-code/SKILL.md +91 -0
  161. package/lib/memorax-code-dsh-adapter/skills/memorax-code/agents/claude.yaml +10 -0
  162. package/lib/memorax-code-dsh-adapter/skills/memorax-code/agents/openai.yaml +7 -0
  163. package/lib/memorax-code-dsh-adapter/skills/memorax-code/defaults.json +12 -0
  164. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/memorax-add.md +86 -0
  165. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/memorax-search.md +91 -0
  166. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/personal-read.md +46 -0
  167. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/personal-write.md +120 -0
  168. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/repo-build.md +319 -0
  169. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/repo-read.md +103 -0
  170. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/repo-templates.md +390 -0
  171. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/repo-update.md +127 -0
  172. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/collect_all.py +579 -0
  173. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/detect_updates.py +919 -0
  174. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/git_commit_facets.py +222 -0
  175. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/github_resource_facets.py +512 -0
  176. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +517 -0
  177. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/prepare_repo_memory.py +411 -0
  178. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/user_profile_memory.py +528 -0
  179. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/validate_memory.py +248 -0
  180. package/lib/memorax-code-dsh-adapter/src/backend-client.mjs +119 -0
  181. package/lib/memorax-code-dsh-adapter/src/dsh-message.mjs +32 -0
  182. package/lib/memorax-code-dsh-adapter/src/dsh-version.mjs +18 -0
  183. package/lib/memorax-code-dsh-adapter/src/http-client.mjs +55 -0
  184. package/lib/memorax-code-dsh-adapter/src/index.mjs +72 -0
  185. package/lib/memorax-code-dsh-adapter/src/personal-context-worker.mjs +48 -0
  186. package/lib/memorax-code-dsh-adapter/src/personal-context.mjs +114 -0
  187. package/lib/memorax-code-dsh-adapter/src/plugin.mjs +724 -0
  188. package/lib/memorax-code-dsh-adapter/src/profile-lifecycle.mjs +1289 -0
  189. package/lib/memorax-code-dsh-adapter/src/protocol.mjs +145 -0
  190. package/lib/memorax-code-dsh-adapter/src/runtime-state.mjs +132 -0
  191. package/lib/memorax-code-opencode-adapter/hooks/repo-memory-job.mjs +37 -0
  192. package/lib/memorax-code-opencode-adapter/package.json +10 -0
  193. package/lib/memorax-code-opencode-adapter/skills/memorax-code/SKILL.md +91 -0
  194. package/lib/memorax-code-opencode-adapter/skills/memorax-code/agents/claude.yaml +10 -0
  195. package/lib/memorax-code-opencode-adapter/skills/memorax-code/agents/openai.yaml +7 -0
  196. package/lib/memorax-code-opencode-adapter/skills/memorax-code/defaults.json +12 -0
  197. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/memorax-add.md +86 -0
  198. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/memorax-search.md +91 -0
  199. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/personal-read.md +46 -0
  200. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/personal-write.md +120 -0
  201. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/repo-build.md +319 -0
  202. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/repo-read.md +103 -0
  203. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/repo-templates.md +390 -0
  204. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/repo-update.md +127 -0
  205. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/collect_all.py +579 -0
  206. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/detect_updates.py +919 -0
  207. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/git_commit_facets.py +222 -0
  208. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/github_resource_facets.py +512 -0
  209. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +517 -0
  210. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/prepare_repo_memory.py +411 -0
  211. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/user_profile_memory.py +528 -0
  212. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/validate_memory.py +248 -0
  213. package/lib/memorax-code-opencode-adapter/src/adapter-paths.mjs +37 -0
  214. package/lib/memorax-code-opencode-adapter/src/cli.mjs +260 -0
  215. package/lib/memorax-code-opencode-adapter/src/diagnostics.mjs +31 -0
  216. package/lib/memorax-code-opencode-adapter/src/plugin-install.mjs +673 -0
  217. package/lib/memorax-code-opencode-adapter/src/plugin.mjs +536 -0
  218. package/lib/memorax-code-opencode-adapter/src/repo-memory-server-runner.mjs +207 -0
  219. package/lib/resolve-claude-command.mjs +154 -1
  220. package/lib/resolve-codex-command.mjs +56 -1
  221. package/lib/run-entrypoint.mjs +6 -0
  222. package/package.json +7 -3
  223. package/lib/memorax-code-backend/dist/client-plugin-removal.js +0 -67
  224. /package/lib/memorax-code-backend/dist/{claude-transcript-turn.js → clients/claude/transcript-turn.js} +0 -0
  225. /package/lib/memorax-code-backend/dist/{codex-effective-prompt.js → clients/codex/effective-prompt.js} +0 -0
  226. /package/lib/memorax-code-backend/dist/{codex-rollout-turn.js → clients/codex/rollout-turn.js} +0 -0
  227. /package/lib/memorax-code-backend/dist/{codex-session-turn-index.js → clients/codex/session-turn-index.js} +0 -0
  228. /package/lib/memorax-code-backend/dist/{codex-workspace-links.js → clients/codex/workspace-links.js} +0 -0
  229. /package/lib/memorax-code-backend/dist/{backend-env.js → config/backend-env.js} +0 -0
  230. /package/lib/memorax-code-backend/dist/{proxy-env.js → config/proxy-env.js} +0 -0
  231. /package/lib/memorax-code-backend/dist/{entrypoint.js → entrypoints/main.js} +0 -0
  232. /package/lib/memorax-code-backend/dist/{backend-process.js → lifecycle/backend/process.js} +0 -0
  233. /package/lib/memorax-code-backend/dist/{backend-shutdown-request.js → lifecycle/backend/shutdown-request.js} +0 -0
  234. /package/lib/memorax-code-backend/dist/{backend-status.js → lifecycle/backend/status.js} +0 -0
  235. /package/lib/memorax-code-backend/dist/{adapter-lifecycle-participant.js → lifecycle/contracts.js} +0 -0
  236. /package/lib/memorax-code-backend/dist/{install-watchdog.js → lifecycle/install-watchdog.js} +0 -0
  237. /package/lib/memorax-code-backend/dist/{memory-observability.js → lifecycle/participant.js} +0 -0
  238. /package/lib/memorax-code-backend/dist/{memory-project.js → memory/project.js} +0 -0
  239. /package/lib/memorax-code-backend/dist/{incremental-jsonl-projection.js → shared/incremental-jsonl-projection.js} +0 -0
  240. /package/lib/memorax-code-backend/dist/{utils.js → shared/record.js} +0 -0
  241. /package/lib/memorax-code-backend/dist/{server-json.js → transport/http/json.js} +0 -0
  242. /package/lib/memorax-code-backend/dist/{memory-viewer-data-projection-cache.js → viewer/projection/cache.js} +0 -0
  243. /package/lib/memorax-code-backend/dist/{memory-viewer-event-identity.js → viewer/projection/event-identity.js} +0 -0
  244. /package/lib/memorax-code-backend/dist/{memory-viewer-redaction.js → viewer/projection/redaction.js} +0 -0
  245. /package/lib/memorax-code-backend/dist/{memory-viewer-turn-reference.js → viewer/projection/turn-reference.js} +0 -0
  246. /package/lib/memorax-code-backend/dist/{memory-viewer-logo.js → viewer/ui/logo.js} +0 -0
@@ -7,31 +7,43 @@ import {
7
7
  stringOption,
8
8
  withJsonFileLock,
9
9
  } from "../config-utils.mjs";
10
+ import {
11
+ isMemorySkillReminderDue,
12
+ memorySkillReminderContext,
13
+ personalMemoryReminderContext,
14
+ resolveMemorySkillReminderIntervalTurns,
15
+ } from "./memory-skill-reminder-policy.mjs";
10
16
 
11
- const DEFAULT_REMINDER_INTERVAL_TURNS = 5;
12
- const DEFAULT_MEMORY_SKILL_INVOCATION = "$memorax-code";
13
17
  export const PERSONAL_MEMORY_REMINDER_CONTEXT = personalMemoryReminderContext();
14
-
15
- export function personalMemoryReminderContext(memorySkillInvocation) {
16
- const invocation = stringOption(memorySkillInvocation) ?? DEFAULT_MEMORY_SKILL_INVOCATION;
17
- return [
18
- `MemoraX Code personal-memory reminder: Use ${invocation} when the user states a durable current-repo identity or interaction preference, asks to list or recall stored personal memory, or explicitly asks to save, update, forget, or delete it.`,
19
- "Route reusable action sequences and work rules to procedure memory; do not store repository facts, one-off task details, or secrets.",
20
- ].join(" ");
21
- }
18
+ export { personalMemoryReminderContext } from "./memory-skill-reminder-policy.mjs";
22
19
 
23
20
  export async function runMemorySkillReminderHook(options, hookInput) {
24
21
  try {
25
22
  const input = hookInput ?? await readStdinJson();
23
+ const result = await evaluateMemorySkillReminder(options, input);
24
+ if (!result) return;
25
+ process.stdout.write(`${JSON.stringify({
26
+ hookSpecificOutput: {
27
+ hookEventName: "UserPromptSubmit",
28
+ additionalContext: result.additionalContext,
29
+ },
30
+ })}\n`);
31
+ if (result.reminder) await notifyReminder(options, result.reminder);
32
+ } catch (error) {
33
+ debugError(options, error);
34
+ }
35
+ }
36
+
37
+ export async function evaluateMemorySkillReminder(options, input) {
38
+ try {
26
39
  const sessionId = stringOption(input.session_id) ?? stringOption(input.sessionId);
27
- if (!sessionId) return;
40
+ if (!sessionId) return undefined;
28
41
  const transcriptPath = stringOption(input.transcript_path) ?? stringOption(input.transcriptPath);
29
- if (options.requireTranscriptPath && !transcriptPath) return;
42
+ if (options.requireTranscriptPath && !transcriptPath) return undefined;
30
43
  const hookEventName = stringOption(input.hook_event_name) ?? stringOption(input.hookEventName) ?? "UserPromptSubmit";
44
+ if (hookEventName !== "UserPromptSubmit") return undefined;
31
45
 
32
- const memoraxCodeHome = process.env.MEMORAX_CODE_HOME || defaultMemoraxCodeHome();
33
- if (hookEventName !== "UserPromptSubmit") return;
34
-
46
+ const memoraxCodeHome = resolveMemoraxCodeHome(options);
35
47
  const statePath = join(memoraxCodeHome, "adapters", options.adapterDir, "memory-skill-reminders.json");
36
48
  const turnId = stringOption(input.turn_id)
37
49
  ?? stringOption(input.turnId)
@@ -48,7 +60,7 @@ export async function runMemorySkillReminderHook(options, hookInput) {
48
60
  );
49
61
  if (next.duplicate) return next;
50
62
  const sessionState = next.state.sessions[sessionId];
51
- const memoryReminderDue = shouldRemind(
63
+ const memoryReminderDue = isMemorySkillReminderDue(
52
64
  sessionState?.turnCount,
53
65
  intervalTurns,
54
66
  options.remindOnFirstTurn !== false,
@@ -64,34 +76,30 @@ export async function runMemorySkillReminderHook(options, hookInput) {
64
76
  turnCount: sessionState?.turnCount,
65
77
  };
66
78
  });
67
- if (update.duplicate) return;
79
+ if (update.duplicate) return undefined;
68
80
  const { memoryReminderDue, supplementalReminderDue } = update;
69
81
 
70
82
  const baseAdditionalContext = stringOption(options.baseAdditionalContext);
71
- if (baseAdditionalContext || memoryReminderDue || supplementalReminderDue) {
72
- const cadenceReminderContext = memoryReminderDue
73
- ? await buildCadenceReminderContext(options, input)
74
- : undefined;
75
- const personalMemoryContext = supplementalReminderDue || (memoryReminderDue && update.turnCount === 1)
76
- ? await buildPersonalMemoryContext(options, input)
77
- : undefined;
78
- const reminderContext = stringOption(combinedReminderContext(options, {
79
- memoryReminderDue,
80
- supplementalReminderDue,
81
- }, cadenceReminderContext, personalMemoryContext));
82
- const additionalContext = [baseAdditionalContext, reminderContext].filter(Boolean).join("\n\n");
83
- const triggers = [
84
- ...(memoryReminderDue ? ["cadence"] : []),
85
- ...(supplementalReminderDue ? ["post_compaction"] : []),
86
- ];
87
- process.stdout.write(`${JSON.stringify({
88
- hookSpecificOutput: {
89
- hookEventName: "UserPromptSubmit",
90
- additionalContext,
91
- },
92
- })}\n`);
93
- if (reminderContext) {
94
- await notifyReminder(options, {
83
+ if (!baseAdditionalContext && !memoryReminderDue && !supplementalReminderDue) return undefined;
84
+ const cadenceReminderContext = memoryReminderDue
85
+ ? await buildCadenceReminderContext(options, input)
86
+ : undefined;
87
+ const personalMemoryContext = supplementalReminderDue || (memoryReminderDue && update.turnCount === 1)
88
+ ? await buildPersonalMemoryContext(options, input)
89
+ : undefined;
90
+ const reminderContext = stringOption(combinedReminderContext(options, {
91
+ memoryReminderDue,
92
+ supplementalReminderDue,
93
+ }, cadenceReminderContext, personalMemoryContext));
94
+ const additionalContext = [baseAdditionalContext, reminderContext].filter(Boolean).join("\n\n");
95
+ const triggers = [
96
+ ...(memoryReminderDue ? ["cadence"] : []),
97
+ ...(supplementalReminderDue ? ["post_compaction"] : []),
98
+ ];
99
+ return {
100
+ additionalContext,
101
+ ...(reminderContext ? {
102
+ reminder: {
95
103
  sessionId,
96
104
  turnId,
97
105
  transcriptPath,
@@ -99,13 +107,12 @@ export async function runMemorySkillReminderHook(options, hookInput) {
99
107
  workspaceKind: stringOption(input.workspace_kind) ?? stringOption(input.workspaceKind),
100
108
  content: reminderContext,
101
109
  triggers,
102
- });
103
- }
104
- }
110
+ },
111
+ } : {}),
112
+ };
105
113
  } catch (error) {
106
- if (process.env[options.debugEnv] === "1") {
107
- console.error(error instanceof Error ? error.message : String(error));
108
- }
114
+ debugError(options, error);
115
+ return undefined;
109
116
  }
110
117
  }
111
118
 
@@ -125,21 +132,28 @@ export function markSupplementalReminderAfterCompact(options, input) {
125
132
  const hookEventName = stringOption(input.hook_event_name) ?? stringOption(input.hookEventName);
126
133
  if (hookEventName !== "SessionStart" || stringOption(input.source) !== "compact") return;
127
134
  const sessionId = stringOption(input.session_id) ?? stringOption(input.sessionId);
128
- if (!sessionId) return;
129
- const memoraxCodeHome = process.env.MEMORAX_CODE_HOME || defaultMemoraxCodeHome();
135
+ markSupplementalReminderForSession(options, sessionId);
136
+ } catch (error) {
137
+ debugError(options, error);
138
+ }
139
+ }
140
+
141
+ export function markSupplementalReminderForSession(options, sessionId) {
142
+ try {
143
+ const normalizedSessionId = stringOption(sessionId);
144
+ if (!normalizedSessionId) return;
145
+ const memoraxCodeHome = resolveMemoraxCodeHome(options);
130
146
  const statePath = join(memoraxCodeHome, "adapters", options.adapterDir, "memory-skill-reminders.json");
131
147
  withJsonFileLock(statePath, () => {
132
148
  const existing = readJsonFile(statePath);
133
149
  atomicWriteJson(statePath, markSupplementalReminderPending(
134
150
  existing?.unreadable ? undefined : existing?.value,
135
151
  options.runtime,
136
- sessionId,
152
+ normalizedSessionId,
137
153
  ));
138
154
  });
139
155
  } catch (error) {
140
- if (process.env[options.debugEnv] === "1") {
141
- console.error(error instanceof Error ? error.message : String(error));
142
- }
156
+ debugError(options, error);
143
157
  }
144
158
  }
145
159
 
@@ -169,7 +183,7 @@ async function buildPersonalMemoryContext(options, input) {
169
183
 
170
184
  function combinedReminderContext(options, due, cadenceReminderContext, personalMemoryContext) {
171
185
  const contexts = [];
172
- if (due.memoryReminderDue) contexts.push(memoryReminderContext(options));
186
+ if (due.memoryReminderDue) contexts.push(memorySkillReminderContext(options.memorySkillInvocation));
173
187
  if (due.supplementalReminderDue || personalMemoryContext) {
174
188
  const additionalReminderContext = stringOption(options.additionalReminderContext);
175
189
  if (additionalReminderContext) contexts.push(additionalReminderContext);
@@ -180,15 +194,22 @@ function combinedReminderContext(options, due, cadenceReminderContext, personalM
180
194
  return contexts.join("\n\n");
181
195
  }
182
196
 
183
- function memoryReminderContext(options) {
184
- const invocation = stringOption(options.memorySkillInvocation) ?? DEFAULT_MEMORY_SKILL_INVOCATION;
185
- return `MemoraX Code reminder: proactively invoke ${invocation} whenever coding memory might help, even when uncertain; when in doubt, run one focused coding-memory search for relevant prior knowledge. Also use ${invocation} for repository-scoped personal memory, and classify the authority before reading or writing.`;
186
- }
187
-
188
197
  function defaultMemoraxCodeHome() {
189
198
  return process.env.HOME ? join(process.env.HOME, ".memorax-code") : ".memorax-code";
190
199
  }
191
200
 
201
+ function resolveMemoraxCodeHome(options) {
202
+ return stringOption(options.memoraxCodeHome)
203
+ ?? process.env.MEMORAX_CODE_HOME
204
+ ?? defaultMemoraxCodeHome();
205
+ }
206
+
207
+ function debugError(options, error) {
208
+ if (process.env[options.debugEnv] === "1") {
209
+ console.error(error instanceof Error ? error.message : String(error));
210
+ }
211
+ }
212
+
192
213
  function nextReminderState(existing, runtime, sessionId, turnId) {
193
214
  const state = reminderState(existing, runtime);
194
215
  const current = state.sessions[sessionId] && typeof state.sessions[sessionId] === "object" && !Array.isArray(state.sessions[sessionId])
@@ -231,47 +252,17 @@ function reminderState(existing, runtime) {
231
252
  return state;
232
253
  }
233
254
 
234
- function shouldRemind(turnCount, intervalTurns, remindOnFirstTurn) {
235
- if (!Number.isInteger(turnCount) || turnCount <= 0) return false;
236
- if (remindOnFirstTurn) return (turnCount - 1) % intervalTurns === 0;
237
- return turnCount > intervalTurns && (turnCount - 1) % intervalTurns === 0;
238
- }
239
-
240
255
  function reminderIntervalTurns(memoraxCodeHome) {
241
- return positiveInteger(process.env.MEMORAX_CODE_MEMORY_SKILL_REMINDER_INTERVAL_TURNS)
242
- ?? configReminderIntervalTurns(join(memoraxCodeHome, "config.toml"))
243
- ?? DEFAULT_REMINDER_INTERVAL_TURNS;
256
+ return resolveMemorySkillReminderIntervalTurns({
257
+ environmentValue: process.env.MEMORAX_CODE_MEMORY_SKILL_REMINDER_INTERVAL_TURNS,
258
+ configText: configReminderText(join(memoraxCodeHome, "config.toml")),
259
+ });
244
260
  }
245
261
 
246
- function configReminderIntervalTurns(path) {
262
+ function configReminderText(path) {
247
263
  try {
248
- return parseReminderIntervalTurns(readFileSync(path, "utf8"));
264
+ return readFileSync(path, "utf8");
249
265
  } catch {
250
266
  return undefined;
251
267
  }
252
268
  }
253
-
254
- function parseReminderIntervalTurns(text) {
255
- let section = "";
256
- for (const rawLine of text.split(/\r?\n/)) {
257
- const line = rawLine.split("#", 1)[0].trim();
258
- if (!line) continue;
259
- const sectionMatch = line.match(/^\[([^\]]+)\]$/);
260
- if (sectionMatch) {
261
- section = sectionMatch[1].trim();
262
- continue;
263
- }
264
- if (section !== "memory.skill_reminder") continue;
265
- const fieldMatch = line.match(/^interval_turns\s*=\s*(.+)$/);
266
- if (fieldMatch) return positiveInteger(fieldMatch[1]);
267
- }
268
- return undefined;
269
- }
270
-
271
- function positiveInteger(value) {
272
- if (typeof value !== "string") return undefined;
273
- const normalized = value.trim().replaceAll("_", "");
274
- if (!/^[1-9]\d*$/.test(normalized)) return undefined;
275
- const parsed = Number(normalized);
276
- return Number.isSafeInteger(parsed) ? parsed : undefined;
277
- }
@@ -0,0 +1,58 @@
1
+ export const DEFAULT_MEMORY_SKILL_REMINDER_INTERVAL_TURNS = 5;
2
+ const DEFAULT_MEMORY_SKILL_INVOCATION = "$memorax-code";
3
+
4
+ export function memorySkillReminderContext(memorySkillInvocation) {
5
+ const invocation = nonEmptyString(memorySkillInvocation) ?? DEFAULT_MEMORY_SKILL_INVOCATION;
6
+ return `MemoraX Code reminder: proactively invoke ${invocation} whenever coding memory might help, even when uncertain; follow the skill's router to decide whether any memory operation is needed. Also use ${invocation} for repository-scoped personal memory, and classify the authority before reading or writing.`;
7
+ }
8
+
9
+ export function personalMemoryReminderContext(memorySkillInvocation) {
10
+ const invocation = nonEmptyString(memorySkillInvocation) ?? DEFAULT_MEMORY_SKILL_INVOCATION;
11
+ return [
12
+ `MemoraX Code personal-memory reminder: Use ${invocation} when the user states a durable current-repo identity or interaction preference, asks to list or recall stored personal memory, or explicitly asks to save, update, forget, or delete it.`,
13
+ "Route reusable action sequences and work rules to procedure memory; do not store repository facts, one-off task details, or secrets.",
14
+ ].join(" ");
15
+ }
16
+
17
+ export function resolveMemorySkillReminderIntervalTurns(input = {}) {
18
+ return positiveInteger(input.environmentValue)
19
+ ?? parseMemorySkillReminderIntervalTurns(input.configText)
20
+ ?? DEFAULT_MEMORY_SKILL_REMINDER_INTERVAL_TURNS;
21
+ }
22
+
23
+ export function isMemorySkillReminderDue(turnCount, intervalTurns, remindOnFirstTurn = true) {
24
+ if (!Number.isInteger(turnCount) || turnCount <= 0) return false;
25
+ if (!Number.isInteger(intervalTurns) || intervalTurns <= 0) return false;
26
+ if (remindOnFirstTurn) return (turnCount - 1) % intervalTurns === 0;
27
+ return turnCount > intervalTurns && (turnCount - 1) % intervalTurns === 0;
28
+ }
29
+
30
+ export function parseMemorySkillReminderIntervalTurns(text) {
31
+ if (typeof text !== "string") return undefined;
32
+ let section = "";
33
+ for (const rawLine of text.split(/\r?\n/)) {
34
+ const line = rawLine.split("#", 1)[0].trim();
35
+ if (!line) continue;
36
+ const sectionMatch = line.match(/^\[([^\]]+)\]$/);
37
+ if (sectionMatch) {
38
+ section = sectionMatch[1].trim();
39
+ continue;
40
+ }
41
+ if (section !== "memory.skill_reminder") continue;
42
+ const fieldMatch = line.match(/^interval_turns\s*=\s*(.+)$/);
43
+ if (fieldMatch) return positiveInteger(fieldMatch[1]);
44
+ }
45
+ return undefined;
46
+ }
47
+
48
+ function positiveInteger(value) {
49
+ if (typeof value !== "string") return undefined;
50
+ const normalized = value.trim().replaceAll("_", "");
51
+ if (!/^[1-9]\d*$/.test(normalized)) return undefined;
52
+ const parsed = Number(normalized);
53
+ return Number.isSafeInteger(parsed) ? parsed : undefined;
54
+ }
55
+
56
+ function nonEmptyString(value) {
57
+ return typeof value === "string" && value.trim() ? value.trim() : undefined;
58
+ }
@@ -0,0 +1,38 @@
1
+ import { spawn } from "node:child_process";
2
+ import { existsSync } from "node:fs";
3
+ import { join } from "node:path";
4
+
5
+ export function scheduleMissingRepoMemoryBuild(repo, options = {}) {
6
+ try {
7
+ const repoPath = nonEmptyString(repo);
8
+ const pluginRoot = nonEmptyString(options.pluginRoot);
9
+ if (!repoPath || !pluginRoot) return false;
10
+ if (existsSync(join(repoPath, ".repo_memory", "PROFILE.md"))) return false;
11
+
12
+ const jobHookPath = join(pluginRoot, "hooks", "repo-memory-job.mjs");
13
+ if (!existsSync(jobHookPath)) return false;
14
+ const child = spawn(options.nodePath ?? process.execPath, [jobHookPath, "maintain", "--repo", repoPath], {
15
+ cwd: repoPath,
16
+ detached: true,
17
+ env: options.env ?? process.env,
18
+ stdio: "ignore",
19
+ windowsHide: true,
20
+ });
21
+ child.once("error", (error) => debug(options, error));
22
+ child.unref();
23
+ return true;
24
+ } catch (error) {
25
+ debug(options, error);
26
+ return false;
27
+ }
28
+ }
29
+
30
+ function nonEmptyString(value) {
31
+ return typeof value === "string" && value.trim() ? value.trim() : undefined;
32
+ }
33
+
34
+ function debug(options, error) {
35
+ if (process.env[options.debugEnv] === "1") {
36
+ console.error(error instanceof Error ? error.message : String(error));
37
+ }
38
+ }
@@ -517,7 +517,7 @@ function buildPrompt(repo, snapshotHead, memorySkillInvocation) {
517
517
  }
518
518
 
519
519
  function updatePrompt(repo, snapshotHead, memorySkillInvocation) {
520
- return `This invocation is the authorized background repo-memory worker. Complete the requested operation yourself; do not inspect, launch, or defer to another repo-memory job.\n\nUse ${memorySkillInvocation} and select the Repo Memory repo-update operation to incrementally update this repository's existing .repo_memory.\n\nRepository: ${repo}\nSnapshot HEAD: ${snapshotHead}\n\nDefault behavior:\n- Treat existing .repo_memory as the baseline.\n- Detect local commit delta from the stored baseline to the exact snapshot SHA above.\n- Also try GitHub/GitLab PR, MR, and issue evidence when provider CLIs and authentication are available.\n- If provider evidence is unavailable, continue with local git evidence and preserve existing provider resources.\n- Do not rebuild unless updater reports the baseline is unusable; if a full rebuild is required, stop and report that.\n- Keep file writes scoped to ${repo}/.repo_memory and necessary repo-memory ignore/config entries.\n- Do not modify source code, dependency files, global config, or files outside the target repo unless explicitly required by repo-memory tooling.\n- Ensure PROFILE.md local_head resolves to the snapshot SHA above.\n- Run the packaged repo-memory validator before finishing.\n- Write a concise final summary with changed files, provider evidence status, and any follow-up needed.\n`;
520
+ return `This invocation is the authorized background repo-memory worker. Complete the requested operation yourself; do not inspect, launch, or defer to another repo-memory job.\n\nUse ${memorySkillInvocation} and select the Repo Memory repo-update operation to incrementally update this repository's existing .repo_memory.\n\nRepository: ${repo}\nSnapshot HEAD: ${snapshotHead}\n\nDefault behavior:\n- Treat existing .repo_memory as the baseline.\n- Run and follow the packaged repo-update detector's effective history policy.\n- Do not re-enable commit or provider evidence channels disabled by repoHistory.mode.\n- If provider evidence is unavailable when provider history is enabled, preserve existing provider resources.\n- Do not rebuild unless updater reports the baseline is unusable; if a full rebuild is required, stop and report that.\n- Keep file writes scoped to ${repo}/.repo_memory and necessary repo-memory ignore/config entries.\n- Do not modify source code, dependency files, global config, or files outside the target repo unless explicitly required by repo-memory tooling.\n- Ensure PROFILE.md local_head resolves to the snapshot SHA above.\n- Run the packaged repo-memory validator before finishing.\n- Write a concise final summary with changed files, provider evidence status, and any follow-up needed.\n`;
521
521
  }
522
522
 
523
523
  function gitSnapshot(repo) {
@@ -37,7 +37,11 @@ export function resolveWindowsCliInvocation(command, args, options = {}) {
37
37
  .filter(isNodeEntrypoint)
38
38
  .find((candidate) => fileExists(candidate));
39
39
  if (!cli) {
40
- const override = name === "claude" ? "MEMORAX_CODE_CLAUDE_CLI_JS" : "MEMORAX_CODE_CODEX_CLI_JS";
40
+ const override = name === "claude"
41
+ ? "MEMORAX_CODE_CLAUDE_CLI_JS"
42
+ : name === "dsh"
43
+ ? "MEMORAX_CODE_DSH_CLI_JS"
44
+ : "MEMORAX_CODE_CODEX_CLI_JS";
41
45
  throw new Error(
42
46
  `refusing to execute ${pathApi.basename(resolvedCommand)} through a command shell; `
43
47
  + `set ${override} to its Node entrypoint`,
@@ -75,6 +79,14 @@ function cliEntrypointCandidates(name, command, env, pathApi) {
75
79
  pathApi.join(root, "..", "@anthropic-ai", "claude-code", "cli.js"),
76
80
  ];
77
81
  }
82
+ if (name === "dsh") {
83
+ return [
84
+ env.MEMORAX_CODE_DSH_CLI_JS,
85
+ env.DSH_CLI_JS,
86
+ pathApi.join(root, "node_modules", "@deepseek-ai", "dsh", "lib", "bin.js"),
87
+ pathApi.join(root, "..", "@deepseek-ai", "dsh", "lib", "bin.js"),
88
+ ];
89
+ }
78
90
  return [];
79
91
  }
80
92
 
@@ -0,0 +1,210 @@
1
+ import { createServer, } from "node:http";
2
+ import { backendDebug } from "../shared/debug-log.js";
3
+ import { createMemoryReminderTraceRecorder } from "../memory/reminder-trace-recorder.js";
4
+ import { handleMemoryViewerRequest } from "../viewer/http/public-routes.js";
5
+ import { handleMemoryHookRequest } from "../transport/http/memory-hook.js";
6
+ import { createBackendMemoryObservability } from "./memory-observability.js";
7
+ import { createMemoryService } from "../memory/service.js";
8
+ import { handleHealthRequest } from "../transport/http/health.js";
9
+ import { authorized, memoryViewerSessionCookieHeader, publicErrorMessage, statusCodeFromError } from "../transport/http/request.js";
10
+ import { json } from "../transport/http/json.js";
11
+ import { createBackendState } from "./state.js";
12
+ import { TRACE_CLIENTS } from "../trace/config.js";
13
+ import { pruneExpiredTraceSessionsForClient } from "../trace/store.js";
14
+ import { startMemoryWritebackReconciler } from "../memory/writeback-reconciler.js";
15
+ import { createMemoryWritebackTaskProjection } from "../memory/writeback-task-projection.js";
16
+ import { readActiveManagedClients } from "../lifecycle/active-clients.js";
17
+ const DEFAULT_BACKEND_SHUTDOWN_TIMEOUT_MS = 4_000;
18
+ export function createBackendServer(state = createBackendState(), options = {}) {
19
+ const memoryEnv = { ...process.env, MEMORAX_CODE_HOME: state.sessionHome };
20
+ const memoryWritebackTaskProjections = TRACE_CLIENTS.map((client) => createMemoryWritebackTaskProjection({
21
+ memoraxCodeHome: state.sessionHome,
22
+ client,
23
+ }));
24
+ const memoryObservability = createBackendMemoryObservability(state.sessionHome, options.memoryObservability, memoryEnv, memoryWritebackTaskProjections.map((projection) => projection.observabilityHook));
25
+ const memoryService = createMemoryService({
26
+ diagnosticLogger: backendDebug,
27
+ env: memoryEnv,
28
+ memoraxCodeHome: state.sessionHome,
29
+ memoryObservability,
30
+ });
31
+ const memoryHookDependencies = {
32
+ memoryService,
33
+ memoryReminderTraceRecorder: createMemoryReminderTraceRecorder({
34
+ diagnosticLogger: backendDebug,
35
+ env: memoryEnv,
36
+ memoraxCodeHome: state.sessionHome,
37
+ }),
38
+ };
39
+ for (const client of TRACE_CLIENTS) {
40
+ void pruneExpiredTraceSessionsForClient({
41
+ client,
42
+ memoraxCodeHome: state.sessionHome,
43
+ }).catch((error) => {
44
+ backendDebug(`${client}_trace.retention_cleanup_failed`, {
45
+ error: error instanceof Error ? error.message : String(error),
46
+ });
47
+ });
48
+ }
49
+ const memoryWritebackReconcilers = memoryWritebackTaskProjections.map((taskProjection) => (startMemoryWritebackReconciler({
50
+ memoraxCodeHome: state.sessionHome,
51
+ env: memoryEnv,
52
+ taskProjection,
53
+ })));
54
+ const handleRequest = async (req, res) => {
55
+ const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "127.0.0.1"}`);
56
+ backendDebug("http.request", {
57
+ method: req.method,
58
+ path: url.pathname,
59
+ });
60
+ try {
61
+ if (req.method === "GET" && url.pathname === "/health")
62
+ return handleHealthRequest(state, res);
63
+ if (!authorized(state, req, url))
64
+ return json(res, 401, { ok: false, error: "unauthorized" });
65
+ if (url.pathname === "/memory-viewer"
66
+ || url.pathname.startsWith("/memory-viewer/")) {
67
+ if (await handleMemoryViewerRequest(url, req, res, {
68
+ memoraxCodeHome: state.sessionHome,
69
+ claudeProjectsRoot: readActiveManagedClients(state.sessionHome)?.claude === true
70
+ ? state.claudeProjectsRoot
71
+ : false,
72
+ sessionCookie: memoryViewerSessionCookieHeader(state, req, url),
73
+ }))
74
+ return;
75
+ }
76
+ if (await handleMemoryHookRequest(memoryHookDependencies, url, req, res))
77
+ return;
78
+ return json(res, 404, { ok: false, error: "not found" });
79
+ }
80
+ catch (error) {
81
+ const status = statusCodeFromError(error);
82
+ const publicMessage = publicErrorMessage(error);
83
+ if (status >= 500)
84
+ console.error("request failed", error);
85
+ if (res.headersSent) {
86
+ return res.end();
87
+ }
88
+ return json(res, status, { ok: false, error: publicMessage });
89
+ }
90
+ };
91
+ const activeRequests = new Set();
92
+ const server = createServer((req, res) => {
93
+ const request = handleRequest(req, res);
94
+ activeRequests.add(request);
95
+ void request.then(() => activeRequests.delete(request), () => activeRequests.delete(request));
96
+ });
97
+ return attachBackendShutdown(server, {
98
+ activeRequests,
99
+ memoryObservability,
100
+ memoryService,
101
+ memoryWritebackReconcilers,
102
+ timeoutMs: positiveShutdownTimeout(options.shutdownTimeoutMs),
103
+ });
104
+ }
105
+ function attachBackendShutdown(server, resources) {
106
+ const closeHttpServer = server.close.bind(server);
107
+ const backendServer = server;
108
+ let shutdownPromise;
109
+ backendServer.shutdown = () => {
110
+ shutdownPromise ??= shutdownBackend(backendServer, closeHttpServer, resources);
111
+ return shutdownPromise;
112
+ };
113
+ backendServer.close = ((callback) => {
114
+ void backendServer.shutdown().then(() => callback?.(), (error) => callback?.(error instanceof Error ? error : new Error(String(error))));
115
+ return backendServer;
116
+ });
117
+ return backendServer;
118
+ }
119
+ async function shutdownBackend(server, closeHttpServer, resources) {
120
+ const deadline = Date.now() + resources.timeoutMs;
121
+ const reconcilerDrain = settleShutdownWork("memory_writeback_reconcilers", Promise.all(resources.memoryWritebackReconcilers.map((reconciler) => reconciler.close())));
122
+ try {
123
+ await waitForShutdownPhase("http_server", closeBackendHttpServer(server, closeHttpServer, resources.timeoutMs), deadline);
124
+ await waitForShutdownPhase("http_requests", waitForActiveRequests(resources.activeRequests), deadline);
125
+ if (Date.now() < deadline) {
126
+ await waitForShutdownPhase("memory_service", settleShutdownWork("memory_service", resources.memoryService.drain()), deadline);
127
+ }
128
+ if (Date.now() < deadline && resources.memoryObservability?.drain) {
129
+ await waitForShutdownPhase("memory_observability", settleShutdownWork("memory_observability", resources.memoryObservability.drain()), deadline);
130
+ }
131
+ await waitForShutdownPhase("background_work", reconcilerDrain, deadline);
132
+ }
133
+ finally {
134
+ resources.memoryService.close();
135
+ }
136
+ }
137
+ function closeBackendHttpServer(server, closeHttpServer, timeoutMs) {
138
+ return new Promise((resolve, reject) => {
139
+ const forceTimer = setTimeout(() => {
140
+ backendDebug("shutdown.http_connections_forced", { timeoutMs });
141
+ try {
142
+ server.closeAllConnections();
143
+ }
144
+ catch (error) {
145
+ backendDebug("shutdown.http_connections_force_failed", {
146
+ error: error instanceof Error ? error.message : String(error),
147
+ });
148
+ }
149
+ }, timeoutMs);
150
+ const done = (error) => {
151
+ clearTimeout(forceTimer);
152
+ if (error && error.code !== "ERR_SERVER_NOT_RUNNING") {
153
+ reject(error);
154
+ return;
155
+ }
156
+ resolve();
157
+ };
158
+ try {
159
+ closeHttpServer(done);
160
+ server.closeIdleConnections();
161
+ }
162
+ catch (error) {
163
+ done(error instanceof Error ? error : new Error(String(error)));
164
+ }
165
+ });
166
+ }
167
+ async function waitForActiveRequests(activeRequests) {
168
+ while (activeRequests.size > 0) {
169
+ await Promise.allSettled([...activeRequests]);
170
+ }
171
+ }
172
+ async function waitForShutdownPhase(phase, work, deadline) {
173
+ const remainingMs = deadline - Date.now();
174
+ if (remainingMs <= 0) {
175
+ backendDebug("shutdown.phase_timed_out", { phase, remainingMs: 0 });
176
+ return false;
177
+ }
178
+ let timer;
179
+ const result = await Promise.race([
180
+ work.then(() => ({ completed: true }), (error) => ({ completed: true, error })),
181
+ new Promise((resolve) => {
182
+ timer = setTimeout(() => resolve({ completed: false }), remainingMs);
183
+ }),
184
+ ]);
185
+ if (timer)
186
+ clearTimeout(timer);
187
+ if (!result.completed) {
188
+ backendDebug("shutdown.phase_timed_out", { phase, remainingMs });
189
+ return false;
190
+ }
191
+ if ("error" in result)
192
+ throw result.error;
193
+ return true;
194
+ }
195
+ async function settleShutdownWork(label, work) {
196
+ try {
197
+ await work;
198
+ }
199
+ catch (error) {
200
+ backendDebug("shutdown.work_failed", {
201
+ label,
202
+ error: error instanceof Error ? error.message : String(error),
203
+ });
204
+ }
205
+ }
206
+ function positiveShutdownTimeout(value) {
207
+ if (typeof value === "number" && Number.isSafeInteger(value) && value > 0)
208
+ return value;
209
+ return DEFAULT_BACKEND_SHUTDOWN_TIMEOUT_MS;
210
+ }
@@ -1,8 +1,8 @@
1
1
  import { randomUUID } from "node:crypto";
2
- import { backendDebug } from "./debug-log.js";
3
- import { TRACE_CLIENTS, clientTraceConfigFromEnv, } from "./trace-config.js";
4
- import { recordTraceEvent } from "./trace-store.js";
5
- import { memoryViewerObservabilityHook } from "./memory-viewer-observability.js";
2
+ import { backendDebug } from "../shared/debug-log.js";
3
+ import { TRACE_CLIENTS, clientTraceConfigFromEnv, } from "../trace/config.js";
4
+ import { recordTraceEvent } from "../trace/store.js";
5
+ import { memoryViewerObservabilityHook } from "../viewer/projection/observability.js";
6
6
  export function createBackendMemoryObservability(memoraxCodeHome, existingHook, env = process.env, additionalDefaultHooks = []) {
7
7
  if (existingHook)
8
8
  return existingHook;
@@ -1,6 +1,6 @@
1
1
  import { homedir } from "node:os";
2
2
  import { join, resolve } from "node:path";
3
- import { backendEnv } from "./backend-env.js";
3
+ import { backendEnv } from "../config/backend-env.js";
4
4
  export function createBackendState(host = "127.0.0.1", options = {}) {
5
5
  const authToken = options.authToken ?? backendEnv("TOKEN");
6
6
  const sessionHome = options.sessionHome ?? process.env.MEMORAX_CODE_HOME ?? join(homedir(), ".memorax-code");
@@ -120,10 +120,10 @@ function claudeAdapterOptions(argv, serviceOptions, backendUrl) {
120
120
  };
121
121
  }
122
122
  async function loadClaudeAdapterConfig() {
123
- return await import(new URL("../../memorax-code-claude-adapter/src/config.mjs", import.meta.url).href);
123
+ return await import(new URL("../../../../memorax-code-claude-adapter/src/config.mjs", import.meta.url).href);
124
124
  }
125
125
  async function loadClaudePluginInstaller() {
126
- return await import(new URL("../../memorax-code-claude-adapter/src/plugin-install.mjs", import.meta.url).href);
126
+ return await import(new URL("../../../../memorax-code-claude-adapter/src/plugin-install.mjs", import.meta.url).href);
127
127
  }
128
128
  function argValue(argv, name) {
129
129
  const index = argv.indexOf(name);