@memorax/memorax-code 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (242) hide show
  1. package/README.md +16 -12
  2. package/bin/memorax-code-npm-preinstall.mjs +7 -2
  3. package/bin/memorax-code-opencode.mjs +4 -0
  4. package/bin/memorax-code-plugin-postinstall.mjs +342 -93
  5. package/docs/configuration.md +148 -35
  6. package/docs/troubleshooting.md +73 -13
  7. package/lib/dsh-plugin-install.mjs +22 -0
  8. package/lib/memorax-code-adapter-common/src/hooks/capture-cwd-hook.mjs +21 -14
  9. package/lib/memorax-code-adapter-common/src/hooks/ensure-backend-runner.mjs +26 -7
  10. package/lib/memorax-code-adapter-common/src/hooks/memory-skill-reminder-hook.mjs +86 -95
  11. package/lib/memorax-code-adapter-common/src/hooks/memory-skill-reminder-policy.mjs +58 -0
  12. package/lib/memorax-code-adapter-common/src/repo-memory/repo-memory-auto-build.mjs +2 -2
  13. package/lib/memorax-code-adapter-common/src/repo-memory/repo-memory-job-supervisor.mjs +1 -1
  14. package/lib/memorax-code-adapter-common/src/windows-cli-invocation.mjs +13 -1
  15. package/lib/memorax-code-backend/dist/app/backend-server.js +210 -0
  16. package/lib/memorax-code-backend/dist/{server-observability.js → app/memory-observability.js} +4 -4
  17. package/lib/memorax-code-backend/dist/{backend-state.js → app/state.js} +1 -1
  18. package/lib/memorax-code-backend/dist/{claude-adapter-lifecycle.js → clients/claude/lifecycle.js} +2 -2
  19. package/lib/memorax-code-backend/dist/{claude-memory-hook-runtime.js → clients/claude/memory-hook-runtime.js} +7 -7
  20. package/lib/memorax-code-backend/dist/clients/codex/lifecycle.js +131 -0
  21. package/lib/memorax-code-backend/dist/{codex-memory-hook-runtime.js → clients/codex/memory-hook-runtime.js} +9 -9
  22. package/lib/memorax-code-backend/dist/{codex-plugin-hooks.js → clients/codex/plugin-hooks.js} +1 -1
  23. package/lib/memorax-code-backend/dist/{codex-plugin-install.js → clients/codex/plugin-install.js} +6 -6
  24. package/lib/memorax-code-backend/dist/clients/dsh/lifecycle.js +75 -0
  25. package/lib/memorax-code-backend/dist/clients/dsh/memory-hook-runtime.js +258 -0
  26. package/lib/memorax-code-backend/dist/clients/dsh/session-turn.js +249 -0
  27. package/lib/memorax-code-backend/dist/clients/opencode/lifecycle.js +54 -0
  28. package/lib/memorax-code-backend/dist/clients/opencode/memory-hook-runtime.js +277 -0
  29. package/lib/memorax-code-backend/dist/clients/opencode/message-turn.js +78 -0
  30. package/lib/memorax-code-backend/dist/codex-adapter-lifecycle.js +1 -131
  31. package/lib/memorax-code-backend/dist/{memorax-code-config.js → config/memorax-code.js} +32 -4
  32. package/lib/memorax-code-backend/dist/{server-cli.js → entrypoints/backend-cli.js} +137 -37
  33. package/lib/memorax-code-backend/dist/jsonl-append.js +1 -75
  34. package/lib/memorax-code-backend/dist/{active-client-selection.js → lifecycle/active-clients.js} +12 -1
  35. package/lib/memorax-code-backend/dist/{backend-service-cleanup.js → lifecycle/backend/cleanup.js} +1 -1
  36. package/lib/memorax-code-backend/dist/{backend-service-record.js → lifecycle/backend/record.js} +1 -1
  37. package/lib/memorax-code-backend/dist/{backend-service-result.js → lifecycle/backend/result.js} +2 -2
  38. package/lib/memorax-code-backend/dist/{service.js → lifecycle/backend/service.js} +16 -16
  39. package/lib/memorax-code-backend/dist/{backend-token-record.js → lifecycle/backend/token-record.js} +1 -1
  40. package/lib/memorax-code-backend/dist/{backend-service-token.js → lifecycle/backend/token.js} +2 -2
  41. package/lib/memorax-code-backend/dist/lifecycle/client-plugin-removal.js +109 -0
  42. package/lib/memorax-code-backend/dist/{client-selection.js → lifecycle/client-selection.js} +11 -5
  43. package/lib/memorax-code-backend/dist/{backend-lifecycle-lock.js → lifecycle/lock.js} +1 -1
  44. package/lib/memorax-code-backend/dist/{memorax-code-lifecycle.js → lifecycle/orchestrator.js} +325 -39
  45. package/lib/memorax-code-backend/dist/memorax-cli.js +1 -1
  46. package/lib/memorax-code-backend/dist/memorax-code.js +1 -1
  47. package/lib/memorax-code-backend/dist/{automatic-memory-retrieval.js → memory/automatic-retrieval.js} +3 -3
  48. package/lib/memorax-code-backend/dist/{automatic-memory-writeback.js → memory/automatic-writeback.js} +75 -21
  49. package/lib/memorax-code-backend/dist/{memory-cli.js → memory/cli.js} +23 -10
  50. package/lib/memorax-code-backend/dist/{memory-hook-command.js → memory/hook-command.js} +156 -9
  51. package/lib/memorax-code-backend/dist/memory/observability.js +1 -0
  52. package/lib/memorax-code-backend/dist/memory/payload-redaction.js +212 -0
  53. package/lib/memorax-code-backend/dist/{memory-reminder-trace-recorder.js → memory/reminder-trace-recorder.js} +20 -7
  54. package/lib/memorax-code-backend/dist/{repository-memory-context.js → memory/repository-session.js} +2 -2
  55. package/lib/memorax-code-backend/dist/{memory-service.js → memory/service.js} +27 -5
  56. package/lib/memorax-code-backend/dist/{memory-turn-coordinator.js → memory/turn-coordinator.js} +2 -1
  57. package/lib/memorax-code-backend/dist/{memory-writeback-buffer.js → memory/writeback-buffer.js} +3 -3
  58. package/lib/memorax-code-backend/dist/{memory-writeback-chunk.js → memory/writeback-chunk.js} +1 -1
  59. package/lib/memorax-code-backend/dist/{memory-writeback-reconciler.js → memory/writeback-reconciler.js} +6 -6
  60. package/lib/memorax-code-backend/dist/{memory-writeback-task-projection.js → memory/writeback-task-projection.js} +4 -4
  61. package/lib/memorax-code-backend/dist/{memorax-adapter.js → provider/memorax/adapter.js} +5 -5
  62. package/lib/memorax-code-backend/dist/{memorax-config.js → provider/memorax/config.js} +4 -4
  63. package/lib/memorax-code-backend/dist/{memorax-http.js → provider/memorax/http.js} +1 -1
  64. package/lib/memorax-code-backend/dist/{repo-memory-readiness.js → repository/readiness.js} +3 -3
  65. package/lib/memorax-code-backend/dist/server.js +3 -212
  66. package/lib/memorax-code-backend/dist/service-entrypoint.js +1 -1
  67. package/lib/memorax-code-backend/dist/{debug-log.js → shared/debug-log.js} +1 -1
  68. package/lib/memorax-code-backend/dist/shared/jsonl-append.js +75 -0
  69. package/lib/memorax-code-backend/dist/shared/windows-cli-invocation.js +148 -0
  70. package/lib/memorax-code-backend/dist/{trace-config.js → trace/config.js} +43 -5
  71. package/lib/memorax-code-backend/dist/{trace-context.js → trace/context.js} +53 -2
  72. package/lib/memorax-code-backend/dist/{trace-store.js → trace/store.js} +3 -3
  73. package/lib/memorax-code-backend/dist/{server-health.js → transport/http/health.js} +1 -1
  74. package/lib/memorax-code-backend/dist/{server-memory-hook.js → transport/http/memory-hook.js} +3 -3
  75. package/lib/memorax-code-backend/dist/{server-http.js → transport/http/request.js} +1 -1
  76. package/lib/memorax-code-backend/dist/{claude-local-transcript.js → viewer/history/claude-transcript.js} +3 -3
  77. package/lib/memorax-code-backend/dist/{memory-viewer-session-title.js → viewer/history/session-title.js} +1 -1
  78. package/lib/memorax-code-backend/dist/{server-memory-viewer.js → viewer/http/public-routes.js} +15 -15
  79. package/lib/memorax-code-backend/dist/viewer/model.js +1 -0
  80. package/lib/memorax-code-backend/dist/{memory-viewer-activity.js → viewer/projection/activity.js} +2 -2
  81. package/lib/memorax-code-backend/dist/{memory-viewer-history-projection.js → viewer/projection/history.js} +1 -1
  82. package/lib/memorax-code-backend/dist/{memory-viewer-observability.js → viewer/projection/observability.js} +1 -1
  83. package/lib/memorax-code-backend/dist/{memory-viewer-user-projection.js → viewer/projection/user.js} +1 -1
  84. package/lib/memorax-code-backend/dist/{memory-viewer-writeback-status.js → viewer/projection/writeback-status.js} +1 -1
  85. package/lib/memorax-code-backend/dist/{memory-viewer-store.js → viewer/store.js} +59 -32
  86. package/lib/memorax-code-backend/dist/{memory-viewer-user-html.js → viewer/ui/user-html.js} +11 -10
  87. package/lib/memorax-code-backend/dist/windows-cli-invocation.js +1 -148
  88. package/lib/memorax-code-backend/package.json +3 -3
  89. package/lib/memorax-code-claude-adapter/.claude-plugin/plugin.json +1 -1
  90. package/lib/memorax-code-claude-adapter/hooks/runtime-shell.json +1 -1
  91. package/lib/memorax-code-claude-adapter/package.json +1 -1
  92. package/lib/memorax-code-claude-adapter/skills/memorax-code/SKILL.md +11 -2
  93. package/lib/memorax-code-claude-adapter/skills/memorax-code/defaults.json +8 -5
  94. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/memorax-add.md +1 -1
  95. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/memorax-search.md +37 -9
  96. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/personal-read.md +1 -1
  97. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/personal-write.md +33 -13
  98. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/repo-build.md +62 -13
  99. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/repo-read.md +11 -4
  100. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/repo-templates.md +179 -59
  101. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/repo-update.md +18 -7
  102. package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/collect_all.py +122 -39
  103. package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/detect_updates.py +73 -10
  104. package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/github_resource_facets.py +9 -1
  105. package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +9 -1
  106. package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/validate_memory.py +23 -1
  107. package/lib/memorax-code-claude-adapter/src/plugin-install.mjs +1 -0
  108. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/.claude-plugin/plugin.json +1 -1
  109. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/hooks/runtime-shell.json +1 -1
  110. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/capture-cwd-hook.mjs +21 -14
  111. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/ensure-backend-runner.mjs +26 -7
  112. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/memory-skill-reminder-hook.mjs +86 -95
  113. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/memory-skill-reminder-policy.mjs +58 -0
  114. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/repo-memory/repo-memory-auto-build.mjs +2 -2
  115. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/repo-memory/repo-memory-job-supervisor.mjs +1 -1
  116. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/windows-cli-invocation.mjs +13 -1
  117. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/package.json +1 -1
  118. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/SKILL.md +11 -2
  119. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/defaults.json +8 -5
  120. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/memorax-add.md +1 -1
  121. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/memorax-search.md +37 -9
  122. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/personal-read.md +1 -1
  123. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/personal-write.md +33 -13
  124. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/repo-build.md +62 -13
  125. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/repo-read.md +11 -4
  126. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/repo-templates.md +179 -59
  127. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/repo-update.md +18 -7
  128. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/collect_all.py +122 -39
  129. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/detect_updates.py +73 -10
  130. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/github_resource_facets.py +9 -1
  131. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +9 -1
  132. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/validate_memory.py +23 -1
  133. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/src/plugin-install.mjs +1 -0
  134. package/lib/memorax-code-codex-adapter/.codex-plugin/plugin.json +1 -1
  135. package/lib/memorax-code-codex-adapter/hooks/runtime-shell.json +1 -1
  136. package/lib/memorax-code-codex-adapter/package.json +1 -1
  137. package/lib/memorax-code-codex-adapter/runtime-hooks/memory-skill-reminder.mjs +10 -2
  138. package/lib/memorax-code-codex-adapter/skills/memorax-code/SKILL.md +11 -2
  139. package/lib/memorax-code-codex-adapter/skills/memorax-code/defaults.json +8 -5
  140. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/memorax-add.md +1 -1
  141. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/memorax-search.md +37 -9
  142. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/personal-read.md +1 -1
  143. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/personal-write.md +33 -13
  144. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/repo-build.md +62 -13
  145. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/repo-read.md +11 -4
  146. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/repo-templates.md +179 -59
  147. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/repo-update.md +18 -7
  148. package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/collect_all.py +122 -39
  149. package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/detect_updates.py +73 -10
  150. package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/github_resource_facets.py +9 -1
  151. package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +9 -1
  152. package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/validate_memory.py +23 -1
  153. package/lib/memorax-code-dsh-adapter/cordis.patch.yml +10 -0
  154. package/lib/memorax-code-dsh-adapter/hooks/repo-memory-job.mjs +68 -0
  155. package/lib/memorax-code-dsh-adapter/package.json +69 -0
  156. package/lib/memorax-code-dsh-adapter/skills/memorax-code/SKILL.md +91 -0
  157. package/lib/memorax-code-dsh-adapter/skills/memorax-code/agents/claude.yaml +10 -0
  158. package/lib/memorax-code-dsh-adapter/skills/memorax-code/agents/openai.yaml +7 -0
  159. package/lib/memorax-code-dsh-adapter/skills/memorax-code/defaults.json +12 -0
  160. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/memorax-add.md +86 -0
  161. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/memorax-search.md +91 -0
  162. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/personal-read.md +46 -0
  163. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/personal-write.md +120 -0
  164. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/repo-build.md +319 -0
  165. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/repo-read.md +103 -0
  166. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/repo-templates.md +390 -0
  167. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/repo-update.md +127 -0
  168. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/collect_all.py +579 -0
  169. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/detect_updates.py +919 -0
  170. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/git_commit_facets.py +222 -0
  171. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/github_resource_facets.py +512 -0
  172. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +517 -0
  173. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/prepare_repo_memory.py +411 -0
  174. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/user_profile_memory.py +528 -0
  175. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/validate_memory.py +248 -0
  176. package/lib/memorax-code-dsh-adapter/src/backend-client.mjs +119 -0
  177. package/lib/memorax-code-dsh-adapter/src/dsh-message.mjs +32 -0
  178. package/lib/memorax-code-dsh-adapter/src/dsh-version.mjs +18 -0
  179. package/lib/memorax-code-dsh-adapter/src/http-client.mjs +55 -0
  180. package/lib/memorax-code-dsh-adapter/src/index.mjs +72 -0
  181. package/lib/memorax-code-dsh-adapter/src/personal-context-worker.mjs +48 -0
  182. package/lib/memorax-code-dsh-adapter/src/personal-context.mjs +114 -0
  183. package/lib/memorax-code-dsh-adapter/src/plugin.mjs +724 -0
  184. package/lib/memorax-code-dsh-adapter/src/profile-lifecycle.mjs +1358 -0
  185. package/lib/memorax-code-dsh-adapter/src/protocol.mjs +145 -0
  186. package/lib/memorax-code-dsh-adapter/src/runtime-state.mjs +132 -0
  187. package/lib/memorax-code-opencode-adapter/hooks/repo-memory-job.mjs +37 -0
  188. package/lib/memorax-code-opencode-adapter/package.json +10 -0
  189. package/lib/memorax-code-opencode-adapter/skills/memorax-code/SKILL.md +91 -0
  190. package/lib/memorax-code-opencode-adapter/skills/memorax-code/agents/claude.yaml +10 -0
  191. package/lib/memorax-code-opencode-adapter/skills/memorax-code/agents/openai.yaml +7 -0
  192. package/lib/memorax-code-opencode-adapter/skills/memorax-code/defaults.json +12 -0
  193. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/memorax-add.md +86 -0
  194. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/memorax-search.md +91 -0
  195. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/personal-read.md +46 -0
  196. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/personal-write.md +120 -0
  197. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/repo-build.md +319 -0
  198. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/repo-read.md +103 -0
  199. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/repo-templates.md +390 -0
  200. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/repo-update.md +127 -0
  201. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/collect_all.py +579 -0
  202. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/detect_updates.py +919 -0
  203. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/git_commit_facets.py +222 -0
  204. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/github_resource_facets.py +512 -0
  205. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +517 -0
  206. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/prepare_repo_memory.py +411 -0
  207. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/user_profile_memory.py +528 -0
  208. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/validate_memory.py +248 -0
  209. package/lib/memorax-code-opencode-adapter/src/adapter-paths.mjs +37 -0
  210. package/lib/memorax-code-opencode-adapter/src/cli.mjs +260 -0
  211. package/lib/memorax-code-opencode-adapter/src/diagnostics.mjs +31 -0
  212. package/lib/memorax-code-opencode-adapter/src/plugin-install.mjs +673 -0
  213. package/lib/memorax-code-opencode-adapter/src/plugin.mjs +539 -0
  214. package/lib/memorax-code-opencode-adapter/src/repo-memory-server-runner.mjs +442 -0
  215. package/lib/run-entrypoint.mjs +6 -0
  216. package/package.json +7 -3
  217. package/lib/memorax-code-backend/dist/client-plugin-removal.js +0 -67
  218. /package/lib/memorax-code-backend/dist/{claude-transcript-turn.js → clients/claude/transcript-turn.js} +0 -0
  219. /package/lib/memorax-code-backend/dist/{codex-effective-prompt.js → clients/codex/effective-prompt.js} +0 -0
  220. /package/lib/memorax-code-backend/dist/{codex-rollout-turn.js → clients/codex/rollout-turn.js} +0 -0
  221. /package/lib/memorax-code-backend/dist/{codex-session-turn-index.js → clients/codex/session-turn-index.js} +0 -0
  222. /package/lib/memorax-code-backend/dist/{codex-workspace-links.js → clients/codex/workspace-links.js} +0 -0
  223. /package/lib/memorax-code-backend/dist/{backend-env.js → config/backend-env.js} +0 -0
  224. /package/lib/memorax-code-backend/dist/{proxy-env.js → config/proxy-env.js} +0 -0
  225. /package/lib/memorax-code-backend/dist/{entrypoint.js → entrypoints/main.js} +0 -0
  226. /package/lib/memorax-code-backend/dist/{backend-process.js → lifecycle/backend/process.js} +0 -0
  227. /package/lib/memorax-code-backend/dist/{backend-shutdown-request.js → lifecycle/backend/shutdown-request.js} +0 -0
  228. /package/lib/memorax-code-backend/dist/{backend-status.js → lifecycle/backend/status.js} +0 -0
  229. /package/lib/memorax-code-backend/dist/{adapter-lifecycle-participant.js → lifecycle/contracts.js} +0 -0
  230. /package/lib/memorax-code-backend/dist/{install-watchdog.js → lifecycle/install-watchdog.js} +0 -0
  231. /package/lib/memorax-code-backend/dist/{memory-observability.js → lifecycle/participant.js} +0 -0
  232. /package/lib/memorax-code-backend/dist/{memory-project.js → memory/project.js} +0 -0
  233. /package/lib/memorax-code-backend/dist/{repository-memory-scope.js → repository/scope.js} +0 -0
  234. /package/lib/memorax-code-backend/dist/{incremental-jsonl-projection.js → shared/incremental-jsonl-projection.js} +0 -0
  235. /package/lib/memorax-code-backend/dist/{utils.js → shared/record.js} +0 -0
  236. /package/lib/memorax-code-backend/dist/{server-json.js → transport/http/json.js} +0 -0
  237. /package/lib/memorax-code-backend/dist/{memory-viewer-data-projection-cache.js → viewer/projection/cache.js} +0 -0
  238. /package/lib/memorax-code-backend/dist/{memory-viewer-event-identity.js → viewer/projection/event-identity.js} +0 -0
  239. /package/lib/memorax-code-backend/dist/{memory-viewer-redaction.js → viewer/projection/redaction.js} +0 -0
  240. /package/lib/memorax-code-backend/dist/{memory-viewer-turn-reference.js → viewer/projection/turn-reference.js} +0 -0
  241. /package/lib/memorax-code-backend/dist/{memory-viewer-icon.js → viewer/ui/icon.js} +0 -0
  242. /package/lib/memorax-code-backend/dist/{memory-viewer-logo.js → viewer/ui/logo.js} +0 -0
@@ -18,8 +18,10 @@ import {
18
18
  normalizeMemoraxMemoryOutputLanguage,
19
19
  } from "../lib/memorax-code-adapter-common/src/memorax-defaults.mjs";
20
20
  import { stagePackagedClientHookRuntime } from "../lib/client-hook-runtime.mjs";
21
+ import { discoverDshProfiles } from "../lib/dsh-plugin-install.mjs";
21
22
  import { ensureClaudeCommandEnv } from "../lib/resolve-claude-command.mjs";
22
23
  import { ensureCodexCommandEnv } from "../lib/resolve-codex-command.mjs";
24
+ import { commandOnPath } from "../lib/vscode-extension-command.mjs";
23
25
  import { resolveWindowsCliInvocation } from "../lib/windows-cli-invocation.mjs";
24
26
 
25
27
  const PLUGIN_NAME = "memorax-code-codex-adapter";
@@ -30,14 +32,17 @@ const HOOK_TRUST_SELECTION_ENV = "MEMORAX_CODE_CODEX_HOOK_TRUST_SELECTION_JSON";
30
32
  const PREFIX = "[MemoraX Code Install]:";
31
33
  const BACKEND_PREFIX = "[MemoraX Code Backend]:";
32
34
  const GREEN = "\x1b[32m";
35
+ const BRIGHT_CYAN = "\x1b[96m";
33
36
  const BLUE = "\x1b[34m";
34
37
  const RED = "\x1b[31m";
35
38
  const BOLD = "\x1b[1m";
39
+ const UNDERLINE = "\x1b[4m";
36
40
  const RESET = "\x1b[0m";
37
41
 
38
42
  if (truthyEnv(process.env.MEMORAX_CODE_SKIP_POSTINSTALL)) process.exit(0);
39
43
  const skipCodexPluginInstall = truthyEnv(process.env.MEMORAX_CODE_SKIP_CODEX_PLUGIN_INSTALL);
40
44
  const skipClaudeAdapterInstall = truthyEnv(process.env.MEMORAX_CODE_SKIP_CLAUDE_ADAPTER_INSTALL);
45
+ const skipOpenCodeAdapterInstall = truthyEnv(process.env.MEMORAX_CODE_SKIP_OPENCODE_ADAPTER_INSTALL);
41
46
 
42
47
  const scriptDir = dirname(fileURLToPath(import.meta.url));
43
48
  const memoraxCodeBin = join(scriptDir, "memorax-code.mjs");
@@ -52,6 +57,19 @@ const scriptedAnswers = (canPrompt() || canPromptForUpdate()) && process.stdin.i
52
57
  ? parseScriptedAnswers(readFileSync(0, "utf8"))
53
58
  : undefined;
54
59
  const previousClients = readPersistedClientSelection();
60
+ const persistedDshSelection = readPersistedDshSelection();
61
+ let dshProfiles = [];
62
+ let dshProfilesVerified = true;
63
+ try {
64
+ dshProfiles = discoverDshProfiles();
65
+ } catch (error) {
66
+ dshProfilesVerified = false;
67
+ const code = typeof error?.code === "string" ? ` (${error.code})` : "";
68
+ logRed(`DeepSeek Harness Profile discovery could not be verified${code}; DSH setup was skipped, but other client setup will continue.`);
69
+ }
70
+ const dshSelected = dshProfilesVerified
71
+ && dshProfiles.length > 0
72
+ && persistedDshSelection !== false;
55
73
  if (seedMissingMemoraxCodeConfig() === "failed") {
56
74
  printPostinstallSummary("not-verified");
57
75
  process.exit(0);
@@ -70,7 +88,7 @@ try {
70
88
  process.exit(0);
71
89
  }
72
90
  runCommonPreflight();
73
- const requestedClients = ["codex", "claude"];
91
+ const requestedClients = ["codex", "claude", "opencode"];
74
92
  const codexPreflight = requestedClients.includes("codex") && !skipCodexPluginInstall
75
93
  ? runCodexPreflight({
76
94
  integrationSelected: !updatePostinstall
@@ -85,18 +103,31 @@ const claudePreflight = requestedClients.includes("claude") && !skipClaudeAdapte
85
103
  || previousClients.includes("claude"),
86
104
  })
87
105
  : { ok: true };
106
+ const opencodePreflight = requestedClients.includes("opencode") && !skipOpenCodeAdapterInstall
107
+ ? runOpenCodePreflight({
108
+ integrationSelected: !updatePostinstall
109
+ || previousClients === undefined
110
+ || previousClients.includes("opencode"),
111
+ })
112
+ : { ok: true };
88
113
  const detectedClients = requestedClients.filter((client) => {
89
114
  if (client === "codex") return !skipCodexPluginInstall && codexPreflight.ok;
90
- return !skipClaudeAdapterInstall && claudePreflight.ok;
115
+ if (client === "claude") return !skipClaudeAdapterInstall && claudePreflight.ok;
116
+ return !skipOpenCodeAdapterInstall && opencodePreflight.ok;
91
117
  });
92
118
  const selectedClients = updatePostinstall && previousClients !== undefined
93
119
  ? await chooseUpdateClients(previousClients, detectedClients, scriptedAnswers)
94
120
  : detectedClients;
95
121
  const installClients = detectedClients.filter((client) => selectedClients.includes(client));
96
122
  if (updatePostinstall && previousClients !== undefined) {
97
- log(clientSelectionMessage(selectedClients));
123
+ log(clientSelectionMessage(selectedClients, { dshSelected }));
98
124
  } else {
99
- log(detectedClientMessage(installClients));
125
+ log(detectedClientMessage(installClients, dshSelected ? dshProfiles : []));
126
+ }
127
+ if (dshSelected) {
128
+ log(`DeepSeek Harness profiles: found (${dshProfiles.map((profile) => profile.name).join(", ")}); supported profiles will be reconciled by \`memorax-code start\`.`);
129
+ } else if (dshProfiles.length > 0) {
130
+ log("DeepSeek Harness profiles were detected, but the DSH integration is disabled by [clients].dsh.");
100
131
  }
101
132
  if (requestedClients.includes("codex") && !skipCodexPluginInstall && !codexPreflight.ok) {
102
133
  log("Codex runtime was not detected; skipping its adapter setup.");
@@ -104,13 +135,18 @@ if (requestedClients.includes("codex") && !skipCodexPluginInstall && !codexPrefl
104
135
  if (requestedClients.includes("claude") && !skipClaudeAdapterInstall && !claudePreflight.ok) {
105
136
  log("Claude Code runtime was not detected; skipping its adapter setup.");
106
137
  }
138
+ if (requestedClients.includes("opencode") && !skipOpenCodeAdapterInstall && !opencodePreflight.ok) {
139
+ log("OpenCode runtime or configuration was not detected; skipping its adapter setup.");
140
+ }
107
141
  if (writeClientSelectionConfig(selectedClients) === "failed") {
108
142
  printPostinstallSummary("not-verified");
109
143
  process.exit(0);
110
144
  }
111
- const clientMode = clientModeFor(installClients);
145
+ const clientMode = clientModeFor(installClients, {
146
+ includeDsh: dshProfilesVerified && persistedDshSelection !== false,
147
+ });
112
148
  let memoraxConfigResult = "skipped";
113
- if (installClients.length > 0) {
149
+ if (installClients.length > 0 || dshSelected) {
114
150
  memoraxConfigResult = await maybeConfigureMemoraxMemory(scriptedAnswers);
115
151
  }
116
152
  if (memoraxConfigResult === "configured") {
@@ -121,6 +157,7 @@ if (memoraxConfigResult === "configured") {
121
157
  }
122
158
  const codexClientEnabled = installClients.includes("codex");
123
159
  const claudeClientEnabled = installClients.includes("claude");
160
+ const opencodeClientEnabled = installClients.includes("opencode");
124
161
  const codexClientNewlyEnabled = codexClientEnabled
125
162
  && updatePostinstall
126
163
  && previousClients !== undefined
@@ -147,6 +184,7 @@ if (codexClientEnabled && result.status === 0) {
147
184
  }
148
185
  const skipCodexAdapter = !codexClientEnabled;
149
186
  const skipClaudeAdapter = !claudeClientEnabled;
187
+ const skipOpenCodeAdapter = !opencodeClientEnabled;
150
188
  const codexSkipReason = postinstallClientSkipReason({
151
189
  explicitlySkipped: skipCodexPluginInstall,
152
190
  selected: selectedClients.includes("codex"),
@@ -157,21 +195,39 @@ const claudeSkipReason = postinstallClientSkipReason({
157
195
  selected: selectedClients.includes("claude"),
158
196
  enabled: claudeClientEnabled,
159
197
  });
198
+ const opencodeSkipReason = postinstallClientSkipReason({
199
+ explicitlySkipped: skipOpenCodeAdapterInstall,
200
+ selected: selectedClients.includes("opencode"),
201
+ enabled: opencodeClientEnabled,
202
+ });
160
203
 
161
- let backendAndAdaptersStatus = startBackendAndCheck({
204
+ const backendAndAdapters = startBackendAndCheck({
162
205
  skipCodexAdapter,
163
206
  clientMode,
164
207
  codexSkipReason,
165
208
  skipClaudeAdapter,
166
209
  claudeAdapterRequired: !skipClaudeAdapter,
167
210
  claudeSkipReason,
211
+ skipOpenCodeAdapter,
212
+ opencodeAdapterRequired: !skipOpenCodeAdapter,
213
+ opencodeSkipReason,
168
214
  });
215
+ const backendAndAdaptersStatus = backendAndAdapters.status;
169
216
  if (backendAndAdaptersStatus === "enabled") {
170
217
  logGreen(`Client Hook runtime ${stagedHookRuntime.generationId} activated.`);
171
218
  }
172
219
  if (backendAndAdaptersStatus === "enabled") {
173
- printNextSteps({ codexAdapterEnabled: !skipCodexAdapter, claudeAdapterEnabled: !skipClaudeAdapter });
174
- printCommonCommands({ codexAdapterEnabled: !skipCodexAdapter, claudeAdapterEnabled: !skipClaudeAdapter });
220
+ printNextSteps({
221
+ codexAdapterEnabled: !skipCodexAdapter,
222
+ claudeAdapterEnabled: !skipClaudeAdapter,
223
+ dshAdapterEnabled: backendAndAdapters.dshAdapterEnabled,
224
+ opencodeAdapterEnabled: !skipOpenCodeAdapter,
225
+ });
226
+ printCommonCommands({
227
+ codexAdapterEnabled: !skipCodexAdapter,
228
+ claudeAdapterEnabled: !skipClaudeAdapter,
229
+ opencodeAdapterEnabled: !skipOpenCodeAdapter,
230
+ });
175
231
  }
176
232
  printPostinstallSummary(backendAndAdaptersStatus);
177
233
  if (backendAndAdaptersStatus === "enabled") {
@@ -183,26 +239,31 @@ process.exit(0);
183
239
 
184
240
  async function maybeConfigureMemoraxMemory(scriptedAnswers) {
185
241
  printMemoraxDisclosure();
186
- if (!canPrompt()) {
242
+ const promptAvailable = canPrompt();
243
+ if (promptAvailable && readMemoraxInstallStatus()?.configured) {
244
+ log("Existing MemoraX credentials detected; keeping the effective configuration unchanged.");
245
+ return "preserved";
246
+ }
247
+ if (!promptAvailable) {
187
248
  log(`This install cannot prompt for a MemoraX ID and key. Register at ${MEMORAX_ACCOUNT_URL}, then edit \`~/.memorax-code/config.toml\` or rerun interactively with \`--foreground-scripts\`.`);
188
249
  return "skipped";
189
250
  }
190
251
  if (scriptedAnswers) {
191
252
  return await configureMemoraxMemoryFromAnswers(scriptedAnswers);
192
253
  }
254
+ printMemoraxRegistrationLink();
255
+ printMemoraxUserIdGuidance();
193
256
  let rl = createInterface({ input: process.stdin, output: process.stderr });
194
257
  try {
195
- const configureNow = await rl.question(`${PREFIX} Connect MemoraX Code to MemoraX now? [Y/n] `);
196
- if (/^n(?:o)?$/i.test(configureNow.trim())) {
197
- log("MemoraX connection skipped. MemoraX Code memory is not fully configured until valid credentials are supplied.");
198
- return "skipped";
199
- }
200
- log(`If you do not have a MemoraX account/API key, register at ${MEMORAX_ACCOUNT_URL}.`);
201
- const userId = (await rl.question(`${PREFIX} MemoraX base user ID: `)).trim();
258
+ const userId = await questionRequiredLine(
259
+ rl,
260
+ `${PREFIX} Your MemoraX user ID (required, e.g. your-name): `,
261
+ "MemoraX user ID is required.",
262
+ );
202
263
  const outputLanguage = await questionPreferredLanguage(rl);
203
264
  rl.close();
204
265
  rl = undefined;
205
- const apiKey = (await questionMasked(`${PREFIX} MemoraX API key: `)).trim();
266
+ const apiKey = await questionRequiredMasked(`${PREFIX} MemoraX API key (required): `);
206
267
  return await writeMemoraxConfigFromInput({
207
268
  userId,
208
269
  apiKey,
@@ -221,7 +282,7 @@ async function chooseUpdateClients(previousClients, detectedClients, scriptedAns
221
282
 
222
283
  if (!canPromptForUpdate()) {
223
284
  for (const client of availableDisabledClients) {
224
- const label = client === "codex" ? "Codex" : "Claude Code";
285
+ const label = clientLabel(client);
225
286
  log(`${label} runtime is available, but its integration remains disabled because this update cannot prompt. Rerun \`memorax-code update\` from an interactive terminal to choose whether to enable it.`);
226
287
  }
227
288
  return [...previousClients];
@@ -230,7 +291,7 @@ async function chooseUpdateClients(previousClients, detectedClients, scriptedAns
230
291
  let rl;
231
292
  try {
232
293
  for (const client of availableDisabledClients) {
233
- const label = client === "codex" ? "Codex" : "Claude Code";
294
+ const label = clientLabel(client);
234
295
  const question = `${label} runtime is available, but its integration is disabled in [clients]. Enable it now? [Y/n]`;
235
296
  let answer;
236
297
  if (scriptedAnswers) {
@@ -250,32 +311,31 @@ async function chooseUpdateClients(previousClients, detectedClients, scriptedAns
250
311
  } finally {
251
312
  rl?.close();
252
313
  }
253
- return ["codex", "claude"].filter((client) => selected.has(client));
314
+ return ["codex", "claude", "opencode"].filter((client) => selected.has(client));
254
315
  }
255
316
 
256
317
  async function configureMemoraxMemoryFromAnswers(answers) {
257
- if (answers.length === 0) {
258
- log(`No MemoraX connection response was received. Register at ${MEMORAX_ACCOUNT_URL}, then edit \`~/.memorax-code/config.toml\` or rerun interactively with \`--foreground-scripts\`.`);
259
- return "skipped";
260
- }
261
- log("Connect MemoraX Code to MemoraX now? [Y/n]");
262
- const configureNow = String(answers.shift() ?? "").trim();
263
- if (/^n(?:o)?$/i.test(configureNow)) {
264
- log("MemoraX connection skipped. MemoraX Code memory is not fully configured until valid credentials are supplied.");
265
- return "skipped";
266
- }
267
- log(`If you do not have a MemoraX account/API key, register at ${MEMORAX_ACCOUNT_URL}.`);
268
- log("MemoraX base user ID: <provided>");
269
- const userId = String(answers.shift() ?? "").trim();
270
- const outputLanguageAnswer = String(answers.shift() ?? "").trim();
271
- log(`Preferred language [ZH/en] (used for Memory extraction): ${outputLanguageAnswer ? "<provided>" : "<default>"}`);
272
- log("MemoraX API key: <provided>");
273
- const apiKey = String(answers.shift() ?? "").trim();
318
+ printMemoraxRegistrationLink();
319
+ printMemoraxUserIdGuidance();
320
+ const userId = requiredScriptedAnswer(answers, {
321
+ prompt: "Your MemoraX user ID (required, e.g. your-name)",
322
+ requiredMessage: "MemoraX user ID is required.",
323
+ missingMessage: "No MemoraX user ID response was received; MemoraX configuration is incomplete.",
324
+ });
325
+ if (!userId) return "skipped";
326
+ const outputLanguage = scriptedPreferredLanguage(answers);
327
+ if (!outputLanguage) return "skipped";
328
+ const apiKey = requiredScriptedAnswer(answers, {
329
+ prompt: "MemoraX API key (required)",
330
+ requiredMessage: "MemoraX API key is required.",
331
+ missingMessage: "No MemoraX API key response was received; MemoraX configuration is incomplete.",
332
+ });
333
+ if (!apiKey) return "skipped";
274
334
  return await writeMemoraxConfigFromInput({
275
335
  userId,
276
336
  apiKey,
277
337
  endpoint: memoraxInstallEndpoint(),
278
- outputLanguage: preferredLanguage(outputLanguageAnswer),
338
+ outputLanguage,
279
339
  });
280
340
  }
281
341
 
@@ -285,9 +345,19 @@ function printMemoraxDisclosure() {
285
345
  log("Newly generated configuration enables automatic writeback. Existing configuration is never enabled implicitly; disable it with `[memory.writeback] enabled = false` or `MEMORAX_CODE_MEMORAX_WRITEBACK_ENABLED=false`.");
286
346
  }
287
347
 
348
+ function printMemoraxUserIdGuidance() {
349
+ log("MemoraX uses one user ID to keep your coding memories consistent across supported agents and devices.");
350
+ log("Choose a stable ID and use the same value everywhere; MemoraX Code separates repositories automatically.");
351
+ }
352
+
353
+ function printMemoraxRegistrationLink() {
354
+ log("No MemoraX account or API key yet?");
355
+ log(`→ Register here: ${BRIGHT_CYAN}${BOLD}${UNDERLINE}${MEMORAX_ACCOUNT_URL}${RESET}`);
356
+ }
357
+
288
358
  async function writeMemoraxConfigFromInput({ userId, apiKey, endpoint, outputLanguage }) {
289
359
  if (!userId || !apiKey) {
290
- logRed("MemoraX config was not written because base user ID or API key was empty.");
360
+ logRed("MemoraX config was not written because MemoraX user ID or API key was empty.");
291
361
  return "skipped";
292
362
  }
293
363
  if (!outputLanguage) {
@@ -303,6 +373,45 @@ async function writeMemoraxConfigFromInput({ userId, apiKey, endpoint, outputLan
303
373
  return "configured";
304
374
  }
305
375
 
376
+ async function questionRequiredLine(rl, prompt, requiredMessage) {
377
+ while (true) {
378
+ const answer = (await rl.question(prompt)).trim();
379
+ if (answer) return answer;
380
+ logRed(requiredMessage);
381
+ }
382
+ }
383
+
384
+ async function questionRequiredMasked(prompt) {
385
+ while (true) {
386
+ const answer = (await questionMasked(prompt)).trim();
387
+ if (answer) return answer;
388
+ logRed("MemoraX API key is required.");
389
+ }
390
+ }
391
+
392
+ function requiredScriptedAnswer(answers, { prompt, requiredMessage, missingMessage }) {
393
+ while (answers.length > 0) {
394
+ const answer = String(answers.shift() ?? "").trim();
395
+ log(`${prompt}: ${answer ? "<provided>" : "<empty>"}`);
396
+ if (answer) return answer;
397
+ logRed(requiredMessage);
398
+ }
399
+ logRed(missingMessage);
400
+ return undefined;
401
+ }
402
+
403
+ function scriptedPreferredLanguage(answers) {
404
+ while (answers.length > 0) {
405
+ const answer = String(answers.shift() ?? "").trim();
406
+ log(`Preferred language [ZH/en] (used for Memory extraction): ${answer ? "<provided>" : "<default>"}`);
407
+ const language = preferredLanguage(answer);
408
+ if (language) return language;
409
+ logRed("Preferred language must be zh or en.");
410
+ }
411
+ logRed("No preferred language response was received; MemoraX configuration is incomplete.");
412
+ return undefined;
413
+ }
414
+
306
415
  async function questionPreferredLanguage(rl) {
307
416
  while (true) {
308
417
  const answer = await rl.question(`${PREFIX} Preferred language [ZH/en] (used for Memory extraction): `);
@@ -602,7 +711,22 @@ function readPersistedClientSelection() {
602
711
  try {
603
712
  const clients = parse(readFileSync(path, "utf8"))?.clients;
604
713
  if (!clients || typeof clients !== "object" || typeof clients.codex !== "boolean" || typeof clients.claude !== "boolean") return undefined;
605
- return [clients.codex ? "codex" : undefined, clients.claude ? "claude" : undefined].filter(Boolean);
714
+ return [
715
+ clients.codex ? "codex" : undefined,
716
+ clients.claude ? "claude" : undefined,
717
+ clients.opencode === true ? "opencode" : undefined,
718
+ ].filter(Boolean);
719
+ } catch {
720
+ return undefined;
721
+ }
722
+ }
723
+
724
+ function readPersistedDshSelection() {
725
+ const path = memoraxCodeConfigPath();
726
+ if (!existsSync(path)) return undefined;
727
+ try {
728
+ const value = parse(readFileSync(path, "utf8"))?.clients?.dsh;
729
+ return typeof value === "boolean" ? value : undefined;
606
730
  } catch {
607
731
  return undefined;
608
732
  }
@@ -620,7 +744,8 @@ function writeClientSelectionConfig(clients) {
620
744
  }
621
745
 
622
746
  function setManagedClientSelection(text, clients) {
623
- const withClaude = setTomlField(text, "clients", "claude", String(clients.includes("claude")));
747
+ const withOpenCode = setTomlField(text, "clients", "opencode", String(clients.includes("opencode")));
748
+ const withClaude = setTomlField(withOpenCode, "clients", "claude", String(clients.includes("claude")));
624
749
  return setTomlField(withClaude, "clients", "codex", String(clients.includes("codex")));
625
750
  }
626
751
 
@@ -668,6 +793,8 @@ function defaultMemoraxCodeConfig() {
668
793
  "[clients]",
669
794
  "codex = true # Manage the Codex adapter.",
670
795
  "claude = true # Manage the Claude adapter.",
796
+ "dsh = true # Manage the DeepSeek Harness adapter when Profiles exist.",
797
+ "opencode = true # Manage the OpenCode adapter.",
671
798
  "",
672
799
  "# MemoraX remote-memory connection. Credentials may also come from the environment.",
673
800
  "[memorax]",
@@ -687,7 +814,7 @@ function defaultMemoraxCodeConfig() {
687
814
  "[memory.add]",
688
815
  `output_language = "${MEMORAX_DEFAULT_MEMORY_OUTPUT_LANGUAGE}" # Language for newly generated MemoraX memories.`,
689
816
  "",
690
- "# Controls how often Codex and Claude Code native client sessions see the MemoraX Code skill reminder.",
817
+ "# Controls how often supported native client sessions see the MemoraX Code skill reminder.",
691
818
  "[memory.skill_reminder]",
692
819
  "interval_turns = 5 # Show the MemoraX Code skill reminder every N native client turns, starting on the first turn.",
693
820
  "",
@@ -706,6 +833,14 @@ function defaultMemoraxCodeConfig() {
706
833
  "enabled = true # Enable local Claude session memory trace collection.",
707
834
  "capture_content = true # Store content in local Claude trace events.",
708
835
  "",
836
+ "[trace.dsh]",
837
+ "enabled = true # Enable local DSH session memory trace collection.",
838
+ "capture_content = true # Store content in local DSH trace events.",
839
+ "",
840
+ "[trace.opencode]",
841
+ "enabled = true # Enable local OpenCode session memory trace collection.",
842
+ "capture_content = true # Store content in local OpenCode trace events.",
843
+ "",
709
844
  ].join("\n");
710
845
  }
711
846
 
@@ -769,10 +904,13 @@ function runCommonPreflight() {
769
904
  const memoraxCodeVersion = runNodeMemoraxCodeCommand(["--version"], { print: false });
770
905
  log(`MemoraX Code backend package: ${commandSummary(memoraxCodeVersion) ?? packageVersionSummary()}`);
771
906
  if (skipCodexPluginInstall) {
772
- log("Codex plugin registration is disabled for this npm postinstall; backend and Claude Code setup can still continue.");
907
+ log("Codex plugin registration is disabled for this npm postinstall; other client setup can still continue.");
773
908
  }
774
909
  if (skipClaudeAdapterInstall) {
775
- log("Claude Code adapter setup is disabled for this npm postinstall; backend and Codex setup can still continue.");
910
+ log("Claude Code adapter setup is disabled for this npm postinstall; other client setup can still continue.");
911
+ }
912
+ if (skipOpenCodeAdapterInstall) {
913
+ log("OpenCode adapter setup is disabled for this npm postinstall; other client setup can still continue.");
776
914
  }
777
915
  return {};
778
916
  }
@@ -812,6 +950,27 @@ function runClaudePreflight({ integrationSelected = true } = {}) {
812
950
  return { ok: true };
813
951
  }
814
952
 
953
+ function runOpenCodePreflight({ integrationSelected = true } = {}) {
954
+ const explicitConfigDir = stringOption(process.env.OPENCODE_CONFIG_DIR);
955
+ const configHome = stringOption(process.env.XDG_CONFIG_HOME) ?? join(homedir(), ".config");
956
+ const configDir = resolve(explicitConfigDir ?? join(configHome, "opencode"));
957
+ const configDetected = explicitConfigDir !== undefined || existsSync(configDir);
958
+ const cliDetected = commandOnPath(
959
+ "opencode",
960
+ process.env.PATH,
961
+ process.platform,
962
+ process.env.PATHEXT,
963
+ );
964
+ const detected = configDetected || cliDetected;
965
+ log(`OpenCode configuration: ${configDetected ? `found (${configDir})` : "not detected"}`);
966
+ log(`OpenCode CLI: ${cliDetected ? "found in PATH" : "not detected"}`);
967
+ if (!detected) return { ok: false };
968
+ log(integrationSelected
969
+ ? "Keeping OpenCode provider config unchanged and enabling the shared memory plugin integration."
970
+ : "Keeping OpenCode provider config unchanged while checking whether to enable its integration.");
971
+ return { ok: true };
972
+ }
973
+
815
974
  function installedPluginCache() {
816
975
  for (const marketplaceName of [CLI_MARKETPLACE_NAME, PERSONAL_MARKETPLACE_NAME]) {
817
976
  const versions = installedPluginCacheVersions(marketplaceName);
@@ -835,7 +994,17 @@ function installedPluginCacheVersions(marketplaceName) {
835
994
  }
836
995
  }
837
996
 
838
- function startBackendAndCheck({ skipCodexAdapter = false, clientMode = "all", codexSkipReason, skipClaudeAdapter = false, claudeAdapterRequired = !skipClaudeAdapter, claudeSkipReason } = {}) {
997
+ function startBackendAndCheck({
998
+ skipCodexAdapter = false,
999
+ clientMode = "all",
1000
+ codexSkipReason,
1001
+ skipClaudeAdapter = false,
1002
+ claudeAdapterRequired = !skipClaudeAdapter,
1003
+ claudeSkipReason,
1004
+ skipOpenCodeAdapter = false,
1005
+ opencodeAdapterRequired = !skipOpenCodeAdapter,
1006
+ opencodeSkipReason,
1007
+ } = {}) {
839
1008
  logGreen("Starting backend with `memorax-code start`...");
840
1009
  const adapterFlags = clientLifecycleFlags({ clientMode });
841
1010
  const startArgs = ["start", ...adapterFlags];
@@ -847,18 +1016,18 @@ function startBackendAndCheck({ skipCodexAdapter = false, clientMode = "all", co
847
1016
  if (clientHookRuntimeActivationFailed(started)) {
848
1017
  logRed("Client Hook runtime activation failed; automatic lifecycle recovery was skipped.");
849
1018
  logRed("The previously active runtime remains authoritative.");
850
- return "not-verified";
1019
+ return { status: "not-verified", dshAdapterEnabled: false };
851
1020
  }
852
1021
  if (lifecycleLockFailureCode(started)) {
853
1022
  logRed("Automatic stop/start recovery is skipped because another MemoraX Code lifecycle command still owns the Backend authority.");
854
1023
  printLifecycleLockFailureSuggestions();
855
- return "not-verified";
1024
+ return { status: "not-verified", dshAdapterEnabled: false };
856
1025
  }
857
1026
  const runtimeAuthorityFailure = runtimeAuthorityFailureCode(started);
858
1027
  if (runtimeAuthorityFailure) {
859
1028
  logRed("Automatic stop/start recovery is skipped because persisted Backend runtime authority requires explicit repair.");
860
1029
  printRuntimeAuthorityFailureSuggestions(runtimeAuthorityFailure);
861
- return "not-verified";
1030
+ return { status: "not-verified", dshAdapterEnabled: false };
862
1031
  }
863
1032
  logRed("Attempting automatic recovery: `memorax-code stop` then `memorax-code start`...");
864
1033
  runMemoraxCodeCommand(["stop", ...adapterFlags]);
@@ -869,7 +1038,7 @@ function startBackendAndCheck({ skipCodexAdapter = false, clientMode = "all", co
869
1038
  logRed("Diagnostic: running `memorax-code status` so the failure is visible.");
870
1039
  runMemoraxCodeCommand(statusArgs);
871
1040
  printFailureSuggestions();
872
- return "not-verified";
1041
+ return { status: "not-verified", dshAdapterEnabled: false };
873
1042
  }
874
1043
  }
875
1044
  logGreen(recovered ? "Backend start completed after automatic recovery." : "Backend start completed.");
@@ -878,19 +1047,27 @@ function startBackendAndCheck({ skipCodexAdapter = false, clientMode = "all", co
878
1047
  if (checked.status !== 0) {
879
1048
  logRed("Backend status check failed during npm postinstall.");
880
1049
  printFailureSuggestions();
881
- return "not-verified";
1050
+ return { status: "not-verified", dshAdapterEnabled: false };
882
1051
  }
883
1052
  logGreen("Backend status check completed.");
884
1053
  const enabled = memoraxCodeEnabled(checked, {
885
1054
  codexAdapterRequired: !skipCodexAdapter,
886
1055
  claudeAdapterRequired,
1056
+ opencodeAdapterRequired,
887
1057
  });
888
1058
  if (!enabled) {
889
- if (skipCodexAdapter || skipClaudeAdapter) printSkippedAdapterDiagnostics({ codexSkipReason, claudeSkipReason });
890
- else printUnavailableDiagnostics();
891
- return "unavailable";
1059
+ printUnavailableDiagnostics({ codexSkipReason, claudeSkipReason, opencodeSkipReason });
1060
+ return { status: "unavailable", dshAdapterEnabled: false };
892
1061
  }
893
- return "enabled";
1062
+ return {
1063
+ status: "enabled",
1064
+ dshAdapterEnabled: dshAdapterReady(checked),
1065
+ };
1066
+ }
1067
+
1068
+ function dshAdapterReady(statusResult) {
1069
+ const output = `${statusResult.stdout ?? ""}\n${statusResult.stderr ?? ""}`;
1070
+ return /\bDSH adapter:\s*ok\b[^\r\n]*\bintegration=plugin\b/im.test(stripAnsi(output));
894
1071
  }
895
1072
 
896
1073
  function pendingClientHookRuntimeEnv() {
@@ -929,13 +1106,12 @@ function clientLifecycleFlags({ clientMode = "all" } = {}) {
929
1106
  return ["--clients", clientMode];
930
1107
  }
931
1108
 
932
- function clientModeFor(clients) {
933
- const hasCodex = clients.includes("codex");
934
- const hasClaude = clients.includes("claude");
935
- if (hasCodex && hasClaude) return "all";
936
- if (hasCodex) return "codex";
937
- if (hasClaude) return "claude";
938
- return "none";
1109
+ function clientModeFor(clients, { includeDsh = false } = {}) {
1110
+ const selected = ["codex", "claude", "dsh", "opencode"].filter((client) => (
1111
+ client === "dsh" ? includeDsh : clients.includes(client)
1112
+ ));
1113
+ if (selected.length === 4) return "all";
1114
+ return selected.length > 0 ? selected.join(",") : "none";
939
1115
  }
940
1116
 
941
1117
  function postinstallClientSkipReason({ explicitlySkipped, selected, enabled }) {
@@ -944,22 +1120,51 @@ function postinstallClientSkipReason({ explicitlySkipped, selected, enabled }) {
944
1120
  return enabled ? undefined : "client-selection";
945
1121
  }
946
1122
 
947
- function clientSelectionMessage(clients) {
1123
+ function clientSelectionMessage(clients, { dshSelected = false } = {}) {
1124
+ if (dshSelected) {
1125
+ const labels = [
1126
+ clients.includes("codex") ? "Codex" : undefined,
1127
+ clients.includes("claude") ? "Claude Code" : undefined,
1128
+ "DeepSeek Harness",
1129
+ clients.includes("opencode") ? "OpenCode" : undefined,
1130
+ ].filter(Boolean);
1131
+ return `Configuring MemoraX Code for ${joinedLabels(labels)}.`;
1132
+ }
948
1133
  const hasCodex = clients.includes("codex");
949
1134
  const hasClaude = clients.includes("claude");
1135
+ const hasOpenCode = clients.includes("opencode");
1136
+ if (hasCodex && hasClaude && hasOpenCode) return "Configuring MemoraX Code for Codex, Claude Code, and OpenCode.";
950
1137
  if (hasCodex && hasClaude) return "Configuring MemoraX Code for Codex and Claude Code.";
1138
+ if (hasCodex && hasOpenCode) return "Configuring MemoraX Code for Codex and OpenCode.";
1139
+ if (hasClaude && hasOpenCode) return "Configuring MemoraX Code for Claude Code and OpenCode.";
951
1140
  if (hasCodex) return "Configuring MemoraX Code for Codex only.";
952
1141
  if (hasClaude) return "Configuring MemoraX Code for Claude Code only.";
1142
+ if (hasOpenCode) return "Configuring MemoraX Code for OpenCode only.";
953
1143
  return "Skipping client adapter setup for this npm postinstall.";
954
1144
  }
955
1145
 
956
- function detectedClientMessage(clients) {
957
- if (clients.length === 0) {
1146
+ function clientLabel(client) {
1147
+ if (client === "codex") return "Codex";
1148
+ if (client === "claude") return "Claude Code";
1149
+ return "OpenCode";
1150
+ }
1151
+
1152
+ function detectedClientMessage(clients, dshProfiles = []) {
1153
+ if (clients.length === 0 && dshProfiles.length === 0) {
958
1154
  return "No supported client runtime was detected; starting the shared Backend without client adapters.";
959
1155
  }
1156
+ if (clients.length === 0) {
1157
+ return "Detected existing DeepSeek Harness profiles; configuring the native DSH plugin and shared Backend.";
1158
+ }
960
1159
  return `Detected supported client runtimes. ${clientSelectionMessage(clients)}`;
961
1160
  }
962
1161
 
1162
+ function joinedLabels(labels) {
1163
+ if (labels.length < 2) return labels[0] ?? "";
1164
+ if (labels.length === 2) return `${labels[0]} and ${labels[1]}`;
1165
+ return `${labels.slice(0, -1).join(", ")}, and ${labels.at(-1)}`;
1166
+ }
1167
+
963
1168
  function codexHome() {
964
1169
  return process.env.CODEX_HOME || join(homedir(), ".codex");
965
1170
  }
@@ -1087,35 +1292,65 @@ function codexClientRunning() {
1087
1292
  });
1088
1293
  }
1089
1294
 
1090
- function printNextSteps({ codexAdapterEnabled = true, claudeAdapterEnabled = true } = {}) {
1091
- const clientText = enabledClientText({ codexAdapterEnabled, claudeAdapterEnabled });
1092
- if (clientText && updatePostinstall) {
1295
+ function printNextSteps({
1296
+ codexAdapterEnabled = true,
1297
+ claudeAdapterEnabled = true,
1298
+ dshAdapterEnabled = false,
1299
+ opencodeAdapterEnabled = true,
1300
+ } = {}) {
1301
+ const hookClientText = enabledClientText({
1302
+ codexAdapterEnabled,
1303
+ claudeAdapterEnabled,
1304
+ opencodeAdapterEnabled,
1305
+ });
1306
+ if (hookClientText && updatePostinstall) {
1093
1307
  logGreen(`${bold("The new Hook runtime is active")}; existing sessions with the stable shell select it on their next user prompt.`);
1094
- log(`Restart or refresh ${clientText} only if its plugin shell was installed, changed, or newly enabled, or if MemoraX Code is not active on the next prompt.`);
1095
- } else if (clientText) {
1096
- logGreen(`${bold(`Restart or refresh ${clientText}`)} before opening a new MemoraX Code session.`);
1097
- } else {
1308
+ log(`Restart or refresh ${hookClientText} only if its plugin shell was installed, changed, or newly enabled, or if MemoraX Code is not active on the next prompt.`);
1309
+ } else if (hookClientText) {
1310
+ logGreen(`${bold(`Restart or refresh ${hookClientText}`)} before opening a new MemoraX Code session.`);
1311
+ }
1312
+ if (dshAdapterEnabled) {
1313
+ logGreen(`${bold("Restart or refresh DeepSeek Harness")} so its Profiles load the installed MemoraX Code plugin.`);
1314
+ } else if (!hookClientText) {
1098
1315
  logGreen(`${bold("MemoraX Code backend is running")}; client adapters were skipped for this install.`);
1099
1316
  }
1100
1317
  if (codexAdapterEnabled && !updatePostinstall) {
1101
1318
  logGreen(`After restart, ${bold("enable the MemoraX Code Codex Adapter plugin")} from Codex Plugins or CLI \`/plugins\` if it is not already enabled.`);
1102
1319
  }
1103
- const statusCommands = statusCommandText({ codexAdapterEnabled, claudeAdapterEnabled });
1104
- log(`If MemoraX Code is not active ${updatePostinstall ? "on the next prompt" : "in new sessions"}, run ${statusCommands}.`);
1320
+ const statusCommands = statusCommandText({ codexAdapterEnabled, claudeAdapterEnabled, opencodeAdapterEnabled });
1321
+ if (hookClientText || !dshAdapterEnabled) {
1322
+ log(`If MemoraX Code is not active ${updatePostinstall ? "on the next prompt" : "in new sessions"}, run ${statusCommands}.`);
1323
+ }
1324
+ if (dshAdapterEnabled) {
1325
+ log("If MemoraX Code is not active after restarting or refreshing DeepSeek Harness, run `memorax-code status`.");
1326
+ }
1105
1327
  log("If npm hides install details, reinstall with `--foreground-scripts`.");
1106
1328
  }
1107
1329
 
1108
- function enabledClientText({ codexAdapterEnabled = true, claudeAdapterEnabled = true } = {}) {
1109
- if (codexAdapterEnabled && claudeAdapterEnabled) return "Codex or Claude Code";
1110
- if (codexAdapterEnabled) return "Codex";
1111
- if (claudeAdapterEnabled) return "Claude Code";
1112
- return "";
1113
- }
1114
-
1115
- function statusCommandText({ codexAdapterEnabled = true, claudeAdapterEnabled = true } = {}) {
1330
+ function enabledClientText({
1331
+ codexAdapterEnabled = true,
1332
+ claudeAdapterEnabled = true,
1333
+ opencodeAdapterEnabled = true,
1334
+ } = {}) {
1335
+ const labels = [
1336
+ codexAdapterEnabled ? "Codex" : undefined,
1337
+ claudeAdapterEnabled ? "Claude Code" : undefined,
1338
+ opencodeAdapterEnabled ? "OpenCode" : undefined,
1339
+ ].filter(Boolean);
1340
+ if (labels.length < 2) return labels[0] ?? "";
1341
+ if (labels.length === 2) return `${labels[0]} or ${labels[1]}`;
1342
+ return `${labels.slice(0, -1).join(", ")}, or ${labels.at(-1)}`;
1343
+ }
1344
+
1345
+ function statusCommandText({
1346
+ codexAdapterEnabled = true,
1347
+ claudeAdapterEnabled = true,
1348
+ opencodeAdapterEnabled = true,
1349
+ } = {}) {
1116
1350
  const commands = ["`memorax-code status`"];
1117
1351
  if (codexAdapterEnabled) commands.push("`memorax-code-codex status`");
1118
1352
  if (claudeAdapterEnabled) commands.push("`memorax-code-claude status`");
1353
+ if (opencodeAdapterEnabled) commands.push("`memorax-code-opencode status`");
1119
1354
  if (commands.length === 1) return commands[0];
1120
1355
  if (commands.length === 2) return `${commands[0]} and ${commands[1]}`;
1121
1356
  return `${commands.slice(0, -1).join(", ")}, and ${commands.at(-1)}`;
@@ -1195,19 +1430,17 @@ function readMemoraxInstallStatus() {
1195
1430
  }
1196
1431
  }
1197
1432
 
1198
- function printUnavailableDiagnostics() {
1433
+ function printUnavailableDiagnostics({ codexSkipReason, claudeSkipReason, opencodeSkipReason } = {}) {
1199
1434
  logRed("MemoraX Code is not enabled for new client sessions.");
1200
- logRed("Check `memorax-code status`, `memorax-code-codex status`, and `memorax-code-claude status` for Backend and adapter details.");
1201
- logRed("If Codex or Claude Code is open, restart or refresh it after fixing the reported status.");
1202
- printCommonCommands();
1203
- }
1204
-
1205
- function printSkippedAdapterDiagnostics({ codexSkipReason, claudeSkipReason } = {}) {
1435
+ logRed("Check `memorax-code status`, `memorax-code-codex status`, `memorax-code-claude status`, and `memorax-code-opencode status` for Backend and adapter details.");
1436
+ logRed("If Codex, Claude Code, or OpenCode is open, restart or refresh it after fixing the reported status.");
1206
1437
  if (codexSkipReason) printCodexSkippedDiagnostics(codexSkipReason);
1207
1438
  if (claudeSkipReason) printClaudeSkippedDiagnostics(claudeSkipReason);
1439
+ if (opencodeSkipReason) printOpenCodeSkippedDiagnostics(opencodeSkipReason);
1208
1440
  printCommonCommands({
1209
1441
  codexAdapterEnabled: !codexSkipReason,
1210
1442
  claudeAdapterEnabled: !claudeSkipReason,
1443
+ opencodeAdapterEnabled: !opencodeSkipReason,
1211
1444
  });
1212
1445
  }
1213
1446
 
@@ -1223,10 +1456,15 @@ function printClaudeSkippedDiagnostics() {
1223
1456
  log("Run `memorax-code start` after installing Claude Code, then restart or refresh Claude Code.");
1224
1457
  }
1225
1458
 
1459
+ function printOpenCodeSkippedDiagnostics() {
1460
+ logRed("OpenCode adapter setup was skipped for this npm postinstall, so MemoraX Code left the OpenCode integration unchanged.");
1461
+ log("Run `memorax-code start --clients opencode` after installing OpenCode, then restart or refresh OpenCode.");
1462
+ }
1463
+
1226
1464
  function printFailureSuggestions() {
1227
1465
  logRed("Suggested recovery: run `memorax-code stop`, then `memorax-code start`, then `memorax-code status`.");
1228
1466
  logRed("If the Backend port is busy, stop the process using 127.0.0.1:8787 and retry `memorax-code start`.");
1229
- logRed("If client sessions still bypass MemoraX Code, restart or refresh Codex or Claude Code and verify the relevant adapter status.");
1467
+ logRed("If client sessions still bypass MemoraX Code, restart or refresh the affected client and verify the relevant adapter status.");
1230
1468
  printCommonCommands();
1231
1469
  }
1232
1470
 
@@ -1248,7 +1486,11 @@ function printLifecycleLockFailureSuggestions() {
1248
1486
  printCommonCommands();
1249
1487
  }
1250
1488
 
1251
- function printCommonCommands({ codexAdapterEnabled = true, claudeAdapterEnabled = true } = {}) {
1489
+ function printCommonCommands({
1490
+ codexAdapterEnabled = true,
1491
+ claudeAdapterEnabled = true,
1492
+ opencodeAdapterEnabled = true,
1493
+ } = {}) {
1252
1494
  log("Common commands:");
1253
1495
  log("- `memorax-code status`: check the local backend and adapter state.");
1254
1496
  log("- `memorax-cli status`: check required MemoraX configuration and effective memory switches.");
@@ -1256,9 +1498,14 @@ function printCommonCommands({ codexAdapterEnabled = true, claudeAdapterEnabled
1256
1498
  log("- `memorax-code stop`: stop the local memory backend and disable managed client integrations.");
1257
1499
  if (codexAdapterEnabled) log("- `memorax-code-codex sessions`: verify recent native Codex session registration.");
1258
1500
  if (claudeAdapterEnabled) log("- `memorax-code-claude sessions`: verify recent native Claude Code session registration.");
1501
+ if (opencodeAdapterEnabled) log("- `memorax-code-opencode doctor`: verify the managed OpenCode plugin, runtime evidence, and Backend health.");
1259
1502
  }
1260
1503
 
1261
- function memoraxCodeEnabled(statusResult, { codexAdapterRequired = true, claudeAdapterRequired = true } = {}) {
1504
+ function memoraxCodeEnabled(statusResult, {
1505
+ codexAdapterRequired = true,
1506
+ claudeAdapterRequired = true,
1507
+ opencodeAdapterRequired = true,
1508
+ } = {}) {
1262
1509
  const output = `${statusResult.stdout ?? ""}\n${statusResult.stderr ?? ""}`;
1263
1510
  const normalized = stripAnsi(output);
1264
1511
  const backendOk = /MemoraX Code Backend status:\s*Enabled\b/im.test(normalized)
@@ -1268,10 +1515,12 @@ function memoraxCodeEnabled(statusResult, { codexAdapterRequired = true, claudeA
1268
1515
  || /Backend:\s*(?:running|ok)\b/im.test(normalized);
1269
1516
  const codexAdapterOk = /Codex adapter:\s*ok\b/im.test(normalized);
1270
1517
  const claudeAdapterOk = /Claude adapter:\s*ok\b/im.test(normalized);
1518
+ const opencodeAdapterOk = /OpenCode adapter:\s*ok\b/im.test(normalized);
1271
1519
  return backendOk
1272
1520
  && serviceOk
1273
1521
  && (!codexAdapterRequired || codexAdapterOk)
1274
- && (!claudeAdapterRequired || claudeAdapterOk);
1522
+ && (!claudeAdapterRequired || claudeAdapterOk)
1523
+ && (!opencodeAdapterRequired || opencodeAdapterOk);
1275
1524
  }
1276
1525
 
1277
1526
  function log(message) {