@memorax/memorax-code 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -12
- package/bin/memorax-code-npm-preinstall.mjs +7 -2
- package/bin/memorax-code-opencode.mjs +4 -0
- package/bin/memorax-code-plugin-postinstall.mjs +342 -93
- package/docs/configuration.md +144 -35
- package/docs/troubleshooting.md +73 -13
- package/lib/dsh-plugin-install.mjs +22 -0
- package/lib/memorax-code-adapter-common/src/hooks/capture-cwd-hook.mjs +21 -14
- package/lib/memorax-code-adapter-common/src/hooks/ensure-backend-runner.mjs +26 -7
- package/lib/memorax-code-adapter-common/src/hooks/memory-skill-reminder-hook.mjs +86 -95
- package/lib/memorax-code-adapter-common/src/hooks/memory-skill-reminder-policy.mjs +58 -0
- package/lib/memorax-code-adapter-common/src/repo-memory/repo-memory-auto-build.mjs +2 -2
- package/lib/memorax-code-adapter-common/src/repo-memory/repo-memory-job-supervisor.mjs +1 -1
- package/lib/memorax-code-adapter-common/src/windows-cli-invocation.mjs +13 -1
- package/lib/memorax-code-backend/dist/app/backend-server.js +210 -0
- package/lib/memorax-code-backend/dist/{server-observability.js → app/memory-observability.js} +4 -4
- package/lib/memorax-code-backend/dist/{backend-state.js → app/state.js} +1 -1
- package/lib/memorax-code-backend/dist/{claude-adapter-lifecycle.js → clients/claude/lifecycle.js} +2 -2
- package/lib/memorax-code-backend/dist/{claude-memory-hook-runtime.js → clients/claude/memory-hook-runtime.js} +7 -7
- package/lib/memorax-code-backend/dist/clients/codex/lifecycle.js +131 -0
- package/lib/memorax-code-backend/dist/{codex-memory-hook-runtime.js → clients/codex/memory-hook-runtime.js} +9 -9
- package/lib/memorax-code-backend/dist/{codex-plugin-hooks.js → clients/codex/plugin-hooks.js} +1 -1
- package/lib/memorax-code-backend/dist/{codex-plugin-install.js → clients/codex/plugin-install.js} +6 -6
- package/lib/memorax-code-backend/dist/clients/dsh/lifecycle.js +75 -0
- package/lib/memorax-code-backend/dist/clients/dsh/memory-hook-runtime.js +258 -0
- package/lib/memorax-code-backend/dist/clients/dsh/session-turn.js +249 -0
- package/lib/memorax-code-backend/dist/clients/opencode/lifecycle.js +54 -0
- package/lib/memorax-code-backend/dist/clients/opencode/memory-hook-runtime.js +277 -0
- package/lib/memorax-code-backend/dist/clients/opencode/message-turn.js +78 -0
- package/lib/memorax-code-backend/dist/codex-adapter-lifecycle.js +1 -131
- package/lib/memorax-code-backend/dist/{memorax-code-config.js → config/memorax-code.js} +32 -4
- package/lib/memorax-code-backend/dist/{server-cli.js → entrypoints/backend-cli.js} +137 -37
- package/lib/memorax-code-backend/dist/jsonl-append.js +1 -75
- package/lib/memorax-code-backend/dist/{active-client-selection.js → lifecycle/active-clients.js} +12 -1
- package/lib/memorax-code-backend/dist/{backend-service-cleanup.js → lifecycle/backend/cleanup.js} +1 -1
- package/lib/memorax-code-backend/dist/{backend-service-record.js → lifecycle/backend/record.js} +1 -1
- package/lib/memorax-code-backend/dist/{backend-service-result.js → lifecycle/backend/result.js} +2 -2
- package/lib/memorax-code-backend/dist/{service.js → lifecycle/backend/service.js} +16 -16
- package/lib/memorax-code-backend/dist/{backend-token-record.js → lifecycle/backend/token-record.js} +1 -1
- package/lib/memorax-code-backend/dist/{backend-service-token.js → lifecycle/backend/token.js} +2 -2
- package/lib/memorax-code-backend/dist/lifecycle/client-plugin-removal.js +109 -0
- package/lib/memorax-code-backend/dist/{client-selection.js → lifecycle/client-selection.js} +11 -5
- package/lib/memorax-code-backend/dist/{backend-lifecycle-lock.js → lifecycle/lock.js} +1 -1
- package/lib/memorax-code-backend/dist/{memorax-code-lifecycle.js → lifecycle/orchestrator.js} +325 -39
- package/lib/memorax-code-backend/dist/memorax-cli.js +1 -1
- package/lib/memorax-code-backend/dist/memorax-code.js +1 -1
- package/lib/memorax-code-backend/dist/{automatic-memory-retrieval.js → memory/automatic-retrieval.js} +3 -3
- package/lib/memorax-code-backend/dist/{automatic-memory-writeback.js → memory/automatic-writeback.js} +75 -21
- package/lib/memorax-code-backend/dist/{memory-cli.js → memory/cli.js} +23 -10
- package/lib/memorax-code-backend/dist/{memory-hook-command.js → memory/hook-command.js} +156 -9
- package/lib/memorax-code-backend/dist/memory/observability.js +1 -0
- package/lib/memorax-code-backend/dist/memory/payload-redaction.js +212 -0
- package/lib/memorax-code-backend/dist/{memory-reminder-trace-recorder.js → memory/reminder-trace-recorder.js} +20 -7
- package/lib/memorax-code-backend/dist/{repository-memory-context.js → memory/repository-session.js} +2 -2
- package/lib/memorax-code-backend/dist/{memory-service.js → memory/service.js} +27 -5
- package/lib/memorax-code-backend/dist/{memory-turn-coordinator.js → memory/turn-coordinator.js} +2 -1
- package/lib/memorax-code-backend/dist/{memory-writeback-buffer.js → memory/writeback-buffer.js} +3 -3
- package/lib/memorax-code-backend/dist/{memory-writeback-chunk.js → memory/writeback-chunk.js} +1 -1
- package/lib/memorax-code-backend/dist/{memory-writeback-reconciler.js → memory/writeback-reconciler.js} +6 -6
- package/lib/memorax-code-backend/dist/{memory-writeback-task-projection.js → memory/writeback-task-projection.js} +4 -4
- package/lib/memorax-code-backend/dist/{memorax-adapter.js → provider/memorax/adapter.js} +5 -5
- package/lib/memorax-code-backend/dist/{memorax-config.js → provider/memorax/config.js} +4 -4
- package/lib/memorax-code-backend/dist/{memorax-http.js → provider/memorax/http.js} +1 -1
- package/lib/memorax-code-backend/dist/{repo-memory-readiness.js → repository/readiness.js} +3 -3
- package/lib/memorax-code-backend/dist/server.js +3 -212
- package/lib/memorax-code-backend/dist/service-entrypoint.js +1 -1
- package/lib/memorax-code-backend/dist/{debug-log.js → shared/debug-log.js} +1 -1
- package/lib/memorax-code-backend/dist/shared/jsonl-append.js +75 -0
- package/lib/memorax-code-backend/dist/shared/windows-cli-invocation.js +148 -0
- package/lib/memorax-code-backend/dist/{trace-config.js → trace/config.js} +43 -5
- package/lib/memorax-code-backend/dist/{trace-context.js → trace/context.js} +53 -2
- package/lib/memorax-code-backend/dist/{trace-store.js → trace/store.js} +3 -3
- package/lib/memorax-code-backend/dist/{server-health.js → transport/http/health.js} +1 -1
- package/lib/memorax-code-backend/dist/{server-memory-hook.js → transport/http/memory-hook.js} +3 -3
- package/lib/memorax-code-backend/dist/{server-http.js → transport/http/request.js} +1 -1
- package/lib/memorax-code-backend/dist/{claude-local-transcript.js → viewer/history/claude-transcript.js} +3 -3
- package/lib/memorax-code-backend/dist/{memory-viewer-session-title.js → viewer/history/session-title.js} +1 -1
- package/lib/memorax-code-backend/dist/{server-memory-viewer.js → viewer/http/public-routes.js} +15 -15
- package/lib/memorax-code-backend/dist/viewer/model.js +1 -0
- package/lib/memorax-code-backend/dist/{memory-viewer-activity.js → viewer/projection/activity.js} +2 -2
- package/lib/memorax-code-backend/dist/{memory-viewer-history-projection.js → viewer/projection/history.js} +1 -1
- package/lib/memorax-code-backend/dist/{memory-viewer-observability.js → viewer/projection/observability.js} +1 -1
- package/lib/memorax-code-backend/dist/{memory-viewer-user-projection.js → viewer/projection/user.js} +1 -1
- package/lib/memorax-code-backend/dist/{memory-viewer-writeback-status.js → viewer/projection/writeback-status.js} +1 -1
- package/lib/memorax-code-backend/dist/{memory-viewer-store.js → viewer/store.js} +59 -32
- package/lib/memorax-code-backend/dist/{memory-viewer-user-html.js → viewer/ui/user-html.js} +11 -10
- package/lib/memorax-code-backend/dist/windows-cli-invocation.js +1 -148
- package/lib/memorax-code-backend/package.json +3 -3
- package/lib/memorax-code-claude-adapter/.claude-plugin/plugin.json +1 -1
- package/lib/memorax-code-claude-adapter/hooks/runtime-shell.json +1 -1
- package/lib/memorax-code-claude-adapter/package.json +1 -1
- package/lib/memorax-code-claude-adapter/skills/memorax-code/SKILL.md +11 -2
- package/lib/memorax-code-claude-adapter/skills/memorax-code/defaults.json +8 -5
- package/lib/memorax-code-claude-adapter/skills/memorax-code/references/memorax-add.md +1 -1
- package/lib/memorax-code-claude-adapter/skills/memorax-code/references/memorax-search.md +37 -9
- package/lib/memorax-code-claude-adapter/skills/memorax-code/references/personal-read.md +1 -1
- package/lib/memorax-code-claude-adapter/skills/memorax-code/references/personal-write.md +33 -13
- package/lib/memorax-code-claude-adapter/skills/memorax-code/references/repo-build.md +62 -13
- package/lib/memorax-code-claude-adapter/skills/memorax-code/references/repo-read.md +11 -4
- package/lib/memorax-code-claude-adapter/skills/memorax-code/references/repo-templates.md +179 -59
- package/lib/memorax-code-claude-adapter/skills/memorax-code/references/repo-update.md +18 -7
- package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/collect_all.py +122 -39
- package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/detect_updates.py +73 -10
- package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/github_resource_facets.py +9 -1
- package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +9 -1
- package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/validate_memory.py +23 -1
- package/lib/memorax-code-claude-adapter/src/plugin-install.mjs +1 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/.claude-plugin/plugin.json +1 -1
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/hooks/runtime-shell.json +1 -1
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/capture-cwd-hook.mjs +21 -14
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/ensure-backend-runner.mjs +26 -7
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/memory-skill-reminder-hook.mjs +86 -95
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/memory-skill-reminder-policy.mjs +58 -0
- 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
- 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
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/windows-cli-invocation.mjs +13 -1
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/package.json +1 -1
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/SKILL.md +11 -2
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/defaults.json +8 -5
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/memorax-add.md +1 -1
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/memorax-search.md +37 -9
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/personal-read.md +1 -1
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/personal-write.md +33 -13
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/repo-build.md +62 -13
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/repo-read.md +11 -4
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/repo-templates.md +179 -59
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/repo-update.md +18 -7
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/collect_all.py +122 -39
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/detect_updates.py +73 -10
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/github_resource_facets.py +9 -1
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +9 -1
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/validate_memory.py +23 -1
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/src/plugin-install.mjs +1 -0
- package/lib/memorax-code-codex-adapter/.codex-plugin/plugin.json +1 -1
- package/lib/memorax-code-codex-adapter/hooks/runtime-shell.json +1 -1
- package/lib/memorax-code-codex-adapter/package.json +1 -1
- package/lib/memorax-code-codex-adapter/runtime-hooks/memory-skill-reminder.mjs +10 -2
- package/lib/memorax-code-codex-adapter/skills/memorax-code/SKILL.md +11 -2
- package/lib/memorax-code-codex-adapter/skills/memorax-code/defaults.json +8 -5
- package/lib/memorax-code-codex-adapter/skills/memorax-code/references/memorax-add.md +1 -1
- package/lib/memorax-code-codex-adapter/skills/memorax-code/references/memorax-search.md +37 -9
- package/lib/memorax-code-codex-adapter/skills/memorax-code/references/personal-read.md +1 -1
- package/lib/memorax-code-codex-adapter/skills/memorax-code/references/personal-write.md +33 -13
- package/lib/memorax-code-codex-adapter/skills/memorax-code/references/repo-build.md +62 -13
- package/lib/memorax-code-codex-adapter/skills/memorax-code/references/repo-read.md +11 -4
- package/lib/memorax-code-codex-adapter/skills/memorax-code/references/repo-templates.md +179 -59
- package/lib/memorax-code-codex-adapter/skills/memorax-code/references/repo-update.md +18 -7
- package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/collect_all.py +122 -39
- package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/detect_updates.py +73 -10
- package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/github_resource_facets.py +9 -1
- package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +9 -1
- package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/validate_memory.py +23 -1
- package/lib/memorax-code-dsh-adapter/cordis.patch.yml +10 -0
- package/lib/memorax-code-dsh-adapter/hooks/repo-memory-job.mjs +68 -0
- package/lib/memorax-code-dsh-adapter/package.json +69 -0
- package/lib/memorax-code-dsh-adapter/skills/memorax-code/SKILL.md +91 -0
- package/lib/memorax-code-dsh-adapter/skills/memorax-code/agents/claude.yaml +10 -0
- package/lib/memorax-code-dsh-adapter/skills/memorax-code/agents/openai.yaml +7 -0
- package/lib/memorax-code-dsh-adapter/skills/memorax-code/defaults.json +12 -0
- package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/memorax-add.md +86 -0
- package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/memorax-search.md +91 -0
- package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/personal-read.md +46 -0
- package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/personal-write.md +120 -0
- package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/repo-build.md +319 -0
- package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/repo-read.md +103 -0
- package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/repo-templates.md +390 -0
- package/lib/memorax-code-dsh-adapter/skills/memorax-code/references/repo-update.md +127 -0
- package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/collect_all.py +579 -0
- package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/detect_updates.py +919 -0
- package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/git_commit_facets.py +222 -0
- package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/github_resource_facets.py +512 -0
- package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +517 -0
- package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/prepare_repo_memory.py +411 -0
- package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/user_profile_memory.py +528 -0
- package/lib/memorax-code-dsh-adapter/skills/memorax-code/scripts/validate_memory.py +248 -0
- package/lib/memorax-code-dsh-adapter/src/backend-client.mjs +119 -0
- package/lib/memorax-code-dsh-adapter/src/dsh-message.mjs +32 -0
- package/lib/memorax-code-dsh-adapter/src/dsh-version.mjs +18 -0
- package/lib/memorax-code-dsh-adapter/src/http-client.mjs +55 -0
- package/lib/memorax-code-dsh-adapter/src/index.mjs +72 -0
- package/lib/memorax-code-dsh-adapter/src/personal-context-worker.mjs +48 -0
- package/lib/memorax-code-dsh-adapter/src/personal-context.mjs +114 -0
- package/lib/memorax-code-dsh-adapter/src/plugin.mjs +724 -0
- package/lib/memorax-code-dsh-adapter/src/profile-lifecycle.mjs +1289 -0
- package/lib/memorax-code-dsh-adapter/src/protocol.mjs +145 -0
- package/lib/memorax-code-dsh-adapter/src/runtime-state.mjs +132 -0
- package/lib/memorax-code-opencode-adapter/hooks/repo-memory-job.mjs +37 -0
- package/lib/memorax-code-opencode-adapter/package.json +10 -0
- package/lib/memorax-code-opencode-adapter/skills/memorax-code/SKILL.md +91 -0
- package/lib/memorax-code-opencode-adapter/skills/memorax-code/agents/claude.yaml +10 -0
- package/lib/memorax-code-opencode-adapter/skills/memorax-code/agents/openai.yaml +7 -0
- package/lib/memorax-code-opencode-adapter/skills/memorax-code/defaults.json +12 -0
- package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/memorax-add.md +86 -0
- package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/memorax-search.md +91 -0
- package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/personal-read.md +46 -0
- package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/personal-write.md +120 -0
- package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/repo-build.md +319 -0
- package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/repo-read.md +103 -0
- package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/repo-templates.md +390 -0
- package/lib/memorax-code-opencode-adapter/skills/memorax-code/references/repo-update.md +127 -0
- package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/collect_all.py +579 -0
- package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/detect_updates.py +919 -0
- package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/git_commit_facets.py +222 -0
- package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/github_resource_facets.py +512 -0
- package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +517 -0
- package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/prepare_repo_memory.py +411 -0
- package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/user_profile_memory.py +528 -0
- package/lib/memorax-code-opencode-adapter/skills/memorax-code/scripts/validate_memory.py +248 -0
- package/lib/memorax-code-opencode-adapter/src/adapter-paths.mjs +37 -0
- package/lib/memorax-code-opencode-adapter/src/cli.mjs +260 -0
- package/lib/memorax-code-opencode-adapter/src/diagnostics.mjs +31 -0
- package/lib/memorax-code-opencode-adapter/src/plugin-install.mjs +673 -0
- package/lib/memorax-code-opencode-adapter/src/plugin.mjs +536 -0
- package/lib/memorax-code-opencode-adapter/src/repo-memory-server-runner.mjs +207 -0
- package/lib/run-entrypoint.mjs +6 -0
- package/package.json +7 -3
- package/lib/memorax-code-backend/dist/client-plugin-removal.js +0 -67
- /package/lib/memorax-code-backend/dist/{claude-transcript-turn.js → clients/claude/transcript-turn.js} +0 -0
- /package/lib/memorax-code-backend/dist/{codex-effective-prompt.js → clients/codex/effective-prompt.js} +0 -0
- /package/lib/memorax-code-backend/dist/{codex-rollout-turn.js → clients/codex/rollout-turn.js} +0 -0
- /package/lib/memorax-code-backend/dist/{codex-session-turn-index.js → clients/codex/session-turn-index.js} +0 -0
- /package/lib/memorax-code-backend/dist/{codex-workspace-links.js → clients/codex/workspace-links.js} +0 -0
- /package/lib/memorax-code-backend/dist/{backend-env.js → config/backend-env.js} +0 -0
- /package/lib/memorax-code-backend/dist/{proxy-env.js → config/proxy-env.js} +0 -0
- /package/lib/memorax-code-backend/dist/{entrypoint.js → entrypoints/main.js} +0 -0
- /package/lib/memorax-code-backend/dist/{backend-process.js → lifecycle/backend/process.js} +0 -0
- /package/lib/memorax-code-backend/dist/{backend-shutdown-request.js → lifecycle/backend/shutdown-request.js} +0 -0
- /package/lib/memorax-code-backend/dist/{backend-status.js → lifecycle/backend/status.js} +0 -0
- /package/lib/memorax-code-backend/dist/{adapter-lifecycle-participant.js → lifecycle/contracts.js} +0 -0
- /package/lib/memorax-code-backend/dist/{install-watchdog.js → lifecycle/install-watchdog.js} +0 -0
- /package/lib/memorax-code-backend/dist/{memory-observability.js → lifecycle/participant.js} +0 -0
- /package/lib/memorax-code-backend/dist/{memory-project.js → memory/project.js} +0 -0
- /package/lib/memorax-code-backend/dist/{repository-memory-scope.js → repository/scope.js} +0 -0
- /package/lib/memorax-code-backend/dist/{incremental-jsonl-projection.js → shared/incremental-jsonl-projection.js} +0 -0
- /package/lib/memorax-code-backend/dist/{utils.js → shared/record.js} +0 -0
- /package/lib/memorax-code-backend/dist/{server-json.js → transport/http/json.js} +0 -0
- /package/lib/memorax-code-backend/dist/{memory-viewer-data-projection-cache.js → viewer/projection/cache.js} +0 -0
- /package/lib/memorax-code-backend/dist/{memory-viewer-event-identity.js → viewer/projection/event-identity.js} +0 -0
- /package/lib/memorax-code-backend/dist/{memory-viewer-redaction.js → viewer/projection/redaction.js} +0 -0
- /package/lib/memorax-code-backend/dist/{memory-viewer-turn-reference.js → viewer/projection/turn-reference.js} +0 -0
- /package/lib/memorax-code-backend/dist/{memory-viewer-icon.js → viewer/ui/icon.js} +0 -0
- /package/lib/memorax-code-backend/dist/{memory-viewer-logo.js → viewer/ui/logo.js} +0 -0
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { isRecord } from "../../shared/record.js";
|
|
2
|
+
const DSH_SESSION_FORMAT_VERSION = 0;
|
|
3
|
+
// Mirrors the supported DSH persistence catalog. Events outside this
|
|
4
|
+
// vocabulary are safe to skip only when their envelope explicitly says so.
|
|
5
|
+
const KNOWN_SESSION_EVENT_TYPES = new Set([
|
|
6
|
+
"agent-preset/selected",
|
|
7
|
+
"agent/inbox/spliced",
|
|
8
|
+
"approval/asked",
|
|
9
|
+
"approval/decided",
|
|
10
|
+
"approval/policy",
|
|
11
|
+
"turn/start",
|
|
12
|
+
"turn/end",
|
|
13
|
+
"step/start",
|
|
14
|
+
"step/end",
|
|
15
|
+
"user/message",
|
|
16
|
+
"assistant/chunk",
|
|
17
|
+
"assistant/message",
|
|
18
|
+
"command/done",
|
|
19
|
+
"command/run",
|
|
20
|
+
"compaction/end",
|
|
21
|
+
"compaction/prune",
|
|
22
|
+
"compaction/start",
|
|
23
|
+
"compaction/summary",
|
|
24
|
+
"feedback/record",
|
|
25
|
+
"goal/change",
|
|
26
|
+
"hook/invoked",
|
|
27
|
+
"hook/result",
|
|
28
|
+
"llm/retry",
|
|
29
|
+
"llm/retry-started",
|
|
30
|
+
"permission/preset",
|
|
31
|
+
"plan/mode",
|
|
32
|
+
"tool/call",
|
|
33
|
+
"tool/code-dispatch",
|
|
34
|
+
"tool/code-dispatch-start",
|
|
35
|
+
"tool/result",
|
|
36
|
+
"todo/write",
|
|
37
|
+
"request/header",
|
|
38
|
+
"request/context",
|
|
39
|
+
"sandbox/mode",
|
|
40
|
+
"schedule/change",
|
|
41
|
+
"session/end-seed",
|
|
42
|
+
"session/title",
|
|
43
|
+
"session/title-llm-request",
|
|
44
|
+
"subagent/descriptor",
|
|
45
|
+
"tool-workflow/agent-end",
|
|
46
|
+
"tool-workflow/agent-start",
|
|
47
|
+
"tool-workflow/run-end",
|
|
48
|
+
"tool-workflow/run-start",
|
|
49
|
+
"web/deepseek-search-llm-request",
|
|
50
|
+
]);
|
|
51
|
+
const TURN_IDENTITY_REQUIRED_EVENT_TYPES = new Set([
|
|
52
|
+
"turn/start",
|
|
53
|
+
"turn/end",
|
|
54
|
+
"assistant/message",
|
|
55
|
+
]);
|
|
56
|
+
export function dshSessionEventTurn(input) {
|
|
57
|
+
const header = validateSessionHeader(input);
|
|
58
|
+
if (header)
|
|
59
|
+
return { ok: false, reason: header };
|
|
60
|
+
if (input.events.length === 0
|
|
61
|
+
|| input.endSeq - input.startSeq !== input.events.length - 1) {
|
|
62
|
+
return { ok: false, reason: "interval_length_mismatch" };
|
|
63
|
+
}
|
|
64
|
+
const first = input.events[0];
|
|
65
|
+
const last = input.events[input.events.length - 1];
|
|
66
|
+
if (!isRecord(first)
|
|
67
|
+
|| first.type !== "turn/start"
|
|
68
|
+
|| !isRecord(last)
|
|
69
|
+
|| last.type !== "turn/end")
|
|
70
|
+
return { ok: false, reason: "turn_boundary_mismatch" };
|
|
71
|
+
const userParts = [];
|
|
72
|
+
const assistantParts = [];
|
|
73
|
+
let outcome;
|
|
74
|
+
for (const [index, value] of input.events.entries()) {
|
|
75
|
+
if (!isRecord(value))
|
|
76
|
+
return { ok: false, reason: "event_invalid" };
|
|
77
|
+
const type = stringField(value, "type");
|
|
78
|
+
const seq = safeIntegerField(value, "seq", 0);
|
|
79
|
+
if (!type || seq === undefined) {
|
|
80
|
+
return { ok: false, reason: "event_invalid" };
|
|
81
|
+
}
|
|
82
|
+
if (seq !== input.startSeq + index) {
|
|
83
|
+
return { ok: false, reason: "event_sequence_mismatch" };
|
|
84
|
+
}
|
|
85
|
+
if (Object.prototype.hasOwnProperty.call(value, "ignorable") && value.ignorable !== true) {
|
|
86
|
+
return { ok: false, reason: "event_invalid" };
|
|
87
|
+
}
|
|
88
|
+
if (!KNOWN_SESSION_EVENT_TYPES.has(type)) {
|
|
89
|
+
if (value.ignorable === true)
|
|
90
|
+
continue;
|
|
91
|
+
return { ok: false, reason: "unknown_required_event" };
|
|
92
|
+
}
|
|
93
|
+
const data = isRecord(value.data) ? value.data : undefined;
|
|
94
|
+
const carriesTurn = data ? Object.prototype.hasOwnProperty.call(data, "turn") : false;
|
|
95
|
+
const eventTurn = data && carriesTurn ? safeIntegerField(data, "turn", 1) : undefined;
|
|
96
|
+
if ((carriesTurn && eventTurn === undefined)
|
|
97
|
+
|| (TURN_IDENTITY_REQUIRED_EVENT_TYPES.has(type) && eventTurn === undefined))
|
|
98
|
+
return { ok: false, reason: "event_invalid" };
|
|
99
|
+
if (eventTurn !== undefined && eventTurn !== input.turn) {
|
|
100
|
+
return { ok: false, reason: "turn_identity_mismatch" };
|
|
101
|
+
}
|
|
102
|
+
if ((type === "turn/start" && index !== 0)
|
|
103
|
+
|| (type === "turn/end" && index !== input.events.length - 1)) {
|
|
104
|
+
return { ok: false, reason: "turn_boundary_mismatch" };
|
|
105
|
+
}
|
|
106
|
+
switch (type) {
|
|
107
|
+
case "turn/start":
|
|
108
|
+
break;
|
|
109
|
+
case "turn/end": {
|
|
110
|
+
const reason = data && isRecord(data.reason) ? stringField(data.reason, "kind") : undefined;
|
|
111
|
+
if (!reason)
|
|
112
|
+
return { ok: false, reason: "event_invalid" };
|
|
113
|
+
outcome = reason;
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
case "user/message": {
|
|
117
|
+
if (!data)
|
|
118
|
+
return { ok: false, reason: "event_invalid" };
|
|
119
|
+
const message = messageEnvelope(data, "user");
|
|
120
|
+
if (!message || !validSurfaceOp(value.surfaceOp)) {
|
|
121
|
+
return { ok: false, reason: "event_invalid" };
|
|
122
|
+
}
|
|
123
|
+
if (message.source.kind === "user") {
|
|
124
|
+
if (value.surfaceOp !== "append") {
|
|
125
|
+
return { ok: false, reason: "event_invalid" };
|
|
126
|
+
}
|
|
127
|
+
const text = textContent(message.content);
|
|
128
|
+
if (text === undefined)
|
|
129
|
+
return { ok: false, reason: "event_invalid" };
|
|
130
|
+
if (text)
|
|
131
|
+
userParts.push(text);
|
|
132
|
+
}
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
case "assistant/message": {
|
|
136
|
+
if (!data || value.surfaceOp !== "append" || !isRecord(data.message)) {
|
|
137
|
+
return { ok: false, reason: "event_invalid" };
|
|
138
|
+
}
|
|
139
|
+
const message = messageEnvelope(data.message, "assistant");
|
|
140
|
+
if (!message
|
|
141
|
+
|| message.source.kind !== "model"
|
|
142
|
+
|| !stringField(message.source, "provider")
|
|
143
|
+
|| !stringField(message.source, "model"))
|
|
144
|
+
return { ok: false, reason: "event_invalid" };
|
|
145
|
+
const text = textContent(message.content);
|
|
146
|
+
if (text === undefined)
|
|
147
|
+
return { ok: false, reason: "event_invalid" };
|
|
148
|
+
if (text)
|
|
149
|
+
assistantParts.push(text);
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (!outcome)
|
|
155
|
+
return { ok: false, reason: "turn_boundary_mismatch" };
|
|
156
|
+
if (outcome !== "completed") {
|
|
157
|
+
return { ok: false, reason: "turn_not_completed", outcome };
|
|
158
|
+
}
|
|
159
|
+
const userPrompt = userParts.join("\n\n").trim();
|
|
160
|
+
if (!userPrompt)
|
|
161
|
+
return { ok: false, reason: "user_prompt_missing" };
|
|
162
|
+
const assistantReply = assistantParts.join("\n\n").trim();
|
|
163
|
+
if (!assistantReply)
|
|
164
|
+
return { ok: false, reason: "assistant_message_missing" };
|
|
165
|
+
return {
|
|
166
|
+
ok: true,
|
|
167
|
+
turn: {
|
|
168
|
+
sessionId: input.sessionId,
|
|
169
|
+
turn: input.turn,
|
|
170
|
+
startSeq: input.startSeq,
|
|
171
|
+
endSeq: input.endSeq,
|
|
172
|
+
userPrompt,
|
|
173
|
+
assistantReply,
|
|
174
|
+
outcome,
|
|
175
|
+
},
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
function validateSessionHeader(input) {
|
|
179
|
+
const header = input.sessionHeader;
|
|
180
|
+
if (header.version !== DSH_SESSION_FORMAT_VERSION
|
|
181
|
+
|| safeIntegerField(header, "createdAt", 0) === undefined)
|
|
182
|
+
return "session_header_invalid";
|
|
183
|
+
if (stringField(header, "id") !== input.sessionId)
|
|
184
|
+
return "session_identity_mismatch";
|
|
185
|
+
if (stringField(header, "cwd") !== input.cwd)
|
|
186
|
+
return "workspace_identity_mismatch";
|
|
187
|
+
if (Object.prototype.hasOwnProperty.call(header, "parentSession")) {
|
|
188
|
+
if (!stringField(header, "parentSession"))
|
|
189
|
+
return "session_header_invalid";
|
|
190
|
+
}
|
|
191
|
+
if (Object.prototype.hasOwnProperty.call(header, "origin")) {
|
|
192
|
+
if (header.origin !== "subagent")
|
|
193
|
+
return "session_header_invalid";
|
|
194
|
+
return "subagent_session";
|
|
195
|
+
}
|
|
196
|
+
const delegationDepth = optionalSafeIntegerField(header, "delegationDepth", 0);
|
|
197
|
+
if (!delegationDepth.ok)
|
|
198
|
+
return "session_header_invalid";
|
|
199
|
+
if ((delegationDepth.value ?? 0) > 0)
|
|
200
|
+
return "subagent_session";
|
|
201
|
+
return undefined;
|
|
202
|
+
}
|
|
203
|
+
function messageEnvelope(value, role) {
|
|
204
|
+
if (value.role !== role
|
|
205
|
+
|| !Array.isArray(value.content)
|
|
206
|
+
|| !isRecord(value.source)
|
|
207
|
+
|| !stringField(value.source, "kind"))
|
|
208
|
+
return undefined;
|
|
209
|
+
return { content: value.content, source: value.source };
|
|
210
|
+
}
|
|
211
|
+
function textContent(content) {
|
|
212
|
+
const parts = [];
|
|
213
|
+
for (const block of content) {
|
|
214
|
+
if (!isRecord(block) || !stringField(block, "type"))
|
|
215
|
+
return undefined;
|
|
216
|
+
if (block.type !== "text")
|
|
217
|
+
continue;
|
|
218
|
+
if (typeof block.text !== "string")
|
|
219
|
+
return undefined;
|
|
220
|
+
if (block.text.trim())
|
|
221
|
+
parts.push(block.text);
|
|
222
|
+
}
|
|
223
|
+
return parts.join("\n").trim();
|
|
224
|
+
}
|
|
225
|
+
function validSurfaceOp(value) {
|
|
226
|
+
if (value === "append")
|
|
227
|
+
return true;
|
|
228
|
+
return isRecord(value)
|
|
229
|
+
&& Object.keys(value).length === 3
|
|
230
|
+
&& value.op === "replace"
|
|
231
|
+
&& safeIntegerField(value, "start", 0) !== undefined
|
|
232
|
+
&& safeIntegerField(value, "end", 0) !== undefined;
|
|
233
|
+
}
|
|
234
|
+
function stringField(record, key) {
|
|
235
|
+
const value = record[key];
|
|
236
|
+
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
237
|
+
}
|
|
238
|
+
function safeIntegerField(record, key, minimum) {
|
|
239
|
+
const value = record[key];
|
|
240
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= minimum
|
|
241
|
+
? value
|
|
242
|
+
: undefined;
|
|
243
|
+
}
|
|
244
|
+
function optionalSafeIntegerField(record, key, minimum) {
|
|
245
|
+
if (!Object.prototype.hasOwnProperty.call(record, key))
|
|
246
|
+
return { ok: true };
|
|
247
|
+
const value = safeIntegerField(record, key, minimum);
|
|
248
|
+
return value === undefined ? { ok: false } : { ok: true, value };
|
|
249
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export const openCodeAdapterLifecycle = {
|
|
2
|
+
async status({ argv, serviceOptions, backendUrl }) {
|
|
3
|
+
try {
|
|
4
|
+
return (await loadOpenCodePluginInstaller()).readOpenCodePluginStatus(openCodeAdapterOptions(argv, serviceOptions.home, backendUrl));
|
|
5
|
+
}
|
|
6
|
+
catch (error) {
|
|
7
|
+
return { ok: false, action: "status", error: error instanceof Error ? error.message : String(error) };
|
|
8
|
+
}
|
|
9
|
+
},
|
|
10
|
+
async prepareEnable({ argv, serviceOptions, backendUrl }) {
|
|
11
|
+
try {
|
|
12
|
+
return (await loadOpenCodePluginInstaller()).ensureOpenCodePluginInstalled(openCodeAdapterOptions(argv, serviceOptions.home, backendUrl));
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
return { ok: false, action: "enable", error: error instanceof Error ? error.message : String(error) };
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
async disable({ argv, serviceOptions }) {
|
|
19
|
+
try {
|
|
20
|
+
return (await loadOpenCodePluginInstaller()).disableOpenCodePlugin(openCodeAdapterOptions(argv, serviceOptions.home));
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
return { ok: false, action: "disable", error: error instanceof Error ? error.message : String(error) };
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
async remove({ argv, serviceOptions }) {
|
|
27
|
+
try {
|
|
28
|
+
return (await loadOpenCodePluginInstaller()).removeOpenCodePluginInstallation(openCodeAdapterOptions(argv, serviceOptions.home));
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
return {
|
|
32
|
+
ok: false,
|
|
33
|
+
action: "opencode-plugin-remove",
|
|
34
|
+
reason: "plugin_remove_failed",
|
|
35
|
+
message: error instanceof Error ? error.message : String(error),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
function openCodeAdapterOptions(argv, memoraxCodeHome, backendUrl) {
|
|
41
|
+
const openCodeConfigDir = argValue(argv, "--opencode-config-dir");
|
|
42
|
+
return {
|
|
43
|
+
...(openCodeConfigDir ? { openCodeConfigDir } : {}),
|
|
44
|
+
memoraxCodeHome,
|
|
45
|
+
...(backendUrl ? { backendUrl } : {}),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
async function loadOpenCodePluginInstaller() {
|
|
49
|
+
return await import(new URL("../../../../memorax-code-opencode-adapter/src/plugin-install.mjs", import.meta.url).href);
|
|
50
|
+
}
|
|
51
|
+
function argValue(argv, name) {
|
|
52
|
+
const index = argv.indexOf(name);
|
|
53
|
+
return index >= 0 ? argv[index + 1] : undefined;
|
|
54
|
+
}
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import { createAutomaticMemoryWritebackRuntime, } from "../../memory/automatic-writeback.js";
|
|
2
|
+
import { retrieveAutomaticMemoryContext } from "../../memory/automatic-retrieval.js";
|
|
3
|
+
import { createMemoryTurnCoordinator, } from "../../memory/turn-coordinator.js";
|
|
4
|
+
import { createRepositoryMemorySessionRuntime, resolvedRepoMemoryWorktree, } from "../../memory/repository-session.js";
|
|
5
|
+
import { traceContextFromOpenCodeHookBody } from "../../trace/context.js";
|
|
6
|
+
import { markCurrentTraceTurnOutcome, recordTraceEvent, traceTurnEventId, writeCurrentTraceTurn, } from "../../trace/store.js";
|
|
7
|
+
import { openCodeMessageTurn, } from "./message-turn.js";
|
|
8
|
+
const OPENCODE_MEMORY_TURN_CLIENT = "opencode";
|
|
9
|
+
export function createOpenCodeMemoryHookRuntime(options = {}) {
|
|
10
|
+
const now = options.now ?? (() => Date.now());
|
|
11
|
+
const automaticWritebackRuntime = options.turnCoordinator
|
|
12
|
+
? undefined
|
|
13
|
+
: options.automaticWriteback
|
|
14
|
+
? { enqueue: options.automaticWriteback }
|
|
15
|
+
: createAutomaticMemoryWritebackRuntime({ diagnosticLogger: options.diagnosticLogger });
|
|
16
|
+
const turnCoordinator = options.turnCoordinator ?? createMemoryTurnCoordinator({
|
|
17
|
+
automaticWriteback: automaticWritebackRuntime.enqueue,
|
|
18
|
+
now,
|
|
19
|
+
ttlMs: options.ttlMs,
|
|
20
|
+
maxEntries: options.maxEntries,
|
|
21
|
+
cleanupIntervalMs: options.cleanupIntervalMs,
|
|
22
|
+
});
|
|
23
|
+
const ownsTurnCoordinator = options.turnCoordinator === undefined;
|
|
24
|
+
const repositoryMemorySession = options.repositoryMemorySession ?? createRepositoryMemorySessionRuntime({
|
|
25
|
+
onScopeUpgrade: automaticWritebackRuntime?.discardForScopeUpgrade,
|
|
26
|
+
});
|
|
27
|
+
const ownsRepositoryMemorySession = options.repositoryMemorySession === undefined;
|
|
28
|
+
const retrievalTurns = new Set();
|
|
29
|
+
const retrievalTurnLimit = positiveInteger(options.maxEntries, 256);
|
|
30
|
+
return {
|
|
31
|
+
async recordTurnStart(command) {
|
|
32
|
+
turnCoordinator.pruneExpired();
|
|
33
|
+
const createdAt = now();
|
|
34
|
+
const traceContext = traceContextFromOpenCodeHookBody(command, new Date(createdAt).toISOString());
|
|
35
|
+
const repositoryMemory = await resolveHookRepositoryMemory(command, options, repositoryMemorySession);
|
|
36
|
+
const repoMemoryWorktree = resolvedRepoMemoryWorktree(repositoryMemory);
|
|
37
|
+
turnCoordinator.recordTurnStart({
|
|
38
|
+
client: OPENCODE_MEMORY_TURN_CLIENT,
|
|
39
|
+
sessionId: command.sessionId,
|
|
40
|
+
clientTurnId: command.userMessageId,
|
|
41
|
+
cwd: command.cwd,
|
|
42
|
+
workspaceKind: command.workspaceKind,
|
|
43
|
+
createdAt,
|
|
44
|
+
traceContext,
|
|
45
|
+
repositoryMemory,
|
|
46
|
+
});
|
|
47
|
+
await recordTraceBestEffort("opencode_memory.turn_start_event", recordTraceEvent({
|
|
48
|
+
eventId: traceTurnEventId(traceContext, "turn_start"),
|
|
49
|
+
memoraxCodeHome: options.memoraxCodeHome,
|
|
50
|
+
env: options.env,
|
|
51
|
+
traceContext,
|
|
52
|
+
type: "turn_start",
|
|
53
|
+
source: "opencode-plugin",
|
|
54
|
+
operation: "query",
|
|
55
|
+
ok: true,
|
|
56
|
+
request: {
|
|
57
|
+
prompt: command.prompt,
|
|
58
|
+
cwd: command.cwd,
|
|
59
|
+
},
|
|
60
|
+
}), options.diagnosticLogger);
|
|
61
|
+
await recordTraceBestEffort("opencode_memory.current_turn_write", writeCurrentTraceTurn(traceContext, {
|
|
62
|
+
client: "opencode",
|
|
63
|
+
memoraxCodeHome: options.memoraxCodeHome,
|
|
64
|
+
env: options.env,
|
|
65
|
+
now: () => new Date(now()),
|
|
66
|
+
}), options.diagnosticLogger);
|
|
67
|
+
options.diagnosticLogger?.("opencode_memory.turn_start", {
|
|
68
|
+
sessionId: command.sessionId,
|
|
69
|
+
userMessageId: command.userMessageId,
|
|
70
|
+
cacheSize: turnCoordinator.size(OPENCODE_MEMORY_TURN_CLIENT),
|
|
71
|
+
workspace: repositoryMemory.ok ? repositoryMemory.memory.scope?.repositorySlug : undefined,
|
|
72
|
+
workspaceScopeReason: repositoryMemory.ok ? undefined : repositoryMemory.reason,
|
|
73
|
+
});
|
|
74
|
+
const retrievalKey = JSON.stringify([command.sessionId, command.userMessageId]);
|
|
75
|
+
if (retrievalTurns.has(retrievalKey)) {
|
|
76
|
+
return {
|
|
77
|
+
ok: true,
|
|
78
|
+
...(repoMemoryWorktree ? { repoMemoryWorktree } : {}),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
retrievalTurns.add(retrievalKey);
|
|
82
|
+
while (retrievalTurns.size > retrievalTurnLimit) {
|
|
83
|
+
const oldest = retrievalTurns.values().next().value;
|
|
84
|
+
if (typeof oldest !== "string")
|
|
85
|
+
break;
|
|
86
|
+
retrievalTurns.delete(oldest);
|
|
87
|
+
}
|
|
88
|
+
const retrieval = await retrieveAutomaticMemoryContext({
|
|
89
|
+
diagnosticLogger: options.diagnosticLogger,
|
|
90
|
+
env: options.env ?? process.env,
|
|
91
|
+
fetchImpl: options.fetchImpl,
|
|
92
|
+
memoryObservability: options.memoryObservability,
|
|
93
|
+
memoryObservabilitySource: "opencode_plugin_retrieval",
|
|
94
|
+
query: command.prompt,
|
|
95
|
+
repositoryMemory,
|
|
96
|
+
sessionKey: command.sessionId,
|
|
97
|
+
traceContext,
|
|
98
|
+
});
|
|
99
|
+
return {
|
|
100
|
+
ok: true,
|
|
101
|
+
...(repoMemoryWorktree ? { repoMemoryWorktree } : {}),
|
|
102
|
+
...(retrieval.context ? { additionalContext: retrieval.context } : {}),
|
|
103
|
+
};
|
|
104
|
+
},
|
|
105
|
+
async writeback(command) {
|
|
106
|
+
turnCoordinator.pruneExpired();
|
|
107
|
+
const key = openCodeTurnKey(command.sessionId, command.userMessageId);
|
|
108
|
+
const entry = turnCoordinator.getTurn(key);
|
|
109
|
+
const materialized = openCodeMessageTurn(command.messages, command);
|
|
110
|
+
if (!materialized.ok) {
|
|
111
|
+
options.diagnosticLogger?.("opencode_memory.writeback", {
|
|
112
|
+
scheduled: false,
|
|
113
|
+
reason: materialized.reason,
|
|
114
|
+
sessionId: command.sessionId,
|
|
115
|
+
userMessageId: command.userMessageId,
|
|
116
|
+
assistantMessageId: command.assistantMessageId,
|
|
117
|
+
});
|
|
118
|
+
return { ok: true, scheduled: false, reason: materialized.reason };
|
|
119
|
+
}
|
|
120
|
+
if (materialized.turn.outcome === "interrupted") {
|
|
121
|
+
if (!entry) {
|
|
122
|
+
options.diagnosticLogger?.("opencode_memory.writeback", {
|
|
123
|
+
scheduled: false,
|
|
124
|
+
reason: "turn_metadata_mismatch",
|
|
125
|
+
sessionId: command.sessionId,
|
|
126
|
+
userMessageId: command.userMessageId,
|
|
127
|
+
assistantMessageId: command.assistantMessageId,
|
|
128
|
+
});
|
|
129
|
+
return { ok: true, scheduled: false, reason: "turn_metadata_mismatch" };
|
|
130
|
+
}
|
|
131
|
+
const traceContext = entry.traceContext;
|
|
132
|
+
await recordTraceBestEffort("opencode_memory.interrupted_turn_end_event", recordTraceEvent({
|
|
133
|
+
eventId: traceTurnEventId(traceContext, "turn_end"),
|
|
134
|
+
memoraxCodeHome: options.memoraxCodeHome,
|
|
135
|
+
env: options.env,
|
|
136
|
+
traceContext,
|
|
137
|
+
type: "turn_end",
|
|
138
|
+
source: "opencode-plugin",
|
|
139
|
+
operation: "reply",
|
|
140
|
+
ok: true,
|
|
141
|
+
outcome: "interrupted",
|
|
142
|
+
response: {
|
|
143
|
+
assistantMessage: materialized.turn.assistantReply,
|
|
144
|
+
},
|
|
145
|
+
}), options.diagnosticLogger);
|
|
146
|
+
await recordTraceBestEffort("opencode_memory.interrupted_current_turn_close", markCurrentTraceTurnOutcome(traceContext, "interrupted", {
|
|
147
|
+
client: "opencode",
|
|
148
|
+
memoraxCodeHome: options.memoraxCodeHome,
|
|
149
|
+
env: options.env,
|
|
150
|
+
}), options.diagnosticLogger);
|
|
151
|
+
turnCoordinator.discardTurn(key, "interrupted");
|
|
152
|
+
options.diagnosticLogger?.("opencode_memory.writeback", {
|
|
153
|
+
scheduled: false,
|
|
154
|
+
reason: "interrupted",
|
|
155
|
+
metadataDisposition: "consumed",
|
|
156
|
+
sessionId: command.sessionId,
|
|
157
|
+
userMessageId: command.userMessageId,
|
|
158
|
+
assistantMessageId: command.assistantMessageId,
|
|
159
|
+
});
|
|
160
|
+
return { ok: true, scheduled: false, reason: "interrupted" };
|
|
161
|
+
}
|
|
162
|
+
const traceContext = entry?.traceContext
|
|
163
|
+
?? traceContextFromOpenCodeHookBody(command, new Date(now()).toISOString());
|
|
164
|
+
await recordTraceBestEffort("opencode_memory.turn_end_event", recordTraceEvent({
|
|
165
|
+
eventId: traceTurnEventId(traceContext, "turn_end"),
|
|
166
|
+
memoraxCodeHome: options.memoraxCodeHome,
|
|
167
|
+
env: options.env,
|
|
168
|
+
traceContext,
|
|
169
|
+
type: "turn_end",
|
|
170
|
+
source: "opencode-plugin",
|
|
171
|
+
operation: "writeback",
|
|
172
|
+
ok: true,
|
|
173
|
+
outcome: materialized.turn.outcome,
|
|
174
|
+
response: {
|
|
175
|
+
content: materialized.turn.assistantReply,
|
|
176
|
+
},
|
|
177
|
+
}), options.diagnosticLogger);
|
|
178
|
+
await recordTraceBestEffort("opencode_memory.current_turn_close", markCurrentTraceTurnOutcome(traceContext, "completed", {
|
|
179
|
+
client: "opencode",
|
|
180
|
+
memoraxCodeHome: options.memoraxCodeHome,
|
|
181
|
+
env: options.env,
|
|
182
|
+
}), options.diagnosticLogger);
|
|
183
|
+
const writeback = await turnCoordinator.completeMaterializedTurn({
|
|
184
|
+
key,
|
|
185
|
+
metadata: entry,
|
|
186
|
+
resolveRepositoryMemory: () => resolveCurrentHookRepositoryMemory(entry, command, options, repositoryMemorySession),
|
|
187
|
+
userText: materialized.turn.userPrompt,
|
|
188
|
+
assistantText: materialized.turn.assistantReply,
|
|
189
|
+
writeback: {
|
|
190
|
+
client: OPENCODE_MEMORY_TURN_CLIENT,
|
|
191
|
+
sessionKey: command.sessionId,
|
|
192
|
+
env: options.env ?? process.env,
|
|
193
|
+
fetchImpl: options.fetchImpl,
|
|
194
|
+
memoryObservability: options.memoryObservability,
|
|
195
|
+
memoryObservabilitySource: "opencode_plugin_writeback",
|
|
196
|
+
traceContext,
|
|
197
|
+
},
|
|
198
|
+
});
|
|
199
|
+
if (!writeback.scheduled) {
|
|
200
|
+
options.diagnosticLogger?.("opencode_memory.writeback", {
|
|
201
|
+
scheduled: false,
|
|
202
|
+
reason: writeback.reason,
|
|
203
|
+
metadataDisposition: writeback.metadataDisposition,
|
|
204
|
+
sessionId: command.sessionId,
|
|
205
|
+
userMessageId: command.userMessageId,
|
|
206
|
+
assistantMessageId: command.assistantMessageId,
|
|
207
|
+
});
|
|
208
|
+
return { ok: true, scheduled: false, reason: writeback.reason };
|
|
209
|
+
}
|
|
210
|
+
options.diagnosticLogger?.("opencode_memory.writeback", {
|
|
211
|
+
scheduled: true,
|
|
212
|
+
metadataDisposition: writeback.metadataDisposition,
|
|
213
|
+
sessionId: command.sessionId,
|
|
214
|
+
userMessageId: command.userMessageId,
|
|
215
|
+
assistantMessageId: command.assistantMessageId,
|
|
216
|
+
promptChars: materialized.turn.userPrompt.length,
|
|
217
|
+
assistantChars: materialized.turn.assistantReply.length,
|
|
218
|
+
contentSource: "opencode_sdk_messages",
|
|
219
|
+
});
|
|
220
|
+
return { ok: true, scheduled: true };
|
|
221
|
+
},
|
|
222
|
+
size() {
|
|
223
|
+
return turnCoordinator.size(OPENCODE_MEMORY_TURN_CLIENT);
|
|
224
|
+
},
|
|
225
|
+
close() {
|
|
226
|
+
retrievalTurns.clear();
|
|
227
|
+
if (ownsTurnCoordinator)
|
|
228
|
+
turnCoordinator.close();
|
|
229
|
+
if (ownsRepositoryMemorySession)
|
|
230
|
+
repositoryMemorySession.close();
|
|
231
|
+
automaticWritebackRuntime?.close?.();
|
|
232
|
+
},
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
function openCodeTurnKey(sessionId, userMessageId) {
|
|
236
|
+
return {
|
|
237
|
+
client: OPENCODE_MEMORY_TURN_CLIENT,
|
|
238
|
+
sessionId,
|
|
239
|
+
clientTurnId: userMessageId,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
async function resolveHookRepositoryMemory(command, options, repositoryMemorySession) {
|
|
243
|
+
return await repositoryMemorySession.resolve({
|
|
244
|
+
client: OPENCODE_MEMORY_TURN_CLIENT,
|
|
245
|
+
sessionId: command.sessionId,
|
|
246
|
+
workspaceRoot: command.cwd,
|
|
247
|
+
workspaceKind: command.workspaceKind,
|
|
248
|
+
memoraxCodeHome: options.memoraxCodeHome ?? options.env?.MEMORAX_CODE_HOME,
|
|
249
|
+
env: options.env,
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
async function resolveCurrentHookRepositoryMemory(entry, command, options, repositoryMemorySession) {
|
|
253
|
+
return await repositoryMemorySession.resolve({
|
|
254
|
+
client: OPENCODE_MEMORY_TURN_CLIENT,
|
|
255
|
+
sessionId: command.sessionId,
|
|
256
|
+
workspaceRoot: command.cwd ?? entry?.cwd,
|
|
257
|
+
workspaceKind: command.workspaceKind ?? entry?.workspaceKind,
|
|
258
|
+
requireBoundScope: true,
|
|
259
|
+
memoraxCodeHome: options.memoraxCodeHome ?? options.env?.MEMORAX_CODE_HOME,
|
|
260
|
+
env: options.env,
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
async function recordTraceBestEffort(label, promise, diagnosticLogger) {
|
|
264
|
+
try {
|
|
265
|
+
await promise;
|
|
266
|
+
}
|
|
267
|
+
catch (error) {
|
|
268
|
+
diagnosticLogger?.("opencode_trace.write_failed", {
|
|
269
|
+
label,
|
|
270
|
+
error: error instanceof Error ? error.message : String(error),
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
function positiveInteger(value, fallback) {
|
|
275
|
+
const parsed = Number(value);
|
|
276
|
+
return Number.isInteger(parsed) && parsed > 0 ? parsed : fallback;
|
|
277
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { isRecord } from "../../shared/record.js";
|
|
2
|
+
export function openCodeMessageTurn(messages, input) {
|
|
3
|
+
const user = messages.find((message) => messageId(message) === input.userMessageId);
|
|
4
|
+
if (!isMessageRecord(user) || user.info.role !== "user") {
|
|
5
|
+
return { ok: false, reason: "user_message_not_found" };
|
|
6
|
+
}
|
|
7
|
+
const assistant = messages.find((message) => messageId(message) === input.assistantMessageId);
|
|
8
|
+
if (!isMessageRecord(assistant) || assistant.info.role !== "assistant") {
|
|
9
|
+
return { ok: false, reason: "assistant_message_not_found" };
|
|
10
|
+
}
|
|
11
|
+
if (stringField(user.info, "sessionID") !== input.sessionId
|
|
12
|
+
|| stringField(assistant.info, "sessionID") !== input.sessionId
|
|
13
|
+
|| stringField(assistant.info, "parentID") !== input.userMessageId) {
|
|
14
|
+
return { ok: false, reason: "message_identity_mismatch" };
|
|
15
|
+
}
|
|
16
|
+
const assistantTime = isRecord(assistant.info.time) ? assistant.info.time : undefined;
|
|
17
|
+
if (!Number.isFinite(assistantTime?.completed)) {
|
|
18
|
+
return { ok: false, reason: "assistant_not_completed" };
|
|
19
|
+
}
|
|
20
|
+
const assistantError = assistant.info.error;
|
|
21
|
+
const interrupted = isRecord(assistantError) && assistantError.name === "MessageAbortedError";
|
|
22
|
+
if (assistantError !== undefined && assistantError !== null && !interrupted) {
|
|
23
|
+
return { ok: false, reason: "assistant_error" };
|
|
24
|
+
}
|
|
25
|
+
if (assistant.info.summary === true) {
|
|
26
|
+
return { ok: false, reason: "summary_message" };
|
|
27
|
+
}
|
|
28
|
+
if (hasCompactionPart(user.parts) || hasCompactionPart(assistant.parts)) {
|
|
29
|
+
return { ok: false, reason: "compaction_message" };
|
|
30
|
+
}
|
|
31
|
+
const userPrompt = messageText(user, input.sessionId, input.userMessageId);
|
|
32
|
+
if (!userPrompt)
|
|
33
|
+
return { ok: false, reason: "user_prompt_missing" };
|
|
34
|
+
const assistantReply = messageText(assistant, input.sessionId, input.assistantMessageId);
|
|
35
|
+
if (!assistantReply && !interrupted)
|
|
36
|
+
return { ok: false, reason: "assistant_message_missing" };
|
|
37
|
+
return {
|
|
38
|
+
ok: true,
|
|
39
|
+
turn: {
|
|
40
|
+
sessionId: input.sessionId,
|
|
41
|
+
userMessageId: input.userMessageId,
|
|
42
|
+
assistantMessageId: input.assistantMessageId,
|
|
43
|
+
userPrompt,
|
|
44
|
+
assistantReply,
|
|
45
|
+
outcome: interrupted ? "interrupted" : "completed",
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function isMessageRecord(value) {
|
|
50
|
+
return isRecord(value) && isRecord(value.info) && Array.isArray(value.parts);
|
|
51
|
+
}
|
|
52
|
+
function messageId(value) {
|
|
53
|
+
return isMessageRecord(value) ? stringField(value.info, "id") : undefined;
|
|
54
|
+
}
|
|
55
|
+
function messageText(message, sessionId, messageId) {
|
|
56
|
+
return message.parts
|
|
57
|
+
.flatMap((part) => {
|
|
58
|
+
if (!isRecord(part)
|
|
59
|
+
|| part.type !== "text"
|
|
60
|
+
|| part.synthetic === true
|
|
61
|
+
|| part.ignored === true
|
|
62
|
+
|| stringField(part, "sessionID") !== sessionId
|
|
63
|
+
|| stringField(part, "messageID") !== messageId) {
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
const text = stringField(part, "text");
|
|
67
|
+
return text ? [text] : [];
|
|
68
|
+
})
|
|
69
|
+
.join("\n\n")
|
|
70
|
+
.trim();
|
|
71
|
+
}
|
|
72
|
+
function hasCompactionPart(parts) {
|
|
73
|
+
return parts.some((part) => isRecord(part) && part.type === "compaction");
|
|
74
|
+
}
|
|
75
|
+
function stringField(value, key) {
|
|
76
|
+
const field = value[key];
|
|
77
|
+
return typeof field === "string" && field.trim() ? field.trim() : undefined;
|
|
78
|
+
}
|