superlocalmemory 3.6.22 → 3.7.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/CHANGELOG.md +52 -0
- package/README.md +275 -72
- package/bin/slm-npm +43 -89
- package/docs/pi-dev-integration.md +43 -0
- package/ide/configs/antigravity-mcp.json +2 -2
- package/ide/configs/chatgpt-desktop-mcp.json +1 -1
- package/ide/configs/claude-desktop-mcp.json +2 -2
- package/ide/configs/windsurf-mcp.json +2 -2
- package/ide/hooks/context-hook.js +6 -2
- package/ide/hooks/post-recall-hook.js +7 -3
- package/ide/hooks/tool-event-hook.sh +2 -1
- package/package.json +19 -10
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/_GENERATED.md +1 -1
- package/plugin/agents/slm-memory-advisor.md +1 -1
- package/plugin/requirements.txt +1 -1
- package/plugin/skills/slm-session/SKILL.md +1 -1
- package/plugin-src/rules/AGENTS.md +1 -1
- package/pyproject.toml +40 -8
- package/scripts/postinstall-interactive.js +17 -94
- package/scripts/postinstall.js +185 -258
- package/scripts/preuninstall.js +9 -50
- package/src/superlocalmemory/__init__.py +2 -2
- package/src/superlocalmemory/attribution/mathematical_dna.py +1 -1
- package/src/superlocalmemory/attribution/signer.py +34 -19
- package/src/superlocalmemory/attribution/watermark.py +1 -1
- package/src/superlocalmemory/cli/_lazy_init.py +3 -5
- package/src/superlocalmemory/cli/commands.py +490 -195
- package/src/superlocalmemory/cli/context_commands.py +5 -4
- package/src/superlocalmemory/cli/daemon.py +282 -187
- package/src/superlocalmemory/cli/db_migrate.py +3 -1
- package/src/superlocalmemory/cli/diagnostics_cmd.py +28 -0
- package/src/superlocalmemory/cli/evidence_cmd.py +103 -0
- package/src/superlocalmemory/cli/ingest_cmd.py +7 -3
- package/src/superlocalmemory/cli/main.py +128 -31
- package/src/superlocalmemory/cli/pending_store.py +54 -38
- package/src/superlocalmemory/cli/scale_engine_cmd.py +37 -0
- package/src/superlocalmemory/cli/service_installer.py +57 -52
- package/src/superlocalmemory/cli/setup_wizard.py +142 -88
- package/src/superlocalmemory/cli/version_banner.py +2 -1
- package/src/superlocalmemory/code_graph/config.py +3 -1
- package/src/superlocalmemory/core/backend_orchestrator.py +81 -21
- package/src/superlocalmemory/core/config.py +65 -20
- package/src/superlocalmemory/core/consolidation_engine.py +9 -7
- package/src/superlocalmemory/core/context_cache.py +56 -8
- package/src/superlocalmemory/core/derivation_lineage.py +246 -0
- package/src/superlocalmemory/core/embedding_worker.py +32 -20
- package/src/superlocalmemory/core/embeddings.py +54 -18
- package/src/superlocalmemory/core/engine.py +150 -104
- package/src/superlocalmemory/core/engine_ingestion.py +513 -0
- package/src/superlocalmemory/core/engine_wiring.py +2 -0
- package/src/superlocalmemory/core/evidence_bundle.py +526 -0
- package/src/superlocalmemory/core/fact_consolidator.py +5 -11
- package/src/superlocalmemory/core/graph_analyzer.py +2 -2
- package/src/superlocalmemory/core/health_monitor.py +4 -2
- package/src/superlocalmemory/core/ingestion_command.py +636 -0
- package/src/superlocalmemory/core/injection.py +69 -18
- package/src/superlocalmemory/core/lifecycle_state.py +153 -0
- package/src/superlocalmemory/core/maintenance.py +23 -22
- package/src/superlocalmemory/core/maintenance_scheduler.py +51 -35
- package/src/superlocalmemory/core/mutations.py +143 -0
- package/src/superlocalmemory/core/platform_utils.py +7 -4
- package/src/superlocalmemory/core/ram_lock.py +16 -5
- package/src/superlocalmemory/core/rate_limit.py +1 -1
- package/src/superlocalmemory/core/recall_pipeline.py +60 -101
- package/src/superlocalmemory/core/recall_worker.py +76 -59
- package/src/superlocalmemory/core/registry.py +1 -1
- package/src/superlocalmemory/core/scale_engine.py +293 -0
- package/src/superlocalmemory/core/score_contract.py +62 -0
- package/src/superlocalmemory/core/security_primitives.py +3 -1
- package/src/superlocalmemory/core/slm_disabled.py +3 -5
- package/src/superlocalmemory/core/store_pipeline.py +172 -40
- package/src/superlocalmemory/core/tier_manager.py +32 -20
- package/src/superlocalmemory/core/worker_pool.py +13 -4
- package/src/superlocalmemory/dynamics/activation_guided_quantization.py +1 -1
- package/src/superlocalmemory/dynamics/eap_scheduler.py +10 -3
- package/src/superlocalmemory/dynamics/ebbinghaus_langevin_coupling.py +1 -1
- package/src/superlocalmemory/dynamics/fisher_langevin_coupling.py +1 -1
- package/src/superlocalmemory/encoding/auto_linker.py +1 -1
- package/src/superlocalmemory/encoding/cognitive_consolidator.py +7 -16
- package/src/superlocalmemory/encoding/consolidator.py +22 -5
- package/src/superlocalmemory/encoding/fact_extractor.py +1 -1
- package/src/superlocalmemory/encoding/foresight.py +2 -0
- package/src/superlocalmemory/encoding/graph_builder.py +1 -1
- package/src/superlocalmemory/encoding/temporal_parser.py +2 -0
- package/src/superlocalmemory/evaluation/__init__.py +13 -0
- package/src/superlocalmemory/evaluation/calibration.py +308 -0
- package/src/superlocalmemory/evolution/skill_evolver.py +2 -1
- package/src/superlocalmemory/graph/cozo_backend.py +256 -23
- package/src/superlocalmemory/hooks/_outcome_common.py +21 -11
- package/src/superlocalmemory/hooks/antigravity_adapter.py +10 -31
- package/src/superlocalmemory/hooks/auto_invoker.py +25 -27
- package/src/superlocalmemory/hooks/auto_recall.py +31 -6
- package/src/superlocalmemory/hooks/auto_recall_hook.py +13 -33
- package/src/superlocalmemory/hooks/before_web_hook.py +9 -7
- package/src/superlocalmemory/hooks/claude_code_hooks.py +126 -39
- package/src/superlocalmemory/hooks/codex_assets.py +59 -0
- package/src/superlocalmemory/hooks/codex_hooks.py +186 -0
- package/src/superlocalmemory/hooks/context_payload.py +1 -1
- package/src/superlocalmemory/hooks/copilot_adapter.py +9 -24
- package/src/superlocalmemory/hooks/cursor_adapter.py +10 -32
- package/src/superlocalmemory/hooks/hook_daemon.py +4 -2
- package/src/superlocalmemory/hooks/hook_handlers.py +241 -55
- package/src/superlocalmemory/hooks/memory_protocol.py +5 -3
- package/src/superlocalmemory/hooks/post_tool_async_hook.py +4 -2
- package/src/superlocalmemory/hooks/session_registry.py +15 -8
- package/src/superlocalmemory/hooks/stop_outcome_hook.py +10 -6
- package/src/superlocalmemory/hooks/topic_shift_hook.py +42 -12
- package/src/superlocalmemory/hooks/user_prompt_hook.py +9 -14
- package/src/superlocalmemory/hooks/user_prompt_rehash_hook.py +19 -11
- package/src/superlocalmemory/infra/auth_middleware.py +38 -5
- package/src/superlocalmemory/infra/backup.py +7 -5
- package/src/superlocalmemory/infra/cloud_backup.py +18 -8
- package/src/superlocalmemory/infra/daemon_identity.py +248 -0
- package/src/superlocalmemory/infra/data_root.py +199 -0
- package/src/superlocalmemory/infra/event_bus.py +3 -1
- package/src/superlocalmemory/infra/local_diagnostics.py +327 -0
- package/src/superlocalmemory/infra/process_reaper.py +23 -0
- package/src/superlocalmemory/ingestion/adapter_manager.py +27 -9
- package/src/superlocalmemory/ingestion/base_adapter.py +25 -31
- package/src/superlocalmemory/ingestion/calendar_adapter.py +13 -4
- package/src/superlocalmemory/ingestion/credentials.py +14 -7
- package/src/superlocalmemory/ingestion/gmail_adapter.py +13 -4
- package/src/superlocalmemory/ingestion/transcript_adapter.py +7 -2
- package/src/superlocalmemory/learning/consolidation_quantization_worker.py +1 -1
- package/src/superlocalmemory/learning/ensemble.py +11 -0
- package/src/superlocalmemory/learning/entity_compiler.py +1 -1
- package/src/superlocalmemory/learning/feedback.py +1 -1
- package/src/superlocalmemory/learning/forgetting_scheduler.py +12 -7
- package/src/superlocalmemory/learning/quantization_scheduler.py +1 -1
- package/src/superlocalmemory/learning/ranker.py +4 -1
- package/src/superlocalmemory/learning/source_quality.py +1 -1
- package/src/superlocalmemory/learning/trigram_index.py +3 -2
- package/src/superlocalmemory/llm/backbone.py +13 -8
- package/src/superlocalmemory/math/ebbinghaus.py +1 -1
- package/src/superlocalmemory/math/fisher.py +1 -1
- package/src/superlocalmemory/math/fisher_quantized.py +1 -1
- package/src/superlocalmemory/math/hopfield.py +1 -1
- package/src/superlocalmemory/math/langevin.py +1 -1
- package/src/superlocalmemory/math/polar_quant.py +3 -4
- package/src/superlocalmemory/math/qjl.py +1 -1
- package/src/superlocalmemory/math/sheaf.py +1 -1
- package/src/superlocalmemory/math/turbo_quant.py +3 -2
- package/src/superlocalmemory/mcp/_daemon_proxy.py +12 -11
- package/src/superlocalmemory/mcp/_pool_adapter.py +27 -0
- package/src/superlocalmemory/mcp/http_transport.py +53 -0
- package/src/superlocalmemory/mcp/server.py +39 -13
- package/src/superlocalmemory/mcp/shared.py +69 -3
- package/src/superlocalmemory/mcp/tools_active.py +141 -31
- package/src/superlocalmemory/mcp/tools_core.py +128 -29
- package/src/superlocalmemory/mcp/tools_evolution.py +5 -7
- package/src/superlocalmemory/mcp/tools_learning.py +42 -2
- package/src/superlocalmemory/mcp/tools_mesh.py +7 -23
- package/src/superlocalmemory/mcp/tools_optimize.py +8 -1
- package/src/superlocalmemory/mcp/tools_v28.py +23 -2
- package/src/superlocalmemory/mcp/tools_v3.py +26 -1
- package/src/superlocalmemory/mcp/tools_v33.py +56 -17
- package/src/superlocalmemory/mesh/broker.py +2 -0
- package/src/superlocalmemory/mesh/remote_sync.py +50 -12
- package/src/superlocalmemory/optimize/cache/manager.py +77 -1
- package/src/superlocalmemory/optimize/cache/semantic.py +23 -3
- package/src/superlocalmemory/optimize/compress/ccr.py +4 -0
- package/src/superlocalmemory/optimize/compress/router.py +6 -1
- package/src/superlocalmemory/optimize/config/__init__.py +5 -0
- package/src/superlocalmemory/optimize/config/store.py +6 -4
- package/src/superlocalmemory/optimize/proxy/_helpers.py +15 -5
- package/src/superlocalmemory/optimize/proxy/capture.py +3 -2
- package/src/superlocalmemory/optimize/proxy/server.py +2 -2
- package/src/superlocalmemory/optimize/storage/db.py +14 -13
- package/src/superlocalmemory/retrieval/agentic.py +1 -1
- package/src/superlocalmemory/retrieval/ann_index.py +1 -1
- package/src/superlocalmemory/retrieval/bm25_channel.py +35 -11
- package/src/superlocalmemory/retrieval/bridge_discovery.py +73 -8
- package/src/superlocalmemory/retrieval/engine.py +169 -79
- package/src/superlocalmemory/retrieval/entity_channel.py +289 -67
- package/src/superlocalmemory/retrieval/forgetting_filter.py +1 -1
- package/src/superlocalmemory/retrieval/fusion.py +1 -1
- package/src/superlocalmemory/retrieval/hopfield_channel.py +118 -30
- package/src/superlocalmemory/retrieval/profile_channel.py +1 -1
- package/src/superlocalmemory/retrieval/quantization_aware_search.py +16 -10
- package/src/superlocalmemory/retrieval/reranker.py +56 -20
- package/src/superlocalmemory/retrieval/scope_policy.py +85 -0
- package/src/superlocalmemory/retrieval/semantic_channel.py +122 -14
- package/src/superlocalmemory/retrieval/spreading_activation.py +141 -25
- package/src/superlocalmemory/retrieval/strategy.py +1 -1
- package/src/superlocalmemory/retrieval/temporal_channel.py +30 -15
- package/src/superlocalmemory/retrieval/vector_store.py +1 -1
- package/src/superlocalmemory/server/api.py +10 -7
- package/src/superlocalmemory/server/bandit_loops.py +4 -2
- package/src/superlocalmemory/server/recall_serializer.py +24 -0
- package/src/superlocalmemory/server/route_mutations.py +84 -0
- package/src/superlocalmemory/server/routes/agents.py +8 -6
- package/src/superlocalmemory/server/routes/brain.py +14 -12
- package/src/superlocalmemory/server/routes/chat.py +29 -12
- package/src/superlocalmemory/server/routes/data_io.py +55 -24
- package/src/superlocalmemory/server/routes/helpers.py +29 -4
- package/src/superlocalmemory/server/routes/ingest.py +53 -36
- package/src/superlocalmemory/server/routes/memories.py +104 -43
- package/src/superlocalmemory/server/routes/mesh.py +31 -0
- package/src/superlocalmemory/server/routes/profiles.py +26 -4
- package/src/superlocalmemory/server/routes/tiers.py +43 -11
- package/src/superlocalmemory/server/routes/timeline.py +5 -1
- package/src/superlocalmemory/server/routes/v3_api.py +76 -21
- package/src/superlocalmemory/server/security_middleware.py +1 -1
- package/src/superlocalmemory/server/ui.py +6 -3
- package/src/superlocalmemory/server/unified_daemon.py +680 -293
- package/src/superlocalmemory/server/write_identity.py +147 -0
- package/src/superlocalmemory/storage/access_log.py +4 -3
- package/src/superlocalmemory/storage/database.py +118 -25
- package/src/superlocalmemory/storage/migration_runner.py +84 -1
- package/src/superlocalmemory/storage/migration_v33.py +1 -1
- package/src/superlocalmemory/storage/migrations/M002_model_state_history.py +6 -60
- package/src/superlocalmemory/storage/migrations/M018_ingestion_operations.py +120 -0
- package/src/superlocalmemory/storage/migrations/M019_derivation_lineage.py +54 -0
- package/src/superlocalmemory/storage/migrations/M020_model_state_integrity.py +52 -0
- package/src/superlocalmemory/storage/migrations/__init__.py +5 -0
- package/src/superlocalmemory/storage/models.py +16 -0
- package/src/superlocalmemory/storage/quantized_store.py +20 -3
- package/src/superlocalmemory/storage/v2_migrator.py +5 -3
- package/src/superlocalmemory/ui/favicon.svg +5 -0
- package/src/superlocalmemory/ui/index.html +1 -0
- package/src/superlocalmemory/ui/js/compliance.js +1 -1
- package/src/superlocalmemory/ui/js/core.js +49 -8
- package/src/superlocalmemory/ui/js/dashboard.js +23 -2
- package/src/superlocalmemory/ui/js/feedback.js +1 -1
- package/src/superlocalmemory/ui/js/graph-filters.js +1 -1
- package/src/superlocalmemory/ui/js/graph-ui.js +1 -1
- package/src/superlocalmemory/ui/js/lifecycle.js +1 -1
- package/src/superlocalmemory/ui/js/ng-mesh.js +15 -49
- package/src/superlocalmemory/ui/js/settings.js +4 -2
- package/src/superlocalmemory/vector/lancedb_backend.py +57 -9
- package/bin/slm +0 -59
- package/bin/slm.bat +0 -77
- package/bin/slm.cmd +0 -5
- package/ide/integrations/langchain/README.md +0 -106
- package/ide/integrations/langchain/langchain_superlocalmemory/__init__.py +0 -9
- package/ide/integrations/langchain/langchain_superlocalmemory/chat_message_history.py +0 -201
- package/ide/integrations/langchain/pyproject.toml +0 -38
- package/ide/integrations/langchain/tests/__init__.py +0 -3
- package/ide/integrations/langchain/tests/test_chat_message_history.py +0 -215
- package/ide/integrations/langchain/tests/test_security.py +0 -117
- package/ide/integrations/llamaindex/README.md +0 -81
- package/ide/integrations/llamaindex/llama_index/storage/chat_store/superlocalmemory/__init__.py +0 -9
- package/ide/integrations/llamaindex/llama_index/storage/chat_store/superlocalmemory/base.py +0 -316
- package/ide/integrations/llamaindex/pyproject.toml +0 -43
- package/ide/integrations/llamaindex/tests/__init__.py +0 -3
- package/ide/integrations/llamaindex/tests/test_chat_store.py +0 -294
- package/ide/integrations/llamaindex/tests/test_security.py +0 -241
- package/plugin-src/.mcp.json +0 -12
- package/plugin-src/agents/slm-memory-advisor.md +0 -44
- package/plugin-src/agents/slm-optimize-advisor.md +0 -38
- package/plugin-src/hooks/.gitkeep +0 -0
- package/plugin-src/hooks/hooks.json +0 -23
- package/plugin-src/manifest.json +0 -25
- package/plugin-src/requirements.txt +0 -1
- package/plugin-src/rules/CLAUDE.md.fragment +0 -44
- package/plugin-src/scripts/ensure-venv.bat +0 -122
- package/plugin-src/scripts/ensure-venv.sh +0 -105
- package/plugin-src/scripts/slm-launch +0 -15
- package/plugin-src/scripts/slm-launch.bat +0 -17
- package/plugin-src/settings.json +0 -16
- package/plugin-src/skills/slm-cache/SKILL.md +0 -140
- package/plugin-src/skills/slm-compress/SKILL.md +0 -143
- package/plugin-src/skills/slm-graph/SKILL.md +0 -300
- package/plugin-src/skills/slm-recall/SKILL.md +0 -204
- package/plugin-src/skills/slm-remember/SKILL.md +0 -194
- package/plugin-src/skills/slm-session/SKILL.md +0 -207
- package/plugin-src/skills/slm-status/SKILL.md +0 -149
- package/scripts/__tests__/build-plugin.test.mjs +0 -613
- package/scripts/_savings_math.py +0 -270
- package/scripts/build-dmg.sh +0 -417
- package/scripts/build-plugin.js +0 -742
- package/scripts/build-slm-hook.ps1 +0 -40
- package/scripts/build-slm-hook.sh +0 -45
- package/scripts/build_entry.py +0 -452
- package/scripts/ci/stage5b_gate.sh +0 -50
- package/scripts/dogfood_savings.py +0 -490
- package/scripts/generate-thumbnails.py +0 -218
- package/scripts/install-skills.ps1 +0 -4
- package/scripts/install-skills.sh +0 -5
- package/scripts/install.ps1 +0 -701
- package/scripts/install.sh +0 -1015
- package/scripts/postinstall_binary.js +0 -287
- package/scripts/prepack.js +0 -33
- package/scripts/release_manifest.py +0 -273
- package/scripts/slm-hook.spec +0 -56
- package/scripts/start-dashboard.ps1 +0 -52
- package/scripts/start-dashboard.sh +0 -41
- package/scripts/sync-wiki.ps1 +0 -127
- package/scripts/sync-wiki.sh +0 -82
- package/scripts/test-dmg.sh +0 -161
- package/scripts/test-npm-package.ps1 +0 -252
- package/scripts/test-npm-package.sh +0 -207
- package/scripts/verify-install.ps1 +0 -294
- package/scripts/verify-install.sh +0 -266
- package/scripts/verify-v27.ps1 +0 -301
- package/scripts/verify-v27.sh +0 -233
- package/src/superlocalmemory.egg-info/PKG-INFO +0 -513
- package/src/superlocalmemory.egg-info/SOURCES.txt +0 -529
- package/src/superlocalmemory.egg-info/dependency_links.txt +0 -1
- package/src/superlocalmemory.egg-info/entry_points.txt +0 -2
- package/src/superlocalmemory.egg-info/requires.txt +0 -71
- package/src/superlocalmemory.egg-info/top_level.txt +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* SuperLocalMemory
|
|
3
|
+
* SuperLocalMemory — Interactive Profile Configurator
|
|
4
4
|
*
|
|
5
|
-
*
|
|
5
|
+
* Invoked explicitly by `slm reconfigure`; it is not an npm lifecycle hook.
|
|
6
6
|
*
|
|
7
7
|
* Responsibilities:
|
|
8
8
|
* 1. Detect TTY; non-TTY (CI, piped stdin) → apply Balanced defaults
|
|
@@ -489,9 +489,9 @@ async function runInteractiveFlow(rl, recommendedProfile) {
|
|
|
489
489
|
// under 60 LOC per Stage-8 G2 scope.
|
|
490
490
|
function printLivingBrainDelta() {
|
|
491
491
|
console.log('');
|
|
492
|
-
console.log('
|
|
492
|
+
console.log('Current setup guarantees:');
|
|
493
493
|
console.log(' + session_init mandate hook — Claude calls ToolSearch→session_init first, every session');
|
|
494
|
-
console.log(' +
|
|
494
|
+
console.log(' + External IDE integrations are installed only after explicit consent in `slm setup`');
|
|
495
495
|
console.log(' + M017 migration — ccq_consolidated_blocks gets scope column (no more silent CCQ scope drop)');
|
|
496
496
|
console.log(' + GC-safe test flags baked into pyproject.toml + Makefile (no more macOS ARM SIGSEGV)');
|
|
497
497
|
console.log('What\'s unchanged:');
|
|
@@ -500,88 +500,6 @@ function printLivingBrainDelta() {
|
|
|
500
500
|
console.log(' * All CLI commands you already use');
|
|
501
501
|
}
|
|
502
502
|
|
|
503
|
-
// T1-B: Auto-install the Claude Code plugin after pip/npm install.
|
|
504
|
-
// Best-effort: never fails the installer, never blocks the main flow.
|
|
505
|
-
// Checks for `claude` CLI, then runs:
|
|
506
|
-
// 1. claude plugin marketplace add qualixar/superlocalmemory
|
|
507
|
-
// 2. claude plugin install superlocalmemory@qualixar
|
|
508
|
-
// 3. slm hooks install
|
|
509
|
-
async function tryInstallClaudePlugin() {
|
|
510
|
-
const { execFile } = require('child_process');
|
|
511
|
-
const { promisify } = require('util');
|
|
512
|
-
const execFileAsync = promisify(execFile);
|
|
513
|
-
|
|
514
|
-
// Find claude binary — try PATH first, then common install locations.
|
|
515
|
-
const claudeCandidates = ['claude'];
|
|
516
|
-
if (process.platform !== 'win32') {
|
|
517
|
-
claudeCandidates.push(
|
|
518
|
-
'/usr/local/bin/claude',
|
|
519
|
-
process.env.HOME + '/.npm-global/bin/claude',
|
|
520
|
-
process.env.HOME + '/.local/bin/claude',
|
|
521
|
-
);
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
let claudeBin = null;
|
|
525
|
-
for (const candidate of claudeCandidates) {
|
|
526
|
-
try {
|
|
527
|
-
await execFileAsync(candidate, ['--version'], { timeout: 5000 });
|
|
528
|
-
claudeBin = candidate;
|
|
529
|
-
break;
|
|
530
|
-
} catch (_e) { /* keep looking */ }
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
if (!claudeBin) {
|
|
534
|
-
// Claude Code not installed — print guidance and skip.
|
|
535
|
-
console.log('SLM: Claude Code CLI not found — skipping plugin auto-install.');
|
|
536
|
-
console.log('SLM: To install the plugin manually after installing Claude Code:');
|
|
537
|
-
console.log('SLM: claude plugin marketplace add qualixar/superlocalmemory');
|
|
538
|
-
console.log('SLM: claude plugin install superlocalmemory@qualixar');
|
|
539
|
-
console.log('SLM: slm hooks install');
|
|
540
|
-
return;
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
console.log('SLM: Claude Code found — installing SLM plugin...');
|
|
544
|
-
|
|
545
|
-
// Step 1: Add marketplace
|
|
546
|
-
try {
|
|
547
|
-
await execFileAsync(claudeBin,
|
|
548
|
-
['plugin', 'marketplace', 'add', 'qualixar/superlocalmemory'],
|
|
549
|
-
{ timeout: 30000 });
|
|
550
|
-
console.log('SLM: marketplace added (qualixar/superlocalmemory)');
|
|
551
|
-
} catch (e) {
|
|
552
|
-
// "already exists" or network error — not fatal
|
|
553
|
-
console.log('SLM: marketplace add note: ' + (e.stderr || e.message || String(e)).trim().split('\n')[0]);
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
// Step 2: Install plugin
|
|
557
|
-
try {
|
|
558
|
-
await execFileAsync(claudeBin,
|
|
559
|
-
['plugin', 'install', 'superlocalmemory@qualixar'],
|
|
560
|
-
{ timeout: 30000 });
|
|
561
|
-
console.log('SLM: plugin installed (superlocalmemory@qualixar)');
|
|
562
|
-
} catch (e) {
|
|
563
|
-
console.log('SLM: plugin install note: ' + (e.stderr || e.message || String(e)).trim().split('\n')[0]);
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
// Step 3: Install hooks (only if not already current — avoids needless writes)
|
|
567
|
-
// `slm hooks install` uses atomic tmp-then-rename and only touches the SLM
|
|
568
|
-
// section of settings.json; all other Claude Code settings are preserved.
|
|
569
|
-
try {
|
|
570
|
-
const statusResult = await execFileAsync('slm', ['hooks', 'status', '--json'],
|
|
571
|
-
{ timeout: 10000 }).catch(() => null);
|
|
572
|
-
const alreadyCurrent = statusResult &&
|
|
573
|
-
(() => { try { const s = JSON.parse(statusResult.stdout); return s.installed && !s.needs_upgrade; } catch { return false; } })();
|
|
574
|
-
if (!alreadyCurrent) {
|
|
575
|
-
await execFileAsync('slm', ['hooks', 'install'], { timeout: 15000 });
|
|
576
|
-
console.log('SLM: hooks installed into Claude Code settings');
|
|
577
|
-
} else {
|
|
578
|
-
console.log('SLM: hooks already current — skipped');
|
|
579
|
-
}
|
|
580
|
-
} catch (e) {
|
|
581
|
-
console.log('SLM: hooks install note: ' + (e.stderr || e.message || String(e)).trim().split('\n')[0]);
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
|
|
585
503
|
function printFirstRunChecklist(config) {
|
|
586
504
|
console.log('');
|
|
587
505
|
console.log('SuperLocalMemory is configured.');
|
|
@@ -596,6 +514,14 @@ function printFirstRunChecklist(config) {
|
|
|
596
514
|
console.log(' slm doctor — run health checks (DB, models, ports)');
|
|
597
515
|
console.log(' slm health --watch — live health ladder readout');
|
|
598
516
|
console.log(' slm dashboard — open the dashboard in your browser');
|
|
517
|
+
console.log('');
|
|
518
|
+
console.log('Available capability map (nothing external is enabled silently):');
|
|
519
|
+
console.log(' Memory + graph: dated episodic facts, entity graph, and local SQLite retrieval are ready.');
|
|
520
|
+
console.log(' Scale Engine: stage and verify CozoDB graph + LanceDB vector projections with `slm db scale prepare`.');
|
|
521
|
+
console.log(' Cache + compression: use the MCP optimize tools or `slm optimize on`; aggressive prose is opt-in.');
|
|
522
|
+
console.log(' Mesh: local coordination is available; configure a shared secret before exposing it to a LAN.');
|
|
523
|
+
console.log(' Adapters: Gmail, Calendar, and Transcript are OFF until `slm adapters enable <name>`.');
|
|
524
|
+
console.log(' IDE add-ons: install only SLM-owned integration with `slm hooks install --agent codex` or `--agent claude`.');
|
|
599
525
|
if (config.skill_evolution_enabled) {
|
|
600
526
|
// UX-L3: make the failure mode explicit to users who opted into
|
|
601
527
|
// evolution. If three LLM calls fail, the circuit breaker trips — and
|
|
@@ -621,8 +547,11 @@ async function main() {
|
|
|
621
547
|
return 2;
|
|
622
548
|
}
|
|
623
549
|
}
|
|
624
|
-
const
|
|
625
|
-
|
|
550
|
+
const configuredRoot = process.env.SLM_DATA_DIR
|
|
551
|
+
|| process.env.SL_MEMORY_PATH
|
|
552
|
+
|| process.env.SLM_HOME
|
|
553
|
+
|| path.join(os.homedir(), '.superlocalmemory');
|
|
554
|
+
const slmDir = args.home ? path.join(args.home, '.superlocalmemory') : configuredRoot;
|
|
626
555
|
const cfgPath = path.join(slmDir, 'config.toml');
|
|
627
556
|
const bakPath = path.join(slmDir, 'config.toml.bak');
|
|
628
557
|
|
|
@@ -773,12 +702,6 @@ async function main() {
|
|
|
773
702
|
// UX-G2: show the one-screen delta banner so upgraders see what shipped.
|
|
774
703
|
printLivingBrainDelta();
|
|
775
704
|
|
|
776
|
-
// T1-B: Auto-install Claude Code plugin + hooks. Best-effort, non-blocking.
|
|
777
|
-
// Only runs on npm install (not --dry-run), when claude CLI is present.
|
|
778
|
-
if (!args.dryRun) {
|
|
779
|
-
await tryInstallClaudePlugin();
|
|
780
|
-
}
|
|
781
|
-
|
|
782
705
|
printFirstRunChecklist(config);
|
|
783
706
|
return 0;
|
|
784
707
|
}
|
package/scripts/postinstall.js
CHANGED
|
@@ -1,293 +1,220 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* SuperLocalMemory V3 - NPM
|
|
3
|
+
* SuperLocalMemory V3 - safe NPM runtime installer.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
* Python
|
|
5
|
+
* NPM owns a private Python virtual environment inside its package directory.
|
|
6
|
+
* This script never installs into system Python and never creates or modifies
|
|
7
|
+
* SLM data, hooks, IDE configuration, daemons, or model caches.
|
|
7
8
|
*
|
|
8
9
|
* Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
|
|
9
|
-
* Licensed under
|
|
10
|
+
* Licensed under AGPL-3.0-or-later.
|
|
10
11
|
*/
|
|
11
12
|
|
|
13
|
+
'use strict';
|
|
14
|
+
|
|
12
15
|
const { spawnSync } = require('child_process');
|
|
16
|
+
const fs = require('fs');
|
|
13
17
|
const path = require('path');
|
|
14
18
|
const os = require('os');
|
|
15
|
-
const fs = require('fs');
|
|
16
19
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
console.log(' https://github.com/qualixar/superlocalmemory');
|
|
21
|
-
console.log('════════════════════════════════════════════════════════════\n');
|
|
20
|
+
const MIN_PYTHON = Object.freeze([3, 11]);
|
|
21
|
+
const MAX_PYTHON_EXCLUSIVE = Object.freeze([3, 15]);
|
|
22
|
+
const INSTALL_TIMEOUT_MS = 15 * 60 * 1000;
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
if (!
|
|
26
|
-
|
|
27
|
-
console.log('✓ Created data directory: ' + SLM_HOME);
|
|
28
|
-
} else {
|
|
29
|
-
console.log('✓ Data directory exists: ' + SLM_HOME);
|
|
24
|
+
function parsePythonVersion(output) {
|
|
25
|
+
const match = String(output || '').match(/Python\s+(\d+)\.(\d+)(?:\.(\d+))?/i);
|
|
26
|
+
if (!match) return null;
|
|
27
|
+
return [Number(match[1]), Number(match[2]), Number(match[3] || 0)];
|
|
30
28
|
}
|
|
31
29
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
try {
|
|
41
|
-
const parts = cmd.split(' ');
|
|
42
|
-
const r = spawnSync(parts[0], [...parts.slice(1), '--version'], {
|
|
43
|
-
stdio: 'pipe', timeout: 5000,
|
|
44
|
-
env: { ...process.env, PATH: '/opt/homebrew/bin:/usr/local/bin:/usr/bin:' + (process.env.PATH || '') },
|
|
45
|
-
});
|
|
46
|
-
if (r.status === 0 && (r.stdout || '').toString().includes('3.')) return parts;
|
|
47
|
-
} catch (e) { /* next */ }
|
|
48
|
-
}
|
|
49
|
-
return null;
|
|
30
|
+
function isSupportedPython(version) {
|
|
31
|
+
if (!version) return false;
|
|
32
|
+
const [major, minor] = version;
|
|
33
|
+
const atLeastMinimum = major > MIN_PYTHON[0]
|
|
34
|
+
|| (major === MIN_PYTHON[0] && minor >= MIN_PYTHON[1]);
|
|
35
|
+
const belowMaximum = major < MAX_PYTHON_EXCLUSIVE[0]
|
|
36
|
+
|| (major === MAX_PYTHON_EXCLUSIVE[0] && minor < MAX_PYTHON_EXCLUSIVE[1]);
|
|
37
|
+
return atLeastMinimum && belowMaximum;
|
|
50
38
|
}
|
|
51
39
|
|
|
52
|
-
|
|
53
|
-
if (
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
40
|
+
function pythonCandidates(platform = os.platform()) {
|
|
41
|
+
if (platform === 'win32') {
|
|
42
|
+
return [
|
|
43
|
+
['py', '-3.14'],
|
|
44
|
+
['py', '-3.13'],
|
|
45
|
+
['py', '-3.12'],
|
|
46
|
+
['py', '-3.11'],
|
|
47
|
+
['python3'],
|
|
48
|
+
['python'],
|
|
49
|
+
];
|
|
50
|
+
}
|
|
51
|
+
return [
|
|
52
|
+
['python3'],
|
|
53
|
+
['python'],
|
|
54
|
+
['/opt/homebrew/bin/python3'],
|
|
55
|
+
['/usr/local/bin/python3'],
|
|
56
|
+
['/usr/bin/python3'],
|
|
57
|
+
];
|
|
64
58
|
}
|
|
65
|
-
console.log('✓ Found Python: ' + pythonParts.join(' '));
|
|
66
|
-
|
|
67
|
-
// --- Step 3: Install ALL Python dependencies ---
|
|
68
|
-
console.log('\nInstalling Python dependencies (this may take 1-2 minutes)...\n');
|
|
69
59
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
'--user', ...packages,
|
|
86
|
-
], { stdio: 'pipe', timeout: 300000, env: { ...process.env, PATH: '/opt/homebrew/bin:/usr/local/bin:/usr/bin:' + (process.env.PATH || '') } });
|
|
87
|
-
if (result.status === 0) return true;
|
|
88
|
-
|
|
89
|
-
// Last resort: --break-system-packages
|
|
90
|
-
result = spawnSync(pythonParts[0], [
|
|
91
|
-
...pythonParts.slice(1), '-m', 'pip', 'install', '--quiet', '--disable-pip-version-check',
|
|
92
|
-
'--break-system-packages', ...packages,
|
|
93
|
-
], { stdio: 'pipe', timeout: 300000, env: { ...process.env, PATH: '/opt/homebrew/bin:/usr/local/bin:/usr/bin:' + (process.env.PATH || '') } });
|
|
94
|
-
return result.status === 0;
|
|
60
|
+
function findSupportedPython() {
|
|
61
|
+
for (const candidate of pythonCandidates()) {
|
|
62
|
+
try {
|
|
63
|
+
const result = spawnSync(candidate[0], [...candidate.slice(1), '--version'], {
|
|
64
|
+
stdio: 'pipe',
|
|
65
|
+
timeout: 5000,
|
|
66
|
+
env: process.env,
|
|
67
|
+
});
|
|
68
|
+
const output = `${(result.stdout || '').toString()} ${(result.stderr || '').toString()}`;
|
|
69
|
+
const version = parsePythonVersion(output);
|
|
70
|
+
if (result.status === 0 && isSupportedPython(version)) {
|
|
71
|
+
return { command: candidate[0], prefixArgs: candidate.slice(1), version };
|
|
72
|
+
}
|
|
73
|
+
} catch (_error) {
|
|
74
|
+
// Try the next interpreter without mutating PATH or the machine.
|
|
95
75
|
}
|
|
96
|
-
|
|
97
|
-
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
98
78
|
}
|
|
99
79
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
console.log(' (Single pip install — versions pinned in pyproject.toml)');
|
|
105
|
-
console.log(' This may take 1-3 minutes (downloads ~500MB of models on first use).');
|
|
106
|
-
console.log('');
|
|
107
|
-
console.log(' Includes: numpy, scipy, fastapi, sentence-transformers, onnxruntime,');
|
|
108
|
-
console.log(' torch, transformers, sqlite-vec, lightgbm, mcp, and more.');
|
|
109
|
-
|
|
110
|
-
// --- Step 3b: Install the superlocalmemory package itself ---
|
|
111
|
-
// This ensures `python -m superlocalmemory.cli.main` always resolves the
|
|
112
|
-
// correct version, even when invoked outside the Node.js wrapper (e.g.,
|
|
113
|
-
// via slm.bat on Windows or direct Python invocation).
|
|
114
|
-
console.log('\nInstalling superlocalmemory Python package...');
|
|
115
|
-
const pkgRoot = path.join(__dirname, '..');
|
|
116
|
-
const pipInstallPkg = spawnSync(pythonParts[0], [
|
|
117
|
-
...pythonParts.slice(1), '-m', 'pip', 'install', '--quiet', '--disable-pip-version-check',
|
|
118
|
-
pkgRoot,
|
|
119
|
-
], { stdio: 'pipe', timeout: 300000, env: { ...process.env, PATH: '/opt/homebrew/bin:/usr/local/bin:/usr/bin:' + (process.env.PATH || '') } });
|
|
120
|
-
|
|
121
|
-
if (pipInstallPkg.status === 0) {
|
|
122
|
-
console.log('✓ SuperLocalMemory Python package installed');
|
|
123
|
-
} else {
|
|
124
|
-
// Try with --user if PEP 668
|
|
125
|
-
const stderr = (pipInstallPkg.stderr || '').toString();
|
|
126
|
-
if (stderr.includes('externally-managed') || stderr.includes('PEP 668')) {
|
|
127
|
-
const retryResult = spawnSync(pythonParts[0], [
|
|
128
|
-
...pythonParts.slice(1), '-m', 'pip', 'install', '--quiet', '--disable-pip-version-check',
|
|
129
|
-
'--user', pkgRoot,
|
|
130
|
-
], { stdio: 'pipe', timeout: 300000, env: { ...process.env, PATH: '/opt/homebrew/bin:/usr/local/bin:/usr/bin:' + (process.env.PATH || '') } });
|
|
131
|
-
if (retryResult.status === 0) {
|
|
132
|
-
console.log('✓ SuperLocalMemory Python package installed (--user)');
|
|
133
|
-
} else {
|
|
134
|
-
// WP-07: --user also failed — try --break-system-packages last-resort,
|
|
135
|
-
// then surface the pipx hint (PEP 668 advisory).
|
|
136
|
-
const retryBsp = spawnSync(pythonParts[0], [
|
|
137
|
-
...pythonParts.slice(1), '-m', 'pip', 'install', '--quiet',
|
|
138
|
-
'--disable-pip-version-check', '--break-system-packages', pkgRoot,
|
|
139
|
-
], { stdio: 'pipe', timeout: 300000, env: { ...process.env, PATH: '/opt/homebrew/bin:/usr/local/bin:/usr/bin:' + (process.env.PATH || '') } });
|
|
140
|
-
if (retryBsp.status === 0) {
|
|
141
|
-
console.log('✓ SuperLocalMemory Python package installed (--break-system-packages)');
|
|
142
|
-
} else {
|
|
143
|
-
console.log('⚠ pip install failed (PEP 668 — externally managed Python).');
|
|
144
|
-
console.log(' The Node.js wrapper (slm-npm) sets PYTHONPATH automatically,');
|
|
145
|
-
console.log(' so the CLI will still work via npm.');
|
|
146
|
-
console.log('');
|
|
147
|
-
console.log(' To install into an isolated environment (recommended):');
|
|
148
|
-
console.log(' pipx install superlocalmemory');
|
|
149
|
-
console.log(' Last resort (may break OS packages):');
|
|
150
|
-
console.log(' pip install --break-system-packages superlocalmemory');
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
} else {
|
|
154
|
-
console.log('⚠ Could not pip install the package. The Node.js wrapper (slm-npm)');
|
|
155
|
-
console.log(' sets PYTHONPATH automatically, so CLI will still work.');
|
|
156
|
-
console.log('');
|
|
157
|
-
console.log(' If you see a PEP 668 error in future, install via:');
|
|
158
|
-
console.log(' pipx install superlocalmemory');
|
|
159
|
-
}
|
|
80
|
+
function runtimePythonPath(packageRoot, platform = os.platform()) {
|
|
81
|
+
return platform === 'win32'
|
|
82
|
+
? path.join(packageRoot, '.slm-venv', 'Scripts', 'python.exe')
|
|
83
|
+
: path.join(packageRoot, '.slm-venv', 'bin', 'python');
|
|
160
84
|
}
|
|
161
85
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
`import ${mod}; v=getattr(${mod},'__version__',''); print(v)`,
|
|
172
|
-
], { stdio: 'pipe', timeout: 10000, env: { ...process.env, PATH: '/opt/homebrew/bin:/usr/local/bin:/usr/bin:' + (process.env.PATH || '') } });
|
|
173
|
-
const actual = (check.stdout || '').toString().trim();
|
|
174
|
-
if (actual && actual !== expected) {
|
|
175
|
-
const pipName = mod.replace('_', '-');
|
|
176
|
-
console.log(`⚠ ${pipName} is ${actual}, expected ${expected}. Fixing...`);
|
|
177
|
-
pipInstall([`${pipName}==${expected}`], pipName);
|
|
178
|
-
console.log(`✓ ${pipName}==${expected} installed`);
|
|
179
|
-
} else if (actual === expected) {
|
|
180
|
-
console.log(`✓ ${mod}==${expected}`);
|
|
86
|
+
function validateRuntimeLocation(venvRoot) {
|
|
87
|
+
if (!fs.existsSync(venvRoot)) return { ok: true };
|
|
88
|
+
try {
|
|
89
|
+
const stat = fs.lstatSync(venvRoot);
|
|
90
|
+
if (stat.isSymbolicLink()) {
|
|
91
|
+
return { ok: false, error: `${venvRoot} is a symbolic link` };
|
|
92
|
+
}
|
|
93
|
+
if (!stat.isDirectory()) {
|
|
94
|
+
return { ok: false, error: `${venvRoot} is not a directory` };
|
|
181
95
|
}
|
|
96
|
+
return { ok: true };
|
|
97
|
+
} catch (error) {
|
|
98
|
+
return { ok: false, error: `cannot inspect ${venvRoot}: ${error.message}` };
|
|
99
|
+
}
|
|
182
100
|
}
|
|
183
101
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
console.log('');
|
|
192
|
-
console.log(' Found V2 data at: ' + V2_HOME);
|
|
193
|
-
console.log(' Your memories are safe and will NOT be deleted.');
|
|
194
|
-
console.log('');
|
|
195
|
-
console.log(' To migrate V2 data to V3, run:');
|
|
196
|
-
console.log(' slm migrate');
|
|
197
|
-
console.log('');
|
|
102
|
+
function printPythonGuidance() {
|
|
103
|
+
console.error('');
|
|
104
|
+
console.error('SuperLocalMemory requires Python 3.11, 3.12, 3.13, or 3.14.');
|
|
105
|
+
console.error('Install Python from https://www.python.org/downloads/ and rerun:');
|
|
106
|
+
console.error(' npm rebuild superlocalmemory');
|
|
107
|
+
console.error('The npm installer will create a private virtual environment;');
|
|
108
|
+
console.error('it will not install packages into your system Python.');
|
|
198
109
|
}
|
|
199
110
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
} else {
|
|
206
|
-
console.log('\nInstalling Claude Code hooks (auto-memory lifecycle)...');
|
|
207
|
-
const hookResult = spawnSync(pythonParts[0], [
|
|
208
|
-
...pythonParts.slice(1), '-m', 'superlocalmemory.cli.main', 'hooks', 'install',
|
|
209
|
-
], {
|
|
210
|
-
stdio: 'pipe', timeout: 15000,
|
|
211
|
-
env: {
|
|
212
|
-
...process.env,
|
|
213
|
-
PATH: '/opt/homebrew/bin:/usr/local/bin:/usr/bin:' + (process.env.PATH || ''),
|
|
214
|
-
PYTHONPATH: path.join(__dirname, '..', 'src') + ':' + (process.env.PYTHONPATH || ''),
|
|
215
|
-
},
|
|
216
|
-
});
|
|
111
|
+
function failureDetail(result) {
|
|
112
|
+
if (result && result.error) return result.error.message || String(result.error);
|
|
113
|
+
if (result && Number.isInteger(result.status)) return `exit code ${result.status}`;
|
|
114
|
+
return 'process did not complete';
|
|
115
|
+
}
|
|
217
116
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
117
|
+
function main(argv = process.argv.slice(2)) {
|
|
118
|
+
if (argv.includes('--help') || argv.includes('-h')) {
|
|
119
|
+
console.log('Usage: node scripts/postinstall.js');
|
|
120
|
+
console.log('Creates or repairs the package-owned .slm-venv runtime.');
|
|
121
|
+
console.log('This command never configures SLM or writes durable memory.');
|
|
122
|
+
return 0;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const packageRoot = path.resolve(__dirname, '..');
|
|
126
|
+
const venvRoot = path.join(packageRoot, '.slm-venv');
|
|
127
|
+
const packageVersion = require(path.join(packageRoot, 'package.json')).version;
|
|
128
|
+
const python = findSupportedPython();
|
|
129
|
+
|
|
130
|
+
console.log('');
|
|
131
|
+
console.log('SuperLocalMemory: creating an isolated npm-owned Python runtime.');
|
|
132
|
+
|
|
133
|
+
if (!python) {
|
|
134
|
+
printPythonGuidance();
|
|
135
|
+
return 1;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const locationCheck = validateRuntimeLocation(venvRoot);
|
|
139
|
+
if (!locationCheck.ok) {
|
|
140
|
+
console.error(`SuperLocalMemory: refusing unsafe runtime location: ${locationCheck.error}.`);
|
|
141
|
+
console.error('Move that path aside manually, verify it contains no needed files, then run:');
|
|
142
|
+
console.error(' npm rebuild superlocalmemory');
|
|
143
|
+
return 1;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
console.log(` Python ${python.version.join('.')} (${[python.command, ...python.prefixArgs].join(' ')})`);
|
|
147
|
+
|
|
148
|
+
const createVenv = spawnSync(
|
|
149
|
+
python.command,
|
|
150
|
+
[...python.prefixArgs, '-m', 'venv', venvRoot],
|
|
151
|
+
{ stdio: 'inherit', timeout: 120000, env: process.env },
|
|
152
|
+
);
|
|
153
|
+
if (createVenv.status !== 0) {
|
|
154
|
+
console.error(`SuperLocalMemory: could not create ${venvRoot} (${failureDetail(createVenv)}).`);
|
|
155
|
+
if (os.platform() === 'linux') {
|
|
156
|
+
console.error('Install your distribution\'s Python venv package (for example python3-venv), then run:');
|
|
221
157
|
} else {
|
|
222
|
-
|
|
223
|
-
// Non-fatal — don't block npm install
|
|
158
|
+
console.error('Repair the selected Python installation so the stdlib venv module is available, then run:');
|
|
224
159
|
}
|
|
160
|
+
console.error(' npm rebuild superlocalmemory');
|
|
161
|
+
return 1;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const runtimePython = runtimePythonPath(packageRoot);
|
|
165
|
+
const installPackage = spawnSync(
|
|
166
|
+
runtimePython,
|
|
167
|
+
[
|
|
168
|
+
'-m', 'pip', 'install',
|
|
169
|
+
'--disable-pip-version-check',
|
|
170
|
+
'--no-input',
|
|
171
|
+
'--upgrade',
|
|
172
|
+
packageRoot,
|
|
173
|
+
],
|
|
174
|
+
{ stdio: 'inherit', timeout: INSTALL_TIMEOUT_MS, env: process.env },
|
|
175
|
+
);
|
|
176
|
+
if (installPackage.status !== 0) {
|
|
177
|
+
console.error(`SuperLocalMemory: private-runtime installation failed (${failureDetail(installPackage)}).`);
|
|
178
|
+
console.error('Check network access, available disk space, and Python build prerequisites, then run:');
|
|
179
|
+
console.error(' npm rebuild superlocalmemory');
|
|
180
|
+
console.error('No system Python packages or SLM durable data were modified.');
|
|
181
|
+
return 1;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const verify = spawnSync(
|
|
185
|
+
runtimePython,
|
|
186
|
+
[
|
|
187
|
+
'-c',
|
|
188
|
+
"import importlib.metadata as m; print(m.version('superlocalmemory'))",
|
|
189
|
+
],
|
|
190
|
+
{ stdio: 'pipe', timeout: 15000, env: process.env },
|
|
191
|
+
);
|
|
192
|
+
const installedVersion = (verify.stdout || '').toString().trim();
|
|
193
|
+
if (verify.status !== 0 || installedVersion !== packageVersion) {
|
|
194
|
+
console.error(
|
|
195
|
+
`SuperLocalMemory: runtime identity check failed (npm=${packageVersion}, python=${installedVersion || 'unavailable'}).`,
|
|
196
|
+
);
|
|
197
|
+
console.error('Run `npm rebuild superlocalmemory` to repair the package-owned runtime.');
|
|
198
|
+
return 1;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
console.log(`SuperLocalMemory ${packageVersion}: isolated runtime verified.`);
|
|
202
|
+
console.log('No memory database, IDE hooks, daemon, configuration, or models were changed.');
|
|
203
|
+
console.log('Run `slm setup` explicitly when you are ready to configure SLM.');
|
|
204
|
+
console.log('');
|
|
205
|
+
return 0;
|
|
225
206
|
}
|
|
226
207
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
// If TTY is available (interactive terminal), runs the full wizard.
|
|
230
|
-
// If not (CI, piped), uses defaults (Mode A, skip model download).
|
|
231
|
-
console.log('\n════════════════════════════════════════════════════════════');
|
|
232
|
-
console.log(' Running setup wizard (model download + verification)...');
|
|
233
|
-
console.log('════════════════════════════════════════════════════════════\n');
|
|
234
|
-
|
|
235
|
-
const isTTY = process.stdin.isTTY && process.stdout.isTTY;
|
|
236
|
-
const setupArgs = isTTY ? ['setup'] : ['setup'];
|
|
237
|
-
const setupEnv = {
|
|
238
|
-
...process.env,
|
|
239
|
-
PATH: '/opt/homebrew/bin:/usr/local/bin:/usr/bin:' + (process.env.PATH || ''),
|
|
240
|
-
PYTHONPATH: path.join(__dirname, '..', 'src') + ':' + (process.env.PYTHONPATH || ''),
|
|
241
|
-
CUDA_VISIBLE_DEVICES: '',
|
|
242
|
-
TOKENIZERS_PARALLELISM: 'false',
|
|
243
|
-
TORCH_DEVICE: 'cpu',
|
|
244
|
-
};
|
|
245
|
-
|
|
246
|
-
// Non-interactive: set env flag so wizard uses defaults
|
|
247
|
-
if (!isTTY) {
|
|
248
|
-
setupEnv.SLM_NON_INTERACTIVE = '1';
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
const setupResult = spawnSync(pythonParts[0], [
|
|
252
|
-
...pythonParts.slice(1), '-m', 'superlocalmemory.cli.main', ...setupArgs,
|
|
253
|
-
], {
|
|
254
|
-
stdio: 'inherit', // Show all output including download progress
|
|
255
|
-
timeout: 900000, // 15 min (model downloads can be slow)
|
|
256
|
-
env: setupEnv,
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
if (setupResult.status === 0) {
|
|
260
|
-
console.log('✓ Setup wizard completed successfully');
|
|
261
|
-
} else {
|
|
262
|
-
console.log('⚠ Setup wizard had issues (run: slm setup)');
|
|
263
|
-
console.log(' SuperLocalMemory will still work — models download on first use.');
|
|
208
|
+
if (require.main === module) {
|
|
209
|
+
process.exit(main());
|
|
264
210
|
}
|
|
265
211
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
console.log(' slm adapters enable gmail # Enable Gmail ingestion');
|
|
276
|
-
console.log(' slm setup # Re-run 9-step wizard');
|
|
277
|
-
console.log('');
|
|
278
|
-
console.log(' New in v3.4.3:');
|
|
279
|
-
console.log(' • Unified daemon (one process, 24/7, < 700MB)');
|
|
280
|
-
console.log(' • SLM Mesh (agent-to-agent P2P built in)');
|
|
281
|
-
console.log(' • Entity compilation (auto knowledge summaries)');
|
|
282
|
-
console.log(' • Ingestion adapters (Gmail, Calendar, Transcripts)');
|
|
283
|
-
console.log('');
|
|
284
|
-
console.log(' Docs: https://github.com/qualixar/superlocalmemory');
|
|
285
|
-
console.log('════════════════════════════════════════════════════════════\n');
|
|
286
|
-
|
|
287
|
-
console.log('────────────────────────────────────────────────────────────');
|
|
288
|
-
console.log(' ⭐ Help us grow!');
|
|
289
|
-
console.log(' If this saves you time, please star the repo:');
|
|
290
|
-
console.log(' https://github.com/qualixar/superlocalmemory');
|
|
291
|
-
console.log(' Part of the Qualixar AI Agent Reliability Platform:');
|
|
292
|
-
console.log(' https://qualixar.com (7 OSS products, 19K+ monthly downloads)');
|
|
293
|
-
console.log('────────────────────────────────────────────────────────────\n');
|
|
212
|
+
module.exports = {
|
|
213
|
+
findSupportedPython,
|
|
214
|
+
isSupportedPython,
|
|
215
|
+
main,
|
|
216
|
+
parsePythonVersion,
|
|
217
|
+
pythonCandidates,
|
|
218
|
+
runtimePythonPath,
|
|
219
|
+
validateRuntimeLocation,
|
|
220
|
+
};
|