superlocalmemory 2.6.0 → 2.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 +167 -1803
- package/README.md +212 -397
- package/bin/slm +179 -3
- package/bin/superlocalmemoryv2:learning +4 -0
- package/bin/superlocalmemoryv2:patterns +4 -0
- package/docs/ACCESSIBILITY.md +291 -0
- package/docs/ARCHITECTURE.md +12 -6
- package/docs/FRAMEWORK-INTEGRATIONS.md +300 -0
- package/docs/MCP-MANUAL-SETUP.md +14 -4
- package/install.sh +99 -3
- package/mcp_server.py +291 -1
- package/package.json +2 -1
- package/requirements-learning.txt +12 -0
- package/scripts/verify-v27.sh +233 -0
- package/skills/slm-show-patterns/SKILL.md +224 -0
- package/src/learning/__init__.py +201 -0
- package/src/learning/adaptive_ranker.py +826 -0
- package/src/learning/cross_project_aggregator.py +866 -0
- package/src/learning/engagement_tracker.py +638 -0
- package/src/learning/feature_extractor.py +461 -0
- package/src/learning/feedback_collector.py +690 -0
- package/src/learning/learning_db.py +842 -0
- package/src/learning/project_context_manager.py +582 -0
- package/src/learning/source_quality_scorer.py +685 -0
- package/src/learning/synthetic_bootstrap.py +1047 -0
- package/src/learning/tests/__init__.py +0 -0
- package/src/learning/tests/test_adaptive_ranker.py +328 -0
- package/src/learning/tests/test_aggregator.py +309 -0
- package/src/learning/tests/test_feedback_collector.py +295 -0
- package/src/learning/tests/test_learning_db.py +606 -0
- package/src/learning/tests/test_project_context.py +296 -0
- package/src/learning/tests/test_source_quality.py +355 -0
- package/src/learning/tests/test_synthetic_bootstrap.py +433 -0
- package/src/learning/tests/test_workflow_miner.py +322 -0
- package/src/learning/workflow_pattern_miner.py +665 -0
- package/ui/index.html +346 -13
- package/ui/js/clusters.js +90 -1
- package/ui/js/graph-core.js +445 -0
- package/ui/js/graph-cytoscape-monolithic-backup.js +1168 -0
- package/ui/js/graph-cytoscape.js +1168 -0
- package/ui/js/graph-d3-backup.js +32 -0
- package/ui/js/graph-filters.js +220 -0
- package/ui/js/graph-interactions.js +354 -0
- package/ui/js/graph-ui.js +214 -0
- package/ui/js/memories.js +52 -0
- package/ui/js/modal.js +104 -1
package/bin/slm
CHANGED
|
@@ -121,13 +121,178 @@ case "$1" in
|
|
|
121
121
|
context)
|
|
122
122
|
python3 "$SLM_DIR/pattern_learner.py" context "$@"
|
|
123
123
|
;;
|
|
124
|
+
correct)
|
|
125
|
+
# slm patterns correct <id> <new_value>
|
|
126
|
+
pattern_id="$1"
|
|
127
|
+
new_value="$2"
|
|
128
|
+
if [ -z "$pattern_id" ] || [ -z "$new_value" ]; then
|
|
129
|
+
echo "Usage: slm patterns correct <pattern_id> <new_value>"
|
|
130
|
+
exit 1
|
|
131
|
+
fi
|
|
132
|
+
python3 -c "
|
|
133
|
+
import sys
|
|
134
|
+
sys.path.insert(0, '${SLM_DIR}')
|
|
135
|
+
sys.path.insert(0, '$(dirname "${SLM_DIR}")/Documents/AGENTIC_Official/SuperLocalMemoryV2-repo/src')
|
|
136
|
+
try:
|
|
137
|
+
from learning import get_learning_db
|
|
138
|
+
ldb = get_learning_db()
|
|
139
|
+
if ldb:
|
|
140
|
+
conn = ldb._get_connection()
|
|
141
|
+
cursor = conn.cursor()
|
|
142
|
+
cursor.execute('SELECT * FROM transferable_patterns WHERE id = ?', (int(sys.argv[1]),))
|
|
143
|
+
p = cursor.fetchone()
|
|
144
|
+
conn.close()
|
|
145
|
+
if p:
|
|
146
|
+
ldb.upsert_transferable_pattern(
|
|
147
|
+
pattern_type=p['pattern_type'], key=p['key'],
|
|
148
|
+
value=sys.argv[2], confidence=1.0,
|
|
149
|
+
evidence_count=p['evidence_count']+1,
|
|
150
|
+
profiles_seen=p['profiles_seen'],
|
|
151
|
+
contradictions=[f\"Corrected from '{p['value']}' to '{sys.argv[2]}'\"],
|
|
152
|
+
)
|
|
153
|
+
print(f\"Pattern '{p['key']}' corrected: '{p['value']}' -> '{sys.argv[2]}'\")
|
|
154
|
+
else:
|
|
155
|
+
print(f'Pattern #{sys.argv[1]} not found')
|
|
156
|
+
else:
|
|
157
|
+
print('Learning database not available')
|
|
158
|
+
except ImportError:
|
|
159
|
+
print('Learning features not available')
|
|
160
|
+
except Exception as e:
|
|
161
|
+
print(f'Error: {e}')
|
|
162
|
+
" "$pattern_id" "$new_value"
|
|
163
|
+
;;
|
|
124
164
|
*)
|
|
125
|
-
echo "Usage: slm patterns {update|list|context}"
|
|
165
|
+
echo "Usage: slm patterns {update|list|context|correct}"
|
|
126
166
|
exit 1
|
|
127
167
|
;;
|
|
128
168
|
esac
|
|
129
169
|
;;
|
|
130
170
|
|
|
171
|
+
useful)
|
|
172
|
+
shift
|
|
173
|
+
# Mark memory IDs as useful (v2.7 learning feedback)
|
|
174
|
+
if [ -z "$1" ]; then
|
|
175
|
+
echo "Usage: slm useful <memory_id> [memory_id...]"
|
|
176
|
+
echo " Mark recalled memories as useful to improve future ranking"
|
|
177
|
+
exit 1
|
|
178
|
+
fi
|
|
179
|
+
python3 -c "
|
|
180
|
+
import sys
|
|
181
|
+
sys.path.insert(0, '${SLM_DIR}')
|
|
182
|
+
sys.path.insert(0, '$(dirname \"${SLM_DIR}\")/Documents/AGENTIC_Official/SuperLocalMemoryV2-repo/src')
|
|
183
|
+
try:
|
|
184
|
+
from learning.feedback_collector import FeedbackCollector
|
|
185
|
+
fc = FeedbackCollector()
|
|
186
|
+
ids = [int(x) for x in sys.argv[1:]]
|
|
187
|
+
fc.record_cli_useful(ids, query='cli-feedback')
|
|
188
|
+
print(f'Marked {len(ids)} memor{\"y\" if len(ids)==1 else \"ies\"} as useful')
|
|
189
|
+
except ImportError:
|
|
190
|
+
print('Learning features not available. Install: pip3 install lightgbm scipy')
|
|
191
|
+
except Exception as e:
|
|
192
|
+
print(f'Error: {e}')
|
|
193
|
+
" "$@"
|
|
194
|
+
;;
|
|
195
|
+
|
|
196
|
+
learning)
|
|
197
|
+
shift
|
|
198
|
+
subcommand="${1:-status}"
|
|
199
|
+
shift 2>/dev/null || true
|
|
200
|
+
case "$subcommand" in
|
|
201
|
+
status)
|
|
202
|
+
python3 -c "
|
|
203
|
+
import sys, json
|
|
204
|
+
sys.path.insert(0, '${SLM_DIR}')
|
|
205
|
+
sys.path.insert(0, '$(dirname \"${SLM_DIR}\")/Documents/AGENTIC_Official/SuperLocalMemoryV2-repo/src')
|
|
206
|
+
try:
|
|
207
|
+
from learning import get_status
|
|
208
|
+
status = get_status()
|
|
209
|
+
print('SuperLocalMemory v2.7 — Learning System Status')
|
|
210
|
+
print('=' * 50)
|
|
211
|
+
deps = status['dependencies']
|
|
212
|
+
print(f'LightGBM: {\"installed (\" + deps[\"lightgbm\"][\"version\"] + \")\" if deps[\"lightgbm\"][\"installed\"] else \"not installed\"}')
|
|
213
|
+
print(f'SciPy: {\"installed (\" + deps[\"scipy\"][\"version\"] + \")\" if deps[\"scipy\"][\"installed\"] else \"not installed\"}')
|
|
214
|
+
print(f'ML Ranking: {\"available\" if status[\"ml_ranking_available\"] else \"unavailable\"}')
|
|
215
|
+
print(f'Full Learning: {\"available\" if status[\"learning_available\"] else \"unavailable\"}')
|
|
216
|
+
if status.get('learning_db_stats'):
|
|
217
|
+
s = status['learning_db_stats']
|
|
218
|
+
print(f'')
|
|
219
|
+
print(f'Feedback signals: {s[\"feedback_count\"]}')
|
|
220
|
+
print(f'Unique queries: {s[\"unique_queries\"]}')
|
|
221
|
+
print(f'Patterns learned: {s[\"transferable_patterns\"]} ({s[\"high_confidence_patterns\"]} high confidence)')
|
|
222
|
+
print(f'Workflow patterns: {s[\"workflow_patterns\"]}')
|
|
223
|
+
print(f'Sources tracked: {s[\"tracked_sources\"]}')
|
|
224
|
+
print(f'Models trained: {s[\"models_trained\"]}')
|
|
225
|
+
print(f'Learning DB size: {s[\"db_size_kb\"]} KB')
|
|
226
|
+
except ImportError:
|
|
227
|
+
print('Learning features not available. Install: pip3 install lightgbm scipy')
|
|
228
|
+
except Exception as e:
|
|
229
|
+
print(f'Error: {e}')
|
|
230
|
+
"
|
|
231
|
+
;;
|
|
232
|
+
retrain)
|
|
233
|
+
python3 -c "
|
|
234
|
+
import sys
|
|
235
|
+
sys.path.insert(0, '${SLM_DIR}')
|
|
236
|
+
sys.path.insert(0, '$(dirname \"${SLM_DIR}\")/Documents/AGENTIC_Official/SuperLocalMemoryV2-repo/src')
|
|
237
|
+
try:
|
|
238
|
+
from learning import get_adaptive_ranker
|
|
239
|
+
ranker = get_adaptive_ranker()
|
|
240
|
+
if ranker:
|
|
241
|
+
result = ranker.train(force=True)
|
|
242
|
+
if result:
|
|
243
|
+
print(f'Model retrained successfully')
|
|
244
|
+
else:
|
|
245
|
+
print('Insufficient data for training (need 200+ feedback signals)')
|
|
246
|
+
else:
|
|
247
|
+
print('Adaptive ranker not available')
|
|
248
|
+
except ImportError:
|
|
249
|
+
print('Learning features not available. Install: pip3 install lightgbm scipy')
|
|
250
|
+
except Exception as e:
|
|
251
|
+
print(f'Error: {e}')
|
|
252
|
+
"
|
|
253
|
+
;;
|
|
254
|
+
reset)
|
|
255
|
+
python3 -c "
|
|
256
|
+
import sys
|
|
257
|
+
sys.path.insert(0, '${SLM_DIR}')
|
|
258
|
+
sys.path.insert(0, '$(dirname \"${SLM_DIR}\")/Documents/AGENTIC_Official/SuperLocalMemoryV2-repo/src')
|
|
259
|
+
try:
|
|
260
|
+
from learning import get_learning_db
|
|
261
|
+
ldb = get_learning_db()
|
|
262
|
+
if ldb:
|
|
263
|
+
ldb.reset()
|
|
264
|
+
print('All learning data reset. Memories in memory.db preserved.')
|
|
265
|
+
else:
|
|
266
|
+
print('Learning database not available')
|
|
267
|
+
except ImportError:
|
|
268
|
+
print('Learning features not available')
|
|
269
|
+
except Exception as e:
|
|
270
|
+
print(f'Error: {e}')
|
|
271
|
+
"
|
|
272
|
+
;;
|
|
273
|
+
*)
|
|
274
|
+
echo "Usage: slm learning {status|retrain|reset}"
|
|
275
|
+
exit 1
|
|
276
|
+
;;
|
|
277
|
+
esac
|
|
278
|
+
;;
|
|
279
|
+
|
|
280
|
+
engagement)
|
|
281
|
+
python3 -c "
|
|
282
|
+
import sys
|
|
283
|
+
sys.path.insert(0, '${SLM_DIR}')
|
|
284
|
+
sys.path.insert(0, '$(dirname \"${SLM_DIR}\")/Documents/AGENTIC_Official/SuperLocalMemoryV2-repo/src')
|
|
285
|
+
try:
|
|
286
|
+
from learning.engagement_tracker import EngagementTracker
|
|
287
|
+
tracker = EngagementTracker()
|
|
288
|
+
print(tracker.format_for_cli())
|
|
289
|
+
except ImportError:
|
|
290
|
+
print('Learning features not available. Install: pip3 install lightgbm scipy')
|
|
291
|
+
except Exception as e:
|
|
292
|
+
print(f'Error: {e}')
|
|
293
|
+
"
|
|
294
|
+
;;
|
|
295
|
+
|
|
131
296
|
help|--help|-h)
|
|
132
297
|
cat <<EOF
|
|
133
298
|
SuperLocalMemory V2 - Universal CLI
|
|
@@ -154,6 +319,14 @@ PATTERN LEARNING:
|
|
|
154
319
|
slm patterns update Learn patterns from memories
|
|
155
320
|
slm patterns list [threshold] List learned patterns
|
|
156
321
|
slm patterns context [threshold] Get coding identity context
|
|
322
|
+
slm patterns correct <id> <value> Correct a learned pattern
|
|
323
|
+
|
|
324
|
+
LEARNING (v2.7):
|
|
325
|
+
slm useful <id> [id...] Mark memories as useful (ranking feedback)
|
|
326
|
+
slm learning status Learning system status
|
|
327
|
+
slm learning retrain Force model retrain
|
|
328
|
+
slm learning reset Delete all learning data (memories preserved)
|
|
329
|
+
slm engagement Show engagement metrics
|
|
157
330
|
|
|
158
331
|
WEB DASHBOARD:
|
|
159
332
|
slm ui [PORT] Start web dashboard (default port 8765)
|
|
@@ -187,13 +360,13 @@ DOCUMENTATION:
|
|
|
187
360
|
README: https://github.com/varun369/SuperLocalMemoryV2
|
|
188
361
|
Docs: ~/.claude-memory/docs/
|
|
189
362
|
|
|
190
|
-
VERSION: 2.
|
|
363
|
+
VERSION: 2.7.0
|
|
191
364
|
EOF
|
|
192
365
|
;;
|
|
193
366
|
|
|
194
367
|
version|--version|-v)
|
|
195
368
|
echo "SuperLocalMemory V2 - Universal CLI"
|
|
196
|
-
echo "Version: 2.
|
|
369
|
+
echo "Version: 2.7.0"
|
|
197
370
|
echo "Database: $SLM_DIR/memory.db"
|
|
198
371
|
;;
|
|
199
372
|
|
|
@@ -213,6 +386,9 @@ EOF
|
|
|
213
386
|
echo " profile - Manage profiles"
|
|
214
387
|
echo " graph - Knowledge graph operations"
|
|
215
388
|
echo " patterns - Pattern learning"
|
|
389
|
+
echo " useful - Mark memories as useful"
|
|
390
|
+
echo " learning - Learning system management"
|
|
391
|
+
echo " engagement - Show engagement metrics"
|
|
216
392
|
echo " help - Show detailed help"
|
|
217
393
|
echo ""
|
|
218
394
|
echo "Run 'slm help' for more information"
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
# Accessibility Features - SuperLocalMemory V2.6.5
|
|
2
|
+
|
|
3
|
+
**Last Updated:** February 16, 2026
|
|
4
|
+
**Author:** Varun Pratap Bhardwaj
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
SuperLocalMemory V2.6.5 includes comprehensive keyboard navigation and screen reader support for the interactive knowledge graph, making it fully accessible to users with disabilities.
|
|
11
|
+
|
|
12
|
+
## Keyboard Navigation
|
|
13
|
+
|
|
14
|
+
### Graph Container Focus
|
|
15
|
+
|
|
16
|
+
The graph container (`#graph-container`) is focusable via keyboard:
|
|
17
|
+
|
|
18
|
+
- **Focus method:** Click graph OR press `Tab` from controls above
|
|
19
|
+
- **Visual indicator:** Browser native focus outline + first node highlighted with blue border
|
|
20
|
+
- **ARIA role:** `role="application"` signals custom keyboard handling
|
|
21
|
+
|
|
22
|
+
### Node Navigation
|
|
23
|
+
|
|
24
|
+
| Key | Action |
|
|
25
|
+
|-----|--------|
|
|
26
|
+
| **Tab** | Move to next node (cycles through all nodes) |
|
|
27
|
+
| **Shift+Tab** | Move to previous node |
|
|
28
|
+
| **→** (Right Arrow) | Move to nearest node on the right |
|
|
29
|
+
| **←** (Left Arrow) | Move to nearest node on the left |
|
|
30
|
+
| **↓** (Down Arrow) | Move to nearest node below |
|
|
31
|
+
| **↑** (Up Arrow) | Move to nearest node above |
|
|
32
|
+
| **Home** | Jump to first node |
|
|
33
|
+
| **End** | Jump to last node |
|
|
34
|
+
|
|
35
|
+
**Arrow Key Algorithm:**
|
|
36
|
+
- Finds nodes in specified direction (based on X/Y coordinates)
|
|
37
|
+
- Prioritizes nodes closer to current position
|
|
38
|
+
- Combines Euclidean distance with directional score
|
|
39
|
+
- Ensures no "stuck" states (always finds a valid next node)
|
|
40
|
+
|
|
41
|
+
### Actions
|
|
42
|
+
|
|
43
|
+
| Key | Action |
|
|
44
|
+
|-----|--------|
|
|
45
|
+
| **Enter** or **Space** | Open modal for focused node |
|
|
46
|
+
| **Escape** | Clear active filter OR blur graph (if no filter) |
|
|
47
|
+
|
|
48
|
+
### Visual Focus Indicator
|
|
49
|
+
|
|
50
|
+
Focused nodes have the CSS class `.keyboard-focused` with:
|
|
51
|
+
|
|
52
|
+
```css
|
|
53
|
+
border-width: 5px;
|
|
54
|
+
border-color: #0066ff;
|
|
55
|
+
border-style: solid;
|
|
56
|
+
box-shadow: 0 0 15px #0066ff;
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The graph smoothly animates to center the focused node in the viewport.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Screen Reader Support
|
|
64
|
+
|
|
65
|
+
### ARIA Attributes
|
|
66
|
+
|
|
67
|
+
#### Graph Container
|
|
68
|
+
|
|
69
|
+
```html
|
|
70
|
+
<div id="graph-container"
|
|
71
|
+
role="application"
|
|
72
|
+
aria-label="Interactive knowledge graph - use Tab to navigate nodes, Enter to view details, Arrow keys to move between adjacent nodes, Escape to clear filters"
|
|
73
|
+
aria-describedby="graph-stats">
|
|
74
|
+
</div>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
- **`role="application"`** - Signals custom keyboard handling
|
|
78
|
+
- **`aria-label`** - Provides usage instructions
|
|
79
|
+
- **`aria-describedby`** - Links to graph statistics (node/edge count)
|
|
80
|
+
|
|
81
|
+
#### Status Regions
|
|
82
|
+
|
|
83
|
+
```html
|
|
84
|
+
<div id="graph-status-full" role="status" aria-live="polite">
|
|
85
|
+
Showing all memories
|
|
86
|
+
</div>
|
|
87
|
+
|
|
88
|
+
<div id="graph-status-filtered" role="status" aria-live="polite">
|
|
89
|
+
Viewing Cluster X (Y memories)
|
|
90
|
+
</div>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
- **`role="status"`** - Semantic status information
|
|
94
|
+
- **`aria-live="polite"`** - Announces changes when user is idle
|
|
95
|
+
|
|
96
|
+
#### Hidden Status Region
|
|
97
|
+
|
|
98
|
+
An off-screen status region announces keyboard navigation events:
|
|
99
|
+
|
|
100
|
+
```html
|
|
101
|
+
<div id="graph-sr-status"
|
|
102
|
+
role="status"
|
|
103
|
+
aria-live="polite"
|
|
104
|
+
aria-atomic="true"
|
|
105
|
+
style="position:absolute; left:-10000px; width:1px; height:1px; overflow:hidden;">
|
|
106
|
+
</div>
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
This element is invisible but screen readers announce its content changes.
|
|
110
|
+
|
|
111
|
+
#### Buttons
|
|
112
|
+
|
|
113
|
+
All interactive buttons have `aria-label` attributes:
|
|
114
|
+
|
|
115
|
+
```html
|
|
116
|
+
<button aria-label="Refresh graph data">...</button>
|
|
117
|
+
<button aria-label="Clear filter and show all memories">...</button>
|
|
118
|
+
<button aria-label="Toggle dark mode">...</button>
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
#### Dropdowns
|
|
122
|
+
|
|
123
|
+
Form controls have proper labels:
|
|
124
|
+
|
|
125
|
+
```html
|
|
126
|
+
<label for="graph-layout-selector">Layout Algorithm:</label>
|
|
127
|
+
<select id="graph-layout-selector" aria-label="Select graph layout algorithm">
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Screen Reader Announcements
|
|
131
|
+
|
|
132
|
+
The `updateScreenReaderStatus()` function announces:
|
|
133
|
+
|
|
134
|
+
1. **Graph load:** "Graph loaded with X memories and Y connections"
|
|
135
|
+
2. **Node navigation:** "Memory 123: SuperLocalMemory Project, Cluster 2, Importance 8 out of 10"
|
|
136
|
+
3. **Filter cleared:** "Filters cleared, showing all memories"
|
|
137
|
+
|
|
138
|
+
These announcements are sent to the hidden `#graph-sr-status` region.
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Modal Focus Management
|
|
143
|
+
|
|
144
|
+
### Opening Modal
|
|
145
|
+
|
|
146
|
+
When `openMemoryModal()` is called:
|
|
147
|
+
|
|
148
|
+
1. **Store last focused element:** `window.lastFocusedElement = document.activeElement`
|
|
149
|
+
2. **Bootstrap modal shown event:** Focus moves to first button in modal
|
|
150
|
+
3. **Tab order:** Close button → Modal content → Action buttons → Footer buttons
|
|
151
|
+
|
|
152
|
+
### Closing Modal
|
|
153
|
+
|
|
154
|
+
When modal closes (via Bootstrap `hidden.bs.modal` event):
|
|
155
|
+
|
|
156
|
+
1. **Restore focus:** `window.lastFocusedElement.focus()`
|
|
157
|
+
2. **Clear stored element:** `window.lastFocusedElement = null`
|
|
158
|
+
3. **User can continue:** Keyboard navigation resumes from same node
|
|
159
|
+
|
|
160
|
+
This ensures users don't lose their place in the graph when opening/closing modals.
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Skip Links
|
|
165
|
+
|
|
166
|
+
A skip link is provided for keyboard users:
|
|
167
|
+
|
|
168
|
+
```html
|
|
169
|
+
<a href="#memories-pane" class="visually-hidden-focusable">Skip to Memories list</a>
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
This link is invisible until focused (via Tab), allowing users to bypass the graph and jump directly to the Memories tab.
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Testing with Screen Readers
|
|
177
|
+
|
|
178
|
+
### macOS VoiceOver
|
|
179
|
+
|
|
180
|
+
1. **Enable:** Press `Cmd+F5`
|
|
181
|
+
2. **Navigate:** `Control+Option+Arrow keys`
|
|
182
|
+
3. **Read current element:** `Control+Option+A`
|
|
183
|
+
4. **Test focus:** Tab through graph → Verify announcements
|
|
184
|
+
|
|
185
|
+
### Windows NVDA
|
|
186
|
+
|
|
187
|
+
1. **Install:** Download from [nvaccess.org](https://www.nvaccess.org/)
|
|
188
|
+
2. **Start:** `Control+Alt+N`
|
|
189
|
+
3. **Navigate:** Arrow keys
|
|
190
|
+
4. **Browse mode:** Press `Insert+Space` to toggle
|
|
191
|
+
|
|
192
|
+
### Windows JAWS
|
|
193
|
+
|
|
194
|
+
1. **Commercial software:** Most widely used screen reader
|
|
195
|
+
2. **Navigate:** Arrow keys + Tab
|
|
196
|
+
3. **Read mode:** Virtual cursor navigation
|
|
197
|
+
|
|
198
|
+
### Linux Orca
|
|
199
|
+
|
|
200
|
+
1. **Enable:** `Alt+F2`, type "orca"
|
|
201
|
+
2. **Configure:** `orca --setup`
|
|
202
|
+
3. **Navigate:** Arrow keys
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## Compliance
|
|
207
|
+
|
|
208
|
+
### WCAG 2.1 AA Compliance
|
|
209
|
+
|
|
210
|
+
| Criterion | Status | Implementation |
|
|
211
|
+
|-----------|--------|----------------|
|
|
212
|
+
| **1.3.1 Info and Relationships** | ✅ Pass | Semantic HTML, ARIA roles |
|
|
213
|
+
| **2.1.1 Keyboard** | ✅ Pass | Full keyboard navigation |
|
|
214
|
+
| **2.1.2 No Keyboard Trap** | ✅ Pass | Escape key blurs graph |
|
|
215
|
+
| **2.4.3 Focus Order** | ✅ Pass | Logical tab order |
|
|
216
|
+
| **2.4.7 Focus Visible** | ✅ Pass | Blue outline on focused nodes |
|
|
217
|
+
| **3.2.1 On Focus** | ✅ Pass | No unexpected context changes |
|
|
218
|
+
| **4.1.2 Name, Role, Value** | ✅ Pass | ARIA labels on all controls |
|
|
219
|
+
| **4.1.3 Status Messages** | ✅ Pass | aria-live regions |
|
|
220
|
+
|
|
221
|
+
### Section 508 Compliance
|
|
222
|
+
|
|
223
|
+
- ✅ **(a) Keyboard access** - All graph functions accessible via keyboard
|
|
224
|
+
- ✅ **(c) Color contrast** - Blue focus indicator meets 4.5:1 contrast ratio
|
|
225
|
+
- ✅ **(d) Screen reader compatible** - ARIA labels and live regions
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## Developer Notes
|
|
230
|
+
|
|
231
|
+
### Code Location
|
|
232
|
+
|
|
233
|
+
- **Keyboard navigation:** `/ui/js/graph-cytoscape.js` (lines 950-1150)
|
|
234
|
+
- **Modal focus management:** `/ui/js/modal.js` (lines 10-18, 142-160)
|
|
235
|
+
- **ARIA attributes:** `/ui/index.html` (graph-pane section)
|
|
236
|
+
|
|
237
|
+
### Key Functions
|
|
238
|
+
|
|
239
|
+
| Function | Purpose |
|
|
240
|
+
|----------|---------|
|
|
241
|
+
| `setupKeyboardNavigation()` | Attaches keyboard event handlers to graph container |
|
|
242
|
+
| `focusNodeAtIndex(index)` | Highlights node and centers viewport |
|
|
243
|
+
| `moveToAdjacentNode(direction, currentNode)` | Finds nearest node in specified direction |
|
|
244
|
+
| `announceNode(node)` | Sends node info to screen reader |
|
|
245
|
+
| `updateScreenReaderStatus(message)` | Updates hidden status region |
|
|
246
|
+
|
|
247
|
+
### Global State Variables
|
|
248
|
+
|
|
249
|
+
```javascript
|
|
250
|
+
var focusedNodeIndex = 0; // Currently focused node index
|
|
251
|
+
var keyboardNavigationEnabled = false; // Is keyboard nav active?
|
|
252
|
+
var lastFocusedElement = null; // For modal focus return
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### Cytoscape.js Style Class
|
|
256
|
+
|
|
257
|
+
```javascript
|
|
258
|
+
{
|
|
259
|
+
selector: 'node.keyboard-focused',
|
|
260
|
+
style: {
|
|
261
|
+
'border-width': 5,
|
|
262
|
+
'border-color': '#0066ff',
|
|
263
|
+
'border-style': 'solid',
|
|
264
|
+
'box-shadow': '0 0 15px #0066ff'
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
## Future Enhancements (v2.7+)
|
|
272
|
+
|
|
273
|
+
1. **Voice commands:** Integrate Web Speech API for voice navigation
|
|
274
|
+
2. **Braille support:** Test with refreshable Braille displays
|
|
275
|
+
3. **High contrast mode:** Additional theme for low vision users
|
|
276
|
+
4. **Keyboard shortcuts help:** Press `?` to show keyboard shortcuts overlay
|
|
277
|
+
5. **Focus trapping in modal:** Prevent Tab from leaving modal when open
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## Feedback
|
|
282
|
+
|
|
283
|
+
If you encounter accessibility issues, please report them:
|
|
284
|
+
|
|
285
|
+
- **GitHub Issues:** https://github.com/varun369/SuperLocalMemoryV2/issues
|
|
286
|
+
- **Label:** Use `accessibility` tag
|
|
287
|
+
- **Include:** Browser, screen reader (if applicable), and steps to reproduce
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
**Copyright © 2026 Varun Pratap Bhardwaj - MIT License**
|
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -85,7 +85,7 @@ Simple Storage → Intelligent Organization → Adaptive Learning
|
|
|
85
85
|
|
|
86
86
|
The MCP server provides native integration with modern AI tools:
|
|
87
87
|
|
|
88
|
-
**
|
|
88
|
+
**12 Tools:**
|
|
89
89
|
- `remember(content, tags, project)` - Save memories
|
|
90
90
|
- `recall(query, limit)` - Search memories
|
|
91
91
|
- `list_recent(limit)` - Recent memories
|
|
@@ -94,12 +94,18 @@ The MCP server provides native integration with modern AI tools:
|
|
|
94
94
|
- `switch_profile(name)` - Change profile
|
|
95
95
|
- `search(query)` - Search memories (OpenAI MCP spec for ChatGPT Connectors)
|
|
96
96
|
- `fetch(id)` - Fetch memory by ID (OpenAI MCP spec for ChatGPT Connectors)
|
|
97
|
+
- `backup_status()` - Auto-backup status
|
|
98
|
+
- `memory_used(memory_id, query, usefulness)` - Feedback for learning (v2.7)
|
|
99
|
+
- `get_learned_patterns(min_confidence, category)` - Retrieve learned patterns (v2.7)
|
|
100
|
+
- `correct_pattern(pattern_id, correct_value)` - Correct a learned pattern (v2.7)
|
|
97
101
|
|
|
98
|
-
**
|
|
99
|
-
- `memory://recent` - Recent memories feed
|
|
102
|
+
**6 Resources:**
|
|
103
|
+
- `memory://recent/{limit}` - Recent memories feed
|
|
100
104
|
- `memory://stats` - System statistics
|
|
101
105
|
- `memory://graph/clusters` - Graph clusters
|
|
102
106
|
- `memory://patterns/identity` - Learned patterns
|
|
107
|
+
- `memory://learning/status` - Learning system status (v2.7)
|
|
108
|
+
- `memory://engagement` - Engagement metrics (v2.7)
|
|
103
109
|
|
|
104
110
|
**2 Prompts:**
|
|
105
111
|
- `coding_identity_prompt` - User's coding style
|
|
@@ -221,16 +227,16 @@ SuperLocalMemory V2 uses a hierarchical, additive architecture where each layer
|
|
|
221
227
|
↑
|
|
222
228
|
┌─────────────────────────────────────────────────────────────────┐
|
|
223
229
|
│ Layer 6: MCP Integration (mcp_server.py) │
|
|
224
|
-
│
|
|
230
|
+
│ 12 tools, 6 resources, 2 prompts │
|
|
225
231
|
│ Auto-configured for Claude Desktop, Cursor, Windsurf, etc. │
|
|
226
232
|
│ Output: Native AI tool access via Model Context Protocol │
|
|
227
233
|
└─────────────────────────────────────────────────────────────────┘
|
|
228
234
|
↑
|
|
229
235
|
┌─────────────────────────────────────────────────────────────────┐
|
|
230
236
|
│ Layer 5: Skills Layer (skills/*) │
|
|
231
|
-
│
|
|
237
|
+
│ 7 slash-command skills for Claude Code, Continue.dev, Cody │
|
|
232
238
|
│ slm-remember, slm-recall, slm-status, slm-list-recent, │
|
|
233
|
-
│ slm-build-graph, slm-switch-profile
|
|
239
|
+
│ slm-build-graph, slm-switch-profile, slm-show-patterns │
|
|
234
240
|
│ Output: Familiar /command interface across AI tools │
|
|
235
241
|
└─────────────────────────────────────────────────────────────────┘
|
|
236
242
|
↑
|