@memorax/memorax-code 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +53 -0
- package/bin/memorax-cli.mjs +28 -0
- package/bin/memorax-code-backend.mjs +4 -0
- package/bin/memorax-code-claude.mjs +4 -0
- package/bin/memorax-code-codex.mjs +4 -0
- package/bin/memorax-code-npm-preinstall.mjs +55 -0
- package/bin/memorax-code-plugin-postinstall.mjs +1236 -0
- package/bin/memorax-code.mjs +204 -0
- package/docs/configuration.md +232 -0
- package/docs/troubleshooting.md +179 -0
- package/lib/client-hook-runtime.mjs +32 -0
- package/lib/memorax-code-adapter-common/src/backend-connection.d.mts +111 -0
- package/lib/memorax-code-adapter-common/src/backend-connection.mjs +304 -0
- package/lib/memorax-code-adapter-common/src/clients/claude-command.mjs +38 -0
- package/lib/memorax-code-adapter-common/src/clients/codex-command.mjs +41 -0
- package/lib/memorax-code-adapter-common/src/clients/codex-plugin-artifact.d.mts +3 -0
- package/lib/memorax-code-adapter-common/src/clients/codex-plugin-artifact.mjs +38 -0
- package/lib/memorax-code-adapter-common/src/config-utils.d.mts +27 -0
- package/lib/memorax-code-adapter-common/src/config-utils.mjs +391 -0
- package/lib/memorax-code-adapter-common/src/hooks/capture-cwd-hook.mjs +137 -0
- package/lib/memorax-code-adapter-common/src/hooks/client-hook-launcher.mjs +324 -0
- package/lib/memorax-code-adapter-common/src/hooks/ensure-backend-runner.mjs +142 -0
- package/lib/memorax-code-adapter-common/src/hooks/hook-runtime-generation.d.mts +38 -0
- package/lib/memorax-code-adapter-common/src/hooks/hook-runtime-generation.mjs +501 -0
- package/lib/memorax-code-adapter-common/src/hooks/memory-skill-reminder-hook.mjs +277 -0
- package/lib/memorax-code-adapter-common/src/memorax-code-config-file.d.mts +28 -0
- package/lib/memorax-code-adapter-common/src/memorax-code-config-file.mjs +296 -0
- package/lib/memorax-code-adapter-common/src/memorax-defaults.d.mts +10 -0
- package/lib/memorax-code-adapter-common/src/memorax-defaults.mjs +12 -0
- package/lib/memorax-code-adapter-common/src/repo-memory/repo-memory-job-context.mjs +28 -0
- package/lib/memorax-code-adapter-common/src/repo-memory/repo-memory-job-marker.mjs +252 -0
- package/lib/memorax-code-adapter-common/src/repo-memory/repo-memory-job-supervisor.mjs +559 -0
- package/lib/memorax-code-adapter-common/src/repo-memory/repo-memory-job-worker.mjs +411 -0
- package/lib/memorax-code-adapter-common/src/repo-memory/repo-memory-update-policy-evaluator.mjs +185 -0
- package/lib/memorax-code-adapter-common/src/repo-memory/repo-memory-update-policy.mjs +165 -0
- package/lib/memorax-code-adapter-common/src/repo-memory/repo-procedure-memory-context.mjs +181 -0
- package/lib/memorax-code-adapter-common/src/repo-memory/repo-user-profile-context.mjs +251 -0
- package/lib/memorax-code-adapter-common/src/runtime-record.d.mts +55 -0
- package/lib/memorax-code-adapter-common/src/runtime-record.mjs +152 -0
- package/lib/memorax-code-adapter-common/src/windows-cli-invocation.mjs +100 -0
- package/lib/memorax-code-backend/dist/active-client-selection.js +35 -0
- package/lib/memorax-code-backend/dist/adapter-lifecycle-participant.js +1 -0
- package/lib/memorax-code-backend/dist/automatic-memory-retrieval.js +113 -0
- package/lib/memorax-code-backend/dist/automatic-memory-writeback.js +297 -0
- package/lib/memorax-code-backend/dist/backend-env.js +13 -0
- package/lib/memorax-code-backend/dist/backend-lifecycle-lock.js +42 -0
- package/lib/memorax-code-backend/dist/backend-process.js +147 -0
- package/lib/memorax-code-backend/dist/backend-service-cleanup.js +18 -0
- package/lib/memorax-code-backend/dist/backend-service-record.js +206 -0
- package/lib/memorax-code-backend/dist/backend-service-result.js +37 -0
- package/lib/memorax-code-backend/dist/backend-service-token.js +11 -0
- package/lib/memorax-code-backend/dist/backend-shutdown-request.js +133 -0
- package/lib/memorax-code-backend/dist/backend-state.js +58 -0
- package/lib/memorax-code-backend/dist/backend-status.js +53 -0
- package/lib/memorax-code-backend/dist/backend-token-record.js +79 -0
- package/lib/memorax-code-backend/dist/claude-adapter-lifecycle.js +134 -0
- package/lib/memorax-code-backend/dist/claude-local-transcript.js +648 -0
- package/lib/memorax-code-backend/dist/claude-memory-hook-runtime.js +472 -0
- package/lib/memorax-code-backend/dist/claude-transcript-turn.js +876 -0
- package/lib/memorax-code-backend/dist/client-plugin-removal.js +67 -0
- package/lib/memorax-code-backend/dist/client-selection.js +36 -0
- package/lib/memorax-code-backend/dist/codex-adapter-lifecycle.js +131 -0
- package/lib/memorax-code-backend/dist/codex-effective-prompt.js +54 -0
- package/lib/memorax-code-backend/dist/codex-memory-hook-runtime.js +541 -0
- package/lib/memorax-code-backend/dist/codex-plugin-hooks.js +421 -0
- package/lib/memorax-code-backend/dist/codex-plugin-install.js +523 -0
- package/lib/memorax-code-backend/dist/codex-rollout-turn.js +402 -0
- package/lib/memorax-code-backend/dist/codex-session-turn-index.js +88 -0
- package/lib/memorax-code-backend/dist/codex-workspace-links.js +55 -0
- package/lib/memorax-code-backend/dist/debug-log.js +21 -0
- package/lib/memorax-code-backend/dist/entrypoint.js +14 -0
- package/lib/memorax-code-backend/dist/incremental-jsonl-projection.js +271 -0
- package/lib/memorax-code-backend/dist/install-watchdog.js +71 -0
- package/lib/memorax-code-backend/dist/jsonl-append.js +75 -0
- package/lib/memorax-code-backend/dist/memorax-adapter.js +451 -0
- package/lib/memorax-code-backend/dist/memorax-cli.js +14 -0
- package/lib/memorax-code-backend/dist/memorax-code-config.js +279 -0
- package/lib/memorax-code-backend/dist/memorax-code-lifecycle.js +523 -0
- package/lib/memorax-code-backend/dist/memorax-code.js +3 -0
- package/lib/memorax-code-backend/dist/memorax-config.js +283 -0
- package/lib/memorax-code-backend/dist/memorax-http.js +142 -0
- package/lib/memorax-code-backend/dist/memory-cli.js +345 -0
- package/lib/memorax-code-backend/dist/memory-hook-command.js +200 -0
- package/lib/memorax-code-backend/dist/memory-observability.js +1 -0
- package/lib/memorax-code-backend/dist/memory-project.js +89 -0
- package/lib/memorax-code-backend/dist/memory-reminder-trace-recorder.js +58 -0
- package/lib/memorax-code-backend/dist/memory-service.js +66 -0
- package/lib/memorax-code-backend/dist/memory-turn-coordinator.js +139 -0
- package/lib/memorax-code-backend/dist/memory-viewer-activity.js +113 -0
- package/lib/memorax-code-backend/dist/memory-viewer-data-projection-cache.js +69 -0
- package/lib/memorax-code-backend/dist/memory-viewer-event-identity.js +3 -0
- package/lib/memorax-code-backend/dist/memory-viewer-history-projection.js +79 -0
- package/lib/memorax-code-backend/dist/memory-viewer-logo.js +1 -0
- package/lib/memorax-code-backend/dist/memory-viewer-observability.js +8 -0
- package/lib/memorax-code-backend/dist/memory-viewer-redaction.js +52 -0
- package/lib/memorax-code-backend/dist/memory-viewer-session-title.js +93 -0
- package/lib/memorax-code-backend/dist/memory-viewer-store.js +964 -0
- package/lib/memorax-code-backend/dist/memory-viewer-turn-reference.js +12 -0
- package/lib/memorax-code-backend/dist/memory-viewer-user-html.js +115 -0
- package/lib/memorax-code-backend/dist/memory-viewer-user-projection.js +168 -0
- package/lib/memorax-code-backend/dist/memory-viewer-writeback-status.js +97 -0
- package/lib/memorax-code-backend/dist/memory-writeback-buffer.js +217 -0
- package/lib/memorax-code-backend/dist/memory-writeback-chunk.js +120 -0
- package/lib/memorax-code-backend/dist/memory-writeback-reconciler.js +244 -0
- package/lib/memorax-code-backend/dist/memory-writeback-task-projection.js +377 -0
- package/lib/memorax-code-backend/dist/proxy-env.js +54 -0
- package/lib/memorax-code-backend/dist/repo-memory-readiness.js +188 -0
- package/lib/memorax-code-backend/dist/repository-memory-context.js +134 -0
- package/lib/memorax-code-backend/dist/repository-memory-scope.js +490 -0
- package/lib/memorax-code-backend/dist/server-cli.js +787 -0
- package/lib/memorax-code-backend/dist/server-health.js +16 -0
- package/lib/memorax-code-backend/dist/server-http.js +110 -0
- package/lib/memorax-code-backend/dist/server-json.js +4 -0
- package/lib/memorax-code-backend/dist/server-memory-hook.js +32 -0
- package/lib/memorax-code-backend/dist/server-memory-viewer.js +135 -0
- package/lib/memorax-code-backend/dist/server-observability.js +102 -0
- package/lib/memorax-code-backend/dist/server.js +220 -0
- package/lib/memorax-code-backend/dist/service-entrypoint.js +10 -0
- package/lib/memorax-code-backend/dist/service.js +567 -0
- package/lib/memorax-code-backend/dist/trace-config.js +112 -0
- package/lib/memorax-code-backend/dist/trace-context.js +111 -0
- package/lib/memorax-code-backend/dist/trace-store.js +571 -0
- package/lib/memorax-code-backend/dist/utils.js +3 -0
- package/lib/memorax-code-backend/dist/windows-cli-invocation.js +148 -0
- package/lib/memorax-code-backend/package.json +26 -0
- package/lib/memorax-code-claude-adapter/.claude-plugin/plugin.json +15 -0
- package/lib/memorax-code-claude-adapter/hooks/hook-launcher.mjs +27 -0
- package/lib/memorax-code-claude-adapter/hooks/hooks.json +66 -0
- package/lib/memorax-code-claude-adapter/hooks/repo-memory-job.mjs +37 -0
- package/lib/memorax-code-claude-adapter/hooks/runtime-hook.mjs +4 -0
- package/lib/memorax-code-claude-adapter/hooks/runtime-shell.json +5 -0
- package/lib/memorax-code-claude-adapter/package.json +13 -0
- package/lib/memorax-code-claude-adapter/runtime-hooks/capture-cwd.mjs +17 -0
- package/lib/memorax-code-claude-adapter/runtime-hooks/ensure-backend.mjs +59 -0
- package/lib/memorax-code-claude-adapter/runtime-hooks/memory-cli-session.mjs +33 -0
- package/lib/memorax-code-claude-adapter/runtime-hooks/memory-skill-reminder.mjs +73 -0
- package/lib/memorax-code-claude-adapter/runtime-hooks/memory-turn.mjs +91 -0
- package/lib/memorax-code-claude-adapter/scripts/build-marketplace.mjs +99 -0
- package/lib/memorax-code-claude-adapter/skills/memorax-code/SKILL.md +83 -0
- package/lib/memorax-code-claude-adapter/skills/memorax-code/agents/claude.yaml +10 -0
- package/lib/memorax-code-claude-adapter/skills/memorax-code/agents/openai.yaml +7 -0
- package/lib/memorax-code-claude-adapter/skills/memorax-code/defaults.json +9 -0
- package/lib/memorax-code-claude-adapter/skills/memorax-code/references/memorax-add.md +82 -0
- package/lib/memorax-code-claude-adapter/skills/memorax-code/references/memorax-search.md +61 -0
- package/lib/memorax-code-claude-adapter/skills/memorax-code/references/personal-read.md +46 -0
- package/lib/memorax-code-claude-adapter/skills/memorax-code/references/personal-write.md +100 -0
- package/lib/memorax-code-claude-adapter/skills/memorax-code/references/repo-build.md +270 -0
- package/lib/memorax-code-claude-adapter/skills/memorax-code/references/repo-read.md +96 -0
- package/lib/memorax-code-claude-adapter/skills/memorax-code/references/repo-templates.md +270 -0
- package/lib/memorax-code-claude-adapter/skills/memorax-code/references/repo-update.md +116 -0
- package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/collect_all.py +496 -0
- package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/detect_updates.py +856 -0
- package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/git_commit_facets.py +222 -0
- package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/github_resource_facets.py +504 -0
- package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +509 -0
- package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/prepare_repo_memory.py +411 -0
- package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/user_profile_memory.py +528 -0
- package/lib/memorax-code-claude-adapter/skills/memorax-code/scripts/validate_memory.py +226 -0
- package/lib/memorax-code-claude-adapter/src/adapter-paths.mjs +46 -0
- package/lib/memorax-code-claude-adapter/src/cli.mjs +363 -0
- package/lib/memorax-code-claude-adapter/src/config-utils.mjs +1 -0
- package/lib/memorax-code-claude-adapter/src/config.mjs +544 -0
- package/lib/memorax-code-claude-adapter/src/plugin-artifact-contract.mjs +148 -0
- package/lib/memorax-code-claude-adapter/src/plugin-install.mjs +566 -0
- package/lib/memorax-code-claude-marketplace/.claude-plugin/marketplace.json +15 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/.claude-plugin/plugin.json +15 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/hooks/hook-launcher.mjs +27 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/hooks/hooks.json +66 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/hooks/repo-memory-job.mjs +37 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/hooks/runtime-hook.mjs +4 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/hooks/runtime-shell.json +5 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/backend-connection.d.mts +111 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/backend-connection.mjs +304 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/clients/claude-command.mjs +38 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/clients/codex-command.mjs +41 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/clients/codex-plugin-artifact.d.mts +3 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/clients/codex-plugin-artifact.mjs +38 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/config-utils.d.mts +27 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/config-utils.mjs +391 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/capture-cwd-hook.mjs +137 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/client-hook-launcher.mjs +324 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/ensure-backend-runner.mjs +142 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/hook-runtime-generation.d.mts +38 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/hook-runtime-generation.mjs +501 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/hooks/memory-skill-reminder-hook.mjs +277 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/memorax-code-config-file.d.mts +28 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/memorax-code-config-file.mjs +296 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/memorax-defaults.d.mts +10 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/memorax-defaults.mjs +12 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/repo-memory/repo-memory-job-context.mjs +28 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/repo-memory/repo-memory-job-marker.mjs +252 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/repo-memory/repo-memory-job-supervisor.mjs +559 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/repo-memory/repo-memory-job-worker.mjs +411 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/repo-memory/repo-memory-update-policy-evaluator.mjs +185 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/repo-memory/repo-memory-update-policy.mjs +165 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/repo-memory/repo-procedure-memory-context.mjs +181 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/repo-memory/repo-user-profile-context.mjs +251 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/runtime-record.d.mts +55 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/runtime-record.mjs +152 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/memorax-code-adapter-common/src/windows-cli-invocation.mjs +100 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/package.json +13 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/runtime-hooks/capture-cwd.mjs +17 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/runtime-hooks/ensure-backend.mjs +59 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/runtime-hooks/memory-cli-session.mjs +33 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/runtime-hooks/memory-skill-reminder.mjs +73 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/runtime-hooks/memory-turn.mjs +91 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/scripts/build-marketplace.mjs +99 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/SKILL.md +83 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/agents/claude.yaml +10 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/agents/openai.yaml +7 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/defaults.json +9 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/memorax-add.md +82 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/memorax-search.md +61 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/personal-read.md +46 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/personal-write.md +100 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/repo-build.md +270 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/repo-read.md +96 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/repo-templates.md +270 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/references/repo-update.md +116 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/collect_all.py +496 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/detect_updates.py +856 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/git_commit_facets.py +222 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/github_resource_facets.py +504 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +509 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/prepare_repo_memory.py +411 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/user_profile_memory.py +528 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/skills/memorax-code/scripts/validate_memory.py +226 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/src/adapter-paths.mjs +46 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/src/cli.mjs +363 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/src/config-utils.mjs +1 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/src/config.mjs +544 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/src/plugin-artifact-contract.mjs +148 -0
- package/lib/memorax-code-claude-marketplace/plugins/memorax-code-claude-adapter/src/plugin-install.mjs +566 -0
- package/lib/memorax-code-codex-adapter/.codex-plugin/plugin.json +33 -0
- package/lib/memorax-code-codex-adapter/assets/composer-icon.png +0 -0
- package/lib/memorax-code-codex-adapter/assets/logo.png +0 -0
- package/lib/memorax-code-codex-adapter/hooks/hook-launcher.mjs +26 -0
- package/lib/memorax-code-codex-adapter/hooks/hooks.json +61 -0
- package/lib/memorax-code-codex-adapter/hooks/repo-memory-job.mjs +38 -0
- package/lib/memorax-code-codex-adapter/hooks/repo-memory-update-policy.mjs +10 -0
- package/lib/memorax-code-codex-adapter/hooks/runtime-hook.mjs +4 -0
- package/lib/memorax-code-codex-adapter/hooks/runtime-shell.json +5 -0
- package/lib/memorax-code-codex-adapter/package.json +13 -0
- package/lib/memorax-code-codex-adapter/runtime-hooks/capture-cwd.mjs +18 -0
- package/lib/memorax-code-codex-adapter/runtime-hooks/ensure-backend.mjs +82 -0
- package/lib/memorax-code-codex-adapter/runtime-hooks/memory-skill-reminder.mjs +125 -0
- package/lib/memorax-code-codex-adapter/runtime-hooks/memory-writeback.mjs +52 -0
- package/lib/memorax-code-codex-adapter/skills/memorax-code/SKILL.md +83 -0
- package/lib/memorax-code-codex-adapter/skills/memorax-code/agents/claude.yaml +10 -0
- package/lib/memorax-code-codex-adapter/skills/memorax-code/agents/openai.yaml +7 -0
- package/lib/memorax-code-codex-adapter/skills/memorax-code/defaults.json +9 -0
- package/lib/memorax-code-codex-adapter/skills/memorax-code/references/memorax-add.md +82 -0
- package/lib/memorax-code-codex-adapter/skills/memorax-code/references/memorax-search.md +61 -0
- package/lib/memorax-code-codex-adapter/skills/memorax-code/references/personal-read.md +46 -0
- package/lib/memorax-code-codex-adapter/skills/memorax-code/references/personal-write.md +100 -0
- package/lib/memorax-code-codex-adapter/skills/memorax-code/references/repo-build.md +270 -0
- package/lib/memorax-code-codex-adapter/skills/memorax-code/references/repo-read.md +96 -0
- package/lib/memorax-code-codex-adapter/skills/memorax-code/references/repo-templates.md +270 -0
- package/lib/memorax-code-codex-adapter/skills/memorax-code/references/repo-update.md +116 -0
- package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/collect_all.py +496 -0
- package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/detect_updates.py +856 -0
- package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/git_commit_facets.py +222 -0
- package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/github_resource_facets.py +504 -0
- package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/gitlab_resource_facets.py +509 -0
- package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/prepare_repo_memory.py +411 -0
- package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/user_profile_memory.py +528 -0
- package/lib/memorax-code-codex-adapter/skills/memorax-code/scripts/validate_memory.py +226 -0
- package/lib/memorax-code-codex-adapter/src/adapter-paths.mjs +29 -0
- package/lib/memorax-code-codex-adapter/src/cli.mjs +368 -0
- package/lib/memorax-code-codex-adapter/src/config-utils.mjs +1 -0
- package/lib/memorax-code-codex-adapter/src/config.mjs +226 -0
- package/lib/memorax-code-codex-adapter/src/session-registry.mjs +331 -0
- package/lib/memorax-code-codex-adapter/src/workspace-kind.mjs +68 -0
- package/lib/node-version.mjs +11 -0
- package/lib/npm-invocation.mjs +31 -0
- package/lib/resolve-claude-command.mjs +47 -0
- package/lib/resolve-codex-command.mjs +94 -0
- package/lib/run-entrypoint.mjs +83 -0
- package/lib/vscode-extension-command.mjs +119 -0
- package/lib/windows-cli-invocation.mjs +100 -0
- package/package.json +45 -0
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import {
|
|
4
|
+
atomicWriteJson,
|
|
5
|
+
readJsonFile,
|
|
6
|
+
readStdinJson,
|
|
7
|
+
stringOption,
|
|
8
|
+
withJsonFileLock,
|
|
9
|
+
} from "../config-utils.mjs";
|
|
10
|
+
|
|
11
|
+
const DEFAULT_REMINDER_INTERVAL_TURNS = 5;
|
|
12
|
+
const DEFAULT_MEMORY_SKILL_INVOCATION = "$memorax-code";
|
|
13
|
+
export const PERSONAL_MEMORY_REMINDER_CONTEXT = personalMemoryReminderContext();
|
|
14
|
+
|
|
15
|
+
export function personalMemoryReminderContext(memorySkillInvocation) {
|
|
16
|
+
const invocation = stringOption(memorySkillInvocation) ?? DEFAULT_MEMORY_SKILL_INVOCATION;
|
|
17
|
+
return [
|
|
18
|
+
`MemoraX Code personal-memory reminder: Use ${invocation} when the user states a durable current-repo identity or interaction preference, asks to list or recall stored personal memory, or explicitly asks to save, update, forget, or delete it.`,
|
|
19
|
+
"Route reusable action sequences and work rules to procedure memory; do not store repository facts, one-off task details, or secrets.",
|
|
20
|
+
].join(" ");
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export async function runMemorySkillReminderHook(options, hookInput) {
|
|
24
|
+
try {
|
|
25
|
+
const input = hookInput ?? await readStdinJson();
|
|
26
|
+
const sessionId = stringOption(input.session_id) ?? stringOption(input.sessionId);
|
|
27
|
+
if (!sessionId) return;
|
|
28
|
+
const transcriptPath = stringOption(input.transcript_path) ?? stringOption(input.transcriptPath);
|
|
29
|
+
if (options.requireTranscriptPath && !transcriptPath) return;
|
|
30
|
+
const hookEventName = stringOption(input.hook_event_name) ?? stringOption(input.hookEventName) ?? "UserPromptSubmit";
|
|
31
|
+
|
|
32
|
+
const memoraxCodeHome = process.env.MEMORAX_CODE_HOME || defaultMemoraxCodeHome();
|
|
33
|
+
if (hookEventName !== "UserPromptSubmit") return;
|
|
34
|
+
|
|
35
|
+
const statePath = join(memoraxCodeHome, "adapters", options.adapterDir, "memory-skill-reminders.json");
|
|
36
|
+
const turnId = stringOption(input.turn_id)
|
|
37
|
+
?? stringOption(input.turnId)
|
|
38
|
+
?? stringOption(input.prompt_id)
|
|
39
|
+
?? stringOption(input.promptId);
|
|
40
|
+
const intervalTurns = reminderIntervalTurns(memoraxCodeHome);
|
|
41
|
+
const update = withJsonFileLock(statePath, () => {
|
|
42
|
+
const existing = readJsonFile(statePath);
|
|
43
|
+
const next = nextReminderState(
|
|
44
|
+
existing?.unreadable ? undefined : existing?.value,
|
|
45
|
+
options.runtime,
|
|
46
|
+
sessionId,
|
|
47
|
+
turnId,
|
|
48
|
+
);
|
|
49
|
+
if (next.duplicate) return next;
|
|
50
|
+
const sessionState = next.state.sessions[sessionId];
|
|
51
|
+
const memoryReminderDue = shouldRemind(
|
|
52
|
+
sessionState?.turnCount,
|
|
53
|
+
intervalTurns,
|
|
54
|
+
options.remindOnFirstTurn !== false,
|
|
55
|
+
);
|
|
56
|
+
const supplementalReminderDue = options.supplementalReminderAfterCompact === true
|
|
57
|
+
&& sessionState?.supplementalReminderPending === true;
|
|
58
|
+
if (supplementalReminderDue) sessionState.supplementalReminderPending = false;
|
|
59
|
+
atomicWriteJson(statePath, next.state);
|
|
60
|
+
return {
|
|
61
|
+
...next,
|
|
62
|
+
memoryReminderDue,
|
|
63
|
+
supplementalReminderDue,
|
|
64
|
+
turnCount: sessionState?.turnCount,
|
|
65
|
+
};
|
|
66
|
+
});
|
|
67
|
+
if (update.duplicate) return;
|
|
68
|
+
const { memoryReminderDue, supplementalReminderDue } = update;
|
|
69
|
+
|
|
70
|
+
const baseAdditionalContext = stringOption(options.baseAdditionalContext);
|
|
71
|
+
if (baseAdditionalContext || memoryReminderDue || supplementalReminderDue) {
|
|
72
|
+
const cadenceReminderContext = memoryReminderDue
|
|
73
|
+
? await buildCadenceReminderContext(options, input)
|
|
74
|
+
: undefined;
|
|
75
|
+
const personalMemoryContext = supplementalReminderDue || (memoryReminderDue && update.turnCount === 1)
|
|
76
|
+
? await buildPersonalMemoryContext(options, input)
|
|
77
|
+
: undefined;
|
|
78
|
+
const reminderContext = stringOption(combinedReminderContext(options, {
|
|
79
|
+
memoryReminderDue,
|
|
80
|
+
supplementalReminderDue,
|
|
81
|
+
}, cadenceReminderContext, personalMemoryContext));
|
|
82
|
+
const additionalContext = [baseAdditionalContext, reminderContext].filter(Boolean).join("\n\n");
|
|
83
|
+
const triggers = [
|
|
84
|
+
...(memoryReminderDue ? ["cadence"] : []),
|
|
85
|
+
...(supplementalReminderDue ? ["post_compaction"] : []),
|
|
86
|
+
];
|
|
87
|
+
process.stdout.write(`${JSON.stringify({
|
|
88
|
+
hookSpecificOutput: {
|
|
89
|
+
hookEventName: "UserPromptSubmit",
|
|
90
|
+
additionalContext,
|
|
91
|
+
},
|
|
92
|
+
})}\n`);
|
|
93
|
+
if (reminderContext) {
|
|
94
|
+
await notifyReminder(options, {
|
|
95
|
+
sessionId,
|
|
96
|
+
turnId,
|
|
97
|
+
transcriptPath,
|
|
98
|
+
cwd: stringOption(input.cwd),
|
|
99
|
+
workspaceKind: stringOption(input.workspace_kind) ?? stringOption(input.workspaceKind),
|
|
100
|
+
content: reminderContext,
|
|
101
|
+
triggers,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
} catch (error) {
|
|
106
|
+
if (process.env[options.debugEnv] === "1") {
|
|
107
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
async function notifyReminder(options, reminder) {
|
|
113
|
+
if (typeof options.onReminder !== "function") return;
|
|
114
|
+
try {
|
|
115
|
+
await options.onReminder(reminder);
|
|
116
|
+
} catch (error) {
|
|
117
|
+
if (process.env[options.debugEnv] === "1") {
|
|
118
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export function markSupplementalReminderAfterCompact(options, input) {
|
|
124
|
+
try {
|
|
125
|
+
const hookEventName = stringOption(input.hook_event_name) ?? stringOption(input.hookEventName);
|
|
126
|
+
if (hookEventName !== "SessionStart" || stringOption(input.source) !== "compact") return;
|
|
127
|
+
const sessionId = stringOption(input.session_id) ?? stringOption(input.sessionId);
|
|
128
|
+
if (!sessionId) return;
|
|
129
|
+
const memoraxCodeHome = process.env.MEMORAX_CODE_HOME || defaultMemoraxCodeHome();
|
|
130
|
+
const statePath = join(memoraxCodeHome, "adapters", options.adapterDir, "memory-skill-reminders.json");
|
|
131
|
+
withJsonFileLock(statePath, () => {
|
|
132
|
+
const existing = readJsonFile(statePath);
|
|
133
|
+
atomicWriteJson(statePath, markSupplementalReminderPending(
|
|
134
|
+
existing?.unreadable ? undefined : existing?.value,
|
|
135
|
+
options.runtime,
|
|
136
|
+
sessionId,
|
|
137
|
+
));
|
|
138
|
+
});
|
|
139
|
+
} catch (error) {
|
|
140
|
+
if (process.env[options.debugEnv] === "1") {
|
|
141
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
async function buildCadenceReminderContext(options, input) {
|
|
147
|
+
if (typeof options.buildCadenceReminderContext !== "function") return undefined;
|
|
148
|
+
try {
|
|
149
|
+
return stringOption(await options.buildCadenceReminderContext(input));
|
|
150
|
+
} catch (error) {
|
|
151
|
+
if (process.env[options.debugEnv] === "1") {
|
|
152
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
153
|
+
}
|
|
154
|
+
return undefined;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
async function buildPersonalMemoryContext(options, input) {
|
|
159
|
+
if (typeof options.buildPersonalMemoryContext !== "function") return undefined;
|
|
160
|
+
try {
|
|
161
|
+
return stringOption(await options.buildPersonalMemoryContext(input));
|
|
162
|
+
} catch (error) {
|
|
163
|
+
if (process.env[options.debugEnv] === "1") {
|
|
164
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
165
|
+
}
|
|
166
|
+
return undefined;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function combinedReminderContext(options, due, cadenceReminderContext, personalMemoryContext) {
|
|
171
|
+
const contexts = [];
|
|
172
|
+
if (due.memoryReminderDue) contexts.push(memoryReminderContext(options));
|
|
173
|
+
if (due.supplementalReminderDue || personalMemoryContext) {
|
|
174
|
+
const additionalReminderContext = stringOption(options.additionalReminderContext);
|
|
175
|
+
if (additionalReminderContext) contexts.push(additionalReminderContext);
|
|
176
|
+
}
|
|
177
|
+
if (personalMemoryContext) contexts.push(personalMemoryContext);
|
|
178
|
+
if (due.memoryReminderDue && cadenceReminderContext) contexts.push(cadenceReminderContext);
|
|
179
|
+
|
|
180
|
+
return contexts.join("\n\n");
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function memoryReminderContext(options) {
|
|
184
|
+
const invocation = stringOption(options.memorySkillInvocation) ?? DEFAULT_MEMORY_SKILL_INVOCATION;
|
|
185
|
+
return `MemoraX Code reminder: proactively invoke ${invocation} whenever coding memory might help, even when uncertain; when in doubt, run one focused coding-memory search for relevant prior knowledge. Also use ${invocation} for repository-scoped personal memory, and classify the authority before reading or writing.`;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function defaultMemoraxCodeHome() {
|
|
189
|
+
return process.env.HOME ? join(process.env.HOME, ".memorax-code") : ".memorax-code";
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function nextReminderState(existing, runtime, sessionId, turnId) {
|
|
193
|
+
const state = reminderState(existing, runtime);
|
|
194
|
+
const current = state.sessions[sessionId] && typeof state.sessions[sessionId] === "object" && !Array.isArray(state.sessions[sessionId])
|
|
195
|
+
? state.sessions[sessionId]
|
|
196
|
+
: {};
|
|
197
|
+
if (turnId && current.lastTurnId === turnId) return { state, duplicate: true };
|
|
198
|
+
const currentCount = Number.isInteger(current.turnCount) && current.turnCount >= 0 ? current.turnCount : 0;
|
|
199
|
+
state.sessions[sessionId] = {
|
|
200
|
+
...current,
|
|
201
|
+
turnCount: currentCount + 1,
|
|
202
|
+
...(turnId ? { lastTurnId: turnId } : {}),
|
|
203
|
+
lastSeenAt: state.updatedAt,
|
|
204
|
+
};
|
|
205
|
+
return { state, duplicate: false };
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function markSupplementalReminderPending(existing, runtime, sessionId) {
|
|
209
|
+
const state = reminderState(existing, runtime);
|
|
210
|
+
const current = state.sessions[sessionId] && typeof state.sessions[sessionId] === "object" && !Array.isArray(state.sessions[sessionId])
|
|
211
|
+
? state.sessions[sessionId]
|
|
212
|
+
: {};
|
|
213
|
+
state.sessions[sessionId] = {
|
|
214
|
+
...current,
|
|
215
|
+
supplementalReminderPending: true,
|
|
216
|
+
lastSeenAt: state.updatedAt,
|
|
217
|
+
};
|
|
218
|
+
return state;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function reminderState(existing, runtime) {
|
|
222
|
+
const state = existing && typeof existing === "object" && !Array.isArray(existing)
|
|
223
|
+
? existing
|
|
224
|
+
: { version: 1, runtime, sessions: {} };
|
|
225
|
+
state.version = 1;
|
|
226
|
+
state.runtime = runtime;
|
|
227
|
+
state.updatedAt = new Date().toISOString();
|
|
228
|
+
state.sessions = state.sessions && typeof state.sessions === "object" && !Array.isArray(state.sessions)
|
|
229
|
+
? state.sessions
|
|
230
|
+
: {};
|
|
231
|
+
return state;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
function shouldRemind(turnCount, intervalTurns, remindOnFirstTurn) {
|
|
235
|
+
if (!Number.isInteger(turnCount) || turnCount <= 0) return false;
|
|
236
|
+
if (remindOnFirstTurn) return (turnCount - 1) % intervalTurns === 0;
|
|
237
|
+
return turnCount > intervalTurns && (turnCount - 1) % intervalTurns === 0;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function reminderIntervalTurns(memoraxCodeHome) {
|
|
241
|
+
return positiveInteger(process.env.MEMORAX_CODE_MEMORY_SKILL_REMINDER_INTERVAL_TURNS)
|
|
242
|
+
?? configReminderIntervalTurns(join(memoraxCodeHome, "config.toml"))
|
|
243
|
+
?? DEFAULT_REMINDER_INTERVAL_TURNS;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
function configReminderIntervalTurns(path) {
|
|
247
|
+
try {
|
|
248
|
+
return parseReminderIntervalTurns(readFileSync(path, "utf8"));
|
|
249
|
+
} catch {
|
|
250
|
+
return undefined;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function parseReminderIntervalTurns(text) {
|
|
255
|
+
let section = "";
|
|
256
|
+
for (const rawLine of text.split(/\r?\n/)) {
|
|
257
|
+
const line = rawLine.split("#", 1)[0].trim();
|
|
258
|
+
if (!line) continue;
|
|
259
|
+
const sectionMatch = line.match(/^\[([^\]]+)\]$/);
|
|
260
|
+
if (sectionMatch) {
|
|
261
|
+
section = sectionMatch[1].trim();
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
if (section !== "memory.skill_reminder") continue;
|
|
265
|
+
const fieldMatch = line.match(/^interval_turns\s*=\s*(.+)$/);
|
|
266
|
+
if (fieldMatch) return positiveInteger(fieldMatch[1]);
|
|
267
|
+
}
|
|
268
|
+
return undefined;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function positiveInteger(value) {
|
|
272
|
+
if (typeof value !== "string") return undefined;
|
|
273
|
+
const normalized = value.trim().replaceAll("_", "");
|
|
274
|
+
if (!/^[1-9]\d*$/.test(normalized)) return undefined;
|
|
275
|
+
const parsed = Number(normalized);
|
|
276
|
+
return Number.isSafeInteger(parsed) ? parsed : undefined;
|
|
277
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export const CONFIG_UPDATE_WARNING: string;
|
|
2
|
+
|
|
3
|
+
export type ConfigFileUpdateResult = "created" | "updated" | "unchanged" | "failed";
|
|
4
|
+
|
|
5
|
+
export function updateConfigFileAtomically(options: {
|
|
6
|
+
path: string;
|
|
7
|
+
defaultText: string;
|
|
8
|
+
transform: (text: string, parsed: unknown) => string;
|
|
9
|
+
parseToml: (text: string) => unknown;
|
|
10
|
+
warn?: (message: string) => void;
|
|
11
|
+
operations?: Record<string, (...args: any[]) => any>;
|
|
12
|
+
platform?: NodeJS.Platform;
|
|
13
|
+
}): ConfigFileUpdateResult;
|
|
14
|
+
|
|
15
|
+
export function ensurePrivateConfigDirectory(
|
|
16
|
+
path: string,
|
|
17
|
+
options?: {
|
|
18
|
+
operations?: Record<string, (...args: any[]) => any>;
|
|
19
|
+
platform?: NodeJS.Platform;
|
|
20
|
+
},
|
|
21
|
+
): void;
|
|
22
|
+
|
|
23
|
+
export function setTomlField(
|
|
24
|
+
text: string,
|
|
25
|
+
section: string,
|
|
26
|
+
key: string,
|
|
27
|
+
renderedValue: string | undefined,
|
|
28
|
+
): string;
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
import {
|
|
2
|
+
accessSync,
|
|
3
|
+
chmodSync,
|
|
4
|
+
closeSync,
|
|
5
|
+
constants,
|
|
6
|
+
copyFileSync,
|
|
7
|
+
fchmodSync,
|
|
8
|
+
fchownSync,
|
|
9
|
+
linkSync,
|
|
10
|
+
lstatSync,
|
|
11
|
+
mkdirSync,
|
|
12
|
+
openSync,
|
|
13
|
+
readFileSync,
|
|
14
|
+
renameSync,
|
|
15
|
+
unlinkSync,
|
|
16
|
+
writeFileSync,
|
|
17
|
+
} from "node:fs";
|
|
18
|
+
import { randomUUID } from "node:crypto";
|
|
19
|
+
import { basename, dirname, join } from "node:path";
|
|
20
|
+
|
|
21
|
+
export const CONFIG_UPDATE_WARNING = "MemoraX Code config could not be safely updated or verified; existing config was preserved.";
|
|
22
|
+
|
|
23
|
+
const defaultOperations = {
|
|
24
|
+
accessSync,
|
|
25
|
+
chmodSync,
|
|
26
|
+
closeSync,
|
|
27
|
+
copyFileSync,
|
|
28
|
+
fchmodSync,
|
|
29
|
+
fchownSync,
|
|
30
|
+
linkSync,
|
|
31
|
+
lstatSync,
|
|
32
|
+
mkdirSync,
|
|
33
|
+
openSync,
|
|
34
|
+
readFileSync,
|
|
35
|
+
renameSync,
|
|
36
|
+
unlinkSync,
|
|
37
|
+
writeFileSync,
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export function updateConfigFileAtomically({
|
|
41
|
+
path,
|
|
42
|
+
defaultText,
|
|
43
|
+
transform,
|
|
44
|
+
parseToml,
|
|
45
|
+
warn = console.warn,
|
|
46
|
+
operations = {},
|
|
47
|
+
platform = process.platform,
|
|
48
|
+
}) {
|
|
49
|
+
const fs = { ...defaultOperations, ...operations };
|
|
50
|
+
let existingStat;
|
|
51
|
+
try {
|
|
52
|
+
existingStat = fs.lstatSync(path);
|
|
53
|
+
if (!existingStat.isFile()) return failed(warn);
|
|
54
|
+
} catch (error) {
|
|
55
|
+
if (!isNodeError(error) || error.code !== "ENOENT") return failed(warn);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
let existingText;
|
|
59
|
+
if (existingStat) {
|
|
60
|
+
try {
|
|
61
|
+
existingText = fs.readFileSync(path, "utf8");
|
|
62
|
+
} catch {
|
|
63
|
+
return failed(warn);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
let candidate;
|
|
68
|
+
let unchanged = false;
|
|
69
|
+
try {
|
|
70
|
+
if (existingText === undefined) {
|
|
71
|
+
candidate = defaultText;
|
|
72
|
+
} else {
|
|
73
|
+
const parsed = parseToml(existingText);
|
|
74
|
+
candidate = transform(existingText, parsed);
|
|
75
|
+
unchanged = candidate === existingText;
|
|
76
|
+
}
|
|
77
|
+
if (!unchanged) parseToml(candidate);
|
|
78
|
+
} catch {
|
|
79
|
+
return failed(warn);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
try {
|
|
83
|
+
ensurePrivateConfigDirectoryWithOperations(fs, path, platform);
|
|
84
|
+
} catch {
|
|
85
|
+
return failed(warn);
|
|
86
|
+
}
|
|
87
|
+
if (unchanged) return "unchanged";
|
|
88
|
+
if (existingText !== undefined) {
|
|
89
|
+
try {
|
|
90
|
+
fs.accessSync(path, constants.W_OK);
|
|
91
|
+
} catch {
|
|
92
|
+
return failed(warn);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const uniqueSuffix = `${process.pid}.${randomUUID()}`;
|
|
97
|
+
const tempPath = join(dirname(path), `.${basename(path)}.${uniqueSuffix}.tmp`);
|
|
98
|
+
const backupPath = existingStat
|
|
99
|
+
? join(dirname(path), `.${basename(path)}.${uniqueSuffix}.bak`)
|
|
100
|
+
: undefined;
|
|
101
|
+
let fd;
|
|
102
|
+
let backupCreated = false;
|
|
103
|
+
let renamed = false;
|
|
104
|
+
try {
|
|
105
|
+
fd = fs.openSync(tempPath, "wx", 0o600);
|
|
106
|
+
fs.writeFileSync(fd, candidate, "utf8");
|
|
107
|
+
if (existingStat && platform !== "win32") {
|
|
108
|
+
fs.fchownSync(fd, existingStat.uid, existingStat.gid);
|
|
109
|
+
fs.fchmodSync(fd, existingStat.mode & 0o7777);
|
|
110
|
+
} else if (!existingStat && platform !== "win32") {
|
|
111
|
+
fs.fchmodSync(fd, 0o600);
|
|
112
|
+
}
|
|
113
|
+
fs.closeSync(fd);
|
|
114
|
+
fd = undefined;
|
|
115
|
+
if (backupPath) {
|
|
116
|
+
if (platform === "win32") {
|
|
117
|
+
fs.copyFileSync(path, backupPath, constants.COPYFILE_EXCL);
|
|
118
|
+
} else {
|
|
119
|
+
fs.linkSync(path, backupPath);
|
|
120
|
+
}
|
|
121
|
+
backupCreated = true;
|
|
122
|
+
}
|
|
123
|
+
fs.renameSync(tempPath, path);
|
|
124
|
+
renamed = true;
|
|
125
|
+
} catch {
|
|
126
|
+
if (fd !== undefined) {
|
|
127
|
+
try {
|
|
128
|
+
fs.closeSync(fd);
|
|
129
|
+
} catch {
|
|
130
|
+
// Best effort: unlinking an open temporary file is safe on supported Unix hosts.
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (!renamed) {
|
|
134
|
+
try {
|
|
135
|
+
fs.unlinkSync(tempPath);
|
|
136
|
+
} catch {
|
|
137
|
+
// The temporary file may not have been created or may already have been renamed.
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
if (backupCreated && backupPath) {
|
|
141
|
+
try {
|
|
142
|
+
fs.unlinkSync(backupPath);
|
|
143
|
+
} catch {
|
|
144
|
+
// The original target is still authoritative when rename has not completed.
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return failed(warn);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
try {
|
|
151
|
+
const verifiedText = fs.readFileSync(path, "utf8");
|
|
152
|
+
if (verifiedText !== candidate) throw new Error("config verification failed");
|
|
153
|
+
parseToml(verifiedText);
|
|
154
|
+
const verifiedStat = fs.lstatSync(path);
|
|
155
|
+
if (!verifiedStat.isFile()) throw new Error("config type verification failed");
|
|
156
|
+
if (platform !== "win32") {
|
|
157
|
+
const expectedMode = existingStat ? existingStat.mode & 0o7777 : 0o600;
|
|
158
|
+
if ((verifiedStat.mode & 0o7777) !== expectedMode) throw new Error("config mode verification failed");
|
|
159
|
+
if (existingStat && (verifiedStat.uid !== existingStat.uid || verifiedStat.gid !== existingStat.gid)) {
|
|
160
|
+
throw new Error("config owner verification failed");
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
if (backupCreated && backupPath) {
|
|
164
|
+
fs.unlinkSync(backupPath);
|
|
165
|
+
backupCreated = false;
|
|
166
|
+
}
|
|
167
|
+
} catch {
|
|
168
|
+
if (existingStat && backupCreated && backupPath) {
|
|
169
|
+
if (platform === "win32") {
|
|
170
|
+
const restorePath = join(dirname(path), `.${basename(path)}.${uniqueSuffix}.restore.tmp`);
|
|
171
|
+
let restoreCopied = false;
|
|
172
|
+
try {
|
|
173
|
+
fs.copyFileSync(backupPath, restorePath, constants.COPYFILE_EXCL);
|
|
174
|
+
restoreCopied = true;
|
|
175
|
+
fs.renameSync(restorePath, path);
|
|
176
|
+
restoreCopied = false;
|
|
177
|
+
fs.unlinkSync(backupPath);
|
|
178
|
+
backupCreated = false;
|
|
179
|
+
} catch {
|
|
180
|
+
if (restoreCopied) {
|
|
181
|
+
try {
|
|
182
|
+
fs.unlinkSync(restorePath);
|
|
183
|
+
} catch {
|
|
184
|
+
// Keep the original backup for operator recovery.
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
} else {
|
|
189
|
+
try {
|
|
190
|
+
fs.renameSync(backupPath, path);
|
|
191
|
+
backupCreated = false;
|
|
192
|
+
} catch {
|
|
193
|
+
// Keep the hard-link backup for operator recovery if atomic restore itself fails.
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
} else if (!existingStat) {
|
|
197
|
+
try {
|
|
198
|
+
fs.unlinkSync(path);
|
|
199
|
+
} catch {
|
|
200
|
+
// Best effort: the new target may already be absent.
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return failed(warn);
|
|
204
|
+
}
|
|
205
|
+
return existingText === undefined ? "created" : "updated";
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export function ensurePrivateConfigDirectory(
|
|
209
|
+
path,
|
|
210
|
+
{ operations = {}, platform = process.platform } = {},
|
|
211
|
+
) {
|
|
212
|
+
const fs = { ...defaultOperations, ...operations };
|
|
213
|
+
ensurePrivateConfigDirectoryWithOperations(fs, path, platform);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export function setTomlField(text, section, key, renderedValue) {
|
|
217
|
+
const source = String(text ?? "");
|
|
218
|
+
const newline = source.includes("\r\n") ? "\r\n" : "\n";
|
|
219
|
+
const lines = source.split(/\r?\n/);
|
|
220
|
+
const escapedSection = section.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
221
|
+
const escapedKey = key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
222
|
+
const header = new RegExp(`^\\s*\\[(?:${escapedSection}|"${escapedSection}"|'${escapedSection}')\\]\\s*(?:#.*)?$`);
|
|
223
|
+
const assignment = new RegExp(`^(\\s*(?:${escapedKey}|"${escapedKey}"|'${escapedKey}')\\s*=\\s*)`);
|
|
224
|
+
const start = lines.findIndex((line) => header.test(line));
|
|
225
|
+
if (start === -1) {
|
|
226
|
+
if (renderedValue === undefined) return source;
|
|
227
|
+
const separator = source.length === 0
|
|
228
|
+
? ""
|
|
229
|
+
: source.endsWith(`${newline}${newline}`)
|
|
230
|
+
? ""
|
|
231
|
+
: source.endsWith(newline)
|
|
232
|
+
? newline
|
|
233
|
+
: `${newline}${newline}`;
|
|
234
|
+
return `${source}${separator}[${section}]${newline}${key} = ${renderedValue}${newline}`;
|
|
235
|
+
}
|
|
236
|
+
const nextHeader = lines.findIndex((line, index) => index > start && /^\s*\[/.test(line));
|
|
237
|
+
const end = nextHeader === -1 ? lines.length : nextHeader;
|
|
238
|
+
const field = lines.findIndex((line, index) => index > start && index < end && assignment.test(line));
|
|
239
|
+
if (field !== -1) {
|
|
240
|
+
if (renderedValue === undefined) {
|
|
241
|
+
lines.splice(field, 1);
|
|
242
|
+
} else {
|
|
243
|
+
const prefix = lines[field].match(assignment)?.[1] ?? `${key} = `;
|
|
244
|
+
const comment = tomlInlineComment(lines[field].slice(prefix.length));
|
|
245
|
+
lines[field] = `${prefix}${renderedValue}${comment}`;
|
|
246
|
+
}
|
|
247
|
+
} else if (renderedValue !== undefined) {
|
|
248
|
+
lines.splice(start + 1, 0, `${key} = ${renderedValue}`);
|
|
249
|
+
}
|
|
250
|
+
return lines.join(newline);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
function ensurePrivateConfigDirectoryWithOperations(fs, path, platform) {
|
|
254
|
+
const directoryPath = dirname(path);
|
|
255
|
+
fs.mkdirSync(directoryPath, { recursive: true, mode: 0o700 });
|
|
256
|
+
if (platform !== "win32") fs.chmodSync(directoryPath, 0o700);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
function failed(warn) {
|
|
260
|
+
warn(CONFIG_UPDATE_WARNING);
|
|
261
|
+
return "failed";
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
function tomlInlineComment(value) {
|
|
265
|
+
let quote;
|
|
266
|
+
let escaped = false;
|
|
267
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
268
|
+
const character = value[index];
|
|
269
|
+
if (quote === '"' && escaped) {
|
|
270
|
+
escaped = false;
|
|
271
|
+
continue;
|
|
272
|
+
}
|
|
273
|
+
if (quote === '"' && character === "\\") {
|
|
274
|
+
escaped = true;
|
|
275
|
+
continue;
|
|
276
|
+
}
|
|
277
|
+
if (quote) {
|
|
278
|
+
if (character === quote) quote = undefined;
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
if (character === '"' || character === "'") {
|
|
282
|
+
quote = character;
|
|
283
|
+
continue;
|
|
284
|
+
}
|
|
285
|
+
if (character === "#") {
|
|
286
|
+
let commentStart = index;
|
|
287
|
+
while (commentStart > 0 && /[ \t]/.test(value[commentStart - 1])) commentStart -= 1;
|
|
288
|
+
return value.slice(commentStart);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
return "";
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
function isNodeError(error) {
|
|
295
|
+
return error instanceof Error;
|
|
296
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export const MEMORAX_DEFAULT_BASE_URL: "https://platform.memorax.net";
|
|
2
|
+
export const MEMORAX_ACCOUNT_URL: "https://platform.memorax.net/";
|
|
3
|
+
export const MEMORAX_DEFAULT_MEMORY_OUTPUT_LANGUAGE: "zh";
|
|
4
|
+
|
|
5
|
+
export type MemoraxMemoryOutputLanguage = "zh" | "en";
|
|
6
|
+
|
|
7
|
+
export function normalizeMemoraxBaseUrl(value: unknown): string;
|
|
8
|
+
export function normalizeMemoraxMemoryOutputLanguage(
|
|
9
|
+
value: unknown,
|
|
10
|
+
): MemoraxMemoryOutputLanguage | undefined;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export const MEMORAX_DEFAULT_BASE_URL = "https://platform.memorax.net";
|
|
2
|
+
export const MEMORAX_ACCOUNT_URL = "https://platform.memorax.net/";
|
|
3
|
+
export const MEMORAX_DEFAULT_MEMORY_OUTPUT_LANGUAGE = "zh";
|
|
4
|
+
|
|
5
|
+
export function normalizeMemoraxBaseUrl(value) {
|
|
6
|
+
return String(value ?? "").trim().replace(/\/+$/, "");
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function normalizeMemoraxMemoryOutputLanguage(value) {
|
|
10
|
+
const normalized = String(value ?? "").trim().toLowerCase();
|
|
11
|
+
return normalized === "zh" || normalized === "en" ? normalized : undefined;
|
|
12
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
const INTERNAL_JOB_KIND = "repo-memory";
|
|
2
|
+
const JOB_ID_PATTERN = /^\d{17}-(?:build|update)-[a-zA-Z0-9_.-]+-[0-9a-f]{8}$/;
|
|
3
|
+
const RUN_ID_PATTERN = /^[0-9a-f]{32}$/;
|
|
4
|
+
|
|
5
|
+
export function readRepoMemoryJobWorkerContext(env = process.env) {
|
|
6
|
+
if (env.MEMORAX_CODE_REPO_MEMORY_JOB_KIND !== INTERNAL_JOB_KIND) return undefined;
|
|
7
|
+
const jobId = stringValue(env.MEMORAX_CODE_REPO_MEMORY_JOB_ID);
|
|
8
|
+
const runId = stringValue(env.MEMORAX_CODE_REPO_MEMORY_JOB_RUN_ID);
|
|
9
|
+
if (!jobId || !JOB_ID_PATTERN.test(jobId) || !runId || !RUN_ID_PATTERN.test(runId)) return undefined;
|
|
10
|
+
return { kind: INTERNAL_JOB_KIND, jobId, runId };
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function isRepoMemoryJobWorker(env = process.env) {
|
|
14
|
+
return readRepoMemoryJobWorkerContext(env) !== undefined;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function repoMemoryJobWorkerEnv(input, env = process.env) {
|
|
18
|
+
return {
|
|
19
|
+
...env,
|
|
20
|
+
MEMORAX_CODE_REPO_MEMORY_JOB_KIND: INTERNAL_JOB_KIND,
|
|
21
|
+
MEMORAX_CODE_REPO_MEMORY_JOB_ID: input.jobId,
|
|
22
|
+
MEMORAX_CODE_REPO_MEMORY_JOB_RUN_ID: input.runId,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function stringValue(value) {
|
|
27
|
+
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
28
|
+
}
|