@memorax/memorax-code 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (242) hide show
  1. package/README.md +16 -12
  2. package/bin/memorax-code-npm-preinstall.mjs +7 -2
  3. package/bin/memorax-code-opencode.mjs +4 -0
  4. package/bin/memorax-code-plugin-postinstall.mjs +342 -93
  5. package/docs/configuration.md +148 -35
  6. package/docs/troubleshooting.md +73 -13
  7. package/lib/dsh-plugin-install.mjs +22 -0
  8. package/lib/memorax-code-adapter-common/src/hooks/capture-cwd-hook.mjs +21 -14
  9. package/lib/memorax-code-adapter-common/src/hooks/ensure-backend-runner.mjs +26 -7
  10. package/lib/memorax-code-adapter-common/src/hooks/memory-skill-reminder-hook.mjs +86 -95
  11. package/lib/memorax-code-adapter-common/src/hooks/memory-skill-reminder-policy.mjs +58 -0
  12. package/lib/memorax-code-adapter-common/src/repo-memory/repo-memory-auto-build.mjs +2 -2
  13. package/lib/memorax-code-adapter-common/src/repo-memory/repo-memory-job-supervisor.mjs +1 -1
  14. package/lib/memorax-code-adapter-common/src/windows-cli-invocation.mjs +13 -1
  15. package/lib/memorax-code-backend/dist/app/backend-server.js +210 -0
  16. package/lib/memorax-code-backend/dist/{server-observability.js → app/memory-observability.js} +4 -4
  17. package/lib/memorax-code-backend/dist/{backend-state.js → app/state.js} +1 -1
  18. package/lib/memorax-code-backend/dist/{claude-adapter-lifecycle.js → clients/claude/lifecycle.js} +2 -2
  19. package/lib/memorax-code-backend/dist/{claude-memory-hook-runtime.js → clients/claude/memory-hook-runtime.js} +7 -7
  20. package/lib/memorax-code-backend/dist/clients/codex/lifecycle.js +131 -0
  21. package/lib/memorax-code-backend/dist/{codex-memory-hook-runtime.js → clients/codex/memory-hook-runtime.js} +9 -9
  22. package/lib/memorax-code-backend/dist/{codex-plugin-hooks.js → clients/codex/plugin-hooks.js} +1 -1
  23. package/lib/memorax-code-backend/dist/{codex-plugin-install.js → clients/codex/plugin-install.js} +6 -6
  24. package/lib/memorax-code-backend/dist/clients/dsh/lifecycle.js +75 -0
  25. package/lib/memorax-code-backend/dist/clients/dsh/memory-hook-runtime.js +258 -0
  26. package/lib/memorax-code-backend/dist/clients/dsh/session-turn.js +249 -0
  27. package/lib/memorax-code-backend/dist/clients/opencode/lifecycle.js +54 -0
  28. package/lib/memorax-code-backend/dist/clients/opencode/memory-hook-runtime.js +277 -0
  29. package/lib/memorax-code-backend/dist/clients/opencode/message-turn.js +78 -0
  30. package/lib/memorax-code-backend/dist/codex-adapter-lifecycle.js +1 -131
  31. package/lib/memorax-code-backend/dist/{memorax-code-config.js → config/memorax-code.js} +32 -4
  32. package/lib/memorax-code-backend/dist/{server-cli.js → entrypoints/backend-cli.js} +137 -37
  33. package/lib/memorax-code-backend/dist/jsonl-append.js +1 -75
  34. package/lib/memorax-code-backend/dist/{active-client-selection.js → lifecycle/active-clients.js} +12 -1
  35. package/lib/memorax-code-backend/dist/{backend-service-cleanup.js → lifecycle/backend/cleanup.js} +1 -1
  36. package/lib/memorax-code-backend/dist/{backend-service-record.js → lifecycle/backend/record.js} +1 -1
  37. package/lib/memorax-code-backend/dist/{backend-service-result.js → lifecycle/backend/result.js} +2 -2
  38. package/lib/memorax-code-backend/dist/{service.js → lifecycle/backend/service.js} +16 -16
  39. package/lib/memorax-code-backend/dist/{backend-token-record.js → lifecycle/backend/token-record.js} +1 -1
  40. package/lib/memorax-code-backend/dist/{backend-service-token.js → lifecycle/backend/token.js} +2 -2
  41. package/lib/memorax-code-backend/dist/lifecycle/client-plugin-removal.js +109 -0
  42. package/lib/memorax-code-backend/dist/{client-selection.js → lifecycle/client-selection.js} +11 -5
  43. package/lib/memorax-code-backend/dist/{backend-lifecycle-lock.js → lifecycle/lock.js} +1 -1
  44. package/lib/memorax-code-backend/dist/{memorax-code-lifecycle.js → lifecycle/orchestrator.js} +325 -39
  45. package/lib/memorax-code-backend/dist/memorax-cli.js +1 -1
  46. package/lib/memorax-code-backend/dist/memorax-code.js +1 -1
  47. package/lib/memorax-code-backend/dist/{automatic-memory-retrieval.js → memory/automatic-retrieval.js} +3 -3
  48. package/lib/memorax-code-backend/dist/{automatic-memory-writeback.js → memory/automatic-writeback.js} +75 -21
  49. package/lib/memorax-code-backend/dist/{memory-cli.js → memory/cli.js} +23 -10
  50. package/lib/memorax-code-backend/dist/{memory-hook-command.js → memory/hook-command.js} +156 -9
  51. package/lib/memorax-code-backend/dist/memory/observability.js +1 -0
  52. package/lib/memorax-code-backend/dist/memory/payload-redaction.js +212 -0
  53. package/lib/memorax-code-backend/dist/{memory-reminder-trace-recorder.js → memory/reminder-trace-recorder.js} +20 -7
  54. package/lib/memorax-code-backend/dist/{repository-memory-context.js → memory/repository-session.js} +2 -2
  55. package/lib/memorax-code-backend/dist/{memory-service.js → memory/service.js} +27 -5
  56. package/lib/memorax-code-backend/dist/{memory-turn-coordinator.js → memory/turn-coordinator.js} +2 -1
  57. package/lib/memorax-code-backend/dist/{memory-writeback-buffer.js → memory/writeback-buffer.js} +3 -3
  58. package/lib/memorax-code-backend/dist/{memory-writeback-chunk.js → memory/writeback-chunk.js} +1 -1
  59. package/lib/memorax-code-backend/dist/{memory-writeback-reconciler.js → memory/writeback-reconciler.js} +6 -6
  60. package/lib/memorax-code-backend/dist/{memory-writeback-task-projection.js → memory/writeback-task-projection.js} +4 -4
  61. package/lib/memorax-code-backend/dist/{memorax-adapter.js → provider/memorax/adapter.js} +5 -5
  62. package/lib/memorax-code-backend/dist/{memorax-config.js → provider/memorax/config.js} +4 -4
  63. package/lib/memorax-code-backend/dist/{memorax-http.js → provider/memorax/http.js} +1 -1
  64. package/lib/memorax-code-backend/dist/{repo-memory-readiness.js → repository/readiness.js} +3 -3
  65. package/lib/memorax-code-backend/dist/server.js +3 -212
  66. package/lib/memorax-code-backend/dist/service-entrypoint.js +1 -1
  67. package/lib/memorax-code-backend/dist/{debug-log.js → shared/debug-log.js} +1 -1
  68. package/lib/memorax-code-backend/dist/shared/jsonl-append.js +75 -0
  69. package/lib/memorax-code-backend/dist/shared/windows-cli-invocation.js +148 -0
  70. package/lib/memorax-code-backend/dist/{trace-config.js → trace/config.js} +43 -5
  71. package/lib/memorax-code-backend/dist/{trace-context.js → trace/context.js} +53 -2
  72. package/lib/memorax-code-backend/dist/{trace-store.js → trace/store.js} +3 -3
  73. package/lib/memorax-code-backend/dist/{server-health.js → transport/http/health.js} +1 -1
  74. package/lib/memorax-code-backend/dist/{server-memory-hook.js → transport/http/memory-hook.js} +3 -3
  75. package/lib/memorax-code-backend/dist/{server-http.js → transport/http/request.js} +1 -1
  76. package/lib/memorax-code-backend/dist/{claude-local-transcript.js → viewer/history/claude-transcript.js} +3 -3
  77. package/lib/memorax-code-backend/dist/{memory-viewer-session-title.js → viewer/history/session-title.js} +1 -1
  78. package/lib/memorax-code-backend/dist/{server-memory-viewer.js → viewer/http/public-routes.js} +15 -15
  79. package/lib/memorax-code-backend/dist/viewer/model.js +1 -0
  80. package/lib/memorax-code-backend/dist/{memory-viewer-activity.js → viewer/projection/activity.js} +2 -2
  81. package/lib/memorax-code-backend/dist/{memory-viewer-history-projection.js → viewer/projection/history.js} +1 -1
  82. package/lib/memorax-code-backend/dist/{memory-viewer-observability.js → viewer/projection/observability.js} +1 -1
  83. package/lib/memorax-code-backend/dist/{memory-viewer-user-projection.js → viewer/projection/user.js} +1 -1
  84. package/lib/memorax-code-backend/dist/{memory-viewer-writeback-status.js → viewer/projection/writeback-status.js} +1 -1
  85. package/lib/memorax-code-backend/dist/{memory-viewer-store.js → viewer/store.js} +59 -32
  86. package/lib/memorax-code-backend/dist/{memory-viewer-user-html.js → viewer/ui/user-html.js} +11 -10
  87. package/lib/memorax-code-backend/dist/windows-cli-invocation.js +1 -148
  88. package/lib/memorax-code-backend/package.json +3 -3
  89. package/lib/memorax-code-claude-adapter/.claude-plugin/plugin.json +1 -1
  90. package/lib/memorax-code-claude-adapter/hooks/runtime-shell.json +1 -1
  91. package/lib/memorax-code-claude-adapter/package.json +1 -1
  92. package/lib/memorax-code-claude-adapter/skills/memorax-code/SKILL.md +11 -2
  93. package/lib/memorax-code-claude-adapter/skills/memorax-code/defaults.json +8 -5
  94. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/memorax-add.md +1 -1
  95. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/memorax-search.md +37 -9
  96. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/personal-read.md +1 -1
  97. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/personal-write.md +33 -13
  98. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/repo-build.md +62 -13
  99. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/repo-read.md +11 -4
  100. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/repo-templates.md +179 -59
  101. package/lib/memorax-code-claude-adapter/skills/memorax-code/references/repo-update.md +18 -7
  102. package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/collect_all.py +122 -39
  103. package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/detect_updates.py +73 -10
  104. package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/github_resource_facets.py +9 -1
  105. package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +9 -1
  106. package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/validate_memory.py +23 -1
  107. package/lib/memorax-code-claude-adapter/src/plugin-install.mjs +1 -0
  108. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/.claude-plugin/plugin.json +1 -1
  109. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/hooks/runtime-shell.json +1 -1
  110. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/capture-cwd-hook.mjs +21 -14
  111. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/ensure-backend-runner.mjs +26 -7
  112. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/memory-skill-reminder-hook.mjs +86 -95
  113. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/memory-skill-reminder-policy.mjs +58 -0
  114. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/repo-memory/repo-memory-auto-build.mjs +2 -2
  115. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/repo-memory/repo-memory-job-supervisor.mjs +1 -1
  116. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/windows-cli-invocation.mjs +13 -1
  117. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/package.json +1 -1
  118. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/SKILL.md +11 -2
  119. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/defaults.json +8 -5
  120. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/memorax-add.md +1 -1
  121. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/memorax-search.md +37 -9
  122. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/personal-read.md +1 -1
  123. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/personal-write.md +33 -13
  124. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/repo-build.md +62 -13
  125. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/repo-read.md +11 -4
  126. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/repo-templates.md +179 -59
  127. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/repo-update.md +18 -7
  128. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/collect_all.py +122 -39
  129. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/detect_updates.py +73 -10
  130. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/github_resource_facets.py +9 -1
  131. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +9 -1
  132. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/validate_memory.py +23 -1
  133. package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/src/plugin-install.mjs +1 -0
  134. package/lib/memorax-code-codex-adapter/.codex-plugin/plugin.json +1 -1
  135. package/lib/memorax-code-codex-adapter/hooks/runtime-shell.json +1 -1
  136. package/lib/memorax-code-codex-adapter/package.json +1 -1
  137. package/lib/memorax-code-codex-adapter/runtime-hooks/memory-skill-reminder.mjs +10 -2
  138. package/lib/memorax-code-codex-adapter/skills/memorax-code/SKILL.md +11 -2
  139. package/lib/memorax-code-codex-adapter/skills/memorax-code/defaults.json +8 -5
  140. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/memorax-add.md +1 -1
  141. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/memorax-search.md +37 -9
  142. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/personal-read.md +1 -1
  143. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/personal-write.md +33 -13
  144. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/repo-build.md +62 -13
  145. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/repo-read.md +11 -4
  146. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/repo-templates.md +179 -59
  147. package/lib/memorax-code-codex-adapter/skills/memorax-code/references/repo-update.md +18 -7
  148. package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/collect_all.py +122 -39
  149. package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/detect_updates.py +73 -10
  150. package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/github_resource_facets.py +9 -1
  151. package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +9 -1
  152. package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/validate_memory.py +23 -1
  153. package/lib/memorax-code-dsh-adapter/cordis.patch.yml +10 -0
  154. package/lib/memorax-code-dsh-adapter/hooks/repo-memory-job.mjs +68 -0
  155. package/lib/memorax-code-dsh-adapter/package.json +69 -0
  156. package/lib/memorax-code-dsh-adapter/skills/memorax-code/SKILL.md +91 -0
  157. package/lib/memorax-code-dsh-adapter/skills/memorax-code/agents/claude.yaml +10 -0
  158. package/lib/memorax-code-dsh-adapter/skills/memorax-code/agents/openai.yaml +7 -0
  159. package/lib/memorax-code-dsh-adapter/skills/memorax-code/defaults.json +12 -0
  160. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/memorax-add.md +86 -0
  161. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/memorax-search.md +91 -0
  162. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/personal-read.md +46 -0
  163. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/personal-write.md +120 -0
  164. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/repo-build.md +319 -0
  165. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/repo-read.md +103 -0
  166. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/repo-templates.md +390 -0
  167. package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/repo-update.md +127 -0
  168. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/collect_all.py +579 -0
  169. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/detect_updates.py +919 -0
  170. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/git_commit_facets.py +222 -0
  171. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/github_resource_facets.py +512 -0
  172. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +517 -0
  173. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/prepare_repo_memory.py +411 -0
  174. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/user_profile_memory.py +528 -0
  175. package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/validate_memory.py +248 -0
  176. package/lib/memorax-code-dsh-adapter/src/backend-client.mjs +119 -0
  177. package/lib/memorax-code-dsh-adapter/src/dsh-message.mjs +32 -0
  178. package/lib/memorax-code-dsh-adapter/src/dsh-version.mjs +18 -0
  179. package/lib/memorax-code-dsh-adapter/src/http-client.mjs +55 -0
  180. package/lib/memorax-code-dsh-adapter/src/index.mjs +72 -0
  181. package/lib/memorax-code-dsh-adapter/src/personal-context-worker.mjs +48 -0
  182. package/lib/memorax-code-dsh-adapter/src/personal-context.mjs +114 -0
  183. package/lib/memorax-code-dsh-adapter/src/plugin.mjs +724 -0
  184. package/lib/memorax-code-dsh-adapter/src/profile-lifecycle.mjs +1358 -0
  185. package/lib/memorax-code-dsh-adapter/src/protocol.mjs +145 -0
  186. package/lib/memorax-code-dsh-adapter/src/runtime-state.mjs +132 -0
  187. package/lib/memorax-code-opencode-adapter/hooks/repo-memory-job.mjs +37 -0
  188. package/lib/memorax-code-opencode-adapter/package.json +10 -0
  189. package/lib/memorax-code-opencode-adapter/skills/memorax-code/SKILL.md +91 -0
  190. package/lib/memorax-code-opencode-adapter/skills/memorax-code/agents/claude.yaml +10 -0
  191. package/lib/memorax-code-opencode-adapter/skills/memorax-code/agents/openai.yaml +7 -0
  192. package/lib/memorax-code-opencode-adapter/skills/memorax-code/defaults.json +12 -0
  193. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/memorax-add.md +86 -0
  194. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/memorax-search.md +91 -0
  195. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/personal-read.md +46 -0
  196. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/personal-write.md +120 -0
  197. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/repo-build.md +319 -0
  198. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/repo-read.md +103 -0
  199. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/repo-templates.md +390 -0
  200. package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/repo-update.md +127 -0
  201. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/collect_all.py +579 -0
  202. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/detect_updates.py +919 -0
  203. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/git_commit_facets.py +222 -0
  204. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/github_resource_facets.py +512 -0
  205. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +517 -0
  206. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/prepare_repo_memory.py +411 -0
  207. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/user_profile_memory.py +528 -0
  208. package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/validate_memory.py +248 -0
  209. package/lib/memorax-code-opencode-adapter/src/adapter-paths.mjs +37 -0
  210. package/lib/memorax-code-opencode-adapter/src/cli.mjs +260 -0
  211. package/lib/memorax-code-opencode-adapter/src/diagnostics.mjs +31 -0
  212. package/lib/memorax-code-opencode-adapter/src/plugin-install.mjs +673 -0
  213. package/lib/memorax-code-opencode-adapter/src/plugin.mjs +539 -0
  214. package/lib/memorax-code-opencode-adapter/src/repo-memory-server-runner.mjs +442 -0
  215. package/lib/run-entrypoint.mjs +6 -0
  216. package/package.json +7 -3
  217. package/lib/memorax-code-backend/dist/client-plugin-removal.js +0 -67
  218. /package/lib/memorax-code-backend/dist/{claude-transcript-turn.js → clients/claude/transcript-turn.js} +0 -0
  219. /package/lib/memorax-code-backend/dist/{codex-effective-prompt.js → clients/codex/effective-prompt.js} +0 -0
  220. /package/lib/memorax-code-backend/dist/{codex-rollout-turn.js → clients/codex/rollout-turn.js} +0 -0
  221. /package/lib/memorax-code-backend/dist/{codex-session-turn-index.js → clients/codex/session-turn-index.js} +0 -0
  222. /package/lib/memorax-code-backend/dist/{codex-workspace-links.js → clients/codex/workspace-links.js} +0 -0
  223. /package/lib/memorax-code-backend/dist/{backend-env.js → config/backend-env.js} +0 -0
  224. /package/lib/memorax-code-backend/dist/{proxy-env.js → config/proxy-env.js} +0 -0
  225. /package/lib/memorax-code-backend/dist/{entrypoint.js → entrypoints/main.js} +0 -0
  226. /package/lib/memorax-code-backend/dist/{backend-process.js → lifecycle/backend/process.js} +0 -0
  227. /package/lib/memorax-code-backend/dist/{backend-shutdown-request.js → lifecycle/backend/shutdown-request.js} +0 -0
  228. /package/lib/memorax-code-backend/dist/{backend-status.js → lifecycle/backend/status.js} +0 -0
  229. /package/lib/memorax-code-backend/dist/{adapter-lifecycle-participant.js → lifecycle/contracts.js} +0 -0
  230. /package/lib/memorax-code-backend/dist/{install-watchdog.js → lifecycle/install-watchdog.js} +0 -0
  231. /package/lib/memorax-code-backend/dist/{memory-observability.js → lifecycle/participant.js} +0 -0
  232. /package/lib/memorax-code-backend/dist/{memory-project.js → memory/project.js} +0 -0
  233. /package/lib/memorax-code-backend/dist/{repository-memory-scope.js → repository/scope.js} +0 -0
  234. /package/lib/memorax-code-backend/dist/{incremental-jsonl-projection.js → shared/incremental-jsonl-projection.js} +0 -0
  235. /package/lib/memorax-code-backend/dist/{utils.js → shared/record.js} +0 -0
  236. /package/lib/memorax-code-backend/dist/{server-json.js → transport/http/json.js} +0 -0
  237. /package/lib/memorax-code-backend/dist/{memory-viewer-data-projection-cache.js → viewer/projection/cache.js} +0 -0
  238. /package/lib/memorax-code-backend/dist/{memory-viewer-event-identity.js → viewer/projection/event-identity.js} +0 -0
  239. /package/lib/memorax-code-backend/dist/{memory-viewer-redaction.js → viewer/projection/redaction.js} +0 -0
  240. /package/lib/memorax-code-backend/dist/{memory-viewer-turn-reference.js → viewer/projection/turn-reference.js} +0 -0
  241. /package/lib/memorax-code-backend/dist/{memory-viewer-icon.js → viewer/ui/icon.js} +0 -0
  242. /package/lib/memorax-code-backend/dist/{memory-viewer-logo.js → viewer/ui/logo.js} +0 -0
@@ -13,6 +13,15 @@ from typing import Any, Optional
13
13
  SCRIPT_DIR = Path(__file__).resolve().parent
14
14
  DEFAULTS_PATH = SCRIPT_DIR.parent / "defaults.json"
15
15
  FALLBACK_DEFAULTS = {
16
+ "repoHistory": {
17
+ "mode": "provider",
18
+ "limits": {
19
+ "commits": 30,
20
+ "prs": 30,
21
+ "issues": 30,
22
+ },
23
+ },
24
+ # Kept for compatibility with defaults.json v1.
16
25
  "limits": {
17
26
  "commits": 30,
18
27
  "prs": 30,
@@ -21,6 +30,8 @@ FALLBACK_DEFAULTS = {
21
30
  "summaryChars": 4000,
22
31
  }
23
32
 
33
+ HISTORY_MODES = {"none", "commits-only", "local-only", "provider", "provider-required"}
34
+
24
35
 
25
36
  class ProgressBar:
26
37
  def __init__(self, enabled: bool, total: int) -> None:
@@ -102,6 +113,7 @@ def write_failure(
102
113
  steps: Optional[dict[str, Any]] = None,
103
114
  outputs: Optional[dict[str, str]] = None,
104
115
  notices: Optional[list[dict[str, Any]]] = None,
116
+ effective_settings: Optional[dict[str, Any]] = None,
105
117
  ) -> int:
106
118
  emit_process_output(result)
107
119
  step_reports = dict(steps or {})
@@ -121,6 +133,8 @@ def write_failure(
121
133
  report["outputs"] = outputs
122
134
  if notices:
123
135
  report["notices"] = notices
136
+ if effective_settings is not None:
137
+ report["effective_settings"] = effective_settings
124
138
  write_report(report, pretty)
125
139
  return result.returncode or 1
126
140
 
@@ -234,16 +248,53 @@ def validate_range(parser: argparse.ArgumentParser, name: str, value: int, minim
234
248
  parser.error(f"{name} must be from {minimum} to {maximum}")
235
249
 
236
250
 
251
+ def default_history_mode(settings: dict[str, Any]) -> str:
252
+ history = settings.get("repoHistory")
253
+ if not isinstance(history, dict):
254
+ return "provider"
255
+ mode = history.get("mode", "provider")
256
+ if not isinstance(mode, str) or mode not in HISTORY_MODES:
257
+ raise ValueError(f"{DEFAULTS_PATH}: repoHistory.mode must be one of {', '.join(sorted(HISTORY_MODES))}")
258
+ return mode
259
+
260
+
261
+ def default_limit(settings: dict[str, Any], key: str) -> int:
262
+ history = settings.get("repoHistory")
263
+ if isinstance(history, dict) and isinstance(history.get("limits"), dict) and history["limits"].get(key) is not None:
264
+ return default_int(settings, ["repoHistory", "limits", key], FALLBACK_DEFAULTS["repoHistory"]["limits"][key])
265
+ return default_int(settings, ["limits", key], FALLBACK_DEFAULTS["limits"][key])
266
+
267
+
268
+ def history_collect(mode: str) -> dict[str, bool]:
269
+ return {
270
+ "commits": mode != "none",
271
+ "provider": mode in {"provider", "provider-required"},
272
+ }
273
+
274
+
275
+ def resolve_history_mode(args: argparse.Namespace, default_mode: str) -> str:
276
+ mode = args.history_mode or default_mode
277
+ if args.skip_provider:
278
+ mode = "local-only"
279
+ if args.require_provider:
280
+ mode = "provider-required"
281
+ return mode
282
+
283
+
237
284
  def apply_effective_settings(args: argparse.Namespace, parser: argparse.ArgumentParser) -> argparse.Namespace:
238
285
  try:
239
286
  defaults, source = load_default_settings()
240
- default_commit_limit = default_int(defaults, ["limits", "commits"], FALLBACK_DEFAULTS["limits"]["commits"])
241
- default_pr_limit = default_int(defaults, ["limits", "prs"], FALLBACK_DEFAULTS["limits"]["prs"])
242
- default_issue_limit = default_int(defaults, ["limits", "issues"], FALLBACK_DEFAULTS["limits"]["issues"])
287
+ default_mode = default_history_mode(defaults)
288
+ default_commit_limit = default_limit(defaults, "commits")
289
+ default_pr_limit = default_limit(defaults, "prs")
290
+ default_issue_limit = default_limit(defaults, "issues")
243
291
  default_summary_chars = default_int(defaults, ["summaryChars"], FALLBACK_DEFAULTS["summaryChars"])
244
292
  except ValueError as exc:
245
293
  parser.error(str(exc))
246
294
 
295
+ history_mode = resolve_history_mode(args, default_mode)
296
+ collect = history_collect(history_mode)
297
+
247
298
  commit_limit = args.commit_limit if args.commit_limit is not None else default_commit_limit
248
299
  pr_limit = args.pr_limit if args.pr_limit is not None else default_pr_limit
249
300
  issue_limit = args.issue_limit if args.issue_limit is not None else default_issue_limit
@@ -255,7 +306,13 @@ def apply_effective_settings(args: argparse.Namespace, parser: argparse.Argument
255
306
  if summary_chars < 100:
256
307
  parser.error("--summary-chars must be at least 100")
257
308
 
258
- overrides: dict[str, int] = {}
309
+ overrides: dict[str, Any] = {}
310
+ if args.history_mode is not None:
311
+ overrides["history_mode"] = args.history_mode
312
+ if args.skip_provider:
313
+ overrides["skip_provider"] = True
314
+ if args.require_provider:
315
+ overrides["require_provider"] = True
259
316
  if args.commit_limit is not None:
260
317
  overrides["commit_limit"] = args.commit_limit
261
318
  if args.pr_limit is not None:
@@ -269,7 +326,13 @@ def apply_effective_settings(args: argparse.Namespace, parser: argparse.Argument
269
326
  args.pr_limit = pr_limit
270
327
  args.issue_limit = issue_limit
271
328
  args.summary_chars = summary_chars
329
+ args.history_mode = history_mode
330
+ args.history_collect = collect
272
331
  args.effective_settings = {
332
+ "history": {
333
+ "mode": history_mode,
334
+ "collect": collect,
335
+ },
273
336
  "limits": {
274
337
  "commits": commit_limit,
275
338
  "prs": pr_limit,
@@ -291,6 +354,7 @@ def parse_args(argv: list[str]) -> argparse.Namespace:
291
354
  parser.add_argument("--pr-limit", type=int, default=None, help="Maximum snapshot-filtered PRs/MRs retained")
292
355
  parser.add_argument("--issue-limit", type=int, default=None, help="Maximum provider issues retained")
293
356
  parser.add_argument("--summary-chars", type=int, default=None)
357
+ parser.add_argument("--history-mode", choices=sorted(HISTORY_MODES), default=None, help="History evidence policy for this build")
294
358
  parser.add_argument("--skip-provider", action="store_true", help="Skip GitHub/GitLab PR/MR/issue collection and build local-only memory")
295
359
  parser.add_argument("--require-provider", action="store_true", help="Fail if provider PR/MR/issue evidence cannot be collected")
296
360
  parser.add_argument("--pretty", action="store_true", help="Pretty-print JSON")
@@ -302,6 +366,10 @@ def parse_args(argv: list[str]) -> argparse.Namespace:
302
366
  args = parser.parse_args(argv)
303
367
  if args.skip_provider and args.require_provider:
304
368
  parser.error("--skip-provider and --require-provider cannot be used together")
369
+ if args.history_mode and args.skip_provider and args.history_mode != "local-only":
370
+ parser.error(f"--skip-provider cannot be combined with --history-mode {args.history_mode}")
371
+ if args.history_mode and args.require_provider and args.history_mode != "provider-required":
372
+ parser.error("--require-provider cannot be combined with a non-required history mode")
305
373
  args.repo_path = Path(args.repo_path).expanduser().resolve()
306
374
  return apply_effective_settings(args, parser)
307
375
 
@@ -330,38 +398,50 @@ def main(argv: list[str]) -> int:
330
398
  notices = provider_notices(prepare_data)
331
399
 
332
400
  git_commits_path = raw_dir / "git-commits.json"
333
- git_commits = run_step(
334
- [
335
- sys.executable,
336
- str(SCRIPT_DIR / "git_commit_facets.py"),
337
- "--repo-path",
338
- str(repo),
339
- "--snapshot-ref",
340
- args.snapshot_ref,
341
- "--limit",
342
- str(args.commit_limit),
343
- "--summary-chars",
344
- str(args.summary_chars),
345
- "--out",
346
- str(git_commits_path),
347
- ],
348
- repo,
349
- )
350
401
  outputs = {
351
402
  "prepare_report": str(prepare_report_path),
352
403
  "git_commits": str(git_commits_path),
353
404
  }
354
- if git_commits.returncode != 0:
355
- progress.fail(1, "git commits failed")
356
- return write_failure(
357
- "git_commits",
358
- git_commits,
359
- args.pretty,
360
- repo=repo,
361
- memory=memory,
362
- steps={"prepare": json_step(prepare)},
363
- outputs=outputs,
405
+ if args.history_collect["commits"]:
406
+ git_commits = run_step(
407
+ [
408
+ sys.executable,
409
+ str(SCRIPT_DIR / "git_commit_facets.py"),
410
+ "--repo-path",
411
+ str(repo),
412
+ "--snapshot-ref",
413
+ args.snapshot_ref,
414
+ "--limit",
415
+ str(args.commit_limit),
416
+ "--summary-chars",
417
+ str(args.summary_chars),
418
+ "--out",
419
+ str(git_commits_path),
420
+ ],
421
+ repo,
364
422
  )
423
+ git_commits_step = json_step(git_commits)
424
+ if git_commits.returncode != 0:
425
+ progress.fail(1, "git commits failed")
426
+ return write_failure(
427
+ "git_commits",
428
+ git_commits,
429
+ args.pretty,
430
+ repo=repo,
431
+ memory=memory,
432
+ steps={"prepare": json_step(prepare)},
433
+ outputs=outputs,
434
+ )
435
+ else:
436
+ git_commits_path.write_text("[]\n", encoding="utf-8")
437
+ git_commits_step = {
438
+ "ok": True,
439
+ "exit_code": 0,
440
+ "stdout": "",
441
+ "stderr": "",
442
+ "skipped": True,
443
+ "reason": "history_disabled_by_policy",
444
+ }
365
445
  progress.update(2, "git commits")
366
446
 
367
447
  provider = provider_report(prepare_data)
@@ -369,11 +449,12 @@ def main(argv: list[str]) -> int:
369
449
  provider_facets: dict[str, Any]
370
450
  provider_output = raw_dir / provider_raw_name(provider_name)
371
451
  provider_script_name = provider_script(provider_name)
372
- if args.skip_provider:
452
+ if not args.history_collect["provider"]:
453
+ reason = "provider_skipped_by_user" if args.skip_provider else "history_disabled_by_policy" if args.history_mode == "none" else "history_provider_disabled_by_policy"
373
454
  provider_facets = {
374
455
  "ok": True,
375
456
  "skipped": True,
376
- "reason": "provider_skipped_by_user",
457
+ "reason": reason,
377
458
  "output": "",
378
459
  }
379
460
  elif provider["evidence_state"] == "ready" and provider_script_name and provider["repo"]:
@@ -408,12 +489,12 @@ def main(argv: list[str]) -> int:
408
489
  "output": str(provider_output),
409
490
  }
410
491
  if provider_result.returncode != 0:
411
- provider_facets["degraded_to_local_only"] = not args.require_provider
492
+ provider_facets["degraded_to_local_only"] = args.history_mode != "provider-required"
412
493
  provider_facets["reason"] = "provider_facets_failed"
413
494
  provider_facets["output"] = ""
414
495
  if provider_output.exists():
415
496
  provider_output.unlink()
416
- if args.require_provider:
497
+ if args.history_mode == "provider-required":
417
498
  progress.fail(2, "provider facets failed")
418
499
  return write_failure(
419
500
  "provider_facets",
@@ -424,16 +505,17 @@ def main(argv: list[str]) -> int:
424
505
  provider=provider,
425
506
  steps={
426
507
  "prepare": json_step(prepare),
427
- "git_commits": json_step(git_commits),
508
+ "git_commits": git_commits_step,
428
509
  },
429
510
  outputs=outputs,
430
511
  notices=[provider_failure_notice(provider, provider_result, continuing=False)],
512
+ effective_settings=args.effective_settings,
431
513
  )
432
514
  notices.append(provider_failure_notice(provider, provider_result, continuing=True))
433
515
  else:
434
516
  outputs["provider_facets"] = provider_facets["output"]
435
517
  else:
436
- if args.require_provider:
518
+ if args.history_mode == "provider-required":
437
519
  provider_result = subprocess.CompletedProcess(
438
520
  args=[],
439
521
  returncode=1,
@@ -450,10 +532,11 @@ def main(argv: list[str]) -> int:
450
532
  provider=provider,
451
533
  steps={
452
534
  "prepare": json_step(prepare),
453
- "git_commits": json_step(git_commits),
535
+ "git_commits": git_commits_step,
454
536
  },
455
537
  outputs=outputs,
456
538
  notices=notices,
539
+ effective_settings=args.effective_settings,
457
540
  )
458
541
  provider_facets = {
459
542
  "ok": True,
@@ -481,7 +564,7 @@ def main(argv: list[str]) -> int:
481
564
  "effective_settings": args.effective_settings,
482
565
  "steps": {
483
566
  "prepare": json_step(prepare),
484
- "git_commits": json_step(git_commits),
567
+ "git_commits": git_commits_step,
485
568
  "provider_facets": provider_facets,
486
569
  },
487
570
  "outputs": outputs,
@@ -27,7 +27,16 @@ BUILDER_HELPER_FILES = {
27
27
  "gitlab_resource_facets": BUILDER_SCRIPTS_DIR / "gitlab_resource_facets.py",
28
28
  }
29
29
  PREFERRED_REMOTE_NAMES = ("upstream", "origin")
30
+ HISTORY_MODES = {"none", "commits-only", "local-only", "provider", "provider-required"}
30
31
  FALLBACK_DEFAULTS = {
32
+ "repoHistory": {
33
+ "mode": "provider",
34
+ "limits": {
35
+ "prs": 30,
36
+ "issues": 30,
37
+ },
38
+ },
39
+ # Kept for compatibility with defaults.json v1.
31
40
  "limits": {
32
41
  "prs": 30,
33
42
  "issues": 30,
@@ -69,6 +78,30 @@ def default_int(settings: dict[str, Any], path: list[str], fallback: int) -> int
69
78
  return value
70
79
 
71
80
 
81
+ def default_limit(settings: dict[str, Any], key: str) -> int:
82
+ history = settings.get("repoHistory")
83
+ if isinstance(history, dict) and isinstance(history.get("limits"), dict) and history["limits"].get(key) is not None:
84
+ return default_int(settings, ["repoHistory", "limits", key], FALLBACK_DEFAULTS["repoHistory"]["limits"][key])
85
+ return default_int(settings, ["limits", key], FALLBACK_DEFAULTS["limits"][key])
86
+
87
+
88
+ def default_history_mode(settings: dict[str, Any]) -> str:
89
+ history = settings.get("repoHistory")
90
+ if not isinstance(history, dict):
91
+ return "provider"
92
+ mode = history.get("mode", "provider")
93
+ if not isinstance(mode, str) or mode not in HISTORY_MODES:
94
+ raise ValueError(f"{BUILDER_DEFAULTS_PATH}: repoHistory.mode must be one of {', '.join(sorted(HISTORY_MODES))}")
95
+ return mode
96
+
97
+
98
+ def history_collect(mode: str) -> dict[str, bool]:
99
+ return {
100
+ "commits": mode in {"commits-only", "local-only", "provider", "provider-required"},
101
+ "provider": mode in {"provider", "provider-required"},
102
+ }
103
+
104
+
72
105
  def load_default_settings() -> tuple[dict[str, Any], str]:
73
106
  if not BUILDER_DEFAULTS_PATH.exists():
74
107
  return FALLBACK_DEFAULTS, "hardcoded_fallback"
@@ -86,12 +119,19 @@ def validate_range(parser: argparse.ArgumentParser, name: str, value: int, minim
86
119
  def apply_effective_settings(args: argparse.Namespace, parser: argparse.ArgumentParser) -> argparse.Namespace:
87
120
  try:
88
121
  defaults, source = load_default_settings()
89
- default_pr_limit = default_int(defaults, ["limits", "prs"], FALLBACK_DEFAULTS["limits"]["prs"])
90
- default_issue_limit = default_int(defaults, ["limits", "issues"], FALLBACK_DEFAULTS["limits"]["issues"])
122
+ default_mode = default_history_mode(defaults)
123
+ default_pr_limit = default_limit(defaults, "prs")
124
+ default_issue_limit = default_limit(defaults, "issues")
91
125
  default_summary_chars = default_int(defaults, ["summaryChars"], FALLBACK_DEFAULTS["summaryChars"])
92
126
  except ValueError as exc:
93
127
  parser.error(str(exc))
94
128
 
129
+ history_mode = args.history_mode or default_mode
130
+ collect = history_collect(history_mode)
131
+ if args.provider_mode == "off":
132
+ if history_mode == "provider-required":
133
+ parser.error("--provider-mode off cannot be combined with --history-mode provider-required")
134
+ collect = {**collect, "provider": False}
95
135
  pr_limit = args.pr_limit if args.pr_limit is not None else default_pr_limit
96
136
  issue_limit = args.issue_limit if args.issue_limit is not None else default_issue_limit
97
137
  summary_chars = args.summary_chars if args.summary_chars is not None else default_summary_chars
@@ -101,7 +141,9 @@ def apply_effective_settings(args: argparse.Namespace, parser: argparse.Argument
101
141
  if summary_chars < 100:
102
142
  parser.error("--summary-chars must be at least 100")
103
143
 
104
- overrides: dict[str, int] = {}
144
+ overrides: dict[str, Any] = {}
145
+ if args.history_mode is not None:
146
+ overrides["history_mode"] = args.history_mode
105
147
  if args.pr_limit is not None:
106
148
  overrides["pr_limit"] = args.pr_limit
107
149
  if args.issue_limit is not None:
@@ -109,10 +151,16 @@ def apply_effective_settings(args: argparse.Namespace, parser: argparse.Argument
109
151
  if args.summary_chars is not None:
110
152
  overrides["summary_chars"] = args.summary_chars
111
153
 
154
+ args.history_mode = history_mode
155
+ args.history_collect = collect
112
156
  args.pr_limit = pr_limit
113
157
  args.issue_limit = issue_limit
114
158
  args.summary_chars = summary_chars
115
159
  args.effective_settings = {
160
+ "history": {
161
+ "mode": history_mode,
162
+ "collect": collect,
163
+ },
116
164
  "limits": {
117
165
  "prs": pr_limit,
118
166
  "issues": issue_limit,
@@ -592,13 +640,13 @@ def cli_evidence_state(command: str, host: str) -> tuple[str, bool]:
592
640
  return ("ready", True) if result.returncode == 0 else ("auth_required", True)
593
641
 
594
642
 
595
- def provider_report(repo: Path, memory: Path) -> dict[str, Any]:
643
+ def provider_report(repo: Path, memory: Path, *, inspect_cli: bool = True) -> dict[str, Any]:
596
644
  remote = provider_from_profile(memory) or parse_code_host_repo(git(repo, ["remote", "-v"], "git could not list remotes"))
597
645
  provider = remote["provider"]
598
646
  cli = "gh" if provider == "github" else "glab" if provider == "gitlab" else ""
599
- evidence_state = "unavailable"
647
+ evidence_state = "unavailable" if inspect_cli else "skipped_by_policy"
600
648
  cli_available = False
601
- if cli:
649
+ if cli and inspect_cli:
602
650
  evidence_state, cli_available = cli_evidence_state(cli, remote["host"])
603
651
  return {
604
652
  "name": provider,
@@ -766,6 +814,7 @@ def parse_args(argv: list[str]) -> argparse.Namespace:
766
814
  parser.add_argument("--repo-path", default=".", help="Local git repository path")
767
815
  parser.add_argument("--memory-path", help="Existing .repo_memory path; defaults to <repo>/.repo_memory")
768
816
  parser.add_argument("--snapshot-ref", default="HEAD", help="Local git ref used for current detection")
817
+ parser.add_argument("--history-mode", choices=sorted(HISTORY_MODES), default=None, help="History evidence policy for this update")
769
818
  parser.add_argument("--provider-mode", choices=["auto", "off"], default="auto", help="Whether to fetch latest provider PR/issue facets when provider evidence is ready")
770
819
  parser.add_argument("--pr-limit", type=int, default=None, help="Maximum latest PR/MR candidates to compare")
771
820
  parser.add_argument("--issue-limit", type=int, default=None, help="Maximum latest issue candidates to compare")
@@ -793,12 +842,19 @@ def main(argv: list[str]) -> int:
793
842
 
794
843
  head = git(repo, ["rev-parse", "--verify", f"{args.snapshot_ref}^{{commit}}"], f"git could not resolve {args.snapshot_ref!r}")
795
844
  baseline_sha = commit_baseline(memory, repo, head)
796
- local_commits, local_commit_status = commit_delta(repo, baseline_sha, head)
845
+ if args.history_collect["commits"]:
846
+ local_commits, local_commit_status = commit_delta(repo, baseline_sha, head)
847
+ else:
848
+ local_commits, local_commit_status = [], {
849
+ "status": "skipped",
850
+ "reason": "history_disabled_by_policy",
851
+ "message": "Local commit delta detection is disabled by repoHistory.mode.",
852
+ }
797
853
 
798
854
  existing_prs = baseline_items(memory, "prs.md", "pr")
799
855
  existing_issues = baseline_items(memory, "issues.md", "issue")
800
- provider = provider_report(repo, memory)
801
- if args.provider_mode == "auto":
856
+ provider = provider_report(repo, memory, inspect_cli=args.history_collect["provider"])
857
+ if args.history_collect["provider"]:
802
858
  provider_fetch, current_prs, current_issues = fetch_provider_items(
803
859
  repo,
804
860
  provider,
@@ -808,7 +864,14 @@ def main(argv: list[str]) -> int:
808
864
  args.summary_chars,
809
865
  )
810
866
  else:
811
- provider_fetch, current_prs, current_issues = {"attempted": False, "reason": "provider-mode=off"}, [], []
867
+ reason = (
868
+ "provider-mode=off"
869
+ if args.provider_mode == "off"
870
+ else "history_disabled_by_policy"
871
+ if args.history_mode == "none"
872
+ else "history_provider_disabled_by_policy"
873
+ )
874
+ provider_fetch, current_prs, current_issues = {"attempted": False, "reason": reason}, [], []
812
875
  fetched_prs = current_prs if provider_fetch.get("ok") is True else []
813
876
  fetched_issues = current_issues if provider_fetch.get("ok") is True else []
814
877
  if not current_prs and provider_fetch.get("ok") is not True:
@@ -88,8 +88,16 @@ def is_git_ancestor(repo_path: Path, ancestor_sha: str, descendant_sha: str) ->
88
88
  return True
89
89
  if result.returncode == 1:
90
90
  return False
91
+ stderr = result.stderr.strip()
92
+ normalized_stderr = stderr.lower()
93
+ if (
94
+ "not a valid commit" in normalized_stderr
95
+ or "no such commit" in normalized_stderr
96
+ or "not a valid object name" in normalized_stderr
97
+ ):
98
+ return False
91
99
  raise SystemExit(
92
- f"git could not compare {ancestor_sha} with snapshot {descendant_sha} in {repo_path}:\n{result.stderr.strip()}"
100
+ f"git could not compare {ancestor_sha} with snapshot {descendant_sha} in {repo_path}:\n{stderr}"
93
101
  )
94
102
 
95
103
 
@@ -117,8 +117,16 @@ def is_git_ancestor(repo_path: Path, ancestor_sha: str, descendant_sha: str) ->
117
117
  return True
118
118
  if result.returncode == 1:
119
119
  return False
120
+ stderr = result.stderr.strip()
121
+ normalized_stderr = stderr.lower()
122
+ if (
123
+ "not a valid commit" in normalized_stderr
124
+ or "no such commit" in normalized_stderr
125
+ or "not a valid object name" in normalized_stderr
126
+ ):
127
+ return False
120
128
  raise SystemExit(
121
- f"git could not compare {ancestor_sha} with snapshot {descendant_sha} in {repo_path}:\n{result.stderr.strip()}"
129
+ f"git could not compare {ancestor_sha} with snapshot {descendant_sha} in {repo_path}:\n{stderr}"
122
130
  )
123
131
 
124
132
 
@@ -19,6 +19,7 @@ BASELINE_FILES = [
19
19
 
20
20
  PROVIDER_RAW_FILES = [Path("raw/github-facets.json"), Path("raw/gitlab-facets.json")]
21
21
  PROVIDER_RESOURCE_FILES = [Path("resources/prs.md"), Path("resources/issues.md")]
22
+ DISABLED_RESOURCE_SOURCES = {"history_disabled", "provider_skipped_local_only", "provider_unavailable", "github_resource_facets_unavailable", "gitlab_resource_facets_unavailable", "provider_unavailable_local_only"}
22
23
  USER_PROFILE_SIDECAR = Path("user-profile/preferences.md")
23
24
  PROCEDURE_SIDECAR_DIRECTORY = "procedure-memory"
24
25
  PLACEHOLDER_RE = re.compile(r"\[([^\]\n]+)\]")
@@ -128,6 +129,10 @@ def validate_json(path: Path, memory: Path, errors: list[str], checked: list[str
128
129
  errors.append(f"{relative(path, memory)}: could not read JSON: {exc}")
129
130
 
130
131
 
132
+ def raw_source_points_to_provider(raw_source: Any) -> bool:
133
+ return isinstance(raw_source, str) and raw_source.endswith(("github-facets.json", "gitlab-facets.json"))
134
+
135
+
131
136
  def validate_markdown(path: Path, memory: Path, errors: list[str], warnings: list[str], checked: list[str]) -> None:
132
137
  checked.append(relative(path, memory))
133
138
  try:
@@ -148,7 +153,7 @@ def validate_markdown(path: Path, memory: Path, errors: list[str], warnings: lis
148
153
  if path.parent.name != "resources":
149
154
  return
150
155
 
151
- for field in ["resource_count", "raw_source"]:
156
+ for field in ["source", "resource_count", "trust_state", "raw_source"]:
152
157
  if field not in frontmatter:
153
158
  errors.append(f"{rel}: frontmatter field '{field}' is missing")
154
159
 
@@ -160,6 +165,23 @@ def validate_markdown(path: Path, memory: Path, errors: list[str], warnings: lis
160
165
  elif expected is not None:
161
166
  errors.append(f"{rel}: resource_count must be an integer")
162
167
 
168
+ source = frontmatter.get("source")
169
+ raw_source = frontmatter.get("raw_source")
170
+ if "source" in frontmatter and not source:
171
+ errors.append(f"{rel}: frontmatter field 'source' must not be empty")
172
+ if "trust_state" in frontmatter and not frontmatter.get("trust_state"):
173
+ errors.append(f"{rel}: frontmatter field 'trust_state' must not be empty")
174
+ if source in DISABLED_RESOURCE_SOURCES and isinstance(expected, int) and expected != 0:
175
+ errors.append(f"{rel}: disabled or unavailable resource source {source!r} must use resource_count 0")
176
+ if source in DISABLED_RESOURCE_SOURCES and raw_source:
177
+ errors.append(f"{rel}: disabled or unavailable resource source {source!r} must use an empty raw_source")
178
+ if path.name in {"commits.md", "prs.md", "issues.md"} and source not in DISABLED_RESOURCE_SOURCES and raw_source == "":
179
+ errors.append(f"{rel}: empty raw_source requires a disabled or unavailable source")
180
+ if path.name in {"prs.md", "issues.md"} and raw_source_points_to_provider(raw_source):
181
+ provider_path = (path.parent / raw_source).resolve()
182
+ if not provider_path.exists():
183
+ errors.append(f"{rel}: provider raw evidence is missing for raw_source {raw_source!r}")
184
+
163
185
 
164
186
  def provider_raw_paths(memory: Path) -> list[Path]:
165
187
  return [memory / rel for rel in PROVIDER_RAW_FILES if (memory / rel).exists()]
@@ -0,0 +1,10 @@
1
+ - insert:
2
+ - id: memorax-code-skill-filesystem
3
+ name: '@deepseek-ai/dsh-skill-filesystem'
4
+ config:
5
+ providerName: memorax-code-bundled
6
+ includeDefaultRoots: false
7
+ watch: false
8
+ bundledSkillDir: !!js "process.getBuiltinModule('node:url').fileURLToPath(new URL('node_modules/@memorax-code/dsh-memorax-code/skills/', baseUrl))"
9
+ - id: memorax-code
10
+ name: '@memorax-code/dsh-memorax-code'
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync, readdirSync } from "node:fs";
3
+ import { dirname, join, resolve } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { runRepoMemoryJob } from "../memorax-code-adapter-common/src/repo-memory/repo-memory-job-supervisor.mjs";
6
+ import { evaluateRepository } from "../memorax-code-adapter-common/src/repo-memory/repo-memory-update-policy-evaluator.mjs";
7
+ import { requireEnabledDshRuntime } from "../src/runtime-state.mjs";
8
+
9
+ const ADAPTER_PACKAGE_NAME = "@memorax-code/dsh-memorax-code";
10
+ const HEADLESS_BUNDLE_NAME = "@deepseek-ai/dsh-headless";
11
+ const hookDir = dirname(fileURLToPath(import.meta.url));
12
+ const pluginRoot = dirname(hookDir);
13
+
14
+ try {
15
+ const runtime = requireEnabledDshRuntime(pluginRoot);
16
+ process.env.MEMORAX_CODE_HOME = runtime.memoraxCodeHome;
17
+ const profile = selectHeadlessProfile(runtime.dshHome, runtime.profiles);
18
+ if (!profile) throw new Error("no existing DSH headless-capable profile is available");
19
+ const payload = runRepoMemoryJob(process.argv.slice(2), {
20
+ runner: "dsh",
21
+ finalMessageSource: "stdout",
22
+ memorySkillInvocation: "/memorax-code",
23
+ validatorPath: resolve(pluginRoot, "skills/memorax-code/scripts/validate_memory.py"),
24
+ evaluateRepository,
25
+ createCommand({ prompt }) {
26
+ return [runtime.dshCommand, "--profile", profile, prompt];
27
+ },
28
+ });
29
+ process.stdout.write(`${JSON.stringify(payload)}\n`);
30
+ } catch (error) {
31
+ process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
32
+ process.exit(1);
33
+ }
34
+
35
+ function selectHeadlessProfile(dshHome, managedProfiles) {
36
+ const profilesRoot = join(dshHome, "profiles");
37
+ const managedNames = new Set(managedProfiles);
38
+ let entries;
39
+ try {
40
+ entries = readdirSync(profilesRoot, { withFileTypes: true });
41
+ } catch {
42
+ return undefined;
43
+ }
44
+ for (const entry of entries
45
+ .filter((candidate) => candidate.isDirectory()
46
+ && managedNames.has(candidate.name)
47
+ && validProfileName(candidate.name))
48
+ .sort((left, right) => left.name.localeCompare(right.name))) {
49
+ try {
50
+ const manifest = JSON.parse(readFileSync(join(profilesRoot, entry.name, "package.json"), "utf8"));
51
+ const bundles = manifest?.dsh?.profile?.bundles;
52
+ if (Array.isArray(bundles)
53
+ && bundles.includes(HEADLESS_BUNDLE_NAME)
54
+ && bundles.includes(ADAPTER_PACKAGE_NAME)
55
+ && Object.hasOwn(manifest.dependencies || {}, ADAPTER_PACKAGE_NAME)) {
56
+ return entry.name;
57
+ }
58
+ } catch {
59
+ // Ignore invalid or concurrently replaced Profiles.
60
+ }
61
+ }
62
+ return undefined;
63
+ }
64
+
65
+ function validProfileName(value) {
66
+ return value && value !== "." && value !== ".." && value !== "node_modules"
67
+ && !value.includes("/") && !value.includes("\\");
68
+ }