flurryx-code-memory 0.5.0__tar.gz → 0.5.2__tar.gz
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.
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/CHANGELOG.md +44 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/PKG-INFO +1 -1
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/README.md +42 -26
- flurryx_code_memory-0.5.2/install.ps1 +369 -0
- flurryx_code_memory-0.5.2/install.sh +302 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/plugins/claude-code/README.md +13 -17
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/plugins/claude-code/scripts/lib/state.js +3 -31
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/plugins/claude-code/scripts/on-post-tool.js +4 -10
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/plugins/claude-code/scripts/on-pre-tool.js +4 -6
- flurryx_code_memory-0.5.2/plugins/claude-code/scripts/on-user-prompt.js +48 -0
- flurryx_code_memory-0.5.2/plugins/cursor/README.md +161 -0
- flurryx_code_memory-0.5.2/plugins/cursor/hooks/hooks.json.template +79 -0
- flurryx_code_memory-0.5.2/plugins/cursor/install.sh +231 -0
- flurryx_code_memory-0.5.2/plugins/cursor/rules/code-memory.mdc +39 -0
- flurryx_code_memory-0.5.2/plugins/cursor/scripts/lib/claim-intent.js +158 -0
- flurryx_code_memory-0.5.2/plugins/cursor/scripts/lib/claim-intent.test.js +159 -0
- flurryx_code_memory-0.5.2/plugins/cursor/scripts/lib/io.js +42 -0
- flurryx_code_memory-0.5.2/plugins/cursor/scripts/lib/memory.js +155 -0
- flurryx_code_memory-0.5.2/plugins/cursor/scripts/lib/state.js +176 -0
- flurryx_code_memory-0.5.2/plugins/cursor/scripts/on-after-file-edit.js +57 -0
- flurryx_code_memory-0.5.2/plugins/cursor/scripts/on-before-mcp-execution.js +22 -0
- flurryx_code_memory-0.5.2/plugins/cursor/scripts/on-before-submit-prompt.js +43 -0
- flurryx_code_memory-0.5.2/plugins/cursor/scripts/on-post-tool-use.js +33 -0
- flurryx_code_memory-0.5.2/plugins/cursor/scripts/on-pre-compact.js +54 -0
- flurryx_code_memory-0.5.2/plugins/cursor/scripts/on-pre-tool-use.js +54 -0
- flurryx_code_memory-0.5.2/plugins/cursor/scripts/on-session-end.js +18 -0
- flurryx_code_memory-0.5.2/plugins/cursor/scripts/on-session-start.js +36 -0
- flurryx_code_memory-0.5.2/plugins/cursor/scripts/on-stop.js +54 -0
- flurryx_code_memory-0.5.2/plugins/cursor/scripts/resolver-debounce.js +44 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/plugins/opencode/README.md +24 -26
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/plugins/opencode/src/code-memory.ts +14 -190
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/pyproject.toml +1 -1
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/scripts/install.ps1 +27 -14
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/scripts/install.sh +32 -11
- flurryx_code_memory-0.5.2/src/code_memory/__init__.py +16 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/claims/indexer.py +79 -1
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/claims/store.py +12 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/cli.py +12 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/config.py +11 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/mcp_server.py +49 -1
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/sync/autostart/__init__.py +7 -1
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/sync/autostart/base.py +35 -1
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/sync/autostart/launchd.py +35 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/sync/safety.py +28 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/updater.py +181 -27
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_autostart_adapters.py +38 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_claim_indexer.py +108 -2
- flurryx_code_memory-0.5.2/tests/test_mcp_shutdown.py +91 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_watch_safety.py +56 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/uv.lock +56 -56
- flurryx_code_memory-0.5.0/install.ps1 +0 -217
- flurryx_code_memory-0.5.0/install.sh +0 -181
- flurryx_code_memory-0.5.0/plugins/claude-code/scripts/lib/format.js +0 -79
- flurryx_code_memory-0.5.0/plugins/claude-code/scripts/lib/intent.js +0 -53
- flurryx_code_memory-0.5.0/plugins/claude-code/scripts/on-user-prompt.js +0 -110
- flurryx_code_memory-0.5.0/plugins/opencode/src/code-memory-lib/intent.ts +0 -74
- flurryx_code_memory-0.5.0/src/code_memory/__init__.py +0 -8
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/.claude-plugin/marketplace.json +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/.env.example +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/.gitignore +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/docker/docker-compose.yml +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/docs/BENCHMARK.md +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/docs/BENCHMARK_VS_BASELINE.json +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/docs/BENCHMARK_VS_BASELINE.md +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/docs/architecture.png +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/docs/benchmark-raw.json +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/docs/hero.png +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/plugins/claude-code/.claude-plugin/plugin.json +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/plugins/claude-code/commands/code-memory.md +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/plugins/claude-code/hooks/hooks.json +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/plugins/claude-code/install.sh +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/plugins/claude-code/scripts/lib/claim-intent.js +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/plugins/claude-code/scripts/lib/claim-intent.test.js +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/plugins/claude-code/scripts/lib/io.js +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/plugins/claude-code/scripts/lib/memory.js +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/plugins/claude-code/scripts/on-retrieve-seen.js +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/plugins/claude-code/scripts/on-session-start.js +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/plugins/claude-code/scripts/on-stop.js +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/plugins/claude-code/scripts/resolver-debounce.js +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/plugins/claude-code/skills/code-memory/SKILL.md +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/plugins/opencode/install.sh +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/plugins/opencode/package-lock.json +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/plugins/opencode/package.json +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/plugins/opencode/scripts/add-mcp.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/plugins/opencode/scripts/install.mjs +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/plugins/opencode/scripts/uninstall.mjs +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/plugins/opencode/skills/code-memory/SKILL.md +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/plugins/opencode/src/code-memory-lib/claim-intent.test.mts +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/plugins/opencode/src/code-memory-lib/claim-intent.ts +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/plugins/opencode/src/code-memory-lib/memory-client.ts +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/plugins/opencode/tsconfig.json +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/scripts/benchmark.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/scripts/benchmark_queries.json +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/scripts/benchmark_vs_baseline.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/scripts/benchmark_vs_grep.sh +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/scripts/ingest.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/claims/__init__.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/claims/extractor.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/claims/resolver.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/embed/__init__.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/embed/cache.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/embed/m3.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/embed/ollama.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/embed/tei.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/episodic/__init__.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/episodic/sqlite_store.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/extractor/__init__.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/extractor/csproj.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/extractor/dll.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/extractor/gitignore.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/extractor/nuget.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/extractor/sanity.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/extractor/sln.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/extractor/treesitter.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/graph/__init__.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/graph/falkor_store.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/metrics.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/orchestrator/__init__.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/orchestrator/git_delta.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/orchestrator/ingest_state.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/orchestrator/pipeline.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/orchestrator/reset.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/orchestrator/resolver.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/orchestrator/retrieve.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/resilience.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/sync/__init__.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/sync/autostart/schtasks.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/sync/autostart/systemd.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/sync/hooks.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/sync/snapshot.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/sync/store.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/sync/sync.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/sync/watcher.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/vector/__init__.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/src/code_memory/vector/qdrant_store.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_chunk_text.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_claim_extractor.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_claim_resolver.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_claim_store.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_config_embed_dim.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_config_sentinel.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_csproj.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_dll_members.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_dll_parser.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_embed_backend.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_embed_cache.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_embed_m3.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_embed_tei.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_episode_dedup.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_episode_head_sha.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_extractor_csharp.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_extractor_filters.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_extractor_php.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_extractor_python_imports.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_extractor_receiver_type.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_extractor_references.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_extractor_sanity.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_extractor_ts_abstract.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_extractor_ts_inject.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_extractor_utf8.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_file_containment.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_git_delta.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_graph_queries.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_graph_temporal.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_graph_vacuum_at_sha.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_hooks_installer.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_ingest_state.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_mcp_assert_claim.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_mcp_server_descriptions.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_mcp_strict_project.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_metrics.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_nuget_resolver.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_overload_resolution.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_partial_class.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_pipeline_references.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_pipeline_temporal_wiring.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_qdrant_legacy_guard.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_razor_inject.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_resilience.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_resolver.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_resolver_assembly.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_retrieve_claims_surfacing.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_retrieve_rerank.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_sln.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_smoke.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_snapshot_e2e.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_snapshot_format.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_snapshot_store.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_sync_decision_tree.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_watcher_debouncer.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_watcher_exclude.py +0 -0
- {flurryx_code_memory-0.5.0 → flurryx_code_memory-0.5.2}/tests/test_watcher_ref_events.py +0 -0
|
@@ -8,6 +8,50 @@ when the repo grows.
|
|
|
8
8
|
This file complements `git log`: commits explain mechanics, this file
|
|
9
9
|
explains intent.
|
|
10
10
|
|
|
11
|
+
## [0.5.2] — 2026-05-30
|
|
12
|
+
|
|
13
|
+
Release theme: **the watcher stops leaking**. A diagnosis of runaway RAM
|
|
14
|
+
turned up dozens of orphaned `code-memory watch` daemons — one permanent
|
|
15
|
+
launchd agent per directory any MCP server had ever booted in, including
|
|
16
|
+
throwaway per-session dirs. This release stops the bleed and self-heals
|
|
17
|
+
the cruft. Also lands semantic dedupe for near-duplicate user claims.
|
|
18
|
+
|
|
19
|
+
### Fixed — Unbounded launchd watcher accumulation
|
|
20
|
+
|
|
21
|
+
**What:** `ensure_autostart()` no longer registers a persistent OS agent
|
|
22
|
+
for ephemeral / per-session directories (`~/.claude/homunculus/*`,
|
|
23
|
+
`.cursor/worktrees/*`, `plugins/cache/*`); the session-scoped in-process
|
|
24
|
+
watcher still covers them. `LaunchdAdapter.prune_stale()` (run on every
|
|
25
|
+
MCP bootstrap) boots out and removes agents whose `WorkingDirectory` is
|
|
26
|
+
gone or ephemeral.
|
|
27
|
+
|
|
28
|
+
**Reason:** each MCP boot registered a `KeepAlive` + `RunAtLoad` agent for
|
|
29
|
+
its cwd. Ephemeral session dirs got permanent watchers that survived kill
|
|
30
|
+
(launchd relaunched them) and reboot, piling up dozens of daemons and the
|
|
31
|
+
RAM/CPU they pin. `prune_stale` is launchd-only for now; systemd/schtasks
|
|
32
|
+
GC is a follow-up.
|
|
33
|
+
|
|
34
|
+
### Fixed — Graceful watcher teardown on MCP shutdown
|
|
35
|
+
|
|
36
|
+
**What:** the MCP server registers `atexit` + `SIGTERM` handlers that call
|
|
37
|
+
`Watcher.stop()`.
|
|
38
|
+
|
|
39
|
+
**Reason:** the in-process watcher ran as a daemon thread with no clean
|
|
40
|
+
stop, so an in-flight debounced sync was dropped and the watchdog Observer
|
|
41
|
+
never joined cleanly on exit.
|
|
42
|
+
|
|
43
|
+
### Added — Semantic dedupe of near-duplicate claims
|
|
44
|
+
|
|
45
|
+
**What:** `ClaimsIndexer` collapses a new claim into the closest open claim
|
|
46
|
+
when cosine similarity is `>= CLAIMS_SEMANTIC_DEDUP_THRESHOLD` (default
|
|
47
|
+
0.90), ahead of the SQL write.
|
|
48
|
+
|
|
49
|
+
**Reason:** exact (subject, predicate, object) dedupe missed paraphrases
|
|
50
|
+
("project uses flurryx" / "project depends-on flurryx"), so semantically
|
|
51
|
+
identical claims were stored three times. Best-effort — embedder/backend
|
|
52
|
+
errors fall through to the existing SQL-level dedupe; set `>= 1.0` to
|
|
53
|
+
disable.
|
|
54
|
+
|
|
11
55
|
## [0.3.0] — 2026-05-26
|
|
12
56
|
|
|
13
57
|
Release theme: **the claim loop closes**. v0.2.0 shipped the storage
|
|
@@ -199,6 +199,10 @@ claude mcp add code-memory --scope user \
|
|
|
199
199
|
# 5. OpenCode plugin
|
|
200
200
|
npm i -g code-memory-opencode
|
|
201
201
|
code-memory-opencode-install
|
|
202
|
+
|
|
203
|
+
# 6. Cursor plugin (requires repo cloned; package release pending)
|
|
204
|
+
git clone https://github.com/fmflurry/code-memory ~/.code-memory/repo
|
|
205
|
+
~/.code-memory/repo/plugins/cursor/install.sh
|
|
202
206
|
```
|
|
203
207
|
|
|
204
208
|
</details>
|
|
@@ -206,7 +210,7 @@ code-memory-opencode-install
|
|
|
206
210
|
<details>
|
|
207
211
|
<summary><strong>MCP-only (lightest, ~10 s)</strong></summary>
|
|
208
212
|
|
|
209
|
-
Just the Claude Code MCP server — no auto-
|
|
213
|
+
Just the Claude Code MCP server — no auto-learn / auto-record hooks, no Docker, no Ollama. Useful when FalkorDB + Qdrant already run elsewhere, or you only want the `codememory_*` tools by hand.
|
|
210
214
|
|
|
211
215
|
```bash
|
|
212
216
|
claude mcp add code-memory \
|
|
@@ -1341,45 +1345,55 @@ uvx --from git+https://github.com/dev/code-memory code-memory-mcp
|
|
|
1341
1345
|
### Harness plugins
|
|
1342
1346
|
|
|
1343
1347
|
The MCP server above exposes manual tools. The **harness plugins** make
|
|
1344
|
-
the same backend **ambient** —
|
|
1345
|
-
|
|
1346
|
-
recording sessions as episodes when the agent stops
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
| Plugin
|
|
1351
|
-
|
|
|
1352
|
-
| [`plugins/opencode`](plugins/opencode/README.md)
|
|
1353
|
-
| [`plugins/claude-code`](plugins/claude-code/README.md) | Plain Node scripts wired via `hooks.json`; uses `SessionStart`, `UserPromptSubmit`, `PostToolUse` (`Write`/`Edit`/`MultiEdit`), `Stop`.
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
-
|
|
1348
|
+
the same backend **ambient** — steering the agent toward the index
|
|
1349
|
+
before grep / read / shell, auto-reingesting on every `Write` / `Edit`,
|
|
1350
|
+
recording sessions as episodes when the agent stops, and nudging on
|
|
1351
|
+
durable user assertions. The plugins are optional and live alongside
|
|
1352
|
+
the MCP server; install whichever your agent harness uses.
|
|
1353
|
+
|
|
1354
|
+
| Plugin | Hook model |
|
|
1355
|
+
| ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
1356
|
+
| [`plugins/opencode`](plugins/opencode/README.md) | Bun-loaded TypeScript module; uses `chat.message`, `experimental.chat.system.transform`, `tool.execute.after`, `session.idle`. |
|
|
1357
|
+
| [`plugins/claude-code`](plugins/claude-code/README.md) | Plain Node scripts wired via `hooks.json`; uses `SessionStart`, `UserPromptSubmit`, `PostToolUse` (`Write`/`Edit`/`MultiEdit`), `Stop`. |
|
|
1358
|
+
| [`plugins/cursor`](plugins/cursor/README.md) | Plain Node scripts wired via `hooks.json`; uses `sessionStart`, `beforeSubmitPrompt`, `preToolUse`, `beforeMCPExecution`, `postToolUse`, `afterFileEdit`, `preCompact`, `stop`, `sessionEnd`. |
|
|
1359
|
+
|
|
1360
|
+
All three plugins:
|
|
1361
|
+
|
|
1362
|
+
- Steer the agent toward `codememory_retrieve` via a one-shot gate
|
|
1363
|
+
nudge before grep / read / shell (never blocks).
|
|
1359
1364
|
- Debounce the cross-file resolver (~1.5 s after the last write) so a
|
|
1360
1365
|
20-file refactor collapses to exactly one resolver run.
|
|
1361
1366
|
- Run a one-shot git-delta ingest at session start to catch
|
|
1362
1367
|
out-of-band edits (vim, IDE, `git pull`).
|
|
1363
1368
|
- Record the session as an episode on idle / stop with the first user
|
|
1364
|
-
message + `git diff` as the patch.
|
|
1369
|
+
message + `git diff` as the patch. The Cursor plugin additionally
|
|
1370
|
+
records on `preCompact`, catching state before context compaction.
|
|
1365
1371
|
- **Detect durable user assertions on every prompt** — preferences
|
|
1366
1372
|
(`I love X`), decisions (`we use X`), rejections (`don't use Y`),
|
|
1367
1373
|
ownership (`Alice owns billing`), location (`auth lives at apps/api`)
|
|
1368
|
-
— and inject an in-
|
|
1374
|
+
— and inject an in-prompt nudge that demands the agent call
|
|
1369
1375
|
`codememory_assert_claim` *before* answering. The nudge is
|
|
1370
1376
|
polarity-flipped: asserting is the default, skipping requires a
|
|
1371
1377
|
one-line written justification. See
|
|
1372
|
-
[`plugins/claude-code/scripts/lib/claim-intent.js`](plugins/claude-code/scripts/lib/claim-intent.js)
|
|
1373
|
-
|
|
1374
|
-
|
|
1378
|
+
[`plugins/claude-code/scripts/lib/claim-intent.js`](plugins/claude-code/scripts/lib/claim-intent.js),
|
|
1379
|
+
[`plugins/opencode/src/code-memory-lib/claim-intent.ts`](plugins/opencode/src/code-memory-lib/claim-intent.ts),
|
|
1380
|
+
and [`plugins/cursor/scripts/lib/claim-intent.js`](plugins/cursor/scripts/lib/claim-intent.js)
|
|
1381
|
+
for the regex patterns and nudge template — kept in lockstep.
|
|
1382
|
+
|
|
1383
|
+
> Cursor caveat: `beforeSubmitPrompt` cannot inject context, so the
|
|
1384
|
+
> Cursor plugin stashes the claim nudge on `beforeSubmitPrompt` and
|
|
1385
|
+
> drains it on the first `postToolUse` of the turn. If the reply uses
|
|
1386
|
+
> no tools, the nudge does not surface for that turn — uncommon in
|
|
1387
|
+
> substantive sessions.
|
|
1375
1388
|
|
|
1376
1389
|
Install via the top-level installer:
|
|
1377
1390
|
|
|
1378
1391
|
```bash
|
|
1379
|
-
./scripts/install.sh --plugins=all
|
|
1380
|
-
./scripts/install.sh --plugins=claudecode
|
|
1381
|
-
./scripts/install.sh --plugins=
|
|
1382
|
-
./scripts/install.sh --plugins=
|
|
1392
|
+
./scripts/install.sh --plugins=all # all three, global
|
|
1393
|
+
./scripts/install.sh --plugins=claudecode # Claude Code only
|
|
1394
|
+
./scripts/install.sh --plugins=cursor # Cursor only
|
|
1395
|
+
./scripts/install.sh --plugins=opencode,claudecode,cursor # csv form
|
|
1396
|
+
./scripts/install.sh --plugins=all --plugins-scope=project # ./.opencode, ./.claude, ./.cursor
|
|
1383
1397
|
```
|
|
1384
1398
|
|
|
1385
1399
|
Or install a single plugin directly without re-running the backend
|
|
@@ -1390,6 +1404,8 @@ installer:
|
|
|
1390
1404
|
./plugins/claude-code/install.sh # registers a local Claude Code
|
|
1391
1405
|
# marketplace at the repo root and runs
|
|
1392
1406
|
# `claude plugin install code-memory@code-memory`
|
|
1407
|
+
./plugins/cursor/install.sh # ~/.cursor/hooks.json + mcp.json
|
|
1408
|
+
# (add --scope project for ./.cursor/)
|
|
1393
1409
|
```
|
|
1394
1410
|
|
|
1395
1411
|
> **Claude Code only:** symlinking the plugin into `~/.claude/plugins/`
|
|
@@ -1744,7 +1760,7 @@ See `CHANGELOG.md` for the design rationale.
|
|
|
1744
1760
|
- [x] `.gitignore`-aware walker that skips minified bundles + generated junk
|
|
1745
1761
|
- [x] Resolved call / import edges (bind `CALLS` / `IMPORTS` to real nodes)
|
|
1746
1762
|
- [x] Lightweight rerank (entrypoint / generated boost, idle-episode filter)
|
|
1747
|
-
- [x] Harness plugins for OpenCode and Claude Code (
|
|
1763
|
+
- [x] Harness plugins for OpenCode and Claude Code (steering + auto-learn)
|
|
1748
1764
|
- [x] `code-memory reset` CLI + auto-purge on `ingest --full`
|
|
1749
1765
|
- [x] File-watcher daemon for live re-ingest (cross-platform via `watchdog`)
|
|
1750
1766
|
- [x] Team-shared snapshots (orphan branch, content-addressed, model-aware verify)
|
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
<#
|
|
2
|
+
.SYNOPSIS
|
|
3
|
+
code-memory zero-clone installer (Windows PowerShell).
|
|
4
|
+
|
|
5
|
+
.DESCRIPTION
|
|
6
|
+
No `git clone` required. Installs the `code-memory` CLI via `uv`, drops
|
|
7
|
+
infra files into $HOME\.code-memory\, waits for Docker + Ollama,
|
|
8
|
+
pulls the bge-m3 embedding model (and optionally gemma2:9b for claim
|
|
9
|
+
extraction), and wires up the Claude Code plugin + MCP server.
|
|
10
|
+
Optionally installs the OpenCode plugin from npm.
|
|
11
|
+
|
|
12
|
+
Interactive by default. Pass -Yes to accept defaults; pass any -No*
|
|
13
|
+
switch to skip a step; pass -NonInteractive to refuse all prompts.
|
|
14
|
+
|
|
15
|
+
One-liner (interactive):
|
|
16
|
+
irm https://raw.githubusercontent.com/fmflurry/code-memory/main/install.ps1 | iex
|
|
17
|
+
|
|
18
|
+
Contributors hacking on the repo should still `git clone` and run
|
|
19
|
+
`scripts/install.ps1` instead.
|
|
20
|
+
|
|
21
|
+
.PARAMETER Yes
|
|
22
|
+
Accept default for every prompt (Claude=Y, OpenCode=N, claims=N).
|
|
23
|
+
|
|
24
|
+
.PARAMETER NonInteractive
|
|
25
|
+
Refuse all prompts; use defaults (same as -Yes but without confirmation).
|
|
26
|
+
|
|
27
|
+
.PARAMETER NoDocker
|
|
28
|
+
Skip starting FalkorDB + Qdrant via docker compose.
|
|
29
|
+
|
|
30
|
+
.PARAMETER NoOllama
|
|
31
|
+
Skip pulling bge-m3.
|
|
32
|
+
|
|
33
|
+
.PARAMETER NoClaude
|
|
34
|
+
Skip Claude Code marketplace + plugin registration.
|
|
35
|
+
|
|
36
|
+
.PARAMETER NoOpencode
|
|
37
|
+
Skip OpenCode plugin install from npm.
|
|
38
|
+
|
|
39
|
+
.PARAMETER NoMcp
|
|
40
|
+
Skip MCP server registration with Claude Code.
|
|
41
|
+
|
|
42
|
+
.PARAMETER NoClaims
|
|
43
|
+
Skip pulling gemma2:9b for claim extraction.
|
|
44
|
+
|
|
45
|
+
.PARAMETER WithClaims
|
|
46
|
+
Force-pull gemma2:9b without prompting.
|
|
47
|
+
|
|
48
|
+
.EXAMPLE
|
|
49
|
+
irm https://raw.githubusercontent.com/fmflurry/code-memory/main/install.ps1 | iex
|
|
50
|
+
|
|
51
|
+
.EXAMPLE
|
|
52
|
+
# Download then run with flags:
|
|
53
|
+
iwr https://raw.githubusercontent.com/fmflurry/code-memory/main/install.ps1 -OutFile install.ps1
|
|
54
|
+
./install.ps1 -NoOpencode -NoOllama
|
|
55
|
+
#>
|
|
56
|
+
|
|
57
|
+
[CmdletBinding()]
|
|
58
|
+
param(
|
|
59
|
+
[switch]$Yes,
|
|
60
|
+
[switch]$NonInteractive,
|
|
61
|
+
[switch]$NoDocker,
|
|
62
|
+
[switch]$NoOllama,
|
|
63
|
+
[switch]$NoClaude,
|
|
64
|
+
[switch]$NoOpencode,
|
|
65
|
+
[switch]$NoMcp,
|
|
66
|
+
[switch]$NoClaims,
|
|
67
|
+
[switch]$WithClaims
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
$ErrorActionPreference = 'Stop'
|
|
71
|
+
|
|
72
|
+
$RepoUrl = if ($env:CODEMEMORY_REPO_URL) { $env:CODEMEMORY_REPO_URL } else { 'https://github.com/fmflurry/code-memory' }
|
|
73
|
+
$RawUrl = if ($env:CODEMEMORY_RAW_URL) { $env:CODEMEMORY_RAW_URL } else { 'https://raw.githubusercontent.com/fmflurry/code-memory/main' }
|
|
74
|
+
$HomeDir = if ($env:CODEMEMORY_HOME) { $env:CODEMEMORY_HOME } else { Join-Path $HOME '.code-memory' }
|
|
75
|
+
$NpmPkg = if ($env:CODEMEMORY_OPENCODE_PKG) { $env:CODEMEMORY_OPENCODE_PKG } else { 'code-memory-opencode' }
|
|
76
|
+
|
|
77
|
+
function Step($msg) { Write-Host "`n==> $msg" -ForegroundColor Cyan }
|
|
78
|
+
function Ok($msg) { Write-Host "[ok] $msg" -ForegroundColor Green }
|
|
79
|
+
function Warn($msg) { Write-Host "[warn] $msg" -ForegroundColor Yellow }
|
|
80
|
+
function Err($msg) { Write-Host "[err] $msg" -ForegroundColor Red }
|
|
81
|
+
function Dim($msg) { Write-Host " $msg" -ForegroundColor DarkGray }
|
|
82
|
+
function Test-Cmd($name) { return [bool](Get-Command $name -ErrorAction SilentlyContinue) }
|
|
83
|
+
|
|
84
|
+
function Test-Interactive() {
|
|
85
|
+
if ($NonInteractive) { return $false }
|
|
86
|
+
# Read-Host targets console host. When invoked via `irm | iex`, the
|
|
87
|
+
# console host is still attached, so prompts work even though stdin is
|
|
88
|
+
# the script body.
|
|
89
|
+
try {
|
|
90
|
+
return [Environment]::UserInteractive -and ($Host.Name -ne 'Default Host')
|
|
91
|
+
} catch { return $false }
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
# Returns $true for yes, $false for no.
|
|
95
|
+
function Ask-YesNo([string]$Prompt, [string]$Default = 'Y') {
|
|
96
|
+
$hint = if ($Default -match '^[Yy]') { '[Y/n]' } else { '[y/N]' }
|
|
97
|
+
$defaultYes = $Default -match '^[Yy]'
|
|
98
|
+
if ($Yes -or -not (Test-Interactive)) { return $defaultYes }
|
|
99
|
+
Write-Host "? $Prompt $hint " -ForegroundColor Yellow -NoNewline
|
|
100
|
+
$ans = Read-Host
|
|
101
|
+
if ([string]::IsNullOrWhiteSpace($ans)) { return $defaultYes }
|
|
102
|
+
return ($ans -match '^[Yy]')
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
# Waits until a CLI is on PATH. Returns $true if present, $false if user skipped.
|
|
106
|
+
function Wait-ForCmd([string]$Cmd, [string]$Label, [string]$Url) {
|
|
107
|
+
while (-not (Test-Cmd $Cmd)) {
|
|
108
|
+
Warn "$Label not found."
|
|
109
|
+
Dim "Install from: $Url"
|
|
110
|
+
if (-not (Test-Interactive)) {
|
|
111
|
+
Warn "non-interactive: skipping $Label"
|
|
112
|
+
return $false
|
|
113
|
+
}
|
|
114
|
+
Write-Host "? Press Enter once installed (or type 'skip' to skip): " -ForegroundColor Yellow -NoNewline
|
|
115
|
+
$ans = Read-Host
|
|
116
|
+
if ($ans -eq 'skip') { return $false }
|
|
117
|
+
# Refresh PATH from machine + user so newly installed tools show up
|
|
118
|
+
# without restarting the shell.
|
|
119
|
+
$env:Path = [System.Environment]::GetEnvironmentVariable('Path','Machine') + ';' + `
|
|
120
|
+
[System.Environment]::GetEnvironmentVariable('Path','User')
|
|
121
|
+
}
|
|
122
|
+
return $true
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
# ---------- 1. uv ----------
|
|
126
|
+
Step "Ensuring uv is installed"
|
|
127
|
+
if (Test-Cmd 'uv') {
|
|
128
|
+
Ok "uv $(uv --version 2>$null)"
|
|
129
|
+
} else {
|
|
130
|
+
# Run uv installer in a child powershell so its `exit` cannot tear down
|
|
131
|
+
# the parent session (especially when this script itself was launched via
|
|
132
|
+
# `irm | iex`).
|
|
133
|
+
$uvInstaller = Join-Path ([System.IO.Path]::GetTempPath()) ("uv-install-{0}.ps1" -f ([guid]::NewGuid()))
|
|
134
|
+
$prevEAP = $ErrorActionPreference
|
|
135
|
+
$ErrorActionPreference = 'Continue'
|
|
136
|
+
try {
|
|
137
|
+
Invoke-WebRequest -Uri 'https://astral.sh/uv/install.ps1' -OutFile $uvInstaller -UseBasicParsing
|
|
138
|
+
$psExe = (Get-Process -Id $PID).Path
|
|
139
|
+
if (-not $psExe) { $psExe = 'powershell.exe' }
|
|
140
|
+
& $psExe -NoProfile -ExecutionPolicy Bypass -File $uvInstaller
|
|
141
|
+
$uvExit = $LASTEXITCODE
|
|
142
|
+
if ($uvExit -ne 0) { throw "uv installer exited with code $uvExit" }
|
|
143
|
+
} catch {
|
|
144
|
+
Err "Failed to install uv: $($_.Exception.Message)"
|
|
145
|
+
Err "Install manually: winget install --id=astral-sh.uv -e then re-run."
|
|
146
|
+
exit 3
|
|
147
|
+
} finally {
|
|
148
|
+
Remove-Item $uvInstaller -ErrorAction SilentlyContinue
|
|
149
|
+
$ErrorActionPreference = $prevEAP
|
|
150
|
+
}
|
|
151
|
+
$env:Path = "$HOME\.local\bin;$HOME\.cargo\bin;$env:Path"
|
|
152
|
+
if (-not (Test-Cmd 'uv')) {
|
|
153
|
+
Err "uv installed but not on PATH; re-open shell and re-run."
|
|
154
|
+
exit 3
|
|
155
|
+
}
|
|
156
|
+
Ok "uv installed"
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
# ---------- 2. code-memory CLI ----------
|
|
160
|
+
Step "Installing code-memory CLI"
|
|
161
|
+
& uv tool install --force --from "git+$RepoUrl" flurryx-code-memory
|
|
162
|
+
if ($LASTEXITCODE -ne 0) { Err "uv tool install failed"; exit 1 }
|
|
163
|
+
$cliPath = (Get-Command code-memory -ErrorAction SilentlyContinue)
|
|
164
|
+
Ok "code-memory CLI: $($cliPath.Source)"
|
|
165
|
+
|
|
166
|
+
# ---------- 3. side files ----------
|
|
167
|
+
Step "Writing infra files to $HomeDir"
|
|
168
|
+
New-Item -ItemType Directory -Force -Path (Join-Path $HomeDir 'docker') | Out-Null
|
|
169
|
+
Invoke-WebRequest -Uri "$RawUrl/docker/docker-compose.yml" -OutFile (Join-Path $HomeDir 'docker/docker-compose.yml') -UseBasicParsing
|
|
170
|
+
Ok "wrote $HomeDir\docker\docker-compose.yml"
|
|
171
|
+
$envFile = Join-Path $HomeDir '.env'
|
|
172
|
+
if (-not (Test-Path $envFile)) {
|
|
173
|
+
Invoke-WebRequest -Uri "$RawUrl/.env.example" -OutFile $envFile -UseBasicParsing
|
|
174
|
+
Ok "wrote $envFile (from .env.example)"
|
|
175
|
+
} else {
|
|
176
|
+
Ok ".env already present (not overwritten)"
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
# ---------- 4. docker ----------
|
|
180
|
+
$doDocker = -not $NoDocker
|
|
181
|
+
if ($doDocker -and -not $Yes -and (Test-Interactive)) {
|
|
182
|
+
$doDocker = Ask-YesNo "Start FalkorDB + Qdrant via Docker?" "Y"
|
|
183
|
+
}
|
|
184
|
+
if ($doDocker) {
|
|
185
|
+
Step "Starting FalkorDB + Qdrant"
|
|
186
|
+
if (Wait-ForCmd 'docker' 'Docker Desktop' 'https://www.docker.com/products/docker-desktop') {
|
|
187
|
+
# ensure daemon up
|
|
188
|
+
& docker info *>$null
|
|
189
|
+
if ($LASTEXITCODE -ne 0) {
|
|
190
|
+
Warn "Docker CLI present but daemon not running. Start Docker Desktop."
|
|
191
|
+
if (Test-Interactive) {
|
|
192
|
+
Write-Host "? Press Enter once the daemon is up (or 'skip'): " -ForegroundColor Yellow -NoNewline
|
|
193
|
+
$ans = Read-Host
|
|
194
|
+
if ($ans -eq 'skip') { $doDocker = $false }
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
if ($doDocker) {
|
|
198
|
+
& docker compose -f (Join-Path $HomeDir 'docker/docker-compose.yml') --project-directory $HomeDir up -d
|
|
199
|
+
if ($LASTEXITCODE -ne 0) {
|
|
200
|
+
Warn "docker compose up failed"
|
|
201
|
+
} else {
|
|
202
|
+
Ok "containers up"
|
|
203
|
+
Dim "FalkorDB browser: http://localhost:3000"
|
|
204
|
+
Dim "Qdrant dashboard: http://localhost:6333/dashboard"
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
} else {
|
|
208
|
+
Warn "docker step skipped"
|
|
209
|
+
}
|
|
210
|
+
} else {
|
|
211
|
+
Warn "docker step skipped"
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
# ---------- 5. ollama ----------
|
|
215
|
+
$doOllama = -not $NoOllama
|
|
216
|
+
if ($doOllama -and -not $Yes -and (Test-Interactive)) {
|
|
217
|
+
$doOllama = Ask-YesNo "Pull embedding model via Ollama?" "Y"
|
|
218
|
+
}
|
|
219
|
+
if ($doOllama) {
|
|
220
|
+
Step "Embedding model (bge-m3)"
|
|
221
|
+
if (Wait-ForCmd 'ollama' 'Ollama' 'https://ollama.com/download/windows') {
|
|
222
|
+
& ollama list 2>$null | Out-Null
|
|
223
|
+
if ($LASTEXITCODE -ne 0) {
|
|
224
|
+
try { Start-Process -FilePath 'ollama' -ArgumentList 'serve' -WindowStyle Hidden -ErrorAction Stop } catch {}
|
|
225
|
+
for ($i = 0; $i -lt 30; $i++) {
|
|
226
|
+
Start-Sleep -Seconds 1
|
|
227
|
+
& ollama list 2>$null | Out-Null
|
|
228
|
+
if ($LASTEXITCODE -eq 0) { break }
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
$models = (& ollama list 2>$null) -join "`n"
|
|
232
|
+
if ($models -match '(?m)^bge-m3(\s|:)') {
|
|
233
|
+
Ok "bge-m3 already present"
|
|
234
|
+
} else {
|
|
235
|
+
& ollama pull bge-m3
|
|
236
|
+
if ($LASTEXITCODE -eq 0) { Ok "bge-m3 pulled" } else { Warn "ollama pull bge-m3 returned exit $LASTEXITCODE" }
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
# optional gemma2:9b for claim extraction
|
|
240
|
+
$doClaims = $false
|
|
241
|
+
if ($WithClaims) {
|
|
242
|
+
$doClaims = $true
|
|
243
|
+
} elseif (-not $NoClaims) {
|
|
244
|
+
$doClaims = Ask-YesNo "Also pull gemma2:9b for user-claim extraction (~5.4 GB)?" "N"
|
|
245
|
+
}
|
|
246
|
+
if ($doClaims) {
|
|
247
|
+
$models2 = (& ollama list 2>$null) -join "`n"
|
|
248
|
+
if ($models2 -match '(?m)^gemma2:9b\s') {
|
|
249
|
+
Ok "gemma2:9b already present"
|
|
250
|
+
} else {
|
|
251
|
+
& ollama pull gemma2:9b
|
|
252
|
+
if ($LASTEXITCODE -eq 0) { Ok "gemma2:9b pulled" } else { Warn "ollama pull gemma2:9b returned exit $LASTEXITCODE" }
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
} else {
|
|
256
|
+
Warn "ollama step skipped"
|
|
257
|
+
}
|
|
258
|
+
} else {
|
|
259
|
+
Warn "ollama step skipped"
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
# ---------- 6. Claude Code ----------
|
|
263
|
+
$doClaude = -not $NoClaude
|
|
264
|
+
if ($doClaude -and -not $Yes -and (Test-Interactive)) {
|
|
265
|
+
$doClaude = Ask-YesNo "Install Claude Code plugin + MCP?" "Y"
|
|
266
|
+
}
|
|
267
|
+
if ($doClaude) {
|
|
268
|
+
if (-not (Test-Cmd 'claude')) {
|
|
269
|
+
Step "Installing Claude Code CLI"
|
|
270
|
+
$claudeInstaller = Join-Path ([System.IO.Path]::GetTempPath()) ("claude-install-{0}.ps1" -f ([guid]::NewGuid()))
|
|
271
|
+
$prevEAP = $ErrorActionPreference
|
|
272
|
+
$ErrorActionPreference = 'Continue'
|
|
273
|
+
try {
|
|
274
|
+
Invoke-WebRequest -Uri 'https://claude.ai/install.ps1' -OutFile $claudeInstaller -UseBasicParsing
|
|
275
|
+
$psExe = (Get-Process -Id $PID).Path
|
|
276
|
+
if (-not $psExe) { $psExe = 'powershell.exe' }
|
|
277
|
+
& $psExe -NoProfile -ExecutionPolicy Bypass -File $claudeInstaller
|
|
278
|
+
if ($LASTEXITCODE -ne 0) { Warn "claude installer exited with code $LASTEXITCODE" }
|
|
279
|
+
} catch {
|
|
280
|
+
Warn "claude install failed: $($_.Exception.Message)"
|
|
281
|
+
} finally {
|
|
282
|
+
Remove-Item $claudeInstaller -ErrorAction SilentlyContinue
|
|
283
|
+
$ErrorActionPreference = $prevEAP
|
|
284
|
+
}
|
|
285
|
+
# Refresh PATH from machine + user so the freshly installed claude shim is visible.
|
|
286
|
+
$env:Path = [System.Environment]::GetEnvironmentVariable('Path','Machine') + ';' + `
|
|
287
|
+
[System.Environment]::GetEnvironmentVariable('Path','User') + ';' + `
|
|
288
|
+
"$HOME\.local\bin"
|
|
289
|
+
}
|
|
290
|
+
if (-not (Test-Cmd 'claude')) {
|
|
291
|
+
Warn "claude CLI still not found after install attempt — skipping Claude Code plugin"
|
|
292
|
+
Dim "Install manually: https://docs.anthropic.com/claude/docs/claude-code"
|
|
293
|
+
} else {
|
|
294
|
+
Step "Registering Claude Code plugin + MCP"
|
|
295
|
+
& claude plugin marketplace add $RepoUrl 2>$null
|
|
296
|
+
if ($LASTEXITCODE -ne 0) { Warn "marketplace add failed (may already be registered)" }
|
|
297
|
+
|
|
298
|
+
$pluginList = & claude plugin list 2>$null
|
|
299
|
+
if ($pluginList -match 'code-memory@code-memory') {
|
|
300
|
+
Ok "plugin already installed"
|
|
301
|
+
} else {
|
|
302
|
+
& claude plugin install code-memory@code-memory --scope user
|
|
303
|
+
if ($LASTEXITCODE -eq 0) { Ok "plugin installed" } else { Warn "plugin install failed" }
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
if (-not $NoMcp) {
|
|
307
|
+
$mcpList = & claude mcp list 2>$null
|
|
308
|
+
if ($mcpList -match '(?m)^\s*code-memory\s') {
|
|
309
|
+
Ok "MCP already registered"
|
|
310
|
+
} else {
|
|
311
|
+
& claude mcp add code-memory `
|
|
312
|
+
--scope user `
|
|
313
|
+
-e CODE_MEMORY_PROJECT=auto `
|
|
314
|
+
-- uvx --from "git+$RepoUrl" code-memory-mcp
|
|
315
|
+
if ($LASTEXITCODE -eq 0) { Ok "MCP registered (restart Claude Code to pick it up)" }
|
|
316
|
+
else { Warn "claude mcp add failed; see README §MCP server" }
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
} else {
|
|
321
|
+
Warn "Claude Code step skipped"
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
# ---------- 7. OpenCode ----------
|
|
325
|
+
$doOpencode = -not $NoOpencode -and ($Yes -or $false)
|
|
326
|
+
# OpenCode defaults to N — only prompt if not explicitly skipped.
|
|
327
|
+
if (-not $NoOpencode -and -not $Yes -and (Test-Interactive)) {
|
|
328
|
+
$doOpencode = Ask-YesNo "Install OpenCode plugin (npm global)?" "N"
|
|
329
|
+
} elseif ($Yes) {
|
|
330
|
+
$doOpencode = $false # -Yes accepts the default (N) for OpenCode
|
|
331
|
+
}
|
|
332
|
+
if ($doOpencode) {
|
|
333
|
+
Step "Installing OpenCode plugin"
|
|
334
|
+
if (-not (Test-Cmd 'npm')) {
|
|
335
|
+
Warn "npm not found — skipping. Install Node.js, then: npm i -g $NpmPkg ; code-memory-opencode-install"
|
|
336
|
+
} else {
|
|
337
|
+
& npm i -g $NpmPkg
|
|
338
|
+
if ($LASTEXITCODE -ne 0) {
|
|
339
|
+
Warn "npm install failed"
|
|
340
|
+
} elseif (Test-Cmd 'code-memory-opencode-install') {
|
|
341
|
+
& code-memory-opencode-install
|
|
342
|
+
} else {
|
|
343
|
+
Warn "$NpmPkg installed but code-memory-opencode-install not on PATH"
|
|
344
|
+
Warn "Add npm global bin to PATH (npm bin -g) and re-run: code-memory-opencode-install"
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
} else {
|
|
348
|
+
Warn "OpenCode step skipped"
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
# ---------- done ----------
|
|
352
|
+
Step "Done"
|
|
353
|
+
@"
|
|
354
|
+
|
|
355
|
+
Side files: $HomeDir\
|
|
356
|
+
CLI: $(if ($cliPath) { $cliPath.Source } else { 'code-memory (not on PATH)' })
|
|
357
|
+
|
|
358
|
+
Ingest a repo:
|
|
359
|
+
code-memory ingest C:\path\to\repo
|
|
360
|
+
|
|
361
|
+
Query:
|
|
362
|
+
code-memory retrieve "where is the auth middleware?"
|
|
363
|
+
|
|
364
|
+
Browse:
|
|
365
|
+
FalkorDB http://localhost:3000
|
|
366
|
+
Qdrant http://localhost:6333/dashboard
|
|
367
|
+
|
|
368
|
+
Edit defaults: $HomeDir\.env
|
|
369
|
+
"@ | Write-Host
|