@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,964 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { resolve } from "node:path";
3
+ import { clearClaudeLocalTranscriptProjections, readClaudeLocalTranscriptHistory, } from "./claude-local-transcript.js";
4
+ import { stripCodexPreambleSegments } from "./codex-effective-prompt.js";
5
+ import { clearIncrementalJsonlProjections, readIncrementalJsonlProjectionSnapshot, } from "./incremental-jsonl-projection.js";
6
+ import { clearMemoryViewerDataProjectionCache, clearMemoryViewerDataProjections, memoryViewerDataProjectionCacheSize, prepareMemoryViewerDataProjectionHistory, readMemoryViewerDataProjection, shareMemoryViewerDataProjectionValue, shouldCacheMemoryViewerDataProjection, writeMemoryViewerDataProjection, } from "./memory-viewer-data-projection-cache.js";
7
+ import { memoryViewerActivityProjection, memoryViewerActivitySummary, } from "./memory-viewer-activity.js";
8
+ import { memoryViewerEventKey } from "./memory-viewer-event-identity.js";
9
+ import { memoryViewerEventTurnIds } from "./memory-viewer-turn-reference.js";
10
+ import { foldMemoryViewerSupersededTurnStarts, foldMemoryViewerTurnMaterializations, } from "./memory-viewer-history-projection.js";
11
+ import { memoryProjectFromUnknown, resolveMemoryProject, UNCLASSIFIED_PROJECT_ID, } from "./memory-project.js";
12
+ import { sanitizeMemoryViewerDetails } from "./memory-viewer-redaction.js";
13
+ import { earliestMemoryViewerSessionTitleCandidates, } from "./memory-viewer-session-title.js";
14
+ import { projectMemoryViewerUserData, } from "./memory-viewer-user-projection.js";
15
+ import { completeMemoryViewerWriteback, foldMemoryViewerWritebackStatuses, memoryText, memoryViewerWritebackOutcome, nonNegativeInteger, pendingMemoryViewerWritebacks, stringArray, writebackOutcomeForStatus, } from "./memory-viewer-writeback-status.js";
16
+ import { clientTracePaths, tracePaths } from "./trace-config.js";
17
+ export { completeMemoryViewerWriteback, memoryViewerEventTurnIds, pendingMemoryViewerWritebacks, };
18
+ const CAPACITY = 200;
19
+ const TURN_CAPACITY = 50;
20
+ export const MEMORY_VIEWER_UNSCOPED_SESSION_FILTER = "__unscoped__";
21
+ const events = [];
22
+ let liveEventsVersion = 0;
23
+ const combinedTraceHistories = new Map();
24
+ const EMPTY_MEMORY_VIEWER_HISTORY = Object.freeze([]);
25
+ const claudeTranscriptSources = new Map();
26
+ export function recordMemoryViewerEvent(input) {
27
+ const client = memoryViewerClient(input);
28
+ const response = record(input.response);
29
+ const request = record(input.request);
30
+ const items = arrayValue(response?.items);
31
+ const query = searchQuery(request);
32
+ const results = searchResults(items);
33
+ const traceSessionId = sessionId(input.traceContext?.sessionId);
34
+ const traceTurnId = safeMemoryViewerTurnId(input.traceContext?.turnId);
35
+ const turnReferences = client === "claude"
36
+ ? memoryViewerTurnReferences(input.relatedTurns, input.traceContext)
37
+ : [];
38
+ const projectIdentity = memoryProjectFromUnknown(input.traceContext?.memoryProject)
39
+ ?? resolveMemoryProject(input.traceContext?.cwd);
40
+ const writeback = writebackState(input.operation, response);
41
+ const conversation = writebackConversation(input.operation, request);
42
+ const id = memoryViewerEventId(client, input.eventId);
43
+ const event = {
44
+ id,
45
+ eventKey: memoryViewerEventKey({
46
+ id,
47
+ client,
48
+ ...(traceSessionId ? { sessionId: traceSessionId } : {}),
49
+ }),
50
+ client,
51
+ type: memoryEventType(input.source, input.operation),
52
+ timestamp: new Date().toISOString(),
53
+ source: input.source,
54
+ operation: input.operation,
55
+ ok: input.ok,
56
+ ...viewerProjectFields(projectIdentity),
57
+ ...(traceSessionId ? { sessionId: traceSessionId } : {}),
58
+ ...(traceTurnId ? { turnId: traceTurnId } : {}),
59
+ ...(turnReferences.length > 0 ? { turnReferences } : {}),
60
+ content: eventContent(input.operation, request, response, items, input.error),
61
+ ...(conversation.prompt ? { prompt: conversation.prompt } : {}),
62
+ ...(conversation.answer ? { answer: conversation.answer } : {}),
63
+ ...(query ? { query } : {}),
64
+ ...(results.length > 0 ? { results } : {}),
65
+ ...(items.length > 0 ? { itemCount: items.length } : {}),
66
+ ...(stringValue(response?.receiptId) ? { receiptId: stringValue(response?.receiptId) } : {}),
67
+ ...(writeback.taskId ? { taskId: writeback.taskId } : {}),
68
+ ...(writeback.status ? { writebackStatus: writeback.status } : {}),
69
+ ...(writeback.status ? { writebackOutcome: writebackOutcomeForStatus(writeback.status) } : {}),
70
+ ...(input.error ? { error: input.error.slice(0, 2000) } : {}),
71
+ details: sanitizeMemoryViewerDetails({ request: input.request, response: input.response }),
72
+ };
73
+ events.push(event);
74
+ while (events.length > CAPACITY)
75
+ events.shift();
76
+ liveEventsVersion += 1;
77
+ clearMemoryViewerDataProjections();
78
+ return event;
79
+ }
80
+ export function listMemoryViewerEvents() {
81
+ return events.map((event) => structuredClone(event));
82
+ }
83
+ export async function listMemoryViewerEventsWithHistory(memoraxCodeHome) {
84
+ return (await listMemoryViewerDataWithHistory(memoraxCodeHome)).events;
85
+ }
86
+ export async function listMemoryViewerDataWithHistory(memoraxCodeHome, filter = {}, dependencies = {}) {
87
+ const claudeProjectsRoot = claudeTranscriptRoot(dependencies.claudeProjectsRoot);
88
+ observeClaudeTranscriptSource(memoraxCodeHome, claudeProjectsRoot);
89
+ const historicalSnapshot = await readTraceHistory(memoraxCodeHome, dependencies.resolveProject ?? resolveMemoryProject, filter.client, claudeProjectsRoot);
90
+ const historical = historicalSnapshot.values;
91
+ const projectionKey = memoryViewerProjectionKey(memoraxCodeHome, filter.client);
92
+ prepareMemoryViewerDataProjectionHistory(projectionKey, historical);
93
+ const filterKey = memoryViewerHistoryFilterKey(filter);
94
+ const cached = readMemoryViewerDataProjection(projectionKey, filterKey, historical, liveEventsVersion);
95
+ if (cached)
96
+ return structuredClone(cached);
97
+ const merged = new Map();
98
+ const liveEvents = filter.client
99
+ ? events.filter((event) => event.client === filter.client)
100
+ : events;
101
+ for (const event of [...historical, ...liveEvents])
102
+ merged.set(event.eventKey, event);
103
+ const traceEvents = [...merged.values()];
104
+ const claudeTranscriptAdmission = admitClaudeTranscriptEvents(traceEvents, historicalSnapshot.claudeLocal);
105
+ const associatedEvents = associateClaudeEventsWithTranscriptTurns(coalesceClaudeTranscriptTurns(traceEvents, claudeTranscriptAdmission.events), historicalSnapshot.claudeLocal, claudeTranscriptAdmission.turnScopes);
106
+ const coalescedEvents = coalesceClaudeTranscriptActivities(associatedEvents);
107
+ const allEvents = foldMemoryViewerSupersededTurnStarts(foldMemoryViewerTurnMaterializations(foldMemoryViewerWritebackStatuses(coalescedEvents.sort(compareMemoryViewerEvents))));
108
+ const selectionCatalogEvents = allEvents.filter(memoryViewerEventVisible);
109
+ const catalogEvents = selectionCatalogEvents;
110
+ const catalogWindow = catalogEvents.slice(-CAPACITY);
111
+ const projects = projectCatalog(catalogWindow);
112
+ const projectSessions = projectSessionCatalog(catalogWindow);
113
+ const hasUnclassified = catalogWindow.some((event) => !event.projectId);
114
+ const selectableEvents = filter.includePendingWritebacks
115
+ ? allEvents.filter((event) => memoryViewerEventVisible(event)
116
+ || (event.operation === "writeback" && event.writebackOutcome === "pending"))
117
+ : catalogEvents;
118
+ const activitySelectionProjects = filter.includePendingWritebacks
119
+ ? projectCatalog(selectableEvents)
120
+ : projectCatalog(selectionCatalogEvents);
121
+ const activitySelectionHasUnclassified = filter.includePendingWritebacks
122
+ ? selectableEvents.some((event) => !event.projectId)
123
+ : selectionCatalogEvents.some((event) => !event.projectId);
124
+ const activityProjects = activitySelectionProjects;
125
+ const activityProjection = memoryViewerActivityProjection(selectableEvents);
126
+ const activityProjectSessions = activityProjection.projectSessions;
127
+ const selection = resolveProjectSelection(activitySelectionProjects, activitySelectionHasUnclassified, filter.projectId, filter.rejectProjectFilter === true);
128
+ const activeSessionSince = filter.activeSessionSince;
129
+ const scopedEvents = (selection.blockAll ? [] : selectableEvents)
130
+ .filter((event) => !filter.eventKey || event.eventKey === filter.eventKey)
131
+ .filter((event) => !filter.unscopedSession && !filter.sessionId
132
+ ? true
133
+ : filter.unscopedSession
134
+ ? !event.sessionId
135
+ : event.sessionId === filter.sessionId)
136
+ .filter((event) => !selection.projectId
137
+ ? true
138
+ : selection.projectId === UNCLASSIFIED_PROJECT_ID
139
+ ? !event.projectId
140
+ : event.projectId === selection.projectId);
141
+ const explicitSession = Boolean(filter.sessionId || filter.unscopedSession);
142
+ const explicitSessionHasRecentActivity = activeSessionSince !== undefined
143
+ && explicitSession
144
+ && scopedEvents.some((event) => ((activityProjection.eventActivityOrder.get(event.eventKey) ?? Number.NEGATIVE_INFINITY) >= activeSessionSince));
145
+ // Active scopes contain complete Turns started inside the window plus recent standalone events.
146
+ // Explicit stale sessions retain historical access.
147
+ const filteredEvents = activeSessionSince === undefined || (explicitSession && !explicitSessionHasRecentActivity)
148
+ ? scopedEvents
149
+ : scopedEvents.filter((event) => ((activityProjection.eventActivityOrder.get(event.eventKey) ?? Number.NEGATIVE_INFINITY) >= activeSessionSince));
150
+ const eventWindow = filteredEvents.slice(-CAPACITY);
151
+ const data = {
152
+ events: eventWindow.map((event) => structuredClone(event)),
153
+ turnEvents: completeTurnEventWindow(filteredEvents, TURN_CAPACITY, eventWindow)
154
+ .map((event) => structuredClone(event)),
155
+ activitySummary: memoryViewerActivitySummary(filteredEvents),
156
+ catalogSourceEvents: selectableEvents.slice(-CAPACITY).map((event) => structuredClone(event)),
157
+ sessionTitleCandidates: shareMemoryViewerDataProjectionValue(projectionKey, `session-titles:${filter.includePendingWritebacks === true}`, historical, liveEventsVersion, () => earliestMemoryViewerSessionTitleCandidates(selectableEvents)),
158
+ projects,
159
+ projectSessions,
160
+ hasUnclassified,
161
+ activityProjects,
162
+ activityProjectSessions,
163
+ ...(filter.includeUserProjection
164
+ ? { userProjection: projectMemoryViewerUserData(filteredEvents) }
165
+ : {}),
166
+ ...(selection.projectId ? { selectedProjectId: selection.projectId } : {}),
167
+ ...(selection.status ? { projectFilterStatus: selection.status } : {}),
168
+ };
169
+ if (shouldCacheMemoryViewerDataProjection(filter, data)) {
170
+ writeMemoryViewerDataProjection(projectionKey, filterKey, historical, liveEventsVersion, data);
171
+ }
172
+ return structuredClone(data);
173
+ }
174
+ function completeTurnEventWindow(allEvents, capacity, requiredEvents = []) {
175
+ const turns = new Map();
176
+ for (const event of allEvents) {
177
+ if (!event.sessionId)
178
+ continue;
179
+ const timestamp = Date.parse(event.timestamp);
180
+ const order = Number.isFinite(timestamp) ? timestamp : 0;
181
+ for (const turnId of memoryViewerEventTurnIds(event)) {
182
+ const key = `${event.client}\u0000${event.sessionId}\u0000${turnId}`;
183
+ const current = turns.get(key);
184
+ if (!current) {
185
+ turns.set(key, {
186
+ startedAt: event.type === "turn_start" ? order : Number.NEGATIVE_INFINITY,
187
+ firstSeenAt: order,
188
+ });
189
+ continue;
190
+ }
191
+ current.firstSeenAt = Math.min(current.firstSeenAt, order);
192
+ if (event.type === "turn_start")
193
+ current.startedAt = order;
194
+ }
195
+ }
196
+ const selected = new Set([...turns.entries()]
197
+ .sort((left, right) => {
198
+ const leftOrder = Number.isFinite(left[1].startedAt) ? left[1].startedAt : left[1].firstSeenAt;
199
+ const rightOrder = Number.isFinite(right[1].startedAt) ? right[1].startedAt : right[1].firstSeenAt;
200
+ return leftOrder - rightOrder || left[0].localeCompare(right[0]);
201
+ })
202
+ .slice(-capacity)
203
+ .map(([key]) => key));
204
+ for (const event of requiredEvents) {
205
+ if (!event.sessionId)
206
+ continue;
207
+ for (const turnId of memoryViewerEventTurnIds(event)) {
208
+ selected.add(`${event.client}\u0000${event.sessionId}\u0000${turnId}`);
209
+ }
210
+ }
211
+ return allEvents.filter((event) => (Boolean(event.sessionId)
212
+ && memoryViewerEventTurnIds(event).some((turnId) => (selected.has(`${event.client}\u0000${event.sessionId}\u0000${turnId}`)))));
213
+ }
214
+ export function clearMemoryViewerEvents() {
215
+ events.length = 0;
216
+ liveEventsVersion += 1;
217
+ combinedTraceHistories.clear();
218
+ claudeTranscriptSources.clear();
219
+ clearClaudeLocalTranscriptProjections();
220
+ clearIncrementalJsonlProjections();
221
+ clearMemoryViewerDataProjectionCache();
222
+ }
223
+ function claudeTranscriptRoot(configuredRoot) {
224
+ return typeof configuredRoot === "string" && configuredRoot.trim()
225
+ ? resolve(configuredRoot.trim())
226
+ : false;
227
+ }
228
+ function observeClaudeTranscriptSource(memoraxCodeHome, source) {
229
+ const key = resolve(memoraxCodeHome);
230
+ const previous = claudeTranscriptSources.get(key);
231
+ claudeTranscriptSources.set(key, source);
232
+ if (previous === undefined || previous === source)
233
+ return;
234
+ clearClaudeLocalTranscriptProjections();
235
+ for (const cacheKey of combinedTraceHistories.keys()) {
236
+ if (cacheKey === key || cacheKey.startsWith(`${key}\u0000`)) {
237
+ combinedTraceHistories.delete(cacheKey);
238
+ }
239
+ }
240
+ clearMemoryViewerDataProjections();
241
+ }
242
+ export function memoryViewerDataProjectionCount(memoraxCodeHome) {
243
+ return memoryViewerDataProjectionCacheSize(tracePaths(memoraxCodeHome).sessionsRoot);
244
+ }
245
+ function memoryViewerHistoryFilterKey(filter) {
246
+ return JSON.stringify([
247
+ filter.client ?? "",
248
+ filter.includePendingWritebacks === true,
249
+ filter.eventKey ?? "",
250
+ filter.sessionId ?? "",
251
+ filter.unscopedSession === true,
252
+ filter.projectId ?? "",
253
+ filter.rejectProjectFilter === true,
254
+ filter.activeSessionSince ?? null,
255
+ filter.includeUserProjection === true,
256
+ ]);
257
+ }
258
+ export function memoryViewerEventVisible(event) {
259
+ return isMemoryViewerEventType(event.type) && event.type !== "memory_writeback_status"
260
+ && event.type !== "turn_materialized";
261
+ }
262
+ function eventContent(operation, request, response, items, error) {
263
+ if (error)
264
+ return error;
265
+ if (operation === "writeback") {
266
+ const payload = record(request?.payload);
267
+ const messages = arrayValue(payload?.messages);
268
+ const contents = messages.map((message) => stringValue(record(message)?.content)).filter(Boolean);
269
+ return contents.join("\n\n") || "Memory writeback accepted.";
270
+ }
271
+ const memories = items.map(memoryText).filter(Boolean);
272
+ if (memories.length > 0)
273
+ return memories.join("\n\n");
274
+ const payload = record(request?.payload);
275
+ return stringValue(payload?.query) || "Memory retrieval completed.";
276
+ }
277
+ async function readTraceHistory(memoraxCodeHome, resolveProject, client, claudeProjectsRoot = false) {
278
+ const historyCacheRoot = resolve(memoraxCodeHome);
279
+ const projectsByCwd = new Map();
280
+ const resolveProjectOnce = (cwd) => {
281
+ const key = cwd?.trim() ?? "";
282
+ if (!key)
283
+ return undefined;
284
+ if (projectsByCwd.has(key))
285
+ return projectsByCwd.get(key);
286
+ const identity = resolveProject(key);
287
+ projectsByCwd.set(key, identity);
288
+ return identity;
289
+ };
290
+ const readClient = (traceClient) => readIncrementalJsonlProjectionSnapshot({
291
+ root: clientTracePaths(traceClient, memoraxCodeHome).sessionsRoot,
292
+ filename: "events.jsonl",
293
+ identity: resolveProject,
294
+ project(value, sessionDir) {
295
+ const event = traceEventToViewerEvent(value, sessionDir, resolveProjectOnce, traceClient);
296
+ if (!event)
297
+ return undefined;
298
+ const retryKey = event.projectId ? "" : traceEventProjectInput(value);
299
+ return { value: event, ...(retryKey ? { retryKey } : {}) };
300
+ },
301
+ refreshEntry(entry) {
302
+ if (!entry.retryKey)
303
+ return false;
304
+ const identity = resolveProjectOnce(entry.retryKey);
305
+ if (!identity)
306
+ return false;
307
+ entry.value = { ...entry.value, ...viewerProjectFields(identity) };
308
+ entry.retryKey = undefined;
309
+ return true;
310
+ },
311
+ compare: compareMemoryViewerEvents,
312
+ });
313
+ if (client === "codex") {
314
+ const codex = await readClient("codex");
315
+ return { ...codex, claudeLocal: EMPTY_MEMORY_VIEWER_HISTORY };
316
+ }
317
+ const claudeLocalPromise = readClaudeLocalTranscriptHistory(claudeProjectsRoot, resolveProject);
318
+ if (client === "claude") {
319
+ const [claude, claudeLocal] = await Promise.all([
320
+ readClient("claude"),
321
+ claudeLocalPromise,
322
+ ]);
323
+ return {
324
+ values: combinedTraceHistory(`${historyCacheRoot}\u0000client=claude\u0000source=${claudeProjectsRoot || "disabled"}`, EMPTY_MEMORY_VIEWER_HISTORY, claude.values, claudeLocal),
325
+ complete: claude.complete,
326
+ claudeLocal,
327
+ };
328
+ }
329
+ const [codex, claude, claudeLocal] = await Promise.all([
330
+ readClient("codex"),
331
+ readClient("claude"),
332
+ claudeLocalPromise,
333
+ ]);
334
+ return {
335
+ values: combinedTraceHistory(`${historyCacheRoot}\u0000client=all\u0000source=${claudeProjectsRoot || "disabled"}`, codex.values, claude.values, claudeLocal),
336
+ complete: codex.complete && claude.complete,
337
+ claudeLocal,
338
+ };
339
+ }
340
+ function combinedTraceHistory(cacheKey, codex, claude, claudeLocal) {
341
+ const cached = combinedTraceHistories.get(cacheKey);
342
+ if (cached?.codex === codex
343
+ && cached.claude === claude
344
+ && cached.claudeLocal === claudeLocal) {
345
+ return cached.values;
346
+ }
347
+ // Native Claude transcripts invalidate this cached identity, but they are
348
+ // admitted only after retained and live Hook trace events are merged.
349
+ const values = [...codex, ...claude].sort(compareMemoryViewerEvents);
350
+ combinedTraceHistories.set(cacheKey, { codex, claude, claudeLocal, values });
351
+ return values;
352
+ }
353
+ function admitClaudeTranscriptEvents(traceEvents, localEvents) {
354
+ const hookProjectsByTurn = new Map();
355
+ for (const event of traceEvents) {
356
+ if (event.client !== "claude"
357
+ || event.type !== "turn_start"
358
+ || event.id.startsWith("claude-local:")
359
+ || !event.sessionId
360
+ || !event.turnId) {
361
+ continue;
362
+ }
363
+ const key = viewerTurnKey(event.client, event.sessionId, event.turnId);
364
+ const projects = hookProjectsByTurn.get(key) ?? new Set();
365
+ projects.add(event.projectId ?? "");
366
+ hookProjectsByTurn.set(key, projects);
367
+ }
368
+ const turnScopes = new Map();
369
+ for (const [key, projects] of hookProjectsByTurn) {
370
+ if (projects.size !== 1)
371
+ continue;
372
+ const projectId = projects.values().next().value;
373
+ turnScopes.set(key, projectId || undefined);
374
+ }
375
+ if (turnScopes.size === 0 || localEvents.length === 0) {
376
+ return { turnScopes, events: EMPTY_MEMORY_VIEWER_HISTORY };
377
+ }
378
+ return { turnScopes, events: localEvents.filter((event) => (claudeTranscriptEventAdmitted(event, turnScopes))) };
379
+ }
380
+ function claudeTranscriptEventAdmitted(event, turnScopes) {
381
+ if (event.client !== "claude" || !event.sessionId || !event.turnId)
382
+ return false;
383
+ const key = viewerTurnKey(event.client, event.sessionId, event.turnId);
384
+ if (!turnScopes.has(key))
385
+ return false;
386
+ const projectId = turnScopes.get(key);
387
+ return event.projectId === projectId;
388
+ }
389
+ function coalesceClaudeTranscriptTurns(traceEvents, localEvents) {
390
+ if (localEvents.length === 0)
391
+ return traceEvents;
392
+ const localByTurn = new Map();
393
+ for (const event of localEvents) {
394
+ const key = claudeTurnLifecycleKey(event);
395
+ if (!key)
396
+ continue;
397
+ const candidates = localByTurn.get(key) ?? [];
398
+ candidates.push(event);
399
+ localByTurn.set(key, candidates);
400
+ }
401
+ const suppressed = new Set();
402
+ const coalesced = traceEvents.map((event) => {
403
+ const key = claudeTurnLifecycleKey(event);
404
+ const candidates = key ? localByTurn.get(key) : undefined;
405
+ if (!key || !candidates)
406
+ return event;
407
+ for (const candidate of candidates)
408
+ suppressed.add(candidate);
409
+ const matching = event.projectId
410
+ ? candidates.filter((candidate) => candidate.projectId === event.projectId)
411
+ : candidates;
412
+ const local = matching.length === 1 ? matching[0] : undefined;
413
+ if (!local)
414
+ return event;
415
+ const project = event.projectId ? {} : viewerProjectFields(memoryProjectFromViewerEvent(local));
416
+ if (event.type === "turn_start") {
417
+ const prompt = local.prompt || event.prompt;
418
+ return {
419
+ ...event,
420
+ ...project,
421
+ ...(prompt ? { prompt, content: prompt } : {}),
422
+ };
423
+ }
424
+ const answer = local.answer || event.answer;
425
+ return {
426
+ ...event,
427
+ ...project,
428
+ ...(answer ? { answer, content: answer } : {}),
429
+ ...((local.turnOutcome === "interrupted" || !event.turnOutcome) && local.turnOutcome
430
+ ? { turnOutcome: local.turnOutcome }
431
+ : {}),
432
+ };
433
+ });
434
+ for (const event of localEvents) {
435
+ if (!suppressed.has(event))
436
+ coalesced.push(event);
437
+ }
438
+ return coalesced;
439
+ }
440
+ function claudeTurnLifecycleKey(event) {
441
+ if (event.client !== "claude"
442
+ || !event.sessionId
443
+ || !event.turnId
444
+ || (event.type !== "turn_start" && event.type !== "turn_end")) {
445
+ return "";
446
+ }
447
+ return `${event.sessionId}\u0000${event.turnId}\u0000${event.type}`;
448
+ }
449
+ function memoryProjectFromViewerEvent(event) {
450
+ return event.projectId && event.projectLabel
451
+ ? { projectId: event.projectId, projectLabel: event.projectLabel }
452
+ : undefined;
453
+ }
454
+ function associateClaudeEventsWithTranscriptTurns(traceEvents, transcriptEvents, admittedTurnScopes) {
455
+ if (transcriptEvents.length === 0)
456
+ return traceEvents;
457
+ const startsBySession = new Map();
458
+ const endsByTurn = new Map();
459
+ for (const event of transcriptEvents) {
460
+ if (event.client !== "claude" || !event.sessionId || !event.turnId)
461
+ continue;
462
+ if (event.type === "turn_start") {
463
+ const starts = startsBySession.get(event.sessionId) ?? [];
464
+ starts.push(event);
465
+ startsBySession.set(event.sessionId, starts);
466
+ }
467
+ else if (event.type === "turn_end") {
468
+ endsByTurn.set(viewerTurnProjectKey(event.client, event.sessionId, event.turnId, event.projectId), event);
469
+ }
470
+ }
471
+ for (const starts of startsBySession.values())
472
+ starts.sort(compareMemoryViewerEvents);
473
+ let changed = false;
474
+ const associated = traceEvents.map((event) => {
475
+ if (event.client !== "claude"
476
+ || !event.sessionId
477
+ || !event.projectId
478
+ || (event.turnId
479
+ && event.type !== "memory_cli_search"
480
+ && event.type !== "memory_cli_add")) {
481
+ return event;
482
+ }
483
+ const starts = startsBySession.get(event.sessionId);
484
+ if (!starts)
485
+ return event;
486
+ const references = event.turnReferences ?? [];
487
+ if (references.length === 0)
488
+ return event;
489
+ const resolvedReferences = references.map((reference) => {
490
+ const owner = transcriptTurnForReference(event, reference, starts, endsByTurn, admittedTurnScopes);
491
+ if (owner?.turnId)
492
+ return { ...reference, turnId: owner.turnId };
493
+ const { turnId: _turnId, ...unassociated } = reference;
494
+ return unassociated;
495
+ });
496
+ const turnIds = [...new Set(resolvedReferences
497
+ .map((reference) => safeMemoryViewerTurnId(reference.turnId))
498
+ .filter(Boolean))];
499
+ changed = true;
500
+ const { turnId: _turnId, ...unassociated } = event;
501
+ if (turnIds.length === 0
502
+ || resolvedReferences.some((reference) => !safeMemoryViewerTurnId(reference.turnId))) {
503
+ return { ...unassociated, turnReferences: resolvedReferences };
504
+ }
505
+ return turnIds.length === 1
506
+ ? { ...unassociated, turnId: turnIds[0], turnReferences: resolvedReferences }
507
+ : { ...unassociated, turnReferences: resolvedReferences };
508
+ });
509
+ return changed ? associated : traceEvents;
510
+ }
511
+ const CLAUDE_NATIVE_ACTIVITY_MATCH_WINDOW_MS = 10 * 60 * 1_000;
512
+ function coalesceClaudeTranscriptActivities(allEvents) {
513
+ const nativeByTurn = new Map();
514
+ for (const event of allEvents) {
515
+ if (!isClaudeNativeMemoryActivity(event) || !event.sessionId)
516
+ continue;
517
+ for (const turnId of memoryViewerEventTurnIds(event)) {
518
+ const key = claudeActivityTurnKey(event.sessionId, turnId, event.type);
519
+ const candidates = nativeByTurn.get(key) ?? [];
520
+ candidates.push(event);
521
+ nativeByTurn.set(key, candidates);
522
+ }
523
+ }
524
+ if (nativeByTurn.size === 0)
525
+ return allEvents;
526
+ for (const candidates of nativeByTurn.values())
527
+ candidates.sort(compareMemoryViewerEvents);
528
+ const suppressed = new Set();
529
+ for (const traceEvent of allEvents) {
530
+ if (!isClaudeTraceMemoryActivity(traceEvent) || !traceEvent.sessionId)
531
+ continue;
532
+ const traceTimes = claudeTraceActivityTimes(traceEvent);
533
+ if (traceTimes.length === 0)
534
+ continue;
535
+ const candidates = memoryViewerEventTurnIds(traceEvent)
536
+ .flatMap((turnId) => nativeByTurn.get(claudeActivityTurnKey(traceEvent.sessionId, turnId, traceEvent.type)) ?? [])
537
+ .filter((candidate) => !suppressed.has(candidate));
538
+ const projectCandidates = traceEvent.projectId
539
+ ? candidates.filter((candidate) => candidate.projectId === traceEvent.projectId)
540
+ : candidates;
541
+ if (!traceEvent.projectId
542
+ && new Set(projectCandidates.map((candidate) => candidate.projectId ?? "")).size > 1) {
543
+ continue;
544
+ }
545
+ const ranked = projectCandidates
546
+ .map((candidate) => ({
547
+ candidate,
548
+ distance: Math.min(...traceTimes.map((traceTime) => (Math.abs(Date.parse(candidate.timestamp) - traceTime)))),
549
+ }))
550
+ .filter((entry) => Number.isFinite(entry.distance))
551
+ .sort((left, right) => (left.distance - right.distance
552
+ || compareMemoryViewerEvents(left.candidate, right.candidate)));
553
+ const nearest = ranked[0];
554
+ if (!nearest
555
+ || nearest.distance > CLAUDE_NATIVE_ACTIVITY_MATCH_WINDOW_MS) {
556
+ continue;
557
+ }
558
+ suppressed.add(nearest.candidate);
559
+ }
560
+ return suppressed.size === 0
561
+ ? allEvents
562
+ : allEvents.filter((event) => !suppressed.has(event));
563
+ }
564
+ function claudeTraceActivityTimes(event) {
565
+ return [event.timestamp, ...(event.turnReferences ?? []).map((reference) => reference.capturedAt)]
566
+ .map((timestamp) => Date.parse(timestamp))
567
+ .filter(Number.isFinite);
568
+ }
569
+ function isClaudeNativeMemoryActivity(event) {
570
+ return event.client === "claude"
571
+ && event.id.startsWith("claude-local:")
572
+ && (event.type === "memory_cli_search" || event.type === "memory_cli_add");
573
+ }
574
+ function isClaudeTraceMemoryActivity(event) {
575
+ return event.client === "claude"
576
+ && !event.id.startsWith("claude-local:")
577
+ && (event.type === "memory_cli_search" || event.type === "memory_cli_add");
578
+ }
579
+ function claudeActivityTurnKey(sessionId, turnId, type) {
580
+ return `${sessionId}\u0000${turnId}\u0000${type}`;
581
+ }
582
+ function transcriptTurnForReference(event, reference, starts, endsByTurn, admittedTurnScopes) {
583
+ const capturedAt = Date.parse(reference.capturedAt);
584
+ if (!Number.isFinite(capturedAt) || !event.sessionId || !event.projectId)
585
+ return undefined;
586
+ const explicitTurnId = safeMemoryViewerTurnId(reference.turnId);
587
+ const candidates = [];
588
+ for (const [index, start] of starts.entries()) {
589
+ if (!start.turnId || start.projectId !== event.projectId)
590
+ continue;
591
+ if (!claudeTranscriptEventAdmitted(start, admittedTurnScopes))
592
+ continue;
593
+ if (explicitTurnId && start.turnId !== explicitTurnId)
594
+ continue;
595
+ const startedAt = Date.parse(start.timestamp);
596
+ if (!Number.isFinite(startedAt) || capturedAt < startedAt)
597
+ continue;
598
+ const end = endsByTurn.get(viewerTurnProjectKey(event.client, event.sessionId, start.turnId, start.projectId));
599
+ const endedAt = end ? Date.parse(end.timestamp) : Number.NaN;
600
+ const nextStart = starts.slice(index + 1).find((candidate) => (candidate.projectId === event.projectId));
601
+ const nextStartedAt = Date.parse(nextStart?.timestamp ?? "");
602
+ if (Number.isFinite(endedAt) && capturedAt > endedAt)
603
+ continue;
604
+ if (!Number.isFinite(endedAt) && Number.isFinite(nextStartedAt) && capturedAt >= nextStartedAt)
605
+ continue;
606
+ candidates.push(start);
607
+ }
608
+ return candidates.length === 1 ? candidates[0] : undefined;
609
+ }
610
+ function memoryViewerTurnReferences(relatedTurns, traceContext) {
611
+ const collect = (values) => {
612
+ const output = [];
613
+ const seen = new Set();
614
+ for (const value of values) {
615
+ const raw = record(value);
616
+ const capturedAt = canonicalOptionalMemoryViewerTimestamp(raw?.captured_at ?? raw?.capturedAt);
617
+ if (!capturedAt)
618
+ continue;
619
+ const turnId = safeMemoryViewerTurnId(raw?.turn_id ?? raw?.turnId);
620
+ const key = `${turnId}\u0000${capturedAt}`;
621
+ if (seen.has(key))
622
+ continue;
623
+ seen.add(key);
624
+ output.push({ ...(turnId ? { turnId } : {}), capturedAt });
625
+ }
626
+ return output;
627
+ };
628
+ const related = collect(arrayValue(relatedTurns));
629
+ return related.length > 0 ? related : collect(traceContext ? [traceContext] : []);
630
+ }
631
+ function viewerTurnKey(client, sessionId, turnId) {
632
+ return `${client}\u0000${sessionId}\u0000${turnId}`;
633
+ }
634
+ function viewerTurnProjectKey(client, sessionId, turnId, projectId) {
635
+ return `${viewerTurnKey(client, sessionId, turnId)}\u0000${projectId ?? ""}`;
636
+ }
637
+ function traceEventProjectInput(value) {
638
+ const raw = record(value);
639
+ const trace = record(raw?.trace);
640
+ if (memoryProjectFromUnknown(trace?.memory_project) || memoryProjectFromUnknown(trace?.memoryProject))
641
+ return "";
642
+ return stringValue(trace?.cwd) || stringValue(record(raw?.request)?.cwd);
643
+ }
644
+ function compareMemoryViewerEvents(left, right) {
645
+ const leftTime = Date.parse(left.timestamp);
646
+ const rightTime = Date.parse(right.timestamp);
647
+ const leftOrder = Number.isFinite(leftTime) ? leftTime : 0;
648
+ const rightOrder = Number.isFinite(rightTime) ? rightTime : 0;
649
+ return leftOrder - rightOrder || left.eventKey.localeCompare(right.eventKey);
650
+ }
651
+ function traceEventToViewerEvent(value, sessionDir, resolveProject, client) {
652
+ const raw = record(value);
653
+ const type = memoryViewerEventType(raw?.type);
654
+ if (!raw || !type)
655
+ return undefined;
656
+ const operation = type === "turn_start"
657
+ ? "query"
658
+ : type === "turn_end" || type === "turn_materialized"
659
+ ? "reply"
660
+ : raw.operation === "writeback"
661
+ ? "writeback"
662
+ : raw.operation === "query"
663
+ ? "query"
664
+ : raw.operation === "retrieve"
665
+ ? "retrieve"
666
+ : undefined;
667
+ if (!operation)
668
+ return undefined;
669
+ const source = typeof raw.source === "string" ? raw.source : "unknown";
670
+ const request = record(raw.request);
671
+ const response = record(raw.response);
672
+ const items = arrayValue(response?.items);
673
+ const query = searchQuery(request);
674
+ const results = searchResults(items);
675
+ const timestamp = canonicalMemoryViewerTimestamp(raw.timestamp);
676
+ const error = stringValue(raw.error);
677
+ const trace = record(raw.trace);
678
+ const turnId = safeMemoryViewerTurnId(stringValue(trace?.turn_id) || stringValue(trace?.turnId));
679
+ const turnReferences = client === "claude"
680
+ ? memoryViewerTurnReferences(raw.related_turns ?? raw.relatedTurns, trace)
681
+ : [];
682
+ const persistedProjectIdentity = memoryProjectFromUnknown(trace?.memory_project)
683
+ ?? memoryProjectFromUnknown(trace?.memoryProject);
684
+ const projectCwd = stringValue(trace?.cwd) || stringValue(request?.cwd);
685
+ // Resolving the persisted cwd rebuilds the process-local project-root index on
686
+ // cold start and verifies any persisted identity before readiness uses it.
687
+ const resolvedProjectIdentity = resolveProject(projectCwd);
688
+ const projectIdentity = resolvedProjectIdentity ?? persistedProjectIdentity;
689
+ const rawTraceSessionId = stringValue(trace?.session_id) || stringValue(trace?.sessionId);
690
+ const traceSessionId = rawTraceSessionId ? sessionId(rawTraceSessionId) : sessionId(sessionDir);
691
+ const writeback = writebackState(operation === "reply" ? "query" : operation, response);
692
+ const persistedOutcome = memoryViewerWritebackOutcome(response?.outcome);
693
+ const savedMemoryCount = nonNegativeInteger(response?.savedMemoryCount ?? response?.saved_memory_count);
694
+ const savedMemoryIds = stringArray(response?.savedMemoryIds ?? response?.saved_memory_ids);
695
+ const savedMemories = stringArray(response?.savedMemories ?? response?.saved_memories);
696
+ const turnOutcome = type === "turn_end" || type === "turn_materialized"
697
+ ? memoryViewerTurnOutcome(raw.outcome) ?? "completed"
698
+ : undefined;
699
+ const writebackMessages = operation === "writeback"
700
+ ? writebackConversation(operation, request)
701
+ : { prompt: "", answer: "" };
702
+ const rawPrompt = stringValue(request?.prompt)
703
+ || stringValue(request?.userPrompt)
704
+ || stringValue(request?.user_prompt);
705
+ const prompt = type === "turn_start" || type === "turn_materialized"
706
+ ? (client === "codex" ? stripCodexPreambleSegments(rawPrompt) : rawPrompt)
707
+ : writebackMessages.prompt;
708
+ const answer = type === "turn_end" || type === "turn_materialized"
709
+ ? stringValue(response?.assistantMessage) || stringValue(response?.assistant_message) || stringValue(response?.answer)
710
+ : writebackMessages.answer;
711
+ const content = type === "turn_start"
712
+ ? prompt || "Turn started."
713
+ : type === "turn_end" || type === "turn_materialized"
714
+ ? answer || (turnOutcome === "interrupted" ? "" : "Turn ended.")
715
+ : eventContent(operation === "reply" ? "query" : operation, request, response, items, error || undefined);
716
+ const eventId = stringValue(raw.event_id) || `${traceSessionId || "unscoped"}:${type}:${timestamp}`;
717
+ const id = persistedMemoryViewerEventId(client, eventId);
718
+ const originalEventId = memoryViewerOriginalEventId(request?.original_event_id ?? request?.originalEventId, client);
719
+ return {
720
+ id,
721
+ eventKey: memoryViewerEventKey({
722
+ id,
723
+ client,
724
+ ...(traceSessionId ? { sessionId: traceSessionId } : {}),
725
+ }),
726
+ client,
727
+ type,
728
+ timestamp,
729
+ source,
730
+ operation,
731
+ ok: raw.ok !== false,
732
+ ...viewerProjectFields(projectIdentity),
733
+ ...(traceSessionId ? { sessionId: traceSessionId } : {}),
734
+ ...(turnId ? { turnId } : {}),
735
+ ...(turnReferences.length > 0 ? { turnReferences } : {}),
736
+ content,
737
+ ...(turnOutcome ? { turnOutcome } : {}),
738
+ ...(prompt ? { prompt } : {}),
739
+ ...(answer ? { answer } : {}),
740
+ ...(query ? { query } : {}),
741
+ ...(results.length > 0 ? { results } : {}),
742
+ ...(items.length > 0 ? { itemCount: items.length } : {}),
743
+ ...(stringValue(response?.receiptId) ? { receiptId: stringValue(response?.receiptId) } : {}),
744
+ ...(writeback.taskId ? { taskId: writeback.taskId } : {}),
745
+ ...(originalEventId ? { originalEventId } : {}),
746
+ ...(writeback.status ? { writebackStatus: writeback.status } : {}),
747
+ ...(persistedOutcome
748
+ ? { writebackOutcome: persistedOutcome }
749
+ : writeback.status ? { writebackOutcome: writebackOutcomeForStatus(writeback.status) } : {}),
750
+ ...(savedMemoryCount === undefined ? {} : { savedMemoryCount }),
751
+ ...(savedMemoryIds.length > 0 ? { savedMemoryIds } : {}),
752
+ ...(savedMemories.length > 0 ? { savedMemories } : {}),
753
+ ...(error ? { error: error.slice(0, 2000) } : {}),
754
+ details: sanitizeMemoryViewerDetails({ request: raw.request, response: raw.response }),
755
+ };
756
+ }
757
+ function memoryViewerTurnOutcome(value) {
758
+ return value === "completed" || value === "interrupted" ? value : undefined;
759
+ }
760
+ function memoryViewerOriginalEventId(value, client) {
761
+ const eventId = stringValue(value);
762
+ if (!eventId)
763
+ return "";
764
+ return persistedMemoryViewerEventId(client, eventId);
765
+ }
766
+ function viewerProjectFields(identity) {
767
+ if (!identity)
768
+ return {};
769
+ return {
770
+ projectId: identity.projectId,
771
+ projectLabel: identity.projectLabel,
772
+ project: identity.projectLabel,
773
+ };
774
+ }
775
+ function projectCatalog(allEvents) {
776
+ const projects = new Map();
777
+ for (const event of allEvents) {
778
+ if (!event.projectId || !event.projectLabel)
779
+ continue;
780
+ const current = projects.get(event.projectId);
781
+ projects.set(event.projectId, {
782
+ projectId: event.projectId,
783
+ projectLabel: event.projectLabel,
784
+ eventCount: (current?.eventCount ?? 0) + 1,
785
+ lastSeenAt: !current || Date.parse(event.timestamp) >= Date.parse(current.lastSeenAt)
786
+ ? event.timestamp
787
+ : current.lastSeenAt,
788
+ });
789
+ }
790
+ return [...projects.values()].sort((left, right) => (left.projectLabel.localeCompare(right.projectLabel) || left.projectId.localeCompare(right.projectId)));
791
+ }
792
+ function projectSessionCatalog(allEvents) {
793
+ const entries = new Map();
794
+ for (const event of allEvents) {
795
+ const projectId = event.projectId ?? UNCLASSIFIED_PROJECT_ID;
796
+ const key = `${event.client}\u0000${projectId}\u0000${event.sessionId ?? ""}`;
797
+ const current = entries.get(key);
798
+ entries.set(key, {
799
+ client: event.client,
800
+ projectId,
801
+ ...(event.sessionId ? { sessionId: event.sessionId } : { unscoped: true }),
802
+ eventCount: (current?.eventCount ?? 0) + 1,
803
+ lastSeenAt: !current || Date.parse(event.timestamp) >= Date.parse(current.lastSeenAt)
804
+ ? event.timestamp
805
+ : current.lastSeenAt,
806
+ });
807
+ }
808
+ return [...entries.values()].sort((left, right) => (left.projectId.localeCompare(right.projectId)
809
+ || left.client.localeCompare(right.client)
810
+ || Date.parse(right.lastSeenAt) - Date.parse(left.lastSeenAt)
811
+ || (left.sessionId ?? "").localeCompare(right.sessionId ?? "")));
812
+ }
813
+ function resolveProjectSelection(projects, hasUnclassified, projectId, rejectProjectFilter) {
814
+ if (rejectProjectFilter)
815
+ return { status: "invalid", blockAll: true };
816
+ if (projectId) {
817
+ const exists = projectId === UNCLASSIFIED_PROJECT_ID
818
+ ? hasUnclassified
819
+ : projects.some((project) => project.projectId === projectId);
820
+ return { projectId, status: exists ? "resolved" : "missing", blockAll: !exists };
821
+ }
822
+ return {};
823
+ }
824
+ function memoryViewerEventType(value) {
825
+ return isMemoryViewerEventType(value) ? value : undefined;
826
+ }
827
+ function isMemoryViewerEventType(value) {
828
+ return value === "turn_start"
829
+ || value === "turn_materialized"
830
+ || value === "memory_retrieve"
831
+ || value === "memory_cli_search"
832
+ || value === "memory_cli_add"
833
+ || value === "memory_writeback"
834
+ || value === "memory_writeback_status"
835
+ || value === "turn_end";
836
+ }
837
+ function memoryEventType(source, operation) {
838
+ if (source === "memory_cli")
839
+ return operation === "writeback" ? "memory_cli_add" : "memory_cli_search";
840
+ return operation === "writeback" ? "memory_writeback" : "memory_retrieve";
841
+ }
842
+ function searchQuery(request) {
843
+ return stringValue(record(request?.payload)?.query) || stringValue(request?.query);
844
+ }
845
+ function searchResults(items) {
846
+ return items
847
+ .map((item) => {
848
+ const value = record(item);
849
+ const content = memoryText(item);
850
+ if (!value || !content)
851
+ return undefined;
852
+ const score = typeof value.score === "number" && Number.isFinite(value.score) ? value.score : undefined;
853
+ const scoreDetails = record(value.score_details);
854
+ const semanticSimilarity = scoreDetails?.semantic_similarity ?? value.semantic_similarity;
855
+ const confidence = typeof semanticSimilarity === "number"
856
+ && Number.isFinite(semanticSimilarity)
857
+ && semanticSimilarity >= 0
858
+ && semanticSimilarity <= 1
859
+ ? semanticSimilarity
860
+ : undefined;
861
+ return {
862
+ content,
863
+ ...(score === undefined ? {} : { score }),
864
+ ...(confidence === undefined ? {} : { confidence }),
865
+ };
866
+ })
867
+ .filter((item) => Boolean(item));
868
+ }
869
+ function writebackConversation(operation, request) {
870
+ if (operation !== "writeback")
871
+ return { prompt: "", answer: "" };
872
+ const messages = arrayValue(record(request?.payload)?.messages);
873
+ const contentsForRole = (role) => messages
874
+ .map(record)
875
+ .filter((message) => stringValue(message?.role).toLowerCase() === role)
876
+ .map((message) => stringValue(message?.content))
877
+ .filter(Boolean)
878
+ .join("\n\n");
879
+ return {
880
+ prompt: contentsForRole("user"),
881
+ answer: contentsForRole("assistant"),
882
+ };
883
+ }
884
+ function writebackState(operation, response) {
885
+ if (operation !== "writeback")
886
+ return { taskId: "", status: "" };
887
+ const raw = record(response?.raw) ?? response;
888
+ const data = record(raw?.data);
889
+ return {
890
+ taskId: stringValue(data?.task_id) || stringValue(response?.taskId),
891
+ status: (stringValue(data?.status)
892
+ || stringValue(response?.status)
893
+ || stringValue(response?.addStatus)).toLowerCase(),
894
+ };
895
+ }
896
+ function record(value) {
897
+ return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
898
+ }
899
+ function arrayValue(value) {
900
+ return Array.isArray(value) ? value : [];
901
+ }
902
+ function stringValue(value) {
903
+ return typeof value === "string" ? value.trim() : "";
904
+ }
905
+ function canonicalMemoryViewerTimestamp(value) {
906
+ if (value === undefined || value === null || value === "")
907
+ return new Date().toISOString();
908
+ return canonicalOptionalMemoryViewerTimestamp(value) ?? new Date(0).toISOString();
909
+ }
910
+ function canonicalOptionalMemoryViewerTimestamp(value) {
911
+ if (typeof value !== "string" || !value.trim() || value.length > 512)
912
+ return "";
913
+ const parsed = Date.parse(value.trim());
914
+ return Number.isFinite(parsed) ? new Date(parsed).toISOString() : "";
915
+ }
916
+ export function safeMemoryViewerSessionId(value) {
917
+ const candidate = typeof value === "string" ? value.trim() : "";
918
+ if (candidate.length > 512)
919
+ return "";
920
+ // This value is reserved by the viewer protocol to select events without a session.
921
+ if (!candidate || candidate === MEMORY_VIEWER_UNSCOPED_SESSION_FILTER)
922
+ return "";
923
+ if (/[\u0000-\u001f\u007f]/.test(candidate))
924
+ return "";
925
+ if (/[\\/]/.test(candidate))
926
+ return "";
927
+ return candidate;
928
+ }
929
+ export function safeMemoryViewerTurnId(value) {
930
+ const candidate = typeof value === "string" ? value.trim() : "";
931
+ if (!candidate || candidate.length > 512)
932
+ return "";
933
+ if (/[\u0000-\u001f\u007f\\/]/.test(candidate))
934
+ return "";
935
+ return candidate;
936
+ }
937
+ function sessionId(value) {
938
+ return safeMemoryViewerSessionId(value);
939
+ }
940
+ function memoryViewerClient(input) {
941
+ if (input.traceContext?.client === "claude")
942
+ return "claude";
943
+ if (input.traceContext?.client === "codex")
944
+ return "codex";
945
+ if (input.source === "claude_hook_retrieval" || input.source === "claude_hook_writeback")
946
+ return "claude";
947
+ return "codex";
948
+ }
949
+ function memoryViewerEventId(client, eventId) {
950
+ if (eventId)
951
+ return persistedMemoryViewerEventId(client, eventId);
952
+ return client === "codex"
953
+ ? `memory-viewer:${randomUUID()}`
954
+ : `claude-memory-viewer:${randomUUID()}`;
955
+ }
956
+ function persistedMemoryViewerEventId(client, eventId) {
957
+ return client === "codex" ? `trace:${eventId}` : `claude-trace:${eventId}`;
958
+ }
959
+ function memoryViewerProjectionKey(memoraxCodeHome, client) {
960
+ if (client === "claude")
961
+ return clientTracePaths("claude", memoraxCodeHome).sessionsRoot;
962
+ const codexSessionsRoot = tracePaths(memoraxCodeHome).sessionsRoot;
963
+ return client === "codex" ? `${codexSessionsRoot}\u0000client=codex` : codexSessionsRoot;
964
+ }