@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
@@ -1,131 +1 @@
1
- import { createInterface } from "node:readline/promises";
2
- import { installCodexPlugin, isCodexPluginActive, isCodexPluginStaged, removeCodexPlugin, } from "./codex-plugin-install.js";
3
- const BACKEND_PREFIX = "[MemoraX Code Backend]:";
4
- const GREEN = "\x1b[32m";
5
- const RESET = "\x1b[0m";
6
- export async function enableCodexAdapterForStart(argv, serviceOptions, backendUrl) {
7
- try {
8
- let options = codexAdapterOptions(argv, serviceOptions, backendUrl);
9
- const codexHome = typeof options.codexHome === "string" ? options.codexHome : undefined;
10
- if (!isCodexPluginActive({ codexHome }) && !isCodexPluginStaged({ codexHome })) {
11
- const installed = await maybeInstallCodexPluginForStart(argv);
12
- if (installed) {
13
- backendLog(green("Codex plugin source registered. Activate the MemoraX Code Codex Adapter plugin, then restart or refresh Codex."));
14
- }
15
- else if (installed === false) {
16
- return codexPluginNotInstalled();
17
- }
18
- }
19
- options = codexAdapterOptions(argv, serviceOptions, backendUrl);
20
- if (!isCodexPluginActive({ codexHome })) {
21
- return isCodexPluginStaged({ codexHome })
22
- ? codexPluginActivationRequired()
23
- : codexPluginNotInstalled();
24
- }
25
- return (await loadCodexAdapterConfig()).enableCodexAdapter(options);
26
- }
27
- catch (error) {
28
- return { ok: false, action: "enable", error: error instanceof Error ? error.message : String(error) };
29
- }
30
- }
31
- export async function readCodexAdapterStatusForLifecycle(argv, serviceOptions, backendUrl) {
32
- try {
33
- return (await loadCodexAdapterConfig()).readCodexAdapterStatus(codexAdapterOptions(argv, serviceOptions, backendUrl));
34
- }
35
- catch (error) {
36
- return { ok: false, action: "status", error: error instanceof Error ? error.message : String(error) };
37
- }
38
- }
39
- export async function disableCodexAdapterForLifecycle(argv, serviceOptions) {
40
- try {
41
- return (await loadCodexAdapterConfig()).disableCodexAdapter(codexAdapterOptions(argv, serviceOptions));
42
- }
43
- catch (error) {
44
- return { ok: false, action: "disable", error: error instanceof Error ? error.message : String(error) };
45
- }
46
- }
47
- export const codexAdapterLifecycle = {
48
- status: ({ argv, serviceOptions, backendUrl }) => (readCodexAdapterStatusForLifecycle(argv, serviceOptions, backendUrl)),
49
- prepareEnable: ({ argv, serviceOptions, backendUrl }) => (enableCodexAdapterForStart(argv, serviceOptions, backendUrl)),
50
- disable: ({ argv, serviceOptions }) => (disableCodexAdapterForLifecycle(argv, serviceOptions)),
51
- remove: ({ argv }) => removeCodexPlugin(codexPluginRemoveOptions(argv)),
52
- };
53
- function codexAdapterOptions(argv, serviceOptions, backendUrl) {
54
- const codexHome = argValue(argv, "--codex-home");
55
- return {
56
- ...(codexHome ? { codexHome } : {}),
57
- memoraxCodeHome: serviceOptions.home,
58
- ...(backendUrl ? { backendUrl } : {}),
59
- };
60
- }
61
- function codexPluginNotInstalled() {
62
- return {
63
- ok: true,
64
- action: "enable",
65
- skipped: true,
66
- reason: "codex_plugin_not_installed",
67
- message: "Codex plugin is not installed; run `memorax-code codex-plugin install`, then activate it and rerun `memorax-code start`.",
68
- };
69
- }
70
- function codexPluginActivationRequired() {
71
- return {
72
- ok: true,
73
- action: "enable",
74
- skipped: true,
75
- reason: "codex_plugin_activation_required",
76
- message: "Codex plugin source is registered but not active; run `memorax-code codex-plugin activate --yes`, then rerun `memorax-code start`.",
77
- };
78
- }
79
- async function maybeInstallCodexPluginForStart(argv) {
80
- if (argv.includes("--json"))
81
- return undefined;
82
- if (argv.includes("--yes")) {
83
- await installCodexPlugin(codexPluginInstallOptions(argv));
84
- return true;
85
- }
86
- if (!canPromptOnStdin())
87
- return undefined;
88
- const rl = createInterface({ input: process.stdin, output: process.stdout });
89
- try {
90
- const answer = await rl.question(`${BACKEND_PREFIX} Install MemoraX Code Codex Adapter plugin now? [y/N] `);
91
- if (!process.stdout.isTTY)
92
- process.stdout.write("\n");
93
- if (!/^y(?:es)?$/i.test(answer.trim()))
94
- return false;
95
- await installCodexPlugin(codexPluginInstallOptions(argv));
96
- return true;
97
- }
98
- finally {
99
- rl.close();
100
- }
101
- }
102
- function codexPluginInstallOptions(argv) {
103
- return {
104
- codexHome: argValue(argv, "--codex-home"),
105
- marketplacePath: argValue(argv, "--marketplace-path"),
106
- pluginSourcePath: argValue(argv, "--plugin-source-path"),
107
- codexCommand: argValue(argv, "--codex-command"),
108
- };
109
- }
110
- function codexPluginRemoveOptions(argv) {
111
- return {
112
- ...codexPluginInstallOptions(argv),
113
- workspace: argValue(argv, "--workspace"),
114
- };
115
- }
116
- function canPromptOnStdin() {
117
- return process.stdin.isTTY === true;
118
- }
119
- function backendLog(message) {
120
- console.log(`${BACKEND_PREFIX} ${message}`);
121
- }
122
- function green(value) {
123
- return `${GREEN}${value}${RESET}`;
124
- }
125
- function argValue(argv, name) {
126
- const index = argv.indexOf(name);
127
- return index >= 0 ? argv[index + 1] : undefined;
128
- }
129
- async function loadCodexAdapterConfig() {
130
- return await import(new URL("../../memorax-code-codex-adapter/src/config.mjs", import.meta.url).href);
131
- }
1
+ export * from "./clients/codex/lifecycle.js";
@@ -3,8 +3,8 @@ import { writeFile } from "node:fs/promises";
3
3
  import { homedir } from "node:os";
4
4
  import { join } from "node:path";
5
5
  import { parse } from "smol-toml";
6
- import { ensurePrivateConfigDirectory } from "../../memorax-code-adapter-common/src/memorax-code-config-file.mjs";
7
- import { MEMORAX_DEFAULT_BASE_URL, MEMORAX_DEFAULT_MEMORY_OUTPUT_LANGUAGE, } from "../../memorax-code-adapter-common/src/memorax-defaults.mjs";
6
+ import { ensurePrivateConfigDirectory } from "../../../memorax-code-adapter-common/src/memorax-code-config-file.mjs";
7
+ import { MEMORAX_DEFAULT_BASE_URL, MEMORAX_DEFAULT_MEMORY_OUTPUT_LANGUAGE, } from "../../../memorax-code-adapter-common/src/memorax-defaults.mjs";
8
8
  export function defaultMemoraxCodeHome(env = process.env) {
9
9
  return env.MEMORAX_CODE_HOME?.trim() || join(homedir(), ".memorax-code");
10
10
  }
@@ -22,6 +22,8 @@ export function renderDefaultMemoraxCodeConfig() {
22
22
  "[clients]",
23
23
  "codex = true",
24
24
  "claude = true",
25
+ "dsh = true",
26
+ "opencode = true",
25
27
  "",
26
28
  "# MemoraX remote-memory connection. Credentials may also come from the environment.",
27
29
  "[memorax]",
@@ -41,7 +43,7 @@ export function renderDefaultMemoraxCodeConfig() {
41
43
  "[memory.add]",
42
44
  `output_language = "${MEMORAX_DEFAULT_MEMORY_OUTPUT_LANGUAGE}" # Language for newly generated MemoraX memories.`,
43
45
  "",
44
- "# Controls how often Codex and Claude Code native client sessions see the MemoraX Code skill reminder.",
46
+ "# Controls how often supported native client sessions see the MemoraX Code skill reminder.",
45
47
  "[memory.skill_reminder]",
46
48
  "interval_turns = 5 # Show the MemoraX Code skill reminder every N native client turns, starting on the first turn.",
47
49
  "",
@@ -60,6 +62,14 @@ export function renderDefaultMemoraxCodeConfig() {
60
62
  "enabled = true # Enable local Claude session memory trace collection.",
61
63
  "capture_content = true # Store content in local Claude trace events.",
62
64
  "",
65
+ "[trace.dsh]",
66
+ "enabled = true # Enable local DSH session memory trace collection.",
67
+ "capture_content = true # Store content in local DSH trace events.",
68
+ "",
69
+ "[trace.opencode]",
70
+ "enabled = true # Enable local OpenCode session memory trace collection.",
71
+ "capture_content = true # Store content in local OpenCode trace events.",
72
+ "",
63
73
  ].join("\n");
64
74
  }
65
75
  export async function seedMissingMemoraxCodeConfig(memoraxCodeHome = defaultMemoraxCodeHome(process.env)) {
@@ -134,10 +144,14 @@ function normalizeMemoraxCodeConfig(value) {
134
144
  const repoUpdate = recordValue(memory?.repo_update);
135
145
  const traceCodex = recordValue(trace?.codex);
136
146
  const traceClaude = recordValue(trace?.claude);
147
+ const traceDsh = recordValue(trace?.dsh);
148
+ const traceOpenCode = recordValue(trace?.opencode);
137
149
  return (prune({
138
150
  clients: prune({
139
151
  codex: booleanField(clients, "codex"),
140
152
  claude: booleanField(clients, "claude"),
153
+ dsh: booleanField(clients, "dsh"),
154
+ opencode: booleanField(clients, "opencode"),
141
155
  }),
142
156
  memorax: prune({
143
157
  endpoint: stringField(memorax, "endpoint"),
@@ -202,6 +216,20 @@ function normalizeMemoraxCodeConfig(value) {
202
216
  max_event_chars: numberField(traceClaude, "max_event_chars"),
203
217
  max_file_bytes: numberField(traceClaude, "max_file_bytes"),
204
218
  }),
219
+ dsh: prune({
220
+ enabled: booleanField(traceDsh, "enabled"),
221
+ capture_content: booleanField(traceDsh, "capture_content"),
222
+ retention_days: numberField(traceDsh, "retention_days"),
223
+ max_event_chars: numberField(traceDsh, "max_event_chars"),
224
+ max_file_bytes: numberField(traceDsh, "max_file_bytes"),
225
+ }),
226
+ opencode: prune({
227
+ enabled: booleanField(traceOpenCode, "enabled"),
228
+ capture_content: booleanField(traceOpenCode, "capture_content"),
229
+ retention_days: numberField(traceOpenCode, "retention_days"),
230
+ max_event_chars: numberField(traceOpenCode, "max_event_chars"),
231
+ max_file_bytes: numberField(traceOpenCode, "max_file_bytes"),
232
+ }),
205
233
  }),
206
234
  }) ?? {});
207
235
  }
@@ -214,7 +242,7 @@ function validateRawLifecycleConfig(value, path) {
214
242
  const clients = tableValue(rawClients);
215
243
  if (!clients)
216
244
  throw invalidLifecycleConfig(path, "clients must be a table");
217
- for (const field of ["codex", "claude"]) {
245
+ for (const field of ["codex", "claude", "dsh", "opencode"]) {
218
246
  if (clients[field] !== undefined && typeof clients[field] !== "boolean") {
219
247
  throw invalidLifecycleConfig(path, `clients.${field} must be a boolean`);
220
248
  }
@@ -1,20 +1,20 @@
1
1
  import { basename, resolve } from "node:path";
2
- import { backendServiceEndpoint, backendServiceLogs, isProcessAlive, readBackendServiceState, readBackendToken, writeBackendToken, } from "./service.js";
3
- import { BackendConnectionAuthorityError, resolveBackendConnection, } from "../../memorax-code-adapter-common/src/backend-connection.mjs";
4
- import { RuntimeRecordError, } from "../../memorax-code-adapter-common/src/runtime-record.mjs";
5
- import { activateClientHookRuntimeGeneration, CLIENT_HOOK_RUNTIME_ABI, } from "../../memorax-code-adapter-common/src/hooks/hook-runtime-generation.mjs";
6
- import { createBackendState } from "./backend-state.js";
7
- import { createBackendServer } from "./server.js";
8
- import { backendDebug } from "./debug-log.js";
9
- import { prepareClientPluginRemovalCleanup } from "./client-plugin-removal.js";
10
- import { resolveBackendInstallWatchdogConfig, startBackendInstallWatchdog, } from "./install-watchdog.js";
11
- import { activateCodexPlugin, installCodexPlugin } from "./codex-plugin-install.js";
12
- import { inspectCodexPluginHooks, trustCodexPluginHooks } from "./codex-plugin-hooks.js";
13
- import { collectMemoraxCodeStatus, isAdapterReady, isOptionalUnconfiguredClaudeAdapter, restartMemoraxCodeService, startMemoraxCodeService, stopMemoraxCodeService, uninstallMemoraxCodeService, } from "./memorax-code-lifecycle.js";
14
- import { backendEnv } from "./backend-env.js";
15
- import { backendServiceHome, BackendLifecycleLockError, withBackendLifecycleLock, } from "./backend-lifecycle-lock.js";
16
- import { startBackendShutdownRequestWatcher, } from "./backend-shutdown-request.js";
17
- import { runtimeRecordDurabilityWarning } from "./backend-service-result.js";
2
+ import { backendServiceEndpoint, backendServiceLogs, isProcessAlive, readBackendServiceState, readBackendToken, writeBackendToken, } from "../lifecycle/backend/service.js";
3
+ import { BackendConnectionAuthorityError, resolveBackendConnection, } from "../../../memorax-code-adapter-common/src/backend-connection.mjs";
4
+ import { RuntimeRecordError, } from "../../../memorax-code-adapter-common/src/runtime-record.mjs";
5
+ import { activateClientHookRuntimeGeneration, CLIENT_HOOK_RUNTIME_ABI, } from "../../../memorax-code-adapter-common/src/hooks/hook-runtime-generation.mjs";
6
+ import { createBackendState } from "../app/state.js";
7
+ import { createBackendServer } from "../app/backend-server.js";
8
+ import { backendDebug } from "../shared/debug-log.js";
9
+ import { prepareClientPluginRemovalCleanup } from "../lifecycle/client-plugin-removal.js";
10
+ import { resolveBackendInstallWatchdogConfig, startBackendInstallWatchdog, } from "../lifecycle/install-watchdog.js";
11
+ import { activateCodexPlugin, installCodexPlugin } from "../clients/codex/plugin-install.js";
12
+ import { inspectCodexPluginHooks, trustCodexPluginHooks } from "../clients/codex/plugin-hooks.js";
13
+ import { collectMemoraxCodeStatus, isAdapterReady, isOptionalUnavailableDshAdapter, isOptionalUnconfiguredClaudeAdapter, restartMemoraxCodeService, startMemoraxCodeService, stopMemoraxCodeService, uninstallMemoraxCodeService, } from "../lifecycle/orchestrator.js";
14
+ import { backendEnv } from "../config/backend-env.js";
15
+ import { backendServiceHome, BackendLifecycleLockError, withBackendLifecycleLock, } from "../lifecycle/lock.js";
16
+ import { startBackendShutdownRequestWatcher, } from "../lifecycle/backend/shutdown-request.js";
17
+ import { runtimeRecordDurabilityWarning } from "../lifecycle/backend/result.js";
18
18
  // Keep process-facing CLI orchestration outside the HTTP server module.
19
19
  // This preserves server.ts as the importable route factory used by tests and tools.
20
20
  export function runBackendCli(argv = process.argv) {
@@ -29,8 +29,9 @@ export function runBackendCli(argv = process.argv) {
29
29
  `Usage: ${usageName} [${commands}] [--backend-url URL] [--backend-token TOKEN] [--home DIR]`,
30
30
  "[--host HOST] [--port PORT] [--rotate] [--show]",
31
31
  "[--codex-command CMD]",
32
- "[--codex-home DIR] [--claude-home DIR]",
33
- "[--clients codex|claude|codex,claude|all|none]",
32
+ "[--codex-home DIR] [--claude-home DIR] [--dsh-home DIR] [--opencode-config-dir DIR]",
33
+ "[--dsh-command CMD] [--dsh-adapter-root DIR] [--memorax-code-command CMD]",
34
+ "[--clients codex|claude|dsh|opencode|CLIENT,...|all|none]",
34
35
  "[--json]",
35
36
  "[--marketplace-path FILE] [--plugin-source-path DIR] [--claude-command CMD] [--help]",
36
37
  "[--yes]",
@@ -206,8 +207,12 @@ async function startRawBackendServer(state, host, port, argv) {
206
207
  memoraxCodeHome: state.sessionHome,
207
208
  codexHome: argValue(argv, "--codex-home"),
208
209
  claudeHome: argValue(argv, "--claude-home"),
210
+ dshHome: argValue(argv, "--dsh-home"),
211
+ dshAdapterRoot: argValue(argv, "--dsh-adapter-root"),
212
+ openCodeConfigDir: argValue(argv, "--opencode-config-dir"),
209
213
  codexCommand: argValue(argv, "--codex-command"),
210
214
  claudeCommand: argValue(argv, "--claude-command"),
215
+ dshCommand: argValue(argv, "--dsh-command"),
211
216
  })
212
217
  : undefined;
213
218
  const server = createBackendServer(state);
@@ -227,6 +232,10 @@ async function startRawBackendServer(state, host, port, argv) {
227
232
  codexReason: "reason" in cleanup.codexPlugin ? cleanup.codexPlugin.reason : undefined,
228
233
  claudeOk: cleanup.claudePlugin.ok,
229
234
  claudeReason: cleanup.claudePlugin.reason,
235
+ dshOk: cleanup.dshPlugin.ok,
236
+ dshReason: cleanup.dshPlugin.reason,
237
+ opencodeOk: cleanup.opencodePlugin.ok,
238
+ opencodeReason: cleanup.opencodePlugin.reason,
230
239
  });
231
240
  }
232
241
  server.close(() => {
@@ -476,6 +485,10 @@ function printMemoraxCodeStatus(report) {
476
485
  }
477
486
  if (report.claudeAdapter)
478
487
  backendLog(`Claude adapter: ${claudeAdapterStatusLine(report.claudeAdapter, report.codexAdapter)}`);
488
+ if (report.dshAdapter)
489
+ backendLog(`DSH adapter: ${dshAdapterStatusLine(report.dshAdapter)}`);
490
+ if (report.opencodeAdapter)
491
+ backendLog(`OpenCode adapter: ${adapterStatusLine(report.opencodeAdapter)}`);
479
492
  if (!suppressBackendGuidance()) {
480
493
  for (const line of statusGuidance(report))
481
494
  backendLog(line);
@@ -559,7 +572,12 @@ function printLifecycleResult(report) {
559
572
  if (report.message)
560
573
  backendLog(report.message);
561
574
  if (report.backend) {
562
- backendLog(`Backend: ${report.backend.ok ? green(report.backend.degraded ? "ok (degraded)" : "ok") : red("not ok")}${report.backend.state?.url ? ` ${report.backend.state.url}` : ""}${report.backend.errorCode ? ` code=${report.backend.errorCode}` : ""}${report.backend.error ? ` error=${report.backend.error}` : ""}`);
575
+ const status = !report.backend.ok
576
+ ? red("not ok")
577
+ : report.backend.action === "stop"
578
+ ? green(report.backend.skipped ? "kept running" : "stopped")
579
+ : green(report.backend.degraded ? "ok (degraded)" : "ok");
580
+ backendLog(`Backend: ${status}${report.backend.state?.url ? ` ${report.backend.state.url}` : ""}${report.backend.errorCode ? ` code=${report.backend.errorCode}` : ""}${report.backend.error ? ` error=${report.backend.error}` : ""}`);
563
581
  for (const warning of report.backend.warnings ?? []) {
564
582
  backendLog(`Warning: ${warning.message}${warning.errorCode ? ` code=${warning.errorCode}` : ""}`);
565
583
  }
@@ -568,6 +586,10 @@ function printLifecycleResult(report) {
568
586
  backendLog(`Codex adapter: ${adapterStatusLine(report.codexAdapter)}`);
569
587
  if (report.claudeAdapter)
570
588
  backendLog(`Claude adapter: ${adapterStatusLine(report.claudeAdapter)}`);
589
+ if (report.dshAdapter)
590
+ backendLog(`DSH adapter: ${dshAdapterStatusLine(report.dshAdapter)}`);
591
+ if (report.opencodeAdapter)
592
+ backendLog(`OpenCode adapter: ${adapterStatusLine(report.opencodeAdapter)}`);
571
593
  if (report.codexPlugin) {
572
594
  const removed = report.codexPlugin.removedPaths.length;
573
595
  const marketplace = report.codexPlugin.marketplaceChanged ? " marketplace=updated" : " marketplace=unchanged";
@@ -623,17 +645,37 @@ function lifecycleGuidance(report) {
623
645
  "Run `memorax-code logs` for details, then retry `memorax-code start`.",
624
646
  ];
625
647
  }
626
- if (!report.codexAdapter && !report.claudeAdapter) {
648
+ if (!report.codexAdapter && !report.claudeAdapter && !report.dshAdapter && !report.opencodeAdapter) {
627
649
  return [
628
650
  green("Backend is running."),
629
651
  "Adapters were not changed for this command.",
630
652
  ];
631
653
  }
632
- if ((!report.codexAdapter || isAdapterReady(report.codexAdapter)) && (!report.claudeAdapter || isAdapterReady(report.claudeAdapter))) {
654
+ const optionalDshSkipped = isOptionalUnavailableDshAdapter(report.dshAdapter);
655
+ if ((!report.codexAdapter || isAdapterReady(report.codexAdapter))
656
+ && (!report.claudeAdapter || isAdapterReady(report.claudeAdapter))
657
+ && (!report.dshAdapter
658
+ || isAdapterReady(report.dshAdapter)
659
+ || optionalDshSkipped)
660
+ && (!report.opencodeAdapter || isAdapterReady(report.opencodeAdapter))) {
633
661
  return [
634
- green("Backend is running and adapters are enabled."),
635
- green("Existing sessions with the stable plugin shell select the active Hook runtime on their next user prompt."),
636
- "Restart or refresh a client only if its plugin shell was installed, changed, or newly enabled, or MemoraX Code is not active on the next prompt.",
662
+ green(optionalDshSkipped
663
+ && !report.codexAdapter
664
+ && !report.claudeAdapter
665
+ && !report.opencodeAdapter
666
+ ? "Backend is running; the optional DSH integration was skipped."
667
+ : "Backend is running and available client integrations are enabled."),
668
+ ...(optionalDshSkipped
669
+ ? [`DSH integration was skipped: ${report.dshAdapter?.reason ?? "not available"}.`]
670
+ : []),
671
+ ...(report.codexAdapter || report.claudeAdapter || report.opencodeAdapter
672
+ ? [
673
+ green("Existing sessions with the stable plugin shell select the active runtime on their next user prompt."),
674
+ "Restart or refresh a client only if its plugin shell changed or MemoraX Code is not active on the next prompt.",
675
+ ]
676
+ : optionalDshSkipped
677
+ ? []
678
+ : [green("New DSH sessions can use MemoraX Code through the active Profile integration.")]),
637
679
  ];
638
680
  }
639
681
  return [
@@ -642,11 +684,17 @@ function lifecycleGuidance(report) {
642
684
  ];
643
685
  }
644
686
  if (report.action === "stop") {
687
+ const backendKeptRunning = report.backend?.skipped === true
688
+ && report.backend.reason === "active_clients_remaining";
645
689
  return report.ok
646
690
  ? [
647
- green("Backend is stopped."),
691
+ green(backendKeptRunning
692
+ ? "Backend remains running for the other active client integrations."
693
+ : "Backend is stopped."),
648
694
  ...(report.codexAdapter ? [green("Codex Hook integration is stopped; provider config was not changed.")] : []),
649
695
  ...(report.claudeAdapter ? [green("Claude Code Hook integration is stopped; provider config was not changed.")] : []),
696
+ ...(report.dshAdapter ? [green("DSH Profile integration is stopped.")] : []),
697
+ ...(report.opencodeAdapter ? [green("OpenCode plugin integration is stopped; provider config was not changed.")] : []),
650
698
  ]
651
699
  : [
652
700
  red("Backend did not stop cleanly."),
@@ -657,7 +705,7 @@ function lifecycleGuidance(report) {
657
705
  return report.ok
658
706
  ? [
659
707
  green("Backend restarted."),
660
- green("Existing sessions with the stable plugin shell use the active Hook runtime on their next user prompt."),
708
+ green("Available client integrations were reconciled with the restarted Backend."),
661
709
  "Restart or refresh a client only if MemoraX Code is not active on the next prompt.",
662
710
  ]
663
711
  : [
@@ -666,22 +714,54 @@ function lifecycleGuidance(report) {
666
714
  ];
667
715
  }
668
716
  if (report.action === "uninstall") {
669
- return report.ok
670
- ? [
671
- green("MemoraX Code has been uninstalled from this npm installation."),
672
- green("Restart or refresh Codex so it drops the removed adapter plugin."),
673
- ]
674
- : [
717
+ if (!report.ok) {
718
+ return [
675
719
  red("Uninstall needs attention."),
676
720
  "Run `memorax-code status` and `memorax-code logs` before retrying.",
677
721
  ];
722
+ }
723
+ const clientName = lifecycleClientName(report);
724
+ const npmPackageRemoved = report.npmPackageRemoval?.ok === true
725
+ && report.npmPackageRemoval.skipped !== true;
726
+ const removalNoun = report.dshAdapter
727
+ ? `client integration${selectedLifecycleClientNames(report).length === 1 ? "" : "s"}`
728
+ : `adapter plugin${selectedLifecycleClientNames(report).length === 1 ? "" : "s"}`;
729
+ return [
730
+ ...(npmPackageRemoved
731
+ ? [green("MemoraX Code has been uninstalled from this npm installation.")]
732
+ : clientName
733
+ ? [green(`MemoraX Code has been uninstalled from ${clientName}.`)]
734
+ : []),
735
+ ...(clientName
736
+ ? [green(`Restart or refresh ${clientName} so it drops the removed ${removalNoun}.`)]
737
+ : []),
738
+ ];
678
739
  }
679
740
  return [];
680
741
  }
681
742
  function statusGuidance(report) {
682
743
  if (report.ok) {
744
+ const optionalDshSkipped = isOptionalUnavailableDshAdapter(report.dshAdapter);
745
+ if (report.dshAdapter
746
+ && !report.codexAdapter
747
+ && !report.claudeAdapter
748
+ && !report.opencodeAdapter) {
749
+ if (optionalDshSkipped) {
750
+ return [
751
+ green("Backend is running; the optional DSH integration was skipped."),
752
+ `DSH integration was skipped: ${report.dshAdapter.reason ?? "not available"}.`,
753
+ ];
754
+ }
755
+ return [
756
+ green("MemoraX Code is ready for new DSH sessions."),
757
+ "Restart or refresh DSH only if its Profile integration changed or MemoraX Code is not active on the next prompt.",
758
+ ];
759
+ }
683
760
  return [
684
761
  green("MemoraX Code is ready; sessions with the stable plugin shell use the active Hook runtime on their next user prompt."),
762
+ ...(optionalDshSkipped
763
+ ? [`DSH integration was skipped: ${report.dshAdapter?.reason ?? "not available"}.`]
764
+ : []),
685
765
  "Restart or refresh a client only if its plugin shell was installed, changed, or newly enabled, or MemoraX Code is not active on the next prompt.",
686
766
  ];
687
767
  }
@@ -711,6 +791,20 @@ function statusGuidance(report) {
711
791
  "Run `memorax-code start`, then restart or refresh Claude Code.",
712
792
  ];
713
793
  }
794
+ if (report.dshAdapter
795
+ && !isAdapterReady(report.dshAdapter)
796
+ && !isOptionalUnavailableDshAdapter(report.dshAdapter)) {
797
+ return [
798
+ red("DSH adapter is not enabled."),
799
+ "Run `memorax-code start`, then retry `memorax-code status`.",
800
+ ];
801
+ }
802
+ if (report.opencodeAdapter && !isAdapterReady(report.opencodeAdapter)) {
803
+ return [
804
+ red("OpenCode adapter is not enabled."),
805
+ "Run `memorax-code start`, then restart or refresh OpenCode.",
806
+ ];
807
+ }
714
808
  return [
715
809
  red("MemoraX Code needs attention."),
716
810
  "Run `memorax-code status` and `memorax-code logs` for details.",
@@ -751,10 +845,29 @@ function adapterStatusLine(report) {
751
845
  return `not ok endpoint_mismatch configured=${report.configuredBackendUrl ?? "missing"} expected=${report.expectedBackendUrl ?? "unknown"}`;
752
846
  }
753
847
  const enabled = isAdapterReady(report);
754
- const skillStatus = report.codexSkills?.status ?? report.claudeSkills?.status;
848
+ const skillStatus = report.codexSkills?.status
849
+ ?? report.claudeSkills?.status
850
+ ?? report.opencodeSkills?.status;
755
851
  const skills = skillStatus ? ` skills=${skillStatus}` : "";
756
852
  const changed = report.changed === true ? " changed" : "";
757
- return `${enabled ? "ok" : "not enabled"} integration=hooks${skills}${changed}`;
853
+ const integration = report.integration ?? report.state?.integration ?? "hooks";
854
+ return `${enabled ? "ok" : "not enabled"} integration=${integration}${skills}${changed}`;
855
+ }
856
+ function selectedLifecycleClientNames(report) {
857
+ return [
858
+ report.codexAdapter ? "Codex" : undefined,
859
+ report.claudeAdapter ? "Claude Code" : undefined,
860
+ report.dshAdapter ? "DSH" : undefined,
861
+ report.opencodeAdapter ? "OpenCode" : undefined,
862
+ ].filter((name) => name !== undefined);
863
+ }
864
+ function lifecycleClientName(report) {
865
+ const names = selectedLifecycleClientNames(report);
866
+ if (names.length < 2)
867
+ return names[0];
868
+ if (names.length === 2)
869
+ return `${names[0]} and ${names[1]}`;
870
+ return `${names.slice(0, -1).join(", ")}, and ${names.at(-1)}`;
758
871
  }
759
872
  function claudeAdapterStatusLine(report, codexAdapter) {
760
873
  if (isOptionalUnconfiguredClaudeAdapter(report, codexAdapter)) {
@@ -762,6 +875,16 @@ function claudeAdapterStatusLine(report, codexAdapter) {
762
875
  }
763
876
  return adapterStatusLine(report);
764
877
  }
878
+ function dshAdapterStatusLine(report) {
879
+ if (isOptionalUnavailableDshAdapter(report)) {
880
+ return `skipped ${report.reason ?? "not-detected"}`;
881
+ }
882
+ const version = report.version ?? report.dshVersion;
883
+ const tested = version && report.dshVersionTested !== undefined
884
+ ? ` version=${version} tested=${report.dshVersionTested}`
885
+ : "";
886
+ return `${adapterStatusLine(report)}${tested}`;
887
+ }
765
888
  function argValue(argv, name) {
766
889
  const index = argv.indexOf(name);
767
890
  if (index >= 0)
@@ -1,75 +1 @@
1
- import { open } from "node:fs/promises";
2
- const JSONL_TAIL_SCAN_CHUNK_BYTES = 8 * 1024;
3
- const pathOperations = new Map();
4
- export async function appendRepairingJsonl(path, text) {
5
- await serializePath(path, async () => {
6
- const handle = await open(path, "a+", 0o600);
7
- try {
8
- const { rollbackSize, separator } = await prepareTailForAppend(handle);
9
- try {
10
- await handle.writeFile(`${separator}${text}`, "utf8");
11
- }
12
- catch (error) {
13
- await handle.truncate(rollbackSize).catch(() => undefined);
14
- throw error;
15
- }
16
- }
17
- finally {
18
- await handle.close();
19
- }
20
- });
21
- }
22
- async function serializePath(path, operation) {
23
- const previous = pathOperations.get(path) ?? Promise.resolve();
24
- const current = previous.catch(() => undefined).then(operation);
25
- pathOperations.set(path, current);
26
- try {
27
- return await current;
28
- }
29
- finally {
30
- if (pathOperations.get(path) === current)
31
- pathOperations.delete(path);
32
- }
33
- }
34
- async function prepareTailForAppend(handle) {
35
- const size = (await handle.stat()).size;
36
- if (size === 0)
37
- return { rollbackSize: 0, separator: "" };
38
- const lastByte = Buffer.allocUnsafe(1);
39
- await readExactAt(handle, lastByte, size - 1);
40
- if (lastByte[0] === 0x0a)
41
- return { rollbackSize: size, separator: "" };
42
- const tailStart = await jsonlTailStart(handle, size);
43
- const tail = Buffer.allocUnsafe(size - tailStart);
44
- await readExactAt(handle, tail, tailStart);
45
- try {
46
- JSON.parse(tail.toString("utf8"));
47
- return { rollbackSize: size, separator: "\n" };
48
- }
49
- catch {
50
- await handle.truncate(tailStart);
51
- return { rollbackSize: tailStart, separator: "" };
52
- }
53
- }
54
- async function jsonlTailStart(handle, size) {
55
- let end = size;
56
- while (end > 0) {
57
- const start = Math.max(0, end - JSONL_TAIL_SCAN_CHUNK_BYTES);
58
- const buffer = Buffer.allocUnsafe(end - start);
59
- await readExactAt(handle, buffer, start);
60
- const newline = buffer.lastIndexOf(0x0a);
61
- if (newline >= 0)
62
- return start + newline + 1;
63
- end = start;
64
- }
65
- return 0;
66
- }
67
- async function readExactAt(handle, buffer, position) {
68
- let offset = 0;
69
- while (offset < buffer.length) {
70
- const { bytesRead } = await handle.read(buffer, offset, buffer.length - offset, position + offset);
71
- if (bytesRead === 0)
72
- throw new Error("failed to read JSONL tail");
73
- offset += bytesRead;
74
- }
75
- }
1
+ export * from "./shared/jsonl-append.js";
@@ -8,7 +8,18 @@ export function readActiveManagedClients(memoraxCodeHome) {
8
8
  const value = JSON.parse(readFileSync(path, "utf8"));
9
9
  if (typeof value.codex !== "boolean" || typeof value.claude !== "boolean")
10
10
  return undefined;
11
- return { codex: value.codex, claude: value.claude };
11
+ if (value.opencode !== undefined && typeof value.opencode !== "boolean")
12
+ return undefined;
13
+ if (value.dsh !== undefined && typeof value.dsh !== "boolean")
14
+ return undefined;
15
+ return {
16
+ codex: value.codex,
17
+ claude: value.claude,
18
+ // Records written before DSH became a Backend participant cannot claim
19
+ // that the Backend was serving DSH.
20
+ dsh: value.dsh === true,
21
+ opencode: value.opencode === true,
22
+ };
12
23
  }
13
24
  catch {
14
25
  return undefined;
@@ -1,4 +1,4 @@
1
- import { removeBackendServiceStateIfOwnedAtPath, } from "./backend-service-record.js";
1
+ import { removeBackendServiceStateIfOwnedAtPath, } from "./record.js";
2
2
  export function clearBackendServiceState(path, state, action, prefix = "failed to clear Backend service state") {
3
3
  const result = removeBackendServiceStateIfOwnedAtPath(path, state);
4
4
  if (result.disposition === "removed"
@@ -1,6 +1,6 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import { linkSync, readFileSync, rmSync, statSync, unlinkSync } from "node:fs";
3
- import { readJsonRuntimeRecord, RuntimeRecordError, writePrivateJsonRecord, } from "../../memorax-code-adapter-common/src/runtime-record.mjs";
3
+ import { readJsonRuntimeRecord, RuntimeRecordError, writePrivateJsonRecord, } from "../../../../memorax-code-adapter-common/src/runtime-record.mjs";
4
4
  export const BACKEND_SERVICE_RECORD_VERSION = 1;
5
5
  const BACKEND_SERVICE_RECORD_KEYS = new Set([
6
6
  "version",
@@ -1,5 +1,5 @@
1
- import { BackendConnectionAuthorityError } from "../../memorax-code-adapter-common/src/backend-connection.mjs";
2
- import { RuntimeRecordError, } from "../../memorax-code-adapter-common/src/runtime-record.mjs";
1
+ import { BackendConnectionAuthorityError } from "../../../../memorax-code-adapter-common/src/backend-connection.mjs";
2
+ import { RuntimeRecordError, } from "../../../../memorax-code-adapter-common/src/runtime-record.mjs";
3
3
  export function runtimeRecordServiceFailure(action, error) {
4
4
  return {
5
5
  ok: false,