@memorax/memorax-code 0.1.0

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 (282) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +53 -0
  3. package/bin/memorax-cli.mjs +28 -0
  4. package/bin/memorax-code-backend.mjs +4 -0
  5. package/bin/memorax-code-claude.mjs +4 -0
  6. package/bin/memorax-code-codex.mjs +4 -0
  7. package/bin/memorax-code-npm-preinstall.mjs +55 -0
  8. package/bin/memorax-code-plugin-postinstall.mjs +1236 -0
  9. package/bin/memorax-code.mjs +204 -0
  10. package/docs/configuration.md +232 -0
  11. package/docs/troubleshooting.md +179 -0
  12. package/lib/client-hook-runtime.mjs +32 -0
  13. package/lib/memorax-code-adapter-common/src/backend-connection.d.mts +111 -0
  14. package/lib/memorax-code-adapter-common/src/backend-connection.mjs +304 -0
  15. package/lib/memorax-code-adapter-common/src/clients/claude-command.mjs +38 -0
  16. package/lib/memorax-code-adapter-common/src/clients/codex-command.mjs +41 -0
  17. package/lib/memorax-code-adapter-common/src/clients/codex-plugin-artifact.d.mts +3 -0
  18. package/lib/memorax-code-adapter-common/src/clients/codex-plugin-artifact.mjs +38 -0
  19. package/lib/memorax-code-adapter-common/src/config-utils.d.mts +27 -0
  20. package/lib/memorax-code-adapter-common/src/config-utils.mjs +391 -0
  21. package/lib/memorax-code-adapter-common/src/hooks/capture-cwd-hook.mjs +137 -0
  22. package/lib/memorax-code-adapter-common/src/hooks/client-hook-launcher.mjs +324 -0
  23. package/lib/memorax-code-adapter-common/src/hooks/ensure-backend-runner.mjs +142 -0
  24. package/lib/memorax-code-adapter-common/src/hooks/hook-runtime-generation.d.mts +38 -0
  25. package/lib/memorax-code-adapter-common/src/hooks/hook-runtime-generation.mjs +501 -0
  26. package/lib/memorax-code-adapter-common/src/hooks/memory-skill-reminder-hook.mjs +277 -0
  27. package/lib/memorax-code-adapter-common/src/memorax-code-config-file.d.mts +28 -0
  28. package/lib/memorax-code-adapter-common/src/memorax-code-config-file.mjs +296 -0
  29. package/lib/memorax-code-adapter-common/src/memorax-defaults.d.mts +10 -0
  30. package/lib/memorax-code-adapter-common/src/memorax-defaults.mjs +12 -0
  31. package/lib/memorax-code-adapter-common/src/repo-memory/repo-memory-job-context.mjs +28 -0
  32. package/lib/memorax-code-adapter-common/src/repo-memory/repo-memory-job-marker.mjs +252 -0
  33. package/lib/memorax-code-adapter-common/src/repo-memory/repo-memory-job-supervisor.mjs +559 -0
  34. package/lib/memorax-code-adapter-common/src/repo-memory/repo-memory-job-worker.mjs +411 -0
  35. package/lib/memorax-code-adapter-common/src/repo-memory/repo-memory-update-policy-evaluator.mjs +185 -0
  36. package/lib/memorax-code-adapter-common/src/repo-memory/repo-memory-update-policy.mjs +165 -0
  37. package/lib/memorax-code-adapter-common/src/repo-memory/repo-procedure-memory-context.mjs +181 -0
  38. package/lib/memorax-code-adapter-common/src/repo-memory/repo-user-profile-context.mjs +251 -0
  39. package/lib/memorax-code-adapter-common/src/runtime-record.d.mts +55 -0
  40. package/lib/memorax-code-adapter-common/src/runtime-record.mjs +152 -0
  41. package/lib/memorax-code-adapter-common/src/windows-cli-invocation.mjs +100 -0
  42. package/lib/memorax-code-backend/dist/active-client-selection.js +35 -0
  43. package/lib/memorax-code-backend/dist/adapter-lifecycle-participant.js +1 -0
  44. package/lib/memorax-code-backend/dist/automatic-memory-retrieval.js +113 -0
  45. package/lib/memorax-code-backend/dist/automatic-memory-writeback.js +297 -0
  46. package/lib/memorax-code-backend/dist/backend-env.js +13 -0
  47. package/lib/memorax-code-backend/dist/backend-lifecycle-lock.js +42 -0
  48. package/lib/memorax-code-backend/dist/backend-process.js +147 -0
  49. package/lib/memorax-code-backend/dist/backend-service-cleanup.js +18 -0
  50. package/lib/memorax-code-backend/dist/backend-service-record.js +206 -0
  51. package/lib/memorax-code-backend/dist/backend-service-result.js +37 -0
  52. package/lib/memorax-code-backend/dist/backend-service-token.js +11 -0
  53. package/lib/memorax-code-backend/dist/backend-shutdown-request.js +133 -0
  54. package/lib/memorax-code-backend/dist/backend-state.js +58 -0
  55. package/lib/memorax-code-backend/dist/backend-status.js +53 -0
  56. package/lib/memorax-code-backend/dist/backend-token-record.js +79 -0
  57. package/lib/memorax-code-backend/dist/claude-adapter-lifecycle.js +134 -0
  58. package/lib/memorax-code-backend/dist/claude-local-transcript.js +648 -0
  59. package/lib/memorax-code-backend/dist/claude-memory-hook-runtime.js +472 -0
  60. package/lib/memorax-code-backend/dist/claude-transcript-turn.js +876 -0
  61. package/lib/memorax-code-backend/dist/client-plugin-removal.js +67 -0
  62. package/lib/memorax-code-backend/dist/client-selection.js +36 -0
  63. package/lib/memorax-code-backend/dist/codex-adapter-lifecycle.js +131 -0
  64. package/lib/memorax-code-backend/dist/codex-effective-prompt.js +54 -0
  65. package/lib/memorax-code-backend/dist/codex-memory-hook-runtime.js +541 -0
  66. package/lib/memorax-code-backend/dist/codex-plugin-hooks.js +421 -0
  67. package/lib/memorax-code-backend/dist/codex-plugin-install.js +523 -0
  68. package/lib/memorax-code-backend/dist/codex-rollout-turn.js +402 -0
  69. package/lib/memorax-code-backend/dist/codex-session-turn-index.js +88 -0
  70. package/lib/memorax-code-backend/dist/codex-workspace-links.js +55 -0
  71. package/lib/memorax-code-backend/dist/debug-log.js +21 -0
  72. package/lib/memorax-code-backend/dist/entrypoint.js +14 -0
  73. package/lib/memorax-code-backend/dist/incremental-jsonl-projection.js +271 -0
  74. package/lib/memorax-code-backend/dist/install-watchdog.js +71 -0
  75. package/lib/memorax-code-backend/dist/jsonl-append.js +75 -0
  76. package/lib/memorax-code-backend/dist/memorax-adapter.js +451 -0
  77. package/lib/memorax-code-backend/dist/memorax-cli.js +14 -0
  78. package/lib/memorax-code-backend/dist/memorax-code-config.js +279 -0
  79. package/lib/memorax-code-backend/dist/memorax-code-lifecycle.js +523 -0
  80. package/lib/memorax-code-backend/dist/memorax-code.js +3 -0
  81. package/lib/memorax-code-backend/dist/memorax-config.js +283 -0
  82. package/lib/memorax-code-backend/dist/memorax-http.js +142 -0
  83. package/lib/memorax-code-backend/dist/memory-cli.js +345 -0
  84. package/lib/memorax-code-backend/dist/memory-hook-command.js +200 -0
  85. package/lib/memorax-code-backend/dist/memory-observability.js +1 -0
  86. package/lib/memorax-code-backend/dist/memory-project.js +89 -0
  87. package/lib/memorax-code-backend/dist/memory-reminder-trace-recorder.js +58 -0
  88. package/lib/memorax-code-backend/dist/memory-service.js +66 -0
  89. package/lib/memorax-code-backend/dist/memory-turn-coordinator.js +139 -0
  90. package/lib/memorax-code-backend/dist/memory-viewer-activity.js +113 -0
  91. package/lib/memorax-code-backend/dist/memory-viewer-data-projection-cache.js +69 -0
  92. package/lib/memorax-code-backend/dist/memory-viewer-event-identity.js +3 -0
  93. package/lib/memorax-code-backend/dist/memory-viewer-history-projection.js +79 -0
  94. package/lib/memorax-code-backend/dist/memory-viewer-logo.js +1 -0
  95. package/lib/memorax-code-backend/dist/memory-viewer-observability.js +8 -0
  96. package/lib/memorax-code-backend/dist/memory-viewer-redaction.js +52 -0
  97. package/lib/memorax-code-backend/dist/memory-viewer-session-title.js +93 -0
  98. package/lib/memorax-code-backend/dist/memory-viewer-store.js +964 -0
  99. package/lib/memorax-code-backend/dist/memory-viewer-turn-reference.js +12 -0
  100. package/lib/memorax-code-backend/dist/memory-viewer-user-html.js +115 -0
  101. package/lib/memorax-code-backend/dist/memory-viewer-user-projection.js +168 -0
  102. package/lib/memorax-code-backend/dist/memory-viewer-writeback-status.js +97 -0
  103. package/lib/memorax-code-backend/dist/memory-writeback-buffer.js +217 -0
  104. package/lib/memorax-code-backend/dist/memory-writeback-chunk.js +120 -0
  105. package/lib/memorax-code-backend/dist/memory-writeback-reconciler.js +244 -0
  106. package/lib/memorax-code-backend/dist/memory-writeback-task-projection.js +377 -0
  107. package/lib/memorax-code-backend/dist/proxy-env.js +54 -0
  108. package/lib/memorax-code-backend/dist/repo-memory-readiness.js +188 -0
  109. package/lib/memorax-code-backend/dist/repository-memory-context.js +134 -0
  110. package/lib/memorax-code-backend/dist/repository-memory-scope.js +490 -0
  111. package/lib/memorax-code-backend/dist/server-cli.js +787 -0
  112. package/lib/memorax-code-backend/dist/server-health.js +16 -0
  113. package/lib/memorax-code-backend/dist/server-http.js +110 -0
  114. package/lib/memorax-code-backend/dist/server-json.js +4 -0
  115. package/lib/memorax-code-backend/dist/server-memory-hook.js +32 -0
  116. package/lib/memorax-code-backend/dist/server-memory-viewer.js +135 -0
  117. package/lib/memorax-code-backend/dist/server-observability.js +102 -0
  118. package/lib/memorax-code-backend/dist/server.js +220 -0
  119. package/lib/memorax-code-backend/dist/service-entrypoint.js +10 -0
  120. package/lib/memorax-code-backend/dist/service.js +567 -0
  121. package/lib/memorax-code-backend/dist/trace-config.js +112 -0
  122. package/lib/memorax-code-backend/dist/trace-context.js +111 -0
  123. package/lib/memorax-code-backend/dist/trace-store.js +571 -0
  124. package/lib/memorax-code-backend/dist/utils.js +3 -0
  125. package/lib/memorax-code-backend/dist/windows-cli-invocation.js +148 -0
  126. package/lib/memorax-code-backend/package.json +26 -0
  127. package/lib/memorax-code-claude-adapter/.claude-plugin/plugin.json +15 -0
  128. package/lib/memorax-code-claude-adapter/hooks/hook-launcher.mjs +27 -0
  129. package/lib/memorax-code-claude-adapter/hooks/hooks.json +66 -0
  130. package/lib/memorax-code-claude-adapter/hooks/repo-memory-job.mjs +37 -0
  131. package/lib/memorax-code-claude-adapter/hooks/runtime-hook.mjs +4 -0
  132. package/lib/memorax-code-claude-adapter/hooks/runtime-shell.json +5 -0
  133. package/lib/memorax-code-claude-adapter/package.json +13 -0
  134. package/lib/memorax-code-claude-adapter/runtime-hooks/capture-cwd.mjs +17 -0
  135. package/lib/memorax-code-claude-adapter/runtime-hooks/ensure-backend.mjs +59 -0
  136. package/lib/memorax-code-claude-adapter/runtime-hooks/memory-cli-session.mjs +33 -0
  137. package/lib/memorax-code-claude-adapter/runtime-hooks/memory-skill-reminder.mjs +73 -0
  138. package/lib/memorax-code-claude-adapter/runtime-hooks/memory-turn.mjs +91 -0
  139. package/lib/memorax-code-claude-adapter/scripts/build-marketplace.mjs +99 -0
  140. package/lib/memorax-code-claude-adapter/skills/memorax-code/SKILL.md +83 -0
  141. package/lib/memorax-code-claude-adapter/skills/memorax-code/agents/claude.yaml +10 -0
  142. package/lib/memorax-code-claude-adapter/skills/memorax-code/agents/openai.yaml +7 -0
  143. package/lib/memorax-code-claude-adapter/skills/memorax-code/defaults.json +9 -0
  144. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/memorax-add.md +82 -0
  145. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/memorax-search.md +61 -0
  146. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/personal-read.md +46 -0
  147. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/personal-write.md +100 -0
  148. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/repo-build.md +270 -0
  149. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/repo-read.md +96 -0
  150. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/repo-templates.md +270 -0
  151. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/repo-update.md +116 -0
  152. package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/collect_all.py +496 -0
  153. package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/detect_updates.py +856 -0
  154. package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/git_commit_facets.py +222 -0
  155. package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/github_resource_facets.py +504 -0
  156. package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +509 -0
  157. package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/prepare_repo_memory.py +411 -0
  158. package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/user_profile_memory.py +528 -0
  159. package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/validate_memory.py +226 -0
  160. package/lib/memorax-code-claude-adapter/src/adapter-paths.mjs +46 -0
  161. package/lib/memorax-code-claude-adapter/src/cli.mjs +363 -0
  162. package/lib/memorax-code-claude-adapter/src/config-utils.mjs +1 -0
  163. package/lib/memorax-code-claude-adapter/src/config.mjs +544 -0
  164. package/lib/memorax-code-claude-adapter/src/plugin-artifact-contract.mjs +148 -0
  165. package/lib/memorax-code-claude-adapter/src/plugin-install.mjs +566 -0
  166. package/lib/memorax-code-claude-marketplace/.claude-plugin/marketplace.json +15 -0
  167. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/.claude-plugin/plugin.json +15 -0
  168. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/hooks/hook-launcher.mjs +27 -0
  169. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/hooks/hooks.json +66 -0
  170. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/hooks/repo-memory-job.mjs +37 -0
  171. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/hooks/runtime-hook.mjs +4 -0
  172. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/hooks/runtime-shell.json +5 -0
  173. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/backend-connection.d.mts +111 -0
  174. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/backend-connection.mjs +304 -0
  175. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/clients/claude-command.mjs +38 -0
  176. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/clients/codex-command.mjs +41 -0
  177. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/clients/codex-plugin-artifact.d.mts +3 -0
  178. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/clients/codex-plugin-artifact.mjs +38 -0
  179. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/config-utils.d.mts +27 -0
  180. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/config-utils.mjs +391 -0
  181. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/capture-cwd-hook.mjs +137 -0
  182. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/client-hook-launcher.mjs +324 -0
  183. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/ensure-backend-runner.mjs +142 -0
  184. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/hook-runtime-generation.d.mts +38 -0
  185. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/hook-runtime-generation.mjs +501 -0
  186. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/memory-skill-reminder-hook.mjs +277 -0
  187. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/memorax-code-config-file.d.mts +28 -0
  188. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/memorax-code-config-file.mjs +296 -0
  189. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/memorax-defaults.d.mts +10 -0
  190. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/memorax-defaults.mjs +12 -0
  191. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/repo-memory/repo-memory-job-context.mjs +28 -0
  192. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/repo-memory/repo-memory-job-marker.mjs +252 -0
  193. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/repo-memory/repo-memory-job-supervisor.mjs +559 -0
  194. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/repo-memory/repo-memory-job-worker.mjs +411 -0
  195. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/repo-memory/repo-memory-update-policy-evaluator.mjs +185 -0
  196. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/repo-memory/repo-memory-update-policy.mjs +165 -0
  197. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/repo-memory/repo-procedure-memory-context.mjs +181 -0
  198. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/repo-memory/repo-user-profile-context.mjs +251 -0
  199. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/runtime-record.d.mts +55 -0
  200. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/runtime-record.mjs +152 -0
  201. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/windows-cli-invocation.mjs +100 -0
  202. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/package.json +13 -0
  203. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/runtime-hooks/capture-cwd.mjs +17 -0
  204. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/runtime-hooks/ensure-backend.mjs +59 -0
  205. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/runtime-hooks/memory-cli-session.mjs +33 -0
  206. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/runtime-hooks/memory-skill-reminder.mjs +73 -0
  207. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/runtime-hooks/memory-turn.mjs +91 -0
  208. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/scripts/build-marketplace.mjs +99 -0
  209. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/SKILL.md +83 -0
  210. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/agents/claude.yaml +10 -0
  211. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/agents/openai.yaml +7 -0
  212. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/defaults.json +9 -0
  213. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/memorax-add.md +82 -0
  214. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/memorax-search.md +61 -0
  215. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/personal-read.md +46 -0
  216. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/personal-write.md +100 -0
  217. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/repo-build.md +270 -0
  218. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/repo-read.md +96 -0
  219. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/repo-templates.md +270 -0
  220. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/repo-update.md +116 -0
  221. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/collect_all.py +496 -0
  222. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/detect_updates.py +856 -0
  223. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/git_commit_facets.py +222 -0
  224. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/github_resource_facets.py +504 -0
  225. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +509 -0
  226. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/prepare_repo_memory.py +411 -0
  227. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/user_profile_memory.py +528 -0
  228. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/validate_memory.py +226 -0
  229. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/src/adapter-paths.mjs +46 -0
  230. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/src/cli.mjs +363 -0
  231. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/src/config-utils.mjs +1 -0
  232. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/src/config.mjs +544 -0
  233. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/src/plugin-artifact-contract.mjs +148 -0
  234. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/src/plugin-install.mjs +566 -0
  235. package/lib/memorax-code-codex-adapter/.codex-plugin/plugin.json +33 -0
  236. package/lib/memorax-code-codex-adapter/assets/composer-icon.png +0 -0
  237. package/lib/memorax-code-codex-adapter/assets/logo.png +0 -0
  238. package/lib/memorax-code-codex-adapter/hooks/hook-launcher.mjs +26 -0
  239. package/lib/memorax-code-codex-adapter/hooks/hooks.json +61 -0
  240. package/lib/memorax-code-codex-adapter/hooks/repo-memory-job.mjs +38 -0
  241. package/lib/memorax-code-codex-adapter/hooks/repo-memory-update-policy.mjs +10 -0
  242. package/lib/memorax-code-codex-adapter/hooks/runtime-hook.mjs +4 -0
  243. package/lib/memorax-code-codex-adapter/hooks/runtime-shell.json +5 -0
  244. package/lib/memorax-code-codex-adapter/package.json +13 -0
  245. package/lib/memorax-code-codex-adapter/runtime-hooks/capture-cwd.mjs +18 -0
  246. package/lib/memorax-code-codex-adapter/runtime-hooks/ensure-backend.mjs +82 -0
  247. package/lib/memorax-code-codex-adapter/runtime-hooks/memory-skill-reminder.mjs +125 -0
  248. package/lib/memorax-code-codex-adapter/runtime-hooks/memory-writeback.mjs +52 -0
  249. package/lib/memorax-code-codex-adapter/skills/memorax-code/SKILL.md +83 -0
  250. package/lib/memorax-code-codex-adapter/skills/memorax-code/agents/claude.yaml +10 -0
  251. package/lib/memorax-code-codex-adapter/skills/memorax-code/agents/openai.yaml +7 -0
  252. package/lib/memorax-code-codex-adapter/skills/memorax-code/defaults.json +9 -0
  253. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/memorax-add.md +82 -0
  254. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/memorax-search.md +61 -0
  255. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/personal-read.md +46 -0
  256. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/personal-write.md +100 -0
  257. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/repo-build.md +270 -0
  258. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/repo-read.md +96 -0
  259. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/repo-templates.md +270 -0
  260. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/repo-update.md +116 -0
  261. package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/collect_all.py +496 -0
  262. package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/detect_updates.py +856 -0
  263. package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/git_commit_facets.py +222 -0
  264. package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/github_resource_facets.py +504 -0
  265. package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +509 -0
  266. package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/prepare_repo_memory.py +411 -0
  267. package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/user_profile_memory.py +528 -0
  268. package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/validate_memory.py +226 -0
  269. package/lib/memorax-code-codex-adapter/src/adapter-paths.mjs +29 -0
  270. package/lib/memorax-code-codex-adapter/src/cli.mjs +368 -0
  271. package/lib/memorax-code-codex-adapter/src/config-utils.mjs +1 -0
  272. package/lib/memorax-code-codex-adapter/src/config.mjs +226 -0
  273. package/lib/memorax-code-codex-adapter/src/session-registry.mjs +331 -0
  274. package/lib/memorax-code-codex-adapter/src/workspace-kind.mjs +68 -0
  275. package/lib/node-version.mjs +11 -0
  276. package/lib/npm-invocation.mjs +31 -0
  277. package/lib/resolve-claude-command.mjs +47 -0
  278. package/lib/resolve-codex-command.mjs +94 -0
  279. package/lib/run-entrypoint.mjs +83 -0
  280. package/lib/vscode-extension-command.mjs +119 -0
  281. package/lib/windows-cli-invocation.mjs +100 -0
  282. package/package.json +45 -0
@@ -0,0 +1,567 @@
1
+ import { randomBytes } from "node:crypto";
2
+ import { spawn } from "node:child_process";
3
+ import { closeSync, existsSync, openSync, readFileSync } from "node:fs";
4
+ import { join, resolve } from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
+ import { BackendConnectionAuthorityError, DEFAULT_BACKEND_URL, resolveBackendConnection, writeBackendConnectionAuthority, } from "../../memorax-code-adapter-common/src/backend-connection.mjs";
7
+ import { ensurePrivateDirectory, } from "../../memorax-code-adapter-common/src/runtime-record.mjs";
8
+ import { backendEnv, parseBooleanEnv } from "./backend-env.js";
9
+ import { isProcessAlive, managedServiceCommandLine, probeProcessCommandLine, terminateProcessTree, } from "./backend-process.js";
10
+ import { clearBackendServiceState } from "./backend-service-cleanup.js";
11
+ import { readBackendServiceRecordAtPath, readBackendServiceStateAtPath, writeBackendServiceStateAtPath, } from "./backend-service-record.js";
12
+ import { assertBackendTokenPersistenceEligible } from "./backend-token-record.js";
13
+ import { clearBackendShutdownRequest, writeBackendShutdownRequest, } from "./backend-shutdown-request.js";
14
+ import { runtimeRecordDurabilityWarning, runtimeRecordErrorFields, runtimeRecordServiceFailure, withRuntimeRecordWarnings, } from "./backend-service-result.js";
15
+ import { persistBackendToken, readBackendToken, writeBackendToken, } from "./backend-service-token.js";
16
+ import { backendServiceHome } from "./backend-lifecycle-lock.js";
17
+ import { isLoopbackHost } from "./backend-state.js";
18
+ import { withLoopbackProxyBypass } from "./proxy-env.js";
19
+ export { BACKEND_SERVICE_RECORD_VERSION, BackendServiceStateError, } from "./backend-service-record.js";
20
+ export { isProcessAlive, terminateProcessTree } from "./backend-process.js";
21
+ export { readBackendToken, writeBackendToken };
22
+ function serviceDir(options) {
23
+ return join(backendServiceHome(options), "runtime", "backend");
24
+ }
25
+ function pidPath(options) { return join(serviceDir(options), "backend.pid.json"); }
26
+ function logPath(options) {
27
+ const configured = backendEnv("LOG");
28
+ if (configured)
29
+ return configured;
30
+ return join(serviceDir(options), "backend.log");
31
+ }
32
+ export function readBackendServiceRecordState(options = {}) {
33
+ return readBackendServiceRecordAtPath(pidPath(options));
34
+ }
35
+ export function readBackendServiceState(options = {}) {
36
+ return readBackendServiceStateAtPath(pidPath(options));
37
+ }
38
+ export function backendServiceEndpoint(options = {}) {
39
+ const memoraxCodeHome = backendServiceHome(options);
40
+ let configured;
41
+ try {
42
+ configured = resolveBackendConnection({
43
+ memoraxCodeHome,
44
+ env: { ...process.env, MEMORAX_CODE_BACKEND_URL: undefined },
45
+ });
46
+ }
47
+ catch (error) {
48
+ const hasExplicitBind = options.host !== undefined || options.port !== undefined;
49
+ if (!(error instanceof BackendConnectionAuthorityError) || !hasExplicitBind)
50
+ throw error;
51
+ configured = resolveBackendConnection({
52
+ memoraxCodeHome,
53
+ backendUrl: DEFAULT_BACKEND_URL,
54
+ env: {},
55
+ });
56
+ }
57
+ const host = options.host ?? configured.host;
58
+ const port = options.port ?? configured.port;
59
+ const formattedHost = host.includes(":") && !host.startsWith("[") ? `[${host}]` : host;
60
+ const url = `http://${formattedHost}:${port}`;
61
+ const connection = resolveBackendConnection({
62
+ memoraxCodeHome,
63
+ backendUrl: url,
64
+ backendToken: options.authToken,
65
+ });
66
+ return {
67
+ host,
68
+ port,
69
+ url,
70
+ ...(connection.token ? { authToken: connection.token } : {}),
71
+ ...(connection.tokenSource !== "none" ? { authTokenSource: connection.tokenSource } : {}),
72
+ };
73
+ }
74
+ export function preflightBackendServiceStart(options = {}) {
75
+ const endpoint = backendServiceEndpoint(options);
76
+ const token = backendServiceTokenCandidate(options, endpoint);
77
+ if (token)
78
+ assertBackendTokenPersistenceEligible(backendServiceHome(options));
79
+ return endpoint;
80
+ }
81
+ export async function startBackendService(options = {}, runtime = {}) {
82
+ let endpoint;
83
+ try {
84
+ endpoint = backendServiceEndpoint(options);
85
+ }
86
+ catch (error) {
87
+ return {
88
+ ok: false,
89
+ action: "start",
90
+ error: error instanceof Error ? error.message : String(error),
91
+ ...runtimeRecordErrorFields(error),
92
+ };
93
+ }
94
+ const processAlive = runtime.isProcessAlive ?? isProcessAlive;
95
+ let existing;
96
+ try {
97
+ existing = readBackendServiceState(options);
98
+ }
99
+ catch (error) {
100
+ return runtimeRecordServiceFailure("start", error);
101
+ }
102
+ let token;
103
+ try {
104
+ token = resolveBackendServiceToken(options, endpoint);
105
+ }
106
+ catch (error) {
107
+ return runtimeRecordServiceFailure("start", error);
108
+ }
109
+ const { host, port, url } = endpoint;
110
+ if (existing && processAlive(existing.pid)) {
111
+ const ownership = await readBackendOwnership(existing, options.timeoutMs ?? 5000, backendServiceHome(options), runtime);
112
+ if (canReportRunning(ownership)) {
113
+ return { ok: true, action: "start", alreadyRunning: true, state: existing };
114
+ }
115
+ if (processAlive(existing.pid)) {
116
+ return {
117
+ ok: false,
118
+ action: "start",
119
+ state: existing,
120
+ error: `refusing to replace unverified process ${existing.pid}; ${describeOwnershipFailure(ownership)}; remove stale Backend state after confirming process ownership`,
121
+ };
122
+ }
123
+ }
124
+ if (existing) {
125
+ const cleanup = clearBackendServiceState(pidPath(options), existing, "start");
126
+ if (cleanup)
127
+ return cleanup;
128
+ }
129
+ clearBackendShutdownRequest(backendServiceHome(options));
130
+ ensurePrivateDirectory(serviceDir(options), { durableBoundary: backendServiceHome(options) });
131
+ const logs = logPath(options);
132
+ const outFd = openSync(logs, "a");
133
+ const errFd = openSync(logs, "a");
134
+ const serverPath = fileURLToPath(new URL("./service-entrypoint.js", import.meta.url));
135
+ const instanceId = randomBytes(24).toString("base64url");
136
+ let child;
137
+ try {
138
+ child = (runtime.spawnProcess ?? spawn)(process.execPath, [serverPath, "--memorax-code-backend-instance", instanceId], {
139
+ detached: true,
140
+ env: withLoopbackProxyBypass({
141
+ ...process.env,
142
+ MEMORAX_CODE_HOME: backendServiceHome(options),
143
+ MEMORAX_CODE_BACKEND_HOST: host,
144
+ MEMORAX_CODE_BACKEND_PORT: String(port),
145
+ MEMORAX_CODE_BACKEND_INSTANCE_ID: instanceId,
146
+ ...(options.claudeProjectsRoot === false
147
+ ? { MEMORAX_CODE_MEMORY_VIEWER_CLAUDE_PROJECTS_ROOT: "disabled" }
148
+ : typeof options.claudeProjectsRoot === "string" && options.claudeProjectsRoot.trim()
149
+ ? { MEMORAX_CODE_MEMORY_VIEWER_CLAUDE_PROJECTS_ROOT: resolve(options.claudeProjectsRoot.trim()) }
150
+ : {}),
151
+ ...(token ? { MEMORAX_CODE_BACKEND_TOKEN: token } : {}),
152
+ }, url),
153
+ stdio: ["ignore", outFd, errFd],
154
+ });
155
+ }
156
+ catch (error) {
157
+ closeSync(outFd);
158
+ closeSync(errFd);
159
+ return {
160
+ ok: false,
161
+ action: "start",
162
+ logPath: logs,
163
+ error: `failed to spawn Backend process: ${error instanceof Error ? error.message : String(error)}`,
164
+ };
165
+ }
166
+ closeSync(outFd);
167
+ closeSync(errFd);
168
+ const spawnError = await waitForSpawn(child);
169
+ const childPid = child.pid;
170
+ if (spawnError || !Number.isSafeInteger(childPid) || (childPid ?? 0) <= 0) {
171
+ return {
172
+ ok: false,
173
+ action: "start",
174
+ logPath: logs,
175
+ error: spawnError
176
+ ? `failed to spawn Backend process: ${spawnError.message}`
177
+ : "failed to spawn Backend process: child PID is unavailable",
178
+ };
179
+ }
180
+ child.unref();
181
+ const state = {
182
+ pid: childPid,
183
+ instanceId,
184
+ host,
185
+ port,
186
+ url,
187
+ logPath: logs,
188
+ startedAt: new Date().toISOString(),
189
+ };
190
+ const durabilityWarnings = [];
191
+ try {
192
+ const written = writeBackendServiceStateAtPath(pidPath(options), state, backendServiceHome(options), runtime.recordWriteRuntime);
193
+ const warning = runtimeRecordDurabilityWarning("pid", written);
194
+ if (warning)
195
+ durabilityWarnings.push(warning);
196
+ }
197
+ catch (error) {
198
+ const terminated = (runtime.terminateProcessTree ?? terminateProcessTree)(state.pid);
199
+ if (terminated) {
200
+ await waitUntilStopped(state.pid, options.timeoutMs ?? 5000, processAlive);
201
+ }
202
+ return {
203
+ ok: false,
204
+ action: "start",
205
+ state,
206
+ error: `failed to persist Backend service state: ${error instanceof Error ? error.message : String(error)}`,
207
+ };
208
+ }
209
+ const healthy = await waitForHealth(url, options.timeoutMs ?? 5000, instanceId, backendServiceHome(options), runtime);
210
+ if (!healthy) {
211
+ const terminated = (runtime.terminateProcessTree ?? terminateProcessTree)(state.pid);
212
+ if (terminated) {
213
+ await waitUntilStopped(state.pid, options.timeoutMs ?? 5000, processAlive);
214
+ }
215
+ if (terminated && !processAlive(state.pid)) {
216
+ const cleanup = clearBackendServiceState(pidPath(options), state, "start", `backend did not become healthy at ${url}; process stopped`);
217
+ if (cleanup)
218
+ return cleanup;
219
+ return {
220
+ ok: false,
221
+ action: "start",
222
+ state,
223
+ error: `backend did not become healthy at ${url}`,
224
+ };
225
+ }
226
+ return {
227
+ ok: false,
228
+ action: "start",
229
+ state,
230
+ error: `backend did not become healthy at ${url}; cleanup failed and PID state was retained`,
231
+ };
232
+ }
233
+ try {
234
+ const activeTokenRecord = token
235
+ ? persistBackendToken(options, token, runtime.recordWriteRuntime)
236
+ : undefined;
237
+ const tokenWarning = runtimeRecordDurabilityWarning("token", activeTokenRecord?.persistence);
238
+ if (tokenWarning)
239
+ durabilityWarnings.push(tokenWarning);
240
+ const connectionWrite = writeBackendConnectionAuthority({
241
+ memoraxCodeHome: backendServiceHome(options),
242
+ url,
243
+ ...(activeTokenRecord ? { tokenPath: activeTokenRecord.tokenPath } : {}),
244
+ }, runtime.recordWriteRuntime);
245
+ const connectionWarning = runtimeRecordDurabilityWarning("connection", connectionWrite);
246
+ if (connectionWarning)
247
+ durabilityWarnings.push(connectionWarning);
248
+ }
249
+ catch (error) {
250
+ const terminated = (runtime.terminateProcessTree ?? terminateProcessTree)(state.pid);
251
+ if (terminated) {
252
+ await waitUntilStopped(state.pid, options.timeoutMs ?? 5000, processAlive);
253
+ }
254
+ if (terminated && !processAlive(state.pid)) {
255
+ const cleanup = clearBackendServiceState(pidPath(options), state, "start", `failed to persist Backend connection authority: ${error instanceof Error ? error.message : String(error)}; process stopped`);
256
+ if (cleanup)
257
+ return cleanup;
258
+ }
259
+ return {
260
+ ok: false,
261
+ action: "start",
262
+ state,
263
+ error: `failed to persist Backend connection authority: ${error instanceof Error ? error.message : String(error)}`,
264
+ ...runtimeRecordErrorFields(error),
265
+ };
266
+ }
267
+ return withRuntimeRecordWarnings({ ok: true, action: "start", state }, durabilityWarnings);
268
+ }
269
+ function resolveBackendServiceToken(options, endpoint) {
270
+ const loopback = isLoopbackHost(endpoint.host);
271
+ const serverMode = backendEnv("MODE") === "server";
272
+ const allowExternalAccess = parseBooleanEnv(backendEnv("ALLOW_EXTERNAL")) ?? serverMode;
273
+ if (!loopback && !allowExternalAccess) {
274
+ throw new Error(`external Backend host "${endpoint.host}" is disabled; set MEMORAX_CODE_BACKEND_ALLOW_EXTERNAL=1 and configure MEMORAX_CODE_BACKEND_TOKEN to opt in`);
275
+ }
276
+ const token = backendServiceTokenCandidate(options, endpoint);
277
+ if ((!loopback || serverMode) && !token) {
278
+ throw new Error("MEMORAX_CODE_BACKEND_TOKEN is required for server mode or external Backend access");
279
+ }
280
+ if (token)
281
+ assertBackendTokenPersistenceEligible(backendServiceHome(options));
282
+ return token;
283
+ }
284
+ function backendServiceTokenCandidate(options, endpoint) {
285
+ const loopback = isLoopbackHost(endpoint.host);
286
+ const loopbackAuth = parseBooleanEnv(backendEnv("LOOPBACK_AUTH"));
287
+ const serverMode = backendEnv("MODE") === "server";
288
+ const needsStoredToken = endpoint.authToken === undefined
289
+ && (!loopback || loopbackAuth === true || serverMode);
290
+ const tokenFromFile = needsStoredToken ? readBackendToken(options)?.token : undefined;
291
+ const configuredToken = loopback
292
+ && loopbackAuth === false
293
+ && endpoint.authTokenSource === "authority-file"
294
+ ? undefined
295
+ : endpoint.authToken;
296
+ const token = configuredToken
297
+ ?? (loopback && loopbackAuth !== true ? undefined : tokenFromFile);
298
+ return token;
299
+ }
300
+ export async function stopBackendService(options = {}, runtime = {}) {
301
+ const processAlive = runtime.isProcessAlive ?? isProcessAlive;
302
+ let state;
303
+ try {
304
+ state = readBackendServiceState(options);
305
+ }
306
+ catch (error) {
307
+ return runtimeRecordServiceFailure("stop", error);
308
+ }
309
+ if (!state)
310
+ return { ok: true, action: "stop", alreadyRunning: false };
311
+ if (processAlive(state.pid)) {
312
+ const timeoutMs = options.timeoutMs ?? 5000;
313
+ const windowsInstanceId = (runtime.platform ?? process.platform) === "win32"
314
+ ? state.instanceId
315
+ : undefined;
316
+ if (windowsInstanceId) {
317
+ try {
318
+ writeBackendShutdownRequest(backendServiceHome(options), {
319
+ pid: state.pid,
320
+ instanceId: windowsInstanceId,
321
+ });
322
+ await waitUntilStopped(state.pid, timeoutMs, processAlive);
323
+ }
324
+ catch {
325
+ // A verified process may still be force-stopped below when the private
326
+ // request file cannot be written.
327
+ }
328
+ finally {
329
+ clearBackendShutdownRequest(backendServiceHome(options));
330
+ }
331
+ }
332
+ if (processAlive(state.pid)) {
333
+ const ownership = await readBackendOwnership(state, timeoutMs, backendServiceHome(options), runtime);
334
+ if (processAlive(state.pid)) {
335
+ if (!canForceStop(ownership)) {
336
+ const refusal = windowsInstanceId
337
+ ? `refusing to force-stop process ${state.pid}`
338
+ : `refusing to stop unverified process ${state.pid}`;
339
+ return {
340
+ ok: false,
341
+ action: "stop",
342
+ state,
343
+ error: `${refusal}; ${describeOwnershipFailure(ownership)}`,
344
+ };
345
+ }
346
+ if (!(runtime.terminateProcessTree ?? terminateProcessTree)(state.pid)) {
347
+ return {
348
+ ok: false,
349
+ action: "stop",
350
+ state,
351
+ error: `failed to terminate verified Backend process ${state.pid}`,
352
+ };
353
+ }
354
+ await waitUntilStopped(state.pid, timeoutMs, processAlive);
355
+ if (processAlive(state.pid)) {
356
+ return { ok: false, action: "stop", state, error: `backend process ${state.pid} did not stop` };
357
+ }
358
+ }
359
+ }
360
+ }
361
+ clearBackendShutdownRequest(backendServiceHome(options));
362
+ const cleanup = clearBackendServiceState(pidPath(options), state, "stop", "Backend process stopped");
363
+ if (cleanup)
364
+ return cleanup;
365
+ return { ok: true, action: "stop", state };
366
+ }
367
+ export async function restartBackendService(options = {}, runtime = {}) {
368
+ const stopped = await stopBackendService(options, runtime);
369
+ if (!stopped.ok)
370
+ return { ...stopped, action: "restart" };
371
+ const started = await startBackendService(options, runtime);
372
+ return { ...started, action: "restart" };
373
+ }
374
+ export function backendServiceLogs(options = {}, bytes = 12000) {
375
+ const path = logPath(options);
376
+ if (!existsSync(path))
377
+ return { ok: false, action: "logs", logPath: path, error: "log file does not exist" };
378
+ const text = readFileSync(path, "utf8");
379
+ return { ok: true, action: "logs", logPath: path, text: text.slice(Math.max(0, text.length - bytes)) };
380
+ }
381
+ async function waitForHealth(url, timeoutMs, instanceId, expectedSessionHome, runtime) {
382
+ const budgetMs = Number.isFinite(timeoutMs) ? Math.max(0, Math.trunc(timeoutMs)) : 0;
383
+ const deadline = Date.now() + budgetMs;
384
+ while (Date.now() < deadline) {
385
+ const remainingMs = deadline - Date.now();
386
+ try {
387
+ const health = await readHealthWithTimeout(new URL("/health", url), remainingMs, runtime.fetch);
388
+ if (health.ok
389
+ && health.body.ok === true
390
+ && health.body.service === "memorax-code-backend"
391
+ && health.body.instanceId === instanceId
392
+ && typeof health.body.state?.sessionHome === "string"
393
+ && resolve(health.body.state.sessionHome) === resolve(expectedSessionHome))
394
+ return true;
395
+ }
396
+ catch {
397
+ // Retry until timeout; the child process may still be starting.
398
+ }
399
+ const retryBudgetMs = deadline - Date.now();
400
+ if (retryBudgetMs > 0)
401
+ await sleep(Math.min(100, retryBudgetMs));
402
+ }
403
+ return false;
404
+ }
405
+ async function readBackendOwnership(state, timeoutMs, expectedSessionHome, runtime) {
406
+ if (!isTrustedServiceState(state))
407
+ return { status: "invalid_state" };
408
+ let health = "inconclusive";
409
+ if (isLoopbackHealthUrl(state.url)) {
410
+ try {
411
+ const result = await readHealthWithTimeout(new URL("/health", state.url), timeoutMs, runtime.fetch);
412
+ if (result.ok) {
413
+ health = result.body.ok === true
414
+ && result.body.service === "memorax-code-backend"
415
+ && result.body.instanceId === state.instanceId
416
+ && typeof result.body.state?.sessionHome === "string"
417
+ && resolve(result.body.state.sessionHome) === resolve(expectedSessionHome)
418
+ ? "matched"
419
+ : "conflicting";
420
+ }
421
+ }
422
+ catch {
423
+ // Process evidence can still prove ownership for a hung Backend.
424
+ }
425
+ }
426
+ if (health === "conflicting") {
427
+ return {
428
+ status: "evaluated",
429
+ health,
430
+ process: { status: "not_probed" },
431
+ };
432
+ }
433
+ // Read the process marker after the bounded health probe so PID reuse while
434
+ // awaiting health cannot authorize the following synchronous taskkill path.
435
+ const probe = runtime.probeProcessCommandLine
436
+ ? runtime.probeProcessCommandLine(state.pid)
437
+ : runtime.platform
438
+ ? probeProcessCommandLine(state.pid, { platform: runtime.platform })
439
+ : probeProcessCommandLine(state.pid);
440
+ let processEvidence;
441
+ if (probe.status === "ok") {
442
+ processEvidence = managedServiceCommandLine(probe.commandLine, state.instanceId)
443
+ ? { status: "matched" }
444
+ : { status: "mismatched" };
445
+ }
446
+ else if (probe.status === "not_found") {
447
+ processEvidence = { status: "not_found" };
448
+ }
449
+ else {
450
+ processEvidence = { status: "inconclusive", probe };
451
+ }
452
+ return {
453
+ status: "evaluated",
454
+ health,
455
+ process: processEvidence,
456
+ };
457
+ }
458
+ function canReportRunning(ownership) {
459
+ if (ownership.status !== "evaluated")
460
+ return false;
461
+ if (ownership.health === "conflicting"
462
+ || ownership.process.status === "mismatched"
463
+ || ownership.process.status === "not_found")
464
+ return false;
465
+ return ownership.health === "matched" || ownership.process.status === "matched";
466
+ }
467
+ function canForceStop(ownership) {
468
+ return ownership.status === "evaluated"
469
+ && ownership.health !== "conflicting"
470
+ && ownership.process.status === "matched";
471
+ }
472
+ function describeOwnershipFailure(ownership) {
473
+ if (ownership.status === "invalid_state") {
474
+ return "Backend service state is not trusted";
475
+ }
476
+ if (ownership.health === "conflicting") {
477
+ return "Backend health identity conflicts with the recorded instance";
478
+ }
479
+ if (ownership.process.status === "mismatched") {
480
+ return "process command identity does not match the recorded Backend instance";
481
+ }
482
+ if (ownership.process.status === "not_found") {
483
+ return "the recorded process was not found by the ownership probe";
484
+ }
485
+ if (ownership.process.status === "inconclusive") {
486
+ return describeInconclusiveProcessProbe(ownership.process.probe);
487
+ }
488
+ return "Backend ownership could not be established";
489
+ }
490
+ function describeInconclusiveProcessProbe(probe) {
491
+ if (probe.reason === "timeout") {
492
+ return `ownership probe timed out after ${probe.timeoutMs}ms`;
493
+ }
494
+ const details = [
495
+ probe.reason,
496
+ probe.code ? `code ${probe.code}` : undefined,
497
+ typeof probe.exitCode === "number" ? `exit code ${probe.exitCode}` : undefined,
498
+ probe.signal ? `signal ${probe.signal}` : undefined,
499
+ ].filter((value) => value !== undefined);
500
+ return `ownership probe was inconclusive (${details.join(", ")})`;
501
+ }
502
+ function isTrustedServiceState(state) {
503
+ if (!Number.isSafeInteger(state.pid) || state.pid <= 0)
504
+ return false;
505
+ if (!Number.isSafeInteger(state.port) || state.port <= 0 || state.port > 65535)
506
+ return false;
507
+ try {
508
+ const url = new URL(state.url);
509
+ return url.protocol === "http:" && Number(url.port || "80") === state.port;
510
+ }
511
+ catch {
512
+ return false;
513
+ }
514
+ }
515
+ function isLoopbackHealthUrl(url) {
516
+ try {
517
+ const parsed = new URL(url);
518
+ return parsed.protocol === "http:" && isLoopbackHost(parsed.hostname);
519
+ }
520
+ catch {
521
+ return false;
522
+ }
523
+ }
524
+ function waitForSpawn(child) {
525
+ return new Promise((resolveSpawn) => {
526
+ let settled = false;
527
+ const finish = (error) => {
528
+ if (settled)
529
+ return;
530
+ settled = true;
531
+ resolveSpawn(error);
532
+ };
533
+ child.once("error", finish);
534
+ child.once("spawn", () => finish());
535
+ });
536
+ }
537
+ async function readHealthWithTimeout(url, timeoutMs, fetchImpl = fetch) {
538
+ const controller = new AbortController();
539
+ const boundedTimeoutMs = Math.max(1, Math.min(timeoutMs, 1000));
540
+ const timeout = setTimeout(() => controller.abort(), boundedTimeoutMs);
541
+ try {
542
+ const response = await fetchImpl(url, {
543
+ headers: { connection: "close" },
544
+ signal: controller.signal,
545
+ });
546
+ if (!response.ok)
547
+ return { ok: false, body: {} };
548
+ return {
549
+ ok: true,
550
+ body: await response.json(),
551
+ };
552
+ }
553
+ finally {
554
+ clearTimeout(timeout);
555
+ }
556
+ }
557
+ async function waitUntilStopped(pid, timeoutMs, processAlive = isProcessAlive) {
558
+ const started = Date.now();
559
+ while (Date.now() - started < timeoutMs) {
560
+ if (!processAlive(pid))
561
+ return;
562
+ await sleep(100);
563
+ }
564
+ }
565
+ function sleep(ms) {
566
+ return new Promise((resolve) => setTimeout(resolve, ms));
567
+ }
@@ -0,0 +1,112 @@
1
+ import { createHash } from "node:crypto";
2
+ import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { loadMemoraxCodeConfig } from "./memorax-code-config.js";
5
+ import { isTraceClient } from "./trace-context.js";
6
+ export const TRACE_CLIENTS = ["codex", "claude"];
7
+ export const CODEX_TRACE_DEFAULT_CONFIG = {
8
+ enabled: true,
9
+ captureContent: true,
10
+ retentionDays: 7,
11
+ maxEventChars: 20_000,
12
+ maxFileBytes: 52_428_800,
13
+ };
14
+ export const CLAUDE_TRACE_DEFAULT_CONFIG = {
15
+ enabled: true,
16
+ captureContent: true,
17
+ retentionDays: 7,
18
+ maxEventChars: 20_000,
19
+ maxFileBytes: 52_428_800,
20
+ };
21
+ export const TRACE_CLEANUP_DEBOUNCE_MS = 60 * 60 * 1000;
22
+ export const TRACE_CURRENT_TURN_TTL_MS = 30 * 60 * 1000;
23
+ export const CODEX_TRACE_CLEANUP_DEBOUNCE_MS = TRACE_CLEANUP_DEBOUNCE_MS;
24
+ export const CODEX_TRACE_CURRENT_TURN_TTL_MS = TRACE_CURRENT_TURN_TTL_MS;
25
+ const WINDOWS_RESERVED_PATH_SEGMENT = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\.|$)/i;
26
+ const WINDOWS_REWRITTEN_LABEL_MAX_CHARS = 48;
27
+ export function codexTraceConfigFromEnv(env = process.env, fileConfig) {
28
+ return clientTraceConfigFromEnv("codex", env, fileConfig);
29
+ }
30
+ export function claudeTraceConfigFromEnv(env = process.env, fileConfig) {
31
+ return clientTraceConfigFromEnv("claude", env, fileConfig);
32
+ }
33
+ export function clientTraceConfigFromEnv(client, env = process.env, fileConfig) {
34
+ assertTraceClient(client);
35
+ const config = fileConfig ?? loadMemoraxCodeConfig(memoraxCodeHomeForTrace(env), { warn: () => undefined });
36
+ const section = config.trace?.[client];
37
+ const defaults = client === "claude" ? CLAUDE_TRACE_DEFAULT_CONFIG : CODEX_TRACE_DEFAULT_CONFIG;
38
+ const prefix = client === "claude" ? "MEMORAX_CODE_CLAUDE_TRACE" : "MEMORAX_CODE_CODEX_TRACE";
39
+ return {
40
+ enabled: booleanValue(env[`${prefix}_ENABLED`], section?.enabled ?? defaults.enabled),
41
+ captureContent: booleanValue(env[`${prefix}_CAPTURE_CONTENT`], section?.capture_content ?? defaults.captureContent),
42
+ retentionDays: positiveInteger(env[`${prefix}_RETENTION_DAYS`] ?? section?.retention_days, defaults.retentionDays),
43
+ maxEventChars: positiveInteger(env[`${prefix}_MAX_EVENT_CHARS`] ?? section?.max_event_chars, defaults.maxEventChars),
44
+ maxFileBytes: positiveInteger(env[`${prefix}_MAX_FILE_BYTES`] ?? section?.max_file_bytes, defaults.maxFileBytes),
45
+ };
46
+ }
47
+ export function memoraxCodeHomeForTrace(env = process.env) {
48
+ return env.MEMORAX_CODE_HOME?.trim() || join(homedir(), ".memorax-code");
49
+ }
50
+ export function tracePaths(memoraxCodeHome = memoraxCodeHomeForTrace(process.env)) {
51
+ return clientTracePaths("codex", memoraxCodeHome);
52
+ }
53
+ export function claudeTracePaths(memoraxCodeHome = memoraxCodeHomeForTrace(process.env)) {
54
+ return clientTracePaths("claude", memoraxCodeHome);
55
+ }
56
+ export function clientTracePaths(client, memoraxCodeHome = memoraxCodeHomeForTrace(process.env)) {
57
+ assertTraceClient(client);
58
+ const root = join(memoraxCodeHome, "debug", "traces", client);
59
+ const sessionsRoot = join(root, "sessions");
60
+ const sessionDir = (sessionId) => join(sessionsRoot, sanitizeTracePathSegment(sessionId));
61
+ return {
62
+ root,
63
+ currentTurnPath: join(root, ".current-turn.json"),
64
+ sessionsRoot,
65
+ sessionDir,
66
+ sessionCurrentTurnPath: (sessionId) => join(sessionDir(sessionId), ".current-turn.json"),
67
+ traceJson: (sessionId) => join(sessionDir(sessionId), "trace.json"),
68
+ eventsJsonl: (sessionId) => join(sessionDir(sessionId), "events.jsonl"),
69
+ };
70
+ }
71
+ export function sanitizeTracePathSegment(value, platform = process.platform) {
72
+ const raw = value.trim();
73
+ const normalized = raw.replace(/[^a-zA-Z0-9._-]+/g, "_").replace(/^_+|_+$/g, "");
74
+ const segment = !normalized || normalized === "." || normalized === ".." ? "session" : normalized;
75
+ if (platform !== "win32")
76
+ return segment;
77
+ const withoutTrailingDotsOrSpaces = segment.replace(/[. ]+$/g, "");
78
+ if (withoutTrailingDotsOrSpaces === segment
79
+ && !WINDOWS_RESERVED_PATH_SEGMENT.test(segment)) {
80
+ return segment;
81
+ }
82
+ const label = (withoutTrailingDotsOrSpaces || "session").slice(0, WINDOWS_REWRITTEN_LABEL_MAX_CHARS);
83
+ const hash = createHash("sha256").update(raw).digest("hex").slice(0, 12);
84
+ return `_win_${label}-${hash}`;
85
+ }
86
+ function booleanValue(value, fallback) {
87
+ if (typeof value === "boolean")
88
+ return value;
89
+ if (typeof value !== "string")
90
+ return fallback;
91
+ const normalized = value.trim().toLowerCase();
92
+ if (["1", "true", "yes", "on"].includes(normalized))
93
+ return true;
94
+ if (["0", "false", "no", "off"].includes(normalized))
95
+ return false;
96
+ return fallback;
97
+ }
98
+ function positiveInteger(value, fallback) {
99
+ if (typeof value === "number" && Number.isSafeInteger(value) && value > 0)
100
+ return value;
101
+ if (typeof value !== "string")
102
+ return fallback;
103
+ const normalized = value.trim().replaceAll("_", "");
104
+ if (!/^[1-9]\d*$/.test(normalized))
105
+ return fallback;
106
+ const parsed = Number(normalized);
107
+ return Number.isSafeInteger(parsed) ? parsed : fallback;
108
+ }
109
+ function assertTraceClient(client) {
110
+ if (!isTraceClient(client))
111
+ throw new TypeError("Unsupported trace client");
112
+ }