superlocalmemory 3.7.7 → 3.8.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/.claude-plugin/marketplace.json +1 -1
- package/ATTRIBUTION.md +1 -3
- package/CHANGELOG.md +85 -0
- package/README.md +199 -29
- package/package.json +4 -2
- package/plugin/.claude-plugin/plugin.json +2 -2
- package/plugin/CLAUDE.md +8 -8
- package/plugin/agents/slm-governance-advisor.md +80 -0
- package/plugin/agents/slm-loop-runner.md +71 -0
- package/plugin/agents/slm-memory-advisor.md +10 -5
- package/plugin/agents/slm-optimize-advisor.md +9 -3
- package/plugin/commands/slm-loop.md +31 -0
- package/plugin/hooks/hooks.json +79 -0
- package/plugin/requirements.txt +1 -1
- package/plugin/scripts/slm-launch +46 -7
- package/plugin/settings.json +9 -0
- package/plugin/skills/slm-cache/SKILL.md +9 -1
- package/plugin/skills/slm-compress/SKILL.md +8 -1
- package/plugin/skills/slm-governance/SKILL.md +248 -0
- package/plugin/skills/slm-graph/SKILL.md +17 -3
- package/plugin/skills/slm-loop/SKILL.md +99 -0
- package/plugin/skills/slm-mesh/SKILL.md +282 -0
- package/plugin/skills/slm-profile/SKILL.md +148 -0
- package/plugin/skills/slm-recall/SKILL.md +46 -10
- package/plugin/skills/slm-remember/SKILL.md +48 -1
- package/plugin/skills/slm-scope/SKILL.md +176 -0
- package/plugin/skills/slm-session/SKILL.md +24 -1
- package/plugin/skills/slm-status/SKILL.md +18 -1
- package/plugin-src/agents/slm-governance-advisor.md +80 -0
- package/plugin-src/agents/slm-loop-runner.md +71 -0
- package/plugin-src/agents/slm-memory-advisor.md +10 -5
- package/plugin-src/agents/slm-optimize-advisor.md +9 -3
- package/plugin-src/commands/slm-loop.md +31 -0
- package/plugin-src/hooks/hooks.json +79 -0
- package/plugin-src/manifest.json +7 -2
- package/plugin-src/requirements.txt +1 -1
- package/plugin-src/rules/AGENTS.md +57 -18
- package/plugin-src/rules/CLAUDE.md.fragment +8 -8
- package/plugin-src/scripts/slm-launch +46 -7
- package/plugin-src/settings.json +9 -0
- package/plugin-src/skills/slm-cache/SKILL.md +9 -1
- package/plugin-src/skills/slm-compress/SKILL.md +8 -1
- package/plugin-src/skills/slm-governance/SKILL.md +248 -0
- package/plugin-src/skills/slm-graph/SKILL.md +17 -3
- package/plugin-src/skills/slm-loop/SKILL.md +99 -0
- package/plugin-src/skills/slm-mesh/SKILL.md +282 -0
- package/plugin-src/skills/slm-profile/SKILL.md +148 -0
- package/plugin-src/skills/slm-recall/SKILL.md +46 -10
- package/plugin-src/skills/slm-remember/SKILL.md +48 -1
- package/plugin-src/skills/slm-scope/SKILL.md +176 -0
- package/plugin-src/skills/slm-session/SKILL.md +24 -1
- package/plugin-src/skills/slm-status/SKILL.md +18 -1
- package/pyproject.toml +1 -2
- package/scripts/postinstall/validation.js +2 -0
- package/scripts/postinstall-interactive.js +74 -2
- package/src/superlocalmemory/__init__.py +1 -1
- package/src/superlocalmemory/access/__init__.py +3 -0
- package/src/superlocalmemory/access/rbac.py +477 -0
- package/src/superlocalmemory/cli/commands.py +96 -12
- package/src/superlocalmemory/cli/compress_cmd.py +17 -7
- package/src/superlocalmemory/cli/loop_cmd.py +192 -0
- package/src/superlocalmemory/cli/main.py +39 -4
- package/src/superlocalmemory/cli/mesh_cmd.py +38 -0
- package/src/superlocalmemory/cli/optimize_cmd.py +3 -0
- package/src/superlocalmemory/cli/pending_store.py +49 -13
- package/src/superlocalmemory/cli/proxy_cmd.py +4 -0
- package/src/superlocalmemory/cli/scale_engine_cmd.py +6 -0
- package/src/superlocalmemory/cli/setup_wizard.py +22 -13
- package/src/superlocalmemory/compliance/audit.py +6 -0
- package/src/superlocalmemory/compliance/gdpr.py +128 -138
- package/src/superlocalmemory/compliance/retention.py +176 -45
- package/src/superlocalmemory/core/backend_orchestrator.py +5 -43
- package/src/superlocalmemory/core/community_summary.py +267 -0
- package/src/superlocalmemory/core/config.py +216 -3
- package/src/superlocalmemory/core/consolidation_engine.py +95 -22
- package/src/superlocalmemory/core/context_cache.py +61 -18
- package/src/superlocalmemory/core/embedding_worker.py +17 -2
- package/src/superlocalmemory/core/embeddings.py +12 -1
- package/src/superlocalmemory/core/engine.py +17 -1
- package/src/superlocalmemory/core/engine_ingestion.py +29 -0
- package/src/superlocalmemory/core/engine_wiring.py +13 -0
- package/src/superlocalmemory/core/entity_community.py +178 -0
- package/src/superlocalmemory/core/graph_analyzer.py +39 -2
- package/src/superlocalmemory/core/graph_pruner.py +13 -8
- package/src/superlocalmemory/core/key_expander.py +138 -0
- package/src/superlocalmemory/core/maintenance.py +23 -0
- package/src/superlocalmemory/core/modes.py +1 -1
- package/src/superlocalmemory/core/mutations.py +2 -2
- package/src/superlocalmemory/core/pii.py +105 -0
- package/src/superlocalmemory/core/progressive_abstraction.py +208 -0
- package/src/superlocalmemory/core/recall_pipeline.py +2 -0
- package/src/superlocalmemory/core/recall_worker.py +20 -6
- package/src/superlocalmemory/core/scale_engine.py +60 -1
- package/src/superlocalmemory/core/security_primitives.py +40 -2
- package/src/superlocalmemory/core/store_pipeline.py +35 -11
- package/src/superlocalmemory/core/worker_pool.py +21 -6
- package/src/superlocalmemory/encoding/entity_reflexion.py +200 -0
- package/src/superlocalmemory/encoding/entity_resolver.py +34 -24
- package/src/superlocalmemory/encoding/fact_extractor.py +26 -1
- package/src/superlocalmemory/encoding/temporal_validator.py +64 -1
- package/src/superlocalmemory/evolution/evolution_store.py +122 -45
- package/src/superlocalmemory/evolution/llm_dispatch.py +12 -1
- package/src/superlocalmemory/evolution/model_selection.py +160 -0
- package/src/superlocalmemory/evolution/mutation_generator.py +16 -0
- package/src/superlocalmemory/evolution/skill_evolver.py +127 -42
- package/src/superlocalmemory/evolution/triggers.py +22 -13
- package/src/superlocalmemory/graph/cozo_backend.py +43 -20
- package/src/superlocalmemory/hooks/adapter_base.py +5 -1
- package/src/superlocalmemory/hooks/auto_recall.py +13 -1
- package/src/superlocalmemory/hooks/claude_code_hooks.py +11 -0
- package/src/superlocalmemory/hooks/codex_assets.py +64 -5
- package/src/superlocalmemory/hooks/hook_daemon.py +20 -3
- package/src/superlocalmemory/hooks/memory_protocol.py +54 -0
- package/src/superlocalmemory/hooks/portable_kit.py +114 -1
- package/src/superlocalmemory/infra/auth_middleware.py +28 -0
- package/src/superlocalmemory/infra/backup.py +12 -1
- package/src/superlocalmemory/infra/daemon_identity.py +40 -4
- package/src/superlocalmemory/infra/data_root.py +43 -4
- package/src/superlocalmemory/infra/event_bus.py +107 -24
- package/src/superlocalmemory/infra/rate_limiter.py +93 -0
- package/src/superlocalmemory/ingestion/adapter_manager.py +4 -1
- package/src/superlocalmemory/ingestion/credentials.py +1 -1
- package/src/superlocalmemory/learning/cross_project.py +28 -19
- package/src/superlocalmemory/learning/reward_proxy.py +42 -9
- package/src/superlocalmemory/loops/__init__.py +56 -0
- package/src/superlocalmemory/loops/budget.py +58 -0
- package/src/superlocalmemory/loops/engine.py +164 -0
- package/src/superlocalmemory/loops/ledger.py +243 -0
- package/src/superlocalmemory/loops/models.py +152 -0
- package/src/superlocalmemory/loops/rules.py +52 -0
- package/src/superlocalmemory/mcp/_daemon_proxy.py +3 -0
- package/src/superlocalmemory/mcp/_pool_adapter.py +2 -0
- package/src/superlocalmemory/mcp/profiles.py +103 -0
- package/src/superlocalmemory/mcp/server.py +21 -49
- package/src/superlocalmemory/mcp/tools_active.py +4 -7
- package/src/superlocalmemory/mcp/tools_code_graph.py +51 -5
- package/src/superlocalmemory/mcp/tools_core.py +50 -5
- package/src/superlocalmemory/mcp/tools_evolution.py +6 -3
- package/src/superlocalmemory/mcp/tools_loops.py +300 -0
- package/src/superlocalmemory/mcp/tools_mesh.py +140 -4
- package/src/superlocalmemory/mcp/tools_optimize.py +15 -8
- package/src/superlocalmemory/mesh/broker.py +237 -129
- package/src/superlocalmemory/mesh/remote_sync.py +50 -8
- package/src/superlocalmemory/optimize/NOTICE +1 -6
- package/src/superlocalmemory/optimize/adapters/anthropic_adapter.py +1 -4
- package/src/superlocalmemory/optimize/adapters/openai_adapter.py +1 -4
- package/src/superlocalmemory/optimize/cache/semantic.py +27 -19
- package/src/superlocalmemory/optimize/compress/align.py +32 -26
- package/src/superlocalmemory/optimize/compress/ccr.py +14 -71
- package/src/superlocalmemory/optimize/compress/router.py +105 -22
- package/src/superlocalmemory/optimize/config/defaults.py +1 -1
- package/src/superlocalmemory/optimize/config/schema.py +87 -4
- package/src/superlocalmemory/optimize/metrics/counters.py +13 -4
- package/src/superlocalmemory/optimize/metrics/estimator.py +0 -3
- package/src/superlocalmemory/optimize/proxy/_helpers.py +31 -4
- package/src/superlocalmemory/optimize/storage/db.py +38 -9
- package/src/superlocalmemory/optimize/storage/schema.py +10 -0
- package/src/superlocalmemory/parameterization/pattern_extractor.py +6 -3
- package/src/superlocalmemory/retrieval/agentic.py +1 -1
- package/src/superlocalmemory/retrieval/bm25_channel.py +68 -10
- package/src/superlocalmemory/retrieval/engine.py +168 -26
- package/src/superlocalmemory/retrieval/entity_channel.py +7 -5
- package/src/superlocalmemory/retrieval/hopfield_channel.py +9 -2
- package/src/superlocalmemory/retrieval/semantic_channel.py +114 -21
- package/src/superlocalmemory/retrieval/spreading_activation.py +11 -2
- package/src/superlocalmemory/retrieval/temporal_channel.py +48 -9
- package/src/superlocalmemory/retrieval/temporal_frame.py +102 -0
- package/src/superlocalmemory/retrieval/temporal_validity_filter.py +135 -0
- package/src/superlocalmemory/retrieval/time_window.py +181 -0
- package/src/superlocalmemory/server/api.py +21 -4
- package/src/superlocalmemory/server/profile_runtime.py +125 -8
- package/src/superlocalmemory/server/rbac_enforce.py +142 -0
- package/src/superlocalmemory/server/recall_health.py +24 -3
- package/src/superlocalmemory/server/recall_serializer.py +19 -1
- package/src/superlocalmemory/server/routes/abstraction.py +115 -0
- package/src/superlocalmemory/server/routes/agents.py +128 -38
- package/src/superlocalmemory/server/routes/backup.py +34 -10
- package/src/superlocalmemory/server/routes/behavioral.py +13 -12
- package/src/superlocalmemory/server/routes/brain.py +21 -5
- package/src/superlocalmemory/server/routes/chat.py +72 -16
- package/src/superlocalmemory/server/routes/compliance.py +171 -21
- package/src/superlocalmemory/server/routes/config_api.py +436 -0
- package/src/superlocalmemory/server/routes/data_io.py +30 -8
- package/src/superlocalmemory/server/routes/entity.py +9 -4
- package/src/superlocalmemory/server/routes/events.py +24 -8
- package/src/superlocalmemory/server/routes/evolution.py +135 -17
- package/src/superlocalmemory/server/routes/helpers.py +16 -1
- package/src/superlocalmemory/server/routes/ingest.py +7 -4
- package/src/superlocalmemory/server/routes/insights.py +3 -3
- package/src/superlocalmemory/server/routes/learning.py +14 -14
- package/src/superlocalmemory/server/routes/lifecycle.py +59 -8
- package/src/superlocalmemory/server/routes/memories.py +221 -49
- package/src/superlocalmemory/server/routes/mesh.py +95 -15
- package/src/superlocalmemory/server/routes/optimize.py +33 -1
- package/src/superlocalmemory/server/routes/prewarm.py +2 -0
- package/src/superlocalmemory/server/routes/profiles.py +63 -17
- package/src/superlocalmemory/server/routes/ratelimit.py +124 -0
- package/src/superlocalmemory/server/routes/rbac.py +367 -0
- package/src/superlocalmemory/server/routes/stats.py +13 -6
- package/src/superlocalmemory/server/routes/tiers.py +11 -9
- package/src/superlocalmemory/server/routes/v3_api.py +194 -81
- package/src/superlocalmemory/server/routes/ws.py +5 -2
- package/src/superlocalmemory/server/security_middleware.py +12 -5
- package/src/superlocalmemory/server/ui.py +30 -5
- package/src/superlocalmemory/server/unified_daemon.py +431 -75
- package/src/superlocalmemory/server/write_identity.py +38 -8
- package/src/superlocalmemory/storage/database.py +265 -53
- package/src/superlocalmemory/storage/migration_runner.py +53 -0
- package/src/superlocalmemory/storage/migrations/M021_ingestion_log_profile.py +108 -0
- package/src/superlocalmemory/storage/migrations/M022_entity_aliases_profile.py +86 -0
- package/src/superlocalmemory/storage/migrations/M023_mesh_profile_isolation.py +194 -0
- package/src/superlocalmemory/storage/migrations/M024_rbac_users_roles.py +87 -0
- package/src/superlocalmemory/storage/migrations/M025_perf_indexes.py +90 -0
- package/src/superlocalmemory/storage/migrations/M026_rbac_memberships_fk.py +136 -0
- package/src/superlocalmemory/storage/migrations/M027_transferable_patterns_profile.py +163 -0
- package/src/superlocalmemory/storage/models.py +4 -0
- package/src/superlocalmemory/storage/schema.py +87 -0
- package/src/superlocalmemory/storage/schema_v32.py +0 -9
- package/src/superlocalmemory/storage/schema_v343.py +24 -12
- package/src/superlocalmemory/trust/gate.py +49 -8
- package/src/superlocalmemory/ui/assets/slm-icon-white.svg +64 -0
- package/src/superlocalmemory/ui/assets/slm-icon.svg +36 -0
- package/src/superlocalmemory/ui/css/design-system.css +621 -0
- package/src/superlocalmemory/ui/css/neural-glass.css +6 -0
- package/src/superlocalmemory/ui/css/od-bridge.css +158 -0
- package/src/superlocalmemory/ui/favicon.svg +35 -4
- package/src/superlocalmemory/ui/index.html +306 -173
- package/src/superlocalmemory/ui/js/brain.js +5 -20
- package/src/superlocalmemory/ui/js/core.js +47 -31
- package/src/superlocalmemory/ui/js/dashboard.js +314 -63
- package/src/superlocalmemory/ui/js/event-delegation.js +102 -0
- package/src/superlocalmemory/ui/js/knowledge-graph.js +11 -11
- package/src/superlocalmemory/ui/js/math-health.js +1 -1
- package/src/superlocalmemory/ui/js/memories.js +15 -4
- package/src/superlocalmemory/ui/js/memory-chat.js +7 -7
- package/src/superlocalmemory/ui/js/ng-entities.js +6 -8
- package/src/superlocalmemory/ui/js/ng-ingestion.js +4 -4
- package/src/superlocalmemory/ui/js/ng-mesh.js +4 -9
- package/src/superlocalmemory/ui/js/ng-shell.js +8 -8
- package/src/superlocalmemory/ui/js/ng-skills.js +54 -2
- package/src/superlocalmemory/ui/js/od-agents.js +544 -0
- package/src/superlocalmemory/ui/js/od-auth-gate.js +257 -0
- package/src/superlocalmemory/ui/js/od-backup.js +780 -0
- package/src/superlocalmemory/ui/js/od-brain.js +779 -0
- package/src/superlocalmemory/ui/js/od-entities.js +579 -0
- package/src/superlocalmemory/ui/js/od-graph.js +593 -0
- package/src/superlocalmemory/ui/js/od-health.js +539 -0
- package/src/superlocalmemory/ui/js/od-mcp.js +508 -0
- package/src/superlocalmemory/ui/js/od-memories.js +887 -0
- package/src/superlocalmemory/ui/js/od-mesh.js +539 -0
- package/src/superlocalmemory/ui/js/od-operations.js +1250 -0
- package/src/superlocalmemory/ui/js/od-optimize.js +787 -0
- package/src/superlocalmemory/ui/js/od-settings.js +1053 -0
- package/src/superlocalmemory/ui/js/od-shell.js +593 -0
- package/src/superlocalmemory/ui/js/od-skills.js +573 -0
- package/src/superlocalmemory/ui/js/od-team.js +258 -0
- package/src/superlocalmemory/ui/js/profiles.js +159 -46
- package/src/superlocalmemory/ui/js/settings.js +2 -2
- package/src/superlocalmemory/ui/js/timeline.js +34 -5
- package/src/superlocalmemory/ui/js/trust-dashboard.js +2 -2
- package/src/superlocalmemory/vector/lancedb_backend.py +8 -6
- package/src/superlocalmemory/learning/behavioral_listener.py +0 -94
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
+
// Copyright (c) 2026 Varun Pratap Bhardwaj / Qualixar
|
|
3
|
+
// B2 (3.7.9): CSP-safe event delegation. Replaces inline on*= handlers
|
|
4
|
+
// (which force script-src 'unsafe-inline') with data-act-* attributes
|
|
5
|
+
// dispatched by document-level listeners. Registry keys are an allowlist
|
|
6
|
+
// by construction — no reflective window[name] invocation.
|
|
7
|
+
(function () {
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
// action-key -> handler(el, event). Handlers call existing globals.
|
|
11
|
+
const ACTIONS = {
|
|
12
|
+
// --- bespoke ---
|
|
13
|
+
'scroll-into': (el) => { const t = document.getElementById(el.dataset.target); if (t) t.scrollIntoView({ behavior: 'smooth', block: 'start' }); },
|
|
14
|
+
'sigma-clear-search': () => { sigmaClearSearch(); const i = document.getElementById('sigma-search-input'); if (i) i.value = ''; },
|
|
15
|
+
'export-all': (el, e) => { if (e) e.preventDefault(); exportAll(el.dataset.format); },
|
|
16
|
+
'export-search-results': (el, e) => { if (e) e.preventDefault(); exportSearchResults(); },
|
|
17
|
+
'set-memory-filter': (el) => setMemoryFilter(el.dataset.filter),
|
|
18
|
+
'community-source': (el) => handleCommunitySourceToggle(el.dataset.source),
|
|
19
|
+
// --- value (this.value) ---
|
|
20
|
+
'handle-resolution-change': (el) => handleResolutionChange(el.value),
|
|
21
|
+
'sigma-filter-by-category': (el) => sigmaFilterByCategory(el.value),
|
|
22
|
+
'sigma-search': (el) => sigmaSearch(el.value),
|
|
23
|
+
// --- no-arg ---
|
|
24
|
+
'backup-learning-db': () => backupLearningDb(),
|
|
25
|
+
'clear-event-stream': () => clearEventStream(),
|
|
26
|
+
'compact-dry-run': () => compactDryRun(),
|
|
27
|
+
'compact-execute': () => compactExecute(),
|
|
28
|
+
'connect-git-hub': () => connectGitHub(),
|
|
29
|
+
'connect-google-drive': () => connectGoogleDrive(),
|
|
30
|
+
'copy-memory-to-clipboard': () => copyMemoryToClipboard(),
|
|
31
|
+
'create-backup-now': () => createBackupNow(),
|
|
32
|
+
'create-profile': () => createProfile(),
|
|
33
|
+
'create-retention-policy': () => createRetentionPolicy(),
|
|
34
|
+
'evaluate-tiers-now': () => evaluateTiersNow(),
|
|
35
|
+
'export-backup': () => exportBackup(),
|
|
36
|
+
'export-memory-as-markdown': () => exportMemoryAsMarkdown(),
|
|
37
|
+
'filter-events': () => filterEvents(),
|
|
38
|
+
'load-agents': () => loadAgents(),
|
|
39
|
+
'load-clusters': () => loadClusters(),
|
|
40
|
+
'load-compliance': () => loadCompliance(),
|
|
41
|
+
'load-entity-explorer': () => loadEntityExplorer(),
|
|
42
|
+
'load-graph': () => loadGraph(),
|
|
43
|
+
'load-health-monitor': () => loadHealthMonitor(),
|
|
44
|
+
'load-ingestion-status': () => loadIngestionStatus(),
|
|
45
|
+
'load-mesh-peers': () => loadMeshPeers(),
|
|
46
|
+
'load-skill-evolution': () => loadSkillEvolution(),
|
|
47
|
+
'refresh-dashboard': () => refreshDashboard(),
|
|
48
|
+
'reset-learning-data': () => resetLearningData(),
|
|
49
|
+
'run-community-detection': () => runCommunityDetection(),
|
|
50
|
+
'save-backup-config': () => saveBackupConfig(),
|
|
51
|
+
'search-memories': () => searchMemories(),
|
|
52
|
+
'sigma-reset-view': () => sigmaResetView(),
|
|
53
|
+
'sigma-zoom-in': () => sigmaZoomIn(),
|
|
54
|
+
'sigma-zoom-out': () => sigmaZoomOut(),
|
|
55
|
+
'sync-cloud-now': () => syncCloudNow(),
|
|
56
|
+
'toggle-dark-mode': () => toggleDarkMode(),
|
|
57
|
+
// --- phase 2: handlers on JS-generated markup (dynamic args via data-*) ---
|
|
58
|
+
'toggle-privacy-blur': () => togglePrivacyBlur(),
|
|
59
|
+
'open-settings-tab': () => { const t = document.querySelector('[data-target=settings]'); if (t) t.click(); },
|
|
60
|
+
'show-chat-panel': () => showChatPanel(),
|
|
61
|
+
'show-detail-panel': () => showDetailPanel(),
|
|
62
|
+
'send-chat-from-input': () => sendChatFromInput(),
|
|
63
|
+
'cancel-chat': () => cancelChat(),
|
|
64
|
+
'send-chat-query': (el) => sendChatQuery(el.dataset.query),
|
|
65
|
+
'chat-submit-on-enter': (el, e) => { if (e && e.key === 'Enter') sendChatFromInput(); },
|
|
66
|
+
'citation-click': (el, e) => { if (e) e.preventDefault(); _onCitationClick(el.dataset.factId); },
|
|
67
|
+
'filter-entities': (el) => filterEntities(el.value),
|
|
68
|
+
'navigate-entity-page': (el) => navigateEntityPage(parseInt(el.dataset.page, 10)),
|
|
69
|
+
'show-entity-detail': (el) => showEntityDetail(el.dataset.entity),
|
|
70
|
+
'recompile-entity': (el) => recompileEntity(el.dataset.entity),
|
|
71
|
+
'close-entity-detail': () => { const p = document.getElementById('entity-detail-panel'); if (p) p.style.display = 'none'; },
|
|
72
|
+
'trigger-evolution': () => triggerEvolution(),
|
|
73
|
+
'enable-evolution': () => enableEvolution(),
|
|
74
|
+
'save-evolution-config': () => saveEvolutionConfig(),
|
|
75
|
+
'sigma-highlight-node': (el) => sigmaHighlightNode(el.dataset.nodeId),
|
|
76
|
+
'open-memory-detail': (el) => openMemoryDetail({ id: el.dataset.memId, content: el.dataset.memContent, category: el.dataset.memCategory, importance: parseFloat(el.dataset.memImportance) }, 'graph'),
|
|
77
|
+
'sigma-filter-community': (el) => sigmaFilterByCommunity(parseInt(el.dataset.communityId, 10), el.dataset.communitySrc),
|
|
78
|
+
'odg-select': (el) => odgSelect(el.dataset.odgId), // od-graph.js node inspector + citation clicks
|
|
79
|
+
'load-memories-page': (el) => loadMemories(parseInt(el.dataset.page, 10)),
|
|
80
|
+
'disconnect-destination': (el) => disconnectDestination(el.dataset.destId),
|
|
81
|
+
'adapter-action': (el) => adapterAction(el.dataset.adapter, el.dataset.adapterAction),
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const ATTR = { click: 'actClick', change: 'actChange', input: 'actInput', keydown: 'actKeydown' };
|
|
85
|
+
|
|
86
|
+
function makeHandler(type) {
|
|
87
|
+
const key = ATTR[type];
|
|
88
|
+
return function (event) {
|
|
89
|
+
let el = event.target;
|
|
90
|
+
while (el && el.nodeType === 1) {
|
|
91
|
+
if (el.dataset && el.dataset[key]) {
|
|
92
|
+
const fn = ACTIONS[el.dataset[key]];
|
|
93
|
+
if (typeof fn === 'function') fn(el, event);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
el = el.parentElement;
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
['click', 'change', 'input', 'keydown'].forEach((t) => document.addEventListener(t, makeHandler(t)));
|
|
102
|
+
})();
|
|
@@ -457,7 +457,7 @@ function openSigmaNodeDetail(nodeId) {
|
|
|
457
457
|
var neighbors = sigmaGraph.neighbors(nodeId);
|
|
458
458
|
var neighborList = neighbors.slice(0, 10).map(function(nid) {
|
|
459
459
|
var na = sigmaGraph.getNodeAttributes(nid);
|
|
460
|
-
return '<div class="border-bottom py-1 cursor-pointer"
|
|
460
|
+
return '<div class="border-bottom py-1 cursor-pointer" data-act-click="sigma-highlight-node" data-node-id="' + nid + '">'
|
|
461
461
|
+ '<small class="text-primary">' + escapeHtml((na.label || '').substring(0, 40)) + '</small>'
|
|
462
462
|
+ '</div>';
|
|
463
463
|
}).join('');
|
|
@@ -477,7 +477,7 @@ function openSigmaNodeDetail(nodeId) {
|
|
|
477
477
|
+ '<h6 class="mb-1">Connected (' + neighbors.length + ')</h6>'
|
|
478
478
|
+ '<div style="max-height:250px;overflow-y:auto;">' + (neighborList || '<span class="text-muted">No connections</span>') + '</div>'
|
|
479
479
|
+ '<hr class="my-2">'
|
|
480
|
-
+ '<button class="btn btn-sm btn-outline-primary w-100"
|
|
480
|
+
+ '<button class="btn btn-sm btn-outline-primary w-100" data-act-click="open-memory-detail" data-mem-id="' + nodeId + '" data-mem-content="' + escapeHtml((attrs.slm_content || '').substring(0, 80)).replace(/"/g, '"') + '" data-mem-category="' + (attrs.slm_category || '') + '" data-mem-importance="' + (attrs.slm_importance || 0.5) + '"><i class="bi bi-box-arrow-up-right"></i> Full Detail</button>';
|
|
481
481
|
}
|
|
482
482
|
}
|
|
483
483
|
|
|
@@ -493,7 +493,7 @@ function updateSigmaStatsPanel(data) {
|
|
|
493
493
|
categories[cat] = (categories[cat] || 0) + 1;
|
|
494
494
|
});
|
|
495
495
|
var catHtml = Object.keys(categories).map(function(k) {
|
|
496
|
-
return '<div>' + k + ': <strong>' + categories[k] + '</strong></div>';
|
|
496
|
+
return '<div>' + escapeHtml(k) + ': <strong>' + categories[k] + '</strong></div>';
|
|
497
497
|
}).join('');
|
|
498
498
|
panel.innerHTML = '<div>Nodes: <strong>' + nodes.length + '</strong></div>'
|
|
499
499
|
+ '<div>Edges: <strong>' + links.length + '</strong></div>'
|
|
@@ -738,14 +738,14 @@ function renderLiveCommunityPanel(communityMap) {
|
|
|
738
738
|
// Generate simple label from most common entity
|
|
739
739
|
var label = generateLiveLabel(c.community_id, c.members);
|
|
740
740
|
html += '<div class="d-flex align-items-center mb-1 cursor-pointer" '
|
|
741
|
-
+ '
|
|
741
|
+
+ 'data-act-click="sigma-filter-community" data-community-id="' + c.community_id + '" data-community-src="' + communitySource + '" '
|
|
742
742
|
+ 'title="' + c.members.length + ' memories">'
|
|
743
743
|
+ '<span style="display:inline-block;width:10px;height:10px;border-radius:50%;background:' + color + ';flex-shrink:0;"></span>'
|
|
744
744
|
+ '<span class="ms-1 text-truncate" style="font-size:0.75rem;">' + escapeHtml(label) + '</span>'
|
|
745
745
|
+ '<span class="badge bg-light text-dark ms-auto" style="font-size:0.65rem;">' + c.members.length + '</span>'
|
|
746
746
|
+ '</div>';
|
|
747
747
|
});
|
|
748
|
-
html += '<button class="btn btn-sm btn-outline-secondary w-100 mt-1"
|
|
748
|
+
html += '<button class="btn btn-sm btn-outline-secondary w-100 mt-1" data-act-click="sigma-clear-search">'
|
|
749
749
|
+ '<i class="bi bi-x-circle"></i> Clear Filter</button>';
|
|
750
750
|
panel.innerHTML = html;
|
|
751
751
|
}
|
|
@@ -780,7 +780,7 @@ function loadCommunities() {
|
|
|
780
780
|
var communities = data.communities || [];
|
|
781
781
|
if (communities.length === 0) {
|
|
782
782
|
panel.innerHTML = '<div class="text-muted small">No communities detected yet.</div>'
|
|
783
|
-
+ '<button class="btn btn-sm btn-outline-primary w-100 mt-1"
|
|
783
|
+
+ '<button class="btn btn-sm btn-outline-primary w-100 mt-1" data-act-click="run-community-detection">'
|
|
784
784
|
+ '<i class="bi bi-cpu"></i> Detect Communities</button>';
|
|
785
785
|
return;
|
|
786
786
|
}
|
|
@@ -789,16 +789,16 @@ function loadCommunities() {
|
|
|
789
789
|
communities.forEach(function(c) {
|
|
790
790
|
var color = c.color || SIGMA_CLUSTER_COLORS[c.community_id % SIGMA_CLUSTER_COLORS.length];
|
|
791
791
|
html += '<div class="d-flex align-items-center mb-1 cursor-pointer" '
|
|
792
|
-
+ '
|
|
793
|
-
+ 'title="' + (c.top_entities || []).join(', ') + '">'
|
|
792
|
+
+ 'data-act-click="sigma-filter-community" data-community-id="' + c.community_id + '" data-community-src="backend" '
|
|
793
|
+
+ 'title="' + escapeHtml((c.top_entities || []).join(', ')) + '">'
|
|
794
794
|
+ '<span style="display:inline-block;width:10px;height:10px;border-radius:50%;background:' + color + ';flex-shrink:0;"></span>'
|
|
795
795
|
+ '<span class="ms-1 text-truncate" style="font-size:0.75rem;">' + escapeHtml(c.label) + '</span>'
|
|
796
796
|
+ '<span class="badge bg-light text-dark ms-auto" style="font-size:0.65rem;">' + c.member_count + '</span>'
|
|
797
797
|
+ '</div>';
|
|
798
798
|
});
|
|
799
|
-
html += '<button class="btn btn-sm btn-outline-secondary w-100 mt-1"
|
|
799
|
+
html += '<button class="btn btn-sm btn-outline-secondary w-100 mt-1" data-act-click="sigma-clear-search">'
|
|
800
800
|
+ '<i class="bi bi-x-circle"></i> Clear Filter</button>';
|
|
801
|
-
html += '<button class="btn btn-sm btn-outline-primary w-100 mt-1"
|
|
801
|
+
html += '<button class="btn btn-sm btn-outline-primary w-100 mt-1" data-act-click="run-community-detection">'
|
|
802
802
|
+ '<i class="bi bi-arrow-clockwise"></i> Refresh</button>';
|
|
803
803
|
panel.innerHTML = html;
|
|
804
804
|
})
|
|
@@ -816,7 +816,7 @@ function runCommunityDetection() {
|
|
|
816
816
|
loadCommunities();
|
|
817
817
|
loadGraphSigma();
|
|
818
818
|
} else {
|
|
819
|
-
if (panel) panel.innerHTML = '<div class="text-danger small">Failed: ' + (data.error || 'Unknown') + '</div>';
|
|
819
|
+
if (panel) panel.innerHTML = '<div class="text-danger small">Failed: ' + escapeHtml(data.error || 'Unknown') + '</div>';
|
|
820
820
|
}
|
|
821
821
|
})
|
|
822
822
|
.catch(function(e) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// SuperLocalMemory V3 — Math Health
|
|
2
|
-
// Displays status of
|
|
2
|
+
// Displays status of the mathematical scoring, consistency, and lifecycle layers.
|
|
3
3
|
|
|
4
4
|
async function loadMathHealth() {
|
|
5
5
|
var CID = 'math-health-cards';
|
|
@@ -27,8 +27,13 @@ var _slmLastTotal = 0;
|
|
|
27
27
|
|
|
28
28
|
async function loadMemories(page) {
|
|
29
29
|
if (typeof page === 'number') _slmPage = Math.max(0, page);
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
// OD dashboard renders memories via odRenderMemories; the legacy
|
|
31
|
+
// #filter-category / #filter-project selects may be absent. Null-guard so
|
|
32
|
+
// this legacy loader never throws on the OD panes.
|
|
33
|
+
var _catEl = document.getElementById('filter-category');
|
|
34
|
+
var _projEl = document.getElementById('filter-project');
|
|
35
|
+
var category = _catEl ? _catEl.value : '';
|
|
36
|
+
var project = _projEl ? _projEl.value : '';
|
|
32
37
|
var limit = _slmPageSize;
|
|
33
38
|
var offset = _slmPage * limit;
|
|
34
39
|
var url = '/api/memories?limit=' + limit + '&offset=' + offset;
|
|
@@ -70,9 +75,9 @@ function renderPaginationControls(data) {
|
|
|
70
75
|
'<div class="d-flex justify-content-between align-items-center mt-3 small">' +
|
|
71
76
|
'<span class="text-muted">Showing ' + firstIdx + '\u2013' + showing + ' of ' + total + ' memories</span>' +
|
|
72
77
|
'<div class="btn-group btn-group-sm">' +
|
|
73
|
-
'<button type="button" class="btn btn-outline-secondary" ' + prevDisabled + '
|
|
78
|
+
'<button type="button" class="btn btn-outline-secondary" ' + prevDisabled + ' data-act-click="load-memories-page" data-page="' + (_slmPage - 1) + '"><i class="bi bi-chevron-left"></i> Prev</button>' +
|
|
74
79
|
'<button type="button" class="btn btn-outline-secondary disabled">Page ' + (_slmPage + 1) + ' / ' + (lastPage + 1) + '</button>' +
|
|
75
|
-
'<button type="button" class="btn btn-outline-secondary" ' + nextDisabled + '
|
|
80
|
+
'<button type="button" class="btn btn-outline-secondary" ' + nextDisabled + ' data-act-click="load-memories-page" data-page="' + (_slmPage + 1) + '">Next <i class="bi bi-chevron-right"></i></button>' +
|
|
76
81
|
'</div>' +
|
|
77
82
|
'</div>';
|
|
78
83
|
}
|
|
@@ -85,6 +90,12 @@ function renderMemoriesTable(memories, showScores) {
|
|
|
85
90
|
}
|
|
86
91
|
|
|
87
92
|
window._slmMemories = memories;
|
|
93
|
+
// OD dashboard renders memories via odRenderMemories; the legacy
|
|
94
|
+
// #memories-list table is absent on those panes. The cache above is set
|
|
95
|
+
// for OD features that read window._slmMemories, but skip the legacy DOM
|
|
96
|
+
// render here so this loader never throws on OD panes (mirrors the
|
|
97
|
+
// #filter-category / #filter-project null-guards in loadMemories).
|
|
98
|
+
if (!container) return;
|
|
88
99
|
var scoreHeader = showScores ? '<th>Score</th>' : '';
|
|
89
100
|
|
|
90
101
|
var rows = '';
|
|
@@ -34,8 +34,8 @@ function initMemoryChat() {
|
|
|
34
34
|
+ '<div class="card" style="height:550px; display:flex; flex-direction:column;">'
|
|
35
35
|
+ ' <div class="card-header py-2 d-flex align-items-center justify-content-between">'
|
|
36
36
|
+ ' <div>'
|
|
37
|
-
+ ' <button class="btn btn-sm btn-outline-primary active me-1" id="chat-tab-btn"
|
|
38
|
-
+ ' <button class="btn btn-sm btn-outline-secondary" id="detail-tab-btn"
|
|
37
|
+
+ ' <button class="btn btn-sm btn-outline-primary active me-1" id="chat-tab-btn" data-act-click="show-chat-panel"><i class="bi bi-chat-dots"></i> Ask Memory</button>'
|
|
38
|
+
+ ' <button class="btn btn-sm btn-outline-secondary" id="detail-tab-btn" data-act-click="show-detail-panel"><i class="bi bi-info-circle"></i> Detail</button>'
|
|
39
39
|
+ ' </div>'
|
|
40
40
|
+ ' <span class="badge bg-secondary" id="chat-mode-badge" style="font-size:0.7rem;">Mode A</span>'
|
|
41
41
|
+ ' </div>'
|
|
@@ -47,7 +47,7 @@ function initMemoryChat() {
|
|
|
47
47
|
// Quick actions
|
|
48
48
|
+ ' <div id="chat-quick-actions" class="px-2 py-1 border-top" style="font-size:0.75rem;">'
|
|
49
49
|
+ ' ' + QUICK_ACTIONS.map(function(a) {
|
|
50
|
-
return '<button class="btn btn-sm btn-outline-secondary me-1 mb-1"
|
|
50
|
+
return '<button class="btn btn-sm btn-outline-secondary me-1 mb-1" data-act-click="send-chat-query" data-query="' + escapeHtml(a.query).replace(/"/g, '"') + '">' + a.label + '</button>';
|
|
51
51
|
}).join('')
|
|
52
52
|
+ ' </div>'
|
|
53
53
|
|
|
@@ -55,11 +55,11 @@ function initMemoryChat() {
|
|
|
55
55
|
+ ' <div class="p-2 border-top">'
|
|
56
56
|
+ ' <div class="input-group input-group-sm">'
|
|
57
57
|
+ ' <input type="text" class="form-control" id="chat-input" placeholder="Ask your memory..."'
|
|
58
|
-
+ '
|
|
59
|
-
+ ' <button class="btn btn-primary"
|
|
58
|
+
+ ' data-act-keydown="chat-submit-on-enter">'
|
|
59
|
+
+ ' <button class="btn btn-primary" data-act-click="send-chat-from-input" id="chat-send-btn">'
|
|
60
60
|
+ ' <i class="bi bi-send"></i>'
|
|
61
61
|
+ ' </button>'
|
|
62
|
-
+ ' <button class="btn btn-outline-danger d-none"
|
|
62
|
+
+ ' <button class="btn btn-outline-danger d-none" data-act-click="cancel-chat" id="chat-cancel-btn">'
|
|
63
63
|
+ ' <i class="bi bi-stop-circle"></i>'
|
|
64
64
|
+ ' </button>'
|
|
65
65
|
+ ' </div>'
|
|
@@ -241,7 +241,7 @@ function _renderMessages() {
|
|
|
241
241
|
var citation = msg.citations[idx];
|
|
242
242
|
if (citation) {
|
|
243
243
|
return '<a href="#" class="badge bg-primary text-decoration-none" '
|
|
244
|
-
+ '
|
|
244
|
+
+ 'data-act-click="citation-click" data-fact-id="' + citation.fact_id + '" '
|
|
245
245
|
+ 'title="' + (citation.content_preview || '').replace(/"/g, '"') + '">'
|
|
246
246
|
+ match + '</a>';
|
|
247
247
|
}
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
var html =
|
|
50
50
|
'<div style="margin-bottom:16px">' +
|
|
51
51
|
'<input type="text" class="form-control" id="entity-search-input" placeholder="Search ' + total + ' entities..." ' +
|
|
52
|
-
'
|
|
52
|
+
'data-act-input="filter-entities" style="max-width:500px">' +
|
|
53
53
|
'</div>';
|
|
54
54
|
|
|
55
55
|
// Stats summary
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
for (var i = 0; i < Math.min(pages, 10); i++) {
|
|
77
77
|
var isActive = i === currentP;
|
|
78
78
|
html += '<button class="ng-btn' + (isActive ? ' ng-btn-accent' : '') + '" ' +
|
|
79
|
-
'
|
|
79
|
+
'data-act-click="navigate-entity-page" data-page="' + i + '" style="min-width:36px">' + (i + 1) + '</button>';
|
|
80
80
|
}
|
|
81
81
|
if (pages > 10) html += '<span style="padding:8px;color:var(--ng-text-tertiary)">...</span>';
|
|
82
82
|
html += '</div>';
|
|
@@ -97,10 +97,8 @@
|
|
|
97
97
|
: '';
|
|
98
98
|
|
|
99
99
|
return '<div class="col-md-6 col-lg-4">' +
|
|
100
|
-
'<div class="ng-glass" style="padding:16px;cursor:pointer;transition:border-color 0.2s;' + borderAccent + '" ' +
|
|
101
|
-
'
|
|
102
|
-
'onmouseover="this.style.borderColor=\'var(--ng-border-prominent)\'" ' +
|
|
103
|
-
'onmouseout="this.style.borderColor=\'var(--ng-border-subtle)\'">' +
|
|
100
|
+
'<div class="ng-glass ng-hover-border" style="padding:16px;cursor:pointer;transition:border-color 0.2s;' + borderAccent + '" ' +
|
|
101
|
+
'data-act-click="show-entity-detail" data-entity="' + escapeHtml(entity.name).replace(/"/g, '"') + '">' +
|
|
104
102
|
'<div style="display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:8px">' +
|
|
105
103
|
'<div style="font-weight:590;font-size:0.9375rem;color:var(--ng-text-primary)">' +
|
|
106
104
|
'<i class="bi ' + typeIcon + '" style="color:' + typeColor + ';margin-right:4px"></i>' +
|
|
@@ -143,9 +141,9 @@
|
|
|
143
141
|
'<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:16px">' +
|
|
144
142
|
'<h5 style="margin:0"><i class="bi bi-person-badge"></i> ' + escapeHtml(entityName) + '</h5>' +
|
|
145
143
|
'<div style="display:flex;gap:8px">' +
|
|
146
|
-
'<button class="ng-btn"
|
|
144
|
+
'<button class="ng-btn" data-act-click="recompile-entity" data-entity="' + escapeHtml(entityName).replace(/"/g, '"') + '">' +
|
|
147
145
|
'<i class="bi bi-arrow-repeat"></i> Recompile</button>' +
|
|
148
|
-
'<button class="ng-btn"
|
|
146
|
+
'<button class="ng-btn" data-act-click="close-entity-detail">' +
|
|
149
147
|
'<i class="bi bi-x-lg"></i></button>' +
|
|
150
148
|
'</div>' +
|
|
151
149
|
'</div>' +
|
|
@@ -127,14 +127,14 @@
|
|
|
127
127
|
'<div style="display:flex;gap:8px">' +
|
|
128
128
|
(isEnabled ?
|
|
129
129
|
(isRunning ?
|
|
130
|
-
'<button class="ng-btn"
|
|
130
|
+
'<button class="ng-btn" data-act-click="adapter-action" data-adapter="' + adapter.name + '" data-adapter-action="stop">' +
|
|
131
131
|
'<i class="bi bi-stop-circle"></i> Stop</button>' :
|
|
132
|
-
'<button class="ng-btn ng-btn-accent"
|
|
132
|
+
'<button class="ng-btn ng-btn-accent" data-act-click="adapter-action" data-adapter="' + adapter.name + '" data-adapter-action="start">' +
|
|
133
133
|
'<i class="bi bi-play-circle"></i> Start</button>'
|
|
134
134
|
) +
|
|
135
|
-
'<button class="ng-btn"
|
|
135
|
+
'<button class="ng-btn" data-act-click="adapter-action" data-adapter="' + adapter.name + '" data-adapter-action="disable" style="color:var(--ng-status-error)">' +
|
|
136
136
|
'<i class="bi bi-x-circle"></i> Disable</button>' :
|
|
137
|
-
'<button class="ng-btn ng-btn-accent"
|
|
137
|
+
'<button class="ng-btn ng-btn-accent" data-act-click="adapter-action" data-adapter="' + adapter.name + '" data-adapter-action="enable">' +
|
|
138
138
|
'<i class="bi bi-power"></i> Enable</button>'
|
|
139
139
|
) +
|
|
140
140
|
'</div>' +
|
|
@@ -12,17 +12,12 @@
|
|
|
12
12
|
// Dashboard callers authenticate with the install token so we never
|
|
13
13
|
// embed the mesh secret in JS. Token is fetched from /internal/token
|
|
14
14
|
// (loopback-only endpoint) and cached in sessionStorage for the tab session.
|
|
15
|
-
var
|
|
15
|
+
// B2 (3.7.9): keep the token in a private closure var, never sessionStorage.
|
|
16
|
+
var _tokenCache = null;
|
|
16
17
|
|
|
17
|
-
function readToken() {
|
|
18
|
-
try { return window.sessionStorage ? window.sessionStorage.getItem(TOKEN_STORAGE_KEY) : null; }
|
|
19
|
-
catch (e) { return null; }
|
|
20
|
-
}
|
|
18
|
+
function readToken() { return _tokenCache; }
|
|
21
19
|
|
|
22
|
-
function writeToken(value) {
|
|
23
|
-
try { if (window.sessionStorage) window.sessionStorage.setItem(TOKEN_STORAGE_KEY, value); }
|
|
24
|
-
catch (e) { /* storage disabled */ }
|
|
25
|
-
}
|
|
20
|
+
function writeToken(value) { _tokenCache = value; }
|
|
26
21
|
|
|
27
22
|
function fetchTokenFromServer() {
|
|
28
23
|
return fetch('/internal/token', { credentials: 'same-origin' })
|
|
@@ -115,7 +115,7 @@
|
|
|
115
115
|
|
|
116
116
|
footer.innerHTML =
|
|
117
117
|
// v3.4.10: Cloud Backup Account Widget
|
|
118
|
-
'<div id="ng-account-widget" style="margin-bottom:10px;padding:8px;border-radius:10px;background:rgba(255,255,255,0.03);border:1px solid rgba(255,255,255,0.06);cursor:pointer;"
|
|
118
|
+
'<div id="ng-account-widget" style="margin-bottom:10px;padding:8px;border-radius:10px;background:rgba(255,255,255,0.03);border:1px solid rgba(255,255,255,0.06);cursor:pointer;" data-act-click="open-settings-tab">' +
|
|
119
119
|
'<div style="display:flex;align-items:center;gap:8px;">' +
|
|
120
120
|
'<span id="ng-account-avatar" style="width:28px;height:28px;border-radius:50%;background:rgba(255,255,255,0.08);display:flex;align-items:center;justify-content:center;font-size:13px;flex-shrink:0;overflow:hidden;">' +
|
|
121
121
|
'<i class="bi bi-cloud-slash" style="font-size:13px;opacity:0.4;"></i>' +
|
|
@@ -128,16 +128,16 @@
|
|
|
128
128
|
'</div>' +
|
|
129
129
|
'<div id="ng-account-actions" style="display:none;margin-top:8px;padding-top:8px;border-top:1px solid rgba(255,255,255,0.05);">' +
|
|
130
130
|
'<div style="display:flex;gap:4px;">' +
|
|
131
|
-
'<button class="ng-btn"
|
|
131
|
+
'<button class="ng-btn" data-act-click="connect-google-drive" title="Connect Google Drive" style="flex:1;justify-content:center;font-size:11px;padding:4px;">' +
|
|
132
132
|
'<i class="bi bi-google" style="color:#4285f4;"></i>' +
|
|
133
133
|
'</button>' +
|
|
134
|
-
'<button class="ng-btn"
|
|
134
|
+
'<button class="ng-btn" data-act-click="connect-git-hub" title="Connect GitHub" style="flex:1;justify-content:center;font-size:11px;padding:4px;">' +
|
|
135
135
|
'<i class="bi bi-github"></i>' +
|
|
136
136
|
'</button>' +
|
|
137
|
-
'<button class="ng-btn"
|
|
137
|
+
'<button class="ng-btn" data-act-click="sync-cloud-now" title="Sync Now" style="flex:1;justify-content:center;font-size:11px;padding:4px;">' +
|
|
138
138
|
'<i class="bi bi-cloud-upload" style="color:#00D4AA;"></i>' +
|
|
139
139
|
'</button>' +
|
|
140
|
-
'<button class="ng-btn"
|
|
140
|
+
'<button class="ng-btn" data-act-click="export-backup" title="Export Backup" style="flex:1;justify-content:center;font-size:11px;padding:4px;">' +
|
|
141
141
|
'<i class="bi bi-download" style="color:#f39c12;"></i>' +
|
|
142
142
|
'</button>' +
|
|
143
143
|
'</div>' +
|
|
@@ -151,10 +151,10 @@
|
|
|
151
151
|
'<button class="ng-btn" id="ng-refresh-btn" title="Refresh" style="flex:1;justify-content:center">' +
|
|
152
152
|
'<i class="bi bi-arrow-clockwise"></i>' +
|
|
153
153
|
'</button>' +
|
|
154
|
-
'<button class="ng-btn" id="ng-theme-toggle" title="Toggle theme"
|
|
154
|
+
'<button class="ng-btn" id="ng-theme-toggle" title="Toggle theme" data-act-click="toggle-dark-mode" style="flex:1;justify-content:center">' +
|
|
155
155
|
'<i class="bi bi-sun-fill" id="ng-theme-icon"></i>' +
|
|
156
156
|
'</button>' +
|
|
157
|
-
'<button class="ng-btn" id="ng-privacy-btn" title="Privacy blur (for screen recording)"
|
|
157
|
+
'<button class="ng-btn" id="ng-privacy-btn" title="Privacy blur (for screen recording)" data-act-click="toggle-privacy-blur" style="flex:1;justify-content:center">' +
|
|
158
158
|
'<i class="bi bi-eye-slash" id="ng-privacy-icon"></i>' +
|
|
159
159
|
'</button>' +
|
|
160
160
|
'<a href="https://github.com/qualixar/superlocalmemory" target="_blank" class="ng-btn" title="Star on GitHub" style="flex:1;justify-content:center">' +
|
|
@@ -364,7 +364,7 @@
|
|
|
364
364
|
case 'health-pane':
|
|
365
365
|
// v3.4.21 / v3.4.21 (taxonomy): Health = runtime health ONLY
|
|
366
366
|
// (Daemon, Events, Agents, IDEs, Math). Governance concerns live
|
|
367
|
-
// in operations-pane. IDEs folded in v3.4.21
|
|
367
|
+
// in operations-pane. IDEs folded in v3.4.21 — they're
|
|
368
368
|
// connected-client state, same category as Agents.
|
|
369
369
|
if (typeof loadHealthMonitor === 'function') loadHealthMonitor();
|
|
370
370
|
if (typeof initEventStream === 'function') initEventStream();
|
|
@@ -47,11 +47,38 @@
|
|
|
47
47
|
'</div>' +
|
|
48
48
|
'<div style="display:flex;gap:8px">' +
|
|
49
49
|
(enabled
|
|
50
|
-
? '<button class="btn btn-sm btn-outline-success"
|
|
51
|
-
: '<button class="btn btn-sm btn-outline-primary"
|
|
50
|
+
? '<button class="btn btn-sm btn-outline-success" data-act-click="trigger-evolution"><i class="bi bi-play-fill"></i> Run Now</button>'
|
|
51
|
+
: '<button class="btn btn-sm btn-outline-primary" data-act-click="enable-evolution"><i class="bi bi-power"></i> Enable</button>') +
|
|
52
52
|
'</div>' +
|
|
53
53
|
'</div>';
|
|
54
54
|
|
|
55
|
+
// Per-step evolution model config (v3.7.9) — shown when enabled.
|
|
56
|
+
if (enabled) {
|
|
57
|
+
var cfg = data.config || {};
|
|
58
|
+
var modelOpts = function(sel) {
|
|
59
|
+
var cur = sel || 'auto';
|
|
60
|
+
if (cur === '') cur = 'auto';
|
|
61
|
+
return ['auto', 'haiku', 'sonnet', 'ollama'].map(function(m) {
|
|
62
|
+
return '<option value="' + m + '"' + (m === cur ? ' selected' : '') + '>' + m + '</option>';
|
|
63
|
+
}).join('');
|
|
64
|
+
};
|
|
65
|
+
html += '<div style="margin-top:12px;border-top:1px solid var(--bs-border-color);padding-top:12px">' +
|
|
66
|
+
'<div style="font-size:0.8125rem;font-weight:600;margin-bottom:8px">Evolution models ' +
|
|
67
|
+
'<span style="font-weight:400;color:var(--ng-text-tertiary,#888)">(lowest-cost by default)</span></div>' +
|
|
68
|
+
'<div style="display:flex;gap:12px;flex-wrap:wrap;align-items:flex-end">' +
|
|
69
|
+
'<label style="font-size:0.75rem">Generate<br><select id="evo-mutation-model" class="form-select form-select-sm">' + modelOpts(cfg.mutation_model) + '</select></label>' +
|
|
70
|
+
'<label style="font-size:0.75rem">Verify<br><select id="evo-verify-model" class="form-select form-select-sm">' + modelOpts(cfg.verify_model) + '</select></label>' +
|
|
71
|
+
'<label style="font-size:0.75rem">Confirm<br><select id="evo-confirm-model" class="form-select form-select-sm">' + modelOpts(cfg.confirm_model) + '</select></label>' +
|
|
72
|
+
'<label style="font-size:0.75rem">Max/cycle<br><input id="evo-max-cycle" type="number" min="1" max="50" value="' + (cfg.max_per_cycle || 3) + '" class="form-control form-control-sm" style="width:84px"></label>' +
|
|
73
|
+
'<button class="btn btn-sm btn-primary" data-act-click="save-evolution-config"><i class="bi bi-save"></i> Save</button>' +
|
|
74
|
+
'</div>' +
|
|
75
|
+
'<div style="font-size:0.7rem;color:var(--ng-text-tertiary,#888);margin-top:8px">' +
|
|
76
|
+
'⚠ Evolution makes background LLM calls during consolidation (capped 10/cycle, 3 cycles/day). ' +
|
|
77
|
+
'“auto” picks the cheapest capable model for your backend; the verifier stays independent of the generator.' +
|
|
78
|
+
'</div>' +
|
|
79
|
+
'</div>';
|
|
80
|
+
}
|
|
81
|
+
|
|
55
82
|
// Evolution history (if any)
|
|
56
83
|
if (data.recent && data.recent.length > 0) {
|
|
57
84
|
html += '<div style="margin-top:12px;border-top:1px solid var(--bs-border-color);padding-top:12px">' +
|
|
@@ -105,6 +132,31 @@
|
|
|
105
132
|
.catch(function(err) { alert('Error: ' + err.message); });
|
|
106
133
|
};
|
|
107
134
|
|
|
135
|
+
window.saveEvolutionConfig = function() {
|
|
136
|
+
var g = function(id) { var e = document.getElementById(id); return e ? e.value : undefined; };
|
|
137
|
+
var body = {
|
|
138
|
+
mutation_model: g('evo-mutation-model'),
|
|
139
|
+
verify_model: g('evo-verify-model'),
|
|
140
|
+
confirm_model: g('evo-confirm-model'),
|
|
141
|
+
};
|
|
142
|
+
var mx = g('evo-max-cycle');
|
|
143
|
+
if (mx) body.max_evolutions_per_cycle = parseInt(mx, 10);
|
|
144
|
+
fetch('/api/evolution/config', {
|
|
145
|
+
method: 'POST',
|
|
146
|
+
headers: { 'Content-Type': 'application/json' },
|
|
147
|
+
body: JSON.stringify(body),
|
|
148
|
+
})
|
|
149
|
+
.then(function(r) { return r.json(); })
|
|
150
|
+
.then(function(data) {
|
|
151
|
+
if (data.ok) {
|
|
152
|
+
loadSkillEvolution();
|
|
153
|
+
} else {
|
|
154
|
+
alert('Could not save evolution config: ' + (data.error || 'unknown'));
|
|
155
|
+
}
|
|
156
|
+
})
|
|
157
|
+
.catch(function(err) { alert('Error: ' + err.message); });
|
|
158
|
+
};
|
|
159
|
+
|
|
108
160
|
function fetchSkillOverview() {
|
|
109
161
|
var el = document.getElementById('skills-overview-cards');
|
|
110
162
|
if (!el) return;
|