Reorganize cognitive-memory skill: consolidate scripts, systemd, dev subdirs
- Move session_memory.py, ensure-symlinks.sh into skills/cognitive-memory/scripts/ - Copy systemd units into skills/cognitive-memory/systemd/ with README - Move PROJECT_PLAN.json, migrate.py into skills/cognitive-memory/dev/ - Add mtime-based embeddings cache to client.py (6x faster semantic recall) - Default recall to semantic+keyword merge (was keyword-only) - Update settings.json SessionEnd hook path, MCP allow entry - Update SKILL.md, feature.json, mcp_server.py docs for new defaults Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
09429eec3a
commit
f0f075461e
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
{
|
||||
"numStartups": 661,
|
||||
"numStartups": 663,
|
||||
"installMethod": "native",
|
||||
"autoUpdates": true,
|
||||
"preferredNotifChannel": "iterm2_with_bell",
|
||||
@ -11,7 +11,7 @@
|
||||
"enter-to-steer-in-relatime": 651,
|
||||
"todo-list": 660,
|
||||
"# for memory": 38,
|
||||
"install-github-app": 653,
|
||||
"install-github-app": 663,
|
||||
"permissions": 654,
|
||||
"drag-and-drop-images": 659,
|
||||
"double-esc": 75,
|
||||
@ -21,7 +21,7 @@
|
||||
"custom-commands": 655,
|
||||
"shift-enter": 661,
|
||||
"shift-tab": 655,
|
||||
"custom-agents": 648,
|
||||
"custom-agents": 663,
|
||||
"status-line": 536,
|
||||
"git-worktrees": 661,
|
||||
"image-paste": 646,
|
||||
@ -44,7 +44,7 @@
|
||||
"agent-flag": 652
|
||||
},
|
||||
"memoryUsageCount": 18,
|
||||
"promptQueueUseCount": 4477,
|
||||
"promptQueueUseCount": 4513,
|
||||
"cachedStatsigGates": {
|
||||
"tengu_disable_bypass_permissions_mode": false,
|
||||
"tengu_use_file_checkpoints": true,
|
||||
@ -144,7 +144,7 @@
|
||||
"tengu_vinteuil_phrase": true,
|
||||
"tengu_oboe": true,
|
||||
"tengu_tst_names_in_messages": false,
|
||||
"tengu_chomp_inflection": true,
|
||||
"tengu_chomp_inflection": false,
|
||||
"tengu_silver_lantern": false,
|
||||
"tengu_copper_lantern": false,
|
||||
"tengu_workout2": true,
|
||||
@ -615,17 +615,17 @@
|
||||
"ssh-tdarr",
|
||||
"notediscovery"
|
||||
],
|
||||
"lastCost": 0.29647025,
|
||||
"lastAPIDuration": 4856,
|
||||
"lastToolDuration": 0,
|
||||
"lastDuration": 247436,
|
||||
"lastLinesAdded": 0,
|
||||
"lastLinesRemoved": 0,
|
||||
"lastTotalInputTokens": 297,
|
||||
"lastTotalOutputTokens": 29,
|
||||
"lastTotalCacheCreationInputTokens": 47321,
|
||||
"lastTotalCacheReadInputTokens": 0,
|
||||
"lastSessionId": "8d1ffe8f-1e99-4e60-b9dd-270e9a939153",
|
||||
"lastCost": 40.23374199999994,
|
||||
"lastAPIDuration": 5995420,
|
||||
"lastToolDuration": 2896147,
|
||||
"lastDuration": 20374119,
|
||||
"lastLinesAdded": 2594,
|
||||
"lastLinesRemoved": 143,
|
||||
"lastTotalInputTokens": 747870,
|
||||
"lastTotalOutputTokens": 224482,
|
||||
"lastTotalCacheCreationInputTokens": 1751354,
|
||||
"lastTotalCacheReadInputTokens": 47009653,
|
||||
"lastSessionId": "606a9f26-d08c-4654-8a9a-e118a2735aaa",
|
||||
"reactVulnerabilityCache": {
|
||||
"detected": false,
|
||||
"package": null,
|
||||
@ -633,34 +633,44 @@
|
||||
"version": null,
|
||||
"packageManager": null
|
||||
},
|
||||
"lastAPIDurationWithoutRetries": 4855,
|
||||
"lastAPIDurationWithoutRetries": 4961513,
|
||||
"lastModelUsage": {
|
||||
"claude-haiku-4-5-20251001": {
|
||||
"inputTokens": 294,
|
||||
"outputTokens": 16,
|
||||
"cacheReadInputTokens": 0,
|
||||
"cacheCreationInputTokens": 0,
|
||||
"webSearchRequests": 0,
|
||||
"costUSD": 0.000374
|
||||
},
|
||||
"claude-opus-4-6": {
|
||||
"inputTokens": 3,
|
||||
"outputTokens": 13,
|
||||
"cacheReadInputTokens": 0,
|
||||
"cacheCreationInputTokens": 47321,
|
||||
"inputTokens": 9124,
|
||||
"outputTokens": 164889,
|
||||
"cacheReadInputTokens": 44348975,
|
||||
"cacheCreationInputTokens": 1408982,
|
||||
"webSearchRequests": 0,
|
||||
"costUSD": 0.29609625
|
||||
"costUSD": 35.148469999999996
|
||||
},
|
||||
"claude-haiku-4-5-20251001": {
|
||||
"inputTokens": 732883,
|
||||
"outputTokens": 15034,
|
||||
"cacheReadInputTokens": 0,
|
||||
"cacheCreationInputTokens": 67247,
|
||||
"webSearchRequests": 0,
|
||||
"costUSD": 0.892111749999999
|
||||
},
|
||||
"claude-sonnet-4-6": {
|
||||
"inputTokens": 5863,
|
||||
"outputTokens": 44559,
|
||||
"cacheReadInputTokens": 2660678,
|
||||
"cacheCreationInputTokens": 275125,
|
||||
"webSearchRequests": 0,
|
||||
"costUSD": 4.19316025
|
||||
}
|
||||
},
|
||||
"lastSessionMetrics": {
|
||||
"frame_duration_ms_count": 24,
|
||||
"frame_duration_ms_min": 0.26554799999999545,
|
||||
"frame_duration_ms_max": 3.014287000000081,
|
||||
"frame_duration_ms_avg": 1.1559620416666985,
|
||||
"frame_duration_ms_p50": 0.9233974999999646,
|
||||
"frame_duration_ms_p95": 1.925081300000033,
|
||||
"frame_duration_ms_p99": 2.771056710000067
|
||||
}
|
||||
"frame_duration_ms_count": 126433,
|
||||
"frame_duration_ms_min": 0.033378999680280685,
|
||||
"frame_duration_ms_max": 185.3289749994874,
|
||||
"frame_duration_ms_avg": 4.580825976891975,
|
||||
"frame_duration_ms_p50": 1.4972434998489916,
|
||||
"frame_duration_ms_p95": 3.451200450630833,
|
||||
"frame_duration_ms_p99": 90.20297368977218
|
||||
},
|
||||
"lastFpsAverage": 6.12,
|
||||
"lastFpsLow1Pct": 11.02
|
||||
},
|
||||
"/mnt/NV2/Development/major-domo": {
|
||||
"allowedTools": [],
|
||||
@ -2012,13 +2022,20 @@
|
||||
}
|
||||
},
|
||||
"hasOpusPlanDefault": false,
|
||||
"lastPlanModeUse": 1771437917321,
|
||||
"lastPlanModeUse": 1771532414321,
|
||||
"feedbackSurveyState": {
|
||||
"lastShownTime": 1771451253831
|
||||
},
|
||||
"sonnet45MigrationComplete": true,
|
||||
"claudeCodeFirstTokenDate": "2025-07-09T18:28:23.685647Z",
|
||||
"mcpServers": {},
|
||||
"mcpServers": {
|
||||
"cognitive-memory": {
|
||||
"command": "python3",
|
||||
"args": [
|
||||
"/home/cal/.claude/skills/cognitive-memory/mcp_server.py"
|
||||
]
|
||||
}
|
||||
},
|
||||
"s1mNonSubscriberAccessCache": {
|
||||
"fda1c56e-6b2f-4c2d-94f2-636cf90ad0f2": {
|
||||
"hasAccess": false,
|
||||
@ -2088,7 +2105,7 @@
|
||||
"currency": "USD"
|
||||
},
|
||||
"remaining_passes": 3,
|
||||
"timestamp": 1771521872816
|
||||
"timestamp": 1771535572741
|
||||
}
|
||||
},
|
||||
"opus45MigrationComplete": true,
|
||||
@ -2171,8 +2188,8 @@
|
||||
"lastUsedAt": 1770959377885
|
||||
},
|
||||
"sync-config": {
|
||||
"usageCount": 18,
|
||||
"lastUsedAt": 1771507439661
|
||||
"usageCount": 19,
|
||||
"lastUsedAt": 1771530471038
|
||||
},
|
||||
"claude-optimised": {
|
||||
"usageCount": 4,
|
||||
@ -2187,8 +2204,8 @@
|
||||
"lastUsedAt": 1771528594878
|
||||
},
|
||||
"commit-push": {
|
||||
"usageCount": 16,
|
||||
"lastUsedAt": 1771507468440
|
||||
"usageCount": 17,
|
||||
"lastUsedAt": 1771537208260
|
||||
},
|
||||
"check-rarity": {
|
||||
"usageCount": 1,
|
||||
@ -2213,6 +2230,10 @@
|
||||
"claude-automation-recommender": {
|
||||
"usageCount": 1,
|
||||
"lastUsedAt": 1771474474878
|
||||
},
|
||||
"bmad-qa": {
|
||||
"usageCount": 1,
|
||||
"lastUsedAt": 1771536951910
|
||||
}
|
||||
},
|
||||
"opusProMigrationComplete": true,
|
||||
@ -2221,7 +2242,7 @@
|
||||
"passesLastSeenRemaining": 3,
|
||||
"clientDataCache": {
|
||||
"data": {},
|
||||
"timestamp": 1771529175111
|
||||
"timestamp": 1771537923325
|
||||
},
|
||||
"hasShownOpus46Notice": {
|
||||
"57783733-6e1e-48d5-9cb7-fa588a77b795": true
|
||||
@ -1,5 +1,5 @@
|
||||
{
|
||||
"numStartups": 661,
|
||||
"numStartups": 663,
|
||||
"installMethod": "native",
|
||||
"autoUpdates": true,
|
||||
"preferredNotifChannel": "iterm2_with_bell",
|
||||
@ -11,7 +11,7 @@
|
||||
"enter-to-steer-in-relatime": 651,
|
||||
"todo-list": 660,
|
||||
"# for memory": 38,
|
||||
"install-github-app": 653,
|
||||
"install-github-app": 663,
|
||||
"permissions": 654,
|
||||
"drag-and-drop-images": 659,
|
||||
"double-esc": 75,
|
||||
@ -21,7 +21,7 @@
|
||||
"custom-commands": 655,
|
||||
"shift-enter": 661,
|
||||
"shift-tab": 655,
|
||||
"custom-agents": 648,
|
||||
"custom-agents": 663,
|
||||
"status-line": 536,
|
||||
"git-worktrees": 661,
|
||||
"image-paste": 646,
|
||||
@ -44,7 +44,7 @@
|
||||
"agent-flag": 652
|
||||
},
|
||||
"memoryUsageCount": 18,
|
||||
"promptQueueUseCount": 4477,
|
||||
"promptQueueUseCount": 4513,
|
||||
"cachedStatsigGates": {
|
||||
"tengu_disable_bypass_permissions_mode": false,
|
||||
"tengu_use_file_checkpoints": true,
|
||||
@ -144,7 +144,7 @@
|
||||
"tengu_vinteuil_phrase": true,
|
||||
"tengu_oboe": true,
|
||||
"tengu_tst_names_in_messages": false,
|
||||
"tengu_chomp_inflection": true,
|
||||
"tengu_chomp_inflection": false,
|
||||
"tengu_silver_lantern": false,
|
||||
"tengu_copper_lantern": false,
|
||||
"tengu_workout2": true,
|
||||
@ -615,17 +615,17 @@
|
||||
"ssh-tdarr",
|
||||
"notediscovery"
|
||||
],
|
||||
"lastCost": 0.29647025,
|
||||
"lastAPIDuration": 4856,
|
||||
"lastToolDuration": 0,
|
||||
"lastDuration": 247436,
|
||||
"lastLinesAdded": 0,
|
||||
"lastLinesRemoved": 0,
|
||||
"lastTotalInputTokens": 297,
|
||||
"lastTotalOutputTokens": 29,
|
||||
"lastTotalCacheCreationInputTokens": 47321,
|
||||
"lastTotalCacheReadInputTokens": 0,
|
||||
"lastSessionId": "8d1ffe8f-1e99-4e60-b9dd-270e9a939153",
|
||||
"lastCost": 40.23374199999994,
|
||||
"lastAPIDuration": 5995420,
|
||||
"lastToolDuration": 2896147,
|
||||
"lastDuration": 20374119,
|
||||
"lastLinesAdded": 2594,
|
||||
"lastLinesRemoved": 143,
|
||||
"lastTotalInputTokens": 747870,
|
||||
"lastTotalOutputTokens": 224482,
|
||||
"lastTotalCacheCreationInputTokens": 1751354,
|
||||
"lastTotalCacheReadInputTokens": 47009653,
|
||||
"lastSessionId": "606a9f26-d08c-4654-8a9a-e118a2735aaa",
|
||||
"reactVulnerabilityCache": {
|
||||
"detected": false,
|
||||
"package": null,
|
||||
@ -633,34 +633,44 @@
|
||||
"version": null,
|
||||
"packageManager": null
|
||||
},
|
||||
"lastAPIDurationWithoutRetries": 4855,
|
||||
"lastAPIDurationWithoutRetries": 4961513,
|
||||
"lastModelUsage": {
|
||||
"claude-haiku-4-5-20251001": {
|
||||
"inputTokens": 294,
|
||||
"outputTokens": 16,
|
||||
"cacheReadInputTokens": 0,
|
||||
"cacheCreationInputTokens": 0,
|
||||
"webSearchRequests": 0,
|
||||
"costUSD": 0.000374
|
||||
},
|
||||
"claude-opus-4-6": {
|
||||
"inputTokens": 3,
|
||||
"outputTokens": 13,
|
||||
"cacheReadInputTokens": 0,
|
||||
"cacheCreationInputTokens": 47321,
|
||||
"inputTokens": 9124,
|
||||
"outputTokens": 164889,
|
||||
"cacheReadInputTokens": 44348975,
|
||||
"cacheCreationInputTokens": 1408982,
|
||||
"webSearchRequests": 0,
|
||||
"costUSD": 0.29609625
|
||||
"costUSD": 35.148469999999996
|
||||
},
|
||||
"claude-haiku-4-5-20251001": {
|
||||
"inputTokens": 732883,
|
||||
"outputTokens": 15034,
|
||||
"cacheReadInputTokens": 0,
|
||||
"cacheCreationInputTokens": 67247,
|
||||
"webSearchRequests": 0,
|
||||
"costUSD": 0.892111749999999
|
||||
},
|
||||
"claude-sonnet-4-6": {
|
||||
"inputTokens": 5863,
|
||||
"outputTokens": 44559,
|
||||
"cacheReadInputTokens": 2660678,
|
||||
"cacheCreationInputTokens": 275125,
|
||||
"webSearchRequests": 0,
|
||||
"costUSD": 4.19316025
|
||||
}
|
||||
},
|
||||
"lastSessionMetrics": {
|
||||
"frame_duration_ms_count": 24,
|
||||
"frame_duration_ms_min": 0.26554799999999545,
|
||||
"frame_duration_ms_max": 3.014287000000081,
|
||||
"frame_duration_ms_avg": 1.1559620416666985,
|
||||
"frame_duration_ms_p50": 0.9233974999999646,
|
||||
"frame_duration_ms_p95": 1.925081300000033,
|
||||
"frame_duration_ms_p99": 2.771056710000067
|
||||
}
|
||||
"frame_duration_ms_count": 126433,
|
||||
"frame_duration_ms_min": 0.033378999680280685,
|
||||
"frame_duration_ms_max": 185.3289749994874,
|
||||
"frame_duration_ms_avg": 4.580825976891975,
|
||||
"frame_duration_ms_p50": 1.4972434998489916,
|
||||
"frame_duration_ms_p95": 3.451200450630833,
|
||||
"frame_duration_ms_p99": 90.20297368977218
|
||||
},
|
||||
"lastFpsAverage": 6.12,
|
||||
"lastFpsLow1Pct": 11.02
|
||||
},
|
||||
"/mnt/NV2/Development/major-domo": {
|
||||
"allowedTools": [],
|
||||
@ -2012,13 +2022,20 @@
|
||||
}
|
||||
},
|
||||
"hasOpusPlanDefault": false,
|
||||
"lastPlanModeUse": 1771437917321,
|
||||
"lastPlanModeUse": 1771532414321,
|
||||
"feedbackSurveyState": {
|
||||
"lastShownTime": 1771451253831
|
||||
},
|
||||
"sonnet45MigrationComplete": true,
|
||||
"claudeCodeFirstTokenDate": "2025-07-09T18:28:23.685647Z",
|
||||
"mcpServers": {},
|
||||
"mcpServers": {
|
||||
"cognitive-memory": {
|
||||
"command": "python3",
|
||||
"args": [
|
||||
"/home/cal/.claude/skills/cognitive-memory/mcp_server.py"
|
||||
]
|
||||
}
|
||||
},
|
||||
"s1mNonSubscriberAccessCache": {
|
||||
"fda1c56e-6b2f-4c2d-94f2-636cf90ad0f2": {
|
||||
"hasAccess": false,
|
||||
@ -2088,7 +2105,7 @@
|
||||
"currency": "USD"
|
||||
},
|
||||
"remaining_passes": 3,
|
||||
"timestamp": 1771521872816
|
||||
"timestamp": 1771535572741
|
||||
}
|
||||
},
|
||||
"opus45MigrationComplete": true,
|
||||
@ -2171,8 +2188,8 @@
|
||||
"lastUsedAt": 1770959377885
|
||||
},
|
||||
"sync-config": {
|
||||
"usageCount": 18,
|
||||
"lastUsedAt": 1771507439661
|
||||
"usageCount": 19,
|
||||
"lastUsedAt": 1771530471038
|
||||
},
|
||||
"claude-optimised": {
|
||||
"usageCount": 4,
|
||||
@ -2187,8 +2204,8 @@
|
||||
"lastUsedAt": 1771528594878
|
||||
},
|
||||
"commit-push": {
|
||||
"usageCount": 16,
|
||||
"lastUsedAt": 1771507468440
|
||||
"usageCount": 17,
|
||||
"lastUsedAt": 1771537208260
|
||||
},
|
||||
"check-rarity": {
|
||||
"usageCount": 1,
|
||||
@ -2213,6 +2230,10 @@
|
||||
"claude-automation-recommender": {
|
||||
"usageCount": 1,
|
||||
"lastUsedAt": 1771474474878
|
||||
},
|
||||
"bmad-qa": {
|
||||
"usageCount": 1,
|
||||
"lastUsedAt": 1771536951910
|
||||
}
|
||||
},
|
||||
"opusProMigrationComplete": true,
|
||||
@ -2221,7 +2242,7 @@
|
||||
"passesLastSeenRemaining": 3,
|
||||
"clientDataCache": {
|
||||
"data": {},
|
||||
"timestamp": 1771529292422
|
||||
"timestamp": 1771538023670
|
||||
},
|
||||
"hasShownOpus46Notice": {
|
||||
"57783733-6e1e-48d5-9cb7-fa588a77b795": true
|
||||
@ -1,5 +1,5 @@
|
||||
{
|
||||
"numStartups": 661,
|
||||
"numStartups": 663,
|
||||
"installMethod": "native",
|
||||
"autoUpdates": true,
|
||||
"preferredNotifChannel": "iterm2_with_bell",
|
||||
@ -11,7 +11,7 @@
|
||||
"enter-to-steer-in-relatime": 651,
|
||||
"todo-list": 660,
|
||||
"# for memory": 38,
|
||||
"install-github-app": 653,
|
||||
"install-github-app": 663,
|
||||
"permissions": 654,
|
||||
"drag-and-drop-images": 659,
|
||||
"double-esc": 75,
|
||||
@ -21,7 +21,7 @@
|
||||
"custom-commands": 655,
|
||||
"shift-enter": 661,
|
||||
"shift-tab": 655,
|
||||
"custom-agents": 648,
|
||||
"custom-agents": 663,
|
||||
"status-line": 536,
|
||||
"git-worktrees": 661,
|
||||
"image-paste": 646,
|
||||
@ -44,7 +44,7 @@
|
||||
"agent-flag": 652
|
||||
},
|
||||
"memoryUsageCount": 18,
|
||||
"promptQueueUseCount": 4478,
|
||||
"promptQueueUseCount": 4513,
|
||||
"cachedStatsigGates": {
|
||||
"tengu_disable_bypass_permissions_mode": false,
|
||||
"tengu_use_file_checkpoints": true,
|
||||
@ -144,7 +144,7 @@
|
||||
"tengu_vinteuil_phrase": true,
|
||||
"tengu_oboe": true,
|
||||
"tengu_tst_names_in_messages": false,
|
||||
"tengu_chomp_inflection": true,
|
||||
"tengu_chomp_inflection": false,
|
||||
"tengu_silver_lantern": false,
|
||||
"tengu_copper_lantern": false,
|
||||
"tengu_workout2": true,
|
||||
@ -615,17 +615,17 @@
|
||||
"ssh-tdarr",
|
||||
"notediscovery"
|
||||
],
|
||||
"lastCost": 0.29647025,
|
||||
"lastAPIDuration": 4856,
|
||||
"lastToolDuration": 0,
|
||||
"lastDuration": 247436,
|
||||
"lastLinesAdded": 0,
|
||||
"lastLinesRemoved": 0,
|
||||
"lastTotalInputTokens": 297,
|
||||
"lastTotalOutputTokens": 29,
|
||||
"lastTotalCacheCreationInputTokens": 47321,
|
||||
"lastTotalCacheReadInputTokens": 0,
|
||||
"lastSessionId": "8d1ffe8f-1e99-4e60-b9dd-270e9a939153",
|
||||
"lastCost": 40.23374199999994,
|
||||
"lastAPIDuration": 5995420,
|
||||
"lastToolDuration": 2896147,
|
||||
"lastDuration": 20374119,
|
||||
"lastLinesAdded": 2594,
|
||||
"lastLinesRemoved": 143,
|
||||
"lastTotalInputTokens": 747870,
|
||||
"lastTotalOutputTokens": 224482,
|
||||
"lastTotalCacheCreationInputTokens": 1751354,
|
||||
"lastTotalCacheReadInputTokens": 47009653,
|
||||
"lastSessionId": "606a9f26-d08c-4654-8a9a-e118a2735aaa",
|
||||
"reactVulnerabilityCache": {
|
||||
"detected": false,
|
||||
"package": null,
|
||||
@ -633,34 +633,44 @@
|
||||
"version": null,
|
||||
"packageManager": null
|
||||
},
|
||||
"lastAPIDurationWithoutRetries": 4855,
|
||||
"lastAPIDurationWithoutRetries": 4961513,
|
||||
"lastModelUsage": {
|
||||
"claude-haiku-4-5-20251001": {
|
||||
"inputTokens": 294,
|
||||
"outputTokens": 16,
|
||||
"cacheReadInputTokens": 0,
|
||||
"cacheCreationInputTokens": 0,
|
||||
"webSearchRequests": 0,
|
||||
"costUSD": 0.000374
|
||||
},
|
||||
"claude-opus-4-6": {
|
||||
"inputTokens": 3,
|
||||
"outputTokens": 13,
|
||||
"cacheReadInputTokens": 0,
|
||||
"cacheCreationInputTokens": 47321,
|
||||
"inputTokens": 9124,
|
||||
"outputTokens": 164889,
|
||||
"cacheReadInputTokens": 44348975,
|
||||
"cacheCreationInputTokens": 1408982,
|
||||
"webSearchRequests": 0,
|
||||
"costUSD": 0.29609625
|
||||
"costUSD": 35.148469999999996
|
||||
},
|
||||
"claude-haiku-4-5-20251001": {
|
||||
"inputTokens": 732883,
|
||||
"outputTokens": 15034,
|
||||
"cacheReadInputTokens": 0,
|
||||
"cacheCreationInputTokens": 67247,
|
||||
"webSearchRequests": 0,
|
||||
"costUSD": 0.892111749999999
|
||||
},
|
||||
"claude-sonnet-4-6": {
|
||||
"inputTokens": 5863,
|
||||
"outputTokens": 44559,
|
||||
"cacheReadInputTokens": 2660678,
|
||||
"cacheCreationInputTokens": 275125,
|
||||
"webSearchRequests": 0,
|
||||
"costUSD": 4.19316025
|
||||
}
|
||||
},
|
||||
"lastSessionMetrics": {
|
||||
"frame_duration_ms_count": 24,
|
||||
"frame_duration_ms_min": 0.26554799999999545,
|
||||
"frame_duration_ms_max": 3.014287000000081,
|
||||
"frame_duration_ms_avg": 1.1559620416666985,
|
||||
"frame_duration_ms_p50": 0.9233974999999646,
|
||||
"frame_duration_ms_p95": 1.925081300000033,
|
||||
"frame_duration_ms_p99": 2.771056710000067
|
||||
}
|
||||
"frame_duration_ms_count": 126433,
|
||||
"frame_duration_ms_min": 0.033378999680280685,
|
||||
"frame_duration_ms_max": 185.3289749994874,
|
||||
"frame_duration_ms_avg": 4.580825976891975,
|
||||
"frame_duration_ms_p50": 1.4972434998489916,
|
||||
"frame_duration_ms_p95": 3.451200450630833,
|
||||
"frame_duration_ms_p99": 90.20297368977218
|
||||
},
|
||||
"lastFpsAverage": 6.12,
|
||||
"lastFpsLow1Pct": 11.02
|
||||
},
|
||||
"/mnt/NV2/Development/major-domo": {
|
||||
"allowedTools": [],
|
||||
@ -2012,13 +2022,20 @@
|
||||
}
|
||||
},
|
||||
"hasOpusPlanDefault": false,
|
||||
"lastPlanModeUse": 1771437917321,
|
||||
"lastPlanModeUse": 1771532414321,
|
||||
"feedbackSurveyState": {
|
||||
"lastShownTime": 1771451253831
|
||||
},
|
||||
"sonnet45MigrationComplete": true,
|
||||
"claudeCodeFirstTokenDate": "2025-07-09T18:28:23.685647Z",
|
||||
"mcpServers": {},
|
||||
"mcpServers": {
|
||||
"cognitive-memory": {
|
||||
"command": "python3",
|
||||
"args": [
|
||||
"/home/cal/.claude/skills/cognitive-memory/mcp_server.py"
|
||||
]
|
||||
}
|
||||
},
|
||||
"s1mNonSubscriberAccessCache": {
|
||||
"fda1c56e-6b2f-4c2d-94f2-636cf90ad0f2": {
|
||||
"hasAccess": false,
|
||||
@ -2088,7 +2105,7 @@
|
||||
"currency": "USD"
|
||||
},
|
||||
"remaining_passes": 3,
|
||||
"timestamp": 1771521872816
|
||||
"timestamp": 1771535572741
|
||||
}
|
||||
},
|
||||
"opus45MigrationComplete": true,
|
||||
@ -2171,8 +2188,8 @@
|
||||
"lastUsedAt": 1770959377885
|
||||
},
|
||||
"sync-config": {
|
||||
"usageCount": 18,
|
||||
"lastUsedAt": 1771507439661
|
||||
"usageCount": 19,
|
||||
"lastUsedAt": 1771530471038
|
||||
},
|
||||
"claude-optimised": {
|
||||
"usageCount": 4,
|
||||
@ -2187,8 +2204,8 @@
|
||||
"lastUsedAt": 1771528594878
|
||||
},
|
||||
"commit-push": {
|
||||
"usageCount": 16,
|
||||
"lastUsedAt": 1771507468440
|
||||
"usageCount": 17,
|
||||
"lastUsedAt": 1771537208260
|
||||
},
|
||||
"check-rarity": {
|
||||
"usageCount": 1,
|
||||
@ -2213,6 +2230,10 @@
|
||||
"claude-automation-recommender": {
|
||||
"usageCount": 1,
|
||||
"lastUsedAt": 1771474474878
|
||||
},
|
||||
"bmad-qa": {
|
||||
"usageCount": 1,
|
||||
"lastUsedAt": 1771536951910
|
||||
}
|
||||
},
|
||||
"opusProMigrationComplete": true,
|
||||
@ -2221,7 +2242,7 @@
|
||||
"passesLastSeenRemaining": 3,
|
||||
"clientDataCache": {
|
||||
"data": {},
|
||||
"timestamp": 1771529403021
|
||||
"timestamp": 1771538091026
|
||||
},
|
||||
"hasShownOpus46Notice": {
|
||||
"57783733-6e1e-48d5-9cb7-fa588a77b795": true
|
||||
@ -1,5 +1,5 @@
|
||||
{
|
||||
"numStartups": 661,
|
||||
"numStartups": 663,
|
||||
"installMethod": "native",
|
||||
"autoUpdates": true,
|
||||
"preferredNotifChannel": "iterm2_with_bell",
|
||||
@ -11,7 +11,7 @@
|
||||
"enter-to-steer-in-relatime": 651,
|
||||
"todo-list": 660,
|
||||
"# for memory": 38,
|
||||
"install-github-app": 653,
|
||||
"install-github-app": 663,
|
||||
"permissions": 654,
|
||||
"drag-and-drop-images": 659,
|
||||
"double-esc": 75,
|
||||
@ -21,7 +21,7 @@
|
||||
"custom-commands": 655,
|
||||
"shift-enter": 661,
|
||||
"shift-tab": 655,
|
||||
"custom-agents": 648,
|
||||
"custom-agents": 663,
|
||||
"status-line": 536,
|
||||
"git-worktrees": 661,
|
||||
"image-paste": 646,
|
||||
@ -44,7 +44,7 @@
|
||||
"agent-flag": 652
|
||||
},
|
||||
"memoryUsageCount": 18,
|
||||
"promptQueueUseCount": 4478,
|
||||
"promptQueueUseCount": 4513,
|
||||
"cachedStatsigGates": {
|
||||
"tengu_disable_bypass_permissions_mode": false,
|
||||
"tengu_use_file_checkpoints": true,
|
||||
@ -144,7 +144,7 @@
|
||||
"tengu_vinteuil_phrase": true,
|
||||
"tengu_oboe": true,
|
||||
"tengu_tst_names_in_messages": false,
|
||||
"tengu_chomp_inflection": true,
|
||||
"tengu_chomp_inflection": false,
|
||||
"tengu_silver_lantern": false,
|
||||
"tengu_copper_lantern": false,
|
||||
"tengu_workout2": true,
|
||||
@ -615,17 +615,17 @@
|
||||
"ssh-tdarr",
|
||||
"notediscovery"
|
||||
],
|
||||
"lastCost": 0.29647025,
|
||||
"lastAPIDuration": 4856,
|
||||
"lastToolDuration": 0,
|
||||
"lastDuration": 247436,
|
||||
"lastLinesAdded": 0,
|
||||
"lastLinesRemoved": 0,
|
||||
"lastTotalInputTokens": 297,
|
||||
"lastTotalOutputTokens": 29,
|
||||
"lastTotalCacheCreationInputTokens": 47321,
|
||||
"lastTotalCacheReadInputTokens": 0,
|
||||
"lastSessionId": "8d1ffe8f-1e99-4e60-b9dd-270e9a939153",
|
||||
"lastCost": 40.23374199999994,
|
||||
"lastAPIDuration": 5995420,
|
||||
"lastToolDuration": 2896147,
|
||||
"lastDuration": 20374119,
|
||||
"lastLinesAdded": 2594,
|
||||
"lastLinesRemoved": 143,
|
||||
"lastTotalInputTokens": 747870,
|
||||
"lastTotalOutputTokens": 224482,
|
||||
"lastTotalCacheCreationInputTokens": 1751354,
|
||||
"lastTotalCacheReadInputTokens": 47009653,
|
||||
"lastSessionId": "606a9f26-d08c-4654-8a9a-e118a2735aaa",
|
||||
"reactVulnerabilityCache": {
|
||||
"detected": false,
|
||||
"package": null,
|
||||
@ -633,34 +633,44 @@
|
||||
"version": null,
|
||||
"packageManager": null
|
||||
},
|
||||
"lastAPIDurationWithoutRetries": 4855,
|
||||
"lastAPIDurationWithoutRetries": 4961513,
|
||||
"lastModelUsage": {
|
||||
"claude-haiku-4-5-20251001": {
|
||||
"inputTokens": 294,
|
||||
"outputTokens": 16,
|
||||
"cacheReadInputTokens": 0,
|
||||
"cacheCreationInputTokens": 0,
|
||||
"webSearchRequests": 0,
|
||||
"costUSD": 0.000374
|
||||
},
|
||||
"claude-opus-4-6": {
|
||||
"inputTokens": 3,
|
||||
"outputTokens": 13,
|
||||
"cacheReadInputTokens": 0,
|
||||
"cacheCreationInputTokens": 47321,
|
||||
"inputTokens": 9124,
|
||||
"outputTokens": 164889,
|
||||
"cacheReadInputTokens": 44348975,
|
||||
"cacheCreationInputTokens": 1408982,
|
||||
"webSearchRequests": 0,
|
||||
"costUSD": 0.29609625
|
||||
"costUSD": 35.148469999999996
|
||||
},
|
||||
"claude-haiku-4-5-20251001": {
|
||||
"inputTokens": 732883,
|
||||
"outputTokens": 15034,
|
||||
"cacheReadInputTokens": 0,
|
||||
"cacheCreationInputTokens": 67247,
|
||||
"webSearchRequests": 0,
|
||||
"costUSD": 0.892111749999999
|
||||
},
|
||||
"claude-sonnet-4-6": {
|
||||
"inputTokens": 5863,
|
||||
"outputTokens": 44559,
|
||||
"cacheReadInputTokens": 2660678,
|
||||
"cacheCreationInputTokens": 275125,
|
||||
"webSearchRequests": 0,
|
||||
"costUSD": 4.19316025
|
||||
}
|
||||
},
|
||||
"lastSessionMetrics": {
|
||||
"frame_duration_ms_count": 24,
|
||||
"frame_duration_ms_min": 0.26554799999999545,
|
||||
"frame_duration_ms_max": 3.014287000000081,
|
||||
"frame_duration_ms_avg": 1.1559620416666985,
|
||||
"frame_duration_ms_p50": 0.9233974999999646,
|
||||
"frame_duration_ms_p95": 1.925081300000033,
|
||||
"frame_duration_ms_p99": 2.771056710000067
|
||||
}
|
||||
"frame_duration_ms_count": 126433,
|
||||
"frame_duration_ms_min": 0.033378999680280685,
|
||||
"frame_duration_ms_max": 185.3289749994874,
|
||||
"frame_duration_ms_avg": 4.580825976891975,
|
||||
"frame_duration_ms_p50": 1.4972434998489916,
|
||||
"frame_duration_ms_p95": 3.451200450630833,
|
||||
"frame_duration_ms_p99": 90.20297368977218
|
||||
},
|
||||
"lastFpsAverage": 6.12,
|
||||
"lastFpsLow1Pct": 11.02
|
||||
},
|
||||
"/mnt/NV2/Development/major-domo": {
|
||||
"allowedTools": [],
|
||||
@ -2012,13 +2022,20 @@
|
||||
}
|
||||
},
|
||||
"hasOpusPlanDefault": false,
|
||||
"lastPlanModeUse": 1771437917321,
|
||||
"lastPlanModeUse": 1771532414321,
|
||||
"feedbackSurveyState": {
|
||||
"lastShownTime": 1771451253831
|
||||
},
|
||||
"sonnet45MigrationComplete": true,
|
||||
"claudeCodeFirstTokenDate": "2025-07-09T18:28:23.685647Z",
|
||||
"mcpServers": {},
|
||||
"mcpServers": {
|
||||
"cognitive-memory": {
|
||||
"command": "python3",
|
||||
"args": [
|
||||
"/home/cal/.claude/skills/cognitive-memory/mcp_server.py"
|
||||
]
|
||||
}
|
||||
},
|
||||
"s1mNonSubscriberAccessCache": {
|
||||
"fda1c56e-6b2f-4c2d-94f2-636cf90ad0f2": {
|
||||
"hasAccess": false,
|
||||
@ -2088,7 +2105,7 @@
|
||||
"currency": "USD"
|
||||
},
|
||||
"remaining_passes": 3,
|
||||
"timestamp": 1771521872816
|
||||
"timestamp": 1771535572741
|
||||
}
|
||||
},
|
||||
"opus45MigrationComplete": true,
|
||||
@ -2171,8 +2188,8 @@
|
||||
"lastUsedAt": 1770959377885
|
||||
},
|
||||
"sync-config": {
|
||||
"usageCount": 18,
|
||||
"lastUsedAt": 1771507439661
|
||||
"usageCount": 19,
|
||||
"lastUsedAt": 1771530471038
|
||||
},
|
||||
"claude-optimised": {
|
||||
"usageCount": 4,
|
||||
@ -2187,8 +2204,8 @@
|
||||
"lastUsedAt": 1771528594878
|
||||
},
|
||||
"commit-push": {
|
||||
"usageCount": 16,
|
||||
"lastUsedAt": 1771507468440
|
||||
"usageCount": 17,
|
||||
"lastUsedAt": 1771537208260
|
||||
},
|
||||
"check-rarity": {
|
||||
"usageCount": 1,
|
||||
@ -2213,6 +2230,10 @@
|
||||
"claude-automation-recommender": {
|
||||
"usageCount": 1,
|
||||
"lastUsedAt": 1771474474878
|
||||
},
|
||||
"bmad-qa": {
|
||||
"usageCount": 1,
|
||||
"lastUsedAt": 1771536951910
|
||||
}
|
||||
},
|
||||
"opusProMigrationComplete": true,
|
||||
@ -2221,7 +2242,7 @@
|
||||
"passesLastSeenRemaining": 3,
|
||||
"clientDataCache": {
|
||||
"data": {},
|
||||
"timestamp": 1771529672138
|
||||
"timestamp": 1771538153521
|
||||
},
|
||||
"hasShownOpus46Notice": {
|
||||
"57783733-6e1e-48d5-9cb7-fa588a77b795": true
|
||||
2268
backups/.claude.json.backup.1771538521524
Normal file
2268
backups/.claude.json.backup.1771538521524
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
{
|
||||
"fetchedAt": "2026-02-19T19:47:49.668Z",
|
||||
"fetchedAt": "2026-02-19T21:12:52.014Z",
|
||||
"plugins": [
|
||||
{
|
||||
"plugin": "code-review@claude-plugins-official",
|
||||
|
||||
@ -13,6 +13,6 @@
|
||||
"repo": "anthropics/claude-code"
|
||||
},
|
||||
"installLocation": "/home/cal/.claude/plugins/marketplaces/claude-code-plugins",
|
||||
"lastUpdated": "2026-02-19T19:47:51.730Z"
|
||||
"lastUpdated": "2026-02-19T21:13:33.303Z"
|
||||
}
|
||||
}
|
||||
@ -54,7 +54,8 @@
|
||||
"mcp__notediscovery__get_notes_by_tag",
|
||||
"mcp__memorygraph__*",
|
||||
"mcp__memorygraph__get_memory",
|
||||
"Skill(notediscovery)"
|
||||
"Skill(notediscovery)",
|
||||
"mcp__cognitive-memory__*"
|
||||
],
|
||||
"deny": [
|
||||
"Bash(diskutil partitionDisk)",
|
||||
@ -115,7 +116,7 @@
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "/usr/bin/python3 /home/cal/.claude/scripts/session-memory/session_memory.py",
|
||||
"command": "/usr/bin/python3 /home/cal/.claude/skills/cognitive-memory/scripts/session_memory.py",
|
||||
"timeout": 15
|
||||
}
|
||||
]
|
||||
|
||||
@ -56,8 +56,10 @@ All commands support `--help` for full argument details. Key non-obvious feature
|
||||
# --episode flag auto-logs a session entry when storing
|
||||
claude-memory store --type solution --title "Fixed X" --content "..." --tags "t1,t2" --episode
|
||||
|
||||
# --semantic merges keyword + Ollama embedding results (run embed first)
|
||||
claude-memory recall "timeout error" --semantic
|
||||
# recall uses semantic+keyword merge by default (when embeddings exist)
|
||||
claude-memory recall "timeout error"
|
||||
# use --no-semantic for keyword-only (faster, ~3ms vs ~200ms)
|
||||
claude-memory recall "timeout error" --no-semantic
|
||||
|
||||
# procedure type takes structured steps/preconditions/postconditions
|
||||
claude-memory procedure --title "Deploy flow" --content "..." \
|
||||
@ -99,7 +101,29 @@ claude-memory tags suggest <memory_id>
|
||||
| 0.5-0.7 | Standard - useful pattern or solution |
|
||||
| 0.3-0.4 | Minor - nice-to-know, edge cases |
|
||||
|
||||
## Directory Structure
|
||||
## Skill Directory Structure
|
||||
|
||||
```
|
||||
~/.claude/skills/cognitive-memory/
|
||||
├── client.py # Core API + CLI entrypoint
|
||||
├── mcp_server.py # MCP server for Claude Code tools
|
||||
├── SKILL.md # This file
|
||||
├── SCHEMA.md # Format reference for all file types
|
||||
├── feature.json # Skill manifest
|
||||
├── scripts/
|
||||
│ ├── session_memory.py # SessionEnd hook — auto-stores session learnings
|
||||
│ └── ensure-symlinks.sh # Refreshes MEMORY.md symlinks to CORE.md
|
||||
├── systemd/
|
||||
│ ├── README.md # Install instructions for timers
|
||||
│ ├── cognitive-memory-daily.* # Daily: decay, core, symlinks
|
||||
│ ├── cognitive-memory-embed.* # Hourly: refresh embeddings
|
||||
│ └── cognitive-memory-weekly.* # Weekly: reflection cycle
|
||||
└── dev/
|
||||
├── PROJECT_PLAN.json # Development roadmap
|
||||
└── migrate.py # One-time MemoryGraph migration
|
||||
```
|
||||
|
||||
## Data Directory Structure
|
||||
|
||||
```
|
||||
~/.claude/memory/
|
||||
@ -185,8 +209,10 @@ claude-memory store --type decision \
|
||||
# First-time setup: generate embeddings (requires Ollama + nomic-embed-text)
|
||||
claude-memory embed
|
||||
|
||||
# Recall with semantic search (merges keyword + embedding results)
|
||||
claude-memory recall "authentication timeout" --semantic
|
||||
# Recall uses semantic+keyword merge by default
|
||||
claude-memory recall "authentication timeout"
|
||||
# Use --no-semantic for keyword-only
|
||||
claude-memory recall "authentication timeout" --no-semantic
|
||||
```
|
||||
|
||||
### 5. Store a Procedure
|
||||
@ -256,7 +282,7 @@ Auto-generated summary of memory themes, cross-project patterns, and access stat
|
||||
|
||||
## Semantic Search
|
||||
|
||||
Requires Ollama running locally with the `nomic-embed-text` model. Generate embeddings with `claude-memory embed`, then use `--semantic` flag on recall to merge keyword and embedding-based results. Semantic search provides deeper matching beyond exact title/tag keywords - useful for finding conceptually related memories even when different terminology was used.
|
||||
Requires Ollama running locally with the `nomic-embed-text` model. Generate embeddings with `claude-memory embed`. Recall uses semantic+keyword merge by default when embeddings exist (~200ms with warm cache). Use `--no-semantic` for keyword-only (~3ms). Embeddings are cached in memory (mtime-based invalidation) so repeated recalls avoid re-parsing the 24MB embeddings file. Semantic search provides deeper matching beyond exact title/tag keywords - useful for finding conceptually related memories even when different terminology was used.
|
||||
|
||||
## MCP Server
|
||||
|
||||
@ -315,7 +341,7 @@ This skill should be used proactively when:
|
||||
4. **Pattern discovered** - Store for future recall
|
||||
5. **Configuration worked** - Store what worked and why
|
||||
6. **Troubleshooting complete** - Store what was tried, what worked
|
||||
7. **Session start** - CORE.md auto-loads via MEMORY.md symlinks; read REFLECTION.md for theme context, then recall relevant memories (use `--semantic` for deeper matching)
|
||||
7. **Session start** - CORE.md auto-loads via MEMORY.md symlinks; read REFLECTION.md for theme context, then recall relevant memories (semantic is on by default)
|
||||
8. **Multi-step workflow documented** - Use `procedure` type with structured steps/preconditions/postconditions
|
||||
9. **Periodically** - Run `reflect` to cluster memories and surface cross-cutting insights. Run `tags suggest` to find missing tag connections
|
||||
10. **After adding memories** - Run `embed` to refresh semantic search index
|
||||
|
||||
@ -553,6 +553,8 @@ class CognitiveMemoryClient:
|
||||
self.memory_dir = memory_dir or MEMORY_DIR
|
||||
self.index_path = self.memory_dir / "_index.json"
|
||||
self.state_path = self.memory_dir / "_state.json"
|
||||
self._embeddings_cache: Optional[Dict] = None
|
||||
self._embeddings_mtime: float = 0.0
|
||||
self._ensure_dirs()
|
||||
|
||||
def _ensure_dirs(self):
|
||||
@ -563,6 +565,32 @@ class CognitiveMemoryClient:
|
||||
(self.memory_dir / "episodes").mkdir(parents=True, exist_ok=True)
|
||||
(self.memory_dir / "vault").mkdir(parents=True, exist_ok=True)
|
||||
|
||||
def _load_embeddings_cached(self) -> Optional[Dict]:
|
||||
"""Load _embeddings.json with mtime-based caching.
|
||||
|
||||
Returns the parsed dict, or None if the file doesn't exist or fails to parse.
|
||||
Only re-reads from disk when the file's mtime has changed.
|
||||
"""
|
||||
embeddings_path = self.memory_dir / "_embeddings.json"
|
||||
if not embeddings_path.exists():
|
||||
return None
|
||||
try:
|
||||
current_mtime = embeddings_path.stat().st_mtime
|
||||
except OSError:
|
||||
return None
|
||||
if (
|
||||
self._embeddings_cache is not None
|
||||
and current_mtime == self._embeddings_mtime
|
||||
):
|
||||
return self._embeddings_cache
|
||||
try:
|
||||
data = json.loads(embeddings_path.read_text())
|
||||
self._embeddings_cache = data
|
||||
self._embeddings_mtime = current_mtime
|
||||
return data
|
||||
except (json.JSONDecodeError, OSError):
|
||||
return None
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Index and State management
|
||||
# -------------------------------------------------------------------------
|
||||
@ -877,7 +905,7 @@ class CognitiveMemoryClient:
|
||||
query: str,
|
||||
memory_types: Optional[List[str]] = None,
|
||||
limit: int = 10,
|
||||
semantic: bool = False,
|
||||
semantic: bool = True,
|
||||
) -> List[Dict[str, Any]]:
|
||||
"""Search memories by query, ranked by relevance and decay score.
|
||||
|
||||
@ -941,57 +969,55 @@ class CognitiveMemoryClient:
|
||||
results.sort(key=lambda x: x.pop("_score", 0), reverse=True)
|
||||
keyword_results = results[:limit]
|
||||
|
||||
# Merge with semantic results if requested
|
||||
# Weights: semantic 60%, keyword 40% (--semantic signals intent for
|
||||
# conceptual matching; keyword acts as precision boost for exact terms)
|
||||
# Merge with semantic results (on by default)
|
||||
# Weights: semantic 60%, keyword 40%
|
||||
# Conceptual matching dominates; keyword acts as precision boost for exact terms
|
||||
if semantic:
|
||||
embeddings_path = self.memory_dir / "_embeddings.json"
|
||||
if embeddings_path.exists():
|
||||
sem_results = self.semantic_recall(query, limit=limit)
|
||||
if sem_results:
|
||||
score_map: Dict[str, float] = {}
|
||||
result_map: Dict[str, Dict] = {}
|
||||
sem_results = self.semantic_recall(query, limit=limit)
|
||||
if sem_results:
|
||||
score_map: Dict[str, float] = {}
|
||||
result_map: Dict[str, Dict] = {}
|
||||
|
||||
# Keyword: normalize rank to 0-1 (rank 1 = 1.0, last = ~0.1)
|
||||
kw_weight = 0.4
|
||||
for i, r in enumerate(keyword_results):
|
||||
mid = r["id"]
|
||||
normalized = (limit - i) / limit
|
||||
score_map[mid] = normalized * kw_weight
|
||||
result_map[mid] = r
|
||||
# Keyword: normalize rank to 0-1 (rank 1 = 1.0, last = ~0.1)
|
||||
kw_weight = 0.4
|
||||
for i, r in enumerate(keyword_results):
|
||||
mid = r["id"]
|
||||
normalized = (limit - i) / limit
|
||||
score_map[mid] = normalized * kw_weight
|
||||
result_map[mid] = r
|
||||
|
||||
# Semantic: similarity is already 0-1
|
||||
sem_weight = 0.6
|
||||
for r in sem_results:
|
||||
mid = r["id"]
|
||||
sim = r.get("similarity", 0.0)
|
||||
sem_score = sim * sem_weight
|
||||
if mid in score_map:
|
||||
score_map[mid] += sem_score
|
||||
result_map[mid]["similarity"] = sim
|
||||
else:
|
||||
score_map[mid] = sem_score
|
||||
idx_entry = index.get("entries", {}).get(mid, {})
|
||||
s = state.get("entries", {}).get(mid, {})
|
||||
result_map[mid] = {
|
||||
"id": mid,
|
||||
"type": r.get("type"),
|
||||
"title": r.get("title"),
|
||||
"tags": r.get("tags", []),
|
||||
"importance": idx_entry.get("importance"),
|
||||
"decay_score": round(s.get("decay_score", 0.5), 3),
|
||||
"similarity": sim,
|
||||
"path": r.get("path"),
|
||||
"created": idx_entry.get("created"),
|
||||
}
|
||||
# Semantic: similarity is already 0-1
|
||||
sem_weight = 0.6
|
||||
for r in sem_results:
|
||||
mid = r["id"]
|
||||
sim = r.get("similarity", 0.0)
|
||||
sem_score = sim * sem_weight
|
||||
if mid in score_map:
|
||||
score_map[mid] += sem_score
|
||||
result_map[mid]["similarity"] = sim
|
||||
else:
|
||||
score_map[mid] = sem_score
|
||||
idx_entry = index.get("entries", {}).get(mid, {})
|
||||
s = state.get("entries", {}).get(mid, {})
|
||||
result_map[mid] = {
|
||||
"id": mid,
|
||||
"type": r.get("type"),
|
||||
"title": r.get("title"),
|
||||
"tags": r.get("tags", []),
|
||||
"importance": idx_entry.get("importance"),
|
||||
"decay_score": round(s.get("decay_score", 0.5), 3),
|
||||
"similarity": sim,
|
||||
"path": r.get("path"),
|
||||
"created": idx_entry.get("created"),
|
||||
}
|
||||
|
||||
# Sort by merged score
|
||||
merged = sorted(
|
||||
result_map.values(),
|
||||
key=lambda x: score_map.get(x["id"], 0),
|
||||
reverse=True,
|
||||
)
|
||||
return merged[:limit]
|
||||
# Sort by merged score
|
||||
merged = sorted(
|
||||
result_map.values(),
|
||||
key=lambda x: score_map.get(x["id"], 0),
|
||||
reverse=True,
|
||||
)
|
||||
return merged[:limit]
|
||||
|
||||
return keyword_results
|
||||
|
||||
@ -2181,13 +2207,8 @@ class CognitiveMemoryClient:
|
||||
Uses the same provider that generated stored embeddings to embed the query.
|
||||
Skips vectors with dimension mismatch as safety guard.
|
||||
"""
|
||||
embeddings_path = self.memory_dir / "_embeddings.json"
|
||||
if not embeddings_path.exists():
|
||||
return []
|
||||
|
||||
try:
|
||||
emb_data = json.loads(embeddings_path.read_text())
|
||||
except (json.JSONDecodeError, OSError):
|
||||
emb_data = self._load_embeddings_cached()
|
||||
if emb_data is None:
|
||||
return []
|
||||
|
||||
stored = emb_data.get("entries", {})
|
||||
@ -2831,10 +2852,10 @@ def main():
|
||||
sp.add_argument("--types", help="Comma-separated memory types")
|
||||
sp.add_argument("--limit", "-n", type=int, default=10, help="Max results")
|
||||
sp.add_argument(
|
||||
"--semantic",
|
||||
"--no-semantic",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="Also use embedding similarity (requires embed first)",
|
||||
help="Disable semantic search (keyword-only, faster)",
|
||||
)
|
||||
|
||||
# get
|
||||
@ -3041,7 +3062,10 @@ def main():
|
||||
elif args.command == "recall":
|
||||
types = [t.strip() for t in args.types.split(",")] if args.types else None
|
||||
result = client.recall(
|
||||
args.query, memory_types=types, limit=args.limit, semantic=args.semantic
|
||||
args.query,
|
||||
memory_types=types,
|
||||
limit=args.limit,
|
||||
semantic=not args.no_semantic,
|
||||
)
|
||||
|
||||
elif args.command == "get":
|
||||
|
||||
@ -7,9 +7,14 @@
|
||||
"status": "active",
|
||||
"files": {
|
||||
"client.py": "CLI and Python API for all memory operations",
|
||||
"migrate.py": "One-time migration from MemoryGraph SQLite",
|
||||
"mcp_server.py": "MCP server for Claude Code tool integration",
|
||||
"SKILL.md": "Skill documentation and activation triggers",
|
||||
"SCHEMA.md": "Format documentation for all file types"
|
||||
"SCHEMA.md": "Format documentation for all file types",
|
||||
"scripts/session_memory.py": "SessionEnd hook — auto-stores session learnings",
|
||||
"scripts/ensure-symlinks.sh": "Refreshes MEMORY.md symlinks to CORE.md",
|
||||
"systemd/": "Reference copies of systemd user timers (see systemd/README.md)",
|
||||
"dev/migrate.py": "One-time migration from MemoryGraph SQLite",
|
||||
"dev/PROJECT_PLAN.json": "Development roadmap and task tracking"
|
||||
},
|
||||
"data_location": "~/.claude/memory/",
|
||||
"dependencies": "stdlib-only (no external packages; Ollama optional for semantic search)",
|
||||
|
||||
@ -64,7 +64,7 @@ def create_tools() -> list:
|
||||
"name": "memory_recall",
|
||||
"description": (
|
||||
"Search memories by a natural language query, ranked by relevance and decay score. "
|
||||
"Set semantic=true to merge keyword results with vector similarity when embeddings exist."
|
||||
"Semantic search is enabled by default when embeddings exist. Set semantic=false for keyword-only."
|
||||
),
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
@ -75,7 +75,7 @@ def create_tools() -> list:
|
||||
},
|
||||
"semantic": {
|
||||
"type": "boolean",
|
||||
"description": "Merge with semantic/vector similarity search (requires embeddings, default false)",
|
||||
"description": "Merge with semantic/vector similarity search (requires embeddings, default true)",
|
||||
},
|
||||
"limit": {
|
||||
"type": "integer",
|
||||
@ -442,7 +442,7 @@ def handle_tool_call(
|
||||
elif tool_name == "memory_recall":
|
||||
results = client.recall(
|
||||
query=arguments["query"],
|
||||
semantic=arguments.get("semantic", False),
|
||||
semantic=arguments.get("semantic", True),
|
||||
limit=arguments.get("limit", 10),
|
||||
)
|
||||
return ok(results)
|
||||
|
||||
26
skills/cognitive-memory/scripts/ensure-symlinks.sh
Executable file
26
skills/cognitive-memory/scripts/ensure-symlinks.sh
Executable file
@ -0,0 +1,26 @@
|
||||
#!/bin/bash
|
||||
# Ensure all Claude Code project MEMORY.md files symlink to cognitive memory CORE.md
|
||||
# This makes CORE.md auto-load into every session's system prompt.
|
||||
# Run by cognitive-memory-daily.service or manually.
|
||||
|
||||
CORE="/home/cal/.claude/memory/CORE.md"
|
||||
PROJECTS="/home/cal/.claude/projects"
|
||||
|
||||
if [ ! -f "$CORE" ]; then
|
||||
echo "ERROR: CORE.md not found at $CORE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for dir in "$PROJECTS"/*/; do
|
||||
memdir="$dir/memory"
|
||||
memfile="$memdir/MEMORY.md"
|
||||
mkdir -p "$memdir"
|
||||
# Only create/fix symlink if it doesn't already point to CORE.md
|
||||
if [ -L "$memfile" ] && [ "$(readlink "$memfile")" = "$CORE" ]; then
|
||||
continue
|
||||
fi
|
||||
# Remove existing file (regular file or broken symlink)
|
||||
rm -f "$memfile"
|
||||
ln -s "$CORE" "$memfile"
|
||||
echo "Linked: $memfile"
|
||||
done
|
||||
@ -109,15 +109,38 @@ def read_transcript(transcript_path: str) -> list[dict]:
|
||||
return messages
|
||||
|
||||
|
||||
def _is_memory_tool_use(block: dict) -> str | None:
|
||||
"""Check if a tool_use block is a memory operation.
|
||||
|
||||
Detects both CLI calls (Bash with 'claude-memory') and MCP tool calls
|
||||
(mcp__cognitive-memory__memory_*). Returns a short description of the
|
||||
match or None.
|
||||
"""
|
||||
name = block.get("name", "")
|
||||
|
||||
# MCP tool calls: mcp__cognitive-memory__memory_store, memory_recall, etc.
|
||||
if name.startswith("mcp__cognitive-memory__memory_"):
|
||||
return f"MCP:{name}"
|
||||
|
||||
# Legacy/CLI: Bash commands containing 'claude-memory'
|
||||
if name == "Bash":
|
||||
cmd = block.get("input", {}).get("command", "")
|
||||
if "claude-memory" in cmd:
|
||||
return f"CLI:{cmd[:100]}"
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def find_last_memory_command_index(messages: list[dict]) -> int:
|
||||
"""Find the index of the last message containing a claude-memory command.
|
||||
"""Find the index of the last message containing a memory operation.
|
||||
|
||||
Scans for Bash tool_use blocks where the command contains 'claude-memory'
|
||||
(store, recall, episode, etc). Returns the index of that message so we can
|
||||
slice the transcript to only process messages after the last memory operation,
|
||||
avoiding duplicate storage.
|
||||
Scans for both MCP tool calls (mcp__cognitive-memory__memory_*) and
|
||||
Bash tool_use blocks where the command contains 'claude-memory'.
|
||||
Returns the index of that message so we can slice the transcript to
|
||||
only process messages after the last memory operation, avoiding
|
||||
duplicate storage.
|
||||
|
||||
Returns -1 if no claude-memory commands were found.
|
||||
Returns -1 if no memory operations were found.
|
||||
"""
|
||||
last_index = -1
|
||||
found_commands = []
|
||||
@ -132,19 +155,17 @@ def find_last_memory_command_index(messages: list[dict]) -> int:
|
||||
continue
|
||||
if block.get("type") != "tool_use":
|
||||
continue
|
||||
if block.get("name") != "Bash":
|
||||
continue
|
||||
cmd = block.get("input", {}).get("command", "")
|
||||
if "claude-memory" in cmd:
|
||||
match = _is_memory_tool_use(block)
|
||||
if match:
|
||||
last_index = i
|
||||
found_commands.append(f"msg[{i}]: {cmd[:100]}")
|
||||
found_commands.append(f"msg[{i}]: {match}")
|
||||
if found_commands:
|
||||
log(f"[cutoff] Found {len(found_commands)} claude-memory commands:")
|
||||
log(f"[cutoff] Found {len(found_commands)} memory operations:")
|
||||
for fc in found_commands:
|
||||
log(f"[cutoff] {fc}")
|
||||
log(f"[cutoff] Will slice after message index {last_index}")
|
||||
else:
|
||||
log("[cutoff] No claude-memory commands found — processing full transcript")
|
||||
log("[cutoff] No memory operations found — processing full transcript")
|
||||
return last_index
|
||||
|
||||
|
||||
34
skills/cognitive-memory/systemd/README.md
Normal file
34
skills/cognitive-memory/systemd/README.md
Normal file
@ -0,0 +1,34 @@
|
||||
# Cognitive Memory Systemd Timers
|
||||
|
||||
Reference copies of the systemd user units that automate memory maintenance.
|
||||
|
||||
## Services
|
||||
|
||||
| Unit | Schedule | What it does |
|
||||
|------|----------|-------------|
|
||||
| `cognitive-memory-daily` | daily | Decay scores, regenerate CORE.md, refresh MEMORY.md symlinks |
|
||||
| `cognitive-memory-embed` | hourly | Refresh embeddings (skips if unchanged) |
|
||||
| `cognitive-memory-weekly` | weekly | Run reflection cycle |
|
||||
|
||||
## Install / Update
|
||||
|
||||
```bash
|
||||
# Copy units into place
|
||||
cp ~/.claude/skills/cognitive-memory/systemd/*.service \
|
||||
~/.claude/skills/cognitive-memory/systemd/*.timer \
|
||||
~/.config/systemd/user/
|
||||
|
||||
# Reload and enable
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user enable --now cognitive-memory-daily.timer
|
||||
systemctl --user enable --now cognitive-memory-embed.timer
|
||||
systemctl --user enable --now cognitive-memory-weekly.timer
|
||||
```
|
||||
|
||||
## Verify
|
||||
|
||||
```bash
|
||||
systemctl --user list-timers 'cognitive-memory-*'
|
||||
systemctl --user start cognitive-memory-daily.service # manual test run
|
||||
journalctl --user -u cognitive-memory-daily.service --since today
|
||||
```
|
||||
@ -0,0 +1,6 @@
|
||||
[Unit]
|
||||
Description=Cognitive Memory daily maintenance (decay, core, symlinks)
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/bin/bash -c 'export PATH="/home/cal/.local/bin:$PATH" && /home/cal/.local/bin/claude-memory decay && /home/cal/.local/bin/claude-memory core && /home/cal/.local/bin/claude-memory-symlinks'
|
||||
@ -0,0 +1,9 @@
|
||||
[Unit]
|
||||
Description=Run cognitive memory daily maintenance
|
||||
|
||||
[Timer]
|
||||
OnCalendar=daily
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
@ -0,0 +1,6 @@
|
||||
[Unit]
|
||||
Description=Cognitive Memory hourly embedding refresh (skips if unchanged)
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/bin/bash -c 'export PATH="/home/cal/.local/bin:$PATH" && /home/cal/.local/bin/claude-memory embed --if-changed'
|
||||
@ -0,0 +1,9 @@
|
||||
[Unit]
|
||||
Description=Run cognitive memory embedding refresh hourly
|
||||
|
||||
[Timer]
|
||||
OnCalendar=hourly
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
@ -0,0 +1,6 @@
|
||||
[Unit]
|
||||
Description=Cognitive Memory weekly reflection
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/home/cal/.local/bin/claude-memory reflect
|
||||
@ -0,0 +1,9 @@
|
||||
[Unit]
|
||||
Description=Run cognitive memory weekly reflection
|
||||
|
||||
[Timer]
|
||||
OnCalendar=weekly
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
Loading…
Reference in New Issue
Block a user