@memorax/memorax-code 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (242) hide show
  1. package/README.md +16 -12
  2. package/bin/memorax-code-npm-preinstall.mjs +7 -2
  3. package/bin/memorax-code-opencode.mjs +4 -0
  4. package/bin/memorax-code-plugin-postinstall.mjs +342 -93
  5. package/docs/configuration.md +144 -35
  6. package/docs/troubleshooting.md +73 -13
  7. package/lib/dsh-plugin-install.mjs +22 -0
  8. package/lib/memorax-code-adapter-common/src/hooks/capture-cwd-hook.mjs +21 -14
  9. package/lib/memorax-code-adapter-common/src/hooks/ensure-backend-runner.mjs +26 -7
  10. package/lib/memorax-code-adapter-common/src/hooks/memory-skill-reminder-hook.mjs +86 -95
  11. package/lib/memorax-code-adapter-common/src/hooks/memory-skill-reminder-policy.mjs +58 -0
  12. package/lib/memorax-code-adapter-common/src/repo-memory/repo-memory-auto-build.mjs +2 -2
  13. package/lib/memorax-code-adapter-common/src/repo-memory/repo-memory-job-supervisor.mjs +1 -1
  14. package/lib/memorax-code-adapter-common/src/windows-cli-invocation.mjs +13 -1
  15. package/lib/memorax-code-backend/dist/app/backend-server.js +210 -0
  16. package/lib/memorax-code-backend/dist/{server-observability.js → app/memory-observability.js} +4 -4
  17. package/lib/memorax-code-backend/dist/{backend-state.js → app/state.js} +1 -1
  18. package/lib/memorax-code-backend/dist/{claude-adapter-lifecycle.js → clients/claude/lifecycle.js} +2 -2
  19. package/lib/memorax-code-backend/dist/{claude-memory-hook-runtime.js → clients/claude/memory-hook-runtime.js} +7 -7
  20. package/lib/memorax-code-backend/dist/clients/codex/lifecycle.js +131 -0
  21. package/lib/memorax-code-backend/dist/{codex-memory-hook-runtime.js → clients/codex/memory-hook-runtime.js} +9 -9
  22. package/lib/memorax-code-backend/dist/{codex-plugin-hooks.js → clients/codex/plugin-hooks.js} +1 -1
  23. package/lib/memorax-code-backend/dist/{codex-plugin-install.js → clients/codex/plugin-install.js} +6 -6
  24. package/lib/memorax-code-backend/dist/clients/dsh/lifecycle.js +75 -0
  25. package/lib/memorax-code-backend/dist/clients/dsh/memory-hook-runtime.js +258 -0
  26. package/lib/memorax-code-backend/dist/clients/dsh/session-turn.js +249 -0
  27. package/lib/memorax-code-backend/dist/clients/opencode/lifecycle.js +54 -0
  28. package/lib/memorax-code-backend/dist/clients/opencode/memory-hook-runtime.js +277 -0
  29. package/lib/memorax-code-backend/dist/clients/opencode/message-turn.js +78 -0
  30. package/lib/memorax-code-backend/dist/codex-adapter-lifecycle.js +1 -131
  31. package/lib/memorax-code-backend/dist/{memorax-code-config.js → config/memorax-code.js} +32 -4
  32. package/lib/memorax-code-backend/dist/{server-cli.js → entrypoints/backend-cli.js} +137 -37
  33. package/lib/memorax-code-backend/dist/jsonl-append.js +1 -75
  34. package/lib/memorax-code-backend/dist/{active-client-selection.js → lifecycle/active-clients.js} +12 -1
  35. package/lib/memorax-code-backend/dist/{backend-service-cleanup.js → lifecycle/backend/cleanup.js} +1 -1
  36. package/lib/memorax-code-backend/dist/{backend-service-record.js → lifecycle/backend/record.js} +1 -1
  37. package/lib/memorax-code-backend/dist/{backend-service-result.js → lifecycle/backend/result.js} +2 -2
  38. package/lib/memorax-code-backend/dist/{service.js → lifecycle/backend/service.js} +16 -16
  39. package/lib/memorax-code-backend/dist/{backend-token-record.js → lifecycle/backend/token-record.js} +1 -1
  40. package/lib/memorax-code-backend/dist/{backend-service-token.js → lifecycle/backend/token.js} +2 -2
  41. package/lib/memorax-code-backend/dist/lifecycle/client-plugin-removal.js +109 -0
  42. package/lib/memorax-code-backend/dist/{client-selection.js → lifecycle/client-selection.js} +11 -5
  43. package/lib/memorax-code-backend/dist/{backend-lifecycle-lock.js → lifecycle/lock.js} +1 -1
  44. package/lib/memorax-code-backend/dist/{memorax-code-lifecycle.js → lifecycle/orchestrator.js} +325 -39
  45. package/lib/memorax-code-backend/dist/memorax-cli.js +1 -1
  46. package/lib/memorax-code-backend/dist/memorax-code.js +1 -1
  47. package/lib/memorax-code-backend/dist/{automatic-memory-retrieval.js → memory/automatic-retrieval.js} +3 -3
  48. package/lib/memorax-code-backend/dist/{automatic-memory-writeback.js → memory/automatic-writeback.js} +75 -21
  49. package/lib/memorax-code-backend/dist/{memory-cli.js → memory/cli.js} +23 -10
  50. package/lib/memorax-code-backend/dist/{memory-hook-command.js → memory/hook-command.js} +156 -9
  51. package/lib/memorax-code-backend/dist/memory/observability.js +1 -0
  52. package/lib/memorax-code-backend/dist/memory/payload-redaction.js +212 -0
  53. package/lib/memorax-code-backend/dist/{memory-reminder-trace-recorder.js → memory/reminder-trace-recorder.js} +20 -7
  54. package/lib/memorax-code-backend/dist/{repository-memory-context.js → memory/repository-session.js} +2 -2
  55. package/lib/memorax-code-backend/dist/{memory-service.js → memory/service.js} +27 -5
  56. package/lib/memorax-code-backend/dist/{memory-turn-coordinator.js → memory/turn-coordinator.js} +2 -1
  57. package/lib/memorax-code-backend/dist/{memory-writeback-buffer.js → memory/writeback-buffer.js} +3 -3
  58. package/lib/memorax-code-backend/dist/{memory-writeback-chunk.js → memory/writeback-chunk.js} +1 -1
  59. package/lib/memorax-code-backend/dist/{memory-writeback-reconciler.js → memory/writeback-reconciler.js} +6 -6
  60. package/lib/memorax-code-backend/dist/{memory-writeback-task-projection.js → memory/writeback-task-projection.js} +4 -4
  61. package/lib/memorax-code-backend/dist/{memorax-adapter.js → provider/memorax/adapter.js} +5 -5
  62. package/lib/memorax-code-backend/dist/{memorax-config.js → provider/memorax/config.js} +4 -4
  63. package/lib/memorax-code-backend/dist/{memorax-http.js → provider/memorax/http.js} +1 -1
  64. package/lib/memorax-code-backend/dist/{repo-memory-readiness.js → repository/readiness.js} +3 -3
  65. package/lib/memorax-code-backend/dist/server.js +3 -212
  66. package/lib/memorax-code-backend/dist/service-entrypoint.js +1 -1
  67. package/lib/memorax-code-backend/dist/{debug-log.js → shared/debug-log.js} +1 -1
  68. package/lib/memorax-code-backend/dist/shared/jsonl-append.js +75 -0
  69. package/lib/memorax-code-backend/dist/shared/windows-cli-invocation.js +148 -0
  70. package/lib/memorax-code-backend/dist/{trace-config.js → trace/config.js} +43 -5
  71. package/lib/memorax-code-backend/dist/{trace-context.js → trace/context.js} +53 -2
  72. package/lib/memorax-code-backend/dist/{trace-store.js → trace/store.js} +3 -3
  73. package/lib/memorax-code-backend/dist/{server-health.js → transport/http/health.js} +1 -1
  74. package/lib/memorax-code-backend/dist/{server-memory-hook.js → transport/http/memory-hook.js} +3 -3
  75. package/lib/memorax-code-backend/dist/{server-http.js → transport/http/request.js} +1 -1
  76. package/lib/memorax-code-backend/dist/{claude-local-transcript.js → viewer/history/claude-transcript.js} +3 -3
  77. package/lib/memorax-code-backend/dist/{memory-viewer-session-title.js → viewer/history/session-title.js} +1 -1
  78. package/lib/memorax-code-backend/dist/{server-memory-viewer.js → viewer/http/public-routes.js} +15 -15
  79. package/lib/memorax-code-backend/dist/viewer/model.js +1 -0
  80. package/lib/memorax-code-backend/dist/{memory-viewer-activity.js → viewer/projection/activity.js} +2 -2
  81. package/lib/memorax-code-backend/dist/{memory-viewer-history-projection.js → viewer/projection/history.js} +1 -1
  82. package/lib/memorax-code-backend/dist/{memory-viewer-observability.js → viewer/projection/observability.js} +1 -1
  83. package/lib/memorax-code-backend/dist/{memory-viewer-user-projection.js → viewer/projection/user.js} +1 -1
  84. package/lib/memorax-code-backend/dist/{memory-viewer-writeback-status.js → viewer/projection/writeback-status.js} +1 -1
  85. package/lib/memorax-code-backend/dist/{memory-viewer-store.js → viewer/store.js} +59 -32
  86. package/lib/memorax-code-backend/dist/{memory-viewer-user-html.js → viewer/ui/user-html.js} +11 -10
  87. package/lib/memorax-code-backend/dist/windows-cli-invocation.js +1 -148
  88. package/lib/memorax-code-backend/package.json +3 -3
  89. package/lib/memorax-code-claude-adapter/.claude-plugin/plugin.json +1 -1
  90. package/lib/memorax-code-claude-adapter/hooks/runtime-shell.json +1 -1
  91. package/lib/memorax-code-claude-adapter/package.json +1 -1
  92. package/lib/memorax-code-claude-adapter/skills/memorax-code/SKILL.md +11 -2
  93. package/lib/memorax-code-claude-adapter/skills/memorax-code/defaults.json +8 -5
  94. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/memorax-add.md +1 -1
  95. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/memorax-search.md +37 -9
  96. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/personal-read.md +1 -1
  97. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/personal-write.md +33 -13
  98. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/repo-build.md +62 -13
  99. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/repo-read.md +11 -4
  100. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/repo-templates.md +179 -59
  101. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/repo-update.md +18 -7
  102. package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/collect_all.py +122 -39
  103. package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/detect_updates.py +73 -10
  104. package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/github_resource_facets.py +9 -1
  105. package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +9 -1
  106. package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/validate_memory.py +23 -1
  107. package/lib/memorax-code-claude-adapter/src/plugin-install.mjs +1 -0
  108. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/.claude-plugin/plugin.json +1 -1
  109. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/hooks/runtime-shell.json +1 -1
  110. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/capture-cwd-hook.mjs +21 -14
  111. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/ensure-backend-runner.mjs +26 -7
  112. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/memory-skill-reminder-hook.mjs +86 -95
  113. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/memory-skill-reminder-policy.mjs +58 -0
  114. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/repo-memory/repo-memory-auto-build.mjs +2 -2
  115. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/repo-memory/repo-memory-job-supervisor.mjs +1 -1
  116. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/windows-cli-invocation.mjs +13 -1
  117. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/package.json +1 -1
  118. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/SKILL.md +11 -2
  119. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/defaults.json +8 -5
  120. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/memorax-add.md +1 -1
  121. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/memorax-search.md +37 -9
  122. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/personal-read.md +1 -1
  123. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/personal-write.md +33 -13
  124. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/repo-build.md +62 -13
  125. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/repo-read.md +11 -4
  126. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/repo-templates.md +179 -59
  127. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/repo-update.md +18 -7
  128. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/collect_all.py +122 -39
  129. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/detect_updates.py +73 -10
  130. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/github_resource_facets.py +9 -1
  131. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +9 -1
  132. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/validate_memory.py +23 -1
  133. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/src/plugin-install.mjs +1 -0
  134. package/lib/memorax-code-codex-adapter/.codex-plugin/plugin.json +1 -1
  135. package/lib/memorax-code-codex-adapter/hooks/runtime-shell.json +1 -1
  136. package/lib/memorax-code-codex-adapter/package.json +1 -1
  137. package/lib/memorax-code-codex-adapter/runtime-hooks/memory-skill-reminder.mjs +10 -2
  138. package/lib/memorax-code-codex-adapter/skills/memorax-code/SKILL.md +11 -2
  139. package/lib/memorax-code-codex-adapter/skills/memorax-code/defaults.json +8 -5
  140. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/memorax-add.md +1 -1
  141. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/memorax-search.md +37 -9
  142. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/personal-read.md +1 -1
  143. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/personal-write.md +33 -13
  144. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/repo-build.md +62 -13
  145. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/repo-read.md +11 -4
  146. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/repo-templates.md +179 -59
  147. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/repo-update.md +18 -7
  148. package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/collect_all.py +122 -39
  149. package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/detect_updates.py +73 -10
  150. package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/github_resource_facets.py +9 -1
  151. package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +9 -1
  152. package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/validate_memory.py +23 -1
  153. package/lib/memorax-code-dsh-adapter/cordis.patch.yml +10 -0
  154. package/lib/memorax-code-dsh-adapter/hooks/repo-memory-job.mjs +68 -0
  155. package/lib/memorax-code-dsh-adapter/package.json +69 -0
  156. package/lib/memorax-code-dsh-adapter/skills/memorax-code/SKILL.md +91 -0
  157. package/lib/memorax-code-dsh-adapter/skills/memorax-code/agents/claude.yaml +10 -0
  158. package/lib/memorax-code-dsh-adapter/skills/memorax-code/agents/openai.yaml +7 -0
  159. package/lib/memorax-code-dsh-adapter/skills/memorax-code/defaults.json +12 -0
  160. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/memorax-add.md +86 -0
  161. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/memorax-search.md +91 -0
  162. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/personal-read.md +46 -0
  163. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/personal-write.md +120 -0
  164. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/repo-build.md +319 -0
  165. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/repo-read.md +103 -0
  166. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/repo-templates.md +390 -0
  167. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/repo-update.md +127 -0
  168. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/collect_all.py +579 -0
  169. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/detect_updates.py +919 -0
  170. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/git_commit_facets.py +222 -0
  171. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/github_resource_facets.py +512 -0
  172. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +517 -0
  173. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/prepare_repo_memory.py +411 -0
  174. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/user_profile_memory.py +528 -0
  175. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/validate_memory.py +248 -0
  176. package/lib/memorax-code-dsh-adapter/src/backend-client.mjs +119 -0
  177. package/lib/memorax-code-dsh-adapter/src/dsh-message.mjs +32 -0
  178. package/lib/memorax-code-dsh-adapter/src/dsh-version.mjs +18 -0
  179. package/lib/memorax-code-dsh-adapter/src/http-client.mjs +55 -0
  180. package/lib/memorax-code-dsh-adapter/src/index.mjs +72 -0
  181. package/lib/memorax-code-dsh-adapter/src/personal-context-worker.mjs +48 -0
  182. package/lib/memorax-code-dsh-adapter/src/personal-context.mjs +114 -0
  183. package/lib/memorax-code-dsh-adapter/src/plugin.mjs +724 -0
  184. package/lib/memorax-code-dsh-adapter/src/profile-lifecycle.mjs +1289 -0
  185. package/lib/memorax-code-dsh-adapter/src/protocol.mjs +145 -0
  186. package/lib/memorax-code-dsh-adapter/src/runtime-state.mjs +132 -0
  187. package/lib/memorax-code-opencode-adapter/hooks/repo-memory-job.mjs +37 -0
  188. package/lib/memorax-code-opencode-adapter/package.json +10 -0
  189. package/lib/memorax-code-opencode-adapter/skills/memorax-code/SKILL.md +91 -0
  190. package/lib/memorax-code-opencode-adapter/skills/memorax-code/agents/claude.yaml +10 -0
  191. package/lib/memorax-code-opencode-adapter/skills/memorax-code/agents/openai.yaml +7 -0
  192. package/lib/memorax-code-opencode-adapter/skills/memorax-code/defaults.json +12 -0
  193. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/memorax-add.md +86 -0
  194. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/memorax-search.md +91 -0
  195. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/personal-read.md +46 -0
  196. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/personal-write.md +120 -0
  197. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/repo-build.md +319 -0
  198. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/repo-read.md +103 -0
  199. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/repo-templates.md +390 -0
  200. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/repo-update.md +127 -0
  201. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/collect_all.py +579 -0
  202. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/detect_updates.py +919 -0
  203. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/git_commit_facets.py +222 -0
  204. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/github_resource_facets.py +512 -0
  205. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +517 -0
  206. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/prepare_repo_memory.py +411 -0
  207. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/user_profile_memory.py +528 -0
  208. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/validate_memory.py +248 -0
  209. package/lib/memorax-code-opencode-adapter/src/adapter-paths.mjs +37 -0
  210. package/lib/memorax-code-opencode-adapter/src/cli.mjs +260 -0
  211. package/lib/memorax-code-opencode-adapter/src/diagnostics.mjs +31 -0
  212. package/lib/memorax-code-opencode-adapter/src/plugin-install.mjs +673 -0
  213. package/lib/memorax-code-opencode-adapter/src/plugin.mjs +536 -0
  214. package/lib/memorax-code-opencode-adapter/src/repo-memory-server-runner.mjs +207 -0
  215. package/lib/run-entrypoint.mjs +6 -0
  216. package/package.json +7 -3
  217. package/lib/memorax-code-backend/dist/client-plugin-removal.js +0 -67
  218. /package/lib/memorax-code-backend/dist/{claude-transcript-turn.js → clients/claude/transcript-turn.js} +0 -0
  219. /package/lib/memorax-code-backend/dist/{codex-effective-prompt.js → clients/codex/effective-prompt.js} +0 -0
  220. /package/lib/memorax-code-backend/dist/{codex-rollout-turn.js → clients/codex/rollout-turn.js} +0 -0
  221. /package/lib/memorax-code-backend/dist/{codex-session-turn-index.js → clients/codex/session-turn-index.js} +0 -0
  222. /package/lib/memorax-code-backend/dist/{codex-workspace-links.js → clients/codex/workspace-links.js} +0 -0
  223. /package/lib/memorax-code-backend/dist/{backend-env.js → config/backend-env.js} +0 -0
  224. /package/lib/memorax-code-backend/dist/{proxy-env.js → config/proxy-env.js} +0 -0
  225. /package/lib/memorax-code-backend/dist/{entrypoint.js → entrypoints/main.js} +0 -0
  226. /package/lib/memorax-code-backend/dist/{backend-process.js → lifecycle/backend/process.js} +0 -0
  227. /package/lib/memorax-code-backend/dist/{backend-shutdown-request.js → lifecycle/backend/shutdown-request.js} +0 -0
  228. /package/lib/memorax-code-backend/dist/{backend-status.js → lifecycle/backend/status.js} +0 -0
  229. /package/lib/memorax-code-backend/dist/{adapter-lifecycle-participant.js → lifecycle/contracts.js} +0 -0
  230. /package/lib/memorax-code-backend/dist/{install-watchdog.js → lifecycle/install-watchdog.js} +0 -0
  231. /package/lib/memorax-code-backend/dist/{memory-observability.js → lifecycle/participant.js} +0 -0
  232. /package/lib/memorax-code-backend/dist/{memory-project.js → memory/project.js} +0 -0
  233. /package/lib/memorax-code-backend/dist/{repository-memory-scope.js → repository/scope.js} +0 -0
  234. /package/lib/memorax-code-backend/dist/{incremental-jsonl-projection.js → shared/incremental-jsonl-projection.js} +0 -0
  235. /package/lib/memorax-code-backend/dist/{utils.js → shared/record.js} +0 -0
  236. /package/lib/memorax-code-backend/dist/{server-json.js → transport/http/json.js} +0 -0
  237. /package/lib/memorax-code-backend/dist/{memory-viewer-data-projection-cache.js → viewer/projection/cache.js} +0 -0
  238. /package/lib/memorax-code-backend/dist/{memory-viewer-event-identity.js → viewer/projection/event-identity.js} +0 -0
  239. /package/lib/memorax-code-backend/dist/{memory-viewer-redaction.js → viewer/projection/redaction.js} +0 -0
  240. /package/lib/memorax-code-backend/dist/{memory-viewer-turn-reference.js → viewer/projection/turn-reference.js} +0 -0
  241. /package/lib/memorax-code-backend/dist/{memory-viewer-icon.js → viewer/ui/icon.js} +0 -0
  242. /package/lib/memorax-code-backend/dist/{memory-viewer-logo.js → viewer/ui/logo.js} +0 -0
@@ -0,0 +1,248 @@
1
+ #!/usr/bin/env python3
2
+ """Validate authored repo-memory bundles."""
3
+
4
+ import argparse
5
+ import json
6
+ import re
7
+ import sys
8
+ from pathlib import Path
9
+ from typing import Any
10
+
11
+
12
+ BASELINE_FILES = [
13
+ Path("PROFILE.md"),
14
+ Path("resources/commits.md"),
15
+ Path("resources/prs.md"),
16
+ Path("resources/issues.md"),
17
+ Path("raw/git-commits.json"),
18
+ ]
19
+
20
+ PROVIDER_RAW_FILES = [Path("raw/github-facets.json"), Path("raw/gitlab-facets.json")]
21
+ PROVIDER_RESOURCE_FILES = [Path("resources/prs.md"), Path("resources/issues.md")]
22
+ DISABLED_RESOURCE_SOURCES = {"history_disabled", "provider_skipped_local_only", "provider_unavailable", "github_resource_facets_unavailable", "gitlab_resource_facets_unavailable", "provider_unavailable_local_only"}
23
+ USER_PROFILE_SIDECAR = Path("user-profile/preferences.md")
24
+ PROCEDURE_SIDECAR_DIRECTORY = "procedure-memory"
25
+ PLACEHOLDER_RE = re.compile(r"\[([^\]\n]+)\]")
26
+ LINK_TARGET_AFTER_BRACKET_RE = re.compile(r"[ \t\r\n]*\(")
27
+
28
+
29
+ def relative(path: Path, memory: Path) -> str:
30
+ return path.relative_to(memory).as_posix()
31
+
32
+
33
+ def resolve_memory_root(path: Path) -> Path:
34
+ candidate = path.expanduser().resolve()
35
+ if candidate.name == ".repo_memory":
36
+ return candidate
37
+ return candidate / ".repo_memory"
38
+
39
+
40
+ def parse_frontmatter(text: str) -> dict[str, Any]:
41
+ if not text.startswith("---\n"):
42
+ return {}
43
+ end = text.find("\n---", 4)
44
+ if end == -1:
45
+ return {}
46
+ values: dict[str, Any] = {}
47
+ for line in text[4:end].splitlines():
48
+ if ":" not in line:
49
+ continue
50
+ key, value = line.split(":", 1)
51
+ key = key.strip()
52
+ value = value.strip()
53
+ if not key:
54
+ continue
55
+ if (value.startswith('"') and value.endswith('"')) or (value.startswith("'") and value.endswith("'")):
56
+ values[key] = value[1:-1]
57
+ elif re.fullmatch(r"-?\d+", value):
58
+ values[key] = int(value)
59
+ elif value.lower() == "true":
60
+ values[key] = True
61
+ elif value.lower() == "false":
62
+ values[key] = False
63
+ else:
64
+ values[key] = value
65
+ return values
66
+
67
+
68
+ def body_after_frontmatter(text: str) -> str:
69
+ if not text.startswith("---\n"):
70
+ return text
71
+ end = text.find("\n---", 4)
72
+ if end == -1:
73
+ return text
74
+ return text[end + 4 :].lstrip("\n")
75
+
76
+
77
+ def item_section_count(text: str) -> int:
78
+ body = body_after_frontmatter(text)
79
+ lines = body.splitlines()
80
+ title_seen = False
81
+ count = 0
82
+ for line in lines:
83
+ if line.startswith("# ") and not title_seen:
84
+ title_seen = True
85
+ continue
86
+ if title_seen and line.startswith("## "):
87
+ count += 1
88
+ return count
89
+
90
+
91
+ def placeholder_matches(text: str) -> list[str]:
92
+ text = strip_markdown_code(text)
93
+ matches: list[str] = []
94
+ for match in PLACEHOLDER_RE.finditer(text):
95
+ if LINK_TARGET_AFTER_BRACKET_RE.match(text, match.end()):
96
+ continue
97
+ value = match.group(1).strip()
98
+ if not value or value.startswith("#"):
99
+ continue
100
+ if re.search(r"[A-Za-z]", value):
101
+ matches.append(f"[{value}]")
102
+ return matches
103
+
104
+
105
+ def strip_markdown_code(text: str) -> str:
106
+ without_fences = re.sub(r"```.*?```", "", text, flags=re.DOTALL)
107
+ return re.sub(r"`[^`\n]*`", "", without_fences)
108
+
109
+
110
+ def check_exists(memory: Path, rel_path: Path, errors: list[str], checked: list[str]) -> bool:
111
+ path = memory / rel_path
112
+ checked.append(rel_path.as_posix())
113
+ if not path.exists():
114
+ errors.append(f"{rel_path.as_posix()}: required file is missing")
115
+ return False
116
+ if not path.is_file():
117
+ errors.append(f"{rel_path.as_posix()}: expected a file")
118
+ return False
119
+ return True
120
+
121
+
122
+ def validate_json(path: Path, memory: Path, errors: list[str], checked: list[str]) -> None:
123
+ checked.append(relative(path, memory))
124
+ try:
125
+ json.loads(path.read_text(encoding="utf-8"))
126
+ except json.JSONDecodeError as exc:
127
+ errors.append(f"{relative(path, memory)}: invalid JSON at line {exc.lineno}, column {exc.colno}: {exc.msg}")
128
+ except OSError as exc:
129
+ errors.append(f"{relative(path, memory)}: could not read JSON: {exc}")
130
+
131
+
132
+ def raw_source_points_to_provider(raw_source: Any) -> bool:
133
+ return isinstance(raw_source, str) and raw_source.endswith(("github-facets.json", "gitlab-facets.json"))
134
+
135
+
136
+ def validate_markdown(path: Path, memory: Path, errors: list[str], warnings: list[str], checked: list[str]) -> None:
137
+ checked.append(relative(path, memory))
138
+ try:
139
+ text = path.read_text(encoding="utf-8")
140
+ except OSError as exc:
141
+ errors.append(f"{relative(path, memory)}: could not read Markdown: {exc}")
142
+ return
143
+
144
+ frontmatter = parse_frontmatter(text)
145
+ rel = relative(path, memory)
146
+ if not frontmatter.get("schema"):
147
+ errors.append(f"{rel}: frontmatter field 'schema' is missing")
148
+
149
+ placeholders = placeholder_matches(text)
150
+ if placeholders:
151
+ errors.append(f"{rel}: unresolved bracket placeholder(s): {', '.join(placeholders)}")
152
+
153
+ if path.parent.name != "resources":
154
+ return
155
+
156
+ for field in ["source", "resource_count", "trust_state", "raw_source"]:
157
+ if field not in frontmatter:
158
+ errors.append(f"{rel}: frontmatter field '{field}' is missing")
159
+
160
+ expected = frontmatter.get("resource_count")
161
+ actual = item_section_count(text)
162
+ if isinstance(expected, int):
163
+ if expected != actual:
164
+ errors.append(f"{rel}: resource_count is {expected}, but found {actual} item section(s)")
165
+ elif expected is not None:
166
+ errors.append(f"{rel}: resource_count must be an integer")
167
+
168
+ source = frontmatter.get("source")
169
+ raw_source = frontmatter.get("raw_source")
170
+ if "source" in frontmatter and not source:
171
+ errors.append(f"{rel}: frontmatter field 'source' must not be empty")
172
+ if "trust_state" in frontmatter and not frontmatter.get("trust_state"):
173
+ errors.append(f"{rel}: frontmatter field 'trust_state' must not be empty")
174
+ if source in DISABLED_RESOURCE_SOURCES and isinstance(expected, int) and expected != 0:
175
+ errors.append(f"{rel}: disabled or unavailable resource source {source!r} must use resource_count 0")
176
+ if source in DISABLED_RESOURCE_SOURCES and raw_source:
177
+ errors.append(f"{rel}: disabled or unavailable resource source {source!r} must use an empty raw_source")
178
+ if path.name in {"commits.md", "prs.md", "issues.md"} and source not in DISABLED_RESOURCE_SOURCES and raw_source == "":
179
+ errors.append(f"{rel}: empty raw_source requires a disabled or unavailable source")
180
+ if path.name in {"prs.md", "issues.md"} and raw_source_points_to_provider(raw_source):
181
+ provider_path = (path.parent / raw_source).resolve()
182
+ if not provider_path.exists():
183
+ errors.append(f"{rel}: provider raw evidence is missing for raw_source {raw_source!r}")
184
+
185
+
186
+ def provider_raw_paths(memory: Path) -> list[Path]:
187
+ return [memory / rel for rel in PROVIDER_RAW_FILES if (memory / rel).exists()]
188
+
189
+
190
+ def validate(memory: Path) -> dict[str, Any]:
191
+ errors: list[str] = []
192
+ warnings: list[str] = []
193
+ checked: list[str] = []
194
+
195
+ if not memory.exists():
196
+ errors.append(f"{memory}: .repo_memory directory is missing")
197
+ return {"ok": False, "errors": errors, "warnings": warnings, "checked": checked}
198
+ if not memory.is_dir():
199
+ errors.append(f"{memory}: expected .repo_memory to be a directory")
200
+ return {"ok": False, "errors": errors, "warnings": warnings, "checked": checked}
201
+
202
+ for rel_path in BASELINE_FILES:
203
+ check_exists(memory, rel_path, errors, checked)
204
+
205
+ markdown_paths = sorted(
206
+ path
207
+ for path in memory.rglob("*.md")
208
+ if path.is_file()
209
+ and path.relative_to(memory) != USER_PROFILE_SIDECAR
210
+ and path.relative_to(memory).parts[0] != PROCEDURE_SIDECAR_DIRECTORY
211
+ )
212
+ for path in markdown_paths:
213
+ if path.exists() and path.is_file():
214
+ validate_markdown(path, memory, errors, warnings, checked)
215
+
216
+ json_paths = sorted(path for path in (memory / "raw").rglob("*.json") if path.is_file())
217
+ provider_raw = provider_raw_paths(memory)
218
+
219
+ if provider_raw:
220
+ for rel_path in PROVIDER_RESOURCE_FILES:
221
+ check_exists(memory, rel_path, errors, checked)
222
+
223
+ seen_json: set[Path] = set()
224
+ for path in json_paths:
225
+ if path.exists() and path.is_file() and path not in seen_json:
226
+ seen_json.add(path)
227
+ validate_json(path, memory, errors, checked)
228
+
229
+ checked = sorted(dict.fromkeys(checked))
230
+ return {"ok": not errors, "errors": errors, "warnings": warnings, "checked": checked}
231
+
232
+
233
+ def parse_args(argv: list[str]) -> argparse.Namespace:
234
+ parser = argparse.ArgumentParser(description="Validate a repo-memory bundle.")
235
+ parser.add_argument("path", help="Path to a repository or its .repo_memory directory")
236
+ parser.add_argument("--pretty", action="store_true", help="Pretty-print JSON output")
237
+ return parser.parse_args(argv)
238
+
239
+
240
+ def main(argv: list[str]) -> int:
241
+ args = parse_args(argv)
242
+ report = validate(resolve_memory_root(Path(args.path)))
243
+ print(json.dumps(report, ensure_ascii=False, indent=2 if args.pretty else None))
244
+ return 0 if report["ok"] else 1
245
+
246
+
247
+ if __name__ == "__main__":
248
+ raise SystemExit(main(sys.argv[1:]))
@@ -0,0 +1,37 @@
1
+ import { homedir } from "node:os";
2
+ import { join, resolve } from "node:path";
3
+
4
+ export function defaultOpenCodeConfigDir(env = process.env, home = homedir()) {
5
+ const explicit = stringOption(env.OPENCODE_CONFIG_DIR);
6
+ if (explicit) return resolve(explicit);
7
+ const configHome = stringOption(env.XDG_CONFIG_HOME) ?? join(home, ".config");
8
+ return resolve(configHome, "opencode");
9
+ }
10
+
11
+ export function defaultMemoraxCodeHome(env = process.env, home = homedir()) {
12
+ return resolve(stringOption(env.MEMORAX_CODE_HOME) ?? join(home, ".memorax-code"));
13
+ }
14
+
15
+ export function adapterStatePath(memoraxCodeHome = defaultMemoraxCodeHome()) {
16
+ return join(memoraxCodeHome, "adapters", "opencode", "state.json");
17
+ }
18
+
19
+ export function openCodeWorkspaceStatePath(memoraxCodeHome = defaultMemoraxCodeHome()) {
20
+ return join(memoraxCodeHome, "adapters", "opencode", "workspaces.json");
21
+ }
22
+
23
+ export function openCodePluginPath(configDir = defaultOpenCodeConfigDir()) {
24
+ return join(configDir, "plugins", "memorax-code.js");
25
+ }
26
+
27
+ export function openCodeSkillPath(configDir = defaultOpenCodeConfigDir()) {
28
+ return join(configDir, "skills", "memorax-code");
29
+ }
30
+
31
+ export function openCodeRepoMemoryHelperPath(configDir = defaultOpenCodeConfigDir()) {
32
+ return join(configDir, "hooks", "repo-memory-job.mjs");
33
+ }
34
+
35
+ function stringOption(value) {
36
+ return typeof value === "string" && value.trim() ? value.trim() : undefined;
37
+ }
@@ -0,0 +1,260 @@
1
+ #!/usr/bin/env node
2
+ import { resolveBackendConnection } from "../../memorax-code-adapter-common/src/backend-connection.mjs";
3
+ import {
4
+ defaultMemoraxCodeHome,
5
+ defaultOpenCodeConfigDir,
6
+ } from "./adapter-paths.mjs";
7
+ import { readOpenCodeWorkspaceStatus } from "./diagnostics.mjs";
8
+ import { readOpenCodePluginStatus } from "./plugin-install.mjs";
9
+
10
+ const DEFAULT_TOKEN_ENV = "MEMORAX_CODE_BACKEND_TOKEN";
11
+ const BACKEND_HEALTH_TIMEOUT_MS = 5_000;
12
+ const VALUE_OPTIONS = new Set([
13
+ "--opencode-config-dir",
14
+ "--memorax-code-home",
15
+ "--backend-url",
16
+ "--backend-token-env",
17
+ ]);
18
+
19
+ try {
20
+ const parsed = parseCli(process.argv);
21
+ if (parsed.help) {
22
+ printHelp();
23
+ process.exit(0);
24
+ }
25
+
26
+ const options = parsed.options;
27
+ if (parsed.command === "status") {
28
+ print(openCodeStatus(options), options);
29
+ } else if (parsed.command === "doctor") {
30
+ const [status, workspace, backend] = await Promise.all([
31
+ openCodeStatus(options),
32
+ readOpenCodeWorkspaceStatus(options),
33
+ backendHealth(options.backendUrl, backendToken(options)),
34
+ ]);
35
+ print({
36
+ ok: status.ok && workspace.ok && workspace.captured && backend.ok,
37
+ action: "doctor",
38
+ status,
39
+ workspace,
40
+ backend,
41
+ }, options);
42
+ } else {
43
+ throw new Error(`unknown command: ${parsed.command}`);
44
+ }
45
+ } catch (error) {
46
+ console.error(error instanceof Error ? error.message : String(error));
47
+ process.exit(1);
48
+ }
49
+
50
+ function printHelp() {
51
+ console.log([
52
+ "Usage: memorax-code-opencode [status|doctor] [options]",
53
+ "",
54
+ "Lifecycle note: use `memorax-code start --clients opencode` to install or reconcile the OpenCode plugin.",
55
+ "",
56
+ "Options:",
57
+ " --opencode-config-dir DIR OpenCode config root (default: OPENCODE_CONFIG_DIR, XDG_CONFIG_HOME/opencode, or ~/.config/opencode)",
58
+ " --memorax-code-home DIR MemoraX Code state home (default: MEMORAX_CODE_HOME or ~/.memorax-code)",
59
+ " --backend-url URL Local Backend URL (default: persisted connection or http://127.0.0.1:8787)",
60
+ " --backend-token-env NAME Token env var for Backend health checks",
61
+ " --json Print machine-readable JSON",
62
+ ].join("\n"));
63
+ }
64
+
65
+ function parseCli(argv) {
66
+ const args = argv.slice(2);
67
+ const first = args[0];
68
+ const command = first && !first.startsWith("-") ? first : "status";
69
+ const optionArgs = command === first ? args.slice(1) : args;
70
+ const help = command === "help" || optionArgs.includes("--help");
71
+ return {
72
+ command,
73
+ help,
74
+ options: help ? {} : parseOptions(optionArgs),
75
+ };
76
+ }
77
+
78
+ function parseOptions(args) {
79
+ const values = {};
80
+ for (let index = 0; index < args.length; index += 1) {
81
+ const arg = args[index];
82
+ if (arg === "--json" || arg === "--help") {
83
+ values[arg] = true;
84
+ continue;
85
+ }
86
+ if (VALUE_OPTIONS.has(arg)) {
87
+ const value = args[index + 1];
88
+ if (!value || value.startsWith("--")) throw new Error(`${arg} requires a value`);
89
+ values[arg] = value;
90
+ index += 1;
91
+ continue;
92
+ }
93
+ if (arg.startsWith("--")) throw new Error(`unknown option: ${arg}`);
94
+ throw new Error(`unexpected argument: ${arg}`);
95
+ }
96
+
97
+ const memoraxCodeHome = values["--memorax-code-home"] ?? defaultMemoraxCodeHome();
98
+ const requestedBackendUrl = values["--backend-url"] ?? process.env.MEMORAX_CODE_BACKEND_URL;
99
+ if (requestedBackendUrl) validateHttpUrl(requestedBackendUrl, "--backend-url");
100
+ const connection = resolveBackendConnection({
101
+ memoraxCodeHome,
102
+ backendUrl: values["--backend-url"],
103
+ });
104
+ return {
105
+ openCodeConfigDir: values["--opencode-config-dir"] ?? defaultOpenCodeConfigDir(),
106
+ memoraxCodeHome,
107
+ backendUrl: connection.url,
108
+ backendTokenEnv: values["--backend-token-env"],
109
+ connection,
110
+ json: Boolean(values["--json"]),
111
+ };
112
+ }
113
+
114
+ function openCodeStatus(options) {
115
+ const status = readOpenCodePluginStatus(options);
116
+ const openCodeConfigDir = typeof status.state?.openCodeConfigDir === "string"
117
+ ? status.state.openCodeConfigDir
118
+ : options.openCodeConfigDir;
119
+ const ready = status.ok === true
120
+ && status.installed === true
121
+ && status.enabled === true
122
+ && status.current === true
123
+ && status.backendUrlMatches !== false
124
+ && status.opencodeSkills?.ok === true;
125
+ return {
126
+ ...status,
127
+ ok: ready,
128
+ action: "status",
129
+ openCodeConfigDir,
130
+ ...(openCodeConfigDir !== options.openCodeConfigDir
131
+ ? { requestedOpenCodeConfigDir: options.openCodeConfigDir }
132
+ : {}),
133
+ memoraxCodeHome: options.memoraxCodeHome,
134
+ };
135
+ }
136
+
137
+ function validateHttpUrl(value, optionName) {
138
+ try {
139
+ const url = new URL(value);
140
+ if (url.protocol !== "http:" && url.protocol !== "https:") throw new Error("unsupported protocol");
141
+ } catch {
142
+ throw new Error(`${optionName} must be an http(s) URL`);
143
+ }
144
+ }
145
+
146
+ async function backendHealth(backendUrl, token) {
147
+ try {
148
+ const headers = {
149
+ connection: "close",
150
+ ...(token ? { authorization: `Bearer ${token}` } : {}),
151
+ };
152
+ const response = await fetch(new URL("/health", backendUrl), {
153
+ headers,
154
+ signal: AbortSignal.timeout(BACKEND_HEALTH_TIMEOUT_MS),
155
+ });
156
+ const body = await response.json().catch(() => undefined);
157
+ return {
158
+ ok: response.ok && body?.ok === true && body?.service === "memorax-code-backend",
159
+ status: response.status,
160
+ body,
161
+ };
162
+ } catch (error) {
163
+ return { ok: false, error: error instanceof Error ? error.message : String(error) };
164
+ }
165
+ }
166
+
167
+ function backendToken(options) {
168
+ const tokenEnv = options.backendTokenEnv ?? DEFAULT_TOKEN_ENV;
169
+ return tokenEnv === DEFAULT_TOKEN_ENV
170
+ ? options.connection.token
171
+ : process.env[tokenEnv];
172
+ }
173
+
174
+ function print(result, options) {
175
+ if (options.json) {
176
+ console.log(JSON.stringify(result, null, 2));
177
+ } else if (result.action === "doctor") {
178
+ printDoctor(result);
179
+ } else {
180
+ printStatus(result);
181
+ }
182
+ process.exit(result.ok ? 0 : 1);
183
+ }
184
+
185
+ function printStatus(result, includeHints = true) {
186
+ console.log(`status: ${result.ok ? "ok" : "needs attention"}`);
187
+ console.log(`opencode config: ${result.openCodeConfigDir}`);
188
+ if (result.requestedOpenCodeConfigDir) {
189
+ console.log(`requested opencode config: ${result.requestedOpenCodeConfigDir}`);
190
+ }
191
+ console.log(`memorax-code home: ${result.memoraxCodeHome}`);
192
+ console.log(`state: ${result.statePath}`);
193
+ console.log("integration: plugin");
194
+ console.log("provider config: unchanged (OpenCode-owned)");
195
+ console.log(`managed plugin: ${check(result.pluginExists && result.pluginCurrent)}`);
196
+ console.log(`memorax-code skill: ${check(result.skillExists && result.skillCurrent)}`);
197
+ console.log(`repo-memory helper: ${check(result.repoMemoryHelperExists && result.repoMemoryHelperCurrent)}`);
198
+ console.log(`backend endpoint: ${check(result.backendUrlMatches !== false)} configured=${result.configuredBackendUrl ?? "missing"} expected=${result.expectedBackendUrl ?? "unknown"}`);
199
+ if (includeHints) printHints(statusHints(result));
200
+ }
201
+
202
+ function printDoctor(result) {
203
+ console.log(`doctor: ${result.ok ? "ok" : "needs attention"}`);
204
+ printStatus(result.status, false);
205
+ console.log(`plugin runtime evidence: ${check(result.workspace?.captured === true)}${workspaceDetail(result.workspace)}`);
206
+ console.log(`backend health: ${check(result.backend?.ok === true)}${backendDetail(result.backend)}`);
207
+ printHints(doctorHints(result));
208
+ }
209
+
210
+ function check(ok) {
211
+ return ok ? "ok" : "not ok";
212
+ }
213
+
214
+ function workspaceDetail(workspace) {
215
+ if (!workspace) return " missing";
216
+ if (workspace.ok === false) return ` ${workspace.reason ?? "invalid"} (${workspace.path})`;
217
+ if (!workspace.captured) return ` not observed (${workspace.path})`;
218
+ const latest = workspace.latest;
219
+ const event = typeof latest?.event === "string" ? ` event=${latest.event}` : "";
220
+ const cwd = typeof latest?.cwd === "string" ? ` cwd=${latest.cwd}` : "";
221
+ const capturedAt = typeof latest?.capturedAt === "string" ? ` at=${latest.capturedAt}` : "";
222
+ return `${event}${cwd}${capturedAt}`;
223
+ }
224
+
225
+ function backendDetail(backend) {
226
+ if (!backend) return " missing";
227
+ if (backend.ok) return backend.status ? ` status=${backend.status}` : "";
228
+ return ` ${backend.error ?? backend.status ?? "not reachable"}`;
229
+ }
230
+
231
+ function statusHints(result) {
232
+ const hints = [];
233
+ if (result.installed !== true || result.enabled !== true || result.current !== true) {
234
+ hints.push("Install or reconcile the managed integration with `memorax-code start --clients opencode`, then restart or refresh OpenCode.");
235
+ }
236
+ if (result.backendUrlMatches === false) {
237
+ hints.push("Adapter state points at a different Backend endpoint; rerun `memorax-code start --clients opencode`.");
238
+ }
239
+ return hints;
240
+ }
241
+
242
+ function doctorHints(result) {
243
+ const hints = [...statusHints(result.status)];
244
+ if (result.backend?.ok !== true) {
245
+ hints.push("Backend is not reachable; start it with `memorax-code start` or pass the correct `--backend-url`.");
246
+ }
247
+ if (result.workspace?.ok === false) {
248
+ hints.push("OpenCode runtime evidence is unreadable or invalid; inspect or remove that state file, then restart or refresh OpenCode.");
249
+ } else if (result.workspace?.captured !== true) {
250
+ hints.push("No OpenCode plugin runtime has been observed yet; restart or refresh OpenCode, then rerun this command.");
251
+ }
252
+ return [...new Set(hints)];
253
+ }
254
+
255
+ function printHints(hints) {
256
+ if (hints.length === 0) return;
257
+ console.log("");
258
+ console.log("Recommended next steps:");
259
+ for (const hint of hints) console.log(`- ${hint}`);
260
+ }
@@ -0,0 +1,31 @@
1
+ import { readAdapterState } from "../../memorax-code-adapter-common/src/config-utils.mjs";
2
+ import {
3
+ defaultMemoraxCodeHome,
4
+ openCodeWorkspaceStatePath,
5
+ } from "./adapter-paths.mjs";
6
+
7
+ export function readOpenCodeWorkspaceStatus(options = {}) {
8
+ const memoraxCodeHome = options.memoraxCodeHome ?? defaultMemoraxCodeHome();
9
+ const path = options.workspaceStatePath ?? openCodeWorkspaceStatePath(memoraxCodeHome);
10
+ const state = readAdapterState(path);
11
+ const stateValid = !state || (
12
+ state.unreadable !== true
13
+ && state.version === 1
14
+ && state.runtime === "opencode"
15
+ );
16
+ const latest = stateValid && state?.latest && typeof state.latest === "object"
17
+ ? state.latest
18
+ : undefined;
19
+ return {
20
+ ok: stateValid,
21
+ action: "workspace-status",
22
+ memoraxCodeHome,
23
+ path,
24
+ captured: Boolean(latest?.cwd),
25
+ latest,
26
+ state,
27
+ ...(!stateValid
28
+ ? { reason: state?.unreadable ? "state_unreadable" : "state_invalid" }
29
+ : {}),
30
+ };
31
+ }